refactor(skills+agents): host-agnostic prompts, replace raw gh with curl #13

Merged
slaid098 merged 4 commits from refactor/skills-agents/forgejo-first into main 2026-08-07 12:32:41 +03:00
Owner

Что сделано

Issue #6 — host-agnostic refactor skills и agents (PR #1 вырезал GitHub fallback из кода, этот PR — из промптов).

9 skills (frontmatter description + тело):

  • issue/SKILL.md — "Creates GitHub issues" → "Creates issues"; gh label create → curl POST /repos/{repo}/labels; gh issue create/gh pr merge → "raw curl blocked"/"raw bash merge blocked"; {host} убран из memory path (L172).
  • audit/SKILL.md — "GitHub issues" → "issues"; gh issue create → create-issue; "gh недоступен" → "create-issue недоступен".
  • bug-discovery/SKILL.md — gh issue list → pipeline-status оракул или curl GET /issues; "GitHub issue" → "issue".
  • spec/SKILL.md — "GitHub owner" → "git-host owner"; "GitHub issues" → "issues"; gh issue create → create-issue; "gh сам" → "issue-create сам".
  • configure-opencode/SKILL.md — примеры gh pr merge* → curl -sX POST*; gh pr checks* → curl -sX DELETE*.
  • project-template/SKILL.md — frontmatter "GitHub remote" → "git-host remote"; Template GITHUB → Template FORGEJO (полная переработка L224-304: gh repo create/gh api → curl POST/PATCH к Forgejo API, Forgejo branch_protections schema {enable_push,enable_status_check,required_approvals} вместо GitHub Rules API; gh repo view → curl -o /dev/null -w %{http_code} для existence check; gh auth setup-git → git config http.extraheader).
  • release/SKILL.md — "GitHub Release" → "release"; gh release create → curl POST /repos/{repo}/releases.
  • repo-readme/SKILL.md — "GitHub metadata" → "Репозиторий metadata"; gh repo edit → curl PATCH /repos/{repo} + curl PUT /repos/{repo}/topics; "GitHub API"/"GitHub sidebar"/"на GitHub" → "git-host API"/"git-host sidebar"/"на git-host".
  • run-pipeline/SKILL.md — gh pr view M --json headRefName,body,title → pipeline-status({pr_number: M}) оракул; gh run list/view → pipeline-status (web UI для деталей jobs); gh pr checkout M → git fetch origin pull/M/head:pr-M && git checkout pr-M (git-native); {host} убран из memory path (L109,111); raw gh API restrictions → pipeline-status как единственный способ.

3 commands (audit, project-template, spec) — "gh issue create"/"gh repo create"/"gh" → "create-issue"/"repo create via Forgejo API"/"issue-create"; "GitHub remote" → "git-host remote".

2 agents (frontmatter permission.bash + тело):

  • memory-syncer.md — удалены 4 raw gh* frontmatter rules (1 deny + 3 allow); gh pr view N --json body,title → pipeline-status({pr_number: N}) (L44, L119) — расширенный в PR #1 оракул возвращает body, title, issue context.
  • reviewer.md — удалены 17 raw gh* frontmatter rules (16 allow + 1 deny: gh pr diff/checkout/issue/view/review/comment, gh api repos/*/actions/runs|contents|branches|pulls|issues, gh repo clone/view, gh run list/view/run, gh pr merge deny); gh pr view --json headRefName,body,title → pipeline-status (L98); gh run list → pipeline-status (L106); gh pr checks → убран (Forgejo не экспонирует checks-rollup); gh pr view --json author → pipeline-status (author) или curl GET /repos/{repo}/pulls/{N} для fallback (L397); "GitHub PR comment/review" → "PR comment/review".

Tests — tests/test_project_template_skill.py (4 теста-контракта обновлены под Forgejo-first, paired writer↔reader update):

  • test_skill_init_flow_steps — gh repo create → Forgejo API/FORGEJO_URL.
  • test_skill_phase_a_migrated — GitHub Rules API контракты (gh api -f, required_status_checks, non_fast_forward, refs/heads/main, squash_merge_commit_title) → Forgejo branch_protections контракты (allow_squash_merge/allow_merge_commit/allow_rebase/default_delete_branch_after_merge/branch_protections/enable_push/enable_status_check/required_approvals/curl).
  • test_skill_boundary_cases — "GitHub repo уже существует"/"gh repo view" → "repo уже существует"/"curl".
  • test_skill_delegates_not_edits — Template GITHUB → Template FORGEJO.

Почему

PR #1 (tools) вырезал GitHub fallback из кода — gh CLI недоступен в Forgejo-режиме (binary убран). Но 9 skills и 2 agents всё ещё инструктировали агентов вызывать raw gh через bash — что падает без gh binary. 62+ упоминаний GitHub/gh в skills/agents/commands, 0 — Forgejo. Этот PR переписывает промпты на host-agnostic + Forgejo-first инструкции (curl к Forgejo API для операций без tool'а, pipeline-status/create-issue/create-pr/merge-pr/post-review оракулы где есть).

Принцип (из issue #6 контракты): новые tools НЕ создаются (решение пользователя). Для операций без существующего tool'а (label create, release create, repo edit, repo create, branch protection set) — curl к Forgejo REST API в bash-блоке skill'а. Для pr view/run list/issue view — pipeline-status оракул (расширенный в PR #1).

Watch out

  • Template FORGEJO полностью переработан (project-template L224-304) — gh api GitHub Rules API schema → curl Forgejo branch_protections schema. Forgejo enable_push:false = защищён (инвертирован относительно ожиданий). 409 на существующей protection → PATCH вместо POST.
  • Тесты-контракты обновлены paired — test_project_template_skill.py проверял устаревший GitHub-контракт (gh repo create, GitHub Rules API fields). Без обновления тестов skills-правки бы сломали тесты. Paired writer↔reader update в одном PR.
  • Stale {host} почищен (issue #6 критерий D): issue/SKILL.md:172, run-pipeline/SKILL.md:109,111 — {host}/{org}/{repo} → {org}/{repo} (соответствует PR #12 memory path fix).
  • create-pr баг #9 — при создании этого PR использован raw curl workaround (tool не передаёт head field корректно → 422). Issue #9 не закрыт.
  • Описания-запреты "НЕ raw gh pr checkout"/"Запрещено raw gh pr checks" оставлены — это контекст для агента почему НЕ использовать, не инструкция использовать.
  • "GitHub Rules API" / "ADR-005 для GitHub" упоминания оставлены как исторический контекст сравнения ( Forgejo ≠ GitHub) — не инструкции.
  • Untracked draw-image/templates/cover-*.svg и node_modules/ — НЕ коммичены (вне scope issue #6).

Pending

  • PR #3 (issue #5): opencode.json global permission.bash — 24 gh* правила удалить; Dockerfile убрать gh; .env.example удалить GITHUB_TOKEN; AGENTS.md секция про git-host; pyproject.toml/README.md URLs; ADR creation.
  • PR #4 (issue #7): Templates (cookiecutter files) — GitHub → Forgejo.
  • Issue #9: create-pr tool баг (head field 422) — не закрыт.

Closes #6

## Что сделано Issue #6 — host-agnostic refactor skills и agents (PR #1 вырезал GitHub fallback из кода, этот PR — из промптов). **9 skills** (frontmatter description + тело): - `issue/SKILL.md` — "Creates GitHub issues" → "Creates issues"; `gh label create` → `curl POST /repos/{repo}/labels`; `gh issue create`/`gh pr merge` → "raw curl blocked"/"raw bash merge blocked"; `{host}` убран из memory path (L172). - `audit/SKILL.md` — "GitHub issues" → "issues"; `gh issue create` → `create-issue`; "gh недоступен" → "create-issue недоступен". - `bug-discovery/SKILL.md` — `gh issue list` → `pipeline-status` оракул или `curl GET /issues`; "GitHub issue" → "issue". - `spec/SKILL.md` — "GitHub owner" → "git-host owner"; "GitHub issues" → "issues"; `gh issue create` → `create-issue`; "gh сам" → "issue-create сам". - `configure-opencode/SKILL.md` — примеры `gh pr merge*` → `curl -sX POST*`; `gh pr checks*` → `curl -sX DELETE*`. - `project-template/SKILL.md` — frontmatter "GitHub remote" → "git-host remote"; Template GITHUB → Template FORGEJO (полная переработка L224-304: `gh repo create`/`gh api` → `curl POST/PATCH` к Forgejo API, Forgejo `branch_protections` schema `{enable_push,enable_status_check,required_approvals}` вместо GitHub Rules API; `gh repo view` → `curl -o /dev/null -w %{http_code}` для existence check; `gh auth setup-git` → `git config http.extraheader`). - `release/SKILL.md` — "GitHub Release" → "release"; `gh release create` → `curl POST /repos/{repo}/releases`. - `repo-readme/SKILL.md` — "GitHub metadata" → "Репозиторий metadata"; `gh repo edit` → `curl PATCH /repos/{repo}` + `curl PUT /repos/{repo}/topics`; "GitHub API"/"GitHub sidebar"/"на GitHub" → "git-host API"/"git-host sidebar"/"на git-host". - `run-pipeline/SKILL.md` — `gh pr view M --json headRefName,body,title` → `pipeline-status({pr_number: M})` оракул; `gh run list/view` → `pipeline-status` (web UI для деталей jobs); `gh pr checkout M` → `git fetch origin pull/M/head:pr-M && git checkout pr-M` (git-native); `{host}` убран из memory path (L109,111); raw `gh` API restrictions → `pipeline-status` как единственный способ. **3 commands** (audit, project-template, spec) — "gh issue create"/"gh repo create"/"gh" → "create-issue"/"repo create via Forgejo API"/"issue-create"; "GitHub remote" → "git-host remote". **2 agents** (frontmatter permission.bash + тело): - `memory-syncer.md` — удалены 4 raw `gh*` frontmatter rules (1 deny + 3 allow); `gh pr view N --json body,title` → `pipeline-status({pr_number: N})` (L44, L119) — расширенный в PR #1 оракул возвращает body, title, issue context. - `reviewer.md` — удалены 17 raw `gh*` frontmatter rules (16 allow + 1 deny: `gh pr diff/checkout/issue/view/review/comment`, `gh api repos/*/actions/runs|contents|branches|pulls|issues`, `gh repo clone/view`, `gh run list/view/run`, `gh pr merge` deny); `gh pr view --json headRefName,body,title` → `pipeline-status` (L98); `gh run list` → `pipeline-status` (L106); `gh pr checks` → убран (Forgejo не экспонирует checks-rollup); `gh pr view --json author` → `pipeline-status` (author) или `curl GET /repos/{repo}/pulls/{N}` для fallback (L397); "GitHub PR comment/review" → "PR comment/review". **Tests** — `tests/test_project_template_skill.py` (4 теста-контракта обновлены под Forgejo-first, paired writer↔reader update): - `test_skill_init_flow_steps` — `gh repo create` → `Forgejo API`/`FORGEJO_URL`. - `test_skill_phase_a_migrated` — GitHub Rules API контракты (`gh api -f`, `required_status_checks`, `non_fast_forward`, `refs/heads/main`, `squash_merge_commit_title`) → Forgejo branch_protections контракты (`allow_squash_merge`/`allow_merge_commit`/`allow_rebase`/`default_delete_branch_after_merge`/`branch_protections`/`enable_push`/`enable_status_check`/`required_approvals`/`curl`). - `test_skill_boundary_cases` — "GitHub repo уже существует"/"gh repo view" → "repo уже существует"/"curl". - `test_skill_delegates_not_edits` — Template GITHUB → Template FORGEJO. ## Почему PR #1 (tools) вырезал GitHub fallback из кода — `gh` CLI недоступен в Forgejo-режиме (binary убран). Но 9 skills и 2 agents всё ещё инструктировали агентов вызывать raw `gh` через bash — что падает без `gh` binary. 62+ упоминаний GitHub/`gh` в skills/agents/commands, 0 — Forgejo. Этот PR переписывает промпты на host-agnostic + Forgejo-first инструкции (curl к Forgejo API для операций без tool'а, `pipeline-status`/`create-issue`/`create-pr`/`merge-pr`/`post-review` оракулы где есть). Принцип (из issue #6 контракты): новые tools НЕ создаются (решение пользователя). Для операций без существующего tool'а (label create, release create, repo edit, repo create, branch protection set) — `curl` к Forgejo REST API в bash-блоке skill'а. Для `pr view`/`run list`/`issue view` — `pipeline-status` оракул (расширенный в PR #1). ## Watch out - **Template FORGEJO полностью переработан** (project-template L224-304) — `gh api` GitHub Rules API schema → `curl` Forgejo `branch_protections` schema. Forgejo `enable_push:false` = защищён (инвертирован относительно ожиданий). 409 на существующей protection → PATCH вместо POST. - **Тесты-контракты обновлены paired** — `test_project_template_skill.py` проверял устаревший GitHub-контракт (`gh repo create`, GitHub Rules API fields). Без обновления тестов skills-правки бы сломали тесты. Paired writer↔reader update в одном PR. - **Stale `{host}` почищен** (issue #6 критерий D): `issue/SKILL.md:172`, `run-pipeline/SKILL.md:109,111` — `{host}/{org}/{repo}` → `{org}/{repo}` (соответствует PR #12 memory path fix). - **create-pr баг #9** — при создании этого PR использован raw curl workaround (tool не передаёт `head` field корректно → 422). Issue #9 не закрыт. - Описания-запреты "НЕ raw `gh pr checkout`"/"Запрещено raw `gh pr checks`" оставлены — это контекст для агента почему НЕ использовать, не инструкция использовать. - "GitHub Rules API" / "ADR-005 для GitHub" упоминания оставлены как исторический контекст сравнения ( Forgejo ≠ GitHub) — не инструкции. - Untracked `draw-image/templates/cover-*.svg` и `node_modules/` — НЕ коммичены (вне scope issue #6). ## Pending - PR #3 (issue #5): `opencode.json` global `permission.bash` — 24 `gh*` правила удалить; `Dockerfile` убрать `gh`; `.env.example` удалить `GITHUB_TOKEN`; `AGENTS.md` секция про git-host; `pyproject.toml`/`README.md` URLs; ADR creation. - PR #4 (issue #7): Templates (cookiecutter files) — GitHub → Forgejo. - Issue #9: `create-pr` tool баг (head field 422) — не закрыт. Closes #6
refactor(agents): host-agnostic prompts, replace gh with pipeline-status
Some checks failed
CI (always) / bootstrap (pull_request) Successful in 9s
CI / bootstrap (pull_request) Successful in 13s
Permission Security Check / check (pull_request) Successful in 13s
CI / complexity (pull_request) Successful in 34s
CI / typecheck (pull_request) Successful in 34s
CI / lint (pull_request) Failing after 34s
CI / test (3.13) (pull_request) Successful in 1m39s
71a1681adc
Author
Owner

Code Review Summary

Summary

PR #13 успешно делает промпты host-agnostic: github.com полностью вырезан, raw gh заменён на curl к Forgejo API и pipeline-status оракул, {host} cleanup завершён (согласуется с PR #12), Forgejo API endpoints корректны, тесты зелёные (768 passed). Однако найдены 2 критических cross-file несоответствия между промптами и реальным контрактом pipeline-status tool'а + permission set'ом reviewer'а.

Critical (must fix before merge)

  • .opencode/agents/reviewer.md:81,90,382 / .opencode/agents/memory-syncer.md:41,118 / .opencode/skills/run-pipeline/SKILL.md:90,115 [cross-file contract] Промпты утверждают, что pipeline-status({ pr_number: M }) "расширен в PR #1" и возвращает headRefName, body, title, author, CI runs, issue context. Реальность: нативный tool pipeline-status (.opencode/tools/pipeline-status.ts:5-20) вызывает pipeline-status.py и возвращает stdout — форматированный фазовый отчёт (PR #N: <title> + 6 фаз + NEXT: <action>). Tool НЕ возвращает структурированные поля. "PR #1" — forward-reference на planned future PR, которого не существует в репо (нумерация PR начинается с #17 в git log). Если reviewer/memory-syncer следуют этим промптам, они не смогут получить PR body для review/memory-sync → REVIEW и MEMORY phases сломаются.
    Fix: либо (a) реализовать расширение pipeline-status tool'а в этом PR (добавить args fields или отдельный tool pr-info), либо (b) убрать утверждения о возврате body/headRefName/author/issue context и заменить на curl fallback (см. следующий issue), либо (c) явно отметить "PR #1" как planned future work с TODO.

  • .opencode/agents/reviewer.md:383-384 [permission regression] Промпт предписывает reviewer'у curl fallback для получения author: curl -s -H "Authorization: token $FORGEJO_TOKEN" "$FORGEJO_URL/api/v1/repos/<owner>/<repo>/pulls/<N>". Но permission set reviewer.md (lines 6-74) не содержит curl в allow-list. Catch-all "*": deny (line 10) заблокирует curl → fallback недоступен. Это paired update: промпт добавляет curl fallback, но permission set не обновлён.
    Fix: добавить "curl -s*": allow в permission.bash reviewer.md (после catch-all deny, до других allow). Альтернатива: если pipeline-status будет расширен возвращать author (issue выше), curl fallback можно убрать.

Cross-file impact: missing paired update

PR #13 меняет writer (промпты reviewer.md / memory-syncer.md / run-pipeline/SKILL.md) — утверждает, что pipeline-status tool возвращает PR metadata (body, headRefName, author, issue context). pipeline-status.ts (reader/tool definition) зависит от этого:

  • pipeline-status.ts:5-20 — tool принимает только pr_number, возвращает r.stdout.trim() (фазовый отчёт)
  • Промпты теперь ожидают структурированные поля → tool их не возвращает → reviewer/memory-syncer не получат PR body

ТЗ на fix:

  • Что: расширить pipeline-status tool (или добавить новый pr-info tool) возвращать headRefName, body, title, author, issue context — либо убрать эти утверждения из промптов
  • Где: .opencode/tools/pipeline-status.ts (tool definition) + .opencode/scripts/pipeline-status.py (_forgejo_pr_view уже получает PR JSON — нужно экспонировать поля)
  • Контракт: pipeline-status({ pr_number: N }) → { phase, next, pr: { headRefName, body, title, author, issueContext } } ИЛИ промпты используют curl fallback (с paired permission update)
  • Тесты: tests/test_pipeline_status.py — add test for PR metadata fields

Альтернатива (меньше кода): убрать утверждения о возврате body/headRefName/author/issue context из промптов, оставить только "возвращает фазовый статус + NEXT action". Для PR body использовать curl (с paired permission update для reviewer.md).

Warnings (should fix)

  • .opencode/skills/bug-discovery/SKILL.md:10-12 [cross-file contract] Утверждает pipeline-status({ pr_number: N }) "returns issue context" (неверно — см. critical issue выше) + curl fallback для issues list. bug-discovery — skill, исполняется general subagent (permission set наследуется). Менее критично, но та же проблема: pipeline-status не возвращает issue context. Если оставляете curl fallback — убедитесь что general agent имеет curl в allow-list.
    Fix: убрать "returns issue context" из утверждения о pipeline-status, оставить curl как primary способ для duplicate check.

Positives

  • Host-agnostic cleanup полный: github.com вырезан везде, raw gh заменён на curl/pipeline-status (кроме корректных негативных упоминаний "НЕ gh pr checkout")
  • Forgejo API endpoints корректны: /repos/{repo}/labels, /releases, /topics (PUT), /pulls/{N}, /user/repos, /branch_protections, /repos/{repo} (GET/PATCH)
  • {host} cleanup завершён, согласуется с pipeline-status.py:_resolve_memory_base (path repos/{org}/{repo}.md без host) — cross-file consistency ✅
  • Forgejo branch_protections schema (enable_push, enable_status_check, required_approvals) корректна
  • git-native checkout git fetch origin pull/M/head:pr-M && git checkout pr-M корректен для Forgejo
  • Frontmatter cleanup: 17 gh rules удалены из reviewer.md, 4 из memory-syncer.md — permission set остался функциональным
  • Тесты: 768 passed, test_project_template_skill.py обновлён корректно (asserts на Forgejo API fields)
  • Ruff clean на изменённом тесте; mypy/ruff errors в scripts — pre-existing (PR не изменяет .opencode/scripts/)

Verdict: REQUEST_CHANGES

## Code Review Summary ### Summary PR #13 успешно делает промпты host-agnostic: `github.com` полностью вырезан, raw `gh` заменён на `curl` к Forgejo API и `pipeline-status` оракул, `{host}` cleanup завершён (согласуется с PR #12), Forgejo API endpoints корректны, тесты зелёные (768 passed). Однако найдены 2 критических cross-file несоответствия между промптами и реальным контрактом `pipeline-status` tool'а + permission set'ом reviewer'а. ### Critical (must fix before merge) - **.opencode/agents/reviewer.md:81,90,382 / .opencode/agents/memory-syncer.md:41,118 / .opencode/skills/run-pipeline/SKILL.md:90,115** [cross-file contract] Промпты утверждают, что `pipeline-status({ pr_number: M })` "расширен в PR #1" и возвращает `headRefName`, `body`, `title`, `author`, `CI runs`, `issue context`. Реальность: нативный tool `pipeline-status` (`.opencode/tools/pipeline-status.ts:5-20`) вызывает `pipeline-status.py` и возвращает stdout — форматированный фазовый отчёт (`PR #N: <title>` + 6 фаз + `NEXT: <action>`). Tool **НЕ** возвращает структурированные поля. "PR #1" — forward-reference на planned future PR, которого не существует в репо (нумерация PR начинается с #17 в git log). Если reviewer/memory-syncer следуют этим промптам, они не смогут получить PR body для review/memory-sync → REVIEW и MEMORY phases сломаются. Fix: либо (a) реализовать расширение `pipeline-status` tool'а в этом PR (добавить args `fields` или отдельный tool `pr-info`), либо (b) убрать утверждения о возврате body/headRefName/author/issue context и заменить на curl fallback (см. следующий issue), либо (c) явно отметить "PR #1" как planned future work с TODO. - **.opencode/agents/reviewer.md:383-384** [permission regression] Промпт предписывает reviewer'у curl fallback для получения author: `curl -s -H "Authorization: token $FORGEJO_TOKEN" "$FORGEJO_URL/api/v1/repos/<owner>/<repo>/pulls/<N>"`. Но permission set reviewer.md (lines 6-74) **не содержит** `curl` в allow-list. Catch-all `"*": deny` (line 10) заблокирует curl → fallback недоступен. Это paired update: промпт добавляет curl fallback, но permission set не обновлён. Fix: добавить `"curl -s*": allow` в `permission.bash` reviewer.md (после catch-all deny, до других allow). Альтернатива: если `pipeline-status` будет расширен возвращать author (issue выше), curl fallback можно убрать. ## Cross-file impact: missing paired update PR #13 меняет writer (промпты reviewer.md / memory-syncer.md / run-pipeline/SKILL.md) — утверждает, что `pipeline-status` tool возвращает PR metadata (body, headRefName, author, issue context). `pipeline-status.ts` (reader/tool definition) зависит от этого: - `pipeline-status.ts:5-20` — tool принимает только `pr_number`, возвращает `r.stdout.trim()` (фазовый отчёт) - Промпты теперь ожидают структурированные поля → tool их не возвращает → reviewer/memory-syncer не получат PR body ТЗ на fix: - Что: расширить `pipeline-status` tool (или добавить новый `pr-info` tool) возвращать `headRefName`, `body`, `title`, `author`, `issue context` — либо убрать эти утверждения из промптов - Где: `.opencode/tools/pipeline-status.ts` (tool definition) + `.opencode/scripts/pipeline-status.py` (`_forgejo_pr_view` уже получает PR JSON — нужно экспонировать поля) - Контракт: `pipeline-status({ pr_number: N })` → `{ phase, next, pr: { headRefName, body, title, author, issueContext } }` ИЛИ промпты используют curl fallback (с paired permission update) - Тесты: `tests/test_pipeline_status.py` — add test for PR metadata fields Альтернатива (меньше кода): убрать утверждения о возврате body/headRefName/author/issue context из промптов, оставить только "возвращает фазовый статус + NEXT action". Для PR body использовать curl (с paired permission update для reviewer.md). ### Warnings (should fix) - **.opencode/skills/bug-discovery/SKILL.md:10-12** [cross-file contract] Утверждает `pipeline-status({ pr_number: N })` "returns issue context" (неверно — см. critical issue выше) + curl fallback для issues list. bug-discovery — skill, исполняется general subagent (permission set наследуется). Менее критично, но та же проблема: `pipeline-status` не возвращает issue context. Если оставляете curl fallback — убедитесь что general agent имеет `curl` в allow-list. Fix: убрать "returns issue context" из утверждения о pipeline-status, оставить curl как primary способ для duplicate check. ### Positives - Host-agnostic cleanup полный: `github.com` вырезан везде, raw `gh` заменён на curl/pipeline-status (кроме корректных негативных упоминаний "НЕ `gh pr checkout`") - Forgejo API endpoints корректны: `/repos/{repo}/labels`, `/releases`, `/topics` (PUT), `/pulls/{N}`, `/user/repos`, `/branch_protections`, `/repos/{repo}` (GET/PATCH) - `{host}` cleanup завершён, согласуется с `pipeline-status.py:_resolve_memory_base` (path `repos/{org}/{repo}.md` без host) — cross-file consistency ✅ - Forgejo `branch_protections` schema (`enable_push`, `enable_status_check`, `required_approvals`) корректна - git-native checkout `git fetch origin pull/M/head:pr-M && git checkout pr-M` корректен для Forgejo - Frontmatter cleanup: 17 gh rules удалены из reviewer.md, 4 из memory-syncer.md — permission set остался функциональным - Тесты: 768 passed, `test_project_template_skill.py` обновлён корректно (asserts на Forgejo API fields) - Ruff clean на изменённом тесте; mypy/ruff errors в scripts — pre-existing (PR не изменяет `.opencode/scripts/`) ### Verdict: REQUEST_CHANGES
fix(review): correct pipeline-status scope, allow curl for metadata fetch
Some checks failed
CI (always) / bootstrap (pull_request) Successful in 3s
CI / bootstrap (pull_request) Successful in 6s
Permission Security Check / check (pull_request) Successful in 8s
CI / lint (pull_request) Failing after 31s
CI / complexity (pull_request) Successful in 30s
CI / typecheck (pull_request) Successful in 35s
CI / test (3.13) (pull_request) Successful in 1m35s
e3b1272ec6
Author
Owner

Code Review Summary

Повторный review после fix-коммита e3b1272. Оба blocking-замечания из предыдущего review устранены корректно.

Замечание 1 (pipeline-status scope) — ✅ ИСПРАВЛЕНО

Все 7+ мест в reviewer.md, memory-syncer.md, run-pipeline/SKILL.md теперь последовательно разделяют ответственность:

  • pipeline-status → только phase verdict (DONE/NOT_DONE/AMBIGUOUS) + NEXT action
  • curl GET /pulls/N → PR metadata (headRefName, body, title, author)
  • curl GET /issues/N → issue context

Проверенные места: reviewer.md:83-84 (Setup 1), reviewer.md:91-94 (Setup 5), reviewer.md:384-389 (Rule 9), memory-syncer.md:42-46 (Setup 3), memory-syncer.md:121 (Rule 4), run-pipeline:69-71 (Template C), run-pipeline:91-93 (Template D), run-pipeline:116-118 (Template E). Каждое явно отмечает "pipeline-status НЕ возвращает metadata" и направляет к curl.

Замечание 2 (scoped curl allow-rules) — ✅ ИСПРАВЛЕНО

reviewer.md:11-12 и memory-syncer.md:11-12 — добавлены scoped allow-rules:

"curl -s -H \"Authorization: token $FORGEJO_TOKEN\" \"$FORGEJO_URL/api/v1/repos/*/pulls/*\"": allow
"curl -s -H \"Authorization: token $FORGEJO_TOKEN\" \"$FORGEJO_URL/api/v1/repos/*/issues/*\"": allow

Паттерны scoped (не broad curl*): -s silent, auth header, path ограничен /repos/*/pulls/* и /repos/*/issues/*. Catch-all "*": deny сохранён (строка 10 в обоих файлах). Мутации (-X POST/PATCH/DELETE) не матчатся — заблокированы deny. Корректно для read-only агентов.

Regression check — ✅ нет regression

Остальные правки PR #13 не сломаны:

  • host-agnostic: GitHub → git-host в descriptions, gh repo create → curl к Forgejo API — последовательно во всех skills
  • {host} cleanup: memory path {host}/{org}/{repo} → {org}/{repo} — исправлено в run-pipeline Template E и issue/SKILL.md:179
  • frontmatter gh rules удалены: gh pr view*, gh issue*, gh api repos/*, gh run* — удалены из reviewer.md и memory-syncer.md, заменены на curl scoped rules

Suggestions (info, не blocking)

  • run-pipeline/SKILL.md:150 [consistency] Раздел "API Restrictions" всё ещё говорит "Использовать только pipeline-status оракул для CI-статуса и PR-метаданных". Это противоречит исправлениям в Template C (step 1) и Template E (step 1), которые явно говорят "pipeline-status НЕ возвращает PR metadata, используй curl". Fix: "Использовать pipeline-status для CI-статуса (phase verdict + NEXT) и curl для PR-метаданных".

  • bug-discovery/SKILL.md:10-12 [consistency] Шаг 1 утверждает pipeline-status({ pr_number: N }) "(returns issue context)" — неверно: pipeline-status не принимает issue context и возвращает phase verdict, не issue metadata. Противоречит исправлениям в reviewer/memory-syncer. Fix: убрать pipeline-status из шага 1, оставить только curl .../issues?state=open&type=issues для duplicate check.

Оба замечания — documentation inconsistencies в описательных разделах. Templates (C, E) и Setup шаги правильно направляют агента к curl, так что функциональность не нарушена. Рекомендую исправить в follow-up для консистентности.

Verdict: APPROVE

## Code Review Summary Повторный review после fix-коммита `e3b1272`. Оба blocking-замечания из предыдущего review устранены корректно. ### Замечание 1 (pipeline-status scope) — ✅ ИСПРАВЛЕНО Все 7+ мест в `reviewer.md`, `memory-syncer.md`, `run-pipeline/SKILL.md` теперь последовательно разделяют ответственность: - `pipeline-status` → только phase verdict (DONE/NOT_DONE/AMBIGUOUS) + NEXT action - `curl GET /pulls/N` → PR metadata (headRefName, body, title, author) - `curl GET /issues/N` → issue context Проверенные места: `reviewer.md:83-84` (Setup 1), `reviewer.md:91-94` (Setup 5), `reviewer.md:384-389` (Rule 9), `memory-syncer.md:42-46` (Setup 3), `memory-syncer.md:121` (Rule 4), `run-pipeline:69-71` (Template C), `run-pipeline:91-93` (Template D), `run-pipeline:116-118` (Template E). Каждое явно отмечает "pipeline-status НЕ возвращает metadata" и направляет к curl. ### Замечание 2 (scoped curl allow-rules) — ✅ ИСПРАВЛЕНО `reviewer.md:11-12` и `memory-syncer.md:11-12` — добавлены scoped allow-rules: ``` "curl -s -H \"Authorization: token $FORGEJO_TOKEN\" \"$FORGEJO_URL/api/v1/repos/*/pulls/*\"": allow "curl -s -H \"Authorization: token $FORGEJO_TOKEN\" \"$FORGEJO_URL/api/v1/repos/*/issues/*\"": allow ``` Паттерны scoped (не broad `curl*`): `-s` silent, auth header, path ограничен `/repos/*/pulls/*` и `/repos/*/issues/*`. Catch-all `"*": deny` сохранён (строка 10 в обоих файлах). Мутации (`-X POST/PATCH/DELETE`) не матчатся — заблокированы deny. Корректно для read-only агентов. ### Regression check — ✅ нет regression Остальные правки PR #13 не сломаны: - host-agnostic: `GitHub` → `git-host` в descriptions, `gh repo create` → `curl` к Forgejo API — последовательно во всех skills - `{host}` cleanup: memory path `{host}/{org}/{repo}` → `{org}/{repo}` — исправлено в `run-pipeline` Template E и `issue/SKILL.md:179` - frontmatter gh rules удалены: `gh pr view*`, `gh issue*`, `gh api repos/*`, `gh run*` — удалены из reviewer.md и memory-syncer.md, заменены на curl scoped rules ### Suggestions (info, не blocking) - **run-pipeline/SKILL.md:150** [consistency] Раздел "API Restrictions" всё ещё говорит "Использовать только `pipeline-status` оракул для CI-статуса **и PR-метаданных**". Это противоречит исправлениям в Template C (step 1) и Template E (step 1), которые явно говорят "pipeline-status НЕ возвращает PR metadata, используй curl". Fix: "Использовать `pipeline-status` для CI-статуса (phase verdict + NEXT) и `curl` для PR-метаданных". - **bug-discovery/SKILL.md:10-12** [consistency] Шаг 1 утверждает `pipeline-status({ pr_number: N })` "(returns issue context)" — неверно: pipeline-status не принимает issue context и возвращает phase verdict, не issue metadata. Противоречит исправлениям в reviewer/memory-syncer. Fix: убрать pipeline-status из шага 1, оставить только `curl .../issues?state=open&type=issues` для duplicate check. Оба замечания — documentation inconsistencies в описательных разделах. Templates (C, E) и Setup шаги правильно направляют агента к curl, так что функциональность не нарушена. Рекомендую исправить в follow-up для консистентности. ### Verdict: APPROVE
fix(ci): reformat test_project_template_skill for ruff format check
All checks were successful
CI (always) / bootstrap (pull_request) Successful in 5s
CI / bootstrap (pull_request) Successful in 9s
Permission Security Check / check (pull_request) Successful in 11s
CI / lint (pull_request) Successful in 36s
CI / typecheck (pull_request) Successful in 37s
CI / complexity (pull_request) Successful in 37s
CI / test (3.13) (pull_request) Successful in 1m44s
60ed829375
slaid098 deleted branch refactor/skills-agents/forgejo-first 2026-08-07 12:32:41 +03:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
slaid098/opencode-config!13
No description provided.