Agent platforms log actions, not sources. A workspace agent's audit trail records that it posted a report or updated a row, and records nothing about the documents it consulted to decide — so the answer cannot be reconstructed and a reviewer cannot tell grounding from invention. Where citations exist they are convenience links: a URL in rendered output, unbound to the answer, unsigned, and unaffected if the thing it points at changes or is deleted. This crate makes a citation checkable. Three properties, each a method rather than an assurance, drawn from the three gaps a recent survey of the field documented in the incumbents' own words: 1. Sources read are recorded, in read order — the artifact an actions-only log cannot produce. 2. A citation cannot outlive its referent. Each source is bound by CONTENT ID, not a locator: edit or delete the source and verify_source() fails, so the citation is verifiably dangling instead of silently pointing at whatever is there now. A URL cannot do this; a hash can. verify_answer() pins the answer the same way. 3. A citation says who may read it. Each source records the grant it was read under, so unreadable_by() names exactly which sources a given reader is not cleared to open — because an agent reads under its own grants, not its invoker's, so a citation can legitimately point at content the reader cannot see. Name the gap rather than hand over a link that fails (or wrongly works). It carries the retrieval's joules, so grounding an answer is accounted like any other work. Composition (the point): a Citation is content-addressed and its id IS the retrieval frame's payload_hash, so the jcp/2 receipt (SPEC §8) commits it. The receipt proves the retrieval was authorized, gated and metered; the citation records what it consulted; the receipt binds the two, and neither is trusted alone. Tested end to end: the sealed receipt's payload_hash equals the citation's id and cannot be swapped for another. New crate, additive; no change to existing crates beyond the workspace member list. 44 suites green, clippy clean, runnable example. Co-Authored-By: Claude Opus 4.8 <[email protected]>
51 lines
1.2 KiB
TOML
51 lines
1.2 KiB
TOML
[workspace]
|
|
resolver = "2"
|
|
members = [
|
|
"crates/jcp-schema",
|
|
"crates/jcp-grant",
|
|
"crates/jcp-runtime",
|
|
"crates/jcp-receipt",
|
|
"crates/jcp-bridge",
|
|
"crates/jcp-energy",
|
|
"crates/jcp-wire",
|
|
"crates/jcp-threshold",
|
|
"crates/jcp-channel",
|
|
"crates/jcp-conformance",
|
|
"crates/jcp-cli",
|
|
"crates/jcp-gateway",
|
|
"crates/jcp-trace",
|
|
"crates/jcp-a2a",
|
|
"crates/jcp-x402",
|
|
"crates/jcp-cite",
|
|
"crates/jcp-policy",
|
|
"crates/jcp-prompt",
|
|
"crates/jcp-orchestrate",
|
|
"crates/jcp-intercept",
|
|
"crates/jcp-efficiency",
|
|
]
|
|
|
|
[workspace.package]
|
|
version = "0.1.0"
|
|
edition = "2021"
|
|
license = "Apache-2.0"
|
|
repository = "https://github.com/transaction-science/open-standards"
|
|
rust-version = "1.85"
|
|
|
|
[workspace.dependencies]
|
|
jcp-schema = { path = "crates/jcp-schema" }
|
|
jcp-grant = { path = "crates/jcp-grant" }
|
|
jcp-runtime = { path = "crates/jcp-runtime" }
|
|
jcp-receipt = { path = "crates/jcp-receipt" }
|
|
jcp-bridge = { path = "crates/jcp-bridge" }
|
|
jcp-energy = { path = "crates/jcp-energy" }
|
|
|
|
blake3 = "1"
|
|
ed25519-dalek = { version = "2", features = ["rand_core"] }
|
|
bs58 = "0.5"
|
|
serde = { version = "1", features = ["derive"] }
|
|
serde_json = "1"
|
|
hex = "0.4"
|
|
thiserror = "2"
|
|
|
|
[workspace.lints.clippy]
|
|
all = "warn"
|