# ADR-055: System ripgrep fallback + memory-doctor status checks

## Статус
Accepted (2026-07-29)

## Контекст

Keyword search (ripgrep) в memory-системе заявлен в README как "always
works", но на практике system `rg` не был установлен нигде — только
npm-пакет `@vscode/ripgrep` через volume-mount (хрупко, platform-specific).
CI не устанавливал ripgrep. `memory-doctor` имел 4 диагностических gap'а:
allGreen проверял `rgBin!==null` вместо `r.status===0`, расхождение
`allowSystemFallback` с memory-search, нет arch-mismatch detection,
require-ошибки не попадали в отчёт.

## Решение

- **Dual ripgrep source**: `@vscode/ripgrep` (npm, primary) + system `rg`
  через apt (fallback). Dockerfile и CI устанавливают оба.
- **`resolveRgBinary({ allowSystemFallback: true })`** в memory-doctor —
  консистентно с memory-search (раньше doctor не пробовал system fallback,
  что расходилось с реальным поведением search).
- **`checkRipgrep` возвращает `{ lines, rgWorks }`** — `rgWorks` =
  `rgBin!==null && r.status===0`. `allGreen` использует `rgWorks`, не
  `rgBin!==null` — закрывает G9 (битый бинарник с существующим path).
- **`detectArchMismatch()`** — эвристика по имени path бинарника (contains
  'darwin'/'linux'/'win32' + 'arm64'/'x64'). Не вызывает `file` — portable.
- **Warning в stderr** при `rgBin===null` в memory-search — вместо
  молчаливого skip. Упрощает диагностику.

## Альтернативы

- **Только system rg (убрать npm-пакет)**: rejected — npm-пакет даёт
  pinned version и не зависит от distro package manager; Dockerfile slim
  image может не иметь rg в apt без extra repos.
- **Только npm-пакет (убрать apt)**: rejected — volume-mount хрупок,
  CI runner без npm install для .opencode/package.json = нет rg.
- **`file` command для arch-mismatch**: rejected — extra dependency,
  эвристика по path покрывает основной случай (@vscode/ripgrep platform
  dir names стандартизированы).