Skip to main content
/pm:upgrade brings your project up to date after installing a new version of PM. It refreshes the managed rules block in CLAUDE.md, runs any pending migrations on .conductor/state.json, re-renders PROJECT.md, and stamps the new pmVersion — all without touching your epic history or any non-PM content. Use it whenever the SessionStart briefing shows an upgrade nudge like pm 0.4.0 → 0.4.1 available.

When to run it

The SessionStart briefing tells you when an upgrade is needed. The sequence is always:
  1. Install the new PM version via the Claude Code plugin marketplace.
  2. Run /reload-plugins (or restart Claude Code) to load the new plugin code into the running session.
  3. Run /pm:upgrade to migrate your project’s state and refresh the rules block.
If you skip step 2, Claude Code is still executing the old plugin code and the upgrade will not apply the correct migrations. The briefing message "this is pm 0.4.0 but 0.4.1 is installed" is the reload reminder — it means the reload has not happened yet.

What it does

1

Refreshes the managed rules block

The managed PM section is replaced with the version shipped by the new plugin. Any content outside the managed delimiters — your own notes, other tool rules, project context — is left completely untouched.As of 0.24.0 the target file is platform-aware: CLAUDE.md on Claude Code, and on a platform that resolves project context through a precedence chain, whichever file that platform will actually read. Upgrading from a pre-0.24.0 release also migrates the block’s own delimiter wording in place — detection keys on a stable prefix, so an older block is found and refreshed rather than duplicated.
2

Runs pending state migrations

The engine applies any schema migrations needed to bring state.json up to the new version’s format. Migrations are idempotent: if your state is already at the target schema, the migration step is skipped with no changes written. The 0.24.0 migration stamps a platform field on repos that predate it, defaulting to claude-code.
3

Re-renders PROJECT.md

PROJECT.md is regenerated from the now-migrated state.json, picking up any new fields or formatting changes introduced in the new version.
4

Stamps pmVersion

The pmVersion field in state.json is updated to the newly installed version, so future SessionStart checks know the upgrade has been applied and stop showing the nudge.

What 0.27.0’s migration does

One entry, additive, idempotent, and backward-compatible — a state.json written by 0.26.0 still loads, and a second run changes nothing. It reads nothing outside state, because a migration that consulted disk would produce a different result on a machine whose checkout sits at a different commit. both would be wrong for an existing non-github-issues primary in the direction that costs something: a Jira tracker receives only the outward section today, so both would grant an inward pull no repo has ever had, and /pm:sync would start registering an untriaged epic per open issue. Every archived epic also gets a terminal outcome, regardless of lanedelivered only where a passing Gate 2 exists, unknown everywhere else, both carrying recordedBy: "migration" so a later rule can key on which path wrote the stamp. Lane-scoping this would be wrong on measured data: of PM’s own 69 archived epics only 3 are openspec-lane, so stamping one lane would leave 66 with no outcome and the outcome invariant would fail on its own repository the instant the migration ran. An existing disposition is never overwritten.
Expect a burst of heal-archived-epic-passed-gate-2 on your first /pm:integrity after this upgrade. The migration only stamps epics already archived in state; the archive-drift heal flips the rest to archived afterwards and stamps them unknown at that moment. So every repo that followed the documented /opsx:archive then heal flow lands on unknown rather than delivered, by one step. That is the expected shape, not a bug. Each finding names the exact remedy — update-epic <id> --status archived --outcome delivered --no-deferrals — and the archive gate lets an agent replace an engine-written stamp, so nothing is stuck at unknown.
Three things about PM’s emitted output also differ from 0.26.0, deliberately: the “Sync after completing tracker-linked work” reminder now leaves the rules block where no inward procedure is emitted; the briefing’s consider /pm:sync nudge now leaves outward-only repos; and progress renders · N lifecycle where tasks carry the {/* pm:lifecycle */} marker. Treat a fourth as a regression.

Is OpenSpec current, and is this project current with it?

pm and superpowers are plugins — they update themselves, and PM already nudges when a repo’s stamped version lags the installed one. OpenSpec is a CLI you upgrade by hand, and openspec update — which regenerates the per-project instruction files, slash commands and skills the whole OpenSpec lane runs on — is a separate, manual, per-project step. So a machine can sit on OpenSpec 1.10 while a project still runs 1.6’s generated artifacts, indefinitely, with nothing anywhere saying so. Measured in PM’s own repository: four minor versions stale, while actively running an OpenSpec change, with two upstream slash commands its agents could not know existed. As of 0.28.0 both /pm:upgrade and the SessionStart briefing report that drift, from one shared emitter so the two surfaces can never disagree.
1

It never runs openspec update for you

PM emits the instruction; you run the terminal command — exactly as with openspec init. This is the instruction-layer law, and it is enforced mechanically: a source scan in the test suite fails the build if any engine file ever passes the openspec binary an argv other than --version.
2

It holds mid-change instead of suppressing itself

openspec update rewrites the very instruction files an in-flight change is being authored against. So with an active change the drift is still reported, but the imperative becomes hold until that change is archived, naming it. Suppressing the nudge outright would silence it permanently in any repo that usually has a change open — which is precisely how the four-version drift above accumulated unseen.
3

It tells you whether a diff will exist

Where the generated files are git-tracked, git diff after the run is your review. Where they are not tracked — or where that cannot be confirmed — the nudge tells you to copy them aside first, because the rewrite destroys local edits to your generated OpenSpec skills with no diff and no trace. Tracked-ness is scoped to this project even when it sits inside a larger repository.
Either version being undeterminable is reported as cannot tell, never as stale — the same third answer PM’s ancestry checks give. And nothing is spawned at all unless the repo has an openspec/ directory and a readable generated stamp, so a project that does not use OpenSpec never pays for the check.

Idempotency

Running /pm:upgrade more than once is always safe. If your project is already at the latest version, every step is a no-op — nothing is written, nothing is changed, and the command exits cleanly.
Always run /reload-plugins before /pm:upgrade when you’ve just installed a new version. If you skip the reload, Claude Code is still running the old plugin code, and the upgrade command will apply the old engine’s logic rather than the new one. Reload first, then upgrade.

Recommending adoption of new capabilities

After printing the changelog delta, PM doesn’t just leave you to read it — the agent reviews each Added headline in the “What’s new in pm” output and judges whether it describes an opt-in capability (a new flag, a new set-* subcommand, a new tracker/autonomy/review-mode behavior) rather than a bug fix or a change that applies automatically with no action needed. For anything opt-in that looks relevant to your project’s current .conductor/state.json — say, you already have a primary tracker configured but haven’t added a secondary one, or you’re touching schema-sensitive files without thorough review mode turned on — the agent recommends it in one line: what it is, why it fits, and the exact command to enable it. It never enables anything on its own; adoption is always your call. If nothing in the delta is opt-in or relevant to your project, the agent says so rather than silently skipping the review.

/pm:changelog — Review what changed between versions

/pm:changelog surfaces the PM plugin’s own changelog entries that are newer than a given version, so you know exactly what a release brought rather than just that an upgrade happened. By default, the floor is the version stamped in your project’s .conductor/state.json (pmVersion) — so running it after an upgrade shows you everything that version introduced. /pm:upgrade automatically prints this changelog delta for the versions it crosses, so you see what changed as part of every upgrade. Use /pm:changelog directly to review the delta again or to inspect a different version range on demand.