docs/0realtalk-grammar.mdpinned to impactium@637886d

0REALTALK — the language the chain is written in

Grammar version: 0.3.2 · pre-genesis

0REALTALK is a contextual language. A term carries its own frame: -3 is a number and means nothing on its own, while 0DOOM carries its scale, its direction and its zero-anchor wherever it appears. An agent meeting a term on the chain needs no accompanying manual to read it.

Impactium is written in it. An accountability expression, an impact expression, a sacred number and a settled verdict are not four formats — they are one language, and this page is its published grammar.

Section numbers are citations. impact-sdk-realtalk cites this page as grammar §4.5, and a reference written decisions §81 points at the decision log instead — a separate, internal document. Both render as §NN, so the qualifier is always written out.

This grammar is pre-genesis, and its version is 0.x for that reason. The constructs below are implemented and stable enough to build against; the language as a whole has not been ratified, and §4.6 says plainly which parts are still moving. Pin GRAMMAR_VERSION from impact-sdk-realtalk if you need to know which revision a release implements.

Why a language and not a format

The alternative was a set of fingerprint formats with a rule sheet per format. That does not survive its first hard case.

#O0{#E0} — "one party acting on behalf of another" — has to yield three different results depending on where it is read from. As a format that needs three bespoke rules, each remembered and applied by hand. As a language it is simply what a closure does, and the same machinery then answers every later case for free. See §4.5.

1. Lexical structure

Token Form Example
TERM 0[A-Z][A-Z0-9]* 0DOOM 0BIKE 0SCALE
ENTITY [#$@][A-Z]{1,2}[0-9A-F]+ #E0 $AP1 @E1
NUMERAL -?[0-9]+(\.[0-9]+)? 4 100000 5.1
SACRED ^ + name or numeral ^GRID ^4 ^PI
ATTR ~key=value ~v=5%2E1 ~scope=team
ELISION % + hex commitment %a1b2c3d4e5f60718
QUANTIFIER <*>, <TERM>, <ENTITY-CLASS> <*> <#E>
COMPOSE . #E0.#O0
CONTAIN { } #O0{#E0}
LIST [ , ] [0ECONOMIC, 0SOCIAL]
SPAN <> COA <> COI
PERSPECTIVE > expr > #E0

A sigil is earned, not assigned. A construct gets its own symbol only if it changes the shape of an expression. Anything that adds detail is an attribute — which is why scope, version and kind are ~k=v rather than sigils, and why the symbol budget stays small enough to read.

1.1 Attributes ~k=v

Attributes carry detail without spending a sigil. Values are percent-encoded for the characters that already mean something in the grammar — . ~ = % ^.

This is not tidiness. A model version is 5.1, and a raw dot there is the segment separator, so it splits one segment into two. v=5.1 is only ever valid written ~v=5%2E1.

2. Sacred numbers ^

A sacred number is a numeral that carries its own frame. 4 is a number; ^GRID is 4 together with what it means, so a reader meeting it needs no lookup table.

Their kinds form a mutability ladder that is enforced rather than documented — universal constants are never amendable however good the justification, structural ones require a recorded reason, and calibration constants amend through ordinary governance.

Sacred numbers resolve from the chain's lexicon, never from the expression. An expression that carried its own definition of ^GRID could redefine the frame it is evaluated in — the "instructions arriving inside content" pattern, which on a value ledger is an attack rather than a convenience.

2.1 Deliberately unset

A calibration constant may be declared unset, which records "this has not been decided" on chain rather than burying an invented number in a grammar. A reader who resolves one finds the deferral and its reason, never a plausible constant with no provenance.

Currently unset: the proximity decay function, the charge for a failed proof-of-functioning attempt, and the magnitude of the closure rule's outward recognition.

3. Expressions

3.1 Composition . — order is the claim

A chain reads actor last. The final element acted; everything before it is who they acted for.

written means
#E0.#O0 Civicognita for Wishborn
#O0.#E0 Wishborn for Civicognita

These are different claims and neither is derivable from the other. A segment's dimension comes from its sigil — #E0 is an Entity wherever it sits, so parsing needs no position — but a segment's meaning is entirely positional, and no sigil recovers it.

Actor-last governs the whole expression. The final element acted, literally — so anchors and lineage lead rather than trail, and the canonical form runs C001.@A0.#E0.$A0. This resolves a contradiction the earlier format carried: it ended .@Node.Lineage, an anchor and a lineage id rather than a party, so "the final element acted" was false of every expression written under it.

Canonical order is asserted, never imposed. An expression whose segments are out of canonical order is refused. It is not silently reordered, because reordering across sigil classes changes what the expression says: rewriting $AP1.#E0 to #E0.$AP1 turns "#E0 acted for $AP1" into its opposite. A parser that normalises here would hand back a clean result meaning the reverse of what was written.

SHIPPED. x-network's canonicaliser orders Chain.@Node.%elision.#Entity.$Resource.0TERM, Coa::parse refuses a non-canonical order, and x-identity emits the same order — the three spellings that used to disagree now agree, and a test asserts it.

3.2 Containment {} — the closure

#O0{#E0} is "the outer party acting through the inner", and it is not the same as #O0.#E0. The outer party is the binding and the public face; the inner party executed. Nesting is legal at arbitrary depth: #O0{#T1{#E0}}.

What a containment evaluates to is §4.5.

3.4 Elision %<commitment> — opaque, not absent

A record rendered at a broad layer must not carry detail registered at a narrow one. Segments that do not reach the reader are removed and replaced by one commitment — a hash over their canonical form.

%a1b2… evaluates to an opaque party: present, provable, unnamed. It has to be a real construct rather than a gap, because the evaluator must distinguish "a party is here and I cannot see who" from "no party."

Eliding a party must not change the weight totals. If it did, an observer could detect and size the hidden party by arithmetic, and the elision would leak exactly what it exists to hide. An opaque party carries its full weight; only its identity is withheld.

Elision is committed, never silent: the commitment lets an upstream reader learn that local detail existed and that it has not changed since, and nothing about what it was.

3.6 Lists [] — silos are sealed

[0ECONOMIC~m=+2, 0SOCIAL~m=+1] is impact in two domains. A list is not a sum. Domains never convert, so the language deliberately offers no arithmetic operator between impact terms — there is nothing to add them with, by design.

4. Context and evaluation

Every expression evaluates in a context:

field what it carries
layer the collective the reader is reading from
perspective whose viewpoint values are derived from
epoch when it is evaluated
population the universe a quantifier resolves against
proximity graph distance to the subject matter

4.2 The restriction rule

The evaluator always supplies the context. An expression may only make the visible set smaller.

visible(ctx) = { scope : scope is ctx.layer, or scope CONTAINS ctx.layer }

In plain terms: you can read records at your own level, and at any collective you belong to. What happens inside a family does not travel up to the city in the clear.

visible is the set of records a reader may see in full. A record outside it still counts toward any total; only its details are sealed.

ctx is the context a record is read in, and it always comes from the reader. That is what stops a record from choosing its own audience.

ctx.layer is the collective the reader is reading from: a person, their family, their organization, their city.

scope is the collective a record belongs to, the level it was recorded at.

CONTAINS holds when one collective sits inside another, directly or through a chain of memberships. A city contains the families in it, and so it also contains the people in those families.

The rule is stated as a set deliberately, because no direction word survives this structure. "Up", "above" and "outward" each invert depending on whether you picture the containment or the tree that draws it, and "narrow" is worse still — evaluating deeper in reveals more, not less, so a rule reading "an expression may narrow the context" permits precisely the escalation it exists to forbid. A set has no direction to get backwards.

A refused restriction is an error, never a clamp. Silently clamping would let an expression request an escalation and receive a plausible-looking answer.

4.2a Perspective is not access

> changes whose viewpoint values are derived from. It does not move the layer gate.

Keeping the two apart is what makes the operator safe to expose. If perspective carried access, record > #E0 would grant the evaluator everything #E0 can see, and anyone could read anyone's narrow-scoped detail simply by naming them. Perspective decides how much something is worth to whom; the layer decides what is legible at all.

4.4 What evaluation yields

eval(record, ctx) -> [ (party, domain, share) ]

A weight distribution: who receives how much, in which sealed silo, at this context. The accountability expression is the program; the weight is what it evaluates to.

eval works out who a record credits, in which kind of impact, and by how much. The record is the instruction; the weights are what it produces.

record is the entry being evaluated: who acted, on whose behalf, and what it affected.

party is someone the record credits: a person, an organization, or a sealed placeholder standing in for a party the reader cannot see.

domain is the kind of impact the credit lands in, such as social or economic. Impact in one domain never converts into another.

share is how much of the record's weight that party receives in that domain.

Determinism is a consensus requirement, not a quality goal. The same expression, context and chain state must produce identical result bytes across platforms and versions. A non-determinism in evaluation is a chain halt.

4.5 The closure rule

One expression, three loci, three results — and all three hold at once:

locus result
the layer the record was submitted on #O0 — Production. The outer party is the public face
inside #O0 #E0 — Production. The internal truth
outward #E0 — Social. Recognition crossing the boundary

They do not net against one another. Impact silos are sealed — domains may influence each other but they never convert — so the inner party's outward recognition is not the outer party's production credit seen from further away, and no arithmetic relates the two.

Nesting resolves one boundary at a time. #O0{#T1{#E0}} credits #T1{#E0} whole at the inner locus, and that expression is evaluated in turn. How results compose across two boundaries is not yet ruled, so nothing composes them.

4.6 What is not settled

Stated plainly, so nothing above is mistaken for finished:

  • The impact silos themselves. The set of domains is being described and is not fixed. §4.5 names Production and Social because its own specification does; that is not a claim about what else exists.
  • Composition weights. That order matters in A.B is settled. How much each position receives is not, and guessing it would bury a fabricated constant inside a grammar.
  • The magnitude of outward recognition in §4.5's third row.
  • How closure results compose across nested boundaries.
  • Guards, terminals and NULL are implemented but not ratified, including whether a guard may have side effects at all.
  • Quantifiers (<*>, <#E>) — ruled and not yet built. Collective named two things, and separating them settled most of this. A population is picked out by class ("every Personal entity"); a collective Entity is registered and has members — an Organization, a Family, a Municipality. Only the second can be an actor, because only it has a keyholder who could have acted, and it needs no notation at all: it is an Entity, so # already parses it and the canonical order already sorts it. Both constructs are kept, so the population still needs a spelling, and it is angle brackets. What is not settled is how a population is RESOLVED — by consulting the class registry, or by walking collective membership — and whether scope names a registration rung or a network. Nothing here is lexed yet.
  • The perspective operator and the span are specified and not yet built.
  • A 0TERM's semantics. It now sorts last, terminating the chain (#E0.0BIKE is "Wishborn's bicycle"), but what a chain terminating in an unregistered object means for evaluation is unspecified.

6. Guards ¿

¿PREDICATE( consequent | alternative )

The predicate is evaluated; on satisfaction the expression is the consequent, otherwise the alternative. Wrapped in a terminal :( … ): it becomes a settled verdict.

PREDICATE is the condition a guard checks. A name the chain does not recognise stops with an error, so a typo can never silently switch a guard off.

consequent is what the expression becomes when the condition holds.

alternative is what the expression becomes when the condition does not hold.

An unknown predicate is an error, never false. If a misspelled predicate quietly evaluated as unsatisfied, the guard would refuse forever while reading exactly like a guard that works — a typo would disable a gate and nothing would say so.

A branch may be NULL, meaning never entered consideration — which is deliberately not the same as rejected. Rejection is a judgement somebody had to make; a gate exists so that nobody had to.

Implementation

The grammar is implemented in impact-sdk-realtalk, which is dependency-free on purpose: anything evaluated inside consensus makes every dependency a determinism surface and an audit surface in a validator. It uses no floating point and no unordered iteration, for the same reason.

GRAMMAR_VERSION in that crate names the revision of this page it implements, and a test fails the build if the two ever disagree.