[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
This commit is contained in:
parent
960918c939
commit
5fb49da0f2
4 changed files with 134 additions and 21 deletions
|
|
@ -8,6 +8,72 @@ configuration du dépôt — les lire plutôt que de supposer : `.flake8`,
|
|||
Prettier (via npm) formate XML/JSON/YAML ; `.editorconfig` donne les
|
||||
indentations par type de fichier.
|
||||
|
||||
## Commentaires
|
||||
|
||||
Un commentaire dit COMMENT le code fonctionne : ce que la fonction prend, ce
|
||||
qu'elle rend, l'invariant qu'elle tient, ses effets de bord, la contrainte
|
||||
technique qu'on ne devine pas en lisant la ligne d'à côté. Il doit se lire
|
||||
dans dix ans sans rien savoir de la semaine où il a été écrit. La règle vaut
|
||||
pour les docstrings autant que pour les lignes `#`.
|
||||
|
||||
**L'épreuve : le sujet et le temps.** Chaque phrase a le CODE pour sujet, au
|
||||
présent de ce qu'il fait. Une phrase dont le sujet est un incident, une
|
||||
machine, une date ou une personne est à couper, où qu'elle se trouve dans le
|
||||
paragraphe. Le MODE DE DÉFAILLANCE que le code empêche est du fonctionnement
|
||||
et reste — « une VM renommée se voit attribuer la passerelle ». L'INCIDENT où
|
||||
on l'a observé est du récit et part — « vécu sur telle VM, annoncée à telle
|
||||
adresse ».
|
||||
|
||||
**Les chiffres.** Une mesure qui établit un fait durable reste, dépouillée de
|
||||
sa date, de son lieu et de son opérateur : une limite, un seuil, une valeur
|
||||
que documente l'éditeur. Un relevé de ce qui répondait ce jour-là part.
|
||||
|
||||
**Rien d'identifiant, jamais** : nom d'un client ou d'une organisation tierce,
|
||||
nom de base de données réelle, nom de VM ou d'hôte, adresse IP, courriel,
|
||||
chemin portant un nom d'utilisateur, libellé ou chiffre tiré des données d'un
|
||||
client. La seule exception est l'en-tête de copyright : le dépôt nomme son
|
||||
propriétaire, pas ses clients. Généraliser plutôt que censurer — « sur une
|
||||
base de production », « sur un hôte qui exige une authentification sudo
|
||||
interactive » — dit la CLASSE de situation, qui est ce qui sert au lecteur.
|
||||
|
||||
Le récit n'est pas perdu, il change de place : l'enquête, les mesures datées
|
||||
et les impasses vivent dans `tasks/`, qui n'est pas versionné. Ni le fichier
|
||||
ni le corps du commit ne les portent.
|
||||
|
||||
Cela vaut aussi pour l'existant, mais **au fur et à mesure** : on corrige les
|
||||
commentaires du fichier qu'on touche, au moment où on le touche, et non en une
|
||||
passe qui réécrirait le dépôt. Le hook `pre-commit` liste ce qui est à relire
|
||||
dans les fichiers indexés, sans jamais bloquer le commit ; le même outil se
|
||||
lance à la main :
|
||||
|
||||
```bash
|
||||
python3 script/analyse/check_comment_hygiene.py script/todo/todo.py
|
||||
python3 script/analyse/check_comment_hygiene.py --staged
|
||||
```
|
||||
|
||||
🔴 `identifiant` est une trouvaille, à retirer. 🟡 `récit` est un signal à
|
||||
relire : l'outil ne sait pas si la phrase énonce un fait durable ou raconte
|
||||
une journée, et ne tranche pas à votre place.
|
||||
|
||||
Trois exemples pris dans ce dépôt, leurs noms propres masqués — une règle qui
|
||||
interdit de nommer ne se cite pas elle-même en clair.
|
||||
|
||||
`qemu_manage.py` — la dernière phrase, « Vécu sur « <VM> », annoncée en
|
||||
<adresse> au lieu de <adresse> », part en entier. Les deux qui la précèdent
|
||||
disent déjà tout, une fois l'imparfait du récit passé au présent : « une VM
|
||||
renommée, dont le bail porte encore l'ancien nom d'hôte, SE VOIT attribuer la
|
||||
passerelle ».
|
||||
|
||||
`todo.py` — « recopier « <base_client>_neutralize_upgrade_18 » oblige à
|
||||
regarder ce qu'on détruit » devient « recopier un nom long oblige à regarder
|
||||
ce qu'on détruit, là où « o » se tape par réflexe ». L'exemple ne servait qu'à
|
||||
illustrer « long ».
|
||||
|
||||
`qemu_install.py` — le relevé daté des miroirs, qui répondait et qui non tel
|
||||
jour, part : c'est l'état d'une journée. « Aucun miroir ne réplique tout,
|
||||
d'où plusieurs entrées plutôt qu'une » reste : c'est la raison d'être de la
|
||||
liste, et elle est vraie demain.
|
||||
|
||||
## Git
|
||||
- Branches : `develop` (développement), `master` (production)
|
||||
- Pas de submodules Git — utilise **Google Repo** pour les addons
|
||||
|
|
@ -39,8 +105,13 @@ virgules, en disent plus dans la même place — `[FIX] proxmox : pmxcfs à terr
|
|||
pvesm muet, diagnostic à la source`. C'est un repli, pas un défaut : la phrase
|
||||
reste préférable quand elle tient.
|
||||
|
||||
Un garde-fou refuse le mécanique — tag absent, plus de 72 caractères, sujet
|
||||
qui s'ouvre sur une citation :
|
||||
Un garde-fou refuse le mécanique. Sur le sujet : tag absent, plus de 72
|
||||
caractères, ouverture sur une citation. Sur le corps : plus de 10 lignes pour
|
||||
une langue, une adresse IP, un courriel, un chemin de compte, et tout terme de
|
||||
`private/noms_interdits.txt` — la liste des clients et des machines, qui ne
|
||||
peut pas vivre dans git puisque c'est ce qu'elle protège. Absente, ce dernier
|
||||
contrôle est muet. Ce qui reste un jugement — « ce corps raconte-t-il
|
||||
l'enquête » — n'est vérifié par personne.
|
||||
|
||||
```bash
|
||||
git config core.hooksPath script/git/hooks # une fois par clone
|
||||
|
|
@ -60,9 +131,16 @@ Trois exigences, sans exception — `AI_POLICY.md` en donne la raison :
|
|||
- Corps **bilingue** : le corps, puis `--- FR ---` (ou `--- EN ---`, le
|
||||
marqueur nomme la langue de ce qui SUIT), puis la traduction.
|
||||
|
||||
Court et direct : **10 lignes par langue**, 15 est déjà long. Le corps dit
|
||||
Court et direct : **8 lignes par langue**, 10 est un plafond. Le corps dit
|
||||
pourquoi c'était nécessaire, puis s'arrête. Rien de ce que le diff montre
|
||||
déjà ; on garde le symptôme, le chiffre mesuré et la vérification.
|
||||
déjà ; on garde le mode de défaillance, le chiffre qui borne et la
|
||||
vérification. Le bilinguisme achète la concision, il ne l'excuse pas.
|
||||
|
||||
Le corps obéit aux mêmes deux règles que les commentaires : **rien
|
||||
d'identifiant**, et **le fonctionnement plutôt que l'enquête**. Le corps dit
|
||||
ce que le code fait ou refuse DÉSORMAIS ; il ne raconte ni la séance, ni les
|
||||
hypothèses écartées, ni qui s'est trompé. Une mesure se généralise à sa classe
|
||||
de situation — « sur une base de production », jamais son nom.
|
||||
|
||||
Le mode d'emploi complet — résolution dynamique du modèle, gabarit, identité
|
||||
git, taille des correctifs — est dans
|
||||
|
|
|
|||
|
|
@ -45,5 +45,8 @@
|
|||
2. **Verify Plan**: Check in before starting implementation.
|
||||
3. **Track Progress**: Mark items complete as you go.
|
||||
4. **Explain Changes**: High-level summary at each step.
|
||||
5. **Document Results**: Add review section to `tasks/todo.md`
|
||||
5. **Document Results**: Add review section to `tasks/todo.md`. L'enquête,
|
||||
les mesures datées, les impasses et les traces d'exécution restent LÀ.
|
||||
`tasks/` n'est pas versionné : il porte ce que ni le code ni le commit ne
|
||||
doivent porter. Ne les fais pas remonter.
|
||||
6. **Capture Lessons**: Update `tasks/lessons.md` after corrections
|
||||
|
|
|
|||
|
|
@ -19,7 +19,14 @@ Version Odoo par défaut : **18.0** (support officiel ERPLibre 1.6.0)
|
|||
`ls -d .venv.odoo*` plutôt que de le composer de tête
|
||||
- Les scripts ERPLibre utilisent `.venv.erplibre/bin/python`
|
||||
- Le Makefile principal inclut des fragments depuis `conf/make.*.Makefile`
|
||||
- Les fichiers privés vont dans `private/` (non versionné)
|
||||
- Les fichiers privés vont dans `private/`. C'est le SEUL endroit qui a le
|
||||
droit de porter une donnée de client — nom, base, machine, adresse,
|
||||
chiffres. Il peut être commité, mais seulement sur un dépôt privé : sur
|
||||
un fork public, ce qui s'y trouve devient public comme le reste
|
||||
- Partout ailleurs — code, commentaires, messages de commit, documentation
|
||||
— aucune donnée identifiante, jamais. Ce sont les fichiers qui suivent le
|
||||
dépôt en amont. La règle complète, avec l'épreuve qui tranche, est dans
|
||||
`.claude/rules/04-code-conventions.md`
|
||||
- La DB PostgreSQL par défaut est sur le port 5432, mot de passe admin : `admin`
|
||||
- Port Odoo par défaut : 8069, longpolling : 8072
|
||||
- Pour les commits : suivre le format `[TYPE] description` (ex: `[FIX]`, `[UPD]`, `[ADD]`, `[REM]`)
|
||||
|
|
|
|||
|
|
@ -80,7 +80,9 @@ The first five cover every one of the last 400 commits. Reach for `[REM]`,
|
|||
[TAG] scope: short description in imperative mood
|
||||
|
||||
Explain WHY the change was made — the diff already shows what. Name the
|
||||
symptom that led to it, and what was measured rather than assumed.
|
||||
failure mode, and what was measured rather than assumed, in words a
|
||||
stranger to this site can read: the software, the version, the class of
|
||||
situation — never a customer, a real database, a machine or an address.
|
||||
Wrap at 80 characters.
|
||||
|
||||
--- FR ---
|
||||
|
|
@ -135,21 +137,27 @@ that matter says more in the space than half a sentence does:
|
|||
That form is a fallback, not a default. Prefer the sentence when it fits.
|
||||
|
||||
**The guard rail.** `script/git/hooks/commit-msg` refuses a subject with no
|
||||
tag, one over 72 characters, and one opening on a quotation. Install it with
|
||||
`git config core.hooksPath script/git/hooks`; `git commit --no-verify` passes
|
||||
a legitimate exception. It checks only what is mechanical — whether the
|
||||
subject says what the code is about stays a judgement, and the test above is
|
||||
how you make it.
|
||||
tag, one over 72 characters, and one opening on a quotation. It reads the body
|
||||
too: over ten lines for one language, an IP address, an e-mail, a
|
||||
`/home/<account>/` path, or any term listed in `private/noms_interdits.txt` —
|
||||
the customer and machine names, which cannot live in git because they are what
|
||||
the list protects. With no such file, that last check stays silent. Install
|
||||
the hook with `git config core.hooksPath script/git/hooks`; `git commit
|
||||
--no-verify` passes a legitimate exception. It checks only what is mechanical
|
||||
— whether the subject says what the code is about, and whether the body tells
|
||||
the story instead of the mechanism, stay judgements, and the tests above are
|
||||
how you make them.
|
||||
|
||||
### Keep it short
|
||||
|
||||
The body answers one question: why was this necessary. Stop once it is
|
||||
answered — the reader owes you nothing beyond that.
|
||||
|
||||
**Ten lines per language. Fifteen is already long.** Past that, the reasoning
|
||||
belongs in a document or a code comment, and the commit points at it. The
|
||||
budget is per language: bilingual doubles everything, so it buys terseness,
|
||||
it does not excuse length.
|
||||
**Eight lines per language. Ten is the ceiling.** Past that, the reasoning
|
||||
belongs in `tasks/`, which is not versioned, and the commit points at it —
|
||||
never in a code comment: a comment says how the code WORKS, not what happened
|
||||
the week it was written. The budget is per language: bilingual doubles
|
||||
everything, so it buys terseness, it does not excuse length.
|
||||
|
||||
Cut, in this order:
|
||||
|
||||
|
|
@ -160,10 +168,25 @@ Cut, in this order:
|
|||
- Every clause that would not change what a reader does: no `this commit`,
|
||||
no `I decided to`, no summary of the summary, no restating the subject.
|
||||
|
||||
Keep, always: the symptom that led to the change, the figure you measured
|
||||
rather than assumed, and one line naming what you verified and how. A single
|
||||
`Checked: 4 jobs, 1.63 s at parallelism 1 vs 0.58 s at 4` is worth three
|
||||
paragraphs of prose.
|
||||
Keep, always: the failure mode the change removes, the figure that bounds it,
|
||||
and one line naming what you verified and how. A single `Checked: 4 jobs,
|
||||
1.63 s at parallelism 1 vs 0.58 s at 4` is worth three paragraphs of prose.
|
||||
|
||||
Two tests decide what survives, and they apply to every sentence of the body.
|
||||
|
||||
**Tense and subject.** Each sentence says what the code now does or refuses,
|
||||
in the present. A sentence whose subject is an incident, a session, a machine,
|
||||
a date or a person is cut — including your own reasoning: no `my conclusion
|
||||
was wrong`, no `three faults found by running it`. That belongs in `tasks/`.
|
||||
|
||||
**Nothing identifying.** No customer or third-party organisation, no real
|
||||
database name, no VM or host name, no IP address, no e-mail, no path carrying
|
||||
a user name, no label or figure taken from a customer's data. Generalise to
|
||||
the CLASS of situation instead of censoring: `on a production database`, `on a
|
||||
development VM`, `on a host that demands interactive sudo` — the class is what
|
||||
serves the reader; the name never was. A figure that is a durable limit or
|
||||
threshold stays (65 536 inotify watches); a reading taken during one incident
|
||||
goes.
|
||||
|
||||
### Bilingual body
|
||||
|
||||
|
|
@ -197,7 +220,9 @@ the work.
|
|||
- `scope` is the Odoo technical module (`sale_order`, `account`, `stock`) or
|
||||
the area of the repository (`script todo`, `qemu ssh`, `migration`).
|
||||
- The commit stands on its own: state what was verified, and how. If a claim
|
||||
was not checked, say so rather than implying it was.
|
||||
was not checked, say so rather than implying it was. Standing on its own
|
||||
means it needs no OTHER COMMIT to be understood — not that it carries the
|
||||
whole investigation. The line budget above still binds.
|
||||
- If you cannot explain and defend every line, do not commit it.
|
||||
|
||||
### Size and pace
|
||||
|
|
|
|||
Loading…
Reference in a new issue