← All documentation

Explanation

Evidence & receipts

Why OOMU distinguishes what a model said from what actually happened.

A language model that says "I've updated the spreadsheet" has produced a sentence. Whether the spreadsheet changed is a separate question, and most AI tools never ask it. They show you the sentence.

OOMU treats those as different kinds of thing, all the way down. This page explains the distinction and how it is enforced.


The five levels

LevelWhat it establishesExample
Model assertionA model produced text."I created the file."
Resolved argumentA real resource was identified, with its identity recorded.This exact path, device, inode, size, and modification time.
Executed effectA native executor ran, under a described effect.The write went through files.write.
Verified postconditionOOMU looked at the world afterwards and reported what it observed.The file exists at that path with that digest.
ReceiptAll of the above, recorded and digested.A NativeReceipt with status, evidence, timings, and route.

A model assertion is the weakest evidence in the system, and OOMU treats it that way. It is never sufficient for a claim that something was done.


What a receipt contains

Every capability execution produces one:

Field
receiptId, turnId, executionIdIdentity and lineage
capabilityIdWhich action
effectDigestSHA-256 of the effect descriptor
decisionDigestWhich routing decision authorized it
startedAtUnixMs, finishedAtUnixMsTiming
resolvedResourceSummaryWhat it actually touched
destinationSummaryWhere anything went
nativeResultWhat the executor returned
postconditionEvidenceWhat the verifier observed, and whether it held
retryStateWhether this was a retry
reasoningRoute, contentModelId, routerModelIdWhich models were involved
statusSuccess · Partial · Failed · Cancelled · Unknown outcome
failureCodeWhere one applies

Unknown outcome is the field that matters most. It exists because OOMU sometimes cannot determine what happened: a process died mid-action, a restart interrupted a step. Without that state, a system has to pick between claiming success and claiming failure, and both are lies.


The effect descriptor

Before a capability runs, OOMU builds a structured description of what it is about to do:

FieldValues
reversibilityNo mutation · Reversible · Irreversible
externalityLocal only · Public read · Private egress · External mutation
privilegeLevelStandard · Elevated · System critical
canonicalResourcesResolved identifiers, with content digests
destinations, recipientsWhere anything goes
dataClassesWhat kinds of data are involved
objectCount, blastRadiusHow much this touches, and how much it could
executableCodeWhether executable content is involved
originTurnId, proposedActionIdWhich turn and which proposal
resolvedArgumentDigestSHA-256 of the resolved arguments
idempotencyKeySo a retry cannot repeat a completed effect

The descriptor is validated (objectCount cannot exceed blastRadius, digests must be well-formed) and then digested. That digest is what the receipt refers to.

An effect that is irreversible, above standard privilege, or involves executable code is flagged for isolated qualification.

Note that files.trash and files.delete_permanently are separate capabilities carrying different reversibility. That is not cosmetic: it is the difference between an action OOMU classifies as recoverable and one it does not.


Postcondition verifiers

Every capability has one. It is a separate component from the executor, with a stable identifier, and it answers a single question: is the world now in the state this action claimed to produce?

It returns what it observed, not what it expected. A verifier can report verified: false alongside the observation that shows why.

This is why a document is not finished when the compiler returns. It is finished when the file has been reopened and its structure checked. It is why a browser click is not done until a fresh observation confirms the page changed. It is why a schedule run records what it verified rather than that it ran.


Activity

The Activity tab in the Chat workspace shows the whole picture: "See what OOMU is doing, what needs you, and what finished." Filter by In progress, Needs attention, Finished, or All.

Each record has a state (queued, routing, running, verifying, completed, failed, or recovery_required) and the database enforces consistency between state and evidence:

  • completed requires at least one receipt and an evidence digest, and no failure category.
  • failed requires zero receipts, no evidence digest, and a failure category.
  • Everything else requires none of the three.

A turn cannot be marked complete without evidence. Not by policy: by constraint. The row is refused.

Failure categories are specific: routing, local_model, cloud_service, native_execution, persistence, setup, unknown. When something goes wrong you learn which layer.


Provenance on every reply

Assistant messages carry a provenance record: the routing mode, execution kind, provider, runtime, and model.

Two rules are enforced rather than trusted:

  • A reply produced by native code cannot claim a cloud provider.
  • A native reply with no successful execution receipt behind it cannot claim provenance at all.

Imported and pre-provenance records stay readable, but the interface will not invent an attribution for a row without evidence.


Recovery

If OOMU or your Mac stops mid-work, startup reconciliation decides what each unfinished thing becomes:

WasBecomesWhy
A reserved workflow stepReset to pendingIt had not started. Safe to run again.
A running workflow stepCheck requiredOutcome unknown. Not safe to assume either way.
An expired routine leaseReleasedThe holder is gone. Claimable again.
An in-flight activityrecovery_requiredSame reason.

The count of each is written to the activity log. Nothing is quietly cleaned up.


What honesty looks like in the interface

The error copy is where a design like this either holds or does not:

"OOMU couldn't verify that work as completed. Nothing unverified was reported as done."

"OOMU couldn't safely save that turn. Your draft is still here."

"OOMU couldn't delete this project. Nothing unverified was removed."

"OOMU couldn't add those files. Nothing unverified was added."

Every one of those tells you both what failed and what state you are in. That second half is what makes an error message useful.


What this is not

OOMU does not claim its verifiers are exhaustive. A postcondition confirms a specific expected outcome; it does not prove nothing else happened. What it rules out is the most common and most damaging failure mode in AI tooling: a fluent claim with nothing behind it.