Repository navigation
docs-drift: bounded history sweep over the 91 enumeration-carrying pages — measure the real rate of uncaught vocabulary widenings (#11817 ruling) #11995
Description
Activity
- addeddocumentationImprovements or additions to documentationImprovements or additions to documentation
on Aug 25, 2026 Claim + Dispatch — R34 ·
⚠️ measurement-only; the deliverable is a sweep record, not codedomain:devxPM seat (seat post #6023), sessionsession_01Pk26oZ12t5N1hwGW1m1MgC.
Branch:claude/issue-11995-enumeration-drift-history-sweep— create it only if you end up with committed artifacts.Pre-checks by this seat: no
content/docs/references/**landing (≈53% of which is generated frompackages/spec) ⇒ ⛔ no clause ② path limb. Epic #12243'scontent/docs/**territory is frontmatter title/description and body headings — this card reads history and writes a record, so no intersection.
Zone 1 — CHARTER + PRE-RULED DECISION RULE (⛔ not re-litigable, quoted verbatim)
Chartered by the maintainer on #11817 (2026-08-25, verbatim 「其他接受」):
Content: sweep the history of the 91 enumeration-carrying doc pages … for past instances of the class: an enumerable vocabulary widened in code while the page enumerating it was not updated, and docs-drift stayed green. Bound the sweep (page set is fixed; pick a defensible history window and state it). Report identities, not counts — each instance names the commit/PR, the page, and the missing members.
Instrument discipline: positive control first — the method must find the one known instance (#11347's formula-function widening, reproduced byte-for-byte on #11817) before any zero elsewhere is believed.
Decision rule (pre-ruled on #11817 — ⛔ not re-litigable here):
- ≥2 real instances (the known feat(service-automation): CEL-mirrored function table for flow value expressions, with a loud unknown-function diagnostic #11347 one counts as the first) → file a NEW decision card carrying the measured rate; option C … is decided there, on data.
- 0–1 instances → B … is the end state; C is not built; close this card with the measurement as the record.
Acceptance criterion: a posted sweep record with the window, the method, the positive-control result, and every instance identified — or a defended zero.
Binding consequences:
- ⭐ The positive control is a gate, not a courtesy. If your method cannot re-find feat(service-automation): CEL-mirrored function table for flow value expressions, with a loud unknown-function diagnostic #11347's formula-function widening, then no zero it produces anywhere else means anything — and the honest report is "the instrument does not work", ⛔ not "I found nothing". This seat has been burned twice this round by probes whose zeros were meaningless; one dev caught it only by running a known-present control.
- Identities, not counts. ⛔ A number alone does not satisfy the acceptance criterion. Each instance = commit/PR + page + the missing members.
- The outcome is already ruled — ⛔ do not propose a remedy. ≥2 ⇒ you say so and it becomes a new decision card; 0–1 ⇒ option B stands and C is not built. Your job is the number and the identities.
- State your window. A bounded sweep with an unstated bound is not bounded.
Zone 2 — PM mechanism assumptions (
⚠️ measure them; falsifying one is a valued deliverable)- A2.1 — I assume the 91-page set and the 447 cells / 1363 spans from [Decision] docs-drift cannot catch a vocabulary widening at all — the only route that would costs an authoring regime on 91 of 189 pages #11817 still describe today's tree. ⛔ Re-derive; if the set has moved, say so and state which set you swept.
- A2.2 — I assume the history is reachable at useful depth. It may not be.
⚠️ If the window you can honestly sweep is too shallow to support a rate, say that with the number of commits you could actually read — "we cannot measure this from history" is a real answer that changes the decision, and far better than a rate built on a handful of commits presented as solid. - A2.3 — I assume "docs-drift stayed green" is recoverable for historical commits. If the gate did not exist, or its verdict is not recoverable that far back, that bounds your window — and the bound belongs in the record.
Zone 3 — suggested route (optional)
- Build the detector; run the positive control on feat(service-automation): CEL-mirrored function table for flow value expressions, with a loud unknown-function diagnostic #11347 first and show it fires.
- Fix your window and state why it is defensible.
- Sweep; record every hit with commit/PR + page + missing members.
- Post the record on this card. Report which branch of the pre-ruled decision rule your result selects — ⛔ without acting on it.
⛔ Boundaries
- ⛔ Do not implement option B or C. ⛔ Do not touch the docs-drift gate's behaviour.
- ⛔ Do not edit
content/docs/releases/. ⛔ Nevergit stash—refs/stashis shared across every worktree. - If you produce committed artifacts (a script, a dataset), use a dedicated per-task worktree and a draft PR — the record still goes on this card.
Generated by Claude Code
os-dev-report
Sweep record — enumeration-drift history sweep (#11995)
Dev seat, session
session_01Pk26oZ12t5N1hwGW1m1MgC. Measurement only; nothing implemented,
docs-drift untouched, no PR (see section 8).TL;DR
- ⭐ The positive control FAILED for the instrument that yields trustworthy identities, and
the instrument that does fire on the control has no discriminative power. Both measured.
⇒ every number here is a FLOOR, not a rate. I am not reporting a zero. - The sweep still found 2 previously unrecorded instances. With feat(service-automation): CEL-mirrored function table for flow value expressions, with a loud unknown-function diagnostic #11347 that is 3.
- ⇒ Result selects the
>=2branch of the pre-ruled rule. ⛔ No remedy proposed.
1. Window — bounded by the GATE, not by shallowness
The checkout is shallow (boundary
798febce8/a49cfc21d, both 2026-05-26), but that does
not bind, because the gate is younger than the boundary.bound commit date reachable history floor 798febce82026-05-26 docs-drift gate BORN ( affected-docs.mjs+docs-drift-check.yml, #1906)3a100c9f32026-06-15 sweep HEAD 90578117f2026-08-31 Swept window =
3a100c9f3..90578117f= 2026-06-15 .. 2026-08-31 = 6008 commits — 4214
touchingpackages/, 1290 touchingcontent/docs/. This is the gate's entire lifetime;
the 847 reachable pre-gate commits are excluded because "docs-drift stayed green" is undefined
there.⚠️ A2.2 falsified, helpfully: the history is not too shallow. No instance can hide
before the window — the gate did not exist to be green."Stayed green" is operationalised as the run did not list the falsified page — the workflow
is advisory only and its VERDICT never fails the build (docs-drift-check.ymlheader), so
"green" cannot mean "the check passed".2. The page set, re-derived (A2.1)
#11817's figures reproduce once the definition is recovered. An enumeration cell = a
markdown table cell carrying at least 3 inline-code spans:tree corpus enumeration pages cells distinct spans #11817's stated figures 189 91 447 1363 2026-08-24 ( da2353495, #11817's day)189 91 448 1365 today ( 90578117f)189 90 460 1411 Corpus =
content/docs/**/*.mdxminuscontent/docs/references/**(affected-docs.mjs:670);
releases/**stays in, which is what makes it 189 rather than 180.A2.1 holds, with one movement: 90 pages today, not 91 —
content/docs/kernel/contracts/metadata-service.mdxfell out. I swept the 91-page set at its
historical positions and the 90-page set at HEAD; every instance below is in both.3. Method
Instrument A — member-overlap binder (the identity-producing one). Bind an enumeration cell
C to a code vocabulary V iff C already names at least 3 of V's members and at least half
of V; thenV \ spans(C)are the members the page fails to enumerate. Vocabularies are
extracted frompackages/**/*.tsin four carriers —z.enum([...]),type X = 'a' | 'b' | 'c',
[...] as const, and object-literal registry tables (1189 on today's tree).Instrument B — file-level binder, built only because A failed the control: bind C to a source
FILE on notation tokens that survive a widening (the file's own comment/literal spellings such as
{NOW()},{$User.Id}), then report omitted members of vocabularies declared in that file.Widening test (the filter that carries the result). A candidate is an instance only if an
in-window commit widened the vocabulary — member set at the commit strictly contains a
non-empty parent set. This excludes creations and package moves, which a baregit log -S
calls "added": of 99 raw-Shits, 91 were move/creation artifacts.Two passes were run: (i) today's-tree pass (finds surviving staleness), and (ii) a full-window
code-side pass over everypackages/**file touched in the window — 2025 widening events
across 468 commits — which also catches instances repaired later. Pass (ii) found both
instances below; pass (i) found only the second.4. ⭐ Positive control — #11347's formula-function widening
Control tree assembled byte-exactly: code half of
815585513(the landed #11347 squash), docs
half reverted to its parent — verified, controlflows.mdxblob
27cedf8b1d4338c83e03344af839c6a1ac674865=815585513^:content/docs/automation/flows.mdx.First finding, and it reframes the card. #11347's squash commit on
maincontains both
halves —content/docs/automation/flows.mdx | 13 +- .../service-automation/src/builtin/template.ts | 185 +++++++++++++++++-— and its own message records the docs as a third commit added in a "PM review round". The
implementation-only state docs-drift was green on never existed onmain. No sweep over
maincan see it; it lives only in PR head commits.Instrument A on the control: FAILS.
tree max member-overlap: any template.tsvocabulary x any offlows.mdx's 16 enumeration cellscontrol (impl half only, docs reverted) 0 landed (docs repaired) 6 / 6 The binding signal exists only after the page is repaired. The six new members are the
defect so they cannot be the anchor, andKNOWN_EXPRESSION_FUNCTIONSwas created disjoint
from everything the page already named (NOW()/TODAY()are deliberately not in it). That is
#11817's structural finding, re-measured independently from the enumeration-cell side.Instrument B on the control: FIRES — but is not an instrument. It re-finds the known instance
exactly:content/docs/automation/flows.mdx:1276, bridged on 5 surviving notation tokens
({$User.Id},{$User.Email},{NOW()},{TODAY()},{TODAY() + 90}), missinground,
floor,ceil,abs,min,max; and its negative control passes (the hit vanishes on the
repaired tree). But on today's tree it emits 9374 candidates over 460 cells, of which
8647 (92.2%) are cells naming zero members of the vocabulary they are accused of
omitting. It fires on the control because it acceptspresent = 0— the same thing that makes
it fire everywhere.⇒ Verdict on the instrument: the trustworthy binder is blind to the control's shape; the
binder that sees the control's shape cannot discriminate. The count below is a floor, and any
zero this method produced would have been meaningless.5. Instances
#1 — #11347 (given by the charter; not re-litigated)
#2 — PR #2065 /
e7f6539a1, 2026-06-20 — NEWfeat(security): ADR-0056 D1 canonical OWD vocab + D2 anonymous-deny posture (#2065)Widening in
packages/spec/src/data/object.zod.ts:- sharingModel: z.enum(['private', 'read', 'read_write', 'full', 'controlled_by_parent']) + sharingModel: z.enum(['private', 'public_read', 'public_read_write', 'controlled_by_parent', 'read', 'read_write', 'full'])- Page:
content/docs/guides/metadata/object.mdx:206(todaycontent/docs/data-modeling/objects.mdx) - Cell:
| `sharingModel` | `enum` | `'private'`, `'read'`, `'read_write'`, `'full'` |— an unambiguous enumeration of exactly this vocabulary - Missing members:
public_read,public_read_write - Docs touched by the commit: NONE
- docs-drift verdict (PR feat(security): ADR-0056 D1 (canonical OWD vocab) + D2 (anonymous deny posture) #2065 comment, 2026-06-20T07:53:12Z): an explicit green tick —
No hand-written docs reference the 0 changed package(s). ✅
Repaired later (today's row is canonical, citing ADR-0090 D4) — so this instance is invisible
to a today's-tree sweep and was recoverable only from the full-window pass.#3 — PR #13371 /
b6d3d76b5, 2026-08-30 — NEW, and still stale at HEADfeat(service-automation): definition-level input-schema refusal is non-retryable (FLOW_INPUT_SCHEMA_INVALID) (#13371)Widening in
packages/runtime/src/flow-dispatch-status.ts:- export type FlowRefusalCode = 'FLOW_DISABLED' | 'FLOW_NO_START_NODE' | 'FLOW_FAILED'; + export type FlowRefusalCode = 'FLOW_DISABLED' | 'FLOW_NO_START_NODE' | 'FLOW_INPUT_SCHEMA_INVALID' | 'FLOW_FAILED';The PR did update
automation/flows.mdx,api/client-sdk.mdx,permissions/system-context.mdx.
It missed four further pages enumerating the same union — each binding 3/3 on the
pre-widening set, each still stale at90578117f:page cell enumerates missing content/docs/api/declarative-endpoints.mdxL103 FLOW_DISABLED,FLOW_NO_START_NODE,FLOW_FAILEDFLOW_INPUT_SCHEMA_INVALIDcontent/docs/api/plugin-endpoints.mdxL51 same three FLOW_INPUT_SCHEMA_INVALIDcontent/docs/protocol/kernel/http-protocol.mdxL1228 same three FLOW_INPUT_SCHEMA_INVALIDcontent/docs/ui/actions.mdxL349 same three FLOW_INPUT_SCHEMA_INVALIDAll four are inside the chartered 91-page set (and the 90-page set today). Repo-wide only the
two pages the PR touched nameFLOW_INPUT_SCHEMA_INVALIDtoday.docs-drift stayed green (PR #13371 comment, 2026-08-30): it listed 2 release-owned pages
only —releases/v16.mdx,releases/v17.mdx, both viaAutomationEngine (symbol)— and named
none of the four;declarative-endpoints,plugin-endpoints,http-protocoland
actions.mdxare all absent from the comment body.Excluded near-miss, recorded because it is decision-relevant
PR #2049 /
4c213c289, 2026-06-20 widened the samesharingModel(+controlled_by_parent),
touched no docs at all, and left the same cell stale — but docs-drift did name the page.
It named it inside a 89-page list (the pre-#9192 package-mention predicate). Not an instance
under the class as chartered (the tool was not green), but it is the flood mode #11817 itself
cites for #6893 / #7009.Triaged out (false positives, hand-checked)
SPEC_TYPE_TO_CELxfield-type-decision-tree.mdx:245and xwidget-contract.mdx:107(cells
list text-family field types; the map is merely keyed by field type) ·ReadPresentationKind
xvalidation-rules.mdx:319(cell is the validation-rule inferred result type, and includes
text, which is not in that union) ·DispatcherErrorCodexruntime-capabilities.mdx:109
(pre-set was the HTTP-status strings'404','405','501','503'; the cell is about
transactionalBatchdiscovery).6. The number, and the branch it selects
3 real instances — #11347 (given) + PR #2065 + PR #13371 — so the pre-ruled threshold is
crossed on the found instances alone, without leaning on the given one.Rate, stated with its true denominator: the full-window pass found 2025 widening events
over 468 commits, but only 193 events over 142 commits carry a vocabulary name that is
unique in its file and can therefore be evaluated reliably (section 7.3). 2 of those 142
commits (≈1.4%) produced a class instance.⇒
>=2branch selected: this becomes a NEW decision card carrying the measured rate, where
option C is decided on data. ⛔ Not acted on here; no remedy proposed; option B untouched.7. Bounds — what this number cannot claim
- The control's shape is invisible. A widening that creates a container disjoint from what
the page already names cannot be bound by any member-overlap method. Instance Add metamodel interfaces for ObjectQL/ObjectUI contract #1 is of that
shape and the sweep would not have found it. True count is greater than or equal to the
reported count. mainis squash-merged (192 merges in 6855 commits; the rest squashes), so a PR whose docs
half was added during review lands as one clean commit — the feat(service-automation): CEL-mirrored function table for flow value expressions, with a loud unknown-function diagnostic #11347 case exactly. Every such
near-miss is invisible to any sweep overmain, and recoverable only from PR head commits.- Extractor collision caps the exhaustive pass. Inline
z.enum([...])is named by its
property key, so one file can hold several distinct enums sharing a name — measured: 6
distinctvariantenums with disjoint member sets in
packages/spec/src/ui/component.zod.ts. Parent-vs-commit comparison by name then compares the
wrong pair and reports a phantom widening. Of 2025 events only 193 (9.5%) have a
file-unique name; 1691 (83%) are phantom-widening risk and 884 (44%) sit in two
collision-hotspot files. The 151 raw hits from the exhaustive pass reduce to 10 under the
uniqueness filter, and those 10 hand-triage to the 2 instances plus 4 false positives above. - Rename blind spot (found, corrected by hand): a moved page reads as "did not exist" at the
widening commit. One exclusion was of this kind —content/docs/ui/pages.mdxwas
content/docs/guides/metadata/page.mdxon 2026-06-30 — and re-checking at the historical path
did not change the verdict. The other "did not exist" exclusions are genuine creations
(declarative-endpoints.mdx2026-08-21,releases/v17.mdx2026-07-28), i.e. pages born
incomplete rather than drifted. - Precision is not mechanical. Deciding "does this cell purport to enumerate V?" is exactly
the judgement an authored mark would supply — which is the cost option C prices. Every false
positive in this sweep is a case where a human had to answer that question.
8. No PR
No committed artifacts. The tooling is one-off and its precision limits are section 7; putting it
underscripts/**pulls in 12 gate families (derived viascripts/pm/dispatch-gates.mjs,
includingcheck:test-completeness) for throwaway measurement code — against startup scope
discipline, with option C not being built. Section 3 states the method precisely enough to re-run.
The pushed branchclaude/issue-11995-enumeration-drift-history-sweepcarries no commits.
Generated by Claude Code
- ⭐ The positive control FAILED for the instrument that yields trustworthy identities, and
✅ ACCEPT — measurement delivered, acceptance criterion met. Card closed; the pre-ruled ≥2 branch fires as #13721.
domain:devxPM seat (#6023), sessionsession_01Pk26oZ12t5N1hwGW1m1MgC, R34 review.⭐⭐ The headline is the positive control — and it FAILED, and was reported as a failure rather than as a zero
This is the thing the dispatch order made a gate rather than a courtesy, and it is the most valuable output of the run:
instrument positive control discrimination A — member-overlap binder (the one that produces identities) ❌ structurally blind: max overlap between any template.tsvocabulary and any offlows.mdx's 16 enumeration cells = 0 on the control tree, 6/6 on the landed tree ⇒ the binding signal exists only AFTER the page is repaired— B — file-level binder ✅ fires on the control exactly ( flows.mdx:1276, bridged on 5 surviving notation tokens), and its negative control passes❌ 9374 candidates over 460 cells, of which 8647 (92.2%) name ZERO members of the vocabulary they accuse ⇒ A zero from instrument A would have been meaningless, and the run says so instead of banking it. The control tree was built byte-exactly and verified by blob hash (
27cedf8b1d…==815585513^:content/docs/automation/flows.mdx) — the control itself was controlled.⭐ And it did not stop there: having established the instrument could not be trusted, it produced the identities by another route (a full-window code-side widening pass, then a uniqueness filter, then hand triage) rather than reporting a number it could not stand behind.
🔬 A methodological finding that outlives this card
⚠️ #11347's squash commit onmaincontains BOTH halves — its message records the docs as a third commit added in a "PM review round". ⇒ the implementation-only state docs-drift was green on never existed onmain, so no sweep overmaincan see it. The given positive control is unreproducible frommainby construction — which is precisely why instrument A read 0 and why a less careful run would have called the method broken or the corpus clean.Zone 2 outcomes
- A2.1 REPRODUCED — 91 pages / 448 cells / 1365 spans on [Decision] docs-drift cannot catch a vocabulary widening at all — the only route that would costs an authoring regime on 91 of 189 pages #11817's own tree vs its stated 91/447/1363. ⭐ And the set MOVED: 90 pages today (
kernel/contracts/metadata-service.mdxfell out), so the sweep used the 91-set at historical positions and the 90-set at HEAD rather than one anachronistic set. - A2.2 FALSIFIED in the helpful direction — history is not too shallow. The window's lower bound is the gate's birth (
3a100c9f3, chore(docs): tooling to keep hand-written docs in sync with implementation #1906), not the shallow floor; 847 reachable commits predate the gate. ⇒ no instance can hide before the window, which closes off "you didn't look far enough" as a rebuttal. - A2.3 handled — "docs-drift stayed green" operationalised as "the run did not list the falsified page", because the workflow is advisory and its VERDICT never fails the build. Stated, not assumed.
Instrument flaws found and quantified, not just noted
- Inline
z.enumis named by its property key, so one file can hold several same-named enums with disjoint members (measured: 6 distinctvariantenums incomponent.zod.ts). ⇒ only 193 of 2025 widening events (9.5%) carry a file-unique name and are reliably evaluable; 151 raw hits reduce to 10 under the uniqueness filter, hand-triaged to 2 instances + 4 false positives. - Rename blind spot found and hand-corrected (
ui/pages.mdxwasguides/metadata/page.mdxon 2026-06-30); re-checked at the historical path, verdict unchanged. - The widening filter itself was validated: of 99 raw
git log -Shits, 91 were file-move/creation artifacts.
Disposition, per the pre-ruled decision rule (⛔ not mine to vary)
≥2 real instances … → file a NEW decision card carrying the measured rate; option C is decided there, on data.
3 instances (#11347 + 2 new) ⇒ branch selected ⇒ #13721 filed, carrying the rate, the instrument findings, and the four-axis analysis. ⭐ The decisive input there is not the count but the instrument result: the binding signal option C would rest on is the one that failed its control, and the sweep found a real precedent for what C degrades into — PR #2049, where docs-drift did name the page, buried in an 89-page list.
Acceptance criterion — "a posted sweep record with the window, the method, the positive-control result, and every instance identified" — met: comment
5475560422, 13.8k characters, read back byte-identical.⛔ No remedy proposed, ⛔ option B/C untouched, ⛔ docs-drift behaviour untouched, ⛔ no PR. Exactly the scope ruled.
Closing this card;
pm:*stripped in the same stroke. The decision lives on #13721; the first concrete defect the sweep surfaced is filed as #13720 (four pages still omittingFLOW_INPUT_SCHEMA_INVALID), unassigned and unlabelled for triage.🧹 One housekeeping item for someone with branch rights: the probe branch
claude/issue-11995-enumeration-drift-history-sweepstill exists on origin at90578117f— zero commits, exactlyorigin/main's tip; the dev's delete was refused by the remote.
Generated by Claude Code
- A2.1 REPRODUCED — 91 pages / 448 cells / 1365 spans on [Decision] docs-drift cannot catch a vocabulary widening at all — the only route that would costs an authoring regime on 91 of 189 pages #11817's own tree vs its stated 91/447/1363. ⭐ And the set MOVED: 90 pages today (
Chartered in #11817's ruling (maintainer, 2026-08-25, verbatim 「其他接受」 accepting the bounded-middle recommendation; full record = #11817 comment 5404972937). Filed by PM session
session_01KWRU3s15AJz7PGW7a7wdChper the confirmed checklist.Content: sweep the history of the 91 enumeration-carrying doc pages (#11817 measured 447 enumeration cells / 1363 distinct enumerated spans) for past instances of the class: an enumerable vocabulary widened in code while the page enumerating it was not updated, and docs-drift stayed green. Bound the sweep (page set is fixed; pick a defensible history window and state it). Report identities, not counts — each instance names the commit/PR, the page, and the missing members.
Instrument discipline: positive control first — the method must find the one known instance (#11347's formula-function widening, reproduced byte-for-byte on #11817) before any zero elsewhere is believed.
Decision rule (pre-ruled on #11817 — ⛔ not re-litigable here):
Acceptance criterion: a posted sweep record with the window, the method, the positive-control result, and every instance identified — or a defended zero.