fix(reconstruction): finalize track builder v1 freeze
This commit is contained in:
parent
f1a139e3c1
commit
cd6ad105a6
6 changed files with 71 additions and 43 deletions
|
|
@ -547,8 +547,8 @@ CREATE INDEX track_observations_lookup_idx
|
|||
**Statut** : les tables sont créées par la migration et validées par les
|
||||
tests. L'API C (`create_track_set`, `load_track_set`, `find_track_set`,
|
||||
`list_track_sets`, `load_track`, `list_tracks`, `find_track_by_observation`)
|
||||
est exposée et implémentée. Les limites réelles restent l'absence de Track
|
||||
Builder algorithmique, de tâche dédiée et de triangulation.
|
||||
est exposée et implémentée. Le Track Builder algorithmique et sa tâche durable
|
||||
sont implémentés par les Gates A–E ; la triangulation reste hors périmètre.
|
||||
|
||||
## Schéma v15 — payload durable Track Builder
|
||||
|
||||
|
|
|
|||
|
|
@ -122,9 +122,9 @@ USAC/MAGSAC avec configuration, seed et fingerprint déterministes.
|
|||
| **Lien avec le catalogue** | Les tracks référenceront les images par `image_id`, jamais par nom ou chemin. |
|
||||
| **Persistance** | Les tracks sont persistés entre les sessions de traitement. Un track ne peut être détruit que par une action explicite de l'utilisateur. |
|
||||
|
||||
**Statut :** PARTIAL — le Track Model v1 (persistance) est implémenté dans
|
||||
Project DB v15 (`track_sets`, `tracks`, `track_observations`). Le Track
|
||||
Builder, la triangulation et le Sparse SfM restent PLANNED.
|
||||
**Statut :** COMPLETED/FROZEN — le Track Builder v1 direct et durable est
|
||||
implémenté dans Project DB v15 (`track_sets`, `tracks`, `track_observations` et
|
||||
le payload de tâche). La triangulation et le Sparse SfM restent PLANNED.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -2,9 +2,11 @@
|
|||
|
||||
## Status
|
||||
|
||||
**GATE A — PASS.** This document is the scientific and algorithmic contract
|
||||
for the future Track Builder. It specifies no implementation, migration or
|
||||
Task. `FACT`, `DECISION` and `FROZEN` are intentionally distinguished below.
|
||||
**GATE A — PASS. GATE B — PASS. GATE C — PASS. GATE D — PASS. GATE E — PASS.**
|
||||
This document is the frozen scientific and algorithmic contract for Track
|
||||
Builder v1. `FACT`, `DECISION` and `FROZEN` remain distinguished below. Runtime
|
||||
freeze is limited to the Track Builder v1 task contract; generic Task Runtime
|
||||
and Resource Governor evolution remains separate.
|
||||
|
||||
## Scope
|
||||
|
||||
|
|
@ -561,14 +563,14 @@ different-scope identity and late matching-GVR exclusion. The test-only phase
|
|||
seam is compiled only into the Gate C test executable.
|
||||
|
||||
Normal and AddressSanitizer/UndefinedBehaviorSanitizer targeted runs pass for
|
||||
the core and project executables. The 106,496-edge synthetic resource case
|
||||
completed in 0.281 seconds with a 26,564 KiB process high-water RSS and one
|
||||
Match File live at a time. C26 has no clean fault injection in the frozen DB
|
||||
API and C27 belongs to the future concurrency gate.
|
||||
the core and project executables. The historical 106,496-edge synthetic
|
||||
resource case completed in 0.281 seconds with a 26,564 KiB fresh-process RSS
|
||||
and one Match File live at a time. C26 has no clean fault injection in the
|
||||
frozen DB API; C27 was closed by Gate D.
|
||||
|
||||
Gate C status: **PASS**. Gate A: **PASS**. Gate B: **PASS**. Gate D:
|
||||
**NOT_IMPLEMENTED**. Gate E: **NOT_DONE**. Track Builder v1 is not marked
|
||||
fully frozen by this document; the future runtime gates remain separate.
|
||||
Gate C status: **PASS**. Gate D status: **PASS**. Gate E status: **PASS**.
|
||||
Track Builder v1 is **FROZEN** by this Gate E closure. Future scientific changes
|
||||
require a new Builder version and explicit identity decision.
|
||||
|
||||
## Gate D — durable runtime contract
|
||||
|
||||
|
|
@ -591,8 +593,7 @@ the task ID, payload format version, scope path, byte size and SHA-256, exact
|
|||
selector, builder identity, scope hash and count. The scope asset stores field-
|
||||
by-field little-endian uint64 GVR IDs with explicit magic/version/count/size and
|
||||
checksum. No native struct dump, SQL text list or arbitrary small ID limit is
|
||||
allowed. A v14 database remains readable and is upgraded transactionally only
|
||||
when this payload is actually implemented.
|
||||
allowed. A v14 database remains readable and is upgraded transactionally to v15.
|
||||
|
||||
### Recovery and publication
|
||||
|
||||
|
|
@ -611,7 +612,7 @@ Pause and cancellation are cooperative at task boundaries and between bounded
|
|||
GVR units. Gate B is non-preemptible: an active invocation finishes, then pause
|
||||
or cancellation is observed before publication. Prepublication cancellation
|
||||
publishes no Track Set; a committed publication remains valid even if a late
|
||||
cancellation is requested. A deterministic test seam will exercise the Gate C
|
||||
cancellation is requested. A deterministic test seam exercised the Gate C
|
||||
late-identity collision: an exact identity conflict is re-looked-up and reused;
|
||||
an unrelated constraint remains an error.
|
||||
|
||||
|
|
@ -645,4 +646,4 @@ apparent 1,079,972 KiB result was contaminated cumulative RUSAGE from the
|
|||
persistent shell that launched direct runs; it was not Track Builder memory.
|
||||
A normal 250k hardware run completed in 0.368 seconds with 33,228 KiB peak RSS,
|
||||
MemAvailable loss of 14,108 KiB, no swap delta and zero PSI averages. Gate D
|
||||
is **PASS**; Gate E remains responsible for final full-suite freeze.
|
||||
is **PASS**; Gate E final validation and freeze are complete.
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@ géométriquement vérifiées en structures multi-view cohérentes. Il stocke de
|
|||
ensembles d'observations 2D liées à un même point physique supposé. Il ne
|
||||
calcule rien, ne triangule pas, ne contient aucune coordonnée 3D et ne résout
|
||||
aucun conflit. Le Track Builder, la triangulation, le Sparse SfM et le Bundle
|
||||
Adjustment sont des étapes ultérieures séparées.
|
||||
Adjustment sont des étapes séparées ; Gate E a gelé le Builder v1 sans
|
||||
implémenter ces étapes 3D.
|
||||
|
||||
## Track definition
|
||||
|
||||
|
|
@ -22,12 +23,12 @@ triangulation appartient à une étape ultérieure.
|
|||
La chaîne scientifique correcte est :
|
||||
|
||||
```text
|
||||
Matcher → Match Result → Geometric Verification → Track Builder (futur)
|
||||
Matcher → Match Result → Geometric Verification → Track Builder v1
|
||||
→ Track Model → Sparse SfM (futur)
|
||||
```
|
||||
|
||||
Le Matcher ne produit pas les Tracks. Le Track Builder futur les
|
||||
assemblera à partir des Geometric Verification Results.
|
||||
Le Matcher ne produit pas les Tracks. Le Track Builder v1 les assemble à partir
|
||||
des Geometric Verification Results.
|
||||
|
||||
## Observation identity
|
||||
|
||||
|
|
@ -140,7 +141,7 @@ différents. Le reuse est donc scoped à une seule DB projet.
|
|||
|
||||
1. **Minimum structurel** : un Track contient au moins 2 observations.
|
||||
Une seule observation ne constitue aucune relation multi-view. Le futur
|
||||
Track Builder, la triangulation ou le Sparse SfM pourront appliquer des
|
||||
Track Builder v1, la triangulation ou le Sparse SfM pourront appliquer des
|
||||
critères plus stricts. Le Model ne fixe pas de plafond de reconstruction.
|
||||
|
||||
2. **One observation per image** : un Track ne contient pas deux observations
|
||||
|
|
@ -258,7 +259,7 @@ Track Set supprime ses tracks et observations.
|
|||
- cohérent avec tous les résultats publiés existants (Feature Sets, Match
|
||||
Results, GVRs) qui sont immutables après publication.
|
||||
|
||||
Le Track Builder futur construira en mémoire, puis publiera un set complet
|
||||
Le Track Builder v1 construit en mémoire, puis publie un set complet
|
||||
dans une transaction. Aucun track n'est visible avant que le set entier soit
|
||||
validé.
|
||||
|
||||
|
|
@ -405,7 +406,8 @@ track individuel) n'est pas persistée. Les raisons :
|
|||
disponibles ;
|
||||
- une table `track_set_sources` volumineuse complexifie la DB sans bénéfice
|
||||
immédiat ;
|
||||
- le Track Builder futur pourra l'ajouter dans une migration ultérieure.
|
||||
- une future version du Track Builder pourra l'ajouter dans une migration
|
||||
ultérieure.
|
||||
|
||||
## Invalidation
|
||||
|
||||
|
|
@ -437,8 +439,8 @@ et de toutes ses observations.
|
|||
- le `created_at` du set est le timestamp de la transaction ;
|
||||
- le `track_count` et `gvr_count` sont validés contre les INSERTs réels.
|
||||
|
||||
Le Track Builder futur utilisera le Task Runtime pour le checkpoint/reprise
|
||||
et le Resource Governor pour l'admission. Le Model ne contient aucune
|
||||
Le Track Builder v1 utilise le Task Runtime pour le checkpoint/reprise et le
|
||||
Resource Governor pour l'admission. Le Model ne contient aucune
|
||||
logique d'exécution.
|
||||
|
||||
## Resource bounds
|
||||
|
|
@ -511,13 +513,14 @@ transactionnel.
|
|||
## Track rejected state
|
||||
|
||||
Le Model v1 ne persiste pas d'état Track rejected. Le Model représente des
|
||||
Tracks structurellement valides (≥ 2 observations, cohérents). Le futur
|
||||
Track Builder décidera quels candidats publier. Les candidats non publiés
|
||||
n'existent pas dans le Model.
|
||||
Tracks structurellement valides (≥ 2 observations, cohérents). Le Track Builder
|
||||
v1 décide quels candidats publier. Les candidats non publiés n'existent pas dans
|
||||
le Model ; cette séparation reste la frontière scientifique figée.
|
||||
|
||||
## Versioning
|
||||
|
||||
Project DB schema version future décrira le stockage Track. `builder_version`
|
||||
et `verifier_version` décrivent indépendamment les contrats scientifiques.
|
||||
Project DB v14 introduced the Track storage and v15 adds only durable Track
|
||||
Builder task payload persistence. `builder_version` et `verifier_version`
|
||||
décrivent indépendamment les contrats scientifiques.
|
||||
Changer un algorithme n'impose une migration DB que si la représentation
|
||||
persistante change.
|
||||
|
|
|
|||
|
|
@ -10,6 +10,10 @@
|
|||
#include <lardon3d/task_kind_registry.h>
|
||||
#include <lardon3d/track_builder_project.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define LARDON3D_TRACK_BUILDER_TASK_KIND "track_builder.run"
|
||||
|
||||
enum {
|
||||
|
|
@ -40,4 +44,8 @@ bool lardon3d_track_builder_task_reconstruct(
|
|||
const Lardon3DTaskDurableSnapshot *snapshot, void *context,
|
||||
Lardon3DTaskKindBinding *binding);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -207,18 +207,34 @@ static bool create_v13_database(const char *path) {
|
|||
}
|
||||
|
||||
static bool create_v14_database(const char *path) {
|
||||
Lardon3DProjectDb *database = NULL;
|
||||
char error[LARDON3D_PROJECT_DB_ERROR_CAPACITY];
|
||||
if (lardon3d_project_db_open(path, &database, error) != LARDON3D_PROJECT_DB_OK) return false;
|
||||
lardon3d_project_db_close(database);
|
||||
if (!create_v13_database(path)) return false;
|
||||
sqlite3 *connection = NULL;
|
||||
if (sqlite3_open(path, &connection) != SQLITE_OK) return false;
|
||||
bool ok = sqlite3_exec(connection,
|
||||
static const char sql[] =
|
||||
"PRAGMA foreign_keys=OFF;BEGIN IMMEDIATE;"
|
||||
"DROP TABLE track_builder_tasks;"
|
||||
"UPDATE metadata SET value=14 WHERE key='schema_version';"
|
||||
"COMMIT;PRAGMA foreign_keys=ON;",
|
||||
NULL, NULL, NULL) == SQLITE_OK;
|
||||
"CREATE TABLE track_sets(track_set_id INTEGER PRIMARY KEY AUTOINCREMENT "
|
||||
"CHECK(track_set_id>0),builder_kind TEXT NOT NULL CHECK(length(builder_kind)>0 AND "
|
||||
"length(builder_kind)<=64),builder_version INTEGER NOT NULL CHECK(builder_version>0),"
|
||||
"parameter_fingerprint BLOB NOT NULL CHECK(length(parameter_fingerprint)=32),"
|
||||
"verifier_kind INTEGER NOT NULL CHECK(verifier_kind>0),verifier_version INTEGER NOT NULL "
|
||||
"CHECK(verifier_version>0),verifier_fingerprint BLOB NOT NULL CHECK(length(verifier_fingerprint)=32),"
|
||||
"input_scope_hash BLOB NOT NULL CHECK(length(input_scope_hash)=32),gvr_count INTEGER NOT NULL "
|
||||
"CHECK(gvr_count>=1),track_count INTEGER NOT NULL CHECK(track_count>=0),created_at INTEGER NOT NULL "
|
||||
"CHECK(created_at>=0),UNIQUE(builder_kind,builder_version,parameter_fingerprint,verifier_kind,"
|
||||
"verifier_version,verifier_fingerprint,input_scope_hash));"
|
||||
"CREATE TABLE tracks(track_id INTEGER PRIMARY KEY AUTOINCREMENT CHECK(track_id>0),"
|
||||
"track_set_id INTEGER NOT NULL REFERENCES track_sets(track_set_id) ON DELETE CASCADE,"
|
||||
"observation_count INTEGER NOT NULL CHECK(observation_count>=2));"
|
||||
"CREATE INDEX tracks_set_idx ON tracks(track_set_id,track_id);"
|
||||
"CREATE TABLE track_observations(track_set_id INTEGER NOT NULL,track_id INTEGER NOT NULL "
|
||||
"REFERENCES tracks(track_id) ON DELETE CASCADE,feature_set_id INTEGER NOT NULL "
|
||||
"REFERENCES feature_sets(feature_set_id),feature_index INTEGER NOT NULL CHECK(feature_index>=0),"
|
||||
"position_in_track INTEGER NOT NULL CHECK(position_in_track>=0),PRIMARY KEY(track_set_id,feature_set_id,"
|
||||
"feature_index),UNIQUE(track_id,position_in_track));"
|
||||
"CREATE INDEX track_observations_lookup_idx ON track_observations(feature_set_id,feature_index,"
|
||||
"track_set_id);UPDATE metadata SET value=14 WHERE key='schema_version';COMMIT;"
|
||||
"PRAGMA foreign_keys=ON;";
|
||||
bool ok = sqlite3_exec(connection, sql, NULL, NULL, NULL) == SQLITE_OK;
|
||||
return sqlite3_close(connection) == SQLITE_OK && ok;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue