From b9e4309842878a6bfe85d25a65d1e6c6d4bda1a6 Mon Sep 17 00:00:00 2001 From: fy59 Date: Thu, 3 Sep 2026 06:44:50 +0200 Subject: [PATCH] fix: align calibration tooling with science v1 --- README.md | 12 +- docs/README.md | 6 +- .../calibration_solver_preflight_v1.md | 20 ++++ docs/architecture/calibration_tooling.md | 103 ++++++++++++++++++ docs/roadmap/roadmap.md | 50 ++++++--- include/lardon3d/calibration_tooling.h | 6 + prompt/02_CURRENT_FROZEN_STATE.md | 4 +- prompt/12_CALIBRATION.md | 19 +++- prompt/31_IMPLEMENTATION_ORDER.md | 4 +- src/calibration_tooling.c | 2 +- tests/test_calibration_tooling.c | 3 +- 11 files changed, 201 insertions(+), 28 deletions(-) create mode 100644 docs/architecture/calibration_tooling.md diff --git a/README.md b/README.md index f71090a..22e9a55 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,8 @@ The following major foundations are implemented and validated at their documente - **Calibration Science v1 — PASS / FROZEN** - **Calibration Tooling v1 — PASS / FROZEN** - **Calibration Solver Preflight v1 — PASS** +- **Calibration Evidence Solver v1 — IMPLEMENTED / VALIDATED** +- **Calibration Tooling planarity alignment — PASS / FROZEN** - **Project DB v24/v25 operational overlays — IMPLEMENTED / VALIDATED** - raw.develop.batch/1 durable selected-execution path - features.extract.batch/1 durable selected-execution path @@ -188,9 +190,13 @@ BLOCKED_BY_KNOWN_CALIBRATION_DATA ``` Calibration Science v1 defines the protocol for future physically controlled calibration -acquisitions. Calibration Tooling v1 validates an already acquired Science v1 evidence bundle and -produces the bounded L3DCALB1 artifact; Calibration Bootstrap v1 imports that artifact. Neither -stage solves calibration internally or turns EXIF into scientific calibration. +acquisitions. The external Calibration Evidence Solver v1 implements the qualified OpenCV 5.x +evidence path. Calibration Tooling v1 validates bounded Science v1 evidence and produces the +L3DCALB1 artifact; Calibration Bootstrap v1 imports that artifact. None of these stages turns EXIF +into scientific calibration. + +The current missing product boundary is the workflow coordinator that binds the immutable physical +session and solver bundle to one exact selected execution and drives Tooling/Bootstrap to `READY`. ## Architecture diff --git a/docs/README.md b/docs/README.md index 97a104a..966abf9 100644 --- a/docs/README.md +++ b/docs/README.md @@ -10,7 +10,8 @@ CURRENT_PRODUCTION_TASK_KINDS=16 REAL_S21_TRACKS=PASS/FROZEN REAL_A6000_PRE_SFM=PASS/FROZEN PRODUCT_DEFINITION_V1=PASS/FROZEN -PROMPT_TREE=NEXT +PROMPT_TREE=CURRENT +CURRENT_NEXT=CALIBRATION_WORKFLOW_COORDINATOR ``` This index separates current authority, historical evidence and future product-definition work. @@ -147,6 +148,7 @@ Historical verifier results are never relabelled. ## Calibration - [Calibration Science v1](architecture/calibration_science_v1.md) +- [Calibration Tooling v1](architecture/calibration_tooling.md) - [Calibration Bootstrap v1](architecture/calibration_bootstrap.md) - [Calibration Solver Preflight v1](architecture/calibration_solver_preflight_v1.md) @@ -212,7 +214,7 @@ Canonical target-product authority: ```text PRODUCT_DEFINITION_V1=PASS/FROZEN IMPLEMENTATION_AUTHORIZATION=NO -PROMPT_TREE=NEXT +PROMPT_TREE=CURRENT ``` The product definition freezes desired end-product behavior without reopening existing FROZEN diff --git a/docs/architecture/calibration_solver_preflight_v1.md b/docs/architecture/calibration_solver_preflight_v1.md index f39de8e..fbac1be 100644 --- a/docs/architecture/calibration_solver_preflight_v1.md +++ b/docs/architecture/calibration_solver_preflight_v1.md @@ -124,3 +124,23 @@ optique, acquérir au moins 40 vues, hacher, résoudre trois fois, vérifier Science v1, passer le bundle à Calibration Tooling dans un projet dédié et vérifier `CALIBRATION → READY`. La preuve s'arrête avant Sparse SfM ; S21 ne participe jamais. + +## Current lifecycle update + +The preflight decision above has now been implemented. + +```text +CALIBRATION_EVIDENCE_SOLVER_V1=IMPLEMENTED/VALIDATED +``` + +`tools/calibration_evidence_solver/` contains the external OpenCV 5.x solver selected by this +preflight. Its deterministic synthetic CPU1 self-test passes. It remains external to Lardon3D +runtime linkage and Project DB mutation. + +The current missing implementation boundary is no longer the solver. It is the higher-level +calibration workflow coordinator that binds an immutable physical session plus the complete solver +bundle to the exact selected execution, constructs `Lardon3DCalibrationToolingEvidence`, invokes the +frozen Tooling/Bootstrap path and reaches `READY` without manufacturing evidence. + +The original preflight text is retained as decision history; this section owns its later lifecycle +status. diff --git a/docs/architecture/calibration_tooling.md b/docs/architecture/calibration_tooling.md new file mode 100644 index 0000000..9a5b771 --- /dev/null +++ b/docs/architecture/calibration_tooling.md @@ -0,0 +1,103 @@ +# Calibration Tooling v1 + +## Status + +```text +CALIBRATION_TOOLING_V1=PASS/FROZEN +CALIBRATION_TOOLING_PLANARITY_ALIGNMENT=PASS/FROZEN +L3DCALB1_VERSION=1 +``` + +## Authority + +Calibration Science v1 is the scientific authority. This document specializes +the bounded operational bridge implemented by +`include/lardon3d/calibration_tooling.h` and `src/calibration_tooling.c`. + +The bridge connects: + +```text +Calibration Science v1 evidence +-> Calibration Tooling v1 +-> L3DCALB1 v1 +-> Calibration Bootstrap v1 +``` + +It does not acquire images, run a solver, infer optical state, create +reconstruction results, add a Project DB schema version, add a Task kind, or +start Sparse SfM. + +## Planarity alignment + +Calibration Science v1 requires a rigid planar physical target and rejects a +warped board. It defines no numeric target-flatness tolerance. + +The canonical external session records categorical physical evidence: + +```text +planarity PASS +``` + +The Science v1 value `0.20 mm` applies to the allowed range of the ten measured +30.000 mm squares. It is not a target-flatness threshold. + +`Lardon3DCalibrationToolingEvidence.target_flatness_mm` is retained only to +preserve the existing public structure layout. In v1 it MUST be IEEE-754 NaN. +Any finite value is rejected so a caller cannot invent a physical measurement +or silently create a new scientific threshold. + +The immutable session containing the categorical planarity attestation is bound +by the higher-level workflow through `initialization_evidence_sha256`. + +This corrective alignment changes neither Calibration Science v1 nor +`L3DCALB1` v1 nor Calibration Bootstrap v1. + +## Bounded evidence + +Tooling continues to validate the frozen Science v1 requirements, including: + +- exact ChArUco 9 x 7 / DICT_5X5_100 target identity; +- 30.000 mm squares and 21.000 mm markers; +- ten physical square measurements and instrument resolution; +- immutable target, optical-state, solver and evidence digests; +- accepted and rejected view evidence; +- field-region, distance and angle diversity; +- corner quality, clipping, residual and hold-out evidence; +- deterministic repeated parameters; +- representative coordinate equivalence; +- exact selected-image order and representation SHA-256; +- the exact eight-parameter pinhole model; +- zero active extra distortion coefficients. + +Successful solver exit alone is never sufficient acceptance. + +## Artifact and Bootstrap + +For valid evidence Tooling produces exactly the existing fixed-width, +little-endian `L3DCALB1` v1 artifact and may invoke only the frozen Calibration +Bootstrap importer. + +A failed validation reaches neither artifact publication nor Project DB +mutation. Exact successful retries converge through the existing immutable +Bootstrap contract. + +## Current next boundary + +The external Calibration Evidence Solver v1 is implemented and validated. + +The missing product boundary is the higher-level calibration workflow +coordinator. It must consume: + +```text +session.l3dcal +session.l3dcal.bundle/detection.json +session.l3dcal.bundle/solve.json +session.l3dcal.bundle/evidence.json +``` + +together with the exact selected execution and optical state, then construct +the bounded `Lardon3DCalibrationToolingEvidence`. + +The coordinator must verify regular bounded files, immutable digests, +session/bundle identity, categorical planarity PASS, selected-execution image +binding and optical-state equality. It must never manufacture missing evidence. diff --git a/docs/roadmap/roadmap.md b/docs/roadmap/roadmap.md index 52e9cc7..b8b701a 100644 --- a/docs/roadmap/roadmap.md +++ b/docs/roadmap/roadmap.md @@ -24,7 +24,7 @@ SOURCE_COMMENT_AUDIT PASS PRODUCT_DEFINITION PASS/FROZEN PROMPT_TREE CURRENT USER_FACING_UI_LANGUAGE_NORMALIZATION PASS -CURRENT_NEXT FINAL_USABLE_CALIBRATION_WORKFLOW +CURRENT_NEXT CALIBRATION_WORKFLOW_COORDINATOR ``` The current Project DB head is additive: @@ -515,8 +515,29 @@ contract and produces deterministic `L3DCALB1` v1. Calibration Bootstrap v1 imports the explicit artifact. -Calibration Solver Preflight v1 selects the future external OpenCV 5.0.x solver path. That solver is -not a runtime dependency and does not itself execute reconstruction. +Calibration Evidence Solver v1 implements the external OpenCV 5.x evidence path selected by +Calibration Solver Preflight v1. It remains outside the Lardon3D runtime and Project DB and its +deterministic synthetic CPU1 self-test is validated. + +A bounded Tooling correction aligned planarity handling with Calibration Science v1: Science v1 +defines a categorical physical planarity attestation, not a numeric flatness threshold. Tooling +therefore rejects invented finite `target_flatness_mm` values. `L3DCALB1` v1 and Calibration +Bootstrap remain unchanged. + +The current implementation dependency is the calibration workflow coordinator: + +```text +immutable session.l3dcal ++ detection.json ++ solve.json ++ evidence.json ++ exact selected execution ++ exact optical state +-> bounded Calibration Tooling evidence +-> L3DCALB1 v1 +-> Bootstrap +-> READY +``` No calibration component silently turns metadata into scientific calibration. @@ -857,18 +878,19 @@ The established Queue/Governor plus bounded internal fan-out are sufficient to e ## Current next -The immediate repository work is: +The repository execution contract is active: ```text -DOCUMENTATION_FINDING_REMEDIATION PASS -SOURCE_COMMENT_AUDIT PASS -SOURCE_COMMENT_REMEDIATION PASS -PRODUCT_DEFINITION_V1 PASS/FROZEN -PROMPT_TREE NEXT +DOCUMENTATION_FINDING_REMEDIATION PASS +SOURCE_COMMENT_AUDIT PASS +SOURCE_COMMENT_REMEDIATION PASS +PRODUCT_DEFINITION_V1 PASS/FROZEN +PROMPT_TREE CURRENT +CALIBRATION_EVIDENCE_SOLVER_V1 IMPLEMENTED/VALIDATED +CALIBRATION_TOOLING_ALIGNMENT PASS/FROZEN +CURRENT_NEXT CALIBRATION_WORKFLOW_COORDINATOR ``` -No new Lardon3D implementation is authorized by this roadmap update. - -Implementation order is the next preparation phase and will be frozen in `prompt.md` and the numbered -`prompt/` execution contract under explicit human authority. Product Definition v1 is the product-intent input to -that tree; it is not implementation authorization. +Implementation proceeds only through explicitly human-authorized tranches under `prompt.md` and the +numbered `prompt/` execution contract. The current authorized dependency is the final usable +calibration workflow; its next missing sub-boundary is the workflow coordinator. diff --git a/include/lardon3d/calibration_tooling.h b/include/lardon3d/calibration_tooling.h index 865672e..d51902c 100644 --- a/include/lardon3d/calibration_tooling.h +++ b/include/lardon3d/calibration_tooling.h @@ -103,6 +103,12 @@ typedef struct { double target_white_border_mm; double target_measurements_mm[LARDON3D_CALIBRATION_TOOLING_TARGET_MEASUREMENTS]; double measurement_resolution_mm; + /* Calibration Science v1 defines planarity as a categorical physical + * attestation, not a numeric flatness tolerance. This legacy ABI field is + * therefore a required NAN sentinel and MUST NOT carry an invented physical + * measurement. The future workflow coordinator binds the canonical session + * manifest containing `planarity PASS ` through + * initialization_evidence_sha256. */ double target_flatness_mm; double holdout_rmse_px; double holdout_maximum_residual_px; diff --git a/prompt/02_CURRENT_FROZEN_STATE.md b/prompt/02_CURRENT_FROZEN_STATE.md index 23e79f7..2b4acf4 100644 --- a/prompt/02_CURRENT_FROZEN_STATE.md +++ b/prompt/02_CURRENT_FROZEN_STATE.md @@ -6,7 +6,7 @@ CURRENT_PROJECT_DB_SCHEMA=v25 PRODUCTION_TASK_KINDS=16 USER_FACING_UI_LANGUAGE_NORMALIZATION=PASS -CURRENT_IMPLEMENTATION_CURSOR=1_FINAL_USABLE_CALIBRATION_WORKFLOW +CURRENT_IMPLEMENTATION_CURSOR=1_CALIBRATION_WORKFLOW_COORDINATOR ``` ## Authority @@ -26,6 +26,8 @@ TUI operational observatory VALIDATED User-facing TUI/control language PASS External SSD controller VALIDATED Calibration Solver Preflight v1 PASS +Calibration Evidence Solver v1 IMPLEMENTED/VALIDATED +Calibration Tooling planarity alignment PASS/FROZEN ``` The additive schema lineage is: diff --git a/prompt/12_CALIBRATION.md b/prompt/12_CALIBRATION.md index 9d74cae..bca3e05 100644 --- a/prompt/12_CALIBRATION.md +++ b/prompt/12_CALIBRATION.md @@ -5,15 +5,22 @@ ```text CALIBRATION_SCIENCE_V1=PASS/FROZEN CALIBRATION_TOOLING_V1=PASS/FROZEN +CALIBRATION_TOOLING_PLANARITY_ALIGNMENT=PASS/FROZEN CALIBRATION_BOOTSTRAP_V1=PASS/FROZEN -CALIBRATION_WORKFLOW=PLANNED +CALIBRATION_EVIDENCE_SOLVER_V1=IMPLEMENTED/VALIDATED +CALIBRATION_WORKFLOW=IN_PROGRESS +CURRENT_CALIBRATION_NEXT=WORKFLOW_COORDINATOR ``` ## Authority `docs/architecture/calibration_science_v1.md`, `docs/architecture/calibration_bootstrap.md` and `docs/architecture/calibration_solver_preflight_v1.md` are the current specialized calibration documents. -At this checkpoint there is no `docs/architecture/calibration_tooling.md`. Calibration Tooling v1 is nevertheless an acquired PASS/FROZEN implementation boundary. For its exact current API/constant behavior, inspect the executable/public implementation authority, beginning with `include/lardon3d/calibration_tooling.h`, together with the lifecycle declarations in `README.md`, `docs/roadmap/roadmap.md` and `docs/product/product_definition.md`. Do not invent a missing documentation file or treat this prompt file as a replacement architecture specification. +`docs/architecture/calibration_tooling.md` is the specialized Tooling authority. The public API remains `include/lardon3d/calibration_tooling.h`. + +A bounded corrective review established that Calibration Science v1 defines target planarity as a categorical physical attestation, not a numeric flatness tolerance. Tooling preserves its public structure layout while requiring `target_flatness_mm` to be NaN, so callers cannot invent a millimetre measurement. The canonical session's `planarity PASS ` evidence is bound through immutable initialization evidence. + +The external `tools/calibration_evidence_solver/` implementation is present and validated by its deterministic synthetic CPU1 self-test. It remains external to the Lardon3D runtime and Project DB. ## CURRENT @@ -30,15 +37,19 @@ Do not retro-calibrate them by invention. ```text dedicated physical calibration acquisition --> external OpenCV 5.x solver +-> external OpenCV 5.x Calibration Evidence Solver v1 +-> immutable session manifest + complete solver bundle +-> workflow coordinator -> Calibration Tooling v1 -> deterministic L3DCALB1 v1 -> Calibration Bootstrap v1 --> exact optical assignment +-> exact selected-execution calibration scope attachment -> READY -> real Sparse SfM ``` +The current implementation gap is the workflow coordinator. It consumes the immutable `session.l3dcal` plus `detection.json`, `solve.json` and `evidence.json`, binds them to the exact selected execution and optical state, constructs the bounded Tooling evidence and never manufactures missing physical evidence. + ## REQUIRED_PRODUCT_TARGET The TUI calibration assistant must expose: diff --git a/prompt/31_IMPLEMENTATION_ORDER.md b/prompt/31_IMPLEMENTATION_ORDER.md index 97ddb63..c597e66 100644 --- a/prompt/31_IMPLEMENTATION_ORDER.md +++ b/prompt/31_IMPLEMENTATION_ORDER.md @@ -6,7 +6,7 @@ IMPLEMENTATION_ORDER=DEPENDENCY_DRIVEN IMPLEMENTATION_AUTHORIZATION=NO STEP_0_USER_FACING_LANGUAGE_NORMALIZATION=PASS -CURRENT_NEXT=1_FINAL_USABLE_CALIBRATION_WORKFLOW +CURRENT_NEXT=1_CALIBRATION_WORKFLOW_COORDINATOR ``` ## Authority @@ -20,7 +20,7 @@ Implementation remains unauthorized until the human explicitly authorizes a tran Default dependency order: 0. user-facing repository/UI language normalization where appropriate — PASS; -1. final usable calibration workflow — CURRENT NEXT; +1. final usable calibration workflow — IN PROGRESS; current next sub-boundary: workflow coordinator; 2. dedicated physical calibrated real campaign; 3. real Sparse SfM proof; 4. durable Dense/OpenMVS orchestration; diff --git a/src/calibration_tooling.c b/src/calibration_tooling.c index 4dc7da3..e4fb3a9 100644 --- a/src/calibration_tooling.c +++ b/src/calibration_tooling.c @@ -79,7 +79,7 @@ Lardon3DCalibrationToolingResult lardon3d_calibration_tooling_validate( !finite_value(e->target_white_border_mm) || e->target_white_border_mm < 30.0 || e->extra_distortion_coefficient_count != 0 || !finite_value(e->measurement_resolution_mm) || e->measurement_resolution_mm <= 0 || e->measurement_resolution_mm > 0.1 || - !finite_value(e->target_flatness_mm) || e->target_flatness_mm < 0 || e->target_flatness_mm > 0.20) + !isnan(e->target_flatness_mm)) return LARDON3D_CALIBRATION_TOOLING_SCIENCE_REJECTED; double lo = 30.0, hi = 30.0; for (size_t i = 0; i < LARDON3D_CALIBRATION_TOOLING_TARGET_MEASUREMENTS; ++i) { diff --git a/tests/test_calibration_tooling.c b/tests/test_calibration_tooling.c index 790ea68..16d506d 100644 --- a/tests/test_calibration_tooling.c +++ b/tests/test_calibration_tooling.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -37,7 +38,7 @@ static void fixture(Lardon3DCalibrationToolingEvidence *e, Lardon3DCalibrationTo e->target_family=LARDON3D_CALIBRATION_TOOLING_TARGET_CHARUCO_9X7_DICT_5X5_100; e->target_squares_x=9; e->target_squares_y=7; e->target_square_length_mm=30; e->target_marker_length_mm=21; e->target_active_width_mm=270; e->target_active_height_mm=210; e->target_white_border_mm=30; for (size_t i=0;i<10;++i) e->target_measurements_mm[i]=30.0; - e->measurement_resolution_mm=.1; e->target_flatness_mm=.1; e->holdout_rmse_px=.4; e->holdout_maximum_residual_px=.8; + e->measurement_resolution_mm=.1; e->target_flatness_mm=NAN; e->holdout_rmse_px=.4; e->holdout_maximum_residual_px=.8; for (size_t i=0;i<60;++i) { static const uint32_t quadrants[10]={0,0,1,1,2,2,3,3,4,4}; static const uint32_t distances[10]={0,1,2,0,1,2,0,1,2,0};