Prevent EventStore read verbs from creating events.db-wal/events.db-shm sidecars - #80
Conversation
events.db-wal/events.db-shm sidecars
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 160b331e71
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| def _readonly_query(path: Path) -> str: | ||
| """Avoid creating sidecars on clean stores while preserving crash-left WAL reads.""" | ||
| return "mode=ro" if (path.parent / (path.name + "-wal")).exists() else "mode=ro&immutable=1" |
There was a problem hiding this comment.
Recheck the WAL before trusting an immutable snapshot
When a writer starts an append after this exists() check returns false but before sqlite3.connect() opens the database, the URI remains immutable=1; SQLite then ignores the newly created WAL and its committed frames. Running status, replay, or doctor concurrently with an active loop can consequently report a stale event count or a false state divergence, so the WAL selection needs an atomic/retry check around opening the immutable connection.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Pull request overview
This pull request updates Loop’s read-only runtime/doctor surfaces to open the SQLite EventStore in a way that avoids creating events.db-wal/events.db-shm sidecars on clean stores, preserving filesystem immutability for status, replay, and doctor’s consistency checks.
Changes:
- Added a WAL-aware
_readonly_query()helper inloop/runtime.pyto choosemode=ro&immutable=1when no WAL sidecar exists, otherwise fall back tomode=ro. - Updated runtime read paths (run-id discovery and event-row reads) to use the same WAL-aware read-only URI selection.
- Strengthened regression tests to detect newly created
.loopfiles after status/replay and to assert doctor reads do not leave WAL/SHM sidecars behind.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| scripts/test_loop_cli_status_replay.py | Makes the no-write regression test detect newly created .loop files by re-snapshotting the directory after status/replay. |
| scripts/test_doctor_eventstore.py | Adds a doctor regression asserting EventStore-backed reads do not leave WAL/SHM sidecars behind. |
| loop/runtime.py | Introduces WAL-aware read-only SQLite URI selection and applies it to runtime EventStore reads. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Heads up — separate from the WAL/immutable race the Codex review flagged, I think there's a second issue: this closes the sidecar leak only on clean stores, and the new test may be masking the other half. The Reproduced (crash-left state on disk = The added test A few directions that would actually close it: checkpoint-on-open under a controlled recovery; validate the WAL then reopen with Happy to share the exact repro script if useful. — flagged via Coretexa (adversarial PR verification) |
status,replay, and doctor’s EventStore consistency reads were logically read-only but still reopening SQLite in a way that recreated WAL sidecars, breaking tree-byte-identity checks on store-backed workspaces. This change aligns runtime read semantics with the existing WAL-aware projection path so read verbs remain non-mutating at the filesystem level on clean stores.Runtime read URI selection (WAL-aware)
mode=ro&immutable=1when noevents.db-walexists (prevents sidecar creation).mode=rowhenevents.db-walexists (preserves crash-left WAL replay behavior).Apply fix across runtime read surfaces
loop/runtime.pyto use the same WAL-aware query logic.status,replay, and doctor’s event consistency path (which composes those runtime reads).Regression coverage for sidecar cleanliness
.loopfile set before/after reads.events.db-wal/events.db-shmare left behind after EventStore-backed doctor reads.