docs: la trace du partage EV_GRID_START, verbatim, pour l'agent app

Il ne peut pas produire ce régime sur le banc : pluggedIn est en lecture seule,
aucune action RPC ne l'écrit, et sans assignedCarId la borne reste hors loads[].
Le partage est une propriété du CODE, pas du matériel — le banc n'ajouterait que
la confirmation que le binaire arm64 fait pareil.

La charge utile de testEvGridStartIsAnnouncedAndBounded est donc reproduite telle
quelle dans le brief, avec son critère vérifiable ligne à ligne :

  params.budgetW 900 → counts["budget.allocatedW"] 900 → budget.allocatedW 900
  params.gridW   480 → counts["draw.committedW"]   480 → draw.committedW   480
  Σ counts = 1380 == targetW == allocatedW

Les deux moitiés sont dans les deux compteurs, et les deux compteurs sont de même
nature. budget.evReservedW vaut 0 : il ne reçoit plus de tranche d'allocation, il
est redevenu la correction de latence qu'il a toujours été.

La seconde borne de la trace montre l'autre moitié de la règle — targetW: 0 avec
counts PRÉSENT et sa destination à zéro. C'est le cas le plus fréquent, celui
qu'un counts vide aurait perdu.

+etm32 est posé sur .75 et l'identité s'y vérifie sur des données réelles : Σ
counts[budget.allocatedW] = 1700 = budget.allocatedW. Le régime EV_GRID_START n'y
est pas reproductible et ne sera pas fabriqué — counts en serait la seule preuve,
et il l'est déjà dans la trace.

L'instrumentation qui a produit la trace était temporaire et a été retirée ;
l'arbre est identique à avant. Elle n'aurait rien affiché sans
QT_LOGGING_RULES="*.debug=true" — les règles par défaut suppriment qDebug sans
catégorie, ce qui a d'abord donné une sortie vide et un test qui passait.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015F7G5VeaPVSMeVNjiGj36p
This commit is contained in:
Patrick Schurig 2026-08-30 10:25:34 +02:00
parent 30d624a82d
commit ed877d86d2
2 changed files with 77 additions and 0 deletions

View File

@ -204,6 +204,18 @@ vers un gestionnaire d'énergie complet (EV, ECS, PAC SG-Ready, batterie).
> (3 680 W au lieu de 6 000). Suites : simulation 29/29, charging 16/16, loadmodel 18/18,
> spotmarket 7/7 — amd64 0 erreur / 0 avertissement.
**DÉPLOYÉ SUR `.75` — `1.15.2+etm32`, 2026-08-30.** `counts` est en ligne et l'identité de
réconciliation se vérifie sur des données réelles : Σ counts[`budget.allocatedW`] = 1 700 =
`budget.allocatedW`, Σ counts[`draw.committedW`] = 0 = `draw.committedW`.
> **`EV_GRID_START` n'est PAS reproductible au banc, et il ne faut pas le fabriquer.**
> `pluggedIn` est en lecture seule — aucune action RPC ne l'écrit — et sans `assignedCarId` la
> borne reste hors `loads[]`. Le partage entre les deux registres est une propriété du **code**,
> pas du matériel : la suite de simulation en porte la trace complète
> (`testEvGridStartIsAnnouncedAndBounded`), reproduite verbatim dans
> `docs/BRIEF_depuis_plugin.md`. Le banc n'ajouterait que la confirmation que le binaire arm64
> fait pareil.
**DÉPLOYÉ SUR `.75` — `1.15.2+etm27`, 2026-08-29.** Cross-build arm64 (`build-etm27`), posé par
`deploy.sh`, version relue, `nymead` actif. Vérifié sur machine : aller-retour `Get`→`Set`
verbatim **neutre** ; `SetLoadConfig` à rangs doublés **refusé** avec sa raison, 4 charges

View File

@ -845,6 +845,71 @@ destination** · publié **même à zéro, avec sa destination** · **clés opaq
> borne en charge, son recrédit porte le budget au-dessus du plancher et le régime ne peut plus
> se produire), et une assertion qui **exige** que le régime ait été exercé.
### 🔍 LA TRACE DU PARTAGE — `EV_GRID_START`, charge utile verbatim
Vous ne pouvez pas produire ce régime sur le banc : `pluggedIn` est en lecture seule, aucune
action RPC ne l'écrit, et sans `assignedCarId` la borne reste hors `loads[]`. **Le partage est
une propriété du CODE, pas du matériel** — le banc n'ajouterait que la confirmation que le
binaire arm64 fait pareil. Voici donc la sortie de la suite de simulation,
`testEvGridStartIsAnnouncedAndBounded`, telle quelle :
```jsonc
{
"budget": { "allocatedW": 900, "evReservedW": 0, "recreditedW": 0,
"remainingW": 0, "surplusW": 900 },
"draw": { "committedW": 480 },
"degradedMode": false,
"loads": [
{
"loadId": "{87432679-b9b7-4f14-986a-089a83c92941}",
"allocatedW": 1380,
"decision": { "code": "EV_GRID_START",
"params": { "budgetW": 900, "floorW": 1380, "gridW": 480 } },
"levels": [
{ "level": "comfort", "targetW": 1380, "funding": "grid",
"counts": { "budget.allocatedW": 900, "draw.committedW": 480 } }
],
"measurement": { "powerW": 1380, "source": "device" },
"mechanism": { "kind": "evcharger", "chargingEnabled": true,
"currentA": 6, "phaseCount": 1, "pluggedIn": true }
},
{
"loadId": "{bbf6709c-deac-4bf9-a7b9-1281d1aa52f4}",
"allocatedW": 0,
"decision": { "code": "SURPLUS_INSUFFICIENT", "params": { "budgetW": 0 } },
"levels": [
{ "level": "comfort", "targetW": 0, "funding": "surplus",
"counts": { "budget.allocatedW": 0 } }
]
}
],
"timestamp": "2026-06-08T13:01:00Z"
}
```
**Votre critère, vérifiable ligne à ligne sur ce bloc** :
| | |
|---|---|
| `params.budgetW` = **900** | → `counts["budget.allocatedW"]` = **900** → `budget.allocatedW` = **900** |
| `params.gridW` = **480** | → `counts["draw.committedW"]` = **480** → `draw.committedW` = **480** |
| `Σ counts` = 900 + 480 = **1380** | == `targetW` = **1380** == `allocatedW` |
**Les deux moitiés sont dans les deux compteurs, et les deux compteurs sont de même nature** —
un registre d'allocation et un registre de soutirage. `budget.evReservedW` vaut **0** : il ne
reçoit plus de tranche d'allocation, il est redevenu la seule correction de latence qu'il a
toujours été.
Et la seconde borne montre l'autre moitié de la règle : `targetW: 0`, `counts` **présent** avec
sa destination à zéro. C'est le cas le plus fréquent, et c'est celui qu'un `counts: {}` aurait
perdu.
> **Ce que le banc ajoute quand même** : `+etm32` est posé sur `.75`, et l'identité s'y vérifie
> sur des données réelles — Σ counts[budget.allocatedW] = 1 700 = `budget.allocatedW`,
> Σ counts[draw.committedW] = 0 = `draw.committedW`. Le régime `EV_GRID_START`, lui, n'y est pas
> reproductible, et nous ne le fabriquerons pas : `counts` en serait la seule preuve, et il l'est
> déjà ci-dessus.
### `GetChargingInfos` filtre — et c'était le seul cas du namespace
Votre relevé était juste : paramètre déclaré au schéma, documenté « for all or a single EV