Skip to the content.

Planning with Kelix

You can go from a goal in your head to a machine-checked roadmap and loop-ready backlog in one iteration — without the agent writing product code or re-litigating your decisions every run.

That hierarchy is proven on this repo, not a paper spec. Kelix decomposed its own v0.3 and v0.4 milestones through kelix plan — phased REQs, proposed tasks, and lint rejection of slop before anything was promoted to ready. Reproduce the draft-and-validate path with pytest tests/test_plan.py tests/test_lint.py -q.

Kelix can run on a flat backlog — edit .kelix/backlog.md, set tasks to status: ready, run kelix run. That path is still the quick path for small repos and bugfix queues.

Use planning when the work has structure: milestones you will ship in order, phases that close only when specific requirements are verified, or parallel agents that must not collide on dependent tasks. This page is the owner’s guide to that hierarchy.

For task-level writing rules, see writing-for-the-loop.md.

Plan-first flow

Six steps from zero to verified commits:

kelix init                              # seeds GOAL.md, backlog, kelix.toml
$EDITOR GOAL.md                         # outcome, non-goals, acceptance bullets
kelix plan --goal-file GOAL.md          # interview + draft roadmap + proposed tasks
kelix lint                              # reject slop before you promote anything
$EDITOR .kelix/backlog.md               # status: proposed -> ready
kelix run --max-iterations 25           # one task per iteration, verified-done

What each step produces:

Step Output Who owns it
GOAL.md Intent: outcome, non-goals, testable acceptance You
kelix plan .kelix/roadmap.md + proposed backlog tasks Agent drafts; you review
kelix lint Actionable findings (missing acceptance, cyclic deps, …) Machine
Promote Tasks with status: ready enter the queue You
kelix run Verified commits, .kelix/STATE.md updates, retrospectives Runner + agent

kelix plan never implements code. It may ask structured questions first (with a TTY, live; headless, it writes .kelix/phases/<id>/QUESTIONS.md and exits until you answer). Answers land in the phase’s CONTEXT.md — decisions captured once, injected every iteration as read-only data.

Skip planning when you already know the next three tasks. Edit the backlog directly; the loop contract is unchanged.

Roadmap → phase → task

Three layers, top-down:

Milestone (releasable increment)
  └── Phase (largest unit safely closed as one run)
        └── REQ-ID (coverage contract — must map to verified-done task(s))
              └── Backlog task (one iteration, one commit)

Roadmap (.kelix/roadmap.md) is owner intent. Format:

## Milestone M1 — Title
(prose: goal, non-goals)

### Phase P-FOO — Title
Outcome: one sentence for what "done" means here.

- REQ-A1: testable requirement text
- REQ-A2: another requirement

Parsed by roadmap.py: ## Milestone <id> — <title>, ### Phase <id> — <title>, optional Outcome: line, - REQ-X: text bullets.

Backlog tasks link upward with optional pipe fields:

- [ ] T1: add parser | priority: 80 | status: ready | by: owner | phase: P-FOO | req: REQ-A1
  details: create src/foo.py with parse(); tests/test_foo.py round-trip.

Tasks without phase: / req: behave exactly like a flat backlog. Planning adds the fields; quick-path repos never need them.

Phase decisions live in .kelix/phases/<phase-id>/CONTEXT.md. When STATE.md names that phase and the file exists, its contents are injected into the prompt — data, not instructions. Do not re-litigate decisions there in every iteration.

STATE.md — where the project is

The runner (not the agent) maintains .kelix/STATE.md. Every iteration reads it first. Fixed schema:

# Kelix state

- milestone: M1
- phase: P-FOO
- current_task: selecting
- last_task: T1
- last_verified_commit: abc1234
- done: 3
- total: 12
- blockers:
  - REQ-A2 uncovered

Fields:

The runner writes STATE.md at run start, after verified iterations, and at run end. It is committed with retrospectives so history shows orientation over time.

kelix lint — reject slop before the loop runs

kelix lint          # exit 0 = clean, exit 1 = findings on stderr

lint_backlog checks non-done tasks: missing details:, no acceptance signal (test path, assert, exit code, named file), unfalsifiable wording without a metric, dangling or cyclic deps, title over 80 chars, multiple deliverables ( and then in details).

With a roadmap, validate_plan also requires every REQ to be referenced by at least one task. Run lint after kelix plan and before promoting tasks.

Good input in, good output out — see writing-for-the-loop.md for the task anatomy lint enforces.

Phase gate — when a phase closes

A phase is done when every REQ in that phase maps to a verified-done task (status: done after [verify] commands pass). The runner computes coverage; it does not trust the agent’s sentinel.

At run end (and when all active-phase tasks finish mid-run):

The agent never decides the phase is closed. Inspect coverage anytime:

kelix status        # milestone, phase, REQ table, blockers

Waves — safe parallelism in fleet mode

When multiple agents share one backlog, dependency order matters. Kelix derives waves from task deps: — no new syntax:

Fleet claim hooks restrict agents to the earliest incomplete wave. An agent cannot claim wave-1 work while wave 0 still has unfinished tasks. kelix status lists pending tasks with wave numbers.

Solo kelix run ignores waves; they matter only when .kelix/fleet.toml runs parallel loops.

When NOT to use planning

Stay on the flat backlog when:

Planning adds files and ceremony. The quick path (kelix init → edit backlog → kelix run) is intentionally unchanged. Delete .kelix/roadmap.md if you started with the init template and never promoted it.

Quick reference

Command Purpose
kelix init Seed GOAL.md, backlog, kelix.toml, optional roadmap skeleton
kelix plan --goal-file GOAL.md Interview + draft roadmap and proposed tasks
kelix lint Machine-check backlog and roadmap before promoting
kelix run One verified task per iteration
kelix status Milestone, phase, REQ coverage, fleet claims, waves
kelix diagnose (secondary) Review failed runs; write .kelix/memory/diagnosis-*.md
kelix propose (secondary) Tuning PR from metrics + diagnosis; owner records merge/grade

Further reading: quickstart.md (install and verify gate), prioritization.md (selection order and priority bands), fleet.md (parallel agents and claims), memory-and-skills.md (context compiler, distillation, manifests).