ASK KNOX
beta
LESSON 300

Till-Done Semantics: Making Agents Actually Finish

One prompt-level change eliminates the most common agent failure mode: the agent that stops partway through a multi-step task and reports partial completion as done.

7 min read·Claude Code Operations

Most agent failures are not model failures. The model understood the task. It executed correctly. Then it stopped early — at the first sign of uncertainty, the first unexpected state, the first step that didn't behave exactly as anticipated. The human sees "done" in the output. The task is 60% complete.

This is the partial-completion failure mode, and it is the most common reliability problem in multi-step agent work. The fix is a single prompt-level change.

Why Checklists Produce Partial Completion

The intuitive way to structure multi-step agent work is a checklist:

- [ ] Run tests
- [ ] Commit changes
- [ ] Open PR
- [ ] Verify CI passes

The problem is that a checklist is a sequence of items, not a completion contract. The agent processes items sequentially and marks them complete as it proceeds. When it hits uncertainty — the test runner output is ambiguous, the commit fails due to a pre-commit hook, the PR command returns an unexpected error — it has to make a decision: retry, ask for help, or stop.

Checklists implicitly favor stopping. The agent has completed some items successfully. The current item is uncertain. The default behavior is to report what was done and surface the uncertainty. From the agent's perspective, this is reasonable. From the human's perspective, the task is incomplete and the agent said it was done.

The checklist format encodes no completion contract. It says nothing about what "done" means at the end.

The Completion Loop Frame

The alternative is till-done semantics — instructions that explicitly define a completion state and require the agent to reach it before exiting:

Work until ALL of the following are verified complete.
Do not exit until each item passes its verification check.
If any item fails, retry with adjusted approach before escalating.

1. Tests passing — verified by running the test suite and confirming
   zero failures in stdout output
2. Changes committed — verified by git status showing clean working tree
3. PR open — verified by PR URL present in your output
4. CI green — verified by checking PR status after 2 minutes

The difference is not cosmetic. The completion loop frame changes what the agent treats as a stopping condition. A checklist says "stop when you've processed all items." The completion loop says "stop when all items are verified complete — and retry before you give up."

Tool Verification: Closing the Loop

Till-done semantics require more than re-framing the instructions — they require the agent to verify that the side effect of each step actually occurred.

Running a command is not the same as confirming the command worked. The agent needs to close the loop:

StepAnti-pattern (no verification)Till-done (with verification)
Commit changesgit commit -m "..."git commit -m "..." followed by git status confirming clean tree
Open PRgh pr create ...gh pr create ... followed by confirming PR URL in output
Deploy servicedocker compose up -ddocker compose up -d followed by docker compose ps confirming service is running
Run cronpython3 script.pypython3 script.py followed by log check confirming expected output

The verification step is not overhead. It is the only way to distinguish "the command ran" from "the command succeeded." These are not the same thing. A commit command can run and exit 0 while the pre-commit hook rejected the content. A deploy command can run and exit 0 while the container immediately crashes.

Without verification, the agent marks the step complete based on command execution. With verification, it marks the step complete based on confirmed state change.

Retry-Before-Escalate

The completion loop includes an explicit retry policy before human escalation:

If any step fails its verification check:
1. Diagnose the failure (read the error, check the state)
2. Attempt a fix (adjusted command, corrected input, alternative approach)
3. Re-verify
4. If still failing after one fix attempt, escalate explicitly:
   "I cannot complete [step] because [specific reason]. Manual intervention needed."

The escalation message is the key output. An agent using till-done semantics that cannot complete a step produces an explicit, specific failure message. An agent using checklist semantics that cannot complete a step produces silence — or worse, a partial completion report that looks like success.

The retry threshold matters. One fix attempt per step is a reasonable default for most workflows. High-risk operations (production deploys, irreversible actions) might warrant zero retries and immediate escalation. Exploratory tasks might tolerate two or three attempts. Set the threshold in the instructions based on what the failure cost is.

Where Till-Done Semantics Matter Most

Not every task needs this treatment. Single-step tasks, purely exploratory queries, and tasks with immediate human review don't require completion loop framing.

Till-done semantics are load-bearing in:

Multi-step pipelines. Any task with 3+ sequential steps where later steps depend on earlier ones completing correctly. If step 2 is optional, the agent may skip it and still reach step 3 — but step 3's output will be wrong because step 2 was skipped.

Agents that spawn subagents. The parent agent needs to know whether each subagent completed successfully before proceeding. Without till-done semantics, a subagent can exit partial and the parent has no way to detect this.

Skills with external dependencies. Skills that call APIs, interact with file systems, trigger launchd, or deploy containers depend on external state that the agent cannot control. External calls fail in unexpected ways. Verification is the only way to catch this.

Content pipelines. A pipeline that must end in a published state — post live on a blog, video uploaded to YouTube, message sent to Discord — cannot be partially done. Either the content is published or it isn't. Till-done semantics make the completion state unambiguous.

The Implementation

Adding till-done semantics to an existing prompt or skill is a small textual change with a large behavioral impact:

Remove: "Complete the following steps:"

Add: "Work until ALL of the following are verified complete. Do not exit until each item passes its verification check. If any item fails, retry with adjusted approach before escalating to human."

The word "verified" is doing most of the work. It signals to the agent that the task requires confirmation of state, not just execution of commands. That signal changes the agent's default behavior from "process and exit" to "process, confirm, retry if needed, then exit."

Build this pattern into your skill templates. Once it's in the template, it propagates to every new skill you write without extra effort.