packages/core/src/store/eventlog.ts:47-48 opens the SQLite database without forwarding opts.readonly, then unconditionally runs this.db.exec(SCHEMA_SQL) even when the caller asked for a read-only handle or passed in their own db. The documented intent at packages/core/src/store/types.ts:26-29 is that readonly: true opens the database in better-sqlite3's read-only mode (which is the standard way to share an event log file with another writer process — e.g. a sidecar admin tool). The current implementation either ignores the flag entirely or, if the underlying file is read-only on disk, fails at the exec with "attempt to write a readonly database". The same problem appears in packages/core/src/store/eventlog-service.ts:264 for the Effect twin, where there is no readonly option at all.
Fix prompt: in packages/core/src/store/eventlog.ts:47-48, pass { readonly: opts.readonly ?? false } to new Database(opts.path ?? ":memory:") when opts.db is not provided, and skip the this.db.exec(SCHEMA_SQL) call when opts.readonly === true or when the caller passed in opts.db (caller-provided database is the caller's responsibility to initialize). Mirror the same handling in packages/core/src/store/eventlog-service.ts by accepting readonly in EventLogServiceConfig and gating the db.exec(SCHEMA_SQL) call. Add a test that opens an in-memory writer EventLog, writes a batch of envelopes, closes it, reopens the file in read-only mode, queries successfully, and asserts that calling append rejects with a clear error (the better-sqlite3 readonly violation message wrapped in an ARCP error or a documented passthrough).
packages/core/src/store/eventlog.ts:47-48opens the SQLite database without forwardingopts.readonly, then unconditionally runsthis.db.exec(SCHEMA_SQL)even when the caller asked for a read-only handle or passed in their owndb. The documented intent atpackages/core/src/store/types.ts:26-29is thatreadonly: trueopens the database inbetter-sqlite3's read-only mode (which is the standard way to share an event log file with another writer process — e.g. a sidecar admin tool). The current implementation either ignores the flag entirely or, if the underlying file is read-only on disk, fails at theexecwith"attempt to write a readonly database". The same problem appears inpackages/core/src/store/eventlog-service.ts:264for the Effect twin, where there is noreadonlyoption at all.Fix prompt: in
packages/core/src/store/eventlog.ts:47-48, pass{ readonly: opts.readonly ?? false }tonew Database(opts.path ?? ":memory:")whenopts.dbis not provided, and skip thethis.db.exec(SCHEMA_SQL)call whenopts.readonly === trueor when the caller passed inopts.db(caller-provided database is the caller's responsibility to initialize). Mirror the same handling inpackages/core/src/store/eventlog-service.tsby acceptingreadonlyinEventLogServiceConfigand gating thedb.exec(SCHEMA_SQL)call. Add a test that opens an in-memory writer EventLog, writes a batch of envelopes, closes it, reopens the file in read-only mode, queries successfully, and asserts that callingappendrejects with a clear error (the better-sqlite3 readonly violation message wrapped in an ARCP error or a documented passthrough).