# Auto-Conform analysis assets

`auto-conform-v1.schema.json` is the single versioned contract for benchmark inputs, matcher results, cache metadata, Top-K evidence, confidence decisions, and later placement outcomes. Public time values are seconds.

`contract.py` validates that schema directly with a deliberately small Draft 2020-12 subset so the bundled Python/OpenCV runtime does not need a separate `jsonschema` dependency. Keep the schema within the supported keywords or extend the validator and its tests together.

The v1 safety policy distinguishes `AUTO_CONFIRMED`, `REVIEW_RECOMMENDED`, and `NO_RELIABLE_MATCH`. A matcher may rank a best candidate without auto-confirming it; the product workflow explicitly chooses whether low-confidence winners are placed or left as gaps and can expose lower-ranked candidates as disabled review alternatives without changing their confidence.

`auto_conform_benchmark.py` also serves as the dependency-free matcher core while the product workflow is assembled. Pass `--cache-dir <folder>` to reuse source indexes across runs. Cache keys include the declared source `cacheIdentity`, usable range, sampling interval, coarse decode geometry, descriptor version, chunk duration, and cache-format version. Source-index v2 plans the complete globally aligned sampling grid first, decodes five-minute half-open chunks by default, captures FFmpeg filter-output PTS for every stored sample, and atomically checkpoints each validated NumPy `.npz` chunk beneath a source manifest. Every grid point strictly before the declared usable-range end is part of the plan, including a final point in a partial sampling interval; a point exactly at the end is excluded. Codec EOF rounding does not produce that last valid point consistently, so the decoder applies bounded last-frame padding, lets FFmpeg decode one sampling interval beyond the requested range, then removes each image/PTS pair at or beyond the true half-open end. The remaining observed PTS must match the complete plan exactly; missing, excess, shifted, duplicate, non-monotone, or early samples fail closed. Exact-fit refinement windows use a direct center-frame export instead of attempting an empty decode range. Warm setup validates manifest completeness and recorded chunk sizes without decompressing descriptors; retrieval then loads each chunk with `allow_pickle=False`, validates its arrays and timestamps fail-closed, and scans it once per bounded shot batch. Invalid deep data is removed from the completed manifest so the next run repairs only that chunk. The product default gives each bounded five-minute index chunk a fixed one-hour FFmpeg timeout, deliberately separate from the shorter random-access frame timeout. `--cache-max-bytes` bounds legacy v1 files and v2 source directories together with least-recently-used eviction while protecting every index addressed by the current run; an exact legacy v1 file is removed only after its complete v2 replacement validates. Omit `--cache-dir` for an ephemeral chunk index inside the run work directory. Any change to descriptor math or variant generation must bump `DESCRIPTOR_VERSION`; cache-key fields separately invalidate decode-geometry and chunk-plan changes. `--placement-table-output` writes one strict winner row per analyzed shot. Batch finalization also writes a strict alternative table for every retained rank above one on uncertain shots. `auto_conform_alternative_plan.py` combines that table with a fresh Premiere track/marker snapshot and classifies fixed-rank lanes without adding a general JSON-query language or overwriting editor content.

Matcher result compatibility is versioned independently through `ANALYSIS_VERSION`, so adding required diagnostics or changing result semantics does not invalidate reusable descriptor caches. Completed analysis results include `run.analysisDiagnostics`. Retrieval-side reference work and refinement-side source work have separate timing fields, while pixel identity, local features, motion, and image reads are divided into reference and source/comparison costs. Feature-detector construction is reported separately so it does not migrate between reference and source buckets as reuse changes. Media-input counters count every independently opened FFmpeg input, while `ffmpegInvocations` counts child processes. Ordered batch finalization sums run and per-shot rollups. Each candidate's score evidence also records `alignmentWinnerMargin`, the score difference between the winning and runner-up neighboring frame alignment, plus `alignmentOptionCount` so calibration can distinguish zero, one, two, and three legal alternatives. A single legal frame has margin `1.0`; a tied neighborhood has margin `0.0`; no decoded alignment has count `0` and margin `0.0`. These fields are diagnostic only and do not influence current ranking, confidence, or placement.

Exact PNG exports put `select='eq(n,0)',showinfo` before the unchanged scale filter. Multiple exact requests may share one bounded FFmpeg process, but each retains its own independently sought input, lossless PNG output, and named `showinfo` record. This records the PTS of the one frame that is actually allowed to reach each output while remaining byte-identical to the earlier uninstrumented PNG path on the regression fixtures. The export fails locally when its role is unknown, its frame rate is invalid, or its decoded timestamp is non-finite. A decoded timestamp outside the nominal one-frame tolerance is recorded as `OUTSIDE_NOMINAL_FRAME` and counted, but does not fail analysis because VFR and frame-gap media can legitimately exceed nominal cadence. PTS evidence is bounded to 64 records: the first 32 records are retained for chronological context and the remaining slots retain the largest absolute requested-to-decoded deltas. Across multiple four-shot matcher batches, the chronological portion therefore normally comes from the earliest batch and is not intended as a representative sample. Aggregate counts and ordered per-shot maxima always cover all exports. This evidence gates frame reuse in the next milestone; it does not enable reuse by itself.

Refinement-window JPEG exports group up to five candidate requests in one bounded FFmpeg process. Every request still has its own independently sought media input, FPS/trim/showinfo/scale chain, JPEG sequence, and half-open PTS validation; only child-process startup is shared. Decode and scoring are interleaved per group, and scored frame arrays are released before the next group is decoded, so increasing `--top-k` cannot make all candidate windows resident at once. `ffmpegInvocations` therefore falls while original/proxy media-input counters intentionally remain unchanged. Within a prepared shot, normalized reference pixel-identity vectors are cached by image identity and reference motion descriptors by anchor-pair index, just as reference local features are reused by image identity. These caches remove invariant reference work without changing candidate breadth, source calculations, scores, or decisions.

The product Recipe explicitly pins `--window-descriptor-mode coarse-consensus`, `--window-descriptor-min-correlation-separation 0.05`, and `--refinement-window-group-size 5`. The last option is a diagnostic process-organization control bounded to `1..5`; changing it must not change decoded windows or matching semantics. The separation is measured in raw descriptor-correlation units on `[-1, 1]`, not in the normalized `[0, 1]` descriptor-score units; `0.05` raw separation corresponds to `0.025` normalized score separation. A dense refinement window uses one spatial/polarity descriptor variant only when all three usable coarse anchors agree on that variant and every anchor clears the pinned separation. Any disagreement, weak anchor, missing anchor, or very short one-anchor shot falls back to all eight variants. The reduced dense scan chooses only an approximate center; the following alignment stage still evaluates the selected center and its legal immediate neighbors with all eight variants. Consequently, the exact path can recover a reduced-scan error only when it is at most one source frame. Corpus equality and the conservative fallback rule are therefore release evidence, not a mathematical proof for arbitrary footage.

The human-readable processing-time report exposes reference/source FFmpeg time, reference/source OpenCV time, image-read time, operation counts, retained-versus-total PTS evidence, and the largest requested-to-decoded PTS delta.

`matching_math.py` contains the dependency-free source-bound helpers used by the matcher. Candidate starts are clamped so the complete shot duration remains inside the declared usable source range; sources that are shorter than the shot are rejected before frame refinement. Refined starts are evaluated on the source media's frame grid before they are emitted, avoiding approximate ffmpeg window timestamps that Premiere would floor to an adjacent source frame.

`auto_conform_source_index.py` is the product-facing pre-index command used by **Build Auto-Conform Source Index**. It consumes the same strict source TSV rows as the reconstruction workflow, fills `PATH_SIZE_MTIME` identities from the direct media files, reuses `build_source_index(...)`, and writes an atomic durable source-index report. `--rebuild-selected true` removes only the exact cache identities addressed by the selected sources before rebuilding; it never clears the complete workspace cache. A shared editor-facing Auto-Conform workspace uses `cache/` for reusable descriptors, `reports/` for durable JSON results, and `runs/` for uniquely named disposable work folders. Local storage is recommended for the workspace even when source media is remote.

When the editor explicitly chooses overwrite behavior, the recipe clears the existing target video track before rebuilding it. Independent per-shot overwrites can otherwise leave microscopic fragments at floating-point-adjacent edit boundaries.

Placement-table source times may intentionally differ from the exact analysis/report values by at most one microsecond. That bounded handoff nudge prevents Premiere from flooring a mathematically frame-aligned floating-point value to the preceding frame; media-range edges remain exact.

`auto_conform_manifest.py` is the product-facing boundary between the DSL and the versioned JSON contract. It converts strict tab-delimited reference, source, and shot tables into a schema-validated manifest, rejects duplicate IDs, unexpected columns/fields, and inconsistent/invalid ranges, and preserves Premiere project-item and timeline-item refs for later placement and reporting. Keeping this conversion in the bundled Python asset avoids hand-assembled JSON and keeps quoted TSV parsing consistent across Panel and MCP runs. File-backed production sources should use `PATH_SIZE_MTIME`, which requires both `sizeBytes` and `modifiedAtMs`; a project-item ref alone is not a sufficient identity when media may be replaced. Product workflows may pass `--fill-file-identities` to read those two values directly from the validated media paths instead of attempting date conversion in the DSL.

`auto_conform_finalize.py` merges the DSL's strict per-shot outcome table back into the validated analysis result and atomically writes the durable final report. It requires exactly one outcome for every analyzed shot, preventing a partially applied timeline mutation from being reported as a complete conform.

Ranked alternative outcomes are a separate durable TSV beside the final JSON and timing report. A rerun reuses an alternative only when its fixed rank lane contains one exact disabled project-item/sequence/source-range match and a durable marker with the same shot/rank/source/range identity. An exact workflow-owned item that remained enabled is repaired in place; any other overlap is preserved and reported as occupied. Placement or verification failure for an optional alternative is reported per rank and does not abort winner reconstruction after any exact fresh enabled placement has been removed safely. If Premiere rejects that cleanup and an enabled higher-track clip could cover the winner, the run fails closed.
