Phero Lang / Verifiable model-driven engineering
Software should be designed as a system.
Phero Lang turns business intent into structured, executable models. 9 modelling surfaces share one semantic foundation, and each compiles to a versioned artifact that generators, schemas and policy engines read. The model is not a diagram next to the code — it is what the code is generated from.
OPEN SOURCE · RUST · EXTENSIBLE · MODEL-DRIVEN
01 / The problem
One system. Many specifications. No shared meaning.
A domain lives in an object model. Decisions live in a table only one team can read. Permissions live in a policy file nobody diffs. Workflows live in a drawing. Each one is right on its own.
Every tool in that list is authoritative about something and silent about everything else. The object model cannot say that a refund above five thousand needs finance. The policy file cannot say that the refund amount is an int cents value on a class calledTicket. The table cannot say either. What connects them is a meeting, a wiki page, and a reviewer's memory.
So the specifications do not disagree loudly — they drift quietly. A field is renamed in code and the decision table keeps its old header. A capability is granted on an aggregate that was split two releases ago. Nothing fails until it fails in production, in a place that has nothing to do with the change that caused it.
The failure is structural, not personal. No amount of review discipline makes four tools agree about a type they each store differently. To check that the specifications are consistent, one of them has to be able to see the others.
02 / The proposition
One semantic foundation. Many surfaces. One artifact each.
Phero Lang gives each kind of specification its own language, and gives all of them one type system, one expression language and one compiler.
One foundation
Every surface resolves names through the same domain. A when condition in a policy, a decision input, an event field and a service operation signature are all checked against the same classes and the same expression rules.
Many surfaces
9 file kinds, each with its own grammar and formatter: structure, design, policy, decisions, events, use cases, cases, interaction flows, deployment. One of them is usually the entry point; none of them is the whole system.
One artifact each
Each surface compiles to its own versioned JSON artifact, gated on aformatVersion. Backends read the artifact and nothing above it, so a generator cannot depend on a grammar it was not written against.
The platform overviewtakes each capability in turn, with the invariant that holds them together.
03 / How it works
Six moves from intent to generated code.
Six things the toolchain does. Each card opens the surface — or the register — that demonstrates it.
01 · Domain model
Model
Packages, classes, features, operations, enums and vocabularies in one file. Types, relation ends and operation bodies are checked, so a typo is a compile error and not a runtime surprise.
.mox
02 · Application design
Connect
Services, repositories, aggregate roots and entity state machines that import the domain instead of restating it. The design is checked against the names the domain actually declares.
.ddd
03 · Authorisation
Validate
Actors, capabilities, grants and obligations as their own dimension. Every grant condition is type-checked against the domain class it is written over, then lowered to Cedar policy.
.actor
04 · Decision model
Generate
Backends read the compiled artifact and write code: Rust model code, JSON Schema, Cedar policy, a DMN engine model, a case definition. One artifact, several targets, no second grammar to learn.
.dmn
05
Verify
No surface proves this one. A register does: every structural claim carries a status and an evidence pointer, with a review date on the rows that carry one — and the compiler prints a receipt naming the sources and artifacts it was checked over.
06 · Interaction flow
Extend
Composition instead of forks. Interaction flows compose a shared pattern library by reference instead of copying, the same move a new backend makes: consume the published artifact, never the grammar behind it.
.ifml
04 / The surfaces
Every surface, one compiler discipline.
4 surfaces have an in-tree backend today; the other 5 compile and check with no backend yet. The word is the status, not a promise.
| Extension | Surface | Status |
|---|---|---|
| .mox | Domain modelStructure, relationships and behaviour | Backend |
| .ddd | Application designServices, repositories and aggregate roots | Validated |
| .actor | AuthorisationActors, capabilities and obligations | Backend |
| .dmn | Decision modelDecision requirements and decision services | Backend |
| .evt | Event contractVersioned events, channels and subscriptions | Validated |
| .uc | Use case patternSubjects, actors and successions | Validated |
| .cmmn | Case managementCases, plans and sentry criteria | Backend |
| .ifml | Interaction flowViews, navigation and CLI commands | Validated |
| .deploy | DeploymentComponents, profiles and targets | Validated |
The cataloguehas a page per extension: the problem it solves, a real example from the repository, what it compiles to, and where it stands.
05 / The demonstration
One domain, 8 perspectives.
The support-desk example is one domain plus the surfaces around it — a design, a policy, decisions, events, use cases, a case, an interaction flow, a deployment. One compiler, one graph.
pherolang graph build compiles the whole tree into a single artifact:8 import-connected applications, 305 nodes and 463 edges. It is derived after compilation — the builder never re-reads a source file — so a node in the graph is the node the compiler produced.
The domain perspective holds 20 nodes and23 connections on its own. The same declarations reappear in the other perspectives, joined differently: the refund capability sits next to the operation it authorises, the decision service next to the operation that invokes it, the event next to the subscription that consumes it.
The static drawing of the domain perspective is onthe architecture page, where it renders without JavaScript. Theinteractive explorer is the same data with the perspective switcher as a real tablist, and a no-JS transcript underneath.
The perspectives
- Domain
- Decisions
- Events
- Workflows
- Authorisation
- Experience
- Deployment
- Cases
06 / Correctness
Correctness is enumerated, not implied.
The proof-obligation register holds 17 claims. Each one carries a status and the evidence class that backs it; the rows that are argued or assumed also carry a trigger and a review date. The ladder reports the weakest honest class per row, never the average.
8
proved
6
tested
1
argued
2
assumed
What this is not: "Phero Lang is formally verified" is a claim the project does not make and must not be read into these numbers. What exists is a proved kernel for the compiler's own graph structure, a tested cross-layer integrity pass, and a set of stated obligations with named assumptions. The register spells out the weakest class for each — including the rows where the argument is incomplete and says so.
The counts above are computed fromsite/data/register.json, a copy ofdocs/verification/register.json taken when the site is generated. No number on this page is folded into prose by hand: the honesty mechanism is that a claim without a live evidence pointer fails the project's own gate.
pherolang verify turns that into a receipt — the source closure it was checked over, the artifact hashes, and the register's rows — which can be validated later, offline, with no prover toolchain present.
07 / Open ecosystem
Rust in the core, open at the edges.
The compiler is a Rust workspace and an Apache-2.0 repository. The extension point is not an interface we designed for you — it is a JSON artifact with a version gate.
Rust, all the way down
23 workspace crates and one binary. Lexers, grammars, formatters, the salsa-based driver, the IR, the editor server, the generated-code runtime, the backends.
Extensible backends
5 target backends ship in tree, each one a pure function from artifact to output. A new backend never learns a grammar, and it can live outside the workspace entirely.
A wire contract
camelCase keys, adjacent tagging, a formatVersion gate, and additive-only growth. The backend contract is the whole integration surface.
A pattern library
patterns/ifml composes domain-agnostic modules into interaction flows. Reuse is a use statement, not a copied file.
08 / Get started
Install it, compile a model.
A released archive per target, a checksum manifest, and one binary. The block below is the download-and-verify chain CI itself runs to fetch the released compiler, so the printed steps and the working ones are the same steps.
curl -LO https://github.com/yestechgroup/pherolang/releases/download/v0.3.0/pherolang-0.3.0-x86_64-unknown-linux-gnu.tar.gz
curl -LO https://github.com/yestechgroup/pherolang/releases/download/v0.3.0/SHA256SUMS
sha256sum -c --ignore-missing SHA256SUMS
tar -xzf pherolang-0.3.0-x86_64-unknown-linux-gnu.tar.gz
sudo install -m 0755 pherolang /usr/local/bin/pherolangWindows archives, the aarch64 Linux build, and the cargo install fallback are on the install page.
The five-minute walkthrough takes one.mox file through check, ir and gen, and ends with a compiled artifact you can inspect. Every shell line on that page is executed by CI against the released binary.
Want the shape of the whole thing first? How it works follows one file from source text to an artifact to generated Rust, JSON Schema and Cedar.
09 / Design partners
A few teams with a system worth specifying.
Phero Lang is pre-1.0. There is no support SLA, no hosted product, and no roadmap anyone should schedule a release against yet. What exists is a working compiler, documentation you can read in an afternoon, and a maintainer who will sit in your model with you.
What you get
- Your domain modelled with you, in the open: the
.mox,.dddand.actorlayers written beside your engineers, not handed over as a PDF. - Compiler work sequenced from what your model exposes — a missing check or an awkward grammar shows up as a fix, not a feature request in a queue.
- No fee. There is nothing to buy yet.
What we ask
- A system with real constraints: regulated, authorised, or expensive to get wrong. A clean CRUD app will not teach either of us anything.
- A few hours a month from someone who owns the domain, not only the ticket queue.
- Tolerance for a pre-1.0 toolchain. Minor versions may change the grammar and the wire format until 1.0 freezes it.
- Blunt feedback when the model does not fit the way your system actually works.
A paragraph about what you are modelling is enough.