mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-10-20 05:49:37 +08:00
Nondeterministic Windows reds came from races on _config.db:
test-windows-guards section_start_status_port / daemon_lifecycle ("the
daemon did not accept the UI configuration"), section_churn_stability
("could not load saved runtime settings"), the windows-2025 release
smoke whose `--ui=true --port` server exited about 5 s after start
(Phase 15, read as "no embedded UI assets"), and section_crash_recovery
("the stale daemon state never cleared").
- Every _config.db connection now waits out a committing writer
(cbm_runtime_settings_wait_for_writers: one busy handler, logs
config_db.busy_wait once per busy wait, a 3 s bound for a wedged
holder). Startup's 50 ms window let a daemon's routine commit end
unrelated CLI starts; cbm_config_open and the UI load had no wait at
all, so a concurrent commit failed the daemon's UI save and made the
load keep defaults.
- A process killed mid-write (crash, taskkill /F, power loss) left a hot
rollback journal that the read-only settings reads cannot roll back
(SQLITE_READONLY_ROLLBACK). Every later command then failed with
"could not load saved runtime settings", permanently. Settings startup
and the UI load now recover once through a read-write open that rolls
the interrupted write back (config_db.hot_journal_recovered); a failed
recovery is reported with the journal path and stays fatal.
- write_value no longer rewrites an unchanged value. The upsert fired the
revision trigger, so every `daemon start` on a UI build committed and
locked readers out although nothing changed.
- `daemon start` and the stdio server wait for the set_context and
set_ui_config replies within their startup budget instead of the 1 s
probe budget (MAIN_CONNECT_TIMEOUT_MS) that decided the command
whenever the daemon's save ran long.
Tests, red on 8df0639c and green here:
- runtime_settings suite: three single-threaded lock tests (a log sink
commits the held lock when the waiter logs config_db.busy_wait, so no
test depends on a duration) and two hot-journal tests (a portable
fixture snapshots the database and its journal mid-transaction and
checks the journal is hot before the code under test runs).
- tests/windows/test_daemon_stability.py: new section
start_port_waits_for_settings_writer holds the lock against a real
`daemon start --port` and releases it on events; the crash section
now prints the status output it saw.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>