--- id: subagents title: What a distinct subagent identity would buy, and what a harness lets you enforce status: open crates: [didbot-pds, didbot-hook] dependsOn: [credentials, node] exitCriterion: > A written decision on whether a subagent gets its own DID, backed by a statement of which part of that decision the harness enforces and which part it only reports. --- # subagents [credentials](credentials.md) states the current rule twice — once in its own list, once in [node](node.md)'s boundaries section: *the custody boundary is the session; subagent identity is attribution.* A subagent's `agent_id` and `agent_type` are stamped by the hook onto the tool calls it makes, they land on records as provenance, and none of it grants a subagent anything a credential can enforce. This epic is where that gets revisited, not where it gets reversed by default — the honest answer may still be "attribution is correct and a distinct DID is not worth what it costs." ## What a distinct DID would buy A subagent with its own `did:web` would let a write carry cryptographic proof of which subagent made it, rather than a claim the parent session's hook attached. It would let [write-policy](write-policy.md) grant different collections to different subagent types by credential rather than by convention, and it would let a subagent be individually revoked without ending the session that spawned it. It would also let a compromised subagent be told apart from a compromised session after the fact, which attribution alone does not: a forged `agent_id` and a genuine one look identical once they are both just a field on a record the session's own key signed. ## What it would cost [agent-accounts](agent-accounts.md) makes provisioning a DNS write, a keypair, two hostnames that must both resolve, and a repository, all before an account exists. A subagent's lifetime is a fraction of a session's — `SubagentStop` fires the moment its one task ends — so the same cost that [account-types](account-types.md) already flags for per-run accounts applies here at a smaller grain still: minting a DID, a hostname and a DNS write for something that lives for one tool call's worth of work spends real infrastructure on an identity nothing will resolve twice. Provisioning latency also sits on the hot path of every subagent spawn, which [node](node.md) already worries about at the granularity of one hook firing per tool call; a DID per subagent multiplies that by however many subagents a session spawns. - [ ] **Decide whether the exit criterion is per-subagent-type rather than per-subagent.** A DID per invocation is the expensive version above; a DID per *type*, minted once and reused across every `Explore` subagent a session spawns, is a different and cheaper claim — closer to what [write-policy](write-policy.md) actually needs, since policy is naturally keyed on type already. - [ ] **Say what a subagent DID would be a credential for**, if it does not also carry a write credential of its own. An identity a session's own key still signs on behalf of is not the enforcement gain described above; it is attribution with a fancier label. ## What a harness actually lets you enforce, versus what it merely reports This is the honest part, and it is not a Claude-Code-specific caveat — it is the crux of the whole question. `docs/hook-flow.md` is explicit about the ceiling: a `PreToolUse` hook can block a call, rewrite its arguments, and inject context, but it cannot synthesize a call the model did not make, and `agent_id`/`agent_type` arrive on the hook payload as the harness's own report of what is running, not as something the harness cryptographically attests about the subagent process itself. - [ ] **Say what `agent_id` actually authenticates.** It identifies which subagent invocation the harness believes is calling out, sourced from the harness's own bookkeeping of what it spawned. Nothing here proves the subagent process is isolated from its parent's memory, its parent's file descriptors, or another subagent's — the harness reports a boundary; it does not necessarily enforce one at the OS level. [credentials](credentials.md)'s "say what is in the trusted set, and check it" item is the general version of this; here it is specific to what a subagent claim is worth. - [ ] **A subagent cannot be denied a capability the session itself holds**, on any harness examined so far, because a subagent runs inside the same process tree and the same filesystem access as its parent. A credential scoped to a subagent restricts what it is *handed*, not what it could reach if it chose to ignore the scoping and act as the session directly. - [ ] **This is the concrete instance of [harnesses](harnesses.md)'s general question**, narrowed to one guarantee: does *any* harness let a subagent's identity be enforced rather than merely reported, and if none does today, say that plainly rather than let a distinct DID imply a stronger boundary than the harness backs it with. ## Done Nothing closed yet.