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 0ou 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>.jsonausente 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ósticosdie 78re-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-001via./.board/bin/oci-run --profile bootstrap-readonly-v1 --card AUR-422.