Merge bake diagnosis soundness: every printed claim backed by an observation, write proof only where evidence crosses the plugin boundary
This commit is contained in:
+90
-11
@@ -654,17 +654,16 @@ tracks-and-range-only shape.
|
||||
|
||||
**Context (surfaced by Ψ-W2-T2, mono-collapse).** The collapse (`collapseCapturedFileToMono`
|
||||
/ `core/capture/wav_codec::collapseToMono`) ships for every extension capture path —
|
||||
offline, realtime, batch, recapture — but not for `bake_land.cpp`'s `landOne`, the
|
||||
resample bake's landing function. A dead-center instrument render (the common case
|
||||
offline, realtime, batch, recapture — but not for `bake_land.cpp`'s landing, the
|
||||
resample bake's `prepareLanding` / `commitLanding` pair. A dead-center instrument render (the common case
|
||||
that motivated Ψ.6 in the first place) is exactly the dual-mono shape the predicate
|
||||
collapses, so an un-collapsed bake keeps paying for the second channel it doesn't need.
|
||||
|
||||
**Not deferred for the reason once given.** `landOne` reads the staged file into `bytes`
|
||||
once (`bake_land.cpp:101`), parses its layout (`:105`), hashes it (`:126`), derives the
|
||||
channel count twice (`:131`, `:178`), and writes it (`:165`) — all from that same one
|
||||
buffer, so collapsing `bytes` right after the layout parse would keep the hash, the
|
||||
channel count, and the written file consistent by construction; there is no ordering
|
||||
hazard here to defer around.
|
||||
**Not deferred for the reason once given.** `prepareLanding` reads the staged file into
|
||||
`prep.bytes` once, parses its layout, hashes it and derives the channel count from that
|
||||
same one buffer, and `commitLanding` writes that buffer — so collapsing it right after the
|
||||
layout parse would keep the hash, the channel count, and the written file consistent by
|
||||
construction; there is no ordering hazard here to defer around.
|
||||
|
||||
**The real reason.** `bake_land.cpp` is Phase Ξ's freshly-landed surface
|
||||
(Ξ-W2-T1, the resample bake chain) and another team is actively remediating it. Landing
|
||||
@@ -677,9 +676,9 @@ however many channels the dialed sound has, and `bake_render.cpp:38` reads
|
||||
`sample.channelCount()` off that render rather than hardcoding 2 — a mono-programmed
|
||||
sound already bakes to a mono file today, with no change needed.
|
||||
|
||||
**Intended fix.** Once `bake_land.cpp` is quiet, call `collapseToMono` on the staged
|
||||
`bytes` in `landOne` right after the layout parse (`:105`) and before the hash (`:126`),
|
||||
matching the offline/realtime insertion point (post-parse, pre-identity-read).
|
||||
**Intended fix.** Once `bake_land.cpp` is quiet, call `collapseToMono` on `prep.bytes` in
|
||||
`prepareLanding` right after the layout parse and before the hash, matching the
|
||||
offline/realtime insertion point (post-parse, pre-identity-read).
|
||||
|
||||
**Priority / risk.** Low — a size optimization on an already-correct path, not a
|
||||
precision-invariant gap; the bake's dual-mono case still lands as a valid (if larger)
|
||||
@@ -768,3 +767,83 @@ above.
|
||||
function under a `<module>_tests` target with no REAPER, no VST3 SDK, and no
|
||||
filesystem includes; `shell/capture/render_bounds_gate` shrinks to the file-move and
|
||||
the two callers' plumbing.
|
||||
|
||||
## The capture path ignores `saveToActiveProject`'s return at four sites
|
||||
|
||||
**Context.** `saveToActiveProject()` returns false for exactly two reasons — no active
|
||||
project, or an unsaved one — and in both cases NOTHING was written. Four capture sites
|
||||
discard that return outright: `capture_orchestrator.cpp:343`, `capture_batch.cpp:266` and
|
||||
`:333`, and `realtime_lifecycle.cpp:39`.
|
||||
|
||||
**The wart.** A capture on an unsaved project renders the file into the bank folder, adds
|
||||
the `Sample` to the in-memory book, records a birth record in memory — and loses all three
|
||||
on reload. The bytes stay on disk with no index entry and no persisted ledger record, so
|
||||
they are a foreign file prune will never reclaim (an unrecorded file is untouchable by
|
||||
design — `core/tracking/CLAUDE.md`). Nothing is printed. The bank-op family already reads
|
||||
this return and discards its undo point on a false; the capture family does not read it at
|
||||
all.
|
||||
|
||||
**Why filed, not fixed.** Pre-existing, and the right answer is a product decision this
|
||||
dispatch had no mandate for: refuse the capture up front, keep it and warn, or prompt for
|
||||
a Save-As (the bank ops chose "quiet persist by design, deliberately no Save-As prompt" —
|
||||
whether capture should follow is a separate call).
|
||||
|
||||
**Done looks like.** A capture attempted with no saved project either does not write bytes
|
||||
at all, or writes them and says so in a sentence naming what will not survive a reload —
|
||||
and the choice between those two is recorded rather than implicit.
|
||||
|
||||
## `panel_input`'s wheel handler persists the whole book per wheel message
|
||||
|
||||
**Context.** `panel_input.cpp:450` — `handleWheel` calls `markTailDirty()` on every wheel
|
||||
message that actually moves `manualMs`, while the pointer is over the footer in Manual
|
||||
mode. (It coalesces sub-notch deltas within ONE message and no-ops at a bound, so the
|
||||
count is wheel messages that changed the value, not raw notches.)
|
||||
|
||||
**The wart.** `markTailDirty` is `saveToActiveProject()` — a full `BankBook` serialize plus
|
||||
six ext-state value writes on the UI thread — for a setting that is one number. A flick
|
||||
over the footer is a dozen of them in a few hundred milliseconds. Disproportionate rather
|
||||
than incorrect: no guardrail is violated (this is nowhere near the two named hot paths),
|
||||
and the writes are idempotent.
|
||||
|
||||
**Intended fix.** Coalesce: mark dirty and let one timer tick flush, the same shape the
|
||||
panel already uses elsewhere for repaint batching.
|
||||
|
||||
**Done looks like.** A continuous wheel gesture over the footer produces one persist, and
|
||||
the value that lands is the gesture's final one.
|
||||
|
||||
## `RunCaptureItemAssign`'s undo point does not follow the pattern its comment claims
|
||||
|
||||
**Context.** `capture_orchestrator.cpp:364-365` states that the action follows the bank-op
|
||||
family's discard-on-unsaved pattern.
|
||||
|
||||
**The wart.** It does not: `:382-383` records the undo point unconditionally whenever
|
||||
`sampleId` is non-empty, and never consults the persist's return at all. So on an unsaved
|
||||
project it records an undo point for ext-state that was never written — the empty
|
||||
no-effect entry `persistBankOp`'s guardrail exists to avoid. The comment describes the
|
||||
intended behavior, not the code.
|
||||
|
||||
**Why filed, not fixed.** It is one instance of the capture-family gap filed above, and
|
||||
fixing it alone would leave the other four sites divergent. Fix them together, or explain
|
||||
in one place why capture differs from bank ops.
|
||||
|
||||
**Done looks like.** The comment and the code agree, and the whole capture family answers
|
||||
the unsaved-project case one way.
|
||||
|
||||
## `core/tracking/CLAUDE.md`'s untracked-file enumeration says "reaches the `.rpp`" too loosely
|
||||
|
||||
**Context.** `src/core/tracking/CLAUDE.md:24-31` enumerates how a created file can stay
|
||||
untracked, and describes the ledger as reaching the `.rpp` at the following
|
||||
`saveToActiveProject()`.
|
||||
|
||||
**The wart.** `saveToActiveProject()` writes REAPER's IN-MEMORY project state and marks the
|
||||
project dirty; REAPER writes the `.rpp` on the project's own save, which may be much later
|
||||
or never. The sentence was already loose before this branch and is not made wrong by it —
|
||||
but it is the same over-claim ("a write reached the file on disk") the bake's reporting
|
||||
pass spent several rounds removing from its own sentences, so it should read the same way.
|
||||
|
||||
**Why filed, not fixed.** Editing another layer's own CLAUDE.md from a persist-and-report
|
||||
dispatch is exactly the boundary crossing the per-directory docs exist to prevent. It is a
|
||||
doc-keeper edit.
|
||||
|
||||
**Done looks like.** The enumeration distinguishes "in the project's state" from "on disk
|
||||
in the `.rpp`", and does not gain a second home for the distinction.
|
||||
|
||||
Reference in New Issue
Block a user