3710253c02
Constat: faisabilite/generator/brief.schema.json, documenté « Contrat d'entrée » et sibling de version/projets_master (tous deux test-enforced), n'était validé par AUCUN test — _validate_brief() ne garde que le code projet, jamais la forme complète du brief; un brief drifté hors contrat passait inaperçu. Fix (teeth): test_input_briefs_validate_against_brief_schema valide les 2 fixtures contre brief.schema.json via le validateur maison Publiciste (zéro-pip, toujours exécuté, pas de skip sous python -S). Conformité pré-vérifiée sous validateur maison ET oracle jsonschema. L'« incomplet » est conforme au sens schéma (null admis) — incomplet seulement au sens sémantique (prix→placeholders #6). Cascade régénérée (générateurs, jamais à la main #6): regression_plan/run/MANIFEST 16→17 · totaux 624→625 exécutés / 607→608 passés / 17 skippés · quality_report evidence 16→17. Prose gatée réalignée (le gate check-readme-claims a mordu): README module + fiches faisabilite/qa/erpnext_backend. Prose ungatée: GAP_ANALYSIS 16→17 + nouveau bloc daily_report (blocs currency antérieurs = snapshots datés, non réécrits). 0 gate ajouté (#5) · 0 chiffre à la main (#6) · 0 commande VPS (#8). run_ci.sh = 33 PASS · 0 FAIL · 0 SKIP. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
114 lines
4.8 KiB
Markdown
114 lines
4.8 KiB
Markdown
# Générateur Faisabilité 4 volets · Sprint 2
|
||
|
||
> Livrable **Faisabilité · Sprint 2** — `03_agents/faisabilite/AGENT.md` §Livrable S2
|
||
> (« Générateur 4 volets automatique »).
|
||
> Cible de portage VPS : `otoia/capabilities/faisabilite_agent.py`.
|
||
|
||
Produit une faisabilité canonique `data_room/PXX/` (conforme au
|
||
[`TEMPLATE_FAISABILITE_CANONIQUE_v1.0.md`](../TEMPLATE_FAISABILITE_CANONIQUE_v1.0.md))
|
||
à partir d'un **brief JSON sourcé**, puis **prouve** que le résultat est
|
||
consommable par le Publiciste.
|
||
|
||
## Place dans la chaîne de valeur
|
||
|
||
```
|
||
brief.json ──► faisabilite_gen ──► data_room/PXX/ (template v1.0)
|
||
│
|
||
▼ (module Publiciste, déjà livré)
|
||
publiciste.parser ──► projets_master.json ──► site
|
||
```
|
||
|
||
Le générateur ferme la boucle amont du Publiciste : ce dernier ne fait que
|
||
**publier** ; c'est ici que les 4 volets sont **produits** et **notés**.
|
||
|
||
## Zéro invention de chiffres (CLAUDE.md #6)
|
||
|
||
Principe défensif de bout en bout :
|
||
|
||
- Les **paramètres canoniques** (3 % édition · 8.5 % marketing · 52 % point
|
||
d'équilibre · USD+DOP · Cardnet · Letter US, CLAUDE.md #9/#10) sont **imposés
|
||
par le générateur** — ils ne proviennent jamais du brief, donc ne peuvent être
|
||
faussés projet par projet.
|
||
- Tout **champ 🔴 absent** du brief est rendu en placeholder `{{…}}`, listé dans
|
||
`champs_manquants`, et **rétrograde** le statut (jamais « complete » douteux).
|
||
- Un prix manquant reste `{{…}}` (jamais `0`, jamais une valeur inventée) → le
|
||
Publiciste publie le projet « En développement ».
|
||
|
||
## Scoring 4Big (§7 du template · 5 axes × 20)
|
||
|
||
| Axe | Source | Calcul |
|
||
|---|---|---|
|
||
| Complétude | brief | fraction des champs 🔴 des 4 volets remplis |
|
||
| Anti-gap prix | brief §3.2 | fraction des cellules typologies renseignées |
|
||
| Traçabilité | brief | `sources[]` + `taux_conversion{date,source}` |
|
||
| Paramètres canoniques | générateur | 20 (garanti · vérifié dans le rendu) |
|
||
| Machine-lisible | **preuve** | `version.json` valide **+** parser Publiciste OK |
|
||
|
||
L'axe machine-lisible n'est **pas auto-décerné** : le CLI re-parse le projet
|
||
généré avec le parser Publiciste et valide `version.json` contre
|
||
[`version.schema.json`](../version.schema.json). En cas d'échec, les 20 points
|
||
sont retirés, `version.json` réécrit, et la commande sort en erreur.
|
||
|
||
Statut « complete » ⇔ score ≥ 95 **et** aucun champ 🔴 manquant **et** bloc prix
|
||
intégral **et** 4 volets — cohérent avec la contrainte `allOf` de
|
||
`version.schema.json`.
|
||
|
||
## Utilisation
|
||
|
||
```bash
|
||
# Bilan 4Big d'un brief (sans rien écrire)
|
||
python3 faisabilite_gen.py score fixtures/brief_complete.json
|
||
|
||
# Générer une faisabilité (+ preuve machine-lisible)
|
||
python3 faisabilite_gen.py generate fixtures/brief_complete.json -o /tmp/data_room
|
||
|
||
# Amorcer un nouveau projet (arborescence vide à placeholders)
|
||
python3 faisabilite_gen.py scaffold P07 -o /tmp/data_room
|
||
|
||
# Générer tous les briefs d'un dossier
|
||
python3 faisabilite_gen.py batch fixtures -o /tmp/data_room
|
||
```
|
||
|
||
Puis, via le module Publiciste, publier :
|
||
|
||
```bash
|
||
cd ../../publiciste
|
||
python3 publiciste.py run /tmp/data_room -o /tmp/site
|
||
```
|
||
|
||
`--generated-at` fige l'horodatage (sorties déterministes / tests).
|
||
|
||
## Contrat d'entrée
|
||
|
||
Voir [`brief.schema.json`](./brief.schema.json). Les fixtures sont **synthétiques**
|
||
(`"synthetique": true`, bannière « ne jamais publier ») :
|
||
|
||
- `fixtures/brief_complete.json` → statut `complete`, score 100/100.
|
||
- `fixtures/brief_incomplete.json` → prix absents → rétrogradation
|
||
`en_developpement`, prix restés en placeholders (démontre l'anti-invention).
|
||
|
||
## Tests
|
||
|
||
```bash
|
||
python3 -m unittest discover -s tests -v
|
||
```
|
||
|
||
17 tests `unittest` (stdlib pur, **zéro pip**) : scoring, rétrogradation,
|
||
paramètres canoniques, conformité des fixtures au **contrat d'entrée**
|
||
(`brief.schema.json`), et **round-trip end-to-end** generator → parser Publiciste
|
||
→ `projets_master.json` validé contre le schéma. Réutilise le parser + le
|
||
validateur du Publiciste (aucune duplication · workflow #5). Un oracle
|
||
`jsonschema` est activé en plus s'il est installé.
|
||
|
||
Job CI : `faisabilite-gen-tests` (gate `.gitea/workflows/ci.yml` · Gitea Actions
|
||
uniquement · contrainte #2).
|
||
|
||
## Hors périmètre worker (VPS / calendrier ultérieur)
|
||
|
||
- Application sur les **données réelles** `data_room/` (VPS · Faisabilité/ERPNext).
|
||
- Archives auto `_ARCHIVES/PXX_v{N}_YYYYMMDD/` sur bump MAJOR du template (S3/S4).
|
||
- Génération des `40_llm_outputs/` marché/directeur/fiscal/juridique + rapports
|
||
bancables FR/EN/ES (S3+ ; seuls brief/masterplan/architecture/paysage/
|
||
ingénierie/commercial sont produits ici).
|
||
- Trigger `otoia-faisabilite.timer` + notification Publiciste/WhatsApp (S6 · VPS).
|