test(spec): pin the solution-blueprint pointer row to its subject - #16994
Conversation
The published skill-index row for `ai/solution-blueprint.zod.ts` is generated from the module's own doc block, with an export list as the fallback when no block qualifies. Neither generator can see the difference: `check:skill-refs` and `check:docs` each compare an artifact against the generator that wrote it, and the generator reproduces the header selector faithfully — so a generator-only check passes on exactly the state where the row says nothing about the file's subject. This pins the fact the artifact must state instead. Two legs that fail differently. The SOURCE leg reds the moment the separator between the module header and `SNAKE_CASE` goes away — no regeneration needed. The CORPUS leg stays green through that, because it reads checked-in bytes, and reds once an index is regenerated from a file whose header no longer qualifies. Both directions measured by ablation. The pin reads `skills/*/references/_index.md`, outside its own package, so it is declared in `vitest.repo-tests.json` and runs under the `repo` project, whose hash moves with what it actually reads. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016N6xmWt5hYm94ffVEwGH8x
📓 Docs Drift Check
What this run could not see
Coarse fallback — 131 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
The red is the declared landing order, not a defect — and it is this pin working
⭐ Those are the pin's own three legs, and they are the same three the ablation reddened when the fix was removed. This PR carries the pin without the fix — the fix is in #16992 — so on this base the published row is still the This is the What unblocks it#16992 lands first. It is currently GOVERNED — ⇒ Once #16992 is on Generated by Claude Code |
Correction to my 00:44Z comment — #16992 is no longer governed
I wrote:
That was true when written and is not true now. The split it described has since completed: the ⇒ #16992 needs no maintainer merge. It lands through the ordinary queue as soon as its checks close green, and this PR follows it. ⛔ Nobody should be waiting on a human for it. Everything else in that comment stands unchanged: this PR's three red legs are the pin correctly reading a Generated by Claude Code |
✅
|
✅ Landing — all three limbs verified at head
|
grep over content/docs/ |
hits |
|---|---|
repo-tests |
0 |
cross-package-test-inputs |
0 |
control — objectstack |
355 files |
control — ObjectQL |
85 files |
The controls fire, so the zeroes are readings: no doc page states a rule this file carries, and the advisory's blind spot is empty on this PR. ⛔ Nothing owed.
⛔ What was not done
The pin was never touched. Its three red legs before #16992 landed were the correct reading of a main that still carried the Exports: fallback — that redness was the evidence it is not vacuous, and it went green because the world changed, not because the assertion did.
This PR carries Refs, not Fixes ⇒ ⛔ no card moves on merge. #15263 is already closed and cleaned.
Generated by Claude Code
Refs #15263
Blocked-by: #16992 — must land AFTER it. Measured, not assumed: see "Landing order" below.
Clause-②: no
A test-only change. It adds no schema, no export, no accept set and no runtime path;
it asserts an existing published artifact's content. Nothing an author can write moves.
What this pins, and why a generator-only check cannot
The published skill-index row for
ai/solution-blueprint.zod.tsis generated from themodule's own doc block, with
Exports: …as the fallback when no block qualifies.check:skill-refsandcheck:docseach compare an artifact against the generator thatwrote it, and the generator reproduces the header selector faithfully — so both stayed
green for the entire life of the defect #16992 fixes. Triage said it plainly:
So this asserts the fact the artifact must state. Modelled on
packages/spec/scripts/query-pointer-row.test.ts, which #14441's fix used for the samereason one file over.
Two legs that fail differently
SNAKE_CASEgoes away — reds immediately, no regeneration neededAblation from the committed fix, deleting the one-line doc:
Exports:fallbackThe mutation was proven on disk by blob hash before each run and the restore proven by an
empty
git diff HEAD. A fourth leg ("finds the rows at all") is an anti-vacuity guard andstayed green throughout — without it, "no bad row" would read as green when nothing parsed.
Landing order — this PR is red until #16992 lands
Measured on this branch, which is based on
mainwhere the fix has NOT landed:That is the pin correctly detecting the defect that is still on
main— it is evidence thepin is not vacuous, not a fault in this PR. It goes green the moment #16992 lands and this
branch takes that commit. ⛔ Do not land this first.
Cross-package declaration
The pin reads
skills/*/references/_index.md, outside its own package, so it is declared inpackages/spec/vitest.repo-tests.jsonand runs under therepoproject, whose hash moveswith what it actually reads. Left undeclared it would run under
@objectstack/spec#test,invisible to both the affected-subset filter and the turbo cache — green on every PR while
red on main, which is the one failure a pin like this exists to refuse.
pnpm check:cross-package-test-inputscaught exactly that and is now green.Governed-surface verdict
exit 0.
Changeset — both halves, measured
Half 1:
packages/spec'sfiles[]isdist,json-schema,liveness,prompts,llms.txt,README.md,src/**/*.zod.ts,CHANGELOG.md,api-surface,spec-changes.json. Neitherpackages/spec/scripts/**nor a rootvitest.repo-tests.jsonis on it, so half 1 says no.
Half 2, measured on the deciding tree —
npm pack --dry-run --jsonon the@objectstack/spectarball:scripts/solution-blueprint-header-row.test.tsvitest.repo-tests.jsonscripts/entry at allsrc/**/*.zod.ts*.jsonthat DO shippackage.json,spec-changes.jsonThe last row is what makes this a measurement rather than an absence: a sibling root-level
.jsonis shipped by the samefiles[]mechanism, and this one is not. ⇒ nothingpublished moves ⇒
skip-changeset, applied as a label rather than an empty changeset(an empty-frontmatter changeset is a real input to
changesets/actionand an all-empty setstalls the release silently and greenly).
Verification
pnpm check:cross-package-test-inputs✓ ·pnpm check:test-source-alias✓ ·pnpm check:nul-bytes✓ ·pnpm --filter @objectstack/spec check:scripts-typecheck✓ ·pnpm check:agent-test-spelling✓ ·pnpm check:type-check-coverage✓test:repo28 files / 407 passed.Generated by Claude Code