docs: 1.0 documentation restructure
Split root CLAUDE.md into 19 per-directory files scoped to their source area. Roll v0 history into docs/ARCHIVE.md; retire CONTEXT.md, CONTEXT-ARCHIVE.md, PLAN.md, COMPLETED.md. Move plan docs under docs/. Rescue 9 live deferrals into docs/TODO.md.
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
# src/shell/persist — project ext-state persistence, prune filesystem I/O, usage scan
|
||||
|
||||
## Scope
|
||||
|
||||
The persist seam: project ext-state read/write (`session` / `ext_state_io`), the
|
||||
prune path's filesystem half (`prune_fs`), and the extension-side instance-usage
|
||||
scan (`usage_scan`) that feeds prune's referenced-set. Internal helpers shared only
|
||||
within the persist TU family live in `persist_internal.h`. The pure orphan
|
||||
computation is owned elsewhere (`core/reclaim`); the pure usage wire is owned
|
||||
elsewhere (`core/wire`) — this directory is the REAPER/filesystem-facing half only.
|
||||
|
||||
## Invariants
|
||||
|
||||
- **Prune is the single, exclusive file-deletion authority.** No bank op, no
|
||||
capture op, no Design View op deletes a file; if any path other than prune
|
||||
deletes a bank file, reject it in review.
|
||||
- **Dry-run first, always; no silent deletion.** Prune reports before it deletes
|
||||
(orphan count, reclaimed size, and — for a small set — the files); actual
|
||||
deletion is a confirmed second step. No periodic/background sweep.
|
||||
- **Referenced-set is the union across ALL banks, pool included**, further unioned
|
||||
(pS-usage) with every live instance's held paths via `usage_scan` →
|
||||
`prune_reconcile::mergeReferenced`. A file is an orphan iff no bank AND no live
|
||||
instance references it.
|
||||
- **Safest platform deletion available.** Trash-preferred, unlink fallback — Windows
|
||||
routes through `SHFileOperationW` (`FOF_ALLOWUNDO`, verified against SDK
|
||||
10.0.26100); macOS/Linux fall back to unlink (no portable SWELL trash surface).
|
||||
`prune_fs` is the only module that calls this.
|
||||
- **Manual, explicit trigger only** — a bindable action + a `bank_panel` button,
|
||||
never a silent background sweep.
|
||||
- **Instance-usage fail-safe (pS-usage):** a capture held by any live ReaSampler
|
||||
9000 instance can never be deleted by prune. If any `rsusage_*` record is
|
||||
unreadable or ambiguous, prune **aborts entirely and deletes nothing** —
|
||||
over-protection is the accepted residual, under-protection is a data-loss bug.
|
||||
`usage_scan` decodes every `rsusage_*` key, enumerates every ReaSampler 9000 FX
|
||||
instance (all tracks incl. master, normal + record/input chains, containers
|
||||
recursively, take FX), and folds via the pure `sample_usage::foldUsageRecords` /
|
||||
`usageHeldPaths` (a record with no live instance context protects all its paths —
|
||||
identity-failure net, never degrades toward delete). This is read-only at
|
||||
prune-scan time: `usage_scan` writes no ext-state.
|
||||
- **`PruneReport` carries `abortedUnreadableUsage` + `offendingUsageKeys`**; dry-run,
|
||||
orphan-set, and reclaim each independently abort (delete nothing) when usage
|
||||
state is unreadable. `BANK_PRUNE_FOLDER` (in `shell/actions`) halts on this flag
|
||||
and prints the offending keys.
|
||||
|
||||
## Modules
|
||||
|
||||
- `shell/persist` (`session` / `ext_state_io` / `prune_fs`) — the persist seam, split by responsibility (Q-W5; the former `persist.cpp` god-TU and its `persist.h` compatibility umbrella are both retired — callers include `shell/persist/session.h` / `ext_state_io.h` directly). `session` owns the `ReaSamplerSession` lifecycle: the poll identity-transition detection (load / Save-As / forked sibling / recycled pointer) and the `projectconfig`-driven deferred undo/redo reload. `ext_state_io` owns project ext state (`SetProjExtState`/`GetProjExtState`, namespace `"reasampler"`) ↔ `BankBook` JSON, `ViewModeModel` JSON, `TailSetting` JSON, `OwnedManifest` JSON, the writing-version stamp, GUID minting, and bank-folder relocation. `prune_fs` hosts the prune dry-run / full-set orphan queries (supplying `referencedPaths()` + `owned().paths()` to the `prune_reconcile` pure core) and is **the single file-deletion authority over user files in the bank folder** (`deleteOrphanFile` via `SHFileOperationW`); nothing else in the system deletes bank-folder bytes. **pS-usage:** the prune scan unions instance usage via `usage_scan`; `PruneReport` carries `abortedUnreadableUsage` + `offendingUsageKeys`; dry-run / orphan-set / reclaim each independently abort (delete nothing) when usage state is unreadable.
|
||||
- `usage_scan` — extension-side prune-scan shell (pS-usage): at prune-scan time, enumerates every `rsusage_*` ext-state key, decodes each `sample_usage` wire record, enumerates every ReaSampler 9000 FX instance across all tracks + master / normal + record chains / containers (recursive) / take FX, and folds with `sample_usage::foldUsageRecords` / `usageHeldPaths` to produce the set of held paths — or `abortPrune` when any record is unreadable (fail-safe: an unreadable record may protect anything, so the prune halts). Feeds `prune_reconcile::mergeReferenced`. Read-only: writes no ext-state.
|
||||
- `persist_internal.h` — internal-only shared helpers for the persist TU family (`session` / `ext_state_io` / `prune_fs`); included only by those three TUs, never a public seam (mirror of the panel's `panel_state.h` / the editor's `editor_internal.h` precedent). Holds the former anonymous-namespace helpers more than one split TU needs (active-project + `.rpp` path lookup, project-dir derivation, growing `GetProjExtState` read, project-GUID minting, bank-folder relocation) — all definitions live in `ext_state_io.cpp`. REAPER-free header: the project handle crosses this seam as the same opaque `void*` the public `session` header already uses.
|
||||
|
||||
## Gotchas
|
||||
|
||||
- The pure orphan computation (`prune_reconcile`, `(owned ∩ present) − referenced`)
|
||||
is documented under `core/reclaim`, not here — do not duplicate its spec in this
|
||||
file.
|
||||
- The pure usage wire (`sample_usage`: `UsageRecord`, `planUsagePublish`,
|
||||
`foldUsageRecords`/`usageHeldPaths`, `identityMatches`) is documented under
|
||||
`core/wire`, not here.
|
||||
- `persist_internal.h` is an internal seam, not a public header — do not include it
|
||||
outside `session.cpp` / `ext_state_io.cpp` / `prune_fs.cpp`.
|
||||
Reference in New Issue
Block a user