Skip to content

ci(pm): retire the half-state patrol's schedule — on demand only; every scheduled invocation of the patrol action stops (ruling #208 on #19491) #19497

Description

@os-project-manager

Path: none | tooling | maintainer-directed (ruling #208 on #19491) — dispatched at filing, never queued

Filed and dispatched by the director seat, summon #25 (session_012GcsUbuqFGBibkEDMRC1eE), under the maintainer's verbatim direct-dispatch instruction: Ruling #208 on #19491 — maintainer 「19491 接受你的建议,并立刻派发处理相关任务。」 (2026-09-21, chat, on the director seat's 档 2 package R1–R7). Direct-dispatch channel (SKILL.md 〈多仓协调〉规则 4 「维护者直派通道」): the audit quote above is the authorization; ⛔ not a triage grading, ⛔ never queued. The full analysis and measured table are the ruling record on #19491.

Why (measured, 2026-09-21T03:43Z, origin/main 4045781)

scripts/pm/check-half-states.mjs is 36,717 lines / 2.48 MB with 68 H rows, changed 52 times in 14 days (8 times on 2026-09-20, every one a misread repair). It blocks no branch, but the charter made its anchor rows a dispatch precondition, so a row that misreads a now-legal state costs every executive seat a handling step, four times a day, until a dev repairs the row — the loop the maintainer asked to stop (「留着却不继续开发,会不会反而不停的报错误的信息」 — yes, and this card is the answer). Ruled: retire the schedule, keep the script runnable on demand, delete no line of it; the charter half (the anchor is no longer a precondition) is the sibling charter card filed with this one.

The change (.github/** — not on the governed register: Tier S, the director seat lands it after an at-tier read)

  1. .github/workflows/half-state-patrol.yml: remove the schedule: block (today cron: '37 1,7,13,19 * * *'); keep workflow_dispatch: {} exactly. Rewrite the header prose that explains the four-times-a-day cadence and the :37 offset so it describes on-demand use, citing this ruling (objectstack#19491, ruling 🔗 Broken links detected in documentation #208) — the file's own comments must not promise a schedule that no longer exists.
  2. Census every other scheduled path into the patrol: git grep -n 'half-state-patrol' .github (PR ci(pm): make the half-state patrol callable instead of copied #19225 made the patrol a callable action, .github/actions/half-state-patrol/action.yml; board-snapshot.yml, checklist-status.yml, merged-branch-reaper.yml were hits on a wider grep). Any workflow that runs the patrol action on a schedule loses that call or that schedule in this PR (say which, per file); a workflow that calls it only on workflow_dispatch or as part of a maintainer-run job stays. ⛔ Do not touch the action file or the script.
  3. The anchor issue (vars.HALF_STATE_ANCHOR_ISSUE) keeps its last body; the triage seat may run the workflow by hand for its daily full reconciliation. Row H57 (「the workflow's latest scheduled run is green and fresh」) will read the retired schedule as stale on every on-demand run: state this in the PR body as a known, unread reading; ⛔ do not edit check-half-states.mjs for it — if a one-line fix exists, put it in out_of_scope_findings.

Acceptance

  • git grep -n 'cron' .github/workflows/half-state-patrol.yml = 0 with control git grep -n 'workflow_dispatch' .github/workflows/half-state-patrol.yml = 1; the census of item 2 listed file by file with the verdict per file.
  • Every family node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derives for a .github/workflows/** diff (workflow lint / self-test-wired / gate-population families), exit codes captured before any pipe; bash scripts/ci/select-gate-families.selftest.sh still passes (it reads lint.yml, untouched here).
  • PR body: the ruling quote, the census, the H57 note; skip-changeset (nothing under packages/**).

Out of scope

The charter's anchor-precondition lines (sibling card); the self-test scoping in lint.yml (sibling card); any trimming of the 68 rows (⛔ ruled not now — a PR on a 36,717-line file is its own risk; if the script stays unused for a month it is deleted whole, on its own card).


Generated by Claude Code

Activity

  1. os-project-manager commented on Sep 21, 2026

    @os-project-manager
    CollaboratorAuthor

    Claim: objectstack#19497 — director seat, summon #25, session_012GcsUbuqFGBibkEDMRC1eE, 2026-09-21T04:12Z
    Branch: claude/issue-19497-patrol-schedule-retired
    Seat: director
    Mode: subagent
    Clause-②: no

    Direct dispatch under the maintainer's verbatim 「19491 接受你的建议,并立刻派发处理相关任务。」 (ruling #208 on #19491). File surface declared for the in-flight intersection check: .github/workflows/half-state-patrol.yml (schedule block + header prose) and any other workflow that runs the patrol action on a schedule. Concurrency: three maintainer-directed tooling devs in flight at once for this ruling (#19496, #19497, #19498), disjoint file surfaces; the ≤1 tooling dev rule of ruling #202 B yields to the maintainer's 「立刻派发」 for this batch only. Review: at-tier, diff-scoped, CI read from check-runs (R5's shape, applied to these PRs first).


    Generated by Claude Code

  2. os-project-manager commented on Sep 21, 2026

    @os-project-manager
    CollaboratorAuthor

    os-dev-report

    Reported 2026-09-21T05:01Z - draft PR #19516, head dbeb16d, branch claude/issue-19497-patrol-schedule-retired

    {
    "issue": 19497,
    "status": "done",
    "branch": "claude/issue-19497-patrol-schedule-retired",
    "pr": "#19516",
    "head": "dbeb16ddbb1032dfd15d69445969ff61fdc5e69a",
    "session": "session_012GcsUbuqFGBibkEDMRC1eE",
    "premise_still_valid": true,
    "summary": "The patrol workflow's schedule: block (37 1,7,13,19 * * *) is gone; workflow_dispatch: {} and the pull_request: paths trigger are byte-identical, and the header prose that promised the four-times-a-day cadence is rewritten in seven places for on-demand use, carrying the maintainer's sentence and the forbidding of a silent re-schedule. The action file and scripts/pm/check-half-states.mjs are untouched (0 of its 36,717 lines). The census found exactly one scheduled invocation of the patrol in the whole tree — this workflow — so no other file loses a call or a schedule; board-snapshot.yml, lint.yml, checklist-status.yml, merged-branch-reaper.yml and ten prose-only files keep everything they had, listed file by file in the PR body. ONE FILE OUTSIDE THE CARD'S SURFACE WAS TOUCHED AND IS FLAGGED: retiring the schedule falsified two cases of scripts/pm/dispatch-gates.mjs's self-test that read the live workflows tree and assert the specimen declares schedule (measured red first: 2 of 1883, and no others); check:pm-dispatch-gates is a required context and the CI family selector runs it for a workflow-class path, so the pin was repaired in the same change that made it false, minimally, adding nothing.",
    "tests": "48 of 48 derived families run and reconciled: node scripts/pm/dispatch-gates.mjs --ran RANFILE --repo objectstack-ai/objectstack -> 'Run reconciliation - 48 derived, 48 run, 0 NOT-MEASURED, 0 UNRUN' and 'a DERIVED zero - all 48 recorded an exit code and none of them is 3'. 47 exited 0 in one detached battery (exit code captured before any pipe: cmd > log 2>&1; code=$?). The 48th, pnpm check:pm-dispatch-gates, is the reverse-verification pair for the repair, both legs from committed states: BEFORE (51a65a3, workflow-only) '✗ dispatch-gates self-test: 2 of 1883 case(s) failed' naming exactly the two schedule pins; AFTER (dbeb16d) '✓ dispatch-gates self-test: 1883 cases pass' + 'the battery took 1031.6s on this box', exit 0. Also bash scripts/ci/select-gate-families.selftest.sh exit 0, 'all 40 cases passed (192 checks)'. Acceptance greps: git grep -n 'cron' .github/workflows/half-state-patrol.yml = 0 hits (exit 1), was 1 line on the base tree; control git grep -c 'workflow_dispatch' = 3 (was 2 - the trigger key plus two rewritten prose mentions; the trigger key itself is exactly one, line 174) and the parsed on: mapping reads {'workflow_dispatch': {}, 'pull_request': {...}} with no schedule. node scripts/pm/check-governed-merges.mjs --branch claude/issue-19497-patrol-schedule-retired on the final file list: '0 of 2 path(s) hit the register ... NOT governed', 134 changed lines. actionlint is not wired in this repo (0 hits in .github/workflows/*.yml and package.json). NOT MEASURED: the 54 artifact-roster families, 11 wide-population families, 14 pending-changeset families and the always-runs tail the same tool prints outside the derived 48 - CI owns those.",
    "mcp_calls": "0 - no MCP tool was called, GitHub or otherwise",
    "api_writes": "2 - POST /repos/objectstack-ai/objectstack/pulls (draft PR 19516), POST /repos//issues/19497/comments (this report, via scripts/pm/post-stamped.mjs). No labels, no assignee, no ready flip, no PATCH of any body, no issue created. Four git pushes to the feature branch are outside the REST budget.",
    "open_questions": [
    {
    "question": "scripts/pm/dispatch-gates.mjs is ruled 'kept frozen' by R6, yet this PR edits two of its self-test cases because retiring the schedule makes them false and the gate is a required context. Is the forced pin repair inside the freeze or outside it?",
    "options": [
    "A - keep it here: the repair is the smallest thing that makes a required gate true again, adds no assertion, and is the same PR that falsified the pin",
    "B - split it into its own PR so the card's diff stays inside its named surface, and land that one first",
    "C - revert the repair and let the PR sit red until the sibling card's work lands, on the argument that the freeze binds absolutely"
    ],
    "recommendation": "A, because the pin is false only because of this change, and a PR that knowingly leaves a required context red on main is the expensive option; B costs a second round and lands the same two lines; C leaves a false pin on main for as long as it takes."
    }
    ],
    "out_of_scope_findings": [
    "to file (3 classes, dedupe words: PATROL_CRON, renderCadenceExpectation, anchor cadence deadline, half-state heartbeat, retired schedule) - class (a): renderCadenceExpectation() in scripts/pm/check-half-states.mjs stamps 'expected every 6h (...) - next by ...' beside Swept in the anchor body on EVERY run, computed from PATROL_CRON / PATROL_CADENCE_HOURS, so from this PR onward the pinned anchor publishes a deadline against a schedule nothing fires. One-line shape: render the cadence clause only when the caller passes a schedule, i.e. make the constants optional rather than assumed. Blocked by the ruling's 'no line of the 36,717 is edited' - a seat must file it and a later card must land it.",
    "noted, not filed: the card's item-3 expectation about H57 is falsified and the PR body carries the measurement - h57Population() holds any workflow declaring pull_request out of H57's population (H57_PR_GATING_EVENTS), and half-state-patrol.yml declared pull_request before this PR, so H57 never judged it and could not have read the retired schedule as stale. After this PR it is held out one branch earlier, as not-scheduled. The only visible change is the population summary line: one fewer 'declares a schedule', one fewer held out as PR-gating.",
    "noted, not filed: stale cadence prose in files this PR does not own - .github/workflows/lint.yml:4742 ('runs REPORT-ONLY in half-state-patrol.yml, four times a day'), successor: the sibling card's dev, already in flight in that file; .github/workflows/board-snapshot.yml:38,140 and .github/workflows/release-coverage-patrol.yml:102,113 cite the retired cron as the reason their own minute/hour was chosen (the offsets stay correct, only the reason is now historical), successor: none scheduled; scripts/pm/check-half-states.mjs header prose ('a scheduled caller'), under the same forbidding as its constants."
    ]
    }


    Generated by Claude Code

  3. os-project-manager commented on Sep 21, 2026

    @os-project-manager
    CollaboratorAuthor

    Landing record — director seat, summon #25 (session_012GcsUbuqFGBibkEDMRC1eE), 2026-09-21T06:09Z. PR #19516 merged through the queue (d76facf22a5daa6c8c642ff595cd0ae681d381ad, 2026-09-21T06:08Z), verified on fetched origin/main: .github/workflows/half-state-patrol.yml declares workflow_dispatch and the pre-existing pull_request paths trigger and no schedule (grep on main); .github/actions/half-state-patrol/action.yml and scripts/pm/check-half-states.mjs untouched; the two dispatch-gates.mjs self-test pins repaired in the same change. Contract review of record 5755780744 (PASS on head dbeb16dd), provenance 5755791129. Ruling #208 R3's workflow half is thereby in force: the half-state patrol runs on demand only (the triage seat's daily full reconciliation may dispatch it; sweep-closed-cards.mjs's 72-hour default window means at least every three days or a wider --window); the charter half (the anchor is no longer a dispatch precondition) lands with PR #19513. GitHub closed this card on the Fixes keyword; pm:dispatched removed in this stroke so the close is whole.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions