docs(canon): accept ADR-012 and retract the parts it supersedes
ADR-012 accepted 2026-08-25.
ADR-010 — partially superseded, notes added inline:
decision 1: "a reading of the repositories" never said which copy, and the
answer was neither the forge nor a working copy but whichever checkout last
synced. The hub holds no repository files and never reads one.
decision 5: "central derives, does not accept pushes" was policy while the
workstation pushed everything.
decision 6: "preliminary" was named but never built.
ADR-003 — partially superseded:
decision 2: fingerprints composed from filesystem mtime are invalidated in
part. mtime is a property of one workstation, differs across clones, and
says nothing about content. Evidence: git_fingerprint for the-custodian
held the initial commit while last_state_synced_at was minutes old.
decision 5: the rebuild principle was correct but never exercised, and its
"without data loss" claim holds only while nothing exists solely in the hub
— which was false for 111 records on 2026-08-25.
ADR-001, ADR-005, ADR-007 and ADR-011 reviewed and unaffected; ADR-007 is
reinforced, since derived identifiers let an overlay and a forge-derived
projection compute the same identity.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
8c2825f4c3
commit
c0cead2169
3 changed files with 59 additions and 5 deletions
|
|
@ -16,7 +16,10 @@ tags: ["architecture", "state-hub", "caching", "read-model", "materialized-view"
|
|||
|
||||
## Status
|
||||
|
||||
Accepted.
|
||||
Accepted, and **partially superseded by `ADR-012`** (accepted 2026-08-25).
|
||||
Decision 2's fingerprint composition is invalidated in part; decision 5's rebuild
|
||||
principle is given a concrete source and a required operation. See the notes on
|
||||
each.
|
||||
|
||||
## Context
|
||||
|
||||
|
|
@ -84,6 +87,19 @@ the stored value is updated.
|
|||
computation (repo record, related domain, goals, snapshots).
|
||||
- Include the `mtime` (filesystem modification time) of every file that feeds
|
||||
the computation (`SCOPE.md`, `CLAUDE.md`, lockfiles, `tpsc.yaml`, etc.).
|
||||
|
||||
> **Invalidated in part 2026-08-25 by `ADR-012` decisions 1 and 2.** Filesystem
|
||||
> `mtime` is not a property of the source. It differs between machines, changes
|
||||
> on a fresh clone, and says nothing about content — so a fingerprint built from
|
||||
> it describes one workstation's filesystem rather than the repository. Under
|
||||
> `ADR-012` the projection derives from the forge, and the commit that produced
|
||||
> a record is both the correct input and the auditable one.
|
||||
>
|
||||
> This was not merely theoretical drift. `git_fingerprint` for `the-custodian`
|
||||
> held the repository's *initial* commit while `last_state_synced_at` was minutes
|
||||
> old: the field meant to identify what a projection reflects was wrong by the
|
||||
> entire history of the repository, and nothing noticed. Replace `mtime` inputs
|
||||
> with the source commit.
|
||||
- Join all components with `|` as a pipe-separated string — no hashing needed
|
||||
since the string is compared by equality, not transmitted to clients.
|
||||
- If a file is absent, encode `filename:absent` rather than omitting it, so
|
||||
|
|
@ -110,6 +126,19 @@ table's `max(snapshot_at)` directly rather than relying on the repo record.
|
|||
Per ADR-001, the state-hub must be rebuildable from scratch by re-ingesting
|
||||
all canonical sources. Materialised tables are **caches**, not records of
|
||||
authority. They may be wiped and repopulated at any time without data loss.
|
||||
|
||||
> **Given concrete form 2026-08-25 by `ADR-012` decision 7.** This principle was
|
||||
> correct and, until now, never exercised — an untested rebuild path is an
|
||||
> assumption rather than a capability, and this one was believed for long enough
|
||||
> that a divergence survived seven weeks behind it. `ADR-012` requires the
|
||||
> reconstruction to exist as a routine operation, scoped per repository, sourced
|
||||
> from the forge, and verifiable against it.
|
||||
>
|
||||
> The claim "without data loss" also needs its precondition stated: it holds only
|
||||
> while the rule immediately below does. On 2026-08-25, 111 work records existed
|
||||
> only in the hub, so a rebuild at that moment would have destroyed them.
|
||||
> `ADR-012` therefore requires reset to refuse, per repository, when records have
|
||||
> no counterpart in the forge.
|
||||
This means:
|
||||
- No materialised table may be the only copy of any information.
|
||||
- Schema migrations that wipe a materialised table are safe and expected.
|
||||
|
|
|
|||
|
|
@ -16,7 +16,9 @@ tags: ["architecture", "state-hub", "repo-manager", "hub-core", "authority", "ca
|
|||
|
||||
## Status
|
||||
|
||||
Proposed.
|
||||
Proposed, and **partially superseded by `ADR-012`** (accepted 2026-08-25).
|
||||
Decisions 1, 5 and 6 are sharpened or given a mechanism there; see the notes on
|
||||
each below. Everything else in this ADR remains in force.
|
||||
|
||||
## Context
|
||||
|
||||
|
|
@ -69,6 +71,12 @@ Hub — running on railiance — is authoritative. It is authoritative *as a rea
|
|||
of the repositories*, not as a second place data lives. Repository files remain
|
||||
the source of truth (`ADR-001`).
|
||||
|
||||
> **Sharpened 2026-08-25 by `ADR-012` decision 1.** "A reading of the
|
||||
> repositories" never said *which* copy of them, and the honest answer was
|
||||
> neither the forge nor any particular working copy: the projection derived from
|
||||
> whichever checkout last ran the sync. The hub holds no repository files at all
|
||||
> and never reads one. `ADR-012` names the forge as the projection source.
|
||||
|
||||
**2. A local hub is a cache, never a database.** Local instances hold a
|
||||
rebuildable projection. A cache may be discarded and reconstructed from the
|
||||
repositories at any time, and losing it must never lose work.
|
||||
|
|
@ -118,11 +126,23 @@ conflict and belongs to git.
|
|||
"Authoritative" means authoritative *reading*, so nothing may inject derived
|
||||
state directly. Hub-native records are the exception and keep a real write path.
|
||||
|
||||
> **Sharpened 2026-08-25 by `ADR-012` decision 6.** This was policy, not
|
||||
> practice: nothing derived, and the workstation pushed everything. `ADR-012`
|
||||
> retires push-based sync as the primary path so that "central derives" becomes
|
||||
> true rather than aspirational.
|
||||
|
||||
**6. Preliminary until confirmed.** Locally registered data and uncommitted
|
||||
repository state are preliminary until the central service has seen them.
|
||||
Mitigation is by changing the repository files and the local cache — never by
|
||||
editing central to match a local view.
|
||||
|
||||
> **Given a mechanism 2026-08-25 by `ADR-012` decisions 3 and 4.** "Preliminary"
|
||||
> was named here but never built, so in practice locally registered data was
|
||||
> indistinguishable from derived state once it arrived. It is now a labelled
|
||||
> overlay within the same projection — explicitly not a second store — and it
|
||||
> retires when the commit carrying it reaches the forge. The prohibition on
|
||||
> editing central to match a local view is unchanged.
|
||||
|
||||
Combined with `ADR-007` decision 2 (identifiers derived from `PREFIX-WP-NNNN`),
|
||||
"preliminary" largely stops mattering: a cache computes the same identifier
|
||||
central will, so offline-registered data is already correct on arrival and needs
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@
|
|||
id: CUST-ADR-012
|
||||
type: architecture-decision-record
|
||||
title: "What the Hub Projects: Forge as Projection Source, Working Copies as Preliminary Overlay"
|
||||
status: proposed
|
||||
status: accepted
|
||||
owner: the-custodian
|
||||
revision: "draft-1"
|
||||
revision: "1.0"
|
||||
last_reviewed: "2026-08-25"
|
||||
review_interval: 6m
|
||||
decided_by: Bernd Worsch
|
||||
|
|
@ -16,7 +16,7 @@ tags: ["architecture", "state-hub", "forgejo", "projection", "provenance", "auth
|
|||
|
||||
## Status
|
||||
|
||||
Proposed. Supersedes `ADR-010` decision 1's phrase "authoritative as a reading of
|
||||
**Accepted 2026-08-25** by Bernd Worsch. Supersedes `ADR-010` decision 1's phrase "authoritative as a reading of
|
||||
the repositories" by making the reading concrete, and implements decision 6's
|
||||
unbuilt notion of "preliminary".
|
||||
|
||||
|
|
@ -227,6 +227,11 @@ built. Those belong to implementation.
|
|||
- **`ADR-010`** — decisions 1 and 5 are sharpened, not reversed: central still
|
||||
derives and still does not accept pushes of derived state. Decision 6's
|
||||
"preliminary" gains a mechanism. The local-cache-versus-database framing stands.
|
||||
- **`ADR-003`** — partially superseded. Decision 2 composes fingerprints from
|
||||
filesystem `mtime`, which is a property of one workstation rather than of the
|
||||
source; under decision 1 here the input is the commit. Decision 5 already
|
||||
stated the rebuild principle correctly but had never been exercised; decision 7
|
||||
here makes it an operation with a source, a scope and a verification.
|
||||
- **`ADR-007`** — derived identifiers become more valuable here: a forge-derived
|
||||
projection and a preliminary overlay compute the same identifier for the same
|
||||
record, so absorbing an overlay entry needs no reconciliation.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue