Mesh-LLM capsules plugin
The open-source capsules plugin for Mesh-LLM (release v0.1.4) seals a signed record of every exchange a node serves or asks for, lets two nodes swap those records, and, for a pair of requests a client marked as twins, can ask a third node to referee answers that differ.
1What it is
capsules is a Mesh-LLM plugin that keeps, on each node's own disk, a signed and hash-chained record of every exchange that node serves or asks for, in the Agent Action Capsule format.
When the operators turn it on, the two sides of an exchange send each other their own sealed records, and each side checks the other's against the peer's key: one its host announced, bound to its node key, or one the operator configured.
When a client marks two requests as one pair and the two answers differ, a node can ask a third node to re-answer the request and sign a verdict on the pair.
2Design choices
x-mesh-twin-bracket value on two requests.docs/plugins/openai-exchange-lifecycle.md, “Client-marked pairs”; capsules docs/TWIN-REFEREE-SELECTION.md §4)openai-exchange-lifecycle.md)CAPSULES_PEER_KEYS disagree for a peer, nothing from that peer verifies.crates/evidence-plugin/src/peer_keys.rs)docs/TWIN-REFEREE-SELECTION.md §2, §3, §5)docs/TWIN-REFEREE-SELECTION.md §1)docs/SHARING-POLICY.md; CHANGELOG.md 0.1.3)3What it shows / what it does not
Shows
- That the holder of a given plugin key signed a record of one exchange, and that the record's bytes are unchanged (its
capsule_idrecomputes). - Where a host lists a peer's plugin key (mesh-llm PR 2299): that the peer's node key vouched for that key. capsules v0.1.4 reads such keys; it does not yet announce its own.
- With record push on at both ends: each side holds the other's signed record of the same exchange.
- For a pushed bundle: inclusion of the record under a checkpoint the sender signed.
- For a refereed pair: a signed ruling on one pair of answers, which twin the referee's re-answer agrees with, and the word position where they start to differ (
divergence_index).
Does not show
- Who holds a key in the real world. The node key's binding says nothing about whether the node served honestly (PR 2299).
- That a model claim is true.
model_name_digestis a hash of the model's name, not of its weights. - Anything about a pair no client marked: those read “Not adjudicated” and nothing is called.
- A node's future answers. A verdict is a ruling on one pair; nothing counts against a twin without one.
- That the referee's prompt is the twins' prompt: the verdict records it as the requester's word (
referee_prompt: requester_attested). - In v0.1.4, the plugin announcing its own key: it reads peers' announced keys; announcing its own “follows once a mesh-llm plugin release carries the request” (INSTALL.md).
- A live run: host-announced keys were exercised only against a test build of the host, and a referee verdict on live hosts is covered by tests only (CHANGELOG 0.1.4).
4Example
A verdict signed by a reference referee, kept as a test fixture; the plugin's test checks that its signature verifies under referee_key_id. It rules on a twin pair in which node aaaa… served half A and node bbbb… served half B.
{
…
"referee_key_id": "6a9a93a3af20ca17d85764e3206fd1d0417ea943f53f07157792299ba9b6f033",
"verdict_capsule": {
…
"capsule_id": "1bd4fa92a5ff02c278b3c79e4e0398ede6c62212483c5a9466176bfc45408f62",
"action_id": "adjudicate/1bb92507-473a-49b7-96a0-a6752fb42308",
"action_type": "decide",
…
"provenance": "referee",
"model_attestation": {
"compute_attestation": {
"epistemic_type": "adjudication",
"adjudication": {
"schema": "capsule-emit-mesh/adjudication/v1",
"source": "twin_comparison",
"capture_method": "deterministic_replay",
"verdict": "contradicted:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"status": "CONTRADICTED",
"divergence_index": 3,
"margin": "0",
"margin_tau": "0.9",
"prefix_digest": "0ec7db901e57f96f8d195aa69bbdbd858eb13d125021a24c90972a5ce35d587b",
"twin_owner_distinct": true,
"weights_digest": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd",
"half_a_capsule_id": "7dc9427b6df5ff222617fb721f25d3c54aebe32682329bb7075902336437fb06",
"half_b_capsule_id": "b80db10999779aa17c8fcf7006a57aeaecbc81f5e9de3ecea33e9365c2bfd4d9",
"referee_capsule_id": "5d6b949bc8a8f20cd0dc4ba25642b12d4906eeccf5763adbe27f00841356cd44",
…
"referee_node_id": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
"half_a_node_id": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"half_b_node_id": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"twins_request_digest": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
"referee_prompt": "requester_attested",
"referee_answer_digest": "0242bc9526adbb014565b8175ff134e2ba8731f4a13cab2d1b4d8aff8727586e",
"twin_bracket_id": "bracket-1"
}
}
},
"assurance": {
"attestation_mode": "self_attested",
…
},
…
"chain": {
"parent_capsule_id": "7dc9427b6df5ff222617fb721f25d3c54aebe32682329bb7075902336437fb06",
"relation": "adjudicates"
},
…
"key_id": "6a9a93a3af20ca17d85764e3206fd1d0417ea943f53f07157792299ba9b6f033"
}
}
| Field | Type | Meaning |
|---|---|---|
| referee_key_id | hex | The referee's Ed25519 public key; the fixture's signature verifies under it. |
| capsule_id | hex | SHA-256 of the record's canonical (JCS) bytes; changing any committed field changes it. |
| action_type | string | decide: this record is a ruling, not a served exchange. |
| provenance | string | referee: the node that wrote it was asked as referee. |
| source / capture_method | string | A comparison of twins, decided by the referee re-answering the request. |
| verdict | string | A referee signs contradicted: + the node id its re-answer did not agree with, inconclusive, or not_comparable. (corroborated applies only when the answers agree, and then no referee is called.) |
| status | string | Paired with the verdict: SATISFIED, CONTRADICTED or UNKNOWN. |
| divergence_index | integer | The word position at which the two answers start to differ. |
| prefix_digest | hex | Digest of the words the two answers share before they differ. |
| margin / margin_tau | string | Read and shown by the v0.1.4 web UI; written by no v0.1.4 Rust code. unverified what they mean. |
| twin_owner_distinct | bool | The twins have different owners; a same-owner pair gets no verdict. |
| weights_digest | hex | The weights both halves name; set only when both name the same. |
| half_a/b_capsule_id | hex | The two twins' served records (A's and B's), pushed to the requesting node and held there. |
| referee_capsule_id | hex | The referee's own record of its re-answer. |
| half_a/b_node_id, referee_node_id | hex | The node ids of the two twins and the referee. |
| twins_request_digest | hex | Digest of the request both twins answered. |
| referee_prompt | string | requester_attested: the prompt is the requester's word, not checked by the referee. The requesting node checks a supplied request against both records' request_digest. |
| referee_answer_digest | hex | Digest of the referee's own answer. |
| twin_bracket_id | string | The value the client sent in x-mesh-twin-bracket. |
| attestation_mode | string | self_attested: the signer's own key, with no outside vouching. |
| chain | object | Links the verdict to half A's record with the relation adjudicates. |
| key_id | hex | The plugin's own key that signed this record (here referee_key_id); on disk keys/node-key.pub.pem, not mesh-llm's node key. |
This fixture's spec_version (trimmed above) names an earlier revision of the capsule Internet-Draft; the v0.1.4 producer seals draft-mih-scitt-agent-action-capsule-05.
Source: Mesh-LLM/capsules:crates/evidence-plugin/tests/fixtures/referee-verdict.json @ b4e24453f572b2d9fe8f2cefbd0f35a5eb54b0ad (tag v0.1.4)
5Specs
- Internet-Draft draft-mih-scitt-agent-action-capsule-05 — the record format each node seals.
- Internet-Draft draft-mih-scitt-checkpointed-local-log-02 — the node's checkpointed Merkle log; a pushed bundle carries a checkpoint and an inclusion proof.
- Internet-Draft draft-mih-agent-evidence-layer-00 — why the plugin coarsens committed latency (a timing side channel).
- RFC RFC 9052 — COSE: the
COSE_Sign1signature on each record. - RFC RFC 8785 — JSON Canonicalization Scheme: the bytes every digest and
capsule_idcovers. - RFC RFC 9943 — SCITT architecture: the witness an operator may name for checkpoints (none by default).
- RFC RFC 9942 — COSE Receipts: what a named witness returns.
- Code Mesh-LLM/capsules v0.1.4 — the plugin, its Evidence page, vectors and docs.
- Code Mesh-LLM/mesh-llm#2299 — plugin keys bound to the node key, carried in gossip (merged).
- Code Mesh-LLM/mesh-llm#2300 — the
twin_bracketcapability; the header stripped before forwarding (merged).