feat(studio): M6 — the primary visual product is a contract, and it's always live#114
Open
Yona-Appletree wants to merge 5 commits into
Open
feat(studio): M6 — the primary visual product is a contract, and it's always live#114Yona-Appletree wants to merge 5 commits into
Yona-Appletree wants to merge 5 commits into
Conversation
ADR 2026-07-16-primary-visual-product: the project's face = the resolved value of bus:visual.out (engine-resolved by provider priority; ties = the probe's deterministic order, now contract). The channel name lives once as PRIMARY_VISUAL_CHANNEL in the well-known registry (PRIMARY_CONTROL_CHANNEL declared for symmetry, unconsumed); the bus pane's PRIMARY badge references it instead of a string literal. ProjectController::primary_visual_product() reads the answer off the cached binding graph — no new wire surface. None is the defined empty state (no graph / no provider / unresolved / non-visual value). Co-Authored-By: Claude Opus 4.8 <[email protected]>
…not (M6 P3) subscribed_products() unions the primary visual product, and the node walk carries the primary ref so its preview presents as Tracking on the owning node even when unfocused (Default intent previously read Untracked/Paused). The project's face is always live while a project is open (ADR 2026-07-16-primary-visual-product). Co-Authored-By: Claude Opus 4.8 <[email protected]>
The diffs predate this branch: recent UI PRs (popover chrome, editor split-bar) changed slot-value-editor/config-slot-row/option-presence renders without re-capture, and CI never runs studio-story-check so the drift landed silently (follow-up filed to add a path-gated CI job). Captured from this branch; the M6 changes themselves are core-only. Co-Authored-By: Claude Opus 4.8 <[email protected]>
The story capture readiness gate never consulted document.fonts, so pages that lost the webfont race rendered fallback metrics and diffed nondeterministically. Baselines re-captured with the wait in place. KNOWN REMAINING FLAKE (pre-existing, follow-up filed): ~12 input-row stories are bistable — identical diff pixel counts per story every run (focus-ring race suspected) — so studio-story-check can still flip on those until captures are made deterministic. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Binding/bus roadmap M6 (plan:
Planning/lp2025/2026-07-16-m6-primary-visual/).P1 — Contract. ADR
docs/adr/2026-07-16-primary-visual-product.md:the project's face = the resolved value of
bus:visual.out(engineresolves by provider priority; the probe's deterministic ordering is now
contract). The channel name exists once —
PRIMARY_VISUAL_CHANNELinthe well-known registry (
PRIMARY_CONTROL_CHANNELdeclared forsymmetry) — and the bus pane's PRIMARY badge references it.
P2 — Helper.
ProjectController::primary_visual_product()reads theresolved channel value off the cached binding graph — no new wire
surface.
Noneis the defined empty state.P3 — Always-live.
subscribed_products()unions the primaryproduct, and the node walk threads it so the owning node's preview
presents live without focus. Verified in the sim: the playlist Output
went from "not tracked" to an always-present live frame surface with
nothing focused.
Also: the story-capture readiness gate now waits for
document.fonts(captures raced webfont decoding), baselines re-captured. A pre-existing
bistable capture flake on ~12 input-row stories remains (focus-ring race
suspected; follow-up task filed) — story-check may flip on those.
Note for the visual gate: visual RENDER frames for the playlist
product currently don't arrive even when focused (empty preview frame),
and the fixture Output is black on today's main despite animating on
the 07-15 post-naga build — possibly a fresh main regression
(candidates: #99 interp.f32 gate, #107 wgpu target). Worth a look
before judging the always-live preview visually.
Gates:
just check/just test/schema-checkgreen.🤖 Generated with Claude Code