ADR 0005: The CLI lens is a client, not a twin
- Status: accepted
- Date: 2026-09-23
Context
Generators commonly emit an in-process CLI: the binary links the store and handlers directly, so it can run without a server. That is a second deployment of the same state — two binaries to test, two ways for the CLI to disagree with the API, and the "convenience" evaporates the moment the store is anything but trivial.
Decision
The CLI lens generates a typed HTTP client (reqwest) against the
running server. mosaic <op> subcommands and the REST API are the same
request. State has exactly one home: the process you started with
serve. In v0 the store is in-memory, so up (build + serve + run) is
the workflow; a persisted store is a later ADR, and the CLI stays a
client regardless.
Consequences
- The CLI cannot drift from the API: both hit the same code path.
- The generated app is one binary doing two thin jobs (serve, call).
- The
--urlflag makes the CLI testable against any instance.
Proof
CI job example, step smoke test (proof of ADR 0005): starts the
generated serve process, then drives create/list/custom-op through
the generated CLI against that process, asserting the returned total.