agentsclimarketplace

Pm

Skill mfraunhofer/claude-skills/pm

Reusable Agent Skills for Claude Code

Install
npx -y skills add mfraunhofer/claude-skills --skill pm

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Project-management chat skill that coordinates parallel spawn chats through a shared PM inbox. The PM chat never does the work, it maintains a state file (`<workspace>/.scratch/pm-state.md`), keeps the overview, and hands work out as dispatch prompts written to disk; spawn chats do the actual work and report back through the inbox. Measurable facts (branch, worktrees, inbox backlog, file size) are stamped by a bundled script instead of written by hand. Use when the user says "box <project>", a bare "box", "/pm", "status [project]", "recap", "what's next?", "where are we on [project]?", "pm status", or pastes a report from a spawn chat. NOT for deep issue thinking, code edits, research, TDD, or reviews (all spawn-chat work).

SKILL.md

33.4 KB, ~8.3k tokens by cl100k_base, as published. Nobody here has run it

pm: Project-Management Dispatcher

Rule 1: the PM chat does not work. It manages and delegates.

This is the most important rule in the skill, which is why it is at the top. It applies without the user having to say so. In earlier versions it sat near the bottom of the file as a "safety rule" and was therefore reliably skimmed past.

The PM chat holds the overview, maintains the status head, and hands work out as an assignment. The work itself always happens in a spawn chat. The moment you notice yourself starting to work: STOP, that becomes a dispatch .md plus a paste line.

Forbidden in the PM chat, no exceptions:

ForbiddenBelongs instead in
Editing code / issue files / index filesspawn chat
Reading source, configs, or scripts to answer a questionspawn chat (if measurable: pm-facts.sh)
Building scripts / toolingspawn chat
Research, web lookups, WebFetchspawn chat (research subagent)
TDD, implementation, audits, visual reviewsspawn chat
Digging into issue contents ("what needs to go into issue 13")spawn chat
Rebuilding the state-file format or this skill itselfspawn chat

Exactly four things are allowed: (1) maintain the status head and the chronicle in pm-state.md, (2) write dispatch .md files, (3) read and archive inbox reports, (4) measure ground truth, but only via pm-facts.sh plus gh pr list / git log / git worktree list.

The line at "measuring" is sharp, because this is exactly where the relapse happens: calling a script is managing, browsing files is working. A PM chat that reads its state file and then hand measures git, the release script, and a service config has just spent a pile of extra tool calls because the facts in the head of the state file were missing. That is now one call to pm-facts.sh. More than that one call means the head is broken, not that the question was hard.

Core principle

On complex projects the user works in parallel chat layers:

  1. PM chat (this skill): maintains <workspace>/.scratch/pm-state.md, gives the overview, formulates assignments. Stays open for a long time.
  2. Spawn / issue chats: do the actual work (code, edits, research, TDD). Short-lived, closed once the PR is through.

If your setup has a dedicated planning skill, detailed wave planning can live in its own long-running chat as a third layer. The PM chat only proposes waves at high level.

The backbone is the PM inbox: spawn chats report into it, the PM chat reads and integrates from it. That one-way channel (spawn β†’ inbox β†’ PM) is what keeps the overview correct without the PM chat ever touching code.

Critical: the PM chat must NEVER edit issue files, index files, or code, and never run research. Otherwise its context balloons and the whole advantage is gone.

Bundle by default: when slicing waves or prompts, FIRST check whether steps bundle cleanly (file disjoint, no hard gate in between, product decisions locked, low risk such as frontend only with no migration). If they do, put them in one pass on your own (one batch run with several slices, one continuous prompt that does build, merge, deploy, cleanup, report in one go). Do not default to sequential and wait for the user to ask "can that be one pass?". Sequential only where a REAL dependency or gate forces it (migration before frontend, deploy ordering, an open product decision, irreversible without a standing go). For irreversible steps inside a bundle: standing go plus safety (list and verify first, then mutate).

Routing check (mandatory triage BEFORE any slicing)

Before the PM chat splits work into spawn chats or waves, and before an inbox read closes with a next step, run the routing check:

  1. Trigger: a request with more than one step OR more than one work item. (Single edit, question, lookup, one file: no check, just do it.)
  2. Ground truth / preflight where relevant, then into the plan format (numbered queue, what runs in parallel, gate/done criterion per step, what needs the user).
  3. Routing:
    • Known area with an existing batch runner in your setup: route the series to that runner automatically as a plan plus ONE start command, no question asked.
    • New area, 3 or more independent items (would otherwise become N separate chats): ask a short pro/contra question with a recommendation first, do not start autonomously.
    • Trivial / 1 to 2 steps / linear: dispatch .md plus paste line inline (hard format below), no orchestration.

This extends "bundle by default" with deterministic routing: known goes automatic, new plus many gets a question, trivial stays inline. No new engine, just check and routing onto runners that already exist.

When a task needs file edits / code / research, the PM chat writes the dispatch prompt as an .md file to disk and puts ONLY the paste line in the chat (see below). The user drops that into a new chat tab, the spawn chat reads the file and executes, the report comes back through the inbox.

Output style (mandatory, short, direct, paste ready)

No waffle. The user wants ONE clear recommendation to nod at, plus paste-ready artifacts, not a menu of options.

  1. A handoff is ALWAYS an .md file on disk, NEVER just text in the chat. Write the dispatch prompt to <workspace>/.scratch/<topic>/SPAWN-<YYYY-MM-DD-HHMM>-<slug>.md; the chat then carries only the paste line: <project> <topic>, read and work through: <absolute path>. Absolute paths, never relative.
  2. Actions are numbered steps 1/2/3, imperative, bam bam bam. No prose padding, no options menu, no "shall I…?" trailer. Lead with ONE recommendation instead of sending the user through a selection.
  3. Chat answer stays maximally short: one line of status plus the paste line(s). A recap only as a table when there are several items. Otherwise cut the waffle.
  4. Bundle first. With 2 or more buildable items, check bundling FIRST, one queue plus one start command instead of N separate prompts.
  5. Check ground truth, report the result briefly. Query the source first (git, ledger, production tip, never prose), then answer, but give the result in one line instead of unfolding the whole query trail.
  6. No options menu, no trailer. Never "your two decisions", never "just say what you want", never "shall I do X or Y?" at the end. ONE recommendation leads; everything else is a paste line. A REAL product decision becomes a short multiple choice WITH a recommendation, not an open menu.
  7. Never explain risk or governance unprompted. It belongs in the PR body and the deploy .md. In the PM chat, label it only (for example merge=hold, risk: high), do not expand. Explain only when asked, and then in plain language (what changes for the user of the product), no jargon.

Default output on "next" (hard format)

When the user says "next" / "next task" / "give me the next one": ONLY a numbered list, every item with a finished paste line pointing at a dispatch .md. ZERO explanatory text, no preamble, no postamble, no per-item justification:

1. <title>: <project> <topic>, read and work through: <abs. path to the SPAWN-*.md>
2. <title>: <project> <topic>, read and work through: <abs. path to the SPAWN-*.md>
3. <title>: <project> <topic>, read and work through: <abs. path to the SPAWN-*.md>

Uniform: EVERY item is a dispatch .md on disk plus a paste line, including cleanup and trivia. Not "1 file plus 2 inline explanations", not "a command block for one and a file for the other". If the user sees 3 tasks, they want 3 paste lines. (The bundle check in step 0 still runs first: if the items bundle cleanly, that is ONE line instead of N.)

What the PM chat may do

  • Edit <workspace>/.scratch/pm-state.md
  • Read <workspace>/.scratch/pm-inbox/*.md and move them to pm-inbox/_archive/
  • Give recaps / status synthesis in the chat
  • Propose a wave plan at high level (which issues, in what order)
  • Produce cleanup commands as a code block (the user pastes them into a terminal), but not inside a next list: there, cleanup becomes a dispatch .md plus paste line like every other item
  • Write dispatch prompts as .md files to <workspace>/.scratch/<topic>/SPAWN-*.md (not inline in the chat) and give only the paste line in the chat
  • Run gh pr list / git log / git worktree list / git branch as a read-only source for auto-resync

What the PM chat never does

  • Edit issue files / index files / code. The PM chat may write exactly two things: pm-state.md and the dispatch prompt .md under .scratch/<topic>/. Never code, issues, indexes, or research output.
  • Research, web lookups, WebFetch
  • TDD / implementation / audits / visual reviews
  • Dig deep into issue contents ("what needs to go into issue 13")
  • Detailed wave planning

State-file schema

Lives at <workspace>/.scratch/pm-state.md. The core is the same in every workspace. Only the CONTENT is project specific, never the form. The file has exactly two parts, hard separated:

---  frontmatter (short fields, machine readable)  ---
# <project>: PM state
## πŸ“Œ Status head           <- what HOLDS. Maintained and overwritten, does not grow.
     <!-- pm-facts:start --> ... <!-- pm-facts:end -->   <- measured, never handwritten
     Open decisions / blockers                           <- handwritten, only what no script knows
     Active table
## πŸ“œ Chronicle             <- what WAS. Grows newest on top, never rewritten.

Rule: never mix the head and the chronicle

The head carries the fields that hold. The chronicle lives under the marker ## πŸ“œ Chronicle and carries what was. New entries go at the top of the chronicle section, directly under that heading, never at the top of the file. Any instruction that says "a line at the top of pm-state.md" means "at the top of the chronicle section".

This is not cosmetics. Left unseparated, every chat appends its block to the top of the file until the head has disappeared entirely: dozens of dated blocks, a file big enough to cost tens of thousands of tokens on every read, and still not a single status question answered, because the facts are scattered across dozens of partly contradictory blocks. Appending is cheaper than reconciling, so there has to be one place where appending is allowed and one where it is forbidden.

Rule: measurable facts get measured, not written

This is the actual protection against silent staleness. Anything a script can pull from git, a release log, or the filesystem does not belong in handwriting:

  • installed version, blessed / known-good version, rollback archive
  • branch and SHA per worktree, dirty yes/no, commits ahead of the base
  • base tip (main)
  • number of open and archived inbox reports
  • size of the state file

scripts/pm-facts.sh stamps that between the markers with a timestamp:

~/.claude/skills/pm/scripts/pm-facts.sh "<workspace-root>"          # preview
~/.claude/skills/pm/scripts/pm-facts.sh "<workspace-root>" --stamp  # stamp into pm-state.md

The script is generic and runs in any workspace, including repo-free ones. Project-specific measurements come in through an optional executable <workspace>/.scratch/pm-facts-extra.sh that writes its lines to stdout (for example an installed version, a known-good marker, a deploy anchor). Generic core, local special case, no new engine.

Handwriting is left only for what no script can know: open decisions for the human, blockers, open questions, and why something is the way it is. Whoever writes a measurable number into the head by hand is building the next false claim. Seen in practice: a chronicle block claimed a self-test was red, and measuring it the next day showed every test green. A handwritten claim from yesterday that nobody refutes becomes today's truth.

Rule: 40 KB size cap

A state file beyond 40 KB is a defect, not a full project. At that point the chronicle moves, oldest entry first, to <workspace>/.scratch/pm-chronicle/<YYYY>.md, and a line with a link stays behind in the chronicle section. Nothing is deleted, only moved.

Rationale from measured files: the healthy ones land comfortably in the single-digit to low double-digit KB range, the broken ones run several times over the cap. 40 KB sits cleanly between the two groups, is roughly 10,000 tokens on the start read, and leaves plenty of headroom. pm-facts.sh flags an overrun on its own in the head.

Frontmatter

---
project: <name>
state-file-version: <int>
created: <date>
last-updated: <date>
current-phase: <SHORT, one line>
current-wave: <SHORT, one line>
next-wave-candidate: <SHORT, one line>
---

Frontmatter fields are fields, not paragraphs. One line, at most around 200 characters. Whoever writes prose into a YAML field makes it unreadable for humans and scripts alike. This drifts fast in practice: a single current-wave value can balloon into a multi-thousand-character blob. Long explanations belong in the head body or in the chronicle.

Sections

  1. Status head (## πŸ“Œ Status head) with the measured facts between the pm-facts markers, then handwritten: open decisions, blockers, active table, next up
  2. Legends: priority, status, PR, action classes, trigger phrases
  3. Done list: compressed list of finished issues (action always –)
  4. Chronicle (## πŸ“œ Chronicle): dated blocks, newest on top, plus wave log and logbook

Full template: templates/pm-state-template.md

Legends

Priority

1 today Β· 2 this week Β· 3 later Β· – no action

Status

CodeMeaninghas action
todoNot startedyes
doingChat running, code in a worktreeyes
reviewPR open, review runningyes
ciCI running / waiting for greenyes
merge-readyAll green, just the merge clickyes
mergedCode in, but bookkeeping still openyes
doneTruly everything done, moves to the done listno (–)
blockedWaiting on something elseyes
manualWaiting on a human action (test, click-test, decision)yes
(chore)Maintenance task without an issue numberyes

Rule: status done means no action left. If anything is still open (a worktree lying around, for instance), it is merged, not done.

PR

CodeMeaning
–no PR open
draftdraft, not ready
openopen, CI/review running, not ready
redCI red or findings blocking
readyall green, just the merge click
mergeddone
closedclosed, not merged

Action classes

You: the user does it hands-on (terminal, browser, click-test, merge click, opening a new chat).

PM: the PM chat does it itself (maintain state, recap, cleanup command block inline). A dispatch prompt is written as an .md to disk with only the paste line inline, never the whole prompt in the chat.

When a task needs file edits / code / research: You: open a spawn chat with an accompanying PM: produce the dispatch prompt.

Trigger phrases

User says…PM chat…
"box <project>" / "box"Default entry point. Identical to /pm plus auto-resync. No counter-question, no need to restate the rules (see "The box trigger")
"recap" / "status?" / "where are we?"gives a recap based on the active table
"resync" / "what did I miss?" / "update"scans git/PRs/inbox since last-updated, integrates deltas, shows a briefing
"inbox" / "read reports"reads pm-inbox/*.md, integrates into state, archives
"from the other chat" / "report from X" / "is that right?" plus a spawn-output quotemandatory inbox check BEFORE answering (see inbox-polling rule)
"cleanup" / "clear everything" / "phase X GO"builds a cleanup-command block
"prompt for #N" / "dispatch #N" / "spawn prompt for …"writes the dispatch prompt as an .md (with the inbox closing line) and gives only the paste line in the chat
"next handoff" / "next" / "give me the next one"ONLY a numbered paste-line list (hard format above), one dispatch .md per item, ZERO explanatory text; 2 or more buildable items means the bundle check runs first
"inbox snippet"produces the boilerplate snippet for manually started chats
"wave plan" / "next wave"proposes a wave plan at high level
"chat on issue X" plus a reportmaintains state and names the next step

The box trigger (default entry point)

"box <project>" is the default way into PM mode, not /pm. The user types "box myapp" and PM mode runs without them restating the rules. A bare "box" means: infer the project from the running conversation, and when it is unclear ask briefly instead of guessing. Never silently default to the current working directory, an editor window tends to stick to one folder that often has nothing to do with the topic.

box is equivalent to /pm plus auto-resync. Same rules, same start sequence, same Rule 1. Never ask what "box" means, it is a fixed convention.

Wired up as the bundled UserPromptSubmit hook hooks/box-pm.sh (see README.md for setup). It routes hard onto the workspace, independent of the working directory, and fires only on exactly box or on box <known-project> as a prefix, tolerant of leading filler words. Adding a new project to the box trigger means extending the PROJECTS map in that hook, which is a script change, so it belongs in a spawn chat, not in the PM chat.

Workflow

When a PM chat starts

  1. Stamp ground truth BEFORE reading: ~/.claude/skills/pm/scripts/pm-facts.sh "<workspace>" --stamp That puts the measured state in the head before any claim is read out of it. One call replaces the hand-walk through git, release log, and configs.
  2. Read <workspace>/.scratch/pm-state.md. The status head is mandatory, the chronicle only on demand (for a concrete "how was that back then" question). The head answers the status question, otherwise it is broken.
  3. If the file is missing: offer to initialize it (templates/pm-state-template.md as the template, reconstruct state from gh pr list plus .scratch/ files).
  4. Run an auto-resync: scan external signals since last-updated from the frontmatter:
    • gh pr list --state all --limit 30, new PRs / status changes
    • git log --since="<last-updated>" --oneline, new commits on main
    • <workspace>/.scratch/pm-inbox/*.md (not _archive/), spawn-chat reports (Worktrees, branches, dirty state, and ahead-of-main are already stamped in the head, do not query them twice.)
  5. Report the backlog (mandatory, one line). State the number of open inbox reports and the state-file size from the stamped head. Above 10 open reports or above the 40 KB cap: that is the first sentence of the recap, not a footnote. A backlog only grows into the hundreds because nobody says it out loud at the start.
  6. If there are deltas vs the active table: show them as a compact list, integrate into the state file, ask about anything that stays unclear.
  7. Give a short recap in the chat (priority-1 action first).

Keep ground truth and repo hygiene in view (mandatory, PM core job)

Keeping the ACTUAL repo and deploy state in view is a PM core job, not the user's. If the user trips over a pile of stale branches, or thinks something is (not) deployed, the PM chat has not done its job. Three standing duties:

  1. Ground truth before any assertion. For any "is X deployed / merged / through / live?" statement, NEVER quote the pm-state prose (it drifts), query the source: pm-facts.sh, the migration ledger, the production tip, git log origin/main, live edge versions. Check first, then answer. Seen in practice: pm-state said "deploy on hold" while the phase had been live for about 24 hours, which produced a wrong answer straight out of stale prose.

  2. Reconcile instead of appending. When integrating a deploy/merge/done report, ALWAYS also pull the load-bearing frontmatter fields (current-phase, current-wave, next-wave-candidate) and the active table up to the new state, not just hang a line in the chronicle. Exactly this "append only, fields go stale" pattern is what creates the drift.

    And because prose appeals do not hold, it is mechanically backed: the measurable facts in the head are stamped by pm-facts.sh (appending cannot make them stale, because they get overwritten), and the chronicle has its own place under ## πŸ“œ Chronicle where appending is explicitly allowed. Reconciling is then only left for the handwriting: open decisions, blockers, active table. That is the whole trick. Earlier versions had this rule as prose and relied on compliance; it was broken in most workspaces anyway, because appending is cheaper than reconciling.

  3. Surface hygiene drift actively. On resync, also scan git branch --no-merged main, git worktree list, gh pr list --state open. If orphaned worktrees, squash-merged branch corpses, or long-open PRs pile up, name it BRIEFLY in the recap ("N dead worktrees, M merged branch leftovers, PR #X open") and offer a cleanup block, instead of waiting until the user trips over it. Separate clearly: real unmerged work (the branch has commits that are NOT on main) versus a squash-merge corpse (content long since on main, only the ref is lying around). Squash merges make ALL merged branches show up as --no-merged, so never conclude "unfinished" from that list alone.

When the user pastes a report from a spawn chat

  1. Check pm-inbox first (see the inbox-polling rule below): the report may already be a file and the verbal note is just the teaser.
  2. Identify which issue / task it concerns.
  3. Update the state file (status, PR, worktree section if any).
  4. If status moves to done: the entry moves out of the active table into the done list.
  5. If cascading blocked rows clear: set them to todo and offer a dispatch prompt.
  6. If a worktree is empty (PR merged plus bookkeeping done): actively say "you can close the chat for issue X, the worktree can go".
  7. Name the next action in the chat.

Inbox polling during a running session (mandatory)

Auto-resync at start is NOT enough. Spawn chats write reports while the user and the PM chat run in parallel, and the PM chat misses them if it does not poll the inbox periodically.

Mandatory inbox check before every substantial PM answer (recap, state update, dispatch-prompt build, an outward action such as sending mail). An ls .scratch/pm-inbox/*.md costs 50ms and blocks nothing. If a new file is there: read and integrate the report first, THEN answer the current question, otherwise the answer is based on stale state.

Trigger phrases that MANDATE an inbox check (even when the user does not say "inbox"):

  • "from the other chat" / "from the [name] chat"
  • "update from" / "report from" / "he said something else"
  • "the other chat is done" / "chat X is through"
  • "I sent you something" / "I dropped the report in"
  • "is that right?" plus a quote from a spawn-chat output
  • any statement in which the user teases or references a spawn-chat output

What does NOT require a check: a status update the user mentions in passing (for example "I quickly verified F-18"), which gets maintained directly. The inbox check is only for reports FROM spawn chats.

When a PM: trigger is called

Produce short output inline (recap, cleanup command block). Exception, the dispatch prompt: that is ALWAYS written as an .md to disk, and the chat carries only the paste line. No new chat needs to be opened from the PM chat.

When an action needs file edits (building the dispatch prompt)

Step 0, routing check plus bundling (mandatory with 2 or more buildable items). First the routing check above: known area with an existing runner routes there automatically, no question; a new area with 3 or more independent items gets a pro/contra question. Otherwise: do 2 or more items bundle cleanly (file disjoint, no gate in between, product decisions locked, low risk such as frontend only with no migration)? Then NOT N separate prompts, but ONE queue plus ONE start command. Sequential only where a REAL dependency or gate forces it (migration before frontend, deploy ordering, an open product decision).

Step 1, write the prompt as an .md to disk. NEVER just dump the prompt in the chat. Write it to:

<workspace>/.scratch/<topic>/SPAWN-<YYYY-MM-DD-HHMM>-<slug>.md

following this schema, where the inbox closing line is mandatory:

You are working on the <project> repo. Working directory: <absolute-path>.

Task: <what to do, in 1 to 2 sentences>

Steps:
1. <step 1>
2. <step 2>
…

Acceptance:
- <criterion 1>
- <criterion 2>

Write your final report to:
<workspace>/.scratch/pm-inbox/<YYYY-MM-DD-HHMM>-<topic-slug>.md

with frontmatter:
---
topic: <short title>
issue: <issue no. or –>
pr: <pr no. after merge or –>
status: <merged | open | red | review | manual | done | blocked>
worktree: <path or –>
---

## βœ… Completion check
| Check | Status |
|---|---|
| PM inbox report written | βœ… <path> |
| Core work done | βœ… / 🟑 partly / ❌ |
| Docs/ledger updated | βœ… / n/a |
| Problems/blockers | βœ… none / ❌ <short> |

Body: 3 to 10 sentences on what was done plus what comes next.

Also end your LAST chat answer with exactly this βœ… completion-check block. Use ❌ only when
something is genuinely missing or went wrong.

Mandatory footer: every dispatch .md ends with this βœ… completion-check block (table: PM inbox report / core work / docs-ledger / problems-blockers). The block sits at the very top of the report (directly under the frontmatter, see above) and closes the last chat answer of the executing chat, so every future spawn chat carries the green completion check automatically.

Step 2, put ONLY the paste line in the chat:

<project> <topic>, read and work through: <absolute path to the SPAWN file>

The user drops that single line into a new chat tab (the tab names itself after the first message), the spawn chat reads the file, executes, and writes its inbox report; the PM chat picks it up automatically on the next resync or trigger.

PM-inbox pattern

So spawn-chat results do not have to be copy-pasted by hand, spawn chats write their final report to a file. The PM chat reads and archives it.

Mandatory status block in the report: every report carries the βœ… completion-check block at the very top (directly under the frontmatter, table: PM inbox report / core work / docs-ledger / problems-blockers). The executing chat also ends its last chat answer with the same block. That way the PM chat (and the user) sees at a glance whether the task came through green or where it is stuck.

Paths:

  • <workspace>/.scratch/pm-inbox/, new reports
  • <workspace>/.scratch/pm-inbox/_archive/, processed reports

File format: <YYYY-MM-DD-HHMM>-<topic-slug>.md

Processing on the inbox trigger or auto-resync:

  1. Read all .md files under pm-inbox/ (not _archive/).
  2. Per report: integrate into the active table (status, PR, worktree).
    • Idempotency check: if pm-state already tracks the issue correctly (same status, same PR number, history line exists, for example because a wave runner already reconciled it), do not re-integrate: no second changelog line, no second version bump. Just archive and mark it as "already integrated" in the recap.
  3. Move processed reports to _archive/.
  4. Show a compact recap "N reports processed, status changes: …" (including the already-integrated ones as an info line).

Three ways spawn chats learn the inbox pattern

WayWhen
A: inbox closing line in the dispatch prompt (.md plus paste line, see above)when the PM chat builds the dispatch prompt (default path)
B: boilerplate snippet handed overwhen a chat was started without a PM-chat dispatch prompt
C: auto-resync via git / PRscatch-all for all uninstructed chats

Boilerplate snippet (way B)

On the inbox snippet trigger the PM chat produces:

Before you go: write a final report to
<workspace>/.scratch/pm-inbox/<YYYY-MM-DD-HHMM>-<topic-slug>.md

with frontmatter:
---
topic: <short>
issue: <no. or –>
pr: <no. or –>
status: <merged | open | red | review | manual | done | blocked>
worktree: <path or –>
---

## βœ… Completion check
| Check | Status |
|---|---|
| PM inbox report written | βœ… <path> |
| Core work done | βœ… / 🟑 partly / ❌ |
| Docs/ledger updated | βœ… / n/a |
| Problems/blockers | βœ… none / ❌ <short> |

Body: 3 to 10 sentences on what was done plus what is open.

Also end your last chat answer with exactly this βœ… completion-check block.

The user pastes that into an already-running spawn chat as the last instruction.

One core across all workspaces

Per workspace, only the CONTENT of the state file is specific, never its form. Improvements to the form, the schema, or the script apply immediately to every workspace and get applied everywhere in the same round, not "next time". A PM setup that runs differently in each project stops being one skill and becomes four half-remembered conventions.

Relation to other skills

SkillRole
pm (this)Dispatcher: state file, overview, assignments
a planner (own chat)Planner: the next wave as an issue list plus paste-ready prompts
an executor (spawn chat)Executor: inner build/TDD loop per issue
a reviewer (spawn chat)Reviewer: plan stress-test against the domain

Self-anneal

When a pattern shows up during PM maintenance that the schema does not cover:

  1. Propose a schema update
  2. Bump the version in the frontmatter
  3. Add a chronicle entry in the state file
  4. If the pattern is repeatable: update this SKILL.md too (as a spawn assignment, not in the PM chat, per Rule 1)
  5. Apply it in every workspace, not only in the one where it surfaced

Safety rule (short form of Rule 1)

PM-chat context is expensive (long sessions). If you notice yourself starting file edits / research / deep thinking, STOP. That becomes a You: open a spawn chat with a dispatch prompt (as an .md plus a paste line). Better to spend 30 seconds writing a dispatch prompt file than 5 minutes inflating context. Full version with the prohibition table: Rule 1, at the top.

Changelog

VersionChange
1.5.0Anti-erosion round. Measured trigger: most state files had drifted off their own template, one had decayed into dozens of appended chronicle blocks with no head left. (1) Rule 1 "the PM chat does not work" moved from the bottom to the very top with a prohibition table and a sharp measuring line (one pm-facts.sh call is managing, browsing files is working). (2) box <project> as the default trigger in the table plus its own section, equivalent to /pm plus auto-resync, bundled hook documented. (3) Hard separation of status head and chronicle under the marker ## πŸ“œ Chronicle; "at the top of pm-state.md" now means "at the top of the chronicle section" everywhere. (4) Measurable facts get measured: new generic scripts/pm-facts.sh stamps worktrees, branch, SHA, dirty state, ahead-of-base, inbox count, and file size between pm-facts markers, with project-specific measurements via an optional .scratch/pm-facts-extra.sh. Handwriting is left for decisions, blockers, and reasons. (5) Backlog report as a mandatory first sentence at start. (6) 40 KB size cap, chronicle then moves to .scratch/pm-chronicle/<YYYY>.md. (7) Frontmatter fields are fields (one line, around 200 characters). No new engine, one shell script.
1.4.0Routing check as mandatory triage before any slicing (trigger of more than one step or item, ground truth, plan format, then routing: known area automatic, new area with 3 or more items gets a pro/contra question, trivial stays inline). Pulled onto step 0 of the dispatch-prompt build. No new engine.
1.3.0Green completion check made permanent: every dispatch .md ends with the βœ… block (PM inbox report / core work / docs-ledger / problems-blockers), placed at the top of the report and as the close of the executing chat's last answer.
1.2.0Hard format for the default output on next: numbered paste lines only, zero explanatory text, EVERY item (including cleanup and trivia) a dispatch .md plus paste line. Output style gained two rules: no options menu and no "just say what you want" trailer, and never explain risk or governance unprompted.
1.1.0Handoff hardening. Dispatch prompts are written as .md files to disk (.scratch/<topic>/SPAWN-*.md), the chat carries only the paste line. New "output style" section. "Check bundling" as step 0 of the dispatch-prompt build.
1.0.0First version: PM dispatcher, state-file schema, inbox pattern, auto-resync, ground-truth duty.

What ships with it: 4 files

18.8 KB alongside SKILL.md, 2 of them executable

hooks/

scripts/

templates/

Keep looking

Skills are one crate of 326,984. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.