Skip to main content
PM’s source of truth lives in .conductor/state.json. Every epic, every detour stack frame, every link, every tracker configuration — it’s all in that one JSON file. PROJECT.md is a generated view rendered from it and should never be hand-edited. Understanding what each file is for — and what the rules around touching them are — prevents the class of state corruption that’s hardest to debug: a file that looks valid but disagrees with the real state.

The .conductor/ directory

Three files live here. Each has a distinct purpose and a distinct write policy.
The directory is created by /pm:init and managed entirely by the PM engine after that. Only state.json is the authoritative source; the other two are logs and should never be edited directly.

state.json structure

The top-level fields of .conductor/state.json and what they mean: A minimal real example of a claude-code-lane epic with inline stories:

PROJECT.md

PROJECT.md is a generated Markdown view that renders the full conductor briefing. It is re-rendered by conductor.mjs render after every state change. Never edit it by hand — state.json always wins, and the next render will overwrite any manual changes. The briefing shows:
  • Active epic — title, lane icon, priority, and current status.
  • Detour stack — each frame with its paused epic, reason, and spawned detour.
  • NEXT UP queue — highest-priority queued epics, P0→P3, skipping any epic starved on an unresolved depends-on link (with the blocker named explicitly).
  • Per-lane counts — how many epics are in each lane, by status.
  • Tracker sync line — any active-work epics missing externalId when a tracker is configured. Only honestly-computable drift is shown; PM never fabricates transition state it can’t see.
  • Hierarchy rollup — for parent epics, an X/Y children archived progress indicator.
The SessionStart hook re-injects the briefing via additionalContext every time a session opens or resumes after a compaction — this is how PM survives context loss without requiring you to re-read docs.

detours.log

.conductor/detours.log is an append-only trail of all detour events. One entry per line:
Every minimal detour is logged here by the log-detour subcommand. Substantial pushes and pops are logged automatically. The PostToolUse hook also auto-detects unlogged minimal detours from commit shape (file count, commit prefix, whether an active detour is already open) and logs them without requiring a manual /pm:detour --minimal invocation. This log is never modified by hand. If you need to audit what happened during a session or trace when a particular change was introduced as a side-effect of a detour, this is the file to read.

CLAUDE.md rules block

PM writes and maintains a managed rules block in the project’s CLAUDE.md. This is how the conductor discipline — the detour protocols, the reconcile gate, the tracker sync instructions, the lane workflow rules — becomes part of every Claude Code session automatically, without you re-reading documentation. The rules block is:
  • Written by /pm:init when a project is first set up.
  • Re-injected by the SessionStart hook via additionalContext on every session open, resume, and compaction recovery, so the rules survive context loss.
  • Refreshable via /pm:upgrade after a plugin update — run it to pull in any new rules or behavioral changes from the latest version.
  • Idempotent — deleting the block from CLAUDE.md and re-running /pm:init or /pm:upgrade restores it safely. To permanently opt out, delete the block and do not run upgrade.
Never hand-edit state.json directly. Use PM commands. Bypassing the engine means render timestamps, active-epic invariants, and cross-link consistency can silently diverge. If you must recover from a bad state, use git checkout .conductor/state.json to restore the last known-good version — PM’s state changes are committed regularly, so git history is always the recovery path.
conductor.mjs verify-state fails loudly if state.json has been modified more recently than the last render stamp — a mechanical check for accidental hand-edits. Run it any time you suspect the file has drifted, or wire it into your own pre-commit checks. A clean output means the state PM is working from matches what was last rendered.