diff --git a/spec/CoreArchitectureBlueprint.md b/spec/CoreArchitectureBlueprint.md index b68b716..cc6145d 100644 --- a/spec/CoreArchitectureBlueprint.md +++ b/spec/CoreArchitectureBlueprint.md @@ -359,7 +359,7 @@ derived**; recompute reads them, never regenerates them. It comprises: - **Identity resolution & equivalence** — detect "same topic / derived content" path- independently from *derived* signals (content fingerprint, span-set overlap) **plus** the *coordination-canonical* inputs (alias table, curator binding); present as - **chorus-of-voices** or designated-canonical (a *policy* preset). (Scaling: §8.6.) + **chorus-of-voices** or designated-canonical (a *policy* preset). (Scaling: §8.7.) - **Union graph** — the navigable join of pages, links, and dimensions (namespace, genealogy, version, shard, equivalence). A *derived lens over canonical files+journal, never a new store* (the ZigZag boundary). @@ -394,6 +394,66 @@ One snapshot-provenance record (run id, source rev, timestamp, environment "ungu serves notebooks, renders, and recordings alike. **No INTENT amendment is required** — this lives inside the existing page model (L2) and projection model (L4). +### 8.6 Consistency, concurrency & conflict model + +INTENT makes real-time cross-shard consistency a non-goal — but "no strong consistency" is not +the same as "no defined consistency." This is the guarantee shard-wiki *does* offer, and the +mechanism (not policy) that makes concurrent editing safe (review bug B-2). + +**The consistency guarantee — causal, anchored on the journal:** + +- **Read-your-writes for coordination-canonical state.** Once an overlay/binding/merge is + committed to the journal, this client always sees it (the journal is the client's own causal + spine). This is a *strong* local guarantee, cheap because the journal is local Git. +- **Causal consistency across the derived tier.** The union/index/projections reflect a causal + cut of `(sharded inputs seen so far, journal)`. Effects never appear before their causes; a + projection that has seen journal commit *C* has seen everything *C* depends on. +- **Eventual convergence for sharded-canonical inputs.** Remote shard content is pulled + asynchronously (lazily or by notify/poll, §8.7); the union converges to each shard's latest + *as observed*, bounded by the shard's operational envelope. Freshness is always *shown* + (provenance envelope), never faked — a stale projection is labelled stale, not wrong. + +So: **strong + read-your-writes for what shard-wiki owns (the journal); causal for what it +derives; eventual + freshness-labelled for what shards own.** No global clock, no distributed +transaction, no two-phase commit across shards — none is needed, because shard-wiki coordinates +rather than controls. + +**Conflict detection & representation is core mechanism; only resolution is policy (I-7).** +The split the earlier draft elided: + +- **Detection (core).** Divergence is detected structurally: two identities resolve as + equivalent (§8.4) but their content fingerprints differ, or an overlay's base revision no + longer matches the shard's current revision. Detection is always on; it is never optional. +- **Representation (core).** A detected conflict is **first-class data in the union**, not an + error: equivalent-but-divergent pages are presented as a **coexisting set** (the + chorus/keep-both representation), each fully attributed, with the divergence recorded in the + provenance envelope (union without erasure — a conflict is information, not a failure). +- **Resolution (policy).** *Which* version wins, or whether they stay coexisting, is a + configurable preset (§10): chorus / designated-canonical / git-merge / vote-to-merge / + overlay-only. Core never hard-codes one. + +**Overlay-apply under source drift (the concurrent-write case).** An overlay carries the +**base revision** of the shard content it was authored against. On apply, core compares base to +the shard's current revision: + +- *unchanged* → apply (fast-forward), commit to journal, propagate if the profile permits; +- *changed, non-overlapping* → three-way merge where the merge capability allows (axis 6), + else keep-both; +- *changed, overlapping* → **refuse + re-present** as a conflict (above); never silently + clobber (I-5, no silent remote mutation). The unapplied overlay remains coordination- + canonical and valid against its base. + +**Ordering.** The journal commit is the ordering authority for coordination-canonical effects; +a shard-native write is only *acknowledged* in the journal after the adapter confirms it, so a +crash between journal-intent and shard-write is recoverable (the intent is replayable, the +write is idempotent-keyed on identity+base-rev). Cross-shard operations are ordered by their +journal commits, giving the causal cut above. + +**Residual open items** (tracked in *Known scaling risks & open problems*, §12, not pretended +solved): the exact convergence bound for +high-write CRDT shards under partition, and whether per-equivalence-set divergence needs a +vector clock vs. a simple base-rev comparison, are deferred to implementation spikes. + --- ## 9. Cross-cut — Authorization (L5) diff --git a/workplans/SHARD-WP-0005-architecture-hardening.md b/workplans/SHARD-WP-0005-architecture-hardening.md index e7469e0..1901329 100644 --- a/workplans/SHARD-WP-0005-architecture-hardening.md +++ b/workplans/SHARD-WP-0005-architecture-hardening.md @@ -72,7 +72,7 @@ out of L4-rebuildable into the coordination tier. ```task id: SHARD-WP-0005-T2 -status: todo +status: done priority: high state_hub_task_id: "d76a6b07-5157-426c-9343-a3e7efedf4a9" ```