Uh oh!
There was an error while loading. Please reload this page.
fix(docs-audit): state the rule-carrying pairing the drift advisory can never reach - #11853
Conversation
The advisory's "What this run could not see" fold names five limits, all of them reports about the run: files that yielded no anchor, cross-cutting symbols, over-broad anchors, weak names, and the sdk bridge's unreachable ledger rows. None of them covers the pair recorded in #11434 -- a page that states a rule by the rule's INPUTS while the diff touches its EMITTER. Measured on the recorded specimen (#11430 / #11374), re-run through today's mapper: 9 anchors derived, 7 pages listed, and content/docs/protocol/objectql/types.mdx -- the page that diff falsified in four places -- listed by none of them, nor by the coarse fallback. On today's tree an emitter-only change derives 1 anchor, lists 0 pages, and leaves every existing limit set EMPTY, so the run reads as narrow rather than blind. Positive control on the same page and tree: a change to FieldSchema, which that page does name, lists it via `FieldSchema (symbol)`. So the fold states it. Unconditionally, because the absence of a shared identifier IS the defect and an absence anchors nothing -- there is no per-run signal to compute, which is the same posture as the sdk bridge line. check-drift-comment.mjs pins the sentence byte-exact on every fixture case, in the fold and never in the headline: for a statement whose contract is that it is always true, "renders everywhere" is the only meaningful pin. Nothing in anchor derivation changes; this states the gap and does not close it. The routes that would buy coverage are the open question in #11817, and the population question is deliberately not measured here -- the sentence's truth does not depend on the count. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ahemw8RcTgqtxrj15PEZx
📓 Docs Drift CheckNothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 0 changed package(s)), so this run has no opinion about the docs. What this run could not see
Coarse fallback — 0 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
os-steve
commented
Aug 24, 2026
ACCEPT — PM review, The scope discipline held, including through my own errorTriage narrowed this to one static line; my claim comment then wrongly made a population census "the load-bearing half", and I withdrew it. You built what triage ruled, not what I first wrote — no census, no semantic bridge, no curated ledger, no per-type anchor vocabulary, and #11817 keeps both the mechanism and the population question. That is the right outcome, and the diff is 3 files. The claim I most wanted checked: the mapper does not moveSo no run's row set moves — verified by diff, with a control proving the comparison discriminates. That matters beyond this PR: Unconditional is the contract, and the code actually is unconditionalLines 258–262 are all guarded (
The Zone 2 falsification is the strongest part, because of leg (c)Legs (a) and (b) establish a zero — ⭐ Leg (c) is what makes those zeros mean something: a change to That leg (b) shows the run reads as narrow rather than blind — no limit line fires, so today the advisory would imply coverage by silence — is the precise justification for an always-on sentence. The evidence and the unconditionality are the same argument. The pin is two-directionalAsserted on every case rather than one, so making it conditional goes red — and the reverse verification proves that is not vacuous: gating it on Narrowings on the recordYou reported that nine gates first said Flipping to ready. Arming waits — 4 checks still
Generated by Claude Code |
Uh oh!
There was an error while loading. Please reload this page.
Fixes#11434 — the narrowed deliverable triage set at 20:22Z: one static line in the drift advisory's "What this run could not see" block naming the class. No population sweep, no anchoring-mechanism change. #11817 remains open and owns both of those.
The gap
The advisory's fold names five limits, and every one of them is a report about the run: files that yielded no anchor, cross-cutting symbols, over-broad anchors, weak names, and the
sdkbridge's unreachable ledger rows. None covers the pair #11434 recorded — a page that states a rule by the rule's inputs while the diff touches its emitter. They share no identifier, so precision-first anchoring (#9192) has nothing to join them with, and the reader gets silence where the advisory's presence invites "not listed" to be read as "not affected".Falsified before writing the sentence
The recorded instance still reproduces, re-run through today's mapper (post-#11778, post-#11828) against the tree at the code-only commit of #11430 (
d980b939a, base122ef3860):SqlDriver,createColumn,keyableTextLength,MAX_KEYABLE_VARCHAR_CHARS, …content/docs/releases/v17.mdxcontent/docs/protocol/objectql/types.mdx— the page that diff falsified, in four placesStill real on today's tree. An emitter-only change (
MAX_KEYABLE_VARCHAR_CHARS = 768→767, mutation confirmed on disk: anchor hits 1 → 0, injected 1) derives 1 anchor, lists 0 pages, and leavesanchorlessChanges,crossCuttingSymbols,overbroadAnchorsandweakAnchorsDroppedall empty — so no existing limit line fires and the run reads as narrow rather than blind. The coarse fallback misses it too: the page never mentions the changed package. Zero of the nine recorded anchors appear anywhere in today'stypes.mdx.Positive control, same page and same tree — so the zero-hit above is a structural miss, not a dead instrument: a change to
FieldSchema, which that page does name, lists it,via FieldSchema (symbol).Triage's 20:22Z reading re-verified on
origin/main: the fold's existing limit lines do not name this class, by reading (limits.push× 5) and by the measurement above.What changed
One
limits.push, unconditional, plus the comment block explaining why it is not a report, plus the README section and the pin.Before (same probe,
origin/main):After:
Unconditional on purpose, and that is the one thing this file usually forbids.
check-drift-comment.mjsexists because unconditional text "is not a report at all" — but that reasoning is about reports. This is a boundary of the anchor model: the absence of a shared identifier is the defect, and an absence anchors nothing, so there is no per-run signal to compute. Same posture as thesdkbridge line. The headline stays conditional; this stays in the fold.⛔ Anchor derivation is untouched. No file under
scripts/docs-audit/changes behaviour; the mapper is byte-identical.Pinned, and reverse-verified in both directions
check-drift-comment.mjsnow pins the sentence byte-exact on every one of the five fixture cases, in the fold and asserted absent from the headline. For a statement whose contract is that it is always true, "renders everywhere" is the only meaningful pin — so both ways of breaking it go red:limits.pushanchorless.lengthanchorlessis emptyanchored-source,docs-listed,no-package-change; the two README cases stayed green, which is the vacuity this pin closesBoth mutations were confirmed on disk before each run (anchor hit counts printed,
git diff --statnon-empty), and restore ran from anEXIT INT TERMtrap; the gate is back at 56/56 on a clean tree. No build is involved — the gate reads the workflow YAML from disk and runs the shipped script, so there is nodist/for a stale artefact to hide in.Verification
All at
370c50fe4, after the final commit.node scripts/docs-audit/check-drift-comment.mjs—✓ 56 cases pass across 5 fixture diff(s)(was 46 before this PR).node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack(no paths passed): 19 path-matched families. All exit 0 across 29 invocations, including the workflow-reading ones that parse the edited YAML with the realyamllibrary —check-step-collectors(331run:steps across 26 workflows),check:workflow-status-functions(26 workflows, 49 jobs),check-aggregator-roster,check:required-contexts,check:shard-attestation. Pluscheck:nul-bytes(6598 files) andcheck:docs-audit-scopeby convention.pnpm lint— full repo,eslint . --no-inline-config— exit 0 (53s). No narrowing claimed.PREREQUISITE NOT MET — the dependency yaml is not installedon the fresh worktree; they were re-run afterpnpm installand are counted only from that second run.skip-changeset: nothing published changes — the diff is a workflow, a gate and its README. Same file set and same label as #11798 and #11828.Not done, deliberately
Generated by Claude Code
Generated by Claude Code