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

Le meshmap

Le meshmap — quatre coordonnées, et le pivot qui n'en est pas un

Planche 5 · Le meshmap
26 pièces · 5 bâties · 13 partielles · 3 absentes · 5 non établies
Planche 5 — Le meshmap

ouvrir la planche en plein écran → · 26 pièces · 19 traverses · 12 marges

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

Une arête AT·OM se tient sur quatre coordonnées (adresse · proximité · lieu · mode) ; au commit 8addf1c94 aucune des quatre n'est entière, et le « pivot partagé » annoncé — le domaine — n'est pas partagé du tout : les 9 chaînes exactes existent bien, mais entre le routeur et le frontend seulement, le corpus des 188 graines ne portant aucune colonne de domaine.

Les marges 12 arbitrages ouverts, entiers
  • ⚑ MA PLUS GROSSE CORRECTION — le pivot. L'agent annonçait BATI « 9 chaînes exactes, recomptées », avec `logistique` en neuvième. Le code dit `monEquipe` (knowledge_seeds.py:95) et range `logistique` dans un legacy_map (:215). Et le côté corpus du pivot n'existe pas : verite-schema.sql n'a aucune colonne domaine. Le pivot EST réel — mais entre le routeur et le frontend, pas entre la carte et le corpus. Une planche qui dessine un trait carte↔corpus par le domaine dessinerait un trait qui n'est nulle part.
  • ⚑ MA DEUXIÈME CORRECTION — l'îlot de 16 modules. Le 243 de l'agent est EXACT, je l'ai recompté au chiffre près. Mais un compte d'occurrences n'est pas un compte d'écrivains vivants : BFS de 6 tours, deux arbres, zéro routeur, zéro main.py, zéro script. Et deux des modules les plus chargés (enclosure_place_membership_authority 29 occ., place_projection_binding_authority 24 occ.) n'ont même pas d'appelant SERVICE — leur seule citation hors tests est dans des .md de docs/inventaires/, c'est-à-dire dans des rapports d'audit antérieurs. Un module dont les seuls appelants sont les rapports qui le mentionnent n'est pas bâti.
  • ⚑ MA TROISIÈME CORRECTION, dans l'autre sens — l'aligneur d'espaces. L'agent l'a sous-estimé en disant « un seul appelant ». La chaîne est ENTIÈRE du frontend au code : governance-init.js → embeddings-explorer.js → /api/v2/embeddings monté → orchestrator → SpaceAligner. Le vrai défaut est arithmétique et bien pire qu'un appelant manquant : ALIGNMENT_MIN_SAMPLES=8 contre un corpus de 5, et aucune route d'ingestion arbitraire. L'aligneur ne peut JAMAIS s'ajuster, et l'endpoint publie un `aligned_convergence` qui est la convergence non alignée. C'est une garde qui passe sa propre épreuve sans rien faire.
  • ⚠ ARBITRAGE POUR JONATHAN — le dénominateur des routeurs doit cesser d'être cité nu. Trois nombres coexistent, tous justes sous leur règle : 351 (fichiers au 1er niveau de backend/app/routers/) · 375 (récursif, sous-dossiers compris, dont 4 fichiers d'_archive) · 377 (appels register_router dans main.py, dont 11 vers app/api/ et 1 vers le SECOND ARBRE). Il faut trancher LEQUEL la planche affiche, parce que les trois mènent à des phrases différentes.
  • ⚠ ARBITRAGE — le second arbre contribue exactement UN routeur monté (causal_engine/api/endpoints.py, ≥8 routes sous /api/v1/causal). L'agent annonçait BATI « le second arbre ne change PAS ce dénominateur ». C'est faux. Faut-il un cliquet qui interdise un DEUXIÈME ? Aujourd'hui rien ne l'empêche, et un routeur du second arbre est invisible à tout audit qui ne fouille que backend/app/routers/.
  • ⚠ ARBITRAGE — le MODE a deux implémentations qui ne se parlent pas : `ModePassage.FENETRE/PORTE` (passage_decision.py:70, îlot clos de 6 modules, 0 route) et le champ manquant de `RelationKind` (relation_kind.py:56-63, 7 champs). Le rapport T1 du 30-09 l'avait déjà posé en C4/DÉCISION_JONATHAN et ça n'a pas bougé. Deux options, pas trois : ajouter `mode` au dataclass canon, ou déclarer que le mode n'appartient pas au TYPE de l'arête mais à l'OPÉRATION qui la franchit (ce que COUTURE-COVENANT-2026-09-03:632 proposait déjà). La planche ne peut pas dessiner les deux.
  • ⚠ PIÈGE QUE J'AI FAILLI COMMETTRE, et qu'il faut écrire sur la planche : mon premier grep `ForeignKey` sur v82_281 a rendu ZÉRO. J'allais déclarer l'arête verte ABSENTE. Les six clés étrangères y sont en SQL BRUT MAJUSCULE (`CONSTRAINT fk_seat_place_membership FOREIGN KEY`), pas en SQLAlchemy. Loi : chercher la FONCTION, jamais le MOT — et jamais la seule ORTHOGRAPHE du mot.
  • ⚠ MÊME PIÈGE SUR LE LIEU, en sens inverse : `place_ref` est à ZÉRO dans les 375 routeurs, et je l'ai vérifié sous 6 noms de plus (place_id, lieu_id, lieu_ref, situated_seat, place_tree_scope). Mais le 7ᵉ — `scope_membership`, la table que la clé étrangère du siège référence — est présent dans 4 routeurs montés. Le lieu a donc une surface de LECTURE et aucune surface d'ÉCRITURE. Une planche qui dirait « lieu = ABSENT » d'un seul trait serait fausse de ces 4.
  • ⚠ LE DÉPARTAGE QUI DOIT ÊTRE VISIBLE SUR LA PLANCHE — la grappe `enclosure_*` ne se dessine PAS d'un seul trait. Le MANDAT vit : main.py:491 → enclosure_runtime_assembly → supervisor_p0p2_admission_gate → core/agent_mandate.py, avec un refus honnête nommé (`enclosure_runtime_database_unavailable`). Le SIÈGE SITUÉ est mort : aucun des 8 imports de l'assembly n'est un module de l'îlot place/siège. Même préfixe, même suite de migrations, deux états opposés.
  • ⚠ REGISTER_ROUTER — correction en faveur de main.py, que l'agent n'a pas vue : l'ImportError n'est PLUS muette (logger.error + _registered_broken + exposition en :2610-2613 + readiness "degraded" en :3003). Mais la garde reste DÉSARMÉE : `core=False` par défaut et REGISTER_ROUTER_STRICT éteint. C'est le 3ᵉ mécanisme de la loi « une garde cesse de garder » : elle existe, elle mesure, et rien n'en dépend.
  • ⚠ DÉFAUT NEUF, trouvé en passant, non demandé — knowledge_seeds.py:217 : `return normalized if normalized in _domain_batches else "institutions"`. Tout domaine inconnu est SILENCIEUSEMENT reclassé `institutions` (S3 Souveraineté). Pas de refus, pas de raison, pas de drapeau. C'est la même famille que le repli-en-mémoire que U-03 appelle « la fabrique de défauts ». Et le registre lui-même est en mémoire (`_registry: Dict[str, dict] = {}`, :147).
  • ⚠ CHIFFRES DE FICHE QUE JE N'AI PAS REPRODUITS, avec ce que J'AI mesuré à leur place : le « 47 » → j'obtiens 15 fichiers / 103 occurrences de fractal_address dans les routeurs ; le « 146 en migrations » → j'obtiens 52 occurrences de place_ref sur 4 fichiers ; les « 20 013 graines » → j'obtiens 188 fichiers (confirmé sous deux règles), 11 145 n-uplets de VALUES, 6 062 lignes d'événement kp-. Trois règles de comptage sont introuvables ; les trois chiffres restent NON_ETABLI et je ne les ai pas devinés.
Les blancs déclarés ce que la mesure n’a pas pu voir

Ce que cette collecte N'A PAS pu voir. (1) RIEN N'A ÉTÉ EXÉCUTÉ : aucun serveur démarré, aucune page ouverte, aucun test lancé, aucune requête HTTP émise. Tout « atteignable » ci-dessus est une atteignabilité STATIQUE lue dans le code, jamais un appel observé. (2) LA PRODUCTION N'A PAS ÉTÉ INTERROGÉE. La dernière révision alembic mesurée en prod est `v82_260_atom_positions` (CLAUDE.md, mesure du 2026-08-08, base `atom_db` sur `compose-atom-db-1`) ; le dépôt est à `v82_299`. Les quatre migrations qui PORTENT l'arête verte — v82_281, v82_283, v82_289, v82_296 — sont donc 20 à 39 révisions AU-DELÀ du dernier état prod connu : les clés étrangères que j'ai lues peuvent n'exister nulle part en prod. Je n'ai pas vérifié, et un fait de prod non interrogé n'est pas un fait. (3) JE N'AI PAS MESURÉ L'IMPORTABILITÉ RÉELLE de `atom_canon` depuis `relation_service.py` : j'ai lu `backend/Dockerfile:44 pip install -e /opt/hf-atom-tools` et j'en déduis que l'import passe dans l'image — je ne l'ai pas prouvé, et le `except Exception` rendrait l'échec invisible. (4) MON BFS a suivi les CITATIONS TEXTUELLES de noms de module, pas un graphe d'imports résolu : un appel par chaîne dynamique, par `importlib`, par entrée de registre ou par abonnement de bus m'aurait échappé. J'ai cherché ces formes dans main.py, backend/app/core/ et scripts/ et n'en ai trouvé aucune pour l'îlot place/siège — mais l'absence que je rends est l'absence sous CETTE règle. (5) LES DEUX ARBRES ont bien été fouillés pour chaque « zéro » (backend/app/ : 1 627 .py ; hors app/ : ~278 .py), et j'ai nommé le seul routeur du second arbre. Je n'ai PAS fouillé `transit/`, `archives/`, ni `AT-OM-999-DEPLOY-ZAMA-ALLELUYA/` : ils sont hors périmètre live par l'audit R5, mais c'est une exclusion assumée, pas une mesure. (6) LE FRONTEND : « 0 appel à /api/v2/fractale » est un grep sur `frontend/` au commit — il ne voit pas une URL construite par concaténation ni une route atteinte via un proxy ou un manifeste de configuration.

ne pas dessiner

  • ⛔ Ne pas refaire les 7 cosmogrammes existants (frontend/planches/*.svg) : QG, poumons, Metatron, grille 27, urbanisme, contenu du village, anatomie des lieux. La grille 27+0 en particulier est DÉJÀ la planche IV (frontend/planches-atelier.html:119) — cette planche-ci ne la redessine pas, elle mesure l'ARÊTE, pas les cases.
  • ⛔ Ne pas dessiner un trait carte↔corpus étiqueté « le domaine ». Il n'existe pas : verite-schema.sql n'a aucune colonne domaine, et les 188 graines portent un axe `theme` au vocabulaire étranger. Le pivot réel va du routeur au frontend, et seulement là.
  • ⛔ Ne pas dessiner `logistique` comme neuvième chaîne du domaine. Le code dit `monEquipe` (knowledge_seeds.py:95, sphere-directives.js:548). `logistique` est un alias legacy (:215) — l'écrire en clé reproduirait l'erreur à l'encre.
  • ⛔ Ne pas dessiner la grappe `enclosure_*` d'un seul trait ni d'une seule couleur. Le mandat est atteint au démarrage, le siège situé n'est atteint par rien. Un trait unique mentirait sur l'un des deux.
  • ⛔ Ne pas annoncer « N routeurs » sans dire laquelle des trois règles est employée (351 / 375 / 377) ni, pour la troisième, que le second arbre en fournit un.
  • ⛔ Ne pas dessiner l'aligneur d'espaces en gris « non branché ». Il est branché jusqu'au navigateur. Il faut le dessiner EN SERVICE ET INERTE — 5 échantillons contre un plancher de 8 — sinon la planche rate le seul défaut qui soit arithmétique et non architectural.
  • ⛔ Ne pas dessiner register_router comme un avaleur muet. Il journalise, il accumule, il publie, il dégrade la readiness. Ce qu'il faut dessiner, c'est une garde ARMÉE NULLE PART : core=False par défaut, REGISTER_ROUTER_STRICT éteint.
  • ⛔ Ne pas porter sur la planche le 47, le 146 ni les 20 013. Aucune règle de comptage ne les rend au commit 8addf1c94, et la devise interdit un fait sans sa source mesurable.
Les traverses 19 relations, de source à source
frontend/js/governance-init.js:148,400,1174
charge
→frontend/js/embeddings-explorer.js3 tableaux de scripts distincts citent /js/embeddings-explorer.js
frontend/js/embeddings-explorer.js:12,35-36
appelle
→backend/app/routers/embeddings.py:39 (/api/v2/embeddings)API_BASE = '/api/v2/embeddings' via atomFetch ; routeur monté par register_router("app.routers.embeddings")
backend/app/routers/embeddings.py
appelle
→backend/app/services/embeddings/embedding_orchestrator.pygit grep -l embedding_orchestrator -- backend/app/routers/ → embeddings.py
embedding_orchestrator.py:28,85,87,183-187
appelle
→space_alignment.py SpaceAlignerfit() appelé, apply() appelé — mais ALIGNMENT_MIN_SAMPLES=8 > 5 chunks du bootstrap ⇒ apply() rend l'identité, status()="non_ajusté"
embedding_orchestrator.py:89-91 bootstrap()
alimente
→corpus_ingester.py:15 bootstrap_minimal_corpus()5 graines C1..C5 en dur ; aucune route d'ingestion arbitraire parmi les 9 endpoints de embeddings.py
corpus_ingester.py:86
appelle
→fractal_position_resolver.py:638 resolve_position()0 occurrence de fractal_position_resolver dans corpus_ingester.py ; l'adresse est forgée en f-string avec .S2. en dur
fractal_position_resolver.py:638
alimente
→backend/app/routers/code_index_router.pycode_index_router importe le resolveur ; monté par register_router("app.routers.code_index_router")
backend/app/main.py:2220
appelle
→backend/causal_engine/api/endpoints.py:36 (SECOND ARBRE)register_router("causal_engine.api.endpoints", "", ["Causal Engine"], "causal_engine") — la seule monture hors app.*
backend/app/main.py:491-497 (_activate_enclosure_runtime)
appelle
→backend/app/services/enclosure_runtime_assembly.pygaté sur `if not db_connected: return False` (main.py:486) — refus honnête nommé enclosure_runtime_database_unavailable
enclosure_runtime_assembly.py:43
traverse
→supervisor_p0p2_admission_gate.py → app/core/agent_mandate.py:53 (lieu_attache)supervisor_p0p2_admission_gate.py:21 importe AgentMandate/mandate_digest ; :412 appelle mandate_digest(mandate)
enclosure_runtime_assembly.py (8 imports, :18-43)
appelle
→enclosure_situated_seat_authority.py et les 15 autres modules de l'îlot place/siègeaucun des 8 imports n'est un module de l'îlot ; BFS de 6 tours sur les DEUX arbres : 0 routeur, 0 main.py, 0 script, 0 core/
enclosure_situated_seat_authority.py
alimente
→v82_281 fk_seat_place_membership → scope_membership(entity_id, tree_scope)l'écrivain existe et la clé étrangère existe (v82_281:223) ; l'écrivain n'a aucun appelant hors backend/tests/unit/
backend/app/routers/{canon_coherence_router.py:140-149, local_steward_router.py, fractale_communautaire.py, babel/fractal_websocket_router.py}
appelle
→scope_membershiples 4 sont montés dans main.py ; canon_coherence_router passe par app.services.scope_membership_service
backend/app/routers/fractale_communautaire.py:79 (/api/v2/fractale, 6 routes)
alimente
→frontend (122 pages, ~1660 fichiers JS)git grep 'api/v2/fractale' -- frontend/ → 0 ; ma-coordonnee|mes-communautes|grille-27|ma-portee-projection → 0 hit JS (seuls une .md et le nom d'image d'une planche)
backend/app/services/relation_service.py:31
appelle
→hf-atom-tools/atom_canon/primitives/relation_kind.pyunique importeur de production du dépôt, dans try/except Exception, sans sys.path.insert — dépend de backend/Dockerfile:44
relation_kind.py:68 ABRITE (lecture_directe/lecture_inverse)
traverse
→v82_289:427 'abrite' ET v82_291:112 'est_situe_dans'les deux lectures de la MÊME arête stockées comme deux types — ce que l'en-tête de relation_kind.py interdit ; et l'accent est perdu en v82_291
passage_decision.py:70-76 (ModePassage FENETRE/PORTE)
alimente
→n'importe quel routeur des 375îlot clos de 6 modules — passage_canonical, passage_identifiers, mirror_envelope, mirror_crypto, passage_outbox ; 0 routeur, 0 main.py
backend/app/routers/knowledge_seeds.py:93-96 DOMAINS
traverse
→frontend/js/sphere-directives.js:22..595 sphere_key9 chaînes identiques une à une, monEquipe comprise — c'est le SEUL pivot réellement partagé des quatre coordonnées
knowledge_seeds.py:93-96 DOMAINS
alimente
→les 188 fichiers frontend/sql/sql/verite-seed-*.sqlverite-schema.sql → 0 colonne 'domain' ; l'axe des graines est `theme` (military, surveillance, politics) ; le domaine est DÉCLARÉ à l'enregistrement du lot, jamais lu de la graine
La nomenclature 26 pièces, chacune avec sa source
1LE DÉNOMINATEUR — 351 fichiers au premier niveau, 375 en récursif, et la règle qui sépare les deux351 top-level / 375 récursif — IDENTIQUE au commit et dans l'arbre de travail. L'écart de 24 EST exactement le contenu des 4 sous-dossiers, dont 4 fichiers d'_archive.git ls-tree -r 8addf1c94 -- backend/app/routers/ ; sous-dossiers : _archive(4) babel(13) stone_decoder(3) agents_browser(4) · confirmé dans le code
2COORD 1bis — le producteur canonique d'adresse EXISTE et EST appelé — mais pas à l'ingestion3 appelants hors tests, dont 1 routeur montébackend/app/services/fractal_position_resolver.py:638 def resolve_position() ; appelé par backend/app/routers/code_index_router.py (monté dans main.py), backend/app/services/mcp_carte_tools.py, hf-atom-tools/atom_canon/translator/ctx_canon_builder.py · confirmé dans le code
3⚑ CE QUI RESTE VRAI DU PIVOT — un joint exact routeur ↔ frontend, 9 chaînes, et UNE fracture au neuvième9 sur 9 identiques entre le routeur et le frontendbackend/app/routers/knowledge_seeds.py:93-96 (9 chaînes) comparé une à une à frontend/js/sphere-directives.js:22,93,148,360,407,454,501,548,595 (9 sphere_key) → identiques, monEquipe compris · confirmé dans le code
4Correction d'emplacement confirmée — le mandat est dans l'arbre 1, et il porte bien le lieu17 clés autorisées, dont lieu_attache. Fichier sous backend/app/core/ — arbre 1, pas le second.backend/app/core/agent_mandate.py:53 _ALLOWED_KEYS = frozenset({...}) → 17 clés ; :56 "role", "portee", "lieu_attache" ; :175 lieu_attache: str # le Point 0 ou le quai d'un lieu · confirmé dans le code
5⚑ RELEVÉ — le mandat (et son lieu_attache) EST sur un chemin de démarrage vivant, contrairement au siègechaîne de 4 maillons, du démarrage FastAPI au canon du mandatbackend/app/main.py:491-497 _activate_enclosure_runtime → from app.services.enclosure_runtime_assembly import create_enclosure_runtime_assembly ; enclosure_runtime_assembly.py:43 from app.services.supervisor_p0p2_admission_gate import … ; supervisor_p0p2_admission_gate.py:21 from app.core.agent_mandate import AgentMandate, MandateError, mandate_digest ; :412 digest = mandate_digest(mandate) · confirmé dans le code
6⚑ RÉFUTÉ — le second arbre CHANGE le dénominateur : il porte un routeur monté377 appels register_router dans main.py (multilignes compris) : 365 vers app.routers.* · 11 vers app.api.* · 1 vers causal_engine.api.endpoints, HORS backend/app/. Plus 4 app.include_router directs.backend/app/main.py:2220 register_router("causal_engine.api.endpoints", ...) ; backend/causal_engine/api/endpoints.py:36 APIRouter(prefix="/api/v1/causal") · confirmé dans le codeL'agent annonçait BATI : « le second arbre ne change PAS ce dénominateur ». C'est faux d'exactement un routeur, et ce routeur-là est monté et expose ≥8 routes POST/GET sous /api/v1/causal. Toute phrase « N routeurs » comptée sur backend/app/routers/ est aveugle à lui.
7COORD 1 — ADRESSE : fractal_address est sur la surface HTTP, concentrée sur 3 routeurs15 fichiers / 103 occurrences. 73 des 103 (71 %) vivent dans 3 fichiers.git grep -c fractal_address 8addf1c94 -- backend/app/routers/ backend/app/api/ → 15 fichiers, 103 occurrences ; world_canon.py:38 occ · acmi_router.py:23 · canon_history_router.py:12 · confirmé dans le code12 des 15 fichiers n'en portent que 1 à 4 occurrences — l'adresse y est transportée, pas produite ni validée.
8COORD 2 — PROXIMITÉ : le vecteur est un dérivé de SHA-256 quand aucun fournisseur ne répond2 modes déclarés honnêtement : deterministic_hash et deterministic_hash_fallbackbackend/app/services/embeddings/multi_model_embedder.py:105 salt = hashlib.sha256(model_id.encode("utf-8")).digest() ; :152 "mode": "deterministic_hash" ; :160 "deterministic_hash_fallback" · confirmé dans le codeLe champ `mode` DIT la vérité — c'est le seul endroit des quatre coordonnées où la dégradation s'avoue. Mais un SHA-256 n'a aucune structure sémantique : la « proximité » mesurée dessus est un bruit reproductible.
9⚑ COORD 2bis — RELEVÉ : l'aligneur est câblé DU FRONTEND JUSQU'AU CODE. Son maillon manquant n'est pas un appelant, c'est une arithmétique5 échantillons contre un plancher de 8 — l'aligneur ne peut JAMAIS s'ajusterbackend/app/services/embeddings/space_alignment.py:36 ALIGNMENT_MIN_SAMPLES = 8 ; backend/app/services/embeddings/corpus_ingester.py:15 bootstrap_minimal_corpus() → 5 chunks C1..C5 ; chaîne : frontend/js/governance-init.js:148,400,1174 → frontend/js/embeddings-explorer.js:12 API_BASE='/api/v2/embeddings' → main.py register_router("app.routers.embeddings") → backend/app/routers/embeddings.py:39 → embedding_orchestrator.py:28,85,87,183-187 → space_alignment.py · confirmé dans le codespace_alignment.py:88 `if sample_count < self.min_samples: continue` ⇒ aucune carte n'est posée ⇒ apply() rend `list(vector)`, l'identité ⇒ status() rend mode="non_ajusté". Et il n'existe AUCUN point d'ingestion arbitraire : les 9 routes de embeddings.py n'offrent que /bootstrap, qui re-sème les mêmes 5. Donc chaque `aligned_convergence` publié par l'endpoint EST la convergence non alignée, sous un autre nom. L'agent disait « un seul appelant » — le vrai défaut est que 5 < 8, par construction.
10COORD 3bis — RELEVÉ : le lieu a BIEN une surface HTTP, mais sous le nom scope_membership, et en LECTURE seulement4 routeurs sur 375 — le 7ᵉ nom est le seul qui n'est pas à zéroscope_membership dans backend/app/routers/babel/fractal_websocket_router.py, canon_coherence_router.py:140-149, fractale_communautaire.py, local_steward_router.py — les 4 montés dans main.py · confirmé dans le codeC'est la table que le siège situé référence par clé étrangère. Le côté LECTURE du lieu est donc atteignable ; le côté ÉCRITURE (place_ref, sièges situés) ne l'est par aucune route.
11⚑⚑ RÉFUTÉ — « 243 lignes d'écrivains = BATI ». Le 243 est EXACT. Les écrivains n'ont AUCUN appelant de production243 occurrences — confirmé au chiffre près. Et 0 routeur, 0 ligne de main.py, 0 script, 0 fichier de backend/app/core/ : seuls backend/tests/unit/* les appellent.git grep -c place_ref 8addf1c94 -- backend/app/services/ backend/app/models/ → somme = 243 (confirmé). BFS de 6 tours sur les DEUX arbres depuis les 11 modules porteurs : 16 modules atteints, clôture. · confirmé dans le codeLes 16 modules de l'îlot : enclosure_situated_seat_authority · enclosure_place_seat_plan_authority · enclosure_birth_place_seat_issuer · enclosure_place_membership_authority · place_projection_binding_authority · enclosure_birth_membrane_adapters · enclosure_seat_passage_adapter · enclosure_team_birth_{coordinator,directive_executor,edge_codec,edge_issuer,prepare_mandate_port,register_mandate_port,register_passport_port,register_seat_plan_port,registry_applier}. Deux d'entre eux — enclosure_place_membership_authority (29 occ.) et place_projection_binding_authority (24 occ.) — n'ont même pas d'appelant SERVICE : leur seule citation hors tests est dans des .md de docs/inventaires/.
12COORD 4bis — le MODE fenêtre/porte est bâti, et c'est un ÎLOT CLOS de 6 modules sans aucune route6 modules · 0 routeur · 0 appel au démarragepassage_decision.py ← importé par backend/app/core/passage_canonical.py, backend/app/core/passage_identifiers.py, backend/app/services/mirror_envelope.py, backend/app/services/passage_outbox.py ; mirror_envelope.py ← mirror_crypto.py SEULEMENT ; 0 routeur, 0 ligne de main.py · confirmé dans le codeL'organe est entier et tenu par des tests (test_passage_decision_p3.py, test_passage_outbox_p4.py, test_mirror_envelope_m0.py) mais la grappe ne touche aucune des 377 montures. Rien ne l'expose : ni route, ni sujet de bus, ni widget.
13Le canon des relations a UN SEUL importeur dans tout le dépôt, dans un try/except, et sans amorce de chemin1 importeur de production sur tout le dépôt ; le repli connaît 1 type sur les 8 du noyaubackend/app/services/relation_service.py:31 (dans try:, lignes 30-49, except Exception: → fallback _ARBRE_TYPES = {"abrite"}) ; seul autre importeur du dépôt : hf-atom-tools/atom_canon/tests/test_relation_kind.py:17 · confirmé dans le codeContrairement à ~10 routeurs frères (canon_access_router.py:13, canon_historian_router.py:20, canon_history_router.py:17, acmi_router.py:12, atom.py:50…) qui font `sys.path.insert(... 'hf-atom-tools')`, relation_service.py n'amorce PAS le chemin. Il dépend de backend/Dockerfile:44 `pip install -e /opt/hf-atom-tools`. Dans l'image l'import passe probablement ; rien dans le dépôt ne le PROUVE au runtime, et `except Exception` rend l'échec muet — le repli ne connaîtrait que `abrite` sur 8 types.
14⚑ TROIS vocabulaires sous le MÊME nom de colonne `relation_kind` — et deux des trois sont les DEUX LECTURES de la même arête3 vocabulaires sous `relation_kind` + un 4ᵉ nom de colonne, `rel_type`, dans relation_service.pybackend/alembic/versions/v82_289_enclosure_birth_place_seat_issuer.py:427 → 'abrite' · v82_291_person_position_membership_authority.py:112 → DEFAULT 'est_situe_dans' · v82_296_place_projection_binding.py:26,33 → 'represents' sous CHECK ; à comparer à relation_kind.py:68-69 ABRITE = (lecture_directe='abrite', lecture_inverse='est_situé_dans') · confirmé dans le codePlus grave que « trois vocabulaires » : 'abrite' et 'est_situe_dans' sont la lecture_directe et la lecture_inverse du MÊME RelationKind, stockées comme s'il s'agissait de deux types. C'est exactement ce que l'en-tête de relation_kind.py interdit : « sont la MÊME arête — jamais deux lignes ». Et v82_291 a perdu l'accent : 'est_situe_dans' ≠ 'est_situé_dans', donc même la chaîne ne joint pas. Le troisième, 'represents', est un mot anglais verrouillé par CHECK et ABSENT du catalogue canon.
15⚑ LA FRACTURE DU PIVOT, AU NEUVIÈME — et le défaut de repli qui l'accompagne1 alias legacy + 1 repli muet vers `institutions`backend/app/routers/knowledge_seeds.py:209-217 _normalize_domain() — dernière ligne : `return normalized if normalized in _domain_batches else "institutions"` · confirmé dans le codeTout domaine inconnu est silencieusement reclassé `institutions` — sans refus, sans raison, sans drapeau. Un lot mal nommé n'échoue pas : il atterrit dans S3 Souveraineté. C'est le même genre de défaut que le repli-en-mémoire que le plan unifié U-03 appelle « la fabrique de défauts ».
16⚑ L'ARÊTE VERTE — les clés étrangères EXISTENT (je m'étais d'abord trompé) mais l'arête n'a aucun écrivain atteignable6 clés étrangères + 4 contraintes UNIQUE + ~14 CHECK dans la seule v82_281backend/alembic/versions/v82_281_enclosure_situated_seats.py:223 CONSTRAINT fk_seat_place_membership FOREIGN KEY (place_ref, place_tree_scope) REFERENCES scope_membership (entity_id, tree_scope) ON DELETE RESTRICT ; :228 fk_seat_lease_binding (… agent_instance_ref) ; + fk_seat_passport_binding, fk_seat_mandate_binding, fk_seat_activation_authority, fk_seat_termination_authority ; backend/app/models/enclosure_situated_seat.py:65,73 (place_ref: Text, agent_instance_ref: UUID) · confirmé dans le codeLa DDL est le morceau le plus sérieux des quatre coordonnées — mais son UNIQUE écrivain, enclosure_situated_seat_authority.py, est au centre de l'îlot de 16 modules que seuls les tests appellent. Une arête typée, gardée, et que rien ne peut écrire. ⚑ Note de méthode : mon premier grep `ForeignKey` a rendu 0 sur v82_281 — les clés y sont en SQL brut majuscule, pas en SQLAlchemy. J'ai failli déclarer ABSENT un organe bâti.
17⚑ ET LE DÉPARTAGE QUE CELA FAIT VOIR — la même grappe enclosure, deux destins8 modules importés par l'unique porte de démarrage de la grappe ; AUCUN des 16 modules de l'îlot place/siège n'y figurebackend/app/services/enclosure_runtime_assembly.py:18-43 — ses 8 imports : enclosure_birth_recovery_{database,scheduler,worker} · enclosure_http_agent_admission_executor · enclosure_runtime_adapter · enclosure_runtime_http_executor · enclosure_supervisor · enclosure_termination_authority · supervisor_p0p2_admission_gate · confirmé dans le codeC'est le départage précis, et il contredit toute planche qui dessinerait « enclosure » d'un seul trait : le MANDAT est vivant au démarrage (gaté sur `db_connected`, main.py:486-491, refus honnête `enclosure_runtime_database_unavailable`), le SIÈGE SITUÉ est mort. Même préfixe, même migration, deux états.
18⚠ « Monté dans main.py » ≠ « chargé » — confirmé, MAIS la surface d'honnêteté existe, elle est seulement désarmée par défaut377 montures ; 1 drapeau d'environnement, éteint par défaut ; 1 liste exposée en lecturebackend/app/main.py:1637-1664 register_router() ; :1644 except ImportError → _registered_broken.append + logger.error, continue si core=False ; :1634 _registered_broken: List[dict] ; :2610-2613 exposé ({"total", "broken_count", "broken"}) ; :3003,3018,3028 readiness → "degraded" ; :1638 strict = os.getenv("REGISTER_ROUTER_STRICT") · confirmé dans le codeDeux corrections à l'agent, en sens inverses. (a) Ce N'EST PAS muet : l'échec est journalisé en ERROR, accumulé dans _registered_broken, publié, et bascule la readiness en "degraded". (b) Mais `core=False` est le DÉFAUT et REGISTER_ROUTER_STRICT est éteint : un routeur mort ne bloque pas le démarrage. La garde existe et n'est pas armée — le 3ᵉ mécanisme de la loi « une garde cesse de garder ».
19⚑ LE DÉFAUT D'UNE LIGNE — .S2. en dur, confirmé verbatim1 ligne ; 0 appel à resolve_position() dans tout corpus_ingester.pybackend/app/services/embeddings/corpus_ingester.py:86 → fractal_address=f"f{...}.{CORPUS_DEFINITIONS[corpus_id]['label']}.S2.embeddings.delta.{identity_digest}" · confirmé dans le codeLe producteur canonique est à trois appels de distance et n'est jamais appelé ici. Tout embedding du système naît classé S2 Entreprise.
20COORD 3 — LIEU : zéro routeur porte place_ref, vérifié sous 7 noms et pas un seul0 sur 375 routeurs, pour 6 noms sur 7git grep -l sur backend/app/routers/ + backend/app/api/ pour place_ref, place_id, lieu_id, lieu_ref, situated_seat, place_tree_scope → 0 fichier chacun · confirmé dans le code
21COORD 4 — MODE : absent de RelationKind, lu champ par champ7 champs, aucun nommé modehf-atom-tools/atom_canon/primitives/relation_kind.py:56-63 — les 7 champs du dataclass : nom · direction · topologie · lecture_directe · lecture_inverse · merit_gated · consenti · confirmé dans le code
22⚠ LE 47 DE LA FICHE RESTE NON REPRODUIT — et je dis ce que j'ai mesuré à sa placeni 15 ni 103 n'est 47 ; je n'ai pas trouvé la règle qui rendrait 47ma propre mesure : 15 fichiers / 103 occurrences au commit 8addf1c94 · confirmé dans le code
23⚠ Le « 146 en migrations » reste non reproduit — voici ce que j'ai compté52 occurrences en migrations, sur 4 fichiers. Pas 146.git grep -c place_ref 8addf1c94 -- backend/alembic/versions/ → v82_281(7) + v82_283(8) + v82_289(32) + v82_296(5) = 52 · confirmé dans le code
24⚠ Et `presence` n'y est pas non plus : DEUX cardinalités, pas trois2 membres exactementbackend/app/services/passage_decision.py:70-76 class ModePassage(str, Enum) → FENETRE="fenetre", PORTE="porte" ; grep PRESENCE dans passage_decision.py + mirror_envelope.py → 0 · confirmé dans le code
25⚑⚑ RÉFUTÉ DEUX FOIS — « LE PIVOT PARTAGÉ : 9 chaînes exactes = BATI ». La neuvième chaîne est fausse, et le corpus ne porte aucun domainela 9ᵉ chaîne du code est `monEquipe`, PAS `logistique`. Dans les 188 graines : `logistique` apparaît dans 35 fichiers — en PROSE française (« soutien logistique aux forces armées ») ; `monEquipe` dans 2 fichiers, les deux étant env-3d-schema.sql, pas une graine.backend/app/routers/knowledge_seeds.py:93-96 DOMAINS = [personnel, entreprise, institutions, creation, communaute, communication, formation, monEquipe, durabilite] ; :215 legacy_map = {"logistique": "monEquipe", "mon_equipe": "monEquipe"} ; frontend/js/sphere-directives.js:548 sphere_key: 'monEquipe' ; frontend/sql/sql/verite-schema.sql → 0 occurrence de 'domain' · confirmé dans le codeDeux défauts distincts. (a) `logistique` n'est pas une clé : c'est un ALIAS LEGACY que _normalize_domain remappe vers monEquipe. (b) Le schéma des graines — (id, date_sort, date_display, title, theme, period, controlled_narrative, documented_reality, sources, verification, connections, pattern) — n'a AUCUNE colonne domaine ; son axe est `theme`, avec un vocabulaire étranger (military, surveillance, politics). Le domaine des lots vit dans knowledge_seed_batches, DÉCLARÉ par celui qui enregistre, jamais lu depuis la graine. Donc « clés de la carte ET noms de domaine des graines » n'est pas établi : le corpus n'a pas ce côté du pivot.
26⚠ Les 20 013 graines — non reproduit, et voici mes deux comptes avec leur règle188 fichiers (confirmé sous deux règles) · 11 145 n-uplets de VALUES · 6 062 lignes d'événement kp-. Aucun des trois n'est 20 013.git ls-tree -r 8addf1c94 | grep 'verite-seed-.*\.sql$' → 188, tous sous frontend/sql/sql/ ; git grep -ohcE "^\('" sur ces 188 → 11 145 ; git grep -ohE "^\('kp-[0-9]+'" → 6 062 · confirmé dans le code
Le lexique de cette planche 20 termes à deux registres · 6 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.

scope / tree_scopeLe champ qui enregistre la portée d'une chose, et qui lui donne un contenant différent dans chacun des trois classements empilés.
contenance / abriteLe lien qui dit qu'un endroit en contient un autre, avec un seul contenant possible à la fois.
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.
mode (fenêtre / porte)La distinction entre regarder depuis chez soi et passer de l'autre côté : passer demande une permission et laisse une trace, regarder ne change rien.
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é.
scope_membershipLa table qui dit qui est contenu par qui, avec un contenant différent par portée, et c'est elle qui tranche quand l'adresse dit autre chose.
status (green / yellow / red)C'est la note de confiance mise sur l'étiquetage d'un message : vert, le classement est bon ; rouge, il a échoué.
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.
covenantL'entente qu'une personne accepte en entrant, qui fixe ce que le systeme peut faire avec elle et sert de reference a tous les accords qui viennent apres.
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.
fenetreUne 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.
Babel (Décodeur de Babel)L'outil qui mesure comment les mots ont été retournés, et qui refuse de répondre plutôt que de deviner quand sa base manque.
embeddingUne suite de nombres qui devrait rapprocher deux textes de sens voisin — mais, dans ce qui tourne aujourd'hui, elle est tirée d'un simple calcul d'empreinte du texte.
cliquetUn compteur à sens unique : il laisse passer ce qui améliore et fait échouer la construction dès qu'on empire.
plancher (trouvé / déclaré)Dire « au moins tant » au lieu de « tant », et écrire juste après ce que le comptage n'a pas pu voir.cliquet — Un compteur à sens unique : il laisse passer ce qui améliore et fait échouer la construction dès qu'on empire.plancher (seuil minimal d'un cliquet en intégration continue) — Un minimum inscrit dans une épreuve : si le code en perd un, l'épreuve passe au rouge.
plancher (seuil minimal d'un cliquet en intégration continue)Un minimum inscrit dans une épreuve : si le code en perd un, l'épreuve passe au rouge.plancher (trouvé / déclaré) — Dire « au moins tant » au lieu de « tant », et écrire juste après ce que le comptage n'a pas pu voir.

Matière : PLANCHES-MATIERE-1-TECHNIQUE-2026-10-03.json (sha256 b29a3dc78614) — planche de matière « Le meshmap — quatre coordonnées, et le pivot qui n'en est pas un ». 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.