01 · Introduction
arest turns plain-English business rules into running applications. You write sentences like
Order was placed by Customer.
Each Order was placed by exactly one Customer.
and the compiler produces a database schema, a foreign key, a uniqueness constraint, a state machine, and a REST endpoint. There is no separate ORM definition, no handler boilerplate, and no translation layer.
The approach builds on four decades of published work:
- Backus 1978: functional programming as an algebra, with named definitions resolved by a representation function ρ.
- Codd 1970: the relational model and its algebra θ₁ (projection, join, restriction, tie).
- Halpin 2008: FORML 2 and the RMAP procedure that produces 3NF tables from fact-oriented models.
- Fielding 2000: REST and HATEOAS as navigation over a resource graph.
AREST is the composition of these four. A FORML 2 reading is simultaneously a relation schema, a constraint specification, a REST resource, and an FFP object. One sentence occupies all four roles at once. The engine recognizes that identity rather than translating between representations.
When to use it
arest is a fit under these conditions:
- Your domain is fact-oriented. You can describe what you want in sentences like “Each Order was placed by exactly one Customer” rather than pseudo-code.
- You want the spec to be the implementation. Business analysts write readings, and developers do not translate those readings into models and controllers.
- You need the same logic in several runtimes. The same readings produce SQL, on-chain Solidity, or FPGA gates without rewrites.
- You need automated agents to be able to modify the system safely. Every value returned by the API is a ρ-application over facts, so an LLM consumer cannot hallucinate a value that does not exist.
- You need a compliance or audit story. Derivations are traced, constraint violations are reported as the original sentence, and every state change is an event in an append-only log.
When not to use it
It is not a fit under these conditions:
- Your core logic is arithmetic or optimization. Statistical scoring, ML inference, and numerical simulation are opaque to ρ. For those, call a Platform function whose implementation the runtime resolves by name.
- You need to evolve aggressively without review.
compile performs immediate self-modification, whereas propose is governed. Teams that want neither workflow should not use this system.
- Your performance budget is measured in microseconds end-to-end. Compile runs once per deploy; per-command
create runs the full pipeline (resolve → derive → validate → emit). Both are fast enough for request-level latencies, but putting arest on a hot path where every microsecond counts is the wrong trade.
What you will learn in these docs
- This file explains why the project exists and when to pick it up.
- Writing readings: entity types, fact types, verbs, and instance facts.
- Constraints: all 17 constraint kinds, the alethic-vs-deontic split, and violation messages.
- State machines: statuses, transitions, events, and facts-as-events.
- Derivation rules: forward chaining, join syntax, and the least fixed point.
- Compile pipeline: what happens between readings and runnable state.
- Generators: SQL, iLayer, XSD, Verilog, and Solidity, plus the opt-in mechanism.
- Federation: external systems, credentials, and populate functions.
- MCP verbs: the full v1.0 tool surface for agents.
- Self-modification:
compile, propose, and the Domain Change workflow.
Conventions
Code blocks labelled forml2 contain readings you could save to readings/*.md and then compile. Code blocks labelled bash, json, or a language name show exactly what you would run or write in that language.
Each doc ends with a “What’s next” section that links to the logical next step.