docs(localdb): amend Phase 1 plan - split Task 5 (event-log id change)

Execution review against the code found the integer site_events.id is
load-bearing in three places the original Task 5 did not list:

  - keyset cursor      EventLogQueryService.cs:70,141,153  (id > $afterId)
  - storage-cap purge  EventLogPurgeService.cs:164         (ORDER BY id ASC)
  - wire contracts     EventLogEntry.Id, both ContinuationTokens (long)
                       cross the site<->central Akka boundary

A GUID PK against the existing cursor silently drops rows, and against the
purge deletes arbitrary rows instead of the oldest. Task 5 is therefore split
into 5a (writer, standard) and 5b (read path + DTOs, high-risk), with 5b's
full file set spelled out and Task 10 gated on it.

Also recorded: Task 4's real registration site, and that both legacy DB paths
are CWD-relative and unset in docker today (so they live outside the data
volume and are already lost on container recreate - Phase 1 fixes that).

Claude-Session: https://claude.ai/code/session_01BL2Vu1ESDQ9SCN4gVKkdts
This commit is contained in:
Joseph Doherty
2026-07-19 02:34:38 -04:00
parent 84170b63ec
commit 1556ae04e4
2 changed files with 71 additions and 14 deletions
@@ -4,19 +4,28 @@
"mode": "parallel-waves",
"implementerModel": "opus",
"isolation": "worktree",
"branch": "feat/localdb-phase1",
"note": "Dispatch every unblocked task concurrently (waves in the plan header). Parallel implementers MUST use worktree isolation - concurrent git in one worktree races destructively."
},
"amendments": [
{
"date": "2026-07-19",
"by": "execution review",
"change": "Task 5 split into 5a (id 5, writer) and 5b (id 15, read path). Code recon found the integer site_events.id load-bearing in the keyset cursor (EventLogQueryService:70,141,153), the storage-cap purge (EventLogPurgeService:164), and long-typed DTOs crossing the site<->central Akka boundary (EventLogEntry.Id, both ContinuationTokens) - none of which were in the original Task 5 file set. 5b is high-risk. Task 10 gains a blockedBy on 15."
}
],
"tasks": [
{"id": 1, "subject": "Task 1: Add LocalDb packages to the build", "status": "pending"},
{"id": 2, "subject": "Task 2: Shared schema helpers (tracking + events, GUID PK)", "status": "pending", "blockedBy": [1]},
{"id": 3, "subject": "Task 3: Register LocalDb in the site composition root", "status": "pending", "blockedBy": [2]},
{"id": 4, "subject": "Task 4: Rewire OperationTrackingStore onto ILocalDb connections", "status": "pending", "blockedBy": [3]},
{"id": 5, "subject": "Task 5: Rewire SiteEventLogger + EventLogQueryService (GUID ids)", "status": "pending", "blockedBy": [3]},
{"id": 5, "subject": "Task 5a: Rewire SiteEventLogger onto ILocalDb + mint GUID ids", "status": "pending", "blockedBy": [3]},
{"id": 15, "subject": "Task 5b: Migrate the event-log read path off integer ids", "status": "pending", "blockedBy": [5]},
{"id": 6, "subject": "Task 6: One-time legacy data migrator", "status": "pending", "blockedBy": [4, 5]},
{"id": 7, "subject": "Task 7: Replication registration + sync endpoint (default OFF)", "status": "pending", "blockedBy": [3]},
{"id": 8, "subject": "Task 8: Bearer auth interceptor for the sync endpoint", "status": "pending", "blockedBy": [7]},
{"id": 9, "subject": "Task 9: Surface ISyncStatus as site health signal", "status": "pending", "blockedBy": [7]},
{"id": 10, "subject": "Task 10: Two-node in-process convergence test", "status": "pending", "blockedBy": [6, 8]},
{"id": 10, "subject": "Task 10: Two-node in-process convergence test", "status": "pending", "blockedBy": [6, 8, 15]},
{"id": 11, "subject": "Task 11: Docker rig enablement (site-a pair)", "status": "pending", "blockedBy": [8]},
{"id": 12, "subject": "Task 12: Live gate on the docker rig", "status": "pending", "blockedBy": [9, 10, 11]},
{"id": 13, "subject": "Task 13: Documentation truth pass", "status": "pending", "blockedBy": [12]},