26 KiB
Impl: OPS113 — Agentes designer e designer-degraded: design hi-fi como fonte de verdade
Status: aprovado (gate humano 2026-09-15, com ajuste de JS mínimo autorizado) Atualizado em: 2026-09-15 Issue: #1056 Intenção: docs/plans/ops113-agentes-designer-e-designer-degraded.md Appetite restante: ~0,5–1 dia (herdado; doc/config only — sem corte necessário)
Leitura da intenção
- Outcome:
.opencode/agent/designer.md(mode: all,temperature: 0.7,model: openai/gpt-5.6-sol) e.opencode/agent/designer-degraded.md(mode: subagent,model: opencode-go/deepseek-v4.1-flash) existem e são invocáveis, com os modos Criar/Criticar e sem escrita emsrc/; a doutrina viva é.agents/skills/plan-issue/ui-design-html.md; o artefatodocs/plans/<slug>-ui-design.html(+docs/plans/<slug>-ui-design-assets/*.svg) é a fonte de verdade do port; a ladderopenai/gpt-5.6-sol → openai/gpt-6-astra → opencode-go/deepseek-v4.1-flash (DEGRADED) → deepseek/deepseek-flash (DEGRADED, inline)está documentada e auditável, com o tier registrado no PR — tier degradado nunca certifica. - O que NÃO negociar: output só em
docs/plans/<slug>-ui-design.*(o designer nunca escreve emsrc/);DEGRADED+ sign-off humano no tier degradado (nunca certifica); teto protetivo da doutrina mantido, com o ajuste autorizado no GATE em 2026-09-15 (JS mínimo de apresentação permitido — modal, tabs, toggle; sem lógica de negócio — ver decisão 6; estados como cenas estáticas seguem válidos; 390/1280; copy pt-BR real; sem imports desrc/; sem decisão de engenharia; claims só os aprovados no plano;NEEDS ASSET; LGPD/TSE; um CTA primário); pins literais de modelo/modo/temperatura; pré-requisito operacional verificado antes do pin; quota/indisponibilidade desce a ladder explicitamente — nunca pula design em silêncio. - O que reavaliar: (a) que o frontmatter de agente aceita
permission.editaninhado e que o merge com o global preserva o fail-closed — confirmado nas docs oficiais e a confirmar noopencode agent list/smoke; (b) quedocs/plans/*-ui-design*casa o caminho que o edit tool envia — hipótese fundada no exemplo relativo das docs oficiais, provada no smoke (falso-deny é fail-closed: o smoke acusa e o padrão é corrigido antes do merge); (c) que os consumidores do nome antigo ficam intocados (OPS114) e o sufixo do painel é OPS116 — dívida declarada, não corrigida aqui.
Estado atual verificado (explorador)
- Doutrina atual:
.agents/skills/plan-issue/ui-draft-html.md(63 linhas), incluindo as seções "O teto", "Como fazer" e "Gate". Consumidores do nome antigo (intocados, OPS114):.agents/skills/plan-issue/SKILL.md:42,100,intention-template.md:33,107,shaping.md:56,skills-map.md:42. O sufixo irmão-ui-draft.htmlemscripts/lib/issues-panel.mjs:91,100é OPS116. .opencode/agent/*.mdhoje usa sódescription/mode/temperature(ex.:.opencode/agent/designer-campanha-solla.md:2-4). Nenhum teste/guard no repo lê.opencode/agent/*.md— o único spec que lê.opencode/(tests/unit/opencodeCommands.unit.spec.ts) cobrecommands/*.mde proíbemodel:lá (OPS101); agentes fora.- Precedente de frontmatter e visão nativa/fail-closed:
.opencode/agent/designer-campanha-solla.md:63-65(visão nativa via Read; crítica visual estruturada com hierarquia/contraste/tipografia/espaçamento/mobile/acessibilidade + lista numerada; "a referência é o alvo — nunca a critique"; parada fail-closed se a leitura da imagem falhar). - Formato de agente (schema oficial
https://opencode.ai/config.json+ docs/docs/permissions): frontmatter aceitaname, model, variant, description, mode, hidden, color, steps, options, permission, disable, temperature, top_p(campo desconhecido cai emoptions); o corpo do arquivo é o prompt (semprompt:);mode:primary|subagent|all.permission.edité objeto{ padrão: allow|ask|deny }com avaliação last-match-wins;editcobreedit,writeepatch; padrões são wildcards simples (*casa qualquer caractere, inclusive/); o exemplo das docs usa paths relativos ao projeto.--autonunca aprovadeny. - Precedente de
permissionpor agente no repo:opencode.json(agent.<nome>.permissionpara MCP tools; global negapenpot*/postgres*e os subagentes específicos reabilitam). Config global:~/.config/opencode/opencode.jsonc(disabled_providerssemopenai, sópermission.bash: ask). - Formatação:
.prettierignoreignora.agents/(a doutrina renomeada fica fora do check) mas não.opencode/— os dois agentes novos precisam passarpnpm exec prettier --check(o precedentedesigner-campanha-solla.mdpassa com description longa numa linha; printWidth 100). - Operação:
docs/AGENT-OPS.md(148 linhas) — o parágrafo**Skills:**está em ≈L22 e a lista de bullets em L24-26;## Comandosem L37. Changelog:docs/changelog/<data>-<id>.md, linha única (ex.:docs/changelog/2026-09-15-ops111.md); o agregado é gitignored. - CLI: opencode 1.18.31 tem
opencode agent list(verificado: lista agentes e o ruleset de permissão resolvido) eopencode run --agent <nome> --auto. Config não é hot-reloaded — o smoke precisa de subprocesso novo (a sessão atual não enxerga agentes criados agora). package.json(verificado):gate:fast=pnpm lint && pnpm typecheck && pnpm test:unit;push=node scripts/git-push.mjs(ensure-deps +gate:push→gate:ci).- Pré-requisito operacional verificado em 2026-09-15:
disabled_providersglobal semopenai(religado); OAuth conectado;opencode models | grep '^openai/'lista 15 ids, incluindoopenai/gpt-5.6-soleopenai/gpt-6-astra;opencode-go/deepseek-v4.1-flashedeepseek/deepseek-flashexistem; smoke de visão (PNG sólido lido corretamente pelo Sol) OK. O preset canônico do orquestrador édeepseek/deepseek-flash(scripts/lib/worktree.mjs:40).
Abordagem recomendada
flowchart LR
REN["F1 · git mv\ndoutrina do gate"] --> DOC["F1 · ui-design-html.md\nfonte de verdade do port\n+ teto + SVG + ladder"]
DOC --> AG["F2 · designer.md (sol, all)\ndesigner-degraded.md (deepseek-v4.1, subagent)"]
AG --> PERM["F2 · permission.edit fail-closed\n* deny → docs/plans/*-ui-design* allow"]
DOC --> OPS["F3 · docs/AGENT-OPS.md\n1 parágrafo: pin/ladder/tier"]
PERM --> EV["F3 · opencode agent list\nsmoke subprocesso: src/ deny + docs/plans/ allow"]
OPS --> EV
EV --> GATES["changelog · prettier --check\ngate:fast · pnpm push → PR Closes #1056"]
Opções consideradas: A | B | C
Recomendação: A — rename da doutrina via git mv + reescrita elevando o contrato; dois arquivos de agente com pin literal e permission.edit fail-closed; ladder documentada na doutrina e resumida em docs/AGENT-OPS.md; prova por smoke em subprocesso. É doc/config puro (4 arquivos + changelog), cabe no appetite e não toca src/.
Rejeitadas: B — um único agente com troca de modelo para o tier degradado: não carrega a identidade DEGRADED/mode: subagent que a intenção fixou e confunde certificação com fallback (o DEGRADED precisa ser um agente distinto, invocável por --agent); C — regras duplicadas nos prompts sem elevar a doutrina: contraria o aceite "doutrina viva ui-design-html.md" e garante drift.
Decisões de engenharia (com rejeitadas)
-
Forma do gate de escrita dos agentes.
- Opções: A)
"src/**": "deny"sozinho | B) fail-closed{"*":"deny","docs/plans/*-ui-design*":"allow"}(allowlist só do artefato:<slug>-ui-design.html+-ui-design-assets/**) | C) sempermission, só prompt. - Recomendação: B — o corte da intenção é "output só em
docs/plans/<slug>-ui-design.*"; a allowlist codifica exatamente isso e nega todo o resto (src/,scripts/,.github/,.agents/,.opencode/, planos existentes inclusive o de intenção). Com last-match-wins e catch-all primeiro, o bloco exato no frontmatter dos dois agentes é:
Fatos que sustentam:permission: edit: '*': deny 'docs/plans/*-ui-design*': alloweditcobreedit/write/patch;*casa/, logodocs/plans/*-ui-design*cobre tambémdocs/plans/<slug>-ui-design-assets/*.svg;--autonão aprovadeny, portanto o smoke prova stop duro.readpermanece allow (a crítica lê app/screenshots) — o gate é de escrita. Revisão pós-simplify: o padrão foi estreitado dedocs/plans/*paradocs/plans/*-ui-design*— o catch-all largo permitiria sobrescrever o plano de intenção (imutável) e planos de outros itens. - Rejeitadas: A — deny-list deixa todos os outros caminhos graváveis e não implementa o corte; C — prompt não é gate: a violação vira silenciosa, contra o aceite "sem permissão de escrita em
src/". - Resíduo declarado:
bashnão é sandbox — apermissioncobre os file tools (edit/write/patch), não redirecionamento de shell. O prompt proíbesrc/explicitamente; o fluxo é humano-supervisionado. O smoke prova o gate dos file tools, não prometemos sandbox de shell. - Como o smoke prova: subprocesso novo (
opencode run, config não é hot-reloaded) pedindo (1)writeemdocs/plans/ops113-ui-design-smoke.html(deve passar) e (2)writeemsrc/ops113-smoke.txt(deve ser negado, sem contornar por bash). Odesignerroda direto com--agent designer; odesigner-degradednão roda como primário (mode: subagent— o CLI cai no default), então é lançado via task a partir de um run dobuild. Saída colada no PR; arquivos de smoke removidos antes do commit.
- Opções: A)
-
Rename da doutrina.
- Opções: A)
git mv+ reescrita no mesmo lote | B) delete + create. - Recomendação: A — preserva histórico/blame (
git log --follow), o diff aparece como rename + edição e o path novo já nasce como o que o OPS114 vai consumir. O rename vem primeiro (rename puro num commit, reescrita em seguida) para leitura limpa. - Rejeitadas: B — perde o histórico sem nenhum ganho; renomear com
git mvé a convenção barata e auditável.
- Opções: A)
-
Conteúdo dos agentes.
- Opções: A) prompt próprio enxuto que aponta para a doutrina (fonte única) | B) duplicar as regras da doutrina nos dois prompts.
- Recomendação: A — a doutrina é a dona do contrato do artefato (teto, caminhos, SVG, ladder, modos); cada prompt carrega só a identidade do papel: persona em 1 parágrafo, "leia
.agents/skills/plan-issue/ui-design-html.mdantes de qualquer trabalho", modos Criar (produz/estende o hi-fi) e Criticar (relê a implementação renderizada contra o artefato aprovado), a proibição de escrever emsrc/(o gate duro é apermission), a visão nativa/fail-closed adaptada dedesigner-campanha-solla.md:63-65("leia screenshots direto com a tool Read, nunca peça ao usuário para descrever o que você pode ver"; crítica estruturada com hierarquia/contraste/tipografia/espaçamento/mobile 390px/acessibilidade + lista numerada; "a referência é o alvo — nunca a critique"; "se a leitura da imagem falhar, pare e peça a troca via/models; nunca descreva o que não viu") e, no degradado, "todo output marcadoDEGRADED; nunca certifica — sign-off humano". - Rejeitadas: B — duas cópias divergem (risco "Drift entre os dois prompts" da intenção); a doutrina é o único lugar onde o contrato muda.
-
Ladder: registro do tier e o que é "inline".
- Opções: A) ladder na doutrina + tier registrado no PR (linha no body) +
DEGRADEDno artefato/output quando degradado | B) arquivos gêmeos (designer-astra.md,designer-deepseek.md) | C) registro informal (só no chat). - Recomendação: A. Ladder literal:
openai/gpt-5.6-sol → openai/gpt-6-astra → opencode-go/deepseek-v4.1-flash (DEGRADED) → deepseek/deepseek-flash (DEGRADED, inline).- Tier 1: pin do
designer. Tier 2 (openai/gpt-6-astra, mesmo pool Plus): mesmo agente, troca via/models(ou--model openai/gpt-6-astrano headless) quando a crítica for contestada/pixel-critical; tier registrado também (pergunta B da intenção assumida —designer-astra.mdnão é criado). - Tier 3:
--agent designer-degraded(opencode-go/deepseek-v4.1-flash),DEGRADED. - Tier 4 ("inline"): sem arquivo de agente — o orquestrador (
work-issue/agent-work-issue, cujo modelo canônico de sessão édeepseek/deepseek-flash,scripts/lib/worktree.mjs:40) faz o design/crítica ele mesmo seguindo a doutrina, com as mesmas obrigações (DEGRADED+ sign-off humano; nunca certifica). Um arquivo para o tier 4 seria twin do papel (drift sem ganho), já que é o próprio modelo da sessão. - Registro auditável: linha
Design tier: <slug>(ouDesign tier: DEGRADED (<slug>)) no body do PR; quando tier 3/4,DEGRADEDvisível no topo do artefato e no output do agente. Queda por quota/indisponibilidade/visão é explícita; se todos os tiers falharem, o design fica bloqueado (humano decide) — nunca "segue sem".
- Tier 1: pin do
- Rejeitadas: B — twin/drift e contraria a pergunta assumida; C — tier implícito é exatamente o anti-goal "pula design em silêncio".
- Opções: A) ladder na doutrina + tier registrado no PR (linha no body) +
-
Parágrafo em
docs/AGENT-OPS.md.- Opções: A) sim, 1 parágrafo curto no fluxo (após o parágrafo
**Skills:**, ≈L22, antes da lista de bullets em L24) | B) nova seção H2 antes de## Comandos| C) deixar só na doutrina. - Recomendação: A — o doc é o ponto de entrada da operação de agentes; 3–4 linhas cobrem pin, ladder,
DEGRADED/sign-off e linkam a doutrina, sem inflar a página. Conteúdo sugerido: "Design hi-fi (OPS113): item que muda UI passa pelo agentedesigner(model: openai/gpt-5.6-sol; crítica contestada emopenai/gpt-6-astra); a doutrina.agents/skills/plan-issue/ui-design-html.mdé a fonte única do artefatodocs/plans/<slug>-ui-design.html(+-ui-design-assets/*.svg). Indisponibilidade desce a ladder —opencode-go/deepseek-v4.1-flash(designer-degraded) →deepseek/deepseek-flash(inline pelo orquestrador) — sempre gravando o tier no PR; tier degradado marcaDEGRADED, não certifica e para em sign-off humano (triggers: OPS115)." - Rejeitadas: B — H2 nova para um contrato de 1 parágrafo adiciona cerimônia; C — enterra a ladder na skill, contra o risco nomeado na intenção.
- Opções: A) sim, 1 parágrafo curto no fluxo (após o parágrafo
-
Teto de JS na doutrina (ajuste de produto autorizado no GATE em 2026-09-15).
- Opções: A) manter "zero JS de comportamento" (literal original da intenção) | B) JS mínimo de apresentação: modal abrir/fechar, tabs, dropdown/accordion, toggle, hover/scroll reveal — sem lógica de negócio | C) protótipo funcional (fetch, validação, estado de produto).
- Recomendação: B — decisão do humano no GATE: as cenas podem implementar a interação de apresentação (abrir/fechar modal, trocar de tab), tornando o artefato mais fiel ao que será portado; C viola os anti-goals "não é protótipo funcional" / "não é implementação disfarçada".
- Limites do teto com B: JS inline e autocontido (sem build, sem imports além do Tailwind CDN, nada de
src/); proibido fetch/rede, persistência, validação de dados, cálculo de produto e roteamento; estados críticos continuam demonstráveis como cenas estáticas (o gate não depende de clicar); copy pt-BR real e claims aprovados inalterados. - Rejeitadas: A — o humano pediu interação; zero JS tornaria o artefato menos fiel ao port; C — vira implementação e mata a função do gate.
- Registro: o plano de intenção (Issue
in-progress) é imutável — o ajuste fica registrado aqui, autorizado pelo humano no GATE.
Componentes / mudanças
.agents/skills/plan-issue/ui-design-html.md(renomeada deui-draft-html.mdviagit mv; owner do contrato): eleva tokens reais/brand/shadcn como esperados e o HTML como fonte de verdade do port (implementador porta classe-a-classe; não descartável; imutável como registro e mutável durante o work-issue pelo designer, com mudança material voltando ao humano no PR); mantém o teto (JS restrito ao mínimo de apresentação conforme decisão 6; estados críticos como cenas estáticas; 390/1280; copy pt-BR real; sem imports desrc/; sem decisão de engenharia; claims só os aprovados no plano;NEEDS ASSET; LGPD/TSE; um CTA primário); define modos Criar/Criticar, caminhos do artefato, regras de SVG (lucide/shadcn primeiro; custom só sem equivalente; grid 24px;currentColor; stroke lucide; salvar em-ui-design-assets/) e a seção da ladder..opencode/agent/designer.md(novo): frontmattermode: all,temperature: 0.7,model: openai/gpt-5.6-sol,permissionfail-closed da decisão 1; corpo enxuto apontando a doutrina (decisão 3)..opencode/agent/designer-degraded.md(novo): frontmattermode: subagent,model: opencode-go/deepseek-v4.1-flash(semtemperature— não fixada na intenção), mesmapermission; corpo idem +DEGRADEDobrigatório e "nunca certifica".docs/AGENT-OPS.md: 1 parágrafo no fluxo (decisão 5).docs/changelog/2026-09-15-ops113.md(novo): linha única no formato vigente, sem citar o nome antigo da doutrina (o grep da verificação precisa zerar nos arquivos da entrega).- Migration: sem migration — docs/config puro. Access/Consent: N/A. UI: Impeccable A — sem UI de produto; nenhum arquivo em
src/é tocado.
Dados → forma (se aplicável)
- N/A — sem dados. O plano de intenção já declara "sem dados de produto" e os literais desta entrega são de configuração de agente/doutrina (modelos, modos, temperatura, caminhos), não de apresentação.
Fases verificáveis
- F1 — Doutrina (rename + reescrita) — quota ~35%.
git mv .agents/skills/plan-issue/ui-draft-html.md .agents/skills/plan-issue/ui-design-html.md(rename puro), depois reescrever o conteúdo: título/papel elevados, fonte de verdade do port, teto mantido item a item com o ajuste do GATE (JS mínimo de apresentação — decisão 6), artefato + assets SVG, modos Criar/Criticar, ladder com os 4 slugs +DEGRADED+ registro do tier + "nunca pula em silêncio", gate (abrir o HTML, iterar, confirmação explícita antes do register). Não editar consumidores do nome antigo (OPS114) nem o sufixo do painel (OPS116).- Prova:
git diff --stat -Mmostra o rename; leitura final da doutrina contra a checklist de teto/elevação.
- F2 — Agentes — quota ~25%.
- Criar
designer.mdedesigner-degraded.mdcom os literais (frontmatter + permission) e prompts enxutos (doutrina como fonte única; visão nativa/fail-closed;DEGRADEDno degradado). - Prova:
opencode agent listem processo novo listadesigner (all)edesigner-degraded (subagent)e mostra o ruleset* deny→docs/plans/*-ui-design* allowresolvido.
- Criar
- F3 — Operacional + verificação — quota ~40%.
- Parágrafo em
docs/AGENT-OPS.md; smokes em subprocesso (deny/allow) com limpeza dos arquivos de smoke; grep do nome antigo; prettier; changelog;pnpm gate:fast;pnpm push→ PRCloses #1056(basemain) comDesign tier:+ evidência dos smokes no body.
- Parágrafo em
Verificação
- Pré-requisito (antes do pin):
opencode models | grep '^openai/'listaopenai/gpt-5.6-sol(eopenai/gpt-6-astra);opencode-go/deepseek-v4.1-flashedeepseek/deepseek-flashexistem — verificado em 2026-09-15. Se o id fixado não existir: parar e escalar o humano — nunca pinar adivinhação nem trocar de modelo em silêncio. opencode agent list(processo novo — config não é hot-reloaded) mostra os dois agentes com os modos corretos e o ruleset de escrita fail-closed.- Smoke de permissão (subprocesso, fresh): grava
docs/plans/ops113-ui-design-smoke.html(permitido) e temwriteemsrc/ops113-smoke.txtnegado (deny duro, nãoask). Odesignerroda com--agent designer; odesigner-degraded(subagente não é primário — o CLI cai no default) é lançado via task a partir de um run dobuild. Saída colada no PR;rmdos arquivos de smoke antes do commit — nada de artefato-lixo no diff. - Grep do nome antigo (zero nos arquivos da entrega):
grep -rn "ui-draft-html" .agents/skills/plan-issue/ui-design-html.md .opencode/agent/designer.md .opencode/agent/designer-degraded.md docs/AGENT-OPS.md docs/changelog/2026-09-15-ops113.md→ vazio (o próprio-impl.mdcita o nome antigo como registro do rename e por isso fica fora do grep). Consumidores restantes = dívida do OPS114; sufixo do painel = OPS116. pnpm exec prettier --checknos tocados (.opencode/edocs/não são ignorados): os dois agentes,docs/AGENT-OPS.md,docs/changelog/2026-09-15-ops113.mde este-impl.md. A doutrina está em.agents/(ignorada) — mantê-la formatada por consistência.pnpm gate:fast(lint + typecheck + unit) verde;pnpm push(ensure-deps + gate:ci) e PRCloses #1056com CI verde. Sem migration; sem mudança emsrc/.
Rabbit holes / Não escopo (engenharia)
- OPS114 (consumidores do nome antigo e rename de campo
Rascunho UI:→Design UI:):.agents/skills/plan-issue/SKILL.md,intention-template.md,shaping.md,skills-map.md— não tocar. - OPS115 (triggers do designer no
work-issue/agent-work-issue, mecanismo do fail-closed/auto-merge do PR degradado) — não tocar. - OPS116 (retrocompat do painel ao sufixo
-ui-design.html;scripts/lib/issues-panel.mjsescripts/issues-tui.mjs) — não tocar. designer-astra.mdnão é criado (pergunta B da intenção assumida: tier 2 por troca de modelo); nenhum arquivo extra para o tier 4 inline.- "Já que pode JS, faz o protótipo funcional." Se alguém "só completar": fetch, persistência, validação de formulário, cálculo de produto, roteamento. Corte neste item: JS só de apresentação (modal/tab/toggle/accordion, sem rede e sem estado de produto) — decisão 6.
- Nada de UI de produto/
src/; nada no MCPpenpot; planos/changelog históricos imutáveis;.opencode/commands/intocado (a proibição demodel:do OPS101 segue valendo lá); pool dormente; sem migration; sem guard/teste novo lendo.opencode/agent/*.md(fora de escopo explícito da intenção); não ressuscitardesign-vision(OPS105) nem renderizador de PNG.
Riscos e mitigação
- Pinar id não exposto pelo OAuth. Pré-requisito verificado em 2026-09-15; mitigação: revalidar no início da execução; se sumir, fail-closed — parar e escalar, sem troca silenciosa.
- Certificação degradada por atalho.
DEGRADEDobrigatório no artefato + output, linhaDesign tier:no PR, sign-off humano; os prompts dizem "nunca certifica". - Teto protetivo relaxado demais (brand/tokens/JS viram implementação). A doutrina mantém o teto explícito (JS só de apresentação, sem lógica de negócio/rede/persistência — decisão 6) e a proibição de
src/; apermissionfail-closed é o stop duro. - Drift entre os dois prompts. Doutrina como fonte única; prompts enxutos que apontam para ela (decisão 3).
- Referências quebradas ao nome antigo entre F1 e OPS114. Dívida declarada e aceita; o grep da verificação garante que esta entrega não adiciona novas.
- Matching de caminho na
permission. Se o padrão não casar o que o edit tool envia, o efeito é falso-deny (fail-closed) e o smoke acusa — corrigir o padrão antes do merge. bashfora do gate. Resíduo declarado na decisão 1; proibição no prompt + supervisão humana; o smoke só promete o gate dos file tools.- Lixo de smoke no PR. Limpeza explícita antes de
git status/commit; diff final só com os arquivos da entrega. - Prettier vermelho em
.opencode/. Rodarprettier --writenos tocados; frontmatter com description longa passa como o precedente. - Sem hot reload. Qualquer prova de agente é subprocesso novo (
opencode run), nunca a sessão atual.
Débitos da triagem pós-simplify (2026-09-15)
- Já resolvido no simplify/critique (não reabrir): S4 (prova dos smokes vai no body do PR); S6–S12 (commit
refactor(OPS113): prompts enxutos anti-drift, permission estreitada ao artefato,descriptioncitada, roteamento de visão, posição no AGENT-OPS, duplicações da doutrina/grep). - Registrado: S1 —
bashfora do gate de escrita dos agentes → OPS117 (#1063),depends OPS113, planodocs/plans/ops117-guard-bash-agentes-design.md(nasceblocked; promove no merge comRelated #1063). - Absorvido: S3 — guardrail do plano OPS114 (
docs/plans/ops114-plan-issue-design-hifi-no-gate.md) alinhado ao teto de JS do GATE 2026-09-15 (JS só de apresentação; anti-goal "não é protótipo funcional" segue). - Descartados: S2 — o fail-closed do tier degradado (inclusive tier 4 inline) já é aceite/fase do OPS115 (#1058), não reabrir; S5 —
.agents/fora do prettier é convenção pré-existente (.prettierignore). Défer com gatilho: nenhum.
Aceite de engenharia
- Aceite de produto da intenção coberto: os dois agentes existem e são invocáveis com os literais pinados; doutrina viva
ui-design-html.mdcomo fonte de verdade; ladder documentada com tier registrado eDEGRADEDsem certificação; pré-requisito verificado. - Invariantes AGENTS/engineering-standards: sem tocar
src/; sem migration (push: falseirrelevante — nada de schema); dono editado (doutrina renomeada, sem twin); precedentes reusados (designer-campanha-solla.md,agent.<nome>.permissiondoopencode.json); identificadores de código em inglês e texto de prompt/admin em pt-BR. - Testes de domínio (unit/int): N/A justificado — nenhum access/write path de app muda; a prova é o smoke de permissão (evidência no PR), e guard/teste novo lendo
.opencode/agent/*.mdestá explicitamente fora de escopo.
Self-score decision-quality: 5/5 — (1) as 5 decisões caras têm opções e rejeitadas registradas (gate fail-closed, git mv, doutrina-fonte-única, ladder/tier, AGENT-OPS); (2) cabe no appetite herdado: 4 arquivos + changelog, sem código e sem src/; (3) rabbit holes nomeados (twin de agente, src/, consumidores OPS114/OPS116, sandbox de bash); (4) depth check: edita o dono da doutrina (rename, sem par), reusa o precedente de frontmatter/visão e o precedente de permission por agente — nenhum módulo, helper ou arquivo extra; (5) o aceite de produto da intenção permanece intacto — a engenharia só escolheu a forma (allowlist, prompts enxutos, onde o tier é registrado).