Lock M10 provenance spec to Daniel's fork picks (P1=a, P2=a)
Settle the reshaped Milestone 10: thin capture-recipe fingerprint and bank-only re-capture; P3/P4 closed as moot. Remove the pending-picks banner in PLAN.md and stamp the provenance product note as settled.
This commit is contained in:
@@ -28,26 +28,26 @@ state persists via the index.
|
|||||||
fingerprint) on resample-from-sample, and ship a **"re-capture from source"**
|
fingerprint) on resample-from-sample, and ship a **"re-capture from source"**
|
||||||
action that regenerates a sample from its recorded source. Reconciled with the
|
action that regenerates a sample from its recorded source. Reconciled with the
|
||||||
dual-canvas (Phase D2) model. CONTEXT.md §Data model, §capture; product framing +
|
dual-canvas (Phase D2) model. CONTEXT.md §Data model, §capture; product framing +
|
||||||
the reconciliation forks in `docs/product/provenance.md`.
|
the settled reconciliation in `docs/product/provenance.md`.
|
||||||
**Verify (in DAW):** A sample resampled from a bank sample carries its parent id +
|
**Verify (in DAW):** A sample resampled from a bank sample carries its parent id +
|
||||||
recipe fingerprint; "re-capture from source" regenerates the file into the bank
|
recipe fingerprint; "re-capture from source" regenerates the file into the bank
|
||||||
(never auto-inserting into the timeline — load-bearing principle); re-capture with
|
(never auto-inserting into the timeline — load-bearing principle); re-capture with
|
||||||
an unchanged source + request is byte-identical to the original (bit-identical
|
an unchanged source + request is byte-identical to the original (bit-identical
|
||||||
repeats); non-destructive to source items/tracks.
|
repeats); non-destructive to source items/tracks.
|
||||||
|
|
||||||
> **PROPOSAL — pending Daniel's fork picks (2026-07-23).** Reshaped from the old
|
> **Reshaped from the old "provenance + null-test verify" M10.** **Cut (fixed by
|
||||||
> "provenance + null-test verify" M10. **Cut (fixed by Daniel):** the null-test
|
> Daniel):** the null-test verification *action* and the true-pre-FX-dry *mechanism*
|
||||||
> verification *action* and the true-pre-FX-dry *mechanism* the old note required —
|
> the old note required — both dropped, see `docs/product/provenance.md` §What was
|
||||||
> both dropped, see `docs/product/provenance.md` §What was cut. **Kept:** provenance
|
> cut. **Kept:** provenance + re-capture. The `Sample.provenance` struct and its JSON
|
||||||
> + re-capture. The `Sample.provenance` struct and its JSON round-trip **already
|
> round-trip **already exist** (M1) — M10 populates and consumes the field, it does
|
||||||
> exist** (M1) — M10 populates and consumes the field, it does not add it. The points
|
> not add it. Fork picks settled by Daniel (2026-07-23): **P1=a thin fingerprint,
|
||||||
> below reflect the **leaned path** (bank-only re-capture, thin fingerprint); the
|
> P2=a bank-only re-capture**; P3/P4 moot under P2=a. The points below are locked to
|
||||||
> re-place variant is deferred behind forks P2–P4. Lock the points once Daniel picks.
|
> that path.
|
||||||
|
|
||||||
- [ ] Populate `Sample.provenance` on resample-from-sample: `parentSampleId` (the
|
- [ ] Populate `Sample.provenance` on resample-from-sample: `parentSampleId` (the
|
||||||
bank sample the capture derived from) + `fxChainSnapshot` as a **capture-recipe
|
bank sample the capture derived from) + `fxChainSnapshot` as a **thin capture-recipe
|
||||||
fingerprint** (scope + source FX-chain identity at capture time — a drift/repro
|
fingerprint** (scope + source FX-chain identity/hash at capture time — a drift/repro
|
||||||
fingerprint, NOT a pre-FX-dry chain; see product note fork P1).
|
fingerprint, NOT a serialized pre-FX-dry chain to restore; P1=a settled).
|
||||||
- [ ] "Re-capture from source" action: regenerate a provenanced sample by re-running
|
- [ ] "Re-capture from source" action: regenerate a provenanced sample by re-running
|
||||||
its recorded capture request against the source's **current** state; update the
|
its recorded capture request against the source's **current** state; update the
|
||||||
bank file + Sample in place. **Bank-only — never inserts/re-places into the
|
bank file + Sample in place. **Bank-only — never inserts/re-places into the
|
||||||
@@ -56,14 +56,14 @@ repeats); non-destructive to source items/tracks.
|
|||||||
capture (bit-identical repeats); non-destructive (`FxBypassGuard` snapshot/restore
|
capture (bit-identical repeats); non-destructive (`FxBypassGuard` snapshot/restore
|
||||||
as M7); relative-paths-only preserved.
|
as M7); relative-paths-only preserved.
|
||||||
|
|
||||||
**Dual-canvas reconciliation (forks for Daniel — `docs/product/provenance.md`):**
|
**Dual-canvas reconciliation (settled — `docs/product/provenance.md`):** With
|
||||||
Under the leaned path (bank-only re-capture) provenance is **pure per-sample bank
|
bank-only re-capture (P2=a), provenance is **pure per-sample bank metadata**,
|
||||||
metadata**, `bank_model` and `view_mode_model` **stay decoupled**, and M10 touches
|
`bank_model` and `view_mode_model` **stay decoupled**, and M10 touches **no** canvas
|
||||||
no canvas code — compliance is satisfied by staying on the right side of the
|
code. Dual-canvas compliance is satisfied by staying on the right side of the
|
||||||
capture-never-places line. Forks P3 (canvas/lane memory in provenance) and P4
|
capture-never-places line — not by any new coupling. Forks P3 (canvas/lane memory in
|
||||||
(re-capture auto-tag interaction) only wake up if Daniel wants **P2 =
|
provenance) and P4 (re-capture auto-tag interaction) were only live under
|
||||||
re-capture-and-replace-on-timeline**, which would make re-place a mode-aware
|
re-capture-and-replace (P2=b) and are **closed as moot**; if the user manually
|
||||||
placement. Awaiting picks on P1 (fingerprint shape) and P2 (re-capture scope).
|
re-places a regenerated sample, the existing D2 mode-aware placement rule governs.
|
||||||
|
|
||||||
## Milestone 11 — polish
|
## Milestone 11 — polish
|
||||||
**Goal:** Batch capture (per selected item / per razor area),
|
**Goal:** Batch capture (per selected item / per razor area),
|
||||||
|
|||||||
+46
-37
@@ -6,11 +6,12 @@ authoritative technical detail is `CONTEXT.md` (§Data model, §capture) plus th
|
|||||||
note for the reconciliation calls. This doc holds the *why* and the open forks so
|
note for the reconciliation calls. This doc holds the *why* and the open forks so
|
||||||
they don't clutter the build docs.
|
they don't clutter the build docs.
|
||||||
|
|
||||||
Status: **PROPOSAL, pending Daniel's sign-off (2026-07-23).** Reshaped from the
|
Status: **SETTLED (2026-07-23).** Reshaped from the old "provenance + null-test
|
||||||
old "provenance + null-test verify" M10. Two decisions are fixed by Daniel and are
|
verify" M10. Two decisions were fixed by Daniel up front (see *What was cut* below).
|
||||||
**not** reopened here (see *What was cut* below). The remaining content is the
|
The four dual-canvas interaction forks are now resolved: **P1=a thin fingerprint,
|
||||||
provenance-only shape plus the dual-canvas interaction forks Daniel needs to
|
P2=a bank-only re-capture**, which makes **P3 and P4 moot (closed)**. The fork
|
||||||
settle.
|
analysis below is retained as the rationale record — each fork is stamped with its
|
||||||
|
resolution inline; nothing here is open.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -72,7 +73,8 @@ bit — enough of the **source FX-chain identity at capture time** that "re-capt
|
|||||||
from source" can tell whether the source still matches what was captured. This is a
|
from source" can tell whether the source still matches what was captured. This is a
|
||||||
*fingerprint for reproducibility*, not a mechanism for a different render mode.
|
*fingerprint for reproducibility*, not a mechanism for a different render mode.
|
||||||
|
|
||||||
> **Fork P1 — how much chain state does `fxChainSnapshot` carry?** Two shapes:
|
> **Fork P1 — how much chain state does `fxChainSnapshot` carry? — CHOSEN: (a)
|
||||||
|
> thin fingerprint (Daniel, 2026-07-23).** Two shapes:
|
||||||
> **(a) thin fingerprint** — a hash/summary of the source scope + FX-chain identity
|
> **(a) thin fingerprint** — a hash/summary of the source scope + FX-chain identity
|
||||||
> at capture time, used only to detect drift ("source has changed since capture")
|
> at capture time, used only to detect drift ("source has changed since capture")
|
||||||
> and to re-run the *same* capture request; or **(b) fat snapshot** — a full
|
> and to re-run the *same* capture request; or **(b) fat snapshot** — a full
|
||||||
@@ -85,7 +87,8 @@ from source" can tell whether the source still matches what was captured. This i
|
|||||||
> most naturally means "run the capture again against the source's *current* state"
|
> most naturally means "run the capture again against the source's *current* state"
|
||||||
> — that's the useful workflow (I changed the source, give me the updated sample).
|
> — that's the useful workflow (I changed the source, give me the updated sample).
|
||||||
> The fingerprint's job is to *tell* the user the source drifted, not to freeze it.
|
> The fingerprint's job is to *tell* the user the source drifted, not to freeze it.
|
||||||
> Confirm this is the intent before scoping.
|
> **Resolved 2026-07-23: (a). `fxChainSnapshot` is a capture-recipe fingerprint for
|
||||||
|
> drift detection and re-run — not a serialized chain to restore.**
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -119,7 +122,7 @@ onto the timeline (replacing the old placed item). That is a *placement*, and
|
|||||||
placement is mode-aware under D2.
|
placement is mode-aware under D2.
|
||||||
|
|
||||||
> **Fork P2 — does "re-capture from source" re-place, or only refresh the bank
|
> **Fork P2 — does "re-capture from source" re-place, or only refresh the bank
|
||||||
> entry?** Two shapes:
|
> entry? — CHOSEN: (a) bank-only re-capture (Daniel, 2026-07-23).** Two shapes:
|
||||||
> **(a) bank-only re-capture** — regenerate the file + update the bank Sample
|
> **(a) bank-only re-capture** — regenerate the file + update the bank Sample
|
||||||
> in place; the user re-places manually if they want the new version on the
|
> in place; the user re-places manually if they want the new version on the
|
||||||
> timeline. Fully honors the load-bearing principle with zero canvas coupling;
|
> timeline. Fully honors the load-bearing principle with zero canvas coupling;
|
||||||
@@ -132,6 +135,9 @@ placement is mode-aware under D2.
|
|||||||
> pillar's clean "capture never places" line and defers all the canvas-placement
|
> pillar's clean "capture never places" line and defers all the canvas-placement
|
||||||
> complexity. (b) can be a later opt-in ("re-capture and replace in place") once (a)
|
> complexity. (b) can be a later opt-in ("re-capture and replace in place") once (a)
|
||||||
> proves the provenance thread. If Daniel wants (b), P3 and P4 below become live.
|
> proves the provenance thread. If Daniel wants (b), P3 and P4 below become live.
|
||||||
|
> **Resolved 2026-07-23: (a). Re-capture regenerates the file into the bank and
|
||||||
|
> updates the Sample in place; it never places/replaces on the timeline. P3 and P4
|
||||||
|
> are therefore moot — closed (b) can still be revisited as a later opt-in.**
|
||||||
|
|
||||||
### Does provenance need to record canvas/mode membership?
|
### Does provenance need to record canvas/mode membership?
|
||||||
|
|
||||||
@@ -146,7 +152,8 @@ it needs no canvas memory; the bank stays mode-agnostic and the two pure modules
|
|||||||
stay decoupled. Under P2 = (b) re-place, the answer becomes **yes, partially**.
|
stay decoupled. Under P2 = (b) re-place, the answer becomes **yes, partially**.
|
||||||
|
|
||||||
> **Fork P3 — (only live if P2 = re-place) does provenance store canvas/lane
|
> **Fork P3 — (only live if P2 = re-place) does provenance store canvas/lane
|
||||||
> membership?** If re-capture re-places, where does it land?
|
> membership? — CLOSED/moot under P2=a (2026-07-23).** If re-capture re-places, where
|
||||||
|
> does it land?
|
||||||
> **(a) active-mode rule** — re-placement follows the *same* D2 auto-tag/placement
|
> **(a) active-mode rule** — re-placement follows the *same* D2 auto-tag/placement
|
||||||
> rule as any explicit placement: it lands in whatever mode is active *now*.
|
> rule as any explicit placement: it lands in whatever mode is active *now*.
|
||||||
> Provenance stores **nothing** about canvas; the view model's existing rule
|
> Provenance stores **nothing** about canvas; the view model's existing rule
|
||||||
@@ -159,6 +166,9 @@ stay decoupled. Under P2 = (b) re-place, the answer becomes **yes, partially**.
|
|||||||
> avoids. **Lean: (a) active-mode rule**, kept in the view model; provenance stays
|
> avoids. **Lean: (a) active-mode rule**, kept in the view model; provenance stays
|
||||||
> pure bank metadata with no view-model ids. Only reach for (b) if "re-capture
|
> pure bank metadata with no view-model ids. Only reach for (b) if "re-capture
|
||||||
> restores the exact original lane" is a stated requirement.
|
> restores the exact original lane" is a stated requirement.
|
||||||
|
> **Closed 2026-07-23: moot under P2=a. Re-capture never places, so it stores no
|
||||||
|
> canvas memory; provenance stays pure bank metadata and the two modules stay
|
||||||
|
> decoupled. Revisit only if re-capture-and-replace (P2=b) is later adopted.**
|
||||||
|
|
||||||
### Re-capture and auto-tagging
|
### Re-capture and auto-tagging
|
||||||
|
|
||||||
@@ -171,29 +181,31 @@ must tag the new item explicitly and **suppress** the auto-tag for that GUID (or
|
|||||||
two fight).
|
two fight).
|
||||||
|
|
||||||
> **Fork P4 — (only live if P2 = re-place AND P3 = origin-lane) does re-capture
|
> **Fork P4 — (only live if P2 = re-place AND P3 = origin-lane) does re-capture
|
||||||
> preserve or re-run auto-tagging?** If provenance restores the origin lane, the
|
> preserve or re-run auto-tagging? — CLOSED/moot under P2=a (2026-07-23).** If
|
||||||
|
> provenance restores the origin lane, the
|
||||||
> re-placed item must be tagged to the *origin* mode, not the active mode — so
|
> re-placed item must be tagged to the *origin* mode, not the active mode — so
|
||||||
> re-capture has to write the membership itself and exempt that GUID from the
|
> re-capture has to write the membership itself and exempt that GUID from the
|
||||||
> timer's auto-tag (same class as the manual-lane exemption already in
|
> timer's auto-tag (same class as the manual-lane exemption already in
|
||||||
> `autoTagNewContent`). **This fork only exists under P2=(b) + P3=(b).** Under the
|
> `autoTagNewContent`). **This fork only exists under P2=(b) + P3=(b).** Under the
|
||||||
> leaned defaults (P2=a, or P2=b + P3=a) it does not arise: bank-only re-capture
|
> leaned defaults (P2=a, or P2=b + P3=a) it does not arise: bank-only re-capture
|
||||||
> places nothing, and active-mode re-placement rides the existing auto-tag path
|
> places nothing, and active-mode re-placement rides the existing auto-tag path
|
||||||
> unchanged.
|
> unchanged. **Closed 2026-07-23: moot under P2=a — bank-only re-capture places
|
||||||
|
> nothing, so no auto-tag interaction arises.**
|
||||||
|
|
||||||
### Summary of the leaned path
|
### Summary of the settled path
|
||||||
|
|
||||||
If Daniel takes the leans (**P1=a thin fingerprint, P2=a bank-only re-capture**),
|
Daniel took the leans (**P1=a thin fingerprint, P2=a bank-only re-capture**,
|
||||||
the reconciliation collapses to almost nothing: provenance is **pure per-sample
|
2026-07-23), so the reconciliation collapses to almost nothing: provenance is
|
||||||
bank metadata**, `bank_model` and `view_mode_model` **stay decoupled**, and M10
|
**pure per-sample bank metadata**, `bank_model` and `view_mode_model` **stay
|
||||||
touches **no** canvas code. The dual-canvas compliance is satisfied by *staying on
|
decoupled**, and M10 touches **no** canvas code. The dual-canvas compliance is
|
||||||
the right side of the load-bearing line* (capture/re-capture never places), not by
|
satisfied by *staying on the right side of the load-bearing line* (capture/re-capture
|
||||||
new coupling. P3 and P4 only wake up if Daniel wants re-capture to also re-place
|
never places), not by new coupling. P3 and P4 are moot (closed) — they were only
|
||||||
onto the timeline.
|
live if re-capture also re-placed onto the timeline.
|
||||||
|
|
||||||
This is the recommendation: **keep provenance in the bank, keep re-capture a
|
The settled shape: **keep provenance in the bank, keep re-capture a bank-only
|
||||||
bank-only regenerate, and let the existing D2 placement rule handle the timeline if
|
regenerate, and let the existing D2 placement rule handle the timeline if and when
|
||||||
and when the user manually re-places.** It is the smallest thing that delivers the
|
the user manually re-places.** It is the smallest thing that delivers the useful
|
||||||
useful workflow and the cleanest against the architecture.
|
workflow and the cleanest against the architecture.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -225,19 +237,16 @@ useful workflow and the cleanest against the architecture.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Open forks for Daniel (the decision list)
|
## Decision list (settled 2026-07-23)
|
||||||
|
|
||||||
1. **P1 — `fxChainSnapshot` shape:** thin reproducibility fingerprint *(lean)* vs.
|
1. **P1 — `fxChainSnapshot` shape: CHOSEN (a) thin reproducibility fingerprint.**
|
||||||
fat serialized FX-chain chunk.
|
(Rejected: (b) fat serialized FX-chain chunk.)
|
||||||
2. **P2 — re-capture scope:** bank-only regenerate *(lean)* vs.
|
2. **P2 — re-capture scope: CHOSEN (a) bank-only regenerate.** (Rejected for now:
|
||||||
re-capture-and-replace-on-timeline.
|
(b) re-capture-and-replace-on-timeline; may return as a later opt-in.)
|
||||||
3. **P3 — (only if P2=replace) canvas memory:** re-place follows the active-mode
|
3. **P3 — canvas memory: CLOSED/moot under P2=a.** Was only live under P2=b; lean
|
||||||
rule, provenance stores no view ids *(lean)* vs. provenance records origin
|
was (a) active-mode rule, provenance stores no view ids.
|
||||||
mode/lane and restores it.
|
4. **P4 — auto-tag interaction: CLOSED/moot under P2=a.** Was only live under P2=b +
|
||||||
4. **P4 — (only if P2=replace AND P3=origin-lane) auto-tag interaction:** re-capture
|
P3=b.
|
||||||
writes origin-mode membership and exempts the GUID from the timer auto-tag. Only
|
|
||||||
live under the two non-leaned choices above.
|
|
||||||
|
|
||||||
The leaned path (1a, 2a) makes 3 and 4 moot and keeps M10 a small, decoupled,
|
Picks 1a + 2a make P3 and P4 moot and keep M10 a small, decoupled, capture-pillar
|
||||||
capture-pillar milestone. Awaiting Daniel's picks before the PLAN M10 points are
|
milestone. The PLAN M10 points are locked to this path.
|
||||||
locked.
|
|
||||||
|
|||||||
Reference in New Issue
Block a user