Rune Protocol: Discovered, Not Designed
Mere had four sigils before they had a name. @ ~ ! ? — read, sync, act, intent — were working in a reactive document format before anyone asked what they were formally. The protocol wasn't invented. It was extracted. What it turned out to be: a bounded-complete reactive binding grammar, a governance layer, and the syntax substrate the whole ecosystem was already running on.
The Sigils Were Already Working
Mere is a workbook format where the file is the app — a single .mp.html that contains screens, state, behavior, and theme. No server. No build step. Open it and it runs.
Inside that format, four sigils handle every interactive operation:
<!-- @ read: display a value from state -->
<list @tasks>
<item @item.title />
</list>
<!-- ~ sync: two-way binding between input and state -->
<field ~new-task placeholder="New task…" />
<!-- ! act: explicit trigger -->
<button !add-task>Add</button>
<!-- ? intent: annotation for humans and AI -->
<screen ?"mobile task list, minimal, focus on speed">These four sigils were working before anyone asked what they were formally. A Mere file with ~new-task, !add-task, and @pending was a complete reactive application — no framework, no runtime dependency, four characters. The question “what is this as a protocol?” came after the fact.
Extracting the Protocol
The moment of recognition was not “let's design a binding protocol.” It was “these sigils are not Mere-specific — they are the answer to a question every reactive system asks.”
SQL has named state, user input, actions, and annotations. React has them. Configuration files have them. Clinical records have them. Trading systems have them. Each domain solved the same four problems differently, incompatibly, and — with one exception — incompletely. The incompatibility is familiar: React's onChange is not Vue's v-modelis not Angular's [(ngModel)]. None are interoperable.
The incompleteness is less obvious but more significant. Every existing framework covers three of the four operations. None covers the fourth. Mere had all four. Extracting the protocol meant naming what was already there — not inventing something new.
That origin is the strongest credential a protocol can have. The theory describes a working system. It does not prescribe a hypothetical one.
Why Exactly Four
The obvious question: why four? Why not three, or five, or twelve?
The answer is that four is not a design choice — it is the result of a proof by elimination. Start with the four and attempt to collapse them:
Merge @ and ~Merge ~ and !Remove ?Add a fifthThe four runes are bounded complete: they cover every reactive document operation, and no subset covers them all. That bounded completeness is what makes Rune embeddable as a protocol rather than a framework — it has a floor and a ceiling, and both are provable.
The Primitive Nobody Built
Three of the four runes have rough equivalents in existing frameworks. The fourth does not.
| System | @ Read | ~ Sync | ! Act | ? Intent |
|---|---|---|---|---|
| React | {val} | onChange | onClick | — |
| Angular | [prop] | [(ngModel)] | (event) | — |
| Vue | :prop | v-model | @click | — |
| SQL | VIEW | column | PROCEDURE | -- comment |
| Config | ${ENV} | value | — | # comment |
| Rune | @ | ~ | ! | ? |
The ? column is the one that matters. Comments exist in every system — but a comment is not ?. Comments are stripped by compilers, don't travel with bindings across layers, can't be queried at runtime, and carry no structural relationship to the construct they annotate.
? is different in every property: co-located with the binding it describes, versioned with the code in the same commit, addressable by name, and queryable at runtime. host.intent.for('risk-threshold') returns the full rationale. No equivalent call exists in any other framework. That call has no equivalent because no other framework has the concept.
Governance, Not Just Binding
The four runes look like a binding protocol. Under examination, they are a governance layer. Each rune is a governance primitive.
@ establishes a read boundary: this value cannot be mutated from here. That is a governance claim — not a naming convention, not a comment, a structural constraint. ~ makes the mutation surface explicit and enumerable: every mutable value in a system is named and addressable, and host.state is the complete list. An auditor can ask “what can be changed?” and get a structural answer.
! is the strongest governance statement in the spec. Nothing consequential happens without explicit invocation through a registered, named action. No implicit side effects. No back doors. In finance and healthcare and legal — domains where “nothing happened without intent” is a compliance requirement — this guarantee is what policy frameworks try to enforce through process. Rune encodes it structurally.
? is what makes governance survive time. Every governance system eventually fails because the rationale decays — the decision is preserved but the reasoning is lost. ? keeps the reasoning co-located with the binding it governs, in version control, readable by any reader including ones that don't exist yet.
// C# — governance as type system
[RuneState]
[RuneIntent("approved by risk committee Q1-2025 — review at quarter end")]
public decimal RiskThreshold { get; set; } = 0.15m;
[RuneComputed] // structural read boundary — cannot be synced
public IEnumerable<Order> Pending => _orders.Where(o => !o.Filled);
[RuneAction("submit-order")]
[RuneIntent("explicit, logged to OMS, irrevocable — pre-trade risk check runs here")]
public async Task SubmitOrder(Guid orderId) { ... }The governance isn't in the comments. It's in the attributes. An AI tool, an auditor, or a new engineer reads the same structural claims — not the same hope that someone wrote a comment.
What AI Reads
When AI works with a codebase it has two modes: infer or read.
Inference is archaeology. AI reads a property named riskThreshold, guesses it's mutable because there's a setter, finds a method that modifies it, searches comments for rationale, probably finds none. Every step is probabilistic. The quality of assistance is bounded by how accurately the reconstruction matches reality — which degrades with codebase size, naming inconsistency, and time.
Declaration is direct. [RuneState] announces mutability. [RuneComputed] announces that a value is derived and cannot be written. [RuneIntent] carries the rationale. The system has already answered every question AI would otherwise approximate.
The shift is not incremental improvement in AI-assisted development. It is a change in kind — from a codebase AI reconstructs probabilistically to a codebase that speaks directly to any reader in a grammar that does not decay. The quality of AI assistance stops being bounded by code quality and starts being bounded by the quality of the declarations — which are first-class, versioned, and maintained by the same discipline that maintains the code itself.
The Syntax Layer
A DSL owns the vocabulary and semantics of a particular domain. It answers what does this mean — what a TRADE is in finance, what a DIAGNOSIS is in healthcare, what a DIMENSION is in cascade analysis.
Rune sits one layer beneath that. It doesn't care what risk-threshold means in finance or what dosage means in a clinical record. It only answers how does this value behave — is it readable, mutable, triggerable, annotated. That question is pre-semantic. It appears in every domain without exception.
EMBER defines what constructs mean in a legacy modernisation context — INTENT, DIMENSION, THRESHOLD, SIGNAL. That is the semantic layer. Rune governs how EMBER bindings behave — which constructs are readable, which are editable, which trigger actions. Those are different questions, answered at different levels. Rune is the syntax layer. EMBER is the semantic layer. Neither competes with the other.
The same relationship holds across the ecosystem. Mere, Recall, Phoenix, Strata, Wake — each owns a domain vocabulary. Each answers a domain-specific “what does this mean?” Underneath all of them, the same four questions appear: is this readable, mutable, triggerable, annotated? Rune is the layer that answers those questions, once, for all of them.
The protocol was always running. It just needed a name.
The specification, reference implementations in C#, TypeScript, React, and SQL, and the full rationale are at rune.semanticintent.dev and github.com/semanticintent/rune-protocol.