--- id: SHARD-WP-0009 type: workplan title: "git-backed DecisionLog + per-space append authority" domain: whynot repo: shard-wiki status: done owner: tegwick topic_slug: whynot created: "2026-06-15" updated: "2026-06-15" depends_on: - SHARD-WP-0007 state_hub_workstream_id: "4fb5b29b-955c-4f37-85cf-58b4643ab1ca" --- # SHARD-WP-0009 — git-backed DecisionLog + per-space append authority ## Goal Back the keystone with real storage: swap the in-memory `DecisionLog` (SHARD-WP-0007 T5) for a **git-addressable, append-only** log with a **per-space append authority (lease)**, exactly as `CoreArchitectureBlueprint` §8.1 specifies and `SHARD-WP-0006` T2 decided (resolves review B-1/B-3). The log API and the derived fold are unchanged; only storage + the concurrency model become real. This makes coordination-canonical state git-addressable (history/patch/review/ backup — I-6) and read-your-writes correct across processes, not just in-process. **Non-goal:** distributed multi-node leasing beyond a single coordinator; per-space log sharding (blueprint O-12). Single append authority per space is the target. ## Context - Keystone spec: `CoreArchitectureBlueprint.md` §8.1; decision `SHARD-WP-0006` T2. - Current impl: `src/shard_wiki/coordination/decision_log.py` (in-memory; same API to preserve). --- ## Git event-store backend (append = commit/object) ```task id: SHARD-WP-0009-T1 status: done priority: high state_hub_task_id: "a8fcbb3e-fbc4-4f68-9cf0-d8a6ee057191" ``` A git-backed `DecisionLog` storage backend: each space is a ref/branch (or an objects stream); `append` writes an immutable event object and advances the ref; `events(space)` reads the ordered log; events serialize deterministically (stable JSON). Preserve the in-memory backend as the test/default double behind the same interface. Tests: append→git→read round-trips; ordering preserved; deterministic serialization. ## Per-space append authority (lease) ```task id: SHARD-WP-0009-T2 status: done priority: high state_hub_task_id: "62abd162-4243-4659-8d27-9fc967ab11a0" ``` A **single append authority per space**: a lease/leader abstraction that serializes appends so the log is a total order (the ordering authority §8.6 relies on). Non-holders forward append intents to the holder; the lease is time-bounded and re-grantable (HA: a failed holder is replaced and resumes from the log head). Tests: concurrent append attempts serialize; lease hand-off resumes from head; a partitioned non-holder cannot fork the log. ## Fold over the git log + read-your-writes across processes ```task id: SHARD-WP-0009-T3 status: done priority: high state_hub_task_id: "8cc3691e-05a7-443f-9292-a3fdf3fd59a4" ``` `fold` reads the git log into `CoordinationState` (unchanged semantics); verify **read-your- writes across separate processes/handles** against the same space ref. Tests: process A appends, process B (new handle) sees it; fold equals the in-memory fold for the same event sequence. ## Migration + wiring ```task id: SHARD-WP-0009-T4 status: done priority: medium state_hub_task_id: "281e1db4-6a75-456b-a2bc-b761feb10609" ``` Make `InformationSpace` use the git backend (configurable; in-memory remains for tests). A one-time importer replays an in-memory/JSON log into git. Update SCOPE; `pytest` + pyflakes green; no behavioural change to overlay/union (same fold). --- ## Acceptance criteria - `DecisionLog` git backend passes the same tests as the in-memory one (API/fold parity). - Appends are totally ordered per space via a single append authority; read-your-writes holds across processes; a non-holder never forks the log. - Coordination-canonical state is git-addressable (history/patch/review/backup). - `pytest` + pyflakes green; each task committed; state-hub synced. ## Suggested task order T1 git store → T2 append authority → T3 cross-process fold → T4 migration + wiring.