Skip to content

Scene candidates & selection

Clawbot, the videoclaw mascot, illustrating scene candidates

Every scene can have many takes — videoclaw keeps all of them, lets you pick the winner per scene, and re-rolls just the bad scenes without burning budget on the good ones. It is a director's selection desk for AI video: nothing is overwritten, every "which one did we ship?" question has a real answer, and you can re-run scene 3 alone while scenes 1, 2, and 4 stay locked.

What it does

  • Keeps every take. Each time the runtime generates a scene, the result is appended as a new candidate (scene-0-take-1, scene-0-take-2, …). Old takes are never overwritten, so you can compare take 1 to take 2 after the fact.
  • Separates "what was generated" from "what you chose." An append-only registry records every take; a separate mutable ledger records your pick, your rejections, pending takes, and re-roll requests per scene.
  • Re-runs one scene at a time. produce --scene 2 regenerates only scene 2 and appends a fresh round; the scenes you didn't name keep their current winner.
  • Asks for several takes on demand. Re-roll the same scene a few times to get takes 1, 2, 3, then pick the best.
  • Chains continuity between cuts. chain-from tells the runtime to feed scene N−1's selected clip into scene N so a provider like Seedance 2.0 carries identity, environment, and motion across the cut.
  • Gates downstream stages. review and publish refuse to advance while any scene with candidates has no winner picked — so you can't ship an unselected scene by accident.
  • Migrates legacy projects. A one-shot command turns an old single-generation project into one pre-selected candidate per scene.

How to use it

All commands below use the form node dist/cli/vclaw.js video .... If you installed the package globally you can type vclaw video ... instead — they are identical.

bash
node dist/cli/vclaw.js video candidates-list --project demo

Lists every take grouped by scene, plus a portfolio-wide summary (total / completed / pending / failed). Add --scene 0 to focus one scene.

bash
node dist/cli/vclaw.js video candidates-show --project demo --candidate-id scene-0-take-1

Prints one candidate looked up by id across all scenes as { sceneIndex, candidate }. Exits non-zero on an unknown id.

bash
node dist/cli/vclaw.js video select-candidate --project demo --scene 0 --candidate-id scene-0-take-1 --notes "first take was perfect"

Marks that take as the winner for scene 0. It is pulled out of the rejected/pending lists and any pending re-roll flag is cleared. --notes is optional.

bash
node dist/cli/vclaw.js video reject-candidate --project demo --scene 2 --candidate-id scene-2-take-1

Records a rejection. If that take was the current winner, the selection is cleared; the id is removed from pending if present.

bash
node dist/cli/vclaw.js video reroll-scene --project demo --scene 2 --chain-from-prev on

Flags scene 2 as needing a fresh generation and clears its winner so you must re-pick. --chain-from-prev on|off is optional and sets the chain flag at the same time.

bash
node dist/cli/vclaw.js video produce --project demo --scene 2

Regenerates only scene 2 and appends it as a new round/take. Pass --scene more than once (e.g. --scene 1 --scene 3) for a specific subset; scenes you omit keep their current candidate. produceexecute are aliases.

bash
node dist/cli/vclaw.js video chain-from --project demo --scene 5 --from 4

Turns on chain-from-prev for scene 5, feeding scene 4's selected clip in as the upstream hint. v1 only supports the immediately previous scene — --from must equal --scene − 1 or it returns chain-from-unsupported.

bash
node dist/cli/vclaw.js video unchain --project demo --scene 5

Turns the chain-from-prev flag back off for that scene.

How it flows

scene candidates diagram

Diagram source (live Mermaid)

Artifacts & outputs

Two canonical JSON artifacts live under projects/<slug>/artifacts/:

  • scene-candidates.jsonappend-only registry of every take, grouped by sceneIndex. Each candidate has a globally-unique id scene-<sceneIndex>-take-<n>, a generationRound, status (pending | completed | failed | cancelled), outputs[] (kind + path), and a source block recording the execution round, adapter, and any chainedFromCandidateId.
  • scene-selection.jsonmutable ledger, one entry per scene with selectedCandidateId, rejectedCandidateIds[], pendingCandidateIds[], rerollRequested, chainFromPrev, and optional notes. The three id sets are pairwise disjoint per scene (enforced by validation).

At publish time the selected candidates are projected into a canonical asset-manifest.json view, so the shipped assets match exactly what you picked. Per-scene Obsidian notes also surface candidate counts, the selected take, rejected/pending counts, and the chain flag.

Tips & gotchas

One scene, many takes — keep the good one

The whole point: re-run only the scene that's off. reject-candidatereroll-sceneproduce --scene <n>select-candidate gives you a clean fix without re-rendering scenes that were already perfect.

Lock the upstream scene before chaining

chain-from-prev reads the previous scene's selectedCandidateId. If that scene has no winner, the runtime hard-fails with chain-from-prev-source-missing; if the upstream winner isn't completed, it fails with scene-chain-upstream-stale. Run select-candidate on the previous scene first, or unchain the downstream scene.

Pick a winner or you can't ship

readiness, review, and publish all block with scene-selection-missing when any scene has candidates but no selection. doctor-project / doctor-portfolio also flag scene-selection-stale (a newer completed take exists), scene-reroll-pending (a re-roll is still outstanding), and scene-chain-upstream-stale.

Migration is one-shot

candidates-migrate-from-assets synthesizes one pre-selected candidate per scene from an existing asset-manifest.json. It refuses with migrate-refused if scene-candidates.json already exists — there is no --force in v1. Use --dry-run to preview, and delete the artifact manually if you genuinely need to re-migrate.

Driving it from an agent

An AI agent (e.g. Claude Code) drives the full loop with plain shell calls: produce --scene <n> to generate, candidates-list --project <slug> to read back the JSON, then select-candidate/reject-candidate/reroll-scene to record the decision. Every command emits machine-readable JSON on stdout and follows the exit-code contract: 0 = ok, non-zero = validation or lookup error (candidates-show on an unknown id, chain-from with an unsupported source, etc.). Because selection is gated, an agent can loop produce → inspect → select until readiness stops returning scene-selection-missing, then advance to review/publish.

  • providers — which routes (Seedance, Veo, Runway) generate the takes a candidate captures.
  • characters — identity bindings carried through each generated scene; chain-from-prev preserves identity across the cut.
  • assemble — stitches the selected winners into the final master.
  • Deep reference: docs/SCENE_CANDIDATES.md — full data model, chain-from semantics, migration, readiness/doctor codes, and troubleshooting.

Built to be driven by agent hosts like Claude Code, Claude Desktop, or Codex · Source-available, commercial use requires a paid license.