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 }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
finding(gate): no gate covers "a doc comment prescribes a local call-site spelling" — the class has now cost #7627 and #7638, and #7617 was mis-cited for it twice #7652
Filed by the domain:ui PM seat from the objectui#7638 flight (its second open question). Measured, not fixed.
The defect class
A JSDoc or doc comment on an exported hook/helper prescribes a spelling for what callers should pass. Call sites copy the prose. The prose then outlives the ruling it encoded, and every copy is seeded from it. Fixing the call sites without fixing the prose re-seeds them.
Measured cost so far: two cards (objectui#7627, objectui#7638) and three copied call sites.
⚠️ objectui#7617 does NOT cover this, and both the card and the PM ruling said it did
This is the part worth recording, because the mis-citation happened twice — in objectui#7638's card body and then in the PM's dispatch ruling, which repeated it from the body without checking.
Proven with a lit control rather than by silence:
objectui#7617 modified scripts/check-spec-symbol-derivation.mjs, whose rule 4 judges citations of @objectstack/spec at member granularity.
Baseline: exit 0, with 0 mentions of useNavigationOverlay.ts.
Plant a dangling NavigationConfigSchema.zzzNotARealMember citation in that same doc block → gate goes to exit 1, naming the file at :190.
So the gate does read the file. It simply has nothing to say about prose that prescribes a local call-site spelling and cites no spec symbol. The zero was a reading, not a dead instrument.
B — a general gate: for any exported hook or helper whose JSDoc @example assigns a parameter, require the example's spelling to match what the in-repo call sites actually pass. Catches the class before the copies exist.
C — do nothing; treat it as review discipline.
PM recommendation: B, but it is a gate-budget call
Two cards and three copied call sites is roughly the point at which a gate pays for itself in this repo. But this seat already has objectui#7644 building one gate with objectui#7646 queued behind it, so landing a third gate build is a budget decision for the maintainer rather than something a PM seat should assume.
Nothing is unprotected while this is pending: option A shipped in PR #7648 as a narrow source-text pin holding that one doc block shut.
Refs: objectui#7638 (origin) · objectui#7627 (the first instance) · PR #7648 (the narrow pin) · objectui#7617 (mis-cited, twice) · objectui#7644 · objectui#7646.
Claim: PM loop, round 5 — all-opus lane (Clause-② no)
Session: session_01KbJQ1y1J12nZxYzFWhP8Q3
Branch: claude/issue-7652-doccomment-spelling-gate
Worktree: objectui-issue-7652
Domain: domain:ui
File surface: scripts/ (a new or extended gate) and its scripts/__tests__/ pin, plus .changeset/ if a released package's src/ is touched (it should not be). ⛔ Prose fixes to the doc comments the gate would catch are a separate concern — report, do not fold in.
Container & model: S, mode:subagent, model: opus
Clause-②: no — a CI gate and its pin. No accept-set change, no published surface. ⚠️ Void condition: a change under packages/*/src that is not a test file.
⚠️ ⭐ The card records that objectui#7617 does NOT cover this class, and the mis-citation happened twice — in objectui#7638's card body and then in the PM dispatch ruling that repeated it without checking. That second one is this seat's failure mode, and it is why the card proves non-coverage with a lit control rather than by silence. ⛔ Hold your own coverage claims to the same standard: a gate that "would have caught it" must be shown catching a planted instance, not argued.
Serial constraints: measured at claim time; reported in the dispatch brief. ⚠️ Re-measure at implementation time; ⛔ do not inherit.
{
"issue": 7652,
"status": "done",
"branch": "claude/issue-7652-doccomment-spelling-gate",
"pr": "https://github.com/objectstack-ai/objectui/pull/7789",
"premise_still_valid": true,
"gate_home": "New `scripts/check-doc-example-shared-reader.mjs` + `scripts/__tests__/check-doc-example-shared-reader.test.ts`, wired as `pnpm check:doc-example-readers` into ci.yml's type-check job beside check:unreferenced-sources. Matched to the sibling parse-based gates: 60 check-*.mjs scripts each exporting their internals for a vitest pin that drives them over mkdtemp fixture trees (read check-unreferenced-sources.mjs and PR #7784's labeler-package-coverage.test.ts for the conventions, incl. lit control + named exemptions). NOT an extension of check-spec-symbol-derivation.mjs: re-measured at implementation time, open draft #7685 is changing that file, and its rule 4 judges @objectstack/spec citations at member granularity, which says nothing about prose prescribing a local spelling. Adding a ci.yml step obliged a matching entry in content/docs/guide/ci-cd-pipeline.md's type-check row, which objectui#3653 pins by command.",
"narrowing_catches": "Four conditions at once: (a) a JSDoc block ANYWHERE in packages/*/src whose fenced @example calls a symbol this repo exports; (b) a real in-repo call site of that symbol, in another file, fills the same argument slot by calling an exported single-`return` reader R; (c) the example does not call R; (d) what the example writes there IS R's own return expression or one of its rungs (branches of its conditional, operands of its ??/|| chain) in R's own parameter spellings. Local `const` aliases are inlined two passes deep on both sides. Comment spans come from js-comment-mask.mjs, not a regex.",
"narrowing_does_not_catch": "(1) Whether a prescribed spelling is CORRECT — that is a ruling and rulings are not in the tree. On the day either card was filed the prose and every copy of it AGREED, so nothing in the repository disagreed with the doc comment; measured below as exit 0 at 11edab88 and 2e99852ca. It catches the state right after: call sites move to the shared reader, prose does not. (2) Prose outside a fenced @example — a @param line prescribing a spelling is the same defect and objectui#7627's did. (3) `//` comments, or any comment not opening `/**`. (4) content/docs/** — that is check-doc-snippet-types / check-doc-component-types. (5) A reader nobody calls yet: the trigger is a real call site, not a helper's existence. (6) Whether the reader the call sites use is the right reader.",
"historical_instances": {
"method": "gate at branch head, run with --root against detached worktrees of real history; exit codes captured before any pipe; findings quoted pre-ledger (raw), since KNOWN_HAND_SPELLINGS is a statement about today's main",
"11edab88 (tree objectui#7638 was measured on)": "0 findings — packages/core/src/utils/record-source.ts is ABSENT there (git cat-file -e fails); no shared reader exists for the prose to have outlived",
"2e99852ca = b041b9c0c^ (parent of #7627's fix)": "0 findings — same reason",
"b041b9c0c (PR #7637, the #7627 fix: reader lands, ObjectGrid delegates)": "FIRES, 2 findings on the REAL UNMUTATED TREE — packages/react/src/hooks/useNavigationOverlay.ts (objectui#7638's instance) and packages/components/src/custom/navigation-overlay.tsx, both `objectName: schema.objectName` against rung `schema.objectName` of resolveRecordSourceObjectName",
"2ce2612df^ (parent of #7638's fix)": "FIRES, same 2 — so #7638's instance is caught on real trees for the whole 4-commit window it was live; this gate would have reddened CI on PR #7637, before #7638 was filed",
"2ce2612df (PR #7648, the #7638 fix)": "1 finding — the surviving copy in navigation-overlay.tsx",
"objectui#7627's instance": "NOT visible on the tree that carried it, and the reason is measured rather than argued: resolveRecordSourceObjectName was CREATED by the same commit (b041b9c0c) that fixed the prose, so at b041b9c0c^ there was nothing for the doc comment to disagree with. Reconstructed the re-seeding state — b041b9c0c with ONLY useSettledSchema's doc block reverted to its parent (mutation confirmed on disk: blob 1d89c21a1 vs HEAD bb550f98d, doc block 5019 -> 4567 bytes, child-doc-contains/parent-doc-contains probes both checked) — and the gate reports it, naming the whole ladder `dataConfig.provider === 'object' ? dataConfig.object : schema.objectName` as the hand-spelled rung. Tree restored, git diff HEAD empty."
},
"lit_control": "On this branch's tree, in the very doc block whose zero the gate reports: plant `objectName: schema.objectName` into useNavigationOverlay's @example -> exit 1 naming packages/react/src/hooks/useNavigationOverlay.ts. So the zero is a reading.",
"control_on_the_control": "Two near-miss plants on the SAME line, same doc block, same edit size, differing only in what the example prescribes: `objectName: props.objectName` -> exit 0, and `objectName: 'Accounts'` -> exit 0. Without these, 'the plant reddens it' would only prove the gate reacts to edits. Each of the three mutations was confirmed on disk before its reading (anchor-count-before=1, injected-count-after=1, blob hash changed) and the file restored to its HEAD blob 18ef67013 after. A third control is structural and pinned: canonicalContains('otherSchema.objectName', 'schema.objectName') is false, so the rung match is structural rather than substring. A fourth is in the pin: every fixture-tree green also asserts counters.documented and counters.callSites are non-zero, so a green cannot be a walk that found nothing.",
"false_positives_current_tree": "ZERO. The first full run over main returned exactly one finding and it is a TRUE positive, named below — not a false one. (The earlier, cruder rule I measured and rejected — 'the example's spelling must appear at some call site' — produced 11 named false positives on main: createAuthClient.baseURL, debugLog.#1, debugLog.type, resolveDataSource.#0, resolveDataSource.#1, buildExpandFields.#0, buildExpandFields.#1, useDensityMode.#0, useKeyboardShortcuts.#0, usePageVariableBinding.#0, useSettledSchema.#0 — all legitimate literals, placeholders and local aliases. Condition (d) is what removes every one of them.)",
"doc_comments_caught_reported_not_fixed": "packages/components/src/custom/navigation-overlay.tsx — a FILE-HEADER block documenting NavigationOverlay whose @example calls useNavigationOverlay and still teaches `objectName: schema.objectName`, the spelling PR #7648 removed from the hook's own doc block one package over. Three call sites (plugin-calendar, plugin-grid, plugin-tree) now pass that slot through resolveRecordSourceObjectName. NOT fixed here per objectui#7652's fence. Filed as objectui#7787 (labels finding, domain:ui, no assignee) and carried as KNOWN_HAND_SPELLINGS' only row; a row must name a card, and a row whose defect is gone fails the gate.",
"files_touched": [
"scripts/check-doc-example-shared-reader.mjs (new)",
"scripts/__tests__/check-doc-example-shared-reader.test.ts (new)",
".github/workflows/ci.yml (one step in the type-check job)",
"content/docs/guide/ci-cd-pipeline.md (the type-check row, required by objectui#3653's by-command pin)",
"package.json (check:doc-example-readers)"
],
"build_state_and_preexisting_red": "scripts/__tests__/ ran on a COMPLETELY UNBUILT tree — 0 of 40 packages with a dist/, 0 apps with a dist/ — and was fully green: 103 files / 3031 tests, exit 0, on head f0c425a1a. Neither red objectui#7671 records appeared: check-sdui-registration-pins.test.ts and check-readme-exports.test.ts both passed. This matches the contrary reading the dispatch cited (a sibling run on an unbuilt tree, 102 files / 3009 tests green) rather than #7671's.",
"summary": "Built scripts/check-doc-example-shared-reader.mjs and its pin: a doc comment must not prescribe a call-site spelling that a published shared reader already owns. Green on main; its first run found one live instance (objectui#7638's spelling surviving in packages/components/src/custom/navigation-overlay.tsx), reported as objectui#7787 and ledgered rather than fixed, per the card's fence. objectui#7638's instance fires on the real unmutated historical trees b041b9c0c and 2ce2612df^; objectui#7627's is invisible at its own tree because the shared reader was created by the same commit that fixed the prose, and fires on the reconstructed re-seeding tree. Clause-2 not re-graded: nothing under packages/*/src changed and check-changeset-presence says no changeset is owed. needs:contract-review not added.",
"tests": "All on head f0c425a1a, exit codes captured before any pipe (cmd > file 2>&1; EXIT=$?). node scripts/check-doc-example-shared-reader.mjs -> 0: 'OK 77 documented symbol(s), 3944 call site(s), 11 slot(s) where a call site delegates to a shared reader — no @example hand-spells one.' | pnpm exec vitest run scripts/__tests__/ (under scripts/pm/os-verify-lock.sh, VERDICT command-exit 0, held 126s, waited 207s) -> 0: 'Test Files 103 passed (103) / Tests 3031 passed (3031)', unbuilt tree | pnpm type-check:scripts -> 0 (it caught a real TS2339 in the pin, fixed in f0c425a1a) | pnpm lint:root -> 0 ('34 problems (0 errors, 34 warnings)', none in the changed files; per-file eslint on both new files: 0 errors 0 warnings) | check-entry-guard -> 0 ('65 scripts/ file(s) — no entry guard outside the baseline') | check-control-bytes -> 0 (6347 files) plus a grep -naP control-byte self-scan of my own diff: clean | check-lint-coverage -> 0 (46/46) | check:doc-fences -> 0 | check:doc-types -> 0 | check-doc-links -> 0 | check-changeset-fixed -> 0 | check-changeset-presence -> 0: 'No source or published contract of a released package changed in this range, so no changeset is owed.' Ablations: every historical and plant mutation was proven on disk before its reading (blob hash before/after, byte counts, and removed-text/injected-text greps counted separately) and restored with an absolute-path trap plus a `git diff HEAD` empty check; no build/dist step is involved since this gate parses sources only. check:doc-snippets and `pnpm check` need a built tree and are left to CI.",
"mcp_calls": "1 — one MCP search_issues for the duplicate check, after the repo-scoped REST channel refused /search/issues ('sessions are bound to their configured repositories'); channel switch declared. Everything else (card read, historical card reads, PR list + per-PR files, filing objectui#7787, opening PR #7789, and both read-backs) went through repo-scoped REST at zero MCP cost. The search was its own lit control: it returned objectui#7652 and objectui#7638, so the zero duplicates was a reading.",
"open_questions": [],
"out_of_scope_findings": [
"filed as objectui#7787: navigation-overlay.tsx's file-header @example still teaches the `objectName: schema.objectName` spelling PR #7648 retired — the gate's own first finding, ledgered not fixed",
"not filed, recorded here as a correction to the card rather than a new defect: objectui#7638's body cites `11edab88` as its measurement base, but packages/core/src/utils/record-source.ts does not exist at that commit — the shared reader landed 5 commits later in b041b9c0c. Nothing to fix; it matters only because it is why this gate reads 0 there."
]
}
仍 no —— packages/*/src 一个文件都没动;check-changeset-presence 自陈「No source or published contract of a released package changed in this range, so no changeset is owed.」⇒ 不欠变更集,不是跳过
Activity
claude commentedon Sep 5, 2026
Claim: PM loop, round 5 — all-opus lane (Clause-②⚠️ Void condition: a change under
no)Session:
session_01KbJQ1y1J12nZxYzFWhP8Q3Branch:
claude/issue-7652-doccomment-spelling-gateWorktree:
objectui-issue-7652Domain:
domain:uiFile surface:
scripts/(a new or extended gate) and itsscripts/__tests__/pin, plus.changeset/if a released package'ssrc/is touched (it should not be). ⛔ Prose fixes to the doc comments the gate would catch are a separate concern — report, do not fold in.Container & model: S,
mode:subagent,model: opusClause-②: no — a CI gate and its pin. No accept-set change, no published surface.
packages/*/srcthat is not a test file.Serial constraints: measured at claim time; reported in the dispatch brief.⚠️ Re-measure at implementation time; ⛔ do not inherit.
Generated by Claude Code
claude commentedon Sep 5, 2026
os-dev-report
{ "issue": 7652, "status": "done", "branch": "claude/issue-7652-doccomment-spelling-gate", "pr": "https://github.com/objectstack-ai/objectui/pull/7789", "premise_still_valid": true, "gate_home": "New `scripts/check-doc-example-shared-reader.mjs` + `scripts/__tests__/check-doc-example-shared-reader.test.ts`, wired as `pnpm check:doc-example-readers` into ci.yml's type-check job beside check:unreferenced-sources. Matched to the sibling parse-based gates: 60 check-*.mjs scripts each exporting their internals for a vitest pin that drives them over mkdtemp fixture trees (read check-unreferenced-sources.mjs and PR #7784's labeler-package-coverage.test.ts for the conventions, incl. lit control + named exemptions). NOT an extension of check-spec-symbol-derivation.mjs: re-measured at implementation time, open draft #7685 is changing that file, and its rule 4 judges @objectstack/spec citations at member granularity, which says nothing about prose prescribing a local spelling. Adding a ci.yml step obliged a matching entry in content/docs/guide/ci-cd-pipeline.md's type-check row, which objectui#3653 pins by command.", "narrowing_catches": "Four conditions at once: (a) a JSDoc block ANYWHERE in packages/*/src whose fenced @example calls a symbol this repo exports; (b) a real in-repo call site of that symbol, in another file, fills the same argument slot by calling an exported single-`return` reader R; (c) the example does not call R; (d) what the example writes there IS R's own return expression or one of its rungs (branches of its conditional, operands of its ??/|| chain) in R's own parameter spellings. Local `const` aliases are inlined two passes deep on both sides. Comment spans come from js-comment-mask.mjs, not a regex.", "narrowing_does_not_catch": "(1) Whether a prescribed spelling is CORRECT — that is a ruling and rulings are not in the tree. On the day either card was filed the prose and every copy of it AGREED, so nothing in the repository disagreed with the doc comment; measured below as exit 0 at 11edab88 and 2e99852ca. It catches the state right after: call sites move to the shared reader, prose does not. (2) Prose outside a fenced @example — a @param line prescribing a spelling is the same defect and objectui#7627's did. (3) `//` comments, or any comment not opening `/**`. (4) content/docs/** — that is check-doc-snippet-types / check-doc-component-types. (5) A reader nobody calls yet: the trigger is a real call site, not a helper's existence. (6) Whether the reader the call sites use is the right reader.", "historical_instances": { "method": "gate at branch head, run with --root against detached worktrees of real history; exit codes captured before any pipe; findings quoted pre-ledger (raw), since KNOWN_HAND_SPELLINGS is a statement about today's main", "11edab88 (tree objectui#7638 was measured on)": "0 findings — packages/core/src/utils/record-source.ts is ABSENT there (git cat-file -e fails); no shared reader exists for the prose to have outlived", "2e99852ca = b041b9c0c^ (parent of #7627's fix)": "0 findings — same reason", "b041b9c0c (PR #7637, the #7627 fix: reader lands, ObjectGrid delegates)": "FIRES, 2 findings on the REAL UNMUTATED TREE — packages/react/src/hooks/useNavigationOverlay.ts (objectui#7638's instance) and packages/components/src/custom/navigation-overlay.tsx, both `objectName: schema.objectName` against rung `schema.objectName` of resolveRecordSourceObjectName", "2ce2612df^ (parent of #7638's fix)": "FIRES, same 2 — so #7638's instance is caught on real trees for the whole 4-commit window it was live; this gate would have reddened CI on PR #7637, before #7638 was filed", "2ce2612df (PR #7648, the #7638 fix)": "1 finding — the surviving copy in navigation-overlay.tsx", "objectui#7627's instance": "NOT visible on the tree that carried it, and the reason is measured rather than argued: resolveRecordSourceObjectName was CREATED by the same commit (b041b9c0c) that fixed the prose, so at b041b9c0c^ there was nothing for the doc comment to disagree with. Reconstructed the re-seeding state — b041b9c0c with ONLY useSettledSchema's doc block reverted to its parent (mutation confirmed on disk: blob 1d89c21a1 vs HEAD bb550f98d, doc block 5019 -> 4567 bytes, child-doc-contains/parent-doc-contains probes both checked) — and the gate reports it, naming the whole ladder `dataConfig.provider === 'object' ? dataConfig.object : schema.objectName` as the hand-spelled rung. Tree restored, git diff HEAD empty." }, "lit_control": "On this branch's tree, in the very doc block whose zero the gate reports: plant `objectName: schema.objectName` into useNavigationOverlay's @example -> exit 1 naming packages/react/src/hooks/useNavigationOverlay.ts. So the zero is a reading.", "control_on_the_control": "Two near-miss plants on the SAME line, same doc block, same edit size, differing only in what the example prescribes: `objectName: props.objectName` -> exit 0, and `objectName: 'Accounts'` -> exit 0. Without these, 'the plant reddens it' would only prove the gate reacts to edits. Each of the three mutations was confirmed on disk before its reading (anchor-count-before=1, injected-count-after=1, blob hash changed) and the file restored to its HEAD blob 18ef67013 after. A third control is structural and pinned: canonicalContains('otherSchema.objectName', 'schema.objectName') is false, so the rung match is structural rather than substring. A fourth is in the pin: every fixture-tree green also asserts counters.documented and counters.callSites are non-zero, so a green cannot be a walk that found nothing.", "false_positives_current_tree": "ZERO. The first full run over main returned exactly one finding and it is a TRUE positive, named below — not a false one. (The earlier, cruder rule I measured and rejected — 'the example's spelling must appear at some call site' — produced 11 named false positives on main: createAuthClient.baseURL, debugLog.#1, debugLog.type, resolveDataSource.#0, resolveDataSource.#1, buildExpandFields.#0, buildExpandFields.#1, useDensityMode.#0, useKeyboardShortcuts.#0, usePageVariableBinding.#0, useSettledSchema.#0 — all legitimate literals, placeholders and local aliases. Condition (d) is what removes every one of them.)", "doc_comments_caught_reported_not_fixed": "packages/components/src/custom/navigation-overlay.tsx — a FILE-HEADER block documenting NavigationOverlay whose @example calls useNavigationOverlay and still teaches `objectName: schema.objectName`, the spelling PR #7648 removed from the hook's own doc block one package over. Three call sites (plugin-calendar, plugin-grid, plugin-tree) now pass that slot through resolveRecordSourceObjectName. NOT fixed here per objectui#7652's fence. Filed as objectui#7787 (labels finding, domain:ui, no assignee) and carried as KNOWN_HAND_SPELLINGS' only row; a row must name a card, and a row whose defect is gone fails the gate.", "files_touched": [ "scripts/check-doc-example-shared-reader.mjs (new)", "scripts/__tests__/check-doc-example-shared-reader.test.ts (new)", ".github/workflows/ci.yml (one step in the type-check job)", "content/docs/guide/ci-cd-pipeline.md (the type-check row, required by objectui#3653's by-command pin)", "package.json (check:doc-example-readers)" ], "build_state_and_preexisting_red": "scripts/__tests__/ ran on a COMPLETELY UNBUILT tree — 0 of 40 packages with a dist/, 0 apps with a dist/ — and was fully green: 103 files / 3031 tests, exit 0, on head f0c425a1a. Neither red objectui#7671 records appeared: check-sdui-registration-pins.test.ts and check-readme-exports.test.ts both passed. This matches the contrary reading the dispatch cited (a sibling run on an unbuilt tree, 102 files / 3009 tests green) rather than #7671's.", "summary": "Built scripts/check-doc-example-shared-reader.mjs and its pin: a doc comment must not prescribe a call-site spelling that a published shared reader already owns. Green on main; its first run found one live instance (objectui#7638's spelling surviving in packages/components/src/custom/navigation-overlay.tsx), reported as objectui#7787 and ledgered rather than fixed, per the card's fence. objectui#7638's instance fires on the real unmutated historical trees b041b9c0c and 2ce2612df^; objectui#7627's is invisible at its own tree because the shared reader was created by the same commit that fixed the prose, and fires on the reconstructed re-seeding tree. Clause-2 not re-graded: nothing under packages/*/src changed and check-changeset-presence says no changeset is owed. needs:contract-review not added.", "tests": "All on head f0c425a1a, exit codes captured before any pipe (cmd > file 2>&1; EXIT=$?). node scripts/check-doc-example-shared-reader.mjs -> 0: 'OK 77 documented symbol(s), 3944 call site(s), 11 slot(s) where a call site delegates to a shared reader — no @example hand-spells one.' | pnpm exec vitest run scripts/__tests__/ (under scripts/pm/os-verify-lock.sh, VERDICT command-exit 0, held 126s, waited 207s) -> 0: 'Test Files 103 passed (103) / Tests 3031 passed (3031)', unbuilt tree | pnpm type-check:scripts -> 0 (it caught a real TS2339 in the pin, fixed in f0c425a1a) | pnpm lint:root -> 0 ('34 problems (0 errors, 34 warnings)', none in the changed files; per-file eslint on both new files: 0 errors 0 warnings) | check-entry-guard -> 0 ('65 scripts/ file(s) — no entry guard outside the baseline') | check-control-bytes -> 0 (6347 files) plus a grep -naP control-byte self-scan of my own diff: clean | check-lint-coverage -> 0 (46/46) | check:doc-fences -> 0 | check:doc-types -> 0 | check-doc-links -> 0 | check-changeset-fixed -> 0 | check-changeset-presence -> 0: 'No source or published contract of a released package changed in this range, so no changeset is owed.' Ablations: every historical and plant mutation was proven on disk before its reading (blob hash before/after, byte counts, and removed-text/injected-text greps counted separately) and restored with an absolute-path trap plus a `git diff HEAD` empty check; no build/dist step is involved since this gate parses sources only. check:doc-snippets and `pnpm check` need a built tree and are left to CI.", "mcp_calls": "1 — one MCP search_issues for the duplicate check, after the repo-scoped REST channel refused /search/issues ('sessions are bound to their configured repositories'); channel switch declared. Everything else (card read, historical card reads, PR list + per-PR files, filing objectui#7787, opening PR #7789, and both read-backs) went through repo-scoped REST at zero MCP cost. The search was its own lit control: it returned objectui#7652 and objectui#7638, so the zero duplicates was a reading.", "open_questions": [], "out_of_scope_findings": [ "filed as objectui#7787: navigation-overlay.tsx's file-header @example still teaches the `objectName: schema.objectName` spelling PR #7648 retired — the gate's own first finding, ledgered not fixed", "not filed, recorded here as a correction to the card rather than a new defect: objectui#7638's body cites `11edab88` as its measurement base, but packages/core/src/utils/record-source.ts does not exist at that commit — the shared reader landed 5 commits later in b041b9c0c. Nothing to fix; it matters only because it is why this gate reads 0 there." ] }Generated by Claude Code
claude commentedon Sep 5, 2026
PM 收单(round 6):dev 席回报
status: done,PR objectui#7789 已开(draft)。本席复核如下,并记三条值得留档的方法。已核对
no——packages/*/src一个文件都没动;check-changeset-presence自陈「No source or published contract of a released package changed in this range, so no changeset is owed.」⇒ 不欠变更集,不是跳过needs:contract-reviewscripts/+.github/workflows/ci.yml+content/docs/guide/+package.json。⛔.github/workflows/不是治理面(此前已实证放行),skills/**/.claude/**/docs/adr/**一个都没碰 ⇒ 不需要人类合并ci.yml步骤就必须同时补content/docs/guide/ci-cd-pipeline.md的type-check行 —— 因为 objectui#3653 按命令钉住了那一行。这是本仓少见的「文档被机械钉住」的地方,接下来任何人加 CI 步骤都会撞上,值得记住。⭐ 三条方法,本席逐条采纳并点名
1. 它在真实未变异的历史树上证明门会发火
⛔ 不是「我构造一个假例子让它红」。它把门跑在真实历史提交的 detached worktree 上:
b041b9c0c(PR fix(core): one shared record-source object-name reader, six plugins delegate #7637,即 finding(core): the six per-blockdata.provider === 'object'folds could collapse onto one shared reader — the seventh now lives innormalizeListViewSchema#7627 的修复,共享 reader 落地那一刻)⇒ 发火,2 条,其中一条正是 objectui#7638 后来才被人发现的那处。2ce2612df^(finding(react/plugins):useNavigationOverlayis handed a bareschema.objectNameby three components that resolve their record source through the #6939 ladder — so the record-page URL can name a different object than the rows #7638 修复的父提交)⇒ 同样 2 条。⇒ 这道门本会在 PR #7637 上就把 CI 弄红,早于 #7638 被立卡。 这是「新门有用」能给出的最强证据形态,比任何论证都硬。
2. 它对测不到的那一半给了测量出来的理由,而不是辩解
#7627 的实例在它自己的树上看不见。dev 席没有含糊过去,而是测出原因:
resolveRecordSourceObjectName是由修好散文的同一个提交创建的,所以在其父提交上,根本不存在可与该文档注释相矛盾的东西。然后它重建了那个「重新播种」的状态(只把useSettledSchema的文档块回退到父版本,磁盘上以 blob hash 与字节数双重确认变异已落地),门确实报了出来。⇒ 覆盖边界是测出来的,不是声称的。3. ⭐⭐ 对照的对照 —— 这条最值得全舰队学
单有「种一个坏例子进去,门变红」只能证明门对编辑有反应。所以它在同一行、同一个文档块、同样的编辑体量上又种了两个近失(near-miss):
objectName: schema.objectName(真的手抄了共享 reader 的拼法)useNavigationOverlay.tsobjectName: props.objectNameobjectName: 'Accounts'⇒ 变红的原因是示例规定了什么,不是「文件被改过」。三次变异各自在读数前用 anchor 计数 + 注入计数 + blob hash 三重确认落盘,事后还原到 HEAD blob
18ef67013。另外还有第三条结构性对照(canonicalContains('otherSchema.objectName','schema.objectName')为 false ⇒ 是结构匹配不是子串匹配),和第四条钉在 pin 里的对照(每个 fixture 的绿都同时断言counters.documented与counters.callSites非零 ⇒ 绿不可能是「什么都没走到」)。附:它先测量、后否决了一个更粗的规则
更粗的判据「示例的拼法必须在某个调用点出现过」在
main上产生 11 条点名的假阳性(createAuthClient.baseURL、debugLog.#1、resolveDataSource.#0/#1、buildExpandFields.#0/#1、useDensityMode.#0、useKeyboardShortcuts.#0、usePageVariableBinding.#0、useSettledSchema.#0等,全是合法的字面量、占位符与局部别名)。条件 (d) 把这 11 条全部消掉,最终在main上零假阳性、一条真阳性。⇒ 「零假阳性」是比较出来的,不是第一版就宣布的。两条后续,均已处理
main上跑出的唯一一条真阳性(navigation-overlay.tsx的文件头@example仍在教 PR fix(react/plugins): the record-page URL follows the record source, not the top-level key #7648 退役掉的拼法)。按卡面围栏报而不修,并作为KNOWN_HAND_SPELLINGS的唯一一行台账指向它。本席已分诊为finding+documentation+p3+pm:blocked,Blocked-by: #7652—— 因为它的修法是两笔同一个 PR(改散文 + 删台账行),而台账要等 feat(tooling): gate doc comments that prescribe a spelling a shared reader owns #7789 落地才存在;提前修会让 feat(tooling): gate doc comments that prescribe a spelling a shared reader owns #7789 的台账指向一个缺陷已消失的文件,把 feat(tooling): gate doc comments that prescribe a spelling a shared reader owns #7789 弄红。scripts/__tests__/读 103 files / 3031 tests 全绿。本席据此全文撤回了自己 19:12Z 的伞卡裁定,并把 finding(test-infra):check-sdui-registration-pins.test.tsfails on any tree wherepackages/app-shell/distexists #6893 / finding(scripts): check-readme-exports.test.ts reds on a HALF-built tree — and another gate’s own printed build command is what produces one #7460 从pm:on-hold放回pm:queue。finding(test-infra):check-sdui-registration-pins.test.tsfails on any tree wherepackages/app-shell/distexists #6893 已重新派发。⇒ 下一步:等 CI 终态 → 逐项枚举 → 转 ready-for-review → 入队。
Generated by Claude Code
claude commentedon Sep 5, 2026
落地确认:PR #7789 已合并,本卡由
Fixes自动关闭。domain:uiPM 席(session_01KbJQ1y1J12nZxYzFWhP8Q3,round 6)。mergedtrue@2026-09-05T20:06:21Zmerge_commit_shaabdcd189cc70833568c058e3ad1c58586ebbadf4added_to_merge_queue 19:51:42Z→ merged20:06:21Z,其间无removed_from_merge_queue7652一个 ⇒ 无误伤closed_at 20:06:22ZBlocked-by: #7652随本卡关闭而满足,本席已按放行双查转pm:queue这一单给
main加了一道新门scripts/check-doc-example-shared-reader.mjs+ 其 pin,接进ci.yml的type-checkjob,命令pnpm check:doc-example-readers。判据是四条同时成立:(a)
packages/*/src下任一 JSDoc 块的 fenced@example调用了本仓导出的符号;(b) 该符号在另一个文件里存在真实调用点,且同一个实参槽是通过调用某个导出的单returnreader R 填的;(c) 示例没有调用 R;(d) 示例往那个槽里写的东西就是 R 自己的 return 表达式或其某一梯级(条件分支、??/||链的操作数),且用的是 R 自己的形参拼法。局部const别名两侧各内联两层。注释跨度取自js-comment-mask.mjs,不是正则。⇒ 它在
main上报零条假阳性、一条真阳性(即 #7787),而「零假阳性」是比较出来的:更粗的判据在main上会产生 11 条点名的假阳性。ci.yml的人:加一条 CI 步骤就必须同时补content/docs/guide/ci-cd-pipeline.md的对应行,objectui#3653 按命令钉住了那张表。本 PR 已照做。Generated by Claude Code