Skip to content

Architecture Decision Records — Index

Per-file ADRs migrated from the monolithic documentation/ADR.md during Phase 0 of issue #593 on 2026-04-23.

Backfilled ADRs (2026-04-24) — ADR-46, 47, 48 were referenced in the codebase (TUNING_PROTOCOL, FILTER_FUNNEL, TRAINING_PIPELINE, ML Platform design) since Sprint 10–11 but had never been authored as standalone ADRs. Reconstructed from those references + the code they describe. The header comment in each of those files flags them as backfilled.

Reserved / unassigned numbers: 0049, 0050, 0051, 0053, 0072, 0073, 0074, 0075, 0078. Available for future ADRs — do NOT re-number existing ADRs to fill gaps (invariants elsewhere in the repo cite them by number). 0078 is reserved for the IDP framework choice (stub referenced in CVN-N012-EA-S01 plan dossier ; formal ADR lands in CVN-N012-EA-S04).

New ADRs: use documentation/templates/TEMPLATE_adr.md and the next available number (current max: 0089 → next 0090).

Index

# Title File
0001 ZenML OSS, pas Pro 0001-zenml-oss-pas-pro.md
0002 Séparation Discovery / Promotion 0002-separation-discovery-promotion.md
0003 Build ≠ Deploy 0003-build-deploy.md
0004 Cache Policy explicite par step 0004-cache-policy-explicite-par-step.md
0005 NannyML CBPE est un signal secondaire 0005-nannyml-cbpe-est-un-signal-secondaire.md
0006 Validation OHLCV obligatoire 0006-validation-ohlcv-obligatoire.md
0007 Idempotence des mutations 0007-idempotence-des-mutations.md
0008 Logging exhaustif des signaux 0008-logging-exhaustif-des-signaux.md
0009 Drift monitoring 0009-drift-monitoring.md
0010 Configuration PTE versionnée 0010-configuration-pte-versionnee.md
0011 Airflow = UI opérateur, ZenML = backend pipeline 0011-airflow-ui-operateur-zenml-backend-pipeline.md
0012 ZenML Airflow Orchestrator natif 0012-zenml-airflow-orchestrator-natif.md
0013 DAGs publiés via Git 0013-dags-publies-via-git.md
0014 Le testing DOIT estimer la généralisation, pas la performance locale récente 0014-le-testing-doit-estimer-la-generalisation-pas-la-performance.md
0015 Les seuils de décision DOIVENT être calibrés out-of-sample 0015-les-seuils-de-decision-doivent-etre-calibres-out-of-sample.md
0016 Screening et testing DOIVENT partager la même sémantique de labels 0016-screening-et-testing-doivent-partager-la-meme-semantique-de-.md
0017 Les optimisations de vitesse NE DOIVENT PAS altérer la sémantique statistique 0017-les-optimisations-de-vitesse-ne-doivent-pas-alterer-la-seman.md
0018 Les DAGs générés sont manual-only (pas de schedule) 0018-les-dags-generes-sont-manual-only-pas-de-schedule.md
0019 Le launcher est l'autorité unique d'exécution 0019-le-launcher-est-l-autorite-unique-d-execution.md
0020 Pas de cleanup post-création de DagRuns 0020-pas-de-cleanup-post-creation-de-dagruns.md
0021 La sémantique du DAG DOIT correspondre à l'intention d'exécution 0021-la-semantique-du-dag-doit-correspondre-a-l-intention-d-execu.md
0022 Les DAGs générés sont créés paused par défaut 0022-les-dags-generes-sont-crees-paused-par-defaut.md
0023 Feature retrieval must be version-pinned (fail-fast) 0023-feature-retrieval-must-be-version-pinned-fail-fast.md
0024 Le feature set fait partie du contrat modèle 0024-le-feature-set-fait-partie-du-contrat-modele.md
0025 Pas de fallback silencieux dans les pipelines ML 0025-pas-de-fallback-silencieux-dans-les-pipelines-ml.md
0026 Grafana comme point d'entrée unique 0026-grafana-comme-point-d-entree-unique.md
0027 Comparaison intra-crypto uniquement 0027-comparaison-intra-crypto-uniquement.md
0028 Classification binaire (BUY/HOLD) assumée 0028-classification-binaire-buy-hold-assumee.md
0029 Baseline naïve obligatoire pour interpréter le ML 0029-baseline-naive-obligatoire-pour-interpreter-le-ml.md
0030 Logs structurés comme interface stable (CORRELATION DATA) 0030-logs-structures-comme-interface-stable-correlation-data.md
0031 Logging unifié via Python logging, interdiction de print() dans les pipelines 0031-logging-unifie-via-python-logging-interdiction-de-print-dans.md
0032 Les événements métier utilisent le format structuré event=name key=value 0032-les-evenements-metier-utilisent-le-format-structure-event-na.md
0033 Catalogue fermé des événements de pipeline 0033-catalogue-ferme-des-evenements-de-pipeline.md
0034 Séparation lisibilité humaine et parsabilité machine 0034-separation-lisibilite-humaine-et-parsabilite-machine.md
0035 Pas de passage en DEBUG sans résumé INFO 0035-pas-de-passage-en-debug-sans-resume-info.md
0036 Filtrage centralisé des loggers tiers non actionnables 0036-filtrage-centralise-des-loggers-tiers-non-actionnables.md
0037 Budget qualité des logs mesurable 0037-budget-qualite-des-logs-mesurable.md
0038 Champs canoniques, golden fields, séparation status/code 0038-champs-canoniques-golden-fields-separation-status-code.md
0039 Runtime standalone, API façade 0039-runtime-standalone-api-facade.md
0040 Paper et live partagent le même kernel 0040-paper-et-live-partagent-le-meme-kernel.md
0041 Sessions event-sourced et recouvrables 0041-sessions-event-sourced-et-recouvrables.md
0042 Promotion atomique par crypto 0042-promotion-atomique-par-crypto.md
0043 Centralisation de l'observabilité dans le FilterChainExecutor 0043-centralisation-de-l-observabilite-dans-le-filterchainexecuto.md
0044 Contrat de données strict pour l'événement signal_funnel 0044-contrat-de-donnees-strict-pour-l-evenement-signal-funnel.md
0045 Gate Checks basés sur la densité de signal (Anti-Starvation) 0045-gate-checks-bases-sur-la-densite-de-signal-anti-starvation.md
0046 Class balancing obligatoire en training binaire (backfilled 2026-04-24) 0046-class-balancing-obligatoire.md
0047 Meta-label model trained on a separate fold (backfilled 2026-04-24) 0047-meta-label-trained-on-separate-fold.md
0048 Cost and Kelly are execution-layer, not signal filters (backfilled 2026-04-24) 0048-cost-and-kelly-at-execution-layer.md
0052 Auditabilité des sessions du comité d'experts 0052-auditabilite-des-sessions-du-comite-d-experts.md
0054 Replace Static CUSUM Filter with Adaptive Event Engine 0054-replace-static-cusum-filter-with-adaptive-event-engine.md
0055 Format de présentation des verdicts du comité d'experts 0055-format-de-presentation-des-verdicts-du-comite-d-experts.md
0056 Every Pipeline Change Must Be FTF-Testable (A/B Testable by Design) 0056-every-pipeline-change-must-be-ftf-testable-a-b-testable-by-d.md
0057 ADRs Must Be Written in English 0057-adrs-must-be-written-in-english.md
0058 Every FTF Factor Must Have a Guardrail 0058-every-ftf-factor-must-have-a-guardrail.md
0059 All Pipeline Parameters Must Be Stored in PostgreSQL and Editable via Console 0059-all-pipeline-parameters-must-be-stored-in-postgresql-and-edi.md
0060 Hot-Path Sequential Pipeline (CandlePipeline Pattern) 0060-hot-path-sequential-pipeline-candlepipeline-pattern.md
0061 Batch Dataflow DAG Pattern (Hamilton for Feature Computation) 0061-batch-dataflow-dag-pattern-hamilton-for-feature-computation.md
0062 Unified Observability via OpenTelemetry 0062-unified-observability-via-opentelemetry.md
0063 FTF Mission Mode is Binary BUY/NOT_BUY; 3-class is Legacy 0063-ftf-mission-mode-is-binary-buy-not-buy-3-class-is-legacy.md
0064 FTF Preflight is a First-Class Phase (No External Data-Prep Scripts) 0064-ftf-preflight-is-a-first-class-phase.md
0065 Airflow DAG Params Are Run-Level Context Only; Config Lives in ftf_config 0065-airflow-dag-params-run-level-only.md
0066 UI Stack: Figma + MkDocs + Structurizr + Mermaid + Storybook + Next.js 0066-ui-stack.md
0067 Pluggable Feature-Selection Framework (variance / covariance / FI / SHAP × {global, perfold}) 0067-pluggable-feature-selection-framework.md
0068 Expert Committee is the default channel for plan and PR reviews 0068-expert-committee-as-default-review-channel.md
0069 OpenProject is the project orchestrator (versions = sprints, Story-pull / version-close discipline) 0069-openproject-as-project-orchestrator.md
0070 MLOps readiness plan template is mandatory before any ML production merge 0070-mlops-readiness-template-mandatory.md
0071 Trading kill-switch invariants (single PG source, operator-only disengage, fail-safe on connectivity loss) 0071-trading-kill-switch-invariants.md
0076 OpenProject is the single source of truth for project memory (extends ADR-69) 0076-openproject-single-source-of-truth.md
0077 MkDocs + Structurizr is the single source of truth for project documentation 0077-mkdocs-structurizr-single-source-of-truth-docs.md
0079 FTF sweep — results analysis, dossier, and Story closure (8-step workflow + verdict decision tree) 0079-ftf-sweep-results-analysis-and-story-closure.md
0080 FTF post-run extraction, dossier, and Story-update mechanics (operator-triggered, single-PR closure, PG = PDF source-of-truth) 0080-ftf-post-run-extraction-dossier-story-update.md
0081 Eight-state Story workflow with rituals at every gate (amends ADR-69 state model) 0081-eight-state-story-workflow-with-rituals.md
0082 Every committee session MUST be logged as an OpenProject Meeting (amends ADR-68 traceability) 0082-committee-session-logged-as-op-meeting.md
0083 Test taxonomy (12 types) + tiered gate hierarchy + canonical performance budgets (companion : documentation/strategy/CVN-N015-test-strategy.md) 0083-test-taxonomy-and-gate-hierarchy.md
0089 Training harness as plugin registry (Hamilton) — XGB / LGB / CB unified ; new model = drop a DAG file ; stacking = composition ; opt-in θ-sweep ; CVN_USE_HARNESS flag for gradual cutover 0089-training-harness-as-plugin-registry.md
0090 All training hyperparameters live in PG ftf_config (Console-only) — CVN_HPO_<MODEL>_<TF>_<PARAM> naming, canonical resolver fail-fast on missing key, fallback path emits WARN event=hpo_fallback_applied, CI grep gate G5, sharpens ADR-59 0090-training-hyperparameters-in-pg-console-only.md
0091 Console/ftf_config keys a DAG resolves MUST be guaranteed-seeded by an automated, idempotent, insert-missing-only, fail-loud deploy mechanism (Helm post-upgrade hook) — never a manual operator chore ; ADR-90 resolver fail-fast = last-line guard only ; sharpens ADR-59 / ADR-90 0091-console-keys-guaranteed-seeded-by-deploy.md
0092 DAG versioning + operator-visible build provenance (doc_md banner + DAG-list tag + first-task event=dag_loaded ; stamp file written at sync time ; CI guardrail G6) 0092-dag-versioning-and-build-provenance.md
0095 Diagnostic Stories follow the canonical 5-artifact template (hub · plan · architecture · runbook · test strategy) + pre-registered methodological invariants (pre-registration, envelope bootstrap, multiple-testing, significance-keyed decision, first-class inconclusive, no-crash, full-run input gate) ; reference = CVN-N001-EI-S05 ; operator-mandated 0095-diagnostic-story-canonical-template.md
0096 Every CPU-bound compute pod MUST cap ALL its parallelism (threads + processes) to its cgroup allocation — env-level OMP/OPENBLAS/MKL/NUMEXPR_NUM_THREADS + LOKY_MAX_CPU_COUNT + OMP_WAIT_POLICY=passive at the shared pod entrypoint (unconditional), Downward-API cgroup read, fail-loud startup assertion (incl. undeclared limit), n_jobs≠-1 joint constraint — prevents the OpenMP/BLAS/loky-in-cgroup busy-wait livelock (s42 RCA) ; proposed 0096-compute-pods-cap-thread-pools-to-cgroup.md
0097 Every experiment report MUST follow the canonical template (TEMPLATE_experiment_report.md) — front-matter → pre-registration-before-results (§3) → methods → results (effect sizes + CIs) → first-class Threats-to-Validity (§8) → Reproducibility (run ids + commit + calendar windows not indices) → Glossary/References ; reports under documentation/reports/, on the Reports nav ; active 0097-experiment-reports-follow-canonical-template.md
0098 A diagnostic/experiment MUST map the deployment regime it informs — metric (measure the deployment objective, or prove the proxy transfers) AND regime (search vs fixed-HP, calibrated vs raw, joint vs marginal) — verified by a framing §0bis read of live config at the PLAN stage, before building/running ; generalises ADR-0093 §0bis up one level ; lesson-of-record S04/s42 (AUC-on-fixed-HP didn't map prod's f1_buy search) ; active 0098-diagnostic-framing-must-map-deployment-regime.md
0099 Staged-proof architecture — existence-vs-selection boundary + inter-stage validity chains : a stage proves existence of its property (legit proxy) but MUST NOT select a config that needs the downstream objective (deferred to composition) ; each seam validates the local proxy as a faithful contributor to the economic goal (assumed transfer = defect) ; magnitude-aware sub-objectives (expectancy, not win-rate/F1) ; objective is top-level. ADR-0098 = the diagnostic-seam instance. Durable lesson of the S04 thread ; active 0099-staged-proof-existence-vs-selection-and-seam-validity.md
0100 Inter-task data transport standard — object-storage XCom backend, threshold-driven, no bespoke per-task storage. Verified (common-io 1.4.2) : the backend transports XComEncoder-JSON, not arbitrary objects (numpy fails at any size, before the threshold) ; below-threshold = byte-identical to BaseXCom (near-inert flip) ; above-threshold DB holds the path string → rollback = revert + re-trigger. Flip is proof-gated (hardened pre-flight proves provider + S3 conn + effective dotted-section config in-pod ; static+dynamic serialization audit) ; numpy/pandas → registered serializer or pass-by-reference (S02, default Y). CVN-N014-ED-S01 ; proposed 0100-xcom-objectstorage-transport-standard.md
0101 Universal Story/Epic documentation standard — the documentary structure (hub · plan [problématisation→DoD→Consolidation] · architecture · runbook · test strategy + epic doc & nav) applies to every substantial work item (objective, non-circular "substantial" trigger) ; artifacts adapted-not-empty (N/A+rationale) per an applicability matrix ; DoD = operational readiness (MLOps where ML/data, process-equivalent otherwise) ; dual enforcement CI + story-advance, advisory→blocking with a waiver contract. Generalizes the doc shape beyond diagnostics ; ADR-0095 keeps the diagnostic method add-ons. CVN-N014-EC-S17 ; proposed 0101-universal-story-epic-documentation-standard.md
0102 Tradability decision protocol (durable rules) — pre-registered, falsifiable, budget-bounded protocol producing a defensible verdict (PROMOTE / KILL tuple→family→thesis / single INFEASIBLE) and making downstream optimisation before upstream proof structurally impossible. 9 invariants: named program thesis (instance-free ADR) · switch boundary = separate Epic · strict gate chain Phase 2→6 · verdict taxonomy (no PARK ; INFEASIBLE→substrate/S03-relock/stop only) · anti-snooping (action-policy not a free retry, structural=new tuple, final-holdout one-touch+violation, siloed-exploration source, cost-retune=post-hoc) · budgets decremented · blocking registries (killed-tuple material-equivalence) · E_econ_minE_pred_min · joint sign-off + blocking risk-owner veto, no trading authority. Values live in the charter (S02 fills, S03 locks). CVN-N001-EK-S01 ; accepted 0102-tradability-decision-protocol.md