Les planches d’ancrage · série II · feuille 14 / 19

L’armure 15D

L'ARMURE 15D — quinze fentes, une mesure, et la chaîne rompue avant le premier envoi

Planche 14 · L’armure 15D
10 pièces · 2 bâties · 4 partielles · 4 absentes · 0 non établies
Planche 14 — L’armure 15D

ouvrir la planche en plein écran → · 10 pièces · 22 traverses · 12 marges

La thèse une ligne, écrite dans la matière

L'armure n'est pas l'organe le plus durci du dépôt : c'est un organe DURCI MAIS DÉBRANCHÉ — son pont frontend→backend ne peut pas se déclencher (trois ruptures indépendantes), sa garde de signature n'a aucun appelant, son régime v2 keyé n'existe qu'en test, et son unique sortie vers l'économie se déclare elle-même inactive ; ce qui tient vraiment, c'est le refus : le registre fail-close et la contrainte de base qui interdit à l'armure d'être autoritative.

Les marges 12 arbitrages ouverts, entiers
  • ⚑ LA RÉFUTATION PRINCIPALE, en une phrase : la vague annonçait sept pièces BÂTIES ; au commit 8addf1c94, DEUX seulement le restent (le registre durable et la contrainte de base), deux passent à PARTIEL (le schéma, la trajectoire), une à PARTIEL par son producteur (l'exposition de menace), une à PARTIEL par son régime (l'engagement : v1 seul vit), et le PONT — la pièce dont dépendent toutes les autres — passe à ABSENT.
  • ⚑ TROIS RUPTURES INDÉPENDANTES sur le même pont, chacune suffisante à elle seule : un champ absent du contrat de bus (`tokenId`), une fonction d'entrée sans appelant (`updatePoint0`), et un endpoint de mint qui lève 503 inconditionnellement. Les réparer une à une ne réveille rien ; il faut les trois. C'est le genre de panne que seul un parcours de bout en bout révèle — aucun des deux côtés n'est en faute isolément.
  • ⚑ UN GABARIT MENTEUR, À L'INVERSE DE D'HABITUDE : l'en-tête d'`armure_sentinel.py:6-8` annonce « Ici la garde devient vivante » pour corriger un défaut nommé (« `snapshot_matches` n'avait AUCUN appel runtime »). Le fichier a été écrit, le branchement non. Le défaut est donc intact — mais désormais couvert par une phrase qui dit l'avoir réparé. C'est pire que le défaut nu.
  • ⚑ TROIS FICHES DE CONSEIL AFFIRMENT UN APPEL QUI N'EXISTE PAS : conseil_3.json:89, conseil_6.json:54 et conseil_9.json:58 (data/urbanisme/projets-services/protocol-999-protocole-de-resistance/) écrivent « `armure_sentinel.guard` appelée depuis `armure.py:96-100` », et conseil_3 en fait « le seul espace de ce lieu à la fois bâti, appelé et monté ». Les lignes 96-100 d'armure.py ne contiennent pas cet appel ; `guard` n'a aucun appelant. Trois conseils ont convergé sur la même erreur — probablement en se citant.
  • CHIFFRES DE DOCS QUI NE PASSENT PLUS : `frontend/etat-technique.html:130,502,512` et `docs/cartographie-proprietaire.json:1557-1559` annoncent « armure.py, 166 lignes » (c'est 208 au commit), « monté à main.py:1491 » (c'est 1957), « le pont frontend→backend fonctionne de bout en bout » (il ne part jamais) et « `armure_store` retient → `aip_signing` estampe » (plus personne n'écrit le store). À noter : etat-technique.html:130 contient aussi, dans la MÊME page, le constat juste — « Le ROUTEUR tient, le PONT ne tient pas ». La page se contredit par ses deux bouts ; le bout juste est celui-là.
  • CE QUE LA THÈSE D'ORIGINE AVAIT RAISON DE DIRE, et que je confirme pièce en main : les quinze dimensions dérivent bien d'UN SEUL scalaire — `FractalExpansion.js:188-196` pondère `harmony` par φ (`Math.pow(PHI_INV, (DIMENSIONS - d) / DIMENSIONS)`) pour fabriquer quinze forces. Et la fréquence EST jetée à la frontière Python : `fractal_dimensions.py:60-68` (`commitment_vector`) ne retient que `strength`, écartant explicitement fréquence et cohérence comme « dérivables ». Quinze fentes, une mesure — c'est exact.
  • CE QUI TIENT VRAIMENT, ET QU'IL NE FAUT PAS DÉGRADER EN LE REDESSINANT : le registre (verrou advisory, rejeu à deux refus distincts, commit avant retour, 503 nommé) et la contrainte `ck_armure_observation_non_authoritative_class`. C'est la doctrine « fail-close sur ce qui engage » appliquée correctement. Le reste du domaine est un refus honnête (aip_signing) ou un organe débranché — jamais une fausse confirmation. Sur ce point précis, l'armure est exemplaire : elle n'a jamais menti en répondant « créé » ; elle s'est tue.
  • DÉCISION QUI ATTEND JONATHAN — nº1 : réveiller le pont, ou l'assumer dormant ? Le geste minimal est de trois lignes (ajouter `tokenId` au payload de mint OU assouplir la garde FractalExpansion.js:882, et donner un appelant à `updatePoint0`) — mais il ouvre un robinet d'écritures en base derrière une identité, sur un mint actuellement fail-close par décision. Ne pas le faire sans trancher le mint d'abord.
  • DÉCISION nº2 : la custody de la clé v2. Le code HMAC est bien écrit (séparation de domaine armure_15d.py:89-90, sous-clé dérivée pour l'aveuglement l.161, `hmac.compare_digest` l.237, refus des clés < 16 octets l.103). Il attend UNE décision : qui détient la clé par membre, et comment elle tourne. Tant qu'elle n'est pas prise, le dépôt scelle en SHA-256 nu — c'est-à-dire en valeur recomposable par quiconque connaît les identifiants publics.
  • DÉCISION nº3 : trancher les trois tables de 15. La plus dangereuse des trois dérives parce qu'elle est SILENCIEUSE et que le troisième vocabulaire (dimensional-armor.js) est CHARGÉ en production. Coût faible aujourd'hui : faire importer `dimensions_15.py` par `antenna.py` (recopie identique, migration triviale) et nommer autrement les quinze de `spiderweb.py` et de `dimensional-armor.js`, qui ne sont pas les mêmes objets.
  • DÉCISION nº4 : les trois lecteurs orphelins d'`armure_store`. Le store a été correctement déclassé, mais `verite.py:731-741` en tire une cote d'identité permanente « absente » pour tout usager, et `passage_decision.ArmureStorePort` reste un port qui lit un dictionnaire de processus. Il faut soit les repointer sur le registre durable, soit les retirer. Attention au piège que le code nomme lui-même (passage_decision.py:1221-1223) : NE PAS se contenter de changer l'étiquette `MEMOIRE` en `DURABLE`.
  • PIÈGE POUR LA PROCHAINE SESSION : `verify_chain` est écrite, testée et bonne. La tentation sera de l'appeler depuis le routeur pour « compléter la trajectoire ». Mais rien ne LIT les versions historiques (`aget_current_owner_observation` ne rend que la tête) — il faudrait d'abord un lecteur de la suite ordonnée. Brancher `verify_chain` sur une liste vide rendrait `{valid: True, length: 0}` : une planche verte sur un organe non mesuré.
Les blancs déclarés ce que la mesure n’a pas pu voir

Ce que cette collecte N'A PAS pu voir. (1) AUCUNE BASE, AUCUNE PROD : lecture seule, par consigne. Donc NON ÉTABLI — que la migration v82_293 soit appliquée sur le VPS (CLAUDE.md mesure la prod au 2026-08-08 à `v82_260_atom_positions`, soit 33 révisions en retard de la table d'observations d'armure) ; que la table `armure_owner_observation_versions` contienne ne serait-ce qu'une ligne ; qu'un `identities.id` existe pour un usager authentifié (la FK `fk_armure_observation_owner` restreint sur `identities`, et un usager absent de cette table ferait échouer l'insertion en 503 — c'est la même famille de défaut que le `owner_principal_id` corrigé au commit dfcb8a3ec, mais je ne l'ai PAS vérifiée). (2) AUCUN SERVEUR LANCÉ, AUCUN NAVIGATEUR : je n'ai pas chargé une page, donc l'enchaînement « module chargé → bus → POST » est établi par LECTURE DE CODE, pas par observation. Un script inline d'une page HTML particulière pourrait appeler `ATOMArmureBridge.pushDimensions` ou `updatePoint0` d'une façon que mes motifs de recherche ont manquée — j'ai cherché `ATOMArmureBridge`, `pushDimensions`, `refinePoint0`, `updatePoint0`, `.aspirate(`, `.breathe(` et `FractalExpansion` sur frontend/ et agents/, et n'ai trouvé que des tests ; je n'ai pas lu les 122 pages HTML une à une. (3) AUCUN TEST LANCÉ : je n'ai exécuté aucune garde, aucun banc. Toute mention de test dans ce rendu décrit un FICHIER LU, jamais une sortie verte. (4) PÉRIMÈTRE DES « ZÉRO APPELANT » : chaque « 0 appelant » de ce rendu a été mesuré par `git grep` sur l'ARBRE SUIVI PAR GIT, au commit 8addf1c94, en excluant `backend/tests/`, `**/__tests__/**`, `docs/`, `leaves/`, `leaf-flows/` et `frontend/etat-technique.html` — et en INCLUANT les deux arbres de `backend/` (`backend/app/`, 1 627 fichiers, et les ~278 `.py` hors `app/` sur 29 racines), plus `frontend/`, `agents/`, `hf-atom-tools/`, `scripts/`. `archives/` et `transit/` sont exclus comme code de référence non actif. (5) LE COMMIT, PAS L'ARBRE : tous les chiffres et toutes les lignes citées viennent de `git show HEAD:<fichier>`. L'arbre de travail porte 60+ fichiers modifiés non commités (dont `main.py`) : une mesure sur l'arbre pourrait différer. (6) LES 12 `backend/verticals/` ACTIFS sont des bytecode-squatters non versionnés, donc invisibles à `git grep` : si un appelant d'armure y vit, je ne l'ai pas vu. (7) LES BUNDLES CODEX ET LES WORKTREES hors dépôt n'ont pas été fouillés.

ne pas dessiner

  • NE PAS dessiner l'armure comme un CHIFFREMENT ni comme un BOUCLIER. C'est un engagement (hash) sur des attaches d'identité ; rien n'est déchiffrable, rien ne bloque. Le code le dit deux fois : armure_15d.py:137-141 (« v2 N'ATTEINT PAS prouver-sans-révéler ») et armure_sentinel.py:15-17 (« ON EXPOSE, ON NE FRAPPE PAS »).
  • NE PAS dessiner une arête armure→économie. Elle n'existe pas : le seul pont se déclare inactif et n'est chargé par aucune page (armor-economy-bridge.js:6-11). Les multiplicateurs ×1.0 à ×5.0 et les « 30 UR/jour » de son en-tête sont de la doctrine résiduelle dans un module mort — les reproduire sur une planche leur donnerait une existence qu'ils n'ont pas.
  • NE PAS dessiner le pont et le registre du MÊME TRAIT. Le registre est bâti et fail-close ; le pont qui devrait l'alimenter ne peut pas partir. Les montrer semblables serait exactement le mensonge que la devise interdit.
  • NE PAS dessiner « v1/v2 » comme deux régimes disponibles. Un seul vit (v1 nu). Le v2 est du code correct sans porteur de clé — si on le dessine, il faut l'ombrer et nommer la décision de custody qui manque.
  • NE PAS redessiner les 7 cosmogrammes existants (frontend/planches/*.svg), ni le plan VISION de docs/presentation/CARTE-CONTENU-grand-cosmogramme.md.
  • NE PAS dessiner un verdict sur la production. Aucune base n'a été interrogée dans cette collecte : la table d'observations peut exister ou non sur le VPS, et je n'en sais rien.
  • NE PAS dessiner « 15 dimensions » au singulier. Il y en a trois tables qui ne se parlent pas, dont deux vivantes côte à côte en production (dimensions_15.py et dimensional-armor.js). Une planche honnête montre TROIS tables et l'absence de pont entre elles.
Les traverses 22 relations, de source à source
nft-soul-manager.js (mint)
alimente
→FractalExpansion.aspirate()FractalExpansion.js:882 exige `data.tokenId` ; nft-soul-manager.js:375-381 publie `{serial, userId, stage}` ; antenna.py:570 lève 503 inconditionnel (l.53-65)
meta-map-manager.updatePoint0()
alimente
→FractalExpansion.aspirate()meta-map-manager.js:289,314 ; 0 appelant de production de updatePoint0 (seul appel : __tests__/unit/canon-messagebus-wiring.test.js:246)
FractalExpansion.js
alimente
→armure-bridge.jsFractalExpansion.js:173 (seul publieur de `fractal.agent.aspirated`) ; armure-bridge.js:191 (abonné) — l'abonnement est bâti, l'émission impossible
aura-display.js
alimente
→armure-bridge.js (D5, la seule mesure réelle)aura-display.js:344 publie `aura.updated` ; armure-bridge.js:193-196 met en cache ; mais la valeur ne sort qu'avec pushDimensions, jamais appelé
armure-bridge.js
alimente
→POST /api/v2/armure/dimensionsarmure-bridge.js:121,126-160 ; module chargé governance-init.js:392 ; routeur monté main.py:1957 — code des deux côtés bâti, déclencheur jamais atteint
routeur armure
produit
→armure_15d.compute_armure_snapshot (v1 nu)backend/app/routers/armure.py:93 (key=None → armure_15d.py:155-156)
armure_15d v2 (HMAC keyé + aveuglement)
produit
→tout appelant de productionarmure_15d.py:121-162 ; 0 appel keyé hors backend/tests/test_atom_pay.py:532-599
armure_15d.snapshot_matches
autorise
→armure_sentinel.guardarmure_sentinel.py:136 — le seul appelant existe, mais guard lui-même n'est appelé par personne
armure_sentinel.guard
gouverne
→runtime (toute route, tout service)0 appelant dans le dépôt hors tests ; armure.py n'appelle que armure_fingerprint (l.94) et expose_threat (l.142)
routeur armure
alimente
→armure_owner_observation_registryarmure.py:99-118 → registry:343 (arecord_owner_observation), commit avant retour registry:588
registre
produit
→armure_trajectory.extend_chain / genesis_linkregistry:32,470,472
registre (chaîne écrite)
gouverne
→armure_trajectory.verify_chainarmure_trajectory.py:91 ; 0 appelant de production dans tout le dépôt
base de données
gouverne
→classe de preuve de l'armuremodels/armure_owner_observation.py:90-94 (CHECK evidence_class='owner_submitted') ; migration v82_293
routeur armure
produit
→immune.threat.detectedarmure.py:129-150 ; conditionné à guard_verdict=='threat', inatteignable sans première observation ; best-effort sous except (l.148-150)
immune.threat.detected
alimente
→QGEngineConnector (survival/deduction/incidents)qg_engine_connector.py:98-102 ; abonnement effectué au démarrage main.py:604-606
armure_store
autorise
→aip_signing (signature AIP)aip_signing.py:155,174-180 ; 0 écrivain de armure_store → refus systématique ArmureSnapshotUnavailable
armure_store
alimente
→verite.py (cote d'identité de l'enquête)verite.py:731-741 → identity_provenance(armure_present=False) pour tout usager
armure_store
autorise
→passage_decision.ArmureStorePortpassage_decision.py:1228-1235 — provenance=MEMOIRE même garni ; identite_ancre() rend id() d'un dict
dimensions_15.py (schéma canon)
gouverne
→antenna.py::DIMENSIONS_15antenna.py:154-170 recopie à l'identique ; 0 import de dimensions_15 dans antenna.py
dimensions_15.py (schéma canon)
gouverne
→spiderweb.py::DIMENSIONS_15spiderweb.py:103-107 — 15 autres noms, 0 nom commun
dimensions_15.py (schéma canon)
gouverne
→frontend/js/dimensional-armor.js::DIMENSIONSdimensional-armor.js:49-64 — troisième vocabulaire, module CHARGÉ (governance-init.js:587)
armure
alimente
→économie (UR, trésorerie, forge)armor-economy-bridge.js:6-11 se déclare inactif et n'est dans aucun tableau de scripts ; D7/D9 (dimensions_15.py:32,34) sont des étiquettes, pas des soldes
La nomenclature 10 pièces, chacune avec sa source
1Le registre durable des observations d'armure625 lignes ; verrou `pg_advisory_xact_lock` par propriétaire (registry:385-394) ; rejeu par nonce avec DEUX refus distincts (corps vs effet dérivé, l.429-437) ; commit AVANT tout retour (l.588) ; 503 nommé `armure_observation_persistence_unavailable` si indisponible (armure.py:110-115, 182-187) ; 10 contraintes CHECK sur la table des versions ; migration dans la chaîne (v82_292 → v82_293 → v82_294)backend/app/services/armure_owner_observation_registry.py (625 L) ; backend/app/models/armure_owner_observation.py ; backend/alembic/versions/v82_293_armure_owner_observations.py · confirmé dans le codeBÂTI et fail-close — c'est la meilleure pièce du domaine, et je la confirme. MAIS elle n'a AUCUN PRODUCTEUR VIVANT : son unique entrée est POST /api/v2/armure/dimensions, dont la pièce « pont » établit qu'aucun client chargé ne l'appelle. Le registre est atteignable par un appel authentifié direct, pas par le système livré. Divergence doc↔code à noter : la genèse de chaîne est ancrée sur `owner_id` (registry:470, `genesis_link(str(owner))`) alors qu'armure_trajectory.py:41 annonce une ancre sur l'âme (`nft_soul_id`).
2⚑ LA BASE INTERDIT À L'ARMURE D'ÊTRE AUTORITATIVE1 contrainte CHECK qui fige DEUX colonnes : canonicalization_schema = 'atom.armure.owner-observation.v1' ET evidence_class = 'owner_submitted' ; `authoritative: False` écrit EN DUR dans les deux réponses du routeurbackend/app/models/armure_owner_observation.py:90-94 (ck_armure_observation_non_authoritative_class) ; même CHECK dans la migration v82_293 ; routeur backend/app/routers/armure.py:159 et :205 · confirmé dans le codeRIEN sur le plan du code — c'est la pièce la plus honnête du domaine et je la confirme sans la dégrader. Elle rend structurellement impossible qu'une observation déposée par son propriétaire devienne une attestation. Un seul caveat de PORTÉE, pas d'état : la contrainte vit dans la migration v82_293, et CLAUDE.md mesure la prod au 2026-08-08 à la révision `v82_260_atom_positions`. Je n'ai interrogé aucune base (lecture seule, aucune prod) : que la table existe en production est NON ÉTABLI.
3Le schéma canonique des 15 dimensions15 dimensions = 5 triades × 3 (len(DIMENSIONS_15)==15, index 1..15 contigus, garde is_valid_schema() l.73) — RE-VÉRIFIÉ au commit. MAIS 4 emplacements portent une table « 15 dimensions », pour 3 vocabulaires incompatiblesbackend/app/services/dimensions_15.py:25-44 ; importé par armure_15d.py:209 et fractal_dimensions.py:29 · confirmé dans le codeLa prétention de « source unique » (en-tête l.11-15) est fausse au commit : antenna.py:154-170 RECOPIE la table à l'identique sans jamais l'importer (0 import de dimensions_15 dans antenna.py) ; spiderweb.py:103-107 porte 15 autres noms (Physical, Emotional… Cosmic) ; frontend/js/dimensional-armor.js:49-64 un troisième (Électrique, Physique, Réseau…) — et ce dernier EST chargé en production (governance-init.js:587). Zéro nom commun entre les trois vocabulaires. « Dimension 7 » désigne financial, Financial et Décision selon l'organe.
4L'engagement cryptographique — ce que les docs appellent « l'encryption »1 appelant de production de `compute_armure_snapshot`, avec key=None → régime v1 SHA-256 NU. Régime v2 (HMAC-SHA256 domaine-séparé + aveuglement) : 0 appelant de production dans tout le dépôt ; 30+ appels, tous dans backend/tests/test_atom_pay.py:532-599backend/app/services/armure_15d.py:37,121-162 ; appelé une seule fois en production à backend/app/routers/armure.py:93 · confirmé dans le codeTrois choses. (1) Le seul régime VIVANT est le v1, que le module lui-même qualifie de « TRAÇABLE — qui connaît les ids publics recompose le hash » et « NON recommandé » (l.125-128) : le routeur appelle `compute_armure_snapshot(bindings)` sans clé. (2) Le v2 n'a ni porteur de clé, ni custody, ni rotation — rien ne lit ni ne fabrique une clé d'armure dans le dépôt ; `new_blinding()` (l.75) et `stratified_snapshot()` (l.178) ont ZÉRO appelant hors tests. (3) Ce n'est PAS un chiffrement : rien n'est déchiffrable, c'est un engagement (hash) ; le module l'avoue (l.137-141 : « CE QUE v2 N'ATTEINT PAS : prouver-sans-révéler »). Dérive mineure mais réelle : `_ARMURE_VERSION = "15d.v1"` (l.37) entre dans le canonique y compris en régime v2 — le payload scellé dit « v1 » dans les deux régimes.
5La trajectoire chaînéeÉCRITE : `previous_chain_digest` + `chain_digest`, NOT NULL, CHECK hex64. VÉRIFIÉE : `verify_chain` = 0 appelant dans tout le dépôt hors backend/tests/ et hors archives/ (les occurrences d'`archives/backend-reference/` sont d'autres fonctions, code de référence non actif). `next_step` et `step_from_store` : 0 appelant de productionbackend/app/services/armure_trajectory.py:40-47,91-113 ; écrite par registry:470-472 ; colonnes models/armure_owner_observation.py:53-54 + CHECK l.83-89 · confirmé dans le codeLa chaîne est écrite durablement, elle n'est JAMAIS RELUE. `verify_chain` (armure_trajectory.py:91) — la fonction qui dirait « maillon rompu » ou « maillon forgé », c'est-à-dire exactement « la discontinuité de la personne » que le fichier donne pour sa raison d'être (l.11-19) — n'est appelée par aucune route, aucun service, aucun ordonnanceur. Aucun endpoint ne rend une trajectoire. Donc : durable, oui ; vérifiable, non ; vérifiée, jamais.
6L'exposition de menace1 consommateur réellement abonné au démarrage (`QGEngineConnector.get_instance().connect_bus()`, main.py:605) routant `immune.threat.detected` vers 3 moteurs (survival/deduction/incidents) ; 1 producteur, conditionné à `guard_verdict == "threat"`producteur backend/app/routers/armure.py:129-150 ; organe backend/app/services/armure_sentinel.py:148-180 ; consommateur backend/app/services/qg_engine_connector.py:98-102, abonné au démarrage via backend/app/main.py:604-606 · confirmé dans le codeLe CONSOMMATEUR est bien monté — je confirme cette moitié. Le PRODUCTEUR est inatteignable : `guard_verdict` ne vaut « threat » qu'après une observation PRÉCÉDENTE puis une perte/substitution du noyau (armure_sentinel.py:78-83) ; avec zéro producteur de pont, il n'y a jamais de première observation, donc jamais de seconde, donc jamais de verdict de menace. Deuxième réserve, avouée dans le code lui-même (armure.py:130-133) : l'exposition est best-effort sous `except Exception` (l.148-150) — aucune outbox, donc une menace perdue après le commit n'est jamais réémise.
7⚑ Le pont JS→Python des dimensions vivantes0 publication de `fractal.agent.aspirated` possible en production ; 3 ruptures indépendantes ; 0 appelant externe de `aspirate()` / `breathe()` dans tout le dépôt git hors tests (arbres fouillés : frontend/, agents/, backend/app/, backend/ hors app/, hf-atom-tools/, scripts/)frontend/js/FractalExpansion.js:145,173,881-884,893-899 ; frontend/js/nft-soul-manager.js:352-357,375-381 ; frontend/js/meta-map-manager.js:289,314 ; backend/app/routers/antenna.py:53-65,567-570 · confirmé dans le codeLES DEUX CÔTÉS SONT BÂTIS ET CHARGÉS — armure-bridge.js (governance-init.js:392, sur les 28 pages de GOVERNANCE_PAGES l.50-66), FractalExpansion.js (l.359), routeur monté (main.py:1957) — mais l'ÉVÉNEMENT QUI LES RELIE NE PART JAMAIS. Seul publieur de `fractal.agent.aspirated` = FractalExpansion.js:173, dans `aspirate()` (l.145). `aspirate()` n'a AUCUN appelant externe ; ses deux seules entrées sont des abonnements, et les deux sont rompues : (a) `nft.soul.minted` — FractalExpansion.js:882 exige `data.tokenId`, or le seul publieur (nft-soul-manager.js:375-381) envoie `{serial, userId, stage}`, SANS `tokenId` → la garde n'est jamais vraie ; et de toute façon le mint ne réussit jamais, antenna.py:570 appelle `_antenna_nft_mutation_not_active()` qui lève 503 INCONDITIONNELLEMENT (l.53-65) et nft-soul-manager.js:352-357 re-lève sans repli ; (b) `metamap.point0.updated` — seul publieur meta-map-manager.js:314, à l'intérieur de `updatePoint0()` (l.289), qui a ZÉRO appelant de production : le seul appel du dépôt est un test unitaire (frontend/js/__tests__/unit/canon-messagebus-wiring.test.js:246). Conséquence : 0 POST /api/v2/armure/dimensions depuis le frontend livré. La seule mesure RÉELLE du système (cohérence d'aura → D5) arrive bien dans le cache du pont (armure-bridge.js:193-196, publiée par aura-display.js:344, module chargé l.928) et n'en sort jamais.
8⚑ La garde de signature — l'organe qui VÉRIFIE un hash revendiqué`snapshot_matches` : 1 appelant, armure_sentinel.py:136. `armure_sentinel.guard()` : 0 appelant dans tout le dépôt git hors tests (arbres fouillés : backend/app/, backend/ hors app/ (29 racines), hf-atom-tools/, scripts/, agents/, frontend/)backend/app/services/armure_15d.py:222-237 (snapshot_matches) ; backend/app/services/armure_sentinel.py:6-8,123-145 (guard) · confirmé dans le codeL'en-tête d'armure_sentinel.py:6-8 annonce : « `snapshot_matches` n'avait AUCUN appel runtime — l'armure ne gardait rien. Ici la garde devient vivante. » C'EST FAUX AU COMMIT : le fichier a été écrit, mais `guard()` n'est appelé par personne. Le routeur n'appelle que `armure_fingerprint` (armure.py:94) et `expose_threat` (l.142) — jamais `guard`. Donc aucun chemin runtime ne compare jamais une armure PRÉSENTÉE au miroir vivant ; ce qui est câblé (classify_observation, registry:478) compare des cardinalités et deux digests déjà stockés, jamais une revendication d'un porteur. ⚑ Trois fiches de conseil du dépôt affirment le contraire — data/urbanisme/projets-services/protocol-999-protocole-de-resistance/conseil_3.json:89, conseil_6.json:54 et conseil_9.json:58 écrivent « `armure_sentinel.guard` appelée depuis `armure.py:96-100` », et conseil_3 la déclare « le seul espace de ce lieu à la fois bâti, appelé et monté ». L'appel n'existe pas.
9⚑ Le magasin que la signature lit, et que personne n'écrit`set_latest` : 0 appelant dans tout le dépôt git hors tests. 3 lecteurs de production. `sign_aip_payload` : 0 appelant de production (re-vérifié au commit, hors backend/tests/)backend/app/services/armure_store.py:8-12,45 ; lecteurs : backend/app/services/aip_signing.py:146-188, backend/app/routers/verite.py:731-741, backend/app/services/passage_decision.py:1215-1243 · confirmé dans le codeLe store est un `Dict` de processus plafonné à 5 000 membres, et PERSONNE NE L'ÉCRIT — le fichier le dit lui-même (l.8-12 : « le routeur de production écrit dans armure_owner_observation_registry, jamais ici […] Aucun câblage de production ne doit le repeupler »). Trois organes continuent pourtant de le LIRE, et chacun en tire une conclusion permanente : (1) aip_signing.py:174-180 → `ArmureSnapshotUnavailable` à chaque signature (fail-close volontaire et bien nommé, mais c'est un refus systématique, pas une garde) ; (2) verite.py:732-741 → `identity_provenance(armure_present=False)` POUR TOUT LE MONDE : la cote d'identité de l'enquête Vérité est structurellement « armure absente » ; (3) passage_decision.py:1228-1235 → `ArmureStorePort` déclare `provenance=MEMOIRE` même garni, et son `identite_ancre()` rend l'`id()` d'un dictionnaire Python. Le store a été correctement déclassé ; ses trois lecteurs n'ont pas suivi.
10La sortie de l'armure vers l'économie0 occurrence de `'/js/armor-economy-bridge.js'` dans le tableau `scripts` de governance-init.js ; 1 seule page du dépôt le mentionne, frontend/etat-technique.html (une page de constat, pas un porteur)frontend/js/armor-economy-bridge.js:6-11 ; absent des tableaux de scripts de frontend/js/governance-init.js (seule occurrence : un motif de TIER3 l.1318, qui classe un ordre de chargement et ne charge rien) · confirmé dans le codeLe fichier se déclare lui-même mort (l.6-11 : « Statut : inactif. Cette implementation attribuait localement des UR à partir de l'apparence et de la progression, sans registre financier durable […] l'armure ne crée ni solde, ni droit économique, ni redistribution »), et il n'est de toute façon chargé par aucune page. Le reste du fichier décrit encore trois flux de revenus et des multiplicateurs ×1.0 à ×5.0 : c'est de la DOCTRINE RÉSIDUELLE dans un module mort — à ne pas lire comme une mécanique. Il n'existe aucune arête bâtie entre l'armure et l'économie : D7 `financial` et D9 `security` (dimensions_15.py:32,34) sont des ÉTIQUETTES de catégorie, ni soldes, ni clés, ni preuves.
Le lexique de cette planche 17 termes à deux registres · 7 avec un jumeau

On ne remplace pas le nom canon, on le double : le terme reste l’autorité, la glose est une poignée. Le lexique entier est sur sa propre page.

portée (axe POSITION — ind / com / civ)Jusqu'où une chose compte — pour moi seul, pour un groupe, ou pour tous — et c'est l'endroit où l'on agit qui le décide, pas une case à cocher.trinity_scope (la portée-LENTILLE) — La mesure de combien une même chose pèse à la fois pour une personne, pour son groupe et pour tous — trois nombres ensemble, pas un choix…
arêteUn lien enregistré une seule fois, qui se lit dans un sens ou dans l'autre selon le côté d'où on le regarde.
lieu (type de nœud)Le genre de place qu'occupe un endroit ; le dépôt en compte déjà plus de cinq mille, tous géographiques.
agent (type de nœud)Le genre de place qu'occupe un agent qui agit au nom de quelqu'un, avec l'endroit auquel il est rattaché.
bus (valeur de canal)C'est la valeur qui dit : ce message ne sort pas de la machine, il passe d'un module à l'autre dans le même programme.bus (l'organe de distribution) — C'est la pièce de code qui reçoit un message et le remet à tous ceux qui s'y sont abonnés.
bus (l'organe de distribution)C'est la pièce de code qui reçoit un message et le remet à tous ceux qui s'y sont abonnés.canal — C'est par quel moyen un message voyage : le réseau interne, le web, le courriel, le SMS, l'écran, et onze autres.bus (valeur de canal) — C'est la valeur qui dit : ce message ne sort pas de la machine, il passe d'un module à l'autre dans le même programme.
portée (VALID_PORTEES : indiv | commu | civ)C'est la taille de l'espace qu'un message concerne : une personne, un groupe, ou tout le monde.
fail-closeQuand l'outil ne peut pas faire le travail pour de vrai, il refuse et dit pourquoi, au lieu de repondre « c'est fait ».
porteUn passage qu'on traverse vraiment : il faut une permission pour le franchir, et il laisse une trace de ce qui est passe.porte (Porte de la Connaissance, knowledge_gate/porte.py) — Elle decide combien d'un document on montre a quelqu'un — de rien du tout jusqu'au texte complet — en six crans, et par defaut elle ne…
porte (Porte de la Connaissance, knowledge_gate/porte.py)Elle decide combien d'un document on montre a quelqu'un — de rien du tout jusqu'au texte complet — en six crans, et par defaut elle ne montre rien.porte — Un passage qu'on traverse vraiment : il faut une permission pour le franchir, et il laisse une trace de ce qui est passe.fenetre — Une vue sur ce qui se passe ailleurs : on voit, on ne prend rien, et rien ne change de main.
gardeUn controle pose sur le chemin d'une action, qui la laisse passer ou la refuse.
engagement (niveaux d'engagement citoyen)Quatre paliers de responsabilite choisis librement : plus on en prend, plus on peut poser de gestes qui touchent le collectif.
armure 15DElle réunit quinze mesures d'un compte en une seule empreinte, et vérifie à chaque passage qu'aucune n'a bougé.Armure Quantique 15 Dimensions (version navigateur) — C'est l'affichage à l'écran qui dessine les quinze dimensions et en tire une note de protection.
forgeL'atelier qui capte : c'est son volume des dernières vingt-quatre heures qui autorise, ou non, le système à émettre de la monnaie.
Hz / fréquence (famille Solfeggio)registre spirituelUne courte liste de nombres admis : un nombre qui n'y figure pas est refusé comme hors famille.
ACTIF / PONT / PARTIEL_ENERGIE / LATENT / VIDECinq étiquettes qui disent, pour un site, ce qui est présent de chaque côté et à quel point les deux s'accordent.
l'encryption (la computation de chiffrement)Le chiffrement n'est pas ce que le système vend : c'est un poste de travail qu'il traverse, et le travail des temples décodés lui fournit sa puissance de calcul.Pierre Philosophale — Un compteur qui retient 1 % de chaque cycle complet d'atelier et qui, à 100 %, déclenche une prime dont le montant suit la suite de…forge — L'atelier qui capte : c'est son volume des dernières vingt-quatre heures qui autorise, ou non, le système à émettre de la monnaie.

Matière : PLANCHES-MATIERE-2-INSTITUTIONNEL-2026-10-03.json (sha256 5cc49a404485) — planche de matière « L'ARMURE 15D — quinze fentes, une mesure, et la chaîne rompue avant le premier envoi ». Générée par scripts/generer-planches-ancrage.py ; la version « avant » (avant le passage du sceptique) que la matière conserve n’est pas dessinée — c’est la version dégradée au doute qui l’est, et les marges portent les dégradations.