OpenAI Film Fieldnotes

Candidate construction guide · native Resolve not tested

Insert, resize and place a selected badge

An original SVG/code Remotion treatment with a complete manual DaVinci Resolve / Fusion construction guide. Two meaningful content variants share one framegraph. No source artwork, raster/video adaptation input or native Resolve project is shipped. Builder tests are not a rendered-quality approval.

Public kit: install and verify

The kit root contains core-publication-v08.zip, active-assets.zip, handoff.py, guide.json, this README, controls.csv, fusion-controls.csv, overlay-manifest.json, provenance.json and test_kit.py. The distributor supplies the pinned core and handoff helper; neither a private worker nor a repository checkout is required. No generator or prebuilt inputs helper is needed: both payloads are embedded in the recipe.

The active archive contains a flat list of regular file members (no directory entries, nested archives, symlinks or project/inputs/): one selected recipe and its active SVGs only. Both ZIPs start with project/. From the kit root, unpack core first, then the active overlay into the same kit root, not into project/ again:

python3 -m zipfile -e core-publication-v08.zip .
python3 -m zipfile -e active-assets.zip .
python3 handoff.py verify --guide guide.json --project project
python3 handoff.py frames --guide guide.json --project project > controls-regenerated.csv
cmp controls.csv controls-regenerated.csv
PYTHONDONTWRITEBYTECODE=1 python3 test_kit.py --project project --core core-publication-v08.zip

Integrity contracts (SHA-256):

Artifact SHA-256
Core ZIP 307fb6b927e35e6d73779652873d994f5c3e36cb7deba65f22fa64748057a0de
Active ZIP e31d40eeab431c4707a7d6d7e38ddc9dd7809c1ec8ad7fb0de899e7bc86b6ed9
Recipe b0751bf0185ee0d80d59db032657a1e67cdd5818a406dad177938cf612c082e0
Guide 69b60ab5f7fe4e40b2e00e21f2d4455a5d4fcbfdff5e1dcd29b7332665f0060d
Handoff helper dedfeaefb89a3158c060f092d9393fe208a52f88b51e21e8bd06c8b272a25721

overlay-manifest.json binds every active recipe/SVG ZIP member and every guide/control/provenance artifact. The active ZIP has only this recipe and its 4 original SVGs, no core, dependencies or legacy art. source.localMedia is research metadata, not a requested input path.

Remotion: preflight, then authorized rendering

Read project/README.md and project/AGENT_GUIDE.md. Use Node >=22.18, Python 3.11+, FFmpeg/FFprobe and an explicitly installed supported Chromium. Preserve project/public/fonts/Geist.ttf and its OFL.txt; do not replace the font or silently shrink text. The core browser text-fit gate remains authoritative. Set REMOTION_BROWSER_EXECUTABLE if your installed browser is not discovered. No automatic browser download is required by these instructions.

From project/, the actual archived CLI is:

cd project
npm ci
node --experimental-strip-types --input-type=module -e '
import {prepareInput} from "./scripts/lib.mjs";
for (const variant of ["default", "adaptation"]) {
  const prepared = await prepareInput({projectRoot: process.cwd(), recipeId: "layer-insert-resize-place", variant});
  console.log(variant, prepared.expected);
}
'
node --experimental-strip-types scripts/render.mjs --recipe layer-insert-resize-place --variant default --out out/layer-insert-resize-place-default.mp4
node --experimental-strip-types scripts/render.mjs --recipe layer-insert-resize-place --variant adaptation --out out/layer-insert-resize-place-adaptation.mp4
node --experimental-strip-types scripts/verify.mjs out/layer-insert-resize-place-default.mp4
node --experimental-strip-types scripts/verify.mjs out/layer-insert-resize-place-adaptation.mp4

Expected: 1920×1080, 24000/1001 fps, 152 frames, 19019/3000 seconds (6.339666667), zero audio streams. The renderer refuses an existing MP4 or its sibling manifest; choose a new basename instead of overwriting. Keep each generated .manifest.json with its output. These commands are for the authorized renderer: this builder did not encode or review candidate output.

Content substitutions

Default: an original travel case and mountain/compass badge. Adaptation: an original seed crate and leaf badge. Both change the context and the cutout silhouette, not just a palette. There is no live text in this treatment; the three colors control pointer, handles and cropped toolbar, while SVG colors are explicit editable primitive fills.

Every slot, both literal payloads, consuming layers and field contracts appear under guide.json.editableSubstitutions. Keep the same number of rows/items, literal line breaks, aspect ratios and range/camera parenting. Character limits are not a font-fit guarantee. For custom SVGs use original permitted geometry, no <image>, raster data URI, external resource, script, embedded font or source frame. Inspect both content and framing after every edit.

From project/, create a complete Content object, not a partial override:

python3 - <<'PY'
import json
from pathlib import Path
recipe = json.loads(Path("recipes/layer-insert-resize-place.json").read_text())
content = dict(recipe["defaults"])
content["accent"] = "#a86d35"
Path("custom.json").write_text(json.dumps(content, indent=2) + "\n")
PY
node --experimental-strip-types --input-type=module -e '
import {prepareInput} from "./scripts/lib.mjs";
console.log((await prepareInput({projectRoot: process.cwd(), recipeId: "layer-insert-resize-place", contentPath: "custom.json"})).expected);
'
node --experimental-strip-types scripts/render.mjs --recipe layer-insert-resize-place --content custom.json --out out/layer-insert-resize-place-custom.mp4

--content and --variant are mutually exclusive. Relative content paths are resolved against the process working directory; the example deliberately runs inside project/. The frozen guide verifies the embedded variants. A changed recipe or SVG requires a revised hash contract; do not relabel it as this freeze.

Source clock, observation and adaptation

Film: Transparent Layers with 4o Image Generation. Retained official-player publication: 2025-03-25, timestamp 2025-03-25T11:19:55-07:00. This is pinned local metadata, not a new live web verification. Selection window: September 5, 2024 through September 5, 2026 at 17:13:40.602033 UTC; no later publication is used.

Source interval [1506, 1658) at 24000/1001, with exact nominal source seconds [251251/4000, 829829/12000). Local frame zero = source 1506; last local frame 151 = source 1657. Excerpt offset is zero. The retained source-relative clock (16000 ticks/second) and all 152 PTS/durations are preserved verbatim. Every separately probed excerpt PTS and duration agrees as a rational time. Nominal 24000/1001 and encoded average 486400/20287 are not interchangeable; the coded excerpt duration is 6.339688 seconds, not the exact nominal 19019/3000 seconds. Absolute master PTS remain unknown. guide.json.encodedExcerptClock records actual retained-excerpt PTS, time base, frame durations and coded stream rate separately. Do not round the source nominal cadence, substitute an excerpt average rate, or stretch to another rate.

Research excerpt SHA-256: 980782ed963997285072ec40eeff97ecc72679deb12c7148a4598e8016833c12. The source master SHA is inherited, not freshly rehashed. The source/timing unit and related implementation file hashes are in provenance.json. Related Edit/ObjectContext and its partial Resolve guide supplied parenting/masking concepts, not a complete adapter.

Inspection: all 152 excerpt frames viewed statically as consecutively decoded 480×270 thumbnails, plus 6 selected 1920×1080 native-size stills. The 1920×1080 output canvas is an authored delivery choice; excerpt dimensions are not a master probe. Contact sheets are not moving review or all-frame full-resolution inspection. No whole-film/new-coverage claim, native Resolve execution, exact source-quality approval or measured OpenAI props is made.

Authored choreography

  1. Local 0–32: stationary context only. The oversized transparent badge enters at 33. Eight selection handles appear at 42; the brief upper toolbar sliver ends at 46.
  2. 72–78: drag the selected badge downward, intentionally carrying its bottom outside the final picture. Keep the case/crate stationary.
  3. 101–107: shrink the badge from 1.10 to 0.56 while its lower selection anchor remains at y=1225. Local 108 still clips the lower badge. Keep handles constant-size and do not mask to the context.
  4. 127–135: move the smaller badge upward and slightly right, onto the lower-left region. Retain selection through 151 and change the pointer back to a diagonal resize pose. Do not add a deselection, save action or finished loop.

Visible-state brackets are source observations/estimates; all numeric tracks are chosen adaptation values. guide.json.observationPolicy keeps those categories separate. The following samples are checkpoints to inspect, not assertions that a rendered output already passed:

Local frame Source frame Nominal source seconds Expected authored state
0 1506 62.812750 Context only; no badge.
32 1538 64.147417 Last context-only frame.
33 1539 64.189125 Oversized badge inserted.
42 1548 64.564500 Eight selected-layer handles.
72 1578 65.815750 Downward drag begins.
77 1583 66.024292 Badge crosses lower output edge.
101 1607 67.025292 Resize begins with lower anchor y=1225.
107 1613 67.275542 Resize reaches scale 0.56; still low.
108 1614 67.317250 Intentional lower-edge clipping.
127 1633 68.109708 Placement begins, not a snap fit.
135 1641 68.443375 Smaller badge placed, handles remain.
151 1657 69.110708 Selected layer and resize cursor at cutoff.

Resolve / Fusion construction

  1. Create a 1920×1080, square-pixel composition at 24000/1001, local frames 0–151 inclusive. Set the actual rational cadence, not a rounded integer substitute. Do not add a final hold. Keep audio empty.
  2. Work on transparent 4096×4096 domains, with design pixel (0,0) placed at work pixel (1024,1024). Parent/child domains stay identical. Build the opaque RootPaper Background and nodes listed below in order; later siblings are foreground. guide.json.rootPipeline supplies its color/domain, final crop coordinates and MediaOut connection. nativePalette supplies normalized RGB values for editable colors in both variants; use opacity separately.
  3. For each layer build Construct → LocalMask → AnchorShift → ScaleRotate → Position → Gated → Merge.Foreground; the previous sibling feeds Merge.Background. For a group, Construct is its ordered child merges over a transparent background. Apply group alpha once after assembly.
  4. guide.json.fusionNodes names every tool, connection, parent, raw/static control, content binding and gate. svgSubgraphs enumerates every original SVG Rectangle/Ellipse/Polygon, color, alpha and merge order for both variants. Build those natively; do not rasterize SVGs or use source footage as Loaders.
  5. Bake the numeric rows in fusion-controls.csv at each integer local frame. Its AnchorShift/Position/ScaleRotate/Gated columns are derived below. controls.csv contains every raw property sample, including independent width/radius tracks. Neither CSV is an importable .setting file: transfer columns to the named native controls using frame-based keys.
  6. Install the licensed bundled Geist. Use Text+ for text, the explicit weight, pixel box, line advance, tracking and alignment in each node. Text+ Size fontSize/4096 is only an uncalibrated starting estimate, not a verified CSS conversion. Compare glyph footprint, baseline and fit natively before delivery. Retain literal line breaks and stepped character reveals. Never scale type down just to hide overflow.
  7. After the last root merge, crop exactly work pixels x=[1024,2944), y=[1024,2104) to 1920×1080; do not resize. Send to MediaOut. Keep anything outside the final crop until this final operation, except declared local masks.

Coordinates and interpolation

Treatment-specific hierarchy

The context and contact-shadow ellipses are independent of selected-layer. selected-layer owns only badge-art. Eight sibling handle nodes use x+u1000scale and y+v1000scale, subtracting a 4px radius; they do not scale with the badge. Local 101–107 preserves y+1000*scale=1225. Pointer pose groups are mutually gated; their filled Polygon sublayers provide outlines without OS cursor assets. Only the final output crop clips the excursion. No caret, text reveal, selection-border stroke or hidden upload state is present.

RootPaper -> ordered root merges -> FinalCrop -> MediaOut
table [rect] -> table_Merge
context-shadow-2 [ellipse] -> context-shadow-2_Merge
context-shadow-1 [ellipse] -> context-shadow-1_Merge
context-shadow-0 [ellipse] -> context-shadow-0_Merge
context-art [image] -> context-art_Merge
selected-layer [group] -> selected-layer_Merge
  badge-art [image] -> badge-art_Merge
handle-0 [ellipse] -> handle-0_Merge
handle-1 [ellipse] -> handle-1_Merge
handle-2 [ellipse] -> handle-2_Merge
handle-3 [ellipse] -> handle-3_Merge
handle-4 [ellipse] -> handle-4_Merge
handle-5 [ellipse] -> handle-5_Merge
handle-6 [ellipse] -> handle-6_Merge
handle-7 [ellipse] -> handle-7_Merge
toolbar-sliver [rect] -> toolbar-sliver_Merge
toolbar-left [rect] -> toolbar-left_Merge
toolbar-right [rect] -> toolbar-right_Merge
approach-hand [group] -> approach-hand_Merge
  approach-hand-outline [path] -> approach-hand-outline_Merge
  approach-hand-mark [path] -> approach-hand-mark_Merge
handle-approach [group] -> handle-approach_Merge
  handle-approach-outline [path] -> handle-approach-outline_Merge
  handle-approach-mark [path] -> handle-approach-mark_Merge
resize-pointer [group] -> resize-pointer_Merge
  resize-pointer-outline [path] -> resize-pointer-outline_Merge
  resize-pointer-mark [path] -> resize-pointer-mark_Merge
place-pointer [group] -> place-pointer_Merge
  place-pointer-outline [path] -> place-pointer-outline_Merge
  place-pointer-mark [path] -> place-pointer-mark_Merge
final-resize-pointer [group] -> final-resize-pointer_Merge
  final-resize-pointer-outline [path] -> final-resize-pointer-outline_Merge
  final-resize-pointer-mark [path] -> final-resize-pointer-mark_Merge

Animated controls

Every static numeric/text/shape control remains in guide.json.fusionNodes; this short table lists animated controls only. The complete raw key arrays and per-frame values are in the guide and CSVs.

Layer.property Keys Numeric minimum → maximum
selected-layer.x 8 410 → 440
selected-layer.y 8 -20 → 665
selected-layer.scale 8 0.56 → 1.1
handle-0.x 8 406.0 → 436.0
handle-0.y 8 -24.0 → 661.0
handle-1.x 8 686.0 → 956.0
handle-1.y 8 -24.0 → 661.0
handle-2.x 8 966.0 → 1506.0
handle-2.y 8 -24.0 → 661.0
handle-3.x 8 406.0 → 436.0
handle-3.y 8 526.0 → 941.0
handle-4.x 8 966.0 → 1506.0
handle-4.y 8 526.0 → 941.0
handle-5.x 8 406.0 → 436.0
handle-5.y 8 896.0 → 1221.0
handle-6.x 8 686.0 → 956.0
handle-6.y 8 896.0 → 1221.0
handle-7.x 8 966.0 → 1506.0
handle-7.y 8 896.0 → 1221.0
approach-hand.x 4 1270 → 1450
approach-hand.y 4 25 → 680
handle-approach.x 2 1470 → 1490
handle-approach.y 2 122 → 350
resize-pointer.x 5 710 → 1490
resize-pointer.y 5 122 → 900
place-pointer.x 3 710 → 980
place-pointer.y 3 390 → 900

Differences and acceptance limits

Largest gap: the film is a photograph plus a different illustrated sticker; this is a deliberately flat, original case/crate and geometric badge. No source silhouette is traced. Three hard-edged translucent ellipses approximate context contact shadow rather than photographic lighting. Pointer paths, antialiasing, capture-toolbar slivers and placements are authored approximations; only the bounded action structure and nominal clock are retained.

The builder has not executed Resolve or reviewed moving candidate output. Archive hashes, schema checks, sampled controls and custom-content preflights cannot validate native antialiasing, Text+ layout, browser shaping, occlusion readability or motion quality. Parent rendering and independent comparison are separate acceptance gates. Source quality remains false until that process explicitly establishes otherwise. No corpus or publication count is changed.

Optional provenance audits may resolve the repo: and accepted-stage: bindings in provenance.json against the retained research archive. Those historical sources are not needed to install, preflight, render or manually construct this public kit, and may never become adaptation inputs.