The log your next session resumes from
Your agent starts every session knowing nothing about the last one. You pay for that twice — once explaining the project again, and once when it walks into a wall a previous session already found.
todox is not a checklist. Each task carries a log — the decisions behind it, the approaches that failed, the questions still open, and the note the last session left behind. A fresh agent reads it with one get_context call and continues without asking you anything.
It gets written down
Mostly by the agent, while it works: what it decided, what it tried that failed, what it needs you to answer.
It stays put
In one database outside your repos. Branches, worktrees and fresh clones can't lose it, and it never lands in git.
The next session reads it
One get_context call and a cold agent knows what the last one knew — including which walls not to walk into again.
what actually goes in a log — the five kinds
- noteWorth remembering, but not a decision.
- decisionWhat you chose — and why the alternatives lost.
- dead endAn approach that did NOT work. The most valuable thing here: it stops the next session hitting the same wall.
- questionSomething only a human can answer. Surfaced instead of guessed.
- handoffEnd-of-session state, written so a stranger could continue.
Why the log is worth trusting
Dead ends are a kind of entry
Most notes record what worked. The expensive knowledge is what did not: the approach that looked right, cost an afternoon and failed for a reason nobody writes down. That one has its own kind here, because it is the entry that stops the next session repeating it.
A stale note says so
Every linked file is hashed by the side that can see it — your agent — and checked again later. When the code moves on, the note is flagged as possibly lying. Until somebody has actually looked, it says "not checked" rather than claiming to be fresh: context that lies is worse than none, and that includes lying about how sure it is.
The report is a query, not archaeology
Every status change is an event, so what got finished today, how long it took and which model did it are read from the log rather than reconstructed from commits.
Why not the memory your agent already has?
Claude Code writes its own notes now, and Cursor and Codex have theirs. Use them: they are good at remembering that you prefer pnpm. What they say, in their own documentation, is that they are per repository, per machine and per tool, and shared with nobody. todox is for what falls outside that line.
- Two machines, one log. A repository is identified by its remote, so the note left on the laptop is read on the desktop.
- Every agent, one log. Claude Code, Codex, Cursor and VS Code all speak MCP, and the handoff one leaves is what the next one reads — whichever it is.
- The people, too. A project can be shared, and the log carries who wrote what and which model did it.
- A shape a note in a file does not have: tasks that open and close, dead ends as their own kind, a report read from the log, and a stale note that says so.
What your agent reads, in one call
This is the shape of `get_context` — the first call every session makes. Not a summary of the product: the payload.
{
"project": { "slug": "todox", "summary": "Working memory for agents." },
"project_context": [
{ "kind": "gotcha",
"title": "A tool that answers {} still looks connected",
"body": "get_context returned {} on both transports: the transform
is async and the call site did not await it." }
],
"open_tasks": [
{
"title": "Bound the reads that had no ceiling",
"status": "doing",
"last_handoff": {
"id": 903, "kind": "handoff", "created_at": "2026-09-04",
"head": "Byte budget landed; heads are the remaining axis.",
"body": "auth bypass closed; briefing capped per kind and now
per byte. Left: the heads, which are still row-capped."
},
"decisions": [
{ "id": 812, "kind": "decision", "created_at": "2026-08-21",
"head": "Capped per kind, not per task.",
"body": "A flat cut drops the two old dead ends, and a dead
end is the entry that stops a repeat." },
{ "id": 819, "kind": "decision", "created_at": "2026-09-04",
"head": "Bytes, not count — a count of three says nothing.",
"body": null }
],
"dead_ends": [
{ "id": 806, "kind": "dead_end", "created_at": "2026-08-20",
"head": "1 MB body ceiling refused legal calls.",
"body": null }
],
"files": [
{ "path": "lib/services/briefing.ts", "status": "changed" },
{ "path": "proxy.ts", "status": "not checked" }
],
"entry_count": 14,
"log_omitted": 3
}
],
"log_bodies_omitted": 2,
"log_ranked_by": "focus",
"stale_refs": ["task #113 -> lib/services/briefing.ts (changed)"]
}Trimmed for width. The real one carries every open task.
Works with the agent you already use
One URL and a token. No package to install, no local process to keep running — anything that speaks MCP can connect: Claude Code, Codex, Cursor, VS Code.