Patrick Schurig 0cdcfe433b docs: align the branch model with the actual remote
Two points the document got wrong. The stable branch is main, not
master: the remote has never had a master. And the promotion chain was
written as if it existed, while landing-silo and experimental-silo were
created only today, the first as empty branches off main.

Nothing else in the document is touched.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-02 10:29:32 +02:00

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/*  ──►  landing-silo  ──►  experimental-silo  ──►  main
                  (nightly)          (testing)            (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 ; landing-silo a ensuite reçu feature/fronius-sunspec comme premier contenu, experimental-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.

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 → 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 experimental-silo, puis dans landing-silo
dans experimental-silo, pas dans main 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 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

  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 main.
  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. 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.