From 5314fa5ab62de73827f8c75038f0edf670422dd2 Mon Sep 17 00:00:00 2001 From: friench Date: Mon, 27 Jul 2026 13:56:24 +0000 Subject: [PATCH] docs(agents): working style + git workflow + agent-loop/drift configs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CLAUDE.md: fleet working-style sections (§0–§11), §12 Git Workflow (mailctl is the working remote, origin is the public mirror; squash-PR into main; CI gates), §13 skills incl. project drizzle skill. AGENT_LOOP.md (target main = default, verify mirrors ci.yml, mail-infra hard limits) and DRIFT.md (discovery-only; auth/docker-exec surfaces flagged security). .claude/drift/ gitignored. --- .gitignore | 1 + AGENT_LOOP.md | 59 ++++++++++++ CLAUDE.md | 247 ++++++++++++++++++++++++++++++++++++++++++++++++++ DRIFT.md | 25 +++++ 4 files changed, 332 insertions(+) create mode 100644 AGENT_LOOP.md create mode 100644 DRIFT.md diff --git a/.gitignore b/.gitignore index 28127a0..a85d619 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,4 @@ nginx/nginx_secrets/ # Claude Code runtime .claude/scheduled_tasks.lock .claude/*.lock +.claude/drift/ diff --git a/AGENT_LOOP.md b/AGENT_LOOP.md new file mode 100644 index 0000000..8827866 --- /dev/null +++ b/AGENT_LOOP.md @@ -0,0 +1,59 @@ +# AGENT_LOOP.md — конфиг ralf-loop для mailserver (mail-control-plane) + +**Механика: юзер-скилл `agent-loop` v1** (`~/.claude/skills/agent-loop`) — +итерация загружает его первым и следует ему с конфигом из этого файла. При +несовпадении версий — стоп, вопрос владельцу. Механика issue/досок — скилл +`github-issues`. + +Итерация читает: этот файл, скилл, доску, доки в `_docs/` +(`architecture.md`, `deployment.md`), git и CI. + +## Конфиг + +- **Репо/трекер:** `friench/mailctl` (remote `mailctl` — рабочий; remote + `origin` = публичное зеркало `friench/mailserver`, цикл его НЕ трогает). +- **Доска:** ещё не создана (см. «Предпосылки запуска»). Issues живут в + `friench/mailctl`; после создания доски вписать сюда номер + (`gh project item-list --owner friench`). +- **`TARGET_BRANCH = main`** — она же default-ветка `mailctl`, поэтому + `Closes #N` в PR закрывает issue при мердже. PR **squash**-мерджит человек. +- **Verify (из `mailserver-api/`, зеркалит ci.yml):** + 1. `pnpm lint` + `pnpm format:check` + 2. `pnpm typecheck` + `pnpm --dir ui typecheck` + 3. `pnpm test` + 4. `pnpm build` + CI-workflow есть и прогоняется → действует правило (а) скилла: зелёный CI + на PR обязателен; account-причины — правило (в). +- **Порядок Select:** метка `security` < `bug` < `enhancement`; без метки — + после всех; при равенстве — меньший номер. + +## Жёсткие ограничители (mailserver — сильнее механики скилла) + +- **Никаких операций против развёрнутого стека.** Прод живёт отдельно + (Dokploy; `docker-compose.dokploy.yml`): не деплоить, не перезапускать + контейнеры, не гонять `docker compose` против боевых томов. Локальный + compose — можно. +- **Реальную почтовую инфраструктуру не трогать:** ни DNS/DKIM/сертификатов, + ни отправки настоящих писем. Всё через тесты (Vitest + Supertest) и моки. +- **Секреты не трогать:** `.env`, `SESSION_SECRET`, API-ключи, пароли — + только владелец. В коде секреты не появляются (см. существующие паттерны + sha256 / SecretBox). +- **Drizzle-миграции** пишутся как код (`pnpm db:generate`), применяются + только к локальной dev-БД. Никогда против боевой `data.db`. +- **Push только в `mailctl`.** В `origin` (публичное зеркало) цикл не пушит. + +## Стоп-лист (метка `manual-track`) + +Метку ставит владелец. Кандидаты на сейчас: #75 (неатомарные двойные записи +DMS+DB — архитектурное решение о транзакционности), #71 (vhost/сертификат — +завязано на поведение боевого nginx). Пока метки не расставлены и доски нет, +цикл не запускать. + +## Предпосылки запуска + +- [ ] Создать доску Projects-v2, привязать `friench/mailctl`, настроить + Status-колонки под pipeline скилла, занести открытые issues; вписать + номер доски в этот файл. +- [ ] Проставить `manual-track` по стоп-листу выше. +- [ ] В `Todo` — хотя бы одна refined-issue с acceptance criteria и закрытыми + блокерами (хорошие кандидаты: #80, #81 — узкие UI-задачи). diff --git a/CLAUDE.md b/CLAUDE.md index 4c249a9..e4cf74b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -122,3 +122,250 @@ docker exec -it mailserver setup config dkim domain example.com | `DOCKER_HOST` | (unset) | When set (e.g. `tcp://docker-socket-proxy:2375`) all dockerode clients connect via the proxy instead of the raw socket. `lib/docker.ts` resolves the connection; the default compose wires a least-privilege `tecnativa/docker-socket-proxy`. | | `TRUST_PROXY` | `0` | Set to `1` when behind nginx so `req.ip` is correct | | `INITIAL_ADMIN_EMAIL` / `INITIAL_ADMIN_PASSWORD` | (optional) | Bootstrap first admin if `users` table is empty | + +--- + +## Working style + +Behavioral and review guidelines for this project. Bias toward caution over speed; for trivial tasks, use judgment. + +## 0. Start Mode + +Before starting any non-trivial task, ask: + +**Is this a BIG, SMALL, or TRIVIAL change?** + +- **BIG** — full review across all sections (Architecture → Code → Tests → Performance), top 3–4 issues per section, pause for feedback after each. +- **SMALL** — one focused question per section, keep the review concise. +- **TRIVIAL** — skip the structured review; apply behavioral rules (§1–§5) directly. + +For BIG and SMALL changes, do NOT begin implementation until the plan is reviewed and approved. + +--- + +## 1. Think Before Coding + +Don't assume. Don't hide confusion. Surface tradeoffs. + +- State assumptions explicitly. If uncertain, ask. +- If multiple interpretations exist, present them — don't pick silently. +- If a simpler approach exists, say so. Push back when warranted. +- If something is unclear, stop. Name what's confusing. Ask. + +For every issue or recommendation: + +- Explain concrete tradeoffs +- Give an opinionated recommendation (not a neutral summary) +- Ask for input before proceeding + +--- + +## 2. Simplicity First + +Minimum code that solves the problem. Nothing speculative. + +- No features beyond what was asked. +- No abstractions for single-use code. +- No "flexibility" or "configurability" that wasn't requested. +- No error handling for impossible scenarios (real edge cases are covered in §4). +- If you write 200 lines and it could be 50, rewrite it. + +Test: "Would a senior engineer say this is overcomplicated?" If yes, simplify. + +--- + +## 3. Surgical Changes + +Touch only what you must. Clean up only your own mess. + +When editing existing code: + +- Don't "improve" adjacent code, comments, or formatting. +- Don't refactor things that aren't broken. +- Match existing style, even if you'd do it differently. +- If you notice unrelated dead code, mention it — don't delete it. + +When your changes create orphans: + +- Remove imports/variables/functions that YOUR changes made unused. +- Don't remove pre-existing dead code unless asked. + +Test: every changed line should trace directly to the request. + +--- + +## 4. Engineering Principles + +- **DRY** — aggressively flag _real_ duplication. Do not pre-abstract for hypothetical reuse (see §2). +- **Well-tested code is mandatory** for non-trivial logic — better too many tests than too few. Trivial glue code does not need tests. +- **Engineered enough** — not fragile or hacky, not over-engineered. +- **Correctness over speed of implementation** — think hard about real edge cases. +- **Explicit over clever.** + +> Note on §2 ↔ §4 tension: §2 governs _scope and abstraction_; §4 governs _correctness of what you ship_. Don't write tests for code that shouldn't exist, but don't ship untested non-trivial logic to stay "minimal." + +--- + +## 5. Goal-Driven Execution + +Define success criteria. Loop until verified. + +Transform tasks into verifiable goals: + +- "Add validation" → "Write tests for invalid inputs, then make them pass" +- "Fix the bug" → "Write a test that reproduces it, then make it pass" +- "Refactor X" → "Ensure tests pass before and after" + +For multi-step tasks, state a brief plan: + +``` +1. [Step] → verify: [check] +2. [Step] → verify: [check] +3. [Step] → verify: [check] +``` + +Strong success criteria enable independent looping. Weak criteria ("make it work") require constant clarification. + +--- + +## 6. Review Sections (BIG changes) + +### 6.1 Architecture + +- Overall system design and component boundaries +- Dependency graph and coupling risks +- Data flow and potential bottlenecks +- Scaling characteristics and single points of failure +- Security boundaries (auth, data access, API limits) + +### 6.2 Code Quality + +- Project structure and module organization +- DRY violations +- Error handling patterns and missing edge cases +- Technical debt risks +- Areas over- or under-engineered + +### 6.3 Tests + +- Coverage (unit, integration, e2e) +- Quality of assertions +- Missing edge cases +- Untested failure scenarios + +### 6.4 Performance + +- N+1 queries or inefficient I/O +- Memory usage risks +- CPU hotspots or heavy code paths +- Caching opportunities +- Latency and scalability concerns + +After each section, pause and ask for feedback. Do NOT implement until confirmed. + +--- + +## 7. Issue Format + +For each issue found, provide: + +1. Clear description of the problem +2. Why it matters +3. 2–3 options (including "do nothing" if reasonable) +4. For each option: **effort / risk / impact / maintenance cost** +5. Recommended option and why + +Then ask for approval before moving forward. + +--- + +## 8. Output Style + +- Structured and concise +- Opinionated recommendations, not neutral summaries +- Focus on real risks and tradeoffs +- Think like a Staff/Senior Engineer reviewing a production system + +--- + +## 9. Documentation & Context + +- Use **Context7 MCP** automatically when library/API documentation, code generation, or setup/configuration steps are needed — without explicit request. +- When generating code, verify against up-to-date docs for the specific version in use. +- Reference project documentation in `_docs/` before making architectural decisions. + +--- + +## 10. Workflow Rules + +- Do NOT assume priorities or timelines. +- Pause for feedback after each review section on BIG changes. +- Do NOT implement until confirmed. +- Clarifying questions come **before** implementation, not after mistakes. + +--- + +## 11. Agent Teams + +When a task is non-trivial, prefer to **dispatch a team** rather than work alone: one role plays tech-lead/router (usually the conversation itself), others do focused implementation, and a final pass re-verifies everything. + +### 11.1 Subagent types worth knowing + +- **`Explore`** — read-only search agent. Cheap. Use it before writing anything when the scope spans more than 2-3 files. It reads excerpts, not whole files — not suitable for cross-file consistency checks. +- **`general-purpose`** — the main implementation agent (TS backend, React UI, MCP server), and the fallback for cross-cutting chores. +- **`Plan`** — when you need an explicit step-by-step implementation plan before writing code. +- **Specialists** (`fullstack-dev-skills:{code-reviewer,security-reviewer,test-master,…}`) — the auth/session/API-key surface and the docker-exec paths are security-sensitive; use `security-reviewer` on changes touching them. + +### 11.2 Orchestration patterns that work + +- **Parallel-by-file-boundary** (most common): N agents at once, each owning a disjoint set of files; zero merge conflicts at integration. Here that maps to: a `domain/` module vs. its routes/validators vs. UI pages vs. `mcp/`. +- **Tech-lead sweep**: when work touches **shared** files (`schema.ts`, route registration, `openapi.ts` manifest, i18n locales), agents write only their owned files and the tech-lead applies shared-file edits post-factum. +- **Sequential by dependency**: don't parallelise across a contract you haven't agreed yet (e.g. a new table schema must land before the worker consuming it). +- **Scout first, plan, then implement**; **worktree isolation** (`isolation: "worktree"`) only when file overlap is unavoidable. + +### 11.3 Verification discipline (learned the hard way) + +- **Agents commonly claim "verification pending" when shell access is denied to them.** Always re-run typecheck + lint + tests as the tech-lead after each agent returns. Do not trust self-reports of "all looks correct". +- **Agents over-report test counts.** Verify with `pnpm test` directly, not the agent's tally. +- **Agents do not commit.** Tech-lead commits after review, grouping by logical concern. +- **Revision cycles** — up to 10 per task, but in practice 0-1 is typical with sufficient briefing. If you hit cycle 3, the prompt was wrong; rewrite it. + +--- + +## 12. Git Workflow + +### 12.1 Remotes — check before every push + +- **`mailctl`** (`friench/mailctl`) — the **working** remote: `main` tracks `mailctl/main`, issues and PRs live here. +- **`origin`** (`friench/mailserver`) — the public release mirror. Push there only deliberately (release/`chore/public-release` work), never as a side effect. + +### 12.2 Branches & PRs + +- **`main`** — default and target branch. Feature branches `/` (`feat/mcp-coverage`, `fix/security-hardening`, `refactor/service-layer`, `infra/deployment-hardening`). +- PRs go to `main` on `mailctl` and are **squash-merged** (linear history; the squash title keeps the `(#N)` suffix). Merge is the owner's call. +- Direct pushes to `main` have happened for urgent deploy-fixes only; the default path is a PR. + +### 12.3 CI & commits + +- [ci.yml](./.github/workflows/ci.yml) runs on push/PR to `main`: `pnpm lint`, `format:check`, API + UI `typecheck`, `test`, `build` (all in `mailserver-api/`). Green CI before merge; reproduce failures locally with the same commands — don't debug by re-pushing. +- Conventional-Commits-style prefixes (`feat`, `fix`, `chore`, `refactor`, `perf`, `infra`); subjects may be in Russian — match the existing style. +- Do NOT append the `Co-Authored-By: Claude ...` trailer (or any Claude/Anthropic co-author line) to commit messages. End the commit message at the actual content. + +--- + +## 13. Skills + +Invoke via the Skill tool (or `/`). Available in sessions on this host: + +### 13.1 User-level (`~/.claude/skills/`, available in every session) + +- **`apple-design`** — Apple-style interface design and fluid motion for the web: gestures, spring animations, sheets/drawers, translucency, typography, reduced-motion. Use when building or reviewing the React dashboard (`mailserver-api/ui/`). +- **`github-issues`** — gh CLI + Projects-v2 board mechanics on this host. Use for any work on the `friench/mailctl` issue tracker. +- **`agent-loop`** — supervised board-driven iteration; project config in [AGENT_LOOP.md](./AGENT_LOOP.md) (check its launch prerequisites before starting a loop). +- **`drift`** — autonomous discovery mode (no code changes; findings become `drift`-labeled issues in `friench/mailctl`); project config in [DRIFT.md](./DRIFT.md). +- **`humanize-text`** — rewrite text into a natural human voice (README, release notes). +- **agentmemory suite** — `recall`, `remember`, `recap`, `handoff`, `session-history`, `commit-context`, `commit-history`, `forget`. Use `handoff`/`recall` at session start to pick up prior context; `remember` for decisions worth keeping. + +### 13.2 Project-level ([.claude/skills/](./.claude/skills/)) + +- **`drizzle`** — Drizzle ORM patterns for this repo (schema in `src/db/schema.ts`, generated SQL migrations in `drizzle/`). Use for any schema/migration work. diff --git a/DRIFT.md b/DRIFT.md new file mode 100644 index 0000000..e0fa2b7 --- /dev/null +++ b/DRIFT.md @@ -0,0 +1,25 @@ +# DRIFT.md — конфиг drift-режима для mailserver (mail-control-plane) + +**Механика: юзер-скилл `drift` v1** (`~/.claude/skills/drift`). Drift ничего +не меняет в коде — только issues с меткой `drift`. + +## Конфиг + +- **Трекер:** `friench/mailctl` (remote `mailctl`; `origin` — публичное + зеркало, issues туда НЕ создавать). Доски нет — пока только метки; + появится — вписать номер и колонку «Drift». +- **FOCUS:** `mailserver-api/src/` — auth/session/API-key поверхность и + docker-exec пути (это security-чувствительные зоны: находки → метка + `security`), санитизация в `lib/*-parsers.ts`, дыры в тестах воркеров + (send/webhook/sync/migration), `mcp/` — дрейф инструментов от REST; + расхождения `_docs/*.md` с кодом. Известный контекст — открытые issues + #67–#81: дубли не плодить. +- **FROZEN:** `.env*`, `data/` (боевая `data.db`), всё про DNS/DKIM/сертификаты + и Dokploy-деплой (находки об этом — только `needs-owner`, без операций). +- **Лимиты:** `MAX_ISSUES=5` за тик · `SECURITY_EVERY=7д` · тик ≤ 45 мин. + +## Предпосылки запуска + +- [ ] `.claude/drift/` добавлен в `.gitignore` (сейчас `.temp/`/`.claude/` + статус проверить). +- [ ] Метка `drift` создана в `friench/mailctl`.