Spec-lite is the Chorus-native lightweight spec mode: a small, git-tracked spec trail that
needs nothing installed. It is what a session uses when [OpenSpec](/guides/openspec-mode/) is
not usable in the repository, and what you get when you ask for it with
`CHORUS_SPEC_MODE=lite`. Compared with the OpenSpec path it is deliberately smaller — no CLI,
no validation step, no archive step, no delta grammar — so it costs less time and fewer tokens
while still leaving a record you can read in `git log`.

The [AI-DLC workflow](/guides/ai-dlc-workflow/) is unchanged. Only the shape of the local spec
files changes.

## When you get it

Look for `CHORUS_SPEC_MODE=lite` in the runtime's spec-mode result. Claude Code, Codex,
Kiro, and Pi report it in startup context; DeepSeek Harness (`dsh`) provides it on the first
agent step after plugin load. OpenClaw resolves it during the stage skill instead of injecting startup
context; use `/chorus spec` or `/chorus status` to inspect it.

You land on `lite` either because OpenSpec is not usable in this repository — which is the
common case, since it needs an `openspec/` directory and the `openspec` CLI — or because you
asked for it:

```bash
export CHORUS_SPEC_MODE=lite
```

Pinning it this way means you get spec-lite even in a repository where OpenSpec would work.
See [how the mode is chosen](/guides/openspec-mode/#how-the-mode-is-chosen) for the full
precedence.

## What lands on disk

Everything lives under `.chorus/specs/`, and that directory is the only part of `.chorus/`
meant to be committed:

```text
.chorus/specs/<capability-slug>/
├── spec.md                              # durable, never synced
└── 2026-09-08-add-csv-export/           # one folder per change effort
    ├── prd.md                           # → Chorus PRD document
    └── tech_design.md                   # → Chorus tech design document
```

**The durable spec — `<capability-slug>/spec.md`.** One per capability or feature, *not* per
change. It is the cumulative "current truth": intent, requirements with acceptance points, and
non-goals. Every change edits it in place, and its git history is the whole record — there is
no changelog section to maintain. It is **never** copied into Chorus and carries no Chorus
identifiers. Its `status` (`draft`, `active`, `done`) describes the capability: `active` while
a change is in flight, `done` once delivered with no open change remaining; a new change
reopens it.

**One dated folder per change — `<capability-slug>/<YYYY-MM-DD>-<change-slug>/`.** The date
sorts folders chronologically; use distinct change slugs for changes made on the same day.
Each file in the folder is one Chorus document type: `prd.md` is required, and
`tech_design.md`, `adr.md`, `guide.md`, or a change-scoped `spec.md` are added only when they
earn their place. These files **are** mirrored into Chorus, one file to one persistent
document, byte-for-byte rather than retyped by the model, so the local file and the Chorus
document stay identical. After approval, every mirrored edit increments that document's
version, which is the change's record inside Chorus alongside git.

There is no `tasks.md`. Tasks live in Chorus as task drafts, and the acceptance points in
`spec.md` are intent, not a tracker.

So that a later session can find the change, the proposal description carries one exact line:

```text
Spec-lite: .chorus/specs/<capability-slug>/<YYYY-MM-DD>-<change-slug>/
```

## From local file to draft to document

The agent handles the sync in stages:

1. **Before approval:** the agent puts `proposalUuid` in each change document's frontmatter,
   leaves `documentUuid` empty, and mirrors the file into a proposal draft; later edits update
   that draft.
2. **On approval:** the draft becomes a persistent Document. The agent resolves it by
   `(proposalUuid, type)`, records its `documentUuid` locally, then mirrors once more so the
   stored content includes the identifier too.
3. **After approval:** the agent edits the local file and updates that same Document by
   `documentUuid`. These updates increment its version. The durable capability-level `spec.md` never enters
   this process.

A lookup with no match or multiple matches stops the sync for investigation; the agent must
not create a replacement or guess by title. This is agent-driven mirroring, not a background
file watcher. The frontmatter appears as a
[metadata card when reading the document](/guides/documents/#metadata-at-the-top-of-a-document).

## The two files named `spec.md`

`<capability-slug>/spec.md` — the durable one, local only, no Chorus identifiers. A file at
`<capability-slug>/<dated-folder>/spec.md` is something else: a change-scoped spec document that
*is* mirrored to Chorus. Prefer `prd.md` as a change's primary document and the ambiguity never
comes up.

## While work is in flight

The current change's dated folder stays editable: the agent keeps updating both it and the
durable `spec.md` as work lands, re-mirroring the change documents each time and ticking
acceptance points. Folders from **already delivered** changes are left alone — a new change is a
new dated folder, never a rewrite of a past one.

When several tasks run in parallel, only the main agent writes to these files; workers report
progress through Chorus instead. That keeps a shared folder from being overwritten by two
sessions at once.

## Where it ships

Spec-lite ships with the Chorus plugin on Claude Code, Codex, Kiro, Pi, OpenClaw, and dsh.
They share the same mode rules, not the same startup mechanism; see the
[OpenSpec guide](/guides/openspec-mode/) for the runtime differences. The standalone skill
distribution does not include spec-mode routing and keeps writing free-form documents.

## For agents

- **Triggers.** Use spec-lite only when the runtime's resolved mode is `CHORUS_SPEC_MODE=lite`.
  Read injected `## Spec Mode` context where provided; OpenClaw runs the shipped resolver at
  the stage skill's spec-mode step. If context is missing on other runtimes, follow their
  skill fallback rather than inventing a detection rule. This skill is a no-op in other modes.
- **Constraints.** Never mirror the durable `<slug>/spec.md`. Mirror each dated-folder document
  with `chorus mcp call <tool> '<json>' --arg-file content=<file>` so the body is streamed from
  the file rather than retyped, falling back to the `chorus-api.sh` / `chorus-mcp-call.sh`
  wrappers only when `chorus` is not on `PATH`. Resolve document identity by `documentUuid` or
  `(proposalUuid, type)` and **halt** when a lookup finds zero or more than one — never match on
  title alone. Halt on any mirror error. Do not create `tasks.md` and do not scaffold
  `openspec/changes/`. The proposal description must carry the exact
  `Spec-lite: .chorus/specs/<slug>/<YYYY-MM-DD>-<change-slug>/` locator line, on its own line
  with no trailing punctuation.
