Metadata-Version: 2.5
Name: doubled-graph
Version: 3.0.1
Summary: MCP facade over CodeGraphContext + GRACE 4 (.grace artifacts): impact, context, drift-detect, migration for LLM-driven codebases.
Project-URL: Homepage, https://github.com/rour/doubled-graph-mcp
Project-URL: Repository, https://github.com/rour/doubled-graph-mcp
Project-URL: Issues, https://github.com/rour/doubled-graph-mcp/issues
Project-URL: Documentation, https://github.com/rour/doubled-graph-mcp/blob/main/docs/SPEC.md
Author: doubled-graph methodology authors
License: MIT
License-File: LICENSE
Keywords: ast,claude,codebase,continue,cursor,graph,llm,mcp
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Software Development
Classifier: Topic :: Software Development :: Code Generators
Classifier: Topic :: Software Development :: Documentation
Requires-Python: <3.15,>=3.11
Requires-Dist: anyio>=4.15.1
Requires-Dist: codegraphcontext<0.7,>=0.6.13
Requires-Dist: mcp<2,>=1.30.0
Requires-Dist: pydantic>=2.14.1
Requires-Dist: tree-sitter-language-pack>=1.22.1
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == 'dev'
Requires-Dist: hatchling>=1.25; extra == 'dev'
Requires-Dist: mutmut<4,>=3.8.1; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest-cov>=5; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.5; extra == 'dev'
Description-Content-Type: text/markdown

# doubled-graph

MCP-сервер для LLM-агентов, работающих с большими кодовыми базами.

Проблема: агент правит код не зная, кто вызывает функцию и какой у неё контракт — получаем регрессии и тихий дрейф. `doubled-graph` даёт агенту два графа одновременно:

- **Computed graph** — AST-граф реального кода (через CodeGraphContext): кто вызывает что, где определено.
- **Declared graph** — граф из артефактов GRACE 4 (`.grace/`): замысел, контракты, верификация.

Четыре доменных MCP-инструмента (плюс `health`, `migrate_check` и четыре gateway над `grace`):

| Инструмент | Когда |
|---|---|
| `analyze` | построить/обновить граф |
| `impact` | радиус влияния изменений — **до** правки |
| `context` | 360° вид: символ + контракт + вызовы |
| `detect_changes` | дрейф кода от артефактов — **до** коммита |

`detect_changes` возвращает шесть типов дрейфа: `code_without_module`, `module_without_code`, `contract_mismatch`, `stale_crosslinks`, `missing_verification`, `markup_missing`. `contract_mismatch` сверяет `<Exports>`, `MODULE_MAP` и `INPUTS` контрактов с AST-сигнатурой (имена; типы — только если CGC их отдаёт), `stale_crosslinks` — с реальными `CALLS`/`IMPORTS`-рёбрами между файлами модулей.

---

## Установка

**Требования:** Python **3.11–3.14** (3.15 не поддерживается: `codegraphcontext`
0.6.13 требует `ladybug<0.20,>=0.19`, а эта линия публикует колёса только до
cp314 — на 3.15 pip не может разрешить зависимость), Bun ≥ 1.3.14 или Node+tsx
(движок `@osovv/grace-cli` 4.2.1), [pipx](https://pipx.pypa.io/).

`doubled-graph` — CLI-утилита. Рекомендуемый способ — `pipx`: он ставит её в изолированный venv и кладёт бинарь в PATH. Это также обходит PEP 668 (`externally-managed-environment`) на современных Homebrew/Debian/Ubuntu.

### 1. Установить pipx

| OS | Команда |
|---|---|
| macOS | `brew install pipx` |
| Debian / Ubuntu | `sudo apt install pipx` |
| Fedora | `sudo dnf install pipx` |
| Arch | `sudo pacman -S python-pipx` |
| Windows / прочее | `python3 -m pip install --user pipx` |

После установки один раз добавьте pipx-папку в PATH и перезапустите терминал:

```bash
pipx ensurepath
```

### 2. Установить doubled-graph

На PyPI сейчас опубликована **2.1.0**. Версия **3.0.0 в PyPI ещё не
опубликована**, поэтому `pipx install doubled-graph` (без версии) на
поддерживаемом Python поставит 2.1.0, а `doubled-graph --version` покажет не
3.0.0. Чтобы поставить именно
3.0.0 из этого репозитория, соберите wheel поддерживаемым интерпретатором
(3.11–3.14) и установите его **с явным `--python`**: если сам pipx запущен
на 3.15, его venv тоже будет 3.15, и pip откажется ставить пакет.

```bash
python3.14 -m pip install build
python3.14 -m build --wheel
pipx install --python python3.14 --force dist/doubled_graph-3.0.0-py3-none-any.whl
```

Подойдёт любой минор из 3.11–3.14; `--python python3.14` — пример. После
публикации релиза команда станет обычной и точной:

```bash
pipx install --python python3.14 doubled-graph==3.0.0   # до релиза — wheel выше
```

> Уже работаете в своём venv или conda-окружении? `python3.14 -m pip install
> doubled-graph` из PyPI тоже поставит 2.1.0; для 3.0.0 используйте wheel:
> `python3.14 -m pip install dist/doubled_graph-3.0.0-py3-none-any.whl`.

---

## Первые шаги

### 1. Онбординг репозитория

```bash
cd your-project
doubled-graph setup
```

Одна команда:
- установит `@osovv/grace-cli@4.2.1` через первый найденный JS-менеджер (`bun` → `npm` → `yarn` → `pnpm`); если Bun отсутствует — поставит `tsx` тем же менеджером и запустит grace под Node. Установленный движок 3.x будет обновлён: он умеет читать только `docs/*.xml`
- подготовит артефакты `.grace`: мигрирует GRACE 3 `docs/*.xml` (копирование, без удаления исходников) или создаст пустой скелет Grace 4, если артефактов нет вовсе
- скопирует `prompts/` и `methodology/` в репозиторий
- запишет 7 наших skills в native-формат для всех известных IDE одновременно (`.claude/skills/`, `.cursor/rules/`, `.continue/rules/`, `.roo/rules/`, `.kilocode/rules/`, `.opencode/rules/` + `opencode.json`, `.windsurfrules`) — мы не знаем, каким клиентом вы пользуетесь
- зарегистрирует MCP-сервер в вашей IDE (Claude Code / Cursor / Continue)
- установит `git post-commit` хук для автообновления графа. Хук вызывает `doubled-graph` из `PATH` (в отличие от `.mcp.json`, куда `setup` пишет абсолютный путь к интерпретатору); если бинаря в `PATH` нет, коммит не блокируется, а в `.doubled-graph/logs/post-commit.log` появляется строка `'doubled-graph' is not on PATH; skipped incremental analyze…`
- поставит **демон графа** (`graphd`) как сервис ОС (launchd / `systemd --user` /
  Task Scheduler) и зарегистрирует проект в `~/.doubled-graph/state.json`;
  повторный `setup` не создаёт второй сервис и не перезапускает исправный
- запустит первый полный `analyze`

Если хотя бы один из этих шагов завершился ошибкой (например, битый
`docs/knowledge-graph.xml` не дал создать `.grace`, или первый `analyze`
получил `CGC_BACKEND_FAIL`/не обработал ни одного файла), команда завершается
с **rc=1**, в JSON-отчёте `ok: false` и `failed_steps` перечисляет сломанные
шаги; строка «Setup complete.» не печатается. Явные `--skip-*` — это
осознанный отказ, а не ошибка. `DOUBLED_GRAPH_NO_SERVICE=1` — **dev/test-
переключатель**, а не пользовательский флаг: он пропускает шаг 10 (установку
сервиса `graphd`), `setup` остаётся rc=0, но JSON-отчёт содержит
`warnings: ["daemon_not_installed: …"]`, и в консоль печатается `WARNING`.
Для обычной установки этот переменной быть не должно.

> **Важно:** `setup` при каждом запуске **перезаписывает** скопированные
> `prompts/` и `methodology/` версиями из установленного пакета
> (`_copy_bundle` всегда пишет файлы заново, чтобы после `pipx upgrade`
> не оставались устаревшие workflow). Не редактируйте их на месте — правки
> будут потеряны при следующем `setup`. Для локальных изменений скопируйте
> нужный файл в отдельный путь проекта и ссылайтесь на него оттуда;
> исходные `prompts/`/`methodology/` в репозитории считайте managed-контентом.

> **Сетевые side effects.** Кроме установки `grace-cli`/`tsx`, `setup` может
> один раз переустановить сам пакет: если CGC не импортируется из-за
> отсутствующих колёс для текущего Python, шаг 2 «CGC dep self-heal» вызывает
> `pipx install --python python3.12|3.13|3.14 --force doubled-graph==<установленная
> версия>` (`setup.py::_auto_reinstall_on_working_python`). Версия
> **запинена**: команда без версии поставила бы опубликованную 2.1.0 и молча
> откатила 3.0. Это единственная сетевая переустановка пакета; при `--dry-run`
> она только репортится (`status: "dry_run_reinstall"`), а при `pip install` в
> venv/CI не выполняется вовсе (`_looks_like_pipx_install()`). Если сети нет
> или такой версии ещё нет на PyPI, шаг честно возвращает `reinstall_failed`
> с `exit_code`/`stderr_tail` и командой для ручного повтора, а `setup`
> продолжает работу.

Посмотреть план без реальных изменений:

```bash
doubled-graph setup --dry-run
```

Явно указать IDE:

```bash
doubled-graph setup --ide claude-code
```

### 2. Подключить MCP вручную (если нужно)

Рекомендуем `doubled-graph setup` — он сам сгенерирует `.mcp.json` с правильными значениями (абсолютный путь к Python, не `doubled-graph` из PATH). Если ни один IDE не обнаружен, `setup` всё равно пишет корневой `.mcp.json` в формате Claude Code; `--ide none` — явный отказ от регистрации. Это важно: GUI-приложения (Claude Desktop, Cursor, Continue) на macOS стартуют без `~/.local/bin` в PATH, и простая запись `command: "doubled-graph"` у них не работает.

Если нужно прописать руками — используйте абсолютный путь к Python, в который установлен `doubled-graph`:

```bash
# Узнать путь к нужному Python:
doubled-graph --version  # проверить, что бинарь работает
head -1 "$(which doubled-graph)"  # вывести shebang — это и есть нужный python
```

`.mcp.json` в корне репозитория:

```json
{
  "mcpServers": {
    "doubled-graph": {
      "command": "/Users/you/.local/pipx/venvs/doubled-graph/bin/python",
      "args": ["-m", "doubled_graph", "serve"]
    }
  }
}
```

### 3. Инициализация

Введите в ваш ИИ первый промт. Остальные промты он сам подгрузит.

Сценарий 1. Новый проект — `prompts/new-project/00-entry-prompt.md`.

Сценарий 2. Миграция существующего — `prompts/migrate-existing-project/00-entry-prompt.md`.

Сценарий 3. Обновление версии методики (2.x → 3.0) — `prompts/upgrade-methodology/00-entry-prompt.md`.

### 4. Проверить, что всё встало

```bash
doubled-graph --version          # 3.0.0 (после wheel-установки выше; 2.1.0 при pipx install из PyPI)
doubled-graph status --repo .    # artifacts.project_kind = grace4, grace_engine.upgrade_required = false
doubled-graph daemon status      # installed = true, running = true
doubled-graph health --repo .    # cgc.ok = true (демон ответил)
doubled-graph lint --repo .      # summary.errors = 0
doubled-graph migrate check --repo .   # map_pending / placeholders — что осталось заполнить
```

Если `project_kind` = `grace3` — артефакты ещё не перенесены: `doubled-graph setup --repo .`.
Если `upgrade_required` = `true` — движок старее 4.x: `npm install -g @osovv/grace-cli@4.2.1`, затем `setup` повторно.
Если `daemon.running` = `false`, а `health.cgc.ok` = `false` — демон не запущен: выполните `doubled-graph setup` в обычном шелле (из песочницы `launchctl`/`systemctl` могут быть запрещены), затем `daemon status`. Без демона графовые команды возвращают `CGC_BACKEND_FAIL` и rc=1 — это не «пустой граф».
Если `health.cgc.diagnostic` = `FalkorDB Lite previously failed to start…` — в 3.0.0 это была памятка о прошлой неудаче, а не причина. В 3.0.1 кэш сбрасывается перед каждой попыткой, а мёртвый `falkordb.sock` и осиротевший `graph.settings` удаляются автоматически: первый `analyze`/`setup` чинит репозиторий сам, `health.cgc.repaired` перечисляет удалённое. Если ошибка осталась — это настоящий сбой движка: `daemon logs` и `cgc.backend`.
Если `lint` вернул `markup.module-map-missing` — это содержательная работа, промпт `prompts/upgrade-methodology/01-content-gaps.md`.

Полная проверка (ruff + unit + real-CGC E2E + diff/version): `bash scripts/verify.sh`; критерии готовности — [docs/VERIFICATION.md](docs/VERIFICATION.md).

В 3.0: `detect_changes` проверяет `<Exports>`/`MODULE_MAP`/`INPUTS` и реальные CALLS/IMPORTS-рёбра, `impact` отдаёт `anchor`, `include_unchanged` расширяет охват, а `DG-Authored`-трейлер ставится через `prepare-commit-msg`. Установить все хуки: `doubled-graph init-hooks --all` (git + Claude Code + provenance); без Claude Code — `--post-commit --prepare-commit-msg`.


---

## Другие команды

```bash
# Диагностика миграции GRACE 3 -> GRACE 4 (ничего не пишет)
doubled-graph migrate check

# Миграция артефактов (legacy docs/*.xml остаются на месте)
doubled-graph migrate apply --dry-run
doubled-graph migrate apply

# Шлюз к движку: линт, модули, файлы, верификации
doubled-graph lint
doubled-graph module show M-AUTH
doubled-graph module health M-AUTH
doubled-graph file show src/auth.py
doubled-graph verify V-M-AUTH
doubled-graph status
doubled-graph --version

# Обновить граф вручную
doubled-graph analyze --mode auto

# 360° контекст символа
doubled-graph context validateUser

# Текущая фаза методологии (migration | post_migration)
doubled-graph phase get
doubled-graph phase set post_migration --reason "migration complete"

# Удалить всё, что поставил setup (сервис/state; с флагом — артефакты в репо)
doubled-graph uninstall
doubled-graph uninstall --purge-project
```

---

## Демон графа (`graphd`)

Начиная с 3.0 движок CGC и его база живут не в процессе IDE, а в демоне
`graphd`. Это нужно для песочниц (macOS Seatbelt, контейнеры, read-only home,
NFS-home): CGC при инициализации пишет `graph.settings` и Unix-сокет рядом с
`db_path`, и в песочнице падает с `Operation not permitted`. Клиент в песочнице
не пишет в исходники, `.grace` или корень проекта (единственная его запись —
`.doubled-graph/`: fingerprint, лог `analyze` и runtime-файл `.lock`) и не
запускает движок — он только спрашивает демон.

```bash
# Установить/проверить сервис (идемпотентно; ничего не удаляет)
doubled-graph daemon install
doubled-graph daemon start

# Состояние: сервис + живой демон + реестр проектов
doubled-graph daemon status

# Логи и foreground-режим для отладки
doubled-graph daemon logs --lines 100
doubled-graph daemon run

# Удалить сервис — только явной командой; setup этого не делает
doubled-graph daemon uninstall
```

`daemon status` завершается с rc=0, только если живой демон ответил на `ping`;
если сервис установлен, но не запущен (или не установлен вовсе), rc=1 и
`daemon.running: false` — это диагностический код, а не сбой установки.

`daemon uninstall` честен и при отказе супервизора: если `launchctl bootout` /
`systemctl disable --now` вернул ошибку, команда выводит `status: "failed"` и
rc=2, а unit-файл **остаётся** на месте — иначе загруженный сервис остался бы
без файла, которым его можно остановить или продиагностировать. После снятия
unit команда удаляет и discovery, оставшийся от SIGKILL/краха: `daemon.json`
(токен), `graphd.pid`, `daemon.sock`, `graphd.lock`; реестр `state.json`
сохраняется. Полное удаление вместе с реестром — `doubled-graph uninstall`
(§Удаление). `daemon run --transport pipe` на macOS/Linux завершается rc=2 с
`{"error": "TRANSPORT_UNSUPPORTED"}` (pipe доступен только Windows).

Демон — один на пользователя, слушает AF_UNIX (macOS/Linux), named pipe
(Windows) или TCP `127.0.0.1` + 128-битный токен, если путь Unix-сокета не
влезает в 104 байта. Держит не более N живых движков (по умолчанию 1, максимум
2), закрывает простаивающие и сериализует запросы к одному репозиторию. Реестр
и токен — в `~/.doubled-graph/` с правами 0700/0600. Контракт —
[docs/DAEMON.md](docs/DAEMON.md).

**Без демона** инструменты не деградируют молча: `analyze`, `impact`,
`context` и `detect-changes` возвращают `CGC_BACKEND_FAIL`/`CGC_QUERY_FAIL` и
**rc=1 без всяких флагов** (JSON с warning и командой `doubled-graph daemon
install` всё равно печатается), `health.cgc.daemon` показывает
`installed/running/version`. `--strict`/`--fail-on-drift` добавляют свои
проверки (пустой индекс / дрейф), но не являются единственным честным путём:
CI-скрипт не примет пустой граф за успешный ответ. `analyze` при
`CGC_ANALYZE_FAIL` тоже rc=1. Автоматически поднимать движок из песочного
процесса инструмент не будет — `fork/exec` наследует Seatbelt-профиль.

Переменные окружения для отладки и CI (production их не требует):
`DOUBLED_GRAPH_HOME` (каталог состояния), `DOUBLED_GRAPH_ENGINE=local`
(явный standalone-режим без демона), `DOUBLED_GRAPH_TRANSPORT=tcp|unix|pipe`,
`DOUBLED_GRAPH_SERVICE_BACKEND=launchd|systemd|taskscheduler`,
`DOUBLED_GRAPH_NO_SERVICE=1` (только тесты/CI: `setup` не трогает супервизор,
шаг 10 пропускается и помечается warning'ом `daemon_not_installed`).
`DOUBLED_GRAPH_CGC_HOME` переопределяет родительский каталог per-repo БД CGC
(по умолчанию `$HOME`; тесты используют его, чтобы не писать в настоящий
`~/.codegraphcontext`). Клиент и демон должны видеть одно и то же значение,
иначе они откроют разные графы одного репозитория.

## Если `Operation not permitted` (Seatbelt, контейнер, read-only home)

Это не баг doubled-graph, а запрет на запись в `~/.codegraphcontext`, где CGC
держит БД и Unix-сокет. Проверьте, что демон установлен и запущен:

```bash
doubled-graph daemon status      # installed: true, running: true
doubled-graph health             # cgc.daemon.running = true, cgc.ok = true
```

Если `running: false` — `doubled-graph daemon install && doubled-graph daemon start`.
Установка сервиса требует обычного шелла (в песочнице `launchctl`/`systemctl`
могут быть запрещены); после установки из песочницы можно только «будить»
уже существующий сервис. Если сервис поставить нельзя вообще, явно включите
standalone-режим `DOUBLED_GRAPH_ENGINE=local` и запускайте из обычного шелла —
но не из песочницы.

---

## Удаление

Сначала — одной командой, пока CLI ещё установлен:

```bash
doubled-graph uninstall                 # сервис + state-каталог (~/.doubled-graph)
doubled-graph uninstall --purge-project # + артефакты setup в текущем репозитории
```

`uninstall` останавливает и выгружает сервис **даже если демон уже умер или не
отвечает**, удаляет unit, `daemon.json` (с 128-битным токеном), `graphd.pid`,
`daemon.sock`, `graphd.lock`, `state.json` и логи самого демона
(`logs/graphd*.log`; чужие файлы в `logs/` сохраняются), а затем per-repo БД
CGC зарегистрированных репозиториев
(`<CGC home>/.codegraphcontext/repos/<slug>-<hash>/`, где `<CGC home>` —
`$HOME` или `DOUBLED_GRAPH_CGC_HOME`). Последние удаляются только по записям
реестра: нечитаемый `state.json` даёт `engine_dbs.status: "unverified"` и не
удаляет ничего, а уцелевшая БД — `ok: false` с сохранением реестра для
повторной попытки. Затем — только с `--purge-project` — git-хуки, блок
anti-patterns в `AGENTS.md`, запись `doubled-graph` в MCP-конфигах и наши
skill-файлы. После SIGKILL/краха демона
команда находит его осиротевшие движки по реестру (`state.json`) и записанному
PID воркера, подтверждает PID по командной строке (`falkor_worker`), останавливает
их и только затем удаляет реестр; уцелевший или неподтверждённый PID попадает в
`orphaned_engines`/`unknown_engine`, а команда возвращает `ok: false` (реестр
сохраняется для повторной попытки). Чужие `pipx`/FalkorDB-процессы не
затрагиваются. Исходники, `.grace` и пользовательские хуки/правила не
трогаются. Команда идемпотентна: повторный запуск возвращает rc=0 с
`status: "not_installed"`. Подробности — [docs/TOOLS.md §5](docs/TOOLS.md).

Только после этого удаляйте сам пакет:

```bash
pipx uninstall doubled-graph
```

(или `python3 -m pip uninstall doubled-graph`, если ставили в venv).

> **Почему именно в таком порядке.** Если сделать `pipx uninstall` первым, unit
> launchd/systemd останется с `KeepAlive`/`Restart=on-failure` и будет
> перезапускать `python -m doubled_graph.daemon.main`, который больше не
> импортируется, — получится цикл падений/перезапусков, а команды
> `doubled-graph uninstall`/`daemon uninstall` уже не будет. Сначала
> `doubled-graph uninstall`, потом `pipx uninstall`.

Если `doubled-graph` уже удалён, а unit остался, снимите его вручную:
`launchctl bootout gui/$(id -u)/com.doubled-graph.daemon` + удалите
`~/Library/LaunchAgents/com.doubled-graph.daemon.plist` (macOS) или
`systemctl --user disable --now doubled-graph-graphd` + удалите
`~/.config/systemd/user/doubled-graph-graphd.service` (Linux).

`--purge-project` не удаляет скопированные `prompts/` и `methodology/`
(это документация, а не исполняемый артефакт; вы могли их отредактировать) —
удалите их вручную, если не нужны. Локальный кеш `.doubled-graph/`
(`config.json`, `drafts/`, логи) тоже сохраняется: там ваши настройки и
история; при необходимости `rm -rf .doubled-graph`. grace-cli — отдельный
Bun/Node-пакет 4.x: `bun remove -g @osovv/grace-cli` или
`npm uninstall -g @osovv/grace-cli`.

---

## Обновление на 3.0 (клиент + демон `graphd`)

3.0 — ломающий релиз: AST-движок и его база больше не запускаются внутри
процесса IDE/песочницы. Ими владеет демон `graphd` под супервизором ОС
(launchd / `systemd --user` / Task Scheduler). Поэтому `analyze`, `impact`,
`context` и `detect-changes` без запущенного демона возвращают
`CGC_BACKEND_FAIL` и rc=1 (JSON с warning и командой установки всё равно
печатается) — «тихой» локальной деградации больше нет.

Пошагово с 2.x (или 1.9.x, если проект ещё на `docs/*.xml`):

1. **Поставьте именно 3.0.** `pipx upgrade doubled-graph` сейчас даёт
   **2.1.0**, а не 3.0.0 (3.0.0 ещё не в PyPI). Точный путь — wheel с явным
   `--python`: см. [§Установка](#2-установить-doubled-graph). Убедитесь:
   `doubled-graph --version` → `3.0.0`.
2. **`cd your-project && doubled-graph setup`** — в **обычном** шелле, не из
   песочницы. `setup` идемпотентно ставит/запускает сервис `graphd`,
   регистрирует проект, обновляет движок и `.grace`.
3. **Проверьте:** `doubled-graph daemon status` → `installed: true`,
   `running: true`; `doubled-graph health` → `cgc.ok: true`. Если демон не
   ответил за 60 с холодного старта, `setup` печатает честное сообщение с
   бюджетом и командами диагностики, а не «unavailable» без объяснений.
4. **Если сервис поставить нельзя** (Seatbelt, контейнер, чужой хост):
   запускайте из обычного шелла с `DOUBLED_GRAPH_ENGINE=local` — это явный
   standalone-режим для CI/отладки, а не автоматический fallback. Из
   песочницы `local` тоже не заработает: `fork/exec` наследует профиль.
5. **Если проект был на GRACE 3** — `setup` сам перенесёт `docs/*.xml` в
   `.grace`; подробности ниже.

Удаление/откат — `doubled-graph uninstall` (сначала он, потом
`pipx uninstall doubled-graph`; см. [§Удаление](#удаление)).

---

## Обновление с 1.9.x (GRACE 3 → GRACE 4)

2.0 — ломающий релиз: движок `@osovv/grace-cli` 4.x валидирует только `.grace`
и отказывается читать `docs/*.xml`. Сегодня этот переход выполняется вместе с
обновлением на 3.0:

```bash
# 1. поставить 3.0 (pipx upgrade даст только 2.1.0 — см. §Установка)
python3.14 -m build --wheel
pipx install --python python3.14 --force dist/doubled_graph-3.0.0-py3-none-any.whl
cd your-project
doubled-graph setup          # 2. движок, .grace и демон graphd — одной командой
```

Что делает `setup`: ставит движок 4.2.1, конвертирует `docs/*.xml` → `.grace`
(модули `M-*`, зависимости, `V-M-*` с командами/сценариями/тест-файлами),
создаёт недостающие обязательные документы, добавляет `LINKS: M-*` в
`MODULE_CONTRACT` (без этого файл не привязан к модулю; id из `MODULE:`
дописывается даже если в `LINKS` уже есть чужой `M-*`, а для контракта без
`MODULE:` владелец берётся из legacy `<Path>`), приводит `MAP_MODE`
в соответствие с `ROLE`. Повторный `setup` не перезаписывает `.grace`, но
по-прежнему чинит разметку и перечисляет незаписанные артефакты в
`kept_existing`. Legacy `docs/` не изменяются и не удаляются.
`setup` также дописывает в `AGENTS.md` управляемый блок anti-patterns
(идемпотентно; существующий текст и BOM сохраняются).

Если миграцию не сделать:

| Сценарий | Последствия |
|---|---|
| Остались на 1.9.x | Всё работает по-старому, но без обновлений и поддержки `.grace` |
| Обновили пакет, `setup` не запускали | `doubled-graph lint` → `project.grace3-detected` (exit 1), MCP `file_show`/`module_show` → `invalid-project`; графовые команды без демона → `CGC_BACKEND_FAIL`, rc=1 |
| Мигрировали, но `LINKS` не поправили | lint зелёный, но модули «пустые»: `module show` не показывает файлы, `detect_changes` даёт `code_without_module` на весь код |

Обновление версии методики — отдельный (третий) сценарий, он не требует проходить миграцию
заново: [prompts/upgrade-methodology/00-entry-prompt.md](prompts/upgrade-methodology/00-entry-prompt.md)
(готовый промт для ИИ: статус → `setup` → проверки → закрытие пробелов).

После обновления остаётся только содержательная работа — заполнить пустые
`V-<M>` и `MODULE_MAP` по реальному коду и тестам. Готовый промпт:
[prompts/upgrade-methodology/01-content-gaps.md](prompts/upgrade-methodology/01-content-gaps.md)
— скопируйте текст из блока «Промт» в ИИ-ассистента; он соберёт `map_pending` /
`placeholders`, допишет карты модулей, заполнит верификации командами из
существующих тестов и прогонит финальные проверки. Выдуманные команды запрещены
(иначе «не проверено» станет «проверено»). При желании можно архивировать
`docs/` — отдельным решением.

---

## Документация

- [SPEC.md](docs/SPEC.md) — архитектура, хранилище `.doubled-graph/`
- [TOOLS.md](docs/TOOLS.md) — подробные схемы инструментов
- [HOOKS.md](docs/HOOKS.md) — git и Claude Code хуки
- [DAEMON.md](docs/DAEMON.md) — демон `graphd`: протокол, сервис, безопасность
- [CHANGELOG.md](docs/CHANGELOG.md) — история изменений

---

## Лицензия

MIT. Upstream-компоненты (CodeGraphContext, grace-marketplace) — MIT.
