Skip to content

fix: SessionStart banner reliability on first session (busy_timeout + adaptive defer)#16

Merged
rumitvn merged 2 commits into
mainfrom
fix/session-banner-first-session-ordering
Jun 7, 2026
Merged

fix: SessionStart banner reliability on first session (busy_timeout + adaptive defer)#16
rumitvn merged 2 commits into
mainfrom
fix/session-banner-first-session-ordering

Conversation

@rumitvn

@rumitvn rumitvn commented Jun 7, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes the tre-mem SessionStart banner failing to show on a project's first
session
(reported alongside a "1 setup issue: MCP" warning). Two distinct root
causes, both fixed.

1. SQLITE_BUSY on the seeding first session (the "no banner + MCP issue")

On the first session of a project, three short-lived tre processes open
~/.tre-mem/tre-mem.db at the same time: the SessionStart hook (migrate +
branch_state write), the MCP server, and the autostarted web daemon (WAL
checkpoint). The sidecar DB opened with no busy_timeout, so SQLite returned
SQLITE_BUSY instantly instead of waiting:

  • the hook's write threw → caught → empty envelope → no banner
  • the MCP server failed to open → "1 setup issue: MCP"

Fix: set busy_timeout = 5000 on every connection (sidecar writer, migrate,
and the read-only claude-mem adapter). Proven directly: a write under a held lock
throws in 0 ms with busy_timeout=0 vs waiting ~339 ms with 300.

2. Banner ordering on the no-memory first session

The defer that makes tre-mem render below claude-mem was a fixed 250 ms — too
short for claude-mem's slower first-run onboarding banner, so tre-mem raced above
it. Now adaptive: 1200 ms on the first session, 250 ms once a project has
claude-mem memory, 0 on non-Claude harnesses / when claude-mem is absent.
TRE_MEM_HOOK_DELAY_MS overrides everything.

Changes

  • src/store/paths.tsDB_BUSY_TIMEOUT_MS = 5000
  • src/store/repo.ts, src/store/migrate.ts, src/adapter/claude-mem.ts
    apply the pragma; TreMemRepo.busyTimeoutMs() introspection accessor
  • src/hooks/defer.ts — pure, unit-tested sessionDeferMs (adaptive defer)
  • src/cli.ts — feed disk/DB probes into sessionDeferMs; claudeMemHasProject
  • CHANGELOG.md — Unreleased entry

Test plan

  • test/hook-defer.test.ts (6) + test/repo.test.ts busy_timeout regression
  • Full gate green: format:check, lint, typecheck, 403 tests, build
  • Reproduced at a real repo (onego-ios): hook fired under a held lock now
    waits and emits the banner; direct write-under-lock proof confirms the
    SQLITE_BUSY mechanism

v-rumnv added 2 commits June 7, 2026 19:53
The 250ms banner defer (so tre-mem renders below claude-mem) wasn't enough
on a project's first session: claude-mem's longer first-run onboarding banner
is slower to render, so tre-mem raced above it.

Make the defer adaptive: 1200ms when claude-mem has no memory for the project
yet, 250ms steady-state, 0 on non-Claude harnesses / when claude-mem is absent.
TRE_MEM_HOOK_DELAY_MS still overrides everything.

Extract the policy into a pure, unit-tested src/hooks/defer.ts (sessionDeferMs);
the CLI feeds it the disk/DB probes (claudeMemHasProject via listProjects).
…n SQLITE_BUSY

On a project's first (seeding) session the SessionStart hook, the MCP server, and
the background web daemon all open ~/.tre-mem/tre-mem.db at once. With no
busy_timeout, SQLite returned SQLITE_BUSY instantly: the hook's branch_state
write threw → empty envelope → no banner, and the MCP open failed → "1 setup
issue: MCP". Set busy_timeout=5000 on every connection (sidecar writer, migrate,
and the read-only claude-mem adapter) so they wait out the brief contention.

Adds TreMemRepo.busyTimeoutMs() introspection + a regression test.
@rumitvn rumitvn changed the title fix(cli): defer SessionStart banner longer on no-memory first session fix: SessionStart banner reliability on first session (busy_timeout + adaptive defer) Jun 7, 2026
@rumitvn rumitvn merged commit aaa5e92 into main Jun 7, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants