baseline / docs
friedbotstudio/baseline

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.

A track flows through three chain nodes into a selector that branches into two alternates and reconverges into commit. track intake spec approve swarm T-A T-B solo tdd selectors and sub-tracks

§ 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-spec once, then produces a sliced spec with one ## Slice section 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 by track_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).

IDInvariant
I1Unique track_id across the file.
I2Unique node.id within a track.
I3type=task nodes carry exactly one of {skill, sub_track}. type=selector nodes carry non-empty alternates.
I4Every depends_on and blocks reference resolves to a node.id in the same track.
I5The dependency DAG is acyclic.
I6Tracks declaring the commits invariant include a needs_user /grant-commit node ordered before the node with skill: "commit".
I7Every sub_track reference resolves to a track with selectable: false.
I8Every skill reference resolves to a known invokable: a skill in EXPECTED_SKILLS plus project.json additions.skills, or a consent-gate command.
I9needs_user nodes appear in dependency order before any node that depends on their consent.
I10A selector node's alternates share the same shape (all skill, or all sub_track).
I11Every 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.

PredicateArgumentEvaluates 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.

  1. Schema conformance. Each Track record validates against .claude/schemas/workflow-track.v1.json.
  2. Article IV invariants. I1..I11 evaluated per Track.
  3. Skill resolution. Every skill reference resolves to EXPECTED_SKILLS plus project.json additions.skills, or to a consent-gate command in .claude/commands/.
  4. Predicate vocabulary. Every Predicate.name is 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.