All four platforms available
Reference · all four platforms availableDocs v1.0 · KernelPort v1 call names and shapes are stable

Evidence

Declarations

A declaration is the rule set elan1 Govern checks every write intent against. It has seven versioned blocks covering what may change, which gates apply, the limits, the autonomy level and who approves. This page explains each block, how versions work and how the version in force is recorded in every proof record.

A declaration is a process’s rules as data: what may change, under which gates, and who approves. It has seven blocks and every change makes a new version. Every proof record names the declaration and the version it was checked against, so a rule change never rewrites the meaning of an old record.

Docs v1.0Document date 10 Oct 2026Examples are illustrative specimens, not customer data

Docs menu

What a declaration is

Your rules do not live in prompts or in code paths. They live in declarations, held in Declaration Studio in elan1 Govern. A declaration is configuration, not a build: an operator who knows the process can read every block of it.

Held in
Declaration Studio, in elan1 Govern. Not Decision Studio, which belongs to elan1 Decide and holds questions, not the rules a write must pass.
Registered by
define, the first KernelPort call. Registering a version is itself a governed write under dual control.
Blocks
Seven: identity, shape, permissions, write_types, gates, proof_binding and channels.
Versioned
Every registered change is a new version. Old versions are never edited.
Named on every record
F06 declaration_id and F07 declaration_version, next to F08 policy_version.
Evaluated by
evaluate() at rung 4, with versioned rules and no model on the allow path.
Status
Available · part of L1 Guarded

The seven blocks

The block names are fixed. What each block says is below; the exact keys and value types inside each block are in the customer reference; the ones shown here are illustrative.

The seven declaration blocks and what each says
BlockWhat it says
1
identity
What this is: name, owner role, residency domain, system of record.
Read at: Rung 1 IDENTITY
2
shape
The record type, its fields and how each is classified.
Read at: Rungs 3 and 4
3
permissions
Who may change it, by actor kind, role and minimum autonomy. An agent may never approve.
Read at: Rung 6 AUTONOMY
4
write_types
The write types, each with a blast radius, dual control, ordered gates and a reversal plan, or irreversible: true.
Read at: Rungs 2 and 5
5
gates
Which of the nine gates run, with their parameters and refusal codes.
Read at: Rung 3 PRE-GATES
6
proof_binding
Which fields the proof commits to, and how they are canonicalised.
Read at: Rung 8 PROOF
7
channels
Web, mobile, messaging, API, MCP, voice: what each carries, and in which mode.
Read at: The connection
Two rules hold in every declaration. An agent may never approve, whatever the permissions block says about its role. And six of the nine kernel gates can never be switched off: consent, residency, retention, dual control, counterparty and precondition.

Where each block acts on the Right Path

A write intent climbs the Right Path from rung 0b STOP to rung 9 METERED. Each block is read at a known rung, so a refusal can always be traced to the block that caused it.

The rung at which each declaration block is read, and the record fields it informs
BlockRead atWhat it decides thereOn the record
identityRung 1 IDENTITY · gate G2 ResidencyWhich tenant and residency domain the process belongs to, and which system of record it writes to.F01 · F06
write_typesRung 2 WRITE DOOR · rung 5 GUARDRAILThe door opens only for declared write types. The guardrail measures the blast radius against the declared limit.F05
gatesRung 3 PRE-GATESWhich gates run, in which order, with which parameters, and the refusal code each emits.Refusal code, beside the record
shapeRung 3 PRE-GATES · rung 4 evaluate()The record type and how each field is classified, which tells consent and retention gates where personal data may sit.F12 · F13
permissionsRung 6 AUTONOMYWho may propose and who may approve, by actor kind, role and minimum autonomy. Above the ceiling, a named person decides.F09 · F10 · F11
proof_bindingRung 8 PROOFWhich fields the proof commits to, and how they are canonicalised. It never adds a field: the record stays at sixteen.F14
channelsRung 1 and the connectionWhich channels may carry the process, and in which mode. Only a Mode A channel is enforced.Mode mark, in every export

Every rung reads the declaration version that was in force when the intent arrived. See The Right Path for every rung.

An illustrative declaration

The month-end close declaration for Kolam Components*, at version 7: the declaration that specimen record seq 1042 was checked against. It is written as JSON here to show the shape of the seven blocks. The serialisation format is in the customer reference.

jsondecl_month_end_close · version 7JSON code: decl_month_end_close · version 7
{
  "declaration_id": "decl_month_end_close",
  "declaration_version": 7,

  "identity": {
    "name": "Month-end close",
    "owner_role": "financial_controller",
    "residency_domain": "in",
    "system_of_record": "erpnext_hosted"
  },

  "shape": {
    "record_type": "journal_entry",
    "fields": [
      { "name": "posting_date", "class": "business" },
      { "name": "accounts",     "class": "business" },
      { "name": "amount_inr",   "class": "business" },
      { "name": "narration",    "class": "may_contain_personal_data" }
    ]
  },

  "permissions": [
    { "actor_kind": "agent", "role": "close_agent",          "may": "propose", "min_autonomy": "A1" },
    { "actor_kind": "human", "role": "accounts_executive",   "may": "propose" },
    { "actor_kind": "human", "role": "financial_controller", "may": "approve" }
  ],

  "write_types": [
    {
      "write_type": "journal_entry.post",
      "blast_radius": { "max_amount_inr": 500000, "max_records": 1 },
      "dual_control": true,
      "gates": ["G2", "G9", "G4", "G6"],
      "reversal_plan": "compensating_entry"
    }
  ],

  "gates": {
    "G6": { "budget_period": "month", "on": true },
    "G8": { "on": false, "decision_record": "dr_specimen_0007" },
    "G9": { "preconditions": ["period_open", "no_duplicate_number"] }
  },

  "proof_binding": {
    "commit_fields": ["posting_date", "accounts", "amount_inr", "narration"],
    "canonicalisation": "<per the record-shape reference>"
  },

  "channels": {
    "web": { "mode": "A" },
    "mcp": { "mode": "B" },
    "api": { "mode": "B" }
  }
}
Illustrative specimen. Not customer data. Keys inside each block are illustrative.

*Fictional company; all data is illustrative. Gate identifiers follow the kernel register (G1 Consent to G9 Precondition). The six gates that are never skipped run whether or not a write type lists them; the list sets their order. G8 Schedule is switched off here, which needs a decision record.

Reading it

  • The close agent may only propose, at A1 or above. It may never approve, and no permission can grant that.
  • journal_entry.post is the only door. Any other write type is refused at rung 2.
  • Dual control is on, so a second named person approves every posting. The approver is never the asker.
  • A posting above ₹5,00,000 or touching more than one record exceeds the blast radius and is refused at rung 5. (Illustrative limits.)
  • The web channel is Mode A, where elan1 Work holds the write credential, so writes there are enforced. MCP and API are Mode B: evaluated and recorded.

Versioning

A declaration is never edited in place. A change is registered as a new version, through define, and the old version stays exactly as it was, because records still point at it.

  1. Draft.

    The rules are written in Declaration Studio, block by block. A draft governs nothing.

  2. Register at an explicit version.

    define registers the declaration at a stated version and returns a content-addressed digest. Registering is itself a governed write under dual control, so it is held for a second named person and leaves its own proof record.

  3. In force.

    From then on, write intents for the process are evaluated against that version, and each record carries it in F07.

  4. Change.

    A new version is registered the same way. Writes after it name the new version; every earlier record still names the version it ran under.

  5. Replay.

    The same intent, under the same versions and the same as-of time, gives the same decision. That is what makes an old record checkable against old rules.

textRegistering version 8, then writing under itTEXT code: Registering version 8, then writing under it
define(decl_month_end_close, version 8)      # registering is itself a governed write
  → dual control: a second named person must approve the new version

  ← escalated  waiting for usr_specimen_controller_2 at rung 6
  ← committed  declaration_version 8 · digest sha256:7a1d…c03e · proof record sealed

assert(journal_entry.post, …)                  # every later write names the version it ran under
  ← committed  F06 decl_month_end_close · F07 8 · F08 2027.06.1
Illustrative specimen. Not customer data.
  • Pin versions. A production key cannot ask for “latest”; every decision records the versions it used. This is conformance test C13.
  • Wide autonomy costs more control. Where a declaration lets an agent act at A5, at tenant scope, the declaration itself needs dual control.
  • Policy has its own version. F08 policy_version records the version of the policy rules evaluate() ran, separately from the declaration version, so either can move without hiding the other.

How a record names its declaration

Four fields tie a record to its rules. Here they are on specimen seq 1042:

Fields that name the rules on a proof record
FieldNameSpecimen (seq 1042)
F05write_typejournal_entry.post
F06declaration_iddecl_month_end_close
F07declaration_version7
F08policy_version2027.06.1

Illustrative specimen. Not customer data.

To answer “which rule allowed this?”, read F06 and F07, open that exact version, and find the write type in F05. Because each of these fields is inside the hashed preimage, changing which declaration a record claims would break the chain. See the preimage.

From L2, the evidence bundle carries a declarations/ member, so the rules a record names travel with it and can be read offline, without us.

Decision Packs compile to the same blocks

elan1 Decide’s Decision Packs bundle the schemas, context, thresholds and write types for one use case, such as claims first notice of loss or AML alert triage. A pack holds schemas from Decision Studio, a calibration plan, routing tiers, review queues and the write types it may propose, and compiles to the same seven blocks. There is one rule format across the layers, and a pack never becomes a second kernel: its writes still go to elan1 Govern as intents, in Mode B.

What the customer reference covers

  • Serialisation format and keys inside each block

    The block names are fixed. The keys, value types and file format shown above are illustrative.

    In the customer reference

  • How the content-addressed digest is computed

    define returns a digest of the registered version; its canonical form is part of KernelPort v1.

    In the customer reference

  • Pack gate names and the kernel's nine gates

    Accounting packs name gates by what they check in the books, such as G1 Ledger and G4 GST. How each pack gate maps onto the nine kernel gates is listed per pack.

    In the customer reference

  • Intents held across a version change

    What happens to a write held for approval when a new version is registered before the approver acts.

    In the customer reference

  • Refusal codes per gate

    Codes on this site are illustrative; the closed register is part of KernelPort v1.

    In the customer reference

// DECLARE IT

Put one real process on the governed path.

Customers write their first declaration with us during onboarding. Early-adopter design partners also help shape what comes next.