Skip to content

feat(spec): lint that spec "Locked by Test..." references resolve#90

Merged
remyluslosius merged 1 commit into
mainfrom
feat/spec-test-ref-lint
Jun 15, 2026
Merged

feat(spec): lint that spec "Locked by Test..." references resolve#90
remyluslosius merged 1 commit into
mainfrom
feat/spec-test-ref-lint

Conversation

@remyluslosius

Copy link
Copy Markdown
Contributor

Why

The strict-coverage gate maps tests to ACs by @spec/@ac annotation id, not by checking spec prose against the tree. So a Locked by TestX reference rots silently when TestX is renamed or never written — coverage stays green while the spec lies. The audit found 26 such stale references across 12 specs, and nothing flagged them.

What

TestSpecTestReferencesResolve (in cmd/kensa-validate, runs under the existing go test ./... CI job — no new wiring) scans every specs/**/*.spec.yaml for Go test identifiers and fails on any that don't resolve to a real func Test…, unless tolerated by a ratcheting ledger.

It mirrors the repo's existing divergence-ledger idiom (param_contract_corpus_test.go + mechanism.HandlerParamDivergence):

  • The ledger knownStaleSpecTestRefs seeds the 26 current stale refs, so it lands green.
  • New drift fails immediately — any unresolved reference not in the ledger.
  • Ratchet: a ledger entry that now resolves (or is no longer referenced) also fails, so the ledger can only shrink. Goal: empty.

Matching is strict: exact-name refs require an exact test; only explicit prefix families (trailing _) get prefix matching, so TestFoo can't silently match an unrelated TestFooBar.

Verification

  • Lands green (ledger populated, grouped by spec with rename-vs-gap notes).
  • Proved it catches new drift: injecting a nonexistent Locked by TestThisDoesNotExistAtAll_Sentinel reference into a spec fails the test; removing it restores green.
  • golangci-lint 0 · test-only, no production code.

What's next (the ledger is the worklist)

  • Part (2)-A — re-point the ~24 rename refs to their real test names (11 specs at 100% coverage), deleting each ledger entry as it's fixed.
  • Part (2)-Bagent-bootstrap (83%): write the one genuinely-missing test, then clear its entry.

When the ledger reaches empty, this becomes a pure enforcing gate.

🤖 Generated with Claude Code

Part (2)-lint of the spec-prose drift cleanup. The strict-coverage gate
maps tests to ACs by @spec/@ac annotation id, not by checking spec prose
against the tree — so a "Locked by TestX" reference rots silently when
TestX is renamed or never written, while coverage stays green. The audit
found 26 such stale references across 12 specs; nothing flagged them.

TestSpecTestReferencesResolve (cmd/kensa-validate, runs under
`go test ./...`) closes that hole: it scans every specs/**/*.spec.yaml
for Go test identifiers and FAILS on any that don't resolve to a real
`func Test...`, unless tolerated by the ratcheting ledger
knownStaleSpecTestRefs. It mirrors the param-contract divergence-ledger
idiom: the ledger can only shrink — an entry that now resolves (or is no
longer referenced) also fails (ratchet), so debt can't linger once fixed.

Exact-name references require an exact test; only explicit prefix
families (trailing "_") get prefix matching, so "TestFoo" can't silently
match an unrelated "TestFooBar".

Lands green: the 26 current stale refs are seeded in the ledger, grouped
by spec with rename-vs-gap notes (11 specs are renames; agent-bootstrap
holds the one genuine missing-test gap). Verified it catches NEW drift
(an injected nonexistent reference fails the test). Part (2)-A will
shrink the ledger to empty.

No production code; test-only.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@remyluslosius remyluslosius merged commit 24fafcb into main Jun 15, 2026
14 checks passed
@remyluslosius remyluslosius deleted the feat/spec-test-ref-lint branch June 15, 2026 12:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant