Unpinned, openai and fsspec float to releases that break resolution:
openai 3.x needs idna>=3.18 against the idna==3.6 of Odoo, and s3fs
wants fsspec at its own exact version. openai stays on 2.x, fsspec moves
with s3fs, idna 3.20 overrides Odoo (3.6 carries CVE-2024-3651).
meteostat returns to 1.x, every 2.x caps pytz below 2024. The s390x
exclusion of PyMuPDF now lives in the requirements, so it survives.
Checked: no dependency leaves the pyproject (194 to 196) or the lock.
Not tested: majors ujson 6, plotly 7, python-slugify 9, sqlalchemy 2.1.
--- FR ---
[UPD] requirement : lock Odoo 18 à jour, épingles openai, idna et fsspec
Sans borne, openai et fsspec dérivent vers des versions qui cassent la
résolution : openai 3.x exige idna>=3.18 contre l'idna==3.6 d'Odoo, et
s3fs veut fsspec à sa propre version exacte. openai reste en 2.x, fsspec
suit s3fs, idna 3.20 supplante Odoo (la 3.6 porte CVE-2024-3651).
meteostat revient en 1.x, toute 2.x plafonne pytz sous 2024. L'exclusion
s390x de PyMuPDF vit désormais dans les requirements : elle survit.
Vérifié : aucune dépendance ne quitte le pyproject (194 à 196) ni le lock.
Non testé : majeures ujson 6, plotly 7, python-slugify 9, sqlalchemy 2.1.
Assisted-by: Claude Opus 5.5
Every meteostat 2.x release, 2.0.0 to 2.1.5, requires pytz <2024.0.
Odoo leaves pytz unpinned, so the resolution takes the current release
and meteostat 2.x makes it fail; forcing pytz down instead would freeze
the timezone data of every Odoo instance. meteostat 1.x leaves pytz
free, so only its minor and patch updates are proposed.
Checked: requires_dist of each 2.x release on PyPI; the YAML parses.
--- FR ---
[UPD] dependabot : ignorer les versions majeures de meteostat
Chaque version 2.x de meteostat, de 2.0.0 à 2.1.5, exige pytz <2024.0.
Odoo laisse pytz libre, la résolution prend donc la version courante et
meteostat 2.x la fait échouer ; forcer pytz vers le bas figerait les
données de fuseaux horaires de toute instance Odoo. meteostat 1.x laisse
pytz libre : seules ses versions mineures et correctives sont proposées.
Vérifié : requires_dist de chaque version 2.x sur PyPI ; le YAML se lit.
Assisted-by: Claude Opus 5.5
Poetry works in the active virtualenv when VIRTUAL_ENV is set. Launched
from a shell under .venv.erplibre, poetry add and poetry lock inherited
its Python, outside the pyproject bounds, and failed with
InvalidCurrentPythonVersionError. Both calls now activate the Odoo venv
of the ERPLibre version, as install_locally.sh already does.
Checked: poetry env info -p reports .venv.erplibre before, the Odoo
venv after, for the shell script and for the Python call alike.
--- FR ---
[FIX] poetry update : poetry dans le venv Odoo, pas dans le venv actif
Poetry travaille dans le virtualenv actif quand VIRTUAL_ENV est posé.
Lancés d'un shell sous .venv.erplibre, poetry add et poetry lock en
héritaient le Python, hors des bornes du pyproject, et échouaient sur
InvalidCurrentPythonVersionError. Les deux appels activent désormais le
venv Odoo de la version ERPLibre, comme le fait déjà install_locally.sh.
Vérifié : poetry env info -p donne .venv.erplibre avant, le venv Odoo
après, pour le script shell comme pour l'appel Python.
Assisted-by: Claude Opus 5.5
The root pyproject.toml and poetry.lock are unversioned symlinks to the
active version's files in requirement/, created by the version switch.
Without them the script died on a FileNotFoundError traceback. It now
names the fix, make switch_odoo_XX for the active Odoo version; on a
terminal it offers to run it and restarts with the same arguments.
Checked: an existing file passes, a missing one exits 1 off a terminal
and on a declined prompt. The accepted path, which runs the switch, is
not tested.
--- FR ---
[FIX] poetry update : arrêt sur pyproject.toml absent, switch proposé
pyproject.toml et poetry.lock à la racine sont des liens non versionnés
vers les fichiers de la version active dans requirement/, créés par le
switch de version. Sans eux, le script mourait sur un FileNotFoundError.
Il nomme désormais le remède, make switch_odoo_XX pour la version Odoo
active ; dans un terminal, il propose de le lancer et se relance avec
les mêmes arguments. Vérifié : un fichier présent passe, un absent sort
en 1 hors terminal et sur un refus. L'acceptation, qui lance le switch,
n'est pas testée.
Assisted-by: Claude Opus 5.5
Security updates reuse a dependabot.yml entry only when its directory
matches the manifest's; they scan requirement/ as "/requirement", which
no entry declared, so their pull requests bumped the frozen pins of
Odoo 12 to 17. Only Odoo 18 now receives updates. Globs replace the
exact names and also cover ignore_requirements, pyproject and poetry.lock.
Checked: the YAML parses and the globs match 27 files in requirement/,
none for odoo18. Not yet checked on GitHub: takes effect once on master.
--- FR ---
[FIX] dependabot : exclure aussi Odoo 12-17 des mises à jour de sécurité
Les mises à jour de sécurité ne reprennent une entrée de dependabot.yml
que si son répertoire correspond à celui du manifeste ; elles lisent
requirement/ comme « /requirement », qu'aucune entrée ne déclarait, d'où
des PR qui modifiaient les versions figées d'Odoo 12 à 17. Seul Odoo 18
reçoit désormais les mises à jour. Des globs remplacent les noms exacts
et couvrent aussi ignore_requirements, pyproject et poetry.lock.
Vérifié : le YAML se lit et les globs ciblent 27 fichiers de requirement/,
aucun pour odoo18. Non vérifié sur GitHub : effectif une fois sur master.
Assisted-by: Claude Opus 5.5
[IMP] todo: safe startup, Claude command sync, English-first commits
8 commits. make runs todo.sh, whose name says a menu opens; install.sh keeps
choosing the interpreter, now probed by running code, since python -V
vouched for a venv built on another machine that could not start. The
install, which deletes an existing .venv.erplibre, runs only on a yes. The
Claude command list shows missing and outdated copies, their diff, and
redeploys them; commit messages open in English with a French title under
--- FR ---, enforced by the hook; language and Fork move to Configuration.
Checked: unit suites of each piece pass, 108 in test_todo and i18n.
--- FR ---
[IMP] todo : démarrage sûr, commandes Claude à jour, commits en anglais
8 commits. make lance todo.sh, dont le nom annonce un menu ; install.sh garde
le choix de l'interpréteur, sondé désormais en exécutant du code, puisque
python -V cautionnait un venv bâti sur une autre machine incapable de
démarrer. L'installation, qui supprime un .venv.erplibre existant, ne part
que sur un oui. La liste des commandes Claude montre les copies absentes et
périmées, leur diff, et les redéploie ; les messages de commit s'ouvrent en
anglais avec un titre français sous --- FR ---, que le hook exige ; la
langue et Fork passent dans Configuration.
Vérifié : suites unitaires de chaque partie au vert, 108 pour test_todo et i18n.
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
Execute carried a Preferences section whose one entry, the language, is
already Configuration's first item: two places for one setting. It is
removed, with its two unused translations. Fork, which opens a second TODO,
leaves the main menu for Configuration; the main menu now numbers Telemetry
4 and Configuration 5, and Reset all preferences becomes 6.
Checked: Configuration displayed with Fork at 5; 108 tests pass.
--- FR ---
[IMP] menus todo : langue dans Configuration seule, Fork y déménage
Execute portait une section Préférences dont la seule entrée, la langue, est
déjà la première de Configuration : deux endroits pour un réglage. Elle part,
avec ses deux traductions devenues inutiles. Fork, qui ouvre un second TODO,
quitte le menu principal pour Configuration ; le menu principal numérote
désormais Télémétrie 4 et Configuration 5, et la réinitialisation devient 6.
Vérifié : Configuration affichée avec Fork en 5 ; 108 tests passent.
Assisted-by: Claude Opus 5.5
The language chooser was the only TODO screen without icons, and it spelled
Francais without its accent. The first-launch prompt and the one reached
from Configuration now open on a globe and mark each language with its flag;
the label reads Français in both.
Checked: both prompts displayed; test_todo and i18n tests, 108, pass.
--- FR ---
[IMP] todo : icônes au choix de la langue, accent sur Français
Le choix de la langue était le seul écran de TODO sans icône, et il écrivait
Francais sans accent. L'invite du premier lancement et celle de Configuration
s'ouvrent désormais sur un globe et marquent chaque langue de son drapeau ;
le libellé se lit Français dans les deux.
Vérifié : les deux invites affichées ; test_todo et tests i18n, 108, passent.
Assisted-by: Claude Opus 5.5
The command list showed only what sat in ~/.claude/commands, with a date:
a command never installed stayed invisible, and a copy older than its
template in conf/ looked the same as a current one. Each ERPLibre template is
now compared with its copy, ignoring the git identity line: not installed,
up to date, or to redeploy with its +/- line count; other commands are
marked not from ERPLibre. On y/N it shows the diff, then redeploys the
outdated copies, keeping the name and e-mail /commit carried.
Checked: 7 new tests on a temporary directory; test_todo, 81 tests, passes.
--- FR ---
[IMP] todo configs claude : commandes absentes, périmées, redéploiement
La liste des commandes ne montrait que le contenu de ~/.claude/commands,
avec une date : une commande jamais installée restait invisible, et une copie
plus vieille que son gabarit de conf/ ressemblait à une copie à jour. Chaque
gabarit d'ERPLibre est désormais comparé à sa copie, hors ligne d'identité
git : non installée, à jour, ou à redéployer avec son compte +/- ; les autres
commandes sont marquées hors ERPLibre. Sur o/N elle montre le diff, puis
redéploie les copies périmées en gardant le nom et le courriel de /commit.
Vérifié : 7 nouveaux tests sur un dossier temporaire ; test_todo, 81 tests.
Assisted-by: Claude Opus 5.5
git log --oneline shows only the subject, and it read in whichever language
the author was thinking in. The subject and the body under it are now in
English, then --- FR --- opens the French section, which starts with the
subject translated under the same tag. The hook refuses a --- EN --- marker
and a French section without that title, and checks the title like a
subject; it does not count against the body budget. Whether the subject is
really English is not checked. /commit and /git_prepare_merge follow.
Checked: 55 hook tests, 7 of them new; i18n tests pass.
--- FR ---
[UPD] règle de commit : sujet anglais d'abord, titre FR sous --- FR ---
git log --oneline ne montre que le sujet, et il se lisait dans la langue où
l'auteur pensait. Le sujet et le corps qui le suit sont désormais en anglais,
puis --- FR --- ouvre la section française, qui commence par le sujet traduit
sous le même tag. Le hook refuse un marqueur --- EN --- et une section
française sans ce titre, et juge ce titre comme un sujet ; il ne compte pas
dans le budget du corps. Que le sujet soit vraiment en anglais ne se vérifie
pas. /commit et /git_prepare_merge suivent.
Vérifié : 55 tests du hook, dont 7 nouveaux ; tests i18n au vert.
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
"python -V" answers before loading the standard library. A venv whose
interpreter cannot find it, such as a checkout mounted from another machine,
still reported its version and passed as healthy. install.sh then handed TODO
to it, which died on "No module named 'encodings'", and the "venv built
elsewhere" guard never printed. The probe now runs "import sys": an
interpreter that cannot start returns nothing.
Checked: a fake python that answers -V but fails otherwise makes the test
fail on the old code and pass with the fix.
--- FR ---
[FIX] install.sh : sonder la version en exécutant du code, non par -V
« python -V » répond avant de charger la bibliothèque standard. Un venv dont
l'interpréteur ne la trouve pas, comme un checkout monté depuis une autre
machine, rendait donc sa version et passait pour sain. install.sh lui passait
alors TODO, qui mourait sur « No module named 'encodings' », et le garde
« venv bâti ailleurs » ne s'affichait jamais. La sonde exécute maintenant
« import sys » : un interpréteur qui ne démarre pas ne rend rien.
Vérifié : un faux python sain à -V mais mort ailleurs fait échouer le test
sur l'ancien code et le réussit avec la correction.
Assisted-by: Claude Opus 5.5
« python -V » répond avant de charger la bibliothèque standard. Un venv dont
l'interpréteur ne la trouve pas, comme un checkout monté depuis une autre
machine, rendait donc sa version et passait pour sain. install.sh lui passait
alors TODO, qui mourait sur « No module named 'encodings' », et le garde
« venv bâti ailleurs » ne s'affichait jamais. La sonde exécute maintenant
« import sys » : un interpréteur qui ne démarre pas ne rend rien.
Vérifié : un faux python sain à -V mais mort ailleurs fait échouer le test
sur l'ancien code et le réussit avec la correction.
--- EN ---
"python -V" answers before loading the standard library. A venv whose
interpreter cannot find it, such as a checkout mounted from another machine,
still reported its version and passed as healthy. install.sh then handed TODO
to it, which died on "No module named 'encodings'", and the "venv built
elsewhere" guard never printed. The probe now runs "import sys": an
interpreter that cannot start returns nothing.
Checked: a fake python that answers -V but fails otherwise makes the test
fail on the old code and pass with the fix.
Assisted-by: Claude Opus 5.5
Le formateur de ce dépôt est ruff depuis qu'il remplace black, qui ne connaît
aucune cible au-delà de py313 ; ce passage applique sa norme à l'arbre entier,
d'un coup, pour qu'aucun commit de fond n'ait à porter du style. L'écart tient
presque entièrement aux chaînes coupées à la main que ruff recolle quand elles
tiennent sur une ligne, et aux « with » multiples qu'il regroupe : aucune
valeur ne change, et les clés de traduction non plus.
Vérifié : la suite unitaire reste verte après le passage, et le contrôle de
syntaxe ne signale rien.
--- EN ---
This repository's formatter is ruff since it replaced black, which knows no
target beyond py313; this pass applies its standard to the whole tree at once,
so that no substantive commit has to carry style. The difference is almost
entirely the hand-split strings ruff joins back when they fit on one line, and
the multiple "with" it merges: no value changes, nor do the translation keys.
Checked: the unit suite stays green after the pass, and the syntax check
reports nothing.
Assisted-by: Claude Opus 5
[UPD] outillage : un Python à lui, un formateur par contexte, des gardes
17 commits. Le venv d'outillage prenait le python3 du système, quel qu'il
soit : sur une machine en 3.10, TODO mourait sur une SyntaxError avant tout
message, et rien ne permettait plus de lancer l'installation qui en serait
sorti. Il a désormais sa version, distincte de celle d'Odoo, et le patch ne
borne que cette dernière — l'exiger partout écartait un Python de
distribution d'un cran en retard et faisait compiler CPython pour rien. Le
formatage suit le contexte : ruff ici, la norme OCA pour les modules Odoo.
Debian 11 part, sa suite de sécurité n'étant ni servie ni archivée.
Vérifié : 6764 tests verts, et l'arbre Python parse de 3.10 à 3.14.
--- EN ---
17 commits. The tooling venv took the system python3, whatever it was: on a
3.10 machine TODO died on a SyntaxError before any message, and nothing could
start the install that would have rescued it. It now has its own version,
distinct from Odoo's, and the patch bounds only the latter — requiring it
everywhere turned away a distribution Python one step behind and compiled
CPython for nothing. Formatting follows context: ruff here, the OCA standard
for Odoo modules. Debian 11 goes, its security suite being neither served nor
archived.
Checked: 6764 tests green, and the Python tree parses from 3.10 to 3.14.
Assisted-by: Claude Opus 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
tasks/ porte les notes de travail que la convention garde hors du dépôt, et
.erplibre-state.json l'état de ce qu'un checkout a installé, écrit par
erplibre_state.py. Non ignorés, un « git add -A » les emportait.
--- EN ---
tasks/ holds the working notes the convention keeps out of the repository,
and .erplibre-state.json the state of what a checkout has installed, written
by erplibre_state.py. Left unignored, a "git add -A" swept them in.
Assisted-by: Claude Opus 5
« make version » lit .python-odoo-version et l'affichait sous le libellé nu
« Python version ». Tant que les deux venvs partageaient leur interpréteur, le
libellé suffisait ; depuis qu'ils divergent, il laisse croire que le dépôt n'a
qu'une version de Python, et le chiffre affiché n'est pas celui du venv dans
lequel l'utilisateur travaille. Les deux sont désormais nommées, celle d'Odoo
comme celle de l'outillage. Seule la sortie change : cette valeur ne participe
à aucun identifiant, et l'absence du fichier reste sans conséquence.
Vérifié : les deux versions s'affichent, puis la conclusion reste la même.
--- EN ---
"make version" reads .python-odoo-version and printed it under the bare label
"Python version". While both venvs shared their interpreter the label was
enough; now that they diverge, it suggests the repository has a single Python
version, and the figure shown is not that of the venv the user works in. Both
are now named, Odoo's and the tooling's. Only the output changes: this value
takes part in no identifier, and a missing file stays without consequence.
Checked: both versions print, then the conclusion stays the same.
Assisted-by: Claude Opus 5
Elle faisait ajouter bullseye-security pour y prendre libssl1.1 sur Debian 13.
Ce dépôt n'existe plus : son index est encore publié mais son pool ne porte
plus les fichiers, et rien n'en a été archivé. La recette ne pouvait donc que
donner une source morte, puis une erreur qui n'en désigne pas la cause.
Elle était en outre inutile : le build de wkhtmltopdf qu'on installe là-bas
est celui de bookworm, qui réclame libssl3 — que trixie fournit sous le nom
libssl3t64, en déclarant « Provides: libssl3 ». L'installation se résout donc
seule. La section qui suit garde l'issue de secours, un service en conteneur.
Vérifié : plus aucune mention de bullseye ni de libssl1.1 dans la FAQ.
--- EN ---
It had the reader add bullseye-security to take libssl1.1 from it on Debian
13. That repository is gone: its index is still published but its pool no
longer holds the files, and nothing was archived. The recipe could therefore
only yield a dead source, then an error naming none of its cause. It was
useless besides: the wkhtmltopdf build installed there is bookworm's, which
requires libssl3 — which trixie supplies as libssl3t64, declaring "Provides:
libssl3". The install resolves on its own. The next section keeps the fallback,
a containerised service.
Checked: no mention of bullseye or libssl1.1 left in the FAQ.
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
Les variables du cache — PIP_CERT et ses voisines — recevaient le chemin
canonique de la famille de paquets, sans que rien ne vérifie qu'il soit là. Une
image peut ne pas le porter : sur une Fedora récente,
« /etc/pki/tls/certs/ca-bundle.crt » manque alors que le faisceau extrait
existe. pip refuse alors TOUT téléchargement, y compris ce qui n'a rien à voir
avec le cache, et l'installation s'arrête sur des paquets publics. Le faisceau
de la famille est essayé d'abord, les autres connus ensuite ; aucun trouvé
n'écrit aucune variable, et pip garde son propre jeu de certificats.
Vérifié : la commande produite parcourt les quatre chemins avant de renoncer.
--- EN ---
The cache variables — PIP_CERT and its neighbours — received the canonical path
of the package family, with nothing checking it was there. An image may not
carry it: on a recent Fedora, "/etc/pki/tls/certs/ca-bundle.crt" is missing
while the extracted bundle exists. pip then refuses EVERY download, including
what has nothing to do with the cache, and the install stops on public
packages. The family bundle is tried first, the other known ones next; none
found writes no variable, and pip keeps its own certificate set.
Checked: the produced command walks the four paths before giving up.
Assisted-by: Claude Opus 5
Une image de VM pèse un demi-gigaoctet : une coupure y est bien plus probable
que sur une page. Le contrôle de complétude existait — sans lui un .part
tronqué passait pour une image, donnant un qcow2 valide mais VIDE — mais il
jetait les octets reçus et renvoyait l'utilisateur à un « curl -C - » tapé à
la main. Le transfert se reprend désormais sur le même miroir, trois essais,
par un « Range » qui demande la suite ; on ne change de miroir qu'ensuite. Un
serveur qui ignore le Range rend le fichier entier, et l'on repart alors de
zéro plutôt que de doubler les octets déjà là.
Vérifié : 5 tests contre un serveur qui coupe au tiers, image reconstituée à
l'octet près, et le .part tronqué part quand les reprises s'épuisent.
--- EN ---
A VM image weighs half a gigabyte: an interruption is far likelier there than
on a page. The completeness check existed — without it a truncated .part
passed for an image, giving a valid but EMPTY qcow2 — but it threw away the
bytes received and sent the user back to a hand-typed "curl -C -". The
transfer now resumes on the same mirror, three attempts, through a "Range"
asking for the rest; only then does it change mirror. A server ignoring the
Range returns the whole file, and we restart from zero rather than doubling
the bytes already there.
Checked: 5 tests against a server cutting at one third, image reassembled byte
for byte, and the truncated .part goes when the retries run out.
Assisted-by: Claude Opus 5
Les six cibles d'addons visaient « ./addons/<dépôt>/ », une disposition que
seul un manifeste produit : la production les range sous
« odoo<version>/addons/ ». isort s'arrêtait donc sur une trace pour un chemin
inexistant, et « make format_all » échouait sans avoir formaté un module. Les
dépôts sont maintenant NOMMÉS, cherchés sous les deux dispositions, et celui
qu'un manifeste ne rapatrie pas s'annonce puis est ignoré. Le formateur est
celui de la communauté, qui a quitté black : ruff en 88 colonnes, avec les
sections d'imports « odoo » et « odoo.addons » qu'isort ne sait pas produire.
Vérifié : trois des six dépôts sont présents ici, les autres s'annoncent
absents sans faire échouer la cible.
--- EN ---
The six addons targets aimed at "./addons/<repo>/", a layout only one manifest
produces: production files them under "odoo<version>/addons/". isort therefore
stopped on a traceback for a non-existent path, and "make format_all" failed
without formatting a module. Repositories are now NAMED, looked up under both
layouts, and one a manifest does not check out announces itself then is
skipped. The formatter is the community's, which left black: ruff at 88
columns, with the "odoo" and "odoo.addons" import sections isort cannot
produce.
Checked: three of the six repositories are present here, the others announce
themselves absent without failing the target.
Assisted-by: Claude Opus 5
Un échec de « repo forall » arrêtait tout : la liste des fichiers locaux, déjà
obtenue, était jetée, et « make format » rendait 0 sans avoir formaté une
ligne. Sa sortie d'erreur, capturée puis jetée, emportait la seule explication,
et seule l'exception Python restait à l'écran. Google Repo n'ajoute pourtant
que les dépôts rapatriés : il est joué sans check, ce qu'il a écrit est relayé,
et les fichiers locaux sont formatés quand même. « Rien à formater » se dit au
lieu d'une sortie muette, et un échec du dépôt lui-même rend non nul.
Vérifié : avec un repo bouchonné qui échoue, son message s'affiche et le
fichier local est formaté.
--- EN ---
A failing "repo forall" stopped everything: the local file list, already
gathered, was dropped, and "make format" returned 0 without formatting a line.
Its error output, captured then thrown away, carried the only explanation, and
only the Python exception stayed on screen. Google Repo only adds the checked
out repositories: it runs without check, whatever it wrote is relayed, and
local files are formatted anyway. "Nothing to format" is said instead of a
silent exit, and a failure of the repository itself returns non-zero.
Checked: with a stub repo that fails, its message shows and the local file is
formatted.
Assisted-by: Claude Opus 5
« -L » relaie UN service ; « -D » ouvre un relais SOCKS, par lequel le
navigateur atteint n'importe quelle destination depuis la machine distante —
une interface qui n'écoute que sur sa boucle locale, un hôte de son réseau sans
route depuis ici. Le port par défaut est 1080, modifiable, et contrôlé libre
avant d'ouvrir. La saisie de l'adresse est celle de sshfs, désormais partagée :
l'alias de ~/.ssh/config part tel quel à ssh, faute de quoi son ProxyJump se
perdrait et une VM imbriquée deviendrait injoignable. Le réglage de Firefox
s'affiche AVANT le lancement, la commande ne rendant la main qu'au Ctrl+C.
Vérifié : 9 tests neufs, et la numérotation du menu que deux autres gardent.
--- EN ---
"-L" relays ONE service; "-D" opens a SOCKS relay, through which the browser
reaches any destination from the remote machine — an interface listening only
on its loopback, a host of its network with no route from here. The default
port is 1080, changeable, and checked free before opening. The address prompt
is sshfs's, now shared: the ~/.ssh/config alias goes to ssh as is, failing
which its ProxyJump would be lost and a nested VM become unreachable. The
Firefox settings print BEFORE the launch, the command only returning on
Ctrl+C.
Checked: 9 new tests, and the menu numbering two others guard.
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
Cinq fichiers employaient des f-strings PEP 701 — guillemets imbriqués du même
type, backslash dans l'expression, expression sur plusieurs lignes — que
Python refuse avant 3.12. Or les hooks de script/git/hooks portent
« #!/usr/bin/env python3 » et tournent donc sur l'interpréteur du système,
qu'une distribution livre encore en 3.10 : la SyntaxError tombe au chargement,
sans qu'aucun garde puisse nommer la commande à taper. Les chaînes traduites
gardent leur texte à l'octet près, sans quoi leur clé se perdrait. Les
commentaires de ces fichiers passent du récit au présent, comme la règle le
demande de ce qu'on touche.
Vérifié : tout l'arbre Python parse sous 3.10, 3.11, 3.12 et 3.14.
--- EN ---
Five files used PEP 701 f-strings — quotes of the same kind nested, a backslash
in the expression, an expression spanning lines — which Python refuses before
3.12. The hooks in script/git/hooks carry "#!/usr/bin/env python3" and so run
on the system interpreter, which a distribution still ships as 3.10: the
SyntaxError lands at load, before any guard can name the command to type.
Translated strings keep their text byte for byte, else their key would be lost.
The comments of those files move from tale to present tense, as the rule asks
of what one touches.
Checked: the whole Python tree parses under 3.10, 3.11, 3.12 and 3.14.
Assisted-by: Claude Opus 5
Aucune cible ne formatait les tests : « make format_all » couvre script/ et les
six dépôts d'addons, et rien d'autre. Seul « make format » les atteignait, et
seulement ceux qu'un diff signalait, si bien que 75 fichiers sur 210 ne
suivaient aucune norme — de la dérive silencieuse dans un arbre qui sert de
référence au reste. Les tests tournent dans le venv d'outillage : ils suivent
donc ruff, comme script/, et la cible entre dans format_all.
Vérifié : « make -n format_test » nomme bien ruff, et format_all l'inclut.
--- EN ---
No target formatted the tests: "make format_all" covers script/ and the six
addons repositories, nothing else. Only "make format" reached them, and only
those a diff reported, so that 75 files out of 210 followed no standard —
silent drift in a tree the rest takes as reference. The tests run in the
tooling venv: they therefore follow ruff, like script/, and the target joins
format_all.
Checked: "make -n format_test" names ruff, and format_all includes it.
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
[FIX] qemu : clé portable du cache, re-clé du magasin, image reprise
10 commits. Le magasin rangeait un objet sous le chemin ENTIER de son URL : un
miroir qui préfixe ce chemin donnait deux clés pour les mêmes octets, et le
cache retéléchargeait ce qu'il détenait — sur un journal de 7099 noms livrés,
1124 vivaient sous plusieurs chemins, 3,18 Gio repris à l'amont pour rien.
Seuls les six derniers segments comptent désormais, quatre pour la famille
pacman dont les chemins sont plus courts. « --recle » rattrape un magasin
déjà rempli sans rien retélécharger, et une image gardée devenue périmée est
reprise une fois au lieu de perdre la campagne entière.
Vérifié : suites Go et Python vertes, et une campagne hors ligne où la seconde
VM n'a repris aucun octet de paquet à l'amont.
--- EN ---
10 commits. The store filed an object under the WHOLE path of its URL: a mirror
prefixing that path gave two keys for the same bytes, and the cache
re-downloaded what it held — over a log of 7099 delivered names, 1124 lived
under several paths, 3.18 GiB taken upstream for nothing. Only the last six
segments count now, four for the pacman family whose paths are shorter.
« --recle » brings over a store already filled, downloading nothing, and a
kept image gone stale is fetched once more instead of losing a whole campaign.
Checked: Go and Python suites green, and an offline campaign where the second
VM took no package byte from upstream.
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
Un miroir d'Arch sert « archlinux/core/os/x86_64/<paquet> » là où un autre
sert « core/os/x86_64/<paquet> » : quatre et cinq segments, plus courts que la
borne commune de six, qui les garde entiers et en fait deux clés pour un même
octet. La famille pacman passe donc à quatre, ce qui retire le segment du
miroir et garde le nom du dépôt. La borne haute reste partout ailleurs : deux
distributions peuvent publier un « .deb » de même nom pour d'autres octets, et
les confondre servirait le paquet de l'une à l'autre. Vérifié : quatre
mutations attrapées, aucune collision sur les chemins relevés.
--- EN ---
An Arch mirror serves « archlinux/core/os/x86_64/<package> » where another
serves « core/os/x86_64/<package> »: four and five segments, shorter than the
common bound of six, which keeps them whole and makes two keys for one byte.
The pacman family therefore moves to four, which drops the mirror's segment
and keeps the repository name. The high bound stays everywhere else: two
distributions may publish a « .deb » of the same name for other bytes, and
merging them would serve one's package as the other's. Checked: four mutations
caught, no collision over the paths surveyed.
Assisted-by: Claude Opus 5
Additionner déplacés, fondus et inchangés dépasse le nombre d'objets lus, et
la passe paraît alors se contredire. Elle ne se trompe pas : une copie déjà
rangée sous la clé courante est comptée inchangée quand le parcours la visite,
puis fondue si une copie plus récente vient prendre sa place. Le commentaire
le dit désormais, pour que personne ne prenne cette somme pour un inventaire.
--- EN ---
Adding moved, merged and unchanged exceeds the number of objects read, and the
pass then seems to contradict itself. It does not: a copy already stored under
the current key is counted unchanged when the walk visits it, then merged if a
more recent copy takes its place. The comment now says so, lest anyone take
that sum for an inventory.
Assisted-by: Claude Opus 5
La règle de clé d'un fichier portable a changé : seule la fin du chemin compte
désormais. Les objets écrits sous l'ancienne règle restent sur le disque mais
deviennent introuvables — le service les redemande à l'amont, et la place
qu'ils tiennent ne sert plus personne. Sur un magasin de 12 764 objets, 5 419
étaient dans ce cas, soit 9,11 Gio. La passe les range sous la clé courante
sans rien retélécharger, et fond au passage les copies qu'un miroir portait
sous plusieurs chemins — 1 422 groupes, environ 3,37 Gio rendus. Un statut
seul n'est pas touché : sa clé porte l'hôte. Vérifié : cinq tests, trois
mutations attrapées.
--- EN ---
The key rule for a portable file changed: only the end of the path now counts.
Objects written under the old rule stay on disk but become unreachable — the
service asks upstream again, and the space they hold serves no one. On a store
of 12 764 objects, 5 419 were in that case, that is 9.11 GiB. The pass stores
them again under the current key without downloading anything, and merges on
the way the copies a mirror carried under several paths — 1 422 groups, about
3.37 GiB returned. A status-only entry is left alone: its key carries the
host. Checked: five tests, three mutations caught.
Assisted-by: Claude Opus 5
Un miroir préfixe le chemin à sa guise — « /rocky/10.2/… »,
« /mirror/rocky-linux/10.2/… », « /pub/archive/fedora/… » — et le chemin
entier donnait deux clés pour un même octet : le cache retéléchargeait ce
qu'il détenait. Relevé sur un journal de 7099 noms livrés : 1124 vivaient sous
plusieurs chemins, et 3,18 Gio repartaient à l'amont pour rien. Seuls les six
derniers segments comptent désormais, les segments vides tombant avec eux. Six
est le plus petit nombre sans collision : un chemin Debian en porte six, si
bien que cinq confondraient son paquet avec celui d'Ubuntu, qui porte le même
nom pour d'autres octets — 38 cas mesurés. Vérifié : deux mutations attrapées.
--- EN ---
A mirror prefixes the path as it pleases, and the whole path gave two keys for
one byte: the cache re-downloaded what it held. Measured over a log of 7099
delivered names: 1124 lived under several paths, and 3.18 GiB went back
upstream for nothing. Only the last six segments now count, empty ones falling
with them. Six is the smallest number without collision: a Debian path carries
six, so five would confuse its package with Ubuntu's, which bears the same
name for other bytes — 38 measured cases. Checked: two mutations caught.
Assisted-by: Claude Opus 5
Le relevé des fichiers que la seconde VM découvre seule attribuait leur
existence à la publication continue d'Arch, quelle que soit la distribution
mesurée. Sur une famille RHEL, ces fichiers viennent surtout d'un miroir qui
range les mêmes paquets sous un autre chemin : la clé du magasin portant le
chemin, le cache les retélécharge alors qu'il les détient. Le message nomme
désormais les deux causes sans en imputer une à un système qui n'est pas
celui de la campagne.
--- EN ---
The report of files the second VM discovers alone blamed their existence on
Arch's rolling release, whatever the distribution measured. On a RHEL family
system they mostly come from a mirror storing the same packages under another
path: the store key carrying the path, the cache re-downloads what it already
holds. The message now names both causes without pinning one on a system that
is not the campaign's.
Assisted-by: Claude Opus 5
Un même paquet vit sous deux chemins selon le miroir, et la clé du magasin
porte le chemin : la première VM peut recevoir « 504 » sur l'un — amont jugé
muet — puis être servie du disque par l'autre. Rien n'entre alors au magasin
sous le premier chemin, et le téléchargement honnête de la seconde y était
compté en faute, faisant échouer une mesure où le cache avait tout servi. Une
URL n'est « déjà vue » que si la première VM en a obtenu les octets ; un
statut absent vaut livré, les journaux d'avant ne l'écrivant pas toujours.
Vérifié : trois tests, deux mutations attrapées.
--- EN ---
One package lives under two paths depending on the mirror, and the store key
carries the path: the first VM can get « 504 » on one — upstream judged mute —
then be served from disk by the other. Nothing enters the store under the
first path, and the second VM's honest download was counted a fault there,
failing a measurement where the cache had served everything. A URL is « already
seen » only if the first VM obtained its bytes; a missing status counts as
delivered, older logs not always writing it. Checked: three tests, two
mutations caught.
Assisted-by: Claude Opus 5
Une image gardée vieillit : le répertoire « latest » d'une distribution avance
à chaque version mineure, et la somme publiée cesse de décrire celle du
disque. La vérification la supprimait puis sortait en erreur — une campagne
entière, trois VM, perdue pour une péremption qu'un seul téléchargement
répare. Un écart sur une image DÉJÀ présente la fait désormais reprendre une
fois ; un second écart porte sur des octets fraîchement téléchargés, et arrête
tout. Sans liste de miroirs, et pour des sommes injoignables, rien ne change.
Vérifié : quatre tests de comportement, deux mutations attrapées.
--- EN ---
A kept image ages: a distribution's « latest » directory moves with each point
release, and the published sum stops describing the one on disk. The check
deleted it and exited — a whole campaign, three VMs, lost to a staleness one
download repairs. A mismatch on an image ALREADY present now makes it fetched
once more; a second mismatch is on freshly downloaded bytes, and stops
everything. With no mirror list, and for unreachable sums, nothing changes.
Checked: four behaviour tests, two mutations caught.
Assisted-by: Claude Opus 5
Le binaire a gagné le retrait d'une entrée du magasin par URL et le classement
des objets nix comme immuables sans que la version bouge : « --version » ne
distinguait plus un cache qui porte ces règles d'un cache qui ne les porte
pas, et une réinstallation ne se constatait donc pas. Un hôte pouvait servir
un binaire ignorant l'option « --oublie » tout en annonçant le même numéro.
--- EN ---
The binary gained the removal of a single store entry by URL and the
classification of nix objects as immutable without the version moving:
« --version » could no longer tell a cache holding those rules from one that
does not, so a reinstall could not be observed. A host could serve a binary
ignoring the « --oublie » option while announcing the same number.
Assisted-by: Claude Opus 5
[ADD] garde-fous : refuser une clé i18n double, borner le guide à 80
3 commits. Deux défauts qui ne se signalent pas d'eux-mêmes, et que rien
n'empêchait de revenir.
Une clé de traduction écrite deux fois fait afficher à un menu la traduction
d'un autre : Python bâtit un dictionnaire littéral de haut en bas et garde la
dernière, sans un mot. Le contrôle lit le fichier par son ARBRE, la collision
pouvant s'écrire sur une seule ligne où une expression régulière ne la voit
pas. Vert sur l'état actuel : aucune clé n'est en double aujourd'hui.
Le guide de connexion tenait dans 80 colonnes nu et en rendait 103 une fois
la VM équipée, là où l'épreuve de largeur ne regardait que le guide nu. C'est
la mise en page qui porte la règle désormais. 6706 tests.
--- EN ---
3 commits. Two defects that do not report themselves, and that nothing
prevented from coming back.
A translation key written twice makes one menu show another's translation:
Python builds a literal dictionary top to bottom and keeps the last one,
without a word. The check reads the file by its TREE, the collision being
writable on a single line where a regular expression does not see it. Green
on the current state: no key is duplicated today.
The connection guide fitted in 80 columns bare and rendered 103 once the VM
was equipped, where the width check looked only at the bare guide. The layout
now carries the rule. 6706 tests.
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 guide tenait dans 80 colonnes nu, et rendait 103 dès qu'une VM portait
ses outils et un bureau. Le cadre débordait alors, le terminal repliait où
il voulait, et l'alignement en deux colonnes — seule chose qui rend un
guide lisible d'un coup d'œil — disparaissait.
La mise en page porte désormais la règle, plutôt que la longueur des textes
qui n'aurait tenu que jusqu'au prochain outil : la glose se replie sous sa
colonne, et passe sous sa commande quand celle-ci ne laisse plus de quoi
écrire. L'épreuve de largeur ne couvrait que le guide nu ; elle couvre le
guide équipé, qui est celui où le débordement vivait.
--- EN ---
The guide fitted in 80 columns bare, and rendered 103 as soon as a VM
carried its tools and a desktop. The frame then overflowed, the terminal
wrapped wherever it liked, and the two-column alignment — the only thing
making a guide readable at a glance — was gone.
The layout now carries the rule, rather than the length of texts which would
have held only until the next tool: a gloss wraps under its column, and
moves below its command when that command leaves no room. The width check
covered only the bare guide; it now covers the equipped one, which is where
the overflow lived.
Assisted-by: Claude Opus 5
Python bâtit un dictionnaire littéral de haut en bas : la dernière
occurrence gagne. Une clé posée deux fois fait donc qu'un menu affiche la
traduction d'un autre, et rien ne le signale — ni au chargement, ni à
l'exécution, ni au test qui exerce le premier menu.
Le contrôle lit le fichier par son ARBRE et non par une expression
régulière, laquelle n'attrapait que la forme multiligne quand la collision
peut s'écrire sur une seule. Vert sur l'état actuel, donc aucune clé en
double aujourd'hui ; éprouvé sur les deux formes, qu'il refuse.
--- EN ---
Python builds a literal dictionary top to bottom: the last occurrence wins.
A key written twice therefore makes one menu show another's translation, and
nothing reports it — not at load, not at run, not in the test exercising the
first menu.
The check reads the file by its TREE rather than by a regular expression,
which only caught the multi-line form when the collision can be written on
one. Green on the current state, so no duplicate key today; exercised on
both forms, which it refuses.
Assisted-by: Claude Opus 5
[ADD] qemu, proxmox et cache : NixOS devient déployable
23 commits. NixOS est le neuvième système déployable, et le seul dont aucune
distribution ne publie d'image cloud : celle d'un tiers est épinglée, sa somme
vérifiée, l'UEFI imposé là où elle n'a pas de secteur BIOS. Les dépendances
d'ERPLibre y sont DÉCLARÉES au lieu d'être posées commande par commande.
Presque rien ne s'y devine — /etc est en lecture seule, /bin un montage FUSE
que systemd ne voit pas, le pare-feu est actif et sshd ne montre aucun motd.
Le cache de téléchargement a dû apprendre à lui servir l'autorité, perdue à
trois frontières, sans quoi NixOS en restait soustrait et le hors ligne lui
était fermé. Vérifié sur machines réelles : installation complète, 0 refus de
certificat, Odoo en 303. 6697 tests.
--- EN ---
23 commits. NixOS is the ninth deployable system, and the only one no
distribution publishes a cloud image for: a third party's is pinned, its sum
verified, UEFI forced where it has no BIOS sector. ERPLibre's dependencies are
DECLARED there instead of installed one command at a time.
Almost nothing there is guessable — /etc is read-only, /bin a FUSE mount
systemd does not see, the firewall is on and sshd shows no motd. The download
cache had to learn to serve it the authority, lost at three boundaries,
without which NixOS stayed exempt from it and offline deployment was closed
to it. Checked on real machines: a complete install, 0 certificate refusals,
Odoo in 303. 6697 tests.
Assisted-by: Claude Opus 5