Context
T3.2 of the harness pillar (#13349), operator-seeded (the src/state/Provider.mjs hint, 2026-07-04): the flow state has MANY consumers across the module tree (chat surface, blueprint preview, pane chrome, promote affordance) — a provider gives each a declarative bind to one truth instead of reaching into a specific component. Topology note (operator-corrected 2026-07-04): the whole component tree lives in the shared app worker — windows are render targets — so ALL worker-side state (component configs included) is naturally window-agnostic; the promote step working across windows comes free with the architecture, and the provider’s contribution is the shared-binding surface + stores_ registry exposure. This leaf is the state substrate the SSOT-gated view chrome binds to — non-view itself, so unblocked now.
The Fix
apps/agentos/view/create/CreationStateProvider.mjs — extends Neo.state.Provider:
data: {flowState: 'empty', flowReason: null, activeInstanceId: null} — the five SSOT states live HERE; views bind, never re-derive.
stores_: exposes the CreatedInstances singleton so grids/panes bind the registry reactively across windows.
applyFlowEvent(event, {reason}) — the ONE writer: consults the #14711 transition oracle (nextCreationState), applies legal transitions to data, returns the oracle's bounded result for illegal ones (never throws, nothing mutated). applyRouteOutcome sugar mirrors the oracle's.
- Unit spec: legal wedge run mutates provider data; illegal events leave data untouched + return reason; the refused route outcome lands
flowReason for the ERROR render; stores exposure resolves.
§9.6 Core-Idiom Pre-Flight record (first live execution): contracts read this session — src/core/Base.mjs (reactive configs, set() batching, observeConfig, destroy), src/Neo.mjs (setupClass/Neo.get), src/state/Provider.mjs (hierarchical data proxy, formulas_, stores_, windowId; unit pattern from test/playwright/unit/state/Provider.spec.mjs).
Acceptance Criteria
Out of Scope
The view chrome binding it (SSOT-gated tranche) · the transition table itself (#14711, in review — this consumes it) · NL wiring · dock/promote mechanics (the affordance consumes this provider; its wiring is the dock lane).
Related
Parent #13349 (T3.2) · #14711 / PR #14712 (the oracle this guards writes with) · #14656 (the exposed registry, merged) · #14692 (the SSOT whose five states this carries) · src/state/Provider.mjs (the core contract, operator-seeded).
First-claim: @neo-fable (create-stack continuity; claiming at filing — implementation follows immediately this session).
Origin Session ID: b9b95ac6-42f5-47a3-b58f-6071f79657e8
Retrieval Hint: "creation state provider flow state multi window stores exposure app worker heap keeper"
Context
T3.2 of the harness pillar (#13349), operator-seeded (the
src/state/Provider.mjshint, 2026-07-04): the flow state has MANY consumers across the module tree (chat surface, blueprint preview, pane chrome, promote affordance) — a provider gives each a declarativebindto one truth instead of reaching into a specific component. Topology note (operator-corrected 2026-07-04): the whole component tree lives in the shared app worker — windows are render targets — so ALL worker-side state (component configs included) is naturally window-agnostic; the promote step working across windows comes free with the architecture, and the provider’s contribution is the shared-binding surface +stores_registry exposure. This leaf is the state substrate the SSOT-gated view chrome binds to — non-view itself, so unblocked now.The Fix
apps/agentos/view/create/CreationStateProvider.mjs— extendsNeo.state.Provider:data:{flowState: 'empty', flowReason: null, activeInstanceId: null}— the five SSOT states live HERE; views bind, never re-derive.stores_: exposes theCreatedInstancessingleton so grids/panes bind the registry reactively across windows.applyFlowEvent(event, {reason})— the ONE writer: consults the #14711 transition oracle (nextCreationState), applies legal transitions todata, returns the oracle's bounded result for illegal ones (never throws, nothing mutated).applyRouteOutcomesugar mirrors the oracle's.flowReasonfor the ERROR render; stores exposure resolves.§9.6 Core-Idiom Pre-Flight record (first live execution): contracts read this session —
src/core/Base.mjs(reactive configs,set()batching,observeConfig, destroy),src/Neo.mjs(setupClass/Neo.get),src/state/Provider.mjs(hierarchical data proxy,formulas_,stores_,windowId; unit pattern fromtest/playwright/unit/state/Provider.spec.mjs).Acceptance Criteria
stores_exposure above; flow-state writes ONLY viaapplyFlowEvent(the oracle-guarded writer).{state, reason, changed:false}returned.data.flowReason.Out of Scope
The view chrome binding it (SSOT-gated tranche) · the transition table itself (#14711, in review — this consumes it) · NL wiring · dock/promote mechanics (the affordance consumes this provider; its wiring is the dock lane).
Related
Parent #13349 (T3.2) · #14711 / PR #14712 (the oracle this guards writes with) · #14656 (the exposed registry, merged) · #14692 (the SSOT whose five states this carries) ·
src/state/Provider.mjs(the core contract, operator-seeded).First-claim: @neo-fable (create-stack continuity; claiming at filing — implementation follows immediately this session).
Origin Session ID: b9b95ac6-42f5-47a3-b58f-6071f79657e8 Retrieval Hint: "creation state provider flow state multi window stores exposure app worker heap keeper"