---
name: sever-trust-plane
description: Verifiable trust plane for agent task settlement. Delegate and revoke capabilities, attest task outputs with serialization-invariant content addresses, verify the full chain, and release XRPL testnet escrow on ALLOW.
version: "1.0"
author: Maura Clark (Kessai / UOR Foundation)
---

# Sever — Verifiable Trust Plane for Agent Task Settlement

**Skill name:** sever-trust-plane
**Author:** Maura Clark (Kessai / UOR Foundation)
**Base URL:** `https://sever-trust.onrender.com` (this file is served live from the service; all endpoint URLs are templated to the real host)
**Auth:** None. All endpoints are open for the sandbox. The service manages its own demo keypairs and XRPL testnet wallet — you never need keys.
**Version:** 1.0

---

## What this skill does

**Sever stops an autonomous agent from being paid unless it can prove two things: it was authorized to do the task, and the verified output is exactly the one being paid for.**

Everything below is how it proves that. In one question: when an agent finishes a task, how do you prove the right agent, with the right permission, produced the right output — before money moves?

**Verified:** two stock OpenClaw agents completed this full loop blind — given only this skill file's URL, no other context — on Maritime (a NANDA-affiliated agent host). Both settlements are real and checkable on the XRPL testnet ledger. Transcripts are committed in the repo.

It gives any agent four verbs:

1. **DELEGATE** — give an agent a capability, or narrow an existing one. A child capability can only be smaller than its parent, never bigger.
2. **REVOKE** — cancel a capability. Everything delegated under it is canceled too.
3. **ATTEST** — create a signed, timestamped record that links a finished task to its output, using a content address that does not change when the same data is re-encoded.
4. **VERIFY** — run all trust checks (signatures, capability chain, revocation, timestamps, output integrity). If all pass, release the XRPL testnet escrow.

**NANDA DataFacts alignment:** DataFacts asks whether an agent's data is *current, authentic, and authorized* — and Sever's verification answers exactly those three questions. Authorized is the capability chain. Authentic is the content-addressed output. Current is the signed timestamp in the append-only log. The three DataFacts properties are not a separate feature here; they are the three things `/verify` checks. `GET /datafacts/{artifact_addr}` returns them in DataFacts shape.

---

## Quick start (60 seconds, no setup)

```
POST /demo/bootstrap
```

Returns a ready-made scenario: a root delegator, a worker agent, an attenuated capability chain, a funded XRPL testnet escrow, and a sample artifact. Use the IDs it returns in the recipes below. Every recipe works with only these IDs — no keys, no signup.

Response example:
```json
{
  "root_did": "did:key:z6MkrRoot...",
  "worker_did": "did:key:z6MkrWork...",
  "leaf_link_id": "sha256:ab12...",
  "escrow_id": "esc_7f3a",
  "task_spec_hash": "sha256:9c4e...",
  "sample_artifact_url": "/demo/artifact",
  "escrow_state": "assigned",
  "escrow_create_tx": "F24F1AC1... (XRPL EscrowCreate hash, testnet mode)",
  "escrow_create_explorer_url": "https://testnet.xrpl.org/transactions/F24F1AC1..."
}
```

---

## Recipes (follow steps exactly)

### Recipe 1 — Delegate authority to an agent

1. `POST /delegate` with:
```json
{
  "issuer_did": "<root_did from bootstrap>",
  "audience_did": "<worker_did>",
  "capabilities": [{ "resource": "task:translate/*", "action": "execute" }],
  "expires_at": "2026-07-12T00:00:00Z",
  "parent_link_id": null
}
```
2. Read `link_id` from the response. That is the capability.
3. To narrow it (attenuate), call `POST /delegate` again with `parent_link_id` set to that `link_id` and a **subset** of capabilities. A superset returns HTTP 422 `ATTENUATION_VIOLATION` — this is by design.
4. Confirm with `GET /chain/{link_id}` — you'll see the full chain from root to leaf.

### Recipe 2 — Attest a completed task

1. Obtain the artifact as structured JSON (demo: `GET /demo/artifact` returns a JSON object).
2. `POST /attest` with:
```json
{
  "capability_link_id": "<leaf_link_id>",
  "task_spec_hash": "<task_spec_hash from bootstrap>",
  "artifact": { "rows": [[1, 2], [3, 4]], "unit": "kg" }
}
```
   Note: `artifact` is the structured content itself (any JSON value), NOT base64 bytes.
3. The service computes the artifact's structural UOR address (two byte-different
   encodings of the same content get the same address), signs the attestation as the
   capability holder, timestamps it, and appends it to the transparency log.
4. Read `attestation_id` from the response. Save it — Recipe 3 needs it.

### Recipe 3 — Verify and settle

1. `POST /verify` with:
```json
{ "attestation_id": "<attestation_id>", "escrow_id": "<escrow_id>" }
```
2. Read `decision` from the response:
   - `"ALLOW"` → the response includes `xrpl_tx_hash`; the testnet escrow was released. Done. In testnet mode it also carries `explorer_url` (the EscrowFinish receipt, verifiable at `https://testnet.xrpl.org/transactions/<hash>`) and `escrow_create_tx` (the matching EscrowCreate). Mock-mode hashes are always `MOCK-` prefixed — never mistake one for a ledger receipt.
   - `"REJECT"` → the response includes `failure.code` and the ordered `checks[]` list showing exactly which check failed and why.
3. Verification is authoritative; settlement is a receipt path. If the XRPL ledger is unreachable, `decision` is still `"ALLOW"` but the response carries `settlement: {"status": "XRPL_UNAVAILABLE", ...}` and **no** transaction hash — the service never fabricates a receipt.
4. The verdict is itself signed and content-addressed (`verdict_id`) — other skills (e.g., a notary) can countersign it.

### Recipe 4 — Revoke, and watch settlement die (the Sever demo)

1. `POST /revoke` with:
```json
{ "revoked_link_id": "<leaf_link_id>", "revoker_did": "<root_did>" }
```
2. Repeat Recipe 3 with the same attestation.
3. Expect `decision: "REJECT"` with `failure.code: "REVOKED_BEFORE_SETTLEMENT"` (or `REVOKED_BEFORE_ISSUANCE` if the attestation was created after the revocation timestamp). One revocation call severs the entire downstream chain — no funds move under severed authority.

### Recipe 5 — Check DataFacts for an artifact

1. `GET /datafacts/{artifact_addr}` (use the `artifact_addr` from any attestation response).
2. Returns machine-readable trust facts:
```json
{
  "artifact_addr": "uor:...",
  "integrity": { "scheme": "UOR-ADDR", "serialization_invariant": true },
  "last_attested": "2026-07-09T18:22:04Z",
  "freshness": { "log_index": 41, "anchored_xrpl_tx": "ABC123..." },
  "authorization": { "required_capability": "task:translate/*", "chain_status": "active | revoked" }
}
```

---

## Endpoint reference

| Method | Path | Purpose | Key fields |
|---|---|---|---|
| GET | `/skill.md` | This file, served live (URLs templated from host) | — |
| POST | `/demo/bootstrap` | Create a full demo scenario | — |
| GET | `/demo/artifact` | Sample artifact (JSON object) | — |
| POST | `/delegate` | Issue or attenuate a capability | `issuer_did, audience_did, capabilities, parent_link_id` |
| GET | `/chain/{link_id}` | Resolve chain root→leaf | — |
| POST | `/revoke` | Revoke a link (and its subtree) | `revoked_link_id, revoker_did` |
| GET | `/revocations/{link_id}` | Revocation status | — |
| POST | `/attest` | Create signed, timestamped attestation | `capability_link_id, task_spec_hash, artifact` (JSON value) |
| GET | `/attestations/{id}` | Fetch attestation + log proof | — |
| POST | `/verify` | Full verification; settles escrow on ALLOW | `attestation_id, escrow_id` |
| GET | `/datafacts/{artifact_addr}` | NANDA DataFacts-style trust facts | — |
| GET | `/log/head` | Transparency log head | — |

All errors return `{ "failure": { "code": "...", "detail": "..." } }`. Failure codes: `MALFORMED_ATTESTATION, BAD_SIGNATURE, ID_MISMATCH, TIMESTAMP_INVALID, CHAIN_UNRESOLVABLE, LINK_BAD_SIGNATURE, CHAIN_DISCONTINUITY, ATTENUATION_VIOLATION, WRONG_HOLDER, UNTRUSTED_ROOT, CAPABILITY_EXPIRED, REVOKED_BEFORE_ISSUANCE, REVOKED_BEFORE_SETTLEMENT, TASK_MISMATCH, SCOPE_INSUFFICIENT, ARTIFACT_MISMATCH, LOG_INCONSISTENT`.

---

## Judge test (4 tasks, runnable by any agent from this file alone)

1. **Delegate:** Bootstrap, then create an attenuated child capability under the leaf. Confirm `GET /chain` shows 3 links. *(Bonus check: attempt a widened delegation and confirm HTTP 422.)*
2. **Attest:** Attest the sample artifact under the leaf capability. Confirm you receive an `attestation_id` and a `log.index`.
3. **Verify (ALLOW):** Verify the attestation against the bootstrap escrow. Confirm `decision: "ALLOW"` and a `xrpl_tx_hash`.
4. **Sever (REJECT):** Revoke the mid-chain link, re-verify the same attestation, confirm `decision: "REJECT"` with a `REVOKED_*` failure code.

Passing all four demonstrates the full loop: authority granted → work proven → payment released → authority severed → payment blocked.

---

## Production posture

This service will stay live in Nanda Town after the hackathon. Three parts are
simplified for the sandbox, listed here clearly:

- **Demo keys.** The service holds demo keypairs and signs attestations on the
  server, so any agent can complete the loop with no key setup. In production
  (per the VTEAI draft standard this service implements), workers sign their own
  attestations and the service only verifies. The verifier already supports this;
  the `/attest` route gains a signed-payload mode after the hackathon.
- **Settlement is XRPL testnet** — the right choice for a sandbox. The escrow
  mechanics (PREIMAGE-SHA-256 crypto-conditions, released only by the verifier)
  are identical on mainnet; only the ledger differs.
- **State persistence and rate limiting** are the first additions after the
  hackathon, before any use where revocations must survive a restart.

The cryptographic core — canonical structural addressing, Ed25519 did:key identity,
the ordered verification checks, signed content-addressed verdicts, and the
hash-chained transparency log — is production-grade as deployed today.

## Why this is different

- **Chain-agnostic verification, pluggable settlement.** Delegation, revocation,
  attestation, and verification never touch a ledger. They are Ed25519 signatures
  over canonical data structures. The signed verdict is the product. Settlement
  is a pluggable backend behind a standard interface (VTEAI, draft ERC). This
  deployment settles on XRPL testnet using crypto-conditions: the verifier's
  ALLOW reveals the secret that unlocks the escrow. No smart contracts needed.
  A sibling implementation (AgentLevy) runs the same settlement state machine on
  EVM. Two ledgers, two settlement models, one trust layer.

- **Serialization-invariant integrity:** the output is addressed by its structure, not its bytes. Re-encode the same content (different byte layout, same structure) and it still verifies. A plain checksum changes when the bytes change; a structural address does not.
- **Capability-level revocation, bound to outputs and money:** capability skills typically govern authorization — who may act (for example, key-chain revocation in Agent Keyring). Sever adds two things on top: it binds live authority to an **attested output** (content-addressed, so re-encoding does not change the address) and to **settlement** (escrow releases only on a signed ALLOW verdict). One revoke call cancels a whole delegation subtree, and unsettled money stops moving.
- **Verifiable time, not claimed time:** attestations are hash-chained in an append-only log. The log head is anchored to XRPL testnet, so the age of any record can be proven against ledger close times.
- **Composable verdicts:** every verdict is signed and content-addressed. Other Nanda Town skills (notaries, brokers, reputation systems) can consume or countersign it.

## Compose with this skill

Verdicts from `/verify` are signed and content-addressed. Notary, broker, and
reputation skills can countersign or consume them. The `/hasher/address` endpoint gives
any skill serialization-invariant content addressing.

Building on this skill, or want your skill's outputs attested? Contact me on
Discord: **@sheilahthecryptoshillah**
(<https://discord.com/users/444028370552881152>) — also in the NandaHack server.
