# VibeScope — World-Class Acceptance Checklist > Companion to `00-MASTER-PLAN.md`. This is the operator-facing checklist > for ratifying whether each phase is DONE. For each phase, ALL items in the corresponding section must be checked off. --- ## Phase 1 — Foundation Lock - [ ] `bash pact/scripts/audit-chip-system-v3.3.x.sh` → 32/0 PASS - [ ] All 5 pact workspace files are VibeScope-specialised (no `` placeholders) - [ ] `@chips` array in `workspace.md` exactly matches `studio/modules/vibescope/src/registry/fragmentRegistry.ts` `FRAGMENTS` - [ ] Lowercase chip ids in registry (Title-Case display only) — AMEND-006 §3.1 --- ## Phase 2 — Editor Store - [ ] `useVSILStore` exists at `studio/modules/vibescope/src/state/VSILStore.ts` - [ ] `vsilOps.ts` exists at `studio/modules/vibescope/src/vsil/vsilOps.ts` - [ ] All 6 cards read from `useVSILStore` (no direct mock imports in card files) - [ ] Mutations dispatched through `vsilOps.*` only — no inline `state.layers.push(...)` - [ ] `mutationLog.ts` records every op - [ ] All mutations produce immutable outputs (Object.freeze per `vsil.a.layer.state.node.001`) - [ ] `vsilOps.test.ts` passes (50+ tests) - [ ] Drift-check 32/0 PASS (no regression) - [ ] 3-substrate CardMount parity test still passes --- ## Phase 3 — Scrubber + Evaluator - [ ] `ScrubberContext.tsx` exists and is used by all 6 cards - [ ] No card uses `useState` for time (lint rule enforces) - [ ] `CinemaProcedural.eval.ts` exists and renders evaluated FrameState - [ ] `mocks/timeline.tracks.json` exists with 3-5 sample tracks - [ ] Scrubbing Timeline triggers `evaluateFrame` per frame (verified by integration test) - [ ] Procedural engine renders <16ms on 60-frame composition with 4 animated layers (Playwright measured) - [ ] Evaluation is deterministic (snapshot test) - [ ] Bezier interpolation works for `transform.translate` track - [ ] Drift-check 32/0 PASS --- ## Phase 4 — Paint Surface + Brush + Transform + Selection - [ ] `PaintSurface.tsx` mounts a `` element with pointer event dispatch - [ ] `BrushEngine.ts` implements `cinema.engine.procedural.subsystem.brush.001` — real-time, 60fps, low-latency - [ ] `TransformEngine.ts` implements `cinema.engine.procedural.subsystem.transform.001` — move/scale/rotate with snap-to - [ ] `SelectionEngine.ts` implements `cinema.engine.procedural.subsystem.selection.001` — marquee + lasso - [ ] `HitTest.ts` does point-in-layer test for rect/ellipse/path/text - [ ] VisualCard uses `` (no more raw SVG dump) - [ ] Selection state lives in `SelectionStore.ts`, separate from `VSILStore` - [ ] Brush strokes → `vsilOps.addPaintLayer` or `vsilOps.updateLayer(path)` - [ ] Drag handles → `vsilOps.updateTransform` in real-time <16ms - [ ] Marquee → multi-select - [ ] Performance gate: 50 layers + active brush = <16ms/frame (Playwright) - [ ] Drift-check 32/0 PASS - [ ] All new tests pass (brush 20+, transform 20+, selection 15+, hit-test) - [ ] No `STUB:` markers in shipped code --- ## Phase 5 — Layer Panel - [ ] `LayerPanel.tsx` + `LayerRow.tsx` exist - [ ] `layerOps.ts` implements `addLayer`, `removeLayer`, `reorderLayer`, `groupLayers`, `ungroupLayer`, `setBlendMode`, `setVisibility`, `renameLayer`, `duplicateLayer` - [ ] CinemaLayout's Structure cell uses LayerPanel (not duplicated InspectorCard) - [ ] DevLayout's Structure cell uses DataCard (live state tree) - [ ] Inspector AST mode reflects live tree - [ ] Group operations validate (no cycles) - [ ] Blend mode enum enforced (throws VSILParseError on invalid) - [ ] All ops reversible via mutationLog (undo button) - [ ] Drift-check 32/0 PASS - [ ] `layerOps.test.ts` (50+) + `LayerPanel.test.tsx` (15+) pass --- ## Phase 6 — Mask + Animation - [ ] `MaskEngine.ts` implements `cinema.engine.procedural.subsystem.mask.001` - [ ] `AnimationEngine.ts` implements `cinema.engine.procedural.subsystem.animation.001` - [ ] `animationOps.ts` implements `addKeyframe`, `moveKeyframe`, `removeKeyframe`, `setInterpolation`, `setBezierHandles` - [ ] float-keyframe-track + vec2-keyframe-track both implemented - [ ] `KeyframeRow.tsx` is draggable - [ ] TimelineCard shows per-layer animated properties - [ ] VisualCard has mask mode toggle (brush → mask channel) - [ ] Mask channel stored as `layer.maskChannel: Uint8Array` (base64 PNG) - [ ] Performance gate: scrub 60-frame animation with 4 animated layers <16ms/frame - [ ] Drift-check 32/0 PASS - [ ] Tests pass (mask 15+, animation 15+, animationOps 50+) - [ ] No `STUB:` markers --- ## Phase 7 — Properties Two-Way - [ ] `propertyBindings.ts` exists - [ ] PropsMode: each property is a controlled input bound to `vsilOps.updateLayer` - [ ] Validators: opacity clamps 0..1, scale clamps >0, etc. - [ ] Multi-selection: common property changes apply to all selected layers - [ ] AST/State/Logs/Metadata modes remain READ-ONLY (snapshot test) - [ ] Undo/redo wired to mutationLog - [ ] Performance: opacity slider drag = <16ms/frame - [ ] Drift-check 32/0 PASS - [ ] `props-two-way.test.tsx` (20+) passes --- ## Phase 8 — Cinema vs Dev + Monaco - [ ] `DesignerCard.tsx` uses Monaco with VSIL JSON syntax - [ ] `DataCard.tsx` shows live state tree (not placeholder) - [ ] `LogsCard.tsx` shows engine telemetry (frame time, drop frames, errors) - [ ] `useMonacoVSIL.ts` provides Monaco language definition for VSIL - [ ] CinemaLayout: 4 cells = PaintSurface + PropertiesPanel + LayerPanel + TimelineCard - [ ] DevLayout: 4 cells = DesignerCard + DataCard + LogsCard + InspectorCard (AST) - [ ] Footer-level layout switcher in CentreStage toggles Cinema ↔ Dev - [ ] Monaco is dynamically imported (code-split, not in main bundle) - [ ] Editing VSIL source in Monaco re-evaluates on blur (or 500ms debounce) - [ ] Monaco errors → inline gutter markers (no console error storm) - [ ] DevLayoutGate: `FUTURE-OAUTH-INTEGRATION` marker REMOVED (replaced with `OAUTH-DEFERRED-VS-2026Q3` if real OAuth not built) - [ ] Layout preference persists via localStorage `vibescope.layout.user_pref.v1` - [ ] Drift-check 32/0 PASS - [ ] Bundle size: VibeScope route < 1.5MB - [ ] Visual regression snapshots for both layouts - [ ] Tests pass (CinemaLayout 5+, DevLayout 5+, DesignerCard 10+) --- ## Phase 9 — WebGL2 + Render CLI + Docs - [ ] `CinemaUltra.webgl.ts` has real vertex + fragment shaders - [ ] WebGL2 detected → `data-vibescope-ultra-gpu="true"` + real shader output (pixel-by-pixel different from procedural fallback) - [ ] WebGL2 absent → `data-vibescope-ultra-fallback="true"` (already works) - [ ] `renderCli.ts` loops frames 0..duration*fps calling `RenderEngine.render`, writes to `dist/` as SVG - [ ] All 7 track kinds implemented in animationOps (float + vec2 + vec3 + colour + path + string + discrete) - [ ] `pact/workspaces/vibescope/editor-getting-started.md` exists (operator onboarding) - [ ] `studio/modules/vibescope/README.md` updated - [ ] Drift-check 32/0 PASS - [ ] Tests pass (ultra-webgl 5+, render-cli 5+, per-track-kind tests 25+) - [ ] No `STUB:` markers anywhere in shipped code - [ ] No `FUTURE-OAUTH-INTEGRATION` markers anywhere --- ## DONE Definition (consolidated from Phase 9) ### Functional DONE - [ ] User opens VisualCard in Cinema layout → real canvas with at least one layer via CinemaProcedural Engine - [ ] Click on canvas → selects a layer (SelectionEngine) - [ ] Drag transform handle → layer moves in real-time, <16ms per frame - [ ] Change opacity in Properties panel → layer fades in real-time - [ ] Open Layer Panel → add a new rect layer → appears in canvas - [ ] Toggle visibility eye → layer hides - [ ] Toggle Cinema → Dev → DevLayout shows Monaco with live VSIL source - [ ] Edit source in Monaco → cinema_procedural re-evaluates on blur, canvas updates - [ ] Scrub Timeline → frames advance, animated layers interpolate - [ ] Add a keyframe via Animation engine → drag it → motion updates - [ ] Paint with brush → new layer OR mask channel updated - [ ] Click "Render" → CLI driver produces 60 SVG frames to `dist/` - [ ] Switch engine quality: Draft (procedural) / Good (procedural + sampling) / Best (Ultra WebGL2) - [ ] Save → VSIL doc written to Codex storage - [ ] Reload → doc loaded back, identical to saved state (deterministic round-trip) ### Pact DONE - [ ] All 8 chips work: Editor / Visual / Timeline / Inspector / Docs / Replay / Diff / Tests - [ ] All 3 engines implemented: cinema_procedural / cinema_ultra / render - [ ] Both layouts differentiated: Cinema (paint-first) + Dev (data-first) - [ ] All 6 engine subsystem fragments implemented: brush / transform / selection / layer / mask / animation - [ ] All 7 VSIL-A track kinds have addKeyframe/moveKeyframe ops: float / vec2 / vec3 / colour / path / string / discrete - [ ] 4 Cinema cells = paint + properties + structure + timeline - [ ] 4 Dev cells = designer + data + logs + inspector ### Drift DONE - [ ] `bash pact/scripts/audit-chip-system-v3.3.x.sh` → 32/0 PASS - [ ] 0 STUB: markers in shipped code - [ ] 0 FUTURE-OAUTH-INTEGRATION markers (replaced with explicit deferral) - [ ] All 5 pact workspace files VibeScope-specialised - [ ] All 5 workspace pact files contain the VibeScope-specialised template - [ ] `@chips` array matches registry `FRAGMENTS` exactly - [ ] DC-VC-FALLBACK-N: exactly 1 dispatcher - [ ] AMEND-006 §3.1: lowercase chip ids in registry ### Test DONE - [ ] All existing tests pass (parser, sceneGraph, evaluator, keyframeExtractor, assetRegistry, diff) - [ ] New tests cumulative: vsilOps (50+), brush (20+), transform (20+), selection (15+), mask (15+), animation (15+), animationOps (50+), propertyBindings (20+), DesignerCard (10+), ultra-webgl (5+), render-cli (5+), CinemaLayout (5+), DevLayout (5+), hitTest (10+) - [ ] Visual regression snapshots: Cinema layout, Dev layout - [ ] Performance tests: 60fps paint with 50 layers, 60fps scrub with 4 animated layers - [ ] Integration test: 3-substrate CardMount parity (unchanged from Phase 1 baseline) ### Build DONE - [ ] `vite build` clean, <30s - [ ] VibeScope route bundle <1.5MB (Monaco dynamic-imported) - [ ] All 3 engines tree-shake correctly - [ ] CF Pages deploy succeeds - [ ] Canonical URL `https://freshvibestudio.pages.dev/vibescope/...` works - [ ] 0 page errors, 0 console errors in Playwright smoke ### Operational DONE - [ ] `pact/workspaces/vibescope/editor-getting-started.md` exists - [ ] `studio/modules/vibescope/README.md` reflects Phase 9 state - [ ] Codex v0031.0 published with VibeScope Editor invariants - [ ] All tracked follow-ups from prior sessions reviewed (CSS stubbiness fix, integration test hole, CentreState-state failures, studio-pages history noise) --- ## END OF ACCEPTANCE CHECKLIST