codexproof

Questions and answers. Asked by the authors, answered against the implementation.

The questions on this page were asked adversarially during the paper's preparation, then answered against the code and the measurements rather than from memory. The page grows as new questions survive that treatment, and the order is narrative: each answer tends to raise the next question. The paper is Provenance-Native Retrieval: A Signed, Content-Addressed Thin Waist for Agent Evidence (AgentNet workshop at IEEE ICNP 2026); the live verifier is on the front page, and highlighted terms link into the glossary.

1. Isn't this just NDN?

Deliberately close, and bounded explicitly. From the information-centric networking tradition the design keeps self-certifying data, schematized name-based trust, and verify-anywhere semantics. It drops the forwarding plane entirely: nothing here asks anyone to replace routers, and every byte travels over ordinary HTTP. What it adds is the part NDN never had: typed W3C PROV lineage fused into content addressing, so the 32-byte target of every provenance link is also the integrity commitment to its parent, plus just-in-time capture and mandatory fail-closed revocation freshness. The lineage graph and the integrity graph become one structure.

In the paper: the inherited-versus-new passage in Design, and the Related Work comparisons.

That one structure has to be made of something.

2. What exactly is one of these objects?

A small record, not a bare payload - the paper gives it four fields: a self-certifying address (the content-id), a schema-matchable name, an authenticity proof, and typed lineage. The right analogy is git: a blob is content, but a commit is the record holding the content, the parent pointers, and the authorship - and the hash everyone quotes is the commit's. These nodes are commits. The content-id is BLAKE3 over the record's canonical bytes - sorted keys and links, length-prefixed fields - so the payload and the lineage links are inside what gets named, and because every link carries the parent's content-id, one 32-byte name pins the content and its entire ancestry at once. Granularity is deliberately the producer's choice: "an evidence unit may be a corpus, document, segment, or claim."

In the paper: the evidence object in Design, and the four-fields claim in the Introduction.

A name computed from the bytes suggests nobody is keeping the books.

3. Is there a database tracking all these content-ids?

No - and the design would collapse if there were. The instinct comes from issued identifiers: most IDs are assigned by an authority that must remember the binding forever, so losing the database loses all meaning. A content-id is derived, not issued: it is computed from the bytes - the content-addressing move - so any checker recomputes the binding on demand, with no lookup, no registry, nothing to go down or be corrupted. The registrar is arithmetic, and uniqueness is BLAKE3 collision resistance doing the work a uniqueness constraint would otherwise do. Storage still exists, but as warehouse, never registry: a store shelves nodes by content-id and serves them back, and the verifier re-hashes whatever arrives. A registry can make a false binding true by asserting it; a warehouse can only lose things or serve them. That is why any mirror is exactly as authoritative as the origin, and why free riders can propagate evidence but never mint it. The only authoritative things a consumer holds are its own anchor list, and arithmetic.

In the paper: content addressing in Section II, and the verification path in Design.

If the registrar is arithmetic, verification is something you can watch.

4. How do I actually run an interrogation?

Four avenues, by decreasing infrastructure. Over HTTP, the primary path: POST a query to the gateway's /interrogate endpoint and receive the answer together with its envelope - anchors, certs, revocations, and the signed bundle - then verify offline against your own anchors. Over MCP, for agent clients: the JSON-RPC binding at /mcp exposes verify and capture as tools, so an MCP-speaking agent checks or stores provenance with no new client code (interrogation itself stays on plain HTTP by design - see question 7). From the command line, with no server at all: prov scenario emits a complete cross-domain envelope - four evidence nodes, one per store, each sealed under its own domain, and one answer citing all four by content-id - then prov inspect shows the graph, prov verify checks every node, and prov authorize walks each signer to its anchor through the fail-closed revocation gate. In the browser: the front page of this site runs the same verifier as WebAssembly.

What you see when something is wrong is the point: flip one byte anywhere in one node and re-verify - that node fails with both fingerprints printed, the claimed content-id and the actual hash, while every other store's evidence still passes; the answer's citation to the tampered node goes dangling and the completeness check names it. The verdict arrives pre-localized to the responsible store, because attribution was sealed into every node at capture.

In the paper: the capture path in Design, and the four surfaces in Deployment. Reproduce it: prov scenario | prov verify -.

Five green lights - worth being precise about what they prove.

5. Does a valid proof mean the answer is true?

No, and the paper says so in one sentence: the system verifies declared lineage, not whether the declaration is true, complete, or faithful to the producer's actual execution. A passing verification establishes that these exact bytes were sealed by a signer that a consumer-chosen anchor authorizes for that name, with the declared derivation intact and the signer unrevoked. It converts "trust me" into "check me" for custody and authorship. Whether the content deserved sealing is a different question, answerable by different machinery - execution attestation in the RATS sense composes here, and the paper cites it as the complementary rail.

In the paper: the scope sentence in the Introduction, and the threat model.

Honest scope invites the harder question of failure.

6. What breaks it?

Three ways, in descending order of concern. First, steal a domain's anchor key: the anchor cannot rotate, revocation lists are signed by the anchor, so nothing inside the system revokes the anchor itself; recovery is out-of-band re-anchoring by every consumer. This is the number-one named limitation. Second, feed it lies: the system signs what capture is handed, so a compromised producer obtains true signatures on false structure; provenance is authenticated, truth is not claimed. Third, starve it: expire or jam revocation-list distribution, skew the verifier's clock, or spam certificates into the walk fences, and consumers authorize nothing. Every availability attack converts to denial of authorization. The design's summary of that trade: denial, never forgery. You can turn the system off; you cannot make it lie.

In the paper: the threat model and Limitations.

The worst failure on that list traces to one deliberate trade.

7. Why can't trust anchors rotate?

Because anchors are did:key identities: the identifier is derived from the public key itself. That is what buys verification with no certificate authority, no registry, and no network - anyone can check that data matches its name and that a key owns its name, offline, forever. The price is that a new key is a new identity by construction. The design accepts that price at the root, keeps the anchor cold (it signs only certificates and revocation lists), and does all hot-path signing with delegated per-domain keys that can be revoked and reissued at any time.

In the paper: Design (trust plane) and Limitations.

Identity as raw key bytes leaves a human problem.

8. Where is the DNS in all of this?

Closer than it looks, in two layers. Humans never handle the key strings: hierarchical names are the human layer - /alpha/evidence/e1 reads like a path, and in production the namespace is the operator's own domain name - and certificates bind those names to keys. The real DNS-shaped question is what binds a domain's name to its anchor key, and the answer is that the anchor list is DNS with the root zone privatized to each consumer: a personal, few-line zone file mapping namespaces to did:key anchors. There is no global registry to capture, poison, or subpoena; the price is that the first binding must arrive out of band - typically fetched once from the domain's own website over ordinary HTTPS. So the old web performs the introduction exactly once: DNS introduces, the anchor list remembers, and arithmetic verifies from then on. Keys below an anchor are retired by revocation; the anchor itself leaves the list only when its consumer removes it.

In the paper: anchor discovery in Deployment, and the trust plane in Design.

Everything now leans on revocation - the part the web famously fumbled.

9. Why fail-closed, when the web soft-fails revocation?

Because the web's experience is the argument. CRLs and OCSP were neutered in practice by soft failure: responders were slow, down, or privacy-leaking, browsers proceeded on failure, and measurement studies concluded that web revocation mostly does not work. Revocation died of optional. Here the revocation list is signed as a whole set, carries a freshness window and a monotone version, and its absence or staleness means nothing authorizes - the one part of PKI everyone soft-fails is the one thing a verifier may never skip. The accepted trade is stated openly: forgery risk is exchanged for outage risk, and operations shift from intrusion detection to freshness monitoring.

In the paper: Design (revocation) and Related Work.

Severity accepted - now the blast radius.

10. When verification fails closed, does retrieval stop?

No. The fail-closed event fires at the consumer's verifier, not in the pipes: stores answer, the gateway assembles, the answer ships, and sealing even proceeds - the signing proxy's only veto is namespace, and it never reads a revocation list. What fails is the verdict: authorization returns deny, which means "here is the answer; I cannot currently vouch for its evidence." Denial of authorization is not denial of service. What happens next is consumer policy at the edge: a strict pipeline refuses to proceed, which is its chosen gate working as designed; a human may read on with the light red. The provenance toggle is the wrong lever for such an event, by design: it governs capture on the producer side, while verification belongs to consumers nobody administers. Switching capture off during a freshness outage changes nothing for a strict consumer - a missing envelope fails closed exactly like a stale one - and merely strips the layer for everyone else: the alarm silenced by unplugging the detector. Only actual freshness reopens the gate - a fresh list, restored distribution, a corrected clock.

In the paper: Design (revocation) and the threat model.

A corrected clock, because time is an input here.

11. What does clock skew do to verification?

It causes denial, never acceptance. A verifier clock running ahead makes fresh revocation lists look expired; a clock running behind makes newly issued lists look like they are from the future; a missing clock refuses authorization outright. In every direction the failure is an outage, not a forgery - a wrong clock can take a consumer offline and cannot make it trust anything. Operationally that makes time synchronization a first-class liveness concern for verifiers, alongside revocation-list freshness, and both are diagnosable from local state because verification itself is offline.

In the paper: Design (revocation freshness) and Deployment considerations.

Enough machinery has accumulated to ask who operates what.

12. Who actually runs all of this?

Three planes, three different owners. The data plane is the operator's own stores - Pinecone, pgvector, Qdrant - queried with the operator's own credentials, crypto-free. The coordination plane is a gateway that routes, fans out, and assembles, and deliberately cannot sign: its configuration surface has no key type. The trust plane lives at the edges - each domain runs its own namespace-pinned signing proxy holding its own key, and each consumer holds its own list of trust anchors and runs its own verifier, offline. Nobody administers the ring: in the paper's words, each organization runs a proxy and publishes an anchor, and whoever exposes evidence runs a gateway. Convenience is centralized; authority never is.

In the paper: the security-consequences passage in Design, and Operating across organizations in Deployment.

"Whoever exposes evidence runs a gateway" sounds alarming from the store owner's chair.

13. If anyone can run a gateway, can anyone reach my stores?

No. "Anyone can run a gateway" means any organization can operate a gateway over the estate it already controls - the protocol privileges no operator. A gateway queries data stores natively, which requires the stores' own credentials; the provenance layer adds no new access path to any backend, so an operator's billing and data exposure are exactly what they were before adopting it. What a stranger can do is run a gateway over their own stores and keys - joining the federation at their own cost - or re-serve already-published signed objects, which any host can do precisely because the receiver verifies bytes against names. Free riders can propagate evidence; they cannot mint it, and they cannot query anyone else's backends.

In the paper: Design (three planes) and Deployment considerations.

Access settled; the other worry is the bill.

14. How is the cost figure derived, and doesn't it depend on scale?

The abstract's producer-side figure (about $0.065 per million sealed nodes) is a marginal unit cost: measured resource consumption per node - CPU time for the cryptography and envelope bytes of egress - multiplied by published cloud list prices. The split is roughly $0.0002 of CPU and $0.065 of egress; shipping the roughly 700-byte envelope dominates, and the cryptography is financially invisible. Quoting it per million nodes makes the number a rate, so totals scale linearly by construction, and fixed costs are excluded because marginal cost is the scale-independent quantity. Scale bends the figure only downward: volume pricing, or deployments where envelopes never cross a metered boundary, collapse it toward the CPU floor. The figure exists to anchor one comparison: the measured fallbacks - re-embedding, LLM judging, re-derivation - cost two to five orders of magnitude more per event.

In the paper: Evaluation (unit economics); re-runnable via cargo run --release -p prov-bench.

The crypto is financially invisible; here it is physically.

15. What happens in the 15 microseconds of sealing?

Five steps, and signing is only the fourth. Serialize: the node is laid out as canonical bytes - sorted keys and links, length-prefixed fields, one deterministic layout, because you cannot hash a maybe. Hash: BLAKE3 over those bytes yields the 32-byte content-id in a microsecond or two - the node gains its name. Frame: a domain-separation tag (prov-sig:v1 and a newline) is laid in front of the content-id, pinning protocol and version so the signature can never be replayed into another context. Sign: Ed25519 over that 44-byte frame - about 11 of the 15 microseconds, and flat at any payload size, because it signs the name rather than the content. Assemble: node, content-id, signer, and signature are stapled into the sealed unit that travels. The wax metaphor is exact - pressed at the moment of sending, identifying the sender, making opening evident - and this seal binds bytes, author, and ancestry in one motion, since the lineage links ride inside the sealed bytes. The other 74 microseconds of the 88.6 figure is loopback dispatch wait, not cryptography.

In the paper: the node format and capture path in Design, and the sealing decomposition in Evaluation.

Eleven of those fifteen microseconds are one algorithm - and not the incumbent one.

16. Why Ed25519 instead of ECDSA?

Determinism, size, and speed, in that order. ECDSA requires a fresh, secret, unpredictable nonce for every signature, and a single reuse or bias hands over the private key - the failure behind the PlayStation 3 signing-key extraction and the 2013 Android wallet thefts. Ed25519 derives its nonce by hashing the secret with the message, so a broken random-number generator cannot leak the key. It also gives 32-byte keys and 64-byte signatures at about 11 microseconds per signature in this system's measurements, which matters when sealing sits on the serving path rather than on a release pipeline.

In the paper: Design (sealing) and Evaluation (capture latency).

Deterministic over "the message" - so the message deserves an exact definition.

17. What exactly does the signature sign?

Two direct inputs, and everything else transitively. Direct: the signer's 32-byte secret key, and a 44-byte framed message - the domain tag prov-sig:v1, a newline, then the content-id. Nothing else enters, and no randomness: Ed25519 derives its nonce deterministically from the secret and the message. Transitive: the content-id is BLAKE3 over the node's canonical bytes - kind, hierarchical name, attributes, links - and every link carries a parent's content-id that covered that parent's bytes and links in turn, so the recursion reaches the leaves: forty-four bytes under the pen, the whole subtree under the seal. Just as telling is the exclusion list, which reads as a threat model. No timestamp: backdating by a valid signer is a named concession, with transparency logs the patch above. No signer identity inside the message: the signer field is a verify-with-this-key claim, and authorship binds through the signature itself. No certificates or revocation lists: those are envelope siblings, separately signed, so the same node can be judged under different consumers' anchors. And no transport or request context: a sealed node means the same thing over HTTP, over MCP, in a file, or on a QR code.

In the paper: the node format in Design - the signature is over a domain-separated message containing the content-id.

A signature that travels anywhere still has to sit somewhere.

18. Does the signature wrap the object, or ride beside it?

Beside it - a detached signature, and the geometry forces the choice. The sealed unit is four sibling fields: node, content-id, signer, signature. Of the three signature architectures - enveloping, where the signature contains its payload (CMS, JWS); enveloped, where it is embedded inside the signed document (XML-DSig, a notorious bug factory, since verifying requires excising the signature first); and detached, where it sits alongside (git tags, minisign) - only detachment avoids a cycle here: the bytes determine the content-id, and the content-id is what gets signed, so a signature living inside the bytes would have to be computed over a hash of itself. Detachment also pays dividends. The content-id is signature-independent, so identical content deduplicates regardless of signer; co-signatures can be added later without renaming anything; and integrity, authenticity, and authorization remain separable checks. The nuance worth keeping: structurally appended, cryptographically ingested - the framed content-id is the signature's input, so a signature is a function of the name, never a container of it.

In the paper: the node format in Design; in the implementation, the signing call is literally sign_detached.

Everything so far has used the key; nothing yet said where it lives.

19. Where does a signing key actually live?

In exactly one process, and it never travels. A domain's leaf key is generated where it will be used, rests in the signing proxy's environment, and loads into that namespace-pinned process alone: templates go in, signatures come out, and the secret crosses no boundary. The keyless-gateway split is the custody design - the internet-facing component holds nothing by construction, and the key-holding component accepts one narrow input from inside a perimeter the paper assigns to deployment. The algorithm cooperates: Ed25519's nonces are deterministic, so signing consumes no randomness an attacker could bias. And the blast radius is layered by design: the hot key is the revocable one - pop the host, revoke the certificate, reissue, bounded by namespace and revocation latency - while the unrevocable anchor stays cold, off the request path, signing only certificates and revocation lists. Within the proxy, the secret is as safe as its host: the paper defines the interface and leaves the backing - environment variable, keyring, KMS, hardware module - as an operator's ladder, with the hardware rung explicitly accommodated.

In the paper: the capture path and security consequences in Design, and the HSM note in Deployment.

Keys settled; what remains is the integration bill.

20. What does adopting it actually require?

Per producer stack: one emit-as-node shim. Per consumer: one verifier, native or WebAssembly - the same crate either way. That is the whole integration surface, and it is the point of a shared object: in the paper's words, without one, every distinct producer stack can require a separate interface to every consumer; with it, each stack writes one shim and each consumer uses one verifier. The object standardizes the mechanism, not the trust decisions - anchors stay per-domain. Nothing changes in the stores (the waist sits above them), nothing changes in the network (plain HTTP carries everything), and the only out-of-band step is obtaining a domain's anchor once, after which verification never needs the network again.

In the paper: the shared-object argument in Section II, and anchor discovery in Deployment.

Notice what the adoption list never mentioned: a required protocol.

21. Does the design require MCP?

No, and it would undermine the thesis if it did. The service is an ordinary HTTP server; MCP is one JSON-RPC binding at one route, exposing verify and capture so MCP-speaking agents integrate with zero new client code. Interrogation itself is plain HTTP, discovery for non-MCP frameworks is an A2A agent card at the well-known path, and verification needs no transport at all - the offline CLI and the browser WebAssembly verifier check the same envelope. The waist is the signed, content-addressed evidence object, not any protocol above it; a waist that only worked through one protocol would be a socket.

In the paper: Design (surfaces) and the thin-waist discussion.

This page is maintained by the authors and grows as new questions survive adversarial answering. Front page: the in-browser verifier. Contact: via the paper's author information.