Fiche de décision — Vérité-terrain économique du programme¶
- Story : CVN-N001-EI-S11 (le HPO f1_buy prod sur-apprend-il ?)
- Date : 2026-06-05
- Statut : DÉCIDÉ 2026-06-05 (voir §8) — C élargie en priorité (CVN-N001-EI-S12) + garde intérimaire faible-regret maintenant + B adjuge la science. Comité
plan_reviewREJECTED/EXECUTION_RISK(single-scorer Gemini, Meeting #250) lu comme question-bien-posée, tranché sur la logique d'asymétrie. - Origine : sonde PG read-only
finetune_results(reconnaissance §0bis appliquée à la sonde elle-même : peuplé / keyé-jusqu'à-la-config / deux-côtés) - Auteur : reconnaissance stratégique, pré-plan S11
1. Décision à prendre¶
Sachant que la vérité-terrain économique existe dans
finetune_resultsmais (1) est découplée de la config déployée (clés de join mortes) et (2) n'est fiable que sur n≈27 lignes post-S19, comment fait-on avancer S11 et le programme Tier-2 économique ?
Ce n'est pas un détail d'implémentation S11 : c'est le substrat de preuve de tout le Tier-2 économique (A0, EE-S09 cost-sensitive loss, confiance dans le coût réel du gate s43 §2bis). Le choix conditionne ce qu'on peut affirmer et ce qu'on doit d'abord construire.
2. Faits établis (sonde read-only, PG managé 172.16.16.4 / db champollion)¶
Table économique = finetune_results (9216 rows), pas finetune_runs (68 rows, métadonnées). Sonde exécutée en read-only depuis le pod airflow-scheduler (le PG prod est managé, non joignable depuis localhost).
Critère 1 — peuplé (distribution, pas présence) : ✅ réel, mais 99,7 % pré-S19¶
- Colonnes éco non-dégénérées :
sortino(min −13.6 / max 100 / avg 1.30 / std 2.37 ; 824 zéros/9216),expectancy(−907→+1490),total_return(−98→+1654),win_rate,n_trades(0→340). L'opposé du placeholderwf_oos=0.0 de MLflow. f1_buy(8171/9216, avg 0.365) etauc_buy(7938/9216, zéro zéro, 0.44→0.99) présents côte-à-côte avec l'éco.- MAIS : runs 2026-04-17 → 2026-05-24. 9189/9216 = pré-S19 (biais LGB over-trade, cf.
track_verdicts_subordinate_to_s19). Post-S19 fiable = 27 lignes.
Critère 2 — keyé jusqu'à la config : ❌ niveau déploiement / ✅ niveau FTF¶
- Colonnes de join-config mortes :
model_hyperparams0/9216,optuna_trial_id0/9216,feature_hashconstant (distinct=1). → aucune colonne ne relie une ligne à une config HPO déployée. - Keyé richement aux coordonnées d'ablation FTF : 20 factors × 100 variants × 13 crypto × 12 fold × 3 strategy × 3 cost_bps. Proxy↔goal joint observable au niveau variant, pas au niveau déploiement.
Critère 3 — deux côtés (val/sélection vs OOS) : ⚠️ structure présente, paires non-peuplées¶
- Fenêtres
train/validation/testprésentes → côté OOS là. Maisprimary_metric='sortino'partout,threshold_source/calibration_method=NULL → FTF range par sortino, aucune paire val-f1_buy↔OOS-f1_buy stockée (un seul scalaire OOS/ligne).
Critère 4 — calculé sous coûts validés (et non assumés) : ❌ non-établi par la sonde¶
Ce critère manquait aux trois premiers — un §0bis que la sonde elle-même avait raté. Critères 1-3 prouvent que l'éco existe et est joignable ; ils ne prouvent pas qu'elle est vraie. - Les
sortino/expectancy/total_returndefinetune_resultssont des éco backtestées souscost_bpsassumés — une simulation, pas du P&L réalisé (fills live). - Le sweepcost_bps(3 valeurs) est une sensibilité, pas une validation : il fait varier l'hypothèse de coût, il ne la confronte pas au réel. - Une valeur keyée-mais-sous-faux-coût est le même trap que les zéros-placeholder, en plus subtil : c'est un nombre, il a l'air réel, il est calculé avec les mauvais coûts. - Statut : que l'éco réalisée soit captée quelque part est une question séparée et non-établie par cette sonde.
Aperçu reconnaissance — ⚠️ PAS l'analyse S11 ; première hypothèse à trancher par B, pas une annexe¶
Tranche post-S19, cost_bps=15, OOS, n_trades≥3, n=23 :
corr(f1_buy, sortino) = -0.54
corr(f1_buy, total_return) = -0.62
corr(f1_buy, expectancy) = -0.13
corr(auc_buy, sortino) = 0.005
corr(f1_buy, sortino) subit un effet de sélection (comment f1_buy varie parmi des configs choisies pour le sortino ≠ la relation dans la population déploiement f1_buy-sélectionnée). Le −0.54 peut s'évaporer sur le substrat propre.
- Net : ne pas agir sur −0.54 ; ne pas l'enterrer. B est le juge — c'est la première hypothèse que B doit trancher, enjeu opérationnel si elle tient, dissolution possible si le confound domine.
Conclusion factuelle¶
Le programme mesure son éco — précisément : l'éco backtestée sous coûts assumés (donc pas « il ne la mesure pas », mais pas non plus « il mesure du P&L vrai »). Trois découplages : 1. Découplé du déploiement : substrat FTF (sélection-par-sortino) ≠ substrat HPO (sélection-par-f1_buy), sans clé partagée. 2. Découplé du réel : éco simulée sous coûts assumés, validité-coût non-établie (critère 4). 3. Fiable seulement à n≈27 post-S19.
Le split proxy-objectif de S11 est confirmé au niveau données.
3. Options¶
Option A — Recadrer S11 sur le substrat FTF existant (lecture seule, cheap)¶
- Quoi : exécuter l'analyse proxy↔éco de S11 sur
finetune_resultspost-S19 tel quel (niveau variant, n≈27, sans join déploiement). - Coût : ~nul (données là, read-only). Quelques jours.
- Débloque : une réponse observationnelle, grade-indice à A0 (f1_buy suit-il l'éco à travers les variants FTF).
- Limites : n≈27 → pas de significativité ; pas keyé déploiement → ne peut pas dire « la config déployée sur-apprend » ; substrat sélectionné-par-sortino → répond à une autre question de sélection que celle de la prod.
- Risque majeur : produire un nombre qui ressemble à une réponse A0 mais ne transfère pas à la question-déploiement que S11 devait poser — exactement la transfer-fallacy que le programme percute en boucle (AUC→f1_buy, S04).
Option B — Produire la vérité-terrain keyée-config d'abord (lourd, correct)¶
- Quoi : corriger le gap d'observabilité (peupler la clé de join
model_hyperparams/optuna_trial_id/feature_hashdans le writer FTF +finetune_baselines), puis re-run un sweep post-S19 ciblé keyé sur les configs LGB/CB déployées, puis S11 sur ce substrat. - Coût : changement code + un sweep compute (launch operator-gated, cf.
no_autonomous_launches) + re-run. Semaines. - Débloque : le substrat propre pour A0 et tout le Tier-2 (EE-S09 cost-sensitive loss, confiance coût-réel s43 §2bis) — l'actif durable. B est aussi le juge de l'anti-corrélation (§2 aperçu) : sur un substrat f1_buy-représentatif (pas sortino-sélectionné), le −0.54 se confirme (dommage opérationnel réel) ou se dissout (confound de sélection).
- B échappe au n≈27 : ce n'est pas une borne intrinsèque mais un artefact « pas re-tourné depuis le fix S19 » ; le re-run de B régénère un substrat fiable keyé sur tous les folds. B est vraiment le substrat propre, pas time-borné — ce qui conforte la séquence C→B.
- Limites : chemin le plus long ; nécessite un lancement compute (politique : pas de launch autonome).
- Risque : scope-creep infra (le fix de clé recoupe l'observabilité de CVN-N014-ED).
Option C — Séparer : livrer le gap d'observabilité comme Story-prérequis, S11 en pause¶
- Quoi : acter que le vrai livrable du tour = « l'observabilité économique keyée-config-et-coût-validée manque ». Ouvrir une Story d'observabilité ciblée, en faire le prérequis explicite de S11 et du Tier-2. S11 reste
Specified/en pause jusqu'à ce que le substrat existe. En parallèle, filer les 3 issues d'écart. - Livrable élargi (raffinement) : « keyé ET coût-validé », pas « keyé » seul. Keying et validité-coût sont deux prérequis co-égaux et constitutifs de la vérité-terrain éco — la validité-coût n'est pas en aval du substrat (un bénéficiaire), elle est constitutive (les nombres ne sont vrais que si les coûts le sont). Périmètre C :
- Peupler la clé de join morte (
model_hyperparams/optuna_trial_id/feature_hash) — ferme l'écart #2 (ADR-25). - Peupler
finetune_baselines— ferme l'écart #3 (ADR-29). - Trancher les paires val/OOS (critère 3).
- Établir la validité-coût : soit ancrer le
cost_bpsdu backtest sur les fills réalisés (réconciliation P&L simulé↔réel), soit, à défaut, étiqueter explicitement toute éco persistée comme « backtestée-sous-coûts-assumés » et ouvrir le chantier de captation de l'éco réalisée (recoupe le §2bis de s43). - Coût : une Story code (fix writer + étiquetage) — aucun sweep compute requis pour démarrer (le fix rend keyés/étiquetés les sweeps futurs ; backfill possible plus tard).
- Débloque : transforme la reconnaissance négative en livrable concret et mergeable ; de-risque chaque Story Tier-2 aval de construire sur un substrat découplé ou sous-faux-coût.
- C'est le cadrage que tu as toi-même articulé (« l'observabilité économique keyée-config est le prérequis de tout le Tier-2 »), durci par le critère 4.
4. Critères de décision¶
- Ne pas répéter la transfer-fallacy : ne pas produire un chiffre A0 qui ne transfère pas à la question-déploiement (disqualifie A en solo).
- Actif durable > réponse jetable : le programme a besoin d'un substrat keyé-config réutilisable (favorise B/C).
- Pas de launch autonome : tout ce qui démarre sans sweep compute est préférable à court terme (favorise C, qui démarre sans launch).
- No-silent-fail (ADR-25) : les colonnes logged-never-populated (
model_hyperparams,optuna_trial_id) etfinetune_baselinesvide (ADR-29 violé) doivent être traitées, pas contournées. - Coût-validité constitutive (critère 4) : un substrat keyé sous faux coût est un substrat propre de nombres faux — même trap que les zéros-placeholder. La validité-coût est co-égale au keying, pas un bénéficiaire aval (favorise C-élargi, disqualifie tout livrable « keyé » qui s'arrête au keying).
- Honnêteté du verdict : tout résultat S11 doit déclarer son substrat, son n et son hypothèse de coût (le
diagnostic_committee_score_cap+dont_downplay_review_roundss'appliquent).
5. Recommandation argumentée¶
Option C élargie (keyé ET coût-validé) comme livrable shippable ; l'anti-corrélation est la première hypothèse de B, pas une annexe ; B devient le mode d'exécution de S11 une fois C atterri.
- C est le livrable honnête du tour : la reconnaissance a découvert que la prod ne peut pas lire son éco keyée-config, et que ce qu'elle lit est sous coût assumé non-validé. Le ranger comme une Story d'observabilité-prérequis (clés mortes + baselines + val/OOS + validité-coût) convertit un constat négatif en actif mergeable, sans lancement compute — démarrable immédiatement.
- L'anti-corrélation n'est pas une annexe qui justifie C — c'est la première hypothèse que B doit trancher. −0.54/−0.62 + mécanisme over-trade = f1_buy pourrait détruire de la valeur (enjeu opérationnel : la sélection live travaille peut-être contre l'objectif). MAIS confound de sélection réel (substrat sortino-sélectionné) → peut s'évaporer sur le substrat propre. On n'agit pas sur −0.54, on ne l'enterre pas : B est le juge.
- Implication intérimaire ouverte (à trancher, pas à décider ici) : faut-il un garde sur la sur-confiance en f1_buy en sélection pendant qu'on bâtit le substrat ? Question posée, non-résolue — dépend de B.
- Déplacement de scope : si l'anti-corrélation tient, EE-S09 (cost-sensitive loss) passe de « doublement précieux » à « mitigation d'un dommage potentiel » — change son urgence.
- B est l'aval, pas le présent : une fois C mergé (clés peuplées + coût-validé) + un sweep post-S19 keyé lancé (geste opérateur), S11 s'exécute sur un substrat propre, keyé-déploiement et coût-validé, juge l'anti-corrélation, et peut répondre à « la config déployée sur-apprend-elle ». Le tenter avant C, c'est A déguisé. B n'est pas time-borné (le n≈27 est un artefact pré-fix-S19, pas une borne).
Refusé : A en solo (transfer-fallacy, critère 1), B-immédiat (exige un launch + un fix non mergé, critère 3), et tout C qui s'arrête à « keyé » sans validité-coût (critère 5).
6. Écarts connexes à filer (logged-never-populated = même maladie §0bis)¶
| # | Écart | ADR | Destination proposée |
|---|---|---|---|
| 1 | MLflow wf_oos_net_expectancy=0.0 sur 300 CVNTrade_Models |
ADR-25 | Issue séparée (déjà ta directive) |
| 2 | finetune_results.model_hyperparams + optuna_trial_id = 0/9216, feature_hash constant |
ADR-25 | Le cœur de la Story-prérequis C (gap clé-config) |
| 3 | finetune_baselines = 0 rows (baseline naïve absente) |
ADR-29 | Issue ou inclus dans C |
| 4 | Éco persistée = backtestée sous coûts assumés, éco réalisée (fills live) non-captée/non-réconciliée | — (constitutif, pas placeholder) | Item 4 de C (validité-coût) ; recoupe s43 §2bis |
7. Prochaine action (au choix opérateur)¶
- Valider C → créer la Story-prérequis d'observabilité économique (via
/create-story). Placement Epic : penche CVN-N001-EI (instrumentation du substrat de recherche — mesurabilité de l'objectif éco — pas du transport infra ED) ; ce qui compte est son statut de gate du Tier-2, pas l'Epic. Filer les 3 issues, mettre S11 en attente explicite. - Comité — optionnel et ciblé : C est shippable sans comité (prérequis clair, sans launch, ferme ADR-25/29 — non-controversé). Si tu soumets, soumets la question durcie — le 4ᵉ critère (validité-coût) + la direction de l'aperçu (anti-corrélation) changent-ils l'urgence/le scope de C, et faut-il un garde intérimaire sur f1_buy-en-sélection ? — pas « A/B/C ». C'est là que la revue externe ajoute.
- Trancher autrement (A solo / B immédiat) avec justification écrite contre les critères §4.
8. Convergence post-comité (2026-06-05) — décision finale¶
Comité : plan_review sur cette fiche, question durcie, session 0e81c38a → Meeting OP #250 (wp#246). Run Gemini-primary single-scorer : MISTRAL_API_KEY Unauthorized → le score_b Mistral du dual-LLM par expert a échoué ; les 5 experts ont produit via score_a (Gemini), consolidateur Gemini. Verdict REJECTED/EXECUTION_RISK, consensus split, human_review_required. À lire comme une question bien posée, pas un arbitrage : single-scorer + split → c'est l'opérateur qui tranche ; le comité a fait surgir le risque, il ne l'a pas réglé. (Re-run canonique Mistral+Gemini non effectué — clé toujours morte au moment de la décision ; la décision tient sur la logique, pas sur le score de 5 personas Gemini.)
Décision opérateur : C élargie en priorité + garde intérimaire maintenant + B adjuge la science. L'accroc était sur le cadrage — prudence scientifique (« ne pas conclure sur −0.54 », tenue, correcte) laissée déborder sur la posture opérationnelle (« donc ne pas toucher au live »). Deux décisions distinctes, fondues à tort : 1. Scientifique : f1_buy anti-corrèle-t-il ? → B juge, on n'affirme pas. 2. Opérationnelle : quelle exposition garder pendant les semaines C→B face à un signal crédible-mais-non-confirmé que le critère live peut nuire ? → asymétrie : garde cheap et réversible vs semaines de composition négative potentielle sur capital réel. Penche vers le garde.
§0bis sur la reco du comité elle-même (tient sur le critère 4) — les 4 gardes proposées ne sont pas équivalentes :
| Garde | Nature | Regret |
|---|---|---|
| Réduction d'exposition / cap d'influence / pause f1_buy-comme-seul-sélecteur / human-in-the-loop | réduit le pari sur un critère non-validé sans en affirmer aucun autre | faible-regret des deux côtés (cheap si −0.54 s'évapore, protecteur s'il tient) |
| « Override / sélection par éco simulée » | affirme un critère de remplacement lui-même non-validé (critère 4) et circulaire (−0.54 mesuré sur substrat sortino-sélectionné → troquer sélection-f1_buy contre sélection-éco = échanger un non-validé contre un non-validé avec moins de preuve indépendante) | haut-regret si l'éco simulée est fausse aussi |
→ Garde retenu = faible-regret uniquement (hedge sans croire le −0.54). Rejeté : la sélection-par-éco-simulée.
Ça dissout le split : le dissent a raison de craindre d'agir sur −0.54 ; la majorité a raison de vouloir un hedge — un garde réduction-d'exposition hedge sans croire. Personne n'a à trancher la science pour poser la couverture.
Le dissent (« urgence non-mesurée ») se retourne : gap #4 = aucune observabilité de l'éco réalisée → on ne peut pas voir si la sélection-f1_buy nuit déjà. L'in-observabilité est le risque ; on hedge ce qu'on ne voit pas → argument pour le garde cheap, pas contre.
Raffinement reco-3 (data-contract coût-validité) : = critère 4 opérationnalisé (bien), mais doit ancrer sur des fills réalisés (gap #4), pas « assume cost_bps=X » — sinon le contrat certifie une hypothèse au lieu de la valider. Donc périmètre C item 4 : la voie valide = réconciliation fills réalisés ; l'étiquetage « backtested-under-assumed-cost » est un stopgap d'honnêteté, pas une certification.
Actions (placement/forme = geste opérateur) :
- C élargie = CVN-N001-EI-S12 (#1109 / wp#246, New) — priorité.
- Garde intérimaire = action distincte et plus rapide que C ; faible-regret only ; a besoin de son propre home (issue/Story) + forme (réduction expo / cap / pause f1_buy-seul / HITL). Touche la sélection live → domaine Console/kill-switch opérateur, pas d'implémentation autonome.
- B (analyse aval) adjuge l'anti-corrélation sur le substrat propre que C produit.
Journal des écritures de ce tour : sonde PG read-only · cette fiche · Story C CVN-N001-EI-S12 (#1109 + wp#246
New) · comité session0e81c38a→ Meeting OP #250 · issue gap #1111 (wf_oos, MLflow-side, séparée) · tracker garde intérimaire #1112 (forme/home = opérateur, faible-regret only) · S11 wp#239New → On hold(bloquée par S12).MISTRAL_API_KEYmise à jour + vérifiée vivante (re-run comité canonique non requis — opérateur a tranché sur la logique). Gaps #2/#3/#4 absorbés dans S12 (scope items 1/2/4), pas d'issues séparées. Reste 100 % gestes opérateur : forme + placement du garde #1112 (domaine Console/kill-switch), démarrage de S12.