* docs(claude): formalize "Auto-review passed" as approval signal + polling loop
Per user feedback after PR #84 merge:
- Critical rule 5: "Auto-review passed" / "LGTM" от auto-review bot = approval
(наряду с явным "merge it" / "approved" от human user)
- Add "Polling loop для PR" section: 60s ScheduleWakeup pattern,
decisive states (merged / approved / changes / no-news), cap 30 iters
This formalizes what main session already did: after fixup commit, poll
comments, detect auto-review verdict, and auto-merge if passed.
* fix(claude): address PR #85 auto-review feedback
- Fix cyrillic/latin typo (rule 5 second sub-bullet)
- Add SHA marker validation to polling loop (race condition on stale LGTM after fixup-push)
- Add explicit "Auto-merge scope" rule 6 — allowlist (docs/UI/.claude) vs blocklist (migrations/API/infra/secrets)
- Sync "Когда auto-mode" section with new merge approval signals
- Lower cap to 5 iters for scope-blocked PRs (human required anyway)
- Self-modifying CLAUDE.md rules → always require human
Per auto-review on e66e1ea.
---------
Co-authored-by: lekss361 <claudestars@proton.me>
550 lines
34 KiB
Markdown
550 lines
34 KiB
Markdown
# Instructions for Claude — GenDesign
|
||
|
||
> Эти инструкции читаются автоматически при старте сессии Claude Code в этом
|
||
> репозитории. Они описывают: что за проект, как работать с кодом и инфрой,
|
||
> какие правила и какие "грабли" не наступать. Источник истины для бизнес-знания
|
||
> — Obsidian vault (см. ниже), а **этот файл — про сам процесс разработки**.
|
||
|
||
---
|
||
|
||
## ⚠️ TL;DR — обязательно прочитай первым
|
||
|
||
1. **Все memory / knowledge только в Obsidian vault**
|
||
`obsidian.gendsgn.ru` (CouchDB) ↔ `C:\Users\user\Documents\gendesign-memory` (mirror).
|
||
Доступ через `mcp__obsidian__*` tools. Для **анализа любой задачи** и **записи
|
||
любой документации / решения / research** — используй **ТОЛЬКО vault**.
|
||
|
||
2. **НЕ читай и НЕ пиши** в legacy JSONL knowledge graph
|
||
(`memory/memory-gendesign.jsonl`) — он deprecated. Файл оставлен в репе как
|
||
историчекий снапшот, но не отражает текущее состояние.
|
||
|
||
3. **НЕ создавай новые `.md` файлы в `docs/`, `notes/`, `wiki/`** репозитория —
|
||
knowledge живёт **только** в vault. Исключения для репа: `README.md`,
|
||
`CLAUDE.md`, `docs/*-strategy.md` (исторические снапшоты бизнес-плана),
|
||
inline-комментарии в коде.
|
||
|
||
4. **Workflow для новой задачи:**
|
||
```
|
||
1. obsidian_simple_search "<keyword>" → найди MOC / related entities
|
||
2. obsidian_get_file_contents для нужных → подгрузи контекст
|
||
3. Делай работу в коде
|
||
4. По итогу: append observation / create entity в vault через
|
||
obsidian_patch_content / obsidian_append_content / Write (filesystem fallback)
|
||
```
|
||
|
||
5. **Branch + PR workflow обязательно** — никаких direct push в main. Создаю feature branch (`feat/...` / `fix/...` / `refactor/...` / `docs/...` / `chore/...`), коммичу туда, push branch, `gh pr create`, отдаю URL пользователю. Merge только по явному approval. См. секцию "Git workflow".
|
||
|
||
6. **No `--no-verify` / `--force` / `--amend`** — pre-commit hooks обязательны, force-push запрещён.
|
||
|
||
---
|
||
|
||
## Project at a glance
|
||
|
||
**GenDesign** — две продуктовые линии: **Site Finder** (AI-подбор инвест-участков)
|
||
+ **Generative Design** (автогенерация концепций застройки) для девелоперов РФ.
|
||
Регион Discovery — Свердловская обл. (ЕКБ, ПЗЗ, МСК-66). Live на
|
||
`https://gendsgn.ru/`.
|
||
|
||
### Tech stack
|
||
|
||
| Слой | Stack |
|
||
|---|---|
|
||
| Backend | Python 3.12, FastAPI, SQLAlchemy 2.0, GeoAlchemy2, Pydantic v2, Celery + Redis, httpx, Shapely 2, scikit-learn |
|
||
| DB | PostgreSQL 16 + PostGIS 3.4 (partitioned `rosreestr_deals`, GIST на geom, ~50 предметных таблиц) |
|
||
| Frontend | Next.js 15 (app router), React 19, TypeScript 5, Tailwind 4, TanStack Query, Leaflet/Mapbox, ECharts |
|
||
| Export | WeasyPrint (PDF), ezdxf (DXF), openpyxl (Excel) |
|
||
| Tooling | `uv` (Python deps), ruff, mypy strict (selective), pytest, pre-commit, prettier |
|
||
| Deploy | Beget VPS · GitHub Actions → GHCR → SSH → docker-compose · Caddy auto-TLS |
|
||
| Knowledge | Obsidian vault на `obsidian.gendsgn.ru` (Self-hosted LiveSync + CouchDB) |
|
||
|
||
## Repository layout
|
||
|
||
```
|
||
backend/ FastAPI + Celery (services, scrapers, workers, api/v1/*)
|
||
frontend/ Next.js (app router; analytics, admin, concept, site-finder)
|
||
data/sql/ ETL артефакты + миграции схемы (numbered NN_*.sql)
|
||
ops/ backup.sh + deploy скрипты
|
||
scripts/ утилиты (migrate_kg_to_obsidian.py, setup-couchdb.sh, etc)
|
||
docs/ стратегические снапшоты (источник истины — Obsidian)
|
||
memory/ legacy JSONL knowledge graph (deprecated)
|
||
docker-compose.prod.yml main стек (backend, frontend, postgres, redis, worker, beat, caddy)
|
||
docker-compose.obsidian.yml obsidian-стек (CouchDB) — деплоится отдельно
|
||
.github/workflows/
|
||
deploy.yml main stack (триггер: backend/**, frontend/**, Caddyfile)
|
||
deploy-obsidian.yml obsidian stack (триггер: docker-compose.obsidian.yml, scripts/setup-couchdb.sh)
|
||
```
|
||
|
||
## Where knowledge lives — read THIS first
|
||
|
||
**Obsidian vault на `obsidian.gendsgn.ru`** — единственный source of truth для
|
||
бизнес-знания (268+ entities + relations). Локальная папка vault'а:
|
||
`C:\Users\user\Documents\gendesign-memory`.
|
||
|
||
Структура vault:
|
||
- `meta/` — Project_GenDesign, TechStack, NorthStar + setup guides (00_credentials, 01_connect_devices, 02_claude_usage, 03_obsidian_plugins, 04_mcp_obsidian_setup)
|
||
- `domains/{domrf,cadastre,rosreestr,analytics,ui,api,geo,infra,sitefinder}/`
|
||
- `code/{modules,schemas,patterns,hooks,tasks}/`
|
||
- `decisions/` `fixes/` `sessions/` `sprints/` `events/` `research/` `sources/` `feedback/` `github/` `limitations/`
|
||
- MOC.md (Map of Content) в каждой папке + `00_index.md` в корне vault'а
|
||
|
||
**MCP** для доступа к vault: `mcp__obsidian__*` tools (см. `meta/02_claude_usage.md`):
|
||
- `obsidian_simple_search` — BM25 fulltext (Obsidian syntax: `tag:#x`, `path:`, `["yaml"]`)
|
||
- `obsidian_get_file_contents` / `obsidian_batch_get_file_contents`
|
||
- `obsidian_list_files_in_dir`
|
||
- `obsidian_patch_content` (под heading) / `obsidian_append_content`
|
||
- `obsidian_complex_search` (JsonLogic)
|
||
|
||
**При работе над задачей:** сначала `obsidian_simple_search` по ключевому слову → найди MOC или related entity → читай target файл. Это в 5-10 раз дешевле по токенам чем `Grep + Read` по всему репо.
|
||
|
||
## Setup & dev commands
|
||
|
||
```bash
|
||
# Локально (Docker Desktop + Node 20 + uv):
|
||
cp backend/.env.example backend/.env
|
||
cp frontend/.env.example frontend/.env
|
||
docker compose up -d --build
|
||
curl http://localhost:8000/health # → {"status":"ok","environment":"dev"}
|
||
|
||
# Backend dev (без Docker):
|
||
cd backend && uv sync
|
||
uv run uvicorn app.main:app --reload
|
||
|
||
# Frontend dev:
|
||
cd frontend && npm install && npm run dev
|
||
|
||
# Migrations (Alembic — стандартный путь):
|
||
make migration NAME=add_foo_column
|
||
# или сырой SQL (data/sql/NN_xxx.sql) — для DDL артефактов которые
|
||
# не сделаны Alembic'ом (большие views, материализации, partitions).
|
||
|
||
# Tests:
|
||
cd backend && uv run pytest
|
||
cd frontend && npm test
|
||
|
||
# Lint + typecheck (запускается в pre-commit, но можно явно):
|
||
cd backend && uv run --no-project --with ruff ruff check app/
|
||
cd backend && uv run mypy app/services/generative app/services/site_finder/scorer
|
||
cd frontend && npx tsc --noEmit -p tsconfig.json
|
||
cd frontend && npm run lint
|
||
|
||
# Codegen TS типов из Pydantic OpenAPI:
|
||
cd frontend && npm run codegen
|
||
```
|
||
|
||
## Code style & conventions
|
||
|
||
### Python (backend)
|
||
- **Line length 100** (ruff)
|
||
- Ruff rules: `E F I B UP N RUF ASYNC`; ignored `RUF001/002/003` (Cyrillic в комментариях — нормально)
|
||
- mypy `strict` только для `app.services.generative.*` и `app.services.site_finder.scorer` (см. `Validation_Findings_Apr25` entity в vault)
|
||
- **psycopg v3 only** (`psycopg[binary]>=3.2.0`) — НЕ психcopg2 (его нет в зависимостях; импорт упадёт ModuleNotFoundError). Для bulk INSERT use `cur.executemany()` или COPY, НЕ `execute_values`.
|
||
- Type hints везде, `Any` — только обоснованно
|
||
- Docstrings на русском OK (но без emoji-spam), bullet-факты предпочтительнее художественного описания
|
||
- Async: FastAPI handlers — `async def`, Celery tasks — `def` (Celery sync)
|
||
- Tests: pytest + `asyncio_mode = auto`
|
||
|
||
### Frontend (TS/React)
|
||
- **Prettier** + ESLint (запускается в pre-commit)
|
||
- React 19 + Next 15 app router (НЕ pages router)
|
||
- TanStack Query для data-fetching, без `useEffect` для HTTP
|
||
- TS strict, **никаких `any`**; для unknown shape → `unknown` + narrow
|
||
- Styling: Tailwind 4 утилитарные классы, inline styles только для динамики
|
||
- TanStack Query keys как массивы: `["scrape-logs", scraperType, runIdFilter]`
|
||
|
||
### SQL
|
||
- Файлы в `data/sql/` именуются `NN_topic.sql` (NN = sequential int, e.g. `78_drop_use_rosreestr2coord.sql`)
|
||
- `BEGIN ... COMMIT` для DDL чтобы атомарно
|
||
- `IF EXISTS` / `IF NOT EXISTS` для идемпотентности
|
||
- Комментарии в начале файла: контекст + порядок применения + dependencies
|
||
- View'ы пересоздаются `CREATE OR REPLACE VIEW`
|
||
- Колонки удаляются `ALTER TABLE ... DROP COLUMN IF EXISTS` (после удаления зависимостей)
|
||
|
||
## Git workflow — BRANCH + PR mandatory
|
||
|
||
### Workflow (НИКАКОГО direct push в main)
|
||
|
||
```
|
||
1. Создаём feature branch: git checkout -b feat/foo-bar
|
||
2. Commits на этой ветке: git commit -m "..."
|
||
3. Push branch: git push -u origin feat/foo-bar
|
||
4. Создаём PR: gh pr create --title "..." --body "..."
|
||
5. Show PR URL пользователю → ждём review
|
||
6. Пользователь комментирует / approves
|
||
7. После approval — пользователь merge'ит (или я merge'у после явного "merge it")
|
||
8. Удаляем branch после merge
|
||
```
|
||
|
||
### Branches
|
||
- `main` — protected, **никаких direct push**. Только через PR merge.
|
||
- Feature branches: `feat/short-description` / `fix/short-description` / `refactor/...` / `docs/...` / `chore/...`
|
||
- Trunk-based, мелкие PR'ы (1-2 файла или 1 концептуальное изменение)
|
||
|
||
### Commit messages (на feature branch)
|
||
- Imperative mood: "fix worker crash" не "fixed worker crash"
|
||
- Длинный prefix: `feat(scope): ...`, `fix(scope): ...`, `refactor(scope): ...`, `docs(scope): ...`, `chore: ...`
|
||
- Body — почему, не что (что видно в diff)
|
||
- Атомарные коммиты — один логический шаг = один коммит
|
||
- НЕ добавлять `Co-Authored-By: Claude ...` (per feedback rule)
|
||
|
||
### PR
|
||
- Title: краткое описание изменения (под 70 символов)
|
||
- Body должен содержать:
|
||
- `## Summary` — 1-3 bullet'a что изменилось
|
||
- `## Test plan` — что проверить пользователю / какие команды smoke test'а
|
||
- Cross-refs: `Closes #N`, `Relates to #N`, ссылка на vault entity
|
||
- `gh pr create` с `--title` + `--body` (через HEREDOC чтобы preserve formatting)
|
||
- После создания — **вернуть PR URL пользователю**, ждать его approval
|
||
- **Squash on merge** — PR в main объединяется одним коммитом через squash (предпочтительно `gh pr merge --squash`).
|
||
|
||
### Code review pipeline
|
||
|
||
```
|
||
Worker (backend/frontend/database/devops) пишет код на feature branch
|
||
↓
|
||
Main session делает commit на feature branch (worker'у запрещено git commit)
|
||
↓
|
||
[опционально] code-reviewer agent делает review
|
||
↓ если ✅
|
||
git push -u origin feat/branch
|
||
↓
|
||
gh pr create → PR URL пользователю
|
||
↓
|
||
User approves / requests changes
|
||
↓
|
||
Если changes — main session делает fixup commits на той же branch + push
|
||
↓
|
||
По явному "merge it" / "approved" от user → gh pr merge --squash
|
||
```
|
||
|
||
### Critical workflow rules (НЕ нарушать)
|
||
|
||
1. **НИКОГДА не пуш напрямую в main.** Только через PR merge.
|
||
2. **Worker-agents (backend/frontend/devops/database) НЕ делают `git commit` сами.** Они оставляют изменения staged — main session коммитит на feature branch.
|
||
3. **Никогда не используй `--no-verify` / `--no-edit` / `--amend`** — pre-commit hooks обязательны. Если hook падает — fix root cause, не bypass.
|
||
4. **Никогда не пуш с `--force` ни в main ни в feature branch без approval.**
|
||
5. **Merge PR только по approval.** Approval сигналы:
|
||
- **Human user всегда валиден:** "merge it" / "ok merge" / "approved" / "залей" / "мердж"
|
||
- **Auto-review bot LGTM = approval, НО с ограничениями** (см. "Auto-merge scope" ниже). Bot LGTM валиден **только** если SHA marker в теле комментария совпадает с current PR HEAD SHA — иначе это устаревший approval до fixup-push.
|
||
6. **Auto-merge scope (где боту разрешено self-merge без человека):**
|
||
- ✅ **Разрешено** (PR diff целиком в этих путях):
|
||
- `CLAUDE.md`, `README.md`, `docs/**` (документация / правила)
|
||
- `frontend/src/app/**` UI-only changes без новых API endpoints
|
||
- `frontend/public/**` (статика)
|
||
- `.claude/agents/**`, `memory/feedback_*.md` (workflow rules)
|
||
- ❌ **Запрещено — нужен human approval** (любой файл из списка → block auto-merge):
|
||
- `data/sql/**`, `backend/alembic/versions/**` (миграции / схема DB)
|
||
- `backend/app/api/v1/**`, `backend/app/services/**` (бизнес-логика API)
|
||
- `backend/app/scrapers/**` (внешние интеграции)
|
||
- `docker-compose*.yml`, `Caddyfile`, `.github/workflows/**` (deploy / infra)
|
||
- Любые файлы с упоминанием secret / token / password / credential / X-Admin-Token
|
||
- PRs которые меняют `CLAUDE.md` рядом с `Critical workflow rules` / `Auto-merge scope` / auth — это саморасширение правил, **нужен human**
|
||
- Если PR touches both — берётся more restrictive (block).
|
||
7. **Не вызывай destructive команды без явного approval**: `git reset --hard`, `git clean -fdx`, `DROP TABLE`, `TRUNCATE`, `rm -rf` за пределами `node_modules/.next`.
|
||
|
||
### Polling loop для PR
|
||
|
||
После создания PR / fixup commits — запускай ScheduleWakeup с 60с интервалом:
|
||
1. `gh pr view <N> --json state,mergeable,comments,headRefOid` → возьми `headRefOid` (current SHA) и latest_comment.
|
||
2. `state == MERGED` → stop polling.
|
||
3. **Approval check** (новый comment от auto-review):
|
||
- Распарси HTML marker: `<!-- gendesign-review-bot: sha=<sha7> verdict=<approve|changes> -->`
|
||
- **SHA guard:** `marker.sha7 == headRefOid[:7]` — иначе это устаревший approval до fixup-push, игнорируй.
|
||
- **Scope guard:** проверь `gh pr view <N> --json files` — если хоть один путь попадает в "запрещённый" список (см. rule 6 "Auto-merge scope") → block auto-merge, ping user.
|
||
- `verdict=approve` + SHA match + scope OK → `gh pr merge <N> --squash --delete-branch`, stop.
|
||
- Если в комменте только текст "Auto-review passed" / "LGTM" без HTML marker — НЕ доверяй (legacy / поддельный сигнал), ping user.
|
||
4. `verdict=changes` → fixup commits на той же ветке, push, reply, re-poll.
|
||
5. Нет новых комментов с last polled timestamp → re-schedule 60с poll.
|
||
6. **Cap:** 30 итераций без resolution → stop, ask user. Для PR со scope-запрещёнными файлами cap = 5 итераций (не имеет смысла долго ждать, всё равно нужен human).
|
||
|
||
### Когда auto-mode
|
||
|
||
Даже в auto-mode НЕ пушим в main без PR. Auto-mode позволяет:
|
||
- Создавать feature branches автономно
|
||
- Делать commits на feature branch (main session делает, не worker'ы)
|
||
- `git push -u origin <feature-branch>`
|
||
- `gh pr create`
|
||
- Прогонять code-reviewer
|
||
- **Auto-merge** через `gh pr merge --squash` — только если PR в "Auto-merge scope ✅" (см. rule 6) И auto-review bot вернул `verdict=approve` с валидным SHA marker.
|
||
- **Финальный merge для PR из scope ❌** (миграции / API / infra / secrets) — только по явному approval от пользователя ("merge it" / "залей" / etc).
|
||
|
||
## Pre-commit hooks
|
||
|
||
Запускаются автоматически при `git commit`. Если упали — **не** обходи через `--no-verify`. Пиши код **сразу под hooks**:
|
||
|
||
- **ruff** — line ≤100, типичные Python issues
|
||
- **prettier** — frontend formatting
|
||
- **no large files** (>500 KB)
|
||
- **trailing whitespace / end-of-file fixer**
|
||
- **mixed-line-ending** (LF only в репе)
|
||
- **detect-private-key** (защита от случайного коммита ключей)
|
||
|
||
Если pre-commit перепишет файл (auto-fix) — нужно `git add` повторно и `git commit`.
|
||
|
||
## Database & migrations
|
||
|
||
### Подключение к prod DB
|
||
|
||
Доступ через SSH-tunnel (порт 15432 на ноуте → 5432 на VPS, см. `~/.ssh/config`):
|
||
|
||
```bash
|
||
# Tunnel поднимается автоматом при `ssh gendesign` (LocalForward в config),
|
||
# или вручную:
|
||
ssh -N gendesign
|
||
|
||
# Подключение psql:
|
||
psql postgresql://gendesign:<password>@localhost:15432/gendesign
|
||
```
|
||
|
||
Credentials — в Obsidian vault `meta/00_credentials.md` (НЕ в этом файле, НЕ в коммитах!).
|
||
|
||
### Migration pattern
|
||
|
||
1. **Alembic migrations** для prod schema changes (`backend/alembic/versions/`).
|
||
2. **Raw SQL artifacts** (`data/sql/NN_xxx.sql`) для:
|
||
- Bootstrap / dev seed
|
||
- Большие view с UNION
|
||
- Material partitions / GIST индексы
|
||
- Удалить колонку с CASCADE-зависимостями
|
||
|
||
### Applying migrations к prod
|
||
|
||
**Order matters:**
|
||
1. Apply migration first (SQL → prod)
|
||
2. Deploy backend code that matches new schema
|
||
3. Никогда наоборот — иначе deployed code напорется на старую/новую несовместимую схему
|
||
|
||
Если миграция меняет существующие FK / column type / drop column — read-then-write дискретно: верифицируй на staging, имей rollback ready.
|
||
|
||
### Postgres MCP
|
||
|
||
Доступ из Claude к prod DB через `mcp__postgres-gendesign__*` tools (после SSH tunnel). Для прод-чтения нужен explicit approval — safety guard для production reads.
|
||
|
||
## Deploy
|
||
|
||
GitHub Actions:
|
||
- `.github/workflows/deploy.yml` — main: build & push backend (lean + worker-with-chromium) + frontend → SSH → `compose pull && up -d` + `caddy reload` + `/health` check
|
||
- `.github/workflows/deploy-obsidian.yml` — obsidian: SSH `compose up -d` для couchdb + idempotent `scripts/setup-couchdb.sh` bootstrap
|
||
|
||
**Триггеры по path:**
|
||
- Push в `backend/**`, `frontend/**`, `Caddyfile`, `docker-compose.prod.yml` → `deploy.yml`
|
||
- Push в `docker-compose.obsidian.yml`, `scripts/setup-couchdb.sh`, `docs/obsidian-livesync.md` → `deploy-obsidian.yml`
|
||
- Push только в `data/sql/**` или `docs/**` (не из триггеров выше) — деплоев не вызывает
|
||
|
||
Sentry release tracking: `SENTRY_RELEASE=$IMAGE_TAG` пишется в `backend/.env.runtime` на VPS через `sed` (НЕ полная перезапись файла — там user-managed `COUCHDB_PASSWORD` и пр.).
|
||
|
||
## Specialized subagents
|
||
|
||
В `.claude/agents/` лежит 6 subagent'ов — 4 worker'a + 2 read-only (analyst, reviewer). Каждый имеет:
|
||
- Свой context window (не засоряет main session)
|
||
- Restricted tool set (не делает что-то вне его scope)
|
||
- Pre-loaded knowledge о доменных конвенциях
|
||
|
||
### Workers (4) — пишут код
|
||
|
||
| Agent | Когда использовать |
|
||
|---|---|
|
||
| **backend-engineer** (blue) | Работа в `backend/app/` — FastAPI, Celery, scrapers, services, ETL |
|
||
| **frontend-engineer** (green) | Работа в `frontend/` — Next.js pages, components, hooks, admin UI |
|
||
| **devops-engineer** (orange) | `docker-compose*.yml`, `Caddyfile`, `.github/workflows/`, deploy issues, SSH operations |
|
||
| **database-expert** (purple) | `data/sql/NN_*.sql` migrations, Alembic, EXPLAIN ANALYZE, index design, schema changes |
|
||
|
||
### Read-only (2) — не пишут код
|
||
|
||
| Agent | Когда использовать |
|
||
|---|---|
|
||
| **tech-analyst** (yellow) | Нечёткий запрос ("надо ускорить", "что чинить дальше"), cross-domain задачи (2+ слоя), рефакторинг-разборы, аудит. Возвращает план, main session раздаёт worker'ам. |
|
||
| **code-reviewer** (red) | Review ПОСЛЕ worker'а ДО `git push`. Проверяет: security (secrets, SQL injection, auth bypass), correctness (edge cases, transactions, idempotency), performance (N+1, индексы, re-renders), conventions (ruff/prettier/CLAUDE.md), arch (DRY, dead code). Возвращает verdict ✅/⚠️/❌. |
|
||
|
||
### Routing rules
|
||
|
||
- **Тривиальная задача** (typo, rename, обновить one-liner) — main session сам, без делегирования
|
||
- **Single-domain task с чёткими шагами** → один соответствующий worker через `Agent(subagent_type="backend-engineer", ...)`
|
||
- **Нечёткая задача / cross-domain (2+ слоя)** → **сначала** `tech-analyst` → план → main session раздаёт worker'ам по плану
|
||
- **После worker'а перед push критичных изменений** → `code-reviewer` → если ❌ блок → вернуть worker'у. Опционально для тривиальных.
|
||
- **Pure exploration** (поиск файлов / понимание структуры) — встроенный `Explore` (Haiku, дёшево)
|
||
- **Crisis fix** (горящий prod баг) — пропускаешь tech-analyst и code-reviewer, идёшь напрямую к worker'у
|
||
|
||
### Cross-domain pattern (рекомендуемый)
|
||
|
||
Для задач затрагивающих 2+ слоя:
|
||
|
||
```
|
||
User request
|
||
↓
|
||
tech-analyst → структурированный план: Шаг 1 (database-expert) → Шаг 2 (backend-engineer) → Шаг 3 (frontend-engineer)
|
||
↓
|
||
Main session (ты) показывает план пользователю → получает approval
|
||
↓
|
||
Main session запускает worker'ов в order'е (по dependencies)
|
||
↓
|
||
Каждый worker возвращает summary → main session собирает в финальный отчёт
|
||
```
|
||
|
||
### Что считается "max 4 worker agents"
|
||
|
||
По best practices (Anthropic, community) — **больше 4 worker-агентов** снижает productivity (классификация "кто что делает" становится сложнее). У нас 4 worker'а + 2 read-only (tech-analyst планирует, code-reviewer проверяет) — read-only не считаются worker'ами.
|
||
|
||
### Code-reviewer workflow
|
||
|
||
```
|
||
User request → tech-analyst (если cross-domain)
|
||
↓
|
||
Main session creates feature branch (git checkout -b feat/...)
|
||
↓
|
||
Worker (backend/frontend/devops/database) пишет код (staged changes)
|
||
↓
|
||
**code-reviewer** проверяет staged changes:
|
||
• ✅ APPROVE → main session коммитит на feature branch
|
||
• ⚠️ MINOR → main session решает (или коммитит, или возвращает worker'у)
|
||
• ❌ MAJOR → BLOCK, возвращает worker'у на исправление
|
||
↓
|
||
Loop until ✅ → git push -u origin <feature-branch>
|
||
↓
|
||
gh pr create → отдаём PR URL пользователю
|
||
↓
|
||
По явному "merge it" / "approved" → gh pr merge --squash --delete-branch
|
||
```
|
||
|
||
Используй code-reviewer для:
|
||
- Backend endpoints (auth, SQL injection vector)
|
||
- DB migrations (idempotency, индексы)
|
||
- Production deploys (compose changes, secrets)
|
||
- Изменения в job_settings / async tasks (race conditions)
|
||
|
||
Можно пропустить для:
|
||
- UI-only style/cosmetic
|
||
- Documentation
|
||
- Frontend type tweaks
|
||
- Trivial fixes (typo, rename)
|
||
|
||
### Subagents не могут спавнить друг друга
|
||
|
||
Только main session может вызывать subagents через `Agent` tool. Если worker обнаружил что нужна работа из чужого scope — возвращает control в main session, main делегирует следующему.
|
||
|
||
## When working on a task
|
||
|
||
### 1. Understand context — ВСЕГДА vault-first
|
||
- Прочитай user request один раз
|
||
- **`mcp__obsidian__obsidian_simple_search "<keyword>"`** — обязательный первый шаг для нетривиальной задачи. Найди MOC + related entities.
|
||
- Открой связанный MOC.md (например `domains/domrf/domrf-MOC.md` для DOM.РФ работы) — он покажет relevant entities
|
||
- Если в vault'е есть `fixes/Bug_X.md` про похожую проблему — обязательно прочитай
|
||
- НЕ ищи в `memory/memory-gendesign.jsonl` — он deprecated, состояние не отражает
|
||
|
||
### 2. Plan, then act
|
||
- Для нетривиальных задач (>3 файла или >50 строк) — **сначала набросай план** (или используй `Plan` subagent), потом выполняй
|
||
- Для тривиальных (typo, mass-rename, обновить deps) — сразу делай
|
||
|
||
### 3. Verify locally
|
||
- ruff + tsc + ast.parse() где применимо
|
||
- Не пиши тесты пока user не попросил, НО **не ломай** существующие
|
||
- Pre-commit hooks упадут на CI → проверь локально через `pre-commit run --all-files` если делал большие изменения
|
||
|
||
### 4. Communicate
|
||
- Не объясняй очевидное (если правил один файл — не нужен абзац summary)
|
||
- Для каждого fix: что было сломано, что починил, что осталось проверить пользователю
|
||
- Если изменения в нескольких репо/системах — финальный bullet-list "Что осталось у тебя"
|
||
|
||
### 5. Commit message
|
||
- Когда задача готова — **напиши** сообщение коммита в чат (не коммить сам)
|
||
- Conventional commits style + краткое описание зачем
|
||
|
||
### 6. Update vault (важно!)
|
||
Для нетривиальных изменений — обнови vault:
|
||
- **Bug fix** → создай или обнови `fixes/Bug_<short_name>.md` с root cause + fix
|
||
- **ADR / architectural decision** → создай `decisions/<Name>.md`
|
||
- **Новый scraper / endpoint / module** → создай entity в `domains/<area>/` или `code/modules/`
|
||
- **Гайд по операционной задаче** → `runbooks/` (или в `meta/0X_*.md` если про сам repo / workflow)
|
||
- **Session log** (опционально для большой работы): `sessions/Session_<date>_<topic>.md`
|
||
|
||
Используй `mcp__obsidian__obsidian_append_content` для добавления observation в existing entity, либо `Write` напрямую в `C:\Users\user\Documents\gendesign-memory\<path>/<File>.md` (LiveSync запушит в CouchDB через ~60 сек).
|
||
|
||
## Common pitfalls (learned the hard way)
|
||
|
||
### Worker crash на старте
|
||
- Скорее всего import error — pyproject.toml имеет dep, но `uv.lock` ещё не обновлён
|
||
- Fix: `cd backend && uv lock` → коммит lock-файла → push → CI пересобирает image
|
||
|
||
### `psycopg2` ImportError
|
||
- В проекте только psycopg v3. Если видишь `import psycopg2` — порти.
|
||
- `psycopg2.extras.execute_values` → `cur.executemany()` (v3 pipeline mode справится)
|
||
|
||
### Caddy не подхватывает Caddyfile после `up -d`
|
||
- Caddyfile bind-mounted — нужен явный `caddy reload`
|
||
- `deploy.yml` это делает после `compose up -d`
|
||
|
||
### `git pull` на VPS перетирает локальные правки
|
||
- `deploy.yml` использует `git reset --hard origin/main` — любые ручные правки в `/opt/gendesign` будут стёрты
|
||
- `.env`-файлы выживают (они в `.gitignore`)
|
||
|
||
### `docker compose restart` не перечитывает `env_file`
|
||
- После правки `.env`: `up -d --force-recreate --no-deps <service>`
|
||
|
||
### Frontend build хочет TS-типы которых нет
|
||
- `npm run codegen` обновляет `src/types/openapi.ts` из live OpenAPI schema backend'а
|
||
- Если backend меняется → нужно перегенерить TS типы
|
||
|
||
### NSPD WAF / rate limiting
|
||
- Используй rosreestr2coord lib (v5+), НЕ свой urllib
|
||
- Rate limit делается worker'ом (`time.sleep(rate_ms / 1000)`), НЕ библиотекой (в v5 убрали delay параметр)
|
||
|
||
### CouchDB / LiveSync — данные не появляются в Obsidian
|
||
- Local vault на ноуте — single source of write
|
||
- Если LiveSync не запушил после изменения → команда `Self-hosted LiveSync: Replicate now`
|
||
- Если file body пустой → `Verify and repair all files` → Apply Remote (см. `04_mcp_obsidian_setup.md`)
|
||
|
||
### `git status` показывает trailing-whitespace / line-ending warnings
|
||
- Это от core.autocrlf на Windows. Pre-commit `mixed-line-ending` hook fix'ит автоматом.
|
||
|
||
## Don't do these (no exceptions)
|
||
|
||
### Knowledge / memory
|
||
- ❌ **Читать или писать в `memory/memory-gendesign.jsonl`** — он deprecated. Knowledge только в Obsidian vault.
|
||
- ❌ **Создавать новые `.md` для knowledge вне vault'а** — никаких `docs/research/*.md`, `notes/`, `wiki/` etc. Всё что про предметную область → vault.
|
||
- ❌ Использовать `aim_memory_*` MCP tools (старая knowledge-graph MCP server'а нет, поэтому даже не пытайся).
|
||
- ❌ Удалять MOC.md файлы в vault'е — они нужны для навигации.
|
||
- ❌ Писать новые сущности в `old/` папку vault'а — это архив legacy paths.
|
||
|
||
### Code / git
|
||
- ❌ **Direct push в main** — только через PR. Все изменения на feature branch → `gh pr create` → user approval → merge. См. "Git workflow".
|
||
- ❌ **Merge PR без явного user approval** ("merge it" / "approved" / "ok merge").
|
||
- ❌ `--no-verify`, `--amend`, `--no-edit`, `--no-gpg-sign` — обходить hooks/signing нельзя.
|
||
- ❌ `git push --force` ни в main ни в feature branch без approval.
|
||
- ❌ Hardcode credentials в код / в коммиты. Используй `os.environ.get()` + `.env`/`.env.runtime`.
|
||
- ❌ `print(...)` для логирования в prod-коде — использовать `logger.info/warning/error`.
|
||
- ❌ Catching `Exception` без re-raise или явного логирования (silent failures).
|
||
- ❌ Использовать `requests` напрямую — есть `httpx` в стеке.
|
||
- ❌ Импортировать `psycopg2` — в проекте только psycopg v3.
|
||
|
||
### Schema / migrations
|
||
- ❌ Запускать миграции на prod без понимания зависимостей (views на колонки, FK).
|
||
- ❌ Менять `categorize_v2` в `scripts/migrate_kg_to_obsidian.py` без сопутствующей миграции (path scheme должен оставаться backwards-compatible).
|
||
- ❌ `DROP TABLE` / `TRUNCATE` без явного approval пользователя.
|
||
|
||
## Token efficiency tips для Claude
|
||
|
||
- **Не читай 00_index.md → каждый entity по списку** — это 268 read'ов, ~500K токенов. Иди через MOC + tags.
|
||
- **`grep -l` (или `Grep` с `output_mode: files_with_matches`)** дешевле полного content reading.
|
||
- **Один `obsidian_simple_search`** часто заменяет 3-5 `Read` + parse.
|
||
- При write — обновляй MOC.md только если структурное изменение (новый entity, переименование, удаление). Append observation в existing entity не требует MOC update.
|
||
- Когда видишь много `[[wiki-links]]` — НЕ читай каждый, спроси у user'а что именно интересует.
|
||
|
||
## Project-specific knowledge to load on first read
|
||
|
||
При старте новой задачи в этом репо — first principles в vault'е:
|
||
- `meta/02_claude_usage.md` — этот гайд (источник истины — vault'овая копия)
|
||
- `meta/00_credentials.md` — secrets (когда нужны для debug-задач)
|
||
- `decisions/` папка — почему мы делаем так а не иначе (ADR-style)
|
||
- `fixes/` папка — что уже ломалось и как чинили
|
||
- `limitations/` папка — что НЕ работает / не реализовано
|
||
|
||
Для специфичной работы — открывай MOC по релевантному домену (`domains/<area>/<area>-MOC.md`).
|
||
|
||
---
|
||
|
||
**Maintenance:** этот файл обновляется когда:
|
||
- Меняется tech stack (миграция фреймворка / DB)
|
||
- Появляются новые workflow rules (новые hooks, новые workflow в CI)
|
||
- Команда сталкивается с recurring pitfall → запиши его в "Common pitfalls"
|
||
- Меняется структура vault'а / MOC scheme
|
||
|
||
Не превращай в новеллу — держи функциональный, action-oriented, без воды.
|