AUR-404 — Perfil Go Git offline (go-git-offline-v1)
Documento histórico do board. Pode descrever componentes removidos; para uso atual, consulte o guia do produto.
Este documento descreve a entrada go-git-offline-v1 publicada no registry
canônico de profiles. O card publica somente documentos: nenhum engine é
invocado, nenhuma fixture Git é criada e o runner permanece fail-closed para
esta chave até um card de implementação dependente habilitá-la explicitamente.
Artefatos
| Artefato | Caminho |
|---|---|
| Schema | .board/schemas/go-git-offline-profile.schema.json |
| Profile | .board/oci/profiles/go-git-offline-v1.json |
| Lock | .board/locks/oci/go-git-offline-v1.lock.json |
| Registry | .board/oci/profiles/registry.v1.json |
O registry passa a publicar exatamente quatro chaves, em ordem canônica
crescente: bootstrap-readonly-v1, go-git-offline-v1, go-unit-offline-v1,
registry-v1. Nenhuma chave existente muda de digest, schema ou lock.
Imagem pinada
O lock fixa Go e Git na mesma imagem, por digest imutável:
golang@sha256:4746d26432a9117a5f58e95cb9f954ddf0de128e9d5816886514199316e4a2fb
A imagem foi escolhida por prova, não por conveniência: é a única imagem local
que satisfaz simultaneamente bash, go1.21.13 e git 2.39.2 sob
--pull=never --network=none --read-only --user=65534:65534 --cap-drop=ALL.
A imagem de bootstrap aurum-bootstrap-go-bash tem bash e go, mas não
tem git, e por isso não pode servir este profile.
Somente golang@sha256:<64 hex> é aceito. Uma tag mutável (golang:1.21),
um nome sem digest ou outro repositório é rejeitado com mutable-input antes
de qualquer resolução de imagem.
Plano declarado
Limites e isolamento (idênticos em espírito ao go-unit-offline-v1, com folga
de tmpfs e wall-clock para a fixture Git descartável):
| Chave | Valor |
|---|---|
network |
none |
user |
65534:65534 |
cap_drop / cap_add |
ALL / none |
mounts / devices |
none / none |
pull |
never |
tmpfs |
rw,nosuid,nodev |
checkout_readonly |
true |
read_only_rootfs |
true |
no_new_privileges |
true |
privileged |
false |
timeout_seconds |
120 |
memory_mb |
256 |
cpu_millis |
1000 |
pids_limit |
128 |
tmpfs_mb |
256 |
stdout_limit_bytes / stderr_limit_bytes |
65536 / 65536 |
max_input_files / max_input_bytes |
10000 / 67108864 |
module_cache |
/go/pkg/mod (module_cache_read_only: true) |
Capacidades Git, todas negadas no documento e verificadas pelo loader:
| Chave | Valor | Efeito |
|---|---|---|
git_fixture |
ephemeral |
apenas fixture descartável é admitida |
git_fixture_root |
/tmp/aurum-git-fixture |
fixture vive no tmpfs limitado, nunca no checkout |
host_checkout |
denied |
nenhum repositório do host é alcançável |
credential_helpers |
denied |
nenhum helper de credencial é permitido |
hooks |
denied |
nenhum hook do repositório é executado |
signing |
denied |
nenhum helper de assinatura é invocado |
Comandos permitidos
["go", "test", "-mod=readonly", "./..."]
Qualquer outro comando, ou o mesmo comando com aridade diferente, invalida o plano. O ambiente é fechado sobre exatamente estas chaves:
| Variável | Valor |
|---|---|
GOPROXY |
off |
GOSUMDB |
off |
GONOSUMDB |
* |
GOTOOLCHAIN |
local |
GIT_CONFIG_NOSYSTEM |
1 |
GIT_CONFIG_GLOBAL |
/dev/null |
GIT_CONFIG_SYSTEM |
/dev/null |
GIT_TERMINAL_PROMPT |
0 |
GIT_ASKPASS |
/bin/false |
GIT_ALLOW_PROTOCOL |
none |
GIT_CEILING_DIRECTORIES |
/tmp |
Nenhuma credencial, valor de ambiente do host ou segredo entra no documento.
Códigos de rejeição
O loader (ValidateRegistryAUR404 / ValidateProfileAUR404) é
side-effect-free e devolve exatamente um código:
| Código | Causa |
|---|---|
registry-missing |
registry ausente ou não regular |
schema-invalid |
registry, schema ou profile fora da forma canônica (inclui chave duplicada dentro de um objeto JSON) |
schema-missing |
documento de schema ausente |
schema-digest-mismatch |
schema_digest não reproduz os bytes do schema |
profile-missing |
documento do profile ausente |
profile-unregistered |
chave desconhecida, ou go-git-offline-v1 ausente do registry |
duplicate-profile |
a mesma chave publicada duas vezes |
order-invalid |
chaves fora da ordem canônica crescente |
digest-invalid |
digest vizinho fora do formato sha256:<64 hex> |
unsafe-plan |
limite obrigatório ausente/relaxado, rede, mount, device, root, capability, checkout host, hook, credential helper, signing ou fixture persistente |
lock-missing |
lock ausente |
mutable-input |
imagem por tag mutável, repositório inesperado ou lock fora do schema |
lock-digest-mismatch |
lock_digest não reproduz os bytes do lock |
Diagnóstico offline
Tudo abaixo roda sem rede e sem engine.
# digests declarados vs. bytes em disco
sha256sum .board/schemas/go-git-offline-profile.schema.json
sha256sum .board/locks/oci/go-git-offline-v1.lock.json
printf '%s' 'golang@sha256:4746d26432a9117a5f58e95cb9f954ddf0de128e9d5816886514199316e4a2fb' | sha256sum
# aceitação selada do card (única forma verde é exit 0)
./.board/bin/oci-run --profile bootstrap-readonly-v1 --card AUR-404
# camadas isoladas
bash tests/acceptance/AUR-404.sh TestAUR404
bash tests/acceptance/AUR-404.sh ContractAUR404
bash tests/acceptance/AUR-404.sh IntegrationAUR404
bash tests/acceptance/AUR-404.sh E2EAUR404
# mutantes declarados
bash tests/acceptance/AUR-404.sh AC-001-MUT-001 # duplicate-profile
bash tests/acceptance/AUR-404.sh AC-001-MUT-002 # mutable-input
bash tests/acceptance/AUR-404.sh AC-001-MUT-003 # unsafe-plan
Compatibilidade
tests/unit/AUR-402.go e tests/unit/AUR-403.go fecham a allowlist de chaves
do registry sobre o conjunto registrado, e o loader de AUR-403 ainda afirma o
comprimento e a ordem posicional das chaves. Registrar a quarta chave portanto
exige ensinar go-git-offline-v1 aos dois loaders no mesmo commit; sem isso as
regressões já entregues quebrariam de fora do write-set deste card. Nenhum dos
dois loaders lê os documentos de go-git-offline-v1: ambos verificam apenas o
caminho declarado e a forma do digest, de modo que registrar Git não pode
redirecionar silenciosamente o plano Go unit.
A aceitação deste card roda sob bootstrap-readonly-v1 (que não tem git) e é
validação pura de documento: nenhum comando Git é executado e
engine_invocations permanece 0.