From ec2ea7d4a16c4939d83c88ba391826f24ff65d8b Mon Sep 17 00:00:00 2001 From: Fedorov Vladimir Date: Sun, 30 Aug 2026 21:25:02 +0700 Subject: [PATCH] add rules --- .dsh/AGENTS.md | 33 +++++++++++++++++++++++++++++ .dsh/skills/task-execution/SKILL.md | 33 ++++++++++++++++++----------- 2 files changed, 54 insertions(+), 12 deletions(-) create mode 100644 .dsh/AGENTS.md diff --git a/.dsh/AGENTS.md b/.dsh/AGENTS.md new file mode 100644 index 0000000..f5bafa9 --- /dev/null +++ b/.dsh/AGENTS.md @@ -0,0 +1,33 @@ +# Правила работы в репозитории evening_detective_server + +Дополняют глобальный `~/.dsh/AGENTS.md`. Применяются в любой сессии в этом каталоге. + +## Сборка и проверки + +- **Кэш сборки**: системный `GOCACHE` (`/home/vladimir/.cache/go-build`) в этом окружении read-only. Всегда запускай Go-команды с локальным кэшем: + `export GOCACHE=/home/vladimir/projects/evening_detective_server/.gocache` + (иначе `go build/vet/test` падают с `read-only file system`). +- Стандартный набор проверок после изменений: `gofmt -l cmd/ internal/ api/`, `go build ./...`, `go vet ./...`, `go test -count=1 ./...`; при конкурентности — `go test -race ./...`. +- `go mod tidy` может не отработать (read-only module cache): если не хватает только перевода импортируемого пакета в прямые зависимости — перенеси его в первый require-блок вручную (эквивалентно tidy). + +## Прото + +- API описано в `api/main.proto`; сгенерированный код — `proto/` и `cmd/evening_detective_server/main.swagger.json`. +- После правки proto обязателен `make generate` (protoc v35.1, плагины в `~/go/bin`), затем `go build ./...`. +- **Конвенция REST — camelCase** (`accessToken`, `actionsCount`). Осознанное исключение: `file_type` в `Application`/`UploadFileRsp` (явный `json_name = "file_type"`, единый snake_case с внутренним JSON истории). Новые поля с явным json_name — только по согласованию. + +## Известные факты (не переоткрывать в каждой задаче) + +- Файлы хранятся в S3-совместимом RustFS (`file_storage`), URL префиксуются `FILE_PREFIX_DOMAIN` (см. `.env.example`). В БД и JSON истории — относительные имена; префикс добавляется только при чтении (идемпотентно, `prefixDomain`/`mapStory`). +- `string_tools.Transliterate` удаляет ВСЁ кроме `[a-z0-9_]` — включая точку расширения: `Transliterate("photo.png")` → `"photopng"`. Работать с расширением файла — отдельно (split base/ext до транслитерации). +- Улики = `Application { name, image, file_type }` (proto `api/main.proto`, `storytelling.Application`): живут в JSON истории сценария и в таблице `applications` (выданные команде). `file_type`: `image | pdf | audio`, деривируется из расширения через `file_storage.FileType`. +- Загрузка файлов: `POST /api/files/upload` — только роль `Author`, allowlist расширений pdf/jpg/jpeg/png/gif/webp/mp3/ogg/wav, содержимое проверяется sniff'ом (текст/html отклоняется), имя уникализируется `translit(base)_.`. Лимит файла 64 МБ: HTTP `maxFileUploadBody`, gRPC `grpcMsgLimit = maxFileSize + 1MiB`, бизнес-проверка в `file_service`. +- Ошибки размера на HTTP-слое мапятся в 413 через `customErrorHandler` (см. `cmd/evening_detective_server/main.go`): ветка `InvalidArgument` + «request body too large» — единственная реальная защита 413 (сгенерированный gateway-код строкифицирует `*http.MaxBytesError` через `%v`). +- Скачивание `GET /api/files/{filename}` — публичное, с `X-Content-Type-Options: nosniff`. + +## Процесс ревью (скилл task-execution) + +Загружай скилл `task-execution` для нетривиальных задач. Внутри него действуют правила экономии контекста: +- бюджет **3 раунда** на цикл (план/результат), «все замечания одним списком»; +- план/состояние — во внешнем файле (`.dsh/task-plan.md`), промпт ревью — дельта + `git diff`; +- саморевью фактическими проверками до отправки сеньёру (поведение функций на реальных данных, сгенерированный код, арифметика). diff --git a/.dsh/skills/task-execution/SKILL.md b/.dsh/skills/task-execution/SKILL.md index 0a53a11..94c58db 100644 --- a/.dsh/skills/task-execution/SKILL.md +++ b/.dsh/skills/task-execution/SKILL.md @@ -13,7 +13,7 @@ whenToUse: Пользователь просит выполнить задачу ## Роли - **Исполнитель** — ты (агент). Составляешь план, выполняешь, правишь по замечаниям. -- **Сеньёр (senior developer)** — отдельный субагент, запускаемый через `subagent`. Он **не видит наш диалог**, поэтому каждый промпт ревью должен быть самодостаточным: включай в него всю необходимую информацию (задачу, план, критерии, предыдущие замечания). +- **Сеньёр (senior developer)** — отдельный субагент, запускаемый через `subagent`. Он **не видит наш диалог**, поэтому каждый промпт ревью должен быть самодостаточным — но самодостаточность достигается за счёт внешнего файла состояния, а не дублирования всего плана в промпте (см. правило 9). - **Пользователь** — источник требований и финальный судья. Ему задаются вопросы при неясностях. ## Обязательные правила @@ -25,6 +25,9 @@ whenToUse: Пользователь просит выполнить задачу 5. **Неясно — спроси.** На любом этапе (задача, шаг плана, замечание сеньёра) при неоднозначности задай вопрос пользователю через `ask_user_question`. Догадки вместо вопросов — ошибка. 6. **Отслеживай прогресс** через `todo_write`: план из шага 2 переносится в todo-список, пункты отмечаются по мере выполнения. 7. **Профильные скилы** (например `create-go-module`) — источник правил «как делать» для конкретной задачи. Этот скил управляет процессом «как вести задачу»; оба применяются вместе. +8. **Бюджет раундов ревью — 3 на цикл** (план и результат отдельно). В шаблонах промптов требуй от сеньёра перечислить **все замечания одним списком за один заход** — включая мелочи, ниты и потенциальные будущие проблемы. После 3 раундов без `APPROVED` остановись и спроси пользователя: продолжать цикл или зафиксировать оставшиеся замечания как известные ограничения (не растягивай полировку на десятки раундов). +9. **Дифф-ревью и внешнее состояние.** План, чек-лист и учёт замечаний держи во внешнем файле состояния (например, `.dsh/task-plan.md`). Промпт ревью содержит: задачу, путь к файлу состояния, **короткую дельту** «что изменилось с прошлого раза» и `git diff` изменённых файлов. Не пересказывай ревьюеру весь план и всю историю замечаний — файл состояния он прочитает сам (это его контекст, а не наш). +10. **Саморевью до отправки.** Перед первым и каждым повторным ревью прогоняй фактические проверки, которые сеньёр всё равно сделает: поведение функций на реальных данных (например, `Transliterate("photo.png")`, `http.DetectContentType`, `filepath.Ext("x.PNG?v=2")`), чтение сгенерированного кода (pb.gw.go и пр.), арифметику лимитов. «Ревью результата» отправляй как `git diff` + выводы проверок, а не как пересказ плана. ## Шаги @@ -46,12 +49,12 @@ whenToUse: Пользователь просит выполнить задачу ### 3. Ревью плана сеньёром -Запусти субагента с промптом по шаблону **«Ревью плана»** (ниже). Сеньёр возвращает либо `APPROVED`, либо список замечаний. +Сохрани план и критерии в файл состояния (например, `.dsh/task-plan.md`), прогони саморевью (правило 10), затем запусти субагента с промптом по шаблону **«Ревью плана»** (ниже). Сеньёр возвращает либо `APPROVED`, либо список замечаний. ### 4. Цикл правок плана -- Есть замечания → исправь план (и todo-список), отправь на ревью **повторно**: в промпт добавь предыдущие замечания и что именно изменилось. -- Повторяй, пока не получишь `APPROVED`. +- Есть замечания → исправь план в файле состояния (и todo-список), отправь на ревью **повторно**: в промпт добавь только дельту «что изменилось с прошлого раза» (правило 9). +- Повторяй, пока не получишь `APPROVED`; после 3 раундов без `APPROVED` — спроси пользователя (см. «Ограничение итераций»). ### 5. Выполнение @@ -59,11 +62,11 @@ whenToUse: Пользователь просит выполнить задачу ### 6. Ревью результата -Сначала сам проверь результат (прогони проверки из плана), затем отдай его сеньёру по шаблону **«Ревью результата»**. Сеньёр сверяет результат с планом и критериями, проверяет корректность и соблюдение конвенций проекта. +Сначала сам проверь результат (прогони проверки из плана, правило 10), затем отдай его сеньёру по шаблону **«Ревью результата»**: `git diff` изменённых файлов + выводы проверок. Сеньёр сверяет результат с планом (файл состояния) и критериями, проверяет корректность и соблюдение конвенций проекта. ### 7. Цикл правок результата -Правь по замечаниям, повторяй ревью, пока сеньёр не вернёт `APPROVED`. При каждом повторе сообщай сеньёру, что изменилось с прошлого раза. +Правь по замечаниям, повторяй ревью, пока сеньёр не вернёт `APPROVED`. При каждом повторе сообщай сеньёру только дельту — что изменилось с прошлого раза (правило 9). После 3 раундов без `APPROVED` — спроси пользователя. ### 8. Финальный отчёт @@ -71,15 +74,19 @@ whenToUse: Пользователь просит выполнить задачу ## Шаблон: промпт «Ревью плана» +План и критерии — в файле состояния (путь ниже); в промпт включай только задачу, путь к файлу, дельту с прошлого раза (если есть) и diff, если правился код. + ``` Ты — senior developer. Оцени план выполнения задачи. Задача: <текст задачи> -План: <план> -Критерии готовности: <критерии> +План и критерии готовности: <путь к файлу состояния, например .dsh/task-plan.md> (прочитай сам) +Изменения с прошлого раза: <дельту или «первое ревью»> Проверь: полноту (нет ли пропущенных шагов), достижимость, корректность подхода, риски, соответствие конвенциям проекта, отсутствие лишних шагов. +Перечисли ВСЕ замечания одним списком за один заход — включая мелочи, +ниты и потенциальные будущие проблемы; не растягивай на несколько раундов. Ответь СТРОГО одним из двух вариантов: - APPROVED — если замечаний нет; - список замечаний, каждое в формате «<что не так> → <как исправить>». @@ -91,12 +98,14 @@ whenToUse: Пользователь просит выполнить задачу Ты — senior developer. Оцени результат выполнения задачи. Задача: <текст задачи> -План: <план> -Критерии готовности: <критерии> -Результат: <что сделано: файлы, изменения, выводы проверок> +План и критерии готовности: <путь к файлу состояния> (прочитай сам) +Результат: git diff изменённых файлов + выводы проверок (build/vet/test/race) +Изменения с прошлого раза: <дельту или «первое ревью»> Проверь: результат соответствует плану и критериям готовности, код/текст корректен, соблюдены конвенции проекта, нет регрессий. +Перечисли ВСЕ замечания одним списком за один заход — включая мелочи, +ниты и потенциальные будущие проблемы. Ответь СТРОГО одним из двух вариантов: - APPROVED — если замечаний нет; - список замечаний, каждое в формате «<что не так> → <как исправить>». @@ -104,7 +113,7 @@ whenToUse: Пользователь просит выполнить задачу ## Ограничение итераций -Если в одном цикле (план или результат) после **5 раундов** замечания не исчерпались — остановись и спроси пользователя: продолжать цикл или зафиксировать оставшиеся замечания как известные ограничения. +Если в одном цикле (план или результат) после **3 раундов** замечания не исчерпались — остановись и спроси пользователя: продолжать цикл или зафиксировать оставшиеся замечания как известные ограничения. ## Критерии готовности