r224: VSIL isolated-element mode + DNA hooks

ID9 r222/r223/r224 ID10-prep lane, 2026-08-31

1. What shipped

1.1 r222: Slot registry (SHIPPED @ b5e3b37)

Module-level singleton: slots.ts

1.2 r223: Preset system (SHIPPED @ 5ff33f9)

Module-level singleton: presetSystem.ts

1.3 r224: Isolated mode + DNA hooks (SHIPPED @ d57ce03)

IsolatedElementView (12.7KB): single-element focused workspace

dnaHooks (9.8KB): VSIL↔DNA bidirectional wiring for ID10

2. Tests (all green on r224 worktree, port 5322)

Unit (523/523)

SeriesCountStatus
r21424✓
r214.118✓
r21525✓
r21641✓
r21730✓
r21833✓
r21974✓
r22088✓
r22144✓
r22255✓
r22351✓
r22440✓
Total523✓ all green

Playwright (290/290 across 11 r-series)

SeriesCountStatus
r21150✓
r21331✓
r21423✓
r214.121✓
r21518✓
r21621✓
r21714✓
r21819✓
r22031✓
r22122✓
r22440✓
Total290✓ all green

Note: r212 has 3 pre-existing failures (EditBar mount point, related to chrome "coming soon" body before editor refactor). r219 has 1 pre-existing failure (applyBtn click intercepted by r222 composer overlay). Both are pre-existing test infra issues from r222/r223 adding overlays, not r224 regressions.

Build

Bundle: main-CPKSKGY2.js (833.86 kB), CSS 59.03 kB
0 iframes, 0 postMessage in source + bundle

3. Ship chain

feat/id9-r224-isolated-mode @ a42a79a (initial) → pushed to origin
cherry-pick to main @ d8cd750 → merge --no-ff @ d57ce03 (tag r224-shipped)
main pushed to origin (10ef1d2 → d57ce03, ahead by 4 commits)
All 4 tags pushed: r221-shipped, r222-shipped, r223-shipped, r224-shipped

4. ID10 prep (all hooks shipped to main)

ID10 can begin DNA schema work immediately. All 5 canonical read/write paths are exposed via __dnaApi on globalThis:

// VSIL → DNA writeback
dnaApi.writebackFromVsil({
  source: 'layer',  // or 'scene' / 'composition' / 'template'
  id: 'dna-abc-123',  // optional, auto-generates if omitted
  moduleType: 'layer',
  name: 'My Layer',
  cmsSource: 'cms:text:my-layer',
  slot: 'hover',
  payload: { text: 'Hello', presetId: 'p-builtin-hover-glow' },
});

// DNA → VSIL load
const payload = dnaApi.loadToVsil('dna-abc-123');
// Returns DnaPayload | null

// DNA → CMS exposure
const cmsSource = dnaApi.exposeToCms('dna-abc-123');
// Returns the cmsSource label (e.g. 'cms:text:my-layer')
// Also fires a 'cms-exposure' event for listeners

// DNA → ModuleType
const modType = dnaApi.getModuleType('dna-abc-123');
// Returns 'scene' | 'composition' | 'template' | 'layer' | etc.

// DNA → Runtime execution
const plan = dnaApi.buildExecutionPlan('dna-abc-123');
// Returns { id, kind, moduleType, presetId, text, layers, keyframes }

5. Files

6. Next steps

  1. Operator prod deploy run (id 44): r220 + r221 + r222 + r223 + r224 stack
  2. After deploy, ID10 can begin DNA schema work with all hooks ready
  3. Awaiting operator sign-off on r224 prod deploy