Check-box lists in AI agent plans: keep them honest
Bobby Huang ·
Write one box per outcome you can verify, such as a file changed or a test passing, not per activity. Tell your agent to tick a box only after the step is done and checked, to mark stuck items with a BLOCKED: or SKIPPED: prefix instead of deleting them, and to add new tasks at the end of the right section. Then use git diff and git log -p on the plan file to see which boxes were ticked since you last looked, and look for the matching change in the same commit. If there is none, ask the agent what shows the step is done.
Key takeaways
- An agent plan written as a check-box list is a status report the agent edits while you read it.
- Write one box per outcome you can check, like a file changed or a test passing, never per activity.
- Tell your agent to tick only after a step is done and checked, and to mark stuck items BLOCKED: or SKIPPED: instead of deleting them.
- A tick is a one-character change, so git diff and git log -p show every new tick quickly.
- Sashmark is in development and not released; rendered check-box lists, Live Reload and the Changes View are planned for v1.
When your agent writes its plan as a check-box list and ticks boxes as it goes, the agent plan becomes more than a to-do list. It's a running status report, and the agent edits it while you're reading it. If the boxes match reality, you can glance at the file and know where the work stands. If they don't, the file tells you a story that isn't true.
This page is about keeping that check-box list honest. You'll shape the list so each box can be checked and give your agent a few rules for ticking. Then you'll use git to see what got ticked and whether the work backs it up. The syntax itself is covered in Markdown task lists, so it isn't repeated here.
Everything below runs in a macOS or Linux terminal with git. No other tools are needed.
Write boxes that can be checked
A box is only useful if someone can tell whether it's really done. That means one box per outcome you can verify, such as a file changed or a test passing. Boxes that describe an activity ("look into", "work on") can be ticked at any point, because there's nothing to check them against.
Here are a few pairs. The first line in each pair is hard to verify; the second isn't.
- [ ] Look into the theme setting
- [ ] Add a theme setting to the config
- [ ] Work on colors
- [ ] Switch colors when the setting changes
- [ ] Check the docs
- [ ] Update the help page
Two more habits help. Split a box when one part can finish before the other, using nested boxes. And keep each box to one line, so a tick changes one line and nothing else.
A small plan shaped this way looks like this:
# Plan: settings page dark theme
## Steps
- [x] Add a theme setting to the config
- [x] Read the setting on startup
- [ ] Switch colors when the setting changes
- [x] Text and background
- [ ] Borders and focus rings
- [ ] Update the help page
- [ ] BLOCKED: confirm contrast targets with Jane Doe
Every open box names something you could point to when it's done. The last one also says why it's stuck.
Rules to give your agent for the check-box list
Agents follow written rules better than habits you hope they pick up. Paste a short block like this into the instruction file your agent reads at the start of each session. If you haven't set one up, agent instruction files explains where it lives.
## Plan file rules
- Keep one plan file for this task. Do not start a second one.
- Tick a box only after the step is done and checked (the file changed, the test passed).
- Never delete an open box. If you stop on it, keep it open and add a prefix:
- "BLOCKED: <reason>" when you need something from me
- "SKIPPED: <reason>" when you decided not to do it
- Add new tasks at the end of the right section. Do not rewrite or reorder the list.
- When ticking, change only the box. Do not re-wrap lines or re-number the list.
The last rule matters more than it looks. If the agent re-wraps paragraphs or renumbers a list every time it ticks one box, the diff fills with lines that didn't really change, and the tick gets lost among them. Keeping agent Markdown diffs small covers that problem in more depth.
See what the agent ticked since you last looked
A tick changes one character, so it stands out in a diff. When the agent ticks "Update the help page" in the sample plan, git diff shows only this pair, with the unchanged lines around it as context:
-- [ ] Update the help page
+- [x] Update the help page
The removed line has the open box and the added line has the ticked one. Nothing else in the file moved.
You don't have to read the whole diff to find these. Two commands pull out just the ticks.
To list the boxes ticked in the last commit, including boxes that were added already ticked, filter that commit's diff for added lines that hold a ticked box:
git diff HEAD~1 HEAD -- plan.md | grep -E '^\+[[:space:]]*[-*+] \[[xX]\]'On the sample plan it prints:
+- [x] Update the help pageTo see the ticks across a run of commits, use
git log -pwith the same filter, and keep the commit lines so you know where each tick came from:git log -p --format='commit %h' -- plan.md | grep -E '^(commit |\+[[:space:]]*[-*+] \[[xX]\])'On the sample it prints the newer commit with
+- [x] Update the help pageunder it, then the first commit with the three boxes that were already ticked when the file was created.
These are quick text checks, not a Markdown parser. They also match lines inside code blocks, so a plan that quotes a task list in a fenced example can show extra hits. If you want the full picture of a file's changes beyond ticks, seeing what changed in a Markdown file covers the wider diff workflow.
Check each tick against the work
Finding a tick is half the job. The other half is checking that the work behind it exists.
- Take one newly ticked box from the output above.
- Open the same commit or diff and look for the change the box names. For "Update the help page", that's an edit to the help page file. For a box about a test, it's the test file or a passing run.
- If the matching change is there, the tick holds.
- If the box is ticked and nothing in that commit backs it up, don't count it as done. Ask the agent which file or test shows the step is finished.
A tick with no matching change is a question for the agent, not a fact. Boxes written as checkable outcomes make this step fast, because each one already tells you what to look for.
For a full read-through of a plan file from top to bottom, see reading an agent plan file without an IDE. This page only covers the ticks.
Read blocked and skipped items first
Open boxes with a BLOCKED: or SKIPPED: prefix are where the agent needs you. Find them with a plain search for the prefix:
grep -n -i 'blocked' plan.md
On the sample it prints the line number and the line:
11:- [ ] BLOCKED: confirm contrast targets with Jane Doe
Run the same search with skipped. Read these lines before anything else in the plan. A blocked box is waiting on an answer only you can give, and a skipped box is a decision you may want to overrule before the agent builds on it.
Where Sashmark fits
A good reader should render a check-box list as real boxes, keep your place in the file when the agent ticks one, and show what changed since you last looked without needing git. Sashmark is a Markdown reader and editor for people whose AI agents write Markdown, being built for Mac, Windows and Linux. It is in development and has not been released, and the app itself has no AI features. Rendered check-box lists, Live Reload and the Changes View are planned for v1, so a plan file should update in place as the agent ticks boxes, with the new ticks shown as changes. See the planned features for what each part is meant to do. Sashmark is being built for this; the roadmap shows where it stands.
Sashmark is in development. See what it is at sashmark.com.
Questions
- Should my agent delete a task it decides not to do?
- No. Ask it to keep the box open and add a SKIPPED: or BLOCKED: prefix with a short reason. A deleted box leaves no trace in the plan, while a marked one tells you a decision was made and why.
- How do I see which boxes the agent ticked since my last look?
- Run git diff on the plan file against the last commit you read, and filter for added lines that hold a ticked box. For a run of several commits, git log -p on the plan file with the same filter lists the new ticks commit by commit.
- What if a box is ticked but nothing else changed?
- Ask the agent which file or test shows the step is done. Until something in the same commit backs it up, count the step as open.