Skip to content

fix(pm): check-half-states H16 excludes changeset-release/* as H12 does - #25017

Merged
objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/issue-24856-h16-drop-changeset-release
Oct 21, 2026
Merged

objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/issue-24856-h16-drop-changeset-release

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #24856
Clause-②: no

What this does

A deletion in scripts/pm/check-half-states.mjs, the report-only half-state patrol. Scope is the triage answer on the card (comment 6292721219, scope (b)). H16 now excludes changeset-release/* the way H12 already does. H16 does not get a new row, any regeneration remedy text, or a threshold for that branch.

H16's docblock assumed the Version Packages PR is "regenerated from main on every push". That stopped being true when the version-pr job moved to a six-hourly schedule (#11233). release.yml's own header on origin/main says: "Between refreshes changeset-release/main is a static branch." So a dirty Version Packages PR is in its normal stale window. H16 flagged it after 2 h and told the reader to hand-merge main into a generated branch, which the next refresh overwrites.

Changes (one file, +10 / -12)

  • h16StuckMergeConflict (the predicate, L4262): if ((pr.head?.ref ?? '').startsWith('changeset-release/')) return null;, H12's exact spelling.
  • h16NeedsDetail (the gathering gate, L4197): the same exclusion, returning false.
  • Docblock, replaced in place: the 6-line paragraph claiming the branch is "deliberately NOT excluded, unlike in H12 ... regenerated from main on every push" is now a 3-line reason that quotes release.yml and cites release.yml 的 version-pr 车道改为「定时 + 按需」刷新——终结 Version Packages PR 被每次 main push 强刷、CI 永不收敛的合并竞态 #11233 (L4191). The predicate's existing out-of-scope sentence gains one clause pointing to it (L4248), with no new line. Net prose: -3 lines.
  • Self-test: the two pins that asserted the old premise are flipped in place, and their comment is rewritten (3 lines down to 2):
    • H16 gate: a changeset-release head is not a candidate (excluded, as in H12) now expects false.
    • H16: a dirty changeset-release/main PR past the threshold yields no row (the limb is deleted, #11233) now expects null.
    • Every other H16 pin is unchanged, including the ordinary dirty-PR pins (dirty beyond the threshold -> finding, dirty within the threshold -> clean). The case count is 4916 before and after.

Where the exclusion lives, and why both functions

  • The live sweep cannot skip the gate. It calls the predicate in one place only (L22472), and that call comes after if (!h16NeedsDetail(pr)) continue; (L22462).
  • The gate alone is not enough. The self-test's never narrower than the predicate (every flagged row is fetched) invariant requires the gate to fetch every row the predicate can flag. If only the gate excluded the branch, the predicate would still flag it and that invariant would go red. Ablation leg A below measured exactly that. So the predicate carries the exclusion, since every caller ends there.
  • The gate mirrors it because its own docblock defines it as "the halves of the predicate that do not need mergeable_state", and the head ref is one of those halves. Without the mirror, every sweep would spend one GET on the Version Packages PR, which the predicate can never flag.

Tests (at 43d062e63)

  • Before (a7199ef97): node scripts/pm/check-half-states.mjs --self-test, exit 0, ✓ check-half-states self-test: 4916 cases pass.
  • After (43d062e63): the same command, exit 0, ✓ check-half-states self-test: 4916 cases pass.

Ablation (the fix was committed first; mutations went through node scripts/ablation-replace.mjs, which restores itself on exit):

  • Leg A, predicate line removed (gate kept), marker count 1, exit 1, 2 of 4916 case(s) failed:
    • the new yields no row pin failed (it got the old hand-merge row text, expected null);
    • H16 gate: never narrower than the predicate failed (got false, want true).
    • Restore: blob 4cb17365 matches HEAD, and git diff HEAD is empty.
    • The first attempt at this leg was a no-op: the tool refused before mutating, because the replacement text already occurred in the anchor. I picked a new anchor and re-ran it.
  • Leg B, gate line removed, marker count 1, exit 1, 1 of 4916 case(s) failed: H16 gate: a changeset-release head is not a candidate (got true, want false). Restore: blob matches HEAD, and git diff HEAD is empty.

Gates

I derived the local gates with node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at 43d062e63: 43 commands. All 43 were run on 43d062e63 and every one exited 0. pnpm check:pm-dispatch-gates was run detached, as its header prescribes: fast tier, 1913 cases pass, exit 0.

The --ran reconciliation answered: 43 derived famil(ies) accounted for — 43 run, 0 NOT-MEASURED (a DERIVED zero — all 43 recorded an exit code and none of them is 3). It also warned that the tree is 46 commits behind origin/main 62bc12930, and that 4 derivation-input files changed in that range. None of them is this file. origin/main does not touch scripts/pm/check-half-states.mjs since the base, and git merge-tree against it is clean, so I did not merge. CI runs on the merge ref.

release.yml is untouched (Tier H).

Acceptance notes

  • H36's banner (now L8273-8276) gives a second reason for excluding changeset-release/* from the shared-file pairing, and that reason repeats the same stale premise: "it is regenerated from main on every push — it holds nothing." H36 behaves correctly: it excludes the branch on its first reason, that the Version Packages PR consumes every changeset and would pair with every open PR. Only the stated sub-reason is out of date. The fix would be a prose correction outside this card's declared surface (the claim names H16 only), so I left it alone. No carrier.
  • scripts/pm/check-skill-line-ratchet.mjs L1482 already describes that premise as false since release.yml 的 version-pr 车道改为「定时 + 按需」刷新——终结 Version Packages PR 被每次 main push 强刷、CI 永不收敛的合并竞态 #11233. No other row or tool cites H16's treatment of the branch: .claude/skills/pm-dispatch/** and scripts/pm/** have zero hits.

Generated by Claude Code

H16's docblock rested on the premise that the Version Packages PR is
regenerated from main on every push. That has been false since the
version-pr job moved to a six-hourly schedule (#11233): between refreshes
changeset-release/main is a static branch, so a dirty one is its normal
stale window, and the row's hand-merge remedy is overwritten by the next
refresh. The half-state patrol is report-only, so the limb is deleted:
the gate and the predicate both exclude the branch, the false paragraph
is replaced in place, and the two self-test pins that asserted the old
premise now state the deletion.

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

Copy link
Copy Markdown
Contributor Author

席位核对

ACCEPT · domain:skills seat 1 (seat post #7623) · session_01M82feuetLzrCiBz41BJb7L · head 43d062e63952b2ebfeffc69c7ac084ef20774d1a · 2026-10-21T01:01Z

  1. Form. The PR is a draft against main, and the body's first line is Fixes #24856. Assignee huangyiirene equals the card's. Files: scripts/pm/check-half-states.mjs only (+10/−12), the declared surface. check-governed-merges.mjs --pr 25017: NOT governed. It touches none of the contract-review faces, so this seat's own read at TIER_DEFAULT is the review of record. skip-changeset is right: no package is touched.
  2. Premises measured.
    • The seat read the whole diff. It is a deletion only, as the triage answer 6292721219 scoped it. H12's exact spelling, (pr.head?.ref ?? '').startsWith('changeset-release/'), now sits in both h16NeedsDetail (the gate) and h16StuckMergeConflict (the predicate).
    • There is no new row, no remedy text and no threshold. The false paragraph shrinks from 6 lines to 3, in place.
    • The quoted source is exact: release.yml:104 on origin/main reads "Between refreshes changeset-release/main is a static branch."
    • The predicate must carry the exclusion: the dev's ablation leg A shows that excluding at the gate alone reds the never-narrower invariant.
  3. Gate check-runs, pinned to this head (2026-10-21T01:00Z): 47 complete, 0 pending, 0 failures. check-expected-skips.mjs --pr 25017, from a checkout pinned to origin/main 62bc12930: roster: identical to … main's tip, then OK — 13 skipped check-run(s), every one in main's roster (exit 0). The dev's local run: 43 derived, 43 run, 0 NOT MEASURED. check-half-states --self-test passes 4916 cases, the same count as the base.
  4. Accepted deviations.
    • Two existing pins are flipped in place instead of adding one; the flipped predicate pin is the "yields no row" pin the dispatch asked for.
    • The exclusion appears in two functions, for the measured reason above.
    • origin/main was not merged: the merge-tree is clean and does not overlap this file.
    • A stray untracked file the dev's report generator wrote into the shared checkout was moved out at once. git status --porcelain there reads empty (seat re-read 2026-10-21T00:51Z).
  5. Out-of-scope findings. H36's banner (about L8273–8276) gives the same stale "regenerated from main on every push" as a second reason for excluding changeset-release/*. Its behaviour is right on its first reason. The banner is prose, not a reading, and outside classes a, b and c, so it stays in Acceptance notes, as the PR body has it.
  6. Landing. Not governed: the seat flips it ready, arms auto-merge once mergeable_state settles, follows it to MERGED, then closes out check-half-states: delete H16's changeset-release/* limb — its premise ("regenerated from main on every push") is false since #11233, so it can only print a false reading and a hand-merge remedy (report-only: deletion is the only in-flight shape) #24856.

Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 21, 2026 01:02
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 21, 2026
Merged via the queue into main with commit 094a39c Oct 21, 2026
48 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-24856-h16-drop-changeset-release branch October 21, 2026 01:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

2 participants