ultradoc — responda perguntas a partir da fonte, não da memória
ultradoc responde perguntas ultra-precisas sobre um projeto open-source recuperando evidências fundamentadas e raciocinando sobre elas. O mecanismo determinístico (scripts/ultradoc.mjs, Node sem dependências) faz a busca e indexação com código; seu trabalho é ler as evidências recuperadas e escrever uma resposta precisa e citada. Cada afirmação deve apontar para uma fonte real. Isso é imposto: ultradoc check falha se alguma citação não for resolvida para uma evidência recuperada.
A regra central: não responda a partir do seu próprio conhecimento da biblioteca. Seus dados de treinamento estão desatualizados e alucinam APIs. Responda apenas a partir das evidências que o
ultradocrecupera do repositório real, issues, PRs, documentação e web. Se a evidência não cobrir o assunto, diga isso e recupere mais — nunca adivinhe.
O script
Um pacote único e sem dependências: node scripts/ultradoc.mjs <comando>. Sem npm install, sem chaves de API. Execute --help para ver a superfície completa. Comandos principais:
ask --repo <url|caminho> --q "<pergunta>" [--sources ...] [--package <p>] [--semantic] [--docs-url <u>]Clone (qualquer URL git, armazenado em cache em/tmp/ultradoc/<slug>), indexe, recupere de todas as fontes selecionadas e escreva um dossiê de evidências (EVIDENCE.md,evidence.json,meta.json) em uma pasta de execução — persistida ao lado do clone em<clone>/.ultradoc/runs/<id>(um lar estável, fixado ao commit e reutilizado entre perguntas), a menos que você passe--out. Fontes padrão:code,issues,prs,docs(adicioneweb,soquando o repositório sozinho não responder; adicionereleases,historypara perguntas "quando X foi adicionado/alterado", ediscussionspara Q&A da comunidade — precisa do gh CLI). Em um monorepo,--package <nome|dir>define o escopo da recuperação de código/doc para um pacote do workspace.code|issues|prs|docs|releases|history|discussions|so --repo <...> --q "..."— aprofunde-se em UMA fonte, imprima evidências na saída padrão (sem dossiê). Use estes para expandir uma área superficial.historyexecuta git pickaxe (log -S/-G) no clone — a primeira chamada em um repositório remoto busca o histórico completo uma vez.web --repo <...> [--q "..."] [--url <u,...>]— descoberta web sem chave (SearXNG → DuckDuckGo → sua WebSearch) + busca/extração. Passe--urlpara fundamentar uma página específica que você encontrou com sua própria WebSearch.overview --repo <...> [--refresh]— gere (uma vez) um resumo markdown em cache do repositório: o que é, seus pacotes do workspace, layout, API pública e mapa de documentação. Em cache ao lado do clone e reutilizado enquanto o commit não mudar — leia-o para se orientar em várias perguntas sem reindexar. É um mapa de navegação, NÃO uma evidência citável.doc --repo <...> [--package <p>] [--sources ...]— crie um esqueleto para um documento de referência fundamentado: um esboço de seção determinístico (visão geral, instalação, API pública/por pacote, configuração, arquitetura), um dossiê recuperado por seção mesclado em um únicoevidence.json, e uma lista de tarefasDOC.todo.md. Você escreve a prosa citada emDOC.md;checka valida como uma resposta. Persistido em<clone>/.ultradoc/doc/. Veja "Gerar uma documentação" abaixo.check --run <dir-dossie>— valide as citações doANSWER.md(ou de uma execuçãodocdoDOC.md) contra oevidence.jsondo dossiê. Saída não-zero ⇒ sem fundamentação.--answer <arquivo>valida um arquivo específico.index --repo <...>— construa/imprima o índice estrutural (depuração/inspeção); lista os pacotes do workspace descobertos em um monorepo.semantic up|down|status— backend vetorial local opcional (veja abaixo).
Fluxo de trabalho
Você é dono desta tarefa do início ao fim: retorne uma resposta fundamentada e citada, e nunca devolva um dossiê parcialmente recuperado. Mas o trabalho de recuperação e verificação é um conjunto de chamadas independentes e quase gratuitas — paralelize-as quando seu ambiente permitir (agrupe as perfurações independentes em uma mensagem; distribua para subagentes ou um fluxo de trabalho se disponível) e faça inline caso contrário. Itere em rodadas até que as evidências estejam completas; não retorne até que estejam. Veja references/orchestration.md.
-
Resolva o alvo. Identifique o projeto e a pergunta precisa. Se você só tiver um nome, encontre a URL canônica do repositório (use sua WebSearch, ou pergunte ao usuário se ambíguo). Observe qualquer versão/branch que o usuário se importe (
--ref).Várias perguntas sobre o mesmo repositório? Execute
overview --repo <url>uma vez e leia oOVERVIEW.mdem cache que ele imprime: ele mapeia o repositório (pacotes, layout, API pública, documentação) para que perguntas de acompanhamento reutilizem o mesmo clone+índice em vez de se orientar do zero. Nunca cite-o — é navegação, não evidência.Monorepo? Se
ask/index/overviewrelatar pacotes do workspace (ex.:socialgouv/code-du-travail-numerique→@cdt/frontend,@socialgouv/modeles-social, …), escolha o pacote cujo nome/diretório corresponda ao subsistema sobre o qual a pergunta é e adicione--package <nome|dir>para que a recuperação não se afogue nos outros pacotes. Se nenhum nome de pacote corresponder obviamente, execute umasksem escopo primeiro, veja em qual pacote os principais resultados se agrupam, então execute novamente com escopo para ele. Um nome de pacote desconhecido falha ruidosamente e lista o que existe. -
Recupere. Primeiro, pense como um desenvolvedor e derive 2–3 variantes de consulta para a pergunta — o motor busca literalmente, então a formulação importa:
- a formulação em linguagem natural ("retry backoff"),
- as formas de identificador que a base de código provavelmente usa (
retryBackoff,retry_backoff,MAX_RETRIES), - a mensagem de erro literal, nome de opção ou flag se o usuário citou uma.
Pergunta de múltiplas partes? Divida-a em sub-perguntas agora — cada uma precisa de sua própria evidência ou de um "desconhecido" explícito no final. Acompanhe a cobertura por sub-pergunta.
O motor já dobra plurais e acentos ("retries"/"retry", "délai"/"delai"), divide identificadores em subtokens, e promove arquivos nomeados após uma palavra-chave — então gaste suas variantes em sinônimos e identificadores ("heartbeat" vs
ping, "pool" vsconnectionLimit), não em flexões da mesma palavra. E saiba quando a busca lexical será superficial: ela precisa de palavras que literalmente apareçam no repositório. Para perguntas conceituais ou "por que foi projetado assim", comece comdocs,discussions,web(ou--semantic) em vez de esperar quecodecarregue a resposta.Execute
askcom a melhor variante e as fontes que se encaixam:node scripts/ultradoc.mjs ask --repo <url> --q "<pergunta precisa>" --sources code,issues,prs,docsultradoc descobre automaticamente a URL oficial da documentação do projeto a partir de seus próprios README/manifestos (e prioriza a árvore
docs/canônica no repositório), então fundamenta contra ela — passe--docs-url <url>apenas para sobrescrever. Adicioneweb,soquando a pergunta for conceitual ou o repositório for esparso; adicionereleases,historyquando for sobre quando/por que/qual versão algo mudou. O comando imprime o caminho do dossiê. Em seguida, trate as variantes restantes × fontes de perfuração como uma expansão — emita essas perfurações independentes como chamadas paralelas em uma mensagem (ou um subagente por célula). Vejareferences/orchestration.md. -
Leia o dossiê. Abra
EVIDENCE.mdna pasta de execução. Cada item tem um id ([E1],[E2], …), uma referênciarefde proveniência e um trecho. Esta é sua evidência — leia o texto real do código/issue/PR/doc. -
Aprofunde-se nas lacunas. Uma sub-pergunta está superficial quando tem menos de ~2 itens no tópico, ou nenhum item contém realmente o símbolo/comportamento perguntado. Não espere até que um dossiê pareça superficial para perfurar as variantes — execute as perfurações das variantes em paralelo desde o início (perfurações são quase gratuitas: o clone e o índice estão em cache). Distribua-as entre as fontes:
code --repo <...> --q "<símbolo ou comportamento>"para puxar mais regiões de código.issues/prspara ler discussões relacionadas e mudanças em andamento.releases(changelog + notas de lançamento) ehistory(git pickaxe) quando a pergunta for quando/por que/qual versão algo mudou.discussionspara Q&A da comunidade e discussões de design (precisa do gh CLI).web(ou sua WebSearch →web --url <u>) para referências externas. Sigareferences/retrieval-playbook.mdpara como iterar ereferences/orchestration.mdpara como executar as perfurações em paralelo.
Triagem antes de escrever. A recuperação é orientada à revocação, então o dossiê conterá itens fora do tópico que apenas compartilham palavras-chave. O teste: um item diz respeito à pergunta apenas se seu trecho nomeia o símbolo/comportamento perguntado ou descreve o mesmo mecanismo — compartilhar uma palavra-chave não é suficiente. Liste quais ids de evidência passam nesse teste e ignore o resto — um item fora do tópico não deve ser citado só porque existe. Se após a triagem menos de ~2 itens apoiarem a afirmação central, volte e recupere mais.
Re-consulte em vez de reler. Se os 3 principais itens de código estiverem fora do tópico, não continue lendo a lista — execute novamente
code --qcom a próxima variante em forma de identificador do passo 2. Dois dossiês fora do tópico seguidos significam que a redação está errada, não que o repositório não tem a resposta.Faça um loop até secar. Perfure em rodadas (limite ~3). Pare quando uma rodada não trouxer novas evidências no tópico, ou quando cada sub-pergunta tiver ≥2 itens de apoio — então faça a triagem e escreva. Uma sub-pergunta ainda não suportada após o limite é um desconhecido explícito, nunca preenchido da memória.
-
Escreva a resposta. Crie
ANSWER.mdna mesma pasta de execução. Seja preciso e conciso. Cite cada afirmação factual com o id da evidência em que se baseia, ex.:As tentativas usam backoff exponencial com jitter [E1], e o PR #79 está reescrevendo isso [E7].Vejareferences/citation-format.md. Fixe a resposta ao commit mostrado emmeta.jsonquando a versão for importante. Cubra cada sub-pergunta do passo 2; sinalize qualquer coisa que a evidência não resolva como um desconhecido explícito — não a preencha da memória. -
Valide (duas camadas).
- Estrutural:
node scripts/ultradoc.mjs check --run <dir-dossie>. Ele falha em qualquer citação que não resolva para uma evidência, ou em uma resposta sem citações. Corrija e execute novamente até passar. - Semântico (verificação adversarial de suporte):
node scripts/ultradoc.mjs verify --run <dir-dossie>escreve uma lista de trabalho afirmação↔evidência (VERIFY.todo.json+VERIFY.md). Julgue cada par como um cético: por padrão,unsupported/refuteda menos que o trecho citado literalmente apoie a afirmação, definindoverdictpara supported · partial · refuted · unsupported (+ uma nota curta). Execute um cético por par — distribua para subagentes quando disponível (cada um retorna seu veredito), senão julgue cada par inline — e colete todos os vereditos em um únicoverdicts.json(vejareferences/orchestration.md), então:
Isso falha em coisas pendentes/sem fonte (estrutural) e em qualquer afirmação refutada ou não suportada — fechando a lacuna onde uma citação resolve mas não apoia realmente a afirmação. Corrija a afirmação (recite, enfraqueça, remova ou recupere um item melhor) e re-verifique até passar. Também faça uma auto-revisão contranode scripts/ultradoc.mjs verify --apply verdicts.json --run <dir-dossie> node scripts/ultradoc.mjs check --semantic --run <dir-dossie>references/answer-rubric.mdpara completude/atualidade/desconhecidos.
- Estrutural:
-
Apresente. Dê ao usuário a resposta fundamentada com suas citações e links (arquivo:linha, números de issues/PRs, URLs de documentação/SO/web da evidência), e o commit contra o qual foi verificada.
Gerar uma documentação
Quando o usuário quiser um documento de projeto inteiro (ou de pacote inteiro) em vez de uma resposta, use doc — é o mesmo loop fundamentado, expandido sobre um esboço de seção:
- Crie o esqueleto.
node scripts/ultradoc.mjs doc --repo <url> [--package <p>]. O motor constrói um esboço determinístico (visão geral, instalação/uso, API pública ou uma seção por pacote do workspace, configuração, arquitetura), recupera um dossiê por seção, mescla-os em um únicoevidence.jsoncom ids globais[E#], e escreveDOC.todo.md(a lista de trabalho por seção) +DOC.plan.json. Adicione--sources code,docs,issues,prspara fundamentar seções em mais do que código+documentação. Ele persiste em<clone>/.ultradoc/doc/. - Escreva cada seção. Leia
DOC.todo.mdeEVIDENCE.md, depois escrevaDOC.mdna pasta de execução: uma seção por entrada do esboço, cada afirmação citada[E#]. Uma seção cuja evidência é superficial é uma unidade de expansão — perfure-a (code|docs|issues …) ou marque a lacuna como um desconhecido explícito; nunca escreva da memória. O trabalho por seção é paralelizável — vejareferences/orchestration.md. - Valide & apresente.
node scripts/ultradoc.mjs check --run <dir-doc>(everify+check --semanticpara a verificação de suporte, exatamente como no passo 6 — ambos detectamDOC.mdautomaticamente). Corrija até estar fundamentado, então apresenteDOC.mdfixado ao seu commit.
Modo semântico opcional (totalmente local, sem chave de API)
A busca determinística de Nível 1 (ripgrep + índice de símbolos) é o padrão e não precisa de nada. Para perguntas mais difusas e conceituais, você pode ativar a busca semântica local:
node scripts/ultradoc.mjs semantic up # docker compose: Qdrant + Ollama (+ SearXNG)
node scripts/ultradoc.mjs ask --repo <url> --q "..." --semantic
Tudo roda em contêineres Docker locais — sem chave, sem dados saírem da máquina. Se a pilha não estiver ativa, --semantic registra um aviso e recai para o Nível 1. Veja references/semantic-setup.md.
Referências
references/orchestration.md— como paralelizar perfurações de recuperação e verificação entre chamadas/subagentes, com os contratos de retorno + montagem de veredito e o fallback sequencial.references/retrieval-playbook.md— como escolher fontes e iterar para uma resposta completa.references/citation-format.md— a gramática de citação que ocheckimpõe.references/answer-rubric.md— a auto-revisão semântica antes de apresentar.references/provider-apis.md— como issues/PRs são buscados por host, sem chave.
…
[truncado para tradução]