NanookNanook
  • Docs
  • API
  • Blog
  • Articles
  • GitHub

›Recent Posts

Recent Posts

  • 2026-11 Rules Need Exit Codes
  • 2026-11 The Agent That Pleases
  • 2026-11 Working Through 1,200 Plans
  • 2026-10 Tests First, Then Implement
  • 2026-10 A Table Cannot Stay Silent
  • 2026-10 What the Next Session Knows
  • 2026-10 One Root, Many Repos
  • 2026-09 Fewer Skills, Shorter Rules
  • 2026-09 Agentic Development
  • 2026-08 E-Invoices: 40 Dialects
  • 2026-08 One Login, Eight Cases
  • 2026-08 Testing a SaaS
  • 2026-03 AI-Assisted Tables
  • 2026-03 Manual vs. Automated
  • 2026-03 Equivalence Class Testing
  • 2026-02 Nanook Is Back
  • 2019-06 Introducing Nanook

One Root, Many Repositories: A Directory Layout and a Requirements Lifecycle for Agent Work

October 6, 2026

Torsten Link

Part 3 of 9 in the series on agentic software development. Part 1, The Agent Writes the Code has the two settings, the numbers, and the ten sentences the series works through.

For nine months an AI coding agent has written nearly all the code of a multi-product SaaS platform, and in a client project it built an event-driven service in eleven days. What makes the result trustworthy is the structure the agent works in, and the most literal form of that structure is a directory layout: where the rules live, where the code lives, where a requirement lives at each stage of its life. The layout is the same in both settings except at one point, and the lifecycle is the same in both.

The root is a repository too

I always work from a root directory that is itself a Git repository. It holds everything that steers the agent and everything that is shared across the code repositories:

root/                          ← Git repository
├── CLAUDE.md                  ← instruction file
├── .claude/
│   ├── rules/                 ← long versions of the rules, path-bound
│   ├── skills/                ← active skills
│   ├── skills-archiv/         ← archived skills (not loaded)
│   ├── agents/                ← sub-agent definitions (implementer, QA runner, reviewer)
│   ├── commands/              ← slash commands
│   └── architecture/          ← architecture docs
├── REQUIREMENTS/              ← analyses, designs, plans, done
├── knowlage-base/             ← knowledge base (its own repository)
└── repo/                      ← the code repositories

Why a repository? Because plans, rules, and decisions change constantly, and I want to see when a rule appeared and which incident caused it. A rule without its incident is a preference; with the commit that introduced it, and the plan that was open at the time, it is evidence. The root repository has 4,284 commits, more than most of the code repositories under it.

Two layouts, one difference

For a multi-product SaaS with shared modules, requirements live above the code, and the code is sorted by who owns it:

root/REQUIREMENTS/<PRODUCT or TOPIC>/
    analyse/
    design/
    plan/
    done/

root/repo/
    products/<product>/     ← app backend, app frontend, portal, landing page,
                               product-exclusive packages
    packages/               ← shared modules: backend / frontend / spec
    tools/                  ← test framework, table tooling, admin tools, MCP servers
    mocks/                  ← mock services
    archive/

REQUIREMENTS/ has one folder per product and a few cross-cutting ones: core, general, E2E tests, and a folder for items that are blocked or deferred. The assignment rule for code is mechanical, so that neither I nor the agent has to think about it:

If a package’s prefix is a product name, it lives in that product. If a second product adopts it, the prefix goes and it moves to packages/.

Every directory under repo/ is its own Git repository with its own release, and the apps import shared modules as versioned npm packages. That is what makes a change to a shared package travel through ten or more repositories before a user sees it; the release cascades that result are part 7.

For an event-driven microservice architecture, the main difference is that requirements live per service, not in a shared folder at the root:

root/
└── repo/
    ├── service-a/
    │   ├── REQUIREMENTS/{analyse,design,plan,done}/
    │   └── src/, tests/, tables/
    ├── service-b/
    │   └── REQUIREMENTS/…
    └── contracts/          ← message schemas shared between services

The reason is ownership. A service is designed, tested, and deployed on its own, so its requirements belong next to its code. In a multi-product platform with shared modules, a single requirement usually cuts across several repositories, so it belongs above them. The question to ask is not “monorepo or not” but “what is the unit that gets designed and released together?” The requirements go wherever that unit is.

All requirement documents, in both layouts, follow one file-name pattern:

<yyyy-mm-dd>_<analyse|design|plan>_<topic>.md

For example 2026-09-15_plan_01-the-xsd-gate-fails-silently.md. Plans get a daily sequence number starting at 01. The date sorts naturally, the type is visible without opening the file, and the agent can find all plans from last week about a topic with a single glob. That last point is the one that pays: an agent that can locate its own history with one pattern does not have to be told where to look.

Where to start: analysis or design

A requirement enters the folders at one of two points.

  • Analysis when I know nothing yet. What exists, what does the specification say, what do comparable systems do, what does the code currently do? An analysis ends with findings and open questions, not with a solution. If it ends with a solution, it was a design in disguise, written before the facts were in.
  • Design when I know enough to shape a solution. This is the normal starting point.

When the project is a new service, the agent’s first design is not a design. It is an outline of the designs we will need. For an event-driven service, a cut that has held up looks like this:

No.DesignDefines
00Overviewvision, core decisions, glossary, decision log
10Data contractmessages: fields, required, enum values, keys
20Data model & persistencetables, indexes, permissions, who migrates
30Inbound processingordering, conflicts, idempotency
40Responsibilitywho sees and may do what
50Deadlines & schedulingtick, grace periods, what a deadline triggers
60Outboundwhich message leaves when
70UI interfacepaths, roles, error shapes
80Operationsinstances, health, alerts, cleanup
90Test integrationhow the service fits the existing test landscape

The outline determines the order of work. Then we design one item after another until every item has been done once. In the client project, the twelve designs for the service were written on day one; the outline is what made that a sequence rather than a pile.

A review after every design, and tables early

Each design gets a review before the next one starts. By me, and often by a second agent that has not seen the conversation, so that it reads the document rather than the intent behind it. An agent that wrote the design will defend it; an agent that only receives the file has nothing to defend and reads what is there.

Two things go into every design:

  • Open questions as their own section. What is unclear stays visible, at the end of the document, until someone answers it.
  • A numbered decision log in the overview: decided, rejected, with the reason. The rejected alternative is the more valuable entry, because it is the one someone will propose again, and the log answers them without a meeting.

When interfaces already exist, one of the first items is often to build the decision tables: for inbound data, for the expected outbound data, and for the remaining data of an API. The tables define which classes of data exist and later generate them. In the service, they were also what found the contradictions in the specification before any code existed; that is important enough to be part 5 on its own. What matters here is their place in the order: early, among the first designs, not after the code as a test activity.

Plans change designs: the ripple effect

When all designs are done, the agent writes the plans: executable, step by step, with the files to touch, the tests to run, and the definition of done. A design says what; a plan says in which order, in which file, checked by which test.

In practice, writing the plans uncovers changes that were not visible during design. A step that sounded simple turns out to need a column nobody modelled. An interface assumed by design 60 is not what design 30 produces. These changes almost always affect the following designs and plans, and sometimes the preceding ones.

So planning is not a one-way street. When a plan changes an assumption, the affected designs are updated before the next plan is written. Otherwise the next plan is based on a design that is already wrong, and the plan after that on a plan that was based on it. The cost of going back is an edit to a document; the cost of not going back is an implementation of the wrong thing.

Done means moved

The folders analyse/, design/, plan/, and done/ are not labels. They are the state machine, and a document changes state by changing folder.

  • When the plans for a design exist, the design (or analysis) moves to done/. From then on it is reference material, no longer an instruction.
  • When a plan has been implemented, the plan moves to done/, and what was learned goes into the knowledge base (part 4).

This is not bookkeeping. The agent treats everything in plan/ as open work. A finished plan left in plan/ gets re-implemented, or worse, “fixed” against code that has moved on since. A plan’s status is also checked against the code, not against the plan’s own checkboxes: a box that says done is a claim; the code is the evidence.

Two more rules keep the folders honest.

  • Blockers leave the plan. If part of a plan cannot proceed, for a missing decision or missing access, the implemented part goes to done/, and the blocked remainder is extracted into a central BLOCKED-DEFERRED/ folder with the reason. A plan that stays half-open forever hides both what was done and what is missing. Before extracting, the blocker is verified; more than once, a “no access” turned out to be self-service.
  • Test plans go into a central E2E folder, not scattered across products, because tests usually span modules and a test plan filed under one product will be missed by the other.

The rules this part comes down to: the root is a repository, so that every rule has its incident and every plan its date. Requirements live with the unit that is designed and released together, above shared code and next to a service. Designs come first and in the order the outline sets, a review follows every one of them, and the plans are allowed to change the designs. And a document is what its folder says it is: a plan in plan/ is open work, a plan in done/ is history, and nothing is allowed to be both.

Previous: Part 2, Fewer Skills, Shorter Rules. Next: Part 4, What the Next Session Knows.

Recent Posts
Nanook
Docs Tutorials Guide
More About Articles Imprint Privacy Policy GitHub Manage Cookies
© 2018-2026 nanook.xhub.io — An Open Source Project by BeeBack UG.
Cookie preferences

We use cookies to analyze site usage and improve your experience. You can choose which cookies to allow below. See our Privacy Policy for details.

EssentialAlways active
Analytics