Skip to content

docs(pm): fold the SKILL.md serial chain — lane consolidation, lane job descriptions, request cards, foreign-gate parking, family dispatch - #9899

Merged
os-warren merged 5 commits into
mainfrom
claude/issue-9854-skill-chain-fold
Aug 19, 2026
Merged

docs(pm): fold the SKILL.md serial chain — lane consolidation, lane job descriptions, request cards, foreign-gate parking, family dispatch#9899
os-warren merged 5 commits into
mainfrom
claude/issue-9854-skill-chain-fold

Conversation

@os-warren

Copy link
Copy Markdown
Collaborator

Fixes#9854
Fixes#9871
Fixes#9852
Fixes#9776
Fixes#9663

Family dispatch — five ruled cards, one branch, per-card commits. First live run of the mechanism that the fifth member itself legalizes (maintainer fold order, verbatim: 「开始折叠派发」; fold authority: 「SKILL.md 串行链 为什么不能合并成一个卡伐」). Every member carries a claim comment naming this branch; each lands as its own commit. Governed surface — this PR stays draft; the maintainer merges.

Per-commit map (commit order = member order)

commitcarddelivers
3f64a399854Domain-lane table merge: engine-core + metadata + drivers rows collapse into one domain:engine row (package families verbatim; the 2026-08-05 investment-freeze note rides its packages); identity's four plugins fold into the domain:services row; the four retired labels are marked retired IN the table (label objects stay). Companion roster sync in scripts/pm/ensure-pm-labels.sh — its own header mandates "keep both in sync BY PR whenever a lane is added or retired", and it records that domain:engine re-enters circulation after its own earlier retirement. Stale-lane-name sweep: one hit (the metadata-from-engine-core secondary-split sentence in the spec intra-seat reference) rewritten; .claude/agents/os-dev.md and all other pm-dispatch references: zero hits.
c7683ca9871Six lane job descriptions in references/lanes/ (engine, services, cli, devx, skills, spec), each 范围 + 常设承诺 + 席内判断, migrated from the live seat posts' prose, self-contained (id-lint auto-covers them). Seat-post template shrinks 6 → 4 sections in SKILL.md 座位贴协议 and references/seat-post-protocol.md; a post points at its lane file; live seat-post bodies deliberately untouched (migration is seat work). CEILINGS entries at landed counts + a self-test case.
22ba7c29852Request-card protocol on the 跨座位转移 clause: a cross-seat ask of any kind (a reading, a card-opening obligation, an access need) is work and lands as a card in the target lane's queue with provenance + a one-line executable criterion; a seat-post knock or ruling comment is never the only carrier; the waiting card flips pm:blocked + Blocked-by: at the request card in the same stroke; unreachable target repo routes via the seam-card rule (repo: label + named reader). No new labels, no new sweep.
684466c9776Done-but-unlandable state, on the pm:blocked row directly adjacent to the 放行双查 discharge rules: no new label; Blocked-by: at the gate card plus a machine-readable Unlock-action: re-check PR body line that swaps the unlock action from re-queue-for-work to re-check-the-PR; the re-queue premise check treats an existing finished open PR as landing work; the parked PR must name the gate card in its own body.
7371c479663批次独立性 absorbs the family-dispatch scope clarification: one dev covering N same-region ruled cards satisfies the independence invariant trivially; admission = the five gates as filed (gate 3 — every member already ruled, none in the decision box — and gate 5 — the named exclusion list — are load-bearing); fold-or-serial is a mandatory question whenever 2+ queued cards share a hot file, with the maintainer's verbatim 「你自己定的工作方式你也会忘。」 in the clause; the folded-claim conventions (shared branch named in every member claim, per-card commits, multi-Fixes PR body, lead claim carries the serial-constraints check) land in the claim protocol, written from this dispatch's own record.

Ratchet economics — one coherent pass funds all five additions

filebeforeafterceiling
.claude/skills/pm-dispatch/SKILL.md682682682 (headroom 0)
references/seat-post-protocol.md101101101
references/lanes/engine.mdnew4141
references/lanes/services.mdnew3131
references/lanes/cli.mdnew3737
references/lanes/devx.mdnew3838
references/lanes/skills.mdnew3636
references/lanes/spec.mdnew4444

Payments, all genuine dedup/relocation — no re-wrap of existing content: table 5 rows → 2 (-3); spec intra-seat reference relocated to lanes/spec.md (-8 incl. its stale sentence); the spec-only fixture-triage dispatch rule relocated to lanes/spec.md as its home (-3); the platform-readings TOC enumeration and the ccusage tool description collapse to pointers at the facts table that already carries them, verified against its actual headings (-2); the seat-post migration detail defers to seat-post-protocol.md (-1). Additions: request-card clause (+5), family-dispatch clause (+8 at the file's native line density — new text, not re-wrapped existing text), lane-file pointer in 座位贴协议 (+2), foreign-gate rule (+0, extends the pm:blocked table row, which is a single line by markdown table syntax). One extension rides an existing claim-protocol line (folded-claim conventions appended where the branch-naming rule already lives).

Gates — union run at head 7371c47, after the final commit

Derived by node scripts/pm/dispatch-gates.mjs (no paths — script took the changeset from merge-base): 9 matched families. All green, exit codes captured before any pipe:

  • pnpm check:pm-skill-ratchet — "✓ … SKILL.md is 682 lines (ceiling 682; headroom 0)" + all six lane files at headroom 0, self-test 14 cases
  • pnpm check:pm-skill-id-lint — "✓ check-skill-id-lint: 15 file(s) clean" (the six lane files are inside the scan set)
  • pnpm check:doc-authoring — "✓ doc authoring guard: 377 files clean"
  • pnpm check:skill-frame-sync — "binding sentence present in all 4; 4 count mention(s) agree"
  • pnpm check:pm-governed-prose — "✓ … 2 instruction surface(s) name all 5 registered governed surfaces"
  • pnpm check:pm-governed-merges — self-test 77 assertions
  • pnpm check:cross-package-test-inputs / node scripts/check-cross-package-test-inputs.mjs — "OK: 12 package(s) … all declared"
  • pnpm --filter @objectstack/lint run check:doc-formula-expressions — "✓ … 22 record-scoped formula example(s) … judged clean" (first run was the classic unbuilt-dist prerequisite in a fresh worktree; green after building the lint dependency closure)
  • pnpm check:nul-bytes — "OK (scanned 6288 text file(s) … no raw ASCII control bytes)"

Notes for the merging maintainer

  • Seat work after merge (recorded on the lead card, not this PR's): label rename engine-core → engine (measured: no leftover domain:engine label object exists, get_label 404 — the rename path is clear), 44-card migration, seat-post consolidation + per-seat 4-section shrink, bash scripts/pm/ensure-pm-labels.sh rerun.
  • scripts/pm/check-half-states.mjs self-test fixtures use the literal domain:engine-core as an arbitrary label string; they assert nothing about the lane vocabulary and were left untouched (judged inert, reported here).
  • One migrated-prose conflict was resolved in SKILL.md's favor: the devx seat post records flipping governed ADR PRs ready-for-review so the merge button works, while SKILL.md's ACCEPT-path fork says such PRs are never flipped ready. The devx lane file follows SKILL.md (恒 draft、留维护者); flagged in the dev report for the skills seat to reconcile.
  • skip-changeset applied: the diff is .claude/skills/** + scripts/pm/** only — nothing published.

Generated by Claude Code

… identity into domain:services (#9854)
Anchoring-table consolidation, table-first per the card's binding sequencing:
the three engine-side rows collapse into one domain:engine row carrying all
three package families verbatim (the 2026-08-05 investment-freeze note rides
its packages), identity's four plugins fold into the domain:services row, and
the four retired labels are marked retired IN the table (label objects stay —
deleting them would strip closed cards).
Companion edit mandated by ensure-pm-labels.sh's own header ("keep both in
sync BY PR whenever a lane is added or retired"): the lane roster loop drops
the four retired lanes and gains engine; the retired-lanes header comment
records the ruling and notes domain:engine re-enters circulation after its own
earlier retirement.
Sweep of the skill tree + os-dev.md for stale literal lane names: one hit in
the spec intra-seat reference (the metadata-from-engine-core secondary-split
sentence, now moot — both sides are one lane) rewritten; os-dev.md and all
references/*.md: zero hits.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AeA3nU1B5Q2pgxqxgUrexd
…eat-post template shrinks to four sections (#9871)
Six lane files (engine, services, cli, devx, skills, spec), each carrying 范围
+ 常设承诺 + lane-specific judgment notes migrated from the live seat posts'
prose — written self-contained (no issue IDs; the id-lint auto-covers them).
The spec intra-seat dispatch reference relocates from SKILL.md into
lanes/spec.md (one home; the domain-table pointer follows). Seat-post template
shrinks from six sections to four (当前 PM / 继承台账 / 热文件串行队 / 说明)
in SKILL.md's 座位贴协议 and references/seat-post-protocol.md; a post points
at its lane file. Live seat-post bodies are deliberately NOT rewritten —
migration is seat work at each incumbent's next flush.
Ratchet: every new lane file gets a CEILINGS entry at its landed line count
(shrink-only convention, headroom 0) plus a self-test case;
seat-post-protocol.md pays its template addition with in-file dedup of clauses
duplicated in the main file, landing back at 101/101.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AeA3nU1B5Q2pgxqxgUrexd
…the wait flips pm:blocked at it (#9852)
Scope clarification on the 跨座位转移 clause: cross-seat asks (a reading, an
obligation to open cards, an access/authorization need) are work and land as a
card in the target lane's queue with a provenance line and a one-line
executable criterion; a seat-post knock or ruling comment is never the only
carrier — comments are accelerators, not records, and prose is invisible to
every candidate query, sweep and age alarm. The waiting card flips pm:blocked
+ Blocked-by: at the request card in the same stroke, so the existing unlock
scan, candidate queries and aging machinery cover both ends — no new labels,
no new sweep. When the target repo is unreachable the request card lands in
objectstack via the seam-card rule (repo:* + named reader), which also
dissolves the requester-has-no-access failure.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AeA3nU1B5Q2pgxqxgUrexd
…e gate card, unlock action = re-check the PR (#9776)
A card whose work is finished and verified but whose PR is red only on a
foreign gate defect had no honest state: pm:dispatched lies (nobody is
working), plain pm:blocked lies at unlock time (the sweep would re-dispatch a
finished card), pm:on-hold and close are both false. Ruling: no new label
state. The card goes pm:blocked + Blocked-by: at the gate card, with a
machine-readable body line (Unlock-action: re-check PR) that the unlock scan
reads to swap the unlock action from re-queue-for-work to re-check-the-PR —
and the re-queue premise check treats an existing finished open PR as landing
work, never re-dispatching. The parked PR must name the gate card in its own
body so the linkage reads from either end without the seat post (which is
rewritten wholesale at every takeover).
Placed on the pm:blocked row, directly adjacent to the 放行双查 discharge
discipline in the pm:on-hold row — same unlock/discharge semantics region.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AeA3nU1B5Q2pgxqxgUrexd
…ates, fold-or-serial as a mandatory question (#9663)
The batch-independence paragraph gains its scope clarification: the invariant
stops two agents colliding on one region; one dev deliberately covering N
same-region ruled cards satisfies it trivially and may fold into one dispatch.
Admission is five gates as filed — same defect shape + fix pattern; same
package/region; every member already ruled (⛔ none in the decision box —
load-bearing against laundering unruled cards into a ruled PR); per-member
independent verifiability; a named exclusion list (load-bearing against
blanket same-class sweeps). Fold-or-serial is a mandatory question whenever
two or more queued cards share a hot file (maintainer verbatim quoted in the
clause); an unanswered default-to-serial is a missed answer. The folded-claim
conventions from this dispatch's own first live run land in the claim
protocol: shared branch named after the lead card, a claim comment on every
member naming that branch, per-card commits + one multi-Fixes PR, the full
serial-constraints check on the lead claim.
Ratchet payment (all genuine dedup, no re-wrap): the spec-only fixture-triage
dispatch rule relocates to lanes/spec.md as its home; the platform-readings
TOC enumeration and the ccusage tool description collapse to pointers at the
facts table that already carries them; the seat-post migration detail defers
to seat-post-protocol.md. SKILL.md lands at exactly 682/682.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AeA3nU1B5Q2pgxqxgUrexd
@github-actionsgithub-actionsBot added size/m documentation Improvements or additions to documentation labels Aug 19, 2026
@os-warrenos-warren added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 19, 2026 — with Claude
@os-warren
os-warren marked this pull request as ready for review August 19, 2026 06:49
@os-warren
os-warren added this pull request to the merge queueAug 19, 2026
Merged via the queue into main with commit 597a466Aug 19, 2026
24 checks passed
@os-warren
os-warren deleted the claude/issue-9854-skill-chain-fold branch August 19, 2026 07:08
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment