DEV Community

Niv Dvir
Niv Dvir

Posted on Edited on Originally published at nivdvir.github.io

A Garbage-Collector Layer Between Claude Code Projects

Painting of trees of different species sharing one glowing golden root network in open grassland, with birds carrying threads of script flying between the canopies under a partly clouded sky.

Different species, the same marks. Separate trees, one soil, and the birds carrying what crosses between them.

A request you have made a dozen times, one that used to run at once, now sits and thinks. Tokens burn before a file changes. The forums blame the model, and often they are right. One of the reasons is quieter: the project is working from a picture of your code that stopped being true.

A Claude Code project keeps a managing layer above its content: instruction files, notes, who owns what. You write that layer once. The content moves every day, and nothing tells the layer. A missing file fails loudly. A stale one fails in silence. The project acts on an old map, learns of changes late, and cannot measure how far it has drifted. That drift is the garbage, and nothing collects it.

It cannot collect its own. A stale picture cannot know it is stale. Only the owner of the live state can. Change something another project owns and you leave work you cannot see. Asking its owner puts the only one who can spot it in the loop while you are still there, not after it has cost you a week.

A boss does not fix it, because the worlds differ. One project builds a product, one writes about it, one runs the outreach. The product project knows nothing about publishing. The article project cannot tell which version shipped this morning. Put either in charge and it rules on what it does not understand. Each needs the opposite: what its peers know, taken whole, to be the best in its own field.

That is what a working collector gives you, and the collector is a rule. No project acts on another's content because it looked right from outside. It asks the owner, who holds what the files do not say, names the work the change drags with it, and knows when someone touched it. Work happens by consent.

No runtime does this. The six laws that follow are the collector, and the owner of each project does the collecting.

The shape: a forest of projects

The unit here is the Claude Code project (CC-project from here on). An agent is one worker inside it. Inside a project, orchestrators already handle hierarchy: one spawns workers, all under one owner. Between projects there is no default. A tree in a forest is not higher than the tree beside it. Hierarchy exists only inside each trunk. Between trunks there is law.

A directory is a CC-project if and only if it carries its own CLAUDE.md. That file gives it a head, the one owner that answers for everything under it. Everything else is content of the nearest CC-project above. A subproject passes the same test and is a whole unit, the way a subsidiary is a whole company.

Two kinds of edge exist. Inside a trunk, head to sub-head: commands down, answers owed up. Between trunks, head to head: asks across, with no power to command.

Containment shows ownership but does not prove it. A file can sit in one tree and belong to another's domain. A scheduled job belongs to the domain it serves. Where the layout and the record disagree, the record decides. A contested entry stays contested until the dispatcher or the human rules, and a project that settles its own contested entry has ruled in its own favour.

Diagram of project A probing project B: a red blocked line trying to read B’s directory, which sits inside a solid guarded boundary, next to two green successful paths reaching B’s GitHub repo and public status inside a larger dashed boundary the permission system cannot see.

The permission system can see the solid line. The domain is the dashed one.

One entity sits above the trees. The dispatcher owns the working method and no content, serves every project, commands none, and insists on correct conduct. Gaps between projects end there: a contradiction that will not dissolve, an owner nobody can reach, a remit nobody recorded. A ruling inside a tree does not. With three CC-projects you hold that role yourself.

Diagram of three CC-project folders side by side. Inside the first, black arrows run down from its head to a sub-project and back up, with the labels commands and answers to. Between the separate folders, teal arrows carry the label asks, cannot command. A dashed box below holds the dispatcher.

Two kinds of edge, and only two: commands down inside a trunk, asks across between them.

The six laws

Each law covers one dimension, so you can read or apply any of them alone. Only the person these projects serve may amend one. Together they are the collector: the first tells you whose a subject is, the second stamps what comes back with its kind, the third carries the request and the answer, the fourth says what a request may not carry, the fifth gates what it may cause, and the sixth keeps two paths honest with each other. The walk-through after them shows it running.

1. Ownership

Every domain has one owner: a head.

Ownership is three inseparable things: the authority to rule on the domain, the responsibility for its records, and the capability to refresh them. Capability exercised through a human’s gated hands (a login, a credential, a click they must perform) still counts; it is mediated, not missing. If a leg is genuinely missing, the ownership itself is broken: fix that, never the symptom. Tree containment is evidence of ownership, never proof: an ownership recorded as contested in the registry stands contested until the dispatcher or the human rules, whatever tree holds the files. OS-level artifacts (a LaunchAgent, a cron entry) belong to the domain they serve, not the directory that contains them. The shared configuration directory is neutral ground, stewarded by the dispatcher. The registry is ownership’s map: read it before any cross-project work; keep your own row true; never write another’s; two heads whose subjects touch must recognize each other in both directions. (Standing rulings, 2026-08: the subject of a piece, never the platform, decides its ownership; every head carries its own publication capability, and no head manages publication for others.) Nobody else touches, verifies, or rules on a domain. They ask.

The mechanism is a shared registry, the thing FIPA calls a Directory Facilitator and describes as a yellow pages service.

  • Read it before any cross-project work.
  • Keep your own row true.
  • Never write another head's row.
  • Two heads whose subjects touch must recognise each other in both directions.

Who wrote an entry matters. One written by the head it describes is authoritative. You may use anyone else's entry about a head, and it carries no authority. An owner who cannot refresh a class of fact says so and stops. A caveat does not stand in for an answer. What this removes is the confident wrong answer.

2. Records

Every record is one of five kinds, and naming the kind is part of writing it:

a fact, true about the world, refreshable from a source; a positioning choice, a deliberate presentation (a CV emphasis, an outbound stance), which may differ from fact without contradiction, set and recorded by whoever owns the presentation, the human’s own presentation only by the human, and never invented by a head; a ruling, a decision by the human or an owner, which exists only once written into the file that governs the behaviour it changes, dated and sourced; a snapshot, a dated copy taken for one task, expiring with the task, never authority, and a snapshot of another head’s live state is taken with that owner’s knowledge, stamped with source, and discarded when the task ends; a draft, what was true when written, an archive, never a queue. A record’s kind is fixed when it is written; reclassifying your own record under challenge is resolving the dispute in your own favour: the defect, not a defence. Authority has exactly one home per kind: conduct here, ownership in the registry, procedure in the mechanics file, each domain’s rules in its owner’s governing files. Everything else anywhere, memories, boxes, histories, seeded context, is a pointer or a snapshot. A fix that has not landed in its single home has not happened. When two records disagree, check their kinds first: most contradictions are a positioning choice read as a fact, and dissolve. A genuine contradiction between owners, including a dispute about a record’s kind, is handled one way: tell the peer first, record both readings openly, neither side acts on either, until it is ruled. The dispatcher rules, except where the question is about the person all these projects serve, whose identity, history, or intent only they answer. Holding it open is correct behaviour; quietly resolving it is the defect.

Hold a pointer, not a copy. For any fact another head owns and can change, store the address and ask when you need it. When you must copy, stamp it with date and source and let it expire with the task.

Going stale is the small problem. The large one is the owner hearing their own record quoted back at them. And a ruling agreed in conversation has not happened, because the next session reads the governing file and not the conversation.

The figure shows the shape of it: two projects disagreed about where a third one lived, both held snapshots, and naming the kinds settled it. What the laws do not yet do is notify. Nothing told those projects the path had moved, and a rule that dissolves the contradiction after the fact leaves room for one that announces the change before it.

Two-panel diagram. Left, headed What it looks like: head A's record says the project lives at tilde slash old-name, head B's says new-name, with a red band between them reading contradiction, one of them must be wrong. Right, headed What it is: the same two lines tagged SNAPSHOT and FACT, with a green band reading no contradiction.

One is a snapshot, the other the owner's live fact.

3. Communication

You reach a domain only through its owner.

Enter at the head; the request descends one level at a time, and every node on the path is a participant, free to amend, answer, or refuse, never a relay. The answer returns up the same path, hop by hop. Name the subject, never another tree’s internals. One session per coherent request, and the test is: would the answer to one change the answer to the other? Yes, one session; no, separate sessions. A request is one of three kinds, named explicitly: a ruling (is this true, is this yours), evidence (give me your material, and the holder decides what leaves its scope), or capability (operate your tool for me, tiered by what the tool does, never by who asks). Asking is how facts cross boundaries. Never verify another’s domain yourself, and never impose a constraint that forbids an owner from refreshing its own facts. Constraints bind scope, not tools. An owner who cannot refresh a fact class says so and stops; a caveat is not a substitute for an answer. An owner who cannot be reached at all is a gap: log it to the dispatcher’s queue and stop, because self-service is not a fallback, and urgency that cannot wait goes to the human.

Skipping the middle costs. A node that holds two commitments, each visible to only one of its children, is the only one placed to see that they conflict.

A request path diagram. An initiator box on the left points into a target CC-project: the head, marked may amend, constrain, refuse, then one hop down to an intermediate level that adapts it, then one hop down to the owner of the content, who answers. A dashed line climbs back up, annotated at every hop, and a single consolidated reply returns to the initiator from the head only.

Every node on the path may amend or refuse the request. The answer climbs back annotated.

You never need another tree's internals. Name the subject, address the head, and let the chain place it. If you find yourself naming a sub-subproject, you have left the protocol.

4. Authority

A request carries the requester’s need, never its permission.

Laundering is the circumvention of a refusal, actual or reasonably anticipated: if you were denied something, or never asked because you expected denial, a peer doing it for you is the confused deputy, and it goes to the human, however large the efficiency argument. Providing a capability you legitimately own to a peer who was never refused is service, exceptional, not routine, and it is gated like any other action, by its consequence (Law 5). The complement of service: a deliverable’s substance is produced inside the domain responsible for it, and a peer supplies evidence and capability, never your work. If you cannot tell whether you are looking at service or at a refusal being routed around, you are looking at the second. Ask.

This is the confused deputy, arriving as a polite message from a peer. The law makes the deputy check the authority instead of inheriting it. The harder half in practice is the complement of service: the substance of a deliverable comes from the domain that answers for it, and a peer supplies evidence and capability. Claude Code now ships the first half of this rule itself. A message from another session does not count as consent, and a session must not ask a peer for an action its own permissions denied.

5. Consequence

The check precedes the act, always: a ruling that arrives after delivery is damage control.

Then gate every action by its consequence. Reversible, inside your own domain: proceed (GREEN / AMBER). Reversible, inside another’s domain: its owner decides. Irreversible, outbound, money, credentials, deletion, in whoever’s domain: the human, never automatic (RED). A recorded ruling outranks this ladder wherever it is stricter, and a standing gate binds even inside your own domain. And where an intervention risks real harm to a domain and rational weighing gives no sharp answer, the question returns to the human. Ordinary cross-project gaps are not that: they go to the dispatcher’s queue, not to the human’s desk. Operational tests: reversible means the same actor can restore the prior state, at the same tier, with no residue. Outbound means it reaches any party other than the human. Real harm means severe enough that the human would have preferred the act avoided or undone. GREEN, AMBER and RED are the official names of these rungs; satellite files that speak tier language are speaking this law.

Three stacked rungs of a consequence ladder. Top, red: to the human, tagged RED, for anything irreversible or outbound. Middle, grey: its owner decides, for a reversible action inside another head’s domain. Bottom, green: proceed, tagged GREEN slash AMBER, for a reversible action inside your own. A dashed box above says a recorded ruling outranks every rung. A dashed box below says an ordinary cross-project gap goes to the dispatcher’s queue, not the human’s desk.

Every action lands on one rung. A recorded ruling outranks the ladder wherever it is stricter.

Write the operational tests next to the gates, because a gate is only as good as the predicate under it.

6. Convergence

Two lanes serving one goal are not independent, however unrelated their subjects look.

Each must know the other’s live state, in both directions, or neither can price its own urgency. Say so explicitly the moment you discover a convergence, and keep the state flowing.

They are alternative routes to one outcome, so neither can price its urgency alone: progress on one changes what the other should spend. Detecting a convergence is the hard part. Two projects with different subjects, owners and vocabularies have no natural moment at which either notices. It is the law used least and found late most often.

One request, end to end

Project A needs a fact that project B owns.

A reads the registry, learns the subject is B's, and sends an evidence request into a session inside B. It addresses B's head, not the node A suspects holds the file, and names the subject in A's own terms. B's head decides the request is B's and places it one hop down. Each node answers or passes it on, until the owner of the content decides what leaves its scope. On the way back up, the middle node adds the one thing only it can see: a commitment its sibling made last week bounds the answer. B's head consolidates and replies once. A records the reply as a snapshot with source and date, keeps the pointer to B, and asks again next time.

When A wants B to do something, it sends a capability request naming the tool's effect, and B applies the gates. What A may not do is take a refusal from B and send the same action to project C because C has the same tool and no history of saying no. A records the refusal, stops, and takes it to the human.

When A and B contradict each other, they check the kinds first, because most of these are a snapshot read as a fact and dissolve on sight. If the contradiction survives, neither side resolves it. A tells B, both readings go on record with their authors, neither acts, and the dispatcher rules. Holding it open is the correct state until then.

What it costs, and what it does not do yet

This is a set of files and behaviours, and nothing in it intercepts a call. Only behaviour enforces it. The files exist to make correct behaviour cheap to look up. Renumbering a live standard has a price too: every note that cites a bare number then cites nothing, so write the concordance before you delete the old numbering.

Three limits stand today.

  • The mechanics move questions and answers between heads and have not yet carried a full cross-tree modification from request to landed change.
  • One lane asserted convergence with another, and nobody has confirmed it from the other side.
  • The laws are new, checked on paper and not by months of use.

What broke in the tooling is a separate field-notes piece. A protocol write-up with no failures in it is a design document in field-report clothing.

Test your rules like code

Rules a system runs on are code, and "it reads better now" is not a test. You wrote the sentences, so you are the worst judge of whether a stranger can follow them. Three checks catch what the others miss.

Blind adjudication. Take a dozen decisions your projects have already made and strip every trace of how they came out. Hand them, with the rule text and nothing else, to two or three agents that have never seen your system, and let each rule alone. A divergence from your verdict is either a real disagreement about what the rule should say or a sentence that reads two ways. You want both before the rules go live.

An inventory of undefined predicates. List every term the rules lean on without defining, then attach a test to each or delete it. Gates fail on undefined predicates, because everyone applying one is sure they know what the word means.

An adversarial read. Set an agent on the draft with no brief except to break it, and watch for a tidier definition that decides an open question while claiming to reorganise. A clean-up pass produces that failure more than any other.

The bar is not that every situation has a precomputed answer. It is that no situation lacks a lawful next move: following the rules always gives you something you may do, even when that is to hold the question open, tell the other side, and act on neither reading. Holding open is lawful. Resolving in private is the defect.

Where the ideas come from

Almost every piece of this has a published name already.

A tree, one head plus everything under it, is a bounded context in Evans and a holon in Koestler. The forest of independent trees interacting as peers is Koestler's holarchy, and distributed systems call it a federated architecture. The shared roster of who owns what is FIPA's Directory Facilitator, a yellow pages service, and Evans's context map. The dispatcher is a platform team in Skelton and Pais. Never modifying another tree's content, only asking, is Evans's anticorruption layer. A request that carries no authority of its own is Hardy's confused deputy.

Koestler describes hierarchies whose branches interlock with other hierarchies to form horizontal networks, which is the forest, half a century early. Agent communication languages typed requests by act long before this, with KQML's ask-if and FIPA's query-if and request. Entering at the head is Evans's aggregate root. Gating by reversibility is Amazon's one-way and two-way doors.

Two pieces are in no source I reached. The intermediate node as an active participant, free to amend a request in transit, where the closest specified behaviour requires a faithful relay. And marking a registry entry by who wrote it, so that anyone may use an entry written about a head, and it carries no authority, where FIPA's registry disclaims responsibility for what anyone registers and restricts nobody from registering anything.

Since this was written, part of it has shipped. Claude Code's cross-session messaging gives independent sessions a channel and a refusal switch, and its docs carry the fourth law: a message from another session does not count as consent, and a session must not ask a peer for an action its own permissions denied. The docs carry no notion of ownership, jurisdiction, or a request typed by what it asks for. Single-agent collectors exist too. Self-GC prunes a long-running agent's context, and context-diet audits persistent context for staleness. Each collects inside one agent. None collects between projects.

What transfers

If you run one agent, none of this applies. If you run several with real capability over shared resources, four things do.

Only behaviour enforces ownership. No configuration makes the permission guard and the ownership boundary coincide. "It did not prompt me" is not "it was mine to do."

Ask, don't verify. When another head owns a fact, ask for a per-claim verdict of confirmed, wrong, or not stated, and close with "what did I get backwards?"

Hold a pointer, not a copy. Store the address of anything that can change, and stamp any copy you take with its date and source.

Test your rules the way you test code. Blind adjudication is an afternoon, and it is the only way to learn whether a stranger reads your rules the way you meant them.

The literature is in domain-driven design, Team Topologies, Koestler, and a 1988 note about a compiler tricked into writing a file it should not have touched. Read those before you write your eleventh clause.

Reading, most useful first

  • Team Topologies (Skelton and Pais, 2019). Settles the platform-team role, and is the only source built for this problem shape rather than adapted to it.
  • Domain-Driven Design (Evans, 2003). Settles domain ownership and the seams between domains. The condensed DDD Reference is enough if time is short.
  • Koestler on the holon. Settles the forest shape. Two texts get confused: "Some General Properties of Self-Regulating Open Hierarchic Order" is Appendix I of The Ghost in the Machine (1967), and "Beyond Atomism and Holism: The Concept of the Holon" is the 1969 Alpbach paper. Check which you want before citing.
  • Hardy, "The Confused Deputy" (1988). Four pages, and the failure mode the anti-laundering rule exists to prevent.

FIPA's specifications are worth reading for the Directory Facilitator definition. The live fipa.org domain no longer serves them, so use the Internet Archive copies.

Originally published at https://nivdvir.github.io on September 8, 2026.

Top comments (0)