DR-117: Pipeline fixtures live with the pipeline, not with the tests
DR-117: Pipeline fixtures live with the pipeline, not with the tests
Section titled “DR-117: Pipeline fixtures live with the pipeline, not with the tests”AMENDED by DR-142 (2026-08-10). This ruling’s filing rule stands and is what decides where the Python tests live. Two things below are corrected: the “anything under
scripts/cocoindex_pipeline/moves as one unit” premise is false at the directory boundary (six measured cross-boundary edges;onprem-deploy.ymlpackagesscripts/whole), and the deferred destination is now settled as a singular root-levelpipeline/holding the runtime bundle plus its tests — which is the open question this record routed forward.
Context
Section titled “Context”The form-extraction template fixtures — real product inputs, including a British Council RFP and a standard selection questionnaire — have moved twice without a ruling, and each move was made to fix the symptom the previous location caused.
They began at docs/testing/test-data/templates/. That tree is outside the sidecar’s
pruned build context (cp -R scripts + requirements.lock), so verify_driver.py
running in-container could not read them, and the nightly compensated with a docker cp.
At S521–S522 they were moved to scripts/tests/fixtures/form-extraction/templates/
(b9c55abf, 90cc3b03, eb9ccac9), which fixed the build-context problem.
The owner’s ruling at S522 is that neither location was ever correct, and that the
second move is what surfaced the real defect: the vendored synthetic Platform corpus at
scripts/cocoindex_pipeline/fixtures/platform-corpus/ had been missed entirely as the
walked baseline (id-412). With that in view, the question “where do the form fixtures
live” stops being a tidiness question and becomes a question about which axis fixture
trees are filed on.
Two ratified constraints frame the answer, and they pull in opposite directions if read
naively. D3 (RATIFIED S511, the owner having explicitly overruled a proposal to retire
the two orphan fixtures) says they should “sit with the other corpus forms”, with the exact
destination deferred until the manifest lands — that is now, via id-406. DR-014
retires the corpus forms-route, and platform-corpus-shape.test.ts enforces it: the tree
must contain exactly ten entries, with forms/ and __qa__/ named as prohibited.
A third constraint arrived from an unrelated direction. DR-116 settled that palace
rooms key on directory name matched at any depth, and the S521 rooms review left an
open finding: 99 Python pipeline tests route to room tests rather than pipeline,
because tests is a token of __tests__ and no part of scripts/tests/** says
cocoindex. Anything filed under scripts/tests/ is therefore roomed by kind, not by
domain — the opposite of the ratified intent.
Decision
Section titled “Decision”Fixture trees are filed by the domain that owns them, never by the kind of artefact they are. The form-extraction templates settle at:
scripts/cocoindex_pipeline/fixtures/form-templates/— a sibling of platform-corpus/ under the pipeline’s own fixtures root, not a child
of it and not under scripts/tests/.
This resolves D3 and DR-014 together rather than at each other’s expense: the fixtures root
is “with the other corpus forms”, while platform-corpus/ keeps its exactly-ten-entries
shape and its no forms/ invariant untouched. It also extends an already-ratified anchor
rather than inventing a location — deploy/onprem/sync-platform-corpus.sh:8 names
scripts/cocoindex_pipeline/fixtures/platform-corpus/ as “RATIFY-1: the single source of
truth”.
Two consequences follow that a purely local reading would miss. Under DR-116 these files
now room by domain, because cocoindex_pipeline carries the matching token — which is also
the shape of the answer owed to the S521 scripts/tests/ finding. And when cocoindex moves
out of scripts/ (agreed in principle, deferred), anything under scripts/cocoindex_pipeline/
moves as one unit, while anything under scripts/tests/ would be orphaned by that move.
Alternatives Considered
Section titled “Alternatives Considered”- Keep them at
scripts/tests/fixtures/form-extraction/. Rejected. It files a pipeline artefact by kind, it rooms totestsunder DR-116, and the deferred cocoindex relocation would strand it — guaranteeing a third move of the same files. It is also the location the owner has ruled is not the correct approach. - Move them inside
platform-corpus/, e.g. asplatform-corpus/forms/. Rejected on a hard constraint, not a preference: DR-014 retires the corpus forms-route andplatform-corpus-shape.test.tsasserts exactly ten entries withforms/prohibited. Adopting this would require weakening a ratified guard to accommodate a filing choice. - Return them to
docs/testing/test-data/. Rejected. Outside the pruned build context, so the in-container driver cannot read them without the compensatingdocker cpthat caused the original problem. - Leave the question open until the sidecar leaves
scripts/. Rejected. id-406’s manifest is landing now and must record a destination; deferring means the register whose entire purpose is to replace hardcoded paths would itself hardcode a known-wrong one.
Consequences
Section titled “Consequences”- id-406 settles AC-7 with this destination and registers the tree with
staging_mode: per-test, againstplatform-corpus/’s walked baseline. - id-412 performs the move and repoints all 24 consumers — 21 TS integration tests
(through the new shared fixtures module),
.github/workflows/cocoindex-nightly.yml,scripts/cocoindex_pipeline/verify_driver.py, andscripts/tests/test_form_extractors.py. - The rule generalises beyond these files. Any future fixture tree is filed under the
domain directory that owns it.
__tests__/fixtures/**remains correct for app-side fixtures, because the app’s tests are the owning domain there. - A partial answer to the S521
scripts/tests/room finding. It does not settle where the 99 Python pipeline tests should live — that stays open and belongs with the deferred cocoindex relocation — but it removes the fixture trees from the disputed ground. - Three defects surfaced while deriving this, each routed rather than fixed here: the
nightly’s
docker cpof the form fixtures is likely redundant now that they ship in the build context (id-412); the workflow’s claim that the image “never carries … tests” became false when they moved underscripts/(id-412); and five files still cite deaddocs/testing/paths, including an operator-run IP-leak sweep that now silently finds zero files where it expects eight, on a public repo (id-128 W9).