# Env-snapshot durability plan (Athenaeum commune forever-loop)

## Scope

Reported via doyle from Librarian@Athenaeum-Library: echo-commune fails **every turn**
(`ECHO_COMMUNE_FAIL: endpoint environment unavailable`, 3/3 strikes, forever-loop). Root cause
(doyle-confirmed adapter-owned; the path/string exist nowhere in core): omp-spt writes its
per-endpoint env snapshot to a **project-CWD-relative** `.spt/omp-spt-env-v1/<id>.json`, and on the
daemon-respawn path the CWD resolves under `/tmp`. systemd-tmpfiles reaps `/tmp` (~10d); on a
10-day-uptime node the snapshot is deleted and every later echo/Psyche turn fails.

- Writer: `launch_omp::run` passes `current_dir()` as the snapshot root (`launch_omp.rs:438,452`).
- Readers: `echo_commune`/`psyche`/`digest`/`history` pass `--project-dir {cwd}` → same volatile root.
- `project_root` is also reused for OMP's own launch cwd/identity env — must **not** move that;
  relocate only the snapshot.

## Decision

1. **Durable, cwd-independent snapshot root.** New `durable_snapshot_root()` resolves a per-user
   state dir from process env: `OMP_SPT_STATE_DIR` override → `%LOCALAPPDATA%\omp-spt` (Windows) →
   `$XDG_STATE_HOME/omp-spt` → `$HOME/.local/state/omp-spt`. Writer and all readers run as the same
   user, so both resolve the same root. Only the `run()` entry points switch to it; the core
   `write_snapshot`/`load_endpoint_env`/`locate_*` functions keep taking an explicit root, so the
   existing race-free explicit-path tests are unaffected. Do **not** use `XDG_RUNTIME_DIR` (per-login
   tmpfs, also volatile).
2. **Rebuild-on-missing self-heal.** When `load_endpoint_env` finds the snapshot file absent, it
   regenerates from the current process env (`SessionEnv::capture` + `resolve_omp`) and rewrites it,
   so a reaped snapshot degrades to regeneration instead of a permanent strike-loop.
3. Resolver is a **pure function of injected env** (`durable_snapshot_root_from`) so it is unit-
   testable without process-env races, matching the codebase style.

## Tasks

1. `REQ-HAZARD-DURABLE-STATE-NOT-TMP` in `traceable-reqs.toml` (doc/impl/unit) + KNOWN-HAZARDS entry
   (pairs with spt-core's docs-rider: adapter durable state must not live in `/tmp`).
2. `durable_snapshot_root` (+ pure `_from`) and rebuild-on-missing in `digest_omp.rs`; switch the
   five `run()` sites (launch/echo/psyche/digest/history) to the durable root, leaving OMP's cwd.
3. Tests: resolver precedence/fallbacks (pure), rebuild-on-missing regenerates a valid snapshot,
   existing snapshot round-trip/locate still green.
4. Version bump 0.3.22 across manifest/package/Cargo/docs; CHANGELOG; findings note.
5. Gates + drive release (same pipeline as 0.3.21).

## Gate

`cargo test` + `node --test` + `sh ci/run-gates.sh` + `traceable-reqs check` all green; new tests
fail before the fix and pass after; Librarian unblocked by the durable relocation on relaunch and by
self-heal on a future reap.
