Unpublished local test candidate. Synthetic only; not production readiness.
Guide / Markdown · Toolchain / ZIP
Recording → capture → edit
This is the production handoff for the existing Remotion project. It reuses
RecordingClock, alignToRecording, the Trail bitmap/camera adaptation, the
bundled fonts, and the OBS worksheet. It is not another editor or playback
synchronizer. Read RECORDING_ALIGNMENT.md, ASSET_ADAPTATION.md and the
relevant RECIPE_GEOMETRY.md entries alongside it.
Boundary: preserve the supplied talking head outside public/. OBS plays
that recording, including its only narration. Google Slides plays the separate
silent presentation. No compositing, replacement voice, duplicated narration,
or default music. Real production rendering requires the single consolidated
storyboard/demo approval. A synthetic-only pass never establishes Poe behavior,
human approval, or actual OBS/Slides/Zoom readiness.
1. Prepare a supported local environment
The tested profiles are Linux x86-64, Node 24.13.1, CPython 3.14.7 for media
checks, and CPython 3.13 for the optional local ASR adapter. Other platforms are
untested. FFmpeg/ffprobe with libx264 and a working Chrome/Chromium installation
are explicit prerequisites. HOST_SETUP.md records the browser library and
network-interface failure modes encountered on the test host.
npm ci
npm run typecheck
npm test
python3.14 -m venv .media-env
.media-env/bin/python -m pip install --require-hashes -r requirements-linux-py314.lock
python3 scripts/test-media.py
export PRODUCTION_PYTHON="$PWD/.media-env/bin/python"
export REMOTION_BROWSER_EXECUTABLE=/path/to/working/chrome-headless-shell
Initial dependency/browser/model provisioning can require internet. No source
media, transcript, capture, or composition is uploaded by the included tools.
To reproduce offline, prefetch the locked wheels, npm ci dependencies and
browser/model, then use pip --no-index --find-links wheelhouse --require-hashes.
The original study's six-distribution lock is retained; the Remotion dependency
lock is extended only for the optional browser capture/playback adapter.
2. Inspect the recording before selecting recipes
Put the supplied file under private/, not under the served asset directory.
The inspector hashes it, records actual stream metadata, compares decoded PCM
tracks, and creates an untrimmed 16 kHz mono analysis derivative. Duplicate
tracks do not imply multiple speakers. If distinct tracks exist, it refuses to
guess. Inspect them and repeat with an explicit stream index:
python3 scripts/media.py --report private/inspect-run.json inspect \
--source private/recording.mp4 --out private/intake --audio-stream 1
The selected stream's original offset relative to the container start is
retained. ASR time on analysis.wav is mapped back by that offset; do not trim
leading silence and then call the new clock original recording time.
For optional local transcription, provision a supported faster-whisper model directory through your authorized tooling. The adapter never downloads one:
python3.13 -m venv .asr-env
.asr-env/bin/python -m pip install --require-hashes -r requirements-asr-linux-py313.lock
.asr-env/bin/python scripts/transcribe.py --audio private/intake/analysis.wav \
--model /path/to/local/model --out private/raw-asr.json
python3 scripts/media.py --report private/transcript-run.json import-asr \
--intake private/intake/intake.json --asr private/raw-asr.json \
--out private/transcript.json --engine faster-whisper-1.2.1 \
--revision MODEL_REVISION --proper-nouns PRODUCT_NAME
Another authorized ASR tool may supply segments[].words[] with word, start,
end, and optional probability, relative to the analysis WAV. Retain its raw
file, engine/revision and command. The supplied adapter records every model
file hash, parameters and software version. Do not describe estimated word
decimals as human-certified timing or infer measured vocal stress from meaning.
The importer flags words whose first 120 ms fall below a triage acoustic
threshold. The default is −35 dBFS over 20 ms windows, adjustable at inspection;
it is not a universal silence detector. Keep the raw times. Add review decisions
under review_decisions with uncertainty_id, status (resolved or
accepted-uncertain), reason, and evidence. For real production also require
human_verified: true after that review. Do not delete uncertain words.
Watch the source's actual gesture and ending. Retain tail-observations.json
with source_sha256, evidence_kind: "visual-inspection", start_seconds,
end_seconds, and observations. Noisy but calm footage can be usable; an
audio silence threshold cannot establish a wave or pose. The worked fixture
has a raw first-word estimate at 0 although its acoustic onset is near 0.9 s;
it also misrecognizes a name and a number. Those uncertainties remain visible.
3. Derive the review packet
Use examples/transfer/packet.json as a complete worked input, not as a timing
preset. src/production.ts is the typed contract and executable validator.
The schemaVersion is 1. Paths in a packet are relative to the downloaded
project root; every input is bound by SHA-256. Generate a binding with
sha256sum relative/file or Python's hashlib.file_digest.
recording,intake,transcript: immutable input bindings.timing.worksheet: the existing OBStiming-private.json, schema 1 with secondsC,H,T,E,L,P,B,R1,R2,R3; no second worksheet is introduced.nominalReactionSecondslies within the observed range.evidenceKindissynthetic-fixtureormeasured-rehearsal, never implied by decimal precision.timing.tailObservation: the source-bound visual record. In production,rehearsalEvidenceadditionally binds a record containingkind: "measured-rehearsal",setup, and at least threetrialswithreaction_seconds. These are claims to audit against the real rehearsal, not measurements manufactured by this software.identityandexportProfile: original title/label/accent and explicit resolution/rate/format/color/no-audio settings. The implemented study profiles are 1280 or 1920 pixels wide, 16:9, 24/30/60 fps, H.264/yuv420p/MP4/BT.709. Supported encoding is not approval of a real presentation profile.captures: manifest binding, stableobjectId, actual settled-result time, authorized runtime/version/instructions, expected/actual outcome and evidence. The canonicalexpectedandactualoutcome strings must agree; a mismatch is a content/capture review conflict, not permission to rewrite the narration.unavailableorfailedstops the handoff. Verify real Poe against its current checkout instructions, exports, runtime and authorized data; no access means a precise conflict report, not invented proof. If one screen recording contains several verified results, separate capture IDs may reference that same manifest. Give each result its own settlement time and outcome evidence; retain the sameobjectIdwhen it is the same object. A later result must not borrow an earlier result's proof claim.beats: recording phrase bounds and proof anchor; reference URL, inspected source interval, reason and contrasting alternative; proposed motion; explicit capture-time map; complete proof and protected reading frames.
For each segments entry, fromFrame/endFrame are half-open local output
frames. mode: "play" advances capture time at 1× from sourceStartSeconds;
mode: "hold" uses a specific already captured frame. Omitted waits require
an exact gap in omissions with afterLocalFrame, source start/end, reason,
and a visible disclosure. The adapter renders that disclosure for two seconds.
Do not accelerate an actual interaction or reset an object's identity silently.
Choose motion.kind from hold, cut, or push; actionFrame, changeFrame,
zoom, focusX/Y use the existing full-frame camera geometry. Motion must end
before proof. evidenceKind: "proposed-edit" distinguishes these choices from
reference.evidenceKind: "source-observation". Source timestamps and easing
values are not interchangeable evidence.
First anchor completed proof to a recorded phrase, then work backward. Keep native product motion when it communicates the action; do not add a camera move to every shot. Account for actual capture waits and reading time. The provided reading budget is a proposed floor to test with a reader at meeting size, not a guarantee. If necessary, omit a documented wait, shorten surplus holds, choose a cut, or bring a conflict to review. Do not rewrite fixed speech.
4. Capture real behavior and import encoded PTS
Use the product-native collaborative browser when available. If it explicitly reports unavailable, the included optional adapter can record a permitted local or authenticated browser surface. It uses real browser actions, never generated result graphics. Credentials/account setup must be authorized separately; the example does not grant access or make external writes.
node scripts/capture.mjs --url http://127.0.0.1:8765/demo.html \
--actions examples/transfer/capture-actions.json --out private/capture \
--browser "$REMOTION_BROWSER_EXECUTABLE" --width 1920 --height 1080
python3 scripts/media.py --report private/capture-import.json capture \
--source private/capture/capture.webm --out public/captures/demo \
--kind native-recording --useful-region 0 0 1920 1080
The action list supports click, select, fill, wait, and assert-text;
see the worked list for the exact fields. Preserve the action ledger and actual
result. Its wall times are not encoded PTS. Import the actual file, inspect
decoded frames around initiation/arrival/settlement, and enter capture-relative
seconds from capture.json. Every decoded frame is hashed. Native browser
capture here has measured 25 fps cadence; replay holds each captured frame until
the next PTS. This is not a claim of 30/60 fps native capture.
--useful-region x y width height is the inspected useful rectangle, not the
container dimensions by default. Check the moving capture for letterboxing,
browser UI, downscaled content and interpolation. Useful width/height must cover
output dimensions times maximum zoom. If not, recapture closer or reduce the
crop. The supplied adapter cannot make padded low-resolution content sharper.
5. One review, then the checked render
Consolidate the timed storyboard, demo plan/results, transcript decisions,
reference choices, original identity, capture map/omissions, cue, measured
range, usable tail, export profile and unresolved constraints into the single
review. check validates the packet but is not approval:
node scripts/production.mjs check private/packet.json out/review-check
node scripts/production.mjs digest private/packet.json
The digest covers all packet fields except approval, including input hashes.
For approved real work set approval.state: "approved", planSha256 to that
digest, and humanEvidence to the retained authorization's path/hash. Do not
author the human's approval yourself. A material packet change invalidates it.
Synthetic studies instead use mode: "synthetic-study" and approval.state:
"synthetic-only"; they cannot be represented as production-ready.
node scripts/production.mjs render private/packet.json out/new-render
Use a new output directory. The command validates all source/capture bindings,
imports the OBS clock into alignToRecording, compiles the explicit edit,
renders with the existing camera/font system, encodes, probes the actual movie,
fully decodes it, compares every encoded frame with the rendered reference,
and rechecks source hashes. It writes a fresh .run.json status even on failure.
The temporary served render assets contain only referenced capture frames and
fonts, never the talking-head recording or transcript.
The output includes compiled-edit.json, expected frames/, presentation.mp4,
actual encoded-check.json, and pairing.json. The encoder applies the adopted
SDR study conversion and explicit H.264 color metadata; the checker requires
actual BT.709 matrix, range, primaries and transfer fields. Flags/sidecars alone
are not a pass. Never re-tag unknown third-party footage as if it were converted.
Every encoded frame, including motion, joins and protected holds, is compared at its actual PTS. Declared tolerance is mean RGB error below 4/255 and every 64×64 tile below 18/255. This is a lossy-encoding tolerance, not a perceptual guarantee or a detector for every possible one-pixel error. Missing reference frames, added audio, incorrect cadence/geometry/color or corrupt middle frames fail. A renderer can faithfully render a bad editorial plan; inspect that too.
6. Inspect moving output and deliver the pair
Serve only the intended local output directory. Do not serve a private project root or publish source recordings. For the permitted synthetic example:
python3 -m http.server 8766 --bind 127.0.0.1 --directory out/new-render
node scripts/playback.mjs --url http://127.0.0.1:8766/presentation.mp4 \
--out out/playback-640 --width 640 --height 360 --browser "$REMOTION_BROWSER_EXECUTABLE"
The playback check runs the entire encoded file at 1× without seeking and records video-frame callbacks, elapsed/media clocks, displayed dimensions, errors and frame drops. Repeat at the intended meeting size and inspect text, action/result order, object identity, cut boundaries, cue and ending. Screenshots are supplemental, not a substitute for moving playback. Automated playback is not a human reading/comprehension check or an actual meeting rehearsal.
pairing.json identifies both files, nominal/observed start offsets, cue,
presentation end and minimum usable reserve. Rehearse the real OBS virtual
camera/virtual microphone and Slides/Zoom pair using the OBS runbook, with
single narration, audience-side lip-sync, presentation alignment, and manual
mute/video-off before usable tail end. Keep those gates untested until done.
Worked transfer and limits
examples/transfer/packet.json is a 33 s Moss Ledger companion derived from its
35 s synthetic recording and actual fixture runtime. It retains raw ASR errors,
two identical audio tracks plus a silent track, low-level noise during the calm
tail, a genuine seven-second app wait, a 5.4 s declared omission, stable object
identity, a still-camera result beat and one later settled-detail push. The title
cuts to the actual app at 2 s. Invented synthetic reactions .55/.65/.75 give a
2.55 s minimum usable reserve. The figure leaves its calm pose at 33 s even
though the file continues to 35 s. These are fixture facts, not real calibration.
Replay without changing core constructions:
python3 scripts/prepare-example.py
node scripts/production.mjs check examples/transfer/packet.json out/example-check
node scripts/production.mjs render examples/transfer/packet.json out/example-render
The download retains the encoded synthetic recording and capture, raw ASR and intake records. It does not ship hundreds of redundant decoded PNGs. The first command decodes the supplied capture locally and refreshes the packet's bindings; it needs no network, private files or new editorial choices. Run it once in a fresh extracted project. Do not count an unprepared example as a verified packet.
To recapture, serve examples/transfer, use its action list, import the new
capture and re-observe its PTS; do not reuse old wall-to-source times. Replace
the capture binding/map in a new packet. The main site includes the original
study verifier's bounded --only mode and corrupted-frame controls separately.
Real-product access, human review, and a real meeting remain untested by this
synthetic transfer.