T-XC32-task-acs-phrase-against-clean-fixtures
Status: closed/superseded · Impact: low · Complexity: small
Spawned from T-M5RS-port-check-entities-to-ts in git@github.com:sksizer/dev.git.
AC-1’s “exit 0 against the live entities tree” and AC-2’s “grep returns no matches” were literally unsatisfiable on the check_entities port because of pre-existing corpus drift and explicitly-out-of-scope reference sites — a faithful port was blocked by orthogonal drift. Task authoring should phrase corpus-dependent ACs against a clean fixture tree (or carve out the known pre-existing drift), so a port AC verifies the change, not the ambient state of the corpus.
The AC contract and the task template both say an AC must be
“objectively verifiable / observable from outside the change,” but
neither warns against the corpus-dependent shape that bit the
check_entities port: an AC phrased as a grep/audit against the
live tree, whose pass/fail depends on the ambient corpus rather
than on the change. The companion baseline mechanism solves this for
the Step-7 quality gate, not for the AC text itself.
| Location | Role today |
|---|---|
plugin/lib/model/entities/task/implementation-ready.md | The AC contract. Its “Acceptance criteria” bullet and “Disqualifiers” list cover subjective ACs and placeholder phrases, but not the corpus-dependent AC shape (a grep/audit against the live tree whose result depends on ambient corpus state). |
plugin/lib/model/entities/task/body-template.eta | The authoring scaffold. Its ## Acceptance criteria guidance says “observable from outside the change,” with no caution about live-corpus dependence. |
docs/planning/tasks/2026-06-02-port-check-entities-to-ts.md#Post-mortem | The incident: AC-1 (“exit 0 against the live entities tree”) and AC-2 (“grep returns no matches”) were unsatisfiable due to 6 pre-existing drift findings and out-of-scope reference sites; the post-mortem had to mark both “with caveat.” |
plugin/scripts/quality_baseline.ts | The companion mechanism that isolates pre-existing drift for the Step-7 quality gate (via --diff-against-baseline). It does NOT touch AC text — this task addresses the AC-authoring side the baseline doesn’t reach. |
Proposed
Section titled “Proposed”implementation-ready.md names the corpus-dependent AC as a
disqualifier and prescribes the two acceptable rephrasings: (a) assert
against a clean fixture tree the task ships, or (b) carve out the known
pre-existing drift explicitly in the AC text (e.g. “no NEW match beyond
the N pre-existing sites, enumerated in Out of scope”). body-template.eta’s
## Acceptance criteria guidance carries a one-line caution pointing at
the same rule. The check_entities post-mortem’s two caveated ACs are
the worked example the contract cites.
Approach
Section titled “Approach”- In
plugin/lib/model/entities/task/implementation-ready.md, extend the “Acceptance criteria” required-section bullet (and add a matching entry to the “Disqualifiers” list) to name the corpus-dependent AC anti-pattern: an AC whose pass/fail depends on the ambient state of the live corpus rather than on the change under test (e.g.audit_entities.tsexits 0 against the live tree, or a repo-widegrepreturns no matches). Prescribe the two acceptable rephrasings — (a) assert against a clean fixture tree, or (b) enumerate the known pre-existing matches and assert “no NEW match beyond those.” Cite thecheck_entitiesport post-mortem as the worked example. - In
plugin/lib/model/entities/task/body-template.eta, add a one-line caution to the## Acceptance criteriaHTML-guidance block pointing at the new rule, so the caution is visible at authoring time. (Keep it inside the<!-- ... -->guidance comment so it does not become instance prose.) - Run the project-check entity-consistency gate to confirm the template/schema/contract triad stays in sync.
Files to touch
Section titled “Files to touch”| Location | Kind | Change |
|---|---|---|
plugin/lib/model/entities/task/implementation-ready.md | modify | Add the corpus-dependent-AC disqualifier + the two acceptable rephrasings; cite the check_entities post-mortem |
plugin/lib/model/entities/task/body-template.eta | modify | One-line authoring caution in the ## Acceptance criteria guidance comment |
Acceptance criteria
Section titled “Acceptance criteria”- AC-1:
plugin/lib/model/entities/task/implementation-ready.mdcontains a disqualifier naming the corpus-dependent AC shape (an AC whose result depends on the ambient live corpus, e.g. anaudit_entities/grep-against-the-live-tree assertion) and prescribes both acceptable rephrasings (clean fixture tree OR enumerated pre-existing carve-out). Verifiable:grep -c "fixture tree" plugin/lib/model/entities/task/implementation-ready.mdreturns ≥1, and the new disqualifier bullet references the carve-out alternative. - AC-2:
plugin/lib/model/entities/task/body-template.eta’s## Acceptance criteriaguidance comment carries a one-line caution about corpus-dependent ACs; the caution lives inside the<!-- -->block (so it is not copied into instance prose). - AC-3:
bun run .claude/skills/project-check/check_entities.tsexits 0 against the live entities tree (the template/schema/contract triad still validates after the doc edits — the doc edits touch no frontmatter keys). - AC-4:
bun testpasses (no entity-loader, audit, or migration test regresses from the contract/template wording change).
Out of scope
Section titled “Out of scope”- The Step-7 quality-gate baseline mechanism (
quality_baseline.ts/--diff-against-baseline) — that already isolates pre-existing drift for the gate; this task only addresses the AC text the gate cannot rephrase. See T-H69K-run-quality-checks-isolates-pre-existing-drift. - Mechanically linting AC bodies for the corpus-dependent shape (a scanner like the grep-AC linter) — this task is the contract/guidance fix; a scanner is a separate, heavier follow-up.
- Cleaning up the 6 pre-existing entity-corpus drift findings the check_entities port surfaced — corpus cleanup is a distinct task.
- Retro-editing already-merged tasks’ ACs — the contract change is forward-looking.
Dependencies
Section titled “Dependencies”- none
Discovery context
Section titled “Discovery context”Spawned by /sdlc:spawn-task-pr on 2026-06-02 UTC from T-M5RS-port-check-entities-to-ts in git@github.com:sksizer/dev.git.