Files
memo/README.md
T

120 lines
6.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# memo
Локальная библиотека заметок с семантическим поиском.
**Markdown на диске — истина, `.db` рядом — пересобираемый кэш.** Агент (или человек) пишет и
читает обычные `.md`-файлы своими штатными средствами: `memo` не требует ни специального API записи,
ни изменения привычек. Он следит за файловой системой, держит рядом с каждой папкой-темой
индекс (SQLite + sqlite-vec + FTS5) и отвечает на смысловые вопросы гибридным поиском
(BM25 + вектор + RRF).
## Статус
Реализовано и принято на эталонном корпусе. 38 тестов, мутационная проверка, сквозной recall@5 = 20/20.
| Что | Вердикт приёмки |
|---|---|
| юнит-тесты всех модулей | ✅ |
| мутационная проверка (13 мутаций) | ✅ все убиты |
| индексация: 3 коллекции, повторный прогон — 0 обновлений | ✅ |
| recall@5 на эталонном корпусе (sem 20/20, lex 3/3) | ✅ |
| MCP-протокол живым клиентом + холодный старт | ✅ |
## Идея
- Коллекций (папок-тем) — сколько угодно; они не мешают друг другу.
- **Коллекция — каталог, в котором есть `*.md` напрямую** (не в подкаталогах). Вложенные папки
без своих заметок коллекциями не считаются — иначе одни и те же файлы индексируются по нескольку раз.
- Индекс каждой коллекции живёт в её `.memo/index.db` и **удаляется без потерь** — пересобирается.
- Поиск — обычный read-only инструмент; записи в markdown он не делает никогда.
- Только локально: эмбеддинг на CPU, сеть не нужна ни при индексации, ни при поиске.
## Состав (JVM-first, один Gradle-проект)
```
memo-cli # memo index|search|status — ручные проверки и приёмка без агента
memo-core # чанкер по заголовкам, sqlite-схема, инкрементальная переиндексация, гибридный поиск
memo-watch # демон: WatchService + debounce + реконсиляция по mtime
memo-mcp # MCP-сервер (stdio): memo_search / memo_status / memo_reindex
```
`memo-core` не знает ни про watcher, ни про MCP — это драйверы поверх ядра.
## Быстрый старт
```bash
./gradlew installDist # собрать все дистрибутивы
CLI=memo-cli/build/install/memo/bin/memo
$CLI index ~/notes # проиндексировать дерево (коллекции найдутся сами)
$CLI search ~/notes "чем чинят карточку в jellyfin"
$CLI search ~/notes "76.132" --mode lex --json
$CLI status ~/notes
```
MCP-сервер (stdio), регистрируется как обычный MCP-сервер:
```json
{
"mcpServers": {
"memo": {
"command": "/opt/memo/memo-mcp",
"env": { "MEMO_MODEL_DIR": "/opt/memo/models/siglip2" }
}
}
}
```
Инструменты: `memo_search(path, query, k, mode)`, `memo_status(path)`, `memo_reindex(path)`.
`memo_search` **сам создаёт индекс**, если его ещё нет — можно просто писать `.md` и сразу искать.
Демон слежения (для правок мимо агента — людьми, git, сторонними редакторами):
```bash
memo-watch/build/install/memo-watch/bin/memo-watch ~/notes
```
## Приёмка
```bash
bash scripts/accept.sh # полный прогон: сборка, тесты, мутации, индекс, recall, MCP
bash scripts/accept.sh --fast # то же без мутационной проверки (самая долгая)
```
Правило проекта: **«зелёная сборка» ничего не доказывает.** Тесты проверяются мутациями
(`e2e/mutations.tsv`): боевой код ломается, и нужный тест обязан упасть. Выжившая мутация —
дыра в покрытии, а не удача. Приёмка идёт на реальном корпусе (`scripts/make_e2e_corpus.sh`),
а не на моках.
## Документы
| Документ | Что внутри |
|---|---|
| [`docs/SPEC.md`](docs/SPEC.md) | полная спека: модель данных, индекс, маршрутизация, watcher, интерфейс, приёмка |
| [`TASK.md`](TASK.md) | ТЗ для исполнителя: стек, схема БД, контракты, чего не делать |
| [`TESTING.md`](TESTING.md) | тест-план: приёмочные проверки, команды, признаки провала |
| [`docs/orders/`](docs/orders/) | журнал заказов исполнителю — с доказательствами дефектов, а не «сделай хорошо» |
## Зависимости (проверено 02.10.2026)
| Что | Координата | Откуда |
|---|---|---|
| SQLite + sqlite-vec + FTS5 | `pw.binom.db:ksqlite:0.1.4` | Maven Central |
| Текстовый эмбеддинг (SigLIP2 int8, 768 dims) | `pw.binom.ai.embeddingtext:api:5` + `:siglip:5` | `http://nexus.xx/repository/caffeine/` |
Модель (в артефакты не входит, скачивается отдельно):
```bash
mkdir -p models/siglip2
curl -fSL -o models/siglip2/text_model_int8.onnx http://static.binom.pw/models/siglip2/text_model_int8.onnx # 283M
curl -fSL -o models/siglip2/tokenizer.model http://static.binom.pw/models/siglip2/tokenizer.model # 4.2M
```
## Требования
JDK 21. Индекс и поиск работают офлайн после скачивания модели.
## Лицензия
Apache-2.0.