refactor(config): remove gh from Dockerfile, clean env.example, opencode.json permissions, ADRs #7

Closed
opened 2026-08-07 09:45:43 +03:00 by slaid098 · 0 comments
Owner

Контекст

PR #1 (tools) и PR #2 (skills) вырезали GitHub-fallback из кода и промптов. Этот PR завершает адаптацию: Dockerfile (убрать gh CLI), .env.example (удалить GITHUB_TOKEN), opencode.json (удалить 24 gh* permission rules), AGENTS.md (секция про git-host), pyproject.toml/README.md (URLs), и создание ADRs для документирования решения.

Задача

  1. Dockerfile (62 строки):

    • Удалить gh CLI установку (L29-35: cli.github.com/packages apt source + gh package)
    • Удалить git config --system credential.helper '!gh auth git-credential' (L39)
    • cloudflared download URL (L37): https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 → альтернативный CDN (Cloudflare有自己的 CDN: https://pkg.cloudflareclient.com/cloudflared/releases/latest/cloudflared-linux-amd64 или оставить github.com — cloudflared releases только там; решение: оставить, это не наш код, пометить комментарием что downloads с github.com для cloudflared, не для наших репо)
    • Проверить: после удаления gh — memory-doctor.ts (L38, rg --version), memory-search.ts (L120, rg), commit.ts (git) — не зависят от gh, OK
  2. .env.example (51 строка):

    • Удалить секцию # GitHub + GITHUB_TOKEN=your-github-token-here (L18-19)
    • OPENCODE_MEMORY_REMOTE (L50): https://github.com/your-username/your-opencode-memory.git → https://git.slaid098.dev/slaid098/opencode-memory.git (Forgejo URL)
    • Оставить # Forgejo (self-hosted) секцию (L21-23) с FORGEJO_URL/FORGEJO_TOKEN — это primary
  3. opencode.json permission.bash — удалить 24 gh* правила:

    • L206-219 (14 allow правил): gh pr create*, gh pr merge*, gh pr list*, gh pr status*, gh run*, gh issue*, gh pr diff*, gh pr view*, gh pr comment*, gh pr review*, gh api repos/*/actions/runs*, gh api repos/*/issues*, gh run list*, gh run view*
    • L249 (gh repo delete *: deny), L250 (gh pr close *: ask)
    • L329-337 (8 deny правил): gh pr create *: deny, gh pr merge *: deny, gh issue create *: deny, gh api * -X DELETE *: deny, gh api -X DELETE *: deny, gh api * --method DELETE *: deny, gh api * --method delete *: deny, gh repo transfer *: deny
    • После удаления проверить: конфликт правил L206 allow vs L329 deny — resolved (оба удалены)
    • Добавить safety net правило: "curl * -X DELETE *FORGEJO_URL*": "deny" (если будет прямой curl в skills — запретить delete операции)
    • Оставить permission.read секцию (L165-173) без изменений (нейтральна)
  4. AGENTS.md — добавить секцию про git-host после ## Pipeline:

    ## Git Host
    
    Primary: Forgejo (`git.slaid098.dev`). GitHub мёртв (аккаунт удалён).
    - Все tools/scripts ходят через `fetch`/`urllib` к Forgejo REST API (`$FORGEJO_URL/api/v1`), НЕ через `gh` CLI
    - `gh` CLI НЕ установлен в Docker образе (PR #3) — raw `gh` в bash НЕ работает
    - Для операций без tool'а (label create, release create, repo edit, repo create, branch protection) — `curl` к Forgejo API в bash-блоке
    - Описания в skills/agents — host-agnostic ("issue", не "GitHub issue"/"Forgejo issue") — задел на будущие зеркала
    - Env vars: `FORGEJO_URL`, `FORGEJO_TOKEN` (в `.env`, пробрасываются через docker-compose)
    - `GITHUB_TOKEN` удалён из `.env.example` — больше не нужен
    
  5. pyproject.toml (L48-50):

    • Homepage = "https://github.com/slaid098/opencode-config" → https://git.slaid098.dev/slaid098/opencode-config
    • Repository = "https://github.com/slaid098/opencode-config" → https://git.slaid098.dev/slaid098/opencode-config
    • Issues = "https://github.com/slaid098/opencode-config/issues" → https://git.slaid098.dev/slaid098/opencode-config/issues
  6. README.md (L46, L85):

    • git clone https://github.com/slaid098/opencode-config.git → git clone https://git.slaid098.dev/slaid098/opencode-config.git (2 места: Quick Start EN + RU)
    • L39 "agent creates GitHub issue" → "agent creates issue"
    • L78 "агент сам создаёт GitHub issue" → "агент сам создаёт issue"
  7. Создать ADRs:

    • docs/decisions/092-forgejo-dispatch.md — документировать существующий Forgejo dispatch (env-presence fallback в _shared.ts + 3 oracle-скриптах, реализованный до этого ADR). Ссылается на PR #1.
    • docs/decisions/093-forgejo-first.md — стратегия перехода: GitHub мёртв → Forgejo primary, gh CLI убран, fallback вырезан. Ссылается на PR #1, #2, #3.
    • docs/decisions/094-host-agnostic-docs.md — описания skills/agents/tools host-agnostic ("issue", не "GitHub issue") — задел на будущие зеркала (GitLab/Codeberg). Ссылается на PR #2.
    • docs/decisions/095-curl-in-skills-where-no-tool.md — для операций без tool'а (label/release/repo create/edit) используем curl к Forgejo API в bash-блоке skill'а, НЕ создаём новые tools (решение пользователя: tools только где нужен детерминированный формат). Ссылается на PR #2.
  8. Пометить устаревшие ADRs:

    • docs/decisions/022-pr-53-git-insteadof.md — добавить в начало > **STATUS: SUPERSEDED** — setup-memory.sh удалён, GitHub-специфика, миграция на Forgejo (ADR-093).
    • docs/decisions/005-pr-25-reviewer-echo-bypass.md — > **STATUS: SUPERSEDED** — GitHub fine-grained PAT 403, Forgejo не имеет GraphQL Checks API (ADR-093).
    • docs/decisions/023-pr-55-parse-remote-url.md — > **STATUS: SUPERSEDED** — GitHub PAT в URL, Forgejo использует token-in-URL напрямую (ADR-093).

Контракты

  • Dockerfile: после правки docker build должен собираться без gh — проверить rg "gh" Dockerfile → 0
  • .env.example: rg "GITHUB_TOKEN" .env.example → 0; rg "github.com" .env.example → 0 (кроме cloudflared если оставили)
  • opencode.json: rg "gh " .opencode/opencode.json → 0 (в permission.bash секции)
  • AGENTS.md: новая секция ## Git Host после ## Pipeline
  • pyproject.toml: rg "github.com" pyproject.toml → 0
  • README.md: rg "github.com" README.md → 0
  • ADRs: 4 новых (092-095) + 3 помеченных superseded (022, 005, 023)

Инварианты

  • Dockerfile должен собираться (docker build . не падает) — это критично, образ пересобирается при docker-compose restart
  • opencode.json после удаления 24 gh* правил — остальная permission.bash секция НЕ сломана (valid JSON)
  • cloudflared download URL — оставить github.com (Cloudflare публикует releases только там), пометить комментарием "downloads cloudflared binary, not our code"
  • .env.example — template для пользователей, не наш .env (наш .env не трогаем)
  • ADR numbering: 092-095 (последний 091, без пропусков)
  • Устаревшие ADRs: пометить в начале файла, НЕ удалять (история)

Граничные случаи

  • Dockerfile без gh — если какой-то tool всё ещё вызывает spawnSync("gh") (не вырезан в PR #1) → runtime ошибка. PR #1 должен быть смержен ДО этого PR.
  • opencode.json конфликт правил L206 allow vs L329 deny — после удаления обоих конфликта нет
  • opencode.json после удаления — если остался "gh repo delete *": "deny" (L249) — тоже удалить (это gh* rule)
  • .env.example OPENCODE_MEMORY_REMOTE — если пользователь уже скопировал .env.example в .env с GitHub URL, наш .env не меняется (только template)
  • cloudflared — если Cloudflare уберёт releases с github.com → tunnel skill сломается, но это не наша проблема (Cloudflare CDN)
  • AGENTS.md новая секция — проверить что не нарушает existing структуру заголовков

Влияние на связанные компоненты

  • PR #1 (tools) — зависимость: gh spawnSync вырезан из кода ДО удаления gh из Dockerfile (иначе runtime ошибка)
  • PR #2 (skills) — зависимость: raw gh инструкции удалены из skills ДО удаления gh* permission rules (иначе skills инструктируют вызвать запрещённое)
  • docker-compose.yml — проверь environment: секцию, нет ли GITHUB_TOKEN проброса (по аудиту нет, только env_file: .env)
  • Dockerfile — memory-doctor.ts (L38 rg --version), memory-search.ts (L120 rg), commit.ts (git) — не зависят от gh, OK
  • check-permissions.py (L14-17, 19-28, 31-34, 59-61) — DANGEROUS_PATTERNS содержат gh * паттерны. После удаления gh* правил из opencode.json — паттерны в check-permissions.py становятся неактуальны. Обновить: удалить gh * паттерны или пометить как deprecated.
  • permission.bash в agent frontmatter (memory-syncer L19/L31-33, reviewer L33-55/L69) — удалены в PR #2, этот PR не трогает agent files
  • pre-commit-config.yaml (L2, L9) — repo: https://github.com/astral-sh/ruff-pre-commit, repo: https://github.com/pre-commit/mirrors-mypy — оставить (pre-commit hooks тянутся с github.com, это не наш код, работает через git clone)

Вне scope

  • check-permissions.py DANGEROUS_PATTERNS — обновить (удалить gh * паттерны), но это в этом PR (см. Влияние)
  • pre-commit-config.yaml URLs — оставить (не наш код)
  • Templates (cookiecutter) — PR #4
  • Витрина slaid098-dev — отдельный репо
  • Настройка act_runner — инфра

Критерии приемки

  • docker build . succeeds without gh installed (проверить docker build -t opencode-config-test . 2>&1 | tail -20)
  • rg "gh " Dockerfile → 0 совпадений
  • rg "GITHUB_TOKEN" .env.example → 0 совпадений
  • rg "github.com" .env.example → 0 (или только cloudflared с комментарием)
  • rg "gh " .opencode/opencode.json → 0 в permission.bash секции
  • opencode.json valid JSON после правки (python3 -c "import json; json.load(open('.opencode/opencode.json'))")
  • AGENTS.md содержит секцию ## Git Host после ## Pipeline
  • rg "github.com" pyproject.toml → 0
  • rg "github.com" README.md → 0
  • docs/decisions/092-forgejo-dispatch.md exists
  • docs/decisions/093-forgejo-first.md exists
  • docs/decisions/094-host-agnostic-docs.md exists
  • docs/decisions/095-curl-in-skills-where-no-tool.md exists
  • docs/decisions/022-pr-53-git-insteadof.md содержит SUPERSEDED в начале
  • docs/decisions/005-pr-25-reviewer-echo-bypass.md содержит SUPERSEDED в начале
  • docs/decisions/023-pr-55-parse-remote-url.md содержит SUPERSEDED в начале
  • check-permissions.py — gh * паттерны удалены или помечены deprecated
  • Smoke-test: docker-compose restart (после merge) — opencode поднимается без gh, tools работают
## Контекст PR #1 (tools) и PR #2 (skills) вырезали GitHub-fallback из кода и промптов. Этот PR завершает адаптацию: Dockerfile (убрать `gh` CLI), `.env.example` (удалить `GITHUB_TOKEN`), `opencode.json` (удалить 24 `gh*` permission rules), `AGENTS.md` (секция про git-host), `pyproject.toml`/`README.md` (URLs), и создание ADRs для документирования решения. ## Задача 1. **`Dockerfile`** (62 строки): - Удалить `gh` CLI установку (L29-35: `cli.github.com/packages` apt source + `gh` package) - Удалить `git config --system credential.helper '!gh auth git-credential'` (L39) - `cloudflared` download URL (L37): `https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64` → альтернативный CDN (Cloudflare有自己的 CDN: `https://pkg.cloudflareclient.com/cloudflared/releases/latest/cloudflared-linux-amd64` или оставить github.com — cloudflared releases только там; решение: оставить, это не наш код, пометить комментарием что downloads с github.com для cloudflared, не для наших репо) - Проверить: после удаления `gh` — `memory-doctor.ts` (L38, `rg --version`), `memory-search.ts` (L120, `rg`), `commit.ts` (git) — не зависят от `gh`, OK 2. **`.env.example`** (51 строка): - Удалить секцию `# GitHub` + `GITHUB_TOKEN=your-github-token-here` (L18-19) - `OPENCODE_MEMORY_REMOTE` (L50): `https://github.com/your-username/your-opencode-memory.git` → `https://git.slaid098.dev/slaid098/opencode-memory.git` (Forgejo URL) - Оставить `# Forgejo (self-hosted)` секцию (L21-23) с `FORGEJO_URL`/`FORGEJO_TOKEN` — это primary 3. **`opencode.json` `permission.bash`** — удалить 24 `gh*` правила: - L206-219 (14 allow правил): `gh pr create*`, `gh pr merge*`, `gh pr list*`, `gh pr status*`, `gh run*`, `gh issue*`, `gh pr diff*`, `gh pr view*`, `gh pr comment*`, `gh pr review*`, `gh api repos/*/actions/runs*`, `gh api repos/*/issues*`, `gh run list*`, `gh run view*` - L249 (`gh repo delete *: deny`), L250 (`gh pr close *: ask`) - L329-337 (8 deny правил): `gh pr create *: deny`, `gh pr merge *: deny`, `gh issue create *: deny`, `gh api * -X DELETE *: deny`, `gh api -X DELETE *: deny`, `gh api * --method DELETE *: deny`, `gh api * --method delete *: deny`, `gh repo transfer *: deny` - После удаления проверить: конфликт правил L206 allow vs L329 deny — resolved (оба удалены) - Добавить safety net правило: `"curl * -X DELETE *FORGEJO_URL*": "deny"` (если будет прямой curl в skills — запретить delete операции) - Оставить `permission.read` секцию (L165-173) без изменений (нейтральна) 4. **`AGENTS.md`** — добавить секцию про git-host после `## Pipeline`: ``` ## Git Host Primary: Forgejo (`git.slaid098.dev`). GitHub мёртв (аккаунт удалён). - Все tools/scripts ходят через `fetch`/`urllib` к Forgejo REST API (`$FORGEJO_URL/api/v1`), НЕ через `gh` CLI - `gh` CLI НЕ установлен в Docker образе (PR #3) — raw `gh` в bash НЕ работает - Для операций без tool'а (label create, release create, repo edit, repo create, branch protection) — `curl` к Forgejo API в bash-блоке - Описания в skills/agents — host-agnostic ("issue", не "GitHub issue"/"Forgejo issue") — задел на будущие зеркала - Env vars: `FORGEJO_URL`, `FORGEJO_TOKEN` (в `.env`, пробрасываются через docker-compose) - `GITHUB_TOKEN` удалён из `.env.example` — больше не нужен ``` 5. **`pyproject.toml`** (L48-50): - `Homepage = "https://github.com/slaid098/opencode-config"` → `https://git.slaid098.dev/slaid098/opencode-config` - `Repository = "https://github.com/slaid098/opencode-config"` → `https://git.slaid098.dev/slaid098/opencode-config` - `Issues = "https://github.com/slaid098/opencode-config/issues"` → `https://git.slaid098.dev/slaid098/opencode-config/issues` 6. **`README.md`** (L46, L85): - `git clone https://github.com/slaid098/opencode-config.git` → `git clone https://git.slaid098.dev/slaid098/opencode-config.git` (2 места: Quick Start EN + RU) - L39 "agent creates GitHub issue" → "agent creates issue" - L78 "агент сам создаёт GitHub issue" → "агент сам создаёт issue" 7. **Создать ADRs:** - `docs/decisions/092-forgejo-dispatch.md` — документировать существующий Forgejo dispatch (env-presence fallback в `_shared.ts` + 3 oracle-скриптах, реализованный до этого ADR). Ссылается на PR #1. - `docs/decisions/093-forgejo-first.md` — стратегия перехода: GitHub мёртв → Forgejo primary, `gh` CLI убран, fallback вырезан. Ссылается на PR #1, #2, #3. - `docs/decisions/094-host-agnostic-docs.md` — описания skills/agents/tools host-agnostic ("issue", не "GitHub issue") — задел на будущие зеркала (GitLab/Codeberg). Ссылается на PR #2. - `docs/decisions/095-curl-in-skills-where-no-tool.md` — для операций без tool'а (label/release/repo create/edit) используем `curl` к Forgejo API в bash-блоке skill'а, НЕ создаём новые tools (решение пользователя: tools только где нужен детерминированный формат). Ссылается на PR #2. 8. **Пометить устаревшие ADRs:** - `docs/decisions/022-pr-53-git-insteadof.md` — добавить в начало `> **STATUS: SUPERSEDED** — setup-memory.sh удалён, GitHub-специфика, миграция на Forgejo (ADR-093).` - `docs/decisions/005-pr-25-reviewer-echo-bypass.md` — `> **STATUS: SUPERSEDED** — GitHub fine-grained PAT 403, Forgejo не имеет GraphQL Checks API (ADR-093).` - `docs/decisions/023-pr-55-parse-remote-url.md` — `> **STATUS: SUPERSEDED** — GitHub PAT в URL, Forgejo использует token-in-URL напрямую (ADR-093).` ## Контракты - `Dockerfile`: после правки `docker build` должен собираться без `gh` — проверить `rg "gh" Dockerfile` → 0 - `.env.example`: `rg "GITHUB_TOKEN" .env.example` → 0; `rg "github.com" .env.example` → 0 (кроме cloudflared если оставили) - `opencode.json`: `rg "gh " .opencode/opencode.json` → 0 (в permission.bash секции) - `AGENTS.md`: новая секция `## Git Host` после `## Pipeline` - `pyproject.toml`: `rg "github.com" pyproject.toml` → 0 - `README.md`: `rg "github.com" README.md` → 0 - ADRs: 4 новых (092-095) + 3 помеченных superseded (022, 005, 023) ## Инварианты - `Dockerfile` должен собираться (`docker build .` не падает) — это критично, образ пересобирается при `docker-compose restart` - `opencode.json` после удаления 24 `gh*` правил — остальная permission.bash секция НЕ сломана (valid JSON) - `cloudflared` download URL — оставить github.com (Cloudflare публикует releases только там), пометить комментарием "downloads cloudflared binary, not our code" - `.env.example` — template для пользователей, не наш `.env` (наш `.env` не трогаем) - ADR numbering: 092-095 (последний 091, без пропусков) - Устаревшие ADRs: пометить в начале файла, НЕ удалять (история) ## Граничные случаи - `Dockerfile` без `gh` — если какой-то tool всё ещё вызывает `spawnSync("gh")` (не вырезан в PR #1) → runtime ошибка. PR #1 должен быть смержен ДО этого PR. - `opencode.json` конфликт правил L206 allow vs L329 deny — после удаления обоих конфликта нет - `opencode.json` после удаления — если остался `"gh repo delete *": "deny"` (L249) — тоже удалить (это `gh*` rule) - `.env.example` `OPENCODE_MEMORY_REMOTE` — если пользователь уже скопировал `.env.example` в `.env` с GitHub URL, наш `.env` не меняется (только template) - `cloudflared` — если Cloudflare уберёт releases с github.com → tunnel skill сломается, но это не наша проблема (Cloudflare CDN) - `AGENTS.md` новая секция — проверить что не нарушает existing структуру заголовков ## Влияние на связанные компоненты - PR #1 (tools) — зависимость: `gh` spawnSync вырезан из кода ДО удаления `gh` из Dockerfile (иначе runtime ошибка) - PR #2 (skills) — зависимость: raw `gh` инструкции удалены из skills ДО удаления `gh*` permission rules (иначе skills инструктируют вызвать запрещённое) - `docker-compose.yml` — проверь `environment:` секцию, нет ли `GITHUB_TOKEN` проброса (по аудиту нет, только `env_file: .env`) - `Dockerfile` — `memory-doctor.ts` (L38 `rg --version`), `memory-search.ts` (L120 `rg`), `commit.ts` (git) — не зависят от `gh`, OK - `check-permissions.py` (L14-17, 19-28, 31-34, 59-61) — DANGEROUS_PATTERNS содержат `gh *` паттерны. После удаления `gh*` правил из opencode.json — паттерны в check-permissions.py становятся неактуальны. Обновить: удалить `gh *` паттерны или пометить как deprecated. - `permission.bash` в agent frontmatter (memory-syncer L19/L31-33, reviewer L33-55/L69) — удалены в PR #2, этот PR не трогает agent files - `pre-commit-config.yaml` (L2, L9) — `repo: https://github.com/astral-sh/ruff-pre-commit`, `repo: https://github.com/pre-commit/mirrors-mypy` — оставить (pre-commit hooks тянутся с github.com, это не наш код, работает через git clone) ## Вне scope - `check-permissions.py` DANGEROUS_PATTERNS — обновить (удалить `gh *` паттерны), но это в этом PR (см. Влияние) - `pre-commit-config.yaml` URLs — оставить (не наш код) - Templates (cookiecutter) — PR #4 - Витрина slaid098-dev — отдельный репо - Настройка act_runner — инфра ## Критерии приемки - [ ] `docker build .` succeeds without `gh` installed (проверить `docker build -t opencode-config-test . 2>&1 | tail -20`) - [ ] `rg "gh " Dockerfile` → 0 совпадений - [ ] `rg "GITHUB_TOKEN" .env.example` → 0 совпадений - [ ] `rg "github.com" .env.example` → 0 (или только cloudflared с комментарием) - [ ] `rg "gh " .opencode/opencode.json` → 0 в permission.bash секции - [ ] `opencode.json` valid JSON после правки (`python3 -c "import json; json.load(open('.opencode/opencode.json'))"`) - [ ] `AGENTS.md` содержит секцию `## Git Host` после `## Pipeline` - [ ] `rg "github.com" pyproject.toml` → 0 - [ ] `rg "github.com" README.md` → 0 - [ ] `docs/decisions/092-forgejo-dispatch.md` exists - [ ] `docs/decisions/093-forgejo-first.md` exists - [ ] `docs/decisions/094-host-agnostic-docs.md` exists - [ ] `docs/decisions/095-curl-in-skills-where-no-tool.md` exists - [ ] `docs/decisions/022-pr-53-git-insteadof.md` содержит `SUPERSEDED` в начале - [ ] `docs/decisions/005-pr-25-reviewer-echo-bypass.md` содержит `SUPERSEDED` в начале - [ ] `docs/decisions/023-pr-55-parse-remote-url.md` содержит `SUPERSEDED` в начале - [ ] `check-permissions.py` — `gh *` паттерны удалены или помечены deprecated - [ ] Smoke-test: `docker-compose restart` (после merge) — opencode поднимается без `gh`, tools работают
Sign in to join this conversation.
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#7
No description provided.