Skip to content

docs(ci-cd-pipeline): correct the Half-State Patrol wiring and pin it against the workflow - #8061

Merged
baozhoutao merged 2 commits into
mainfrom
claude/issue-8043-half-state-patrol-doc-knob
Sep 6, 2026
Merged

docs(ci-cd-pipeline): correct the Half-State Patrol wiring and pin it against the workflow#8061
baozhoutao merged 2 commits into
mainfrom
claude/issue-8043-half-state-patrol-doc-knob

Conversation

@baozhoutao

Copy link
Copy Markdown
Contributor

Fixes #8043

The Half-State Patrol section told readers the sweeper's closed-card reader was "switched off here via PM_SWEEP_CLOSED_WINDOW_PAGES: '0'". .github/workflows/half-state-patrol.yml stopped setting that variable on 2026-08-28. It survives only in the file's header comments, as history — so the page sent anyone looking for the switch to a variable nothing assigns, and, in the direction this page is actually read, described a predicate as disabled while it ran four times a day.

Head this was measured on: 8d17db858.

What the workflow actually sets

Re-derived on the merged head, comments excluded on the workflow side:

PM_SWEEP_REPO           .github/workflows/half-state-patrol.yml:272
PM_SWEEP_CLOSED_FLOOR   .github/workflows/half-state-patrol.yml:280   '2026-08-28'

PM_SWEEP_CLOSED_WINDOW_PAGES appears at :39 and :80 only, both whole-line comments. So: the closed-card reader is on with a dated floor, the page window is deliberately absent (back to CLOSED_ISSUE_WINDOW_PAGES = 4, the sweeper's own upstream default), and the floor — not a zeroed window — is what keeps the ~815 historical pm:dispatched carriers out.

The rewrite

Sourced from the workflow's env-block comment (:270-280) and its header divergence (1) (:37-39), which are the two places this install records the wiring. Two paragraphs where there was one: what is set, and why a floor rather than a plain "on" (the 2026-08-24 measurement, the body-budget consequence, the no-backfill reasoning, the loud refusal of a malformed value).

Two neighbouring claims were re-checked against the code rather than carried over:

  • "Stripping pm:* on close was never this repo's practice" — no longer true as written. It became the practice on the cutover date; that is what the floor is dated to. Rewritten to say so.
  • "The rendered summary says that surface is UNREAD, never that it is clean" — true only while the escape hatch is set. summaryLine in scripts/pm/check-half-states.mjs branches on closedWindowDisabled; with the window unset it renders H22 read N recently-closed issue(s) … only cards closed on/after 2026-08-28 are judged. Kept, but re-conditioned onto the hatch, which is dormant live code rather than removed.

The retired identifier is deliberately not named in the section any more — a page that names a variable nothing sets is the defect, and the pin below enforces its absence.

#7852 is the parent; it stays open for its half ①, the repository variable HALF_STATE_ANCHOR_ISSUE, which only a maintainer can set. Nothing here touches that half. The workflow itself is read, not written.

The pin

scripts/__tests__/ci-cd-pipeline-doc.test.ts, a new describe block; no existing assertion changed. Every PM_SWEEP_* identifier the Half-State Patrol section names must be a key the workflow sets in an env: mapping.

The comparison reads env keys, never the file as text. That is the load-bearing part: a whole-file grep finds PM_SWEEP_CLOSED_WINDOW_PAGES in the header at :39 / :80 and accepts the exact sentence this pin exists to reject. envKeysOf strips whole-line comments and reads only children at env:'s indent + 2, so the continuation lines of a folded scalar (PROVENANCE: >- has three) cannot be mistaken for keys; it is unit-controlled against a specimen carrying both shapes.

Four legs: the two non-vacuity checks (the workflow-side set non-empty, the doc-side set non-empty — a rewrite that names nothing leaves the comparison green over an empty list); the extractor control; the set comparison; and a value leg requiring the section to quote the floor date the sweep step is given.

The workflow inventory block above it matches filenames in headings, so a false sentence inside a documented section is precisely what it cannot see — #7852 says that in as many words. This closes that gap for the one thing on this page that names the sweeper's wiring by identifier.

Ablation

Doc mutated on disk back to the wrong sentence, run, restored under a trap, blob compared both ways.

HEAD blob   = e2db116a866c53033c1f9d34de5ba81e060c8618
before blob = e2db116a866c53033c1f9d34de5ba81e060c8618   (tree at HEAD before mutating)
after blob  = cd01541b3ab4631ca101f9c83b8e9313a4dc1008   (changed -> not a no-op)

anchors  PM_SWEEP_CLOSED_FLOOR         1 -> 0
         PM_SWEEP_CLOSED_WINDOW_PAGES  0 -> 1

ABLATION-VITEST-EXIT=1     Tests  2 failed | 42 passed (44)
RESTORE-DIFF: 0 path(s) still differing        blob back to e2db116a8

Red exactly as predicted, naming the knob:

AssertionError: The Half-State Patrol section names these `PM_SWEEP_*` variables:
  - PM_SWEEP_CLOSED_WINDOW_PAGES

…and `half-state-patrol.yml` sets none of them. What it does set is:
  - PM_SWEEP_CLOSED_FLOOR
  - PM_SWEEP_REPO

The second failure is the value leg (the section must keep naming the floor variable). The mutation was committed-state-relative: the implementation was committed first, so the restore leg had a real restore point, and it is verified by blob equality rather than by an exit code.

Gates

All on 8d17db858 unless noted.

Gate Verdict
pnpm exec vitest run scripts/__tests__/ci-cd-pipeline-doc.test.ts Tests 44 passed (44)
pnpm exec vitest run scripts/__tests__/ 111 passed (111) / 3331 passed (3331) — see note
pnpm type-check:scripts exit 0
pnpm lint:root exit 0
pnpm check:doc-fences exit 0
pnpm check:doc-snippets Scanned 227 document(s): 211 covered … Semantic phase: 549 of 549 block(s) judged, 0 failed.
node scripts/check-doc-links.mjs Links are valid across 17 scan roots.
pnpm check:doc-example-readers exit 0
pnpm check:control-bytes + manual grep -naP over both paths exit 0; grep exit 1 (no matches)
node scripts/check-changeset-presence.mjs No source or published contract of a released package changed in this range, so no changeset is owed.
node scripts/check-governed-queue-guard.mjs --test <both paths> NOT GOVERNED — 2 path(s) checked against 5 governed surface(s); none matched.
node scripts/check-doc-component-types.mjs Every documented component type is registered.
node scripts/check-doc-expression-carriage.mjs exit 0 (report-only census)
node scripts/check-shell-escape-residue.mjs exit 0
node scripts/check-upstream-port-parity.mjs 3 ported file(s) match … modulo their declared divergences.
pnpm exec vitest run packages/auth/src/__tests__/reserved-auth-features.test.ts 17 passed (17) — the one reader of this page outside scripts/__tests__

check:doc-snippets first answered PRECONDITION NOT MET (exit 2) — not a red, and not a reading about any document. Ran its own scoped build (--build-filter, 34 tasks) and re-ran; the green above is the measured one.

One flake, recorded rather than papered over. On the first scripts/__tests__/ run after merging origin/main, two corpus tests in check-doc-links.test.ts timed out at 15000ms (1 failed | 110 passed). Same tree content for those files had passed the same command minutes earlier (111 passed), and the file alone re-runs green in 12.5s for all 121 tests. The variable is container load, not this diff — the run that failed took 188s against 118s for the green one. node scripts/check-doc-links.mjs, the gate itself, is green on the merged head.

No changeset: docs plus a scripts/__tests__ file, and the presence script agrees. skip-changeset is a phantom label in this repository (this same test file pins that at :235 / :277); no label was applied.

Live E2E (informational) is red on every branch today for an upstream reason (#7990) and is not this branch's.


🤖 Generated with Claude Code

https://claude.ai/code/session_01FhBNJcLRZLe8M87VcUgpKr


Generated by Claude Code

The section said the sweeper's closed-card reader is "switched off here via
PM_SWEEP_CLOSED_WINDOW_PAGES: '0'". half-state-patrol.yml stopped setting that
variable on 2026-08-28; it survives only in the file's header comments as
history. The sweep step sets PM_SWEEP_CLOSED_FLOOR: '2026-08-28' instead: the
reader is ON, the page window is deliberately absent (back to the sweeper's
upstream default of 4), and the dated floor -- not a zeroed window -- is what
keeps the ~815 historical pm:dispatched carriers out.

Rewritten against the workflow's own env-block comment and header divergence
(1). The "UNREAD, never clean" summary branch is kept but re-conditioned: it
fires only while the escape hatch is set, and it is unset here.

Pinned in scripts/__tests__/ci-cd-pipeline-doc.test.ts: every PM_SWEEP_*
identifier the section names must be one the workflow sets as an env KEY --
never a whole-file grep, which would find the retired knob in the header
comments and accept the sentence this pin rejects. envKeysOf is unit-controlled
against that shape, and both sides carry a non-vacuity leg.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhBNJcLRZLe8M87VcUgpKr

Copy link
Copy Markdown
Contributor Author

Standing down on Live E2E (informational): that check is red on main itself today (base-red, anchored on objectui#7990 / objectstack-ai/objectstack#16186), it is informational (not required), and this PR changes one docs section and one scripts/__tests__ file — nothing the live lane exercises. No fix is ported because none exists yet upstream. The flip to ready happens only once every non-informational check on 8d17db858 is green.


Generated by Claude Code

@baozhoutao
baozhoutao marked this pull request as ready for review September 6, 2026 13:51
@baozhoutao
baozhoutao added this pull request to the merge queue Sep 6, 2026
Merged via the queue into main with commit 1198027 Sep 6, 2026
30 of 31 checks passed
@baozhoutao
baozhoutao deleted the claude/issue-8043-half-state-patrol-doc-knob branch September 6, 2026 14:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

2 participants