diff --git a/.agents/skills/worktree-next-issue/SKILL.md b/.agents/skills/worktree-next-issue/SKILL.md index d03c9d87..c6728576 100644 --- a/.agents/skills/worktree-next-issue/SKILL.md +++ b/.agents/skills/worktree-next-issue/SKILL.md @@ -31,7 +31,7 @@ No opencode, isso é o comando **`/worktree next`** / **`/worktree kill`** (`.op **Default-go:** `next`, `plan` e `new` imprimem `cd ` na última linha **por padrão**; `--stay` suprime; `--go` explícito continua aceito como no-op. No terminal interativo, use a função `worktree()` de **`.agents/shell/worktree.sh`** (uma linha de `source` no profile) para o `cd` ser aplicado de verdade no shell que te chamou — node não consegue mudar o cwd do shell pai. `kill` também imprime `cd
` no fim (a sessão nunca fica num diretório destruído). -**Launch do opencode (OPS26 + OPS33 + OPS31):** só a função shell marca `TEQO_WORKTREE_TERMINAL=1`; com o marcador, `next`/`plan`/`new` imprimem também a diretiva `launch opencode --model vercel/deepseek/deepseek-v4-flash-0731 --auto [--prompt "/work-issue --issue "]` **antes** do `cd`, e a função a executa depois do cd — `next` abre o TUI com `/work-issue --issue ` já enviado (a Issue claimada vai no prompt; a skill lê o resto do Forgejo); `plan` abre com `/plan-issue` já enviado (OPS31: o TUI já cai no fluxo de planejamento); `new` abre sem `--prompt` ("apenas conversar"). O preset roteia pelo **Vercel AI Gateway** (OPS78: rota com cache/estabilidade/failover; variantes low/high/max do model override em `opencode.json`, selecionáveis no TUI e sticky por model). Sem `exec`: sair do opencode volta ao shell no worktree. Presets são constantes em `scripts/lib/worktree.mjs`. **O comando `/worktree` do opencode (e qualquer automação sem o marcador) nunca lança o TUI.** +**Launch do opencode (OPS26 + OPS33 + OPS31):** só a função shell marca `TEQO_WORKTREE_TERMINAL=1`; com o marcador, `next`/`plan`/`new` imprimem também a diretiva `launch opencode --model vercel/deepseek/deepseek-v4-flash-0731 --auto [--prompt "/work-issue --issue "]` **antes** do `cd`, e a função a executa depois do cd — `next` abre o TUI com `/work-issue --issue ` já enviado (a Issue claimada vai no prompt; a skill lê o resto do GitHub); `plan` abre com `/plan-issue` já enviado (OPS31: o TUI já cai no fluxo de planejamento); `new` abre sem `--prompt` ("apenas conversar"). O preset roteia pelo **Vercel AI Gateway** (OPS78: rota com cache/estabilidade/failover; variantes low/high/max do model override na config global do opencode (`~/.config/opencode/opencode.jsonc`), selecionáveis no TUI e sticky por model). Sem `exec`: sair do opencode volta ao shell no worktree. Presets são constantes em `scripts/lib/worktree.mjs`. **O comando `/worktree` do opencode (e qualquer automação sem o marcador) nunca lança o TUI.** ## Fluxo quando invocado como skill (agentes que não têm opencode) diff --git a/docs/CHANGELOG-AGENTS.md b/docs/CHANGELOG-AGENTS.md index 2ec7a35c..04e98c24 100644 --- a/docs/CHANGELOG-AGENTS.md +++ b/docs/CHANGELOG-AGENTS.md @@ -4,6 +4,8 @@ Conteúdo movido do `AGENTS.md` em 2026-07-30 (fatiamento do paradigma de agente --- +**OPS89 — variantes do provider Vercel AI Gateway movidas do repo para a config global do opencode (2026-08-24):** fecha o ciclo aberto pela OPS78/OPS82: as variantes low/high/max dos dois DeepSeek V4 Flash (`deepseek-v4-flash` e `-0731`) saíram do `opencode.json` do repo e voltam a ser preferência de máquina no global `~/.config/opencode/opencode.jsonc` (aplicação manual pelo dono — nada commitado; auth continua em `~/.local/share/opencode/auth.json`). O repo fica mínimo: só `$schema` + `mcp.penpot` — o mesmo princípio "edit the owner, don't twin" da OPS82, agora para o próprio `provider.vercel` (o anti-goal original da OPS78 de não commitar config de opencode no repo prevalece). Config-only + prosa: `-32` linhas de config; docblock de `OPENCODE_PRESET_MODEL` (`scripts/lib/worktree.mjs`) e prosa de `worktree-next-issue/SKILL.md` passam a apontar para a config global; a constante (model ID) e os pins de `worktree.unit.spec.ts` ficam intactos — o launch de `pnpm worktree next` não muda. No mesmo diff: "Forgejo" → "GitHub" na linha reescrita da skill (rastro stale pós-cutover); a varredura ampla do resíduo virou a OPS91 (#841). Verificação: `pnpm gate:fast` verde (256 arquivos/2443 testes), JSON estrito validado, grep sem ref viva a `provider.vercel` fora do docblock atualizado; aceite final do TUI condicionado ao global aplicado pelo dono (`opencode debug config`, `--variant max`, Ctrl+T). + **OPS83 — desbloquear deploy: estabilizar os e2e do verify sem reduzir cobertura; AgendaFeed volta a rodar em prod (2026-08-24):** o deploy manual (`deploy.yml`) estava bloqueado pelo job `verify` (run #15: 1 failed + 7 flaky + 2 skipped + 1 did-not-run). Causas estudadas e corrigidas por reescrita de specs (settle/poll/hermeticidade/escopo de locator) — **nenhum** `test.flaky`, nenhuma remoção de cobertura, nenhuma mudança de workers/retries, zero mudança de app/contrato/acesso: (1) kill switch da home — o poll de server-HTML convergia enquanto a seção renderizada ainda mostrava o link do Instagram; passou a pollar o **DOM rendered** escopado a `[data-home-section="contents"]` (`expectSectionCardCount`, usado também no sibling de fallback IG); (2) section-hidden — o revalidate `tag=posts` era engolido por `.catch`; agora o POST é **assertado** e a convergência ganha orçamento explícito (não bump cego); (3) SavedFilters strict-mode — o link 'Municípios' agora é escopado ao container `[data-slot="sidebar"]` (2º match = bottom nav, #669 absorvida); (4) People — gate `S:` + settle do stream antes de asserir rows (testes 15, pós-search e C118); (5) Municípios:642 — poll DOM da liderança específica em vez de `.first()` no stream; (6) Municípios:386 B176 — `settleMunicipalityStream` entre remove-chip e o próximo clique de opção; (7) Newsletter:222 — `toHaveURL(/#novidades/)` sem `$` (o `?e2e=scroll-…` é legítimo); (8) DemandVisibility:62 — `.goto` com cache-buster para a asserção de 404 do peer (a cache RSC servia a demanda acessível após a troca de cookie). **AgendaFeed (Decision B):** os 2 `test.skip(isProdMode)` foram **removidos** — o build e2e agora inlina `NEXT_PUBLIC_SITE_URL=https://feed.e2e.teqo.test` (`.test` TLD, passa o fail-closed `requireProductionDNSOrigin`), o diálogo gera o link canônico e os testes asserem o **path** e buscam via `campaign.baseURL + path`; confirmado que share usa `window.location.origin`, webauthn é desacoplado via request-host e webhooks usam `campaign.baseURL` — nenhum outro e2e depende do origin. Escopo config: `playwright.config.ts` (default do webServer env em prod), `deploy.yml` e `ci-pr.yml` (env do build-for-e2e + do passo de testes). Verificação: specs afetadas verdes em dev mode (2×) e AgendaFeed verde em `E2E_PROD=1`; `pnpm lint`/`tsc`/`format:check`/`knip`/`check:cycles`/`test:unit` (2443) verdes; PR em main com auto-merge. **OPS79 — última migração de dados em produção: plataforma antiga → nova (vertical campanha) (2026-08-23):** com a fonte congelada pelo OPS80 (zero escritas no Neon desde 2026-08-23 22:30 UTC), reconciliação e migração do residual. **Descoberta-chave:** a vertical campanha JÁ estava 100% íntegra no `teo_1313` (aceite do OPS51 confirmado por reconciliação repetível — diff 0 em contagens e junta de IDs das 13 coleções; `municipality_rels` só 3 links de edição de portfólio pós-OPS51, absorvidos como não-dado). O único residual real entre Neon e target era a `signature` pública 1486 (petition `fim-escala-6x1`) com seu contato + subscription, cujo contato originário (Juares) **não existia** no target (o id 2221 do target é outra pessoa). **Ferramentas:** `scripts/reconcile-campaign-vertical.mjs` (read-only, 19/19 PASS, nunca imprime PII) + `scripts/migrate-signature-orphan.mjs` (dry-run/apply, guard `OPS79_MIGRATE_CONFIRM=1`, transação única, PII mascarada nos logs). **Execução 100% no homeserver:** aplicado contact novo **2225** + signature **1486** preservada + subscription **1492** + sequences ajustadas; pós-verificação `signature` 1485=1485, reconcile 19/19, smoke `/` `/campanha` `/admin` 200. Runbook (rollback = DELETE das 3 linhas + setval) em `docs/ops/teqo-1313-deploy.md` §OPS79. Sem migration de schema, sem access/Consent novo, sem UI. Closes #797. diff --git a/docs/changelog/2026-08-24-ops89.md b/docs/changelog/2026-08-24-ops89.md new file mode 100644 index 00000000..8e6a256f --- /dev/null +++ b/docs/changelog/2026-08-24-ops89.md @@ -0,0 +1 @@ +**OPS89 — variantes do provider Vercel AI Gateway movidas do repo para a config global do opencode (2026-08-24):** fecha o ciclo aberto pela OPS78/OPS82: as variantes low/high/max dos dois DeepSeek V4 Flash (`deepseek-v4-flash` e `-0731`) saíram do `opencode.json` do repo e voltam a ser preferência de máquina no global `~/.config/opencode/opencode.jsonc` (aplicação manual pelo dono — nada commitado; auth continua em `~/.local/share/opencode/auth.json`). O repo fica mínimo: só `$schema` + `mcp.penpot` — o mesmo princípio "edit the owner, don't twin" da OPS82, agora para o próprio `provider.vercel` (o anti-goal original da OPS78 de não commitar config de opencode no repo prevalece). Config-only + prosa: `-32` linhas de config; docblock de `OPENCODE_PRESET_MODEL` (`scripts/lib/worktree.mjs`) e prosa de `worktree-next-issue/SKILL.md` passam a apontar para a config global; a constante (model ID) e os pins de `worktree.unit.spec.ts` ficam intactos — o launch de `pnpm worktree next` não muda. No mesmo diff: "Forgejo" → "GitHub" na linha reescrita da skill (rastro stale pós-cutover); a varredura ampla do resíduo virou a OPS91 (#841). Verificação: `pnpm gate:fast` verde (256 arquivos/2443 testes), JSON estrito validado, grep sem ref viva a `provider.vercel` fora do docblock atualizado; aceite final do TUI condicionado ao global aplicado pelo dono (`opencode debug config`, `--variant max`, Ctrl+T). diff --git a/docs/plans/mover-variantes-vercel-global-impl.md b/docs/plans/mover-variantes-vercel-global-impl.md new file mode 100644 index 00000000..10e8d4cb --- /dev/null +++ b/docs/plans/mover-variantes-vercel-global-impl.md @@ -0,0 +1,132 @@ +# Impl: Mover as variantes do provider Vercel AI Gateway para a config global do opencode + +Status: rascunho +Atualizado em: 2026-08-24 +Issue: #836 +Intenção: docs/plans/mover-variantes-vercel-global.md +Appetite restante: ~0,25–0,5 dia herdado (config-only + prosa; sem migration, sem testes novos) + +## Leitura da intenção + +- **Outcome:** o repo `opencode.json` fica mínimo (só `$schema` + `mcp.penpot`); as variantes low/high/max dos dois DeepSeek V4 Flash do Vercel AI Gateway passam a viver no global `~/.config/opencode/opencode.jsonc` (manual, fora do repo — nada é commitado); os textos vivos do repo que localizam as variantes passam a apontar para a config global; comportamento do opencode inalterado antes/depois (`opencode debug config` mostra vercel com variants, `opencode run --model vercel/deepseek/deepseek-v4-flash-0731 --variant max` responde, TUI cicla variantes); `pnpm worktree next` segue emitindo `--model vercel/deepseek/deepseek-v4-flash-0731` com o teste unit intacto. +- **O que NÃO negociar:** anti-goals da intenção — NÃO mover o preset de launch para o repo (fica no script — model ID, não bloco de config); NÃO mexer em auth/rota do gateway Vercel; NÃO editar docs históricos congelados (`docs/plans/*`, `docs/CHANGELOG-AGENTS.md`, `docs/changelog/*`). Aceite **condicionado à edição manual do global pelo dono** (arquivo fora do repo). +- **O que reavaliar:** hipóteses da "Direção no codebase" — confirmadas ao vivo com os números exatos: o bloco a mover é `opencode.json:10-41` (fecha em `}` na linha 41; sobram `$schema` + `mcp.penpot`, linhas 2–9); o docblock que localiza as variantes é o de `OPENCODE_PRESET_MODEL` em `scripts/lib/worktree.mjs` (frase em `:26-27` pré-edição, `:26-28` pós; constante `:30`, intocada); a prosa é `.agents/skills/worktree-next-issue/SKILL.md:34`. Verificado também: **nenhum teste lê `opencode.json` estruturalmente** (`readFileSync`/`JSON.parse` em `tests/`: zero) e nenhum gate/lint/CI o lê (`.github/` zero matches) — a remoção do bloco não tem ponto de quebra automatizado. O estilo JSONC do global é `//` em pt-BR (visto no arquivo real: `cheapestinception`, `deepinfra`, comentários de MCP) — o bloco colado segue esse estilo. + +## Abordagem recomendada + +```mermaid +flowchart LR + R["opencode.json (repo)\nprovider.vercel REMOVIDO (10-41)\nfica $schema + mcp.penpot (2-9)"] --> T["TUI opencode"] + G["~/.config/opencode/opencode.jsonc (global, fora do repo)\nprovider.vercel + 2 model keys × variants low/high/max\n(manual — dono aplica; não commitar)"] --> T + P["scripts/lib/worktree.mjs:29\nOPENCODE_PRESET_MODEL (model ID, intocado)"] --> L["diretiva launch\n--model vercel/deepseek/deepseek-v4-flash-0731"] + L --> T + T -->|"variante sticky por model"| V["Vercel AI Gateway"] +``` + +**Opções consideradas (onde vivem as variantes):** A | B | C +**Recomendação:** A — remover `provider.vercel` inteiro do repo (`opencode.json:10-41`) e colar o mesmo bloco no global `~/.config/opencode/opencode.jsonc`, com comentário explicativo no estilo JSONC do arquivo. É o dono natural da preferência: as variantes não carregam secret (auth vive em `~/.local/share/opencode/auth.json`), configs do opencode são merged (global + projeto somam — a remoção do repo não quebra nada), o precedente OPS82 já removeu o twin `cheapest-inference` do repo com "edit the owner, don't twin", e o anti-goal original do OPS78 era não commitar config de opencode no repo. O preset de launch referencia o MODEL ID, não o bloco — nada de launch depende do bloco no repo. +**Rejeitadas:** + +- **B — manter cópia no repo + adicionar no global (twin):** viola engineering-standards ("edit the owner, don't twin") e o precedente OPS82; as duas cópias divergem cedo ou tarde, e o repo volta a commitar config opencode (anti-goal OPS78). +- **C — status quo (manter só no repo, atualizar só os textos):** não atende o outcome — o repo continua com `provider.vercel` commitado e as variantes seguem presas à máquina errada. + +**Opções consideradas (textos vivos):** A | B +**Recomendação:** A — atualizar os dois textos que localizam as variantes (`worktree.mjs` docblock + `worktree-next-issue/SKILL.md`) na **mesma** mudança, junto da remoção. Senão os textos mentem para o próximo dev que ler o docblock ou a skill. **Rejeitada: B** (só o docblock, adiar a skill) porque a prosa da skill é o texto que um agente lê ao executar o fluxo worktree — ficaria apontando para um bloco que não existe mais. + +**Preset de launch (não-decisão):** `OPENCODE_PRESET_MODEL` (`scripts/lib/worktree.mjs:29`), a interpolação do help em `scripts/worktree.mjs`, o comentário de `.agents/shell/worktree.sh:10` e os pins do teste unit ficam exatamente como estão — o preset é um model ID, não um bloco de config; movê-lo seria anti-goal explícito. + +### Componentes / mudanças + +- **`opencode.json`** (raiz, `:10-41`): **remover inteiro** o bloco `provider.vercel` (2 model keys × variants low/high/max). O `},` da linha 9 vira `}` (JSON estrito — sem trailing comma); o arquivo final fica com 10 linhas: `$schema` + `mcp.penpot`, sem `provider`. +- **`scripts/lib/worktree.mjs`** (`:26-27`, docblock de `OPENCODE_PRESET_MODEL`): substituir a frase "the low/high/max variants are exposed by the `provider.vercel` override in `opencode.json`." por: + ``` + * `-0731` flavor (input $0.076/M vs $0.13/M); the low/high/max variants are + * exposed by the `provider.vercel` override in the global opencode config + * (`~/.config/opencode/opencode.jsonc`, outside the repo — OPS89). + ``` + (linhas 24–25 do docblock — histórico OPS78/OPS82 — permanecem; a frase editada ocupa `:26-28` pós-edição e a constante `:30` fica intocada) +- **`.agents/skills/worktree-next-issue/SKILL.md`** (`:34`): na frase "variantes low/high/max do model override em `opencode.json`, selecionáveis no TUI e sticky por model", substituir "do model override em `opencode.json`" por "do model override na config global do opencode (`~/.config/opencode/opencode.jsonc`)". O literal `--model vercel/deepseek/deepseek-v4-flash-0731` na mesma linha **fica**. +- **Global `~/.config/opencode/opencode.jsonc`** (FORA do repo — **MANUAL, o dono aplica; não commitar**): inserir `provider.vercel` como sibling dentro do objeto `"provider"` existente — após o fechamento do bloco `deepinfra` (linha ~156 atual) e antes do `}` que fecha `provider` (~157). Bloco a colar, no estilo JSONC do arquivo (comentário `//` pt-BR): + ```jsonc + "vercel": { + // Vercel AI Gateway (built-in models.dev). Variantes low/high/max dos + // dois DeepSeek V4 Flash — selecionáveis no TUI (Ctrl+T) ou + // `opencode run --variant max`. Migrado do `opencode.json` do repo em + // OPS89: variantes são preferência de máquina (auth vive em auth.json) + // e o repo fica mínimo (só mcp.penpot). Sem este bloco, o Vercel não + // expõe as variantes. + "models": { + "deepseek/deepseek-v4-flash": { + "variants": { + "low": { + "reasoningEffort": "low" + }, + "high": { + "reasoningEffort": "high" + }, + "max": { + "reasoningEffort": "max" + } + } + }, + "deepseek/deepseek-v4-flash-0731": { + "variants": { + "low": { + "reasoningEffort": "low" + }, + "high": { + "reasoningEffort": "high" + }, + "max": { + "reasoningEffort": "max" + } + } + } + } + } + ``` + (formato expandido igual ao do bloco repo atual e ao estilo do `cheapestinception` global; provider `vercel` é built-in/models.dev — sem `npm`/`options`; sem trailing comma, pois vira o último membro de `"provider"` — o `deepinfra` anterior mantém a vírgula dele) +- **Migration:** sem migration — configuração/tooling + prosa; nenhum schema de Payload muda. +- **Access / Consent:** N/A — não há collection nem dado de cidadão envolvido; não afeta login de campanha nem LGPD. +- **UI:** N/A — o TUI do opencode é consumidor (verificação do aceite), não produto deste plano. + +## Fases verificáveis + +1. **Repo (tracer)** — `opencode.json`: remover `:10-41` (o `},` da linha 9 vira `}` — resultado: 10 linhas, JSON válido); `scripts/lib/worktree.mjs:26-27` (docblock); `.agents/skills/worktree-next-issue/SKILL.md:34` (prosa). Verificar: `node -e "JSON.parse(require('fs').readFileSync('opencode.json','utf8'))"` e `git diff` mostrando **apenas** esses 3 arquivos. Quota: maior parte do appetite (é todo o código do plano). +2. **Gates** — `pnpm gate:fast` (guards → lint → format → typecheck → knip → cycles → unit) verde: `tests/unit/worktree.unit.spec.ts` intacto continua pinando o literal do model ID (`:151,159,165,171,177,180,185,196`) e a constante (`:185`) — nenhuma asserção lê `opencode.json`. Push via `pnpm push` → CI PR (`checks`). Quota: resto do appetite. +3. **Global (MANUAL — dono; condiciona o aceite)** — colar o bloco `provider.vercel` no `~/.config/opencode/opencode.jsonc`; `opencode debug config` mostra vercel com variants; `opencode run --model vercel/deepseek/deepseek-v4-flash-0731 --variant max` responde; TUI mostra as variantes (Ctrl+T). Ordem recomendada: **global primeiro, PR depois** (merge soma — sem janela de perda). + +## Rabbit holes / Não escopo (engenharia) + +- NÃO reorganizar o `opencode.jsonc` global inteiro (corte: tocar apenas vercel/variantes; `permission`, `mcp`, `cheapestinception`, `deepinfra` ficam intactos). +- NÃO manter o bloco no repo por medo (twin — corte: o aceite cobre o launch via `worktree next` + `debug config`; se algo quebrar, o plano volta ao repo com evidência). +- NÃO tocar em `scripts/worktree.mjs:240,345`, `.agents/shell/worktree.sh:10`, `AGENTS-infra.md:13` — citam `opencode.json` só pelo `mcp.penpot`/`penpot-token` (o MCP penpot fica; remover o `mcp` sim quebraria o launch). +- NÃO mexer em `tests/unit/opencodeCommands.unit.spec.ts` (frontmatter `model:` dos comandos de execução, provider direto, sem vercel — anti-goal) nem em `tests/unit/worktree.unit.spec.ts` (nada muda). +- NÃO editar docs históricos congelados (`docs/CHANGELOG-AGENTS.md`, `docs/changelog/*`, `docs/plans/*` — a entrada de changelog desta entrega é criada depois, no fluxo padrão `docs/changelog/-.md` + `pnpm changelog:build`). +- NÃO mudar `OPENCODE_PRESET_MODEL`, a auth nem a rota do gateway Vercel. + +## Riscos e mitigação + +- **Dono não aplicar o bloco global (ou aplicar depois do merge do PR)** → a entrega só fecha com o aceite da Fase 3 (a intenção condiciona o aceite à edição pelo dono). Enquanto o global não tem o bloco, `opencode debug config` deixa de mostrar as variants do Vercel (o repo já não as tem) — janela aceita e documentada; ordem recomendada: global primeiro. Se o dono não aplicar, volta ao repo com evidência (o inverso do rabbit hole "manter por medo" — gatilho explícito). +- **Divergência de variants entre global e repo durante a transição** → configs do opencode são merged (soma, não substitui): com os dois blocos idênticos presentes, o conjunto resolvido é o mesmo; sem janela de perda. A única divergência possível é a ausência temporária (risco acima). +- **JSONC inválido no global** → o loader do opencode falha alto em config inválida; o dono valida com `opencode debug config` imediatamente após colar (Fase 3). +- **`opencode.json` inválido no repo** (JSON estrito, sem comentários) → `node -e "JSON.parse(...)"` na Fase 1 antes de commit. +- **Referência viva a `opencode.json` fora da lista** → pós-mudança, `grep -rn "opencode.json" scripts .agents AGENTS-infra.md` deve retornar só as refs de `mcp.penpot`/`penpot-token` (`scripts/worktree.mjs:240,345`, `AGENTS-infra.md:13`) e nenhuma menção a `provider.vercel`. +- **Sticky variant preso ao model key** → os model keys não mudam (`vercel/deepseek/...`); o sticky de variante por model key sobrevive à troca de origem da config — comportamento upstream já documentado na OPS82, sem ação do plano (só nota no PR). + +## Aceite de engenharia + +- [ ] Aceite de produto da intenção coberto: repo `opencode.json` sem `provider.vercel` (só `$schema` + `mcp.penpot`); global com `provider.vercel` e os 2 model keys × variants low/high/max no estilo JSONC do arquivo (manual, dono — nada commitado); textos vivos do repo apontando para a config global; `opencode debug config` / `opencode run --variant max` / TUI com variantes (Fase 3, com o global aplicado). +- [ ] Anti-goals preservados: preset de launch no script (model ID) intocado; auth/rota do gateway Vercel intactas; cardápio de execução (`work-issue.md`/`plan-issue.md` + `opencodeCommands.unit.spec.ts`) intacto; docs históricos intactos; config-only + prosa (sem migration, sem código novo). +- [ ] Invariantes AGENTS/engineering-standards: sem twin — o global vira o owner das variantes (precedente OPS82); textos do repo não mentem; nada de config opencode commitado no repo. +- [ ] Testes de domínio previstos: **nenhum teste novo** — verificado que `tests/` não lê `opencode.json` estruturalmente (zero `readFileSync`/`JSON.parse`); `tests/unit/worktree.unit.spec.ts` intacto e verde no `pnpm gate:fast`; verificação manual via `node -e JSON.parse` + grep pós-mudança + Fase 3 executada pelo dono. + +## Self-score decision-quality + +1. **Decisões caras têm rejeitadas?** Sim — Decisão 1 (A | B | C: B é twin/anti-goal, C não atende o outcome) e Decisão 2 (A | B: B deixa a skill mentindo); o preset de launch é não-decisão por anti-goal explícito, registrado como tal. +2. **Cabe no appetite?** Sim — config-only + 2 edições de prosa; ~0,25–0,5 dia herdado mantido; sem migration, sem testes novos. +3. **Rabbit holes nomeados?** Sim — reorganizar o global inteiro, manter o bloco por medo (twin), refs de `mcp.penpot`, docs congelados, cardápio de execução, preset/auth/rota. +4. **Depth check reusa?** Sim — nenhum helper novo; espelha o bloco OPS82/OPS78 e o estilo JSONC existente do global; reaproveita os pins de teste existentes (que não leem `opencode.json`) como verificação. +5. **Intenção (aceite de produto) permanece satisfeita?** Sim — a engenharia não reescreveu o outcome; a única reavaliação (números exatos do bloco/textos, confirmados ao vivo) não muda resultado nem escopo. + +**Score: 5/5** diff --git a/docs/plans/ops91-sweep-pos-cutover-forgejo-textos-vivos.md b/docs/plans/ops91-sweep-pos-cutover-forgejo-textos-vivos.md new file mode 100644 index 00000000..a44a0cb9 --- /dev/null +++ b/docs/plans/ops91-sweep-pos-cutover-forgejo-textos-vivos.md @@ -0,0 +1,52 @@ +# Sweep pós-cutover OPS76: textos vivos ainda apontam o tracker ao Forgejo + +Status: rascunho +Atualizado em: 2026-08-24 +Issue: registrada via `agent:register` (OPS91) +Priority: P2 +Impeccable: A — N/A sem UI +Rascunho UI: N/A +Appetite: ~0,5 dia, só edição de texto/prosa +Responsável: — + +## Intenção + +O cutover GitHub (OPS71 + OPS76, 2026-08) tornou o GitHub o host único (Actions + tracker de Issues); o Forgejo ficou congelado e seu tracker inativo. O OPS76 atualizou AGENTS.md/AGENT-OPS e o OPS71 Fase 2 removeu os arquivos Forgejo-era, mas uma varredura de superfícies vivas (feita na sessão OPS89, #836) provou que vários textos vivos ainda instruem leitura/escrita no tracker do Forgejo — um agente novo que siga essas instruções erra o host. + +## Evidência (grep da sessão OPS89) + +- `.agents/rules/agent-pr-workflow.mdc:8` — "The ISSUE TRACKER stays on the Forgejo — GitHub is only the Actions host" (regra alwaysApply com a realidade invertida). +- `.agents/skills/work-issue/execution-pipeline.md:69,75-76` — diz que o flip pós-merge escreve "no Forgejo" via `FORGEJO_API_TOKEN`; o real (`scripts/issue-transition-on-merge.mjs`, OPS76) escreve na API do GitHub com `GITHUB_TOKEN`. +- `.agents/skills/project-status/SKILL.md:25` — "leia a Issue via API do Forgejo". +- `.agents/skills/engineering-audit/SKILL.md:69` — "leitura da Issue via API do Forgejo/MCP". +- `.agents/skills/plan-issue/SKILL.md:23` — "Nada no Forgejo antes do gate" (shorthand do tracker). +- `docs/roadmap.md:5` — ponteiro canônico de Issues para `git.solla.dev/fsolla/teqo/issues`. + +## Objetivo e aceite + +- Todos os textos vivos acima apontam para o GitHub (`github.com/fsolla/teqo/issues`) como tracker único. +- Nenhuma instrução viva manda usar `FORGEJO_API_TOKEN`/API do Forgejo para o fluxo atual. +- Menções históricas corretas permanecem intactas (ver Fora de escopo). + +## Direção no codebase + +Edição de prosa apenas — sem código, sem testes novos. Cada arquivo é dono da própria frase; corrigir in place. + +## Fora de escopo / Explicitamente fora + +- Rename de pureza `scripts/lib/agent-forgejo.mjs` (+~15 imports com nome "Forgejo") — score 1, churn alto, zero ganho funcional. +- Menções históricas CORRETAS: runbook de rollback (`docs/ops/teqo-1313-deploy.md`), backup mirror OPS76-FOLLOWUP, marcações "legado/removido/congelado" em AGENT-OPS/AGENT-pr-workflow (:60,:85), skill `agent-pool` dormente. +- Docs congelados (`docs/plans/*`, `docs/changelog/*`, `docs/CHANGELOG-AGENTS.md`). + +## Rabbit holes + +- Não reescrever histórico de decisões (OPS50/OPS64/OPS71 citados como história ficam). +- Não tocar nos scripts que já falam GitHub (`github-api.mjs`, `issue-transition-on-merge.mjs`) — já corretos. + +## Já resolvido no simplify/critique (não reabrir) + +- `worktree-next-issue/SKILL.md` ("a skill lê o resto do Forgejo" → GitHub) — corrigido na sessão OPS89 (#836), linha tocada pela entrega. + +## Riscos + +- Baixo: mudanças são prosa; gates de lint/format cobrem os `.md` versionados. diff --git a/opencode.json b/opencode.json index b561d404..4653e50f 100644 --- a/opencode.json +++ b/opencode.json @@ -6,37 +6,5 @@ "url": "https://design.penpot.app/mcp/stream?userToken={file:.opencode/secrets/penpot-token}", "enabled": true } - }, - "provider": { - "vercel": { - "models": { - "deepseek/deepseek-v4-flash": { - "variants": { - "low": { - "reasoningEffort": "low" - }, - "high": { - "reasoningEffort": "high" - }, - "max": { - "reasoningEffort": "max" - } - } - }, - "deepseek/deepseek-v4-flash-0731": { - "variants": { - "low": { - "reasoningEffort": "low" - }, - "high": { - "reasoningEffort": "high" - }, - "max": { - "reasoningEffort": "max" - } - } - } - } - } } } diff --git a/scripts/lib/worktree.mjs b/scripts/lib/worktree.mjs index 042cefba..c2bd99d5 100644 --- a/scripts/lib/worktree.mjs +++ b/scripts/lib/worktree.mjs @@ -24,7 +24,8 @@ export const WORKTREE_TERMINAL_ENV = 'TEQO_WORKTREE_TERMINAL' * constant. OPS78: routes through the Vercel AI Gateway (cache/stability/ * failover) instead of the direct provider. OPS82: the preset is the cheaper * `-0731` flavor (input $0.076/M vs $0.13/M); the low/high/max variants are - * exposed by the `provider.vercel` override in `opencode.json`. + * exposed by the `provider.vercel` override in the global opencode config + * (`~/.config/opencode/opencode.jsonc`, outside the repo — OPS89). */ export const OPENCODE_PRESET_MODEL = 'vercel/deepseek/deepseek-v4-flash-0731'