`openDatabase` opens provider databases with `readOnly: true`, which is not
enough for a WAL-mode database: SQLite has to create `<db>-shm` and an empty
`<db>-wal` in the database's own directory unless they already exist. Two
things follow, and both are real.
The open writes. On a writable directory it succeeds and leaves two files
behind in the user's provider directory, which is not what "CodeBurn only reads
your session logs" implies.
On a non-writable parent it fails outright with "attempt to write a readonly
database". It is conditional on -shm being absent, which is exactly the state
after the tool exits cleanly, so the symptom is intermittent: a provider's
spend disappears whenever that tool is not running. Both discovery sites
swallowed it with a bare `catch { continue }`, so the provider reported zero
sessions with nothing on stderr - indistinguishable from the tool not being
installed. It covers cursor, cursor-agent, opencode, goose, warp, kilo-code,
zerostack and the copilot agent-traces DB.
The direct open stays the fast path and is unchanged when it succeeds: no stat,
no permission probe. Only when SQLite reports SQLITE_READONLY does the fallback
run, copying the database and its -wal/-shm siblings into the CodeBurn cache
directory and opening the copy there. The copy is fingerprinted the same way
session-cache fingerprints a SQLite source, so an unchanged database is not
copied twice, and there is one bounded entry per source path.
The discovery sites now tell SQLITE_READONLY apart from ENOENT and emit one
notice per source path rather than per session, matching what the parse-time
paths already do.
This is not specific to any one sandbox: it applies to a database on read-only
media, a restrictive-permissions setup, and both the Flatpak and snap
confinements. The snap was narrowed to a read-only personal-files plug in #978
and is likely affected; I have no snap install to confirm that on.