Capabilities · 6. Evidence

A receipt is a verifiable record of what was stored and retrieved. It is not an attestation of what an agent did. Every capability in this chapter sits underneath that sentence, and this chapter exists as much to draw the boundary as to describe what is inside it.

This chapter is Explanation. It says why the evidence subsystem is shaped the way it is, what each part changes for a person who has to answer to someone else, and what each part does not establish. It does not restate the verification checks, the receipt kind table or the route list; those are in Receipts and proof and the receipts API plane, and each explainer points at the section that holds the detail.

The standing rails, stated once and applied throughout. Execution receipts are Ed25519-signed and chained. Retrieval receipts are BLAKE3 content-addressed and are not signed. These are two different guarantees and they must never be collapsed into one. Every field inside a receipt is supplied by the client and is a self-report. An operator holding the signing key can forge receipts freely. There is no global receipt chain: chaining is per session, so truncating a chain or deleting a whole chain is undetectable, because there is no signed tip anywhere that would notice the absence. Several of the receipt classes below default off, and one is never emitted at all.

That is a lot of negative space, and stating it is deliberate. The parts of this subsystem that do work are genuinely strong: an offline audit bundle verified by an independently written implementation is a real, checkable artefact. The parts that do not work are named here rather than left for a reader to discover.

CapabilityWhat it establishesStatus
6.1Observation chainThis session's records were not reordered or edited in placeSHIPPED
6.2Mediation, usage and consolidation receiptsThat a call, a stream or a consolidation was recordedPARTIAL; main classes default off
6.3Receipt verificationThese bytes carry a valid signature over this bodyLibrary SHIPPED; MCP tool FLAG, default off
6.4Audit bundles and replay exportAn offline third party can check this bundle unaidedSHIPPED; MCP tool FLAG, default off
6.5Content provenance on outputA signed credential travels with an outputFLAG, default off
6.6Transparency-log anchoringNothing, in this buildNOT ACTIVE
6.7Observe-audit step graphA typed record of a run's stepsFLAG, default off
6.8Activity journalA human-legible per-turn narrative, verifiable per turnFLAG, default off
6.9Incident recordsA filed, exportable incidentFLAG, default off
6.10Acknowledged memory useWhich facts an agent says it consultedFLAG, default off; receipt not wired
6.11Scoped forgetThat content was deleted, to whoever holds the responseFLAG, default on
6.12Session handshakeWhich capabilities this caller actually hasSHIPPED
6.13Posture self-auditThe daemon's own account of its configurationSHIPPED

6.1 The hash-chained observation journal

Status · SHIPPED · Reached through · POST/GET /v1/sessions/{id}/observations, /batch, GET /v1/observations/aggregate · MCP list_observations, get_observation, verify_observation · Who it is for · both

What it does. Every observation a session writes is appended to a per-session chain of newline-delimited records, and each record commits to the previous record's body hash. Because the commitment is over content rather than position, reordering records, inserting one in the middle or editing a single record's body all break the chain and are detectable by validate_chain (observations.rs:1033) without holding any key.

Why it works this way. The design goal was tamper-evidence that a reader can check with no secret material. A signature-only scheme proves who wrote a record but tells you nothing about whether records were removed from between two others; a hash chain gets you ordering integrity for free and, critically, gets it for a party who does not trust the daemon and holds none of its keys. The choice to keep one chain per session rather than one global chain was made for concurrency: a single global chain serialises every writer in the process and turns a busy fleet into a queue. That choice has a direct evidential consequence, stated below, and it is the most important limit in this chapter.

What changes for you.

  • As an operator: you can hand a session's observation file to someone who does not trust you, and they can establish for themselves that its records are in the order they were written and that none was edited.
  • As an agent: observations are an append surface with no read-modify-write, so writing one is cheap and never contends with a peer.

What it does not do.

  • Truncation is undetectable, and so is deleting a whole chain. There is no signed tip and no external commitment, so removing the last N records leaves a chain that still validates perfectly, and removing a session's file entirely leaves nothing that notices it is gone.
  • There is no global chain. Chains are per session and unrelated to one another, so the absence of an entire session's evidence is not visible from any other session's chain.
  • It does not establish what happened. A chain shows that the records it holds have not been reordered or edited. The records themselves are what the session chose to write.

Where the detail lives. Daemon §13.3 for the three unrelated chaining mechanisms and why there is no global one; API §2.2 for the routes and what is hashed.

6.2 Mediation, usage and consolidation receipts

Status · PARTIAL, and the main classes default off · stream receipts CORECRUXD_STREAM_RECEIPTS, default false · usage receipts CORECRUXD_FEATURE_USAGE_RECEIPTS, default false · Reached through · POST /v1/mediation/receipts, GET /v1/receipts/list · Console → Trust › Receipts, Trust › Mediation · Who it is for · human

What it does. These are signed CBOR bodies recording that a model call happened, which context hash entered it, how the stream terminated, and separately that a consolidation collapsed a set of facts (consolidation_receipt.rs:41). Both of the main classes are off by default: stream receipts behind CORECRUXD_STREAM_RECEIPTS, default false, and usage receipts behind CORECRUXD_FEATURE_USAGE_RECEIPTS, default false. Consolidation receipts are minted best-effort.

Why it works this way. Recording the context hash rather than the context is the design decision that makes this class usable at all. Storing the prompt would make every receipt a copy of your data, with the retention, residency and erasure problems that implies; storing a hash of it lets you demonstrate later that a specific context was the one that entered a specific call, without the receipt itself carrying anything sensitive. The same reasoning produces the metadata-only adoption pings, which are designed so that they provably cannot carry content. The reason the classes default off is that a receipt on every model call is a real write-amplification cost on a busy fleet, and the project's position is that evidence you did not ask for should not be silently charged to you.

What changes for you.

  • As an operator: with the flags on, "did that call happen, and what went into it" has a signed answer that does not require you to have kept the prompt.
  • As an agent: nothing. These are minted by the daemon around calls; an agent does not write them.

What it does not do.

  • They are off unless you turn them on. A daemon in its default configuration is not minting stream or usage receipts, and an empty receipt list is the expected state rather than a fault.
  • Every field is a client-supplied self-report. The daemon signs what it was told. A receipt saying a call used a particular model is a record of that assertion, not an independent observation of the call.
  • Consolidation receipts are best-effort. A consolidation that happened without one is not an anomaly.
  • A signature over these bodies is made with the daemon's own key. An operator holding that key can produce any of these records at will.

Turn it on. CORECRUXD_STREAM_RECEIPTS=1 for stream receipts and CORECRUXD_FEATURE_USAGE_RECEIPTS=1 for usage receipts. Both default false.

Where the detail lives. Daemon §13.9 for every receipt kind and which are actually minted; API §2.3 for the routes.

6.3 Receipt verification

Status · Library SHIPPED · MCP tool behind CORECRUXD_FEATURE_RECEIPT_VERIFY, default off · the receipt keyring environment variables are DECLARED-NOT-WIRED · Reached through · MCP receipt_verify · GET /v1/receipts/{id}, /signature, /verification · corecruxctl audit-verify, receipts verify-cose, output-verify · Who it is for · both

What it does. Verification runs fourteen ordered checks over a receipt's exact stored bytes, ending in an Ed25519 strict signature check, and returns a report that names every check's result rather than stopping at the first failure. Twelve outcome codes are defined, eleven of them distinct failure modes, so a failure is diagnosable rather than merely negative. The MCP tool sits behind CORECRUXD_FEATURE_RECEIPT_VERIFY, default off; the library and the CLI paths do not.

Why it works this way. Three design decisions are worth understanding, because each one is a deliberate choice against an easier alternative.

The first is bytes-first. Verification runs over the bytes as stored, never over a re-serialisation of a parsed structure. The easier design parses the receipt, re-encodes it and checks the signature over the re-encoding, and it is subtly wrong: it verifies your serialiser rather than the artefact, and it will happily validate a receipt whose stored bytes differ from what was signed in ways your parser normalises away.

The second is the total report. A first-failure verifier answers "is this valid" and nothing else. An auditor's real question is "what exactly is wrong with this", because the answer determines whether they are looking at bit rot, a wrong key or an actual forgery. Running every check and reporting all of them costs a little more and answers the question that gets asked.

The third follows from the second and is the one people find surprising: a receipt with a bad body hash still gets its signature checked and reported. A naive implementation short-circuits, because why check a signature over a body you already know is wrong. But then corrupt storage and a bad signature produce the same output, and those two conditions call for completely different responses. Keeping them distinguishable is worth the extra work.

What changes for you.

  • As an operator: a failed verification tells you which of fourteen properties failed, so an incident starts from a fact rather than from a hypothesis.
  • As an agent: with the flag on, an agent can verify a receipt it was handed before acting on it, rather than trusting the surface that handed it over.

What it does not do.

  • The HTTP verification route is self-attesting. It builds its keyring from the daemon's own passport key (receipts.rs:466), so a pass means "these bytes carry a valid signature by this daemon" and nothing more. It is not an independent check, and it cannot be, because the verifier and the signer are the same party. For an independent check, use the offline path in 6.4.
  • The receipt keyring configuration is declared and not wired. The keyring path, keyring JSON and verify-enabled environment variables exist as configuration but do not reach a verifier.
  • Verification says nothing about the recorded event. It establishes that these bytes were signed by that key and have not changed since. Whether the thing the receipt describes actually happened is outside what a signature can carry, and an operator holding the key can sign a description of something that never occurred.

Turn it on. CORECRUXD_FEATURE_RECEIPT_VERIFY=1 for the MCP tool. Default off. The library and CLI paths are always available.

Where the detail lives. Daemon §13.8 for every check in order and every error code; Daemon §13.14 for the boundary in full.

6.4 Evidence export: audit bundles and replay

Status · Bundle export and verification SHIPPED · MCP tool behind CORECRUXD_FEATURE_AUDIT_EXPORT, default off · several replay routes return 501 in the community edition · Reached through · MCP audit_export_bundle · POST /v1/audit/bundle/verify, GET /v1/replay/exports/... · corecruxctl audit-verify, audit-pack · Who it is for · human

What it does. An audit bundle is a compressed archive whose manifest is domain-separated, key-canonicalised and Ed25519-signed, and which carries the verifying public key inside the signed payload. It can be verified offline, with no daemon and no network, by a separately written Python verifier that continuous integration runs against committed test vectors. Alongside it sit per-answer, per-action, per-receipt and per-stream replay exports.

Why it works this way. This is the strongest part of the evidence subsystem, and the reason is that it was built to be checked by someone who does not have the software. Domain separation stops a signature over one kind of object being replayed as a signature over another. Key canonicalisation removes the class of bug where two serialisers disagree about map ordering and produce different bytes for the same content. And the independent Python implementation is the load-bearing choice: a verifier written from the specification, in a different language, by different code, catches the ambiguities that a shared library hides from itself. Running it in CI against committed vectors is what stops the specification and the implementation drifting apart quietly.

What changes for you.

  • As an operator: you can hand a regulator, a client or an auditor a file and a verifier and let them check it without access to your systems, your network or your account.
  • As an agent: with the flag on, an agent can produce the bundle itself rather than routing an evidence request through a person.

What it does not do.

  • The bundle is self-consistent, not self-authenticating. The public key travelling inside the signed payload means anyone can check the manifest is internally intact and unmodified since signing. Establishing that the key is yours is a separate step, out of band, against a trust root you publish; without it, a bundle proves only that whoever made it signed it consistently.
  • It carries the same content limits as everything else here. A verified bundle establishes that the records inside it are the records that were signed. It does not establish that they describe what happened.
  • Several replay export routes return 501 in the community edition. A 501 is the honest answer that the surface is not present in this build, not a fault.

Turn it on. CORECRUXD_FEATURE_AUDIT_EXPORT=1 for the MCP tool. Default off. Bundle verification and the CLI export path do not need it.

Where the detail lives. Platform §5.6.1 for how to verify a bundle yourself, offline, with the independent implementation; Daemon §13.10 for the tamper test and exactly what it proves; API §4.3 for the verify route.

6.5 Content provenance on output

Status · Output attestation behind CORECRUXD_FEATURE_C2PA_OUTPUT, default off · the provenance gateway behind CORECRUXD_FEATURE_PROVENANCE_API, default off · Reached through · MCP output_attest · POST /v1/provenance/sign, /verify, /verify-record · corecruxctl output-verify, c2pa-verify · Who it is for · human

What it does. Two separate things, both default off. Behind CORECRUXD_FEATURE_C2PA_OUTPUT, default off, a signed content credential can be attached to an agent's output. Behind CORECRUXD_FEATURE_PROVENANCE_API, default off, a bring-your-own-key gateway signs, verifies and records provenance manifests without the daemon ever holding your key.

Why it works this way. The two are deliberately separate because they answer different questions: the first is "did this output come from my agent", the second is "can I run a provenance workflow on my own key material without handing it over". The gateway's flag is the only one in the daemon that unmounts its routes rather than returning a disabled response, and that is a considered security choice: a route that exists and refuses still has code paths that touch key material, and the strongest guarantee that no key was read is that nothing capable of reading one was ever mounted.

What changes for you.

  • As an operator: an output can travel with a credential that survives being copied out of your systems, and the key that signs it can remain yours.
  • As an agent: with the output flag on, attestation is one call at the point of producing the output rather than a later re-processing step.

What it does not do.

  • A mainstream C2PA viewer cannot validate these manifests. Doing so requires a published platform trust anchor, and there is not one; a manifest that fails in a third-party viewer is failing for that reason, not because it is malformed.
  • The content hash is BLAKE3, not SHA-256 (c2pa_manifest_v1.rs:328), which is a deliberate divergence from mainline C2PA and a real interoperability constraint.
  • It attests the bytes, not the conduct. A credential says this output was signed by this key over this content. It says nothing about how the content was produced.

Turn it on. CORECRUXD_FEATURE_C2PA_OUTPUT=1 for output attestation, CORECRUXD_FEATURE_PROVENANCE_API=1 for the gateway. Both default off.

Where the detail lives. API §4.4 for the gateway routes and the key custody model; API §12.8 for output_attest.

6.6 Transparency-log anchoring

Status · NOT ACTIVE. CORECRUXD_WITNESS_ENABLED is false, CORECRUXD_TSA_ENABLED is false, and the feature is unreachable in this build regardless of either · Reached through · GET /v1/witness/smoke · corecruxctl receipts witness-smoke, verify-external-anchor, verify-rfc3161-timestamp · Who it is for · human

What it does. Anchoring receipts into an external transparency log is not active. Both flags are false, and enabling them is not sufficient: the only path that enqueues anything for submission requires the data-plane pool, which the community edition hard-codes to absent (main.rs:565). What is built and does work is the other half: rigorous verification of RFC 6962 inclusion proofs and RFC 3161 timestamp tokens that somebody else produced.

Why it works this way. Anchoring is the control that would fix the largest hole in 6.1: with an external commitment to a chain's tip, truncation stops being undetectable, because the log remembers a tip you can no longer produce. That is exactly why the verification half was built first and built properly. Verification is the part that has to be correct and the part a third party depends on; the submission half is operationally entangled with a data plane the community edition does not ship. Building verification first also means that when anchoring becomes reachable, its output is checkable by machinery that already exists and is already tested.

What changes for you.

  • As an operator: you can verify an inclusion proof or a timestamp token that another system produced, today. You cannot anchor your own receipts, in this build, by any configuration.

What it does not do.

  • A green /v1/witness/smoke means "witnessing is off", not "anchoring works". This is the single most misread signal in the subsystem. Do not treat that endpoint as evidence of an anchoring capability.
  • Turning either flag on changes nothing, because the enqueue path is unreachable in this edition.
  • Because nothing is anchored, the truncation limit in 6.1 stands in full and is not mitigated anywhere in this build.

Where the detail lives. Daemon §13.11 for why it is unreachable and what the smoke route actually reports; Daemon §13.12 for the correction this forces on the shipped threat model.

6.7 The observe-audit step graph

Status · FLAG CORECRUXD_OBSERVE, default off · Reached through · POST /v1/observe/sessions/{id}/steps, PATCH .../steps/{node}, GET .../audit, .../audit/conformance, .../audit/export · Who it is for · both

What it does. Behind CORECRUXD_OBSERVE, default off, a run can be captured as a typed graph of steps rather than as a flat log (observe_audit.rs:274), with configurable redaction on what the steps carry. It can then be read back as an audit view, checked for conformance and exported.

Why it works this way. A flat log tells you what happened in order; a step graph tells you what depended on what, which is the question you have when a run went wrong three branches deep. The typed shape is what makes a conformance verdict possible at all: you cannot mechanically check "did this run follow the expected shape" against unstructured text. Redaction is a mode on capture rather than a filter on read, which is the safer ordering: content that is never captured cannot leak from a store that is later exported or copied. The reason this defaults off is cost. Capturing a step graph is a write per step, and most runs do not need one.

What changes for you.

  • As an operator: a run becomes an inspectable structure with a conformance verdict, rather than a transcript you read hoping to spot the branch that went wrong.
  • As an agent: steps are opened and updated explicitly, so the graph reflects what the agent declared, at the granularity the agent chose.

What it does not do.

  • It captures what it is told. The graph is written by the run being observed, so it is a self-report with the same standing as everything else in this chapter.
  • A conformance verdict is a check against a declared expectation, not an independent judgement of whether the run was correct.
  • With the flag off the routes are not a partial capability; there is no graph being captured in the background.

Turn it on. CORECRUXD_OBSERVE=1. Default off. Redaction is configured separately.

Where the detail lives. API §4.5 for the step routes, the redaction modes and the conformance response.

6.8 The activity journal

Status · FLAG CORECRUXD_FEATURE_ACTIVITY_LOG, default off · Reached through · MCP activity_recent · POST/GET /v1/activity, GET /v1/activity/turn/{id}, .../verify · Console → Work › Activity · Who it is for · both

What it does. Behind CORECRUXD_FEATURE_ACTIVITY_LOG, default off, the journal records a per-turn narrative of what happened, readable back by turn and verifiable per turn against a named signer (activity.rs:345). It is the human-legible complement to the receipt chain: prose a person can read, with a verification step attached.

Why it works this way. The receipt subsystem is optimised for machine verification and is close to unreadable by design; canonical bytes are not prose. But the person who most needs to know what an agent did is usually reading, not verifying. Rather than making receipts friendlier, which would have compromised their canonical form, the journal is a parallel surface with its own shape: legible first, with verification available per turn for the cases where legibility is not enough. The trade-off is duplication, and it is accepted knowingly, because collapsing the two would have produced an artefact that is bad at both jobs.

What changes for you.

  • As an operator: the console shows a rolling log you can actually read, and any individual turn can be checked rather than trusted.
  • As an agent: activity_recent gives a bounded read of what has just happened, including work done by peers.

What it does not do.

  • It is off by default, and entries have a configurable time-to-live, so the journal is a recent-history surface rather than a permanent record.
  • Per-turn verification checks a turn's signature. It does not chain turns together, so it carries none of the ordering guarantees in 6.1.
  • The narrative is written by the participants. It is a self-report, in prose, and prose is easier to write misleadingly than canonical bytes.

Turn it on. CORECRUXD_FEATURE_ACTIVITY_LOG=1. Default off. Retention is set separately.

Where the detail lives. API §2.4 for the routes and the verify response; Operations §3.8 for the console view and its two limits.

6.9 Incident records and export

Status · FLAG CORECRUXD_FEATURE_INCIDENTS, default off · Reached through · POST/GET /v1/incidents, GET /v1/incidents/{id}, POST /v1/incidents/{id}/export · corecruxctl incident · Who it is for · human

What it does. Behind CORECRUXD_FEATURE_INCIDENTS, default off, an incident is filed with its symptom, cause, fix and reproduction steps (incidents.rs:853) and can be exported as a portable record.

Why it works this way. Incidents are usually written in the tracker the humans use, which means the agents that will hit the same failure next month cannot read them. Filing them into the substrate puts the cause and the fix where a cold-start agent will find them, alongside everything else it recalls. The fields are fixed rather than free-form for a specific reason: an incident without reproduction steps is an anecdote, and requiring the shape is how you avoid a store full of anecdotes. It defaults off because a fleet that does not intend to use the field structure is better served leaving it absent than half-populated.

What changes for you.

  • As an operator: a post-mortem lands where both people and agents look, and exports as a record you can send elsewhere.
  • As an agent: a past incident is recallable at the moment you are about to reproduce it.

What it does not do.

  • It does not detect incidents. Filing is deliberate; nothing infers an incident from behaviour.
  • An incident record is a description, not evidence. It is not signed, and it carries no relationship to the receipt subsystem.
  • With the flag off, the routes are not present.

Turn it on. CORECRUXD_FEATURE_INCIDENTS=1. Default off.

Where the detail lives. API §4.6 for the record shape and the export route.

6.10 Acknowledged memory use

Status · FLAG CORECRUXD_FEATURE_MEMORY_ACK, default off · the memory_use receipt class is DECLARED-NOT-WIRED and is never emitted · Reached through · MCP memory_acknowledge_use · Who it is for · agent

What it does. Behind CORECRUXD_FEATURE_MEMORY_ACK, default off, an agent declares which stored facts it actually consulted for a turn. Read the status line carefully before relying on this: the receipt class designed to carry that declaration has no production emitter. The tool buffers in process and returns a synthetic identifier (memory_use.rs:230) that dereferences to nothing.

Why it works this way. The capability is aimed at a genuinely hard question: when an agent produced an answer, which of the things it remembered did it lean on. Nothing can observe that from outside the model, so the honest design is to have the agent say so, and to be explicit that the resulting record is a declaration rather than an observation. That is why this was built as an acknowledgement rather than as inferred provenance: an inferred answer would have looked stronger and been less true. The receipt half is specified and is not wired, and that gap is stated here rather than left to be discovered from an identifier that resolves to nothing.

What changes for you.

  • As an agent: with the flag on you can declare what you used, and that declaration is visible in process for the current turn.
  • As an operator: treat this as a development-stage surface. Do not build an audit process on it, because the returned identifier does not resolve to a stored receipt.

What it does not do.

  • It does not mint a receipt. The memory_use class is never emitted, so there is nothing durable, nothing signed and nothing to verify.
  • The returned identifier dereferences to nothing. It is synthetic, and looking it up will not find a record.
  • Even fully wired, it would be a self-report. An agent's account of what it consulted is not independently checkable.

Turn it on. CORECRUXD_FEATURE_MEMORY_ACK=1. Default off, and the limits above apply with the flag on.

Where the detail lives. Daemon §13.14 for where this sits in the boundary; API §12.7 for the tool.

6.11 Scoped forget

Status · FLAG CORECRUXD_FEATURE_SCOPED_FORGET, default on · the dry run is always available · Reached through · MCP memory_forget, memory_forget_dry_run · Who it is for · human

What it does. Behind CORECRUXD_FEATURE_SCOPED_FORGET, default on, a named scope of memory is deleted, and a dry run (forget.rs:316) shows exactly what would go before anything does. This is the tool a data-subject erasure request reaches for.

Why it works this way. Erasure is the one operation where "roughly right" is not acceptable in either direction: deleting too little fails the request, deleting too much destroys work. So the dry run is not an optional convenience, it is the primary interface, and it is available regardless of whether the destructive half is enabled. Making the preview unconditional means an operator can always answer "what would this remove" without needing the permission to remove it.

What changes for you.

  • As an operator: an erasure request becomes an enumerable, reviewable operation with a preview you can attach to the request record.
  • As an agent: nothing. This is an operator surface.

What it does not do.

  • The forget receipt is unsigned and unpersisted. Only the caller holding the response holds the proof that the content existed and was removed. If you need that proof, capture the response; nothing stores it for you.
  • Deletion here is the soft-delete half of erasure. Content leaves disk when compaction rewrites the journal, which is a separate operation.
  • The tool's own description misstates its flag default. The flag is on by default; treat the tool's text as the drifted artefact, not the behaviour.

Turn it on. On by default via CORECRUXD_FEATURE_SCOPED_FORGET. The dry run does not depend on it.

Where the detail lives. API §12.9 for both tools and the response shape; API §15.2 for the documented flag-default drift.

6.12 Session handshake and invocation verify

Status · SHIPPED, both public routes · Reached through · MCP cuecrux_session · POST /session, POST /invocation/verify, GET /v1/sessions/{id}/plan · Who it is for · agent

What it does. Opening a session returns a typed capability plan (session.rs:358): which retrieval, proofing, memory, journaling and audit capabilities this caller actually has. A legacy route verifies an invocation.

Why it works this way. Most of the capabilities in this chapter are flag-gated, and several are off by default. A caller that cannot tell which are present has two bad options: probe every surface and interpret the errors, or assume and fail late. The handshake makes the answer explicit and, importantly, makes it typed, so a harness can branch on it rather than parse it. This is the same reasoning as the autonomy contract in chapter 4, applied to evidence capabilities rather than to permission: knowing your own configuration is cheaper than discovering it.

What changes for you.

  • As an agent: one call at the start of a session tells you whether receipts, journaling and audit export are available here, so you can degrade deliberately rather than by accident.
  • As an operator: what a caller believes it can do is derived from the daemon's actual configuration, not from a client-side assumption you would have to keep in sync.

What it does not do.

  • It is a statement of capability, not a grant. The plan reports what is available; it does not enable anything.
  • It is not evidence. The handshake response is unsigned and is not a receipt.
  • It describes the daemon's configuration as the daemon sees it, which is the same limit as 6.13.

Where the detail lives. API §2.1 for both routes and the plan shape; API §12.1 for the tool.

6.13 Posture self-audit tools

Status · SHIPPED, unflagged · execplan_gate requires token_budget · Reached through · MCP route_access_matrix, auth_posture_audit, egress_policy_check, execplan_gate · Who it is for · both

What it does. Four read-only probes run against a live daemon: the route and scope access matrix (hardening.rs:78), an authentication posture audit, an egress-policy check and an ExecPlan gate assertion. None is flag-gated. They are the capability an auditor uses to interrogate a running system rather than reading its configuration file.

Why it works this way. The gap these close is between what an operator believes is configured and what the process is actually doing. A configuration file describes intent; these tools report the live posture, which is the thing that differs after a deploy, an environment override or a partial rollout. They are deliberately unflagged and read-only: a self-audit capability that can itself be switched off is not much of a self-audit capability, and one that can change something is a new attack surface. The egress check exists as a probe rather than a claim for the same reason, so that "this daemon does not call out" is something you test rather than something you are told.

What changes for you.

  • As an operator: posture drift is detectable from outside the box, before it becomes an incident, using calls anyone with access can run.
  • As an agent: an agent can check the posture it is operating under and refuse work that the posture does not support.

What it does not do.

  • These are the daemon's account of itself. They are excellent against drift and misconfiguration, which is what they are for. They are worth nothing against an adversary who controls the daemon, because the thing reporting is the thing under examination.
  • They do not change anything. Every one of the four is read-only, and none of them remediates.
  • execplan_gate requires a token_budget and will not run without one.

Where the detail lives. API §12.15 for all four tools and their parameters.

Sources