--- id: vouch title: What an owner vouches, what an agent vouches, and what the server vouches status: open crates: [didbot-pds, didbot-lexicon] dependsOn: [ownership] exitCriterion: > A verifier reading a disagreement between the owner's, the agent's and the server's statements about one another has a written rule for which one it believes for which purpose, rather than picking one by convention. --- # vouch [ownership](ownership.md) builds bidirectional ownership — an owner's vouch and an agent's owner claim, checked against each other — and its own exit criterion is a verifier confirming "an agent and its owner claim each other." That is two of three parties. [index](index.md) discovers every server by *"following a server's `/events`"* and, per its Done list, walking `the vouch chain: voucher, repository, vouch, server`. A third statement is already load-bearing there and its own weight is never written down: the server answering, on `ownership`'s words, *"its controlling DID on an unauthenticated status endpoint."* Three statements exist or are proposed. This epic is naming what each one is worth, because the index treats disagreement between them as something to resolve, not something the lexicons currently say how to resolve. ## The three claims **Read the first claim with its correction.** `bot.did.vouch` was an earlier, unbuilt design; no schema for it was ever checked in, and `crates/didbot-lexicon/src/nsid.rs` deleted even its retired NSID constant. The record that exists instead is `bot.did.operator`, and it is **not this claim renamed**: `lexicons/bot/did/operator.json` is explicit that it says who runs a *server*, not who governs what it may do, and proves nothing about delegation. So the owner-vouches-for-an-agent claim below has no record behind it, and the three-way analysis in this file needs rewriting against `bot.did.operator` before it is actionable. The server-and-operator half of it is real and polled — see [handshake](handshake.md) and `crates/didbot-serve/src/ownership_poll.rs`. - **The owner vouches for an agent** (`bot.did.vouch` — **never built, and the name is retired**; see the note under "The three claims" below): *this DID is mine, I am accountable for it.* Signed with the owner's own key, in the owner's own repository. A stranger who trusts the owner's identity can trust this without trusting the server at all — it says nothing about the server the agent happens to live on. - **The agent vouches for its owner** (the still-unbuilt half of [ownership](ownership.md)): *this human is who provisioned me.* Written by the server at provisioning, "never by the agent about itself" — `ownership.md` is explicit that this is not the agent asserting anything; it is the server asserting it on the agent's behalf, inside the agent's own repository. Its trust is bounded by the server: an operator who controls provisioning controls what every agent it mints appears to claim. - **The server vouches for itself, and implicitly for its own agents** (`ownership.md`'s unauthenticated status endpoint, plus [index](index.md)'s practice of trusting a server's own account listing as the enumeration of its agents): *this DID controls me, and these are the agents I minted.* `ownership.md`'s own "Enumeration is derived, and is a lower bound" item already says this is not fully trusted — a compromised server can hide an agent, though containment stops it minting one outside its zone. What is not written down is what a *disagreement* means, only what an omission means. ## What each is worth to a stranger, and where they can disagree - [ ] **Owner vouches, agent silent.** The owner's claim exists but the agent carries no owner claim of its own — either because bidirectional ownership is not built yet, or because provisioning skipped it. `ownership.md` says a bare vouch, absent the agent's side, "is a claim anybody may make about any account, and the account cannot disagree." Say plainly what a verifier does with this case today, since it is the *current* state of every existing vouch and not a hypothetical. - [ ] **Owner and agent agree, server disagrees about which agents exist.** The pair vouches for each other; the server's own listing does not include the agent, or includes an agent neither side named. Ownership's lower-bound framing covers omission — a server can hide an agent — but not fabrication: nothing in these lexicons stops a server from *listing* an agent it never truthfully provisioned, since the server writes both the listing and the agent-side claim. - [ ] **Server claims a controlling DID the owner does not vouch for.** The unauthenticated status endpoint is the server's own word about who controls it; `ownership.md`'s "three statements, none written into somebody else's repository" item requires the owner to vouch for the *server* from their own policy dashboard, independently. A server claiming an owner that owner never vouched for is the server lying about itself, and the fix is the same as the agent case above: the claim that matters is the one written in a repository the claimant does not control. - [ ] **Expiry and revocation land on different schedules.** `ownership.md`'s open item says a reader that is not polling learns nothing about a revocation, and DNS is explicitly not the mechanism — a deleted agent stays cached for a day. A verifier holding a cached "agrees" answer across an owner's revocation is holding a claim that has already stopped being true; say what a stale-but-cached agreement is worth compared to a fresh disagreement. ## What a verifier does when they disagree - [ ] **Ownership (human accountability) is decided by the owner-and-agent pair, never by the server alone.** The server's status endpoint proves the server *controls itself*, which is a different claim from *who owns the agents it hosts* — conflating the two lets a server vouch for its own agents' ownership by fiat, which is exactly what the bidirectional check in [ownership](ownership.md) exists to prevent. - [ ] **Existence (which agents this server hosts) is decided by the server's own listing, bounded to a lower bound as `ownership.md` already states.** A verifier cannot use a disagreement here to prove an agent exists that the server does not list — only to prove the server is hiding one it does list evidence for elsewhere (an old vouch, a cached DID document). - [ ] **Say which of the two, ownership or existence, [index](index.md) is actually answering when it walks the vouch chain**, since its own description elides the difference: "discovers every vouched server" is an existence question about servers, layered under an ownership question about agents, and a reader of that epic should not have to infer which one is load-bearing for a given query. ## Done Nothing closed yet.