How to spot a stale plan before your agent follows it
Last updated: 23 September 2026
A plan does not announce that it has gone out of date. It reads as confidently on day forty as on day one, and the next agent to open it will follow it just as confidently. The problem is common. A 2023 study found outdated code references in 40.7% of the documentation files it examined, and a 2026 study found stale references inside the AI context files of 23% of the repositories it looked at.
The good news is that the signs are mechanical, and you can check them. Here are three you can check with git, and how flanner checks them for you.
Sign one: it names things that no longer exist
The strongest sign is a plan that cites a file or a function your code no longer has. Look for each path and name it mentions:
git ls-files src/auth/session.tsgit grep -n "createSession"No output means it is gone. To see whether it existed once, and when it went, ask the log for the last commit that touched it:
git log --oneline -1 -- src/auth/session.tsA name that once existed and no longer does is not a guess about the plan. It is a fact: the plan describes code that is not there.
Sign two: the code under it has moved a lot
A plan can cite only things that still exist and still be wrong, because the code around them changed. Count the commits that touched the files it describes since it was written:
git log --oneline --since="2026-09-01" -- src/auth/ | wc -lA handful is normal. Dozens mean the plan was written against code that has since been reworked, and it needs reading again before anyone follows it.
Sign three: it is old
Age on its own is weak evidence. A plan for a quiet corner of the codebase can stay right for a year. Treat age as a reason to look, not a reason to throw the plan away.
How flanner checks a plan
flanner freshness runs those checks against your git history for every plan flanner keeps, and gives each one a status:
- stale: the plan cites a path or name that existed in your history and no longer does.
- suspect: 20 or more commits touched the files it cites since it was written, or 60 across the whole repository when it cites no files.
- aging: 5 or more such commits, or the plan is more than 45 days old.
- fresh: none of the above. Without git, only age is checked.
flanner freshnessflanner why auth-rewriteflanner why prints the evidence behind one plan's status: the names that no longer resolve, the commits since, the files it cites. Add --output json to flanner freshness for the raw fields.
"Since it was written" means since the newest commit at or before that version was saved. flanner works it out when you ask, and stores nothing about your code. It finds the files and names a plan cites in its code spans, so writing src/auth/session.ts in backticks is what makes a path checkable.
Your agent can ask the same question before it trusts a plan: the MCP tool get_plan_freshness_tool returns the status and its evidence.
What to do with a stale plan
- Update it. Ask your agent to revise the plan against the code as it is now. The revision is saved as a new version, so the old one stays readable.
- Retire it. If the work is done or abandoned,
flanner retire auth-rewrite --reason "shipped in 2.3"takes it out of the way without deleting its history. - Disagree. A status is evidence, not an order. Heavy churn in a file can be a rename that changed nothing the plan relies on. You decide.
Plans that stop being true is why flanner exists, and the freshness docs have the full rules.