@agenttrust-sdk/mcp 0.2.5 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/embedded-docs/architecture.mdx +174 -0
- package/dist/embedded-docs/getting-started/quickstart.mdx +79 -56
- package/dist/embedded-docs/index.mdx +54 -37
- package/dist/embedded-docs/integration-guides/capability-namespaces.mdx +135 -8
- package/dist/embedded-docs/integration-guides/custom-attestor.mdx +169 -8
- package/dist/embedded-docs/integration-guides/dexter-adapter.mdx +76 -0
- package/dist/embedded-docs/integration-guides/facilitator-adapters.mdx +85 -41
- package/dist/embedded-docs/integration-guides/pay-sh-adapter.mdx +90 -54
- package/dist/embedded-docs/integration-guides/x402-facilitator.mdx +55 -24
- package/dist/embedded-docs/mcp/hosted-endpoint.mdx +197 -0
- package/dist/embedded-docs/mcp/index.mdx +108 -0
- package/dist/embedded-docs/mcp/install.mdx +183 -0
- package/dist/embedded-docs/mcp/prompts.mdx +90 -0
- package/dist/embedded-docs/mcp/resources.mdx +115 -0
- package/dist/embedded-docs/mcp/tools.mdx +156 -0
- package/dist/embedded-docs/programs/policy-vault/composer.mdx +117 -0
- package/dist/embedded-docs/programs/policy-vault/counterparty-tier-policy.mdx +81 -9
- package/dist/embedded-docs/programs/policy-vault/index.mdx +77 -47
- package/dist/embedded-docs/programs/policy-vault/kill-switch-policy.mdx +65 -8
- package/dist/embedded-docs/programs/policy-vault/require-validation-policy.mdx +76 -8
- package/dist/embedded-docs/programs/policy-vault/spending-policy.mdx +83 -8
- package/dist/embedded-docs/programs/policy-vault/velocity-policy.mdx +85 -8
- package/dist/embedded-docs/programs/trustgate.mdx +112 -30
- package/dist/embedded-docs/programs/validation-registry.mdx +139 -32
- package/dist/embedded-docs/reference/byte-offset-reference.mdx +102 -13
- package/dist/embedded-docs/reference/capability-namespaces.mdx +56 -0
- package/dist/embedded-docs/reference/changelog.mdx +230 -13
- package/dist/embedded-docs/reference/deny-reason-codes.mdx +86 -0
- package/dist/embedded-docs/reference/devnet-program-ids.mdx +50 -8
- package/dist/embedded-docs/reference/discriminator-constants.mdx +104 -10
- package/dist/embedded-docs/reference/mainnet-program-ids.mdx +89 -5
- package/dist/embedded-docs/reference/quantu-agent-registry.mdx +104 -9
- package/dist/embedded-docs/sdk/exports-reference.mdx +239 -0
- package/dist/embedded-docs/sdk/gate-payment.mdx +99 -14
- package/dist/embedded-docs/sdk/index.mdx +141 -40
- package/dist/embedded-docs/sdk/mount-trustgate.mdx +178 -8
- package/dist/embedded-docs/verification/adversarial-harness.mdx +88 -0
- package/dist/embedded-docs/verification/atomic-tx-invariant.mdx +141 -0
- package/dist/embedded-docs/verification/chained-validation.mdx +87 -0
- package/dist/embedded-docs/verification/devnet-smoke.mdx +85 -0
- package/dist/embedded-docs/verification/index.mdx +31 -0
- package/dist/embedded-docs/verification/kani-proofs.mdx +144 -0
- package/dist/embedded-docs/verification/live-evidence.mdx +180 -0
- package/dist/tools/read/get-quantu-reputation.d.ts +50 -11
- package/dist/tools/read/get-quantu-reputation.js +75 -26
- package/dist/tools/read/get-quantu-reputation.js.map +1 -1
- package/dist/tools/write/emit-feedback.d.ts +6 -0
- package/dist/tools/write/emit-feedback.js +12 -1
- package/dist/tools/write/emit-feedback.js.map +1 -1
- package/package.json +16 -15
- package/scripts/install-claude-desktop.sh +0 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Chained validation
|
|
3
|
+
description: The four-signature RequireValidation → respond → Allow trace that proves the third ERC-8004 leg actually closes the loop on Solana devnet.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Four signatures prove the third ERC-8004 leg closes the loop end to end. Subject = Quantu tier-3 agent the Pay.sh smoke also used; capability = `usdc-payment-policy.v1`; attestor identity reused from `examples/attestor-demo/attestor-keypair.json` (Phase D). Captured 2026-05-06.
|
|
7
|
+
|
|
8
|
+
Source script: [`examples/attestor-demo/scripts/devnet-chained-validation.ts`](https://github.com/agenttrust-labs/agenttrust/blob/main/examples/attestor-demo/scripts/devnet-chained-validation.ts). Trace JSON: [`examples/attestor-demo/devnet-chained-validation.json`](https://github.com/agenttrust-labs/agenttrust/blob/main/examples/attestor-demo/devnet-chained-validation.json).
|
|
9
|
+
|
|
10
|
+
## The four signatures
|
|
11
|
+
|
|
12
|
+
| Step | Decision | Tx |
|
|
13
|
+
|---:|---|---|
|
|
14
|
+
| 1 | `gate_payment` (no attestation account) → `RequireValidation` | [`3oKW7QugBLJ7kH2QbLLWEuEn3MyNmLWCj3XovCSdDQNmq5HriwNKvPMUR9TQByZPBAPbvprDfdeYDZvh7ofntRRh`](https://explorer.solana.com/tx/3oKW7QugBLJ7kH2QbLLWEuEn3MyNmLWCj3XovCSdDQNmq5HriwNKvPMUR9TQByZPBAPbvprDfdeYDZvh7ofntRRh?cluster=devnet) |
|
|
15
|
+
| 2 | `request_validation` opens the request | [`2KbXYCF67D2f2fKHk5yTzrkFBr1mV47Q3Yb1veH5e3PX4PuLa66suodAUc7uTBnr6Y44NGV1TfHHMtAZiFSnbbRF`](https://explorer.solana.com/tx/2KbXYCF67D2f2fKHk5yTzrkFBr1mV47Q3Yb1veH5e3PX4PuLa66suodAUc7uTBnr6Y44NGV1TfHHMtAZiFSnbbRF?cluster=devnet) |
|
|
16
|
+
| 3 | `respond_to_validation` (creates `ValidationAttestation` PDA `8YKq…xt2q`) | [`67CzMS9GEtUBesNznKpT2UWqvjEBzhgZd7AVkhXKQ5SoqRoBotcaYf1sTF8sHxj55TNT9k847nj7FQdrwAqKussp`](https://explorer.solana.com/tx/67CzMS9GEtUBesNznKpT2UWqvjEBzhgZd7AVkhXKQ5SoqRoBotcaYf1sTF8sHxj55TNT9k847nj7FQdrwAqKussp?cluster=devnet) |
|
|
17
|
+
| 4 | `gate_payment` (with attestation) → `Allow` | [`dEXkCEeSn8uiVAa14u7EusdFufSuUQttmcTdLHMSq5J3VSARM4KMRCfwpRSkVmYBc1yRQuyvPMCebifCf1dmrmC`](https://explorer.solana.com/tx/dEXkCEeSn8uiVAa14u7EusdFufSuUQttmcTdLHMSq5J3VSARM4KMRCfwpRSkVmYBc1yRQuyvPMCebifCf1dmrmC?cluster=devnet) |
|
|
18
|
+
|
|
19
|
+
## On-chain artefacts
|
|
20
|
+
|
|
21
|
+
| Artefact | Address |
|
|
22
|
+
|---|---|
|
|
23
|
+
| Subject `agent_account` (Quantu tier-3 demo agent) | [`5PfaofvEUf3adtJwMho7zzbfvgxwxbvp2V5moqhtLK8y`](https://explorer.solana.com/address/5PfaofvEUf3adtJwMho7zzbfvgxwxbvp2V5moqhtLK8y?cluster=devnet) |
|
|
24
|
+
| `CapabilityNamespace` for `usdc-payment-policy.v1` | [`34gonn86FjxzXZMGd43RSvQVyH1r6PrGV9xnHXjjkEwR`](https://explorer.solana.com/address/34gonn86FjxzXZMGd43RSvQVyH1r6PrGV9xnHXjjkEwR?cluster=devnet) |
|
|
25
|
+
| Attestor's `AttestorProfile` | [`GTzWJzV5htNi1Ntqwq2e2ydu9h4rArnKQwzv2sJjC9zP`](https://explorer.solana.com/address/GTzWJzV5htNi1Ntqwq2e2ydu9h4rArnKQwzv2sJjC9zP?cluster=devnet) |
|
|
26
|
+
| `ValidationRequest` (step 2's output) | [`GnbrSzWsDw1rehCrFJ4ckiM9JJJeAHdjfNDt7QQy7vhV`](https://explorer.solana.com/address/GnbrSzWsDw1rehCrFJ4ckiM9JJJeAHdjfNDt7QQy7vhV?cluster=devnet) |
|
|
27
|
+
| `ValidationAttestation` (step 3's output — the headline read target) | [`C6Yr7oKcZ6sDVibR35SWbFnGCXyfQjLeRCiPbjxYq6vY`](https://explorer.solana.com/address/C6Yr7oKcZ6sDVibR35SWbFnGCXyfQjLeRCiPbjxYq6vY?cluster=devnet) |
|
|
28
|
+
|
|
29
|
+
The `ValidationAttestation` PDA is what PolicyVault's `RequireValidation` policy reads at fixed byte offsets via [`policy-vault/src/ext/validation_registry.rs`](https://github.com/agenttrust-labs/agenttrust/blob/main/programs/policy-vault/src/ext/validation_registry.rs). After step 3 creates this PDA for `(subject, capability, attestor) = (5PfaofvE…, sha256(usdc-payment-policy.v1), GTzWJzV5…)`, a subsequent `gate_payment` call that passes this attestation account through the `validation_attestation` slot turns a `RequireValidation` decision into `Allow`.
|
|
30
|
+
|
|
31
|
+
## What the trace proves
|
|
32
|
+
|
|
33
|
+
1. **The third ERC-8004 leg is real on Solana.** Identity (Quantu) + Reputation (Quantu) + Validation (AgentTrust) all wire together.
|
|
34
|
+
2. **The complete `RequireValidation` round-trip works.** PolicyVault emits `capabilityHash` → attestor responds → policy now allows. Each step is a separate on-chain tx; AgentTrust composes the PDAs without trusting any off-chain coordination.
|
|
35
|
+
3. **The byte-offset parser reads the right fields.** PolicyVault's `RequireValidation` policy reads `subject_asset` at byte 8, `capability_hash` at byte 40, `attestor` at byte 72, `expires_at` at byte 208, `revoked` at byte 216 — exactly the offsets [`policy-vault/src/ext/validation_registry.rs`](https://github.com/agenttrust-labs/agenttrust/blob/main/programs/policy-vault/src/ext/validation_registry.rs) declares. The Phase F evidence reports verified each parsed value matches the on-chain raw bytes.
|
|
36
|
+
4. **The Phase D demo capability hash is consistent end to end.** `sha256("usdc-payment-policy.v1") = a968ecd0b93d9bfe57aa62c56d1e439717cf51d1dfe0ec413267834f2ca08375` — the same digest that policy-vault's `required_capability_hash` stores, that `CapabilityNamespace` keys against, that `ValidationAttestation.capability_hash` carries.
|
|
37
|
+
|
|
38
|
+
## Reproduce
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
git clone https://github.com/agenttrust-labs/agenttrust && cd agenttrust
|
|
42
|
+
pnpm install
|
|
43
|
+
|
|
44
|
+
pnpm --filter ./examples/attestor-demo run chained
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Cost: ~0.012 SOL devnet total across the four txs. Output JSON: `examples/attestor-demo/devnet-chained-validation.json`.
|
|
48
|
+
|
|
49
|
+
For the full lifecycle including revocation:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
REVOKE=1 pnpm --filter ./examples/attestor-demo run chained
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
`REVOKE=1` runs the optional fifth step — `revoke_validation` sets `revoked=true` on the attestation PDA in place. A subsequent `gate_payment` call returns `Deny(AttestationRevoked)` (DenyReason code 13).
|
|
56
|
+
|
|
57
|
+
## How a facilitator drives this in production
|
|
58
|
+
|
|
59
|
+
The Pay.sh adapter ([`trustgate/server/src/facilitators/pay-sh/`](https://github.com/agenttrust-labs/agenttrust/tree/main/trustgate/server/src/facilitators/pay-sh)) already surfaces `capabilityHash` in its `formatChallenge` response when the policy gate returns `RequireValidation`. A facilitator that hits this branch:
|
|
60
|
+
|
|
61
|
+
1. Sees `decision.kind = "RequireValidation"` + `capabilityHash` in the x402 `/verify` response body (header `X-Capability-Required: <hex>`).
|
|
62
|
+
2. Looks up the attestor service that handles that capability (typically discovered out-of-band via a registry or hard-coded contract).
|
|
63
|
+
3. Submits the claim payload off chain; the attestor responds on chain via `respond_to_validation`.
|
|
64
|
+
4. Re-submits the payment to the SERVICE; the new `/verify` call includes the `validation_attestation` PDA in the gate_payment account list, the policy reads it, and the decision flips to `Allow`.
|
|
65
|
+
|
|
66
|
+
The script demonstrates steps 3-4 working end to end on devnet. Steps 1-2 are business logic the SERVICE owns. Walkthrough: [Custom attestor](/integration-guides/custom-attestor).
|
|
67
|
+
|
|
68
|
+
## Validated by Kani
|
|
69
|
+
|
|
70
|
+
- [`validation_expiry_correct`](/verification/kani-proofs#4-validation_expiry_correct) — an expired attestation cannot produce `Allow`.
|
|
71
|
+
- [`gate_payment_strict_correctness`](/verification/kani-proofs#6-gate_payment_strict_correctness-phase-j5) — strict handler returns `Ok(())` if and only if the lazy composer returns `Allow`.
|
|
72
|
+
|
|
73
|
+
If a future change broke the policy's expiry semantics or the `RequireValidation` arm slipped into `Ok`, both proofs fail loud. Plus the Anchor end-to-end suite covers the full lifecycle in [`tests/validation-registry.spec.ts`](https://github.com/agenttrust-labs/agenttrust/blob/main/tests/validation-registry.spec.ts).
|
|
74
|
+
|
|
75
|
+
## Read next
|
|
76
|
+
|
|
77
|
+
<Cards>
|
|
78
|
+
<Card title="Devnet smoke" href="/verification/devnet-smoke">
|
|
79
|
+
The Pay.sh + AT atomic-settlement trace.
|
|
80
|
+
</Card>
|
|
81
|
+
<Card title="Custom attestor" href="/integration-guides/custom-attestor">
|
|
82
|
+
Build the other side — register, respond, revoke.
|
|
83
|
+
</Card>
|
|
84
|
+
<Card title="Capability namespaces" href="/reference/capability-namespaces">
|
|
85
|
+
Every seeded v1 namespace with PDA + Explorer URL.
|
|
86
|
+
</Card>
|
|
87
|
+
</Cards>
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Devnet smoke
|
|
3
|
+
description: The Pay.sh + AgentTrust atomic-settlement trace on Solana devnet — gate, transfer, emit_feedback in one transaction. Reproducible from a clean checkout.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
A real signed SPL transfer flowed through the demo's `/protected` endpoint, completed `gate_payment + transfer + emit_feedback` atomically, and wrote a `FeedbackEmissionLog` PDA on chain. Captured 2026-05-06.
|
|
7
|
+
|
|
8
|
+
Source script: [`examples/pay-sh-demo/scripts/devnet-smoke.ts`](https://github.com/agenttrust-labs/agenttrust/blob/main/examples/pay-sh-demo/scripts/devnet-smoke.ts). Trace JSON: [`examples/pay-sh-demo/devnet-smoke.json`](https://github.com/agenttrust-labs/agenttrust/blob/main/examples/pay-sh-demo/devnet-smoke.json).
|
|
9
|
+
|
|
10
|
+
## The trace
|
|
11
|
+
|
|
12
|
+
| Step | Tx |
|
|
13
|
+
|---|---|
|
|
14
|
+
| `emit_feedback` PDA-signed CPI → `agent_registry::give_feedback` → `atom_engine::update_stats` | [`jMobmWJUAXuL8FmQujfxW9NmeMbzADUoABzqjiMeuc5m3YXyeuZeUw1ZJc29JGsqyWQGDY8q3vrtBdamhKXraag`](https://explorer.solana.com/tx/jMobmWJUAXuL8FmQujfxW9NmeMbzADUoABzqjiMeuc5m3YXyeuZeUw1ZJc29JGsqyWQGDY8q3vrtBdamhKXraag?cluster=devnet) |
|
|
15
|
+
| Signed SPL `transferChecked` (the proof Pay.sh's CLI would produce) | [`5iV8EYmJh9XSXkBQrrbQ5L9kmBQabD3G3RXVPsHn9PkWceTFoeRsUV4g5aLLzZyRjeBoFvK3Woxr2cZa5xeUwhVD`](https://explorer.solana.com/tx/5iV8EYmJh9XSXkBQrrbQ5L9kmBQabD3G3RXVPsHn9PkWceTFoeRsUV4g5aLLzZyRjeBoFvK3Woxr2cZa5xeUwhVD?cluster=devnet) |
|
|
16
|
+
|
|
17
|
+
## On-chain artefacts
|
|
18
|
+
|
|
19
|
+
| Artefact | Address | Notes |
|
|
20
|
+
|---|---|---|
|
|
21
|
+
| `FeedbackEmissionLog` PDA | [`HB4BBi9jaD3VPcZkQQaH3DxukSqBiXfW8RejtaLa8bF3`](https://explorer.solana.com/address/HB4BBi9jaD3VPcZkQQaH3DxukSqBiXfW8RejtaLa8bF3?cluster=devnet) | Owned by trustgate · `score=100` · `is_dispute=0` · slot 460466788 |
|
|
22
|
+
| Tier-3 `agent_account` | [`5PfaofvEUf3adtJwMho7zzbfvgxwxbvp2V5moqhtLK8y`](https://explorer.solana.com/address/5PfaofvEUf3adtJwMho7zzbfvgxwxbvp2V5moqhtLK8y?cluster=devnet) | Quantu's payee identity |
|
|
23
|
+
| Tier-3 `atom_stats` | [`4z9RiK6B49QZbmqPM9yNZWgfxYD3tvQ3NETU6X89f5mv`](https://explorer.solana.com/address/4z9RiK6B49QZbmqPM9yNZWgfxYD3tvQ3NETU6X89f5mv?cluster=devnet) | `tier_immediate=3` after the feedback CPI |
|
|
24
|
+
| Asset (Metaplex Core) | [`C6cuZeDT4kmCC1RXw8mzaoLGwmAMe5fHDvutAjicVi8B`](https://explorer.solana.com/address/C6cuZeDT4kmCC1RXw8mzaoLGwmAMe5fHDvutAjicVi8B?cluster=devnet) | Quantu MPL-Core asset |
|
|
25
|
+
| Facilitator authority PDA | [`4TWqmxoMQRSJTmH879TDWqvqgiEwr9akWnpPVg51Z5Bg`](https://explorer.solana.com/address/4TWqmxoMQRSJTmH879TDWqvqgiEwr9akWnpPVg51Z5Bg?cluster=devnet) | TrustGate's PDA-signer for the CPI |
|
|
26
|
+
|
|
27
|
+
## What the trace proves
|
|
28
|
+
|
|
29
|
+
1. **All three Anchor programs are executable on devnet.** PolicyVault, TrustGate, and (transitively, since `atom_stats` exists for the demo agent) the Quantu agent-registry are reachable from off-chain code.
|
|
30
|
+
2. **The PDA-signed CPI works.** TrustGate's `["trustgate_auth", facilitator]` PDA signed a CPI into Quantu's `give_feedback`. The resulting `atom_stats` was bumped — Quantu's reputation surface accepted the feedback.
|
|
31
|
+
3. **Idempotency holds.** The `FeedbackEmissionLog` exists on chain at the predicted PDA seeds `["feedback_log", payment_id_hash]`. A second `emit_feedback` for the same `payment_id_hash` would fail account-already-in-use; retries cannot double-emit.
|
|
32
|
+
4. **The atomic-tx invariant is enforced end to end on devnet.** The SDK's `composeAtomicSettleTx` produces one `Transaction` with three instructions in canonical order; both the gate-mutation and the feedback-emission committed in the same slot.
|
|
33
|
+
|
|
34
|
+
## Reproduce
|
|
35
|
+
|
|
36
|
+
From a clean checkout:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
git clone https://github.com/agenttrust-labs/agenttrust && cd agenttrust
|
|
40
|
+
pnpm install
|
|
41
|
+
|
|
42
|
+
# 1. publish IDLs (one-time, ~0.03 SOL)
|
|
43
|
+
anchor idl init --provider.cluster devnet \
|
|
44
|
+
--filepath target/idl/trustgate.json HF8zHfoyA7b5mhLViopTnRMprc6ZT5KActHTdkFrih2N
|
|
45
|
+
anchor idl init --provider.cluster devnet \
|
|
46
|
+
--filepath target/idl/policy_vault.json 8Y6fGeNEHgmWmbt8JsRcF72jxbeBfJhomMjG6SuoJQTR
|
|
47
|
+
anchor idl init --provider.cluster devnet \
|
|
48
|
+
--filepath target/idl/validation_registry.json Cx4RFa6ysw3qXYhugPkF8pFSWBkmKq59h2dWgF2tKhtv
|
|
49
|
+
|
|
50
|
+
# 2. pre-warm 3 Quantu agents (one-time, ~0.04 SOL)
|
|
51
|
+
pnpm --filter ./examples/pay-sh-demo exec ts-node scripts/prewarm-devnet.ts
|
|
52
|
+
|
|
53
|
+
# 3. run the smoke (~0.03 SOL)
|
|
54
|
+
pnpm --filter ./examples/pay-sh-demo exec ts-node scripts/devnet-smoke.ts
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
The full trace (signatures, PDAs, slot numbers) lands in `examples/pay-sh-demo/devnet-smoke.json`. Re-running is idempotent — `TrustGateAuthority`, test mint, payer keypair, and ATAs are reused if present.
|
|
58
|
+
|
|
59
|
+
## Daily smoke (cron)
|
|
60
|
+
|
|
61
|
+
[`.github/workflows/daily-devnet-smoke.yml`](https://github.com/agenttrust-labs/agenttrust/blob/main/.github/workflows/daily-devnet-smoke.yml) runs the same flow on a 24-hour cron. The result is committed back to the repo at [`docs/proofs/smoke-2026-05-06.md`](https://github.com/agenttrust-labs/agenttrust/blob/main/docs/proofs/smoke-2026-05-06.md) (template). A failed daily smoke flips a status badge red; a green smoke means devnet, the Quantu programs, and AgentTrust's three programs are all healthy.
|
|
62
|
+
|
|
63
|
+
## Anchor end-to-end suite
|
|
64
|
+
|
|
65
|
+
The Anchor TS suite at [`tests/`](https://github.com/agenttrust-labs/agenttrust/tree/main/tests) covers 50 end-to-end cases including the atomic-tx invariant, chained kill-switch atomicity, and full RequireValidation lifecycle. Run via:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
anchor test --skip-deploy --provider.cluster devnet
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Adversarial-harness coverage: [Adversarial harness](/verification/adversarial-harness).
|
|
72
|
+
|
|
73
|
+
## Read next
|
|
74
|
+
|
|
75
|
+
<Cards>
|
|
76
|
+
<Card title="Chained validation" href="/verification/chained-validation">
|
|
77
|
+
Four-signature trace through the third ERC-8004 leg.
|
|
78
|
+
</Card>
|
|
79
|
+
<Card title="Atomic-tx invariant" href="/verification/atomic-tx-invariant">
|
|
80
|
+
Why the gate, transfer, and feedback must execute as one Solana tx.
|
|
81
|
+
</Card>
|
|
82
|
+
<Card title="Live evidence" href="/verification/live-evidence">
|
|
83
|
+
Consolidated index across every claim.
|
|
84
|
+
</Card>
|
|
85
|
+
</Cards>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Verification
|
|
3
|
+
description: Every load-bearing claim in AgentTrust has an independently checkable artifact — a Kani proof, a devnet tx signature, a localnet test, a cron job. This section indexes them.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
If you're a judge with five minutes, start with [Live evidence](/verification/live-evidence) — every claim with a clickable Explorer URL.
|
|
7
|
+
|
|
8
|
+
If you're a developer debugging a specific property, jump straight to the relevant per-claim page below.
|
|
9
|
+
|
|
10
|
+
## Pages
|
|
11
|
+
|
|
12
|
+
<Cards>
|
|
13
|
+
<Card title="Live evidence" href="/verification/live-evidence">
|
|
14
|
+
Consolidated index — Kani 6/6 + 635 sub-checks, devnet smoke, chained validation, capability namespaces, daily-smoke cron. Every claim with an Explorer URL.
|
|
15
|
+
</Card>
|
|
16
|
+
<Card title="Kani proofs" href="/verification/kani-proofs">
|
|
17
|
+
Six machine-checked invariants over the pure-Rust composer. Per-harness deep-dive: file path, sub-check count, time, what it proves, what it doesn't.
|
|
18
|
+
</Card>
|
|
19
|
+
<Card title="Devnet smoke" href="/verification/devnet-smoke">
|
|
20
|
+
The Pay.sh + AgentTrust atomic-settlement trace on Solana devnet — gate, transfer, emit_feedback CPI, all in one tx, with reproduction commands.
|
|
21
|
+
</Card>
|
|
22
|
+
<Card title="Chained validation" href="/verification/chained-validation">
|
|
23
|
+
The four-signature RequireValidation → respond → Allow trace that proves the third ERC-8004 leg actually closes the loop.
|
|
24
|
+
</Card>
|
|
25
|
+
<Card title="Atomic-tx invariant" href="/verification/atomic-tx-invariant">
|
|
26
|
+
Three layers of proof — compile-time literal-type guard, runtime throw, composer structure — plus the on-chain Kani strict-correctness binding.
|
|
27
|
+
</Card>
|
|
28
|
+
<Card title="Adversarial harness" href="/verification/adversarial-harness">
|
|
29
|
+
Fourteen hostile-scenario assertions in tests/adversarial.spec.ts that exercise the gate against malformed PDAs, replayed proofs, and corrupted state.
|
|
30
|
+
</Card>
|
|
31
|
+
</Cards>
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Kani proofs
|
|
3
|
+
description: Six machine-checked invariants over the pure-Rust composer — 635 sub-checks, zero failures, ~80 s on a single CI runner. Per-harness deep-dive.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
PolicyVault ships with six `#[kani::proof]` harnesses over the pure-Rust composer (and one helper). Each runs on every PR via [`.github/workflows/kani-prove.yml`](https://github.com/agenttrust-labs/agenttrust/blob/main/.github/workflows/kani-prove.yml). Source: [`programs/policy-vault/src/proofs/`](https://github.com/agenttrust-labs/agenttrust/tree/main/programs/policy-vault/src/proofs).
|
|
7
|
+
|
|
8
|
+
Kani is the [model-checking/kani](https://github.com/model-checking/kani) bounded model checker. It compiles the Rust under verification to CBMC's intermediate form and explores every reachable state inside the configured bounds.
|
|
9
|
+
|
|
10
|
+
<KaniProofBadge />
|
|
11
|
+
|
|
12
|
+
## Six invariants — summary
|
|
13
|
+
|
|
14
|
+
| # | Invariant | Sub-checks | Time | Bound |
|
|
15
|
+
|---:|---|---:|---:|---|
|
|
16
|
+
| 1 | `paused_implies_no_allow` | 126 | 0.25 s | `#[kani::unwind(N)]` on the policy-bitmask scan |
|
|
17
|
+
| 2 | `velocity_counter_le_limit` | 9 | 0.03 s | none |
|
|
18
|
+
| 3 | `counterparty_tier_monotone` | 8 | 0.02 s | none |
|
|
19
|
+
| 4 | `validation_expiry_correct` | 85 | 0.23 s | none |
|
|
20
|
+
| 5 | `multisig_threshold_enforced` | 149 | 77.17 s | 3 members + 3 signers |
|
|
21
|
+
| 6 | `gate_payment_strict_correctness` | 258 | ~0.9 s | none |
|
|
22
|
+
|
|
23
|
+
**Total: 635 sub-checks, 0 failures, ~80 s.** Phase J5 added invariant 6.
|
|
24
|
+
|
|
25
|
+
## 1 · `paused_implies_no_allow`
|
|
26
|
+
|
|
27
|
+
**Property.** If the agent's KillSwitch is `paused == true` AND `KIND_KILLSWITCH` is set in the policy bitmask, `compose_decision` cannot return `Allow` for any values of the other policy fields, ledger, or input parameters.
|
|
28
|
+
|
|
29
|
+
**File.** [`proofs/inv_paused_implies_no_allow.rs`](https://github.com/agenttrust-labs/agenttrust/blob/main/programs/policy-vault/src/proofs/inv_paused_implies_no_allow.rs). **Harness:** `paused_killswitch_implies_no_allow`.
|
|
30
|
+
|
|
31
|
+
**Why it's load-bearing.** This is the safety invariant of the gate. If a future change re-orders or skips KillSwitch evaluation, Kani fails this proof loud.
|
|
32
|
+
|
|
33
|
+
## 2 · `velocity_counter_le_limit`
|
|
34
|
+
|
|
35
|
+
**Property.** Inductive form: if the pre-state ledger satisfies `cumulative_amount ≤ max_in_window`, then after `velocity::evaluate` returns `Allow(deltas)` the new cumulative counter still satisfies the bound.
|
|
36
|
+
|
|
37
|
+
**File.** [`proofs/inv_velocity_counter_le_limit.rs`](https://github.com/agenttrust-labs/agenttrust/blob/main/programs/policy-vault/src/proofs/inv_velocity_counter_le_limit.rs). **Harness:** `velocity_allow_implies_cumulative_le_max`.
|
|
38
|
+
|
|
39
|
+
**Why it's inductive.** Every prior `Allow` preserves the bound; a fresh ledger trivially satisfies the base case. Cross-policy preservation against `spending.weekly_max` is a separate proof if/when needed.
|
|
40
|
+
|
|
41
|
+
The `apply_deltas` rule on the composer side — only on `Allow` — is what makes this inductive on chain. If a future change applied deltas on `Deny` or `RequireValidation`, this proof becomes a falsehood.
|
|
42
|
+
|
|
43
|
+
## 3 · `counterparty_tier_monotone`
|
|
44
|
+
|
|
45
|
+
**Property.** If a STRICT policy (high `min_counterparty_tier`) produces `Allow` for a given payee, a LOOSER policy (lower or equal `min_tier`) on the same payee must also produce `Allow`. Loosening the tier requirement can never turn an `Allow` into a `Deny`.
|
|
46
|
+
|
|
47
|
+
**File.** [`proofs/inv_counterparty_tier_monotone.rs`](https://github.com/agenttrust-labs/agenttrust/blob/main/programs/policy-vault/src/proofs/inv_counterparty_tier_monotone.rs). **Harness:** `counterparty_tier_monotone`.
|
|
48
|
+
|
|
49
|
+
**Why it's anti-regression.** This is a sanity invariant. If a refactor introduces non-monotone behaviour (e.g., a config combination where loosening the threshold accidentally tightens it), Kani fails.
|
|
50
|
+
|
|
51
|
+
## 4 · `validation_expiry_correct`
|
|
52
|
+
|
|
53
|
+
**Property.** An expired attestation (`expires_at != 0 AND expires_at <= now_slot`) cannot produce `Allow` from `require_validation::evaluate`.
|
|
54
|
+
|
|
55
|
+
**File.** [`proofs/inv_validation_expiry_correct.rs`](https://github.com/agenttrust-labs/agenttrust/blob/main/programs/policy-vault/src/proofs/inv_validation_expiry_correct.rs). **Harness:** `validation_expiry_correct`.
|
|
56
|
+
|
|
57
|
+
**Why it matters.** Subject + capability + revocation are forced equal in the symbolic search so expiry is the deciding gate. Closes the obvious time-of-check / time-of-use stale-attestation hole — even if a payment race somehow passes a stale attestation through the verify path, the expiry check on the gate itself denies it.
|
|
58
|
+
|
|
59
|
+
## 5 · `multisig_threshold_enforced`
|
|
60
|
+
|
|
61
|
+
**Property.** `PolicyAuthority::count_distinct_signing_members` cannot return a count exceeding `min(member_count, signer_keys.len())`.
|
|
62
|
+
|
|
63
|
+
**File.** [`proofs/inv_multisig_threshold_enforced.rs`](https://github.com/agenttrust-labs/agenttrust/blob/main/programs/policy-vault/src/proofs/inv_multisig_threshold_enforced.rs). **Harness:** `multisig_threshold_enforced`.
|
|
64
|
+
|
|
65
|
+
**Why it's load-bearing.** This is the property that backs `set_killswitch`'s `require!(distinct_count >= threshold)` gate. A caller cannot construct a signer set that fools the function into over-counting (duplicate pubkeys, off-by-one tricks, corrupted `members` arrays).
|
|
66
|
+
|
|
67
|
+
**Bound.** 3 members + 3 signers for symbolic-search tractability; the property generalises by induction.
|
|
68
|
+
|
|
69
|
+
## 6 · `gate_payment_strict_correctness` (Phase J5)
|
|
70
|
+
|
|
71
|
+
**Property.** Two harnesses pin the SDK's atomicity contract end-to-end:
|
|
72
|
+
|
|
73
|
+
- `strict_returns_ok_iff_allow` — `compose_decision == Allow` ⇒ strict handler returns `Ok(())`. `compose_decision == Deny(_)` ⇒ strict returns `Err(_)`. `compose_decision == RequireValidation` ⇒ strict returns `Err(_)`.
|
|
74
|
+
- `gate_decision_is_one_of_three_disjoint_variants` — the three `GateDecision` arms are pairwise disjoint, so a future fourth variant cannot silently slip past the strict dispatch.
|
|
75
|
+
|
|
76
|
+
Together: `strict_returns_ok ⇔ matches!(decision, Allow)`.
|
|
77
|
+
|
|
78
|
+
**File.** [`proofs/inv_gate_payment_strict_correctness.rs`](https://github.com/agenttrust-labs/agenttrust/blob/main/programs/policy-vault/src/proofs/inv_gate_payment_strict_correctness.rs).
|
|
79
|
+
|
|
80
|
+
**Why it matters.** This is the on-chain anchor of the SDK's atomic-tx invariant. The SDK enforces atomicity at three TS layers; this proof pins the on-chain handler that those layers feed into. If a future change re-routes the `Deny` arm to an `Ok` return, both the TS guards and this proof fail loud.
|
|
81
|
+
|
|
82
|
+
Sub-check breakdown:
|
|
83
|
+
|
|
84
|
+
| Sub-harness | Failed | Sub-checks | Unreachable |
|
|
85
|
+
|---|---:|---:|---:|
|
|
86
|
+
| `strict_returns_ok_iff_allow` | 0 | 131 | 3 |
|
|
87
|
+
| `gate_decision_is_one_of_three_disjoint_variants` | 0 | 127 | 3 |
|
|
88
|
+
|
|
89
|
+
Combined: 0 / 258 failed.
|
|
90
|
+
|
|
91
|
+
## Reproduce locally
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
git clone https://github.com/agenttrust-labs/agenttrust && cd agenttrust
|
|
95
|
+
cargo install --locked kani-verifier
|
|
96
|
+
cargo kani setup
|
|
97
|
+
|
|
98
|
+
cd programs/policy-vault
|
|
99
|
+
|
|
100
|
+
cargo kani --harness paused_killswitch_implies_no_allow
|
|
101
|
+
cargo kani --harness velocity_allow_implies_cumulative_le_max
|
|
102
|
+
cargo kani --harness counterparty_tier_monotone
|
|
103
|
+
cargo kani --harness validation_expiry_correct
|
|
104
|
+
cargo kani --harness multisig_threshold_enforced
|
|
105
|
+
cargo kani --harness strict_returns_ok_iff_allow
|
|
106
|
+
cargo kani --harness gate_decision_is_one_of_three_disjoint_variants
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Or run all six via the CI workflow:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
gh workflow run kani-prove.yml
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Expected output per harness:
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
SUMMARY:
|
|
119
|
+
** 0 of <N> failed (<X> unreachable)
|
|
120
|
+
|
|
121
|
+
VERIFICATION:- SUCCESSFUL
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## What Kani does NOT prove
|
|
125
|
+
|
|
126
|
+
- **Anchor handler account validation.** These are tested via [`tests/policy-vault.spec.ts`](https://github.com/agenttrust-labs/agenttrust/blob/main/tests/policy-vault.spec.ts) — Anchor end-to-end suite, 50 cases.
|
|
127
|
+
- **Borsh deserialization correctness of foreign PDAs.** Manual byte-offset parsers in [`programs/policy-vault/src/ext/`](https://github.com/agenttrust-labs/agenttrust/tree/main/programs/policy-vault/src/ext); unit tests + runtime constraint checks per parser.
|
|
128
|
+
- **Integer overflow in the SPL token transfer.** Legacy SPL token's own invariant — out of scope for AgentTrust verification.
|
|
129
|
+
- **Liveness.** A denied request never reaches Allow, but the proofs do not bound the number of denials before an Allow eventually fires. Liveness + economic-game-theoretic properties are out of scope for v1.
|
|
130
|
+
|
|
131
|
+
The six invariants above are the **safety** properties: nothing catastrophic happens.
|
|
132
|
+
|
|
133
|
+
## Why bounded
|
|
134
|
+
|
|
135
|
+
Kani is a bounded model checker. Two of the proofs (`paused_implies_no_allow`, `multisig_threshold_enforced`) use `#[kani::unwind(N)]` to cap loop iterations. This is the standard discipline for finite-state proofs over Solana data — member arrays cap at 7 per `PolicyAuthority`, atom-engine tier domain is `0..=4`, etc. The bounds match production-realistic state sizes; symbolic search exhausts all reachable states inside those bounds.
|
|
136
|
+
|
|
137
|
+
For an unbounded inductive proof on top of these, the canonical next step is `qedgen-formal-verification` (Lean 4 + Kani harness compilation from a single `.qedspec`), tracked as a v1.1 hardening item.
|
|
138
|
+
|
|
139
|
+
## Source
|
|
140
|
+
|
|
141
|
+
- All proofs: [`programs/policy-vault/src/proofs/`](https://github.com/agenttrust-labs/agenttrust/tree/main/programs/policy-vault/src/proofs)
|
|
142
|
+
- Workflow: [`.github/workflows/kani-prove.yml`](https://github.com/agenttrust-labs/agenttrust/blob/main/.github/workflows/kani-prove.yml)
|
|
143
|
+
- README: [`docs/proofs/README.md`](https://github.com/agenttrust-labs/agenttrust/blob/main/docs/proofs/README.md)
|
|
144
|
+
- Sub-check summary: [`docs/proofs/kani-summary.txt`](https://github.com/agenttrust-labs/agenttrust/blob/main/docs/proofs/kani-summary.txt)
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Live evidence
|
|
3
|
+
description: Every AgentTrust claim with an independently checkable artifact — Kani proofs, devnet tx signatures, localnet tests, cron jobs, hosted endpoints. One page.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Every claim on this page is checkable from a terminal in under five minutes. No login. No clone (unless you want to re-run the proofs locally). Each row links to the artifact directly.
|
|
7
|
+
|
|
8
|
+
Captured 2026-05-08 against `main` post-Phase Q1.
|
|
9
|
+
|
|
10
|
+
## Three programs deployed on devnet
|
|
11
|
+
|
|
12
|
+
| Program | Address | Explorer | IDL |
|
|
13
|
+
|---|---|---|---|
|
|
14
|
+
| `policy_vault` | `8Y6f…QTR` | [Open](https://explorer.solana.com/address/8Y6fGeNEHgmWmbt8JsRcF72jxbeBfJhomMjG6SuoJQTR?cluster=devnet) | published |
|
|
15
|
+
| `trustgate` | `HF8z…ih2N` | [Open](https://explorer.solana.com/address/HF8zHfoyA7b5mhLViopTnRMprc6ZT5KActHTdkFrih2N?cluster=devnet) | published |
|
|
16
|
+
| `validation_registry` | `Cx4R…Khtv` | [Open](https://explorer.solana.com/address/Cx4RFa6ysw3qXYhugPkF8pFSWBkmKq59h2dWgF2tKhtv?cluster=devnet) | published |
|
|
17
|
+
|
|
18
|
+
Verify executable status:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
for p in 8Y6fGeNEHgmWmbt8JsRcF72jxbeBfJhomMjG6SuoJQTR \
|
|
22
|
+
HF8zHfoyA7b5mhLViopTnRMprc6ZT5KActHTdkFrih2N \
|
|
23
|
+
Cx4RFa6ysw3qXYhugPkF8pFSWBkmKq59h2dWgF2tKhtv; do
|
|
24
|
+
solana program show "$p" --url devnet | grep Executable
|
|
25
|
+
done
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Six Kani proofs
|
|
29
|
+
|
|
30
|
+
<KaniProofBadge />
|
|
31
|
+
|
|
32
|
+
| # | Invariant | Sub-checks | Time |
|
|
33
|
+
|---:|---|---:|---:|
|
|
34
|
+
| 1 | `paused_implies_no_allow` | 126 | 0.25 s |
|
|
35
|
+
| 2 | `velocity_counter_le_limit` | 9 | 0.03 s |
|
|
36
|
+
| 3 | `counterparty_tier_monotone` | 8 | 0.02 s |
|
|
37
|
+
| 4 | `validation_expiry_correct` | 85 | 0.23 s |
|
|
38
|
+
| 5 | `multisig_threshold_enforced` | 149 | 77.17 s |
|
|
39
|
+
| 6 | `gate_payment_strict_correctness` (J5) | 258 (`131 + 127`) | ~0.9 s |
|
|
40
|
+
|
|
41
|
+
**Total: 635 sub-checks, 6/6 proven, ~80 s on a single CI runner.** Workflow: [`.github/workflows/kani-prove.yml`](https://github.com/agenttrust-labs/agenttrust/blob/main/.github/workflows/kani-prove.yml). Per-harness deep-dive: [Kani proofs](/verification/kani-proofs).
|
|
42
|
+
|
|
43
|
+
Reproduce:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
git clone https://github.com/agenttrust-labs/agenttrust && cd agenttrust
|
|
47
|
+
cargo install --locked kani-verifier
|
|
48
|
+
cargo kani --manifest-path programs/policy-vault/Cargo.toml \
|
|
49
|
+
--harness paused_killswitch_implies_no_allow
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Pay.sh + AgentTrust atomic settlement (live devnet)
|
|
53
|
+
|
|
54
|
+
A real signed SPL transfer flowed through `demo.agenttrust.tech/protected`, completed `gate_payment + transfer + emit_feedback` atomically, and wrote a `FeedbackEmissionLog` PDA on chain (2026-05-06).
|
|
55
|
+
|
|
56
|
+
| Step | Tx |
|
|
57
|
+
|---|---|
|
|
58
|
+
| `emit_feedback` PDA-signed CPI → Quantu `give_feedback` → `update_stats` | [`jMobmWJUAXuL8…`](https://explorer.solana.com/tx/jMobmWJUAXuL8FmQujfxW9NmeMbzADUoABzqjiMeuc5m3YXyeuZeUw1ZJc29JGsqyWQGDY8q3vrtBdamhKXraag?cluster=devnet) |
|
|
59
|
+
| signed SPL `transferChecked` (the proof Pay.sh's CLI would produce) | [`5iV8EYmJh9XS…`](https://explorer.solana.com/tx/5iV8EYmJh9XSXkBQrrbQ5L9kmBQabD3G3RXVPsHn9PkWceTFoeRsUV4g5aLLzZyRjeBoFvK3Woxr2cZa5xeUwhVD?cluster=devnet) |
|
|
60
|
+
|
|
61
|
+
Resulting on-chain artefacts:
|
|
62
|
+
|
|
63
|
+
| Artefact | Address |
|
|
64
|
+
|---|---|
|
|
65
|
+
| `FeedbackEmissionLog` PDA (owned by trustgate, score=100, slot 460466788) | [`HB4BBi9j…`](https://explorer.solana.com/address/HB4BBi9jaD3VPcZkQQaH3DxukSqBiXfW8RejtaLa8bF3?cluster=devnet) |
|
|
66
|
+
| Tier-3 `agent_account` | [`5Pfa…K8y`](https://explorer.solana.com/address/5PfaofvEUf3adtJwMho7zzbfvgxwxbvp2V5moqhtLK8y?cluster=devnet) |
|
|
67
|
+
| Tier-3 `atom_stats` | [`4z9R…f5mv`](https://explorer.solana.com/address/4z9RiK6B49QZbmqPM9yNZWgfxYD3tvQ3NETU6X89f5mv?cluster=devnet) |
|
|
68
|
+
| Asset (Metaplex Core) | [`C6cu…Vi8B`](https://explorer.solana.com/address/C6cuZeDT4kmCC1RXw8mzaoLGwmAMe5fHDvutAjicVi8B?cluster=devnet) |
|
|
69
|
+
| Facilitator authority PDA | [`4TWq…Z5Bg`](https://explorer.solana.com/address/4TWqmxoMQRSJTmH879TDWqvqgiEwr9akWnpPVg51Z5Bg?cluster=devnet) |
|
|
70
|
+
|
|
71
|
+
Reproduce: see [Devnet smoke](/verification/devnet-smoke).
|
|
72
|
+
|
|
73
|
+
## Chained validation — third ERC-8004 leg, full lifecycle (live devnet)
|
|
74
|
+
|
|
75
|
+
Four signatures prove the third leg actually closes the loop. Subject = the same Quantu tier-3 agent the Pay.sh trace used; capability = `usdc-payment-policy.v1` (2026-05-06).
|
|
76
|
+
|
|
77
|
+
| Step | Tx |
|
|
78
|
+
|---|---|
|
|
79
|
+
| `gate_payment` (no attestation) → `RequireValidation` | [`3oKW7QugBLJ7…`](https://explorer.solana.com/tx/3oKW7QugBLJ7kH2QbLLWEuEn3MyNmLWCj3XovCSdDQNmq5HriwNKvPMUR9TQByZPBAPbvprDfdeYDZvh7ofntRRh?cluster=devnet) |
|
|
80
|
+
| `request_validation` | [`2KbXYCF67D2f…`](https://explorer.solana.com/tx/2KbXYCF67D2f2fKHk5yTzrkFBr1mV47Q3Yb1veH5e3PX4PuLa66suodAUc7uTBnr6Y44NGV1TfHHMtAZiFSnbbRF?cluster=devnet) |
|
|
81
|
+
| `respond_to_validation` (creates attestation PDA `8YKq…xt2q`) | [`67CzMS9GEt…`](https://explorer.solana.com/tx/67CzMS9GEtUBesNznKpT2UWqvjEBzhgZd7AVkhXKQ5SoqRoBotcaYf1sTF8sHxj55TNT9k847nj7FQdrwAqKussp?cluster=devnet) |
|
|
82
|
+
| `gate_payment` (with attestation) → `Allow` | [`dEXkCEeSn8…`](https://explorer.solana.com/tx/dEXkCEeSn8uiVAa14u7EusdFufSuUQttmcTdLHMSq5J3VSARM4KMRCfwpRSkVmYBc1yRQuyvPMCebifCf1dmrmC?cluster=devnet) |
|
|
83
|
+
|
|
84
|
+
`ValidationAttestation` PDA: [`8YKq…xt2q`](https://explorer.solana.com/address/8YKqxoBaKfQ4VcDNa6dcoMQGevxbRmcr4ENbWcyrJxt2q?cluster=devnet). Reproduce + full trace: [Chained validation](/verification/chained-validation).
|
|
85
|
+
|
|
86
|
+
## Ten capability namespaces seeded (live devnet)
|
|
87
|
+
|
|
88
|
+
Every PDA exists on chain. Auto-generated lookup with per-namespace Explorer URLs: [Reference → Capability namespaces](/reference/capability-namespaces). Every name decomposes to `MAX_NAME_LEN = 32` per the on-chain bound; the playbook-level descriptive labels live in the schema-URI document.
|
|
89
|
+
|
|
90
|
+
Reproduce: `pnpm --filter ./examples/attestor-demo run seed:namespaces` is idempotent.
|
|
91
|
+
|
|
92
|
+
## Hosted services (Fly.io)
|
|
93
|
+
|
|
94
|
+
| Service | URL | Healthz |
|
|
95
|
+
|---|---|---|
|
|
96
|
+
| Demo | [`demo.agenttrust.tech`](https://demo.agenttrust.tech) | `GET /health` |
|
|
97
|
+
| Facilitator (`/verify` + `/settle`) | [`api.agenttrust.tech`](https://api.agenttrust.tech) | `GET /healthz` |
|
|
98
|
+
| MCP HTTP endpoint | [`mcp.agenttrust.tech`](https://mcp.agenttrust.tech) | `GET /healthz` (returns `version: "0.2.6"`, `toolCount: 18`) |
|
|
99
|
+
|
|
100
|
+
Singapore region, `shared-cpu-1x@256MB`, two machines for HA, `min_machines_running = 1`. Lets-Encrypt certs on every subdomain.
|
|
101
|
+
|
|
102
|
+
## Atomic-tx invariant — three layers + on-chain anchor
|
|
103
|
+
|
|
104
|
+
| Layer | What it proves | Evidence |
|
|
105
|
+
|---|---|---|
|
|
106
|
+
| Compile-time literal-type guard | `AtomicityEnforced` is `{ atomicityEnforced: true }` (literal `true`). TS rejects `false`, missing, or `boolean` widening. | [`trustgate/sdk/src/atomicity.ts`](https://github.com/agenttrust-labs/agenttrust/blob/main/trustgate/sdk/src/atomicity.ts) lines 31-33 |
|
|
107
|
+
| Runtime guard | `assertAtomicityEnforced` throws `AtomicityNotEnforcedError` for any value that isn't strictly `=== true`. Catches `as any` casts. | [`trustgate/sdk/src/atomicity.ts`](https://github.com/agenttrust-labs/agenttrust/blob/main/trustgate/sdk/src/atomicity.ts) lines 51-58 |
|
|
108
|
+
| Composer structure | `composeAtomicSettleTx` returns one `Transaction` with exactly three instructions in canonical order. | [`trustgate/sdk/test/atomicity.test.ts`](https://github.com/agenttrust-labs/agenttrust/blob/main/trustgate/sdk/test/atomicity.test.ts) `describe("composeAtomicSettleTx")` (5 cases) |
|
|
109
|
+
| Single-tx atomic revert (localnet) | Bundled tx with failing inner ix reverts the whole bundle; `gate_payment_strict` rolls back. | [`tests/atomic-tx-invariant.spec.ts`](https://github.com/agenttrust-labs/agenttrust/blob/main/tests/atomic-tx-invariant.spec.ts) `describe("B. single-tx atomic revert")` |
|
|
110
|
+
| Split-tx corruption (localnet) | Splitting the bundle leaves `VelocityLedger` dirty after the transfer reverts — the fault model A+B prevents. | [`tests/atomic-tx-invariant.spec.ts`](https://github.com/agenttrust-labs/agenttrust/blob/main/tests/atomic-tx-invariant.spec.ts) `describe("C. split-tx anti-pattern corrupts state")` |
|
|
111
|
+
| On-chain anchor | `gate_payment_strict_correctness` Kani proof binds strict `Ok(())` to composer `Allow`. | [`programs/policy-vault/src/proofs/inv_gate_payment_strict_correctness.rs`](https://github.com/agenttrust-labs/agenttrust/blob/main/programs/policy-vault/src/proofs/inv_gate_payment_strict_correctness.rs) |
|
|
112
|
+
|
|
113
|
+
Full deep-dive: [Atomic-tx invariant](/verification/atomic-tx-invariant). Background writeup: [`docs/proofs/transfer-hook-atomicity.md`](https://github.com/agenttrust-labs/agenttrust/blob/main/docs/proofs/transfer-hook-atomicity.md).
|
|
114
|
+
|
|
115
|
+
## Adversarial harness — fourteen hostile-scenario assertions
|
|
116
|
+
|
|
117
|
+
[`tests/adversarial.spec.ts`](https://github.com/agenttrust-labs/agenttrust/blob/main/tests/adversarial.spec.ts) exercises the gate against malformed PDAs, replayed proofs, corrupted state, schema-version drift, expired attestations, off-curve attestor pubkeys, and more. Per-scenario detail: [Adversarial harness](/verification/adversarial-harness).
|
|
118
|
+
|
|
119
|
+
## Test coverage
|
|
120
|
+
|
|
121
|
+
| Layer | Count | Where |
|
|
122
|
+
|---|---:|---|
|
|
123
|
+
| Rust unit tests | 113 | `cargo test --workspace --lib` |
|
|
124
|
+
| Kani formal proofs | 6 / 635 sub-checks | `cargo kani` per proof harness |
|
|
125
|
+
| Anchor TS end-to-end | 50 | `anchor test --provider.cluster devnet` |
|
|
126
|
+
| Adversarial harness | 14 | `tests/adversarial.spec.ts` |
|
|
127
|
+
| SDK unit tests | 56 (+ 16 INTEGRATION-gated) | `cd trustgate/sdk && pnpm test` |
|
|
128
|
+
| Server adapter tests | 146 | `cd trustgate/server && pnpm test` |
|
|
129
|
+
| MCP unit tests | 76 (+ 3 INTEGRATION + 21 protocol-conformance) | `cd mcp && pnpm test` |
|
|
130
|
+
| pay-sh-demo flow | 7 (+ 1 INTEGRATION) | `cd examples/pay-sh-demo && pnpm test` |
|
|
131
|
+
| attestor-demo lifecycle | 6 (INTEGRATION-gated) | `cd examples/attestor-demo && pnpm test` |
|
|
132
|
+
| **Total** | **~360 tests + 6 formal proofs + 14 adversarial scenarios** | All green on `main` |
|
|
133
|
+
|
|
134
|
+
## CI workflows (15 total)
|
|
135
|
+
|
|
136
|
+
| Workflow | Purpose |
|
|
137
|
+
|---|---|
|
|
138
|
+
| `kani-prove.yml` | All 6 Kani proofs on every PR |
|
|
139
|
+
| `kani-budget.yml` | Total runtime ceiling for Kani |
|
|
140
|
+
| `anchor-test.yml` | Full Anchor end-to-end with Quantu mainnet clones |
|
|
141
|
+
| `ts-test.yml` | SDK + server + web + demo + MCP build/test |
|
|
142
|
+
| `adapter-contract-conformance.yml` | Adapter-contract walk |
|
|
143
|
+
| `mcp-protocol-conformance.yml` | 21 MCP protocol assertions |
|
|
144
|
+
| `bundle-size.yml` | SDK npm pack-size budget |
|
|
145
|
+
| `daily-devnet-smoke.yml` | Cron — full devnet round-trip every 24h |
|
|
146
|
+
| `devnet-integration.yml` | Gated on `DEVNET_FACILITATOR_KEYPAIR` secret |
|
|
147
|
+
| `idl-diff.yml` | ABI-stability gate vs deployed IDL |
|
|
148
|
+
| `link-check.yml` | README + MDX dead-link sweep |
|
|
149
|
+
| `lint-and-format.yml` | tsc + cargo fmt + clippy |
|
|
150
|
+
| `lockfile-freshness.yml` | pnpm + Cargo.lock drift |
|
|
151
|
+
| `secret-scan.yml` | gitleaks against the diff |
|
|
152
|
+
| `build.yml` | cargo + anchor build |
|
|
153
|
+
|
|
154
|
+
Latest run summary: [`docs/proofs/ci-runs.md`](https://github.com/agenttrust-labs/agenttrust/blob/main/docs/proofs/ci-runs.md).
|
|
155
|
+
|
|
156
|
+
## Phase reports
|
|
157
|
+
|
|
158
|
+
| Phase | Date | Report |
|
|
159
|
+
|---|---|---|
|
|
160
|
+
| F (verification) | 2026-05-06 | [`phase-f-verification-report.md`](https://github.com/agenttrust-labs/agenttrust/blob/main/docs/proofs/phase-f-verification-report.md) |
|
|
161
|
+
| G | 2026-05-07 | [`phase-g-report.md`](https://github.com/agenttrust-labs/agenttrust/blob/main/docs/proofs/phase-g-report.md) |
|
|
162
|
+
| H (hosting + npm) | 2026-05-07 | [`phase-h-report.md`](https://github.com/agenttrust-labs/agenttrust/blob/main/docs/proofs/phase-h-report.md) |
|
|
163
|
+
| J (Kani strict-correctness) | 2026-05-07 | [`phase-j-report.md`](https://github.com/agenttrust-labs/agenttrust/blob/main/docs/proofs/phase-j-report.md) |
|
|
164
|
+
| M (MCP comprehensive E2E) | 2026-05-07 | [`phase-m-mcp-e2e.md`](https://github.com/agenttrust-labs/agenttrust/blob/main/docs/proofs/phase-m-mcp-e2e.md) |
|
|
165
|
+
| P (real-LLM tool routing) | 2026-05-08 | [`phase-p-llm-routing.md`](https://github.com/agenttrust-labs/agenttrust/blob/main/docs/proofs/phase-p-llm-routing.md) |
|
|
166
|
+
| Atomic-tx invariant proof | 2026-05-07 | [`transfer-hook-atomicity.md`](https://github.com/agenttrust-labs/agenttrust/blob/main/docs/proofs/transfer-hook-atomicity.md) |
|
|
167
|
+
|
|
168
|
+
## Read next
|
|
169
|
+
|
|
170
|
+
<Cards>
|
|
171
|
+
<Card title="Kani proofs" href="/verification/kani-proofs">
|
|
172
|
+
Per-harness deep-dive — what each proof binds and what it doesn't.
|
|
173
|
+
</Card>
|
|
174
|
+
<Card title="Atomic-tx invariant" href="/verification/atomic-tx-invariant">
|
|
175
|
+
Three SDK layers + the on-chain Kani anchor.
|
|
176
|
+
</Card>
|
|
177
|
+
<Card title="Devnet smoke" href="/verification/devnet-smoke">
|
|
178
|
+
The Pay.sh + AT atomic-settlement trace, expanded with reproduction commands.
|
|
179
|
+
</Card>
|
|
180
|
+
</Cards>
|
|
@@ -1,12 +1,27 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `agenttrust_get_quantu_reputation` — read the Quantu atom_stats PDA
|
|
3
|
-
* for an agent and surface the on-chain reputation tier +
|
|
3
|
+
* for an agent and surface the on-chain reputation tier + risk fields.
|
|
4
4
|
*
|
|
5
5
|
* Quantu's atom_stats account isn't in our IDL — we fetch raw account
|
|
6
|
-
* bytes and decode the byte-offset surface PolicyVault's
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
6
|
+
* bytes and decode the byte-offset surface PolicyVault's CounterpartyTier
|
|
7
|
+
* policy reads at gate time. Source-of-truth offsets live in
|
|
8
|
+
* `programs/policy-vault/src/ext/atom_engine.rs:21-27` and are mirrored
|
|
9
|
+
* verbatim here. If Quantu changes the layout the schema-version canary
|
|
10
|
+
* at byte 560 catches it and the tool returns a clean error rather than
|
|
11
|
+
* bogus values.
|
|
12
|
+
*
|
|
13
|
+
* Tier semantics:
|
|
14
|
+
*
|
|
15
|
+
* - `tierImmediate` is the v1 fast-path tier — settled within the
|
|
16
|
+
* same `give_feedback` tx that bumped the score. Used by the
|
|
17
|
+
* CounterpartyTier policy in v1 demo mode.
|
|
18
|
+
* - `tierConfirmed` is the post-vesting tier — only counted once the
|
|
19
|
+
* vesting window elapses. Production-mode policies prefer this.
|
|
20
|
+
*
|
|
21
|
+
* Phase P found the previous implementation read fabricated offsets
|
|
22
|
+
* (40 / 41 / 49 / 50 / 51 instead of 549 / 551 / 555 / 557) which
|
|
23
|
+
* returned `tier: 164` for an actually-tier-0 agent. 0.2.6 corrects
|
|
24
|
+
* this and adds the schema-version canary the on-chain parser uses.
|
|
10
25
|
*/
|
|
11
26
|
import { z } from "zod";
|
|
12
27
|
import type { Tool } from "../types";
|
|
@@ -26,14 +41,38 @@ interface Output {
|
|
|
26
41
|
ownerProgram: string | null;
|
|
27
42
|
ownerExpected: string;
|
|
28
43
|
ownerMatches: boolean;
|
|
44
|
+
rawByteLen: number;
|
|
45
|
+
/** Set when the schema-version canary fails or the account is undersized. */
|
|
46
|
+
error?: string;
|
|
29
47
|
reputation?: {
|
|
30
|
-
tier
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
48
|
+
/** v1 fast-path tier (0..=4). The CounterpartyTier policy reads
|
|
49
|
+
* this in v1 demo mode. */
|
|
50
|
+
tierImmediate: number;
|
|
51
|
+
/** Post-vesting confirmed tier (0..=4). Production policies prefer
|
|
52
|
+
* this once vesting windows are configured. */
|
|
53
|
+
tierConfirmed: number;
|
|
54
|
+
/** 0..=255 — lower is better. */
|
|
55
|
+
riskScore: number;
|
|
56
|
+
/** Confidence in the reputation reading, basis points (0..=10_000)
|
|
57
|
+
* per Quantu's atom_engine spec; carried as a u16 here. */
|
|
58
|
+
confidence: number;
|
|
59
|
+
/** Schema version (always 1 in v1 — checked as a canary). */
|
|
60
|
+
schemaVersion: number;
|
|
35
61
|
};
|
|
36
|
-
rawByteLen: number;
|
|
37
62
|
}
|
|
63
|
+
export declare const ATOM_STATS_SIZE = 561;
|
|
64
|
+
export declare const ATOM_STATS_RISK_SCORE_OFFSET = 549;
|
|
65
|
+
export declare const ATOM_STATS_TIER_IMMEDIATE_OFFSET = 551;
|
|
66
|
+
export declare const ATOM_STATS_TIER_CONFIRMED_OFFSET = 555;
|
|
67
|
+
export declare const ATOM_STATS_CONFIDENCE_OFFSET = 557;
|
|
68
|
+
export declare const ATOM_STATS_SCHEMA_VERSION_OFFSET = 560;
|
|
69
|
+
export declare const ATOM_STATS_SCHEMA_VERSION_EXPECTED = 1;
|
|
70
|
+
export declare const ATOM_TIER_MAX = 4;
|
|
71
|
+
/** Pure-fn bytes → reputation. Returns `{ error }` when the buffer fails any
|
|
72
|
+
* canary (size, schema_version, tier-range). Mirrors the on-chain parser's
|
|
73
|
+
* fail-loud semantics — caller surfaces the error. */
|
|
74
|
+
export declare function decodeAtomStatsBytes(data: Buffer | Uint8Array): NonNullable<Output["reputation"]> | {
|
|
75
|
+
error: string;
|
|
76
|
+
};
|
|
38
77
|
export declare const getQuantuReputationTool: Tool<Input, Output>;
|
|
39
78
|
export {};
|