The chain climbs experimental-silo, then landing-silo, then main: a change is attempted in testing before it becomes a nightly candidate for stable. The document had the two silos the other way round, which is how the Fronius work ended up one rung below stable while it had only ever been verified against the bench simulator. Corrected in the diagram, the promotion criteria, the fix table and its downward path, the packaging channel list and the agent rules. The channel each branch feeds is unchanged: experimental-silo is testing, landing-silo is nightly. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
8.8 KiB
AGENTS.md — etm-powersync-plugins-modbus
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 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/* ──► experimental-silo ──► landing-silo ──► main
(testing) (nightly) (stable)
Vers la droite on promeut, vers la gauche on redescend un correctif. Une correction ne saute jamais un cran.
Les trois branches existent sur le remote depuis le 2026-08-02. Les deux silos ont été créés
vides depuis main ; experimental-silo a ensuite reçu le travail Fronius comme premier
contenu, landing-silo est encore au niveau de main. Avant cette date le modèle ci-dessus
était une intention, pas un état du dépôt.
Aucun silo n'est une branche de travail : landing-silo ne reçoit que ce qui a déjà survécu à
experimental-silo. Le travail se fait dans feature/*.
Critères de promotion
| Passage | Critère |
|---|---|
commits dans feature/* |
verify en local, l'agent boucle seul |
feature/* → experimental-silo |
PR, verify vert sur le runner, AC de la spec couverts par des tests |
experimental-silo → landing-silo |
build complet propre, banc nocturne vert |
landing-silo → main |
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
main 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 main |
hotfix/* depuis main |
fusion dans main, puis redescente dans landing-silo, puis dans experimental-silo |
dans landing-silo, pas dans main |
fix/* depuis landing-silo |
redescente dans experimental-silo |
seulement dans experimental-silo |
fix/* depuis experimental-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 (experimental-silo/testing,
landing-silo/nightly, 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 experimental-silo,
landing-silo ou main : 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
- 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 danslanding-silofinit par atteindremain. abbterraest volontairement sous nom amont (transition upstream propre) — ne pas « corriger ».- Matrice validée beta : SDM72 / SDM120 (eastron), Waveshare D8.
- Aucun composant propriétaire ici. Aucun ne doit y entrer.
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.