#Trying to get my claw to autonomously maintain a TODO.md list

34 messages · Page 1 of 1 (latest)

eternal sedge
#

So, if I mention something we needs to be done, she'll add it, and if I ask her what's on the todo list she'll list them elegantly. I'm having trouble where she forgets what's on the list and doesn't automatically add things to it even if I say things "this is a todo" or "add to the list". I have AGENTS reminding her to use it, I have instructions at the top of TODO, and I have it loaded into memory using openclaw.json config keys.
openclaw version 2026.4.11

obtuse heronBOT
vagrant lionBOT
#

Yep, I think I see why this is acting flaky. Let me pin down the exact config path for “loaded into memory” vs “injected every turn”, because those are different systems in 2026.4.11.

#

I dug through 2026.4.11, and the main issue is that TODO.md is not a built-in bootstrap file.

By default, normal prompt injection includes fixed files like AGENTS.md, SOUL.md, TOOLS.md, IDENTITY.md, USER.md, HEARTBEAT.md, BOOTSTRAP.md, and MEMORY.md/memory.md, not arbitrary files like TODO.md.

So if your list lives in TODO.md:

  • AGENTS.md can tell the model to use it, but the file itself usually is not in prompt context
  • agents.defaults.memorySearch.extraPaths only adds it to the memory index, not guaranteed per-turn injection
  • agents.defaults.startupContext is only a first-turn /new or /reset prelude
  • if you set agents.defaults.contextInjection: "continuation-skip", even normal bootstrap files can be skipped on continuation turns

That explains both symptoms:

  • “forgets what’s on the list” = TODO.md is not reliably in context
  • “doesn’t auto-add” = there is no built-in deterministic todo parser, the model still has to infer intent and choose to write/edit

Best stock setup on 2026.4.11:

#
  1. Put the canonical todo list in MEMORY.md under a ## TODO section
  2. Keep agents.defaults.contextInjection on "always"
  3. Run /context list and confirm MEMORY.md is actually injected
  4. Keep it short, or raise agents.defaults.bootstrapMaxChars / bootstrapTotalMaxChars if it’s getting truncated
  5. Treat TODO.md as optional mirror/output only, unless you build a custom hook/plugin

Also, the bundled bootstrap-extra-files hook will not solve TODO.md, because it only allows recognized bootstrap basenames, not arbitrary names like TODO.md.

Docs:

If you paste your agents.defaults block plus /context list, I can sanity-check the exact config.

eternal sedge
#
"agents": {
  "defaults": {
    "workspace": "/home/openclaw/.openclaw/workspace",
    "model": {...},
    "compaction": { "reserveTokensFloor": 20000 },
    "memorySearch": {
      "extraPaths": ["~/.openclaw/workspace/docs", "~/.openclaw/workspace/TODO.md", "~/.openclaw/workspace/TODO.completed.md"]
    }
  },
  "list": [
    { "id": "main" },
    { "id": "public", ... }
  ]
}
vagrant lionBOT
#

That config explains it pretty cleanly. You’re feeding TODO.md into memorySearch.extraPaths, which makes it searchable memory, not always-on prompt context. I want to check one more thing though: whether ~/.openclaw/... is even expanded there, because if it isn’t, those paths may not be indexing at all.

#

Yep, that config is the smoking gun.

memorySearch.extraPaths is searchable memory, not always-in-prompt context. So right now your TODO system is relying on semantic retrieval, which is inherently fuzzy.

A few things in that config are working against you:

  • TODO.md is only indexed, not injected every turn
  • TODO.completed.md is also indexed, so retrieval can mix active and completed items
  • docs/ is in the same memory pool, so TODO chunks can lose to unrelated docs chunks
  • instructions at the top of TODO.md only help if that file is actually retrieved

So on 2026.4.11, this setup is good for “maybe recall this file”, not for “always maintain this task list”.

What I’d do instead

Make the active todo live in:

#

/home/openclaw/.openclaw/workspace/MEMORY.md

Example shape:

## TODO
- task one
- task two

## Completed
- done thing

And in config, keep it simple:

#
"agents": {
  "defaults": {
    "workspace": "/home/openclaw/.openclaw/workspace",
    "contextInjection": "always",
    "memorySearch": {
      "extraPaths": ["/home/openclaw/.openclaw/workspace/docs"]
    }
  }
}

Why this works better

MEMORY.md is one of the files OpenClaw actually injects as bootstrap context, so the model sees it much more reliably than TODO.md.

I’d also recommend

#
  • remove TODO.md and TODO.completed.md from memorySearch.extraPaths
  • run /context list and confirm MEMORY.md shows up under injected workspace files
  • keep the TODO section short enough not to get truncated

Important caveat

Even with that, “add this to the todo list” is still not 100 percent deterministic, because there is no built-in todo command/parser. The model still has to decide to edit the file.

So the reliability ladder is basically:

  1. Best stock setup: put TODO inside MEMORY.md
  2. More reliable: add very explicit AGENTS.md rules like “when user says add to todo, update MEMORY.md before replying”
  3. Truly deterministic: custom hook/plugin/command

Docs:

eternal sedge
#

Sure

vagrant lionBOT
#

Yep, I’d split it like this:

AGENTS.md

Put the behavior here, not in the todo file:

## Todo behavior

The canonical task list lives in `MEMORY.md` under the `## TODO` heading.

When the user clearly indicates a task, for example:
- "add this to the todo list"
- "this is a todo"
- "remember to ..."
- "we need to ..."
#
you should:
1. update `MEMORY.md` first
2. add a short, concrete item under `## TODO`
3. avoid duplicates
4. if the task is finished, move it to `## Completed`
5. then reply normally

When the user asks what is on the todo list, use the current contents of `MEMORY.md`, not vague conversational recall.

If the request is ambiguous, ask one short clarifying question instead of guessing.

MEMORY.md

Keep this mostly data, not policy:

#
# MEMORY

## TODO
- 

## Completed
-

Why this split helps

  • AGENTS.md tells the model what to do
  • MEMORY.md holds the actual list
  • less instruction noise inside the file it has to read back

I’d remove the instructions from TODO.md entirely and move them into AGENTS.md. Keep the todo file itself boring and structured.

#

If you want, I can also give you a slightly stricter version that makes it more aggressive about auto-adding tasks.

eternal sedge
#

sure

vagrant lionBOT
#

Nice. Here’s a stricter version I’d actually use:

## Todo behavior

The canonical todo list is `MEMORY.md`, under the headings `## TODO` and `## Completed`.

Task detection rules:
- If the user says "add this to the todo list", "this is a todo", "put this on the list", or similar, update `MEMORY.md` immediately.
- If the user clearly describes something that needs to be done, default to treating it as a todo unless they are obviously just chatting.
- Prefer adding the task over ignoring it when intent is reasonably clear.
- If the wording is ambiguous, ask one short clarifying question.

Todo update rules:
- Add new tasks as short, concrete bullet points under `## TODO`.
- Do not add duplicates or near-duplicates.
#
- If a task is completed, remove it from `## TODO` and move it to `## Completed`.
- Keep wording concise and action-oriented.

Todo answer rules:
- When the user asks about the todo list, answer from the current contents of `MEMORY.md`.
- Do not rely on loose conversation memory when `MEMORY.md` is available.
- Present the list cleanly and elegantly, grouping or lightly rewording for readability without changing meaning.

Priority:
- `MEMORY.md` is the source of truth for todos.
- If chat history and `MEMORY.md` disagree, prefer `MEMORY.md`.

I’d pair that with a very plain MEMORY.md like:

#
# MEMORY

## TODO

## Completed

One small opinionated tweak: avoid phrases like “use the todo list when relevant”. They’re too soft. “Update MEMORY.md immediately” works better.

eternal sedge
#

is there any point to the TODO.md anymore?

vagrant lionBOT
#

Honestly, for the stock 2026.4.11 setup, mostly no.

If you move the live task list into MEMORY.md, then TODO.md stops being useful as the source of truth.

The only good reasons to keep TODO.md would be:

  • you want a separate human-facing file for your own browsing
  • you have external scripts/tools that already read TODO.md
  • you want TODO.completed.md as an archive/reporting format

But in that case, I’d treat TODO.md as a derived mirror, not the canonical list.

So my recommendation is:

  • Source of truth: MEMORY.md
  • Optional mirror/export: TODO.md
#

If you are not using it for another tool, I’d just delete TODO.md and simplify the whole setup. That’ll be more reliable and less confusing.

eternal sedge
#

my concern is they probably won't keep TODO.md or TODO.completed.md up to date, so they'll just be out of sync all the time.

vagrant lionBOT
#

Yep, I think that concern is totally valid.

If the agent has to keep MEMORY.md + TODO.md + TODO.completed.md in sync, it will absolutely drift sooner or later. That’s just too much bookkeeping for something the model is already doing heuristically.

I’d keep one file only as the source of truth:

  • MEMORY.md
    • ## TODO
    • ## Completed

And drop the separate TODO.md files entirely unless you have automation that updates them deterministically.

My honest recommendation:

  • best reliability: one canonical list in MEMORY.md
  • worst reliability: multiple mirrored todo files managed by the model
#

So yeah, I would simplify, not duplicate.

eternal sedge
#

Any benefit to mentioning it in TOOLS.md?

vagrant lionBOT
#

A little, but I wouldn’t rely on it.

My take:

  • AGENTS.md = best place for behavior rules like “update MEMORY.md when user adds a todo”
  • TOOLS.md = okay for a small environment note like “canonical todo list lives in MEMORY.md”
  • MEMORY.md = actual data

So if you want, a tiny note in TOOLS.md is fine:

### Todo
- Canonical todo list: `MEMORY.md`
- Sections: `## TODO`, `## Completed`

But I would not put the real instruction logic there. That belongs in AGENTS.md.

#

So, benefit? Slightly.
Critical? No.

eternal sedge
#

is there a concern of MEMORY.md becoming unwieldy?

vagrant lionBOT
#

Yes, definitely.

MEMORY.md is useful because it’s injected, but that also means you don’t want it turning into a giant junk drawer.

The sweet spot is:

  • MEMORY.md = working set
    • active TODOs
    • a small Completed section
    • a few durable facts/preferences
  • memory/*.md = archive/history if you need it later

So I’d keep MEMORY.md lean and periodically move old completed items out if it starts getting bloated.

Why this matters:

  • injected bootstrap files can be truncated
  • bigger MEMORY.md means more noise every turn
#
  • too much old stuff makes the todo behavior worse, not better

So the pattern I’d use is:

  • MEMORY.md for current state
  • optional memory/todo-archive-YYYY-MM.md for old completed items

That gives you one clear live file without letting it grow forever.