Skip to content

feat(cinema): shot variations strip (g-cinema-per-shot Part B) - #16

Merged
JustinPerea merged 3 commits into
mainfrom
feat/cinema-shot-variations
Jul 22, 2026
Merged

feat(cinema): shot variations strip (g-cinema-per-shot Part B)#16
JustinPerea merged 3 commits into
mainfrom
feat/cinema-shot-variations

Conversation

@JustinPerea

@JustinPerea JustinPerea commented Jun 22, 2026

Copy link
Copy Markdown
Owner

Part A merged in #15. This PR is now retargeted to main; its diff contains only Part B.

What

Adds a per-shot variations strip. A 1 to 4 stepper generates seeded candidates, stores them on the scene, and lets the user promote any thumbnail to the canonical shot image.

How

  • POST /api/cinema/generate-shot accepts a bounded variations count and runs distinct uncached seeds. _seedOverride is applied after connected Character data so explicit variation seeds still vary.
  • Successful batches persist shot.variations, selectedVariation, canonical output, and shot_<id> under the same per-node lock as Part A. Per-pass graphComplete events are suppressed, leaving one final graph sync.
  • If every variation pass fails, the target shot receives a terminal error through Part A's reconciliation path.
  • POST /api/cinema/promote-shot-variation atomically updates selectedVariation, canonical shot output, and the dynamic shot_<id> port, then broadcasts graph state.
  • The frontend mirrors scene and port state after backend promotion. Frontend-only Cinema nodes use the same local transaction without a backend request.

Restack and retarget evidence

  • Head: 4b25f3b15a59112adab44ffeffc4fecc4ac2d2b6.
  • Retargeted from Part A to merged main at 6f0681de065211d4bc00c6557267fc05e95b257f.
  • The unique Part B diff still retains the exact original 13-path set: 757 insertions, 36 deletions.
  • range-diff maps all three commits; only the expected inherited import union and updated implementation note differ.
  • Diff check and additions-only credential scan passed.

Validation

  • Focused backend Cinema suites: 30 passed.
  • Frontend graph-store suite: 35 passed.
  • Aggregate local gate: 1,164 backend tests, 394 frontend tests, lint, production build, 142 node contracts, contract inventory, and generated reference all passed.
  • Browser canvas at $0: Generate All, single-shot regeneration, four variations, Variation 3 promotion, reload persistence, downstream dynamic-port propagation, and renamed-local-file terminal failure all passed. The failure retained the last good image, variation state, sibling shot, and downstream port while showing a visible error.
  • No paid provider calls were run.

Remaining note

Variation batches still re-resolve the Cinema subgraph for each candidate. Optimizing repeated upstream work remains a separate performance follow-up.

JustinPerea added a commit that referenced this pull request Jun 22, 2026
…or review; log iter 9

Co-Authored-By: Claude Opus 4.8 <[email protected]>
@JustinPerea
JustinPerea force-pushed the feat/cinema-shot-variations branch from 4468ba1 to 0a172c9 Compare July 22, 2026 13:51
@JustinPerea
JustinPerea force-pushed the feat/cinema-per-shot-generate branch from 66599b7 to d4421a8 Compare July 22, 2026 13:51
@JustinPerea
JustinPerea force-pushed the feat/cinema-per-shot-generate branch from d4421a8 to d7c8c56 Compare July 22, 2026 22:40
JustinPerea and others added 3 commits July 22, 2026 18:40
Builds on Part A. A 1-4 stepper generates N seeded candidates per shot; the
strip renders them and clicking one promotes it to canonical.

Backend (backend/):
- GenerateShotRequest.variations (count). When > 1 the route runs N single-shot
  passes at distinct seeds (cache OFF so each truly regenerates) and stores them
  via _merge_shot_variations — first promoted canonical (output + port),
  siblings untouched, per-node lock as in Part A.
- Seed now applied via the shot's _seedOverride, which the cinema handler honors
  LAST so a variation seed wins even over a Character bundle seed (fixes the
  Part A precedence note).

Frontend (frontend/):
- CinemaShot.variations[] + selectedVariation on the scene spec (persists w/ save).
- graphStore.executeShot(..., variations?) + promoteShotVariation (canonical-only
  via updateScene; documented: the dynamic port keeps the batch's first variation
  until regenerated — Send-to-motion follows the promote since it reads output).
- CinemaShotPanel: count stepper + "Generate N" + promotable strip + CSS.

Tests: backend +3 (variations merge, empty no-op, _seedOverride precedence over
bundle); 1062 backend green; frontend tsc/eslint/vitest(389)/build green. Browser
store-check: promote updates selected+output; batch shows optimistic running.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Independent-verify (Part B) flagged two:
1. GenerateShotRequest.variations was unbounded server-side — a raw POST could
   queue 1000 real base-model passes. Clamped to 1–4 (Field ge/le), matching the
   panel stepper. +test asserting 0/5/1000 → 422.
2. A variations batch broadcast N graphComplete events → N spurious "pipeline
   complete" notifications. Per-shot regen runs outside the global run lifecycle,
   so _emit_scoped now suppresses graphComplete; the finally graphSync reconciles.

1063 backend green.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Persist variation promotion through the backend under the per-node Cinema lock, update the dynamic shot output, and broadcast graph state. Mirror scene and port state in the frontend and cover endpoint, frontend-only, and concurrent sibling behavior.
@JustinPerea
JustinPerea force-pushed the feat/cinema-shot-variations branch from 0a172c9 to 4b25f3b Compare July 22, 2026 22:43
@JustinPerea
JustinPerea changed the base branch from feat/cinema-per-shot-generate to main July 22, 2026 22:55
@JustinPerea JustinPerea reopened this Jul 22, 2026
@JustinPerea
JustinPerea merged commit 109ebc4 into main Jul 22, 2026
6 checks passed
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