Reference
Workflow tracks.
Workflows live in .claude/workflows.jsonl. Tracks are DAGs of skill nodes; selector nodes pick among alternates by evaluating declarative preconditions. 7 selectable tracks ship in the pristine template.
§ I
What a track is
A track is a DAG of skill nodes declared in .claude/workflows.jsonl. One record per line. Each node names a skill, lists its predecessors and successors, and optionally flags itself as a consent gate or as part of a parallel cluster.
The canonical set
7 selectable tracks ship in the pristine template:
intake-full. Eleven nodes for a new feature that needs a written spec: intake, scout, research, spec,/approve-spec, implementation (selector: swarm or solo TDD), simplify, security, integrate, document, archive, memory-flush,/grant-commit, commit.spec-entry. Starts at/spec. For a bugfix where the failing case is contract-level. Skips intake, scout, research.tdd-quickfix. Starts at/tdd. For a localised bug with a known failing case. Skips spec entirely.chore. Stripped-down. For documentation, configuration tweaks, dependency bumps. Skips scenario and implement.freeform. Ad-hoc batch of edits with relaxed phase ordering. The DAG carries only the closing sequence:memory-flush,/grant-commit,commit. All 24 hooks remain active, so per-tool guards still fire. For batches of unrelated edits that share no single goal.epic. Discovery-once umbrella for a feature built as three or more separately-committed slices. Runs intake, scout, research, spec, and/approve-speconce, then produces a sliced spec with one## Slicesection per child. The single approval (gate A) covers every slice.epic-child. One slice of an approved epic. Inherits the epic's discovery through pinned artifacts, enforced bytrack_guard, so it re-runs no discovery phase. Runs the fast path: tdd, integrate, archive,/grant-commit, commit. Escalates simplify, security, or document only when the slice's risk flags require it.
Sub-tracks
2 sub-tracks ship in the canonical set, referenced only by selector nodes inside the 7 selectable tracks: swarm-implementation (parallel dispatch via swarm-plan and swarm-dispatch) and tdd-worker-chain (solo fallback). Sub-tracks carry selectable: false; triage cannot pick them directly.
§ II
Article IV invariants
Every track in workflows.jsonl satisfies eleven invariants. The validator runs at install time (audit-baseline), at triage time (the LLM-driven selector), and at harness time (per node before dispatch).
| ID | Invariant |
|---|---|
| I1 | Unique track_id across the file. |
| I2 | Unique node.id within a track. |
| I3 | type=task nodes carry exactly one of {skill, sub_track}. type=selector nodes carry non-empty alternates. |
| I4 | Every depends_on and blocks reference resolves to a node.id in the same track. |
| I5 | The dependency DAG is acyclic. |
| I6 | Tracks declaring the commits invariant include a needs_user /grant-commit node ordered before the node with skill: "commit". |
| I7 | Every sub_track reference resolves to a track with selectable: false. |
| I8 | Every skill reference resolves to a known invokable: a skill in EXPECTED_SKILLS plus project.json additions.skills, or a consent-gate command. |
| I9 | needs_user nodes appear in dependency order before any node that depends on their consent. |
| I10 | A selector node's alternates share the same shape (all skill, or all sub_track). |
| I11 | Every Predicate.name resolves to a known v1 predicate (see §III). |
§ III
Predicate vocabulary (v1)
The closed set of declarative predicates that may appear in Track or Alternate preconditions. Unknown predicates fail Article IV invariant I11 at validate time.
| Predicate | Argument | Evaluates true when |
|---|---|---|
| requires_git | (none) | git rev-parse --is-inside-work-tree exits 0 at the project root. |
| requires_user_override | <value> | The user explicitly named this alternate in conversation (e.g., "use solo"). |
| requires_min_components | <int> | The approved spec has at least N C4 Components. |
| requires_phase_completed | <phase> | The named phase appears in workflow.json -> completed. |
| requires_skill_present | <skill_id> | The named skill exists in EXPECTED_SKILLS plus additions.skills. |
Adding a new predicate is a constitutional change. Update seed.md §18.4, the predicate validator (src/cli/workflows-validator-predicates.js), and the corresponding seed.template.md mirror.
§ IV
Declaring a project-local track
Tracks are project-owned. The file .claude/workflows.jsonl is tier-classified NEVER_TOUCH; baseline upgrades preserve your additions verbatim.
Add a Track record to .claude/workflows.jsonl, one record per line. The schema lives at .claude/schemas/workflow-track.v1.json and is documented in seed.md §18.2.
Validate with /init-project doctor before the next /triage invocation. The doctor checks JSON Schema conformance and Article IV invariants; named errors point at offending lines with a remediation path.
Triage classifies your declared track from its selector_hints at the next request. The track participates in the same selector + AskUserQuestion flow as the canonical five.
Example
A minimal pre-commit-lint track that runs a linter after memory-flush and before /grant-commit:
{"$schema":"./schemas/workflow-track.v1.json","track_id":"pre-commit-lint","name":"Pre-commit lint","description":"Run linter before commit.","selectable":true,"selector_hints":["lint pass","formatting"],"preconditions":[],"invariants":["commits"],"nodes":[
{"id":"lint","type":"task","skill":"prose","depends_on":[],"blocks":["grant-commit"]},
{"id":"grant-commit","type":"task","skill":"grant-commit","depends_on":["lint"],"blocks":["commit"],"needs_user":true},
{"id":"commit","type":"task","skill":"commit","depends_on":["grant-commit"],"blocks":[]}
]}
§ V
/init-project doctor
Run /init-project doctor to validate .claude/workflows.jsonl against the shipped JSON Schema and Article IV's eleven invariants. The doctor surfaces every violation with a remediation path and applies the named fix on user confirmation.
Drift detection
The doctor checks four dimensions on every run.
- Schema conformance. Each Track record validates against
.claude/schemas/workflow-track.v1.json. - Article IV invariants. I1..I11 evaluated per Track.
- Skill resolution. Every
skillreference resolves toEXPECTED_SKILLSplusproject.json additions.skills, or to a consent-gate command in.claude/commands/. - Predicate vocabulary. Every
Predicate.nameis in the v1 closed set above.
The four-way Article IV mirror is enforced separately. The seed.md §18 text, CLAUDE.md Article IV, src/seed.template.md, and src/CLAUDE.template.md are bound together by audit-baseline. The doctor extends that check to workflows.jsonl against the shipped pristine template at obj/template/.claude/workflows.template.jsonl. Any track in your workflows.jsonl that has the same track_id as a pristine track but differs structurally is flagged.
Schema-version handling closes the upgrade-safety loop. Each Track carries a $schema field referencing the JSON Schema document version. Unknown $schema values are rejected with a named error citing the supported versions. This prevents silent schema-version skew across baseline upgrades; bumping the schema is a constitutional change that updates the mirror at the same time.