# Decisões das fases F7+ — registro de 2026-10-23

> **Status:** decisões do dono, tomadas sobre o [`INVENTARIO.md`](./INVENTARIO.md) §4.
> **Autoridade:** `AGENTS.md` e os ADRs vencem este registro; aqui ficam a escolha, o escopo e as
> consequências operacionais. Implementação só começa com a fatia no `kd` e o ADR/emenda aceito.

## 1. Quadro final

| # | Decisão | Escolha | Efeito no plano |
|---|---|---|---|
| **D1** | Configurações tipadas | **A** — JSON por escopo, schema em código, foco no tema e no tema de widgets | `core_settings` por seção; `theme`/`theme.widgets` (ADR-046) |
| **D2** | Seções/páginas | **A** — catálogo fechado | Edição profunda só em Home e no módulo de páginas estáticas; demais módulos só posicionam widgets (emenda ADR-016) |
| **D3** | Módulos essenciais | **A** — lista estática | Grupo `Suporte` inteiro é exceção garantida; invisível/404 por padrão para todos, exceto `suporte@maxima.inf.br` (emenda ADR-034) |
| **D4** | Métricas | **A** — agregados simples, sem PII | `core_metrics_daily` + HLL; sem APM (ADR-047) |
| **D5** | Legislação | **A** — versões + consolidação/revogação | Versão imutável e URL estável (ADR-048) |
| **D6** | Navegação/layout por área | **A** — porta no Core + botão por módulo | Porta `Navigation`; layout da área com fallback na configuração global definida pelo Suporte **na área de Suporte** |
| **D7** | Search | **A** — local → service no 2º consumidor | Cada módulo chama o service e envia objeto padrão `portal` e `cms`; integração opcional (ADR-050) |
| **D8** | Importador | **A** — CSV operacional | Preview/dry-run/apply com Poka-yoke visual; porta no Core (ADR-051) |
| **D9** | Transparência | **A** — DadosAbertos é o único owner | Demais páginas/módulos são views; sem dataset/serializador paralelo (emenda ADR-049) |
| **D10** | Integrações externas | **Adiadas para o fim do backlog** | P13 vira trilha opcional; reavaliar após **toda** a implementação |
| **D11** | Câmara | **A, com implantação posterior** | Manter desenho A; executar quando o gate abrir; se simples, tratar como backlog |
| **D12** | Vídeo | **A** — link externo | Sem embed; thumbnail local; embed só com ADR nova |
| **D13** | Pessoas | **A** — allowlist mínimo | Sem CPF/matrícula; remuneração só com base legal/parecer |
| **D14** | Associações | **A, com implantação posterior** | Sem multi-tenant; executar quando houver cliente; se simples, backlog |
| **D15** | Saúde | **Adiada** | Reavaliar quando a fase for iniciada; DPIA/base legal antes de qualquer código |
| **D16** | Dados abertos | **A** — pull-based | ADR-049 aceita; registry no Core; um serializador |
| **D17** | Solicitações de serviços | **A** — módulo com catálogo/protocolo | Especificação detalhada em P25 e no backlog; sem helpdesk genérico (ADR-052) |
| **D18** | Declarações de inexistência | **A** — conteúdo estruturado | Tabela + AST + componente; sem HTML livre (aplicação de ADR-017/028) |
| **D19** | VIAP/cotas | **A** — P17 é dono | P28 apenas lê/apresenta por porta Core; sem tabela duplicada (ADR-054) |
| **D20** | PDF pesquisável | **A** — gerado pelo sistema tem texto a partir do dado bruto; anexo externo sem OCR | Diário Oficial gerado a partir do dado; externo é atestado/aviso (ADR-053) |

## 2. Nuances que precisam sobreviver à implementação

### D1 — Configuração é um JSON por escopo

- `core_settings` guarda **um documento JSON por seção** (`institution`, `theme`, `cms`, `seo`,
  `system`, `support`), não uma chave avulsa por linha. `section()` lê a seção inteira em uma query.
- `theme` carrega `portal`, `cms` e `widgets`; `widgets` é um mapa por id/tipo de widget com os
  mesmos tokens semânticos do tema. O schema do widget valida o subconjunto; chave desconhecida é
  ignorada.
- Campos `secret` ficam em payload cifrado separado; a leitura pública mascara; auditoria registra
  apenas “mudou/não mudou”, nunca o valor.
- Precedência: banco → `config/` fallback → default do schema. Valor inválido é ignorado e logado.
- **Não** criar motor de settings por módulo, endpoint de chave avulsa ou JSON livre editável.

### D2 — Edição profunda é exceção, não regra

- **Home** (`Portal/Home`) e o módulo especial de **páginas estáticas** (`Portal/Paginas`) usam o
  catálogo fechado de blocos, schema por tipo, preview autenticado e publicação versionada.
- Os demais módulos **não** ganham editor de seções/blocos. Eles só declaram seus widgets e o
  posicionamento é feito pelo botão/ação **“Configurar layout da área/módulo”**.
- O catálogo fechado continua valendo para Home/Páginas: nada de HTML/Blade/CSS no banco; tipo
  desconhecido ou `props` inválido é ignorado; `hidden` preserva posição.

### D3 — Suporte é exceção dura

- `config/core.php` mantém `essential_modules` (mínimo: `Acesso`, `Configuracoes`).
- **Todo módulo do grupo `Suporte`** é inibível de desativação, independentemente de lista, perfil
  ou `--force`. A UI não oferece o toggle; a Action recusa; o comando falha com mensagem.
- O grupo continua **invisível e 404** para todos, exceto `suporte@maxima.inf.br` (ADR-033).
- Para os demais essenciais, a UI recusa; `--force` existe **apenas no CLI de suporte** e é auditado.

### D6 — Layout por área com fallback global

- Porta `Navigation` no Core: o módulo `Menus` registra a implementação; `layout` nunca importa
  módulo.
- O botão **“Configurar layout da área/módulo”** abre a mesma superfície de layout, escopada à rota
  ou ao módulo; ele edita **posições de widgets** (slots), não blocos de conteúdo.
- Precedência: perfil da área/módulo → configuração global definida pelo Suporte **na área de
  Suporte** → default do preset. Sem perfil, o global vale. Widget de módulo inativo não aparece.
- A permissão é da superfície de layout (Suporte/admin), não uma permissão nova por módulo; o módulo
  só declara o escopo e os widgets que oferece.
- Sem posição absoluta/pixel; a ordem é a pilha do slot e o DOM acompanha a posição visual.

### D7 — Search é opcional e tem dois objetos

- A integração é **opt-in por módulo**. Um módulo sem `SearchSource` simplesmente não entra no
  índice; não quebra o build.
- O módulo **chama o service** e envia um objeto padrão **separado por escopo**:
  - `portal`: URL pública, título/resumo/corpo, locale, `published_at`, visibilidade pública;
  - `cms`: URL do painel, título/resumo, locale, permissão `{module}.ver`, status editorial.
- O índice guarda `scope` (`portal|cms`), `module`, `entity_type`, `entity_id`, `locale`; a busca
  filtra por escopo e permissão. Não há mistura de resultado público com rascunho.
- O service nasce em P9 com o 2º consumidor; P7 mantém a busca local de Notícias. O cutover de
  Notícias para o índice compartilhado é obrigatório em P9 (uma verdade).
- Reindexação idempotente; despublicado sai; `ts_headline` escapado; sem trigger paralelo.

### D8 — Importador com Poka-yoke visual

- Preview e relatório mostram, por linha: válida, inválida, duplicada, ignorada; erro no campo;
  contagem e amostra; nenhuma escrita antes da confirmação.
- Alertas visuais claros (não só cor), resumo antes/depois, confirmação explícita e dry-run.
- Referência de UX: `../lotep` (preview → relatório → apply), sem copiar código.
- Regras: CSV streaming, encoding/delimitador, limite de linhas/bytes, anti-CSV-injection, chave
  idempotente, falha parcial sem abortar o lote, arquivo privado no S3, job com retry.

### D9 — DadosAbertos é o único owner da camada pública

- `Portal/DadosAbertos` é dono do catálogo, datasets, DCAT/INDA, export, `ETag` e serialização.
- Nenhum outro módulo cria dataset, tabela de dataset ou serializador paralelo. Páginas de
  transparência são **views/curadoria** sobre datasets existentes.
- Módulos de domínio (P22–P24) continuam donos dos **dados operacionais** e expõem uma
  `DatasetSource`; o dado público é lido por DadosAbertos. Se um módulo só apresenta dado, ele é
  view — não ganha tabela própria.
- `/transparencia` não tem tabela de dados; usa blocos/páginas e links para datasets.

### D10–D15 — Adiamentos e gates

- **D10:** P13 inteira fica para o fim do backlog, opcional, reavaliada após **toda** a
  implementação. Nenhum item externo bloqueia P0–P29. gov.br/ICP/e-mail/CDN não entram no caminho
  crítico.
- **D11:** manter o desenho A (perfil Câmara + grupo ativável), mas a implantação fica posterior.
  Se o escopo for simples, tratar como backlog; se complexo, executar A quando houver contrato.
- **D14:** idem D11 para associações; sem multi-tenant; `unidades_regionais` é referência.
- **D15:** saúde fica para o fim, com a decisão tomada **quando a fase for iniciada**; DPIA/base
  legal/DPO antes de abrir. Público agregado é o padrão; individual só com necessidade jurídica e
  pseudonimização.
- **D12/D13:** link-only e allowlist mínimo valem desde já quando a fase abrir.

### D17 — Solicitações de serviços digitais

- Módulo `Servicos/Solicitacoes` (não service, não helpdesk): catálogo de serviços, protocolo,
  acompanhamento, prazos, anexos privados e consentimento.
- Reusa `ProtocolGenerator`/`Deadline` de P11 por composição/convenção, sem trait.
- Cada serviço tem `form_schema` fechado (campos, tipos, obrigatórios, validação) e um fluxo de
  status simples; sem motor de workflow genérico.
- CMS responde; portal acompanha por link assinado; LGPD/retention; sem PII em log.
- Especificação detalhada: [`P25`](./P25-sic-lgpd-governo-digital.md) §3/S3 e
  [`wiki/backlog/servico-solicitacoes.md`](../backlog/servico-solicitacoes.md).

### D18 — Declarações são conteúdo estruturado

- Tabela `declaracoes_inexistencia` com critério, módulo, período, texto AST, publicação e estado.
- Componente `<x-pntp::declaracao>`; aparece quando o conjunto está vazio; 4 locales; export.
- Nada de HTML/Blade no banco.

### D19 — VIAP/cotas tem um dono

- `Transparencia/Viap` (P17) é dono da tabela e dos valores.
- P28 lê/apresenta cotas/verba no perfil legislativo; não cria segunda tabela.
- Se P17 não for executado no perfil, P28 referencia o módulo quando ativo; não duplica.

### D20 — PDF pesquisável

- **PDF gerado pelo sistema** (Diário Oficial, atos, relatórios) é produzido a partir do dado bruto
  no banco, com camada de texto real; a busca indexa o texto estruturado e o PDF é pesquisável.
- **PDF anexado externo** não passa por OCR. Media registra `pdf_pesquisavel` como atestado
  (`true|false|unknown`) e o CMS avisa; sem promessa de pontuação quando não há camada de texto.
- Se o cliente exigir OCR, é decisão separada (dependência, custo, privacidade), fora do padrão.

## 3. Consequências no programa

- **P0** implementa settings por payload JSON, incluindo `theme.widgets`.
- **P1** define a porta `Navigation` e a superfície de layout por área com fallback global.
- **P3** endurece a ADR-034: `Suporte` é grupo intocável; essenciais recusam desativação.
- **P5** limita edição profunda a Home e páginas estáticas; demais módulos só widgets.
- **P7/P9** implementam busca opcional com objetos `portal`/`cms` e importador Poka-yoke.
- **P12** não cria módulo/dataset paralelo; DadosAbertos é o owner público.
- **P13/P18/P20/P21** ficam posteriores/condicionais, sem bloquear o núcleo.
- **P25** ganha a especificação de `Solicitacoes`.
- **P29** implementa declarações estruturadas e a política de PDF.
- **P17/P28** confirmam VIAP/cotas com dono único.

## 4. Cobertura arquitetural das decisões

| Decisão | Onde está a decisão arquitetural |
|---|---|
| D1 | **ADR-046** (settings por escopo) |
| D2 | **ADR-016**, emenda de 2026-10-23 (Home/páginas × blocos) |
| D3 | **ADR-034**, emenda de 2026-10-23 (essenciais + `Suporte` intocável) |
| D4 | **ADR-047** (métricas privacy-first) |
| D5 | **ADR-048** (legislação versionada) |
| D6 | **ADR-016**, emenda de 2026-10-23 (layout por área) |
| D7 | **ADR-050** (busca local-first + serviço no 2º consumidor) |
| D8 | **ADR-051** (importação CSV operacional) |
| D9 | **ADR-049**, emenda de 2026-10-23 (`DadosAbertos` owner único) |
| D10–D15 | roadmap/produto; D12 é regra da **ADR-002**, D14 é single-tenant da **ADR-001/042**; sem ADR nova |
| D16 | **ADR-049** (motor pull-based) |
| D17 | **ADR-052** (módulo de solicitações) |
| D18 | aplicação das **ADR-017/028**; sem ADR nova (conteúdo estruturado, sem HTML) |
| D19 | **ADR-054** (dono único de VIAP/cotas) |
| D20 | **ADR-053** (PDF pesquisável, sem OCR) |

## 5. Pendências antes do código

- [x] **ADR-046** (settings por escopo), **ADR-047** (métricas) e **ADR-048** (legislação)
      aceitas em `wiki/adr/`.
- [x] **ADR-049** (motor de dados abertos) aceita em `wiki/adr/`.
- [x] **ADR-050** (busca), **ADR-051** (importação CSV), **ADR-052** (solicitações),
      **ADR-053** (PDF) e **ADR-054** (VIAP/cotas) aceitas em `wiki/adr/`.
- [x] Emendas à **ADR-016** (Home/Páginas × layout por área), **ADR-034** (Suporte intocável) e
      **ADR-049** (`DadosAbertos` como owner único) registradas nos próprios ADRs.
- [x] Especificação de `Solicitacoes` no backlog e revisão de P25.S3.
- [ ] Registrar no `kd` a decisão D1–D20 e as âncoras dos arquivos alterados.
