OpenAI Film Fieldnotes

Candidate construction guide · native Resolve not tested

Change a chart representation without losing context

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 9bbae66a507800bf4a92ebdb632a4f0cd7fafd67665bbfd0779444ed9aa1bf2d
Recipe af910c42ed33bf191b0b6c3be9a2dcc5610e79535ab9b5bfe80e7af25d3dd37a
Guide 128e8c6fd8d45ade05a627d941004cd634391ae5cbd71238e4d8ca3a5b1d848c
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: "chart-representation-change", variant});
  console.log(variant, prepared.expected);
}
'
node --experimental-strip-types scripts/render.mjs --recipe chart-representation-change --variant default --out out/chart-representation-change-default.mp4
node --experimental-strip-types scripts/render.mjs --recipe chart-representation-change --variant adaptation --out out/chart-representation-change-adaptation.mp4
node --experimental-strip-types scripts/verify.mjs out/chart-representation-change-default.mp4
node --experimental-strip-types scripts/verify.mjs out/chart-representation-change-adaptation.mp4

Expected: 1920×1080, 60/1 fps, 360 frames, 6 seconds (6.000000000), 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: workshop bench utilization across 30 sessions. Adaptation: nursery bloom percentages across 30 trays. Titles, units, tooltip values, neighboring notes and every original chart point change. Each pair of line/bar SVGs comes from exactly the same variant dataset. guide.json.originalData gives the authored numbers and SVG mapping; it is audit metadata, not a runtime generator. To change numeric data, update both SVGs and the tooltip together using that mapping; changing metadata alone does not redraw a chart.

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/chart-representation-change.json").read_text())
content = dict(recipe["defaults"])
content["title"] = "Workshop session overview"
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: "chart-representation-change", contentPath: "custom.json"})).expected);
'
node --experimental-strip-types scripts/render.mjs --recipe chart-representation-change --content custom.json --out out/chart-representation-change-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: Codex for data science. Retained official-player publication: 2026-06-09, timestamp 2026-06-09T14:30:13-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 [2280, 2640) at 60/1, with exact nominal source seconds [38, 44). Local frame zero = source 2280; last local frame 359 = source 2639. Excerpt offset is zero. The selected unit declares nominal native 60/1 but supplies no retained master/source-relative PTS clock: retained_source_clock stays null. The excerpt is separately probed at 1/15360 time base with PTS increments of 256. These encoded excerpt timestamps are not proof of the missing master clock. Absolute master PTS and master dimensions 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: bb80446d8ddd770e59fc4555f3eb1a56bc285d8c7a44405286c76742835b1f01. The source master SHA is inherited, not freshly rehashed. The source/timing unit and related implementation file hashes are in provenance.json. Related Edit/FocusType and its partial Resolve guide supplied parenting/masking concepts, not a complete adapter.

Inspection: all 360 excerpt frames viewed statically as consecutively decoded 480×270 thumbnails, plus 6 selected 960×540 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–48: line chart and reset-area hand cursor. 48–115: the cursor crosses to the representation control; labels stay in place.
  2. 119–126: menu fades from 0.30 to 1.00. It remains over the same chart. At 146 the cursor switches to an arrow; it descends and switches back to a hand at 211.
  3. Local 239 still shows line plus menu. At 240, hide both and expose bars, the grouped/orientation row and tooltip in one frame. No line-to-bar morph, crossfade, click pulse or loading screen is invented.
  4. 270–320: a small whole-pane pullback exposes neighboring notes; tooltip remains. The hand fades and reappears, then switches to an arrow for 357–359. Stop there without another selection.

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 2280 38.000000 Line chart; pointer near reset.
48 2328 38.800000 Pointer begins crossing.
115 2395 39.916667 Pointer at representation control.
119 2399 39.983333 Menu first visible, translucent.
126 2406 40.100000 Opaque menu over unchanged line.
146 2426 40.433333 Arrow starts menu traversal.
211 2491 41.516667 Hand targets bar row.
239 2519 41.983333 Last line/menu frame.
240 2520 42.000000 Bars, new controls and tooltip; no menu.
275 2555 42.583333 Small pullback under way.
320 2600 43.333333 Pulled-back chart with neighbor visible.
357 2637 43.950000 Arrow pose at early-bar tooltip.
359 2639 43.983333 Cutoff: tooltip persists, no new action.

Resolve / Fusion construction

  1. Create a 1920×1080, square-pixel composition at 60/1, local frames 0–359 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

chart-camera owns the neighboring pane, main paper, persistent title/axes, both mutually exclusive chart states, menu, tooltip and all cursor groups. Its pivot is (1850,0); scale 1→0.93 is on this parent, not on text-box widths. representation-menu has one group alpha after opaque child assembly. line-state ends exactly when bar-state starts; the series row uses the same boundary. The tooltip covers early bars and is not clipped to the plot. No text typing, caret or native chart plugin is used; all plotted geometry is editable SVG primitives.

RootPaper -> ordered root merges -> FinalCrop -> MediaOut
chart-camera [group] -> chart-camera_Merge
  neighbor-paper [rect] -> neighbor-paper_Merge
  neighbor-copy [text] -> neighbor-copy_Merge
  main-paper [rect] -> main-paper_Merge
  chart-title [text] -> chart-title_Merge
  line-type [group] -> line-type_Merge
    line-type-paper [rect] -> line-type-paper_Merge
    line-type-label [text] -> line-type-label_Merge
    line-type-chevron [path] -> line-type-chevron_Merge
  bar-type [group] -> bar-type_Merge
    bar-type-paper [rect] -> bar-type-paper_Merge
    bar-type-label [text] -> bar-type-label_Merge
    bar-type-chevron [path] -> bar-type-chevron_Merge
  x-control [group] -> x-control_Merge
    x-control-paper [rect] -> x-control-paper_Merge
    x-control-label [text] -> x-control-label_Merge
    x-control-chevron [path] -> x-control-chevron_Merge
  y-control [group] -> y-control_Merge
    y-control-paper [rect] -> y-control-paper_Merge
    y-control-label [text] -> y-control-label_Merge
    y-control-chevron [path] -> y-control-chevron_Merge
  series-control [group] -> series-control_Merge
    series-control-paper [rect] -> series-control-paper_Merge
    series-control-label [text] -> series-control-label_Merge
    series-control-chevron [path] -> series-control-chevron_Merge
  group-control [group] -> group-control_Merge
    group-control-paper [rect] -> group-control-paper_Merge
    group-control-label [text] -> group-control-label_Merge
    group-control-chevron [path] -> group-control-chevron_Merge
  orientation-control [text] -> orientation-control_Merge
  reset-label [text] -> reset-label_Merge
  grid-0 [rect] -> grid-0_Merge
  y-label-0 [text] -> y-label-0_Merge
  grid-1 [rect] -> grid-1_Merge
  y-label-1 [text] -> y-label-1_Merge
  grid-2 [rect] -> grid-2_Merge
  y-label-2 [text] -> y-label-2_Merge
  grid-3 [rect] -> grid-3_Merge
  y-label-3 [text] -> y-label-3_Merge
  grid-4 [rect] -> grid-4_Merge
  y-label-4 [text] -> y-label-4_Merge
  line-state [image] -> line-state_Merge
  bar-state [image] -> bar-state_Merge
  x-label-0 [text] -> x-label-0_Merge
  x-label-1 [text] -> x-label-1_Merge
  x-label-2 [text] -> x-label-2_Merge
  x-label-3 [text] -> x-label-3_Merge
  x-label-4 [text] -> x-label-4_Merge
  x-label-5 [text] -> x-label-5_Merge
  x-label-6 [text] -> x-label-6_Merge
  axis-title [text] -> axis-title_Merge
  representation-menu [group] -> representation-menu_Merge
    menu-shadow [rect] -> menu-shadow_Merge
    menu-paper [rect] -> menu-paper_Merge
    menu-trends [text] -> menu-trends_Merge
    menu-label-0 [text] -> menu-label-0_Merge
    menu-icon-0-0 [rect] -> menu-icon-0-0_Merge
    menu-icon-0-1 [rect] -> menu-icon-0-1_Merge
    menu-icon-0-2 [rect] -> menu-icon-0-2_Merge
    menu-label-1 [text] -> menu-label-1_Merge
    menu-icon-1-0 [rect] -> menu-icon-1-0_Merge
    menu-icon-1-1 [rect] -> menu-icon-1-1_Merge
    menu-icon-1-2 [rect] -> menu-icon-1-2_Merge
    menu-label-2 [text] -> menu-label-2_Merge
    menu-icon-2-0 [rect] -> menu-icon-2-0_Merge
    menu-icon-2-1 [rect] -> menu-icon-2-1_Merge
    menu-icon-2-2 [rect] -> menu-icon-2-2_Merge
    menu-label-3 [text] -> menu-label-3_Merge
    menu-icon-3-0 [rect] -> menu-icon-3-0_Merge
    menu-icon-3-1 [rect] -> menu-icon-3-1_Merge
    menu-icon-3-2 [rect] -> menu-icon-3-2_Merge
    menu-label-4 [text] -> menu-label-4_Merge
    menu-icon-4-0 [rect] -> menu-icon-4-0_Merge
    menu-icon-4-1 [rect] -> menu-icon-4-1_Merge
    menu-icon-4-2 [rect] -> menu-icon-4-2_Merge
    menu-label-5 [text] -> menu-label-5_Merge
    menu-icon-5-0 [rect] -> menu-icon-5-0_Merge
    menu-icon-5-1 [rect] -> menu-icon-5-1_Merge
    menu-icon-5-2 [rect] -> menu-icon-5-2_Merge
    selected-line-check [path] -> selected-line-check_Merge
    menu-divider [rect] -> menu-divider_Merge
    menu-compare [text] -> menu-compare_Merge
    menu-divider-bottom [rect] -> menu-divider-bottom_Merge
    menu-distribution [text] -> menu-distribution_Merge
  bar-tooltip [group] -> bar-tooltip_Merge
    tooltip-shadow [rect] -> tooltip-shadow_Merge
    tooltip-paper [rect] -> tooltip-paper_Merge
    tooltip-heading [text] -> tooltip-heading_Merge
    tooltip-dot [ellipse] -> tooltip-dot_Merge
    tooltip-value [text] -> tooltip-value_Merge
  reset-to-menu [group] -> reset-to-menu_Merge
    reset-to-menu-outline [path] -> reset-to-menu-outline_Merge
    reset-to-menu-mark [path] -> reset-to-menu-mark_Merge
  menu-arrow [group] -> menu-arrow_Merge
    menu-arrow-outline [path] -> menu-arrow-outline_Merge
    menu-arrow-mark [path] -> menu-arrow-mark_Merge
  bar-hand [group] -> bar-hand_Merge
    bar-hand-outline [path] -> bar-hand-outline_Merge
    bar-hand-mark [path] -> bar-hand-mark_Merge
  end-arrow [group] -> end-arrow_Merge
    end-arrow-outline [path] -> end-arrow-outline_Merge
    end-arrow-mark [path] -> end-arrow-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
chart-camera.y 3 0 → 8
chart-camera.scale 3 0.93 → 1
representation-menu.opacity 2 0.3 → 1
reset-to-menu.x 4 360 → 1620
reset-to-menu.y 4 205 → 315
reset-to-menu.opacity 4 0.6 → 1
menu-arrow.x 4 354 → 390
menu-arrow.y 4 229 → 790
bar-hand.x 2 350 → 354
bar-hand.y 2 790 → 855
bar-hand.opacity 5 0 → 1

Differences and acceptance limits

Largest gap: exact source cursor easing, fractional text rendering and chart-library interpolation are not recovered. Original percentages and polyline samples replace source data; no financial, cancellation or source branding data is reused. Menu glyphs and neighboring notes are simplified. The short final pullback is visually fitted, not a measured source camera matrix. The hard 239/240 switch is grounded in adjacent retained frames; all other numerical props remain authored choices.

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.