Order bbox corners, and find the ground truth is for another manga

`_bbox_to_pixels` sorts each coordinate pair after clamping. Run B returned
`p007 person_1` as `[226, 417, 130, 551]`, x1 > x2, which cropped to nothing
and lost that detection silently. The third GPU cycle came back with 0
degenerate boxes over 119 detections.

The plan's first item cannot run as written. All 145 rows of `identity_labels`
belong to chapter 8ca8249b, a different manga. Chapter 7c944dd4 has none, so
`/review/identity` reports `accuracy: null`. Scoring 8ca8249b gives 7/138 on
an identity run that predates every fix.

The cycle also settled the coverage question. All 68 assignments landed on
face-bearing detections and none on a gated one, so recall among face-bearing
detections is 96%, up from 82%. Coverage is the `has_face` gate and nothing
else. What is now open is precision: the lead holds 36 of 68 assignments.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-12 22:21:52 +04:00
parent 18b49c43bd
commit 54bd126cd7
8 changed files with 211 additions and 180 deletions
+1
View File
@@ -47,3 +47,4 @@ still live belongs in `caveats/`.
| [The extras gate runs at enrollment and at narration, not at the speaker prompt](identity-bbox.md#extras-gate-consumers) | closed |
| [A roster name is a guess, so it never reaches detection](identity-bbox.md#roster-does-not-name) | closed |
| [`merged_into` is exactly one hop deep](identity-bbox.md#merge-chains-flatten) | closed |
| [`_bbox_to_pixels` orders the corners, because the model sometimes swaps them](identity-bbox.md#bbox-corners-ordered) | closed |
+22
View File
@@ -221,3 +221,25 @@ Two rules, one per direction, and both are needed:
The keeper walk alone is not enough, which the 17:38 run proved by producing
`477c1894 -> a92d9df4 -> 4fb94c15` with the walk deployed. At merge time that pair was fine. The chain
formed later, when a row that was already somebody's keeper was itself retired.
## `_bbox_to_pixels` orders the corners, because the model sometimes swaps them {#bbox-corners-ordered}
**Closed, 2026-08-12.**
The 17:38 run returned `p007 person_1` as `[226, 417, 130, 551]`, x1 greater than x2. One detection in 117.
Clamping each coordinate into the panel kept the swap, so the box stayed a negative-width region. It
cropped to nothing, so that detection could not enroll, embed or match, and nothing reported the loss.
`_bbox_to_pixels` now sorts each pair after clamping:
```python
xs = sorted((clamped_x1, clamped_x2))
ys = sorted((clamped_y1, clamped_y2))
c["bbox"] = [xs[0], ys[0], xs[1], ys[1]]
```
Sorting is enough. A zero-area box still crops to nothing, and no consumer needs a minimum size that it
does not already enforce. The self-check feeds the real swapped box in and asserts `[117, 688, 203, 909]`,
which fails without the sort.
Proven on the 18:07 run: 0 degenerate boxes over 119 detections.