Retiring finished plans¶
A plan in docs/plans/ is written to get one piece of work done.
Once that work is finished, the plan is retired: what it knew that
is still worth knowing is moved to where it will be maintained, and
its files are deleted. This page defines when a plan is eligible and
what retiring one involves.
Why¶
Nothing removes a finished plan, so docs/plans/ only grows. In
October 2026 shakenfist and ryll each held over 180 plan files --
more than 100,000 lines in shakenfist -- and ryll had 23 plans that
had been finished for more than 90 days. Every agent session that
searches a repository wades through plans describing code that has
since been rewritten, and treats them as current. Worse, what a
finished plan holds that the documentation does not -- why the code
is that shape, which designs were tried and rejected, the work it
deferred -- is never read again, so it is lost while still sitting
in the tree.
Eligibility¶
A plan is eligible for retirement when both of these hold:
- its row in
docs/plans/index.mdhas the statusComplete,SupersededorAbandoned; and - no commit has touched the master plan, or any of its phase files, for 90 days.
The clock is the last commit rather than a date written into the
plan, so plans do not have to start recording anything new, and a
plan whose push-audit follow-ups are still landing is not yet
eligible. Superseded and Abandoned plans retire on the same
clock; for an abandoned plan, the reasoning worth keeping is usually
why it was abandoned.
What retiring involves¶
docs/describes what the plan built. Usually it already does; where it does not, the gap is filled.- The plan's reasoning is written down where it will be
maintained -- in
docs/, or inARCHITECTURE.mdwhere it is about the shape of the system. That means the constraints it verified, the measurements it took, the alternatives it rejected and why, and any push-audit findings it declined in writing. This is the part most easily lost, and the part whose loss costs most: it is how the next change avoids re-proposing a design that has already failed. - Each Future work item still worth doing becomes a GitHub
issue, labelled
from-retired-plan. The issues are filed while the pull request is prepared and listed in its body; if the pull request is closed unmerged, they are closed again. Items dropped instead are listed in the body too, each with a reason. - Every pointer to the plan is rewritten, to the new home of
whatever it was pointing at, or to the permalink below. Search for
each file's basename (
git grep -n PLAN-example.md), master and phase files alike. Two kinds of pointer are caught if missed: relative links insidedocs/are reported bydocs-external-links, and plan references in source byplan-source-references. Nothing catches the rest, which become silent 404s and stale names: absoluteblob/<branch>links inREADME.md, and plan names in backticks inAGENTS.md,ARCHITECTURE.md, other plans and.claude/. - The master plan and its phase files are deleted.
- The index row stays. It keeps its date, intent and status, and its link becomes a permalink to the plan's final text:
where <sha> is
That is the last commit on the default branch that changed the
file, so it holds the final text and, being on the default
branch, is never garbage collected. Never link blob/main: once
the file is deleted that is a 404. The index stays the complete
history of what the repository has planned, and git keeps the
text. A row whose link is an absolute URL registers no local
plan, so plan-index accepts a retired
row as it stands.
What it is not¶
- Retired is not a status. A retired plan's row still reads
Complete,SupersededorAbandoned. A status says whether a plan still wants attention, and a retired plan does not; that its text now lives only in history is already shown by the link. - A plan whose reasoning cannot be placed is not retired. If
there is no sensible home in
docs/for why the code is the shape it is, the plan is left where it is and reported, so that a person can decide. Deleting the only copy of a decision's justification to meet a 90-day rule is exactly the loss retirement exists to prevent. - It is never automatic. Retirement always goes through a
reviewed pull request: one per repository, one commit per plan,
merged by a person. It is deliberately not part of the
prune-reviewsworkflow, which pushes straight to the default branch and is safe only because what it does is computable. Deciding where a plan's reasoning belongs is not.
History¶
ryll's docs/plans/completed/ was an earlier approach: finished
phase files were moved there by hand and kept in the tree.
Retirement replaces it; the files in it retire like any others.
The retire-plans skill in the private llm-setup repository is
what does this, once it is written; it does not exist yet.