Status: accepted, 2026-08-17 (owner ruling, recorded in
../evidence/20260817-source-docs-skeptical-read.md §A)
Context#
versable-runner proved a reusable runner (app/) around a method registry
(lib/). A PM note appended to Von's doc drew the conclusion that new
capabilities should be registered into that one runner deployment or a
near-identical clone of its harness. The owner's stated goal is several
versions of one capability across several apps, swappable and independently
upgradable, with graceful degradation, and named the monolith module as bad.
Decision#
One runner implementation (template code, later a shared library per
language), many module deployments, each with its own manifest, version,
queue, identity audience, and release cadence. "Register a capability" is
how a module is built; it is not how one is deployed. Two capabilities may
share one deployment when they are small and differ only in payload
(../canon/14-graceful-degradation.md).
Rejected alternatives#
- One runner deployment, all capabilities registered. One scaling profile, one auth boundary, one release train, one blast radius for five capabilities. It is App V5's monolith with a queue in front, and it makes "two versions of the matcher at once" a code fork.
- A clone of the harness per capability, by copy. What the estate did
twice already; the copies drift (
../evidence/20260817-runner-four-file-diff.md), and every fix lands N times.
Consequences#
- The runner template is a real deliverable and the first thing the three named modules share.
- Provisioning per module is a script run per module;
deploy.shis the shape. - Cross-module concerns (identity, cache, field registry) need a home that is not any one module.
- V1 (2026-08-18) ships the four capabilities CO-HOSTED on one runner
deployment under the
canon/14exception: the shape this ADR rejects, taken deliberately for the three-day schedule, with four capabilities in one manifest so the split stays a config change. The split trigger is named now so silence does not make the exception the default: a second caller for one capability, a divergent memory or scaling profile, or a second version of one capability while another stays.guides/00:75-78states when the many-modules trade is premature, and today matches it.