mini-tars 0.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mini_tars-0.0.1/.claude/agents/construtor.md +15 -0
- mini_tars-0.0.1/.claude/agents/revisor.md +14 -0
- mini_tars-0.0.1/.claude/hooks/verify.py +21 -0
- mini_tars-0.0.1/.claude/settings.json +34 -0
- mini_tars-0.0.1/.github/workflows/ci.yml +81 -0
- mini_tars-0.0.1/.gitignore +12 -0
- mini_tars-0.0.1/00-descobrir/assumptions.md +18 -0
- mini_tars-0.0.1/00-descobrir/competitors.md +46 -0
- mini_tars-0.0.1/00-descobrir/idea.md +34 -0
- mini_tars-0.0.1/00-descobrir/kill-criteria.md +20 -0
- mini_tars-0.0.1/01-definir/arquitetura.md +105 -0
- mini_tars-0.0.1/01-definir/requisitos.md +54 -0
- mini_tars-0.0.1/01-definir/visao.md +53 -0
- mini_tars-0.0.1/CLAUDE.md +27 -0
- mini_tars-0.0.1/CONTEXT.md +27 -0
- mini_tars-0.0.1/LICENSE +21 -0
- mini_tars-0.0.1/PKG-INFO +96 -0
- mini_tars-0.0.1/README.md +79 -0
- mini_tars-0.0.1/depth.md +35 -0
- mini_tars-0.0.1/docs/adr/0001-armazenamento-sqlite.md +24 -0
- mini_tars-0.0.1/docs/adr/0002-busca-propria-em-memoria.md +25 -0
- mini_tars-0.0.1/docs/adr/0003-transporte-mcp.md +35 -0
- mini_tars-0.0.1/docs/adr/0004-correcoes-com-supersedes.md +24 -0
- mini_tars-0.0.1/docs/adr/0005-seguranca-por-padrao.md +26 -0
- mini_tars-0.0.1/docs/decisions.md +41 -0
- mini_tars-0.0.1/docs/handoff.md +39 -0
- mini_tars-0.0.1/docs/risks.md +19 -0
- mini_tars-0.0.1/evals/README.md +55 -0
- mini_tars-0.0.1/evals/cases.example.json +13 -0
- mini_tars-0.0.1/evals/cases.grande-idg.json +945 -0
- mini_tars-0.0.1/evals/cases.grande.json +945 -0
- mini_tars-0.0.1/evals/cases.json +474 -0
- mini_tars-0.0.1/evals/cases.original-gold.json +460 -0
- mini_tars-0.0.1/evals/cases.rascunho-assistente.json +460 -0
- mini_tars-0.0.1/evals/experimento-01.md +61 -0
- mini_tars-0.0.1/evals/experimento-02.md +96 -0
- mini_tars-0.0.1/evals/experimento-03.md +81 -0
- mini_tars-0.0.1/evals/modos.json +2 -0
- mini_tars-0.0.1/evals/queries-exp01-sem-suspeitos.json +1 -0
- mini_tars-0.0.1/evals/queries-exp01.json +1 -0
- mini_tars-0.0.1/evals/run_baseline.py +122 -0
- mini_tars-0.0.1/evals/run_exp03.py +89 -0
- mini_tars-0.0.1/evals/run_pkg.py +107 -0
- mini_tars-0.0.1/evals/sinonimos.json +28 -0
- mini_tars-0.0.1/evals/supersedes.json +3 -0
- mini_tars-0.0.1/evals/teste-reservado.json +231 -0
- mini_tars-0.0.1/evals/teste-reservado.original-breno.json +217 -0
- mini_tars-0.0.1/examples/demo_client.py +47 -0
- mini_tars-0.0.1/pyproject.toml +32 -0
- mini_tars-0.0.1/src/mini_tars/__init__.py +3 -0
- mini_tars-0.0.1/src/mini_tars/cli.py +103 -0
- mini_tars-0.0.1/src/mini_tars/config.py +41 -0
- mini_tars-0.0.1/src/mini_tars/export_import.py +92 -0
- mini_tars-0.0.1/src/mini_tars/http_app.py +60 -0
- mini_tars-0.0.1/src/mini_tars/mcp_server.py +75 -0
- mini_tars-0.0.1/src/mini_tars/models.py +76 -0
- mini_tars-0.0.1/src/mini_tars/search.py +102 -0
- mini_tars-0.0.1/src/mini_tars/service.py +147 -0
- mini_tars-0.0.1/src/mini_tars/store.py +165 -0
- mini_tars-0.0.1/tests/test_config.py +20 -0
- mini_tars-0.0.1/tests/test_evals_regression.py +40 -0
- mini_tars-0.0.1/tests/test_export_import.py +142 -0
- mini_tars-0.0.1/tests/test_http_app.py +153 -0
- mini_tars-0.0.1/tests/test_mcp_server.py +227 -0
- mini_tars-0.0.1/tests/test_search.py +111 -0
- mini_tars-0.0.1/tests/test_service.py +186 -0
- mini_tars-0.0.1/tests/test_store.py +165 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: construtor
|
|
3
|
+
description: Implementa uma fatia do mini-Tars a partir de 01-definir/, com teste e avaliação. Use quando houver uma especificação pronta e aprovada.
|
|
4
|
+
tools: Read, Write, Edit, Glob, Grep, Bash
|
|
5
|
+
---
|
|
6
|
+
Você implementa o mini-Tars, um servidor de memória MCP em Python. Leia `CONTEXT.md` e `CLAUDE.md` antes de tudo.
|
|
7
|
+
|
|
8
|
+
Como trabalhar:
|
|
9
|
+
- Implemente só a fatia pedida, ligada a IDs de `01-definir/requisitos.md` (RF-xx, RNF-xx). Não amplie o escopo.
|
|
10
|
+
- Toda mudança de comportamento vem com teste (`tests/`) ou caso em `evals/`.
|
|
11
|
+
- A busca é a medida em `evals/`; não altere o algoritmo sem experimento e conjunto de teste novos. Nunca leia nem rode `evals/teste-reservado.json`.
|
|
12
|
+
- Datas em America/Sao_Paulo; nenhum dado real em testes, fixtures ou logs; nenhum log com o texto dos fatos.
|
|
13
|
+
- Nunca leia ou edite `.env`, chaves ou credenciais; nunca publique, faça push ou deploy.
|
|
14
|
+
- Se a especificação estiver ambígua, registre a dúvida em `docs/handoff.md` e siga a opção mais conservadora, dizendo qual foi.
|
|
15
|
+
Ao terminar, entregue: o que mudou (arquivos), quais requisitos ficam atendidos, como verificar (comando), o que ficou de fora. O revisor vai ler seu diff sem ver esta conversa.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: revisor
|
|
3
|
+
description: Revisa o diff de uma fatia do mini-Tars contra a especificação. Somente leitura, contexto separado. Use depois que o construtor terminar.
|
|
4
|
+
tools: Read, Glob, Grep, Bash
|
|
5
|
+
---
|
|
6
|
+
Você revisa código do mini-Tars e NÃO edita nada. Não confie no resumo do construtor: leia o diff e rode os testes.
|
|
7
|
+
|
|
8
|
+
Confira, nesta ordem:
|
|
9
|
+
1. O diff atende os requisitos citados (`01-definir/requisitos.md`) e nada além? Aponte escopo extra.
|
|
10
|
+
2. Há teste para cada comportamento novo e ele falharia se o código estivesse errado?
|
|
11
|
+
3. Segurança: escuta local por padrão, token fora do local, texto dos fatos tratado como dado, nenhum segredo, nenhum log com conteúdo dos fatos.
|
|
12
|
+
4. Regras do `CLAUDE.md`: fuso America/Sao_Paulo, sem dado real, nada de `.env`, nada do conjunto reservado.
|
|
13
|
+
5. O algoritmo de busca continua igual ao medido em `evals/`.
|
|
14
|
+
Responda com: aprovado ou não, lista de problemas por gravidade (com arquivo e linha), e o que você verificou e como. Se não conseguiu verificar algo, diga.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Gancho de parada: roda os testes antes de o agente encerrar.
|
|
3
|
+
|
|
4
|
+
Se falharem, devolve código 2 e a mensagem, e o agente continua para corrigir.
|
|
5
|
+
Se o gancho já bloqueou uma vez neste turno (stop_hook_active), deixa parar para não entrar em laço.
|
|
6
|
+
"""
|
|
7
|
+
import json, subprocess, sys
|
|
8
|
+
|
|
9
|
+
try:
|
|
10
|
+
payload = json.load(sys.stdin)
|
|
11
|
+
except Exception:
|
|
12
|
+
payload = {}
|
|
13
|
+
if payload.get("stop_hook_active"):
|
|
14
|
+
sys.exit(0)
|
|
15
|
+
if not __import__("os").path.isdir("tests"):
|
|
16
|
+
sys.exit(0)
|
|
17
|
+
r = subprocess.run([sys.executable, "-m", "pytest", "-q", "-x"], capture_output=True, text=True)
|
|
18
|
+
if r.returncode not in (0, 5): # 5 = nenhum teste coletado
|
|
19
|
+
sys.stderr.write("Testes falharam; corrija antes de encerrar:\n" + (r.stdout + r.stderr)[-1500:])
|
|
20
|
+
sys.exit(2)
|
|
21
|
+
sys.exit(0)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(python -m pytest:*)",
|
|
5
|
+
"Bash(python3 -m pytest:*)",
|
|
6
|
+
"Bash(python3 evals/run_exp03.py:*)",
|
|
7
|
+
"Bash(git status:*)",
|
|
8
|
+
"Bash(git diff:*)",
|
|
9
|
+
"Bash(git log:*)"
|
|
10
|
+
],
|
|
11
|
+
"deny": [
|
|
12
|
+
"Read(./.env)",
|
|
13
|
+
"Read(./.env.*)",
|
|
14
|
+
"Read(**/*.pem)",
|
|
15
|
+
"Read(**/*secret*)",
|
|
16
|
+
"Read(**/*credential*)",
|
|
17
|
+
"Edit(./.env)",
|
|
18
|
+
"Edit(./.env.*)",
|
|
19
|
+
"Bash(git push:*)",
|
|
20
|
+
"Bash(twine:*)",
|
|
21
|
+
"Bash(python -m twine:*)",
|
|
22
|
+
"Bash(pip publish:*)",
|
|
23
|
+
"Bash(uv publish:*)",
|
|
24
|
+
"Bash(rm -rf:*)",
|
|
25
|
+
"Read(./evals/teste-reservado.json)",
|
|
26
|
+
"Bash(*teste-reservado*)"
|
|
27
|
+
]
|
|
28
|
+
},
|
|
29
|
+
"hooks": {
|
|
30
|
+
"Stop": [
|
|
31
|
+
{ "hooks": [ { "type": "command", "command": "python3 .claude/hooks/verify.py" } ] }
|
|
32
|
+
]
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
name: ci
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
pull_request:
|
|
5
|
+
permissions:
|
|
6
|
+
contents: read
|
|
7
|
+
jobs:
|
|
8
|
+
test:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
strategy:
|
|
11
|
+
matrix:
|
|
12
|
+
python: ["3.11", "3.12"]
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
- uses: actions/setup-python@v5
|
|
16
|
+
with:
|
|
17
|
+
python-version: ${{ matrix.python }}
|
|
18
|
+
- run: python -m pip install -e ".[dev]"
|
|
19
|
+
- name: Testes e avaliações (regressão da busca)
|
|
20
|
+
run: python -m pytest -q
|
|
21
|
+
|
|
22
|
+
test-windows:
|
|
23
|
+
# Confirma no Windows o que o job `test` já confirma no Linux (achamos um bug só
|
|
24
|
+
# visível lá: arquivo de banco aberto ao apagar a pasta temporária, corrigido em 2026-09-24).
|
|
25
|
+
runs-on: windows-latest
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v4
|
|
28
|
+
- uses: actions/setup-python@v5
|
|
29
|
+
with:
|
|
30
|
+
python-version: "3.12"
|
|
31
|
+
- run: python -m pip install -e ".[dev]"
|
|
32
|
+
- name: Testes e avaliações (regressão da busca)
|
|
33
|
+
run: python -m pytest -q
|
|
34
|
+
|
|
35
|
+
instalacao-limpa:
|
|
36
|
+
# RNF-06: instala só o pacote construído (sem as dependências de desenvolvimento) e
|
|
37
|
+
# confere que `mini-tars --version` e um ciclo guardar/buscar funcionam.
|
|
38
|
+
runs-on: ubuntu-latest
|
|
39
|
+
steps:
|
|
40
|
+
- uses: actions/checkout@v4
|
|
41
|
+
- uses: actions/setup-python@v5
|
|
42
|
+
with:
|
|
43
|
+
python-version: "3.12"
|
|
44
|
+
- name: Constrói o pacote
|
|
45
|
+
run: |
|
|
46
|
+
python -m pip install build
|
|
47
|
+
python -m build
|
|
48
|
+
- name: Instala o pacote construído num ambiente novo, sem as dependências de dev
|
|
49
|
+
run: |
|
|
50
|
+
python -m venv /tmp/instalacao-limpa
|
|
51
|
+
/tmp/instalacao-limpa/bin/pip install dist/*.whl
|
|
52
|
+
- run: /tmp/instalacao-limpa/bin/mini-tars --version
|
|
53
|
+
- name: Guarda e busca um fato fictício (prova que o pacote funciona sozinho)
|
|
54
|
+
run: |
|
|
55
|
+
/tmp/instalacao-limpa/bin/python - <<'PY'
|
|
56
|
+
import tempfile
|
|
57
|
+
from pathlib import Path
|
|
58
|
+
|
|
59
|
+
from mini_tars.service import Service
|
|
60
|
+
from mini_tars.store import Store
|
|
61
|
+
|
|
62
|
+
d = Path(tempfile.mkdtemp())
|
|
63
|
+
svc = Service(Store(d / "m.db"))
|
|
64
|
+
svc.remember("fato fictício da instalação limpa")
|
|
65
|
+
resultado = svc.search("fato fictício instalação limpa")
|
|
66
|
+
assert resultado and resultado[0][0].text == "fato fictício da instalação limpa"
|
|
67
|
+
print("ok: instalação limpa funciona")
|
|
68
|
+
PY
|
|
69
|
+
|
|
70
|
+
dependencias:
|
|
71
|
+
# RNF-07: falha se alguma dependência tiver uma vulnerabilidade conhecida.
|
|
72
|
+
runs-on: ubuntu-latest
|
|
73
|
+
steps:
|
|
74
|
+
- uses: actions/checkout@v4
|
|
75
|
+
- uses: actions/setup-python@v5
|
|
76
|
+
with:
|
|
77
|
+
python-version: "3.12"
|
|
78
|
+
- run: python -m pip install --upgrade pip setuptools
|
|
79
|
+
- run: python -m pip install -e ".[dev]" pip-audit
|
|
80
|
+
- name: Verifica vulnerabilidades conhecidas nas dependências
|
|
81
|
+
run: python -m pip_audit
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
status: rascunho
|
|
3
|
+
atualizado: 2026-09-23
|
|
4
|
+
dono: Breno
|
|
5
|
+
---
|
|
6
|
+
# Hipóteses e riscos de aprendizado
|
|
7
|
+
|
|
8
|
+
Ordenadas da mais arriscada para a menos. "Como testar" é o experimento mais barato que dá evidência.
|
|
9
|
+
|
|
10
|
+
| # | Hipótese | Se for falsa | Como testar | Status |
|
|
11
|
+
| --- | --- | --- | --- | --- |
|
|
12
|
+
| H1 | Uma busca simples por palavra-chave recupera o fato certo na maioria dos casos | O projeto precisa de embeddings ou de outro método, e o escopo cresce | 30 fatos e 30 perguntas, medir acerto (ver `idea.md`) | Sustentada só em parte (2026-09-23): palavra-chave pura hit@3 72%, hit@1 41%, vocabulário 50%. Com o assistente reescrevendo a consulta: hit@3 83%, hit@1 55%, mas 5 de 6 perguntas sem resposta trazem ruído. Experimento 2 (124 fatos): hit@3 entre 55% e 72% (baseline) e entre 69% e 72% (reescrita), ruído 3 a 6 de 6; ganho da reescrita não confirmado como robusto. Experimento 3 (teste reservado, 18 perguntas): hit@3 72% (13/18) com desempate por regra, K1 passou por um acerto; ruído 4 de 5. Ver `decisions.md` e `evals/experimento-0{1,2,3}.md` |
|
|
13
|
+
| H2 | Desenvolvedores têm esse problema com força suficiente para instalar algo novo | Fica só como projeto pessoal e de portfólio | Entrevistas puladas por decisão do Breno; só o uso real após o lançamento (K3) testa | Não validada (risco aceito) |
|
|
14
|
+
| H3 | Desenvolvedores aceitam auto-hospedar (Docker ou Python local) em vez de usar um serviço pronto | Precisa de instalação de um comando ou de uma versão hospedada, que muda custo, legal e suporte | Teste de instalação limpa no CI; depois do lançamento, observar issues de instalação | Não validada (risco aceito) |
|
|
15
|
+
| H4 | O Breno consegue manter o projeto e o suporte com o tempo que tem para estudo | Reduzir escopo ou o número de usuários | Registrar horas reais por semana nas 6 primeiras semanas | Não testada |
|
|
16
|
+
| H5 | Uma memória própria oferece algo que alternativas existentes não oferecem | Melhor usar uma existente e focar o aprendizado em outra coisa | Pesquisa de concorrentes na fase 1 (fontes verificadas, estado atual) | Refutada como produto novo: o Basic Memory já cobre o mesmo espaço (ver `competitors.md`) |
|
|
17
|
+
|
|
18
|
+
Regra: uma hipótese só muda de status com evidência registrada em `docs/decisions.md`.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
status: rascunho
|
|
3
|
+
atualizado: 2026-09-23
|
|
4
|
+
dono: Breno
|
|
5
|
+
fontes: páginas dos repositórios no GitHub, abertas em 2026-09-23
|
|
6
|
+
---
|
|
7
|
+
# Concorrentes e alternativas (H5)
|
|
8
|
+
|
|
9
|
+
Dados lidos nas páginas dos repositórios em 2026-09-23. Números de estrelas e versões mudam; confirmar antes de citar. Onde a página não informou, está marcado "não informado" (não significa que não exista).
|
|
10
|
+
|
|
11
|
+
| Projeto | O que é | Licença | Estrelas | Armazenamento | MCP | Uso local |
|
|
12
|
+
| --- | --- | --- | --- | --- | --- | --- |
|
|
13
|
+
| [Basic Memory](https://github.com/basicmachines-co/basic-memory) | Memória em arquivos Markdown que humano e IA leem e escrevem; grafo de entidades, observações e relações | AGPL-3.0 | 3,6 mil | Markdown + SQLite (padrão) ou PostgreSQL | Sim (Claude Desktop, Claude Code, Cursor, VS Code, outros) | Sim; `uv tool install basic-memory` |
|
|
14
|
+
| [Graphiti (Zep)](https://github.com/getzep/graphiti) | Grafo de contexto temporal para agentes (fatos com janela de validade) | Apache-2.0 | 29 mil | Banco de grafos: Neo4j, FalkorDB, Neptune | Sim (servidor MCP incluído) | Sim, com Docker Compose; exige banco de grafos |
|
|
15
|
+
| [mem0](https://github.com/mem0ai/mem0) | Camada de memória para agentes de IA; busca híbrida (semântica, BM25, entidades) | Apache-2.0 | 65,9 mil | Vetorial (Qdrant citado); servidor com Docker Compose | Não informado na página | Sim, com Docker Compose; usa modelos da OpenAI por padrão |
|
|
16
|
+
| [Letta](https://github.com/letta-ai/letta) | Plataforma de agentes com estado e memória própria | Apache-2.0 | 24,7 mil | Não detalhado na página | Não informado claramente | Servidor local (`letta server`) e nuvem própria |
|
|
17
|
+
| [Tars](https://github.com/fonsecabc/tars) | Memória pessoal de usuário único, exposta ao Claude por MCP | MIT | 2 | PostgreSQL com pgvector | Sim (13 ferramentas) | Sim; Node.js, Docker |
|
|
18
|
+
|
|
19
|
+
Fonte adicional: README do Tars enviado pelo Breno (benchmark LOCOMO com modelos locais).
|
|
20
|
+
|
|
21
|
+
## O que isso diz sobre H5
|
|
22
|
+
|
|
23
|
+
**H5 ("uma memória própria oferece algo que as existentes não oferecem") não se sustenta como produto novo.** O concorrente mais próximo é o **Basic Memory**: Python, SQLite local, MCP, distribuição por PyPI, instalação em um comando, grafo de entidades e observações. É essencialmente o que o mini-Tars pretende ser, com 3,6 mil estrelas e mais de 1.700 commits.
|
|
24
|
+
|
|
25
|
+
Diferenças possíveis do mini-Tars, ainda não validadas:
|
|
26
|
+
|
|
27
|
+
- **Método de avaliação como parte do produto** (placar de recuperação reproduzível, como o benchmark do Tars). Nenhuma das páginas lidas destacou isso, mas não conferi a documentação interna de cada uma.
|
|
28
|
+
- **Escopo muito menor e mais simples de entender**, útil para aprender.
|
|
29
|
+
- **Licença permissiva** (MIT ou Apache) em vez de AGPL, relevante para quem não quer copyleft.
|
|
30
|
+
|
|
31
|
+
## Consequência para o projeto
|
|
32
|
+
|
|
33
|
+
Como as entrevistas foram puladas (H2, H3) e a H5 fica fraca, o projeto se sustenta hoje **como aprendizado e portfólio**, não como produto que compete no mercado. Isso muda a decisão sobre o esforço em onboarding, suporte e documentação para terceiros, que está proposto como "mínimo até haver sinal de uso" em `depth.md`.
|
|
34
|
+
|
|
35
|
+
Opções para o Breno decidir (registrar em `docs/decisions.md`):
|
|
36
|
+
|
|
37
|
+
1. **Manter o mini-Tars como projeto de aprendizado**, com foco em arquitetura, testes e avaliações, e divulgar sem promessa de suporte.
|
|
38
|
+
2. **Reposicionar em torno das avaliações:** um pequeno kit de avaliação de recuperação de memória que funcione com qualquer servidor MCP (inclusive Basic Memory). Diferencia do que existe e é bom material de portfólio, mas exige validar que alguém quer isso.
|
|
39
|
+
3. **Contribuir com o Basic Memory** em vez de criar outro, e usar o mini-Tars só como estudo privado. Aprende-se com código real e o portfólio mostra contribuição aceita.
|
|
40
|
+
4. **Parar aqui** e escolher outro projeto de teste do processo (o critério K1 e a regra de "matar cedo" existem para isso).
|
|
41
|
+
|
|
42
|
+
## Limites desta pesquisa
|
|
43
|
+
|
|
44
|
+
- Leitura feita só das páginas iniciais dos repositórios, resumidas por ferramenta automática. Detalhes (por exemplo, suporte a MCP no mem0 e no Letta, motores de armazenamento do Letta) não foram confirmados na documentação.
|
|
45
|
+
- Não foram avaliados serviços proprietários nem outros projetos de memória para MCP. Uma busca adicional por "MCP memory server" pode revelar mais alternativas.
|
|
46
|
+
- Não testei nenhum deles na prática; a comparação de qualidade de recuperação depende do teste da fase 2.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
status: rascunho
|
|
3
|
+
atualizado: 2026-09-23
|
|
4
|
+
dono: Breno
|
|
5
|
+
---
|
|
6
|
+
# Ideia
|
|
7
|
+
|
|
8
|
+
## Problema (sem citar a solução)
|
|
9
|
+
Quem trabalha com assistentes de IA em vários projetos perde contexto entre sessões. Decisões, preferências e o estado de cada projeto precisam ser repetidos. Quando ficam em arquivos soltos, eles se desatualizam e se contradizem, e o assistente age com informação velha.
|
|
10
|
+
|
|
11
|
+
## Para quem
|
|
12
|
+
Desenvolvedores que usam assistentes de IA (Claude Code e similares) em vários projetos. Primeiro usuário: o próprio Breno.
|
|
13
|
+
|
|
14
|
+
## Modelo de distribuição
|
|
15
|
+
Auto-hospedado: cada pessoa roda o servidor na própria máquina (ou no próprio servidor), com os próprios dados. O Breno não opera nem armazena dados de ninguém.
|
|
16
|
+
|
|
17
|
+
## Por que agora
|
|
18
|
+
O MCP virou um padrão para conectar ferramentas a assistentes de IA, e projetos como o Tars mostram que uma memória pessoal desse tipo é viável.
|
|
19
|
+
|
|
20
|
+
## Objetivo do projeto
|
|
21
|
+
Principal (decisão de 2026-09-23): **aprender e montar portfólio** com Python e FastAPI, MCP, testes e avaliações, e arquitetura com decisões registradas. Não é um produto que compete com o Basic Memory (ver `competitors.md`).
|
|
22
|
+
Secundário: se outros desenvolvedores usarem, ótimo; isso é medido só por K3, sem promessa de suporte.
|
|
23
|
+
|
|
24
|
+
## Hipótese mais arriscada
|
|
25
|
+
A recuperação traz o fato certo, e não ruído, com uma busca simples. Se isso falhar, o resto do sistema não importa.
|
|
26
|
+
|
|
27
|
+
## Validação barata (fase 2)
|
|
28
|
+
Antes de construir o servidor:
|
|
29
|
+
1. Escrever cerca de 30 fatos sobre um projeto do Breno e 30 perguntas com a resposta esperada.
|
|
30
|
+
2. Medir quantas vezes uma busca simples por palavra-chave devolve o fato certo.
|
|
31
|
+
3. Entrevistas com usuários: puladas por decisão do Breno (ver `docs/decisions.md`). A demanda de outros desenvolvedores só será testada pelo uso real, após o lançamento (K3).
|
|
32
|
+
|
|
33
|
+
## Fora de escopo por ora
|
|
34
|
+
Busca semântica com embeddings, versão hospedada, aplicativo móvel, painel web, cobrança.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
status: rascunho (números a confirmar pelo Breno)
|
|
3
|
+
atualizado: 2026-09-23
|
|
4
|
+
dono: Breno
|
|
5
|
+
---
|
|
6
|
+
# Critérios de parada
|
|
7
|
+
|
|
8
|
+
Definidos antes de investir. Formato: se [métrica] não atingir [valor] até [prazo], então [ação].
|
|
9
|
+
Contagem de prazo começa na data de aprovação deste arquivo. Mudar um critério depois de ver o resultado é sinal de apego, não de aprendizado, e deve ser registrado em `docs/decisions.md`.
|
|
10
|
+
|
|
11
|
+
| # | Se | Até | Então |
|
|
12
|
+
| --- | --- | --- | --- |
|
|
13
|
+
| K1 | A busca simples acertar menos de 70% das perguntas do teste da fase 2 | Fim da fase 2 | Testar uma alternativa (por exemplo, embeddings). Como é projeto de aprendizado, também é válido seguir e documentar o porquê da falha, desde que registrado em `decisions.md` |
|
|
14
|
+
| K2 | (Removido em 2026-09-23: entrevistas puladas por decisão do Breno. A demanda passa a ser testada só por K3) | n/a | n/a |
|
|
15
|
+
| K3 | Menos de 3 pessoas (além do Breno) usarem por pelo menos 3 sessões por semana | 6 semanas após o lançamento | Não é motivo para encerrar (projeto de aprendizado): manter só como portfólio, sem suporte ativo. Só reforça o corte de onboarding e documentação |
|
|
16
|
+
| K4 | O Breno gastar mais de 5 horas por semana em suporte e manutenção | Qualquer semana, 2 vezes seguidas | Reduzir escopo ou pausar novos usuários |
|
|
17
|
+
| K5 | Surgir qualquer custo recorrente para o Breno (meta: R$ 0 por mês) | Qualquer mês | Pausar o item que gera o custo ou migrar para alternativa gratuita |
|
|
18
|
+
| K6 | Vulnerabilidade de segurança relevante encontrada em versão já distribuída | Imediato | Corrigir, publicar aviso e orientar atualização; se não houver correção em 7 dias, retirar a versão |
|
|
19
|
+
|
|
20
|
+
Teto de custo confirmado pelo Breno: R$ 0. Stack gratuita: GitHub (repositório, Actions, Pages, registro de contêineres), PyPI e SQLite local.
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
---
|
|
2
|
+
status: rascunho
|
|
3
|
+
atualizado: 2026-09-23
|
|
4
|
+
dono: Breno
|
|
5
|
+
---
|
|
6
|
+
# Arquitetura do MVP
|
|
7
|
+
|
|
8
|
+
Decisões individuais, com alternativas e consequências, ficam em `docs/adr/`. Este arquivo mostra o conjunto. Os ADRs 0001 a 0005 foram aceitos pelo Breno em 2026-09-23.
|
|
9
|
+
|
|
10
|
+
## Visão geral
|
|
11
|
+
```
|
|
12
|
+
Assistente de IA (Claude Code etc.) <-- cliente MCP
|
|
13
|
+
| |
|
|
14
|
+
stdio (padrão) HTTP em 127.0.0.1 (opcional, token fora do local)
|
|
15
|
+
| |
|
|
16
|
+
+------ mini-tars (processo Python) ------+
|
|
17
|
+
|
|
|
18
|
+
Camada MCP (ferramentas) remember | search | forget | list_recent
|
|
19
|
+
|
|
|
20
|
+
Serviço (regras): validação, datas, substituição, sinal de resultado fraco
|
|
21
|
+
| |
|
|
22
|
+
Busca (índice em memória) Armazenamento (SQLite)
|
|
23
|
+
palavra-chave, desempate um arquivo no diretório de dados do usuário
|
|
24
|
+
por regra (evals/) migrações versionadas, backup antes de migrar
|
|
25
|
+
|
|
26
|
+
CLI: mini-tars serve | export | import | --version (usa o mesmo Serviço)
|
|
27
|
+
```
|
|
28
|
+
Nenhuma chamada de rede de saída. Nenhum serviço do Breno.
|
|
29
|
+
|
|
30
|
+
## Componentes e responsabilidades
|
|
31
|
+
| Módulo (`src/mini_tars/`) | Responsabilidade | Depende de |
|
|
32
|
+
| --- | --- | --- |
|
|
33
|
+
| `models.py` | Tipos: Fato, Resultado, erros do domínio | nada |
|
|
34
|
+
| `config.py` | Caminho dos dados, porta, token, limites; lê variáveis de ambiente | nada |
|
|
35
|
+
| `store.py` | SQLite: criar, ler, substituir, apagar, migrar, backup antes de migrar | `models` |
|
|
36
|
+
| `search.py` | Normalização, índice, pontuação, desempate por regra, sinal de resultado fraco. **Mesmo algoritmo de `evals/run_exp03.py`** | `models` |
|
|
37
|
+
| `service.py` | Regras de negócio: valida entradas, aplica datas em America/Sao_Paulo, substituição, mantém o índice em sincronia com o banco | `store`, `search` |
|
|
38
|
+
| `mcp_server.py` | Declara as ferramentas MCP e converte para chamadas do serviço; rotula texto de fato como dado | `service` |
|
|
39
|
+
| `http_app.py` | Modo HTTP (FastAPI ou Starlette), token e escuta local | `mcp_server`, `config` |
|
|
40
|
+
| `cli.py` | Comandos `serve`, `export`, `import` | `service`, `http_app` |
|
|
41
|
+
|
|
42
|
+
Regra de dependência: de cima para baixo na tabela; `search.py` e `store.py` não se conhecem (é o `service.py` que os liga). Isso permite testar a busca sem banco e trocá-la (por exemplo, por embeddings) sem tocar no armazenamento.
|
|
43
|
+
|
|
44
|
+
## Modelo de dados
|
|
45
|
+
```sql
|
|
46
|
+
CREATE TABLE facts (
|
|
47
|
+
id INTEGER PRIMARY KEY,
|
|
48
|
+
text TEXT NOT NULL CHECK (length(text) BETWEEN 1 AND 2000),
|
|
49
|
+
fact_date TEXT NOT NULL, -- AAAA-MM-DD, data local (America/Sao_Paulo)
|
|
50
|
+
project TEXT, -- opcional
|
|
51
|
+
created_at TEXT NOT NULL, -- UTC, ISO 8601
|
|
52
|
+
superseded_by INTEGER REFERENCES facts(id) -- preenchido quando outro fato substitui este
|
|
53
|
+
);
|
|
54
|
+
CREATE INDEX idx_facts_project ON facts(project);
|
|
55
|
+
-- versão do esquema: PRAGMA user_version
|
|
56
|
+
```
|
|
57
|
+
Regra de escrita: **uma afirmação por fato** (ver limite de RF-03 nos requisitos). Nada de campos livres extras no MVP.
|
|
58
|
+
|
|
59
|
+
## Contratos das ferramentas MCP
|
|
60
|
+
Todos os resultados incluem o texto do fato dentro de um campo `data`, com um aviso curto de que é conteúdo guardado pelo usuário e não instrução (RNF-02).
|
|
61
|
+
|
|
62
|
+
| Ferramenta | Entrada | Saída |
|
|
63
|
+
| --- | --- | --- |
|
|
64
|
+
| `remember` | `text` (obrigatório), `date` (opcional, AAAA-MM-DD), `project` (opcional), `supersedes` (opcional, id) | `{id}` ou erro |
|
|
65
|
+
| `search` | `query` (obrigatório), `limit` (1 a 10, padrão 3), `project` (opcional), `include_superseded` (padrão falso) | lista de `{id, data: {text, date, project}, score, weak_match, superseded_by?}` |
|
|
66
|
+
| `forget` | `id` | `{deleted: true}` ou erro |
|
|
67
|
+
| `list_recent` | `limit` (padrão 10), `project` (opcional) | lista de fatos ativos |
|
|
68
|
+
|
|
69
|
+
Erros têm mensagem em português clara e código estável (`empty_text`, `text_too_long`, `unknown_id`, `invalid_date`).
|
|
70
|
+
|
|
71
|
+
## Segurança (modelo de ameaças resumido)
|
|
72
|
+
| Ameaça | Risco | Controle |
|
|
73
|
+
| --- | --- | --- |
|
|
74
|
+
| Porta aberta para a rede sem autenticação | R2 | Escuta em 127.0.0.1; outra interface só com token; recusa iniciar sem token (RNF-01) |
|
|
75
|
+
| Texto guardado que tenta comandar o assistente | R3 | Saída marcada como dado, aviso na documentação; limite honesto: o servidor não controla o assistente (RNF-02) |
|
|
76
|
+
| Dependência vulnerável | R5 | Poucas dependências, verificação no CI, versões fixadas (RNF-07) |
|
|
77
|
+
| Perda de dados ao atualizar | R6 | Migração com backup antes; exportar e importar (RF-08, RNF-04) |
|
|
78
|
+
| Vazamento por log | R3/R2 | Logs sem o texto dos fatos (RNF-03) |
|
|
79
|
+
| Página de outro site chamando o servidor local pelo navegador | novo, a tratar no modo HTTP | Validar cabeçalho `Origin` e `Host`; recusar origens que não sejam locais |
|
|
80
|
+
|
|
81
|
+
O último item foi identificado agora e ainda não está em `risks.md`: entra como R13 (ver `docs/risks.md`).
|
|
82
|
+
|
|
83
|
+
## Estratégia de testes
|
|
84
|
+
| Nível | O que cobre | Ferramenta |
|
|
85
|
+
| --- | --- | --- |
|
|
86
|
+
| Unitário | `search.py` (normalização, desempate, sinal fraco), `service.py` (validação, datas, substituição) | pytest |
|
|
87
|
+
| Armazenamento | `store.py` com SQLite em arquivo temporário; migração de banco antigo | pytest |
|
|
88
|
+
| Contrato MCP | Cliente MCP de teste chama as ferramentas nos dois modos e confere formato e erros | pytest |
|
|
89
|
+
| Segurança | Bind sem token falha; cabeçalhos de origem; texto de injeção devolvido como dado; logs sem conteúdo | pytest |
|
|
90
|
+
| Avaliações | `evals/` como regressão: hit@3 no ajuste ≥ 19 de 29; modos padrão e histórico registrados | script de `evals/` chamado no CI |
|
|
91
|
+
| Instalação limpa | Instala o pacote construído e roda uma busca | job do CI |
|
|
92
|
+
|
|
93
|
+
Fixtures: só os dados fictícios de `evals/`.
|
|
94
|
+
|
|
95
|
+
## Distribuição e CI (nível Mínimo, planos gratuitos a confirmar)
|
|
96
|
+
Pacote Python publicado no PyPI; imagem Docker opcional. CI no GitHub Actions: testes, avaliações, instalação limpa e verificação de dependências. **A publicação é sempre feita pelo Breno** (`CLAUDE.md`). Limites dos planos gratuitos ainda precisam ser confirmados na fonte oficial antes de depender deles.
|
|
97
|
+
|
|
98
|
+
## Passo zero da construção: verificação técnica (feita em 2026-09-23)
|
|
99
|
+
Confirmado no SDK Python do MCP (linha 2.x, `MCPServer`, `mcp>=2,<3`): stdio, HTTP e montagem no FastAPI funcionam; a proteção de `Host` e `Origin` já vem no SDK. Detalhes e ressalvas no ADR-0003.
|
|
100
|
+
|
|
101
|
+
## Decisões do Breno (resolvidas em 2026-09-23)
|
|
102
|
+
1. **Nome do pacote e do comando**: `mini-tars` (conferir se o nome está livre no PyPI antes de publicar).
|
|
103
|
+
2. **Licença**: MIT.
|
|
104
|
+
3. **Versão mínima do Python**: 3.11.
|
|
105
|
+
4. **ADRs 0001 a 0005**: aprovados.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
status: rascunho
|
|
3
|
+
atualizado: 2026-09-23
|
|
4
|
+
dono: Breno
|
|
5
|
+
---
|
|
6
|
+
# Requisitos do MVP
|
|
7
|
+
|
|
8
|
+
Prioridade: **M** (precisa estar no MVP), **S** (deveria; entra se o tempo permitir), **C** (poderia; depois). Cada requisito tem critério de aceite que um teste ou uma avaliação consegue verificar, e uma origem (hipótese, risco ou decisão), para rastrear.
|
|
9
|
+
|
|
10
|
+
## Funcionais
|
|
11
|
+
| ID | Requisito | Prior. | Critério de aceite | Origem |
|
|
12
|
+
| --- | --- | --- | --- | --- |
|
|
13
|
+
| RF-01 | **Guardar fato** (`remember`): texto (até 2.000 caracteres), data do fato (padrão: hoje em America/Sao_Paulo) e projeto opcional | M | Devolve o id; o fato existe após reiniciar o servidor; texto vazio ou acima do limite é recusado com mensagem clara | idea.md |
|
|
14
|
+
| RF-02 | **Buscar** (`search`): consulta em linguagem natural devolve até 3 fatos (configurável até 10) ordenados por relevância, com id, texto, data, pontuação e sinal de resultado fraco | M | Usa a busca base dos experimentos (palavra-chave, desempate por regra); no conjunto de ajuste `evals/cases.grande.json`, hit@3 ≥ 66% (19 de 29) | H1, R1, experimento 3 |
|
|
15
|
+
| RF-03 | **Substituir fato** (`remember` com `supersedes`): marca o fato antigo como substituído; a busca padrão ignora os substituídos, e `include_superseded` traz também o histórico | M | Nos casos f16→f17 (preço) e f05→f18 (donos dos testes), a busca padrão devolve só o atual e com `include_superseded` devolve também o antigo. Atenção: a pergunta temporal q06 ("em março, quem olhava os testes?") tem como resposta o fato antigo f05, então só funciona no modo histórico; as avaliações precisam registrar o modo de cada pergunta, e o hit@3 dos dois modos é medido e registrado. Limite: substituir um fato esconde tudo o que ele dizia (f05 também dizia quem cuidava da infraestrutura); por isso a regra de escrita é **uma afirmação por fato** | M | tipos "corrigido" (50%) e "temporal" |
|
|
16
|
+
| RF-04 | **Apagar fato** (`forget`): remoção definitiva por id | M | Após apagar, o fato não aparece em busca, exportação nem no arquivo do banco; apagar id inexistente devolve erro claro. **Limite documentado:** os arquivos de backup criados antes de uma migração (`.bak-vN`) mantêm o conteúdo antigo; o usuário deve apagá-los se quiser eliminar o fato de vez (README) | depth.md (dados) |
|
|
17
|
+
| RF-05 | **Sinal de resultado fraco** (`weak_match`) no resultado da busca, sem filtrar | S | Definido a partir da pontuação relativa da consulta; medido nas avaliações e registrado. Meta (revista em 2026-09-23 depois de medir; ver decisions.md): as perguntas sem resposta do ajuste voltam vazias ou sinalizadas em pelo menos 5 de 6, e no máximo 1 em cada 5 primeiros resultados corretos é sinalizado por engano | R12; experimento 3 (filtro perdia acertos, sinal não) |
|
|
18
|
+
| RF-06 | **Projeto** como espaço de nomes: `project` opcional em `remember`, `search` e `list_recent` | S | Busca com `project` só devolve fatos daquele projeto; a pontuação (idf) é calculada só dentro do projeto | idea.md |
|
|
19
|
+
| RF-07 | **Listar recentes** (`list_recent`): últimos N fatos ativos | S | Ordem por data do fato, depois por criação | uso diário |
|
|
20
|
+
| RF-08 | **Exportar e importar** por linha de comando, em JSON com versão do esquema | M | Exportar e importar em banco vazio reproduz o mesmo conteúdo (incluindo substituições); importar arquivo de versão desconhecida falha com aviso | R6, depth.md (backup) |
|
|
21
|
+
| RF-09 | **Iniciar o servidor**: `mini-tars serve` (stdio por padrão) e `mini-tars serve --http` (HTTP local) | M | Um cliente MCP real lista as ferramentas e chama `remember` e `search` nos dois modos | idea.md |
|
|
22
|
+
| RF-10 | **Configuração**: caminho do banco padrão no diretório de dados do usuário, alterável por variável de ambiente ou opção | M | Nenhum caminho fixo do computador do Breno no código; nenhum segredo em arquivo do repositório | CLAUDE.md |
|
|
23
|
+
|
|
24
|
+
## Não funcionais
|
|
25
|
+
| ID | Requisito | Prior. | Critério de aceite | Origem |
|
|
26
|
+
| --- | --- | --- | --- | --- |
|
|
27
|
+
| RNF-01 | **Escuta local por padrão**: o modo HTTP escuta em 127.0.0.1; outra interface só com token configurado | M | Teste: iniciar com `0.0.0.0` sem token falha; com token, exige cabeçalho de autorização; sem token no modo local, funciona | R2, K6 |
|
|
28
|
+
| RNF-02 | **Conteúdo recuperado é dado**: a saída das ferramentas marca o texto dos fatos como dados não confiáveis, e a documentação explica o risco | M | Teste com fato que contém "ignore as instruções anteriores": é devolvido literalmente, dentro do campo de dados, sem ser tratado como comando. Limite: não garante que o assistente obedeça | R3 |
|
|
29
|
+
| RNF-03 | **Privacidade**: sem telemetria; logs sem o texto dos fatos | M | Teste procura texto de fato de teste nos logs; nenhuma chamada de rede de saída no servidor | depth.md, CLAUDE.md |
|
|
30
|
+
| RNF-04 | **Migrações versionadas** com backup automático antes de migrar | M | Teste migra um banco antigo e confere o conteúdo; falha na migração deixa o banco original intacto (a transação é desfeita) e o arquivo de backup permanece | R6 |
|
|
31
|
+
| RNF-05 | **Avaliações como regressão** no CI | M | O CI roda `evals/` e falha se o hit@3 no ajuste ficar abaixo de 19 de 29. Mudar a busca exige novo conjunto de teste (o atual está esgotado) | H1, R1 |
|
|
32
|
+
| RNF-06 | **Instalação em um comando** (por exemplo `pipx` ou `uv tool`), testada em ambiente limpo no CI | S | Job do CI instala do pacote construído e roda `mini-tars --version` e uma busca | R4, H3 |
|
|
33
|
+
| RNF-07 | **Dependências verificadas** automaticamente | S | Job do CI com verificação de vulnerabilidades conhecidas; falha em relevante | R5, K6 |
|
|
34
|
+
| RNF-08 | **Fuso e datas**: datas do fato em America/Sao_Paulo; carimbos internos em UTC | M | Teste em torno da meia-noite: fato criado às 23h30 locais recebe a data local | CLAUDE.md |
|
|
35
|
+
| RNF-09 | **Desempenho**: busca responde rápido com milhares de fatos | C | Medir com 5.000 fatos em um computador comum e registrar o p95; a meta será definida depois de medir (sem número sem evidência) | uso diário |
|
|
36
|
+
| RNF-10 | **Sem dado real** em testes, fixtures e exemplos | M | Revisão do reviewer; fixtures são os fatos fictícios de `evals/` | CLAUDE.md |
|
|
37
|
+
|
|
38
|
+
## Fora do escopo (decisão registrada)
|
|
39
|
+
Embeddings (só depois, com experimento novo e conjunto de teste novo), painel web, versão hospedada, sincronização, multiusuário, importação automática de notas, autenticação por usuário.
|
|
40
|
+
|
|
41
|
+
## Rastreabilidade
|
|
42
|
+
| Hipótese ou risco | Requisitos que tratam |
|
|
43
|
+
| --- | --- |
|
|
44
|
+
| H1 recuperação (R1) | RF-02, RF-03, RNF-05 |
|
|
45
|
+
| R12 ruído com confiança | RF-05, RNF-02 |
|
|
46
|
+
| R2 servidor exposto | RNF-01 |
|
|
47
|
+
| R3 injeção de prompt | RNF-02 |
|
|
48
|
+
| R4 instalação difícil (H3) | RNF-06 |
|
|
49
|
+
| R5 vulnerabilidades (K6) | RNF-07 |
|
|
50
|
+
| R6 migração perde dados | RF-08, RNF-04 |
|
|
51
|
+
| K5 custo zero | Restrição da visão; RNF-06 e RNF-07 usam só planos gratuitos |
|
|
52
|
+
|
|
53
|
+
## Critérios de pronto do MVP
|
|
54
|
+
Todos os requisitos M atendidos e verificados por teste ou avaliação; README com instalação em um comando e aviso "sem garantia" e "nenhum dado sai da sua máquina"; o Breno consegue explicar cada diff (`CLAUDE.md`).
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
status: rascunho
|
|
3
|
+
atualizado: 2026-09-23
|
|
4
|
+
dono: Breno
|
|
5
|
+
---
|
|
6
|
+
# Visão do produto
|
|
7
|
+
|
|
8
|
+
## Em uma frase
|
|
9
|
+
Um servidor de memória, auto-hospedado e feito em Python, que deixa um assistente de IA guardar e recuperar fatos sobre os seus projetos entre sessões, com recuperação medida por avaliações que qualquer pessoa consegue reproduzir.
|
|
10
|
+
|
|
11
|
+
## Problema e público
|
|
12
|
+
Ver `00-descobrir/idea.md`. Desenvolvedores que usam assistentes de IA em vários projetos perdem decisões, preferências e estado do projeto entre sessões. Primeiro usuário: o Breno.
|
|
13
|
+
|
|
14
|
+
## Objetivo do projeto (ordem de importância)
|
|
15
|
+
1. **Aprender e montar portfólio**: Python e FastAPI, MCP, testes, avaliações e arquitetura com decisões registradas (decisão de 2026-09-23).
|
|
16
|
+
2. **Ser útil ao Breno** no dia a dia, como memória dos próprios projetos.
|
|
17
|
+
3. **Outros desenvolvedores usarem**, sem promessa de suporte (K3 mede isso).
|
|
18
|
+
|
|
19
|
+
## O que torna este projeto diferente
|
|
20
|
+
Não é a funcionalidade: o Basic Memory já cobre o espaço (`competitors.md`). O que é próprio, e o que o README deve mostrar:
|
|
21
|
+
- **Avaliações reproduzíveis**: o repositório traz o conjunto de fatos e perguntas, o script e os protocolos pré-registrados (`evals/`). Qualquer pessoa roda e confere os números.
|
|
22
|
+
- **Decisões registradas** (`docs/decisions.md` e ADRs em `docs/adr/`), incluindo o que deu errado.
|
|
23
|
+
- **Correções explícitas**: um fato pode substituir outro, e a busca devolve o atual (RF-03).
|
|
24
|
+
|
|
25
|
+
## Princípios
|
|
26
|
+
1. **Local primeiro.** Os dados ficam na máquina do usuário. Sem telemetria, sem conta, sem serviço do Breno.
|
|
27
|
+
2. **Dizer "não sei" é melhor que inventar.** A busca sinaliza resultado fraco em vez de apresentar ruído como certeza (R12).
|
|
28
|
+
3. **Conteúdo recuperado é dado, nunca instrução** (R3).
|
|
29
|
+
4. **Simples e medido antes de sofisticado.** Nenhuma técnica de busca entra sem passar pelas avaliações (lição dos experimentos 1 a 3).
|
|
30
|
+
5. **Seguro por padrão.** Escuta só em 127.0.0.1; qualquer outra interface exige token (R2).
|
|
31
|
+
|
|
32
|
+
## Escopo do MVP
|
|
33
|
+
Dentro: guardar, buscar, substituir e apagar fatos; exportar e importar; servidor MCP por stdio e por HTTP local; avaliações e testes no CI.
|
|
34
|
+
Fora (por ora): embeddings e busca semântica, painel web, versão hospedada, sincronização entre máquinas, várias pessoas no mesmo servidor, importação automática de notas.
|
|
35
|
+
Detalhes e critérios de aceite em `requisitos.md`.
|
|
36
|
+
|
|
37
|
+
## Como saberemos que funcionou
|
|
38
|
+
| Objetivo | Medida | Meta |
|
|
39
|
+
| --- | --- | --- |
|
|
40
|
+
| Aprender | ADRs escritos, testes e avaliações no CI, servidor rodando com um cliente MCP real | MVP funcionando de ponta a ponta |
|
|
41
|
+
| Recuperação (H1, K1) | hit@3 no conjunto de ajuste (`evals/cases.grande.json`) | não cair abaixo de 66% (19/29); K1 mantém o mínimo de 70% em conjunto de teste novo |
|
|
42
|
+
| Uso próprio | O Breno usa o mini-Tars em pelo menos um projeto real por 4 semanas | sim ou não, registrado no `handoff.md` |
|
|
43
|
+
| Uso por outros (K3) | Colegas ativos além do Breno, 3 sessões por semana | menos de 3 em 6 semanas: manter como portfólio |
|
|
44
|
+
| Custo (K5) | Custo recorrente | R$ 0 |
|
|
45
|
+
|
|
46
|
+
## Restrições
|
|
47
|
+
- Custo recorrente zero (K5): nada de domínio, hospedagem ou serviço pago.
|
|
48
|
+
- Tempo do Breno limitado (K4, R7): escopo pequeno.
|
|
49
|
+
- Sem dados reais de ninguém em testes, fixtures ou logs (`CLAUDE.md`).
|
|
50
|
+
- Fuso America/Sao_Paulo (`CLAUDE.md`).
|
|
51
|
+
|
|
52
|
+
## Perguntas em aberto para o Breno
|
|
53
|
+
Ver o fim de `arquitetura.md` (seção "Decisões que dependem do Breno"): nome do pacote, licença e versão mínima do Python.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# mini-Tars
|
|
2
|
+
|
|
3
|
+
Servidor de memória (MCP) para assistentes de IA, feito em Python com FastAPI.
|
|
4
|
+
Status do projeto: fase 4 (entregar) aprovada em 2026-09-24. MVP completo (todos os requisitos M).
|
|
5
|
+
|
|
6
|
+
## Como navegar
|
|
7
|
+
Leia primeiro `CONTEXT.md` (índice). Estado atual em `docs/handoff.md`. Decisões em `docs/decisions.md`.
|
|
8
|
+
|
|
9
|
+
## Regras permanentes
|
|
10
|
+
- Nunca ler nem editar `.env`, chaves ou qualquer credencial.
|
|
11
|
+
- Nunca fazer deploy, nem publicar nada: só o Breno faz.
|
|
12
|
+
- Toda mudança de comportamento precisa de teste ou de caso em `evals/`.
|
|
13
|
+
- Fuso horário sempre America/Sao_Paulo, nunca o padrão do servidor.
|
|
14
|
+
- Dado que não puder ser interpretado com confiança: perguntar, nunca gravar.
|
|
15
|
+
- Outras pessoas vão usar (auto-hospedado): nenhum dado real de ninguém em testes, fixtures ou logs; o servidor escuta só em 127.0.0.1 por padrão.
|
|
16
|
+
- Se a especificação estiver ambígua, registrar a dúvida em `docs/handoff.md` em vez de adivinhar.
|
|
17
|
+
- Se o Breno não conseguir explicar um diff, o diff não é aceito.
|
|
18
|
+
|
|
19
|
+
## Fluxo
|
|
20
|
+
Especificação em `01-definir/` -> construtor implementa -> revisor (contexto separado, só leitura) revisa -> Breno aprova.
|
|
21
|
+
|
|
22
|
+
## Comandos
|
|
23
|
+
- Testes: `python -m pytest -q`
|
|
24
|
+
- Medir a busca: `python evals/run_pkg.py -v`
|
|
25
|
+
- Servidor MCP (stdio): `mini-tars serve` (banco em `MINI_TARS_DB` ou `--db`)
|
|
26
|
+
- Servidor MCP (HTTP local): `mini-tars serve --http` (token fora do local em `MINI_TARS_TOKEN`)
|
|
27
|
+
- Exportar/importar: `mini-tars export saida.json` / `mini-tars import saida.json` (import exige banco vazio)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
status: rascunho
|
|
3
|
+
atualizado: 2026-09-23
|
|
4
|
+
dono: Breno
|
|
5
|
+
---
|
|
6
|
+
# Índice do projeto
|
|
7
|
+
|
|
8
|
+
Para cada pergunta, o arquivo que responde. Leia só o que precisar.
|
|
9
|
+
|
|
10
|
+
| Pergunta | Arquivo |
|
|
11
|
+
| --- | --- |
|
|
12
|
+
| Que problema resolvemos e para quem? | `00-descobrir/idea.md` |
|
|
13
|
+
| O que ainda não sabemos e pode invalidar o projeto? | `00-descobrir/assumptions.md` |
|
|
14
|
+
| Quando paramos ou mudamos de direção? | `00-descobrir/kill-criteria.md` |
|
|
15
|
+
| Quem já faz algo parecido? | `00-descobrir/competitors.md` |
|
|
16
|
+
| Quanto rigor cada área exige? | `depth.md` |
|
|
17
|
+
| O que já foi decidido, e por quê? | `docs/decisions.md` |
|
|
18
|
+
| O que pode dar errado? | `docs/risks.md` |
|
|
19
|
+
| Em que ponto estamos e o que vem agora? | `docs/handoff.md` |
|
|
20
|
+
| Como medimos a recuperação (H1)? | `evals/README.md` |
|
|
21
|
+
| Regras que valem sempre | `CLAUDE.md` |
|
|
22
|
+
| Que produto é, para quê e o que fica fora? | `01-definir/visao.md` |
|
|
23
|
+
| O que o MVP precisa fazer e como verificamos? | `01-definir/requisitos.md` |
|
|
24
|
+
| Como é o sistema por dentro? | `01-definir/arquitetura.md` |
|
|
25
|
+
| Por que cada decisão técnica? | `docs/adr/` |
|
|
26
|
+
|
|
27
|
+
Pastas ainda não criadas (aparecem conforme as fases): `02-entregar/`, `.claude/agents/`, `src/`.
|
mini_tars-0.0.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Breno Henrique Bortoloti Santos
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|