[Decision D8] Valider le modèle d’état SQLite et ses invariants #9

Closed
opened 2026-08-30 20:42:56 +00:00 by hephaistos · 7 comments
Owner

MODE: DECISION

Statut

Proposé. Le ticket reste ouvert jusqu’à ton go explicite.

Question

Quel modèle persistant permet audit, statut lisible, migrations et récupération sans event-sourcing inutile ?

Options

A — Journal d’événements pur

Historique fort, mais requêtes/statuts et invariants plus complexes.

B — Tables d’état mutable seulement

Simple, mais historique et preuve de décision faibles.

C — Preuves/historique immuables + lignes de cycle de vie explicites

Tables séparées pour bases, identités, fichiers, inspections, findings déterministes, assessments LLM, décisions humaines, transactions, recettes de transaction, approbations, sessions processus, builds, artefacts et installations.

Recommandation

Option C. IDs aléatoires BLOB 128 bits; chemins/argv/cwd en bytes réversibles; enums CHECK; FK/composites/triggers pour les invariants croisés. Une approbation référence obligatoirement une décision humaine approve pour la même inspection/identité.

Concurrence et durabilité

  • WAL sur filesystem local avec self-test de verrouillage;
  • foreign_keys=ON, busy timeout 5 s;
  • écritures courtes; aucune transaction DB pendant attente réseau/éditeur/humain;
  • verrou applicatif pour une mutation interactive à la fois; status read-only concurrent;
  • synchronous=FULL pour l’état d’approbation;
  • migrations SQL embarquées, ordonnées, checksumées; backup avant migration; pas de down-migration promise v1.

Récupération

quick_check, expiration des approbations, validation PID+start-time, transactions orphelines marquées interrompues, cleanup seulement des workspaces enregistrés.

Risques

Corruption disque; WAL non sûr sur certains FS réseau; contraintes intertables mal encodées. Tests de concurrence/crash obligatoires.

Réponse attendue

Choisis A/B/C ou amende le schéma. ADR/clôture seulement après ton go.

Documentation

Protocole automatique de décision

  • Ce ticket reste en discussion et n’autorise aucune implémentation.
  • Les commentaires ordinaires poursuivent la discussion avec Hephaistos dans le ticket.
  • Quand la dernière proposition concrète te convient, publie un commentaire dont le contenu est exactement :
GO DECISION
  • Ce signal transfère automatiquement le ticket à Hephaistos pour consigner l’ADR, mettre à jour les documents de design, vérifier les changements et fermer le ticket.
  • GO DECISION n’autorise ni code de production ni plan d’implémentation; ce travail doit avoir son propre ticket MODE: EXECUTION.
MODE: DECISION ## Statut **Proposé.** Le ticket reste ouvert jusqu’à ton **go explicite**. ## Question Quel modèle persistant permet audit, statut lisible, migrations et récupération sans event-sourcing inutile ? ## Options ### A — Journal d’événements pur Historique fort, mais requêtes/statuts et invariants plus complexes. ### B — Tables d’état mutable seulement Simple, mais historique et preuve de décision faibles. ### C — Preuves/historique immuables + lignes de cycle de vie explicites Tables séparées pour bases, identités, fichiers, inspections, findings déterministes, assessments LLM, décisions humaines, transactions, recettes de transaction, approbations, sessions processus, builds, artefacts et installations. ## Recommandation **Option C.** IDs aléatoires BLOB 128 bits; chemins/argv/cwd en bytes réversibles; enums `CHECK`; FK/composites/triggers pour les invariants croisés. Une approbation référence obligatoirement une décision humaine `approve` pour la même inspection/identité. ## Concurrence et durabilité - WAL sur filesystem local avec self-test de verrouillage; - `foreign_keys=ON`, busy timeout 5 s; - écritures courtes; aucune transaction DB pendant attente réseau/éditeur/humain; - verrou applicatif pour une mutation interactive à la fois; status read-only concurrent; - `synchronous=FULL` pour l’état d’approbation; - migrations SQL embarquées, ordonnées, checksumées; backup avant migration; pas de down-migration promise v1. ## Récupération `quick_check`, expiration des approbations, validation PID+start-time, transactions orphelines marquées interrompues, cleanup seulement des workspaces enregistrés. ## Risques Corruption disque; WAL non sûr sur certains FS réseau; contraintes intertables mal encodées. Tests de concurrence/crash obligatoires. ## Réponse attendue Choisis A/B/C ou amende le schéma. ADR/clôture seulement après ton **go**. ## Documentation - https://git.2027a.net/2027a/auroscope/src/branch/design/technical-contracts/docs/architecture/design-proposals.md ## Protocole automatique de décision - Ce ticket reste en discussion et n’autorise aucune implémentation. - Les commentaires ordinaires poursuivent la discussion avec Hephaistos dans le ticket. - Quand la dernière proposition concrète te convient, publie un commentaire dont le contenu est exactement : ```text GO DECISION ``` - Ce signal transfère automatiquement le ticket à Hephaistos pour consigner l’ADR, mettre à jour les documents de design, vérifier les changements et fermer le ticket. - `GO DECISION` n’autorise ni code de production ni plan d’implémentation; ce travail doit avoir son propre ticket `MODE: EXECUTION`.
Owner

C - attention au scope creep. Uniquement ce qui est nécessaire

C - attention au scope creep. Uniquement ce qui est nécessaire
Author
Owner

Ticket classé comme décision humaine. La discussion continue ici, mais aucune implémentation ni ADR accepté ne sera produit tant que Mathieu n’aura pas publié exactement GO DECISION dans un commentaire distinct.

Ticket classé comme décision humaine. La discussion continue ici, mais aucune implémentation ni ADR accepté ne sera produit tant que Mathieu n’aura pas publié exactement `GO DECISION` dans un commentaire distinct. <!-- auroscope-loop:decision;cursor:1207 -->
Author
Owner

Oui. Je resserre C à un modèle v1 strictement instrumental — pas à un mini event store.

Règle de scope : une table ou une colonne n’entre en v1 que si elle sert directement au moins un de ces besoins : identité exacte/anti-TOCTOU, preuve d’inspection, décision humaine explicite, statut lisible ou récupération après crash. Sans invariant testable et sans lecture concrète du produit, on diffère.

Socle v1 minimal

  • migrations : schema_migrations;
  • identité de recette : package_bases, recipe_identities, recipe_files;
  • inspection/décision : inspections, deterministic_findings, human_decisions;
  • exécution et garde : transactions, transaction_args, transaction_recipes, approvals, process_sessions;
  • résultat strictement nécessaire à la preuve : builds, package_artifacts (hash exact) et install_outcomes.

llm_assessments n’est créée que dans la migration qui livre effectivement l’évaluation LLM; elle ne doit pas précéder cette fonctionnalité. Même règle pour toute donnée de rétention ou de rapport non requise par le flux v1.

Invariants indispensables, pas davantage

  1. foreign_keys=ON; identité/inspection/décision/approbation cohérentes dans la même chaîne de références.
  2. Une approbation ne peut être armée qu’à partir d’une décision humaine approve pour la même inspection et donc la même identité de recette.
  3. armed → claimed est atomique et à usage unique; les transitions de cycle de vie sont monotones.
  4. Aucun artefact réutilisable sans build réussi lié à l’identité exacte et au hash enregistré.
  5. Chemins, argv et cwd restent des bytes réversibles; le texte échappé est seulement une représentation d’affichage.

Explicitement différé

  • table d’événements générique, event sourcing/replay global;
  • graphe de provenance générique, EAV ou schéma de plugins;
  • orchestration distribuée, DB sur filesystem réseau et down-migrations v1;
  • champs « au cas où » sans requête ou invariant déjà identifié.

A reste trop complexe pour le besoin; B ne garde pas assez de preuve. Ma recommandation actuelle est donc C-minimal, avec preuves/décisions immuables et seulement les quelques lignes de cycle de vie mutables nécessaires. Le schéma grandit ensuite par migrations forward quand une fonctionnalité réelle l’exige. Le statut reste proposé : aucune implémentation ni ADR accepté à ce stade.

Oui. Je resserre **C** à un modèle v1 strictement instrumental — pas à un mini event store. **Règle de scope :** une table ou une colonne n’entre en v1 que si elle sert directement au moins un de ces besoins : identité exacte/anti-TOCTOU, preuve d’inspection, décision humaine explicite, statut lisible ou récupération après crash. Sans invariant testable et sans lecture concrète du produit, on diffère. ### Socle v1 minimal - migrations : `schema_migrations`; - identité de recette : `package_bases`, `recipe_identities`, `recipe_files`; - inspection/décision : `inspections`, `deterministic_findings`, `human_decisions`; - exécution et garde : `transactions`, `transaction_args`, `transaction_recipes`, `approvals`, `process_sessions`; - résultat strictement nécessaire à la preuve : `builds`, `package_artifacts` (hash exact) et `install_outcomes`. `llm_assessments` n’est créée que dans la migration qui livre effectivement l’évaluation LLM; elle ne doit pas précéder cette fonctionnalité. Même règle pour toute donnée de rétention ou de rapport non requise par le flux v1. ### Invariants indispensables, pas davantage 1. `foreign_keys=ON`; identité/inspection/décision/approbation cohérentes dans la même chaîne de références. 2. Une approbation ne peut être armée qu’à partir d’une décision humaine `approve` pour la même inspection et donc la même identité de recette. 3. `armed → claimed` est atomique et à usage unique; les transitions de cycle de vie sont monotones. 4. Aucun artefact réutilisable sans build réussi lié à l’identité exacte et au hash enregistré. 5. Chemins, argv et cwd restent des bytes réversibles; le texte échappé est seulement une représentation d’affichage. ### Explicitement différé - table d’événements générique, event sourcing/replay global; - graphe de provenance générique, EAV ou schéma de plugins; - orchestration distribuée, DB sur filesystem réseau et down-migrations v1; - champs « au cas où » sans requête ou invariant déjà identifié. A reste trop complexe pour le besoin; B ne garde pas assez de preuve. Ma recommandation actuelle est donc **C-minimal**, avec preuves/décisions immuables et seulement les quelques lignes de cycle de vie mutables nécessaires. Le schéma grandit ensuite par migrations forward quand une fonctionnalité réelle l’exige. Le statut reste proposé : aucune implémentation ni ADR accepté à ce stade.
Owner

C-mininal GO DECISION

C-mininal GO DECISION
Author
Owner

Je retiens ton choix de C-minimal comme orientation de discussion. Ma recommandation concrète reste donc : preuves et décisions immuables, lignes de cycle de vie mutables strictement nécessaires, et aucune table/colonne sans besoin v1 ou invariant testable.

Le signal automatique n’est toutefois pas déclenché par C-mininal GO DECISION : il doit être publié seul et exactement dans un nouveau commentaire :

GO DECISION

Jusque-là, le statut reste proposé : aucun ADR accepté, aucune clôture et aucune implémentation.

Je retiens ton choix de **C-minimal** comme orientation de discussion. Ma recommandation concrète reste donc : preuves et décisions immuables, lignes de cycle de vie mutables strictement nécessaires, et aucune table/colonne sans besoin v1 ou invariant testable. Le signal automatique n’est toutefois pas déclenché par `C-mininal GO DECISION` : il doit être publié **seul et exactement** dans un nouveau commentaire : ```text GO DECISION ``` Jusque-là, le statut reste proposé : aucun ADR accepté, aucune clôture et aucune implémentation.
Owner

GO DECISION

GO DECISION
Author
Owner

Décision D8 consignée et vérifiée.

  • ADR accepté : docs/decisions/0009-minimal-sqlite-state-model.md
  • commit signé de décision : 9828998
  • tête intégrée de la branche de design : d7aa6c4
  • PR de design mise à jour : #1 (mergeable: true)
  • validations : git diff --check, cibles des liens Markdown locaux, identité/signatures Git et tête distante vérifiées.

Le modèle retenu est C-minimal : preuves et décisions immuables, seules lignes de cycle de vie nécessaires, aucun event store ou schéma spéculatif. Aucun code de production ni plan d’implémentation n’a été créé.

Décision D8 consignée et vérifiée. - ADR accepté : [`docs/decisions/0009-minimal-sqlite-state-model.md`](https://git.2027a.net/2027a/auroscope/src/commit/9828998eac0f5d52fe54004b900ae08ce9eb7704/docs/decisions/0009-minimal-sqlite-state-model.md) - commit signé de décision : [`9828998`](https://git.2027a.net/2027a/auroscope/commit/9828998eac0f5d52fe54004b900ae08ce9eb7704) - tête intégrée de la branche de design : [`d7aa6c4`](https://git.2027a.net/2027a/auroscope/commit/d7aa6c43a3b389904a9c9cffda420cc0fd4f7cad) - PR de design mise à jour : [#1](https://git.2027a.net/2027a/auroscope/pulls/1) (`mergeable: true`) - validations : `git diff --check`, cibles des liens Markdown locaux, identité/signatures Git et tête distante vérifiées. Le modèle retenu est C-minimal : preuves et décisions immuables, seules lignes de cycle de vie nécessaires, aucun event store ou schéma spéculatif. Aucun code de production ni plan d’implémentation n’a été créé.
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
2027a/auroscope#9
No description provided.