From 3aa533000357ef046324e332b83d4005cf33c4ad Mon Sep 17 00:00:00 2001 From: Sergey <93754860+slaid098@users.noreply.github.com> Date: Sun, 26 Jul 2026 20:12:15 +0300 Subject: [PATCH] fix(memory): setup step 5 check index.json + align docs to real state (#85) * fix(memory): check index.json not .rag dir in setup step 5 * docs(readme): align to real state after memory PRs * chore(env): remove dead vars from env example * docs(handoff): add handoff + ADR-037 for memory setup step5 fix * docs(handoff): set PR number --------- Co-authored-by: opencode-agent --- .env.example | 4 --- .opencode/scripts/setup-memory.sh | 4 +-- README.md | 15 ++++++---- .../037-pr-85-memory-setup-step5-docs.md | 28 ++++++++++++++++++ docs/handoff/pr-85-memory-setup-step5-docs.md | 29 +++++++++++++++++++ 5 files changed, 69 insertions(+), 11 deletions(-) create mode 100644 docs/decisions/037-pr-85-memory-setup-step5-docs.md create mode 100644 docs/handoff/pr-85-memory-setup-step5-docs.md diff --git a/.env.example b/.env.example index e4aa67f..de93f02 100644 --- a/.env.example +++ b/.env.example @@ -11,7 +11,6 @@ OPENAI_BASE_URL=https://openrouter.ai/api/v1 OPENAI_API_KEY=your-openrouter-api-key OPENAI_EMBEDDING_MODEL=qwen/qwen3-embedding-8b OPENAI_EMBEDDING_BATCH_SIZE=50 -OPENAI_EMBEDDING_BATCH_DELAY=1 MEMORY_CHUNK_SIZE=512 MEMORY_CHUNK_OVERLAP=64 @@ -29,9 +28,6 @@ TELEGRAM_API_ID=your-telegram-api-id TELEGRAM_API_HASH=your-telegram-api-hash TELEGRAM_BOT_TOKEN=your-telegram-bot-token -# Redis (optional) -REDIS_PASSWORD=your-redis-password - # Cloudflare Tunnel (optional — see separate tunnel repo) CLOUDFLARE_TUNNEL_TOKEN= TUNNEL_DOMAIN= diff --git a/.opencode/scripts/setup-memory.sh b/.opencode/scripts/setup-memory.sh index beb743c..78d916b 100755 --- a/.opencode/scripts/setup-memory.sh +++ b/.opencode/scripts/setup-memory.sh @@ -75,9 +75,9 @@ else echo " [4/6] hook correct" fi -# 5. .rag index exists? → memory index (no) | noop (yes) +# 5. .rag/index.json exists? → memory index (no) | noop (yes) if "$MEMORY_PYTHON" -c "import src.memory" >/dev/null 2>&1; then - if [ ! -d "$MEMORY_DIR/.rag" ]; then + if [ ! -f "$MEMORY_DIR/.rag/index.json" ]; then echo " [5/7] building RAG index (memory CLI)" ( "$MEMORY_PYTHON" -m src.memory index "$MEMORY_DIR" -o "$MEMORY_DIR/.rag" ) 2>&1 \ || echo " memory index failed — continuing" diff --git a/README.md b/README.md index a0fafc2..dee2fac 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,6 @@ Docker-based AI coding assistant with persistent memory — opencode configurati ```bash git clone https://github.com/slaid098/opencode-config.git cd opencode-config -mkdir -p app_data/{workspaces,ssh} cp .env.example .env # fill in your keys docker compose up -d ``` @@ -31,12 +30,11 @@ opencode # .opencode/ auto-discovered - `agents/` — subagent definitions (docs-reviewer, memory-syncer, reviewer) - `commands/` — slash commands (run-pipeline, spec, configure-opencode) - `skills/` — skill definitions (14 skills) - - `tools/` — custom tools (pipeline-status, spec-status, merge-pr) + - `tools/` — custom tools (commit, create-issue, create-pr, memory-setup, merge-pr, pipeline-status, post-docs-review, post-review, spec-status, tunnel) - `scripts/` — Python scripts (pipeline-status, spec-status, check-adr-refs, etc.) - `opencode.json` — main config (providers, MCP servers, permissions) - `app_data/workspaces/` — agent working directory - `app_data/ssh/` — SSH keys (not in git) -- `app_data/opencode-memory/` — persistent memory (separate git repo) - `src/` — Python RAG CLI (memory) - `docs/` — handoffs, decisions (ADRs), project map - `.github/workflows/` — CI workflows (ubuntu-latest) @@ -49,16 +47,23 @@ Copy `.env.example` to `.env` and fill in: |----------|-------------| | `AI_PROVIDER_BASE_URL` | AI provider API URL | | `AI_PROVIDER_API_KEY` | AI provider API key | +| `OPENAI_BASE_URL` | Embeddings API URL (OpenRouter default) | +| `OPENAI_API_KEY` | Embeddings API key (OpenRouter) | +| `OPENAI_EMBEDDING_MODEL` | Embedding model (default: `qwen/qwen3-embedding-8b`) | +| `OPENAI_EMBEDDING_BATCH_SIZE` | Embedding batch size (default: 50) | | `OPENCODE_SERVER_PASSWORD` | opencode server password | | `GITHUB_TOKEN` | GitHub personal access token | | `CONTEXT7_API_KEY` | Context7 MCP API key | +| `OPENCODE_MEMORY_REMOTE` | Git remote for your opencode-memory fork (required) | +| `MEMORY_CHUNK_SIZE` | Memory index chunk size (default: 512) | +| `MEMORY_CHUNK_OVERLAP` | Memory index chunk overlap (default: 64) | | `ANTIDETECT_BROWSER_MCP_URL` | Antidetect browser MCP URL (optional) | ## Memory setup -Memory uses `@mathew-cf/opencode-memory` plugin (hybrid search: ripgrep + local RAG). +Memory uses `@mathew-cf/opencode-memory` plugin (hybrid search: ripgrep + cloud embeddings (OpenRouter Qwen3 8B)). -- `OPENCODE_MEMORY_DIR` env var points to memory directory (default: `app_data/opencode-memory/`) +- `OPENCODE_MEMORY_DIR` env var points to memory directory (default: `/root/.local/share/opencode/opencode-memory`) - `OPENCODE_MEMORY_REMOTE` must point at your git remote — fork the upstream [`slaid098/opencode-memory`](https://github.com/slaid098/opencode-memory) repo and set the URL in `.env` - Run `.opencode/scripts/setup-memory.sh` to initialize memory repo diff --git a/docs/decisions/037-pr-85-memory-setup-step5-docs.md b/docs/decisions/037-pr-85-memory-setup-step5-docs.md new file mode 100644 index 0000000..0395ebc --- /dev/null +++ b/docs/decisions/037-pr-85-memory-setup-step5-docs.md @@ -0,0 +1,28 @@ +# ADR-037: setup-memory.sh step 5 — check index.json, not .rag dir + +## Статус + +Accepted (2026-07-26) + +## Контекст + +setup-memory.sh step 5 проверял наличие директории `$MEMORY_DIR/.rag` через `[ ! -d ... ]`, чтобы решить, нужно ли пересобирать RAG индекс. После внедрения Python memory CLI (PR#75) и wrapper'а для opencode-memory plugin (PR#77), наш формат индекса — `index.json` в директории `.rag/`. Однако оригинальный Rust rag-cli (который plugin использовал до wrapper'а) создаёт `meta.json` + `index.bin` в той же директории `.rag/`. + +Баг: если Rust rag-cli уже отработал, директория `.rag/` существует, но содержит stale Rust-формат без `index.json`. Проверка `[ ! -d "$MEMORY_DIR/.rag" ]` возвращает false → step 5 пропускает rebuild → plugin продолжает использовать Rust rag-cli (wrapper не перезаписан, индекс не в нашем формате). End-to-end проверка после PR#77/#83 подтвердила это: wrapper не перезаписывался, meta.json в Rust схеме. + +## Решение + +Заменить проверку директории на проверку файла индекса: +`[ ! -d "$MEMORY_DIR/.rag" ]` → `[ ! -f "$MEMORY_DIR/.rag/index.json" ]`. + +Теперь step 5 форсирует rebuild, если: +- директория `.rag/` не существует (fresh install), ИЛИ +- директория существует, но `index.json` отсутствует (stale Rust-формат, частичный индекс, удалённый файл). + +Это гарантирует, что после первого запуска setup-memory.sh с новым кодом индекс будет в нашем Python memory CLI формате, а wrapper (step 5b) перезапишется при следующем запуске plugin'а. + +## Альтернативы + +- **Проверять `meta.json` (Rust-формат) и удалять директорию целиком.** Отклонено: деструктивно, может удалить валидный наш индекс при ложном срабатывании. Безопаснее проверять наличие нашего файла, чем absence чужого. +- **Всегда пересобирать индекс (unconditional rebuild).** Отклонено: ломает idempotent-контракт setup-memory.sh (тест `test_idempotent` ожидает, что 3-й запуск = 1-й по snapshot). Rebuild при каждом запуске = ~минута лишней работы + нагрузка на embeddings API. +- **Проверять содержимое `index.json` (схему/версию).** Отклонено: over-engineering для bash-скрипта. Проверка существования файла достаточна — формат валидируется Python memory CLI при загрузке. \ No newline at end of file diff --git a/docs/handoff/pr-85-memory-setup-step5-docs.md b/docs/handoff/pr-85-memory-setup-step5-docs.md new file mode 100644 index 0000000..9c096f5 --- /dev/null +++ b/docs/handoff/pr-85-memory-setup-step5-docs.md @@ -0,0 +1,29 @@ +--- +pr: 85 +title: fix(memory): setup step 5 check index.json + align docs to real state +--- + +## Что сделано + +- `.opencode/scripts/setup-memory.sh` step 5: проверка `[ ! -d "$MEMORY_DIR/.rag" ]` заменена на `[ ! -f "$MEMORY_DIR/.rag/index.json" ]`. Теперь скрипт проверяет наличие нашего индексного файла (формат Python memory CLI), а не саму директорию — это форсирует rebuild, если остался stale Rust rag-cli индекс (meta.json + index.bin без index.json). +- `README.md` Quick start: убран `mkdir -p app_data/{workspaces,ssh}` (директории уже в репо с .gitkeep). +- `README.md` Structure: убрана строка `app_data/opencode-memory/` (runtime dir, не в репо); tools list обновлён до актуальных 10 tools (commit, create-issue, create-pr, memory-setup, merge-pr, pipeline-status, post-docs-review, post-review, spec-status, tunnel). +- `README.md` Configuration: таблица расширена с 6 до 13 vars (+7: OPENAI_BASE_URL, OPENAI_API_KEY, OPENAI_EMBEDDING_MODEL, OPENAI_EMBEDDING_BATCH_SIZE, OPENCODE_MEMORY_REMOTE, MEMORY_CHUNK_SIZE, MEMORY_CHUNK_OVERLAP). +- `README.md` Memory setup: "local RAG" → "cloud embeddings (OpenRouter Qwen3 8B)"; default OPENCODE_MEMORY_DIR исправлен с `app_data/opencode-memory/` на `/root/.local/share/opencode/opencode-memory`. +- `.env.example`: удалён `OPENAI_EMBEDDING_BATCH_DELAY` (dead — не используется в embedder.py); удалён `REDIS_PASSWORD` + комментарий (dead — нигде не используется). Telegram и Cloudflare оставлены. + +## Почему + +После merge PR#77 (setup-memory.sh wrapper) и PR#83 (incremental index) end-to-end проверка показала, что plugin продолжал использовать оригинальный Rust rag-cli: wrapper не перезаписывался, meta.json оставался в Rust схеме, index.bin лежал рядом. Причина — баг в step 5: проверка `[ ! -d "$MEMORY_DIR/.rag" ]` всегда false, если Rust rag-cli уже создавал директорию. Проверка `index.json` (наш формат) форсирует rebuild при рассинхронизации форматов. + +README и .env.example устарели после PR#75/#77/#83: инструкции создавали уже существующие директории, описывали "local RAG" вместо cloud embeddings, таблица конфига была неполной, dead env vars вводили в заблуждение. + +## Pending + +— (после merge: удалить stale Rust rag-cli index вручную при первом запуске setup-memory.sh — step 5 пересоберёт в нашем формате) + +## Watch out + +- ADR-037 зафиксировал решение проверять index.json, не директорию — при будущих правках setup-memory.sh не откатывать к dir-check. +- README tools list содержит 10 .ts tools (без _shared.ts, который вспомогательный). +- Если добавится новый tool — обновить README Structure tools list. \ No newline at end of file