Skip to main content
The execution profile says how intensely to review, which model and effort each job role runs on, and how often you report. It is a pure instruction-layer setting: PM records it, resolves it and emits it into the rules block and the session brief. It never dispatches an agent or checks which model actually ran. Applying {model, effort} to a dispatch is your agent’s job, where its platform supports it (and it should say so where it does not).
New in 0.51.0. /pm:init asks for the profile; see /pm:init.
Changed in 0.52.0. There are now six job roles, and each has a built-in default model, so a repo that never set a model no longer reads “no model directive”. /pm:init now recommends accepting the defaults, which records nothing.

The three fields

Where it is resolved from

Each field resolves independently, most specific first: the epic’s own value, else its lane’s, else the project’s, else the built-in default (review: standard, verbosity: quiet, and per role the model below). model resolves per role, and the {model, effort} pair is taken whole from the first layer that sets that role. An epic’s review wins even where it is lower than the lane’s or the project’s. A stored value outside its list is ignored (and named by profile). A detour epic resolves from its own record and inherits nothing from the epic it paused.

The six roles and their defaults (0.52.0)

A default is applied at read time and never written to state.json. profile reports it as source default, and unsetting a role falls back to it. To have a top-tier model build one epic straight off its finished plan, set update-epic <id> --model implement=fable:<effort>: an override of implement, not a seventh role. Breaking, in emitted instructions only. After /pm:upgrade the rules block names a default pair for every role. A repo’s state.json does not change.

Set the project or a lane

  • --lane <lane> writes that lane’s layer instead of the project’s. One of openspec, superpowers, claude-code, decision or external.
  • --review <off|standard|thorough>: the project review is state.reviewMode, the same record set-review-mode --mode writes.
  • --model <role>=<model>[:<effort>] is repeatable. Setting one role leaves the layer’s other roles alone. haiku with an effort, or any other model without one, is refused.
  • --verbosity <quiet|verbose>.
  • At least one operation is required. A bare set-profile exits non-zero and writes nothing.
  • Every refusal (an unknown lane, model, role, effort or level; a field both set and unset in one call) exits non-zero, names the offending value and the accepted list, and leaves state.json byte-identical.
A successful write refreshes the managed rules block in CLAUDE.md (which carries the project values and every lane override) and re-renders PROJECT.md.

Set an epic’s own values

--review-mode, --model <role>=<model>[:<effort>] (repeatable) and --verbosity are accepted by add-epic, update-epic and, as the batch keys reviewMode, model and verbosity, add-many. An epic’s --review-mode may be below the project’s: it wins, and profile --epic shows what it overrides. A batch with one invalid value refuses the whole batch and writes nothing.

Every set has an inverse

--unset <field> is repeatable; the field is review, verbosity, model (every role) or model:<role> (one role). The field then falls through to the next layer. A lane left with no field set is removed from the record, so an emptied lane is indistinguishable from one never configured. Unsetting a field that is not set succeeds, writes nothing and says it was already unset. set-review-mode ships no inverse of its own: set-profile --unset review is its inverse. At the epic layer: update-epic <id> --clear review-mode, --clear verbosity, --clear model (every role) and --clear-model <role> (repeatable, one role). Each field then falls through to the lane, then the project.

Read it, with sources

--epic and --lane are mutually exclusive. profile is read-only: it writes nothing. For every field and every model role it names the value and the layer it came from (epic, lane:<lane>, project or default), so an epic that lowered a value is visible as such: it names the value it overrides. An unknown epic or lane is refused, naming it.