docs(règles): sept règles étaient implémentées et non citées

Premier usage réel de l'index, et il donne un résultat inattendu : sur les 70
règles « spécifiée seule », une part notable n'est PAS un trou d'implémentation
mais un trou de CITATION. Vérifié en cherchant le CONTENU dans le code plutôt que
l'identifiant :

  ECS-110-b      un Thing n'appartient qu'à une charge active  → validateSet()
  LM-302-b       l'exclusivité ne se valide pas dans une charge utile → idem
  LM-1209-a-bis  écarter et refuser ne sont pas la même fonction → validateRanks()
  ECS-410-b      l'issue de ClearLoadFault est journalisée par l'arbitre
  LM-303         les verrous appartiennent au mécanisme, pas au domaine
  LM-1208-c      sans voiture, le nombre de phases vient de la borne
  ECS-308        MaxRelays TRONQUE au lieu de refuser

Toutes portées par du code, aucune citée. L'index les comptait donc comme
spécifiées seules — il SOUS-DÉCLARE la couverture, exactement comme il peut la
surdéclarer. C'est la même limite que celle écrite en tête de la page générée
(« cité par n'est pas couvert par »), prise par l'autre bout : un identifiant
absent d'un commentaire ne dit rien de ce que le code fait.

Citations ajoutées avec \rule{}, l'alias posé hier — donc navigables du
commentaire vers la règle. Aucun changement de comportement : ce sont des
commentaires. 63 « spécifiée seule » au lieu de 70, 21 citées par le code au lieu
de 14.

ci-quality 3/3, build 0/0.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015F7G5VeaPVSMeVNjiGj36p
This commit is contained in:
Patrick Schurig 2026-08-29 12:44:12 +02:00
parent 010a7da0f4
commit d3dfe519d5
5 changed files with 15 additions and 1 deletions

View File

@ -15,6 +15,9 @@
namespace {
//! Au-delà, 2^N combinaisons explose. 16 relais = 65536 combos — bien au-delà de tout ECS réel.
//! \rule{ECS-308} — le plafond TRONQUE au lieu de refuser : au-delà, les relais
//! surnuméraires sont ignorés en silence. Connu, non corrigé, et c'est pour cela que la
//! règle existe — 2^16 sous-ensembles est déjà une table qu'aucune installation n'atteint.
constexpr int MaxRelays = 16;
}

View File

@ -115,6 +115,8 @@ public:
* \param relays Liste \c {thingId, powerW} des relais \c power. Les paliers atteignables
* sont dérivés de toutes leurs combinaisons.
* \param minOnS/minOffS Verrous anti-rebond (protection relais/compresseur), appliqués ici.
* \rule{LM-303} — les verrous appartiennent au MÉCANISME, pas au domaine : c'est le
* relais qui craint le court-cycle, pas le service rendu.
* \param priority Rang dans le waterfall (1 = servi en premier).
* \param needs Besoins déclarés (exposés via descriptor().needs).
* \param parent Propriétaire Qt.

View File

@ -112,6 +112,10 @@ bool LoadConfigStore::validateSet(const LoadConfigs &configs, QString *error)
if (!c.enabled())
continue; // ne construit aucun adaptateur : ne revendique rien
// \rule{ECS-110-b} — un Thing n'appartient qu'à UNE charge active. \rule{LM-302-b} :
// l'exclusivité ne peut PAS se valider dans une charge utile, aucune charge ne voyant
// les autres — d'où ce contrôle d'ENSEMBLE, et d'où le fait qu'il soit distinct de
// isValid().
for (const QString &thing : c.claimedThingIds()) {
const QString deja = proprietaire.value(thing);
if (!deja.isEmpty())

View File

@ -71,7 +71,9 @@ public:
* \param configs Ensemble candidat. \param error Motif du refus, si refus.
* \return Faux si deux charges portent le même rang.
*
* \note **Distincte de \c validateSet(), et la distinction est de sûreté, pas de propreté.**
* \note **Distincte de \c validateSet(), et la distinction est de sûreté, pas de propreté**
* — \rule{LM-1209-a-bis} : une vérification qui ÉCARTE et une qui REFUSE ne peuvent pas
* être la même fonction.
* \c validateSet() nomme ce qui rend un ensemble DANGEREUX — deux charges sur un même
* organe — et \c load() s'en sert pour ÉCARTER l'entrée fautive. Celle-ci nomme ce qui
* rend un ensemble MAL FORMÉ, et le seul geste correct y est de REFUSER l'écriture

View File

@ -206,6 +206,8 @@ bool EnergyArbitrator::clearLoadFault(const QString &loadId)
return false;
}
// \rule{ECS-410-b} — l'issue est journalisée, et par l'ARBITRE : c'est lui qui sait si
// un défaut existait, l'adaptateur ne rendant qu'un booléen.
qCInfo(dcNymeaEnergy()) << "[Arbitre] ClearLoadFault demandé par l'opérateur pour" << loadId;
const bool leve = adapter->clearFault();
if (leve)
@ -532,6 +534,7 @@ uint EnergyArbitrator::evTargetPhases(EvCharger *ev, double referenceA)
// retient le nombre de phases de la BORNE, qui est celui qu'elle utilisera réellement.
// C'est l'hypothèse conservatrice pour le budget : elle SURESTIME la consommation de la
// borne plutôt que de la sous-estimer.
// \rule{LM-1208-c}
if (!internalHasProcessInfo(ev))
return qMax(1u, ev->phaseCount());