tracking: one ledger, one authority — prune protection and replace-vs-add answered from the same records, fail-safe on unreadable state
This commit is contained in:
+13
-9
@@ -58,7 +58,10 @@ This directory owns two cross-artifact contracts specifically:
|
||||
delete). The guarantee: a capture held by any live instance can never be deleted; if
|
||||
the prune cannot determine with certainty which captures are held, it aborts
|
||||
entirely (deletes nothing). Over-protection is the accepted residual; under-protection
|
||||
is a data-loss bug.
|
||||
is a data-loss bug. The fold reports `counted` — the live records still attributed to
|
||||
their `rsusage_*` keys — because the flattened path list cannot answer "who holds
|
||||
this"; `counted` is empty whenever `abortPrune` is set, since attribution is exactly
|
||||
what an unreadable record destroys.
|
||||
- **Collision safety (`planUsagePublish`).** A persisted GUID is copyable (FX copy /
|
||||
track duplication). `ownerNonce` — a per-lifetime nonce minted fresh in memory at
|
||||
instance creation, never persisted — proves "exactly this incarnation wrote the key
|
||||
@@ -67,13 +70,14 @@ This directory owns two cross-artifact contracts specifically:
|
||||
Resolution always leans over-protect: same-nonce + not-unioned → clean replace;
|
||||
same-track foreign nonce or unioned → union; cross-track foreign nonce → remint under
|
||||
a fresh key. None of the three directions can under-protect.
|
||||
- **Deferred follow-up (TODO.md, not this dispatch's scope):** `ownerNonce` is not
|
||||
persisted, so after save→reopen an instance cannot recognize its own prior-session
|
||||
usage record — it unions and marks the record `unioned` forever, so prune stops
|
||||
reclaiming captures the instance once held but no longer uses (safe, but the bank
|
||||
folder grows unbounded). Persisting the nonce is deferred because a persisted nonce
|
||||
would be inherited by a Ctrl+D in-place FX duplicate, and a divergent clone must
|
||||
still be detected and protected fail-safe without reintroducing the sibling-drop bug.
|
||||
- **Deferred follow-up (TODO.md, deliberately NOT absorbed by the tracking
|
||||
consolidation):** `ownerNonce` is not persisted, so after save→reopen an instance
|
||||
cannot recognize its own prior-session usage record — it unions and marks the record
|
||||
`unioned` forever, so prune stops reclaiming captures the instance once held but no
|
||||
longer uses (safe, but the bank folder grows unbounded). This is a *completeness*
|
||||
wart, not a safety one; every candidate fix examined so far trades it for a new
|
||||
under-protection window, which the consolidation's own safety mandate forbids. See
|
||||
`docs/TODO.md` for the constraint and the rejected session-epoch candidate.
|
||||
|
||||
## Modules
|
||||
|
||||
@@ -81,7 +85,7 @@ This directory owns two cross-artifact contracts specifically:
|
||||
- `reasampler_uid.h` — SDK-free header owning the FOREVER-FROZEN VST3 class-UID integer macros (stable + beta pairs, `REASAMPLER_PROC_UID_*` / `REASAMPLER_PROC_UID_BETA_*`) and the `REASAMPLER_ACTIVE_UID_*` channel-selector macros. Split out of `reasampler_vst.h` so the pure extension side (`instrument_drop`) can derive the `.vstpreset` class-ID hex string without pulling in the VST3 SDK. Both `reasampler_vst.h` (runtime `FUID`) and `instrument_drop` (preset hex string) source from this single header — the binary identity and the preset-file identity cannot diverge.
|
||||
- `assignment_request` — pure ingest-assign wire: typed request record carrying the drop payload from the `ingest` shell through to the VST3 bridge.
|
||||
- `instrument_drop` — pure FX-drop payload builder: constructs a Steinberg-format `.vstpreset` image (channel-active class ID + the instrument's own component state, capture pre-selected) the shell applies via `TrackFX_SetPreset`; owns the `infoNamesFxHotspot` prefix classifier for `GetThingFromPoint` tokens. All-or-nothing contract — caller rolls back via `TrackFX_Delete` on any failure.
|
||||
- `sample_usage` — instance-usage wire: `UsageRecord`, `planUsagePublish` (fresh/heal/clean-replace/union/remint publish plan), `foldUsageRecords`/`usageHeldPaths` (liveness fold — protect-all when records exist but no instance is live; abort→protect-all on unreadable record), `identityMatches` (ReaSampler 9000 FX identity). REAPER-free, unit-tested. The mirror of `assignment_request` on the instrument→extension direction: the wire format and the two safety-critical decisions (what to write on publish, which records count at prune time) are pure so they are provable without a DAW.
|
||||
- `sample_usage` — instance-usage wire: `UsageRecord`, `planUsagePublish` (fresh/heal/clean-replace/union/remint publish plan), `foldUsageRecords`/`usageHeldPaths` (liveness fold — protect-all when records exist but no instance is live; abort→protect-all on unreadable record; `counted` carries key-attributed live records), `identityMatches` (ReaSampler 9000 FX identity). REAPER-free, unit-tested. The mirror of `assignment_request` on the instrument→extension direction: the wire format and the two safety-critical decisions (what to write on publish, which records count at prune time) are pure so they are provable without a DAW. It lives here because it is a *wire format* with an instrument-side writer; the fold's output is consumed by `core/tracking`'s authority, which owns every consumer-facing decision built on it.
|
||||
|
||||
## Gotchas
|
||||
|
||||
|
||||
Reference in New Issue
Block a user