test(cold-start): hermetic SessionStart banner — kill live-env dependency (#174 follow-up)#183
Merged
Merged
Conversation
…ependency (#174) test_normal_session_with_memories ran session_start.py as a subprocess under the inherited real environment: the SessionStart backend gate read the developer's live backend marker (~/.claude/methodology/backend.json), the banner then read the real ~/.claude/methodology/memory.db (or a live PostgreSQL), and the subprocess additionally spawned detached consolidate/reanalyze workers against the real HOME and repo. The in-process `remember` seed landed in the per-process test DB while the subprocess read a *different* live store, so the assertion outcome depended on whose machine ran it (it failed on this developer's machine, passed on an empty CI home). The raw `UPDATE ... NOW()` seed is also PostgreSQL-only, silently mismatched under the SQLite default. Rewritten to the canonical hermetic pattern already used by tests_py/hooks/test_sqlite_hook_paths.py: seed an ephemeral SqliteMemoryStore in tmp_path and drive the SQLite banner path (_sqlite_context) in-process via a monkeypatched get_shared_store, asserting the seeded memory is injected and no PostgreSQL install guidance leaks. Same behavior verified (DB has memories -> banner injected, not cold start), now deterministic and environment-independent. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Owner
Author
Full-suite proof (this machine, live
|
This was referenced Jul 25, 2026
Closed
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #174 / #180 (merged). The first full-suite run after #180 surfaced two more failures in the same test-isolation family; this PR fixes the one that is a genuine test defect.
test_cold_start.py::test_normal_session_with_memories— live-environment dependencyRoot cause: the test ran
session_start.pyas a subprocess under the inherited real environment. The SessionStart backend gate reads the developer's live backend marker (~/.claude/methodology/backend.json); the banner then reads the real~/.claude/methodology/memory.db(or a live PostgreSQL); and the subprocess additionally spawned detached consolidate/reanalyze workers against the real HOME and repo. The in-processrememberseed landed in the per-process test DB while the subprocess read a different live store — so the assertion outcome depended on whose machine ran it (failed on this developer's populated home, passed on an empty CI home). The seed's rawUPDATE ... NOW()is also PostgreSQL-only, silently mismatched under the SQLite default.Fix (test-side — the SQLite banner path itself is already proven correct by
tests_py/hooks/test_sqlite_hook_paths.py): rewritten to the canonical hermetic pattern — seed an ephemeralSqliteMemoryStoreintmp_pathand drive_sqlite_contextin-process via a monkeypatchedget_shared_store, asserting the seeded memory is injected and no PostgreSQL install guidance leaks. Deterministic and environment-independent; same behavior verified (DB has memories -> banner injected, not cold start).The second failure —
test_I2_no_unauthorized_heat_writes— is NOT a code defecttest_I2is a stateless static source scan (rglob mcp_server/**/*.py, compareSET heat_basesites to a line-pinned allow-list). It holds no runtime state, so it cannot carry hidden shared state between tests. Its one observed failure occurred in a working tree a second concurrent agent was actively mutating (running its ownpytest tests_py/and editingtest_I2+pg_store.py/sqlite_store.pyon another branch in the same checkout); agit checkout/edit landing mid-run shifts the pinned offsets so the scan reads source that no longer matches the allow-list. It passes standalone and in every controlled/isolated run — no code change is warranted (hardening the scan against a concurrently-mutated tree would only weaken the invariant it guards).Gates:
ruff check+ruff format --checkpass. Full suite verified green in an isolated worktree (own source via PYTHONPATH, own throwaway DB via conftest), immune to the concurrent agent's mutations.🤖 Generated with Claude Code