OpenAI Film Fieldnotes

Candidate construction guide · native Resolve not tested

Evidence first, answer second

An original SVG/code Remotion recipe and a complete manual DaVinci Resolve / Fusion handoff. One source-grounded treatment, two original content variants. This is a candidate, not source-fidelity acceptance or a tested native .setting. This worker did not render an output or run Resolve. Later parent renders need their own hashes/review; this statement is not a claim about the parent's current queue.

Public download: prepare once

Use a fresh kit directory. The public package supplies core-publication-v08.zip, active-assets.zip, handoff.py, this README, guide.json, controls.csv, fusion-controls.csv, overlay-manifest.json, provenance.json, and test_kit.py. No private worker, repository checkout, generator, source clip or inputs/ helper is needed. This overlay contains only this recipe and its active original SVGs. Both content variants are embedded in the recipe. Do not add old raster/video ZIPs.

# Run in the downloaded kit root. Both ZIPs contain project/ at their top level.
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

Do not unpack either ZIP into project/ again: that creates project/project/. Core first, overlay second. The public tests verify the exact ZIP members and hashes; the handoff command verifies the recipe, native clock and selected SVG bytes only.

Remotion: parent or recipient renders

Prerequisites: Node ≥22.18, Python 3, FFmpeg/FFprobe and an explicitly installed supported Chromium. Preserve the pinned package lock and core README. Rendering does not auto-download a browser; set REMOTION_BROWSER_EXECUTABLE to its existing executable when needed. Do not place persistent browser profiles in an evidence tree.

cd project
npm ci
node --experimental-strip-types scripts/render.mjs --recipe knowledge-source-stagger --variant default --out out/knowledge-source-stagger-default.mp4
node --experimental-strip-types scripts/render.mjs --recipe knowledge-source-stagger --variant adaptation --out out/knowledge-source-stagger-adaptation.mp4
node --experimental-strip-types scripts/verify.mjs out/knowledge-source-stagger-default.mp4
node --experimental-strip-types scripts/verify.mjs out/knowledge-source-stagger-adaptation.mp4

Expected: 1920×1080, 60/1 fps, 300 frames, no audio. Keep each adjacent .manifest.json with its MP4. The renderer refuses pre-existing outputs; use a fresh filename for each revision. Do not add holds to synchronized comparisons. These are the actual commands from the archived renderer, not a hypothetical API.

Change the content, not the clock

default: a shared-workshop recap with warm green/orange source marks; adaptation: a gallery planning note with blue/purple archive marks. Counts are fictional 6–9 notes versus 8–11 items, not retrieval results.

Every string/color/media slot and its contract is in recipe.fields and in guide.json → editableSubstitutions. Text is live Geist from the core's public/fonts/Geist.ttf; retain public/fonts/OFL.txt. Do not use a system fallback. SVG art has no text, raster, external links or font dependency. Replace it with your own standalone SVG at the declared viewport/aspect ratio and with an accurate rights declaration. Do not flatten or trace source footage.

To make a custom JSON, run from project/:

python3 - <<'PY'
import json
from pathlib import Path
recipe = json.loads(Path('recipes/knowledge-source-stagger.json').read_text())
content = recipe['defaults']
content['title1'] = 'Studio notes'
Path('inputs').mkdir(exist_ok=True)
Path('inputs/my-content.json').write_text(json.dumps(content, indent=2) + '\n')
PY
node --experimental-strip-types --input-type=module - <<'JS'
import {prepareInput} from './scripts/lib.mjs';
const checked = await prepareInput({projectRoot: process.cwd(), recipeId: 'knowledge-source-stagger', contentPath: 'inputs/my-content.json'});
console.log(checked.expected, checked.assets);
JS
node --experimental-strip-types scripts/render.mjs --recipe knowledge-source-stagger --content inputs/my-content.json --out out/my-content.mp4
node --experimental-strip-types scripts/verify.mjs out/my-content.mp4

The custom-content preflight does not render, measure browser glyphs or execute Resolve. It checks the real core input contract and asset bytes. The renderer's font gate then rejects overflowing lines; shorten copy, never shrink or retime it. Custom assets are no longer the frozen guide.svgAssets contract: retain their new render manifest and review the substitution. handoff.py verify still verifies the two frozen built-in variants, not an arbitrary custom JSON. SVG-only policy is stricter than the core's general media API; run the supplied test's SVG checker or inspect replacement SVG resources before using new artwork.

The offline tests also check nominal advances from the actual archived Geist cmap/hmtx tables and all text-box heights. This is an unshaped default-font metric check, not the renderer's browser shaping or a Resolve Text+ fit verdict.

Source and clock

Research film: Work smarter with your company knowledge in ChatGPT. The film link, publication date (2025-10-23) and master SHA are retained queue metadata, not a new online lookup. Only the accepted excerpt was rehashed and inspected. Master SHA: 88ba469d8878090a68e97474a743107b7bc25a52c1adf0d520816ba2dc665077 (inherited, not rehashed). Excerpt SHA: 32246d9573d6bd4e95bb9a0029b8cb5da5836b5dfe55fa1d1bbddd8df5cedf4e.

Source window [1500, 1800) = 25–30 seconds. Local frame f maps to source frame 1500 + f and excerpt frame f (zero lead offset). Seconds are exact frame/60 arithmetic, not newly measured source PTS. Header/decode checks confirm 60/1 and 300 consecutive excerpt frames. The retained study's 2ms PTS statement is inherited, not a new master-PTS check.

All frames were viewed statically in ordered 480×270 labeled sheets; selected boundary/cutoff stills were also viewed at native excerpt resolution 960×540. That is not moving-source review, not full-resolution viewing of every frame, not full-film inspection, and not evidence of source-quality equivalence. provenance.json binds each sheet range/hash and native still ordinal/hash without shipping research images as presentation inputs. Positions, easing and styling below are chosen adaptation values; only explicitly labeled cut observations are frame-exact.

Choreography

  1. 0–3: brief finding status. First card gates at 4, second at 34, each with a 12-frame rise/fade.
  2. 0–72: enlarged source view; parent moves upward at 59–72. At 73, scale jumps 1.6→1 and the request/context appears. Do not interpolate across this cut.
  3. 74–86: third source arrives; 73–95: the wide context settles. Count badge starts at 134 and its payload switches at 143, 153 and 163 independently of card timing.
  4. 187: status and working note change. Answer lines start at 187/203; heading at 248; four detail lines at 264/280/288/296. The parent scrolls 0→−310px over 248–299, clipping the request above the frame. No completion hold.

Fusion: complete manual construction

  1. Set composition/output 1920×1080, square pixels, 60 fps, local frames 0–299 inclusive. Disable optical flow, motion blur and automatic retiming. No MediaIn of the research clip. resolveApplicationVerified remains false.
  2. Work every intermediate branch on a transparent 4096×4096 square domain, padding the design origin by (1024,1024). This preserves negative positions and child overflow. Do not crop each branch to 1920×1080. The phone viewport clips long content before parent camera magnification. Final crop only after the root merge: design rectangle starts at (1024,1024), size 1920×1080, with no resize. Composite over opaque white RootPaper, then MediaOut1.
  3. Construct the hierarchy below back to front at every level. Each child finishes into its parent's transparent merge chain. The last child output feeds that group's Construct, then its own mask/transform/alpha. guide.fusionNodes lists every node, connection, raw/static control, parent and effective frame gate. guide.svgSubgraphs lists every original primitive, geometry, fill and connection for both variants. Instantiate native Rectangle/Ellipse/Polygon + Background + Merge branches; no raster stand-in. SVG contain fitting precedes its box transform.
  4. Coordinate rule: recipe pixels use top-left origin, +X right, +Y down. Fusion mask position is ((x+1024)/4096, 1-(y+1024)/4096); width/height normalize by 4096. Local geometry is built before its layer transform. Radius is pixels: clamp to half the smaller dimension. Build rounded masks as a union of a (r,0,w−2r,h) rectangle, a (0,r,w,h−2r) rectangle and four radius-r circles centered at (r,r), (w−r,r), (r,h−r), (w−r,h−r). Union/clamp mask alpha; do not sum overlapping paint. At r=0 use one rectangle. Polygon vertices use the same normalization; preserve path subpath winding/holes. Intersect overflow:hidden rounded bounds and clip insets locally. A plain group width/height or radius does not clip unless declared. Borders are inside the box.
  5. Exact transform order avoids Fusion pivot ambiguity. Let local origin o be layer.origin, default (0,0), and working design center c=(1024,1024). AnchorShift translates by c−o; ScaleRotate has Center/Pivot (.5,.5), Size=scale, Angle=−rotation; Position translates by (x,y)+o−c. A translation (dx,dy) has Center (.5+dx/4096, .5−dy/4096). This gives parentPoint=(x,y)+o+R_clockwise(rotation)*scale*(point−o). These kits use uniform scale only. Apply Gated Merge Blend=active*opacity once after assembly, not to each child. Active is 1 only when the layer and every ancestor contain the local frame. End gates are exclusive.
  6. Text+ uses the exact live content, font weight, box, line advance and tracking in each node's textControls. The listed fontSize/4096 is only a starting Size estimate, not a calibrated conversion. Match actual glyph footprint and baseline using licensed Geist before review. Do not auto-fit, outline source lettering, or imply native typography equivalence. Reveal steps key StyledText on the same global frame clock, including prefix/suffix. No child-clock reset.
  7. controls.csv gives every present recipe numeric property at every native frame; fusion-controls.csv additionally gives every layer's numeric AnchorShift, ScaleRotate, Position, Blend, size, radius and clip inputs at every frame. Use those values as frame-by-frame linear baked keys; they are not measured source controls. Between sparse recipe keys, ease according to the left key: smooth=t*t*(3-2*t), linear=t, hold=left value until the exact right key. A Bézier preset is not a substitute. Preserve the declared one-frame cuts.
  8. Select all content/colors/art from one variant. Check all checkpoints, then compare an actual Resolve render against Remotion and the allowed source excerpt at native cadence. Native Resolve execution and moving comparison remain open.
RootPaper (opaque white working-domain Background)
evidence-scene [group] -> evidence-scene_Merge
  request [group] -> request_Merge
    request-bg [rect] -> request-bg_Merge
    request-copy [text] -> request-copy_Merge
  search-status [text] -> search-status_Merge
  reading-one [text] -> reading-one_Merge
  reading-two [text] -> reading-two_Merge
  summarizing [text] -> summarizing_Merge
  checked-status [text] -> checked-status_Merge
  source-card-0 [group] -> source-card-0_Merge
    card-0-bg [rect] -> card-0-bg_Merge
    card-0-badge [image] -> card-0-badge_Merge
    card-0-category [text] -> card-0-category_Merge
    card-0-title [text] -> card-0-title_Merge
  source-card-1 [group] -> source-card-1_Merge
    card-1-bg [rect] -> card-1-bg_Merge
    card-1-badge [image] -> card-1-badge_Merge
    card-1-category [text] -> card-1-category_Merge
    card-1-title [text] -> card-1-title_Merge
  source-card-2 [group] -> source-card-2_Merge
    card-2-bg [rect] -> card-2-bg_Merge
    card-2-badge [image] -> card-2-badge_Merge
    card-2-category [text] -> card-2-category_Merge
    card-2-title [text] -> card-2-title_Merge
  source-count [group] -> source-count_Merge
    count-bg [rect] -> count-bg_Merge
    count-mark-0 [image] -> count-mark-0_Merge
    count-mark-1 [image] -> count-mark-1_Merge
    count-mark-2 [image] -> count-mark-2_Merge
    count-0 [text] -> count-0_Merge
    count-1 [text] -> count-1_Merge
    count-2 [text] -> count-2_Merge
    count-3 [text] -> count-3_Merge
  working-note [text] -> working-note_Merge
  answer1 [text] -> answer1_Merge
  answer2 [text] -> answer2_Merge
  heading [text] -> heading_Merge
  detail1 [text] -> detail1_Merge
  detail2 [text] -> detail2_Merge
  detail3 [text] -> detail3_Merge
  detail4 [text] -> detail4_Merge
Final crop (1024,1024,1920,1080; no resize) -> MediaOut1

Animated controls

All static values and every original key are also present in guide.json.

Layer.property Keys Authored value range
evidence-scene.x 2 -8 → 0
evidence-scene.y 7 -368 → 110
evidence-scene.scale 2 1 → 1.6
source-card-0.y 2 480 → 496
source-card-0.opacity 2 0 → 1
source-card-1.y 2 480 → 496
source-card-1.opacity 2 0 → 1
source-card-2.y 2 480 → 496
source-card-2.opacity 2 0 → 1
source-count.opacity 2 0 → 1
answer1.opacity 2 0 → 1
answer2.opacity 2 0 → 1
heading.opacity 2 0 → 1
detail1.opacity 2 0 → 1
detail2.opacity 2 0 → 1
detail3.opacity 2 0 → 1
detail4.opacity 2 0 → 1

Checkpoints

Local / excerpt frame Source frame Frame-derived source seconds Expected candidate state
0 1500 25.000000 Finding state, enlarged source region.
4 1504 25.066667 First source group opens; alpha begins at zero.
15 1515 25.250000 First source nearly opaque.
34 1534 25.566667 Second source opens independently.
46 1546 25.766667 Two source cards present.
72 1572 26.200000 Last close view; preserve the following cut.
73 1573 26.216667 Wider request/status composition appears in one frame.
86 1586 26.433333 Third source fully visible.
95 1595 26.583333 Wide-context settling finishes.
134 1634 27.233333 Count badge begins independently.
143 1643 27.383333 Second fictional count.
153 1653 27.550000 Third fictional count.
163 1663 27.716667 Final fictional count.
186 1686 28.100000 Working note still present.
187 1687 28.116667 Checked status and first answer gate replace working note.
203 1703 28.383333 Second answer line starts.
217 1717 28.616667 Two answer lines remain below sources.
248 1748 29.133333 Heading begins and upward travel resumes.
264 1764 29.400000 First detail line starts.
280 1780 29.666667 Second detail line starts.
299 1799 29.983333 Request is cropped above; detail continues at cutoff.

Differences and open review

Largest gap: Provider marks, exact status-word highlights, source counts and answer content are replaced. Soft entrance/streaming curves and the late scroll distance are authored approximations; the original answer has inline citations and emphasis that this plain live-type draft omits.

Common open gates: browser text shaping, antialiasing, actual moving-output comparison, native Fusion text/mask calibration, and native Resolve execution. No source image was traced or flattened. No source-master download, video render, dependency copy, deployment, shared-state edit or completion-count credit is part of this build.

Immutable preparation contract

From kit root, after preparation, run python3 test_kit.py --project project --core core-publication-v08.zip. This runs focused offline checks and actual-core default/adaptation/custom-content preflights, with negative content cases. No browser, Resolve or video encoding. Repository/provenance replay is optional historical auditing; source clips and the private worker are never prerequisites for rendering or this public handoff.