Skip to content

db-backed SQLite containers re-sync every interval on their own -shm writes #1583

Description

@dqtz5vpvj9-create

agentsview version

main at f64e22e (v0.42.0 era); not reproducible on v0.41.1 commit 55646d6 from 2026-08-22.

Install method

Built from source

OS / platform

Linux x86_64 (Debian-based)

Which agent and version

zcode CLI (db-backed provider, ~/.zcode/cli/db/db.sqlite); goose shares the same dbBackedSourceSet

Which model(s)

Not applicable

What happened, and what did you expect

What happened

After upgrading a daemon to current main, the watcher fired every five seconds with "1 file(s) changed" and each cycle rewrote all 22 zcode sessions (sync: 22 file(s) updated), although db.sqlite and db.sqlite-wal had not changed for over half an hour and no zcode process was running. The only file moving was db.sqlite-shm, whose mtime advanced by exactly one dispatch interval each cycle.

The loop is self-inflicted. Opening a WAL-mode database as a reader rewrites its -shm index. dbBackedSourceSet.dbPathForEvent resolves a bare -shm event to the whole container, and zcodeSessionFileMtime folds the -shm mtime into every member's fingerprint. So the sync opens the database, the watcher sees the -shm write, every fingerprint moves, every member is rewritten, and the next interval repeats it.

Downstream, the archive never held still: usage cache backfill could not stabilize after 3 attempts on every start, and /api/v1/usage/summary returned 500 with "usage cache source archive changed during rollup build" continuously.

Omnigent and Cursor IDE already guard against exactly this through rejectShmSiblingEvents in classifySQLiteContainerPath; the db-backed providers do not.

Expected behavior

A bare -shm event should not resolve to a db-backed container, and the -shm mtime should not participate in the zcode fingerprint. Real writes always land in the main file or the -wal sibling, which should keep triggering syncs as before.

Sample session file or snippet

19:43:00 watcher: 1 file(s) changed, triggering sync
19:43:01 sync: 22 file(s) updated
19:43:05 watcher: 1 file(s) changed, triggering sync
19:43:06 sync: 22 file(s) updated
...
db.sqlite      mtime 19:16:54   (unchanged)
db.sqlite-wal  mtime 19:16:54   (unchanged)
db.sqlite-shm  mtime 19:45:25 -> 19:45:30 -> ...  (advances every cycle)

Steps to reproduce

  1. Have a zcode (or goose) database with several sessions under its default root, with the CLI not running.
  2. Start agentsview serve from current main and watch the log.
  3. Observe a sync every dispatch interval that rewrites every session in the container, and stat showing only db.sqlite-shm changing.

Fix in #1580.

Checklist

  • I searched existing issues
  • I removed secrets and private data from any attached session files

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions