ultradoc — répondre aux questions à partir de la source, pas de la mémoire
ultradoc répond à des questions ultra-précises sur un projet open source en récupérant des preuves fondées et en raisonnant dessus. Le moteur déterministe (scripts/ultradoc.mjs, Node sans dépendance) effectue la recherche et l'indexation avec du code ; votre travail consiste à lire les preuves récupérées et à rédiger une réponse précise et citée. Chaque affirmation doit pointer vers une source réelle. Ceci est appliqué : ultradoc check échoue si une citation ne correspond pas à une preuve récupérée.
La règle fondamentale : ne répondez pas à partir de votre propre connaissance de la bibliothèque. Vos données d'entraînement sont obsolètes et hallucinent des API. Répondez uniquement à partir des preuves que
ultradocrécupère du dépôt réel, des issues, des PRs, de la documentation et du web. Si les preuves ne couvrent pas le sujet, dites-le et récupérez-en plus — ne devinez jamais.
Le script
Un bundle unique et validé, sans dépendance : node scripts/ultradoc.mjs <commande>. Pas de npm install, pas de clés API. Exécutez --help pour voir toutes les fonctionnalités. Commandes clés :
ask --repo <url|chemin> --q "<question>" [--sources ...] [--package <p>] [--semantic] [--docs-url <u>]Clonez (n'importe quelle URL git, mise en cache dans/tmp/ultradoc/<slug>), indexez, récupérez à partir de toutes les sources sélectionnées, et écrivez un dossier de preuves (EVIDENCE.md,evidence.json,meta.json) dans un dossier d'exécution — persistant à côté du clone sous<clone>/.ultradoc/runs/<id>(un emplacement stable lié à un commit, réutilisé pour plusieurs questions), sauf si vous passez--out. Sources par défaut :code,issues,prs,docs(ajoutezweb,solorsque le dépôt seul ne suffit pas ; ajoutezreleases,historypour les questions "quand X a-t-il été ajouté/modifié", etdiscussionspour les questions/réponses communautaires — nécessite la gh CLI). Dans un monorepo,--package <nom|dossier>restreint la récupération du code/docs à un seul espace de travail.code|issues|prs|docs|releases|history|discussions|so --repo <...> --q "..."— explorez UNE source, affichez les preuves sur stdout (pas de dossier). Utilisez ces commandes pour approfondir un domaine restreint.historyexécute git pickaxe (log -S/-G) sur le clone — le premier appel sur un dépôt distant récupère tout l'historique une fois.web --repo <...> [--q "..."] [--url <u,...>]— découverte web sans clé (SearXNG → DuckDuckGo → votre WebSearch) + récupération/extraction. Passez--urlpour ancrer une page spécifique que vous avez trouvée avec votre propre WebSearch.overview --repo <...> [--refresh]— générez (une fois) un résumé markdown mis en cache du dépôt : ce qu'il est, ses espaces de travail, sa disposition, son API publique et sa carte de documentation. Mis en cache à côté du clone et réutilisé tant que le commit n'a pas changé — lisez-le pour vous orienter à travers plusieurs questions sans réindexer. C'est une carte de navigation, PAS une preueueueueueueuveueueueueueueueueueueueueueueueueueueueueueueueueu citable.doc --repo <...> [--package <p>] [--sources ...]— échafaudez une documentation de référence fondée : un plan de sections déterministe (aperçu, installation, API publique/par package, configuration, architecture), un dossier récupéré par section fusionné en un seulevidence.json, et une liste de travailDOC.todo.md. Vous écrivez le texte cité dansDOC.md;checkle valide comme une réponse. Persistant sous<clone>/.ultradoc/doc/. Voir "Générer une documentation" ci-dessous.check --run <dossier-exécution>— validez les citations deANSWER.md(ou d'une exécutiondocdeDOC.md) par rapport auevidence.jsondu dossier. Code de sortie non nul ⇒ non fondé.--answer <fichier>valide un fichier spécifique.index --repo <...>— construisez/affichez l'index structurel (débogage/inspection) ; liste les packages d'espace de travail découverts pour un monorepo.semantic up|down|status— backend vectoriel local optionnel (voir ci-dessous).
Flux de travail
Vous possédez cette tâche de bout en bout : renvoyez une réponse fondée et citée, et ne rendez jamais un dossier à moitié récupéré. Mais le travail de récupération et de vérification est un ensemble d'appels indépendants et quasiment gratuits — parallélisez-le lorsque votre environnement le permet (regroupez les explorations indépendantes dans un seul message ; répartissez-les sur des sous-agents ou un workflow si disponible) et faites-le en ligne sinon. Itérez par rounds jusqu'à ce que les preuves soient complètes ; ne revenez pas avant. Voir references/orchestration.md.
-
Résolvez la cible. Identifiez le projet et la question précise. Si vous n'avez qu'un nom, trouvez l'URL du dépôt canonique (utilisez votre WebSearch, ou demandez à l'utilisateur si ambigu). Notez la version/branche qui intéresse l'utilisateur (
--ref).Plusieurs questions sur le même dépôt ? Exécutez
overview --repo <url>une fois et lisez leOVERVIEW.mdmis en cache qu'il affiche : il cartographie le dépôt (packages, disposition, API publique, docs) afin que les questions suivantes réutilisent le même clone+index sans se réorienter. Ne le citez jamais — c'est une navigation, pas une preuve.Monorepo ? Si
ask/index/overviewsignale des packages d'espace de travail (par exemplesocialgouv/code-du-travail-numerique→@cdt/frontend,@socialgouv/modeles-social, …), choisissez le package dont le nom/dossier correspond au sous-système concerné par la question et ajoutez--package <nom|dossier>pour que la récupération ne se noie pas dans les autres packages. Si aucun nom de package ne correspond clairement, exécutez d'abord unasksans portée, voyez dans quel package les meilleurs résultats se regroupent, puis réexécutez avec portée sur celui-ci. Un nom de package inconnu échoue bruyamment et liste ce qui existe. -
Récupérez. D'abord, pensez comme un développeur et dérivez 2–3 variantes de requête pour la question — le moteur cherche littéralement, donc le choix des mots est important :
- la formulation en langage naturel ("retry backoff"),
- les formes d'identifiants que la base de code utilise probablement (
retryBackoff,retry_backoff,MAX_RETRIES), - le message d'erreur littéral, le nom de l'option ou du drapeau si l'utilisateur en a cité un.
Question en plusieurs parties ? Divisez-la en sous-questions maintenant — chacune a besoin de ses propres preuves ou d'un "inconnu" explicite à la fin. Suivez la couverture par sous-question.
Le moteur gère déjà les pluriels et les accents ("retries"/"retry", "délai"/"delai"), divise les identifiants en sous-jetons, et favorise les fichiers nommés d'après un mot-clé — donc utilisez vos variantes pour synonymes et identifiants ("heartbeat" vs
ping, "pool" vsconnectionLimit), pas pour des inflexions du même mot. Et sachez quand la recherche lexicale sera limitée : elle a besoin de mots qui apparaissent littéralement dans le dépôt. Pour les questions conceptuelles ou "pourquoi a-t-il été conçu ainsi", privilégiezdocs,discussions,web(ou--semantic) au lieu de vous attendre à ce quecodefournisse la réponse.Exécutez
askavec la meilleure variante et les sources qui conviennent :node scripts/ultradoc.mjs ask --repo <url> --q "<question précise>" --sources code,issues,prs,docsultradoc découvre automatiquement l'URL officielle de la documentation du projet à partir de ses propres README/manifestes (et privilégie l'arborescence canonique dans le dépôt
docs/), puis l'utilise comme base — passez--docs-url <url>uniquement pour la remplacer. Ajoutezweb,solorsque la question est conceptuelle ou que le dépôt est peu fourni ; ajoutezreleases,historylorsqu'il s'agit du quand/pourquoi/quelle version quelque chose a changé. La commande affiche le chemin du dossier. Ensuite, traitez les variantes restantes × sources d'exploration comme un éventail — émettez ces explorations indépendantes en tant qu'appels parallèles dans un seul message (ou un sous-agent par cellule). Voirreferences/orchestration.md. -
Lisez le dossier. Ouvrez
EVIDENCE.mddans le dossier d'exécution. Chaque élément a un identifiant ([E1],[E2], …), une référencerefde provenance, et un extrait. Ce sont vos preuves — lisez le texte réel du code/issue/PR/doc. -
Approfondissez les lacunes. Une sous-question est mince lorsqu'elle a moins d'environ 2 éléments pertinents, ou qu'aucun élément ne contient réellement le symbole/comportement demandé. N'attendez pas qu'un dossier paraisse mince pour explorer les variantes — exécutez les explorations de variantes en parallèle dès le début (les explorations sont quasiment gratuites : le clone et l'index sont mis en cache). Répartissez-les sur toutes les sources :
code --repo <...> --q "<symbole ou comportement>"pour obtenir plus de régions de code.issues/prspour lire les discussions connexes et les changements en cours.releases(changelog + notes de version) ethistory(git pickaxe) lorsque la question porte sur le quand/pourquoi/quelle version quelque chose a changé.discussionspour les questions/réponses communautaires et les fils de conception (nécessite la gh CLI).web(ou votre WebSearch →web --url <u>) pour les références externes. Suivezreferences/retrieval-playbook.mdpour savoir comment itérer etreferences/orchestration.mdpour savoir comment exécuter les explorations en parallèle.
Triez avant d'écrire. La récupération est orientée rappel, donc le dossier contiendra des éléments hors sujet qui partagent simplement des mots-clés. Le test : un élément concerne la question seulement si son extrait nomme le symbole/comportement demandé ou décrit le même mécanisme — partager un mot-clé ne suffit pas. Listez les identifiants de preuves qui réussissent ce test et ignorez le reste — un élément hors sujet ne doit pas être cité simplement parce qu'il existe. Si après tri, moins d'environ 2 éléments soutiennent l'affirmation principale, revenez en arrière et récupérez plus de preuves.
Re-questionnez au lieu de relire. Si les 3 premiers éléments de code sont hors sujet, ne continuez pas à lire la liste — réexécutez
code --qavec la variante suivante en forme d'identifiant de l'étape 2. Deux dossiers hors sujet consécutifs signifient que la formulation est mauvaise, pas que le dépôt manque de réponse.Bouclez jusqu'à épuisement. Explorez par rounds (limite ~3). Arrêtez-vous lorsqu'un round ne produit aucune nouvel élément de preuve pertinent, ou que chaque sous-question a ≥2 éléments de soutien — puis triez et écrivez. Une sous-question encore non étayée après la limite est un "inconnu" explicite, jamais comblée à partir de la mémoire.
-
Rédigez la réponse. Créez
ANSWER.mddans le même dossier d'exécution. Soyez précis et concis. Citez chaque affirmation factuelle avec l'identifiant de la preuve sur laquelle elle repose, par exempleLes retentatives utilisent un backoff exponentiel avec jitter [E1], et la PR #79 réécrit ceci [E7].Voirreferences/citation-format.md. Ancrez la réponse au commit indiqué dansmeta.jsonlorsque la version est importante. Couvrez chaque sous-question de l'étape 2 ; signalez tout ce que les preuves ne tranchent pas comme "inconnu" explicite — ne le comblez pas à partir de la mémoire. -
Validez (deux niveaux).
- Structurel :
node scripts/ultradoc.mjs check --run <dossier-exécution>. Il échoue sur toute citation qui ne correspond pas à une preuve, ou sur une réponse sans citations. Corrigez et réexécutez jusqu'à ce qu'il réussisse. - Sémantique (vérification contradictoire de soutien) :
node scripts/ultradoc.mjs verify --run <dossier-exécution>écrit une liste de travail affirmation↔preuve (VERIFY.todo.json+VERIFY.md). Jugez chaque paire en sceptique : par défaut, considéreznon soutenu/réfutéà moins que l'extrait cité ne soutienne littéralement l'affirmation, en définissant leverdictsur soutenu · partiel · réfuté · non soutenu (+ une courte note). Exécutez un sceptique par paire — répartissez sur des sous-agents lorsqu'ils sont disponibles (chacun retourne son verdict), sinon jugez chaque paire en ligne — et collectez chaque verdict dans un seulverdicts.json(voirreferences/orchestration.md), puis :
Cela échoue sur les éléments en suspens/sans source (structurel) et sur toute affirmation réfutée ou non soutenue — comblant ainsi l'écart où une citation correspond mais ne soutient pas réellement l'affirmation. Corrigez l'affirmation (re-citez, affaiblissez, supprimez ou récupérez un meilleur élément) et revérifiez jusqu'à ce qu'il réussisse. Auto-évaluez-vous également par rapport ànode scripts/ultradoc.mjs verify --apply verdicts.json --run <dossier-exécution> node scripts/ultradoc.mjs check --semantic --run <dossier-exécution>references/answer-rubric.mdpour la complétude/l'actualité/les inconnus.
- Structurel :
-
Présentez. Donnez à l'utilisateur la réponse fondée avec ses citations et liens (fichier:ligne, numéros d'issue/PR, URL de doc/SO/web provenant des preuves), et le commit sur lequel elle a été vérifiée.
Générer une documentation
Lorsque l'utilisateur souhaite une documentation pour tout le projet (ou tout le package) plutôt qu'une seule réponse, utilisez doc — c'est la même boucle fondée, répartie sur un plan de sections :
- Échafaudez.
node scripts/ultradoc.mjs doc --repo <url> [--package <p>]. Le moteur construit un plan déterministe (aperçu, installation/utilisation, API publique ou une section par package d'espace de travail, configuration, architecture), récupère un dossier par section, les fusionne en un seulevidence.jsonavec des identifiants globaux[E#], et écritDOC.todo.md(la liste de travail par section) +DOC.plan.json. Ajoutez--sources code,docs,issues,prspour fonder les sections sur plus que le code+docs. Il persiste sous<clone>/.ultradoc/doc/. - Écrivez chaque section. Lisez
DOC.todo.mdetEVIDENCE.md, puis écrivezDOC.mddans le dossier d'exécution : une section par entrée du plan, chaque affirmation citée[E#]. Une section dont les preuves sont minces est une unité d'exploration — approfondissez-la (code|docs|issues …) ou marquez la lacune comme un "inconnu" explicite ; n'écrivez jamais de mémoire. Le travail par section se parallélise — voirreferences/orchestration.md. - Validez et présentez.
node scripts/ultradoc.mjs check --run <doc-dir>(etverify+check --semanticpour la vérification de soutien, exactement comme à l'étape 6 — les deux détectent automatiquementDOC.md). Corrigez jusqu'à ce que ce soit fondé, puis présentezDOC.mdancré à son commit.
Mode sémantique optionnel (entièrement local, sans clé API)
La recherche déterministe de niveau 1 (ripgrep + index de symboles) est le défaut et ne nécessite rien. Pour les questions plus floues ou conceptuelles, vous pouvez activer la recherche sémantique locale :
node scripts/ultradoc.mjs semantic up # docker compose : Qdrant + Ollama (+ SearXNG)
node scripts/ultradoc.mjs ask --repo <url> --q "..." --semantic
Tout s'exécute dans des conteneurs Docker locaux — pas de clé, aucune donnée ne quitte la machine. Si la pile n'est pas opérationnelle, --semantic enregistre un avis et revient au niveau 1. Voir references/semantic-setup.md.
Références
references/orchestration.md— comment paralléliser les explorations de récupération et la vérification entre appels/sous-agents, avec les contrats de retour + d'assemblage de verdicts et la solution de repli séquentiel.references/retrieval-playbook.md— comment choisir les sources et itérer jusqu'à une réponse complète.references/citation-format.md— la grammaire de citation quecheckapplique.references/answer-rubric.md— l'auto-évaluation sémantique avant de présenter.references/provider-apis.md— comment les issues/PRs sont récupérées par hôte, sans clé.