feat(perception): freeze blind detector gates
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
# LAB E45 · RAVNOVES00 binding sensitivity
|
||||
|
||||
Date: 2026-07-29
|
||||
|
||||
Status: accepted diagnostic measurement only
|
||||
|
||||
Immutable result:
|
||||
`e45-binding-sensitivity-b10fa117f110d5ac7942f73c62f1300c7d9ce833a187542b992e58fb24d1be72`
|
||||
|
||||
## Task
|
||||
|
||||
E31 accepted zero recorded-host-arrival offset for all 87 evidenced
|
||||
camera↔LiDAR correspondences, but its residual is a support-centroid location
|
||||
inside a reviewed detector box. It is not a calibration-target measurement.
|
||||
E45 asks whether that already accepted diagnostic residual visibly degrades
|
||||
with fisheye radius, rig motion, LiDAR↔camera age, or pose↔point age.
|
||||
|
||||
E45 does not:
|
||||
|
||||
- re-run projection or inference;
|
||||
- change E31 thresholds or the selected offset;
|
||||
- infer hardware firing time;
|
||||
- infer vehicle body or physical mount dimensions;
|
||||
- rename a detector-box residual as calibration truth.
|
||||
|
||||
## Immutable inputs
|
||||
|
||||
- RAVNOVES00 session `20260720T065719Z_viewer_live`;
|
||||
- E10 LiDAR pack
|
||||
`e10-lidar-pack-576c994a6c814e2592dd6240ace3902a5db94843312c759a73ba0c9166157d2b`;
|
||||
- accepted E31
|
||||
`e31-source-qualification-b2460a5eb143688c7eea6821b2277e13aea79868abe81d83f7e78548c119159a`;
|
||||
- E30 materialization
|
||||
`e30-materialization-841af926d8d28ab93538c46d8f31278a2234c4d1c12c7dc4dc296b249d59735a`;
|
||||
- factory calibration identity
|
||||
`05f3ad9b38b3a4fc95388a8ec83da83c745e217709e51787b3d5aad0969f6fa9`;
|
||||
- right camera, `camera_1`, KB4, 800×600.
|
||||
|
||||
## Method
|
||||
|
||||
For every accepted E31 correspondence, E45 joins the zero-offset score with:
|
||||
|
||||
- normalized detector-box-centre radius from the 800×600 image centre;
|
||||
- centred translational speed from adjacent valid recorded poses;
|
||||
- centred quaternion angular speed from adjacent valid recorded poses;
|
||||
- absolute LiDAR↔camera host-arrival age;
|
||||
- absolute pose↔point host-arrival age;
|
||||
- translation and rotation exposure proxies over the combined source age.
|
||||
|
||||
The 561 unavailable E10 LiDAR/pose rows remain unavailable. They are neither
|
||||
interpolated nor replaced. Motion is evaluated only between adjacent valid
|
||||
pose rows. Every derived row preserves the exact E31 item and source frame
|
||||
identity.
|
||||
|
||||
The frozen E45 profile uses descriptive low/middle/high strata. Correlations
|
||||
are Spearman rank coefficients against the existing
|
||||
`centroid_residual_bbox_diagonal`. They are diagnostic associations, not
|
||||
causal calibration-error estimates.
|
||||
|
||||
## Result
|
||||
|
||||
Evidence accounting closes at 87/87 rows. All 87 retain at least two occupied
|
||||
points in their reviewed box.
|
||||
|
||||
| Measurement | Value |
|
||||
| --- | ---: |
|
||||
| Support fraction | 1.000 |
|
||||
| Residual p50 | 0.22045 bbox diagonal |
|
||||
| Residual p95 | 0.39466 bbox diagonal |
|
||||
| Occupied support p50 | 6 points |
|
||||
| Occupied support p95 | 57 points |
|
||||
| Image radius max | 0.72639 normalized |
|
||||
| Translation speed p50 / p95 | 1.325 / 2.709 m/s |
|
||||
| Angular speed p50 / p95 | 13.941 / 34.579 deg/s |
|
||||
| LiDAR↔camera age p50 / p95 | 22.633 / 81.594 ms |
|
||||
| Pose↔point age p50 / p95 | 6.060 / 16.829 ms |
|
||||
| Translation exposure p50 / p95 | 0.0383 / 0.1159 m |
|
||||
| Rotation exposure p50 / p95 | 0.4157 / 1.3000 deg |
|
||||
|
||||
Residual correlations are small:
|
||||
|
||||
| Variable | Spearman ρ |
|
||||
| --- | ---: |
|
||||
| Image radius | +0.0421 |
|
||||
| Translation speed | +0.0076 |
|
||||
| Angular speed | −0.0669 |
|
||||
| LiDAR↔camera age | +0.1016 |
|
||||
| Pose↔point age | −0.0181 |
|
||||
| Translation exposure | +0.0051 |
|
||||
| Rotation exposure | −0.0312 |
|
||||
|
||||
The high LiDAR↔camera-age stratum contains 12 correspondences and still closes
|
||||
12/12 support. The high translation-speed stratum contains 57 and closes
|
||||
57/57. The high angular-speed stratum contains 48 and closes 48/48.
|
||||
|
||||
The image-radius high stratum is empty. The accepted E31 correspondence set
|
||||
does not test the outer KB4 fisheye belt beyond normalized radius `0.85`.
|
||||
|
||||
## Failed attempt retained as implementation evidence
|
||||
|
||||
The first bounded E45 execution failed closed because the source pack contains
|
||||
561 deliberately unavailable LiDAR/pose rows with non-finite pose arrays. The
|
||||
initial implementation incorrectly required finite pose values for all 4,489
|
||||
camera rows. The implementation was corrected to derive motion only between
|
||||
adjacent valid pose rows. No missing pose was interpolated and no E31 input was
|
||||
changed.
|
||||
|
||||
The successful local run completed in 0.74 seconds. Maximum RSS was
|
||||
249,446,400 bytes and peak memory footprint was 213,025,728 bytes. No Docker
|
||||
container, Worker 006 job, model, video decode, network change, or second
|
||||
Mission Core service was started.
|
||||
|
||||
## Decision
|
||||
|
||||
The accepted E31 zero-offset source binding is retained unchanged. E45 finds
|
||||
no material monotonic relationship between the existing detector-box
|
||||
support-centroid residual and the measured motion/age/radius variables inside
|
||||
the represented source envelope.
|
||||
|
||||
This result does not close calibrated-perception P0:
|
||||
|
||||
- measured static-landmark or calibration-target reprojection error remains
|
||||
unavailable;
|
||||
- the outer fisheye belt is not represented;
|
||||
- physical mount/body dimensions remain unavailable;
|
||||
- hardware firing time remains unavailable;
|
||||
- cross-route or changed-mount transfer remains unproved.
|
||||
|
||||
The next detector-quality gate is an independent Truth Island with no model
|
||||
prelabels exposed to reviewers and with prediction frozen before labels are
|
||||
revealed. A later physical calibration-target capture can close the remaining
|
||||
P0 measurement, but E45 does not fabricate it from RAVNOVES00.
|
||||
|
||||
Navigation, safety and command authority remain false.
|
||||
@@ -0,0 +1,95 @@
|
||||
# LAB E46 · RAVNOVES00 detector Truth Island preparation
|
||||
|
||||
Date: 2026-07-29
|
||||
|
||||
Status: prepared; awaiting two independent human reviews
|
||||
|
||||
Immutable result:
|
||||
`e46-detector-truth-island-d8ab2745679636dce374b720b562fce05d6d0a26be3eac88650224d7aa92267d`
|
||||
|
||||
## Task
|
||||
|
||||
E46 prepares a small, bounded and reviewable detector Truth Island on the
|
||||
known RAVNOVES00 right-camera source. It breaks the circular evaluation pattern
|
||||
identified by E41: reviewers receive source-image references and an empty
|
||||
annotation template, while model prelabels, predictions, scores and candidate
|
||||
identities stay outside the review package.
|
||||
|
||||
E46 does not yet create truth, calculate accuracy or select a detector.
|
||||
|
||||
## Immutable input
|
||||
|
||||
- E2 evaluation pack
|
||||
`evaluation-pack-7a983bba75d46c7c260252cb2d461e1384dcb92cda9e164397e841e6ebb37789`;
|
||||
- source job `recorded-camera-602ac89026ed12978619801d`;
|
||||
- source input SHA-256
|
||||
`602ac89026ed12978619801d4edea0cae24b5cc3afabd9f7af2858de6505a20e`;
|
||||
- session `20260720T065719Z_viewer_live`;
|
||||
- right camera, `camera_1`, KB4, 800×600;
|
||||
- fixed valid-FOV-fill preprocessing identity retained only as source
|
||||
provenance, not shown as a model hint.
|
||||
|
||||
## Frozen selection
|
||||
|
||||
The deterministic profile selects 32 frames:
|
||||
|
||||
- 16 anchors: two from each of eight route-time bins;
|
||||
- 16 temporal frames: all four frames from each of four existing temporal
|
||||
groups;
|
||||
- source frame range: 70–4436;
|
||||
- referenced source image bytes: 14,919,621;
|
||||
- copied source images: zero.
|
||||
|
||||
The four temporal groups are:
|
||||
|
||||
- `clip-close-car`;
|
||||
- `clip-near-structure`;
|
||||
- `clip-stroller-person`;
|
||||
- `clip-vehicle-occlusion`.
|
||||
|
||||
The package is content-addressed through
|
||||
`image-references.jsonl`. Every reference retains source path, byte length,
|
||||
file SHA-256 and pixel SHA-256.
|
||||
|
||||
## Review contract
|
||||
|
||||
Two different human reviewers must independently annotate all identifiable
|
||||
instances inside the valid camera field of view. The target classes are
|
||||
`person`, `bicycle`, `motorcycle`, `car`, `heavy_vehicle`,
|
||||
`static_obstacle` and `animal`. Hard-negative status plus occlusion and
|
||||
truncation flags are required. Disagreements require adjudication.
|
||||
|
||||
Neither reviewer may see:
|
||||
|
||||
- model prelabels;
|
||||
- model predictions or scores;
|
||||
- candidate identity;
|
||||
- candidate comparison results.
|
||||
|
||||
Prediction must be frozen before labels are revealed. E47 performs that freeze
|
||||
in a separate immutable result.
|
||||
|
||||
## Result and resource boundary
|
||||
|
||||
The package contains 32/32 valid references, an empty review template, the
|
||||
blind contract and a preparation report. Its state is
|
||||
`prepared-awaiting-independent-human-review`; truth remains unavailable and
|
||||
candidate comparison remains unauthorized.
|
||||
|
||||
The local preparation completed in 0.54 seconds. Maximum RSS was 102,596,608
|
||||
bytes and peak memory footprint was 64,406,344 bytes. No Docker container,
|
||||
Worker 006 job, model inference, image copy, network mutation or second Mission
|
||||
Core service was started.
|
||||
|
||||
## Decision
|
||||
|
||||
Truth Island preparation is complete, but the island is not sealed. The next
|
||||
manual gate is two independent reviews followed by adjudication. Only the
|
||||
sealed adjudicated labels may be joined with the already-frozen E47
|
||||
predictions.
|
||||
|
||||
This is still same-source truth on RAVNOVES00, not cross-route validation.
|
||||
E38–E40 source-trained candidates remain ineligible for this gate because the
|
||||
source already contains dense engineering labels.
|
||||
|
||||
Navigation, safety and command authority remain false.
|
||||
@@ -0,0 +1,72 @@
|
||||
# LAB E47 · detector candidate freeze before truth reveal
|
||||
|
||||
Date: 2026-07-29
|
||||
|
||||
Status: predictions frozen; awaiting E46 truth seal
|
||||
|
||||
Immutable result:
|
||||
`e47-detector-candidate-freeze-514bcca7a8a26313cab5ffcacca053d7a0ec6fe7cbef25f15faf3a11e48ee92f`
|
||||
|
||||
## Task
|
||||
|
||||
E47 freezes two detector prediction candidates for the exact 32 E46 frames
|
||||
before either independent review is revealed. This makes the later
|
||||
raw-versus-calibrated-preprocessing comparison reproducible and prevents
|
||||
post-label tuning.
|
||||
|
||||
E47 deliberately computes no accuracy metric and selects no winner.
|
||||
|
||||
## Candidates
|
||||
|
||||
Both candidates use the same exact generic Mask R-CNN checkpoint:
|
||||
`73cbd0190fcbe3ba339921fbce2c3a0b6bb9126c9a133c85e43a2a8e060a109e`.
|
||||
The only intended comparison variable is camera preprocessing:
|
||||
|
||||
| Candidate | Input profile | Admitted boxes | Frames |
|
||||
| --- | --- | ---: | ---: |
|
||||
| `maskrcnn-kb4-raw` | raw KB4 800×600 | 417 | 32 |
|
||||
| `maskrcnn-kb4-valid-fov-fill` | fixed valid-FOV fill 800×600 | 394 | 32 |
|
||||
|
||||
The raw candidate contained 432 source instances. Fifteen categories outside
|
||||
the frozen task ontology were ignored, leaving 417 admitted predictions. The
|
||||
valid-FOV-fill candidate contained and admitted 394 predictions. Both
|
||||
candidates produced at least one admitted prediction for every selected frame.
|
||||
|
||||
These counts are descriptive only. Fewer or more boxes do not imply better
|
||||
accuracy.
|
||||
|
||||
## Frozen output
|
||||
|
||||
E47 writes 64 content-addressed prediction rows: one row for each candidate and
|
||||
E46 image. The combined prediction row digest is
|
||||
`0aec660d33c002b3e0578841b09e9bbb25e15c425b2428ebbf5a1957d23371fa`.
|
||||
Every row retains the E46 sequence and source-image digest while excluding
|
||||
truth and review fields.
|
||||
|
||||
The E46 reviewer package is not modified. The result records:
|
||||
|
||||
- truth labels unavailable;
|
||||
- no truth join performed;
|
||||
- accuracy metrics unavailable;
|
||||
- no candidate winner;
|
||||
- model retraining unauthorized.
|
||||
|
||||
## Resource boundary
|
||||
|
||||
The local freeze completed in 0.51 seconds. Maximum RSS was 105,103,360 bytes
|
||||
and peak memory footprint was 67,634,016 bytes. It reused existing immutable
|
||||
prediction artifacts; no model inference, video decode, Docker container,
|
||||
Worker 006 job, network mutation or second Mission Core service was started.
|
||||
|
||||
## Decision
|
||||
|
||||
The two preprocessing candidates are now frozen before label reveal. The next
|
||||
gate is to complete and adjudicate both E46 reviews, seal the resulting truth,
|
||||
then compute COCO AP/AR, per-class recall, person/vehicle miss rate,
|
||||
false-large-box rate, valid-FOV boundary leakage and temporal flicker.
|
||||
|
||||
Until that gate, neither candidate is preferred and no detector-quality claim
|
||||
is made. The result remains source-scoped to the known RAVNOVES00 right camera
|
||||
and cannot establish cross-route generalization.
|
||||
|
||||
Navigation, safety and command authority remain false.
|
||||
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Build the source-scoped E45 binding sensitivity audit."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from k1link.compute.e45_binding_sensitivity import (
|
||||
build_e45_binding_sensitivity,
|
||||
)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--e31-result-root", type=Path, required=True)
|
||||
parser.add_argument("--source-pack-root", type=Path, required=True)
|
||||
parser.add_argument("--materialization-root", type=Path, required=True)
|
||||
parser.add_argument("--output-root", type=Path, required=True)
|
||||
args = parser.parse_args()
|
||||
result = build_e45_binding_sensitivity(
|
||||
e31_result_root=args.e31_result_root,
|
||||
source_pack_root=args.source_pack_root,
|
||||
materialization_root=args.materialization_root,
|
||||
output_root=args.output_root,
|
||||
)
|
||||
print(
|
||||
json.dumps(
|
||||
{
|
||||
"result_id": result.result_id,
|
||||
"result_root": str(result.result_root),
|
||||
"analysis": result.report["analysis"],
|
||||
"decision": result.report["decision"],
|
||||
},
|
||||
ensure_ascii=False,
|
||||
sort_keys=True,
|
||||
)
|
||||
)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Prepare the references-only E46 detector Truth Island."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from k1link.compute.e46_detector_truth_island import (
|
||||
build_e46_detector_truth_island,
|
||||
)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--evaluation-pack-root", type=Path, required=True)
|
||||
parser.add_argument("--output-root", type=Path, required=True)
|
||||
args = parser.parse_args()
|
||||
result = build_e46_detector_truth_island(
|
||||
evaluation_pack_root=args.evaluation_pack_root,
|
||||
output_root=args.output_root,
|
||||
)
|
||||
print(
|
||||
json.dumps(
|
||||
{
|
||||
"result_id": result.result_id,
|
||||
"result_root": str(result.result_root),
|
||||
"status": result.report["status"],
|
||||
"selection": result.report["selection"],
|
||||
"blindness": result.report["blindness"],
|
||||
},
|
||||
ensure_ascii=False,
|
||||
sort_keys=True,
|
||||
)
|
||||
)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Freeze E47 detector candidates before E46 truth reveal."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from k1link.compute.e47_detector_candidate_freeze import (
|
||||
build_e47_detector_candidate_freeze,
|
||||
)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--truth-island-root", type=Path, required=True)
|
||||
parser.add_argument("--raw-result-root", type=Path, required=True)
|
||||
parser.add_argument("--valid-fov-result-root", type=Path, required=True)
|
||||
parser.add_argument("--output-root", type=Path, required=True)
|
||||
args = parser.parse_args()
|
||||
result = build_e47_detector_candidate_freeze(
|
||||
truth_island_root=args.truth_island_root,
|
||||
raw_result_root=args.raw_result_root,
|
||||
valid_fov_result_root=args.valid_fov_result_root,
|
||||
output_root=args.output_root,
|
||||
)
|
||||
report = result["report"]
|
||||
print(
|
||||
json.dumps(
|
||||
{
|
||||
"result_id": result["result_id"],
|
||||
"result_root": str(result["result_root"]),
|
||||
"status": report["status"],
|
||||
"candidates": report["candidates"],
|
||||
"blindness": report["blindness"],
|
||||
},
|
||||
ensure_ascii=False,
|
||||
sort_keys=True,
|
||||
)
|
||||
)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user