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 `<Workspace>` 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<number>` 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 `<canvas>` 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 `<PaintSurface>` (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