Skip to content

TEST: exercitar o design-diff #8

TEST: exercitar o design-diff

TEST: exercitar o design-diff #8

Workflow file for this run

name: Design drift
# Audita se o código traduziu o design corretamente. As regras não vão no
# prompt: o CLAUDE.md faz @design/DESIGN-SYSTEM.md, então a action carrega o
# guia inteiro sozinha. O prompt só nomeia o que auditar e onde reportar.
on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
paths:
- "app/**"
- "components/**"
- "design/**"
- "scripts/**"
- ".github/workflows/design-drift.yml"
permissions:
contents: read
pull-requests: write
issues: read
id-token: write
concurrency:
group: design-drift-${{ github.event.pull_request.number }}
cancel-in-progress: true
env:
PEN_FILE: design/pendev/youtube-channel.pen
jobs:
audit:
if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 22
- name: Instalar pen.dev CLI
run: npm install -g @pen.dev/cli && pen version
# Três evidências, todas textuais. Nenhum PNG: render do design sem render
# da app é comparação de um lado só. E a tool `browser` do pen, que
# fecharia o loop carregando a app, exige o app desktop e não roda aqui.
#
# components.html geometria/tipografia RESOLVIDA em px (só tema claro)
# components.json qual token o design usa (nome do token)
# tokens.json o que cada token vale em light e dark
# screens.json composição das telas: quais componentes, em que ordem
#
# As telas não são `reusable`, então ficariam fora das três primeiras —
# sem screens.json o audit cobre componente e não cobre página.
#
# O HTML existe para o agente não ter que resolver $radius-sm -> 8px
# sozinho — errar essa resolução é literalmente a regra 3 do audit.
- name: Extrair design
env:
PEN_CLI_KEY: ${{ secrets.PEN_CLI_KEY }}
run: |
mkdir -p /tmp/design
jq -S '{themes, variables}' "$PEN_FILE" > /tmp/design/tokens.json
jq -S '[.. | objects | select(.reusable == true)] | sort_by(.name)
| map(walk(if type == "object" then del(.id, .x, .y) else . end))' \
"$PEN_FILE" > /tmp/design/components.json
NODES=$(jq -r '[.. | objects | select(.reusable == true) | .name] | join(";")' "$PEN_FILE")
PEN_NODES="$NODES" ./scripts/pen-export.sh \
"$PEN_FILE" /tmp/design/components.html 1 html-tailwind
./scripts/pen-outline.py "$PEN_FILE" > /tmp/design/screens.json
ls -la /tmp/design
# Seis das nove regras são regex sobre o diff. Rodá-las aqui é
# determinístico e grátis; o agente entra só para verificar e julgar.
- name: Pré-análise mecânica
env:
PEN_FILE: design/pendev/youtube-channel.pen
run: ./scripts/drift-scan.sh "origin/${{ github.base_ref }}" | tee /tmp/design/scan.txt
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
prompt: |
Audite drift entre o design e o código neste PR.
As regras estão em design/DESIGN-SYSTEM.md, já carregado via CLAUDE.md.
SIGA ESTA ORDEM. Ela existe para você não gastar turnos:
1. Leia /tmp/design/scan.txt PRIMEIRO. A varredura mecânica já rodou
sobre o diff e listou as ocorrências das regras 1, 2, 4, 5, 6, 8,
os radius da 3, e os data-component sem frame no .pen (metade da
7). Se uma seção não aparece lá, essa regra passou: NÃO a
reinvestigue, e não abra arquivo para reconferir o que ela cobre.
2. Para cada ocorrência listada, abra só aquele arquivo e confirme
se é violação de verdade ou uso correto.
3. Só então cheque as regras 7 e 9, que exigem comparar com o design.
NUNCA use Read em /tmp/design/components.html: são 107KB e vai
estourar seu contexto. Use grep com data-pencil-name="<nome>".
Evidência disponível, cada uma autoridade sobre uma coisa:
- /tmp/design/components.html — cada componente com geometria e
tipografia JÁ RESOLVIDAS em px, marcado com data-pencil-name.
Grepe por data-pencil-name="Chip" para achar um componente.
Use para conferir NÚMEROS: 32px de altura, 8px de radius, 14/20 de
texto. Só tem tema claro. NUNCA copie código daqui: a saída é
achatada (hex cru, px absoluto) e viola as regras 1, 2 e 9.
- /tmp/design/components.json — qual TOKEN o design usa em cada
propriedade ($radius-sm, $surface-chip). Use quando a pergunta for
"qual token deveria estar aqui".
- /tmp/design/tokens.json — o que cada token vale em light E dark.
Autoridade sobre cor e tema; o CSS do repo é transcrição e pode
estar errado.
- /tmp/design/screens.json — a COMPOSIÇÃO de cada tela: quais
componentes, em que ordem, dentro de que container, com que gap e
padding. É contra isto que os arquivos em app/ devem bater.
Conteúdo instanciado (títulos, thumbnails) foi podado de
propósito: aquilo é fixture, não design.
Escopo — decida pelo que mudou:
git diff --name-only origin/${{ github.base_ref }}...HEAD
- Mudou código (app/, components/): audite os arquivos alterados.
- Mudou SÓ o design (design/pendev/): o código não mudou, mas pode
ter ficado defasado. Compare o que mudou no .pen contra os
componentes React correspondentes, mesmo que eles não estejam no
diff. Este é o caso que mais escapa em review.
- Mudaram os dois: faça as duas coisas.
Procure exatamente estas dez falhas — todas compilam e parecem
certas, por isso passam em review:
1. Cor crua em className (`#`, `rgb(`, `hsl(`) — quebra o tema escuro
2. Qualquer variante `dark:` — significa token semântico faltando
3. Radius traduzido pelo nome em vez do valor. Os nomes do .pen estão
deslocados um degrau: $radius-sm é 8px e vira rounded-lg, não
rounded-sm. Confira contra a tabela do §6.
4. `p-14` onde o design pede $space-14 (58px, não os 56px de p-14)
5. `text-lg`/`text-sm` usados achando que batem com o .pen
(font-size-lg é 16px; text-lg do Tailwind é 18px)
6. Altura fixa em thumbnail (`h-[201px]`) em vez de aspect-video
7. Token ou componente que não existe em tokens.json nem no .pen.
Exceção única: estados de interação e foco (§9).
8. Prop `className` exposta em componente (§7)
9. Página que não bate com screens.json: componente faltando, ordem
trocada, container com gap ou padding diferente. Atenção ao
Header Region, que usa $space-14 — 58px, não os 56px de p-14.
10. Componente cujos valores DIVERGEM do design. Esta é a definição
de drift e a mais importante da lista: o componente existe, o
nome está certo, e uma propriedade não bate — padding, gap,
altura, cor, tipografia. Confira contra components.html (px já
resolvido) e components.json (o token). Vale mesmo quando o
.tsx não está no diff: se o scan disser que o design mudou, o
código correspondente está defasado até prova em contrário.
Para cada achado, poste comentário inline na linha exata, com a regra
violada e a correção, citando a seção do DESIGN-SYSTEM.md.
Comentário inline só cola em linha que está no diff: se o arquivo
defasado não mudou neste PR, comente na linha do .pen que causou a
divergência, nomeando o arquivo e a linha do código.
Se não houver achado, não poste nada.
Não reporte estilo, nomes ou arquitetura fora dessas dez.
claude_args: |
--max-turns 60
--allowedTools "mcp__github_inline_comment__create_inline_comment,Read,Grep,Glob,Bash(git diff:*),Bash(git log:*),Bash(git show:*),Bash(jq:*),Bash(diff:*),Bash(comm:*),Bash(sed:*),Bash(head:*),Bash(tail:*),Bash(wc:*),Bash(ls:*)"