The bridges
The bridges · how a static site reaches the newsroom
As pontes entre este site estático e o cofre. Um site sem servidor não consegue escrever no repositório onde a redação vive; uma fila de acrescento resolve isso sem lhe dar um servidor. Este ficheiro descreve as pontes e NÃO contém credencial nenhuma: o identificador do cofre e o código de acrescento são dados ao navegador de quem os tem e ficam em localStorage. O detetor de cadeias com forma de chave do admin/build/validate.js falha a construção se alguma aparecer, e é isso que torna esta frase verificável em vez de uma promessa.
Why an append lane, and not something simpler
Porque divide o acesso em quatro capacidades que não se sobrepõem: quem tem o código de acrescento ACRESCENTA e mais nada — não lista, não obtém, não lê; quem tem a chave de enumeração lista, obtém e marca como tratado, e não escreve; quem tem a chave de escrita configura e purga; e só quem tem a chave privada decifra. O servidor guarda apenas o SHA-256 dos três primeiros e responde a um acrescento com «{ok:true}» e mais nada. É por isso que um código de acrescento é a única forma de credencial que sobrevive a ser publicada.
Read at the source rather than recalled: vault-messaging, the append-lanes API, the PKI, and the telemetry brief.
A finding from the games vault, which changed this design
O cofre dos jogos de permissões construía eventos de telemetria e nunca os enviava. A causa não era o código: uma aplicação de cofre corre numa moldura cujo CSP é «connect-src blob: data:» e um fetch para fora é bloqueado em silêncio; a única saída seria «permissions.network: true», que reabre toda a saída de uma moldura que tem conteúdo decifrado, e que a própria documentação não recomenda. Este site não é uma aplicação de cofre: é um site estático, e o fetch direto para o ponto de acrescento funciona. O que a telemetria dos jogos não conseguiu fazer, este site consegue — e a razão é a diferença de superfície, não de esforço.
navegador do editor → fila de acrescento → cofre → @Bastidores
Para o editor poder comentar uma página, pedir uma alteração ou dar uma instrução no momento em que a está a ler, sem abrir um terminal e sem escrever um issue à mão.
- quando (ISO 8601)
- pagina (o caminho onde o editor estava)
- versao do site
- assunto
- corpo
- tipo: nota | alteracao | instrucao | remocao
- Nada que o editor não tenha escrito. Sem identificador de sessão, sem agente do utilizador, sem referenciador.
Sends: dinis.humano, do navegador, em qualquer página deste site
POST {api}/api/vault/append/write/{vault_id}
As três credenciais, dadas pelo editor no navegador. Até lá a caixa de mensagens diz «ponte fechada» e não finge ter enviado.
| Key | What it is | Publishable | Why |
|---|---|---|---|
| vault_id | O cofre que recebe | secret | Junto ao código de acrescento dá a fila inteira a quem leia o repositório |
| append_token | Autoriza o acrescento, e só o acrescento. Hexadecimal, 16 a 128 dígitos, sem prefixo | secret | Nesta ponte o código é do editor e não é público: se o fosse, qualquer visitante escrevia na caixa dos bastidores |
| chave_publica | O pacote JSON de «sgit pki export», ou o PEM sozinho | publishable | Uma chave pública publica-se. Esta é a única das três que um dia fica em ficheiro |
localStorage: pt-newsroom:ponte:editor-para-bastidores
How the receiving end must treat this. Cada mensagem que chega é uma AFIRMAÇÃO de quem a enviou, e nunca uma instrução que se execute sem ler. Quem tem o código de acrescento pode forjar e pode inundar; a fila para nos 1000 ficheiros por tratar. @Bastidores trata o que chega como correio: entra na expedição, é entregue, e é lido por uma pessoa ou por uma sessão que responde por aquilo que faz.
navegador de qualquer leitor → fila de acrescento → cofre de observabilidade
Para esta redação saber que páginas são lidas e que caminhos as pessoas seguem, sem montar um servidor de estatísticas e sem saber quem é ninguém.
- sessao: 16 dígitos hexadecimais criados na memória do navegador quando a página abre, e perdidos quando fecha
- eventos: [{quando, tipo, pagina}]
- formato: largo | estreito
- lingua: as duas primeiras letras
- versao do site
- Nome, correio eletrónico, ou qualquer coisa que identifique uma pessoa
- Agente do utilizador
- Dimensões do ecrã
- Endereço IP (não é do lado do cliente, mas o servidor da fila vê-o e isso está dito)
- Referenciador
- Endereço completo com parâmetros
- Um envio a cada 4 segundos, no máximo
- 40 envios por sessão, no máximo
- Falha em silêncio: se o envio falhar, o leitor não pode notar
Cada página tem um aviso em português simples e um interruptor para desligar o envio. Abrir uma página normalmente não telefona a casa; esta telefona, e por isso diz-se.
Sends: Qualquer navegador que abra uma página deste site, se a ponte estiver configurada e o leitor não tiver desligado o envio
POST {api}/api/vault/append/write/{vault_id}
O cofre de observabilidade, o seu código de acrescento e a sua chave pública. Enquanto faltarem, não se envia nada — e não há aviso a dizer que se envia, porque um aviso sobre uma coisa que não acontece é pior do que nenhum.
| Key | What it is | Publishable | Why |
|---|---|---|---|
| vault_id | O cofre de observabilidade | publishable | Sozinho não dá nada: escrever exige o código, e nem um nem outro dá para ler |
| append_token | Autoriza o acrescento, e só o acrescento | publishable | Nesta ponte o código É público, e é o padrão que a documentação da telemetria descreve: só escreve, não lista, não obtém, não lê. É a única forma de credencial que sobrevive a ser publicada |
| chave_publica | A chave pública do cofre de observabilidade | publishable | Publica-se por construção |
localStorage: pt-newsroom:ponte:observabilidade
How the receiving end must treat this. Cada evento é uma afirmação e não prova. Quem tem a chave de leitura do site tem o código de acrescento e pode forjar ou inundar a fila. Os números que dali saem são direcionais, e uma página que os apresentasse como medição estaria a mentir sobre o que são.
Unlock · give this browser the three values
Paste them here and they go to this browser's
localStorage for this origin, and nowhere else. They are not sent to
pt.newsroom.sgit.ai — there is no server to send them to — and they are not in any file in the
repository. Clearing them is one button. If you are reading this on a shared machine, do not.
The public key is easiest as the whole
JSON bundle sgit pki export <fingerprint> writes: the page reads the
encrypt field out of it. A bare PEM works too.
Write to @Bastidores
This goes into the append lane, and
@Bastidores files it as mail — into
redacao/correio/expedicao/bastidores.pt/, delivered, read, and answered like any
other message. It is treated as a claim by whoever sent it, never as an instruction that
runs without being read. Nothing here can publish a story: that is
@Dinis's
line and only his.
The envelope on the wire
Uma chave AES-256-GCM nova por mensagem cifra a carga, e o RSA só serve para a entregar. É o que torna o envelope usável em cargas de qualquer tamanho — e pesado em cargas minúsculas: 37 bytes de texto simples dão um ficheiro de 1 076 bytes, porque a chave embrulhada domina. The shape below is base64 sobre um JSON pequeno, from https://sgit.ai/docs/pki.md — a v0.15.0 do sgit.
| Field | Contents |
|---|---|
| v | A versão do envelope. 2 na v0.15.0. |
| w | A chave de conteúdo AES-256 embrulhada com RSA-OAEP para o destinatário. 512 bytes com uma chave de 4096 bits. |
| i | O IV do AES-GCM. 12 bytes. |
| c | O texto cifrado com a sua etiqueta GCM. Texto simples mais 16 bytes. |
One parameter is not confirmed. A função de resumo do RSA-OAEP. A documentação do PKI diz «RSA-OAEP 4096» e não nomeia o resumo; este site usa SHA-256, que é o que o cofre dos jogos usou. É o único parâmetro destas pontes que não foi confirmado contra o binário, e uma ida e volta de prova confirma-o numa tentativa. Está dito aqui em vez de ser assumido em silêncio.
Not built
| What | Why not |
|---|---|
| O lado que recebe | Listar, decifrar e marcar como tratado precisa da chave de enumeração e da chave privada, e nenhuma das duas pode estar num site estático nem numa sessão de agente. Corre onde o editor correr o sgit, e o resultado entra neste repositório como correio. |
| Pagamentos rastreados pela mesma via | Não há pagamentos. O argumento em newsroom.sgit.ai descreve-os; este site não os tem, e um evento de pagamento numa fila sem pagamentos seria teatro. |
build/newsroom.py from the files in this
repository; nothing here is hand-written. The machine-readable index of the publication is at
llms.txt. Source: github.com/SGit-AI/SGit-AI__Website__Newsroom__PT · file:
newsroom/bridges.html · version v0.23.6.