From 9162f7e530996b741f51a957869c633940e0df69 Mon Sep 17 00:00:00 2001 From: codex Date: Tue, 25 Aug 2026 21:36:21 +0200 Subject: [PATCH] =?UTF-8?q?docs(canon):=20ADR-012=20=E2=80=94=20require=20?= =?UTF-8?q?a=20routine=20reset=20of=20the=20projection=20from=20the=20forg?= =?UTF-8?q?e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds decision 7: the projection must be discardable and rebuildable from what Forgejo holds, per repository and fleet-wide. This is what makes the other decisions checkable. A read model that cannot be rebuilt from its source is a database with a projection's reputation, and the difference only surfaces when someone needs to rebuild it. ADR-010 already asserts a cache may be reconstructed at any time; that claim has never been executed. Three properties keep it real: routine rather than emergency, scoped per repository, and idempotent enough to verify against the forge — which derived identifiers make possible. Two refusals are explicit. Reset cannot restore the preliminary overlay, since the forge does not hold it. And reset must refuse when records exist only in the projection: on 2026-08-25 that was 111 work records, which a rebuild would have erased while reporting success. Also flags an unresolved boundary: hub-native records are not forge-derived and must survive a rebuild of forge-derived state. Co-Authored-By: Claude Opus 5 --- ...ojection-source-and-preliminary-overlay.md | 48 +++++++++++++++++-- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/canon/architecture/adr-012-projection-source-and-preliminary-overlay.md b/canon/architecture/adr-012-projection-source-and-preliminary-overlay.md index fadc74f..00170a7 100644 --- a/canon/architecture/adr-012-projection-source-and-preliminary-overlay.md +++ b/canon/architecture/adr-012-projection-source-and-preliminary-overlay.md @@ -111,13 +111,51 @@ records under decision 3, but the baseline is derived, not received. This closes the gap where "central derives" was policy while "the laptop pushes" was practice. -**7. Formal git review stays optional.** Deriving from the default branch gives a +**7. The projection must be resettable from the forge, as a routine operation.** +There must be a supported way to discard the projection — for one repository or +for the whole fleet — and rebuild it from what Forgejo holds. + +This is the decision that makes the others checkable rather than merely stated. +A read model that cannot be rebuilt from its source is not a projection; it is a +database with a projection's reputation, and the difference only becomes visible +on the day someone needs to rebuild it. `ADR-010` decision 2 already asserts that +a cache "may be discarded and reconstructed from the repositories at any time" — +that claim has never been executed, and an untested rebuild path is an assumption, +not a capability. + +Three properties make it real rather than ceremonial: + +- **Routine, not emergency.** It should be run deliberately and often enough that + it is known to work, not discovered under pressure. A reset that has never been + performed is indistinguishable from one that does not work. +- **Scoped.** Per repository as well as fleet-wide. Rebuilding one repository's + records must not require discarding everything, or it will never be used. +- **Idempotent and verifiable.** A reset followed by a reset produces the same + projection, and the result can be compared against the forge to show it matches. + Derived identifiers (`ADR-007`) are what make this possible: the same commit + yields the same record identities every time. + +**Reset does not restore the preliminary overlay.** Overlay records exist +precisely because the forge does not hold them, so a rebuild from the forge +cannot reproduce them and must not pretend to. Reset therefore discards +preliminary state, and must say so plainly before it runs. + +**A reset must refuse when records exist only in the projection.** If the hub +holds records with no counterpart in the forge, rebuilding destroys them. That is +not hypothetical: as of 2026-08-25, 111 work records existed only in a retired +local database, and a rebuild at that moment would have erased them. The reset +path must detect that condition and stop, naming what would be lost, rather than +proceed and report success. + +**8. Formal git review stays optional.** Deriving from the default branch gives a shared baseline without requiring pull requests. Review can be adopted per repository where it earns its keep; this ADR neither mandates nor forbids it. ## Consequences -**Positive.** Truth becomes checkable by anyone, from anywhere, without a clone. +**Positive.** The hub becomes provably a projection: rebuildable on demand, and +therefore knowable to be one. Truth becomes checkable by anyone, from anywhere, +without a clone. Multiple contributors share one baseline instead of overwriting each other's views. Provenance becomes auditable — every record can name its commit. The "push then delete the working copy" case simply works. The distinction between @@ -140,7 +178,11 @@ direct forge fetch, not left dormant with an obsolete justification. **Unresolved.** This ADR does not settle the derive cadence, whether central clones or uses the Forgejo API, how preliminary records are surfaced in the dashboard and MCP, or what happens to a preliminary record whose commit never -arrives. Those belong to implementation. +arrives. Nor does it settle how hub-native records — progress events, decisions, +inbox messages, which `ADR-010` decision 4 classes as originating in the hub — +survive a reset. They are not forge-derived and must not be destroyed by a +rebuild of forge-derived state; the boundary needs drawing before reset is +built. Those belong to implementation. ## Relationship to prior decisions