Pular para conteúdo

AUR-422 — Perfil OCI bootstrap read-only (adoção formal)

Documento histórico do board. Pode descrever componentes removidos; para uso atual, consulte o guia do produto.

Este card formaliza a chave bootstrap-readonly-v1 já materializada pelo bootstrap. Os bytes nominais de .board/oci/profiles/bootstrap-readonly-v1.json e de .board/locks/oci/bootstrap-readonly-v1.lock.json são preservados; o card caracteriza o plano que .board/bin/oci-run deriva desses documentos antes de qualquer engine.

Imagem pinada e usuário

  • Imagem: somente a referência digest-pinada do lock content-addressed (aurum-bootstrap-go-bash@sha256:503ac356fa6bca4bad56fade87b5479ff371bd446ffb9c7db91f211323c7c73e). Uma tag mutável, um nome sem digest ou um digest vindo do profile em vez do lock são rejeitados antes de qualquer pull (mutable-image).
  • Usuário: numérico não-root 65534:65534; uid 0 ou formato fora de ^[1-9][0-9]{2,6}:[1-9][0-9]{2,6}$ rejeita (privileged-plan).
  • Isolamento: network=none, rootfs read-only, cap_drop=ALL, cap_add=none, mounts=none, devices=none, pull=never, no_new_privileges=true, privileged=false. Nenhum socket de engine, bind, volume ou device é concedido a consumidor algum.

Tetos efetivos do plano

Recurso Valor Flag derivada
Wall-clock 120 s timeout --foreground 120s
Memória 256 MB --memory=256m
CPU 1000 millis --cpus=1.000
PIDs 128 --pids-limit=128
stdout 65536 bytes drain bounded; exceder vira exit 74
stderr 65536 bytes drain bounded; exceder vira exit 74
tmpfs 512 MB --tmpfs /tmp:exec,rw,nosuid,nodev,size=512m
Inputs 10000 arquivos / 67108864 bytes staging allowlisted

Todo teto é validado dentro dos pisos e tetos duros do runner (floor_*/ceiling_* em .board/bin/oci-run); um valor ausente, zero ou fora do intervalo rejeita com unbounded-limit.

Códigos de rejeição estáveis

Derivação de plano é pura: zero invocações de engine em qualquer caminho.

Código Condição Mutação coberta
lock-mismatch lock_digest do profile não é o sha256 dos bytes do lock MUT-001
mutable-image imagem do lock não é digest-pinada (tag mutável) MUT-002
privileged-plan rede habilitada, mount/socket, uid 0, rootfs gravável, capability ou privileged MUT-003
unbounded-limit teto ausente/zero/fora do piso-teto do runner —
schema-invalid documento não canônico, chave desconhecida/faltante, identidade errada, lock estrangeiro —
profile-unregistered chave ausente do registry —
duplicate-profile chave registrada mais de uma vez —
schema-digest-mismatch schema_digest do registry não bate com o schema —
digest-invalid digest do registry mal formado —
unsafe-plan entry do registry aponta schema/lock fora dos paths canônicos —

No runner real, essas rejeições correspondem a die 65 em resolve_profile / assert_hardened_plan, sempre antes da detecção de engine: um mutante nunca chega ao die 78 e nunca gera engine call.

Diagnóstico do die 78

die 78 permanece intacto e significa exatamente "não registrado":

  • .board/oci/profiles/<name>.json ausente com o diretório do registry presente → profile is not registered;
  • registry ausente e nome diferente do bootstrap → profile registry is absent; only bootstrap-readonly-v1 is bootstrapped;
  • profile presente sem .board/locks/oci/<name>.lock.json → has no lock at.

Com esta adoção, bootstrap-readonly-v1 tem profile e lock rastreados, então um exit 78 para essa chave indica remoção/renomeação do documento — erro de repositório, nunca comportamento nominal. Exit 79 é engine ausente no host e exit 69 é falha de infraestrutura; nenhum dos três é RED ou GREEN.

Divergência caracterizada (schema × profile)

container-profile.schema.json limita tmpfs_mb a 128; o profile materializado declara 512 e o runner aceita até ceiling_tmpfs_mb=1024. O contrato (tests/contracts/AUR-422.go) fixa esse conjunto de divergência em exatamente {tmpfs_mb}: qualquer nova divergência, ou o desaparecimento silencioso desta, falha. Corrigir o schema é trabalho do card dono do schema, fora dos paths deste card.

Prova

  • Unit tests/unit/AUR-422.go::TestAUR422: loader canônico + mutantes MUT-001..003, rootfs gravável, privileged, cap_add, stdout sem teto, chave fora do registry e lock estrangeiro.
  • Contract tests/contracts/AUR-422.go::ContractAUR422: congruência schema/runner/profile/lock por conjunto exato de chaves e constantes.
  • Integration tests/integration/AUR-422.go::IntegrationAUR422: constantes, padrões e diagnósticos die 78 re-extraídos do source do runner.
  • E2E tests/e2e/AUR-422.sh::E2EAUR422: binding content-addressed real e literais de hardening nos bytes rastreados.
  • Acceptance tests/acceptance/AUR-422.sh::AC-001 via ./.board/bin/oci-run --profile bootstrap-readonly-v1 --card AUR-422.