Skip to content

tooling(pm): name the sweeper's third file in the half-state patrol's adopt list - #15000

Merged
os-steve merged 1 commit into
mainfrom
claude/issue-14881-hotcrm-half-state-patrol
Sep 3, 2026
Merged

tooling(pm): name the sweeper's third file in the half-state patrol's adopt list#15000
os-steve merged 1 commit into
mainfrom
claude/issue-14881-hotcrm-half-state-patrol

Conversation

@os-steve

@os-steve os-steve commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Part of #14881 — this is the objectstack half of that card. The hotcrm half (the workflow copy, the anchor issue and the repository variable) stays open and is delivered to the PM as an install recipe for the repo:hotcrm seam card, so this PR deliberately does not carry a closing keyword.

What was measured, and what it found

The card asks whether .github/workflows/half-state-patrol.yml and scripts/pm/check-half-states.mjs need any change before the patrol is installed in a sibling repo. The answer is yes, and it is not the change anyone expected: the documented install has been missing a required file.

The workflow header's adopt list (step 1) said to copy two files — the sweeper and this workflow. The sweeper's line 897 is:

import { isEntrypoint } from '../invoked-as.mjs';

so it also needs scripts/invoked-as.mjs. Measured on a clean two-file copy of this repo's own files, in a scratch directory:

$ node scripts/pm/check-half-states.mjs --self-test
Error [ERR_MODULE_NOT_FOUND]: Cannot find module '.../scripts/invoked-as.mjs'
  imported from '.../scripts/pm/check-half-states.mjs'
exit 1

$ cp .../scripts/invoked-as.mjs scripts/        # the third file
$ node scripts/pm/check-half-states.mjs --self-test
✓ check-half-states self-test: 2062 cases pass.
exit 0

A repo that followed the list verbatim installed a patrol that cannot start. It fails loudly — the sweep step exits 1, the job's final step turns the run red, and the anchor is rewritten with the "THE SWEEP DID NOT RUN" body — which is the one mercy in it. But the adopter still gets a dead patrol on day one, and the fleet has two more adopters queued behind hotcrm.

The adopted objectui copy already carries the fix on its side: its port added scripts/invoked-as.mjs to the same paths: filter, with the note that the sweeper imports the helper and it "was ported alongside". Upstream is catching up to its own port.

The three changes, all in the workflow

  1. The adopt list names three files, with the measurement above recorded next to it and a standing instruction not to shorten the list from memory again — the import decides it, not the comment.
  2. The "No pnpm install" note states the sweeper's real import set (node: builtins process / child_process / fs / url, global fetch, plus the one repo-local helper) instead of "nothing but node:process and global fetch". The note's conclusion was always right — there is still no npm dependency — but that sentence is exactly what an adopter checks the copy list against, so leaving it stale re-creates the defect one reader later.
  3. scripts/invoked-as.mjs joins the pull_request path filter. Named explicitly because it is the one change here that is not a comment: it is a bounded in-place fix of the same defect one layer down. The dependency was undeclared in both places that have to name it, and with the filter as it stood a change to the helper could break the patrol with no PR-time proof running. Scan for the boundary: invoked-as.mjs has exactly one reader under scripts/pm/, the import above; no other workflow filters on it; the row is byte-identical in intent to the objectui copy's.

What is NOT changed, and why

scripts/pm/check-half-states.mjs is untouched, so this repo's sweep behaviour is byte-identical by construction rather than by assertion.

In particular, no priority-axis parameter was added. hotcrm spells that axis prio:p0/p1/p2 where this repo spells it priority:p0, and a --priority-prefix knob was the obvious candidate change. It is the wrong one: scripts/pm/ensure-pm-labels.sh already seeds priority:p0 into all five fleet repos including hotcrm, and says why in its own comment — "It is in this five-repo loop because that sweep is repo-parameterized (PM_SWEEP_REPO) and grading is a five-repo triage duty". The fleet's declared design is one vocabulary seeded everywhere, not a per-repo dialect in the shared tool; the unused priority:p0 label object the repo:hotcrm seat found sitting at zero cards in hotcrm is that seeding's own product. Teaching the sweeper a second spelling would be consumer-side tolerance for a producer-side divergence. The coverage gap it leaves is real and is reported on the card instead.

Gates

Re-derived after the final commit with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack (no paths — the script takes its own changeset), which reported 27 runnable families; all 27 were harvested with --commands and run at 5c85a642, all exit 0. Their own verdict lines, quoted:

✓ check-half-states self-test: 2062 cases pass.
✓ check-self-test-wired: every one of the 166 script(s) CI runs that ship a
  `--self-test` has that self-test run by CI.
check-nul-bytes: OK (scanned 8160 text file(s) -- 8160 tracked, 0
  untracked-not-ignored; skipped 7 binary; no raw ASCII control bytes).
✓ check:declared-population-live — 159 of 204 famil(ies) declare a path
  population, and every one of them reaches this tree's 8167 tracked file(s).

The one substitution, declared: the derivation lists node scripts/pm/check-half-states.mjs bare, which is the workflow's live sweep against the real board rather than a local gate; it was run in its --self-test form instead.

The workflow parses (yaml.safe_load, pull_request.paths reads back as the three expected entries).

Repo-wide pnpm lint was narrowed, and the narrowing is measured rather than asserted: eslint's own accounting for the changed file is File ignored because no matching configuration was supplied — the flat config supplies no matcher for .yml, so eslint linted 0 of this diff (--format json, one entry, zero errors). The diff touches no JS or TS, and type-aware linting is not enabled, so no untouched file's verdict can move because of it. pnpm lint therefore cannot change in either direction here; CI runs it regardless.

skip-changeset: this ships nothing from any released package — a workflow comment plus one path-filter row.

Generated by Claude Code


Generated by Claude Code

The half-state patrol's documented sibling install listed two files to copy
(`scripts/pm/check-half-states.mjs` and the workflow) while the sweeper has
imported `../invoked-as.mjs` since before that list was written. A repo that
followed it verbatim installed a patrol that cannot start.

Measured on a clean two-file copy of this repo's own files:

    Error [ERR_MODULE_NOT_FOUND]: Cannot find module
      '.../scripts/invoked-as.mjs' imported from
      '.../scripts/pm/check-half-states.mjs'
    exit 1

The same copy with `scripts/invoked-as.mjs` added runs the sweeper's
`--self-test` to `2062 cases pass`, exit 0. The failure is loud rather than
silent — the job's final step turns the run red and the anchor is rewritten
with the "THE SWEEP DID NOT RUN" body — but the adopter still gets a dead
patrol, and the next two adopters in the fleet would each get one.

Three comment/wiring corrections, all in the workflow; the sweeper is not
touched, so this repo's sweep behaviour is byte-identical by construction:

  - the adopt list names three files, with the measurement that decides it;
  - the "No `pnpm install`" note states the sweeper's real import set
    (`node:` builtins plus the one repo-local helper) instead of "nothing but
    `node:process` and global `fetch`" — that sentence is what an adopter
    checks the copy list against, so a stale one re-creates the defect;
  - `scripts/invoked-as.mjs` joins the `pull_request` path filter, so a change
    to it gets the same pre-merge proof the other two files get. The adopted
    objectui copy has carried that row since its port.

Part of #14881

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019RfFHiRCSs3JXLK4cwcfox
@claude claude Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 3, 2026
@os-steve
os-steve marked this pull request as ready for review September 3, 2026 17:23
@os-steve
os-steve enabled auto-merge September 3, 2026 17:24
@os-steve
os-steve added this pull request to the merge queue Sep 3, 2026
Merged via the queue into main with commit 99b4deb Sep 3, 2026
32 checks passed
@os-steve
os-steve deleted the claude/issue-14881-hotcrm-half-state-patrol branch September 3, 2026 17:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants