A refusal log is not a folder of error messages. It is a small evidence format with a specific job: let a third party verify that an enforcement point made a decision, on a specific input, at a specific time.

Here is the shape we use.

{ "decision": "deny", "policy": "payee_not_allowlisted", "reason": "recipient is not in the task mandate", "task_id": "tsk_01J...", "actor": "agent:research-7", "artifact_sha256": "…", "created_at": "2026-10-29T12:00:00Z", "signature": "ed25519:…" } 

What it makes possible

  • Read-only enforcement — a database tool can show that a write was attempted and refused.
  • Spend control — a payment rail can show that a payee or amount was outside the mandate.
  • Buyer review — a security team can verify the record offline without calling your API.
  • Incident review — "what did the agent try?" becomes a query, not a meeting.

What it cannot prove

It cannot prove the model's intent. It cannot prove that no other path bypassed the gateway. It cannot turn a missing log into a complete one. Those limits belong in the document, not in a footnote.

Verification, not trust

The record is signed with Ed25519 and canonicalized before signing. A verifier only needs the public key and the JSON. If the JSON changes, verification fails. That is the whole trick: make the evidence portable, not platform-bound.

At $29/month, the product is intentionally small. It is a refusal record, not a SIEM. The point is to make the missing question visible before a buyer asks it.

The portfolio