+etm62 lit sans désignation, +etm63 en exige une : une installation qui avait
commencé à remplir sa table s'arrêterait silencieusement. Règle proposée et
implémentée :
0 candidat rien, et RIEN au journal — cas normal d'une installation sans
prévision
1 candidat DÉSIGNÉ D'OFFICE, persisté, une ligne au journal
>= 2 rien de désigné, une ligne au journal, candidats publiés au
contrat
LA DISTINCTION QUI LA FONDE. Le silence est la bonne réponse à « cette
installation n'a pas de prévision ». Il n'est PAS la bonne réponse à « cette
installation en avait une et nous venons de la lui retirer ». La première est
une configuration légitime, la seconde une régression que NOUS introduisons —
les confondre ferait passer notre propre rupture pour un cas normal, ce que la
règle du silence existe précisément pour ne pas couvrir.
POURQUOI LE DÉFAUT D'OFFICE NE DEVINE RIEN : avec un seul candidat, désigner
n'est pas CHOISIR — il n'y a rien à choisir. Dès deux, il y a un vrai choix et
le faire serait deviner : le moteur ne désigne rien, le dit une fois, et
GetForecastSite publie candidateSiteThingIds pour qu'un écran pose la question
sans second appel ni heuristique côté client.
« JAMAIS CONFIGURÉ » N'EST PAS « EXPLICITEMENT MIS À RIEN ». Un second réglage,
forecastSiteChosen, est posé par TOUT appel à SetForecastSite, identifiant vide
compris. Sans lui, un utilisateur ayant délibérément coupé la prévision la
verrait se rallumer au prochain démarrage, sa décision écrasée en silence.
Deux détails qui ont failli être faux : un site candidat se reconnaît à une
propriété OBSERVABLE (un enfant publie forecastCurveTransport), jamais à un nom
de ThingClass ; et la migration tourne au PREMIER CYCLE, pas au constructeur —
là, le ThingManager n'a pas chargé les Things, « aucun candidat » serait
toujours vrai, et le défaut ne se déclencherait jamais. Un mécanisme inerte qui
aurait l'air posé.
loadmodel 32/32, charging 48/48, spotmarket 32/32, simulation 69/69,
ci-quality 4/4, build 0 erreur 0 warning.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015F7G5VeaPVSMeVNjiGj36p