Skip to content
Phero Lang
Menu

Engineering / architecture

One artifact, many consumers.

Phero Lang compiles nine modeling surfaces into versioned JSON artifacts. Everything downstream — code generation, schemas, policy, the editor, the graph on this page — reads those artifacts, never the source grammar.

9

Surfaces

23

Crates

305

Graph nodes

463

Graph edges

The pipeline

From source text to a versioned artifact

Five stages, one job each. The boundary between the fourth and the fifth is the invariant the rest of the system rests on.

  1. 01

    Sources

    nine surfaces

    The models you write and review: structure, policy, decisions, events, design, use cases, cases, interaction flows, deployment.

    .mox .ddd .actor .dmn .evt .uc .cmmn .ifml .deploy

  2. 02

    Parse and format

    phero-syntax · phero-ifml · phero-expr

    A logos lexer and a chumsky grammar per surface, plus the canonical formatter. The shared expression language is parsed and typed once by phero-expr; no surface grows its own.

    spanned syntax tree

  3. 03

    Resolve, validate, lower

    phero-driver

    Salsa-based. Imports resolve, references validate, diagnostics come from one registry, and lowering produces the IR. The semantic graph and the editor index are derived after checking.

    diagnostics · graph · span tables

  4. 04

    Versioned artifact

    phero-ir

    The wire contract: camelCase fields, adjacent tagging, a formatVersion gate, and additive-only growth. One Core IR Model, and one artifact per surface.

    formatVersion · byte-stable goldens

  5. 05

    Consumers

    5 backend crates

    Backends and tools read the artifact and nothing above it: generated Rust, JSON Schema, Cedar policy, the DMN engine model, the CMMN case definition.

    cedar · cmmn · dmn · jsonschema · rust

The nine surfaces

Nine languages, one compiler discipline

Each row states what the surface models, where it stands, and which backends consume its artifact: implemented means an in-tree backend reads it today; validated means it compiles and checks with no backend yet.

The nine Phero Lang surfaces: extension, name, what the surface models, its status, and the backends that consume its artifact. Scroll sideways for the full table.
ExtensionSurfaceWhat it modelsStatusBackends
.moxDomain modelPackages, classes, features, operations, enums, datatypes and vocabularies — the structural domain every other surface reads.Backend
  • phero-backend-rust
  • phero-backend-jsonschema
  • phero-backend-cedar
.dddApplication designSculptor-style designs: applications, modules, services, repositories, searches, entity state machines, and executable operation bodies.ValidatedNo in-tree backend
.actorAuthorisationWho may do what: actors, delegation, capability grants with typed when conditions, obligations, and Cedar policy generation.Backend
  • phero-backend-cedar
.dmnDecision modelThe decision-requirements graph, business knowledge models, knowledge sources, decision services, and external markdown decision tables.Backend
  • phero-backend-dmn
.evtEvent contractWhat the system publishes and who reacts: versioned event contracts, channels, and subscriptions with their binding rules.ValidatedNo in-tree backend
.ucUse case patternSysML-v2-style use case patterns: subjects, actors, messages, successions and realizes links.ValidatedNo in-tree backend
.cmmnCase managementCMMN 1.1 case models: case files, discretionary and required plan items, sentries, and decision tasks that invoke sibling decision services.Backend
  • phero-backend-cmmn
.ifmlInteraction flowInteraction flows over a composed pattern library: views, containers, components, events, navigation, and the declaration-backed control/route manifest.ValidatedNo in-tree backend
.deployDeploymentDeployment projections: application components, target capabilities and engines, profiles, settings, and type-checked placement policies.ValidatedNo in-tree backend

What a surface compiles to is not a promise in a table: each row's artifact is generated by the released binary and committed under site/data/artifacts/, one per surface.

The semantic graph

One graph across nine surfaces

pherolang graph build compiles every surface in a tree into one queryable artifact: import-connected applications, nodes and edges. It is derived post-compile — the builder never re-reads a source or re-compiles a file.

Domain perspective of support/cli.ifmlDomain perspective of support/cli.ifml: 20 nodes and 23 connections, from the committed graph artifact. Nodes are grouped in columns: nz.example.support (4), nz.example.support.RefundDecision (3), nz.example.support.Ticket (9), nz.example.support.User (4). Every node is labelled with its short name and its kind; a line joins two nodes the graph connects.nz.example.supportnz.example.support.RefundDecisionnz.example.support.Ticketnz.example.support.UserRefundDecision is a class declared in support/support.mox, with 3 connections shown in this view.RefundDecision classTicket is a class declared in support/support.mox, with 12 connections shown in this view.Ticket classUser is a class declared in support/support.mox, with 7 connections shown in this view.User classTicketState is an enum declared in support/support.mox, with one connection shown in this view.TicketState enumapproved is a feature declared in support/support.mox, with one connection shown in this view.approved featurecents is a feature declared in support/support.mox, with one connection shown in this view.cents featuredecisionId is a feature declared in support/support.mox, with one connection shown in this view.decisionId featureassignee is a feature declared in support/support.mox, with 4 connections shown in this view.assignee featureinternal is a feature declared in support/support.mox, with one connection shown in this view.internal featureneedsRefund is a feature declared in support/support.mox, with one connection shown in this view.needsRefund featurerefundCents is a feature declared in support/support.mox, with one connection shown in this view.refundCents featurestate is a feature declared in support/support.mox, with 2 connections shown in this view.state featureticketNo is a feature declared in support/support.mox, with one connection shown in this view.ticketNo featuretitle is a feature declared in support/support.mox, with one connection shown in this view.title featureapproveRefund is an operation declared in support/support.mox, with one connection shown in this view.approveRefund operationraiseRefund is an operation declared in support/support.mox, with one connection shown in this view.raiseRefund operationactive is a feature declared in support/support.mox, with one connection shown in this view.active featureassignedTickets is a feature declared in support/support.mox, with 4 connections shown in this view.assignedTickets featurename is a feature declared in support/support.mox, with one connection shown in this view.name featureuserId is a feature declared in support/support.mox, with one connection shown in this view.userId feature
Domain20 nodes, 23 connections · scroll sideways for the full diagram

This is the domain perspective of the support application — the full-stack example that exercises all nine surfaces. 20 nodes and 23 connections from the domain surface alone, with each node's declaration file baked into its tooltip. The coordinates are part of the committed data: the first paint is a finished SVG, and JavaScript only adds focus and filtering.

Node ids are the artifact's ids verbatim, so a node here is the same nodepherolang graph query answers for. Edges are kept per perspective and only when both endpoints are in it: a connection into another view is not drawn as a phantom box.

The crates

The crate graph

Every workspace crate, read live from its manifest at build time and grouped by role. Each card lists the workspace crates it depends on; a test-only dev-dependency is omitted, so an edge here is a relationship the compiler actually has.

23 crates · 57 workspace dependencies

Syntax and expressions

Lexers, grammars, formatters, and the shared expression language every surface embeds.

  • phero-dates

    no workspace dependencies

  • phero-expr

    usesphero-datesphero-diagnosticsphero-irphero-parserphero-strings

  • phero-ifml

    usesphero-diagnosticsphero-exprphero-irphero-parserphero-strings

  • phero-parser

    no workspace dependencies

  • phero-strings

    no workspace dependencies

  • phero-syntax

    usesphero-parserphero-strings

Driver, IR and evidence

Resolution, validation and lowering; the versioned artifact; the diagnostics registry and the evidence spine.

  • phero-diagnostics

    no workspace dependencies

  • phero-driver

    usesphero-diagnosticsphero-exprphero-ifmlphero-irphero-syntaxphero-verifyphero-vocab

  • phero-evidence

    no workspace dependencies

  • phero-ir

    no workspace dependencies

  • phero-verify

    no workspace dependencies

  • phero-vocab

    usesphero-ir

Backends

Artifact consumers. Each one is a pure function from the IR to generated output.

  • phero-backend-cedar

    usesphero-backend-commonphero-exprphero-ir

  • phero-backend-cmmn

    usesphero-exprphero-ir

  • phero-backend-common

    no workspace dependencies

  • phero-backend-dmn

    usesphero-backend-commonphero-ir

  • phero-backend-jsonschema

    usesphero-backend-commonphero-ir

  • phero-backend-rust

    usesphero-backend-commonphero-exprphero-ir

Tooling

The binary, the editor server, the generated-code runtime, and the test kit.

  • phero-cli

    usesphero-backend-cedarphero-backend-commonphero-backend-jsonschemaphero-backend-rustphero-diagnosticsphero-driverphero-evidencephero-highlightphero-ifmlphero-irphero-lspphero-runtimephero-syntaxphero-vocab

  • phero-highlight

    usesphero-ifmlphero-syntax

  • phero-lsp

    usesphero-driverphero-exprphero-ifmlphero-irphero-syntax

  • phero-runtime

    usesphero-dates

  • phero-testkit

    usesphero-driverphero-ifmlphero-ir

Outside the backend family, phero-cli carries a backend dependency — so a backend is loaded by the binary, not by the compiler core. Edges run from a crate to the crates it names, and nothing is drawn that a manifest does not declare.

Provenance

Generated, not written

The counts on this page are a projection of the committed graph artifact, not a claim typed into prose. CI regenerates them with the released binary and fails on a one-byte difference.

site/data/graph.json is produced by the releasedpherolang binary from examples/. The site then derivessite/data/evidence.json (counts, kinds, crates),site/data/surfaces.json (the surface table above) andsite/data/support-model.json (the figure's baked geometry) from it.

The generator was pherolang 0.3.0 (x86_64-unknown-linux-gnu). It found8 import-connected applications,305 nodes and 463 edges across the corpus, and the figure on this page is derived from that artifact.

The full contract — node kinds, edge kinds, determinism rules, queries — isdocs/GRAPH.md in the repository.

site/
node scripts/fetch-pherolang.mjs   # released binary, sha256-verified
node scripts/sync-model.mjs          # graph, artifacts, evidence, figure
git diff --exit-code data            # what CI checks

The same script runs in the Site workflow with the released asset. A stale count is a build failure, not a documentation bug.