Properties of the path
Callers do not drive the Right Path step by step. A single assert runs it in order and answers synchronously. Six properties hold for every write, whichever layer or agent proposed it:
- Fixed order. The rungs always run in the same sequence. No caller can skip, reorder or repeat one.
- Any rung can refuse. A refusal names the rung and carries a typed code. Rungs below it do not run, except as noted for the pre-gates.
- Every outcome is recorded. Committed, refused or escalated, the write leaves a 16-field proof record.
- No model on the allow path. Rungs 3 to 8 cannot reach a model client. Conformance test C1 checks the import graph on every build.
- The same path for every change. An agent, the elan1 Decide Router or a person in the console all climb the same rungs. An undo is a write of its own and climbs them too.
- Fail toward a human. If a rung cannot decide, the write stops and waits for a person. It never defaults to allow.
All ten rungs
Five plain steps — ask, check, approve, act, record — map onto ten rungs. Rungs 0b to 6 decide. Rung 7 makes the change. Rungs 8 and 9 record and count it.
| Rung | Name | Step | What it checks | Can reach a model client |
|---|---|---|---|---|
| 0b | STOP | Ask | The tenant stop switch, revocations and any regulator directive. A stopped tenant refuses every write. | Outside the C1 check |
| 1 | IDENTITY | Ask | Actor, tenant and token are resolved. The kernel sets actor_kind; the caller never does. | Outside the C1 check |
| 2 | WRITE DOOR | Ask | The write type exists in the declaration at an explicit version. There is no generic write. | Outside the C1 check |
| 3 | PRE-GATES | Check | Nine gates in declared order against your own data. Six can never be skipped. No gate reads a clock. | Never |
| 4 | evaluate() | Check | Versioned policy rules decide allow, refuse or escalate. Never a score, never a model. | Never |
| 5 | GUARDRAIL | Check | Allow-lists, then the blast radius: the write must stay inside the declared limit. | Never |
| 6 | AUTONOMY | Approve | The autonomy level the actor holds now, against what the write type needs. Above the ceiling a named person decides. | Never |
| 7 | ACT | Act | Snapshot, shadow sandbox, gates run again, then identical bytes to live, by a single writer. | Never |
| 8 | PROOF | Record | Sixteen fields, sealed and chained, returned synchronously. Refusals are recorded too. | Never |
| 9 | METERED | Record | Exactly one meter event. A refusal counts as 0.4 of a governed action, held there by the database. | Outside the C1 check |
STOP · IDENTITY · WRITE DOOR
Ask · rungs 0b to 2
0b STOP
The stop switch is read first, before identity, so a stopped tenant refuses every write without further work. A stop can come from the tenant itself, from a revocation, or from a regulator directive.
1 IDENTITY
The actor, the tenant and the token are resolved. The kernel sets actor_kind (human or agent) from the token; a caller cannot claim to be a person. The actor is held to its own tenant and its own scope, as set through scope.
2 WRITE DOOR
The write type must exist in the named declaration, at the explicit version the intent cites. There is no generic “update”: a write type the declaration does not list cannot be expressed, so it cannot be allowed.
Nine gates, six never skippable
Check · rung 3 · pre-gates G1–G9
Gates are pure functions of the context, the declaration version, the record state and an explicit as-of time. No gate reads a clock, so the same inputs always give the same result and a gate decision can be replayed. The first failure sets the refusal code; the remaining gates still run and record, so an operator sees every problem at once rather than one per retry.
| Gate | Name | Asserts | Can be declared off | Refusal code (illustrative) |
|---|---|---|---|---|
| G1 | Consent | A recorded, unexpired consent covers this purpose. | Never | GATE.CONSENT_MISSING |
| G2 | Residency | The record's residency domain matches the tenant's (Mumbai). | Never | GATE.RESIDENCY_MISMATCH |
| G3 | Retention | The record is inside its declared retention window. | Never | GATE.RETENTION_WINDOW_CLOSED |
| G4 | Dual control | A second named person has approved this write. | Never | GATE.DUAL_CONTROL_PENDING |
| G5 | Rate | Within the declared per-actor rate. | With a decision record | GATE.RATE_EXCEEDED |
| G6 | Budget | Within the declared per-period budget. | With a decision record | GATE.BUDGET_EXHAUSTED |
| G7 | Counterparty | The counterparty is known and not sanctioned. | Never | GATE.COUNTERPARTY_UNKNOWN |
| G8 | Schedule | Inside a declared operating window. | With a decision record | GATE.OUTSIDE_SCHEDULE |
| G9 | Precondition | A declared record state holds: credit limit, period open, no duplicate number. | Never | GATE.PRECONDITION_FAILED |
The six gates that can never be skipped are consent, residency, retention, dual control, counterparty and precondition. Rate, budget and schedule take parameters in the declaration’s gates block, and can be switched off only with a decision record.
evaluate() · GUARDRAIL
Check · rungs 4 and 5
4 evaluate()
evaluate() applies the tenant’s versioned policy rules to the intent and returns a typed result: allow, refuse or escalate. It is never a score and never a model. The policy version it ran is sealed into the record as F08, so a reviewer can see exactly which rules applied. Where elan1 Decide proposed the write, Govern re-checks your threshold here; if the two disagree, Govern wins, and the disagreement is treated as a defect in Decide.
5 GUARDRAIL
The guardrail checks allow-lists first, then the blast radius: how many records, which ledgers and what value the write would touch, against the limit the declaration sets for that write type. “Update one invoice” cannot arrive as an unbounded filter. A write outside the radius is refused.
A0–A5
Approve · rung 6 · autonomy
Autonomy belongs to the actor, and there is no A6. Rung 6 reads the level the actor holds now — not the level it held when the intent was drafted — and compares it with what the write type needs.
| Level | Name | What the actor may do |
|---|---|---|
| A0 | Observe | Reads only. Cannot reach rung 7 by any path. A missing grant resolves here. |
| A1 | Draft | Produces a write intent; a person must submit it. |
| A2 | Propose | Submits; a person approves before the write. |
| A3 | Act reversible | Acts alone where a reversal plan exists. |
| A4 | Act bounded | Acts alone inside a declared blast radius and budget. |
| A5 | Act broad | Acts alone at tenant scope; the declaration itself needs dual control. |
Holds, approvals and expiry
Above the ceiling, assert answers escalated at once, with an obligation for a named approver and a proof record for the escalation. The approver is never the asker, and sees the change, the gate results and the policy version first. Approval is step-up: a larger write can require a more senior approver.
- Approved — the write continues from rung 7, and the record names the human approver as the actor.
- Refused by the approver — a typed refusal, for example
APPROVER_REFUSED(illustrative), recorded and metered at 0.4 of a governed action. - No answer in time — expiry is a refusal, for example
APPROVAL_EXPIRED(illustrative). The wait is held on thefusion.run/v1contract in elan1 Run.
Raising an actor’s level is itself a governed write, approved by two people. Earned autonomy uses a deterministic score, with no model involved.
Single writer
Act · rung 7
What happens at rung 7 depends on the mode, because the mode is the question of who holds the write credential.
assert. elan1 cannot stop a write your system makes, so a Mode B write is never described as blocked.PROOF · METERED
Record · rungs 8 and 9
8 PROOF
A record of exactly 16 fields is sealed under Seal v6 — SHA-256 over a length-prefixed preimage — and chained to the record before it through prev_digest. It is returned synchronously with the outcome. Refusals and escalations write records too, so the chain is a complete account of every attempt, not only of what changed. See Proof record.
9 METERED
Exactly one meter event per write intent. A committed write counts one governed action. A refusal counts as 0.4 of a governed action, and a database check holds it there. Within your allowance, it uses 0.4 of an included action; beyond it, it costs 40% of your level’s rate, for example ₹0.64 at L1. A platform failure is never billed.
A worked trace
One write intent, held at rung 6 for a person, then committed. The agent holds A2, so it may propose but a person must approve.
assert wr_specimen_7c2 journal_entry.post actor agt_specimen_gl02 (agent, A2)
0b STOP pass tenant tnt_specimen_01 not stopped
1 IDENTITY pass tenant token, act scope · actor_kind = agent (set by kernel)
2 WRITE DOOR pass decl_month_end_close v7 lists journal_entry.post
3 PRE-GATES pass G1 G2 G3 G4 G5 G6 G7 G8 G9 · first failure: none
4 evaluate() pass policy 2027.06.1 · result: escalate (A2 proposes, a person approves)
5 GUARDRAIL pass blast radius 1 record · inside declared limit
6 AUTONOMY held obligation OB-specimen-0412 → usr_specimen_approver
← escalated · proof seq 1039 · meter 0
… usr_specimen_approver (human, not the asker) approves
7 ACT pass snapshot → shadow sandbox → gates again → live · credential single-use, 10 min
8 PROOF sealed seq 1042 · prev_digest sha256:9f3c…e41a
9 METERED 1 governed action
← committedTwo records were written: seq 1039 for the escalation and seq 1042 for the commit. The commit names the approver, not the agent, as the actor, and records autonomy_level A2.
Other layers on the path
- elan1 Work proposes changes and never approves them. Every change, and every undo, goes through KernelPort and the Right Path.
- elan1 Decide: when a decision leads to a change, the Router builds a write intent and sends it to Govern in Mode B. Govern re-checks the threshold at rung 4.
- elan1 Run carries Govern’s work on five contracts — gateway, trace, tools, run and guard. A guard verdict is an input, never the allow. Trace spans bind to the proof record. Substitution step 7.3 asks Govern for a gate check, and if Govern is unreachable, step 7 does not go ahead on a timeout.
- Third-party agents reach the same path over the MCP server or the HTTP API, in Mode B.
Open questions
Two parts of the design that touch the Right Path are not settled. We state them as open rather than guess.
- Pack gate names. The kernel register names G1 Consent to G9 Precondition. Accounting packs name gates by what they check in the books — ledger, stock, permissions, GST, MCA. Whether pack gates are parameters of the nine or a separate register is not settled.
- Rung 7 for elan1 Work for small firms. Which component performs the single write for the small-firm edition — the kernel, or the promoter — is not settled.
Both are tracked on the reference architecture.