Originally published on contextforge.dev.

You can keep track of what your AI agents are doing right up until the moment you can't, and in my case the warning sign was a blog post that never appeared.

Here is what had happened. I have a pipeline that drafts posts for this blog twice a week — a scheduled job, a local model, no human in the loop until the draft lands in my dashboard. On Tuesday morning it ran, picked a topic, wrote eleven hundred words, ran them through a quality check, and tried to file the draft. The API rejected it: a post with that exact slug already existed. I had published that same article five days earlier.

The part that bothers me is not the wasted run. It is that the pipeline reported the run as a success, and I only found out because I noticed, hours later, that there was no new post. The duplicate was caught by a unique constraint on a database column. Not by the system. Not by me. By a schema decision I made months ago for unrelated reasons.

This is not a memory problem

My first instinct was to reach for memory, because that is the thing I build. It was the wrong instinct.

The pipeline did have a record of which topics were already covered. A list, maintained by hand, sitting in the code. It was simply out of date, because every time I publish something I have to remember to go add it — and the whole point of delegating the work was to stop holding things in my head.

Memory answers what did we decide. That is a real problem and I have written about it plenty. But it is not this one. This one is what work exists, where is it, and what state is it in — and no amount of recalled context answers it, because the answer isn't something you once said. It is something the work itself has to carry.

It is also not the same as knowing what is running right now. I wrote about that separately: when you have several agents open at once they collide, and the fix is a live presence layer (one developer, five terminals, zero awareness). That answers what's happening. What I am describing here is the slower, quieter question — what's there — and it is the one that bit me.

Four pieces, in order

The structure that fixes this is boring, which is probably why it took me so long to take it seriously. Four nested things, each answering a different question.

A project is the boundary. One product, one repo, one piece of work with edges. It exists so that when an agent asks a question, the answer isn't drawn from everything you have ever done. Your agent links to it once per machine and stops guessing:

memory_link_project → ties this directory to a project memory_current_project → confirms which one it's in 

A space is a folder by topic, inside the project. API, Frontend, Infra, Decisions. Keep them broad — the pull toward a space per feature is strong and you should resist it, because a hundred spaces is the same as none. Spaces are what make retrieval land near the right thing instead of somewhere in the general vicinity.

An item is a fact or a decision. "We chose Postgres over DynamoDB because the access pattern is relational." Tagged, searchable, attached to the files it describes. This is the memory layer proper, and if you have read anything else on this blog you already know my position: the value is in what gets written down, not in the retrieval being clever.

A task is work that hasn't happened yet. This is the piece people skip, and it is the one that would have saved me on Tuesday. A task has an owner, a priority, a due date, and a status that moves from pending to in progress to resolved. It is the only one of the four that represents the future rather than the past.

tasks_create → with title, priority, due date tasks_list → pending, sorted by due date tasks_what_next → "what should I pick up?" tasks_start / tasks_resolve 

Put the four together and the question "what is going on with this project" has a place to be answered from, instead of being reconstructed every morning from your own recollection.

What it looks like from inside the agent

Here is the part that is easy to miss if you only ever look at a dashboard: the point is not that you can go look. The point is that the agent looks, before it does anything.

My own CLAUDE.md opens every session by doing five things in parallel: query the project memory, pull the last few commits, list tasks that are in progress, list tasks that are pending sorted by due date, and check whether another session is already working in this project. Then it tells me what it found before it answers whatever I asked.

It takes about two seconds and it has changed how the first five minutes of my day go. I don't open a session and ask "where were we". The session tells me, and if something is overdue it says so first.

That is also why the structure has to live behind MCP rather than in a project management tool. A tool you have to open is a tool you check when you remember to. A tool your agent reads at session start is one you can't forget.

Setting it up is one command:

claude mcp add contextforge -s user \ -e CONTEXTFORGE_API_KEY=your-api-key-here \ -- npx -y contextforge-mcp 

Then npx contextforge-mcp init, which writes the session-start section into your CLAUDE.md so the agent actually does the looking.

Where this doesn't save you

I want to be straight about the limits, because three of them are real and one of them is the reason I lost a run on Tuesday.

If nothing gets saved, there is nothing to see. The structure is only as good as what the agent writes into it, and agents under-save. I am still tuning this and it is the part of the product I am least satisfied with.

Tasks go stale like every tracker ever built. There is a freshness check that flags memories when the code they describe changes, but it does not watch your task list. A task nobody resolved looks exactly like a task nobody started.

It does not tell you what is happening right now. Different problem, different answer, linked above.

And it will not make you understand code you did not read. Structure over delegated work is not the same thing as knowing your codebase, and conflating the two is its own trap (vibe coding is a trap).

My Tuesday failure was the first one. The pipeline never recorded the posts it had already written as anything an automated check could read. The list lived in a comment, maintained by a human who had other things to do.

What to do today

Pick the project you have most lost the thread on. Then, in order: link it, create three or four broad spaces, and — this is the one that matters — write down the four or five things you are actually waiting on as tasks, with due dates. Not a backlog. The things that are genuinely live.

Then open a session tomorrow morning and let the agent tell you what it found.

The test is simple. If your agent can answer "what is pending on this project, and what did we decide about it" without you explaining anything first, the structure is doing its job. If it can't, the work is still living in your head, and the next thing you delegate will go missing the same way mine did.