OpenSpec mode
The spec-enabled Chorus plugins resolve a spec mode — the shape proposal authoring takes.
OpenSpec mode is one of three, and it is the default whenever OpenSpec is usable in the
repository you are working in. When it is active, the
AI-DLC workflow still runs exactly as usual, but instead of
free-form Markdown typed straight into Chorus, the agent writes structured files on disk with
the openspec CLI and mirrors them into your
proposal’s document drafts. The local files are the working copy; the Chorus drafts are a
faithful mirror your reviewers read on the proposal page.
The three spec modes
Section titled “The three spec modes”| Mode | What the agent writes | When you get it |
|---|---|---|
openspec | Structured files under openspec/changes/<slug>/, mirrored into drafts | Default when OpenSpec is usable |
lite | Chorus-native local specs under .chorus/specs/<slug>/ | Default when OpenSpec is not usable |
off | Free-form drafts, no local spec files at all | Only when you ask for it |
All six spec-enabled plugins use the same resolution rules, but resolve and show the mode at different points:
| Runtime | When it resolves and where to check |
|---|---|
| Claude Code, Codex, Kiro, Pi | At session start (Kiro: agent spawn); the injected ## Spec Mode context states the result. |
| dsh | At plugin load; the first agent step receives the ## Spec Mode context. |
| OpenClaw | When a stage skill reaches its spec-mode step, using the shipped resolver. There is no SessionStart injection. Run /chorus spec or /chorus status to inspect the mode. |
For example, a resolved OpenSpec mode is reported as CHORUS_SPEC_MODE=openspec.
Do not infer a mode from the absence of a connection toast.
How the mode is chosen
Section titled “How the mode is chosen”In precedence order:
- An explicit
CHORUS_SPEC_MODEwins. Set it toopenspec,lite, oroffto pin the mode for a shell, a repository, or a CI job. - Otherwise OpenSpec is the default whenever it is usable. Usable means all three of: an
openspec/directory at the repository root (created byopenspec init), theopenspecCLI on yourPATH, and OpenSpec not switched off (see Choose a different mode). - Otherwise you get
lite— the Chorus-native fallback, which needs nothing installed.
If you pin CHORUS_SPEC_MODE=openspec in a place where OpenSpec is not usable, the session
reports that the requested mode cannot be honored, and the workflow stops rather than
quietly authoring something else.
Fix the cause (install the CLI, run openspec init, or re-enable OpenSpec) or pick a mode
that works. A mode you asked for is never silently downgraded.
Unrecognized CHORUS_SPEC_MODE values are treated like unset, with an explanation; use one
of the three exact values above. The standalone skill distribution does not include spec-mode
routing and continues to author free-form.
Install and initialize
Section titled “Install and initialize”OpenSpec is a Node CLI from Fission AI. Install it globally, then initialize the repository where the agent authors proposals:
npm install -g @fission-ai/openspecopenspec initopenspec init creates the openspec/ working directory (changes/, specs/, config, and
instruction files). Restart sessions that resolve at startup; reload the dsh plugin for
load-time settings. OpenClaw resolves again at the next spec-mode step. The process doing
the resolution must see both the openspec/ directory and the CLI.
For plugin installation, see the agent platforms reference.
What changes in proposal, develop, and yolo
Section titled “What changes in proposal, develop, and yolo”With the mode active, the proposal, develop, and yolo skills author a change on disk under a kebab-case slug and mirror three file types into your Chorus proposal’s document drafts:
- PRD:
openspec/changes/<slug>/proposal.md - Tech design:
openspec/changes/<slug>/design.md - Spec (one per capability):
openspec/changes/<slug>/specs/<capability>/spec.md
openspec/changes/<slug>/tasks.md is not mirrored: Chorus task drafts are the source of
truth for tasks, so the OpenSpec task list is left on disk.
So a later run can recover the change, the proposal description carries one exact line:
OpenSpec change slug: <slug>The mirror is byte-faithful — the plugin streams each file’s bytes into the draft rather than
re-typing the content through the model, which keeps the local file and the Chorus draft
identical. You do not run this yourself; the plugin’s skill handles it with the native MCP
client, chorus mcp call <tool> --arg-file content=<file>, and falls back to the legacy
chorus-api.sh / chorus-mcp-call.sh wrappers only when the chorus CLI is not on PATH.
The exact contract (its halt-on-error rules and post-approval re-sync) lives in the
authoritative sources rather than being reproduced here — see docs/OPENSPEC_MODE.md and the
plugin skill public/chorus-plugin/skills/openspec-aware/SKILL.md.
When openspec archive runs
Section titled “When openspec archive runs”openspec archive is deferred to the very end of the change. After the last task of the
change is verified, the agent follows its runtime’s hook reminder or skill instructions to run:
openspec archive <slug>Archiving moves the change out of openspec/changes/ and merges its spec deltas into the
long-term specs under openspec/specs/. The plugin then mirrors the updated
openspec/specs/<capability>/spec.md files back into the matching Chorus documents. Until
that point the change stays in flight and Chorus only ever sees the delta spec, so there is
no half-merged state to reason about.
Choose a different mode
Section titled “Choose a different mode”Three switches, in precedence order:
-
CHORUS_SPEC_MODE(all runtimes). The direct control — it names the mode you want instead of describing what to avoid:Terminal window export CHORUS_SPEC_MODE=lite # Chorus-native local specsexport CHORUS_SPEC_MODE=off # free-form, no local spec files -
enableOpenSpecuserConfig toggle (Claude Code plugin only, default on). Set it to off in the plugin’s install configuration to make OpenSpec unusable plugin-wide, including the archive reminder. -
CHORUS_OPENSPEC_MODE=offenvironment variable (all runtimes). The older, per-shell OpenSpec opt-out, still honored:Terminal window export CHORUS_OPENSPEC_MODE=off
Note what the last two now mean: they make OpenSpec unusable, which lands the session on
lite rather than on free-form. If you want no local spec files at all, ask for off
explicitly. Either way, an existing openspec/ directory is left on disk untouched and new
proposals get no OpenSpec slug line.
For agents
Section titled “For agents”- Triggers. The proposal, develop, and yolo skills consume the runtime’s resolved
CHORUS_SPEC_MODE. Use injected## Spec Modecontext where provided. OpenClaw instead runs the shipped resolver at each spec-mode step; without injected context on other runtimes, follow that runtime’s skill fallback. Never reimplement the resolution rule from prose.CHORUS_OPENSPEC_ACTIVE=1indicates a usableopenspec; onlitefollow spec-lite, onoffauthor inline. If explicitopenspeccannot be honored, halt — do not fall back. After the last task is verified, follow the runtime’s hook or skill instructions foropenspec archive <slug>; do not assume every runtime has PostToolUse. - Constraints. Every document-draft mirror call must go through
chorus mcp call <tool> '<json>' --arg-file content=<file>(the native MCP client) with the file’s bytes streamed verbatim — falling back to the legacychorus-api.sh mcp-tool/chorus-mcp-call.shwrappers only whenchorusis not onPATH. Never re-type document content inline, and halt on any error. Do not mirrortasks.md. The proposal description must carry the exact lineOpenSpec change slug: <slug>. When the mode is notopenspec, do not scaffoldopenspec/changes/and do not add the slug line. The standalonepublic/skill/distribution does not support spec modes. - Cite.
public/chorus-plugin/bin/resolve-spec-mode.sh(the single-source resolution contract),docs/OPENSPEC_MODE.md(user-facing summary), and the authoritative skillspublic/chorus-plugin/skills/openspec-aware/SKILL.md(Claude Code) andplugins/chorus/skills/openspec-aware/SKILL.md(Codex).