Literate AI

Repository documentation

ADR 0027: Durable Split Web/API/Collector/Cache Application Pattern with Scheduler-Lease Authority

Context

Auditing portfolio-dashboard and telemetry-dashboard surfaced one recurring provider-neutral architecture that generation does not currently produce by default. A dashboard-style service that polls expensive upstream systems keeps being generated as a single service that recollects upstream data inside request handlers and loses all state on restart, coupling frontend availability to collection latency and to upstream credentials.

The correct shape, which both projects converged on independently, has four boundaries:

  1. a browser frontend that consumes only a same-origin, read-only API;
  2. a read-only HTTP API that consumes only a durable local snapshot store;
  3. a single-writer collector/worker that alone may call upstream providers;
  4. a durable embedded SQL snapshot cache (SQLite first).

Projects can model this today with multiple Components and provides/requires, but the reusable contracts are not cataloged, so every project re-derives them and repeatedly gets the anti-pattern. Both projects also need the same collector cadence behavior: a once-daily nominal UTC run with bounded jitter, durable schedule state, and a single-writer lease so restarts and concurrent workers do not double-collect (#217).

This ADR decides the reusable pattern and the scheduler-lease authority together, because the scheduler is the collector boundary's cadence contract — separating them would let the lease store drift from the cache boundary it must share.

Decision

Catalog a four-boundary reference composition, not a monolith template

Ship an inheritable reference Component set (and exact specification-to-source guidance) for the four boundaries, composed through public capabilities only (ADR-0005 PublicInterfaceContract), so no boundary sees another's private specifications:

The four are independent deployment units (ADR-0026) so restarting the frontend or API does not invoke the collector. Capability contracts connect them without exposing private transitive specifications; the framework template carries no provider commands, product schemas, credentials, or application vocabulary — those stay in the deriving project's authority (ADR-0001 boundary, ADR-0002 ecosystem).

Rejected alternative: a single "durable-dashboard" Component kind with four built-in surfaces. That would bake product-shaped structure into the framework, violate ADR-0001, and prevent projects from substituting, say, a non-SQL cache or a different frontend. The pattern is a composition of public capabilities, not a new kind.

Coherent snapshot publication and read isolation

The cache boundary publishes a current snapshot only after all required writes for a collection window validate. Readers (API, therefore frontend) always see the last complete snapshot: a failed or partial collection leaves readers on the prior complete snapshot rather than a half-written one. This is the durable-availability property both audited projects needed and is expressed as a cache capability postcondition, not left to generated code to reinvent.

Scheduler-lease authority is generation guidance, not a framework daemon

The collector's cadence is a reusable worker/scheduler generation skill (or Component template) — reference authority for an application's own worker, not a scheduler process the framework runs. It specifies:

Placing the lease and schedule state inside the cache boundary (rather than a fifth store) is deliberate: the single-writer lease and the single-writer cache write are the same concurrency invariant, so they share one durable store and one migration lineage.

Consequences

A new portfolio sample composes the four Components and is wired into the conformance harness (ADR-0002, ADR-0012 sample-portfolio matrix), proving the boundaries on macOS, Linux, and Windows where SQLite is available. Component locks and CycloneDX evidence preserve the four-boundary composition (ADR-0026 deployment units). The scheduler skill joins the specification-to-source catalog with its own SkillEvaluator coverage and deterministic acceptance tests for jitter bounds, UTC rollover, restart states, concurrent single-winner leasing, expired-lease recovery, boundary-crossing long runs, retry-without-double-run, and cross-process next-run readability.

The cost is a non-trivial reference composition plus a new skill, and it hard- depends on ADR-0026 landing first (the independent deployment units). The benefit is that the durable, restart-safe, credential-isolated architecture both audited projects needed becomes the default a project inherits, instead of an anti-pattern each one re-derives. The frontend of this pattern is exactly what ADR-0028's browser acceptance validates.

Read the Markdown sourceConference homePublished 1.3.0 · Patch 1.3.1 in progress · Development 1.4