diff --git a/AGENTS.md b/AGENTS.md index 1bc7393..d4dd1c4 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -406,6 +406,38 @@ Ensuite : **passe contrats** (OPTIMIZER_PROTOCOL + README). `[plancher × 0,5 ; plancher[`), `BATTERY_RESERVE` avec un surplus réel sous le seuil, et LM-1204-b avec **deux bornes réelles** — la Terra AC ne répond toujours pas à l'ARP. +### Sauvegarder l'historique quand la forge est injoignable + +**Un bundle COPIÉ ailleurs n'est pas une sauvegarde. Un bundle CLONÉ à blanc depuis ailleurs en +est une.** La différence ne se voit que le jour où elle compte, et ce jour-là il est trop tard +pour la découvrir. + +```bash +# 1. produire — --all, pas une branche : les tags et les autres branches comptent aussi +git bundle create ~/etm-plugin-$(date +%Y%m%d-%H%M).bundle --all + +# 2. déposer sur une AUTRE machine (le banc fait l'affaire) +ssh etm@192.168.1.75 'mkdir -p ~/git-secours' +scp ~/etm-plugin-*.bundle etm@192.168.1.75:~/git-secours/ + +# 3. PROUVER qu'il est restaurable — depuis la machine de destination, pas depuis celle-ci +ssh etm@192.168.1.75 'cd ~/git-secours && B=$(ls -t *.bundle | head -1) && + git bundle verify "$B" && git clone -q --bare "$B" /tmp/v && + git --git-dir=/tmp/v log --oneline -1 && + git --git-dir=/tmp/v rev-list --count HEAD && rm -rf /tmp/v' +``` + +L'étape 3 est celle qu'on saute. Elle coûte dix secondes et c'est la seule qui distingue +« restaurable depuis une autre machine » de « présent sur une autre machine ». + +> **Quand.** Dès que la forge est injoignable et que des commits s'accumulent en local. Le +> 2026-08-30, 64 commits ne vivaient que sur `etm-powersync-dev`, fibre coupée — et le bundle +> aussi, tant qu'il y restait. +> +> **Ce que ça ne remplace pas** : un `git push`. Un bundle est une photo, pas un remote — il ne +> se met pas à jour, et personne d'autre ne travaille dessus. À rafraîchir à chaque session tant +> que la forge ne répond pas. + ### Lire le journal de la box — et ce qu'une absence prouve **`journalctl -u nymead`, SANS `sudo`.** L'utilisateur `etm` est dans le groupe `adm`, qui diff --git a/docs/BRIEF_depuis_plugin.md b/docs/BRIEF_depuis_plugin.md index 9a6f42d..b3ecc66 100644 --- a/docs/BRIEF_depuis_plugin.md +++ b/docs/BRIEF_depuis_plugin.md @@ -668,8 +668,41 @@ publierait donc sa ventilation : ``` `Σ counts == targetW`, toujours. L'identité devient calculable **sans exception**, et elle vaudra -telle quelle quand `draw.committedW` arrivera. Dites-nous si cette forme vous va, ou si vous -préférez lire la ventilation autrement — c'est votre réconciliation qui en dépend. +telle quelle quand `draw.committedW` arrivera. + +**`counts` sera publié TOUJOURS, même à une seule destination.** Sur une charge ordinaire, +`counts: {"budget.allocatedW": 3500}` est redondant avec `targetW` — et c'est le prix à payer. +L'omettre vous obligerait à connaître la **destination par défaut**, donc à la déduire ; vous +auriez alors deux chemins de lecture, dont un qui n'est exercé que sur les charges ordinaires, +c'est-à-dire presque toutes. Et l'identité deviendrait conditionnelle (« si `counts`, sommer ; +sinon attribuer `targetW` au compteur par défaut ») — une identité à branche est une identité +qu'on peut se tromper à écrire, en silence. + +> C'est la règle qui a payé toute la semaine : **une absence ne doit jamais vouloir dire « le +> défaut s'applique »**. `measurement.source: "none"` est publié plutôt que la clé retirée ; +> `rankOrigin` absent n'affirme rien, surtout pas `"user"` ; `levels[]` absent dit « box +> antérieure », pas « un seul niveau implicite ». Le silence ne porte que l'ignorance. + +### Et une question que `counts` fait apparaître, sur `funding` lui-même + +En posant la ventilation, on voit que **R2 a déplacé le problème d'un cran sans l'éliminer pour +`EV_GRID_START`** : ce niveau-là est financé **en partie au surplus, en partie au réseau**. +`funding: "grid"` y est donc déjà une approximation — au niveau, comme il l'était à la charge. + +Nous ne touchons pas à `funding` sans vous : c'est votre champ de réconciliation. Mais il faut +choisir en connaissance de cause, et les deux ne dérivent pas l'un de l'autre — + +- **`funding` dit l'ORIGINE** (« ces watts sont achetés »), une intention, voisine du motif ; +- **`counts` dit le REGISTRE** (« ils sont comptés ici »), une comptabilité. + +`counts = {allocatedW: 900, evReservedW: 480}` ne dit pas si l'achat était délibéré ; +`funding: "grid"` ne dit pas où les 900 W sont comptés. **Garder les deux est justifié — à +condition que ce soit dit**, sinon quelqu'un « simplifiera » un jour en supprimant celui qui a +l'air redondant. + +Reste votre arbitrage sur le cas mixte : `funding` y garde-t-il un code unique (approximatif mais +lisible), ou faut-il l'y omettre et laisser `counts` parler seul ? **Nous penchons pour le code +unique** — il porte l'intention, que `counts` ne porte pas — mais c'est votre écran. > Et deux fils antérieurs de votre brief sont **clos**, au cas où ils ne vous seraient pas > parvenus : l'**entrelacement des domaines** est tranché — grouper à l'affichage, **jamais à