From a41ee0d11db131ab6f70e99b32f45012bce552d8 Mon Sep 17 00:00:00 2001 From: Francisco Solla Date: Sun, 13 Sep 2026 16:40:21 -0300 Subject: [PATCH] =?UTF-8?q?docs(C155):=20runbook=20do=20backfill=20em=20pr?= =?UTF-8?q?odu=C3=A7=C3=A3o,=20changelog=20e=20ajustes=20do=20plano?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/changelog/2026-09-13-c155.md | 1 + docs/ops/teqo-1313-deploy.md | 62 ++++++++++++++++++++++++ docs/plans/backfill-acervo-falas-impl.md | 4 +- 3 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 docs/changelog/2026-09-13-c155.md diff --git a/docs/changelog/2026-09-13-c155.md b/docs/changelog/2026-09-13-c155.md new file mode 100644 index 00000000..d3a44917 --- /dev/null +++ b/docs/changelog/2026-09-13-c155.md @@ -0,0 +1 @@ +**C155 — Backfill 2011–2026 + import de produção do acervo de falas (2026-09-13):** o catálogo do C153 ganhou o pipeline de acervo completo. O `pnpm camara:import` ganhou três modos: `--all` (54ª–57ª num processo, com relatório por legislatura e checkpoint por legislatura), `--coverage` (read-only, retrato do banco por legislatura: total, com trecho, com vídeo, com segmentos, sem trecho, sem segmentos, fallback YouTube) e `--verify-links ` (amostra determinística por legislatura com GET Range/HEAD nos links de playback/download do VOD, warning não-fatal). O guard de escrita `CAMARA_IMPORT_CONFIRM=1` (predicado puro `requiresWriteConfirm`/`isLocalDatabaseUrl` em `scripts/lib/cli.mjs`) fail-closa antes de conectar quando o alvo não é provadamente local — `NODE_ENV=production` (env file do homeserver), host remoto ou `ALLOW_REMOTE_DB`; `--coverage`/`--verify-links` são isentos. A paginação da API ganhou backoff (`fetchJsonWithBackoff`, 5 tentativas exponenciais) porque a listagem da 55ª devolveu 500 persistente na página 4. Cobertura via `getSpeechCoverage` (`src/utilities/speech/speechCoverage.ts`, query agregada `COUNT(*) FILTER` + `drizzleResultRows`, aceita sessão transacional para os int tests). Runbook novo em `docs/ops/teqo-1313-deploy.md` §C155 (pré-requisitos, comandos com o proxy 5433, rollback por legislatura). Testes: unit de `aggregateBackfillRuns`/`selectLinkSample`/`requiresWriteConfirm` + int `speechCoverage` (deltas exatos por bucket sob `REPEATABLE READ`). Prova viva em produção (`teqo_1313`, deploy `424ee311` já com o schema C153/C154): smoke idempotente (`--all --limit 1` duas vezes → 0 criados/0 ASR/0 LLM na segunda) e backfill completo com relatório por legislatura. **Resultado:** _preenchido após o run_. diff --git a/docs/ops/teqo-1313-deploy.md b/docs/ops/teqo-1313-deploy.md index d83eff8a..3e00e3c8 100644 --- a/docs/ops/teqo-1313-deploy.md +++ b/docs/ops/teqo-1313-deploy.md @@ -430,6 +430,68 @@ relatório declara qual base foi usada. Não há escrita; "rollback" = rodar de novo (idempotente, read-only). +## C155 — backfill do acervo de falas em produção + +Operação de dados do catálogo de falas (`speech`/`speechSegment`, C153/C154): +processa as 54ª–57ª legislaturas (~1.011 discursos) contra o `teqo_1313` e +imprime um relatório por legislatura + a cobertura do banco. O import é +idempotente por `sourceKey` (reexecutar atualiza metadados e pula VOD/ASR do +que já tem segmentos), então o run é resumível — falha de rede em uma +legislatura não derruba as outras. + +**Pré-requisitos:** o deploy que aplicou as migrations do catálogo +(`20260913_001112_add_speech_catalog`, `20260913_001200_add_speech_segment_trgm_index`, +`20260913_145820_add_speech_search_text`, `20260913_150000_backfill_speech_search_text_trgm_index`) +já está em produção desde o deploy de `424ee311` (2026-09-13); `DEEPINFRA_API_KEY` +no `~/stack/.env` do homeserver; `~/teqo-backfill` no SHA desejado com +`pnpm install`; espaço em `/srv/hdd/backups/teqo-camara` para o cache de MP4 +(o cache do C153 foi descartado com o worktree; o backfill baixa de novo). + +```bash +ssh homeserver +source ~/.nvm/nvm.sh # Node 24 (engines do repo) +cd ~/teqo-backfill && git fetch origin && git checkout && pnpm install +set -a; source ~/stack/.env; set +a # DEEPINFRA_API_KEY +set -a; source ~/stack/teqo-1313.env; set +a # DATABASE_URL + NODE_ENV=production +# o host `postgres` só resolve na rede do stack; do host usa-se o proxy socat: +export DATABASE_URL="${DATABASE_URL/@postgres:5432/@127.0.0.1:5433}" +export CAMARA_IMPORT_CONFIRM=1 # guard C155: escrita em produção + +# smoke (4 discursos, ~2 min; repetir para provar idempotência: 0 criados/0 ASR): +pnpm camara:import --all --limit 1 --out /srv/hdd/backups/teqo-camara +# run completo (tmux; ~10–15h de parede, resumível): +tmux new -d -s c155 "pnpm camara:import --all --out /srv/hdd/backups/teqo-camara 2>&1 | tee -a /srv/hdd/backups/c155-run.log" +# validação pós-run (read-only): +pnpm camara:import --coverage --out /srv/hdd/backups/teqo-camara +pnpm camara:import --verify-links 3 --out /srv/hdd/backups/teqo-camara +``` + +O guard `CAMARA_IMPORT_CONFIRM=1` é exigido sempre que a escrita não é +provadamente local (`NODE_ENV=production`, host remoto ou `ALLOW_REMOTE_DB`); +`--coverage` e `--verify-links` são read-only e não exigem a flag. A escrita é +confinada a `speech`/`speechSegment`/rels; nenhum objeto de mídia vai para o +S3 (os MP4 ficam só no cache local). Crédito CC BY 4.0 da Câmara mantido no +admin/relatórios. + +**Resultado registrado (2026-09-13/14):** _preenchido após o run_ — ver +`docs/changelog/2026-09-13-c155.md` e o JSON em +`/srv/hdd/backups/teqo-camara/reports/`. + +### Rollback + +O import é aditivo e idempotente; não há migração para desfazer. Para remover +uma legislatura (ex.: reimportar do zero), apagar os discursos e seus +segmentos — as rels (`speech_rels`, `speech_topics`, `speech_scopes`) caem por +cascade: + +```sql +DELETE FROM "speech_segment" WHERE "speech_id" IN (SELECT id FROM "speech" WHERE "legislature" = '55'); +DELETE FROM "speech" WHERE "legislature" = '55'; +``` + +Para desfazer o acervo inteiro: `DELETE FROM "speech_segment"; DELETE FROM "speech";` +(a cobertura `--coverage` volta a zero). Reexecutar `--all` reconstrói. + ## Referências - `scripts/deploy-homeserver.sh` — o script (fonte da verdade do fluxo; parametrizado por `TEQO_ENV`) diff --git a/docs/plans/backfill-acervo-falas-impl.md b/docs/plans/backfill-acervo-falas-impl.md index 2ec272d0..ee0bdaab 100644 --- a/docs/plans/backfill-acervo-falas-impl.md +++ b/docs/plans/backfill-acervo-falas-impl.md @@ -190,7 +190,9 @@ _Quota:_ 1 PR; prova: check `checks` verde. - **Fase 3.0 cumprida por outro deploy.** A C154 (`3e062749`) mergeou em `main` e o deploy manual de 2026-09-13 publicou `424ee311` em produção — o schema do C153 (`speech`/`speech_segment` + migrations `20260913_001112`/`001200`) e o `searchText` da C154 já estão no `teqo_1313`. Nenhum deploy novo é pré-requisito do backfill; o workspace `~/teqo-deploy` também já está no SHA novo. - **Rede da workstation para a Câmara instável** (hangs/HTTP 500 na API em 2026-09-13 à tarde; o homeserver responde 200 em ~2s). O smoke local da Fase 1 vira o smoke de produção da Fase 3.3 (mesmo código, rede confiável); unit/int locais continuam sendo o gate de lógica. - **Paginação do import ganhou backoff** (`fetchJsonWithBackoff`, 5 tentativas com espera exponencial até 30s) porque a API devolveu 500 na página 4 da 55ª durante o smoke — o comportamento de abortar só a legislatura e seguir continua, agora com mais paciência. -- **Cache/mídia do run de produção** em `--out /srv/hdd/teqo-backfill/camara` (67 GB livres em `/`, 394 GB no HDD). +- **Cache/mídia do run de produção** em `--out /srv/hdd/backups/teqo-camara` (`/srv/hdd` é root-owned; `backups/` é do usuário — 392 GB livres). +- **Smoke de produção (2026-09-13, `teqo_1313`):** `--all --limit 1` processou 54ª/56ª/57ª (2 ASR, ~US$0,003) e abortou só a 55ª (HTTP 500 persistente na página 4 da listagem da API — não é o import). Reexecução do mesmo comando: **0 criados, 0 ASR, 0 LLM** (idempotência viva em produção); coverage do banco bateu com o relatório. O guard `CAMARA_IMPORT_CONFIRM=1` foi exercitado (sem a flag, o run morre antes de conectar). +- **Run completo em tmux no homeserver** (`c155-run.log` + JSONs em `/srv/hdd/backups/teqo-camara/reports/`), ~13h estimadas; 55ª será retomada com `--legislature 55` (a API precisa recuperar a página 4). ## Rabbit holes / Não escopo (engenharia)