Commit graph

950 commits

Author SHA1 Message Date
Francisco Solla
d46360d1dc feat(C163): relatório — frente de oposição, dobradinhas, investimentos e seções dinâmicas
- Frente de oposição: lista de pesquisa 'opposition' (fato publicado com URL+data, sem inferir culpa) renderizada na seção 2, com nota de guardrail e URLs na seção de fontes.

- Dobradinhas: lista 'alliances' (com quem Solla soma na cidade) como bloco na seção de rede, insumo direto da abordagem.

- Investimentos: lista 'investments' (Solla, estado e federal, município e região; empenho ≠ pagamento) como bloco na conjuntura.

- Seções dinâmicas: numeração por posição; Sinais recentes e Demandas e visitas omitidas quando vazias (lacuna explícita só onde é produto).

Skill, changelog e testes unit cobrindo validador e builder.
2026-09-15 18:38:56 -03:00
Francisco Solla
c2ee60dd6a feat(OPS109): painel de issues e planos no terminal (via SSH) 2026-09-15 16:24:15 -03:00
Francisco Solla
9e00de36c9 fix(OPS111): setup-node 24 antes do pnpm/action-setup no auto-unblock (Closes #1035) 2026-09-15 16:02:29 -03:00
Francisco Solla
46f659147d OPS108 — Modo autônomo por flag --auto nas skills plan-issue e work-issue 2026-09-15 16:01:47 -03:00
Francisco Solla
13aeb9bb36 chore(OPS110-F1): flags desconhecidas falham alto, single-flight do start pinado e help/list completos (Closes #1026) 2026-09-15 14:36:54 -03:00
Francisco Solla
8dece9cd32 fix(C165-F1): fecha município nulo/fora da carteira no access de update da atividade (Closes #1030)
Some checks are pending
Deploy / preflight (push) Waiting to run
Deploy / verify (push) Blocked by required conditions
Deploy / deploy staging (teqo-staging) (push) Blocked by required conditions
Deploy / requeue when main advanced (push) Blocked by required conditions
Deploy / deploy production (teqo-1313) (push) Blocked by required conditions
2026-09-15 13:48:17 -03:00
Francisco Solla
77216481d8 feat(C168): biblioteca de cortes no acervo (origem, download, compartilhar, editar texto)
Lista + detalhe em /campanha/comunicacao/acervo/cortes: busca por título/descrição,\norigem da fala, player do MP4, edição de título/descrição e kill switch de\npublicar/despublicar no mesmo /corte/<id>. Gate speechCatalog fail-closed para\nadvisor/leader. Sem collection/migration nova.
2026-09-15 12:56:51 -03:00
Francisco Solla
897154b58b feat(campaign): C165 — importa eventos do Google como atividades sem município (Closes #1010) 2026-09-15 11:54:21 -03:00
Francisco Solla
352801853f feat(C167): corta o trecho [início,fim] do acervo e publica o arquivo numa página compartilhável
Seleção do C166 ganha "Cortar vídeo": título/descrição por IA (editáveis, com fallback determinístico), job assíncrono com ffmpeg por re-encode exato e polling dos quatro passos, e página pública unlisted /corte/<id> (noindex, OG, crédito CC BY) servindo o mesmo MP4. Collection speechCut com access canReadSpeechCut (advisor/leader negados) e kill switch por status; ffmpeg entra só no runner da imagem com FFMPEG_PATH para teste.
2026-09-15 10:24:36 -03:00
Francisco Solla
19c403f0dc fix(C163): calibra link do vídeo do acervo ao t=608s da sessão 2026-09-15 10:24:27 -03:00
Francisco Solla
bbd147fffb fix(C163): vídeo do acervo ancorado no trecho da Câmara, com folga 2026-09-15 10:24:27 -03:00
Francisco Solla
68efa6eef6 fix(C163): vídeo do acervo abre no início da fala (speechAt − sessão) 2026-09-15 10:24:27 -03:00
Francisco Solla
ebf484c984 feat(C163): link do vídeo do acervo na minutagem do trecho 2026-09-15 10:24:27 -03:00
Francisco Solla
e8f85f6a83 feat(C163): vídeo e transcrição no acervo de falas 2026-09-15 10:24:27 -03:00
Francisco Solla
0f0f9a6eab feat(C163): unifica a visualização da demografia em uma tabela 2026-09-15 10:24:27 -03:00
Francisco Solla
18069dd074 feat(C163): demografia complementar, atividade econômica e transporte no relatório 2026-09-15 10:24:27 -03:00
Francisco Solla
5b801c4b52 feat(C163): colunas mais largas no acervo de falas 2026-09-15 10:24:27 -03:00
Francisco Solla
05d4ac42d5 feat(C163): partido na lista de lideranças da cidade 2026-09-15 10:24:27 -03:00
Francisco Solla
63b60ca7a6 feat(C163): concorrentes, falas descritivas, indícios de emenda, abordagem e links clicáveis no relatório (Related #1025) 2026-09-15 10:24:27 -03:00
Francisco Solla
85de335cc3 fix(C163): emendas por localidade, fontes compactas na página 1 e datas pt-BR (Related #1025) 2026-09-15 10:24:27 -03:00
Francisco Solla
ab9c164615 feat(OPS110): sessões persistentes de agente com attach/detach (Closes #1019) 2026-09-15 09:31:45 -03:00
Francisco Solla
93416cd5ef feat(C166): seleciona trecho do acervo e compartilha link no ponto + WhatsApp (#1013) 2026-09-15 07:51:44 -03:00
Francisco Solla
0c0725835b feat(B202): totais do recorte no rodapé da lista de municípios (Closes #1005) 2026-09-15 07:37:45 -03:00
Francisco Solla
e579406b1f feat(C163): relatório de cidade pré-viagem (agente + skill → PDF A4) (Closes #1007) 2026-09-15 07:10:45 -03:00
Francisco Solla
fc6846ebea fix(C164): registra canal de push normalizando expiration string na borda
O events.watch serializa o expiration (int64 epoch ms) como string JSON;
o client tipava number|null e o motor lancava RangeError: Invalid time
value no new Date(...).toISOString(), gravando pushChannelError sem
persistir o canal.

- parseGoogleWatchExpiration (borda do client) normaliza string|number
  para number|null com teto do range do Date; malformado cai no fallback
  de PUSH_CHANNEL_TTL_SECONDS, nunca lanca.
- pushChannelError ganha a causa do fetch (error.cause) preservada no
  teto de 500 chars.
- Unit: stub de transporte modela /watch (string real) + matriz do
  parser; int: caminho number->ISO, fallback null->now+TTL e causa.

Closes #1009
2026-09-15 06:52:50 -03:00
Francisco Solla
119b8980fb fix(OPS107): aprovação de produção não ocupa a lane do staging (Closes #1002)
Some checks are pending
Deploy / preflight (push) Waiting to run
Deploy / verify (push) Blocked by required conditions
Deploy / deploy staging (teqo-staging) (push) Blocked by required conditions
Deploy / requeue when main advanced (push) Blocked by required conditions
Deploy / deploy production (teqo-1313) (push) Blocked by required conditions
2026-09-14 08:18:21 -03:00
Francisco Solla
6854ede261 refactor(C162): dono único da elegibilidade VOD, start inicial do YouTube e mídia em early-returns (simplify) 2026-09-14 07:09:58 -03:00
Francisco Solla
fbe67f0358 feat(C162): player do acervo resolve o trecho sob demanda e YouTube vira default (Closes #999) 2026-09-14 07:09:58 -03:00
Francisco Solla
37b338a700 feat(OPS106): falha do verify dispara agente autônomo de desbloqueio (single-flight)
Workflow separado auto-unblock.yml (workflow_run no Deploy, push/main + job verify vermelho pela jobs API), launcher com flock próprio + Issue token auto-unblock como single-flight, e wrapper destacado que provisiona worktree fix/* via worktree.mjs fix --headless, aplica guard de banco local teqo_wt* fail-closed e roda opencode run --command bug-fix (cap 4h). deploy.yml/verify intocados; sem auto-retry e produção segue com approval humano.
2026-09-14 05:51:39 -03:00
Francisco Solla
dd8daa2420 feat(C159): Sollinha na assessoria de comunicação — chat escopado ao acervo (Closes #983) 2026-09-14 05:45:28 -03:00
Francisco Solla
03d1b79629 fix(C160): normaliza coleções obsoletas (J/vazia) do link legado para D
A varredura de produção (2026-09-14) achou 33 falas em selCodColecaoCsv=J e 1
com o parâmetro vazio: o endpoint devolve 'Documento não encontrado' e a mesma
data/página resolve na coleção D que a busca atual da Câmara gera. Aliases
J/vazio → D, puros e unit-testados; DCN e demais códigos ficam como estão.
2026-09-14 05:00:18 -03:00
Francisco Solla
e7369839aa feat(C160): link oficial do acervo vira PDF direto do Diário (#988)
- puros: classify/parse da URL legada (dc_20b/dc_20, montaPdf), build do PDF
  direto com #page, cache key por publicação, plano de reparo e fallback
- camaraFetch: resolveOfficialPdfUrl segue o redirect via .leg.br (fail-closed)
  e probeLink generalizado (Range + contentType)
- import: normaliza officialTextUrl no write path (cache <out>/diario por
  publicação; falha preserva PDF direto anterior, senão null)
- novo modo --repair-links [--dry-run] com guard CAMARA_IMPORT_CONFIRM fora de
  alvo local, relatório de cobertura e idempotência
2026-09-14 05:00:18 -03:00
Francisco Solla
4a55c43e19 test(C161): tipa os callbacks do teste de bairro (typecheck estrito) 2026-09-14 04:36:17 -03:00
Francisco Solla
fa79e4da75 feat(C161): relatório Solla × Ceuci com votos por bairro (seções e locais de votação)
A camada de bairro desce à seção eleitoral: votos por seção (votacao_secao_2022_BA),
cadastro seção → local → bairro (eleitorado_local_votacao_2022), aferição por seção
(detalhe_votacao_secao_2022_BA) e candidaturas válidas (votacao_candidato_munzona_2022);
133 coordenadas ausentes preenchidas pelo cadastro atual pelo número do local.

- JSON commitado: 138 bairros, 474 locais, 5.023 seções; Solla 27.264 e Ceuci 19.776
  conferidos zona a zona contra o recorte C157.
- Extrator scripts/build-solla-ceuci-salvador-bairros.mjs (--download cacheia em
  data/tse-2022/, gitignored; sem banco).
- Gerador revisado: mapas por bairro com dados reais, quadrantes de LQ, tabela de
  138 bairros e filas de ação por bairro.
- Personas refeitas com a base granular: sobreposição 62,9% nos bairros (vs 67,8%
  nas zonas); Ceuci supera Solla em 25 bairros com 61,6% do voto dela; redutos
  compartilhados Pituba/Brotas/Itaigara/Ondina/Graça/Imbuí/STIEP/Pituaçu; pontes
  Rio Vermelho/Cabula/Federação/Jardim Armação.
- Métricas puras de bairro + 9 unit tests; README e changelog atualizados.

Closes #992
2026-09-14 04:36:17 -03:00
Francisco Solla
9928fb183e feat(C158): Sollinha sugere trechos de falas do acervo para vídeos (Closes #982) 2026-09-14 03:41:59 -03:00
Francisco Solla
f58a712ad9 feat(OPS104): inicia o deploy no merge, com staging automático e produção com review
- deploy.yml: trigger push em main + preflight guard (pula se há run queued/in_progress; waiting não conta) e job hosted requeue após deploy-staging (fora do grupo deploy-homeserver)
- scripts/lib/deploy-trigger.mjs (decidePreflight/decideRequeue) + CLIs deploy-preflight/deploy-requeue; github-api ganha listWorkflowRuns/getBranchHead
- pins: ciSkipInvariants reescrito (push + guard + dispatch + requeue fora do grupo), deployTrigger/githubApi novos; deployScript intocado
- docs realinhados (AGENTS*, AGENT-OPS, README, runbook, rules/skills) + changelog

Closes #980
2026-09-14 03:07:59 -03:00
Francisco Solla
26a450c8d2 feat(C157): relatório de sobreposição Solla × Ceuci em Salvador (Closes #979) 2026-09-14 02:49:31 -03:00
Francisco Solla
b926e71d91 feat(C155): fallback de listagem desce ao mês quando o ano inteiro falha 2026-09-14 01:54:55 -03:00
Francisco Solla
563a407572 feat(C155): fallback de listagem por ano quando a API recusa página funda 2026-09-14 01:54:55 -03:00
Francisco Solla
4f5f32dfef refactor(C155): simplify pós-review — backoff no camaraFetch, runLegislature e ajustes de guard/relatório 2026-09-14 01:54:55 -03:00
Francisco Solla
aa540ba9e1 feat(C155): backfill 54ª–57ª com cobertura por legislatura, guard de escrita e verificação de VOD 2026-09-14 01:54:55 -03:00
Francisco Solla
be9fe46597 fix(deploy): assa o pnpm na imagem do migrator — destrava o deploy staging
O primeiro deploy staging desde a OPS103 falhou nas migrations (run 34765554681,
job deploy-staging): a imagem do migrator roda `pnpm migrate` no start do
container via corepack e o cache do corepack do build da stage `deps` não é
copiado para a imagem, então o runtime tenta baixar pnpm do registry.npmjs.org
e falhou com ETIMEDOUT/ENETUNREACH (o mesmo download funcionou no build minutos
antes e no migrator de produção). Produção ficou skipped e intocada.

`RUN corepack install` na stage `AS migrator` baixa o pnpm (versão do
packageManager) em build time e assa o cache na layer — o runtime fica offline.
Prova: `docker run --network none <imagem> pnpm --version` = 10.11.0 com o bake
e o erro exato do staging sem ele. Pin novo em deployScript.unit.spec.ts;
post-mortem e changelog.
2026-09-13 14:12:38 -03:00
Francisco Solla
3e062749fa feat(C154): vertical de comunicação — papel communicator e acervo pesquisável
Papel communicator com nav própria e gate speechCatalog; acervo em
/campanha/comunicacao/acervo com busca normalizada (destaque no trecho),
filtros de ano/tema/alcance/fase/município/duração em URL canônica e
paginação por discurso via speech.searchText (GIN trgm + backfill).
Detalhe com player nativo no trecho, transcrição clicável, baixar/abrir
fonte e fallback sem VOD. Resolve o débito do C153 (Sollinha fora da
vertical) e corrige o parser de keywords oficiais no dono.

Closes #956
2026-09-13 13:46:58 -03:00
Francisco Solla
408b086b92 style: prettier no pin de convenção do escopo int 2026-09-13 12:24:10 -03:00
Francisco Solla
fedb291592 fix(int): escopo do espelho Google Calendar por id, não por título — destrava deploy verify
O verify do deploy manual (run 34763253924, main 7ca708a3) falhou em
tests/int/googleCalendarSync.int.spec.ts ("a cancelled event...") nas duas
tentativas do retry: o spec isolava o espelho e a limpeza com
`{ title: { like: 'C114%' } }`, mas no Payload 3.82 `like`/`contains` compilam
para ILIKE '%…%' (contains, sem ancoragem) — um UUID de fixture de outro spec
embutindo o hex `c114` entrava no escopo e podia ser deletado pela limpeza.

Escopa passes e cleanup pelos ids criados (ownedActivityIds), com
`{ track: false }` para linhas deliberadamente alheias; teste de regressão do
cenário exato (falha sem o fix); pin de convenção em codebaseConventions
banindo marcador de título hex em tests/int; post-mortem e changelog.
2026-09-13 12:24:10 -03:00
Francisco Solla
7ca708a3cb fix(C153): colisão de sourceKey, match de município e reclassificação limpa
Chave sufixada por hash de conteúdo para falas distintas que compartilham
data/tipo/fase (caso real 2026-06-17T17:16); keywords oficiais deixam de
alimentar o gazetteer de lugares; nomes ambíguos (Saúde, Wagner, Santana...)
exigem contexto de lugar; teste de nav do communicator; plano com prova viva
e changelog.
2026-09-13 02:08:55 -03:00
Francisco Solla
aca3ea6188 feat(C153): catálogo de falas do Solla — schema, access, import idempotente e busca
Collections speech/speechSegment no grupo Comunicação, papel communicator
(leitura restrita) e índice trigram normalizado para a busca por segmento.
Import idempotente da Câmara (discurso→evento→trecho→VOD→ASR) com facetas
gazetteer+LLM, proveniência e preservação de curadoria manual; parser de
quem presidia; reusa a lógica pura do piloto C152 via scripts/lib.

Related #955
2026-09-13 02:08:55 -03:00
Francisco Solla
b03b7bd969 feat(OPS103): staging no homeserver com verify único e aprovações separadas (Closes #968) 2026-09-12 22:48:22 -03:00
Francisco Solla
907b9ba96b refactor(OPS102): fixes do /simplify — comentários vivos alinhados, pin do exit 0 com mais dentes, runbook/changelog precisos 2026-09-12 21:32:28 -03:00
Francisco Solla
c9bd627de4 fix(OPS102): deploy manual roda até o fim mesmo com main à frente (remove guards de stale run) (Closes #962) 2026-09-12 21:32:28 -03:00