diff --git a/AGENTS.md b/AGENTS.md index f902e52..3dff451 100644 --- a/AGENTS.md +++ b/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 ``.** 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 .pro && make -j"$(nproc)" # whole repository +cd && qmake .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.