Records the branch for the next release under Added: the development
reverse proxy that serves pages and /websocket from one address without
nginx, with HTTPS, one log line per request, the startup probe and the
502 that name the silent Odoo port, and bounds that never apply to an
open WebSocket; the local authority and certificate for HTTPS tests;
the TODO Network entries that start it and issue the certificates.
Checked: make doc_markdown regenerates both files, each language only
in its own; a simulated merge with master has no conflict.
--- FR ---
[UPD] changelog : mandataire de dev Odoo 18, HTTPS, entrées TODO Network
Consigne la branche pour la prochaine version sous Ajouté : le mandataire
inverse de développement qui sert les pages et /websocket depuis une
adresse sans nginx, avec le HTTPS, une ligne de journal par requête, la
sonde au démarrage et le 502 qui nomment le port d'Odoo muet, et des
bornes jamais appliquées à une WebSocket ouverte ; l'autorité et le
certificat locaux des tests HTTPS ; les entrées TODO Network qui le
lancent et émettent les certificats.
Vérifié : make doc_markdown régénère les deux fichiers, chaque langue
dans le sien seulement ; un merge simulé avec master est sans conflit.
Assisted-by: Claude Opus 5.5
Records the branch for the next release: under Security, the git mirror
of the QEMU cache that no longer follows an ssh:// or git:// repository
named by a client, with the binary version 0.2.17 that tells a fixed
cache apart; under Changed, the icons on the interface chooser.
Checked: make doc_markdown regenerates both files, each language only
in its own.
--- FR ---
[UPD] changelog : miroir git du cache qemu limité à http(s), icônes
Consigne la branche pour la prochaine version : sous Sécurité, le miroir
git du cache QEMU qui ne suit plus un dépôt ssh:// ou git:// nommé par un
client, avec la version 0.2.17 du binaire qui distingue un cache corrigé ;
sous Modifié, les icônes du choix d'interface.
Vérifié : make doc_markdown régénère les deux fichiers, chaque langue
dans le sien seulement.
Assisted-by: Claude Opus 5.5
The Unreleased entry named botocore 1.43.49 with aiobotocore 3.9.0,
which the branch replaces by 1.43.75 with 3.9.1; the entry now matches
what installs. Added: openpyxl and xlsxwriter for Transform data and the
factur-x floor under Changed, the doc and examples filter of
poetry_update.py under Fixed, requests 2.32.4 under Security.
Checked: make doc_markdown regenerates both files, each language only
in its own.
--- FR ---
[UPD] changelog : aws 1.43.75, requests 2.32.4, exemples doc écartés
L'entrée Unreleased nommait botocore 1.43.49 avec aiobotocore 3.9.0,
que la branche remplace par 1.43.75 avec 3.9.1 ; l'entrée colle désormais
à ce qui s'installe. Ajoutés : openpyxl et xlsxwriter pour Transform data
et le plancher de factur-x sous Modifié, le filtre doc et examples de
poetry_update.py sous Corrigé, requests 2.32.4 sous Sécurité.
Vérifié : make doc_markdown régénère les deux fichiers, chaque langue
dans le sien seulement.
Assisted-by: Claude Opus 5.5
Records the branch for the next release under Changed: the Odoo 18 move
to pandas 3.0.6, cryptography 50, Pillow 12.3 and the AWS trio aligned on
aiobotocore 3.9.0, with the pandas 4 warning left in a third-party
attendance dashboard, and the Dependabot group that keeps the three AWS
packages in one pull request.
Checked: make doc_markdown regenerates both files, each language only
in its own.
--- FR ---
[UPD] changelog : Odoo 18 sur pandas 3, aws 1.43, groupe aws Dependabot
Consigne la branche pour la prochaine version sous Modifié : le passage
d'Odoo 18 à pandas 3.0.6, cryptography 50, Pillow 12.3 et le trio AWS
aligné sur aiobotocore 3.9.0, avec l'avertissement pandas 4 laissé dans
un tableau de bord de présence tiers, et le groupe Dependabot qui garde
les trois paquets AWS dans une seule demande de fusion.
Vérifié : make doc_markdown régénère les deux fichiers, chaque langue
dans le sien seulement.
Assisted-by: Claude Opus 5.5
Records the dev/github_bot branch for the next release: Dependabot out
of the frozen Odoo 12 to 17 requirements, poetry_update.py on a missing
pyproject.toml and in the Odoo venv, the refreshed Odoo 18 lock with its
untested majors, and idna 3.20 under Security.
Checked: make doc_markdown regenerates both files, each language only
in its own.
--- FR ---
[UPD] changelog : portée dependabot, venv poetry update, lock Odoo 18
Consigne la branche dev/github_bot pour la prochaine version : Dependabot
hors des requirements figés d'Odoo 12 à 17, poetry_update.py sur un
pyproject.toml absent et dans le venv Odoo, le lock d'Odoo 18 rafraîchi
avec ses majeures non testées, et idna 3.20 sous Sécurité.
Vérifié : make doc_markdown régénère les deux fichiers, chaque langue
dans le sien seulement.
Assisted-by: Claude Opus 5.5
Four entries record what the branch changes for a user: a .venv.erplibre
built elsewhere is reported instead of launched, the Claude command list
shows missing and outdated copies and redeploys them, commit messages open
in English, and the language and Fork entries move to Configuration.
Checked: make doc_markdown regenerates both files, bullets aligned.
--- FR ---
[UPD] changelog : sonde du venv, liste des commandes, règle, menus TODO
Quatre entrées disent ce que la branche change pour l'utilisateur : un
.venv.erplibre bâti ailleurs est signalé plutôt que lancé, la liste des
commandes Claude montre les copies absentes et périmées et les redéploie, les
messages de commit s'ouvrent en anglais, et la langue et Fork passent dans
Configuration.
Vérifié : make doc_markdown régénère les deux fichiers, puces alignées.
Assisted-by: Claude Opus 5.5
On a system too old to read TODO, install.sh ran the install without asking,
and the install DELETES an existing .venv.erplibre. It now runs only on a yes
typed in a terminal: o, oui, y or yes, any case. Enter alone means no, and
with no terminal no question is asked and nothing is installed. « aucun
python3 » finally shows when the probe is silent: the || fallback never fired
behind a pipe.
Checked: 16 tests, each answer on a pseudo-terminal; install.sh run in an
isolated copy exits 1 on « n » and installs on « o ».
--- FR ---
[IMP] install.sh : demander o/N avant d'installer le venv d'outillage
Sur un système trop ancien pour lire TODO, install.sh lançait l'installation
sans rien demander, et celle-ci SUPPRIME un .venv.erplibre existant. Elle ne
part plus que sur un oui tapé au terminal : o, oui, y ou yes, toute casse.
Entrée seule vaut non, et sans terminal aucune question n'est posée ni
installation lancée. « aucun python3 » s'affiche enfin quand la sonde est
muette : le repli par || ne se déclenchait jamais derrière un tube.
Vérifié : 16 tests, dont chaque réponse sur un pseudo-terminal ; install.sh
lancé dans une copie isolée sort en 1 sur « n » et installe sur « o ».
Assisted-by: Claude Opus 5.5
make prints the recipe it runs, and « ./install.sh » offered an installation
to read where one opens a menu. The launcher adds nothing but a name and
passes every argument to install.sh, which alone keeps picking an interpreter
able to READ the code and stays the entry point of a fresh machine.
A test caps todo.sh at six lines of code and refuses it python3, bin/python
and sort -V: two copies of that choice would drift. The changelog names the
launcher.
Checked: chain run through to the menu, exit 0; 9 tests.
--- FR ---
[ADD] todo : lanceur todo.sh, que make affiche à la place d'install.sh
make affiche la recette qu'il exécute, et « ./install.sh » y donnait à lire
une installation là où l'on ouvre un menu. Le lanceur n'ajoute qu'un nom et
passe chaque argument à install.sh, qui garde seul le choix d'un interpréteur
capable de LIRE le code et reste le point d'entrée d'une machine neuve.
Un test plafonne todo.sh à six lignes de code et lui refuse python3,
bin/python et sort -V : deux copies de ce choix dériveraient. Le changelog
nomme le lanceur.
Vérifié : chaîne lancée jusqu'au menu, sortie 0 ; 9 tests.
Assisted-by: Claude Opus 5
Assisted-by: Claude Opus 5.5
Cinq livraisons de cette branche manquaient à la liste du non-publié : le proxy
SOCKS du menu de déploiement et la cible qui formate les tests, côté ajouts ;
la reprise d'un téléchargement coupé, le faisceau de certificats désigné
seulement s'il existe, et « make version » qui nomme les deux Python, côté
corrections. Un lecteur qui choisit de mettre à jour n'y voyait donc ni la
commande neuve ni les trois pannes levées.
Vérifié : les quatre sections du non-publié comptent autant de puces en
français qu'en anglais, et les deux fichiers générés suivent leur source.
--- EN ---
Five of this branch's deliveries were missing from the unreleased list: the
SOCKS proxy of the deployment menu and the target formatting the tests, on the
added side; the resume of an interrupted download, the certificate bundle named
only when it exists, and "make version" naming both Pythons, on the fixed side.
A reader choosing whether to upgrade saw neither the new command nor the three
failures lifted.
Checked: the four unreleased sections carry as many bullets in French as in
English, and both generated files follow their source.
Assisted-by: Claude Opus 5
Odoo 13, 14 et 15 bâtissaient encore sur bullseye, dont le dépôt de sécurité
est démantelé. Rien ne les y obligeait : la base est
« python:<version>-slim-<version Debian> », donc l'interpréteur vient de
l'image officielle et non de Debian — les variantes bookworm existent jusqu'à
3.7.17. L'aiguillage portait en outre une branche « buster » INATTEIGNABLE,
sa condition étant la négation de celle qui la précédait ; elle part avec le
reste. Le build de wkhtmltopdf suit la version : celui de bullseye réclame
libssl1.1, absente de bookworm.
Vérifié : les images 3.7.17 et 3.8.20 slim-bookworm existent, le .deb bookworm
rend l'empreinte déclarée, et ses quinze dépendances sont dans bookworm.
--- EN ---
Odoo 13, 14 and 15 still built on bullseye, whose security repository is
dismantled. Nothing required it: the base is
"python:<version>-slim-<suite>", so the interpreter comes from the official
image and not from Debian — the bookworm variants exist down to 3.7.17. The
switch also carried an UNREACHABLE "buster" branch, its condition being the
negation of the one before it; it goes with the rest. The wkhtmltopdf build
follows the suite: bullseye's requires libssl1.1, absent from bookworm.
Checked: the 3.7.17 and 3.8.20 slim-bookworm images exist, the bookworm .deb
matches the declared checksum, and its fifteen dependencies are in bookworm.
Assisted-by: Claude Opus 5
Son LTS est terminé, et sa suite de sécurité n'est ni servie ni archivée :
security.debian.org publie encore un index qui nomme des paquets dont le pool
ne porte plus le fichier, et archive.debian.org ne connaît pas bullseye. apt
s'arrête donc avant d'installer git, sur une version qui ne recevra plus rien.
Elle quitte le catalogue de déploiement et le script de dépendances, où la
variable qui la distinguait n'a plus d'usage. Debian 12 et 13 restent, et
l'image de la 13 est toujours le dernier point de version — sans rien à
changer ici quand le suivant paraît.
Vérifié : plus aucune trace de bullseye dans script/, hors la base des
conteneurs, traitée à part.
--- EN ---
Its LTS has ended, and its security suite is neither served nor archived:
security.debian.org still publishes an index naming packages whose pool no
longer holds the file, and archive.debian.org does not know bullseye. apt
therefore stops before installing git, on a version that will receive nothing
more. It leaves the deployment catalogue and the dependency script, where the
variable telling it apart has no use left. Debian 12 and 13 stay, and 13's
image is always the latest point release — with nothing to change here when
the next one appears.
Checked: no trace of bullseye left in script/, beyond the container base,
handled separately.
Assisted-by: Claude Opus 5
install.sh et make lançaient todo.py par son hashbang, donc par le python3 du
PATH, sans rien garantir de sa version : une syntaxe plus récente l'arrête en
SyntaxError au chargement, et le poste hors d'âge perd tout moyen de lancer
l'installation qui l'en sortirait. L'ordre est désormais le venv d'outillage,
sinon le python3 du PATH s'il suffit, sinon l'installation. TODO lui-même se
relance dans le venv, vérifie version et modules avant ses imports, et propose
l'installation en terminal — ce que « make » sur un clone neuf promet depuis
toujours sans le tenir.
Vérifié : venv à jour, venv périmé, systèmes en 3.10, 3.14 et 3.15 vont chacun
où il faut ; un import du module ne relance rien et lève comme avant.
--- EN ---
install.sh and make ran todo.py through its hashbang, so through the python3 of
the PATH, with no guarantee about its version: a newer syntax stops it with a
SyntaxError at load, and the ageing machine loses every way to start the
install that would rescue it. The order is now the tools venv, else the python3
of the PATH when it suffices, else the install. TODO itself relaunches in the
venv, checks version and modules before its imports, and offers the install in
a terminal — what "make" on a fresh clone has always promised without
keeping.
Checked: fresh venv, stale venv, systems on 3.10, 3.14 and 3.15 each go where
they should; importing the module relaunches nothing and raises as before.
Assisted-by: Claude Opus 5
install_erplibre.sh bâtissait .venv.erplibre avec le python3 du système, quelle
que soit sa version : un 3.10 y donnait un venv que l'outillage ne sait pas
charger. Il délègue à install_venv.sh, qui obtient la version par mise, pyenv
ou la distribution, et rebâtit un venv hors service. Le PATCH ne borne que le
venv d'Odoo, dont le pyproject exige « >=3.12.10,<3.13 » : l'exiger ailleurs
écartait un Python de distribution d'un cran en retard — NixOS 25.11 livre
3.14.2 — et faisait compiler CPython pour rien. Le module NixOS déclare
désormais les DEUX Python, substitués depuis les fichiers de version.
Vérifié : 15 tests sur des venvs factices, conservés, rebâtis ou refusés selon
leur état, et un chemin sans pyvenv.cfg garde son contenu.
--- EN ---
install_erplibre.sh built .venv.erplibre with the system python3, whatever its
version: a 3.10 gave a venv the tooling cannot load. It delegates to
install_venv.sh, which obtains the version through mise, pyenv or the
distribution, and rebuilds a venv out of service. The PATCH bounds only Odoo's
venv, whose pyproject requires ">=3.12.10,<3.13": requiring it elsewhere turned
away a distribution Python one step behind — NixOS 25.11 ships 3.14.2 — and
compiled CPython for nothing. The NixOS module now declares BOTH Pythons,
substituted from the version files.
Checked: 15 tests on stub venvs, kept, rebuilt or refused by their state, and a
path without pyvenv.cfg keeps its content.
Assisted-by: Claude Opus 5
Une syntaxe plus récente que le Python du dépôt ne casse qu'au chargement, et
aucun outil en place ne la voyait : la cible de black borne ce qu'il ÉCRIT,
jamais ce qu'il accepte, et flake8 analyse avec l'interpréteur courant. Le
contrôle compile les fichiers indexés avec un vrai interpréteur de la version
déclarée, trouvé sans réseau par mise, pyenv ou le PATH, et se prend lui-même
quand il y tourne déjà. Sans interpréteur, il DIT qu'il n'a pas vérifié plutôt
que de laisser croire le contraire. Le hook relaie, sans bloquer le commit, et
écarte les dépôts rapatriés dont ce dépôt ne répond pas.
Vérifié : les f-strings PEP 701 de la révision précédente sont signalées, rien
ne l'est sur l'arbre courant, et l'absence du fichier de version se dit.
--- EN ---
A syntax newer than the repository's Python only breaks at load, and no tool in
place saw it: black's target bounds what it WRITES, never what it accepts, and
flake8 parses with the running interpreter. The check compiles staged files
with a real interpreter of the declared version, found without network through
mise, pyenv or the PATH, and takes itself when it already runs under it.
Without one, it SAYS it did not check rather than implying it did. The hook
relays, without blocking the commit, and skips the checked-out repositories
this one does not answer for.
Checked: the PEP 701 f-strings of the previous revision are reported, nothing
is on the current tree, and a missing version file is announced.
Assisted-by: Claude Opus 5
« make format » donnait isort et black à tout fichier Python : la cible py37,
plus petit dénominateur commun de six dépôts d'addons, imposait son style au
code de ce dépôt. Le contexte décide désormais — les modules Odoo gardent isort
et black, le reste passe par ruff, réglé dans .ruff.toml, comme la norme OCA
depuis qu'elle a quitté black. Les dépôts rapatriés sous script/ en sont
écartés, chemin nommé compris. La cible y reste py310 : dès 3.14 ruff écrit
« except A, B: » sans parenthèses, que le python3 des hooks ne sait pas lire.
Vérifié : un fichier reçoit deux normes selon son chemin, et aucun dépôt
rapatrié n'est touché.
--- EN ---
"make format" gave isort and black to every Python file: the py37 target,
lowest common denominator of six addons repositories, imposed its style on this
repository's code. Context now decides — Odoo modules keep isort and black,
everything else goes through ruff, set in .ruff.toml, as the OCA standard does
since it left black. The repositories checked out under script/ are excluded, a
named path included. The target stays py310 there: from 3.14 on, ruff writes
"except A, B:" unparenthesised, which the python3 of the hooks cannot read.
Checked: one file gets two standards by its path, and no checked-out
repository is touched.
Assisted-by: Claude Opus 5
La section du non-publié taisait trois correctifs déjà fusionnés : l'attente
de l'étape finale de cloud-init avant de rendre la main, sans quoi une session
vit sans les variables du cache et une installation lancée par sudo rejette
son certificat ; les métadonnées de dépôt RPM nommées par l'empreinte de leur
contenu, désormais servies du disque, une plage faisant prendre le fichier
entier ; et l'attente NTP levée sur une VM hors ligne, qui sans cela n'ouvre
jamais son serveur ssh. Régénéré par mmg : 54 puces de chaque côté.
--- EN ---
The Unreleased section was silent on three fixes already merged: the wait for
cloud-init's final stage before handing over, without which a session lives
without the cache variables and an install run by sudo rejects its
certificate; RPM repository metadata named after the hash of its content, now
served from disk, a range fetching the whole file; and the NTP wait lifted on
an offline VM, which otherwise never opens its ssh server. Regenerated with
mmg: 54 bullets on each side.
Assisted-by: Claude Opus 5
Ce que le guide fait désormais se voit à chaque ouverture de session sur une
VM équipée : un lecteur qui choisit de mettre à jour doit le lire.
Le garde-fou i18n n'a pas d'entrée : aucune clé n'est en double aujourd'hui,
donc rien ne change pour qui utilise le produit. Il empêche un retour, il ne
corrige pas un symptôme.
--- EN ---
What the guide now does shows at every login on an equipped VM: a reader
choosing whether to upgrade has to read it.
The i18n guard gets no entry: no key is duplicated today, so nothing changes
for whoever uses the product. It prevents a return, it does not fix a
symptom.
Assisted-by: Claude Opus 5
Le point annonçait qu'un fragment de service suffit à donner l'autorité du
cache à NixOS. C'était vrai de ce qu'on savait en l'écrivant, et le lecteur
qui s'y fie repart avec un mécanisme qui échoue.
Mesuré depuis : « sudo nix store info » rend « Store URL: local » et un
NIX_REMOTE vide — le nix de root ne passe pas par le démon, il télécharge
lui-même, avec l'environnement que sudo lui laisse, et sudo n'en laisse
aucun. Le point nomme désormais les trois frontières où l'environnement se
perd, et ce qui traverse chacune.
--- EN ---
The entry announced that a service drop-in is enough to give NixOS the
cache's authority. That was true of what was known when it was written, and
a reader who relies on it leaves with a mechanism that fails.
Measured since: « sudo nix store info » reports « Store URL: local » and an
empty NIX_REMOTE — root's nix does not go through the daemon, it downloads
on its own, with whatever environment sudo leaves it, and sudo leaves none.
The entry now names the three boundaries where the environment is lost, and
what crosses each.
Assisted-by: Claude Opus 5
NixOS était SOUSTRAIT du cache faute d'ancre de confiance par fichier, ce
qui lui fermait le hors ligne : le magasin est alors la seule source, et
l'exception ne laisse rien. Une déclaration arriverait trop tard, la
première reconstruction étant le premier téléchargement.
L'autorité est donc POINTÉE, consommateur par consommateur, et
l'environnement se perd à trois frontières : nix-daemon, activé par
socket, qu'un fragment sous /run/systemd/system atteint ; sudo, que
« env_keep » traverse — le nix de root parle droit au magasin local et
télécharge lui-même ; et la session ssh, ouverte une seconde avant que
cloud-init n'écrive le faisceau. Vérifié : installation complète, 0 refus.
--- EN ---
NixOS was EXEMPTED from the cache for want of a per-file trust anchor,
which closed offline deployment to it: the store is then the only source,
and an exemption leaves nothing. A declaration would come too late, the
first rebuild being the first download.
The authority is therefore POINTED AT, consumer by consumer, and the
environment is lost at three boundaries: nix-daemon, socket-activated,
reached by a drop-in under /run/systemd/system; sudo, crossed by
« env_keep » — root's nix talks straight to the local store and downloads
itself; and the ssh session, opened one second before cloud-init writes
the bundle. Checked: a complete install, 0 refusals.
Assisted-by: Claude Opus 5
Deux changements de comportement manquaient au non-publié, et ce sont
justement ceux qu'un lecteur doit connaître avant de mettre à jour. La
vérification d'une image ne se demande plus, donc une commande qui
passait « --verify » ne change rien et une qui ne le passait pas vérifie
désormais : « --no-verify » est l'échappatoire, à réserver au hors ligne.
Et « --bios » est refusé sur une image sans secteur d'amorçage, là où il
était obéi et donnait une VM « running » à console muette.
--- EN ---
Two behaviour changes were missing from Unreleased, and they are exactly
the ones a reader needs before upgrading. Verifying an image is no longer
asked for, so a command passing "--verify" changes nothing while one that
did not now verifies: "--no-verify" is the way out, to be kept for offline
runs.
And "--bios" is refused on an image with no boot sector, where it used to
be obeyed and gave a VM reported "running" with a silent console.
Assisted-by: Claude Opus 5
La vérification existait sous un drapeau, et pour Ubuntu SEULEMENT : les
autres images arrivaient sans que rien ne les regarde, alors que leurs
éditeurs publient tous une somme. Six y entrent, relevées sur les dépôts
plutôt que devinées — Debian est en sha512, les familles RHEL nomment
« CHECKSUM », Rocky l'écrit en forme BSD, Arch et openSUSE posent une
somme par image. Fedora en reste dehors, son fichier portant un numéro de
construction que l'URL de l'image ne donne pas.
Injoignable n'arrête plus rien, un écart si. Le menu du cache sait aussi
oublier une URL, « --detient » faisant l'aperçu.
--- EN ---
Verification existed behind a flag, and for Ubuntu ONLY: the other images
arrived with nothing looking at them, though every publisher ships a sum.
Six now enter, read off the repositories rather than guessed — Debian is
sha512, the RHEL families name it "CHECKSUM", Rocky writes the BSD form,
Arch and openSUSE ship a sum per image. Fedora stays out, its file
carrying a build number the image URL does not give.
Unreachable no longer stops anything, a mismatch does. The cache menu can
also forget one URL, "--detient" serving as the preview.
Assisted-by: Claude Opus 5
Le déploiement écrit /etc/motd partout et compte sur pam_motd pour le
montrer — vrai des quatre images cloud, faux ici : sshd rend « printmotd
no » et le PAM n'en contient aucun. Le guide était écrit, complet, et
personne ne le lisait. Il gagne un bloc propre à NixOS, dont le piège
qu'il existe pour dire — /etc/nixos/erplibre.nix est réécrit par
« make install_os », et ce qu'on y ajoute disparaît sans un mot.
La locale demandée ne s'appliquait pas : cloud-init passe par locale-gen
et update-locale, absents ici. Mesuré — fr_CA demandé, en_US obtenu. Rien
n'est imposé à une NixOS qu'on avait déjà.
--- EN ---
Deployment writes /etc/motd everywhere and relies on pam_motd to show it —
true of the four cloud images, false here: sshd returns "printmotd no" and
the PAM stack holds none. The guide was written, complete, and nobody read
it. It gains a NixOS block, including the trap it exists to name —
/etc/nixos/erplibre.nix is rewritten by "make install_os", and what you
add there vanishes without a word.
The requested locale did not apply: cloud-init goes through locale-gen and
update-locale, absent here. Measured — fr_CA asked, en_US obtained.
Nothing is imposed on a NixOS one already had.
Assisted-by: Claude Opus 5
Aucune lecture de code ne les aurait trouvés. Son image n'a pas de secteur
d'amorçage BIOS : une VM créée en SeaBIOS se déclare « running » avec une
console MUETTE, d'où un marqueur par distribution — Debian 13 démarre en
SeaBIOS sur le même hôte, et renverser le défaut coûterait un disque EFI
à chaque VM du parc.
« --ciuser » s'en remet au compte par DÉFAUT de l'image, que NixOS nomme
autrement : le cloud-config du dépôt part en extrait pour toutes les
distributions. Et le lecteur cloud-init passe sur le bus SCSI, une image
bâtie pour virtio seul ne voyant jamais un lecteur IDE.
--- EN ---
No code reading would have found them. Its image has no BIOS boot sector:
a VM created in SeaBIOS reports "running" with a SILENT console, hence a
per-distribution marker — Debian 13 boots in SeaBIOS on the same host, and
flipping the default would cost an EFI disk on every VM.
"--ciuser" defers to the image's DEFAULT account, which NixOS names
otherwise: the repository's cloud-config now travels as a snippet for
every distribution. And the cloud-init drive moves to the SCSI bus, an
image built for virtio alone never seeing an IDE drive.
Assisted-by: Claude Opus 5
L'amorçage d'ERPLibre n'atteignait pas NixOS : le Makefile force
« SHELL := /bin/bash », que l'image ne porte pas, et le fournisseur de
Python ne cherche l'interpréteur du système qu'en /usr/bin/pythonX.Y.
Les deux répondent une fois envfs déclaré.
Ce qui n'a pas de roue amont se compile et réclame ses en-têtes : ils sont
liés au profil du système, leurs bibliothèques vont au chargeur, et
pg_config — dérivation à part dans nixpkgs — est nommé. La sortie « doc »
de CPython est écartée : sa construction est un Sphinx de 3 000 pages qui
domine le temps d'installation d'une VM de 4 Go.
--- EN ---
ERPLibre's bootstrap did not reach NixOS: the Makefile forces "SHELL :=
/bin/bash", which the image lacks, and the Python provider only looks for
the system interpreter at /usr/bin/pythonX.Y. Both answer once envfs is
declared.
What has no upstream wheel compiles and demands its headers: they are
linked into the system profile, their libraries reach the loader, and
pg_config — a separate derivation in nixpkgs — is named. CPython's "doc"
output is left out: building it is a 3000-page Sphinx run that dominates
install time on a 4 GB VM.
Assisted-by: Claude Opus 5
Deux réglages régionaux échouaient sur toute VM Debian, et le seul signe
en était le mot « error » dans un compte-rendu qui le porte à chaque fois.
« update-locale » refuse un locale qui n'est pas généré, et le module du
clavier finit par redémarrer console-setup, absent de l'image
genericcloud : le réglage est écrit avant cet échec, donc le poser
nous-mêmes ne perd que la console texte.
Et l'installateur nix n'écrit plus dans ~/.bashrc : un fichier que
l'utilisateur possède ne se modifie pas pour la durée d'un amorçage.
--- EN ---
Two regional settings failed on every Debian VM, and the only sign was the
word "error" in a report that carries it every time. "update-locale"
refuses a locale that is not generated, and the keyboard module ends by
restarting console-setup, absent from the genericcloud image: the setting
is written before that failure, so placing it ourselves loses only the
text console.
And the nix installer no longer writes into ~/.bashrc: a file the user
owns is not edited for the duration of a bootstrap.
Assisted-by: Claude Opus 5
Neuvième système du catalogue, et le seul dont aucune distribution ne
publie d'image cloud : celle d'un tiers est épinglée et sa somme vérifiée
à chaque téléchargement. Son seed diffère aussi — networkd prend la clé
d'un bloc pour un NOM d'interface là où netplan honore un « match: », et
sshd refuse un compte dont le shell n'existe pas, d'où /bin/sh.
Ses dépendances se DÉCLARENT dans conf/nixos/erplibre.nix : envfs répond
à /usr/bin/env, nix-ld donne aux roues manylinux leur chargeur. Vérifié
sur une VM : le verrou de 362 paquets s'installe et Odoo répond.
--- EN ---
Ninth system of the catalogue, and the only one no distribution publishes
a cloud image for: a third party's is pinned and its sum verified at every
download. Its seed differs too — networkd reads a block's key as an
interface NAME where netplan honours a "match:", and sshd refuses an
account whose shell does not exist, hence /bin/sh.
Its dependencies are DECLARED in conf/nixos/erplibre.nix: envfs answers
/usr/bin/env, nix-ld gives manylinux wheels their loader. Checked on a VM:
the 362-package lock installs and Odoo answers.
Assisted-by: Claude Opus 5
Le cache ne diminuait jamais de lui-même et vit sur le disque de
l'orchestrateur : un parc qui déploie chaque jour finissait par le remplir,
sans que rien ne le signale. Deux règles existent désormais, éteintes par
défaut et réglées depuis le menu : l'âge du dernier usage, et un plafond de
taille qui efface le moins récemment servi jusqu'à tenir dessous, objets et
dépôts git confondus. Un minuteur systemd quotidien les applique, et une
réinstallation garde les valeurs choisies. Le menu montre d'abord ce qui
partirait.
--- EN ---
The cache never shrank by itself and lives on the orchestrator's disk: a site
deploying every day filled it up with nothing to say so. Two rules now exist,
off by default and set from the menu: the age of last use, and a size ceiling
that erases the least recently served until the cache fits under it, objects
and git mirrors alike. A daily systemd timer applies them, and a reinstall
keeps the chosen values. The menu first shows what would go.
Assisted-by: Claude Opus 5
Each campaign covered one system, so proving the cache beyond Ubuntu meant
relaunching by hand and comparing reports one by one. --distro now accepts
« tous » or a comma list: each system runs its full campaign with the
catalogue version, its VMs are destroyed before the next one — three VMs per
system would not fit together on the host disk — and a table compares verdict,
durations and upstream bytes. A failure does not stop the series; an unknown
name is refused before any VM is created. Checked: tests and mutations.
--- FR ---
Chaque campagne couvrait un système : prouver le cache au-delà d'Ubuntu
voulait dire relancer à la main et comparer les rapports un à un. --distro
accepte désormais « tous » ou une liste : chaque système fait sa campagne
complète avec la version du catalogue, ses VM sont défaites avant le suivant —
trois VM par système ne tiendraient pas ensemble sur le disque de l'hôte — et
un tableau compare verdict, durées et octets d'amont. Un échec n'arrête pas la
série ; un nom inconnu est refusé avant qu'aucune VM ne soit créée. Vérifié :
tests et mutations.
Assisted-by: Claude Opus 5
Sur une installation complète, les index pip, les métadonnées npm et le
bundle de repo pesaient environ 110 Mo par VM, repris en entier à chaque
fois. Un index déjà gardé part désormais avec son ETag : l'amont juge chaque
requête, et un « 304 » sert le corps depuis le disque. Sous « Vary: Accept »,
chaque représentation est rangée à part, faute de quoi deux clients qui
alternent les retéléchargent tour à tour. Les métadonnées PEP 658 de pip,
nommées « .whl.metadata », sont figées comme l'archive qu'elles décrivent.
--- EN ---
On a full install the pip indexes, npm metadata and repo bundle weighed about
110 MB per VM, taken whole every time. An index already kept now leaves with
its ETag: upstream judges every request, and a « 304 » serves the body from
disk. Under « Vary: Accept » each representation is stored apart, without
which two clients alternating between them re-download each in turn. The
PEP 658 metadata of pip, named « .whl.metadata », are as immutable as the
archive they describe.
Assisted-by: Claude Opus 5
Le binaire ne parlait que français alors que le menu suit EL_LANG : un
opérateur anglophone lisait un statut qu'il ne comprenait pas. Chaque message
humain passe par T(), dont la clé EST le texte français, et un catalogue
anglais le traduit ; la langue vient de --lang, puis d'EL_LANG, le français
restant le défaut. Le menu demande le français pour ce qu'il RELIT, ses
motifs ne connaissant que cette langue. Un test refuse un message sans
traduction, une traduction orpheline et un verbe de format qui diverge.
--- EN ---
The binary spoke French only while the menu follows EL_LANG: an English
reader got a status he could not read. Every human message goes through T(),
whose key IS the French text, and an English catalogue translates it; the
language comes from --lang, then EL_LANG, French remaining the default. The
menu asks for French for what it READS BACK, its patterns knowing that
language alone. A test refuses a message without translation, an orphan
translation, and a format verb that drifts.
Assisted-by: Claude Opus 5
The Unreleased section describes what the preceding commits deliver: the QEMU
download cache and its git mirrors, offline deployment for QEMU and Proxmox VE,
Proxmox 3D acceleration, and the install fixes that go with them. Each entry
says what the software now does or refuses, for a reader choosing whether to
upgrade. CHANGELOG.md and CHANGELOG.fr.md are the files mmg generates from
CHANGELOG.base.md.
--- FR ---
La section du non-publié décrit ce que livrent les commits qui précèdent : le
cache de téléchargement QEMU et ses miroirs git, le déploiement hors ligne
pour QEMU et Proxmox VE, l'accélération 3D sous Proxmox, et les corrections
d'installation qui les accompagnent. Chaque entrée dit ce que le logiciel fait
ou refuse désormais, pour qui choisit de mettre à jour. CHANGELOG.md et
CHANGELOG.fr.md sont les fichiers que mmg génère depuis CHANGELOG.base.md.
Assisted-by: Claude Opus 5
Trois entrées sous [Unreleased] : une sous Ajouté pour la dépendance de rendu
markdown, deux sous Corrigé pour le démarrage des scripts Selenium sur un
Python sans tkinter et pour le mode sombre en fenêtre privée.
La source est CHANGELOG.base.md ; la paire générée par make doc_markdown suit
dans le même commit, étant ce que la plupart des lecteurs ouvrent. Vérifié :
les listes anglaise et française portent le même nombre de puces dans chaque
section, Ajouté 16 et Corrigé 8.
--- EN ---
Three entries under [Unreleased]: one under Added for the markdown rendering
dependency, two under Fixed for the Selenium scripts starting on a Python
without tkinter and for dark mode in a private window.
The source is CHANGELOG.base.md; the pair generated by make doc_markdown
follows in the same commit, being what most readers actually open. Checked:
the English and French lists carry the same number of bullets in every
section, Added 16 and Fixed 8.
Assisted-by: Claude Opus 5
Partager un fichier ou une base demandait d'anonymiser à la main,
colonne par colonne, ou de ne pas partager. L'entrée ouvre un fichier
externe — Excel, Access, CSV, XML, JSON — ou une base Odoo, dit ce
qu'elle porte, puis en tire une copie. L'original n'est jamais touché.
Deux règles gouvernent ce qui sort. Une colonne n'est laissée intacte
que sur son CONTENU mesuré, hors onze étiquettes structurelles : décider
sur l'étiquette recopiait les colonnes les plus identifiantes en les
annonçant protégées. Et la copie est relue octet par octet, un classeur
portant de la donnée en une douzaine d'endroits hors des cellules.
Vérifié : 5 748 tests — 13 rouges, déjà rouges sur master.
--- EN ---
Sharing a file or a database meant anonymising by hand, column by
column, or not sharing. The entry opens an external file — Excel,
Access, CSV, XML, JSON — or an Odoo database, says what it holds, then
draws a copy of it. The original is never touched.
Two rules govern what comes out. A column is left alone on its measured
CONTENT, bar eleven structural labels: deciding on the label copied the
most identifying columns verbatim while announcing them as protected.
And the copy is reread byte by byte, a workbook holding data in a dozen
places that are not cells.
Checked: 5,748 tests — 13 red, already red on master.
Assisted-by: Claude Opus 5
L'entrée « non publié » ne portait que la fonctionnalité. Un lecteur qui
décide d'une mise à jour n'y voyait ni le mot de passe root qu'on ne lui
demande plus, ni le drapeau qui repart sur Python 3.14, ni la clé d'API
désormais caviardée dans une trace.
Trois sections dans l'ordre du fichier — six correctifs, un retrait de
dépendance, une entrée de sécurité — et une puce de plus sous « Ajouté » pour
le signal neuf de l'outil d'hygiène. Les deux langues portent le même nombre
de puces dans le même ordre, vérifié par comptage : les deux listes se lisent
côte à côte, et une puce d'un seul côté laisse l'autre moitié fausse.
--- EN ---
The "unreleased" entry carried only the feature. A reader deciding on an
upgrade saw neither the root password no longer asked of them, nor the flag
that runs again on Python 3.14, nor the API key now redacted from a trace.
Three sections in the file's own order — six fixes, one dependency removal,
one security entry — and one more bullet under "Added" for the hygiene tool's
new signal. Both languages carry the same number of bullets in the same
order, verified by counting: the two lists are read side by side, and a
bullet on one side only leaves the other half wrong.
Assisted-by: Claude Opus 5
L'entrée « Question IA » envoyait toute question à une seule API distante, sur
un modèle figé et sans historique : aucun serveur local n'était atteignable,
et rien ne disait où partait le texte.
Deux règles gouvernent ce qui la remplace. Un port ne dit jamais qui répond —
un seul en héberge jusqu'à trois, et une famille réémet l'API d'une autre en
entier — donc l'identité se lit dans le CORPS, par une échelle ordonnée. Et
une adresse ne devient jamais du texte d'invite : le détecteur du dépôt ne
voit pas les noms d'hôte, d'où une poignée opaque à sa place.
Vérifié : 284 tests, et contre un serveur du réseau — reconnaissance,
capacités lues, conversation multi-tours, triage juste.
--- EN ---
The "AI question" entry sent every question to a single remote API, on a
frozen model and with no history: no local server was reachable, and nothing
said where the text was going.
Two rules govern what replaces it. A port never says who answers — one hosts
up to three products, and one family re-serves another's native API in full —
so identity is read from the BODY, by an ordered ladder. And an address never
becomes prompt text: the repository's detector does not see host names, hence
an opaque handle in its place.
Checked: 284 tests, and against a server on the network — recognition,
capabilities read, a multi-turn conversation, a correct triage.
Assisted-by: Claude Opus 5
Huit puces sous « Unreleased », pour qui choisit de mettre à jour et non
pour qui relit le diff : ce que l'outil joint désormais, et ce qu'il
refusait avant. Le VPN lui-même est arrivé en 1.8.0 ; ces lignes disent
ce qui s'y ajoute.
La section « Added » n'existait pas encore sous « Unreleased » : elle est
créée dans les deux langues, au format du fichier, et les deux listes se
lisent côte à côte dans le même ordre. Régénéré par mmg. Rien
d'identifiant : ni établissement, ni passerelle réelle, ni adresse.
--- EN ---
Eight bullets under "Unreleased", written for someone choosing whether to
upgrade and not for someone reviewing the diff: what the tool now reaches,
and what it used to refuse. The VPN itself landed in 1.8.0; these lines
say what is being added to it.
The "Added" section did not exist yet under "Unreleased": it is created in
both languages, in the file's own format, and the two lists read side by
side in the same order. Regenerated by mmg. Nothing identifying: no
institution, no real gateway, no address.
Assisted-by: Claude Opus 5
Les 39 puces du non-publié décrivent du travail fini qu'aucun numéro ne
permettait de citer. La section 1.8.0 les porte, avec la note de migration que
réclament le choix de l'interpréteur Python et le retrait d'Ubuntu 20.04 et
22.04. La version déclarée suit, comme le veut doc/RELEASE.base.md : le
fichier semver que lit env_var.sh, les huit pyproject, npm, CLAUDE.md et la
note des versions supportées. La ligne de contracts/compatibility.json reste
en 1.7.0, elle atteste un appariement mobile éprouvé et non la version
courante. Le commentaire de todo.py ne nomme plus de version, celle du dépôt
étant marquée « default » dans le fichier des versions supportées.
Vérifié : ERPLIBRE_VERSION=1.8.0, parité 17/8/10/2/2, tests de version verts.
--- EN ---
The unreleased list's 39 entries describe finished work no number could cite.
The 1.8.0 section carries them, with the migration note that choosing the
Python interpreter and dropping Ubuntu 20.04 and 22.04 call for. The declared
version follows, as doc/RELEASE.base.md wants: the semver file env_var.sh
reads, the eight pyproject files, npm, CLAUDE.md and the supported-version
note. The contracts/compatibility.json row stays at 1.7.0, attesting a tested
mobile pairing and not the current version. The todo.py comment names no
version any more, the repository's own being marked « default » in the
supported-version file. Checked: ERPLIBRE_VERSION=1.8.0, 17/8/10/2/2 parity,
version tests green.
Assisted-by: Claude Opus 5
La section portait 152 puces par langue, souvent d'un paragraphe chacune :
illisible pour qui décide s'il met à jour, et un changelog se lit pour
décider, non pour relire un diff. Elle en porte 39, d'une ligne, regroupées
par sujet pour qu'aucun thème ne disparaisse — les 24 puces sur les VM QEMU
tiennent en cinq lignes, les 14 correctifs d'installation en une. Le détail
part volontairement ; il reste dans les commits. Restent la liste des
distributions, qu'un lecteur y cherche la sienne, et les chiffres qui bornent
en trois mots. Vérifié : parité 17/8/10/2/2 dans les deux langues.
--- EN ---
The section carried 152 entries per language, often a paragraph each:
unreadable for someone deciding whether to upgrade, and a changelog is read
to decide, not to review a diff. It now carries 39, one line each, grouped by
subject so no theme disappears — the 24 entries on QEMU VMs fit in five
lines, the 14 installation fixes in one. The detail goes deliberately; it
stays in the commits. What stays is the distribution list, so a reader can
look for their own, and the figures that bound a fix in three words.
Checked: 17/8/10/2/2 parity in both languages.
Assisted-by: Claude Opus 5
Le tag v1.7.0 existe depuis le 11 mars 2026 sans section : ses 209 commits
restaient au non-publié, où un lecteur qui compare une version à ses notes ne
trouvait rien. Le tri suit l'ascendance du tag et non la date d'écriture d'une
puce : le changelog AU tag en donne 19, et douze autres, écrites depuis,
décrivaient du travail antérieur — script/qemu, analyse, proxmox, vpn et
long_test n'existaient pas encore. Le non-publié portait deux sections Modifié
et deux Corrigé, fusionnées dans l'ordre canonique ; ses puces passent de 181
à 152 par langue. La liste des dépendances Odoo 18 mêlait 2024, 1.7.0 et
l'après-tag : seul flanker y reste. Vérifié : parité en/fr par section.
--- EN ---
Tag v1.7.0 has existed since 11 March 2026 with no section: its 209 commits
stayed in the unreleased list, where a reader comparing a version to its notes
found nothing. The sort follows ancestry of the tag, not the date an entry was
written: the changelog AT the tag gives 19 of them, and twelve more, written
since, described earlier work — script/qemu, analyse, proxmox, vpn and
long_test did not exist yet. The unreleased list carried two Changed and two
Fixed sections, now merged in canonical order; its entries go from 181 to 152
per language. The Odoo 18 dependency list mixed 2024, 1.7.0 and post-tag work:
only flanker stays there. Checked: en/fr parity per section.
Assisted-by: Claude Opus 5
Cinq correctifs et une icône de menu passaient d'une branche à la production
sans qu'un lecteur qui décide de mettre à jour puisse le savoir : les cinq
commits QEMU du lot étaient décrits, ceux des outils git et du menu non. Le
non-publié les porte désormais, avec le mode de défaillance retiré et le
chiffre qui le borne — une page HTML de 34 ko avalée par « sh », un lot de
plus de cent dépôts abandonné, 49 tests et une erreur d'import devenus 84.
Les six entrées suivent le même ordre dans les deux langues, la source étant
CHANGELOG.base.md, et make doc_markdown a régénéré la paire.
--- EN ---
Five fixes and one menu icon went from a branch to production with no way for
a reader deciding whether to upgrade to know it: the batch's five QEMU commits
were described, those of the git tools and of the menu were not. The unreleased
section now carries them, with the failure mode removed and the figure that
bounds it — a 34 kB HTML page swallowed by `sh`, a batch of more than a hundred
repositories abandoned, 49 tests and an import error turned into 84. The six
entries follow the same order in both languages, the source being
CHANGELOG.base.md, and make doc_markdown regenerated the pair.
Assisted-by: Claude Opus 5
Une VM prend son adresse dans le /24 de son réseau et en sort par le .1,
porté par le pont : déplacer ce /24 sous une VM allumée lui laisse un bail
qui ne mène nulle part, et abattre le réseau détache son tap, que libvirt
n'y remet pas. network_qemu.py tient les trois gestes dans l'ordre — arrêter
les VM attachées, redéfinir le réseau sur le préfixe voulu, rallumer celles
qu'il a arrêtées, elles seules. Une VM sourde au shutdown annule la
redéfinition plutôt que d'y perdre son pont ; --force-off coupe le courant.
Un préfixe qui recouvre ce que l'hôte route déjà est refusé.
Vérifié : 13 tests neufs, la numérotation du menu, une passe à blanc.
--- EN ---
A VM takes its address in its network's /24 and leaves through the .1,
carried by the bridge: moving that /24 under a live VM leaves it a lease
leading nowhere, and tearing the network down detaches its tap, which
libvirt does not put back. network_qemu.py holds the three steps in order —
shut down the attached VMs, redefine the network on the wanted prefix, start
again the ones it stopped, those only. A VM deaf to the shutdown cancels the
redefinition rather than losing its bridge; --force-off cuts the power.
A prefix overlapping what the host already routes is refused.
Checked: 13 new tests, the menu numbering, one dry run.
Assisted-by: Claude Opus 5
Un réseau libvirt démarré porte et route son /24 sur son pont, et ce pont
comptait dans « ce que l'hôte occupe déjà » : le verdict était donc
« collision » sur toute machine où le réseau tournait, quel que soit son
sous-réseau. Tout déploiement passe par cette vérification, qui abattait
alors le réseau et le déplaçait sur un /24 libre là où rien n'entrait en
conflit — les VM attachées y perdaient passerelle et pont. Le pont du réseau
examiné en est écarté, chaque adresse étant rattachée à son interface ; un
nom de pont illisible n'écarte rien. Le XML de net-define passe par un
fichier temporaire imprévisible, retiré même quand virsh échoue.
Vérifié : 31 tests, dont 10 neufs, que le retrait de l'exclusion casse.
--- EN ---
A started libvirt network carries and routes its /24 on its bridge, and that
bridge counted as « what the host already occupies »: the verdict was
therefore « collision » on every machine where the network ran, whatever
subnet it served. Every deployment goes through that check, which then tore
the network down and moved it onto a free /24 where nothing conflicted — the
attached VMs lost gateway and bridge. The bridge of the network being
examined is now excluded, each address being tied to its own interface; an
unreadable bridge name excludes nothing. The XML for net-define goes through
an unpredictable temporary file, removed even when virsh fails.
Checked: 31 tests, 10 of them new, which removing the exclusion breaks.
Assisted-by: Claude Opus 5
sudo ne dit jamais ce qu'il sert à faire : son invite tombe entre deux lignes
de journal, et l'on tape un mot de passe sans savoir s'il porte sur libvirt,
sur un paquet ou sur un fichier — d'autant qu'appartenir au groupe libvirt a
l'air de suffire. Il ne suffit pas, et libvirt n'y est pour rien : le disque
et le seed s'écrivent dans le pool par défaut, répertoire de root où le
groupe ne donne pas l'écriture. Le motif est constaté, non déduit :
l'écriture s'essaie, une ACL pouvant l'accorder là où le mode semble la
refuser. Dit une fois avant la première commande privilégiée, et en dernière
ligne du récapitulatif. Vérifié : 18 tests, root compris, à qui rien n'est dit.
--- EN ---
sudo never states what it is about to do: its prompt lands between two log
lines, and one types a password without knowing whether it covers libvirt, a
package or a file — the more so as being in the libvirt group looks like it
should be enough. It is not, and libvirt is not the reason: the disk and the
seed are written into the default pool, a root-owned directory where the
group grants no write right. The reason is checked, not deduced: writing is
tried, since an ACL can grant it where the mode seems to refuse it. Said once
before the first privileged command, and last on the review page. Checked: 18
tests, root included, which is told nothing.
Assisted-by: Claude Opus 5
Le réseau « default » de libvirt sert 192.168.122.0/24, et toute VM déployée
par ce dépôt y vit : son pont prendrait la première adresse du /24, celle de
sa passerelle. virsh refuse ce démarrage tant que la route est là ; au
démarrage, libvirtd monte ses réseaux avant le bail DHCP, et plus rien ne la
signale. L'autostart était armé même après un net-start refusé, d'où un hôte
sans réseau au redémarrage suivant. Il ne s'arme plus qu'en l'absence de
collision, le réseau est déplacé par redéfinition — ni pont ni module du
noyau — et un actif en collision est abattu. L'état, cherché en anglais quand
virsh traduit, se lisait toujours éteint : LC_ALL=C. Vérifié sur un hôte en
collision, puis 21 tests.
--- EN ---
libvirt's `default` network serves 192.168.122.0/24, and every VM this
repository deploys lives there: its bridge would take the /24's first
address, which is that machine's gateway. virsh refuses such a start while
the route is there; at boot, libvirtd raises its networks before the DHCP
lease, and nothing signals the collision. Autostart was armed even after a
refused net-start, hence a host with no network at the next boot. It is armed
only where no collision remains, the network is moved by redefinition — no
bridge, no kernel module — and an active collision is torn down. State, read
in English where virsh translates, always read as off: LC_ALL=C. Checked on a
colliding host, then 21 tests.
Assisted-by: Claude Opus 5
L'option des outils d'assistance posait trois installateurs amont, puis
laissait tout à retaper : hook global de rtk, zdiff3, hooks git du dépôt,
commandes Claude, activation du venv. Elle les pose, en deux temps parce que
hooks et gabarits VIVENT dans le dépôt ; le complément suit le clone, rend
toujours 0 — un confort ne fait pas échouer une VM — et sans clone la moitié
manquante est nommée. core.editor n'est posé qu'à défaut, l'hôte transmettant
déjà le sien. L'aide « ? » et F1 dit ce que chaque option installe, là où un
libellé de case porte trois des huit poses. Vérifié : 51 tests, les deux
écrans montés sans terminal, « bash -n » sur les fragments distants.
--- EN ---
The AI tools box posed three upstream installers, then left every setting to
retype: rtk's global hook, zdiff3, the checkout's git hooks, the Claude
commands, activating the venv. It poses them, in two phases because hooks and
templates LIVE in the checkout; the complement follows the clone, always
returns 0 — a comfort must not fail a VM — and with no clone the missing half
is named. core.editor is posed only where there is none, the host already
transmitting its own. The `?` and F1 help says what each option installs,
where a checkbox label carries three of this one's eight poses. Checked: 51
tests, both screens mounted headless, `bash -n` on the remote fragments.
Assisted-by: Claude Opus 5
La branche part de master : elle livre l'outil entier, pas des retouches.
Deux puces sous Ajouté — l'outil et son diagnostic étagé — et une sous
Corrigé pour le coffre KeePassXC, qui ne doit rien au VPN et servait déjà
ailleurs.
Ce qu'une branche corrige de son propre travail n'y figure pas : le lanceur
de tests et ses huit fichiers muets sont revenus à l'état de master, et une
puce les annonçant décrirait un aller-retour invisible du dehors.
--- EN ---
The branch forks from master: it delivers the whole tool, not touch-ups. Two
bullets under Added — the tool and its staged diagnosis — and one under Fixed
for the KeePassXC vault, which owes nothing to the VPN and already served
elsewhere.
What a branch fixes in its own work is absent: the test launcher and its
eight silent files are back to master's state, and a bullet announcing them
would describe a round trip invisible from outside.
Assisted-by: Claude Opus 5
Le journal s'arrêtait à la fusion précédente : trente-deux commits n'y
figuraient pas, l'outillage de migration d'un côté, la convention d'écriture
et ses garde-fous de l'autre.
Dix-sept entrées les couvrent, en Ajouté, Modifié, Corrigé et Retiré. Le
`.base.md` est édité et mmg régénère les deux fichiers dérivés, qui ne se
modifient jamais à la main.
Vérifié : autant de puces en français qu'en anglais dans chaque section, et
aucune donnée identifiante. `[Unreleased]` porte deux sections Modifié et
deux Corrigé, défaut antérieur ; les entrées vont dans les premières.
--- EN ---
The changelog stopped at the previous merge: thirty-two commits were missing
from it, the migration tooling on one side, the writing convention and its
guard rails on the other.
Seventeen entries cover them, across Added, Changed, Fixed and Removed. The
`.base.md` is edited and mmg regenerates the two derived files, which are
never edited by hand.
Checked: as many French bullets as English ones in every section, and no
identifying data. `[Unreleased]` carries two Changed and two Fixed sections,
a pre-existing defect; the entries go into the first of each.
Assisted-by: Claude Opus 5
Trois défauts trouvés en une heure par le premier lancement réel — c'est ce
qu'un test d'intégration doit produire.
1. « --setup-host » a échoué en ZÉRO seconde sur « Unable to locate package
qemu-system-x86 », alors que le paquet existe : la VM venait de démarrer et
ses listes ne portaient que bookworm-security. Le message envoyait chercher
des paquets, pas des listes. Même parade qu'install_proxmox.sh — arrêter
apt-daily, puis réessayer.
2. Le réseau « default » de libvirt sert 192.168.122.0/24 à TOUS les étages.
L'étage 2, dont l'adresse VENAIT de ce réseau, voyait son propre net-start
refusé : « Network is already in use by interface enp1s0 ». Un invité qui
vit dans un réseau ne peut pas servir le même. Chaque étage prend le sien,
déduit de sa profondeur absolue, et le REDÉFINIT avant de le démarrer.
3. Le mien : l'extraction du moteur avait coupé preparer_systeme sur le
« return False » de sa boucle, sans son « return True ». La fonction rendait
None, donc l'étape échouait SANS RIEN DIRE, et les deux piles étaient
cassées. L'essai à blanc ne pouvait pas le voir — il sort avant. Un test
d'AST interdit désormais qu'une étape retombe sur None.
long_test/ était introuvable hors du menu : une ligne dans CLAUDE.md, trois
entrées au CHANGELOG, deux sections au README.
--- EN ---
Three defects found in one hour by the first real run — which is what an
integration test is for.
1. "--setup-host" failed in ZERO seconds on "Unable to locate package
qemu-system-x86" though the package exists: the VM had just booted and its
lists carried only bookworm-security. The message sent us looking for
packages, not for lists. Same remedy as install_proxmox.sh — stop
apt-daily, then retry.
2. libvirt's "default" network serves 192.168.122.0/24 at EVERY level. Level 2,
whose own address CAME from that network, had its net-start refused:
"Network is already in use by interface enp1s0". A guest living inside a
network cannot serve the same one. Each level takes its own, derived from
its absolute depth, and REDEFINES it before starting it.
3. Mine: extracting the engine had cut preparer_systeme at its loop's "return
False", without the final "return True". The function returned None, so the
step failed SAYING NOTHING, and both stacks were broken. The dry run could
not see it — it exits earlier. An AST test now forbids a step from falling
through to None.
long_test/ was undiscoverable outside the menu: one line in CLAUDE.md, three
CHANGELOG entries, two README sections.
Assisted-by: claude-opus-5
(cherry picked from commit e46bad408143f7511a04ffdc6a20efdb785f4b5e)
Le journal ne disait rien de Proxmox, ni de l'anonymisation, ni de
l'éclatement de todo.py — soit l'essentiel de ce qui attend un merge dans
master. Une relecture de 67 commits ne devrait pas commencer par lire 67
commits.
Les entrées suivent les six segments du plan de merge : ce qui précède la
factorisation, la factorisation elle-même, l'écran Proxmox, les réparations
de migration, l'audit, et le choix par VM.
Une section Modifié apparaît, qui manquait à Non publié : un déplacement de
9 500 lignes n'est ni un ajout ni un correctif, et le classer ailleurs
aurait menti sur sa nature.
--- EN ---
The log said nothing of Proxmox, nor of the anonymisation, nor of todo.py
being split — that is most of what is waiting to be merged into master. A
review of 67 commits should not have to start by reading 67 commits.
The entries follow the six segments of the merge plan: what precedes the
split, the split itself, the Proxmox screen, the migration repairs, the
audit, and the per-VM choice.
A Changed section appears, which Unreleased lacked: moving 9 500 lines is
neither an addition nor a fix, and filing it elsewhere would have misstated
what it is.
Assisted-by: Claude Opus 5