ADR-0024: The reference implementation as a workspace member¶
Status: Accepted Date: 2026-09-28 Deciders: Alex Nodeland
Context¶
ADR-0013 calls for examples/docplan: a reference implementation built only on the public API, which doubles as the end-to-end test. Building it (RFC-0001 phase 6) required several decisions:
- how it is packaged and installed next to the library
- how "only the public API" is kept true
- how it is tested without calling a model API
- what it does about authentication, which is the host's concern
Decision¶
- A uv workspace member.
examples/docplanis its own distribution (docplan), a member of the repository's uv workspace. It depends onartifactr[fastapi,mcp]from the workspace, so it always runs against the library in the same commit.uv sync --all-packagesinstalls it, and it provides two commands:docplan-serveanddocplan. - Public API only, enforced. A layering test fails if any docplan module imports an artifactr module other than a package's public surface (
artifactr,artifactr.core,artifactr.agent, and so on). - The same quality gate as the library. docplan is linted, type-checked strictly and counted in the 100% branch-coverage gate. Its tests run the real server (uvicorn on a free port) and the real terminal client over a real WebSocket. The agent's model is a scripted
FunctionModel, so no test needs an API key. - Demo authentication, named as such. The server trusts an
x-userheader and puts everyone in one tenant, and its docs say so. The code shows exactly where a real application plugs in its ownresolve_actorandresolve_client. - The terminal client is a thin protocol client. It builds command frames and renders event and live frames as plain JSON. It does not use artifactr's frame models, so it reads as a template for a client in any language.
Options considered¶
Where the reference implementation lives¶
| Option | Runs against the current library | Installed with one command | Kept honest about the API |
|---|---|---|---|
| Workspace member (chosen) | Yes | Yes | Yes, with the layering test |
A module inside artifactr |
Yes | Yes | No: it could reach private modules unnoticed |
| A separate repository | No: pins a released version | No | Yes |
How it is tested¶
| Option | Covers the wire | Deterministic |
|---|---|---|
| Real server and client, scripted model (chosen) | Yes: HTTP, WebSocket and MCP over a socket | Yes |
In-process TestClient only |
Partly: not the WebSocket client | Yes |
| A live model | Yes | No, and it needs a key |
Consequences¶
- Easier: a new contributor can run a complete application with two commands, and read one small codebase that uses every extension point.
- Easier: API gaps surface as failing example tests. Building docplan found four, each fixed in the library in its own pull request:
- artifact reads did not carry the artifact's
kind - a tool's own
ModelRetryleft notool_returnedevent - the stream sent live frames from threads a client did not follow, and kept watchers for long-ended runs
- proposed edits had no summary for reviewers
- Harder: the library's CI now installs docplan's dependencies (uvicorn, websockets, rich, prompt-toolkit, and the Anthropic and OpenAI SDKs).
- Revisit: switch docplan to SQL storage by configuration once
artifactr.sqllands.
Action items¶
- Create
examples/docplanas a workspace member with its server, client, README and tests. - Enforce public-API-only imports in the layering test.
- Let docplan use
artifactr.sqlstorage by configuration (DOCPLAN_DATABASE_URL).