diff --git a/scripts/artifact-registry-preflight-classification-contract-test.ts b/scripts/artifact-registry-preflight-classification-contract-test.ts index ebd48033..6284398a 100644 --- a/scripts/artifact-registry-preflight-classification-contract-test.ts +++ b/scripts/artifact-registry-preflight-classification-contract-test.ts @@ -42,6 +42,12 @@ assertCondition(Buffer.byteLength(probe.script, "utf8") < 4000, "readonly regist bytes: Buffer.byteLength(probe.script, "utf8"), remoteCommandShape: probe.remoteCommandShape, }); +const hashOutputIndex = probe.script.indexOf('kv config_hash "$config_hash"'); +const matchOutputIndex = probe.script.indexOf("kv config_hash_matches"); +assertCondition(matchOutputIndex > 0 && hashOutputIndex > matchOutputIndex, "readonly registry probe must emit match booleans before long hash values", { + hashOutputIndex, + matchOutputIndex, +}); const missing = asRecord(artifactRegistryReadonlyResultFromCommand(probe, command({ exitCode: 1, @@ -116,6 +122,40 @@ assertCondition(asStringArray(success.failedScopes, "success.failedScopes").leng assertCondition(success.recommendedAction === "none", "healthy registry recommendedAction should be none", success); assertCondition(success.remoteCommandShape === probe.remoteCommandShape, "healthy registry should echo remote command shape", success); +const compactedSuccessStdout = [ + "readonly=true", + "unit_exists=true", + "compose_exists=true", + "config_exists=true", + "storage_exists=true", + "systemctl_available=true", + "unit_active=active", + "unit_enabled=enabled", + "docker_available=true", + "container_running=true", + "container_status=running", + "container_image=registry:2.8.3", + "container_restart_policy=unless-stopped", + "listener_count=1", + "bad_listener_count=0", + "loopback_only=true", + "curl_available=true", + "v2_http_code=200", + "config_hash_matches=true", + "compose_hash_matches=true", + "unit_hash_matches=true", + "image_matches=true", + "config_hash=contract-config", + "compose_hash=contract-compose", + "unit_hash=contract-unit...", + "", +].join("\n"); +const compactedSuccess = asRecord(artifactRegistryReadonlyResultFromCommand(probe, command({ + stdout: compactedSuccessStdout, +})), "compacted success result"); +assertCondition(compactedSuccess.ok === true, "registry health must survive backend-core task detail compaction when match flags are present", compactedSuccess); +assertCondition(asStringArray(compactedSuccess.failedScopes, "compactedSuccess.failedScopes").length === 0, "compacted healthy registry should not have failed scopes", compactedSuccess); + const driftStdout = [ "readonly=true", "unit_exists=true", diff --git a/scripts/src/artifact-registry.ts b/scripts/src/artifact-registry.ts index b9d15459..f36c28e4 100644 --- a/scripts/src/artifact-registry.ts +++ b/scripts/src/artifact-registry.ts @@ -1162,13 +1162,13 @@ fi config_hash="$(hash_file "$config")" compose_hash="$(hash_file "$compose")" unit_hash="$(hash_file "$unit")" -kv config_hash "$config_hash" -kv compose_hash "$compose_hash" -kv unit_hash "$unit_hash" kv config_hash_matches "$([ -n "$config_hash" ] && [ "$config_hash" = ${shellQuote(hashes[bundle.paths.config] ?? "")} ] && printf true || printf false)" kv compose_hash_matches "$([ -n "$compose_hash" ] && [ "$compose_hash" = ${shellQuote(hashes[bundle.paths.compose] ?? "")} ] && printf true || printf false)" kv unit_hash_matches "$([ -n "$unit_hash" ] && [ "$unit_hash" = ${shellQuote(hashes[bundle.paths.unit] ?? "")} ] && printf true || printf false)" kv image_matches "$([ "\${container_image:-}" = "$expected_image" ] && printf true || printf false)" +kv config_hash "$config_hash" +kv compose_hash "$compose_hash" +kv unit_hash "$unit_hash" `; }