Commit graph

27 commits

Author SHA1 Message Date
76c548a781 [UPD] commit rule: English subject first, French title under --- FR ---
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
2026-09-25 01:31:27 -04:00
7a10f268df [FIX] démarrage : choisir un interpréteur capable de lire TODO
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
2026-09-24 13:56:57 -04:00
42e10bcced [UPD] install : le venv d'outillage passe en Python 3.14.7
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
2026-09-24 13:56:57 -04:00
7cdcd8a07a [ADD] garde-fou : signaler au commit un source trop récent pour le dépôt
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
2026-09-24 13:56:57 -04:00
600dd8639f [ADD] claude : activer le plugin superpowers pour le dépôt
.claude/settings.json est la configuration partagée du dépôt : la clé
enabledPlugins active superpowers pour tout contributeur qui ouvre Claude Code
ici, sans manipulation de sa part. Le plugin apporte des skills de méthode —
idéation, débogage systématique, TDD, revue de code — et un hook SessionStart
qui s'exécute au démarrage de chaque session.

Aucune version n'est épinglée : chaque poste prend celle que son marketplace a
installée. Vérifié sur la 6.3.0, qui porte quatorze skills et ce seul hook.

--- EN ---

.claude/settings.json is the repository's shared configuration: the
enabledPlugins key turns superpowers on for every contributor who opens Claude
Code here, with nothing to do on their side. The plugin carries method skills
— brainstorming, systematic debugging, TDD, code review — and a SessionStart
hook that runs at the start of every session.

No version is pinned: each workstation gets whatever its marketplace
installed. Checked on 6.3.0, which carries fourteen skills and that one hook.

Assisted-by: Claude Opus 5
2026-09-14 05:13:03 -04:00
c0b24925bf [ADD] hygiène : signaler un nom de machine pleinement qualifié
L'outil voyait les adresses, les courriels et les chemins de compte, mais pas
les NOMS — la classe que la règle interdit au même titre, et celle qu'un
assistant qui parcourt le réseau multiplie. Le rapport annonçait « 0
identifiant » sur un fichier qui en portait un.

Un signal à relire, jamais une trouvaille : un nom d'hôte NU ne se distingue
mécaniquement ni d'un mot ordinaire ni du nom d'un logiciel, donc seule la
forme qualifiée se reconnaît, contre une liste FERMÉE de suffixes. En sortent
l'en-tête de copyright, les domaines de la RFC 2606, et toute adresse portée
par une URL. Vérifié : 54 tests, et 21 signaux sur le dépôt, tous des miroirs.

--- EN ---

The tool saw addresses, e-mails and account paths, but not NAMES — the class
the rule forbids just as much, and the one an assistant sweeping the network
multiplies. The report announced "0 identifying" on a file that carried one.

A signal to re-read, never a finding: a BARE host name is mechanically
indistinguishable from an ordinary word or a piece of software, so only the
qualified form is recognised, against a CLOSED list of suffixes. Out of it go
the copyright header, the RFC 2606 domains, and any address carried by a URL.
Checked: 54 tests, and 21 signals across the repository, all mirrors.

Assisted-by: Claude Opus 5
2026-09-09 07:35:15 -04:00
197d19d61e [ADD] vpn : cinq pilotes, secrets en coffre, diagnostic étagé
Le dépôt n'avait aucun moyen de monter un tunnel VPN ni de dire pourquoi il
refuse de monter. Cinq technologies libres, un pilote chacune, derrière un
`vpn.py` qui monte, démonte et diagnostique.

Ce qui n'est pas secret — hôte, utilisateur, routes, MTU — vit dans une
configuration JSON lisible ; clés pré-partagées et mots de passe vivent dans
un coffre KeePassXC. Un profil se montre et se partage sans donner de quoi
monter le tunnel. Les secrets s'écrivent en tmpfs sous 0700, jamais sur un
disque persistant. Le diagnostic part du noyau et remonte, pour que la
première ligne fausse soit la cause et non une conséquence.
Vérifié : 138 tests, dont le rendu de chaque fichier généré.

--- EN ---

The repository had no way to raise a VPN tunnel, nor to say why one refuses
to come up. Five free technologies, one driver each, behind a `vpn.py` that
raises, tears down and diagnoses.

What is not secret — host, user, routes, MTU — lives in readable JSON
configuration; pre-shared keys and passwords live in a KeePassXC vault. A
profile can be shown and shared without handing over the means to raise the
tunnel. Secrets are written to tmpfs at 0700, never to a persistent disk.
Diagnosis starts at the kernel and climbs, so the first false line is the
cause and not a consequence.
Checked: 138 tests, including the rendering of every generated file.

Assisted-by: Claude Opus 5
2026-09-04 03:42:49 +00:00
d92797d38a [REF] claude : alléger le contexte, deux règles passent en skills
Environ 1 130 tokens étaient chargés à chaque session pour du contenu
dérivable ou écrit deux fois : les deux tableaux d'index décrivaient des
fichiers déjà chargés en entier, et la ligne de format de commit
contredisait 04-code-conventions.md et le hook qui l'applique. Les règles
du générateur et du déploiement ne servent qu'à une tâche : elles se
chargent désormais à la demande, comme les deux skills déjà en place.
L'interdit du générateur, lui, reste dans CLAUDE.md — une interdiction ne
doit pas dépendre de l'ouverture d'une skill.

Vérifié : aucun renvoi vers les fichiers déplacés, et les quatre skills
déclarent un nom qui correspond à leur répertoire.

--- EN ---

About 1,130 tokens loaded every session for content that is derivable or
written twice: the two index tables described files already loaded in
full, and the commit-format line contradicted 04-code-conventions.md and
the hook enforcing it. The code-generator and deployment rules serve one
task each: they now load on demand, like the two skills already in place.
The generator's prohibition stays in CLAUDE.md — a ban must not depend on
a skill being opened.

Checked: no reference points at the moved files, and all four skills
declare a name matching their directory.

Assisted-by: Claude Opus 5
2026-09-02 08:04:15 -04:00
4701660203 [UPD] convention : nommer les fichiers à l'indexation, pas git add -A
`git add -A` indexe tout ce qui n'est pas suivi. Or `private/` et `tasks/` ne
le sont pas EXPRÈS : le premier est le seul endroit autorisé à porter une
donnée de client, le second reçoit l'enquête précisément parce qu'il ne part
pas dans git. Un ratissage les commit tous les deux.

Il emporte aussi ce qui est en cours ailleurs dans le checkout, sous un sujet
qui ne le couvre pas. Le gabarit nomme désormais les fichiers et renvoie à
`git add -p` quand un fichier porte deux sujets.

La règle porte la même consigne : le gabarit ne se lit qu'à l'appel de la
commande, la règle est chargée à chaque session.

--- EN ---

`git add -A` stages everything untracked. Yet `private/` and `tasks/` are
untracked ON PURPOSE: the first is the only place allowed to carry customer
data, the second receives the investigation precisely because it does not go
into git. A sweep commits both.

It also swallows whatever else is in flight in the checkout, under a subject
that does not cover it. The template now names the files and points at
`git add -p` when one file carries two subjects.

The rule carries the same instruction: the template is read only when the
command is invoked, the rule is loaded every session.

Assisted-by: Claude Opus 5
2026-08-30 06:14:05 -04:00
0e5441ac39 [ADD] commentaires : un relevé non bloquant, sa règle, le code nettoyé
Rien ne relevait les commentaires hors convention. L'outil lit commentaires et
docstrings, jamais le code autour, et rend deux familles inégales :
l'identifiant — adresse, courriel, chemin de compte, nom de la liste privée —
est une trouvaille ; le récit — témoignage, date, personne — un signal à relire.

Le hook pre-commit le lance sur l'index, sort toujours en 0 — un contrôle
bloquant à cette échelle se fait désinstaller — et parle quand l'outil échoue.
La règle du générateur et sa doc portent le nettoyage au fur et à mesure, et
l'exemple d'un interdit s'invente : base, adresse, compte et hôte en prennent un.

L'écran du contexte est posé, sans entrée de menu. Vérifié : 252 tests des six
fichiers d'essai touchés passent.

--- EN ---

Nothing reported the comments that break the convention. The tool reads
comments and docstrings, never the code around them, and returns two unequal
families: identifying data — address, e-mail, account path, private-list name
— is a finding; narrative — witness marker, date, person — a signal to re-read.

The pre-commit hook runs it on the index, always exits 0 — a blocking check at
that scale gets uninstalled — and speaks when the tool fails. The generator
rule and its doc carry the clean-up as you go, and a forbidden thing's example
is invented: a real database, address, account and host each take one.

The context screen is in place, with no menu entry. Checked: 252 tests of the
six touched fixture files pass.

Assisted-by: Claude Opus 5
2026-08-30 06:08:30 -04:00
5fb49da0f2 [ADD] convention : dire le fonctionnement, pas le contexte ni les noms
Le dépôt n'avait aucune règle sur le commentaire de code : le seul modèle
d'écriture était le corps de commit, et le gabarit y renvoyait le
raisonnement qui n'y tenait pas. Le récit s'écoulait dans les sources,
avec les noms qu'il portait.

L'épreuve tient en une phrase : le code est le sujet, au présent de ce
qu'il fait. Une phrase dont le sujet est un incident, une machine, une date
ou une personne part vers tasks/, non versionné ; le mode de défaillance
que le code empêche reste. Rien d'identifiant hors de private/, et
seulement sur un dépôt privé.

--- EN ---

The repository had no rule at all about code comments: the only writing
model available was the commit body, and the template sent the reasoning
that did not fit there into a comment. The story flowed into the sources,
carrying the names it named.

The test fits in one sentence: the code is the subject, in the present of
what it does. A sentence whose subject is an incident, a machine, a date or
a person goes to tasks/, unversioned; the failure mode the code prevents
stays. Nothing identifying outside private/, and only on a private
repository.

Assisted-by: Claude Opus 5
2026-08-30 05:11:36 -04:00
f9edaa4e59 [ADD] git : un garde-fou commit-msg pour le sujet
Rien ne tenait la convention sur le sujet : le tag est respecté partout,
c'est la longueur qui glisse. Le hook refuse le mécanique et rien de plus
— tag absent, plus de 72 caractères, sujet ouvrant sur une citation ; dire
sur quoi porte le code reste un jugement qu'aucun hook ne rendra. Il compte
des caractères et non des octets, sans quoi un sujet français de 72
caractères tomberait sur ses accents. Le refus enseigne le repli vers des
mots-clés plutôt que la troncature, et nomme `--no-verify` : un garde-fou
qui refuse trop est désinstallé. Les tests pèsent donc autant les
acceptations, « Merge branch » ou fixup de rebase. Le lanceur balaie le
préfixe test_git_ : 32 tests jamais exécutés, le total va de 1021 à 1071.

--- EN ---

Nothing held the subject convention: the tag is respected everywhere, it
is the length that slips. The hook refuses the mechanical and nothing more
— no tag, over 72 characters, a subject opening on a quotation; whether it
says what the code is about stays a judgement no hook will make. It counts
characters, not bytes, or a 72-character French subject would fall on its
accents. The refusal teaches the fallback to keywords rather than
truncation, and names `--no-verify`: a guard rail that refuses too much
gets uninstalled. So the tests weigh the acceptances as much, a "Merge
branch" or a rebase fixup. The runner sweeps the test_git_ prefix: 32
tests never ran, and the total goes from 1021 to 1071.

Assisted-by: Claude Opus 5
(cherry picked from commit c9abf4d1b723ae8ff3762d39bfe1d6982400d12d)
2026-08-29 02:11:04 -04:00
55a093a86d [ADD] convention : ce qu'un sujet de commit doit dire
Le manuel encadrait le corps en détail — pourquoi, dix lignes par langue, ce
qu'on ne répète pas du diff — et ne disait du sujet que « courte, à
l'impératif ». Le sujet est pourtant lu cent fois pour une fois que le corps
l'est : git log --oneline, un blame, un bisect, une note de version.

Faute de règle, les sujets dérivent vers le symptôme et la métaphore, qui se
lisent bien sans nommer la partie du système en jeu. La règle ajoute une
épreuve, pas un gabarit : lire le sujet seul, sans diff ni corps, et savoir
ce qui change et où. Les trois exemples avant/après viennent de l'historique
du dépôt, un exemple inventé ne convainquant personne.

--- EN ---

The manual framed the body in detail — why, ten lines per language, what not
to repeat from the diff — and said of the subject only that it be short and
imperative. Yet the subject is read a hundred times for every reading of the
body: git log --oneline, a blame, a bisect, a release note.

With no rule, subjects drift towards the symptom and the metaphor, which read
well without naming the part of the system at stake. The rule adds a test,
not a template: read the subject alone, with no diff and no body, and be able
to say what changes and where. The three before/after pairs come from the
repository's own history, an invented example convincing nobody.

Assisted-by: Claude Opus 5
(cherry picked from commit c86357eab899c65f41287d4f19e88d0da98285c4)
2026-08-29 02:11:04 -04:00
5b748e347e [ADD] make: une cible pour les tests unitaires, dépendance mobile déclarée
Ces 382 tests ne tournaient que lancés à la main, donc jamais. « make test »
demande une base de données et plusieurs minutes ; ceux-ci lisent le code et
exécutent les fragments de shell générés, sudo, pgrep et pkill bouchonnés, en
une dizaine de secondes. Deux cibles : test_unit, et test_unit_file pour la
boucle d'écriture.

La dépendance à mobile/erplibre_home_mobile est DITE plutôt que supposée : le
lanceur l'annonce présente ou absente, et les tests du vrai transfert se
déclarent ignorés — avec la commande qui manque — au lieu de passer en silence.
Vérifié dans les trois états : dépôt absent, présent non compilé, compilé.

Au passage, compile_and_run.sh vérifie le transfert des dépôts, comme
l'installation d'une VM et par le même script.

--- EN ---

These 382 tests only ran when invoked by hand, so never. "make test" wants a
database and several minutes; these read the code and run the generated shell
fragments with sudo, pgrep and pkill stubbed, in about ten seconds. Two targets:
test_unit, and test_unit_file for the writing loop.

The dependency on mobile/erplibre_home_mobile is STATED rather than assumed: the
runner announces it present or absent, and the real-transfer tests declare
themselves skipped — naming the missing command — instead of passing quietly.
Checked in all three states: repo absent, present but unbuilt, built.

Along the way, compile_and_run.sh verifies the repo transfer, like a VM install
and through the same script.

Assisted-by: Claude Opus 5
2026-08-23 02:11:50 -04:00
9c470f065e [ADD] qemu: openSUSE Leap 16.0, numbered, as the default
The catalogue only offered openSUSE Tumbleweed, a rolling release with
no version number. Nearly every openSUSE incident in this series came
from that: the cloud image is a snapshot lagging behind its own repos,
hence the mandatory "zypper dup", and two VMs deployed the same day saw
git-daemon 2.54 on s390x against 2.55 on amd64. For an ERP platform,
that is not what should be offered by default.

Leap 16.0 is numbered, stable, and publishes the three architectures
that matter -- verified, x86_64, aarch64 and s390x all 200. It also
unifies its tree: no separate /ports/, unlike Tumbleweed, whose
equivalent paths 404 for Leap.

Tumbleweed stays on offer, as a bellwether for breakage to come. Two
things separate them in the scripts: the repository path, and "dup" --
which on Leap means CHANGING version, not updating.

--- FR ---

Le catalogue n'offrait qu'openSUSE Tumbleweed, une rolling sans numéro
de version. Presque tous les incidents openSUSE de la série venaient de
là : l'image cloud est un instantané en retard sur ses dépôts, d'où le
« zypper dup » obligatoire, et deux VM déployées le même jour ont vu
git-daemon 2.54 sur s390x contre 2.55 sur amd64. Pour une plateforme
ERP, ce n'est pas ce qu'on veut proposer par défaut.

Leap 16.0 est numérotée, stable, et publie les trois architectures qui
comptent — vérifié, x86_64, aarch64 et s390x en 200. Elle unifie de plus
son arbre : pas de /ports/ séparé, contrairement à Tumbleweed, dont les
chemins équivalents rendent 404 pour Leap.

Tumbleweed reste offerte, comme banc d'essai des ruptures à venir.
Deux points les séparent dans les scripts : le chemin des dépôts, et
« dup » — qui sur Leap sert à CHANGER de version, pas à mettre à jour.

Assisted-by: Claude Opus 5
2026-08-17 00:40:01 -04:00
e20d8d9baa [ADD] install: uv to place Python packages, pip as fallback
uv replaces pip where it can: the tools venv and the Poetry bootstrap. The
choice lives in EL_PIP_PROVIDER -- auto, uv or pip -- and in a single
file, lib_pip_provider.sh, on the exact model of the mise/pyenv switch. A
uv failure falls back to pip: it is stricter on metadata and rejects
packages pip accepts.

Three guards. The target always goes through "--python" rather than being
inferred from the active venv: poetry.toml declares a "./.venv" uv would
also look for. Python 3.7, still used by Odoo 12 and 13, stays on pip. And
"uv pip sync" is never used: it would delete pip itself and everything
Poetry laid down.

One bug falls along the way: the idempotence guard aimed at
.venv.erplibre/bin/poetry while Poetry installs into the Odoo venv, so a
successful replay reported failure all the same.

--- FR ---

uv remplace pip là où il le peut : le venv d'outils et l'amorçage de
Poetry. Le choix vit dans EL_PIP_PROVIDER — auto, uv ou pip — et dans un
seul fichier, lib_pip_provider.sh, sur le modèle exact de l'aiguillage
mise/pyenv. Un échec d'uv retombe sur pip : il est plus strict sur les
métadonnées et refuse des paquets que pip accepte.

Trois gardes. La cible passe toujours par « --python » plutôt que d'être
déduite du venv actif : poetry.toml déclare un « ./.venv » qu'uv
chercherait aussi. Python 3.7, encore utilisé par Odoo 12 et 13, reste sur
pip. Et « uv pip sync » n'est jamais employé : il supprimerait pip
lui-même et tout ce que Poetry a posé.

Un défaut tombe au passage : le garde d'idempotence visait
.venv.erplibre/bin/poetry alors que Poetry s'installe dans le venv Odoo,
si bien qu'un rejeu réussi rapportait quand même un échec.

Assisted-by: Claude Opus 5
2026-08-16 23:33:49 -04:00
70d9ad456c [ADD] install: mise as Python provider, pyenv as fallback
mise lays down a precompiled CPython where pyenv builds one: seconds
against one to three minutes, with no -dev package at all. The choice
lives in EL_PYTHON_PROVIDER -- auto, mise or pyenv -- and in a single
file, lib_python_provider.sh. The rest of the repository only knows venv
paths and needs to know none of this.

In auto mode an ALREADY installed interpreter wins, whichever provider put
it there. mise is never installed on its own, "curl | sh" commits too much
for a script to decide -- make install_mise carries that decision.
MISE_PYTHON_COMPILE=false forbids it from quietly compiling: without that
guard it would fall back to pyenv's own engine, giving us the slowness
without the tooling. That is also what stopped gcc from collapsing while
building CPython on a low-memory s390x guest, for nothing.

One real bug falls along the way: a failed venv did not stop the install,
which then went on and failed further down, far from the cause.

--- FR ---

mise pose un CPython précompilé là où pyenv en compile un : des secondes
contre une à trois minutes, et aucun paquet -dev. Le choix vit dans
EL_PYTHON_PROVIDER — auto, mise ou pyenv — et dans un seul fichier,
lib_python_provider.sh. Le reste du dépôt ne connaît que des chemins de
venv et n'a rien à savoir de tout cela.

En mode auto, un interpréteur DÉJÀ posé l'emporte, quel qu'en soit le
fournisseur. mise n'est jamais installé de lui-même, « curl | sh » engage
trop pour qu'un script en décide — make install_mise porte cette décision.
MISE_PYTHON_COMPILE=false lui interdit de compiler en silence : sans ce
garde, il retomberait sur le moteur de pyenv, et nous aurions sa lenteur
sans son outillage. C'est aussi ce qui a évité que gcc s'écroule en
bâtissant CPython sur une VM s390x à faible mémoire, inutilement.

Un vrai défaut tombe au passage : un venv raté n'arrêtait pas
l'installation, qui continuait et échouait plus loin, loin de la cause.

Assisted-by: Claude Opus 5
2026-08-16 23:33:49 -04:00
7120732c25 [ADD] install: openSUSE support, mirrors and packages
Tumbleweed is the only catalog entry whose qpdf already clears the pikepdf
threshold: 12.3.2 against 12.2 required, so the half-hour qpdf build under
s390x emulation never runs there. It is also the only family foreign to
both RHEL and Debian, and it brings zypper, absent from the repository:
wired into the install_dev.sh dispatch, a dependency script, the remote
bootstrap and the desktop block.

Four SUSE traps, all met on real machines. Global options precede the
subcommand, and misplaced ones abort the call; without
"--auto-agree-with-licenses" zypper waits for an answer nobody gives in a
detached install. A compat package that PROVIDES another under a different
name makes zypper raise a conflict and drop the whole batch, so only what
nothing already provides is requested. pkg-config no longer exists as an
RPM, only as a capability. And a single mirror, unreachable one day, sent
everyone back to Europe -- three are probed in order now.

CentOS Stream is dropped again: it served as a canary but 10 duplicates
what Alma and Rocky already cover.

--- FR ---

Tumbleweed est la seule entrée du catalogue dont qpdf franchit déjà le
seuil de pikepdf : 12.3.2 contre 12.2 exigé, si bien que la demi-heure de
compilation de qpdf sous émulation s390x ne s'y déclenche jamais. C'est
aussi la seule famille étrangère à RHEL comme à Debian, et elle apporte
zypper, absent du dépôt : câblé dans l'aiguillage d'install_dev.sh, un
script de dépendances, l'amorçage distant et le bloc bureau.

Quatre pièges SUSE, tous rencontrés sur machine réelle. Les options
globales précèdent la sous-commande, mal placées elles arrêtent l'appel ;
sans « --auto-agree-with-licenses » zypper attend une réponse que personne
ne donne dans une installation détachée. Un paquet compat qui FOURNIT un
autre sous un nom différent fait lever un conflit à zypper, qui abandonne
le lot entier : on ne demande donc que ce que rien ne fournit déjà.
pkg-config n'existe plus comme RPM, seulement comme capacité. Et un miroir
unique, injoignable un jour, renvoyait tout le monde en Europe — trois
sont désormais sondés dans l'ordre.

CentOS Stream repart : il servait de canari, mais 10 double ce qu'Alma et
Rocky couvrent déjà.

Assisted-by: Claude Opus 5
2026-08-16 23:33:49 -04:00
f39b2e9451 [UPD] support: drop Ubuntu 20.04/22.04, add AlmaLinux and Rocky
Ubuntu 20.04 and 22.04 leave EVERY architecture, not just s390x. pikepdf
needs qpdf 12.2, whose build requires C++20, while focal ships GCC 9 and
publishes no g++-10 for s390x at all. Python 3.8, node 10, cargo 0.67 and
OpenSSL 1.1.1 each had a workaround; the pile of them did not. 18.04
follows, already off the lists. The refusal lands before any apt, this
script also serving existing machines.

AlmaLinux 9 and 10, Rocky 9 and 10 join the catalog on all four
architectures: the twelve "latest" URLs were opened, with no index to
parse unlike Fedora. They would have booted unreachable though -- the
cloud-config forced "groups: users, sudo", but the RHEL family has no
sudo group, only wheel, and an unknown group makes useradd fail, hence no
password and no key. The very trap already known for Debian, repeated
elsewhere. Host side, EPEL and CRB are enabled: without them most -devel
packages are missing, silently.

The server / graphical choice gains Cinnamon, the Linux Mint desktop,
from the distribution's own repositories. Mint's repository is set aside:
plain HTTP, and i386/amd64 only, which would rule out arm64 and s390x.
Along the way, dnf now installs an ENVIRONMENT rather than a group --
"gnome-desktop" brings gdm and gnome-shell but not base-x, hence no X
server.

--- FR ---

Ubuntu 20.04 et 22.04 partent de TOUTES les architectures, pas seulement
de s390x. pikepdf réclame qpdf 12.2, dont la compilation exige C++20,
quand focal livre GCC 9 et ne publie même pas de g++-10 pour s390x.
Python 3.8, node 10, cargo 0.67 et OpenSSL 1.1.1 avaient chacun leur
contournement ; leur accumulation, non. 18.04 suit, déjà hors des
listes. Le refus tombe avant tout apt, ce script servant aussi les
machines existantes.

AlmaLinux 9 et 10, Rocky 9 et 10 entrent au catalogue, sur les quatre
architectures : les douze URL « latest » ont été ouvertes, aucun index à
analyser contrairement à Fedora. Elles auraient pourtant démarré
inaccessibles — le cloud-config imposait « groups: users, sudo », or la
famille RHEL n'a pas de groupe sudo mais wheel, et un groupe inconnu fait
échouer useradd, donc ni mot de passe ni clé. C'est le piège déjà connu
pour Debian, reproduit ailleurs. Côté hôte, EPEL et CRB sont activés :
sans eux la plupart des -devel manquent, en silence.

Le choix serveur / graphique gagne Cinnamon, le bureau de Linux Mint,
depuis les dépôts de la distribution. Le dépôt de Mint lui-même est
écarté : il est en HTTP nu et ne publie que i386 et amd64, ce qui
exclurait arm64 et s390x. Au passage, dnf installe désormais un
ENVIRONNEMENT et non un groupe — « gnome-desktop » apporte gdm et
gnome-shell mais pas base-x, donc pas de serveur X.

Assisted-by: Claude Opus 5
2026-08-16 23:33:49 -04:00
b4b95042ef [UPD] claude: align the commit command with the AI policy
The template wrote « Generated by Claude Code », the form AI_POLICY.md
replaces with the Assisted-by trailer. Three defects rode along: the model
came from ~/.claude/settings.json, which has no model key here, so it
declared the sonnet default rather than the truth; --author alone failed on
the committer, this checkout having no git identity; and [UPD] was missing
from the tag table while being the most used tag, 134 of the last 400.

The model now comes from the session transcript, the only source that
follows a /model switch — checked, it prints Claude Opus 5. The timezone is
left to the system so contributors keep their own, and the menu substitutes
name and email separately, the placeholders no longer being adjacent.

--- FR ---

Le gabarit écrivait « Generated by Claude Code », la forme que AI_POLICY.md
remplace par le trailer Assisted-by. Trois défauts l'accompagnaient : le
modèle venait de ~/.claude/settings.json, sans clé model ici, si bien qu'il
déclarait le défaut sonnet plutôt que la vérité ; --author seul échouait sur
le committer, ce checkout n'ayant aucune identité git ; et [UPD] manquait au
tableau des tags alors qu'il est le plus utilisé, 134 des 400 derniers.

Le modèle vient désormais de la transcription de session, seule source qui
suive un changement par /model — vérifié, elle rend Claude Opus 5. Le fuseau
est laissé au système, pour que chaque contributeur garde le sien, et le
menu substitue nom et courriel séparément, les jetons n'étant plus accolés.

Assisted-by: Claude Opus 5
2026-08-07 01:56:11 -04:00
be93d3d90c [REF] claude: trim the always-loaded guidance, and fix what it got wrong
Every session paid ~4 000 tokens for CLAUDE.md and .claude/rules/, and part of
that content no longer described this repository:

  CLAUDE.md and 05-environments.md gave .venv.odoo18/bin/python — a path that
  does not exist. The real one carries BOTH versions,
  .venv.odoo18.0_python3.12.10. 02-project-structure.md announced addons/ and
  odoo12.0/, absent from the checkout.

That is the reason for the cuts, more than the token count: the files drifted
from the repository, while « ls » cannot. What a session can rebuild by
reading the code is now left to the code.

  02-project-structure.md   deleted — a tree that ls gives, and gives right
  05-environments.md        deleted — a venv list that was simply false
  04-code-conventions.md    reduced to a pointer at .flake8, .editorconfig and
                            pyproject.toml, which already hold every value it
                            repeated, plus the Git conventions, which they
                            do not
  01-versions.md            table dropped for the pointer at
                            conf/supported_version_erplibre.json, whose keys
                            already pair Odoo with Python

Two blocks move to lazy loading — their body costs nothing until invoked:

  03-commands.md      -> skill erplibre-commands (kept whole: there is no
                         « make help » target, and the per-module test recipes
                         carry flags nobody would guess)
  07-documentation.md -> skill erplibre-doc-i18n for the how-to, while the
                         prohibition « never edit a generated .md » STAYS in
                         the rules: a rule that must hold at all times cannot
                         live in a file loaded on demand

Resident guidance: ~3 997 -> ~1 939 est. tokens per session.

--- FR ---

Chaque session payait environ 4 000 jetons pour CLAUDE.md et .claude/rules/, et
une partie de ce contenu ne décrivait plus ce dépôt :

  CLAUDE.md et 05-environments.md donnaient .venv.odoo18/bin/python — un chemin
  qui n'existe pas. Le vrai porte les DEUX versions,
  .venv.odoo18.0_python3.12.10. 02-project-structure.md annonçait addons/ et
  odoo12.0/, absents du checkout.

C'est la raison des coupes, plus encore que le nombre de jetons : les fichiers
avaient dérivé par rapport au dépôt, ce que « ls » ne peut pas faire. Ce qu'une
session peut reconstruire en lisant le code est désormais laissé au code.

  02-project-structure.md   supprimé — une arborescence que ls donne, et donne
                            juste
  05-environments.md        supprimé — une liste de venvs simplement fausse
  04-code-conventions.md    réduit à un renvoi vers .flake8, .editorconfig et
                            pyproject.toml, qui portent déjà toutes les valeurs
                            qu'il répétait, plus les conventions Git, qu'ils ne
                            portent pas
  01-versions.md            tableau abandonné au profit du renvoi vers
                            conf/supported_version_erplibre.json, dont les clés
                            apparient déjà Odoo et Python

Deux blocs passent en chargement paresseux — leur corps ne coûte rien tant
qu'il n'est pas invoqué :

  03-commands.md      -> skill erplibre-commands, conservée entière : il
                         n'existe pas de cible « make help », et les recettes
                         de test par module portent des drapeaux que personne
                         ne devinerait
  07-documentation.md -> skill erplibre-doc-i18n pour le mode d'emploi, tandis
                         que l'interdiction « ne jamais éditer un .md généré »
                         RESTE dans les règles : une règle qui doit tenir en
                         permanence ne peut pas vivre dans un fichier chargé à
                         la demande

Consignes résidentes : environ 3 997 -> 1 939 jetons estimés par session.

Assisted-by: Claude Opus 4.8
2026-08-07 01:15:33 -04:00
e2901526bf [ADD] claude: add /mobile slash command for mobile dev guidance
Provides Claude Code with structured context about the
ERPLibre Home Mobile project (OWL 2, Capacitor 8, Vite,
Vitest, SQLite) including stack, conventions, commands,
and migration patterns.

--- FR ---

Fournit à Claude Code un contexte structuré sur le projet ERPLibre Home
Mobile — OWL 2, Capacitor 8, Vite, Vitest, SQLite — incluant la pile
technique, les conventions, les commandes et les motifs de migration.

Assisted-by: Claude Sonnet 4.6
2026-08-07 01:06:26 -04:00
fd3506351d [ADD] .claude settings local permission 2026-08-07 01:05:20 -04:00
0ab71279b0 [ADD] claude_agents: add feature orchestrator and /feature command
Add a multi-agent orchestrator that coordinates all 25 specialist agents
through 5 phases (analysis, design, implementation, verification, release)
with agent-to-agent communication via Agent Teams. Add /feature slash
command as the entry point. Enable CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS
in project settings to allow direct inter-agent messaging.

--- FR ---

Ajoute un orchestrateur multi-agents qui coordonne les 25 agents spécialisés
en 5 phases — analyse, conception, implémentation, vérification, publication
— avec communication d'agent à agent par les Agent Teams. Ajoute la commande
slash /feature comme point d'entrée. Active
CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS dans les réglages du projet pour
autoriser la messagerie directe entre agents.

Assisted-by: Claude Sonnet 4.6
2026-08-07 01:05:14 -04:00
25796952ee [ADD] claude_agents: add 25 specialized AI agents for mobile project
Add a full catalog of Claude Code subagents covering all development
disciplines needed for a banking-grade open-source mobile app:
code quality, QA, backend, frontend, UX, architecture, security,
docs, community, product, ethics, DevOps/SRE, release, incident
response, performance, pentest, accessibility, compliance, risk,
data governance, legal/license, support, localization, and AI
agent engineering.

--- FR ---

Ajoute un catalogue complet de sous-agents Claude Code couvrant toutes les
disciplines de développement nécessaires à une application mobile libre de
qualité bancaire : qualité du code, AQ, dorsal, frontal, UX, architecture,
sécurité, documentation, communauté, produit, éthique, DevOps/SRE,
publication, réponse aux incidents, performance, test d'intrusion,
accessibilité, conformité, risque, gouvernance des données, aspects
juridiques et de licence, soutien, localisation et ingénierie des agents
d'IA.

Assisted-by: Claude Sonnet 4.6
2026-08-07 01:05:08 -04:00
0cce4a2f4c [UPD] claude command instruction 2026-03-17 04:00:55 -04:00
ac30054d07 [REF] claude: split CLAUDE.md into .claude/rules/
Keep CLAUDE.md lean (~44 lines) with project identity,
core principles, and Claude-specific instructions only.
Move detailed documentation into 9 thematic rule files
under .claude/rules/ for better context optimization.

Generated by Claude Code 2.1.74 model claude-sonnet-4-6

Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
2026-03-14 23:15:54 -04:00