# Editing from the fieldnotes library

This is a review-stage toolkit. Do not mistake a searchable draft for a
source-faithful completed example. The existing approved benchmark is preserved
separately; this package does not authorize publication or all-hands production.

## Find a small relevant subset

From this project directory, with Node 22.18 or newer and FFmpeg/FFprobe installed:

```bash
npm ci
npm run typecheck
npm test
npm run catalog -- search --family typography
npm run catalog -- search --query "highlight selection"
npm run catalog -- show RECIPE_ID --contract
```

Read the selected recipe's source interval, observations, fields, invariants,
entry/exit states, neighbors, inspection limits and fidelity status. A recipe's
presence in search does not prove completion. Match the editorial intention and
observed choreography, not just a visually similar thumbnail.

When piping results into a parser, use `npm --silent run catalog -- search QUERY`
or `npm --silent run catalog -- show RECIPE_ID --contract`. Otherwise npm adds its own
launcher banner around the CLI's JSON. Start with a broad intent/family query
and narrow using duration and inputs; an empty result is not proof that the
library contains no suitable treatment.

Search returns at most 20 records by default. Use `--limit N` (1–50) and
`--offset N` (a nonnegative integer, default 0) to page through ranked matches.
`total` counts the catalog; `matched` and `complete` cover all filtered matches.
`returned` counts this page,
`offset` identifies its start, and `nextOffset` is null at the end. For the next
page, repeat the same query and filters with `--offset` set to `nextOffset`.
Artifact and builder details load only for that page. Pagination flags are not
accepted by `show`; no synthetic scale-test records are added to the library.

`show --contract` retains the selected recipe's source interval and rational fps,
canvas, invariants, entry/exit states, neighbors, limitations, API and artifact
links without layers or example pose payloads. For builder-backed recipes,
search and this compact view expose `designInputs` and the typed `contentBuilder`
contract instead of generated fields. `generatedContentFieldCount` counts all
renderer fields, not just paths. `fullRecipePath` links the unchanged recipe;
ordinary `show RECIPE_ID` still returns its complete fields, examples, observations
and inspection records. Search ranking and `--input` filters continue to match
low-level recipe metadata, not the builder's design inputs. Short editing nouns
match in either number: `search "paragraph cut" --duration '<=2'` finds paragraph
cuts.

Use `--neighbor RECIPE_ID` with an existing recipe ID, not a family name. Returned
directions are relative to that anchor: `before` means the result goes before the
anchor; `after` means it follows. A declaration from either side can establish
the candidate relationship. Family names inside declarations are supported,
but are not valid anchor arguments. This is discovery, not visual continuity
approval; the edit still needs an explicit, inspected join.

Both forms of `show` expose `textLayoutConstraints` before you render. These are
the local text-box widths/heights, font size/weight, letter spacing, prefix/suffix
and any per-line width ranges used by the renderer. They are not measured widths
of your new copy. Every layer must pass with the loaded bundled font; a field's
character limit alone does not guarantee fit. For example, the reel's row0 box
is181px wide: the six-letter word `Sketch` measures207.3px and is rejected rather
than shrunk. If exact brief copy cannot fit, reject that route; do not change
copy, geometry or timing without the brief's permission. The native render
command performs the authoritative loaded-font check before encoding.

The public download deliberately has an empty artifact-history index.
Search and contracts still cover all 20 recipes; artifact status is `not-built`,
not a claim that reviewed movies are included or verified locally. Open
`public-guide/index.html` for the published draft review. All 20 remain
drafts with zero completed examples. Publication authorization does not
approve fidelity or production use.

## Substitute content, not choreography

### Builder-backed recipes

When `contentBuilder` is present, read its `guide`, `inputs` and `limitations`.
Construct the named `designType`, import the named `export` from `module`, and
await that function to obtain renderer `Content`. The flow is **design → builder
→ Content**. A design JSON is not renderable Content. Book, wordmark and reverse
selection builders generate their pose/path internals; do not hand-author those
fields or treat their count as the number of design choices.

Use the documented builder command when provided, choosing unused output names,
or the guide's typed API. For example, from this project directory:

```bash
npm --silent run catalog -- show agent-wordmark-outline-finish --contract
node --experimental-strip-types adapters/typography.ts \
  --recipe agent-wordmark-outline-finish \
  --design inputs/agent-wordmark-outline-finish/design.json \
  --out inputs/agent-wordmark-outline-finish/generated-v01.json
npm run render -- --recipe agent-wordmark-outline-finish \
  --content inputs/agent-wordmark-outline-finish/generated-v01.json \
  --out out/wordmark-v01.mp4
```

Preserve the generated Content and its generation-provenance companion. The
catalog only reads the builder contract; it does not execute the builder or
verify that the supplied design fits. Builder validation, render verification
and source-fidelity review remain separate checks.

### Direct-content recipes

When `contentBuilder` is null, use the recipe's declared low-level fields.
Use `recipes/RECIPE_ID.json` and its `defaults`/`adaptation` records. Copy the
content object into an input JSON file; change only documented fields. Text,
colors, original vector identity paths, image and video inputs are typed in
`src/types.ts`. Do not modify `src/` or recipe tracks to complete an ordinary
editing brief. If its assets cannot fit the declared limits, select another
recipe or report that the brief needs an explicit new adaptation.

Media paths are relative to `public/`. Supply original or permitted assets with
accurate dimensions and rights declarations. Do not place source OpenAI footage,
branding, demo data or private captures in this directory. The renderer rejects
remote paths and unsupported aspect ratios. Video must already have the recipe's
native fps. Text overflow fails rather than shrinking the design. `path` identity
slots use their documented SVG viewbox, not an external SVG file.

Some typographic crops also declare `lineWidthRanges` and
`decreasingLineWidths` on their text layers. The renderer measures each complete
line with the bundled font, size and tracking before rendering. These limits
preserve deliberate margins inside an oversized crop; passing character limits
alone is insufficient. A rejected line reports its measured advance and allowed
range. If exact supplied copy fails, report the incompatibility or choose another
recipe. Do not resize, re-track or reframe it to bypass the contract.

The media-slot gate binds a nonempty, accurate rights declaration for original
or permitted assets. It does not establish authorship or legal permission.
Describe a license or public-domain basis accurately; do not claim that you
created third-party material. The bundled NASA photographs identify NASA, not
this project's builder, as their creator; their credit ledger is in
`ASSET_RIGHTS.md`. Asset provenance still needs separate review before inclusion.
The bundled OFL font retains its own license. SVG image inputs must have outlined
glyphs, not embedded font URLs.

```bash
npm run render -- --recipe RECIPE_ID --variant default --out out/original.mp4
npm run render -- --recipe RECIPE_ID --variant adaptation --out out/adaptation.mp4
npm run render -- --recipe RECIPE_ID --content my-content.json --out out/my-edit.mp4
```

`REMOTION_BROWSER_EXECUTABLE` optionally selects an existing supported Chromium.
Otherwise the CLI searches `PATH`; install a browser explicitly if none is
available. It does not download a browser during rendering. The render writes a sibling provenance
manifest. Keep that manifest with the video; it binds code, selected recipe,
inputs and used asset bytes to the output. Existing output files are not evidence
for changed code or content.

Custom input JSON must stay inside this project, preferably under `inputs/`.
New manifests bind project-relative paths so the toolkit, content, assets and
outputs can move together. Keep their relative layout unchanged. External JSON
and escaping symlinks are rejected; see `docs/PORTABILITY.md` for migration and
verification details.

## Timing and neighboring shots

`source.startFrame` is inclusive; `endFrameExclusive` is exclusive. All tracks
are on the local native-frame clock. Default duration and fps are source-locked.
`--hold-before` and `--hold-after` add explicitly labeled frozen holds; neither
changes active choreography. Those renders are adaptations, not synchronized
source comparisons. The native fps is rational; never round 24000/1001 to 24.

For composition, `src/library.ts` exports `TreatmentAtFrame`, `nativeFrame`, and
the typed `Recipe`/`Content` interfaces. Preserve seconds when crossing clocks:
`nativeFrame(outputFrame, outputFps, sourceFps)`. A mixed-fps edit is an explicit
editorial adaptation; keep separate native-fps examples for fidelity review.
Honor entry/exit fields and continuity keys. A source-specific multi-shot recipe
owns its internal cuts; do not replace them with generic dissolves.

## Verify the rendered edit

Use `npm run verify -- --help` for the output-manifest verifier. It checks
decodability, dimensions, cadence, frame count, silence and provenance. It cannot
approve fidelity. Inspect the actual output at normal speed, including first/
last frames, construction order, intermediate movement, holds, content fit and
every join. Compare it to the selected moving-source treatment and record exact
frames for discrepancies. Contact sheets alone cannot verify motion.

A fresh-context reuse trial must use only this package, the delivered catalog,
the brief and supplied original assets. Selecting recipes is part of the trial.
Do not ask the original builder for missing instructions or patch implementation
files. Report such gaps so the shipped API or documentation can be corrected,
then rerun from a fresh package. Neither render success nor polish is a fidelity
pass. Keep unresolved examples out of the completed count.
