design draft · may 2026

Attestation Protocol

Cryptographic proof that consequence evaluation happened. Non-repudiation for agent actions.

Status: Partial Draft
Specified: §4 Canonicalization, §5 Key Management, §6 Transport, §7 Agent-Side Opt-In
Pending: §8 Verification Procedure, §9 Failure Modes, §10 Wire Format

Problem Statement

RecourseOS evaluates consequences of actions before execution. But there's no way to prove that evaluation happened.

Today, an agent can claim "I checked with RecourseOS and it said allow" without verification. The agent might have:

This makes consequence evaluation advisory. The agent can ignore it with no evidence trail.

Solution: Cryptographic Attestation

Attestations provide cryptographic proof that:

  1. A specific input was evaluated
  2. By a specific RecourseOS instance
  3. At a specific time
  4. Producing a specific verdict

With attestations, third parties (CI systems, approval workflows, audit logs, agent platforms) can require proof of evaluation before allowing execution. The advisory tool becomes a gating tool.

The killer feature is non-repudiation: agents cannot claim they checked without producing a signed artifact from RecourseOS.

Attestation Schema

interface ConsequenceAttestation {
  // Protocol version
  version: 'recourse.attestation.v1';

  // What was evaluated
  input: {
    hash: string;                    // SHA-256 of canonical input
    source: 'terraform' | 'shell' | 'mcp';
    timestamp: string;               // ISO 8601, evaluation time
  };

  // Replay/freshness protection
  nonce: string;                     // Random 128-bit value, hex-encoded
  expires_at: string;                // ISO 8601, attestation validity window

  // Chain to related attestations
  chain_id?: string;                 // Links approval attestations to evaluation
  parent_attestation?: string;       // Hash of attestation this one references

  // The evaluation result
  evaluation: {
    riskAssessment: 'allow' | 'warn' | 'escalate' | 'block';
    worstTier: 1 | 2 | 3 | 4 | 5;
    reportHash: string;              // SHA-256 of full ConsequenceReport
    mutationCount: number;
    hasUnrecoverable: boolean;
  };

  // Who evaluated
  evaluator: {
    instanceId: string;              // Unique RecourseOS instance identifier
    version: string;                 // RecourseOS version
    publicKey: string;               // PEM-encoded public key
    keyAttestation?: string;         // Optional: HSM/TPM provenance
  };

  // Cryptographic binding
  signature: string;                 // Ed25519 signature over all fields
  signatureAlgorithm: 'Ed25519';
}

Schema Design Notes

FieldPurpose
noncePrevents replay attacks. Each evaluation generates a fresh nonce.
expires_atVerdicts have a shelf life. Default: 15 minutes. Configurable.
chain_idLinks approval attestations to evaluation attestations for audit trails.
keyAttestationFuture-proofing for HSM/TPM-backed keys. Not required for v1.

§4 Canonicalization

This section uses RFC 2119 keywords (MUST, MUST NOT, SHOULD, MAY).

4.1 Signed Payload Construction

The signed payload MUST consist of all attestation fields except the signature field. The key_id field MUST be included in the signed payload; it is not metadata.

To construct the signed payload from an attestation object:

  1. Remove the signature field from the attestation object. All other fields MUST remain.
  2. Serialize the resulting object according to RFC 8785 (JSON Canonicalization Scheme).
  3. The output is the canonical byte sequence to be signed.

4.2 RFC 8785 Compliance

Implementations MUST serialize the signed payload according to RFC 8785. This specification does not define a subset or extension of RFC 8785; full compliance is required.

Key requirements from RFC 8785 that implementations MUST observe:

Implementations MUST pass the RFC 8785 test vectors published at test/canonicalization-vectors.json. These vectors include RFC 8785 reference examples and derived edge cases for number representation, Unicode normalization, and key ordering.

4.3 Signing Procedure

To sign an attestation:

  1. Construct the signed payload per Section 4.1.
  2. Compute the Ed25519 signature over the canonical byte sequence using the signing key identified by key_id.
  3. Encode the signature as base64url (RFC 4648 Section 5, no padding).
  4. Set the signature field to the encoded value.

The key_id field MUST be set before signing. The signing key MUST be in the active state (see Section 5.2).

4.4 Verification Procedure

To verify an attestation signature:

  1. Extract the signature field and decode from base64url.
  2. Construct the signed payload per Section 4.1 (removing signature, canonicalizing the remainder).
  3. Retrieve the public key corresponding to key_id from the key registry (see Section 5.3).
  4. If no key exists for key_id, or the key is in the pending or compromised state, verification MUST fail.
  5. Verify the Ed25519 signature over the canonical byte sequence using the retrieved public key.
  6. If verification succeeds and the key is in the active, deprecated, or retired state, the attestation is valid.

§5 Key Management

5.1 Key Identifier

Each signing key MUST have a unique identifier (key_id). The key_id MUST be a non-empty string consisting of printable ASCII characters (U+0021 through U+007E).

Recommended format: {instance_id}-{sequence_number} where sequence_number is a monotonically increasing integer starting at 1. Example: recourse-prod-1, recourse-prod-2.

Implementations MUST NOT reuse a key_id for different key material, even after the key transitions to compromised.

5.2 Key Lifecycle States

Each key exists in exactly one of five states:

StateSigningVerificationDescription
pendingMUST NOTMUST failKey generated but not yet valid. Used to pre-publish keys before rotation.
activeMAYMUST succeedKey available for signing new attestations.
deprecatedMUST NOTMUST succeedKey no longer signs but existing attestations remain verifiable. Normal state after scheduled rotation. SHOULD remain in this state for at least 90 days.
retiredMUST NOTMUST succeedKey permanently out of rotation. Attestations remain verifiable indefinitely. Terminal state for keys that were never compromised.
compromisedMUST NOTMUST failKey cannot be trusted. Attestations signed by this key MUST be rejected regardless of when they were signed.

An instance MUST NOT have more than one key in the active state at any time.

State transitions:

pending → active → deprecated → retired
    ↓         ↓          ↓          ↓
    └─────────┴──────────┴──────────┴───→ compromised

Legal transitions:

No state may transition backwards. No state may transition to pending or active from any other state.

State transitions are operator-initiated. A transition MUST be reflected in the key registry with an incremented registry_version before the transition takes effect for signing or verification. A key MUST NOT sign attestations in a state until that state is published in the registry; a verifier MUST NOT apply a state change until it has fetched a registry reflecting that change.

5.3 Key Registry

Each RecourseOS instance MUST publish a key registry containing all non-compromised keys. The registry MAY also include compromised keys for audit purposes.

The registry MUST be available at: {instance_base_url}/.well-known/recourse-keys.json

The registry URL is the canonical reference for key material. Instances deployed behind load balancers, CDNs, or multiple domains MUST ensure all paths resolve to the same registry content. The instance_base_url used in attestations MUST be consistent; verifiers are not required to follow redirects or resolve aliases.

Registry schema:

{
  "instance_id": "recourse-prod",
  "keys": [
    {
      "key_id": "recourse-prod-1",
      "algorithm": "Ed25519",
      "public_key": "<base64url-encoded public key>",
      "state": "deprecated",
      "valid_from": "2026-01-15T00:00:00Z",
      "valid_until": "2026-04-15T00:00:00Z",
      "deprecated_at": "2026-04-01T00:00:00Z"
    },
    {
      "key_id": "recourse-prod-2",
      "algorithm": "Ed25519",
      "public_key": "<base64url-encoded public key>",
      "state": "active",
      "valid_from": "2026-04-01T00:00:00Z",
      "valid_until": null
    }
  ],
  "registry_version": 2,
  "updated_at": "2026-04-01T12:00:00Z"
}

Field requirements:

5.4 Key Rotation Procedure

To rotate from key A to key B:

  1. Generate key B. Set state to pending. Publish in key registry.
  2. Set valid_until on key A to a future timestamp (rotation time).
  3. At rotation time: Set key B to active with valid_from equal to rotation time. Set key A to deprecated with deprecated_at equal to rotation time.
  4. New attestations MUST be signed with key B. Attestations signed with key A remain verifiable.
  5. After a retention period (operator-defined, SHOULD be at least 90 days), key A MAY transition to retired.

The overlap window (steps 3-4) ensures verifiers fetching the key registry mid-rotation can verify attestations signed by either key.

5.5 Verifier Key Caching

Verifiers MAY cache the key registry. The default cache TTL is 24 hours; operators MAY configure shorter TTLs for high-security deployments or longer TTLs for stable deployments.

Cached registries MUST be refreshed when:

Rollback protection:

When refreshing, verifiers MUST compare registry_version of the fetched registry against the cached version:

Cache desync recovery:

If a verifier's cache becomes corrupted or desynchronized (e.g., restored from backup, clock skew), rollback protection may prevent normal refresh. To recover:

Verifiers MAY implement a "force refresh" operation that discards the cached registry_version and accepts the fetched registry unconditionally. This operation:

The log entry MUST include: timestamp of the force refresh, operator identity if authentication is available, the discarded cached registry_version (or "none" if cache was empty), the accepted registry_version, and any operator-provided justification. Implementations without authentication MAY omit operator identity but MUST log the other fields.

After a force refresh, normal rollback protection resumes from the newly cached registry_version.

Implementations that do not support force refresh MUST document this limitation. Operators of such implementations recover from cache desync by clearing all cached state, which is equivalent to a new verifier bootstrapping.


§6 Transport

6.1 Attestation Delivery

Attestations MUST be delivered via two channels:

  1. Embedded: Included in the MCP tool response that returns the evaluation result.
  2. URL: Retrievable at a stable URL for later verification.

Both channels deliver the identical attestation. The attestation_uri field in the attestation provides the URL for the durable copy.

6.2 Embedded Delivery

When RecourseOS returns an evaluation result via MCP, the response MUST include an attestation field containing the complete attestation object.

{
  "verdict": "recoverable-from-backup",
  "tier": 3,
  "reasoning": "...",
  "attestation": {
    "key_id": "recourse-prod-2",
    "attestation_uri": "https://recourse.example/.well-known/attestations/abc123.json",
    "input": { ... },
    "output": { ... },
    "evaluator": { ... },
    "timestamp": "2026-05-01T14:30:00Z",
    "signature": "..."
  }
}

The attestation object is the same object that would be retrieved from attestation_uri.

6.3 URL Delivery

Each attestation MUST be retrievable at the URL specified in its attestation_uri field. The URL MUST remain stable for the attestation's retention period (see Section 6.5).

URL format: {instance_base_url}/.well-known/attestations/{attestation_id}.json

Attestation ID derivation:

The attestation_id MUST be derived from the attestation content fields, excluding fields that depend on the ID itself. Specifically:

  1. Construct an object containing exactly these fields from the attestation: input, output, evaluator, timestamp, key_id.
  2. Canonicalize this object per RFC 8785.
  3. Compute the SHA-256 hash of the canonical byte sequence.
  4. Take the first 16 bytes of the hash and encode as lowercase hexadecimal (32 characters).

The attestation_id is this 32-character hex string.

The attestation_uri and signature fields are NOT inputs to the attestation_id derivation. This avoids circularity: the ID can be computed before the URI is constructed, and the URI can be constructed before signing.

Signing order:

When creating an attestation:

  1. Populate input, output, evaluator, timestamp, key_id.
  2. Derive attestation_id per the procedure above.
  3. Construct attestation_uri using the derived ID.
  4. Add attestation_uri to the attestation object.
  5. Sign the attestation per Section 4.3 (signature covers all fields including attestation_uri).

The attestation_uri IS part of the signed payload; an attacker cannot redirect verifiers to a different URL without invalidating the signature. Only the ID derivation excludes it to break the circularity.

The response MUST be the attestation object with Content-Type: application/json.

6.4 Consistency Requirement

The embedded attestation and the URL-retrieved attestation MUST be byte-for-byte identical when canonicalized per RFC 8785.

A verifier that receives an embedded attestation MAY fetch the URL copy and compare. The cross-check is performed by parsing both attestation copies as JSON, canonicalizing each independently per RFC 8785, and comparing the resulting byte sequences. Any difference in the canonical forms—including field ordering, whitespace, or encoding—indicates tampering or implementation error and MUST cause verification to fail.

Verifiers are NOT REQUIRED to perform this cross-check, but high-assurance deployments SHOULD.

6.5 Retention

Attestations MUST remain retrievable at their attestation_uri for at least the retention period of the signing key (from valid_from to when the key enters retired or compromised state).

After the signing key is retired or compromised, the attestation URL MAY return 410 Gone. The attestation remains cryptographically verifiable if a verifier has the key's public key, but the authoritative URL is no longer obligated to serve it.

6.6 Failure Modes

If the URL endpoint is unavailable, verifiers MUST NOT treat this as attestation invalidity. The embedded copy remains verifiable using the key registry.

If the key registry is unavailable, verification MUST fail. The attestation cannot be verified without access to the public key.


§7 Agent-Side Opt-In Semantics

This section uses RFC 2119 keywords. Sections 7.1–7.8 are normative. Section 7.9 is non-normative guidance.

7.1 Response Structure

When attestation is enabled, RecourseOS responses include an attestation field at the root level of the consequence report:

{
  "schemaVersion": "recourse.consequence.v1",
  "riskAssessment": "escalate",
  "assessmentReason": "Recoverability needs human review",
  "summary": { ... },
  "mutations": [ ... ],
  "attestation": {
    "input": { "source": "shell", "input": "rm -rf /data" },
    "output": { ... },
    "evaluator": "recourse:blast-radius:1.0.0",
    "timestamp": "2026-05-01T14:30:00Z",
    "key_id": "recourse-prod-1",
    "attestation_uri": "https://recourse.example/.well-known/attestations/abc123.json",
    "signature": "..."
  }
}

The attestation field is a sibling of decision, summary, and mutations. It is metadata about the evaluation, not part of the evaluation result.

When attestation is disabled (default), the attestation field is absent from the response. Agents MUST NOT assume its presence. Agents MUST check for field existence before accessing attestation data.

7.2 Attestation Content

The attestation.output field contains a copy of the consequence report at the time of signing. This copy excludes the attestation field itself to avoid circular embedding.

Size consideration: The attestation roughly doubles response size because output embeds the full consequence report. For evaluations with many mutations (e.g., large Terraform plans), this overhead may be significant. Agents operating under tight context limits MAY:

Agents MUST NOT modify attestation.output if they intend to verify the signature later; any modification invalidates the signature.

7.3 Attestation Modes

Agents operate in one of four attestation modes. Each mode has explicit requirements:

ModeRequirementsUse Case
ignoreAgent MUST NOT verify. Agent MAY log attestation presence. Agent proceeds based on decision field alone.Development, low-stakes operations, agents without verification capability.
logAgent MUST record the attestation (or its hash and URI) before proceeding. Agent MUST NOT block on verification. Agent MAY verify asynchronously after proceeding. Agent proceeds based on decision field.Compliance environments requiring audit trails without blocking on verification.
verifyAgent MUST verify before proceeding. Agent MUST refuse to proceed on verification failure. If attestation is absent, agent MAY proceed with a warning logged.High-assurance deployments where verification failure is meaningful.
requireAgent MUST verify before proceeding. Agent MUST refuse to proceed on verification failure. If attestation is absent, agent MUST refuse to proceed.Zero-trust deployments; agents that must prove they checked.

The protocol does not mandate which mode agents use. The opt-in model allows gradual adoption: agents can start in log mode, then enable verify or require as confidence grows.

7.4 Verification Procedure

This section describes a RECOMMENDED verification sequence. Implementations MAY reorder steps if the functional result is equivalent, but all validation checks MUST be performed.

An agent in verify or require mode SHOULD perform these steps before acting on the evaluation result:

  1. Check attestation presence: If attestation field is absent, behavior depends on mode. In verify mode, log warning and proceed. In require mode, MUST reject.
  2. Check trusted instance: If trusted_instances is non-empty, the scheme and host of attestation_uri MUST match an entry. If no match, MUST reject.
  3. Fetch key registry: HTTP GET to {instance_base_url}/.well-known/recourse-keys.json. The instance_base_url is the scheme and host portion of attestation_uri. Cache rules per Section 5.5 apply.
  4. Locate public key: Find the entry in keys where key_id matches attestation.key_id. If not found, MUST reject.
  5. Check key state: If the key's state is pending or compromised, MUST reject.
  6. Construct signed payload: Remove the signature field from the attestation. Canonicalize the remainder per RFC 8785.
  7. Verify signature: Decode signature from base64url. Verify Ed25519 signature over the canonical payload using the public key. If verification fails, MUST reject.
  8. Accept: If all checks pass and key state is active, deprecated, or retired, the attestation is valid. Agent MAY proceed according to the decision field.

The entire verification procedure requires two HTTP requests (evaluation + key registry) plus local cryptographic operations. Verification latency is typically under 100ms on local networks.

7.5 Cross-Check (Optional)

For high-assurance verification, agents MAY perform the cross-check described in Section 6.4:

  1. Fetch the attestation from attestation_uri.
  2. Canonicalize both the embedded attestation and the fetched attestation per RFC 8785.
  3. Compare the canonical byte sequences.
  4. If they differ, MUST reject the attestation.

This cross-check detects tampering between the MCP response and the durable attestation store. It adds one HTTP request to the verification flow.

Cross-check is NOT REQUIRED for verification. The signature alone provides integrity; the cross-check provides defense-in-depth against implementation bugs or man-in-the-middle attacks that modify the embedded copy.

7.6 Verification Failure Handling

When verification fails, agents in verify or require mode:

Escalation patterns: Escalation means halting autonomous execution and requesting human review. Agents MAY implement escalation as:

The choice of escalation pattern is implementation-defined. The requirement is that autonomous execution MUST NOT continue; a human MUST be involved in the decision to proceed.

Verification failure vs. verdict: Verification failure is independent of the evaluation verdict. Even if decision is block, verification failure adds information: the verdict itself may be fabricated. An agent that would have blocked anyway SHOULD still log the verification failure as a security event.

Retry behavior: Agents MAY retry verification for transient failures (network_error). Agents MUST NOT retry on cryptographic or trust failures (signature_invalid, key_compromised, key_pending, instance_not_trusted, cross_check_mismatch).

7.7 Absence of Attestation

If the attestation field is absent from a response, the agent is receiving an unauthenticated evaluation. This occurs when:

Mode-specific behavior:

The absence of attestation is represented by field omission, not by a null or empty value. Agents check for attestation with if ('attestation' in response) or equivalent.

Security consideration: In require mode, absence of attestation is a security signal, not a benign default. It may indicate the RecourseOS instance was downgraded, replaced by an impersonator, or evaluation was bypassed. The conservative response is to refuse to proceed.

7.8 Agent Configuration

Agent operators SHOULD be able to configure attestation behavior:

SettingValuesDefault
attestation_modeignore, log, verify, requireignore
trusted_instancesList of instance_base_url values[] (accept any)
key_cache_ttlDuration in seconds86400 (24 hours)
cross_checktrue, falsefalse

trusted_instances semantics:

This is an allow-list, not a trust-without-verification list. When non-empty:

Matching is performed on the scheme and host portion of attestation_uri. Example: if trusted_instances contains https://recourse.example, an attestation with attestation_uri of https://recourse.example/.well-known/attestations/abc.json is accepted.

key_cache_ttl and rollback protection:

Agent-side key caches MUST follow the rollback protection rules from Section 5.5. When a cached registry's registry_version is higher than a fetched registry's version, the fetched registry MUST be rejected. The key_cache_ttl controls how long before a cache refresh is attempted, not whether rollback protection applies.

7.9 Reasoning About Attestations (Non-Normative)

This section provides guidance for LLM-based agents. It is non-normative; implementations are not required to support these patterns.

Agents with reasoning capability can interpret attestation fields directly:

An agent asked to "verify the attestation you just received" can:

  1. Extract the attestation_uri and key_id from context.
  2. Invoke a verification tool (if available) or describe the verification steps.
  3. Report whether the signature is valid.

The field names are chosen for clarity when read by both humans and language models. An agent that understands "this is the input that was evaluated, this is the output that was produced, and this signature proves the binding" has correctly interpreted the attestation.

7.10 End-to-End Example

This example walks through a complete verification flow for an agent in require mode.

Step 1: Agent receives evaluation response

POST /api/evaluate → 200 OK
{
  "schemaVersion": "recourse.consequence.v1",
  "riskAssessment": "block",
  "assessmentReason": "Unrecoverable data loss",
  "mutations": [...],
  "attestation": {
    "input": {"source": "shell", "input": "rm -rf /data/production"},
    "output": {"schemaVersion": "...", "riskAssessment": "block", ...},
    "evaluator": "recourse:blast-radius:1.0.0",
    "timestamp": "2026-05-01T14:30:00.000Z",
    "key_id": "recourse-prod-1",
    "attestation_uri": "https://recourse.example/.well-known/attestations/a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6.json",
    "signature": "4-n_0Z2l4sRQjAvu8_tqe22sbFKuvrxHnYZjiAMuXtpj0cq_YoDjEHC5V4fn1O71zDL5mhAjsE6Fu-tPu2hjCw"
  }
}

Step 2: Agent checks trusted instances

Config: trusted_instances: ["https://recourse.example"]

Check: attestation_uri host is recourse.example → matches → proceed.

Step 3: Agent fetches key registry

GET https://recourse.example/.well-known/recourse-keys.json → 200 OK
{
  "instance_id": "recourse-prod",
  "keys": [{
    "key_id": "recourse-prod-1",
    "algorithm": "Ed25519",
    "public_key": "X8RJHBSyeubU49i9QMl1cfGfy3VjpTfyOLGKPjXagQ8",
    "state": "active",
    "valid_from": "2026-04-01T00:00:00Z"
  }],
  "registry_version": 3,
  "updated_at": "2026-04-15T12:00:00Z"
}

Step 4: Agent locates key and checks state

Find: key_id "recourse-prod-1" → found.

Check: state is "active" → valid for verification.

Step 5: Agent constructs signed payload

Remove signature field. Canonicalize remainder per RFC 8785:

{"attestation_uri":"https://recourse.example/.well-known/attestations/a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6.json","evaluator":"recourse:blast-radius:1.0.0","input":{"input":"rm -rf /data/production","source":"shell"},"key_id":"recourse-prod-1","output":{...},"timestamp":"2026-05-01T14:30:00.000Z"}

Step 6: Agent verifies Ed25519 signature

Decode public_key from base64url → 32 bytes.

Decode signature from base64url → 64 bytes.

Verify signature over canonical payload → valid.

Step 7: Agent acts on verdict

Attestation valid. riskAssessment is "block". Agent MUST NOT execute the command.

Agent logs: {"event": "evaluation_blocked", "attestation_uri": "...", "riskAssessment": "block", "verification": "passed"}


Verification Model

Four verification models exist. v1 targets opt-in inline by the agent.

ModelDescriptionv1?
Inline (execution)Target system refuses to execute without attestationNo
Async (audit)Actions execute, attestations logged, audit laterPartial
HybridInline for high-stakes, async otherwiseFuture
Opt-in by agentAgent decides whether to verify before proceedingYes

Why opt-in by agent for v1: RecourseOS doesn't control terraform, kubectl, or AWS CLI. It does influence agent behavior through MCP. The agent's decision loop is the boundary where RecourseOS has leverage.

Trust Anchor

v1: Self-signed, published keys

Each RecourseOS instance:

  1. Generates an Ed25519 keypair on first run
  2. Persists the keypair in a config directory
  3. Exposes the public key via API endpoint
  4. Signs all attestations with the private key

Trust model: Agent operators choose which RecourseOS instances to trust and fetch those public keys. Similar to SSH host key verification.

v2+ (future)

Non-Goals (v1)

The following are explicitly out of scope for v1:

Non-GoalReason
Execution attestationRequires cooperation from AWS/kubectl/etc. RecourseOS provides evaluation attestation.
Distributed witnessesThreshold signatures add complexity. Reserve schema slot, defer implementation.
Credit systemsAgent economy thinking is orthogonal. Attestation-as-proof is cleaner than attestation-as-currency.
Centralized serviceConflicts with offline/local-first architecture. Self-signed keys are the right default.

Threat Model

What the protocol protects against

What it does NOT protect against

Honest framing: The protocol provides integrity of the evaluation chain, not correctness of the evaluation itself.

v1 Implementation Scope

Deliverables

  1. Specification document — complete schema, signing/verification procedures, versioning
  2. RecourseOS integration — attestation in ConsequenceReport, keypair generation, public key API, recourse_verify_attestation MCP tool
  3. Verification library — standalone TypeScript, no RecourseOS dependency
  4. Documentation — how agents request and verify attestations
  5. Partner integration — one MCP server or agent platform consuming attestations

Estimated effort

8-12 weeks of focused work for complete v1 with documentation and partner integration.


Why Attestation Matters

The shift from advisory to verifiable changes RecourseOS's security posture:

Advisory (today)

Agent: "Should I delete this bucket?"
RecourseOS: "Block: unrecoverable data loss"
Agent: *deletes bucket anyway*
Audit log: *nothing*

Verifiable (with attestation)

Agent: "Should I delete this bucket?"
RecourseOS: ConsequenceReport + Attestation(block)
Agent: *attempts to delete*
CI system: "Show attestation"
Agent: *presents block attestation*
CI system: "Attestation says block. Denied."

The attestation protocol doesn't change how evaluation works. It changes whether evaluation matters.


Related: Agent Interface · MCP Setup · Schema Gaps · View markdown source