docs(context): record ratified item auto-tag adoption rule

New items adopt the single mode of their track's pre-existing content; active-mode rule retained for new tracks, empty tracks, and multi-mode tracks. Reconciles spec with the fix-drop-lane-strand merge.
This commit is contained in:
2026-07-27 05:04:00 -04:00
parent 31faf25889
commit 6b643bb089
+28 -14
View File
@@ -400,12 +400,19 @@ Track-only-in-one-mode content is still handled by D1 track-parking, unchanged.
`vendor/reaper-sdk`**): track-side `I_FREEMODE = 2`, `I_NUMFIXEDLANES`,
`C_LANEPLAYS:N`; item-side `I_FIXEDLANE`, `C_LANEPLAYS`, `B_FIXEDLANE_HIDDEN`.
**`I_FREEMODE` changes require `UpdateTimeline()`** to take visible effect.
- **Membership: auto-tag by active mode at creation.** New content — **both new
tracks and new items** — is tagged to whatever mode is active when it is created.
Pre-existing content defaults to **Arrange**. Membership is **exclusive**:
Design-created content never appears in Arrange and vice versa, except via the
existing **show-both** escape hatch. (This is the same tag-to-active-mode rule as
D1 track membership, now reaching items on shared tracks.)
- **Membership: adoption rule for new items; active mode for new tracks.** New
**tracks** are tagged to the active mode at creation. New **items** follow an
adoption rule: if the item's track has pre-existing managed-eligible content
spanning exactly **one** mode, the item adopts **that mode** — the track stays
single-mode, no lane split, nothing stranded. The active-mode fallback applies
only when the track is empty (no prior content) or already spans multiple modes.
Items in **manual lanes** are excluded from the prior-mode computation and are
not auto-tagged at all (manual/managed boundary unchanged). Deliberate multi-mode
splits occur only via the explicit tag/move-item actions, never via auto-tag.
Pre-existing content defaults to **Arrange**. Membership is **exclusive per
item**: an item lives in exactly one mode, except via the existing **show-both**
escape hatch. (New-track tagging follows the same active-mode rule as D1 track
membership; the adoption rule is a refinement for items on shared tracks.)
- **Inactive-mode content is hidden AND silenced.** The off-mode lane is set
`C_LANEPLAYS = 0` — neither shown nor played — consistent with exclusive
membership and with D1's "flipping modes is a real change, not cosmetic." Show-both
@@ -456,8 +463,11 @@ pure query over the ownership index; only reading REAPER's live lane state is sh
manual) and the **"which lanes may this toggle touch" query** (managed only) are
pure and unit-tested — the planner emits lane ops for managed lanes only and never
for manual lanes. The **auto-tag decision** is pure too: given *a set of new
track/item GUIDs + the active mode* — and, for items, whether the item landed in a
manual lane (exempt) — produce the membership writes.
track GUIDs + active mode* (active-mode rule) and *a set of new items, each
carrying the set of modes already present on its track* (`NewItem::trackModes`)
— plus the manual-lane exemption flag — `autoTagNewContent` produces the
membership writes. The adoption guard runs inside the pure layer: single prior
mode → adopt it; empty / multi-mode track, or new track → fall back to active mode.
- **Shell.** Two shell responsibilities. (1) **Apply** the planner's item-lane ops
(`I_FREEMODE`/`I_FIXEDLANE`/`C_LANEPLAYS`/`B_FIXEDLANE_HIDDEN` via the media-item
info setters, `UpdateTimeline()` after `I_FREEMODE` changes) — for managed lanes
@@ -473,8 +483,11 @@ therefore requires the shell to **diff project state on the panel's existing tim
the `bank_panel` already polls and fingerprints the bank; this extends that machinery
to the timeline's tracks and items.
- Each poll, compare the live track/item GUID set against the previous poll's set;
**any GUID new since the last poll is tagged to the then-active mode.**
- Each poll, compare the live track/item GUID set against the previous poll's set.
New **track** GUIDs are tagged to the then-active mode. New **item** GUIDs are
passed to `autoTagNewContent` with the pre-existing mode-span of their track
(`NewItem::trackModes`): single-mode track → adopt that mode; empty / multi-mode
track → fall back to the then-active mode. Manual-lane items are excluded.
- Correctness the implementation must handle: the **first poll after project open must
not mass-tag** pre-existing content (pre-existing defaults to Arrange, per the
membership rule).
@@ -482,7 +495,7 @@ to the timeline's tracks and items.
**not** auto-tagged — auto-tag governs normal timeline content, not lanes the user
hand-manages. Distinguishing the two may need a heuristic at detection (e.g., an item
whose `I_FIXEDLANE` is marked manual in the ownership index is exempt; content
outside any managed lane on a mode-managed track follows the active-mode rule). The
outside any managed lane on a mode-managed track is subject to the adoption rule). The
precise rule is an **open implementation design point**; the settled boundary is that
manual-lane content is off-limits to auto-tag.
- **Lane-identity fragility (design point).** `I_FIXEDLANE` is the lane's identity and
@@ -490,9 +503,10 @@ to the timeline's tracks and items.
reorder/renumber/deletion without going stale is an **implementation design point**
(same class as GUID-keyed reorder-safety for tracks) — flag, don't solve here.
- Pure/shell seam: the **detection** (diffing REAPER's live set each tick, reading live
lane ownership) is shell; the **tagging decision** and the **managed/manual lane
query** (new GUIDs + active mode + manual-lane exemption ⇒ membership + lane writes)
are pure and unit-tested.
lane ownership and per-item `trackModes`) is shell; the **tagging decision** and the
**managed/manual lane query** (new track GUIDs + active mode; new item GUIDs +
`trackModes` + active mode + manual-lane exemption ⇒ membership + lane writes) are
pure and unit-tested.
### REAPER API surface (verify all signatures)