diff --git a/.cursor/rules/agent-pitfalls.mdc b/.cursor/rules/agent-pitfalls.mdc index 90dbbe2..f20cd2c 100644 --- a/.cursor/rules/agent-pitfalls.mdc +++ b/.cursor/rules/agent-pitfalls.mdc @@ -1,119 +1,120 @@ ---- -description: Типичные ошибки агентов EventHub — shell, git, docker, scope, токены (корень + субагенты) -alwaysApply: true ---- - -# EventHub: типичные ошибки агентов (избегать) - -Канон. Субагентам: включать в промпт «следуй `agent-pitfalls.mdc` + `shell-wsl-not-powershell.mdc`». - -## 1. Shell / PowerShell - -| Симптом | Причина | Как правильно | -|---------|---------|---------------| -| `bash: /mnt/c/.../.tmp-*.sh: No such file or directory` при том что `ls` файл видит | **CRLF** от Cursor Write: shebang = `bash\r` | **Всегда** `wsl -e bash /mnt/c/Users/alexc/.cursor/eventhub/run-wsl-sh.sh /mnt/c/.../script.sh` (или `sed -i 's/\r$//' && bash`). **Не** голый `wsl -e bash /mnt/c/.../script.sh` | -| `unexpected EOF`, `ParserError`, пустой curl | PS ломает `"`, `$`, heredoc, `&&` | Файл `.sh` → `run-wsl-sh.sh` | -| `bash: syntax error near '('` | `grep -E ^(...)` в PS; **`fix(ci):` / `(…)` в `wsl -lc` one-liner** | Только внутри `.sh`; commit → `-F` файл (см. ниже) | -| `{{.Names}}: command not found` | `docker --format "{{…}}"` в PS | Формат в `.sh` или простой `docker ps` | -| `&&` is not valid | PowerShell не bash | Отдельные команды или `.sh` | - -**Запрещено в PS:** голый `wsl -e bash /mnt/c/.../.tmp-*.sh` (без `run-wsl-sh.sh`), `wsl -e bash -lc "…\"…"`, `curl -d "{\"x\":…}"`, heredoc commit, `npm`/`rebar3`. - -Канон запуска скриптов: см. `shell-wsl-not-powershell.mdc` § CRLF. - -## 2. Git - -| Симптом | Как правильно | -|---------|---------------| -| `#` в `-m` обрезает сообщение | `-F` файл; в тексте `Refs EventHub/EventHubBack#N` | -| `syntax error near '('` на commit | Сообщение `fix(ci): …` inline в `wsl -lc '… git-commit.sh … fix(ci): …'` | **Только** `.tmp-commit-msg.txt` + `git commit -F`; или `.sh` без inline `-m` | -| `Co-authored-by: Cursor <…>` / `<` ParserError | `git commit -F .tmp-msg.txt` из PS **или** `git-commit.sh` **из `.sh`**, не из PS one-liner | -| `editor` / not a terminal | Не `git commit` без `-F` в WSL; из Windows: `git commit -F file` | -| Сотни `M` после reset на `/mnt/c` | `git config core.filemode false` (локально); не «чинить» код | -| Удалились `.cursor/`, `.idea/` | **`git clean -fdx` только с backup** env + certs; IDE-директории **не трогать** | -| Push «висит» / ждёт login | **Не** `git push origin` — только `~/.cursor/eventhub/git-push.sh` / `git-push-main.sh` | -| Push заблокирован Auto-review | Push в `master` — только по явной просьбе; `request_smart_mode_approval` | - -**`git clean` / reset к origin:** сначала сохранить `docker/.env*`, `.env.development`, `docker/traefik/certs/*`. - -**Push:** запрещены голые `git push` / `git push origin …`. Канон — `bash /mnt/c/Users/alexc/.cursor/eventhub/git-push.sh ` (токен из secrets). - -**Commit (сообщение со скобками, `#`, `$`, пробелами):** не передавать subject/body аргументом через PowerShell или `wsl -e bash -lc '…'`. Пиши `.tmp-commit-msg.txt` в репо, затем в `.sh`: - -```bash -cd /mnt/c/Users/alexc/IdeaProjects/eventHub/EventHubBack -git add path/to/file -GIT_EDITOR=true git commit -F .tmp-commit-msg.txt -``` - -Запуск из PS: `wsl -e bash /mnt/c/Users/alexc/.cursor/eventhub/run-wsl-sh.sh /mnt/c/.../EventHubBack/.tmp-commit.sh` — **без** голого `wsl -e bash …/.tmp-commit.sh`, **без** `-lc` и **без** `-m "fix(ci): …"`. - -## 3. Docker dev (Swarm локально) - -| Ошибка | Правильно | -|--------|-----------| -| «Балансировка» → 3× eventhub | **dev:** `traefik=1` + **`eventhub=1`** (см. `EventHubDevOps/docs/STANDS.md`) | -| `host-mode port already in use` | У eventhub опубликованы 8080/8445 — **нельзя** scale >1; LB = traefik | -| Собрали admin-ui/front без просьбы | «Только бэк» → eventhub (+ traefik если нужен HTTPS), **без** Front/Admin образов | -| Эмулятор не остановился | `docker service scale eventhub_bot-emulator-users=0` | -| `No such image: eventhub:latest` | Сначала `docker build -t eventhub:latest …` или `docker/build-images.sh` | -| Admin API dev не отвечает на :443 | Traefik без ports → **`http://127.0.0.1:8445`**; stage → SSH + `--resolve …:443:127.0.0.1` | - -## 4. Scope (не додумывать) - -- Делать **ровно** запрос; не раздувать (полный `build-images.sh`, 3 ноды, admin-ui, spec commit). -- Перед scale/deploy — прочитать compose и STANDS.md. -- Секреты: `gitea.ps1` / `.sh` + env; не inline `source secrets` в PS one-liner. - -## 5. Субагенты (Task) - -В промпт субагента добавлять: - -```text -Shell: только WSL + .sh (см. shell-wsl-not-powershell.mdc, agent-pitfalls.mdc). -Один репо. Итог на русском. Не push без явного OK. -``` - -## 6. Экономия токенов / лимитов моделей - -### Контекст чата -- **Один чат — одна задача**; после «готово / CI зелёный» — новый чат на следующий шаг (см. `WORKFLOW.md` §5). -- Workspace: для Back-задачи достаточно **`EventHubBack`** (+ Spec при необходимости); не держать все репо без нужды. -- **`@` точечно** — файл/папка, не `@Codebase` без причины. -- Не просить «проанализируй все transcripts» — они огромные. - -### Дешёвые vs дорогие действия -| Дорого | Дешевле | -|--------|---------| -| Task explore «very thorough» | `grep` + 1–2 файла | -| Полный `build-images.sh` | Только нужный образ | -| Весь лог CI (80k строк) | API job + 20 строк вокруг ошибки | -| Несколько subagents «на всякий» | 1 subagent, узкий промпт | -| Browser deep-walk stage | Smoke-скрипт / один URL | - -### Меньше итераций -- Сразу **`.sh`**, не 5 попыток PS one-liner (каждая = новый turn). -- Git перед commit: **один** `status` + `diff`, не три раза подряд. -- Тесты: `rebar3 eunit --module=…` если трогали один модуль; не полный suite без нужды. -- Docker: не rebuild, если `docker images` уже есть нужный tag. - -### Модели и режимы -- **Ask / Plan** — вопросы и варианты без tool calls. -- **Agent** — только когда нужны команды и правки. -- Bugbot / Security Review — не на каждый мелкий diff. - -### Scope в запросе (шаблон) -```text -Репо: EventHubBack -Issue: #N -Scope: только … -Не: front, docker, push, spec -Done: eunit / lint / … -``` - -### Subagents -- Редко; промпт = issue + файлы + done, **без** всей переписки. -- `one-repo-per-agent` — меньше контекста и ошибок. - -### Повторяемое — в скрипты -Токены verify, smoke creds, stage deploy — **`~/.cursor/eventhub/*.sh`**, не заново через SSH в каждом чате. +--- +description: Типичные ошибки агентов EventHub — shell, git, docker, scope, токены (корень + субагенты) +alwaysApply: true +--- + +# EventHub: типичные ошибки агентов (избегать) + +Канон. Субагентам: включать в промпт «следуй `agent-pitfalls.mdc` + `shell-wsl-not-powershell.mdc`». + +## 1. Shell / PowerShell + +| Симптом | Причина | Как правильно | +|---------|---------|---------------| +| `bash: /mnt/c/.../.tmp-*.sh: No such file or directory` при том что `ls` файл видит | **CRLF** от Cursor Write: shebang = `bash\r` | **Всегда** `wsl -e bash /mnt/c/Users/alexc/.cursor/eventhub/run-wsl-sh.sh /mnt/c/.../script.sh` (или `sed -i 's/\r$//' && bash`). **Не** голый `wsl -e bash /mnt/c/.../script.sh` | +| IFT e2e: **N skipped**, exit 0 | Нет `SMOKE_USER_*` (голый `npm run test:e2e:ift`) | `run-front-ift.sh` / source `eventhub-ift.env` **до** npm. Не путать со «стенд недоступен». CI уже крутит e2e-ift → локально не дублировать | +| `unexpected EOF`, `ParserError`, пустой curl | PS ломает `"`, `$`, heredoc, `&&` | Файл `.sh` → `run-wsl-sh.sh` | +| `bash: syntax error near '('` | `grep -E ^(...)` в PS; **`fix(ci):` / `(…)` в `wsl -lc` one-liner** | Только внутри `.sh`; commit → `-F` файл (см. ниже) | +| `{{.Names}}: command not found` | `docker --format "{{…}}"` в PS | Формат в `.sh` или простой `docker ps` | +| `&&` is not valid | PowerShell не bash | Отдельные команды или `.sh` | + +**Запрещено в PS:** голый `wsl -e bash /mnt/c/.../.tmp-*.sh` (без `run-wsl-sh.sh`), `wsl -e bash -lc "…\"…"`, `curl -d "{\"x\":…}"`, heredoc commit, `npm`/`rebar3`. + +Канон запуска скриптов: см. `shell-wsl-not-powershell.mdc` § CRLF. + +## 2. Git + +| Симптом | Как правильно | +|---------|---------------| +| `#` в `-m` обрезает сообщение | `-F` файл; в тексте `Refs EventHub/EventHubBack#N` | +| `syntax error near '('` на commit | Сообщение `fix(ci): …` inline в `wsl -lc '… git-commit.sh … fix(ci): …'` | **Только** `.tmp-commit-msg.txt` + `git commit -F`; или `.sh` без inline `-m` | +| `Co-authored-by: Cursor <…>` / `<` ParserError | `git commit -F .tmp-msg.txt` из PS **или** `git-commit.sh` **из `.sh`**, не из PS one-liner | +| `editor` / not a terminal | Не `git commit` без `-F` в WSL; из Windows: `git commit -F file` | +| Сотни `M` после reset на `/mnt/c` | `git config core.filemode false` (локально); не «чинить» код | +| Удалились `.cursor/`, `.idea/` | **`git clean -fdx` только с backup** env + certs; IDE-директории **не трогать** | +| Push «висит» / ждёт login | **Не** `git push origin` — только `~/.cursor/eventhub/git-push.sh` / `git-push-main.sh` | +| Push заблокирован Auto-review | Push в `master` — только по явной просьбе; `request_smart_mode_approval` | + +**`git clean` / reset к origin:** сначала сохранить `docker/.env*`, `.env.development`, `docker/traefik/certs/*`. + +**Push:** запрещены голые `git push` / `git push origin …`. Канон — `bash /mnt/c/Users/alexc/.cursor/eventhub/git-push.sh ` (токен из secrets). + +**Commit (сообщение со скобками, `#`, `$`, пробелами):** не передавать subject/body аргументом через PowerShell или `wsl -e bash -lc '…'`. Пиши `.tmp-commit-msg.txt` в репо, затем в `.sh`: + +```bash +cd /mnt/c/Users/alexc/IdeaProjects/eventHub/EventHubBack +git add path/to/file +GIT_EDITOR=true git commit -F .tmp-commit-msg.txt +``` + +Запуск из PS: `wsl -e bash /mnt/c/Users/alexc/.cursor/eventhub/run-wsl-sh.sh /mnt/c/.../EventHubBack/.tmp-commit.sh` — **без** голого `wsl -e bash …/.tmp-commit.sh`, **без** `-lc` и **без** `-m "fix(ci): …"`. + +## 3. Docker dev (Swarm локально) + +| Ошибка | Правильно | +|--------|-----------| +| «Балансировка» → 3× eventhub | **dev:** `traefik=1` + **`eventhub=1`** (см. `EventHubDevOps/docs/STANDS.md`) | +| `host-mode port already in use` | У eventhub опубликованы 8080/8445 — **нельзя** scale >1; LB = traefik | +| Собрали admin-ui/front без просьбы | «Только бэк» → eventhub (+ traefik если нужен HTTPS), **без** Front/Admin образов | +| Эмулятор не остановился | `docker service scale eventhub_bot-emulator-users=0` | +| `No such image: eventhub:latest` | Сначала `docker build -t eventhub:latest …` или `docker/build-images.sh` | +| Admin API dev не отвечает на :443 | Traefik без ports → **`http://127.0.0.1:8445`**; stage → SSH + `--resolve …:443:127.0.0.1` | + +## 4. Scope (не додумывать) + +- Делать **ровно** запрос; не раздувать (полный `build-images.sh`, 3 ноды, admin-ui, spec commit). +- Перед scale/deploy — прочитать compose и STANDS.md. +- Секреты: `gitea.ps1` / `.sh` + env; не inline `source secrets` в PS one-liner. + +## 5. Субагенты (Task) + +В промпт субагента добавлять: + +```text +Shell: только WSL + .sh (см. shell-wsl-not-powershell.mdc, agent-pitfalls.mdc). +Один репо. Итог на русском. Не push без явного OK. +``` + +## 6. Экономия токенов / лимитов моделей + +### Контекст чата +- **Один чат — одна задача**; после «готово / CI зелёный» — новый чат на следующий шаг (см. `WORKFLOW.md` §5). +- Workspace: для Back-задачи достаточно **`EventHubBack`** (+ Spec при необходимости); не держать все репо без нужды. +- **`@` точечно** — файл/папка, не `@Codebase` без причины. +- Не просить «проанализируй все transcripts» — они огромные. + +### Дешёвые vs дорогие действия +| Дорого | Дешевле | +|--------|---------| +| Task explore «very thorough» | `grep` + 1–2 файла | +| Полный `build-images.sh` | Только нужный образ | +| Весь лог CI (80k строк) | API job + 20 строк вокруг ошибки | +| Несколько subagents «на всякий» | 1 subagent, узкий промпт | +| Browser deep-walk stage | Smoke-скрипт / один URL | + +### Меньше итераций +- Сразу **`.sh`**, не 5 попыток PS one-liner (каждая = новый turn). +- Git перед commit: **один** `status` + `diff`, не три раза подряд. +- Тесты: `rebar3 eunit --module=…` если трогали один модуль; не полный suite без нужды. +- Docker: не rebuild, если `docker images` уже есть нужный tag. + +### Модели и режимы +- **Ask / Plan** — вопросы и варианты без tool calls. +- **Agent** — только когда нужны команды и правки. +- Bugbot / Security Review — не на каждый мелкий diff. + +### Scope в запросе (шаблон) +```text +Репо: EventHubBack +Issue: #N +Scope: только … +Не: front, docker, push, spec +Done: eunit / lint / … +``` + +### Subagents +- Редко; промпт = issue + файлы + done, **без** всей переписки. +- `one-repo-per-agent` — меньше контекста и ошибок. + +### Повторяемое — в скрипты +Токены verify, smoke creds, stage deploy — **`~/.cursor/eventhub/*.sh`**, не заново через SSH в каждом чате. diff --git a/.gitignore b/.gitignore index 671f9cb..c078796 100644 --- a/.gitignore +++ b/.gitignore @@ -1,42 +1,45 @@ -/EventHubBack.iml -/.idea/ -.rebar3 -_build -_checkouts -_vendor -.eunit -*.o -*.beam -*.plt -*.swp -*.swo -.erlang.cookie -ebin -log -erl_crash.dump -.rebar -logs -data -ci-out -.idea -*.iml -rebar3.crashdump -*~ -/.tool-versions -/rebar.lock -/build/ -docker/.env -docker/.env.ift -docker/.env.stage -/Mnesia.*/ -/doc/ - -# Локальные учётки admin для Tsung IFT (см. test/tsung/ift-admin.csv.example) -/test/tsung/ift-admin.csv -# Пул пользователей для stress hot-path (см. test/tsung/ift-users.csv.example) -/test/tsung/ift-users.csv - -# Traefik TLS private keys (generated locally for dev/staging). -# Никогда не коммитим приватный ключ в репозиторий. -docker/traefik/certs/*.key -docker/traefik/certs/*.pem +/EventHubBack.iml +/.idea/ +.rebar3 +_build +_checkouts +_vendor +.eunit +*.o +*.beam +*.plt +*.swp +*.swo +.erlang.cookie +ebin +log +erl_crash.dump +.rebar +logs +data +ci-out +.idea +*.iml +rebar3.crashdump +*~ +/.tool-versions +/rebar.lock +/build/ +docker/.env +docker/.env.ift +docker/.env.stage +/Mnesia.*/ +/doc/ + +# Локальные учётки admin для Tsung IFT (см. test/tsung/ift-admin.csv.example) +/test/tsung/ift-admin.csv +# Пул пользователей для stress hot-path (см. test/tsung/ift-users.csv.example) +/test/tsung/ift-users.csv + +# Traefik TLS private keys (generated locally for dev/staging). +# Никогда не коммитим приватный ключ в репозиторий. +docker/traefik/certs/*.key +docker/traefik/certs/*.pem + +# Temporary/scratch files +.tmp-*