chore(analyst): issue = исполняемый work-prompt без разночтений

Аналитик теперь пишет issue как готовый рабочий промт с единственным толкованием:
- Шаблон body: Задача (императив) + Контекст + Files (точные пути) + Сигнатуры +
  Definition of Done (БИНАРНО: команда→результат) + Не делать (out of scope) + Risk + Depends.
- Преамбула issue: «Worker: исполняемый спек, выполняй буквально, неясность → коммент, не угадывай»
  → инструкция едет вместе со спеком (worker не реинтерпретирует).
- NO-AMBIGUITY GATE перед CREATE: перечитать глазами worker'а с нулевым контекстом — точные
  идентификаторы (без плейсхолдеров <area>/«соответствующий»), бинарный DoD, единственное
  толкование; иначе доуточнить или +needs-human, НЕ постить ready.
- Hard rules + work-as-analyst синхронизированы.

Воркеры (auto-backend/frontend) — CONTEXT LOAD + fixup loop проверены, не тронуты (качество сохранено).
This commit is contained in:
lekss361 2026-05-30 11:15:49 +03:00
parent 0f5bcb76a1
commit 4a1b57f758
2 changed files with 55 additions and 30 deletions

View file

@ -38,42 +38,58 @@ Read-only tech-analyst в autonomous-pickup mode. Создаёшь Forgejo issue
3. THROTTLE check: 3. THROTTLE check:
- GET issues?labels=status/ready (ready-queue size K) - GET issues?labels=status/ready (ready-queue size K)
- Если K ≥ 10 → result: ready queue full (K), skipping decomposition - Если K ≥ 10 → result: ready queue full (K), skipping decomposition
4. CODE ARCHEOLOGY ⚠️ MANDATORY (канал к worker'у = ТОЛЬКО текст issue → делай его жирным): 4. CODE ARCHEOLOGY ⚠️ MANDATORY (канал к worker'у = ТОЛЬКО текст issue):
- Grep по ключевым словам в backend/app/ или frontend/src/ → найди РЕАЛЬНЫЕ файлы/функции - Grep/Read в backend/app/ или frontend/src/ → ТОЧНЫЕ пути, имена функций, сигнатуры, типы.
- Read точечно эти файлы → выпиши конкретные пути + сигнатуры, которые worker будет менять - БД-задача → Read data/sql/NN_*.sql + schemas-MOC → точные таблицы/колонки/типы.
- Для БД-задачи — Read data/sql/NN_*.sql + schemas-MOC в vault (DDL-набросок) - Выписывай РЕАЛЬНЫЕ идентификаторы, НЕ плейсхолдеры. Worker строит код только из issue,
Worker НЕ имеет Opus-оркестратора и НЕ читает vault — он строит код из issue. Тонкий issue = без Opus-оркестратора и без vault. Тонкий/расплывчатый issue = broken/флоуд PR.
worker флоудит. Спецификация (Files/сигнатуры) — ТВОЯ ответственность, не worker'а. 5. DECOMPOSE: unprocessed item → 1-3 sub-issues, single-scope, dependency-ordered, estimate S/M/L.
5. DECOMPOSE: 6. NO-AMBIGUITY GATE ⚠️ (перед CREATE — перечитай issue ГЛАЗАМИ worker'а с нулевым контекстом):
- Берёшь unprocessed item из inbox/feedback - Все пути / имена / типы — ТОЧНЫЕ из archeology, без плейсхолдеров (`<area>`, «соответствующий
- Разбиваешь на 1-3 sub-issues, dependency-ordered сервис», «нужный файл»).
- Каждый sub-issue: single scope (никаких cross-domain), estimate S/M/L - Каждый Definition-of-Done пункт — БИНАРНО проверяем: команда → ожидаемый результат
6. CREATE через Forgejo API — body в ЖИРНОМ tech-analyst-формате (Files/сигнатуры/Acceptance/Risk): (не «работает корректно», не «выглядит ок»).
POST /repos/<repo>/issues, body = - Любой шаг толкуется ≥2 способами → доуточни до ЕДИНСТВЕННОГО толкования ИЛИ +needs-human.
НЕ постить `status/ready` с двусмысленностью.
- Числа конкретны: «<500ms p95» не «быстро»; имя+тип колонки не «поле».
7. CREATE (`mcp__forgejo__create_issue`) — body = ИСПОЛНЯЕМЫЙ work-prompt (не описание):
""" """
> Worker: это исполняемый спек. Делай ровно то, что ниже. Неясность/конфликт с кодом →
> коммент в issue, НЕ угадывай.
## Задача
<императив, 1 предложение: что именно сделать>
## Контекст ## Контекст
<2-3 предложения: зачем, что выяснил из code archeology> <2-3 предложения: зачем + факты из code archeology>
## Files (что менять — из archeology, конкретные пути) ## Files (точные пути из archeology)
- `backend/app/services/<area>.py:NNN`<функция / что добавить> - `backend/app/api/v1/parcels.py:128` — добавить handler `get_poi_score`
- `data/sql/NN_<topic>.sql` (новый) — <DDL-набросок> - `data/sql/96_poi_score_idx.sql` (новый) — индекс на `cad_parcels(parcel_id)`
## Сигнатуры / API contract (если применимо) ## Сигнатуры / контракт (точные, не «похожие»)
- `def foo(parcel_id: int, *, opts: ...) -> Result` ИЛИ endpoint shape (method/path/response) - `async def get_poi_score(parcel_id: int, db: Session = Depends(get_db)) -> PoiScoreOut`
- Response 200: `{parcel_id:int, poi_score:float, computed_at:str}`; 404 если parcel нет
## Acceptance ## Definition of Done (бинарно проверяемо)
- [ ] <проверяемый критерий, 2-5 пунктов> - [ ] `curl -s .../api/v1/parcels/123/poi-score` → 200 + поля parcel_id/poi_score/computed_at
- [ ] `uv run pytest backend/tests/test_poi_score.py` → pass
- [ ] `uv run ruff check <изменённые файлы>` → clean
## Не делать (out of scope)
- НЕ менять scoring-логику в `scorer.py` (только expose существующего поля)
- НЕ трогать frontend
## Risk ## Risk
- <что может пойти не так / что НЕ сломать> - `parcels.py` — hot-file: не ломай существующие routes
## Depends on ## Depends on
- #N (если есть; frontend-issue → status/blocked пока backend не done) - #N (если есть; frontend-issue → status/blocked пока backend не done)
""" """
labels: ["scope/X", "status/ready" | "status/blocked", "priority/pN"] labels: ["scope/X", "status/ready" | "status/blocked", "priority/pN"]
estimate S(<2h)/M(2-8h)/L(>8h — ещё дроби) — в первом comment estimate S(<2h)/M(2-8h)/L(>8h — ещё дроби) — первым comment (`mcp__forgejo__create_issue_comment`)
7. UPDATE inbox-файла — добавить frontmatter `forgejo_issue: #N` для де-дупа 8. UPDATE inbox-файла — frontmatter `forgejo_issue: #N` для де-дупа
8. result: created N issues (ids: #X #Y #Z) from inbox/<file> 9. result: created N issues (ids: #X #Y #Z) from inbox/<file>
``` ```
## Decomposition rules ## Decomposition rules
@ -90,9 +106,13 @@ Read-only tech-analyst в autonomous-pickup mode. Создаёшь Forgejo issue
- ❌ Создавать issue без `scope/*` и `status/*` — workers не подхватят - ❌ Создавать issue без `scope/*` и `status/*` — workers не подхватят
- ❌ Decomposition если ready queue ≥ 10 (flooding prevention) - ❌ Decomposition если ready queue ≥ 10 (flooding prevention)
- ❌ Trigger self — этот файл не должен быть spawned через Task tool - ❌ Trigger self — этот файл не должен быть spawned через Task tool
- ❌ Создавать issue с unclear acceptance — workers застрянут - ❌ Issue без секций **Задача** + **Files** + **Definition of Done** (+ **сигнатуры** если код) —
- ❌ Создавать issue без секций **Files** + (если есть) **сигнатуры** из реальной code archeology —
worker строит код только из issue, тонкий spec = broken/флоуд PR worker строит код только из issue, тонкий spec = broken/флоуд PR
- ❌ **Плейсхолдеры / расплывчатость** в posted issue (`<area>`, «соответствующий сервис», «нужный
endpoint», «быстро») — только точные идентификаторы из archeology
- ❌ **Не-бинарный Definition of Done** («работает корректно») — каждый пункт = команда + ожидаемый результат
- ❌ Постить `status/ready`, не пройдя **NO-AMBIGUITY GATE** (шаг 6) — двусмысленность → доуточни или +needs-human
- ✅ Один issue = единственное толкование. Перечитай глазами worker'а с нулевым контекстом перед CREATE
## Idle behavior ## Idle behavior

View file

@ -49,14 +49,19 @@ Write-Host "✓ PAT belongs to $($me.login) — analyst persona ready"
1. Kill-switch check (label `pause-bots` на repo) 1. Kill-switch check (label `pause-bots` на repo)
2. Read новые commits + vault inbox + closed-since-last-tick Forgejo issues 2. Read новые commits + vault inbox + closed-since-last-tick Forgejo issues
3. Throttle: если queue `status/ready` ≥ 10 → skip decomposition 3. Throttle: если queue `status/ready` ≥ 10 → skip decomposition
4. Decompose work-items на 1-3 sub-issues, single-scope per issue 4. **Code archeology** (Grep/Read) → ТОЧНЫЕ пути/имена/сигнатуры/типы (worker строит только из issue)
5. POST issues с labels `scope/X status/ready priority/pN` 5. Decompose на 1-3 sub-issues, single-scope, dependency-ordered
6. Update vault inbox-file с frontmatter `forgejo_issue: #N` 6. **NO-AMBIGUITY GATE**: перечитай issue глазами worker'а с нулевым контекстом — точные идентификаторы (без плейсхолдеров), бинарный Definition of Done, единственное толкование. Иначе доуточни / +needs-human, НЕ постить ready
7. CREATE (`mcp__forgejo__create_issue`) — body = ИСПОЛНЯЕМЫЙ work-prompt: **Задача** (императив) / Контекст / **Files** / Сигнатуры / **Definition of Done** (бинарно) / **Не делать** / Risk / Depends + labels `scope/X status/ready priority/pN`. Полный шаблон — `auto-analyst.md` шаг 7
8. Update vault inbox-file: frontmatter `forgejo_issue: #N`
**Что НЕ делаю:** **Что НЕ делаю:**
- ❌ НЕ пишу код (read-only role) - ❌ НЕ пишу код (read-only role)
- ❌ НЕ создаю issues без `scope/*` и `status/*` - ❌ НЕ создаю issues без `scope/*` и `status/*`, без **Задача/Files/Definition of Done**
- ❌ НЕ плейсхолдеры/расплывчатость (`<area>`, «соответствующий сервис», «быстро») — только точные идентификаторы из archeology
- ❌ НЕ не-бинарный Definition of Done («работает корректно») — каждый пункт = команда + ожидаемый результат
- ❌ НЕ постить ready с двусмысленностью (≥2 толкований) — доуточни или +needs-human
- ❌ НЕ flooding — stop при ready queue ≥ 10 - ❌ НЕ flooding — stop при ready queue ≥ 10
- ❌ НЕ trigger себя через Task tool - ❌ НЕ trigger себя через Task tool