Skip to content

Commit 51c28cd

Browse files
claude[bot]claudeos-steve
authored
tooling(pm): H8, H19 and H37 quote the LANDED release act, both halves (#16010)
`scripts/pm/check-half-states.mjs` presented a shorthand inside quotation brackets at four places. In this file's register those brackets signal a verbatim `.claude/skills/pm-dispatch/SKILL.md` quotation, and that phrase is in no SKILL.md: `git grep` outside this one script found zero hits, and a non-shallow `git log -S` over SKILL.md's whole history came back empty. It was the script's own coinage, wearing a promise the source could not answer. Worse than a spelling nit, because the coinage names only ONE half of the act that landed on 2026-09-05: 释放是显式动作:让卡离手者同笔清 assignee + `Release:` 行(会话/因/去向);下一任重新认领。 Clearing the assignee is half of it; the `Release:` line is the other half. A reader following those three remedy sentences exactly produced the shape the H47 row exists to report — the field cleared, no record of who let the card go. The sweeper's own remedy text prescribed a half-state. Re-pointed at the landed line, quoted verbatim from one new module constant (`RELEASE_ACT_RULE`, extracted from the existing transcriptions rather than retyped) so the spellings cannot drift apart again: - H8's full-delivery remedy (the merged-PR re-grade) - H19's release text, shared by the closed and the unresolved branch - H37's dispatched-residue remedy, the third sentence prescribing a release - the H24 header-inventory paragraph, which narrated the coinage's origin and now reads the rule instead of the history No predicate changes, no new rows, the four comment markers untouched. Self-test 2414 -> 2427 cases, all passing. The four pinned cases keep their assertions and re-point at the landed spelling; each re-pointed sentence gains a case that the rule line is quoted UNBROKEN, one that the second half is named, and one grep-negative that fails if the coinage returns. That negative needle is ASSEMBLED rather than spelled: a literal would be the single hit that defeats the whole-file grep measuring this repair, which now reads zero. Claude-Session: https://claude.ai/code/session_019RfFHiRCSs3JXLK4cwcfox Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Steve Jobs <steve@objectstack.ai>
1 parent 2da2901 commit 51c28cd

1 file changed

Lines changed: 89 additions & 15 deletions

File tree

scripts/pm/check-half-states.mjs

Lines changed: 89 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -488,10 +488,17 @@
488488
* second half of the contradiction is a FIELD — which is how 17 cards
489489
* across three repos (2026-08-23 census: 6 objectstack, 10 objectui, 1
490490
* cloud) sat in it with nothing reporting them. The measured origin is a
491-
* state ROLLBACK that swaps the label and leaves the field: of the three
492-
* rollback paths, only dead-claim reclamation ever named the assignee
493-
* drop, so H8's and H19's remedy sentences now name it too (「同笔摘
494-
* assignee」). ⚠️ The field carries two meanings — dead agent claims and
491+
* state ROLLBACK that swaps the label and leaves the field. What every
492+
* rollback path owes instead is the release ACT — ONE act with TWO
493+
* halves:
494+
* 「释放是显式动作:让卡离手者同笔清 assignee + `Release:` 行(会话/因/去向);下一任重新认领。」
495+
* — clear the assignee AND post the `Release:` line, in one write. H8's
496+
* full-delivery remedy, H19's release text and H37's dispatched-residue
497+
* remedy all say exactly that, from one constant (`RELEASE_ACT_RULE`),
498+
* because a remedy naming only the FIELD half prescribes the other
499+
* half-state — the field cleared with no record of who let the card go —
500+
* which is the shape H47 reports.
501+
* ⚠️ The field carries two meanings — dead agent claims and
495502
* genuine human ownership — and the row deliberately does NOT try to tell
496503
* them apart: the ruling of 2026-08-23 puts the rule FIRST and any
497504
* true-ownership exemption in an explicit marker LATER, never the other
@@ -1091,6 +1098,35 @@ export const CLAIM_COMMENT_MARKER = /^\s*>?\s*Claim(?:ed)?\s*:/mi;
10911098
*/
10921099
export const RELEASE_COMMENT_MARKER = /^\s*>?\s*Release\s*:/mi;
10931100

1101+
/**
1102+
* The release ACT, quoted from `.claude/skills/pm-dispatch/SKILL.md` VERBATIM
1103+
* and kept UNBROKEN on one line so it stays greppable against its source:
1104+
*
1105+
* 「释放是显式动作:让卡离手者同笔清 assignee + `Release:` 行(会话/因/去向);下一任重新认领。」
1106+
*
1107+
* ONE constant, because every remedy sentence that tells a seat how to let a
1108+
* card go has to say the SAME thing. Three of them — H8's full-delivery
1109+
* remedy, H19's release text on both branches, H37's dispatched-residue
1110+
* remedy — carried a shorthand of this file's own coining instead: a phrase
1111+
* wearing quotation brackets that appeared in NO SKILL.md, ever (`git log -S`
1112+
* over that file's whole history came back empty). In this file's register the
1113+
* brackets promise that these are the protocol's OWN words, so the shorthand
1114+
* was not a spelling nit — it made a promise the source could not answer.
1115+
*
1116+
* ⚠️ It is ONE act with TWO halves — clear the assignee AND post the
1117+
* `Release:` line (session, cause, destination) — and a remedy naming only the
1118+
* field half PRESCRIBES a half-state: the field cleared, no record of who let
1119+
* the card go or why, which is the exact shape H47 exists to report. ⛔ So do
1120+
* not paraphrase this line, and do not coin a shorthand for it again.
1121+
*
1122+
* `selfTest` keeps its OWN transcription of the same line (`RELEASE_RULE_LINE`)
1123+
* rather than reading this constant: two independent copies compared against
1124+
* each other is a real check, while a pin that reads the value it pins asserts
1125+
* nothing at all.
1126+
*/
1127+
const RELEASE_ACT_RULE =
1128+
'释放是显式动作:让卡离手者同笔清 assignee + `Release:` 行(会话/因/去向);下一任重新认领。';
1129+
10941130
export function h2AssigneeNoClaimComment(issue, commentBodies) {
10951131
const labels = labelNames(issue);
10961132
const pmTracked = labels.some((l) => l === 'pm:queue' || l === 'pm:dispatched');
@@ -1757,7 +1793,10 @@ export function h8MergedPrStillDispatched(issue, mergedPrs, openPrs) {
17571793
`delivering PR ${list} is MERGED but the card still carries \`pm:dispatched\` — ` +
17581794
`the merge's paired write never landed. Drop \`pm:dispatched\` and re-grade the ` +
17591795
`remainder (re-queue, close, or block the un-delivered half) in the same stroke, ` +
1760-
`and 「同笔摘 assignee」 — the landing re-label owes the ASSIGNEE DROP too. A ` +
1796+
`and let the card GO in the landed shape — 「${RELEASE_ACT_RULE}」 — ONE act with TWO ` +
1797+
`halves: clear the assignee AND post the \`Release:\` line (session, cause, destination). ` +
1798+
`Dropping the field alone leaves no record of who let the card go, which is the half-state ` +
1799+
`H47 reports. A ` +
17611800
`re-graded card that keeps the finished dev's assignee lands straight in H24's ` +
17621801
`two-views contradiction (\`pm:queue\` + assigned = dispatchable to the queue view, ` +
17631802
`taken to the claim rule), which is how 17 cards across three repos got stuck where ` +
@@ -3468,7 +3507,10 @@ export function h19BlockOutlivedBlocker(issue, resolutions) {
34683507
'to release when the card carries a MERGED PR newer than that conversion comment (the card moved on ' +
34693508
'after the condition was written, so the cited fact can be true and no longer current). This row ' +
34703509
'surfaces the candidate; the unlock sweep releases it — ⛔ never a label written from this script. ' +
3471-
'When that release does happen, its paired write includes 「同笔摘 assignee」: a card returned to ' +
3510+
`When that release does happen it is the landed ACT — 「${RELEASE_ACT_RULE}」 — ONE write with ` +
3511+
'TWO halves: it clears the assignee AND carries the `Release:` line (session, cause, destination). ' +
3512+
'Dropping the field alone leaves no record of who let the card go, the half-state H47 reports. ' +
3513+
'A card returned to ' +
34723514
'`pm:queue` still carrying the assignee of the seat that parked it is dispatchable to the queue ' +
34733515
'view and taken to the claim rule at the same time (H24), which is the state the unlock scan was ' +
34743516
'measured leaving behind — ⚠️ agent identity only, a HUMAN assignment is ⛔ never cleared by an agent.';
@@ -6948,8 +6990,11 @@ export function h37FamilyMemberDrift(folds, openByNumber, closedByNumber) {
69486990
'That is the same non-atomic family write failing in the MIRROR direction, and it reads to ' +
69496991
'every per-card predicate as an ordinary in-flight card. Patrol input, NOT a verdict — this ' +
69506992
'member may still have work of its own outstanding. Remedy: clear the residue in the write ' +
6951-
'that cleared the head (drop `pm:dispatched` and the assignee together — H24\'s ' +
6952-
'「同笔摘 assignee」), or re-dispatch it on its own card and its own branch if work remains. ' +
6993+
'that cleared the head, in the landed shape — letting a card go is ONE act with TWO ' +
6994+
`halves, 「${RELEASE_ACT_RULE}」 — so drop \`pm:dispatched\`, clear the assignee AND ` +
6995+
'post the `Release:` line (session, cause, destination) together; a kept assignee lands ' +
6996+
'in H24, a cleared field with no line in H47. Or re-dispatch it on its own card and its ' +
6997+
'own branch if work remains. ' +
69536998
`Claimants seen on that branch: ${namedMembers(entry?.claimants ?? [])}.`,
69546999
]);
69557000
}
@@ -13712,6 +13757,12 @@ function selfTest() {
1371213757
// holds is exactly the drift a shared constant cannot express.
1371313758
const RELEASE_RULE_LINE =
1371413759
'释放是显式动作:让卡离手者同笔清 assignee + `Release:` 行(会话/因/去向);下一任重新认领。';
13760+
// The retired coinage, ASSEMBLED rather than spelled. The measure of this
13761+
// repair is a `git grep -c` for that phrase over this file reading ZERO, so a
13762+
// literal needle in the negative cases below would be the single hit that
13763+
// defeats the check it exists to protect. Joining the halves keeps both the
13764+
// case and the grep honest.
13765+
const RETIRED_ASSIGNEE_COINAGE = ['同笔摘', 'assignee'].join(' ');
1371513766

1371613767
// -- Row-text wrappers: every message assertion goes through one -----------
1371713768
//
@@ -17043,19 +17094,36 @@ function selfTest() {
1704317094
t('H24 adjacency: H3 is silent (only ONE label is present)', h3QueueAndDispatched(queued(['pm:queue'], ['os-elon'])), false);
1704417095
t('H24 adjacency: H2 is silent when the claim comment is complete', h2AssigneeNoClaimComment(queued(['pm:queue'], ['os-elon']), ['Claim: PM loop round 1\nSession: session_x']), false);
1704517096

17046-
// -- The paired-write remedy texts (#11196 fix 2) ---------------------------
17097+
// -- The paired-write remedy texts (#11196 fix 2, re-pointed) ---------------
1704717098
// H8's landing re-label and H19's unlock scan are the two rollback paths that
17048-
// never named the assignee drop; both sentences name it now, and the
17049-
// half-delivered branch must NOT (there the label and the claim are CORRECT).
17099+
// never named the release act; both sentences name it now — and they name it
17100+
// in the spelling that LANDED, quoting the rule line UNBROKEN so the quote
17101+
// stays checkable against SKILL.md, and naming the SECOND half (the
17102+
// `Release:` line) that a bare field drop omits. The half-delivered branch
17103+
// must NOT prescribe it (there the label and the claim are CORRECT).
17104+
//
17105+
// Every re-pointed sentence also carries a negative case for the retired
17106+
// coinage: a re-pointing a later edit can silently undo is not a repair, and
17107+
// the whole-file grep that measures this one runs nowhere but in a reviewer's
17108+
// shell.
1705017109
const pairedMerged = [{ number: 900, merged_at: '2026-08-22T10:00:00Z', body: 'Fixes #10638', head: { ref: 'x' } }];
1705117110
const pairedOpenHalf = [{ number: 901, merged_at: null, draft: true, body: 'Part of #10638', head: { ref: 'y' } }];
17052-
t('H8: the full-delivery remedy names 同笔摘 assignee', h8row(queued(['pm:dispatched'], ['os-elon']), pairedMerged, []).includes('同笔摘 assignee'), true);
17111+
t('H8: the full-delivery remedy names the release act in the spelling that LANDED', h8row(queued(['pm:dispatched'], ['os-elon']), pairedMerged, []).includes('同笔清 assignee'), true);
17112+
t('H8: …quoting the rule line unbroken, so the quote stays checkable against SKILL.md', h8row(queued(['pm:dispatched'], ['os-elon']), pairedMerged, []).includes(RELEASE_RULE_LINE), true);
17113+
t('H8: …and names the SECOND half, the `Release:` line a bare field drop omits', h8row(queued(['pm:dispatched'], ['os-elon']), pairedMerged, []).includes('`Release:` line'), true);
17114+
t('H8: …and the retired coinage does not come back', h8row(queued(['pm:dispatched'], ['os-elon']), pairedMerged, []).includes(RETIRED_ASSIGNEE_COINAGE), false);
1705317115
t('H8: …and points at H24 as the state it prevents', h8row(queued(['pm:dispatched'], ['os-elon']), pairedMerged, []).includes('H24'), true);
1705417116
t('H8: …and keeps the human-assignment refusal', h8row(queued(['pm:dispatched'], ['os-elon']), pairedMerged, []).includes('never cleared by an agent'), true);
17055-
t('H8: the HALF-delivered branch prescribes no assignee drop', h8row(queued(['pm:dispatched'], ['os-elon']), pairedMerged, pairedOpenHalf).includes('同笔摘 assignee'), false);
17117+
t('H8: the HALF-delivered branch prescribes no assignee drop', h8row(queued(['pm:dispatched'], ['os-elon']), pairedMerged, pairedOpenHalf).includes('同笔清 assignee'), false);
17118+
t('H8: …nor the release rule line — nothing is being let go there', h8row(queued(['pm:dispatched'], ['os-elon']), pairedMerged, pairedOpenHalf).includes(RELEASE_RULE_LINE), false);
1705617119
t('H8: …and still says the label is correct there', h8row(queued(['pm:dispatched'], ['os-elon']), pairedMerged, pairedOpenHalf).includes('must NOT be dropped'), true);
17057-
t('H19: the release text names 同笔摘 assignee', h19row(queued(['pm:blocked']), [{ key: 'objectstack-ai/objectstack#2', number: 2, local: true, state: 'closed' }]).includes('同笔摘 assignee'), true);
17058-
t('H19: …on the unresolved branch too (one release contract, one sentence)', h19row(queued(['pm:blocked']), [{ key: 'objectstack-ai/cloud#2', number: 2, local: false, state: 'unresolved', detail: 'HTTP 404' }]).includes('同笔摘 assignee'), true);
17120+
t('H19: the release text names the release act in the spelling that LANDED', h19row(queued(['pm:blocked']), [{ key: 'objectstack-ai/objectstack#2', number: 2, local: true, state: 'closed' }]).includes('同笔清 assignee'), true);
17121+
t('H19: …quoting the rule line unbroken', h19row(queued(['pm:blocked']), [{ key: 'objectstack-ai/objectstack#2', number: 2, local: true, state: 'closed' }]).includes(RELEASE_RULE_LINE), true);
17122+
t('H19: …and names the SECOND half, the `Release:` line', h19row(queued(['pm:blocked']), [{ key: 'objectstack-ai/objectstack#2', number: 2, local: true, state: 'closed' }]).includes('`Release:` line'), true);
17123+
t('H19: …and the retired coinage does not come back', h19row(queued(['pm:blocked']), [{ key: 'objectstack-ai/objectstack#2', number: 2, local: true, state: 'closed' }]).includes(RETIRED_ASSIGNEE_COINAGE), false);
17124+
t('H19: …on the unresolved branch too (one release contract, one sentence)', h19row(queued(['pm:blocked']), [{ key: 'objectstack-ai/cloud#2', number: 2, local: false, state: 'unresolved', detail: 'HTTP 404' }]).includes('同笔清 assignee'), true);
17125+
t('H19: …with the rule line unbroken there too', h19row(queued(['pm:blocked']), [{ key: 'objectstack-ai/cloud#2', number: 2, local: false, state: 'unresolved', detail: 'HTTP 404' }]).includes(RELEASE_RULE_LINE), true);
17126+
t('H19: …and the retired coinage gone from that branch as well', h19row(queued(['pm:blocked']), [{ key: 'objectstack-ai/cloud#2', number: 2, local: false, state: 'unresolved', detail: 'HTTP 404' }]).includes(RETIRED_ASSIGNEE_COINAGE), false);
1705917127

1706017128
// -- H25 + the `pm:awaiting-maintainer` vocabulary (#11196 fix 5) -----------
1706117129
t('the ruled spelling is pm:-prefixed', AWAITING_MAINTAINER_LABEL, 'pm:awaiting-maintainer');
@@ -18547,6 +18615,12 @@ function selfTest() {
1854718615
t('H37 mirror: …keyed to the member carrying the residue', h37key1(...residue37), 11679);
1854818616
t('H37 mirror: …and it says the head CLOSED', h37row1(...residue37).includes('CLOSED'), true);
1854918617
t('H37 mirror: …naming it as the same write failing the other way', h37row1(...residue37).includes('MIRROR direction'), true);
18618+
// The third re-pointed remedy sentence: this row prescribes letting a card
18619+
// go, so it owes the same landed act, both halves, as H8's and H19's do.
18620+
t('H37 mirror: …and the remedy names the release act in the spelling that LANDED', h37row1(...residue37).includes('同笔清 assignee'), true);
18621+
t('H37 mirror: …quoting the rule line unbroken', h37row1(...residue37).includes(RELEASE_RULE_LINE), true);
18622+
t('H37 mirror: …and names the SECOND half, the `Release:` line', h37row1(...residue37).includes('`Release:` line'), true);
18623+
t('H37 mirror: …and the retired coinage does not come back', h37row1(...residue37).includes(RETIRED_ASSIGNEE_COINAGE), false);
1855018624
const released37 = [
1855118625
h37FoldBranches([h37claim(11679, FOLD_37)]),
1855218626
h37map(h37card(11679, ['pm:dispatched']), h37card(11678, ['pm:queue'])),

0 commit comments

Comments
 (0)