From b98372bad8128c0ebcf104c2dcba36787f19777e Mon Sep 17 00:00:00 2001 From: Duncan Tourolle Date: Fri, 31 Jul 2026 10:29:53 +0200 Subject: [PATCH] docs: AR-004 is a KPN change, with the measurement behind it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Backpressure cannot be implemented in this repository. Every node output in KPN uses the dropping push() (pool_node.hpp:404 and :710, plus branch, fanout and interrupt_node). A lossless push_blocking() already exists on both Channel and OutputPort — "wait for the consumer to drain instead of dropping; the producer just runs slower" — and nothing calls it. The fix is a per-channel policy or a network default in KPN, and this pipeline should select lossless: a dropped frame here does not degrade a result, it silently changes one. Measured rather than inferred. One 77s clip at 5 fps should yield ~385 sampled frames. On CPU it produced 49, ending at 51s, with 285 dropped at camera_pos and 51 at face_aligner. Rebuilt with CUDA the same clip ran in 29s and reached EOF correctly, and still dropped 320 at camera_pos, yielding 65. Faster hardware moves where the queue backs up; it does not change what happens when it does — which is why this is a correctness requirement rather than a throughput one. Raising channel capacity is therefore a stopgap: it lowers the probability of overflow without changing the behaviour on overflow, and the failure it hides is silent corruption of the output. Co-Authored-By: Claude Opus 5 TRACES: AR-003, AR-004, VR-001 | SR-002 --- docs/SPEC.md | 34 ++++++++++++++++++++++++++++++++-- docs/requirements.md | 2 +- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/docs/SPEC.md b/docs/SPEC.md index 8a6da1b..1ab5a20 100644 --- a/docs/SPEC.md +++ b/docs/SPEC.md @@ -80,8 +80,38 @@ by dropping work or growing without limit. - Memory is the real limit: faces carry 112×112 crops plus 512-float embeddings. Backpressure must engage on bytes in flight, not just item counts. -**Gap:** entire requirement. This is a prerequisite for removing `max_faces`, not -a follow-up to it. +### The fix is not in this repo + +**Every node output in KPN uses the dropping `push()`** (`pool_node.hpp:404`, +`:710`; also `branch.hpp`, `fanout.hpp`, `interrupt_node.hpp`). A lossless +`push_blocking()` — "wait for the consumer to drain instead of dropping; the +producer just runs slower" — already exists on both `Channel` +(`channel.hpp:144`) and `OutputPort` (`variant_node.hpp:81`), **and nothing +calls it.** + +So AR-004 is a change to the KPN repository, not to this one. It needs either a +per-channel lossless policy or a network-wide default, and this pipeline should +select lossless: a dropped frame here does not degrade a result, it silently +changes one. + +**Measured, not inferred.** One 77 s clip at 5 fps should yield ~385 sampled +frames. On CPU it produced 49, ending at 51 s, with 285 frames dropped at +`camera_pos` and 51 at `face_aligner`. Rebuilt with CUDA the same clip ran in +29 s and reached EOF correctly — and still dropped **320** frames at +`camera_pos`, yielding 65. Faster hardware moves where the queue backs up; it +does not change what happens when it does. + +Two consequences worth stating: + +- **Raising channel capacity is a stopgap, not a fix.** It lowers the + probability of overflow without changing the behaviour on overflow, and the + failure it hides is silent corruption of the output. +- **Fixture generation is blocked on this** (VR-001), because what gets dropped + depends on timing. The same command run twice can produce different dumps, and + a golden fixture cannot be built on that. + +**Gap:** entire requirement, and it is **cross-repo** — the drop-versus-block +decision lives in KPN. Removing `max_faces` (AR-003) remains gated on it. ## AR-005 — Face alignment and crop diff --git a/docs/requirements.md b/docs/requirements.md index 386a2d7..cbae3d6 100644 --- a/docs/requirements.md +++ b/docs/requirements.md @@ -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-002 | Minimum face size **32×32 px** (VR-005 measured), 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 | Planned | -| AR-004 | Backpressure: unbounded faces/frame absorbed by slowing, never by dropping or throwing | SR-002 | High | Planned | +| AR-004 | Backpressure: unbounded faces/frame absorbed by slowing, never by dropping or throwing | SR-002 | High | **Blocked — cross-repo.** Every KPN node output uses the dropping `push()`; `push_blocking()` exists but is never called. Needs a KPN change | | AR-005 | Align to 112×112 via ArcFace 5-point similarity transform | 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 |