◉ SHINKIRO

Les décisions de flotte

Une seconde série d'ADR, à côté des 192 d'ADVE-project. C'est un risque assumé : les séries parallèles meurent, l'une prend le pas et l'autre se fossilise. Deux règles la maintiennent en vie.

Règle 1 — elle ne gouverne qu'entre composants

Une décision interne à un composant reste chez lui. ADVE-project garde sa série ADR-NNNN sous docs/governance/adr/, et rien ici ne la remplace.

SHK- n'arbitre que ce qu'aucun dépôt ne peut trancher seul : le partage d'une source entre deux composants, le rang d'un composant dans le programme, la frontière entre ce qui est référencé et ce qui est versé.

Le préfixe existe pour qu'aucune collision de numéro ne soit possible : SHK-0001 et ADR-0001 ne se confondent pas, même cités hors contexte.

Règle 2 — l'audit la lit

Toute ADR Accepted qui énonce une règle vérifiable déclare un signal d'audit, et ce signal existe dans galahad/engine/skills/audit-fleet.json.

## Signal d'audit id-du-signal — ce qui est attendu, et ce qui constitue une violation.

Une ADR sans signal est une ADR que personne ne vérifie : l'audit la signale comme telle. Une décision qu'aucun contrôle ne défend n'a pas d'effet, et vaut mieux écrite nulle part qu'écrite et ignorée — c'est ainsi qu'on obtient un document qui affirme le contraire de la réalité.

Une ADR peut légitimement n'avoir aucun signal — elle porte alors Signal d'audit : aucun, et dit pourquoi. C'est une déclaration, pas un oubli.

Forme

docs/adr/SHK-NNNN-slug.md, numéros attribués dans l'ordre, jamais réutilisés.

# SHK-NNNN — Titre

## Contexte ce qui a été constaté, avec de quoi le recouper ## Décision ce qui est tranché ## Signal d'audit comment on vérifie que ça tient ## Portée ce que la décision ne dit pas

SHK-0001 — Le programme, et ses deux étages

Contexte

Trois noms circulaient pour trois choses différentes, et le même mot désignait tantôt l'ensemble, tantôt une de ses pièces. « Galahad 360 » nommait le programme entier ; galahad nommait aussi une équipe d'agents auto-hébergée, qui n'en est qu'un composant. Une confusion de ce genre ne reste pas verbale longtemps : elle finit en dépôt créé deux fois.

Elle l'a déjà fait. ADVE-project/docs/governance/adr/0100-argos-hunter-backend-port.md, daté du 14 juin 2026, ouvre son contexte par « Argos n'était pas déployable — 0 % de backend » et réimplémente le harvester à neuf.

Le même jour, dans Argos-studio, il y avait 184 fichiers. Une API v1 complète — agencies, awards, brands, assets, markets, references, sectors, years, ingest/dossier — un schema.prisma, une migration 20260512171730_init et un seed. Le tout posé en un seul commit le 15 mai, et intouché depuis. C'est vérifiable en une commande :

gh api 'repos/xtincell/Argos-studio/commits?until=2026-06-14T23:59:59Z&per_page=1'

Un mois d'écart. Un backend reconstruit parce que rien, nulle part, ne disait que l'autre existait. Le coût n'est pas le temps perdu : c'est qu'il y a désormais deux modèles de dossier de campagne à tenir d'accord.

Deuxième constat, de nature différente : les composants n'ont pas la même masse. Le relevé déterministe donne 101 855 Ko d'arbre pour ADVE-project contre 233 Ko pour galahad — 437 pour 1. Les traiter pareil, c'est soit imposer à un outil de trois fichiers la cérémonie d'un dépôt de 3 314, soit charger le programme de cent mégaoctets à chaque clonage.

Décision

Shinkiro est le programme, et la suite. Il ne contient aucun code de produit : il porte le manifeste, l'ordre de construction, les décisions de flotte, l'audit, et la présentation qu'il génère de lui-même. galahad est un produit du portefeuille — une équipe d'IA qui fait tourner l'agence en autonomie depuis un serveur dédié — et non un simple composant de livraison. ADVE est la méthode, et son dépôt canonique est ADVE-project. Ces trois noms ne sont pas interchangeables, et le README l'énonce avant toute autre chose.

Un composant appartient à un étage, et un seul.

referenceverse
Ce que c'estcomposant autonomeoutil léger
Son dépôtle sien, son cycle, sa CIle sien aussi
Dans shinkirocloné à côté par make clone-allsubmodule sous tools/
Critèrese déploie et se vérifie seulne vit que dans le flux d'un autre
Côté clients'adopte seulne s'adopte pas seul

Le critère n'est pas la taille — c'est l'autonomie. Et cette autonomie n'est pas une commodité de dépôt : c'est une propriété commerciale. Shinkiro est une suite, et une suite s'achète par morceaux. reference nomme ce qu'un client peut prendre seul — radar sans rien d'autre, la-barre sur un poste, galahad sur son propre serveur. verse nomme ce qui n'a de sens que dans le flux d'un autre.

La taille n'explique qu'une chose : pourquoi les deux étages ne peuvent pas être un seul. Verser ADVE-project en submodule imposerait ses 100 Mo à quiconque clone le programme pour lire trois fichiers de doctrine.

Le programme ne porte aucun code de produit. Sa propre surface de présentation fait exception, et ce n'en est pas une : un portail généré depuis fleet.yml est une lecture du manifeste, pas une application. Le placer ailleurs créerait une source partagée sans propriétaire — ce que SHK-0002 interdit.

L'appartenance au programme se déclare par le topic shinkiro, et par lui seul. C'est ce que le relevé interroge ; un dépôt sans le topic n'existe pas pour la flotte, un dépôt avec le topic mais absent de fleet.yml est une dérive.

fleet.yml porte le jugement, fleet.lock.yml porte les faits. Le premier est écrit à la main et dit à quoi sert un composant ; le second est régénéré par make releve et dit ce qu'il est. Trois champs du premier — vitalite, licence, deploiement.mode — ressemblent à des faits mais sont des jugements : c'est précisément leur contradiction par le second qui constitue un signal.

Signal d'audit

Le signal qui aurait épargné l'ADR-0100 — deux composants, un seul produit — n'est pas dans cette liste. Il demande une recherche de code à travers les dépôts, donc un jeton, donc le workflow et non la patrouille ; et il n'a de sens qu'une fois désigné le dépôt canonique d'Argos. Il relève de SHK-0002, et c'est là qu'il sera écrit. Le nommer ici sans l'implémenter aurait produit exactement ce que cette ADR combat : un document qui affirme un contrôle absent.

Portée

Cette ADR ne dit pas où tel composant doit aller — fleet.yml le dit, composant par composant, et se corrige sans ADR.

Elle ne crée pas de monorepo et n'impose pas un mode de déploiement unique. Cinq modes coexistent — Coolify, systemd, Vercel, Docker autonome, statique — parce qu'ils correspondent à cinq réalités ; les uniformiser casserait ce qui tourne. docs/TOPOLOGIE.md en tient le détail.

Elle ne dit rien du contenu des composants. Un dépôt reste maître de ses propres décisions ; SHK- n'arbitre qu'entre eux.

docs/adr/SHK-0001-programme-et-deux-etages.md


SHK-0002 — Argos : une bibliothèque, deux surfaces

Contexte

ADR-0100 d'ADVE-project, datée du 14 juin 2026, constate « Argos n'était pas déployable — 0 % de backend » et réimplémente le harvester à neuf. Argos-studio existait depuis le 15 mai, 184 fichiers, API v1 complète. Le récit de cette dérive est dans docs/DERIVE.md.

Mais le relevé des deux modèles dément la lecture simple — « deux fois la même chose ». Ce n'est pas le cas, et c'est ce qui rend l'arbitrage possible.

Argos-studio porte une bibliothèque. Neuf entités relationnelles autour de Reference : une taxonomie de patterns (patternKind, manipulationMode, funnelStage, piliers ADVE, operationGoals, victoryTypes), une preuve de performance à niveau d'attribution explicite — PROVEN_CAUSAL, CORRELATED, ESTIMATED, CLAIMED — la filiation entre campagnes, les annotations d'expert, la provenance nominative du chercheur. Plus une API v1 sur neuf familles de ressources et une voie d'entrée POST /api/v1/ingest/dossier, validée en Zod et idempotente sur le slug : une resoumission amende au lieu de dupliquer.

ADVE-project/src/server/services/seshat/argos/ porte une gouvernance. Un CampaignReferenceDossier à champs JSON — dna, editorial, sources — mais surtout ce que le studio n'a pas : un verdict de sûreté déterministe et sans LLM (PASS / QUARANTINE / REJECT, auto-publication si et seulement si PASS), le passage obligé par le LLM Gateway, les intents SESHAT_HARVEST_REFERENCE et OPERATOR_CREATE_REFERENCE_DOSSIER avec leurs SLO, la parité manual-first, et le lien intentEmissionId vers le journal de gouvernance.

Le recouvrement réel est étroit mais coûteux : les deux persistent une référence de campagne avec marque, secteur, marché et sources, et les deux ont une notion de publication. Deux modèles à tenir d'accord, indéfiniment.

Décision

Argos-studio est canonique pour la bibliothèque. Un seul modèle de référence, une seule taxonomie, une seule échelle d'attribution. C'est là que vit le fonds.

ADVE-project en devient un client gouverné. Il garde intégralement ce qui fait sa valeur et que le studio n'a pas — mais comme politique au-dessus d'une source partagée, plus comme seconde bibliothèque :

  1. Le Hunter récolte via le Gateway, inchangé.
  2. computeSafetyVerdict rend son verdict, déterministe, inchangé.
  3. Sur PASS uniquement, le dossier est projeté en research-dossier-v1 et poussé sur POST /api/v1/ingest/dossier. L'idempotence sur le slug fait que rejouer est sans danger.
  4. CampaignReferenceDossier cesse d'être la bibliothèque et devient le journal de gouvernance : ce qui a été récolté, par quel intent, quel verdict, par qui, quand. C'est une trace d'audit, pas un fonds documentaire.
  5. Les lectures publiques — listPublicDossiers, getPublicDossierByRef — passent par l'API v1 du studio.

L'autonomie des deux est préservée, et c'est une contrainte, pas un effet de bord. Argos-studio se déploie seul sur Vercel depuis app/ : c'est sa raison d'être, la bibliothèque publique et son moteur de recherche. ADVE-project fonctionne sans lui : le studio injoignable, la porte de gouvernance continue de juger et de journaliser, et la projection se rejoue plus tard — l'idempotence est ce qui rend ce report sûr.

Les trois interdits vendor d'ADR-0100 restent entiers. Ils portent sur docs/external-design/argos-hunter-v1/, qui n'est ni importé, ni exécuté, ni modifié. Cette ADR ne les touche pas.

ADR-0100 est amendée, non annulée. Son port est valable et le reste : la gouvernance qu'elle a construite est précisément ce qui manquait au studio. Seule sa prémisse — « 0 % de backend » — est corrigée.

Signal d'audit

C'est le contrôle qui aurait épargné ADR-0100 : contraint de déclarer qui possède Argos, son auteur aurait trouvé Argos-studio.

Il est volontairement déclaratif et sans réseau, donc exécutable par la patrouille à coût nul. Une recherche de code à travers les dépôts dirait mieux, mais exige un jeton, donc le workflow, donc une seule exécution par semaine — et surtout elle ne détecte qu'un symbole déjà dupliqué, quand celui-ci détecte l'intention de le faire.

Portée

Cette ADR ne fusionne pas les dépôts. Absorber Argos-studio dans ADVE-project détruirait l'autonomie qui est l'objet même de la contrainte posée.

Elle ne dicte pas le calendrier du branchement. Le côté ADVE est un dépôt gouverné — 192 ADR, plugin ESLint maison, intents et SLO — et son propre processus décide comment et quand. SHK- arbitre entre composants ; il ne légifère pas à l'intérieur.

Elle ne traite pas de la migration des dossiers déjà récoltés côté ADVE. Ils sont rejouables sur la voie d'entrée, précisément parce qu'elle est idempotente.

docs/adr/SHK-0002-argos-unifie-et-autonome.md


SHK-0003 — Deux moteurs, pas trois

Contexte

Ce manifeste a porté, sur talos, la note suivante :

src/ recouvre galahad/engine/src/. Le moteur existe en trois exemplaires — galahad, talos, hulysse — alors que le README de galahad promet « une image moteur, trois rôles ». C'est la dette structurelle n°1.

Elle était fausse, et un plan de fusion par git subtree en a découlé. Personne ne l'avait mesurée : trois répertoires portant les mêmes noms de fichiers avaient suffi à conclure.

La mesure, reproductible par scripts/mesure-divergence.mjs :

PaireFichiers partagésDivergence
taloshulysse1017 %
galahadtalos973 %
galahadhulysse971 %

Il n'y a pas trois exemplaires. Il y en a deux, et un troisième moteur différent.

talos et hulysse sont bien le même moteur : journal.js, ollama.js et telegram.js sont identiques à l'octet, tools.js ne diffère que par ses commentaires. Ce qui les sépare est fonctionnel, pas structurel — talos porte cron, heartbeat et le pont MCP vers radar ; hulysse porte goals et veille.

galahad est autre chose. Aucun de ses fichiers n'est identique à son homologue. Là où les deux autres appellent ollama.js, il appelle brain.js, agnostique au fournisseur. Il porte roles.js, skill-runner.js, integrations.js, jobs.js — que ni l'un ni l'autre n'a. Son agent-loop.js fait 47 lignes contre 105 et 96 : une session roulante par processus, là où les autres persistent des fils dans sessions.json avec compaction.

Et la promesse citée à l'appui de la note ne disait pas ce qu'on lui faisait dire. « Une seule image, trois rôles » désigne chef, guardian et traveler — trois personas de galahad, déjà livrés par roles.js en pure configuration :

A role is pure configuration: the same engine binary runs any of them.

Cette promesse est tenue, à l'intérieur de galahad. Elle n'a jamais porté sur talos ni hulysse.

Décision

La convergence porte sur talos et hulysse, et sur eux seuls. Ils deviennent un moteur unique à deux rôles — exactement le motif que galahad a déjà éprouvé avec roles.js : cron, heartbeat et le pont MCP d'un côté, goals et veille de l'autre, deviennent des capacités de rôle et non deux forks. Les trois fichiers identiques à l'octet cessent d'exister en double le jour où la fusion est faite.

galahad ne fusionne pas. À 73 % et 71 %, ce ne serait pas une fusion mais une réécriture, et elle détruirait ce qui fait sa valeur propre — l'agnosticisme au fournisseur, le skill-runner qui porte cet audit même, les rôles, les jobs. Le programme assume deux moteurs : l'un agnostique et outillé, l'autre lié à Ollama et multi-fils.

Aucune duplication ne s'affirme plus sans être chiffrée. Une déclaration de divergence dans fleet.yml porte sa mesure, son chemin et sa date. Le chiffre est reproductible par scripts/mesure-divergence.mjs, qui compte par plus longue sous-séquence commune — la seule mesure indépendante de l'ordre des arguments.

Signal d'audit

Une opinion écrite dans un manifeste finit par être lue comme un fait, puis par fonder un plan. C'est ce qui vient de se produire, et c'est ce que ce contrôle empêche de recommencer.

Portée

Cette ADR n'exécute pas la fusion de talos et hulysse. Ce sont deux agents en service sur le VPS, sous systemd ; leur convergence est un travail de code à mener avec ses tests de vie, pas un effet de bord documentaire.

Elle ne dit rien du protocole MCP talos ↔ radar, qui reste à reconstituer depuis radar-mcp/test-client.mjs. C'est un prérequis à la fusion : mcp.js doit devenir une capacité de rôle, et on ne déplace pas ce qu'on ne sait pas décrire.

Elle ne révise pas la promesse de galahad. Elle est tenue.

docs/adr/SHK-0003-deux-moteurs-pas-trois.md