MatrixScript Language
MatrixScript (.mtx) is the declarative DSL in which the MCL compiler is written. The Go binary mclc is a runtime that interprets .mtx files; it contains no compile logic itself.
MatrixScript (.mtx) is the declarative DSL in which the MCL compiler is written. The Go binary mclc is a runtime that interprets .mtx files; it contains no compile logic itself. Every decision the compiler makes is declared in a .mtx file that the runtime executes.
Source files: mtx/spec.md, mtx/grammar.bnf, mtx/lexer/, mtx/parser/, mtx/ast/, mtx/validator/, mtx/canonical/, mtx/interpreter/.
Design principles
| Principle | Choice |
|---|---|
| Syntax family | .kvx-evolved: dense key=value + SECTION headers |
| Semantic model | Pure data: parsed AST; decision trees are literal structures, not code |
| Prompts | Structured typed blocks with named roles |
| Hashing | AST-hash (comments do not break seed determinism, D11) |
| Skill files | SKILL.mtx carries everything: frontmatter, procedure, outputs, failure modes |
Lexical conventions
- Encoding: UTF-8, NFC normalized before parse
- Line endings: LF; CRLF normalized on read
- Comments:
#to end of line (preserved in AST for display, stripped before hashing) - Indentation: 2 spaces; column 0 = top-level entry, column >= 2 = continuation
- Strings: Double-quoted with
\",\\,\n,\tescapes; slot interpolation allowed - URIs:
matrix://URIs are first-class values, no quoting needed - Identifiers:
[a-zA-Z][a-zA-Z0-9_-]*, case-sensitive; section names are UPPER_CASE
File structure
A .mtx file is a sequence of sections:
SECTION_NAME
entry
entry
NEXT_SECTION
...
Section headers: `` followed immediately by an UPPER_CASE identifier on its own line.
Section reference
SKILL -- metadata
SKILL
id=writing-plans
version=1.0.0
display=Writing Plans
author=did:pax:0xABC123...
description=Converts a build/modify intent draft into a structured plan
mcl.verbs=build modify
determinism=seedable
seed_policy=per_intent
INPUTS -- slot declarations
INPUTS
slot target: ArtifactRef
required
hint="The artifact to build or modify"
slot style: enum<formal|casual|technical>
optional
default=formal
PROCEDURE -- decision tree
PROCEDURE
on verb=build
prompt
system="You are the Matrix plan compiler."
user="User goal: {prose}. Fill the Frame JSON."
end
resolve slot.target <- cortex.find(type=Fact, near=slot.target.prose, limit=5)
unknown slot.target
severity=blocking
reason="Cannot identify the target artifact"
end
end
on confidence<0.75
clarify slot.target
prompt="Which artifact are you referring to?"
type=ArtifactRef
required=true
end
end
OUTPUTS -- produced slots
OUTPUTS
slot plan_draft: PlanDraft
required
FAILURE_MODES
FAILURE_MODES
budget_exceeded
suggest=raise_budget
policy_violation
action=fail
Type system
Scalar types
| Type | Description |
|---|---|
string | UTF-8 string |
uint | Non-negative integer |
float | IEEE 754 32-bit float |
bool | true or false |
ulid | ULID (26-char Crockford base32) |
iso8601 | ISO 8601 datetime string |
did | Decentralised Identifier string |
sha256 | 64-hex SHA-256 digest |
MCL domain types
| Type | Description |
|---|---|
ArtifactRef | Reference to a produced or consumed artifact |
Constraint | Typed constraint (budget/deadline/quality/rule/policy/x:custom) |
Predicate | Success criterion |
Unknown | Typed gap (severity + field path + options) |
PlanDraft | Structured plan tree |
SkillRef | matrix://skill/... reference |
ToolRef | matrix://tool/... reference |
Lists and optionals
Any type suffixed with [] is a list. Slots default to required; add optional modifier to override.
Block syntax
on-block
on <condition>
<entries>
end
Conditions: verb=<name>, confidence<0.75, slot.<name>=<value>, unknown. First match wins.
On-block metadata keys: kind (routes to specialist executor model), output_cardinality (planner fan-out hint), skip (legacy sentinel).
prompt block
prompt
system="<system role text>"
user="<user turn text>"
assistant="<optional assistant prefix>"
end
resolve statement
resolve slot.<name> <- cortex.find(type=Fact, near=slot.target.prose, limit=5)
resolve slot.<name> <- cortex.resolve(slot.target.prose)
resolve slot.<name> <- cortex.context(verb=slot.verb, budget_tokens=500)
unknown block
unknown slot.<name>
severity=<blocking|preferred|optional>
reason="Human-readable explanation"
options=<expr>
end
clarify block
clarify slot.<name>
prompt="Which artifact are you referring to?"
type=ArtifactRef
required=true
end
Slot interpolation
Inside string literals, these variables are expanded by the runtime:
| Variable | Expands to |
|---|---|
{prose} | Original NL from intent.draft.prose |
{verb} | Resolved verb name |
{cortex.bundle} | Formatted cortex.context() output |
{slots} | Summary of all currently-filled slots |
{slot.<name>} | Current value of the named slot |
{slot.<name>.prose} | Raw NL text for a not-yet-resolved slot |
Deterministic hashing (D11)
All .mtx files are content-addressable via AST hashing. Comments are stripped before hashing so they do not break seed determinism. The canonical.Hash(file) function computes the digest, which flows into the D11 seed: sha256(intent.id || actor || snapshot_hash || mtx_digest || model_digest).
