← All guides

Feature Lists Are a Harness Primitive, Not a To-Do List

Feature Lists Are a Harness Primitive, Not a To-Do List

Most people hand an agent a paragraph. "Build the checkout flow: cart, payment, receipt email, and an admin refund view." Then they wonder why the loop wanders — half-finishing three things, re-deciding scope every iteration, marking the whole thing "done" when the receipt email was never wired up. The paragraph looks like a spec. It isn't one. It's prose, and prose is the wrong material for the one file the loop leans on hardest.

The Anatomy of an Agent Loop already lists the memory file — IMPLEMENTATION_PLAN.md, tasks.md, progress.txt — as one of the five parts. This is the part underneath that one: not that you keep a plan file, but what happens when that file stops being narrative and becomes a structured, machine-checkable list of discrete units with a pass/fail state on each. That's the move the "Learn Harness Engineering" course makes in its lecture on feature lists as harness primitives, and it's a genuinely good one — worth reading in full alongside this. The framing is right: the feature list is infrastructure, not a note.

Prose to-do list vs. structured feature list

The difference isn't formatting taste. It changes what the loop can and can't do on every iteration.

Prose to-do listStructured feature list
Scope boundary"the checkout flow" — the agent re-interprets it each runone row = one slice; the agent picks the next pending item and stops
"Done"a judgment call, re-litigated every iterationa per-item state (pass / fail / pending) with a defined check
Survives context resetno — the reasoning that decided scope lived in a flushed windowyes — it's state on disk, not a memory of a conversation
What the verifier grades"the whole diff" against a vague goalthis one item against this one item's acceptance check

A prose list is re-read and re-understood every run, which means it's re-decided every run. A model with a fresh context window and a paragraph will not reliably re-derive the same scope you had in your head — it'll find a plausible boundary, which is not the same as the right one. A structured list removes the decision. Row three is pending, its acceptance criteria are written next to it, so the agent does row three. Nothing to interpret.

Why "state, not narrative" is the whole point

The reason this is a primitive and not a nicety is context loss. An agent forgets everything between runs, and often within a long run. A prose plan encodes progress as narrative — "I've started the payment integration and I think the cart is mostly done" — and narrative doesn't survive a compaction. A feature list encodes progress as flags. cart: pass. payment: fail (Stripe test key rejected). receipt_email: pending. That reads identically to a fresh agent, a resumed agent, and a human at 9am. It's the difference between a diary and a control panel — and a diary is exactly what the anatomy guide warns the memory file must never become.

This is also why the plan file wants explicit pass/fail rather than checkboxes a human ticks. A checkbox says a human looked. A fail with a reason says the check ran and the item isn't done — which is a thing the loop itself can act on next iteration without asking anyone.

The feature list is what the verifier grades against

Here's the connection that makes it load-bearing rather than tidy. A loop's quality lives in its verifier — the separate grader that didn't write the code. Hand that verifier a paragraph goal and a full diff, and you've asked it to grade "is all of this good?" — the vaguest possible question, the one it'll answer with plausible-looking approval. Hand it a feature list, and each row becomes its own gradeable unit: does the diff satisfy receipt_email's acceptance check — an email actually sent on order completion — yes or no? That's a question with an evidence-backed answer. The list is what turns one unbounded grading call into a series of bounded, checkable ones.

The same structure feeds the Plan stage in The Claude Code Harness: the plan file is where approved slices live, and the feature list is that plan made checkable. Work happens only against approved rows. The agent doesn't freelance a fifth feature nobody asked for — adding one is a plan-file edit, which makes scope creep a visible, reviewable diff instead of a silent surprise in the output.

Where to see it

The rows aren't abstract — they're lines in a file the agent reads before it touches code, and the verifier reads before it grades. Strip the branding off "spec-driven," "feature-list," and "task-graph" harness write-ups and they're describing the same file: discrete units, a state per unit, a check per unit. The loops in the directory that grade well almost all ship one; the ones that don't are usually the ones handed a paragraph and asked to know when they're finished. Start from a graded one, and copy the list before you copy anything else.

Ready to run one? Browse the loop directory →
All AUTOMATION loops

Draft a sprint plan from the backlog

Turn the open issue backlog into a proposed two-week sprint plan with estimates, a dependency ordering, and an explicit cut line, written as a document for the team to edit.

Open loop →

Cadence: weekly. you are my presale-question compiler. read…

Community loop loop for docs, sourced from submission. Verified exit condition, evaluator-gated.

Open loop →

Cadence: weekly. you are my share-of-model tracker. read…

Community loop loop for automation, sourced from submission. Verified exit condition, evaluator-gated.

Open loop →

Check active goals against rubric

Verify each goal in active.md has evidence attached, stopping after 25 turns or completion.

Open loop →