diff --git a/docs/changelog/2026-09-19-c203-graficos-kit-1313.md b/docs/changelog/2026-09-19-c203-graficos-kit-1313.md index 831e5f61..67273fda 100644 --- a/docs/changelog/2026-09-19-c203-graficos-kit-1313.md +++ b/docs/changelog/2026-09-19-c203-graficos-kit-1313.md @@ -1 +1 @@ -**C203 — Gráficos de dados do Instagram na marca oficial do kit 1313 (2026-09-19):** os gráficos da skill `graficos-dados` (C191) saem agora na **marca e na paleta oficiais do kit 1313** (C196/C204), resolvendo o débito `NEEDS ASSET · LOGO OFICIAL` registrado no hi-fi aprovado. (1) **Rodapé oficial:** o lockup tipográfico provisório ("JORGE SOLLA"/"MANDATO DEPUTADO FEDERAL") saiu; o rodapé usa `public/campaign-kit/jorge-solla-positivo.png` embutido como data URI (frame 286×90, `object-fit: contain`, `alt` do hi-fi) e o renderer **falha fechado** sem a marca — nunca recria o lockup. (2) **Paleta oficial:** destaque único/valência boa `#e4102f`, sinal de marca `#184e92` (régua de topo e kicker), neutros mantidos; amarelo `#ffeb00`/verde `#009647` só dentro dos ativos e o laranja `#f89c0e` não é usado — o mapeamento semântico fixado no hi-fi (C203) não mudou. (3) **Dono único dos ativos:** `scripts/lib/campaignKitAssets.mjs` (novo) passa a ler o kit para os dois renderers (`reelRender` reusa; `build-reel` só trocou o import) com default de root resolvido por `import.meta.url` — cwd-independente, o que mantém entry/e2e rodando de tmpdir; `renderChartHtml(spec, { brandLogo })` segue sync/puro e o entry injeta o ativo (falha com mensagem acionável se o kit sumir). (4) **Compartilhado:** o default de `lineChart` em `chartPrimitives.mjs` acompanha o vermelho oficial; `CHART_COLORS`, dossiês/boletins (snapshots byte-identical) e o mapa seguem intactos. (5) **Prosa e pinos:** `SKILL.md`/command descrevem a marca do kit 1313 (guardrail novo do rodapé oficial), os 4 specs atualizados pinam os literais do gate (data URI, ausência do lockup e do `#c51414`) e `SCRIPTS_SPEC_PINNED` ganhou o módulo novo. Formatos 1080×1350/1080×1080/1080×1920, guardrails (100% local, gitignored, base zero, ≤7 pontos, valência redundante, fonte obrigatória) e o slogan só dentro das marcas completas permanecem. +**C203 — Gráficos de dados do Instagram na marca oficial do kit 1313 (2026-09-19):** os gráficos da skill `graficos-dados` (C191) saem agora na **marca e na paleta oficiais do kit 1313** (C196/C204), resolvendo o débito `NEEDS ASSET · LOGO OFICIAL` registrado no hi-fi aprovado. (1) **Rodapé oficial:** o lockup tipográfico provisório ("JORGE SOLLA"/"MANDATO DEPUTADO FEDERAL") saiu; o rodapé usa `public/campaign-kit/jorge-solla-positivo.png` embutido como data URI (frame 286×90, `object-fit: contain`, `alt` do hi-fi) e o renderer **falha fechado** sem a marca — nunca recria o lockup. (2) **Paleta oficial:** destaque único/valência boa `#e4102f`, sinal de marca `#184e92` (régua de topo e kicker), neutros mantidos; amarelo `#ffeb00`/verde `#009647` só dentro dos ativos e o laranja `#f89c0e` não é usado — o mapeamento semântico fixado no hi-fi (C203) não mudou. (3) **Dono único dos ativos:** `scripts/lib/campaignKitAssets.mjs` (novo) passa a ler o kit para os dois renderers (`reelRender` reusa; `build-reel` só trocou o import) com default de root resolvido por `import.meta.url` — cwd-independente, o que mantém entry/e2e rodando de tmpdir; `renderChartHtml(spec, { brandLogo })` segue sync/puro e o entry injeta o ativo (falha com mensagem acionável se o kit sumir). (4) **Compartilhado:** o default de `lineChart` em `chartPrimitives.mjs` acompanha o vermelho oficial; `CHART_COLORS`, dossiês/boletins (snapshots byte-identical) e o mapa seguem intactos. (5) **Prosa e pinos:** `SKILL.md`/command descrevem a marca do kit 1313 (guardrail novo do rodapé oficial), os 4 specs atualizados pinam os literais do gate (data URI, ausência do lockup e do `#c51414`) e `SCRIPTS_SPEC_PINNED` ganhou o módulo novo. Formatos 1080×1350/1080×1080/1080×1920, guardrails (100% local, gitignored, base zero, ≤7 pontos, valência redundante, fonte obrigatória) e o slogan só dentro das marcas completas permanecem. Crítica de fechamento do `designer` certificada (`Design tier: openai/gpt-5.6-sol`), sem bloqueantes. diff --git a/docs/plans/graficos-dados-marca-kit-1313-impl.md b/docs/plans/graficos-dados-marca-kit-1313-impl.md index 913fbe4e..dc565afc 100644 --- a/docs/plans/graficos-dados-marca-kit-1313-impl.md +++ b/docs/plans/graficos-dados-marca-kit-1313-impl.md @@ -86,11 +86,11 @@ flowchart LR ### Componentes / mudanças -1. **`scripts/lib/campaignKitAssets.mjs` (novo — dono da leitura do kit):** `KIT_ASSETS` verbatim de `reelRender.mjs:121-127` (5 arquivos) + `readKitAssets({ root })` devolvendo data URIs; default `root = join(dirname(fileURLToPath(import.meta.url)), '..', '..')` (repo root, cwd-independente); exporta **só** `readKitAssets` (`KIT_ASSETS` privado — `knip.json` rules `exports: error`); JSDoc; sem dep além de `node:fs/promises`/`node:path`/`node:url`. +1. **`scripts/lib/campaignKitAssets.mjs` (novo — dono da leitura do kit):** `KIT_ASSETS` verbatim de `reelRender.mjs:121-127` (5 arquivos) + `readKitAssets({ root, keys })` devolvendo data URIs (default `keys` = todos; o gráfico pede só `namePositive`); default `root = join(dirname(fileURLToPath(import.meta.url)), '..', '..')` (repo root, cwd-independente); exporta **só** `readKitAssets` (`KIT_ASSETS` privado — `knip.json` rules `exports: error`); JSDoc `@param`/`@returns`; sem dep além de `node:fs/promises`/`node:path`/`node:url`. 2. **`scripts/lib/reelRender.mjs` (editar):** remover `KIT_ASSETS`/`readKitAssets` (`:121-138`); nenhum outro comportamento muda (saída do reel C196 inalterada). 3. **`scripts/build-reel.mjs` (editar):** `readKitAssets` passa a vir de `./lib/campaignKitAssets.mjs` (import atual em `:51`); chamada `:145` mantém `{ root: ROOT }`. 4. **`scripts/lib/graficosInstagramRender.mjs` (editar):** `SOLLA_PALETTE` oficial; CSS `.top-rule`/`.context`→azul e bloco `.brand*` substituído por `.brand-logo-frame`+`img` (286×90, contain); `footer` recebe o data URI; `renderChartHtml(spec, { brandLogo })` sync/puro e fail-closed (ausente ou fora de `data:image/png;base64,`); `alt="Jorge Solla — Deputado Federal"`; `lineChart` chamado com `highlight: SOLLA_PALETTE.highlight` (já passa). -5. **`scripts/build-chart-from-data.mjs` (editar):** importar `readKitAssets`; após `validateSpec` e antes do browser, ler `namePositive` com `readKitAssets()` (**sem** `repoRoot`!) e chamar `renderChartHtml(spec, { brandLogo })` (`:195`); falha na leitura → `die` acionável citando o kit. +5. **`scripts/build-chart-from-data.mjs` (editar):** importar `readKitAssets`; após `validateSpec` e antes do browser, ler só `namePositive` com `readKitAssets({ keys: ['namePositive'] })` (**sem** `repoRoot`!) e chamar `renderChartHtml(spec, { brandLogo })` (`:195`); falha na leitura → `die` acionável citando o kit. 6. **`scripts/lib/chartPrimitives.mjs` (editar):** default `highlight` do `lineChart` (`:504`); `CHART_COLORS` e os demais emissores intactos. 7. **`.agents/skills/graficos-dados/SKILL.md` (editar):** frontmatter (marca/paleta oficiais do kit 1313); `:126` e `:169` `#c51414`→`#e4102f`; guardrail do rodapé com o ativo oficial (nunca recriar lockup); referências ao `public/campaign-kit/README.md` e a `docs/plans/graficos-dados-marca-kit-1313.md`. 8. **`.opencode/commands/graficos-dados.md` (editar):** descrição `:2` — "na marca e paleta oficiais do kit 1313". @@ -142,9 +142,14 @@ Total ~1,0 dia (0,80 de código+testes, 0,15 de prova/crítica, 0,05 de fechamen - **Limpar os resíduos de ilustração do hi-fi** (`:1966-1975`, `:2127-2130`) — sem trigger (a); a revisão C203 é a autoridade; se quiserem consistência do arquivo, item de design separado. - **Editor gráfico / configurar cores** — template fixo + dados de entrada. - **Expor amarelo/verde na paleta** — eles só vivem dentro dos ativos; expor é furar o guardrail. +- **Unificar os defaults de `chartPrimitives` com `SOLLA_PALETTE` (S10)** — decisão (iv) travada; unificar importaria a paleta do kit para dentro do dono compartilhado e os neutros já existem assim em `main`. - **Migration/schema/DB/Consent/access** — ferramenta local, sem persistência. - **Commitar PNG/dado** — saídas gitignored. +## Adiado com gatilho (triage pós-simplify) + +- **S9 — root redundante em `scripts/build-reel.mjs:145`:** gatilho: na próxima edição de `build-reel.mjs`, trocar `readKitAssets({ root: ROOT })` por `readKitAssets()` — o default do dono resolve o mesmo repo root e passa a ser a única resolução. + ## Riscos e mitigação - **Ativo resolvido por cwd/`repoRoot` quebra testes e e2e (cwd tmp).** Default por `import.meta.url` no novo dono; o entry chama sem root; prova no entry-spec (data URI com `repoRoot: tmpdir`) e no e2e (`cwd: workDir`). Se alguém passar `repoRoot`, o ENOENT aparece no teste, não em produção. diff --git a/scripts/build-chart-from-data.mjs b/scripts/build-chart-from-data.mjs index 924d6325..3e42faa7 100644 --- a/scripts/build-chart-from-data.mjs +++ b/scripts/build-chart-from-data.mjs @@ -195,7 +195,7 @@ export const main = async ({ let brandLogo = '' try { - const assets = await readKitAssets() + const assets = await readKitAssets({ keys: ['namePositive'] }) brandLogo = assets.namePositive } catch (error) { die( diff --git a/scripts/lib/campaignKitAssets.mjs b/scripts/lib/campaignKitAssets.mjs index 64a9806c..b183f8b0 100644 --- a/scripts/lib/campaignKitAssets.mjs +++ b/scripts/lib/campaignKitAssets.mjs @@ -19,10 +19,21 @@ const KIT_ASSETS = { const defaultRoot = join(dirname(fileURLToPath(import.meta.url)), '..', '..') -/** Official campaign kit marks as data URIs (committed under `public/campaign-kit`). */ -export const readKitAssets = async ({ root = defaultRoot } = {}) => { +/** + * Official campaign kit marks as data URIs (committed under `public/campaign-kit`). + * + * @param {{ root?: string, keys?: string[] }} [options] repo root (defaults to + * this module's repo) and the asset keys to read (defaults to all). + * @returns {Promise>} data URI per requested key. + */ +export const readKitAssets = async ({ + root = defaultRoot, + keys = Object.keys(KIT_ASSETS), +} = {}) => { const entries = await Promise.all( - Object.entries(KIT_ASSETS).map(async ([key, file]) => { + keys.map(async (key) => { + const file = KIT_ASSETS[key] + if (!file) throw new Error(`ativo do kit desconhecido: ${key}`) const bytes = await readFile(resolve(root, 'public/campaign-kit', file)) return [key, `data:image/png;base64,${bytes.toString('base64')}`] }), diff --git a/scripts/lib/graficosInstagramRender.mjs b/scripts/lib/graficosInstagramRender.mjs index 41eca839..4dde2e3e 100644 --- a/scripts/lib/graficosInstagramRender.mjs +++ b/scripts/lib/graficosInstagramRender.mjs @@ -192,13 +192,13 @@ const plotBody = (spec) => { return rankingBody(spec) } -const brandLogo = (brandLogoDataUri) => `
- Jorge Solla — Deputado Federal +const brandMark = (brandMarkDataUri) => `
+ Jorge Solla — Deputado Federal
` -const footer = (spec, brandLogoDataUri) => `