OpenAI Film Fieldnotes

Candidate construction guide · native Resolve not tested

White-field masked name reel

Resolve/Fusion construction guidance for type-masked-name-reel, with the retained Remotion recipe as the implementation authority. No Fusion import, new render, or fresh motion-fidelity verdict is supplied. The guide awaits separate critique; resolveApplicationVerified is false.

Binding and evidence

The source is Apps in ChatGPT, frames [3596,3896) at 60000/1001 fps, 1920 × 1080: 300 local frames, 0–299. Preserve the rational rate rather than rounding to 60. guide.json pins the exact source object, recipe bytes, core archive, selected asset pack and inspected renderer files. recipePath is relative to toolkit project/; other artifact paths are library-relative.

This pass inspected the retained review02/consecutive-08.jpg source/original/ adaptation sheet (locals 138,142–146) and the hash-verified source/original native PNG pair at 249. It did not play the moving source. Local 148 is an implementation checkpoint but is absent from the retained selected native PNG index; do not claim a native observation there. Extracted but unviewed PNGs are not added to visual coverage.

All exact numbers below are retained implementation controls. They are not fresh film measurements, recovered font settings or official easing tokens.

Fusion construction

Create a 300-frame white composition at 1920 × 1080 and verify its export timebase. Keep local zero distinct from the composition start and source frame 3596. End-exclusive 249 means last visible frame 248. Child animation keys use the same local clock as their parents; never subtract a parent's start.

The root merge order is:

Background_Canvas (white)
masked-reel-viewport [0,249)
  Transparent masked viewport, 700×800
  reel-row-0
    lozenge-0 → row-icon-0 → row-label-0
  reel-row-1
    lozenge-1 → row-icon-1 → row-label-1
  reel-row-2
    lozenge-2 → row-icon-2 → row-label-2
  reel-row-3
    lozenge-3 → row-icon-3 → row-label-3
  reel-row-4
    lozenge-4 → row-icon-4 → row-label-4
  reel-row-5
    lozenge-5 → row-icon-5 → row-label-5
  soft-row-mask (white alpha-gradient OVER the rows)
fixed-suffix [0,249) (outside viewport)
closing-line [249,300) (outside viewport)
MediaOut1

The JSON enumerates all 28 layers, their local parent, explicit merge order, effective activity, static controls and recipe JSON pointer. Each row begins on transparency. Build the lozenge with a Background and rounded Rectangle mask, overlay the original SVG icon and Text+ label, clip that row to its box, then translate it. Composite all rows, add the white gradient, clip the viewport to 700 × 800, then place it at (250,135). These two masks have different domains. Neither belongs on the suffix or final line.

Row Width × height Initial local x Initial local y Final x at 248
0 352 × 132 268 194.5 137
1 384 × 132 236 369.5 105
2 362 × 132 258 544.5 127
3 394 × 132 226 719.5 95
4 352 × 132 268 894.5 137
5 352 × 132 268 1069.5 137

Capsules use #f3f3f3, radius 66 local pixels; icons are 94 × 94 at (35,20). Labels begin at (147,30), fontSize 64, weight 500, lineHeight 1, tracking -0.8, color from accent. Copy each label's own width from the JSON; do not let longer labels reflow or resize every capsule. SVG icons are self-contained, original, square 512-pixel assets. Their native import is not tested here. Use Text+ for editable labels and the bundled Geist substitute; match actual pixel metrics before claiming parity. CSS fontSize is not a Fusion Size value.

Position each row in its 700 × 800 parent, then place the viewport in the 1920 × 1080 scene. For an unscaled box, the target parent-space center is (x + width/2, y + height/2); normalize against that parent's dimensions and invert Y for bottom-up coordinates. Do not normalize row positions against 1920 × 1080 or add the viewport offset twice. Negative y values are intentional and are hidden by the viewport; do not clamp the track to zero.

Motion, holds and easing

Each row has 237 y keys and 14 x keys. Keep them all. The 175-pixel spacing does not authorize a constant-speed scroll. For row 0, y=51 at 48, 30 at 49, 19.5 at 50, -125 at 98, -300 at 148, -471.5 at 198 and -522.5 at 248. Those are checkpoints, not replacements for the intervening keys.

src/timing.ts evaluates the left key's interpolation; exact right-frame values take precedence. Linear is the default. Smooth is progress² × (3 − 2 × progress) and hold switches at the right key. Before the first and after the last key, use the boundary value. The retained dense reel tracks are linear fits; turning them into Smooth splines changes the short bursts and deceleration. There is no exposure group or motion-blur shutter in this recipe. Do not add motion blur to disguise missing keys.

Despite its name, fixed-suffix moves horizontally late in the window: x=902 initially and 879 at 248, with eight keys. It remains at y=491 in a 610 × 118 box, fontSize 100, weight 600, lineHeight 1, tracking -0.8. It stays outside both masks. Preserve its own x track rather than binding it to any row.

White overlay, not a general matte

The supplied art/type-masked-name-reel/reel-fade.svg is 700 × 800. It draws white with variable alpha over the artwork. Its RGB is white even where alpha is zero; using its luminance alone as a matte is wrong. Keep it last inside the viewport. Either preserve that SVG geometry or construct a vertical white Background gradient with the following normalized position/alpha stops:

Position Alpha Position Alpha
0 1 0.12 1
0.21875 0.78 0.24375 0.75
0.26875 0.68 0.29375 0.66
0.298125 0.63 0.30625 0.56
0.31875 0.51 0.33125 0.46
0.34375 0.38 0.35 0.35
0.38125 0.14 0.41875 0
0.58 0 0.68125 0.3726
0.70625 0.5 0.71875 0.58
0.73125 0.66 0.75625 0.66
0.78125 0.76 0.83 0.92
1 1 — —

Map the gradient vertically from local top 0 to bottom 800; use each specified alpha, not a generic Rectangle soft edge. The zero-alpha band runs from y=335 to 464. For an alpha-mask implementation on rows, the theoretical coverage is 1 - overlayAlpha, but color/alpha compositing must still be checked against the white-over construction. No equivalence has been rendered in Fusion. Do not reuse the white overlay on a colored or transparent background and call it the same treatment. That needs a separately reviewed mask adaptation.

The biggest remaining gap is this fade's transfer to editable Fusion: the retained lower tail is already slightly too dark, and gradient interpolation, premultiplication and color management are not validated here.

Hard closing cut and pivot

At frame 249, gate off the entire viewport and suffix; replace them with closing-line. No row, overlay, crossfade, glyph morph or old suffix survives the cut. The final line is a separate center-aligned 960 × 118 text box, y=489, fontSize 98, weight 600, lineHeight 1, tracking -0.8.

Keep all 26 closing x keys: 522 at 249, 517 at 250, 488 at 272, 487.5 at 282 and 487 at 299 are selected anchors. Uniform scale is 1 through 272, then 1.0013020833333333 at 282, 1.0026041666666667 at 288, 1.0052083333333333 at 292, 1.0078125 at 296 and 1.0104166666666667 at 299. The origin is (480,15) within the text box, not its center (480,59).

If using a centered text plane, compensate its placement so the target center after scale is (x + 480, y + 15 + scale × (59 − 15)). This preserves the top-biased pivot without assuming Fusion's default pivot behavior. Keep a text-box-sized local domain so font ink bounds do not silently become the transform domain. Do not freeze the phrase once it appears or add an end fade.

Remotion and shared controls

Use an already authorized assembled core plus downloads/assets/type-masked-name-reel/assets-001.zip; the retained website's project files alone may omit SVGs. No installation or new media is performed by this guide. From the toolkit's project/:

npm --silent run catalog -- show type-masked-name-reel --contract
npm run render -- --help
npm run render -- --recipe type-masked-name-reel --variant default --out out/type-masked-name-reel-original.mp4
npm run render -- --recipe type-masked-name-reel --variant adaptation --out out/type-masked-name-reel-adaptation.mp4
npm run verify -- out/type-masked-name-reel-original.mp4
npm run verify -- out/type-masked-name-reel-adaptation.mp4

The archive's package scripts, parser and help are checked; read-only catalog/ help commands were exercised. These render/output-verify commands were not run. They need existing pinned dependencies, FFmpeg/FFprobe and supported Chromium. Outputs must be new paths; retain their sibling manifests. For new copy, edit the complete examples/type-masked-name-reel/default.json Content in a new inputs/type-masked-name-reel.json; use --content instead of --variant. Reject overflow, rather than changing track timing, font size or row geometry.

From dual-toolkit-200/, with PATH/project replaced:

python3 handoff.py verify --guide guides/layered/type-masked-name-reel/guide.json --project PATH/project
python3 handoff.py frames --guide guides/layered/type-masked-name-reel/guide.json --project PATH/project > controls.csv

Use authorized storage for CSV. The parent-owned exporter provides native raw local values, parent activity and nominal source seconds, not world-space, SVG gradient stops, Text+ shaping, PTS or an importable Resolve node graph. Do not treat a control pass as a render/fidelity pass.

Remaining checks

guide.json lists 14 checkpoints including the 248/249 cut and final drift. Inherited open MR-03 is the small lower-fade tail, not the repaired canvas color. MR-04 is the square/rectangular Geist i dot, not the repaired suffix placement. The prior targeted retest found no material mismatch but retained these two minor findings. That is not a fresh guide review or whole-motion approval. Font shaping, fade parity and actual native Resolve operation remain unverified; variants and individual tracks do not count as new treatments.

Read-only helper tests

From this guide directory, run FIELDNOTES_LIBRARY=PATH/library python3 -B test_guide.py with the retained library root. Six tests check exact recipe/source/archive pins, every layer and numeric-control mapping, original SVG members, inherited findings and the reel's clipping/order/cut/pivot controls. Assets are read from ZIPs without extraction. The tests use the parent handoff helpers; they do not run the full Remotion suite, create controls/media, or verify native Resolve. Missing FIELDNOTES_LIBRARY produces a skip, not a pass.

Per-SVG binding repair · September 13, 2026

guide.json.svgAssets now pins all 13 distinct SVG paths referenced by image layers across defaults and adaptation, with no extra pack members. Keys are relative to project/public/; values are SHA-256 hashes of the uncompressed project/public/<path> ZIP member bytes. The accepted asset archive's own hash was verified before deriving these pins. Shared paths are listed once.

The helper test requires the exact referenced path set and checks every member's bytes against its pin; missing, extra or changed assets fail. The regression failed for the missing map before this repair. Recipe bytes, numeric controls, source bounds, Fusion geometry and prior evidence remain unchanged. This adds asset verification, not new media, motion review or native Resolve validation.