fix(lcm)!: store LCM sessions under their store scope - #2864
Conversation
BREAKING CHANGE: LCM schema 14. Session stores written by earlier versions hold LCM-created session rows with an invented project and report reset-required.
ensure_session lost its last external caller when session rows started taking their store scope; only compression may insert them. The rebind test now runs LCM compression without a wall-clock deadline. Co-authored-by: Zack Jackson <ScriptedAlchemy@users.noreply.github.com>
LCM refuses to write session rows into a store whose shard holds no sessions; this pins that only profile and project session shards resolve a scope. Co-authored-by: Zack Jackson <ScriptedAlchemy@users.noreply.github.com>
Co-authored-by: Zack Jackson <ScriptedAlchemy@users.noreply.github.com>
…-store-scope-14ec Co-authored-by: Zack Jackson <ScriptedAlchemy@users.noreply.github.com>
|
LCM never observes when a host session starts. Writing unixepoch() into the row it inserts let that insert time win the min() in session reconcile, so a rollout that started later reported the LCM compression time as its start. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Master pins shipped LCM v13 profiles as admissible (cf4b1a2), so the 13->14 bump would force a reset on every shipped store. Keep v13 and keep replacing the invented-project shells those stores still hold; new LCM rows already carry their store scope.
|
Resolved the blocker above with option 1 in fab4913 (after merging current master in f5e8b93): LCM stays at schema 13, so shipped v13 profiles stay admissible (master's |
There was a problem hiding this comment.
Devin Review found 1 new potential issue.
🐛 1 issue in files not directly in the diff
🐛 Legacy LCM sessions remain under invented projects
Admitting version-13 stores leaves LCM-only sessions under unknown or lcm-active-context. ensure_session never updates existing rows, and reconciliation runs only when an observation arrives. Project-scoped session reads cannot find those sessions.
This reverts commit fab4913.
LCM schema 14 replaces the shipped-v13 admission guarantee: a store at the shipped v13 marker is refused with the typed LCM reset (found 13, required 14), listed in reset_required_stores, and recreated empty by the scoped reset. The unit test that pinned v13 as admissible now pins the refusal; the transport acceptance case ages both session stores to 13 and proves refusal, scoped reset, and serving afterwards. BREAKING CHANGE: session stores at LCM schema 13 (every profile written since v1.0.0-beta.50) refuse session features until `tracedecay wipe --stale --yes` resets exactly those session stores.
Summary
project_id/project_idfor a project session store,user/userfor the profile session store) instead of an inventedunknownproject. The rollout projection's working directory then only refinesproject_path.LCM_UNKNOWN_PROJECT_KEY,LCM_LEGACY_PLACEHOLDER_PROJECT_KEY, andlcm_unscoped_session_project. A scope-shaped row merges through the ordinary reconcile rules.shipped_v13_profile_remains_admissible_for_projector_rebuild, cf4b1a2) is a compatibility promise the project no longer makes. A shipped v13 session store can hold LCM rows with the invented project; it is refused typed, listed inreset_required_stores, and recreated empty by the scopedtracedecay wipe --stale --yes(same shape as the session-temporal v6→v7 bump in perf(sessions)!: extend session generations, don't copy them #2761). No migration, no legacy-row repair.Changes
tracedecay-store:session_project_fields(scope)is the one scope →(project_key, project_path)authority;StoreShardScopeV1::session_scope()names the scope of a shard's sessions (Nonefor non-session shards).tracedecay-lcm:compress,compress_retained_page,record_session_boundarytake the store'sObservationScopeV1;ensure_sessionis private and leavesstarted_atunset; newLcmError::NotASessionStore(not_a_session_store, non-retryable);LCM_SCHEMA_VERSION = 14.tracedecay-sessions/tracedecay-global-db:SessionStoreAccess::lcm_session_scope()resolves the scope from the registered binding and refuses non-session stores before a write transaction; reconcile's placeholder early return is removed.schema::tests::shipped_v13_profile_remains_admissible_for_projector_rebuildis replaced byshipped_v13_profile_refuses_typed_without_upgrading(v13 marker →ProfileResetRequired { found_version: Some(13), required_version: 14 }from admission and fromensure_lcm_schema, marker left at 13). The transport acceptance case is nowsession_stores_at_shipped_lcm_schema_13_refuse_sessions_only_until_their_scoped_reset: a real daemon over a profile whose project and profile session stores are aged to 13 keeps serving code, refuses session reads typed with thewipe --stale --yesremedy, doctor counts both as pending operator actions, the scoped reset deletes exactly those two stores (every other profile file byte-identical), and the restarted daemon serves sessions with an empty census.Fail before / pass after
cargo test -p tracedecay-lcm --lib -- schema::tests::shipped_v13withLCM_SCHEMA_VERSIONset back to master's 13: FAILEDa shipped v13 store must refuse admission: Current. With 14: ok.session_project_rebind_tests::lcm_compression_before_the_rollout_stores_the_session_under_its_store_scopefails on master (row stored as("unknown", "unknown")), passes here;a_rollout_starting_after_lcm_compression_keeps_its_own_start_timefails without thestarted_atfix.Runtime proof (debug
tracedecaybuilt from this branch, isolatedHOME/TRACEDECAY_DATA_DIR, daemon undersystemd-run --user --scope -p MemoryMax=6G)Verification (local; CI not consulted)
cargo test -p tracedecay-store -p tracedecay-lcm -p tracedecay-sessions -p tracedecay-session-runtime -p tracedecay-global-db(test-helpers): global_db lib 389, registered_schema_fail_closed 1, session_relation_graph 8; lcm lib 166 (2 ignored, as on master), lcm_suite 15; session_runtime lib 129, session_store_read_cost 7; sessions lib 539; store lib 73, store_suite 52; hotpath_coverage 1 each.cargo test -p tracedecay --features test-transport,test-helpers:session_suite437 passed; fullmcp_suite617 passed;transport_acceptance_suite -- stale_sessions_store_reset6 passed (re-run on the final merged tip).cargo clippy -p tracedecay-store -p tracedecay-lcm -p tracedecay-sessions -p tracedecay-session-runtime -p tracedecay-global-db -p tracedecay --all-targets(test features)-D warnings: clean.cargo fmt --all -- --check: clean.cargo check --workspace --all-targets --target x86_64-pc-windows-gnu --features tracedecay/test-transport,tracedecay/test-helpers,tracedecay-cli/test-transport: exit 0.NotASessionStoremaps to existingfailed/unavailablestates);@tracedecay/sdkunchanged, the refusal surfaces as the existingreset_requiredproblem.BREAKING CHANGE: LCM schema 14. Session stores at LCM schema 13 (every profile written since v1.0.0-beta.50) refuse session features as reset-required for the LCM component (found 13, required 14) until
tracedecay wipe --stale --yesresets exactly those session stores; code intelligence keeps serving meanwhile. LCM-created sessions now carry their store's project or profile scope instead of an inventedunknownproject.