# Task-card explanation: bounded SVG/Remotion → Resolve handoff

**r02 portability/privacy repair, September 13, 2026. Not a new completed study.**
Frozen r01 is preserved. See `DELTA.md` for this narrow change; the source,
motion, model and retained observations below are unchanged.
This is one additional guidance unit for the existing
`agent-task-card-explanation` mechanism. Its default and second content are two
variants of that mechanism, not two distinct examples. No render, moving-source
review, native Resolve session, packaging, publication, or critic verdict is
claimed. Final all-hands production is outside this work.

The selected core is unchanged. This folder adds an executable, read-only
controls inspector, an exact compact model, archive/evidence bindings, tests,
and this per-layer translation. There is no `.drp`, `.setting`, automatic native
importer, substitute screenshot, or newly prepared media.

## 1. Read these claims separately

- **Retained observation:** the recipe's existing source-frame notes and the
  retained source columns of the five contact sheets listed below. Historical
  measurement labels belong to those records; they are not fresh measurements.
- **Extracted model:** every coordinate, track, reveal count, color, radius,
  hierarchy, and perspective value in `controls.json`. These are implementation
  choices from actual code, not recovered OpenAI animation parameters.
- **Existing adaptation choice:** original workshop/planning copy, illustrated
  notes/agenda icons, original field SVGs, Geist, and the NOT POE disclosure.
  Neither variant establishes live product behavior.
- **Proposed Resolve mapping:** the node/parameter assignments below. Their
  numerical targets are checked against the actual renderer functions. Native
  preparation, image quality, tool-version behavior, and replay are unverified.
- **Unknown:** source shader, exact source 3D rotation, original font, intended
  source interaction semantics, continuous-motion fidelity, and native Resolve
  import/filter/font/shadow equivalence. Do not close these gaps with a score.

The project-local fieldnotes skills were read. Their deleted project/agent-guide
targets were not restored; the selected ZIP's `project/AGENT_GUIDE.md`, focused
editing skill, README, renderer and contracts supply the retained toolkit rules.
Unrelated work and the accepted stage were not edited.

## 2. Fixed source and retained evidence

Official film: **OpenAI, “A Look at ChatGPT agent,” July 17, 2025**. The retained
official-channel metadata records publication at `2025-07-17T10:27:56-07:00`,
channel `UCXZCJLdBC09xxGZ6gcdrc6A`, using
`playerMicroformatRenderer.publishDate`, retrieved September 5, 2026. This is
not the different “Introducing ChatGPT agent” film.

```text
https://www.youtube.com/watch?v=2wzGS_WUZYQ
historical full-source SHA-256:
f39beb96507b79d3779d339fb923ac1d0c5ad74f145295ec0c86d8b333e68391
metadata response SHA-256:
4bfc2111d8e99d297fb7cbed406bf376478d775c8d009c2554c38593632ab17f
```

`bindings.json` includes the metadata record and the hash of its retained
`references/openai/remotion/source-audit.json` ledger. The full source master
is not present in the configured working-copy source locations and was not
freshly hashed. The historical hash is not a claim of current master access.

All evidence/archive paths below are relative to the caller-supplied subset's
`videos/editing/benchmark/library/` directory. There is no machine-local default.
Pass `--stage SUBSET_ROOT` or set `FIELDNOTES_STAGE=SUBSET_ROOT`; an explicit
`--stage` takes precedence. `SUBSET_ROOT` names your existing data location, not
an included site copy. Blank or missing configuration fails before reading the
bindings or archives, exits nonzero, and produces no verification result.

### Supply only the selected already-public layout

The existing public library base is:

```text
https://openai-film-fieldnotes-100.pages.dev/videos/editing/benchmark/library/
```

Supply the **two archives** under `downloads/` plus the **12 retained files**
listed in `bindings.json.retainedFiles`, preserving their paths beneath the
library directory. `bindings.json.archives[].path` names an archive relative to
`downloads/`; each `retainedFiles[].path` is relative to the library directory.
Those are the paths to append to the public base when obtaining an independently
authorized subset. The checker needs no homepage, other recipes' assets, native
frame archives, full source master, or full-site copy. Layout:

```text
SUBSET_ROOT/
  videos/editing/benchmark/library/
    downloads/core-publication-v08.zip
    downloads/assets/agent-task-card-explanation/assets-001.zip
    evidence/agent-task-card-explanation/review01/
      comparison.json
      source.mp4
      comparison.mp4
      consecutive-01.jpg
      consecutive-08.jpg
      consecutive-12.jpg
      consecutive-15.jpg
      consecutive-18.jpg
    renders/agent-task-card-explanation/review01/
      original.mp4
      adaptation.mp4
      original.manifest.json
      adaptation.manifest.json
```

No files were fetched or copied from that stage in r02. Public retrieval and a
fresh minimal-subset assembly were not exercised. If served bytes differ from a
locked archive, member or retained-file hash, the checker fails; do not update
hashes merely to make a different location work. The `acceptedStage` label and
repo-relative `source.localMedia` / `publicationLedger.path` retain historical
lineage, not runtime defaults or additional files to download. All their SHA
values are unchanged. Existing source-access and review limitations describe
the retained r01 evidence, not a new source-access or aesthetic assessment.

The bounded source passage is **source frames [1156,1450), 60/1 fps**,
`[19.266666666… s,24.166666666… s)`. The retained excerpt is
`evidence/agent-task-card-explanation/review01/source.mp4`, SHA-256
`48ab05e0add2b4062cc192dbcfa7f34164a8734ba159edde44990460c55853ed`.
It is a 960×540 re-encoded silent excerpt, **not the 1920×1080 master**.
The 1920×540 `comparison.mp4` is a retained two-up comparison, not an editable
asset. Its hash is `46aca95807c9bf0f36763956a5713bca866b4438c867b69d454d7a30d8e28ae9`.

### What r01 inspected (not repeated in r02)

During r01, the following existing JPEGs were opened directly, without making derived media.
They contain SOURCE / ORIGINAL / ADAPTATION columns. Paths are beneath the same
`evidence/agent-task-card-explanation/review01/` directory; exact hashes are in
`bindings.json.retainedFiles`.

| Existing sheet | Local frames shown | Bounded static reading |
| --- | --- | --- |
| `consecutive-01.jpg` | 0–5 | Short white card grows; candidate artwork has conspicuous elongated colored folds unlike the source's softer shapes. Different background topology is visible, not resolved. |
| `consecutive-08.jpg` | 71–76 | Pointer exists before the explanation. No capsule at 73; pale first glyph/capsule at 74; more letters at 75–76. |
| `consecutive-12.jpg` | 112–116,122 | One-line shell at 112; taller shell and first second-line character at 113. Content differs deliberately across columns. |
| `consecutive-15.jpg` | 160,161,217–220 | Complete two-line explanations at these samples; card, icon, field and pale rows coexist. These samples do not establish shimmer cadence or smoothness. |
| `consecutive-18.jpg` | 277–282 | Narrowing tile at 278–280; explanation gone and label changed at 281; next icon visible at 282. No new moving-quality verdict. |

`comparison.json` records 294 source PTS entries and historical frame bindings.
The new test checks all PTS against `(1156 + localFrame)/60` within one
microsecond of decimal serialization. Its historical comparison-quantization
limit is `6.666666703125657e-7 s`. No frame is rounded onto a 30 fps timeline.

## 3. Source, default and second-content clocks

Use a **1920×1080, square-pixel, 60 fps** Fusion composition, with **294 frames**.
Set its local start to 0 and inclusive end to 293. If the host composition starts
at `S`, sample the model with `localFrame = time - S`; `--fusion-start S` emits
this offset in expressions. Source absolute frame is `1156 + localFrame`.
Don't use a 59.94 or 30 fps project, optical flow, speed change, or extra holds.

The original/default and second-content adaptation both use exactly this clock,
with `holdBeforeFrames=0` and `holdAfterFrames=0`. There is no new timing
adaptation, title lead-in, cue, audio, or narration in this research unit.

| Local frame | Source frame / seconds | Model event |
| ---: | --- | --- |
| 0 | 1156 / 19.266666… | Card 898×524 at (511,278); center (960,540). |
| 13 | 1169 / 19.483333… | Card height 732; icon scale reaches 1. |
| 24 | 1180 / 19.666666… | Card height 774 at y=153; layout/outline opacity reaches 1. |
| 43 | 1199 / 19.983333… | Task pointer first active. |
| 74 | 1230 / 20.5 | Explanation starts: 95×110, first character at opacity .25. |
| 112 | 1268 / 21.133333… | 32 visible code points, one line; shell 606×110. |
| 113 | 1269 / 21.15 | 34 code points including newline; shell steps to 606×160. |
| 159 | 1315 / 21.916666… | Full 68-code-point explanation. |
| 270 | 1426 / 23.766666… | Last stationary pointer/capsule key before departure travel. |
| 274 | 1430 / 23.833333… | First nonzero model Y-rotation key, −8°. |
| 278 / 280 | 1434 / 23.9; 1436 / 23.933333… | Notes icon rotation −45° / −69°. |
| 281 | 1437 / 23.95 | Label switches, explanation and old icon disappear; new icon starts at −89.8°. Pointer persists. |
| 291 | 1447 / 24.116666… | New icon reaches 0°. |
| 293 | 1449 / 24.15 | Last encoded frame. |
| 294 | 1450 / 24.166666… | Exclusive end, not an extra rendered frame. |

Local duration is `294/60 = 4.9 s`, last sample `293/60`, not a five-second
rounded clip. The description “narrow handoff” does not override the actual
model's reopening through frame 291. Cut after 293 if joining another shot;
no continuation or matched join has been verified.

## 4. Code and controls you can run without media preparation

From this self-contained handoff directory, explicitly bind your selected data.
The relative example location is a placeholder you supply, not a fallback:

```bash
export FIELDNOTES_STAGE="./fieldnotes-subset"
PYTHONDONTWRITEBYTECODE=1 python3 handoff.py verify --probe
PYTHONDONTWRITEBYTECODE=1 python3 -m unittest discover -s . -p 'test_*.py' -v
PYTHONDONTWRITEBYTECODE=1 python3 handoff.py table --layer attached-explanation --frames 74,76,99,112,113,270,274,280,281 --format csv
PYTHONDONTWRITEBYTECODE=1 python3 handoff.py table --variant adaptation --layer typed-explanation --frames all --format csv
PYTHONDONTWRITEBYTECODE=1 python3 handoff.py table --layer notes-icon-handoff --frames 278,280
PYTHONDONTWRITEBYTECODE=1 python3 handoff.py curve --layer moving-folds --property x
PYTHONDONTWRITEBYTECODE=1 python3 handoff.py expression --layer attached-explanation --property width --fusion-start 0
```

Or provide the root directly, overriding any environment binding:

```bash
PYTHONDONTWRITEBYTECODE=1 python3 handoff.py verify --stage ./fieldnotes-subset --probe
```

`load(stage)` accepts an explicit root; `load()` resolves `FIELDNOTES_STAGE`.
The test setup resolves that same explicit environment binding once and passes
it to `load`, PTS checks and `binding_report`. Running without either binding is
an error, not a skipped source check. Python uses only its standard library;
verification also needs the existing Node runtime, and `--probe` needs FFprobe.

These commands read selected members with `ZipFile.open`; output is stdout only.
Do not redirect large tables to disk under this grant. `--frames all` means
0–293, not time resampling. `verify` also executes actual `sample` and
`visibleText` from the selected `src/timing.ts`, and actual `boxStyle` and
`textAt` extracted from `src/Treatment.tsx`, with type stripping only. It does
not load React, a browser, or Remotion's render pipeline. Node 24.13.1 ran this
check here; the original toolkit declares Node ≥22.18.

`controls.json` contains **41 layer records and 30 deduplicated track arrays**.
`{"track":"t001"}` is a reference to `tracks.t001`, not a different curve.
Expanding those references must equal `recipe.layers` structurally, including
all 86 typing/shell steps. Both content objects must equal their archived props.
Every archive and selected-member hash is checked before emitting controls.
The 774,105-byte toolkit manifest stays inside its ZIP; no copy is written.

### Curve semantics: do not use an arbitrary Ease preset

The **left key** owns the segment interpolation. Values clamp before/after the
first/last key. `linear` is linear; `hold` retains the left value until the exact
right frame, when it changes. `smooth` is `p*p*(3-2*p)`, not a spring and not
Remotion's unrelated default easing. For a smooth segment from `(a,u)` to `(b,v)`,
Bezier handles in **frame/value units** are `(a+(b-a)/3,u)` and
`(b-(b-a)/3,v)`. The handle X spacing makes Bezier time linear.

Fusion's documented node graph supports expressions and spline editing; its
normalized coordinates have bottom-left (0,0). The proposed adapter uses those
facilities, not an Edit-page title preset. Official documentation consulted:

```text
https://www.blackmagicdesign.com/ca/products/davinciresolve/fusion
https://documents.blackmagicdesign.com/UserManuals/DaVinci-Resolve-17-Fusion-Visual-Effects.pdf
Coordinate convention: printed page 103. No local manual download was made.
```

Paste `expression` output only into a **numeric source-pixel control** with the
corresponding name. It uses Fusion-style `time` and `iif`; arithmetic was tested
with an equivalent evaluator, not inside Resolve. Conversion to a particular
node's units is a separate operation. For dense integer-frame tables, use
linear segments for continuous controls and explicit holds for discrete
controls, disable motion blur, and check every rendered integer sample later.
That is only integer-sample equivalence; it does not preserve smoothstep at
subframes. The expression or exact Bezier route preserves the fitted curve.

## 5. Resolve construction: common coordinate and compositing rules

Treat every subgraph as a local-coordinate transparent plate with a declared
origin. Preserve the hierarchy, then merge on a 1920×1080 canvas. An inspector
box position is **top-left in source pixels**, not a Fusion Center control.
For an unrotated box on a full-canvas plate:

```text
Center X = (x + width/2) / 1920
Center Y = 1 - (y + height/2) / 1080
Width = width / 1920; Height = height / 1080   [normalized rectangle controls]
absolute CSS point (px,py) -> Fusion point (px/1920, 1-py/1080)
```

`localFusionCenter` assumes an unrotated full-canvas local plate; it is not a
world-space center for nested, scaled or projected layers. Prefer the emitted
`anchorPixels` and `quadFusionTLTRBRBL` for world-position checks. Quads are
ordered top-left, top-right, bottom-right, bottom-left. Do not use a projected
bounding box as a projective quad.

The actual CSS order is:

```text
T(x,y) T(origin) Perspective(depth) Rx Ry Rz Scale T(-origin)
```

The rightmost operation acts first. Nest this under the parent transform. The
checks evaluate the actual CSS string numerically and compare the resulting
quads to the handoff's independent matrix implementation. A native 3D camera
with similar-looking rotation is not automatically equivalent.

For 2D rotations, CSS's screen-space positive rotation and Fusion's Y-up axes
need sign conversion if using an Angle control: use `-rotation` for a native
positive-counterclockwise angle. Check a positive marker rotation before
committing to that node; emitted quads are the authoritative targets. Keep
background pivots at (1152,648) within their 2304×1296 planes, and icon pivots at
(104,104) within their 208×208 planes. No auto-centering on cropped alpha bounds.

Each node receives its **local** opacity; group opacity applies once after
merging its children. `effectiveOpacity` is a diagnostic product, not an extra
opacity multiplier to apply again. Use ordinary foreground-over-background
merges. There is no animated exposure, trail sampler, motion blur, layer-level
blur or clip-inset track in this recipe. Blur exists inside the original SVGs
and CSS shadows. Crop only at the canvas boundary and the explicit local masks.

Match CSS sRGB color values and straight/premultiplied alpha behavior before
judging pale grays or shadows. Native color management and filter kernels have
not been matched. A profile change is not permission to alter the SVG colors.

### Root merge order, bottom to top

```text
white canvas
  moving-base
  moving-folds
  moving-mist
  growing-card [children in listed order below]
  notes-icon-handoff [frames 0..280]
  agenda-icon-handoff [frames 281..293]
  attached-explanation [frames 74..280]
  task-pointer [frames 43..293]
  disclosure-back
  disclosure
  MediaOut
```

The icon and callout are **not children of growing-card**. The callout is not
clipped to the card. Do not place everything under one card Transform, mask, or
zoom. Keep the pointer above the capsule so the white-edged hotspot remains
visible at the attachment.

## 6. Three drifting SVG field planes

For each plane, prepare the named **unchanged original SVG** on a 2304×1296 plate,
keep its intrinsic gradient/filter/alpha, and use its own Transform or equivalent
projected coordinates. All three are active 0–293, with opacity 1, scale 1,
origin (1152,648). No automatic fit-to-1920 before applying its track.

| Layer / content slot | X keys `frame:value` | Y keys | Rotation degrees |
| --- | --- | --- | --- |
| `moving-base` / `fieldBase` | 0:−192,100:−173,200:−215,293:−242 | 0:−108,147:−88,293:−115 | 0:0,293:.45 (linear) |
| `moving-folds` / `fieldFolds` | 0:−178,90:−206,200:−158,293:−219 | 0:−123,147:−65,293:−107 | 0:−1,130:.8,293:−.3 (smooth) |
| `moving-mist` / `fieldMist` | 0:−224,150:−158,293:−192 | 0:−97,150:−136,293:−84 | 0:.8,293:−.5 (linear) |

All X/Y segments in this table are smoothstep. The files are
`field-r04-{base,folds,mist}-{default,adaptation}.svg`. Choose all three from the
same variant. Base is opaque; folds and mist overlay it with their own alpha.
The base uses an active 28px Gaussian SVG filter; folds use 16px and 8px; mist
uses 20px. Some unused filter definitions also exist. Do not interpret the
recipe's prose “8/16/20px” as a complete list of the actual base filter settings.

**Preparation gate:** SVG vector import must preserve `feGaussianBlur`, gradient
coordinates/stops, group opacity, strokes, and filter bounds. This has not been
tested in Resolve. If import drops them, do not replace the field with flat
shapes, a title background, or source footage. Stop for a permitted exact
original-SVG preparation path. No prepared raster plate is supplied here.

## 7. Growing card and live foreground rows

`growing-card` is a translation/layout group, not a uniform scaling group.
Set x=511, width=898, y=`540-height/2`, height as follows; use **linear** keys.

```text
frame:  0   1   2   3   4   5   6   7   8   9  10  11  12  13  18  24 293
height:524 544 564 583 601 618 634 650 665 680 694 707 720 732 762 774 774
```

Retained observation reports the initial white-fill envelope as
[511,278,1409,802] and frame-13 envelope [511,174,1409,906]. The full 17-key track
is the model fit. Keep the center fixed at (960,540); do not scale the label,
corner radius or border along with the card height.

Inside `growing-card`, merge in this order (coordinates relative to its origin):

| ID | Native subgraph / precise target |
| --- | --- |
| `card-shell` | White Background through a rounded mask, width 898, height matching parent, radius 38px, no stroke. Separate unclipped shadow: CSS `0 3px 12px #4d66840d`. |
| `task-status-symbol` | The exact model path at (40,33), 39×39, viewBox 0 0 34 34; no fill, stroke #626567, viewBox stroke width 2.5. Do not substitute a connector logo. |
| `first-task-label` | Text+ target (97,30), 750×46, Geist 34px/weight 500, line-height 1.25, #626262, left/top alignment. Active 0–280 only. |
| `second-task-label` | Same box/type, active 281–293 only. Direct switch, not a dissolve. |
| `skeleton-panel-outline` | At (36,103), width 826, height=`cardHeight−140`, radius 19px; transparent fill, 2px inside-box #ededed stroke. Opacity 0:.15,13:.8,24:1 (linear). |
| `skeleton-layout` | At (36,103), 826×634, origin (0,0), scaleY=`(cardHeight−140)/634`; scaleX=1. Opacity 0:.04,3:.25,13:.95,24:1 (linear). Contains the nine masks below. |

CSS `fill:"none"` on the outline means no visible CSS background; do not paint a
black rectangle. Border boxes include their stroke. Shadow blur radii are CSS
values, not already-calibrated Fusion Shadow or Blur slider values. Keep shadow
outside the silhouette mask; match it later against the retained default, not
by entering 12 into an unrelated blur unit.

### Nine masks, one synchronized shimmer coordinate field

Build nine separate rounded masks inside `skeleton-layout`, each radius 20px,
height 41px and overflow hidden. Their **local** (x,y,width) values are:

| `shimmer-mask-row-N` | x | y | width |
| --- | ---: | ---: | ---: |
| 1 | 26 | 12 | 514 |
| 2 | 83 | 83 | 404 |
| 3 | 83 | 154 | 485 |
| 4 | 57 | 225 | 711 |
| 5 | 112 | 296 | 574 |
| 6 | 112 | 367 | 675 |
| 7 | 26 | 438 | 678 |
| 8 | 26 | 509 | 710 |
| 9 | 26 | 580 | 574 |

Each mask contains `moving-shimmer-N`, the same 4000×700 `shimmer-r04.svg` in
slot `skeletonShimmer`. In the mask's local coordinates set:

```text
image X = phase - mask X; image Y = -mask Y
phase keys (linear): 0:-1850,24:-1780,99:-1520,159:-1120,220:-860,270:-620,293:-500
```

Thus all nine children sample one shared moving diagonal field; they are not
nine independently restarting gradients. Clip **after** moving the SVG inside
each rounded mask, merge the nine results, then scale that finished layout about
its top-left. This scales the rows and their rounding together. Do not move the
masks with the shimmer or scale the whole card. All SVG edges cover all masks
through frame 293; tests check that coverage and phase cancellation.

The shimmer SVG is a repeating user-space gradient from (0,0) to (900,450):
stops 0:#f9f9f9, .28:#f8f8f8, .40:#f3f3f3, .56:#f3f3f3,
.73:#f9f9f9, 1:#f9f9f9. Retain this asset, not an invented animated opacity pulse.
The faint model variation is independent of the field drift. The source's
actual procedural shader and phase remain unknown.

## 8. Center icon with narrow, asymmetric handoff

`notes-icon-handoff` and `agenda-icon-handoff` are root siblings, both at
(856,472), size 208×208, origin (104,104); their pivot is (960,576), **not** the
card's (960,540). Both use scale keys 0:.74,13:1,293:1, linear. In each, merge
`{notes,agenda}-tile-shadow` then `{notes,agenda}-art`:

- Shadow tile: x=4,y=4,width=200,height=200,radius=20,white, CSS shadow
  `0 9px 30px #15263816`. Preserve overscan for the shadow.
- Artwork: the unchanged `symbolNotes` or `symbolAgenda` SVG, 208×208 at (0,0),
  contain. Do not extract the source Gmail/Calendar marks from a contact sheet.
- Notes group active [0,281); agenda active [281,294). Child ranges [0,294)
  do not override their parent gates.

Perspective is the fitted CSS value **1100px**, not a measured source lens.
RotationY keys are linear:

```text
notes:  0:0,273:0,274:-8,275:-18,276:-26,277:-35,278:-45,279:-54,280:-69
agenda: 281:-89.8,282:-72,283:-56,284:-43,285:-31,286:-22,287:-14,289:-5,291:0,293:0
```

For an independent target check, a point `(u,v)` relative to the icon center,
already multiplied by the scale, projects at:

```text
denominator = 1 + sin(angleY)*u/1100
screenX = 960 + cos(angleY)*u/denominator
screenY = 576 + v/denominator
```

Use the emitted quads to configure a Corner Positioner or an equivalent native
projective mapping. Its source quad must correspond to the 208×208 tile plane,
not the whole output frame or alpha-trimmed art. Pad/shadow extent and source-
quad calibration are still native-preparation checks. A cosine-only X scale
misses the unequal left/right projected edge heights. A same-size crossfade
misses the silhouette mechanism entirely. Do not silently fit a different
native camera and call it the extracted model.

## 9. Delayed attached explanation, text clip and pointer

`attached-explanation` is a root group, active **[74,281)**. Capsule and text
follow that parent, not an independent full-frame Text+ position. Its own x/y
tracks are **linear**, unlike the pointer's smooth tracks:

```text
capsule X: 74:934,83:920,99:912,270:912,275:943,280:980
capsule Y: 74:707,99:701,280:701
```

The model is a fitted local attachment, **not a rigid `(pointer+38,+35)` parent
constraint**. Capsule minus pointer positions at selected frames:

| Frame | Delta X | Delta Y |
| ---: | ---: | ---: |
| 74 | 38 | 36 |
| 76 | 36.655692730… | 35.61088 |
| 99 / 270 | 38 | 35 |
| 274 | 35.024 | 34.296 |
| 280 | 38 | 33 |

Across active integer samples, delta X spans **34.448–41.552px**, Y **33–36px**.
Preserve both tracks, including this residual. Rigidly parenting the capsule
to the pointer would change the retained choreography. Within the capsule,
the text anchor remains exactly parent+(36,31) during entry and departure.
The tests also translate the parent by (+17,−9) in memory and check that all its
children follow while the sibling pointer does not.

### Capsule graph

```text
attached-explanation translation and gate
  explanation-shell [unclipped shadow + white/stroked rounded body]
  explanation-text-clip [rounded alpha clip, no fill]
    typed-explanation [Text+ content and local opacity]
```

`explanation-shell`, the parent, and `explanation-text-clip` share **identical
86-key width/height arrays** from frames 74 through 159. Import these exact
arrays via `controls.json` or print `curve --layer attached-explanation
--property width`; every segment is a **hold**, not a size tween. Width examples:
74:95,75:114,76:131,83:230,99:447,112:606,159:606. Height is 110 through 112,
then 160 from 113 onward. The last values persist until the parent gate closes.

Both body and text clip have radius 35px. Body is #ffffff with 1px #e5e5e5
border and CSS shadow `0 5px 26px #2034491c`. The body shadow is a sibling of
the clip, **not inside it**. The root parent has overflow visible. Do not clip
the shadow at the capsule or the whole capsule at the card.

### Typing is exact content-prefix substitution, not a caret effect

`typed-explanation`: (36,31), 540×101, Geist 34px, weight 400, line-height 1.47
(49.98px), letter spacing −.3px, #0c0c0c, left/top alignment, preserved newline,
no wrapping. The loaded-font full-line width constraints are 510–538px and
517–535px, respectively. Those checks have **not** been rerun in a browser or
Text+ here. Matching character count alone does not prove font fit.

Use the selected content's exact Unicode-code-point prefix for each reveal
step. The newline itself counts. `table --layer typed-explanation --frames all`
outputs the strings at every frame. For Text+, use discrete StyledText states
or an equivalent expression with these strings. Do not assume normalized Write
On values count whitespace and newlines like JavaScript `Array.from`.

Key checkpoints: 74→1 character,75→2,79→6,80→6 (hold),112→32,
113→34 (newline plus first next-line character),114→36,159→68.
Text opacity is 74:.25,75:.64,77:1, linear. The **capsule itself does not fade**
with this text-opacity ramp. At 281, the entire group disappears immediately,
even though the child's own end is 294. Do not add a fade-out or text deletion.

**There is no text caret layer, suffix, or blink in this selected implementation.**
The visible black cursor is `task-pointer`. The caret check is an absence check,
not an invitation to add a typing-caret animation from another recipe.

### Pointer path and travel

Use the exact `taskPointerPath` from either props object, viewBox 0 0 54 56,
rendered at 54×56, black #030303 fill and 4-unit white stroke. This is an original
rounded triangular pointer, not the renderer's generic `kind:pointer` cursor.
It is a `kind:path` layer active [43,294), with these smoothstep tracks:

```text
X:43:984,54:956,69:909,74:896,83:882,99:874,270:874,275:905,280:942,281:950,283:976,293:1023
Y:43:747,54:721,69:684,74:671,99:666,270:666,280:668,293:688
path: M7 3Q2 1 3 7L17 44Q20 51 24 44L29 28L45 24Q52 21 45 17Z
```

Do not hide it with the explanation at 281. It remains and travels toward
(1023,688) at 293. Its top-left coordinate is not the shape's first path point;
attachment deltas above compare layer origins, not measured black-pixel bounds.

## 10. Disclosure and content substitution

Keep `disclosure-back` at (18,1038), 254×28, radius 5px, white opacity .9.
Keep `disclosure` at (29,1044), 232×19, Geist 13px weight 600, line-height 1.25,
#292d31. Both run 0–293 above the other layers. Text is immutable:
`ILLUSTRATED UI · NOT POE`. This deliberately differs from the source.

| Slot | Default | Second content (`adaptation`) |
| --- | --- | --- |
| `firstLabel` (24 characters) | Preparing workshop notes | Reviewing planning notes |
| `secondLabel` (25 characters) | Preparing the team agenda | Reviewing team milestones |
| `explanation`, line 1 (32) | Reviewing the workshop notes and | Reviewing the planning notes and |
| `explanation`, line 2 (35) | collecting next steps for the team. | collecting open items for the team. |

The explanation is exactly 32 characters, one newline, 35 characters: 68 total.
Change palette/art only by selecting the archived variant's image slots.
Arbitrary third copy is not authorized by this handoff: capsule widths, line
widths and revealed prefixes are coupled. Recalculating them and new font/replay
review would be a separate phase, not a harmless text edit.

## 11. Required companions, exact rebuild commands, package errors

Both of these **existing** archives are required. No native evidence archive,
source film, or comparison movie is a runtime asset.

| Archive relative to `downloads/` | Bytes | SHA-256 |
| --- | ---: | --- |
| `core-publication-v08.zip` | 2,639,476 | `307fb6b927e35e6d73779652873d994f5c3e36cb7deba65f22fa64748057a0de` |
| `assets/agent-task-card-explanation/assets-001.zip` | 16,039 | `51590d8f651963c7727a9b255d860455b4bdc8b2fc05beaa207e11cb8cfb0e07` |

`bindings.json.archives[].selectedMembers` lists **every exact member name,
byte count and SHA-256** used here: 31 selected core members and all 11 SVG
members. Those lists include the recipe, default/adaptation props, typed input,
composition entry/renderer, timing, validation, render/verify scripts, lockfiles,
README/guide, font and rights. The large manifest is required for these read-only
historical binding checks, not as a Resolve plate or an extra copied deliverable.

Important selected hashes:

```text
recipes/agent-task-card-explanation.json
28c76fdbbc025361bde3249716491b040fb8ec75c066b6f4b6090bbaa8d52239
src/Treatment.tsx
619961bce2dd3ceb6ef66a4a2575956eda749a73dc4bb8d716d6534b3c96e1ce
src/timing.ts
b7228f76ac5fd8a3854e2e9777238a68f4ba7db105b2818a3dadd7f22865e434
package-lock.json
d49a849f7eb399e171ed709b67e00e96104f1116e571c96e6e94952e14110922
public/fonts/Geist.ttf
73894e0448cae90a92b6c2f8732b7bb9acb7b94c418bff559dad4a18e1de9659
```

**Later, only in a separately authorized prepared toolkit:** put the selected
members under their unchanged `project/...` paths, with licensed font and all
variant SVGs in `public/`. Use existing pinned dependencies (Remotion 4.0.520,
React 19.2.8), FFmpeg/FFprobe and a local Chromium configured using
`REMOTION_BROWSER_EXECUTABLE`. No installation, extraction or browser launch
was done in this phase. Do not restore the deleted repo project directory.

From that prepared `project/` directory, these are the actual documented rebuild
commands. **They were not executed here.** Choose new output names; the CLI
refuses overwrites.

```bash
npm run render -- --recipe agent-task-card-explanation --variant default --out out/task-card-default.mp4
npm run render -- --recipe agent-task-card-explanation --variant adaptation --out out/task-card-second-content.mp4
npm run verify -- out/task-card-default.mp4
npm run verify -- out/task-card-second-content.mp4
```

Alternatively, the exact existing second-content JSON can be supplied with
`--content examples/agent-task-card-explanation/adaptation.json` **instead of**
`--variant adaptation`; never pass both. Neither route changes the recipe or
shared implementation. No hold flags or output-fps conversion are needed.
The renderer targets silent H.264/yuv420p, BT.709, CRF 16 at native dimensions
and cadence. A new environment need not reproduce old compressed MP4 bytes;
preserve its new provenance rather than claiming an unexecuted byte replay.

### Errors and missing companion material found now

The two ZIPs and all 42 selected members match the retained download index.
All 11 SVGs are self-contained original assets; no bitmap/image/font embeddings,
remote references, scripts or source footage were found. The licensed runtime
font is separately present in core. However:

1. Both **retained render-manifest wrapper files differ from their indexed
   historical hashes**, each by eight bytes in length. The actual parsed
   `binding` and `inputProps` equal the embedded toolkit manifest's values, and
   all their selected code/asset hashes match. This establishes a narrower
   selected-binding result, not full manifest identity. The retained toolchain
   browser path is redacted; the exact cause of the historical wrapper-byte
   change is not established by this handoff.
2. Props/recipe prose refer to per-recipe `ASSET-NOTES.json` and
   `FONT-LICENSE.txt`, but neither is included in these two archives. Core
   includes `ASSET_RIGHTS.md` and `public/fonts/OFL.txt`. Report those missing
   ancillary references; do not silently fabricate the files or a rights audit.
3. A fresh selected-subset preparation, loaded-font validation, original/default
   and adaptation replay, and native SVG import were **not performed**.

Exact manifest wrapper distinction:

| Variant | Indexed historical hash | Actual retained wrapper hash |
| --- | --- | --- |
| default | `ce1076cea30803589310897b97b90d76d3dc1be54da85bd2263ea83efe402806` | `d68cc37b8c19893ea3f807ff42550e594885174662fb7339f6fc02f90c4b332c` |
| adaptation | `6205fb831650e0a465e16b0a45ad49daed72125091f0eb362df1eb9aad9ec680` | `7e2d10f21e3af4bcce71b2ed05f56a16270f4718768bf9782b4e1941ea00f3f9` |

The retained movies themselves match their recorded hashes:

```text
renders/agent-task-card-explanation/review01/original.mp4
44b255b6ba153e90fc72f027e49ca1d732349e625aad9f4ec642c1541c0e5729
renders/agent-task-card-explanation/review01/adaptation.mp4
bff839246669a24dc86fd96308473618d1f60ac05a790859d586bb763a7bce06
```

## 12. Gates before any packaging or completion credit

The read-only check completed **650 cases, 26,650 layer rows, and 746,200 numeric
comparisons** against actual selected renderer functions at tolerance `1e-9`.
It covers both contents, every integer frame 0–294, and selected ±.25-frame
boundary probes. The 15 retained mechanism tests include curve/Bezier arithmetic, emitted expression
arithmetic, parent attachment during motion, typing/newline/capsule boundaries,
caret absence, abrupt departure, source PTS, icon projective corners, synchronized
shimmer and rejected non-original/external SVG constructs.

That is not a pixel test. In particular, it does not prove Text+ metrics,
SVG-gradient/filter support, native corner radii/shadows, alpha/color handling,
actual node wiring, or smooth moving playback.

Before accepting a native build, a reviewer must check:

- **Preparation:** reproduce selected members without altering core; resolve
  ancillary rights-note and manifest-wrapper discrepancies. Establish font,
  SVG/import and color-management behavior on the actual Resolve version.
- **Hierarchy:** card center fixed at (960,540); background planes continue
  independently; nine shimmer masks retain shared phase; icon stays centered
  at (960,576); text remains parent+(36,31) throughout capsule travel.
- **Clock and boundaries:** compare 42/43,73/74/75,79/80,112/113/114,158/159,
  270–281 and 291/293 at 60 fps. No new caret, auto-wrap, opacity fade on the
  entire capsule, doubled gate frame, or pointer deletion at 281.
- **Native render/replay:** compare both original-SVG variants to retained
  outputs, including subframe policy, projective edges, clipping, pale row
  contrast and shadows. Do not substitute a movie layer for editable controls.
- **Moving source:** separately inspect continuous source and candidate motion,
  with native source-access limits stated. A contact-sheet match and a numerical
  fit are not a moving-source win.
- **Fresh critic:** the user will supply the next independent technical review.
  No critic was requested, read, simulated or accepted in this phase.

Completion increment **0**; packaged increment **0**; new renders **0**;
native-Resolve passes **0**; new moving-source passes **0**. Keep this unit out
of the 100 completed/distinct-example count until its required gates pass.
