docs(OPS68): reescreve docs canônicos da era GitHub/Vercel para Forgejo/homeserver
Parte 2 do OPS50 (fechamento): AGENT-OPS, README, roadmap (ponteiro), AGENTS.md (refs Neon/job gate), rule agent-pr-workflow e 8 skills de operação sem comandos gh (API/MCP + safety net) nem secrets Vercel — fonte canônica única: git.solla.dev/fsolla/teqo.
This commit is contained in:
parent
cc6149191b
commit
3ca2cbd438
15 changed files with 166 additions and 84 deletions
|
|
@ -11,13 +11,15 @@ alwaysApply: true
|
|||
|
||||
```bash
|
||||
pnpm push -u origin HEAD
|
||||
gh pr create --base main --title "<id> — <title>" --body "$(cat <<'EOF'
|
||||
```
|
||||
|
||||
Depois, abra a PR via API/MCP do opencode (humano) ou `ManagePullRequest` (Cursor Cloud) — **Ready**, base **`main`**, title `<id> — <title>`, body:
|
||||
|
||||
```
|
||||
## O que é
|
||||
<2–4 linhas>
|
||||
|
||||
Closes #<N>
|
||||
EOF
|
||||
)"
|
||||
```
|
||||
|
||||
- **Never** `--draft`. PRs must be **Ready for review** on creation.
|
||||
|
|
@ -26,11 +28,9 @@ EOF
|
|||
|
||||
### Cursor Cloud / `ManagePullRequest`
|
||||
|
||||
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 --rebase <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 — inclui PRs do `engineering-audit` (artefatos e remediações).
|
||||
- Não há auto-merge a armar por PR: o safety net (abaixo) espera o rollup `checks` e mergea sozinho.
|
||||
- Never end a turn with an open agent PR left as **Draft** — inclui PRs do `engineering-audit` (artefatos e remediações).
|
||||
|
||||
## Push (determinístico)
|
||||
|
||||
|
|
@ -48,13 +48,7 @@ git push --no-verify # WIP / cutover escape — CI repete tudo; ver AGENT-OPS
|
|||
|
||||
## Auto-merge immediately
|
||||
|
||||
Right after the PR exists and is **Ready**:
|
||||
|
||||
```bash
|
||||
gh pr merge --auto --rebase
|
||||
```
|
||||
|
||||
Do not wait for human approval on normal deliveries. Auto-merge fires when **required** checks pass.
|
||||
The safety net (`agent-pr-ready-automerge.yml`, abaixo) merges the PR when the required checks pass — there is nothing to arm per PR. Do not wait for human approval on normal deliveries.
|
||||
|
||||
## Required checks
|
||||
|
||||
|
|
@ -66,26 +60,22 @@ Branch protection on `main` (applied 2026-08-18, OPS61) requires only:
|
|||
|
||||
(`migration-lock` removed 2026-08-12 — the CI validates migration chains via migrate + int on every PR/main.)
|
||||
|
||||
**There is no deploy from CI.** The `ci.yml` verifier on `main` runs the full suite and stops (production is self-hosted on the homeserver — `jorgesolla1313.com.br` — deployed via an ops runbook outside this repo). Do not add a Vercel/Git-integration deploy gate.
|
||||
**There is no deploy from PR CI.** The `ci.yml` verifier on `main` runs the full suite in its fixed 30-minute window and, on a production change, the `deploy` job publishes to the homeserver (`jorgesolla1313.com.br`, self-hosted) — migrations applied before the rollout. Do not add a Vercel/Git-integration deploy gate.
|
||||
|
||||
When watching CI:
|
||||
When watching CI, use the PR page (or the API) — the safety net is what waits on checks; `gh` does not exist in this repo (OPS50).
|
||||
|
||||
```bash
|
||||
gh pr checks <PR> --watch --required
|
||||
```
|
||||
|
||||
Use `--required` — without it, `--watch` also waits for Vercel.
|
||||
Use the rollup context `CI (PR) / checks` — without it, you are not covering the cascade.
|
||||
|
||||
## Promote
|
||||
|
||||
There is no stage→main promote. Merging to `main` is the delivery; `ci.yml` verifies the full suite and production deploys from the homeserver runbook.
|
||||
There is no stage→main promote. Merging to `main` is the delivery; `ci.yml` verifies the full suite and, on a production change, deploys to the homeserver (OPS53/OPS65; runbook: `docs/ops/teqo-1313-deploy.md`).
|
||||
|
||||
## Safety net (workflow)
|
||||
|
||||
`agent-pr-ready-automerge.yml` — PRs same-repo → `main` (todas as branches).
|
||||
O workflow roda `scripts/forgejo-pr-automerge.mjs` (plain Node, zero-dep): se
|
||||
draft `cursor/*` → marca Ready; espera os checks e mergea por rebase (o
|
||||
equivalente Forgejo do `gh pr merge --auto --rebase`). O wait exige o rollup
|
||||
equivalente Forgejo do auto-merge — sem `gh`). O wait exige o rollup
|
||||
`CI (PR) / checks` POSTADO e verde (OPS61) — o único contexto que só existe
|
||||
quando a cascata inteira do ci-pr assentou (jobs ainda não agendados não
|
||||
postam status; o próprio status do job do safety net é `pending` durante o run
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
name: agent-pool
|
||||
description: >-
|
||||
Opera e monitora o pool de agentes Cursor Cloud do Teqo (supervisor remoto
|
||||
determinístico em GitHub Actions). Ao invocar: SEMPRE status + fila elegível
|
||||
determinístico em Forgejo Actions). Ao invocar: SEMPRE status + fila elegível
|
||||
primeiro; NUNCA liga o pool sem confirmação explícita do usuário. Usar quando
|
||||
o usuário pedir /agent-pool, ligar/desligar/pausar o pool, ver status dos
|
||||
workers, "pool de agentes", orquestrador, triage de Issue que o pool mandou
|
||||
|
|
@ -11,7 +11,11 @@ description: >-
|
|||
|
||||
# Agent pool — operação do supervisor remoto
|
||||
|
||||
O pool mantém até **5 Cursor Cloud Agents** (configurável, máx 12) rodando `agent-work-issue` sobre Issues `ready` elegíveis para autonomia. O supervisor é **determinístico** (não é um agente): workflow **`.github/workflows/agent-pool.yml`** (tick stateless a cada 10 min + a cada merge em `main` + sob dispatch) rodando `scripts/agent-pool.mjs`. Arquitetura e elegibilidade: `docs/plans/agent-pool-orchestrator.md`.
|
||||
**DORMENTE (OPS65):** o workflow `agent-pool.yml` foi removido (o tick `*/10`
|
||||
custava 144 `pnpm install`/dia na workstation) e o dispatch via CLI falha 404 —
|
||||
scripts/skill ficam para histórico e leitura. O que foi:
|
||||
|
||||
O pool mantém até **5 Cursor Cloud Agents** (configurável, máx 12) rodando `agent-work-issue` sobre Issues `ready` elegíveis para autonomia. O supervisor é **determinístico** (não é um agente): workflow `.forgejo/workflows/agent-pool.yml` (removido) com tick stateless a cada 10 min + a cada merge em `main` + sob dispatch, rodando `scripts/agent-pool.mjs`. Arquitetura e elegibilidade: `docs/plans/agent-pool-orchestrator.md`.
|
||||
|
||||
**O pool NUNCA deploya** — deploy gated fica em `ci.yml` após merge em `main`.
|
||||
|
||||
|
|
@ -19,7 +23,7 @@ O pool mantém até **5 Cursor Cloud Agents** (configurável, máx 12) rodando `
|
|||
|
||||
## Fluxo obrigatório ao invocar (não pule)
|
||||
|
||||
**Nunca** rode `pnpm agent:pool -- start` (nem `gh workflow run … action=start`) no primeiro passo. O default é só leitura.
|
||||
**Nunca** rode `pnpm agent:pool -- start` no primeiro passo — e o dispatch do workflow não existe mais (OPS65: `start`/`stop` via CLI falham 404). O default é só leitura.
|
||||
|
||||
```
|
||||
- [ ] 1. Pré-check leve: `pnpm agent:pool -- doctor` se for a 1ª vez na sessão / suspeita de secret; senão pode ir direto ao status
|
||||
|
|
@ -87,7 +91,7 @@ pnpm agent:pool -- resume
|
|||
pnpm agent:pool -- status # leitura local (config, slots, fila, exclusões)
|
||||
```
|
||||
|
||||
Os wrappers disparam `gh workflow run agent-pool.yml -f action=…`; acompanhe com `gh run list --workflow agent-pool.yml --limit 3` (o job summary de cada run é a superfície remota de status: slots, spawns, falhas, decisão do tick). Estado escalar vive em repo variables `POOL_*` (Settings → Variables); workers/Issues em voo são derivados — Issues `in-progress` com marcador `pool-worker` nos comentários.
|
||||
Os wrappers disparam `workflow_dispatch` em `agent-pool.yml` via API do Forgejo (workflow removido no OPS65 — dispatch falha 404); acompanhe com `pnpm agent:pool -- status` (o job summary de cada run era a superfície remota de status: slots, spawns, falhas, decisão do tick). Estado escalar vive em `pool-state.json` na branch `pool-state`; workers/Issues em voo são derivados — Issues `in-progress` com marcador `pool-worker` nos comentários.
|
||||
|
||||
## Ciclo de vida de uma Issue no pool
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
name: capture-review-debts
|
||||
description: Use when the user asks to register leftover /simplify or /impeccable findings as trackable GitHub Issues, harvest session review debts, triage post-simplify or post-critique follow-ups, or says "registra os débitos", "o que ficou do simplify", "coloca como issue o que o critique apontou", "harvest debts".
|
||||
description: Use when the user asks to register leftover /simplify or /impeccable findings as trackable Forgejo Issues, harvest session review debts, triage post-simplify or post-critique follow-ups, or says "registra os débitos", "o que ficou do simplify", "coloca como issue o que o critique apontou", "harvest debts".
|
||||
---
|
||||
|
||||
# Capturar débitos de /simplify e /impeccable em Issues
|
||||
|
|
@ -15,7 +15,7 @@ Após um ciclo de entrega, `/simplify` e `/impeccable` deixam achados **maiores
|
|||
|
||||
```
|
||||
- [ ] 1. Colher candidatos da sessão (simplify + impeccable)
|
||||
- [ ] 2. Deduplicar contra código, Issues (gh issue list) e planos
|
||||
- [ ] 2. Deduplicar contra código, Issues (`pnpm issue all`) e planos
|
||||
- [ ] 3. Pontuar importância e classificar destino
|
||||
- [ ] 4. Mesclar relacionados (mesmo lote / mesma superfície)
|
||||
- [ ] 5. Apresentar tabela de triage e obter confirmação
|
||||
|
|
@ -50,7 +50,7 @@ Contra o repositório **antes** de pontuar:
|
|||
| Check | Ação se verdadeiro |
|
||||
| ------------------------------------------------------ | --------------------------------------------------------------- |
|
||||
| Já no diff / código da sessão | → balde **já_resolvido** (não reabrir) |
|
||||
| Já em `docs/plans/*.md` ou numa Issue (grep + `gh issue list`) | → **absorver** no plano existente ou **descartar** como coberto |
|
||||
| Já em `docs/plans/*.md` ou numa Issue (grep + `pnpm issue all`) | → **absorver** no plano existente ou **descartar** como coberto |
|
||||
| Pré-existente em `main`, fora do escopo da entrega | → **descartar** deste lote (bug separado só se o usuário pedir) |
|
||||
| Intentional em `DESIGN.md` / decisão travada | → **descartar** (ex.: field-mode mobile documentado) |
|
||||
|
||||
|
|
|
|||
|
|
@ -11,9 +11,9 @@ 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.
|
||||
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 (dispatch de workflow é 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. **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 --rebase`. **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`.
|
||||
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, usar `ManagePullRequest` com **`draft: false`** (o merge fica com o safety net `agent-pr-ready-automerge`). **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) = PR Ready + auto-merge dos artefatos (ver "Modo autônomo (Cursor Cloud)").
|
||||
|
|
@ -39,7 +39,7 @@ Method: the engineering skills this repo follows (improve-code-quality, clean-co
|
|||
1. Read-only on `src/`, `tests/`, `scripts/` durante a varredura. Os únicos writes da sessão são: os artefatos do passo 5 (após sign-off interativo; em modo autônomo, direto na branch do PR) e as remediações P0/P1 + guardrails de misses colhidas declarados no cabeçalho.
|
||||
2. Gate commands bare, never piped (`pnpm test | tail` swallows the exit code).
|
||||
3. Never `knip --fix` blind — verify with `git grep -w <symbol>` (knip cannot load `payload.config.ts`; ledgered P3).
|
||||
4. Production is live Neon with real PII. Local DB only, `teqo_test` for tests. The audit needs no DB writes.
|
||||
4. Production is live Postgres on the homeserver (`teqo_1313`) with real PII. Local DB only, `teqo_test` for tests. The audit needs no DB writes.
|
||||
5. Every claim gets a number (lines, exports, call sites, ms, kB). "Rejected by measurement" is an acceptable outcome for any hypothesis, including the ones below.
|
||||
|
||||
## Step 0a — Load the canon
|
||||
|
|
@ -63,12 +63,12 @@ Read, in this order:
|
|||
Antes da varredura, colha os défices comportamentais registrados pelo fluxo:
|
||||
|
||||
```bash
|
||||
gh issue list --label kind:agent-miss --state open
|
||||
pnpm issue all # kind `agent-miss` nos contadores; ou api.listIssues({ state: 'open', labels: 'kind:agent-miss' })
|
||||
```
|
||||
|
||||
**Investigue cada miss colhida** (`gh issue view <N>` — leitura, disponível no Cloud): o corpo registra causa raiz, fix aplicado e o guardrail proposto por `agent:file-miss`. Verifique no código se o fix segurou e se a classe do defeito ainda é reproduzível. Miss cuja classe já tem guarda viva não gera guardrail novo — gera item de hardening da guarda existente (o passo 2 já trata guarda dodgeable como finding).
|
||||
**Investigue cada miss colhida** (leitura da Issue via API do Forgejo/MCP — disponível no Cloud): o corpo registra causa raiz, fix aplicado e o guardrail proposto por `agent:file-miss`. Verifique no código se o fix segurou e se a classe do defeito ainda é reproduzível. Miss cuja classe já tem guarda viva não gera guardrail novo — gera item de hardening da guarda existente (o passo 2 já trata guarda dodgeable como finding).
|
||||
|
||||
Cada Issue colhida alimenta o **Passo 4b (recurrence prevention)**: toda miss vira candidata a guardrail determinístico (tipo / ESLint / convention spec / CI / pin comportamental). O ledger desses guardrails vive em **`docs/GUARDRAILS.md`** (criar o arquivo na primeira execução — é o escopo da Issue OPS2): uma linha por guardrail — miss de origem (link da Issue), classe 1–6, mecanismo, status. Quando o guardrail mergeia, **feche as Issues colhidas** (`done`) com comentário apontando o guardrail. Em Cursor Cloud o fechamento é determinístico e não exige escrita `gh`: o PR do guardrail carrega `Closes #N` (keyword repetida por número — o regex do `issue-done-on-stage-merge.yml` não resolve `Closes #A, #B`) e o merge em `stage` flippa a miss para `done`; guardrails de várias misses podem ir no mesmo PR desde que cada uma tenha seu `closes`. Miss que não admite guardrail determinístico vira convenção explícita marcada "judgment-only" — não fingir que doc é guarda.
|
||||
Cada Issue colhida alimenta o **Passo 4b (recurrence prevention)**: toda miss vira candidata a guardrail determinístico (tipo / ESLint / convention spec / CI / pin comportamental). O ledger desses guardrails vive em **`docs/GUARDRAILS.md`** (criar o arquivo na primeira execução — é o escopo da Issue OPS2): uma linha por guardrail — miss de origem (link da Issue), classe 1–6, mecanismo, status. Quando o guardrail mergeia, **feche as Issues colhidas** (`done`) com comentário apontando o guardrail. Em Cursor Cloud o fechamento é determinístico e não exige escrita manual: o PR do guardrail carrega `Closes #N` (keyword repetida por número — o regex do `issue-done-on-main-merge.yml` não resolve `Closes #A, #B`) e o merge em `main` flippa a miss para `done`; guardrails de várias misses podem ir no mesmo PR desde que cada uma tenha seu `closes`. Miss que não admite guardrail determinístico vira convenção explícita marcada "judgment-only" — não fingir que doc é guarda.
|
||||
|
||||
## Step 1 — Hotspot map
|
||||
|
||||
|
|
@ -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`, **`gh pr merge --auto --rebase`** — 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.
|
||||
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` — mesmo fluxo `agent-pr-workflow`; "Modo autônomo", item 2; o merge fica com o safety net). 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)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
name: plan-issue
|
||||
description: >-
|
||||
Transforma ideias humanas em Issues GitHub + planos de intenção em
|
||||
Transforma ideias humanas em Issues do Forgejo + planos de intenção em
|
||||
docs/plans/ (persona, fluxo, objetivo, direção suave no código — sem
|
||||
decisões duras de engenharia). Se o item muda UI, apresenta no gate um
|
||||
rascunho visual HTML+Tailwind (PNG embutido no plano de intenção). Divide
|
||||
|
|
@ -13,7 +13,7 @@ disable-model-invocation: true
|
|||
|
||||
# Planejar Issues (intenção, não engenharia)
|
||||
|
||||
Esta skill transforma ideias soltas em: (1) um **plano de intenção** em `docs/plans/<slug>.md` por item, e (2) uma **GitHub Issue rastreável** (`pnpm agent:register`, frontmatter `id/depends/serializes/priority/model`). GitHub Issues são a fonte canônica de spec/status/deps/prio/modelo — `docs/roadmap.md` é legado congelado e **nunca** é editado aqui.
|
||||
Esta skill transforma ideias soltas em: (1) um **plano de intenção** em `docs/plans/<slug>.md` por item, e (2) uma **Issue rastreável no Forgejo** (`pnpm agent:register`, frontmatter `id/depends/serializes/priority/model`). As Issues do Forgejo (`git.solla.dev/fsolla/teqo`) são a fonte canônica de spec/status/deps/prio/modelo — `docs/roadmap.md` é legado congelado e **nunca** é editado aqui.
|
||||
|
||||
## Ciclo de vida (obrigatório)
|
||||
|
||||
|
|
@ -29,7 +29,7 @@ rascunho local (Issue: —)
|
|||
|
||||
**Regras duras:**
|
||||
|
||||
1. **Nada no GitHub antes do gate.** Antes da confirmação explícita do Passo 5: proibido `pnpm agent:register`, `gh issue create`, `gh pr create` / push de PR de planos. Planos locais (`Issue: —`) ok.
|
||||
1. **Nada no Forgejo antes do gate.** Antes da confirmação explícita do Passo 5: proibido `pnpm agent:register`, criar Issue/PR / push de PR de planos. Planos locais (`Issue: —`) ok.
|
||||
2. **Confirmação = OK ao overview do lote** (ex. “confirma”, “pode registrar”). “Ok” ambíguo no meio da edição **não** dispara o Passo 6.
|
||||
3. **Register com `--plan` não nasce `ready`.** O script aplica `blocked` automaticamente quando `--plan` está presente (`--blocked` explícito ainda vale para chores sem plano). Sem `--plan` (chore body-only / `file-miss`), pode nascer `ready`.
|
||||
4. **Promote só depois do plano em `main`.** Nunca flipar para `ready` com o PR ainda aberto — isso recria a race de claim. Caminhos: (A) `pnpm agent:ready -- --issue N` no fim do Passo 6 após merge; (B) Action determinística no merge que lê `Related #N` (OPS18). Ambos idempotentes.
|
||||
|
|
@ -67,7 +67,7 @@ Aqui **não** se implementa código de produto, **não** se escreve plano de imp
|
|||
1. **Separe os itens.** Entrada pode ser 1 ideia ou N. Se ambíguo, assuma a leitura mais provável e liste — a confirmação vai no gate.
|
||||
2. **Fatia mínima útil.** Prefira várias Issues pequenas a um epic. Cada item deve caber num appetite curto e entregar um outcome verificável sozinho. Mesclar só quando separar criaria trabalho inútil (mesmo fluxo, mesma persona, mesma superfície sem valor incremental).
|
||||
3. **Dedup intra-lote:** mesclar | absorver (fase de plano existente, sem ID novo) | manter separados com `depends`.
|
||||
4. **Dedup contra o existente:** `gh issue list --state all` + `issuesById()` + grep em `docs/plans/*.md` e `docs/roadmap.md` (legado).
|
||||
4. **Dedup contra o existente:** `pnpm issue all` + `issuesById()` + grep em `docs/plans/*.md` e `docs/roadmap.md` (legado).
|
||||
- Já coberto / entregue → apontar e não criar.
|
||||
- Issue **`in-progress` / `done` / `in-prod`:** **não** editar o plano dela — se a intenção mudou, item **sucessor** (plano + Issue novos).
|
||||
- Issue só `blocked` / `ready` (ainda não claimada): pode editar o plano existente (fase de plano) sem ID novo.
|
||||
|
|
@ -150,7 +150,7 @@ Sem `--plan`: nasce `ready` (use `--blocked` só se quiser não-claimável sem p
|
|||
|
||||
2. Atualize `Issue: #N` (e status) no plano local.
|
||||
3. Commit + **`pnpm push`** + PR **Ready** `--base main` com **`Related #N`** (nunca `Closes #N` em PR só de `docs/plans/` — `plans-only-closes`).
|
||||
4. Auto-merge (`gh pr merge --auto --rebase`); espere o merge em `main`.
|
||||
4. Auto-merge via safety net (`agent-pr-ready-automerge.yml` — o rollup `CI (PR) / checks` verde mergea por rebase); espere o merge em `main`.
|
||||
5. **Promote** com o script (idempotente se já `ready`; só Issues `blocked` + link `docs/plans/`, sem gates humanos `needs:*` nem `in-progress`/`done`/`in-prod`):
|
||||
|
||||
```bash
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
---
|
||||
name: project-status
|
||||
description: Apresenta o estado do projeto Teqo a partir das GitHub Issues rastreáveis — overview (estado/prio/kind), fila atual na ordem do agent:claim com o modelo de cada item, grafo mermaid de dependências, bloqueios com motivo e sugestões de consolidação (merge/break-down). Read-only; NUNCA modifica Issues, em particular nunca toca Issues in-progress. Usar quando o usuário pedir status/visão geral do projeto, "como está o projeto", "qual a fila", "o que está bloqueado", "mostra o grafo", ou perguntar o que dá para consolidar.
|
||||
description: Apresenta o estado do projeto Teqo a partir das Issues do Forgejo rastreáveis — overview (estado/prio/kind), fila atual na ordem do agent:claim com o modelo de cada item, grafo mermaid de dependências, bloqueios com motivo e sugestões de consolidação (merge/break-down). Read-only; NUNCA modifica Issues, em particular nunca toca Issues in-progress. Usar quando o usuário pedir status/visão geral do projeto, "como está o projeto", "qual a fila", "o que está bloqueado", "mostra o grafo", ou perguntar o que dá para consolidar.
|
||||
---
|
||||
|
||||
# Status do projeto (read-only)
|
||||
|
||||
Esta skill apresenta o estado do projeto a partir das GitHub Issues rastreáveis — a fonte canônica de spec/status/deps/prio/modelo. **Read-only por contrato:** nenhuma Issue é criada, editada ou relabelada aqui, e Issues `in-progress` são intocáveis (risco de conflito com o agente que está executando).
|
||||
Esta skill apresenta o estado do projeto a partir das Issues do Forgejo rastreáveis — a fonte canônica de spec/status/deps/prio/modelo. **Read-only por contrato:** nenhuma Issue é criada, editada ou relabelada aqui, e Issues `in-progress` são intocáveis (risco de conflito com o agente que está executando).
|
||||
|
||||
## Fluxo
|
||||
|
||||
|
|
@ -22,6 +22,6 @@ pnpm agent:status
|
|||
- **Bloqueios** — cada `blocked` com o motivo (dep aberta, jurídico, `requirements-changed`).
|
||||
- **Sugestões de consolidação** — as heurísticas do script (merge por domínio+prio; break-down por gargalo de depends) como **texto para o usuário decidir**. Nunca aplique consolidação aqui: aplicação é manual ou via `plan-issue`/`pnpm agent:register`. Nunca proponha nada sobre Issues `in-progress`.
|
||||
|
||||
3. Se o usuário pedir interpretação além da saída (ex.: "o que destrava mais coisa?"), responda a partir do grafo — sem inventar dados que o script não imprimiu; se faltar dado, rode `gh issue view <N>` somente-leitura.
|
||||
3. Se o usuário pedir interpretação além da saída (ex.: "o que destrava mais coisa?"), responda a partir do grafo — sem inventar dados que o script não imprimiu; se faltar dado, leia a Issue via API do Forgejo (MCP/`pnpm issue`) somente-leitura.
|
||||
|
||||
**NÃO faz:** editar `docs/roadmap.md` (legado congelado), claim, registro, qualquer escrita no GitHub.
|
||||
**NÃO faz:** editar `docs/roadmap.md` (legado congelado), claim, registro, qualquer escrita de Issue.
|
||||
|
|
|
|||
|
|
@ -42,11 +42,12 @@ pular a pausa do impl plan; Draft / sem auto-merge.
|
|||
## Passo 1 — Contexto da sessão
|
||||
|
||||
A Issue chega no prompt/`$ARGUMENTS` do `/work-issue` (`--issue <N>` ou o número —
|
||||
contrato OPS33; chamada manual: passar o número). Sempre consulte o GitHub para o
|
||||
contrato OPS33; chamada manual: passar o número). Sempre consulte o Forgejo para o
|
||||
resto (fonte única é a Issue, nunca um brief duplicado).
|
||||
|
||||
- **Presente** → valide o básico (`gh issue view <N>`: existe, `OPEN`, label
|
||||
`in-progress` — confirma que o claim foi feito fora da skill) e use.
|
||||
- **Presente** → valide o básico (issue do Forgejo `git.solla.dev/fsolla/teqo`:
|
||||
existe, `OPEN`, label `in-progress` — confirma que o claim foi feito fora da
|
||||
skill) e use.
|
||||
- **Ausente** → **uma** pergunta ao humano ("Qual Issue?"), valide o número
|
||||
informado com a mesma checagem e siga.
|
||||
- **Checagem falhou** (não existe / não `OPEN` / sem `in-progress`) → a Issue
|
||||
|
|
|
|||
|
|
@ -35,10 +35,9 @@ entrega.
|
|||
(insert-only: entradas históricas nunca mudam; o diff será só a entrada
|
||||
nova + o agregado). Rode `pnpm changelog:check` para confirmar.
|
||||
3. **`pnpm push -u origin HEAD`**
|
||||
4. PR **Ready** (nunca draft): `gh pr create --base main` com `Closes #<N>`
|
||||
5. `gh pr merge --auto --rebase` imediatamente
|
||||
6. `gh pr checks <PR> --watch --required` (`checks`; ignore Vercel Git)
|
||||
7. CI flipa `done`/`in-prod` no merge. Comente na Issue o desfecho em uma linha.
|
||||
4. PR via API/MCP (ou `ManagePullRequest` no Cloud) — **Ready** (nunca draft), base `main`, com `Closes #<N>`
|
||||
5. O safety net `agent-pr-ready-automerge.yml` espera o rollup `CI (PR) / checks` e mergea por rebase — nada a armar
|
||||
6. CI flipa `done`/`in-prod` no merge. Comente na Issue o desfecho em uma linha.
|
||||
|
||||
## Deltas por ator
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ No opencode, isso é o comando **`/worktree next`** / **`/worktree kill`** (`.op
|
|||
|
||||
**Default-go:** `next`, `plan` e `new` imprimem `cd <dir>` 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 <main>` 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 <dir> --model deepseek/deepseek-v4-flash --auto [--prompt "/work-issue --issue <N>"]` **antes** do `cd`, e a função a executa depois do cd — `next` abre o TUI com `/work-issue --issue <N>` 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"). 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 <dir> --model deepseek/deepseek-v4-flash --auto [--prompt "/work-issue --issue <N>"]` **antes** do `cd`, e a função a executa depois do cd — `next` abre o TUI com `/work-issue --issue <N>` 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"). 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)
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ These are product/architecture constraints — not a ban on editing existing cod
|
|||
|
||||
- Single Next.js app, three route groups: `(frontend)` public site, `(payload)` admin, `(campaign)` internal campaign tool. No separate Rust service or frontend app for `/campanha`; it is modeled with Payload collections. The campaign roles are `coordinator` (label "Coordenador Geral"), `advisor` ("Assessor"), `leader` ("Liderança"), and `candidate` ("Candidato", unrestricted visibility), all on the separate auth collection `campaignUser` (see "Campaign auth" below). An advisor sees and manages ONLY the municipalities they administer; a leader is locked down to the supporter contact tool.
|
||||
- **2026-07-23 remodel (DEPLOYED to production 2026-07-23): "Município" is the operational unit** (it replaced "Praça", which replaced "Núcleo Eleitoral"). Municípios are PREDEFINED (seeded, geography read-only): 435 rows — one per Bahia municipality (416), except Salvador (19 zone Municípios, ZE 1–19); Camaçari is a single whole municipality (ZE 170/171 aggregated); shared/leaky TSE zones are cut at the municipal boundary. Code identifier: `municipality`. Leaderships are one record per person (`contact` UNIQUE) linked to N municipalities and N organizations; vote pledges are per leadership×municipality with `declaredVotes` (staff-entered, leader-visible) vs `estimatedVotes` (three scenarios, staff-only, hidden from the leader). Campaign production data was reset by the remodel migrations (public-site data untouched). Master plan: `docs/plans/remodelagem-municipios.md` (supersedes `remodelagem-pracas.md`). Details: "Campaign Municípios model" below.
|
||||
- Production is self-hosted on the homeserver (`jorgesolla1313.com.br`, behind the Cloudflare tunnel; container/database `teqo-1313`/`teqo_1313`). **There is no Vercel deploy anymore** — the Vercel deploy job, `vercel-promote.yml`, the Vercel scripts/`vercel.json` and the `VERCEL_*` repo secrets were removed in OPS50 (2026-08-17). The CI (`ci.yml` on `main`) is the verifier — full suite green — **plus the deploy step (OPS53, 2026-08-17; windowed since OPS65, 2026-08-18)**: `ci.yml` no longer fires on every push — it runs in a **fixed 30-minute window** (`schedule */30` + `workflow_dispatch`), where a cheap gate job (`check`, host runner, no pnpm) reads the SHA deployed on the homeserver from `~/stack/docker-compose.yml` over SSH, diffs it against `main` HEAD and classifies "production change" using `.dockerignore` as the source of truth (docs/`.agents`/`.env*` changes skip; `scripts/`, `tests/`, `.forgejo/`, `AGENTS.md` count as production — conservative). No production change → suite + deploy skipped, run stays green; production change → full suite + deploy in the same window; dispatch always runs the full pipeline. The `deploy` job (runs-on `host` on the workstation runner) streams `scripts/deploy-homeserver.sh` to the homeserver over SSH; the remote script is idempotent ("already deployed" → skip), builds the migrator image first, applies pending migrations through the compose maintenance service `teqo-1313-migrate` **before the runner build** (OPS66: the static build reads the new schema — build-after-migrate, never the reverse), builds the standalone image at the pushed SHA (BuildKit secrets from `~/stack/teqo-1313.env`), pushes it to the local registry (`localhost:5000`), and recreates the container. Merge em `main` com mudança de produção verde == site atualizado em até ~1 h (janela de 30 min + suite + deploy). Runbook (rollback, falhas conhecidas): `docs/ops/teqo-1313-deploy.md`. **The agent-pool supervisor workflow was killed in OPS65** (the `*/10` tick cost 144 full `pnpm install`/day on the workstation; `agent-pool.yml` is gone, pool scripts/skills stay dormant). **The production database lives on the homeserver Postgres (`teqo_1313`, migrated from Neon in OPS51, 2026-08-17)** — the full production content (contacts, signatures, subscriptions, campaign) was restored there via `pg_dump`/`pg_restore` (dump in `/srv/hdd/backups/teqo-neon-pre-migracao/`); Neon remains alive and untouched as the documented rollback (re-point `DATABASE_URL` in `~/stack/teqo-1313.env`). Media moved to the homeserver Garage S3 in OPS52 (2026-08-18): the `media` collection uploads via `@payloadcms/storage-s3` when the `S3_*` envs are set, and Payload proxies the files through `/api/media/file/...` (the bucket stays private). Production env lives in `~/stack/teqo-1313.env` (bucket `teqo-media`, endpoint `http://host.docker.internal:3900` — o container alcança o Garage no host via `extra_hosts: host-gateway` + regras ufw `allow from 10.0.11.0/24 to any port 3900` (INPUT e route/FWD); a workstation/tailnet usa `http://100.119.220.31:3900`, key `teqo-key`); a partial `S3_*` config aborts the boot, and no `S3_*` means local disk (dev/test). The 40 pre-existing media rows are RECOVERED (OPS52-media, 2026-08-18): 38/40 objects restaurados no bucket a partir do WordPress (38 capas servindo 200 em `/api/media/file/...`; exceções sem fonte: `fim-escala-6x1.jpg` e `jorgesolla.jpg`) — re-executar via `pnpm media:recover` (restaura objetos sem tocar no DB; runbook em `docs/plans/ops52-media-recuperar-arquivos-impl.md`; desde OPS52-media-guard o reconcile exige `MEDIA_RECOVER_CONFIRM=1` — guard de intenção explícita para escrita no bucket, `--dry-run`/`--verify` seguem sem flag); the URLs themselves are the same contract the proxy now serves. Never point dev/test databases at the homeserver prod DB either — the local guards (`guard-dev-db`, `assertTestDatabase`) still enforce `localhost`/`_test`-suffixed targets.
|
||||
- Production is self-hosted on the homeserver (`jorgesolla1313.com.br`, behind the Cloudflare tunnel; container/database `teqo-1313`/`teqo_1313`). **There is no Vercel deploy anymore** — the Vercel deploy job, `vercel-promote.yml`, the Vercel scripts/`vercel.json` and the `VERCEL_*` repo secrets were removed in OPS50 (2026-08-17). The CI (`ci.yml` on `main`) is the verifier — full suite green — **plus the deploy step (OPS53, 2026-08-17; windowed since OPS65, 2026-08-18)**: `ci.yml` no longer fires on every push — it runs in a **fixed 30-minute window** (`schedule */30` + `workflow_dispatch`), where a cheap gate job (`gate`, host runner, no pnpm) reads the SHA deployed on the homeserver from `~/stack/docker-compose.yml` over SSH, diffs it against `main` HEAD and classifies "production change" using `.dockerignore` as the source of truth (docs/`.agents`/`.env*` changes skip; `scripts/`, `tests/`, `.forgejo/`, `AGENTS.md` count as production — conservative). No production change → suite + deploy skipped, run stays green; production change → full suite + deploy in the same window; dispatch always runs the full pipeline. The `deploy` job (runs-on `host` on the workstation runner) streams `scripts/deploy-homeserver.sh` to the homeserver over SSH; the remote script is idempotent ("already deployed" → skip), builds the migrator image first, applies pending migrations through the compose maintenance service `teqo-1313-migrate` **before the runner build** (OPS66: the static build reads the new schema — build-after-migrate, never the reverse), builds the standalone image at the pushed SHA (BuildKit secrets from `~/stack/teqo-1313.env`), pushes it to the local registry (`localhost:5000`), and recreates the container. Merge em `main` com mudança de produção verde == site atualizado em até ~1 h (janela de 30 min + suite + deploy). Runbook (rollback, falhas conhecidas): `docs/ops/teqo-1313-deploy.md`. **The agent-pool supervisor workflow was killed in OPS65** (the `*/10` tick cost 144 full `pnpm install`/day on the workstation; `agent-pool.yml` is gone, pool scripts/skills stay dormant). **The production database lives on the homeserver Postgres (`teqo_1313`, migrated from Neon in OPS51, 2026-08-17)** — the full production content (contacts, signatures, subscriptions, campaign) was restored there via `pg_dump`/`pg_restore` (dump in `/srv/hdd/backups/teqo-neon-pre-migracao/`); Neon remains alive and untouched as the documented rollback (re-point `DATABASE_URL` in `~/stack/teqo-1313.env`). Media moved to the homeserver Garage S3 in OPS52 (2026-08-18): the `media` collection uploads via `@payloadcms/storage-s3` when the `S3_*` envs are set, and Payload proxies the files through `/api/media/file/...` (the bucket stays private). Production env lives in `~/stack/teqo-1313.env` (bucket `teqo-media`, endpoint `http://host.docker.internal:3900` — o container alcança o Garage no host via `extra_hosts: host-gateway` + regras ufw `allow from 10.0.11.0/24 to any port 3900` (INPUT e route/FWD); a workstation/tailnet usa `http://100.119.220.31:3900`, key `teqo-key`); a partial `S3_*` config aborts the boot, and no `S3_*` means local disk (dev/test). The 40 pre-existing media rows are RECOVERED (OPS52-media, 2026-08-18): 38/40 objects restaurados no bucket a partir do WordPress (38 capas servindo 200 em `/api/media/file/...`; exceções sem fonte: `fim-escala-6x1.jpg` e `jorgesolla.jpg`) — re-executar via `pnpm media:recover` (restaura objetos sem tocar no DB; runbook em `docs/plans/ops52-media-recuperar-arquivos-impl.md`; desde OPS52-media-guard o reconcile exige `MEDIA_RECOVER_CONFIRM=1` — guard de intenção explícita para escrita no bucket, `--dry-run`/`--verify` seguem sem flag); the URLs themselves are the same contract the proxy now serves. Never point dev/test databases at the homeserver prod DB either — the local guards (`guard-dev-db`, `assertTestDatabase`) still enforce `localhost`/`_test`-suffixed targets.
|
||||
- Donations are NOT handled in this app — they run through QueroApoiar (`apoiar.me/jorgesolla`, TSE-homologated). The site only needs a "Doar" link/CTA out to that URL.
|
||||
|
||||
- **Embasamento de produto/domínio:** `docs/research/` guarda o compêndio de literatura (campanha de DF na Bahia, geografia do voto, cartografia eleitoral) e o relatório de discovery aprovado (2026-07-21) com o playbook dado→decisão. Para métricas, análises territoriais, mapa e priorização em `/campanha`, consulte-o antes de inventar — o kernel: a disputa de DF é conta de quociente fragmentada; leitura útil é relativa e local (captura, LQ, quantis, cobertura de meta por pledges), nunca % estadual absoluto.
|
||||
|
|
|
|||
34
README.md
34
README.md
|
|
@ -6,16 +6,16 @@
|
|||
|
||||
> **Cheatsheet de operação agentic (humanos)** — o fluxo em 5 linhas:
|
||||
>
|
||||
> 1. O agente roda `pnpm agent:claim` e pega a próxima Issue `ready` por prioridade (`prio:P0..P3`).
|
||||
> 2. Ele implementa, roda o fast gate (`lint + typecheck + unit`) e abre **PR para `main`** — sozinho.
|
||||
> 3. CI verde → o PR mergeia em `main` automaticamente; o verificador `ci.yml` roda a suíte completa.
|
||||
> 4. Suíte verde → Action dispara `vercel deploy --prod` (Vercel Git builds estão desligados).
|
||||
> 5. Secrets humanos (uma vez): `FORGEJO_API_TOKEN`, `CURSOR_API_KEY`, `POOL_GITHUB_TOKEN`; `pnpm configure:branch-protection` (main: required `CI (PR) / checks`).
|
||||
> 1. O agente roda `pnpm agent:claim` (ou `pnpm worktree next --issue N`) e pega a próxima Issue `ready` por prioridade (`prio:P0..P3`).
|
||||
> 2. Ele implementa, roda o fast gate (`lint + typecheck + unit`) e `pnpm push -u origin HEAD` — abre a PR para `main` (Ready, `Closes #N`).
|
||||
> 3. CI verde → o safety net `agent-pr-ready-automerge.yml` mergea em `main` por rebase; o verificador `ci.yml` do main roda a suíte completa na janela fixa de 30 min.
|
||||
> 4. Com mudança de produção → o job `deploy` publica no homeserver (`jorgesolla1313.com.br`, self-hosted) — migrações aplicadas antes do rollout.
|
||||
> 5. Secrets humanos (uma vez): `FORGEJO_API_TOKEN` no Forgejo; envs de prod em `~/stack/teqo-1313.env` no homeserver. Branch protection de `main` já aplicada (reaplicar: `pnpm configure:branch-protection`).
|
||||
>
|
||||
> Comandos: `pnpm agent:claim | agent:register | agent:prioritize | agent:file-miss | agent:pool` e `pnpm db:seed:minimal`.
|
||||
> Comandos: `pnpm agent:claim | agent:register | agent:prioritize | agent:file-miss | worktree next` e `pnpm db:seed:minimal`.
|
||||
> Labels: estado `ready|in-progress|blocked|done|in-prod`, `prio:P0..P3`, `kind:*`, `needs:migration|consent`, `requirements-changed`.
|
||||
> **Agente faz sozinho:** claim → implementar → PR → main. **Só humano:** secrets Vercel/pool, branch protection, envs Neon.
|
||||
> Tudo em detalhe: [`docs/AGENT-OPS.md`](docs/AGENT-OPS.md) · CI: `.github/workflows/ci-pr.yml` + `ci.yml`.
|
||||
> **Agente faz sozinho:** claim → implementar → PR → main. **Só humano:** envs do homeserver, branch protection, runbook de rollback.
|
||||
> Tudo em detalhe: [`docs/AGENT-OPS.md`](docs/AGENT-OPS.md) · CI: `.forgejo/workflows/ci-pr.yml` + `ci.yml`.
|
||||
|
||||
Teqo starts as the official digital platform for **deputado Jorge Solla** and evolves into a **white-label civic engagement platform** for politicians in Brazil.
|
||||
|
||||
|
|
@ -35,7 +35,7 @@ Initial delivery focuses on Jorge Solla's public website, editorial CMS, and the
|
|||
|
||||
- Public-facing content and updates (news/`post` + `tag` live)
|
||||
- Institutional pages and biography (still pending a `Pages` collection)
|
||||
- Internal campaign operations: electoral nuclei, leaderships, estimates, updates, WhatsApp invites
|
||||
- Internal campaign operations: municípios (435, pré-definidos), leaderships, estimates, updates, WhatsApp invites
|
||||
- Editorial operations through Payload CMS
|
||||
|
||||
### Phase 2: White-Label Platform
|
||||
|
|
@ -49,7 +49,7 @@ Teqo then becomes a configurable base product for other politicians in Brazil:
|
|||
|
||||
## Local Development
|
||||
|
||||
> **Production safety:** the production database is a live Neon Postgres holding real citizens' data. Local development and tests run against a **local** Postgres and must never point at production. `pnpm dev` refuses to start against a non-local database, and the test suite refuses any database whose name doesn't end in `_test`.
|
||||
> **Production safety:** the production database is a live Postgres on the homeserver (`teqo_1313`) holding real citizens' data. Local development and tests run against a **local** Postgres and must never point at production. `pnpm dev` refuses to start against a non-local database, and the test suite refuses any database whose name doesn't end in `_test`.
|
||||
|
||||
### First-time setup
|
||||
|
||||
|
|
@ -62,8 +62,8 @@ Teqo then becomes a configurable base product for other politicians in Brazil:
|
|||
DATABASE_URL=postgresql://teqo:teqo@localhost:5432/teqo
|
||||
```
|
||||
5. Load a schema + content into the local database — pick one:
|
||||
- **Mirror production content (recommended):** `PROD_DATABASE_URL="<unpooled Neon URL>" pnpm db:pull`
|
||||
Copies production's schema and content into local. It only reads production and **excludes supporter PII** (`contact`/`signature`/`subscription` data).
|
||||
- **Mirror production content (recommended):** `PROD_DATABASE_URL="<prod connection string>" pnpm db:pull`
|
||||
Copies production's schema and content into local. It only reads production and **excludes supporter PII** (`contact`/`signature`/`subscription` data). The prod string is the `DATABASE_URL` of `~/stack/teqo-1313.env` on the homeserver (Postgres `teqo_1313`).
|
||||
- **Empty schema from migrations:** `pnpm migrate`
|
||||
6. Start the dev server: `pnpm dev`
|
||||
7. Open: `http://localhost:3000`
|
||||
|
|
@ -84,7 +84,7 @@ curl -X POST "https://<prod-domain>/api/revalidate" -H "x-revalidate-secret: $RE
|
|||
curl -X POST "https://<prod-domain>/api/revalidate?tag=global_privacy-policy" -H "x-revalidate-secret: $REVALIDATE_SECRET"
|
||||
```
|
||||
|
||||
`REVALIDATE_SECRET` must be set in the Vercel production env (see `.env.example`). See the "Posts & Tags" section of `AGENTS.md` for the full model.
|
||||
`REVALIDATE_SECRET` must be set in the production env (`~/stack/teqo-1313.env` on the homeserver — see `.env.example`). See the "Posts & Tags" section of `AGENTS.md` for the full model.
|
||||
|
||||
### Database migrations
|
||||
|
||||
|
|
@ -97,7 +97,7 @@ To change the schema:
|
|||
3. Review and commit the generated files in `src/migrations/` (both `.ts` and `.json`, plus `index.ts`).
|
||||
4. Apply it locally: `pnpm migrate` (check status anytime with `pnpm migrate:status`).
|
||||
|
||||
**Deploying to production:** `pnpm build` runs `payload migrate` before building, so every Vercel deploy automatically applies pending migrations to the production database. Do not run migrations against production by hand.
|
||||
**Deploying to production:** merges to `main` with production changes are deployed by the `deploy` job of `ci.yml` (windowed — see `docs/AGENT-OPS.md`); the remote script (`scripts/deploy-homeserver.sh`) builds on the homeserver and applies pending migrations through the compose maintenance service `teqo-1313-migrate` **before** the rollout. Do not run migrations against production by hand. Runbook (rollback, known failures): `docs/ops/teqo-1313-deploy.md`.
|
||||
|
||||
### Running tests
|
||||
|
||||
|
|
@ -113,7 +113,7 @@ Then run:
|
|||
- `pnpm test:e2e` — Playwright (requires the test DB schema and a free port)
|
||||
- `pnpm test:all` — unit + integration + E2E
|
||||
|
||||
Quality gates (also enforced by CI on the GitHub mirror): `pnpm lint` (zero warnings — `--max-warnings=0`), `pnpm typecheck`, and `pnpm exec knip` (dead files/dependencies fail; delete what your change orphaned). Standards: `.agents/rules/engineering-standards.mdc`.
|
||||
Quality gates (also enforced by CI on the Forgejo Actions): `pnpm lint` (zero warnings — `--max-warnings=0`), `pnpm typecheck`, and `pnpm exec knip` (dead files/dependencies fail; delete what your change orphaned). Standards: `.agents/rules/engineering-standards.mdc`.
|
||||
|
||||
## Tech Stack
|
||||
|
||||
|
|
@ -124,10 +124,10 @@ Quality gates (also enforced by CI on the GitHub mirror): `pnpm lint` (zero warn
|
|||
|
||||
## Campaign (`/campanha`)
|
||||
|
||||
Internal campaign tool for electoral nuclei, local leaderships, vote estimates, field updates, and WhatsApp invites. Authenticated separately from `/admin` via the `campaignUser` collection (`geral` / `coordenador` / `lideranca`). Operational status and decisions: [`.agents/rules/projects/nucleos-eleitorais.mdc`](.agents/rules/projects/nucleos-eleitorais.mdc). Conventions and deploy checklist: `AGENTS.md` (“Campaign auth” / “Campaign nuclei MVP”).
|
||||
Internal campaign tool for municípios (435 pré-definidos), local leaderships, vote estimates, field updates, and WhatsApp invites. Authenticated separately from `/admin` via the `campaignUser` collection (`coordinator` / `advisor` / `leader` / `candidate`). Operational status and decisions: [`.agents/rules/projects/nucleos-eleitorais.mdc`](.agents/rules/projects/nucleos-eleitorais.mdc). Conventions and deploy checklist: `AGENTS.md` (“Campaign auth” / “Campaign Municípios model”).
|
||||
|
||||
**Production blocker:** do not load real leadership data or enable invites until counsel-approved `Consent.key = 'lideranca-autopreenchimento'` exists. Absolute invite URLs require `NEXT_PUBLIC_SITE_URL` as an exact HTTPS DNS origin in production.
|
||||
|
||||
## Roadmap
|
||||
|
||||
Backlog and future plans live as tracked [GitHub Issues](https://github.com/fsolla/teqo/issues) (spec + deps + prio + model per issue; flow skills: `plan-issue` → `work-issue` → `project-status`; `docs/roadmap.md` is a frozen legacy stub).
|
||||
Backlog and future plans live as tracked [Forgejo Issues](https://git.solla.dev/fsolla/teqo/issues) (spec + deps + prio + model per issue; flow skills: `plan-issue` → `work-issue` → `project-status`; `docs/roadmap.md` is a frozen legacy stub).
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# AGENT-OPS — operação do paradigma de agentes paralelos
|
||||
|
||||
Uma página. Norte: simplicidade (só GitHub + Cursor), agente entrega em `main`, deploy de produção só após o verificador full-suite verde.
|
||||
Uma página. Norte: simplicidade (só Forgejo + Cursor), agente entrega em `main`, deploy de produção só após o verificador full-suite verde.
|
||||
|
||||
## Ambientes de dados (test ladder — nunca misturar)
|
||||
|
||||
|
|
@ -9,7 +9,7 @@ Uma página. Norte: simplicidade (só GitHub + Cursor), agente entrega em `main`
|
|||
| **Mínimo** (`teqo_test` local / service CI) | schema migrado + `pnpm db:seed:minimal` (sintético, sem PII) | agentes, Cursor Cloud, CI |
|
||||
| **Prod** (`teqo_1313`, homeserver) | real | job `deploy` do `ci.yml` (OPS53) |
|
||||
|
||||
Agentes **nunca** recebem `DATABASE_URL` de prod e nunca setam `ALLOW_REMOTE_DB`. Não há mais smoke Neon `stage` / `ALLOW_STAGE_TEST_DB` / `ci-stage.yml`.
|
||||
Agentes **nunca** recebem `DATABASE_URL` de prod e nunca setam `ALLOW_REMOTE_DB`. Não há mais smoke `stage` / `ALLOW_STAGE_TEST_DB` / `ci-stage.yml`.
|
||||
|
||||
## Fluxo
|
||||
|
||||
|
|
@ -18,10 +18,10 @@ claim → feature branch → PR --base main → CI PR green (cascade + skips)
|
|||
main → ci.yml (janela de 30 min, OPS65) full suite verde → job `deploy` (homeserver, OPS53 — merge com mudança de produção == site atualizado em ~30 min + suite/deploy)
|
||||
```
|
||||
|
||||
**Skills:** `plan-issue` (intenção + Issues) → `work-issue` (humano: Issue já claimada → impl plan → confirmação → execução) ou `agent-work-issue` (pool: já claimada → impl plan → execução sem pausa) → `/simplify` → `capture-review-debts` → PR `--base main` → `project-status`. `docs/roadmap.md` = legado congelado; fonte canônica = GitHub Issues.
|
||||
**Skills:** `plan-issue` (intenção + Issues) → `work-issue` (humano: Issue já claimada → impl plan → confirmação → execução) ou `agent-work-issue` (pool: já claimada → impl plan → execução sem pausa) → `/simplify` → `capture-review-debts` → PR `--base main` → `project-status`. `docs/roadmap.md` = legado congelado; fonte canônica = Issues do Forgejo (`git.solla.dev/fsolla/teqo`).
|
||||
|
||||
- **Agente faz sozinho:** claim (pool-supervisor no pool; humano via `pnpm agent:claim` fora da sessão — OPS33: `worktree next` claima) → implementa → **`pnpm push`** → PR **Ready** (nunca draft) com `Closes #N` → `gh pr merge --auto --rebase` → `gh pr checks --watch --required`. Regra always-on: `.agents/rules/agent-pr-workflow.mdc`. Em Cursor Cloud: `ManagePullRequest` com `draft: false`, depois armar auto-merge via `gh pr merge --auto --rebase` (o default draft da tool **não** vale neste repo).
|
||||
- **Só humano:** secrets Vercel (`VERCEL_TOKEN`, `VERCEL_ORG_ID`, `VERCEL_PROJECT_ID`), `POOL_GITHUB_TOKEN`, `pnpm configure:branch-protection`, editar envs Neon/Vercel.
|
||||
- **Agente faz sozinho:** claim (pool-supervisor no pool; humano via `pnpm agent:claim` fora da sessão — OPS33: `worktree next` claima) → implementa → **`pnpm push`** → PR via API/MCP **Ready** (nunca draft) com `Closes #N` → o safety net `agent-pr-ready-automerge.yml` espera o rollup `CI (PR) / checks` e mergea por rebase. Regra always-on: `.agents/rules/agent-pr-workflow.mdc`. Em Cursor Cloud: `ManagePullRequest` com `draft: false` (o default draft da tool **não** vale neste repo) — o merge continua pelo safety net.
|
||||
- **Só humano:** envs de produção no homeserver (`~/stack/teqo-1313.env`, fora do repo — o deploy as lê via BuildKit secrets), `pnpm configure:branch-protection` (idempotente; reaplicar se o drift voltar), runbook manual/rollback (`docs/ops/teqo-1313-deploy.md`).
|
||||
|
||||
### Dono do PR, dono do CI
|
||||
|
||||
|
|
@ -56,7 +56,7 @@ Labels: `ready|in-progress|blocked|done|in-prod`, `prio:*`, `kind:*`, `needs:*`.
|
|||
|
||||
1. Schema → atualizar `db:seed:minimal` no mesmo PR (`needs:migration`).
|
||||
2. Migrations NÃO são serializadas entre PRs: o CI (migrate + int, incl. `campaignMigrationReconciliation`) valida a cadeia em todo PR e na main; rebase antes de `migrate:create` continua obrigatório.
|
||||
3. Ready + auto-merge: `gh pr create --base main` → `gh pr merge --auto --rebase`; `gh pr checks --watch --required` (Vercel Git não é gate). **Merge é por rebase** (nunca merge commit): preserva a linha histórica limpa do `main` e é o modo que o CI guarda contra conflitos latentes.
|
||||
3. Ready + auto-merge: `pnpm push -u origin HEAD` → PR via API/MCP (Ready, base `main`, `Closes #N`) → o safety net `agent-pr-ready-automerge.yml` (`scripts/forgejo-pr-automerge.mjs`) espera o rollup `CI (PR) / checks` e mergea por rebase — não há `gh` em nenhuma máquina (OPS50), o safety net é quem espera os checks. **Merge é por rebase** (nunca merge commit): preserva a linha histórica limpa do `main` e é o modo que o CI guarda contra conflitos latentes.
|
||||
4. **Changelog da entrega (OPS44):** toda entrega escreve `docs/changelog/<data>-<id>.md` (ex. `2026-08-13-ops44.md`) e roda `pnpm changelog:build` antes do push — o agregado `docs/CHANGELOG-AGENTS.md` é **insert-only** (nunca remove/reescreve entradas; entradas históricas não são migradas). Guard de CI `docs-guards`: (a) agregado é append-only (multiset sobre blobs — perda de linha falha); (b) `docs/changelog/` é additions-only (M/D falham); (c) agregado está up to date com `docs/changelog/` (`changelog:check`); (d) nenhum marcador de conflito em diffs de markdown (docs/, AGENTS.md, .agents/ — cobre PRs docs-only, onde a suíte unit não roda). **Desde OPS63 os mesmos três checks rodam também no pre-push local** (`gate:push` → `gate:ci`, fase 1 — mesmos scripts, default `origin/main`). Restauração legítima (header muda, restauração estilo D8) escapa escrevendo **`changelog-rewrite: <motivo>` como linha própria** no body do PR — definição canônica aqui; o texto do checkbox do PR template nunca ativa (linha-ancorado). **O escape é CI-only (body do PR):** no pre-push local a restauração legítima falha com a mesma mensagem do CI — bypass documentado é `git push --no-verify` direto (o CI, com o escape no body, continua sendo a via da restauração). A própria troca `--merge` → `--rebase` deste doc usou o escape — header do agregado mudou.
|
||||
|
||||
## Registries compartilhados (serialização por arquivo, não por PR)
|
||||
|
|
@ -76,6 +76,7 @@ Arquivos de "lista" que N agentes escrevem em paralelo (changelog, plans, migra
|
|||
| `issue-done-on-main-merge.yml` | PR merged → `main` (same-repo) | — | `Closes`/`Fixes` → `done` + `in-prod` (PAT `FORGEJO_API_TOKEN`; `GITHUB_TOKEN` 403 em Issues) |
|
||||
| `plan-issue-ready-on-main-merge.yml` | PR merged → `main` (same-repo) | — | `Related #N` aguardando plano → `ready` (OPS18; soft-skip; mesmo PAT) |
|
||||
| `agent-pr-ready-automerge.yml` | PR same-repo → `main` (open/sync/…) | — | Safety net via `forgejo-pr-automerge.mjs` (plain Node): espera o rollup `checks` e mergea por rebase com `FORGEJO_API_TOKEN` (o `GITHUB_TOKEN` nativo não tem write no repo — o push do merge é rejeitado com 409); draft `cursor/*` → Ready; draft não-`cursor/*` = veto, skip |
|
||||
| `archive-cursor-agent.yml` | dispatch manual (ops) | — | Helper: cancela run + arquiva um agente Cursor Cloud (`CURSOR_API_KEY`) — **dormente (OPS65)** como o pool |
|
||||
|
||||
`agent-pool.yml` foi **removido no OPS65** (pool dormente; o tick `*/10` custava 144 `pnpm install`/dia na workstation).
|
||||
|
||||
|
|
@ -85,11 +86,12 @@ Fast gate: `pnpm gate:fast`. Push: `pnpm push`.
|
|||
|
||||
### Secrets (humano, uma vez)
|
||||
|
||||
| Secret | Uso |
|
||||
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `FORGEJO_API_TOKEN` | Supervisor do pool e scripts Forgejo (`forgejo-api.mjs`); também nos workflows pós-merge (`issue-done`, `plan-issue-ready`) — o `GITHUB_TOKEN` nativo 403 em Issues (OPS61) |
|
||||
| `CURSOR_API_KEY` | Supervisor do pool (Cursor Cloud) |
|
||||
| `POOL_GITHUB_TOKEN` | PAT `actions:write` + `issues:write` (variables do pool; `GITHUB_TOKEN` costuma 403) |
|
||||
| Secret | Uso |
|
||||
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `FORGEJO_API_TOKEN` | Supervisor do pool e scripts Forgejo (`forgejo-api.mjs`); também nos workflows pós-merge (`issue-done`, `plan-issue-ready`) e no safety net — o `GITHUB_TOKEN` nativo 403 em Issues e não tem write no repo (OPS61) |
|
||||
| `CURSOR_API_KEY` | Supervisor do pool (Cursor Cloud) — **dormente (OPS65)**; só o helper `archive-cursor-agent.yml` a usa hoje |
|
||||
|
||||
`POOL_GITHUB_TOKEN` é **legado** (era da transição GitHub): o `scripts/agent-pool.mjs` o ignora quando presente; não criar no Forgejo. Envs de produção (DB, S3, VAPID, `REVALIDATE_SECRET`, `NEXT_PUBLIC_SITE_URL`) vivem em `~/stack/teqo-1313.env` no homeserver — nunca como secrets do Forgejo.
|
||||
|
||||
Branch protection de `main` (aplicada em 2026-08-18, OPS61): required status check `CI (PR) / checks` (o rollup do `ci-pr.yml` — único contexto que cobre a cascata inteira), `strict=false`, 0 reviews. O `waitForChecks` do safety net espera esse mesmo rollup antes de mergear (o próprio status do job é `pending` durante o run e nunca entra no veredito); a regra no servidor é o gate real — o Forgejo bloqueia o merge POST com 405 se o contexto exigido não estiver verde, inclusive merges manuais via API (a PR #52 entrou em main com CI vermelho por merge manual). Reaplicar/consertar drift: `pnpm configure:branch-protection` (idempotente).
|
||||
|
||||
|
|
|
|||
1
docs/changelog/2026-08-19-ops68.md
Normal file
1
docs/changelog/2026-08-19-ops68.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
**Recently resolved (2026-08-19):** **OPS68** — fechamento da parte 2 do OPS50: reescrita dos docs canônicos operacionais que ainda descreviam a era GitHub/Vercel. **12 arquivos, 78+/82−, edições linha-a-linha:** `docs/AGENT-OPS.md` (norte "só Forgejo + Cursor"; fonte canônica = Issues do Forgejo; fluxo do agente e Contrato de PR sem `gh` — criação via API/MCP + merge pelo safety net `agent-pr-ready-automerge.yml`, o único que espera o rollup `CI (PR) / checks`; "Só humano" = envs de `~/stack/teqo-1313.env` + branch protection + runbook; tabela de secrets sem `POOL_GITHUB_TOKEN` (legado — o script o ignora) e com nota de pool dormente; linha `archive-cursor-agent.yml` na tabela CI; "smoke Neon stage" → sem smoke stage), `README.md` (cheatsheet de 5 linhas reescrito: claim → push → PR via API/MCP → safety net mergea → ci.yml em janela de 30 min + deploy homeserver; Neon → homeserver Postgres; `PROD_DATABASE_URL` = `DATABASE_URL` de `~/stack/teqo-1313.env`; migrações no deploy via `teqo-1313-migrate`; "GitHub mirror" → Forgejo Actions; papéis `coordinator/advisor/leader/candidate`; "electoral nuclei" → municípios; Issues → link Forgejo), `docs/roadmap.md` (só o ponteiro da fonte canônica — o stub continua congelado), `AGENTS.md` (refs Neon → homeserver `teqo_1313`; job do gate `check`→`gate`, key real do YAML; "Vercel preview" → host genérico na rationale do WebAuthn), `.agents/rules/agent-pr-workflow.mdc` (comandos `gh pr create/merge/checks` morrem — `gh` não existe em nenhuma máquina (OPS50); regra descreve API/MCP + safety net; "There is no deploy from CI" corrigido — OPS53 colocou o deploy no `ci.yml`), e as skills `work-issue` (SKILL + `execution-pipeline`), `plan-issue` (frontmatter, gate "nada no Forgejo", dedup via `pnpm issue all`), `project-status`, `capture-review-debts`, `engineering-audit` (`gh issue list` → `pnpm issue all`/API; `issue-done-on-stage-merge.yml`→`on-main`; merge `stage`→`main`), `worktree-next-issue` ("resto do Forgejo") e `agent-pool` (descrição Forgejo Actions; workflow marcado removido OPS65; estado em `pool-state.json`, não mais variables). **Mantido como registro histórico** (exclusões explícitas do plano): menções de Vercel/Neon/POOL_GITHUB que documentam remoções (AGENTS.md L15/L105/L167, AGENT-OPS L94/L98, "Vercel/Git-integration deploy gate" como guardrail no rule). Fonte canônica única: `git.solla.dev/fsolla/teqo`. Sem migration/access/Consent/UI. Gate: grep de saída zero nas classes `gh pr`/`gh issue`/`github.com/fsolla`/`GitHub Issues`/`GitHub mirror`/`POOL_GITHUB`/Neon-em-uso; docs-only → CI roda os docs-guards.
|
||||
85
docs/plans/ops68-docs-drift-github-era-impl.md
Normal file
85
docs/plans/ops68-docs-drift-github-era-impl.md
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
# Impl: OPS68 — docs: drift GitHub-era no AGENT-OPS/README — reescrita da parte 2 do OPS50
|
||||
|
||||
Status: aprovado
|
||||
Atualizado em: 2026-08-19
|
||||
Issue: #74
|
||||
Intenção: o body da Issue é a spec (frontmatter `id: OPS68, depends: [OPS61], priority: P3`); o escopo ancora na parte 2 do OPS50 (reescrita de docs canônicos) e no título (drift GitHub-era: `gh pr`, secrets Vercel, fonte canônica GitHub)
|
||||
Appetite restante: P3, ~meio dia de engenharia (docs-only)
|
||||
|
||||
## Leitura da intenção
|
||||
|
||||
- **Outcome:** os docs canônicos operacionais do paradigma (AGENT-OPS, README, roadmap, AGENTS.md e as skills/rules always-on de operação) descrevem a realidade Forgejo/homeserver de 2026-08 — zero resíduo GitHub-era (comandos `gh`, links github.com/fsolla, "GitHub Issues" como fonte canônica) e zero resíduo Vercel-era (secrets `VERCEL_*`, "Neon" como banco de prod, "deploy Vercel").
|
||||
- **O que NÃO negociar:** nada de produto — é docs. Não tocar docs congelados/históricos (`docs/plans/*`, `docs/changelog/*` + `CHANGELOG-AGENTS.md` insert-only, `docs/GUARDRAILS.md` — os links GitHub lá são registro histórico das issues/PRs da época; `docs/CUTOVER-MAIN-ONLY.md` — checklist histórico do cutover, já anotado pelo OPS61; a linha histórica do `nucleos-eleitorais.mdc` que cita "mirror GitHub" descreve uma entrega de 2026-07-23 e permanece como registro). A "fonte canônica" passa a ser Forgejo sem ambigüidade — uma fonte só.
|
||||
- **O que reavaliar:** a hipótese do título (AGENT-OPS/README) é o núcleo, mas a exploração mostra que a mesma classe de drift vive em mais 5 arquivos operacionais always-on — o sweep segue a classe nomeada no título ("gh pr", "Vercel secrets", "fonte canônica GitHub"), não só os dois arquivos.
|
||||
|
||||
## Abordagem recomendada
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[Baseline grep dos alvos] --> B[Reescrita docs canônicos]
|
||||
B --> C[Reescrita .agents operacionais]
|
||||
C --> D[Changelog OPS68 + gates]
|
||||
D --> E[Grep zero de resíduo = aceite]
|
||||
```
|
||||
|
||||
**Opções consideradas (largura do sweep — decisão cara):**
|
||||
|
||||
- **A)** Só `docs/AGENT-OPS.md` + `README.md`. **Rejeitada** — deixa a regra always-on `agent-pr-workflow.mdc` (com `gh pr create/merge/checks` de verdade, e `gh` não existe em nenhuma máquina — achado OPS50) e as skills de fluxo (`work-issue`/`execution-pipeline`/`plan-issue`) instruindo comandos fantasma; o próprio `/work-issue` desta sessão lê `gh issue view` no Passo 1. Um OPS69 nasceria na semana.
|
||||
- **B)** Canônicos operacionais (recomendada): `docs/AGENT-OPS.md`, `README.md`, `docs/roadmap.md` (só a linha de fonte canônica — o resto continua congelado), `AGENTS.md` (refs Neon/era-Vercel + nome do job do gate), `.agents/rules/agent-pr-workflow.mdc` e as 7 skills de operação com drift (`work-issue/SKILL.md`, `work-issue/execution-pipeline.md`, `plan-issue`, `project-status`, `capture-review-debts`, `engineering-audit`, `worktree-next-issue`, `agent-pool`). Edições **pontuais** (só as linhas do drift), nunca reescrita/refrase de conteúdo são.
|
||||
- **C)** OPS50 parte 2 integral = varrer também conteúdo genérico de skills de terceiros (`impeccable` hooks.md, `clean-code` references, etc.). **Rejeitada** — aquilo é biblioteca de skill, não operação do Teqo; "GitHub Copilot"/"Jira/GitHub Issues" em conteúdo genérico é referência ao mundo, não drift do repo.
|
||||
|
||||
**Recomendação: B** — cobre a classe do título inteira no mínimo de arquivos com risco de diff; o critério de saída é verificável por grep.
|
||||
|
||||
### Decisões de engenharia (todas caras o bastante para registar)
|
||||
|
||||
1. **Fluxo de PR documentado (o que substitui `gh pr …`).** Realidade verificada: `gh` não existe na máquina do humano nem nos workers (OPS50); o merge é feito pelo safety net `agent-pr-ready-automerge.yml` (`scripts/forgejo-pr-automerge.mjs`, plain Node) quando o rollup `CI (PR) / checks` posta verde — para TODA PR same-repo → main (OPS57), draft não-`cursor/*` = veto; a branch protection no servidor bloqueia merge com o contexto exigido vermelho (OPS61, 405). Criação de PR é via API/MCP do opencode (humano) ou `ManagePullRequest` `draft:false` (Cursor Cloud). Documentar: `pnpm push -u origin HEAD` → PR via API/MCP (Ready, base `main`, `Closes #N`) → safety net espera o rollup e mergea por rebase; `gh pr checks --watch` não tem equivalente (quem espera é o safety net). **Nunca documentar comando que não existe.**
|
||||
2. **"Só humano" (AGENT-OPS L24 + README L17).** O que sobrou de fato: envs de prod vivem no homeserver (`~/stack/teqo-1313.env`, fora do repo; o deploy lê via BuildKit secrets), reaplicar branch protection é `pnpm configure:branch-protection` (idempotente, já aplicado 2026-08-18), runbook/rollback manual em `docs/ops/teqo-1313-deploy.md`. Segredo de repo único ativo: `FORGEJO_API_TOKEN`; `CURSOR_API_KEY` só existe para o pool dormente. `POOL_GITHUB_TOKEN` é legado — o próprio `scripts/agent-pool.mjs` avisa "legado presente no env — ignorar" (L470); remover da tabela de secrets ou marcar `legado`.
|
||||
3. **Deploy descrito como ele é (OPS53+OPS65).** `ci.yml` do main em janela fixa de 30 min; job `gate` (o AGENTS.md escreve `check` — corrigir para `gate`, job key real no YAML) classifica mudança de produção via `.dockerignore` + revision do container; job `deploy` (runs-on `host`) streama `scripts/deploy-homeserver.sh` — migrações aplicadas pelo serviço de maintenance `teqo-1313-migrate` antes do rollout. A frase do README "every Vercel deploy automatically applies pending migrations" morre; a do AGENT-OPS L96 ("deploy Vercel removido no OPS50") está correta e fica.
|
||||
4. **Roadmap congelado, ponteiro vivo.** `docs/roadmap.md` L5: trocar só o ponteiro da fonte canônica (GitHub → Forgejo, `git.solla.dev/fsolla/teqo/issues`); a declaração "congelado em 2026-07-30, não é mais editado" permanece — o ponteiro é instrução de leitura, não conteúdo do roadmap.
|
||||
5. **Pool dormente.** `agent-pool/SKILL.md` fica (histórico, como o AGENT-OPS já declara), mas a descrição "GitHub Actions" e a referência `.github/workflows/agent-pool.yml` (L14) ganham a marca de removido OPS65 — a skill ainda é descoberta e lida. `archive-cursor-agent.yml` ganha linha na tabela CI do AGENT-OPS (existe no `.forgejo/workflows/` e não está na tabela; dormente com o pool).
|
||||
|
||||
### Componentes / mudanças
|
||||
|
||||
- **`docs/AGENT-OPS.md`** — L3 "só GitHub"→"só Forgejo"; L21 fonte canônica → Issues do Forgejo; L23 fluxo do agente (sem `gh`); L24 "Só humano" (decisão 2); L59 item 3 do Contrato de PR (decisão 1); L92 tabela secrets (`POOL_GITHUB_TOKEN` → legado; nota pool dormente); tabela CI ganha linha `archive-cursor-agent.yml` (dormente); L96 verificado e mantido.
|
||||
- **`README.md`** — cheatsheet L7–18 reescrito (5 linhas: claim → implementa+push → PR via API/MCP + safety net → ci.yml janela 30 min → deploy homeserver; secrets humanos `FORGEJO_API_TOKEN` + envs do homeserver; CI `.forgejo/workflows/`); L38 "electoral nuclei"→"municípios" (vocabulário era Praça); L52 Neon→homeserver Postgres; L65 `PROD_DATABASE_URL` = `DATABASE_URL` de `~/stack/teqo-1313.env`; L87 `REVALIDATE_SECRET` no env do homeserver; L100 migrações no deploy → maintenance service `teqo-1313-migrate` (decisão 3); L116 "GitHub mirror"→Forgejo Actions; L127 papéis de campanha atuais (`coordinator|advisor|candidate|leader`); L133 Issues → link Forgejo.
|
||||
- **`docs/roadmap.md`** — L5 ponteiro da fonte canônica (decisão 4).
|
||||
- **`AGENTS.md`** — L30/L32/L159 refs "Neon" → homeserver Postgres (era-Vercel, mesma classe do parêntese do título); L15 "(`check`"→"(`gate`" (job key real); L147 "no Neon risk" → "no prod-DB risk" (idem).
|
||||
- **`.agents/rules/agent-pr-workflow.mdc`** — create (L14), ManagePullRequest (L32), auto-merge (L54), checks (L74/L77): comandos `gh` → API/MCP + safety net; L69 "There is no deploy from CI … outside this repo" → deploy step no `ci.yml` (janela, OPS53/OPS65) — contradição factual com AGENT-OPS L96; L81 promote idem.
|
||||
- **`.agents/skills/work-issue/SKILL.md`** — L45–48 "consulte o GitHub" / `gh issue view <N>` → Forgejo/API da issue.
|
||||
- **`.agents/skills/work-issue/execution-pipeline.md`** — L38–40: `gh pr create/merge/checks` → API/MCP + safety net; "ignore Vercel Git" morre.
|
||||
- **`.agents/skills/plan-issue/SKILL.md`** — L16/L32/L153: "GitHub Issue rastreável"/"Nada no GitHub"/`gh issue create`/`gh pr create`/`gh pr merge --auto` → Forgejo/`pnpm agent:register`/safety net.
|
||||
- **`.agents/skills/project-status/SKILL.md`** — L3+L8 "GitHub Issues rastreáveis" → "Issues do Forgejo".
|
||||
- **`.agents/skills/capture-review-debts/SKILL.md`** — L3 "trackable GitHub Issues" → Forgejo.
|
||||
- **`.agents/skills/engineering-audit/SKILL.md`** — L16/L169 `gh pr merge --auto --rebase` → safety net (mesma mecânica dos outros).
|
||||
- **`.agents/skills/worktree-next-issue/SKILL.md`** — L34 "a skill lê o resto do GitHub" → Forgejo.
|
||||
- **`.agents/skills/agent-pool/SKILL.md`** — descrição "GitHub Actions" → Forgejo Actions; L14 `.github/workflows/agent-pool.yml` → marcada removida OPS65 (decisão 5).
|
||||
- **Migration:** sem migration. **Access/Consent:** N/A. **UI:** A — sem UI (docs-only).
|
||||
|
||||
## Fases verificáveis
|
||||
|
||||
1. **Baseline** — grep dos alvos registra o inventário do drift (já medido na exploração); o diff do PR prova o que mudou.
|
||||
2. **Docs canônicos** — AGENT-OPS → README → roadmap → AGENTS.md (verificação de fato contra `.forgejo/workflows/ci.yml`, `deploy-homeserver.sh` e `docs/ops/teqo-1313-deploy.md` durante a escrita).
|
||||
3. **`.agents` operacionais** — rule + 8 skills, edições pontuais por linha.
|
||||
4. **Gates + entrega** — `pnpm format:check` (prettier cobre .md), `pnpm changelog:build` + `pnpm changelog:check` após criar `docs/changelog/2026-08-19-ops68.md`; grep de saída zero; `pnpm push -u origin HEAD` → PR via MCP (Ready, base `main`, `Closes #74`); docs-only → CI roda os docs-guards (a suíte unit não roda por scope); safety net mergea.
|
||||
|
||||
## Rabbit holes / Não escopo (engenharia)
|
||||
|
||||
- Docs congelados/históricos (`docs/plans/*`, changelog insert-only, `GUARDRAILS.md`, `CUTOVER-MAIN-ONLY.md`, linha histórica do `nucleos-eleitorais.mdc`) — reescrever registro para a era Forgejo seria falsificar história.
|
||||
- Conteúdo genérico de skills de terceiros (`impeccable` hooks, `clean-code` references etc.).
|
||||
- Comentários de código/scripts com drift (ex.: header do `check-push-chain.mjs` citando Neon; `agent-status.mjs` "gh issue list") — fora: são código, não docs canônicos; se alguém quiser, item futuro.
|
||||
- Reescrita de frases sãs só para "uniformizar" — diff mínimo é o objetivo.
|
||||
- Reformatar arquivos inteiros com prettier — editar só as linhas do drift.
|
||||
|
||||
## Riscos e mitigação
|
||||
|
||||
- **Descrever fluxo errado** (risco principal de docs). Mitigação: cada afirmação nova verificada contra o YAML real dos workflows, `forgejo-api.mjs`/`forgejo-pr-automerge.mjs` e `AGENTS.md` (que está limpo na maior parte); o AGENT-OPS L96 e a tabela CI já estão corretos — não reescrever o que está certo.
|
||||
- **Diff grande nos `.agents`** convidando refrase acidental. Mitigação: edições linha-a-linha; `git diff` revisado contra o inventário do Passo 1.
|
||||
- **docs-guards do pre-push (OPS63)** — changelog append-only + agregado sync: a entrada nova é additions-only e `changelog:build` regenera o agregado; nenhuma restauração. Sem escape.
|
||||
- **P3 docs-only merge rápido** — sem migration/access/Consent, sem risco de prod (`.agents/`, `AGENTS.md`, `docs/` são skip de deploy pelo `.dockerignore`).
|
||||
|
||||
## Aceite de engenharia
|
||||
|
||||
- [ ] Aceite de produto da intenção coberto: docs canônicos operacionais descrevem Forgejo/homeserver; zero resíduo das classes `gh pr`, `VERCEL_*`/Neon como prod, "GitHub Issues" como fonte canônica nos 12 arquivos-alvo
|
||||
- [ ] Invariantes AGENTS/engineering-standards (sem segredos; docs congelados intactos)
|
||||
- [ ] Grep de saída zero nos alvos: `gh pr`, `gh issue`, `github.com/fsolla`, `GitHub Issues`, `VERCEL_`, `POOL_GITHUB`, `Neon` (com as exclusões explícitas de conteúdo genérico/histórico)
|
||||
- [ ] `pnpm format:check`, `pnpm changelog:build` + `pnpm changelog:check` verdes; CI docs-guards verde no PR
|
||||
|
|
@ -2,6 +2,6 @@
|
|||
|
||||
**Congelado em 2026-07-30.** Este arquivo não é mais editado.
|
||||
|
||||
- **Fonte canônica de spec/status/deps/prio/modelo:** [GitHub Issues](https://github.com/fsolla/teqo/issues) (frontmatter `id/depends/serializes/priority/model`; estado em labels `ready | in-progress | blocked | done | in-prod`). Fluxo: skills `plan-issue` → `work-issue` → `project-status` (ver `docs/AGENT-OPS.md`). Status rápido: `pnpm agent:status`.
|
||||
- **Fonte canônica de spec/status/deps/prio/modelo:** [Issues do Forgejo](https://git.solla.dev/fsolla/teqo/issues) (frontmatter `id/depends/serializes/priority/model`; estado em labels `ready | in-progress | blocked | done | in-prod`). Fluxo: skills `plan-issue` → `work-issue` → `project-status` (ver `docs/AGENT-OPS.md`). Status rápido: `pnpm agent:status`.
|
||||
- **Histórico e entregas:** [`docs/CHANGELOG-AGENTS.md`](CHANGELOG-AGENTS.md) + [`docs/plans/`](plans/).
|
||||
- **Conteúdo integral deste roadmap:** preservado no git history (última versão viva no commit imediatamente anterior a este stub).
|
||||
|
|
|
|||
Loading…
Reference in a new issue