{
  "id": "pt-quadro",
  "versao": "0.1.0",
  "atualizado": "2026-09-18",
  "nota": "O quadro de cada agente. Um cartão em «assuntos» é trabalho que o agente abriu para si; um issue do jornal chega ao quadro pela fórmula publicada em dados/agentes.json e por mais nada.",
  "formula": {
    "nota": "A quem pertence um issue do jornal não é escrito à mão em lado nenhum: sai do seu estado, por esta tabela, e é por isso que o quadro não pode discordar dos ficheiros. Um cartão em «assuntos» é diferente: é o trabalho que o próprio agente abriu, e esse é escrito por ele.",
    "de_estado_para_agente": {
      "procurado": "pesquisa.pt",
      "rascunho": "verificacao.pt",
      "verificado": "dinis.humano",
      "congelado": "dinis.humano",
      "publicado": "—",
      "superseded": "—"
    },
    "porque": {
      "procurado": "Falta-lhe uma fonte congelada. Quem a vai buscar é a pesquisa.",
      "rascunho": "Tem prosa. O passo seguinte é alguém reler cada fonte citada na cópia congelada.",
      "verificado": "Está lido e registado. Publicar é a linha do editor de registo, e de mais ninguém.",
      "congelado": "É uma entrega exterior à espera de aprovação item a item, que só o editor dá.",
      "publicado": "Está fora do quadro.",
      "superseded": "Está fora do quadro."
    },
    "colunas": [
      "abertos",
      "bloqueados",
      "fechados"
    ]
  },
  "colunas": [
    "abertos",
    "bloqueados",
    "fechados"
  ],
  "contagens": {
    "cartoes": 17,
    "issues_do_jornal": 3,
    "agentes": 5
  },
  "por_agente": {
    "pesquisa.pt": {
      "agente": "pesquisa.pt",
      "alias": "@Pesquisa",
      "nome": "Pesquisa",
      "colunas": {
        "abertos": [
          {
            "ficheiro": "redacao/correio/pesquisa.pt/assuntos/abertos/001__pdf-do-diario-da-republica.md",
            "agente": "pesquisa.pt",
            "coluna": "abertos",
            "origem_tipo": "assunto",
            "titulo": "O PDF do Diário da República, para a agenda e para a designação",
            "aberto": "2026-09-14T12:10:00Z",
            "prioridade": "alta",
            "esforco": "2h",
            "bloqueado_por": "—",
            "issue": "001,002",
            "origem": "redacao/correio/pesquisa.pt/entrada/002__dinis.humano__tres-primeiras-historias.eml",
            "corpo": "## O que há para fazer\nEncontrar o endereço do PDF do Diário da República para o diploma da agenda nacional (001) e para\no ato de designação do regulador (002). O `dre.pt` congelado a 14 de setembro tem 2 346 bytes e\n22 caracteres visíveis: renderiza por script e não diz nada a um leitor automático. Os PDFs dizem,\ne `build/pdf.py` já os lê — decifra o manipulador de segurança padrão e segue o mapa `/ToUnicode`.\n\n## Como penso fazê-lo\n1. Encontrar o endereço a partir de uma página que o nomeie, e não por construção.\n2. Obter, congelar em `fontes/congeladas/<data>/`, hashear e registar.\n3. Ler o PDF com `build/pdf.py` e extrair o que a fonte diz, sem arrumar nada.\n4. Escrever a @Redacao dizendo o que passou a estar em bytes.\n\n## Critério de aceitação\n- O PDF congelado, com SHA-256 no registo, e o hash a reverificar em cada construção.\n- O instrumento legal nomeado com o número e a data que o PDF diz, e não outros.\n- Se o endereço não for encontrado, o issue fica em «procurado» e a ausência é escrita como\n  ausência. Um endereço inventado que devolve outro diploma é pior do que um que devolve 404.",
            "resumo": "Encontrar o endereço do PDF do Diário da República para o diploma da agenda nacional (001) e para o ato de designação do regulador (002). O `dre.pt` congelado a 14 de setembro tem 2 346 bytes e 22 caracteres visíveis: renderiza por script e não diz nada a um leitor automático. Os PDFs dizem, e `buil"
          },
          {
            "ficheiro": "redacao/correio/pesquisa.pt/assuntos/abertos/002__ausencias-publicaveis-tal-como-estao.md",
            "agente": "pesquisa.pt",
            "coluna": "abertos",
            "origem_tipo": "assunto",
            "titulo": "Duas ausências publicáveis tal como estão",
            "aberto": "2026-09-14T12:10:00Z",
            "prioridade": "média",
            "esforco": "1h",
            "bloqueado_por": "—",
            "issue": "003",
            "origem": "redacao/correio/pesquisa.pt/entrada/002__dinis.humano__tres-primeiras-historias.eml",
            "corpo": "## O que há para fazer\nO portal de transparência do plano de recuperação não resolveu em nenhuma tentativa desta redação,\ne a lista de unidades de I&D devolveu 404. Estão as duas em `dados/excluidas.json`. O editor disse\nque ambas as ausências são publicáveis tal como estão — o que há para fazer é dizê-lo a @Redacao,\ncom a medição ao lado, para que a história 003 se escreva sobre o registo e não sobre a falta dele.\n\n## Como penso fazê-lo\n1. Confirmar que cada ausência tem em `dados/excluidas.json` o endereço, a hora e o que devolveu.\n2. Escrever a @Redacao: o facto estrutural (não há registo comercial aberto em Portugal) está\n   sustentado; a contagem de startups de IA não está, e nenhum conjunto de dados público a dá.\n\n## Critério de aceitação\n- Cada ausência com endereço, hora e resposta medida, no ficheiro, e não em prosa.\n- Nenhuma contagem estimada. A história é sobre porque não existe contagem.",
            "resumo": "O portal de transparência do plano de recuperação não resolveu em nenhuma tentativa desta redação, e a lista de unidades de I&D devolveu 404. Estão as duas em `dados/excluidas.json`. O editor disse que ambas as ausências são publicáveis tal como estão — o que há para fazer é dizê-lo a @Redacao, com "
          }
        ],
        "bloqueados": [
          {
            "ficheiro": "redacao/correio/pesquisa.pt/assuntos/bloqueados/003__acesso-a-anacom.md",
            "agente": "pesquisa.pt",
            "coluna": "bloqueados",
            "origem_tipo": "assunto",
            "titulo": "Acesso à página da ANACOM, que devolve 403",
            "aberto": "2026-09-14T12:10:00Z",
            "prioridade": "alta",
            "esforco": "—",
            "bloqueado_por": "dinis.humano",
            "issue": "002",
            "origem": "redacao/correio/pesquisa.pt/entrada/002__dinis.humano__tres-primeiras-historias.eml",
            "corpo": "## O que há para fazer\nA página da ANACOM que uma entrega apresenta como autoridade nacional no âmbito do AI Act devolve\n403 a esta redação. Nada se pode conferir contra ela.\n\n## Porque está bloqueado\n403 não é uma recusa de informação: é um servidor a bloquear um cliente. Pedir acesso é falar em\nnome desta publicação com uma entidade nomeada, e isso é do editor de registo. A pesquisa não pede\nacesso, não contorna o bloqueio e não cita a página por outra via.\n\n## Critério de aceitação para desbloquear\nUma decisão de @Dinis: pedir acesso, ou escrever a história sobre a ausência no registo público\nlegível, dizendo que a página existe e que devolveu 403 a esta redação à hora medida.",
            "resumo": "A página da ANACOM que uma entrega apresenta como autoridade nacional no âmbito do AI Act devolve 403 a esta redação. Nada se pode conferir contra ela. 403 não é uma recusa de informação: é um servidor a bloquear um cliente. Pedir acesso é falar em nome desta publicação com uma entidade nomeada, e i"
          }
        ],
        "fechados": []
      },
      "issues_do_jornal": [
        {
          "ficheiro": "redacao/issues/003-quantas-startups-ia.json",
          "agente": "pesquisa.pt",
          "coluna": "abertos",
          "origem_tipo": "issue",
          "id": "003",
          "titulo": "Quantas das startups ativas em Portugal são empresas de IA, e porque nenhum conjunto de dados público o diz",
          "estado": "procurado",
          "seccao": "empresas",
          "aberto": "2026-09-14",
          "porque_aqui": "Falta-lhe uma fonte congelada. Quem a vai buscar é a pesquisa.",
          "o_que_falta": [
            "O portal de transparência do plano de recuperação não resolveu em nenhuma tentativa desta redação (dados/excluidas.json). É metade da semente aberta do dia um, e a sua ausência é ela própria publicável.",
            "A lista de unidades de I&D da FCT devolveu 404 no endereço tentado. Encontrar o endereço certo.",
            "O número de startups ativas tem de vir de uma fonte congelada, e não do relatório de ecossistema que o resumo marca como não sendo um conjunto de dados."
          ]
        }
      ],
      "entrada": [
        {
          "ficheiro": "redacao/correio/pesquisa.pt/entrada/002__dinis.humano__tres-primeiras-historias.eml",
          "lugar": "entrada",
          "caixa": "pesquisa.pt",
          "de": "dinis.humano",
          "para": "pesquisa.pt",
          "de_alias": "@Dinis",
          "para_alias": "@Pesquisa",
          "assunto": "As três primeiras histórias estão abertas como issues em «procurado»",
          "quando": "2026-09-14T12:05:00Z",
          "id": "002-tres-primeiras-historias@redacao.local",
          "responde_a": null,
          "issue": "001,002,003",
          "run": "2026-09-14T12:00:00Z",
          "historica": false,
          "migrado_de": "redacao/correio/pesquisa/entrada/2026-09-14T1205__editor__tres-primeiras-historias.md",
          "corpo": "As três histórias que o resumo de comissionamento encomenda estão abertas. Nenhuma pode avançar\nsem uma fonte congelada que a sustente, e as três dizem no próprio ficheiro o que já se tem e o\nque falta.\n\nPara a 001 e a 002 o caminho é o mesmo e está agora aberto: o PDF do Diário da República. Encontre\no endereço, não o construa por adivinhação — um endereço inventado que devolve outro diploma é pior\ndo que um que devolve 404.\n\nPara a 003, o portal de transparência do plano de recuperação não resolveu em nenhuma tentativa, e\na lista de unidades de I&D devolveu 404. Ambas as ausências são publicáveis tal como estão.",
          "resumo": "As três histórias que o resumo de comissionamento encomenda estão abertas. Nenhuma pode avançar sem uma fonte congelada que a sustente, e as três dizem no próprio ficheiro o que já se tem e o que falta. Para a 001 e a 002 o caminho é o mesmo e está agora aberto: o PDF do Diário da República. Encontre o endereço, não o construa por adivinhação — um endereço inventado que devolve outro diploma é pior do que um que devo",
          "bytes": 1141,
          "desconhecido": []
        }
      ],
      "em_transito": [],
      "contagens": {
        "abertos": 2,
        "bloqueados": 1,
        "fechados": 0,
        "issues_do_jornal": 1,
        "por_tratar": 1,
        "em_transito": 0
      }
    },
    "redacao.pt": {
      "agente": "redacao.pt",
      "alias": "@Redacao",
      "nome": "Redação",
      "colunas": {
        "abertos": [],
        "bloqueados": [],
        "fechados": []
      },
      "issues_do_jornal": [],
      "entrada": [],
      "em_transito": [],
      "contagens": {
        "abertos": 0,
        "bloqueados": 0,
        "fechados": 0,
        "issues_do_jornal": 0,
        "por_tratar": 0,
        "em_transito": 0
      }
    },
    "verificacao.pt": {
      "agente": "verificacao.pt",
      "alias": "@Verificacao",
      "nome": "Verificação",
      "colunas": {
        "abertos": [],
        "bloqueados": [],
        "fechados": []
      },
      "issues_do_jornal": [],
      "entrada": [],
      "em_transito": [],
      "contagens": {
        "abertos": 0,
        "bloqueados": 0,
        "fechados": 0,
        "issues_do_jornal": 0,
        "por_tratar": 0,
        "em_transito": 0
      }
    },
    "bastidores.pt": {
      "agente": "bastidores.pt",
      "alias": "@Bastidores",
      "nome": "Bastidores",
      "colunas": {
        "abertos": [
          {
            "ficheiro": "redacao/correio/bastidores.pt/assuntos/abertos/001__a-vista-dos-agentes-e-o-correio.md",
            "agente": "bastidores.pt",
            "coluna": "abertos",
            "origem_tipo": "assunto",
            "titulo": "A vista dos agentes, o quadro de cada um, e o correio",
            "aberto": "2026-09-14T23:30:00Z",
            "prioridade": "alta",
            "esforco": "6h",
            "bloqueado_por": "—",
            "issue": "—",
            "origem": "pedido de @Dinis, nesta sessão",
            "corpo": "## O que há para fazer\nDar ao editor, nos bastidores, a vista de quem são os agentes, do que cada um tem à frente, e do\ncorreio que passou entre eles. Antes disto, saber em que pé estava uma história queria dizer abrir\num terminal e ler pastas.\n\n## Como penso fazê-lo\n1. `dados/agentes.json` — o registo dos agentes no formato que teams.sgit.ai publica para um\n   `ROLE.md`: missão, afirmação central escrita como condição de falha, e o «não responsável por»\n   sem o qual cada papel se torna o mesmo papel.\n2. `redacao/correio/` no protocolo Email-FS-lite: escritor único, expedição partilhada, um commit\n   por ciclo. As duas mensagens que já existiam passam a `.eml` com o corpo intacto.\n3. Um leitor só — `build/backoffice_team.py` — que lê a pasta e escreve `dados/correio.json` e\n   `dados/quadro.json`. As páginas leem o derivado e nunca a pasta, para não haver dois leitores.\n4. Três páginas: a equipa, o quadro por agente, e o correio.\n\n## Critério de aceitação\n- Nenhum número nestas páginas que não seja a contagem de ficheiros deste repositório.\n- O quadro a derivar a posse de cada issue do jornal por fórmula publicada, e não à mão.\n- Os portões verdes: `build/gates.py`, `build/gates_artigos.py`, `admin/build/validate.js`.",
            "resumo": "Dar ao editor, nos bastidores, a vista de quem são os agentes, do que cada um tem à frente, e do correio que passou entre eles. Antes disto, saber em que pé estava uma história queria dizer abrir um terminal e ler pastas. 1. `dados/agentes.json` — o registo dos agentes no formato que teams.sgit.ai p"
          }
        ],
        "bloqueados": [
          {
            "ficheiro": "redacao/correio/bastidores.pt/assuntos/bloqueados/002__a-fila-de-acrescento-nao-tem-credenciais.md",
            "agente": "bastidores.pt",
            "coluna": "bloqueados",
            "origem_tipo": "assunto",
            "titulo": "A fila de acrescento não tem credenciais",
            "aberto": "2026-09-14T23:30:00Z",
            "prioridade": "alta",
            "esforco": "—",
            "bloqueado_por": "dinis.humano",
            "issue": "—",
            "origem": "pedido de @Dinis, nesta sessão",
            "corpo": "## O que há para fazer\nA ponte que deixa o editor escrever aos bastidores a partir do navegador está construída e não tem\npor onde enviar. Uma fila de acrescento precisa de três coisas, e nenhuma delas pode estar neste\nrepositório.\n\n## O que falta, e porque não pode estar aqui\n| O quê | Para quê | Porque não fica em ficheiro |\n|---|---|---|\n| `vault_id` do cofre que recebe | O endereço do `POST` | Identifica o cofre; junto ao código de acrescento dava a fila inteira a quem lesse o repositório |\n| `append_token` (hex, 16–128) | Autoriza o acrescento, e só o acrescento | É uma credencial. Quem a tem escreve; não lista, não obtém, não lê |\n| chave pública do destinatário | Cifrar no navegador antes de enviar | Esta **pode** ser publicada — uma chave pública publica-se. Falta só porque ainda não foi gerada |\n\nO `validate.js` tem um detetor de cadeias com forma de chave e falha a construção se uma aparecer.\nÉ por isso que as três são dadas ao navegador em tempo de execução e guardadas em\n`localStorage`, e não commitadas.\n\n## Critério de aceitação para desbloquear\n@Dinis dá o `vault_id`, o `append_token` e a chave pública. A página `/backoffice/bridges.html`\nrecebe-os no navegador, confirma com um envio de prova, e a ponte passa de «sem credencial» a\n«a enviar».",
            "resumo": "A ponte que deixa o editor escrever aos bastidores a partir do navegador está construída e não tem por onde enviar. Uma fila de acrescento precisa de três coisas, e nenhuma delas pode estar neste repositório. | O quê | Para quê | Porque não fica em ficheiro | |---|---|---| | `vault_id` do cofre que "
          },
          {
            "ficheiro": "redacao/correio/bastidores.pt/assuntos/bloqueados/003__nao-consigo-ler-os-cofres-do-jogo.md",
            "agente": "bastidores.pt",
            "coluna": "bloqueados",
            "origem_tipo": "assunto",
            "titulo": "Não consigo ler os cofres dos jogos",
            "aberto": "2026-09-14T23:30:00Z",
            "prioridade": "média",
            "esforco": "—",
            "bloqueado_por": "a caixa onde esta sessão corre",
            "issue": "—",
            "origem": "pedido de @Dinis, nesta sessão",
            "corpo": "## O que há para fazer\n@Dinis deu as chaves de leitura de dois cofres — o dos jogos de permissões e o cofre de telemetria\na que ele enviava — para eu ler como a telemetria de cofre para cofre foi montada, inclusive em\ncommits anteriores.\n\n## Porque está bloqueado\n`pip install sgit-ai` foi recusado pelo classificador da caixa onde esta sessão corre\n(«Untrusted Code Integration»), e sem o `sgit` não há como decifrar um cofre: a decifração é do\nlado do cliente e a chave de leitura não serve por HTTP simples. As chaves **não** foram escritas\nem ficheiro nenhum deste repositório.\n\n## O que foi feito em vez disso\nO desenho foi lido na fonte publicada, que diz o suficiente:\n`sgit.ai/docs/vault-messaging.md`, `sgit.ai/api/append-lanes.md`,\n`sgit.ai/docs/briefs/vault-telemetry-append-lanes.md` e a página do próprio cofre dos jogos em\n`sgit.ai/demos/vaults/agent-permission-games/`. Daí saiu um achado que muda o desenho aqui: o\ncofre dos jogos não conseguia enviar porque uma aplicação de cofre corre numa moldura cujo CSP é\n`connect-src blob: data:`. **Este site não é uma aplicação de cofre** — é um site estático — e por\nisso o `fetch` direto para `/api/vault/append/write/` funciona sem pedir permissão de rede a\nninguém.\n\n## Critério de aceitação para desbloquear\nUma de duas: permissão para instalar o `sgit` nesta caixa, ou uma sessão onde ele já esteja.\nNenhuma é urgente — a ponte não depende disto, só a leitura dos commits antigos depende.",
            "resumo": "@Dinis deu as chaves de leitura de dois cofres — o dos jogos de permissões e o cofre de telemetria a que ele enviava — para eu ler como a telemetria de cofre para cofre foi montada, inclusive em commits anteriores. `pip install sgit-ai` foi recusado pelo classificador da caixa onde esta sessão corre"
          }
        ],
        "fechados": []
      },
      "issues_do_jornal": [],
      "entrada": [],
      "em_transito": [
        {
          "ficheiro": "redacao/correio/expedicao/bastidores.pt/005__dinis.humano__os-resumos-de-investigacao-precisam-de-uma-pagina.eml",
          "lugar": "expedicao",
          "caixa": "bastidores.pt",
          "de": "dinis.humano",
          "para": "bastidores.pt",
          "de_alias": "@Dinis",
          "para_alias": "@Bastidores",
          "assunto": "Os resumos de investigação precisam de uma página que os renderize, e não de uma segunda cópia",
          "quando": "2026-09-15T09:40:00Z",
          "id": "005-resumos-em-html@redacao.local",
          "responde_a": null,
          "issue": "010",
          "run": null,
          "historica": false,
          "migrado_de": null,
          "corpo": "O QUE PEÇO\n\nUma página HTML que renderize\n`briefs/pack/08__research-briefs/12__research-brief-for-chatgpt.md` — e o irmão da Perplexity,\n`13__research-brief-for-perplexity.md` — com o cromo deste site: cabeçalho, navegação, distintivo\nde versão, bloco «para um agente», rodapé. Hoje o endereço\n\n  https://pt.newsroom.sgit.ai/briefs/pack/08__research-briefs/12__research-brief-for-chatgpt.md\n\ndevolve markdown em bruto ao navegador. É o documento certo no sítio certo e a ler-se mal. Este é\no documento que entregamos a um assistente exterior; é a peça mais pública do método desta redação\ne a única que não se parece com o resto do site.\n\nA REGRA QUE NÃO PODE SER QUEBRADA PARA FAZER ISTO\n\n`build/build.py`, na linha 732, diz porque é que os resumos são ligados e não republicados: **o\nconteúdo existe uma vez**. Se o texto passar a viver também dentro de um `.html`, os dois acabam\npor discordar no dia em que alguém editar um. Não quero uma segunda cópia — quero uma segunda\nVISTA da mesma cópia.\n\nO caminho que já existe neste repositório é o de `build/mandatos.py`: um ficheiro DERIVADO,\ngerado a partir da fonte única, marcado como derivado, e refeito em cada construção. Faça o mesmo:\no `.md` continua a ser a fonte; o `.html` é render dele e nunca é editado à mão. Se o HTML e o\nmarkdown puderem divergir, o desenho está errado.\n\nDeixo-lhe as decisões de implementação, mas registo o que me parece:\n\n- Um portão que falhe a construção se um `.html` de resumo estiver dessincronizado do `.md` de que\n  deriva. Um ficheiro derivado sem portão é uma cópia com outro nome — foi o que o portão 28\n  aprendeu com os mandatos.\n- O `.md` continua a responder no mesmo endereço. Há ferramentas, e assistentes, que o querem em\n  bruto; o brief manda-os lá. Não parta o endereço para acrescentar uma vista.\n- O endereço da vista renderizada é seu para escolher, desde que entre no sitemap e no llms.txt.\n\nPORQUE É QUE ISTO VALE A PENA AGORA, E NÃO DAQUI A UMA VERSÃO\n\nO ciclo de investigação vai passar a correr com regularidade — o editor quer o ChatGPT a fazer uma\npassagem por dia ou de doze em doze horas, e o fluxo de publicação desta redação a correr atrás\ndela. O resumo deixa de ser um documento que se cola uma vez e passa a ser a interface entre esta\nredação e as ferramentas que a alimentam. Uma interface lê-se muitas vezes.\n\nA v0.10.1 corrigiu o endereço do esquema que o resumo mandava buscar — apontava para\n`newsroom.sgit.ai/briefs/pt-newsroom-pack/`, que não existe, quando este site é\n`pt.newsroom.sgit.ai` a servir `briefs/pack/`. A entrega 1/8 do ChatGPT falhou a validação em doze\npontos por não conseguir ler o contrato. O documento está agora certo e é a altura de o pôr\nlegível.\n\n— Dinis",
          "resumo": "O QUE PEÇO Uma página HTML que renderize `briefs/pack/08__research-briefs/12__research-brief-for-chatgpt.md` — e o irmão da Perplexity, `13__research-brief-for-perplexity.md` — com o cromo deste site: cabeçalho, navegação, distintivo de versão, bloco «para um agente», rodapé. Hoje o endereço https://pt.newsroom.sgit.ai/briefs/pack/08__research-briefs/12__research-brief-for-chatgpt.md devolve markdown em bruto ao nave",
          "bytes": 3169,
          "desconhecido": []
        }
      ],
      "contagens": {
        "abertos": 1,
        "bloqueados": 2,
        "fechados": 0,
        "issues_do_jornal": 0,
        "por_tratar": 0,
        "em_transito": 1
      }
    },
    "dinis.humano": {
      "agente": "dinis.humano",
      "alias": "@Dinis",
      "nome": "Dinis Cruz",
      "colunas": {
        "abertos": [
          {
            "ficheiro": "redacao/correio/dinis.humano/assuntos/abertos/002__decidir-os-tipos-novos-da-ontologia.md",
            "agente": "dinis.humano",
            "coluna": "abertos",
            "origem_tipo": "assunto",
            "titulo": "Decidir os três tipos novos da ontologia",
            "aberto": "2026-09-14T12:00:00Z",
            "prioridade": "média",
            "esforco": "—",
            "bloqueado_por": "—",
            "issue": "004",
            "origem": "redacao/correio/dinis.humano/entrada/001__sessao-de-arranque__o-que-foi-construido.eml",
            "corpo": "## O que há para fazer\nA entrega propõe três tipos que a ontologia não tem: `Programa`, `InstrumentoJuridico`,\n`Infraestrutura`. Aceitá-los é uma alteração de ontologia.\n\n## Porque é uma decisão e não uma tarefa\nUm tipo novo muda o que o grafo consegue dizer, e a regra 6 diz que cada aresta tem de ler em voz\nalta em português com um inverso distinto. Um tipo aceite sem os verbos que o ligam é um tipo que\nnão se percorre. Leva uma versão, e a versão diz o que mudou e porquê.\n\n## Critério de aceitação\n- Cada tipo aceite tem, no mesmo commit, os verbos que o ligam ao resto do grafo, cada um com\n  leitura e inverso em português.\n- `admin/versions.html` com a linha que diz o que mudou.",
            "resumo": "A entrega propõe três tipos que a ontologia não tem: `Programa`, `InstrumentoJuridico`, `Infraestrutura`. Aceitá-los é uma alteração de ontologia. Um tipo novo muda o que o grafo consegue dizer, e a regra 6 diz que cada aresta tem de ler em voz alta em português com um inverso distinto. Um tipo acei"
          },
          {
            "ficheiro": "redacao/correio/dinis.humano/assuntos/abertos/003__decidir-o-pedido-de-acesso-a-anacom.md",
            "agente": "dinis.humano",
            "coluna": "abertos",
            "origem_tipo": "assunto",
            "titulo": "Decidir o pedido de acesso à ANACOM",
            "aberto": "2026-09-14T12:00:00Z",
            "prioridade": "média",
            "esforco": "—",
            "bloqueado_por": "—",
            "issue": "002",
            "origem": "redacao/correio/dinis.humano/entrada/001__sessao-de-arranque__o-que-foi-construido.eml",
            "corpo": "## O que há para fazer\nA página da ANACOM devolve 403 a esta redação. Decidir se se pede acesso, ou se a história 002 se\nescreve sobre a ausência no registo público legível.\n\n## Porque só o editor\nPedir acesso é falar em nome desta publicação com uma entidade nomeada. `pesquisa.pt` tem o\nassunto bloqueado à espera desta decisão.\n\n## Critério de aceitação\nUma das duas: o pedido feito e a resposta registada, ou a história escrita sobre a ausência com a\nhora e o código que o servidor devolveu.",
            "resumo": "A página da ANACOM devolve 403 a esta redação. Decidir se se pede acesso, ou se a história 002 se escreve sobre a ausência no registo público legível. Pedir acesso é falar em nome desta publicação com uma entidade nomeada. `pesquisa.pt` tem o assunto bloqueado à espera desta decisão. Uma das duas: o"
          },
          {
            "ficheiro": "redacao/correio/dinis.humano/assuntos/abertos/005__o-grafo-como-linguagem-visual-do-site.md",
            "agente": "dinis.humano",
            "coluna": "abertos",
            "origem_tipo": "assunto",
            "titulo": "Decidir se o grafo passa a ser a linguagem visual do site",
            "aberto": "2026-09-15T02:00:00Z",
            "prioridade": "média",
            "esforco": "—",
            "bloqueado_por": "dinis.humano",
            "issue": "—",
            "origem": "revisão de desenho, cofre e54hfntq, §2.15 e §4.5.1",
            "corpo": "## A decisão\nEste site não tem uma única fotografia, e isso é uma posição defensável numa publicação que não\nreproduz o que não consegue verificar. A consequência é que, abaixo da mancheta, **todos os módulos\ntêm o mesmo peso visual** e a página não tem ponto focal. É uma parte real do «não parece um blogue\nforte».\n\nA revisão diz que o site já tem a resposta e é o **grafo**: é nativo, é gerado, é verificável e é\ngenuinamente distintivo — e aparece uma vez, desenhado à mão como SVG estático, a meio da primeira\npágina. A proposta é fazer dele a linguagem visual: um grafo maior e melhor desenhado como imagem\nprincipal, e uma miniatura gerada por página de entidade e por cartão de artigo, a partir de\n`api/v1/graph.json`.\n\n## Porque é sua e não nossa\nPorque é uma construção significativa **e muda o que a primeira página é**. A revisão marca-a\nexpressamente como precisando da sua assinatura antes de alguém a construir.\n\n## As opções\n- **Sim** — a linguagem visual passa a ser o grafo, em toda a parte.\n- **Não** — a página fica sem ponto focal, e isso é um preço aceitável.\n- **Protótipo primeiro** — uma página de entidade com miniatura, para ver antes de decidir.",
            "resumo": "Este site não tem uma única fotografia, e isso é uma posição defensável numa publicação que não reproduz o que não consegue verificar. A consequência é que, abaixo da mancheta, **todos os módulos têm o mesmo peso visual** e a página não tem ponto focal. É uma parte real do «não parece um blogue fort"
          },
          {
            "ficheiro": "redacao/correio/dinis.humano/assuntos/abertos/006__onde-ficam-as-fichas-de-proveniencia.md",
            "agente": "dinis.humano",
            "coluna": "abertos",
            "origem_tipo": "assunto",
            "titulo": "Decidir onde ficam as fichas de proveniência",
            "aberto": "2026-09-15T02:00:00Z",
            "prioridade": "média",
            "esforco": "—",
            "bloqueado_por": "dinis.humano",
            "issue": "—",
            "origem": "revisão de desenho, cofre e54hfntq, §2.8 e §4.5.2",
            "corpo": "## A decisão\nLogo abaixo do título principal — onde um jornal põe o subtítulo e a assinatura — a primeira página\npõe três fichas de 11px em mono com contagens de caracteres: `dados-gov · 27406 caracteres`,\n`dre-inicio · 22 caracteres`, `gov-ia · 348 caracteres`.\n\nA proveniência **é** o produto e fica na página. Mas uma contagem de caracteres é a camada de\nprova, não a entrada da notícia, e ali faz uma entrada bem escrita parecer um painel de depuração.\n\n## Porque é sua e não nossa\nAs três opções preservam a informação inteira. O que muda é **a ordem em que ela é lida**, e essa\nordem é uma posição editorial sobre com o que é que esta publicação abre. Um agente a escolher\nisto estaria a escolher a voz do jornal.\n\n## As opções\n- **Uma linha de prosa**, no serif, onde as fichas estão: «Assenta em 3 páginas congeladas hoje ·\n  2 não devolveram texto», e as fichas abrem ao clique.\n- **Uma tira de proveniência** imediatamente abaixo do corpo do artigo.\n- **Na coluna da direita**, sob «Nesta edição», onde as outras medições já vivem.",
            "resumo": "Logo abaixo do título principal — onde um jornal põe o subtítulo e a assinatura — a primeira página põe três fichas de 11px em mono com contagens de caracteres: `dados-gov · 27406 caracteres`, `dre-inicio · 22 caracteres`, `gov-ia · 348 caracteres`. A proveniência **é** o produto e fica na página. M"
          },
          {
            "ficheiro": "redacao/correio/dinis.humano/assuntos/abertos/007__modo-escuro.md",
            "agente": "dinis.humano",
            "coluna": "abertos",
            "origem_tipo": "assunto",
            "titulo": "Decidir o modo escuro",
            "aberto": "2026-09-15T02:00:00Z",
            "prioridade": "baixa",
            "esforco": "—",
            "bloqueado_por": "dinis.humano",
            "issue": "—",
            "origem": "revisão de desenho, cofre e54hfntq, §2.16 e §4.5.3",
            "corpo": "## A decisão\nVale a pena num site de leitura. Duplica o trabalho da paleta, e a metáfora do papel e da tinta\n**não transfere de graça**: uma página creme invertida não é um jornal, é um terminal. Cada um dos\ncatorze fichos de cor precisaria de um par medido contra o novo fundo, e os portões 27 e 28 teriam\nde passar a medir os dois conjuntos.\n\nO `color-scheme: light` já está declarado, o que faz os controlos de formulário seguirem a página\nem vez do sistema operativo. Isso é o mínimo e está feito; o resto é esta decisão.\n\n## Porque é sua e não nossa\nÉ um segundo sistema de desenho a manter, e a revisão diz que é «uma questão maior que vale a pena\nfazer em vez de assumir».\n\n## As opções\n- **Sim** — e leva uma versão própria, com a paleta escura medida ficho a ficho.\n- **Não** — e diz-se porquê na folha de estilos, para ninguém voltar a perguntar.\n- **Mais tarde** — depois do trabalho estrutural da §4.3, que é o que torna a paleta mudável.",
            "resumo": "Vale a pena num site de leitura. Duplica o trabalho da paleta, e a metáfora do papel e da tinta **não transfere de graça**: uma página creme invertida não é um jornal, é um terminal. Cada um dos catorze fichos de cor precisaria de um par medido contra o novo fundo, e os portões 27 e 28 teriam de pas"
          },
          {
            "ficheiro": "redacao/correio/dinis.humano/assuntos/abertos/008__a-carteira-no-cabecalho-do-leitor.md",
            "agente": "dinis.humano",
            "coluna": "abertos",
            "origem_tipo": "assunto",
            "titulo": "Decidir se a carteira fica no cabeçalho do leitor",
            "aberto": "2026-09-15T02:00:00Z",
            "prioridade": "alta",
            "esforco": "—",
            "bloqueado_por": "dinis.humano",
            "issue": "—",
            "origem": "revisão de desenho, cofre e54hfntq, §2.12 e §4.5.4",
            "corpo": "## A decisão\nAcima da mancheta, numa só corrida de mono cinzento: a datalinha, a contagem para o Startup Summit,\n`Aviso`, `Método`, `API`, `Back office [EN]`, `● €4,99 carteira` e `v0.9.0`. Duas dessas coisas são\n**editoriais** (a data e a contagem) e quatro são **ferramenta de quem opera**. Estão compostas de\nforma idêntica, e por isso o leitor não distingue quais são quais — e um saldo de carteira\nimediatamente acima da mancheta de um jornal é desorientador.\n\nNum telemóvel é pior: medido a 390×844, são **131px** — os primeiros 15% do ecrã — gastos num\nsaldo, num número de versão e numa ligação para uma consola que o leitor não pode usar. «O\nEcossistema Português de IA», que é a melhor coisa do site, chega por baixo disso.\n\n## Porque é sua, e porque esta é a que desbloqueia mais\nEsta decisão **bloqueia três itens**: a divisão da tira do cabeçalho (§2.12), os 131px no telemóvel\n(§3.8b), e o alvo de ≤48px da §4.4. A pergunta não é de desenho, é de produto: a carteira está ali\npara ser vista pelo leitor, ou é ferramenta de operação que pertence atrás da ligação dos\nbastidores?\n\n## As opções\n- **Fica no cabeçalho do leitor** — e a tira divide-se em duas linhas visualmente distintas.\n- **Vai para uma tira de operação**, mais fina, acima ou abaixo do filete da navegação.\n- **Vai para atrás dos bastidores** — e o cabeçalho do leitor fica com a data e a contagem, que é\n  o que um jornal tem ali.",
            "resumo": "Acima da mancheta, numa só corrida de mono cinzento: a datalinha, a contagem para o Startup Summit, `Aviso`, `Método`, `API`, `Back office [EN]`, `● €4,99 carteira` e `v0.9.0`. Duas dessas coisas são **editoriais** (a data e a contagem) e quatro são **ferramenta de quem opera**. Estão compostas de f"
          },
          {
            "ficheiro": "redacao/correio/dinis.humano/assuntos/abertos/009__quao-magra-a-edicao-pode-parecer.md",
            "agente": "dinis.humano",
            "coluna": "abertos",
            "origem_tipo": "assunto",
            "titulo": "Decidir quão magra a edição pode parecer",
            "aberto": "2026-09-15T02:00:00Z",
            "prioridade": "alta",
            "esforco": "—",
            "bloqueado_por": "dinis.humano",
            "issue": "—",
            "origem": "revisão de desenho, cofre e54hfntq, §3.2 e §4.5.5",
            "corpo": "## A decisão\nA grelha «Em preparação» repete, no mesmo ecrã e textualmente, três histórias que já estão acima:\nduas que já estão na coluna da direita, e uma que **é o título principal**. O leitor lê o título da\nhistória de abertura **duas vezes antes de rolar uma vez**. Metade da grelha é enchimento, e isso\ncontradiz a orientação do próprio projeto: «conteúdo existe uma vez».\n\nA correção é um filtro de cinco linhas e está pronta. O efeito é que a primeira página passa a\nmostrar **três histórias em vez de seis**.\n\n## Porque é sua e não nossa\nPorque «visivelmente mais vazia» é um juízo sobre o jornal e não sobre o código. Pelos padrões\ndesta publicação, três verdadeiras batem seis com três repetidas — mas é o editor que responde pelo\nque a primeira página parece, e a revisão pede expressamente esta confirmação antes de alguém\ndeduplicar.\n\n## As opções\n- **Deduplicar agora** — três histórias, e a página assume a espessura da edição.\n- **Manter seis** e fazer o segundo corte querer dizer outra coisa (por departamento, por estado de\n  verificação), para que a repetição carregue significado em vez de ser enchimento.\n- **Esperar** por mais histórias, e deduplicar quando houver seis distintas.",
            "resumo": "A grelha «Em preparação» repete, no mesmo ecrã e textualmente, três histórias que já estão acima: duas que já estão na coluna da direita, e uma que **é o título principal**. O leitor lê o título da história de abertura **duas vezes antes de rolar uma vez**. Metade da grelha é enchimento, e isso cont"
          },
          {
            "ficheiro": "redacao/correio/dinis.humano/assuntos/abertos/010__o-leitor-de-pdf-mente-quando-lhe-falta-uma-dependencia.md",
            "agente": "dinis.humano",
            "coluna": "abertos",
            "origem_tipo": "assunto",
            "titulo": "O leitor de PDF diz que o diploma é digitalizado quando o que lhe falta é uma dependência",
            "aberto": "2026-09-15T11:30:00Z",
            "prioridade": "alta",
            "esforco": "—",
            "bloqueado_por": "build/pdf.py está na lista de recusa; nenhum agente o pode editar",
            "issue": "005",
            "origem": "sessão a-linha-de-publicacao — encontrado ao pôr build/entregas.py no caminho de construção",
            "corpo": "## O que há para fazer\nCorrigir `build/pdf.py` para que a falta de `pycryptodome` no caminho AESV2 fique registada como\nfalta de dependência e não como um juízo sobre o documento. Hoje `_aes_cbc` devolve `None`, a\n`Cifra` fica com `ok=True` e `porque=None`, e o leitor conclui «é provavelmente um PDF\ndigitalizado, que precisaria de reconhecimento ótico». O diploma não é digitalizado.\n\n## Porque é que isto importa mais do que parece\nO mesmo ficheiro, com o mesmo SHA-256 reverificado pelo portão 1, leu **30 808 caracteres** a 14 de\nsetembro e **0** a 15 de setembro. Os bytes não mudaram — mudou a máquina. Durante essa passagem,\nas duas afirmações da RCM n.º 70/2026 caíram de `confirmada` para `fonte_inacessivel` **com a\nconstrução verde**. Uma prova que depende de quem a lê não é uma prova, e este site é inteiro\nconstruído sobre a promessa contrária.\n\nO caminho do AES-256 já faz isto bem: diz «AES-256 precisa de pycryptodome, que não está\ninstalado». O do AESV2 cala-se. É uma linha de diferença.\n\n## Como se faz\n`build/pdf.py` é seu. Ficam feitas as duas metades que um agente pode fazer:\n`requirements.txt` nomeia as duas dependências com a razão de cada uma, e o CI instala-as antes dos\nportões. Fica por fazer a que está atrás da lista de recusa — e vale a pena pensar num portão que\nleia um PDF conhecido e falhe se ele deixar de dar texto.\n\n## Critério de aceitação\n- Sem a dependência, `Cifra.ok` é `False` e a razão nomeia `pycryptodome`.\n- Nenhuma afirmação é marcada `fonte_inacessivel` com uma explicação que seja um juízo sobre o\n  documento de outra pessoa.",
            "resumo": "Corrigir `build/pdf.py` para que a falta de `pycryptodome` no caminho AESV2 fique registada como falta de dependência e não como um juízo sobre o documento. Hoje `_aes_cbc` devolve `None`, a `Cifra` fica com `ok=True` e `porque=None`, e o leitor conclui «é provavelmente um PDF digitalizado, que prec"
          },
          {
            "ficheiro": "redacao/correio/dinis.humano/assuntos/abertos/011__decidir-a-segunda-entrega-de-politicas.md",
            "agente": "dinis.humano",
            "coluna": "abertos",
            "origem_tipo": "assunto",
            "titulo": "Decidir a segunda entrega do ChatGPT sobre políticas, item a item",
            "aberto": "2026-09-15T11:50:00Z",
            "prioridade": "alta",
            "esforco": "—",
            "bloqueado_por": "—",
            "issue": "007",
            "origem": "entrega chatgpt-2026-09-15-politicas-2, ingerida na sessão a-linha-de-publicacao",
            "corpo": "## O que há para fazer\nDecidir os três itens da segunda entrega de políticas. Três afirmações têm o excerto nos bytes\ncongelados; uma não se pôde conferir porque o EUR-Lex respondeu 202 e não devolveu corpo.\n\nEstá em `/entregas/chatgpt-2026-09-15-politicas-2.html`, que agora abre com um índice: cada item\ncom o seu veredicto de bytes e um salto para a afirmação.\n\n## O que mudou desde a primeira entrega\n**A entrega valida contra o esquema.** A primeira falhou em 45 pontos porque o resumo mandava\nbuscar o contrato a um endereço que não existe. Corrigido o endereço na v0.17.0, esta passagem\nvalidou à primeira e não reenviou nenhuma das oito páginas que a redação já tinha.\n\nO assistente também encontrou um erro **meu**: a v0.17.0 mandava omitir `delivery.vault` antes de\no cofre existir, e o esquema exige a chave. Ele disse-o nas notas e usou `null`, que é o que o\nesquema aceita. O resumo está corrigido.\n\n## Critério de aceitação\n- Cada um dos três itens com uma decisão registada em `redacao/revisoes/`.\n- Nenhum item aprovado sem o excerto ter sido lido nos bytes congelados.",
            "resumo": "Decidir os três itens da segunda entrega de políticas. Três afirmações têm o excerto nos bytes congelados; uma não se pôde conferir porque o EUR-Lex respondeu 202 e não devolveu corpo. Está em `/entregas/chatgpt-2026-09-15-politicas-2.html`, que agora abre com um índice: cada item com o seu veredict"
          }
        ],
        "bloqueados": [
          {
            "ficheiro": "redacao/correio/dinis.humano/assuntos/bloqueados/004__o-aviso-tem-de-falar-da-telemetria-antes-de-ela-ligar.md",
            "agente": "dinis.humano",
            "coluna": "bloqueados",
            "origem_tipo": "assunto",
            "titulo": "O aviso tem de falar da telemetria antes de ela ligar",
            "aberto": "2026-09-15T00:40:00Z",
            "prioridade": "alta",
            "esforco": "—",
            "bloqueado_por": "dinis.humano",
            "issue": "—",
            "origem": "pedido de @Dinis, nesta sessão",
            "corpo": "## O que há para fazer\n`dados/aviso.json` não diz uma palavra sobre eventos de leitura, porque até agora não se enviava\nnenhum. A ponte da observabilidade está construída e desligada por falta de credenciais. **No\nmomento em que ela receber credenciais, o aviso passa a estar errado por omissão.**\n\n## Porque é um assunto do editor e não dos bastidores\n`dados/aviso.json` está na lista de recusa de `.claude/settings.json`, e está bem que esteja: o\naviso é onde uma publicação diz o que faz com dados de pessoas, e um agente que o pudesse reescrever\npodia alargar o que o site faz e ajustar o aviso para caber. @Bastidores não lhe toca. O responsável\npelo tratamento nomeado é @Dinis, e a via de oposição chega a ele.\n\n## O que o aviso tem de passar a dizer, e é pouco\n1. Que eventos anónimos de leitura são enviados para um cofre cifrado desta redação: que páginas\n   foram abertas, por que ordem, e quanto tempo ficaram abertas.\n2. Que o identificador de sessão são dezasseis dígitos criados na memória do navegador quando a\n   página abre e perdidos quando ela fecha, e que não há nome, correio eletrónico, agente do\n   utilizador, dimensões de ecrã nem referenciador.\n3. Que o servidor da fila vê o endereço IP de quem envia. **Isto não é evitável do lado do\n   cliente** e por isso tem de estar escrito: um aviso que dissesse «não recolhemos nada que o\n   identifique» e omitisse o IP estaria a dizer uma coisa falsa sobre a única parte que o leitor\n   não pode verificar.\n4. Que há um interruptor em cada página para desligar o envio, e que ele fica desligado entre\n   visitas.\n\n## Critério de aceitação\nA ordem importa e é esta: **o aviso primeiro, as credenciais depois.** É a mesma ordem que esta\npublicação já seguiu uma vez, quando o aviso de proteção de dados foi publicado ANTES da primeira\npágina que nomeia alguém. Ligar a telemetria antes de o aviso a descrever seria inverter a única\nsequência que este site já acertou de propósito.\n\nAté lá, `assets/observador.js` não envia nada, não mostra aviso nenhum e não põe interruptor — e\nessa é a regra 1 do próprio ficheiro: um aviso a dizer «enviamos eventos» num site que não envia\nnada é pior do que nenhum aviso, porque é uma afirmação falsa sobre o próprio site.",
            "resumo": "`dados/aviso.json` não diz uma palavra sobre eventos de leitura, porque até agora não se enviava nenhum. A ponte da observabilidade está construída e desligada por falta de credenciais. **No momento em que ela receber credenciais, o aviso passa a estar errado por omissão.** `dados/aviso.json` está n"
          }
        ],
        "fechados": [
          {
            "ficheiro": "redacao/correio/dinis.humano/assuntos/fechados/001__decidir-a-entrega-chatgpt-politicas.md",
            "agente": "dinis.humano",
            "coluna": "fechados",
            "origem_tipo": "assunto",
            "titulo": "Decidir a entrega do ChatGPT sobre políticas, item a item",
            "aberto": "2026-09-14T12:00:00Z",
            "prioridade": "alta",
            "esforco": "—",
            "bloqueado_por": "—",
            "issue": "004",
            "origem": "redacao/correio/dinis.humano/entrada/001__sessao-de-arranque__o-que-foi-construido.eml",
            "corpo": "## O que há para fazer\nDecidir, item a item, a entrega 1/8 do ChatGPT sobre políticas: 9 afirmações com o excerto\nencontrado nos bytes, 10 sem fonte legível. Está em `/entregas/` com cada afirmação ao lado da\ncópia congelada em que devia assentar.\n\n## Como se faz\n`/newsroom-entregas` abre a sessão de revisão com os ids reais. Aprovar é por item; rejeitar\ntambém. Nada desta entrega aparece na primeira página nem num artigo enquanto isto não for feito.\n\n## Critério de aceitação\n- Cada um dos 19 itens com uma decisão registada em `redacao/decisoes/`.\n- Nenhum item aprovado sem o excerto ter sido lido nos bytes congelados.\n\n## Como ficou\nDecidido a 15 de setembro por Dinis Cruz, editor de registo, em\n`redacao/revisoes/chatgpt-pt-newsroom-2026-09-14-politicas.json`.\n\n**Cinco itens aprovados** — pol-02, pol-03, pol-05, pol-07, pol-08 — e cinco artigos publicados a\npartir deles, cada um só com as afirmações cujo excerto foi reencontrado nos bytes congelados.\n\n**Nenhum item rejeitado.** Três — pol-01, pol-04, pol-06 — ficaram sem decisão de propósito: todas\nas suas afirmações citam a página de registo do Diário da República, que não devolve texto.\nRejeitá-los diria que esta redação não os quer, e quer. Abriram o issue 006, que é encontrar um\núnico PDF e desbloqueia os três de uma vez.\n\nAs propostas de vocabulário — Programa, InstrumentoJuridico, Infraestrutura — continuam por decidir\ne são uma alteração de ontologia. Nenhum dos cinco artigos precisou delas.",
            "resumo": "Decidir, item a item, a entrega 1/8 do ChatGPT sobre políticas: 9 afirmações com o excerto encontrado nos bytes, 10 sem fonte legível. Está em `/entregas/` com cada afirmação ao lado da cópia congelada em que devia assentar. `/newsroom-entregas` abre a sessão de revisão com os ids reais. Aprovar é p"
          }
        ]
      },
      "issues_do_jornal": [
        {
          "ficheiro": "redacao/issues/004-entrega-chatgpt-politicas.json",
          "agente": "dinis.humano",
          "coluna": "abertos",
          "origem_tipo": "issue",
          "id": "004",
          "titulo": "Entrega ChatGPT 1/8 (políticas): 9 afirmações com excerto confirmado, 10 sem fonte legível",
          "estado": "congelado",
          "seccao": "politicas",
          "aberto": "2026-09-14",
          "porque_aqui": "É uma entrega exterior à espera de aprovação item a item, que só o editor dá.",
          "o_que_falta": [
            "Decisão do editor sobre cada item. Nada desta entrega aparece na primeira página nem num artigo até lá.",
            "Decisão do editor sobre as propostas de vocabulário: um verbo ou um tipo novo é uma alteração de ontologia e leva uma versão.",
            "Encontrar o PDF do Diário da República para a RCM n.º 2/2026, que tornaria conferíveis as três afirmações de item-pol-01."
          ]
        },
        {
          "ficheiro": "redacao/issues/007-entrega-chatgpt-politicas-2.json",
          "agente": "dinis.humano",
          "coluna": "abertos",
          "origem_tipo": "issue",
          "id": "007",
          "titulo": "Entrega ChatGPT 1/8 (políticas, 2.ª passagem): valida contra o esquema, 3 de 4 afirmações com excerto nos bytes",
          "estado": "congelado",
          "seccao": "politicas",
          "aberto": "2026-09-15",
          "porque_aqui": "É uma entrega exterior à espera de aprovação item a item, que só o editor dá.",
          "o_que_falta": [
            "Decisão do editor sobre cada um dos três itens. Nada desta entrega aparece na primeira página nem num artigo até lá.",
            "Uma via legível para o Regulamento (UE) 2026/1744. O EUR-Lex respondeu 202 a esta redação; há outras formas de chegar ao mesmo ato no Jornal Oficial e vale a pena procurá-las antes de dar o item por perdido.",
            "O PDF da Série I da RCM n.º 2/2026 continua por encontrar — o assistente procurou-o em quinze consultas e não o construiu por adivinhação, que é o comportamento certo. Ver o issue 006."
          ]
        }
      ],
      "entrada": [
        {
          "ficheiro": "redacao/correio/dinis.humano/entrada/001__sessao-de-arranque__o-que-foi-construido.eml",
          "lugar": "entrada",
          "caixa": "dinis.humano",
          "de": "sessao-de-arranque",
          "para": "dinis.humano",
          "de_alias": "@Arranque",
          "para_alias": "@Dinis",
          "assunto": "MVP v0.1.0 construído; o que é real, o que não é, e o que precisa da sua decisão",
          "quando": "2026-09-14T12:00:00Z",
          "id": "001-mvp-construido@redacao.local",
          "responde_a": null,
          "issue": null,
          "run": "2026-09-14T12:00:00Z",
          "historica": true,
          "migrado_de": "redacao/correio/editor/entrada/2026-09-14T1200__sessao-de-arranque__o-que-foi-construido.md",
          "corpo": "O site está construído e os portões estão verdes. O que é real: 92 ficheiros congelados com\nSHA-256, um grafo de verbos portugueses onde cada nó nomeia a sua fonte, o aviso de proteção de\ndados publicado ANTES da primeira página que nomeia alguém, e o fluxo de revisão de entregas.\n\nO que NÃO é real e está dito em cada página onde importa: nenhuma história publicada, três das\noito secções vazias, e a camada das empresas impossível de completar sem registo comercial aberto.\n\nPrecisa de decidir três coisas. Primeira: a entrega do ChatGPT (parte 1/8, políticas) está em\n/entregas/ com cada afirmação conferida contra os bytes — 9 confirmadas, 0 não encontradas, 10 sem\nfonte legível. Nada dela aparece em lado nenhum público até aprovar item a item. Segunda: a entrega\npropõe tipos que a ontologia não tem (Programa, InstrumentoJuridico, Infraestrutura); aceitá-los é\numa alteração de ontologia e leva uma versão. Terceira: a página da ANACOM devolve 403 a esta\nredação, e isso não é uma recusa de informação — é um servidor a bloquear um cliente. Pode pedir\nacesso.\n\nUma nota que é um achado e não um detalhe: o Diário da República renderiza por script e devolve 22\ncaracteres a um leitor automático, mas publica os diplomas em PDF, e esses PDFs são legíveis depois\nde decifrados. build/pdf.py faz isso. Foi assim que as duas afirmações sobre a RCM n.º 70/2026\nconfirmaram. O mesmo caminho resolve provavelmente a história 001.",
          "resumo": "O site está construído e os portões estão verdes. O que é real: 92 ficheiros congelados com SHA-256, um grafo de verbos portugueses onde cada nó nomeia a sua fonte, o aviso de proteção de dados publicado ANTES da primeira página que nomeia alguém, e o fluxo de revisão de entregas. O que NÃO é real e está dito em cada página onde importa: nenhuma história publicada, três das oito secções vazias, e a camada das empresa",
          "bytes": 2012,
          "desconhecido": [
            "sessao-de-arranque"
          ]
        }
      ],
      "em_transito": [
        {
          "ficheiro": "redacao/correio/expedicao/dinis.humano/003__bastidores.pt__a-equipa-esta-visivel-e-a-ponte-nao-tem-chave.eml",
          "lugar": "expedicao",
          "caixa": "dinis.humano",
          "de": "bastidores.pt",
          "para": "dinis.humano",
          "de_alias": "@Bastidores",
          "para_alias": "@Dinis",
          "assunto": "A equipa passa a ser visível nos bastidores; a ponte para o navegador está construída e sem credencial",
          "quando": "2026-09-14T23:55:00Z",
          "id": "003-equipa-visivel@redacao.local",
          "responde_a": "001-mvp-construido@redacao.local",
          "issue": null,
          "run": null,
          "historica": false,
          "migrado_de": null,
          "corpo": "Está feito o que pediu: os agentes são agora um registo em `dados/agentes.json`, o correio entre\neles corre pelo protocolo Email-FS-lite em `redacao/correio/`, e há três páginas nos bastidores —\na equipa, o quadro por agente e o correio. Nenhum número nessas páginas é uma afirmação sobre\nPortugal: são contagens de ficheiros deste repositório, e o portão dos bastidores falha a\nconstrução se alguma vez uma delas citar uma fonte congelada como prova.\n\nTrês coisas que precisam de uma decisão sua, e nenhuma é urgente.\n\nPRIMEIRA, E A ÚNICA QUE BLOQUEIA. A ponte que o deixa escrever-me a partir do site está\nconstruída e não tem por onde enviar. Uma fila de acrescento precisa do `vault_id` do cofre que\nrecebe, de um `append_token` em hexadecimal, e da chave pública para eu cifrar no navegador antes\nde enviar. As duas primeiras são credenciais e não podem ficar neste repositório — o `validate.js`\ntem um detetor de cadeias com forma de chave e falharia a construção, o que é o portão a funcionar.\nVão para `localStorage` do seu navegador, dadas por si em `/backoffice/bridges.html`. A chave\npública pode ser publicada, e essa fica em ficheiro.\n\nSEGUNDA. As chaves de leitura que me deu para os cofres dos jogos não puderam ser usadas: instalar\no `sgit` foi recusado pelo classificador da caixa onde esta sessão corre. Não escrevi nenhuma\ndelas em ficheiro. Li o desenho na fonte publicada em vez disso, e isso trouxe um achado que\nmelhora o nosso caso: o cofre dos jogos construía eventos e não os enviava, porque uma aplicação\nde cofre corre numa moldura cujo CSP é `connect-src blob: data:`. Este site é estático, não é uma\naplicação de cofre, e por isso o envio direto funciona. O que a telemetria dos jogos não conseguiu\nfazer, este site consegue.\n\nTERCEIRA, QUE É UMA CORREÇÃO A UM FICHEIRO QUE EU NÃO POSSO EDITAR. O `CLAUDE.md` manda correr\n`node build/validate.js`. O ficheiro está em `admin/build/validate.js`, e é esse que a integração\ncontínua corre. Quem seguir a linha à letra conclui que o portão não existe. `CLAUDE.md` está na\nlista de recusa de propósito e não lhe toquei: a linha é sua.\n\nContinuam abertos os três assuntos que a sessão de arranque lhe deixou — a entrega do ChatGPT item\na item, os três tipos novos da ontologia, e o pedido de acesso à ANACOM, que tem a pesquisa\nbloqueada à espera. Estão agora no seu quadro, em `/backoffice/board.html`.",
          "resumo": "Está feito o que pediu: os agentes são agora um registo em `dados/agentes.json`, o correio entre eles corre pelo protocolo Email-FS-lite em `redacao/correio/`, e há três páginas nos bastidores — a equipa, o quadro por agente e o correio. Nenhum número nessas páginas é uma afirmação sobre Portugal: são contagens de ficheiros deste repositório, e o portão dos bastidores falha a construção se alguma vez uma delas citar ",
          "bytes": 2847,
          "desconhecido": []
        },
        {
          "ficheiro": "redacao/correio/expedicao/dinis.humano/004__bastidores.pt__a-revisao-de-desenho-esta-implementada.eml",
          "lugar": "expedicao",
          "caixa": "dinis.humano",
          "de": "bastidores.pt",
          "para": "dinis.humano",
          "de_alias": "@Bastidores",
          "para_alias": "@Dinis",
          "assunto": "A revisão de desenho está implementada até onde um agente a pode implementar; cinco decisões são suas",
          "quando": "2026-09-15T02:10:00Z",
          "id": "004-revisao-de-desenho@redacao.local",
          "responde_a": "003-equipa-visivel@redacao.local",
          "issue": null,
          "run": null,
          "historica": false,
          "migrado_de": null,
          "corpo": "Clonei o cofre `e54hfntq`, li a revisão inteira, e implementei-a. Dezoito itens feitos, três\nparciais, seis adiados com o bloqueio nomeado, e três que são decisões suas e que não tomei. Cada\num está em /backoffice/design.html, com o portão que o segura quando há um.\n\nO QUE MUDOU, EM MEDIDAS E NÃO EM ADJETIVOS\n\nA coluna do texto passou de 88 caracteres por linha — medidos por mim, 104, e volto a isso — para\n71. A entrelinha passou de 26.1px para 29.16px. Os filetes passaram de 1.36:1 contra o papel, onde\nnão se veem, para 2.65:1. A cor de «disputado» passou de 4.48:1, que FALHA o AA, para 5.81:1. O\nantetítulo, o rótulo de secção, o cabeçalho de tabela e o bloco «para um agente» saíram da face\nmonoespaçada, e é essa a mudança que faz a página deixar de se ler como um registo de construção.\nHá um anel de foco, que não existia em 13,8 kB de folha de estilos. E o distintivo de versão passou\na ser uma ligação para o que mudou nessa versão, que era a única coisa deste site que não se\nrastreava a si mesma.\n\nDUAS COISAS ONDE A REVISÃO ESTAVA ERRADA, E A SEGUNDA MUDAVA A RESPOSTA\n\nA revisão assume que um glifo médio da Newsreader mede 0.48em. Medi no navegador, numa tela, com a\nfonte computada do próprio elemento e com texto português: são 0.405em. A face é 18% mais estreita\ndo que a suposição, e isso corre nos dois sentidos. O problema era PIOR do que ela relatou — a\ncoluna de 758px tinha 104 caracteres e não 88. E a correção que ela pede não chegava ao alvo que\nela própria fixa: os 34em que recomenda são 612px, e a 612px o navegador mede 84 caracteres, ainda\nacima dos 75. Pus 29em, que mede 71. Se tivesse implementado a revisão à letra, teria lançado uma\ncoluna que falhava o alvo da própria revisão e ninguém teria sabido.\n\nA segunda é interna e menor: a §2.1 diz que 34em dão 66 caracteres e 38em dão 68, e os dois não\npodem estar certos, porque com a largura em `em` o corpo cancela-se.\n\nDigo isto sem gosto nenhum de apontar o dedo: aquela revisão mediu em vez de opinar, e é só por\nisso que foi possível verificá-la. Uma revisão que dissesse «a coluna é larga demais» não teria\npodido estar errada em nada.\n\nO QUE O PORTÃO NOVO ENCONTROU QUE A REVISÃO NÃO TINHA VISTO\n\n`build/gates_desenho.py` assere os números da §4.4, e à primeira passagem encontrou a coluna vazia\nem /instituicoes/ e em /casos-de-uso/ e não só em /empresas/ — a revisão só tinha visitado a\nterceira. E a auditoria aos acentos que a §3.4 mandou fazer («isto sugere que as cadeias estão a\nser escritas em algum sítio só ASCII, e vale uma verificação») encontrou o mesmo defeito nos\ntítulos dos cartões do quadro, que fui EU que introduzi há poucas horas, a derivar o título do nome\ndo ficheiro. A revisão apanhou-me a mim.\n\nAS CINCO DECISÕES, E NÃO TOMEI NENHUMA\n\nA §4.5 diz «agentes: não escolham isto por vocês». Estão as cinco no seu quadro, em\n/backoffice/board.html, cada uma com as opções e com o que fica bloqueado por ela:\n\n1. O grafo como linguagem visual do site. É a única coisa que dá identidade visual a este site sem\n   importar uma imagem que não se consegue verificar — e é uma construção grande que muda o que a\n   primeira página é.\n2. Onde ficam as fichas de proveniência. As três opções guardam a informação toda; o que muda é a\n   ordem, e a ordem é com o que o jornal abre.\n3. Modo escuro. Duplica a paleta, e um creme invertido não é um jornal.\n4. A carteira no cabeçalho do leitor. ESTA é a que desbloqueia mais: dela dependem a divisão da\n   tira do cabeçalho e os 131px de cromagem antes da mancheta no telemóvel, onde o alvo é 48.\n5. Quão magra a edição pode parecer. A grelha repete o título de abertura, e o leitor lê-o duas\n   vezes antes de rolar uma. O filtro está pronto e não o liguei: deduplicar deixa três histórias\n   em vez de seis, e «visivelmente mais vazia» é um juízo sobre o jornal.\n\nO QUE NÃO FIZ, ALÉM DAS DECISÕES\n\nO item que a revisão chama o blocker, e com razão: o sistema de desenho vive em atributos `style=`\nem linha nos geradores e não na folha de estilos, e ninguém pode mudar o ritmo deste site a partir\ndo site.css enquanto isso for verdade. Tirei os 54 que estavam a cancelar a correção da medida, e\no portão 30 impede que voltem. O resto — classes com nome para a coluna principal, para a coluna da\ndireita, para os blocos — é uma versão própria, porque não tem resultado visível nenhum e mexe em\ncinco geradores. Não a enfiei numa esquina desta.\n\nContinua aberto o que lhe deixei antes: a entrega do ChatGPT item a item, os três tipos novos da\nontologia, o pedido de acesso à ANACOM que tem a pesquisa bloqueada, e o aviso ter de falar de\ntelemetria antes de a ponte da observabilidade receber credenciais.",
          "resumo": "Clonei o cofre `e54hfntq`, li a revisão inteira, e implementei-a. Dezoito itens feitos, três parciais, seis adiados com o bloqueio nomeado, e três que são decisões suas e que não tomei. Cada um está em /backoffice/design.html, com o portão que o segura quando há um. O QUE MUDOU, EM MEDIDAS E NÃO EM ADJETIVOS A coluna do texto passou de 88 caracteres por linha — medidos por mim, 104, e volto a isso — para 71. A entrel",
          "bytes": 5234,
          "desconhecido": []
        }
      ],
      "contagens": {
        "abertos": 9,
        "bloqueados": 1,
        "fechados": 1,
        "issues_do_jornal": 2,
        "por_tratar": 1,
        "em_transito": 2
      }
    }
  }
}
