- SQLite MVP complete (Phase 3). Lint debt reduction complete: Phase L1+L2, L3.1-L3.5, L4-A through L4-K done. Baseline locked at 7 warnings (all in opentui.d.ts, skipped by design).
- Phase 4 (Living State Layer) complete: experience packets, self-model, belief knowledge, advisory context-brief injection. All 4F-C requirements verified.
- Phase 9B (Onboarding Quality + Telemetry) complete: context injection telemetry schema, compaction telemetry audit, observation window active.
- Phase 9C (Database-Wide Compaction Observability) implemented: project/client/runtime attribution, classified failures, cross-session coverage, gross/injection/net token accounting, and safe partial cache-write handling. Production migration/observation pending runtime restart.
- Capability promotion closure: all 7 criteria implemented, independently reviewed, cross-database verified. Unblocked.
- Observation window active — pre-9C compaction baseline captured 2026-07-21: 390 rows from 1 session, 232 skipped, 158 failed, 0 compressed, 4,107,005→4,107,005 estimated tokens, 0 verified savings. Next observation begins after runtime restart applies the attribution migration.
- Each sub-phase is behavior-preserving, boring, verbatim moves first
- CSM_EMBEDDING_PROVIDER (ollama|openai), OPENAI_API_KEY, OLLAMA_HOST
- Database URL: dev/test=localhost, production=explicit flag
- CI with Postgres service container
- ESLint rules start as warnings, tighten later
- Lint warning baseline: 7 warnings (max-warnings=7 prevents unbounded growth)
caughtErrorsIgnorePattern: '^_'added to@typescript-eslint/no-unused-vars— catch blocks with_errare allowedbetter-sqlite3doesn't support?NNNformat with spread.run()— must use anonymous?parameters- SQLite schema: TEXT for timestamps/JSON/arrays/embeddings; INTEGER PRIMARY KEY AUTOINCREMENT for PKs
- PostgreSQL remains default; SQLite is adapter path, not rewrite; no vector search in SQLite MVP
memories.session_idis nullable (FK on sessions, NULL bypasses it)
- 0
no-consolewarnings: All 15 intentional console calls documented witheslint-disable-next-line no-consolerationale - ~7
no-explicit-anywarnings: Remaininganyin memory-extractor.ts (false positive -determineInitialStatusreturns specific union type but linter can't infer this in this context) - 7
no-unused-varswarnings: External API generic params (opentui.d.ts) — skipped by design max-warnings=7— any new warning added to src/ will fail lint
Phases 1A–4F-C, 7A–9B, L1–L4-K, and capability promotion closure are complete. Full per-phase detail (commits, schemas, test counts) is archived in docs/PHASE_HISTORY.md. Per-phase design docs live alongside it (e.g. PHASE3G_SQLITE_MVP.md, PHASE7C_REENTRY_PROTOCOL_DOCUMENTATION.md).
Native Claude Code plugin (plugins/cross-session-memory/): CSM is now a first-class Claude Code feature. A HostProfile seam (src/native-host-profile.ts) parameterizes the shared relay/runtime/hooks so Codex and Claude reuse one implementation (no duplication) while getting distinct transport pipes (csm-claude-<hash> vs csm-codex-<hash>). runNativeMcpServer(profile) / runNativeHookClient(profile) back thin claude-mcp-server.ts / cli/claude-hook-client.ts entrypoints. The bundle ships the manifest, .mcp.json, 10 lifecycle hooks, 12 slash commands, 3 subagents, and 3 skills, validated against one authoritative surface-catalog.json. Codex behavior is locked by test/codex-native-golden.test.ts. Packaging via plugin:build:claude / plugin:release:claude:windows with a clean-room verify-claude-plugin-release.mjs. See docs/CLAUDE_INSTALLATION.md.
- Observation Window: Restart/reload the runtime, confirm migration
20260721-028-compaction-attribution(PostgreSQL) or20260721-027-sqlite-compaction-attribution, then run fresh sessions across at least two project folders. Audit must report attributed session coverage plus gross, injection-overhead, and net token totals.
- Phase L4+ typed DTO continuation:
checkpoint-store.ts,agent-work-journal.ts, andcontext-cache-runtime.ts.
no-explicit-anytyped-debt (Phase L4+ remaining): L4-A through L4-K reduced 102→7. Remaining 7 warnings are inopentui.d.ts(external API types, skipped by design). Future work: typed DTOs forcheckpoint-store.ts(row mapper),agent-work-journal.ts,context-cache-runtime.ts. Requires per-module typed DTOs and generic row mappers, not blanket replacement.no-consolecleanup (~8 warnings): Remainingeslint-disable-next-line no-consoleannotations in auto-docs.ts, system-transform.ts, work-journal-inject.ts. Blocked by need for logger context support or structural refactors.
- Plain
sessionStateobject (not getter-based wrappers) for mutable state shared across hook modules - Embedding similarity not useful for dedup at current scale — exact content detection catches all real duplication
- Merge is exact-match-only — no embedding-based merging; no deletion; mark superseded; preserve originals
any→unknownsubstitution is NOT safe at scale — requires per-file analysis and typed DTOs/generic mappers- Lint baseline locked at 7 — new warnings fail CI; existing debt is classified and documented
caughtErrorsIgnorePattern: '^_'allowscatch (_err)without warning- SQLite RETURNING and ON CONFLICT DO UPDATE work (SQLite 3.24+/3.35+ bundled with better-sqlite3)
- SQLite JSON ops:
json_type(col, '$.key')replacescol ? 'key';json_extract(col, '$.key')replacescol->>'key';json_each(col)replacescol && $N - SQLite empty-result security:
LOWER(col) LIKE LOWER($N)replacescol ILIKE $N - SQLite vector search: degraded to text search (no
<=>/pgvector equivalent) - PostgreSQL
CREATE UNIQUE INDEX IF NOT EXISTSdoes not upgrade existing non-unique indexes — must DROP INDEX IF EXISTS first (CSM #55513) - Capability ownership boundary (2026-07-11, CSM #68554): Self-model = authoritative live capability state. Belief knowledge = revisable claims/preferences/worldviews. Memories = evidence/provenance/lessons/snapshots — not competing live truth.
candidate_capabilityshould produce provenance records ("crossed threshold at time T"), not "succeeds reliably" assertions. - Promotion must not double-count evidence: experience packets already update self-model; promotion should change status/provenance/eligibility only, not confidence.
isJunkBelief()over-broad filter:subject.startsWith('tool:')discards both success AND failure tool beliefs. Should inspect polarity/specificity, not blanket-rejecttool:subjects.
- Observation window: Reload the updated runtime, verify the Phase 9C attribution migration, and run fresh-session/source-attribution tests across multiple project folders.
- Phase L4+: continue typed-DTO pass on
checkpoint-store.ts,agent-work-journal.ts,context-cache-runtime.ts - Fix remaining
no-consolewarnings (auto-docs.ts x3, system-transform.ts x3, work-journal-inject.ts x1) — convert to logger
- Windows/PowerShell environment:
grep→rg,wc→manual count,&&/||→PowerShell syntax - All checks green: typecheck, build, lint:src (0 errors, 7 warnings)
- Full test suite: 1551/1551 pass
git restore src/+git restore eslint.config.mjsrestores clean working tree- Live DB: 62,682 total memories; 38,000+ active; 7,500+ with embeddings
- Schema additions:
memory_mergestable,memories.superseded_by/superseded_at,memory_recall_events,context_injection_events,context_injection_items - SQLite schema: 7 tables, all indexed —
src/schema/sqlite/index.ts src/checkpoint-store.ts:rowToCheckpoint()usesrow: any— needs typed DTO (Phase L4 target)- Cold-start source attribution diagnostic in
src/hooks/system-transform.ts— distinguishes CSM sources from AGENTS.md
src/db/query-dialect.ts:QueryDialecttype + 11 dialect helpers — Phase 3Dsrc/db/database-pool.ts:DatabaseProvidertype,createDatabasePool()factory — Phase 3Bsrc/db/postgres-pool.ts: wrapspg.Pool→DatabasePoolsrc/db/sqlite-pool.ts:better-sqlite3adapter, param translation, cast strippingsrc/schema/sqlite/index.ts: 7-table SQLite DDL — Phase 3Csrc/schema/index.ts: dispatches to sqlite/postgres schema init based on providersrc/database.ts:Databaseclass withdialectgetter, factory dispatch,getProvider()methodsrc/memory-manager.ts: narrow-path methods dialect-aware — Phase 3Dsrc/hybrid-search.ts: hybrid search withbuildWhereClausefilter helper, dialect-aware sub-searchers — Phase 3F.3src/types.ts:DatabaseProvider,DatabasePool,DatabaseClient,PluginConfigsrc/config.ts:CSM_DATABASE_PROVIDER,CSM_SQLITE_PATHparsingeslint.config.mjs: ESLint v9 flat config,caughtErrorsIgnorePattern: '^_', src strict, tests relaxedpackage.json:max-warnings=7onlint:src
- 774+ errors, 261+ warnings across test files (
**/*.{test,spec}.ts) - Excluded from
lint:srcwithno-console: off,no-explicit-any: off,no-unused-vars: off
npm run lint:src: 0 errors, 7 warnings (all in opentui.d.ts, skipped by design) → exits 0npm run lint:all: ~774 errors + ~261 warnings across test files (excluded from lint:src)
- Goal: reduce
no-explicit-anywarnings module by module - Rule: no broad
anyreplacement; each PR must pass typecheck/build/tests/lint - Approach: (a) typed row-mapping DTOs for DB query results, (b)
eslint-disable-next-linewith documented rationale for interface-levelany, (c) targetedas unknown as Tonly where provably safe