# A short shot can disappear from scene candidates

This is an executed, local source experiment recorded on September 7, 2026. It is **not** a browser end-to-end test, an AI caption benchmark or a general shot-detection accuracy estimate.

## What is in the kit

Four 12-second H.264 MP4 files contain original, procedural geometric slates, with no audio, people, stock footage or AI-generated imagery. The files are 224 × 224, 30 fps, 360 frames, yuv420p, CRF 18. All use the same A/B/C slate recipe and encoder settings.

| File | Deliberate visual change | Default selected timeline times |
| --- | --- | --- |
| `hard-cuts.mp4` | A → B at 4 s; B → C at 8 s | 0, 4, 8 s |
| `dissolves.mp4` | A → B over 3–5 s; B → C over 7–9 s | 0, 4, 5.333, 7.333, 8.667 s |
| `short-between-samples.mp4` | B appears in A for 4.1–4.3 s | 0 s |
| `short-on-sample.mp4` | The same B insert appears for 4.6–4.8 s | 0, 5.333 s; selected picture has already returned to A |

The initial 0 s frame is retained by the selector as a segment boundary. It is not evidence of an interior scene change.

Each `*-samples.png` displays all 19 sampled pictures, left to right, at timeline labels 0, 0.667, 1.333, …, 12 seconds. Green borders identify **selected** pictures; unbordered pictures were sampled but omitted by selection. The last label is 12 s, but its source request is clamped to 11.95 s and reads the decoded frame whose PTS is 11.933 s. Images are downscaled to 64 × 64 solely for this contact sheet, after analysis at 224 × 224.

`short-on-sample-detail.png` enlarges that decision by showing the original 224 × 224 sampled pixels at 4.000, 4.667 and 5.333 seconds side by side. Selection borders are added only in this display, after analysis.

`sample-scores.csv` preserves every sample's time, decoded PTS, raw difference, motion, histogram change, quality, weighted score, threshold and selection status. `run.json` contains the same values plus threshold controls, a minimum-gap control and explicitly hand-authored caption timing inputs/outputs. `commands.json` contains executed native commands and exit codes; the probe files preserve codec metadata. `source-manifest.json` identifies exact source URLs and SHA-256 fingerprints. `discovery-record.json` preserves the initial, disproved expectation that sampling the short insert would be sufficient to select it.

## Reproduce without an account or model download

1. Extract `autoedit-case-kit.zip`. Install Node.js (the recorded run used 22.14.0), and native FFmpeg/ffprobe with libx264 support (recorded FFmpeg 8.0.1).
2. From the extracted directory run `shasum -a 256 -c SHA256SUMS` to verify the published artifacts.
3. Run `node reproduce.mjs ./my-run`. It creates its own source frames and media; no network, API key, npm installation or external input is needed. It needs about 220 MB transient memory for decoded/encoded buffers and up to roughly 1 MB of output space. Exact memory use depends on runtime and encoder.
4. Read `my-run/run.json`, the CSV and MP4s. The script exits nonzero if the fixture observations it checks differ. Passing checks reproduce both successes and failures; they do not certify product quality. Different native encoder/decoder builds can change exact pixel values, bytes, score rankings and selection results. Preserve the new environment and output when comparing versions.

## Exactly which production code ran

All bundled upstream source is from public Timeline Studio commit `68980d142cce421eab86cd4ef26a4475a6affd56`, the snapshot originally cited by the article. It was read from the local repository's Git object database, not copied from an uncommitted working file. This kit does not claim that the currently deployed editor still runs that snapshot.

- `src/workers/auto-edit.worker.js` runs unchanged inside Node's VM. A minimal `self` shim passes messages synchronously to its real `onmessage` and captures `postMessage`. This exercises the real luminance, histogram, block matching, quality and difference calculations. It does not measure worker scheduling, transfer overhead or browser performance.
- The contiguous helper block from `function median` to the line before `function waitForMedia` in `src/lib/autoEdit.js` is evaluated unchanged except for removal of `export` keywords. The executed selectors and caption timing normalizer retain their original bodies. No imported IDs, AI sessions, DOM functions or React state run.
- Three literal sample-schedule statements are checked against the bundled source and transcribed in the harness: 1.5 samples/s for this 12-second fixture, `ceil(duration * rate) + 1`, and `sample / (sampleCount - 1)`. The schedule therefore requests 19 samples. Actual browser video seeking is replaced by a native FFmpeg full decode followed by `floor(sourceTime * 30)` frame lookup. Square 224 × 224 inputs make the production contain-fit an identity; browser scaling, JPEG encoding and non-square letterboxing are outside the case.
- `src/hooks/useAutoEdit.js` is included for **source review only**. The automatic-edit Apply handler hands `review.captions` to `commitCaptionSegments`. The hook does not prove preservation or merging of existing captions, nor did this harness render its review UI.

## Why the two short-shot failures are different

The insert at 4.1–4.3 s lies entirely between decoded samples at 4.0 and 4.667 s. There are six encoded B frames, but none enters the detector. A lower score threshold cannot recover pixels that were never supplied.

The moved insert at 4.6–4.8 s is sampled at 4.667 s and exceeds the default threshold: weighted score approximately 0.67036. The return to A at 5.333 s scores approximately 0.67414. Candidates are ranked by weighted score, so the later A frame is accepted first. The 1.2-second minimum gap then suppresses the B frame only 0.667 s away. The case therefore retains a transition signal while losing the visually important insert.

The harness reruns selection at explicit thresholds 0.03, 0.1, 0.3 and 0.6. The default adaptive threshold is 0.1 in all four clips. None of these thresholds rescues either short-shot result. A separate `minTimeGap: 0.3` developer control selects both sampled transitions in the moved-insert fixture; it still cannot supply an unsampled image in the between-samples fixture. These are helper arguments in a diagnostic harness, **not claims that the live UI exposes sliders**.

The source computes a `localPeak` field but never filters on it. “Only local peaks survive” is therefore not a correct description of this snapshot. Its selector uses raw score distribution to set a threshold, quality-weighted scores to rank/filter, a quality gate and a same-segment time gap. Segment-start pictures are retained before these filters. The two dissolves also produce four additional candidates, demonstrating why a candidate count is not a cut count.

## Caption timing control

The report contains three hand-authored strings, not generated captions. Their supplied ranges are 0–4, 1–2 and 1.5–3 s for a three-second clip. The production `normalizeClipCaptionTimings` returns 0–0.5, 0.5–1.5 and 1.5–3 s. The preferred 1.2 s value is reduced to 1 s for three captions in this clip, and collision adjustment leaves the first caption only 0.5 s long. This is a concrete reason to inspect readability after normalization. It does not measure language quality, speech alignment or generated caption accuracy.

## Use this to make an editing decision

For a montage containing a short product reveal or action, watch the source before relying on a candidate gallery. If the important picture is absent from **samples**, re-run a suitable sampling strategy or mark it manually. If it is sampled but absent from **selected candidates**, investigate ranking and minimum-gap suppression before lowering a threshold. For dissolves, review candidates within and immediately after the transition; several candidates can describe one transition. Preview each caption at playback speed and preserve an earlier project before applying a reviewed draft.

The fixture is deliberately controlled. It provides no recall/precision estimate for real-world footage, no semantic event recognition, no camera-motion benchmark and no proof of online model availability. It changes no deployed app code. Browser LanguageModel/Translator inference, model download, human review, caption application and final export were not executed here.

Upstream source retains its MIT license in `upstream/LICENSE`. Original fixture recipe, case harness, measurements and documentation are supplied by AI Creator for reproducibility.
