Meriadoc (ChatTheatre, 2026)

Meriadoc -- formally Mediated Execution Registry Involving A Dialect Of C, conversationally "Merry" -- is the reference implementation with operational evidence that sandboxed code-load on a property graph works at production scale. The implementation has run in continuous production deployment for over twenty-five years, carrying all five axes of code containment (language, location, invocation, capability, atomic rollback) as substrate primitives rather than as review-time discipline.

The pattern: source lives as a property on objects in the persistent state graph; setting the property compiles the source into the live runtime image; execution happens only when a named signal is dispatched to the storing object. The dispatch model is multi-phase (pre / prime / post), and the dispatcher walks the property's data-inheritance chain (the refererence implementation's "ur-parent" chain, distinct from any host-language class inheritance) to find the matching handler under the host's atomic-call envelope. The handler runs in a constrained vocabulary -- a fixed grammar plus a host-defined function library -- over a denylisted host kernel. The deployment-specific function vocabulary the implementation ships with is a dialect choice that another deployment would adapt to its own object model.

In an eOS workspace, this means an LM-driven agent can author durable handlers directly on workspace objects. When a sub-call commits a result into the namespace, a meriadoc:react:result_committed handler can propagate a constant-size metadata summary upward to the parent reasoning context -- the architectural property RLM proposes at user-space Python scale, realized here at substrate scale. Tools an agent authors are written as properties on workspace objects; the property-set hook compiles them into the live image, and they remain available across process restarts because they live in the orthogonally persistent state graph rather than as ephemeral functions in a Python REPL whose state evaporates on process death. And because handlers themselves live as properties, the same signal mechanism applies to handler authorship: handlers can witness handlers being authored, validated, or revised, making meta-programming a first-class composition surface rather than a meta-layer bolted on top.

Signal-system shape

The pattern requires a host signal system that supports multi-phase dispatch for any operation interesting enough to want hooks around. Three phases generalize cleanly to any reactive substrate; a fourth phase exists in the original text-environment domain and is not part of the pattern.

Pre -- early veto. Fires after the substrate sanity-checks the operation's arguments but before any state mutates. Handlers may inspect the operation's parameters and abort it. Runs inside the triggering operation's atomic envelope -- a pre-handler error reverts the entire operation. Use for state-aware argument validation ("can this principal even attempt this operation?").

Prime -- late veto. Fires when the substrate believes the operation should proceed (preconditions satisfied, no early veto fired). Last opportunity to abort, with the operation's full intent visible to the handler. Runs inside the same atomic envelope as pre -- a prime-handler veto rolls back not only the prime work but the work the operation has already done. Use for veto that depends on state the early phase could not yet decide ("the workspace compiled the LM-authored expression cleanly, but its closure references a capability the principal does not hold; abort before the expression executes").

Post -- react. Fires after the operation has committed. Most common phase to bind to. Runs in a new atomic envelope of its own, so a post-handler error does not retroactively roll back the triggering operation -- post handlers see committed state and react to it; they cannot veto. Use for side-effect cascades ("after a sub-LM call commits its result to a workspace variable, propagate a constant-size metadata summary upward to the parent reasoning context").

A fourth phase, desc, exists in the implementation's hosting domain to compile observer-specific output for varying viewers of the same operation; it is a domain-specific rendering concern, not a generalizable phase of the pattern, and explicitly not part of this reference implemenation's adoption.

A handler binds to a <phase>:<signal> pair on an object. The dispatcher resolves a signal at dispatch time by walking the storing object's data-inheritance chain, so a child object that has not overridden a parent's handler still picks up the parent's behavior. Exactly one handler runs per phase per dispatch -- the first match in the data-inheritance walk, with the child's override taking precedence over its parents' bindings. This is method dispatch, not event-bus fan-out: there is no implicit chaining, no observer-list aggregation, and no subscription-order dependency. Behavior is deterministic in the resolution order. This is what makes "fork an object's behavior by overriding one phase of one signal" the dominant authoring pattern -- and what differentiates Meriadoc from systems where hooks are registered globally rather than carried by the object that owns them.

The foundational signal source in an eOS workspace is the property write itself. The 2004 design document names the primitive directly: "Setting a property on an object fires an event ... this allows developers to hook complicated [scripts] up to react to changes in properties." When any property changes on an object, the substrate fires the change through the same pre / prime / post protocol any other operation uses; handlers register interest by binding to a property key (or a namespace prefix), and they receive the proposed value, the principal performing the write, and the operation's atomic envelope. This collapses what other systems treat as separate concerns -- property setters, observer hooks, schema-validation hooks, change-emit events -- into a single substrate primitive. Operations from the broader operation flow (sub-call dispatch, capability extension, recursion-step transitions, tool invocation) layer on top of the same protocol; pre / prime / post phases are the substrate's atomic-call envelope made dispatchable.

Property-system minimum

The pattern's substrate floor is more than just "an object has properties." Four capabilities are required:

Two further capabilities are commonly used but not strictly required:

A property system that supplies the four required capabilities (keyed map, set-time hook, data-object inheritance, persistence) is sufficient to host the pattern. eOS Continuum's substrate carries all four as primitives.

Data inheritance, not code inheritance

The refererence implementation's substrate provides two distinct inheritance systems, and Meriadoc handlers compose through one of them, not the other.

Code inheritance is the host language's compile-time class inheritance (LPC's inherit directive). It composes the substrate's own implementation: the dispatch object that runs Meriadoc handlers inherits from a curated set of host libraries; system services inherit from kernel libraries; the runtime's structure is built through code inheritance the same way any host-language program is.

Data inheritance is a separate runtime mechanism that operates on data objects through the property system. A data object names another data object as its parent ("ur-parent"); property reads on the child cascade through the chain, and the child may override individual properties. Crucially, in the refererence implementation's design, all data objects are clones of the same underlying host class -- their behavior differs entirely through their data-inheritance chain, not through programmatic class. The compositional surface for authoring (world authoring in the refererence implementation; tool authoring in an eOS workspace) is the data graph, not the class graph.

Meriadoc handlers compose through data inheritance because they are properties on data objects. To specialize a handler, an agent clones a parent object and overrides one property; the clone inherits every other handler, shares the host class, and differs only in its property store. There is no new class, no recompilation, no separate code unit. Code inheritance and data inheritance evolve on different timescales -- code on substrate-source-change (with hot-reload to merge updates), data on principal-authored-property-change -- and the substrate's machinery for managing data inheritance does not require code recompilation. The two systems coexist without interfering: substrate maintainers extend the runtime through code inheritance, and agents extend their workspace through data inheritance, and neither path can substitute for the other.

This distinction is not cosmetic. The refererence implementation's design choice -- many data-object instances of one host class, distinguished by ur-parent state, rather than many host classes with one instance each -- is precisely what makes the code-as-state principle workable at the workspace scale an LM-driven agent will exercise. Class-based composition would force every tool variant to be a new class; data-based composition lets variants exist as cloned property bundles, persistable and inheritable through the substrate's existing primitives.

Reflexive composition

Because Meriadoc handlers themselves live as properties, the property-write signal mechanism applies to handler authorship too. Writing a handler to meriadoc:react:<signal> is itself a property write that fires its own pre / prime / post protocol; other handlers can witness it. The pattern is reflexive: handlers and the things handlers witness are the same kind of substrate object.

This is the structural consequence of the code-as-state principle. Worked examples relevant to an eOS workspace:

Meta-programming is a first-class composition surface, not a meta-layer bolted on top of a fixed event schema. This is what differentiates the pattern from systems where hooks are second-class additions, and from systems where the script population is opaque to the scripts themselves.

Limitations of modern "safe" languages

Modern language-level safety -- memory-safe languages (Rust), sandboxed runtimes (WebAssembly + WASI, V8 isolates, Lua interpreters), capability-typed embeddings -- addresses real problems and gets things right that Meriadoc does not. Modern safe languages have superior tooling, broader audience familiarity, sophisticated type systems, near-native compute performance, and decades of investment in cross-platform portability. For workloads where the safety question is "can untrusted code crash the host process or escape the FFI boundary," any of them is a reasonable answer.

The structural gap, relative to what an LM-driven agent workspace needs, is that none of them addresses state-substrate concerns. Their containment story stops at the language boundary; the substrate they run on does not natively carry the properties an agent's persistent reasoning surface requires. Concretely:

The graph's [[Agent Code Containment Stacks Five Axes, Not One]] table places Wasm + WASI at 2 axes, Lua at 1, Erlang processes at 2. Composing additional axes means stacking technologies (Wasm in a container in a transactional database with a supervisor and an event bus); the composition's boundaries are exactly where bugs live. Meriadoc's 5-of-5 containment is the substrate's natural property, not an externally-stacked composition.

The reference implemenation does not claim modern safe languages should be displaced for workloads where state-substrate concerns are not load-bearing. Pure compute, embedded scripting in non-stateful contexts, sandboxes for untrusted code with clear boundaries -- those workloads do not need orthogonal persistence or reflexive composition, and the modern-safe-language ecosystems serve them well. The narrower claim: for an LM-driven agent workspace where state-substrate properties are exactly the bugs the application keeps fighting, the modern-safe-language path stacks technologies to approximate what Meriadoc's substrate carries natively. The conceptual shift is that instead of making code safe around the system, the substrate is the safety boundary.

Adopted

The code-as-state principle (Property-system minimum and Data inheritance subsections above carry the substantive treatment). Policy and data live in the same store, under the same data-object (ur-parent) inheritance, in the same atomic envelope, with the same persistence -- the substrate model eOS Continuum names as primitive #6 ([[Code Load Compiles Into the Live Runtime, Bounded by Capability Tiers]]).

The five-axis containment claim, grounded in operational artifact with per-axis citations. The graph's [[Agent Code Containment Stacks Five Axes, Not One]] table places the refererence implementation substrate plus Meriadoc as its DSL surface at 5 of 5 axes covered, each enforced by a specific mechanism in the source:

A reviewer can verify each axis by reading the named files. The 5/5 claim is grounded in current implementation behavior, not aspirational design.

The decoration-and-compile strategy. The implementation has no separate VM. Source is decorated host-language: same control flow, same operators, same types, plus syntactic sugar for property access, object refs, argument refs, inline templating, and a delay statement. A grammar pass rewrites the decorations into pure host-language AST nodes; the host compiles the result with its normal compiler and caches it. Safety is enforced at the host-language level, not by interpretation in a separate runtime -- which is why the implementation runs at host-native speed and inherits the host's atomic-rollback semantics for free.

The pre / prime / post phase model (Signal-system shape subsection above). The three generalizable phases form the application surface of the substrate's atomic-call envelope, essential to the veto / late-veto / react composability the pattern enables.

Not adopted (yet)

The deployment-specific function vocabulary. The implementation ships with a function library shaped by its specific hosting deployment rather than by a substrate-layer use case. These deployment-specific primitives presuppose an object model and content surface eOS Continuum does not share; the pattern lifts but the dialect does not. eOS Continuum's adoption is at the pattern layer; the function vocabulary the substrate exposes will be shaped by what eOS workspaces actually need -- sub-call coalescing, namespace operations, capability extension, recursion-budget management, tool authoring and indexing, and reasoning-trace introspection.

The fourth signal phase, "desc". The implementation dispatches a fourth phase per signal to compile observer-specific output for varying viewers of the same operation. This is a domain-specific rendering concern, not a generalizable phase of the pattern, and explicitly not adopted.

The functional-templating sibling. The implementation ships alongside a separate functional templating layer for variable output text. eOS Continuum may need its own content layer or none at all; the templating sibling is not part of the code-load pattern this Reference adopts.

The specific property-namespace conventions and dialect-level idioms. The implementation uses naming patterns like merry:react:<signal>, merry:lib:<name>, merry:inherit:<mode>:<signal>, plus dialect-level constructs (named-reference values, named-object constants, inline-templating literals, label calls between named script-spaces). These are the implementation's specific conventions; eOS workspaces will name and shape their script-properties according to their own conventions.

Open verification questions

Three determinism properties an LM-driven workspace would benefit from having confirmed, but which are not yet verified by by reading of the reference implemenation source. They are reasonable design properties for a deterministic self-modifying runtime; whether the implementation enforces each (and how strictly) is a source-verification task flagged here as potential future development. Confirming each would strengthen the reference implementation's 5/5 containment claim and the eOS substrate's reflexive-composition guarantee.

These three are flagged for future development rather than as current limitations. The reference implementation's containment story holds at the level of language, location, invocation, capability, and atomic rollback regardless of how each verification resolves; the determinism story is a separate, sharper claim that would benefit from the verification.

Sources

Relations