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: resource became entity and the vocabulary is Mesh’s own (0049); every line is kind #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, auto and on:load (0052); validate then do (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 flat ActionContext (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 mx code 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.