v1.16.0 ·
The memory that outlived the code
This framework keeps a written memory of the codebase it works on: which parts exist, what they do, which decisions were taken. The phases are told to read it before the code, because a summary is cheaper than re-deriving one. That memory cannot tell when it has gone out of date.
The report came from another project, a desktop app 48 pieces of work deep. On the 51st, the memory said an earlier piece of work had built a particular screen component. It had not. The component never existed under that name. A design written against that note would have called something that was not there, and nobody would have known until it ran. The note had been accurate when written. A later piece of work renamed things and nothing revised it. Old and wrong look the same from inside.
The wording made it worse. One phase was told to consult the memory "before re-deriving from code". Another was told it is "the first source of understanding", with the code as the fallback for what it does not cover. A careful reader following that does exactly what went wrong.
The same report had a second complaint with the same root. Work framed as building something new turned out to be generalising something half-built. One looked like adding reminders, and the scheduling, the dock badge and the settings were already there. Another looked like deleting a feature's folder, and was really about what else reached into it. The design step never opened a file to find out. Between "what is wanted" and "how it will be built" there was no step that looked at existing code.
What changed
The memory is now described as an index: the cheapest way to find where to look, and no more. Anything it names gets opened before it is designed against.
The report named the design skill. Grepping for the wording found it in three, and the worst was ideation, a step further upstream. The ideation, design and implementation skills (packages/content/skills/10-ideation.md, packages/content/skills/30-design.md, packages/content/skills/40-implementation.md) now all say so. This project already has a lesson about it: one reported bad prompt turned out to be twelve.
Design also gained a step before any structure is proposed: find the seams. It must name the existing files in design.md, or state that nothing exists. That sentence matters. It separates a truly new component from one designed beside the code that should have absorbed it. Each component then says whether it extends a seam or is new. There are two new exit criteria, so the absence is visible. The step renumbering is pinned by packages/cli/test/brownfield-content.test.ts.
Why this way
I rejected a checker that walks the memory and looks for each name in the code. It is automatic, but every future piece of work would pass through it. This project shipped 11 features and no fixes in its first nine days, then one feature and seven fixes in the next five, and five of those seven traced to features that watch the lifecycle. A staleness checker is that shape.
I also rejected stamping each note with its age. An old note still reads as a fact, and the failure was never that someone thought a note was fresh. The instructions said it was the authority.
So the change is a sentence, not a tool. aidlc knowledge verify <id> and aidlc knowledge update <id> already existed, and no phase pointed at them. Design now does.
The new reading step is bounded in words, not a number: the seams the requirements touch, a handful of files, not a survey. A number is wrong both ways, forbidding the reading on a big seam and inviting padding on a small one. I left requirements alone, though a requirement phrased as "build a notification system" has already picked the new-build framing. Asking for the same reading twice costs twice and improves nothing.
What it does not fix
The memory can still be stale. It is just no longer believed on sight.