docs(spec): lead the deletion-gate anchor description with what it must NOT be used for - #16199
Merged
huangyiirene merged 1 commit intoSep 6, 2026
Conversation
…st NOT be used for `authorable-surface.base.json` already called itself an anchor. The warning answered the wrong question: it explains what the file is FOR (the #4650 deletion gate) and never what it must not be USED for, so a reader arriving with "is this key authorable today?" reads "a verbatim copy of the keys in authorable-surface/" and takes it as the live set. The description now leads with the negative, names the live ratchet, and names `scripts/docs-audit/affected-docs.mjs` as the reference consumer for the union read. No count is stated: the gate prints the current delta on every run, and a hard-coded number in a warning about staleness is the same defect one level up. The string lives in `build-schemas.ts` — the committed file is byte-compared against `serializeSurfaceBase()`, so both halves move together or the gate is fatal. `baseRev` and `keys` are untouched, and no consumer's input changes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T6HeZvT9wdSJD1ZxJb5Eno
Contributor
📓 Docs Drift Check
What this run could not see
Coarse fallback — 130 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
This was referenced Sep 6, 2026
huangyiirene
marked this pull request as ready for review
September 6, 2026 11:15
huangyiirene
enabled auto-merge
September 6, 2026 11:16
huangyiirene
deleted the
claude/issue-14612-authorable-surface-anchor-warning
branch
September 6, 2026 11:48
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.
Fixes #14612
The anchor already called itself an anchor. Triage's sharpest point holds, and I verified it against the file before writing: the
descriptionexplains what the file is for (the #4650 deletion gate) and never what it must not be used for, so a reader arriving with "is this key authorable today?" meets "a verbatim copy of the keys inauthorable-surface/" first and takes it as the live set. This adds the missing warning, not a warning.What landed
descriptionnow leads with the negative, in the ruled order:⛔ NOT the live surface — a pinned anchor for the deletion gate; the live surface is authorable-surface/*.json. It then says what the file must not answer, and only afterwards what it is.docs/spec-generated-artifact-sharding.md, which is the only doc naming both artifacts side by side, in the bullet where a reader actually meets the anchor. It answers "which artifact answers is this key authorable today": the live per-category ratchet, never the anchor.scripts/docs-audit/affected-docs.mjsis recorded as the reference consumer for the union read, in both places, with its--self-testpins on the lag and the[RETIRED]stripping named. Prose says do not use the anchor alone; the reference says here is how to read both correctly.keysandbaseRevare untouched (the JSON diff is 1 line changed, 1 line added). No consumer's input changes. No rename.Measured, because the dispatch asked me to falsify it
The file is generated, and the edit therefore belongs at its generator — which is why
packages/spec/scripts/build-schemas.tsis in this diff and was not in the claimed file surface.SURFACE_BASE_DESCRIPTIONthere is the only producer of that string, andreadCommittedSurfaceBase()byte-compares the committed file againstserializeSurfaceBase(doc.baseRev, doc.keys)— so the JSON alone cannot be edited at all. Both halves move together in one reviewed diff, orcheck:authorable-surfaceis fatal.A re-anchor is NOT required for that, and the constant's own doc comment said it was. The canonical form is computed from the committed
baseRevandkeys, so rewriting both halves to the same bytes leaves the anchor authentic and the gate green. The comment is corrected in place and now records the measurement instead of the assumption. The clause it deliberately deferred — thatWritten only by gen:schemaunder-states--update-base— is left deferred, as that comment asks, for the diff that next re-anchors.Plain
gen:schemadoes not rewrite this file. Since #5358 only--update-basewrites it. Evidence: a full@objectstack/specbuild (which runsgen:schema) leftgit statusempty on this branch.The card's 532-key lag has already rotted, so no number is stated anywhere in the new prose. Re-measured at
d5d8d50db, four days after the card: 604 keys live-only after annotation stripping, against the card's 532. The gate prints the current delta itself on every run, and the prose points at that instead. The triage comment's "11 shard files" has moved to 14 for the same reason.Consumer census re-run rather than trusted, and it holds.
git grep -l authorable-surface.basegivespackages/spec/scripts/build-schemas.ts,check-generated.ts,lib/sharded-artifacts.ts,scripts/pm/dispatch-gates.mjs,scripts/regen-artifacts.mjs,scripts/docs-audit/affected-docs.mjsplus its README, three test files,.gitattributes,packages/spec/package.json,docs/spec-generated-artifact-sharding.md, the spec CHANGELOG and.claude/agents/os-dev.md. No live-decision consumer beyond the union read.dispatch-gates.mjscarries a standing instruction to re-point one self-test case only if this file is removed — it is not, so that pin is unmoved.Reverse verification — two ablations, both committed-then-mutated, both restored and proven
Expected direction stated before each run, and both turned red:
check:authorable-surfaceexit 1,❌ authorable-surface.base.json does not match its generated form (#5235).Mutation proven on disk by marker counts (injected 1, removed 0) and by a blob hash differing from HEAD; restore proven by the blob returning to the HEAD hash andgit diff HEADempty.affected-docs.mjs→--self-testexit 1 on exactly the pin the prose names:✗ a key added since the anchor commit is still authorable — the live ratchet is read too: data/Object:editMode → expected true, got false. Same on-disk and restore proofs.Gates
Derived against the real diff with
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands(3 paths, merge based5d8d50db, three-dot): 52 families derived, 50 run green, 2 declared narrowing.--ranreconciliation named 3 UNRUN; one of those,check:doc-formula-expressions, was cleared by building the two packages its own refusal named (turbo run build --filter=@objectstack/formula --filter=@objectstack/lint) and then re-running it — green.Declared narrowing, CI-owned:
check:dts-closureandcheck:dual-build-cjs-loadsboth exit 3 — PREREQUISITE NOT MET, not a finding and not a pass: each reads built output and no workspace package has adist/in a fresh worktree. Clearing them needs a whole-repo build, which is the farm's run, not this card's.Also green:
pnpm lintwhole-repo, 75s, at4ad3eba2a(no narrowing needed, so none is claimed);pnpm --filter @objectstack/spec typecheckincludingcheck:scripts-typecheck, whosetsconfig.scripts.jsonnamesbuild-schemas.tsexplicitly;check:pm-dispatch-gates(1511 cases, 513s);affected-docs.mjs --self-test(585 cases).Tests. Rule for a gate-script edit is its own suites: every
*.test.tsinpackages/spec/scripts/namingbuild-schemas, plus thegit grephits elsewhere in the package — 19 files, 541 tests, all green. The load-bearing one isscripts/build-schemas-check-mode.test.ts, which seeds its fixtures with the description read off the committed file and runs this generator against them, so it is red for any one-sided edit.Affected-package narrowing, declared.
turbo ls --affectedfrom the branch point lists 75 packages, because@objectstack/specis the dependency-graph root and everything reaches it — not because this diff moved anything they consume.packages/spec's publishedfilesarray carries neitherscripts/norauthorable-surface.base.json, and nosrc/file changed, so no package's inputs moved. Their suites are CI's.@objectstack/spechas zero workspace dependencies, so the closure buildpnpm --filter '@objectstack/spec^...' buildmatched no projects — reported here because a zero-match pnpm filter exits 0 and reads like a pass.Changeset
skip-changeset: this PR publishes nothing.packages/spec'sfilesarray isdist,json-schema,liveness,prompts,llms.txt,README.md,src/**/*.zod.ts,CHANGELOG.md,api-surface,spec-changes.json— none of the three changed paths is in it, and the generated output that IS published is byte-unchanged (a full spec build leftgit statusempty).Generated by Claude Code
Generated by Claude Code