gendesign/.claude/agents/_autonomous_pickup.md
lekss361 89303c9769
Some checks failed
CI / backend (pull_request) Failing after 48s
CI / frontend (pull_request) Successful in 1m39s
feat(claude): auto-* agent stubs для autonomous multi-window workflow
DRAFT-файлы для autonomous /loop окон (5 ролей: analyst/backend/frontend/
code-reviewer/qa-tester). НЕ для invoke через Task tool — только как
--append-system-prompt для standalone Claude Code windows с /loop.

Все файлы помечены status:draft. Не активны до сборки .claude/commands/
work-as-* wrappers + Forgejo labels + bot-PATs (см. runbook
multi_agent_autonomous_workflow.md в vault).

Также fix .gitignore: .claude/ → .claude/* чтобы whitelist'ы
!.claude/agents/** работали (git не allow re-include children of ignored
directory).

Refs: runbooks/multi_agent_autonomous_workflow.md (vault)
2026-05-27 22:57:16 +03:00

115 lines
4.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
name: _autonomous_pickup
description: "[SHARED SNIPPET — do not invoke directly] Forgejo queue pickup logic, импортируется во все auto-*.md агенты. Содержит claim/state-transition contract."
status: draft
created_at: 2026-05-27
---
# Autonomous queue pickup — shared contract
> **NOT a standalone agent.** Этот файл — общая инструкция, которую копи-пастят
> внутрь каждого `auto-*.md`. Содержит claim/lifecycle/kill-switch логику.
## Forgejo API endpoints (на основе bot-PAT в окружении)
```bash
# Базовый URL и auth — приходят через env vars при запуске окна:
# FORGEJO_BASE_URL=https://git.gendsgn.ru/api/v1
# FORGEJO_PAT=<your bot's PAT>
# FORGEJO_REPO=lekss361/gendesign
curl_forgejo() {
curl -sS -H "Authorization: token $FORGEJO_PAT" \
-H "Content-Type: application/json" \
"$FORGEJO_BASE_URL/$1" "${@:2}"
}
```
## Kill-switch check (выполняй ПЕРВЫМ делом в каждом /loop tick)
```bash
# Проверка через meta-issue с label "pause-bots"
if curl_forgejo "repos/$FORGEJO_REPO/issues?labels=pause-bots&state=open&limit=1" \
| jq -e 'length > 0' > /dev/null; then
echo "result: paused (pause-bots active)"
exit 0 # /loop спит до следующего тика
fi
```
## Pickup query — по scope
```bash
SCOPE="backend" # ∈ {backend, frontend, db, qa, devops}
NEXT=$(curl_forgejo \
"repos/$FORGEJO_REPO/issues?state=open&labels=scope/$SCOPE,status/ready&assigned_to=none&sort=newest&limit=1" \
| jq -r '.[0] | if . then [.number, .title] | @tsv else "" end')
if [[ -z "$NEXT" ]]; then
echo "result: idle, no work for scope/$SCOPE"
exit 0
fi
```
## Claim — atomic-ish через label transition
```bash
ISSUE=$(echo "$NEXT" | cut -f1)
# 1. Assign self
curl_forgejo "repos/$FORGEJO_REPO/issues/$ISSUE" -X PATCH \
-d "{\"assignees\": [\"$BOT_USERNAME\"]}"
# 2. Transition ready → wip
curl_forgejo "repos/$FORGEJO_REPO/issues/$ISSUE/labels" -X POST \
-d '{"labels": ["status/wip"]}'
curl_forgejo "repos/$FORGEJO_REPO/issues/$ISSUE/labels/status/ready" -X DELETE
# 3. Verify claim не перехвачен
ASSIGNEE=$(curl_forgejo "repos/$FORGEJO_REPO/issues/$ISSUE" | jq -r '.assignees[0].login // ""')
if [[ "$ASSIGNEE" != "$BOT_USERNAME" ]]; then
echo "result: lost race for #$ISSUE (claimed by $ASSIGNEE)"
exit 0
fi
```
## State transitions reference
| От → К | Кто переключает | Условие |
|---|---|---|
| (new) → `status/ready` | auto-analyst | issue декомпозирован, deps удовлетворены |
| `status/ready``status/wip` | auto-backend / auto-frontend | claim успешный |
| `status/wip``status/review` | worker | PR открыт |
| `status/review``status/qa` | auto-code-reviewer | APPROVE + merge |
| `status/review``status/blocked` | auto-code-reviewer | BLOCK/FIX verdict |
| `status/qa``status/done` | auto-qa-tester | smoke OK, issue closed |
| `status/qa``status/blocked` | auto-qa-tester | smoke FAIL |
| `status/blocked``status/ready` | **only human** | manual unblock |
| любой + `pause-bots` присутствует | (никто не работает) | kill-switch |
## Stale-claim cleanup (cron на VPS — отдельная задача)
```bash
# Каждые 30 минут — освобождать issues застрявшие в wip >4h
curl_forgejo "repos/$FORGEJO_REPO/issues?labels=status/wip&state=open" \
| jq -r '.[] | select(.updated_at < (now - 4*3600 | todate)) | .number' \
| while read i; do
curl_forgejo "repos/$FORGEJO_REPO/issues/$i" -X PATCH -d '{"assignees": []}'
curl_forgejo "repos/$FORGEJO_REPO/issues/$i/labels" -X POST -d '{"labels":["status/ready"]}'
curl_forgejo "repos/$FORGEJO_REPO/issues/$i/labels/status/wip" -X DELETE
done
```
## Self-throttle rules
1. **3 итерации подряд idle**`sleep = min(current * 1.5, 60m)`
2. **3 итерации подряд success**`sleep = max(current * 0.8, 5m)`
3. **24h ничего не закрыл** → result: idle 24h, эскалация (label `needs-human`)
## Error escalation
| Ошибка | Действие |
|---|---|
| HTTP 401/403 от Forgejo | PAT истёк / отозван → result: AUTH_ERROR, остановка окна |
| HTTP 500 от Forgejo | result: forgejo down, sleep 30m |
| Subagent error 3× на одной issue | +status/blocked +needs-human, отпустить assignee, next issue |