Patrick Schurig b552a1745b docs(règles): dix numéros retirés, deux tables supprimées, l'index câblé à Doxygen
Étapes 1 et 3 du chantier de documentation.

DIX NUMÉROS RETIRÉS — ECS-100/101/102/300/301/304/400/402/403/404. Ils
n'existaient QUE comme une étiquette de trois mots dans une table de statut :
aucun énoncé, nulle part. Leur reconstruire un texte depuis l'étiquette et le
code aurait été inventer une exigence en croyant la restituer, et une règle
inventée qui porte un numéro fait autorité pour toujours. Si le texte d'origine
n'existe nulle part, la règle n'existe pas ; ce que le code fait reste vrai, il
n'a simplement plus de règle à citer.

Retirés, pas effacés : tools/rules-retired.txt les porte, l'index les publie avec
leur date, leur motif et les endroits qui les citent encore. Un identifiant
croisé dans un vieux relevé renvoie donc à quelque chose — RELEVE_ECS306.md cite
toujours ECS-404, et c'est bien. Un numéro retiré n'est JAMAIS réattribué : le
générateur refuse une définition qui en reprendrait un, une même référence ne
doit pas désigner deux exigences selon la date de lecture.

Les citations VIVANTES de ces numéros sont retirées (spec_ecs §2/§4/§5,
AGENTS.md) — les phrases tiennent sans elles. Les citations HISTORIQUES restent.

DEUX TABLES SUPPRIMÉES, pas corrigées. §1 déclarait ECS-410/411/412 « absents »
alors que les trois étaient implémentées et testées. §9 « Traçabilité » nommait
HUIT tests qui n'ont jamais été écrits. Son défaut n'était pas d'être périmée
mais de mélanger un CONSTAT et une INTENTION sous la même colonne — « ECS-306 →
testEcsBudgetUnderLock » est un fait, « ECS-303 → banc » est un projet ; réunis,
le second garantit que l'ensemble devient faux. Les deux sont séparés : le
constat est généré, l'intention devient « Ce qui reste à éprouver », avec pour
chaque exigence POURQUOI elle n'est pas éprouvée.

DOXYGEN (étape 3). doc-generated/RULES.md entre en INPUT — ses ancres {#LM-1105}
rendent \rule{} résoluble — et l'alias \rule{1} est défini. Les specs restent
HORS périmètre : les y ajouter ferait entrer deux fois le même énoncé et
doublerait les ancres. Les 250 citations existantes ne sont pas converties : le
générateur les voit déjà, et \ref sert l'autre sens — du commentaire vers la
règle. Éprouvé sur un cas réel, \rule{LM-1209-c} résout sans avertissement.

Piège d'ordonnancement corrigé au passage : gen-rules.py écrit DANS $SORTIE, donc
l'appeler avant `rm -rf "$SORTIE"` l'effaçait aussitôt — doxygen signalait
« RULES.md is not a readable file ». L'index se produit après le nettoyage. Son
code de retour ne stoppe pas la génération (un index incomplet reste utile à
lire) mais est répercuté à la fin.

Avertissements doxygen : 30 → 26, dont 3 étaient les miens — rankOrigin(),
setRankOrigin() et knownRankOrigins() n'étaient pas documentés (DoD 5).

L'index sort désormais RC=0 : 111 règles, aucun orphelin, aucun domicile ambigu.
69 spécifiées seules, 16 citées par un test, 14 par le code, 12 vérifiées sur
machine. Build 0/0, loadmodel 20/20.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015F7G5VeaPVSMeVNjiGj36p
2026-08-29 09:36:18 +02:00

144 lines
6.8 KiB
Plaintext

# Doxyfile — etm-powersync-energy-plugin-etm
# Doxygen 1.9.8
#
# Périmètre : energyplugin/etm/ UNIQUEMENT. Le code amont forké
# (SmartChargingManager et satellites) n'est pas le nôtre ; l'inclure rendrait
# la mesure ininterprétable.
#
# ANGLE MORT ASSUMÉ : les ajouts marqués « // [ETM] » dans les en-têtes amont
# (energyplugin/smartchargingmanager.h) sont hors de ce périmètre et ne sont
# mesurés par aucune configuration tant que la frontière est un répertoire. Ils
# sont peu nombreux, déjà marqués, et documentés à la main — cf. la définition
# de fait dans AGENTS.md.
#
# ATTENTION — le graphe d'héritage est TRONQUÉ, et c'est voulu.
# « class EnergyArbitrator : public SmartChargingManager » est l'arête la plus
# intéressante du dépôt. Vérifié sur la sortie réelle (2026-08-11) : l'arête est
# bien DESSINÉE — doxygen rend une classe de base non résolue en boîte simple.
# Ce qui manque, c'est tout ce qu'il y a derrière : la boîte est un cul-de-sac,
# sans membres, sans ancêtres, et non cliquable (aucun href dans le SVG). Le
# graphe dit « ça hérite de là » sans pouvoir dire de quoi il hérite.
# La cause est le périmètre : la classe de base vit dans energyplugin/, hors
# INPUT. Élargir INPUT pour « réparer » ferait entrer tout le code amont dans la
# mesure et exploser le compte d'avertissements — exactement ce que le périmètre
# ci-dessus évite. Le graphe est incomplet par choix, pas par oubli.
#
# ATTENTION — le nombre d'avertissements dépend des générateurs de sortie
# activés. Sans aucun générateur, doxygen 1.9.8 émet des « not documented » sur
# des membres qui SONT documentés (constaté : 163 sans sortie, 113 avec
# HTML+XML, sur le même arbre). GENERATE_HTML et GENERATE_XML doivent donc
# rester à YES : c'est ce qui rend le comptage honnête. Ne pas les désactiver
# pour « aller plus vite ».
PROJECT_NAME = "etm-powersync-energy-plugin-etm"
PROJECT_BRIEF = "Moteur HEMS ETM — couche etm/ (arbitre, scheduler, adaptateurs)"
OUTPUT_DIRECTORY = doc-generated
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = French
# --- Périmètre -------------------------------------------------------------
# doc-generated/RULES.md est GÉNÉRÉ par tools/gen-rules.py, que gen-doc.sh appelle avant
# doxygen. Il porte une ancre {#LM-1105} par règle : c'est ce qui rend \rule{} résoluble.
# Les specs elles-mêmes restent HORS du périmètre — les y ajouter ferait entrer deux fois
# le même énoncé (une fois en prose, une fois dans l'index) et doublerait les ancres.
INPUT = energyplugin/etm doc-generated/RULES.md
RECURSIVE = YES
FILE_PATTERNS = *.h *.cpp *.md
# \rule{LM-1105} — un lien du COMMENTAIRE vers la règle. C'est le sens que \ref sert
# utilement : un lecteur dans relayrouter.cpp veut le texte de la règle. Le sens inverse —
# la page d'une règle liste ce qui l'implémente — est produit par gen-rules.py depuis les
# citations déjà présentes, sans qu'aucun commentaire ait à être réécrit.
#
# Les citations EXISTANTES restent en texte libre, délibérément : les convertir serait une
# réécriture de 250 commentaires pour un gain de navigation, et le générateur les voit déjà.
# Les nouvelles utilisent \rule{}.
ALIASES = "rule{1}=\ref \1 \"\1\""
# --- Extraction ------------------------------------------------------------
# EXTRACT_ALL = NO : sans cela doxygen documente tout d'office et n'avertit de
# rien. C'est le réglage qui rend la vérification possible.
EXTRACT_ALL = NO
EXTRACT_PRIVATE = NO
EXTRACT_STATIC = NO
EXTRACT_LOCAL_CLASSES = NO
# --- Avertissements --------------------------------------------------------
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = YES
# WARN_AS_ERROR reste NO : le job CI n'est pas bloquant tant que l'étape 3 de
# specs/spec_ecs.md n'est pas close (relayrouter.h et le noyau de calcul sont
# différés jusque-là). Passer à YES à ce moment, pas avant.
WARN_AS_ERROR = NO
QUIET = YES
WARN_LOGFILE = doc-generated/warnings.txt
# --- Sorties ---------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT = html
GENERATE_LATEX = NO
# XML : consommable par Breathe si le dépôt s'aligne un jour sur une chaîne
# Sphinx. Coût mesuré : ~180 ms, 73 fichiers, 1,5 Mo.
GENERATE_XML = YES
XML_OUTPUT = xml
# --- Préprocesseur ---------------------------------------------------------
# Neutralise les macros Qt (sinon Q_OBJECT est lu comme une déclaration) et
# définit ETM_ARBITRATOR, sans quoi les blocs #ifdef de l'arbitre seraient
# ignorés.
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = YES
PREDEFINED = Q_OBJECT= \
Q_GADGET= \
Q_PROPERTY(x)= \
Q_INVOKABLE= \
Q_DECLARE_METATYPE(x)= \
Q_ENUM(x)= \
Q_UNUSED(x)= \
ETM_ARBITRATOR \
"Q_DECL_OVERRIDE=override"
# --- Divers ----------------------------------------------------------------
JAVADOC_AUTOBRIEF = NO
QT_AUTOBRIEF = NO
MARKDOWN_SUPPORT = YES
OPTIMIZE_OUTPUT_FOR_C = NO
HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
# --- Graphes (Graphviz) ----------------------------------------------------
# graphviz est une dépendance de la CIBLE DOC, pas du build du paquet : rien à
# installer dans le conteneur build-cross-arm64, qui n'a que faire de dot.
# Debian/Ubuntu : apt install graphviz
HAVE_DOT = YES
# CALL_GRAPH / CALLER_GRAPH restent à NO, et ce n'est pas une question de coût.
# Le moteur est SIGNAL-DRIVEN : powerBalanceChanged → verifyOverloadProtection()
# n'est pas un appel mais une connexion Qt, invisible à l'analyse statique. Un
# graphe d'appel montrerait update() comme un point d'entrée orphelin et
# raterait le mécanisme principal de la couche L4. Un schéma faux vaut moins
# que pas de schéma.
CALL_GRAPH = NO
CALLER_GRAPH = NO
# Ce que dot apporte réellement ici : héritage, collaboration, inclusions.
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = NO
DIRECTORY_GRAPH = YES
TEMPLATE_RELATIONS = NO
# SVG : lisible à toute échelle et diffable, contrairement au PNG.
DOT_IMAGE_FORMAT = svg
INTERACTIVE_SVG = YES
# Au-delà, doxygen tronque plutôt que de produire un pavé illisible — un graphe
# qu'on ne peut pas lire ne documente rien.
DOT_GRAPH_MAX_NODES = 60
MAX_DOT_GRAPH_DEPTH = 3
DOT_CLEANUP = YES