0005. The core's interface is an in-process function call
0005. The core’s interface is an in-process function call
Status
Accepted
Date
2026-10-04
Deciders
operator (Saulo Vallory) ruled the principle (Ruling 8 as corrected); the lead restated it in the rulings file and turned it into roadmap scope. Supersedes ADR-0006.
Context
An action is one named operation on a resource (create, read, update, destroy). A transport is whatever lets an outside caller reach an action: a command line, an HTTP server, a job runner. The synthesis asked which server adapter should come first, Elysia or Hono (TypeScript web frameworks), or both (research synthesis, section 19, question 8).
Ash, which Mesh is modelled on, is not tied to the web: its web and API transports (Phoenix, JSON:API, GraphQL) are separate packages (research synthesis, section 4, table rows 17, 18 and 20). Mesh actions “must also run with no request: jobs, tests, agent tools, daemons” (same file, section 11).
Decision
The operator ruled on 2026-10-04, in Ruling 8 of rulings of 2026-10-04, as corrected the same day:
Neither Elysia nor Hono first. Mesh is not to be tied to web apps, or to any kind of application: like Ash, it must serve a CLI, a daemon, a web app or an API equally. The operator’s words: “let’s test Mesh with a leaner thing that will require less wiring.” This is a statement about how to test first, not a ruling that a CLI is the first transport.
The lead restated it in the same file, “Consequences for the proposal”, first bullet:
Section 15 “Server and API protocol” adapter: no transport is chosen as first. The core’s interface is an in-process function call; every transport is an optional adapter over it.
So the operator ruled the principle in Ruling 8 as corrected; the lead’s restatement says what follows for the architecture; and the lead turned it into roadmap scope: no transport is built in v1 and a transport is built when something needs it. The roadmap follows: the walking skeleton (M0 to M2) “ends in a function call”, a test and a script of about twenty lines call the generated functions against SQLite, and there is “no command line, no server” (roadmap, section 1, item 2; M2).
Options considered
Option A: Function call only; transports are later adapters (chosen)
| Dimension | Assessment |
|---|---|
| Complexity | Lowest: no transport contract, registry or exit codes in v1 |
| Cost | Least wiring now; each transport is built later |
| Fit with Ruling 8 | Exact: serves any program equally |
| Reversibility | High: a transport can be added without changing core |
Pros: Testing the stack needs no wiring. Core stays free of web and process concepts (roadmap, section 2, principle 8).
Cons: Nothing outside a TypeScript program can call Mesh in v1. No transport contract is designed until a transport exists, so core may assume something a transport must later change. The first transport “will need a way to obtain a scope, which is that adapter’s design, not core’s” (roadmap, section 6).
Option B: A command-line transport first
| Dimension | Assessment |
|---|---|
| Complexity | Medium: argument parsing, action registry, exit codes |
| Cost | A transport contract and a scope resolver in M2 |
| Fit with Ruling 8 | Rejected by the correction |
| Reversibility | Medium |
Pros: Leaner than HTTP. This was plan revision 2 (ADR-0006).
Cons: It builds the wiring the operator wanted to avoid (an action registry, a way to obtain a scope; ADR-0008).
Option C: HTTP first (Elysia or Hono)
| Dimension | Assessment |
|---|---|
| Complexity | Highest of the three: routes, validation hand-off, errors |
| Cost | A server dependency in the first milestone |
| Fit with Ruling 8 | Poor |
| Reversibility | Low if it shapes core |
Pros: The Fetch handler is one of four neutral standards (research synthesis, section 9).
Cons: Ruling 8 rejects it. For Elysia, “everything hangs off an HTTP request” (section 11).
Trade-off analysis
Option A trades reach for leanness: v1 cannot be called from outside, in return for a core that assumes nothing about who calls.
Consequences
- Easier: M2 is small; tests call functions directly.
- Harder: the scope has to be passed by the caller (ADR-0007); the agent surface waits for the command-line adapter (ADR-0027).
- Revisit: when the first transport is built, check that core did not assume a shape for it. Elysia stays a candidate (ADR-0038).
Action items
- M2: generate handlers as exported functions
createPost(input, scope)and an example script of about twenty lines. - M2: add no action registry or transport contract.
- After v1: design the first transport and its way of obtaining a scope.