Restructure: agent-centric model + demolition - #673
Draft
Wirasm wants to merge 20 commits into
Draft
Conversation
Captures the reframe from Room-as-primitive to agent-as-primitive, and audits the whole tree against it. The model (docs/model.html): a kild is a worktree/workstream; the agent is the sole inhabitant type on one mechanism axis (owned vs attached); the honryo is an agent wearing human-authority intelligence — in practice the CLI a human drives. Messaging is directed and peer-to-peer; spawn defaults to sharing a tree, forking one is the deliberate act. All process and persona lives outside the engine. The audit (docs/DEMOLITION.md, docs/demolition.html) marks every file keep/reshape/move/die. Two separate teardowns fall out: the Flue lane is dead code no live path imports (kild/run.ts, kild/auth.ts, flue/, workflows/, flue.config.ts, the @flue/runtime dep), and the room choreography — router, lifecycle, decisions ledger, operator tier — is intelligence living in the engine. No code changes; these are design documents.
The extension stays and is rebuilt, not retired. It is not "the operator tier for pi" — it is the pi implementation of the attached-harness contract, peer to Claude Code's: attach a handle, drain an inbox at the turn boundary, act through the same API every client uses. pi's integration is the better of the two (a native turn-boundary drain rather than a shell hook), which is why it earns its keep. A third harness later is another implementation of the same contract, not another mechanism in the engine. Records what the rebuild deletes (the operator guide and prompt injection, the decision vocabulary, @Human semantics) and what it keeps (the REST/WS client, bootId restart detection, the event bridge that is pi's drain).
Five docs describing work that has either shipped or is being torn out: - engine/COMPARISON.md — the Flue-vs-Rust decision record, defending a bet that is being deleted from the tree - docs/fleet-observability.md — spec/tracker; phases 1-2 shipped, phase 3 is superseded by the agent-centric reframe - docs/room-mailbox-notes.md — review notes on the room module being dismantled - docs/pi-extension-plan.md — plan realized by the extension, which is now being rebuilt in a new shape - docs/upstream-worktree-sandbox.md — proposal to upstream the Flue sandbox that is going away docs/DEMOLITION.md records why each one goes.
Nothing on the live path imported any of it. The engine runs server.ts -> worker.ts, which resolves models through pi's ModelRuntime directly; the Flue modules were reachable only from each other and from frozen demos that workflows/README.md already described as off the hot path. Deleted kild/run.ts (Flue in-process runner), kild/auth.ts (bridged pi credentials into Flue's configureProvider, imported only by a demo), src/flue/ and src/workflows/ entire, and flue.config.ts. Dropped the @flue/runtime dependency, the @flue/cli devDependency, and the flue script. DEFAULT_MODEL goes with them: its only importers were deleted files, and model resolution reads KILD_MODEL directly. The one deleted test, flue/worktree-sandbox.test.ts, covered a deleted module. 260 tests pass, typecheck and lint clean.
Every MOVE needs a mechanism counterpart. Deleting the intelligence and its trigger together does not relocate a capability, it removes one — and the first pass of the audit tracked only what leaves. Two cases it coupled without noticing: Memory synthesis loses its only trigger when room-close goes. The engine keeps the seam: a lifecycle event on close/land carrying the facts it holds, and a generic hooks.onClose the engine runs without knowing what it is for. The charter and persona are what move to PRP; memory.synthesis generalizes into that hook rather than disappearing. finalNonSystemPost dies with room-events.ts, and it is what writes the ledger's outcome line. It should not be ported: it is a tail-grab standing in for facts the engine already owns. The ledger instead records the land result, commits vs base, changed files, and per-agent model and cost — all from git-review, worktree-status and the session bus. Prose outcome belongs to PRP's synthesis. Also records the cross-repo call: helm cannot land atomically with kild, but it is unaffected until the one commit that renames /api/rooms to /api/kilds. helm pins across that commit rather than the engine dual-serving both route families.
kild had three baked-in ranks: operator, lead, worker. The operator was a privileged session type the engine granted room-control tools to. In the agent-centric model the human's agent CLI drives the REST API as an ordinary client, so there is no tier to grant: kild ships no brain. Removes the four operator tools, the KILD_OPERATOR capability in worker.ts and server.ts, and the whole `kild operator` CLI group. fleetMemorySection goes with them — it existed only to give operator sessions cross-project memory and had no other caller. engine-client.ts and rooms-status.ts move up out of operator/: neither is an operator concern. rooms-status carries the cross-kild collision computation, which is general observability that was only ever filed in the wrong folder. One test goes with its subject (fleetMemorySection); no other test failed at any point. 259 tests pass, typecheck and lint clean. pi-extension still references the removed capability. It is rebuilt against the new shape in a later commit rather than patched twice.
Three things the engine enforced that are the intelligence layer's to
decide, not mechanism kild should ship.
The decisions ledger: needs-decision[key] markers folded from post text
into a room ledger that blocked close until resolved, with a force
escape hatch to bury it. A protocol, and one the engine had no business
parsing out of prose. Gone with its force parameter, its REST field and
its paragraph in the mechanism prompt.
The idle nudge: a participant that finished a turn without posting got
prompted to report. That is a reporting norm. Deleted — but note the line
drawn here: `idle` itself is kept. It is state, not a norm (it rides the
participant view so a client can see who is finished and waiting, and an
empty mailbox drain is how an attached participant signals the same
thing). What goes is the engine telling an agent how to behave.
Implicit replies: an agent's turn-final narration was auto-posted so the
human could see it, and the router then needed a rule to stop that
narration from waking other agents. Both halves go; reaching another
agent takes an explicit post, which is what the tool always claimed.
The mechanism prompt also advertised the nudge ("kild nudges IT to
report"), which would have become a false promise — removed.
24 tests go with their subjects, each listed in the review notes; no test
was removed to green a gate. 235 pass, typecheck and lint clean.
VOCABULARY.md fixes three collisions the codebase had grown. `agent` meant the persona file in the CLI, the same data was `/api/personas` over REST, and `listAgents()` in code — while the running thing had no stable name at all (worker, participant, session, depending where you looked). `role` meant both the persona wrapper tag and the process role. `session` meant both a running agent and pi's conversation. Now: persona is the file, agent is the process, session is pi's alone. One word per concept, one concept per word, plus the rules that keep it that way — no rank words, and upstream keeps its own vocabulary. helm-migration.md is the client-side guide: every route, payload field and WS frame that moves, what disappears entirely (implicit, decisions, posted, stopped, force) and why, and the pin/un-pin sequence. helm and kild cannot merge atomically, so the rename is deliberately one commit and therefore one pin boundary.
The migration guide claimed git and totals were unchanged "including collidesWith". Wrong: collidesWith is produced by computeCollisions inside compactLiveKilds, which is the CLI's compact view. It is not on GET /api/kilds and never was. What the endpoint does carry is git.changedFiles, which is everything a client needs to derive collisions itself — so deriving them client-side is the correct approach, not a workaround. A guide claiming to be everything a client needs has to be right about what is on the wire. Also documents why /api/worktrees survives next to /api/kilds (a worktree outlives its kild: listing and pruning a stranded tree must work when there is no kild to ask about), flags the duplicate transcript routes as resolved-before-you-migrate, and states that `from` is already engine-derived — supplying it is a hard rejection, not silent acceptance. worktree-disposal.md records a live bug found while auditing: any untracked file marks a tree dirty, dirty trees refuse removal, and prune swallows the failure in a bare catch. Tooling that writes residue into every tree at creation therefore makes every tree unreclaimable from birth, with nothing reporting it. Measured at 116 stranded trees. The silent catch is the defect that let a policy disagreement become a leak.
The rename was 1:1 by design — 25 endpoints in, 25 out — which is right for crossing a pin boundary but means the demolition has not yet reached the surface clients touch. These are the calls for the step that does. An agent is addressed by handle. This reverses helm-migration.md, which said id should win because handle is "an addressing concept, not a routing key" — but that distinction is exactly what produces two identifier schemes for one object, which is the shape the reframe exists to delete. Verified safe: an agent stays on the roster after it stops, so a handle never rebinds. Prompting an owned agent is therefore just sending it a message, and the two delivery paths collapse to one. Disposal gets a verb, guarded on authored commits rather than a clean tree. Measured: 116 worktrees, zero reclaimable, and 27 of 27 sibling trees refused as dirty from provisioning litter written before any agent ran. A branch carrying unmerged commits is real work and the branch is the safety net; uncommitted litter is not work, and treating it as work is what produced 116 permanent trees. /api/worktrees folds into /api/kilds, with the requirement that the listing enumerate from git rather than the registry — otherwise a tree whose kild record is gone has no id to address, which is the same stranding being fixed. Attribution moves to a credential minted at attach, sequenced with the router commit since send is where from is resolved. Notes two corrections: the engine's session id is engine-assigned, not a pi detail, and `from` is already rejected on request bodies rather than caller-supplied.
Agents in different kilds cannot reach each other, so a human copies
messages between them. Not only a cross-repo problem: the agent in
kild/auth that finds an API change affecting kild/api has no way to say
so either. Parallel workstreams that cannot talk are half-parallel.
The tempting design is a kild-to-kild channel. Rejected — the endpoint is
an agent, not a kild, and what is missing is address space, not a channel.
A second messaging system would grow its own delivery rules, its own
guard, and its own log, and drift. This whole reframe exists because a
second answer to "who is this addressed to?" was allowed to exist.
So: widen the address on the existing send. Structured {kild, handle},
kild always an id, never a name — names are not unique across an engine,
and resolving them in the engine would reintroduce exactly the
name-or-path guessing server.ts already removed after it opened a kild
whose worktree could not be created and still returned success. Friendly
name/handle resolution belongs at the caller.
One real change falls out: the wake cap must stop being attached-only.
It guards attached inboxes today because only attached agents could
ping-pong; once any agent can address any other, two owned agents loop
just as easily and cost more, since nobody watches a kild the way a human
watches their own terminal.
Also records the stopgap that works today with no new mechanism (attached
agents do not run in their kild's tree, so a kild can serve as a pure
channel), and why removing the human from the transport makes the keyed
decision protocol in PRP more load-bearing rather than less.
cross-kild-comms.md ended by naming this gap without answering it. PRP raises, kild carries, helm surfaces — and helm owns the surfacing permanently rather than until something better exists. A decision is the one thing the engine produces that is worthless if nobody sees it; everything else is designed to run unattended. Reaching a screen and persisting until acknowledged is a client's job by definition. kild adds nothing for this. `idle` already identifies an agent that went idle after asking — which is exactly why it survived the process-norms cut as observable state rather than a norm — and the planned monotonic `seq` covers "new since I last looked". No escalation type, no engine verb: deciding that a message is a question rather than a status update is interpretation, and the keyed-decision ledger was just removed for parsing exactly that out of prose. The requirement helm must meet is borrowed from the disposal leak, which only became visible when someone counted at 116 trees: unanswered must be loud and countable. If helm cannot answer "how many agents are blocked on me right now" at a glance, the mechanism is not finished. A second app is deferred rather than rejected — it is the right answer if escalations must reach someone when helm is closed, but that is a conclusion to reach after the cheap version shows how often this fires.
One atomic rename, no behavior change, so it reviews as names moving and crosses helm's pin boundary exactly once. Room becomes Kild — the unit of work is a git worktree, not a social construct with its own lifecycle. Participants become agents, the sole inhabitant type. The room/ slice flattens into the domain root, since Kild is now the domain rather than one slice within it. Three collisions are resolved in the same pass, because they were the reason the vocabulary could not be made consistent piecemeal: `agent` meant three things — the persona file in the CLI (`kild agent ls`), the same data as /api/personas over REST, and listAgents() in code — while the running thing had no stable name at all, being variously a worker, a participant, or a session. Now persona is the file and agent is the process. `role` meant both the persona wrapper tag (`withRole`, `<role>`) and the process role (KILD_ROLE). Now `<persona>` wraps personas and KILD_ROLE is the only role. `session` meant both a running agent and pi's conversation. It now means only pi's, which is whose word it is. worker goes with them. It is rank vocabulary — a worker implies a lead and an operator above it, which is the org chart this branch deleted — and it imports the job-queue model of an interchangeable executor pulled from a pool, which an addressable agent that holds context and spawns peers is not. The tell was server.ts having to explain that KILD_ROLE=worker "runs a single agent session". post goes too: you post to a board, you send to a person. Broadcast vocabulary in a system whose whole point is that the sender names the recipient. REST moves to /api/kilds and /api/agents, WS frames follow, and the CLI loses its room subcommand group. HUMAN, the lead default and the lifecycle states are renamed but deliberately intact — they are removed in the router commit, and mixing that into this diff would make it unreadable. 235 tests pass across 26 files, exactly the count before: a rename must not change it, and no test was deleted. Typecheck and lint clean. Engine boots and serves /api/kilds and /api/agents; /api/rooms/live is a 404.
The skill is the contract every agent drives kild through, and it documented commands that no longer exist: the whole `kild operator` group (deleted with the operator tier), `kild room *` (now top-level verbs), `kild sessions` (now `kild agents`), and `kild agent ls` (now `kild persona ls` — the word `agent` moved to the running process). Two claims were not just renamed but false. It described delegation via `invite_agent`/`post_message`, which are now `spawn`/`send`. And it promised "if a delegate finishes a turn without posting, kild nudges IT to report" — that failsafe was deleted as a process norm belonging to PRP, so the skill was teaching agents to rely on a mechanism that no longer exists. It now says plainly that reporting is the agent's responsibility and nothing will chase it. Adds the vocabulary section so the persona/agent/kild/handle distinction is stated where agents actually read it, and points at worktree-disposal.md on prune, since prune only reclaims merged and clean trees and abandoned work otherwise accumulates silently.
The hook drained with `kild room drain`, which is now `kild inbox`. Every failure path here exits 0 by design — a hook must never block a turn — so the rename would not have raised anything. It would simply have stopped delivering mail, silently, which is precisely the failure its own header warns about in the generation before it. Also moves the wiring env to KILD_KILD_ID / KILD_HANDLE, matching what the engine sets on the agents it spawns, so an attached agent describes itself the same way an owned one does. Adds the note this file was missing: because everything here fails silently, the CLI verbs are the one thing to re-check whenever the command surface moves. Verified end to end against a live engine — attach, send, drain returns the Stop-hook block JSON naming the new verbs, and a second drain prints nothing and exits 0.
The guide told helm to pin across the rename and un-pin after, which was true when the rename was the only breaking change. It is not anymore: the router commit drops `system` from messages and `state`/`stopped` from kilds, and requires `to` on every send; the reshape changes routes again. Porting to each intermediate state would mean doing the work three times, so helm stays pinned until the reshape lands and ports once against the final surface. Documents the combined delta of the rename plus the router commit, including the two things a client is most likely to have built on — system notices in the thread, and keying off `state`. Also records the split the router commit is careful about: the engine never infers a recipient, but the CLI may resolve `--to` client-side when a kild has exactly one agent. Convenience in the client, never a rule in the engine.
The extension was the operator tier for pi: it injected a <kild-operator> guide, spawned sessions with operator: true, spoke the needs-decision vocabulary and special-cased @Human. All of that was intelligence the engine no longer has and the extension has no business shipping. It is now the pi implementation of the attached-harness contract, peer to Claude Code's hook plus CLI. Eleven tools mirror the CLI verbs one to one, described in mechanism terms only. The bridge is now literally the drain. A {message} frame addressed to a handle this session attached is only the wake signal; the mail itself always comes from the inbox drain, so the engine's destructive-read and wake-cap semantics apply to pi exactly as to any other harness rather than pi having a privileged push. Reconnect drains each attached handle once, since the inbox is engine state and a socket gap loses nothing. Two things the rebuild surfaced. There is no REST route to spawn an agent into a kild — it is WS-only and fire-and-forget, so kild_spawn cannot report a truthful synchronous failure and instead polls and reports what it observed. And kild_new does not attach the caller, so entering the drain contract is an explicit act now that there is no privileged @Human push. 727 → 844 lines. The ~400 estimate predated the decision to mirror the CLI verbs one to one; the tool definitions alone are ~340.
Addressing bugs bit in three separate places because a shared broadcast
log forced the engine to guess recipients. The sender now names them, and
the whole class goes with the guess.
`to` is required and never inferred. Gone with the defaulting: the lead
(agents[0]-is-lead, KILD_LEAD, the lead-only guard on stop), the
@human-wakes-lead rule, and the 1:1 bare-send special case — a solo kild
now gets the same answer as any other, because a rule that only applies at
one size is a rule the engine has to remember.
HUMAN is deleted outright. A human-driven harness attaches a handle like
anything else; there is no reserved participant and no privileged push.
kild-router.ts did not survive as a file. Once the choreography went, what
remained was a two-branch loop over state the manager already owns — the
injected Delivery seam existed to unit-test routing decisions, and there
are no decisions left to isolate.
Also removed: system messages (roster changes come from the {kilds}
broadcast, not fabricated log entries), the lifecycle state machine and
its six guards (liveness is registry presence; halt collapsed into stop),
and opener notifications (an agent that wants to tell the opener something
sends it a message).
finalNonSystemPost deliberately survives, moved into memory.ts — its
replacement lands with the fact-based ledger, and removing it first would
delete the ledger's outcome line before anything could write one.
222 pass, 0 fail. 13 tests removed with their subjects and listed in the
review notes; the rest rewritten rather than dropped. New tests pin the
rules that replaced them, including cli.send.test.ts on the split that
matters: the engine never infers a recipient, but the CLI may resolve --to
client-side when a kild has exactly one agent.
Wirasm
force-pushed
the
claude/buzz-block-kild-comparison-jdcub4
branch
from
July 27, 2026 20:41
a7b4e3a to
1777a0d
Compare
The extension was rebuilt against the API as it stood an hour earlier, and the router commit moved four things under it. All seven claimed changes were checked against engine source first; every one held. `kild_send` advertised "omit to to address the kild lead" and sent the field only when non-empty. There is no lead and the engine now rejects an absent `to`, so the tool was documenting a rejection. `to` is required, stripped of `@`, and always sent. `kild_new` posted `kickoff` as a bare string, which is now a 400. It takes an explicit recipient. It also pre-flights that the recipient is one of the agents being spawned — without it the engine creates the kild, rejects the kickoff, and tears the kild back down, which is a confusing way to learn you typed a handle wrong. `kild_show` read `.state`; liveness is now which collection answers, so it queries live then archive and says which. Archived kilds became readable rather than an error on the way past. `system` is gone from the message type and the log rendering. Adds `attachAs` to `kild_new`: a pi session that creates a kild otherwise receives nothing until it attaches separately, since there is no privileged push any more. Two explicit calls in one tool — convenience in the client, not a default in the engine.
Two halves of the same obligation: when intelligence leaves, the mechanism
it was hanging from has to stay.
The engine no longer knows what memory synthesis is. On stop it emits a
kildClosed event carrying only facts it holds — kildId, name, cwd,
worktree, base, transcriptPath, ledgerPath — broadcasts them on the event
stream, and runs whatever hooks.onClose declares. A hook is an agent spec
with a prompt, an argv, or both; there is no registry and no hook name the
engine recognises, so it cannot tell a memory hook from a backup hook.
Facts substitute as {{fact}} rather than ${fact} so shell expansion stays
the author's. The hook is not awaited and every failure is swallowed — a
hook must never hold a stop open or prevent one.
The charter moves out: synthesisPrompt, configuredMemorySynthesis and the
memory.synthesis branch are gone. docs/onclose-hook.md carries the exact
old prompt so migrating is copy-paste rather than git archaeology, and
records that live memory.synthesis configs are no longer read and must
re-point.
The ledger stops guessing. finalNonSystemPost was a tail-grab standing in
for facts the engine already owns — a smoke test caught it writing
"outcome: second message" from a throwaway test post. It is deleted, there
is no outcome line, and a test now forbids one. In its place: whether the
branch landed, commits vs base, files changed, uncommitted count, and
per-agent model and spend, read from kildGitStatus and reviewCommits
rather than reimplemented. A git failure reports "landed: unknown" instead
of inventing a result.
239 pass. Two tests removed with the charter they covered; the rest
rewritten, and 21 added — including collectLedgerFacts against real temp
git repos for the unlanded, merged and non-repo cases.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Reframes kild from a Room primitive to an agent primitive, and carries out the teardown. Draft while the remaining work lands; commits are targeted so they review one at a time.
The model
The engine has one inhabitant type: the agent. Everything else is either mechanism kild owns or intelligence that lives outside it.
kild-0; children fork from a base branch.owned(kild runs the process) orattached(an external harness kild addresses but never spawns). Its role is a persona — invisible to the engine.spawn—into: <kild>(another agent in the same worktree) or a new kild forked from a base.send— directed, peer-to-peer. The sender names the recipient, so "who is this addressed to?" stops being a question the engine can get wrong.Hard authority (spawn/stop/kill, guardrails) stays with the human as the control seat — it cannot be delegated to something running inside what it may need to kill.
Why
kild's own rule is "ship mechanism, never intelligence," and the Room model broke it: the engine encoded an org chart (operator → lead → worker), a privileged
@human, a report-and-idle norm, and a decision protocol parsed out of message prose. The recurring "who is this addressed to?" bug — which bit in three separate places — was the symptom.VISION.mdalready described this model; the implementation drifted.$KILD_HOMEstate dir moved$KILD_HOME/rooms/<id>.json→$KILD_HOME/kilds/<id>.json. An engine with existing archives will not find them after this branch. One-time fix on any machine that has run kild before:No migration code ships for this — it is a single-operator tool and a one-line
mv, and auto-migration is the kind of machinery this branch exists to delete. Recorded here so it is not a silent surprise.a63476dEverything before it is the old API; everything after is the new one.
docs/helm-migration.mdhas the full mapping, a checklist, and the pin/un-pin sequence.Two corrections landed after that guide was first written, both in it now:
collidesWithwas never on the wire (derive it client-side fromgit.changedFiles— that is the correct approach, not a workaround), and the kild-scoped transcript route is documented as doomed, so do not build against it.Commits
collidesWithcorrection + worktree disposal leak recordeda63476d— the atomic renameEngine source: 6,710 → 5,761 lines, with the substrate untouched.
The rename
One commit, zero behavior change, so it reviews as names moving and crosses helm's pin boundary exactly once. It also resolves three collisions that could not be fixed piecemeal:
agentmeant three things — the persona file (kild agent ls), the same data at/api/personas, andlistAgents()— while the running thing had no stable name at all (worker / participant / session). Now persona is the file, agent is the process.rolemeant two —withRole/<role>andKILD_ROLE. Now<persona>wraps personas.sessionmeant two — a running agent, and pi's conversation. Now it is pi's alone.workerwent with them: rank vocabulary implying a lead and an operator above it, plus the job-queue model of an interchangeable executor — neither true of an addressable agent that holds context and spawns peers.postwent too: you post to a board, you send to a person.235 tests pass across 26 files — identical to the pre-rename count, which is the check that matters for a rename. No test was deleted.
Two obligations the audit initially missed
Both surfaced in review, both now in
docs/DEMOLITION.md:hooks.onClosethe engine runs without knowing what it is for.finalNonSystemPostis a tail-grab standing in for facts the engine already owns. A smoke test proved it live, writingoutcome: second messagefrom a throwaway test post.Still to land
The router commit — replacing the router with directed
send, which removesHUMAN, the lead default, and the lifecycle states. Those are renamed but functionally intact today; mixing their removal into the rename would have made the diff unreadable. Thenhooks.onClosebeforerecordMemory's synthesis spawn goes, the fact-based ledger beforefinalNonSystemPostgoes, and the reshape surface fromdocs/api-surface.md.The pi extension is kept and rebuilt as the pi implementation of the attached-harness contract — peer to Claude Code's hook + CLI, neither privileged. It currently references the removed operator capability; it is rebuilt once rather than patched three times.
Planning docs on this branch
DEMOLITION.md(full-tree audit) ·VOCABULARY.md(canonical naming) ·helm-migration.md(client guide) ·api-surface.md(reshape decisions) ·cross-kild-comms.md(agent-to-agent addressing) ·escalation.md(who surfaces a blocked agent) ·worktree-disposal.md(the 116-worktree leak)🤖 Generated with Claude Code
https://claude.ai/code/session_01NGEZwcNKSJZmuGuQhuFmcU