Skip to content

feat(doctor): loudly surface sustained vault-write failures (silent memory loss) #243

Description

@CryptoJones

Problem

A machine can silently stop WRITING memory and nothing tells anyone. On makemake, every vault write has failed since 2026-08-09 with append_entry(...): PermissionError(1, 'Operation not permitted') (macOS TCC blocking the hook's python3 from ~/Documents). The failures land as breadcrumbs in ~/.local/state/omind/hook-failures.log — which nobody reads — while sessions keep running, reading a vault that is quietly falling out of date. Later sessions then "don't remember" work that was in fact never saved.

The manual remediation on the Mac (grant Full Disk Access, or move the vault) is operator work and NOT part of this issue. This issue makes the failure impossible to miss.

What to change

1. Doctor check: sustained write-failure streak

  • Find the doctor implementation (grep -rn "def .*doctor\|doctor" src/omind/cli.py src/omind/*.py — likely in verify.py or its own module; read it first and follow its existing check pattern).
  • New check vault-writes: parse hooks.failure_log_path() (format: ISO_TIMESTAMP context: ExceptionRepr, one per line; the log restarts when it exceeds _FAILURE_LOG_CAP_BYTES — handle a mid-stream restart gracefully).
  • FAIL when ≥ 5 entries whose context starts with append_entry( occurred within the last 24 hours; WARN when 1–4. Report: count, first/last timestamp, the exception repr, and remediation hints — on macOS (sys.platform == "darwin") explicitly say: "Grant Full Disk Access to the python3 binary that runs omind hooks (System Settings → Privacy & Security → Full Disk Access), or move the vault outside /Documents//Desktop; then verify with omind doctor."
  • PASS must also verify writability directly: create+delete a temp file in the vault dir (O_EXCL, best-effort, never raise).

2. Capsule banner: surface it in-session

  • build_session_start_context in src/omind/hooks.py already assembles banners from _paused_gate_line() and _update_nudge_line() (~line 574). Add a third: if the streak check (factor the parser into a shared helper so doctor and this banner use ONE implementation) detects a FAIL-level streak, prepend:
    ⚠️ MEMORY WRITES ARE FAILING on this machine (N failures since <date>; last: <repr>). Nothing you save will persist until this is fixed — run 'omind doctor' and tell the operator NOW.
  • The banner path must be fast (< ~50 ms budget: read at most the last 64 KiB of the log) and never raise (wrap in _best_effort).

3. Docs

  • Add a short section to the doctor doc (find it: grep -rln doctor docs) describing the check, the macOS TCC cause, and both remediations.

Acceptance criteria

  • Unit tests: streak parser (5+ recent → FAIL, old entries ignored, mixed contexts filtered, restarted/garbage log tolerated); doctor check output includes macOS hint on darwin (monkeypatch sys.platform).
  • Unit test: capsule contains the banner when a FAIL streak exists, and not otherwise.
  • Doctor on a healthy vault: check passes and leaves no residue file.
  • Full local test suite passes before committing (standing rule).

Out of scope

  • Actually granting Full Disk Access on makemake (operator task, tracked outside the repo).
  • Alerting/mesh propagation of the failure state.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions