tools: la classe « cadrage » — et « spécifiée seule » veut enfin dire quelque chose
Le premier usage de l'index avait donné 70 règles « spécifiée seule », un nombre qui ne voulait rien dire : il mélangeait « pas encore construite » avec « rien ne pourra jamais la citer ». Une règle NÉGATIVE — « un thermostat n'est PAS une charge », « aucune ThingClass n'est exposée » — s'applique par ABSENCE de code. Il n'existe aucune ligne à pointer, et la compter comme un trou de couverture invite à boucher un trou qui n'existe pas. tools/rules-noncode.txt déclare 22 règles de cadrage, chacune avec son motif : constats résolus, interdictions, structure du modèle, hors-périmètre, conventions de nommage, justifications, et un contrat d'affichage client. §10, §14, ECS-5xx et ECS-6xx n'y sont PAS : ils attendent d'être construits, et c'est ce que « spécifiée seule » doit continuer de dire. Résultat : 41 « spécifiée seule » au lieu de 70, dont 27 en territoire non construit. Restent ~14 règles en territoire livré que rien ne cite — un nombre qu'on peut lire une par une. LE GARDE-FOU, éprouvé et non supposé : le générateur CASSE si une règle de cadrage acquiert une citation de code ou de test. Vérifié en ajoutant une citation de LM-202 dans un en-tête — RC=1, la règle nommée, le fichier et la ligne donnés. Même mécanique que le refus de redéfinir un numéro retiré. Et la réparation est TOUJOURS la même : retirer la ligne. Deux cas la déclenchent — la règle a été implémentée depuis, ou elle est citée pour expliquer une absence — et dans les deux « citée par le code » est plus vrai que « cadrage ». La liste ne peut donc que RÉTRÉCIR : elle ne sait pas mentir dans le sens qui compte. C'est ce qui rend une liste tenue à la main acceptable ici. ci-quality 3/3. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015F7G5VeaPVSMeVNjiGj36p
This commit is contained in:
parent
ddaeafbc05
commit
b64a0e4c90
@ -25,6 +25,7 @@ RACINE = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
SORTIE = os.path.join(RACINE, 'doc-generated', 'RULES.md')
|
||||
EXTERNES = os.path.join(RACINE, 'tools', 'rules-external.txt')
|
||||
RETIRES = os.path.join(RACINE, 'tools', 'rules-retired.txt')
|
||||
CADRAGE = os.path.join(RACINE, 'tools', 'rules-noncode.txt')
|
||||
|
||||
# --- Grammaire ---------------------------------------------------------------------
|
||||
#
|
||||
@ -112,11 +113,19 @@ def scanner():
|
||||
return defs, rows, cites
|
||||
|
||||
|
||||
def etat(c):
|
||||
"""DÉRIVÉ de l'endroit où l'identifiant apparaît — aucune tenue à la main."""
|
||||
def etat(c, estCadrage=False):
|
||||
"""DÉRIVÉ de l'endroit où l'identifiant apparaît — aucune tenue à la main.
|
||||
|
||||
Seule exception : « cadrage », déclaré dans tools/rules-noncode.txt. Ce n'est pas un
|
||||
état de preuve mais une NATURE — une règle négative s'applique par absence de code, et
|
||||
la compter comme un trou de couverture invite à boucher un trou qui n'existe pas. Le
|
||||
garde-fou vit dans main() : une règle de cadrage citée par du code fait ÉCHOUER la
|
||||
génération, parce que la classification est alors périmée ou inutile.
|
||||
"""
|
||||
if c.get('releve'): return 'vérifiée sur machine'
|
||||
if c.get('test'): return 'citée par un test'
|
||||
if c.get('code'): return 'citée par le code'
|
||||
if estCadrage: return 'cadrage (aucun porteur attendu)'
|
||||
return 'spécifiée seule'
|
||||
|
||||
|
||||
@ -133,6 +142,7 @@ def main():
|
||||
|
||||
externes = lire(EXTERNES)
|
||||
retires = lire(RETIRES)
|
||||
cadrage = lire(CADRAGE)
|
||||
|
||||
defs, rows, cites = scanner()
|
||||
# Un numéro RETIRÉ est connu : il n'est ni orphelin ni à redéfinir.
|
||||
@ -157,7 +167,7 @@ def main():
|
||||
'> est nommé à un endroit, pas qu\'il y est éprouvé. Le lecteur juge sur pièce —\n'
|
||||
'> c\'est délibéré : un ✅ automatique mentirait comme les tables qu\'il remplace.\n')
|
||||
|
||||
par_etat = collections.Counter(etat(cites[r]) for r in defs)
|
||||
par_etat = collections.Counter(etat(cites[r], r in cadrage) for r in defs)
|
||||
out.append('\n| | |\n|---|---|')
|
||||
out.append('| Règles définies | **%d** |' % len(defs))
|
||||
for e, n in par_etat.most_common():
|
||||
@ -183,7 +193,9 @@ def main():
|
||||
c = cites[rid]
|
||||
out.append('\n## %s {#%s}\n' % (rid, rid))
|
||||
out.append('%s\n' % enonce)
|
||||
out.append('**Domicile** : `%s:%d` · **État** : %s\n' % (rel(f), i, etat(c)))
|
||||
out.append('**Domicile** : `%s:%d` · **État** : %s\n' % (rel(f), i, etat(c, rid in cadrage)))
|
||||
if rid in cadrage and cadrage[rid]:
|
||||
out.append('- *Cadrage* : %s' % cadrage[rid][0])
|
||||
for fam, titre in (('code', 'Implémentée — cité par'),
|
||||
('test', 'Éprouvée — cité par'),
|
||||
('releve', 'Machine — cité par'),
|
||||
@ -205,6 +217,21 @@ def main():
|
||||
pb.append('%d identifiant(s) présent(s) UNIQUEMENT en ligne de tableau : une étiquette '
|
||||
'de trois mots n\'est pas un énoncé, et ne peut pas valoir domicile :\n %s'
|
||||
% (len(sans_enonce), ' '.join(sans_enonce)))
|
||||
# Une règle de CADRAGE citée par du code : la classification ne tient plus. Soit la règle
|
||||
# a été implémentée depuis, soit elle est citée pour expliquer une absence — dans les deux
|
||||
# cas elle a désormais un porteur lisible, et « citée par le code » est plus vrai que
|
||||
# « cadrage ». La réparation est toujours la même : retirer la ligne. La liste ne peut donc
|
||||
# que rétrécir, elle ne sait pas mentir dans le sens qui compte.
|
||||
cadrage_porte = sorted(r for r in cadrage
|
||||
if cites.get(r, {}).get('code') or cites.get(r, {}).get('test'))
|
||||
if cadrage_porte:
|
||||
pb.append('%d règle(s) déclarée(s) CADRAGE mais citée(s) par du code ou un test — la '
|
||||
'classification ne tient plus, RETIRER la ligne de tools/rules-noncode.txt :'
|
||||
'\n%s' % (len(cadrage_porte), '\n'.join(
|
||||
' %-14s cité par %s' % (r, ', '.join(
|
||||
'`%s`' % x for fam in ('code', 'test')
|
||||
for x in cites[r].get(fam, [])))
|
||||
for r in cadrage_porte)))
|
||||
if ressuscites:
|
||||
pb.append('%d numéro(s) RETIRÉ(S) redéfini(s) — un identifiant retiré ne se réattribue '
|
||||
'pas : la même référence désignerait deux exigences selon la date de lecture :'
|
||||
|
||||
62
tools/rules-noncode.txt
Normal file
62
tools/rules-noncode.txt
Normal file
@ -0,0 +1,62 @@
|
||||
# Règles de CADRAGE — celles dont on n'ATTEND aucun porteur de code.
|
||||
#
|
||||
# POURQUOI CETTE LISTE. Sans elle, « spécifiée seule » est un nombre qui ne veut rien
|
||||
# dire : il mélange « pas encore construite » avec « rien ne pourra jamais la citer ».
|
||||
# Une règle NÉGATIVE — « un thermostat n'est PAS une charge », « aucune ThingClass n'est
|
||||
# exposée » — s'applique par ABSENCE de code : il n'existe aucune ligne à pointer. La
|
||||
# compter comme un trou de couverture invite à boucher un trou qui n'existe pas.
|
||||
#
|
||||
# CE QUE LA LISTE NE DIT PAS. Elle ne dit pas « aucun code ne peut la citer », mais
|
||||
# « on n'attend pas de porteur ». La nuance décide du garde-fou ci-dessous.
|
||||
#
|
||||
# ── GARDE-FOU : le générateur CASSE si une règle d'ici acquiert une citation de code ──
|
||||
#
|
||||
# C'est ce qui empêche une liste tenue à la main de dériver — même mécanique que le refus
|
||||
# de redéfinir un numéro retiré. Deux cas la déclenchent, et la réparation est la même :
|
||||
#
|
||||
# · la règle a été implémentée depuis → la classification est PÉRIMÉE ;
|
||||
# · la règle est citée pour expliquer une ABSENCE (« LM-202 : un thermostat n'est pas
|
||||
# une charge, donc rien ici ») → la citation est légitime, et la règle a désormais
|
||||
# un porteur lisible.
|
||||
#
|
||||
# Dans les deux cas : RETIRER la ligne. L'index la comptera « citée par le code », ce qui
|
||||
# est vrai et plus utile que « cadrage ». La liste ne peut donc que RÉTRÉCIR — elle ne
|
||||
# sait pas mentir dans le sens qui compte.
|
||||
#
|
||||
# NE PAS y mettre une règle simplement « pas encore faite ». §10, §14, ECS-5xx et ECS-6xx
|
||||
# n'y sont pas : ils sont en attente de construction, et c'est ce que « spécifiée seule »
|
||||
# doit continuer de dire.
|
||||
#
|
||||
# format : IDENTIFIANT<TAB>motif
|
||||
|
||||
# — Cadre du chantier ECS : constats résolus, frontières tenues par absence, hors périmètre
|
||||
ECS-001 constat résolu, négatif — reconfirmé contre le libnymea du build
|
||||
ECS-002 négatif : ni integration-plugin, ni dépôt, ni ThingClass
|
||||
ECS-003 découpage documentaire, pas une exigence de comportement
|
||||
ECS-007 interdiction — aucune couche ECS ne décide de sa part du surplus
|
||||
ECS-008 contrat d'un AUTRE produit (optimiseur ETM consomme, l'ECS publie)
|
||||
ECS-203 CLOS : aucune ThingClass exposée, donc aucune interface à implémenter
|
||||
|
||||
# — §1 : ce que le modèle EST, avant tout mécanisme
|
||||
LM-100 structure du modèle — deux couches indépendantes
|
||||
LM-101 structure du modèle — une charge choisit un domaine et un mécanisme
|
||||
LM-102 négatif : aucune des deux couches ne répartit de budget
|
||||
|
||||
# — Négatifs et hors moule
|
||||
LM-202 négatif : un thermostat de zone n'est PAS une charge
|
||||
LM-403 négatif : le mode est une sortie, jamais une entrée
|
||||
LM-405 hors périmètre : la décomposition en facettes vit côté ems
|
||||
LM-406 négatif : sans chauffe-eau distinct, il n'y a pas de charge à créer
|
||||
LM-700 hors moule : la batterie n'est pas une charge à rang (renvoi §14)
|
||||
LM-701 hors moule : le smarthome ne se module pas en watts
|
||||
|
||||
# — §5/§6 : définitions et conventions de nommage
|
||||
LM-500 définition — un groupe est une clé de tri, jamais un détenteur de budget
|
||||
LM-503 définition — ce qu'un rang n'est pas
|
||||
LM-504 convention de nommage du domaine hvac
|
||||
LM-601 souhait de renommage, pas une exigence
|
||||
|
||||
# — Justifications et contrats clients
|
||||
LM-1204 justification d'un ordre de travail, pas une exigence
|
||||
LM-1205 constat — la machinerie d'échéance existe déjà
|
||||
LM-1209-d contrat d'AFFICHAGE côté client ; le moteur n'a rien à porter
|
||||
Loading…
x
Reference in New Issue
Block a user