Commit graph

1354 commits

Author SHA1 Message Date
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
Francisco Solla
8e0366d3ba feat(S14): cards personalizados — ajustes de fidelidade e experiência
A home abre o mesmo compositor do /cards ali mesmo (dialog no desktop,
drawer no mobile) e perde o CTA: os três modelos viram botões e nada
navega. A seção sobe para imediatamente antes da captura de novidades.
O nome no card e no tile alinha à esquerda com o SOU (x=213) via leftX
+ drawCardName extraído; o tile passa a desenhar SEU NOME com o próprio
pipeline real (canvas transparente sobre a base). Modal sem o vão
interno (p-0 sm:p-0) e ajuda legível no tema campaign-site
(--muted-foreground). Remove a variante link e o cardModelHref sem call
site. Unit atualizado (+ drawCardName) e e2e com alinhamento por pixel;
sem migration, sem PII em rede.
2026-09-12 21:01:15 -03:00
Francisco Solla
7990c79b3e refactor(campaign): C150 — simplify (catch/sessão do picker, leitura única, webcal morto) + changelog e débito C156 2026-09-12 21:01:12 -03:00
Francisco Solla
cc6d2abd04 feat(campaign): C150 — calendário principal escolhido pelo candidato/coordenador + inscrição de staff no Google (Closes #935) 2026-09-12 21:01:12 -03:00
Francisco Solla
677dbbf0ea docs(plans): registra OPS103 — staging no homeserver com verify único e aprovações separadas 2026-09-12 20:55:07 -03:00
Francisco Solla
fa6933c1cd feat(C152): piloto da fonte de vídeos e transcrição minutada da Câmara
Spike de viabilidade da fonte (sem DB/Payload): script + lib pura + unit tests; 3 discursos (55ª/56ª/57ª) processados ponta a ponta com segmentos ASR; relatório em docs/research/.
2026-09-12 20:43:36 -03:00
Francisco Solla
6d676609cd feat(C151): marca atividade como evento público
Adiciona o checkbox publicEvent ("Evento público", default false, indexado)
à collection activity para registrar a intenção de expor o compromisso na
futura agenda pública do site — sem consumo agora e sem mudar agenda, lista,
detalhe ou o espelho do Google.

- Activity.ts: campo checkbox + snapshot do guard de liderança
- zod/formData/view model do form + ActivityOverlay (ao lado de "Todo o dia")
- migration add_activity_public_event + types regenerados
- unit (overlay), int (parse/persistência/reabertura) e e2e (roundtrip)
2026-09-12 20:28:59 -03:00
Francisco Solla
bf4a4d9807 docs(plans): registra OPS102 — deploy manual roda até o fim mesmo com main à frente 2026-09-12 20:13:52 -03:00
Francisco Solla
1ff755a8ad docs(plans): registra S14 — cards personalizados: ajustes de fidelidade e experiência 2026-09-12 19:52:54 -03:00
Francisco Solla
e29fb8df1d test(int): C149 — isola o advisory lock do harness e2e (vitest fora do processo Playwright) 2026-09-12 19:49:24 -03:00
Francisco Solla
d9b778b269 feat(campaign): C149 — botão Conectar com o Google (OAuth) substitui a configuração manual da service account (Closes #934) 2026-09-12 19:49:24 -03:00
Francisco Solla
0ea5c8131e docs(plans): registra C152–C155 — acervo de falas do Solla na vertical Comunicação 2026-09-12 12:51:25 -03:00
Francisco Solla
c42bd486de fix(deploy): OPS99 — envs do next build fora do prefixo da cadeia (standalone)
O RUN do builder encadeia gerador de importMap e next build com '&&', mas
prefixos de shell (VAR=x cmd1 && cmd2) valem só para o primeiro comando.
Com o OPS99, NEXT_OUTPUT_STANDALONE=1 e NODE_OPTIONS ficaram presos no
gerador: o next build rodou sem output standalone e o stage runner falhou
no COPY de /app/.next/standalone (run 34701266297, pós-#953 — o #953 já
corrigiu o importmap sem react-server e o falso verde do stale run).

Cada comando passa a declarar seu próprio env, e o guard de invariantes do
Dockerfile em tests/unit/deployScript.unit.spec.ts ganha o pin do escopo
(flags no lado do next build). Inclui post-mortem e changelog.
2026-09-12 12:47:14 -03:00
Francisco Solla
60b4e71dc1 docs(S13): formata o impl plan (prettier) 2026-09-12 03:25:43 -03:00
Francisco Solla
b03cec7c7b refactor(S13): endurece o compositor após review
- font: espera a família primária (check falhava pela fallback do next/font)
- load de assets/fonte separado do redraw (sem flicker/live-region por tecla)
- pan/zoom com updates funcionais; photoSize memoizado
- foco volta ao tile do catálogo ao fechar (trigger da home desmonta)
- copy de privacidade centralizada; tile deriva dims/cor do modelo
- aria do input de arquivo sem colidir com o botão; +2 unit tests
2026-09-12 03:25:43 -03:00
Francisco Solla
681f3bb566 feat(S13): cards personalizados da campanha no site público
Home ganha a seção Faça parte com os três modelos e a rota /cards
concentra catálogo + compositor client-side (dialog desktop, bottom
drawer mobile): nome no slot medido do mestre com Brexter 700 e foto
full-bleed sob o overlay oficial (pan/zoom clampados), download PNG
sem conta e sem enviar nome/foto. Núcleo puro em src/lib/card* com
unit tests; e2e cobre home→deep-link, nome→PNG real, erro fail-closed,
foto e drawer mobile. Sem migration/PII.
2026-09-12 03:25:43 -03:00
Francisco Solla
f3c1ad69ea chore(ai): Sollinha no nome canônico deepseek-flash (B201) 2026-09-12 02:47:25 -03:00
Francisco Solla
087635d08b fix(agenda): modais usáveis no desktop — criação, sync e feed (C148) 2026-09-12 02:23:23 -03:00
Francisco Solla
ccc8d6eaf6 style(OPS101): prettier no impl plan 2026-09-12 02:17:37 -03:00
Francisco Solla
84de2c1aeb refactor(OPS101): fixes do /simplify — guard de pin robusto, docblock e triage de débitos 2026-09-12 02:17:37 -03:00
Francisco Solla
e4550384b1 fix(worktree): OPS101 — preset canônico deepseek-flash e commands sem pin de modelo (Closes #944) 2026-09-12 02:17:37 -03:00
Francisco Solla
eed5a59a31 style(postmortem): formata a tabela após registrar o CI verde 2026-09-12 02:17:13 -03:00
Francisco Solla
ff0f5ff1cf docs(postmortem): registra CI verde do PR #943 (run 34673571340) 2026-09-12 02:17:13 -03:00
Francisco Solla
aa85aa12b9 docs(postmortem): deploy verify B196 — fixture com data vencida (PR #943) 2026-09-12 02:17:13 -03:00
Francisco Solla
8fefdb8cba plan(OPS101+B201): modelo canônico deepseek-flash (Related #944, #945) 2026-09-12 01:33:10 -03:00
Francisco Solla
581cb933a8 docs(plans): S13 — cards personalizados da campanha 2026-09-12 00:46:48 -03:00
Francisco Solla
3aad110e48 docs(postmortem): capas do Instagram e clamp das legendas (PR #940)
Post-mortem do bug-fix com as duas causas-raiz (host fbcdn fora do
allowlist + search:'' do pattern new URL), o pré-requisito do teste de
calendário, a verificação local e as prevenções baratas implementadas e
deferidas.
2026-09-11 18:09:03 -03:00
Francisco Solla
e481819d15 C147: Format files with prettier 2026-08-27 19:46:05 -03:00
Francisco Solla
9b728b3338 C147: Add logging to diagnose Google Calendar sync issues in production
- Add logging to readGoogleServiceAccountCredentials for missing/malformed env
- Add logging to runCampaignCalendarSync when sync is skipped
- Add logging to ensureGoogleCalendarPushChannel for channel status/errors
- Add logging to runSyncPass for sync outcomes (only when changes occur)
- Add logging to error catch blocks for better error tracking
- Use payload.logger where available, console.warn for env-only context
- All logs use consistent [GoogleCalendarSync] prefix
- Logging is conditional to reduce noise in production
2026-08-27 19:46:05 -03:00
Francisco Solla
f3cbb4315d ops100: worktree model flags --glm (opencode-go/glm-5.3-flash) e --free (openrouter/openrouter/free) 2026-08-27 19:29:42 -03:00
Francisco Solla
9480f2a2d7 docs(plans): C147–C151 — sync Google Calendar, modais da agenda, OAuth, calendário principal, evento público 2026-08-27 18:20:37 -03:00
Francisco Solla
c5aef80a12 docs(pm): registra deploy verde (4d6533c0, run 33074305879) + admin verificado em prod read-only + changelog do override sharp
Fecha o registro do post-mortem: PRs #926/#927/#929, deploy manual verde
(verify 19m + deploy 16m), /admin/login renderizando em produção com 0
erros de console na verificação read-only via browser — confirmação final
do humano pendente. Changelog do desbloqueio estrutural do deploy
(override sharp → binários via npm registry).
2026-08-27 16:15:14 -03:00
Francisco Solla
dd4f9d8b99 chore: format changelog entry 2026-08-27 16:05:36 -03:00
Francisco Solla
493f4ba997 feat(OPS99): generate importMap at build time with dummy S3_* envs
Generate the Payload importMap at build time (Dockerfile) and dev time
(predev hook) with dummy S3_* envs, eliminating the class of bugs where
the admin goes blank because the S3ClientUploadHandler entry is missing
(OPS69/OPS72/OPS73).

Changes:
- Dockerfile: add pnpm generate:importmap with dummy S3_* envs before next build
- scripts/predev-importmap.mjs: predev hook that generates importMap if missing or stale
- Delete scripts/check-importmap-s3.mjs (guard no longer needed)
- Delete tests/unit/importMapS3UploadHandler.unit.spec.ts (unit pin no longer needed)
- Remove check-importmap-s3.mjs step from CI workflows
- Add importMap.js to .gitignore (build artifact, not committed)
- Update AGENTS.md with new contract

Closes #928
2026-08-27 16:05:36 -03:00
Francisco Solla
81513d5b14 fix(deploy): reverte package.json para desbloquear o deploy — cache deps do BuildKit
O deploy de fea6c645 falhou 2x: a mudança do script generate:importmap
em package.json invalidou a cache da camada deps do Dockerfile no
homeserver, e o pnpm install re-rodou do zero — o postinstall do
sharp@0.32.6 (transitivo) estourou o timeout baixando o libvips de
objects.githubusercontent.com ('sharp: Installation error: Request
timed out'; o git fetch de github.com funciona — o release vai por
outro hostname da CDN). Produção intocada (falha pré compose swap).

Reverte package.json ao byte do estado cacheado (a9f0c61e) — o install
nem roda. Remove o wrapper generate-importmap.mjs (desligado vira dead
code); proteção do importMap fica com o guard CI+deploy + pin unit +
contrato. Hardening do deps documentado no post-mortem (retry do
install / libvips via apk / proxy), changelog do follow-up incluído.
2026-08-27 09:04:47 -03:00
Francisco Solla
fea6c64514 fix(admin): restaura S3ClientUploadHandler no importMap — admin em branco em prod (4ª recorrência da classe OPS69)
O importMap commitado perdeu a entrada do handler S3 no 1c865bd8
(regenerado sem as envs S3_*): com S3_* em prod, getFromImportMap
retorna undefined e a raiz do Payload não monta — tela branca, zero
erros de console, invisível no loop local (storage local em dev/test).

Fix da causa: regeneração com S3_* dummy (+2 linhas). Prevenção no
mesmo PR — o guard planejado no OPS69 (depends #77/#87) que nunca
existiu: pin unit, guard CI+deploy que regenera com envs dummy e falha
em divergência, wrapper do generate:importmap que injeta as envs, e
contrato compartilhado da chave. Post-mortem + changelog incluídos.
2026-08-26 20:27:22 -03:00
Francisco Solla
8dedf1028c feat(worktree): subcomando fix + skill /bug-fix (diagnóstico → fix → verificação → prevenção → post-mortem) 2026-08-26 16:16:18 -03:00
Francisco Solla
a9f0c61edf fix(campanha): restaura submitter no FormData do card de demanda (#921)
O dispatch manual do C139 montava new FormData(form) sem o submitter;
os botões de transição (name=status value=aprovada|rejeitada|…) nunca
viajavam e transitionDemandFormAction rejeitava toda decisão por status
vazio. submitterFrom (cast honesto nativeEvent as SubmitEvent) + segundo
arg do construtor nos handlers de transição e custo; C139 intacto.

Teste unit novo pina o glue FormData→status (SubmitEvent real, não
fireEvent.submit). E2e 'advisor opens a demand and decides it' verde
local (isolado e em runs de arquivo inteiro).
2026-08-25 21:48:30 -03:00
Francisco Solla
053d1e975c E2E-DEMAND-DECIDE (plano): desbloquear deploy — decisão de demanda parou de gravar (regressão pós-react-audit) 2026-08-25 19:31:30 -03:00
Francisco Solla
618e37ee66 fix(campanha): guarda CSRF mesma-origem proxy-aware atrás do túnel (#913) 2026-08-25 17:32:23 -03:00
Francisco Solla
0c3805e605 docs(testing-audit): estado final protegido (draft fail-closed) — CI green no SHA final 2026-08-25 17:09:43 -03:00
Francisco Solla
dd2735340c docs(testing-audit): estado final do PR #919 e log do desarme no relatório 2026-08-25 17:09:43 -03:00
Francisco Solla
5af65a2c84 docs(testing-audit): relatório da run 2 + entrada de changelog (movimentos, fix do metrics, recidiva #906) 2026-08-25 17:09:43 -03:00
Francisco Solla
8199e2ee24 docs(changelog): react-audit run 2026-08-25 — primeira varredura, 6 fixes, follow-ups #915/#916/#917 2026-08-25 13:40:32 -03:00
Francisco Solla
101cd5d791 C146 (plano): corrigir guarda de mesma-origem do CSRF em /campanha atras do tunel
Related #913
2026-08-25 13:08:46 -03:00
Francisco Solla
4f5a5a838c docs(audit-pass6): format — prettier normalization of the three artifacts 2026-08-25 11:29:03 -03:00
Francisco Solla
5454ec42a0 docs(audit-pass6): ledger rows prettier-stable (emphasis chars in table code spans) 2026-08-25 11:29:03 -03:00
Francisco Solla
7611790b2d docs(audit-p6-m895): plan-issue intention must record literal decision data (miss #895) 2026-08-25 11:29:03 -03:00
Francisco Solla
e562af76d8 feat(audit-p6-m909): deterministic disarm guard for /testing-audit (miss #909) 2026-08-25 11:29:03 -03:00
Francisco Solla
de70ae7e1e docs(audit-pass6): -impl plans P6-1, P6-2, P6-M909, P6-M895 2026-08-25 11:29:03 -03:00
Francisco Solla
8a1aa20ce9 docs(audit-pass6): artefatos — seção Pass 6, ledger truth-up, plano de entrega 2026-08-25 11:29:03 -03:00
Francisco Solla
5742180268 docs(ops98): menções vivas (opt-out restrito audit/*), impl plan e changelog 2026-08-25 08:52:07 -03:00
Francisco Solla
0cea0b7d8f fix(ops96): changelog append-only — desfecho vira entrada própria 2026-08-25 08:24:58 -03:00
Francisco Solla
a5c656dd92 docs(ops96): errata do desarme — skill corrige sequência (desarmar com CI pendente) + relatório registra o merge automático de #907 2026-08-25 08:24:58 -03:00
Francisco Solla
c9d3ac76aa docs(OPS97): registro de débitos da triage no plano 2026-08-25 02:43:31 -03:00
Francisco Solla
fca5a1c105 refactor(OPS97): fixes do /simplify — fail-closed em PR inexistente, errata do plano, token neutro na skill 2026-08-25 02:43:31 -03:00
Francisco Solla
eec6fd3d49 fix(OPS97): desarme do auto-merge via GraphQL disablePullRequestAutoMerge com laco verificado (licao do dogfood #905) 2026-08-25 02:43:31 -03:00
Francisco Solla
3cfbfeac0e changelog: OPS97 2026-08-25 02:43:31 -03:00
Francisco Solla
e1c4931d54 skill(OPS97): react-audit — ciclo fechado sweep→plan→implement→PR único sem auto-merge 2026-08-25 02:43:31 -03:00
Francisco Solla
41c94b2bdc docs(ops96): relatório da primeira auditoria noturna + changelog 2026-08-25 02:42:40 -03:00
Francisco Solla
c2f0c44d15 test(ops96-audit): mover 4 specs puros de int para unit (relationship, schemaPrimitives, assertTestDatabase, petition-page-layout) 2026-08-25 02:42:40 -03:00
Francisco Solla
6777aa86f8 docs(plans): OPS98 — engineering-audit v2 (autônoma, sub-agentes, PR único) 2026-08-25 00:23:13 -03:00
Francisco Solla
1b82dc45af docs: plano de intenção OPS97 — skill /react-audit 2026-08-25 00:17:58 -03:00
Francisco Solla
24ad75d8d6 plan(OPS96): PR final da noite vira ready (sem automerge) com CI green e mergeable 2026-08-25 00:14:22 -03:00
Francisco Solla
019cd456cc feat: S9+ (#771) — integridade de consentimento e alinhamento das ações públicas
- Consent.beforeDelete bloqueia delete com referências (APIError 409 composto
  por coleção), fim do 23502 cru no admin (contagens com overrideAccess).
- submitWhatsapp/submitPetitionSignature delegam o ciclo de transação ao dono
  withPayloadTransaction (rollback no commit-falho, AggregateError, after-commit),
  preservando os contratos { ok: true } / { ok: true, signatureNumber }.
- contactStateSchema exportado + contactCitySchema/contactCityFieldSchema
  consolidados; as 4 fichas usam os exports únicos (fim das cópias inline do
  predicate value in CitiesByState). withMutableConsentFixture purga consent
  via raw SQL para bypassar o hook no harness de teste.

Co-Authored-By: opencode <noreply@opencode.ai>
2026-08-25 00:13:47 -03:00
Francisco Solla
428b0e359a plan(OPS96): skill /testing-audit — auditoria autônoma da suíte de testes (intenção) 2026-08-25 00:07:37 -03:00
Francisco Solla
7259193060 S2-FOLLOWUP (#775) — validate do itemId YouTube deixa de ser código morto
O validate de itemId em social-feed-settings lia data.platform (doc inteiro,
sempre undefined) e nunca validava ID de vídeo em produção. Agora lê
siblingData.platform via helper validateExcludedItemId. Stub YouTube ganha
ids de 11 chars e o spec acompanha, destravando o e2e do describe
'Campaign home content section'. Sem migration.
2026-08-24 23:46:57 -03:00
Francisco Solla
d840975eae style: prettier no plano e changelog da C115-F1 2026-08-24 23:34:56 -03:00
Francisco Solla
a658a1025f fix(campaign): C115-F1 — snapshot de eventos do motor Google Calendar com compare-and-swap (Closes #694)
- recordLastSeenSnapshot: update condicional (id + updatedAt) em vez de
  last-writer-wins; miss descarta a visão contaminada (never-throw)
- token CAS capturado no topo de runSyncPass: mesmo doc alimenta as
  decisões D2-D4 e o guard da escrita (fecha a janela basis-vs-token)
- teste int de corrida determinístico (promise gates): passada obsoleta
  não ressuscita remoção permanente (RED confirmado antes do guard)
- convenção de hermeticidade da janela documentada no header da spec
2026-08-24 23:34:56 -03:00
Francisco Solla
d679708c06 fix(worktree): OPS95 — corrige mapa de modelos e remove --variant do launch do TUI (Closes #876) 2026-08-24 23:04:39 -03:00
Francisco Solla
d48914858a fix(campaignInvite): C121 — unifica chave de lock da redenção com contact-ficha (Closes #885) 2026-08-24 22:51:15 -03:00
Francisco Solla
ba77347616 fix(campaign): D13 — align supporter_import_batch.actor_id schema drift (Closes #643)
Make actor_id nullable to match its ON DELETE set null FK; set SupporterImportBatch.actor required:false so config agrees with schema. Keep the deleteCampaignUserImportBatches hook + hand-deletes as explicit cleanup (no schema cascade, per webauthn precedent). Adds int coverage for account-delete with an orphan batch.
2026-08-24 22:39:03 -03:00
Francisco Solla
6d962ffd9c fix(campaign): C114-LOCK — hooks do sync do Google Calendar seguram row lock por I/O de rede (Closes #870)
Os afterChange/afterDelete de activity e googleCalendarSync rodavam a reconciliacao completa dentro da transacao do save, segurando row lock + pool por todo o I/O do Google (15s por hop, N RTTs -> 45-75s). Corrige com deadline proprio do hook (GOOGLE_CALENDAR_SYNC_HOOK_TIMEOUT_MS=5s) via AbortSignal.timeout combinado com per-hop 15s no cliente (AbortSignal.any) — manual/webhook mantem 15s sem transacao como fallback confiavel. Fail-closed preservado (abort vira paused). Pin unit hook < per-hop + int hook <=7s com fetch lento.
2026-08-24 22:25:23 -03:00
Francisco Solla
2af8acff7e test(OPS46-S3): torna steal do allocator determinístico com SELECT do índice alvo (Closes #790)
Consulta o index do claim crashado e dirige o cursor compartilhado até
ele (bound catalogSize) em vez do loop probabilístico catalogSize*3 —
elimina o flake sob carga paralela. Branch null quando outra spec já
roubou antes do SELECT e fallback claimCount==0 para race durante o
drive, invariante claimCount(crashed)==0 preservado.
2026-08-24 22:22:42 -03:00
Francisco Solla
30dac18872 refactor(tests): B194 — extract shared SSE mock helper and migrate legacy chat specs to v7
Extract sollinhaChatStreamBody + mockSollinhaChat into campaignE2EFixtures.ts
(canonical v7 wire format), reuse across all 6 chat e2e specs and migrate the
two legacy specs (transcribe, openingChips) from the format that fails the v7
client schema. Closes #556
2026-08-24 22:22:08 -03:00
Francisco Solla
f8ead7c4b7 chore(e2e): #811 fechada como satisfeita por #767 — shadow de adminHeaders já unificado
Registra o fechamento da #811: o login REST não-serializado do usuário
compartilhado em frontend.e2e.spec.ts foi eliminado pelo commit d0161f6d
(Closes #767), que unificou todos os logins no helper adminHeaders travado
por advisory lock. Nenhuma mudança de código; apenas changelog + impl plan.
2026-08-24 22:03:29 -03:00
Francisco Solla
fcefcac4e6 style: prettier format dos docs da entrega C120 2026-08-24 19:03:29 -03:00
Francisco Solla
6c582bbb3f fix(contact): C120 — serializa o append de telefone no reuso com lock de ficha (Closes #663) 2026-08-24 19:03:29 -03:00
Francisco Solla
2393847c9b style(docs): prettier no plano e2e-flake-cast-rotativa-pos-ops83 2026-08-24 18:42:03 -03:00
Francisco Solla
d0161f6d69 test(e2e): unificar logins do usuário de teste no helper adminHeaders com advisory lock (Closes #767) 2026-08-24 18:42:03 -03:00
Francisco Solla
a180721e11 feat(campaign): C144 — forms de escrita com options de município write-scoped (Closes #769) 2026-08-24 18:37:59 -03:00
Francisco Solla
339508a7c1 test(e2e): B195-F1 — gate S: no spec do wizard Registrar pedido (cópia de stream duplica o form sob carga) 2026-08-24 18:37:33 -03:00
Francisco Solla
1423cf1758 test: scope C113 live feed to claimed municipality (E2E-FLAKE-C113) 2026-08-24 18:23:47 -03:00
Francisco Solla
078ca65949 review(B155+): simplify — useCallback nos shims, constantes no padrão dos irmãos, copy B36 preservada no caminho de erro, impl plan alinhado
- useMemo(() => fn, []) → useCallback (idiom do codebase; shim sem props no de municípios, saveErrorMessage no de state-deputies).
- ENDPOINT/GENERIC_ERROR → STATE_DEPUTIES_ENDPOINT / MUNICIPALITIES_ENDPOINT + SAVE_ERROR_MESSAGE (espelho de MunicipalityListAdvisorsControl).
- Prop opcional saveErrorMessage no wrapper de state-deputies: o call site B36 (fromStateDeputy) volta a falar em 'lideranças' no caminho de erro, como a form action removida.
- impl plan: LeadershipListStateDeputiesResponse (não ToggleResponse), useCallback, saveErrorMessage.
2026-08-24 18:14:56 -03:00
Francisco Solla
0bb8a96485 feat(campanha): B155+ — migrar quick-edits de célula de lideranças para rota JSON (célula → rota)
F2: POST /campanha/liderancas/state-deputies substitui
setLeadershipStateDeputyMembershipFormAction (chips de /campanha/liderancas B31
e /campanha/dobradinhas B36 — mesma action record).
F3: POST /campanha/liderancas/municipalities substitui
setLeadershipMunicipalitiesFormAction (B34).
Wrappers 'use client' LeadershipStateDeputiesColumnCell /
LeadershipMunicipalitiesColumnCell mantêm o contrato (state, formData) das
shared cells (intocadas); rotas reusam os schemas exportados + allowlists
floor/cap/scope; revalidate herdado das actions record (contrato B34/B31).
F1 (sinal de municípios) não existe mais: C87 o substituiu por form
multi-campo, que por regra B155 permanece em server action — registrado
como já resolvido no plano de intenção.
Guards: whitelist sharedSheetHostConventions (+2 wrappers), prewarm e2e
(+2 rotas), B34 aponta para a rota nova. Sem migration/UI (Impeccable A).

Closes #368
2026-08-24 18:14:56 -03:00
Francisco Solla
244de83cc1 style(plan): format docs/plans/worktree-flags-modelo-correcao.md 2026-08-24 18:07:01 -03:00
Francisco Solla
0fae01c814 plan(OPS95): corrigir mapa de modelos e launch do worktree CLI (intenção) 2026-08-24 18:07:01 -03:00
Francisco Solla
1dde06f5fe docs(plan): S11-FOLLOWUP — gatilhos de débitos + flake pré-existente do picker (Explicitamente fora) 2026-08-24 18:03:37 -03:00
Francisco Solla
5844f026db fix(social-feed): deadline próprio de 5s no hook do save de credenciais encurta a janela de row lock (Closes #762) 2026-08-24 18:03:37 -03:00
Francisco Solla
c66a863263 style(changelog): prettier no registro B160 2026-08-24 18:00:20 -03:00
Francisco Solla
23a061098a feat(campaign): serializa mutações do editor de relações por célula (Closes #378)
Fila encadeada por instância no MunicipalityRelationEditor: delta otimista
imediato + transporte serializado (próximo elo só dispara quando o anterior
assenta), falha reverte só o delta do próprio elo e a fila segue, busy
derivado da fila (nunca preso), drain aplica o último selectedIDs confirmado
só quando a resposta final o traz (JSON) — sem ele (dobradinhas) confia no
RSC. Substitui requestSeqRef/latestConfirmedRef-seq por fila; tempID de
create em contador próprio. Contratos dos wrappers e call sites intactos.
2026-08-24 18:00:20 -03:00
Francisco Solla
19683a0efb fix(petition): Lead tracking não falha mais assinatura commitada — guarda interna try/catch + spec (Closes #766) 2026-08-24 17:52:45 -03:00
Francisco Solla
b4484ec604 fix(social-feed): S11-POLISH rota sync 400 em não-configurado e dedup InstagramPersistDatabase (Closes #761)
Rota POST /api/social-feed/sync devolve 400 { ok:false, error } quando IG não configurado (antes 200 status:{}), alinhando ao impl doc S11; sem revalidateTag no branch 400. InstagramPersistDatabase deduplicado: alias de PostgresTransactionDatabase (owner único), instagramSync importa owner direto.

Co-authored-by: opencode/muse-spark-1.2-contributor-free
2026-08-24 17:46:50 -03:00
Francisco Solla
807d937e92 fix(test): DEBT-FLAKES-C100 — silence review sample 10→30 + ensureLeasedConsent ON CONFLICT idempotent (Closes #553) 2026-08-24 17:37:14 -03:00
Francisco Solla
4034fa371e fix(E16): reconcile allocation_decision.rationale NOT NULL drift
Drop the NOT NULL constraint on allocation_decision.rationale to align
the DB schema with the Payload config (required: false since B134).
Hand-written idempotent migration following the consent_text_to_jsonb
precedent. Adds idempotency test in campaignMigrationReconciliation.

Closes #371
2026-08-24 17:24:13 -03:00
Francisco Solla
facce55eda fix(OPS94): fila de claim não morre mais em issue ready sem frontmatter id (skip + aviso; #659 ganha id B195-F1)
- buildClaimQueue exclui Issues ready sem frontmatter id (não viram worktree
  por construção) e withoutIdReadyIssues() expõe as puladas
- agent:claim / worktree next / pnpm issue next avisam com os números em vez
  de morrer — uma Issue quebrada não trava mais a fila
- pin novo em agentPoolEligibility.unit.spec.ts

Closes #864
2026-08-24 17:23:59 -03:00
Francisco Solla
d816e3ff41 chore(OPS92): consolidar MCPs — global só jina+playwright; penpot/postgres subagentes; gh CLI; re-homed (Closes #857)
Global (~/.config/opencode/opencode.jsonc) fica só com jina+playwright (remove github/postgres/forgejo/stalwart/office-word/jobspy) — manual como OPS89.
Repo Teqo opencode.json: penpot+postgres com permission gated (penpot*/postgres*/query deny no build, allow só nos subagentes penpot/postgres).
Novos .opencode/agent/penpot.md + postgres.md (mode subagent, docs de limite teqo vs teqo_wt*).
Re-homed: jobspy→jobs, forgejo+office-word→lei-mercados-digitais, forgejo+stalwart→infra-solla (remove postgres pin, AGENTS.md sem office-word), forgejo→iara-pwa (limpa pins postgres/stalwart).
Prosa: AGENTS-infra.md, prompt-montagem-home.md, project-status/engineering-audit sem MCP/pnpm issue.
Validação: opencode debug config nos 5 repos (Teqo 4, jobs 3, lei 6, infra 7, iara 3 MCPs), gh auth ok, gate:fast verde.
2026-08-24 17:18:53 -03:00
Francisco Solla
2920aa9d63 docs(changelog): OPS93 flags de modelo no worktree CLI (Closes #859) 2026-08-24 17:08:39 -03:00
Francisco Solla
8951f198ca feat(worktree): flags de modelo --cheap/--pro/--zen/--go/--alibaba com --variant max (OPS93)
Mapa fixo commitado em scripts/lib/worktree.mjs (cheap=cheapestinference/deepseek-v4-flash, pro=opencode-go/qwen3.7-max, zen=opencode-go/ox-alpha-free, go=opencode-go/mimo-v2.5, alibaba=alibaba-token-plan/qwen3.7-max) com WORKTREE_VARIANT=max sempre; resolveWorktreeModel fail-high em múltiplas flags; opencodeLaunchDirective passa a emitir --model <map|preset> --variant max --auto; scripts/worktree.mjs valida at-most-one antes do claim e repassa modelo nos 3 propósitos (next/plan/new) com help/docblock atualizados; .agents/shell/worktree.sh, .opencode/commands/worktree.md, .agents/skills/worktree-next-issue/SKILL.md e local-database skill com contrato remapeado (--go deixa de ser no-op); tests/unit/worktree.unit.spec.ts pina as 5 flags, variant e guardrail.

Closes #859
2026-08-24 17:08:39 -03:00
Francisco Solla
1b846463b0 test(e2e): OPS87 — migrar asserções de servidor para HTTP sem browser (Concepts + PermissionProfile + People) + medir −65% (Closes #833) 2026-08-24 16:57:08 -03:00
Francisco Solla
4ee25e31d8 fix(ci): curated result surfaces unmapped risk files before high-risk early-return
Hoist collectUnmappedSrc helper in selectE2eSpecs so unmapped risk-area
files are computed before the high-risk early-return. When high-risk wins
and risk files lack a manifest entry, the curated result now includes
them in unmapped and appends '; curated + risk files without mapping: ...'
to reason — mode stays curated.

Pin: testAffected gains combined case (migration + unmapped risk file →
curated with unmapped in reason). Closes #846.
2026-08-24 16:52:52 -03:00
Francisco Solla
87ffda56e7 docs(changelog): OPS77 — flip pós-merge GH_TOKEN→GITHUB_TOKEN fechado com evidência (Closes #783) 2026-08-24 16:41:03 -03:00
Francisco Solla
3d4ddc08e3 style(plan): prettier no plano OPS93 (ênfase markdown) 2026-08-24 16:32:25 -03:00
Francisco Solla
8cf67e0de9 plan(OPS93): flags de modelo no launch do worktree CLI (intenção) 2026-08-24 16:32:25 -03:00
Francisco Solla
89605212a8 docs(OPS88): restaura HISTORY congelado (snapshot OPS85 intocado) 2026-08-24 16:12:44 -03:00
Francisco Solla
6b93861075 docs(OPS88): prettier na tabela CI do AGENT-OPS pós-rebase 2026-08-24 16:12:44 -03:00
Francisco Solla
2e55872d2b docs(OPS88): agregado do changelog regenerado pós-rebase 2026-08-24 16:12:44 -03:00
Francisco Solla
2cce5b4b94 plan(O88+): parseDatabaseUrl compartilhado + spec do wiring do db:reset (Related #849) 2026-08-24 16:12:44 -03:00
Francisco Solla
6eb40362d9 review(OPS88): simplify — build surface do reset, contrato high-risk, erros rotulados, docs canônicos 2026-08-24 16:12:44 -03:00
Francisco Solla
7d7fee1619 feat(OPS88): verify do CI/deploy com um Postgres e reset determinístico, um build por run (Closes #834) 2026-08-24 16:12:44 -03:00
Francisco Solla
d29b790306 chore(e2e): E2E-DEBT-S-GATE — extract waitForStreamSettled helper and migrate 21 sites across 5 specs (Closes #827) 2026-08-24 16:01:08 -03:00
Francisco Solla
8d26c5d1d1 plan(OPS92): consolidar MCPs do opencode (intenção) 2026-08-24 15:56:07 -03:00
Francisco Solla
9c5cd7830b simplify(OPS86): gate fail-fast no unmapped-risk, smoke fallback no manifesto, pins de sync do wrapper, docs AGENT-OPS (Related #846) 2026-08-24 15:19:52 -03:00
Francisco Solla
9af4b92851 ops(OPS86): blast radius dos testes — curated e2e em high-risk, fail-closed para risco sem mapping, unit/int full na seleção vazia (Closes #832) 2026-08-24 15:19:52 -03:00
Francisco Solla
3b32dbc814 fix(OPS83-recurr): cast rotativa do verify #16 — serializar admin atrás do frontend (stub IG compartilhado) + notificação pula recipient sumido em vez de abortar transação 2026-08-24 15:11:39 -03:00
Francisco Solla
6f6e9fb4b4 ops(OPS91): sweep pós-cutover — textos vivos que apontavam o tracker ao Forgejo passam para o GitHub (Closes #841) 2026-08-24 15:08:14 -03:00
Francisco Solla
2aa445dd1d impl(OPS84): verificar valores (não só entidades) da migração — 13 tabelas, 0 diffs (Closes #828) 2026-08-24 15:03:31 -03:00
Francisco Solla
51ad84583d docs(OPS85): triage pós-simplify no impl plan (0 débitos registrados, 2 defers com gatilho) 2026-08-24 14:44:25 -03:00
Francisco Solla
cbe30604c0 docs(OPS85): impl plan + prettierignore do HISTORY congelado 2026-08-24 14:44:25 -03:00
Francisco Solla
60a71eea4b feat(OPS85): matar o agregado commitado do changelog — registro por-arquivo + HISTORY congelado + leitura sob demanda (Closes #830) 2026-08-24 14:44:25 -03:00
Francisco Solla
c69376f3c2 docs(deploy): caveat de rollback para backups pré-INF13 (tags bare) — review
O primeiro deploy pós-fix faz backup do compose ainda bare e o cleanup novo
remove os aliases bare em seguida: um rollback manual restaurando esse backup
legado precisaria recriar o alias (docker tag) após o pull. Documenta a
janela de transição na seção de rollback e na linha INF13 da tabela de
falhas.
2026-08-24 14:33:07 -03:00
Francisco Solla
b083840b8f docs(OPS90): codificar a pirâmide de testes unit→int→e2e-com-benefício nos donos certos (Closes #838) 2026-08-24 14:20:59 -03:00
Francisco Solla
ddd58a01d1 fix(deploy): compose referencia a tag qualificada do registry; F2 preserva por image ID (INF13)
O compose do stack referenciava a tag local bare teqo-1313:<sha>, que é uma
segunda ref que nada recria se perdida (achado INF8 24/08: só restava a ref
do registry e o 'compose up -d' falhou com No such image). Agora:

- swap escreve sempre localhost:5000/teqo-1313(-migrator):<sha> (sed
  idempotente aceita ambas as formas); os docker tag bare somem (sem
  consumidor);
- rollback do runbook simplifica (docker pull basta, sem dance de tag);
- limpeza pós-deploy (INF3/F2) preserva TODAS as tags da imagem em uso pelo
  IMAGE ID do container, imune a drift de label do compose.

Runbook docs/ops/teqo-1313-deploy.md atualizado (fluxo, rollback, tabela de
falhas com o achado). Issue de referência (tracker infra-solla):
git.solla.dev/fsolla/infra-solla#24
2026-08-24 14:17:43 -03:00
Francisco Solla
ae79eb507c chore(OPS89): variantes Vercel AI Gateway para a config global do opencode (Closes #836)
- opencode.json: removido provider.vercel inteiro — repo fica $schema + mcp.penpot
- docblock de OPENCODE_PRESET_MODEL e prosa de worktree-next-issue/SKILL.md apontam para ~/.config/opencode/opencode.jsonc
- Forgejo → GitHub na linha reescrita da skill (rastro pós-cutover)
- impl plan + changelog da entrega; débito OPS91 (#841) registrado com plano
2026-08-24 14:05:59 -03:00
Francisco Solla
0bb8e6e8a6 plan(OPS90): skills e docs — pirâmide de testes unit→int→e2e-com-benefício (Related #838) 2026-08-24 13:29:10 -03:00
Francisco Solla
9f8c3bdcb5 plan(OPS89): mover variantes Vercel para global (intenção) 2026-08-24 13:23:49 -03:00
Francisco Solla
1f916030c3 plans(OPS86/OPS87/OPS88): simplificar a etapa de verificação CI/deploy — blast radius, pirâmide HTTP, setup único (Related #832, #833, #834) 2026-08-24 13:15:38 -03:00
Francisco Solla
56393d046c plan(OPS85): Estratégia para eliminar conflitos de merge no changelog e reavaliar migração da documentação para fora do repo (Related #830) 2026-08-24 13:09:29 -03:00
Francisco Solla
de1ebdc8b6 plan(OPS84): verificação de valores da migração — foco estimativas de votos (Related #828) 2026-08-24 13:02:48 -03:00
Francisco Solla
e4cb8d1006 fix(e2e): OPS83 — estabilizar os e2e do verify sem reduzir cobertura; AgendaFeed roda em prod (Closes #824) 2026-08-24 07:27:49 -03:00
Francisco Solla
627492000b plan(OPS83): desbloquear deploy — estabilizar e2e do verify, família de flakes estudada (Related #824) 2026-08-24 00:47:00 -03:00
Francisco Solla
a2db543e0c ops(OPS82): preset do launch opencode → DeepSeek V4 Flash 0731 (mais barato) + variantes low/high/max + remoção duplicata cheapest-inference (Closes #817) 2026-08-23 23:20:45 -03:00
Francisco Solla
bddbd5c085 ops(OPS79): última migração de dados em produção — reconciliação da vertical campanha (Neon→teqo_1313) + migração do residual público (Closes #797)
- scripts/reconcile-campaign-vertical.mjs: verificação read-only repetível (contagens + junta de IDs das 13 coleções da vertical + conteúdo semântico das rels); absorve os 3 links de edição de portfolio pós-OPS51; nunca imprime PII
- scripts/migrate-signature-orphan.mjs: migração one-off com guard OPS79_MIGRATE_CONFIRM=1, dry-run/apply, transação única, PII mascarada
- Execução 100% no homeserver: aplicado contact 2225 + signature 1486 preservada + subscription 1492; sequences ajustadas; pós-verificação signature 1485=1485 e reconcile 19/19
- Runbook (docs/ops/teqo-1313-deploy.md §OPS79): execução + rollback (DELETE 3 linhas + setval)
- docs: plano de intenção restaurado (deletado acidentalmente em C140) + impl plan + changelog
2026-08-23 22:45:43 -03:00
Francisco Solla
9039b1bbd3 fix(e2e): C142 — add C106 shell-settle before write-chrome assertions to unblock deploy
The FAB in campaignPermissionProfile:85/:101 (carteira/tudo write present)
and the advisor checkbox in campaignMunicipalities:115 (editar page) failed
consistently under 4-worker CI load because the RSC streaming shell's
S:* copies hadn't settled when networkidle resolved, and the default
expect/action timeout wasn't sufficient on the constrained hosted runner.

A probe proved the FAB SSR-renders correctly for carteira/tudo advisors
(profile scope is honored; no seed false-negative). The fix adds the
C106 shell-settle (document.querySelectorAll('div[id^=S:]').length === 0)
before the presence assertions, matching the established idiom used by
the sibling campaign spec tests.

21/21 passed at E2E_PROD=1 PLAYWRIGHT_WORKERS=4 repeat-each=3.
gate:fast (2439 unit tests) all green.
2026-08-23 22:13:52 -03:00
Francisco Solla
1d762755d9 feat(campaign): editor de permissão do assessor em modal central (desktop) + bottom drawer (mobile) no lugar do popover (Closes #813) 2026-08-23 20:41:29 -03:00
Francisco Solla
5b4e5ecf22 ops(OOPS80): cutoff fase 1 — desativar acesso pela URL antiga pt.jorgesolla.com.br (congelar a fonte)
- scripts/check-push-chain.mjs: default --site, usage, erro → canônico; prosa Neon/vercel → homeserver
- tests: fixtures unit (WebAuthn, JsonMutation, aiMarkdownLinks) + int (campaignMultiPhones) → canônico, semântica preservada
- campaignMultiPhones: adiciona ensureLeasedConsent para invite consent fixture (fix pre-existente)
- personas (.opencode/agent/designer, solla-comunicacao, skill): canônico + operação homeserver
- docs: intenção + impl plan + changelog entry; CHANGELOG-AGENTS append-only preservado
- Sem migration, sem schema, sem access/Consent, sem UI
- Closes #796
2026-08-23 20:14:59 -03:00
Francisco Solla
14160365bf OPS82 — Default launch → DeepSeek V4 Flash 0731 + variantes + limpeza Cheapest Inference 2026-08-23 20:13:33 -03:00
Francisco Solla
6f4a4bd689 docs(OPS76-DOCS): polish do banner histórico — wrap multi-linha e line refs corretos 2026-08-23 20:06:40 -03:00
Francisco Solla
1f31045dc8 docs(OPS76-DOCS): banner histórico em paradigma-agentes-paralelos.md (órfão pré-main com refs mortas) (Closes #800) 2026-08-23 20:06:40 -03:00
Francisco Solla
aec6ec2edd docs(plans): C145 — plano permissão do assessor em modal central + bottom drawer 2026-08-23 19:16:30 -03:00
Francisco Solla
cd26fb8ce2 fix(e2e): serializa o beforeEach UI login do admin com o advisory lock 727001 (Closes #805) 2026-08-23 19:10:21 -03:00
Francisco Solla
368f138282 feat(campaign): C88 deliberação na atualização — responsável, fio e resolvido (Closes #397)
Migration 20260823_161905_add_municipality_update_deliberation + access por mutationKind + ilha client nas 3 superfícies + specs unit/int/e2e.
2026-08-23 18:58:26 -03:00
Francisco Solla
9467e0f292 fix(campaign): C140 — manual dispatch in 18 forms prevents React 19 form reset on error
Fix manual dispatch em 18 formulários de /campanha que usavam <form action={submitAction}>: campos não controlados voltavam ao defaultValue após qualquer action assentada (sucesso ou erro) do React 19.

- WizardStepFormChrome alterado uma vez (cobre 3 wizard steps)
- 15 forms recebem dispatch manual arquivo a arquivo
- AdvisorPasswordResetButton (2 micro-forms sem campo digitável) ficou como está
- Unit spec novo campaignWizardStepFormChrome.unit.spec.tsx
- CHANGELOG-AGENTS.md cleaned (98 duplicates removed)

Also fixes:
- campaignPageActor writable gate only blocks advisors (was blocking coordinators too)
- campaignLeaderships e2e stability (waitForLoadState before attribute assertion)
2026-08-23 17:54:19 -03:00
Francisco Solla
a97cd56fce fix(campaign): desbloqueia deploy — gate 'writable' libera coordinator/candidate e FAB ganha data-slot do e2e (C142)
Dois bugs do C142 que o e2e full do verify do deploy pegou (o PR rodou só o blast radius):
- requireCampaignPageActor gate 'writable' checava advisorEditingAccess(user)==='none', que retorna 'none' para QUALQUER papel não-advisor — barrava coordinator/candidate de páginas de escrita (municipios/[slug]/editar redirecionava o coordinator pro detalhe).
- CampaignQuickActionsFab não renderizava data-slot='campaign-quick-actions-fab', o locator do e2e campaignPermissionProfile.
Regressões pino: campaignPageActorGate.unit.spec.ts (5 casos) + assert de data-slot no spec do FAB.
Verificado: tsc/lint/format/cycles, unit 2435, int 819, e2e local dos specs afetados (os 3 casos que falhavam no deploy passam).
2026-08-23 16:41:40 -03:00
Francisco Solla
98d683b4e7 docs(OPS78): regenera agregado do changelog pós-rebase (sem duplicatas) 2026-08-23 16:08:12 -03:00
Francisco Solla
3eec76ef71 style: prettier no impl plan e no help do worktree 2026-08-23 16:08:12 -03:00
Francisco Solla
67c213585c ops(OPS78): launch do worktree opencode roteia pelo Vercel AI Gateway com variantes low/high/max (Closes #784) 2026-08-23 16:08:12 -03:00
Francisco Solla
37dcd22aeb chore(OPS73-FOLLOWUP): regenera agregado do changelog (53 entradas, reconcilia OPS47/OPS46-S1) 2026-08-23 15:54:49 -03:00