Commit graph

1587 commits

Author SHA1 Message Date
Francisco Solla
81f87c78d1 feat(C234): busca por selfie no álbum público — índice A/C consentido, selfie on-device
- /fotos/encontre + POST /api/fotos/selfie: só o vetor 128-d, sem imagem, sem score e
  sem nomes de terceiros; fail-closed pela flag photoAlbum.selfieSearchEnabled (default
  false) e pelos Consents por chave estável (busca-selfie-fotos/busca-selfie-indice, não
  seedados — a superfície nasce fechada até o aval jurídico/DPIA).
- Índice A/C do gate (PR #1370): só quem aderiu é indexado; descriptors do acervo são
  transitórios. Collection faceSubject (admin-only, sem vínculo com Contact), vínculos
  matchedPhotos e marker faces.checkedKey no archivePhoto (modelo + enrolledAt).
- Engine @vladmandic/face-api nos dois lados: browser lazy com modelos same-origin
  (copy-face-vision-assets no prebuild/predev/Docker) e CLI node-wasm sem tfjs-node.
  CLIs ops-only faces:enroll / faces:index --apply|--verify com guardas C231/C232.
- Opt-out self-service por reconhecimento (leave-index) + canal de remoção do C233;
  rate limit próprio (namespace selfie:<hash>) e bounded body extraído do beacon.
- UI portada classe-a-classe do design estendido (paridade certificada, tier primário);
  e2e frontendFotosSelfie (manifest+curado+projeto, engine stubada) e canário do engine
  real; runbook §C234, contrato em AGENTS-public.md e changelog.
- Migration aditiva add_face_subject (SQL revisado); hard-stops aprovados na sessão.
2026-09-27 19:03:30 -03:00
Francisco Solla
87002b7e82 docs(C233): registra o fechamento do impl plan (design certificado, gates)
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-26 23:54:50 -03:00
Francisco Solla
b2d6483532 feat(C233): álbum público de fotos com busca por data, local, atividade e pessoa pública 2026-09-26 23:54:50 -03:00
Francisco Solla
57b0d168d4 feat(C199-large): gravações do acervo sem o teto de 4 GB
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 diálogo, a rota e o stream deixam de recusar arquivos acima de 4 GiB; o
nome do arquivo e o `formatRecordingFileSize` continuam iguais. Acima de
2 GiB a mídia não passa mais pelo `fs.readFile` do Payload local API: a row
nasce de um placeholder de 0 byte e a mesma key é sobrescrita por upload
multipart direto no S3 (padrão C225-large, extraído para
`utilities/privateMedia/privateMediaUpload.ts` e reusado pelo espelho de
falas web, que mantém o teto de 5 GiB via `maxBytes` do chamador). O objeto
é removido se a transação falhar, sem row fantasma, e o upload multipart de
gravações não tem teto (`Infinity`).
2026-09-26 14:40:16 -03:00
Francisco Solla
671af1e21f feat(C232): pré-catalogar o acervo de fotos com IA local e curadoria que vence
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
Collection archivePhoto ganha o grupo catalog (legenda/descrição/cena/texto
visível/temas/pessoas/município/origem/catalogedAt), curatedFields (o que a
assessoria edita nunca é sobrescrito), takenOn e searchText com índice GIN trgm
(migration aditiva add_archive_photo_catalog); hook beforeValidate deriva o
índice e marca curadoria só em edição humana; pipeline transacional baixa os
bytes privados, prepara JPEG <=1024px com sharp e mescla o VLM local com o
gazetteer/catálogo curado (pessoas só do TEXTO, nunca de rosto); CLI
pnpm archive:catalog (plan/--apply/--verify, recibo honesto, idempotente por
catalogedAt) com engine OpenAI-compatible na rede privada atrás de guarda de
host (ARCHIVE_VISION_ALLOW_REMOTE é o escape); client HTTP com retry/timeout e
parser zod fail-closed; resolver de município extraído para owner compartilhado
com o catálogo de peças delegando; unit/int novos e runbook staging-primeiro.
2026-09-26 12:30:34 -03:00
Francisco Solla
3e8429daae feat(C229): busca por sentido no acervo de falas
Troca o motor do modo tema (Câmara + internet) de expansão lexical para
embeddings (Deep Infra, BAAI/bge-m3), com índice próprio (speechEmbedding),
ranking por proximidade em memória, evidência real do trecho mais próximo,
vazio honesto por limiar e degradação para a busca literal. Inclui a
collection oculta + migration, o CLI pnpm acervo:index (--dry-run/--limit/
--source/--force/--probe), o port do design aprovado e a suíte de testes.

Pós-rebase: o snapshot da migration seguinte (20260926_062039_add_archive_photo,
do C231 já na main) foi regenerado para incluir speech_embedding — sem ele o
próximo migrate:create recriaria a tabela.

Closes #1360
2026-09-26 11:59:21 -03:00
Francisco Solla
111ab265fe chore(DESIGN1): toolkit de design dos agentes e regras visuais vivas
Skills vendoradas (UPSTREAM.md): suíte Taste (design-taste-frontend,
gpt-taste, redesign-existing-projects, briefs de estilo, stitch-design-taste,
full-output-enforcement), web-design-guidelines e awesome-design-md.
Playwright CLI global + skill. Guardrail de marca do kit 1313 retirado:
DESIGN.md §7 (Evolution) passa a ser o dono vivo das regras visuais.
Doutrina ui-design-html.md §Skills de design, designer/-degraded e
designer-campanha-solla alinhados; changelog DESIGN1.
2026-09-26 11:03:04 -03:00
Francisco Solla
355e72c35d test(e2e): escopa locators do card de responsáveis ao form visível
Falha pré-existente reproduzida em origin/main: a página de demanda monta o
form de responsáveis duas vezes no DOM (visível + cópia oculta) e
campaignDemandVisibility batia nos dois com locator estrito — classe
"locator não-escopado" do plano OPS83/#824. O CI curado do PR roda a spec
(diff high-risk) e ficaria vermelho; os locators agora miram o elemento
visível.

Registro no impl plan do C231 e no changelog.
2026-09-26 05:40:22 -03:00
Francisco Solla
aba3aa4816 feat(C231): ingerir o acervo de fotos do Flickr no storage privado
Collection privada archivePhoto (flickrId unique+index, metadados do Flickr +
EXIF, leitura pela comunicação, mutação admin, entrada no mapa S3) com migration
aditiva add_archive_photo; ingestão idempotente (transação + upload) e CLI
pnpm flickr:import (plano dry-run por padrão, --apply com intenção/TEQO_ENV/S3,
--verify inventário read-only, recibos JSON em data/flickr/reports). Guard de
alvo extraído de reel-ingest para scripts/lib/cli.mjs; downloadUrlToFile ganha
headers (User-Agent do Flickr).
2026-09-26 05:40:22 -03:00
Francisco Solla
37bb239d1d fix(build): tira docs do scan do Tailwind — destrava a main
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
A detecção automática do Tailwind v4 lia os designs HTML de docs/plans/
e a classe bg-[url('../../public/…')] do design do álbum (4bf0c0c0)
virava módulo relativo no CSS de produção, quebrando next build na main
e o verify do deploy. @source not mantém o CSS publicado só com os
componentes reais (a variante root-absolute já existe em src).
2026-09-26 03:57:27 -03:00
Francisco Solla
a9f377f985 fix(C225-large): espelha mídia web acima de 2 GiB 2026-09-26 03:57:27 -03:00
Francisco Solla
4b3ea0d04d test: declara o 404 esperado de /conteudos/*/frame nas specs da home
O conjunto curado roda specs concorrentes que publicam peças; a home pede o
still e /frame responde 404 até a cura (C226). As specs da home passam a usar
a mesma declaração que frontend.e2e.spec.ts, fechando o flake do CI.
2026-09-26 02:06:17 -03:00
Francisco Solla
4a07bac596 feat(C230): importar publicações do perfil oficial na Central
Lê a janela recente (12 mídias) de @depjorgesolla pela Graph API oficial e
cria Rascunho só para as novidades pelo pipeline C211/C220 (ou peça-link com
motivo honesto), com progresso real e recibo novas/já estavam/falharam.
Dedupe pela identidade do post (shortcode em qualquer grafia p/reel/tv), sem
migration, compartilhado com o Adicionar por link; fail-closed de credencial
nas duas pontas; nada é publicado.

Closes #1362
2026-09-26 02:06:17 -03:00
Francisco Solla
4bf0c0c0c6 docs(C231–C234): planos + designs hi-fi do acervo de fotos do Flickr (Related #1366, #1367, #1368, #1369) 2026-09-26 02:04:24 -03:00
Francisco Solla
fe3b0c3215 docs(C230): plano + design hi-fi da importação do perfil oficial (Related #1362) 2026-09-25 23:09:35 -03:00
Francisco Solla
e2aa3a7d66 docs(C229): plano + design hi-fi da busca por sentido no acervo (Related #1360) 2026-09-25 21:41:26 -03:00
Francisco Solla
dbe77f08cc feat(C226): frame estático nos vídeos da Central antes do play
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
Peça de vídeo publicada e com arquivo passa a mostrar um frame estático
leve no card público antes do play, sem nenhum request do arquivo antes
do gesto (`preload="none"` do S27 intacto).

O frame é um derivado privado em `contentMedia` (nome determinístico),
gerado por um dono só — `ensureContentPieceFrame` — chamado pelo job
C211 (que já tem o arquivo em disco: a extração sai de graça) e pela
rota `GET /conteudos/<slug>/frame` em miss, que cura o acervo anterior
sem backfill, fila, collection nova ou migration.

A porta reusa o gate de slug publicado e o proxy de mídia privada do
`/midia`: o kill switch fecha as duas de uma vez. Sem frame possível, o
slot mostra o estado neutro honesto com play e o marcador — nunca
imagem quebrada, nunca retry.

A projeção declara o frame por elegibilidade (vídeo com arquivo), não
pela existência do derivado, então a cura é invisível para o cache da
listagem e não há tag para bustar. O frame também aparece na página da
peça e no card da home (variante compacta de 124px, cena 05).

A passagem de design (tier primário) achou dois bugs que só o browser
mostra: o glyph de imagem quebrada numa requisição que falha, e — ao
esconder a imagem até decodificar — o frame sumindo para sempre no
caminho mais rápido (uma imagem que carrega antes da hidratação não
dispara `load` nem `error` de novo; o `ref` decide os dois desfechos).

Também: o guard de falha de e2e aceita `RegExp` e confere os paths
declarados antes do caso do favicon (todo 404 do browser traz a mesma
mensagem), o manifest de e2e mapeia os módulos novos, e o job C211
passa o arquivo que já tem em disco em vez de rebaixar o vídeo.

Design tier: central-conteudos-preview-frame-video
Closes #1352
2026-09-25 14:56:06 -03:00
Francisco Solla
2e5ac5d290 feat(S27-FOLLOWUP): polimento visual da Central de Conteudos (hero e filtros)
Hero com pattern oficial, placa do 1313 e faixa amarela; 1313 visivel no mobile. Filtros com ChevronDown do lucide centralizado (nao mais o glifo baixo) e accordion exclusivo via <details name>. Artefato: docs/plans/central-conteudos-hero-polimento-ui-design.html
2026-09-25 14:03:10 -03:00
Francisco Solla
497e5029f1 fix(C225): fecha guard e runbook da ingestão web 2026-09-25 12:27:13 -03:00
Francisco Solla
0ee0a415c1 docs(media): registra PR do reparo 2026-09-25 12:11:21 -03:00
Francisco Solla
8387a477db fix(media): repara rota do Garage no deploy 2026-09-25 12:11:21 -03:00
Francisco Solla
4be1c0923b style(C226): formata o design do frame preview 2026-09-25 11:30:28 -03:00
Francisco Solla
9404c03df3 docs(C226): frame preview para vídeos da Central 2026-09-25 11:30:28 -03:00
Francisco Solla
1cfeff0250 docs(C220-FOLLOWUP): registra o efeito colateral do ufw (Garage) e a correcao no post-mortem/runbook 2026-09-25 10:47:23 -03:00
Francisco Solla
d865cf9748 docs(C220-FOLLOWUP): preenche o PR #1349 no post-mortem 2026-09-25 10:20:27 -03:00
Francisco Solla
cba4a9d56c fix(C220-FOLLOWUP): retry no download do CDN do Instagram (rede instavel)
Causa-raiz do sintoma residual: o container e IPv4-only e a rota IPv4 ate o
CDN do Instagram e instavel nesta rede (IPv6 e o caminho confiavel); o resolver
baixava com uma tentativa e virava 'indisponivel'. O dono do download ganha
teto de conexao por tentativa e ate 6 tentativas; resposta nao-2xx nao repete.
Rede IPv6 ja corrigida no stack (fora do repo) e documentada no runbook.
2026-09-25 10:20:27 -03:00
Francisco Solla
33573dd0c0 fix(C224): saneia o env do spawn do yt-dlp (Closes #1338) 2026-09-25 10:14:39 -03:00
Francisco Solla
0b05dfe9a0 fix(C223): aceita falas longas no acervo
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-25 02:11:56 -03:00
Francisco Solla
57d24687eb chore(OPS129): atualiza modelos das flags do worktree
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-25 01:48:20 -03:00
Francisco Solla
01831446df feat(S41): assina e ancora eventos de agenda do link (Closes #1335) 2026-09-25 01:47:18 -03:00
Francisco Solla
b4821f1b28 style(fix/11): formata a linha do post-mortem 2026-09-25 01:43:37 -03:00
Francisco Solla
082c19b576 docs(fix/11): numera o PR #1345 no post-mortem 2026-09-25 01:43:37 -03:00
Francisco Solla
0fa618d0af fix(ia-egress): estabiliza a rota ate o deepseek com proxy na tailnet + probe no deploy 2026-09-25 01:43:37 -03:00
Francisco Solla
4678117b08 docs(fix/11): post-mortem registra a camada de rede pos-deploy (Related #1333) 2026-09-25 00:53:23 -03:00
Francisco Solla
c013de13d6 fix(S36-FOLLOWUP): logo do header da Central sem corte — janela na razão da tinta 2026-09-25 00:44:57 -03:00
Francisco Solla
c472c5c0b3 docs(OPS129): registra plano dos modelos do worktree 2026-09-25 00:42:03 -03:00
Francisco Solla
796e68a4e7 docs(C225): plano — Falas na internet no acervo de produção (Related #1339) 2026-09-25 00:21:58 -03:00
Francisco Solla
a2fff97fdc docs(C224): plano — ingestão web funciona no comando documentado (Related #1338) 2026-09-25 00:21:58 -03:00
Francisco Solla
95e925c62d docs(C223): plano — falas longas sem estourar o limite do texto normalizado (Related #1337) 2026-09-25 00:21:58 -03:00
Francisco Solla
0f81e369d1 docs(S41): plano — agenda do link de anúncio com link, assinatura e fuso (Related #1335) 2026-09-25 00:08:27 -03:00
Francisco Solla
63bd370b6c feat(C222): apagar uma peça na Central de Conteúdos (Closes #1330)
Hard delete por peça (sem lixeira/lote/telemetria) em qualquer estado, com confirmação que nomeia o link público só quando publicado; access próprio da vertical + admin (advisor/leader fail-closed), cascata da mídia pós-commit e bust da tag contentPieces no afterDelete; máquina do diálogo extraída no 3º call site (C183/C199/C222).
2026-09-24 23:49:28 -03:00
Francisco Solla
3cdd1cd8fb docs(fix/11): numera o PR #1333 no post-mortem 2026-09-24 23:09:49 -03:00
Francisco Solla
4e7b844419 fix(C192/S28/C219): busca por tema indisponivel — thinking do deepseek-flash truncava o JSON 2026-09-24 23:09:49 -03:00
Francisco Solla
9f43cbb274 docs(C220-FOLLOWUP): preenche o PR #1332 no post-mortem 2026-09-24 22:59:40 -03:00
Francisco Solla
b5c4e274a2 fix(C220-FOLLOWUP): early-stop da janela de link do Instagram na Central
O resolver pedia a janela de 500 (ate 10 paginas de cursor) antes de casar o
shortcode; erro em pagina >=2 virava 'indisponivel' mesmo com o post na pagina 1.
O dono da paginacao ganha shouldStopAt (board/sync intocados) e o resolver para
na pagina que contem o post — a colagem tipica volta a custar uma chamada.
2026-09-24 22:59:40 -03:00
Francisco Solla
767f86c455 style(C222): formata o design hi-fi (Related #1330) 2026-09-24 22:34:47 -03:00
Francisco Solla
a81f2c2672 docs(C222): plano + design hi-fi — Central de Conteúdos — apagar uma peça (Related #1330) 2026-09-24 22:34:47 -03:00
Francisco Solla
c9ab467f23 feat(C217): cortes e links compartilhaveis na fonte "Falas na internet" (Closes #1293) 2026-09-24 20:17:54 -03:00
Francisco Solla
1cd5cfa0b7 style(C216-FOLLOWUP-DRY): formata o impl plan (Related #1325) 2026-09-24 19:29:27 -03:00
Francisco Solla
a041683352 docs(C216-FOLLOWUP-DRY): changelog da entrega (Related #1325) 2026-09-24 19:29:27 -03:00