The phenotype: public read-only web surface + pod-local API + SQLite.
node:http and node:sqlite only; zero runtime npm dependencies. A new
runtime import from node_modules here is a defect.
All SQLite and cold archive work lives in the worker thread
(worker.ts/ops.ts); the main thread owns HTTP, readiness, and SSE.
Never call SQLite from request handlers on the main thread.
The service is the only SQLite writer. Ingestion is idempotent (unique ids);
acknowledged writes are durable (synchronous=FULL).
Archive segments are immutable, versioned, zstd JSONL with sidecar indexes.
Retention: audit 90 days hot, chat 1 year hot, then moved exactly once.
Public routes stay read-only and bounded; auth is enforced at the reverse
proxy. The internal listener binds pod loopback only.
Logs are structured JSON and must never contain secrets, chat bodies, or
raw tool output.
Testing: unit tests for pure policy; integration tests spin real listeners
and a worker on tmpdirs (*.int.test.ts). SSE tests must cover replay via
Last-Event-ID.
# AGENTS.md — src/service
The phenotype: public read-only web surface + pod-local API + SQLite.
- `node:http` and `node:sqlite` only; **zero runtime npm dependencies**. A new
runtime import from node_modules here is a defect.
- All SQLite and cold archive work lives in the worker thread
(`worker.ts`/`ops.ts`); the main thread owns HTTP, readiness, and SSE.
Never call SQLite from request handlers on the main thread.
- The service is the only SQLite writer. Ingestion is idempotent (unique ids);
acknowledged writes are durable (`synchronous=FULL`).
- Archive segments are immutable, versioned, zstd JSONL with sidecar indexes.
Retention: audit 90 days hot, chat 1 year hot, then moved exactly once.
- Public routes stay read-only and bounded; auth is enforced at the reverse
proxy. The internal listener binds pod loopback only.
- Logs are structured JSON and must never contain secrets, chat bodies, or
raw tool output.
- Testing: unit tests for pure policy; integration tests spin real listeners
and a worker on tmpdirs (`*.int.test.ts`). SSE tests must cover replay via
Last-Event-ID.