docs(register): record the quality vector, the benchmark, and what lossless fanout costs

Status for the two changes just landed, plus the consequence AR-004's
fix has for the scene join.

The annotator's old comment said blocking there was safe because the
branches are independent. That stopped being true when the fanout became
lossless: it now stops popping once one branch stops taking, so a
starved detector and a waiting annotator would wedge. What actually
makes it safe is join depth -- the fanout can run the dense branch ahead
by the whole of the sampled branch's buffering, which at kSceneJoinDepth
256 and sample_fps 5 against a 25 fps source is ~1200 dense frames
against TransNetV2's 100-frame window. Cutting kSceneJoinDepth below the
window would reintroduce the wedge, so it is now a correctness
precondition rather than a tuning knob.

TRACES: AR-004, AR-010, AR-028, AR-029 | VR-015 | SR-002
This commit is contained in:
2026-08-05 14:38:42 +02:00
parent a5ee3c05ce
commit 718dad688d
4 changed files with 521 additions and 136 deletions
+115 -13
View File
@@ -253,6 +253,26 @@ the same response.
perfectly healthy. Measured on the **112×112 aligned crop**, not the raw box: perfectly healthy. Measured on the **112×112 aligned crop**, not the raw box:
the crop is already scale-normalised, so a measure taken there cannot silently the crop is already scale-normalised, so a measure taken there cannot silently
re-measure face size and double-count it against AR-002. re-measure face size and double-count it against AR-002.
The measure is the **variance of the Laplacian divided by the variance of the
crop** — `crop_sharpness()`, dimensionless. The division is the part that
earns its place: a raw Laplacian variance, the textbook measure, scales with
the square of image contrast, so a dim scene reads as soft and a graded-up one
as sharp, and VR-012 would locate a different knee in every film. That is
AR-024's objection to the raw cosine in another metric. Normalised, the axis
means the same thing everywhere, which is the precondition for a single knee
existing at all.
Read spectrally it is `E[|ω|⁴]` under the crop's own energy distribution, so
the blur ladder is monotone by construction rather than by fitting: Gaussian
blur multiplies that distribution by `e^{-σ²|ω|²}`, which can only move mass
downward. Two consequences follow from the same identity and are recorded on
the function: it needs the low-frequency mass real images have (on a
flat-spectrum synthetic an anisotropic smear makes it *rise*, because the
surviving perpendicular detail really is as fine as before), and it conflates
focus with intrinsic texture, so a bearded face outscores a smooth one at equal
focus. Both are true of every no-reference sharpness measure, and both are
reasons AR-028 carries the number rather than thresholding on it.
- **Visibility** — extreme pose or occlusion means the face presents fewer of the - **Visibility** — extreme pose or occlusion means the face presents fewer of the
features the embedding assumes are present. The measure is the **residual of features the embedding assumes are present. The measure is the **residual of
the AR-005 alignment fit**: the RMS landmark error, in canonical 112×112 the AR-005 alignment fit**: the RMS landmark error, in canonical 112×112
@@ -333,18 +353,43 @@ hand-chosen cutoff on an uncalibrated measure is the same unfalsifiable magic
number AR-024 retired for similarity, and it would fail the same way: meaning number AR-024 retired for similarity, and it would fail the same way: meaning
something different for every detector, every embedder and every film. something different for every detector, every embedder and every film.
**Current:** visibility is measured and carried`estimate_alignment()` in **Current:** all three axes are measured and carried, and the vector reaches the
`src/face_utils.hpp` returns the residual alongside the transform, and dump. `FaceAlignerFunc` is where it is filled in, because both measured axes fall
`FaceAlignerFunc` writes it to `DetectedFace::alignment_residual`. Size is out of work the warp already does: visibility is the residual from
`min_face_px` (40, decoded-frame space — AR-002 still open). Sharpness is `estimate_alignment()`, and sharpness is `crop_sharpness()` on the 112×112 crop
unmeasured. Nothing yet *consumes* any of it: no discount is applied, and the node has just produced. Size stays `bbox` — deliberately not copied into a
`align_face()` still drops the degenerate-fit case without counting it. field of its own, since that would hold the same quantity in two coordinate
spaces and the copy is the one that drifts. No face is admitted unscored, so a
negative value downstream is a bug rather than a poor-quality face. The
degenerate-fit case is still dropped — it has no crop and no fit to score — but
is now **counted** and reported once at EOF instead of vanishing.
**Gap:** AR-029 entirely. For AR-030, the measure exists but the discount does `sharpness` and `alignment_residual` are written to the VR-001 dump as per-face
not — it must reach `EvidenceDiscounter` as the reliability term. For AR-028, the columns parallel to `confidence`, taking the dump to `schema_version` 2. The bump
residual does not yet reach the VR-001 dump, which is what VR-012 needs to run is not for readers — both sides check by name, and a v1 dump still replays — but
from fixtures; that is the next step, since it unblocks the study that sets so that a consumer of the vector can tell *never scored* from *scored zero*,
every remaining behaviour. which is a real reading on this axis. Nothing yet *consumes* any of it.
**Gap:** three, in the order they block each other.
1. **The fixtures do not carry the vector.** They are v1, and re-dumping needs a
GPU host (`scripts/make_fixtures.sh`), so until that runs VR-012 has recorded
data available in principle and none in hand.
2. **AR-030's discount does not exist.** The measure must reach
`EvidenceDiscounter` as the reliability term, multiplying the novelty weight
rather than replacing it.
3. **Two properties of the sharpness measure are recorded but unquantified on
real faces**, and both distort the low end of the axis, which is where a knee
would go. It is exactly contrast-invariant in the algebra, but the 8-bit
quantisation floor lands in the numerator, so a crop that is *dim and soft*
reads sharper than it is — on the synthetic ladder a half-contrast copy reads
0.9% high when sharp and 148% high at σ 2.5. Separately, `align_face` warps
with `BORDER_CONSTANT`, so a face crossing the frame edge brings a hard black
step into the crop, and a step edge is high-frequency; the normalisation
blunts this but does not remove it. Neither is corrected here. The candidate
fixes are a validity mask or a different border mode, and the second changes
what the embedder is fed (AR-011) — so VR-012 measures the size of each effect
on the dumped distribution first, and no correction is chosen before that.
## AR-007, AR-008 — Tracking ## AR-007, AR-008 — Tracking
@@ -1575,7 +1620,10 @@ Persist pipeline state at the point where the expensive work ends.
per-frame index table (`face_offset`, `face_count`) pointing into them. Avoids per-frame index table (`face_offset`, `face_count`) pointing into them. Avoids
variable-length HDF5 types and reads straight into numpy. variable-length HDF5 types and reads straight into numpy.
- Stores per frame: `timestamp_sec`, `frame_idx`, `is_cut`, `is_scene_boundary`. - Stores per frame: `timestamp_sec`, `frame_idx`, `is_cut`, `is_scene_boundary`.
Per face: `embedding` [N,512], `bbox` [N,4], `landmarks` [N,10], `confidence`. Per face: `embedding` [N,512], `bbox` [N,4], `landmarks` [N,10], `confidence`,
and from v2 the AR-028 quality vector — `sharpness` [N] and
`alignment_residual` [N]. Size, its third axis, is `bbox` and is not
duplicated.
- Invariants: embeddings unit-norm; `face_offset` contiguous; bboxes and - Invariants: embeddings unit-norm; `face_offset` contiguous; bboxes and
landmarks in **decoded-frame** pixels with `bbox_upscale` recorded alongside landmarks in **decoded-frame** pixels with `bbox_upscale` recorded alongside
(the dump is a faithful tap, so it does not transform what the tracker saw — (the dump is a faithful tap, so it does not transform what the tracker saw —
@@ -1586,10 +1634,16 @@ Persist pipeline state at the point where the expensive work ends.
Schema owned by [`scripts/optimizer/SCHEMA.md`](../scripts/optimizer/SCHEMA.md). Schema owned by [`scripts/optimizer/SCHEMA.md`](../scripts/optimizer/SCHEMA.md).
**Current:** C++ dump sink (`embedding_dump_node.hpp`, `dump_embeddings.cpp`), **Current:** C++ dump sink (`embedding_dump_node.hpp`, `dump_embeddings.cpp`),
read by `replay.py`. **Gap:** **AR-012 breaks the replay contract.** Track extents read by `replay.py`. At `schema_version` 2, which AR-028 took it to by adding the
quality columns; readers on both sides check the datasets by name, so a v1 dump
still replays and reports the vector as unknown rather than as zero.
**Gap:** **AR-012 breaks the replay contract.** Track extents
are decided in the tracker, which is *downstream* of the dump — so a replay can are decided in the tracker, which is *downstream* of the dump — so a replay can
reproduce them, but only if the dump preserves everything the tracker needs. reproduce them, but only if the dump preserves everything the tracker needs.
Verify `landmarks`/`bbox`/`is_cut` suffice, and bump `schema_version` if not. Verify `landmarks`/`bbox`/`is_cut` suffice, and bump `schema_version` if not.
The committed fixtures are still v1, so they carry no quality vector until
`scripts/make_fixtures.sh` is re-run on a GPU host.
## VR-002 — Replay and sweep ## VR-002 — Replay and sweep
@@ -1712,6 +1766,54 @@ round 1 seeding references that corrupt round 2.
"expansion helps live matching" from "expansion helps the second pass", which the "expansion helps live matching" from "expansion helps the second pass", which the
current all-or-nothing `expand_gallery` flag cannot distinguish. current all-or-nothing `expand_gallery` flag cannot distinguish.
## VR-015 — Per-node cost and bottleneck attribution
**Requirement: a run must be able to report where its time went, per node, and
which node is setting the pace.** Without it, optimisation is guesswork, and
worse than guesswork — the obvious number is wrong in a specific, repeatable
direction, so acting on it makes the pipeline slower.
**Why the obvious number is wrong.** KPN times a node across `fire_once`, which
wraps the functor *and* `push_outputs`. Under AR-004 a push parks on a full
downstream channel, so a node that is merely waiting bills that wait to itself.
On the SuperHero reference run (`docs/benchmark.md`) `frame_source` reported
`ema=141.899ms` per frame while its own decoder logged 12-18 ms: it was
backpressured, and the report named the *fastest* node in the graph as the most
expensive one. A second trap sits behind the first — `ema_exec_ms` is an
exponentially weighted average, so `frames × ema` is not a total; on a film whose
per-frame cost swings between crowd scenes and landscapes the two differ
substantially.
**Method.** Three measurements per node, none of which is sufficient alone:
| Measure | What it is | What it cannot tell you |
|---|---|---|
| `cpu_ms` | thread CPU time (`CLOCK_THREAD_CPUTIME_ID`) | GPU wait — a device-bound node looks idle |
| `exec_ms` | cumulative wall time inside the node | work from waiting — backpressure inflates it |
| `pressure` | mean input fill mean output fill | how expensive the node is, only that it paces |
Queue occupancy has to be **sampled during the run**. `current_fill` is
instantaneous and every channel has drained by shutdown, so a single read at the
end describes an idle pipeline however congested it was.
**The number that matters** is `pressure`, because work piles up in front of the
bottleneck and starves everything after it, and that ordering holds whether the
node is waiting on a core, a GPU or a disk. `cpu_share` then selects the repair:
a pacing node with a saturated thread is CPU-bound and the work must get cheaper,
while a pacing node with an idle thread is device-bound, where batch size and
engine precision are the knobs and the C++ is not.
**Current:** `--benchmark <path>` writes the JSON report and prints a table at
shutdown; `src/benchmark.hpp`. Attribution is a pure function over KPN snapshots,
so it is verified on CI's GPU-free N100 (UT-120…UT-124) rather than only by
running the pipeline. The node graph is recovered from KPN's channel names, so a
re-wired topology needs no change here. Required `NodeStats::total_exec_us` in
the KPN submodule — the EMA could not be turned into a total.
**Gap:** GPU utilisation and memory are not sampled, so a device-bound verdict
says *that* a node waits on the GPU, not whether the GPU is saturated or merely
badly fed. That distinction needs NVML, and it is what VR-008 will want anyway.
## VR-008 — Gallery scaling benchmark ## VR-008 — Gallery scaling benchmark
Establish the throughput-versus-gallery-size curve required by A10. Establish the throughput-versus-gallery-size curve required by A10.
+7 -6
View File
@@ -31,7 +31,7 @@ Status: `Done` · `In Progress` · `Planned` · `TBD` · `Withdrawn`
| AR-001 | Detect faces in sampled frames; emit bbox, confidence, 5-point landmarks in original pixel space | SR-002 | High | Done | | AR-001 | Detect faces in sampled frames; emit bbox, confidence, 5-point landmarks in original pixel space | SR-002 | High | Done |
| AR-002 | Minimum face size **40×40 px** (VR-013 measured end to end; VR-005's 32 px is an embedder-only upper bound), expressed in **original** resolution (decoupled from `dense_scale`) | SR-002 | High | **Done**`FaceDetectorFunc::drop_undersized()`. The threshold is divided by `bbox_upscale` rather than every box multiplied, which keeps the comparison on the detector's own numbers and means turning `dense_scale` on cannot silently raise the minimum face the pipeline accepts. Verified at the threshold and at `dense_scale` 0.5 (UT-002), and end to end on the fixture (IT-001) — the superhero dump's smallest side is *exactly* its recorded 32 px, so the filter is binding there rather than vacuously satisfied | | AR-002 | Minimum face size **40×40 px** (VR-013 measured end to end; VR-005's 32 px is an embedder-only upper bound), expressed in **original** resolution (decoupled from `dense_scale`) | SR-002 | High | **Done**`FaceDetectorFunc::drop_undersized()`. The threshold is divided by `bbox_upscale` rather than every box multiplied, which keeps the comparison on the detector's own numbers and means turning `dense_scale` on cannot silently raise the minimum face the pipeline accepts. Verified at the threshold and at `dense_scale` 0.5 (UT-002), and end to end on the fixture (IT-001) — the superhero dump's smallest side is *exactly* its recorded 32 px, so the filter is binding there rather than vacuously satisfied |
| AR-003 | No fixed per-frame face cap — crowd scenes must not lose background cast | SR-002 | Medium | **Done**`max_faces` defaults to 0 (no cap); the matcher batches through its GEMM buffer instead of throwing | | AR-003 | No fixed per-frame face cap — crowd scenes must not lose background cast | SR-002 | Medium | **Done**`max_faces` defaults to 0 (no cap); the matcher batches through its GEMM buffer instead of throwing |
| AR-004 | Backpressure: unbounded faces/frame absorbed by slowing, never by dropping or throwing | SR-002 | High | **Mostly** — node outputs *park* on a full channel: the value is held, the worker released, and a channel space-callback resumes the node. Replaces `push_blocking`, which parked a scheduler worker inside the push and, with one thread per node, stopped that node draining its own input. Verified: 385/385 frames, 0 drops. **Gap:** a rare hang survives, ~1 run in 20 at a 300 s timeout (was: every run). `FanoutNode` still drops on overflow (`fanout.hpp:129`) rather than parking, so the AR-010 scene join sheds frames exactly when the dense branch falls behind | | AR-004 | Backpressure: unbounded faces/frame absorbed by slowing, never by dropping or throwing | SR-002 | High | **Mostly** — node outputs *park* on a full channel: the value is held, the worker released, and a channel space-callback resumes the node. Replaces `push_blocking`, which parked a scheduler worker inside the push and, with one thread per node, stopped that node draining its own input. Verified: 385/385 frames, 0 drops. Two remaining holes now closed: **(a)** `FanoutNode` dropped on overflow rather than waiting, so the AR-010 scene join shed frames exactly when the dense branch fell behind — measured at **9 of 2192 items delivered** to the slower of two branches, now lossless with the fast branch throttled to within its buffering; **(b)** the residual hang, recorded as ~1 run in 20 at a 300 s timeout, was a **startup** lost wake, not a mid-stream one — `start()` enables a node's inputs several statements before it installs the push callback, and a producer firing into that gap is accepted by the ring while waking nobody, since `Channel::push` signals only the empty→non-empty edge. Signature is zero items delivered, never a partial stall. Reproduced 7 times in 24 under CPU contention and 0 in 10 without; `start()` now closes with the level-triggered `on_input_ready()`, giving 0 in 24 on the same harness. **Consequence to hold onto:** a lossless fanout makes join depth a correctness precondition — one branch can now run ahead of another only by the slower branch's buffering, so `kSceneJoinDepth` must exceed the TransNetV2 window. **Gap:** capacity is still counted in *items*, not bytes, so a crowd frame carrying 60 crops occupies one slot exactly as an empty one does — the memory ceiling the plan asks for is unenforced |
| AR-005 | Align to 112×112 via ArcFace 5-point similarity transform, fitted by **Umeyama least squares over all five points** (as InsightFace does) — never a robust fit, which would discard the landmarks AR-030 reads | SR-002 | High | **Done**`umeyama_similarity()`. The RANSAC fit it replaces disagreed by a median 17 source px on 400 headshots, 83.5% of crops embedding below cos 0.99, and was unstable and RNG-driven: rebuilding caught 1614 near-duplicates against the original build's ~100. **All galleries rebuilt** (2456 actors, 10254 embeddings); measured separation gain is small (0.583 → 0.590), so recorded accuracy figures should be re-run but are not expected to move far | | AR-005 | Align to 112×112 via ArcFace 5-point similarity transform, fitted by **Umeyama least squares over all five points** (as InsightFace does) — never a robust fit, which would discard the landmarks AR-030 reads | SR-002 | High | **Done**`umeyama_similarity()`. The RANSAC fit it replaces disagreed by a median 17 source px on 400 headshots, 83.5% of crops embedding below cos 0.99, and was unstable and RNG-driven: rebuilding caught 1614 near-duplicates against the original build's ~100. **All galleries rebuilt** (2456 actors, 10254 embeddings); measured separation gain is small (0.583 → 0.590), so recorded accuracy figures should be re-run but are not expected to move far |
| AR-006 | 512-d L2-normalised embeddings, batched | SR-002 | High | Done | | AR-006 | 512-d L2-normalised embeddings, batched | SR-002 | High | Done |
| AR-007 | Associate detections by IoU + embedding, with **frame-dependent** weighting | SR-002 | High | **Done**`track_alpha` is the base for ordinary frames; drops to embedding-only on cut/boundary and for dormant tracks | | AR-007 | Associate detections by IoU + embedding, with **frame-dependent** weighting | SR-002 | High | **Done**`track_alpha` is the base for ordinary frames; drops to embedding-only on cut/boundary and for dormant tracks |
@@ -55,8 +55,8 @@ Status: `Done` · `In Progress` · `Planned` · `TBD` · `Withdrawn`
| AR-025 | Per-track Bayesian accumulation in log-odds, with correlated-observation discounting | SR-002 | High | **Done** — log-odds accumulation with correlation discounting owned by the registry, `src/evidence_discount.hpp` | | AR-025 | Per-track Bayesian accumulation in log-odds, with correlated-observation discounting | SR-002 | High | **Done** — log-odds accumulation with correlation discounting owned by the registry, `src/evidence_discount.hpp` |
| AR-026 | All similarity computed as GEMM, including annex and deferred pass | SR-001 | High | **In Progress** — two of the three call sites done. Baked gallery was already GEMM; the annex now is too — it is a contiguous row-major matrix (`track_gallery.hpp`) whose promoted rows are appended to the engine's resident matrix (`ISimilarityEngine::append_rows`), so one multiply covers baked and promoted references and the host-side cosine loop is gone. CPU path requires OpenBLAS (scalar fallback now opt-in behind `SAE_ALLOW_SCALAR_GEMM`). Remaining: the deferred pass, which does not exist until AR-020 | | AR-026 | All similarity computed as GEMM, including annex and deferred pass | SR-001 | High | **In Progress** — two of the three call sites done. Baked gallery was already GEMM; the annex now is too — it is a contiguous row-major matrix (`track_gallery.hpp`) whose promoted rows are appended to the engine's resident matrix (`ISimilarityEngine::append_rows`), so one multiply covers baked and promoted references and the host-side cosine loop is gone. CPU path requires OpenBLAS (scalar fallback now opt-in behind `SAE_ALLOW_SCALAR_GEMM`). Remaining: the deferred pass, which does not exist until AR-020 |
| AR-027 | Throughput acceptable for **arbitrary** gallery size | SR-001 | High | Planned | | AR-027 | Throughput acceptable for **arbitrary** gallery size | SR-001 | High | Planned |
| AR-028 | **Embedding input quality assessed and carried** — every face scored on size, sharpness and visibility before its embedding is used as identity evidence; the vector travels with the face and reaches the VR-001 dump | SR-002 | High | Planned | | AR-028 | **Embedding input quality assessed and carried** — every face scored on size, sharpness and visibility before its embedding is used as identity evidence; the vector travels with the face and reaches the VR-001 dump | SR-002 | High | **Done** — filled in by `FaceAlignerFunc`, where both measured axes come free from the warp; carried on `DetectedFace` and written to the dump as `faces/sharpness` + `faces/alignment_residual`, taking it to `schema_version` 2. Size is `bbox`, not duplicated into a field that would drift. No face is admitted unscored (-1 sentinel), and the degenerate-fit case is now counted and reported rather than silently dropped. **Carried, not consumed** — no discount and no threshold, which is AR-030 and VR-012. Verified UT-137, UT-138 (aligner) and UT-139…UT-141 (dump round-trip, version, sentinel). The committed fixtures are still v1, so they carry no vector until `make_fixtures.sh` is re-run on a GPU host |
| AR-029 | Sharpness measure on the **aligned crop** (scale-normalised, so it cannot re-measure size) | SR-002 | Medium | Planned | | AR-029 | Sharpness measure on the **aligned crop** (scale-normalised, so it cannot re-measure size) | SR-002 | Medium | **Done**`crop_sharpness()`: variance of the Laplacian over variance of the crop, so contrast cannot leak in the way it does for the raw textbook measure. Both blur ladders monotone, Gaussian and motion. Three properties recorded on the function for VR-012 rather than corrected here: the contrast invariance is exact in the algebra but bends at the 8-bit quantisation floor (a dim *and* soft crop reads sharper than it is — 148% high at σ 2.5), `BORDER_CONSTANT` fill from a frame-edge face adds a step edge, and the measure conflates focus with intrinsic texture. Verified UT-130…UT-136 |
| AR-030 | Visibility measure from the AR-001 5-point landmarks — extreme pose or occlusion **discounts the observation, never deletes the detection** | SR-002 | Medium | **In Progress** — measure is the AR-005 alignment residual (`estimate_alignment()`), carried on `DetectedFace`; roll/scale invariance and monotonicity under foreshortening asserted. Nothing consumes it as a discount yet | | AR-030 | Visibility measure from the AR-001 5-point landmarks — extreme pose or occlusion **discounts the observation, never deletes the detection** | SR-002 | Medium | **In Progress** — measure is the AR-005 alignment residual (`estimate_alignment()`), carried on `DetectedFace`; roll/scale invariance and monotonicity under foreshortening asserted. Nothing consumes it as a discount yet |
## Deployment (DP) ## Deployment (DP)
@@ -116,6 +116,7 @@ Status: `Done` · `In Progress` · `Planned` · `TBD` · `Withdrawn`
| VR-011 | Rewrite the replay harness for the post-AR-012 output contract | PR-002 | High | Planned | | VR-011 | Rewrite the replay harness for the post-AR-012 output contract | PR-002 | High | Planned |
| VR-012 | Quality-knee study — TPI/FPI vs sharpness and vs pose, as VR-005 did for size; also settles whether the 5-point pose proxy needs a dedicated landmark model | PR-002 | Medium | Planned | | VR-012 | Quality-knee study — TPI/FPI vs sharpness and vs pose, as VR-005 did for size; also settles whether the 5-point pose proxy needs a dedicated landmark model | PR-002 | Medium | Planned |
| VR-014 | Audio-signature **offset recovery on real content** — a known trim recovered from film audio, not from the synthetic golden tone | PR-002 | Medium | **Done** — 40 random in-cap offsets, every one recovered to the nearest frame: **worst error 46 ms against a 500 ms budget**, and 46 ms is the floor rather than a result, since the offset is quantised to whole 92.88 ms frames. The `runtime/2` anchor confirmed through real head-trimmed files (a `delta` trim moves the window by `delta/2`). The one soft spot is **tier labelling, not accuracy**: the score falls with sub-frame misalignment (0.940.99 near a frame boundary, 0.690.73 at half a frame), so 27/40 correct alignments were demoted to `loose`. ±1 frame of slack in the *score* fixes it — measured, all 40 back to `audio` (min 0.906), false matches unmoved at 0.120.16, costing 81 ms of the budget | | VR-014 | Audio-signature **offset recovery on real content** — a known trim recovered from film audio, not from the synthetic golden tone | PR-002 | Medium | **Done** — 40 random in-cap offsets, every one recovered to the nearest frame: **worst error 46 ms against a 500 ms budget**, and 46 ms is the floor rather than a result, since the offset is quantised to whole 92.88 ms frames. The `runtime/2` anchor confirmed through real head-trimmed files (a `delta` trim moves the window by `delta/2`). The one soft spot is **tier labelling, not accuracy**: the score falls with sub-frame misalignment (0.940.99 near a frame boundary, 0.690.73 at half a frame), so 27/40 correct alignments were demoted to `loose`. ±1 frame of slack in the *score* fixes it — measured, all 40 back to `audio` (min 0.906), false matches unmoved at 0.120.16, costing 81 ms of the budget |
| VR-015 | Per-node cost and bottleneck attribution for a run — where the time actually goes | PR-004 | High | **Done**`--benchmark <path>` on `scene_analyze`; `src/benchmark.hpp`. Reports cumulative CPU and wall time per node, and locates the pacing node from sampled channel occupancy rather than from time-in-node, which backpressure inflates. Verified UT-120…UT-124 |
| VR-013 | Cross-source identification probe — gallery from one recording, probes from another, swept over input resolution end to end | PR-002 | Medium | **In Progress** — holding 90% of the plateau needs ~50 px end to end against VR-005's ~22 px, the gap being detection and landmark error; **`min_face_px` 40, since 32 admits faces in the falling region** (AR-002). FPI 0.0% at every scale. Ceiling is cross-view, not resolution | | VR-013 | Cross-source identification probe — gallery from one recording, probes from another, swept over input resolution end to end | PR-002 | Medium | **In Progress** — holding 90% of the plateau needs ~50 px end to end against VR-005's ~22 px, the gap being detection and landmark error; **`min_face_px` 40, since 32 admits faces in the falling region** (AR-002). FPI 0.0% at every scale. Ceiling is cross-view, not resolution |
--- ---
@@ -312,7 +313,7 @@ because it will be trusted.
| AR-001 | T3 | Detector returns plausible boxes on a known frame | — smoke only | | AR-001 | T3 | Detector returns plausible boxes on a known frame | — smoke only |
| AR-002 | T2 | Faces below 40 px (original res) are dropped | Exactly at threshold; with `dense_scale` 0.5 — the interaction that motivated the requirement | | AR-002 | T2 | Faces below 40 px (original res) are dropped | Exactly at threshold; with `dense_scale` 0.5 — the interaction that motivated the requirement |
| AR-003 | T2 | No cap applied; a 40-face frame yields 40 | Crowd frame | | AR-003 | T2 | No cap applied; a 40-face frame yields 40 | Crowd frame |
| AR-004 | T1 | Saturated input blocks rather than drops or throws | Bounded queue at capacity; **byte-based** limit with large crops; SIGTERM mid-block | | AR-004 | T1 | Saturated input blocks rather than drops or throws | Bounded queue at capacity; **byte-based** limit with large crops; SIGTERM mid-block. Two cases the KPN suite now pins, both of which failed before being written: a fanout feeding an unequal pair loses nothing *and* throttles the fast branch (either assertion alone passes on a broken implementation); and a node started with data already in its input still fires — the startup lost wake, which needs no contention to reproduce once the state is constructed directly |
| AR-005 | T1 | Known landmarks → expected 112×112 warp; the fit never mirrors | Landmarks near frame edge; degenerate/collinear points; a mirrored set — SVD returns a reflection unless the determinant guard rejects it | | AR-005 | T1 | Known landmarks → expected 112×112 warp; the fit never mirrors | Landmarks near frame edge; degenerate/collinear points; a mirrored set — SVD returns a reflection unless the determinant guard rejects it |
| AR-006 | T3 | Embeddings are unit-norm | Batch smaller than, equal to, larger than `embed_batch_size` | | AR-006 | T3 | Embeddings are unit-norm | Batch smaller than, equal to, larger than `embed_batch_size` |
| AR-007 | T2 | Association picks the right track | Two faces crossing paths; one leaving frame as another enters | | AR-007 | T2 | Association picks the right track | Two faces crossing paths; one leaving frame as another enters |
@@ -335,8 +336,8 @@ because it will be trusted.
| AR-025 | T1 | Log-odds accumulate; correlated frames discounted | 30 identical frames must **not** reach the certainty of 30 diverse ones | | AR-025 | T1 | Log-odds accumulate; correlated frames discounted | 30 identical frames must **not** reach the certainty of 30 diverse ones |
| AR-026 | T1 + T4 | GEMM path produces same result as reference loop | Equivalence on small input in CI; throughput on GPU host | | AR-026 | T1 + T4 | GEMM path produces same result as reference loop | Equivalence on small input in CI; throughput on GPU host |
| AR-027 | **T4** | Throughput at 10²…10⁵ actors | Scheduled, not on-demand | | AR-027 | **T4** | Throughput at 10²…10⁵ actors | Scheduled, not on-demand |
| AR-028 | **T2** | No embedding reaches the matcher unscored; the vector survives into the dump | Face failing exactly one axis; all three healthy; a face whose landmarks are degenerate — scored, not silently vanished | | AR-028 | **T2** | No embedding reaches the matcher unscored; the vector survives into the dump | Face failing exactly one axis; all three healthy; a face whose landmarks are degenerate — dropped for want of a crop to score, but **counted** rather than silently vanished (UT-138) |
| AR-029 | T1 | Synthetic blur ladder → monotonically falling sharpness | Gaussian vs motion blur; **small sharp face vs large soft one** — size must not leak into this axis | | AR-029 | T1 | Synthetic blur ladder → monotonically falling sharpness | Gaussian vs motion blur; **small sharp face vs large soft one** — size must not leak into this axis. The blur ladder must be measured on a **1/f texture**: on a flat-spectrum one the motion ladder *rises*, since an anisotropic smear takes energy out of numerator and denominator together (UT-131). Contrast must not leak either — exact in the algebra, and the 8-bit floor that bends it is pinned by UT-133 |
| AR-030 | T1 | Alignment residual rises monotonically with foreshortening | **In-plane roll, scale and translation must leave it at zero** — the property that makes it a pose measure rather than a pose-and-everything-else measure; face size must not shift it; degenerate landmarks report not-ok rather than a number | | AR-030 | T1 | Alignment residual rises monotonically with foreshortening | **In-plane roll, scale and translation must leave it at zero** — the property that makes it a pose measure rather than a pose-and-everything-else measure; face size must not shift it; degenerate landmarks report not-ok rather than a number |
| VR-012 | **T4** | Knee located per axis on held-out films | Report each candidate threshold's cost in **lost true presence**, not only its gain in precision — a gate that improves misID by discarding half the cast has not helped | | VR-012 | **T4** | Knee located per axis on held-out films | Report each candidate threshold's cost in **lost true presence**, not only its gain in precision — a gate that improves misID by discarding half the cast has not helped |
| VR-013 | **T4** | Identification holds across two recordings of the same people, and degrades to TBI rather than to a wrong name as input resolution falls | Gallery and probes must come from *different* recordings — a hold-one-out over one recording measures a much easier problem and will not surface the cross-view failure. Ground truth is hand-sorted; labels propagated by embedding similarity would keep only the faces the embedder already gets right | | VR-013 | **T4** | Identification holds across two recordings of the same people, and degrades to TBI rather than to a wrong name as input resolution falls | Gallery and probes must come from *different* recordings — a hold-one-out over one recording measures a much easier problem and will not surface the cross-view failure. Ground truth is hand-sorted; labels propagated by embedding similarity would keep only the faces the embedder already gets right |
+388 -114
View File
@@ -3,7 +3,7 @@
<!-- GENERATED FILE - do not edit by hand. --> <!-- GENERATED FILE - do not edit by hand. -->
<!-- Regenerate: scripts/traceability/traceability-gate.sh --> <!-- Regenerate: scripts/traceability/traceability-gate.sh -->
**Generated:** 2026-07-31T20:39:35+00:00 **Generated:** 2026-08-05T12:38:33+00:00
Denominators are read from [`requirements.md`](requirements.md) at run time, never hardcoded. Coverage counts a requirement only when it is tagged in source **and** has a verification tier this repo's CI host can execute (`T1, T2, T3, static`). Denominators are read from [`requirements.md`](requirements.md) at run time, never hardcoded. Coverage counts a requirement only when it is tagged in source **and** has a verification tier this repo's CI host can execute (`T1, T2, T3, static`).
@@ -11,27 +11,27 @@ Denominators are read from [`requirements.md`](requirements.md) at run time, nev
| Metric | Value | | Metric | Value |
|---|---| |---|---|
| Source files scanned | 112 | | Source files scanned | 117 |
| TRACES tags found | 148 | | TRACES tags found | 195 |
| EXCEPTION tags found | 0 | | EXCEPTION tags found | 0 |
| Requirements defined | 69 | | Requirements defined | 70 |
| Requirements covered | 38 | | Requirements covered | 42 |
| **Coverage** | **55.1%** (38/69) | | **Coverage** | **60.0%** (42/70) |
| Coverage of CI-executable scope | 67.9% (38/56) | | Coverage of CI-executable scope | 75.0% (42/56) |
| Tagged but unexecuted in CI | 8 | | Tagged but unexecuted in CI | 9 |
| Orphan tags | 0 | | Orphan tags | 0 |
### By type ### By type
| Type | Covered | Tagged but unexecuted | Defined | | Type | Covered | Tagged but unexecuted | Defined |
|---|---|---|---| |---|---|---|---|
| AR | 22 | 1 | 30 | | AR | 26 | 1 | 30 |
| DP | 2 | 0 | 8 | | DP | 2 | 0 | 8 |
| IR | 8 | 0 | 8 | | IR | 8 | 0 | 8 |
| GR | 5 | 0 | 9 | | GR | 5 | 0 | 9 |
| VR | 1 | 7 | 14 | | VR | 1 | 8 | 15 |
- **UT** tags present (separate taxonomy, not counted in coverage): UT-001, UT-101, UT-102, UT-103, UT-104, UT-105, UT-106, UT-107, UT-108 - **UT** tags present (separate taxonomy, not counted in coverage): UT-001, UT-002, UT-003, UT-004, UT-005, UT-101, UT-102, UT-103, UT-104, UT-105, UT-106, UT-107, UT-108, UT-120, UT-121, UT-122, UT-123, UT-124, UT-130, UT-131, UT-132, UT-133, UT-134, UT-135, UT-136, UT-137, UT-138, UT-139, UT-140, UT-141
- **IT** tags present (separate taxonomy, not counted in coverage): IT-001 - **IT** tags present (separate taxonomy, not counted in coverage): IT-001
- **PR** tags present (separate taxonomy, not counted in coverage): PR-002, PR-004 - **PR** tags present (separate taxonomy, not counted in coverage): PR-002, PR-004
- **SR** tags present (separate taxonomy, not counted in coverage): SR-001, SR-002, SR-003, SR-005 - **SR** tags present (separate taxonomy, not counted in coverage): SR-001, SR-002, SR-003, SR-005
@@ -55,8 +55,9 @@ These requirements have no verification tier this repo's CI host can run, so a t
| VR-011 | out-of-ci | no | Rewrite the replay harness for the post-AR-012 output contract | | VR-011 | out-of-ci | no | Rewrite the replay harness for the post-AR-012 output contract |
| VR-012 | T4, out-of-ci | no | Quality-knee study — TPI/FPI vs sharpness and vs pose, as VR-005 did … | | VR-012 | T4, out-of-ci | no | Quality-knee study — TPI/FPI vs sharpness and vs pose, as VR-005 did … |
| VR-013 | T4, out-of-ci | yes | Cross-source identification probe — gallery from one recording, probe… | | VR-013 | T4, out-of-ci | yes | Cross-source identification probe — gallery from one recording, probe… |
| VR-015 | out-of-ci | yes | Per-node cost and bottleneck attribution for a run — where the time a… |
**Tagged but unexecuted:** AR-027, VR-001, VR-002, VR-003, VR-004, VR-005, VR-010, VR-013 — a test exists and is tagged, but this CI host cannot run it. Report those runs separately. **Tagged but unexecuted:** AR-027, VR-001, VR-002, VR-003, VR-004, VR-005, VR-010, VR-013, VR-015 — a test exists and is tagged, but this CI host cannot run it. Report those runs separately.
## Orphan tags ## Orphan tags
@@ -81,16 +82,16 @@ _None._
| ID | Status | Tier | Traces to | Trace state | Tagged in | Requirement | | ID | Status | Tier | Traces to | Trace state | Tagged in | Requirement |
|---|---|---|---|---|---|---| |---|---|---|---|---|---|---|
| AR-001 | Done | T3 | SR-002 | covered | `src/nodes/face_detector_node.hpp` | Detect faces in sampled frames; emit bbox, confidence, 5-point landma… | | AR-001 | Done | T3 | SR-002 | covered | `src/nodes/face_detector_node.hpp` | Detect faces in sampled frames; emit bbox, confidence, 5-point landma… |
| AR-002 | Planned | T2 | SR-002 | untagged | - | Minimum face size **40×40 px** (VR-013 measured end to end; VR-005's … | | AR-002 | **Done**`FaceDet… | T2 | SR-002 | covered | `src/nodes/face_detector_node.hpp`, `tests/test_face_detector_node.cpp`, `tests/test_replay_fixtures.cpp` | Minimum face size **40×40 px** (VR-013 measured end to end; VR-005's … |
| AR-003 | **Done**`max_fac… | T1, T2, T4 | SR-002 | covered | `src/config.hpp`, `src/nodes/face_detector_node.hpp`, `src/nodes/identity_matcher_node.hpp` | No fixed per-frame face cap — crowd scenes must not lose background c… | | AR-003 | **Done**`max_fac… | T1, T2, T4 | SR-002 | covered | `src/config.hpp`, `src/nodes/face_detector_node.hpp`, `src/nodes/identity_matcher_node.hpp` | No fixed per-frame face cap — crowd scenes must not lose background c… |
| AR-004 | **Done** KPN node… | T1, T4 | SR-002 | covered | `src/main.cpp`, `src/nodes/identity_matcher_node.hpp`, `tests/test_replay_fixtures.cpp` | Backpressure: unbounded faces/frame absorbed by slowing, never by dro… | | AR-004 | **Mostly** — node o… | T1, T4 | SR-002 | covered | `src/benchmark.hpp`, `src/main.cpp`, `src/nodes/identity_matcher_node.hpp`, `tests/test_replay_fixtures.cpp` | Backpressure: unbounded faces/frame absorbed by slowing, never by dro… |
| AR-005 | **Done**`umeyama… | T1, T3 | SR-002 | covered | `src/face_utils.hpp`, `src/nodes/face_aligner_node.hpp`, `tests/test_face_utils.cpp` | Align to 112×112 via ArcFace 5-point similarity transform, fitted by … | | AR-005 | **Done**`umeyama… | T1, T3 | SR-002 | covered | `src/face_utils.hpp`, `src/nodes/face_aligner_node.hpp`, `tests/test_face_utils.cpp` | Align to 112×112 via ArcFace 5-point similarity transform, fitted by … |
| AR-006 | Done | T3 | SR-002 | covered | `src/nodes/embedder_node.hpp` | 512-d L2-normalised embeddings, batched | | AR-006 | Done | T3 | SR-002 | covered | `src/nodes/embedder_node.hpp` | 512-d L2-normalised embeddings, batched |
| AR-007 | **Done**`track_a… | T2 | SR-002 | covered | `src/config.hpp`, `src/main.cpp`, `src/nodes/face_tracker_node.hpp`, `tests/test_face_tracker.cpp` | Associate detections by IoU + embedding, with **frame-dependent** wei… | | AR-007 | **Done**`track_a… | T2 | SR-002 | covered | `src/config.hpp`, `src/main.cpp`, `src/nodes/face_tracker_node.hpp`, `tests/test_face_tracker.cpp` | Associate detections by IoU + embedding, with **frame-dependent** wei… |
| AR-008 | **Done** — one pool… | T2 | SR-002 | covered | `src/config.hpp`, `src/main.cpp`, `src/nodes/face_tracker_node.hpp`, `tests/test_face_tracker.cpp` | One track pool keyed on `last_seen`; no separate revival path | | AR-008 | **Done** — one pool… | T2 | SR-002 | covered | `src/config.hpp`, `src/main.cpp`, `src/nodes/face_tracker_node.hpp`, `tests/test_face_tracker.cpp` | One track pool keyed on `last_seen`; no separate revival path |
| AR-009 | Done | T2 | SR-002 | covered | `src/nodes/camera_position_change_detector_node.hpp` | Camera-cut detection (histogram) as an association hint | | AR-009 | Done | T2 | SR-002 | covered | `src/nodes/camera_position_change_detector_node.hpp` | Camera-cut detection (histogram) as an association hint |
| AR-010 | **Done** — decode b… | T2 | SR-002 | covered | `src/main.cpp`, `src/nodes/scene_boundary_annotator_node.hpp`, `src/nodes/scene_detector_node.hpp`, `src/scene_boundaries.hpp` | Scene-boundary detection (TransNetV2) as an association hint | | AR-010 | **Done** — decode b… | T2 | SR-002 | covered | `src/main.cpp`, `src/nodes/scene_boundary_annotator_node.hpp`, `src/nodes/scene_detector_node.hpp`, `src/scene_boundaries.hpp` | Scene-boundary detection (TransNetV2) as an association hint |
| AR-011 | Planned | T1, T2 | SR-002 | untagged | - | **Every model is fed the input it was trained for** — cost reduced by… | | AR-011 | **Done** — both vio… | T1, T2 | SR-002 | covered | `src/config.hpp`, `src/nodes/scene_detector_node.hpp`, `tests/test_scene_detector_node.cpp` | **Every model is fed the input it was trained for** — cost reduced by… |
| AR-012 | **Done**`src/tra… | T2 | **SR-002** | covered | `src/main.cpp`, `src/nodes/identity_matcher_node.hpp`, `src/nodes/result_sink_node.hpp`, `src/track_registry.hpp`, `tests/test_replay_fixtures.cpp`, `tests/test_track_registry.cpp` | Presence follows **track extent**, not per-frame recognition | | AR-012 | **Done**`src/tra… | T2 | **SR-002** | covered | `src/main.cpp`, `src/nodes/identity_matcher_node.hpp`, `src/nodes/result_sink_node.hpp`, `src/track_registry.hpp`, `tests/test_replay_fixtures.cpp`, `tests/test_track_registry.cpp` | Presence follows **track extent**, not per-frame recognition |
| AR-013 | **Done**`last_se… | T2 | SR-002 | covered | `src/track_registry.hpp`, `tests/test_replay_fixtures.cpp`, `tests/test_track_registry.cpp` | `last_seen` optional state machine; window ends at last sighting, nev… | | AR-013 | **Done**`last_se… | T2 | SR-002 | covered | `src/track_registry.hpp`, `tests/test_replay_fixtures.cpp`, `tests/test_track_registry.cpp` | `last_seen` optional state machine; window ends at last sighting, nev… |
| AR-014 | **Done** — swap clo… | T2 | SR-002 | covered | `src/track_registry.hpp`, `tests/test_track_registry.cpp` | Belief swap A→B terminates the track and starts a new one | | AR-014 | **Done** — swap clo… | T2 | SR-002 | covered | `src/track_registry.hpp`, `tests/test_track_registry.cpp` | Belief swap A→B terminates the track and starts a new one |
@@ -105,10 +106,10 @@ _None._
| AR-023 | Done | T1 | SR-002 | covered | `src/gallery/gallery_calibration.hpp`, `src/nodes/identity_matcher_node.hpp`, `tests/test_calibration.cpp` | Fit sigmoid calibration from intra/inter similarity distributions | | AR-023 | Done | T1 | SR-002 | covered | `src/gallery/gallery_calibration.hpp`, `src/nodes/identity_matcher_node.hpp`, `tests/test_calibration.cpp` | Fit sigmoid calibration from intra/inter similarity distributions |
| AR-024 | **Done** — associat… | T1, static | SR-002 | covered | `src/config.hpp`, `src/evidence_discount.hpp`, `src/gallery/gallery_calibration.hpp`, `src/gallery/track_gallery.hpp`, `src/main.cpp`, `src/nodes/face_tracker_node.hpp`, `src/nodes/identity_matcher_node.hpp`, `tests/test_track_gallery.cpp` | **Always the calibrated probability, never a raw cosine** — exception… | | AR-024 | **Done** — associat… | T1, static | SR-002 | covered | `src/config.hpp`, `src/evidence_discount.hpp`, `src/gallery/gallery_calibration.hpp`, `src/gallery/track_gallery.hpp`, `src/main.cpp`, `src/nodes/face_tracker_node.hpp`, `src/nodes/identity_matcher_node.hpp`, `tests/test_track_gallery.cpp` | **Always the calibrated probability, never a raw cosine** — exception… |
| AR-025 | **Done** — log-odds… | T1 | SR-002 | covered | `src/evidence_discount.hpp`, `src/nodes/identity_matcher_node.hpp` | Per-track Bayesian accumulation in log-odds, with correlated-observat… | | AR-025 | **Done** — log-odds… | T1 | SR-002 | covered | `src/evidence_discount.hpp`, `src/nodes/identity_matcher_node.hpp` | Per-track Bayesian accumulation in log-odds, with correlated-observat… |
| AR-026 | In Progress | T1, T4 | SR-001 | covered | `src/backends/gemm_backend.cpp`, `tests/test_similarity.cpp` | All similarity computed as GEMM, including annex and deferred pass | | AR-026 | **In Progress** — t… | T1, T4 | SR-001 | covered | `src/backends/gemm_backend.cpp`, `src/gallery/track_gallery.hpp`, `src/inference/similarity.hpp`, `src/nodes/identity_matcher_node.hpp`, `tests/test_similarity.cpp`, `tests/test_track_gallery.cpp` | All similarity computed as GEMM, including annex and deferred pass |
| AR-027 | Planned | T4 | SR-001 | tagged, unexecuted | `src/backends/gemm_backend.cpp` | Throughput acceptable for **arbitrary** gallery size | | AR-027 | Planned | T4 | SR-001 | tagged, unexecuted | `src/backends/gemm_backend.cpp` | Throughput acceptable for **arbitrary** gallery size |
| AR-028 | Planned | T2 | SR-002 | untagged | - | **Embedding input quality assessed and carried** — every face scored … | | AR-028 | **Done** — filled i… | T2 | SR-002 | covered | `scripts/optimizer/replay.py`, `src/nodes/embedding_dump_node.hpp`, `src/nodes/face_aligner_node.hpp`, `src/types.hpp`, `tests/test_embedding_dump.cpp`, `tests/test_face_utils.cpp` | **Embedding input quality assessed and carried** — every face scored … |
| AR-029 | Planned | T1 | SR-002 | untagged | - | Sharpness measure on the **aligned crop** (scale-normalised, so it ca… | | AR-029 | **Done**`crop_sh… | T1 | SR-002 | covered | `src/face_utils.hpp`, `src/nodes/face_aligner_node.hpp`, `tests/test_face_utils.cpp` | Sharpness measure on the **aligned crop** (scale-normalised, so it ca… |
| AR-030 | **In Progress** — m… | T1 | SR-002 | covered | `src/face_utils.hpp`, `src/nodes/face_aligner_node.hpp`, `tests/test_face_utils.cpp` | Visibility measure from the AR-001 5-point landmarks — extreme pose o… | | AR-030 | **In Progress** — m… | T1 | SR-002 | covered | `src/face_utils.hpp`, `src/nodes/face_aligner_node.hpp`, `tests/test_face_utils.cpp` | Visibility measure from the AR-001 5-point landmarks — extreme pose o… |
| DP-001 | Done | T1, manual | PR-004 | covered | `src/main.cpp` | One analysis core; modes are front-ends and must not fork pipeline lo… | | DP-001 | Done | T1, manual | PR-004 | covered | `src/main.cpp` | One analysis core; modes are front-ends and must not fork pipeline lo… |
| DP-002 | Done | T1, manual | PR-004 | covered | `src/main.cpp` | Batch CLI over one title | | DP-002 | Done | T1, manual | PR-004 | covered | `src/main.cpp` | Batch CLI over one title |
@@ -135,12 +136,12 @@ _None._
| GR-007 | Planned | T1 | SR-005 | untagged | - | Persist harvested embeddings **flagged and reviewable**, never silent… | | GR-007 | Planned | T1 | SR-005 | untagged | - | Persist harvested embeddings **flagged and reviewable**, never silent… |
| GR-008 | Planned | T1 | SR-005 | untagged | - | Flag distributional outliers among an actor's references (poisoning g… | | GR-008 | Planned | T1 | SR-005 | untagged | - | Flag distributional outliers among an actor's references (poisoning g… |
| GR-009 | TBD | T1 | §4 | untagged | - | Human-confirmed associations persist and improve future extractions | | GR-009 | TBD | T1 | §4 | untagged | - | Human-confirmed associations persist and improve future extractions |
| VR-001 | Done | out-of-ci | PR-002 | tagged, unexecuted | `src/nodes/embedding_dump_node.hpp`, `tests/test_replay_fixtures.cpp` | HDF5 post-inference dump at the embedded-frame boundary | | VR-001 | Done | out-of-ci | PR-002 | tagged, unexecuted | `src/nodes/embedding_dump_node.hpp`, `tests/test_embedding_dump.cpp`, `tests/test_replay_fixtures.cpp` | HDF5 post-inference dump at the embedded-frame boundary |
| VR-002 | **Done** — replay d… | out-of-ci | PR-002 | tagged, unexecuted | `scripts/optimizer/replay.py`, `tests/test_replay_fixtures.cpp` | Replay drives the **real** KPN nodes, not a reimplementation | | VR-002 | **Done** — replay d… | out-of-ci | PR-002 | tagged, unexecuted | `scripts/optimizer/replay.py`, `tests/test_replay_fixtures.cpp` | Replay drives the **real** KPN nodes, not a reimplementation |
| VR-003 | Done | out-of-ci | PR-002 | tagged, unexecuted | `scripts/optimizer/second_score.py` | Scoring: micro-F1 against X-Ray, precision/recall logged at every eva… | | VR-003 | Done | out-of-ci | PR-002 | tagged, unexecuted | `scripts/optimizer/second_score.py` | Scoring: micro-F1 against X-Ray, precision/recall logged at every eva… |
| VR-004 | Done | out-of-ci | PR-002 | tagged, unexecuted | `scripts/validation/ground_truth.py` | Reproducible validation corpus with ground truth | | VR-004 | Done | out-of-ci | PR-002 | tagged, unexecuted | `scripts/validation/ground_truth.py` | Reproducible validation corpus with ground truth |
| VR-005 | **Done** — knee at … | out-of-ci | PR-002 | tagged, unexecuted | `scripts/validation/min_face_size.py` | Minimum face size study — TPI/FPI vs probe size, gallery held at nati… | | VR-005 | **Done** — knee at … | out-of-ci | PR-002 | tagged, unexecuted | `scripts/validation/min_face_size.py` | Minimum face size study — TPI/FPI vs probe size, gallery held at nati… |
| VR-006 | Planned | out-of-ci | PR-002 | untagged | - | Re-tune `scene_threshold` once native-rate decode lands | | VR-006 | **Planned, now unbl… | out-of-ci | PR-002 | untagged | - | Re-tune `scene_threshold` once native-rate decode lands |
| VR-007 | Planned | out-of-ci | PR-002 | untagged | - | Expansion band, clustering threshold, and deferred-pass ablation | | VR-007 | Planned | out-of-ci | PR-002 | untagged | - | Expansion band, clustering threshold, and deferred-pass ablation |
| VR-008 | Planned | out-of-ci | PR-002 | untagged | - | Gallery scaling benchmark — throughput vs gallery size | | VR-008 | Planned | out-of-ci | PR-002 | untagged | - | Gallery scaling benchmark — throughput vs gallery size |
| VR-009 | Planned | T1, out-of-ci | PR-002 | untagged | - | Verify accumulated posteriors are calibrated against held-out tracks | | VR-009 | Planned | T1, out-of-ci | PR-002 | untagged | - | Verify accumulated posteriors are calibrated against held-out tracks |
@@ -149,6 +150,7 @@ _None._
| VR-012 | Planned | T4, out-of-ci | PR-002 | untagged | - | Quality-knee study — TPI/FPI vs sharpness and vs pose, as VR-005 did … | | VR-012 | Planned | T4, out-of-ci | PR-002 | untagged | - | Quality-knee study — TPI/FPI vs sharpness and vs pose, as VR-005 did … |
| VR-013 | **In Progress** — h… | T4, out-of-ci | PR-002 | tagged, unexecuted | `experiments/xsource/resolution_sweep.py`, `experiments/xsource/verify_labels.py` | Cross-source identification probe — gallery from one recording, probe… | | VR-013 | **In Progress** — h… | T4, out-of-ci | PR-002 | tagged, unexecuted | `experiments/xsource/resolution_sweep.py`, `experiments/xsource/verify_labels.py` | Cross-source identification probe — gallery from one recording, probe… |
| VR-014 | **Done** — 40 rando… | T2, out-of-ci | PR-002 | covered | `scripts/validation/test_audio_offset.py` | Audio-signature **offset recovery on real content** — a known trim re… | | VR-014 | **Done** — 40 rando… | T2, out-of-ci | PR-002 | covered | `scripts/validation/test_audio_offset.py` | Audio-signature **offset recovery on real content** — a known trim re… |
| VR-015 | **Done**`--bench… | out-of-ci | PR-004 | tagged, unexecuted | `src/backends/trt_backend.cpp`, `src/benchmark.hpp`, `src/config.hpp`, `src/main.cpp`, `tests/test_benchmark.cpp` | Per-node cost and bottleneck attribution for a run — where the time a… |
## Detailed mapping ## Detailed mapping
@@ -158,21 +160,34 @@ _None._
- [`src/nodes/face_detector_node.hpp:2`](../src/nodes/face_detector_node.hpp#L2) — `Unknown` - [`src/nodes/face_detector_node.hpp:2`](../src/nodes/face_detector_node.hpp#L2) — `Unknown`
### AR-002
**Locations:** 3
- [`src/nodes/face_detector_node.hpp:26`](../src/nodes/face_detector_node.hpp#L26) — `explicit FaceDetectorFunc(const Config& cfg)`
- [`tests/test_face_detector_node.cpp:3`](../tests/test_face_detector_node.cpp#L3) — `Unknown`
- [`tests/test_replay_fixtures.cpp:3`](../tests/test_replay_fixtures.cpp#L3) — `Unknown`
### AR-003 ### AR-003
**Locations:** 3 **Locations:** 3
- [`src/config.hpp:44`](../src/config.hpp#L44) — `Unknown` - [`src/config.hpp:52`](../src/config.hpp#L52) — `Unknown`
- [`src/nodes/face_detector_node.hpp:47`](../src/nodes/face_detector_node.hpp#L47) — `private:` - [`src/nodes/face_detector_node.hpp:64`](../src/nodes/face_detector_node.hpp#L64) — `private:`
- [`src/nodes/identity_matcher_node.hpp:166`](../src/nodes/identity_matcher_node.hpp#L166) — `std::vector<float> host_query(static_cast<size_t>(kMaxFaces) * 512);` - [`src/nodes/identity_matcher_node.hpp:173`](../src/nodes/identity_matcher_node.hpp#L173) — `std::vector<float> host_query(static_cast<size_t>(kMaxFaces) * 512);`
### AR-004 ### AR-004
**Locations:** 4 **Locations:** 9
- [`src/main.cpp:86`](../src/main.cpp#L86) — `static constexpr std::size_t kSceneJoinDepth = 256;` - [`src/benchmark.hpp:176`](../src/benchmark.hpp#L176) — `Unknown`
- [`src/main.cpp:319`](../src/main.cpp#L319) — `Unknown` - [`src/benchmark.hpp:472`](../src/benchmark.hpp#L472) — `void print(std::ostream& os, double film_sec) const`
- [`src/nodes/identity_matcher_node.hpp:166`](../src/nodes/identity_matcher_node.hpp#L166) — `std::vector<float> host_query(static_cast<size_t>(kMaxFaces) * 512);` - [`src/benchmark.hpp:522`](../src/benchmark.hpp#L522) — `else if (c.in_fill_pct > 50.0)`
- [`src/main.cpp:97`](../src/main.cpp#L97) — `static constexpr std::size_t kSceneJoinDepth = 256;`
- [`src/main.cpp:109`](../src/main.cpp#L109) — `static std::shared_ptr<SceneBoundaries> scene_stats;`
- [`src/main.cpp:380`](../src/main.cpp#L380) — `Unknown`
- [`src/main.cpp:423`](../src/main.cpp#L423) — `std::ofstream bf(cfg.benchmark_path);`
- [`src/nodes/identity_matcher_node.hpp:173`](../src/nodes/identity_matcher_node.hpp#L173) — `std::vector<float> host_query(static_cast<size_t>(kMaxFaces) * 512);`
- [`tests/test_replay_fixtures.cpp:3`](../tests/test_replay_fixtures.cpp#L3) — `Unknown` - [`tests/test_replay_fixtures.cpp:3`](../tests/test_replay_fixtures.cpp#L3) — `Unknown`
### AR-005 ### AR-005
@@ -180,7 +195,7 @@ _None._
**Locations:** 3 **Locations:** 3
- [`src/face_utils.hpp:2`](../src/face_utils.hpp#L2) — `Unknown` - [`src/face_utils.hpp:2`](../src/face_utils.hpp#L2) — `Unknown`
- [`src/nodes/face_aligner_node.hpp:7`](../src/nodes/face_aligner_node.hpp#L7) — `struct FaceAlignerFunc` - [`src/nodes/face_aligner_node.hpp:8`](../src/nodes/face_aligner_node.hpp#L8) — `Unknown`
- [`tests/test_face_utils.cpp:1`](../tests/test_face_utils.cpp#L1) — `Unknown` - [`tests/test_face_utils.cpp:1`](../tests/test_face_utils.cpp#L1) — `Unknown`
### AR-006 ### AR-006
@@ -193,8 +208,8 @@ _None._
**Locations:** 4 **Locations:** 4
- [`src/config.hpp:108`](../src/config.hpp#L108) — `Unknown` - [`src/config.hpp:127`](../src/config.hpp#L127) — `Unknown`
- [`src/main.cpp:213`](../src/main.cpp#L213) — `reg_cfg, EvidenceDiscounter(same_person));` - [`src/main.cpp:255`](../src/main.cpp#L255) — `reg_cfg, EvidenceDiscounter(same_person));`
- [`src/nodes/face_tracker_node.hpp:2`](../src/nodes/face_tracker_node.hpp#L2) — `Unknown` - [`src/nodes/face_tracker_node.hpp:2`](../src/nodes/face_tracker_node.hpp#L2) — `Unknown`
- [`tests/test_face_tracker.cpp:1`](../tests/test_face_tracker.cpp#L1) — `Unknown` - [`tests/test_face_tracker.cpp:1`](../tests/test_face_tracker.cpp#L1) — `Unknown`
@@ -202,8 +217,8 @@ _None._
**Locations:** 4 **Locations:** 4
- [`src/config.hpp:108`](../src/config.hpp#L108) — `Unknown` - [`src/config.hpp:127`](../src/config.hpp#L127) — `Unknown`
- [`src/main.cpp:213`](../src/main.cpp#L213) — `reg_cfg, EvidenceDiscounter(same_person));` - [`src/main.cpp:255`](../src/main.cpp#L255) — `reg_cfg, EvidenceDiscounter(same_person));`
- [`src/nodes/face_tracker_node.hpp:2`](../src/nodes/face_tracker_node.hpp#L2) — `Unknown` - [`src/nodes/face_tracker_node.hpp:2`](../src/nodes/face_tracker_node.hpp#L2) — `Unknown`
- [`tests/test_face_tracker.cpp:1`](../tests/test_face_tracker.cpp#L1) — `Unknown` - [`tests/test_face_tracker.cpp:1`](../tests/test_face_tracker.cpp#L1) — `Unknown`
@@ -217,24 +232,33 @@ _None._
**Locations:** 9 **Locations:** 9
- [`src/main.cpp:86`](../src/main.cpp#L86) — `static constexpr std::size_t kSceneJoinDepth = 256;` - [`src/main.cpp:97`](../src/main.cpp#L97) — `static constexpr std::size_t kSceneJoinDepth = 256;`
- [`src/main.cpp:329`](../src/main.cpp#L329) — `Unknown` - [`src/main.cpp:433`](../src/main.cpp#L433) — `Unknown`
- [`src/main.cpp:399`](../src/main.cpp#L399) — `return run_net(std::move(net));` - [`src/main.cpp:503`](../src/main.cpp#L503) — `return run_net(std::move(net));`
- [`src/main.cpp:431`](../src/main.cpp#L431) — `Unknown` - [`src/main.cpp:535`](../src/main.cpp#L535) — `Unknown`
- [`src/nodes/scene_boundary_annotator_node.hpp:2`](../src/nodes/scene_boundary_annotator_node.hpp#L2) — `Unknown` - [`src/nodes/scene_boundary_annotator_node.hpp:2`](../src/nodes/scene_boundary_annotator_node.hpp#L2) — `Unknown`
- [`src/nodes/scene_detector_node.hpp:36`](../src/nodes/scene_detector_node.hpp#L36) — `static constexpr std::string_view label() { return "scene_detector"; }` - [`src/nodes/scene_detector_node.hpp:36`](../src/nodes/scene_detector_node.hpp#L36) — `static constexpr std::string_view label() { return "scene_detector"; }`
- [`src/nodes/scene_detector_node.hpp:110`](../src/nodes/scene_detector_node.hpp#L110) — `void flush_remaining()` - [`src/nodes/scene_detector_node.hpp:147`](../src/nodes/scene_detector_node.hpp#L147) — `void flush_remaining()`
- [`src/nodes/scene_detector_node.hpp:144`](../src/nodes/scene_detector_node.hpp#L144) — `void write_output()` - [`src/nodes/scene_detector_node.hpp:181`](../src/nodes/scene_detector_node.hpp#L181) — `void write_output()`
- [`src/scene_boundaries.hpp:2`](../src/scene_boundaries.hpp#L2) — `Unknown` - [`src/scene_boundaries.hpp:2`](../src/scene_boundaries.hpp#L2) — `Unknown`
### AR-011
**Locations:** 4
- [`src/config.hpp:105`](../src/config.hpp#L105) — `Unknown`
- [`src/nodes/scene_detector_node.hpp:70`](../src/nodes/scene_detector_node.hpp#L70) — `void operator()(Frame f)`
- [`src/nodes/scene_detector_node.hpp:93`](../src/nodes/scene_detector_node.hpp#L93) — `Unknown`
- [`tests/test_scene_detector_node.cpp:4`](../tests/test_scene_detector_node.cpp#L4) — `Unknown`
### AR-012 ### AR-012
**Locations:** 9 **Locations:** 9
- [`src/main.cpp:213`](../src/main.cpp#L213) — `reg_cfg, EvidenceDiscounter(same_person));` - [`src/main.cpp:255`](../src/main.cpp#L255) — `reg_cfg, EvidenceDiscounter(same_person));`
- [`src/main.cpp:230`](../src/main.cpp#L230) — `reg_cfg, EvidenceDiscounter(same_person));` - [`src/main.cpp:272`](../src/main.cpp#L272) — `reg_cfg, EvidenceDiscounter(same_person));`
- [`src/nodes/identity_matcher_node.hpp:125`](../src/nodes/identity_matcher_node.hpp#L125) — `const GalleryCalibration& calibration() const { return cal_; }` - [`src/nodes/identity_matcher_node.hpp:132`](../src/nodes/identity_matcher_node.hpp#L132) — `const GalleryCalibration& calibration() const { return cal_; }`
- [`src/nodes/identity_matcher_node.hpp:272`](../src/nodes/identity_matcher_node.hpp#L272) — `Unknown` - [`src/nodes/identity_matcher_node.hpp:280`](../src/nodes/identity_matcher_node.hpp#L280) — `Unknown`
- [`src/nodes/result_sink_node.hpp:49`](../src/nodes/result_sink_node.hpp#L49) — `static constexpr std::string_view label() { return "result_sink"; }` - [`src/nodes/result_sink_node.hpp:49`](../src/nodes/result_sink_node.hpp#L49) — `static constexpr std::string_view label() { return "result_sink"; }`
- [`src/nodes/result_sink_node.hpp:161`](../src/nodes/result_sink_node.hpp#L161) — `struct ActorMeta { std::string name, imdb_id, tmdb_id, jellyfin_id; };` - [`src/nodes/result_sink_node.hpp:161`](../src/nodes/result_sink_node.hpp#L161) — `struct ActorMeta { std::string name, imdb_id, tmdb_id, jellyfin_id; };`
- [`src/track_registry.hpp:2`](../src/track_registry.hpp#L2) — `Unknown` - [`src/track_registry.hpp:2`](../src/track_registry.hpp#L2) — `Unknown`
@@ -267,7 +291,7 @@ _None._
**Locations:** 4 **Locations:** 4
- [`src/main.cpp:230`](../src/main.cpp#L230) — `reg_cfg, EvidenceDiscounter(same_person));` - [`src/main.cpp:272`](../src/main.cpp#L272) — `reg_cfg, EvidenceDiscounter(same_person));`
- [`src/nodes/result_sink_node.hpp:63`](../src/nodes/result_sink_node.hpp#L63) — `void set_pre_write_hook(std::function<void(double)> fn) { pre_write_ = std::move(fn); }` - [`src/nodes/result_sink_node.hpp:63`](../src/nodes/result_sink_node.hpp#L63) — `void set_pre_write_hook(std::function<void(double)> fn) { pre_write_ = std::move(fn); }`
- [`src/track_registry.hpp:2`](../src/track_registry.hpp#L2) — `Unknown` - [`src/track_registry.hpp:2`](../src/track_registry.hpp#L2) — `Unknown`
- [`tests/test_track_registry.cpp:3`](../tests/test_track_registry.cpp#L3) — `Unknown` - [`tests/test_track_registry.cpp:3`](../tests/test_track_registry.cpp#L3) — `Unknown`
@@ -284,19 +308,19 @@ _None._
**Locations:** 5 **Locations:** 5
- [`src/config.hpp:152`](../src/config.hpp#L152) — `Unknown` - [`src/config.hpp:171`](../src/config.hpp#L171) — `Unknown`
- [`src/gallery/track_gallery.hpp:164`](../src/gallery/track_gallery.hpp#L164) — `struct TrackState` - [`src/gallery/track_gallery.hpp:196`](../src/gallery/track_gallery.hpp#L196) — `struct TrackState`
- [`src/gallery/track_gallery.hpp:274`](../src/gallery/track_gallery.hpp#L274) — `static int plurality_actor(const TrackState& ts)` - [`src/gallery/track_gallery.hpp:309`](../src/gallery/track_gallery.hpp#L309) — `static int plurality_actor(const TrackState& ts)`
- [`src/nodes/identity_matcher_node.hpp:110`](../src/nodes/identity_matcher_node.hpp#L110) — `std::vector<float> host_gallery(static_cast<size_t>(n_gallery_) * 512);` - [`src/nodes/identity_matcher_node.hpp:117`](../src/nodes/identity_matcher_node.hpp#L117) — `std::vector<float> host_gallery(static_cast<size_t>(n_gallery_) * 512);`
- [`tests/test_track_gallery.cpp:1`](../tests/test_track_gallery.cpp#L1) — `Unknown` - [`tests/test_track_gallery.cpp:1`](../tests/test_track_gallery.cpp#L1) — `Unknown`
### AR-019 ### AR-019
**Locations:** 4 **Locations:** 4
- [`src/gallery/track_gallery.hpp:123`](../src/gallery/track_gallery.hpp#L123) — `void forget(int track_id) { tracks_.erase(track_id); }` - [`src/gallery/track_gallery.hpp:155`](../src/gallery/track_gallery.hpp#L155) — `void forget(int track_id) { tracks_.erase(track_id); }`
- [`src/nodes/identity_matcher_node.hpp:147`](../src/nodes/identity_matcher_node.hpp#L147) — `MatchedSceneFrame operator()(TrackedSceneFrame tf)` - [`src/nodes/identity_matcher_node.hpp:154`](../src/nodes/identity_matcher_node.hpp#L154) — `MatchedSceneFrame operator()(TrackedSceneFrame tf)`
- [`src/nodes/identity_matcher_node.hpp:285`](../src/nodes/identity_matcher_node.hpp#L285) — `Unknown` - [`src/nodes/identity_matcher_node.hpp:293`](../src/nodes/identity_matcher_node.hpp#L293) — `Unknown`
- [`tests/test_track_gallery.cpp:1`](../tests/test_track_gallery.cpp#L1) — `Unknown` - [`tests/test_track_gallery.cpp:1`](../tests/test_track_gallery.cpp#L1) — `Unknown`
### AR-023 ### AR-023
@@ -305,24 +329,24 @@ _None._
- [`src/gallery/gallery_calibration.hpp:2`](../src/gallery/gallery_calibration.hpp#L2) — `Unknown` - [`src/gallery/gallery_calibration.hpp:2`](../src/gallery/gallery_calibration.hpp#L2) — `Unknown`
- [`src/gallery/gallery_calibration.hpp:53`](../src/gallery/gallery_calibration.hpp#L53) — `float boundary_at(float p = 0.5f, float log_prior_odds = 0.f) const` - [`src/gallery/gallery_calibration.hpp:53`](../src/gallery/gallery_calibration.hpp#L53) — `float boundary_at(float p = 0.5f, float log_prior_odds = 0.f) const`
- [`src/nodes/identity_matcher_node.hpp:117`](../src/nodes/identity_matcher_node.hpp#L117) — `const GalleryCalibration& calibration() const { return cal_; }` - [`src/nodes/identity_matcher_node.hpp:124`](../src/nodes/identity_matcher_node.hpp#L124) — `const GalleryCalibration& calibration() const { return cal_; }`
- [`tests/test_calibration.cpp:1`](../tests/test_calibration.cpp#L1) — `Unknown` - [`tests/test_calibration.cpp:1`](../tests/test_calibration.cpp#L1) — `Unknown`
### AR-024 ### AR-024
**Locations:** 12 **Locations:** 12
- [`src/config.hpp:108`](../src/config.hpp#L108) — `Unknown` - [`src/config.hpp:127`](../src/config.hpp#L127) — `Unknown`
- [`src/config.hpp:152`](../src/config.hpp#L152) — `Unknown` - [`src/config.hpp:171`](../src/config.hpp#L171) — `Unknown`
- [`src/evidence_discount.hpp:2`](../src/evidence_discount.hpp#L2) — `Unknown` - [`src/evidence_discount.hpp:2`](../src/evidence_discount.hpp#L2) — `Unknown`
- [`src/gallery/gallery_calibration.hpp:53`](../src/gallery/gallery_calibration.hpp#L53) — `float boundary_at(float p = 0.5f, float log_prior_odds = 0.f) const` - [`src/gallery/gallery_calibration.hpp:53`](../src/gallery/gallery_calibration.hpp#L53) — `float boundary_at(float p = 0.5f, float log_prior_odds = 0.f) const`
- [`src/gallery/track_gallery.hpp:133`](../src/gallery/track_gallery.hpp#L133) — `void set_calibration(std::function<float(float)> c) { calibrate_ = std::move(c); }` - [`src/gallery/track_gallery.hpp:165`](../src/gallery/track_gallery.hpp#L165) — `void set_calibration(std::function<float(float)> c) { calibrate_ = std::move(c); }`
- [`src/gallery/track_gallery.hpp:164`](../src/gallery/track_gallery.hpp#L164) — `struct TrackState` - [`src/gallery/track_gallery.hpp:196`](../src/gallery/track_gallery.hpp#L196) — `struct TrackState`
- [`src/gallery/track_gallery.hpp:274`](../src/gallery/track_gallery.hpp#L274) — `static int plurality_actor(const TrackState& ts)` - [`src/gallery/track_gallery.hpp:309`](../src/gallery/track_gallery.hpp#L309) — `static int plurality_actor(const TrackState& ts)`
- [`src/main.cpp:213`](../src/main.cpp#L213) — `reg_cfg, EvidenceDiscounter(same_person));` - [`src/main.cpp:255`](../src/main.cpp#L255) — `reg_cfg, EvidenceDiscounter(same_person));`
- [`src/nodes/face_tracker_node.hpp:2`](../src/nodes/face_tracker_node.hpp#L2) — `Unknown` - [`src/nodes/face_tracker_node.hpp:2`](../src/nodes/face_tracker_node.hpp#L2) — `Unknown`
- [`src/nodes/identity_matcher_node.hpp:110`](../src/nodes/identity_matcher_node.hpp#L110) — `std::vector<float> host_gallery(static_cast<size_t>(n_gallery_) * 512);` - [`src/nodes/identity_matcher_node.hpp:117`](../src/nodes/identity_matcher_node.hpp#L117) — `std::vector<float> host_gallery(static_cast<size_t>(n_gallery_) * 512);`
- [`src/nodes/identity_matcher_node.hpp:117`](../src/nodes/identity_matcher_node.hpp#L117) — `const GalleryCalibration& calibration() const { return cal_; }` - [`src/nodes/identity_matcher_node.hpp:124`](../src/nodes/identity_matcher_node.hpp#L124) — `const GalleryCalibration& calibration() const { return cal_; }`
- [`tests/test_track_gallery.cpp:1`](../tests/test_track_gallery.cpp#L1) — `Unknown` - [`tests/test_track_gallery.cpp:1`](../tests/test_track_gallery.cpp#L1) — `Unknown`
### AR-025 ### AR-025
@@ -330,15 +354,30 @@ _None._
**Locations:** 3 **Locations:** 3
- [`src/evidence_discount.hpp:2`](../src/evidence_discount.hpp#L2) — `Unknown` - [`src/evidence_discount.hpp:2`](../src/evidence_discount.hpp#L2) — `Unknown`
- [`src/nodes/identity_matcher_node.hpp:125`](../src/nodes/identity_matcher_node.hpp#L125) — `const GalleryCalibration& calibration() const { return cal_; }` - [`src/nodes/identity_matcher_node.hpp:132`](../src/nodes/identity_matcher_node.hpp#L132) — `const GalleryCalibration& calibration() const { return cal_; }`
- [`src/nodes/identity_matcher_node.hpp:272`](../src/nodes/identity_matcher_node.hpp#L272) — `Unknown` - [`src/nodes/identity_matcher_node.hpp:280`](../src/nodes/identity_matcher_node.hpp#L280) — `Unknown`
### AR-026 ### AR-026
**Locations:** 2 **Locations:** 17
- [`src/backends/gemm_backend.cpp:44`](../src/backends/gemm_backend.cpp#L44) — `constexpr int kDim = 512;` - [`src/backends/gemm_backend.cpp:44`](../src/backends/gemm_backend.cpp#L44) — `constexpr int kDim = 512;`
- [`src/backends/gemm_backend.cpp:80`](../src/backends/gemm_backend.cpp#L80) — `int n_gallery() const override { return n_gallery_; }`
- [`src/backends/gemm_backend.cpp:256`](../src/backends/gemm_backend.cpp#L256) — `int n_gallery() const override { return n_gallery_; }`
- [`src/gallery/track_gallery.hpp:49`](../src/gallery/track_gallery.hpp#L49) — `struct TrackGallery`
- [`src/gallery/track_gallery.hpp:84`](../src/gallery/track_gallery.hpp#L84) — `bool enabled() const { return enabled_; }`
- [`src/gallery/track_gallery.hpp:99`](../src/gallery/track_gallery.hpp#L99) — `const float* annex_row(int i) const`
- [`src/gallery/track_gallery.hpp:357`](../src/gallery/track_gallery.hpp#L357) — `static constexpr int kEmbDim = 512;`
- [`src/inference/similarity.hpp:19`](../src/inference/similarity.hpp#L19) — `struct ISimilarityEngine`
- [`src/inference/similarity.hpp:39`](../src/inference/similarity.hpp#L39) — `virtual int n_gallery() const = 0;`
- [`src/nodes/identity_matcher_node.hpp:43`](../src/nodes/identity_matcher_node.hpp#L43) — `struct IdentityMatcherFunc`
- [`src/nodes/identity_matcher_node.hpp:193`](../src/nodes/identity_matcher_node.hpp#L193) — `std::vector<float> host_query(static_cast<size_t>(kMaxFaces) * 512);`
- [`src/nodes/identity_matcher_node.hpp:316`](../src/nodes/identity_matcher_node.hpp#L316) — `private:`
- [`tests/test_similarity.cpp:1`](../tests/test_similarity.cpp#L1) — `Unknown` - [`tests/test_similarity.cpp:1`](../tests/test_similarity.cpp#L1) — `Unknown`
- [`tests/test_similarity.cpp:85`](../tests/test_similarity.cpp#L85) — `Unknown`
- [`tests/test_track_gallery.cpp:1`](../tests/test_track_gallery.cpp#L1) — `Unknown`
- [`tests/test_track_gallery.cpp:48`](../tests/test_track_gallery.cpp#L48) — `Embedding annex_view(const TrackGallery& tg, int row)`
- [`tests/test_track_gallery.cpp:341`](../tests/test_track_gallery.cpp#L341) — `TrackGallery tg(expand_cfg());`
### AR-027 ### AR-027
@@ -346,12 +385,34 @@ _None._
- [`src/backends/gemm_backend.cpp:44`](../src/backends/gemm_backend.cpp#L44) — `constexpr int kDim = 512;` - [`src/backends/gemm_backend.cpp:44`](../src/backends/gemm_backend.cpp#L44) — `constexpr int kDim = 512;`
### AR-028
**Locations:** 8
- [`src/nodes/embedding_dump_node.hpp:2`](../src/nodes/embedding_dump_node.hpp#L2) — `Unknown`
- [`src/nodes/embedding_dump_node.hpp:181`](../src/nodes/embedding_dump_node.hpp#L181) — `Unknown`
- [`src/nodes/embedding_dump_node.hpp:296`](../src/nodes/embedding_dump_node.hpp#L296) — `Unknown`
- [`src/nodes/face_aligner_node.hpp:8`](../src/nodes/face_aligner_node.hpp#L8) — `Unknown`
- [`src/types.hpp:62`](../src/types.hpp#L62) — `struct DetectedFace`
- [`tests/test_embedding_dump.cpp:1`](../tests/test_embedding_dump.cpp#L1) — `Unknown`
- [`tests/test_face_utils.cpp:1`](../tests/test_face_utils.cpp#L1) — `Unknown`
- [`scripts/optimizer/replay.py:66`](../scripts/optimizer/replay.py#L66) — `for i in range(len(ts)):`
### AR-029
**Locations:** 4
- [`src/face_utils.hpp:2`](../src/face_utils.hpp#L2) — `Unknown`
- [`src/face_utils.hpp:147`](../src/face_utils.hpp#L147) — `Unknown`
- [`src/nodes/face_aligner_node.hpp:8`](../src/nodes/face_aligner_node.hpp#L8) — `Unknown`
- [`tests/test_face_utils.cpp:1`](../tests/test_face_utils.cpp#L1) — `Unknown`
### AR-030 ### AR-030
**Locations:** 3 **Locations:** 3
- [`src/face_utils.hpp:2`](../src/face_utils.hpp#L2) — `Unknown` - [`src/face_utils.hpp:2`](../src/face_utils.hpp#L2) — `Unknown`
- [`src/nodes/face_aligner_node.hpp:7`](../src/nodes/face_aligner_node.hpp#L7) — `struct FaceAlignerFunc` - [`src/nodes/face_aligner_node.hpp:8`](../src/nodes/face_aligner_node.hpp#L8) — `Unknown`
- [`tests/test_face_utils.cpp:1`](../tests/test_face_utils.cpp#L1) — `Unknown` - [`tests/test_face_utils.cpp:1`](../tests/test_face_utils.cpp#L1) — `Unknown`
### DP-001 ### DP-001
@@ -382,7 +443,7 @@ _None._
**Locations:** 16 **Locations:** 16
- [`src/build_gallery.cpp:83`](../src/build_gallery.cpp#L83) — `Unknown` - [`src/build_gallery.cpp:87`](../src/build_gallery.cpp#L87) — `Unknown`
- [`src/gallery/gallery_calibration.hpp:80`](../src/gallery/gallery_calibration.hpp#L80) — `struct GalleryCalibrationStats` - [`src/gallery/gallery_calibration.hpp:80`](../src/gallery/gallery_calibration.hpp#L80) — `struct GalleryCalibrationStats`
- [`src/gallery/gallery_calibration.hpp:145`](../src/gallery/gallery_calibration.hpp#L145) — `std::vector<bool> actor_eligible(n_actors, false);` - [`src/gallery/gallery_calibration.hpp:145`](../src/gallery/gallery_calibration.hpp#L145) — `std::vector<bool> actor_eligible(n_actors, false);`
- [`src/gallery/gallery_calibration.hpp:294`](../src/gallery/gallery_calibration.hpp#L294) — `Unknown` - [`src/gallery/gallery_calibration.hpp:294`](../src/gallery/gallery_calibration.hpp#L294) — `Unknown`
@@ -403,20 +464,20 @@ _None._
**Locations:** 44 **Locations:** 44
- [`src/config.hpp:54`](../src/config.hpp#L54) — `Unknown` - [`src/config.hpp:62`](../src/config.hpp#L62) — `Unknown`
- [`src/gallery/embedder_stamp.cpp:1`](../src/gallery/embedder_stamp.cpp#L1) — `Unknown` - [`src/gallery/embedder_stamp.cpp:1`](../src/gallery/embedder_stamp.cpp#L1) — `Unknown`
- [`src/gallery/embedder_stamp.hpp:2`](../src/gallery/embedder_stamp.hpp#L2) — `Unknown` - [`src/gallery/embedder_stamp.hpp:2`](../src/gallery/embedder_stamp.hpp#L2) — `Unknown`
- [`src/gallery/gallery_builder.cpp:45`](../src/gallery/gallery_builder.cpp#L45) — `ActorGallery build_gallery(const BuildConfig& cfg)` - [`src/gallery/gallery_builder.cpp:45`](../src/gallery/gallery_builder.cpp#L45) — `ActorGallery build_gallery(const BuildConfig& cfg)`
- [`src/gallery/gallery_store.cpp:82`](../src/gallery/gallery_store.cpp#L82) — `H5::StrType str(H5::PredType::C_S1, H5T_VARIABLE);` - [`src/gallery/gallery_store.cpp:82`](../src/gallery/gallery_store.cpp#L82) — `H5::StrType str(H5::PredType::C_S1, H5T_VARIABLE);`
- [`src/gallery/gallery_store.cpp:167`](../src/gallery/gallery_store.cpp#L167) — `H5::DataSpace scalar(H5S_SCALAR);` - [`src/gallery/gallery_store.cpp:167`](../src/gallery/gallery_store.cpp#L167) — `H5::DataSpace scalar(H5S_SCALAR);`
- [`src/gallery/gallery_store.cpp:219`](../src/gallery/gallery_store.cpp#L219) — `Unknown` - [`src/gallery/gallery_store.cpp:219`](../src/gallery/gallery_store.cpp#L219) — `Unknown`
- [`src/kpn_bindings.cpp:167`](../src/kpn_bindings.cpp#L167) — `Unknown` - [`src/kpn_bindings.cpp:186`](../src/kpn_bindings.cpp#L186) — `Unknown`
- [`src/kpn_bindings.cpp:217`](../src/kpn_bindings.cpp#L217) — `Unknown` - [`src/kpn_bindings.cpp:236`](../src/kpn_bindings.cpp#L236) — `Unknown`
- [`src/main.cpp:188`](../src/main.cpp#L188) — `Unknown` - [`src/main.cpp:230`](../src/main.cpp#L230) — `Unknown`
- [`src/nodes/embedding_dump_node.hpp:127`](../src/nodes/embedding_dump_node.hpp#L127) — `static constexpr std::string_view label() { return "embedding_dump"; }` - [`src/nodes/embedding_dump_node.hpp:127`](../src/nodes/embedding_dump_node.hpp#L127) — `static constexpr std::string_view label() { return "embedding_dump"; }`
- [`src/nodes/embedding_dump_node.hpp:238`](../src/nodes/embedding_dump_node.hpp#L238) — `H5::H5File file(path_, H5F_ACC_TRUNC);` - [`src/nodes/embedding_dump_node.hpp:257`](../src/nodes/embedding_dump_node.hpp#L257) — `H5::H5File file(path_, H5F_ACC_TRUNC);`
- [`src/scene_preview.cpp:133`](../src/scene_preview.cpp#L133) — `int main(int argc, char** argv)` - [`src/scene_preview.cpp:133`](../src/scene_preview.cpp#L133) — `int main(int argc, char** argv)`
- [`src/types.hpp:148`](../src/types.hpp#L148) — `struct Actor` - [`src/types.hpp:173`](../src/types.hpp#L173) — `struct Actor`
- [`tests/test_gallery_store.cpp:182`](../tests/test_gallery_store.cpp#L182) — `TempFile tf("gallery_stamped.h5");` - [`tests/test_gallery_store.cpp:182`](../tests/test_gallery_store.cpp#L182) — `TempFile tf("gallery_stamped.h5");`
- [`tests/test_gallery_store.cpp:201`](../tests/test_gallery_store.cpp#L201) — `TempFile tf("gallery_stamped.h5");` - [`tests/test_gallery_store.cpp:201`](../tests/test_gallery_store.cpp#L201) — `TempFile tf("gallery_stamped.h5");`
- [`tests/test_gallery_store.cpp:219`](../tests/test_gallery_store.cpp#L219) — `TempFile tf("gallery_unstamped.h5");` - [`tests/test_gallery_store.cpp:219`](../tests/test_gallery_store.cpp#L219) — `TempFile tf("gallery_unstamped.h5");`
@@ -440,8 +501,8 @@ _None._
- [`scripts/optimizer/optimize.py:186`](../scripts/optimizer/optimize.py#L186) — `Unknown` - [`scripts/optimizer/optimize.py:186`](../scripts/optimizer/optimize.py#L186) — `Unknown`
- [`scripts/optimizer/optimize.py:202`](../scripts/optimizer/optimize.py#L202) — `if not Path(f["dump"]).exists():` - [`scripts/optimizer/optimize.py:202`](../scripts/optimizer/optimize.py#L202) — `if not Path(f["dump"]).exists():`
- [`scripts/optimizer/reembed_gallery.py:62`](../scripts/optimizer/reembed_gallery.py#L62) — `for i, a in enumerate(ref["actors"], 1):` - [`scripts/optimizer/reembed_gallery.py:62`](../scripts/optimizer/reembed_gallery.py#L62) — `for i, a in enumerate(ref["actors"], 1):`
- [`scripts/optimizer/replay.py:113`](../scripts/optimizer/replay.py#L113) — `Unknown` - [`scripts/optimizer/replay.py:125`](../scripts/optimizer/replay.py#L125) — `Unknown`
- [`scripts/optimizer/replay.py:253`](../scripts/optimizer/replay.py#L253) — `Unknown` - [`scripts/optimizer/replay.py:265`](../scripts/optimizer/replay.py#L265) — `Unknown`
- [`scripts/sae_embed_loader.py:23`](../scripts/sae_embed_loader.py#L23) — `def resolve_arcface(models_dir: str, arcface: str \| None = None) -> str:` - [`scripts/sae_embed_loader.py:23`](../scripts/sae_embed_loader.py#L23) — `def resolve_arcface(models_dir: str, arcface: str \| None = None) -> str:`
- [`scripts/sae_gallery.py:171`](../scripts/sae_gallery.py#L171) — `if not _stamp_empty(embedder):` - [`scripts/sae_gallery.py:171`](../scripts/sae_gallery.py#L171) — `if not _stamp_empty(embedder):`
- [`scripts/sae_gallery.py:200`](../scripts/sae_gallery.py#L200) — `for a in range(len(offset)):` - [`scripts/sae_gallery.py:200`](../scripts/sae_gallery.py#L200) — `for a in range(len(offset)):`
@@ -465,7 +526,7 @@ _None._
**Locations:** 5 **Locations:** 5
- [`src/config.hpp:20`](../src/config.hpp#L20) — `struct Config` - [`src/config.hpp:20`](../src/config.hpp#L20) — `struct Config`
- [`src/main.cpp:230`](../src/main.cpp#L230) — `reg_cfg, EvidenceDiscounter(same_person));` - [`src/main.cpp:272`](../src/main.cpp#L272) — `reg_cfg, EvidenceDiscounter(same_person));`
- [`src/nodes/result_sink_node.hpp:49`](../src/nodes/result_sink_node.hpp#L49) — `static constexpr std::string_view label() { return "result_sink"; }` - [`src/nodes/result_sink_node.hpp:49`](../src/nodes/result_sink_node.hpp#L49) — `static constexpr std::string_view label() { return "result_sink"; }`
- [`src/nodes/result_sink_node.hpp:122`](../src/nodes/result_sink_node.hpp#L122) — `void write_output()` - [`src/nodes/result_sink_node.hpp:122`](../src/nodes/result_sink_node.hpp#L122) — `void write_output()`
- [`src/nodes/result_sink_node.hpp:161`](../src/nodes/result_sink_node.hpp#L161) — `struct ActorMeta { std::string name, imdb_id, tmdb_id, jellyfin_id; };` - [`src/nodes/result_sink_node.hpp:161`](../src/nodes/result_sink_node.hpp#L161) — `struct ActorMeta { std::string name, imdb_id, tmdb_id, jellyfin_id; };`
@@ -474,7 +535,7 @@ _None._
**Locations:** 1 **Locations:** 1
- [`src/main.cpp:230`](../src/main.cpp#L230) — `reg_cfg, EvidenceDiscounter(same_person));` - [`src/main.cpp:272`](../src/main.cpp#L272) — `reg_cfg, EvidenceDiscounter(same_person));`
### IR-004 ### IR-004
@@ -555,7 +616,7 @@ _None._
- [`src/nodes/embedding_dump_node.hpp:18`](../src/nodes/embedding_dump_node.hpp#L18) — `Unknown` - [`src/nodes/embedding_dump_node.hpp:18`](../src/nodes/embedding_dump_node.hpp#L18) — `Unknown`
- [`src/nodes/embedding_dump_node.hpp:133`](../src/nodes/embedding_dump_node.hpp#L133) — `static constexpr std::string_view label() { return "embedding_dump"; }` - [`src/nodes/embedding_dump_node.hpp:133`](../src/nodes/embedding_dump_node.hpp#L133) — `static constexpr std::string_view label() { return "embedding_dump"; }`
- [`src/nodes/embedding_dump_node.hpp:159`](../src/nodes/embedding_dump_node.hpp#L159) — `void operator()(EmbeddedSceneFrame ef)` - [`src/nodes/embedding_dump_node.hpp:159`](../src/nodes/embedding_dump_node.hpp#L159) — `void operator()(EmbeddedSceneFrame ef)`
- [`src/nodes/embedding_dump_node.hpp:242`](../src/nodes/embedding_dump_node.hpp#L242) — `H5::H5File file(path_, H5F_ACC_TRUNC);` - [`src/nodes/embedding_dump_node.hpp:261`](../src/nodes/embedding_dump_node.hpp#L261) — `H5::H5File file(path_, H5F_ACC_TRUNC);`
- [`scripts/optimizer/replay.py:5`](../scripts/optimizer/replay.py#L5) — `Reads an embedding dump (scripts/optimizer/SCHEMA.md), feeds each frame as an` - [`scripts/optimizer/replay.py:5`](../scripts/optimizer/replay.py#L5) — `Reads an embedding dump (scripts/optimizer/SCHEMA.md), feeds each frame as an`
- [`scripts/optimizer/second_score.py:5`](../scripts/optimizer/second_score.py#L5) — `Unknown` - [`scripts/optimizer/second_score.py:5`](../scripts/optimizer/second_score.py#L5) — `Unknown`
- [`scripts/validation/ground_truth.py:24`](../scripts/validation/ground_truth.py#L24) — `Unknown` - [`scripts/validation/ground_truth.py:24`](../scripts/validation/ground_truth.py#L24) — `Unknown`
@@ -564,17 +625,40 @@ _None._
### PR-004 ### PR-004
**Locations:** 1 **Locations:** 22
- [`src/backends/trt_backend.cpp:49`](../src/backends/trt_backend.cpp#L49) — `throw CudaError(std::string(what) + ": " + cudaGetErrorString(e));`
- [`src/benchmark.hpp:2`](../src/benchmark.hpp#L2) — `Unknown`
- [`src/benchmark.hpp:86`](../src/benchmark.hpp#L86) — `namespace sae::bench`
- [`src/benchmark.hpp:107`](../src/benchmark.hpp#L107) — `struct ChannelOccupancy`
- [`src/benchmark.hpp:141`](../src/benchmark.hpp#L141) — `struct NodeCost`
- [`src/benchmark.hpp:176`](../src/benchmark.hpp#L176) — `Unknown`
- [`src/benchmark.hpp:185`](../src/benchmark.hpp#L185) — `Unknown`
- [`src/benchmark.hpp:267`](../src/benchmark.hpp#L267) — `inline std::string verdict(const std::vector<NodeCost>& costs)`
- [`src/benchmark.hpp:315`](../src/benchmark.hpp#L315) — `class BenchmarkRecorder`
- [`src/benchmark.hpp:384`](../src/benchmark.hpp#L384) — `return attribute_cost(final_.nodes, channels(), final_.elapsed_s);`
- [`src/benchmark.hpp:465`](../src/benchmark.hpp#L465) — `void print(std::ostream& os, double film_sec) const`
- [`src/benchmark.hpp:472`](../src/benchmark.hpp#L472) — `void print(std::ostream& os, double film_sec) const`
- [`src/benchmark.hpp:522`](../src/benchmark.hpp#L522) — `else if (c.in_fill_pct > 50.0)`
- [`src/config.hpp:35`](../src/config.hpp#L35) — `Unknown`
- [`src/main.cpp:3`](../src/main.cpp#L3) — `Unknown` - [`src/main.cpp:3`](../src/main.cpp#L3) — `Unknown`
- [`src/main.cpp:109`](../src/main.cpp#L109) — `static std::shared_ptr<SceneBoundaries> scene_stats;`
- [`src/main.cpp:203`](../src/main.cpp#L203) — `int main(int argc, char** argv)`
- [`src/main.cpp:280`](../src/main.cpp#L280) — `Unknown`
- [`src/main.cpp:354`](../src/main.cpp#L354) — `std::lock_guard<std::mutex> lk(event_mtx);`
- [`src/main.cpp:380`](../src/main.cpp#L380) — `Unknown`
- [`src/main.cpp:393`](../src/main.cpp#L393) — `Unknown`
- [`tests/test_benchmark.cpp:3`](../tests/test_benchmark.cpp#L3) — `Unknown`
### SR-001 ### SR-001
**Locations:** 64 **Locations:** 79
- [`src/backends/gemm_backend.cpp:44`](../src/backends/gemm_backend.cpp#L44) — `constexpr int kDim = 512;` - [`src/backends/gemm_backend.cpp:44`](../src/backends/gemm_backend.cpp#L44) — `constexpr int kDim = 512;`
- [`src/build_gallery.cpp:83`](../src/build_gallery.cpp#L83) — `Unknown` - [`src/backends/gemm_backend.cpp:80`](../src/backends/gemm_backend.cpp#L80) — `int n_gallery() const override { return n_gallery_; }`
- [`src/config.hpp:54`](../src/config.hpp#L54) — `Unknown` - [`src/backends/gemm_backend.cpp:256`](../src/backends/gemm_backend.cpp#L256) — `int n_gallery() const override { return n_gallery_; }`
- [`src/build_gallery.cpp:87`](../src/build_gallery.cpp#L87) — `Unknown`
- [`src/config.hpp:62`](../src/config.hpp#L62) — `Unknown`
- [`src/gallery/embedder_stamp.cpp:1`](../src/gallery/embedder_stamp.cpp#L1) — `Unknown` - [`src/gallery/embedder_stamp.cpp:1`](../src/gallery/embedder_stamp.cpp#L1) — `Unknown`
- [`src/gallery/embedder_stamp.hpp:2`](../src/gallery/embedder_stamp.hpp#L2) — `Unknown` - [`src/gallery/embedder_stamp.hpp:2`](../src/gallery/embedder_stamp.hpp#L2) — `Unknown`
- [`src/gallery/gallery_builder.cpp:45`](../src/gallery/gallery_builder.cpp#L45) — `ActorGallery build_gallery(const BuildConfig& cfg)` - [`src/gallery/gallery_builder.cpp:45`](../src/gallery/gallery_builder.cpp#L45) — `ActorGallery build_gallery(const BuildConfig& cfg)`
@@ -593,13 +677,22 @@ _None._
- [`src/gallery/gallery_store.cpp:82`](../src/gallery/gallery_store.cpp#L82) — `H5::StrType str(H5::PredType::C_S1, H5T_VARIABLE);` - [`src/gallery/gallery_store.cpp:82`](../src/gallery/gallery_store.cpp#L82) — `H5::StrType str(H5::PredType::C_S1, H5T_VARIABLE);`
- [`src/gallery/gallery_store.cpp:167`](../src/gallery/gallery_store.cpp#L167) — `H5::DataSpace scalar(H5S_SCALAR);` - [`src/gallery/gallery_store.cpp:167`](../src/gallery/gallery_store.cpp#L167) — `H5::DataSpace scalar(H5S_SCALAR);`
- [`src/gallery/gallery_store.cpp:219`](../src/gallery/gallery_store.cpp#L219) — `Unknown` - [`src/gallery/gallery_store.cpp:219`](../src/gallery/gallery_store.cpp#L219) — `Unknown`
- [`src/kpn_bindings.cpp:167`](../src/kpn_bindings.cpp#L167) — `Unknown` - [`src/gallery/track_gallery.hpp:49`](../src/gallery/track_gallery.hpp#L49) — `struct TrackGallery`
- [`src/kpn_bindings.cpp:217`](../src/kpn_bindings.cpp#L217) — `Unknown` - [`src/gallery/track_gallery.hpp:84`](../src/gallery/track_gallery.hpp#L84) — `bool enabled() const { return enabled_; }`
- [`src/main.cpp:188`](../src/main.cpp#L188) — `Unknown` - [`src/gallery/track_gallery.hpp:99`](../src/gallery/track_gallery.hpp#L99) — `const float* annex_row(int i) const`
- [`src/gallery/track_gallery.hpp:357`](../src/gallery/track_gallery.hpp#L357) — `static constexpr int kEmbDim = 512;`
- [`src/inference/similarity.hpp:19`](../src/inference/similarity.hpp#L19) — `struct ISimilarityEngine`
- [`src/inference/similarity.hpp:39`](../src/inference/similarity.hpp#L39) — `virtual int n_gallery() const = 0;`
- [`src/kpn_bindings.cpp:186`](../src/kpn_bindings.cpp#L186) — `Unknown`
- [`src/kpn_bindings.cpp:236`](../src/kpn_bindings.cpp#L236) — `Unknown`
- [`src/main.cpp:230`](../src/main.cpp#L230) — `Unknown`
- [`src/nodes/embedding_dump_node.hpp:127`](../src/nodes/embedding_dump_node.hpp#L127) — `static constexpr std::string_view label() { return "embedding_dump"; }` - [`src/nodes/embedding_dump_node.hpp:127`](../src/nodes/embedding_dump_node.hpp#L127) — `static constexpr std::string_view label() { return "embedding_dump"; }`
- [`src/nodes/embedding_dump_node.hpp:238`](../src/nodes/embedding_dump_node.hpp#L238) — `H5::H5File file(path_, H5F_ACC_TRUNC);` - [`src/nodes/embedding_dump_node.hpp:257`](../src/nodes/embedding_dump_node.hpp#L257) — `H5::H5File file(path_, H5F_ACC_TRUNC);`
- [`src/nodes/identity_matcher_node.hpp:43`](../src/nodes/identity_matcher_node.hpp#L43) — `struct IdentityMatcherFunc`
- [`src/nodes/identity_matcher_node.hpp:193`](../src/nodes/identity_matcher_node.hpp#L193) — `std::vector<float> host_query(static_cast<size_t>(kMaxFaces) * 512);`
- [`src/nodes/identity_matcher_node.hpp:316`](../src/nodes/identity_matcher_node.hpp#L316) — `private:`
- [`src/scene_preview.cpp:133`](../src/scene_preview.cpp#L133) — `int main(int argc, char** argv)` - [`src/scene_preview.cpp:133`](../src/scene_preview.cpp#L133) — `int main(int argc, char** argv)`
- [`src/types.hpp:148`](../src/types.hpp#L148) — `struct Actor` - [`src/types.hpp:173`](../src/types.hpp#L173) — `struct Actor`
- [`tests/test_calibration.cpp:192`](../tests/test_calibration.cpp#L192) — `Embedding unit_axis(int slot)` - [`tests/test_calibration.cpp:192`](../tests/test_calibration.cpp#L192) — `Embedding unit_axis(int slot)`
- [`tests/test_calibration.cpp:222`](../tests/test_calibration.cpp#L222) — `Unknown` - [`tests/test_calibration.cpp:222`](../tests/test_calibration.cpp#L222) — `Unknown`
- [`tests/test_calibration.cpp:248`](../tests/test_calibration.cpp#L248) — `Unknown` - [`tests/test_calibration.cpp:248`](../tests/test_calibration.cpp#L248) — `Unknown`
@@ -616,6 +709,10 @@ _None._
- [`tests/test_gallery_store.cpp:367`](../tests/test_gallery_store.cpp#L367) — `Unknown` - [`tests/test_gallery_store.cpp:367`](../tests/test_gallery_store.cpp#L367) — `Unknown`
- [`tests/test_gallery_store.cpp:384`](../tests/test_gallery_store.cpp#L384) — `TempFile tf("fake_model.onnx");` - [`tests/test_gallery_store.cpp:384`](../tests/test_gallery_store.cpp#L384) — `TempFile tf("fake_model.onnx");`
- [`tests/test_similarity.cpp:1`](../tests/test_similarity.cpp#L1) — `Unknown` - [`tests/test_similarity.cpp:1`](../tests/test_similarity.cpp#L1) — `Unknown`
- [`tests/test_similarity.cpp:85`](../tests/test_similarity.cpp#L85) — `Unknown`
- [`tests/test_track_gallery.cpp:1`](../tests/test_track_gallery.cpp#L1) — `Unknown`
- [`tests/test_track_gallery.cpp:48`](../tests/test_track_gallery.cpp#L48) — `Embedding annex_view(const TrackGallery& tg, int row)`
- [`tests/test_track_gallery.cpp:341`](../tests/test_track_gallery.cpp#L341) — `TrackGallery tg(expand_cfg());`
- [`scripts/filter_gallery.py:80`](../scripts/filter_gallery.py#L80) — `if actor_jellyfin_id(a) in cast_ids]` - [`scripts/filter_gallery.py:80`](../scripts/filter_gallery.py#L80) — `if actor_jellyfin_id(a) in cast_ids]`
- [`scripts/make_gallery.py:181`](../scripts/make_gallery.py#L181) — `Unknown` - [`scripts/make_gallery.py:181`](../scripts/make_gallery.py#L181) — `Unknown`
- [`scripts/make_jellyfin_gallery.py:4`](../scripts/make_jellyfin_gallery.py#L4) — `Unknown` - [`scripts/make_jellyfin_gallery.py:4`](../scripts/make_jellyfin_gallery.py#L4) — `Unknown`
@@ -628,8 +725,8 @@ _None._
- [`scripts/optimizer/optimize.py:186`](../scripts/optimizer/optimize.py#L186) — `Unknown` - [`scripts/optimizer/optimize.py:186`](../scripts/optimizer/optimize.py#L186) — `Unknown`
- [`scripts/optimizer/optimize.py:202`](../scripts/optimizer/optimize.py#L202) — `if not Path(f["dump"]).exists():` - [`scripts/optimizer/optimize.py:202`](../scripts/optimizer/optimize.py#L202) — `if not Path(f["dump"]).exists():`
- [`scripts/optimizer/reembed_gallery.py:62`](../scripts/optimizer/reembed_gallery.py#L62) — `for i, a in enumerate(ref["actors"], 1):` - [`scripts/optimizer/reembed_gallery.py:62`](../scripts/optimizer/reembed_gallery.py#L62) — `for i, a in enumerate(ref["actors"], 1):`
- [`scripts/optimizer/replay.py:113`](../scripts/optimizer/replay.py#L113) — `Unknown` - [`scripts/optimizer/replay.py:125`](../scripts/optimizer/replay.py#L125) — `Unknown`
- [`scripts/optimizer/replay.py:253`](../scripts/optimizer/replay.py#L253) — `Unknown` - [`scripts/optimizer/replay.py:265`](../scripts/optimizer/replay.py#L265) — `Unknown`
- [`scripts/run_from_jellyfin.py:4`](../scripts/run_from_jellyfin.py#L4) — `Unknown` - [`scripts/run_from_jellyfin.py:4`](../scripts/run_from_jellyfin.py#L4) — `Unknown`
- [`scripts/sae_embed_loader.py:23`](../scripts/sae_embed_loader.py#L23) — `def resolve_arcface(models_dir: str, arcface: str \| None = None) -> str:` - [`scripts/sae_embed_loader.py:23`](../scripts/sae_embed_loader.py#L23) — `def resolve_arcface(models_dir: str, arcface: str \| None = None) -> str:`
- [`scripts/sae_gallery.py:171`](../scripts/sae_gallery.py#L171) — `if not _stamp_empty(embedder):` - [`scripts/sae_gallery.py:171`](../scripts/sae_gallery.py#L171) — `if not _stamp_empty(embedder):`
@@ -639,43 +736,55 @@ _None._
### SR-002 ### SR-002
**Locations:** 35 **Locations:** 47
- [`src/config.hpp:44`](../src/config.hpp#L44) — `Unknown` - [`src/config.hpp:52`](../src/config.hpp#L52) — `Unknown`
- [`src/config.hpp:108`](../src/config.hpp#L108) — `Unknown` - [`src/config.hpp:105`](../src/config.hpp#L105) — `Unknown`
- [`src/config.hpp:127`](../src/config.hpp#L127) — `Unknown`
- [`src/evidence_discount.hpp:2`](../src/evidence_discount.hpp#L2) — `Unknown` - [`src/evidence_discount.hpp:2`](../src/evidence_discount.hpp#L2) — `Unknown`
- [`src/face_utils.hpp:2`](../src/face_utils.hpp#L2) — `Unknown` - [`src/face_utils.hpp:2`](../src/face_utils.hpp#L2) — `Unknown`
- [`src/face_utils.hpp:147`](../src/face_utils.hpp#L147) — `Unknown`
- [`src/gallery/gallery_calibration.hpp:2`](../src/gallery/gallery_calibration.hpp#L2) — `Unknown` - [`src/gallery/gallery_calibration.hpp:2`](../src/gallery/gallery_calibration.hpp#L2) — `Unknown`
- [`src/gallery/gallery_calibration.hpp:53`](../src/gallery/gallery_calibration.hpp#L53) — `float boundary_at(float p = 0.5f, float log_prior_odds = 0.f) const` - [`src/gallery/gallery_calibration.hpp:53`](../src/gallery/gallery_calibration.hpp#L53) — `float boundary_at(float p = 0.5f, float log_prior_odds = 0.f) const`
- [`src/main.cpp:86`](../src/main.cpp#L86) — `static constexpr std::size_t kSceneJoinDepth = 256;` - [`src/main.cpp:97`](../src/main.cpp#L97) — `static constexpr std::size_t kSceneJoinDepth = 256;`
- [`src/main.cpp:213`](../src/main.cpp#L213) — `reg_cfg, EvidenceDiscounter(same_person));` - [`src/main.cpp:255`](../src/main.cpp#L255) — `reg_cfg, EvidenceDiscounter(same_person));`
- [`src/main.cpp:230`](../src/main.cpp#L230) — `reg_cfg, EvidenceDiscounter(same_person));` - [`src/main.cpp:272`](../src/main.cpp#L272) — `reg_cfg, EvidenceDiscounter(same_person));`
- [`src/main.cpp:319`](../src/main.cpp#L319) — `Unknown` - [`src/main.cpp:423`](../src/main.cpp#L423) — `std::ofstream bf(cfg.benchmark_path);`
- [`src/main.cpp:329`](../src/main.cpp#L329) — `Unknown` - [`src/main.cpp:433`](../src/main.cpp#L433) — `Unknown`
- [`src/main.cpp:399`](../src/main.cpp#L399) — `return run_net(std::move(net));` - [`src/main.cpp:503`](../src/main.cpp#L503) — `return run_net(std::move(net));`
- [`src/main.cpp:431`](../src/main.cpp#L431) — `Unknown` - [`src/main.cpp:535`](../src/main.cpp#L535) — `Unknown`
- [`src/nodes/camera_position_change_detector_node.hpp:30`](../src/nodes/camera_position_change_detector_node.hpp#L30) — `struct CameraPositionChangeDetectorFunc` - [`src/nodes/camera_position_change_detector_node.hpp:30`](../src/nodes/camera_position_change_detector_node.hpp#L30) — `struct CameraPositionChangeDetectorFunc`
- [`src/nodes/embedder_node.hpp:21`](../src/nodes/embedder_node.hpp#L21) — `struct EmbedderFunc` - [`src/nodes/embedder_node.hpp:21`](../src/nodes/embedder_node.hpp#L21) — `struct EmbedderFunc`
- [`src/nodes/face_aligner_node.hpp:7`](../src/nodes/face_aligner_node.hpp#L7) — `struct FaceAlignerFunc` - [`src/nodes/embedding_dump_node.hpp:181`](../src/nodes/embedding_dump_node.hpp#L181) — `Unknown`
- [`src/nodes/embedding_dump_node.hpp:296`](../src/nodes/embedding_dump_node.hpp#L296) — `Unknown`
- [`src/nodes/face_aligner_node.hpp:8`](../src/nodes/face_aligner_node.hpp#L8) — `Unknown`
- [`src/nodes/face_detector_node.hpp:2`](../src/nodes/face_detector_node.hpp#L2) — `Unknown` - [`src/nodes/face_detector_node.hpp:2`](../src/nodes/face_detector_node.hpp#L2) — `Unknown`
- [`src/nodes/face_detector_node.hpp:47`](../src/nodes/face_detector_node.hpp#L47) — `private:` - [`src/nodes/face_detector_node.hpp:26`](../src/nodes/face_detector_node.hpp#L26) — `explicit FaceDetectorFunc(const Config& cfg)`
- [`src/nodes/face_detector_node.hpp:64`](../src/nodes/face_detector_node.hpp#L64) — `private:`
- [`src/nodes/face_tracker_node.hpp:2`](../src/nodes/face_tracker_node.hpp#L2) — `Unknown` - [`src/nodes/face_tracker_node.hpp:2`](../src/nodes/face_tracker_node.hpp#L2) — `Unknown`
- [`src/nodes/identity_matcher_node.hpp:117`](../src/nodes/identity_matcher_node.hpp#L117) — `const GalleryCalibration& calibration() const { return cal_; }` - [`src/nodes/identity_matcher_node.hpp:124`](../src/nodes/identity_matcher_node.hpp#L124) — `const GalleryCalibration& calibration() const { return cal_; }`
- [`src/nodes/identity_matcher_node.hpp:125`](../src/nodes/identity_matcher_node.hpp#L125) — `const GalleryCalibration& calibration() const { return cal_; }` - [`src/nodes/identity_matcher_node.hpp:132`](../src/nodes/identity_matcher_node.hpp#L132) — `const GalleryCalibration& calibration() const { return cal_; }`
- [`src/nodes/identity_matcher_node.hpp:166`](../src/nodes/identity_matcher_node.hpp#L166) — `std::vector<float> host_query(static_cast<size_t>(kMaxFaces) * 512);` - [`src/nodes/identity_matcher_node.hpp:173`](../src/nodes/identity_matcher_node.hpp#L173) — `std::vector<float> host_query(static_cast<size_t>(kMaxFaces) * 512);`
- [`src/nodes/identity_matcher_node.hpp:272`](../src/nodes/identity_matcher_node.hpp#L272) — `Unknown` - [`src/nodes/identity_matcher_node.hpp:280`](../src/nodes/identity_matcher_node.hpp#L280) — `Unknown`
- [`src/nodes/result_sink_node.hpp:49`](../src/nodes/result_sink_node.hpp#L49) — `static constexpr std::string_view label() { return "result_sink"; }` - [`src/nodes/result_sink_node.hpp:49`](../src/nodes/result_sink_node.hpp#L49) — `static constexpr std::string_view label() { return "result_sink"; }`
- [`src/nodes/result_sink_node.hpp:63`](../src/nodes/result_sink_node.hpp#L63) — `void set_pre_write_hook(std::function<void(double)> fn) { pre_write_ = std::move(fn); }` - [`src/nodes/result_sink_node.hpp:63`](../src/nodes/result_sink_node.hpp#L63) — `void set_pre_write_hook(std::function<void(double)> fn) { pre_write_ = std::move(fn); }`
- [`src/nodes/result_sink_node.hpp:161`](../src/nodes/result_sink_node.hpp#L161) — `struct ActorMeta { std::string name, imdb_id, tmdb_id, jellyfin_id; };` - [`src/nodes/result_sink_node.hpp:161`](../src/nodes/result_sink_node.hpp#L161) — `struct ActorMeta { std::string name, imdb_id, tmdb_id, jellyfin_id; };`
- [`src/nodes/scene_boundary_annotator_node.hpp:2`](../src/nodes/scene_boundary_annotator_node.hpp#L2) — `Unknown` - [`src/nodes/scene_boundary_annotator_node.hpp:2`](../src/nodes/scene_boundary_annotator_node.hpp#L2) — `Unknown`
- [`src/nodes/scene_detector_node.hpp:36`](../src/nodes/scene_detector_node.hpp#L36) — `static constexpr std::string_view label() { return "scene_detector"; }` - [`src/nodes/scene_detector_node.hpp:36`](../src/nodes/scene_detector_node.hpp#L36) — `static constexpr std::string_view label() { return "scene_detector"; }`
- [`src/nodes/scene_detector_node.hpp:110`](../src/nodes/scene_detector_node.hpp#L110) — `void flush_remaining()` - [`src/nodes/scene_detector_node.hpp:70`](../src/nodes/scene_detector_node.hpp#L70) — `void operator()(Frame f)`
- [`src/nodes/scene_detector_node.hpp:144`](../src/nodes/scene_detector_node.hpp#L144) — `void write_output()` - [`src/nodes/scene_detector_node.hpp:93`](../src/nodes/scene_detector_node.hpp#L93) — `Unknown`
- [`src/nodes/scene_detector_node.hpp:147`](../src/nodes/scene_detector_node.hpp#L147) — `void flush_remaining()`
- [`src/nodes/scene_detector_node.hpp:181`](../src/nodes/scene_detector_node.hpp#L181) — `void write_output()`
- [`src/scene_boundaries.hpp:2`](../src/scene_boundaries.hpp#L2) — `Unknown` - [`src/scene_boundaries.hpp:2`](../src/scene_boundaries.hpp#L2) — `Unknown`
- [`src/track_registry.hpp:2`](../src/track_registry.hpp#L2) — `Unknown` - [`src/track_registry.hpp:2`](../src/track_registry.hpp#L2) — `Unknown`
- [`src/types.hpp:62`](../src/types.hpp#L62) — `struct DetectedFace`
- [`tests/test_calibration.cpp:1`](../tests/test_calibration.cpp#L1) — `Unknown` - [`tests/test_calibration.cpp:1`](../tests/test_calibration.cpp#L1) — `Unknown`
- [`tests/test_embedding_dump.cpp:1`](../tests/test_embedding_dump.cpp#L1) — `Unknown`
- [`tests/test_face_detector_node.cpp:3`](../tests/test_face_detector_node.cpp#L3) — `Unknown`
- [`tests/test_face_tracker.cpp:1`](../tests/test_face_tracker.cpp#L1) — `Unknown` - [`tests/test_face_tracker.cpp:1`](../tests/test_face_tracker.cpp#L1) — `Unknown`
- [`tests/test_face_utils.cpp:1`](../tests/test_face_utils.cpp#L1) — `Unknown` - [`tests/test_face_utils.cpp:1`](../tests/test_face_utils.cpp#L1) — `Unknown`
- [`tests/test_scene_detector_node.cpp:4`](../tests/test_scene_detector_node.cpp#L4) — `Unknown`
- [`scripts/optimizer/replay.py:66`](../scripts/optimizer/replay.py#L66) — `for i in range(len(ts)):`
### SR-003 ### SR-003
@@ -693,15 +802,15 @@ _None._
**Locations:** 11 **Locations:** 11
- [`src/config.hpp:152`](../src/config.hpp#L152) — `Unknown` - [`src/config.hpp:171`](../src/config.hpp#L171) — `Unknown`
- [`src/gallery/gallery_store.hpp:15`](../src/gallery/gallery_store.hpp#L15) — `Unknown` - [`src/gallery/gallery_store.hpp:15`](../src/gallery/gallery_store.hpp#L15) — `Unknown`
- [`src/gallery/track_gallery.hpp:123`](../src/gallery/track_gallery.hpp#L123) — `void forget(int track_id) { tracks_.erase(track_id); }` - [`src/gallery/track_gallery.hpp:155`](../src/gallery/track_gallery.hpp#L155) — `void forget(int track_id) { tracks_.erase(track_id); }`
- [`src/gallery/track_gallery.hpp:133`](../src/gallery/track_gallery.hpp#L133) — `void set_calibration(std::function<float(float)> c) { calibrate_ = std::move(c); }` - [`src/gallery/track_gallery.hpp:165`](../src/gallery/track_gallery.hpp#L165) — `void set_calibration(std::function<float(float)> c) { calibrate_ = std::move(c); }`
- [`src/gallery/track_gallery.hpp:164`](../src/gallery/track_gallery.hpp#L164) — `struct TrackState` - [`src/gallery/track_gallery.hpp:196`](../src/gallery/track_gallery.hpp#L196) — `struct TrackState`
- [`src/gallery/track_gallery.hpp:274`](../src/gallery/track_gallery.hpp#L274) — `static int plurality_actor(const TrackState& ts)` - [`src/gallery/track_gallery.hpp:309`](../src/gallery/track_gallery.hpp#L309) — `static int plurality_actor(const TrackState& ts)`
- [`src/nodes/identity_matcher_node.hpp:110`](../src/nodes/identity_matcher_node.hpp#L110) — `std::vector<float> host_gallery(static_cast<size_t>(n_gallery_) * 512);` - [`src/nodes/identity_matcher_node.hpp:117`](../src/nodes/identity_matcher_node.hpp#L117) — `std::vector<float> host_gallery(static_cast<size_t>(n_gallery_) * 512);`
- [`src/nodes/identity_matcher_node.hpp:147`](../src/nodes/identity_matcher_node.hpp#L147) — `MatchedSceneFrame operator()(TrackedSceneFrame tf)` - [`src/nodes/identity_matcher_node.hpp:154`](../src/nodes/identity_matcher_node.hpp#L154) — `MatchedSceneFrame operator()(TrackedSceneFrame tf)`
- [`src/nodes/identity_matcher_node.hpp:285`](../src/nodes/identity_matcher_node.hpp#L285) — `Unknown` - [`src/nodes/identity_matcher_node.hpp:293`](../src/nodes/identity_matcher_node.hpp#L293) — `Unknown`
- [`tests/test_track_gallery.cpp:1`](../tests/test_track_gallery.cpp#L1) — `Unknown` - [`tests/test_track_gallery.cpp:1`](../tests/test_track_gallery.cpp#L1) — `Unknown`
- [`scripts/make_jellyfin_gallery.py:4`](../scripts/make_jellyfin_gallery.py#L4) — `Unknown` - [`scripts/make_jellyfin_gallery.py:4`](../scripts/make_jellyfin_gallery.py#L4) — `Unknown`
@@ -711,6 +820,32 @@ _None._
- [`tests/test_track_registry.cpp:3`](../tests/test_track_registry.cpp#L3) — `Unknown` - [`tests/test_track_registry.cpp:3`](../tests/test_track_registry.cpp#L3) — `Unknown`
### UT-002
**Locations:** 1
- [`tests/test_face_detector_node.cpp:3`](../tests/test_face_detector_node.cpp#L3) — `Unknown`
### UT-003
**Locations:** 1
- [`tests/test_scene_detector_node.cpp:4`](../tests/test_scene_detector_node.cpp#L4) — `Unknown`
### UT-004
**Locations:** 2
- [`tests/test_similarity.cpp:1`](../tests/test_similarity.cpp#L1) — `Unknown`
- [`tests/test_similarity.cpp:85`](../tests/test_similarity.cpp#L85) — `Unknown`
### UT-005
**Locations:** 2
- [`tests/test_track_gallery.cpp:1`](../tests/test_track_gallery.cpp#L1) — `Unknown`
- [`tests/test_track_gallery.cpp:341`](../tests/test_track_gallery.cpp#L341) — `TrackGallery tg(expand_cfg());`
### UT-101 ### UT-101
**Locations:** 5 **Locations:** 5
@@ -772,11 +907,114 @@ _None._
- [`scripts/validation/test_audio_offset.py:5`](../scripts/validation/test_audio_offset.py#L5) — `The golden vector (IR-005) proves the *arithmetic* is identical in both` - [`scripts/validation/test_audio_offset.py:5`](../scripts/validation/test_audio_offset.py#L5) — `The golden vector (IR-005) proves the *arithmetic* is identical in both`
### UT-120
**Locations:** 1
- [`tests/test_benchmark.cpp:3`](../tests/test_benchmark.cpp#L3) — `Unknown`
### UT-121
**Locations:** 1
- [`tests/test_benchmark.cpp:3`](../tests/test_benchmark.cpp#L3) — `Unknown`
### UT-122
**Locations:** 1
- [`tests/test_benchmark.cpp:3`](../tests/test_benchmark.cpp#L3) — `Unknown`
### UT-123
**Locations:** 1
- [`tests/test_benchmark.cpp:3`](../tests/test_benchmark.cpp#L3) — `Unknown`
### UT-124
**Locations:** 1
- [`tests/test_benchmark.cpp:3`](../tests/test_benchmark.cpp#L3) — `Unknown`
### UT-130
**Locations:** 1
- [`tests/test_face_utils.cpp:1`](../tests/test_face_utils.cpp#L1) — `Unknown`
### UT-131
**Locations:** 1
- [`tests/test_face_utils.cpp:1`](../tests/test_face_utils.cpp#L1) — `Unknown`
### UT-132
**Locations:** 1
- [`tests/test_face_utils.cpp:1`](../tests/test_face_utils.cpp#L1) — `Unknown`
### UT-133
**Locations:** 1
- [`tests/test_face_utils.cpp:1`](../tests/test_face_utils.cpp#L1) — `Unknown`
### UT-134
**Locations:** 1
- [`tests/test_face_utils.cpp:1`](../tests/test_face_utils.cpp#L1) — `Unknown`
### UT-135
**Locations:** 1
- [`tests/test_face_utils.cpp:1`](../tests/test_face_utils.cpp#L1) — `Unknown`
### UT-136
**Locations:** 1
- [`tests/test_face_utils.cpp:1`](../tests/test_face_utils.cpp#L1) — `Unknown`
### UT-137
**Locations:** 1
- [`tests/test_face_utils.cpp:1`](../tests/test_face_utils.cpp#L1) — `Unknown`
### UT-138
**Locations:** 1
- [`tests/test_face_utils.cpp:1`](../tests/test_face_utils.cpp#L1) — `Unknown`
### UT-139
**Locations:** 1
- [`tests/test_embedding_dump.cpp:1`](../tests/test_embedding_dump.cpp#L1) — `Unknown`
### UT-140
**Locations:** 1
- [`tests/test_embedding_dump.cpp:1`](../tests/test_embedding_dump.cpp#L1) — `Unknown`
### UT-141
**Locations:** 1
- [`tests/test_embedding_dump.cpp:1`](../tests/test_embedding_dump.cpp#L1) — `Unknown`
### VR-001 ### VR-001
**Locations:** 2 **Locations:** 3
- [`src/nodes/embedding_dump_node.hpp:2`](../src/nodes/embedding_dump_node.hpp#L2) — `Unknown` - [`src/nodes/embedding_dump_node.hpp:2`](../src/nodes/embedding_dump_node.hpp#L2) — `Unknown`
- [`tests/test_embedding_dump.cpp:1`](../tests/test_embedding_dump.cpp#L1) — `Unknown`
- [`tests/test_replay_fixtures.cpp:3`](../tests/test_replay_fixtures.cpp#L3) — `Unknown` - [`tests/test_replay_fixtures.cpp:3`](../tests/test_replay_fixtures.cpp#L3) — `Unknown`
### VR-002 ### VR-002
@@ -812,7 +1050,7 @@ _None._
- [`src/nodes/embedding_dump_node.hpp:18`](../src/nodes/embedding_dump_node.hpp#L18) — `Unknown` - [`src/nodes/embedding_dump_node.hpp:18`](../src/nodes/embedding_dump_node.hpp#L18) — `Unknown`
- [`src/nodes/embedding_dump_node.hpp:133`](../src/nodes/embedding_dump_node.hpp#L133) — `static constexpr std::string_view label() { return "embedding_dump"; }` - [`src/nodes/embedding_dump_node.hpp:133`](../src/nodes/embedding_dump_node.hpp#L133) — `static constexpr std::string_view label() { return "embedding_dump"; }`
- [`src/nodes/embedding_dump_node.hpp:159`](../src/nodes/embedding_dump_node.hpp#L159) — `void operator()(EmbeddedSceneFrame ef)` - [`src/nodes/embedding_dump_node.hpp:159`](../src/nodes/embedding_dump_node.hpp#L159) — `void operator()(EmbeddedSceneFrame ef)`
- [`src/nodes/embedding_dump_node.hpp:242`](../src/nodes/embedding_dump_node.hpp#L242) — `H5::H5File file(path_, H5F_ACC_TRUNC);` - [`src/nodes/embedding_dump_node.hpp:261`](../src/nodes/embedding_dump_node.hpp#L261) — `H5::H5File file(path_, H5F_ACC_TRUNC);`
### VR-013 ### VR-013
@@ -827,3 +1065,39 @@ _None._
- [`scripts/validation/test_audio_offset.py:5`](../scripts/validation/test_audio_offset.py#L5) — `The golden vector (IR-005) proves the *arithmetic* is identical in both` - [`scripts/validation/test_audio_offset.py:5`](../scripts/validation/test_audio_offset.py#L5) — `The golden vector (IR-005) proves the *arithmetic* is identical in both`
### VR-015
**Locations:** 21
- [`src/backends/trt_backend.cpp:49`](../src/backends/trt_backend.cpp#L49) — `throw CudaError(std::string(what) + ": " + cudaGetErrorString(e));`
- [`src/benchmark.hpp:2`](../src/benchmark.hpp#L2) — `Unknown`
- [`src/benchmark.hpp:86`](../src/benchmark.hpp#L86) — `namespace sae::bench`
- [`src/benchmark.hpp:107`](../src/benchmark.hpp#L107) — `struct ChannelOccupancy`
- [`src/benchmark.hpp:141`](../src/benchmark.hpp#L141) — `struct NodeCost`
- [`src/benchmark.hpp:176`](../src/benchmark.hpp#L176) — `Unknown`
- [`src/benchmark.hpp:185`](../src/benchmark.hpp#L185) — `Unknown`
- [`src/benchmark.hpp:267`](../src/benchmark.hpp#L267) — `inline std::string verdict(const std::vector<NodeCost>& costs)`
- [`src/benchmark.hpp:315`](../src/benchmark.hpp#L315) — `class BenchmarkRecorder`
- [`src/benchmark.hpp:384`](../src/benchmark.hpp#L384) — `return attribute_cost(final_.nodes, channels(), final_.elapsed_s);`
- [`src/benchmark.hpp:465`](../src/benchmark.hpp#L465) — `void print(std::ostream& os, double film_sec) const`
- [`src/benchmark.hpp:472`](../src/benchmark.hpp#L472) — `void print(std::ostream& os, double film_sec) const`
- [`src/benchmark.hpp:522`](../src/benchmark.hpp#L522) — `else if (c.in_fill_pct > 50.0)`
- [`src/config.hpp:35`](../src/config.hpp#L35) — `Unknown`
- [`src/main.cpp:109`](../src/main.cpp#L109) — `static std::shared_ptr<SceneBoundaries> scene_stats;`
- [`src/main.cpp:203`](../src/main.cpp#L203) — `int main(int argc, char** argv)`
- [`src/main.cpp:280`](../src/main.cpp#L280) — `Unknown`
- [`src/main.cpp:354`](../src/main.cpp#L354) — `std::lock_guard<std::mutex> lk(event_mtx);`
- [`src/main.cpp:380`](../src/main.cpp#L380) — `Unknown`
- [`src/main.cpp:393`](../src/main.cpp#L393) — `Unknown`
- [`tests/test_benchmark.cpp:3`](../tests/test_benchmark.cpp#L3) — `Unknown`
## Tag diagnostics
**Groups mixing requirement types (pipe separates types):**
- `src/benchmark.hpp:176` — {'group': ['VR-015', 'AR-004']}
- `src/benchmark.hpp:472` — {'group': ['VR-015', 'AR-004']}
- `src/benchmark.hpp:522` — {'group': ['VR-015', 'AR-004']}
- `src/main.cpp:109` — {'group': ['VR-015', 'AR-004']}
- `src/main.cpp:380` — {'group': ['VR-015', 'AR-004']}
+11 -3
View File
@@ -47,9 +47,17 @@ struct SceneBoundaryAnnotatorFunc {
// consumer is slower, and this branch is orders of magnitude faster per // consumer is slower, and this branch is orders of magnitude faster per
// frame than TransNetV2. Blocking here is what makes the join real. // frame than TransNetV2. Blocking here is what makes the join real.
// //
// Safe under backpressure because the branches are independent: this // What makes that safe is **join depth**, not branch independence. Now
// node stalling does not stop the detector consuming dense frames, and // that the fanout is lossless (AR-004) it stops popping once this branch
// the fanout keeps feeding it. // stops taking, so stalling here does eventually starve the detector —
// the two would wedge if this node could ask about a frame the detector
// has not been given the frames to score. It cannot, by a wide margin:
// the fanout can run the dense branch ahead by the whole of this
// branch's buffering, which is kSceneJoinDepth (256) *sampled* frames,
// and at sample_fps 5 against a ~25 fps source that is on the order of
// 1200 dense frames against TransNetV2's 100-frame window.
//
// Cutting kSceneJoinDepth below the window would reintroduce the wedge.
if (!bounds_->wait_until_scored(f.timestamp_sec)) { if (!bounds_->wait_until_scored(f.timestamp_sec)) {
// The detector finished without covering this frame — the tail after // The detector finished without covering this frame — the tail after
// its last full window. Unknown, not negative; counted so it cannot // its last full window. Unknown, not negative; counted so it cannot