Commit graph

2547 commits

Author SHA1 Message Date
Francisco Solla
1b83cb665d docs(bug-fix): registra merge, deploy e verificação em prod do fix #1433 2026-10-02 22:46:15 -03:00
Francisco Solla
8e32c7cee7 fix(storage): desliga checksum automático de upload no client S3 (Garage multipart) (C246-hotfix)
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
O adapter storage-s3 usa multipart acima de 50 MB e o Garage grava um x-amz-checksum-crc32 errado; o SDK valida no GET e toda leitura do objeto falhava (500 nas fotos 80/83, panorâmicas de 54 MB — conteúdo correto). requestChecksumCalculation: WHEN_REQUIRED no client do plugin; a leitura segue validando o checksum que o objeto tiver e a varredura de integridade segue como checagem honesta. Os dois objetos foram reescritos com PUT único (checksum correto) no ops: canário 2/2 e URLs públicas 200 com 53.762.718 bytes.
2026-10-02 20:01:24 -03:00
Francisco Solla
afc22e5bf3 docs(bug-fix): post-mortem e changelog das chaves AVIF presas no otimizador 2026-10-02 18:55:54 -03:00
Francisco Solla
e4e51a3651 fix(images): hero e cards da home servem masters WebP — AVIF fora do otimizador
Otimizar AVIF no Next 15.4.11 decodifica via libheif (GHSA-2xp9-vwfh-vxw4) e um hang transiente envenena a chave para sempre no Batcher do ResponseCache; o patch oficial (15.5.24) bypassa AVIF. Masters WebP mantêm a entrega e o enquadramento; guards proíbem AVIF em src/ e public/.
2026-10-02 18:55:54 -03:00
Francisco Solla
4aab740895 test(int): estabiliza os specs do álbum no global photoAlbum compartilhado
Aprovações passam a setar o canal e aprovar sob o lease exclusivo do global
(fecha a corrida com o teardown de specs irmãos) e os afterAll não fecham
mais o canal — o padrão que os specs de face já seguiam.
2026-10-02 17:40:41 -03:00
Francisco Solla
53f8e4a3cd fix(fotos): mantém o encoder do store interno ao dono (knip) 2026-10-02 17:40:41 -03:00
Francisco Solla
c15f09531a feat(fotos): miniaturas AVIF pré-geradas do álbum público (C248)
Derivada AVIF 720px q60 armazenada como objeto-irmão determinístico de cada
foto aprovada (flickr-<id>-grade.avif), servida direto quando o cliente
negocia Accept: image/avif; fallback JPEG on-the-fly em ausência/falha, heal
preguiçoso via after(), warm no afterChange da aprovação e backfill
pnpm archive:thumbnails idempotente com recibo e guardas *_CONFIRM.

Sem migration, sem UI, sem mudança de URL pública ou pull-down.
Closes #1424
2026-10-02 17:40:41 -03:00
Francisco Solla
4feea40c01 docs(archive): verificação do canário por GET no runbook (HEAD não valida checksum) 2026-10-02 17:37:39 -03:00
Francisco Solla
255751f5ce fix(archive): teto de 15 min no download do reparo e caminhos do runbook (C246-followup)
O canário 80/83 abortou no download do Flickr: original de ~54 MB (panorâmica 7952px) a ~260 KB/s no link direto do homeserver leva ~3,5 min, acima do teto de 2 min herdado do C231. ARCHIVE_INTEGRITY_DOWNLOAD_TIMEOUT_MS vira 15 min (exportada e pinada no unit); falha de download segue failed retentável. Runbook §C246 usa ~/archive-reports (o /srv do texto original não existe/grava) e ganha docker pull do migrator (a limpeza pós-deploy remove a tag local).
2026-10-02 17:37:39 -03:00
Francisco Solla
a3a49c3462 feat(archive): preflight de integridade antes de aprovar drafts (C249)
O pnpm archive:publish passa cada draft elegível pelo inspectPrivateMediaObject do C246 (download pelo caminho da rota pública + decode sharp) antes de qualquer payload.update: objeto missing/corrupt fica fora do lote, é nomeado no recibo como skippedBroken (stage + motivo) e o comando sai 1 — no plan (read-only) e no apply. A fila seleciona filename além de id; o lote vira o seam exportado runArchivePublishBatch (temp por foto removido no finally) com guard isDirectRun, e o puro scripts/lib/archivePublishPlan.mjs ganha skippedBroken/skippedBrokenCount no summary e as linhas do recibo. scripts/publish-archive-photos.mjs entra no SCRIPTS_SPEC_PINNED (high-risk exato: unit/int full + e2e curado). Guardas do publish intactas; sem S3 num alvo não-local o probe classifica tudo missing (fail-closed). Sem migration, sem UI. Runbook C242/C246 e changelog atualizados; unit do summarize/format, int do lote real (íntegro aprovado, corrompido decode, removido missing, plan sem escrita) e impl plan em docs/plans/acervo-publish-preflight-integridade-impl.md.
2026-10-02 17:25:03 -03:00
Francisco Solla
ac39c81765 style(docs): separa as seções C244/C246 no runbook após o rebase
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-10-02 10:53:39 -03:00
Francisco Solla
dcf8e85a9d feat(archive): varredura e reparo de integridade do acervo no Garage (C246)
Adiciona a CLI pnpm archive:integrity: varredura read-only de todas as archivePhoto (download + decode pelo mesmo caminho da rota pública e do índice facial; sai 1 enquanto houver mídia quebrada approved) e --apply que re-ingere do Flickr pelo flickrId, substitui o objeto na mesma chave via payload.update filePath (sem tocar curadoria/status) e rebaixa a draft as irrecuperáveis (removed intocado).

Dono da leitura ganha inspectPrivateMediaObject e isPrivateMediaMissingError (S3 NoSuchKey/404 + ENOENT local; checksum nunca é missing); archivePhotoIngest ganha repairArchivePhotoObject e withdrawArchivePhotoFromPublic; decisão do reparo em scripts/lib/archiveIntegrityRepair.mjs com deps injetadas e puro de CLI/recibo em scripts/lib/archiveIntegrityPlan.mjs. Sem migration, sem UI. Guardas: ARCHIVE_INTEGRITY_CONFIRM + TEQO_ENV exato + 4 S3_* (em qualquer modo no alvo não-local) + FLICKR_API_KEY. Runbook C246, changelog e unit/int/e2e afetado.
2026-10-02 10:53:39 -03:00
Francisco Solla
ecd9fe478d fix(C245): regenera a migration sobre a cadeia pós-C244
O snapshot da migration da sessão foi gerado antes do merge do C244
(face_figure); regenerado sobre a cadeia nova, o diff segue só coluna
catalog_metadata_checked_at + índice. Aplicada nos bancos do worktree.
2026-10-02 10:17:49 -03:00
Francisco Solla
b6b9bd6360 style(C245): estabiliza a formatação do spec do CLI 2026-10-02 10:17:49 -03:00
Francisco Solla
930db3eb02 feat(C245): catalogar o acervo em produção por camadas — metadados primeiro
A catalogação do C232 nunca rodou em produção: catalog.* zerado nas 6.492
fotos publicadas e o engine de visão fora do ar. O pnpm archive:catalog
ganha --metadata-only: deriva município (gazetteer) e temas do texto já
ingerido, sem engine e sem mídia, grava catalog.metadataCheckedAt
(migration aditiva) e não marca catalogedAt — a fila da IA segue aberta.
Nunca escreve catalog.people (C244 assume a faceta por facial).

A passada de IA passa a carimbar os dois markers; a fila de metadados exclui
linha já catalogada pela IA (não rebaixa o source); o --verify relata as duas
camadas com exit pela selecionada; o --apply de metadados dispensa S3_* e
engine. Runbook §C245: metadados → revalidate archivePhotos → IA.

Closes #1417
2026-10-02 10:17:49 -03:00
Francisco Solla
539138db0a docs(ops): runbook e changelog do ops:global (C247) 2026-10-02 10:10:16 -03:00
Francisco Solla
269b3d9e3b feat(ops): CLI ops:global para flags de globais públicos (C247)
Grava um único campo do global via Local API e busta a tag no processo Next vivo pelo POST /api/revalidate (allowlist ampliada com REVALIDATE_PHOTO_ALBUM_CACHE_TAG), com guardas de escrita, plan/apply/verify, recibo com rollback e int pin do update parcial.
2026-10-02 10:10:16 -03:00
Francisco Solla
d8020607b9 docs(C244): impl plan, runbook, AGENTS-public e changelog 2026-10-02 09:35:43 -03:00
Francisco Solla
9a60807d4e test(C244): e2e da faceta facial e manifesto de afetados 2026-10-02 09:35:43 -03:00
Francisco Solla
ee3dda757b feat(C244): aviso do índice curado, seed de figuras e enrollment 2026-10-02 09:35:43 -03:00
Francisco Solla
e46ed57e2c feat(C244): faceta pessoa do álbum lê o reconhecimento facial 2026-10-02 09:35:43 -03:00
Francisco Solla
625ab5c10e feat(C244): collection curada faceFigure, migração e matcher puro 2026-10-02 09:35:43 -03:00
Francisco Solla
8a87f5f81b docs(plan): C248 — miniaturas AVIF pré-geradas do álbum público (Related #1424) 2026-10-02 09:24:47 -03:00
fsolla
048df6f828 docs: registra merge, verify e staging do fix #1415 no post-mortem
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-10-01 20:50:34 -03:00
Francisco Solla
ff969ec8e4 docs(bug-fix): registra o PR #1421 no post-mortem 2026-10-01 20:41:37 -03:00
Francisco Solla
3c3af5c6bc docs(bug-fix): post-mortem e changelog das imagens lentas da home 2026-10-01 20:41:37 -03:00
Francisco Solla
0fa0e8f41b chore(images): avisa saídas com 2000px ou mais no gerador de assets 2026-10-01 20:41:37 -03:00
Francisco Solla
16f959752a fix(images): masters do hero no tamanho de exibição e TTL de 4h no otimizador 2026-10-01 20:41:37 -03:00
Francisco Solla
9a049bbbb4 docs(C244-C247): planos de intenção — filtro facial de pessoa pública, catalogação em produção, integridade do Garage e toggle de globais 2026-10-01 20:28:53 -03:00
fsolla
8db841f778 docs: registra o PR #1415 no post-mortem e no changelog 2026-10-01 19:38:07 -03:00
fsolla
14e0197df0 docs: post-mortem e changelog do verify (refresh do live preview x hash #novidades) 2026-10-01 19:38:07 -03:00
fsolla
18ec5454fa fix(live-preview): gate do bridge pelo contexto de preview — desbloqueia o verify (hash #novidades)
O bridge do Payload live preview montava em toda página pública e disparava
router.refresh() no mount; quando o RSC chegava depois do clique no CTA do
hero, o HistoryUpdater do App Router regravava a URL canônica sem hash.
Agora o bridge só monta em iframe/popup (window.parent/opener), com unit de
regressão, e2e determinístico (segura o _rsc e libera depois do clique) e
entrada no manifesto de afetados.
2026-10-01 19:38:07 -03:00
Francisco Solla
ab441d36df docs(changelog): S45 — cards verticais na Central de Conteúdos 2026-10-01 19:17:06 -03:00
Francisco Solla
4ac13dc351 feat(S45): cards verticais no catálogo, na home e na página da peça 2026-10-01 19:17:06 -03:00
Francisco Solla
fcc47bb111 docs(plan): S45 — plano de implementação e crítica visual do designer 2026-10-01 19:17:06 -03:00
Francisco Solla
0a8b0774d3 feat(S44): home divulga a Plenária da Vitória (agenda pré-live, embed ao vivo e kill switch)
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-10-01 17:47:30 -03:00
Francisco Solla
8d61b4183f docs(plan): S45 — central de conteúdos — cards verticais no catálogo e na seção da home (Related #1410) 2026-10-01 17:19:23 -03:00
Francisco Solla
33a1d10c09 docs(plan): S44 — Home — seção da Plenária da Vitória (divulgação e acesso) (Related #1408) 2026-10-01 15:24:24 -03:00
fsolla
94d1ca3364 docs: registra o PR #1407 no post-mortem e no changelog 2026-10-01 14:14:37 -03:00
fsolla
f2b5ec0e5c docs: formata o post-mortem do fix do verify (prettier) 2026-10-01 14:14:37 -03:00
fsolla
90768be1cf fix(e2e): clique no dia do calendário pelo contrato data-day — desbloqueia o verify (C104, miss #55)
O verify do deploy falhava nas 3 tentativas no e2e C104: o clique do dia
de término usava getByRole(name: "2 de Outubro de 2026"), e o matcher de
nome do Playwright é substring + case-insensitive — casava também os dias
12 e 22 do mesmo grid (strict mode violation) sempre que hoje+1 caía em
dia 01–09 do mês (02/10 no run de 2026-10-01).

O C104 passa a clicar via calendarDaySelector ([data-day="DD/MM/YYYY"], o
contrato do Calendar.tsx) e o guard miss #55 no e2eNavigationConventions
bane o padrão antigo em todos os specs, com teste do contrato do helper;
TESTING.md, changelog e post-mortem registram a miss.

Related #1406
2026-10-01 14:14:37 -03:00
Francisco Solla
cd4942d9e2 feat(C242/C243): abre a busca por selfie a qualquer visitante (escopo B) + seção na homepage
O escopo A/C do gate (PR #1370) é superado por decisão do dono (2026-10-01, aval jurídico declarado): o índice vira anônimo (archivePhotoFace, foto + descritor 128-d, sem nome/vínculo), o enrollment por pessoa morre (faceSubject/faces:enroll removidos) e qualquer visitante encontra as próprias fotos aprovadas.

- faces:index persiste os descritores por foto (transação substitui as linhas + marker = modelo); desaprovar/remover/deletar foto apaga os descritores (hooks + FK cascade)
- POST /api/fotos/selfie casa o vetor da consulta contra o índice em memória (TTL 60 s) e devolve só a interseção com o read aprovado do C233, sem score/nome de terceiro; leave-index apaga os descritores que casarem
- Consentimentos seguem fail-closed: busca-selfie-fotos (consulta) e busca-selfie-indice (aviso público do índice), textos versionados em scripts/lib/faceConsentTexts.mjs e provisionados por pnpm seed:face-consents
- pnpm archive:publish aprova o acervo em lote (draft -> approved; removed nunca) com guardas e recibo
- C243: seção condicional SelfieSearchHomeSection (port do design hi-fi, cenas 390/1280) entre a Central e a newsletter; sem engine/captura na home e sem CTA morto quando fechada
- docs: planos C242/C243, AGENTS-public, runbook §C242, changelog

Provas: gate:fast 457 arquivos/5.055 testes; int full 109/1.075; e2e frontendFotosSelfie 9/9; knip verde.
2026-10-01 12:54:47 -03:00
Francisco Solla
77e7b0efde docs(plan): S43 — Home — escolher o estadual da dobradinha, montar e compartilhar a colinha (Related #1404) 2026-10-01 12:41:44 -03:00
Francisco Solla
ca843fb4bb fix(C230): fallback da catalogação dá título semântico, não placeholder
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
Quando a sugestão por IA falhava (timeout de 8s) ou a peça não tinha
texto, o fallback preservava o título provisório `Instagram · <código>`
para sempre. Agora isContentPieceLinkTitle (dono em src/lib) identifica o
placeholder e o fallback gera título determinístico (tipo + cidade +
temas); o caminho sem texto faz o mesmo em vez de deixar o placeholder,
a sugestão da IA que ecoa o placeholder é descartada, e título editado
pela assessoria continua intocado.
2026-10-01 02:29:19 -03:00
Francisco Solla
cca5f97482 test(C230): eleva timeout dos specs de guarda dos CLIs do Instagram
Os specs de guarda spawnam o CLI como subprocesso (~2s isolado) e o
timeout padrão de 5s do vitest estoura sob a carga da suíte completa,
derrubando o gate de forma intermitente. 30s dá margem sem mudar o
comportamento testado.
2026-10-01 02:29:19 -03:00
Francisco Solla
3d269725f8 feat(C230): expurgo de peças fora do período eleitoral na Central
O rascunho pré-campanha que o --publish-existing ressuscita precisa sair
do catálogo de vez: o novo CLI content:instagram:prune faz hard delete da
peça e da mídia privada (linha, arquivo e still do C226), então uma
importação futura não a recria. Compartilha o mesmo núcleo de corte da
retirada (data civil na Bahia, peça sem data no feed nunca é tocada) e
espelha as guardas dos irmãos: --before obrigatório, TEQO_ENV casando o
nome exato do banco, CONTENT_INSTAGRAM_PRUNE_CONFIRM=1 e recibos JSON.

Testes: planejador/parser/recibo em unit e guardas do CLI em subprocesso.
Runbook e changelog atualizados.
2026-10-01 02:29:19 -03:00
Francisco Solla
20d3781e4b docs(C240): plano + design hi-fi — carrossel do Instagram como conteúdo de primeira classe (Related #1399) 2026-10-01 01:44:27 -03:00
Francisco Solla
449ef72190 fix(S42): corpo do card da home com min-w-0 (paridade com o artefato)
Some checks failed
Deploy / preflight (push) Has been cancelled
Deploy / verify (push) Has been cancelled
Deploy / deploy staging (teqo-staging) (push) Has been cancelled
Deploy / requeue when main advanced (push) Has been cancelled
Deploy / deploy production (teqo-1313) (push) Has been cancelled
Crítica visual (trigger c, tier gpt-5.6-sol): o título longo em 390 px
precisava da coluna do grid sem min-width intrínseco para quebrar como na
referência. Capturas da crítica certificada em
docs/plans/central-conteudos-secao-home-share-filtro-ui-design-critique/.
2026-09-30 01:09:07 -03:00
Francisco Solla
862da74fbe feat(S42): seção da Central compartilha a peça e abre /conteudos já filtrada
A seção S39 era só vitrine: quem via a peça do seu território tinha de ir
até o catálogo para compartilhar ou recortar. O card agora abre a MESMA
folha do S27 (mensagem de voto por tipo, contador C213, sem sair da home) e
as tags com faceta honesta — mais a fileira Tipo | Cidade | Região — levam
a /conteudos já filtrada pelo construtor canônico; nada filtra a amostra
local e as tags sem faceta (Mais recente, origem) continuam estáticas.

As facetas da fileira são derivadas no server (contentPieceCatalogFacets,
mesmo vocabulário do catálogo) e o lean ContentPieceHomeItem ganha só
sourceUrl, com a folha S27 estreitada ao que lê; classes novas são
home-scoped — CONTENT_PIECE_TAG e /conteudos ficam intactos. Sem migration,
Consent ou analytics novos.

Closes #1391
2026-09-30 01:09:07 -03:00
Francisco Solla
3201b7a93f feat(C237): vetor da fala inclui o sumário/keywords oficiais
A Fase 5 pós-deploy do C229 mediu o corpus real e o aceite 'impeachment'
falhava: a 222 (votação do impeachment de Dilma, 17/04/2016) ficava em #841
porque o índice só embutia o ASR — e a fala nunca pronuncia 'impeachment';
a relevância dela mora no sumário/keywords oficiais da Câmara.

O plano do índice passa a carregar metadataText (sumário — ou título no web
— + keywords, incluído no hash de idempotência) e o vetor da fala vira
normalize(média das unidades + 2·metadata), calibrado no corpus real
(w=2: 222 em #8; w=1: #25). A metadata é vetorizada no mesmo lote do
provedor mas não vira unidade armazenada nem evidência; sem migration.

Related #1395
2026-09-29 22:53:41 -03:00