knowledge: golden-gate schema additions, call-site enumeration, fixture-signature coupling - #20
Merged
Merged
Conversation
- testing/quality/schema-additions-under-a-golden-gate (new): a node kind absent from the golden example is untouched by every mutant derived from it; commit a minimal conforming fixture, add one negative per keyword the new branch adds, and restore each to require red. - backend/common/change-impact/call-site-enumeration (new page, new category): enumerate by callee name and treat a parameter-name search as a partial index — positional-or-keyword is Python's default parameter kind and ast.Call keeps args/keywords in separate fields. - testing/data/test-data-and-isolation (merge): a fixture factory whose shape depends on a value the test also passes to the code under test takes it as a parameter, never as a module-level default.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Knowledge flush — 3 insight(s)
Queue drained:
~/.dev-loop/queue/0c6a5439-….jsonl(1 row),~/.dev-loop/queue/fb7e7221-….jsonl(2 rows). All three were harvested2026-08-04 from the
linkly-t1-spec-notationandlinkly-t1-repo-policyrepos.Result: 2 new pages, 1 merge into an existing page, 1 new category.
testing/quality/schema-additions-under-a-golden-gatebackend/common/change-impact/call-site-enumerationtesting/data/test-data-and-isolationVerified best-practice
Every URL below was fetched during this flush; the quotes are from those
fetches, not from memory. Nothing was cited that I did not open.
Insight 1 — a golden-derived negative corpus cannot reach a newly added schema branch
Claim under test: when a format's only gate builds negatives by mutating one
committed golden example, adding a new node kind to the schema produces a green
run that proves nothing about the addition.
ifis invalid,elsemust also be valid (andthenis ignored)" — a branch keyed on the new kind is simply not applied to an instance that lacks it. So a mutant of a golden without the new kind cannot exercise the new branch.propertieskeyword are not required".Session evidence (kept as a field observation, not as the basis of the
directive): in
linkly-t1-spec-notation,grep -rln "lir.schema\|jsonschema" impl/tests/returned 0 of 447 tests, and the only schema gate over*.lir.jsonwas
scripts/validate_ir.py --self-test, whose three negatives are allcopy.deepcopymutations ofexamples/login.lir.json.Confidence:
verified— the directive's mechanism is stated in the officialJSON Schema documentation; the incident is corroborating, not load-bearing.
Insight 2 — enumerate by callee name, not by parameter name
Claim under test: a keyword-argument search (
repo_rows=) is structurallyincapable of finding call sites that pass the same argument positionally.
ast.Call: "argsholds a list of the arguments passed by position", "keywordsholds a list ofkeywordobjects representing arguments passed by keyword" — the two forms live in separate fields, so a keyword-name text search reads only one of them./and*markers, which is what makes the page's "declare it keyword-only so a stale positional call errors instead of rebinding" edge case actionable.Reproduction run this session (Python 3.14.6, macOS, no files written — piped
to
python3on stdin): over four call sites ofverify(...)of which one passesrepo_rows=by keyword, a regex search forrepo_rows\s*=matches 1 whilean AST pass over
Callnodes namedverifyfinds 4 — 3 sites invisible tothe keyword search. This is the minimal version of the reported incident.
Session evidence: recon reported "13 call sites, 7 need editing"; 8 further
seeds passed the value as
verify()'s 4th positional argument, and the suite thesession had reported green then ran
472 tests / FAILED (failures=11).Confidence:
verified— official language reference plus a reproduction.Insight 3 — a fixture factory takes the value the test also passes to the SUT
Claim under test: when a fixture helper's shape depends on a value the test
also feeds the system under test, that value belongs in the helper's signature
rather than in a module-level default.
Session evidence:
rows_for(doc)seeded from the module constantPAYLOADwhile its tests ran payload
{}; a shape-only migration fixed 1 of 11 failures,moving the payload into the signature fixed 11 of 11.
Confidence:
verified— both sources are prescriptive on the exact point.Note: the canonical name for this smell is xUnit Patterns' Mystery Guest.
xunitpatterns.comis HTTP-only and could not be fetched over HTTPS thissession, so it is deliberately not cited — an unfetchable URL is worse than
none, per the ingest rules.
Existing-layer check
Routed via
INDEX.md→ domainindex.md→ every page whose "load when" lineoverlapped. Pages read in full before deciding: all six of
testing/quality/,testing/data/test-data-and-isolation,testing/index,qa/process/regression-scope,qa/index,debugging/index,backend/index,backend/python/index, plus arepo-wide search for prior coverage (
grep -rliE "call site|callee|positional argument|keyword argument"and a\bgrep\bsweep overwiki/).Insight 1 — nearest neighbours, and why it is not a duplicate
testing/quality/spec-artifact-checkstesting/quality/tests-that-cannot-failrelated:added both ways.testing/quality/harness-reverse-controlsrelated:added both ways.testing/quality/checks-that-cannot-passqa/document-verification/spec-document-gatesrelated:from the new page.No conflicts found. Nothing in the wiki contradicts the new directive.
Insight 2 — no existing coverage anywhere
The repo-wide search found zero pages discussing call-site enumeration,
callee-name search, or positional-vs-keyword arguments as a recon concern. The
single adjacent line is
qa/process/regression-scope's edge-case row "Thechange is in code with no test coverage and unclear callers | Trace callers
before scoping" — which names the need and does not say how. That row now
points at the new page, and
regression-scopegained the new page inrelated:(both directions).Checked and rejected as homes:
debugging/*(diagnosis of a failure, notpre-change recon),
backend/python/language/mutable-state-traps(mutabledefaults and shared state — a different mechanism),
platforms/tools/bsd-vs-gnu-cli(grep flag portability, not search strategy).
Insight 3 — merged, not created
testing/data/test-data-and-isolationalready owns fixture construction andcarries the adjacent rule "pass explicitly only the fields the test's behavior
depends on" plus a row for shared mutable fixture objects. This insight is
the same trigger with a directive that extends it (a defaulted constant, which
is not mutated and so is not covered by the existing row). Merge-before-create
applied — no new page. Added: 1
Dorow, 1 edge-case row (the symptom is alookup miss far from the helper), 1
Instead ofrow, 2 sources, andlast_verifiedbumped to 2026-08-04.Routing decision
testing/quality/ new pageschema-additions-under-a-golden-gateINDEX.mdroutes "writing or structuring automated tests … verifying tests can actually fail" totesting; within it,qualityalready holds the five pages about whether a check proves anything. Existing category, no structural change.testing/data/ merge intotest-data-and-isolationbackend/common/ NEW categorychange-impact/call-site-enumerationNew category:
backend/common/change-impact/Why
backend:AGENTS.md's routing protocol resolves a multi-domain matchby "the domain that owns the artifact you will change" — here, application
code. Why
common: the directive is language-agnostic (any language withoptional or positional arguments; in a language with no keyword arguments at all
the parameter-name search returns nothing whatsoever). The Python mechanics are
cited as the mechanism, not as the scope.
Why not an existing category — all eleven
backend/commoncategories werere-checked by name before creating a new one:
api-designis the only near miss, and all three of its pages are HTTP-shaped(status codes, endpoint idempotency, list-endpoint pagination). Its "load when"
lines are written about endpoints; filing an in-process function-signature
concern there would make the category's routing lines contradict its contents,
which invariant 1 forbids.
reliability,caching,jobs,errors,auth,orm,concurrency,llm,integrations,storage— all runtime-behaviour categories; nonecovers a design-time change-impact question under any other name.
change-impactis the noun for the concern, leaves room for sibling pages(schema/event-contract consumers, deprecation windows), and is registered in
wiki/backend/index.mdplus the rootINDEX.mdbackend row.Plumbing
wiki/testing/index.md— newqualityrow with a use-case-enumerating "load when" line.wiki/backend/index.md— newchange-impactsection + subtree summary row updated.INDEX.md— backend row'scommon/concern list updated.log.md—## [2026-08-04] ingest | …entry appended.related:added both ways for all four adjacent pages.Invariants verified mechanically (not by eye)
Ran over all 141 pages after the edits:
index.md→ 0 unlistedrelated:id and inline[page-id]reference resolves → 0 brokenusually,consider,might want to,generally,as appropriate) in the three touched pages → 0 hitsbare prohibition; anti-patterns appear only in
Instead oftables, each pairedwith its replacement.