> ## Documentation Index
> Fetch the complete documentation index at: https://chatcli.edilsonfreitas.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Bootstrap e Memória Persistente

> Personalize a identidade do agente com arquivos bootstrap e mantenha contexto entre sessões com memória de longo prazo e notas diarias.

O ChatCLI oferece dois sistemas complementares para personalizar e contextualizar o agente: **arquivos bootstrap** para definir personalidade e regras, e **memória persistente** para manter contexto entre sessões.

<Note>
  O sistema de bootstrap e memória está **totalmente conectado** ao fluxo de system prompt. Os arquivos são carregados automaticamente e injetados em todas as interações — tanto no modo chat quanto nos modos `/agent` e `/coder`.
</Note>

***

## Arquivos Bootstrap

Os arquivos bootstrap são documentos Markdown carregados automaticamente no system prompt do agente. Eles definem quem o assistente e, como ele se comporta e quais regras deve seguir.

### Arquivos Suportados

O ChatCLI carrega **exatamente 5 arquivos bootstrap**, nesta ordem. Todos são opcionais — se não existirem, são simplesmente ignorados:

| Arquivo | Proposito | Quando usar |
| :- | :- | :- |
| `AGENTS.md` | Definicoes de sub-agentes e seus papeis | Quando você quer instruir o orquestrador sobre quais agents existem e como usa-los |
| `SOUL.md` | Personalidade, tom e estilo do assistente | Para definir "quem" e o assistente — como ele fala, pensa e se comporta |
| `USER.md` | Preferencias e contexto do usuário/projeto | Para informar o stack, convencoes, ferramentas preferidas e contexto do projeto |
| `IDENTITY.md` | Identidade e capacidades do agente | Para definir "o que" o assistente e — nome, capacidades, limitações |
| `RULES.md` | Regras e restrições explicitas | Para guardrails rígidos — o que ele DEVE e NÃO DEVE fazer |

<Warning>
  Os nomes dos arquivos são **exatos e case-sensitive**. O ChatCLI busca `AGENTS.md`, `SOUL.md`, `USER.md`, `IDENTITY.md` e `RULES.md`. Um diretório sem `AGENTS.md` pode trazer `CHATCLI.md` ou `CLAUDE.md` no lugar (nessa ordem); qualquer outro nome (`README.md`, …) **não é carregado** pelo bootstrap.
</Warning>

### Hierarquia de instruções e imports

`AGENTS.md` não é um arquivo único: o ChatCLI lê um de **cada diretório entre a raiz do projeto e o diretório de trabalho**, raiz primeiro, então um arquivo de pacote refina o do repositório (o mesmo layout que Codex e Claude Code usam). Arquivos aninhados ganham um comentário `<!-- caminho -->` na frente para o modelo saber de onde veio cada bloco; o texto montado tem teto de **32 KiB** (truncado em limite de linha com um aviso visível). O `~/.chatcli/AGENTS.md` global é **sempre mesclado primeiro** (semântica do Claude Code; antes era só fallback). `AGENTS.local.md` / `CLAUDE.local.md` / `CHATCLI.local.md` acrescentam adições por máquina (gitignored) depois do arquivo compartilhado; `AGENTS.override.md` substitui o `AGENTS.md` do diretório por completo (convenção do Codex); `.claude/rules` é lido abaixo de `.chatcli/rules` (uma regra de mesmo nome em `.chatcli/rules` vence). Alvos de `@import` têm symlinks resolvidos e precisam estar sob o workspace ou o diretório global de instruções — um import fora da árvore é logado e deixado como texto — e cada arquivo importado tem teto de 32 KiB por conta própria antes do teto da hierarquia, então o arquivo de instrução de um repositório clonado não consegue puxar arquivos arbitrários do seu disco para o prompt. Um contexto observado observa no máximo 2.000 diretórios, pula nomes de diretório casados pelo `.gitignore` da raiz e avisa quando a observação é parcial.

Qualquer arquivo de bootstrap pode puxar outro com uma linha de import própria:

```markdown theme={"system"}
@docs/convencoes.md
@import ../shared/regras-de-seguranca.md
@~/.chatcli/snippets/checklist-de-review.md
```

Os caminhos resolvem relativos ao arquivo que importa (absolutos e `~` também funcionam), até **4 saltos** de profundidade e nunca o mesmo arquivo duas vezes; um alvo ausente deixa a linha como está, e linhas dentro de blocos de código são ignoradas. Arquivos importados participam da invalidação de cache como os próprios arquivos de bootstrap.

### Prioridade de Carregamento

Os arquivos são buscados em dois níveis, com o workspace tendo prioridade:

<Steps>
  <Step title="Workspace (raiz do projeto)">
    Configurações específicas do projeto. Tem **prioridade** sobre o global. A raiz do projeto e detectada automaticamente (veja abaixo).
  </Step>

  <Step title="Global (~/.chatcli/)">
    Configurações padrão do usuário. Serve como **fallback** quando o arquivo não existe no workspace.
  </Step>
</Steps>

Se o mesmo arquivo existe em ambos os níveis, o do workspace prevalece. Arquivos globais servem como fallback.

#### Detecção Automática do Workspace

O ChatCLI usa `detectProjectDir()` para encontrar a raiz real do projeto. Em vez de usar simplesmente o diretório atual (CWD), ele **sobe na árvore de diretorios** procurando marcadores de projeto:

1. Verifica se o diretório atual contem `.git/` ou `.agent/`
2. Se não encontrar, sobe para o diretório pai e repete
3. Continua até encontrar um marcador ou chegar na raiz do filesystem
4. Se nenhum marcador for encontrado, usa o CWD como fallback

Isso significa que você pode rodar o ChatCLI de **qualquer subdiretorio** do projeto e os arquivos bootstrap na raiz serão encontrados normalmente.

<Info>
  Marcadores reconhecidos: `.git` (repositório Git) e `.agent` (marcador explicito do ChatCLI). Basta um deles existir para definir a raiz do workspace.
</Info>

#### Cenarios de Exemplo

| CWD ao iniciar | Marcador encontrado | Workspace detectado | Arquivos carregados |
| :- | :- | :- | :- |
| `~/project/` | `~/project/.git` | `~/project/` | `~/project/SOUL.md`, etc. |
| `~/project/src/pkg/` | `~/project/.git` | `~/project/` | `~/project/SOUL.md` (sobe 2 níveis) |
| `~/project/src/pkg/` | nenhum | `~/project/src/pkg/` | Apenas globais (`~/.chatcli/`) |
| `~/monorepo/services/api/` | `~/monorepo/.git` | `~/monorepo/` | `~/monorepo/SOUL.md`, etc. |
| `~/tmp/` | nenhum | `~/tmp/` | Apenas globais (`~/.chatcli/`) |

### Exemplos Detalhados

<Tabs>
  <Tab title="SOUL.md">
    Define **personalidade e tom**. Coloque em `~/.chatcli/SOUL.md` (global) ou `./SOUL.md` (projeto):

    ```markdown theme={"system"}
    # Personalidade

    Você e um assistente tecnico especializado em engenharia de software.
    Seja conciso e direto. Prefira exemplos praticos a explicações teoricas.
    Quando sugerir código, use boas praticas e testes.

    # Tom

    - Profissional mas acessivel
    - Prefira respostas curtas e objetivas
    - Use bullet points para listas
    - Responda em portugues por padrão
    ```
  </Tab>

  <Tab title="USER.md">
    Define **contexto do usuário e projeto**. Ideal para `./USER.md` no diretório do projeto:

    ```markdown theme={"system"}
    # Contexto do Projeto

    - Stack: Go 1.25, gRPC, Kubernetes
    - Banco: PostgreSQL 16
    - CI/CD: GitHub Actions
    - Estilo: conventional commits, trunk-based development

    # Preferencias

    - Sempre usar tabelas para comparações
    - Preferir soluces simples e sem over-engineering
    - Testes com table-driven tests idiomaticos em Go
    ```
  </Tab>

  <Tab title="IDENTITY.md">
    Define **o que o assistente e**. Normalmente global em `~/.chatcli/IDENTITY.md`:

    ```markdown theme={"system"}
    # Identidade

    Você e o ChatCLI, um assistente de terminal inteligente.

    ## Capacidades

    - Leitura e edicao de código via @coder plugin
    - Execução de comandos shell com aprovação do usuário
    - Análise de logs e diagnóstico de erros
    - Operações Git (status, diff, log, commit)

    ## Limitações

    - Você NÃO tem acesso a internet
    - Você NÃO pode instalar pacotes sem aprovação
    - Seus patches podem falhar se o contexto mudou
    ```
  </Tab>

  <Tab title="RULES.md">
    Define **regras rigidas e guardrails**. Pode ser global ou por projeto:

    ```markdown theme={"system"}
    # Regras Obrigatorias

    1. NUNCA execute `rm -rf` sem confirmação explicita
    2. NUNCA commite diretamente na branch main
    3. SEMPRE rode testes após modificar código
    4. SEMPRE use conventional commits (feat:, fix:, chore:)

    # Restrições de Segurança

    - Não exponha secrets, tokens ou API keys em logs
    - Não modifique arquivos fora do diretório do projeto
    - Não execute comandos com sudo
    ```
  </Tab>

  <Tab title="AGENTS.md">
    Define **sub-agentes e seus papeis** para o orquestrador:

    ```markdown theme={"system"}
    # Agents Customizados

    ## @devops
    Especialista em infraestrutura, Docker, Kubernetes e CI/CD.
    Use para tarefas de deploy, monitoramento e configuração de pipelines.

    ## @dba
    Especialista em banco de dados PostgreSQL.
    Use para queries, otimização, migrations e análise de performance.

    ## @security
    Auditor de segurança focado em OWASP Top 10.
    Use para revisao de código com foco em vulnerabilidades.
    ```
  </Tab>
</Tabs>

### Onde Colocar os Arquivos

"Raiz do projeto" significa o diretório que contem `.git/` ou `.agent/` -- detectado automaticamente pelo `detectProjectDir()`, não necessariamente o CWD.

```text theme={"system"}
# Configuração GLOBAL (vale para todos os projetos)
~/.chatcli/SOUL.md
~/.chatcli/IDENTITY.md
~/.chatcli/RULES.md
~/.chatcli/USER.md
~/.chatcli/AGENTS.md

# Configuração por PROJETO (override do global)
# "Raiz do projeto" = diretório com .git/ ou .agent/
<raiz-do-projeto>/SOUL.md          # Na raiz do projeto
<raiz-do-projeto>/USER.md          # Na raiz do projeto
<raiz-do-projeto>/RULES.md         # Na raiz do projeto (regras do projeto)
<raiz-do-projeto>/IDENTITY.md      # Na raiz do projeto (raro)
<raiz-do-projeto>/AGENTS.md        # Na raiz do projeto (agents do projeto)
<raiz-do-projeto>/services/AGENTS.md   # Aninhado: lido quando o cwd está sob services/
<raiz-do-projeto>/services/CLAUDE.md   # Nome alternativo para o mesmo papel (CHATCLI.md primeiro)
```

<Warning>
  `CHATCLI_BOOTSTRAP_DIR` substitui apenas o diretório **global** (`~/.chatcli/`), não a detecção do workspace. Arquivos na raiz do projeto (detectada via `.git` ou `.agent`) continuam tendo prioridade sobre os globais, independentemente de `CHATCLI_BOOTSTRAP_DIR`.
</Warning>

<Tip>
  A estratégia recomendada: `SOUL.md` e `IDENTITY.md` globais (são sobre o assistente), `USER.md` e `RULES.md` por projeto (são sobre o contexto de trabalho).
</Tip>

### Cache Inteligente

Os arquivos bootstrap usam cache baseado em mtime (modification time):

* Na primeira leitura, o conteúdo e cacheado em memória
* Leituras subsequentes verificam se o mtime mudou
* Se o arquivo foi modificado, o cache e invalidado automaticamente
* `IsStale()` verifica se algum arquivo mudou desde o ultimo carregamento

***

## Memória Persistente

O sistema de memória mantem contexto entre sessões do ChatCLI usando **armazenamento estruturado** com múltiplos componentes que aprendem sobre você e seu trabalho ao longo do tempo.

### Arquitetura do Sistema

```text theme={"system"}
Conversa -> memoryWorker (3min) -> LLM extraction -> ProcessExtraction()
                                                          |
                    +───────────+───────────+──────────────+────────────+
                    v           v           v              v            v
              FactIndex    Profile    TopicTracker  ProjectTracker  DailyNote
              (scored)     (JSON)     (JSON)        (JSON)          (.md)
                    |
                    v
              Compactor (6h check, 24h cycle)
              |-- Level 1: Score-based pruning + archive
              +-- Level 2: LLM consolidation
                    |
                    v
              MEMORY.md (regenerado, nunca source of truth)
```

### Extração resiliente — nada se perde em silêncio

A extração depende de uma chamada de LLM em background — e um provider fora do ar **não pode custar a memória da conversa**. Três defesas em camadas:

1. **Cadeia de fallback**: a extração tenta o client ativo da sessão e, em falha, percorre `CHATCLI_MEMORY_FALLBACK_PROVIDERS` (ou `CHATCLI_FALLBACK_PROVIDERS`), com timeout próprio por tentativa.
2. **Fila durável em disco**: um segmento que falhar em **todos** os providers é gravado em `~/.chatcli/memory/pending/` (escrita atômica) e reprocessado nas próximas execuções, do mais antigo para o mais novo — **sobrevive a restart**. O worker drena o backlog **no boot e a cada tick de extração** (quem só usa `-p` não enche mais a fila até os segmentos mais antigos serem descartados), um segmento que falha repetidamente é descartado após duas tentativas, a fila tem teto (100 segmentos) e arquivos corrompidos são descartados sem travar o restante. Na saída, a cauda ainda não extraída da sessão é enfileirada para a próxima, e o shutdown espera até 5 s por uma extração em andamento terminar a escrita (uma chamada travada ao provedor nunca segura a saída).
3. **Aviso visível**: duas falhas consecutivas mostram uma linha no terminal (`memória: extração falhando…`) — perda silenciosa de fatos por dias não acontece mais.

<Note>
  O gateway também consulta esta memória: a persona do daemon chama `@memory recall` antes de responder "não sei" a perguntas pessoais. Veja [Chat Gateway](/pt/gateway/chat-gateway).
</Note>

### Estrutura de Armazenamento

Toda a memória fica em `~/.chatcli/memory/`:

```text theme={"system"}
~/.chatcli/memory/
|-- MEMORY.md              # Resumo legivel (regenerado do FactIndex)
|-- memory_index.json      # Fatos com scores de relevancia
|-- user_profile.json      # Perfil do usuário (nome, role, expertise)
|-- topics.json            # Topicos recorrentes com frequência
|-- projects.json          # Projetos ativos com contexto
|-- episodes.json          # Linha do tempo episódica (entradas datadas de trabalho)
|-- graph.json             # Cache persistido do grafo de conhecimento (veja abaixo)
|-- usage_stats.json       # Padroes de uso e estatisticas
|-- memory_archive.json    # Fatos arquivados (baixo score)
|-- weekly/                # Digests semanais (consolidados de notas diarias)
|   +-- 2026-W27.md
|-- monthly/               # Digests mensais (mantidos para sempre)
|   +-- 2026-06.md
|-- 202603/                # Notas diarias de marco 2026
|   |-- 20260301.md
|   +-- 20260306.md
+-- 202602/
    +-- 20260228.md
```

### Componentes

<AccordionGroup>
  <Accordion title="FactIndex -- Memória de Longo Prazo" icon="database">
    Substitui o antigo MEMORY.md append-only. Cada fato tem:

    * **ID unico** por hash SHA-256 do conteúdo (deduplicação automatica)
    * **Categoria**: architecture, pattern, preference, gotcha, project, personal
    * **Score temporal**: `(1 + log(accessCount)) * exp(-days * ln2 / halfLife)`
    * **Tags** para busca por keywords

    Fatos mais acessados e recentes tem scores maiores. Fatos antigos e nunca acessados decaem naturalmente.
  </Accordion>

  <Accordion title="UserProfile -- Perfil do Usuário" icon="user">
    Detectado automaticamente pela IA durante a extracao e editável por você/pelo modelo em qualquer modo:

    * Nome, role, nível de expertise, empresa, localização
    * Idioma preferido e estilo de comunicação
    * Listas com ciclo de vida: **certificações, skills, objetivos, interesses e diretivas** (reafirmar um item **supera** o antigo em vez de duplicar; sufixos `_replace`/`_done`/`_remove` reescrevem)
    * **Diretivas** com severidade (regras duras vs preferências) e **escopo por projeto** (`[scope:<projeto>] regra` só é injetada quando aquele workspace está ativo)
    * **Posições** (`stance`) — opiniões técnicas gravadas **com o porquê** (`"posição :: razão"`)
    * **Marcos** (`milestone`) — linha do tempo datada do que aconteceu
    * **Ambiente** estruturado (`env_os`, `env_shell`, ...) — migrado automaticamente das preferences legadas
    * **Proveniência e frescor por campo**: cada atributo sabe se veio de você ou da extração e quando foi confirmado; campos sem reconfirmação há 120+ dias são sinalizados como possivelmente desatualizados no prompt
    * **Camada de privacidade**: chaves de finanças/saúde/família/documentos são auto-marcadas `[sensitive]` — personalizam respostas, mas nunca entram em código, exemplos ou artefatos gerados (`sensitive_mark`/`sensitive_unmark` para controle manual)
    * Comandos mais usados (top 10) e preferencias gerais

    Veja com `/memory profile`. Perfis antigos poluídos por versões append-only se **auto-curam no próximo load** (fragmentos, duplicatas de progresso e objetivos concluídos saem sozinhos).
  </Accordion>

  <Accordion title="TopicTracker -- Topicos Recorrentes" icon="tags">
    Rastreia topicos tecnicos discutidos:

    * Frequência de mencoes
    * Recencia (topicos recentes pesam mais)
    * Links com fatos relacionados

    Veja com `/memory topics`.
  </Accordion>

  <Accordion title="ProjectTracker -- Projetos" icon="folder-open">
    Rastreia projetos em que você trabalha:

    * Nome, path, descrição
    * Tecnologias usadas
    * Status (active, paused, completed)
    * Ultima atividade

    Veja com `/memory projects`.
  </Accordion>

  <Accordion title="PatternDetector -- Padroes de Uso" icon="chart-line">
    Analisa como você usa o ChatCLI:

    * Sessões totais e duracao media
    * Horas de pico de atividade
    * Features preferidas (chat, agent, coder)
    * Erros comuns e resolucoes

    Veja com `/memory stats`.
  </Accordion>
</AccordionGroup>

### Smart Retrieval

Em vez de injetar toda a memória no system prompt, o ChatCLI usa **retrieval inteligente**:

1. Extrai keywords das ultimas mensagens da conversa
2. Busca fatos relevantes no FactIndex por keyword match + score temporal
3. Respeita um budget configurável (padrão: 4000 caracteres)
4. Prioriza: Perfil > Projetos > Topicos > Fatos relevantes > Notas recentes > Episódios > **Related (graph)** > Trajetória (digests) > Padrões de uso

A seção **`## Related (graph)`** é o grafo de conhecimento participando do recall: os fatos mais bem ranqueados são expandidos um hop pelo grafo, trazendo memórias estruturalmente adjacentes (um fato vizinho, o episódio do dia em que foi aprendido, um tópico ou sessão conectados) que o ranking por keyword e vetor perdeu. É puramente aditiva — nunca desloca um fato ranqueado, só gasta budget sobrando — e aparece tanto na injeção do modo `full` quanto em todo pull de `@memory recall`.

<Info>
  Fatos acessados pelo retriever tem seu score incrementado automaticamente, criando um ciclo virtuoso: quanto mais um fato e util, mais ele aparece.
</Info>

### Modo de injeção: push vs pull

Como a memória chega ao modelo — em **todos os modos**: chat, `/agent` e `/coder` — é controlado por `CHATCLI_MEMORY_MODE`:

| Modo | Comportamento |
| - | - |
| `index` (**default**) | Injeta apenas um **índice compacto e estável** (perfil resumido + nomes dos top topics/projects + contagem de fatos por categoria + contagem de episódios) e deixa o modelo puxar o detalhe sob demanda via a ferramenta de recall de memória. Custo por turno limitado e cacheável. |
| `full` | Injeta o Smart Retrieval completo (acima) a cada turno — o comportamento clássico de "push". |
| `off` | Não injeta memória; os arquivos bootstrap continuam valendo. |

**Cartão de bootstrap de memória persistente** — o system prompt de toda superfície abre com um cartão `[PERSISTENT MEMORY — REAL, CROSS-SESSION]`: um snapshot do início da sessão com contagens reais (fatos de longo prazo, episódios datados, conversas salvas com a mais recente nomeada, cards do work board em andamento) mais uma diretiva anti-amnésia explícita — *nunca alegue não ter memória de sessões passadas; puxe primeiro* (`@memory recall`, `@session search`, `@board list`; no chat, o cartão aponta o usuário para `/session attach` em vez de tools que o chat não tem). O cartão é congelado por sessão para viver no prefixo **cacheado**. O recall proativo também dispara desde o **primeiro turno** de uma sessão nova: a mensagem atual alimenta os hints de ranking, perguntas puramente referenciais ("o que falamos anteriormente?") listam as sessões mais **recentes** em vez de antigas lexicalmente fortes, e a janela de recall ambiente cobre as 60 sessões salvas mais recentes.

O **auto-recall proativo** fecha a lacuna do modelo pull: modelos às vezes pulam a chamada de `@memory recall` mesmo quando um gotcha armazenado é exatamente o que precisam. No modo `index`, cada turno também ranqueia o índice de fatos contra palavras-chave das mensagens recentes e leva os **3 melhores matches** para o prompt num bloco minúsculo `[MEMORY AUTO-RECALL]` (cap de 700 bytes; rotulado como dados, não instruções, cada fato numa linha — a resposta de um provedor externo vai sob a própria cerca `[EXTERNAL MEMORY]`), seguido de uma linha **`Related (graph):`** apontando o que fica ao lado desses fatos no [grafo de conhecimento](#grafo-de-conhecimento-memory-neighbors--map) — assim o modelo sabe que há mais para puxar antes de alegar ignorância. O bloco vive na região final *não-cacheada* junto do contexto de relógio, então o digest estável permanece byte-idêntico e o cache de prompt não é afetado. Gate `CHATCLI_MEMORY_AUTORECALL` (**on** por padrão).

Duas regras de qualidade governam o que o bloco pode carregar. **Piso de relevância:** um fato encontrado só por palavras-chave precisa bater com cerca de um terço dos hints do turno (`computeRelevance ≥ 0.34`), e um fato encontrado pelo índice vetorial precisa passar o piso de cosseno (`min_cosine_score`, 0,25) — um token incidental não injeta mais um fato sem relação em todo turno. **Vetores quando disponíveis:** com um provedor de embeddings configurado (`CHATCLI_EMBED_PROVIDER`), o bloco ranqueia com o mesmo ranker misto semântico + léxico + temporal da ferramenta de recall, embutindo a mensagem do turno uma vez (pulado para mensagens com menos de 8 caracteres), então uma paráfrase sem sobreposição de palavras-chave pode aparecer; setups sem chave mantêm o ranker léxico. **Sem reforço no push:** fatos injetados proativamente não são mais marcados como acessados — reforçar um fato só por ter sido empurrado era auto-entrincheirante (um fato surgido por engano subia no próprio ranking). O acesso é reforçado quando o modelo de fato puxa detalhe pela ferramenta de memória.

**O reforço espera evidência.** Os fatos injetados num turno ficam anotados e, após a resposta, só os que a resposta evidentemente usou — termos significativos suficientes do próprio fato aparecem na resposta (dois, ou um terço deles em fatos longos) — têm o contador de acesso incrementado. Fato ignorado pelo modelo mantém o score; nada é rebaixado. **Episódios vêm junto:** quando a mensagem do turno é longa o bastante, até dois episódios da timeline ranqueados por BM25 sobre o store episódico (resumo, resultado, projeto, refs) entram como bullets datados, então "o que fizemos na migração das faturas" traz a unidade de trabalho, não só os fatos ao redor. O mesmo ranking BM25 agora move as consultas de `@memory timeline` dentro de uma janela de datas.

O modo `pull` (`index`) reduz o bloco de memória por turno em \~88% num store de 500 fatos sem perder acesso ao detalhe — veja [Eficiência de Tokens › Memória pull-first](/pt/context/token-efficiency) para a medição completa. O **chat também honra `index`**: a exceção sancionada da ferramenta de memória do chat (`CHATCLI_CHAT_MEMORY`, on por padrão) dá ao chat o mesmo caminho de pull, então ele recebe o digest compacto mais um hint de recall em vez do retrieval completo. Só quando essa exceção está desabilitada o chat cai em `full` — chat sem caminho de pull nunca pode ficar sem memória. O chat também recebe os blocos proativos `[MEMORY AUTO-RECALL]` e `[SESSION RECALL]` e o card do grafo de conhecimento, antes exclusivos de agent/coder (o wording do session recall no chat sugere `/session attach`, já que o chat não tem ferramenta de sessão). A ferramenta de recall usa HyDE + busca vetorial, então o detalhe puxado tem a mesma qualidade do push. Veja o estado atual em `/config memory`.

### Configuração da Memória

O sistema de memória possui parâmetros configuraveis via variáveis de ambiente:

| Variável | Padrão | Descrição |
| - | - | - |
| `CHATCLI_MEMORY_MODE` | `index` | Modo de injeção em todos os modos (chat, agent, coder): `index` (pull), `full` (push) ou `off` |
| `CHATCLI_MEMORY_AUTORECALL` | `true` | Injeção proativa dos top-3 fatos + linha `Related (graph):` no modo `index` (veja acima) |
| `CHATCLI_MEMORY_GRAPH` | `true` | Cache persistido do grafo de conhecimento (`graph.json`) + expansão de vizinhança no recall; `off` restaura a derivação por chamada, sem expansão |
| `CHATCLI_GRAPH_INDEX` | `true` | Injeção por turno do card map-of-content do grafo (o pull via `@memory map`/`neighbors` fica sempre disponível) |
| `CHATCLI_CHAT_MEMORY` | `true` | Exceção da ferramenta de memória no chat — o caminho de pull que permite ao chat honrar o modo `index` |
| `CHATCLI_MEMORY_MAX_SIZE` | `32768` (32KB) | Tamanho máximo do MEMORY.md renderizado |
| `CHATCLI_MEMORY_RETENTION_DAYS` | `30` | Dias de retencao de notas diarias antes da limpeza |
| `CHATCLI_MEMORY_MAX_FACTS` | `500` | Número máximo de fatos no FactIndex |
| `CHATCLI_MEMORY_RETRIEVAL_BUDGET` | `4000` | Máximo de caracteres de memória injetados no system prompt (modo `full`) |

Alem das variáveis de ambiente, o struct `Config` interno define valores padrão adicionais:

| Parâmetro | Valor Padrão | Descrição |
| - | - | - |
| `CompactionInterval` | 24 horas | Intervalo mínimo entre compactações completas |
| `DecayHalfLifeDays` | 30.0 | Meia-vida do decay temporal dos scores de fatos |
| Intervalo de verificação | 6 horas | Frequência com que o sistema checa se precisa compactar |

### Como as Memorias são Criadas

O worker em background agora extrai **6 tipos de informação** (antes eram apenas 2):

1. **DAILY** -- O que foi feito (arquivos, comandos, erros, tarefas)
2. **LONGTERM** -- Fatos novos para lembrar permanentemente
3. **PROFILE\_UPDATE** -- Informações sobre o usuário (nome, role, expertise)
4. **TOPICS** -- Topicos tecnicos discutidos
5. **PROJECTS** -- Projetos em que se trabalhou
6. **EPISODES** -- Unidades datadas e duráveis de trabalho concluído (veja **Memória episódica: a linha do tempo de trabalho** abaixo)

O worker dispara após 4+ mensagens novas com cooldown de 2 minutos, e também a cada 3 minutos em sessões longas.

**Quanto custa uma chamada, e quanto ela vale.** A requisição de extração tem o formato do cache de prompt: as instruções são um bloco system cacheado, a linha do workspace e a memória de longo prazo existente são outro, e só o segmento novo da conversa viaja como mensagem user. Num provider com cache de prefixo a cadência de três minutos relê os dois primeiros de uma entrada quente e paga a escrita só do segmento; nada é enviado duas vezes. O worker roda no modelo da sessão a menos que `CHATCLI_COMPACT_MODEL` aponte um mais barato, que atende o worker além da compactação: um modelo rápido ali é a maior alavanca sobre o gasto em background. O `/cost` mostra o balanço abaixo da linha do worker: fatos e episódios gravados, custo por item, e quantos recalls proativos colocaram fatos guardados de volta na frente do modelo. Um worker que grava memória que a sessão nunca relê é o que essa linha expõe.

#### Processo de Extracao

O Memory Worker segue este fluxo interno:

1. **EnhancedExtractionPrompt**: Envia o histórico recente da conversa para o LLM com um prompt estruturado solicitando extracao de informações
2. **Resposta esperada**: O LLM retorna texto com headers de seção bem definidos:
   * `## DAILY` -- Resumo do que foi feito na sessão
   * `## LONGTERM` -- Fatos novos para memória de longo prazo
   * `## PROFILE_UPDATE` -- Atualizações de perfil do usuário
   * `## TOPICS` -- Topicos tecnicos identificados
   * `## PROJECTS` -- Projetos mencionados ou trabalhados
3. **ParseEnhancedResponse()**: Faz o parse da resposta e extrai cada seção individualmente
4. **Deduplicação**: Cada fato recebe um ID único via hash SHA-256 do conteúdo. Fatos com hash identico a um já existente são descartados automaticamente
5. **Merge de perfil com ciclo de vida**: Atualizações de `PROFILE_UPDATE` são mescladas com o perfil existente. Campos de lista fazem **upsert** (reafirmar um item supera o antigo em vez de duplicar), e a extração pode emitir operações de reescrita: `goals_done=`/`goals_remove=` removem objetivos concluídos (movendo-os para `milestone=`/`certifications=`), `goals_replace=` substitui a lista inteira — os mesmos sufixos valem para certificações, skills, interesses e diretivas. Instruções suas sobre o perfil ("remove X dos objetivos") são **aplicadas**, nunca gravadas como se fossem fatos

### Compactação Automatica

O sistema executa compactação periodica para evitar crescimento descontrolado:

<Steps>
  <Step title="Verificação (a cada 6 horas)">
    Checa se o número de fatos ultrapassa 80% do limite ou se passaram 24h desde a ultima compactação.
  </Step>

  <Step title="Compactação LLM (preferida)">
    Envia todos os fatos para a IA com instruções para: merge duplicatas, remover obsoletos, consolidar relacionados.
  </Step>

  <Step title="Fallback Score-based">
    Se a chamada LLM falhar, arquiva fatos com score abaixo de 0.1 em `memory_archive.json`.
  </Step>

  <Step title="Limpeza de Notas Diarias">
    Remove notas mais antigas que o periodo de retencao (padrão: 30 dias).
  </Step>

  <Step title="Regeneracao do MEMORY.md">
    Reescreve MEMORY.md a partir do FactIndex -- sempre atualizado, nunca source of truth.
  </Step>
</Steps>

### Digests Semanais e Mensais (Trajetória)

Notas diárias expiram em \~30 dias — os **rollups** preservam a narrativa de longo prazo antes disso:

* Ao fim de cada semana ISO, as notas diárias daquela semana consolidam em `weekly/2026-W27.md` (resumo via LLM com fallback determinístico — nunca depende do provider estar de pé).
* Ao fim de cada mês, os digests semanais consolidam em `monthly/2026-06.md`.
* Retenção: semanais guardam \~26 semanas; **mensais ficam para sempre** (custo mínimo).
* Uma seção **Trajectory** limitada entra no contexto de memória com o último mensal + semanais recentes — é assim que "o que você andou fazendo nos últimos meses" sobrevive à limpeza das notas diárias.

O processo é idempotente e roda sozinho no worker de memória (checagem no startup e a cada 12h).

### Migração Automatica

Ao iniciar pela primeira vez com o novo sistema, o ChatCLI detecta se existe um `MEMORY.md` legado (sem `memory_index.json`) e migra automaticamente:

1. Cada linha/bullet e convertida em um fato individual
2. Categorias são detectadas pelos headers do markdown
3. Tags são extraidas por keywords tecnicas
4. O arquivo original e salvo como `MEMORY.md.bak`

### Comando `/memory`

| Subcomando | Descrição |
| - | - |
| `/memory` ou `/memory today` | Mostra as notas de hoje |
| `/memory yesterday` | Mostra as notas de ontem |
| `/memory 2026-03-04` | Mostra notas de uma data específica |
| `/memory week` | Mostra notas dos ultimos 7 dias |
| `/memory longterm` | Mostra o conteúdo do MEMORY.md |
| `/memory list` | Lista todos os arquivos de memória (inclui JSONs estruturados) |
| `/memory load <data>` | Carrega notas de um dia no contexto da conversa |
| `/memory profile` | Mostra o perfil do usuário detectado |
| `/memory profile set <campo>=<valor>` | Define/atualiza um campo do perfil manualmente |
| `/memory remember <fato>` | Adiciona um fato de longo prazo explicitamente (aceita prefixo `[categoria]`) |
| `/memory forget <trecho>` | Remove fatos de longo prazo que contenham o trecho |
| `/memory topics` | Mostra topicos rastreados com frequência |
| `/memory projects` | Mostra projetos rastreados com status |
| `/memory stats` | Estatisticas completas (sessões, horas de pico, erros, features) |
| `/memory facts [categoria]` | Lista fatos com scores (filtro por categoria) |
| `/memory timeline [q]` | Histórico datado de episódios; `q` filtra por tempo ("3 meses atrás", "abril", "2026-04") e/ou conteúdo |
| `/memory compact` | Forca compactação imediata (LLM + cleanup de notas) |
| `/memory export [caminho]` | Escreve fatos, episódios, tópicos, projetos e perfil como JSONL (padrão `~/.chatcli/exports/memory-<ts>.jsonl`, modo 0600; selado linha a linha quando `CHATCLI_ENCRYPTION_KEY` está definida) |
| `/memory import <caminho>` | Mescla uma exportação na memória desta máquina: todo fato é sanitizado (uma linha, limitado, segredos mascarados) e seu id é re-derivado do conteúdo (conteúdo conhecido fica com os metadados mais fortes; um id escolhido não passa um duplicado pelo dedup), confiança é limitada, tags têm teto e categorias são validadas; episódios deduplicam, tópicos/projetos/perfil mesclam campo a campo; um arquivo cujo cabeçalho declara um schema mais novo é recusado; nada é apagado |
| `/memory recall <consulta>` | Simulação do auto-recall: os fatos que a consulta injetaria, cada um com score e **por quê** (sinais de keyword/semântico/recência, contagem de uso, procedência, projeto de origem) |
| `/memory why` | O auto-recall do último turno com os mesmos motivos |

Todo store também reconcilia com seu arquivo antes de reescrevê-lo — fatos e episódios já faziam isso; **perfil, tópicos e projetos** agora mesclam também (campo mais recente vence, listas unem), então um REPL, um gateway daemon e um MCP server escrevendo na mesma memória nunca apagam o aprendizado um do outro. Notas diárias são anexadas por rename atômico, então um crash no meio da escrita não rasga uma nota. Um fato aprendido em outro projeto é rotulado `(from: ~/caminho)` no bloco lembrado, com git root e seus pacotes contando como um só projeto.

#### Edição manual e perfil estendido

A detecção automática nem sempre captura tudo, então você pode **editar a memória explicitamente**. Além de nome/role/expertise/empresa/localização, o perfil cobre **certificações, skills, objetivos, interesses, diretivas, posições (stance), marcos (milestone) e ambiente (env\_\*)**.

Campos de lista têm **ciclo de vida**, não são append-only: novos itens entram, um item reafirmado (mesmo texto fora do status/parêntese) **supera** o antigo no lugar, e sufixos de operação reescrevem — `_replace` substitui a lista inteira (valor vazio limpa), `_done`/`_remove` removem itens que casem. Vírgulas dentro de parênteses são seguras (`"Quiz X (Provider, 60 questões)"` fica inteiro).

```text theme={"system"}
> /memory profile set company=ACME Corp
> /memory profile set certifications=CKA, AWS SAA        # upsert, deduplicado
> /memory profile set goals_done=tirar CKA               # objetivo concluído sai da lista
> /memory profile set milestone=Concluiu a CKA           # ...e vira marco datado
> /memory profile set goals_replace=lançar o produto Y   # substitui TODOS os objetivos
> /memory profile set stance=preferir backends keyless :: menos atrito de setup
> /memory profile set directives=[scope:meu-repo] sempre rodar o linter antes do push
> /memory profile set env_shell=zsh
> /memory profile set sensitive_mark=renda_mensal        # marca como privado
> /memory remember [preference] Prefere Go a Python para CLIs
> /memory forget Python                                  # remove FATOS contendo "Python"
```

<Info>
  `forget` atua só em **fatos**; para remover itens do perfil use os sufixos (`goals_remove=...`). Diretivas com `[scope:<projeto>]` só são injetadas quando aquele workspace está ativo; sem a tag, valem globalmente.
</Info>

#### Tool `@memory` (agent, coder e chat)

Dentro do `/agent` e `/coder`, o modelo pode persistir e explorar memória sozinho via a tool **`@memory`** (cmds `remember`, `profile`, `forget`, `recall`, `timeline`, `neighbors`, `map`):

```text theme={"system"}
<tool_call name="@memory" args='{"cmd":"remember","args":{"content":"User earned the AWS Solutions Architect certification","category":"personal"}}' />
```

Assim, quando você conta uma novidade ao agente (ex.: uma certificação nova), ele a grava no seu perfil/fatos de longo prazo sem você precisar rodar `/memory` manualmente. O subcomando `profile` aceita todas as operações de ciclo de vida (`goals_done`, `goals_replace`, `stance`, `milestone`, `env_*`, `sensitive_mark`, ...).

**No chat também**: atualização de memória/perfil é a **quarta exceção sancionada** do chat tool-less (junto de `ask_user`, knowledge read-only e `@graphview`). Quando você revela ou corrige um fato durável sobre si, o modelo persiste **no mesmo turno** — nada de "vou considerar daqui pra frente" sem gravar. A exceção também carrega o **lado de leitura**: é o caminho de pull que permite ao chat honrar o modo de memória `index` (digest compacto + recall sob demanda) e receber os blocos proativos de auto-recall, session recall e o card do grafo. Controlada por `CHATCLI_CHAT_MEMORY` (**ligada por padrão**) e alternável com `/config chat memory on|off` — desabilitar reverte o chat ao modelo full-push de memória.

### Memória episódica: a linha do tempo de trabalho

Fatos capturam o que é **verdade**; episódios capturam o que **aconteceu**. Um episódio é uma unidade datada e durável de trabalho concluído — resumo, desfecho e refs (arquivos, PRs, comandos) — extraída automaticamente pelo worker em background (seção `## EPISODES`) e armazenada para sempre em `~/.chatcli/memory/episodes.json`. Ao contrário das daily notes (retenção de 30 dias) e seus digests, episódios nunca expiram — "o que fizemos há três meses?" finalmente tem resposta estruturada.

* **Armazenamento** segue as disciplinas do fact index: escrita atômica, quarentena em corrupção e rewrites reconciliadores multi-processo sob um lock de arquivo entre processos (`<store>.lock` ao lado de cada store, tomado na seção crítica de merge-e-escrita, então REPL, gateway daemon e MCP server nunca se apagam — o mesmo lock protege o store de contextos e o índice vetorial). O mesmo item re-extraído no mesmo dia **deduplica e enriquece** desfecho/refs em vez de duplicar. Cap de 2000 episódios (mais antigos caem primeiro).
* **`@memory timeline`** é a visão cronológica para o modelo: `{project?, from?, to?, query?, limit?}`. `from`/`to` aceitam datas ISO (`2026-04`, `2026-04-12`) **ou expressões naturais em português e inglês** ("há 3 meses", "3 months ago", "abril", "semana passada") — uma expressão de tempo dentro de `query` também funciona.
* **Recall temporal**: uma query de `@memory recall` com expressão de tempo ("o que fizemos em abril?") automaticamente antepõe a fatia correspondente da timeline ao resultado — ranking por relevância sozinho não responde "quando". Quando a janela veio de linguagem natural e as palavras restantes não casam nada, a janela vence e retorna sem filtro (a data era o sinal real).
* **`/memory timeline [q]`** é a visão humana — mesmo parsing temporal, renderizado no terminal.
* **Rollups ancorados em episódios**: os digests semanais/mensais agora lideram com os episódios do período e usam as daily notes como contexto, então a narrativa de longo prazo para de decair — e uma semana cujas notes já expiraram ainda gera digest só dos episódios.

```text theme={"system"}
<tool_call name="@memory" args='{"cmd":"timeline","args":{"query":"há 3 meses"}}' />
<tool_call name="@memory" args='{"cmd":"timeline","args":{"project":"chatcli","from":"2026-04","to":"2026-06"}}' />
```

#### Grafo de conhecimento (`@memory neighbors` / `map`)

O que o ChatCLI sabe sobre você não é uma lista plana: facts, tópicos, projetos, skills, tags — e, desde o grafo persistido, **episódios, sessões salvas e knowledge bases** — formam um grafo (estilo Obsidian, no core) a partir das relações que os stores já guardam (tópico↔fato, fato→projeto, episódio↔projeto, episódio↔fatos do mesmo dia, sessão↔projeto, sessão↔episódio, KB↔tags, triggers de skill) mais `[[wikilinks]]` no texto. Acesso pelo próprio `@memory`:

* `recall` → busca por **conteúdo** ("quais fatos casam com estas palavras?") — a saída agora termina com uma seção `## Related (graph)` de vizinhos a um hop.
* `neighbors <assunto>` → **grafo local**: backlinks + notas conectadas de um assunto ("o que está ligado a isto?").

**O grafo é um cache persistido**, não uma derivação por chamada: vive em `~/.chatcli/memory/graph.json` e só reconstrói quando uma fonte realmente muda (um fato aprendido ou esquecido, uma sessão salva, uma skill instalada, um contexto criado — por você ou pelo modelo via tools). No próximo boot o cache é adotado instantaneamente, então `@memory map` e o card por turno custam nada. O arquivo é auto-curável: cópia corrompida ou stale é descartada e re-derivada. Gate: `CHATCLI_MEMORY_GRAPH` (**on** por padrão; `off` restaura o comportamento antigo de derivar por chamada, sem expansão no recall). Contagem de nós/arestas visível em `/config memory`.

* `map` → visão geral (contagens por tipo + hubs).

Disciplina de contexto: por turno entra só um *index card* minúsculo e determinístico (cache-friendly); a profundidade é puxada sob demanda. Para visualizar, use `/graph` (renderiza o grafo em imagem via go-graphviz embarcado).

#### Qualidade dos fatos (confiança, proveniência, reconciliação)

Cada fato carrega **confiança** e **proveniência**: o que você afirma diretamente vale mais que um palpite da extração de fundo, e um fato re-observado sobe de confiança — a confiança pondera o score (ranking e sobrevivência ao decay/poda). Ao gravar, o ChatCLI **reconcilia**: uma reformulação reforça o fato existente em vez de duplicar, e uma atualização do mesmo assunto com confiança igual ou maior **substitui** o fato obsoleto (conservador — um palpite fraco nunca apaga um fato forte). Tópicos ganham um **resumo rolante** do que foi discutido, virando nós de conhecimento de verdade. Índices de memória legados são enriquecidos uma vez no startup, sem perder nada.

<AccordionGroup>
  <Accordion title="O que vai em cada componente?" icon="layer-group">
    * **FactIndex**: Fatos estaveis e duradouros -- decisoes, padroes, gotchas, preferencias
    * **UserProfile**: Quem você e -- nome, role, expertise, idioma
    * **TopicTracker**: Sobre o que você fala -- Go, Docker, K8s, etc.
    * **ProjectTracker**: Em que você trabalha -- chatcli, meu-app, etc.
    * **PatternDetector**: Como você trabalha -- horarios, features, erros comuns
    * **Notas diarias**: O que aconteceu hoje -- temporal e específico
  </Accordion>

  <Accordion title="Posso editar as memorias manualmente?" icon="file-pen">
    Sim! Todos os arquivos são JSON ou Markdown puro:

    ```bash theme={"system"}
    # Ver perfil
    cat ~/.chatcli/memory/user_profile.json | jq .

    # Ver fatos com scores
    cat ~/.chatcli/memory/memory_index.json | jq '.[0:5]'

    # Editar nota de hoje
    vim ~/.chatcli/memory/$(date +%Y%m)/$(date +%Y%m%d).md
    ```

    Alterações em JSONs são carregadas na proxima inicializacao. O MEMORY.md e regenerado e não deve ser editado diretamente.
  </Accordion>

  <Accordion title="Como funciona o scoring de fatos?" icon="chart-simple">
    Cada fato tem um score calculado por:

    ```
    score = (1 + log(1 + accessCount)) * exp(-daysSinceAccess * ln(2) / halfLifeDays)
    ```

    * **accessCount**: Quantas vezes o fato foi usado pelo retriever
    * **daysSinceAccess**: Dias desde o ultimo acesso
    * **halfLifeDays**: Meia-vida do decay (padrão: 30 dias)

    Fatos acessados frequentemente e recentemente tem score alto. Fatos nunca acessados decaem para \~0 após 3-4 meias-vidas.
  </Accordion>
</AccordionGroup>

### O que e Injetado no Prompt

O ContextBuilder monta o seguinte bloco e injeta como prefixo do system prompt:

```text theme={"system"}
## AGENTS.md

[conteúdo do AGENTS.md]

---

## SOUL.md

[conteúdo do SOUL.md]

---

## USER.md

[conteúdo do USER.md]

---

## IDENTITY.md

[conteúdo do IDENTITY.md]

---

## RULES.md

[conteúdo do RULES.md]

## Path-Specific Rules

[regras condicionais por path — veja abaixo]

---

# Memory

## Long-term Memory

[conteúdo do MEMORY.md]

## Recent Daily Notes

### 2026-03-04

[conteúdo da nota do dia 4]

### 2026-03-05

[conteúdo da nota do dia 5]

### 2026-03-06

[conteúdo da nota de hoje]
```

Secoes vazias (arquivos inexistentes) são **omitidas automaticamente** — apenas o que existe e injetado.

***

## Contexto Dinamico (CWD + Desambiguacao)

O ChatCLI injeta automaticamente no system prompt:

* **Data e hora** atuais
* **Diretório de trabalho** atual (CWD do processo)
* **Instrução de desambiguacao**: o modelo e instruido a SEMPRE resolver "aqui", "este projeto", paths relativos contra o CWD atual — nunca contra paths da memória de longo prazo

<Info>Isso resolve o problema comum onde a memória de longo prazo contem paths de projetos anteriores e o modelo confunde "o projeto atual" com um projeto que estava na memória. Fatos de outros projetos são anotados com `(from: /outro/projeto)` para deixar claro de onde vieram.</Info>

***

## Path-Specific Rules

Alem do `RULES.md` global, você pode criar **regras condicionais por path** em `.chatcli/rules/`:

```text theme={"system"}
.chatcli/rules/
├── go-style.md          # Regras para arquivos Go
├── api-conventions.md   # Regras para APIs
└── testing.md           # Regras para testes
```

Cada arquivo pode ter um frontmatter `paths:` que define para quais arquivos a regra se aplica:

```markdown theme={"system"}
---
paths: ["*.go", "src/**"]
---

Sempre use error wrapping com fmt.Errorf("%w", err) em Go.
Nunca ignore erros retornados.
```

Regras **sem** frontmatter `paths:` se aplicam globalmente. Regras do workspace (`.chatcli/rules/`) tem **prioridade** sobre regras globais (`~/.chatcli/rules/`) com o mesmo nome.

<Tip>Veja [Path-Specific Rules](/pt/context/path-rules) para documentação completa.</Tip>

***

## Configuração

<Tabs>
  <Tab title="Variáveis de Ambiente">
    ```bash theme={"system"}
    CHATCLI_BOOTSTRAP_ENABLED=true
    CHATCLI_BOOTSTRAP_DIR=/path/to/bootstrap/files
    CHATCLI_MEMORY_ENABLED=true
    ```

    | Variável | Padrão | Descrição |
    | - | - | - |
    | `CHATCLI_BOOTSTRAP_ENABLED` | `true` | Ativa/desativa o carregamento dos arquivos bootstrap |
    | `CHATCLI_BOOTSTRAP_DIR` | `~/.chatcli/` | Diretório alternativo para os arquivos bootstrap **globais**. Use quando quiser manter seus arquivos (SOUL.md, RULES.md, etc.) em outro local, por exemplo um repositório versionado ou diretório compartilhado entre máquinas |
    | `CHATCLI_MEMORY_ENABLED` | `true` | Ativa/desativa o sistema de memória persistente |

    <Note>
      `CHATCLI_BOOTSTRAP_DIR` substitui apenas o diretório **global** (`~/.chatcli/`). Arquivos na raiz do projeto (detectada via `.git` ou `.agent`) continuam tendo prioridade sobre os globais.
    </Note>
  </Tab>

  <Tab title="Via Helm Chart">
    ```yaml theme={"system"}
    # values.yaml
    bootstrap:
      enabled: true
      definitions:
        SOUL.md: |
          Você e um assistente DevOps...
        USER.md: |
          O usuário prefere Go...

    memory:
      enabled: true
      subPath: memory   # padrão: diretório próprio da memória no PVC de sessões
    ```

    O Helm chart cria ConfigMaps para os arquivos bootstrap e monta em `/home/chatcli/.chatcli/bootstrap/`; uma mudança em `bootstrap.definitions` reinicia os pods no `helm upgrade`, enquanto um `bootstrap.existingConfigMap` editado exige `kubectl rollout restart`. `bootstrap.enabled` sem `definitions` nem `existingConfigMap` não monta nada.

    Com persistência ligada, a memória fica num diretório próprio do PVC de sessões (`memory.subPath`, padrão `memory`, montado em `~/.chatcli/memory`) e as sessões continuam na raiz do PVC; sem persistência ela é um emptyDir de 200Mi. Charts anteriores (até 1.211.x) guardavam a memória na raiz do PVC, entre os arquivos de sessão: no primeiro start após o upgrade o servidor copia os arquivos da própria memória de lá para o diretório de memória, uma única vez e sem mover nem sobrescrever nada (o chart define `CHATCLI_MEMORY_LEGACY_DIR` para isso). `memory.subPath: ""` mantém o layout compartilhado antigo. Detalhes em [Deploy no Kubernetes](/pt/start/docker-deployment#memória-no-pvc-de-sessões).
  </Tab>
</Tabs>

***

## Boas Praticas

<CardGroup cols={2}>
  <Card title="SOUL.md global, USER.md por projeto" icon="layer-group">
    Mantenha sua personalidade preferida globalmente e contexto tecnico por projeto.
  </Card>

  <Card title="MEMORY.md conciso" icon="compress">
    Mantenha apenas fatos estaveis e confirmados — não sessão-específicos.
  </Card>

  <Card title="Notas diarias para journaling" icon="calendar-day">
    Use para registrar decisoes, problemas resolvidos e contexto temporal.
  </Card>

  <Card title="Não duplique CLAUDE.md" icon="copy">
    Se você já usa CLAUDE.md ou instruções do projeto, evite duplicar no bootstrap.
  </Card>
</CardGroup>

<Tip>Revise periodicamente suas memorias e remova as desatualizadas para manter o contexto relevante.</Tip>

***

## Otimização de Contexto (Cache de Prompt)

O ChatCLI otimiza o custo de tokens quando contextos estão attached usando tres estrategias complementares:

### System Prompt Unificado com Cache

Contextos attached via `/context attach` são injetados como **system prompt**, não como mensagens de usuário. Isso permite que providers apliquem cache automático:

| Provider | Mecanismo | Desconto |
| - | - | - |
| Anthropic | `cache_control: ephemeral` | \~90% |
| OpenAI | Prompt caching automático | \~50% |
| Google | Context caching API | Variável |

O bloco de system prompt contem:

1. Bootstrap (SOUL.md, USER.md, etc.)
2. Memory (MEMORY.md + notas diarias)
3. **Contextos Attached** (novo — antes era user message)
4. K8s Watcher (se ativo)

Como o system prompt e identico entre turnos, o provider cacheia e cobra tokens com desconto.

### Compactação Inteligente

Mensagens de contexto injetado (`/memory load`, contextos summarizados) são **automaticamente truncadas** durante a compactação (Level 1 — trimming). Isso evita que contexto referencial antigo consuma budget precioso.

### Visibilidade de Tokens

O comando `/context attached` agora mostra:

* Estimativa de tokens por contexto
* Total de tokens por turno
* Dicas de cache por provider
* Alertas para contextos muito grandes

Ao executar `/context attach`, o feedback inclui a estimativa de custo por turno.

***

## Próximos Passos

<CardGroup cols={2}>
  <Card title="Controle de Conversa" icon="clock-rotate-left" href="/pt/usage/conversation-control">
    Use /compact e /rewind para gerenciar o tamanho e estado da conversa.
  </Card>

  <Card title="Sessões" icon="floppy-disk" href="/pt/context/session-management">
    Salve e reutilize conversas entre projetos.
  </Card>
</CardGroup>

## Provedor de memória externo (MCP)

A memória embutida continua sendo o padrão. Uma organização que já roda um serviço de memória o pluga via MCP sem código no ChatCLI: `CHATCLI_MEMORY_PROVIDER=mcp:<server>`, onde `<server>` é um servidor MCP configurado que expõe duas tools:

| Tool | Argumentos | Papel |
| - | - | - |
| `memory_recall` | `query`, `hints[]`, `budget_chars` | devolve texto anexado ao bloco de auto-recall de todo turno (chat e agent/coder), limitado a 900 chars, 5 s |
| `memory_store` | `messages[{role, content}]`, `session` | recebe as mensagens novas de cada turno (system excluídas), enviadas de forma assíncrona e best-effort, 10 s |

Fatos, episódios e grafo embutidos continuam funcionando ao lado; a resposta do provedor vem depois deles. Qualquer falha ou timeout não adiciona nada e nunca bloqueia um turno. Aparece em `/config memory`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.