docs: VR-013 and VR-014 results; AR-002 raised to 40px
Records study results and the requirement change that follows from them. VR-013 measures minimum face size end to end — gallery from one recording, probes from another — rather than by degrading an already-aligned crop. Holding 90% of the plateau needs ~50 px that way against VR-005's ~22 px, the gap being detection and landmark error rather than the embedder. AR-002 therefore takes 40 px, not 32: VR-005 isolates the embedder and is an upper bound, and 32 admits faces in the falling region. FPI stayed 0.0% at every scale, and the ceiling is cross-view rather than resolution. VR-014 exercises audio-signature offset recovery on real film audio instead of the synthetic golden tone. Forty 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 quantisation floor rather than a result, since offsets land on whole 92.88 ms frames. The runtime/2 anchor is confirmed through head-trimmed files. The soft spot VR-014 found is tier labelling, not accuracy: the score drops with sub-frame misalignment, so 27 of 40 correct alignments were demoted to `loose`. One frame of slack in the score restores all forty to `audio` with false matches unmoved. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> TRACES: AR-002, VR-005, VR-013, VR-014 | SR-002, SR-003
This commit is contained in:
+82
-16
@@ -40,12 +40,28 @@ Detect faces in sampled video frames.
|
||||
presence (SR-002) a lower rate still answers the question, but it lengthens the
|
||||
interval between samples and so weakens IoU-based association; sweep the two
|
||||
together (VR-002).
|
||||
- **Minimum face size is 66×66 px**, expressed in **original video resolution**,
|
||||
- **Minimum face size is 40×40 px**, expressed in **original video resolution**,
|
||||
not decoded-frame pixels. Stating it in original space decouples it from
|
||||
`dense_scale`: otherwise a 0.5 downscale silently doubles the effective
|
||||
threshold, and dense mode is exactly what scene detection uses.
|
||||
66 is a working estimate of where ArcFace embeddings stop being reliable, not a
|
||||
measured value — it should be replaced by the result of VR-005.
|
||||
|
||||
40 is **measured, not estimated** — it replaces an earlier 66 px guess. Two
|
||||
studies bracket it, and the difference between them is the whole reason the
|
||||
number is 40 rather than 32:
|
||||
|
||||
- **VR-005** degrades an already-aligned 112×112 crop and matches it against
|
||||
a native-resolution gallery. Alignment is held perfect, so it isolates the
|
||||
*embedder*: the knee sits at 24–32 px, and 32 px still returns 98.1% TPI.
|
||||
- **VR-013** downscales the **whole frame before the detector**, so detection
|
||||
and landmark regression degrade along with it. End to end, holding 90% of
|
||||
the plateau needs roughly **50 px**, against VR-005's ~22 px.
|
||||
|
||||
The gap is detection and landmark error, which VR-005 excludes by construction
|
||||
— so VR-005 is an **upper bound on quality**, not a threshold, and reading a
|
||||
floor off it would admit faces in the falling region. **AR-002 therefore takes
|
||||
VR-013's number.** 40 sits below the 50 px plateau deliberately: FPI is 0.0% at
|
||||
every scale in both studies, so resolution loss costs recall and never
|
||||
precision, and an over-tight floor discards presence that SR-002 requires.
|
||||
- Emits bounding box, detector confidence, and 5-point landmarks.
|
||||
- Bounding boxes must be reported in **original video pixel space**. When
|
||||
`dense_scale < 1` downscales the decoded frame, coordinates are rescaled by
|
||||
@@ -59,7 +75,9 @@ Detect faces in sampled video frames.
|
||||
**Current:** SCRFD-500MF via `face_detector_node.hpp`, thresholds in `config.hpp`
|
||||
(`detector_conf` 0.5, `detector_nms` 0.4), `min_face_px` 40, `max_faces` 10.
|
||||
|
||||
**Gap:** `min_face_px` → 66 and re-expressed in original resolution; `max_faces`
|
||||
**Gap:** `min_face_px` re-expressed in original resolution — the value 40 is
|
||||
already correct after VR-013, so what remains is the space it is measured in, not
|
||||
the number; `max_faces`
|
||||
removed, gated on backpressure (AR-004).
|
||||
|
||||
## AR-004 — Backpressure
|
||||
@@ -227,8 +245,8 @@ evidence. They are kept separate and **not collapsed into one scalar**: they fai
|
||||
for different reasons, have different remedies, and — as below — do not even earn
|
||||
the same response.
|
||||
|
||||
- **Size** — already AR-002, floor at 32×32 px in original resolution, measured
|
||||
by VR-005 (knee at 24–32 px). It is the precedent for the other two: the
|
||||
- **Size** — already AR-002, floor at 40×40 px in original resolution, measured
|
||||
end to end by VR-013. It is the precedent for the other two: the
|
||||
threshold was *located*, not chosen.
|
||||
- **Sharpness** — motion blur and soft focus destroy the high-frequency detail
|
||||
the embedder keys on, and unlike size they leave the bounding box looking
|
||||
@@ -260,6 +278,15 @@ the same response.
|
||||
canonical px. Smooth and monotone with a usable range; the mapping onto real
|
||||
faces is VR-012's to establish, and no threshold is set from these numbers.
|
||||
|
||||
**The synthetic ladder is noise-free and therefore optimistic about the low
|
||||
end.** Measured on 400 real TMDB/Jellyfin headshots — the most frontal, most
|
||||
cooperative population the pipeline ever sees — the residual runs p5 1.11,
|
||||
median 2.74, p90 4.82, max 6.35 canonical px. So landmark noise alone occupies
|
||||
roughly the first 3 px, and the synthetic sweep's "26° yaw ≈ 1.2 px" sits
|
||||
*below* the noise floor on real data. VR-012 must set any threshold against
|
||||
this measured distribution, and a discount curve has to treat the first few
|
||||
pixels as uninformative rather than as mild pose.
|
||||
|
||||
Neither a dedicated landmark model (`models/2d106det.onnx` is present but
|
||||
referenced nowhere — and it emits points, not pose) nor a direct pose CNN is
|
||||
adopted unless VR-012 shows the residual insufficient. If one is needed the
|
||||
@@ -278,15 +305,6 @@ the same response.
|
||||
Only size drops the face outright, and only because VR-005 measured a knee below
|
||||
which the embedding carries no signal to discount. Blur and pose are different:
|
||||
|
||||
**The synthetic ladder is noise-free and therefore optimistic about the low
|
||||
end.** Measured on 400 real TMDB/Jellyfin headshots — the most frontal, most
|
||||
cooperative population the pipeline ever sees — the residual runs p5 1.11,
|
||||
median 2.74, p90 4.82, max 6.35 canonical px. So landmark noise alone occupies
|
||||
roughly the first 3 px, and the synthetic sweep's "26° yaw ≈ 1.2 px" sits
|
||||
*below* the noise floor on real data. VR-012 must set any threshold against
|
||||
this measured distribution, and a discount curve has to treat the first few
|
||||
pixels as uninformative rather than as mild pose.
|
||||
|
||||
- A blurred or turned face is still evidence of **presence**, which is what
|
||||
SR-002 actually asks about.
|
||||
- The tracker admits a link on position *or* identity precisely so that a face
|
||||
@@ -1277,7 +1295,47 @@ plugin. Consequences to carry through:
|
||||
- Files never processed by this pipeline still get a signature from the plugin;
|
||||
the two paths coexist deliberately.
|
||||
|
||||
**Gap:** entire requirement — no audio path exists in the pipeline today.
|
||||
**Current:** `src/audio_signature.*` implements the construction, and
|
||||
`tests/fixtures/audio/` holds the golden vector shared verbatim with the plugin
|
||||
repo, which now matches it byte for byte from C# (jRay `JR-042`/`JR-043`).
|
||||
`sae_audio` (nanobind, as `sae_embed` and `sae_kpn` are) exposes the same C++ to
|
||||
Python so a study drives the shipped code rather than a numpy port.
|
||||
|
||||
**VR-014 measures what the golden vector cannot** — that the signature actually
|
||||
aligns a differently trimmed release, on real film audio rather than a synthetic
|
||||
tone. It does, with an order of magnitude to spare.
|
||||
|
||||
**The accuracy question is settled and is not close.** What the offset is *for*
|
||||
is shifting scene windows, which are seconds long, so half a second of error is
|
||||
invisible; the budget is 500 ms. Over 40 random offsets inside the ±600-frame cap
|
||||
the recovered offset was the nearest frame every time — **worst error 46 ms**.
|
||||
That figure is the quantisation floor rather than a measurement of quality: the
|
||||
offset is expressed in whole 92.88 ms frames, so no correct answer can ever be
|
||||
worse than half a frame. The `runtime/2` anchor behaves as specified through real
|
||||
head-trimmed files (cutting `delta` from the head moves the window by
|
||||
`delta/2`), and both an out-of-cap offset and unrelated content are declined
|
||||
outright (0.10 and 0.07).
|
||||
|
||||
**Where it is soft is tier labelling, not alignment.** The *score* at the correct
|
||||
offset falls with sub-frame misalignment — 0.94–0.99 when the true offset lands
|
||||
within 0.1 of a frame boundary, 0.69–0.73 at half a frame — because the two
|
||||
windows' frame grids no longer coincide. The offset stays right, but only 13 of
|
||||
40 cleared the server's 0.85 `audio` threshold and the other 27 were demoted to
|
||||
`loose`, a tier that means "possibly the same cut, degraded audio". The threshold
|
||||
was calibrated on a re-encode at *zero* offset, where the score is 1.00.
|
||||
|
||||
The remedy is measured, not proposed (UT-108): counting a frame as agreeing if
|
||||
its peak bin matches **within ±1 frame** returns all 40 to `audio` (worst 0.906)
|
||||
while unrelated content and out-of-cap offsets stay at 0.12 and 0.16 — the gap
|
||||
that makes the threshold mean anything is untouched. It costs 81 ms of offset
|
||||
accuracy, of a 500 ms budget, because the flattened peak lets the argmax pick an
|
||||
adjacent frame. ±2 frames buys nothing further. Adopting it is a
|
||||
[server spec](../../JRay-public-server/SPEC.md) §3 change — the score is
|
||||
normative and shared by three repos — so this repo measures it and leaves the
|
||||
decision there.
|
||||
|
||||
**Gap:** the signature is computed but **not yet emitted** into the truth file —
|
||||
that is the `IR-002` field and the coordinated `schema_version` bump.
|
||||
|
||||
## IR-006 — Jellyfin round-trip
|
||||
|
||||
@@ -1524,6 +1582,14 @@ Verify `landmarks`/`bbox`/`is_cut` suffice, and bump `schema_version` if not.
|
||||
Quantify where ArcFace degrades, replacing the 66×66 estimate in A1 with a
|
||||
measurement.
|
||||
|
||||
> **Result, and its limit.** Knee at 24–32 px; 32 px returns 98.1% TPI at 0.0
|
||||
> FPI. But the probe is an already-aligned 112×112 crop, so alignment is held
|
||||
> perfect and this measures the **embedder alone** — an upper bound, not a
|
||||
> threshold. **VR-013** re-asks the question end to end, downscaling the whole
|
||||
> frame before the detector, and lands near 50 px. AR-002's floor of 40 px comes
|
||||
> from VR-013; this study is what shows how much of the gap is detection and
|
||||
> landmark error rather than embedding.
|
||||
|
||||
**Method.**
|
||||
|
||||
1. Select ~100 gallery actors having more than one mugshot.
|
||||
|
||||
+64
-3
@@ -243,7 +243,9 @@ Context crops opt-in behind `--dump-unidentified-crops`.
|
||||
|
||||
**Depends on:** nothing (AR-002, AR-011); AR-004 blocks AR-003.
|
||||
|
||||
- **AR-002** — `min_face_px` → 66, expressed in original resolution.
|
||||
- **AR-002** — `min_face_px` stays **40** (VR-013 measured it end to end) but must
|
||||
be expressed in original resolution rather than decoded-frame space. The value
|
||||
is already right in `config.hpp`; the change is the coordinate space.
|
||||
- **AR-011** — feed TransNetV2 at native rate; derive the dedup window from
|
||||
source fps rather than the hardcoded `0.04 s`.
|
||||
- **AR-004** — backpressure. `kMaxFaces` (`identity_matcher_node.hpp:133`)
|
||||
@@ -324,8 +326,67 @@ Windows carry belief and route; `extraction.*` gains `extinction_sec` and
|
||||
|
||||
## VR-005 — Minimum face size study
|
||||
|
||||
**Depends on:** nothing. Standalone Python, no C++ contact. Produces the measured
|
||||
value replacing AR-002's 66 px estimate.
|
||||
**Depends on:** nothing. Standalone Python, no C++ contact. **Done** — knee at
|
||||
24–32 px. It measures the embedder with alignment held perfect, so it bounds the
|
||||
answer from below rather than setting it; AR-002's floor comes from **VR-013**,
|
||||
which sweeps input resolution end to end and lands at 40 px.
|
||||
|
||||
## VR-013 — Cross-source identification probe
|
||||
|
||||
**Depends on:** `sae_embed` exposing `detect()`, `align_face()`, `embed_crop()`
|
||||
and the gallery calibration — it drives the shipped C++ rather than reimplementing
|
||||
it, which is what VR-005 could not do.
|
||||
|
||||
Gallery from one recording, probes from another, sweeping the probe's **input
|
||||
resolution before the detector**, so detection and landmark regression degrade
|
||||
with the frame. `experiments/xsource/`.
|
||||
|
||||
**Findings.** Holding 90% of the plateau needs ~50 px end to end against VR-005's
|
||||
~22 px; `min_face_px` 40 is right and 32 would admit faces in the falling region.
|
||||
FPI is 0.0% at every scale — resolution loss goes entirely to TBI, never to a
|
||||
wrong name. The ceiling is **cross-view, not resolution**: everyone matches
|
||||
themselves within a recording (0.55–0.85) and collapses across two (0.14–0.45),
|
||||
and only the subject with frontal *gallery* references identified reliably — so
|
||||
the lever is gallery pose coverage (`docs/pose-expansion.md`), not a better
|
||||
landmark model. Averaging SCRFD's NMS-discarded landmark estimates lifts
|
||||
cross-clip TPI 41% → 49% for one forward pass.
|
||||
|
||||
**Open.** Four identities and one shoot, so the shape is the result and the
|
||||
absolute rates are not. Both clips hold all four people, so there is no
|
||||
out-of-gallery class and the 10×-weighted out-of-cast misID is untested — holding
|
||||
one identity out of the gallery would fix that.
|
||||
|
||||
## VR-014 — Audio-signature offset recovery
|
||||
|
||||
**Depends on:** `sae_audio` exposing `compute_signature()` and
|
||||
`signature_from_mono()` — it drives the shipped C++, as VR-013 does, so the
|
||||
thing measured is the thing that ships.
|
||||
|
||||
`scripts/validation/test_audio_offset.py` over
|
||||
`tests/fixtures/audio/bali_offset_200s.flac`: 200 s of public-domain film audio
|
||||
(the same Road to Bali clips the replay fixtures use), long enough for a 120 s
|
||||
window to slide past the ±600-frame search cap. The slide itself is numpy here
|
||||
on purpose — matching belongs to the consumer, so writing it out keeps this a
|
||||
test of the signature rather than of somebody's matcher.
|
||||
|
||||
**Findings.** Alignment is a solved problem here: the offset is the nearest frame
|
||||
in every in-cap trial, worst error **46 ms against a 500 ms budget**, and 46 ms is
|
||||
the quantisation floor — offsets are whole 92.88 ms frames, so no correct answer
|
||||
can be worse. The `runtime/2` anchor's factor of two holds through real trimmed
|
||||
files, and out-of-cap offsets and unrelated content are both declined.
|
||||
|
||||
**The score is where the slack is, and it costs a tier rather than accuracy.** It
|
||||
tracks sub-frame misalignment — 0.94–0.99 near a frame boundary, 0.69–0.73 at
|
||||
half a frame — so two thirds of correct alignments miss the server's 0.85 `audio`
|
||||
threshold and land in `loose`. UT-108 measures the fix rather than proposing one:
|
||||
±1 frame of slack in the score returns all 40 to `audio` (min 0.906) with false
|
||||
matches unmoved at 0.12–0.16, costing 81 ms of the budget. See
|
||||
[`SPEC.md`](SPEC.md) IR-004 — the score is normative in the server spec, so the
|
||||
change is theirs to make.
|
||||
|
||||
**Open.** One source, one language, one era of recording. The shape (offset exact,
|
||||
score set by sub-frame phase) should hold generally, but the absolute scores are
|
||||
this fixture's.
|
||||
|
||||
## VR-001 — Dump audit
|
||||
|
||||
|
||||
+11
-8
@@ -29,7 +29,7 @@ Status: `Done` · `In Progress` · `Planned` · `TBD` · `Withdrawn`
|
||||
| ID | Requirement | Traces to | Priority | Status |
|
||||
|---|---|---|---|---|
|
||||
| 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 **32×32 px** (VR-005 measured), expressed in **original** resolution (decoupled from `dense_scale`) | SR-002 | High | Planned |
|
||||
| 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 | Planned |
|
||||
| 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 | **Done** — KPN node outputs use `push_blocking`; sentinels stay out-of-band. Verified: 385/385 frames, 0 drops, byte-identical across runs |
|
||||
| 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 |
|
||||
@@ -107,7 +107,7 @@ Status: `Done` · `In Progress` · `Planned` · `TBD` · `Withdrawn`
|
||||
| VR-002 | Replay drives the **real** KPN nodes, not a reimplementation | PR-002 | High | **Done** — replay driven from committed fixtures in `tests/test_replay_fixtures.cpp`; determinism asserted |
|
||||
| VR-003 | Scoring: micro-F1 against X-Ray, precision/recall logged at every evaluation | PR-002 | High | Done |
|
||||
| VR-004 | Reproducible validation corpus with ground truth | PR-002 | High | Done |
|
||||
| VR-005 | Minimum face size study — TPI/FPI vs probe size, gallery held at native res | PR-002 | Medium | **Done** — knee at 24–32 px; 32 px gives 98.1% TPI, 0.0 FPI at every size |
|
||||
| VR-005 | Minimum face size study — TPI/FPI vs probe size, gallery held at native res | PR-002 | Medium | **Done** — knee at 24–32 px; 32 px gives 98.1% TPI, 0.0 FPI at every size. Degrades an already-aligned 112×112 crop, so it isolates the embedder and is an **upper bound**; VR-013 measures the same question end to end and AR-002 takes its number, not this one |
|
||||
| VR-006 | Re-tune `scene_threshold` once native-rate decode lands | PR-002 | Low | Planned |
|
||||
| VR-007 | Expansion band, clustering threshold, and deferred-pass ablation | PR-002 | Medium | Planned |
|
||||
| VR-008 | Gallery scaling benchmark — throughput vs gallery size | PR-002 | Medium | Planned |
|
||||
@@ -115,7 +115,8 @@ Status: `Done` · `In Progress` · `Planned` · `TBD` · `Withdrawn`
|
||||
| VR-010 | Dump provenance attributes — embedder model, detector settings, `dense_scale`, `scene_detect`, sample rate | 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-013 | Cross-source identification probe — gallery from one recording, probes from another, swept over input resolution end to end | PR-002 | Medium | In Progress |
|
||||
| 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.94–0.99 near a frame boundary, 0.69–0.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.12–0.16, costing 81 ms of the budget |
|
||||
| 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 |
|
||||
|
||||
---
|
||||
|
||||
@@ -200,7 +201,7 @@ as such rather than counted as covered.
|
||||
| Requirement | Tier | Note |
|
||||
|---|---|---|
|
||||
| AR-001, AR-005, AR-006 | T3 | Smoke only — correctness of detection/embedding is a model property, not ours |
|
||||
| AR-002 | Minimum face size **32×32 px** (VR-005 measured), expressed in **original** resolution (decoupled from `dense_scale`) | Size filtering is arithmetic on dumped bboxes |
|
||||
| AR-002 | T2 | Size filtering is arithmetic on dumped bboxes |
|
||||
| AR-003, AR-004 | T1 + T4 | Backpressure logic is unit-testable; saturation behaviour needs real load |
|
||||
| AR-007 … AR-017 | **T2** | The core of the redesign — fully replayable |
|
||||
| AR-018 … AR-022 | **T2** | Expansion, deferred pass, clustering: all post-embedding |
|
||||
@@ -241,9 +242,10 @@ from a copyrighted title could not live in the repository at all.
|
||||
Two properties to design around rather than discover:
|
||||
|
||||
- **480×360 means small faces.** At this resolution a face is often 40–80 px, so
|
||||
the AR-002 minimum of 66 px (original resolution) rejects much of what is
|
||||
there. Fixture generation must set `--min-face-px` explicitly and record it,
|
||||
or the dumps will be sparse for reasons unrelated to what is being tested.
|
||||
the AR-002 minimum of 40 px (original resolution) sits at the very bottom of
|
||||
that range: the filter is close to binding, and anything shot wider is lost.
|
||||
Fixture generation must set `--min-face-px` explicitly and record it, or the
|
||||
dumps will be sparse for reasons unrelated to what is being tested.
|
||||
- **77 s is short.** At 1 fps that is 77 frames — too thin to exercise an
|
||||
extinction window measured in tens of seconds. Generate at 5 fps (≈385 frames,
|
||||
~1 MB) and record the rate in provenance, since the behaviour under test
|
||||
@@ -307,7 +309,7 @@ because it will be trusted.
|
||||
| ID | Tier | Test asserts | Edge cases to cover |
|
||||
|---|---|---|---|
|
||||
| AR-001 | T3 | Detector returns plausible boxes on a known frame | — smoke only |
|
||||
| AR-002 | T2 | Faces below 32 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-004 | T1 | Saturated input blocks rather than drops or throws | Bounded queue at capacity; **byte-based** limit with large crops; SIGTERM mid-block |
|
||||
| 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 |
|
||||
@@ -340,6 +342,7 @@ because it will be trusted.
|
||||
| IR-001/002 | T1 | Serialised output matches golden file | Zero-length window; actor with many windows |
|
||||
| IR-003 | T1 | Output written after deferred pass | Not at EOF |
|
||||
| IR-004/005 | **T1** | Signature matches golden vector bit-for-bit | Identical result in both producer repos |
|
||||
| VR-014 | **T2** | A known trim offset is recovered from **real film audio**, to the nearest frame | An offset past the ±600-frame cap and unrelated content must both be *declined*, never given a best-effort alignment. Fixture and signature are both CPU-only, so unlike the other VR rows this one is CI-*executable* — though the repo's only workflow today is the traceability gate, so nothing runs it there yet. The signature comes from the shipped C++ through `sae_audio`; a numpy port would be a third implementation nobody checks against the golden vector |
|
||||
| IR-006 | T1 + manual | Queue pull and result push against a stubbed Jellyfin API | Partial result never pushed; push only after the deferred pass |
|
||||
| IR-007 | **T1** | Media < 120 s emits no signature at all | Exactly 120 s; just under; zero-length audio. Must match the plugin's cutoff exactly — a caller-varying window length is what SR-004 forbids |
|
||||
| IR-008 | T1 | `v1:` prefix emitted and honoured on read | Unknown prefix rejected, not guessed |
|
||||
|
||||
+150
-68
@@ -3,7 +3,7 @@
|
||||
<!-- GENERATED FILE - do not edit by hand. -->
|
||||
<!-- Regenerate: scripts/traceability/traceability-gate.sh -->
|
||||
|
||||
**Generated:** 2026-07-31T13:11:03+00:00
|
||||
**Generated:** 2026-07-31T14:44:58+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`).
|
||||
|
||||
@@ -11,27 +11,27 @@ Denominators are read from [`requirements.md`](requirements.md) at run time, nev
|
||||
|
||||
| Metric | Value |
|
||||
|---|---|
|
||||
| Source files scanned | 108 |
|
||||
| TRACES tags found | 110 |
|
||||
| Source files scanned | 111 |
|
||||
| TRACES tags found | 132 |
|
||||
| EXCEPTION tags found | 0 |
|
||||
| Requirements defined | 67 |
|
||||
| Requirements covered | 32 |
|
||||
| **Coverage** | **47.8%** (32/67) |
|
||||
| Coverage of CI-executable scope | 58.2% (32/55) |
|
||||
| Tagged but unexecuted in CI | 4 |
|
||||
| Requirements defined | 69 |
|
||||
| Requirements covered | 38 |
|
||||
| **Coverage** | **55.1%** (38/69) |
|
||||
| Coverage of CI-executable scope | 67.9% (38/56) |
|
||||
| Tagged but unexecuted in CI | 5 |
|
||||
| Orphan tags | 0 |
|
||||
|
||||
### By type
|
||||
|
||||
| Type | Covered | Tagged but unexecuted | Defined |
|
||||
|---|---|---|---|
|
||||
| AR | 19 | 1 | 30 |
|
||||
| AR | 22 | 1 | 30 |
|
||||
| DP | 2 | 0 | 8 |
|
||||
| IR | 8 | 0 | 8 |
|
||||
| GR | 3 | 0 | 9 |
|
||||
| VR | 0 | 3 | 12 |
|
||||
| GR | 5 | 0 | 9 |
|
||||
| VR | 1 | 4 | 14 |
|
||||
|
||||
- **UT** tags present (separate taxonomy, not counted in coverage): UT-001, UT-101, UT-102, UT-103, UT-104
|
||||
- **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
|
||||
- **IT** tags present (separate taxonomy, not counted in coverage): IT-001
|
||||
- **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
|
||||
@@ -46,7 +46,7 @@ These requirements have no verification tier this repo's CI host can run, so a t
|
||||
| VR-001 | out-of-ci | yes | HDF5 post-inference dump at the embedded-frame boundary |
|
||||
| VR-002 | out-of-ci | yes | Replay drives the **real** KPN nodes, not a reimplementation |
|
||||
| VR-003 | out-of-ci | yes | Scoring: micro-F1 against X-Ray, precision/recall logged at every eva… |
|
||||
| VR-004 | out-of-ci | no | Reproducible validation corpus with ground truth |
|
||||
| VR-004 | out-of-ci | yes | Reproducible validation corpus with ground truth |
|
||||
| VR-005 | out-of-ci | no | Minimum face size study — TPI/FPI vs probe size, gallery held at nati… |
|
||||
| VR-006 | out-of-ci | no | Re-tune `scene_threshold` once native-rate decode lands |
|
||||
| VR-007 | out-of-ci | no | Expansion band, clustering threshold, and deferred-pass ablation |
|
||||
@@ -54,8 +54,9 @@ These requirements have no verification tier this repo's CI host can run, so a t
|
||||
| VR-010 | out-of-ci | no | Dump provenance attributes — embedder model, detector settings, `dens… |
|
||||
| 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-013 | T4, out-of-ci | no | Cross-source identification probe — gallery from one recording, probe… |
|
||||
|
||||
**Tagged but unexecuted:** AR-027, VR-001, VR-002, VR-003 — 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 — a test exists and is tagged, but this CI host cannot run it. Report those runs separately.
|
||||
|
||||
## Orphan tags
|
||||
|
||||
@@ -80,14 +81,14 @@ _None._
|
||||
| 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-002 | Planned | T2 | SR-002 | untagged | - | Minimum face size **32×32 px** (VR-005 measured), expressed in **orig… |
|
||||
| AR-002 | Planned | T2 | SR-002 | untagged | - | 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-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-005 | **Done** — `umeyama… | T1, T3 | SR-002 | covered | `src/face_utils.hpp`, `tests/test_face_utils.cpp` | Align to 112×112 via ArcFace 5-point similarity transform, fitted by … |
|
||||
| AR-006 | Done | T3 | SR-002 | untagged | - | 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` | 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` | One track pool keyed on `last_seen`; no separate revival path |
|
||||
| AR-009 | Done | T2 | SR-002 | untagged | - | 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-011 | Planned | T1, T2 | SR-002 | untagged | - | **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 |
|
||||
@@ -97,7 +98,7 @@ _None._
|
||||
| AR-016 | **Done** — `flush()… | T2 | SR-002 | covered | `src/main.cpp`, `src/nodes/result_sink_node.hpp`, `src/track_registry.hpp`, `tests/test_track_registry.cpp` | All tracks closed at EOF — a film ends with faces on screen |
|
||||
| AR-017 | **Done** — `DeadTra… | T1, T2 | SR-002 | covered | `src/nodes/result_sink_node.hpp`, `src/track_registry.hpp`, `tests/test_track_registry.cpp` | Every presence claim carries its belief and identification route |
|
||||
| AR-018 | **Done** — banded a… | T1, T2 | SR-005 | covered | `src/config.hpp`, `src/gallery/track_gallery.hpp`, `src/nodes/identity_matcher_node.hpp` | Per-subject embedding store with banded admission (novel enough, safe… |
|
||||
| AR-019 | In Progress | T2 | SR-005 | untagged | - | Per-film gallery annex from owned tracks; acquires the non-frontal vi… |
|
||||
| AR-019 | **Done** — all thre… | T2 | SR-005 | covered | `src/gallery/track_gallery.hpp`, `src/nodes/identity_matcher_node.hpp` | Per-film gallery annex from owned tracks; acquires the non-frontal vi… |
|
||||
| AR-020 | Planned | T2 | SR-005 | untagged | - | Deferred re-identification of unknown tracks against the final expand… |
|
||||
| AR-021 | Planned | T2 | SR-005 | untagged | - | Cluster unknown tracks into one entity per person, under temporal can… |
|
||||
| AR-022 | Planned | T1, T2 | §4 | untagged | - | Capture still-unidentified tracks: embeddings, metadata, **context cr… |
|
||||
@@ -120,16 +121,16 @@ _None._
|
||||
| IR-001 | Done | T1 | SR-003 | covered | `src/nodes/result_sink_node.hpp` | Emit the JRay truth format as sibling `.jray.json` |
|
||||
| IR-002 | **Done** — `schema_… | T1 | SR-003 | covered | `src/config.hpp`, `src/main.cpp`, `src/nodes/result_sink_node.hpp` | Windows carry belief + route; `extraction.*` carries `extinction_sec`… |
|
||||
| IR-003 | **In Progress** — s… | T1 | SR-003 | covered | `src/main.cpp` | Output written **after** the deferred pass, not at EOF |
|
||||
| IR-004 | **Done** — `src/aud… | T1 | SR-003 | covered | `src/audio_signature.cpp`, `src/audio_signature.hpp`, `tests/test_audio_signature.cpp` | Compute the audio signature exactly per server spec §3 |
|
||||
| IR-005 | **Done** — `tests/f… | T1 | SR-003 | covered | `src/audio_signature.cpp`, `src/audio_signature.hpp`, `tests/test_audio_signature.cpp` | Golden-vector fixture shared with the plugin repo to prove bit-exactn… |
|
||||
| IR-004 | **Done** — `src/aud… | T1 | SR-003 | covered | `scripts/validation/test_audio_offset.py`, `src/audio_bindings.cpp`, `src/audio_signature.cpp`, `src/audio_signature.hpp`, `tests/test_audio_signature.cpp` | Compute the audio signature exactly per server spec §3 |
|
||||
| IR-005 | **Done** — `tests/f… | T1 | SR-003 | covered | `src/audio_bindings.cpp`, `src/audio_signature.cpp`, `src/audio_signature.hpp`, `tests/test_audio_signature.cpp` | Golden-vector fixture shared with the plugin repo to prove bit-exactn… |
|
||||
| IR-006 | Done | T1, manual | SR-001 | covered | `scripts/run_from_jellyfin.py` | Jellyfin round-trip: pull pending queue, push complete results only |
|
||||
| IR-007 | **Done** | T1 | SR-003 | covered | `src/audio_signature.cpp`, `src/audio_signature.hpp`, `tests/test_audio_signature.cpp` | Media < 120 s: emit no signature, apply no sync offset — identical ru… |
|
||||
| IR-008 | **Done** | T1 | SR-003 | covered | `src/audio_signature.cpp`, `src/audio_signature.hpp`, `tests/test_audio_signature.cpp` | Emit and honour the signature's own `v1:` version prefix |
|
||||
| GR-001 | Done | T1, T3 | SR-001, SR-005 | covered | `scripts/make_jellyfin_gallery.py` | Build gallery from Jellyfin library cast, TMDB profile fallback |
|
||||
| GR-002 | Done | T1, T3 | PR-003 | covered | `scripts/make_jellyfin_gallery.py` | Incremental `--merge` refresh without re-embedding known actors |
|
||||
| GR-003 | Planned | T1, T3 | SR-001 | untagged | - | Report coverage: zero-image actors, under-referenced actors, dedup, c… |
|
||||
| GR-003 | Planned | T1, T3 | SR-001 | covered | `src/build_gallery.cpp`, `src/gallery/gallery_calibration.hpp`, `src/gallery/gallery_report.hpp` | Report coverage: zero-image actors, under-referenced actors, dedup, c… |
|
||||
| GR-004 | **Done** — basename… | T1, T3 | SR-001 | covered | `scripts/filter_gallery.py`, `scripts/make_gallery.py`, `scripts/make_jellyfin_gallery.py`, `scripts/movienet_eval.py`, `scripts/optimizer/fetch_missing_actors.py`, `scripts/optimizer/optimize.py`, `scripts/optimizer/reembed_gallery.py`, `scripts/optimizer/replay.py`, `scripts/sae_embed_loader.py`, `scripts/sae_gallery.py`, `scripts/sae_stamp.py`, `scripts/stamp_gallery.py`, `src/config.hpp`, `src/gallery/embedder_stamp.cpp`, `src/gallery/embedder_stamp.hpp`, `src/gallery/gallery_builder.cpp`, `src/gallery/gallery_store.cpp`, `src/kpn_bindings.cpp`, `src/main.cpp`, `src/nodes/embedding_dump_node.hpp`, `src/scene_preview.cpp`, `src/types.hpp`, `tests/test_gallery_store.cpp` | Stamp embedder identity into the gallery; **hard startup error** on m… |
|
||||
| GR-005 | Done | T1, T3 | **SR-005** | untagged | - | Gallery data never leaves the instance |
|
||||
| GR-005 | Done | T1, T3 | **SR-005** | covered | `src/gallery/gallery_store.hpp` | Gallery data never leaves the instance |
|
||||
| GR-006 | Planned | T1 | SR-005 | untagged | - | Provenance tiers: baked / harvested / confirmed, distinguishable per … |
|
||||
| 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… |
|
||||
@@ -137,7 +138,7 @@ _None._
|
||||
| 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-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-004 | Done | out-of-ci | PR-002 | untagged | - | 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 | untagged | - | 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-007 | Planned | out-of-ci | PR-002 | untagged | - | Expansion band, clustering threshold, and deferred-pass ablation |
|
||||
@@ -146,6 +147,8 @@ _None._
|
||||
| VR-010 | Planned | out-of-ci | PR-002 | untagged | - | Dump provenance attributes — embedder model, detector settings, `dens… |
|
||||
| VR-011 | Planned | out-of-ci | PR-002 | untagged | - | Rewrite the replay harness for the post-AR-012 output contract |
|
||||
| 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 | untagged | - | 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… |
|
||||
|
||||
## Detailed mapping
|
||||
|
||||
@@ -161,7 +164,7 @@ _None._
|
||||
|
||||
- [`src/config.hpp:44`](../src/config.hpp#L44) — `Unknown`
|
||||
- [`src/nodes/face_detector_node.hpp:47`](../src/nodes/face_detector_node.hpp#L47) — `private:`
|
||||
- [`src/nodes/identity_matcher_node.hpp:155`](../src/nodes/identity_matcher_node.hpp#L155) — `std::vector<float> host_query(static_cast<size_t>(kMaxFaces) * 512);`
|
||||
- [`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);`
|
||||
|
||||
### AR-004
|
||||
|
||||
@@ -169,7 +172,7 @@ _None._
|
||||
|
||||
- [`src/main.cpp:86`](../src/main.cpp#L86) — `static constexpr std::size_t kSceneJoinDepth = 256;`
|
||||
- [`src/main.cpp:299`](../src/main.cpp#L299) — `Unknown`
|
||||
- [`src/nodes/identity_matcher_node.hpp:155`](../src/nodes/identity_matcher_node.hpp#L155) — `std::vector<float> host_query(static_cast<size_t>(kMaxFaces) * 512);`
|
||||
- [`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);`
|
||||
- [`tests/test_replay_fixtures.cpp:3`](../tests/test_replay_fixtures.cpp#L3) — `Unknown`
|
||||
|
||||
### AR-005
|
||||
@@ -179,6 +182,12 @@ _None._
|
||||
- [`src/face_utils.hpp:2`](../src/face_utils.hpp#L2) — `Unknown`
|
||||
- [`tests/test_face_utils.cpp:1`](../tests/test_face_utils.cpp#L1) — `Unknown`
|
||||
|
||||
### AR-006
|
||||
|
||||
**Locations:** 1
|
||||
|
||||
- [`src/nodes/embedder_node.hpp:21`](../src/nodes/embedder_node.hpp#L21) — `struct EmbedderFunc`
|
||||
|
||||
### AR-007
|
||||
|
||||
**Locations:** 3
|
||||
@@ -195,6 +204,12 @@ _None._
|
||||
- [`src/main.cpp:213`](../src/main.cpp#L213) — `reg_cfg, EvidenceDiscounter(same_person));`
|
||||
- [`src/nodes/face_tracker_node.hpp:2`](../src/nodes/face_tracker_node.hpp#L2) — `Unknown`
|
||||
|
||||
### AR-009
|
||||
|
||||
**Locations:** 1
|
||||
|
||||
- [`src/nodes/camera_position_change_detector_node.hpp:30`](../src/nodes/camera_position_change_detector_node.hpp#L30) — `struct CameraPositionChangeDetectorFunc`
|
||||
|
||||
### AR-010
|
||||
|
||||
**Locations:** 9
|
||||
@@ -216,7 +231,7 @@ _None._
|
||||
- [`src/main.cpp:213`](../src/main.cpp#L213) — `reg_cfg, EvidenceDiscounter(same_person));`
|
||||
- [`src/main.cpp:230`](../src/main.cpp#L230) — `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:261`](../src/nodes/identity_matcher_node.hpp#L261) — `Unknown`
|
||||
- [`src/nodes/identity_matcher_node.hpp:272`](../src/nodes/identity_matcher_node.hpp#L272) — `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: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`
|
||||
@@ -267,9 +282,17 @@ _None._
|
||||
**Locations:** 3
|
||||
|
||||
- [`src/config.hpp:152`](../src/config.hpp#L152) — `Unknown`
|
||||
- [`src/gallery/track_gallery.hpp:150`](../src/gallery/track_gallery.hpp#L150) — `struct TrackState`
|
||||
- [`src/gallery/track_gallery.hpp:161`](../src/gallery/track_gallery.hpp#L161) — `struct TrackState`
|
||||
- [`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);`
|
||||
|
||||
### AR-019
|
||||
|
||||
**Locations:** 3
|
||||
|
||||
- [`src/gallery/track_gallery.hpp:122`](../src/gallery/track_gallery.hpp#L122) — `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:285`](../src/nodes/identity_matcher_node.hpp#L285) — `Unknown`
|
||||
|
||||
### AR-023
|
||||
|
||||
**Locations:** 3
|
||||
@@ -286,8 +309,8 @@ _None._
|
||||
- [`src/config.hpp:152`](../src/config.hpp#L152) — `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/track_gallery.hpp:122`](../src/gallery/track_gallery.hpp#L122) — `void forget(int track_id) { tracks_.erase(track_id); }`
|
||||
- [`src/gallery/track_gallery.hpp:150`](../src/gallery/track_gallery.hpp#L150) — `struct TrackState`
|
||||
- [`src/gallery/track_gallery.hpp:132`](../src/gallery/track_gallery.hpp#L132) — `void set_calibration(std::function<float(float)> c) { calibrate_ = std::move(c); }`
|
||||
- [`src/gallery/track_gallery.hpp:161`](../src/gallery/track_gallery.hpp#L161) — `struct TrackState`
|
||||
- [`src/main.cpp:213`](../src/main.cpp#L213) — `reg_cfg, EvidenceDiscounter(same_person));`
|
||||
- [`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);`
|
||||
@@ -299,7 +322,7 @@ _None._
|
||||
|
||||
- [`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:261`](../src/nodes/identity_matcher_node.hpp#L261) — `Unknown`
|
||||
- [`src/nodes/identity_matcher_node.hpp:272`](../src/nodes/identity_matcher_node.hpp#L272) — `Unknown`
|
||||
|
||||
### AR-026
|
||||
|
||||
@@ -344,6 +367,24 @@ _None._
|
||||
|
||||
- [`scripts/make_jellyfin_gallery.py:4`](../scripts/make_jellyfin_gallery.py#L4) — `Unknown`
|
||||
|
||||
### GR-003
|
||||
|
||||
**Locations:** 13
|
||||
|
||||
- [`src/build_gallery.cpp:83`](../src/build_gallery.cpp#L83) — `Unknown`
|
||||
- [`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:294`](../src/gallery/gallery_calibration.hpp#L294) — `Unknown`
|
||||
- [`src/gallery/gallery_report.hpp:2`](../src/gallery/gallery_report.hpp#L2) — `Unknown`
|
||||
- [`src/gallery/gallery_report.hpp:52`](../src/gallery/gallery_report.hpp#L52) — `struct GalleryBuildAudit`
|
||||
- [`src/gallery/gallery_report.hpp:73`](../src/gallery/gallery_report.hpp#L73) — `struct GalleryReport`
|
||||
- [`src/gallery/gallery_report.hpp:154`](../src/gallery/gallery_report.hpp#L154) — `inline GalleryReport build_gallery_report(const ActorGallery& gallery,`
|
||||
- [`src/gallery/gallery_report.hpp:295`](../src/gallery/gallery_report.hpp#L295) — `inline nlohmann::json gallery_report_to_json(const GalleryReport& r)`
|
||||
- [`src/gallery/gallery_report.hpp:361`](../src/gallery/gallery_report.hpp#L361) — `inline GalleryReport gallery_report_from_json(const nlohmann::json& j)`
|
||||
- [`src/gallery/gallery_report.hpp:446`](../src/gallery/gallery_report.hpp#L446) — `inline void save_gallery_report(const std::string& path, const GalleryReport& r)`
|
||||
- [`src/gallery/gallery_report.hpp:454`](../src/gallery/gallery_report.hpp#L454) — `inline GalleryReport load_gallery_report(const std::string& path)`
|
||||
- [`src/gallery/gallery_report.hpp:464`](../src/gallery/gallery_report.hpp#L464) — `return gallery_report_from_json(j);`
|
||||
|
||||
### GR-004
|
||||
|
||||
**Locations:** 44
|
||||
@@ -381,18 +422,24 @@ _None._
|
||||
- [`scripts/movienet_eval.py:65`](../scripts/movienet_eval.py#L65) — `with open(args.gt) as f:`
|
||||
- [`scripts/optimizer/fetch_missing_actors.py:62`](../scripts/optimizer/fetch_missing_actors.py#L62) — `def fetch(missing_path, out_path, token, build_dir, models_dir, arcface,`
|
||||
- [`scripts/optimizer/fetch_missing_actors.py:109`](../scripts/optimizer/fetch_missing_actors.py#L109) — `def merge(base_path, add_path, out_path):`
|
||||
- [`scripts/optimizer/fetch_missing_actors.py:123`](../scripts/optimizer/fetch_missing_actors.py#L123) — `def merge(base_path, add_path, out_path):`
|
||||
- [`scripts/optimizer/fetch_missing_actors.py:124`](../scripts/optimizer/fetch_missing_actors.py#L124) — `def merge(base_path, add_path, out_path):`
|
||||
- [`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/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:252`](../scripts/optimizer/replay.py#L252) — `Unknown`
|
||||
- [`scripts/sae_embed_loader.py:22`](../scripts/sae_embed_loader.py#L22) — `return arcface if arcface else str(Path(models_dir) / DEFAULT_ARCFACE)`
|
||||
- [`scripts/optimizer/replay.py:253`](../scripts/optimizer/replay.py#L253) — `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_gallery.py:171`](../scripts/sae_gallery.py#L171) — `if not _stamp_empty(embedder):`
|
||||
- [`scripts/sae_gallery.py:199`](../scripts/sae_gallery.py#L199) — `for a in range(len(offset)):`
|
||||
- [`scripts/sae_gallery.py:200`](../scripts/sae_gallery.py#L200) — `for a in range(len(offset)):`
|
||||
- [`scripts/sae_stamp.py:3`](../scripts/sae_stamp.py#L3) — `Unknown`
|
||||
- [`scripts/stamp_gallery.py:4`](../scripts/stamp_gallery.py#L4) — `Unknown`
|
||||
|
||||
### GR-005
|
||||
|
||||
**Locations:** 1
|
||||
|
||||
- [`src/gallery/gallery_store.hpp:15`](../src/gallery/gallery_store.hpp#L15) — `Unknown`
|
||||
|
||||
### IR-001
|
||||
|
||||
**Locations:** 1
|
||||
@@ -417,8 +464,9 @@ _None._
|
||||
|
||||
### IR-004
|
||||
|
||||
**Locations:** 16
|
||||
**Locations:** 18
|
||||
|
||||
- [`src/audio_bindings.cpp:3`](../src/audio_bindings.cpp#L3) — `Unknown`
|
||||
- [`src/audio_signature.cpp:3`](../src/audio_signature.cpp#L3) — `Unknown`
|
||||
- [`src/audio_signature.cpp:265`](../src/audio_signature.cpp#L265) — `std::vector<std::uint8_t> pack_frames(const std::vector<float>& mono)`
|
||||
- [`src/audio_signature.cpp:320`](../src/audio_signature.cpp#L320) — `std::optional<std::string> signature_from_mono(const std::vector<float>& mono)`
|
||||
@@ -435,11 +483,13 @@ _None._
|
||||
- [`tests/test_audio_signature.cpp:314`](../tests/test_audio_signature.cpp#L314) — `kNumBands * std::log10(1000.0 / kBandLoHz) / std::log10(kBandHiHz / kBandLoHz)));`
|
||||
- [`tests/test_audio_signature.cpp:328`](../tests/test_audio_signature.cpp#L328) — `std::vector<float> a(kWindowSamples / 50);`
|
||||
- [`tests/test_audio_signature.cpp:344`](../tests/test_audio_signature.cpp#L344) — `return base64_encode(reinterpret_cast<const std::uint8_t*>(s.data()), s.size());`
|
||||
- [`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`
|
||||
|
||||
### IR-005
|
||||
|
||||
**Locations:** 5
|
||||
**Locations:** 6
|
||||
|
||||
- [`src/audio_bindings.cpp:3`](../src/audio_bindings.cpp#L3) — `Unknown`
|
||||
- [`src/audio_signature.cpp:421`](../src/audio_signature.cpp#L421) — `std::optional<std::string> compute_signature(const std::string& path)`
|
||||
- [`src/audio_signature.hpp:4`](../src/audio_signature.hpp#L4) — `Unknown`
|
||||
- [`tests/test_audio_signature.cpp:3`](../tests/test_audio_signature.cpp#L3) — `Unknown`
|
||||
@@ -485,11 +535,12 @@ _None._
|
||||
|
||||
### PR-002
|
||||
|
||||
**Locations:** 3
|
||||
**Locations:** 4
|
||||
|
||||
- [`src/nodes/embedding_dump_node.hpp:2`](../src/nodes/embedding_dump_node.hpp#L2) — `Unknown`
|
||||
- [`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/validation/ground_truth.py:24`](../scripts/validation/ground_truth.py#L24) — `Unknown`
|
||||
|
||||
### PR-004
|
||||
|
||||
@@ -499,13 +550,26 @@ _None._
|
||||
|
||||
### SR-001
|
||||
|
||||
**Locations:** 47
|
||||
**Locations:** 60
|
||||
|
||||
- [`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/config.hpp:54`](../src/config.hpp#L54) — `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/gallery_builder.cpp:45`](../src/gallery/gallery_builder.cpp#L45) — `ActorGallery build_gallery(const BuildConfig& cfg)`
|
||||
- [`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:294`](../src/gallery/gallery_calibration.hpp#L294) — `Unknown`
|
||||
- [`src/gallery/gallery_report.hpp:2`](../src/gallery/gallery_report.hpp#L2) — `Unknown`
|
||||
- [`src/gallery/gallery_report.hpp:52`](../src/gallery/gallery_report.hpp#L52) — `struct GalleryBuildAudit`
|
||||
- [`src/gallery/gallery_report.hpp:73`](../src/gallery/gallery_report.hpp#L73) — `struct GalleryReport`
|
||||
- [`src/gallery/gallery_report.hpp:154`](../src/gallery/gallery_report.hpp#L154) — `inline GalleryReport build_gallery_report(const ActorGallery& gallery,`
|
||||
- [`src/gallery/gallery_report.hpp:295`](../src/gallery/gallery_report.hpp#L295) — `inline nlohmann::json gallery_report_to_json(const GalleryReport& r)`
|
||||
- [`src/gallery/gallery_report.hpp:361`](../src/gallery/gallery_report.hpp#L361) — `inline GalleryReport gallery_report_from_json(const nlohmann::json& j)`
|
||||
- [`src/gallery/gallery_report.hpp:446`](../src/gallery/gallery_report.hpp#L446) — `inline void save_gallery_report(const std::string& path, const GalleryReport& r)`
|
||||
- [`src/gallery/gallery_report.hpp:454`](../src/gallery/gallery_report.hpp#L454) — `inline GalleryReport load_gallery_report(const std::string& path)`
|
||||
- [`src/gallery/gallery_report.hpp:464`](../src/gallery/gallery_report.hpp#L464) — `return gallery_report_from_json(j);`
|
||||
- [`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:219`](../src/gallery/gallery_store.cpp#L219) — `Unknown`
|
||||
@@ -536,22 +600,22 @@ _None._
|
||||
- [`scripts/movienet_eval.py:65`](../scripts/movienet_eval.py#L65) — `with open(args.gt) as f:`
|
||||
- [`scripts/optimizer/fetch_missing_actors.py:62`](../scripts/optimizer/fetch_missing_actors.py#L62) — `def fetch(missing_path, out_path, token, build_dir, models_dir, arcface,`
|
||||
- [`scripts/optimizer/fetch_missing_actors.py:109`](../scripts/optimizer/fetch_missing_actors.py#L109) — `def merge(base_path, add_path, out_path):`
|
||||
- [`scripts/optimizer/fetch_missing_actors.py:123`](../scripts/optimizer/fetch_missing_actors.py#L123) — `def merge(base_path, add_path, out_path):`
|
||||
- [`scripts/optimizer/fetch_missing_actors.py:124`](../scripts/optimizer/fetch_missing_actors.py#L124) — `def merge(base_path, add_path, out_path):`
|
||||
- [`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/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:252`](../scripts/optimizer/replay.py#L252) — `Unknown`
|
||||
- [`scripts/optimizer/replay.py:253`](../scripts/optimizer/replay.py#L253) — `Unknown`
|
||||
- [`scripts/run_from_jellyfin.py:4`](../scripts/run_from_jellyfin.py#L4) — `Unknown`
|
||||
- [`scripts/sae_embed_loader.py:22`](../scripts/sae_embed_loader.py#L22) — `return arcface if arcface else str(Path(models_dir) / DEFAULT_ARCFACE)`
|
||||
- [`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:199`](../scripts/sae_gallery.py#L199) — `for a in range(len(offset)):`
|
||||
- [`scripts/sae_gallery.py:200`](../scripts/sae_gallery.py#L200) — `for a in range(len(offset)):`
|
||||
- [`scripts/sae_stamp.py:3`](../scripts/sae_stamp.py#L3) — `Unknown`
|
||||
- [`scripts/stamp_gallery.py:4`](../scripts/stamp_gallery.py#L4) — `Unknown`
|
||||
|
||||
### SR-002
|
||||
|
||||
**Locations:** 30
|
||||
**Locations:** 32
|
||||
|
||||
- [`src/config.hpp:44`](../src/config.hpp#L44) — `Unknown`
|
||||
- [`src/config.hpp:108`](../src/config.hpp#L108) — `Unknown`
|
||||
@@ -566,13 +630,15 @@ _None._
|
||||
- [`src/main.cpp:309`](../src/main.cpp#L309) — `Unknown`
|
||||
- [`src/main.cpp:379`](../src/main.cpp#L379) — `return run_net(std::move(net));`
|
||||
- [`src/main.cpp:411`](../src/main.cpp#L411) — `Unknown`
|
||||
- [`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/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_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:125`](../src/nodes/identity_matcher_node.hpp#L125) — `const GalleryCalibration& calibration() const { return cal_; }`
|
||||
- [`src/nodes/identity_matcher_node.hpp:155`](../src/nodes/identity_matcher_node.hpp#L155) — `std::vector<float> host_query(static_cast<size_t>(kMaxFaces) * 512);`
|
||||
- [`src/nodes/identity_matcher_node.hpp:261`](../src/nodes/identity_matcher_node.hpp#L261) — `Unknown`
|
||||
- [`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:272`](../src/nodes/identity_matcher_node.hpp#L272) — `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: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; };`
|
||||
@@ -586,8 +652,9 @@ _None._
|
||||
|
||||
### SR-003
|
||||
|
||||
**Locations:** 6
|
||||
**Locations:** 7
|
||||
|
||||
- [`src/audio_bindings.cpp:3`](../src/audio_bindings.cpp#L3) — `Unknown`
|
||||
- [`src/audio_signature.cpp:3`](../src/audio_signature.cpp#L3) — `Unknown`
|
||||
- [`src/audio_signature.hpp:4`](../src/audio_signature.hpp#L4) — `Unknown`
|
||||
- [`src/config.hpp:20`](../src/config.hpp#L20) — `struct Config`
|
||||
@@ -597,12 +664,16 @@ _None._
|
||||
|
||||
### SR-005
|
||||
|
||||
**Locations:** 5
|
||||
**Locations:** 9
|
||||
|
||||
- [`src/config.hpp:152`](../src/config.hpp#L152) — `Unknown`
|
||||
- [`src/gallery/gallery_store.hpp:15`](../src/gallery/gallery_store.hpp#L15) — `Unknown`
|
||||
- [`src/gallery/track_gallery.hpp:122`](../src/gallery/track_gallery.hpp#L122) — `void forget(int track_id) { tracks_.erase(track_id); }`
|
||||
- [`src/gallery/track_gallery.hpp:150`](../src/gallery/track_gallery.hpp#L150) — `struct TrackState`
|
||||
- [`src/gallery/track_gallery.hpp:132`](../src/gallery/track_gallery.hpp#L132) — `void set_calibration(std::function<float(float)> c) { calibrate_ = std::move(c); }`
|
||||
- [`src/gallery/track_gallery.hpp:161`](../src/gallery/track_gallery.hpp#L161) — `struct TrackState`
|
||||
- [`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:147`](../src/nodes/identity_matcher_node.hpp#L147) — `MatchedSceneFrame operator()(TrackedSceneFrame tf)`
|
||||
- [`src/nodes/identity_matcher_node.hpp:285`](../src/nodes/identity_matcher_node.hpp#L285) — `Unknown`
|
||||
- [`scripts/make_jellyfin_gallery.py:4`](../scripts/make_jellyfin_gallery.py#L4) — `Unknown`
|
||||
|
||||
### UT-001
|
||||
@@ -648,6 +719,30 @@ _None._
|
||||
- [`tests/test_audio_signature.cpp:328`](../tests/test_audio_signature.cpp#L328) — `std::vector<float> a(kWindowSamples / 50);`
|
||||
- [`tests/test_audio_signature.cpp:344`](../tests/test_audio_signature.cpp#L344) — `return base64_encode(reinterpret_cast<const std::uint8_t*>(s.data()), s.size());`
|
||||
|
||||
### UT-105
|
||||
|
||||
**Locations:** 1
|
||||
|
||||
- [`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-106
|
||||
|
||||
**Locations:** 1
|
||||
|
||||
- [`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-107
|
||||
|
||||
**Locations:** 1
|
||||
|
||||
- [`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-108
|
||||
|
||||
**Locations:** 1
|
||||
|
||||
- [`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-001
|
||||
|
||||
**Locations:** 2
|
||||
@@ -668,28 +763,15 @@ _None._
|
||||
|
||||
- [`scripts/optimizer/second_score.py:5`](../scripts/optimizer/second_score.py#L5) — `Unknown`
|
||||
|
||||
## Tag diagnostics
|
||||
### VR-004
|
||||
|
||||
**Malformed tags:**
|
||||
**Locations:** 1
|
||||
|
||||
- `scripts/filter_gallery.py:80` — {'ignored': ['— a filtered gallery holds the SAME vectors as its']}
|
||||
- `scripts/make_gallery.py:181` — {'ignored': ['— stamp with the model actually loaded', 'resolved']}
|
||||
- `scripts/make_jellyfin_gallery.py:456` — {'ignored': ["— --merge keeps the existing actors' vectors and"]}
|
||||
- `scripts/movienet_eval.py:65` — {'ignored': ['— match() below is a bare dot product against the']}
|
||||
- `scripts/optimizer/fetch_missing_actors.py:109` — {'ignored': ['— the legacy JSON gallery carries the same stamp as']}
|
||||
- `scripts/optimizer/fetch_missing_actors.py:123` — {'ignored': ['— merging two galleries from different models makes']}
|
||||
- `scripts/optimizer/optimize.py:202` — {'ignored': ['— every (dump', 'gallery) pair is checked ONCE here']}
|
||||
- `scripts/optimizer/reembed_gallery.py:62` — {'ignored': ['— this script exists to produce a gallery in a']}
|
||||
- `scripts/optimizer/replay.py:113` — {'ignored': ['— checked here', 'before any network is built', 'so a']}
|
||||
- `scripts/optimizer/replay.py:252` — {'ignored': ['— promote an unprovable gallery/dump binding from a']}
|
||||
- `scripts/sae_embed_loader.py:22` — {'ignored': ['— single source of truth for "which model is this"']}
|
||||
- `scripts/sae_gallery.py:171` — {'ignored': ['— omitted entirely when unknown', 'so "unstamped"']}
|
||||
- `scripts/sae_gallery.py:199` — {'ignored': ['— carried through so a derived gallery (filter']}
|
||||
- [`scripts/validation/ground_truth.py:24`](../scripts/validation/ground_truth.py#L24) — `Unknown`
|
||||
|
||||
**Groups mixing requirement types (pipe separates types):**
|
||||
### VR-014
|
||||
|
||||
- `src/main.cpp:230` — {'group': ['AR-012', 'AR-016', 'IR-002', 'IR-003']}
|
||||
- `src/nodes/result_sink_node.hpp:49` — {'group': ['AR-012', 'AR-017', 'IR-002']}
|
||||
- `src/nodes/result_sink_node.hpp:161` — {'group': ['AR-012', 'IR-002']}
|
||||
- `tests/test_replay_fixtures.cpp:3` — {'group': ['AR-012', 'AR-013', 'AR-004', 'VR-001', 'VR-002']}
|
||||
**Locations:** 1
|
||||
|
||||
- [`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`
|
||||
|
||||
|
||||
Reference in New Issue
Block a user