.mox
Domain model
Structure, relationships and behaviour
consumed byphero-backend-rustphero-backend-jsonschemaphero-backend-cedar
Packages, classes, features, operations, enums, datatypes and vocabularies — the structural domain every other surface reads.
Why it exists
What .mox is for
A .mox file holds one package and its declarations: classes and their features, enums, datatypes, interfaces, vocabularies, and package-level annotations. It is the only surface that declares structure — every other surface reads this one.
The compiler resolves and validates it into one Core IR Model, and backends generate from that artifact rather than from the syntax tree. Relationships are checked where they are written: refers pairs with refers and contains with container, opposites are mutual and validated, and an expr body is typed against the features it names.
Vocabulary
What it models
The concepts .mox declares, and what each one means to the compiler.
- package
- One per file; the namespace every declaration joins.
- class
- Attributes and relationships, optionally
extends-ing another class. - refers / contains
- A cross reference versus by-value ownership. The
containerback-pointer is the owner slot, and opposites are mutual and validated. - derived
- A computed feature: it carries an
exprbody and no stored value. - op
- An operation. An
exprbody is typed and lowered by every backend; arustor other target body is embedded verbatim by the backend that owns that target. - enum
- Integer values with optional labels (
Open as "open" = 0). Backends emit real enums; canonical JSON uses the literal name. - datatype
- An opaque wrapper around a platform type, with per-target bindings and at most one
formathint. - vocabulary
- An external code set: the declaration names the source, version and facets, and the snapshot is vendored and pinned by sha256 in
model.lock. - inline actors
- A policy block declared next to the domain. It lands on the package as an
ActorsDefand validates exactly like a standalone.actorfile.
Source
A working example
Quoted from the example this page's artifact was compiled from — not a snippet written for the website.
Lines 16–32 of examples/support/support.mox, reproduced byte for byte, read from the file at build time:
class Ticket {
id readonly String ticketNo
String title
boolean internal
int refundCents
TicketState state
refers User[0..1] assignee opposite assignedTickets
derived boolean needsRefund {
expr { refundCents > 0 }
}
op boolean raiseRefund(int cents) {
expr { refundCents + cents <= 5000 }
}
op boolean approveRefund(int cents) {
expr { refundCents + cents <= 100000 }
}
}One class: attributes, an enum-typed feature, a relation with its opposite, a derived feature, and two operations with checked expression bodies.
The whole file is CI-tested: pherolang check examples/ checks every surface in the tree, and the example harness compiles each one on every run. What you see above is the input to the artifact below.
Neighbours
How it relates to the other surfaces
Everything else in the stack reads this surface. .ddd designs reference its classes, .actor capabilities bind to them and type-check their when conditions against them, and the payload fields, inputs, participants, case-file items and data: bindings of .evt, .dmn, .uc, .cmmn and .ifml all resolve against the same union namespace.
Commands
How to compile and validate
Three commands, one file. They run from the repository root against the example on this page.
pherolang check examples/support/support.mox
pherolang ir examples/support/support.mox -o site/data/artifacts/mox.json
pherolang artifact check site/data/artifacts/mox.jsoncheck parses, resolves, validates and type-checks the file and printsOK examples/support/support.mox. ir writes the artifact and prints nothing on success. artifact check then validates the serialized JSON on its own — no model, no import resolution, no compiler — and prints OK site/data/artifacts/mox.json.
Directories work too: pherolang check examples/ enters project mode and checks every supported surface under the tree, each file's imports resolving from the snapshot.
Artifact
What it produces
One versioned JSON artifact, emitted by the compiler and consumed by whatever reads this surface.
One Model for the whole package: enums, datatypes, interfaces, classes and their features, with a stable feature id per class.
The artifact is site/data/artifacts/mox.json, and it is committed here exactly as the released pherolang binary emits it. Its top-level shape:
packages1 entry
Provenance
- formatVersion = 2
- The compatibility gate. A reader accepts this number or refuses the file.
- pheroVersion = 0.3.0
- Provenance only: which compiler wrote the file.
- 9,431 bytes
- 364 lines, two-space indented, in the file's own key order.
The compiled artifact
The first 54 of 364 lines, verbatim — the exact bytes pherolang ir writes, not a hand-written sample. The slice stops at a JSON boundary; the ellipsis marker is outside the JSON, and the full file is site/data/artifacts/mox.json.
artifacts/mox.json · lines 1–54
{
"formatVersion": 2,
"pheroVersion": "0.3.0",
"packages": [
{
"name": "nz.example.support",
"annotations": [],
"enums": [
{
"name": "TicketState",
"literals": [
{
"name": "Open",
"label": "open",
"value": 0
},
{
"name": "InProgress",
"label": "in_progress",
"value": 1
},
{
"name": "Resolved",
"label": "resolved",
"value": 2
}
]
}
],
"datatypes": [],
"interfaces": [],
"classes": [
{
"name": "User",
"extends": [],
"features": [
{
"id": 0,
"name": "userId",
"kind": "attribute",
"type": {
"type": "primitive",
"value": "string"
},
"multiplicity": {
"lower": 1,
"upper": {
"finite": 1
}
},
"isDerived": false,
"isId": true,
"isReadOnly": true
},… 310 more lines in site/data/artifacts/mox.json
Regenerate it from the repository root — the second command validates the serialized bytes with no compiler in the loop:
pherolang ir examples/support/support.mox -o site/data/artifacts/mox.json
pherolang artifact check site/data/artifacts/mox.jsonThe whole data directory is regenerated by node scripts/sync-model.mjs (run from site/) with the released binary; CI fails on a one-byte difference.
Reference
Documentation
The normative reference for this surface, rendered from the repository's own documentation.
docs.pherolang.com
Domain model reference
Generated from docs/LANGUAGE.md in the repository. The page above summarises it; the reference is normative.