# Paragraph cuts: original SVG, Remotion and Resolve guide

One existing example: `type-paragraph-cuts`. Prepared September 13, 2026.
**Guide/preparation evidence only. No new mechanism, source-quality approval,
native Resolve success or publication approval is claimed.**

The paragraph is already formed. A cut introduces crop 1; two internal hard
cuts select crops 2 and 3. The three dwells last **7, 9 and 17 frames**. Nothing
types, pans, eases, dissolves or fades. Both retained original-content variants
use the same unchanged `Treatment` composition and recipe.

Read [content and timing](CONTENT_AND_TIMING.md), then the
[Resolve construction](RESOLVE.md). [Verification](verification.json) separates
technical checks from the pending source and application reviews.

## Exact downloads and contents

- `core-selected.zip`: 23 byte-for-byte members selected from the existing
  `core-publication-v08.zip`, including its renderer, recipe, two inputs, pinned
  package/lock files and unmodified Geist font/OFL license. No new composition.
- `downloads.json`: exact original archive URL, archive hashes, sizes and
  per-member SHA-256s. The original public URL returned HTTP 403 in this
  environment; the **included selected archive** is the tested offline route.
- `assets/index.json`: SHA-256 and half-open dwell binding for all **six SVGs**.
  `original-crop-1.svg` through `original-crop-3.svg` use the default content;
  `adaptation-crop-1.svg` through `adaptation-crop-3.svg` use the second content.
- The SVGs contain editable original text, CSS, an SVG `foreignObject` and an
  embedded unmodified Geist font. They contain **no raster image or film frame**.
  Keep `assets/OFL.txt` with them. These are browser-rendered SVGs, not outlined
  paths or a promise of direct SVG import in Resolve or other vector editors.
- `kit.py` regenerates those exact SVGs from the existing recipe and font;
  `run.mjs` renders that recipe or rasterizes its SVGs for Resolve. PNGs and MP4s
  are generated locally, not supplied inside this public kit.

The supplied core retains its original comments, source-study metadata and
dependency license declarations. Source-study references are provenance, not
bundled source-film assets. No source movie, research raster frame, private
filesystem path, dependency directory, `.drp` or `.dra` is included.

## Tested environment

The tested profile is **Linux x86_64, Node v24.13.1, full Chrome for Testing
152.0.7977.42, Remotion 4.0.520, React 19.2.8 and TypeScript 5.9.3**. Exact
direct dependency versions, core member bytes, Node version and full Chrome
ELF bytes are checked before rendering/preparation. See `downloads.json` and
the generated `environment.json`. Browser binaries and dependencies are not
downloaded or copied. An executable wrapper and HeadlessShell are rejected.

Use an already provisioned dependency directory matching the included lock;
FFmpeg and FFprobe must be available on `PATH`. The Chrome runtime libraries
must be resolvable by the host (set `LD_LIBRARY_PATH` if that installation needs
it). Other OS/browser/runtime profiles require new verification. Host shared
libraries and the complete transitive dependency tree are **not** certified by
the public wrapper; the builder's environment inventory records additional
binary/library hashes. This is not a clean-install or universal-platform claim.

## Reproduce without installing or creating dependency symlinks

Set `KIT` to this unpacked kit, `PARAGRAPH_SHARED_NODE_MODULES` to the existing
read-only dependency directory, and `CHROME` to the full Chrome binary, not a
wrapper. Set a **short**, writable absolute `TMPDIR`; Chrome's Unix socket name
must fit there. All temporary browser, bundler and test work stays in `TMPDIR`.
In a bounded shared run, check its existing storage guard before allocation and
use its existing encoder lock; do not create a different lock or weaken its
symlink policy. Only the storage policy's explicit browser-metadata exception
applies. The kit creates **no dependency symlink**.

The following is the tested command sequence. `WORK` and `OUT` must be new
directories; `ENCODER_LOCK` names the shared encoder lock. Examples use Linux
`flock`. Run only after the run's storage guard has passed.

```bash
export NODE_PATH="$PARAGRAPH_SHARED_NODE_MODULES"
export PYTHONDONTWRITEBYTECODE=1
export WORK="$TMPDIR/${PARAGRAPH_WORK_NAME:-paragraph-demo}"
export OUT="$WORK/evidence"
mkdir -p "$WORK/home" "$WORK/config" "$WORK/cache" "$WORK/data" "$OUT"
export HOME="$WORK/home" XDG_CONFIG_HOME="$WORK/config"
export XDG_CACHE_HOME="$WORK/cache" XDG_DATA_HOME="$WORK/data"
ulimit -c 0

python3 -B "$KIT/kit.py" stage --core "$KIT/core-selected.zip" \
  --project "$WORK/project" --modules "$PARAGRAPH_SHARED_NODE_MODULES"
node "$KIT/run.mjs" --action check --project "$WORK/project" --browser "$CHROME"
node "$KIT/typecheck.mjs" "$WORK/project"
node "$KIT/test_contract.mjs" "$WORK/project"
python3 -B "$KIT/test_kit.py"

python3 -B "$KIT/kit.py" svg --project "$WORK/project" --out "$WORK/svg"
flock "$ENCODER_LOCK" node "$KIT/run.mjs" --action render \
  --project "$WORK/project" --browser "$CHROME" --out "$OUT/renders"
node "$KIT/run.mjs" --action prepare --project "$WORK/project" \
  --browser "$CHROME" --svg "$WORK/svg" --out "$OUT/prepared"
flock "$ENCODER_LOCK" python3 -B "$KIT/verify.py" \
  --renders "$OUT/renders" --plates "$OUT/prepared" --out "$OUT/check.json"
```

The external ESM resolver follows the existing shared-dependency pattern.
Webpack and TypeScript resolve against that same external directory. The core,
its compiler settings and dependency tree remain unchanged. Do **not** run the
core's full `npm test`: its wider-library fixtures are intentionally absent.
The commands above run the focused kit tests and both real content renders.

Keep each movie's generated `.manifest.json`. To recheck the core's provenance
verifier without a local dependency install:

```bash
cd "$WORK/project"
node --experimental-loader "$KIT/shared-dependencies.mjs" scripts/verify.mjs \
  "$OUT/renders/original.mp4"
node --experimental-loader "$KIT/shared-dependencies.mjs" scripts/verify.mjs \
  "$OUT/renders/adaptation.mp4"
```

`verify.py` decodes **every** frame, checks the exact rational clock, and compares
every output frame with its corresponding prepared crop. Its mechanical gate
is ink-mask XOR/union ≤3% at grayscale threshold 128, at most 1px bounding-box
shift, exactly 33 frames and internal cuts at 7/16. A wrong-crop negative control
must fail. These are preparation checks, not a source-quality score. Optional
`--baseline` compares every decoded RGB frame and timestamp against an existing
directory containing the two retained movies. Do not compare different text
inputs as if they should have identical pixels.

## Keep approval gates separate

The preserved movies match both retained outputs byte-for-byte. Original SVG
preparation has been tested; **Resolve itself has not been run**. Static frames,
image metrics, browser callbacks and successful encoding do not establish moving
video perception. A fresh independent critic follows; the builder awards no
source-quality win. Known source discrepancies remain in `CONTENT_AND_TIMING.md`.
