Skip to content

feat(pm): re-enable H22 behind a dated closure floor - #6641

Merged
os-litant merged 1 commit into
mainfrom
claude/issue-5985-h22-closure-floor
Aug 28, 2026
Merged

feat(pm): re-enable H22 behind a dated closure floor#6641
os-litant merged 1 commit into
mainfrom
claude/issue-5985-h22-closure-floor

Conversation

@os-litant

@os-litantos-litant commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator

Fixes#5985

Re-enables the half-state patrol's H22 row — a closed card still carrying a pm:* state label — behind a dated closure floor, so the ~815-card historical backlog needs no backfill and generates no noise.

What

  • .github/workflows/half-state-patrol.yml — the PM_SWEEP_CLOSED_WINDOW_PAGES: '0' hold is removed (the closed-card window returns to the sweeper's own default of 4 pages), replaced by PM_SWEEP_CLOSED_FLOOR: '2026-08-28'. Divergence note 1 in the header is rewritten to document a floor instead of an off-switch.
  • scripts/pm/check-half-states.mjs — the floor mechanism, ported from upstream (see the sequencing note below).
  • scripts/__tests__/check-half-states.test.ts — the adaptation pins updated to the new arrangement.

Why this is not the 87% re-enable the card refused

The measurement that forced the original hold stands, and is exactly why the re-enable is floored rather than plain. Measured 2026-08-24: 815 closed cards here carry pm:dispatched, and ~347 of the 400 issues in the window carry some pm:* residue (~87%, against the 26% upstream measured). An unfloored re-enable would report the convention, not defects — ~347 rows that exhaust the anchor body budget and trim every other predicate out of the report.

#5985 framed the way out as two-way: either stripping is the rule (and ~815 cards need a backfill first) or the row is simply not wanted here. The dated floor is the third option both readings omit. pm:* on a card closed before the convention existed is inert history — the dispatch loop reads state on open cards only — so judging from the cutover forward buys the row's whole value at zero backfill and zero historical noise.

No bulk label backfill of closed cards was run, and none is owed. The sweeper writes no label under any code path, so no bulk rewrite is even reachable from here.

The cutover is 2026-08-28, the date the strip-on-close convention was written into the pm-dispatch protocol's label-discipline section.

⚠️ The earlier ruling on this card is superseded

An earlier domain:devx comment on #5985 ruled the opposite — keep pm:* on closed cards, H22 permanently off, reasoning that a rule nobody had ever followed was not a rule this repo had. That is superseded by the 2026-08-28 skills-lane grading, on two grounds: fleet practice has since uniformly stripped pm:* on close (the 2026-08-27/28 landing accounting made it a hard step across ~20 closures), and the dated floor dissolves the backfill dilemma the old ruling was avoiding.

That ruling also asked that the summary stop saying the closed surface is "UNREAD, not clean". It now does: with the reader on, the sweeper renders the floored read and names the floor date.

⚠️ The port mechanism — and why this PR is not workflow-only

The dispatch assumed a workflow-only diff. It cannot be, and the reason is worth recording:

objectui runs its own ported copy of the sweeper, not upstream's file. That copy is 572 KB against upstream's 784 KB — it has drifted substantially since the port. Critically, resolveClosedWindowPages / PM_SWEEP_CLOSED_WINDOW_PAGES exist only here; they were authored during the port and never upstreamed (git log -S in objectstack finds nothing). There is no sync script and no gate that verifies the two copies match — the port is a manual copy whose divergences are documented by hand in the workflow header.

So setting PM_SWEEP_CLOSED_FLOOR in the workflow while dropping the hold, with no code change here, would have set an env var this copy does not read: the closed reader would have run at 4 pages with no floor, over a board that is ~87% residue. That is precisely the outcome #5985's stop clause forbids. The floor therefore had to be ported alongside the wiring.

⚠️ The floor code is upstream's, not a fourth hand divergence — a re-sync that replaces this file with upstream's keeps it. What diverges is the wiring: upstream sets no floor, because its own board measured 26% and it treats recent closed residue as a live duty.

Replaced pin, not a respelled one

scripts/__tests__/check-half-states.test.ts asserted that the workflow still carries the PM_SWEEP_CLOSED_WINDOW_PAGES zero — a pin that encoded the superseded ruling. It is replaced rather than respelled, and the block now pins:

  • the hold's absence (asserted directly — left in place beside a floor, 0 pages would win silently and the anchor would keep reporting UNREAD while looking re-enabled);
  • the floor set in the workflow and resolving to the expected instant;
  • the floor applied to the predicate, both directions, with the cutover date itself judged (inclusive boundary);
  • malformed floors refused rather than degrading to "no floor";
  • the summary naming the floor, so a floored pass cannot read as a full one;
  • the DISABLED branch still reporting UNREAD — no longer wired, but still live code and still the property the port turned on.

This is the trap the gate-script discipline warns about: the derived gate families were all green while this pinned suite was red, and only running the script's own suite surfaced it.

Verification — run on d9b496c

CheckVerdict lineExit
check-half-states --self-test✓ check-half-states self-test: 1116 cases pass.0
vitest scripts/__tests__/check-half-states.test.tsTest Files 1 passed (1) · Tests 18 passed (18)0
sibling suites reading this workflowTest Files 2 passed (2) · Tests 62 passed (62)0
pnpm type-check:scripts(clean, no diagnostics)0
pnpm check:control-bytes✅ check-control-bytes: OK (scanned 5487 tracked text file(s); skipped 85 binary).0
pnpm check:entry-guard✓ check:entry-guard: 50 scripts/ file(s) — no entry guard outside the baseline0
pnpm check:shell-escape-residue✅ check-shell-escape-residue: OK (4/4 root(s) resolved …)0
pnpm check:skills-paths✅ check-skills-paths: OK (93/94 stated path(s) resolve …; 1 baselined).0
node scripts/check-changeset-presence.mjs✅ No source of a released package changed in this range, so no changeset is owed.0

No changeset: the presence gate reports 2 file(s) changed, 0 of them published source of a package the release covers and declares nothing owed. ⛔ No skip-changeset label applied here — that label object exists in this repo but nothing reads it, so applying it would only hang a false status on the PR.

The floor was also driven end-to-end against the real predicate with the workflow's own value: a card closed 2026-01-01 is skipped, one closed 2026-08-29 is reported.

Sequencing

objectstack-ai/objectstack#12906 carries the same floor upstream plus the protocol sentence. That leg should land first. This PR does not import it — objectui runs its own copy — but if this merged first, objectui's copy would carry a floor that objectstack main lacked, and the next verbatim re-sync would silently remove the floor and restore the ~87% flood. That is the exact hazard divergence note 1 exists to prevent.

Draft until then.

Provenance

Authoring session: https://claude.ai/code/session_01MnijPVVDakqK2J335JoJtq

Generated by Claude Code

The half-state patrol shipped with its closed-card reader fully off
(`PM_SWEEP_CLOSED_WINDOW_PAGES: '0'`). The measurement behind that hold stands:
815 closed cards here carry `pm:dispatched`, and ~347 of the 400 issues in the
window carry some `pm:*` residue (~87%). At that density H22 reports the
convention rather than a defect and exhausts the anchor body budget.
The card framed the way out as two-way — backfill ~815 cards, or drop the row.
The dated floor is the third option: judge only cards closed on/after the
cutover. Historical `pm:*` on an old closed card is inert (the loop reads state
on open cards only), so the row gets its whole value at zero backfill and zero
historical noise. No bulk label backfill was run and none is owed; the sweeper
writes no label under any code path.
The floor is upstream code, ported — not a new hand divergence. A re-sync that
replaces the sweeper with upstream's keeps it. What diverges is the wiring, and
divergence 1 in the workflow header now documents a floor instead of an
off-switch.
The pinned suite's `is switched off by the workflow` case is REPLACED rather
than respelled: it encoded the superseded ruling that stripping `pm:*` on close
is not this lane's convention.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Decide the pm:*-on-close convention, which gates re-enabling the patrol's H22 row

2 participants

@os-litant@claude