Decisions
Decisions
One page per decision, in ADR (architecture decision record) format. A record captures a choice, the options that were considered and why one won, so that a later reader does not have to reconstruct them.
- Start from the template.
- Name files
NNNN-short-title.md. See Contributing to these docs. - Records are never deleted or rewritten. A reversed decision gets a new record; the old one is marked Superseded (replaced) or Amended (partly changed), gains one line at the top linking its successor, and keeps its body as history.
How to read a record
Every record has the same sections: status, date, deciders, context, decision, options considered, trade-off analysis, consequences, action items (ADR-0032).
- Accepted: decided. The record quotes the ruling and says who made it.
- Accepted, amended: decided, but a later record changed part of it. Read the successor first.
- Proposed: open. The record gives the options and a recommendation, and says who must rule and what the decision blocks.
- Superseded: replaced by a later record. Kept so that nobody proposes it again without knowing it was tried and why it was dropped.
Deciders are named by role. The operator is the project owner (Saulo Vallory). The lead coordinates the work; the operator may overrule the lead, and on 2026-10-05 delegated every open decision to the lead (“the lead, delegated by the operator”). The roadmap author wrote the roadmap and proposed parts of the design.
The rulings the records quote are in the dated log, rulings of 2026-10-04. The roadmap says in which milestone each decision is built.
What changed on 2026-10-04 evening and 2026-10-05
The operator’s rulings of those two days replaced the vocabulary copied from Ash with Mesh’s own entity file syntax and renamed most things a user sees. Records 0049 to 0066 hold them:
- Terms and syntax:
resourcebecameentityand the vocabulary is Mesh’s own (0049); every line iskind #name options(0050, with the reference file), later amended so that names and references are atoms,kind :name options(0066); files end in.mesh.mx(0051); actions,autoandon:load(0052);validatethendo(0053); the write strategy is inferred (0054); policies are core, fail closed and combine without order (0055); a function whose body is one expression is translated (0056). - Project shape: one domain at
src/domain/with modules as folders (0057); generated code in.mesh/, imported as#mesh(0058); the flatActionContext(0059); packages@meshfw/*(0060); Jig templates (0061); Zod 4, Drizzle and OpenTelemetry as direct dependencies (0062). - Process: docs first in the 1.0 voice, and the hold (0063); the order of work after approval (0064); highlighting
mxcode on this site (0065).
The code on main still uses the names of 2026-10-04 morning until the realignment task (0064).
What changed on 2026-10-08
ADR-0067 amends the entity syntax: :name declares, &name refers to a member, another entity is imported by path, an action takes one input section, and files remain static. The Entities reference and ADR-0050’s Invoice use that spelling. Earlier decision quotations remain historical.
Current records
| ADR | Decision | Status | Deciders |
|---|---|---|---|
| 0001 | Three rings: core, adapters, extensions | Accepted | operator |
| 0002 | Resource files are .mx, read as a data tree through MX (now entity files, .mesh.mx) |
Accepted, amended by 0049, 0050, 0051 | operator |
| 0003 | Generated code carries the behaviour; the run-time library stays thin | Accepted | operator |
| 0004 | Mesh is built regardless; measuring the agent benefit is not a gate | Accepted | operator |
| 0005 | The core’s interface is a function call; transports are optional adapters, none in v1 | Accepted | operator |
| 0010 | One expression tree, evaluated in memory and in SQL | Accepted, amended by 0056 | operator; roadmap author |
| 0012 | Expression semantics where SQL and JavaScript differ | Proposed (blocks M4) | operator or lead |
| 0013 | Data-layer contract: a mandatory set plus declared capabilities | Accepted | operator |
| 0014 | SQL adapters are built on Drizzle and drizzle-kit | Accepted | operator’s position, lead’s choice of tool |
| 0016 | In-memory data for tests is SQLite’s in-memory mode | Accepted | roadmap author |
| 0017 | Updates are atomic by default; a step never runs twice | Accepted, amended by 0053, 0054 | operator, lead, roadmap author |
| 0018 | A valid but unimplemented tag is a build error | Accepted | roadmap author |
| 0019 | v1 is milestones M0 to M9; what comes after (its rationale cites records since superseded) | Accepted | operator |
| 0020 | Extensions contribute to each other only through declared points | Accepted | operator |
| 0021 | Mesh generates one self-contained MX contracts module | Accepted | lead |
| 0022 | Policies: a simple tier, solver-ready | Accepted, amended by 0055 | operator |
| 0023 | Workflows and jobs come after v1; the adapter interface stays a design document | Accepted | operator |
| 0025 | Mesh runs on Bun only | Accepted | operator |
| 0027 | No MCP server; the agent surface is a rules file, later a generated CLI | Accepted | operator |
| 0028 | Input validation is Zod behind Standard Schema (confirmed by 0062) | Accepted | lead |
| 0029 | Tracing calls the OpenTelemetry API directly | Accepted | lead |
| 0030 | Established tools first, behind Mesh contracts | Accepted | operator |
| 0031 | No CI until the MX packages are published | Accepted | operator |
| 0032 | Docs site in the repo; decisions as ADRs; the repo is the source of truth | Accepted | operator |
| 0033 | Core packages are split by when the code runs | Accepted | roadmap author |
| 0035 | What public on an attribute means (syntax v2 has no public) |
Proposed | operator |
| 0037 | Contracts or registries as the source of truth for the vocabulary | Proposed | operator or lead |
| 0038 | Elysia is not core; a candidate HTTP adapter | Accepted | operator |
| 0039 | Run-time errors: embedded positions or source maps | Proposed | operator or lead |
| 0041 | Entity files and examples always use MX concise syntax | Accepted | operator |
| 0042 | Mesh is open source under MIT; the docs are public | Accepted | operator |
| 0043 | MX is core, not an adapter; no front-end adapter slot | Accepted | operator |
| 0044 | Folding record-reading checks into the atomic statement (after v1) | Proposed | lead and operator |
| 0045 | How has-one is kept to one row |
Proposed | operator |
| 0046 | What a denied write reports on an atomic action | Proposed | operator |
| 0047 | Actions are bound to a data layer: bind and connect |
Accepted, amended by 0059 | operator |
| 0048 | Schema inside the process for tests; the stable Drizzle pin | Accepted | lead |
| 0049 | The vocabulary is Mesh’s own; resource becomes entity |
Accepted | operator |
| 0050 | Entity file syntax: kind #name options, with the reference file |
Accepted | operator |
| 0051 | Entity files end in .mesh.mx; Mesh ships an MX host named mesh |
Accepted | operator; lead, delegated |
| 0052 | Actions are always named; auto; on:load; arguments |
Accepted | operator |
| 0053 | validate, then do; steps set, when, load, run; always; reusable steps planned |
Accepted | operator; lead, delegated |
| 0054 | Mesh infers the write strategy; no require-atomic |
Accepted | lead, delegated |
| 0055 | Policies are core; every covering policy must pass; no policies means forbidden | Accepted | operator; lead, delegated |
| 0056 | A function whose body is one expression is translated; Mesh builds its own translator | Accepted | operator; lead, delegated |
| 0057 | One domain at src/domain/; its folders are modules |
Accepted | operator |
| 0058 | Generated code in .mesh/, committed, imported as #mesh |
Accepted | operator; lead, delegated |
| 0059 | The second argument is the flat ActionContext; tenancy is a user key |
Accepted | operator |
| 0060 | Packages are @meshfw/*; the command is mesh |
Accepted | operator |
| 0061 | Generators are Jig templates; export and per-template override | Accepted | operator |
| 0062 | Zod 4 stays; direct dependencies on Zod, Drizzle, OpenTelemetry | Accepted | operator; lead, delegated |
| 0063 | User docs first, in the 1.0 voice; development on hold until approved | Accepted | operator |
| 0064 | After approval: realignment, Jig port, then M2 | Accepted | lead, delegated |
| 0065 | The docs site highlights mx code with MX’s tree-sitter highlighter |
Accepted | lead, delegated, with the MX lead |
| 0066 | Names and references are atoms: kind :name options |
Accepted, amended by 0067 | operator (three points by the lead) |
| 0067 | Members are &name, entities are imports, one input section, static files |
Accepted | operator; marked choices by the lead |
Superseded records
| ADR | Decision | Superseded by | Deciders |
|---|---|---|---|
| 0006 | The first transport is a CLI | 0005 | lead |
| 0007 | The scope { actor, context } is a plain argument on every action call |
0059 | lead |
| 0008 | Transports obtain the scope through an actor-resolver adapter | 0007 | lead |
| 0009 | Where tenancy lives: core or extension (was Proposed) | 0059 | open (it was Proposed) |
| 0011 | Translatable expressions run only as SQL | 0010 | roadmap author (never accepted) |
| 0015 | Mesh prints SQL and diffs schemas itself | 0014 | roadmap author |
| 0024 | The in-process workflow runner is the first adapter | 0023 | operator |
| 0026 | Mesh runs on Bun and Node | 0025 | operator |
| 0034 | The vocabulary copies Ash’s DSL for v1 | 0049 | operator; lead for the spelling |
| 0036 | Deny by default arrives with the policies extension | 0055 | lead |
| 0040 | Package scope and command name (was Proposed) | 0060 | operator |
Open decisions at a glance
Seven records are Proposed. One blocks v1 work outright: ADR-0012 (expression semantics, before M4). ADR-0037 now also decides where attribute-type tag names come from (ADR-0050) and should be ruled in the realignment task. ADR-0039 (before M5), ADR-0045 (before M7) and ADR-0046 (before M8) have a working assumption in the roadmap. ADR-0044 is for after v1. ADR-0035 blocks nothing in v1.