Matrix logo

MCL Developer Documentation

The Matrix Communication Layer (MCL) is the compiler and protocol backbone of Matrix. Every user interaction starts here: natural language goes in, a typed signed Intent IR comes out.

The Matrix Communication Layer (MCL) is the compiler and protocol backbone of Matrix. Every user interaction starts here: natural language goes in, a typed signed Intent IR comes out, and the executor picks it up from there.

This documentation is written for people working on MCL itself, extending the language, adding skills, touching the pipeline, or understanding how the wire protocol works.


Contents

DocumentWhat it covers
MatrixScript LanguageThe .mtx DSL, syntax, constructs, grammar, all the details
Compiler PipelineThe 6-stage pipeline from intent.draft to intent.compiled
Intent IRThe ir package: Intent, Frame, PlanTree, all the Go types
Envelope & Wire ProtocolThe 15 message kinds, CBOR encoding, ed25519 signing
LLM ClientProvider abstraction, grammar-constrained decoding, seeding, model router
Writing a SKILL.mtxPractical guide to authoring and validating skill files
mclc CLI Referencecompile, validate, hash, parse commands

Repository layout

MCL/
├── cmd/mclc/               standalone compiler CLI (Go)
├── core/                   compiler-core .mtx modules
│   ├── pipeline.mtx        6-stage pipeline wiring
│   ├── verb.mtx            D7 closed vocabulary + classifier prompt
│   ├── frame.mtx           Frame type schema
│   ├── confidence.mtx      confidence scoring formula
│   └── ...
├── envelope/               wire codec: 15 message kinds, CBOR, ed25519
│   ├── envelope.go         Envelope struct, Sign, Verify, SelfHash
│   ├── kinds.go            15 closed message kind constants
│   ├── body.go             Typed body structs for all 15 kinds
│   ├── json.go             On-disk JSON representation (journal/logs)
│   └── keyresolver.go      KeyResolver interface for principal->pubkey
├── ir/                     Intent IR Go types + PlanTree
│   ├── intent.go           Intent, Frame, SlotEntry, Constraint, Predicate, Unknown, Budget, CompileMetadata
│   ├── plan.go             PlanTree, PlanNode, StepPayload, ToolCallPayload, SubDispatchPayload, GatePayload
│   ├── encode.go           Canonical JSON encoding + sha256 hashing
│   └── plan_validate.go    PlanTree structural validation (8 invariants)
├── llm/                    LLM client: 6 providers, 3 API shapes, model router
│   ├── llm.go              Client (chat-completions), New(), Config, Decode, Stream
│   ├── messages_api.go     messagesClient (Anthropic Messages API)
│   ├── responses_api.go    responsesClient (OpenAI Responses API)
│   ├── model.go            ModelSlot, StepKind, ModelRegistry, DefaultRegistry
│   └── identity.go         IdentityPreamble injection (Forge Phase 1)
└── mtx/                    MatrixScript runtime
    ├── grammar.bnf         formal EBNF
    ├── spec.md             language specification
    ├── token/              token types
    ├── lexer/              scanner
    ├── parser/             recursive-descent parser -> AST
    ├── ast/                AST node types
    ├── validator/          semantic validation
    ├── canonical/          deterministic AST hash (D11)
    └── interpreter/        AST walker + LLM/Cortex interface

The one-sentence contract

MCL takes intent.draft (prose + optional slot pre-fills) and produces intent.compiled (a fully-typed, signed, deterministically-hashed Intent IR). Everything downstream, executors, walkers, auditors, replays, operates on the IR, never on prose again.

That is the whole point. It is the boundary between the natural-language world and the executable world.


Key locked decisions

These decisions are frozen. Do not re-litigate them without an explicit protocol version bump.

IDDecision
D7Closed verb vocabulary: exactly 10 verbs (find, acquire, build, modify, deliver, analyze, negotiate, schedule, monitor, delegate) plus x: extension namespace
D8Typed SlotPatch compiles to RFC 6902 JSON Patch on the wire (intent.answer, intent.correct)
D9Plan-diff materiality classifier (materiality/) determines whether a correction triggers a new plan
D11Compiler determinism: `seed = sha256(intent.id
D13Mandatory pre-resolution: all NL entity references resolved to matrix:// URIs before user sign-off. Unresolvable references become Unknown
D18Compiler/executor split: compiler = small seedable grammar-constrained model. Executor = frontier model. They are never the same slot
A9Compiler model slot must be seedable and grammar-constrained

What MCL does

  1. User types natural language -> intent.draft
  2. MCL compiler (small seedable grammar-constrained LLM) converts it -> typed Intent IR
  3. User reviews + signs the IR -> intent.accept
  4. Executor (main frontier LLM) walks the plan inside skills
  5. Completion -> intent.attest (signed, optionally chain-anchored)

No free-form side channels. No prose-only messages. Every input produces a typed artifact.