docs(lanes): document per-feature state and archive (B)

This commit is contained in:
2026-08-04 15:06:05 +07:00
parent 3a83e849cf
commit 917f0794d5
5 changed files with 129 additions and 2 deletions
+47
View File
@@ -543,6 +543,53 @@ ccam lanes add --cwd /path/to/ml-repo --title "Training run #1" --pipeline ml-tr
(The pipeline is selected at creation time. Lanes created without `--pipeline` default to the `default` pipeline.)
## Per-feature state and archive
A lane can carry many features (identified by slug) across its lifetime. Each feature has its own saved pipeline state (stage, status, notes) that persists separately from the live lane — the one every session and the Workspace console observe.
**Why:** `clearLane` used to erase the entire lane on each new feature. Now a lane can accumulate many features' saved states, letting you switch between them (via `ccam feature activate`) and keep their pipeline histories separate. This matters for proof galleries, parallel task batches, and any flow where one lane runs many intentional phases.
### The opt-in model
Nothing changes for a lane that never calls `ccam feature activate``clearLane` still erases the live stage and status rows exactly as before. Only when you opt in to features does a lane start archiving. At that point:
- `clearLane` archives the **current** active feature (if any) before clearing the live lane row — its saved stage goes into the archive
- A lane that has never activated a feature is unaffected by this change and works exactly as it did before feature support
### Slug canonicalization
Every feature is identified by a canonicalized slug. The rule is:
1. Drop a leading `feat/` prefix if present
2. Replace `/` and whitespace with `-`
3. Keep `[A-Za-z0-9._-]` only
4. **Do NOT lowercase** — slugs preserve case
This is a **deliberately different rule** from `worktree.js:slugify`'s branch-name slugification (which lowercases). The two must never be conflated. Every endpoint and CLI command echoes back the canonicalized form so the caller knows the exact slug that was stored.
### Activate semantics
`ccam feature activate <slug>` (or the API's `POST /api/lanes/:id/features/activate`):
1. Archives the current active feature (if any and if different from the target slug) — copies its live stage/status/notes to the archive
2. Restores the target slug's saved pipeline onto the live lane row — so switching back to a past feature resumes its pipeline exactly where it left off
3. Creates a fresh feature row for a never-seen slug (empty stage/status/notes)
This means activating an archived feature twice resumes the same pipeline both times.
### The Workspace feature picker
The Workspace page's feature picker (read-only) shows every archived and active feature for the lane. Selecting one displays its saved pipeline. **It never changes the live lane** — a read-only view matching the standing rule that "the console never writes a lane's stage". Changing the active feature requires the CLI or the API route, not a UI button.
### CLI commands
```bash
ccam feature list [<id>] # List every feature (archived or live)
ccam feature activate <slug> [--title text] [<id>] # Switch to a feature (echoes canonicalized slug)
ccam feature show <slug> [<id>] # Show one feature's saved pipeline
```
Omit `<id>` to address the lane owning the current directory.
## Stage detection
Besides the stage a skill explicitly declares with `ccam stage`, the dashboard