docs: document the branch and promotion model
Committed verbatim from the working tree, where it had been sitting uncommitted. Written by Patrick, not by the agent: this commit only puts it under version control so the promotion chain it describes can be corrected against reality in the next one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
f0a3aafda0
commit
f839f5d435
182
AGENTS.md
182
AGENTS.md
@ -1,16 +1,184 @@
|
||||
# AGENTS.md — etm-powersync-plugins-modbus
|
||||
|
||||
Plugins Modbus ETM (fork GPL) : compteurs, bornes, relais.
|
||||
Contient abbb2x, abbterra, eastron, waveshare-relay-d8.
|
||||
Tous les plugins Modbus supportés par ETM : plugins propres et forks de plugins amont.
|
||||
Compteurs, bornes de recharge, relais, onduleurs.
|
||||
|
||||
- **Licence** : GPL-3.0 (+ LGPL pour libnymea-modbus / libnymea-sunspec) · **Miroir public** : OUI
|
||||
- **Agent** : aucun en beta — plugins déjà publiés, repo de maintenance/référence.
|
||||
- **Licence** : GPL-3.0 pour les plugins, LGPL-3.0 pour `libnymea-modbus` / `libnymea-sunspec`
|
||||
- **Miroir public** : OUI
|
||||
- **Paquets** : publiés sur `repos.etm-powersync.fr`, trois canaux
|
||||
|
||||
L'inventaire des plugins est l'arborescence du dépôt. Ne pas se fier à une liste écrite ici : elle
|
||||
serait périmée, et un agent en conclurait que le reste n'existe pas.
|
||||
|
||||
Ce dépôt est autoportant : tout ce qui est nécessaire pour y travailler est ici.
|
||||
|
||||
## Placement du travail non amont
|
||||
|
||||
Une fois qu'un développement — plugin, correctif, extension vendor — n'est ni upstream officiel ni
|
||||
destiné à y retourner à court terme, il vit dans le dépôt produit ETM correspondant
|
||||
(`etm-powersync-plugins-modbus` ou `etm-powersync-plugins`), vendoré depuis sa source si elle existe
|
||||
ailleurs (`VENDORED.md` avec commit et date), développé directement sinon. Le fork correspondant
|
||||
(`nymea-plugins-modbus` ou `nymea-plugins`) ne garde que ce qui reste candidat à une contribution
|
||||
amont.
|
||||
|
||||
## Branches et canaux
|
||||
|
||||
```
|
||||
feature/* ──► landing-silo ──► experimental-silo ──► master
|
||||
(nightly) (testing) (stable)
|
||||
```
|
||||
|
||||
Vers la droite on promeut, vers la gauche on redescend un correctif. Une correction ne saute
|
||||
jamais un cran.
|
||||
|
||||
`experimental-silo` n'est pas une branche de travail : elle ne reçoit que ce qui a déjà survécu au
|
||||
nightly. Le travail se fait dans `feature/*`.
|
||||
|
||||
### Critères de promotion
|
||||
|
||||
| Passage | Critère |
|
||||
|---|---|
|
||||
| commits dans `feature/*` | `verify` en local, l'agent boucle seul |
|
||||
| `feature/*` → `landing-silo` | PR, `verify` vert sur le runner, AC de la spec couverts par des tests |
|
||||
| `landing-silo` → `experimental-silo` | build complet propre, banc nocturne vert |
|
||||
| `experimental-silo` → `master` | validation matérielle nommée : appareil, firmware, configuration |
|
||||
|
||||
Le dernier critère n'est pas automatisable et ne doit pas l'être.
|
||||
|
||||
### Correctifs
|
||||
|
||||
**Avant de créer une branche : reproduire le bug et déterminer la branche la plus proche de
|
||||
`master` où il apparaît.** C'est elle qui décide du point de départ, pas l'urgence ressentie.
|
||||
|
||||
| Le bug se reproduit… | Départ | Ensuite |
|
||||
|---|---|---|
|
||||
| jusque dans `master` | `hotfix/*` depuis `master` | fusion dans `master`, puis redescente dans `experimental-silo`, puis dans `landing-silo` |
|
||||
| dans `experimental-silo`, pas dans `master` | `fix/*` depuis `experimental-silo` | redescente dans `landing-silo` |
|
||||
| seulement dans `landing-silo` | `fix/*` depuis `landing-silo` | rien, il remonte par la promotion normale |
|
||||
|
||||
Ne jamais corriger en aval un bug présent en amont : le correctif remontera un jour, mais la
|
||||
branche amont reste cassée entre-temps et la promotion suivante réintroduit l'ancien code par
|
||||
dessus. Symptôme : « le correctif ne tient pas ».
|
||||
|
||||
Si une fusion casse le nightly, **révoquer la fusion** dans `landing-silo` pour rendre le canal de
|
||||
nouveau utilisable, puis corriger tranquillement dans la branche `feature/*` d'origine. Ne pas
|
||||
corriger en avant sous pression.
|
||||
|
||||
Trois préfixes, pas davantage : `feature/*`, `fix/*`, `hotfix/*`.
|
||||
|
||||
### Versionnement des paquets
|
||||
|
||||
Tout paquet issu d'un dépôt produit ETM porte un suffixe `+etmN` sur la version amont qu'il modifie
|
||||
ou remplace (ex. `1.15.2+etm1`), à tous les canaux de promotion (`landing-silo`/nightly,
|
||||
`experimental-silo`/testing, `main`/stable). Ce suffixe garantit la préséance apt/dpkg sur le paquet
|
||||
upstream identique.
|
||||
|
||||
Ne jamais le remplacer par un tiret (`-etmN`) : `-` a un sens réservé en version Debian (champ
|
||||
`debian_revision`) et entre en conflit avec une éventuelle révision Debian amont.
|
||||
|
||||
## Agents
|
||||
|
||||
Les agents travaillent dans `feature/*` et `fix/*`. Jamais de commit direct dans `landing-silo`,
|
||||
`experimental-silo` ou `master` : ces branches ne reçoivent que des fusions.
|
||||
|
||||
Une spec, une branche, un jeu de critères d'acceptation.
|
||||
|
||||
Un agent qui estime qu'un refactor s'impose sur un plugin publié le signale et s'arrête. Il ne le
|
||||
fait pas.
|
||||
|
||||
## Invariants locaux
|
||||
1. NE PAS renommer les paquets PUBLIÉS : `powersync-plugin-eastron`,
|
||||
|
||||
1. **NE PAS renommer les paquets PUBLIÉS** : `powersync-plugin-eastron`,
|
||||
`powersync-plugin-abbb2x`, `nymea-plugin-abbterra`. Casse l'upgrade des box beta.
|
||||
Valable sur toutes les branches : un renommage dans `landing-silo` finit par atteindre `master`.
|
||||
2. `abbterra` est volontairement sous nom amont (transition upstream propre) — ne pas « corriger ».
|
||||
3. Matrice validée beta : SDM72 / SDM120 (eastron), Waveshare D8.
|
||||
4. Aucun composant propriétaire ici.
|
||||
4. Aucun composant propriétaire ici. Aucun ne doit y entrer.
|
||||
|
||||
Carte globale et frontières : voir `../AGENTS.md`.
|
||||
## Miroir public — ne doit jamais être commité
|
||||
|
||||
Données client : adresses de site, noms, numéros de série, relevés, adresses IP d'installations
|
||||
réelles. Identifiants et jetons. Documentation constructeur sous réserve de confidentialité — elle
|
||||
se cite en référence (titre, version, section) dans la table de provenance des registres, jamais
|
||||
en contenu.
|
||||
|
||||
Les captures, journaux et dumps de registres joints à un correctif sont expurgés avant commit.
|
||||
|
||||
---
|
||||
|
||||
## Repository Guidelines
|
||||
|
||||
These conventions apply to every `*-plugins-modbus` repository. They are not a style preference:
|
||||
plugins from all of them load into the **same nymea-core**, so they share its ABI, its Qt version,
|
||||
its plugin metadata format and its interface definitions. A repository that diverges produces
|
||||
plugins that do not interoperate.
|
||||
|
||||
**Target: nymea-core `<version>`.** Where these guidelines and the core repository's `AGENTS.md`
|
||||
disagree, the core repository wins and this section is corrected.
|
||||
|
||||
This section is identical, byte for byte, across every `*-plugins-modbus` repository, and is the
|
||||
part that can be contributed upstream. Anything specific to one repository belongs above it.
|
||||
|
||||
### Plugin anatomy
|
||||
|
||||
One directory per vendor, holding its sources, headers, plugin metadata (`*.json`), translations
|
||||
and packaging fragments. Plugin IDs, translation filenames and resource prefixes follow the
|
||||
directory name.
|
||||
|
||||
Shared code stays in the shared libraries. Never move code between an LGPL library and a GPL
|
||||
plugin without addressing the licence change explicitly.
|
||||
|
||||
### Build
|
||||
|
||||
Requires `plugin.pri`, provided by `libnymea1-dev`, or passed explicitly via `PLUGIN_PRI=`.
|
||||
|
||||
```
|
||||
qmake <project>.pro && make -j"$(nproc)" # whole repository
|
||||
cd <vendor> && qmake <vendor>.pro && make # single plugin — the short loop, preferred
|
||||
```
|
||||
|
||||
Select the Qt version before calling qmake. When building against a nymea source tree rather than
|
||||
a system-wide install, `PKG_CONFIG_PATH`, `CPATH`, `LIBRARY_PATH`, `LD_LIBRARY_PATH` and a `PATH`
|
||||
extended with the `nymea-plugininfocompiler` build directory are also required.
|
||||
|
||||
Verbose logs: `QT_LOGGING_RULES="*.debug=true"`.
|
||||
|
||||
### Style
|
||||
|
||||
Qt conventions: 4-space indent, `CamelCase` classes, `lowerCamelCase` functions and members with
|
||||
the `m_` prefix, Qt containers and signals over STL, log output wrapped in
|
||||
`NYMEA_LOGGING_CATEGORY`, and `foreach` rather than range-based `for` to keep C++11 compatibility.
|
||||
|
||||
Refresh translations whenever user-visible text changes.
|
||||
|
||||
### Register provenance
|
||||
|
||||
**Never infer a register address.** Every address comes from the manufacturer's documentation or
|
||||
from a read performed against a real device. A value taken from a third-party implementation is a
|
||||
hypothesis until verified on hardware, and is documented as such.
|
||||
|
||||
Addresses, scale factors and endianness belong in the vendor's register description, not scattered
|
||||
as literals through the implementation.
|
||||
|
||||
### Hardware validation
|
||||
|
||||
Compiling is not verifying. Any claim of validation names the device, its firmware version and its
|
||||
configuration. Without hardware, say so and describe the validation still required rather than
|
||||
implying it was performed.
|
||||
|
||||
Where a Modbus server can be simulated, prefer a captured register dump replayed against the
|
||||
plugin over a hand-written mock: a dump carries the quirks a mock will not.
|
||||
|
||||
### Device writes
|
||||
|
||||
A write can damage equipment or void a warranty. Write paths are reviewed more strictly than read
|
||||
paths: state what is written, under which conditions, and what happens if the plugin stops
|
||||
mid-operation.
|
||||
|
||||
### Commits and pull requests
|
||||
|
||||
Imperative subjects under ~72 characters.
|
||||
Pull request titles: `Plugin name: Add support for xyz` or `New plugin: Plugin name`.
|
||||
State whether the change was tested on hardware, and if not, name someone who can confirm it.
|
||||
Update the plugin's `README.md` and the translations.
|
||||
Call out packaging impacts — Qt 5 and Qt 6 packaging are maintained separately.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user