Concepts

Governed actions

A model may propose an action. Fixed rules check it and name the fact that decides. The owner approves, then releases it. The provider's receipt and the observed outcome are kept apart, because they prove different things.

The lifecycle

Step Who What it records
Propose Model or person A proposal with an evidence snapshot and an idempotency key
Check Fixed rules Admit, refuse or undecidable, with the deciding fact
Approve Owner An approval bound to exactly the evidence the owner saw
Release Owner The execution, run under a lock
Receipt Provider That the call was accepted
Outcome Independent source That the business changed

Rules never guess

evaluate_action resolves the subjects to canonical objects, reads the permitted evidence as of now, and returns admit, refuse or undecidable. Each failed rule names the fact, operator, expected and observed values, and the observation that decided it.

"failed_rules": [{ "fact": "Supplier.active", "op": "eq", "expected": true, "observed": false,
                   "observation_id": "d9bf393f-…" }]

Missing or stale evidence is undecidable. assess_action is the read-only form that scans a bounded set of candidates and never proposes.

Human authority

Proposer and approver roles are declared per action. Agents inherit the proposer's role and cannot hold an approver role. There is no auto-approval path.

States

proposed, approved, executing, executed, refused, uncertain, failed_no_effect. An execution interrupted by a crash is recovered at startup as uncertain, and a late receipt is recorded as its own event.

Note Effects run through an operator-configured HTTP gateway adapter with an idempotency key, or the no-network demo gateway. Connector-executed actions are on a development branch.