# Offline notes: operation and recovery

## Supported deployment

Run one Node 24 process on the operator's computer, bound to loopback. The browser and the API share the localhost origin. SQLite lives on the same local filesystem. The packaged tokens and visits are synthetic. This configuration is usable for a local demonstration and for reproducing the service behavior; it does not grant other computers access.

```sh
node server.mjs
```

A managed service can run that same command under a dedicated OS account with a private data directory. The account needs write access only to its data and backup directories. Its working directory is this extracted project. Set `NOTES_DB` to an absolute database path. Stop with SIGTERM for a normal shutdown. Restart with the same path to retain visits, operation responses and token expiry. Restarting does not renew an expired demo identity.

## Snapshot and recovery commands

The snapshot command uses SQLite's online backup API, verifies database integrity and foreign keys, and writes a SHA-256 manifest. It refuses an existing destination. The parent directory must exist.

```sh
node snapshot.mjs data/notes.sqlite backup-20261027-1200
node restore.mjs backup-20261027-1200 restored-20261027
NOTES_DB=restored-20261027/notes.sqlite node server.mjs
```

Stop the original server before starting the restored instance on the same port. The original database and snapshot remain unchanged. Verify the manifest, assigned visit count, a known version and an idempotent operation retry before using a restored copy. The restore command performs checksum, integrity, foreign-key and row-count checks itself. Token expiration timestamps are preserved. Browser operations newer than the snapshot may conflict and must go through the application's normal review screen.

Use a fresh destination for every snapshot. A 15-minute snapshot interval is the selected theoretical recovery policy; retain a separate offline copy after verifying it. The model uses a five-minute restore and three-minute reconciliation allowance. These timings are declared planning inputs, not measured service guarantees. An old daily snapshot fails the model's 15-minute data-loss target. Browser-only drafts are outside a server snapshot, so export local records before clearing a browser profile.

## Executed incident runs

`node complete.mjs` executes the worker cache simulation, process operations drill, snapshot CLI checks and deployment calculation. It writes `completion.json`, `completion-report.html` and the individual JSON records under `results/`.

The real HTTP run commits 100 notes, submits 20 concurrent edits against one base version, kills the process after an acknowledged write, restarts, replays an operation, takes a live snapshot and restores it. Exactly one concurrent write is accepted; the other 19 retain explicit conflict responses. The snapshot contains its 121 recorded operation outcomes. Later writes are intentionally outside that snapshot.

The actual service-worker script runs with a modeled lifecycle, cache and network. It installs its eight shell assets atomically, rejects a missing asset, retires only old caches for its own scope, serves a cached page during connection loss or HTTP 503, bypasses authenticated API requests, and gives a visible error if its cache was evicted. This closes the offline-reload scenario computationally. It is separate from the existing real Chrome IndexedDB/save/sync/conflict observation.

## Remote deployment run-through

`deployment-inputs.json` contains the selected workload and recovery assumptions. `node deployment-model.mjs` executes the following decisions:

- Seven offline days at 20 visits/day, 12,000-byte notes and six retained operations/visit require 11.76 MB before IndexedDB overhead. The selected planning budget is 16 MiB; the tenfold workload is rejected. This is a capacity estimate, not a browser quota guarantee.
- The 15-minute snapshot and eight-minute restore/reconciliation model meet the selected recovery targets. A daily snapshot and a 33-minute recovery do not.
- A series combination of assumed network, gateway and host availability is below 99.9%. The single-host design makes no high-availability claim.
- The hypothetical remote configuration requires TLS and a real identity provider and refuses public fixture identities. The shipped application intentionally accepts only localhost; no public listener, remote identity or certificate was installed.

A remote variant would replace the demo-token mapping with server-verified identity and visit assignment, maintain a private data plane, terminate TLS, and configure off-host backups. The calculation completes the deployment assessment; it is not evidence that those services are live. This avoids treating a local demonstration as an internet service.

## Incident decisions

| Observation | Action and preserved evidence |
| --- | --- |
| Connection fails | Keep the draft and operation ID. Retry after connection returns. |
| 401 or 403 | Preserve the local record, correct identity or assignment, then retry. |
| Version conflict | Review both versions. The discarded local draft remains in exported history. |
| Cache evicted | Reconnect and reload shell assets. IndexedDB records are a separate store, but can also be evicted. |
| Database corruption | Stop writes, preserve the damaged files, restore a verified snapshot to a new directory. |
| Suspicious export or snapshot | Verify source and checksum. A checksum detects byte changes; it does not authenticate the author. |

The package contains no production customer data or credentials. Process-kill runs do not certify behavior under physical disk or power failure.
