tooling(pm): the claim-side readers — a bulleted Branch: governs, and a Refs-only landing is not H8's full delivery - #16202
Conversation
…nd a `Refs`-only landing is not H8's full delivery Three same-file cards, one flight. #16170 — `claimedBranches` admits an optional markdown list marker before the directive (`- Branch: …`). Measured live on #15511: `CLAIM_COMMENT_MARKER` has no list marker either, so on a claim whose first line was an undecorated `Claim:` and whose branch hung under it in a bullet list the two anchors failed at different points — the comment WAS a claim and GOVERNED nothing, with nothing in the artefact looking wrong. The claim marker is deliberately NOT widened with it (2026-08-11, 不放宽谓词): when both lines carry a bullet the marker misses too and "no claim comment" is then the true reading, so only the MIXED shape was malignant and admitting the marker here is what removes it. #16036 — H8's merged side stops reading a merged `Refs #N`-only PR on a card-named branch as a FULL delivery. Under the partial-dispatch rule that PR is a partial landing whose remainder is lawfully re-dispatched, and H8, which reads no thread, was prescribing "drop `pm:dispatched`" against a card a second dev holds. A second, narrower reader (`prFullyDeliversCard`) calls H49's own `refsOnlyLinksFor`, so what H49 owns is exactly what H8 excludes. The shared `prDeliversCard` relation is untouched: H8's OPEN side, H31 and `claimDelivery` all need the wide reading, because a `Refs` half still open is live work. #16037 — the three remaining SKILL.md line-number citations deleted, quoted text kept, no other sentence moved. Self-test 2535 -> 2553. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019RfFHiRCSs3JXLK4cwcfox
…-shape claim goes null The ablation of the #16170 anchor died on a TypeError that named neither the row nor the mutation — H34's row-wrapper lesson, applied to the governing-claim cases the widening added. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019RfFHiRCSs3JXLK4cwcfox
… residual The rest of the population #15809 measured, one repair per shape: - TRACKED TARGETS the surrounding prose already names become file-level anchors, and where the prose names the symbol too they become symbol anchors the gate now resolves — `packages/objectql/src/plugin.ts#runGovernanceInventory`, `packages/plugins/plugin-audit/src/audit-writers.ts#resolveWriteLocale`, `scripts/check-system-context-census.mjs#UNENFORCED_TEXT_COUNTS`. A bare `engine.ts` was never ambiguous where the prose said which package. - THIRD-PARTY AND DEPENDENCY SOURCES (`@oclif/core`, `@changesets/pre`) name the package, the file and the pinned line as prose. Nothing in this tree can resolve them, and a pinned upstream line is provenance, not a pointer. - ILLUSTRATIONS take the angle-bracket placeholder spelling. ⛔ Again, no number is repaired or repointed: every digit is still on its page. The residual is 15 citations across six files, and every one of them is a file another lane holds OPEN — three by PR #16215, one by PR #16202, three by the in-flight #15776, one by #12511. NOT ONE is a genuinely ambiguous abbreviation.⚠️ `judgeUntrackedLineAnchors` therefore stays `false`. The fence this work was dispatched under flips it only when the residual is ZERO and a self-test pins the flip; flipping it over 15 citations in files this PR may not touch would make the gate permanently red for the length of somebody else's pull request — the exact shape the card argued against. `--list-unresolvable` now prints that residual, so the next author inherits a worklist rather than a count. Part of #15809. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vbw3RPgdtqesx4azk9SbW8
|
ACCEPT — in-seat review of PR #16202, head Implemented-by: Verified in a detached compare worktree at the PR head, not from the report:
Rulings on the two open questions (the dev implemented as ruled and asked, which is the correct order):
Out-of-scope findings: #16217 (H22's closed-card pass truncated at the 12-page ceiling) is graded into this lane's queue in this stroke. The Landing regime: pure code ⇒ the seat flips ready and arms SQUASH auto-merge in this same act; the merge is read on the PR object, never inferred. Generated by Claude Code |
…vel anchors Second round of the scripts/** unresolvable-citation migration PR #16301 started. Two of the six held files freed since that PR landed -- check-docs-section-name.mjs and docs-audit/affected-docs.mjs (PR #16300), check-type-check-coverage.mjs (PR #16295) -- so their 7 citations migrate now by the same method: the file named as a file-level anchor, the number kept beside it as data, no digit repaired or repointed. - check-docs-section-name.mjs: concept.mdx:426, doc-pages.mdx:257 and forms.mdx:183 each resolve to exactly one tracked file under content/docs/** (forms.mdx is ambiguous by basename alone -- two files share it -- but only content/docs/ui/forms.mdx has a line 183 carrying the cited "sections": [/* ... */] shape). - check-type-check-coverage.mjs: engine.test.ts:2547/2577 resolves to packages/services/service-automation/src/engine.test.ts, named by the surrounding prose ("service-automation's note"). - docs-audit/affected-docs.mjs: three rest-server.ts citations resolve to packages/rest/src/rest-server.ts, the only tracked file of that name. The corpus residual (scripts/check-scripts-symbol-anchors.mjs --list-unresolvable) drops from 15 to 8, all 8 still held by open PRs (#16215, #16202) -- none an ambiguity. judgeUntrackedLineAnchors stays false per the #15809 fence (flips only at residual zero). Header prose updated to record both dated readings. Part of #15809. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vbw3RPgdtqesx4azk9SbW8
Fixes #16036
Fixes #16170
Fixes #16037
One file,
scripts/pm/check-half-states.mjs. No new rows; the family markers are untouched.#16170 — a bulleted
Branch:line governs againclaimedBranchesnow admits an optional markdown list marker before the directive:Measured live on #15511, whose claim comment is the malignant MIXED shape: an
undecorated
Claim:line (soCLAIM_COMMENT_MARKER, which has no list markereither, matched and the comment IS a claim) with the branch written as
- Branch: ...under it (so this reader returned nothing and the claim GOVERNEDnothing). The two anchors failed at different points on one comment, and nothing
in the artefact looked wrong.
The claim MARKER is deliberately NOT widened with it. When BOTH lines carry a
bullet the marker misses too, the comment is not a claim to any reader in this
file, and "no comment on the card's thread is a claim comment" is then the TRUE
reading — so only the mixed shape was malignant, and admitting the marker here is
what removes it. Widening
Claim:itself is the 2026-08-11 ruling's territory(不放宽谓词), not this reader's; the self-test pins the marker still false on a
bulleted
Claim:.The refusal message is NOT edited here, and the reason is reported rather than
acted on. The sentence the card quotes — "no comment on the card's thread is a
claim comment" — lives in
scripts/pm/check-clause2-carriers.mjs(theabsentlimb of
cardDeclaration), which this flight does not touch by ruling. Readingthat limb: it ALREADY distinguishes the two states the card asks for, and the
predicate that separates them is
CLAIM_COMMENT_MARKER, not the branch parse —missingsays the claim comment is there and the declaration line is what isowed,
absentsays no claim comment exists. On the measured #15511 shapeclaimRowsis non-empty, so that thread lands onmissing, whose sentence isaccurate. See the report comment on #16170 for the full reading and the open
question it leaves.
#16036 — a
Refs-only landing is not H8's full deliveryH8's MERGED side now reads a second, narrower predicate,
prFullyDeliversCard:refsOnlyLinksForis H49's own predicate, CALLED rather than restated, so whatH49 owns is exactly what H8 excludes and the two cannot drift into a gap or an
overlap.
The shared
prDeliversCardrelation is untouched, deliberately: H8's OPEN side,H31's carrier comparison,
claimDeliveryand the pairingcheck-clause2-carriersderives all want the wide "is there a PR on this card" reading, because a
Refshalf still open is live work. Narrowing the shared relation would make that half
invisible to the rows that exist to see it — the #10468 harm, run backwards. The
open-side branch-fallback pin is unchanged and still green.
Pins, all three from the dispatch ruling: a
Refs-only merged PR on a card-namedbranch leaves H8 clean; a closing-keyword body fires as before; a body-silent
merged PR on a card-named branch fires as before (the fallback's original #10757
population).
Refs #NBESIDE a delivery does not make it partial, and aRefsfor another card narrows nothing about this one — bound per card number, as H7
binds.
#16037 — three line-number citations deleted
The header inventory's H1 entry (
SKILL.md line 109,SAME write (line 465)) andselfTest'sRELEASE_RULE_LINEcomment (SKILL.md line 465, VERBATIM). Numbersout, quoted text kept, in the same style PR #16040 used for the two ruled
docblocks.
git grepforline 109/line 465/line 493over this file nowreturns nothing.
Verification
All exit codes captured before any pipe.
Self-test —
node scripts/pm/check-half-states.mjs --self-test, exit 0:2535 cases before, 2553 after. Case-name diff: 20 added, 2 removed, both
forced by the ruling that flips H8's verdict on one fixture and each with a named
successor on the same input:
H49 adjacency: on a head NAMED for the card H8 fires through its branch fallbackH49 adjacency: on a head NAMED for the card H8 is silent too, since #16036H49 adjacency: …and this row fires beside it — two readings, no double silenceH49 adjacency: …and this row fires there — one reading now, and no silenceTwo names survive on a moved subject and are named here rather than left to be
found:
H8 branch: a Refs #N-only body delivers via its branch namenow assertsthe unchanged
prDeliversCardrelation (still true of that input), andH8 branch: …and the finding names the delivering PRnow asserts on thebody-silent specimen, which is the case that still produces a finding.
Ablations — on a scratch copy outside the worktree, byte-pinned to the HEAD
blob before each run and restored by blob-hash comparison after it. Each mutation
was confirmed on disk by removed-text and injected-text occurrence counts plus a
blob-hash change, before the run was read:
claimedBrancheslist marker: blob62db8eftoed7c565, removed-textcount 1 to 0, injected-text 0 to 1 — self-test exit 1, 6 named failures, all
the check-half-states: a Branch line written as a markdown bullet parses to ZERO claimed branches, so the claim silently stops governing while the refusal message blames a missing claim comment #16170 cases including the mixed-shape governing one.
62db8efto5778d9e, sameon-disk proof — self-test exit 1, 2 named failures, the two check-half-states: H8's branch-name fallback reads a merged
Refs #N (item k)PR on a card-named branch as a full delivery, so it prescribes droppingpm:dispatchedon a lawfully re-dispatched remainder #16036 cases.62db8efec42e3d68e9c7e76ec2c880bf0b1524d9, equal toHEAD:scripts/pm/check-half-states.mjs.The first ablation initially died on a TypeError naming neither row nor mutation;
the second commit on this branch adds the
?? []row wrapper H34's own noteprescribes, so the reverse run reports NAMED cases. That is why the ablation
numbers above are from the re-run.
Gates —
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderived 33 commands at commit
c493f98f22; all 33 run, all exit 0;--ranreconciles:33 derived famil(ies) accounted for — 33 run, 0 NOT-MEASURED,exit 0.
node scripts/pm/check-governed-merges.mjs --test scripts/pm/check-half-states.mjsexit 0 —
NOT governed — ordinary queue landing applies.The 8 artifact-roster families whose roster sits under
scripts/orscripts/pm/(where the derivation's
silentverdict is evidence in neither direction) wererun too: 6 green;
check:published-readme-exportsandcheck:dts-closurebothexit 3 = PREREQUISITE NOT MET (no package has a
dist/in this worktree),which is NOT MEASURED rather than red — this diff touches no package source, so
neither can reach it, and CI builds the closure and runs both.
Lint — whole-repo
pnpm lint(eslint . --no-inline-config) throughbash scripts/pm/os-verify-lock.sh -cwith slotissue-16036:VERDICT command-exit 0 · held the lock 73s · waited 1s.Live sweeps, read-only, both boards, before and after. Two scratch trees, one
pinned to the merge-base blob and one to the HEAD blob, both verified by
git hash-objectbefore running.Every difference is board drift over the minutes between the paired runs, and
each one is accounted for rather than waved at:
(an OPEN-PR population) left, and their cards [finding]
service-cluster-redis's KV contract suite never exercises the WATCH/MULTI abort-retry path nor the versioned-delete MULTI branch — measured by instrumenting the shipped test #15983 and objectql: publish a recognizer forSystemWriteOrganizationRequiredErrorso consumers stop re-spellingERR_SYSTEM_WRITE_ORGANIZATION_REQUIRED—instanceofis measured unsound across the CJS/ESM split #14936 gained H8 rowsnaming those exact PRs. Both of those new H8 rows come from closing-keyword
bodies, so the narrowing correctly leaves them firing — the ruling's second pin,
observed live. The other movements (H19, H31, H35, H36, H44) are in families
that read neither
claimedBranchesnor H8's predicate.$icontainsis absent from analyticsTEXT_PATTERN_OPERATORS, so the #5234 comparand fence never covered it on thewheredoor — one operator, two answers inside one package #7693 fired at "~62 min after the claim was posted(threshold 60 min)" — a clock crossing, not a reading change — and their H8 rows
arrived with PR [finding]
uninstallPackageunregisters the namespace BEFORE the verb that can refuse — a rejected uninstall leaves the package half-mutated #7970's merge in the same window.direction the change permits: narrowing
deliveringcan only remove rows.on objectstack, 13/13 on objectui), which is the reason nothing was silenced:
no card on either live board currently carries a merged
Refs-only landinginside H8's merged window. The guard is prospective, and the self-test is where
it is measured.
One open question, left to the seat rather than decided here
The ruled anchor puts the list marker BEFORE the optional blockquote, so
- > Branch:reads and> - Branch:— the natural markdown for a bulleted lineINSIDE a blockquote, and arguably what "blockquote + bullet" names — does not.
Implemented exactly as ruled, with the residual pinned as a measured fact and
flagged in the report comment. Say the word and it is a one-character move.
skip-changeset:scripts/pm/**publishes nothing from any package.🤖 Generated with Claude Code
Generated by Claude Code
Generated by Claude Code