cns/infrastructure/
Persistence and caching. All database access for CNS flows through this layer.
Files
continuum_repository.py— PostgreSQL repository for continuums and messages. Per-user DB client caching. Handles segment sentinel creation (_ensure_active_segment), message persistence with UPSERT +::vector(768)cast, JSONB metadata operations (metadata->>'key',jsonb_set()), segment queries, history pagination, full-text search. Admin queries useAdminSessionto bypass RLS. Session resume:find_resumable_segment()finds most-recently-collapsed non-tombstoned segment (when no active exists),reactivate_collapsed_segment()atomically clears collapse artifacts and resets to active,delete_segment_memories()removes memories extracted from a specific segment. ExportsHistoryResult,FailedSegment,ActiveSegmentRowTypedDicts for return type contracts.continuum_pool.py— Valkey-backed session pool.get_or_create()returns cached Continuum or creates new session with segment boundary.UnitOfWorkaccumulates messages + metadata changes, commits atomically. Cache miss = new session. Event-driven invalidation (not TTL). Dead methodsget_by_id()andget_session_info()were removed (zero callers).valkey_message_cache.py— Message serialization/deserialization for Valkey. Converts Message objects to/from JSON. Event-driven invalidation via segment timeout, no TTL expiry. No constructor DI — usesget_valkey_client()singleton directly.feedback_repository.py— CRUD forfeedback_signalstable. Saves assessment signals (with section_id, strength, evidence), retrieves unsynthesized signals, marks as synthesized. ExportsFeedbackSignalRowTypedDict forget_unsynthesized_signals()return type.feedback_tracker.py— Synthesis lifecycle for the user model pipeline. Uses modular arithmetic onusers.cumulative_activity_days(not its own counter) to determine synthesis timing. Storesactivity_days_at_last_synthesissnapshot, user model XML, and needs_checkin flag. ExportsLoraContentTypedDict forget_lora_content()return type,TrackingStatusTypedDict forget_tracking_status()return type.
Patterns to Follow
Database Access
- Use
PostgresClient("mira_service", user_id=user_id)for user-scoped queries (RLS enforced). - Use
AdminSessionfromutils.database_session_managerfor cross-user admin queries only. - Repository caches per-user DB clients in
_db_cachedict — don't create new PostgresClient per call. - JSONB filtering:
metadata->>'key' = %sfor string comparison,metadata ? 'key'for existence. - Atomic metadata updates:
jsonb_set(metadata, '{key}', to_jsonb(%s))withexecute_returning(). - UUIDs stay native for PostgreSQL queries. Convert to string only at serialization boundaries.
Message Persistence
- Use
save_message()orsave_messages_batch()— they handle segment boundary creation automatically via_ensure_active_segment(). - The UPSERT pattern (
ON CONFLICT (id) DO UPDATE) handles replay safety. _parse_message_rows()is the canonical DB-row-to-Message converter. Don't reimplement.
Caching
- Valkey cache is event-driven (no TTL). Invalidated when segment times out.
- Cache miss in
continuum_pool.get_or_create()triggersSegmentCacheLoaderto reconstruct from DB. ValkeyMessageCachehandles Message ↔ JSON serialization — use it, don't roll your own.
Unit of Work
continuum_pool.begin_work(continuum)returns aUnitOfWork.- Call
uow.add_messages(msg1, msg2)during processing, thenuow.commit()once at the end. - Commit persists to both PostgreSQL and Valkey cache atomically.
User Model Storage
FeedbackRepositoryfor assessment signal CRUD (section_id, strength, evidence),FeedbackTrackerfor synthesis lifecycle.- Synthesis timing uses modular arithmetic:
cumulative_activity_days % threshold == 0with dedup guard (activity_days > activity_days_at_last_synthesis). No counters to reset — completely stateless. get_tracking_status()computesuse_days_since_synthesison the fly ascumulative_activity_days - activity_days_at_last_synthesisto preserve API contract.initialize_user()usesON CONFLICT DO NOTHINGfor race-safe account setup.get_lora_content()returns{synthesis_xml, needs_checkin}in a single query for LoraTrinket.