diff --git a/docs/spec-generated-artifact-sharding.md b/docs/spec-generated-artifact-sharding.md index 99e5f9f924..b13bbae042 100644 --- a/docs/spec-generated-artifact-sharding.md +++ b/docs/spec-generated-artifact-sharding.md @@ -51,6 +51,24 @@ arithmetic composes on a merge and the judgement does not). authenticity criterion is untouched in both halves: `baseRev` is an `origin/main` ancestor, and its keys **are** that commit's surface. +### Which artifact answers "is this key authorable today" + +**`packages/spec/authorable-surface/*.json` — the live per-category ratchet, read as one +set. ⛔ Never `authorable-surface.base.json`.** The anchor is pinned at a fixed `baseRev`, +so it is missing every key authored since and answers that question with a stale *no* — a +false negative that grows with the lag. `check:authorable-surface` prints the current +delta on every run; ⛔ do not copy the number into prose, it rots (#14612 re-measured +#13713's figure four days later and it had already moved). + +Where no key may be dropped, read the **union** of ratchet and anchor — a union can only +ever keep an anchor one source vouches for, never drop one more. +`scripts/docs-audit/affected-docs.mjs` is the **reference consumer** for that union read +(#13713 / PR #14607, which measured the false-negative class it closes), and its +`--self-test` pins both halves against the live artifacts: that a key added after +`baseRev` is still authorable, and that the `[RETIRED]` tombstone annotation the ratchet +carries is **stripped** rather than matched — a tombstoned key still rejects with an +upgrade prescription, so it is still surface a page documents. + ## The invariant that makes sharding semantics-preserving > **Every gate reads the whole DIRECTORY as one set — never "the shards this build would diff --git a/packages/spec/authorable-surface.base.json b/packages/spec/authorable-surface.base.json index 907acf8863..4c329b0d3b 100644 --- a/packages/spec/authorable-surface.base.json +++ b/packages/spec/authorable-surface.base.json @@ -1,5 +1,5 @@ { - "description": "In-tree anchor for the authorable-surface deletion gate (#4650, #5235): a verbatim copy of the keys in authorable-surface/ as they stood at `baseRev`, a commit on origin/main. A build that CAN reach origin/main anchors on the merge base instead, and re-verifies this file against `baseRev` — so a PR that edits it to hide a deletion goes red wherever the network exists. A build that CANNOT reach GitHub (image-build stages, air-gapped, fork, historical-tag reproduction) anchors here instead of failing. Written only by `gen:schema`, only from a git-resolved baseline — never from the build that is being checked. See #5235.", + "description": "⛔ NOT the live surface — a pinned anchor for the deletion gate; the live surface is `authorable-surface/*.json`. ⛔ Never answer \"is this key authorable today?\" from this file: it is a snapshot at `baseRev`, so every key authored since is missing from it, and reading it alone yields false negatives that grow with the lag (`check:authorable-surface` prints the current delta on every run — ⛔ never hard-code that number). Ask the live ratchet instead, or read the UNION of ratchet and anchor where no key may be dropped: `scripts/docs-audit/affected-docs.mjs` is the reference consumer for that union read, and its `--self-test` pins both halves — that a key added after `baseRev` is still authorable, and that the `[RETIRED]` tombstone annotation the ratchet carries is stripped rather than matched. What this file IS, and the only question it answers: in-tree anchor for the authorable-surface deletion gate (#4650, #5235) — a verbatim copy of the keys in authorable-surface/ as they stood at `baseRev`, a commit on origin/main. A build that CAN reach origin/main anchors on the merge base instead, and re-verifies this file against `baseRev` — so a PR that edits it to hide a deletion goes red wherever the network exists. A build that CANNOT reach GitHub (image-build stages, air-gapped, fork, historical-tag reproduction) anchors here instead of failing. Written only by `gen:schema`, only from a git-resolved baseline — never from the build that is being checked. See #5235; #14612 for why the negative leads.", "baseRev": "53ef05744f37789a3e2e2ee94325a616b706bea0", "keys": [ "ai/AIModelConfig:maxTokens", diff --git a/packages/spec/scripts/build-schemas.ts b/packages/spec/scripts/build-schemas.ts index 906868c36f..e5fcfaff75 100644 --- a/packages/spec/scripts/build-schemas.ts +++ b/packages/spec/scripts/build-schemas.ts @@ -1088,23 +1088,43 @@ function computeSurfaceReachability(): SurfaceReachability { * ⚠️ Every byte of this string is part of the anchor file's canonical form — * `readCommittedSurfaceBase` compares the committed file against * `serializeSurfaceBase()` and treats any difference as a hand-edit, fatally. - * So changing this text is not a comment edit: it invalidates the committed - * anchor in every checkout until someone re-anchors, which is itself the - * deliberate act #5358 made explicit. It is therefore left verbatim here, and - * "Written only by `gen:schema`" now UNDER-states the rule rather than + * So changing this text is not a comment edit: changed HERE ALONE it leaves the + * committed anchor non-canonical in every checkout, which is the deliberate act + * #5358 made explicit, read as an accident. + * + * It is nevertheless changeable WITHOUT re-anchoring, and #14612 measured that: + * the canonical form is `serializeSurfaceBase(committed.baseRev, committed.keys)`, + * so a diff that rewrites this constant AND `authorable-surface.base.json`'s + * `description` to the same bytes leaves `baseRev` and `keys` untouched and + * `check:authorable-surface` green. Both halves in one reviewed diff, or neither — + * a one-sided edit is the fatal case above, and `build-schemas-check-mode.test.ts` + * is what says so, because it seeds its fixtures with the description read off the + * committed file and runs THIS generator against them. + * + * "Written only by `gen:schema`" still UNDER-states the rule rather than * contradicting it: the writer is still this generator (`scripts/build-schemas.ts`), * but only in its `--update-base` mode (`gen:authorable-surface-base`), never on a * plain build. Narrowing in the safe direction. Whoever next re-anchors should * bring the sentence with them, in that same reviewed diff. */ const SURFACE_BASE_DESCRIPTION = - 'In-tree anchor for the authorable-surface deletion gate (#4650, #5235): a verbatim copy of the ' + - 'keys in authorable-surface/ as they stood at `baseRev`, a commit on origin/main. A build that ' + - 'CAN reach origin/main anchors on the merge base instead, and re-verifies this file against ' + - '`baseRev` — so a PR that edits it to hide a deletion goes red wherever the network exists. A build ' + - 'that CANNOT reach GitHub (image-build stages, air-gapped, fork, historical-tag reproduction) ' + - 'anchors here instead of failing. Written only by `gen:schema`, only from a git-resolved baseline — ' + - 'never from the build that is being checked. See #5235.'; + '⛔ NOT the live surface — a pinned anchor for the deletion gate; the live surface is ' + + '`authorable-surface/*.json`. ⛔ Never answer "is this key authorable today?" from this file: ' + + 'it is a snapshot at `baseRev`, so every key authored since is missing from it, and reading it ' + + 'alone yields false negatives that grow with the lag (`check:authorable-surface` prints the ' + + 'current delta on every run — ⛔ never hard-code that number). Ask the live ratchet instead, or ' + + 'read the UNION of ratchet and anchor where no key may be dropped: ' + + '`scripts/docs-audit/affected-docs.mjs` is the reference consumer for that union read, and its ' + + '`--self-test` pins both halves — that a key added after `baseRev` is still authorable, and that ' + + 'the `[RETIRED]` tombstone annotation the ratchet carries is stripped rather than matched. What ' + + 'this file IS, and the only question it answers: in-tree anchor for the authorable-surface ' + + 'deletion gate (#4650, #5235) — a verbatim copy of the keys in authorable-surface/ as they stood ' + + 'at `baseRev`, a commit on origin/main. A build that CAN reach origin/main anchors on the merge ' + + 'base instead, and re-verifies this file against `baseRev` — so a PR that edits it to hide a ' + + 'deletion goes red wherever the network exists. A build that CANNOT reach GitHub (image-build ' + + 'stages, air-gapped, fork, historical-tag reproduction) anchors here instead of failing. Written ' + + 'only by `gen:schema`, only from a git-resolved baseline — never from the build that is being ' + + 'checked. See #5235; #14612 for why the negative leads.'; /** Canonical bytes of the in-tree anchor — the one form the generator writes. */ function serializeSurfaceBase(baseRev: string, keys: string[]): string {