From 24a867dfc3e4992a06ef36ca7e44859cfcb4526e Mon Sep 17 00:00:00 2001 From: Francisco Solla Date: Wed, 19 Aug 2026 17:12:24 -0300 Subject: [PATCH 01/37] =?UTF-8?q?feat(OPS71):=20CI/PR/deploy=20no=20GitHub?= =?UTF-8?q?=20Actions=20=E2=80=94=20tracker=20de=20Issues=20permanece=20no?= =?UTF-8?q?=20Forgejo=20(Closes=20#97)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .agents/rules/agent-pr-workflow.mdc | 66 ++--- .agents/skills/agent-work-issue/SKILL.md | 7 +- .agents/skills/capture-review-debts/SKILL.md | 2 +- .../skills/work-issue/execution-pipeline.md | 13 +- .../workflows/agent-pr-ready-automerge.yml | 52 ++++ .github/workflows/archive-cursor-agent.yml | 53 ++++ .github/workflows/ci-pr.yml | 223 +++++++++++++++ .github/workflows/deploy.yml | 165 +++++++++++ .../workflows/issue-done-on-main-merge.yml | 34 +++ .../plan-issue-ready-on-main-merge.yml | 49 ++++ AGENTS.md | 4 +- docs/AGENT-OPS.md | 77 ++--- docs/CHANGELOG-AGENTS.md | 2 + docs/changelog/2026-08-19-ops71.md | 1 + docs/ops/teqo-1313-deploy.md | 167 ++++++----- ...-ci-github-actions-tracker-forgejo-impl.md | 130 +++++++++ scripts/configure-branch-protection.mjs | 81 +++--- scripts/deploy-homeserver.sh | 25 +- scripts/forgejo-issue-transition.mjs | 17 +- scripts/github-pr-automerge.mjs | 69 +++++ scripts/github-pr.mjs | 64 +++++ scripts/lib/github-api.mjs | 264 ++++++++++++++++++ scripts/lib/github-branch-protection.mjs | 71 +++++ scripts/lib/github-pr-flow.mjs | 31 ++ tests/unit/githubApi.unit.spec.ts | 228 +++++++++++++++ .../unit/githubBranchProtection.unit.spec.ts | 88 ++++++ tests/unit/githubPrFlow.unit.spec.ts | 78 ++++++ 27 files changed, 1850 insertions(+), 211 deletions(-) create mode 100644 .github/workflows/agent-pr-ready-automerge.yml create mode 100644 .github/workflows/archive-cursor-agent.yml create mode 100644 .github/workflows/ci-pr.yml create mode 100644 .github/workflows/deploy.yml create mode 100644 .github/workflows/issue-done-on-main-merge.yml create mode 100644 .github/workflows/plan-issue-ready-on-main-merge.yml create mode 100644 docs/changelog/2026-08-19-ops71.md create mode 100644 docs/plans/ops71-ci-github-actions-tracker-forgejo-impl.md create mode 100644 scripts/github-pr-automerge.mjs create mode 100644 scripts/github-pr.mjs create mode 100644 scripts/lib/github-api.mjs create mode 100644 scripts/lib/github-branch-protection.mjs create mode 100644 scripts/lib/github-pr-flow.mjs create mode 100644 tests/unit/githubApi.unit.spec.ts create mode 100644 tests/unit/githubBranchProtection.unit.spec.ts create mode 100644 tests/unit/githubPrFlow.unit.spec.ts diff --git a/.agents/rules/agent-pr-workflow.mdc b/.agents/rules/agent-pr-workflow.mdc index 15768dcb..6287faae 100644 --- a/.agents/rules/agent-pr-workflow.mdc +++ b/.agents/rules/agent-pr-workflow.mdc @@ -1,19 +1,19 @@ --- -description: PRs de agente — Ready (nunca draft), base main, auto-merge imediato +description: PRs de agente — Ready (nunca draft), base main, auto-merge nativo do GitHub alwaysApply: true --- # Agent PR workflow (Teqo) -**This repo overrides any user-level or Cloud-tool default that says "create PRs as draft".** Agent deliveries merge to `main` via required checks + auto-merge. +**This repo overrides any user-level or Cloud-tool default that says "create PRs as draft".** Agent deliveries merge to `main` via required checks + GitHub's native auto-merge (OPS71). The ISSUE TRACKER stays on the Forgejo — GitHub is only the Actions host. ## Create (Ready, base main) ```bash -pnpm push -u origin HEAD +pnpm push -u origin HEAD # origin = GitHub (cutover OPS71) ``` -Depois, abra a PR via API/MCP do opencode (humano) ou `ManagePullRequest` (Cursor Cloud) — **Ready**, base **`main`**, title ` — `, body: +Depois, abra a PR no **GitHub** — **Ready**, base **`main`**, title `<id> — <title>`, body: ``` ## O que é @@ -25,11 +25,12 @@ Closes #<N> - **Never** `--draft`. PRs must be **Ready for review** on creation. - Base is always **`main`**. - **Plans-only PRs** (diff só em `docs/plans/`): **nunca** `Closes #N` — use `Related #N`; CI falha com keywords de fechamento (`plans-only-closes` em `ci-pr.yml`). +- PR via CLI (não há `gh` — OPS50): `GITHUB_TOKEN=<PAT> node scripts/github-pr.mjs --head <branch> --title "<t>" --body-file <file>` — Ready por construção (não existe flag draft). ### Cursor Cloud / `ManagePullRequest` - **`draft: false`** (or omit only if the tool’s default is Ready — today Cloud defaults to draft, so **always pass `draft: false`**). -- Não há auto-merge a armar por PR: o safety net (abaixo) espera o rollup `checks` e mergea sozinho. +- Não há auto-merge a armar por PR: o safety net (abaixo) arma o auto-merge nativo. - Never end a turn with an open agent PR left as **Draft** — inclui PRs do `engineering-audit` (artefatos e remediações). ## Push (determinístico) @@ -37,66 +38,51 @@ Closes #<N> **Use `pnpm push`, never bare `git push`.** Não depende do Husky estar wired: 1. `ensure-repo-deps` — `pnpm install` se `node_modules` faltar/stale + `pnpm run prepare` (Husky) se hooks não estiverem apontando para `.husky` -2. `pnpm gate:push` — espelho do `ci-pr.yml` sem e2e (e2e roda uma vez, no CI, após o push; local opcional: `pnpm test:e2e:affected`), com os `docs-guards` locais (OPS63: changelog append-only, agregado sync e marcadores de conflito — o escape `changelog-rewrite:` fica só no CI, body do PR) +2. `pnpm gate:push` — espelho do `ci-pr.yml` sem e2e (e2e roda no CI de PR selected/afetado, e full no `verify` do deploy manual; local opcional: `pnpm test:e2e:affected`), com os `docs-guards` locais (OPS63: changelog append-only, agregado sync e marcadores de conflito — o escape `changelog-rewrite:` fica só no CI, body do PR) 3. `git push --no-verify` — só porque o gate já rodou no passo 2 (não é escape hatch) ```bash -pnpm push -u origin HEAD # canonical +pnpm push -u origin HEAD # canonical — origin é o GitHub (OPS71) git push # só depois de `pnpm i` — hook repete ensure-deps + gate:push git push --no-verify # WIP / cutover escape — CI repete tudo; ver AGENT-OPS ``` ## Auto-merge immediately -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. +The safety net (`agent-pr-ready-automerge.yml`, abaixo) arms GitHub's **native auto-merge** (rebase) — the server merges the PR when the required check passes. There is nothing to arm per PR. Do not wait for human approval on normal deliveries. ## Required checks -Branch protection on `main` (applied 2026-08-18, OPS61) requires only: +Branch protection on `main` (GitHub, applied at the OPS71 cutover via `pnpm configure:branch-protection`) requires only: -- `CI (PR) / checks` — the ci-pr cascade rollup (the only context that covers - every ci-pr job; on the server the rule matches it as a glob, - `CI (PR) / checks*`) +- `CI (PR) / checks` — the ci-pr single-job check-run (OPS62: one sequential job posts one honest verdict; no matrix, no shards, no rollup to lie) -OPS64: the rollup is structurally honest since OPS62 — ci-pr.yml is a SINGLE -sequential job (`checks`), so its own status IS the cascade verdict (no -matrix, no shards, no parent aggregation to lie). The historical bug (Forgejo -9.0.3 reporting the LAST matrix shard's result as the parent's in `needs`, -posting `checks` SUCCESS with an e2e shard red — runs 604/607/610) is gone by -construction; the `needs.<job>.results` array of GitHub does not exist in this -runner, so any future matrix must NOT aggregate via `needs`. The safety-net -CLI pins the defense: it never trusts the rollup alone (scans individual -statuses; run-607 scenario unit-tested in `forgejoApi.unit.spec.ts`). +OPS64 history: the Forgejo runner could report the LAST matrix shard's result as the parent's (runs 604/607/610) — that bug is gone by construction: ci-pr.yml is a SINGLE sequential job, and GitHub's native auto-merge only merges with every required check green (server-side guarantee). The safety-net CLI has no poll path to port. -(`migration-lock` removed 2026-08-12 — the CI validates migration chains via migrate + int on every PR/main.) +(`migration-lock` removed 2026-08-12 — the CI validates migration chains via migrate + int on every PR.) -**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. +**There is no deploy from PR CI.** Publishing is a **manual `workflow_dispatch`** (`.github/workflows/deploy.yml`): `verify` runs the full suite (hosted) and only then the `deploy` job (self-hosted runner on the homeserver) publishes `jorgesolla1313.com.br` — migrations applied before the rollout. Do not add a Vercel/Git-integration deploy gate. -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). +When watching CI, use the PR page (or the API) — the safety net arms the server-side auto-merge; `gh` does not exist in this repo (OPS50). -Use the rollup context `CI (PR) / checks` — without it, you are not covering the cascade. +Use the required check `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, on a production change, deploys to the homeserver (OPS53/OPS65; runbook: `docs/ops/teqo-1313-deploy.md`). +There is no stage→main promote. Merging to `main` is the delivery; publishing is a deliberate manual dispatch with full verification (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 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 -e **nunca** entra no veredito). O CLI nunca confia no rollup sozinho: varre -todos os statuses individuais e falha em qualquer `failure`/`error` — um shard -de e2e vermelho bloqueia o merge mesmo com o rollup verde (OPS64; run 607). -A regra de branch protection no servidor -bloqueia o merge POST (405) enquanto o contexto exigido não estiver satisfeito -— inclusive merges manuais via API: foi um merge manual que colocou a PR #52 -em main com o CI vermelho (o CLI nunca mergeou sozinho antes do OPS61; todo -merge Forgejo era manual). +O workflow roda `scripts/github-pr-automerge.mjs` (plain Node, zero-dep, +REST+GraphQL): se draft `cursor/*` → marca Ready (PATCH `draft: false`); arm +`enablePullRequestAutoMerge` (GraphQL, mergeMethod REBASE) no `node_id` do PR +— o **servidor** espera o required check `CI (PR) / checks` POSTADO e verde +antes de mergear; o próprio check-run do safety net fica `pending` durante o +run e não interfere. A regra de branch protection no servidor +(`enforce_admins: true`) bloqueia qualquer caminho de merge — inclusive API +manual — enquanto o required check não estiver satisfeito (foi um merge +manual que colocou a PR #52 em main com o CI vermelho na era Forgejo). Cobre o caso em que o agente (ou o default draft do Cloud) esqueceu e PRs humanas/worktree com merge falho silencioso (incidente OPS52). **Draft de branch não-`cursor/*` nunca é diff --git a/.agents/skills/agent-work-issue/SKILL.md b/.agents/skills/agent-work-issue/SKILL.md index eed2e251..7d0ea9af 100644 --- a/.agents/skills/agent-work-issue/SKILL.md +++ b/.agents/skills/agent-work-issue/SKILL.md @@ -35,7 +35,7 @@ Conduz **uma** Issue já claimada do plano de implementação ao merge em `main` - [ ] 3. Plan mode → plano de implementação (`*-impl.md`) - [ ] 4. Executar o impl plan (schema/server → UI → gates) - [ ] 5. /simplify → fixes; capture-review-debts (modo autônomo) -- [ ] 6. PR Ready `--base main` + auto-merge + checks --required +- [ ] 6. PR Ready `--base main` (GitHub) + auto-merge nativo — `pnpm push -u origin HEAD` → `node scripts/github-pr.mjs` (ou `ManagePullRequest` `draft: false` no Cloud) ``` ## Passo 0 — Prep @@ -84,8 +84,9 @@ O spawn do pool já fixou o modelo (`model:` da Issue — ver `model-selection`) (Issues novas com `depends: [<id-pai>]` se necessário); score ≤3 / cheap_polish / defer_trigger → defer com gatilho no `*-impl.md` ou descarte — **não** polua a fila. -- **Cloud:** PR via `ManagePullRequest` com `draft: false`; Prep Cloud no - Passo 0. +- **Cloud:** PR via `ManagePullRequest` com `draft: false` no **GitHub** + (repo/PR agora no GitHub; o tracker de Issues segue no Forgejo — OPS71); + Prep Cloud no Passo 0. ## Resumo final diff --git a/.agents/skills/capture-review-debts/SKILL.md b/.agents/skills/capture-review-debts/SKILL.md index 7362bf54..7ddf8d4a 100644 --- a/.agents/skills/capture-review-debts/SKILL.md +++ b/.agents/skills/capture-review-debts/SKILL.md @@ -144,7 +144,7 @@ Para cada lote com destino **registrar** ou **absorver**: Não implemente as fases aqui. Execução é via `work-issue` / `agent-work-issue`, só se o usuário (ou o pipeline autônomo) seguir. -**Próximo no fluxo de entrega:** após a triage (confirmada ou modo autônomo), o fechamento segue o Passo 6 de `agent-work-issue` / `work-issue` (`pnpm push` → PR `--base main` com `Closes #N` → auto-merge → CI). +**Próximo no fluxo de entrega:** após a triage (confirmada ou modo autônomo), o fechamento segue o Passo 6 de `agent-work-issue` / `work-issue` (`pnpm push` → PR no GitHub `--base main` com `Closes #N` → auto-merge nativo → CI). ## Modo autônomo (`work-issue` pós-plano / `agent-work-issue` / pool) diff --git a/.agents/skills/work-issue/execution-pipeline.md b/.agents/skills/work-issue/execution-pipeline.md index ce04e538..51395140 100644 --- a/.agents/skills/work-issue/execution-pipeline.md +++ b/.agents/skills/work-issue/execution-pipeline.md @@ -34,10 +34,15 @@ entrega. e rode `pnpm changelog:build` para regenerar `docs/CHANGELOG-AGENTS.md` (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 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. +3. **`pnpm push -u origin HEAD`** — origin é o **GitHub** (OPS71; o tracker de + Issues continua no Forgejo por API). +4. PR no **GitHub** via `GITHUB_TOKEN=<PAT> node scripts/github-pr.mjs --head <branch> --title "<id> — <título>" --body-file <arquivo>` — **Ready** (nunca draft; o script não tem flag draft), base `main`, body com `Closes #<N>` (ou `Related #N` em plans-only). Em Cursor Cloud: `ManagePullRequest` com `draft: false`. +5. O safety net `agent-pr-ready-automerge.yml` arma o **auto-merge nativo do + GitHub** (`enablePullRequestAutoMerge`, rebase) — o servidor mergea quando + o required check `CI (PR) / checks` fica verde; nada a armar. +6. No merge, o workflow `issue-done-on-main-merge.yml` flipa `done`/`in-prod` + **no Forgejo** (lê o body do PR via API do GitHub, escreve no tracker por + `FORGEJO_API_TOKEN`). Comente na Issue o desfecho em uma linha. ## Deltas por ator diff --git a/.github/workflows/agent-pr-ready-automerge.yml b/.github/workflows/agent-pr-ready-automerge.yml new file mode 100644 index 00000000..ece4c3b2 --- /dev/null +++ b/.github/workflows/agent-pr-ready-automerge.yml @@ -0,0 +1,52 @@ +# Safety net (OPS71 — GitHub): every same-repo PR to main must be Ready + +# auto-merge armed. Covers Cloud ManagePullRequest defaulting to draft, +# agents that forget to arm the merge, and human/worktree PRs (the OPS52 +# incident was a human PR whose merge failed silently). Draft PRs from +# non-`cursor/*` branches are never touched — the draft flag is the actor's +# veto (the CLI skips them). Fork PRs are excluded (the repo is public; a +# merged fork PR would deploy) — same RCE-guard class as the other workflows. +# +# GitHub's NATIVE auto-merge replaces the Forgejo-era poll CLI +# (forgejo-pr-automerge.mjs): `enablePullRequestAutoMerge` (GraphQL, REBASE — +# the repo's canonical merge style) is server-side — GitHub only merges when +# every required check (the `CI (PR) / checks` rollup of ci-pr.yml, OPS62) is +# green and the PR is mergeable. The OPS64 "rollup can lie" defense is +# structural here: a single sequential job posts one honest check-run and the +# server enforces it — nothing to poll, nothing to trust. +# +# Permissions: contents+pull-requests write — enough for PATCH draft:false +# and the GraphQL auto-merge mutation with the built-in GITHUB_TOKEN. +name: 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: + # Same-repo only. This MUST stay in the `if:` (pre-checkout): for a fork + # PR, actions/checkout checks out the fork's head, so a same-repo guard + # inside the CLI would already be running the fork's own script — RCE + # with the Actions token. The draft policy lives in the CLI (skips + # non-`cursor/*` drafts) because there the PR state is re-read from the + # API, not from webhook payload fields. + if: >- + github.event.pull_request.state == 'open' && + github.event.pull_request.head.repo.full_name == github.repository + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v5 + # Script is plain Node (stdlib) — no pnpm. Disable package-manager-cache: + # setup-node@v5 defaults to true and looks for pnpm before pnpm/action-setup. + - uses: actions/setup-node@v5 + with: + node-version: 24 + package-manager-cache: false + - name: Mark Ready and arm auto-merge + run: node scripts/github-pr-automerge.mjs --pr "${{ github.event.pull_request.number }}" diff --git a/.github/workflows/archive-cursor-agent.yml b/.github/workflows/archive-cursor-agent.yml new file mode 100644 index 00000000..614c5708 --- /dev/null +++ b/.github/workflows/archive-cursor-agent.yml @@ -0,0 +1,53 @@ +# Operator helper: cancel+archive a Cursor Cloud agent (CURSOR_API_KEY secret). +name: Archive Cursor agent (ops) +on: + workflow_dispatch: + inputs: + agent_id: + description: Cursor agent id (bc-…) + required: true + type: string + run_id: + description: Cursor run id (run-…) optional cancel first + required: false + type: string +permissions: + contents: read +jobs: + archive: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + - uses: actions/setup-node@v5 + with: + node-version: 24 + package-manager-cache: false + - name: Cancel run (if any) + archive agent + env: + CURSOR_API_KEY: ${{ secrets.CURSOR_API_KEY }} + AGENT_ID: ${{ inputs.agent_id }} + RUN_ID: ${{ inputs.run_id }} + run: | + node --input-type=module <<'NODE' + import { + archiveCursorAgent, + cancelCursorRun, + } from './scripts/lib/agent-pool-cursor.mjs' + + const agentId = process.env.AGENT_ID + const runId = process.env.RUN_ID?.trim() + if (!process.env.CURSOR_API_KEY) { + console.error('CURSOR_API_KEY missing') + process.exit(1) + } + if (runId) { + try { + await cancelCursorRun(agentId, runId) + console.log('cancelled', runId) + } catch (error) { + console.warn('cancel failed (continuing):', error.message) + } + } + await archiveCursorAgent(agentId) + console.log('archived', agentId) + NODE diff --git a/.github/workflows/ci-pr.yml b/.github/workflows/ci-pr.yml new file mode 100644 index 00000000..6a049527 --- /dev/null +++ b/.github/workflows/ci-pr.yml @@ -0,0 +1,223 @@ +# PR gate: feature → main (OPS71 — GitHub Actions). SINGLE sequential job +# (OPS62, X1): one container, one checkout, one pnpm install, one runner slot. +# Fail-fast is STRUCTURAL — a failed step skips every step after it, the job +# fails and the run fails. GitHub-native `concurrency` cancels the in-flight +# run when the PR gets a new push (the Forgejo era had no cancel API; here it +# is free and matches the OPS62 "one slot per PR" spirit). +# +# The job id `checks` preserves the `CI (PR) / checks` check-run that the +# branch protection rule and the native auto-merge rely on (OPS71): GitHub +# names it <workflow name> / <job name> — keep both literals frozen. GitHub's +# auto-merge is server-side: it only merges with every required check green, +# so the OPS64 "rollup can lie" defense is structural here (single job posts +# one honest check-run; no matrix, no shards). +# +# Job-level skips come from the `scope` classifier (scripts/ci-scope.mjs) run +# as a step; its outputs drive `if:` on the heavy steps (same modes as the +# Forgejo cascade: none/changed/full). e2e policy: selected (affected) specs +# on PRs — OPS72 tunes the local-affected flow afterwards. +# +# Schema migrations are NOT serialized across PRs (migration-lock removed +# 2026-08-12): a stale chain is caught by `pnpm migrate` + `test:int` on every +# PR, incl. campaignMigrationReconciliation. +# +# Fork-PRs are excluded at job level (`if:` same-repo): the repo is public and +# a fork PR would burn hosted minutes running arbitrary code. Same guard class +# as the RCE guard on the post-merge workflows. +# +# Postgres services live on the job network and are reached by NAME +# (postgres-int / postgres-build on 5432) — no host publish, so concurrent +# runs never collide on host ports. Two isolated services keep e2e from +# inheriting int fixture residue. +name: CI (PR) + +on: + pull_request: + branches: [main] + +permissions: + contents: read + +concurrency: + group: ci-pr-${{ github.head_ref }} + cancel-in-progress: true + +env: + PAYLOAD_SECRET: test-only-secret-not-used-in-production + NEXT_PUBLIC_SITE_URL: http://localhost:3000 + +jobs: + checks: + if: github.event.pull_request.head.repo.full_name == github.repository + runs-on: ubuntu-latest + timeout-minutes: 50 + services: + # Services are reached by NAME on the job network (no host publish): + # concurrent runs never collide on host ports, which the single + # long-lived job would hold for the whole run. Two isolated services — + # int and build+e2e — keep e2e from inheriting int fixture residue. + postgres-int: + image: postgres:17-alpine + env: + POSTGRES_USER: teqo + POSTGRES_PASSWORD: teqo + POSTGRES_DB: teqo_test + options: >- + --health-cmd "pg_isready -U teqo" + --health-interval 5s + --health-timeout 5s + --health-retries 12 + postgres-build: + image: postgres:17-alpine + env: + POSTGRES_USER: teqo + POSTGRES_PASSWORD: teqo + POSTGRES_DB: teqo_test + options: >- + --health-cmd "pg_isready -U teqo" + --health-interval 5s + --health-timeout 5s + --health-retries 12 + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + - uses: pnpm/action-setup@v6 + - uses: actions/setup-node@v5 + with: + node-version: 24 + cache: pnpm + - run: pnpm install --frozen-lockfile + + - name: Classify PR blast radius + id: scope + env: + GITHUB_BASE_REF: ${{ github.base_ref }} + run: | + set -euo pipefail + result=$(node scripts/ci-scope.mjs) + echo "scope: $(echo "$result" | jq -c '{code:.code.mode,build:.build.mode,test:.test.mode,e2e:.e2e.mode,reason:{code:.code.reason,build:.build.reason,test:.test.reason,e2e:.e2e.reason}}')" + echo "code_mode=$(echo "$result" | jq -r .code.mode)" >> "$GITHUB_OUTPUT" + echo "build_mode=$(echo "$result" | jq -r .build.mode)" >> "$GITHUB_OUTPUT" + echo "test_mode=$(echo "$result" | jq -r .test.mode)" >> "$GITHUB_OUTPUT" + echo "e2e_mode=$(echo "$result" | jq -r .e2e.mode)" >> "$GITHUB_OUTPUT" + echo "e2e_specs=$(echo "$result" | jq -r '[.e2e.specs[] | "tests/e2e/" + . + ".e2e.spec.ts"] | join(" ")')" >> "$GITHUB_OUTPUT" + + # Content guards are PR-scoped and cheap — run them before the suite so + # a guard failure fails fast instead of after 20 minutes of tests. + - name: Changelog is append-only + env: + GITHUB_BASE_REF: ${{ github.base_ref }} + PR_BODY: ${{ github.event.pull_request.body }} + run: node scripts/check-changelog-append-only.mjs + - name: Aggregate is up to date with docs/changelog + run: node scripts/build-changelog.mjs --check + - name: No conflict markers in markdown diffs + env: + GITHUB_BASE_REF: ${{ github.base_ref }} + run: node scripts/check-docs-conflict-markers.mjs + - name: Block Closes/Fixes/Resolves on plans-only PRs + env: + GITHUB_BASE_REF: ${{ github.base_ref }} + PR_BODY: ${{ github.event.pull_request.body }} + run: node scripts/check-plans-only-pr-closes.mjs + + - name: Check test file locations + run: node scripts/check-test-locations.mjs + - name: Lint + run: pnpm lint + - name: Format check + run: pnpm format:check + - name: Typecheck + if: steps.scope.outputs.code_mode != 'none' + run: pnpm typecheck + - name: Knip + if: steps.scope.outputs.code_mode != 'none' + run: pnpm knip + - name: Check cycles + if: steps.scope.outputs.code_mode != 'none' + run: pnpm check:cycles + + - name: Unit tests (full suite) + if: steps.scope.outputs.test_mode == 'full' + run: pnpm test:unit + - name: Unit tests (changed since PR base) + if: steps.scope.outputs.test_mode == 'changed' + run: pnpm test:unit -- --changed origin/${{ github.base_ref }} --passWithNoTests + - name: Prepare database URL (int service) + run: | + set -euo pipefail + echo "DATABASE_URL=postgresql://teqo:teqo@postgres-int:5432/teqo_test" >> "$GITHUB_ENV" + # vitest re-loads .env.test over the process env, so the service URL + # must win through the .env.test.local layer (same mechanism + # `pnpm worktree next` uses). OPS50. + echo "DATABASE_URL=postgresql://teqo:teqo@postgres-int:5432/teqo_test" > .env.test.local + - name: Migrate (int database) + run: pnpm migrate + - name: Seed minimal (int database) + run: pnpm db:seed:minimal + + - name: Integration tests (full suite) + if: steps.scope.outputs.test_mode == 'full' + env: + # vitest forks ≈ CPUs and each fork holds a Payload pool (max 10) → + # overflows the service Postgres' 100 clients ("too many clients + # already"). 4 forks stay well under. The unit step above stays + # CPU-relative (no DB). + VITEST_MAX_WORKERS: 4 + run: pnpm test:int + - name: Integration tests (changed since PR base) + if: steps.scope.outputs.test_mode == 'changed' + env: + VITEST_MAX_WORKERS: 4 + run: pnpm test:int -- --changed origin/${{ github.base_ref }} --passWithNoTests + + - name: Prepare database URL (build/e2e service) + if: steps.scope.outputs.build_mode != 'none' || steps.scope.outputs.e2e_mode != 'none' + run: | + set -euo pipefail + echo "DATABASE_URL=postgresql://teqo:teqo@postgres-build:5432/teqo_test" >> "$GITHUB_ENV" + echo "DATABASE_URL=postgresql://teqo:teqo@postgres-build:5432/teqo_test" > .env.test.local + - name: Migrate (build/e2e database) + if: steps.scope.outputs.build_mode != 'none' || steps.scope.outputs.e2e_mode != 'none' + run: pnpm migrate + - name: Seed minimal (build/e2e database) + if: steps.scope.outputs.build_mode != 'none' || steps.scope.outputs.e2e_mode != 'none' + run: pnpm db:seed:minimal + + - name: Build (against the local service database) + if: steps.scope.outputs.build_mode != 'none' + run: pnpm build + + - name: Cache Playwright browsers + if: steps.scope.outputs.e2e_mode != 'none' + uses: actions/cache@v4 + with: + path: ~/.cache/ms-playwright + key: playwright-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }} + restore-keys: | + playwright-${{ runner.os }}- + - name: Install Playwright chromium + if: steps.scope.outputs.e2e_mode != 'none' + run: pnpm exec playwright install --with-deps chromium + - name: Build for e2e + # Selected mode needs the build too (the Playwright webServer serves + # .next-e2e; the fallback `.next-e2e` dir is what gate-ci.mjs builds). + if: steps.scope.outputs.e2e_mode != 'none' + run: pnpm build + env: + NEXT_DIST_DIR: .next-e2e + - name: E2E tests (full suite, single job, 4 workers) + if: steps.scope.outputs.e2e_mode == 'full' + # Explicit CI workers; the local default stays 2 (playwright.config.ts). + # 4 workers in one process replace the former 2 shards × 2 workers. + # No `--` separator: pnpm would forward it verbatim to playwright and + # the flag would be parsed as a file pattern ("No tests found"). + env: + PLAYWRIGHT_WORKERS: 4 + run: pnpm test:e2e + - name: E2E tests (manifest-selected specs) + if: steps.scope.outputs.e2e_mode == 'selected' + env: + PLAYWRIGHT_WORKERS: 4 + run: pnpm test:e2e -- ${{ steps.scope.outputs.e2e_specs }} diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 00000000..c6f4961b --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,165 @@ +# Manual production deploy (OPS71 — GitHub Actions). `workflow_dispatch` +# only: there is NO automatic main verifier anymore (ci.yml eliminated in the +# gate 2026-08-19) — publishing is a deliberate operator act, and this +# workflow runs the FULL suite (no scope skips, e2e included) before the +# deploy job touches the homeserver. +# +# TWO jobs, same workflow: +# verify — ubuntu-latest (hosted): full cascade (guards for PR contracts are +# left out — they gate PRs, not production). +# deploy — needs: [verify], runs-on [self-hosted, homeserver]: the GitHub +# self-hosted runner ON the homeserver executes +# scripts/deploy-homeserver.sh LOCALLY (no SSH; outbound-only +# runner, works behind the Cloudflare tunnel). The hosted job +# never reaches the homeserver; the self-hosted job never counts +# hosted minutes. +# +# The production build CANNOT leave the homeserver (migrate pre-build on the +# prod DB — OPS66 — and the compose network / local registry localhost:5000), +# which is exactly why the hosted job only verifies and the self-hosted job +# only builds + deploys. Deploy is idempotent ("already deployed" guard in +# deploy-homeserver.sh) and serialized by flock on the homeserver. +# +# The `deploy` job fetches the repo from github.com (public) — TEQO_REPO_URL +# in deploy-homeserver.sh now defaults there; the script's HEAD guard only +# deploys when the dispatched SHA is main's HEAD (a stale dispatch skips). + +name: Deploy (manual) + +on: + workflow_dispatch: + +permissions: + contents: read + +env: + PAYLOAD_SECRET: test-only-secret-not-used-in-production + NEXT_PUBLIC_SITE_URL: http://localhost:3000 + +jobs: + verify: + runs-on: ubuntu-latest + timeout-minutes: 50 + services: + # Services are reached by NAME on the job network (no host publish). + # Two isolated services — int and build+e2e — keep e2e from inheriting + # int fixture residue. + postgres-int: + image: postgres:17-alpine + env: + POSTGRES_USER: teqo + POSTGRES_PASSWORD: teqo + POSTGRES_DB: teqo_test + options: >- + --health-cmd "pg_isready -U teqo" + --health-interval 5s + --health-timeout 5s + --health-retries 12 + postgres-build: + image: postgres:17-alpine + env: + POSTGRES_USER: teqo + POSTGRES_PASSWORD: teqo + POSTGRES_DB: teqo_test + options: >- + --health-cmd "pg_isready -U teqo" + --health-interval 5s + --health-timeout 5s + --health-retries 12 + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + - uses: pnpm/action-setup@v6 + - uses: actions/setup-node@v5 + with: + node-version: 24 + cache: pnpm + - run: pnpm install --frozen-lockfile + + - name: Check test file locations + run: node scripts/check-test-locations.mjs + - name: Lint + run: pnpm lint + - name: Format check + run: pnpm format:check + - name: Typecheck + run: pnpm typecheck + - name: Knip + run: pnpm knip + - name: Check cycles + run: pnpm check:cycles + - name: Unit tests (full suite) + run: pnpm test:unit + + - name: Prepare database URL (int service) + run: | + set -euo pipefail + echo "DATABASE_URL=postgresql://teqo:teqo@postgres-int:5432/teqo_test" >> "$GITHUB_ENV" + # vitest re-loads .env.test over the process env, so the service URL + # must win through the .env.test.local layer (same mechanism + # `pnpm worktree next` uses). + echo "DATABASE_URL=postgresql://teqo:teqo@postgres-int:5432/teqo_test" > .env.test.local + - name: Migrate (int database) + run: pnpm migrate + - name: Seed minimal (int database) + run: pnpm db:seed:minimal + - name: Integration tests (full suite) + env: + # vitest forks ≈ CPUs and each fork holds a Payload pool (max 10) → + # overflows the service Postgres' 100 clients. 4 forks stay well + # under. The unit step above stays CPU-relative (no DB). + VITEST_MAX_WORKERS: 4 + run: pnpm test:int + + - name: Prepare database URL (build/e2e service) + run: | + set -euo pipefail + echo "DATABASE_URL=postgresql://teqo:teqo@postgres-build:5432/teqo_test" >> "$GITHUB_ENV" + echo "DATABASE_URL=postgresql://teqo:teqo@postgres-build:5432/teqo_test" > .env.test.local + - name: Migrate (build/e2e database) + run: pnpm migrate + - name: Seed minimal (build/e2e database) + run: pnpm db:seed:minimal + - name: Build (against the service database) + run: pnpm build + + - name: Cache Playwright browsers + uses: actions/cache@v4 + with: + path: ~/.cache/ms-playwright + key: playwright-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }} + restore-keys: | + playwright-${{ runner.os }}- + - name: Install Playwright chromium + run: pnpm exec playwright install --with-deps chromium + - name: Build for e2e + # Same dir the Playwright webServer serves (playwright.config.ts + # falls back to '.next-e2e'; gate-ci.mjs builds there too). + run: pnpm build + env: + NEXT_DIST_DIR: .next-e2e + - name: E2E tests (full suite, single job, 4 workers) + # Explicit CI workers; the local default stays 2 (playwright.config.ts). + # No `--` separator: pnpm would forward it verbatim to playwright and + # the flag would be parsed as a file pattern ("No tests found"). + env: + PLAYWRIGHT_WORKERS: 4 + run: pnpm test:e2e + + deploy: + name: deploy homeserver (teqo-1313) + # OPS53 + OPS71. Runs on the GitHub self-hosted runner ON the homeserver + # (labels self-hosted + homeserver): the script executes locally — no SSH + # hop, no workstation involvement. Deliberately wired ONLY here (manual + # dispatch), never in ci-pr.yml: a self-hosted job is code execution on + # the production machine, and only an explicit dispatch with the full + # verify suite green can reach it. + needs: [verify] + if: needs.verify.result == 'success' + runs-on: [self-hosted, homeserver] + timeout-minutes: 60 + steps: + - uses: actions/checkout@v5 + - name: Deploy teqo-1313 on the homeserver + run: bash scripts/deploy-homeserver.sh "$GITHUB_SHA" diff --git a/.github/workflows/issue-done-on-main-merge.yml b/.github/workflows/issue-done-on-main-merge.yml new file mode 100644 index 00000000..989caed4 --- /dev/null +++ b/.github/workflows/issue-done-on-main-merge.yml @@ -0,0 +1,34 @@ +# Main merge flips claimed issues to done + in-prod. +# OPS71: the PR lives on GitHub; the ISSUES stay on the Forgejo tracker. The +# job passes the PR body via PR_BODY (GitHub event payload) and +# scripts/forgejo-issue-transition.mjs flips labels/comments on the Forgejo +# API with the FORGEJO_API_TOKEN PAT (the built-in GITHUB_TOKEN cannot touch +# Forgejo issues — OPS61). The fork guard is the same class as +# agent-pr-ready-automerge.yml: on a merged fork PR the checkout pulls the +# fork's own script, which would run with the repo PAT (RCE). +name: Main merge flips claimed issues to done + in-prod + +on: + pull_request: + types: [closed] + +permissions: + contents: read + +jobs: + issue-done: + if: github.event.pull_request.base.ref == 'main' && github.event.pull_request.merged == true && github.event.pull_request.head.repo.full_name == github.repository + runs-on: ubuntu-latest + env: + FORGEJO_API_TOKEN: ${{ secrets.FORGEJO_API_TOKEN }} + PR_BODY: ${{ github.event.pull_request.body }} + steps: + - uses: actions/checkout@v5 + # Script is plain Node (stdlib) — no pnpm. Disable package-manager-cache: + # setup-node@v5 defaults to true and looks for pnpm before pnpm/action-setup. + - uses: actions/setup-node@v5 + with: + node-version: 24 + package-manager-cache: false + - name: Flip Closes/Fixes #N issues to done and in-prod + run: node scripts/forgejo-issue-transition.mjs --pr "${{ github.event.pull_request.number }}" diff --git a/.github/workflows/plan-issue-ready-on-main-merge.yml b/.github/workflows/plan-issue-ready-on-main-merge.yml new file mode 100644 index 00000000..ed3048ea --- /dev/null +++ b/.github/workflows/plan-issue-ready-on-main-merge.yml @@ -0,0 +1,49 @@ +# Safety net OPS18: when a PR merges to main with `Related #N`, promote Issues +# that are still awaiting their intention plan (`blocked` + docs/plans/ link) +# to `ready`. Idempotent with `pnpm agent:ready` (agent happy path). OPS71: +# the PR lives on GitHub, the issues on the Forgejo tracker — the job passes +# the PR body via PR_BODY and scripts/agent-promote-related-on-merge.mjs flips +# labels on the Forgejo API (FORGEJO_API_TOKEN; the built-in GITHUB_TOKEN +# cannot touch Forgejo issues — OPS61). +# +# Does NOT run on open PRs — only after merge — so the claim race stays closed. +# Job is gated on Related # in the body so non-plan merges skip checkout/Node. +# Fork guard: on a merged fork PR the checkout pulls the fork's own script, +# which would run with the repo PAT (RCE — same class as +# agent-pr-ready-automerge.yml). +name: Promote plan-issue Related on main merge + +on: + pull_request: + types: [closed] + branches: [main] + +permissions: + contents: read + +jobs: + plan-issue-ready: + if: >- + github.event.pull_request.merged == true && + github.event.pull_request.head.repo.full_name == github.repository && + ( + contains(github.event.pull_request.body, 'Related #') || + contains(github.event.pull_request.body, 'related #') || + contains(github.event.pull_request.body, 'RELATED #') + ) + runs-on: ubuntu-latest + timeout-minutes: 5 + env: + FORGEJO_API_TOKEN: ${{ secrets.FORGEJO_API_TOKEN }} + PR_BODY: ${{ github.event.pull_request.body }} + steps: + - uses: actions/checkout@v5 + # Script is plain Node (stdlib) — no pnpm. Disable + # package-manager-cache: setup-node@v5 defaults to true and looks for + # pnpm (packageManager in package.json) before pnpm/action-setup. + - uses: actions/setup-node@v5 + with: + node-version: 24 + package-manager-cache: false + - name: Promote Related #N awaiting plan → ready + run: node scripts/agent-promote-related-on-merge.mjs --pr "${{ github.event.pull_request.number }}" diff --git a/AGENTS.md b/AGENTS.md index ab3eca86..c0cb96f5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -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 (`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. +- 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). **CI/PR/deploy live on GitHub Actions (OPS71, 2026-08-19); the ISSUE TRACKER stays on the Forgejo** (`git.solla.dev/fsolla/teqo` — labels, claims, `pnpm issue`/`agent:*` and the post-merge flips all keep talking to the Forgejo API; GitHub is only the Actions host). The PR CI (`ci-pr.yml`, job único `checks` — OPS62) runs the same cascade as always (guards → lint → format → typecheck → knip → cycles → unit → int → build → e2e selected/afetado, skips via `ci-scope.mjs`); its check-run `CI (PR) / checks` is the required check of `main` and the gate of the **native auto-merge** (`agent-pr-ready-automerge.yml` → `scripts/github-pr-automerge.mjs`, GraphQL `enablePullRequestAutoMerge`, rebase — the server only merges with the required check green). **There is NO main verifier (`ci.yml`) anymore**: publishing is a **manual `workflow_dispatch`** (`.github/workflows/deploy.yml`) with two jobs — `verify` (hosted `ubuntu-latest`, suíte **full** incl. e2e full) → `deploy` (`needs: [verify]`, `runs-on: [self-hosted, homeserver]`): the GitHub self-hosted runner ON the homeserver executes `scripts/deploy-homeserver.sh` **locally** (no SSH; outbound-only runner, works behind the tunnel; the hosted job never touches the homeserver). 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; the repo comes from `TEQO_REPO_URL` (default `https://github.com/fsolla/teqo.git`, public). `pnpm push` pushes to `origin` — **the GitHub remote** (one-time local cutover: `git remote set-url origin git@github.com:fsolla/teqo.git`; the Forgejo stays as a secondary remote and its git repo freezes at the cutover point — tracker intacto por API). The Forgejo-era files (`.forgejo/workflows/`, `forgejo-pr-automerge.mjs`, `forgejo-dispatch.mjs`, `ci-classify-production.mjs`) are preserved as rollback until the OPS71 Fase 2 removal. Runbook (rollback, falhas conhecidas, passos do cutover): `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. @@ -158,7 +158,7 @@ The artifact is at **v3**: v2 added E8's `campoFederalVotesByYear` / `federalTal 1. Confirm `DATABASE_URL` is `postgresql://teqo:teqo@localhost:5432/teqo` and `.env.test` points to `teqo_test`; never use the homeserver prod DB for development, tests, E2E, or local builds. In a provisioned worktree (`pnpm worktree next`) the values come from its `.env.local` / `.env.test.local` (`teqo_wt<slot>` / `teqo_wt<slot>_test`, dev port `3100+slot`) — read them there instead of assuming the main-repo names. 2. Run `pnpm db:start`, `pnpm migrate:status`, and `DATABASE_URL=postgresql://teqo:teqo@localhost:5432/teqo_test pnpm migrate:status`; every migration must show `Ran: Yes`. -3. Run `pnpm generate:types`, `pnpm generate:importmap` when components changed — **com as envs `S3_*` setadas (valores dummy ok) enquanto o plugin `s3Storage` for condicional: sem elas o importMap fica órfão do `S3ClientUploadHandler` e o admin abre em branco em produção (OPS69, P0 em 2026-08-19)** —, `pnpm exec tsc --noEmit`, `pnpm lint` (zero warnings — the script enforces `--max-warnings=0`), `pnpm format:check` (Prettier is the formatting authority; `pnpm format` fixes), `pnpm exec knip` (dead files/dependencies are CI-blocking; delete what your change orphaned), `pnpm check:cycles` (madge — zero circular imports), `pnpm test` (unit + int), and `pnpm build` against the local database. Payload CLI scripts (`migrate`, `generate:*`, `payload`) and the build migrate step use `--conditions=react-server` so `server-only` modules load correctly outside Next.js. **O e2e não roda mais no gate local (OPS59):** ele roda **uma vez, no CI** (PR e main — gateia merge e deploy); local opcional para feedback antecipado: `pnpm test:e2e:affected` (gera `--no-deps` para runs filtrados — S6-FOLLOWUP: no dev mode a cadeia de dependencies dos projects arrasta os arquivos das dependências via closure; filtros manuais locais: `pnpm test:e2e --no-deps -- <path>` ou `--no-deps --project=<família>`). +3. Run `pnpm generate:types`, `pnpm generate:importmap` when components changed — **com as envs `S3_*` setadas (valores dummy ok) enquanto o plugin `s3Storage` for condicional: sem elas o importMap fica órfão do `S3ClientUploadHandler` e o admin abre em branco em produção (OPS69, P0 em 2026-08-19)** —, `pnpm exec tsc --noEmit`, `pnpm lint` (zero warnings — the script enforces `--max-warnings=0`), `pnpm format:check` (Prettier is the formatting authority; `pnpm format` fixes), `pnpm exec knip` (dead files/dependencies are CI-blocking; delete what your change orphaned), `pnpm check:cycles` (madge — zero circular imports), `pnpm test` (unit + int), and `pnpm build` against the local database. Payload CLI scripts (`migrate`, `generate:*`, `payload`) and the build migrate step use `--conditions=react-server` so `server-only` modules load correctly outside Next.js. **O e2e não roda mais no gate local (OPS59):** ele roda **no CI** — no PR (selected/afetado, via `ci-scope.mjs`) e **full no `verify` do deploy manual** (gateia merge e deploy); local opcional para feedback antecipado: `pnpm test:e2e:affected` (gera `--no-deps` para runs filtrados — S6-FOLLOWUP: no dev mode a cadeia de dependencies dos projects arrasta os arquivos das dependências via closure; filtros manuais locais: `pnpm test:e2e --no-deps -- <path>` ou `--no-deps --project=<família>`). - Never run `knip --fix` blind: when knip's module graph is incomplete (it still cannot load `payload.config.ts` — ledgered as P3), `--fix` deletes exports that migrations/tests still reference. Verify each removal (e.g. `git grep -w <symbol>`) before deleting. - Run gate commands bare — never piped (`pnpm test | tail` swallows the exit code, and a real failure was masked exactly this way during Pass 2). Large outputs are captured by the terminal; read them from there. 4. Scan every edited runtime source file with Aikido and resolve new findings before handoff. Do not expand hardening work into unrelated pre-existing findings without an explicit scope change. diff --git a/docs/AGENT-OPS.md b/docs/AGENT-OPS.md index 4bb416b1..a6282ab4 100644 --- a/docs/AGENT-OPS.md +++ b/docs/AGENT-OPS.md @@ -1,27 +1,27 @@ # AGENT-OPS — operação do paradigma de agentes paralelos -Uma página. Norte: simplicidade (só Forgejo + Cursor), agente entrega em `main`, deploy de produção só após o verificador full-suite verde. +Uma página. Norte: simplicidade (Forgejo = tracker, GitHub = Actions), agente entrega em `main`, deploy de produção é **manual** com verificação full (OPS71). ## Ambientes de dados (test ladder — nunca misturar) -| Ambiente | Conteúdo | Quem usa | -| ------------------------------------------- | ------------------------------------------------------------ | -------------------------------- | -| **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) | +| Ambiente | Conteúdo | Quem usa | +| ------------------------------------------- | ------------------------------------------------------------ | -------------------------------------------- | +| **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 `deploy.yml` (OPS53 + OPS71) | 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 ```text -claim → feature branch → PR --base main → CI PR green (cascade + skips) → auto-merge em main -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) +claim → feature branch → PR --base main (GitHub) → CI PR green (cascade + skips) → auto-merge nativo em main (rebase) +main → (opcional, deliberado) workflow_dispatch deploy.yml → verify full suite verde → job deploy no homeserver (OPS53) ``` -**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`). +**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` (GitHub) → `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 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`). +- **Agente faz sozinho:** claim (pool-supervisor no pool; humano via `pnpm agent:claim` fora da sessão — OPS33: `worktree next` claima) → implementa → **`pnpm push`** (origin = GitHub) → PR via `node scripts/github-pr.mjs` **Ready** (nunca draft) com `Closes #N` → o safety net `agent-pr-ready-automerge.yml` arma o **auto-merge nativo do GitHub** (`enablePullRequestAutoMerge`, rebase) — o servidor mergea quando o required check `CI (PR) / checks` fica verde. 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), `GITHUB_TOKEN` local (PAT) para os scripts GitHub, secrets no repo GitHub, `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 @@ -36,28 +36,29 @@ main → ci.yml (janela de 30 min, OPS65) full suite verde → job `deploy` (hom | Comando | Faz | | ------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | -| `pnpm agent:claim [-- --dry-run]` | Fila ready+unblocked por prio → `in-progress` + brief | +| `pnpm agent:claim [-- --dry-run]` | Fila ready+unblocked por prio → `in-progress` + brief (Forgejo) | | `pnpm worktree next [--issue N] [--stay]` | Claim determinístico (mesma fila/lock do claim) → worktree + provisionamento | -| `pnpm agent:register -- --id X --title T [--prio P1] [--depends A,B] [--plan docs/plans/x.md] [--model slug]` | Cria Issue (`--plan` ⇒ `blocked` até `agent:ready`; sem plano ⇒ `ready`) | +| `pnpm agent:register -- --id X --title T [--prio P1] [--depends A,B] [--plan docs/plans/x.md] [--model slug]` | Cria Issue no Forgejo (`--plan` ⇒ `blocked` até `agent:ready`; sem plano ⇒ `ready`) | | `pnpm agent:ready -- --issue N[,N…]` | Pós-merge do plano: `blocked`→`ready` (só Issues com link `docs/plans/`) | | `pnpm agent:status` | Overview / fila / mermaid | | `pnpm agent:prioritize -- <issue> <P0..P3>` | Troca `prio:*` | | `pnpm agent:file-miss -- --title ...` | Issue `kind:agent-miss` | | `pnpm agent:pool -- status\|tick --dry-run\|doctor` | Pool Cloud **dormente (OPS65)** — o workflow `agent-pool.yml` foi removido; dispatch falha 404; scripts/skill ficam para histórico | -| `pnpm push [-- -u origin HEAD …]` | Canônico: ensure-deps + gate:push + push | -| `pnpm configure:branch-protection [-- --dry-run]` | Proteção de `main`: required status check `CI (PR) / checks` (rollup do ci-pr; idempotente — cria/atualiza/no-op) | +| `pnpm push [-- -u origin HEAD …]` | Canônico: ensure-deps + gate:push + push para o **GitHub** (origin) | +| `GITHUB_TOKEN=… node scripts/github-pr.mjs --head <b> --title <t> --body-file <f>` | Abre PR no **GitHub** (Ready, base `main`, nunca draft) | +| `GITHUB_TOKEN=… pnpm configure:branch-protection [-- --dry-run]` | Proteção de `main` no **GitHub**: required check `CI (PR) / checks` (idempotente — cria/atualiza/no-op) | | `pnpm db:seed:minimal` | DB mínimo sintético | -Labels: `ready|in-progress|blocked|done|in-prod`, `prio:*`, `kind:*`, `needs:*`. +Labels (Forgejo): `ready|in-progress|blocked|done|in-prod`, `prio:*`, `kind:*`, `needs:*`. **plan-issue (OPS17 + OPS18):** gate pós-overview fecha o lote antes de qualquer Issue/PR; register com `--plan` nasce `blocked` (não entra na fila do claim/pool); após o PR de planos mergear em `main` (`Related #N`), promote dual idempotente: (A) `pnpm agent:ready` na sessão; (B) Action `plan-issue-ready-on-main-merge.yml` lê `Related #N` e promove Issues ainda “aguardando plano” (`blocked` + link `docs/plans/`). Chores sem plano continuam nascendo `ready`. ## Contrato de PR 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: `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. +2. Migrations NÃO são serializadas entre PRs: o CI (migrate + int, incl. `campaignMigrationReconciliation`) valida a cadeia em todo PR; rebase antes de `migrate:create` continua obrigatório. +3. Ready + auto-merge: `pnpm push -u origin HEAD` (GitHub) → PR via `node scripts/github-pr.mjs` (Ready, base `main`, `Closes #N`) → o safety net `agent-pr-ready-automerge.yml` (`scripts/github-pr-automerge.mjs`) arma o **auto-merge nativo do GitHub por rebase** — o servidor espera o required check `CI (PR) / checks` e mergea; nada a armar por PR, não há `gh` (OPS50) e não há poll (OPS71). **Merge é por rebase** (nunca merge commit): preserva a linha histórica limpa do `main` e é o modo do auto-merge. +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). ## Registries compartilhados (serialização por arquivo, não por PR) @@ -67,39 +68,39 @@ Arquivos de "lista" que N agentes escrevem em paralelo (changelog, plans, migra - **`serializes` no plano de intenção** nomeia o registro exato que a Issue toca (ex. `serializes: 'docs/plans/'`), para o executor agendar com clareza — é dica de ordem, não lock (rebase continua obrigatório). - O rebase (Contrato de PR item 3) é o mecanismo real de conciliação: conflitos de append resolvem com `git checkout --ours/--theirs` por lado. -## CI por alvo +## CI por alvo (GitHub Actions, OPS71) -| Workflow | Trigger | Banco | Passos | -| ------------------------------------ | ----------------------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `ci-pr.yml` | PR → `main` | 2× service Postgres 17 | Job único `checks` sequencial (OPS62 X1): guards → lint→format→typecheck→knip→cycles→unit→int→build→e2e; skips via `ci-scope.mjs` (step `scope`); **fail-fast estrutural** — step vermelho interrompe o job, o run falha e o slot é liberado; e2e 1 processo com `PLAYWRIGHT_WORKERS=4`; 2 services por nome na rede do job (`postgres-int`/`postgres-build`, sem publish host) | -| `ci.yml` | schedule `*/30` / dispatch `main` | 2× service Postgres 17 | Janela fixa (OPS65): gate `gate` (host, main-only, sem pnpm) classifica mudança de produção desde a **revision do container rodando** no homeserver (`.dockerignore` = fonte da verdade; fail-open; incapaz de classificar → run **vermelho**); sem mudança → suite + deploy skipped, run verde; com mudança → job único `checks` sequencial (mesma mecânica X1) + job `deploy` (runs-on `host`) publica no homeserver via `scripts/deploy-homeserver.sh` (OPS53, guard "already deployed") | -| `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 | +| Workflow | Trigger | Banco | Passos | +| ------------------------------------ | ----------------------------------- | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `ci-pr.yml` | PR → `main` (same-repo) | 2× service Postgres 17 | Job único `checks` sequencial (OPS62 X1): guards → lint→format→typecheck→knip→cycles→unit→int→build→e2e; skips via `ci-scope.mjs` (step `scope`); **fail-fast estrutural** — step vermelho interrompe o job, o run falha; `concurrency` nativo cancela o run em push novo; e2e 1 processo com `PLAYWRIGHT_WORKERS=4`; 2 services por nome na rede do job (`postgres-int`/`postgres-build`, sem publish host); fork-PR excluída no `if:` do job (repo público — não queima minutes) | +| `deploy.yml` | **`workflow_dispatch` manual** | 2× service Postgres 17 | **Dois jobs:** `verify` (hosted, suíte **full** sem skips — lint→format→typecheck→knip→cycles→unit→int→build→e2e full) → `deploy` (`needs: [verify]`, `runs-on: [self-hosted, homeserver]`) executa `scripts/deploy-homeserver.sh <sha>` **localmente** no homeserver (sem SSH; idempotente; HEAD guard; flock; migrator→migrate→runner→rollout→smoke) | +| `issue-done-on-main-merge.yml` | PR merged → `main` (same-repo) | — | `Closes`/`Fixes` → `done` + `in-prod` **no Forgejo** (PAT `FORGEJO_API_TOKEN`; body do PR via `PR_BODY` do evento GitHub) | +| `plan-issue-ready-on-main-merge.yml` | PR merged → `main` (same-repo) | — | `Related #N` aguardando plano → `ready` **no Forgejo** (OPS18; soft-skip; mesmo PAT) | +| `agent-pr-ready-automerge.yml` | PR same-repo → `main` (open/sync/…) | — | Safety net via `github-pr-automerge.mjs` (plain Node, REST+GraphQL): draft `cursor/*` → Ready (PATCH); arm `enablePullRequestAutoMerge` (rebase) — o **servidor** espera o required check `CI (PR) / checks` (o OPS64 "rollup pode mentir" é estrutural aqui: job único posta um check-run honesto); 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). +`agent-pool.yml` foi **removido no OPS65** (pool dormente; o tick `*/10` custava 144 `pnpm install`/dia na workstation). O verificador de main (`ci.yml`) foi **eliminado no OPS71** (gate 2026-08-19): só o `verify` do dispatch manual roda a suíte full. -Action runtimes: `actions/checkout@v5`, `actions/setup-node@v5`, `pnpm/action-setup@v6` e `styfle/cancel-workflow-action@0.13.1` usam Node 24 nativo — sem `FORCE_JAVASCRIPT_ACTIONS_TO_NODE24`. +Action runtimes: `actions/checkout@v5`, `actions/setup-node@v5`, `pnpm/action-setup@v6` e `actions/cache@v4`. Fast gate: `pnpm gate:fast`. Push: `pnpm push`. -### Secrets (humano, uma vez) +### Secrets (humano, uma vez — repo GitHub) -| 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 | +| Secret | Uso | +| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `FORGEJO_API_TOKEN` | Scripts Forgejo (`forgejo-api.mjs`) e flips pós-merge (`issue-done`, `plan-issue-ready`) — o `GITHUB_TOKEN` nativo do GitHub não toca Issues do Forgejo (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. +Local: `GITHUB_TOKEN` (PAT com escopo `repo`) para `node scripts/github-pr.mjs`, `pnpm configure:branch-protection` e qualquer script GitHub — o push SSH usa a chave `~/.ssh/id_ed25519` registrada no GitHub. 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 GitHub. `POOL_GITHUB_TOKEN` é **legado** (era da transição GitHub pré-OPS50). -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). **OPS64:** o CLI nunca confia no rollup sozinho — varre os statuses individuais e falha em qualquer `failure`/`error` (pin em `forgejoApi.unit.spec.ts`, cenário run 607: rollup verde com shard de e2e vermelho → throw). Com o desenho de job único do OPS62 (sem matrix, sem shards) o status do job `checks` já é o veredito honesto da cascata — o bug de agregação do parent de matrix deixou de existir estruturalmente. Reaplicar/consertar drift: `pnpm configure:branch-protection` (idempotente). +Branch protection de `main` no **GitHub** (aplicada no cutover do OPS71, via `pnpm configure:branch-protection`): required check `CI (PR) / checks` (o check-run do `ci-pr.yml` — job único, veredito honesto da cascata inteira), `strict=false`, 0 reviews, `enforce_admins: true` (nem admin mergea com CI vermelho — mesmo invariante do rule-based Forgejo). O auto-merge nativo espera esse mesmo check antes de mergear; a regra no servidor é o gate real de qualquer caminho de merge, inclusive API manual. Reaplicar/consertar drift: `pnpm configure:branch-protection` (idempotente). -Deploy (OPS53 + OPS65): o `ci.yml` do main roda em **janela fixa de 30 min** (`schedule */30` + `workflow_dispatch` — não dispara mais a cada push). O job `gate` (host, sem pnpm) lê a **revision do container rodando** no homeserver (label `org.opencontainers.image.revision` — o compose pode mentir após rollback falho) e classifica "mudança de produção" pelos padrões do `.dockerignore` (fonte da verdade do artefato; `docs/`, `.agents/`, `.env*` viram skip; `scripts/`, `tests/`, `.forgejo/`, `AGENTS.md` contam como produção — conservador). Deployed == HEAD → suite e deploy skipped (run verde); estado desconhecido (sem revision) → suite roda fail-open; gate incapaz de classificar → suite roda e o run fica **vermelho** (nunca blackout). Com mudança → suite full verde → job `deploy` (runs-on `host`) streama `scripts/deploy-homeserver.sh` para o homeserver via SSH — build no homeserver (secrets de `~/stack/teqo-1313.env`), registry `localhost:5000`, migrate pelo serviço de maintenance `teqo-1313-migrate` antes do rollout, smoke pós-deploy; o script é idempotente (revision do container já no SHA → skip verde "already deployed"). Nenhum secret novo no Forgejo. Runbook (rollback, falhas conhecidas): `docs/ops/teqo-1313-deploy.md`. O deploy Vercel (`vercel-promote.yml`, scripts, `vercel.json`) foi removido no OPS50. +Deploy (OPS53 + OPS71): **manual** via `workflow_dispatch` no `deploy.yml` — o job `verify` (hosted, suíte full incl. e2e full) roda **antes** do job `deploy` (`needs: [verify]`), que executa `scripts/deploy-homeserver.sh <sha>` no runner self-hosted do GitHub **no homeserver** (conecta outbound ao GitHub — funciona atrás do Cloudflare tunnel; o hosted nunca toca o homeserver; o self-hosted não conta minutos hosted). O script: HEAD guard (`TEQO_REPO_URL` — default `https://github.com/fsolla/teqo.git`, público) → flock → guard "already deployed" (revision do container) → build do migrator (BuildKit, secrets de `~/stack/teqo-1313.env`) → push/tag em `localhost:5000` → swap dos tags no compose (backup) → **migrations** (`teqo-1313-migrate` — antes do build do runner, OPS66) → build do runner (contra o banco JÁ migrado) → rollout → healthcheck → smoke. Falha = job vermelho; nada é publicado pela metade. Runbook (rollback, falhas conhecidas): `docs/ops/teqo-1313-deploy.md`. O deploy Vercel foi removido no OPS50; o verificador automático de main foi eliminado no OPS71 — se um dia o merge em main quiser rede de regressão, o `ci.yml` volta com 1 linha de trigger (sem deploy). ## Cursor Cloud -`.cursor/environment.json` instala deps + Postgres nativo + `db:seed:minimal`. Sem secrets de prod. Preferir `pnpm push`; escape `git push --no-verify` só no cutover documentado acima. +`.cursor/environment.json` instala deps + Postgres nativo + `db:seed:minimal`. Sem secrets de prod. Preferir `pnpm push`; escape `git push --no-verify` só no cutover documentado acima. PR via `ManagePullRequest` (draft: false) — o merge continua pelo safety net do GitHub. ## Agent pool diff --git a/docs/CHANGELOG-AGENTS.md b/docs/CHANGELOG-AGENTS.md index 1cebc11b..2d0514e0 100644 --- a/docs/CHANGELOG-AGENTS.md +++ b/docs/CHANGELOG-AGENTS.md @@ -38,6 +38,8 @@ Conteúdo movido do `AGENTS.md` em 2026-07-30 (fatiamento do paradigma de agente **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. +**Recently resolved (2026-08-19):** **OPS71** — CI/PR/deploy do Forgejo Actions de volta para o **GitHub Actions**, com o **tracker de Issues permanecendo no Forgejo** (labels, claims, `pnpm issue`/`agent:*` e flips pós-merge continuam via API do Forgejo; o GitHub é só o host do Actions). O PR CI (`ci-pr.yml`, job único `checks` — OPS62) roda no GitHub com a mesma cascata (guards → lint → format → typecheck → knip → cycles → unit → int → build → e2e selected/afetado via `ci-scope.mjs`), com `concurrency` nativo cancelando o run em push novo e `if:` same-repo (repo público — fork não queima minutes). Seu check-run `CI (PR) / checks` é o required check do `main` e o gate do **auto-merge nativo** (`agent-pr-ready-automerge.yml` → `scripts/github-pr-automerge.mjs`: draft `cursor/*` → Ready via PATCH, arm `enablePullRequestAutoMerge` GraphQL com REBASE — o servidor espera o required check verde; sem poll; o pin OPS64 "rollup pode mentir" é estrutural aqui: job único posta um check-run honesto). **`ci.yml` (verificador de main) eliminado** — publicar é **dispatch manual** (`deploy.yml`): `verify` (hosted, suíte full incl. e2e full) → `deploy` (`needs`, `runs-on: [self-hosted, homeserver]`) executa `scripts/deploy-homeserver.sh <sha>` **localmente** no runner do GitHub instalado no homeserver (sem SSH; outbound-only; o hosted nunca toca o homeserver); o script re-aponta o workspace `~/teqo-deploy` para `TEQO_REPO_URL` (default `https://github.com/fsolla/teqo.git`, público). `pnpm push` passa a empurrar para `origin` = **GitHub** (cutover manual de remote documentado; o repo Forgejo congela em main, tracker vivo por API). Novos helpers plain-Node zero-dep: `scripts/lib/github-api.mjs` (REST+GraphQL, retry OPS67), `scripts/lib/github-pr-flow.mjs` (decisão draft/veto/skip, pura), `scripts/lib/github-branch-protection.mjs` (regra desejada + drift, `enforce_admins: true`), `scripts/github-pr.mjs` (criação de PR Ready — nunca draft), `scripts/configure-branch-protection.mjs` reescrito para a REST do GitHub; `forgejo-issue-transition.mjs` aceita `PR_BODY` (body do PR via evento GitHub; flip continua no Forgejo por `FORGEJO_API_TOKEN`). **Cutover em duas fases (gate):** nada do Forgejo foi apagado (`.forgejo/workflows/`, `forgejo-pr-automerge.mjs`, `forgejo-dispatch.mjs`, `ci-classify-production.mjs` preservados como rollback) — a remoção é entrega sucessora pós-validação. Testes: `githubApi` (10), `githubBranchProtection` (10), `githubPrFlow` (9) unit novos. Docs: `AGENTS.md`, `docs/AGENT-OPS.md`, `.agents/rules/agent-pr-workflow.mdc`, `work-issue/execution-pipeline.md`, `agent-work-issue`, `capture-review-debts`, runbook `docs/ops/teqo-1313-deploy.md` (dispatch manual, runner no homeserver, cutover com ordem, rollback). + **Recently resolved (2026-08-18):** **OPS52** — a media saiu do Vercel Blob para o Garage S3 do homeserver (bucket `teqo-media` + key `teqo-key`, já existentes no Garage v2.1.0). O plugin `@payloadcms/storage-vercel-blob` (e o `@vercel/blob` do seed) foi trocado por `@payloadcms/storage-s3` na config, no padrão R2 da doc do Payload (`endpoint` + `forcePathStyle: true`, region `garage`). **Decisão de arquitetura (revisão A→B durante a execução, gate com o humano):** o Garage v2.1.0 **não suporta acesso anônimo na API S3** (sem `--public-read`; source: "when we support anonymous access in the future"; testado: `anonymous`/`anon` → `NoSuchAccessKey`), então o bucket fica **privado** e a app **serve a media por proxy** — sem `disablePayloadAccessControl`, o `staticHandler` do plugin streama o objeto do Garage em `/api/media/file/<filename>` (range + etag/304 nativos) — o **mesmo contrato de URL relativa que as 40 rows pré-existentes já têm** (a recuperação dos arquivos é a Issue #10/OPS52-media). **Fail-closed:** `resolveS3StorageEnv` (`src/utilities/mediaStorage.ts`, unit-testado) — envs `S3_*` parciais → throw no boot com a lista exata de faltantes; nenhuma → storage local (dev/test). Envs novas: `S3_BUCKET`, `S3_ENDPOINT`, `S3_REGION` (default `garage`), `S3_ACCESS_KEY_ID`, `S3_SECRET_ACCESS_KEY` (`.env.example`, `.env.test`, worktree.mjs com cópia all-or-nothing). Seed de posts: pre-delete do Blob removido (o S3 sobrescreve o key determinístico nativamente — idempotência intacta). Prova de contrato real: PUT/GET/DELETE via SDK contra o Garage (tailnet `http://100.119.220.31:3900`), depois media criada pelo Payload local com S3 ativo → `media.url` relativa + `GET /api/media/file/...` → 200 image/png; bucket devolvido a 0 objects e `.env.local` do worktree limpo (sem credenciais de prod). Sem migration (config-only; importMap regenerado sem `VercelBlobClientUploadHandler`). Runbook de cutover registrado no impl plan: setar as 5 `S3_*` no `~/stack/teqo-1313.env` (endpoint tailnet) antes do próximo deploy (OPS53). Repo: `docs/plans/ops52-blob-vercel-para-garage-impl.md`; infra-solla `STATE.md` atualizado à parte. **Recently resolved (2026-08-18):** **OPS52-media** — os objetos de media de produção (as ~40 capas dos posts, que existiam como rows com URL relativa `/api/media/file/<filename>` mas sem arquivo em lugar nenhum) são recuperáveis do WordPress de origem com `pnpm media:recover` (`scripts/recover-media.mjs`, novo): lê as rows de `media` + `post.coverImage` (mapeamento exato row→slug; fallback pelo filename determinístico `<slug>.<ext>`), resolve a capa com a MESMA lógica do seed (featured media do REST `_embed`, senão 1ª imagem inline do corpo — só 7/43 posts têm featured), baixa e faz `PutObject` no bucket das envs `S3_*` com key = `filename` da row, **sem nunca escrever no DB** (rows e URLs intocadas; o staticHandler do Payload passa a servir). Extraído para `scripts/lib/wpArticles.mjs` o fetch ao vivo do WordPress (seed-posts agora importa de lá — sem twin; unit-testado). Fail-closed: exige as 4 `S3_*` completas (`resolveS3StorageEnv` reusado; recuperação nunca vai pro storage local), `ALLOW_REMOTE_DB=true` explícito para DB remoto + echo do alvo (DB/bucket/endpoint), e timeouts curtos no SDK (`@smithy/node-http-handler`, 5s/15s) — endpoint inalcançável falha em segundos em vez de pendurar (a rota pública de media de prod pendurava >25s; evidência de possível falta de rota container→Garage, diagnosticada no runbook do impl plan). Modos: reconcile (padrão, upload idempotente por overwrite), `--dry-run` (plano + `headObject`), `--verify` (HEAD da URL pública por filename — o aceite da Issue, sem credencial). Runbook de execução no homeserver: `docs/plans/ops52-media-recuperar-arquivos-impl.md`. diff --git a/docs/changelog/2026-08-19-ops71.md b/docs/changelog/2026-08-19-ops71.md new file mode 100644 index 00000000..ebe67b9e --- /dev/null +++ b/docs/changelog/2026-08-19-ops71.md @@ -0,0 +1 @@ +**Recently resolved (2026-08-19):** **OPS71** — CI/PR/deploy do Forgejo Actions de volta para o **GitHub Actions**, com o **tracker de Issues permanecendo no Forgejo** (labels, claims, `pnpm issue`/`agent:*` e flips pós-merge continuam via API do Forgejo; o GitHub é só o host do Actions). O PR CI (`ci-pr.yml`, job único `checks` — OPS62) roda no GitHub com a mesma cascata (guards → lint → format → typecheck → knip → cycles → unit → int → build → e2e selected/afetado via `ci-scope.mjs`), com `concurrency` nativo cancelando o run em push novo e `if:` same-repo (repo público — fork não queima minutes). Seu check-run `CI (PR) / checks` é o required check do `main` e o gate do **auto-merge nativo** (`agent-pr-ready-automerge.yml` → `scripts/github-pr-automerge.mjs`: draft `cursor/*` → Ready via PATCH, arm `enablePullRequestAutoMerge` GraphQL com REBASE — o servidor espera o required check verde; sem poll; o pin OPS64 "rollup pode mentir" é estrutural aqui: job único posta um check-run honesto). **`ci.yml` (verificador de main) eliminado** — publicar é **dispatch manual** (`deploy.yml`): `verify` (hosted, suíte full incl. e2e full) → `deploy` (`needs`, `runs-on: [self-hosted, homeserver]`) executa `scripts/deploy-homeserver.sh <sha>` **localmente** no runner do GitHub instalado no homeserver (sem SSH; outbound-only; o hosted nunca toca o homeserver); o script re-aponta o workspace `~/teqo-deploy` para `TEQO_REPO_URL` (default `https://github.com/fsolla/teqo.git`, público). `pnpm push` passa a empurrar para `origin` = **GitHub** (cutover manual de remote documentado; o repo Forgejo congela em main, tracker vivo por API). Novos helpers plain-Node zero-dep: `scripts/lib/github-api.mjs` (REST+GraphQL, retry OPS67), `scripts/lib/github-pr-flow.mjs` (decisão draft/veto/skip, pura), `scripts/lib/github-branch-protection.mjs` (regra desejada + drift, `enforce_admins: true`), `scripts/github-pr.mjs` (criação de PR Ready — nunca draft), `scripts/configure-branch-protection.mjs` reescrito para a REST do GitHub; `forgejo-issue-transition.mjs` aceita `PR_BODY` (body do PR via evento GitHub; flip continua no Forgejo por `FORGEJO_API_TOKEN`). **Cutover em duas fases (gate):** nada do Forgejo foi apagado (`.forgejo/workflows/`, `forgejo-pr-automerge.mjs`, `forgejo-dispatch.mjs`, `ci-classify-production.mjs` preservados como rollback) — a remoção é entrega sucessora pós-validação. Testes: `githubApi` (10), `githubBranchProtection` (10), `githubPrFlow` (9) unit novos. Docs: `AGENTS.md`, `docs/AGENT-OPS.md`, `.agents/rules/agent-pr-workflow.mdc`, `work-issue/execution-pipeline.md`, `agent-work-issue`, `capture-review-debts`, runbook `docs/ops/teqo-1313-deploy.md` (dispatch manual, runner no homeserver, cutover com ordem, rollback). diff --git a/docs/ops/teqo-1313-deploy.md b/docs/ops/teqo-1313-deploy.md index 8d4e4191..6595fd27 100644 --- a/docs/ops/teqo-1313-deploy.md +++ b/docs/ops/teqo-1313-deploy.md @@ -1,40 +1,30 @@ -# Runbook: deploy do site 1313 no homeserver (OPS53, janela OPS65) +# Runbook: deploy do site 1313 no homeserver (OPS53 + OPS71 — dispatch manual) -O deploy de produção é uma etapa do CI (`ci.yml` no Forgejo): mergir em `main` -com a suite verde publica o site em `jorgesolla1313.com.br` — sem passo manual. -Merge **com mudança de produção** = site atualizado em ~30 min (janela) + tempo -da suite/deploy (~15–25 min cada; tipicamente < 1 h no total). +O deploy de produção é uma **action manual** (`workflow_dispatch` no GitHub +Actions, `.github/workflows/deploy.yml`): mergir em `main` **não** publica +nada. O operador dispara o deploy quando decide publicar; antes de tocar o +homeserver, o job `verify` (hosted) roda a suíte **full** (incl. e2e full). ## Gatilho e fluxo -1. `git push` para `main` (via PR merge) — o `ci.yml` **não dispara mais a cada - push**: roda por **janela fixa de 30 min** (`schedule */30`) ou via - `workflow_dispatch` (deploy manual, imediato, sempre full suite). -2. Job `gate` (barato, host, sem pnpm): lê a **revision do container rodando** - no homeserver (`docker inspect` → label `org.opencontainers.image.revision` - do `teqo-1313` — a fonte de verdade; o compose pode mentir após rollback - falho, pois é trocado antes do rollout) e classifica "mudança de produção" - com o `.dockerignore` como fonte da verdade (o que não entra na imagem não - justifica build novo; `docs/`, `.agents/`, `.env*` viram skip; - `scripts/`, `tests/`, `.forgejo/`, `AGENTS.md` contam como produção — - conservador, qualquer dúvida roda a suite). - - Deployed == HEAD → suite e deploy **skipped**; run verde. - - Sem revision conhecida (label ausente, container sem label) → fail-open: - suite + deploy rodam na janela (run verde; comportamento conservador). - - Gate incapaz de classificar (erro de git/`.dockerignore`) → suite roda e - o run fica **vermelho** — nunca blackout silencioso. -3. Com mudança de produção: suite completa verde (static/int/build/e2e/checks). -4. Job `deploy` (runs-on `host`, na **workstation**) roda - `ssh homeserver "bash -s -- <sha>" < scripts/deploy-homeserver.sh`. - O script é **idempotente**: se o container rodando já tem a revision do SHA - (ex.: dispatch duplicado), sai verde "already deployed" sem rebuild. -5. O script, no **homeserver**: guarda de HEAD (`main` remoto == SHA do job, - senão skip) → `flock` (serializa) → guard "already deployed" (revision do - container) → **build do migrator** (o estágio migrator não roda `next -build` — builda mesmo contra o schema antigo; BuildKit, secrets do - `~/stack/teqo-1313.env`) → push/tag do migrator em `localhost:5000` → - swap dos tags de imagem no `~/stack/docker-compose.yml` (backup antes) → - **migrations** +1. GitHub → Actions → **Deploy (manual)** → Run workflow (ref: `main`). +2. Job `verify` (hosted `ubuntu-latest`, ~50 min): suíte full sem skips — + check-test-locations → lint → format → typecheck → knip → cycles → unit → + int (migrate+seed nos services) → build → e2e full. +3. Se `verify` verde, o job `deploy` (`needs: [verify]`, + `runs-on: [self-hosted, homeserver]`) roda no **runner do GitHub instalado + no homeserver** e executa `scripts/deploy-homeserver.sh <sha>` **localmente** + (sem SSH; o runner conecta outbound ao GitHub — funciona atrás do + Cloudflare tunnel; o hosted nunca toca o homeserver; o self-hosted não + conta minutos hosted). +4. O script, no **homeserver**: guarda de HEAD (`git ls-remote` de + `TEQO_REPO_URL` — default `https://github.com/fsolla/teqo.git`, público — + == SHA do job, senão "stale run" skip) → `flock` (serializa) → guard + "already deployed" (revision do container rodando) → **build do migrator** + (o estágio migrator não roda `next build` — builda mesmo contra o schema + antigo; BuildKit, secrets do `~/stack/teqo-1313.env`) → push/tag do + migrator em `localhost:5000` → swap dos tags de imagem no + `~/stack/docker-compose.yml` (backup antes) → **migrations** (`docker compose --profile maintenance run --rm teqo-1313-migrate </dev/null`, já com a imagem do SHA novo) → **build do runner** (contra o banco JÁ migrado — o `next build` da geração estática lê o schema novo, OPS66; @@ -43,27 +33,59 @@ build` — builda mesmo contra o schema antigo; BuildKit, secrets do → push/tag do runner → `docker compose up -d teqo-1313` → healthcheck → smoke (`/`, `/campanha/login`, `/admin`, barreira 307, WebAuthn login-options, `api/revalidate` com o secret real). -6. Falha = job vermelho no commit; nada é publicado pela metade. +5. Falha = job vermelho; nada é publicado pela metade (rollback automático + após o swap). -**Primeira janela (verificação ao vivo):** após o merge do OPS65, acompanhe um -run agendado — confira no log do job `gate` o `deployed_sha` lido do container e -o veredito da classificação, e que um dispatch manual roda suite + deploy -(idempotência: segundo dispatch no mesmo SHA sai "already deployed"). Isso -prova ao vivo a paridade Forgejo de `needs.<gate>.outputs` com gate falho -(suite roda; deploy pula; run vermelho). +**Primeiro deploy (verificação ao vivo):** depois do cutover OPS71, dispare o +deploy manual e confira no log do job `deploy` o `set-url` do workspace +(origem Forgejo → GitHub), o `deployed_sha` lido do container e o guard +"already deployed" num segundo dispatch do mesmo SHA. ## Onde roda cada coisa -| Máquina | Papel | -| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **workstation** (16c/61GB) | runner Forgejo (`workstation-runner`); job `deploy` roda no host (chave SSH `~/.ssh/id_ed25519` → `ssh homeserver`) | -| **homeserver** (8c/16GB) | todo o stack (`~/stack/docker-compose.yml`): postgres `teqo_1313`, forgejo, registry `localhost:5000`, cloudflared, `teqo-1313` na 127.0.0.1:1313; workspace `~/teqo-deploy` (clone do Forgejo local) | +| Máquina | Papel | +| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **GitHub hosted** (ubuntu) | CI de PR (`ci-pr.yml`, job `checks`) e job `verify` do `deploy.yml` (suíte full). Nunca toca o homeserver. | +| **homeserver** (8c/16GB) | todo o stack (`~/stack/docker-compose.yml`): postgres `teqo_1313`, forgejo, registry `localhost:5000`, cloudflared, `teqo-1313` na 127.0.0.1:1313; **runner self-hosted do GitHub** (labels `self-hosted`, `homeserver`; instalado no cutover OPS71 — registrar em infra-solla); workspace `~/teqo-deploy` (clone de `github.com/fsolla/teqo`, público) | +| **workstation** | dev/agentes apenas — o runner do Forgejo foi **desligado** no cutover (o schedule do `ci.yml` antigo não tem mais razão; religar é reversível) | -Segredos **não** ficam no Forgejo: o script sourceia `~/stack/teqo-1313.env` e -`~/stack/.env` (chmod 600) no próprio homeserver. Nenhum secret novo em -Settings → Actions. +Segredos **não** ficam no GitHub: o script sourceia `~/stack/teqo-1313.env` e +`~/stack/.env` (chmod 600) no próprio homeserver. O repo GitHub é público — o +clone do workspace não precisa de credencial. No GitHub ficam apenas os +secrets de integração: `FORGEJO_API_TOKEN` (flips pós-merge) e +`CURSOR_API_KEY` (archive helper, dormente). -## Rollback +## Cutover OPS71 (passos manuais, ordem) + +1. Remotes locais (config compartilhada pelos worktrees): + `git remote set-url origin git@github.com:fsolla/teqo.git` e + `git remote add forgejo ssh://git@192.168.15.142:2222/fsolla/teqo.git` + (ou `https://git.solla.dev/fsolla/teqo.git`) — o repo Forgejo congela em + main; o tracker (Issues) segue vivo por API. +2. GitHub repo: secrets `FORGEJO_API_TOKEN` + `CURSOR_API_KEY` + (Settings → Secrets and variables → Actions) e **`Allow auto-merge`** + (Settings → General → Pull Requests; ou `PATCH /repos/...` com + `allow_auto_merge: true`). Repo é público: em Settings → Actions → + General, defina fork PR workflows como não executar (ou exigir aprovação). +3. PAT local: criar token GitHub com escopo `repo` e exportar `GITHUB_TOKEN` + (para `node scripts/github-pr.mjs` e `pnpm configure:branch-protection`). +4. `GITHUB_TOKEN=… pnpm configure:branch-protection` — required check + `CI (PR) / checks`, 0 reviews, `enforce_admins: true`. **Antes do primeiro + push** (senão o PR mergearia sem required check). +5. **Desligar o runner do Forgejo** na workstation (ex.: + `systemctl --user stop forgejo-runner`) — após o primeiro PR GitHub + validado; para o schedule do `ci.yml` antigo. +6. Instalar o runner self-hosted do GitHub no homeserver (labels + `self-hosted` + `homeserver`; usuário com docker + acesso a `~/stack`; + registrar em infra-solla: `STATE.md`). +7. Push do PR do OPS71 → CI verde → auto-merge → flip da Issue no Forgejo → + deploy manual de validação. + +Rollback do cutover (se o GitHub falhar cedo): religar o runner do Forgejo e +abrir PRs no Forgejo (os workflows de `.forgejo/workflows/` seguem no repo +até a Fase 2) — remotes: `git remote set-url origin ssh://git@192.168.15.142:2222/fsolla/teqo.git`. + +## Rollback (do deploy) A imagem anterior continua local e no registry (`localhost:5000/teqo-1313:<sha>` — o registry nunca deleta). O compose anterior fica em @@ -90,39 +112,40 @@ roda após migrator build+push+swap ok; rollout só após runner build ok). Desd o OPS66 o migrate roda **antes** do build do runner (o build precisa do schema novo): um build do runner que falhe depois do migrate deixa o banco à frente do código — migrations são append-only e revisadas antes do deploy (checklist); -a correção se re-mergeia e a próxima janela completa o deploy. +a correção se re-mergeia e o próximo deploy completo publica. ## Falhas conhecidas -| Sintoma | Causa | Tratamento | -| ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Job verde sem deploy ("stale run") | Push mais novo venceu; o deploy antigo saiu da fila | Nada a fazer — o run do SHA novo deploya | -| Job verde sem deploy ("already deployed") | O container rodando já tem a revision do SHA do job (ex.: `workflow_dispatch` duplicado da mesma HEAD) | Nada a fazer — o site já roda esse SHA. Forçar rebuild da MESMA HEAD não é suportado via dispatch: edite o tag da imagem no compose (`image: teqo-1313:<sha>-rebuild`) e `docker compose up -d`, ou espere um commit novo | -| Gate `gate` vermelho (erro de git/`.dockerignore`) | SHA deployado ilegível para o git (ex.: história reescrita) ou `.dockerignore` corrompido no checkout | Fail-open: suite roda; deploy pula (nunca deploy às cegas). Corrigir a causa e esperar a próxima janela (auto-cura). Se `ssh homeserver` estiver fora, o gate lê revision vazia e roda tudo (verde) — checar tailnet se a suite roda sem deploy recorrente | -| Sem revision no container (label ausente no compose) | O compose do homeserver não define `org.opencontainers.image.revision` (deploy pré-OPS53 ou edição manual) | Degradação conservadora: toda janela roda suite + rebuild (verde). Corrigir adicionando o label ao serviço `teqo-1313` no compose e re-deployando | -| Todo job docker quebra com `exec: "node": executable file not found in $PATH` | `runner.envs.PATH` do `~/.forgejo-runner/config.yaml` (workstation) com paths só de host (nvm/bun) — o container perde o node do toolcache (`/opt/acttoolcache`); edição do config exige o toolcache primeiro (ver comentário no próprio config) | Corrigir o PATH no config (toolcache primeiro — ver comentário no próprio arquivo) + `systemctl --user restart forgejo-runner` (incidente 2026-08-17) | -| Deploy para logo após o migrate ("Done." e nada mais, EXIT=0) | `docker compose run` anexa stdin por padrão — o container consome o resto do script que vai no pipe do `bash -s`; o bash chega a EOF e termina sem rodar o rollout | O script já usa `< /dev/null` no `run --rm` do migrate (não remover); sintoma visto 2026-08-17 no primeiro deploy | -| Build falha: `network mode "stack_default" not supported by buildkit` | BuildKit (drivers docker e docker-container) recusa rede bridge custom no `--network` | O script builda com `--network host` + proxy socat `teqo-1313-build-proxy` (na `stack_default`, publicado em 127.0.0.1:5433, criado idempotentemente com `restart: unless-stopped`) + `DATABASE_URL` reescrita para o loopback | -| Build OOM no homeserver | Laptop 8c/16GB com o stack ativo (~12GB livres medidos) | Re-dispatch; se recorrente, item futuro: build na workstation com túnel | -| Build do runner falha: `relation "..." does not exist` no `next build` | Migration nova criou tabela lida em geração estática. Pré-OPS66 a ordem era build→migrate e o deploy morria aqui para sempre (incidente 2026-08-18, S2) | Pós-OPS66 não deve ocorrer: migrate roda antes do build do runner. Se reaparecer, confira no log se o passo migrate rodou; recovery manual: `docker build --target migrator` + `docker run --rm --network stack_default --env-file ~/stack/teqo-1313.env localhost:5000/teqo-1313-migrator:<sha>` e re-dispatch do workflow | -| `checkout@v5` falha no job `host` | Label host do act_runner | Fallback: baixar o script direto do Forgejo (`curl -s https://git.solla.dev/fsolla/teqo/raw/branch/main/scripts/deploy-homeserver.sh`) | -| Migrate falha | Drift/erro de schema | Job vermelho; site segue no container antigo; corrigir e re-mergear | -| Smoke falha pós-up | Regressão de runtime | Rollback automático (restore + `up -d`) + job vermelho; investigar | +| Sintoma | Causa | Tratamento | +| ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Job verde sem deploy ("stale run") | Push mais novo venceu; o dispatch apontava um SHA que não é mais o HEAD do main do GitHub | Nada a fazer — dispatch novo no main atual | +| Job verde sem deploy ("already deployed") | O container rodando já tem a revision do SHA do job (ex.: `workflow_dispatch` duplicado da mesma HEAD) | Nada a fazer — o site já roda esse SHA. Forçar rebuild da MESMA HEAD não é suportado via dispatch: edite o tag da imagem no compose (`image: teqo-1313:<sha>-rebuild`) e `docker compose up -d`, ou espere um commit novo | +| Job `deploy` nunca roda / runner offline | Runner self-hosted do homeserver não instalado ou parado (passo manual do cutover OPS71) | Instalar/religar o runner (labels `self-hosted`, `homeserver`); os PRs e o `verify` não dependem dele — só o deploy | +| Deploy dispara mas o job `verify` falha | Regressão real na suíte full | Corrigir e re-dispatchar — o homeserver nunca é tocado | +| Deploy para logo após o migrate ("Done." e nada mais, EXIT=0) | `docker compose run` anexa stdin por padrão — o container consome o resto do script; o bash chega a EOF e termina sem rodar o rollout | O script já usa `< /dev/null` no `run --rm` do migrate (não remover); sintoma visto 2026-08-17 no primeiro deploy | +| Build falha: `network mode "stack_default" not supported by buildkit` | BuildKit (drivers docker e docker-container) recusa rede bridge custom no `--network` | O script builda com `--network host` + proxy socat `teqo-1313-build-proxy` (na `stack_default`, publicado em 127.0.0.1:5433, criado idempotentemente com `restart: unless-stopped`) + `DATABASE_URL` reescrita para o loopback | +| Build OOM no homeserver | Laptop 8c/16GB com o stack ativo (~12GB livres medidos) | Re-dispatch; se recorrente, item futuro: build na workstation com túnel | +| Build do runner falha: `relation "..." does not exist` no `next build` | Migration nova criou tabela lida em geração estática. Pré-OPS66 a ordem era build→migrate e o deploy morria aqui para sempre (incidente 2026-08-18, S2) | Pós-OPS66 não deve ocorrer: migrate roda antes do build do runner. Se reaparecer, confira no log se o passo migrate rodou; recovery manual: `docker build --target migrator` + `docker run --rm --network stack_default --env-file ~/stack/teqo-1313.env localhost:5000/teqo-1313-migrator:<sha>` e re-dispatch do workflow | +| Workspace clone sem o SHA novo | O workspace antigo apontava para o Forgejo local (pré-OPS71) e o fetch não achou o SHA | O script agora re-aponta `origin` para `TEQO_REPO_URL` (idempotente) antes do fetch — se ainda falhar, `git -C ~/teqo-deploy remote -v` e corrigir manualmente | +| Migrate falha | Drift/erro de schema | Job vermelho; site segue no container antigo; corrigir e re-mergear | +| Smoke falha pós-up | Regressão de runtime | Rollback automático (restore + `up -d`) + job vermelho; investigar | ## Segurança (decisão deliberada) -- O job `deploy` usa `runs-on: host` — executa como `fsolla` na workstation. - Está **apenas** no `ci.yml` (janela `*/30` em `main` + dispatch), nunca no - `ci-pr.yml`. O job `gate` tem o mesmo perfil e é restrito a - `github.ref == 'refs/heads/main'` (dispatch em branch não roda código do - branch no host — a suite roda fail-open em containers com secrets de teste). - `main` só anda por PR mergeado com suite verde. Fork-PRs não disparam - workflows no Forgejo (default off — verificado). +- O job `deploy` usa `runs-on: [self-hosted, homeserver]` — executa como o + usuário do runner no homeserver. Está **apenas** no `deploy.yml` + (dispatch manual), nunca no `ci-pr.yml`; o hosted (`verify`) não tem acesso + ao homeserver e o self-hosted não recebe secrets de produção (as envs vivem + no próprio homeserver). `main` só anda por PR mergeado com CI verde; o + deploy só roda com `verify` full verde. Fork-PRs não rodam CI (same-repo + gate + setting do repo). - Segredos nunca ecoados: sem `set -x`, senhas via `--password-stdin` / build-secrets; envs só no homeserver. ## Referências -- `scripts/deploy-homeserver.sh` — o script remoto (fonte da verdade do fluxo) -- `docs/plans/ops53-ci-deploy-homeserver*.md` — intenção e decisões +- `scripts/deploy-homeserver.sh` — o script (fonte da verdade do fluxo) +- `.github/workflows/deploy.yml` — verify → deploy +- `docs/plans/ops53-ci-deploy-homeserver*.md` — intenção e decisões (era Forgejo) +- `docs/plans/ops71-ci-github-actions-tracker-forgejo*.md` — o cutover - infra-solla: `STATE.md`, `plano-infra-final.md` §"Arquitetura de deploy" diff --git a/docs/plans/ops71-ci-github-actions-tracker-forgejo-impl.md b/docs/plans/ops71-ci-github-actions-tracker-forgejo-impl.md new file mode 100644 index 00000000..82d5a013 --- /dev/null +++ b/docs/plans/ops71-ci-github-actions-tracker-forgejo-impl.md @@ -0,0 +1,130 @@ +# Impl: CI/PR do Forgejo Actions de volta para o GitHub Actions — tracker de Issues permanece no Forgejo + +Status: aprovado +Atualizado em: 2026-08-19 +Issue: #97 +Intenção: docs/plans/ops71-ci-github-actions-tracker-forgejo.md +Appetite restante: herdado (~2–3 dias eng; este impl é o item inteiro — OPS72 roda depois com `depends`) + +## Leitura da intenção + +- **Outcome:** código/PR/CI no GitHub Actions (mesma cascata de verificações, + job único `checks`), tracker de Issues no Forgejo por API, deploy **manual** + (`workflow_dispatch`) com dois jobs (`verify` hosted full → `deploy` + self-hosted no homeserver), rollup `CI (PR) / checks` como required check do + GitHub, workstation livre da suíte. +- **O que NÃO negociar:** tracker (Issues/labels/claims) permanece no Forgejo; + estrutura de job único (OPS62) preservada — nada de matrix; deploy NÃO volta + a ser automático; sem migrar Issues; sem segundo deploy (nada de Vercel); + nunca merge com CI vermelho; `pnpm push` continua sendo o caminho canônico. +- **O que reavaliar:** a intenção sugere "auto-merge nativo do GitHub ou + safety net equivalente" e "`gh workflow run` (ou API GitHub)". Reavaliado: + `gh` **não existe** em nenhuma máquina (OPS50) e a filosofia do repo é + plain-Node stdlib — os helpers novos são scripts Node zero-dep sobre a REST + do GitHub, no mesmo molde de `forgejo-api.mjs`. O auto-merge é o **nativo do + GitHub** (GraphQL `enablePullRequestAutoMerge`, rebase) — o servidor espera o + required check; o OPS64 pin (varrer statuses individuais) era defesa contra o + rollup mentiroso do runner Forgejo, que **não existe** no GitHub (o check-run + `CI (PR) / checks` de um job único é o veredito honesto, e o auto-merge nativo + só mergeia com required checks verdes — garantia do servidor). + +## Abordagem recomendada + +```mermaid +flowchart LR + W[worktree local] -->|pnpm push -u origin HEAD| GH[github.com/fsolla/teqo] + GH -->|PR Ready base main Closes #N| CI["ci-pr.yml — job único checks (mesma cascata OPS62)"] + CI -->|required check CI (PR) / checks| AM["agent-pr-ready-automerge.yml — auto-merge nativo (GraphQL, rebase)"] + AM -->|merge| MAIN[main no GitHub] + MAIN -->|PR closed merged| FLIP["issue-done / plan-issue-ready — flip no Forgejo via FORGEJO_API_TOKEN"] + MAIN -->|dispatch manual| V[deploy.yml verify hosted full suite] + V -->|needs| D["deploy runs-on self-hosted homeserver — deploy-homeserver.sh local"] + D --> P[(teqo-1313 produção)] +``` + +**Opções consideradas:** + +- **A — origin vira GitHub; Forgejo como remote secundário congelado; TEQO_REPO_URL → GitHub (repo público, sem auth).** `origin/main` é o base dos gates locais (ci-scope/gate-ci) — precisa apontar para o repo que recebe os merges, senão o diff local compara contra um main defasado. O repo GitHub é público (verificado: `private: false`) → o homeserver clona sem credencial. +- **B — auto-merge via GraphQL nativo.** GitHub espera o required check no servidor; nenhum poll; sem semáforo portado. Draft `cursor/*` → Ready via PATCH; draft não-`cursor/*` = veto (OPS57, preservado). +- **C — deploy.yml com `verify` (hosted, suíte full sem skips) → `deploy` (needs, self-hosted homeserver) executando `deploy-homeserver.sh <sha>` localmente (sem SSH).** +- **D — `forgejo-issue-transition.mjs` / `agent-promote-related-on-merge.mjs` ganham `PR_BODY` env** (mecanismo que `agent-promote-related` já usa): o body do PR vem do evento GitHub; o script flipa no Forgejo por API sem ler o PR do Forgejo (PR lá não existe mais). +- **E — `configure-branch-protection.mjs` reescrito para a REST do GitHub** com lib pura `github-branch-protection.mjs` (regra desejada + drift), no mesmo molde de `branch-protection.mjs`; `enforce_admins: true` preserva o invariante "nunca merge com CI vermelho" inclusive para admin (o rule-based do Forgejo valia para todos). + +**Recomendação:** A+B+C+D+E — porque cada peça reusa o molde existente (plain Node stdlib, libs puras unit-testadas, drift idempotente) e o aceite da intenção exige exatamente esse desenho; nada disso exige binário novo (`gh`) nem semáforo reimplementado. + +**Rejeitadas:** + +- **Instalar `gh` e usar `gh pr create/merge/run`** — binário novo em todas as máquinas + workflows, contra a convenção zero-dep do repo; a REST cobre tudo. +- **Poll-and-merge portado (`waitForChecks` do Forgejo) como mecanismo único** — reimplementa o semáforo que a intenção manda cortar; o OPS64 pin era contra o bug do rollup do Forgejo, inexistente no GitHub com job único + auto-merge nativo. +- **Mirror ativo do Forgejo (`pnpm push` para dois remotes / sync pós-merge)** — nada lê o git do Forgejo em runtime (deploy usa TEQO_REPO_URL=GitHub; flips são API); o repo Forgejo congela em main no ponto do cutover (tracker intacto por API, anti-goal "nunca fecha o tracker" preservado). +- **Deletar os arquivos do Forgejo nesta entrega** — decisão do gate (2026-08-19): o sistema GitHub Actions nasce PRIMEIRO e é validado ao vivo (PR real com CI verde → auto-merge → flips → deploy manual); a remoção de `.forgejo/workflows/` + scripts mortos é **entrega sucessora**, só depois de tudo funcionando. O repo Forgejo congelado no main pré-cutover mantém os workflows como rollback (reversível: religar runner + PRs lá); apagar na primeira entrega queimaria a via de volta. +- **Manter `ci-classify-production.mjs` como check informativo no dispatch** — o hosted não alcança o homeserver (sem SSH) e o `verify` roda a suíte full sem skips; a classificação não muda nada → removido só na entrega de remoção. +- **`TEQO_REPO_URL` → Forgejo local com mirror** — dependência extra de sync; o repo GitHub é público, clone direto sem auth. +- **Fork-PR no CI** — repo público: fork PR rodaria a suíte full em minutes hosted de graça; `if:` same-repo no job `checks` (mesma guarda de RCE dos outros workflows). + +## Cutover em duas fases (gate 2026-08-19) + +O GitHub é **só** o host do Actions; o Forgejo permanece o **tracker principal** (Issues, labels, claims, flips — tudo via API, intacto). A remoção dos arquivos do Forgejo só acontece após validação ao vivo do fluxo GitHub: + +1. **Fase 1 (esta entrega — OPS71):** cria todo o sistema GitHub Actions (workflows, scripts, libs, docs). **Nada do Forgejo é apagado** — `.forgejo/workflows/`, `forgejo-pr-automerge.mjs`, `forgejo-dispatch.mjs`, `ci-classify-production.mjs` + specs permanecem no repo (dormentes: o repo Forgejo não recebe mais push). +2. **Cutover manual (humano, nesta ordem — (a)–(c) ANTES do push do OPS71, senão o PR mergearia sem required check):** (a) remotes locais (`origin` → GitHub, `forgejo` secundário); (b) PAT `GITHUB_TOKEN` local + secrets no GitHub (`FORGEJO_API_TOKEN`, `CURSOR_API_KEY`) + `allow_auto_merge: true`; (c) `pnpm configure:branch-protection` (GitHub); (d) **desligar o runner do Forgejo** (reversível — é o que para o schedule do `ci.yml` antigo, que não tem mais sentido e disputaria a workstation; pode ser logo após o primeiro PR GitHub validado); (e) runner self-hosted no homeserver (deploy; não bloqueia PRs — pode ficar para depois); (f) push do OPS71 → PR no GitHub → CI verde → auto-merge → flip da #97 (valida os flips no merge do próprio OPS71) → deploy manual dispatch quando o runner do homeserver estiver pronto. +3. **Fase 2 (entrega sucessora, registrada no fechamento desta Issue):** remove `.forgejo/workflows/*`, scripts mortos e docs residuais do fluxo antigo. Só depois do fluxo GitHub comprovado de ponta a ponta. + +### Componentes / mudanças + +- **`.github/workflows/ci-pr.yml`** (novo): port do `.forgejo/workflows/ci-pr.yml` — job único `checks`, mesmos steps/guards/services (`postgres-int`/`postgres-build` por nome na rede do job), skips via `ci-scope.mjs` (env `GITHUB_BASE_REF` idêntico). Deltas GitHub: `concurrency: { group: ci-pr-${{ github.head_ref }}, cancel-in-progress: true }` (fail-fast nativo em push novo — o OPS62 não cancelava só porque o Forgejo não tem API; aqui é grátis), `if:` same-repo no job (fork não queima minutes), `permissions: contents: read` (default), e2e selected preservado (OPS72 ajusta a política depois — `depends`). +- **`.github/workflows/deploy.yml`** (novo): `workflow_dispatch` (sem inputs — ref default main). `verify` (ubuntu-latest, timeout 50): `check-test-locations` → lint → format → typecheck → knip → cycles → unit → int (migrate+seed nos services) → build → e2e **full** (4 workers; guardas de contrato de PR ficam de fora — não são verificação de produção). `deploy` (`needs: [verify]`, `runs-on: [self-hosted, homeserver]`, timeout 60, `permissions: contents: read`): checkout → `bash scripts/deploy-homeserver.sh "$GITHUB_SHA"`. +- **`scripts/deploy-homeserver.sh`**: `TEQO_REPO_URL` default → `https://github.com/fsolla/teqo.git`; no workspace existente, `git remote set-url origin "$TEQO_REPO_URL"` idempotente antes do fetch (o clone velho aponta para o Forgejo local); doc de invocação: execução local no runner (não mais pipe via ssh) — o `</dev/null` no `run --rm` do migrate permanece. Fluxo interno intacto (HEAD guard, flock, already-deployed, migrator→migrate→runner→rollout, smoke). +- **`.github/workflows/agent-pr-ready-automerge.yml`** (novo) + **`scripts/github-pr-automerge.mjs`** (novo, plain Node) + **`scripts/lib/github-api.mjs`** (novo, REST+GraphQL zero-dep): lê PR (REST); base != main → skip; draft `cursor/*` → `PATCH draft:false`; draft outro → skip (veto OPS57); senão GraphQL `enablePullRequestAutoMerge(mergeMethod: REBASE)` no `node_id` do PR. Erro do GraphQL → exit 1 (job vermelho, visível). `permissions: { contents: write, pull-requests: write }`. +- **`scripts/github-pr.mjs`** (novo, plain Node): criação de PR para agentes/humano — `GITHUB_TOKEN` env; `--head <branch> --title <t> --body-file <f>` (Ready, base `main` — sem opção draft, regra do repo). Substitui o `forgejo_create_pull_request` do MCP no fluxo de entrega. +- **`scripts/lib/github-branch-protection.mjs`** (novo, puro): `DESIRED_RULE` GitHub (`required_status_checks.checks = [{ context: 'CI (PR) / checks' }]`, strict=false, 0 reviews, `enforce_admins: true`, sem restrictions) + `ruleMatches`/`planBranchProtectionRule` (mesmo contrato do atual). +- **`scripts/configure-branch-protection.mjs`**: reescrito para a REST do GitHub (`PUT /repos/{owner}/{repo}/branches/main/protection`), idempotente (read → plan → apply → verify), `--dry-run` preservado. +- **`scripts/forgejo-issue-transition.mjs`**: aceita `PR_BODY` env (body do PR vem do evento GitHub); sem PR_BODY mantém a leitura via API do Forgejo (fallback — os workflows do Forgejo ainda estão vivos até a Fase 2); comentário do flip atualizado ("deploy manual via dispatch, ver AGENT-OPS"). +- **`.github/workflows/issue-done-on-main-merge.yml` / `plan-issue-ready-on-main-merge.yml`** (novos): `pull_request: closed` + `if:` merged && base main && **same-repo** (guarda RCE: checkout de fork + PAT = RCE — preservada); `PR_BODY: ${{ github.event.pull_request.body }}`; `FORGEJO_API_TOKEN` secret; sem `GITHUB_TOKEN` de Issues do GitHub (flip é no Forgejo). +- **`.github/workflows/archive-cursor-agent.yml`** (novo): port direto do `.forgejo/workflows/` (CURSOR_API_KEY). +- **`docs/AGENT-OPS.md`, `.agents/rules/agent-pr-workflow.mdc`, `.agents/skills/work-issue/` (SKILL + execution-pipeline), `.agents/skills/agent-work-issue/SKILL.md`, `.agents/skills/capture-review-debts/SKILL.md` (linha do fechamento), `AGENTS.md`, `docs/ops/teqo-1313-deploy.md`**: fluxo de PR/CI/merge/deploy reescrito para GitHub (canônico); seção de transição nomeando a Fase 2; tabela de secrets (GitHub agora: `FORGEJO_API_TOKEN`, `CURSOR_API_KEY`, local `GITHUB_TOKEN` PAT); passos manuais do cutover na ordem (incl. desligar o runner do Forgejo e por quê — o schedule do `ci.yml` antigo pararia de ter sentido). +- **Preservados nesta entrega (Fase 2 remove):** `.forgejo/workflows/*` (6 arquivos), `scripts/forgejo-pr-automerge.mjs`, `scripts/forgejo-dispatch.mjs`, `scripts/ci-classify-production.mjs`, `scripts/lib/dockerignore.mjs`, `scripts/lib/branch-protection.mjs` + specs (`ciClassifyProduction`, `dockerignoreMatch`, `branchProtection`) — dormentes, documentados como rollback e alvo da entrega de remoção. +- **Testes novos:** `tests/unit/githubApi.unit.spec.ts` (normalização de shapes + endpoints REST/GraphQL, molde do `forgejoApi.unit.spec.ts`), `tests/unit/githubBranchProtection.unit.spec.ts` (regra desejada + drift, molde do `branchProtection.unit.spec.ts`), e pure-functions da política de draft/skip do automerger (`scripts/lib/github-pr-flow.mjs` + spec — o pin OPS57/OPS64 do jeito GitHub). +- **Migration:** sem migration (nenhum schema). +- **Access / Consent:** nenhum. +- **UI:** Impeccable N/A. + +## Fases verificáveis + +1. **Libs + scripts base** — `github-api.mjs`, `github-pr-flow.mjs` (puro), `github-branch-protection.mjs` (puro), `github-pr.mjs`, `github-pr-automerge.mjs`, `forgejo-issue-transition.mjs` (PR_BODY), `configure-branch-protection.mjs` (GitHub) + specs unit. Gate: `pnpm test:unit`. +2. **Workflows** — `.github/workflows/*` (6). Nada do `.forgejo/workflows/` é tocado nesta fase (Fase 2 do cutover). Gate: `pnpm gate:fast` + `pnpm check:cycles` + knip. +3. **Docs/skills + changelog** — AGENTS.md, AGENT-OPS, agent-pr-workflow.mdc, skills, runbook (com seção de transição), `docs/changelog/2026-08-19-ops71.md` + `pnpm changelog:build`. +4. **Gates finais + entrega** — `pnpm gate:ci` completo (unit+int+build), format, knip, cycles; `pnpm push -u origin HEAD` → PR no GitHub via `node scripts/github-pr.mjs` → CI verde no GitHub → auto-merge → flip da #97. **Passos manuais do cutover listados para o humano** (Fase 1 do cutover: remotes, secrets, branch protection, runner homeserver, shutdown runner Forgejo) — o PR em si não depende deles (CI roda no GitHub com secrets de teste), mas a ordem recomendada é: remotes → secrets → configure → push → PR. + +## Fase 2 — entrega sucessora (pós-validação) + +Registrada no fechamento desta Issue (capture-review-debts): remove `.forgejo/workflows/*`, `forgejo-pr-automerge.mjs`, `forgejo-dispatch.mjs`, `ci-classify-production.mjs`, `dockerignore.mjs` (+ specs órfãs) e qualquer doc residual do fluxo Forgejo. Critério de entrada: um ciclo completo validado no GitHub (PR → CI → auto-merge → flip → deploy manual). + +## Rabbit holes / Não escopo (engenharia) + +- Portar `waitForChecks`/statuses para o GitHub — não há; auto-merge nativo. +- Re-engenharia do `deploy-homeserver.sh` (fluxo docker/compose/migrate) — só a origem do clone e o modo de invocação mudam. +- Sincronizar o repo Forgejo com main — congelado (decidido, anti-goal do tracker preservado). +- Migrar Issues/labels/claims — anti-goal explícito. +- OPS72 (e2e local afetado) — item sucessor com `depends: [OPS71]`. +- Pool/`agent-pool*` — dormente (OPS65); o texto `gh pr` em `agent-pool-prompt.mjs` é de feature morta — deixo como está (fora do serializes). +- Secrets de GitHub (`FORGEJO_API_TOKEN`, `CURSOR_API_KEY`, `GITHUB_TOKEN` PAT local) — passo manual documentado, não código. + +## Riscos e mitigação + +- **Nome do check-run `CI (PR) / checks`:** o workflow `name: CI (PR)` + job `checks` geram exatamente esse check-run no GitHub; o required check usa o mesmo literal — pin no spec da branch protection e verificação ao vivo no primeiro PR (se o nome divergir, o configure aponta o drift e o PR não mergea — fail-closed, nunca merge sem verificação). +- **Auto-merge GraphQL com `GITHUB_TOKEN`:** permissões declaradas (`contents`+`pull-requests: write`) cobrem PATCH draft e a mutation; se o GraphQL recusar (ex.: auto-merge desabilitado no repo), o job fica vermelho com a mensagem — mitigação: passo manual `allow_auto_merge: true` no repo (Settings ou API) listado no cutover. +- **PR com conflito:** auto-merge fica armado e o PR espera — igual ao hoje (waitForChecks lançava "não mergeável"); nenhum merge errado é possível (servidor). +- **Repo público → fork PR:** `if:` same-repo no job `checks` + setting de fork workflows no repo (passo manual) — fork não queima minutes nem acessa secrets. +- **Runner do homeserver ainda não instalado:** o `deploy` fica indisponível até o passo manual; PRs seguem mergeando (CI hosted não depende do runner). O PR deste item não publica nada sozinho — o deploy é dispatch manual. +- **Schedule do `ci.yml` antigo rodando na workstation durante a transição:** com o repo Forgejo congelado, o gate do Forgejo lerá um deployed SHA inexistente no clone → fail-open vermelho → suíte full a cada 30 min na workstation. Mitigado: o cutover desliga o runner do Forgejo logo após o merge (passo (d), reversível) — antes do primeiro deploy via GitHub. +- **`gate:ci` local vs `origin/main`:** o remote muda para GitHub; sem o passo manual dos remotes, o gate local compara contra o Forgejo defasado → risco de diff falso. Mitigado: o passo de remotes é o PRIMEIRO do cutover e o runbook avisa; o `*-impl.md` documenta o comando exato. +- **TEQO_REPO_URL no homeserver:** clone velho com origin Forgejo → `set-url` idempotente no script cobre; repo público → sem credencial. +- **Knip com os scripts do Forgejo preservados:** nada órfão é criado nesta entrega (todos os scripts seguem referenciados pelos YAMLs do `.forgejo/workflows/`, que permanecem) — sem risco de knip flagrar a deleção adiada. + +## Aceite de engenharia + +- [x] Aceite de produto da intenção ainda coberto (CI/PR GitHub, tracker Forgejo, deploy manual verify→self-hosted, rollup required check) +- [x] Cutover em duas fases (gate 2026-08-19): sistema GitHub criado e validado primeiro; arquivos do Forgejo preservados nesta entrega, remoção em entrega sucessora pós-validação +- [x] Invariantes AGENTS/engineering-standards (sem migration, sem schema; plain Node stdlib nos helpers de CI; zero-dep nos workflows) +- [x] Testes de domínio previstos: github-api (normalização/endpoints), github-branch-protection (drift), github-pr-flow (draft policy/skips — pin OPS57/OPS64 no jeito GitHub) diff --git a/scripts/configure-branch-protection.mjs b/scripts/configure-branch-protection.mjs index 34c824d5..f737ab0a 100644 --- a/scripts/configure-branch-protection.mjs +++ b/scripts/configure-branch-protection.mjs @@ -1,38 +1,45 @@ /** - * Drift repair for branch protection (main-only) — Forgejo. Idempotent: reads - * the existing rules and creates / updates / no-ops (never duplicates). + * Drift repair for `main` branch protection — GitHub (OPS71). Idempotent: + * reads the existing rule and creates / updates / no-ops (never duplicates). * - * pnpm configure:branch-protection # apply - * pnpm configure:branch-protection -- --dry-run + * GITHUB_TOKEN=<PAT> pnpm configure:branch-protection # apply + * GITHUB_TOKEN=<PAT> pnpm configure:branch-protection -- --dry-run * - * main: required status check `CI (PR) / checks*` (the ci-pr cascade rollup — - * OPS61: Forgejo matches the contexts as globs against the real status - * contexts like `CI (PR) / checks (pull_request)`, so the old literal `checks` - * would match nothing), strict=false, 0 reviews. Feature PRs auto-merge when - * that context is green; the server rule is the final defense against merges - * before the cascade settles (the waitForChecks rollup gate is the client - * half). - * (migration-lock removed 2026-08-12 — see ci-pr.yml header.) + * Desired rule: required check-run `CI (PR) / checks` (the ci-pr cascade — + * OPS62), strict=false, 0 reviews, `enforce_admins: true` (nobody, admin + * included, merges with a red required check). Feature PRs auto-merge when + * that check is green; the server rule is the final defense against every + * merge path, manual API merges included. */ -import { parseArgs } from './lib/agent-forgejo.mjs' -import { DESIRED_RULE, planBranchProtectionRule } from './lib/branch-protection.mjs' -import { createApi } from './lib/forgejo-api.mjs' +import { createApi } from './lib/github-api.mjs' +import { DESIRED_RULE, planBranchProtectionRule } from './lib/github-branch-protection.mjs' -const { flags } = parseArgs(process.argv.slice(2), new Set()) -const dryRun = flags['dry-run'] === true +const parseArgs = (argv) => { + const flags = {} + for (let index = 2; index < argv.length; index += 1) { + const arg = argv[index] + if (arg.startsWith('--')) { + const name = arg.slice(2).replace(/-([a-z])/g, (_, char) => char.toUpperCase()) + const next = argv[index + 1] + flags[name] = typeof next === 'string' && !next.startsWith('--') ? next : true + if (typeof next === 'string' && !next.startsWith('--')) index += 1 + } + } + return flags +} + +const flags = parseArgs(process.argv) +const dryRun = flags.dryRun === true +const branch = 'main' const api = createApi({}) -const repo = process.env.FORGEJO_REPOSITORY ?? process.env.GITHUB_REPOSITORY ?? 'fsolla/teqo' -const ruleName = DESIRED_RULE.rule_name - -const existingRules = await api.listBranchProtections() -const existing = - existingRules.find((rule) => rule.rule_name === ruleName || rule.branch_name === ruleName) ?? null +const repo = process.env.GITHUB_REPOSITORY ?? 'fsolla/teqo' +const existing = await api.getBranchProtection(branch) const { action } = planBranchProtectionRule(existing) console.log( - `[configure:branch-protection] repo ${repo}${dryRun ? ' (dry-run)' : ''} — regra "${ruleName}": ${ + `[configure:branch-protection] repo ${repo}${dryRun ? ' (dry-run)' : ''} — regra "${branch}": ${ action === 'noop' ? 'já conforme — nada a fazer' : action === 'update' @@ -42,34 +49,26 @@ console.log( ) if (action === 'noop') { - console.log(`[configure:branch-protection] no-op: ${JSON.stringify(DESIRED_RULE)}`) + console.log(`[configure:branch-protection] no-op: ${JSON.stringify(existing)}`) process.exit(0) } -const payload = { ...DESIRED_RULE, branch_name: ruleName } -const target = action === 'create' ? '/branch_protections' : `/branch_protections/${ruleName}` -const method = action === 'create' ? 'POST' : 'PATCH' - if (dryRun) { - console.log(`[dry-run] ${method} /repos/${repo}${target} ${JSON.stringify(payload)}`) + console.log( + `[dry-run] PUT /repos/${repo}/branches/${branch}/protection ${JSON.stringify(DESIRED_RULE)}`, + ) process.exit(0) } -if (action === 'create') { - await api.updateBranchProtection(ruleName, payload) -} else { - await api.editBranchProtection(ruleName, payload) -} +await api.updateBranchProtection(DESIRED_RULE, branch) -const after = await api.listBranchProtections() -const applied = - after.find((rule) => rule.rule_name === ruleName || rule.branch_name === ruleName) ?? null -if (!applied) { +const after = await api.getBranchProtection(branch) +if (!after) { console.error( - `[configure:branch-protection] FALHOU: ${method} ${target} respondeu mas a regra "${ruleName}" não aparece no servidor.`, + `[configure:branch-protection] FALHOU: PUT respondeu mas a regra "${branch}" não aparece no servidor.`, ) process.exit(1) } console.log( - `[configure:branch-protection] done — regra verificada no servidor: ${JSON.stringify(applied)}`, + `[configure:branch-protection] done — regra verificada no servidor: ${JSON.stringify(after)}`, ) diff --git a/scripts/deploy-homeserver.sh b/scripts/deploy-homeserver.sh index 135a93e4..4c36d36d 100644 --- a/scripts/deploy-homeserver.sh +++ b/scripts/deploy-homeserver.sh @@ -2,8 +2,11 @@ # # Deploy teqo-1313 to the homeserver (OPS53). # -# Runs ON the homeserver, piped by the CI deploy job: -# ssh homeserver "bash -s -- <commit-sha>" < scripts/deploy-homeserver.sh +# OPS71: runs ON the homeserver via the GitHub self-hosted runner (deploy job +# of .github/workflows/deploy.yml): +# bash scripts/deploy-homeserver.sh <commit-sha> +# (The Forgejo-era invocation `ssh homeserver "bash -s -- <sha>" < script` +# is gone — no SSH hop, no workstation involvement.) # # Flow: HEAD guard (only the current main HEAD deploys) -> flock # serialization -> workspace fetch at <sha> -> docker login (local registry) @@ -17,14 +20,16 @@ # the running site untouched and the job red. # # Environment defaults assume the homeserver layout: stack under -# $HOME/stack, repo cloned from the local Forgejo. Secrets are sourced from -# the chmod-600 env files and never echoed (no `set -x`, passwords only via -# --password-stdin / build secrets). +# $HOME/stack, repo cloned from github.com/fsolla/teqo (public — no +# credentials; the pre-OPS71 clone pointed at the local Forgejo and is +# re-pointed idempotently below). Secrets are sourced from the chmod-600 env +# files and never echoed (no `set -x`, passwords only via --password-stdin / +# build secrets). set -euo pipefail SHA="${1:?usage: deploy-homeserver.sh <commit-sha>}" -TEQO_REPO_URL="${TEQO_REPO_URL:-http://localhost:3000/fsolla/teqo.git}" +TEQO_REPO_URL="${TEQO_REPO_URL:-https://github.com/fsolla/teqo.git}" STACK_DIR="${STACK_DIR:-$HOME/stack}" WORKSPACE_DIR="${WORKSPACE_DIR:-$HOME/teqo-deploy}" DEPLOY_LOCK="${DEPLOY_LOCK:-/tmp/teqo-1313-deploy.lock}" @@ -88,6 +93,14 @@ if [ ! -d "$WORKSPACE_DIR/.git" ]; then say "cloning $TEQO_REPO_URL into $WORKSPACE_DIR" git clone "$TEQO_REPO_URL" "$WORKSPACE_DIR" else + # OPS71: the pre-cutover clone pointed at the local Forgejo — re-point + # idempotently so the HEAD guard and the fetch compare against the repo + # that actually received the merge. + current_url="$(git -C "$WORKSPACE_DIR" remote get-url origin 2>/dev/null || true)" + if [ -n "$current_url" ] && [ "$current_url" != "$TEQO_REPO_URL" ]; then + say "updating workspace origin: $current_url → $TEQO_REPO_URL" + git -C "$WORKSPACE_DIR" remote set-url origin "$TEQO_REPO_URL" + fi git -C "$WORKSPACE_DIR" fetch origin main fi git -C "$WORKSPACE_DIR" checkout --detach "$SHA" || fatal "checkout of $SHA failed" diff --git a/scripts/forgejo-issue-transition.mjs b/scripts/forgejo-issue-transition.mjs index 0dbee9c5..5092283f 100644 --- a/scripts/forgejo-issue-transition.mjs +++ b/scripts/forgejo-issue-transition.mjs @@ -2,8 +2,12 @@ * Plain-Node CLI (no pnpm) — on merge to main, flip Issues cited as * `Closes #N` / `Fixes #N` in the PR body to `done` + `in-prod` and comment. * Replacement for the `gh issue edit/comment` loop of issue-done-on-main-merge. - * The PR body comes from the API (Forgejo's PR webhook payload is not relied - * on), so the workflow only needs the PR number. + * + * OPS71: the PR now lives on GitHub. The workflow passes the PR body via the + * `PR_BODY` env (from the GitHub event payload) and the script flips Issues + * on the Forgejo tracker by API — no Forgejo PR read when PR_BODY is present. + * Without PR_BODY the script falls back to reading the PR from the Forgejo + * API (the Forgejo-era workflows stay alive until the OPS71 Fase 2 removal). * * OPS61: a failed flip exits 1 — the flip is the whole purpose of this * workflow, and the 403 era proved that a swallowed error ends the job @@ -11,6 +15,7 @@ * (the loop does not abort), but the job goes red so the breakage is visible. * * node scripts/forgejo-issue-transition.mjs --pr <N> + * PR_BODY='Closes #97' node scripts/forgejo-issue-transition.mjs --pr <N> */ import { createApi } from './lib/forgejo-api.mjs' @@ -37,7 +42,11 @@ if (!Number.isInteger(prNumber) || prNumber <= 0) { } const api = createApi({}) -const pr = await api.getPullRequest(prNumber) +const bodyFromEnv = process.env.PR_BODY +const pr = + typeof bodyFromEnv === 'string' + ? { merged: true, body: bodyFromEnv } + : await api.getPullRequest(prNumber) if (!pr) { console.error(`[forgejo-issue-transition] PR #${prNumber} não encontrada`) process.exit(1) @@ -62,7 +71,7 @@ for (const number of numbers) { await api.setLabels(number, { add: ['done', 'in-prod'], remove: ['in-progress'] }) await api.addComment( number, - `Merged em main via PR #${prNumber} — \`done\` + \`in-prod\`. Deploy de produção segue o verificador \`ci.yml\` (gated).`, + `Merged em main via PR #${prNumber} — \`done\` + \`in-prod\`. Deploy de produção é manual (workflow_dispatch no GitHub Actions) — ver docs/AGENT-OPS.md.`, ) console.log(`[forgejo-issue-transition] #${number}: done + in-prod`) } catch (error) { diff --git a/scripts/github-pr-automerge.mjs b/scripts/github-pr-automerge.mjs new file mode 100644 index 00000000..1276690c --- /dev/null +++ b/scripts/github-pr-automerge.mjs @@ -0,0 +1,69 @@ +/** + * Plain-Node CLI (no pnpm) — GitHub PR safety net: mark `cursor/*` drafts + * ready and arm GitHub's native auto-merge (rebase). Runs in + * .github/workflows/agent-pr-ready-automerge.yml with the built-in + * GITHUB_TOKEN (permissions: contents+pull-requests write). + * + * Unlike the Forgejo-era CLI (forgejo-pr-automerge.mjs), there is NO poll + * loop: `enablePullRequestAutoMerge` is server-side — GitHub only merges when + * every required check (incl. `CI (PR) / checks`) is green and the PR is + * mergeable. The OPS64 "never trust the rollup" pin is structural here: a + * single sequential job posts one honest check-run, and the server enforces + * it. Draft policy (OPS57) preserved: only `cursor/*` heads are marked + * ready — any other draft is the actor's veto (skip, exit 0). + * + * Idempotent: already merged / closed / non-main base → no-op success. + * A GraphQL error (e.g. repo auto-merge disabled, PR in conflict) exits 1 so + * the job goes red and the situation is visible. + * + * node scripts/github-pr-automerge.mjs --pr <N> + */ + +import { createApi } from './lib/github-api.mjs' +import { decideAutomergeAction } from './lib/github-pr-flow.mjs' + +const parseArgs = (argv) => { + const flags = {} + for (let index = 2; index < argv.length; index += 1) { + const arg = argv[index] + if (arg.startsWith('--')) { + const name = arg.slice(2) + const next = argv[index + 1] + flags[name] = typeof next === 'string' && !next.startsWith('--') ? next : true + if (typeof next === 'string' && !next.startsWith('--')) index += 1 + } + } + return flags +} + +const flags = parseArgs(process.argv) +const prNumber = Number(flags.pr) +if (!Number.isInteger(prNumber) || prNumber <= 0) { + console.error('Usage: node scripts/github-pr-automerge.mjs --pr <N>') + process.exit(1) +} + +const api = createApi({}) +try { + const pr = await api.getPullRequest(prNumber) + const verdict = decideAutomergeAction(pr) + + if (verdict.action === 'skip') { + console.log(`[github-pr-automerge] PR #${prNumber}: skip (${verdict.reason})`) + process.exit(0) + } + + if (verdict.action === 'mark-ready') { + console.log(`[github-pr-automerge] PR #${prNumber} é draft cursor/* — marcando Ready`) + await api.markPullRequestReady(prNumber) + } + + console.log(`[github-pr-automerge] PR #${prNumber}: armando auto-merge (rebase)`) + await api.enableAutoMerge(pr.nodeId) + console.log( + `[github-pr-automerge] PR #${prNumber}: auto-merge armado — o GitHub mergea quando o required check "CI (PR) / checks" fica verde`, + ) +} catch (error) { + console.error(`[github-pr-automerge] falhou: ${error instanceof Error ? error.message : error}`) + process.exit(1) +} diff --git a/scripts/github-pr.mjs b/scripts/github-pr.mjs new file mode 100644 index 00000000..fbbb7b0d --- /dev/null +++ b/scripts/github-pr.mjs @@ -0,0 +1,64 @@ +/** + * Plain-Node CLI (no pnpm) — create a GitHub PR (Ready, never draft) for + * agent deliveries. Replaces the Forgejo MCP `create_pull_request` in the + * delivery flow (OPS71: PRs live on GitHub; the tracker stays on Forgejo). + * + * GITHUB_TOKEN=<PAT> node scripts/github-pr.mjs \ + * --head <branch> --title "<título>" --body-file <path> + * GITHUB_TOKEN=<PAT> node scripts/github-pr.mjs --head <b> --title <t> --body "Closes #N" + * + * The repo rule "PRs are Ready, never draft" is structural: there is no + * `--draft` flag. Base defaults to `main`. + */ + +import { createApi } from './lib/github-api.mjs' + +const parseArgs = (argv) => { + const flags = {} + for (let index = 2; index < argv.length; index += 1) { + const arg = argv[index] + if (arg.startsWith('--')) { + const name = arg.slice(2) + const next = argv[index + 1] + flags[name] = typeof next === 'string' && !next.startsWith('--') ? next : true + if (typeof next === 'string' && !next.startsWith('--')) index += 1 + } + } + return flags +} + +const flags = parseArgs(process.argv) +const head = flags.head +const title = flags.title +const base = flags.base ?? 'main' + +if (!head || !title) { + console.error( + 'Usage: node scripts/github-pr.mjs --head <branch> --title <t> [--base main] --body "<text>" | --body-file <path>', + ) + process.exit(1) +} + +let body = flags.body +if (flags.bodyFile) { + try { + const { readFileSync } = await import('node:fs') + body = readFileSync(flags.bodyFile, 'utf8') + } catch (error) { + console.error(`[github-pr] não consegui ler --body-file: ${error.message}`) + process.exit(1) + } +} +if (typeof body !== 'string' || body.length === 0) { + console.error('[github-pr] body vazio — passe --body ou --body-file') + process.exit(1) +} + +const api = createApi({}) +try { + const pr = await api.createPullRequest({ head, base, title, body }) + console.log(`[github-pr] PR #${pr.number} criado (Ready): ${pr.htmlUrl}`) +} catch (error) { + console.error(`[github-pr] falhou: ${error instanceof Error ? error.message : error}`) + process.exit(1) +} diff --git a/scripts/lib/github-api.mjs b/scripts/lib/github-api.mjs new file mode 100644 index 00000000..ccc1fbd3 --- /dev/null +++ b/scripts/lib/github-api.mjs @@ -0,0 +1,264 @@ +/** + * GitHub REST + GraphQL client for the CI/PR scripts (`github-pr*`, branch + * protection). Zero dependencies — plain Node `fetch` — so it also runs + * inside GitHub Actions jobs without `pnpm install`. + * + * Auth: `GITHUB_TOKEN` (PAT locally; the built-in Actions token in + * workflows). Base URL: `GITHUB_API_URL`, else `https://api.github.com`. + * + * Retry (same policy as forgejo-api OPS67): transient failures retry with + * exponential backoff — a fetch that rejects (network-level, DNS/TCP/reset) + * retries on ANY method; a 5xx retries on GET only, so read polls survive + * while write endpoints keep failing closed instead of risking duplicated + * side effects. 4xx never retries. Defaults: 3 retries, base 300 ms ×2, + * ±20% jitter. + * + * Shapes are normalized to the contract the CLI scripts use: `pr.state` ∈ + * OPEN|CLOSED, `pr.draft`, `pr.nodeId` (GraphQL auto-merge), branch + * protection normalized for drift comparison. + */ + +const DEFAULT_BASE_URL = 'https://api.github.com' +const DEFAULT_GRAPHQL_URL = 'https://api.github.com/graphql' +const DEFAULT_REPOSITORY = 'fsolla/teqo' +const USER_AGENT = 'teqo-agent-scripts/1.0 (github)' +const RETRYABLE_STATUSES = new Set([502, 503, 504]) + +/** + * @typedef {object} GithubApiOptions + * @property {string} [base] + * @property {string} [graphqlBase] + * @property {string} [token] + * @property {string} [repository] + * @property {(input: string | URL, init?: { method?: string; headers?: Record<string, string>; body?: string }) => Promise<Response>} [fetchImpl] + * @property {number} [retries] Additional attempts after the first (total = retries + 1). Default 3. + * @property {number} [backoffMs] Base exponential delay. Default 300. + * @property {boolean} [jitter] ±20% randomization on each delay. Default true. + * @property {(ms: number) => Promise<void>} [sleepImpl] Test seam for the backoff delay. + */ + +/** + * @param {GithubApiOptions} [options] + */ +export const createApi = ({ + base, + graphqlBase, + token, + repository, + fetchImpl, + retries = 3, + backoffMs = 300, + jitter = true, + sleepImpl = (ms) => new Promise((resolve) => setTimeout(resolve, ms)), +} = {}) => { + const baseUrl = (base ?? process.env.GITHUB_API_URL ?? DEFAULT_BASE_URL).replace(/\/+$/, '') + const graphqlUrl = (graphqlBase ?? process.env.GITHUB_GRAPHQL_URL ?? DEFAULT_GRAPHQL_URL).replace( + /\/+$/, + '', + ) + const repo = repository ?? process.env.GITHUB_REPOSITORY ?? DEFAULT_REPOSITORY + const fetcher = fetchImpl ?? fetch + const [owner, name] = repo.split('/') + if (retries < 0 || backoffMs < 0) { + throw new Error( + `Retry inválido: retries=${retries}, backoffMs=${backoffMs} — ambos devem ser >= 0`, + ) + } + const attemptCount = retries + 1 + + const backoffDelay = (attempt) => { + const base = backoffMs * 2 ** (attempt - 1) + return jitter ? Math.round(base * (0.8 + Math.random() * 0.4)) : base + } + + const warnRetry = (path, method, reason, attempt, delay) => + console.warn( + `[github-api] ${method} ${path} falhou (tentativa ${attempt}/${attemptCount}): ${reason} — retry em ${delay}ms`, + ) + + const headers = (withJson = true) => { + const authToken = token ?? process.env.GITHUB_TOKEN + if (!authToken) { + throw new Error('Sem token para a API do GitHub — defina GITHUB_TOKEN.') + } + return { + Authorization: `Bearer ${authToken}`, + 'User-Agent': USER_AGENT, + ...(withJson ? { 'Content-Type': 'application/json' } : {}), + } + } + + const request = async (path, { method = 'GET', body, query } = {}) => { + const qs = query + ? '?' + + Object.entries(query) + .filter(([, value]) => value !== undefined && value !== null) + .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`) + .join('&') + : '' + const url = `${baseUrl}${path}${qs}` + const retryAfter = async (attempt, reason) => { + const delay = backoffDelay(attempt) + warnRetry(path, method, reason, attempt, delay) + await sleepImpl(delay) + } + for (let attempt = 1; attempt <= attemptCount; attempt += 1) { + const isLastAttempt = attempt === attemptCount + let response + try { + response = await fetcher(url, { + method, + headers: headers(), + ...(body !== undefined ? { body: JSON.stringify(body) } : {}), + }) + } catch (error) { + if (isLastAttempt) throw error + await retryAfter(attempt, error.message) + continue + } + if (method === 'GET' && !isLastAttempt && RETRYABLE_STATUSES.has(response.status)) { + await response.body?.cancel() + await retryAfter(attempt, `HTTP ${response.status}`) + continue + } + let text + try { + text = await response.text() + } catch (error) { + if (isLastAttempt || method !== 'GET') throw error + await retryAfter(attempt, error.message) + continue + } + if (response.status === 404 && method === 'GET') return null + if (!response.ok) { + throw new Error(`GitHub API ${method} ${path} → ${response.status}: ${text.slice(0, 400)}`) + } + if (!text) return null + try { + return JSON.parse(text) + } catch { + throw new Error(`GitHub API ${method} ${path}: resposta não-JSON: ${text.slice(0, 80)}`) + } + } + } + + const graphql = async (query, variables) => { + let response + try { + response = await fetcher(graphqlUrl, { + method: 'POST', + headers: headers(), + body: JSON.stringify({ query, variables }), + }) + } catch (error) { + throw new Error(`GitHub GraphQL falhou (rede): ${error.message}`) + } + const text = await response.text() + if (!response.ok) { + throw new Error(`GitHub GraphQL → ${response.status}: ${text.slice(0, 400)}`) + } + const parsed = JSON.parse(text) + const firstError = parsed?.errors?.[0] + if (firstError) { + throw new Error(`GitHub GraphQL: ${firstError.message}`) + } + return parsed.data ?? null + } + + const normalizeState = (state) => (String(state).toLowerCase() === 'closed' ? 'CLOSED' : 'OPEN') + + const normalizePullRequest = (pr) => ({ + number: pr.number, + title: pr.title, + body: pr.body ?? '', + state: normalizeState(pr.state), + merged: Boolean(pr.merged_at || pr.merged), + draft: Boolean(pr.draft), + mergeable: pr.mergeable ?? null, + nodeId: pr.node_id ?? '', + head: { ref: pr.head?.ref ?? '', sha: pr.head?.sha ?? '' }, + base: { ref: pr.base?.ref ?? '' }, + }) + + const api = { + /** + * GET /repos/{owner}/{repo}/pulls/{number} — normalized. + * @param {number} number + */ + getPullRequest: async (number) => { + const pr = await request(`/repos/${owner}/${name}/pulls/${number}`) + return pr ? normalizePullRequest(pr) : null + }, + + /** PATCH draft:false — marks a draft PR ready for review. */ + markPullRequestReady: (number) => + request(`/repos/${owner}/${name}/pulls/${number}`, { + method: 'PATCH', + body: { draft: false }, + }), + + /** POST /pulls — creates a PR (never draft). */ + createPullRequest: async ({ head, base = 'main', title, body }) => { + const pr = await request(`/repos/${owner}/${name}/pulls`, { + method: 'POST', + body: { head, base, title, body }, + }) + return { number: pr.number, title: pr.title, htmlUrl: pr.html_url } + }, + + /** + * Enables GitHub's native auto-merge (GraphQL) with the repo's canonical + * merge style (rebase). The server waits for the required checks — a PR + * with a red `CI (PR) / checks` can never auto-merge. + */ + enableAutoMerge: async (nodeId, mergeMethod = 'REBASE') => { + await graphql( + ` + mutation EnablePullRequestAutoMerge($id: ID!, $mergeMethod: PullRequestMergeMethod!) { + enablePullRequestAutoMerge(input: { pullRequestId: $id, mergeMethod: $mergeMethod }) { + pullRequest { + number + } + } + } + `, + { id: nodeId, mergeMethod }, + ) + }, + + /** + * GET /repos/{owner}/{repo}/branches/{branch}/protection — normalized for + * drift comparison; `null` when the branch has no protection rule (404). + */ + getBranchProtection: async (branch = 'main') => { + const rule = await request(`/repos/${owner}/${name}/branches/${branch}/protection`) + if (!rule) return null + return { + required_status_checks: rule.required_status_checks + ? { + strict: Boolean(rule.required_status_checks.strict), + contexts: (rule.required_status_checks.checks ?? []).map((entry) => entry.context), + } + : null, + enforce_admins: Boolean(rule.enforce_admins?.enabled ?? rule.enforce_admins), + required_pull_request_reviews: rule.required_pull_request_reviews ?? null, + } + }, + + /** + * PUT /repos/{owner}/{repo}/branches/{branch}/protection — replaces the + * whole rule (GitHub replace semantics: omitted protections are removed). + */ + updateBranchProtection: (payload, branch = 'main') => + request(`/repos/${owner}/${name}/branches/${branch}/protection`, { + method: 'PUT', + body: payload, + }), + + /** PATCH /repos/{owner}/{repo} — repo settings (e.g. allow_auto_merge). */ + updateRepository: (payload) => + request(`/repos/${owner}/${name}`, { method: 'PATCH', body: payload }), + } + + return api +} diff --git a/scripts/lib/github-branch-protection.mjs b/scripts/lib/github-branch-protection.mjs new file mode 100644 index 00000000..c4a4b13f --- /dev/null +++ b/scripts/lib/github-branch-protection.mjs @@ -0,0 +1,71 @@ +/** + * Pure decision for the GitHub `main` branch protection rule (OPS71). + * + * The desired rule is the repo contract: main requires the `CI (PR) / checks` + * check-run (the ci-pr single-job cascade — OPS62) as the only status check + * (strict=false, 0 reviews) and `enforce_admins: true` so even repo admins + * cannot merge with a red required check (the rule-based protection of the + * Forgejo era applied to everyone — preserved). + * + * The auto-merge safety net never merges on red CI by construction (GitHub's + * server-side guarantee), but the branch protection rule is the final defense + * against every other merge path (manual API merges included). + */ + +export const REQUIRED_CHECK_CONTEXT = 'CI (PR) / checks' + +/** + * GitHub PUT /branches/{branch}/protection replace-semantics payload. Only + * `checks` (modern) is sent — `contexts` is legacy-derived and GitHub's API + * rejects the two together (422 anyOf). The GET normalization reads the + * check-run contexts from `checks`, so drift comparison is unaffected. + */ +export const DESIRED_RULE = Object.freeze({ + required_status_checks: { + strict: false, + checks: [{ context: REQUIRED_CHECK_CONTEXT }], + }, + enforce_admins: true, + required_pull_request_reviews: null, + restrictions: null, + required_linear_history: false, + allow_force_pushes: false, + allow_deletions: false, + block_creations: false, +}) + +const sameStrings = (have, want) => + have.length === want.length && + want.every((value) => have.includes(value)) && + have.every((value) => want.includes(value)) + +/** + * True when the existing rule (from `getBranchProtection`, already + * normalized) matches the desired rule on every compared field — array + * fields as sets. + */ +export const ruleMatches = (existing) => { + if (!existing) return false + const wantStatus = DESIRED_RULE.required_status_checks + if (existing.enforce_admins !== DESIRED_RULE.enforce_admins) return false + if (existing.required_pull_request_reviews !== null) return false + const haveStatus = existing.required_status_checks + if (!haveStatus) return false + if (haveStatus.strict !== wantStatus.strict) return false + return sameStrings( + haveStatus.contexts, + wantStatus.checks.map((entry) => entry.context), + ) +} + +/** + * What to do with the rule: `create` (no rule), `update` (rule exists with + * drift), `noop` (already compliant). Idempotent re-runs land on `noop`. + * + * @param {object|null} existing - normalized rule from the API, or null + * @returns {{ action: 'create' | 'update' | 'noop' }} + */ +export const planBranchProtectionRule = (existing) => { + if (ruleMatches(existing)) return { action: 'noop' } + return { action: existing ? 'update' : 'create' } +} diff --git a/scripts/lib/github-pr-flow.mjs b/scripts/lib/github-pr-flow.mjs new file mode 100644 index 00000000..d6f91f61 --- /dev/null +++ b/scripts/lib/github-pr-flow.mjs @@ -0,0 +1,31 @@ +/** + * Pure decision logic for the GitHub PR auto-merge safety net + * (scripts/github-pr-automerge.mjs). Unit-tested in + * tests/unit/githubPrFlow.unit.spec.ts — the OPS57 (draft veto) / OPS64 + * (never merge on red CI) pins ported to the GitHub mechanism. + * + * GitHub's native auto-merge only fires with the required checks green, so + * the safety net's only real decisions are: skip (non-main base, draft veto, + * already merged) or mark-ready (cursor/* draft) before arming auto-merge. + */ + +export const CURSOR_HEAD_PREFIX = 'cursor/' + +/** OPS57: only `cursor/*` drafts get force-marked ready — any other draft is the actor's veto. */ +export const isCursorHead = (ref) => typeof ref === 'string' && ref.startsWith(CURSOR_HEAD_PREFIX) + +/** + * @param {object|null} pr - normalized PR from github-api (or null) + * @returns {{ action: 'skip' | 'mark-ready' | 'enable-auto-merge', reason: string }} + */ +export const decideAutomergeAction = (pr) => { + if (!pr) return { action: 'skip', reason: 'pr-inexistente' } + if (pr.merged) return { action: 'skip', reason: 'ja-mergeada' } + if (pr.state !== 'OPEN') return { action: 'skip', reason: 'pr-nao-aberta' } + if (pr.base?.ref !== 'main') return { action: 'skip', reason: 'base-nao-main' } + if (pr.draft) { + if (isCursorHead(pr.head?.ref)) return { action: 'mark-ready', reason: 'draft-cursor' } + return { action: 'skip', reason: 'draft-veto' } + } + return { action: 'enable-auto-merge', reason: 'ready' } +} diff --git a/tests/unit/githubApi.unit.spec.ts b/tests/unit/githubApi.unit.spec.ts new file mode 100644 index 00000000..5e16363f --- /dev/null +++ b/tests/unit/githubApi.unit.spec.ts @@ -0,0 +1,228 @@ +import { describe, expect, it } from 'vitest' + +import { createApi } from '../../scripts/lib/github-api.mjs' + +type FetchCall = { + url: string + method?: string + init?: { headers?: Record<string, string>; method?: string; body?: string } + body?: unknown +} + +const ok = (body: unknown, status = 200) => + new Response(typeof body === 'string' ? body : JSON.stringify(body), { + status, + headers: { 'Content-Type': 'application/json' }, + }) + +describe('github-api', () => { + it('builds the request with bearer token, JSON body and explicit User-Agent', async () => { + const calls: FetchCall[] = [] + const api = createApi({ + token: 'tok', + repository: 'fsolla/teqo', + fetchImpl: async (url, init) => { + calls.push({ url: String(url), init }) + return ok({ number: 1, title: 't', body: '', state: 'open', node_id: 'PR_x' }) + }, + }) + + await api.getPullRequest(1) + + expect(calls).toHaveLength(1) + expect(calls[0].url).toBe('https://api.github.com/repos/fsolla/teqo/pulls/1') + expect(calls[0].init!.headers!.Authorization).toBe('Bearer tok') + expect(calls[0].init!.headers!['User-Agent']).toContain('teqo-agent-scripts') + }) + + it('fails closed when no token is available', async () => { + delete process.env.GITHUB_TOKEN + const api = createApi({ fetchImpl: async () => ok('{}') }) + + await expect(api.getPullRequest(1)).rejects.toThrow(/GITHUB_TOKEN/) + }) + + it('normalizes the pull request to the CLI contract (state/draft/nodeId/head/base)', async () => { + const api = createApi({ + token: 'tok', + fetchImpl: async () => + ok({ + number: 7, + title: 't', + body: 'Closes #1', + state: 'closed', + merged_at: '2026-08-19T00:00:00Z', + draft: false, + mergeable: true, + node_id: 'PR_abc123', + head: { ref: 'OPS71-x', sha: 'deadbeef' }, + base: { ref: 'main' }, + }), + }) + + const pr = await api.getPullRequest(7) + + expect(pr).toEqual({ + number: 7, + title: 't', + body: 'Closes #1', + state: 'CLOSED', + merged: true, + draft: false, + mergeable: true, + nodeId: 'PR_abc123', + head: { ref: 'OPS71-x', sha: 'deadbeef' }, + base: { ref: 'main' }, + }) + }) + + it('markPullRequestReady patches draft:false', async () => { + const calls: FetchCall[] = [] + const api = createApi({ + token: 'tok', + fetchImpl: async (url, init) => { + calls.push({ url: String(url), method: init?.method, body: init?.body }) + return ok(null) + }, + }) + + await api.markPullRequestReady(4) + + expect(calls).toEqual([ + { + url: 'https://api.github.com/repos/fsolla/teqo/pulls/4', + method: 'PATCH', + body: JSON.stringify({ draft: false }), + }, + ]) + }) + + it('createPullRequest posts a Ready PR (never draft) with the given body', async () => { + const calls: FetchCall[] = [] + const api = createApi({ + token: 'tok', + fetchImpl: async (url, init) => { + calls.push({ url: String(url), method: init?.method, body: init?.body }) + return ok({ number: 9, title: 't', html_url: 'https://github.com/fsolla/teqo/pull/9' }) + }, + }) + + const created = await api.createPullRequest({ + head: 'OPS71-x', + base: 'main', + title: 'OPS71 — x', + body: 'Closes #97', + }) + + expect(created).toEqual({ + number: 9, + title: 't', + htmlUrl: 'https://github.com/fsolla/teqo/pull/9', + }) + expect(calls[0].url).toBe('https://api.github.com/repos/fsolla/teqo/pulls') + expect(JSON.parse(String(calls[0].body))).toEqual({ + head: 'OPS71-x', + base: 'main', + title: 'OPS71 — x', + body: 'Closes #97', + }) + }) + + it('enableAutoMerge posts the GraphQL mutation with rebase', async () => { + const calls: FetchCall[] = [] + const api = createApi({ + token: 'tok', + fetchImpl: async (url, init) => { + calls.push({ url: String(url), body: init?.body }) + return ok({ data: { enablePullRequestAutoMerge: { pullRequest: { number: 4 } } } }) + }, + }) + + await api.enableAutoMerge('PR_abc123') + + expect(calls).toHaveLength(1) + expect(calls[0].url).toBe('https://api.github.com/graphql') + const { query, variables } = JSON.parse(String(calls[0].body)) + expect(query).toContain('enablePullRequestAutoMerge') + expect(query).toContain('mergeMethod') + expect(variables).toEqual({ id: 'PR_abc123', mergeMethod: 'REBASE' }) + }) + + it('enableAutoMerge throws with the GraphQL error message', async () => { + const api = createApi({ + token: 'tok', + fetchImpl: async () => + ok({ + data: null, + errors: [{ message: 'auto-merge is disabled on this repository' }], + }), + }) + + await expect(api.enableAutoMerge('PR_x')).rejects.toThrow(/auto-merge is disabled/) + }) + + it('getBranchProtection returns null on 404 and normalizes an existing rule', async () => { + let calls = 0 + const api = createApi({ + token: 'tok', + fetchImpl: async () => { + calls += 1 + if (calls === 1) return ok('{"message":"Not Found"}', 404) + return ok({ + url: 'https://api.github.com/repos/fsolla/teqo/branches/main/protection', + required_status_checks: { + strict: false, + checks: [{ context: 'CI (PR) / checks', app_id: null }], + contexts: ['CI (PR) / checks'], + }, + enforce_admins: { enabled: true, url: '…' }, + required_pull_request_reviews: null, + }) + }, + }) + + expect(await api.getBranchProtection('main')).toBeNull() + + const rule = await api.getBranchProtection('main') + expect(rule).toEqual({ + required_status_checks: { + strict: false, + contexts: ['CI (PR) / checks'], + }, + enforce_admins: true, + required_pull_request_reviews: null, + }) + }) + + it('updateBranchProtection PUTs the full desired rule', async () => { + const calls: FetchCall[] = [] + const api = createApi({ + token: 'tok', + fetchImpl: async (url, init) => { + calls.push({ url: String(url), method: init?.method }) + return ok(null) + }, + }) + + await api.updateBranchProtection({ enforce_admins: true }, 'main') + + expect(calls[0].url).toBe('https://api.github.com/repos/fsolla/teqo/branches/main/protection') + expect(calls[0].method).toBe('PUT') + }) + + it('throws with the API error body on non-2xx', async () => { + let calls = 0 + const api = createApi({ + token: 'tok', + retries: 0, + fetchImpl: async () => { + calls += 1 + return ok('{"message":"Bad credentials"}', 401) + }, + }) + + await expect(api.getPullRequest(1)).rejects.toThrow(/401/) + await expect(api.getPullRequest(1)).rejects.toThrow(/Bad credentials/) + expect(calls).toBe(2) + }) +}) diff --git a/tests/unit/githubBranchProtection.unit.spec.ts b/tests/unit/githubBranchProtection.unit.spec.ts new file mode 100644 index 00000000..1c446b9e --- /dev/null +++ b/tests/unit/githubBranchProtection.unit.spec.ts @@ -0,0 +1,88 @@ +import { describe, expect, it } from 'vitest' + +import { + DESIRED_RULE, + REQUIRED_CHECK_CONTEXT, + planBranchProtectionRule, + ruleMatches, +} from '../../scripts/lib/github-branch-protection.mjs' + +const compliant = { + required_status_checks: { strict: false, contexts: [REQUIRED_CHECK_CONTEXT] }, + enforce_admins: true, + required_pull_request_reviews: null, +} + +describe('github branch-protection rule planning (OPS71)', () => { + it('plans create when no rule exists', () => { + expect(planBranchProtectionRule(null).action).toBe('create') + }) + + it('plans noop when the rule already matches', () => { + expect(planBranchProtectionRule(compliant).action).toBe('noop') + expect(ruleMatches(compliant)).toBe(true) + }) + + it('plans update when enforce_admins is off (admin bypass = red-CI merge path)', () => { + const drift = { ...compliant, enforce_admins: false } + expect(planBranchProtectionRule(drift).action).toBe('update') + expect(ruleMatches(drift)).toBe(false) + }) + + it('plans update when the required check context drifts', () => { + const drift = { + ...compliant, + required_status_checks: { strict: false, contexts: ['CI (PR) / checks (pull_request)'] }, + } + expect(planBranchProtectionRule(drift).action).toBe('update') + }) + + it('plans update when a second check is required', () => { + const extra = { + ...compliant, + required_status_checks: { + strict: false, + contexts: [REQUIRED_CHECK_CONTEXT, 'migration-lock'], + }, + } + expect(planBranchProtectionRule(extra).action).toBe('update') + }) + + it('plans update when strict becomes true', () => { + const drift = { + ...compliant, + required_status_checks: { strict: true, contexts: [REQUIRED_CHECK_CONTEXT] }, + } + expect(planBranchProtectionRule(drift).action).toBe('update') + }) + + it('plans update when pull request reviews are required (blocks auto-merge)', () => { + const drift = { + ...compliant, + required_pull_request_reviews: { required_approving_review_count: 1 }, + } + expect(planBranchProtectionRule(drift).action).toBe('update') + }) + + it('plans update when status checks are missing entirely', () => { + const drift = { ...compliant, required_status_checks: null } + expect(planBranchProtectionRule(drift).action).toBe('update') + }) + + it('compares contexts as a set (order does not matter)', () => { + const existing = { + ...compliant, + required_status_checks: { strict: false, contexts: [REQUIRED_CHECK_CONTEXT] }, + } + expect(ruleMatches(existing)).toBe(true) + }) + + it('the desired rule names exactly the check-run a single `checks` job posts', () => { + // GitHub check-run naming: <workflow name> / <job name>. The ci-pr.yml + // workflow is named `CI (PR)` and its single job is `checks` (OPS62) — + // the required check literal must match that exact check-run. + const check = DESIRED_RULE.required_status_checks.checks[0] + expect(check.context).toBe('CI (PR) / checks') + expect(DESIRED_RULE.required_status_checks.checks).toHaveLength(1) + }) +}) diff --git a/tests/unit/githubPrFlow.unit.spec.ts b/tests/unit/githubPrFlow.unit.spec.ts new file mode 100644 index 00000000..8e0abf35 --- /dev/null +++ b/tests/unit/githubPrFlow.unit.spec.ts @@ -0,0 +1,78 @@ +import { describe, expect, it } from 'vitest' + +import { + CURSOR_HEAD_PREFIX, + decideAutomergeAction, + isCursorHead, +} from '../../scripts/lib/github-pr-flow.mjs' + +const pr = (overrides: Record<string, unknown> = {}) => ({ + number: 4, + title: 't', + body: '', + state: 'OPEN', + merged: false, + draft: false, + mergeable: true, + nodeId: 'PR_x', + head: { ref: 'OPS71-x', sha: 'abc' }, + base: { ref: 'main' }, + ...overrides, +}) + +describe('github-pr-flow automerge decision (OPS71)', () => { + it('skips a null PR', () => { + expect(decideAutomergeAction(null).action).toBe('skip') + }) + + it('skips an already merged PR (idempotent)', () => { + expect(decideAutomergeAction(pr({ merged: true, state: 'CLOSED' })).action).toBe('skip') + }) + + it('skips a closed PR without merge', () => { + expect(decideAutomergeAction(pr({ state: 'CLOSED' })).action).toBe('skip') + }) + + it('skips a PR whose base is not main', () => { + expect(decideAutomergeAction(pr({ base: { ref: 'stage' } })).action).toBe('skip') + }) + + it('enables auto-merge on a ready PR to main', () => { + const verdict = decideAutomergeAction(pr()) + expect(verdict.action).toBe('enable-auto-merge') + expect(verdict.reason).toBe('ready') + }) + + it('marks a cursor/* draft ready (OPS57 pool flow)', () => { + const verdict = decideAutomergeAction( + pr({ draft: true, head: { ref: `${CURSOR_HEAD_PREFIX}abc-123`, sha: 'abc' } }), + ) + expect(verdict.action).toBe('mark-ready') + }) + + it('skips any non-cursor/* draft — the actor veto (OPS57)', () => { + const verdict = decideAutomergeAction( + pr({ draft: true, head: { ref: 'plans/ops71-x', sha: 'abc' } }), + ) + expect(verdict.action).toBe('skip') + expect(verdict.reason).toBe('draft-veto') + }) + + it('isCursorHead only matches the cursor/ prefix', () => { + expect(isCursorHead('cursor/abc-123')).toBe(true) + expect(isCursorHead('OPS71-x')).toBe(false) + expect(isCursorHead('')).toBe(false) + expect(isCursorHead(undefined)).toBe(false) + }) + + it('the merge contract has no poll path: ready always arms native auto-merge', () => { + // OPS64 pin, GitHub shape: the Forgejo rollup-lie bug is structural here + // (single job → one honest check-run), and the server only merges with + // required checks green — so the decision surface is exactly this. + const actions = [ + decideAutomergeAction(pr()).action, + decideAutomergeAction(pr({ draft: true, head: { ref: 'cursor/x', sha: 'a' } })).action, + ] + expect(actions).toEqual(['enable-auto-merge', 'mark-ready']) + }) +}) -- 2.45.2 From 4bf6086caa8f509f36f6f22a3bb9988024eb885b Mon Sep 17 00:00:00 2001 From: Francisco Solla <fsolla@pm.me> Date: Wed, 19 Aug 2026 18:14:05 -0300 Subject: [PATCH 02/37] fix(OPS71): parse de --body-file no github-pr.mjs --- scripts/github-pr.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/github-pr.mjs b/scripts/github-pr.mjs index fbbb7b0d..fef6d39f 100644 --- a/scripts/github-pr.mjs +++ b/scripts/github-pr.mjs @@ -40,10 +40,10 @@ if (!head || !title) { } let body = flags.body -if (flags.bodyFile) { +if (flags['body-file']) { try { const { readFileSync } = await import('node:fs') - body = readFileSync(flags.bodyFile, 'utf8') + body = readFileSync(flags['body-file'], 'utf8') } catch (error) { console.error(`[github-pr] não consegui ler --body-file: ${error.message}`) process.exit(1) -- 2.45.2 From fcfc9b22d02e0f73630f34a040ae5394739fe6cf Mon Sep 17 00:00:00 2001 From: Francisco Solla <fsolla@pm.me> Date: Wed, 19 Aug 2026 18:18:04 -0300 Subject: [PATCH 03/37] =?UTF-8?q?fix(OPS71):=20GITHUB=5FTOKEN=20expl=C3=AD?= =?UTF-8?q?cito=20no=20safety=20net=20via=20github.token?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/agent-pr-ready-automerge.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/agent-pr-ready-automerge.yml b/.github/workflows/agent-pr-ready-automerge.yml index ece4c3b2..001c7677 100644 --- a/.github/workflows/agent-pr-ready-automerge.yml +++ b/.github/workflows/agent-pr-ready-automerge.yml @@ -49,4 +49,9 @@ jobs: node-version: 24 package-manager-cache: false - name: Mark Ready and arm auto-merge + env: + # Explicit `github.token` — the built-in GITHUB_TOKEN env is not + # guaranteed to be injected on every event path; passing it via the + # documented context is the robust form. + GITHUB_TOKEN: ${{ github.token }} run: node scripts/github-pr-automerge.mjs --pr "${{ github.event.pull_request.number }}" -- 2.45.2 From 8820a4427fd68b05e8c797508ac9adc4fb9bfe25 Mon Sep 17 00:00:00 2001 From: Francisco Solla <fsolla@pm.me> Date: Wed, 19 Aug 2026 18:27:34 -0300 Subject: [PATCH 04/37] =?UTF-8?q?fix(OPS71):=20pins=20do=20forgejoApi=20de?= =?UTF-8?q?termin=C3=ADsticos=20sob=20GITHUB=5FSERVER=5FURL=20do=20GitHub?= =?UTF-8?q?=20Actions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/unit/forgejoApi.unit.spec.ts | 40 ++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/tests/unit/forgejoApi.unit.spec.ts b/tests/unit/forgejoApi.unit.spec.ts index e8d0c70b..57615c82 100644 --- a/tests/unit/forgejoApi.unit.spec.ts +++ b/tests/unit/forgejoApi.unit.spec.ts @@ -39,18 +39,32 @@ describe('forgejo-api', () => { }) it('defaults the base URL to git.solla.dev with the default repo path', async () => { - const calls: FetchCall[] = [] - const api = createApi({ - token: 'tok', - fetchImpl: async (url) => { - calls.push({ url: String(url) }) - return ok([{ number: 1, title: '', body: '', state: 'open', created_at: '', labels: [] }]) - }, - }) + // OPS71: the CI now runs on GitHub Actions, where GITHUB_SERVER_URL is + // set (https://github.com) — forgejo-api's env chain would resolve a + // different base. Pin the fallback default by isolating the env vars. + const savedApi = process.env.FORGEJO_API_URL + const savedServer = process.env.GITHUB_SERVER_URL + delete process.env.FORGEJO_API_URL + delete process.env.GITHUB_SERVER_URL + try { + const calls: FetchCall[] = [] + const api = createApi({ + token: 'tok', + fetchImpl: async (url) => { + calls.push({ url: String(url) }) + return ok([{ number: 1, title: '', body: '', state: 'open', created_at: '', labels: [] }]) + }, + }) - await api.listIssues() + await api.listIssues() - expect(calls[0].url).toContain('https://git.solla.dev/api/v1/repos/fsolla/teqo/issues?') + expect(calls[0].url).toContain('https://git.solla.dev/api/v1/repos/fsolla/teqo/issues?') + } finally { + if (savedApi) process.env.FORGEJO_API_URL = savedApi + else delete process.env.FORGEJO_API_URL + if (savedServer) process.env.GITHUB_SERVER_URL = savedServer + else delete process.env.GITHUB_SERVER_URL + } }) it('normalizes state and labels to the gh-flavored contract', async () => { @@ -100,6 +114,9 @@ describe('forgejo-api', () => { it('setLabels removes by id and adds by name', async () => { const calls: FetchCall[] = [] const api = createApi({ + // OPS71: explicit base — the GitHub Actions CI sets GITHUB_SERVER_URL, + // which would change the env-resolved base and break the URL pins. + base: 'https://git.solla.dev/api/v1', token: 'tok', fetchImpl: async (url, init) => { calls.push({ url: String(url), method: init?.method, body: init?.body }) @@ -440,6 +457,9 @@ describe('forgejo-api', () => { const calls: string[] = [] let poll = 0 const api = createApi({ + // OPS71: explicit base — the GitHub Actions CI sets GITHUB_SERVER_URL, + // which would change the env-resolved base and break the URL pins. + base: 'https://git.solla.dev/api/v1', token: 'tok', fetchImpl: async (url, init) => { calls.push(`${init?.method ?? 'GET'} ${url}`) -- 2.45.2 From 5ec5368ef68440702dfefed753d119329059e9e3 Mon Sep 17 00:00:00 2001 From: Francisco Solla <fsolla@pm.me> Date: Wed, 19 Aug 2026 18:44:40 -0300 Subject: [PATCH 05/37] diag(OPS71): DNS do service postgres-int no GitHub Actions --- .github/workflows/ci-pr.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/ci-pr.yml b/.github/workflows/ci-pr.yml index 6a049527..3838b057 100644 --- a/.github/workflows/ci-pr.yml +++ b/.github/workflows/ci-pr.yml @@ -152,6 +152,11 @@ jobs: # must win through the .env.test.local layer (same mechanism # `pnpm worktree next` uses). OPS50. echo "DATABASE_URL=postgresql://teqo:teqo@postgres-int:5432/teqo_test" > .env.test.local + - name: Debug service DNS (temporary diagnostic) + run: | + getent hosts postgres-int || echo "getent postgres-int: unresolved" + getent hosts postgres-build || echo "getent postgres-build: unresolved" + node -e "require('node:dns').lookup('postgres-int', (e, a) => console.log('node lookup postgres-int:', e ? e.code : a))" - name: Migrate (int database) run: pnpm migrate - name: Seed minimal (int database) -- 2.45.2 From d612dce6bb9e4041e9c05f78140b7e8982cd5f6f Mon Sep 17 00:00:00 2001 From: Francisco Solla <fsolla@pm.me> Date: Wed, 19 Aug 2026 18:53:05 -0300 Subject: [PATCH 06/37] =?UTF-8?q?fix(OPS71):=20services=20Postgres=20por?= =?UTF-8?q?=20porta=20publicada=20no=20localhost=20(jobs=20hosted=20rodam?= =?UTF-8?q?=20na=20VM,=20n=C3=A3o=20na=20rede=20do=20job)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci-pr.yml | 33 +++++++++++++++------------------ .github/workflows/deploy.yml | 19 ++++++++++++------- 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/.github/workflows/ci-pr.yml b/.github/workflows/ci-pr.yml index 3838b057..b8849ca6 100644 --- a/.github/workflows/ci-pr.yml +++ b/.github/workflows/ci-pr.yml @@ -25,10 +25,12 @@ # a fork PR would burn hosted minutes running arbitrary code. Same guard class # as the RCE guard on the post-merge workflows. # -# Postgres services live on the job network and are reached by NAME -# (postgres-int / postgres-build on 5432) — no host publish, so concurrent -# runs never collide on host ports. Two isolated services keep e2e from -# inheriting int fixture residue. +# Postgres services (OPS71 — GitHub hosted): jobs run directly on the runner +# VM (NOT inside the job-container network of the Forgejo era), so services +# are reached at localhost on PUBLISHED host ports. Each hosted run is its own +# VM, so fixed ports never collide across runs. Two isolated services — int +# on 5432 and build+e2e on 5433 — keep e2e from inheriting int fixture +# residue. name: CI (PR) on: @@ -52,16 +54,14 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 50 services: - # Services are reached by NAME on the job network (no host publish): - # concurrent runs never collide on host ports, which the single - # long-lived job would hold for the whole run. Two isolated services — - # int and build+e2e — keep e2e from inheriting int fixture residue. postgres-int: image: postgres:17-alpine env: POSTGRES_USER: teqo POSTGRES_PASSWORD: teqo POSTGRES_DB: teqo_test + ports: + - 5432:5432 options: >- --health-cmd "pg_isready -U teqo" --health-interval 5s @@ -73,6 +73,8 @@ jobs: POSTGRES_USER: teqo POSTGRES_PASSWORD: teqo POSTGRES_DB: teqo_test + ports: + - 5433:5432 options: >- --health-cmd "pg_isready -U teqo" --health-interval 5s @@ -147,16 +149,11 @@ jobs: - name: Prepare database URL (int service) run: | set -euo pipefail - echo "DATABASE_URL=postgresql://teqo:teqo@postgres-int:5432/teqo_test" >> "$GITHUB_ENV" + echo "DATABASE_URL=postgresql://teqo:teqo@localhost:5432/teqo_test" >> "$GITHUB_ENV" # vitest re-loads .env.test over the process env, so the service URL # must win through the .env.test.local layer (same mechanism - # `pnpm worktree next` uses). OPS50. - echo "DATABASE_URL=postgresql://teqo:teqo@postgres-int:5432/teqo_test" > .env.test.local - - name: Debug service DNS (temporary diagnostic) - run: | - getent hosts postgres-int || echo "getent postgres-int: unresolved" - getent hosts postgres-build || echo "getent postgres-build: unresolved" - node -e "require('node:dns').lookup('postgres-int', (e, a) => console.log('node lookup postgres-int:', e ? e.code : a))" + # `pnpm worktree next` uses). + echo "DATABASE_URL=postgresql://teqo:teqo@localhost:5432/teqo_test" > .env.test.local - name: Migrate (int database) run: pnpm migrate - name: Seed minimal (int database) @@ -181,8 +178,8 @@ jobs: if: steps.scope.outputs.build_mode != 'none' || steps.scope.outputs.e2e_mode != 'none' run: | set -euo pipefail - echo "DATABASE_URL=postgresql://teqo:teqo@postgres-build:5432/teqo_test" >> "$GITHUB_ENV" - echo "DATABASE_URL=postgresql://teqo:teqo@postgres-build:5432/teqo_test" > .env.test.local + echo "DATABASE_URL=postgresql://teqo:teqo@localhost:5433/teqo_test" >> "$GITHUB_ENV" + echo "DATABASE_URL=postgresql://teqo:teqo@localhost:5433/teqo_test" > .env.test.local - name: Migrate (build/e2e database) if: steps.scope.outputs.build_mode != 'none' || steps.scope.outputs.e2e_mode != 'none' run: pnpm migrate diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index c6f4961b..5463c715 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -41,15 +41,18 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 50 services: - # Services are reached by NAME on the job network (no host publish). - # Two isolated services — int and build+e2e — keep e2e from inheriting - # int fixture residue. + # OPS71 — GitHub hosted: jobs run on the runner VM, so services are + # reached at localhost on PUBLISHED host ports (fixed — each run is its + # own VM). Two isolated services — int on 5432, build+e2e on 5433 — + # keep e2e from inheriting int fixture residue. postgres-int: image: postgres:17-alpine env: POSTGRES_USER: teqo POSTGRES_PASSWORD: teqo POSTGRES_DB: teqo_test + ports: + - 5432:5432 options: >- --health-cmd "pg_isready -U teqo" --health-interval 5s @@ -61,6 +64,8 @@ jobs: POSTGRES_USER: teqo POSTGRES_PASSWORD: teqo POSTGRES_DB: teqo_test + ports: + - 5433:5432 options: >- --health-cmd "pg_isready -U teqo" --health-interval 5s @@ -95,11 +100,11 @@ jobs: - name: Prepare database URL (int service) run: | set -euo pipefail - echo "DATABASE_URL=postgresql://teqo:teqo@postgres-int:5432/teqo_test" >> "$GITHUB_ENV" + echo "DATABASE_URL=postgresql://teqo:teqo@localhost:5432/teqo_test" >> "$GITHUB_ENV" # vitest re-loads .env.test over the process env, so the service URL # must win through the .env.test.local layer (same mechanism # `pnpm worktree next` uses). - echo "DATABASE_URL=postgresql://teqo:teqo@postgres-int:5432/teqo_test" > .env.test.local + echo "DATABASE_URL=postgresql://teqo:teqo@localhost:5432/teqo_test" > .env.test.local - name: Migrate (int database) run: pnpm migrate - name: Seed minimal (int database) @@ -115,8 +120,8 @@ jobs: - name: Prepare database URL (build/e2e service) run: | set -euo pipefail - echo "DATABASE_URL=postgresql://teqo:teqo@postgres-build:5432/teqo_test" >> "$GITHUB_ENV" - echo "DATABASE_URL=postgresql://teqo:teqo@postgres-build:5432/teqo_test" > .env.test.local + echo "DATABASE_URL=postgresql://teqo:teqo@localhost:5433/teqo_test" >> "$GITHUB_ENV" + echo "DATABASE_URL=postgresql://teqo:teqo@localhost:5433/teqo_test" > .env.test.local - name: Migrate (build/e2e database) run: pnpm migrate - name: Seed minimal (build/e2e database) -- 2.45.2 From 29ad4ba3de319a177862c8e342061e08c23f2c9a Mon Sep 17 00:00:00 2001 From: Francisco Solla <fsolla@pm.me> Date: Wed, 19 Aug 2026 19:20:11 -0300 Subject: [PATCH 07/37] =?UTF-8?q?fix(OPS71):=20FORGEJO=5FAPI=5FURL=20expl?= =?UTF-8?q?=C3=ADcito=20nos=20flips=20=E2=80=94=20GITHUB=5FSERVER=5FURL=20?= =?UTF-8?q?do=20Actions=20resolvia=20base=20errado=20(410)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/issue-done-on-main-merge.yml | 3 +++ .github/workflows/plan-issue-ready-on-main-merge.yml | 3 +++ 2 files changed, 6 insertions(+) diff --git a/.github/workflows/issue-done-on-main-merge.yml b/.github/workflows/issue-done-on-main-merge.yml index 989caed4..578501ff 100644 --- a/.github/workflows/issue-done-on-main-merge.yml +++ b/.github/workflows/issue-done-on-main-merge.yml @@ -21,6 +21,9 @@ jobs: runs-on: ubuntu-latest env: FORGEJO_API_TOKEN: ${{ secrets.FORGEJO_API_TOKEN }} + # Explicit base: in the GitHub Actions env, GITHUB_SERVER_URL points at + # github.com and forgejo-api.mjs would resolve the wrong base (410). + FORGEJO_API_URL: https://git.solla.dev/api/v1 PR_BODY: ${{ github.event.pull_request.body }} steps: - uses: actions/checkout@v5 diff --git a/.github/workflows/plan-issue-ready-on-main-merge.yml b/.github/workflows/plan-issue-ready-on-main-merge.yml index ed3048ea..2213cf1a 100644 --- a/.github/workflows/plan-issue-ready-on-main-merge.yml +++ b/.github/workflows/plan-issue-ready-on-main-merge.yml @@ -35,6 +35,9 @@ jobs: timeout-minutes: 5 env: FORGEJO_API_TOKEN: ${{ secrets.FORGEJO_API_TOKEN }} + # Explicit base: in the GitHub Actions env, GITHUB_SERVER_URL points at + # github.com and forgejo-api.mjs would resolve the wrong base (410). + FORGEJO_API_URL: https://git.solla.dev/api/v1 PR_BODY: ${{ github.event.pull_request.body }} steps: - uses: actions/checkout@v5 -- 2.45.2 From 0901d60d72186512c2095edcae2860d61f522893 Mon Sep 17 00:00:00 2001 From: Francisco Solla <fsolla@pm.me> Date: Wed, 19 Aug 2026 19:22:53 -0300 Subject: [PATCH 08/37] fix(OPS71): literal do required check = nome do check-run (checks) + docs (pin PR #742) --- .agents/rules/agent-pr-workflow.mdc | 2 +- AGENTS.md | 2 +- docs/AGENT-OPS.md | 2 +- docs/ops/teqo-1313-deploy.md | 6 ++++-- scripts/lib/github-branch-protection.mjs | 19 +++++++++++++------ .../unit/githubBranchProtection.unit.spec.ts | 12 ++++++------ 6 files changed, 26 insertions(+), 17 deletions(-) diff --git a/.agents/rules/agent-pr-workflow.mdc b/.agents/rules/agent-pr-workflow.mdc index 6287faae..bea459f1 100644 --- a/.agents/rules/agent-pr-workflow.mdc +++ b/.agents/rules/agent-pr-workflow.mdc @@ -55,7 +55,7 @@ The safety net (`agent-pr-ready-automerge.yml`, abaixo) arms GitHub's **native a Branch protection on `main` (GitHub, applied at the OPS71 cutover via `pnpm configure:branch-protection`) requires only: -- `CI (PR) / checks` — the ci-pr single-job check-run (OPS62: one sequential job posts one honest verdict; no matrix, no shards, no rollup to lie) +- `CI (PR) / checks` — the ci-pr single-job check-run (OPS62: one sequential job posts one honest verdict; no matrix, no shards, no rollup to lie). **Literal de match na proteção: `checks`** (o GitHub casa pelo nome do check-run/job — a UI exibe `CI (PR) / checks`; pin ao vivo PR #742). OPS64 history: the Forgejo runner could report the LAST matrix shard's result as the parent's (runs 604/607/610) — that bug is gone by construction: ci-pr.yml is a SINGLE sequential job, and GitHub's native auto-merge only merges with every required check green (server-side guarantee). The safety-net CLI has no poll path to port. diff --git a/AGENTS.md b/AGENTS.md index c0cb96f5..a5a519ff 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -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). **CI/PR/deploy live on GitHub Actions (OPS71, 2026-08-19); the ISSUE TRACKER stays on the Forgejo** (`git.solla.dev/fsolla/teqo` — labels, claims, `pnpm issue`/`agent:*` and the post-merge flips all keep talking to the Forgejo API; GitHub is only the Actions host). The PR CI (`ci-pr.yml`, job único `checks` — OPS62) runs the same cascade as always (guards → lint → format → typecheck → knip → cycles → unit → int → build → e2e selected/afetado, skips via `ci-scope.mjs`); its check-run `CI (PR) / checks` is the required check of `main` and the gate of the **native auto-merge** (`agent-pr-ready-automerge.yml` → `scripts/github-pr-automerge.mjs`, GraphQL `enablePullRequestAutoMerge`, rebase — the server only merges with the required check green). **There is NO main verifier (`ci.yml`) anymore**: publishing is a **manual `workflow_dispatch`** (`.github/workflows/deploy.yml`) with two jobs — `verify` (hosted `ubuntu-latest`, suíte **full** incl. e2e full) → `deploy` (`needs: [verify]`, `runs-on: [self-hosted, homeserver]`): the GitHub self-hosted runner ON the homeserver executes `scripts/deploy-homeserver.sh` **locally** (no SSH; outbound-only runner, works behind the tunnel; the hosted job never touches the homeserver). 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; the repo comes from `TEQO_REPO_URL` (default `https://github.com/fsolla/teqo.git`, public). `pnpm push` pushes to `origin` — **the GitHub remote** (one-time local cutover: `git remote set-url origin git@github.com:fsolla/teqo.git`; the Forgejo stays as a secondary remote and its git repo freezes at the cutover point — tracker intacto por API). The Forgejo-era files (`.forgejo/workflows/`, `forgejo-pr-automerge.mjs`, `forgejo-dispatch.mjs`, `ci-classify-production.mjs`) are preserved as rollback until the OPS71 Fase 2 removal. Runbook (rollback, falhas conhecidas, passos do cutover): `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). **CI/PR/deploy live on GitHub Actions (OPS71, 2026-08-19); the ISSUE TRACKER stays on the Forgejo** (`git.solla.dev/fsolla/teqo` — labels, claims, `pnpm issue`/`agent:*` and the post-merge flips all keep talking to the Forgejo API; GitHub is only the Actions host). The PR CI (`ci-pr.yml`, job único `checks` — OPS62) runs the same cascade as always (guards → lint → format → typecheck → knip → cycles → unit → int → build → e2e selected/afetado, skips via `ci-scope.mjs`); its check-run `CI (PR) / checks` is the required check of `main` — literal de match na proteção: `checks` (o GitHub casa pelo nome do check-run/job; a UI exibe `CI (PR) / checks` — pin ao vivo PR #742) — and the gate of the **native auto-merge** (`agent-pr-ready-automerge.yml` → `scripts/github-pr-automerge.mjs`, GraphQL `enablePullRequestAutoMerge`, rebase — the server only merges with the required check green). **There is NO main verifier (`ci.yml`) anymore**: publishing is a **manual `workflow_dispatch`** (`.github/workflows/deploy.yml`) with two jobs — `verify` (hosted `ubuntu-latest`, suíte **full** incl. e2e full) → `deploy` (`needs: [verify]`, `runs-on: [self-hosted, homeserver]`): the GitHub self-hosted runner ON the homeserver executes `scripts/deploy-homeserver.sh` **locally** (no SSH; outbound-only runner, works behind the tunnel; the hosted job never touches the homeserver). 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; the repo comes from `TEQO_REPO_URL` (default `https://github.com/fsolla/teqo.git`, public). `pnpm push` pushes to `origin` — **the GitHub remote** (one-time local cutover: `git remote set-url origin git@github.com:fsolla/teqo.git`; the Forgejo stays as a secondary remote and its git repo freezes at the cutover point — tracker intacto por API). The Forgejo-era files (`.forgejo/workflows/`, `forgejo-pr-automerge.mjs`, `forgejo-dispatch.mjs`, `ci-classify-production.mjs`) are preserved as rollback until the OPS71 Fase 2 removal. Runbook (rollback, falhas conhecidas, passos do cutover): `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. diff --git a/docs/AGENT-OPS.md b/docs/AGENT-OPS.md index a6282ab4..7aa5748d 100644 --- a/docs/AGENT-OPS.md +++ b/docs/AGENT-OPS.md @@ -94,7 +94,7 @@ Fast gate: `pnpm gate:fast`. Push: `pnpm push`. Local: `GITHUB_TOKEN` (PAT com escopo `repo`) para `node scripts/github-pr.mjs`, `pnpm configure:branch-protection` e qualquer script GitHub — o push SSH usa a chave `~/.ssh/id_ed25519` registrada no GitHub. 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 GitHub. `POOL_GITHUB_TOKEN` é **legado** (era da transição GitHub pré-OPS50). -Branch protection de `main` no **GitHub** (aplicada no cutover do OPS71, via `pnpm configure:branch-protection`): required check `CI (PR) / checks` (o check-run do `ci-pr.yml` — job único, veredito honesto da cascata inteira), `strict=false`, 0 reviews, `enforce_admins: true` (nem admin mergea com CI vermelho — mesmo invariante do rule-based Forgejo). O auto-merge nativo espera esse mesmo check antes de mergear; a regra no servidor é o gate real de qualquer caminho de merge, inclusive API manual. Reaplicar/consertar drift: `pnpm configure:branch-protection` (idempotente). +Branch protection de `main` no **GitHub** (aplicada no cutover do OPS71, via `pnpm configure:branch-protection`): required check `CI (PR) / checks` (a UI exibe workflow/job; o **literal de match é `checks`** — o GitHub casa pelo nome do check-run — pin ao vivo PR #742), `strict=false`, 0 reviews, `enforce_admins: true` (nem admin mergea com CI vermelho — mesmo invariante do rule-based Forgejo). O auto-merge nativo espera esse mesmo check antes de mergear; a regra no servidor é o gate real de qualquer caminho de merge, inclusive API manual. Reaplicar/consertar drift: `pnpm configure:branch-protection` (idempotente). Deploy (OPS53 + OPS71): **manual** via `workflow_dispatch` no `deploy.yml` — o job `verify` (hosted, suíte full incl. e2e full) roda **antes** do job `deploy` (`needs: [verify]`), que executa `scripts/deploy-homeserver.sh <sha>` no runner self-hosted do GitHub **no homeserver** (conecta outbound ao GitHub — funciona atrás do Cloudflare tunnel; o hosted nunca toca o homeserver; o self-hosted não conta minutos hosted). O script: HEAD guard (`TEQO_REPO_URL` — default `https://github.com/fsolla/teqo.git`, público) → flock → guard "already deployed" (revision do container) → build do migrator (BuildKit, secrets de `~/stack/teqo-1313.env`) → push/tag em `localhost:5000` → swap dos tags no compose (backup) → **migrations** (`teqo-1313-migrate` — antes do build do runner, OPS66) → build do runner (contra o banco JÁ migrado) → rollout → healthcheck → smoke. Falha = job vermelho; nada é publicado pela metade. Runbook (rollback, falhas conhecidas): `docs/ops/teqo-1313-deploy.md`. O deploy Vercel foi removido no OPS50; o verificador automático de main foi eliminado no OPS71 — se um dia o merge em main quiser rede de regressão, o `ci.yml` volta com 1 linha de trigger (sem deploy). diff --git a/docs/ops/teqo-1313-deploy.md b/docs/ops/teqo-1313-deploy.md index 6595fd27..91649d1f 100644 --- a/docs/ops/teqo-1313-deploy.md +++ b/docs/ops/teqo-1313-deploy.md @@ -70,8 +70,10 @@ secrets de integração: `FORGEJO_API_TOKEN` (flips pós-merge) e 3. PAT local: criar token GitHub com escopo `repo` e exportar `GITHUB_TOKEN` (para `node scripts/github-pr.mjs` e `pnpm configure:branch-protection`). 4. `GITHUB_TOKEN=… pnpm configure:branch-protection` — required check - `CI (PR) / checks`, 0 reviews, `enforce_admins: true`. **Antes do primeiro - push** (senão o PR mergearia sem required check). + `CI (PR) / checks` (literal de match: `checks` — o GitHub casa pelo nome do + check-run; a UI exibe workflow/job; pin PR #742), 0 reviews, + `enforce_admins: true`. **Antes do primeiro push** (senão o PR mergearia + sem required check). 5. **Desligar o runner do Forgejo** na workstation (ex.: `systemctl --user stop forgejo-runner`) — após o primeiro PR GitHub validado; para o schedule do `ci.yml` antigo. diff --git a/scripts/lib/github-branch-protection.mjs b/scripts/lib/github-branch-protection.mjs index c4a4b13f..aba11f21 100644 --- a/scripts/lib/github-branch-protection.mjs +++ b/scripts/lib/github-branch-protection.mjs @@ -1,18 +1,25 @@ /** * Pure decision for the GitHub `main` branch protection rule (OPS71). * - * The desired rule is the repo contract: main requires the `CI (PR) / checks` - * check-run (the ci-pr single-job cascade — OPS62) as the only status check - * (strict=false, 0 reviews) and `enforce_admins: true` so even repo admins - * cannot merge with a red required check (the rule-based protection of the - * Forgejo era applied to everyone — preserved). + * The desired rule is the repo contract: main requires the ci-pr cascade + * check-run (OPS62) as the only status check (strict=false, 0 reviews) and + * `enforce_admins: true` so even repo admins cannot merge with a red required + * check (the rule-based protection of the Forgejo era applied to everyone — + * preserved). * * The auto-merge safety net never merges on red CI by construction (GitHub's * server-side guarantee), but the branch protection rule is the final defense * against every other merge path (manual API merges included). + * + * Context literal (verified live on PR #742, 2026-08-19): GitHub's + * required-check matching uses the CHECK-RUN NAME — the bare JOB name + * (`checks`), NOT the UI display `<workflow name> / <job name>` + * (`CI (PR) / checks`). The latter never matches and leaves the PR + * mergeable_state "blocked" forever. The UI still shows + * `CI (PR) / checks`; the rule literal is `checks`. */ -export const REQUIRED_CHECK_CONTEXT = 'CI (PR) / checks' +export const REQUIRED_CHECK_CONTEXT = 'checks' /** * GitHub PUT /branches/{branch}/protection replace-semantics payload. Only diff --git a/tests/unit/githubBranchProtection.unit.spec.ts b/tests/unit/githubBranchProtection.unit.spec.ts index 1c446b9e..d9803035 100644 --- a/tests/unit/githubBranchProtection.unit.spec.ts +++ b/tests/unit/githubBranchProtection.unit.spec.ts @@ -32,7 +32,7 @@ describe('github branch-protection rule planning (OPS71)', () => { it('plans update when the required check context drifts', () => { const drift = { ...compliant, - required_status_checks: { strict: false, contexts: ['CI (PR) / checks (pull_request)'] }, + required_status_checks: { strict: false, contexts: ['CI (PR) / checks'] }, } expect(planBranchProtectionRule(drift).action).toBe('update') }) @@ -77,12 +77,12 @@ describe('github branch-protection rule planning (OPS71)', () => { expect(ruleMatches(existing)).toBe(true) }) - it('the desired rule names exactly the check-run a single `checks` job posts', () => { - // GitHub check-run naming: <workflow name> / <job name>. The ci-pr.yml - // workflow is named `CI (PR)` and its single job is `checks` (OPS62) — - // the required check literal must match that exact check-run. + it('the desired rule uses the check-run literal GitHub matches (job name, live pin)', () => { + // Verified on PR #742 (OPS71): required-check matching uses the CHECK-RUN + // name (`checks`), not the UI display `CI (PR) / checks` — the + // workflow-prefixed literal never matches and leaves the PR blocked. const check = DESIRED_RULE.required_status_checks.checks[0] - expect(check.context).toBe('CI (PR) / checks') + expect(check.context).toBe('checks') expect(DESIRED_RULE.required_status_checks.checks).toHaveLength(1) }) }) -- 2.45.2 From f5862c9ba36c492cb2bb526e5278cadba9c193b8 Mon Sep 17 00:00:00 2001 From: Francisco Solla <fsolla@pm.me> Date: Wed, 19 Aug 2026 19:39:40 -0300 Subject: [PATCH 09/37] =?UTF-8?q?fix(OPS71):=20ciClassifyProduction=20herm?= =?UTF-8?q?=C3=A9tico=20=E2=80=94=20env=20GIT=5F*=20limpa=20+=20assert=20d?= =?UTF-8?q?o=20scratch=20repo=20(n=C3=A3o=20polui=20o=20worktree=20externo?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/unit/ciClassifyProduction.unit.spec.ts | 43 ++++++++++++++++---- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/tests/unit/ciClassifyProduction.unit.spec.ts b/tests/unit/ciClassifyProduction.unit.spec.ts index 7687a6b4..6e5b865c 100644 --- a/tests/unit/ciClassifyProduction.unit.spec.ts +++ b/tests/unit/ciClassifyProduction.unit.spec.ts @@ -15,6 +15,19 @@ const repoRoot = join(fileURLToPath(new URL('.', import.meta.url)), '../..') const cliPath = join(repoRoot, 'scripts/ci-classify-production.mjs') const realRules = parseDockerignore(readFileSync(join(repoRoot, '.dockerignore'), 'utf8')) +// OPS71 (fix 2026-08-19): git hooks (husky pre-push) export GIT_DIR/GIT_WORK_TREE +// — inherited here, they redirect ANY git invocation (scratch repo setup AND +// the CLI's `git diff`) to the OUTER repo of the worktree where the suite +// runs, committing into the branch of the cwd worktree (observed: OPS71 and +// S10 worktrees polluted with the scratch commits). Strip them everywhere. +const strippedEnv = { + ...process.env, + GIT_DIR: undefined, + GIT_WORK_TREE: undefined, + GIT_INDEX_FILE: undefined, + GIT_CEILING_DIRECTORIES: undefined, +} + let fixturesDir: string let filesFrom: string let gitRepo: string @@ -24,11 +37,24 @@ beforeAll(() => { fixturesDir = mkdtempSync(join(tmpdir(), 'ci-classify-production-')) filesFrom = join(fixturesDir, 'changed.txt') gitRepo = join(fixturesDir, 'repo') - execFileSync('git', ['init', '-q', '-b', 'main', gitRepo]) + // Hermetic git: every command below targets the scratch repo and ONLY it. + // With the env stripped, a stray resolution FAILS the rev-parse assert + // below instead of polluting the outer repo. + const runGit = (args: string[]) => execFileSync('git', args, { env: strippedEnv }) + runGit(['init', '-q', '-b', 'main', gitRepo]) + const topLevel = execFileSync('git', ['-C', gitRepo, 'rev-parse', '--show-toplevel'], { + encoding: 'utf8', + env: strippedEnv, + }).trim() + if (topLevel !== gitRepo) { + throw new Error( + `scratch git repo inesperado: --show-toplevel=${topLevel} (esperado ${gitRepo}) — abortando para não poluir o repo externo`, + ) + } writeFileSync(join(gitRepo, '.dockerignore'), 'docs\n') writeFileSync(join(gitRepo, 'README.md'), 'a\n') const commit = (message: string) => - execFileSync('git', [ + runGit([ '-C', gitRepo, '-c', @@ -40,24 +66,27 @@ beforeAll(() => { '-m', message, ]) - execFileSync('git', ['-C', gitRepo, 'add', '-A']) + runGit(['-C', gitRepo, 'add', '-A']) commit('base') const baseSha = execFileSync('git', ['-C', gitRepo, 'rev-parse', 'HEAD'], { encoding: 'utf8', + env: strippedEnv, }).trim() execFileSync('mkdir', ['-p', join(gitRepo, 'src'), join(gitRepo, 'docs')]) writeFileSync(join(gitRepo, 'src', 'a.ts'), 'x\n') writeFileSync(join(gitRepo, 'docs', 'x.md'), 'x\n') - execFileSync('git', ['-C', gitRepo, 'add', '-A']) + runGit(['-C', gitRepo, 'add', '-A']) commit('prod change') const prodSha = execFileSync('git', ['-C', gitRepo, 'rev-parse', 'HEAD'], { encoding: 'utf8', + env: strippedEnv, }).trim() writeFileSync(join(gitRepo, 'docs', 'y.md'), 'x\n') - execFileSync('git', ['-C', gitRepo, 'add', '-A']) + runGit(['-C', gitRepo, 'add', '-A']) commit('docs only') const docsSha = execFileSync('git', ['-C', gitRepo, 'rev-parse', 'HEAD'], { encoding: 'utf8', + env: strippedEnv, }).trim() fixtureShas = { baseSha, prodSha, docsSha } }) @@ -69,7 +98,7 @@ afterAll(() => { const fixture = () => fixtureShas const runCli = (args: string[], options: { cwd?: string } = {}) => { - const env = { ...process.env, GITHUB_EVENT_NAME: 'schedule' } + const env = { ...strippedEnv, GITHUB_EVENT_NAME: 'schedule' } const result = spawnSync('node', [cliPath, ...args], { encoding: 'utf8', env, @@ -181,7 +210,7 @@ describe('ci-classify-production CLI (OPS65 gate)', () => { }) it('workflow_dispatch always runs the full pipeline', () => { - const env = { ...process.env, GITHUB_EVENT_NAME: 'workflow_dispatch' } + const env = { ...strippedEnv, GITHUB_EVENT_NAME: 'workflow_dispatch' } const result = spawnSync('node', [cliPath, '--files-from', filesFrom], { encoding: 'utf8', env, -- 2.45.2 From 21a8e39fe2e9a2ffb1709ecb20173e09711d4139 Mon Sep 17 00:00:00 2001 From: Francisco Solla <fsolla@pm.me> Date: Wed, 19 Aug 2026 20:45:12 -0300 Subject: [PATCH 10/37] =?UTF-8?q?plan(OPS73):=20deploy=20do=20fix=20OPS69?= =?UTF-8?q?=20para=20produ=C3=A7=C3=A3o=20=E2=80=94=20admin=20segue=20em?= =?UTF-8?q?=20branco=20(Related=20#114)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ops73-deploy-admin-prod-evidence.png | Bin 0 -> 2702 bytes docs/plans/ops73-deploy-admin-prod.md | 74 ++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 docs/plans/ops73-deploy-admin-prod-evidence.png create mode 100644 docs/plans/ops73-deploy-admin-prod.md diff --git a/docs/plans/ops73-deploy-admin-prod-evidence.png b/docs/plans/ops73-deploy-admin-prod-evidence.png new file mode 100644 index 0000000000000000000000000000000000000000..116eb10c7b95effc1cac0559d8ad6a7578657f63 GIT binary patch literal 2702 zcmeAS@N?(olHy`uVBq!ia0y~yV7dUrWgJXEk)H)h77Pqr&YmugAr*7pTyx}QFyLS? z+~mXbZ|kB*b!)r+-IZl%xFpTcFr$Eh!SW#kL(w5dh9@n|3@13*872txF(|0ZFgW;G zFf_~=RWKS3qv>HZUyPOyqvhmibud~jjy4ZQP%}vu*qHqPKU>EX*uG?712rd^8GIyI VwU@*ds{utAJYD@<);T3K0RZ%;k$(UH literal 0 HcmV?d00001 diff --git a/docs/plans/ops73-deploy-admin-prod.md b/docs/plans/ops73-deploy-admin-prod.md new file mode 100644 index 00000000..6a2d19b3 --- /dev/null +++ b/docs/plans/ops73-deploy-admin-prod.md @@ -0,0 +1,74 @@ +# Admin do Payload segue em branco em produção — deploy do fix OPS69 + verificação pós-deploy + +Status: rascunho +Atualizado em: 2026-08-19 +Issue: #114 +Priority: P1 +Model: composer-2.5 +Impeccable: A — sem mudança de UI (deploy do que já está em main) +Rascunho UI: N/A +Appetite: ~0,5 dia — deploy + verificação funcional; um outcome verificável +Responsável: — + +## Intenção + +O time editorial e de campanha está **sem CMS**: `/admin` em produção (jorgesolla1313.com.br) abre em branco (tela preta) — a página carrega, o shell hidrata, mas o formulário de login nunca renderiza. O bug raiz já foi diagnosticado e corrigido em `main` pelo **OPS69** (Issue #77, fechada): o `importMap` commitado ficou sem a entrada `@payloadcms/storage-s3/client#S3ClientUploadHandler` e o admin não monta as views quando o plugin `s3Storage` está ativo (envs `S3_*` de produção). O fix está em main desde `7162c65e` (2026-08-19). + +**Mas produção nunca recebeu o fix.** O container roda um build de 2026-08-18 21:49 (`e6bd1d26`), anterior ao merge: o deploy automático antigo morreu (#85 OPS70 — runs agendados skipped) e o caminho novo (dispatch manual do `deploy.yml` no GitHub Actions) depende do runner self-hosted no homeserver, que ainda não está instalado (#113 OPS71-INFRA). A verificação pós-deploy do OPS69 (aceite do próprio plano) nunca rodou. + +Verificado ao vivo em 2026-08-19: `/admin` de produção renderiza o shell vazio — **0 inputs, 0 botões, body sem texto** — mesmo sintoma do diagnóstico OPS69. `main` no GitHub hoje (`f5862c9b`) contém o fix. + +## Persona e fluxo + +- **Persona / contexto:** editor de conteúdo do mandato/campanha (staff que alimenta notícias e campanhas pelo Painel de Controle), bloqueado há ~1 dia. +- **Job principal:** abrir o admin, logar e voltar a editar publicações — sem depender de infra nova. +- **Fluxo desejado:** abre `jorgesolla1313.com.br/admin` → formulário de login aparece (não mais tela preta) → credenciais → dashboard com as coleções → consegue abrir uma coleção. +- **Anti-goals de produto:** não rediagnosticar o bug (OPS69 já fechou o diagnóstico com evidência); não reabrir a Issue #77; não entregar nenhuma mudança de código nova — só publicar o que já está aprovado em main. + +## Objetivo e aceite + +- `/admin` em produção renderiza o formulário de login para quem tem credencial (tela preta some). +- O container de produção roda uma revisão que contém o fix do importMap (`7162c65e` ou posterior — HEAD atual `f5862c9b`). +- O log do container de produção não re-emite `getFromImportMap: PayloadComponent not found in importMap` para o handler do storage. +- Um editor loga e abre uma coleção sem editar nada (smoke mínimo de leitura). +- Guardrail: nada de schema/migration/Consent/UI nesta entrega — é o deploy do que já está em `main`. + +## Dados (intenção) + +- **Vou apresentar dados?** Não — a verificação é funcional (render do login + log do container), nenhum número novo. + +## Direção no codebase (hipótese) + +- **Áreas prováveis:** `scripts/deploy-homeserver.sh` (o script de deploy — fonte da verdade do fluxo, roda no homeserver), `.github/workflows/deploy.yml` (dispatch manual `verify` → `deploy`), runbook `docs/ops/teqo-1313-deploy.md`, `src/app/(payload)/admin/importMap.js` (o fix já commitado — conferir a revision do container, não o arquivo). +- **Precedente a olhar:** OPS69 (`docs/plans/ops69-admin-branco-importmap-s3*.md`, #77) — aceite de verificação pós-deploy pendente; OPS71 (cutover do deploy) e #113 (runner); OPS66 (ordem migrate→build já resolvida no script). +- **Risco de acoplamento:** o deploy de `main` leva junto outras mudanças já aprovadas (ex.: S7, cards da home) — esperado e desejado (deploy do HEAD); o smoke do script cobre `/`, `/campanha/login`, `/admin`; rollback = restore do compose (runbook). + +## Dependências + +- Nenhuma dura. #113 (runner self-hosted) é o habilitador do caminho A, não pré-requisito — o caminho B desbloqueia sem ele. + +## Fora de escopo + +- Rediagnóstico do bug e guard de CI do importMap — #87 OPS70 já na fila (P2). +- Instalação do runner self-hosted do GitHub — #113 (Issue própria). +- Deploy contínuo automático — decisão OPS71 é deploy manual; #85 OPS70 (pipeline antigo) parece obsoleto pós-cutover — sugestão de fechamento à parte, não escopo daqui. + +## Rabbit holes de produto + +- **"A tela preta voltou → reabrir o diagnóstico."** Se alguém só completar o desejo: regressar ao OPS69. **Corte neste item:** conferir a revision do container antes de qualquer diagnóstico — a evidência (build de 2026-08-18 sem o fix, main com o fix desde 2026-08-19) já explica o sintoma. +- **"Já que vou mexer, instalo o runner/automatizo tudo."** **Corte:** #113 (runner) e #87 (guard) são Issues separadas; este item entrega admin no ar. + +## Questões em aberto (produto) + +- **Caminho do deploy?** **Opções:** A) dispatch manual do `deploy.yml` no GitHub Actions (verify full ~50 min → deploy no runner do homeserver — exige instalar o runner, #113, antes); B) executar `scripts/deploy-homeserver.sh <sha>` direto no homeserver (mesmo script idempotente que o runner rodaria; smoke + rollback documentados; não espera #113); C) instalar o runner primeiro e depois A. **Recomendação:** **B agora** — admin caído = CMS indisponível; o script é o mesmo e o runbook cobre smoke e rollback; depois, o primeiro dispatch via A valida o pipeline OPS71. _(assumido — validar com produto)_ +- **Prioridade?** **Opções:** P0 (mesma dor do incidente original) | P1 (o fix já existe em main; resta entrega + verificação). **Recomendação:** **P1** — claimável já, sem precisar de re-P0 da fila. _(assumido — validar com produto)_ +- **Quem toca o homeserver?** O agente não tem acesso ao homeserver nem ao GitHub para dispatch sem ação do operador. **Opções:** o executor prepara os comandos do runbook e o humano roda (2 passos, ~5 min) | o executor dispara via GitHub API (`GITHUB_TOKEN` disponível) quando o runner estiver em pé (#113). **Recomendação:** humana para o caminho B imediato; o agente executa o restante (conferir SHA, verificar `/admin` no browser, checar log) e registra a evidência. _(assumido — validar com produto)_ + +## Referências + +- OPS69: `docs/plans/ops69-admin-branco-importmap-s3.md` + `-impl.md`, Issue #77 (fechada — fix `7162c65e` em main) +- Runbook de deploy: `docs/ops/teqo-1313-deploy.md` (smoke, rollback, falhas conhecidas) +- OPS71 cutover: `docs/plans/ops71-ci-github-actions-tracker-forgejo.md`; runner: #113; guard de importMap: #87; pipeline antigo morto: #85 +- Evidência (gate): `docs/plans/ops73-deploy-admin-prod-evidence.png` — `/admin` de produção em 2026-08-19 (shell vazio, sem login) + +![Admin em branco em produção — 2026-08-19](ops73-deploy-admin-prod-evidence.png) -- 2.45.2 From 851ac3941b67c7e6f52df40fd2d07d6aa8a32a33 Mon Sep 17 00:00:00 2001 From: Francisco Solla <fsolla@pm.me> Date: Wed, 19 Aug 2026 20:45:45 -0300 Subject: [PATCH 11/37] =?UTF-8?q?plan(S11):=20feed=20do=20Instagram=20conf?= =?UTF-8?q?igurado=20n=C3=A3o=20aparece=20na=20home=20p=C3=BAblica=20?= =?UTF-8?q?=E2=80=94=20inten=C3=A7=C3=A3o=20+=20rascunho=20UI=20do=20paine?= =?UTF-8?q?l=20de=20status?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...parece-home-ui-draft-admin-falha-token.png | Bin 0 -> 92278 bytes ...ce-home-ui-draft-admin-nao-configurado.png | Bin 0 -> 44937 bytes ...ram-nao-aparece-home-ui-draft-admin-ok.png | Bin 0 -> 91416 bytes ...d-instagram-nao-aparece-home-ui-draft.html | 269 ++++++++++++++++++ docs/plans/feed-instagram-nao-aparece-home.md | 93 ++++++ 5 files changed, 362 insertions(+) create mode 100644 docs/plans/feed-instagram-nao-aparece-home-ui-draft-admin-falha-token.png create mode 100644 docs/plans/feed-instagram-nao-aparece-home-ui-draft-admin-nao-configurado.png create mode 100644 docs/plans/feed-instagram-nao-aparece-home-ui-draft-admin-ok.png create mode 100644 docs/plans/feed-instagram-nao-aparece-home-ui-draft.html create mode 100644 docs/plans/feed-instagram-nao-aparece-home.md diff --git a/docs/plans/feed-instagram-nao-aparece-home-ui-draft-admin-falha-token.png b/docs/plans/feed-instagram-nao-aparece-home-ui-draft-admin-falha-token.png new file mode 100644 index 0000000000000000000000000000000000000000..7ff0878d92706feaab9396262e0a683daa1b0961 GIT binary patch literal 92278 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 TXwkr%dn4&XO(5mhog)7OmN?i$ literal 0 HcmV?d00001 diff --git a/docs/plans/feed-instagram-nao-aparece-home-ui-draft-admin-nao-configurado.png b/docs/plans/feed-instagram-nao-aparece-home-ui-draft-admin-nao-configurado.png new file mode 100644 index 0000000000000000000000000000000000000000..505f5b9f38f5dc70804c99b46145fe360ceb208e GIT binary patch literal 44937 zcmc$_cU05C*EeWGlp=}((ruvB(0fr4kS-8FItWN7^b$G<hzLjxJ<@ycC4?fqm(U>~ zJrF=3l!TB)f6udL&)Gfip7%ZPp8YFxW+r#ay>n+ipL@UIA5`VZN$5zfUAsoE@cx~~ zwQILtU%PhW-klp)HNwpMQrE8Czozi+4bU@fck%9PAfki#AdcszNCery6S7`9vi>K} z1K*N_kg~-$hkniiR6_IswUg8w^EC#1wfSecX9kXMx^9p^(s=Q}^G*=y{bIf+JIiDu zJi)O2rR(wb_em2f3HwLh?Srt*4DUUnVM2z>{ubTiiaS@MU%M6{G|KX?a82*V_1phS zHMeh&{VP~S`rQIQn77!DNiuX{Oup6BexgU`zBd2*2)>}Kyi=GO{e_FJoAqzsgVRwu zlbI+p8sFNTU$c{wHNVcFr}l(nEr|RCn}B<A6}Trx^Egyv)qe?NG0J0RzlE+|gg6*W zcVP?3Se19!^i|cvf~B5`Z)o%^o`nF^3gNi~LlL(Zc1Nfu0CMZj8Cyi_Lw%+yi}+kw z*+!lIHN`_3wjD(m7Z>MZg7X`-dlS4?xbT}wG3|e+0}jo2+b!U4x_xS_BFHUCU%Oge zQf0$3Ki8GBJLXD~to+c$VsETgKejA>yRoIkYC9HFoKTGv*PE(u{%JQR0<cwm;Kj}s z5zXbL(&~p~AFi7v&F(Mw@D|1jz<Lc#O(2xbT;ypy0LXP@bF=@+2C+J0)Wi98ge>5d z8KjF^dh$<p-Pv|njxg}0J&q^bir->yBy-c~lFwXka^AF2kKxzfX)--D#L{7dECL6s znFn#luC~Gg+Xe&kc0Eo{NrQU8vs+r5tc>%Of)e4Vc8%%paKcGQj-+m9P@dPk<C-i@ zR-IohCanoHP(#~n@@K(mL{xXQoOuz87<NHpTl%Z2=ch94&o>qV?S%k#6s|ekdxZ6C zodTyMx=n3J!*})#0$kg#x4I9M5Uv#7{l7!rwC-(yb9IK9$QR|{GX{hb$;PZk%|))` z0`T5!LvF9_?0DNIXOfoaX2+BR8C=5`Zgo=8H4jh!oGq^{`=az&t~~OdUTTiOX-ciD z`VUB4c$EML*Gb!yWM!8d+V+=wa<gA&@r&K`^_509Wf!Dw#HK37S->GD#dc&WJwKvA zQix)q%2#o0*rmI?6&n<HmrVudwb{+3-iRha)zwCZspwMjVTfpsx~pocz3T+aZFif& zJ)bE3fFPT%<qyMv7P9s;k8K%h1ZE&h-Tu+`cyKXzXR&x#MM*J>Mx2qV)jl8BkJhK= zJW<6S*rkR(?cS^Irrq3A2PH5moSlT!96VDW9VjiuT6=1^?Ko_dENTi{yg4AH7BwEh z<%pSYD!R{HoJMKSAD?}+5{aJ|RvW_ec%pNgRP}Y8OXgS||5OpJZe@KNkB!=!b>7wJ zF>sLJw0f`@ROc#_PP%x88RKx{+SD8kT5h9xCp3sEnPG&MMzU+W``%BUTBX*s-`O*N zQ}nGYjU3sq{;^D>b9QS+%NJGlt}D_0UfOS_N}<B2zlQU=9{a#-OvFP~eK*i09gtPM zNaKGV2szvotj-_Sr|(QV#GER@QY@QzBBA;`(;MScKXi=l&Zbx}G&m=N1|B{4a?_n_ zubtd+5&lf8W_aE%LLL{9)E#A{naD{Z08sfhgx^^dGTSFoGTzAX72MBtnn(nRrfLIO z^Nlfv7|bUKN|Jdv<#J<+Gh!Ko<aWrQl}AXw>OI@FtTsxnXRjOc{c~!{!B{QSN-Kiy zgzkiL8PLt_u_iVt=_7siH^++zev(52ovRi_kUplmH5@2d6e2X}Z^3}zGhZM^meWl; zL{Uw!IwGcBW-X_E-sjR3K_zzv5;SKwg<3>?QDHstfReexzK=&6M50-`5iLchE&P}S zFKC8YYlZ9fKsvp$j4glZO=-MynU}-X@9halNMd-R!)22NJA|ocWBmtBQD?yr48}j; zgPLxhR%7XrN>XKv7g%lUdTP|YwgR+djObq{qu(5Nkgdxu|ElTp6m5jf(MLS9MwdX0 z?%w5cHn><1{W%r7CZehjJ0?2c#tc9}B071f3J*yUYB~xFeRQ3MJ@5Je7sq1pDJK+5 ziID0Ndb%Tg%S|u8vP?`^=omeFys_4q=u7!q6=1qsdyFHGfW6n-(ixCmp!AE%$eF^t zF;9usZyMA&KeC+YfeGM(B`vGJ705PA&?gI}pt3oe9LolOEl%H^=>6wU3YaHmx>KG5 zTF1NYf33s~7!8(4>PNFuL8vsRBg~W{7mXe5w#@}MLc=r|o2#m73ex3W!s8&3P0+%U zR##35_HZy>ahD0@<^mb6Z>U(*$#{=LLk{+JhN{>|^yyQkI3Vem0`z2GadB}3po>W& zkBN=%H0Af(;k^Y)x55I>)7=b71!sDYacbgEw{@#6UKEDI@{~a-PMBKOo;>#?@65pS zjHU6Mr^f*_$m>qw)86pvldYAVgRYyC##wi|?x3lr{vM@u4$Xny1wsRoRm$w}K1-fr zhC6U|FoMF4Oj@aSAh%#N+m-r$t$AQ~$3&*Ms<7}(hCpLuvl-2HR`Jy5xt9A|AAQ9H zj*qEq)+f9>#_uG^a;0!AeN3sbq|kz8<z%mHexoZMe=E$SluaEW=2`RAdes46VQ69D zrf!{`5#lxPZmLJ-vIg9&YrHAT2CuS|@zi)g^(oq(9QK-_C(7R1A#2*xVy8&ZJ8Rew z<<rw294%WPRuw6vAEWO{^zFUIE5ZIZh|T`(QH*-7P+(xzJ#Qn3QaV?qP67Xg!Ayor zuAMx+jmt)79ySFM>fd08ZZB}z{G<lWep}ET{9az6$ajk$z=bja9z9m0vCNL#z`jy) ziCF6viqdlue|)9twzyoSq!etGvI~toDQUi%pCWc`$yO`38;k-J+_QJGc991vtT}hA zRTK)Nw!*Ftl3QoIovI2l$`9Ic?vOS}Gk36aSXpCgIKW}RAOJ<PGvL?bXq-E88j$pZ zxB!a@o=$|e3PTIAHxM|2v(uKE8Q>iw8AY^;rU$L85H<DEj+t>QT#qeG0VA|s=5Fnj z&~&Mo+fu1+v^ZDl5I;bV`7XMMd6CTELaJ)!<e+PtzAh_@00TxB)taQh-DVKqZS&ZZ z*{Xt#H(Yt)k=c>qxWli=L?lNxZ)Dk5u(!o2i49OAK}Z`u)*6kpuywIB7*t7nmkGbU zXv~vu@%VjV$uL`ju>b5U5O6A?)+c`{6#Eg+hMrn|toc&L&3azq8Gx(UrqEJ%DpzCu z5h+TdH&<9c!Fx|pcRJ)``J=1Ht9h$ts=UfL-a=IlTS-||e^o!-O?%FQ->AKES(fZV z(v7RjsZvmVU*C*cQ&P+-Q^%L35S{Z{g*Ya@YwzwU-hB4*Apja7cHi${m#XN{Fe7pi z5!Ns5{H*Hd@XxU3<i8KB<$ZYwkVfmFnJud6sFB-Y9s;?%Sh-M(E1HM(=5UJ(3$fFS za}5bF<N6ZI7Y3q2{hCe|{9VEcr_Djlb5@4D2+@|ez7MDpx)xx5Y2_-v61?xqWz=Ch zyLy;rIvqF%66*0r$=<uc+v*#g-9stOCIc~zmCUW@)^vt?sx$LX=gV9higPsag&?N9 z)fq$;m<#4D8AT+%X-C(CN9gV;(CekD>bjjwOfN;)BY%9!kjsmgJ~K5itP@hnsC#;b z4rX+)%9MAcTUWGbzR_zeLq4gyC8(WHS6rOIq-i#^C1>Mt6t}UsyHYvo`YJrH)YY)E zZY&;6d5EsBK90R-=e-}CQ=_qyYr4a@uam8r?dE&GFSo*jRqmtrIq{HTov)4K+2Id+ z2&zepzPVV<Ops9tGf8v(uRHrmkB^^B*f99SZ=s!!dlrvq%#CE|G2M{NaQIboe|C#X zwiKyo7{*;}mNNg?g{kHnld1ch-JjeX;%4Ba?2<;J;kUVirBq{<O4yAsS`MX%{;wgu zV>ytQ8?TD{zpa6%qE6{T&14J>07Le)&kOs-8dj<);8Mk>hvTw<$HD+(_RX0F@smBS zdy%=a2xVK39^yJD0FOJAa%;wu<wUW0SUf?ZfNX-*cKqmpzFsO_mm{xbzmn2=4$Vcl zOd;nGm#sh@FG#X<cH^0gq?h{q_2;Z^%baW0-a-zMiv6Xm45UXJbwKDj<7ZdN<tI~A zFBuJSCmp4Y-GJ}5>A6#X>~_nfCSO0y41@lAth<&ot5eH{Fmdtuoevo5YqyFGPe*L* zC?Q$Y-M6<IZBh$4Ah(*5=;`Ol=;;N7E9TY0GO<><k#@E(n^rA%r3BY3=wVTes%GWO zvMxQ11(ssGk+8SaXD-fWYBc!ufngwpx5F|IrWDN}&o0+DP(+_#VHwTZXGmS5CovT> zcU```t<j|i-x%$zuDuD|5sf5u6}GIN9c(HoNO~3lp$Yq*-Cuh`qSy2q=podC*1R8& zu&lTL{uIEeFP2!OX*gAxeYG}#A(g=3+|0~E*D0c_{GRs=ZcDsyAW|$*t|hS~19!u) zD0@1-vAuNz#xS+@<Tw5C`bPQ9WJ_TOiTOQMHZM1~=e%`R^Fz}vWO@=^1Knvh@d*P) zqXUwQ!9D4iUr>?w{wh*=0NbKWqB8AgncDN2u7R78E*;UeuoXqNe7>I<mD%LJFC%LA zJBXIJt}FO%hz}Wx4Mf=J+R^|3G-i3B!My^fzJi`5SXDq?<MVWd{-Oj!XyoE#n6)xd z(n<B7f3~S~yxBHsICnTakKoWDQZw9;)WX|n&FxW?=TPaqwD<AW9Sd4+M9TTTMaFA@ zO*@OS7az&F@t=MnE+ahoT~AT)Cy-SALFF!u7}qaq7}o9JcOs~OoQuFyLX+`UP8#lY zUepDxji)<l&rkwpy5&pjXBph*^SJWF$C9FvvX#c^EdHT<!tR@6G}^=<JX^y#Z-3@K zSGmz6$}0R<E_vM)Y8>LQ)KYwqvq*KWidXS?eVpQk3xu(m@?>fLkcc$TuhC!Bw_FzC z-zi1*(m$c<Y^KO#jg;mV*F1dYZFGhi)gN6>FV8D%MqgKcm=|^M66f(44zp9EUHs#2 z?0#HtfjXsEn#h_OLDC`q@TdoSG#(a4O}>`Z8!%)!>~Psc-GECpeV4fcDs_Hm)}A2W zs_?4aObV9T{%NJ&g)SFq(Te^c;JU%g(aLns+;sk4f8gkg^77Vb@+^J8hSizBvDMX1 zq@NE+CxqQ9Ux0m?(?f({_HzvT5RUhgqXMCv`r|&tD%-PM%uGXCC@(i(A)6wKiH@;6 z{ObL`I(i*!Nk;bZ*0LJ!3EpN}aX3R5!pNarhks9fgCcnQaf`2u$zF<y&%M8Bx9uk8 z`89uSx4FO>o1V7U@;(85#-kSj8wF<8?*V^>QG{N*>HlUiA$We6uZIY3vN(UbbYaiK zXngMvi+bjR#w6*#=y~*J)2(GdfhrbT8-7f~2(==U%pN57clm7$fBKgISl+*J+IIDO z1-z%)?)(?bCcpLfO22k3@XiY2zqx=>x;s4oDt`*zH~Ck1ZTqC{Um;-Xb-+LWc&#+> z+RcAedN==X*!{nS{yzzFWi&}rW=$Qct*sU0F(LfvA*7_F{D%){%g!k-o-ar8lgJvH znwlD>D;EOYE0s4P3=9lipF9FzFK?Zdq^C!wr*lPHzW+D)H71rqpx%cMzz-jiQgO}i zG*U7$5+RUz)8xO~f7+T!IdU|D!(y?Vx`%3iIgcy4V9jo+1$}Y;>({SpkNqXsY1X~q zcDu`OBf=go-h0&}Qhw*_cW?dcx*Sf&+oAdD(dDJLlUa6FYisLySK@=ml9Kq9PN+0k zAnjkTYsV~cFGrLW8h-+XV!fa9to9K59kk<oq@e%ZJUra-?OO`ce<ZJUPaY5dAYy*z zs73>M`kzsLM$?J`*S60YsPqfUalFaOG&B%lq)+gF{aXP9qk8s8jQ_Fn;`N)JHv(Dy zv;SM2B_*8X<X%ltQL3t{QU4{1BHJY*JFcv?H84G${J%TyqU|vl+>Vfdz})OC<v+0j zQr}5<$jQl@*tH)1pL>brVTzUyp)vf=KK*3*e^<V5#M`kCA3cvYhBT6uRbSgWH8OB; zkm~Dm+`Q>K?){(t|D?zqALxpJ+zJZx^IHlHy?Mu~bZ%}Qct1C4<LiS?FmLC7Z0j}i zTQ{%5<7d>(_eY(9myaTdC5{I9LqddaQ@Fo?<v?yK`&^WZyYHUiPbHF-<$iJ)aG%av zGE#FJY;B%C`@7bF6Ne?v+-{>g5?pq6oU5yV<4*zG@?bT)-R&PgLaePJKa85*2;M`y z1Inlm$^PAkpOVSSQORa%4^dVpdoX1ft;t&%56UfG0h+(9ZJnqgHuLlI^IKrDA)>!E z2NhtKTXNj~H6xAuv`keT8*neLMlZ;{^78}2u+cYy!#Bn_30CFyB#P(@_w8K*7xOCZ z@%}@?<v^<6<PgH8f852GOBV*%SM?x8&@f=PU?ZO#*!!LXz5j%<D0zIIiha2`jPbRV zo=colp^DF?X~kK|08jr7?rUg|Z3Qi5@LQtNKz^l9V2a7j`<?am=2H(#b2%gR@Rv=- z9176mhAaB%(f5@4wIR0bg<X|!PU+R-_I)^oTB3xqWs<e9yXn_x$@&-Pu7|ZpeOhKW zFvrKeW}P+1UWl+X>68@-TbxuG=gKNbiOE{W2<`rPE0hN@P)y_Xc*(o;QgN$CpR#xl z@az7tAuh0<Ezqd_v5CFlRur$y5#`|Z?t8(UDz|z59%l)K+CF+|>_+|kG35L88}gR* zH29bBt+t)n{{GmAo`+fhpB9$U&^N%Y?QJsoN}`=N99lWd$V%LWR-gSRE2*{fw&~B< z87ZrD`Jb%^)2m@-<7JPu7EO~RcKAMh?p1c8@W2%wc-|oEL8DdXk**WAoC<0pr2<Ya z^n2ECJD7{^Wc55qa#S#ro1xhcHO#N-Y~NyB<JHh+1?k2Z{7@f#Oug}$tvSQsVCzW9 ze&u|Zb;VA;GYa&W4D8hX{Q+0HU3WlW!%*od52xJFy=}h-iJB%~A6}VRz{{vHB<r%V z@rcI<tw)=AJ<M~bXt6$TX86WvoN{K9rq)Q6<D<uX$?w3JgG}QPCFaK_sA>xI*Fx7c z{FwaS#oR@4>}9Ch6WA*yzr~ZTsG_IkAwIBA_lt$3v%lWScrBQb)APWjU<?wXxp@5k zGSFk`>^GU<ZpT{E)#F$FdcdlL#ko9)n5_N<%l2j`+!&5)`O*-wi-dpi7Q1LN8T?pj zVdm#Nc?$J$YI53@x7{SqBXPlPZE}!iYx@{bw%}Eok3sn(OEIOJLZ_*2O5JmD7ZYQ& zL2Q~TBQ5;s)u2j3)R~p%<;iySv@xs0z{$R`mA^f{X4W)P)Bo#PFE?rxQ`N>&y;~)n zQLnp!8=h~^zOC=9u#Q<PU^Mpej_qevemGJH0^GglT0I??3%!RwT$P+Q2X{&%PeII< zWt`IIu2!q{J^Wj2CJdVaEc;w!kEN10niCzbSO_GP?Fnl}^^!j2+Un;K`@s>BhbMUK z!CH~@m_x!W%^|H!P)Pdf-E4Sm`ly#lv#1?Lc!XJ+DK1SjkB|Buv!quj=xC&@N?`SD z#W=RwVTsm6cu?B0J3=)Sg+N6Bb}7U&(g4qIa)xx4G-ce=(!XErPxzz6;&Er%Xiey~ z8-Y=!tF9@o(Hm{r{e702An7B43GEwzmV^6piUzcRxirxsjH<n5&+tR&(Af#^X}w-_ z%UMAuZ{fKXnah|<V4N|N=^~U}6mWU4l2m+d!511{+6!=W|EV+|kY6$=(n^4=?RKzJ zdHgsKCC~z*v!;sRZhy`$JHs1MG>aFk#8}aq8XMoGkX3c3K3x_M?EF2bgm)d($#08B z97J5^7tJ(TG$QVC=D3i1aX9~L#?RB_zz$?fEqTQwOgjZH>7J*^5Xyv!ug+jJO$3PR z1Zvs&61w|Ufx_{zLab0(^NS2SXcgg%s*{#}$%9*>1w;VN#$qppCY_%GNWZ!JS8*F< zJ%hF|NsrFMkRdf1l!Ota9}oGNd8g0Nd4B8VJ=)`rHFa(u)|KWXeI`=n$S{T_-;3W` z;r++658`NsPwMTr2d`{f_f%!$XrC~Ej71&4B8~Q~-SdD8?u$Lzv(=%c$>8%q*5i7W z0POy=r?v^3-vHE2R;n*BvtvD=nL(UMC7ft6?ssFWRq;}y06+Wj2Ulz)IQ0BJVVZix zaXn_dz-_+luyki)qD-4|;^}iE(qzflG6i1;;MUZtZmeEt8<*psaR{Sstxnd-enfx# zk2e`{#;N<DMfW32BYby`D(=vmikB+N$9}0LhFaMgw}H13AXF|+W}b-LAe)};8HyLk zW0s!cvsPxypCI+s?1RITKPiw8ywK5YB5JAEf92^iOr!NKdTW;WcIt+u`I<}EJOvc9 zv@o%qSrxSFlZ-cUumDdc^XHS&rRytgdbYwgWY}RqBc()9wPc$@c_tBkwGrnjVdR7H zkFkyh&x-jg`JWPPX7h<SnECo_a2Y54sCp*DvyYT+eK{3psHFPjhIrB8VCIn!;b6&; zyEcJL(h{n>v%uL{jl2tDX#PAcd_9llZnK9@qe}YWhA=qRn$Z8a`2tqx@Iv}2`<vlf z{uLpiSm`&q3BIj4aH|^M=w}#o4W1xnAY^_b4!w&*DlWh+@t?bj)&aW3B=-mv(zYL# zgGLCV%kJGP=>#L=^AW9b(Monrk1}MOy_DDaZ9v?7qdM-?a&d!1Tzgsjf&#f;?o4Kc zIjOi_&&{|5hwl#m+^9zhKALxT)6&#E%wSe#z*}-A@%B!=lTiUChfVLd@GN%`+1|9* zI(Nc#esYN0Od&0hfcqagb@eV=fXJWC^5QzD2v8e@blBoK%kCN1Q%u(Avil{%=hL_p z_d;t8!IAHe|ISgp3Q)MZ+Jf~aR+G!iZ!@%_>S_A`{893&!|Z#-5#V`bN+xHNKK#-# zxp8`p2#~6o-E*^nkuG)2KLAs}=0|ErYoUPaytn_IuE8dcF&j5@<?7oWc2qmnnld%9 z7c#RwDe50wwIm+$_FpAYLXCLCoYw|NjH*8)KJU#p;2gi<<S&m}FTYlTg_G+y1Zfhh zeyz`g_%5XMR=Pm?2EIm<tq~;wv;e(2_YrbN2}X+j`AVp;|KU;8DfdzpnY~<ykK{;f zJnJ6T0lA_)LbW#p;yEwN2>rvR1H$R2P+I7MyBX)5hJ8L0?j<-K3ukhVQD0)Kmush| z;2Ukt%(vrN!o#vT7A%#WT7}<~7{w+RGdy}#w{@R3iPHr_yH8ZMWelZ<Td!tXsjb)w zO^#b^>y*-P<IQ=q&(5YQe8={Fhm^fIJ&TeNwll&lSJMzz0@*vBQNj0?=myeSj!7%| zTs*ew7(<yksgQtVQ`9cpb&^s><IHxesgpP3x7TDUI`!0PXDIbd&;;cq3jWetq{u#h zvX-3Zpee5#+h1_HsSL%>?E)yxfBD({OjS5)X6adiN}4TQAk=|$D<sMojuGZNN_njg zoL?_52N=hQPWSvbXQJs;4eQ|4CnK{ipGS-yAUeGx4?B^^ZvLizR&s8LWQ0rJh`&b{ ze96%F3G}|El2TbEJ}IDm^6LY`jSHO%qa;}VFB|0m`g&g9Ffa#5ozyvu_-sZ`BpM@- z>%KCt)|$i6u+;0u<j`Xu-&eqBAFmLr76y~XMKaR*Z+!N(K&&5G+|GKSZJ7S3YPUjd z$<udb2jzbpiAiYOtab}i$&l!1|25jN-u1fvx-ef=KM-?%SJ%VtrP_&G-D8uLUCG&z z26m2BImyC7wV_rsS`qJ>>g{Wq#L<0$GGfTl%#tSX<?RP58E?q7AE$^#ru~VnsC6kT zoVf@5Wpk+C9+<t5R!UsZWVAjU8KDD8JsV8g{cI}IHiysc>m1Sp=q@z5wmP=;_Qfrh zlBtx+-D-XDX`v;_Kb2ie7Wn<rKxXQitqw?f`lR#2Wb-7>b#Dt~wIa|l(%Jq2_I%cS z=6hduK{s!WGgQJWr*G)&hzPT$>UYsdkB2RRU(Wb{NiA+pZI<b2=gtdBMZOZYow!b2 zCKcG(P!C#YI{NvaQ_^W(@wLbZAz__Es9u!|*KeBURFb!4f6Q}!l2M1>VetS;zEWo6 zQdLlBerA2t1GUEf{;js;t4>wzuq~a4R^_zb#vj-*ZlNnULp}BQcR<s~=8*vF-zO~! z7X26!7Inok%Sk=yeXF8EKIQhW0h{xAG;e#p6eqLMdez#43<}_yBLV`uJ{;T=lVgef zK;?|c>eNg{b}gOMS>)$5!ci2pkN#<Z)5+l695}1weWTGn-?^Z_jlME#L>ExoNTsEn zS@>L5UbA)J>osAG_*j6wKF`Qp%t#hxtjX8n0N_;JuIv1U?*dcjo$poZte_m}z@-|z z<S97MfI9)mUTi*jrFeE5S}~Ns^m}c#m<PE=S}d46YY*X_9j68ZNp?oV{I|gxteKEa zccX$;{3T1@*iiNx<-pC7dYL>jkL>&(V|3w6)w#+F?XX|DJ-oR_*6}no?;fJ0!3+<% z^JA8XU~NP2+YSy!6=Rb?_zN36jYA$(jU4OaJu1&K#yn!|w3`V^Qco~c<f32Z_5J|S zIi6p<If3-~S+v^`S#(&0*}nw))2_~mdlWe=a2B(lo6dGH@4+NYmKhUJs!oEumDR%5 zqNg~`;16f<b(;Up1>iyMCGBYa`tVBJ&qOK7YQpQI>tvW<s21Hf^v8kA;7}5Mp-j^R zaSsQb#ck={zBGj11KYSu$fWU7V}cHAa|~=RatlW^ht%c?jn3dLaoogGaEG_tz{^v3 z2w5|mD2J-}v7y88%;m~-d%|-BSz()7K)2?cZ;zXo=!;Bg#gq6c2a5JzMHUyC<I#(^ zt(6&z=5}bJ<XH^*xf@HD#6v&iYDk&5`~_#fCa1M0`EQZAod#QcvYo?D8|x<fcp_Jf ztH0T7!?*ITOR|5r76lJQXN$vZwth2LP5HY!Ox8sje~A^`k6N3iVP!&koLxO+n&2k< z1?cgMr+ayo);hL}_GNj9xfX#h<&}J#nxxu2;U78wbb$PJ&-DEBs%ly_;Yw^Ure@p+ zprRiOekx#7-{|u}!8$_Fl#lkyUUz{_E_+_#HeM<MRhLtRLhVt#Y1TK|+Ap-zZxIl7 zK(-dd7i+n`_;g3U4w$WSB;_7$c9kXI4Eq^F=E1aT#%$z>HzKa6)JRw5Br;${?B`#~ zytlXtcZB<8Xq%a-$#c=I^EEwsD9A$iN_y-h}at~^|^fi;iut;$Xb_r~&13S=s3 z!IKM&>*;fbvg}8$7Y*b*{Fd7m#a=237U<{L*3qkf3x5N6p|c-kba(>rs3)ry&^839 z_b2pdD@!m6t)K;MH^OfQ<$p;x@;_gZGev=nT0YwEZGK+DeCdcfZJUIs19XQ!*7A)u z*)!=-ZSrGNaV^#0Iv3omVb?JMwPXxjJ*s*9y$rrxH8ae?|9H?rM_s$iV@4!<=x!g+ z{oCaRd()=hLmEc(*;0J?IsQOaQ>8_@NsMaSI%|d~Im5;Xb6Z+olFv8JRs_}I%0`zb z5%#Aw2}KzHX0P}paM0{XkttxrsP(n^2$y(^`%z@nfa{XM&zqlPuI_P(2mRlQX(Ap^ zt%@y;8$rE2=l2XwLzstL9`QJP_}7*1AiVk5T_^_rbV0f*n<rQ>GB3h}8OzA;oSRf; zhqGJEqYB&yc+bn8pYw*ZC6C98kKCR)YARJ$b9iBzJV)Bwg)GwsAI={K#OGG(%RD6F z*Y??GH_>9e^wHmO$rL|zeay)u!<I?xrk4^vhMb&Sa5?nmFtR)Ppl@M4KtrXFsc(i= zGpaG|dLpxZ4ro<)?%QUT^j0qZd^0=N;*0o2HvZ)a!F#^!`O8mHK0=}T$uU3F6&lQt z`naJc7274Ivgss$G4@r{eRl{XZKU@lI5>FPr~0HBlo(lSH=75(6E;K4?GHL9W`@!H zTw&`3a}fX#g|BTxjTUTPesa!!&nqb|PcLE3C(M`D(^c)YmXrlL1*LX*b%(k?Sqhb< z5`P$`IEjVKg{%Z>-sp)s{6i}^)uURjK4QO8hbLUxO*v{7eLT#cM81c)_SnRaHiQYk zD`bAB?ThcWw+Mp_Mbg%THgw$10&@<dc~@1vba#G+7on!m;)al99R#*J9aXhqdMC2W zUB8`M$Mi&)ciTT~4y**zs*fnvubW2BG)c2H`xOu5lk$+4F5ILk0S~0cr2p`3b`iv; zih0B9F3_{VMI%snA)Sd}fV!a%NFG&u)DOI={2j-SOHFm$k6&ymHTB$e*KJ2%%CL_3 zS${ctO|7Y=l{;F|i5AN5QuDb2OrxsoHfNbH0HW-6tC@T~eR1NFACfZEEVi~Jeog&Q zk4a8iY9yA4R(-{CPBl(!U)Xx4h{beJ7M+%tG&uh$8efoY`+%6D)SP}AMJ=JFiv^uC zN-IWLi~X8t;S)mH!7%T!eN_}CgTV)BJ>j%$;;oAhTwqyVRVf;Uz{SD>G>F5!cAX#P zGLo;<bY3IIideUx%1~po+pB(+p!`t&Pe4aO!P>VC?wG1pmFf4o{>>Rl5n&<+x<y&> z5g`<ISv|j<ZavQ86v1BV8^1GzIHAL$8F!w$PsPyy1=(5Djqy9H2VWGMD>ZxObXe{D zEywCNuM}>m#fB_5f_`{=JDS{aBF?}zl1!`56ba>iYEZ8WQhi|lC7pZwP!)V$Yo_o1 zaxHG<4HUjP;fej|cQpE4!lDOa%%qY}!nnu3Fcc5$D+26)to-B+yghBNxa<hKC_oT= z2qu9VY@)DBJo+w6UgypH+e0Z-Yi6LgBRs{xl(So~)3LB4A5M-q4<BYf{8La+W1Rn= zBAZc{w-FhB<98-HhWtMgc00YJ@)t`=;f7#IK~~mmpaNNlRHurATnJ-pl8%<Kegedu zd*j(+r%>%_#Y@p13gh157Q<wZm4lT@Zohby(C>6PO|BBCPk+#J{b^^N(w2)3UP_vk zi=!2agg4JakKqqIL{1c~(dgebW?>JN^zusii0>VFynx&b>-qp%EaYl+mSW|u*3dFe zqjQnUk6oHcucEKt<M~cpL(kHbPRk6@R+gt+N9%iO6<w#kiPb0jL&IBjk69Y3qowc7 zk3ReJYhL^E(w)<0C%a{+`1c9($j>?>T?0p0Ly>*rHt4N<!*4!pcWQr4!79W&ovtuq zXl26m>Rw}FMx<wLjTk|((f)pw;@Y2>8h*!7T~eo)5$L|XB%a&Y)5lz$bx_kU%6X3r z2?r7Lnk1(`al#udupO|lA)STqc6l@0@NzizXQ7g|eDRIMVegocHSbo5C^x5xqEn<n zo%r-5A{0>xXk+H<0D@(#`8#5!v->5!W_m7p?-QpOkmFI%a)KFZQdCoi5%4VdhNXxO z0~UoA*72cK3KdClop@^6cx#wm{vN<T&d6i9&XsM#-JrLFMr+KNQyqSY__Kgx`))1% z>5%k=%_0uedOq8#Xv<y^BehIxY)shNGRqMb5fO=f`Hd~91;6Pgm9SE6>3^8dWU$aG zu-Vvr3ZQvWl0mrqBY&I;xT0JQTl7*NU@@kM?^F>B%~&5AY%u33kcfLnq+U@sftH@i zP3n2G@|&+^=e^78?Z*r37WS&Y|0JC$i3&RiKM4I(F-!0n82L84!Q0OsI(tCd`r@)9 zfM~#IhX-F+_k^|NDxP)w1fc3({%ye3uwnsfWT;tLx@TVJ_1H;?sM%<J$t*tgYu_ks z;7#uCg3l!+?z#Rc`|(B>>z;%D)rZ@r$(JX7AQ-=<r?|rrwv$WUCIH<)MDQ7^wdYt= zorkT284n;7WTt)2zSjr&ZsRoK>&K%A3<+s5#<I6(nu&%pR*+!09~$F=>Ujmx#Jx)U zb0Qvib6;9cS2uzB1i$gi`7LOX<HIX)f3q#|{j(I{qWAZzqMd)Qabw4|_dv%3vKwkK z6&0Nm`NXkH_wVz_;%<`lxSVgS2Xn+d<SV*mwy6=!#3GMOIr)=Z1ZNOUVhHqHp=jQS zSv)e<hhA7_yf}GnNc=Z86aeSFm6Wfxe>-WZB^=th(z_m=lZ{O8F1kT$xilFfrKym8 zMd)pz_Tef8sF3RqA3~!~9H9L$>e_YX%jdIfMUDT7?nr!JBI7wZIiaPcUE|fHX24CK znGv4BN>PI((qU9<W0@%tSEK!9-M6kVq|96D`~O!S{u;l-!p!I><KA9pg8}z-@`CQn zl&?0g{!4gG&$_dXE$E@A-Us<OvAmqq<3nOy>^bZ`{`o(d{@)T3WKCC8Dm||S=D$@} z4^K!C-Ik1AcQN_b4DOzqQhe5!5aUF($}<-w7BuO^$;MV)%lHng28eF^*XM%j_HFEQ zIWi8;mIuuKZ&<x|)fz&UI@g^GDrrzw8a?sHO#ca`ZRr<W?k%@RO-kPwz5CzUtpB5k z*#EZB+W$aM@I4+`S>e0?R`MDuPyCpkp5s4Zp3zNH654<DR{wub@_#On_&-?f|40!2 zE46J)oj2BmSe`hHMp`vdGH9KdO7{@5x@9BMdV$8sWs$Q#Y)#sb^gK`kF>UFF&?{vv z`O8Yo;MY&Hm1@i=t{#-vUW*?)1Xy#5Vks({Y?t<sU+c5j?^>02$HuRHXV0yABAWSA zUcRdGiKwW4S-f$+wr8yRgTI@cA(Zs?HbtJW=U$3i<O(gTS#ZzC6LX@ygAk<8>nLgw zHF8=9#edoW4?HK~Nn0VEZb6%kA2Lq-Iv+d!gef3+#}7!e54NgDW=!x?so_6JV4iAM zFfd)5JO0z>Xfu;~z!<;N5yKLq)<gGl`=<E4429v|AHB(}?!POaGPep_@YG|_-TiCX zna$a8{NvTd@eG0U2S4kjlQzw~%He=!_uY9w{W}(=uj!jJY%Vu3#|8EADLZ4q>-0*L z9Ucrng}h)tza`Cx;%;&IgNz`Zw-fH}k0kjkf1+ve@c&>o88vz^!Nw9SedeW80b2?t ziLqcfI~!ok2k1D5boQtwZ+5QmiBD$ZC@1&#uAY`Lr4B-tmi4@WZ!~Xo<uS(n*ac5U zF#@~BNw-d1m?T`!lGxs8`tCMz<?dd(4^*!0poBvl9Hca9LT@dB@Ee^E!OMf|JJXZ3 zk9RltS<F{Bh4*SJ&L>(GwJF=<2@z-AVP#roejS05&DokHR~L};Tju^1v!EcE8(j+< zc)a_`cgE?vPWMEs{6+C}Zsyr<J;I<0t#Vw$4`wv!nfW=a`W=<*2b}+E<=~y<6q|YE zbjMOM9^vIRP~Tq^w04j%QAV@7RO=(MxL>M#_G$RyAZV&<J@z~Q&Zeb-as6p(;R)Ck zDteJV3#}<J`r&Nns~CSbKlOP0?~X>5CDr{l*V;MNB7#KwioVP?nZF$Av7r-S7lExC z=W7-yzgux^0D~#m-z8T1UfS;PPwJQTOEF&}&R;#utJ*|Zafa*h;*4LioTj1=&x3Bj zR;~yBJ`uESe(HuZR7*5~B;QuXWFlMsGHAvu1N*RK-wdpW*g1BO8A-pCCRPR_Y})SZ zbG<=4Tm7zl|20w4aOCL6*s4`raGyOzi$?qAe{%sAu2#-(L+uFB)wex{Urff}doB*_ zoZ+80S<d<D1K1wt{5=@~VTWI@()~Ur#KbPJOB(w!3nM59ei34-cWy{6cnh)l5mNfx zfk@%!ySVJ*>QeK*OyhzH(h2)L4{3bj@kCunrzlWZ42v5z#|}H`I?rTm2z0n+RQN3B z36l0CY4-_EXA%$Su=)^SVnRvZ^;&m;<FlPeBJ$i&Ig*b0-K`B?3raCql8E>1TSLCy zs1FmwR2s4Osizp&MP!1d7LFIgT*7v=*qF2Es=iOKxq?kef<3y76~9SW?No=fE6v?g zt`z|LIoE(?Sk0txY};@JUhhJCE`u|6$zS71%oudyMvJL1tND<JEkuo0QIK2RXbEqB zRx5{@Q#bZ2Hwv;A{=Cv;-+V$qHmyGe5l5r=dbekZIsHL<9fI>wzpmoK8W&|Dt|8$P z&&3*x^P~DmR9_ZPL@ciD7p#wD%+xyQ9?W0G<jl_gMVy(2pVI}#yxjNnIEhLGDR<jp zy}Sdg*ViXdm%Nt1-uddSLYYKOnV_s}xUzO0RDnC0<p;})Vq)Xnyw>`6lI7OB9U)gJ zl0xwXoBA||@9~R1TGVNB#(t^3aCGaSbbqT;_ijZ{S@9DN&*j5}=@9{noCYEQbW`Ru z?<UP{`E<WiWi286amk8<0eSN#LyHGNeyEcgh`ocZyWbqNHh{{c8cvE9@|8lw{s>q} zOaKs$E<Fc=i%fggi^Q@0yA#Cs?)iI{MXUXo$uG8XY8>L9D2j~^f!66i7LjmVI(Ur{ zpA1lN4Hat@2`j<LN#@&@<Xf-*qS{>V|GxF*V!8c<<?hgS*y{NhTzJSPin`PHtDM1~ z5{muEYmJe#4)E1Ox2%#~F%6X9{&hAHW+o|v`wYwch{n{czs7h?z{^Lom(GHP(rr`Q z@A4txDYV8{i7l>|j-G{O$PgQJFgp@budl^gY?m`tZpZYf(!<4;)_a*`;R|cdPsPp? zrWy&Y?4pgZ8<r(d5p!Rhigv$%zhC(1%eLhCiMNvpFOPXf52oa49nqol{AzVk9TF9{ z_70X=uHWUzW_jn#dJMIEn;fJL@~?JZI*1Z(`;h$%G$Jkp>aobZa6Utct`v(pykRc0 zZtePNW9qg_nii%fq+>WT>D9m}>Ytp!uFdj1QHv-6MWQPvo_b<plEb%Z^>L>1%fR#@ z%VAxof?*xqG}jhdM~!e~ay_B6LtB+X-<r>7Z*wOxx{Lf@7SF+ts~ds$?%8Sh5PJVv zCb$kf<Wc6bn}!y(Z!QD7yMs@e?{^DSR#&gp`9f{W_cT2A&?vY0>wA5NL#N05L>=vD zFdBSAysWz_*&yzO$W8yNk&gbfS)G5<>r=#NHS}=E?_vG^cF*lcz2O?pe)wJ5>1n+2 zQRy3d$1wP**_Wfl{m!frbKn?%Q-{tl_p6!9{dEU$nougLKwUEA`|-uYm#O=S))_RG z&lm(3hB6GK>3kbg&wUcjrgx=(U*Jzy@<%K+1&bAzjz+ABnD^!cKs=DY%Dr|xvq~R0 zwyKx%AsxZqLCbWwKcp#k1^(@71TvAViGk34+jJ=61kcWmN%_)rV*DiL0j9HzPKi%| z4E~`Zk3!FAWK!cbjPs?k(?OHrQ5s>=vF#>lj8iKA)k4yX!eH3DMzP;-c#SB10GMy{ z@6$uQ-npZ<Q2u2i3gq2sQi&S0R>(ry#^9UM3ruIGW(pmr97~HaoRF9D@`e<&+!c=; zd)-74kEc24eYfZYHH?L%Y1+O>@qqJgXu7#1JbDBa`qsE87`ltCG#i>2k}HjzkqS{% zuUZ2<Y$E4*r0F!e*&HkdS(o?4?ZG>$6%glUcVl&f8y|=K^RyY>?}Yz&bd9^99Is=H z&yz>@vkwsv96d)l3&Tw7<?E*JmleMPt_fpR4}!9hVK0T%nqw1Q$cOkg;{|-p8Zt~8 zQW^1|5Xt*+a_RK6wEI*i_%XZ4)SdQ2gZhBV<7fSAjQUY|!qV2S6QPcFxO&q*No?DB z#-ol}dMO}2P$V`R2@*|tjaZ#I70+U!P!HlfZ^NRARr4VqKu%ogi=2pTHgLL>avm>1 zpjHv+EQRm{=M6i!4?Q<Q1u{=$26k@iz2X<T*h$9_XGPf)&K9Gy5!S;)mSj|Kj&J>5 zd5hIQKfjusxXLs?__PNEJC}Vc%$3=rg<QA_nfe?n2X1r~{Bk*-$24ch>Yuiioj(k^ zZ}`_RmQ5vxdtRktTTa{KcOs&w9x>?iUe0{;E>FGXBkYlwq{#Dzxz*S268p&OFm%?4 zey@D9h0}y7b5ovZgpo>Cn!51`HqKwJcsd8%p_S5Y0<MtoIO~YsV1+ksg0DhO6HtBM zeYd>L6t*{=D&AA=ejlDDO0~B;SWa2KN}wgy8I*nxfBqBov>au9x2pfk0mky}JP7g2 zvdA)wM5v!ze*X@vHG45axt{l!TpYYmxzEKMS9z#R#U}Ew2|Ea@4`~ODXi=z*dCc8P zH+p3B`h}&?MYY@YxPSoelNpCe$7V?)q8xVYBBXqu$3Evaq>0g2-T%&DC1a*>oo@`k z&9`VqzJCdR67fAEH)KYF>2T+lFlJS2rkJ0+L^3ynAR{)(Jl$0AbF*I_PqTNEO7~Mm zqElKf(7ZzrbB}j}h4zibyHwh8_Ot(_Rec8if=iR}jI}f}ae`1sE0<qu-=H!xH|UZZ zBJcVEer=lW0sLQIu|>iJ*na1=%)6StJ?{_Z@Hk<ZWZLX1Wy1|9Z|C9{ch;d|9(1Uh z(d9l2O6*>em9ag#VkVJ}zLmB?r1HhAz#i|daAc{3npK-+sI*^6@{SyMMCR{i_^UPA zM-QaMmm4*_BB&{WR!#vWt;|G%F=$<xMnm+0H`1Pj>3PoP1(i9(QQo(KFj@9QJnOCw z&w^z<y<v4CS2NKUpL%~y9q8kKDT|}&mOj4t?Cj`&Px5O4tz1t``d8E5-u`Pk*A5{6 zi^$^t!=%ao{WJ0eUf+n8zHIQ-&jS_}_+KSL{{0klw0?VQizk^31<hOuu*~oZz4EaN z(J$I25eOX}rE{OS>o;$2?d<SAe!O|*fwp#lMR}p2w^9A8k@PIx-Eww9R}lVK62{C` za6CRbD&kr3{I8=zzcF+)=b4$L>F#d%{hRV_hG{kK;k5v%Jmzh!q3y1@x!9{t0aIC* z@tWDZ7>viAYp<CnQvc1bpe*qj?5b6Qs6cuvApt?aAqiK_#^YDbC-%w7$#<^?2*|$y z1?lN?Tw#4*1<>usxf)&OsK2`PWZ&B1Pf)zdnA}nVAF=wew{7h_Z~H5b<rsr0l-|2_ z?I&P+=$gyvo}mQq6$)N1e1q5R32VIm+Bmr7@6@kd`=3m2{a@4+{*Ht~)sZogm*;mw zu)+A*2U}l0?N<zZm&F5o<D_&f;l?njDYLbBEn<L@hR`qr{6d+<>zVoVbDbfEou>?M z(TlyZgnCQspI0BJsSWGI^px>|?;1uX6WBbHZvHd+=(#w?z?fVgJ`6@Cmka5XfxJ&k z_v8shp}MmapWd@ONfH`A<!d6VDixnW28zwqDpD6d-iM(*uUi(ROJFB-d+t6MT;QFI zm$(~yq(99B=ge0n3M>s7ok;wp9+`dmj{a}L(KT%1OL~)rx;SJ~8Z3OTn$P|vr|06( z7YPB~llJndU7)HflcdIhdDEhQNMBOq-C6p+xGuMh^Y*EjxJ8lJqx|6kJNam@x975~ zBZ;Hi7RR9l_ScUKM@7!JK7?naAIXI2{T;<qPjZFLJkNoj2ENyx*;<uaW5O-?W&C5s z%U&&!Ph%M}#;^xlD`M}q9yGiXsI>4);KZH1d>SVgeV?R@X*C$)AmRn%VR7A#O%Iu@ z#XTgIBY)6zn>okw0%*Z-u^Xv?N`7A^6-R9^p*boxq3C|TJkB<`Q+DiH*jwJMN&1BW za$h64!RGk>N)AD(PvjgyZzd_H0noT9PSC}4$Hy?q6bwaXG)f%%xNyx)|CsyIGczq6 zt}J@wAJL6#APMtS)}x&3ihrq+tB^&b-pp^l!PK-=^*wSmL`JS$%=I8{d5p<*-I5!x zCTC%L*HWmJS5LWA%6UAjhjjj)qSX>odofWN4y_V2&*`ZcBbAyzhr)U^_l7L9i}3zR zFUN4QwKMck2F1eNPdqv5u??15y*V+!MY->O_+Uvktx{qR&lY0*@3UzL=&M6n+{P-$ zz*4nM->{txt=9sdG4_Meh*X0KsyHs6J2(1%tqtOQlw}o>;Eylv4OZ$Q36WA70jj4; zpNTDUmKR4$!a|ad>p`Qof}mkbYuA%=$$>(;C<41|USlI2sj45Jrtf`uVqd!H%O~zI z@xSUjXuw=CeCtle<xju#nQ9nQciUgQR=eNI+qQ;nr_g5Xf69<Q_VAV#<l%_%38@$2 zU9@e-3xr}GdaLg_`c_9KD;Ovb^pg~n&Ds<)m5_H9<=*S*B03~6V1LEwyIt<ALo;$L zOL*x?qy4c@VQimMhdvXK<J0R}iZ%x3ufhuD&6C;Kv{*A%B{3w!J?V1|1py2s6iyC0 zGGKcz>;6m%W9fJP^3%fNeyjNmo59ABHp1V=e67*%qsq@~yfzaM5VbP>?n?2?+4r!Z zUM(em<xG^ENF>ppmkIXMCN?ujri4MnM`2h$KNQw_b}OB!z^%xclA=^WneAf4UmILE zTPxSsr^SyHS2#Tpy`dkq3wEbMkX7xDcD<qBM)8TJb$7&TifdAm#uE#vQd>#1nkBKy zgprIuK68Ylw`j8q%2kpeSHXleOC{m%f$jcR{Fg_jB={8G?HCllF)_3xONT1O5hEZ- z)7av+?H#stt7|gOqC4GAGoX91a-vn?AJeK=R=)IW#MKadU|@q9F^<j)wJZYUKk6^w zI0$hSp8e&r@msB);al_Ldbhj}%cAF64r)vW|IG!sdCW~>5M3OQ5M}2)Z}fsXRMsL- z4sW@Nwb$2C<$0QO;C$OH27Y+>=P37>EVtZWRYfIwUaWFr@I~XGSNAlrnI`3QG%rg~ z0LCf#ZVaK`Z?&6iK%!99-&D~(wfImuTB`@}IRhy<p^Z=9{I(jt9Zrm7RCMcSnVl{c zivmjgtZ^54E}d)Rxp&4+(Nr<OMyYGop8URvz?pUgjgJ6UmmJ#Bw+QTlq7|nMgl$aL zO(YVGZpFc+p$h2jQ&;S(?+bCytTmqqa@RoUh@RHDT)JF-S}2?-3^$EfY^d7pT?M*r zvx-eOiFz$$^zQHt_2`UnFC#>=w`4x;N_dSCKaE>xK-a}lroRG}Dx>-U+ZeF2ZWk@= z7#Ft*kPW?q5fFfI;wJm-nm(b#UNRaiyMi#p`}h7H010m2W8Qw{%|B)ZoLTuV8EoGC zb~ZouT`*YrG8VKN#^Pkl>g{lp)@bF_n=>3tcI7<(kk8-CGiWvXxG44^GhSFosK0pY zQcP3C=9O<f++^$h)6I7{zt*m`u6<R9Z4sT^-Py-r35>IQVN0!sv#!}Ho(>zCRR-U= zD}fdXBUum1%y0+#61^4Ibk=<a>80ORhu{PfrVvy<Q9I^MR?i&k1X&6x8`DT0zGGav zC4>LsioTU0W3Qm7dWusLqgj&eOWBc&G%MVH{~!v8q%>2kpLPmwdD2|OyS%hYNyjov zX_I}UKBi;ClvdK_YcNoOWGfbJAW7uvh7N6-i<z`jc#4=ai0rA?kJKVM9{p%*ajPsl zE!l}JCoCxg#F;AIWYO?W#-)$r3JwehOZ}MiFRV7VRCUpgvt42o{zr61YcVrkVLwNV z9=7+?dnGShN|d%9H!%&ZzxrU0LGK8=V>{yUrv@p9QLa84aBkL-#=Gx?dPoWy6-`e} z>>MlZbX3LL7q?2qB&kTylq^+X2Bt%l$p!7$f(EP$Ijf7gBr9r8WL+A$_H8qMy87pX zTj7R~1(n67C7<SkOuJn^FCI*jQMDkitCtV+&&ALt-H4*ts!k>Fpmz^8a0sEr>NmRg zSKDo7*(%VR6R+ab%_z$K?$gmWrtEnra!>HrCZPr$;T{~2g8a{SSzBt)5O>WMl=m<_ z7!lTEB3Fx(^PS@xky;@{bkfE->PAm8J7XL-s=D}Z%H35tzEm{Em@4fsfR2^zwxjCS zoS*p~i3sk-jAM7Lhj8=Nv4Yc)wx29}GC?SXzPvD2_Ci7tv*WJac%JykgFD+jAqsqy z2+{}1FK}Rs=kg{>aJ?U1$r+0BTEf)<*r{Kt2RuiuVgdne@m_Gg$k?4&Z_}@0Rlvyj z1fs)@$lBD^shIAK-$_MbIwX_;rO7UHbDbq*-_jD}-xZ%#XB<4L>i;gIPl!_-F<}3? z&?JA>Za^_Kpq)+-utHeGsXq^MF4ExJ!ae;0G}cpdP{P=e7OQfmq*+^j!l9<2cT@_Z ztZLWJ^3>=<Uf_VAc3NJ25_9c%6%p5?w3<j1iR{x-BoXv*#U$NmiZ9wF_+SfvX(xg& z_|8c$!Pa1Rv(I1$!?;-d>Q3A$QO;Ft=l|gCt)t@VwlC2nBqR_BA-DvB2Y0vNS`ggb z-JOCYxVyVkXmBVfAh;J&xVyW1SH64i?{$xUqsJSsM|b@Lj8mMw_c?3Jnrp7P8q{Pl z0QdK5`;@r1d+zg%odH3KvXWJseeZWQtY5XMNg(s6T5qSucR=i9C2QCFkdgb7%X>K@ zQ`y`$R^>621T*j&d;OKM5^0bo&Q<O{P$1nZUA)etjM~WWl1Zh_qqA{3k@bg95pB~| z-$c5vxYE_@jBeAf@YBL*2?d23-OOCAGAIhJ6)C4R*8go5SH=?h#sR(0$L>zPN*cHg z=Yn{PzzrUy73vLX7I~sMudfUe{SH9jB&obo$y<J(T^7NYabHW3Yu*>rZV+xa9gkqL zgrsYp#djT*tHjx8$uQy7I6sz*!PLcF3|>yY%wSeNHxB@96AV(Sf9GF}Uk_T}AR0`( zdkl#x-t8X0IG_YV93qQ;NNrZo#7XJ-^0(H#u7D%rr7o<W>&^t9HTa$K>0>r92e?G2 zTAI%Vv%;AVzgMMbJ)dvN%D?9?d3;}*pq!fhAuw~XlmN|Ioyn&-gy(w3v*pR<W~!;9 z?QDqQkADII4xc>xiv;3EvSssGnM*o>?It~2;G>6@+~sCh7tLzAN@cU9!0*(wFka_B z(|RL>ma-cK0gm%;^eTz^o7&<at^YbSZ1b(}?-PFphF=8c=B9}Ra-q|c@IKFOya}S9 zTyG%K6BNG}czJ#daC96Sx?U@>)_aEjMB`)r@ao0MI~_=>k&%%Y{Cpbt;|DeHg4#Gr zd@@Bo@wsR~_3Nlr*?=5hoU|a>jMKySd>r~wb^C`-l`&Csv)t*gO@uhUDL$^}eayo7 zf3t#qv?aBv{4hwJaiEEUJJgV-KgJu)1OlHU9&%AHxL&=NTa60(q^0-q1_(Z-4{!ZD z9Uc}R%Hf=Ho1;V}CnR$+C1}AjPDA|PEA7kk%QWqOe|z!6Rpfs&v+loKj~$8Hz!FMc z)84x}nIxZ!r>)l^q2}x=w*kXh-Z&chU!r6IcTe&Hg7Fk&CpdM4Wi1l!zcWok(-ijG zW(d`$ZYAo6sZ0987FwSKQ`j}1oEBrYfI&nZ$INh-@1Q@jy?8+B!?XPfIQ=fxh?jZ8 zMen7^dUdE4QjAmqUt5DJ7r{r4ETKEfgpH1huPhd=4H|motII*su^++o9Bn`E#z!|N zeTPnAkZP;*C0f+s<Gpi4<k$5?J_4B>gyT5<H63Vr4k_s5dufyVI$*;0PA{X(M&J5c zVg|%CGpN5FzG5Sd!gcBLT}acM6wOGV(mfY>MTkP=df5g=I)B}F_KB2K=}g*+pjeLx zTUFSu?VDX`5U(iQxs}PZ{$Y^pF`{c~Z!RJ#($4EdJSzCT-wN~Y>ZRe^n%0MH4V9P- zjX9>qkoLIVk2iFhBTMxHiRX8@(*erze$oSA<!O8Ha}8n%_-rk0c6Rrz?+wKLNwDz! z{gM<#vqyn?i6e<G8m#hHh)_PGqGZM9B%4Nb?+-F$P2AjOBQ?-AuO0sbR&?7m()mok zV_xTaSVY%TrGQn>q{<{FHo=Y&A_rVuVZ6Zyp>%-J|L93)$4rYb%f292DC@cGI$!M} zpoOwO-~>{owgE7{2BR3RU0>yXODoKMPbJ@Ff+d3lz0-(^%4(Zg$gX>R$`+N{IP;zx zwZkLqRhrLSqW;dYA_1{m22HHlF*7hWk9<pXA)y2jh><jgQFJ@wxZC;*ZZ*_2loVQu zW?$S@4><qmb?wgtd{-`%c*IQ5{c2;VHN)$5fA7)I>@IKf&|be2i>O#_AVxPykkVjX z7+ktjoq2eDH@-Bg-sEm7nO*)<S~nh_AOp^D5l^yX#Q(fQg^fFkp&%SJ<$hy7v95Gx zmBxjj^YDt&gHx>;D78yPmOFl40J!tkiebM*Zm!!hp=Pc^+6};>5wWUr`_Wc}+R#}t zUX~okyc<w3em}gV-BPxrC_5BDd)t7Cn8@&iQRJ0I;H-lWDH=m+!%>6np3#8@<Knyt zn*b)%3ROsI$TFM$MyF*#zD{sHsRt+~21!kNQYIAm@c7nkuj28tbBrCacR+VXa#HOp z{uaSb5>_i2AIqQhj2CHF5@IA$A>qODj1^?*Kd*$9RM7BCbc`swDD$5(^@MKZ)_&}+ zi;Cy(>r6QtV>L<ma7Akh!KnDE-l<=Vn8$@)%oI14Jt%^ubuwOr9-MrR>6#Zw_~f>! zieRASCF|}IYvt5Q6RJp>$7qbB){o@U=UoUm%a<!15u_8EQo$iL`cy5Ge<2^rWk1K| zaE~BT`N?z9^P+u?YmY5Yv)$vOR!yAu`!Iw2avi<&b%L8NahX63riX;<LCJ|XRo8r( zhnS_Y<Kr=X!gZE(mRP>XW<$W>!%~XiP_Td?GNULJxrq`L?z}FaEq)zN{=R9Y)N<S5 zugQxsFtq}l?zdIR;JY{xe41S{ZfD7bz?<30IExt=M47-5<EQ8C9F6M<sWS&>*Ow}R zQ8iYZf_HHDKJHZ0`;UlUGn!s()Y=6tHNVF2ZJ6`F*)MR^$%K5hpL>0YuFzi{M+(Y{ zT+`f3N{00D>em|VReYcd_fS%M3%NDs`h@OVaI5a#7)zV7VDX&1@vZorYCwO1{ONKh znJy$|nb*!EhE^xtvAnI|?N)dGRx!bpZ)%o;tMx{}@@|$WPMgI9KkoyZ#ZpWKbVx2W z6yrm8zN>b_t-Hk??Pwf+$v|bdC{@1MvZ6g=sP_W`_@-da^JJre99hJnoohJ}=!CiG zRaz?iBue}8#W(2g%na91CV$*T;G8C2mYpz>qEYu`z7-&nY@xVK%NMpR8!0c>)=em2 zVLIy088<gHfz%)?#-M7dYN$pgrCHT|;I{0$I6ZcP*59-^FW*l{_4bYYDLVdwEFX3j z)WH$`_d69~Va>aQHJ>T69susHg_(3o^`}qOp_dD$BPm;)qLoay)2tzFw4Zz5Ks}_a zl^sa7+T0ETkt1+vq|Tze7+CmpQ!q9-XI4zTMZKx@$XO<u^%N4=OrA$NDNHf8Mp9Of z4b^X#`?9K?14L{ZdCFyWewPQ%lsYmzuRe~vJui%MWu8!SQG&vhLvn7o?|tBFF4=pV zSIh2VeUl24`Jd-~N^F_nn8`wTiBhEKwj&}M`p)DgWv2W<>=}@%RiM+3>00#+^gM-v z&(oC;?4{=23tHSof#TVXq@55xyLxtPYWXIIKtPs#HKeXtU$Nkpzm*^JYaT>J#`s9$ z+|a7$06qeQ&Iu0j_sX97j^uN!J9~$$emDF1Gg3PCx09E0=2HzL;@vIy-3_JbD-n~V z0%qHu<B;eX*;IbFyS|)PiIG23>bPt6gu8yq9{Jxonckt*7+$h6VZ3WZ5nE!McPn@z z@u6@(dacJRel%Nrqli(}R}0XJTjC<L46TN}zx5Q6Kq;7)_MqiwPvhICZ&iyXN+KI> zJn@P{0Df3tY^HR2M(eHSW^Ac4pPTtprq$m+U79jQ1RWbRH!tQ$i#Pkc)WoYm`SJeE zO*3yQ-g)^APXNAalho8@3>FIEn&r4>N7Qxw`cAZ9s_me2Sql}w<EJLwDXe=>h%`oO zp2MmH9Gf1UnpgW7=fN{O%0}c4lxz$tP&bxkgt<5CLVYgskpv=nJj~W7_H4R4UOw_X z{{HQPpFi+Yq*u;;c7AUpK~G+9%*mm_uwj<_j_SgC4-3g`!}*R1cCyut;qc~8I0m&L z#BzSYM~*CzgSfXa)yiV`@)tU6&$rJpE|xVcWbtPA&jc(XicgDAKRB%Yn+Gi|cf;}u zI*eLcMc`68?=V=)v*<rqz`GKJ61oSE{mdCHLbWz#j7&EcPFCz>2VDGA9S2%k>eI6X zzNVDx<n}Qrcd8RET181@A?rz0ZshiF$f$}n1pvA!>*>4uAhjeCF6p6G<eWB9eYSA4 zNJTS56)=>+JSW6>Y-srOxnkXk$d%9pP3}I?HSWE*`{=OTp$>e$FgqZlq~h<`Oh!M> z&srh+b-!{2K2<@g8oDQNMu@gqXX10F_4M~|(i=OGCN71{`YHl~#Ie(E-vr6x?H8-L zb6hEkoi_pCOA9mqz9tsbsBC!$UGA00q9B-OQ`1)l?Ihzfn@PUP#BqO>nPOPV$b?@} zl*1IQY;fD$vBvclGMwB9t0m*Xr<wIx?Aq9GNS3Q~)^2ECuHY}pS=)j>yPe>hZ47Z& z-f#&x(ccxpd7x_}(_}DbNuciBrj~VYjw`~P9_J1?+6Qe}8mM7nQkS#(;?;{$PC_pG z;^W1x%2KOC_7N@f0ru)M!b6)y<wUiK-7SkZlNu#!p$M<KRmHV4Bewm&#n|eOUxse& zZvX(=NuWykYwY*s;i-%cyQ#sC5W*oYQ{hu{60PYz?)GIB{Vu1EUSSdV<gq+hE`RtR z6;YRY+k3~tX}%w9lbQF)w9Q`iD5wk{gFL#reSbBeMh&v#DB;Y7m&7W{fSYTY?>!aq zZFOe64nlt}KS)(LKWnI@C3wcIGmq#Q+Zr3oO$tle7H&_2aHc2SPI4*^6*jrtZ#<IO zF=Z_0m+|Nr0na)kIB&lvxik^JbfNfeJ<igqs+62sM0-I@RcL9u#WlA)oBg2aDi(Af z%FU6PY52BecDOqa@+QB!HW2Jw_O&&dl=)+ufZd+?seVqMiYTgsIZZhT6vDQPzvG1J z{%V!UE{57q0F%a&6&8l5twf?C0CZ4MNcV*FNb>dj{{At@?0AB5(O@$mH*D*6f0f5g zsKdOHdM+sv(UPO1v{kT8jTo7^v8mt1T#dJN{7fg&a35%?RCTtGq=9<%(rH`v3=`?I zn4tu#_;vF`JK21=0r|y+YL?^&B7r4S09Gt`By9Ig^yN=j(=ao}E#QnJ#;gdZR4c-O zV`koq=@C3?RQp~_R~NK%7S!FYeZVjKb;aS0-{V6jd-P)2&O$c$ZYqz8?b+W`_RNWt zleM~($T<$oAhCn7GOK;-@N@<6*bQ(*-S0b79Ji8v*cwhf+NZ(%fc-wL*OHB+xkPGO zz~1#^-R}sHP*h3Dt-Z6$2e;8lY9O(Trm1A`#10Y>%)-KWAAQHDa`{0{UhbYj%Qkyv zS)P0aPeG!qSGA$=J5V&0R%r4kkKkJ`FCKiC$=#!~?7_2%b1c<71il@o`9G{*+M9-( z0I9)E&*{{8{BL>R6@M+hjnBiM>W!L{Ap2Pwm6Xt05#pAeH5x8q)2CL<NL!(N;Vi+H zm2x<Jxzl2M-KOL9T|~n{I<aF)a5U~|Vr6CZ*hW1rgL>?O!2kXre^=lR=gPbFs`sQ( zHl(Z|aS`i`N)ygw^ejY^TQea@snU8P+}~q$PQwh9bBizDz;f)U;jk`;FhEl!&IXF} zJB!*_Yq3$S=galKFUBO&)_~a}n__GS-4Mem16o3g@ukB`H*Tq>%eg%4=z&FnlzUOi zR?uuIT~!g3fQQ7Vcg#$fCoW2Z1;`2IJ-kuPl~fjR&qz<xh{YjALWWUNK|@<XEw#-^ z?BS863=4Hwg?;T@(@lE%TT+R<$i(B^*kfaADk4Id*)9G1U3`rblxkSP6sB~(%J?Xw z(s7dISG8KLG<;BBs7$c@GemuEA;D}yNlzIS3kwx-3aVL~Vpj-aL$Er2k(9QYlUDhz zTR>om=mRW3Ht@%tUnbD}cy4%#XekfaCCrLYB3qJ)(mDx|*(BVvnxp^=dRF3G1%C(< z-#c0X(!6n*2`?+t+Beb{&0sQFWLKWAhGCt%GFdyBvmIAwzm=#j_~@bFDeT?ha>?Jt z)(XUN)7-_c%bf4}VP|I>O<JCF=clb0mqdi)wkqwDpbd$wa1pVRuU$k7E1|p=9=gpx zNW&T)+~sw1;Y<?9s$ACQhaaW?$X>sKu%$Ws-K8`)M4@mjhXbkyjRF4i-MKKRY{5WZ zsDR4c_`-qmXVI(F!Vj)0DhaKHovX9m+zUeRoqzyvCXL7JTxENU+QY=ezP^WzF`hTk zN_%l!G4%!)@h%^f`1FU}b830n)omlP4m3iP2LWoAfm3ht_x7?&G1(olrqiJiH(RAY zbq79PNa=^i&$zBm1G@xxbq8b#o4ANz@p4}Aj6VSOLm%bl`IrjY*&6XLi_fk=eN+`> zsT5^Tt79DELr4QfB=zSkaOQ0H3NjGe=RhGd1B>{4V$1*HhX<>-jq_$I@~u)iT!n=n zcKr&)@2HbMx`JW%#;roi2}#-9;v6+^|ICHkRw)s3G(eGBI<<?XqBN0JS(IDRBe`LG z;U)ZVyq5i^e15VatDdQAzP6L@jpsfhn#=DwHC12z_S}Fxc7Y8*rjIdn$y<r|8E?YB z-aEF=>iqFt!Tc@xE|?8r?1D4k$wW;NW6jkj5<^Y{bHlQ$4pqC>(b>aR+WWzmgIrzy zuGbq)XMECP8Z><-`9Z=AStBLh(uwR*?zooU#951TN=L*6Qn8hEbm)i{SysY#X>Xn% z56-^#9Id%}2=pg*&9~CL(5(tjoX}N?ucc*c?eDfz46YeX)ggkADLdNba0t?ccJ$f2 z9Y+;?n&=53MBLl@JWn|0;#F^BI;?X1`$+FrWx}SW;ePi>83|S8@XnseJp;NL37H)! zat_Lx`e3pzV4k<Q?|F=Cn#rmbS|GMd&CD$5gHD$DJSA!n6x+<bbGQ$y_YSOhg4~QR zQcthCSvLe_r<s7uH~a>DgWF!=OOI}Q4f&d_b@Ck!x6AI}89$fFY-B>b<WnK%$PywX zG~HR2@L=~29{n9*GDq=yM{QF23Y$l(NpkwcPnO!7^2-?g*_ALF>G!m3XnRWQ9E9TK z`ME9?F~9D>A%mQU_7J^Ct{<6`6YX72YqXVZdw+&`@KP95*cqWDSRTHXmM=x7`y}-! z$}KZe@?ur`(t0a)(5V#D)U=DL8uE+j8EmRgaB)@+CG~dWRq8Rv7wE7!=SQw~TiFn& zwfQ`^a;Lk)A7BSllPE)kK))ySwN3^AL{~@;(~OqpXfh5Q>8T{g^{XC3!}Hjl?}v0M z+`kUIFH2tb>57CJ^p#j@R_1X?(VB!NmOC$gKcp3}gFc4V9gO(7HkImFpSvIcx8Ai- z-J)SA`h_4{1jvfi7E{MH$d#AG#8acVizA|Vh~+G-Xgq%-u0og;0F0*wGEA%V4@hHK zE3CZML+8(sRZuF*xdr|4pURVuz?=HWkhO$S;xz?>rQ#G<@mkVe@6EtOBT8%I3rkAB z+I``3vYqyVuHdF9M(B}PO;q!nyN;ii2<+H9^9AkNQq}1la?BpZ+g?u?3=~8@L9kUN ztx}_Uv-sYEyH{r2?-)^1NR=Nm73q$nqu2<YOFTg5+f$IOf|0}23N$Bq`KGqqAT!hH zr#-!wh(Yoh7AD=kYc)Z*d{!kL0GH6hw(s!lgNHYBc>1`M3`DA-7dyolY3wW(3IqMc zWt6MtF)L8CUIKM5FJ$B03!^8ijq23uviC?hXB&t07F!2Km1&=y&V*x>DQRV*LgW(C z?r+rVpPk?tizm43DWF-!0O_1PA%0YAZ^}qhGl{2o&5GRX!QN19ZafEu2JOOVDMzId zoxY>pEb+*I8x4g1fa2GdI!)yK96Xn*6Oh!fi*uvMZsUZ0%(JtWA*bz%ga-P_A2xrc z3&6=2g_xX-qD6@uY?YQ@PEOcLrJ}-{C}aAq$OAmY6mxUf0?5y`r7OU!`CpUb`<+oE zoTWUb0^V!vWtNuID=SJ|%pxkMEOic9GStSWBz?kCGXFxfIez3J3vuBB=fp}?bRRBa z_=qig#b$}z|0Ig^n@Lr`#YoUqCaa_dW8x)H*zC3D%qb7;XxQa|4Ly{*X~NEs2eJ5P zH|2^e(2GD^?4^?88B$=r_Z$lGD&HUV68LyY1a#&u^_Ak-Xn81=6v-0uvrwX%O}-tz zOTs+?a4E}Iipv$Hmdzy7y6994F)^(YuuaBK)9eI&H5Ti|;c)iYV`s;t>Vl_k#ZO{p zhH<6ju()BQG6lEBu%~H;?e&8&6K0VFyEkfWQYk%jg`Gq1ioUROP-bzt&pEOk@K5U= zbkK)|$qq0Sp#gP?Tp0KpXPc*7RM?3kD@F_u6QshGO?G!FSOP-FC#e?;Q6n;4FxYfL zLI6p9yAk5uW)11}zI%kDqORv1O)_G8%P7^MY3#^43|Rhi8B8>Qw;7hYUW;iCV<3;u zBZrX}UhV^rSp0mf%~wg!$o8N4y2TsTNaYG~q_C8cG;r1w2Vhjs0XFcRFoD#@S8J)D z(J4h^wrLjD=Df#+{pr2g`^X+)IOim0kCxcj!~Q%fG<q81rTIB9<vRT1;!Sbmqt*2| zlpG6?$}2TQ=KE4)g_Y6&GqJD1@m$u9RUzU04{oAEoYml8Td~PEH;^>4Vp<^fh>sJc z^V4rcvYf1}&L@m!PI5Lu@!LO_`DEd~S5XS+ped52S8#8f`BN^2&z$$KOt%WVLouCq zl>D7oa_^8x-{yTN3$rC{F++IZ!<0g$XV1Edx<#sT7!&l7jzZZv<1Y-JD<8nP^(YD? z(rQ@49b<PsyE^@DyjQP0VzuP`xRX3%lcmc3eG(~|z|d&Y!~&duBz>`p@piIwSL^Qe z?W~hj#G2{CpE&g4N{!$mDEgSv>~7&yRL;OdZi&!zSO0l}$IHkC345+1-)NJaddkbU z8sq%Cv_XP8o{df7-Z)X*gAbw^A4og<*uUnJu#i3lG5T1Jvpc*$agqVUfFgAoDO8yP zNnPEP{z_PRAN<WnNM&k>4jd&A5g?CZx2sfb&lmYF?YRwn5B#iG2T!CKw)QxT#0`ND z6{>6B7bj9@Q1xJ+bn5GR!@1*NTIlZg?|qjaJHfB-!asT3^LZ7tlxDG2lrNi?5|h>g z-GABIGZLfi!@wglyZFh$Iv1?2HUdH!AHBDK+*Y#rK9#k5Sw>$NU)({jI6g+!NggmW zm2N$?y5G8UbU)v8|Dn_w`BrsT^ljZ@*d-m4g^XnHA!fKrvE*x!+EVKA?TYDfXkiJy zITvBcUkg^-I0gb4UFszW;Beb$(V)^DQ6T6zeU^N!D+YDH*hbSm;@k~vU(kd~<o#jc z{>xxons4+78q(-Zzj}CKYIqzvRV1j*fcMSNMP63l{FDFbnEhyzUlBCLo}5(RA}r3| zY<HEuKJj^JlVhlhpJ($4*^ekQMdyCd_YI0Qg7DT^E{372-Hgn(tVohYy}$(l01#SO z8YWTwA1pv_6+*(eYFr!tB%Q@MDs&+o+;)ezi2?|K2Rq0v!YeC%oiCWj2|`0{Kj5v2 zzF0vrzgD1$3NCr*KoiVYhiY*3ugXKGy=7~QOXNSY&z*>vhhDY>#GT}jXU|TSa&vH~ z!Z}-Z@7^WnW+?T+Cl6zs8s=2-g$H6Igz&|STBIl2moFY{z7C8tK2&_-+t)Xcq^Zu$ z^-)W{<>mu3!y`#QBwoPv3Rmnz)YK@NFwsBDEYnvG)_=Sk&f22*<^$(^mH+b6hsR^S zkuAW9Q$Xo&?U>>1@W0{z`M=UW?3uvOSKdsCK|kHSRY3(O`n)Wh1p%JU%|gTbl*%Z9 z&s$#?EslpU9s0=%PFY`Knc$GhcNHW_rp?%%V?!9$qTA$DuyH)U%JX@(Hta6%%}SP> z$#`8Co)itEKBNKjSB!Wg;GJ99J%PQ(_3-hwwv3ppHF@7HE~?<9qcGR*LHhVj!*=7y z2&vm;czKr>pw6~@Zvm9H0H|6kd-`#i$DrvY{W*@f5H>o0vxQ9d*e2u|V-`T%y2e5# z`S}4Ck<aR90{V5xgCtETsV~ZKz2{?jNJk=OPHfj><KeH}{bN}y0ojW0QlB{Ng6R)$ zsw*CA#YlW>ME@#FM)gg6(pLtsvjYfoiX`>Fxy0iBGMMn|i~Hk}elap2wQ>Bdpg0<% zwWcAgNrUl97LRZ&KZW#+^UJ?tCKiv0R=hlYiF|m790CFzWpUdT?(>|zD6_{7IF@hn zisl42ir@J$B6|)>FXfYlF6Tw&6S%jr%n9kKB^k7HihBO#0P2pteHAX9n(#3#`p(Pe z%_?sQLSYmJ9<wt0v|(hIZuYic%1jvF<0C&T3#+{E!!mlo{yIR>P*G;X--iAwjiX;F zn<gAt5I;*#;>`DfNov}2t%KVXDXo)$62h8<ACWT{C4ilx_|;}~dp?ZswF-!REt<PC z9J6UPEow4c7k6zquUWOEx{=sNwjt|YE<1q__+0;9bwXmlP_)|&mfQw@aEYPgXSox0 zbx26Z)eHmfMBtkj^A$1BZW+sZ8c;(ZW)LdK8l!TOymEC5tgp|Xw!j6<CzCVNyX<S< z@aQ8p77$0ZRvlX4Z}wQ$*9+CNUYd+nTukUYjG3i?O}WbvO%&ZDr3or)DWnixDk*#B z)P~p?93LDWZ`*WQfb4N5l{m}(G)g_}k1=a}B5QM7I%6)8%qiMX5Rv*<Kw~=(+v6+g zt|~%Pok6z;FbR*gXjj5*A`^-7$+iyZbXsN;%;%-BQj4^fn4u;)j$!zz`Yd!G7aMvf z>uFM(&0#s8>3u4=gl{u43Nwet6LTc2_`Dl;PpNO~0O>y&d|t-2*fi~-%8VQ3tyQ1N z?4~w&Ky>C^7m5)il)@%Q6F4v2KoL>Rx<c&LklqWa$k=2I2elIX3xKw`eEQZzmA9CJ zG>(~!QwER{Ic(jC0h1;0Zhj$Ls{G5}XqYhFD{RQ7V&nM}AAbNj1qUe)L|u*x8yebu z=K-IJb|5MZi(;xrGK`eyObPkz^?Ba=H<4ES5?WE}w{^)o{uc*Y$RpokqI|yvnKC;P z9Rf+%R)wqFbNzlw$EHTxeMu$bm~?+<jPL9H`U4-hJvGoNoDRWCE9bioBsckzzy~LY zj&PBWP{YZhcgx*&H1|u6P(zV}hP14;u%|&lsHN2L3txExSynh5^Jd;_?WK4o*6I3@ z^V%A}?Gm|2?icS5eti{U*1YLdxYu_qF>k14BKYd9lAND%UtB)oz{!GCN)UK~gYl_s zQvNeZYxne9-k<e9&$k_g-N;YP+E^D8j~-2yY4s?ixG*z?`TVeNHR9I%<Iqn7XsAvR zN+*@mKl*fu?wm^p*EQ9li>QeO6gUV7se)nRokpETLpXqHmYwP|6rB&xvtvT*2N9{& z>yhGtSsQJvofE-1ePO7J31T|YK2%);*=wH4T~*(?J*doo2R<cBJKD;d%f`9i32x2Q zn9QD{OI*Q<pO|}V*2xJIYMIgm8Fn&eu>qXxWW|A`cJyZrV+n=+&$tQ(ywt`iVG1HX z4<TeZ_bOpetF)ua{GL&?ijjwKpPouz{6~8z6%+;Skvd9{VS}s+-Gy0T%{VgsaMZOE zCDZ&)kPDGl_*@4EvPt&++Pv99UhMQ1_fa8EcnLka+P^Q0lx&Dzm~R-j<Sf2({sT6C zlLr8<2BsbNGsdU64s5|DrXmh|6V(nH+{T^K4v7fnK{u+m2ZK4S_4R4+`MtpWX`cLi zd*-#X9bXLQcWrcRlna`=cLs`j>>qwDc?6IFqTWTJE~eWa@*9jvsD@gXJYbwoeYQg# zXWu!q&Z*b-+U(0we0#dX?KAaC=I7B5UIMv2Ijbf&Nfq50)86%KaqaCJsOG9cNuNBI z19@FMiKW02{@$!T#hEeBX-bWEMa-V6Piy?N!K;Eb(~Bje3sCh?3K=x?!!j{V2E;tp zCM^K>6`G*IUR9&BomJ9+Ka9u9*Uk#zEPDGe3wCK?{RJAjK&*3mkneFkL!eCgJ#A@m z)Ug`AT(&Q(3!aIB1}dqH*=ODkWw7=ukvn6Cd<KOzv)}H{BA1T6Bob!*Fg-M878{kl zbr-<raZUr~GxPOTBOr@R8ST{TO2kR(S6Q^qrs0Q#(q3KTq&PKgkv<~{Oz{s`mr&~5 zx6cZ-RtOU)mBjTj5gZ)yt7k9mnB&y9v?%86fzSNyt@-%7;hZ)yr&Dvgmms=w3&rc7 zmD9K(aMu*uo?HAw=Fg{kz$|E%9lxZaF(Ff0h4;&MYm=_cS$Da2n7dmPI+Z&ujYr?m zd>O$xul*hoy2RP1S;>+Ad&qjuirJ-Zv6zOsPE?3ZC2C4^=y6*X?~r>&sNJGZ2C9TY z$lpKsC)miCb!honV?-|;3`XdF@*#Z*m1LTM{)Iq)3kwlv&>{t(BvGIHJ@AV~l8))W z&8yFtI3fV3E&mC^7tfyS{nH8UEXz?>EcNmG2Lf(L^9zb<&`=7<uh6M+sT;G^3ZIJ) znOPqE6V7wDHYQwO5##iut+YLO`^yzJ0lOqmeC4XO0;dB8^LZx5#xZ?07Ou+#YLT0E z503nq16y8XtGo7(nf#_(_9>;wd`0%Lu@Iwn_8KfNw0$N;5?Z-_#hJUep5tDt|G`cb zYM1Gzr=YzpYr-7?H~xGG(5;-NAYQxY+6p-%#s5OtU8jZ|YTIgrZtD(0mzLPz8@YKJ z72m4~a>i1Uz@-m1+r6cjpFp8j-F6u(9dKm43AF%AnR6`qPIbC3ecEwRJt?QO)Y9_1 zbIr?uTJfAgIPf|vkC+BEV#VC}iAzWu^9UKdDoJg*Xl#71c2>Hvx71qU;#aaiFcGI) zz4mEs!k00TqqxnCK%ul4-_jBv*PB*uKldN(l84WEHb$kNc4Nb*4g@nDCi5_1M;>22 zW9|ImR!M8EZ`^HUJlRK(`c8+Lq|Jq`v;BMfG=M&dM!6mlpraxW&|9%yR*b*f!X~5L zzo$qe*iDRS%eLXi`->Q=3ia}UL@NfbIkuf=Q;rMAUMt7#;Gb&Azb;v?koo+<vKL8& zf>ByNSiUh+O>@2_$osy~wcE9BY)fR;B&<%k)x<&vKgcp7@fZacfb5|Z<mu*7U)(mn zJwJa&d}EEI;wL+0Z13BP8eZmsIJ-C%Hxv2*tT=eI=)|EmBqk<~GJA8l6$ILdWdU7G zEinqrc^$LE!Nt-!l|Tc^D-4~RQ_)xRMw!W(Kc<FBR^oJFn-*nX0zO$Juw4wo?%(4N z?4Bcv{7voiwF0hEKFPW4lmxjQgK0&sEBUgdlZ2Lq#xA`=>!)2oK6?-V4#gpIgq`DQ z8s-{Zt!WZG^(bLMuL6j7c0uNKwUu^v15Ku^-Ha>KNn2;9m!3ON#=)9Ays*XCZ5jdO z=Q2FIX+h*rOXn*%(3W>n=V}lZZRI;`@godIyVEv7K_X-YQvyDfZ~3jDc9J&+5<I(O z;_S8R=i@fC^4+H65w_4ohW!Nu8x9aC6Om)-To8MD!=$@AeSxs|3N3{f{J5Tcc}sM@ zoU$_t^k%``A>oj+s6MlA6x^){+Ad!+2ox_q%`MENs}y9?SJ<~<g^&7$rMx>b9*{W= zCQXAs*V40c0>BF`LDrCYD?ve98ohgVdmuOw#=L@u$0ikKr3KC{;n@pylxac<WboS) zt8-NZRpEOmCE*F_DtzU1hesVG4)mpU9FnHk%*$GG>l<tPJB+k{G>`$sG*o9<AQ3t8 zlX?mYE_U^4Eo+78_ODYZO%-tRo8X3tRQFy{*rr11SV=5`s&-^sq0d%Y<xZRsSYk*h zo)$`7T$$GBt>j0EI=LTg(7w%NtioOn9H+D>IQZGA%5Mv;Z?@<n!HONI!10<9&to4& zr8vpl5R{cfP5qjWRb7~At!xy=|G-_eYrPv9_}O5`sR@j{3;C?pPp&8ywP&HfvBJ%7 zd_*o}W4Tw(AtC$7N<m9|GzMeTanZK{h4hG={0>SJnpPMC^RdUnTvwzgEMy<OH?gJ- z#{cSi)L!}{pmhEPcWhmU`rmsfrj%8Gt^BPm)Hs!CD5s(AZ0Xvht(uwkG35(0#y!^q zC<@OYIk=m$`XV{GjHSf;?xpr^d4`~lh*hiYZNf4wCXE<iHJ~pJ@2rAXAJH4*LjtAc z#>GMQKWNV|e;osj{0z3Yj)xe<BA(Jh%f}4Oxl!%HpY2}B8p8p7$yT3IS|}MQXbMNa z@eKsDT8Qh$$J#TLDo(b}{lDRM3OH)HX(i)Eu`pB@dIlayPv0y+zn#hHs!C0*EVx8n z!&BC|WMQGVcf9?Z(k0ItS8zFA0JFlb82edju1t)A#`xRF=Zi-E`J=+11{EdGGEdIU zO|bwmb{i)}&WOSg0q8FPrU{mElokb4E?7Rvbx*~uP9cI`oG7)hrl53j`-B_N4bl)} zNf4gAx`6|TTuu}?xt|;dO%$a(4?<vC^hN1~o{GF)tHNOa5BM}58oGeEmsyJ(L=OKw zPz1wEa3NtRD0{0!%})F)h;IR9<Xfw)%~b-8rMw9Y4=Y7?tX_vLqlfhIA=&5xtx{Mw zGs)v<q0aFVL{R5(ICo;j@|O+mD<SWRjOX_s;KMF5`>u~~EL|+oRJ{J>xtYD;2=T0U ztPf?`_lG;@Ho^Pd4V0hIp)a>peJ3_Za1lWqG~$MV*JAsHRDc+X9^3m9V}!8=dvvc^ zJ;tMwcO@9xj1RzTwEa)TAFAv6=C@~QH^KNcf?^xn8Tg*oi=jr!Xwd%oUXd8kya-;S z>3^^Q#b9X5$H!ziBBVD84Rk&8Hqre-2F$A~qobzG>FJ$q2G$L?nECJYNOT|SH7EIa zmz$3-NEzyGgYmd;Z{PW#>EX~)U7VY3L+xz8Mt(JC2nmT=mQe|}r%Qj_l07NBf8+y9 z?$20?R|t`y!aZ+6?^C6?iV&?ISz6;1XFn2;EW9k|0G1-U=g$U4fVtY1K=J*;Z&ht( zJ(-Jo`AXXy%iV*$<s@xX1nlE5Lo~qp?09$X|A-R3VX#?pI7wqIrzYKM2b+Ug1c;zh zwL|_B%1}fV2Wj`N{;f3I8(Rz>f!`zT9AAtX7<oucuLB_$>r5y*g|m0jnFo=9|4hVv zT&7;ev#uw3)lr+Hjn&oso5!UzeED@at10Uv0nX!k(M5I~!?IE6orX0WRH4M`F@e9> zr;5ze%gd-p0dY?eg|T50k#xx{O6VOl@?F3(?|Bg3<y?!W$5l+{?g!RiUB0H_k`zrR zofWbTxAgJ{Z+6NkO`u!2kJ)af$fwj_U!2VRk33lTIy$>vSWI70Jh54g>d8!3oQf%$ z@Y#b)?#!$LiI&E;<fhZ#J0E9MR3SzW#KZ*a<^F4Iqnw$-SLXfIjQLZzbMsm$cx)Tp z5_(@JaqiNd`)|#4a<|8al>4vE)Yzhfh{aYz%@}-7wk<oB!%DU^g*`LcpETaHF2X_J z;tL)!JBgYlJ}dZv^hNFD1hM`OwJtMN-XyUf2wH>H#^V;dBhQbPZ3RESXOYHQy4-d? z1VGg39u_C_d&MQ5MR%y8Qf9oM$wc~L4}W|1?aAl59saXjq@ADX#c0v%*Rr>~|3+`x zmHy`%lm9;jZ}NzD`FVJF;H4A(0uM#6F3mFT*5%;j;#j!Ckt}6iPR`H2olyFDS2JSF zg7i<iqEcV+vV(NN-%Q7LrJO1SDV+@Rf6^5r+i~$72M1~YYV+`66$|deh~41SkE9FJ zA0AsNX5kSLp<yzA6_m`I;I!w$!k+)<dd}}zIv|kW`0r|7F8)Y;yuAFQdruzTk>n-c zaFzsv;!<|C%B|#-l)YVeUgaeo3SSvK$uYZ936zQt{}3c>ZYIEH-jBb3aRG=T*Zkgg zRy@d2SJz;|(xeCidtEd99bYRzLL#W&7=DYga(ZSbloxkp66_qpk8A6vDE}4|I{vf4 z0Ph3bH2zOk4*4&B^Z#xMlK-nW5*Ivs4J)$I!TtE#-pZ7JS7qRrQ5Ztu&<$T}di%tx zLI%y>2bW#oY4=)O<5SbwVFvf1u2C@dk@~t_5BX?F^}|q4K~5|)aXDt@-A$Ok=4IF; zP++dQBW!wII6uYg6D^%YB>I(if`k<HFkjQLWJf~!uK`a(^Zg@ki>q{ISGu!4DJZaY zBQ4A=c=g<>p25k^7RBPOr#q{cy@7TR*1zcMYM)&!V7VI$3>c=JMFe8H11BoxPOSv8 zsJu}U{#F+Gp*spMY$BU!-?3qV(R<5vS=7pk3E^@uTsb(6q{~lYkg7ad&Jq@7rD{T6 z@Jo_)GW_lUwV12czYYo}9Y~{oD}0?XRG|_p@J++Pc7H&H*B2761jX>U3q~oJ{Y2p> zMC5l?iZtuC!)RHVIha`Q6-I)~eAkVhSd#7!+!w|uNPLo624>1bMtq+Z3ou&5M+l)w z>BurIvs9WN|2{vWGMwX|21va_=$}mf#4Pv|h9p2YR*({v-9gPMjV|*`tQvK6^CYct zTSNFpgSO4F)oVkA32C4Dg2k*<Wq&JUlM~JO9%yUEgl_M!0(DPbQ*8|=Ps+GX-o8er z{e)3%8FCnXdcKr?IAVtp7QZQV&tVhMU&86^xINwA#ZPk}DXS<)KiKc&dGdf%(ZXRh zX_mFn{46T1Dn%c6ydz*>+9%5V=&G}tg5X64)uC6$3-vZ-K)$L`+)Q8a-4X4WbnL*1 zNWo*V%E!{u$P`a_u+mKQFP=utG*|L5U5>%n)u6cKqpE^lOq+UXu<Sd^1s=_0eOHE7 zI}o!{xbxJlJq{<C^=Owd5mvds%TOC4)S=fv=k6Mx91GXTs(0DlBmYy&JXFiN8vv8L zmDM0zvzxZat68LV^=%~!n_JBoq&#LLgqRL07KJ*!y&}q?(UU>-MZshB63{^fe|9aO zzq5)A6*LT2_h6urXmlU!?Ubo!c;p*CUF>GCxJNTN)z!MMuyHMNk+NE!AB)iIuXRon zurgju5h-GrWU&sCO>HptOlwq0a-pNEi2c2QU9Q8CvsnBdBEdgD73t_^8BLzTGs>s1 zvWDfP8K#zyHCyej!vp*-E{l|-mA9CpmYI>PGOx$xkbh=uttngqv$}b-JSC*^r*lvP zNf=d6$m~6e%0=?^*ePb_#ZiPY*#Lny@&{2(>SwtLpL03>+Ay|z*L8b5m919Osj@0$ z^EZj<csNFyst>w``?Fz#bSltreahdn$U<g0LtkoOofFt{DvIv_mn?s$+YhoK=p0Y2 zEG$J{kEDW~W?1802H>IRD7<mGZpd!A-Jb#|XedW%l7BbVD>nz~q}Cd3;@rpX*-#<2 znX5d_kGSy0&Mo8R(N%ue@RY+n?yrOb-p%{uXJ>wuk*m0Op9nz#%|@fU=4(qQ=QBAj z?%5PMdI+#mf#b?B2&O;xgG!q{jrUvq=?XHST*M@KktIe_$~*OXjFYF3p0=-slQIdi zlsd5O`L)pCjI>}i2WG?d0l?|z^>s@tUuiTlM@1rjkCr7XDJgP_YrVIMiQK}{A`Y!& zQ3Q*6U}9n*teUQ9n@TS2z(gv_MRHKZ^oTL?x{5+s#D-tAE(;7abSl1bV4>s2Z~<LC zi7R8Z0c$)Zv|n~Ae${uWJA(Acmtr*X;!PzP`vYq(Mc=@A$7S?G@8+Ma(tf@-5ffsV zys2L|bLBQGGn*&H!pUQhz7>{HjB)WcGB?~uFNI*L^<jr*;3jAcmyboV@vchqcRKn* zC28JHno_#r`dQf8t2oi~wvKG@&Ymd8)*c{-|M@%V%>yLvF{{tYZrChg#&f+^+X_b1 zf|c6Uy!*0-{r=R$$I_sfmplY?I?VF{07h9I397^iY=+FEe9Xx$y0C$fvhR@!j042i zV{@E3p#2>g!KgUZ_|o9tE*RtK8|j{g+zy*_A8}$KR<qS#U9MF$qvLgjP$YurQnp7L z`@d>d!@~kZr|iws4W>;aT8GlUIduBv+Mg5@bag9@3$psbBGy#Ct*&zCo9>&#Ss2wS zC}UP(!n*Y(IFhW>6dN1TDv@+0xQKE1)+sCO%Ol~S7LAU=HH4bBj2*EoeJWNCl^uAV zHOg2^ot19A;?{v~Jq_vMbnRITMp^1$dF9ti3O;7N^$Z-8vD~O>*_EWM2k-v+(($y* z0rW>+>v$TI@T8Tl0#BJN>OXPTlbdsLcQ@x!&bJh<<0kXfw1fNchx2B~)h503uE+Ee zmFhL_?&kpMjA<K<U_smNInIDf=2D!aK0}WR_2%&~@=C211|dxnl~1LK4)0Ym;_*@T z>`c3@yv{>5YbzUuYP^GOG!QFhne-&b8yIdMluZqPDi5_R<0p=@T4CD`WNZ0Z9^6yS zPQKnN*7)F1SE~X>?h7fEnpLdyx<;3BB5Nq0%}7*Gmscn2a)k}L9O9>1m|FD&CnUmX zLMQ_D|Gw|LRtbFl_{(wLOaDI{d3OE=)wdUf<#%^eBbJ-pN(nGuIt@BXC5Zj!Iwnw* zIy-l+39$7-?z|c$^M`Jdg}Io^+Wx#Qts2d49j<F);Ke;30g+!Z?+y+1WD}*^nkqEJ zN~5~1Hj<{5of)>7&Tao-JeQCj%R8*~y`&glSrKPX!?gaoFqOS6cVO;uYh#g~v5Iyd zk5OKauhMw&$UkHMlj{|6{mMF4+=B@AcE$Xi)(j_}0bQ>Jt*WfqC@qTyABPSmG`vJr z3OM-n2Us7>fP$@MG*NY9s!X43jlJlsJo#=OG$C%oTc+g3dfN9hIV`1#qHd2~Aw_yJ z2l%@DaAIh*f4YEM!MU#D&R2^d3#6zPK*f}|Y{;@xr+n=e%rk&eVnbV?9Bz=}2|zP0 zq{sp*OA)zh(J5U5lmeZ{<ENB@Qa#$(-_=bfPMP~<3aZMZVP^2z2ak#f*BzS1fXI_R zk)yN@2QxomP(`xsv%Tvir?b?HccJ-vynZpa5`&0K8MX}1^+vkfv>{E1SNaSP$l9CW zyw15L)2*ewxm*Js-b1DsT(_&-1C=WiHfxxSTe7*$zN_`lN?&@DP%3p!I#9*|eKDj# z`E_IiYape*-zyYx>FV^4_OzW-b@80ggC$SWq}_|PUvAw)wUBuj+Djuvh#8G}JdX6f z_}R?H5^a~`Li4%!S(=@M+4<p&KehMm`l8PpGx#=jv0p%@z}-5y&`USZY`E2gK){*N z$B&gFz#*y=?-~B9sO)P@NpUOp@ss=e1X-9yq<M$FEBHQR(IHP}CvB`BlIbR<Idc^p zMx&LLavaGtBv5^+-2Zq5qE+i{^_04gyn~cGHyu54*iPRJam-tv)5w2iA{XN}Gpz1u z*=4tAjaG{pWoW-J*DCQu;xEZ7X_U$!rR$uc`sO@_e|?pjDJcHfK)$XlC4Mfmr(xU) zNo`wgYcw7F<Tfm&AhoBWENdv37=-%wVYlmDnHNQ$`jcg-<0Z)*&Eyky49U@vhZ|t< z(QCa52i<o~n__gHP4>#$EN<61gh+BJ8Yeq4Q}3b3l(i~D?eUMzuiF7!A@q27+*DH) zExVG)EXZ1j8tSgChCU0GNpj++`Fp*HOx8U!+>2T=1y8+(c-460wFd)R`_HnhIE=jF zawDfvYB=CCWyLkTYRLn#g`~Iy_cIjq5)AZZ{_kG_Xp8uHn4tl5h%yjnv85`gZ_K;J zpc5G5XeW{>gMhPtfbsHwumFYLdfSrUO1k_?!YIH8v1@VH;v76ykys@KAs5K3s77X* zM(&Zn*;Zm0Ve=AHj-Ws(n&)gYeWtFiLt%$C6hx%0f2JOOS2{~^J!jVVnT%||YYK2F zlKdtl;QDROoC16s5?Ku?lqF7VJy$%~3s4J+!0lkjae8xX(4cZ=wL?ituC{Io!X{wY zi1~HYpqVKHC2oGc*x1^p)&uk<dLlJz=d}7~zLpeQT1b!eq~%Sl)+SY9cHcw)=X}0% zPjm=)kgbW45!B=w%ZLF|a!3taD+pSa0pw%)oieK3b5Zlwrpue-_J{dI66LU~$Z_Pw zGPuxPNI|(&6Q0ScWPVgUEPWXrGELT%?dT7Q(;i2a<?1W_NxBidLP@R_*@sjlEc8G# z#Hf$O44;=V?+C0qxaPNn@Cy%by5IMrVH7*Ed}7e0H>*~+9z+UD40j{tMyhg7kkh5k zshDC#xgA(gGT`N~2^%KiSQjw`qp}%eKj7Ef?8Ec&E)$_|p#-))wHdz+H-DW*URqQY zjmLMKhD|fz&u*RDt0$6bsR9*Dk+3%NEey0s9d{%XFsexC%Io(Z4{8<Aqef6_B$8v1 zEr~(QK`+Tnp%+yq@OM*nm_P2;5xuqgzHl-uYza7)C{<?}3LA=9cG-Pkm<DoL&r1>8 zY1f!9yc@hLYn;h<Oe~K}YmV;qF19)SJWJ7*30D6@%;6!{*Y{RH5zNOcP@0Jgj;yuP zh^M-6Fjg>PLTVbXNL0h_vR=3#;4fA?oiB`Fej{B_`=ueB#2)7iUH|VysqJ8GZG9RW z>wU*(s(APFwS}upgAd<X74V&j&ej!0sbT+4R0ADWjns0kvY<G(){VR1Z7qY@^}uA& z%sFS-X@l@DxS#uC=ls>HLcTd_<7{-hzJu9Ji<}@**6wp{;?>@ETDu-QRDc0ERIKGL zET&EMqX;o$T5F<i=0}s;ZV@w@*XuY@|IiR#jAFlIl1HAf9vXNw>dO-sd;qvmkkV~p z@;lh{-H25VUwK-K2mlFP-l+-(iu~>U3&^{_L>Bnx8?XL<lz1`zU6u3yn?HRj`D!SF zAT~EQc1}~n$mn01OF2bFX6AkHDx0;{pFYC9_@Zlsp#m9=$GhD|c(r3ZJbc_840xlX zM95+y0Dz6bYQ)~2CT9b@CS`UMyl5g;g6@p<)Hzg;>LbcOBOB#`W!ddT-Sov|!f^2L z)ZnnjKO#*%5uZMP{#-Q!C-}Vhkx0NHd(rm%cnmKH`EL+|nkH6VOY0N-syofhj5-!p z!r$KHa~}T$l_$Wpp#OCRu17pIwM6+Z0jFfRl+?mCe8)L~F)=Zjo3|r~z09`zv)vBA z3A~a26%7aRe->PZ+zKVicP-A}p7uiXRcQVNS@0cZe*e)#JIMX{Qc1d7FX}Uo?8plx z5i*3&!(m^^rHUeZai$h2{%J3JGE?>ks5vIZWqt<GWft2u^y66Ij9bf<^JR~Iwq##L z|43uOmw$bAIJ1kN$*q91VsZxspLz6~0~s^JX}wXqOe6yA<%X?^>4ilIXxSY4a&lU+ zVoTC;FCOLU8?76o+Wbpdn(OqZ-Q10*Vt{W^QjZ5d=Hr=6E9lr9`coNSQF+U_z<9B^ zjLbUkrynAkgVTya<=*eNABf!9Pc<zTzuh0je)y*g7dG-=+84@8TNI}4vYScbnBLBv zrG#*jyIdjcymo5X>M7^B`o>6B_`#t1?VMLgOSq(ss-m<asa3noi1>k!kr}FDQcg>P zBZsabTd*|y_4yDSs#}&bdo<X;&8_^VN79rU@AyRM@dx^|R0Jg)5pSPd%9i@z^UPnE z06rIC7|FtgEjqw7d%*0)1#=-N;RiKieBaK!($UmXG_2;0UwE-wa!<Wn{VTG>pE2La z@%xlvQ*})`;vV~!(yKaJP?A@E^_x@J*aN86Vn-i(tPv7Hetp32Z3Be;Hkaj$LodBK zVpNuTAW#1^sCjT2)xMxYga0nhWYqiqJ(lw8J5FTU{dD&O{1DMU)phLoy@s|)I)eiv zamvf84>`KlD~nzYE3~CG<F-qmH&&+@TEFkZmQ_F2qc^xj;>OtwkT&dW7#V+aPQF9r z@r6+<!}k9@wuw0S*z!Bx<*|!1MOeSZ$6ShDsAqvV$o#4QgfdDpP#r(fhQ;!>$)o85 zoY~_<yIDl8vOhO4kbc2e&@IX7<QMtI&BbjHvXD0+FA;PX`9$RQk00~G97M$wAR8nl zhBOIj(jI#0_Zra+`Mn*MG(O_Yhy1g_MIMg`Mc?S=`4yoaYf6Qw$z=jylU7`oD}cSY zbE7Kp*IgQZG#FoFzheLlhkn{kI3)_2eZS9&1quK2kiKd0KfTE7WE-U#K<s{eZDejW z|LnRnDg35a^_%>Q3FZ|P{gOS~!31YRYU#le1r9jPemp&X8Ov{B0UXQ-vs@68>lx@M zt8Lli5d)g&s?J3SB8I{VB3X9gHmA0N^)LPYY39e2=PRYYWQ6cp@`h@;-BA{<T-I-2 zaHC^fys~SuZ%KL)y<_?=lJXl7sA1FMavxj^Iq~1|d(l15l?Q^gw$V1(lDcp=?qe&* zAirD?xgu~&o!AfO?0PW>oM*)S__D5RP1xItT67d78b2V|Bm5(9_ygPP)l2ap8_U6w zktT&w!kIInL>}>xmrm*P3@q&y8?r?ljE$wwNskM)E89E?+qg^<RhL$UF@El4evK0> zp{WFuZV~BkUD+M~QAv9-w}!NUAmZ%qhe)uPu(7Nd-MenPSe~xM^Xm`x4W`UL<1D`- ze}%#x&(f#TRWZ`2da5pvDCR)Be?2cQ%o*PH&sWTw;BPd%u+s&fU`Lb)4dLf>WB<Rc zXbA)Pzcu%jQE@H%mn2+Ba0qm;5C{@3E*&5cB!S@W?vg+w!D)hoAPMds8h39jxVyW% zHg1i}G?4qB_12p8*1Y-f)|^k!r@FeTPRZ}=+O_w+E-S*;8Ry?PC)b`6u=DZpd8c?F zGHg)%kSvD~-ov|}I*~Dh+Yu+-?xv@GrL2MijyEsf|3RO}##9iFxp#2!J(gTv9`#4! z4){5w71+;f3sZQ0x7abA&fn^c4GtEUmQwst&GU<&#`R8Fte97jl;|QrN4ZOuFL-^P zaq}}#ATduN+XtIW>H%9uCyvxdSnbw2bBNN{&JGNSA(FoTiYVWK6LMaDeqLS=Vs)55 z5__3yZfyMFj|M+dEqdaE6y1MGQ}4f_$G9PSfxg-sPA-ccQ~3t^QT!#L>BX40;^Ws$ zSiKPr2L;fTm353yjB}9JG_qwE+f?NJklI5r2fn+;McSBlw*E^buGDgp5Up&p@bc27 z)EIB?3~DS-v$?14LP|T>fi`?yo2Qmm7?MFY88630?X)ul6V!>8WL0;O1U^rt^_EY! z&^iZ4b^8TM);O)O<W$GHy!LlOC?mJIEI_;BLv!b6Vsmfe^go+25bz0DSJi`X#%g|a z>cz(5wF%`NgrvbpqutyF%@=(*Zd9a9PdbGzWi!?ZROqo#C<_}V8*c<T&yP0I`x81> z&+9h2wqV#JfESvzheW`$BMy9X@>!X?anq1G;7`TMd%8d~{3~mYzxf{e9n;};@7OqC z;VCv_Y2CRrn4Ahn3AS=s{Sf1l=uKMgmPc2Mo3R>`o@jOD6a>O~EUxV^vg@U>c-*<` z&Rr`fM9EF-;7umZ2#&$S6B;~P7WMCq@FtYqnX_9ln-$9ILdgEvEVo65Z@*M7k1%P^ zRA&9vhRJ3~k3q>*F!TItw%5ct@1CVfVz`5F4yC&=cq)0ID9e8pM;?88w{?<AP5lyw zCh{%@LK<MM1>;~2_Y97P0YZfswaKy{eOu#y)7|Gjw-m~&kXU)Stc<66N-ln?!B!(p zs~ZP4>dv?(R)`AhD3B&EWnMSh2)afShBK0$vMGMg3@$aZ4XwNCiKB^UXY}OCOR$tg zchjk~bM*MK7{qZ?bJ%jNFOQ~PsX&Q){#PGlr(bfoDD4f{ed55YbOt>=IlaU7qK4aW zTW!b|L}(cnpw5<<ShOYPu{;#qZd{-ZkY7B%35u-aHB+KyGyhj;dpbh|&P|Jt5i2z3 zSfQjlsEWh>ORR^U)`YTtp|ubk8+w=~q}gnc6;z%6`K(2~Q2NU%omE?&4m7uqR!%K6 zCPZ1%{6|3I>6*Eth{{HleI~tfnhhLOkCzFa9=|9lF?1mRSrwzK-p>vQe2NJ<wfWK0 zN`c9c82bvJF*3F~D&H?GN-}#}ao(PxRt%cb6m%6AMf1u<^b`$<c>js=V%B!`3%GS& zHmDApWl&8txC~xjhlqEilgxuIu0q6_d7Vcn4;pR^*N6O+ctsOoN8f4R7H^^VznCBe z@0#iJb*rp!`<e;43Ad|m$Wiyo{MP6uSz=fMro%!-3vzzyEyb0+DzMX07^90dA1YoQ zXD;o@peGKGQ0%rj{PmL8{V`vSLZYk9-VHvTI!&3BeXr1KzerO}6)TBs<xu?YwO@Lb zwe`kjEV6N61JTb$&ib{<;nBC-3-29)CYguPZxI8Fn9!C!zXkN2237yA@04~JRzLBf zId%;tfn+oN)|fM~dmmQ{(pD2eQKWzxMrnnWQWF_>cG@Re`7=;DSW@b=w*Cxc;A)K) za9R<GBPi!vGI%u%Yh~kq3>f{fXR;d&trMKmT><uqib*iH`s~VBRz5Eb`*pT-lz^sC zo<LQ<^X(&esXUTY)_7DCo7CWS@7rS2Rl-p3Q&3u72V<6zTGhm0WeWe-)AeHt&!Hjh z7F887v~W7<>9Py|<>)SOv&aN}iTiB18GN^AZ4scXKXc&4Qy0#ZTE|L7`6eeRs1r)C z4~vTrA|fZ^Z47NstJ)1i_et$PBm8k-R<h*q1H!O9Kt!KX75n9HM!U<5fwN~rx+_~* z)-SSdHbe6-pFtxWj_ZJ%8&mdbg35^iKxjrOK9Ukp_a7_(UCcsWaH7r@MZy?-l@ZJZ z5u@5I(IstU;4ZT;RMTkf_0raqHB#DdS#JN?s|1&5yXC1(;YS+EMT;$C3{C6^P<I3- zNSI*`{yu1mYBPpva?NL~!V9+5&Rgr!oTq&oSu`SV%WY?a){>tYgS`=^>rGCwZmyPs z6DL$CaH*(<usLO){Qlpj!`Itt@JZUSd~8WNeV!m(c8q5y`8t(U;!~}m#+q2gK&9Cp z`X*O_yXQQ$dVmls?_3__q8kz4+QTUo!w4%FdnT0VIG(p}FdLv%YxL<=@{#04Y~H*7 zBW7DwuhM69lx1nn)ZH@(`kvVlG#8gaCn&{G4**?{D1VV>o^dKp5z`Ru8L?tBM;>?K zPlRx)MB7@O-y_@s_XsyPo7GK?P3LYN(3b|^d?ya1r2Ao&AS(CUZs2$%wKk&yn-8PL zku}IWU3^_Z;^*Q<@HnIWdSs$z^-6q%msgW7{;1VqyKCu*v?{<gTI^S8idO3(94zm& zGA@|D>@|6$`8o|;TRG-`W2H@E*tw}@`hf|c$5Se7F=j;z9nmGOLOW;dWg1Ns=6L4W zY5PoeKh8>Yo_@Fz#|r=Id<y0OU+337>=iZ@Pms_E5ktZ0HpL*6byV;(vyBoq{v<&= znO)JehT+;4_@ykZEwu}Sr%sSd+r&V_!rd|PmC}*K)>h;(mb{CDDjbB+;+$#|0w~#f z|8K;dD>rR!JYbc_s*IsF3Hq(fM*O2N7|hpyDonmu><{1__qAP<PtIbdJ(eo)Bk@zO zo*K{Nw^$AvweI}Hu8Z&R7P{$>Ib@;$7ETD;XZ`DL?MmW%sryY{B3&Wpv}?Jnl1?Yx z&9^_(^GUdcNf))<H~CRzg;zg1m$IuXd4VrIBSywSHSHhL&B6Yw{Fl9^G@6t$J8G_G zPv$=@#yMWcYO`cB%KA;Yv$HYfW|f~uaw0!B+3k0%q7zYPsTIQ7DC*t7<_Yi3tgeB> z?N1H76qH3(W5oAjbIQMy7%Uwy?Vb87!;d4FJpi@wUadf*L7H;&*hc&T40bG7Cg})6 zwfXO!@XH`-t<KJD^B@wRkCVx4L|(77O7(k*bih+{EOkGzFs?^kmkCs&FZ*ob>YQ{s zt7g&Ojniyz3z#>yGrU%Jn4#>JOZcY5Th%n;*L6|#?)X>fPvvkbjpvJ!dqmE?x^L<X zrn9r8b5n?-SPIli26B%WMnVQ-8Q?w!<o1?&MH@ERV;eSa^UGG_`~BWo=dQPu)eP%u zsLIkb1D^yXN>zs`+GK(=BNJrNl$ih@v%S(RO;P*1LU4V<B&74oS1U@1Jv-$_$HyG| zzTXY4fggP3NL0Q2`0=TfJ~Bc*yYugw<Z!x1R0giUnwe*)OdjUY0c<4F07?Q;4*)KN zrO?7%i_Bx>(Rajgf?a{t7+Oe$!)01eOn$tBuGCuxv!xDSZDzXKDgirPEpOOQQw-NU zdKq&*$Z)}S-?jQZhHalGnMI=UEIX|R5~O|l11|=X)3b|u^Cd@fh%AnX+^9-bIb)*& zt;f`3GmdvAt|;1AFZ)9Vd5;^7%r*tMDnztDjFczTM-gGi{{9@K=z3LNgqeaCZfx?Y zJ2Os37>BXwP3beuv%~i4YxKTtjSASfq-ctb%lx*M+$E<T=MUzn{-%(F?`z8qZ%T}T z>UI8H&eF2;^`=4}#|lNm9?#NFIyechK)y1sW4pI>tgSR~+Lju%>U4?s(36{v!MIKH znfetH0Y+;3Vd65q?>-2J-f;Ds&-@E^t^siz*BT#tKQeQsAdV6#IRRfq8DYmX(+WbE zkGcT?kv&9=LeCNW4+N~Df)K(^W$f=&65!6I23BZMTkgWf2wS%2VzffTA;Q{k*9FMg zwP#G6JU_wAn*F-P)GDfETIhdA<SK~bXT<sklTp#GPmD<e9J+EpN&HL>uFvZINd7#y zP9S}yr;Zh(=DayR74=aOK>#@MmnyC%(=Q7;{Hzv6qLh>=U)-aX^F5b_&&drS`*z4T z(i*lBB;EC@XS+qPiHNiD=w^1F(G1sjBwBLgT+Ce3(eXozZ|<~8p$z^>VKlUjQDbSB zhBM%j<CPr-RiJXHopNhY?1EwU>#zbYkx_rM)L#+T$<rm<Er#AXYlPW+*<vYsldRjN zB1e3z$tXGB(+KEkH2i#~i(&Ff%qQA$FG>CY+qvzsWT_6i{{yV|kzr;YaOQ=R3YMJf z6g=kC#^s<-q35pDcf3@khdwLWly=>n4L4k4Z=2m$5Nyk!>F%qXX5FIi_BHJAJ6G8$ zZ-X8Ij+WhO?b!Wjl?CWL^nq=CDz)(=p&UlQG}FmQCebi#)e*wT^`>%$ofowkmmFL- zyV9D_bGWHeNAU|TA9UH+1c&Uply4CDINa!NV;gCs#QEU0o2kY`)YF_xDJ5<^(xzS4 z3xqV)@85QGvb@%Vemj~`=jHXmt>!H~>dhDUkt+&8L#|UtQN4tnvE}$Gd0MP<#r#Ys zN^uHr-43RNsit)bKVcw$x{L{%%B6J>5f=^@)#P;dLgSFIrQK=Sm5z642e5w}UXv{~ zw6CS^H@>JLOmG5NPnW--BWHK>T0|Crd7E<Dz(g@<tAJV7Y1DM{p9bRq7Ku8oE7eo6 zIT8f~1Mhlm66%}=Ka0A#?zVabnA3%~njF@wxnJ!Xkwd5#l_VZb1D$%?hrQ#5k%t|6 zw%^l6<*>dwG16$gHE&0eebE%1v3+G?m7z>ghM`@c6c3-yMx1%V!;Js!BwQ4epB)+F z<6^v<T|^dN-nxbxfA9(@%;&TV9PR-c!Hn=EZ4Q)1eDURJ!|0VpI`D#Nq~F$A438E0 zM_%a{qFnMod1{tM1%R(qTM2`$t17VS_ELi9$@V&OqO~N>c9zlw0h$Bn&j}!xAcp5o zhv}-zG6V7NROMs^hNm1&_Mdue4jo7**B8GID6#0wVq9$DPPHID-c6K@rY9~aQE?%- zs)>Aat)#_ltF|BtT5~+t+p0RuMS){7gi6n!t5M!RR^NYY3eG^A(9;4f;#Ta*BGlm3 z(Z_I8&1g4>(dBMiWSz-9u23rcz9FLhglIJr;i1B26`+3-x@@ZO*!35b!o*#$_REPB z%e{Ohl7%PU9bXJF>tc^Q?OFaBz<&Q<gRU3S0|N3N3f}XEA=xhbq-ABLm8*<RO#FcY zU@&458w(4j{Jg&q0K^{b8VP|ssMNdh6cqG{i1;9^^zKSs`a^I~PEk=)%_+62YOL4d zDMF~<@FG-4IGvC)9)5MykM<XGsLowNZ1{To1r@(d8ZBH{q)i!tEw>{Ga+TJpA4Nq) z8693B(j=|=VBufyx!+cUOAz9k$27IXdVYS?V`B&i1Yx{}jyO6hEKKtNhkVsD0~sUA z@o=ZD%?Ckxd*JCk$|x?zJH59Y;K0PhBq7;<FORgLxzGK8*(7n`>LGGNz#X9f8y1;} zm0QRvzV)et+tmTkG*SYAX(KM#YFYxl-7Xs$(d!6>gK@(j*x|s2k%5l)qDPeI;zQZX z2j2FM4><MbGFp7SO-mz_SxyK1gV+@o;6in<OJCHi^fxx5zn?)tP@pB<9o&OpLzK{3 z<Me350zn)+o+6lU<YvSIBx`nv_QRHu?2#%FJWW>(gH5g}+xPIYh+OWlI35~LzJadU z?okJ%@Gibg_o}}u1<Z!$Vd>ToRN?xoFssdXQ??Y5J_M26>U8Q{^jlA-KQAOT3eCK5 z8p-9^_V9dyFiuy|;2Nl_PJ8G&uG9EWSsl0Ntw!La8<ri^Js#yQCQDf23D-zGjWhX` z*117^1KmHfg<`fnPIM?)s1)KOBf=s&NcO`@@V*XAsC$kW|8152D=?Y}D@CFAn%B1C z^;X5Oy8DE4-3G&es#wA6^j`v^I{UT@o4ClSAKG}t!!*&qKH<EFQ;?Y8e`SQwS*gyy z)>7o;a}6*xqtWZapkcqbiKs5)qK2C{Qc!J@WfbR!=QsQ`)}zMtMP&z+*;`mf%g<HC zDL9Rf+5T)uvZyTc_O?OR46XKLoBn3JNnt}iQphf9qv^VZVT+U~Z4_ByU3mXWfWRKF zs8}5%{ZN~Xh~LcL2%-QyZUURScxYc%i%`lJnOk7NiesjY$Dz<8>d^{-dln(7)9D=3 zS=VM>X}seT@b5BzmJuF!1;ERq#Ug>K%_tt)!NhY;M2t(8QRmS|ZjTOt^E}jT=a?E% zw`|s?&w+SSRMQ@)-dxlb`BGLh3Pt&UA=~|gGOiw5dG~y<)G6>pCE1*jIHwaIttyAI z)AGrhvJLglBpEhp&(7MgoNgQs4<^^8*0*avbZL!EG^tm^`U>)b_EyY<wha^>jR{Rn zn%-ePkIIp=uWTx0bW%siS9Up_LfGQPBkbX)BD%X{E1BAgSevZiy!51-4Ais&k+G^G zXaN*L^kuSF9=1!a<S>|g&&)#_Pze@j*kHvv_Jw}17HA}znmVaZa4eH+ECvkVH`rmm zMUKg-nzo@yQ1cstnnm;`uN1tYU3F}w;HqF=!YCtg3<)oWvNA9gR>{cg#zsdvEC+i~ zeob9lkC)f1nGUvSpt$e;No9}*0`@f|L(b0pJVl;T%%BZS+^48UMzb$B7(csp6hA_+ zlCEj!cHg7J%R<9F6JUX;g8eVM>m72FcgN0!xO-{XP|xdDKz4<C36Er`+BUVMt52p6 zT2RT#2Pyj3`7G3X_Yj?H1h1eOY35<BOlpO^|2C)}KLstZwH%>;QtlFx9u#WZ@M68( zAM*<d_i%PE#_r~=u>cp-S*6S>H)@Za`E{J>3dPGUirvzHlr<5!Hr2X^cHqo?6~2`_ zJw9!~C7VlX6mg_MNSdx3{MK}2SdR+QD?;IKz1t~6dY{YZizI}Vj%foZ&IJ}I^F{?5 z%g=OOT$hIqU@f!U=cBQUc%rGWF9~g^JfZE)?-w{M*&ljQ{;AiW4YG#je<L?6V#V(* zB`YhN{Fwrg;l7gG-vk#I&VP{P=4ES;nc3a+#0$vD1z}-5dDzfH4k#;A)?dWBo8x3r zHv6mc^B;^?fDM==Mh88>eyyqqVZ_b%Jw!KWNJ!Xi;vYXKbzh&>N88)kF)}gz@pbW8 zTI2kf{P}FBVk9h#-COX(-B)tu-0QLhme%`ebCq(Eg`V8o$DAe#iWtYlb4eEJ^oB}U zalLtS*F*y^5oP6_Ljr*q7#M63E5#{qSo`0a>gsX`=a{?eePPpj!~I|X=~m)@15y5e zBsV()8wdci)c4gw+L@eC3)Mk*<YW-$qTGKpK%5bB-v$1Esq#YTZ)+h1B_#z-29UWq zwY#LVv$KznmZqj81H&T^o$n6=tafiGJ<sjhPD?u>FaQ$^^SE<9>|a9$F<BLPZ*o&V z9xxZpj=OQi&oSpVm!zP~YRiScL<a1JrvEuVao-HiXm{J%QEJ<Q?*q+n>3i%F^>2P# zm*{swtF1qEDt`QQjB%mKc}!{~>@1Fmr`+!11Ei$Wncwm$si~gFLt{nyDTv)|cP^_a zhZ3n~ft&M)bVBqpQ7o$(VQ0X@&^pdYq4X^)qwzQ~H_!9)lXz2`J4NcoMd!^MxT_<U zaT4@DM#0i$W$aW`LXUTd?{~k)jte$FQ-hu1yK{@L-R^#QLpm@p(0#i4q*`B3Z(tzl zz|`E`NavMo;oR)I2Zq2m+HH40<O*!G`s<H>6Tk6#-*1-PjBOU|IA425>%<(|OJIS` z)Md%!RJiutRV!~?QdU_X-!J2?g0q1b0%UKmBn?gid3**bK2?O`fB#g=`cpcI0ol%k zc{T4>n_bE7xZGE+Wf!3d9Jv1a?PqFPzK4?*4dJTc#n-x4d1%+(5-f~VR0_6KKz{xs zx|ew8{uk0$0ghi{`6G4Ax^F3bc&K#7+&ykF&ovvK-j|Tq)IRnJr^p(e?_dYbd_Fc& z3w2lA6{upuGkY<*>Pi=T`;v|gxF^EL2DLkiCw|5|=HXnsRu7uL*dRRdiewqRC9qzc zVqzcI@m^@f(6#ye5}I9o(p`rvKx3@Mph_|czUY052G++_1T)a^FjDf+q^1R#!cMxb z(i`WHW65%cYI<N1AQTS!01wYvT{MV5?{GlQVBpWw`3Vhv8#p1$=nHJVFCSp1t2qAJ zi34W?NV9|@^4DhqZs1Jkp<qYSCmUzMgLFK$(Ijqcq{jQOp&J(P#uO31qGn#ej7r6! zs4+O+n%L*P0B`5Ma!GY421sXCHvceSk7v2W-;Pwlh^md@II~#wM(7qrl}zYbz)yjs z!d>~4OnV!6Gaq|(h>8~f^)inZv}$hB9L&Mul2RoNdHSd6@l~Q7IS)`@nU61o6nl>N zem6DR<D8JXPCpb8S;I<?%uL+VGXYDq_?&V<Y6aNC9c^~TY{$*AP?Rg!WeT;wo@tP2 z&y^vQUxO@+C=+xTpM)KPDwL#NXNynX6rMU>g?&H;J98IFDq!b<K|7P0UD)>eVO84! znAwARy7i$d_TzotZpZ2$=W4yvd^P9Y-M1=hNC3k>Td8Fwn#n6HZ-Y0xf@6A}M^h8$ zcB<J#Be|Ktf{uShTG&K}W=58o^ekARnkQzYj+-b)egy9yYYW<m{Kbx{V1=nCMI!Vm z*&i=((hkX>W<kPFft0fUmTh2IZ>RCm?Xy`;<@M3tnj&FmL7^eJn|jp4G`+u2@5T^> z(YQD88BaJS0XF9*0s2JWD}fhS^6u)<2iK&xJYWWvBavAQk^DUz7t>WoNnJhN>6@{7 zN~@WUo?Lls6_Z<n(0ppf{`7g*13v(VlY(lyQTU-QW#23%W<_hFi%_kat^N)v$W5F# z)~0*9@EY~WMLy5ORT%Ut6VYX2tbtUrJl!7S8mem@A;zy*__#VYI#&sYCJ4?Ao8u8j zVj<VfZX9ahDz{a?D*VdhcdP5G2KbfE$p}kLQqj7MWlo9qFSoOt42tT)>c=Ey1vgJi zd^A9{(Z8N%E0ZbVEKpnJEm|nCaD1zzo7>QpsiM-dKZf3X)=`|_5AGO+%ARuQ6i~=w zKTJ)$))IkMGjB<sO9ZB`%xB4$)uk!S>Hb<@JAHwWFbm1`lwS#qtJ1VrQs=UgTV|EY z4Ylkwd@IGt2gpYdN1Qj~0|GJHENUv8djqSm;|n@}PPi^a_kh5w_DqGWo142<AuvuV zqqx%~S|Xje)$RJ7sL8Xnlp8A<L-cki6`8$Gg3G1cF0lEw@!YN)5}(`m{yK^V4!?wL zm1$P+Dj!G&HO9*Xh`+3=;Dvj6&G5{BDUZSBONa%%y(MY>VmoB29Z$45uUmX#H``?q z$Sr&J;nBmAyl*7`$g@3dkH51&SCOY^+6#HLSC`ZBZAh{K&dchzEg-#FSfFM&LQ=Nh zz_AWXID4dqsck{M`#axWAfyNt+aR3ubiSZ_qQYSdrrBb?l1Jm_89Uxo7u*5TRec?Q z-ZCs%GOdoaHD`WinR?^6=wro0>~ewAT6jq`pT8v_c<WA#XP*eE0|5hTZSrJPK?=)E z(pEgMI#%iW#?UTgM;KeI$kLnmYS&PRzL4Syr@GM^Fr0ru3Tj!QBh-xli`xNb*W+%1 z{ze<Hv;XVD?YeXzuw7AOPeOhOnS7{5bEE;I+jgwRlm(3Qaw2u3;SH3eBcmC|6$ewk zU#`1ay`9sBsD<*QvaLTR$@b=&$Svu%9%qsEjr<sgtch(5?z0yQ>!zPtltSx1e+zP_ zu+6%_*Cw%5{$vXyHn>2BENX5IA+wYP&gU0Q<0bc44jgN-(=Wa;dK2Q2in(!a*xFTe zbewR3tZk2(9T5gzA0Bl)`K2-%R)<D){}!?D#rEX9&zXj2_5BCwuH94J*>+BYvC$Fy zAH=t(vlAagFl}=A+3dR82-X5yZ26pvprQNep(Y0ck(qhd<6BRh(lXLa7HY`dVqn}B zc|rz8I#*L%mcLG3wB&Vm_W+%DeptOGEz5ptn?!u=RZ`OtNZS2m)cD3G@L1RxImXJ8 zoV9b`y~1yAEX++1WG1&19B?EJSapPr=x3e6)*i9E*{C^&wl(@q#|AzDs#`*MkkROP z3V(~u4<FWRR=Ud}GhRUQ_8eF(W7%}eUb{XM(Yu>F7JLn>y<HAw4Orl{H1s^RxN~}3 z$#~OUEJo}cZ&PbRkB3>#x1*oSkoIhRFcpFL*Pp*`>24GQZ;5o~^Ry*3s)$ILky^PO zHA79Qytg$?4-UkMxqde5F*sa)Afu`ve&uH3B?ffkj#XPHdA4Ny@dDB|?Z^VDpMD=0 ztG0#SD<&_|JXOhIB{GxWq2zMmPQPg%UyNE<b+fl%ChU_zryH1~OR2QU6`#e@HCniO zrFA-cF7R{^tRHvtbm+HDJX99D=^xjWyZRs<`%sCdeE0l>yFtyky?+ez(5|ETbkwOB zs5t%(hZ*B(%y&AY`-J}<=g54BC3*Gx_oX|Ba~)5yABZf@;SdN!aPSF#QEjmN{X0Y4 z+|K%@AVjCO+VNqe4#Ye0T1rdnUK5<sW+FhJfiK@O9EopZB>yE1f<%JgKjD53Hp53m zgwlKLI*=sbn(*P9A*>g&J7h4ve=<YGf;u5iNiu79Q4Va@-`3`(rW%@>4)(HNY}HXX zJFn0+o4_p2;*RMb!leykOG_aFKc9IwNhUfv#lHzw_WY(Cb5QycWmU43gnnS}x-GiN z^xNcEZSKuvyhDfx9C>_<mxpJbe4irh%Wrafj4_nEPh@=8MjNh5K9%5-<IT|**~bn- zLR9CPL*wJi2dD_Tqq=(R=@$SZ{@f&g)cb%KErb?9p-DG*-*mkHO`!H4@jeHG8wVmK z((i**q$HeF1OI{oO95@|gzw)eACRVjAFJzxn;X2tvahSP<>c<bImC6rN{?{#?7RRF z5*iz8(>#3WIuXgB>hI@gw`xNSC;#W`002O7Q8-gqfGjdcJo)nrwx;lh<i~vRoEE<R z@0cRTj#KOCn3=_7WO{pQ1Rw5R#2g=Y)6w15TBrWJxFAMGehw!mBTK-ea-pQc`NwtD zXsHE8$O5@t4i?BNyyU32JKdcHjk9M;p;ftX-#gSHI_#s7iSCuoLY;cZ<S(7Sc`#8+ z&U1ZGy+7KdW~@1w!kBPy5T|ADuKgAB>GI_k->l!ibqUa0YY8<oLdsUxID0xf)hUXK zN=iy9D$;KboOu5v|64qL=;}%kUjIETENtGrzq8}_h<+^dV@z+7C^oJNTwksDxSOop zT-9u)hX!7dH((_)=af{f&{a_}F*P++42K@E-{K%4-QE@?`|KggfO_{vi;Q#|F6Udh SgSB>7EOB9(j|GBy-~SgJNWshi literal 0 HcmV?d00001 diff --git a/docs/plans/feed-instagram-nao-aparece-home-ui-draft-admin-ok.png b/docs/plans/feed-instagram-nao-aparece-home-ui-draft-admin-ok.png new file mode 100644 index 0000000000000000000000000000000000000000..5706366896004e2d326afa16efb835940f06a8a6 GIT binary patch literal 91416 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 F2>?V6U)TTu literal 0 HcmV?d00001 diff --git a/docs/plans/feed-instagram-nao-aparece-home-ui-draft.html b/docs/plans/feed-instagram-nao-aparece-home-ui-draft.html new file mode 100644 index 00000000..b31fbf71 --- /dev/null +++ b/docs/plans/feed-instagram-nao-aparece-home-ui-draft.html @@ -0,0 +1,269 @@ +<!doctype html> +<html lang="pt-BR"> + <head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script> + <title>UI draft — Feed do Instagram configurado não aparece na home + + +
+

+ Assessoria de comunicação configura o feed do Instagram no admin (global "Feed de redes + sociais") e precisa ver, no mesmo lugar, por que os posts não aparecem na home pública. +

+ + +
+

Cena 1 — token recusado pela Graph API

+
+
+
+ + Configurações + + / Feed de redes sociais +
+ + Draft · Salvar · Cancelar + +
+ +
+

Feed de redes sociais

+

+ Fonte automática do board "Acompanhe de perto" da home de campanha. Sem chave + configurada, os cards da plataforma não aparecem. +

+ +
+

Falha na última sincronização

+

+ A Graph API recusou o token configurado (token inválido/expirado ou emitido via + Facebook Login — a Graph API só aceita tokens gerados pelo Instagram Login). + Enquanto isso, nenhum post do Instagram aparece na home. +

+

+ Correção: gere um token de longa duração pelo Instagram Login + (conta Business/Creator vinculada à página) e atualize o campo abaixo. +

+ +
+ +
+
+ +
+ IGAA...abc123 +
+
+
+ +
+ 17841400000000000 +
+
+
+ +
+ 3 +
+
+
+ +
+

Instagram — posts recentes

+

+ Nenhum post sincronizado. Após uma sincronização bem-sucedida, os últimos posts + aparecem aqui para marcar os que não devem ir para a home. +

+
+ +
+ + +
+
+
+
+ + +
+

Cena 2 — sincronizado com sucesso

+
+
+
+ + Configurações + + / Feed de redes sociais +
+ + Draft · Salvar · Cancelar + +
+ +
+

Feed de redes sociais

+ +
+

Sincronizado · há 2 min · 4 posts

+

+ Próxima atualização automática em ~5 min. Os 4 posts mais recentes estão no board + "Acompanhe de perto" da home. +

+
+ +
+
+ +
+ IGAA...abc123 +
+
+
+ +
+ 17841400000000000 +
+
+
+ +
+ 3 +
+
+
+ +
+

Instagram — posts recentes

+

+ Marque "Não exibir" para tirar um post do board (ex.: posts de grade). O board pula + para o próximo elegível. +

+
    +
  • + + + + Caravana pelo interior: chegada em Vitória da Conquista + + há 2 h · ID 17841400000000000_001 + + + Exibir + +
  • +
  • + + + + Foto do plenário: votação da pauta da saúde + + ontem · ID 17841400000000000_002 + + + Exibir + +
  • +
  • + + + + Post de grade (sem legenda) — para marcar "Não exibir" + + ontem · ID 17841400000000000_003 + + + Não exibir + +
  • +
  • + + + + Agenda da semana: agendas abertas em Salvador + + há 2 dias · ID 17841400000000000_004 + + + Exibir + +
  • +
+
+ +
+ + +
+
+
+
+ + +
+

Cena 3 — sem token nem ID (primeiro acesso)

+
+
+
+ + Configurações + + / Feed de redes sociais +
+ + Draft · Salvar · Cancelar + +
+ +
+

Feed de redes sociais

+ +
+

Instagram ainda não configurado

+

+ Informe o token de acesso e o ID da conta para publicar posts do Instagram na home. + Sem configuração, o board funciona com artigos e YouTube. +

+
+ +
+
+ +
+ (vazio) +
+
+
+ +
+ (vazio) +
+
+
+ +
+ + +
+
+
+
+
+ + diff --git a/docs/plans/feed-instagram-nao-aparece-home.md b/docs/plans/feed-instagram-nao-aparece-home.md new file mode 100644 index 00000000..e467f93a --- /dev/null +++ b/docs/plans/feed-instagram-nao-aparece-home.md @@ -0,0 +1,93 @@ +# Feed do Instagram configurado não aparece na home pública + +Status: aprovado +Atualizado em: 2026-08-19 +Issue: #115 +Priority: P1 +Model: cursor-grok-4.5-medium +Impeccable: C — encaixe na global do admin (painel de status de sincronização) +Rascunho UI: docs/plans/feed-instagram-nao-aparece-home-ui-draft.html + PNGs embutidos abaixo +Appetite: ~1 dia eng + diagnóstico da causa em produção +Responsável: — + +## Intenção + +A assessoria preencheu o token e o ID do Instagram na configuração do feed (global "Feed de redes sociais", entregue na S3) e os posts **não aparecem** na seção "Acompanhe de perto" da home pública — em produção, o board mostra YouTube e artigos, nenhum card do Instagram e nenhum link "Seguir no Instagram →" (verificado em 2026-08-19 em jorgesolla1313.com.br). O desenho da S3 é fail-closed **silencioso**: qualquer falha da API (token recusado, ID inválido, rede) degrada para "sem cards" sem deixar rastro — o único indício hoje é o picker do admin vazio ("Nenhum post recente"), que não diz **por quê**. A assessoria fica num ciclo cego de tentativa-e-erro de credenciais. + +## Persona e fluxo + +- **Persona / contexto:** assessoria de comunicação, configurando a global no admin do Payload (grupo "Configurações"), sem acesso ao código nem a logs. +- **Job principal:** saber, no mesmo lugar onde configurou o feed, se a sincronização do Instagram funcionou — e, se não, **por quê** e **o que fazer**. +- **Fluxo desejado:** + 1. A assessoria preenche token + ID e salva a global. + 2. O admin mostra o estado da sincronização: "Sincronizado · há X min · N posts" (e os posts aparecem no picker, prontos para exclusão), ou "Falha na última sincronização" com o motivo e a correção esperada (ex.: token inválido/expirado ou emitido via Facebook Login — gerar pelo Instagram Login). + 3. Com sincronização OK, os posts aparecem na home pública em minutos (cache revalidado no salvar). + 4. A causa da ocorrência atual fica diagnosticada e documentada num runbook curto para a assessoria não repetir o ciclo. +- **Anti-goals de produto:** nada de wizard OAuth "conectar com Facebook" dentro do admin; nada de dashboard de saúde de feeds; nada de embeds/scripts do Instagram no site público; nada de métricas de engajamento. + +### Esboço de fluxo (B/C/D) + +```text +[admin: global Feed de redes sociais] + → salvar token+ID → [status: Sincronizado · N posts] → [home pública: cards IG em minutos] + → [status: Falha + motivo + correção] → [assessoria corrige credencial e salva] → [status OK] +``` + +### Rascunho UI (B/C/D) + +Painel de status de sincronização por plataforma na global do admin, embutido junto aos campos do Instagram (e reaproveitável para YouTube depois, se a paridade for pedida). + +![Rascunho UI — admin, falha de token](feed-instagram-nao-aparece-home-ui-draft-admin-falha-token.png) + +![Rascunho UI — admin, sincronizado com picker](feed-instagram-nao-aparece-home-ui-draft-admin-ok.png) + +![Rascunho UI — admin, não configurado](feed-instagram-nao-aparece-home-ui-draft-admin-nao-configurado.png) + +## Objetivo e aceite + +- Com credenciais válidas (token gerado pelo Instagram Login + ID da conta Business/Creator), os posts do Instagram aparecem na seção "Acompanhe de perto" da home em até alguns minutos após salvar a configuração — badge "Instagram", legenda, data relativa, clique abre na plataforma. Sem ação manual além da config. +- Quando a Graph API recusa as credenciais ou a sincronização falha, o admin mostra o motivo em linguagem de produto e a correção esperada (ex.: "token inválido/expirado ou emitido via Facebook Login — gere pelo Instagram Login"). A assessoria deixa de ficar cega. +- A home pública continua fail-closed: API fora ou credenciais inválidas nunca quebram a página nem vazam erro — o board segue com artigos + YouTube (comportamento atual preservado). +- A causa da ocorrência em produção fica diagnosticada e registrada em runbook curto (passos para gerar/validar o token), para o ciclo de tentativa-e-erro não se repetir. +- Guardrails: token nunca exposto fora do admin (read da global admin-only, como hoje); zero embeds/scripts do Instagram no site público (LCP); identificadores em inglês, copy em pt. + +## Dados (intenção) + +- **Vou apresentar dados?** Não — o painel mostra estado operacional (última sincronização, nº de posts, motivo de erro), não métricas. Nenhuma decisão de análise desbloqueada. +- **Forma:** adiada ao plano de implementação — sem contadores, sem engajamento. + +## Direção no codebase (hipótese) + +- **Áreas prováveis:** `src/utilities/socialFeed/instagramFeed.ts` (onde o erro é engolido no fail-closed — fonte do "porquê"), `src/globals/SocialFeedSettings.ts` (superfície do status), `src/components/admin/InstagramPostExclusionPicker.tsx` (pickers/superfície admin já existente, mesma família de componente), `src/utilities/revalidateRequest.ts` (tag `social-feed` — o salvar já revalida; não espera-se tocar). +- **Precedente a olhar:** plano/impl da S3 (`docs/plans/secao-conteudos-home-instagram*.md`), irmão `youtubeFeed.ts`, e2e do describe serial da seção (stub IG) e smoke do picker no admin. +- **Risco de acoplamento:** o fetch roda dentro de `unstable_cache` durante render — qualquer persistência de status precisa respeitar a restrição de não chamar `revalidateTag` dentro de cache (precedente documentado da S2/S3). A home pública é ISR; revalidação via tag já cobre o salvar do admin. + +## Dependências + +- **S3** (pai, `done`/`in-prod` — imutável; este é item **sucessor**). + +## Fora de escopo + +- Setup OAuth / "conectar com Facebook" dentro do admin (o fluxo Meta fica com a assessoria; runbook documenta). +- Redesenho do board público ou dos cards (superfície aprovada na S3 não muda). +- Paridade de status para o YouTube (pode virar followup se a plataforma pedir; o desenho do painel é por plataforma). +- Backfill retroativo de snapshot. + +## Rabbit holes de produto + +- **Dashboard de saúde de feeds.** Se alguém "só completar" a ideia de status, vira painel de monitoramento com histórico e alertas. **Corte neste item:** um painel de status por plataforma na própria global, só estado atual + motivo; sem histórico, sem alertas. +- **Wizard OAuth no admin.** Completar o desejo com o fluxo completo da Meta explode o escopo (app Meta, permissões, redirects). **Corte neste item:** credenciais continuam preenchidas manualmente; o valor é diagnóstico e correção, não aquisição de token. +- **Investigação infinita da causa em produção.** A causa pode ser credencial da assessoria (troca fora do nosso controle). **Corte neste item:** diagnóstico com prazo — o que não for descoberto num período curto vira instrução de validação no runbook, não bloqueio do item. + +## Questões em aberto (produto) + +- **Onde a assessoria vê o "porquê"?** **Opções:** A) painel de status na própria global do feed (ao lado dos campos do Instagram) — o lugar onde a assessoria já está quando configura | B) só logs/exceção no servidor (exige acesso técnico — não resolve para a persona) | C) nada além do picker vazio (status quo). **Recomendação:** A — o fracasso acontece onde a configuração acontece; o sinal pertence a esse mesmo lugar. _(assumido — validar com produto)_ +- **O item cobre a ocorrência atual em produção?** **Opções:** A) diagnóstico da causa atual + painel de status (a correção de credencial fica com a assessoria, documentada) | B) só painel de status; a causa atual fica para followup | C) só runbook de credenciais. **Recomendação:** A — sem o diagnóstico, não sabemos se há também um defeito de código por trás do sintoma; sem o painel, o sintoma se repete cegamente. _(assumido — validar com produto)_ +- **Paridade de status para YouTube agora?** **Opções:** A) só Instagram nesta fatia (o YouTube funciona em produção; o painel nasce desenhado por plataforma) | B) YouTube e Instagram juntos. **Recomendação:** A — fatia mínima útil; paridade vira followup barato se pedida. _(assumido — validar com produto)_ + +## Referências + +- Issue pai S3 (#20, `done`/`in-prod`) + `docs/plans/secao-conteudos-home-instagram.md` e `-impl.md` +- Rascunho UI (gate): `docs/plans/feed-instagram-nao-aparece-home-ui-draft.html` + PNGs acima +- Primeiras pistas para o executor: `src/utilities/socialFeed/instagramFeed.ts` (caminho de falha silenciosa), `src/globals/SocialFeedSettings.ts`, `src/components/admin/InstagramPostExclusionPicker.tsx`, `tests/e2e/frontend.e2e.spec.ts` (describe serial da seção) +- `docs/AGENT-OPS.md` (serializes: nenhum recurso compartilhado — `serializes: []`) -- 2.45.2 From 3ea16243cac0ec1a9028620e2a0f8fb47f3a0bfb Mon Sep 17 00:00:00 2001 From: Francisco Solla Date: Wed, 19 Aug 2026 20:48:46 -0300 Subject: [PATCH 12/37] style(S11): prettier no rascunho UI do plano --- ...d-instagram-nao-aparece-home-ui-draft.html | 92 ++++++++++++++----- 1 file changed, 69 insertions(+), 23 deletions(-) diff --git a/docs/plans/feed-instagram-nao-aparece-home-ui-draft.html b/docs/plans/feed-instagram-nao-aparece-home-ui-draft.html index b31fbf71..8a9607b8 100644 --- a/docs/plans/feed-instagram-nao-aparece-home-ui-draft.html +++ b/docs/plans/feed-instagram-nao-aparece-home-ui-draft.html @@ -47,27 +47,39 @@ Correção: gere um token de longa duração pelo Instagram Login (conta Business/Creator vinculada à página) e atualize o campo abaixo.

-
- -
+ +
IGAA...abc123
- -
+ +
17841400000000000
-
+
3
@@ -82,7 +94,9 @@
-
+ + diff --git a/src/app/(frontend)/actions/submitCampaignNewsletter.ts b/src/app/(frontend)/actions/submitCampaignNewsletter.ts new file mode 100644 index 00000000..f6d78dc1 --- /dev/null +++ b/src/app/(frontend)/actions/submitCampaignNewsletter.ts @@ -0,0 +1,50 @@ +'use server' + +import config from '@payload-config' +import { getPayload } from 'payload' + +import { CampaignNewsletterInput, campaignNewsletterSchema } from '@/lib/schemas/campaignNewsletter' +import { requireCampaignNewsletterConsent } from '@/utilities/campaignConsent' +import { withPayloadTransaction } from '@/utilities/payloadTransaction' + +/** + * S9 — public home capture: name + WhatsApp (required) with an optional + * email/state/city/comment and the engagement-level toggle. Mirrors + * `submitWhatsapp` (fail-closed consent by stable key): while the admin has + * not created the `campanha-novidades` Consent row, the form refuses to record + * anything. The toggle choice survives as `subscription.campaignLevel` — never + * a `supporter` (jurídico-blocked). + */ +export const submitCampaignNewsletter = async (input: CampaignNewsletterInput) => { + const parsed = campaignNewsletterSchema.parse(input) + const payload = await getPayload({ config }) + + const consent = await requireCampaignNewsletterConsent(payload) + + return withPayloadTransaction(payload, async ({ req }) => { + const { comment, campaignLevel, phone, ...contactFields } = parsed + const contact = await payload.create({ + collection: 'contact', + data: { + ...contactFields, + // Same shape as the public WhatsApp form: the phones array with the + // captured number as primary (C112). + phones: [{ value: phone }], + }, + req, + }) + + await payload.create({ + collection: 'subscription', + data: { + contact: contact.id, + consent: consent.id, + campaignLevel, + comment, + }, + req, + }) + + return { ok: true } + }) +} diff --git a/src/app/(frontend)/styles.css b/src/app/(frontend)/styles.css index 1400734d..16b5a783 100644 --- a/src/app/(frontend)/styles.css +++ b/src/app/(frontend)/styles.css @@ -179,6 +179,10 @@ body, --campaign-band: #ebe9e9; --campaign-line: rgb(0 0 0 / 12%); --campaign-content-inset: clamp(20px, calc(25.36vw - 79.64px), 180px); + /* S9 — the "novidades" capture form sits on the light band, so the field + border must be visible against it (the :root default is a white border + for the dark WhatsApp page). */ + --field-border: rgb(0 0 0 / 18%); } /* Campaign home geometry is interpolated between the approved Penpot boards. diff --git a/src/app/(payload)/admin/importMap.js b/src/app/(payload)/admin/importMap.js index 343d05e0..2f6f0ae6 100644 --- a/src/app/(payload)/admin/importMap.js +++ b/src/app/(payload)/admin/importMap.js @@ -35,7 +35,6 @@ import { ExportSaveButton as ExportSaveButton_cdf7e044479f899a31f804427d568b36 } import { ImportPreview as ImportPreview_cdf7e044479f899a31f804427d568b36 } from '@payloadcms/plugin-import-export/rsc' import { ImportSaveButton as ImportSaveButton_cdf7e044479f899a31f804427d568b36 } from '@payloadcms/plugin-import-export/rsc' import { InstagramPostExclusionPicker as InstagramPostExclusionPicker_ba03418db242c21470543bbeb06827a0 } from '../../../components/admin/InstagramPostExclusionPicker' -import { S3ClientUploadHandler as S3ClientUploadHandler_f97aa6c64367fa259c5bc0567239ef24 } from '@payloadcms/storage-s3/client' import { ImportExportProvider as ImportExportProvider_cdf7e044479f899a31f804427d568b36 } from '@payloadcms/plugin-import-export/rsc' import { CollectionCards as CollectionCards_f9c02e79a4aed9a3924487c0cd4cafb1 } from '@payloadcms/next/rsc' @@ -77,7 +76,6 @@ export const importMap = { "@payloadcms/plugin-import-export/rsc#ImportPreview": ImportPreview_cdf7e044479f899a31f804427d568b36, "@payloadcms/plugin-import-export/rsc#ImportSaveButton": ImportSaveButton_cdf7e044479f899a31f804427d568b36, "./components/admin/InstagramPostExclusionPicker#InstagramPostExclusionPicker": InstagramPostExclusionPicker_ba03418db242c21470543bbeb06827a0, - "@payloadcms/storage-s3/client#S3ClientUploadHandler": S3ClientUploadHandler_f97aa6c64367fa259c5bc0567239ef24, "@payloadcms/plugin-import-export/rsc#ImportExportProvider": ImportExportProvider_cdf7e044479f899a31f804427d568b36, "@payloadcms/next/rsc#CollectionCards": CollectionCards_f9c02e79a4aed9a3924487c0cd4cafb1 } diff --git a/src/collections/Contact.ts b/src/collections/Contact.ts index e7632362..2add3a38 100644 --- a/src/collections/Contact.ts +++ b/src/collections/Contact.ts @@ -171,7 +171,11 @@ export const Contact: CollectionConfig = { type: 'select', label: 'Estado', options: Object.keys(CitiesByState) as (keyof typeof CitiesByState)[], - required: true, + // S9 — relaxed so the public campaign capture can store a contact + // without a state (optional field in that form). The staff ficha still + // requires it via `contactCreateSchema` — precedent `phones` (optional + // at the collection, zod-required in the flows). + required: false, }, { name: 'city', diff --git a/src/collections/Subscription.ts b/src/collections/Subscription.ts index d7ce4106..e85955cd 100644 --- a/src/collections/Subscription.ts +++ b/src/collections/Subscription.ts @@ -9,6 +9,7 @@ export const Subscription: CollectionConfig = { }, admin: { group: 'Contatos', + defaultColumns: ['contact', 'consent', 'campaignLevel', 'comment'], }, // Citizen PII. Public opt-in flows write via the Local API without a user // (overrideAccess defaults to true), so admin-only access does not affect them. @@ -39,5 +40,20 @@ export const Subscription: CollectionConfig = { label: 'Comentario', maxLength: 1000, }, + { + // S9 — the campaign home capture records the visitor's engagement + // choice ("Quero fazer parte do time" vs "esporádico") as data, so the + // admin can tell who may join WhatsApp groups. Nullable on purpose: the + // WhatsApp community flow writes subscriptions without it; only the + // campaign newsletter schema sets it (zod-required). + name: 'campaignLevel', + type: 'select', + label: 'Nível de engajamento', + required: false, + options: [ + { label: 'Fazer parte do time', value: 'time' }, + { label: 'Comunicações esporádicas', value: 'esporadico' }, + ], + }, ], } diff --git a/src/components/CampaignHero.tsx b/src/components/CampaignHero.tsx index 09734909..4585a8d5 100644 --- a/src/components/CampaignHero.tsx +++ b/src/components/CampaignHero.tsx @@ -102,14 +102,14 @@ export const CampaignHero = () => (
- Conhecer + Receba - bandeiras + novidades void +} + +/** + * S9 — public capture of campaign "novidades" on the home: name + WhatsApp + * required, email/state/city/comment optional, engagement-level toggle + * pre-selected ("Quero fazer parte do time"). Success swaps the form for an + * in-place confirmation (the seam where S10 will fire `Lead`). + */ +const CampaignNewsletterForm = ({ onSubmit }: CampaignNewsletterFormProps) => { + const methods = useForm({ + resolver: zodResolver(campaignNewsletterSchema), + defaultValues: { + name: '', + phone: '', + email: '', + state: undefined, + city: '', + comment: '', + campaignLevel: 'time', + }, + }) + + const [isSubmitting, startTransition] = useTransition() + + const handleSubmit: SubmitHandler = (input) => { + startTransition(async () => { + try { + await submitCampaignNewsletter(input) + methods.reset() + onSubmit() + } catch (error) { + console.log(error) + methods.setError('root', { + message: 'Falha ao enviar. Tente novamente.', + }) + } + }) + } + + const campaignLevel = useWatch({ control: methods.control, name: 'campaignLevel' }) + + return ( + +
+ + + + + + + + + + + + +
+ + + + + + +
+ +