UI skins, landing page, /config, EntityStore, AI stepper documentation (CAL-20). Comprehensive documentation gap analysis applied across README.md, ARCHITECTURE.md, AGENTS.md, and CONTENT_WRITING.md covering:
Pluggable skin system (BasecoatUI, Morpheus, DaisyUI) with env/query/selector switch model.
Landing page (/) and read-only config view (/config) as product surfaces.
EntityStore pluggable persistence (pbstore default, ENTITY_STORE=crdt for CRDT).
AI Suggest stepper signal isolation from Queue + Retry stepper.
Version badge build metadata via ldflags + docker buildx --build-arg.
Per-skin CSS bundle pipeline.
Added (CRDTStore Phase 2 + 3)
crdtstore.transport.go — JetStream cross-instance op transport (publisher + consumer).
crdtstore.ApplyRemoteOp(ctx, ownerID, op) — applies peer Loro ops to the local doc.
crdtstore.Watch(ownerID) — signal-driven channel of doc-version bumps (Phase 3).
internal/server/crdtstore_wire.go — boot-time transport wire (only when ENTITY_STORE=crdt).
cmd/web/main.go — installs the transport post-Init (router exposes concreteTodoStore for this).
Integration test: two CRDTStores share one JetStream, both Observe peer's Creates within ~3s.
ADR-0017 in docs/decisions.md (Phase 2 + 3 design rationale).
Fixed
CRDTStore.Create previously deadlocked when transport != nil because publishOp re-acquired the mutex already held by Create/Update/Delete. Refactored to publishOpFromDoc(ctx, ownerID, opID, d) which expects the caller to already hold s.mu.