C# Implementation โ
The C# implementation maps the four runes to native language idioms โ attributes for declaration, reflection for auto-registration, and a plain class as the host. No framework dependency. No runtime requirement beyond the standard library.
Three files. Each has a distinct role.
RuneCore.cs โ Domain Model โ
The complete domain model. Four types, a parser, three stores.
// The four runes as a first-class enum
public enum RuneType
{
Read, // @ one-way, state โ display
Sync, // ~ two-way, input โ state
Act, // ! explicit trigger, user โ behavior
Intent // ? annotation, no runtime effect
}
// A parsed binding โ what comes out of the parser
public record RuneBinding(
RuneType Type,
string Identifier,
string? Annotation = null, // populated for ? only
string[] Args = default // populated for ! with arguments
);
// Stable, spec-defined error codes
public enum RuneError
{
RNE001_UnknownRune,
RNE002_UnresolvedIdentifier,
RNE003_SyncToComputed,
RNE004_ConflictingRunes,
RNE005_WrongArgumentCount,
RNE006_ReadOnInputElement,
RNE007_SyncOnDisplayElement
}Parser โ sigil โ RuneBinding. Handles @identifier, ~identifier, !action with arg1 arg2, ?"annotation". Validates composition rules: @ and ~ cannot coexist on the same element.
RuneStateStore โ mutable values + computed (read-only derived) values. Set() throws RNE003 if the target is computed. Subscribe() returns a disposable โ used by UI frameworks to trigger re-renders.
RuneActionRegistry โ named async behaviors. Four Register() overloads covering zero-arg, single-arg, async, and sync. Dispatch() throws RNE002 if the action is not registered.
RuneIntentStore โ ? annotations, never discarded. All exports the full intent map as a dictionary โ consumed by AI tooling, audit systems, and documentation generators.
RuneHost.cs โ The Host โ
One host per document or screen. Wires the three stores together and provides the surface that UI frameworks consume.
public class RuneHost
{
public RuneStateStore State { get; } = new();
public RuneActionRegistry Actions { get; } = new();
public RuneIntentStore Intent { get; } = new();
public object? Read(string identifier) // @ โ resolves dot-notation
public void Sync(string id, object? v) // ~ โ write to mutable state
public Task Act(string name, ...) // ! โ dispatch named action
public void RecordIntent(...) // ? โ record annotation
}RuneHostBuilder โ reflection-based registration. Scans a class for [RuneState], [RuneComputed], [RuneAction], and [RuneIntent] attributes and auto-registers everything. ToKebabCase() converts RiskThreshold โ risk-threshold automatically.
// Auto-wire an annotated class โ one line
var host = RuneHostBuilder.From(new TaskWorkbook());
// What a template engine calls
host.Read("pending"); // @
host.Sync("new-task", "Buy milk"); // ~
await host.Act("add-task"); // !
var intent = host.Intent.All; // ?Example.cs โ Usage Patterns โ
Three patterns showing the protocol in action.
Pattern 1 โ Attribute-based (declarative)
public class TaskWorkbook
{
[RuneState]
[RuneIntent("active task list โ user-managed, no auto-sorting")]
public List<TaskItem> Tasks { get; set; } = [];
[RuneState]
[RuneIntent("current input value, cleared after add-task fires")]
public string NewTask { get; set; } = "";
[RuneComputed]
public IEnumerable<TaskItem> Pending => Tasks.Where(t => !t.Done);
[RuneAction("add-task")]
public void AddTask()
{
if (string.IsNullOrWhiteSpace(NewTask)) return;
Tasks.Add(new TaskItem(Guid.NewGuid(), NewTask, false));
NewTask = "";
}
}Pattern 2 โ Fluent (explicit)
var host = new RuneHost();
host.State.DeclareComputed("market-price", () => riskService.GetMarketPrice());
host.State.Declare("risk-threshold", 0.15m);
host.RecordIntent("risk-threshold",
"approved by risk committee Q1-2025 โ review at quarter end");
host.Actions.Register("submit-order", async (object?[] args) =>
{
var orderId = (Guid)args[0]!;
await riskService.SubmitOrder(orderId);
});Pattern 3 โ Template engine integration
Shows how a host format processes element attributes, resolves bindings, and dispatches actions โ the complete render/sync/act loop.
Full Source โ
implementations/csharp/ on GitHub.