The model said
Queued deliveries were retained until acknowledged
, with no upper limit.
Case study · HashRelay, built with Continuum
HashRelay sends notifications from scripts, CI jobs and AI agents to every device subscribed to a hashtag. When a laptop is offline, its notifications are queued. This case study shows how Continuum turned “how long do we keep them?” into a decision the model, the code and the next agent session all agree on.
The problem
The model said
Queued deliveries were retained until acknowledged
, with no upper limit.
The code did
Expired them after ReplayWindowHours (24 by default), and only when the device reconnected.
The reports showed
Expired deliveries counted as delivered in the activity list, the duplicate check, the notification page and the dashboard.
From the rationale recorded with ADR-001 by the agent that proposed it. The project’s architecture notes also listed offline retention as unresolved.
The decision
The trade-off: a laptop closed overnight should still catch up, but a device that never returns shouldn’t make storage grow forever, and nobody should be told an alert arrived when it didn’t.
Decision "A delivery queued for an offline endpoint is retained until it is acknowledged or until its replay window (ReplayWindowHours, 24 by default) elapses, whichever comes first. An expired delivery is recorded as expired and is never counted as delivered." Alternatives considered · Retain until acknowledged, with no bound — storage grows without limit for endpoints that never return · A per-workspace replay window — more configuration than any current workspace needs Consequences · Queued deliveries expire on a schedule, not only when the endpoint reconnects · Activity, duplicate and notification views stop counting expired as delivered Risk · A device offline for longer than the window loses those notifications; it is told they expired, not that they were delivered Proposed 5 Nov 2026 by an AI agent (Claude Code) acting for the owner Accepted by the project owner · rule: a person who did not author it approves Signed by the Continuum Host · record verified: 19 events, chain intact
Excerpt from architecture/decisions/DECISIONS.md in the HashRelay repository (commit 265bafc), rendered from the signed record by continuum-cli 0.28.3. Identities are omitted.
Model-derived diagram
Continuum Diagram drew this from HashRelay’s compiled model, then rebuilt it as an editable SVG and checked every box and arrow against the model. The requirement that ADR-001 added is highlighted.
Verification: of 23 claims on the canvas, 19 are declared in the model and 4 are inferred from quoted descriptions (drawn dashed). None is drawn stronger than the model supports. Model attestation sha256:8f88867a….
The 24-hour figure is not in the diagram because the model doesn’t contain it. The model states that the window is bounded, and the decision sets the default. Open full size
What Continuum produced
A change file adds the requirement, links the service that satisfies it, and rewrites the catch-up requirement so it no longer promises unbounded retention.
add into HashtagDelivery { requirement BoundedOfflineRetention { desc "… replayable for a bounded replay window set per deployment. When the window elapses the delivery becomes expired, whether or not the endpoint ever reconnects. … never counted as delivered." } } link DeliveryService satisfies BoundedOfflineRetention // Catch-up keeps its meaning but loses the promise // the system never kept. modify CatchUpWithoutInterruption description = "… retained until acknowledged or until their replay window elapses …"
Before the change, the decision check failed on the model. After it, the check passed, and the proof that applying the change produces the new model came back equivalent.
model sha256:c2824b88… change-required · 2 missing from the model model sha256:a89061e4… (after the change) aligned · all expectations hold apply(change) → EQUIVALENT
Compiled again for this page, from commit 265bafc.
ledger 78 passed, 0 failed, 0 not-evaluated errors 0 warnings 18 (unrealized-intent) change-state sha256:a89061e4…f7f warning adl/architectural/unrealized-intent @ Requirement HashtagDelivery.BoundedOfflineRetention required: verifies, and it is not supplied
That warning is accurate: tests for this rule exist in the code, but the model doesn’t yet declare which test verifies it.
Either side of the boundary
Two regression tests pin the 24-hour window. They were written before the fix, and the second one failed first: expected 0 delivered, actual 1.
#ops is offline, and “Disk almost full” is publishedParaphrased from tests/HashRelay.Server.Tests/RetentionTests.cs. Results were recorded in the decision record as reported, not verified by Continuum: 167 of 167 tests passed at that commit. The tests don’t run the hosted timer and don’t establish production behaviour. HashRelay’s Continuum acceptance package has no scenario for this requirement yet.
The next session
On 11 November an agent drafted macOS and Linux support in a new session. Its change file names the model state ADR-001 produced as its base. It says the proposal leaves replay alone: ack and replay stay as CatchUpWithoutInterruption/BoundedOfflineRetention state them
. It also marks itself not approved, not adopted
, so reviewers can see what is decided and what is proposed.
| Part of the work | Contributed by Continuum | Not established by Continuum |
|---|---|---|
| Spotting the mismatch | A model with an exact statement to compare against the code | The comparison itself. The agent read the code. |
| Deciding | A signed decision record with alternatives, risk, separation of duties and model expectations | Whether 24 hours is the right number for users |
| Modelling | A change file that compiles, an alignment check that went from failing to passing, and proof the change applies | That the model covers every replay case |
| Building | A place to record test evidence and an honest label for it | That the code conforms. Tests are reported, and the hosted timer was not exercised. |
| Continuing | A pinned model state the next session built on, and a diagram drawn from it | That every future change will respect the decision |
The walkthrough shows each step and what a team does at each one. Launch updates tell you when you can try it.