# SQLite Driver Recovery

CTM stores its local state in SQLite, but Node accesses that file through the
native `better-sqlite3` addon. These are separate failure domains:

- SQLite database integrity failures mean the DB file or WAL family may be
  structurally damaged.
- `better-sqlite3` native load failures mean Node cannot load the addon for the
  current runtime ABI or platform. The DB file may still be healthy.

CTM must never archive, restore, or replace `task-manager.db` because the native
driver failed to load.

## Startup Order

1. Load `better-sqlite3`.
2. Instantiate an in-memory database with `new Database(':memory:')`.
3. Run `PRAGMA quick_check` on the in-memory DB.
4. If the driver fails with an ABI/load/missing-module error, run automatic
   repair before opening `task-manager.db`.
5. Only after the driver is healthy, open the CTM DB read-only and run
   `PRAGMA quick_check`.
6. Archive the DB family only for classified structural SQLite corruption.

This order prevents a native addon crash from being treated as a corrupt CTM
database.

## Automatic Repair

When CTM sees `driver_native_load_error` or `driver_missing`, it attempts:

1. `npm rebuild better-sqlite3`
2. `npm install better-sqlite3@<package.json dependency range> --no-audit --no-fund`
3. `npm install better-sqlite3@latest --no-audit --no-fund`

The commands run from `claude-task-manager/` using the same Node process that is
starting CTM. After each successful command CTM clears the Node require cache and
re-runs the in-memory smoke test.

The repair path records JSONL events in:

```text
${CTM_DATA_DIR:-~/.walle/data}/sqlite-driver-repair.jsonl
```

Each event includes the Node executable path, Node version, Node module ABI, the
repair action, and the result. This log is intentionally outside SQLite so it is
available even when the driver is unavailable.

## Failure Handling

If automatic repair fails, CTM exits with `CTM_SQLITE_DRIVER_UNAVAILABLE` and
leaves `task-manager.db`, `task-manager.db-wal`, and `task-manager.db-shm`
untouched.

If the DB opens but `PRAGMA quick_check` reports structural corruption, CTM may
archive the DB family and restore the latest healthy backup.

If the DB cannot be opened due to path, permission, cloud FileProvider, or
transient I/O errors, CTM fails closed and logs the classification. It does not
archive user data.

## Operator Controls

- `CTM_SQLITE_AUTO_REPAIR=0` disables automatic rebuild/install.
- `CTM_SQLITE_ALLOW_MAJOR_UPGRADE=0` disables the final `@latest` repair step.
- `CTM_SQLITE_REPAIR_TIMEOUT_MS=<ms>` changes the npm command timeout.
- `node bin/check-sqlite-driver.js` runs the same driver preflight and repair
  outside server startup.
- `bin/restart-ctm.sh` runs the preflight when the API is unreachable before it
  asks launchd to restart CTM.

## Regression Coverage

`tests/db-hardening.test.js` verifies:

- ABI/native load errors classify as driver failures, not DB corruption.
- the self-repair path retries the driver after a rebuild/upgrade step.
- CTM does not create `.corrupt-*` archives when the driver cannot load.
- true SQLite structural corruption still follows the quarantine/backup flow.
