The one stash for everything smine removes or replaces.
Every writer deleting or overwriting a file it does not own outright calls its *trash.Store (internal/trash) before the destructive step.
Under the state dir ~/.claude/smine:
| Path | Holds |
|---|---|
| trash/<stamp>/<rel> | The stashed file or dir; <rel> is the original absolute path minus volume and leading separator (C:\Users\k → C/Users/k). |
| owned/<rel>.sha256 | Hex sha256 of the bytes smine last wrote there, plus a newline. |
| journal.jsonl | One line per event: {time, action, kind, path, reason?, stash?} |
Stamp: UTC time, RFC 3339 shape with nanoseconds, - for the time's colons (NTFS refuses a colon in a file name). Two stashes in one nanosecond share a stamp dir.
2026-10-17T13-07-01.000000000Z
| Call | Does |
|---|---|
| Move | Renames a file or dir into the stash; across devices, copies then removes. |
| Keep | Copies the current bytes before the caller overwrites them. |
| Note | Journals a fileless event: a forgotten row, a deleted branch. |
| Restore | Target derived from the stash path alone. A present target is refused unless replacing, which stashes it first. An emptied stamp dir is removed. |
| IsUnchanged | "Did smine write these bytes", from the owned digest; no record means no. |
| HasMarker, MarkerLine, StripMarker | Read and write the # smine-deployed <sha256> line, the ownership proof of hook scripts and agent files. |
| nil store | Keeps and journals nothing; passed by a caller writing its own scratch file. |
The retention sweep is the trash's only deletion: with config-server.trash_retention_days above 0, every stash and server boot remove stamp dirs older than that many days. The journal is never truncated.