Skip to content

feat(scripts): pm patrol tooling — half-state sweeper, dispatch-gates deriver, SKILL line ratchet (#7341 PR C) - #7379

Merged
os-help merged 6 commits into
mainfrom
claude/issue-7341-pm-skill-batch-c
Aug 10, 2026
Merged

feat(scripts): pm patrol tooling — half-state sweeper, dispatch-gates deriver, SKILL line ratchet (#7341 PR C)#7379
os-help merged 6 commits into
mainfrom
claude/issue-7341-pm-skill-batch-c

Conversation

@os-help

@os-help os-help commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

Part of #7341, Part of #7239

PR C of the three-PR #7341 batch (items 2 + 4, plus the item-1 ratchet). Stacked on PR B (#7370, itself on PR A #7357) so the diff shows A+B+C until they merge in order; the C-only commits are ea495be (the tooling) and merge a2f6c8e (propagating A's item-10 follow-up). Three new zero-third-party-dependency scripts under scripts/pm/, each following the repo's scripts/check-*.mjs conventions (why-header, --self-test, absence-is-red per the #4690 anti-pattern).

1. scripts/pm/check-half-states.mjs — report-only board patrol (batch item 2)

Enumerates the label/assignee invariant violations listed on #7341: H1 pm:dispatched with no assignee; H2 assignee with no claim comment; H3 pm:queue+pm:dispatched both present (the #5925 measured specimen); H4 pm:blocked without a Blocked-by: body line; H5 pm:seat sticker title/assignee desync (Routine seats exempt from the assignee half by design; the prose 「当前 PM」 body-paragraph half is deliberately NOT machine-parsed — a fuzzy parser would report phantom desyncs, so the sweep prints the sticker URL for the patrol's own read).

Deliberately not a gate and not wire-able as one: a completed sweep exits 0 whether it found 0 or 40 violations — findings are patrol input, and failing an unrelated PR over live board state would punish the wrong actor (same reasoning that keeps check:platform-checklist out of CI). Only an unrunnable sweep (network/auth) exits non-zero. REST-only, never GraphQL (Operational notes 3). Documented as one line in the SKILL's standby-patrol section (this PR). Complements #7239 — its per-instance repairs stay with that card; this is the enumerator only.

2. scripts/pm/dispatch-gates.mjs — file surface → gate families (batch item 4)

Fills the step-5 "Local gates for this card" line from the tree at runtime: reads .github/workflows/*.yml for every check:* invocation, resolves each through package.json to its script file, scans the check scripts' own sources for the path literals they operate on, and matches the card's paths against those hints. No hardcoded check list and no path→check map exist in the script — the SKILL's own #6492 lesson (a prose copy of a list drifted three ways within an hour) and #6865 (remembered workflow facts relayed into a dispatch prompt, four of six wrong file locations). Checks with no discoverable path literals are reported once as a "repo-wide / undetermined" bucket, explicitly not known irrelevant — convention-scoped gates still match by what the change IS, and the output says so. Measured on the live tree: 75 check families across 23 workflow files, discovered, not listed.

3. scripts/pm/check-skill-line-ratchet.mjs — shrink-only ceiling, wired as check:pm-skill-ratchet (item 1's gate)

Why in C, not B: PR B is a pure byte-identical move by discipline — adding a gate script and lint.yml wiring there would break its "moves only" review contract, and stacking C on B lets the ceiling be set against the actually-landed post-B count. Ceiling 3050 vs the branch's current 3,016 lines (post-B extraction, plus PR A's item-10 follow-up merged through, plus this PR's two pointer lines): ~34 lines of headroom for ordinary rule edits between extractions. Discipline in the header: lower freely; raising requires a maintainer ruling quoted in the raising PR; growth pays its way by extraction into references/ (append-only case law) instead of raising the roof. Wired in lint.yml exactly like the sibling checks (self-test + run in the package.json script, commented step in the ESLint job).

SKILL.md touch (2 pointer lines, both in this PR by design)

  • standby-patrol section: one line naming the half-state sweeper's invocation (report-only, ⛔ not a gate);
  • step 5's gate-sourcing bash block: one line adding dispatch-gates.mjs beside the existing grep.

Verification

  • check-half-states --self-test: 16/16 (all five predicate families, both directions)
  • dispatch-gates --self-test: 14/14 (extraction, resolution, hint scanning, coverage matching)
  • check-skill-line-ratchet --self-test: 5/5; real run green — 3,016 lines, headroom 34, re-run after the item-10 propagation merge
  • Real dispatch-gates runs against .claude/agents/os-dev.md and packages/spec/src/data/filter.zod.ts: sensible families with named match-via hints
  • pnpm check:workflow-status-functions (lint.yml touched): self-test 34 assertions + real scan 23 workflows / 42 jobs — OK
  • npx eslint scripts/pm --no-inline-config — clean
  • node scripts/check-nul-bytes.mjs — OK (re-run post-merge)
  • Declared limitation: the live check-half-states sweep is not runnable from this dispatch container — bare REST returns HTTP 401 (no GITHUB_TOKEN in env; this session's GitHub access is MCP-mediated). The script's behavior on that is itself the designed one: exit 2, never a clean-board report (check:react-declaration-parity 是唯一没接进任何 workflow 的源码审计门禁,且无 MANIFEST 时静默 skip 退出 0 —— 它现在永远不可能红 #4690). Seats running with GITHUB_TOKEN/gh contexts run it directly.

Maintainer authorization (verbatim, untranslated)

关于项目经理的技能,接受你的优化意见,并和前面两个优化任务集中处理。派发使用云卡片,用 Fable 5 模型

.claude/** + scripts/** + workflow wiring only ⇒ no changeset; skip-changeset applied. #7239's per-instance repairs are referenced, not absorbed.


Generated by Claude Code

claude added 3 commits August 10, 2026 07:54
…olicy, and 7 protocol batch items (#7341 PR A)

Batch card #7341's protocol-text half, PR A of three:

- #6644 L2: devs report at draft-PR time; the PM owns CI convergence,
  ready-flip and landing. Step-5 template clause + step-7 PM duty +
  os-dev.md Definition-of-done rewrite, with a per-card wait-for-CI
  override.
- #7055: cleanup prescription drops --force — delete node_modules first,
  then unforced git worktree remove; a refusal means uncommitted work.
- #7156: closed by the L2 clause (idle-poll prohibition at the role-file
  layer), with the measured cost cited in the reporting item.
- Report-channel unification: every dev report also lands as an issue
  comment with the os-dev-report marker; the return message is an
  accelerator. Step-6 collection reads GitHub first, both modes.
- Role-file precedence rule (unconditional clauses live in os-dev.md).
- Triage classification comment gains an optional size/model suggestion
  line; executor may override with a stated reason.
- Same-account scope-marking of shared-identity claim rituals.
- [Decision] cards: every premise line carries its own re-check command.
- Model tiering rewrite: floor sonnet, default opus, ceiling fable;
  mandatory claude-fable-5 for cards touching the PM skill; three
  maintainer rulings quoted verbatim as the authority block.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QrT21cGQfFVDWtVJysRtXo
…byte-identical move (#5925 item 7, #7341 PR B)

Eight narrative blocks (9,941 bytes verbatim) leave the hot file for
references/incidents.md and references/compile-surfaces.md; the main
file keeps rule + one-line anchor + pointer at every cut point.
SKILL.md: 3,098 -> 2,997 lines. incidents.md opens with the append-only
note making it the default landing for future case law.

Cut points re-derived from the post-PR-A file; every moved chunk
verified byte-identical against the pre-move blob and absent from the
post-move file (script-extracted, not retyped).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QrT21cGQfFVDWtVJysRtXo
… deriver, SKILL line ratchet (#7341 PR C)

Three zero-dependency scripts under scripts/pm/, each with --self-test:

- check-half-states.mjs: report-only enumeration of the label/assignee
  half-states the dispatch protocol forbids (pm:dispatched without
  assignee, assignee without claim comment, pm:queue+pm:dispatched,
  pm:blocked without Blocked-by:, seat-sticker title/assignee desync).
  Deliberately not a gate: a completed sweep exits 0 regardless of
  findings; only an unrunnable sweep is non-zero.
- dispatch-gates.mjs: maps a card's file surface to the check:* families
  that watch it, derived at runtime from .github/workflows/*.yml +
  package.json + the check scripts' own path literals — no hardcoded
  list (the #6492/#6865 lesson).
- check-skill-line-ratchet.mjs: shrink-only ceiling (3050) on
  .claude/skills/pm-dispatch/SKILL.md, wired into lint.yml as
  check:pm-skill-ratchet; lower freely, raise only with a maintainer
  ruling quoted in the raising PR.

SKILL.md gains two one-line pointers: the standby-patrol section names
the half-state sweeper; step 5's gate-sourcing block names
dispatch-gates.

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

vercel Bot commented Aug 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 10, 2026 8:16am

Request Review

@os-help os-help added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 10, 2026 — with Claude
claude added 3 commits August 10, 2026 08:16
…item 10)

Maintainer ruling of 2026-08-10, quoted verbatim in the section:
「确认,M 及以上默认云卡,并进 #7341」. The 2026-08-07 heavy-card
exception list becomes examples of the M+ class, not the trigger list;
only S-grade mechanical cards stay mode:subagent. The three companion
disciplines (subscribe on creation, issue-comment report authority,
archive_session at terminal state) are named beside the new default.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QrT21cGQfFVDWtVJysRtXo
@github-actions github-actions Bot added size/xl documentation Improvements or additions to documentation ci/cd dependencies Pull requests that update a dependency file labels Aug 10, 2026
@os-help
os-help marked this pull request as ready for review August 10, 2026 09:06
@os-help
os-help added this pull request to the merge queue Aug 10, 2026
Merged via the queue into main with commit b56a163 Aug 10, 2026
27 checks passed
@os-help
os-help deleted the claude/issue-7341-pm-skill-batch-c branch August 10, 2026 09:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci/cd dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation size/xl 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