Merge pull request #72 from fsolla/cursor/agent-pr-automerge-safety-net-df16

OPS: Ready+auto-merge for all agent PRs (audit included)
This commit is contained in:
Francisco Solla 2026-08-01 00:57:32 -03:00 committed by GitHub
commit e61e80b6dc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 57 additions and 10 deletions

View file

@ -29,7 +29,7 @@ When the environment says to use `ManagePullRequest` instead of `gh pr create`:
- **`draft: false`** (or omit only if the tool’s default is Ready — today Cloud defaults to draft, so **always pass `draft: false`**).
- Right after create (or on `update_pr` if you opened draft by mistake): mark Ready if still draft, then enable auto-merge with `gh pr merge --auto --merge <url|number>` (write allowed for this step — same as `agent-pr-workflow`; do not leave the PR waiting on a human).
- Never end a turn with an open agent PR left as **Draft** or without **auto-merge** armed (exception: `engineering-audit` sign-off PR only — see that skill).
- Never end a turn with an open agent PR left as **Draft** or without **auto-merge** armed — inclui PRs do `engineering-audit` (artefatos e remediações).
## Push (determinístico)
@ -80,6 +80,6 @@ All branches skip Vercel Git builds via `scripts/vercel-ignore-build.sh` (deploy
There is no stage→main promote. Merging to `main` is the delivery; `ci.yml` verifies and deploys.
## Exception (narrow)
## Safety net (GitHub Action)
`engineering-audit` artifact PR: Ready, **no** auto-merge — human merge is the sign-off. All other agent PRs (work-issue, pool workers, chores, docs) use auto-merge.
`agent-pr-ready-automerge.yml` — PRs `cursor/*` → `main`: se Draft → `gh pr ready`; sempre arma `gh pr merge --auto --merge`. Cobre o caso em que o agente (ou o default draft do Cloud) esqueceu. Não há opt-out por skill (audit incluído).

View file

@ -1,6 +1,6 @@
---
name: engineering-audit
description: Runs a Pass-style engineering audit of the Teqo codebase — code smells, drift from documented patterns, and consolidation of near-duplicate components/hooks/functions/modules — producing a findings ledger and a remediation plan (read-only on code during the sweep; sign-off = apresentação interativa ou o PR dos artefatos em Cursor Cloud; remediações P0/P1 e guardrails de agent-miss executados na mesma sessão). Use when the user asks for an engineering audit, code-smell sweep, architecture drift check, deduplication/consolidation pass, "Pass 3", "auditoria de engenharia", "varredura de code smells", "consolidação de duplicações", or to plan fixes against the repo's highest engineering standards.
description: Runs a Pass-style engineering audit of the Teqo codebase — code smells, drift from documented patterns, and consolidation of near-duplicate components/hooks/functions/modules — producing a findings ledger and a remediation plan (read-only on code during the sweep; sign-off interativo = apresentação prévia; autônomo = PR Ready + auto-merge dos artefatos; remediações P0/P1 e guardrails de agent-miss na mesma sessão). Use when the user asks for an engineering audit, code-smell sweep, architecture drift check, deduplication/consolidation pass, "Pass 3", "auditoria de engenharia", "varredura de code smells", "consolidação de duplicações", or to plan fixes against the repo's highest engineering standards.
---
# Engineering Audit (Pass N)
@ -12,11 +12,11 @@ description: Runs a Pass-style engineering audit of the Teqo codebase — code s
A skill roda sem supervisão humana no paradigma de agentes paralelos. Quatro diferenças em relação à execução interativa (desktop):
1. **Precheck solitário, fail-closed.** Antes de qualquer varredura: `pnpm agent:pool -- status` (read-only). Pool `desligado` ou `pausado` → segue. Pool **ligado** → o agente Cloud não consegue pausá-lo (`gh workflow run` é escrita): **pare** com o remédio nomeado ("pause o pool — `pnpm agent:pool -- pause` — e re-dispare o audit"). Nunca rodar a varredura com o pool spawnando.
2. **Sign-off = PR.** O gate "apresentar os três artefatos antes de escrever" (passo 5) não se aplica em modo autônomo — não há humano interativo na sessão. Os artefatos são escritos na branch e o **PR (Ready, base `stage`) é a superfície de sign-off**: merge humano = aprovação do plano; fechar o PR = rejeição (o ledger sobrevive no histórico da branch). As remediações **P0/P1 e os guardrails das misses colhidas não esperam esse sign-off** — são correctness/active-harm e seguem na mesma sessão, cada um em PR próprio com gate completo. P2/P3 continuam só ledger/plano.
3. **Canais de PR:** fechar miss colhida = `Closes #N` no body do PR do guardrail (o flip `done`/`in-prod` no merge em `main` — keyword adjacente a cada número, `Closes #52, closes #73`, nunca `Closes #52, #73`). Em Cloud, preferir `ManagePullRequest` com **`draft: false`**. **Exceção só deste skill:** o PR dos *artefatos* do audit (sign-off) fica Ready **sem** auto-merge — merge humano = aprovação do plano. Remediações P0/P1 e guardrails de misses na mesma sessão seguem o fluxo normal (`agent-pr-workflow`: Ready + `gh pr merge --auto --merge`). Push: `pnpm push -u origin HEAD`.
2. **Entrega = PR Ready + auto-merge.** O gate "apresentar os três artefatos antes de escrever" (passo 5) não se aplica em modo autônomo — não há humano interativo na sessão. Os artefatos são escritos na branch e o **PR Ready → `main` com auto-merge** (mesmo contrato `agent-pr-workflow`) é a entrega do plano. Fechar o PR antes do merge = rejeição (o ledger sobrevive no histórico da branch). As remediações **P0/P1 e os guardrails das misses colhidas** seguem na mesma sessão, cada um em PR próprio com gate completo + auto-merge. P2/P3 continuam só ledger/plano.
3. **Canais de PR:** fechar miss colhida = `Closes #N` no body do PR do guardrail (o flip `done`/`in-prod` no merge em `main` — keyword adjacente a cada número, `Closes #52, closes #73`, nunca `Closes #52, #73`). Em Cloud, preferir `ManagePullRequest` com **`draft: false`**, depois `gh pr merge --auto --merge`. **Sem exceção:** o PR dos *artefatos* do audit também é Ready + auto-merge (igual remediações P0/P1 e guardrails). Push: `pnpm push -u origin HEAD`.
4. **Delta desde o último audit é o foco declarado** (passo 1): a varredura cobre o repo inteiro, mas o esforço concentra-se no churn desde a data do último Pass — é o trabalho paralelo dos agentes desde o último audit que precisa ser consolidado.
Read-only audit that sweeps the Teqo codebase for code smells, drift from documented patterns, and consolidation opportunities, then produces a findings ledger and a remediation plan. **No fixes in the audit run** — deliverables are updated docs, presented for sign-off before writing — exceto as remediações P0/P1 declaradas acima. Sign-off: interativo = apresentação prévia dos artefatos; autônomo (Cursor Cloud) = o PR dos artefatos (ver "Modo autônomo (Cursor Cloud)").
Read-only audit that sweeps the Teqo codebase for code smells, drift from documented patterns, and consolidation opportunities, then produces a findings ledger and a remediation plan. **No fixes in the audit run** — deliverables are updated docs, presented for sign-off before writing — exceto as remediações P0/P1 declaradas acima. Sign-off: interativo = apresentação prévia dos artefatos; autônomo (Cursor Cloud) = PR Ready + auto-merge dos artefatos (ver "Modo autônomo (Cursor Cloud)").
Method: the engineering skills this repo follows (improve-code-quality, clean-code, refactoring-patterns, software-design-philosophy, pragmatic-programmer, working-with-legacy-code, remove-technical-debt), specialized to Teqo's standards and history. The pass number is the next one after the last in `docs/IMPROVE-CODE-QUALITY-PLAN.md`.
@ -166,7 +166,7 @@ Rules:
1. `docs/IMPROVE-CODE-QUALITY-PLAN.md` — new Pass section (context, audit headlines with numbers, workstreams, decisions), matching earlier-pass format.
2. `docs/TECH-DEBT.md` — new rows in the same tables/columns, marked `open — Pass N`; stale rows closed with evidence.
3. `docs/plans/entrega-engenharia-pN.md` (pt-BR, like the other plans) — workstreams ordered P0→P1→P2; each item: goal, evidence, target shape, migration path (Branch by Abstraction / Parallel Change for wide merges), pins to write first, full gate, rollback. Items too big for one delivery → Issue rastreável via `plan-issue`. Every workstream item declares its **Guarda determinística** (class 1–6, step 4b), and the plan carries a **guard map** section: new guards shipped / existing guards hardened / judgment-only residue with the convention that stands in.
4. **Interativo (desktop):** present ALL THREE for sign-off before writing. Then write and stop. **Autônomo (Cursor Cloud):** não há sign-off interativo — escreva os três na branch e abra o PR (**Ready**, base `main`, **sem** auto-merge — merge humano = sign-off; "Modo autônomo", item 2). As remediações P0/P1 e os guardrails das misses colhidas seguem na mesma sessão, em PRs próprios com gate completo + auto-merge normal, sem esperar esse merge.
4. **Interativo (desktop):** present ALL THREE for sign-off before writing. Then write and stop. **Autônomo (Cursor Cloud):** não há sign-off interativo — escreva os três na branch e abra o PR (**Ready**, base `main`, **`gh pr merge --auto --merge`** — mesmo fluxo `agent-pr-workflow`; "Modo autônomo", item 2). As remediações P0/P1 e os guardrails das misses colhidas seguem na mesma sessão, em PRs próprios com gate completo + auto-merge, sem esperar o merge dos artefatos.
## Execution rules for the eventual implementation (record in the plan)

View file

@ -0,0 +1,44 @@
# Safety net: agent PRs (cursor/* → main) must be Ready + auto-merge.
# Covers Cloud ManagePullRequest defaulting to draft and agents that forget
# `gh pr merge --auto --merge`. No skill opt-out (engineering-audit included).
name: Agent PR Ready + auto-merge
on:
pull_request:
types: [opened, reopened, synchronize, ready_for_review, converted_to_draft]
branches: [main]
permissions:
contents: write
pull-requests: write
jobs:
ready-automerge:
if: >-
github.event.pull_request.state == 'open' &&
startsWith(github.event.pull_request.head.ref, 'cursor/')
runs-on: ubuntu-latest
timeout-minutes: 5
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number }}
steps:
- name: Mark Ready and enable auto-merge
run: |
set -euo pipefail
is_draft="$(gh pr view "$PR_NUMBER" --repo "$GITHUB_REPOSITORY" --json isDraft --jq .isDraft)"
if [ "$is_draft" = "true" ]; then
echo "PR #$PR_NUMBER is draft — marking Ready"
gh pr ready "$PR_NUMBER" --repo "$GITHUB_REPOSITORY"
else
echo "PR #$PR_NUMBER already Ready"
fi
# Arm auto-merge (idempotent when already enabled; fails only on hard blocks).
if gh pr merge --auto --merge "$PR_NUMBER" --repo "$GITHUB_REPOSITORY"; then
echo "Auto-merge armed for PR #$PR_NUMBER"
else
# Already merged / already armed / race — succeed only if request exists or merged.
armed="$(gh pr view "$PR_NUMBER" --repo "$GITHUB_REPOSITORY" --json autoMergeRequest,state --jq '(.autoMergeRequest != null) or (.state == "MERGED")')"
echo "gh pr merge --auto exited non-zero; armed_or_merged=$armed"
[ "$armed" = "true" ]
fi

View file

@ -61,6 +61,7 @@ main → ci.yml full suite → vercel deploy --prod (se verde) → requeue se HE
| `ci-pr.yml` | PR → `main` | service Postgres 17 | Fase 1 barata → fase 2 cara; skips via `ci-scope.mjs`; rollup `checks` |
| `ci.yml` | push / dispatch `main` | service Postgres | Full sempre → `deploy` (`vercel deploy --prod`) → `requeue` se HEAD andou |
| `issue-done-on-main-merge.yml` | PR merged → `main` | — | `in-progress` → `done` + `in-prod` |
| `agent-pr-ready-automerge.yml` | PR `cursor/*` → `main` (open/sync/…) | — | Draft→Ready + `gh pr merge --auto --merge` (safety net; audit incluso) |
| `agent-pool.yml` | schedule / PR closed `main` / dispatch | — | Supervisor do pool (`POOL_GITHUB_TOKEN`) |
Fast gate: `pnpm gate:fast`. Push: `pnpm push`.

View file

@ -4,6 +4,8 @@ Conteúdo movido do `AGENTS.md` em 2026-07-30 (fatiamento do paradigma de agente
---
**Recently resolved (2026-08-01):** **PRs de agente = Ready + auto-merge (audit incluso)** — removida a exceção do `engineering-audit` (artefatos também armam `gh pr merge --auto --merge`). Safety net GHA `agent-pr-ready-automerge.yml`: PRs `cursor/*` → `main` Draft→Ready + auto-merge. Rule always-on `agent-pr-workflow.mdc`.
**Recently resolved (2026-07-31):** **Cloud `ensure-postgres` falso negativo no start** — o script tratava “role/DBs `teqo` prontos” como “Postgres aceitando conexões”. Em snapshot warm o cluster já está `online` sem role/DBs; `start_postgres` falhava com `postgres is installed but not accepting connections` **antes** de `bootstrap_databases`, o `start` do `environment.json` saía ≠0 e a UI marcava `INSTALL_FAILED` mesmo com o agente utilizável. Fix: separar `server_ready` (`pg_isready` / peer) de `teqo_ready`, bootstrap após o server up, retry no wait; `cloud-setup.sh` pina `DATABASE_URL` e asserta `payload_migrations` pós-migrate (no-op silencioso visto no JIT). Ruído cosmético no mesmo log (dirs de recording, `.installed` de plugins ENOENT) é race do exec-daemon — não é do Teqo.
**Recently resolved (2026-07-31):** **Pass 4 — auditoria de engenharia autônoma + guardrails das misses** — primeira execução em modo autônomo (Cursor Cloud) da skill engineering-audit, com precheck solitário (pool desligado) e primeiro harvest de `kind:agent-miss` (escopo OPS2: nasce `docs/GUARDRAILS.md`). **P0:** os 4 globals públicos (`site-settings`/`home`/`metadata`/`privacy-policy`) aceitavam qualquer autenticado no `update` — JWT de campanha (liderança inclusa) editava o site público via `/api/globals/*`; lockdown `payloadAdminOnly` + pins + guarda ([PR #91](https://github.com/fsolla/teqo/pull/91); editores perdem escrita nos globals de config deliberadamente). **P1:** `seed-posts.mjs` chamava `dieWithLabel` sem importar ([PR #92](https://github.com/fsolla/teqo/pull/92), com guarda de presença de import + `DAY_MS` single-source + ESLint lib→utilities sem type-import + guarda de `overrideAccess` omitido). **Misses:** #73 (deadlock `municipality_rels` — classe reproduzida: 7 violações int + 11 deep links e2e; migração para o alocador com teste de classe reescrito classe-agnóstico + guarda de 3 regras, [PR #93](https://github.com/fsolla/teqo/pull/93)); #52 (Drawer por célula em 3 listas de chips → `CampaignListSheetProvider` + invariante dev + guarda, [PR #94](https://github.com/fsolla/teqo/pull/94)); #53 (portão de readiness do autenticador virtual) + #54 (guarda de goto não assentado + convenção TESTING.md) em [PR #95](https://github.com/fsolla/teqo/pull/95); #83 fechada (guarda `agent:ship` já viva). **Registrado, não retry-fixed:** spec de chips de `campaignLeaderships` falha deterministicamente em dev na árvore limpa (nenhum POST dispara; prod 48/48 verde) — causa raiz via debug workflow (P4-L). Artefatos: seção Pass 4 no plano de qualidade, 15 linhas novas no ledger (2 stale fechadas: P3-A/P3-B), plano [`entrega-engenharia-p4.md`](docs/plans/entrega-engenharia-p4.md) com ondas P4-A→P4-L + mapa de guardas + defer+gatilho.

View file

@ -208,6 +208,6 @@ Statuses: pending · in-progress · awaiting-evidence · done · deferred: \<rea
## Next Actions
- [ ] Human sign-off = merge of the artifacts PR (plan + ledger + GUARDRAILS.md); remediation PRs merge independently
- [x] Artifacts PR = Ready + auto-merge (mesmo contrato `agent-pr-workflow`; sem exceção de merge humano); remediation PRs merge independently
- [ ] P4-A → P4-L as independent deliveries ([entrega-engenharia-p4.md](plans/entrega-engenharia-p4.md)); oversized items → Issue rastreável via `plan-issue`
- [ ] Leftovers → ledger via `capture-review-debts`

View file

@ -2,7 +2,7 @@
## Contexto e manchetes
- **Executado em 2026-07-31, no modo autônomo (Cursor Cloud)** da skill `engineering-audit`: precheck solitário verde (`agent:gh-doctor` OK; pool **desligado**), varredura completa, remediações P0/P1 e guardrails das misses colhidas na mesma sessão, cada um em PR próprio com gate completo. O sign-off dos artefatos é o merge humano deste PR.
- **Executado em 2026-07-31, no modo autônomo (Cursor Cloud)** da skill `engineering-audit`: precheck solitário verde (`agent:gh-doctor` OK; pool **desligado**), varredura completa, remediações P0/P1 e guardrails das misses colhidas na mesma sessão, cada um em PR próprio com gate completo. **Política atual (2026-08-01):** o PR dos artefatos também é Ready + auto-merge — não há mais exceção de merge humano para audit.
- **Âncora de delta:** Pass 3 (2026-07-28). Em 3 dias o paradigma de agentes tocou **880 arquivos** — homeSearch (8 módulos + ~20 componentes), notificações/push (2 collections + 5 módulos), wizard (~12 componentes), WebAuthn (4 rotas + 4 módulos), 5 migrations. A varredura cobriu o repo inteiro com esforço concentrado no delta.
- **Baseline verde:** `tsc` 0 erros, `lint` 0 warnings, `knip` 0 findings (ruído conhecido do `payload.config.ts`, ledger P3), madge 0 ciclos (**774 arquivos**, +124 desde o Pass 3).
- **Manchetes (todas medidas):**