agent-scroll 0.1.0

Canonical byte-deterministic transcript format for AI-agent conversations (Rust port of @p-vbordei/agent-scroll)
Documentation

agent-scroll (Rust)

CI Spec License

Idiomatic Rust port of @p-vbordei/agent-scroll. Canonical byte-deterministic transcript format for AI-agent conversations. Same RFC 8785 JCS bytes, same SHA-256 hashes, same Ed25519 signatures as the TypeScript reference — verified by 20 byte-equality vectors plus mutation, roundtrip, and chain-tamper tests.

A scroll is an ordered chain of sealed turns. Each turn is a normalized serde_json::Value ({version, turn, role, model, params, messages, ..., timestamp_ns, prev_hash?}) serialized via JCS, SHA-256 hashed, optionally Ed25519-signed, and linked to its predecessor by prev_hash. Any byte flip — in body, hash, signature, or chain order — is detectable.

What's in the box

  • canonical(&Value) — RFC 8785 JCS bytes (with a u64 → f64 normalization pass; see Architecture)
  • hash_canonical(&Value)sha256:<hex> string
  • seal(&turn, sign) — produce a sealed Value (hash + optional Ed25519 signature)
  • seal_chain(&[Value], sign) — chain-linked sealed turns, each carrying prev_hash
  • verify(&[Value], pubkey) — schema + hash + chain link + signature
  • serialize / deserialize — round-trip via canonical bytes
  • validate_turn / validate_sealed_turn — explicit role / tool-call schema checks

Install

[dependencies]
agent-scroll = "0.1"

Quickstart

See examples/quickstart.rs. Build three turns, seal-and-sign as a chain, verify, then mutate a byte and watch verify fail:

cargo run --example quickstart

Expected output:

sealed 3 turns, all hashes set
verify clean: ok=true
verify tampered: ok=false reason=BadHash

How it relates

Port Source Same vectors
agent-scroll TypeScript reference
agent-scroll Python C1–C4 + 20 byte-equality
agent-scroll (this repo) Rust C1–C4 + 20 byte-equality

Conformance

This port is verified against the same fixture set as the TypeScript reference:

  • C1 — byte equality across 20 vectors (the gold standard). Canonical bytes of each fixture must hex-match the TS output.
  • C2 — single-byte mutation in hash or body MUST fail verify.
  • C3serializedeserialize roundtrip is byte-stable.
  • C4 — chain tamper / reorder MUST fail verify.
cargo test

Fixtures in fixtures/ (c1-hex.json carries the expected hex per vector) and the 20 wire-format vectors in vectors/ are copied verbatim from the TS conformance suite.

Architecture

See docs/architecture.md for module map, dependency choices, and the critical serde_jcs u64-precision workaround (timestamp_ns is a u64 larger than 2^53, which serde_jcs doesn't coerce to f64 as RFC 8785 mandates — we normalize numbers manually in canonical.rs).

Development

git clone https://github.com/p-vbordei/agent-scroll-rs
cd agent-scroll-rs
cargo test
cargo run --example quickstart

License

Apache-2.0 — see LICENSE.