# agent-action-capsule (Rust)
Reference verification for the Agent Action Capsule, the Rust sibling of the
Python reference and the Go and TypeScript implementations in
[action-state-group/agent-action-capsule](https://github.com/action-state-group/agent-action-capsule).
It is checked against the same conformance vectors, and CI verifies Python-,
Go-, TypeScript- and Rust-sealed capsules in every implementation.
| `canonical` | RFC 8785 JCS, JSON-DIGEST and `capsule_id` | `go/canonical` |
| `registries` | the profile registries, from an embedded `spec/REGISTRY.md` | `go/registries` |
| `verify` | Class 1 verification (checks 1-9) and the store checks | `go/verify` |
| `envelope` | Producer Envelope (COSE_Sign1 over the Capsule ID), a record's producer signature | `go/envelope` |
| `bundle` (feature `bundle`) | Evidence Bundle v2 codec and verifier; `verify_bundle_strict` with feature `strict` | `go/bundle` |
| `witness` (feature `strict`) | witness receipts (`cll`, `rekor`, `scrapi`) in `checkpoint.witnesses` | Python `witness` |
| `settlement` (feature `settlement`) | two-party settlement records (`draft-mih-agent-settlement-records-00`) | Python `settlement` |
```rust
use agent_action_capsule::verify::{decode_capsule_json, verify};
let capsule = decode_capsule_json(bytes)?;
let result = verify(&capsule, None);
if result.ok {
println!("{}", result.capsule_id.unwrap_or_default());
}
```
Decode capsules with `decode_capsule_json`, a strict RFC 8259 decoder.
Numbers are kept as written (`serde_json`'s `arbitrary_precision` feature), so
a float or an out-of-range integer is reported by check 1 instead of being
rounded away. `serde_json::from_slice` is not a substitute: with that feature
it turns an object holding `serde_json`'s private number token into a number,
which changes the Capsule ID. Cargo unifies features, so
`arbitrary_precision` applies to every `serde_json` user in a build that
depends on this crate.
The `bundle` feature adds `checkpointed-local-log`, which also carries an HTTP
witness client; record verification does not need it.
The `strict` feature (which includes `bundle`) adds
`bundle::verify_bundle_strict`, the checks a verifier needs before it tells a
person that a Bundle is VALID: each record's producer signature, the
checkpoint read only from its signed COSE form, producer-selected Bundles, the
`disclosures` overlay as one claim, and the witness receipts in
`checkpoint.witnesses` under a witness directory the caller supplies (none is
trusted by default). Its result carries a `VALID`, `INCOMPLETE` or `INVALID`
verdict; the plain `verify_bundle` is unchanged. It adds
`scitt-cose-receipt`, `coset` and `p256`. `vectors/bundle/strict/README.md`
describes every rule.
```rust
use agent_action_capsule::bundle::{verify_bundle_strict, StrictOptions};
let result = verify_bundle_strict(&bundle, &StrictOptions {
require_signature: true,
witness_directory: Some(&directory),
});
println!("{}", result.verdict());
```
The `settlement` feature adds `settlement::verify_settlements`, which derives
payment and delivery states from both parties' leg records.
Not yet in Rust: Disclosure Envelopes, composed bundles, and the emitter and
presentation layers.
## Development
From `rust/`:
```sh
cargo fmt --check
cargo clippy --locked --all-targets --all-features -- -D warnings
cargo test --locked --all-features
```
The tests read `../../vectors/`, `../../provenance-mode-vectors/` and
`../../spec/REGISTRY.md`. `data/REGISTRY.md` and `data/cpb_provisional.json`
are byte copies of `spec/REGISTRY.md` and
`python/agent_action_capsule/data/cpb_provisional.json`; the `drift` test
fails until a changed source is copied over.
Licensed under BSD-3-Clause.