You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[finding] The gate section and cli.mdx disagree about the gate in three places — a heading/anchor pair that cannot be renamed alone, a stale rule count, and a retired rule still listed #7465
Observation-class cluster, surfaced while implementing #7442 (the "gate" table's fourth column) and deliberately left out of PR #7458 because all three sit outside that card's ruled file surface. Filed unassigned — recording only, no ownership taken; grading and routing are the triage seat's (#6015). ⛔ Not self-claimed.
These are three separate drifts, but they are one cluster: content/docs/deployment/validating-metadata.mdx and content/docs/deployment/cli.mdx describe the same gate and no longer agree with each other or with the code.
1. The heading is now wrong, and it cannot be fixed in one file
validating-metadata.mdx has ## The one gate, three entry points. Since #4463 P1 there are four doors — the three CLI commands plus the runtime publish gate (saveMetaItem on a state: 'active' write, and publishMetaItem on the draft→active promotion), which PR #7458 has just documented as a fourth column.
⚠️The rename is a paired edit, not a one-word fix.content/docs/deployment/cli.mdx:458 links the anchor #the-one-gate-three-entry-points. Renaming the heading alone silently breaks that inbound link — and because the two files are in different cards' file surfaces, the obvious "just fix the heading" change is exactly the one that breaks it. PR #7458 left the heading alone for this reason and reconciled it in the body instead.
Both edits belong in one commit: the heading and the cli.mdx link.
2. The sample transcript's rule count is stale
The console transcript quoted in validating-metadata.mdx reads:
Running author-time rules (26)
AUTHORING_RULES now holds 38 entries. This is a quoted run transcript rather than a claim about the gate, which is why it was out of scope for a card about the table — but a reader comparing the transcript against the table below it gets two different answers about how many rules exist.
3. cli.mdx still lists a rule that was retired
content/docs/deployment/cli.mdx:473 lists deprecated visibility aliases among what os lint reports. visibility-alias-deprecated was retired by #6318 — confirmed in validate-visibility-predicates.ts, authoring-rules.ts and authoring-rule-input-tier.test.ts. PR #7458 dropped it from the table's advisory row in validating-metadata.mdx; the same claim survives in cli.mdx, which that card could not touch.
This is the only one of the three that is declared ≠ enforced in the user-facing direction: the docs promise a lint report that no longer exists.
Why observation-class
Nobody is blocked. (1) is a correctness-of-prose issue whose only cost is a reader mis-counting doors; (2) is a stale quoted number; (3) is the sharpest — a documented lint output that will never appear — but it is a report line, not a guarantee anyone builds on. Grading left to triage; ⛔ this seat does not self-grade.
Dedup
Searched open issues for the-one-gate-three-entry-points, author-time rules (26), visibility alias and cli.mdx before filing: no existing card. #7442 (now closed by PR #7458) is the discovering neighbour and its report comment records all three; this card exists so they remain discoverable after that issue closes.
Refs: #7442, PR #7458, #4463 (P1, the fourth door), #6318 (the retirement), #7435 / 89d7b35a7 (the advisory channel).
Landing + anchors (read on origin/main @ 603cab8, not a worktree): all three drifts are live —
content/docs/deployment/validating-metadata.mdx:349 still reads ## The one gate, three entry points, and content/docs/deployment/cli.mdx:458 links the #the-one-gate-three-entry-points anchor — the paired-edit constraint is real (renaming the heading alone breaks the inbound link).
validating-metadata.mdx:471 transcript reads Running author-time rules (26)... while packages/lint/src/authoring-rules.ts holds 38 top-level entries on main (counted, not quoted).
cli.mdx:473 still lists deprecated visibility aliases; visibility-alias-deprecated is retired — live code greps only hit changesets/CHANGELOG (visibility-alias-deprecated-retired.md), no live rule.
Routing rationale: the fix lands entirely in the two hand-written gate-docs pages; they document the metadata authoring/contract gate (AUTHORING_RULES, os lint — packages/lint), i.e. tooling that revolves around the spec contract ⇒ domain:spec-tooling per the #5469 split criterion. Direct precedent: #7442 (same file, same gate table) ran as domain:spec-tooling.
Dedup: local sweep over all open issues in the three repos for cli.mdx / validating-metadata / author-time rules — no overlapping card (only this one; falsified the zero-hit with a known-present neighbour term). #7442 is closed via PR #7458 and deliberately excluded these three.
Release grading: no target:* — docs/display class (a mis-counted heading, a stale quoted transcript, one stale report line); nobody is blocked today, same grading family as #7307.
All three drifts re-verified live on origin/main @ 333769d: the stale heading content/docs/deployment/validating-metadata.mdx:349 ("three entry points", four doors since #4463 P1) with its inbound anchor content/docs/deployment/cli.mdx:458; the stale transcript count at validating-metadata.mdx:482 ("Running author-time rules (26)"); and the retired deprecated visibility aliases rule still listed at cli.mdx:473 (retired by #6318). This is a scoped docs-gate fix with named locations and a mechanical paired-edit shape (heading + anchor in one commit) — nothing left to rule. Not target:v17: advisory docs drift, none of the four blocking classes. Dedup from the filing thread stands (no overlapping open card or PR found this round).
Claim: PM loop round 11 — domain:spec-tooling seat (#6018)
Session: session_01KJATVrh6V2ysutYUJigh3B
Branch: claude/issue-7465-gate-docs-drift-cluster
Domain: domain:spec-tooling
File surface: content/docs/deployment/validating-metadata.mdx + content/docs/deployment/cli.mdx. Both, in one commit — that is the point of the card, not an incidental pairing. Stop on breach; explain in the report.
Container & model: S-size, NOT mechanical — one of the three fixes is a live count that no gate can judge, and the rename is a multi-site coordinated edit whose failure mode is a silently broken link. Per the 2026-08-10 sizing ruling this takes M treatment: mode:cloud single container, model: opus. Same shape and precedent as #7442.
Serial constraints cleared: no open PR touches either page; validating-metadata.mdx last landed 45cd354ec/#7458 (this lane, ~14:2xZ) and cli.mdx is untouched since. Neither is under the merge=os-regen tree, so a hand edit is not regenerated away.
Premises re-verified live on origin/main before claiming — and one number re-measured at dispatch time rather than quoted (㊽):
#
Claim
Reading
1
heading is stale
validating-metadata.mdx:349 — ## The one gate, three entry points ✅
2
inbound anchor exists
cli.mdx:458 — [The one gate, three entry points](/docs/deployment/validating-metadata#the-one-gate-three-entry-points) ✅
⚠️Reading 2 is sharper than the card recorded it. The inbound reference is not only a URL anchor — the link text is also "The one gate, three entry points". So the rename is a three-site coordinated edit (heading, anchor fragment, link text), and getting two of three right leaves either a broken link or a link whose text contradicts its destination. This is exactly why #7442 declined to rename inside a single-file surface.
Label pair applied atomically (pm:dispatched in the same write that removed pm:queue, #7239).
{
"issue": 7465,
"status": "implemented",
"branch": "claude/issue-7465-gate-docs-drift-cluster",
"worktree": "/home/user/objectstack-7465 (dedicated, off origin/main @ a76a3af)",
"commit": "bd5d66a",
"pr": 7483,
"pr_url": "https://github.com/objectstack-ai/objectstack/pull/7483",
"pr_state": "draft",
"changeset": "none — docs-only; skip-changeset is the PM's to apply at accept time",
"files_changed": [
"content/docs/deployment/validating-metadata.mdx",
"content/docs/deployment/cli.mdx"
],
"file_surface_breach": false,
"commits": 1,
"drifts": {
"a_heading_rename": {
"sites_moved": 3,
"detail": [
"validating-metadata.mdx:349 heading: '## The one gate, three entry points' -> '## The one gate, four doors'",
"cli.mdx:458 anchor fragment: '#the-one-gate-three-entry-points' -> '#the-one-gate-four-doors'",
"cli.mdx:458 link text: 'The one gate, three entry points' -> 'The one gate, four doors'"
],
"repo_wide_grep": "grep for 'the-one-gate-three-entry-points' and 'one gate, three entry' over the whole tree -> exactly 2 sites, both inside the ruled file surface. Nothing to widen to, no STOP condition hit. The 3 packages/spec hits for the bare phrase 'three entry points' are about npm package exports, unrelated.",
"anchor_verified_by": "this repo's own github-slugger@2.0.0: slug('The one gate, four doors') === 'the-one-gate-four-doors' === the fragment cli.mdx now links",
"residual_old_refs": 0
},
"b_transcript_count": {
"before": "-> Running author-time rules (26)...",
"after": "-> Running author-time rules (38)...",
"measured_value": 38,
"how_counted": "Executed the live registry (temp vitest in packages/lint, deleted after). The transcript line is printed by packages/cli/src/commands/validate.ts:117 as `Running author-time rules (${registered.length})` where registered = authoringRulesFor('validate') = AUTHORING_RULES.filter(r => r.commands.includes('validate')) — NOT the raw table length.",
"measurements": {
"AUTHORING_RULES.length": 38,
"authoringRulesFor('validate')": 38,
"authoringRulesFor('build')": 38,
"authoringRulesFor('lint')": 35,
"distinct_rule_ids": "n/a — entries key on `name`, there is no `id`/`ids` field on AuthoringRule (keys: name, tier, input, commands, source, surfaces, runtimeTypes, run)"
},
"note": "The doc transcript is a '◆ Validate' run, so 38 is what that command would actually print. The two quantities coincide today only because every entry runs on validate; an `os lint` transcript would have to say 35.",
"pm_assumption_38": "CONFIRMED, but for a narrower reason than dispatch stated — 38 is right here because it is the validate-filtered count, not merely because the table holds 38 entries.",
"deliberately_unchanged": "validating-metadata.mdx:466 '23 of 26 rules' — a statement about the #4409 audit, i.e. correct history, not drift."
},
"c_retired_rule": {
"removed": "cli.mdx:473 — 'deprecated visibility aliases' dropped from the os lint advisory list",
"liveness_check": "grep for visibility-alias-deprecated / visibilityAliasDeprecated across the tree (node_modules and dist excluded): every hit is commentary ABOUT the retirement (validate-visibility-predicates.ts:14,631; authoring-rules.ts:242,796), a test pinning it retired (authoring-rule-input-tier.test.ts:218; validate-visibility-predicates.test.ts:43), a CHANGELOG entry, or the changeset. No live rule. Changesets/CHANGELOG were NOT counted as live code."
}
},
"pm_assumptions": {
"A1_heading_should_say_four": "FALSIFIED AS WORDED, and re-decided. Chose '## The one gate, four doors', NOT 'four entry points'. The section's own prose forbids the latter: it introduces the fourth as 'There is a fourth door, and it is not a command', and the sentence directly under the heading enumerates the three *commands* — so 'entry point', which meant a CLI invocation, would be false of a saveMetaItem write path in the same way the old heading was false. 'Door' is the noun the section already uses for the superset (4 occurrences) and matches the 4 table columns. The later 'not one of four — it is the only one' is a perspective note about one author's reachable surface, not a competing count; it reads correctly unchanged under the new heading.",
"A2_three_drifts_independent": "CONFIRMED by inspection, not assumed. Enumerated every 'three'/'four'/26/38 in both files: all remaining 'three' references are 'the three commands' / 'all three' (still true — the runtime door is not a command), and the historical '23 of 26' is correct as history. No neighbouring sentence becomes false under the rename. No #7458-style knock-on (the ✓ᶠ/✓ᵛ legend is about metadata types, untouched by a heading rename)."
},
"gates": [
{"gate": "doc authoring", "invocation": "pnpm check:doc-authoring", "result": "PASS — self-test + 374 files clean, no bare metadata literals"},
{"gate": "doc formula expressions", "invocation": "pnpm --filter @objectstack/lint run check:doc-formula-expressions", "result": "PASS — 24 self-test cases; 22 record-scoped examples across 389 files + 9 spec TSDoc examples clean"},
{"gate": "NUL bytes", "invocation": "node scripts/check-nul-bytes.mjs", "result": "PASS — 6981 text files scanned, no raw ASCII control bytes"},
{"gate": "ADR cross-links (step 1 of the Check Documentation Links job)", "invocation": "node scripts/check-adr-links.mjs --self-test && node scripts/check-adr-links.mjs", "result": "PASS — 524 relative destinations resolve"},
{"gate": "Check Documentation Links (lychee, step 2)", "invocation": "lychee 0.24.2 (downloaded to match the action's pin) with the workflow's exact argv: --offline --root-dir <ws>/content --fallback-extensions mdx,md --config lychee.toml 'content/**/*.md' 'content/**/*.mdx' README.md ARCHITECTURE.md", "result": "PASS — 1756 total / 775 unique / 1525 OK / 0 errors / 231 excluded"}
],
"gate_premise_falsified": {
"claim": "the link gate is 'the only mechanical check that can catch a half-done rename'",
"verdict": "FALSE — it cannot catch one at all",
"evidence": "lychee.toml sets include_fragments = \"none\" (with an in-file comment explaining that a bare `false` is a hard parse error on the pinned 0.24.2). I did not trust the comment: I planted a probe file linking /docs/deployment/validating-metadata#this-anchor-does-not-exist-at-all and ran the CI argv against it — reported '[200] ... OK', 0 errors, then deleted the probe. lychee resolves the FILE target only.",
"consequence": "The anchor half of this rename is verified by the github-slugger computation and the zero-residual grep above, NOT by any CI gate. A future half-done rename in this repo will go green in CI.",
"recommend": "worth a separate card — an anchor-resolution check (or flipping include_fragments once the advisory lane has its green streak). Not filed; not this card's surface."
},
"dispatch_corrections": [
"`pnpm --filter @objectstack/lint run check:doc-authoring` does not exist — check:doc-authoring is a ROOT script (package.json:38). Ran `pnpm check:doc-authoring`. check:doc-formula-expressions IS on @objectstack/lint and ran as quoted.",
"The branch name was already checked out on the SHARED primary checkout at /home/user/objectstack (at origin/main, zero unique commits). Detached that checkout and moved the name onto a dedicated worktree so no edit ever landed on the shared tree.",
"Local `pnpm build` emits JS but DTS builds fail across several packages (e.g. packages/lint: '@objectstack/spec/data' subpath types unresolved). Pre-existing on a clean origin/main tree with zero edits — NOT caused by this change, and it does not touch this docs-only PR. Recording it, not chasing it."
],
"out_of_surface_findings": [
"The stale 26 also survives in two CODE comments, outside this card's ruled file surface and outside its docs-only shape — packages/objectql/src/plugin.ts:76 ('the 26 shared AUTHORING_RULES') and packages/metadata-protocol/src/protocol.ts:2542 ('all 26 shared AUTHORING_RULES'). Not touched, not filed; recorded here so they stay discoverable after this card closes."
],
"ci": "in_progress — reported at draft-PR time per dispatch ruling 3; PM owns CI convergence, the ready-flip and landing. No idle-polling done.",
"open_questions": [
{
"q": "Heading wording — 'four doors' vs the dispatch's 'four entry points'.",
"recommendation": "Keep 'four doors'. It is the section's own vocabulary, it is the only phrasing that is true of all four table columns, and it leaves the 'not one of four — it is the only one' sentence coherent. Flagging because the dispatch named a different string and the PM may prefer the anchor to read 'entry points' for continuity — but that continuity is exactly what made the old heading wrong.",
"blocking": false
},
{
"q": "Should the two stale '26' code comments (objectql/plugin.ts, metadata-protocol/protocol.ts) get their own card?",
"recommendation": "Yes, an observation-class one — same drift, different surface. Not filed from this seat since #7465 is docs-only and filing is the triage seat's call.",
"blocking": false
},
{
"q": "Should the anchor-blindness of the link gate be filed?",
"recommendation": "Yes — it is a gate-coverage hole, sharper than any of the three drifts this card fixed, and this card is the second one in a row (#7442, #7465) whose central risk that gate cannot see. Not filed from this seat.",
"blocking": false
}
]
}
ACCEPTED — PR #7483, two files, +4/−5, one commit as ruled. skip-changeset applied at accept time; mergeable_stateclean; undrafted and armed.
All three fixes verified on the branch by content, not by the report's say-so: heading ## The one gate, four doors, cli.mdx:458 carrying both the new anchor fragment and the matching link text, Running author-time rules (38), the retired item gone, and zero residual the-one-gate-three-entry-points anywhere under content/.
The heading choice was the dev's call and it is better than the one I would have made
I left A1 open and warned that "four entry points" was probably also wrong. The answer — "four doors" — is argued from the section's own text rather than from taste: the section introduces the fourth as "There is a fourth door, and it is not a command", the sentence under the heading enumerates the three commands, and "door" is already the noun the section uses for the superset. It also disposed of the objection I raised: the later "that door is not one of four — it is the only one" is a perspective note about one author's reachable surface, not a competing count, so it stays true under the new heading.
The count was right for a reason I had not measured
My dispatch said 38 as a PM assumption to falsify. It survived — but the dev found the right reason, which is not the one I had: that transcript line is printed by packages/cli/src/commands/validate.ts:117 as authoringRulesFor('validate').length, notAUTHORING_RULES.length.
AUTHORING_RULES.length = 38
authoringRulesFor('validate') = 38 ← what this transcript prints
authoringRulesFor('lint') = 35
They coincide today only because every entry currently runs on validate. An os lint transcript would have to say 35. That is the ㊽ shape one layer in: not "is the number stale" but "which quantity is this line even printing".
⚠️ It falsified my patrol criterion, and the correction is load-bearing
I wrote that the docs-link gate was "the one gate that can mechanically catch a half-done rename" and told the next patrol to read its CI conclusion before arming. That is false.lychee.toml sets include_fragments = "none", and the dev did not take that from the config comment — it probed the pinned lychee 0.24.2 under the CI argv with a link to …#this-anchor-does-not-exist-at-all and got [200] ✅ OK. The gate resolves the file target only.
So no CI gate in this repo checks documentation anchors. What actually verifies this rename is (a) the slug computed with the repo's own github-slugger@2.0.0 — slug("The one gate, four doors") → the-one-gate-four-doors — and (b) the repo-wide grep showing no residual references. Both were done. Filing the gap separately; ⛔ not riding it onto this PR.
Out-of-surface drift, correctly left alone
The stale 26 also survives in two code comments — packages/objectql/src/plugin.ts:76 and packages/metadata-protocol/src/protocol.ts:2542. Outside this card's file surface and outside its docs-only shape. Recorded in the PR body and being filed, rather than widened into this diff.
Activity
claude commentedon Aug 10, 2026
Triage:
finding+domain:spec-tooling(observation-class docs-drift cluster; filer's grading holds).Landing + anchors (read on
origin/main@603cab8, not a worktree): all three drifts are live —content/docs/deployment/validating-metadata.mdx:349still reads## The one gate, three entry points, andcontent/docs/deployment/cli.mdx:458links the#the-one-gate-three-entry-pointsanchor — the paired-edit constraint is real (renaming the heading alone breaks the inbound link).validating-metadata.mdx:471transcript readsRunning author-time rules (26)...whilepackages/lint/src/authoring-rules.tsholds 38 top-level entries on main (counted, not quoted).cli.mdx:473still listsdeprecated visibility aliases;visibility-alias-deprecatedis retired — live code greps only hit changesets/CHANGELOG (visibility-alias-deprecated-retired.md), no live rule.Routing rationale: the fix lands entirely in the two hand-written gate-docs pages; they document the metadata authoring/contract gate (
AUTHORING_RULES,os lint—packages/lint), i.e. tooling that revolves around the spec contract ⇒domain:spec-toolingper the #5469 split criterion. Direct precedent: #7442 (same file, same gate table) ran asdomain:spec-tooling.Dedup: local sweep over all open issues in the three repos for
cli.mdx/validating-metadata/author-time rules— no overlapping card (only this one; falsified the zero-hit with a known-present neighbour term). #7442 is closed via PR #7458 and deliberately excluded these three.Release grading: no
target:*— docs/display class (a mis-counted heading, a stale quoted transcript, one stale report line); nobody is blocked today, same grading family as #7307.本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
claude commentedon Aug 10, 2026
Findings triage: PROMOTED —
finding→pm:queue(lane labeldomain:spec-toolingalready in place).All three drifts re-verified live on
origin/main@ 333769d: the stale headingcontent/docs/deployment/validating-metadata.mdx:349("three entry points", four doors since #4463 P1) with its inbound anchorcontent/docs/deployment/cli.mdx:458; the stale transcript count atvalidating-metadata.mdx:482("Running author-time rules (26)"); and the retireddeprecated visibility aliasesrule still listed atcli.mdx:473(retired by #6318). This is a scoped docs-gate fix with named locations and a mechanical paired-edit shape (heading + anchor in one commit) — nothing left to rule. Nottarget:v17: advisory docs drift, none of the four blocking classes. Dedup from the filing thread stands (no overlapping open card or PR found this round).本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
os-help commentedon Aug 10, 2026
Claim: PM loop round 11 —
domain:spec-toolingseat (#6018)Session:
session_01KJATVrh6V2ysutYUJigh3BBranch:
claude/issue-7465-gate-docs-drift-clusterDomain:
domain:spec-toolingFile surface:
content/docs/deployment/validating-metadata.mdx+content/docs/deployment/cli.mdx. Both, in one commit — that is the point of the card, not an incidental pairing. Stop on breach; explain in the report.Container & model: S-size, NOT mechanical — one of the three fixes is a live count that no gate can judge, and the rename is a multi-site coordinated edit whose failure mode is a silently broken link. Per the 2026-08-10 sizing ruling this takes M treatment:
mode:cloudsingle container,model: opus. Same shape and precedent as #7442.Serial constraints cleared: no open PR touches either page;
validating-metadata.mdxlast landed45cd354ec/#7458 (this lane, ~14:2xZ) andcli.mdxis untouched since. Neither is under themerge=os-regentree, so a hand edit is not regenerated away.Premises re-verified live on
origin/mainbefore claiming — and one number re-measured at dispatch time rather than quoted (㊽):validating-metadata.mdx:349—## The one gate, three entry points✅cli.mdx:458—[The one gate, three entry points](/docs/deployment/validating-metadata#the-one-gate-three-entry-points)✅validating-metadata.mdx:482—→ Running author-time rules (26)...✅origin/mainjust now, ⛔ not taken from triage's commentcli.mdx:473—deprecated visibility aliases, …)✅ (visibility-alias-deprecatedretired by #6318)Label pair applied atomically (
pm:dispatchedin the same write that removedpm:queue, #7239).Generated by Claude Code
os-help commentedon Aug 10, 2026
os-dev report — #7465 (
domain:spec-toolingseat #6018, sessionsession_01KJATVrh6V2ysutYUJigh3B){ "issue": 7465, "status": "implemented", "branch": "claude/issue-7465-gate-docs-drift-cluster", "worktree": "/home/user/objectstack-7465 (dedicated, off origin/main @ a76a3af)", "commit": "bd5d66a", "pr": 7483, "pr_url": "https://github.com/objectstack-ai/objectstack/pull/7483", "pr_state": "draft", "changeset": "none — docs-only; skip-changeset is the PM's to apply at accept time", "files_changed": [ "content/docs/deployment/validating-metadata.mdx", "content/docs/deployment/cli.mdx" ], "file_surface_breach": false, "commits": 1, "drifts": { "a_heading_rename": { "sites_moved": 3, "detail": [ "validating-metadata.mdx:349 heading: '## The one gate, three entry points' -> '## The one gate, four doors'", "cli.mdx:458 anchor fragment: '#the-one-gate-three-entry-points' -> '#the-one-gate-four-doors'", "cli.mdx:458 link text: 'The one gate, three entry points' -> 'The one gate, four doors'" ], "repo_wide_grep": "grep for 'the-one-gate-three-entry-points' and 'one gate, three entry' over the whole tree -> exactly 2 sites, both inside the ruled file surface. Nothing to widen to, no STOP condition hit. The 3 packages/spec hits for the bare phrase 'three entry points' are about npm package exports, unrelated.", "anchor_verified_by": "this repo's own github-slugger@2.0.0: slug('The one gate, four doors') === 'the-one-gate-four-doors' === the fragment cli.mdx now links", "residual_old_refs": 0 }, "b_transcript_count": { "before": "-> Running author-time rules (26)...", "after": "-> Running author-time rules (38)...", "measured_value": 38, "how_counted": "Executed the live registry (temp vitest in packages/lint, deleted after). The transcript line is printed by packages/cli/src/commands/validate.ts:117 as `Running author-time rules (${registered.length})` where registered = authoringRulesFor('validate') = AUTHORING_RULES.filter(r => r.commands.includes('validate')) — NOT the raw table length.", "measurements": { "AUTHORING_RULES.length": 38, "authoringRulesFor('validate')": 38, "authoringRulesFor('build')": 38, "authoringRulesFor('lint')": 35, "distinct_rule_ids": "n/a — entries key on `name`, there is no `id`/`ids` field on AuthoringRule (keys: name, tier, input, commands, source, surfaces, runtimeTypes, run)" }, "note": "The doc transcript is a '◆ Validate' run, so 38 is what that command would actually print. The two quantities coincide today only because every entry runs on validate; an `os lint` transcript would have to say 35.", "pm_assumption_38": "CONFIRMED, but for a narrower reason than dispatch stated — 38 is right here because it is the validate-filtered count, not merely because the table holds 38 entries.", "deliberately_unchanged": "validating-metadata.mdx:466 '23 of 26 rules' — a statement about the #4409 audit, i.e. correct history, not drift." }, "c_retired_rule": { "removed": "cli.mdx:473 — 'deprecated visibility aliases' dropped from the os lint advisory list", "liveness_check": "grep for visibility-alias-deprecated / visibilityAliasDeprecated across the tree (node_modules and dist excluded): every hit is commentary ABOUT the retirement (validate-visibility-predicates.ts:14,631; authoring-rules.ts:242,796), a test pinning it retired (authoring-rule-input-tier.test.ts:218; validate-visibility-predicates.test.ts:43), a CHANGELOG entry, or the changeset. No live rule. Changesets/CHANGELOG were NOT counted as live code." } }, "pm_assumptions": { "A1_heading_should_say_four": "FALSIFIED AS WORDED, and re-decided. Chose '## The one gate, four doors', NOT 'four entry points'. The section's own prose forbids the latter: it introduces the fourth as 'There is a fourth door, and it is not a command', and the sentence directly under the heading enumerates the three *commands* — so 'entry point', which meant a CLI invocation, would be false of a saveMetaItem write path in the same way the old heading was false. 'Door' is the noun the section already uses for the superset (4 occurrences) and matches the 4 table columns. The later 'not one of four — it is the only one' is a perspective note about one author's reachable surface, not a competing count; it reads correctly unchanged under the new heading.", "A2_three_drifts_independent": "CONFIRMED by inspection, not assumed. Enumerated every 'three'/'four'/26/38 in both files: all remaining 'three' references are 'the three commands' / 'all three' (still true — the runtime door is not a command), and the historical '23 of 26' is correct as history. No neighbouring sentence becomes false under the rename. No #7458-style knock-on (the ✓ᶠ/✓ᵛ legend is about metadata types, untouched by a heading rename)." }, "gates": [ {"gate": "doc authoring", "invocation": "pnpm check:doc-authoring", "result": "PASS — self-test + 374 files clean, no bare metadata literals"}, {"gate": "doc formula expressions", "invocation": "pnpm --filter @objectstack/lint run check:doc-formula-expressions", "result": "PASS — 24 self-test cases; 22 record-scoped examples across 389 files + 9 spec TSDoc examples clean"}, {"gate": "NUL bytes", "invocation": "node scripts/check-nul-bytes.mjs", "result": "PASS — 6981 text files scanned, no raw ASCII control bytes"}, {"gate": "ADR cross-links (step 1 of the Check Documentation Links job)", "invocation": "node scripts/check-adr-links.mjs --self-test && node scripts/check-adr-links.mjs", "result": "PASS — 524 relative destinations resolve"}, {"gate": "Check Documentation Links (lychee, step 2)", "invocation": "lychee 0.24.2 (downloaded to match the action's pin) with the workflow's exact argv: --offline --root-dir <ws>/content --fallback-extensions mdx,md --config lychee.toml 'content/**/*.md' 'content/**/*.mdx' README.md ARCHITECTURE.md", "result": "PASS — 1756 total / 775 unique / 1525 OK / 0 errors / 231 excluded"} ], "gate_premise_falsified": { "claim": "the link gate is 'the only mechanical check that can catch a half-done rename'", "verdict": "FALSE — it cannot catch one at all", "evidence": "lychee.toml sets include_fragments = \"none\" (with an in-file comment explaining that a bare `false` is a hard parse error on the pinned 0.24.2). I did not trust the comment: I planted a probe file linking /docs/deployment/validating-metadata#this-anchor-does-not-exist-at-all and ran the CI argv against it — reported '[200] ... OK', 0 errors, then deleted the probe. lychee resolves the FILE target only.", "consequence": "The anchor half of this rename is verified by the github-slugger computation and the zero-residual grep above, NOT by any CI gate. A future half-done rename in this repo will go green in CI.", "recommend": "worth a separate card — an anchor-resolution check (or flipping include_fragments once the advisory lane has its green streak). Not filed; not this card's surface." }, "dispatch_corrections": [ "`pnpm --filter @objectstack/lint run check:doc-authoring` does not exist — check:doc-authoring is a ROOT script (package.json:38). Ran `pnpm check:doc-authoring`. check:doc-formula-expressions IS on @objectstack/lint and ran as quoted.", "The branch name was already checked out on the SHARED primary checkout at /home/user/objectstack (at origin/main, zero unique commits). Detached that checkout and moved the name onto a dedicated worktree so no edit ever landed on the shared tree.", "Local `pnpm build` emits JS but DTS builds fail across several packages (e.g. packages/lint: '@objectstack/spec/data' subpath types unresolved). Pre-existing on a clean origin/main tree with zero edits — NOT caused by this change, and it does not touch this docs-only PR. Recording it, not chasing it." ], "out_of_surface_findings": [ "The stale 26 also survives in two CODE comments, outside this card's ruled file surface and outside its docs-only shape — packages/objectql/src/plugin.ts:76 ('the 26 shared AUTHORING_RULES') and packages/metadata-protocol/src/protocol.ts:2542 ('all 26 shared AUTHORING_RULES'). Not touched, not filed; recorded here so they stay discoverable after this card closes." ], "ci": "in_progress — reported at draft-PR time per dispatch ruling 3; PM owns CI convergence, the ready-flip and landing. No idle-polling done.", "open_questions": [ { "q": "Heading wording — 'four doors' vs the dispatch's 'four entry points'.", "recommendation": "Keep 'four doors'. It is the section's own vocabulary, it is the only phrasing that is true of all four table columns, and it leaves the 'not one of four — it is the only one' sentence coherent. Flagging because the dispatch named a different string and the PM may prefer the anchor to read 'entry points' for continuity — but that continuity is exactly what made the old heading wrong.", "blocking": false }, { "q": "Should the two stale '26' code comments (objectql/plugin.ts, metadata-protocol/protocol.ts) get their own card?", "recommendation": "Yes, an observation-class one — same drift, different surface. Not filed from this seat since #7465 is docs-only and filing is the triage seat's call.", "blocking": false }, { "q": "Should the anchor-blindness of the link gate be filed?", "recommendation": "Yes — it is a gate-coverage hole, sharper than any of the three drifts this card fixed, and this card is the second one in a row (#7442, #7465) whose central risk that gate cannot see. Not filed from this seat.", "blocking": false } ] }Generated by Claude Code
os-help commentedon Aug 10, 2026
ACCEPTED — PR #7483, two files, +4/−5, one commit as ruled.
skip-changesetapplied at accept time;mergeable_stateclean; undrafted and armed.All three fixes verified on the branch by content, not by the report's say-so: heading
## The one gate, four doors,cli.mdx:458carrying both the new anchor fragment and the matching link text,Running author-time rules (38), the retired item gone, and zero residualthe-one-gate-three-entry-pointsanywhere undercontent/.The heading choice was the dev's call and it is better than the one I would have made
I left A1 open and warned that "four entry points" was probably also wrong. The answer — "four doors" — is argued from the section's own text rather than from taste: the section introduces the fourth as "There is a fourth door, and it is not a command", the sentence under the heading enumerates the three commands, and "door" is already the noun the section uses for the superset. It also disposed of the objection I raised: the later "that door is not one of four — it is the only one" is a perspective note about one author's reachable surface, not a competing count, so it stays true under the new heading.
The count was right for a reason I had not measured
My dispatch said 38 as a PM assumption to falsify. It survived — but the dev found the right reason, which is not the one I had: that transcript line is printed by
packages/cli/src/commands/validate.ts:117asauthoringRulesFor('validate').length, notAUTHORING_RULES.length.They coincide today only because every entry currently runs on
validate. Anos linttranscript would have to say 35. That is the ㊽ shape one layer in: not "is the number stale" but "which quantity is this line even printing".I wrote that the docs-link gate was "the one gate that can mechanically catch a half-done rename" and told the next patrol to read its CI conclusion before arming. That is false.
lychee.tomlsetsinclude_fragments = "none", and the dev did not take that from the config comment — it probed the pinned lychee 0.24.2 under the CI argv with a link to…#this-anchor-does-not-exist-at-alland got[200] ✅ OK. The gate resolves the file target only.So no CI gate in this repo checks documentation anchors. What actually verifies this rename is (a) the slug computed with the repo's own
github-slugger@2.0.0—slug("The one gate, four doors")→the-one-gate-four-doors— and (b) the repo-wide grep showing no residual references. Both were done. Filing the gap separately; ⛔ not riding it onto this PR.Out-of-surface drift, correctly left alone
The stale
26also survives in two code comments —packages/objectql/src/plugin.ts:76andpackages/metadata-protocol/src/protocol.ts:2542. Outside this card's file surface and outside its docs-only shape. Recorded in the PR body and being filed, rather than widened into this diff.Generated by Claude Code
docs(deployment): reconcile the gate section with the four doors, the…