okf-hub
CLAUDE.md1 starsChanged 3 months agoApache-2.0View on GitHub
Serveur MCP donnant à des sessions Claude isolées un accès en lecture à des bases de connaissance markdown, et un moyen de les alimenter sans jamais les modifier directement. Tu es dans le dépôt du hub — le moteur. Les bases, elles, sont des dépôts séparés clonés dans bases/ (non versionnés ici). La spécification fait autorité. Elle est dans docs/, transcrite depuis la source du propriétaire. Si une évidence technique la contredit, ce n'est pas une raison de dévier :…
In this repository3 other files it gives its agents.
- kb-redepotSkill
- kb-review-lotSkill
- kb-reviewSkill
The file
Files
Contexte — OKF Bundle Hub
Serveur MCP donnant à des sessions Claude isolées un accès en lecture à des bases de connaissance markdown, et un moyen de les alimenter sans jamais les modifier directement.
Tu es dans le dépôt du hub — le moteur. Les bases, elles, sont des dépôts
séparés clonés dans bases/ (non versionnés ici).
Par où commencer
| Document | Quand le lire |
docs/SPEC-okf-bundle-hub-v0.md | La spécification. Elle fait autorité. Rév. 4.7 : chaque amendement est intégré section par section, son § 12 en donne la carte. Tous les renvois « § x.y » du code y renvoient. À lire avant toute modification de comportement. |
docs/ARCHITECTURE.md | Pourquoi le code est ce qu'il est : choix d'implémentation, mécanismes de correction, écarts assumés, traçabilité test ↔ exigence. |
docs/API.md | Contrat exact des huit outils kb_* : schémas, sorties, erreurs, séquences typiques. |
docs/J0-verification-okf.md | Ce que dit la spec OKF externe, et les trois points où elle diverge de celle du hub. |
README.md | Installation, connexion d'un client Claude, exploitation. |
skills/kb-review/SKILL.md | Le rôle gestionnaire : déroulé de revue imposé. |
skills/kb-review-lot/SKILL.md | Un gros lot sur plusieurs bases : répartition entre agents, décisions sur preuves, commits d'après résolution. |
skills/kb-redepot/SKILL.md | Redéposer des propositions sans hub connecté, par le vrai serveur en client MCP. |
Règles de travail sur ce dépôt
La spécification fait autorité. Elle est dans docs/, transcrite depuis la
source du propriétaire. Si une évidence technique la contredit, ce n'est pas une
raison de dévier : les principes du § 1 et les mécanismes du § 4.4.b doivent
être remontés au propriétaire avant implémentation — c'est écrit en clôture de
la spec, et deux écarts ont suivi cette procédure.
Les écarts assumés se recensent à un seul endroit. ARCHITECTURE.md,
section « Écarts assumés », avec motif, mesure et manière de les annuler. Un
écart introduit sans y figurer est un bug.
Ne pas affaiblir les tests de concurrence. test_fd_neuf_par_acquisition et
test_le_commit_ne_retire_aucun_fichier_du_tree gardent deux erreurs invisibles
en usage normal et destructrices en usage concurrent. Si l'un casse, c'est le
changement qui est faux, pas le test.
Jamais de YAML par templating de chaînes (§ 1.7). Tout frontmatter, tout
manifeste passe par yaml.safe_dump / safe_load. Les tests d'injection en
dépendent, et les invariants d'audit du § 6.2 aussi. Une seule exception, et
elle est un écart remonté au propriétaire : frontmatter.py fusionne dans un
frontmatter existant via le round-trip de ruamel.yaml, parce que réémettre
tout le bloc avec safe_dump reformatait les champs non ciblés et égarait les
parseurs mono-ligne des corpus (ARCHITECTURE.md § 5.4). Depuis le 2026-11-08
(décision du propriétaire), ruamel n'émet que les champs ciblés : le reste
du bloc est recopié de la source par lignes entières, aux bornes du composeur,
pour qu'une forme valide qu'il ne reproduit pas ({ by: x }, la notation
d'OKF) ne soit ni réécrite ni refusée. Rien d'autre n'utilise ruamel, et la
fusion ne tient que par sa garde : ce qui n'est pas vérifié fidèle — le texte
hors des champs ciblés, ligne à ligne, et la relecture de chaque valeur — est
refusé. Affaiblir la garde pour faire passer une revue, c'est rouvrir le
bug — le refus dit quoi corriger à la source.
Ce dépôt est public ; les bases de l'opérateur ne le sont pas. Aucun nom
de base privée, d'objet, de table, d'environnement ou d'organisation n'entre
dans un fichier versionné du hub — ni skill, ni doc, ni exemple, ni test. Une
leçon de revue propre à une base s'écrit dans la section « Revue des
propositions par le hub » de son AGENTS.md ; un exemple prend un nom neutre
(produit-x, installation-x, referentiel-x). Vu le 2026-10-13 : six
semaines de leçons avaient fait des skills le manuel de bases privées, publié ;
il a fallu réécrire l'historique. Trois gardes, sur les termes que
confidentialite.py déduit des bases installées et de private-terms
(hub-config.local.yaml, jamais versionné) : kb_propose refuse de les déposer
dans une base publique (okf-hub-feedback), les hooks de .githooks/ refusent
de les commiter ou de les pousser, tests/test_neutralite.py les cherche. Ne
jamais contourner un hook par --no-verify : expurger, puis recommiter. Les
hooks ne valent qu'activés (okf-hub setup), et l'identité git de ce dépôt
est l'adresse noreply — une adresse personnelle dans un auteur de commit est
une fuite comme une autre (le pre-push l'a attrapée le jour même).
Le code d'une base ne se lance que par okf-review. Ses
governance.checks, par verify sur une copie jetable de tout le hub, ou par
resolve --checks dans la base après les résolutions, pour une base que
l'opérateur a inscrite dans trusted-checks (spec rév. 4.3 et 4.4, § 8).
Jamais depuis le serveur MCP, jamais sur l'initiative d'une session
consommatrice.
Une nouvelle capacité d'écriture ne va pas dans tools/. La surface MCP
exposée aux sessions consommatrices se limite à kb_propose, confiné à
proposals/pending/. Ce qui touche au corpus vit dans review.py, invoqué en
ligne de commande. kb_proposal_status lit proposals/, et kb_search avec
include_pending lit proposals/pending/ (rév. 4.7) — les deux seules
exceptions à la liste d'exclusions du § 5.2, en lecture seule ; le confinement
passe par Base.proposal_files, pas par l'outil. Une troisième se remonte au
propriétaire de la spec.
Une base ne se versionne jamais dans bases/. gitops.commit_paths exécute
git -C <racine du bundle> : une base qui ne serait qu'un sous-répertoire du
dépôt du hub ferait qu'un kb_propose de n'importe quelle session commite sur
main du hub, sans erreur (vérifié, pas supposé) ; ignorée par git, elle casse
dans l'autre sens avec IO_ERROR. La source des bases livrées vit donc dans
bundles/, et bootstrap.py les installe en dépôts autonomes au démarrage.
Toute nouvelle base livrée s'ajoute à bundles/ et à server.META_BASES si
elle doit être annoncée dans les instructions. Si elle a un dépôt canonique,
elle s'ajoute aussi à bundles/upstreams.yaml : elle sera clonée et non semée,
sans quoi chaque machine s'en fabriquerait une histoire orpheline.
Une base clonée se corrige chez elle, jamais dans bundles/. Pour
okf-hub-guide, bundles/ fait autorité et la copie déployée s'y resynchronise.
Pour une base de upstreams.yaml (okf-hub-feedback), c'est l'inverse : sa
copie dans bundles/ n'est qu'une graine, que personne ne lit. Un changement de
code qui rend fausse une de ses affirmations se reporte par une proposition
correction déposée dans la base installée, puis résolue (skills/kb-review).
Vu le 2026-09-23 : 1871691 avait corrigé la graine, et pendant trois semaines
la base servie aux sessions a continué d'affirmer que kb_search était
mono-base. test_bases_meta.py ne l'aurait pas vu : il lit bundles/, et ne
contrôle que des noms d'outils et de paramètres, pas le sens des phrases.
Ce qui est écrit sur les outils ailleurs que dans leur description doit être
gardé par un test. Deux bases meta (okf-hub-guide, okf-hub-feedback)
décrivent le hub. tests/test_bases_meta.py lit les SCHEMA du code et échoue
si un corpus cite un outil inexistant, attribue un paramètre absent d'un schéma,
ou recopie la référence d'API. Il lit bundles/, pas bases/ : la CI part d'un
checkout neuf, où bases/ est vide. Sans ce garde-fou, la duplication dérive — et
c'est la copie que personne ne teste qui égare une session. server.META_BASES
ne fait que décider de leur annonce dans instructions ; aucun outil ne les
traite différemment, le hub tourne sans elles.
Le re-scan a un seul mécanisme, et un compteur par déclencheur.
HubServer._silent_rescan est le seul point de re-scan silencieux ;
_last_silent_rescan est un dict indexé par déclencheur (§ 4.4.c, rév. 4.2) —
un compteur commun laissait un kb_list étouffer le re-scan compensatoire
d'UNKNOWN_BASE, post-mortem en ARCHITECTURE.md § 5 bis. Un second
déclencheur se branche dans server.RESCAN_BEFORE, jamais dans un module de
tools/ — qui n'a ni le cooldown ni la session à notifier. C'est le mécanisme
que la rév. 4.1 interdit de dupliquer. Le processus okf-hub web, qui n'a pas
de session MCP, réutilise ce même mécanisme sous le déclencheur web, câblé
dans __main__.py : il n'en tient pas un second.
La consultation n'écrit rien, et n'a qu'un rendu. lecture/ et web/
(rév. 4.5, § 5 bis) lisent les bases sans les modifier — pas même un verrou
d'index git — et tests/test_lecture.py, tests/test_web.py le vérifient sur
git status. Tout document se rend par lecture/rendu.py : un second rendu
divergerait. La limite d'imbrication de markdown-it n'y redescend jamais : à sa
valeur par défaut, le parseur perd en silence la fin des documents profonds.
Le travail bloquant passe par anyio.to_thread.run_sync. Un subprocess git
ou ripgrep appelé directement dans un handler sérialiserait toutes les requêtes
de l'instance.
Vérifier avant de conclure
uv run pytest -q # 668 tests, dont la boucle de stress
uv run pytest -q -m "not slow" # sans le test deux processus × 25 itérationsQuatre tests d'test_end_to_end.py sont ignorés si le dépôt voisin
okf-bundle-template est absent : c'est attendu, pas une régression.
Un changement de comportement d'outil se vérifie aussi de bout en bout :
tests/test_end_to_end.py et tests/test_boucle_contribution.py pilotent un
vrai serveur en stdio avec le SDK client officiel. Le second porte le critère
d'acceptation de la rév. 4.1 : contribution → revue → consultation du verdict
sans aucun accès git côté contributeur.
Ce que ce dépôt ne contient pas
- Les bases.
bases/est ignoré par git : chaque base est un dépôt à part, importé pargit clone <url> bases/<nom>. Seule la source des bases livrées avec le hub est versionnée, dansbundles/. - Le template de bundle. Livrable distinct, publié sur GitHub et non monté dans le devcontainer. Une modification qui lui revient ne peut donc pas être appliquée ici : la livrer en patch, avec sa procédure, et la retirer du dépôt une fois appliquée en amont.
- Les corpus. Le hub ne connaît que des chemins ; il n'a aucune opinion sur le contenu, et n'implémente aucune validation de conformité OKF.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

