Most AI coding setups keep two documents: a plan the agent writes once, and notes/memory it forgets to update. By Tuesday the plan describes a project that no longer exists.

I had a progress log and was about to add a plan file next to it. Then I asked the obvious question: do these two need to be separate files? They didn't. Here is what I changed and where you can take it.

What I started with

My brief was short: keep a log of which subtasks are done, tell me when to compact, and tell the compactor what to throw away. In my words:

make sure that it reminds to compact? so that it is not losing context for the next set of tasks and saving on the credits.

That became the progress-log skill for Claude Code. A hook reminds the agent to compact between groups of work, gives the compactor rules on what to keep and what to drop, and restores the log afterwards. A fresh context no longer means a fresh start.

None of this is a new idea. Anthropic's guide to context engineering names both halves: compaction, which summarises a conversation near the context limit and starts a new window from the summary, and structured note-taking, where the agent

"regularly writes notes persisted to memory outside of the context window" [1].

Keeping the window small matters too: Chroma's context rot study found that model performance

"grows increasingly unreliable as input length grows" [2].

The skill is my attempt to make those two habits automatic.

Why plan.md was the wrong second file

A plan and a log answer different questions. The plan says what we are doing and why. The log says where we are now. The plan changes rarely; the log changes after every subtask.

That sounds like a reason to keep them apart. In practice, three things went wrong:

  • Compaction. After a compact, the hook restores the end of progress.md. A separate plan.md would not come back on its own.
  • Visibility. The timeline pane reads one file. A plan outside it never shows.
  • Drift. With two files, the plan says one thing while the log has moved on, and nothing notices.

Before: plan.md drifts from progress.md. After: one progress.md with goal, subtasks and evidence.

So the plan moved into the log, and the agent is told never to create a plan.md at all. Each task section now carries its goal, its groups of subtasks, and its proof:

## Add login (2026-11-06) Goal: users can sign in with Google. Done means a new user reaches the dashboard. ### OAuth - [x] Callback route, 6 tests pass - [ ] (background) Run the full test suite ### Sessions - [ ] Session expiry Notes: chose cookies over JWT because we need server-side logout. | Goal | Evidence | Achieved | |---|---|---| | New user reaches dashboard | e2e test passes | Yes | 

The rule that makes it work: a box is ticked only when a test, a command result or a PR shows the work is done. "Done" without evidence stays unticked. Labels such as (background) and (subagent) say how each subtask runs, so the plan doubles as a work order.

Here is the loop the hooks run around that file. Claude Code fires a PreCompact hook before compaction and a SessionStart hook whose matcher includes compact when the session resumes after one [3]:

The loop: work a subtask, tick only with proof, compact when a group finishes, hooks restore the log.

It's ReAct, written down

The loop isn't new either. In 2022, ReAct showed that language models do better when they

"generate both reasoning traces and task-specific actions in an interleaved manner" [5]

Think, act, look at the result, think again.

Claude Code's agent already works this way.

What progress.md adds is a place for that loop to live outside the context window:

ReAct step In progress.md
Thought The goal, the groups and the next unticked box
Action The agent works that subtask
Observation The evidence: a test result, a command output, a PR

In ReAct the trace sits in the model's context, so in a long session it gets summarised away at the next compaction. Here it's written to a file and survives. The evidence column is the observation step you can audit.

The pane

A log nobody reads is a diary. I wanted it in front of me while I work, so I built progress-timeline, a Claude Code mod that shows the log as a timeline in a pane beside the chat. Green is done, yellow is in progress, grey is planned. It opens by itself when a new plan appears.

The progress-timeline pane beside the Claude Code chat, showing subtasks as green (done), yellow (in progress) and grey (planned).

My review of the first working version, verbatim:

this looks awesome? thankyou!!!!

Engineering standards remain high.

Get it

Install the pane from the repository's plugin marketplace. In Claude Code, a marketplace is "a catalog that lists plugins and where to fetch each one" [4]:

claude plugin install progress-timeline --marketplace iaintsaket/how-saket-claudes 

The skill's compaction reminders need Claude Code hooks and Python 3. Setup steps are in hooks-setup.md in the repository.

Before you copy this

  • It is a convention, not magic. The pane only reads the format above, so any tool or person can write the file.
  • The agent still makes mistakes. The evidence column exists so you can check its claims instead of trusting them.
  • The pane needs room. Claude Code only opens it unasked in a wide terminal. In a narrow one, run /progress-timeline to open it yourself. It docks on the right, and that can't be changed.

If you try it, tell me what broke for you.

References

  1. Anthropic Applied AI team, Effective context engineering for AI agents, 29 September 2025.
  2. Kelly Hong, Anton Troynikov and Jeff Huber, Context Rot: How Increasing Input Tokens Impacts LLM Performance, Chroma technical report, 14 July 2025.
  3. Claude Code documentation, Hooks reference.
  4. Claude Code documentation, Plugins overview.
  5. Shunyu Yao, Jeffrey Zhao, Dian Yu, Nan Du, Izhak Shafran, Karthik Narasimhan and Yuan Cao, ReAct: Synergizing Reasoning and Acting in Language Models, arXiv:2210.03629, 6 October 2022.