elan1 Library · 01
The governed write path: an architecture paper
How one write path in four layers keeps every consequential AI agent write behind versioned rules, a named approver where your rules ask for one, a single writer and a hash-chained record.
This paper sets out the governed write path: an architecture in which AI agents may propose changes but only one kernel may write. It covers the nine planes, the two crossings where layers meet, the single-writer credential and the Right Path every write climbs, from identity and pre-gates to approval, proof and metering.
Everything this paper describes is available in elan1 Govern, Work, Decide and Run. Each capability carries its assurance level. Every record, identifier and value shown is an illustrative specimen, not customer data.
Abstract
AI agents are starting to change systems of record: ledgers, invoices, claims and customer files. Most deployments govern the call — which model ran, what it cost — and leave the write itself to whatever credential the agent was given. This paper describes the alternative elan1 runs: a single, fixed route that every consequential write takes, owned by one component and ending in one record.
It sets out the reference architecture (planes P0–P8), the Right Path from rung 0b STOP to rung 9 METERED, the two seams where layers meet (KernelPort v1 and fusion.*/v1), the single writer and its 10-minute single-use credential, and the failure rules. It states what each layer does, what it proves and what it does not.
1. The problem: governing the write, not only the call
An AI agent that drafts an email and an AI agent that posts a journal entry are doing different kinds of work. The first produces text that a person reads. The second changes a record that the business, its auditors and sometimes its regulators will rely on later. Most of the controls that exist today were built for the first kind of work. They govern the call: which model ran, through which gateway, at what cost, with which prompt filters in front of it.
Those controls matter, and elan1 Run provides them. But they answer a different question from the one a finance controller asks when an agent is about to change the books. That question is not “was the model call within policy?” It is “may this record change?” — and, later, “who said it could, under which rule, and can I show that to someone who does not trust me?”
In most deployments, the answer to the second question is whatever the agent’s credential allows. If the agent has a database user or an API key with write access, the write happens, and the evidence is whatever logs the target system kept. The decision to allow was made implicitly, when someone issued the credential.
Two objects, kept apart
The governed write path rests on separating two objects that are usually fused:
- A write intent is a typed proposal to change a record. It names the write type, the declaration it claims to fall under, the record it would change and a hash of the payload. An agent can produce one. elan1 Decide’s router can produce one. A person in the console can produce one.
- An allow is the decision that the write may happen. Only elan1 Govern produces one, at the end of a climb through rungs 0b to 6.
Why the allow lives outside the model
The answer to “may this record change?” has to be reproducible. Given the same intent, the same declaration version and the same policy version, the result must be the same today, next quarter and in front of an auditor. That is why every proof record carries F07 declaration_version and F08 policy_version: so the decision can be replayed against the rules that were in force.
A model cannot make that promise, however capable it is. Its output depends on weights, sampling and context that are not part of the record and cannot be replayed in the same sense. So evaluate() runs versioned rules with no model in it. Earned autonomy — how much an agent may do alone — uses a deterministic score. A guard verdict from elan1 Run, such as a personal-data or prompt-injection check, is an input to the decision, never the allow.
The rule is kept true by construction rather than by policy. Conformance test C1 checks the import graph on every build: no module reachable from rungs 3 to 8 imports a model client, and nothing above P3 imports a kernel type.
| Governing the call | Governing the write | |
|---|---|---|
| Question | Did the call stay within contract? | May this record change? |
| Owner | elan1 Run | elan1 Govern |
| Unit of control | A model or tool call | A typed write intent against a declared write type |
| Evidence | A trace span: who called, what it cost, which component served it | A 16-field proof record, hash-chained per tenant |
| Meter | Node-year | Governed action; a refusal is 0.4 of one |
2. Planes P0–P8
The reference architecture divides the system into nine planes, from residency at the bottom to packs at the top (Figure 1). Four layers act across them — elan1 Work, elan1 Decide, elan1 Govern and elan1 Run — and an assurance rail (L1, L2, L3) runs alongside. Each plane has one owner. Where a layer has no role in a plane, the architecture says so, and that absence is as important as any presence.
Figure 1
Nine planes and the two seams
| Plane | Name | Owner | The rule it carries |
|---|---|---|---|
| P8 | Packs | Govern owns the schema | Configuration for a rule set, never code or a brand. ledger1 for the MCA audit trail is an example. |
| P7 | Apps | Work and Decide | Where work happens. Govern is never an ERP, a CRM or a UI shell. |
| P6 | Channels | Each layer’s own | Console, CA console, /v1, WhatsApp, voice; APIs and SDKs; Govern adds an MCP server and an HTTP API. |
| P5 | Surfaces | Govern | Where a named person approves or refuses a write. Work embeds these surfaces. |
| P4 | Declaration plane | Govern | Your rules as data, in seven versioned blocks. |
| P3 | Kernel (shut) | Govern only | The Right Path. No other layer adds code here, by rule. |
| P2 | System of record | You | Your books stay yours. Every write goes through the single writer. |
| P1 | Platform runtime | Run | The open-source AI stack behind ten contracts. No private door. |
| P0 | Residency and tenancy | Govern sets policy; Run runs it | India first. A cross-domain query is not slow; it is impossible. |
Why the kernel is shut
P3 is the only plane where an allow can be produced, so it is the plane where extension would be most dangerous. A plugin model — where products add their own checks inside the kernel — would make every product a potential author of allows. Instead, the kernel is shut: elan1 Work, elan1 Decide and elan1 Run add nothing at P3. They reach it through KernelPort, like any third party.
Customisation happens one plane up, at P4. A declaration is a process’s rules as data, in seven versioned blocks: identity, shape, permissions, write types, gates, proof binding and channels. Every proof record names the declaration and version it was checked against. elan1 Decide’s Decision Packs compile to the same seven blocks, so a decision model and a hand-written rule set are checked by the same kernel in the same way.
Residency at the bottom
P0 sits under everything because residency is not a feature that can be added later. Each residency domain has its own database and, from L2, its own signing key. India is the first domain: AWS ap-south-1, Mumbai. Pre-gate G2 checks that a record’s domain matches the tenant’s on every write.
3. The Right Path
Every consequential change takes the same path, wherever it starts. Five plain steps — ask, check, approve, act, record — map onto ten rungs, from 0b STOP to 9 METERED (Figure 2). The rungs run in a fixed order. Any rung can refuse, and a refusal at any rung still produces a record.
Figure 2
The Right Path, rung 0b STOP to rung 9 METERED
| Rung | Name | What it checks | Model client |
|---|---|---|---|
| 0b | STOP | Tenant stop switch, revocation, regulator directive. A stopped tenant refuses every write. | — |
| 1 | IDENTITY | Actor, tenant and token resolved. The kernel sets actor_kind, never the caller. | — |
| 2 | WRITE DOOR | The write type exists at an explicit version. There is no generic write. | — |
| 3 | PRE-GATES | Nine gates in declared order, six never skippable. No gate reads a clock. | None |
| 4 | evaluate() | Versioned rules decide allow, refuse or escalate. Never a score, never a model. | None |
| 5 | GUARDRAIL | Allow-lists, then blast radius: “update one invoice” cannot arrive as an unbounded filter. | None |
| 6 | AUTONOMY | The autonomy level this actor holds now. A missing grant resolves to A0. | None |
| 7 | ACT | Snapshot, shadow sandbox, gates run again, then identical bytes to live. | None |
| 8 | PROOF | Sixteen fields, hash-chained, returned synchronously. Refusals are recorded too. | None |
| 9 | METERED | Exactly one meter event. A refusal is metered at 0.4 of a governed action. | — |
Ask: rungs 0b to 2
The stop switch is read before anything else, so a tenant can be halted — by its owner, by revocation or by a regulator’s directive — without depending on any later check. Identity follows. The kernel, not the caller, sets actor_kind, so an agent cannot present itself as a person. The write door then requires that the write type exist at an explicit version in the declaration. There is no generic “update record” call; a write that is not declared does not have a door.
Check: rung 3, the nine pre-gates
Pre-gates are pure functions of the context, the declaration version, the record state and an explicit as-of time. No gate reads a clock, which is what makes a decision replayable. Gates run in declared order. The first failure sets the refusal code, but the remaining gates still run and record, so an operator sees every problem at once instead of fixing them one refusal at a time.
| Gate | Name | Asserts | Can be declared off |
|---|---|---|---|
| G1 | Consent | A recorded, unexpired consent covers this purpose. | Never |
| G2 | Residency | The record’s residency domain matches the tenant’s. | Never |
| G3 | Retention | The record is inside its declared retention window. | Never |
| G4 | Dual control | A second named person has approved this write. | Never |
| G5 | Rate | Within the declared per-actor rate. | With a decision record |
| G6 | Budget | Within the declared per-period budget. | With a decision record |
| G7 | Counterparty | The counterparty is known and not sanctioned. | Never |
| G8 | Schedule | Inside a declared operating window. | With a decision record |
| G9 | Precondition | A declared record state holds: credit limit, period open, no duplicate number. | Never |
Six gates can never be switched off: consent, residency, retention, dual control, counterparty and precondition. The other three — rate, budget and schedule — can be declared off for a write type, and only with a decision record, which is itself a governed write.
Check: rungs 4 and 5
evaluate() applies the declaration’s versioned rules and returns one of three typed results: allow, refuse or escalate. It never returns a score. The guardrail then measures the blast radius against the declared limit for the write type. A request described as “update one invoice” must arrive as one invoice; an unbounded filter is refused before anything is written.
Approve: rung 6
Autonomy belongs to the actor, not the tenant, and runs from A0 Observe to A5 Act broad. There is no A6. A missing grant resolves to A0, never to a tenant default, and raising a level is itself a governed write approved by two people. Above the actor’s ceiling, a named person who is not the asker decides. They see the difference, the gate results and the policy version before they answer. The approval wait is held durably on elan1 Run’s fusion.run/v1 contract, so it survives a restart, and expiry means refusal.
| 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. |
4. One writer, one record
Rungs 7 to 9 turn an allow into a change, a record and a meter event. Each has exactly one owner, and that is the point.
Rung 7: the single writer
Only one component writes to the system of record: the kernel’s single writer. For each allowed write it holds a single-use credential that lasts 10 minutes. It takes a snapshot, applies the change in a shadow sandbox, runs the gates again against the sandbox result, and only then sends identical bytes to the live system. If the second gate run disagrees with the first, the write is refused.
A single writer turns “who can change the books?” from a question about every credential in the estate into a question about one component. Conformance test C2 makes that claim testable: every write path other than the single writer is attempted against the real target, and each attempt must fail. Before a write type moves to Mode A, a bypass test against the real system is part of onboarding.
Every write type declares a reversal plan — a native undo or a compensating entry — or is marked irreversible: true. Test C12 runs the reversal plan by both paths.
Rung 8: the proof record
The record is written synchronously, before the caller gets its answer. It has sixteen fields under Seal v6 — no optional fields and no seventeenth field — and its SHA-256 digest is carried in F03 prev_digest of the next record in the tenant’s chain. The payload itself is never stored in the record; F14 holds a hash of it, so personal data stays out of evidence. Evidence rows cannot be updated or deleted.
A refusal is sealed like a commit, with a zeroed record_id and record_version 0. The outcome, the approver’s name and the refusal code are rendered beside the record, never inside it. The companion brief, Evidence for auditors, explains how an auditor reads these records.
Rung 9: the meter
Exactly one meter event is emitted per decision. A refusal is metered at 0.4 of a governed action, less than an allowed write, so a stricter rule set never makes a write intent cost more. Test C10 reconciles meter events, proof records and the target both ways, and replaying an intent (test C7) returns the original outcome, sequence and digest without a second meter event.
Illustrative specimen — the shape of an assert call and its answer. Not customer data. Exact names are in the KernelPort v1 reference.
assert(write_intent)
write_id wr_specimen_7c2
write_type journal_entry.post
declaration_id decl_month_end_close
record_id je_specimen_5531
payload_hash sha256:e1eb0d8f…1a32ab6a
→ outcome committed | refused | escalated
seq 1042
digest sha256:f2423aa3…5aca2c18
refusal (register code and rung, when refused)5. Two crossings
Four layers could easily become a web of private calls. The architecture allows exactly two crossings, and continuous integration fails the build anywhere else (Figure 1).
KernelPort v1: the only way into Govern
KernelPort has six calls. elan1 Work and elan1 Decide reach the kernel through it. Third-party agents reach it over an MCP server (34 tools) or an HTTP API. No caller has a side entrance that skips a gate.
| Call | What it does | Who may call it |
|---|---|---|
| define | Registers a write type at an explicit declaration version and returns a content-addressed digest. Registering is itself a governed write under dual control. | Control-plane token |
| assert | The central call. Runs the whole Right Path in order and returns committed, refused or escalated, with the proof sequence and digest, synchronously. | Tenant token, act scope |
| seal | The chain writer. At L1 it returns a hash-chain receipt. From L2 the same call also signs. | The kernel only |
| verify | Recomputes the preimage and digest octet for octet and walks the chain. At L1, verification needs elan1. | Read-only token |
| scope | Resolves blast radius and autonomy for rendering. Advisory only, because assert resolves both again. | Read-only token |
| refuse | Emits a typed refusal from a closed register. A refusal still writes a proof record and is metered at 0.4 of a governed action. | Tenant token, act scope |
The frozen identifiers are kernelport/v1, elan1.proof.seal.v6 and action-receipt/1. KernelPort v1 and the record shape are frozen: the six call names do not change, and a breaking change ships as a new version alongside v1.
fusion.*/v1: the only way into Run
elan1 Run puts each part of the open-source AI stack behind a versioned contract: chat, gateway, inference, retrieval, vectors, trace, tools, run, memory and guard. A caller names the contract in the X-Fusion-Contract header, never a vendor. Each contract has two licence-clean implementations and a conformance suite, K1 to K7, so a component can be replaced without changing the integration. elan1 Govern uses five of the ten: gateway, trace, tools, run and guard.
The dependency runs one way
Run never depends on Govern. Infrastructure gets swapped; the write path must not. Where the two meet, the rules are fixed:
- A guard verdict is an input, never the allow.
- The approval wait is held on the run contract, and expiry means refusal.
- Trace spans bind to the proof record.
- Substitution step 7.3 calls a Govern gate check — through KernelPort, like everyone else.
- Erasure is itself a governed write.
- Restore drills are verified with
elan1-verify.
6. Mode A and Mode B
The same kernel can sit in two positions relative to the write, and the difference decides what may truthfully be claimed. The mode follows the credential (Figure 3).
Figure 3
Mode A and Mode B: who holds the write credential
Mode A, Enforced. elan1 Govern runs in-process through the SDK and holds the write credential through the single writer. No write reaches the system of record without a gate decision and a proof record. Only here do we use the word “enforced”. elan1 Work on hosted ERPNext runs in Mode A, and third-party agents can run in Mode A by agreement once conformance tests C1–C14 pass.
Mode B, Attested advisory. elan1 Govern is reached over MCP or HTTP and does not hold the credential. Every write intent is evaluated against your rules and recorded, and the caller receives a typed answer. The caller then makes the write with its own credential. We do not say a Mode B write was blocked, because elan1 Govern does not hold the key that makes it.
| Consumer | Mode | What we may say |
|---|---|---|
| elan1 Work, hosted ERPNext | A · SDK in-process | No write reaches the system of record without a gate decision and a proof record. |
| elan1 Work Attach (your ERPNext) | B · MCP/HTTP | Evaluated against your rules and recorded. |
| elan1 Decide | B · MCP/HTTP | Writes go to Govern as intents. |
| elan1 Run tooling | B · MCP/HTTP | If elan1 is unreachable, the gate check fails closed. |
| Third-party agents | B (A by agreement) | No claim to run on Govern until conformance tests C1–C14 pass. |
Modes do not change with the assurance level. From L2, a Mode B record can be signed, but signing does not make it enforced, and the record keeps the mark that the caller made the write in every export. Mode B is still worth having: it gives an agent vendor a typed, rule-based answer before the write and leaves a record of every attempt. What it cannot give is a guarantee about writes that never asked.
7. Failure directions
Every system fails eventually. The useful design question is which way. The governed write path has one rule: when anything is unclear or unavailable, stop and ask a person. A change that waits costs time. A wrong change committed to the books costs a correction, an explanation to an auditor and sometimes a restatement. Because the costs are not symmetrical, the failure direction is not either.
| If… | Then… |
|---|---|
| elan1 Govern is unavailable | Allows stop. Changes wait for a person. |
| The runtime is unavailable | Writes stop. |
| elan1 is unreachable from Run tooling | The gate check fails closed. |
| A named approver does not answer in time | The write expires. Expiry means refusal, with a record, metered at 0.4 of a governed action. |
| elan1 Decide’s confidence is below your threshold | The case goes to a person in the Review Console. |
| A check cannot be completed | The write is refused with a typed code, never waved through. |
Conformance test C5, the fail-closed matrix, makes each dependency unavailable in turn and requires a platform refusal, never an allow. Test C6 checks that an actor without a grant resolves to A0 Observe. Test C11 checks that no approval is accepted from the requester or from an agent token.
8. What it does not do
An architecture paper that only lists capabilities invites readers to assume the rest. These are the limits, stated as plainly as the capabilities.
| It does | It does not |
|---|---|
| Check every consequential write against versioned rules before it happens | Decide whether the business decision was right, or whether your rules were good |
| Hold the write credential in Mode A, through one writer | Block a write in Mode B, where the caller holds the credential |
| Leave a tamper-evident record of every attempt at L1 | Make a record impossible to alter; it makes alteration visible |
| Let you recompute the chain with elan1 at L1 | Sign records, or let someone check them offline without us, at L1; that needs L2 |
| Ask a named person where your autonomy levels require it | Let an agent approve its own change, or let a model produce an allow |
| Record writes that ask | See activity outside elan1, such as a direct edit in another tool |
| Map records to clauses where a verifier profile exists (from L2) | Make you compliant with any regulation on its own |
Nor is elan1 Govern an ERP, a CRM or a UI shell. It does not store your business data — the record holds hashes, not payloads — and it does not charge per seat. A refusal costs 40% of one governed action, never the full rate.
9. Deployment choices and the customer reference
Reference architecture v1.0 is available in all four platforms. The following are set per deployment or set out in the reference customers receive. Changes are logged in public, on the architecture page and the disclosures page.
- Who performs rung 7 for elan1 Work for small firms — the kernel or the promoter. Rung 7 is the single writer; for the small-firm edition, it is agreed with each firm at onboarding.
- Where the proof record physically lives. The record shape is fixed; its physical home follows the deployment: hosted in your residency domain, or in your own VPC or on premises.
- Key custody for L2 signing: signing keys are held per residency domain; custody details are in the customer reference.
- DPDP erasure alongside an append-only chain. Payloads are hashed rather than stored, and erasure is itself a governed write. The library note sets out elan1’s role under the Act and the question that remains.
- Pack gate names against the kernel register, listed per pack, described in section 3.
- The refusal-code register, part of KernelPort v1 and shared with customers. Codes shown in this paper are illustrative.
Everything else in this paper describes the platform as it runs. Where a precise mechanism is fixed — SHA-256 over a length-prefixed preimage, a 10-minute single-use credential, six un-skippable gates — we have said so.
References
Every reference is a page on this site. Where a page and this paper differ, the page is newer: tell us and we will correct the paper.
- [1]Reference architecture/platform/architecturePlanes, the Right Path, pre-gates, the seams and open conflicts, with the interactive explorer.
- [2]Contracts and integrations/platform/integrationsKernelPort v1, the MCP server and HTTP API, the ten fusion.*/v1 contracts and conformance tests.
- [3]The proof record/platform/proof-recordThe sixteen fields, the chain and an in-browser recompute.
- [4]Assurance levels and modes/platform/assurance-levelsL1, L2 and L3 against Mode A and Mode B.
- [5]elan1 Govern/platform/governThe layer that owns the write path.
- [6]See a governed action/see-itOne write intent climbing every rung, with the refusal branch.
- [7]Field note: A model may produce a write intent, never an allow/blog/a-model-may-produce-a-write-intent-never-an-allow
- [8]Field note: Two crossings/blog/two-crossings
- [9]Field note: Fail toward a human/blog/fail-toward-a-human
- [10]Evidence for auditors: reading an elan1 proof record/resources/library/evidence-for-auditorsThe companion brief for assurance teams.
- [11]What we claim, and what we don’t/trust/claimsThe claims register this paper follows.
- [12]Disclosures and open questions/trust/disclosures
- [13]What's next/trust/roadmapFuture improvements, in order. No dates.
- [14]Glossary/resources/glossaryWrite intent, allow, declaration, rung, seal and the other terms used here.