Add pet-life: the permadeath mechanic and the cemetery !27

merged merged by cmc on 2026-09-04 17:20 UTC · krz/ambient-companions:feat/pet-life into main

cmc

Second of the menubar-pet stack.

Everything derives from timestamps: death occurs at last_activity + 7 days, not when observed, so sleep, reboots, daemon restarts and the app not running are irrelevant by construction. Tests cover every stage boundary, that a 60-day absence yields exactly one grave rather than a chain of eight, that rebirth requires activity, and that a persisted timestamp outranks a pruned history.

Deviates from the design on one point. State is a line-based pet.state, not pet.json. Only this crate reads it, so hand-rolling a JSON parser would have been all risk and no benefit — the terminal spool already stores plain whitespace-separated records for the same reason. JSON is still the contract handed to the app; that direction only needs emitting, and it is pinned to exact bytes.

Verified live: against the running daemon it reports a pet born from the real activity timestamp, writes its state, and is stable across runs.

Closes #17