Step 6
Some checks failed
CI / React UI Build (push) Successful in 11s
CI / Native Windows Build And Tests (push) Successful in 2m43s
CI / Windows Release Package (push) Has been cancelled

This commit is contained in:
Aiden
2026-05-11 19:25:29 +10:00
parent 79855d788c
commit d332dceb5b
9 changed files with 78 additions and 74 deletions

View File

@@ -153,7 +153,7 @@ The following must stay outside `ControlServices` in the target design.
The subsystem may report that an input requested a state change, but it should not decide whether that change is persisted.
That belongs to `RuntimeCoordinator` and `RuntimeStore`.
That belongs to `RuntimeCoordinator`, with `RuntimeStore` and the later persistence writer carrying out durable writes when policy requests them.
### Render Snapshot Publication
@@ -161,9 +161,9 @@ That belongs to `RuntimeCoordinator` and `RuntimeStore`.
### Render-Local Overlay Ownership
Live OSC overlays, temporal state, shader feedback, and render-only transient state belong to `RenderEngine`.
Live OSC automation overlays belong to the live-state/render preparation boundary (`RuntimeLiveState` today). Temporal state, shader feedback, output staging, and other render-only transient state belong to `RenderEngine`.
`ControlServices` may ingest automation targets, but it should not own how those targets are applied inside the render domain.
`ControlServices` may ingest and coalesce automation targets, but it should not own how those targets are composed, committed, persisted, or applied inside the render domain.
### Hardware Timing or Playout Recovery

View File

@@ -43,10 +43,9 @@ The current rendering path is split across several classes:
That split is workable today, but it creates architectural pressure:
- GL ownership is thread-shared instead of sole-owned.
- render and playout timing are still callback-coupled.
- preview and playout are produced in the same immediate path.
- render-local transient state now has clearer Phase 3 boundaries, but GL ownership is still shared through callback and UI entrypoints.
- render-local transient state now has clearer Phase 3/5 boundaries, but output production is still synchronously requested by the backend completion path.
- it is difficult to test render behavior separately from app bootstrap and hardware integration.
`RenderEngine` exists to absorb that responsibility into one subsystem with one direction of ownership. Phase 4 has completed the GL ownership part of this target: normal runtime GL work now enters through the `RenderEngine` render thread.

View File

@@ -80,7 +80,7 @@ The coordinator decides which state category a mutation affects:
The design rule is that classification belongs here, not in the ingress layer and not in render code.
Phase 5 has started codifying the shared vocabulary for this classification in `RuntimeStateLayerModel`. The current model records committed session parameter values, layer bypass state, and runtime compile/reload flags as committed-live/session coordination state, even though some of those values are still physically backed by `RuntimeStore` during migration.
Phase 5 codifies the shared vocabulary for this classification in `RuntimeStateLayerModel`. Current committed session parameter values and layer bypass state are committed-live/session state owned by `CommittedLiveState`; runtime compile/reload flags are coordination state rather than durable store truth.
### 4. Snapshot publication requests
@@ -248,13 +248,15 @@ Typical interaction:
This is the coordinator's primary logical domain.
Even while committed live state is physically stored inside `RuntimeStore`, the coordinator should be considered the policy owner of:
The coordinator is the policy owner of:
- current layer stack composition
- current selected shaders
- current bypass flags
- current operator-authored parameter values
`CommittedLiveState` is the physical owner for this current-session layer state. `RuntimeStore` persists or skips disk writes according to coordinator policy and remains the compatibility facade for existing mutation call shapes.
### Transient live overlay state
The coordinator defines the rules for transient state, but should not become the long-term storage owner for render-local transient data.
@@ -534,7 +536,6 @@ Mitigation:
## Open Questions
- Should committed live state remain physically stored in `RuntimeStore`, or should the coordinator gain a live-session companion object before Phase 3?
- Should preset load/save stay synchronous through early migration, or should the coordinator always treat them as policy requests whose persistence effects may complete later?
- Should reload requests be modeled as a dedicated mutation class distinct from ordinary control mutations from the start?
- How much normalization of parameter values should remain in store-side helpers versus moving into coordinator policy helpers?

View File

@@ -35,7 +35,7 @@ Before the Phase 1 runtime split, the closest behavior lived in:
`RenderSnapshotBuilder` is responsible for:
- building render-facing snapshots from durable store state plus whatever committed-live state view the Phase 3 split ultimately exposes
- building render-facing snapshots from the committed-live read model and package/runtime metadata supplied by `RuntimeStore`
- separating structural snapshot changes from dynamic frame fields
- translating runtime layer state into render-ready layer descriptors
- attaching immutable or near-immutable shader/package-derived data needed by render
@@ -81,13 +81,11 @@ The shape of render-facing layer state should remain consistent across phases ev
`RenderSnapshotBuilder` should build from a read-oriented runtime view, not from direct mutation calls. `RuntimeSnapshotProvider` should consume the builder's output and own publication/cache behavior.
That view will likely include:
That view now includes:
- durable configuration and layer-stack data from `RuntimeStore`
- committed live values from either:
- `RuntimeStore`, while committed live state is still co-located there, or
- a coordinator-owned live-state companion once Phase 3 finishes the split
- package and manifest metadata required to describe render-facing layer structure
- committed live layer state from `CommittedLiveStateReadModel`
- package and manifest metadata supplied through `RuntimeStore`
- durable runtime configuration needed to describe render-facing dimensions and defaults
The important Phase 1 rule is not "the provider always reads one specific object." It is:
@@ -297,9 +295,9 @@ Notes:
### `RuntimeStore`
`RenderSnapshotBuilder` depends on store-owned durable data and package metadata through a read-oriented interface or view. `RuntimeSnapshotProvider` depends on the builder rather than reaching into store internals directly.
`RenderSnapshotBuilder` depends on store-owned durable metadata and the committed-live read model exposed through store-facing read APIs. `RuntimeSnapshotProvider` depends on the builder rather than reaching into store internals directly.
If committed live state remains physically co-located with the store during early migration, the builder may read it through the same view. If committed live state moves behind a coordinator-owned live-session model later, the builder should consume that through a similarly read-oriented view.
Committed session layer state now lives in `CommittedLiveState`; `RuntimeStore` remains the facade that combines that read model with package metadata and persistence-owned data for snapshot publication.
Neither the builder nor provider should mutate the store directly.

View File

@@ -95,7 +95,7 @@ Those are coordinator concerns, not store concerns.
`RuntimeStore` should own the following state categories.
Phase 5 names this boundary in code through `RuntimeStateLayerModel`: persisted layer stack data, saved parameter values, and stack presets are classified as base persisted state. Operator/session values may still be backed by the store during migration, but their mutation policy is committed-live policy owned by the coordinator, not durable-store policy by default.
Phase 5 names this boundary in code through `RuntimeStateLayerModel`: persisted layer stack data, saved parameter values, and stack presets are classified as base persisted state. Operator/session values are owned by `CommittedLiveState`; their mutation policy is committed-live policy owned by the coordinator, not durable-store policy by default.
Phase 5 also adds `CommittedLiveState` as the physical owner of current session/operator layer state and `CommittedLiveStateReadModel` as the named read boundary for render snapshot publication. `RuntimeStore` still owns file IO, config, package metadata, preset persistence, and persistence requests, but it delegates current-session layer mutations to `CommittedLiveState`.
@@ -366,10 +366,14 @@ Those belong under other target subsystems.
- runtime host config load and resolved paths
The current codebase has completed this part of the split: `RuntimeConfigStore` owns config parsing, path resolution, configured ports/formats, runtime roots, and shader compiler paths, while `RuntimeStore` exposes compatibility-shaped delegates for existing callers.
- `CommittedLiveState`
- current committed/session layer stack and parameter values
- layer CRUD/reorder and shader selection for the running session
- committed-live read model for snapshot publication
- `LayerStackStore`
- durable layer stack and parameter values
- layer CRUD/reorder and shader selection
- stack preset value serialization/load
- backing layer stack mechanics used by committed-live state
- layer CRUD/reorder and shader selection helpers
- stack preset value serialization/load helpers
- `RuntimeStatePresenter` / `RuntimeStateJson`
- runtime-state JSON assembly
- layer-stack presentation serialization
@@ -382,7 +386,7 @@ The current codebase has completed this part of the split: `RuntimeConfigStore`
- `PersistenceWriter` helper
- synchronous at first, async/debounced later
The current codebase has completed the layer split: `LayerStackStore` owns durable layer state, layer CRUD/reorder, parameter persistence, and stack preset value serialization/load. `RuntimeStore` keeps file IO and facade methods for existing callers.
The current codebase has completed the committed-live split: `CommittedLiveState` owns current committed/session layer state using `LayerStackStore` backing mechanics. `RuntimeStore` keeps file IO, package metadata, persistence serialization, persistence requests, preset file access, and facade methods for existing callers.
The current codebase has completed the render snapshot split: `RenderSnapshotBuilder` owns render-state assembly, cached parameter refresh, dynamic frame-field refresh, and render snapshot versions. `RuntimeSnapshotProvider` depends on this builder rather than on `RuntimeStore` friendship.
@@ -536,16 +540,7 @@ Current recommendation:
- keep only durable reference/package metadata here
### 2. Should Committed Live State Be Co-Located With Persisted State?
The Phase 1 parent doc leaves open whether committed live state stays in the store or is split with a live companion model owned by the coordinator.
For `RuntimeStore`, the important rule is:
- if a piece of state is part of the durable truth model, the store should own it
- if it is transient or session-only, it should not be forced into the store just for convenience
### 3. Should Preset Application Be A Store Operation Or A Coordinator Operation?
### 2. Should Preset Application Be A Store Operation Or A Coordinator Operation?
The file load and preset parse clearly belong here.
@@ -556,7 +551,7 @@ Current recommendation:
- `RuntimeStore` loads preset content
- `RuntimeCoordinator` decides how to apply it
### 4. How Early Should Async Persistence Land?
### 3. How Early Should Async Persistence Land?
Phase 1 does not require it, but the store design should not block it.