Files
KXKM_Batterie_Parallelator/plan/refactor-safety-core-web-remote-1.md
L'électron rare f55093d6fe
ESP-IDF CI / Host Tests (Unity) (push) Successful in 1m8s
CI / firmware-native (push) Successful in 2m57s
Rust Protection Tests / Cargo test (host) (push) Failing after 3m21s
ESP-IDF CI / ESP-IDF Build (v5.4) (push) Failing after 6m55s
ESP-IDF CI / Memory Budget Gate (push) Has been skipped
qa-cicd-environments / qa-kxkm-s3-build (push) Successful in 8m53s
qa-cicd-environments / qa-sim-host (push) Successful in 2m2s
qa-cicd-environments / qa-kxkm-s3-memory-budget (push) Successful in 11m17s
chore: import KXKM Batterie Parallelator
Context: the project archive (KXKM_Batterie_Parallelator-main) had
no git history locally; a fresh repository is needed to host it on
git.saillant.cc (electron/KXKM_Batterie_Parallelator).

Approach: initialize a new repo on branch main, stage the archive
content, and harden .gitignore before the first commit.

Changes:
- Import the full project tree: firmware/, firmware-idf/,
  firmware-rs/, iosApp/, kxkm-bmu-app/, kxkm-api/, hardware/,
  docs/, specs/, scripts/, models/, tests/
- Keep project dotfiles tracked despite the trailing '.*' ignore
  rule: .github/, .claude/, .superpowers/, .gitattributes,
  .markdownlint.json
- Extend .gitignore: firmware/src/credentials.h (local secrets,
  template kept), kxkm-bmu-app/**/build/ (66 MB compiled iOS
  framework), .remember/ (session data)

Impact: the project can now be maintained on the self-hosted Gitea
forge with a clean, secret-free initial history.
2026-07-04 12:32:28 +02:00

37 KiB
Raw Permalink Blame History

goal, version, date_created, last_updated, owner, status, tags
goal version date_created last_updated owner status tags
Phase 1, Phase 2, and Phase 3A Implementation Plan: Safety Core Stabilization, Web/Remote Hardening, and ML Training 1.1 2026-03-28 2026-03-30 Firmware BMU Team + ML Battery Health Team In progress
refactor
safety
security
freertos
web
esp32-s3
ml
soh
rul
quantization

Introduction

Status: In progress

This plan updates the existing BMU implementation plan by keeping Phase 1 (runtime safety) and Phase 2 (web/remote hardening) and adding Phase 3A (ML data quality, SOH retraining, RUL training, and edge quantization). The intent is deterministic execution with measurable gates and no impact on hard safety authority in firmware.

1. Requirements & Constraints

  • REQ-001: Battery protection state decisions must remain 100% local on MCU and must not depend on cloud connectivity.
  • REQ-002: Switching operations must use a single validated control path and preserve existing threshold protections.
  • REQ-003: All I2C interactions must remain serialized with I2CLockGuard from src/I2CMutex.h.
  • REQ-004: Web mutation routes must require authentication before executing switch operations.
  • REQ-005: Battery index parsing for mutation routes must be strict and bounds-checked.
  • REQ-006: SOH training default must use device-independent proxy mode (--soh-mode=capacity) in scripts/ml/train_fpnn.py.
  • REQ-007: Quantized model output must be < 50 KB hard limit and target < 33 KB preferred edge budget.
  • SEC-001: Do not introduce unauthenticated battery mutation paths.
  • SEC-002: Do not relax voltage/current/reconnect/topology safety checks.
  • SEC-003: Mutation endpoints must include abuse protection (rate limiting) and auditability.
  • SEC-004: ML outputs remain advisory and must not replace firmware protection state machines.
  • CON-001: Keep FreeRTOS task loops non-blocking; avoid long blocking calls in periodic loops.
  • CON-002: Preserve compatibility with pio run -e kxkm-s3-16MB and existing kxkm-v3-16MB behavior.
  • CON-003: If TensorFlow Lite backend is unavailable, ONNX Runtime quantization is mandatory fallback.
  • GUD-001: Use existing DebugLogger categories for observability instead of ad-hoc serial prints.
  • PAT-001: Implement changes as small, verifiable increments with build validation after each increment.

2. Implementation Steps

Implementation Phase 1

  • GOAL-001: Stabilize local safety runtime by reducing failure propagation in task execution and I2C communication paths.
Task Description Completed Date
TASK-001 Add task watchdog integration in src/main.cpp using esp_task_wdt_init, task registration, and periodic esp_task_wdt_reset. ✅ 2026-03-28
TASK-002 Add shared I2C failure counter and recovery threshold helpers in src/I2CMutex.h. ✅ 2026-03-28
TASK-003 Integrate conditional I2C recovery in src/INA_NRJ_lib.cpp on lock failures and repeated sensor errors using i2cBusRecovery. ✅ 2026-03-28
TASK-004 Integrate conditional I2C recovery in src/TCA_NRJ_lib.cpp on lock failures for read/write paths. ✅ 2026-03-28
TASK-005 Add runtime validation task for brownout handling policy in src/main.cpp (restart-loop detection and safe-mode trigger gate). ✅ 2026-03-28
TASK-006 Add shared-state confinement for battery runtime structures in src/BatteryParallelator.cpp and src/main.cpp. ✅ 2026-03-28
TASK-007 Validate Phase 1 by building kxkm-s3-16MB and capturing memory guardrail output. ✅ 2026-03-28

Implementation Phase 2

  • GOAL-002: Harden web/remote mutation surface with strict auth, strict input validation, abuse resistance, and audit logging.
Task Description Completed Date
TASK-008 Enforce mutation auth guard in src/WebServerHandler.cpp for /switch_on and /switch_off. ✅ 2026-03-28
TASK-009 Enforce strict battery argument parsing and bounds validation in src/WebServerHandler.cpp via parseBatteryIndex. ✅ 2026-03-28
TASK-010 Add request-level rate limiting for mutation routes in src/WebServerHandler.cpp with deterministic HTTP 429 responses. ✅ 2026-03-28
TASK-011 Add structured audit log entries for every mutation attempt in src/WebServerHandler.cpp. ✅ 2026-03-28
TASK-012 Add token hardening in src/WebRouteSecurity.cpp with constant-time compare and empty-token rejection tests. ✅ 2026-03-28
TASK-013 Extend tests in test/test_battery_route_validation/test_main.cpp and test/test_web_route_security/test_main.cpp for malformed inputs and rate-limit boundaries. ✅ 2026-03-28
TASK-014 Build validation after Phase 2 changes with pio run -e kxkm-s3-16MB and no new compile errors. ✅ 2026-03-28

Implementation Phase 3

  • GOAL-003: Execute Phase 3A ML training hardening with deterministic SOH/RUL outputs and edge-compatible artifacts.
Task Description Completed Date
TASK-015 Create scripts/ml/analyze_features.py to compute NaN rates, per-device distribution shift (KS), and SOH proxy suitability. ✅ 2026-03-28
TASK-016 Execute feature audit and lock decision: default SOH proxy is capacity, not rest_voltage. ✅ 2026-03-28
TASK-017 Update scripts/ml/train_fpnn.py default --soh-mode from voltage to capacity. ✅ 2026-03-28
TASK-018 Apply Ah_discharge > 0.1 guard in scripts/ml/extract_features.py for coulombic_efficiency stability. ✅ 2026-03-28
TASK-019 Add NaN filtering gate in scripts/ml/adapt_features.py before training export. ✅ 2026-03-28
TASK-020 Retrain FPNN with python scripts/ml/train_fpnn.py --input models/features_adapted.parquet --output-dir models --epochs 50 --hidden 64 --degree 2 --soh-mode capacity. ✅ 2026-03-28
TASK-021 Quantize FPNN with ONNX Runtime backend and verify quality/size gates. ✅ 2026-03-28
TASK-022 Create scripts/ml/create_rul_labels_v2.py and generate models/features_with_rul.parquet. ✅ 2026-03-28
TASK-023 Train SambaMixer with python scripts/ml/train_sambamixer.py --input models/features_with_rul.parquet --output models/rul_sambamixer.pt --epochs 20 --d-model 64 --n-layers 3 --lr 1e-3. ✅ 2026-03-28
TASK-024 Close regeneration loop: rebuild features from corrected extractor to models/features_v2.parquet, adapt/retrain/re-evaluate, and produce final models/phase2_metrics.json. ✅ 2026-03-29

Implementation Phase 4

  • GOAL-004: Fix critical audit findings from 2026-03-30 security audit before S3 hardware validation.
Task Description Completed Date
TASK-040 Fix unit mismatch (CRIT-A): normalize BATTParallelator threshold storage to mV/mA, remove double-conversion in main.cpp setters. ⬜
TASK-041 Fix imbalance check (CRIT-B): is_difference_acceptable() must compare against live fleet max voltage from find_max_voltage(), not config ceiling. ⬜
TASK-042 Fix deadlock (CRIT-C): remove outer I2CLockGuard in validateBatteryVoltageForSwitch() — read_volt() already acquires its own lock. ⬜
TASK-043 Fix web auth (CRIT-D): change mutation routes to POST, wire auth token in JS client, add #warning when BMU_WEB_ADMIN_TOKEN is empty. ⬜
TASK-044 Fix negative overcurrent (HIGH-1): use fabs(current) in ERROR handler overcurrent check. ⬜
TASK-045 Fix task self-deletion (HIGH-8): replace return with continue in timeAndInfluxTask SD failure path. ⬜
TASK-046 Fix I2C speed locking (HIGH-5): wrap setI2CSpeed() Wire.setClock in I2CLockGuard. ⬜
TASK-047 Implement permanent lockout (MED-1): add explicit lock when nb_switch > nbSwitchMax in check_battery_connected_status(). ⬜
TASK-048 Make battery_voltages[] private (HIGH-7): enforce mutex discipline by removing public access. ⬜
TASK-049 Update tests: align thresholds with config.h (10A), add negative overcurrent + permanent lock + fleet imbalance tests. ⬜
TASK-050 Validate Phase 4: pio test -e sim-host all pass + pio run -e kxkm-s3-16MB builds. ⬜

3. Alternatives

  • ALT-001: Implement Phase 2 before Phase 1. Not chosen because runtime instability increases rollout risk.
  • ALT-002: Introduce cloud-authorized switching gate. Not chosen because requirement mandates local-only switching authority.
  • ALT-003: Add broad refactor across all modules in one change set. Not chosen to avoid high regression risk in safety-critical firmware.
  • ALT-004: Keep voltage-only SOH proxy as default. Not chosen due high NaN and poor cross-device transfer.
  • ALT-005: Wait for TensorFlow Lite support on Python 3.14 before quantization. Not chosen because ONNX Runtime INT8 already meets constraints.

4. Dependencies

  • DEP-001: ESP32 Arduino support for task watchdog (esp_task_wdt.h) in current framework.
  • DEP-002: Existing mutex infrastructure in src/I2CMutex.h must remain authoritative for Wire bus access.
  • DEP-003: Existing web stack (ESPAsyncWebServer) and route wiring in src/WebServerHandler.cpp.
  • DEP-004: Existing strict battery parser helper in src/BatteryRouteValidation.cpp.
  • DEP-005: Existing route security helper in src/WebRouteSecurity.cpp.
  • DEP-006: Python ML environment ml_venv with pandas, numpy, torch, scipy, pyarrow, onnxruntime.
  • DEP-007: Existing ML scripts in scripts/ml/ (extract_features.py, adapt_features.py, train_fpnn.py, train_sambamixer.py, quantize_tflite.py).
  • DEP-008: Canonical dataset artifact models/consolidated.parquet.

5. Files

  • FILE-001: src/main.cpp — task watchdog, brownout/restart-loop gate (pending), runtime safety orchestration.
  • FILE-002: src/I2CMutex.h — I2C failure counters and recovery threshold helpers.
  • FILE-003: src/INA_NRJ_lib.cpp — I2C recovery trigger in INA read paths.
  • FILE-004: src/TCA_NRJ_lib.cpp — I2C recovery trigger in TCA lock-failure read/write paths.
  • FILE-005: src/WebServerHandler.cpp — auth guard, strict validation, pending rate limit, pending audit logs.
  • FILE-006: src/WebRouteSecurity.cpp — token authorization hardening.
  • FILE-007: src/BatteryRouteValidation.cpp — strict mutation input parsing.
  • FILE-008: test/test_battery_route_validation/test_main.cpp — parser validation tests.
  • FILE-009: test/test_web_route_security/test_main.cpp — route security tests.
  • FILE-010: scripts/ml/analyze_features.py — feature audit and proxy selection checks.
  • FILE-011: scripts/ml/extract_features.py — coulombic efficiency threshold guard.
  • FILE-012: scripts/ml/adapt_features.py — NaN filtering and schema adaptation.
  • FILE-013: scripts/ml/train_fpnn.py — SOH proxy mode and retraining flow.
  • FILE-014: scripts/ml/create_rul_labels_v2.py — RUL label generation.
  • FILE-015: scripts/ml/train_sambamixer.py — RUL model training.
  • FILE-016: models/fpnn_soh_v2_quantized.onnx — edge-ready quantized SOH model.
  • FILE-017: models/rul_sambamixer.pt — trained RUL model artifact.

6. Testing

  • TEST-001: Compile test pio run -e kxkm-s3-16MB must succeed after each firmware increment.
  • TEST-002: Mutation route auth test: unauthorized calls must return HTTP 403.
  • TEST-003: Battery parameter validation test: malformed/out-of-range arguments must return HTTP 400.
  • TEST-004: I2C recovery threshold test: force repeated lock failures and verify recovery path triggers without deadlock.
  • TEST-005: Watchdog liveness test: simulate stalled task and verify watchdog reset behavior.
  • TEST-006: Rate limit test (Phase 2 pending): repeated mutation attempts beyond threshold must return HTTP 429.
  • TEST-007: Audit log test (Phase 2 pending): every mutation attempt emits a structured log entry with deterministic fields.
  • TEST-008: FPNN SOH quality gate: test MAPE <= 15% on device-split evaluation.
  • TEST-009: Quantization gate: INT8 artifact size < 50 KB and degradation < 5pp MAPE.
  • TEST-010: RUL label gate: coverage equals total rows for selected dataset.
  • TEST-011: SambaMixer gate: checkpoint exists and validation converges before early stop.

7. Risks & Assumptions

  • RISK-001: Watchdog timeout set too low can cause false resets under transient load spikes.
  • RISK-002: Aggressive I2C recovery can mask intermittent hardware faults if not paired with alerts.
  • RISK-003: Rate limiting can block legitimate maintenance operations if thresholds are misconfigured.
  • RISK-004: Synthetic RUL can overestimate remaining life on sparse discharge segments.
  • RISK-005: Regenerated feature pass can shift distribution and require metric re-baselining.
  • ASSUMPTION-001: Existing deployment keeps BMU_WEB_ADMIN_TOKEN configured where remote mutation is required.
  • ASSUMPTION-002: Current hardware wiring allows safe i2cBusRecovery sequence.
  • ASSUMPTION-003: Brownout implementation details may require additional board-specific validation.
  • ASSUMPTION-004: ONNX Runtime remains available in ml_venv for static INT8 quantization.
  • AGENTS.md
  • .github/instructions/firmware-safety.instructions.md
  • .github/instructions/ml-pipeline.instructions.md
  • CLAUDE.md
  • platformio.ini
  • docs/ml-battery-health-spec.md
  • src/main.cpp
  • src/BatteryParallelator.cpp
  • src/WebServerHandler.cpp
  • scripts/ml/train_fpnn.py
  • scripts/ml/train_sambamixer.py

Execution Update — 2026-03-28 (Phase 2 Web Hardening)

  • TASK-010: ✅ Completed — deterministic mutation rate limit in src/WebServerHandler.cpp with HTTP 429 path.
  • TASK-011: ✅ Completed — structured mutation audit logs for route/battery/source/outcome/timestamp in src/WebServerHandler.cpp.
  • TASK-012: ✅ Completed — token hardening (constant-time compare + empty-token rejection) in src/WebRouteSecurity.cpp and tests.
  • TASK-013: ✅ Completed — malformed-input tests extended and new rate-limit boundary tests added in test/test_web_mutation_rate_limit/test_main.cpp.
  • TASK-014: ✅ Completed — build validation passed for kxkm-s3-16MB.

Evidence

  • pio test -e sim-host: PASSED, including test_web_mutation_rate_limit.
  • pio run -e kxkm-s3-16MB: SUCCESS (RAM 8.2%, Flash 29.1%).

Files Updated

  • src/WebServerHandler.cpp
  • src/WebMutationRateLimit.h
  • src/WebMutationRateLimit.cpp
  • test/test_web_mutation_rate_limit/test_main.cpp
  • platformio.ini

Execution Update — 2026-03-28 (Phase 1 Runtime Safety, lot TASK-005)

  • TASK-005: ✅ Implémenté dans src/main.cpp avec détection de boucle de redémarrage (brownout + resets critiques WDT/panic), activation du safe-mode sur seuil, et remise à zéro des compteurs après fenêtre de stabilité.
  • Politique conservatrice: le safe-mode reste verrouillé jusqu’au reboot (pas de relâchement automatique en runtime).

Evidence

  • pio run -e kxkm-s3-16MB: SUCCESS.
  • pio test -e sim-host: PASSED (6 suites).

Files Updated

  • src/main.cpp

Execution Update — 2026-03-28 (Phase 1 Runtime Safety, lot TASK-006)

  • TASK-006: ✅ Implémenté sur src/BatteryParallelator.cpp et src/BatteryParallelator.h pour renforcer le confinement d’état partagé.
  • Ajouts: helper lockState(...), verrouillage des setters de configuration, validation d’index dans check_battery_connected_status, et suppression d’un état mutable non nécessaire dans find_max_voltage.

Evidence

  • pio run -e kxkm-s3-16MB: SUCCESS.
  • pio test -e sim-host: PASSED (6 suites).

Files Updated

  • src/BatteryParallelator.h
  • src/BatteryParallelator.cpp

Execution Update — 2026-03-28 (Phase 1 Memory Guardrail re-check)

  • Build budget revalidé après TASK-006 via scripts/check_memory_budget.sh --env kxkm-s3-16MB --ram-max 75 --flash-max 85.

Evidence

  • RAM: 8.2% (max 75%)
  • Flash: 29.1% (max 85%)
  • Budget check: PASSED

Execution Update — 2026-03-29 (Phase 3A, TASK-024 regeneration loop)

  • TASK-024: ▶️ Exécuté end-to-end (régénération + adaptation + réentraînement + quantification + métriques finales), mais non clôturé car gate qualité SOH en échec.
  • Statut opérationnel: blocked sur qualité modèle FPNN (pas sur pipeline).

Actions exécutées

  • python scripts/ml/extract_features.py --input models/consolidated.parquet --output models/features_v2.parquet --window 60 --log-level INFO
  • python scripts/ml/adapt_features.py --input models/features_v2.parquet --output models/features_adapted_v2.parquet
  • python scripts/ml/train_fpnn.py --input models/features_adapted_v2.parquet --output-dir models --epochs 50 --hidden 64 --degree 2 --soh-mode capacity
  • python scripts/ml/quantize_tflite.py --model models/fpnn_soh.pt --features models/features_adapted_v2.parquet --output models/fpnn_soh_v2_quantized.onnx --backend onnxrt
  • python scripts/ml/create_rul_labels_v2.py --input models/features_adapted_v2.parquet --output models/features_with_rul.parquet
  • python scripts/ml/train_sambamixer.py --input models/features_with_rul.parquet --output models/rul_sambamixer.pt --epochs 20 --d-model 64 --n-layers 3 --lr 1e-3
  • python scripts/ml/finalize_phase2_metrics.py --features models/features_adapted_v2.parquet --quantized models/fpnn_soh_v2_quantized.onnx --rul-model models/rul_sambamixer.pt --train-log phase2_fpnn_train_v2.log --output models/phase2_metrics.json

Evidence

  • Artefact final: models/phase2_metrics.json (overall_gate_pass: false)
  • Gate KO: fpnn_mape_le_15 = false (MAPE test ≈ 43.54%)
  • Gates OK: quantized_size_lt_50kb = true (15.98 KB), quantized_mape_degradation_le_5pp = true (3.95 pp)

Blocker + Next Action

  • Blocker: split/device drift fort sur dataset régénéré v2, entraînant une généralisation insuffisante.
  • Next Action prioritaire: lancer une passe d’analyse de drift sur features_adapted_v2.parquet, puis retuner split/pondération device et réentraîner FPNN jusqu’au retour sous MAPE 15%.

Execution Update — 2026-03-29 (TASK-024 closure after ML split/data fix)

  • TASK-024: ✅ Closed — regeneration loop completed with updated adaptation filter and improved device-aware split for FPNN training.
  • Implemented fixes:
  • scripts/ml/adapt_features.py: removed unnecessary NaN drop on coulombic_efficiency (not used by FPNN features), kept critical NaN drop on R_internal.
  • scripts/ml/train_fpnn.py: updated split to train on multiple devices with deterministic validation carve-out and configurable --test-device / --val-ratio.

Evidence

  • python scripts/ml/adapt_features.py --input models/features_v2.parquet --output models/features_adapted_v2.parquet -> rows: 405,201
  • python scripts/ml/train_fpnn.py --input models/features_adapted_v2.parquet --output-dir models --epochs 50 --hidden 64 --degree 2 --soh-mode capacity --test-device k-led1 --val-ratio 0.1 -> Test MAPE ~2.44%
  • python scripts/ml/quantize_tflite.py --model models/fpnn_soh.pt --features models/features_adapted_v2.parquet --output models/fpnn_soh_v2_quantized.onnx --backend onnxrt -> quantized size ~16.0 KB, degradation ~0.05 pp
  • python scripts/ml/finalize_phase2_metrics.py --features models/features_adapted_v2.parquet --quantized models/fpnn_soh_v2_quantized.onnx --rul-model models/rul_sambamixer.pt --train-log phase2_fpnn_train_v2.log --output models/phase2_metrics.json -> overall_gate_pass: true

Audit Quotidien — 2026-03-29

Portée auditée: plan/refactor-safety-core-web-remote-1.md (avec recoupement plan/process-cicd-environments-1.md).

1. Résumé journalier (5 lignes max)

  • Phase 1, Phase 2 et Phase 3A sont techniquement exécutées et validées côté local.
  • Le gate ML final de TASK-024 est repassé au vert (overall_gate_pass=true).
  • Le principal reste à faire est la preuve distante GitHub Actions par environnement (process CI/CD).
  • La cohérence matrice/execution updates est globalement bonne après synchronisation.
  • Quelques lignes descriptives marquées pending dans les sections statiques nécessitent alignement éditorial.

2. Tableau TODO normalisé

TODO ID Item Statut Priorité Evidence Next Action
TODO-001 Clôturer la preuve CI distante multi-environnements in-progress P0 scripts/ci/run_qa_all.sh local PASS; cellule 2 de plan/process-cicd-environments-1.md Déclencher workflow_dispatch sur .github/workflows/sim-host-tests.yml puis archiver les liens de runs dans plan/process-cicd-environments-1.md.
TODO-002 Aligner les sections statiques pending du plan principal (Files/Testing wording) avec l’état réel not-started P2 Matrice TASK-010..014 et TASK-024 en ✅ dans cellule 1 de ce plan Éditer la section Files pour retirer pending obsolètes et refléter l’état implémenté.
TODO-003 Consolider les métriques ML finales dans un seul point de vérité completed P1 models/phase2_metrics.json (overall_gate_pass=true, fpnn_mape=2.3716) Aucune action. Maintenir ce fichier comme artefact de référence.
TODO-004 Capturer preuve CI distante dans le plan principal (pas seulement plan process) not-started P1 UNKNOWN Ajouter une section Execution Update dédiée une fois les runs GitHub Actions terminés.

3. Blocages et dépendances

  • Blocage principal: absence de preuve distante CI GitHub Actions (dépend d’un déclenchement push/PR ou workflow_dispatch).
  • Dépendance: accès GitHub Actions et exécution réussie de .github/workflows/sim-host-tests.yml.
  • Dépendance: conservation des artefacts/logs de run pour traçabilité plan.

4. Check de cohérence

  • Manques de preuve: TODO-004 contient UNKNOWN (aucun lien de run distant encore collecté).
  • Statuts incohérents: aucun blocage critique technique détecté; l’incohérence restante est documentaire (preuves distantes manquantes).
  • TODO sans Next Action: aucun.
  • Déduplication: les actions CI distantes sont regroupées en TODO-001 pour éviter doublons avec le plan process.

5. Proposition de patch du fichier cible

  • Patch appliqué: ajout de cette section Audit Quotidien — 2026-03-29 dans plan/refactor-safety-core-web-remote-1.md.
  • Étape suivante recommandée: compléter TODO-001 avec liens de runs GitHub Actions puis marquer completed.

Execution Update — 2026-03-30 (synthese analyses et backlog de correction)

  • Revue surete firmware executee: aucun Critical, plusieurs High detectes sur surface web mutatrice et chemins I2C.
  • Revue QA executee: couverture locale partielle validee, mais gate distante et alignement de branche encore incomplets.
  • Ajout des documents de cadrage pour execution continue:
    • docs/governance/integration.md
    • docs/governance/architecture-diagrams.md
    • docs/governance/feature-map.md
    • docs/governance/agent-task-assignment.md

Prioritized Backlog (issue-ready)

ID Priority Action Owner Status
R-001 P0 Corriger le chemin web mutateur expose (auth token en query/GET) SWE + SE: Security planned
R-002 P0 Aligner workflows QA sur branche par defaut et produire preuve distante QA Gate + SE: DevOps/CI in-progress
R-003 P1 Couvrir WebServerHandler mutateur par tests integration host SWE planned
R-004 P1 Clarifier env sim-host vs native dans pipeline et docs QA Gate in-progress
R-005 P1 Executer script snapshot contexte a chaque lot merge SE: Tech Writer in-progress

Evidence

  • Findings issus des agents BMU Safety Review, QA Gate et Explore integres dans les documents de gouvernance et de planification.
  • README deja aligne avec image PCB et liens de pilotage en cours de mise a jour.

Audit Quotidien — 2026-03-30 (normalise)

Portee auditee: plan/refactor-safety-core-web-remote-1.md.

1. Resume journalier (5 lignes max)

  • Les lots critiques firmware (CRIT-001..004) sont traites en local et pousses sur main.
  • Les points HIGH-005/HIGH-006 ont ete corriges en local avec validation pio test -e sim-host reussie.
  • Le README est partiellement normalise mais reste en cours de finalisation/commit separe.
  • Le build kxkm-s3-16MB progresse: dependances C/C++ resolues, blocage residuel environnement Python (intelhex) sur generation bootloader.bin.
  • La preuve CI distante GitHub Actions reste le principal ecart de cloture.

2. Tableau TODO normalise

TODO ID Item Statut Priorite Evidence Next Action
TODO-001 Cloturer preuve CI distante multi-environnements in-progress P0 scripts/ci/run_qa_all.sh local PASS; aucune URL de run distante archivee Declencher workflow_dispatch sur .github/workflows/sim-host-tests.yml puis archiver les URLs dans ce plan.
TODO-002 Finaliser et pousser le lot HIGH-005/HIGH-006 (concurrence web/protection) in-progress P0 Modifs locales sur firmware/src/WebServerHandler.cpp, firmware/src/INAHandler.{h,cpp}, firmware/src/BatteryParallelator.cpp; pio test -e sim-host PASS Committer/pusher ce lot avec message dedie puis lier le hash ici.
TODO-003 Retablir build pio run -e kxkm-s3-16MB de bout en bout blocked P0 Sortie build: dependances C/C++ resolues; echec restant ModuleNotFoundError: No module named 'intelhex' depuis tool-esptoolpy Corriger l'environnement Python PlatformIO utilise par esptool.py et relancer pio run -e kxkm-s3-16MB.
TODO-004 Nettoyer/finaliser README.md et pousser commit separe in-progress P1 README mis a jour partiellement (status/audit/config), statut git local encore modifie Faire revue finale README, commit dedie docs, puis push.
TODO-005 Aligner wording historique src/ vs firmware/src/ dans sections statiques du plan not-started P2 Sections Requirements/Files/Testing contiennent encore des chemins historiques Normaliser toutes references de chemins vers l'arborescence post-migration.

3. Blocages et dependances

  • Blocage principal: preuve CI distante absente (dependance acces GitHub Actions + conservation liens de run).
  • Blocage build cible: environnement Python appele par esptool.py ne charge pas intelhex au moment de la generation bootloader.
  • Dependances techniques: availability des libs PlatformIO deja ajoutees (INA226, PubSubClient, NTPClient, InfluxDB, WebSockets, ArduinoJson, ESP_SSLClient).

4. Check de coherence

  • Manques de preuve: TODO-001 et TODO-003 n'ont pas encore de preuve distante/definitive (build S3 complet).
  • Statuts incoherents detectes: backlog R-* utilise planned; tableau TODO normalise utilise not-started/in-progress/blocked/completed.
  • TODO sans Next Action: aucun.
  • Dedupe: actions CI distantes regroupees sous TODO-001; corrections concurrence regroupees sous TODO-002.

5. Proposition de patch du fichier cible

  • Patch propose/applique: ajout de cette section Audit Quotidien — 2026-03-30 (normalise).
  • Etape suivante recommandee: cloturer TODO-002 et TODO-004 par commit/push, puis lever TODO-003 (build S3 complet) avant cloture globale.

Hypotheses

  • Le parametre ${input:Chemin du fichier plan} n'etant pas explicitement fourni, la normalisation a ete appliquee au plan principal plan/refactor-safety-core-web-remote-1.md.

Execution Update — 2026-03-30 (kxkm-ai containers verification + implementation)

  • Verification SSH OK sur kxkm@kxkm-ai.
  • Inventaire conteneurs existants effectue (dont mascarade-platformio, mascarade-core, mascarade-api).
  • Implementation P0 realisee: script d'orchestration conteneur existant ajoute et valide localement:
    • scripts/ml/remote_kxkm_ai_pipeline.sh
    • modes ajoutes: check, bootstrap-container, run-container
  • Bootstrap dans conteneur existant reussi (SYNC_OK) avec synchro du repo dans /workspace/KXKM_Batterie_Parallelator.
  • Dependances ML installees dans mascarade-platformio via pip (numpy, pandas, pyarrow, onnxruntime, torch).

Evidence

  • scripts/ml/remote_kxkm_ai_pipeline.sh check -> HOST OK + liste conteneurs.
  • scripts/ml/remote_kxkm_ai_pipeline.sh bootstrap-container -> check deps + SYNC_OK.
  • scripts/ml/remote_kxkm_ai_pipeline.sh run-container -> execution demarree puis blocage explicite:
    • BLOCKED: models/consolidated.parquet is missing in container workspace
  • Verification dataset logs dans conteneur:
    • find hardware/log-sd -name "*.csv" -> CSV_COUNT=0.

TODO normalises (delta)

TODO ID Item Statut Priorite Evidence Next Action
TODO-006 Rendre le pipeline ML executable dans conteneur existant mascarade-platformio in-progress P0 Script + bootstrap + deps installes Fournir/synchroniser models/consolidated.parquet ou source CSV versionnee, puis relancer run-container.
TODO-007 Verifier et verrouiller la source de dataset distante blocked P0 models/consolidated.parquet absent, hardware/log-sd absent Definir chemin dataset canonique sur kxkm-ai et l'injecter dans /workspace/KXKM_Batterie_Parallelator/models/.

Hypotheses

  • Le conteneur mascarade-platformio est la cible valide pour les jobs ML batch sur kxkm-ai.
  • Les donnees d'entrainement ne sont pas versionnees dans ce repo et doivent etre injectees par artefact externe.

Execution Update — 2026-03-30 (dataset unblock tooling on existing container)

  • Lot prioritaire implemente pour lever le blocage dataset sans creer de nouveau conteneur.
  • Script scripts/ml/remote_kxkm_ai_pipeline.sh etendu avec:
    • discover-dataset
    • inject-dataset --dataset-path <abs_path_on_kxkm-ai>
  • Verification executee sur mascarade-platformio:
    • aucun consolidated.parquet trouve cote hote
    • dataset toujours absent dans /workspace/KXKM_Batterie_Parallelator/models/

Evidence

  • scripts/ml/remote_kxkm_ai_pipeline.sh discover-dataset
    • CONTAINER_DATASET_MISSING:/workspace/KXKM_Batterie_Parallelator/models/consolidated.parquet
  • ssh kxkm@kxkm-ai 'find /home/kxkm -type f -name "*.parquet"'
    • uniquement des fichiers de test pyarrow, aucun dataset metier consolidated.parquet
  • scripts/ml/remote_kxkm_ai_pipeline.sh run-container
    • BLOCKED: models/consolidated.parquet is missing in container workspace

TODO normalises (delta)

TODO ID Item Statut Priorite Evidence Next Action
TODO-006 Pipeline ML sur conteneur existant mascarade-platformio in-progress P0 Orchestrateur complet (check/bootstrap-container/run-container/discover-dataset/inject-dataset) Injecter le dataset via inject-dataset des que le chemin source est connu.
TODO-007 Source dataset canonique sur kxkm-ai blocked P0 Recherche hote negative pour consolidated.parquet; conteneur sans dataset Identifier le chemin dataset metier (ou artefact externe) puis relancer run-container.

Hypotheses (delta)

  • Le dataset metier est stocke hors /home/kxkm (volume externe, partage reseau, ou artefact CI).
  • Une fois chemin fourni, l'injection dans conteneur existant est immediate via inject-dataset.

Audit Quotidien — 2026-03-30 (delta implementation start)

1. Resume journalier (5 lignes max)

  • Demarrage implementation confirme sur lot P0 gouvernance + cloud/containers.
  • Verification SSH/containers kxkm-ai validee, orchestration remote operationnelle.
  • Blocage critique maintenu: dataset models/consolidated.parquet absent dans le conteneur cible.
  • Le plan est mis a jour avec preuves runtime fraiches et actions immediates.
  • Les diagrammes architecture ont ete regeneres pour enlever la corruption documentaire.

2. Tableau TODO normalise (delta)

TODO ID Item Statut Priorite Evidence Next Action
TODO-001 Cloturer preuve CI distante multi-environnements blocked P0 Aucune URL run distante archivee dans ce plan a date Pousser workflow sur branche par defaut, declencher run, archiver URL + statut.
TODO-006 Pipeline ML conteneur existant mascarade-platformio in-progress P0 check OK, discover-dataset -> CONTAINER_DATASET_MISSING, run-container bloque sur dataset manquant Injecter le dataset via inject-dataset --dataset-path <abs_path_on_kxkm-ai> puis relancer run-container.
TODO-007 Source dataset canonique sur kxkm-ai blocked P0 Recherche negative de consolidated.parquet sur chemins usuels hote/conteneur Identifier et documenter le chemin dataset canonique, puis injecter dans /workspace/KXKM_Batterie_Parallelator/models/.

3. Blocages et dependances

  • Blocage P0-Data: absence du dataset consolidated.parquet dans la cible conteneur.
  • Blocage P0-CI: preuve CI distante non capturee (runs URL manquants).

4. Check de coherence

  • Statuts harmonises: TODO CI passe explicitement en blocked (plus in-progress).
  • TODO sans Next Action: aucun.
  • Evidence UNKNOWN: retiree du delta courant, remplacee par constats verifiables.

5. Proposition de patch du fichier cible

  • Patch applique: ajout de ce delta Audit Quotidien — 2026-03-30 (delta implementation start).

Execution Update — 2026-03-30 (kxkm-ai run-container unblocked, quality gate failed)

  • Le pipeline distant dans mascarade-platformio execute maintenant jusqu'aux artefacts finaux sur le dataset present dans le conteneur.
  • Le correctif racine a ete applique: installation du package onnx dans le conteneur puis ajout du controle onnx dans scripts/ml/remote_kxkm_ai_pipeline.sh pour eviter la regression au bootstrap.
  • Le blocage restant est un gate qualite sur la quantization, pas un blocage infra ou dataset.

Evidence

  • scripts/ml/remote_kxkm_ai_pipeline.sh run-container -> lecture 42,528,590 lignes, generation features_v2.parquet, features_adapted_v2.parquet, entrainement FPNN termine.
  • Echec intermediaire leve: torch.onnx.OnnxExporterError: Module onnx is not installed!.
  • Relance ciblee quantization/finalize -> artefacts distants a 2026-03-30 15:50 UTC:
    • models/fpnn_soh_v2_quantized.onnx -> 16.0 KB
    • models/phase2_metrics.json -> overall_gate_pass=false
  • Metriques finales du run distant:
    • float32 MAPE 7.7289%
    • quantized MAPE 14.2045%
    • degradation +6.4756 pp
    • gate KO: quantized_mape_degradation_le_5pp=false

TODO normalises (delta)

TODO ID Item Statut Priorite Evidence Next Action
TODO-006 Rendre le pipeline ML executable dans conteneur existant mascarade-platformio completed P0 run-container execute jusqu'aux artefacts finaux Aucune. Maintenir le check onnx au bootstrap.
TODO-007 Verifier et verrouiller la source de dataset distante completed P0 dataset visible sur l'hote puis dans /workspace/KXKM_Batterie_Parallelator/models/ Aucune. Documenter le chemin canonique dans le runbook.
TODO-008 Faire repasser le gate qualite quantization sur le dataset distant actuel blocked P0 models/phase2_metrics.json distant: overall_gate_pass=false Tester calibration stricte (stratified, percentiles) et comparer qdq vs qoperator.

Blocker + Next Action

  • Blocker: la degradation quantization depasse le seuil autorise sur le split distant courant.
  • Next Action prioritaire: lancer une matrice courte d'experiences de quantization avec nouveaux paramètres explicites, puis conserver le meilleur run sous seuil.

Execution Update — 2026-03-30 (quantization iteration 1 passed)

  • Premiere iteration qualite executee sur kxkm-ai avec la configuration suivante: qdq + calibration stratified + 500 echantillons + clipping 1 99.
  • Cette configuration est promue comme nouveau baseline distant car elle fait repasser tous les gates.

Evidence

  • python3 scripts/ml/quantize_tflite.py --model models/fpnn_soh.pt --features models/features_adapted_v2.parquet --output models/fpnn_soh_v2_quantized.onnx --backend onnxrt --quant-format qdq --calib-strategy stratified --calib-samples 500 --percentile-clip 1 99
  • python3 scripts/ml/finalize_phase2_metrics.py --features models/features_adapted_v2.parquet --quantized models/fpnn_soh_v2_quantized.onnx --rul-model models/rul_sambamixer.pt --train-log phase2_fpnn_train_v2.log --output models/phase2_metrics.json --gate-fpnn-mape-max 15 --gate-quantized-mape-max 15 --gate-quantized-size-max-kb 50 --gate-quantized-mape-degradation-max-pp 5
  • Artefacts distants promus a 2026-03-30 16:17 UTC:
    • models/fpnn_soh_v2_quantized.onnx -> 15.99 KB
    • models/phase2_metrics.json -> overall_gate_pass=true
  • Metriques finales promues:
    • float32 MAPE 7.7289%
    • quantized MAPE 10.7734%
    • degradation +3.0446 pp

TODO normalises (delta)

TODO ID Item Statut Priorite Evidence Next Action
TODO-008 Faire repasser le gate qualite quantization sur le dataset distant actuel completed P0 models/phase2_metrics.json distant: overall_gate_pass=true Aucune. Conserver cette configuration comme baseline et seulement explorer mieux en lot distinct.