fix(pm-gate): H26 reports no SCHEDULED releaser, not an impossible one - #9391
Draft
baozhoutao wants to merge 1 commit into
Draft
fix(pm-gate): H26 reports no SCHEDULED releaser, not an impossible one#9391baozhoutao wants to merge 1 commit into
baozhoutao wants to merge 1 commit into
Conversation
H26 asserted that `pm:on-hold` and `needs-user-decision` are "by definition states a card sits in WHILE OPEN", so a `pm:blocked` card waiting on one had "NO MECHANISM THAT WILL EVER RELEASE IT". That was asserted, never counted, and counting refutes it: re-derived on this branch (objectui, 2026-09-13, REST `/issues?labels=<L>&state=<S>&per_page=100`, pull requests excluded, the population being every issue in this repository carrying the label) — `pm:on-hold` 62 open / 7 closed (6 completed, 1 not_planned), `needs-user-decision` 3 open / 3 closed (3 completed), control `pm:blocked` 100 open / 7 closed. Nine of the ten measured closures are `completed`: the hold lifted and the work finished, which is exactly the release the row said could not exist. The row now says the wait has NO SCHEDULED RELEASER — nobody has been assigned to be one — and keeps its accurate final sentence verbatim: the release has to come from the target's own state changing and someone has to want that. Six sites move together, not four: the header docblock, the #11219 rationale, the `INDEFINITE_TARGET_LABELS` jsdoc, the resolution-map rationale (its "can never close" is split across two lines, so a line-oriented grep misses it), the emitted string, and the `H26:` self-test. The self-test gains a positive pin on the new wording plus negative pins that the retired wording is gone — without the positive pin, green could not tell "fixed it" from "deleted the assertion along with the sentence it named" — and a new pin on the kept final sentence so a later rewrite cannot quietly take it with the retired half.⚠️ This file is a byte-pinned port of objectstack's copy, so `check:upstream-port-parity` goes RED on this change. See the PR body: the defect is upstream and this must not land by declaring new divergences. Refs: objectui#9317 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FhBNJcLRZLe8M87VcUgpKr
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Draft, and it must stay draft until a routing decision is made. The code change is complete
and its self-test is green, but
check:upstream-port-paritygoes RED on it for a structuralreason neither the card nor triage saw. That is reported below, not worked around.
Part of objectui#9317. Triage ruling: comment
5651018392.What the row used to say, and why it was wrong
H26 asserted that
pm:on-holdandneeds-user-decisionare "by definition states a card sitsin WHILE OPEN", so a
pm:blockedcard waiting on one had "NO MECHANISM THAT WILL EVER RELEASEIT". That was asserted, never counted.
Re-derived on this branch rather than copied from the card — objectui, 2026-09-13, REST
/issues?labels=LABEL&state=STATE&per_page=100, pull requests excluded. Population: everyISSUE in this repository carrying the label (not comments, not PRs, not call sites):
state_reasonpm:on-holdneeds-user-decisionpm:blocked(control)Control with a known direction, and it HIT: the same enumerator returned non-zero on all
three closed rows (7, 3, 7). A broken
state=closedwould have returned 0 on all three. So theclosed column is not a query artefact.
Nine of the ten measured closures are
completed— the hold lifted and the work finished, whichis exactly the release the row said could not exist.
The file had already counted the refutation against itself. On this branch's base
b67b53bc0b3026cccbc263e54cf4baa4e1e5100f, re-measured rather than copied:scripts/pm/check-half-states.mjsline 7922 — the objectui port census recordspm:on-holdon 1 closed card in a 6.2-day window.needs-user-decision"perfectly good states for a closedcard to have ended in", the direct converse of H26's line 502, in the same file.
What it says now
The wait has NO SCHEDULED RELEASER — it is waiting on a releaser nobody has been assigned to
be. Not that the state cannot be exited.
⭐ H26's final sentence is kept verbatim, per triage acceptance 2 — it was always the
accurate half: the release has to come from the target's own state changing (a ruling answered,
a hold restarted) and someone has to want that. It is now pinned by a new assertion, so a
later rewrite cannot quietly take it along with the retired half.
Six sites moved together, not four
The card and triage listed four. Re-measuring on this base found a fifth and a sixth:
#11219rationaleINDEFINITE_TARGET_LABELSjsdocH26:self-testline-oriented grep that finds every other site returns a confident miss on it. Both new sites
carry the same assertion as the four that were listed.
The control FIRES — triage acceptance 4
Green on its own cannot tell "fixed it" from "deleted the assertion along with the sentence it
named". So the self-test gains a positive pin on the new wording, and the retired-wording
pins were rewritten to assert absence rather than deleted:
NO SCHEDULED RELEASERis present — positive pinWAITING ON A RELEASER NOBODY HAS BEEN ASSIGNED TO BEis present — positive pinNO MECHANISM THAT WILL EVER RELEASE ITis gone — negative pincan never CLOSEis gone — negative pinand someone has to want thatis present — the kept half, newly pinnedTwo reverse-verification legs, each mutating the committed file, proving the mutation reached
disk by counting the marker before and after, then restoring via
git checkout HEAD --andproving the restore by an empty
git diff HEADplus a sha256 match. No build step exists forthis file — it is a plain
.mjsthat node runs directly, so there is nodist/a mutation couldfail to reach.
Self-test exit 1, 2 of 1579 cases failed: "names who is missing, not what is impossible"
and "the refuted wording is GONE from the row". ⇒ the new pins genuinely read the emitted
string.
of 1579 failed: "KEEPS the accurate half: the release must be wanted". ⇒ acceptance 2 now
has a real guard.
Unmutated: exit 0, 1579 cases pass.
⛔ Why this cannot land as-is — the blocker
scripts/pm/check-half-states.mjsin this repo is a byte-pinned verbatim port ofobjectstack-ai/objectstack:scripts/pm/check-half-states.mjs, held atscripts/upstream-port-pin.json(refbf10debd5) modulo 11 declared divergences.check:upstream-port-parityverifies it by reversing those divergences and comparing SHA-256.Measured, both sides counted on this branch:
divergences", exit 0;
blob".
⇒ the drift is this change's, not pre-existing.
The defect is upstream. objectstack
origin/main(32a32143036f34cab05772af3982384acd2a522f)still carries all of the retired wording — 10 matching lines, at its lines 537-538, 5987,
6096-6099, 24443, 24467, 24491, 24495. The same six sites exist there verbatim.
The three routes, and why the obvious one is wrong:
divergences are objectui-specific adaptations (the sweep target repo, an objectui-only
page-window knob and its self-test rows). None is a correction of a shared defect, and none
could be: the gate's own header rules that "the divergences are a checklist, not a licence"
and that "the set is meant to SHRINK". A divergence whose
whyreads "upstream is wrong"is drift written down rather than drift decided — and it would leave the false sentence live
in objectstack, where the same sweeper runs, which is the whole reason this card is p2.
port is ~11,000 lines behind (13,103 here vs 24,443 upstream), and
--resyncrewrites theported file wholesale.
whatever re-sync eventually happens. objectui#9317 then closes as fixed-at-the-producer.
My recommendation is 3, falling back to 2 if the port re-sync is wanted anyway. The
commit on this branch is the finished, tested patch, and it applies to the same six sites
upstream.
⛔ No upstream card exists for this yet — checked with a dedupe search whose control hit (24
check-half-statescards returned in objectstack, none about H26's wording). Filing it is thePM's call, not mine: this seat holds a claim on objectui#9317 only, and opening work in
objectstack under a claim it does not hold would collide with that repo's own seats.
Downstream — named, not touched
Triage acceptance 5: ⛔ objectui#2231 and objectui#2890 are the
domain:specseat's cards andare untouched here. Naming them so that seat can dispose of them: comment
5591833377onobjectui#2231 quotes H26 verbatim as "This card's unlock predicate can never fire", and
objectui#2890 mirrors it. Both now rest on a premise this branch retires. Neither card is
addressed by this pull request and neither should be closed by it.
Checks run
node scripts/pm/check-half-states.mjs --self-testpnpm type-check:scripts--listFilesconfirms)pnpm check:control-bytesnode scripts/check-changeset-presence.mjspnpm changeset:checkviteston the 4 pin tests reading this filepnpm check:upstream-port-parity🤖 Generated with Claude Code
https://claude.ai/code/session_01FhBNJcLRZLe8M87VcUgpKr
Generated by Claude Code