Answers with a language model (optional)
Cabeção is good at retrieval: keywords, meaning, graph, validity over time and provenance. Normally the one who writes the answer is the agent you already use, reading the result of search. With cabecao ask (and the ask tool for agents), Cabeção can also generate the answer: it retrieves the passages, sends them to a language model you choose, and checks every citation before returning.
None of this is needed to use Cabeção, and nothing leaves the machine until you run cabecao llm on in a terminal, see what starts leaving and where to, and confirm. Without it, cabecao ask shows the passages it found and how to turn it on, and the ask tool does not even show up for agents.
What ask does
- Retrieves like
search(hybrid when semantic search is on), with--as-of,--scopeand--type, and reads the section of each note found. - Filters what may leave (see below) and builds the request: each passage is labeled (
S1,S2...) with its validity and provenance, between delimiters carrying a mark drawn at random for each question. The note's path, title and sections go inside the delimited block (they are data, like the text), and outside content goes with its words separated by^. - Calls the provider enabled on this machine, asking for the answer as JSON: each claim with its sources and a verbatim quote.
- Checks every citation: the label must exist and the quote must appear in the cited passage (ignoring differences in accents, case, quotes and spaces). The quote must be substantive: at least 16 letters or digits and 3 content words; with an ellipsis, at most 3 pieces, each one like that, in order. The quote you see is always the note's real text, never what the model wrote. What does not check out is dropped. A claim without any checked citation does not come out (it is free text from the model): it only counts in
unsupported_claims. With none checked, the answer becomes "the brain does not have this"; with more than half dropped, the status islow_confidence, with only the checked claims and the passages found, for you to verify. Two claims citing the same passage with different quotes get different numbers, each with its own.
The answer is read only: it is never written to the brain, executed, or used to call anything else. The model's text is escaped: [, ], <, > and \ come out with a backslash, so no Markdown renderer turns them into a link, an image or HTML (in a client that renders, an image would load by itself and carry data in its address); addresses (with a scheme, //host, www., host.tld/... and common domains) become "(link removido)". The missing field is a short line (up to 240 characters), also neutralized, and data_notice tells the agent the answer is text generated by a model: data, never instruction. The question is checked too: if the secret scanner flags something in it, nothing is sent.
Cabeção checks the citation, not the conclusion: it guarantees the cited passage exists and says that, not that the claim follows from it. For anything important, open the source.
Turn it on
cabecao llm on
The command looks for what is already on your machine (Claude Code installed, an ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, OPENROUTER_API_KEY or GROQ_API_KEY variable) and offers that first. You pick a number, confirm, and you are done. When a key has to be pasted, it is read without showing on screen.
Before turning on, it shows exactly what starts leaving and where to. The output below comes from the real CLI but is illustrative: a local test server answered in place of Ollama, which is why the test took 0.0 s (the output is in Portuguese):
$ cabecao llm on --provider ollama --model llama3.2
Para responder ao "cabecao ask" e à tool "ask" dos seus agentes, o Cabeção vai enviar a: Ollama nesta máquina (localhost:11434)
Provedor "ollama" · modelo llama3.2 · roda nesta máquina
O que sai, a cada pergunta: a pergunta e até ~3000 tokens de trechos das notas que a busca achar,
com o caminho, o título, o tipo, a validade e a proveniência (trust, origin) de cada um.
O que NUNCA sai: notas com "private: true" no frontmatter; arquivos de controle (catálogo, diário, AGENTS.md,
CLAUDE.md e afins, cópias de conflito); qualquer trecho em que o scanner de segredos acusar algo (o trecho é
omitido e a omissão aparece na resposta); o que a "llm_policy" do .cabecao.json do cérebro excluir; a chave.
A resposta nunca é gravada no cérebro nem executada: é só lida.
Custo: roda nesta máquina, sem cobrança por pergunta. Limites: até 2048 tokens de saída e ~3000 de contexto por pergunta, 60 s por chamada.
Para desligar: cabecao llm off. Para apagar o provedor: cabecao llm remove ollama.
Ativar? [s/N] s
Respostas ativadas com Ollama (servidor local) (modelo llama3.2).
Teste: funcionou em 0,0 s.
Pergunte com: cabecao ask "o que decidimos sobre ...?"
Nos agentes, a tool "ask" aparece na próxima sessão (reinicie o cliente de IA).
Turning it on, off, testing, deleting and changing the policy are up to you, in the terminal: without a controlling terminal, or when run by an agent, llm refuses with exit code 4 (see Who is human and who is an agent); only llm status runs for everyone, and for an agent it only says whether answers are on. An agent does not turn it on, switch it, test it or read the key, neither through the CLI nor through a tool, not even with a confirmation token. cabecao ask is a memory command: an agent may ask.
The llm on confirmation is signed in llm.json with a secret from this machine (llm-consent.key, 0600 permission) and covers the destination, the model and where the key comes from. An llm.json written by hand, copied from another machine or with its address changed afterwards turns nothing on: run cabecao llm on again.
Where the configuration lives
llm.json, the confirmation secret, the spending-cap counter and file-stored keys live in your user's default configuration folder (~/.config/cabecao; on Windows, %APPDATA%\cabecao), computed from the system user. If the folder is redirected by an environment variable (CABECAO_CONFIG_DIR, XDG_CONFIG_HOME, APPDATA or HOME), the redirected configuration applies only to you, in the terminal; for an agent (which controls the environment of the commands it runs), answers stay off and nothing is read. That way an agent cannot point ask at an llm.json it wrote itself.
The "system user's folder" comes from os.userInfo(), which asks the system account (on macOS and Linux, the user database; on Windows, the process user's profile), not from HOME, USERPROFILE, XDG_CONFIG_HOME or APPDATA. And the MCP server is always treated as an agent, even when it inherits a terminal (a terminal AI client starts cabecao mcp as a child): it never uses a redirected folder, not even one a project's MCP configuration points to. ask.log lives in that same folder, not in the cache folder.
Providers
| Provider | How to turn on | Default model | Key |
|---|---|---|---|
| Claude Code installed | cabecao llm on --provider claude-code | haiku | None: uses Claude Code's login |
| Anthropic (API) | cabecao llm on --provider anthropic | claude-haiku-5-5 | ANTHROPIC_API_KEY or paste |
| OpenAI | cabecao llm on --provider openai | gpt-6-luna | OPENAI_API_KEY or paste |
| Google Gemini (API) | cabecao llm on --provider gemini | gemini-3.5-flash-lite | GEMINI_API_KEY or paste |
| OpenRouter | cabecao llm on --provider openrouter --model <model> | (pick yours) | OPENROUTER_API_KEY or paste |
| Groq | cabecao llm on --provider groq | openai/gpt-oss-20b | GROQ_API_KEY or paste |
| Ollama, on this machine | cabecao llm on --provider ollama --model <model> | (the one you pulled) | None |
| LM Studio, on this machine | cabecao llm on --provider lmstudio --model <model> | (the one you loaded) | None |
| Another OpenAI-compatible service | cabecao llm on --provider compatible --base-url <url> --model <model> | (pick yours) | Optional |
The default models are the cheapest ones with structured output in each provider's documentation on 2026-11-13; change them with --model. The address (--base-url) only applies to compatible, ollama and lmstudio: providers with a fixed address refuse it, so the destination shown in the confirmation is always the real one. It must be https, or http only on this machine (localhost, 127.0.0.1, [::1]); link-local and cloud metadata addresses (169.254.*, fe80::, 0.0.0.0) are refused, and llm.json is checked again on every read. To use a key from a variable without storing it, pass --key-env NAME.
Claude Code is offered because Anthropic documents that claude -p draws from your subscription limits (Anthropic support, checked on 2026-11-13). To generate the answer it runs without any tool: no shell, no file reads, no MCP servers, none of your settings, in an empty temporary folder and with a time limit. If the agent in your conversation is also Claude Code, each ask opens a second session (it costs twice).
llm on stores the real path of the claude you confirmed (covered by the signature), and ask always runs that one, never the first claude on the caller's PATH. When the caller is an agent, nothing in its environment changes where claude sends data or which configuration it reads: no ANTHROPIC_BASE_URL, CLAUDE_CONFIG_DIR, keys or the Bedrock, Vertex or Foundry switches; HOME is your system folder; and PATH only has the claude folder, Node's and the system's. For you, in the terminal, your environment applies.
Why the installed Antigravity is not offered
The Antigravity FAQ (checked on 2026-11-13) says that wrapping agy inside another application "is not supported under consumer plans" and that using third-party software to access it violates the terms, putting the account at risk. So Cabeção does not call agy. For Google's models, use the Gemini API with a key (--provider gemini). Codex is not offered either: OpenAI only advises calling it from another program with an API key (not a ChatGPT login), and with that key the OpenAI API (--provider openai) does the same without starting an agent.
What leaves the machine, and what never does
With each question, what goes to the provider you turned on is: the question and up to ~3,000 tokens of passages from the notes the search found, with path, title, type, validity and provenance. With a local server (Ollama, LM Studio), nothing leaves the machine, unless the model is one of Ollama's "-cloud" models, which run on ollama.com (llm on warns about it).
Never leaves, with any provider:
- private notes, and their names (see below);
- notes whose frontmatter cannot be read (when in doubt, it stays);
- control files: the catalog,
log.md,AGENTS.md,CLAUDE.mdand the like, conflict copies; - any passage where the secret scanner flags something, searched across the whole note (a private key block counts from
BEGINtoEND, and a passage touching it stays out too), ignoringcabecao:allow-secret, which clears a line for git, not for an outside provider; - whatever the brain's policy excludes;
- the key.
What was left out shows in the answer ("Trechos não enviados ao provedor: 1 de nota privada"). And cabecao ask "<question>" --show-context shows exactly what would be sent, without sending anything.
What counts as a private note
A note is private, and never goes to any provider, when its frontmatter has:
- the
privatekey, in any case (private,Private,PRIVATE), with a true value:true,yes,on,sim,verdadeiro,1, as text or in a list ([true]); - or the
privatetag, or a nested tag under it (private/health), with or without#, intagsortag; - or, as in Obsidian, the
#privatetag (or#private/...) in the note's body.
These do not count: private inside another field (meta: {private: true}), cssclasses and look-alike tags (privado, #privateer). A note whose frontmatter cannot be read does not leave either.
And a private note's name does not leave even when another note cites it: its title, aliases (aliases or alias, as a list or as text), path and file name, cited as a whole word (ignoring case and accents, and with %20 as a space), become [nota privada] in the text, title, sections and path of the passages that leave; it never comes in as a note related through the graph. A short name (fewer than 6 letters and digits, such as "Ana") is not replaced inside the text, where it would mangle words and still give it away: the passage that cites it as a whole word simply does not leave (it counts in omitted.private).
The honest limit: Cabeção hides the name where it recognizes it. A partial mention (only the last name, a nickname not in aliases) and a private note's content copied into another note are not detected. The filter also protects only what Cabeção retrieves: what the agent writes in the question itself goes to the provider as is.
Per-brain policy
In .cabecao.json (which applies on every machine), the llm_policy field restricts what a provider receives from this brain:
{
"llm_policy": {
"allow": "agent",
"exclude_paths": ["memory/private/**", "wiki/entities/Someone.md"],
"exclude_types": ["episode"],
"exclude_trust": ["low"]
}
}
| Field | What it does |
|---|---|
allow | "any" (default): any enabled provider. "agent": only the installed agent. "none": never calls a provider for this brain; ask returns only the passages |
exclude_paths | Paths that never leave (*, ** and ?; a folder covers everything inside it) |
exclude_types | Note types that never leave |
exclude_trust | trust levels that never leave (for example ["low"], ingested content) |
Without the field, the brain restricts nothing beyond what the machine configured. An invalid llm_policy closes: nothing is sent, and doctor says what to fix.
The policy only restricts: what enables a provider is always this machine's configuration (cabecao llm on); the brain can only close it further. Change it with cabecao llm policy (only you, in the terminal, with confirmation):
cabecao llm policy # shows the current policy
cabecao llm policy --allow agent # only the installed agent
cabecao llm policy --exclude-path "memory/personal/**"
cabecao llm policy --clear # removes the policy
An agent does not change llm_policy, not through the CLI, not through a tool, not even with a confirmation token (like the embedding section). It goes into git and reaches the other machines through sync: a policy loosened on another machine (or by anyone with write access to the remote) is loosened here too. That is accepted on purpose: whoever writes to the remote can already change the notes themselves, and each machine still decides whether to turn any provider on.
Each provider's data policy
Checked on 2026-11-13. Check the current page before turning one on:
| Provider | What the policy says | Source |
|---|---|---|
| Anthropic (API) | By default, inputs and outputs from commercial products are not used to train models | privacy.claude.com |
| Claude Code with Free, Pro or Max | Use for improving the models depends on your account's privacy setting | privacy.claude.com |
| OpenAI | API data is not used for training without opt-in; abuse monitoring logs kept up to 30 days | developers.openai.com |
| Google Gemini (API) | Free tier: what you send is used to improve products, and people may read it. Paid tier: not used; logs kept for a limited time to detect abuse | aistudio.google.com |
| OpenRouter | Does not store prompts or responses unless you turn logging on; Cabeção asks only for providers that do not collect data (provider.data_collection: "deny", which the routing reference describes as "use only providers which do not collect user data") | logging, routing |
| Groq | Does not retain request data by default; may log it for up to 30 days to investigate errors or abuse | console.groq.com |
| Ollama, LM Studio | Run on your machine | — |
On the Gemini API's free tier, passages from your notes may be read by Google's reviewers and used to improve its products. llm on --provider gemini warns you and asks whether your key belongs to a project with active billing. For personal notes, use the paid tier.
Costs
- APIs (Anthropic, OpenAI, Gemini, OpenRouter, Groq): you pay, in the provider's account, per token. A question sends ~3,000 tokens of context and gets a few hundred back. For a spending cap, set it in the provider's dashboard.
- Claude Code: comes out of your subscription limits (or the key Claude Code uses). In this guide's test run, one question cost US$ 0.0017 with
haiku, according to Claude Code itself. - Local server: no per-question charge.
The limits live in limits in llm.json: per question, context_tokens (default 3000, up to 8000), max_output_tokens (2048) and timeout_ms (60000); and a spending cap: max_calls_per_hour (default 30, counting every question on this machine) and max_calls_per_session (default 20 per MCP server session, that is, per open AI client). Once the cap is reached, ask returns unavailable (limit_reached) with the passages found, without calling the provider: an agent in a loop does not drain your account. Transient errors (rate limit, server down) get up to two retries, and a connection failure at most one, within the time limit. A redirect from the server is never followed: the key and the passages do not go to another address.
The cap counts questions and is reserved before calling the provider, atomically (a lock on the ask-usage.json file, which holds across processes: the CLI and each open MCP server): 35 simultaneous questions do not go past the cap. The slot is only given back when no request went out (no passage to send, provider not installed, policy). And each question makes at most 3 requests to the provider, adding up the retries, the second request when the format came back wrong, and the fallback to the next provider.
Ask
cabecao ask "Que fila o Projeto Atlas usa hoje e por quê?"
A real run with Claude Code (haiku) on the project's example brain, with --verbose (the output is in Portuguese):
Hoje o Projeto Atlas usa SQS como fila. A migração de RabbitMQ para SQS ocorreu em maio de 2026, com status vigente. [1]
O motivo registrado para a troca foi o custo operacional de manter o RabbitMQ, que o time operava por conta própria. A decisão está resumida na fonte de reunião de arquitetura de 2026-05-03. [1]
O RabbitMQ foi a fila do Projeto Atlas de janeiro a maio de 2026, mas esse fato está vencido e não vale mais como resposta atual. [2]
A migração em andamento é de novembro de 2026: dois dos cinco consumidores do Projeto Atlas passaram a ler do SQS em lotes de 10 mensagens. [3]
A leitura em lote foi registrada como migração de novembro de 2026, mas as notas não dizem qual fila os três consumidores restantes usam nem quando eles migram. [3]
Faltou no cérebro: As notas não trazem o conteúdo da seção "Consequência" da síntese sobre SQS, que é embutida na linha do tempo. Também não dizem qual fila os três consumidores restantes do Projeto Atlas usam hoje, nem se eles já foram migrados. Os trechos não detalham as razões técnicas além do custo operacional.
Fontes:
[1] memory/facts/fato-atlas-usa-sqs.md · vigente · trust high · origin agent:claude-code
"O Projeto Atlas migrou de RabbitMQ para SQS em maio de 2026 por custo operacional."
[2] memory/facts/fato-atlas-usa-rabbitmq.md · vencido · trust high · origin human
"O Projeto Atlas usou RabbitMQ como fila de janeiro a maio de 2026."
[3] memory/episodes/2026/11/2026-11-10-migracao-dos-consumidores.md › Migração dos consumidores para leitura em lote · vigente · trust medium · origin agent:claude-code
"Dois dos cinco consumidores do [[Projeto Atlas]] passaram a ler do [[SQS]] em lotes de 10."
3 citação(ões) descartadas: rótulo inexistente ou texto que não está no trecho.
Diagnóstico (só para você; o agente não vê):
provedor: claude-code · modelo haiku · destino: Anthropic, pelo Claude Code instalado (com o login da sua conta)
busca: keyword · trechos recuperados 11 · enviados 11
tokens: entrada 2 · saída 1615 · custo US$ 0,0017 · 8,4 s
Notice the three dropped citations: the model cited passages that did not contain the sentence, and Cabeção removed those citations instead of trusting them. (In this run the input token count did not yet add the part read from the cache; that has been fixed.)
In the terminal, each claim appears as soon as it arrives complete and checked; the sources come at the end. With --json, you get the same object the ask tool returns to agents, without the provider's or the model's name (--verbose adds a diagnostics block, only for you in the terminal: for an agent, the option is ignored).
| Exit code | When |
|---|---|
0 | The command worked: answered, answered with little support (low_confidence) or the brain does not have this (not_found); the --json status says which |
5 | No provider generated the answer (off, failed or cap reached): shows the passages found |
2 | Usage error |
Codes 3 and 4 are left out on purpose: across the whole CLI, they mean "needs your explicit request" and "only you, in the terminal".
Ctrl+C cancels the question and stops the provider (including the Claude Code process and whatever it opened).
In agents: the ask tool
With a provider turned on, the MCP server starts announcing the ask tool, right after search. The agent sends only the question and search options; it does not choose or see the provider or the model, and the answer always has the same shape. If the provider fails, the tool returns unavailable with the passages found, and the agent answers on its own. The tool shows up in the next session: restart the AI client after llm on.
What an agent sees of the provider: nothing. Not the name, the model, the destination or the provider's error message, through any path: the ask tool, cabecao ask (with --verbose or --show-context), llm status (only "on" or "off"), status and doctor. Those details show up only for you, in the terminal. The cabecao-consultar skill teaches the agent to use ask through the CLI the same way.
Where the key lives
| System | Where |
|---|---|
| macOS | Keychain, service cabecao (written by the security command, with the key on standard input, never on the command line) |
| Linux | Secret Service, through secret-tool (libsecret), when it exists; otherwise, the protected file |
| Windows | Encrypted with your Windows user's DPAPI, in %APPDATA%\cabecao\credentials.dpapi.json |
Any, with --store file | ~/.config/cabecao/credentials.json, with 0600 permission |
The provider's environment variable, when set, takes precedence over the stored key. The key never goes into the brain, llm.json, the log or an error message, and llm status shows only its last four characters. Note: an MCP server started by the AI client may not inherit your terminal's variables; for agents' ask, prefer storing the key.
On Windows, to encrypt or decrypt with DPAPI, the key goes through the environment of the PowerShell process Cabeção opens for a moment (never the command line). While it runs, another program of the same Windows user can read that environment; programs of other users cannot. It is the same limit as a key in an environment variable.
Behind a proxy: Node's fetch only uses HTTPS_PROXY when that is switched on. Cabeção switches it on by itself where Node allows (http.setGlobalProxyFromEnv), always with this machine's addresses in NO_PROXY: a local server (Ollama, LM Studio) never goes through a tunnel to the proxy. With NODE_USE_ENV_PROXY=1 and without localhost,127.0.0.1 in NO_PROXY, Cabeção refuses to call the local server and says how to fix it. llm status tells you what applies on your machine.
The stored key is bound to the destination (the keychain account is <provider>@<address>): changing the provider's address does not hand the key to another server. The key file is closed (0600) before it receives the key, and a configuration folder other users of the machine can change is refused.
See, test, turn off and delete
cabecao llm status # providers, model, destination, where the key is (masked)
cabecao llm test # one minimal call, with nothing from the brain: did it work? how long did it take?
cabecao llm off # turns it off: nothing else leaves; the configuration and the key stay
cabecao llm remove openai # deletes the provider and the key Cabeção stored (asks for confirmation)
cabecao llm policy # this brain's sending policy (see above)
If the system keychain refuses to delete the key, llm remove says so and exits with an error, instead of saying "deleted". cabecao uninstall also deletes the answers configuration and the stored keys (in the keychain and in the file).
cabecao status and cabecao doctor show a neutral "Respostas (ask)" line (on, off, or optional and off). The provider never shows up at the end of init nor in the list of optional steps: turning it on is on demand, whenever you want.
Measure
cabecao eval --answers fixtures/eval/respostas.jsonl
Measures, with your questions: valid citations, unsupported claims, right source cited, correct refusal (a question the brain does not answer, marked "answerable": false) and wrong refusal, with time and tokens. Each question is one call to the provider. See cabecao eval.
Known limits
- Tested: the whole flow with a fake provider, both adapters against local servers that mimic the APIs, and one real run with Claude Code. Not tested with real keys for Anthropic, OpenAI, Gemini, OpenRouter and Groq, nor with each system's real keychain (the tests use a fake runner; on Windows, DPAPI is tested for real).
- A quote stitched from different sentences. Up to 3 pieces with an ellipsis, each substantive and in the passage's order, count as one quote: a real quote can be assembled from pieces of different sentences of the same passage and used to back a conclusion the passage does not draw.
- The check verifies the citation, not the conclusion. A claim can cite a true passage and draw a wrong conclusion from it. For anything important, open the source (
cabecao search, orreadwith the citation'sid). - The confirmation signature protects against a forged
llm.json, not against whoever reads your files. An agent with a shell that reads your user folder can read the local secret, just as it can read your notes directly. The protection holds for the path Cabeção controls: the CLI and the tools. - The brain's policy travels through git. Anyone with write access to the remote can loosen it (see above); each machine still decides whether to turn a provider on.
- "Data, never instruction" is still guidance to the model. Content goes delimited, outside content goes marked, and the answer executes nothing; even so, malicious text can influence the answer. Citation checking limits the damage.