Skip to content

fix(pm): the queue guard's narration and remedy state ruling C, not the pre-ruling landing - #18148

Merged
claude[bot] merged 1 commit into
mainfrom
claude/issue-18083-guard-remedy-ruling-c
Sep 14, 2026
Merged

fix(pm): the queue guard's narration and remedy state ruling C, not the pre-ruling landing#18148
claude[bot] merged 1 commit into
mainfrom
claude/issue-18083-guard-remedy-ruling-c

Conversation

@claude

@claude claude Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Fixes #18083

scripts/pm/check-governed-queue-guard.mjs decides on an authorized APPROVED review and has
since the 2026-09-04 predicate landed. What had not moved was the text a seat is told to
consult: the docblock called a draft awaiting the maintainer's own merge the regime's terminal
state, and the printed remedy's preferred option told a seat to take the PR out of the queue
"and leave the merge to the maintainer". Since the charter chain landed (PR #18018 9489e2c0,
PR #18038 c185d087, PR #18051 137eb00e) the rule is ruling C — issue #17971, maintainer
2026-09-13, verbatim and untranslated:

C. approve 后不管后续改动都由席位落地:

So the narration under-permitted: it told a seat not to do the thing the rule now says it
should do once an authorized approval is on record.

What moved

Wording only. ⛔ No decision branch changed — entrySatisfied, the approval reduction, the
tier split and every exit code are untouched. Anchored by content, not by line number.

  1. Docblock, the "why the PR leg must not redden" paragraph. The healthy resting state is
    now a draft waiting for an authorized approval, in the landed rule's own words from
    .claude/skills/pm-dispatch/references/landing-operations.md: 「四件套留 draft 等人批,⛔ 不翻正式不入队;获授权批准后认领席落地。」
  2. Docblock, a new paragraph for what happens after the approval — ruling C, quoted
    verbatim, plus SKILL.md's operational half: 「席位落地 = 过落地前检、清标、ready、auto-merge,踢出/变基同法。」
    The seat's ready → enqueue is now stated as the correct next act there rather than a violation.
  3. Docblock, the "this guard cannot stop a direct merge" paragraph. The direct merge is now
    the OTHER landing rather than the only one — references/core-rules.md: 「受管面由维护者人合或授权批准后席位落地」.
    The docs(adr): ADR-0120 D4 amendment — the duplicate pre-flight is per index class #11387 measurement it cites is kept verbatim as history.
  4. The pull_request leg's EARLY WARNING rendering. The ⛔ list (flip ready / enqueue / arm
    auto-merge) is now explicitly conditional — "while no authorized APPROVED review is on
    record", with AGENTS.md Prime Directive feat: Comprehensive CRM example demonstrating all ObjectStack protocol features #14's own "lift only for that approval" — and a new
    ✅ line says what a seat DOES do after the approval.
  5. The merge_group refusal remedy. Steps 1 → 2 are now an order rather than a menu:
    out of the queue first, then the authorized approval, and the CLAIMING SEAT lands it from
    there. The unapproved direct merge (人工直合) is kept as the landing that PR still has.
  6. Two internal comments that restated the same pre-ruling shape: the tier-default
    asymmetry cost (was "costs one hand merge") and the exit-code precedence note.

The references tier is untouched and still says the in-seat review of record lands it: remedy
option 3 renders byte-for-byte as before, and both of its pins (offered on a references-only
refusal, withheld on a rules-layer one) still pass.

Acceptance readings

Taken on a2e4cd7d9, in the worktree, against merge base a90a9f267.

The two pre-ruling phrases, in the narration and the printed text: N → 0.

reading before after
git grep -c -E 'leave the merge to the maintainer|human merge IS the review record' 2 2
… of those, hits in narration or printed remedy 2 0
… of those, hits inside the self-test pin that FORBIDS them 0 2

Both remaining hits are the new negative assertion itself — a comment and the regex literal in
⛔ a-refusal-never-tells-a-seat-to-leave-the-merge-to-the-maintainer-nor-calls-that-merge-the-record.
A pin has to name what it forbids; neither is text the guard ever prints.

The landed phrase: 0 → 5 (git grep -c 'CLAIMING SEAT lands\|claiming seat lands').

Every hit of the pre-ruling wording enumerated (git grep -n -E 'hand merge|human merge|leave the merge|人工合'),
6 before → 4 after, and each remaining one accounted for:

  • :44 「人工合并即人工审核」 (docblock) — moved.
  • :52 "the human merge IS the review record" (docblock) — moved.
  • :536 "costs one hand merge" (tier-default comment) — moved, now "costs one authorized approval".
  • :1171 「人工合并即人工审核」 (EARLY WARNING rendering) — moved.
  • :1242 "leave the merge to the maintainer. A human merge" (remedy) — moved.
  • :2010 (was :1983) the #9319 replay fixture's name, quoting PR docs(pm): label writes re-read current labels in the same action — stale snapshots are invalid snapshots (#9226) #9238's own body: "a .claude/skills PR whose own body said 'awaiting a human merge'" — stays. It is a historical measurement naming what that PR said in 2026; rewriting it would falsify the fixture.
  • :2429, :2436, :2468new, the three negative pins (two English phrases, one 人工合并即人工审核).

Self-test: node scripts/pm/check-governed-queue-guard.mjs --self-test :: exit 0,
233 cases before → 238 after (5 added, none removed, no battery floor lowered).

Diff surface: git diff --stat a90a9f267 names exactly one file,
scripts/pm/check-governed-queue-guard.mjs, 104 insertions / 32 deletions. origin/main
advanced under this worktree during the run (a90a9f267739ab526d, a shared-ref hazard
AGENTS.md names), so the anchor above is the merge base, not the moving ref.

Governed? No — node scripts/pm/check-governed-merges.mjs --test scripts/pm/check-governed-queue-guard.mjs
:: exit 0, "NOT governed — ordinary queue landing applies". This PR is opened as a draft and the
seat lands it; nothing here flips ready or arms anything on its own.

Reverse verification — the new pins can actually fail

One-shot, from the committed state, with a trap … EXIT INT TERM restoring absolute paths.
Predicted direction: turns red.

  • HEAD blob f7938efe94a20f34a3c1e6f07e2aaca393f16a47.
  • Mutation: the remedy's step-2 line rewritten back to the pre-ruling wording. On-disk
    observation, anchored on both texts: landed anchor 1 → 0, injected stale phrase 0 → 1;
    blob 87b912dbc8acaf5af5d02fb86cc06eb2bcffd986 ≠ HEAD blob, so it reached disk.
  • Mutated leg: --self-test :: exit 1, ✗ 2 of 238 case(s) failed — exactly
    a-refusal-orders-the-remedy-DRAFT-then-the-authorized-APPROVAL-then-the-CLAIMING-SEAT-lands-it
    and ⛔ a-refusal-never-tells-a-seat-to-leave-the-merge-to-the-maintainer-nor-calls-that-merge-the-record.
  • Restore leg: git checkout HEAD -- FILE → blob back to f7938efe… (byte-identical),
    git diff HEAD empty, git status --porcelain empty, anchor restored 1, injected 0.
  • Restored leg: --self-test :: exit 0, 238 cases pass.

Gates

Derived with node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack
(no paths, three-dot against merge base a90a9f267) — 33 commands, all run in the
foreground, every exit code captured before any pipe, all exit 0.
Reconciled:

node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --ran RAN_FILE
Run reconciliation — 33 derived, 33 run, 0 NOT-MEASURED, 0 UNRUN.
✓ 33 derived famil(ies) accounted for — a DERIVED zero — all 33 recorded an exit code and none of them is 3.

Including node scripts/pm/check-governed-queue-guard.mjs --self-test :: exit 0 and
pnpm check:nul-bytes :: exit 0. pnpm check:pm-governed-merges :: exit 0 was run too, though
the derivation does not place it for this path — it is a --self-test-only checker-health
family here, so its green grades that checker's fixtures, not this diff.

Control characters: grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]' over the changed file — no hits.

No changeset: scripts/pm/** ships in no package's files[], so this publishes nothing — the
skip-changeset label carries it.

Acceptance notes

Two observations outside this card's one-file surface, noted and not filed (this seat's write
budget for the round is the branch push, this PR, the label and one report comment):

Generated by Claude Code


Generated by Claude Code

…he pre-ruling landing

The guard's decision already keys on an authorized APPROVED review, but the
text a seat is told to consult still described the landing that preceded
ruling C: the docblock called a draft awaiting the maintainer's own merge the
regime's terminal state, and the printed remedy told a seat to "leave the merge
to the maintainer" as the preferred way through.

Ruling C (#17971, maintainer 2026-09-13) put the landing in the claiming seat's
hands once an authorized approval is on record. The narration, the early-warning
rendering and the refusal remedy now say that, in the charter's own words
(landing-operations.md, SKILL.md), and the unapproved direct merge is kept as
the other landing rather than as the only one.

No decision branch changes. The self-test pins that read the remedy move with
it, and three new pins assert the pre-ruling wording is absent from the printed
text; 233 -> 238 cases.

Claude-Session: https://claude.ai/code/session_01DAcomhvR9kKizeYgg89Vo8
Co-authored-by: Claude <noreply@anthropic.com>
@claude claude Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 14, 2026
@claude

claude Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor Author
  • Served-tier: 2300/2300 CONTRACT_REVIEW_TIER — harness model stamp counted over this seat's own transcript (non-sidechain assistant messages a model served; <synthetic> harness notices excluded) at 2026-09-14T06:46Z and compared to the constant's value outside the repository; get_session external_metadata.last_served_model read equal to the constant at 2026-09-14T00:20Z.

Contract review

Head: a2e4cd7d (PR #18148, card #18083) — reviewed at 2026-09-14T06:47Z by the skills seat at the contract-review tier. Path face clean (scripts/pm/check-governed-queue-guard.mjs only — non-governed PM tooling whose SUBJECT is the governed surface) ⇒ in-seat landing: ready + auto-merge after this record.

① derived judgments (seat-measured on the fetched head a2e4cd7d against merge-base a90a9f26, ⛔ not taken from the report):

  1. Wording only, +104/−32, one file: the docblock narration, the pull_request leg's EARLY WARNING rendering and the merge_group refusal remedy now state ruling C ([Ruling] After an authorized approval, the owning seat lands a governed PR — later pushes need no second word from the maintainer (maintainer, 2026-09-13, option C) #17971, verbatim 「C. approve 后不管后续改动都由席位落地:」) in the landed charter's own words (landing-operations.md 「四件套留 draft 等人批,⛔ 不翻正式不入队;获授权批准后认领席落地。」, SKILL.md 「席位落地 = 过落地前检、清标、ready、auto-merge,踢出/变基同法。」, core-rules.md 「受管面由维护者人合或授权批准后席位落地」); the unapproved direct merge is kept as the OTHER landing; the ⛔ list on the PR leg is now conditional on no authorized approval yet, with a ✅ line for what the seat does after one. ⛔ No decision branch moved: entrySatisfied, the approval reduction, the tier split and every exit code are untouched; the references-tier remedy renders byte-for-byte.
  2. The phrases: the pre-ruling wording is 0 in narration and printed text on the head; the two file-wide hits that remain are the new NEGATIVE self-test pin (a comment and a regex) that forbids them (seat grep :2429 / :2436); the enumeration 6 → 4 keeps one historical fixture (the finding: skill-surface PR #9238 (.claude/skills/**) was flipped ready, enqueued, and merged by the queue — Prime Directive #14 human-merge bypassed #9319 replay quoting PR docs(pm): label writes re-read current labels in the same action — stale snapshots are invalid snapshots (#9226) #9238's own body) and adds three negative pins; the landed phrase 「the CLAIMING SEAT lands」 0 → 5.
  3. Pins: self-test 233 → 238 cases, exit 0 on the head (seat-run); the dev's reverse verification (the remedy's step-2 line mutated back to the pre-ruling wording → 2 of 238 fail, restored to the HEAD blob) shows the pins bite. check:declared-population-live exit 0 on the head (seat-run — the feat(pm): check-clause2-carriers emits the contract-review record as a copyable template #18138 lesson: a wording change can add a path-shaped literal; this one did not).
  4. Gates: 33 derived / 33 run / 0 NOT-MEASURED / 0 UNRUN, all exit 0, plus check:pm-governed-merges (not derived for this path — checker-health only) exit 0; no exit-3 prerequisite; check-governed-merges.mjs --test on the file → NOT governed. Checks on the head at read time: 0 red (13 in progress at 2026-09-14T06:43Z).
  5. Scope held: one file; skip-changeset is the declaration; Clause-②: no holds — no contract path; --pair 18148 on origin/main's reader → exit 0 before this record; 3 REST writes, 0 MCP calls per the report.

② semver: unchanged — scripts/pm/** publishes nothing.

③ boundary flags: the dev's out-of-scope note — scripts/pm/check-governed-merges.mjs :140 and scripts/check-required-contexts.mjs :288 still say 「a human merge IS the review record」 without naming the second terminal (an omission, not a contradiction; the first file is fenced off this card by name) — is carried by the seat: a bare finding follows this landing. .claude/hooks/guard-governed-enqueue.sh :548 already has ruling C's shape (checked, not a defect). The objectui copy is objectui#9449 (bare).

Implemented-by: claude/issue-18083-guard-remedy-ruling-c
Reviewed-by: session_01DAcomhvR9kKizeYgg89Vo8

Verdict: PASS — path face clean ⇒ this seat lands: ready through POST …/pulls/18148/ccr/ready_for_review with read-back, then PUT …/ccr/auto_merge; Fixes #18083 closes the card on landing.

维护者速读(终稿)

受管面队列门禁的判定早就按「授权批准」走,但它打印给席位看的文字还停在旧规矩(「把合并留给维护者,人工合并即审核记录」)。这次只改叙述和打印文案,改成 ruling C 的原话:先 draft 等授权批准,批准后由认领席位 ready + auto-merge 入队;判定分支一条没动,自测 233 → 238。脚本层,本席直接落地。


Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

1 participant