docs(brief): les trois réponses à l'agent app, mesurées sur marque fraîche

Complète 1490183, dont l'édition du brief avait échoué sur une assertion sans
rien écrire — le commit ne portait donc que AGENTS.md, INTERFACE.md et la spec.

1. L'écho verbatim passe, et l'explication de nos relevés contradictoires : le
   premier essai suivait un déplacement qui avait fait tomber la marque.
   sansRankOriginAuto() peut partir ; relire avant de réécrire le remplace.

2. La correction de la promesse fausse sur la recréation d'une entrée supprimée,
   avec ce qu'elle produit — borne arbitrée mais absente de GetLoadConfig — et la
   consigne qui en découle : ne pas supprimer l'entrée d'une borne dont le Thing
   vit, enabled: false reste la voie.

3. Le regroupement par domaine, à l'affichage jamais à l'écriture (LM-1209-d), et
   la note d'entrelacement qui ne devrait pas être un avertissement.

Plus la ligne pour leur README des sondes : un refus arrive en status "success".

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-29 10:49:30 +02:00
parent 1490183ac5
commit 87c97e407f

View File

@ -248,10 +248,24 @@ Thing a été supprimé.
C'est exactement le « geste, pas une suppression d'office » que vous demandez, et il existe déjà.
> **La limite à connaître** : si vous supprimez l'entrée d'une borne dont le **Thing existe
> encore**, elle sera recréée au cycle suivant — c'est l'auto-provisionnement, et c'est voulu.
> Retirer une borne de l'arbitrage sans supprimer son Thing se fait par `enabled: false`, pas par
> suppression.
> ⚠️ **CORRECTION du 2026-08-29 — cette limite était énoncée à l'envers.** Nous vous avions
> écrit que supprimer l'entrée d'une borne dont le **Thing existe encore** la ferait **recréer
> au cycle suivant**. **C'est faux, et c'est mesuré** : sur `.75`, entrée retirée, Thing vivant,
> **rien n'a été recréé en 140 s**.
>
> La cause : l'auto-provisionnement ne tourne qu'à la **création de l'adaptateur**, pas à chaque
> cycle. L'adaptateur est construit depuis le **Thing** — il survit à la suppression de
> l'entrée, donc la borne n'est plus jamais proposée à la configuration.
>
> **Ce que cela produit** : la borne reste **arbitrée** mais **absente de `GetLoadConfig`**, à un
> rang de queue non réglable. C'est exactement le trou que 3g-2 avait refermé — « arbitrée mais
> absente de la configuration » — rouvert par le côté client. Il ne se referme qu'au
> **redémarrage de `nymead`**.
>
> **Donc : ne supprimez pas l'entrée d'une borne dont le Thing vit.** `enabled: false` reste la
> bonne voie pour la sortir de l'arbitrage — ce point-là ne change pas. Un correctif moteur est
> proposé (reprovisionner toute borne sans entrée, pas seulement à la naissance de
> l'adaptateur) ; il n'est pas écrit, la décision appartient à Patrick.
### D — instruction reçue, rien ne bouge côté moteur
@ -414,8 +428,8 @@ Deux conséquences pour vous :
qu'il n'a pas fait. Renvoyer verbatim une entrée qui le porte déjà reste licite — l'aller-retour
`Get` → `Set` n'est pas cassé.
> **Vérifié sur `.75` le 2026-08-29, sur une vraie entrée `"auto"`** (borne appairée après
> `+etm27`, insérée au rang 5). **Vous pouvez renvoyer le `"auto"` sans le filtrer** : l'écho
> **Vérifié sur `.75` le 2026-08-29, sur une marque FRAÎCHE** — entrée recréée au redémarrage,
> rang 5, `rankOrigin: "auto"`, **rien déplacé avant l'essai**. **Vous pouvez renvoyer le `"auto"` sans le filtrer** : l'écho
> verbatim intégral passe, et l'écho verbatim **avec un renommage ailleurs** passe aussi —
> `EnergyErrorNoError`, la marque survit, aucun rang ne bouge. Un renommage n'est donc **jamais**
> bloqué par la présence d'une borne auto-provisionnée. Votre filtre reste inoffensif ; il n'est
@ -427,6 +441,41 @@ Deux conséquences pour vous :
> quelque chose qui n'est plus vrai. **Le remède est de relire avant de réécrire**, et le même
> geste passe ensuite. Un cache de configuration survivant à une écriture est le vrai piège,
> pas le champ.
>
> **C'est ce qui explique nos deux relevés contradictoires.** Notre premier essai suivait un
> déplacement fait pour borner le refus — la marque était donc tombée, et votre écriture portait
> un `"auto"` que le persisté ne portait plus : refus correct, cas de l'écho périmé. Sur marque
> fraîche, sans rien déplacer, l'écho passe. **`sansRankOriginAuto()` peut partir** ; ce qu'il
> faut à la place est de **relire avant de réécrire**.
### Le regroupement par domaine : à l'affichage, jamais à l'écriture
L'insertion en queue entrelace les domaines (`ecs, ev, ev, heating, ev`) et votre note
d'entrelacement s'allume à juste titre — mais la conclusion est l'inverse de celle qui vient
naturellement. Tranché en `spec_loadmodel.md` **LM-1209-d**.
La contiguïté des domaines **n'a jamais été un invariant** : le waterfall trie sur le rang seul,
et `domain` est une métadonnée que l'arbitre ne lit pas. L'exiger du moteur serait d'ailleurs
contradictoire avec la raison même de LM-1209 — insérer une charge `heating` en respectant la
contiguïté décalerait toutes les `ev` suivantes, soit une détection qui réordonne une
installation qu'un humain a classée.
**Le même raisonnement vaut chez vous.** Un regroupement appliqué **à l'enregistrement** est une
machine qui réordonne ce qu'un humain a décidé, au pire moment : il défait un entrelacement
délibéré — « l'ECS après la borne 1 mais avant la borne 2 » est un arbitrage légitime, et le §10
en produira d'autres — et remonterait au rang 3 une borne que le moteur vient de ranger en queue.
- **Grouper à l'affichage : oui.** Rien ne s'y oppose.
- **Grouper à l'écriture : non.** Si le regroupement a de la valeur, qu'il soit un **geste
explicite** de l'installateur, visible et réversible — jamais une normalisation au moment de
sauver.
- **La note d'entrelacement ne devrait pas être un avertissement.** Une liste entrelacée n'a rien
d'incohérent ; l'annoncer comme un défaut pousse à « réparer » un ordre que personne n'a cassé.
Au plus une proposition.
> **Une ligne pour votre README des sondes** : **un refus arrive en `status: "success"`**, le
> verdict étant dans `params.energyError`. Une sonde qui teste `status` annonce « accepté » sur
> une écriture rejetée. C'est désormais en tête d'`INTERFACE.md`, avec l'extrait qui va bien.
---