Skip to content

feat(director-mode): v0 shot authoring with brand-safe validators#24

Open
ninan-versioning wants to merge 1 commit into
mainfrom
jared-shoploop/director-mode
Open

feat(director-mode): v0 shot authoring with brand-safe validators#24
ninan-versioning wants to merge 1 commit into
mainfrom
jared-shoploop/director-mode

Conversation

@ninan-versioning

Copy link
Copy Markdown
Owner

Summary

Director Mode v0 — a render-backend-agnostic shot-authoring package for product twins. Tap-to-drop a camera, draw a Bezier shot path, scrub a preview, save presets, and validate against brand-safe framing rules. Emits portable DirectorShot JSON.

Spec: /home/user/workspace/director-mode-spec.md

New package: packages/director-mode/ (@shoploop/director-mode), following the same pnpm-workspace / tsconfig / vitest patterns as packages/twin-renderer/ and packages/bandit/.

Render path is unchanged and Omniverse-free: open-imagine router (POST /render) → threejs_diffusion. No @nvidia/omniverse, no web-viewer-sample, no OVRTX, no Kit App Streaming. Live Kit streaming stays a deferred Tier-2 concern for unit-economics reasons (see spec).

Modules

  • src/schema.tsDirectorShot, UsdCameraPrim, BezierShotPath, AP2ProductRef, ShotValidationResult + type guards.
  • src/core/shotBuilder (tap/drag → shot, ULID ids), usdSerializer (DirectorShot ↔ .usda camera + xform animation, round-trippable), presetStore (localStorage + remote-sync stub).
  • src/validator/kinfolkRule (subject 38–62% frame width, ≥30% negative space), brandSafeZone (5% edge buffer unless allow_bleed), focalLengthGate (24–135mm unless focal_overrides), composed by validateShot. Thresholds configurable per brand via brand_rules.json.
  • src/adapter/openImagineSubmit (HMAC-signed POST /render), renderProvenance.
  • src/ui/ — React 18 overlay: DirectorOverlay, CameraDropTool, PathDrawTool, Scrubber, PresetLibrary (react/react-dom peer deps only — no new heavy UI deps).

Seam closure (#2)

adapter/renderProvenance.ts populates RenderProvenance.external_id with DirectorShot.id — the join seam the bandit (PR #21) added but left dangling. renderProvenance.test.ts proves the stamp lands and is idempotent. Director Mode is the producer that finally feeds the bandit's external_id join, so reward attribution no longer relies only on the loose shopify_product_gid → twin_handle fallback.

HMAC

openImagineSubmit signs the raw request body as base64(HMAC-SHA256(rawBody, OPEN_IMAGINE_HMAC_SECRET)), sent as X-Open-Imagine-Signature — matching the Shopify-webhook HMAC scheme already in this monorepo (connectors/shopify/src/primitives/webhooks.ts). Retries transient 503s.

Cost

$0 incremental at idle (pure library + UI). Per-shot render unchanged from PR #34. No Tier-2 Kit/OVRTX path added.

Testing

  • pnpm --filter @shoploop/director-mode test34 tests green across 10 files (spec target ≥25).
  • pnpm --filter @shoploop/director-mode typecheck clean.
  • pnpm --filter @shoploop/director-mode build (tsc → dist) succeeds.
  • No runtime dependency on Omniverse Kit, OVRTX, or web-viewer-sample.
  • README documents the DirectorShot schema with a full JSON example.

🤖 Generated with Claude Code

Render-backend-agnostic shot-authoring UX for product twins. Tap-to-drop
camera, draw Bezier shot path, scrub preview, save presets, validate against
Kinfolk composition + brand-safe rules. Emits portable DirectorShot JSON
rendered via the existing open-imagine router → threejs_diffusion path.

- schema + type guards (DirectorShot, UsdCameraPrim, BezierShotPath, AP2ProductRef)
- core: shotBuilder, usdSerializer (.usda round-trip), presetStore
- validator: kinfolk composition, brand safe-zone, focal-length gate
- adapter: HMAC-signed POST /render submit; renderProvenance stamps
  RenderProvenance.external_id with DirectorShot.id (closes bandit seam #2)
- ui: React 18 overlay (DirectorOverlay, CameraDrop, PathDraw, Scrubber, PresetLibrary)
- 34 vitest tests green; Omniverse-free (no Kit/OVRTX/web-viewer-sample)

Spec: /home/user/workspace/director-mode-spec.md

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant