platform/catalog: generic ProjectionStore[T] consumer + race-free holder; finish C1

- Generic SnapshotWriter[T]/SnapshotReader[T] over a value-agnostic raw layer;
  SnapshotHolder[T] now RWMutex-guards munmap vs in-flight Get (race-free swap,
  TestSnapshotHolder_SwapRace) — the drain grace is now just close-batching.
- ProjectionStore[T]: snapshot begin|chunk|end assembly → atomic swap, epoch-gated
  delta overlay, tombstones, atomic epoch sidecar (ordered before the swap),
  cold-start reopen, mandatory ProjectionTransform[T]. Future-epoch deltas are
  dropped by contract (recover via next snapshot), not buffered.
- Shared bus-framing constants so producer + consumer agree.
- Bump slask-finder / go-cart-actor / backoffice pointers; refresh status.md +
  catalog-projection.md to the finished state.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
matsandClaude Opus 4.8 committed 2026-06-28 21:07:39 +02:00
1 parent 5a3ffcb6bc
commit 8b454bccac
8 files changed
+959 -170

No files matched your search

+6
View File
@@ -13,6 +13,12 @@ func os2Stat(path string) (os.FileInfo, error) {
return os.Stat(path)
}
// appendP appends a Projection keyed by its own SKU — the producer/test pattern
// over the now-generic SnapshotWriter[Projection] (Append takes an explicit key).
func appendP(w *SnapshotWriter[Projection], p Projection) error {
return w.Append(p.SKU, p)
}
func repeat32(s string, n int) string {
out := make([]byte, 0, n*len(s))
for i := 0; i < n; i++ {