Skip to content

docs(spec): lead the deletion-gate anchor description with what it must NOT be used for - #16199

Merged
huangyiirene merged 1 commit into
mainfrom
claude/issue-14612-authorable-surface-anchor-warning
Sep 6, 2026
Merged

docs(spec): lead the deletion-gate anchor description with what it must NOT be used for#16199
huangyiirene merged 1 commit into
mainfrom
claude/issue-14612-authorable-surface-anchor-warning

Conversation

@huangyiirene

Copy link
Copy Markdown
Collaborator

Fixes #14612

The anchor already called itself an anchor. Triage's sharpest point holds, and I verified it against the file before writing: the description 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?" meets "a verbatim copy of the keys in authorable-surface/" first and takes it as the live set. This adds the missing warning, not a warning.

What landed

  1. The description now 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.
  2. One section in the docs page that covers the authorable surfacedocs/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.
  3. scripts/docs-audit/affected-docs.mjs is recorded as the reference consumer for the union read, in both places, with its --self-test pins 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.

keys and baseRev are 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.ts is in this diff and was not in the claimed file surface. SURFACE_BASE_DESCRIPTION there is the only producer of that string, and readCommittedSurfaceBase() byte-compares the committed file against serializeSurfaceBase(doc.baseRev, doc.keys) — so the JSON alone cannot be edited at all. Both halves move together in one reviewed diff, or check:authorable-surface is 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 baseRev and keys, 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 — that Written only by gen:schema under-states --update-base — is left deferred, as that comment asks, for the diff that next re-anchors.

Plain gen:schema does not rewrite this file. Since #5358 only --update-base writes it. Evidence: a full @objectstack/spec build (which runs gen:schema) left git status empty 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.base gives packages/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.mjs plus 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.mjs carries 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:

  1. One-sided edit. Reverting only the committed JSON description (generator constant left new) → check:authorable-surface exit 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 and git diff HEAD empty.
  2. The claim the new prose makes about the reference consumer. Dropping the live-ratchet half of the union in affected-docs.mjs--self-test exit 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 base d5d8d50db, three-dot): 52 families derived, 50 run green, 2 declared narrowing.

--ran reconciliation 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-closure and check:dual-build-cjs-loads both exit 3 — PREREQUISITE NOT MET, not a finding and not a pass: each reads built output and no workspace package has a dist/ in a fresh worktree. Clearing them needs a whole-repo build, which is the farm's run, not this card's.

Also green: pnpm lint whole-repo, 75s, at 4ad3eba2a (no narrowing needed, so none is claimed); pnpm --filter @objectstack/spec typecheck including check:scripts-typecheck, whose tsconfig.scripts.json names build-schemas.ts explicitly; 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.ts in packages/spec/scripts/ naming build-schemas, plus the git grep hits elsewhere in the package — 19 files, 541 tests, all green. The load-bearing one is scripts/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 --affected from the branch point lists 75 packages, because @objectstack/spec is the dependency-graph root and everything reaches it — not because this diff moved anything they consume. packages/spec's published files array carries neither scripts/ nor authorable-surface.base.json, and no src/ file changed, so no package's inputs moved. Their suites are CI's.

@objectstack/spec has zero workspace dependencies, so the closure build pnpm --filter '@objectstack/spec^...' build matched 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's files array is dist, 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 left git status empty).

Generated by Claude Code


Generated by Claude Code

…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
@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation tooling labels Sep 6, 2026
@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

⚠️ 1 changed file(s) yielded no anchor (packages/spec/authorable-surface.base.json), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files. Nothing else in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)).

What this run could not see
  • 1 changed file(s) yielded no anchor (packages/spec/authorable-surface.base.json) — pages documenting those are invisible to this run
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.

Coarse fallback — 130 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 33388f9db91938bd95cb7ba0062652de9e2db9d1packageMentionDocs.

@huangyiirene huangyiirene added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 6, 2026 — with Claude
This was referenced Sep 6, 2026
@huangyiirene
huangyiirene marked this pull request as ready for review September 6, 2026 11:15
@huangyiirene
huangyiirene added this pull request to the merge queue Sep 6, 2026
Merged via the queue into main with commit 00e6413 Sep 6, 2026
39 of 40 checks passed
@huangyiirene
huangyiirene deleted the claude/issue-14612-authorable-surface-anchor-warning branch September 6, 2026 11:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate tooling

Projects

None yet

2 participants