Files
xjxandgd-ops 91aabc4870 fix(connections): complete DSH acceptance hardening (#43)
## Development claim / 开发声明

- Domain: `agent-connections`
- Claim: `dsh-connector`
- Base commit: `f31e9580b55564e4bd2566d6383e50ecc58e721c`
- Release preparation: `no`
- Focused validation:
  - `cargo test -p petcore --test integration_d --locked`
  - `./script/validate_connectors_runtime.sh`

<!-- apc-engineering-coordination-v1
{"claim_overlap_rejections":0,"merge_tree_conflicts":0,"schema_version":"apc.engineering-coordination.v1","task_created_at":"2026-08-18T16:45:48Z","train_conflict_resolutions":0}
-->

Co-authored-by: gd-ops <gd-ops@xmfunny.com>
2026-08-19 01:01:47 +08:00

944 lines
34 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
MODE="development"
EXPECTED_ARCH=""
APP_BUNDLE="$ROOT_DIR/dist/AgentPetCompanion.app"
STATIC_ONLY=0
usage() {
cat <<'EOF'
usage: validate_app_bundle.sh \
[--development|--github-release] \
[--architecture arm64|x86_64] \
[--static-only] \
[APP_BUNDLE]
--development validates a local App with an optional ad-hoc signature.
--github-release requires the official ad-hoc signature and release identity.
It does not claim Developer ID identity, Apple notarization, or Gatekeeper trust.
Architecture is required for every non-development mode.
--static-only validates structure, signatures, identities, and resources without
executing packaged App, PetCore, or CLI code.
EOF
}
while (($# > 0)); do
case "$1" in
--development)
MODE="development"
shift
;;
--github-release)
MODE="github-release"
shift
;;
--architecture)
(($# >= 2)) || { usage >&2; exit 2; }
EXPECTED_ARCH="$2"
shift 2
;;
--architecture=*)
EXPECTED_ARCH="${1#--architecture=}"
shift
;;
--static-only)
STATIC_ONLY=1
shift
;;
-h|--help)
usage
exit 0
;;
-* )
printf 'unknown argument: %s\n' "$1" >&2
usage >&2
exit 2
;;
*)
APP_BUNDLE="$1"
shift
(($# == 0)) || { usage >&2; exit 2; }
;;
esac
done
case "$APP_BUNDLE" in
/*)
;;
*)
APP_BUNDLE="$PWD/$APP_BUNDLE"
;;
esac
case "$EXPECTED_ARCH" in
"")
;;
arm64|aarch64)
EXPECTED_ARCH="arm64"
;;
x86_64|x64|amd64|intel)
EXPECTED_ARCH="x86_64"
;;
*)
printf 'unsupported expected architecture: %s\n' "$EXPECTED_ARCH" >&2
exit 2
;;
esac
if [[ "$MODE" != "development" && -z "$EXPECTED_ARCH" ]]; then
echo 'non-development validation requires --architecture arm64 or --architecture x86_64' >&2
exit 2
fi
HOST_ARCH="$(uname -m)"
case "$HOST_ARCH" in
aarch64) HOST_ARCH="arm64" ;;
amd64) HOST_ARCH="x86_64" ;;
esac
RUN_PACKAGED_RUNTIME=1
RUNTIME_VALIDATION_SCOPE="packaged functionality"
if [[ "$STATIC_ONLY" == "1" ]]; then
RUN_PACKAGED_RUNTIME=0
RUNTIME_VALIDATION_SCOPE="static package validation; packaged code not launched"
elif [[ -n "$EXPECTED_ARCH" && "$EXPECTED_ARCH" != "$HOST_ARCH" ]]; then
# Launching an Intel App on Apple silicon invokes Rosetta and now presents a
# system compatibility warning. Cross-architecture release validation stays
# static; the matching native archive exercises the shared runtime behavior.
RUN_PACKAGED_RUNTIME=0
RUNTIME_VALIDATION_SCOPE="static package validation; cross-architecture runtime not launched"
fi
APP_NAME="AgentPetCompanion"
APP_CONTENTS="$APP_BUNDLE/Contents"
APP_BINARY="$APP_CONTENTS/MacOS/$APP_NAME"
APP_RESOURCES="$APP_CONTENTS/Resources"
PETCORE="$APP_RESOURCES/bin/petcore"
PETCORE_CLI="$APP_RESOURCES/bin/petcore-cli"
RUNTIME_MANIFEST="$APP_RESOURCES/runtime-manifest.json"
INTERACTION_ATTESTATION="$APP_RESOURCES/interaction-attestation.json"
# Validation must exercise the evidence shipped with this exact bundle. A
# caller such as test_all may export a source-build attestation for earlier
# checks; never let that override redirect packaged PetCore or CLI processes.
export APC_INTERACTION_ATTESTATION_PATH="$INTERACTION_ATTESTATION"
BUNDLED_SKILL="$APP_RESOURCES/skills/agent-pet-studio/SKILL.md"
SOURCE_SKILL="$ROOT_DIR/skills/agent-pet-studio/SKILL.md"
BUNDLED_PORTABLE_SKILL="$APP_RESOURCES/skills/agent-pet-maker"
SOURCE_PORTABLE_SKILL="$ROOT_DIR/skills/agent-pet-maker"
SOURCE_CODEX_PLUGIN_MANIFEST="$ROOT_DIR/plugins/codex/.codex-plugin/plugin.json"
LOCALIZATION_BUNDLE="$APP_RESOURCES/AgentPetCompanion_AgentPetCompanion.bundle"
BUNDLE_ICON="$APP_RESOURCES/AgentPetCompanion.icns"
SOURCE_ICON="$ROOT_DIR/logo/macos/AgentPetCompanionTransparent.icns"
BUNDLED_BRAND_MARK="$LOCALIZATION_BUNDLE/AgentPetCompanionMark.png"
SOURCE_BRAND_MARK="$ROOT_DIR/logo/transparent/agent-pet-mark-transparent-1024.png"
BUNDLED_PETS_DIR="$LOCALIZATION_BUNDLE/BuiltInPets"
SOURCE_PETS_DIR="$ROOT_DIR/apps/macos/Sources/AgentPetCompanion/Resources/BuiltInPets"
TMP_DIR="$(mktemp -d "${TMPDIR:-/tmp}/apc-bundle-validation.XXXXXX")"
. "$ROOT_DIR/script/validation_helpers.sh"
apc_use_isolated_home "$TMP_DIR"
PETCORE_PID=""
cleanup() {
if [[ -n "$PETCORE_PID" ]]; then
kill "$PETCORE_PID" >/dev/null 2>&1 || true
wait "$PETCORE_PID" >/dev/null 2>&1 || true
fi
rm -rf "$TMP_DIR"
}
trap cleanup EXIT
[[ -d "$APP_BUNDLE" ]] || {
echo "app bundle validation failed: missing bundle $APP_BUNDLE" >&2
exit 1
}
[[ -x "$APP_BINARY" ]] || {
echo "app bundle validation failed: missing executable $APP_BINARY" >&2
exit 1
}
[[ -x "$PETCORE" ]] || {
echo "app bundle validation failed: missing bundled petcore $PETCORE" >&2
exit 1
}
[[ -x "$PETCORE_CLI" ]] || {
echo "app bundle validation failed: missing bundled petcore-cli $PETCORE_CLI" >&2
exit 1
}
if [[ -n "$EXPECTED_ARCH" ]]; then
"$ROOT_DIR/script/validate_macho_architectures.sh" \
--app "$APP_BUNDLE" \
--architecture "$EXPECTED_ARCH"
fi
if [[ "$MODE" == "github-release" ]]; then
# One SDK 26 build must retain the macOS 14 deployment target and weak-link
# every macOS 26 Liquid Glass entry point. This is the static proof that the
# same archive renders native glass on macOS 26 and the authored material
# fallback on macOS 14/15.
"$ROOT_DIR/script/validate_macos_build_contract.py" artifact \
--binary "$APP_BINARY" \
--deployment-target 14.0 \
--minimum-sdk 26.0
fi
SIGNATURE_PRESENT=0
if [[ -e "$APP_CONTENTS/_CodeSignature" ]]; then
SIGNATURE_PRESENT=1
fi
if [[ "$MODE" != "development" && "$SIGNATURE_PRESENT" != "1" ]]; then
echo 'packaged app bundle validation failed: the outer App requires a signature' >&2
exit 1
fi
if [[ "$SIGNATURE_PRESENT" == "1" ]]; then
command -v codesign >/dev/null 2>&1 || {
echo 'app bundle validation failed: a signature is present but codesign is unavailable' >&2
exit 1
}
if ! codesign --verify --deep --strict --verbose=2 "$APP_BUNDLE"; then
echo 'app bundle validation failed: strict signature verification failed' >&2
exit 1
fi
fi
validate_github_release_signature_before_runtime() {
local signed_item
local signature_metadata
for signed_item in "$APP_BINARY" "$PETCORE" "$PETCORE_CLI" "$APP_BUNDLE"; do
if ! signature_metadata="$(codesign -d --verbose=4 "$signed_item" 2>&1)"; then
printf 'GitHub Release validation failed: cannot inspect signature: %s\n' \
"$signed_item" >&2
exit 1
fi
if ! grep -Fx 'Signature=adhoc' <<<"$signature_metadata" >/dev/null; then
printf 'GitHub Release validation failed: expected ad-hoc signature: %s\n' \
"$signed_item" >&2
exit 1
fi
done
python3 - "$APP_CONTENTS/Info.plist" <<'PY'
import plistlib
import sys
with open(sys.argv[1], "rb") as file:
info = plistlib.load(file)
if info.get("APCReleaseChannel") != "release":
raise SystemExit(
"GitHub Release validation failed: APCReleaseChannel must be 'release'"
)
PY
}
if [[ "$MODE" == "github-release" ]]; then
# Keep this before every invocation of packaged App, PetCore, or CLI code.
validate_github_release_signature_before_runtime
fi
[[ -f "$RUNTIME_MANIFEST" ]] || {
echo "app bundle validation failed: missing runtime manifest $RUNTIME_MANIFEST" >&2
exit 1
}
[[ -f "$INTERACTION_ATTESTATION" ]] || {
echo "app bundle validation failed: missing interaction attestation $INTERACTION_ATTESTATION" >&2
exit 1
}
[[ -f "$BUNDLED_SKILL" ]] || {
echo "app bundle validation failed: missing bundled agent-pet-studio skill" >&2
exit 1
}
[[ -f "$BUNDLED_PORTABLE_SKILL/SKILL.md" ]] || {
echo "app bundle validation failed: missing bundled agent-pet-maker skill" >&2
exit 1
}
for table in Common PetLibrary Maker Connections Overlay Settings Diagnostics; do
table_root="$LOCALIZATION_BUNDLE/Localization/$table"
[[ -f "$table_root/$table.xcstrings" ]] || {
echo "app bundle validation failed: missing bundled $table String Catalog" >&2
exit 1
}
[[ -f "$table_root/en.lproj/$table.strings" ]] || {
echo "app bundle validation failed: missing bundled $table English localization" >&2
exit 1
}
[[ -f "$table_root/zh-Hans.lproj/$table.strings" ]] || {
echo "app bundle validation failed: missing bundled $table Simplified Chinese localization" >&2
exit 1
}
done
[[ -f "$BUNDLE_ICON" ]] || {
echo "app bundle validation failed: missing app icon" >&2
exit 1
}
[[ -f "$BUNDLED_BRAND_MARK" ]] || {
echo "app bundle validation failed: missing bundled brand mark" >&2
exit 1
}
cmp -s "$SOURCE_SKILL" "$BUNDLED_SKILL" || {
echo "app bundle validation failed: bundled agent-pet-studio skill differs from source" >&2
exit 1
}
if find "$BUNDLED_PORTABLE_SKILL" \
\( -type d -name '__pycache__' -o -type f \( -name '*.pyc' -o -name '*.pyo' \) \) \
-print -quit | grep -q .; then
echo "app bundle validation failed: bundled agent-pet-maker contains Python bytecode" >&2
exit 1
fi
diff -qr -x '__pycache__' -x '*.pyc' -x '*.pyo' \
"$SOURCE_PORTABLE_SKILL" "$BUNDLED_PORTABLE_SKILL" >/dev/null || {
echo "app bundle validation failed: bundled agent-pet-maker skill differs from source" >&2
exit 1
}
cmp -s "$SOURCE_ICON" "$BUNDLE_ICON" || {
echo "app bundle validation failed: bundled app icon differs from approved transparent icon" >&2
exit 1
}
cmp -s "$SOURCE_BRAND_MARK" "$BUNDLED_BRAND_MARK" || {
echo "app bundle validation failed: bundled brand mark differs from approved transparent mark" >&2
exit 1
}
for petpack_name in pet_xingwutuanzi.petpack pet_bytebudcodex.petpack pet_pinklace.petpack; do
[[ -f "$BUNDLED_PETS_DIR/$petpack_name" && ! -L "$BUNDLED_PETS_DIR/$petpack_name" ]] || {
echo "app bundle validation failed: missing bundled pet $petpack_name" >&2
exit 1
}
cmp -s "$SOURCE_PETS_DIR/$petpack_name" "$BUNDLED_PETS_DIR/$petpack_name" || {
echo "app bundle validation failed: bundled pet differs from audited source: $petpack_name" >&2
exit 1
}
if [[ "$RUN_PACKAGED_RUNTIME" == "1" ]]; then
"$PETCORE_CLI" petpack validate "$BUNDLED_PETS_DIR/$petpack_name" >/dev/null
fi
done
if [[ "$(find "$BUNDLED_PETS_DIR" -mindepth 1 -maxdepth 1 -print | wc -l | tr -d ' ')" != "3" ]]; then
echo "app bundle validation failed: bundled pet inventory must contain exactly the three approved entries" >&2
exit 1
fi
python3 - "$BUNDLED_PETS_DIR" <<'PY'
import json
import pathlib
import sys
import zipfile
root = pathlib.Path(sys.argv[1])
expected = {
"pet_xingwutuanzi.petpack": ("pet_xingwutuanzi", "low", (192, 208)),
"pet_bytebudcodex.petpack": ("pet_bytebudcodex", "standard", (384, 416)),
"pet_pinklace.petpack": ("pet_pinklace", "standard", (384, 416)),
}
for name, (pet_id, quality, size) in expected.items():
path = root / name
with zipfile.ZipFile(path) as archive:
manifest = json.loads(archive.read("manifest.json"))
actual_size = manifest.get("render_size", {})
if (
manifest.get("schema_version") != "apc.petpack.v3"
or manifest.get("id") != pet_id
or manifest.get("quality") != quality
or (actual_size.get("width"), actual_size.get("height")) != size
):
raise SystemExit(f"app bundle validation failed: bundled pet contract mismatch: {name}")
PY
python3 - "$APP_CONTENTS/Info.plist" <<'PY'
import plistlib
import sys
path = sys.argv[1]
with open(path, "rb") as file:
info = plistlib.load(file)
expected = {
"CFBundleExecutable": "AgentPetCompanion",
"CFBundleIdentifier": "dev.agentpet.companion",
"CFBundleIconFile": "AgentPetCompanion.icns",
"CFBundleName": "AgentPetCompanion",
"CFBundlePackageType": "APPL",
"NSPrincipalClass": "NSApplication",
}
for key, value in expected.items():
actual = info.get(key)
if actual != value:
raise SystemExit(f"app bundle validation failed: {key}={actual!r}, expected {value!r}")
minimum = info.get("LSMinimumSystemVersion")
if minimum != "14.0":
raise SystemExit(
f"app bundle validation failed: LSMinimumSystemVersion={minimum!r}, expected '14.0'"
)
version = info.get("CFBundleShortVersionString")
build = info.get("CFBundleVersion")
build_id = info.get("APCBuildID")
release_channel = info.get("APCReleaseChannel")
runtime_manifest_schema = info.get("APCRuntimeManifestSchemaVersion")
if not isinstance(version, str) or not version.strip():
raise SystemExit("app bundle validation failed: missing CFBundleShortVersionString")
if not isinstance(build, str) or not build.strip():
raise SystemExit("app bundle validation failed: missing CFBundleVersion")
if not isinstance(build_id, str) or not build_id.strip():
raise SystemExit("app bundle validation failed: missing APCBuildID")
if release_channel not in {"develop", "release"}:
raise SystemExit("app bundle validation failed: invalid APCReleaseChannel")
if runtime_manifest_schema != "apc.runtime-manifest.v1":
raise SystemExit("app bundle validation failed: invalid APCRuntimeManifestSchemaVersion")
exported_types = info.get("UTExportedTypeDeclarations")
if not isinstance(exported_types, list):
raise SystemExit("app bundle validation failed: missing UTExportedTypeDeclarations")
petpack = next(
(
declaration
for declaration in exported_types
if declaration.get("UTTypeIdentifier") == "dev.agentpet.petpack"
),
None,
)
if petpack is None:
raise SystemExit("app bundle validation failed: missing dev.agentpet.petpack UTI")
if "public.data" not in petpack.get("UTTypeConformsTo", []):
raise SystemExit("app bundle validation failed: dev.agentpet.petpack must conform to public.data")
extensions = petpack.get("UTTypeTagSpecification", {}).get("public.filename-extension", [])
if extensions != ["petpack"]:
raise SystemExit(
"app bundle validation failed: dev.agentpet.petpack filename extension must be petpack"
)
mime = petpack.get("UTTypeTagSpecification", {}).get("public.mime-type")
if mime != "application/vnd.agentpet.petpack+zip":
raise SystemExit(
"app bundle validation failed: dev.agentpet.petpack MIME type is invalid"
)
PY
python3 - "$APP_CONTENTS/Info.plist" "$RUNTIME_MANIFEST" <<'PY'
import json
import plistlib
import sys
with open(sys.argv[1], "rb") as file:
info = plistlib.load(file)
with open(sys.argv[2], "r", encoding="utf-8") as file:
manifest = json.load(file)
expected = {
"schema_version": "apc.runtime-manifest.v1",
"release_channel": info["APCReleaseChannel"],
"app_version": info["CFBundleShortVersionString"],
"app_build": info["CFBundleVersion"],
"build_id": info["APCBuildID"],
"petcore_build_id": info["APCBuildID"],
"petcore_cli_build_id": info["APCBuildID"],
}
for key, value in expected.items():
if manifest.get(key) != value:
raise SystemExit(
f"app bundle validation failed: runtime manifest {key}="
f"{manifest.get(key)!r}, expected {value!r}"
)
PY
python3 -B - \
"$ROOT_DIR" \
"$APP_CONTENTS/Info.plist" \
"$INTERACTION_ATTESTATION" \
"$ROOT_DIR/script/interaction-contract-files.txt" <<'PY'
import hashlib
import json
import pathlib
import plistlib
import stat
import sys
root = pathlib.Path(sys.argv[1]).resolve()
with open(sys.argv[2], "rb") as file:
info = plistlib.load(file)
attestation_path = pathlib.Path(sys.argv[3])
attestation = json.loads(attestation_path.read_text(encoding="utf-8"))
expected_keys = {
"schema_version",
"build_id",
"interaction_contract_digest",
"passed_suites",
"ok",
}
if set(attestation) != expected_keys:
raise SystemExit("app bundle validation failed: interaction attestation fields are not closed")
if attestation["schema_version"] != "apc.overlay-interaction-attestation.v1":
raise SystemExit("app bundle validation failed: interaction attestation schema mismatch")
if attestation["build_id"] != info["APCBuildID"] or attestation["ok"] is not True:
raise SystemExit("app bundle validation failed: interaction attestation build identity mismatch")
expected_suites = [
"OverlayPlacementAuthorityTests",
"AppStoreOverlaySnapshotTests",
"OverlayGeometryTests",
"OverlayDisplayWidthTests",
"OverlayInteractionTelemetryTests",
]
if attestation["passed_suites"] != expected_suites:
raise SystemExit("app bundle validation failed: interaction attestation suites are incomplete")
entries = [
line
for line in pathlib.Path(sys.argv[4]).read_text(encoding="utf-8").splitlines()
if line
]
if not entries or entries != sorted(set(entries)):
raise SystemExit("app bundle validation failed: interaction contract file list is invalid")
digest = hashlib.sha256()
for entry in entries:
relative = pathlib.PurePosixPath(entry)
if relative.is_absolute() or any(part in {"", ".", ".."} for part in relative.parts):
raise SystemExit("app bundle validation failed: unsafe interaction contract path")
path = root.joinpath(*relative.parts)
metadata = path.lstat()
if not stat.S_ISREG(metadata.st_mode) or path.is_symlink():
raise SystemExit("app bundle validation failed: invalid interaction contract file")
digest.update(entry.encode("utf-8"))
digest.update(b"\0")
digest.update(path.read_bytes())
digest.update(b"\0")
if attestation["interaction_contract_digest"] != digest.hexdigest():
raise SystemExit("app bundle validation failed: interaction attestation digest is stale")
PY
grep -q '^name: agent-pet-studio$' "$BUNDLED_SKILL" || {
echo 'app bundle validation failed: bundled Studio skill name is invalid' >&2
exit 1
}
grep -q 'APC_PETCORE_CLI' "$BUNDLED_SKILL" || {
echo 'app bundle validation failed: bundled Studio skill omits the PetCore CLI contract' >&2
exit 1
}
grep -q 'security.md' "$BUNDLED_SKILL" || {
echo 'app bundle validation failed: bundled Studio skill omits the shared security contract' >&2
exit 1
}
grep -q 'Do not read authentication files' \
"$BUNDLED_PORTABLE_SKILL/references/security.md" || {
echo 'app bundle validation failed: bundled security contract omits the agent-auth guardrail' >&2
exit 1
}
grep -q '^name: agent-pet-maker$' "$BUNDLED_PORTABLE_SKILL/SKILL.md" || {
echo 'app bundle validation failed: bundled Maker skill name is invalid' >&2
exit 1
}
grep -q 'capability-missing' "$BUNDLED_PORTABLE_SKILL/SKILL.md" || {
echo 'app bundle validation failed: bundled Maker skill omits capability preflight' >&2
exit 1
}
[[ -x "$BUNDLED_PORTABLE_SKILL/scripts/petpack_workspace.py" ]] || {
echo 'app bundle validation failed: bundled Maker workspace helper is not executable' >&2
exit 1
}
[[ -x "$BUNDLED_PORTABLE_SKILL/scripts/prepare_transparent_frames.py" ]] || {
echo 'app bundle validation failed: bundled Maker transparent-frame helper is not executable' >&2
exit 1
}
grep -q 'transparent-frame-production.md' "$BUNDLED_SKILL" || {
echo 'app bundle validation failed: bundled Studio skill omits the shared transparency contract' >&2
exit 1
}
if [[ "$RUN_PACKAGED_RUNTIME" == "1" ]]; then
# Run the exact native packaged Swift/AppKit executable through its
# prohibited-activation validation mode. This exercises packaged
# optimization, resources, overlay geometry, keyboard accessibility, and
# frame-pipeline wiring without opening windows or taking user input.
UI_VALIDATION_OUTPUT="$(
APC_HOME="$TMP_DIR/ui-validation-home" \
APC_DISABLE_LAUNCH_AGENT=1 \
APC_DISABLE_CODEX_APP_SERVER_AUTO=1 \
"$APP_BINARY" --run-ui-validation
)"
grep -q '^AgentPetCompanionUIValidation ok: [0-9][0-9]*/[0-9][0-9]* checks passed$' \
<<<"$UI_VALIDATION_OUTPUT" || {
echo 'app bundle validation failed: packaged UI validation did not complete' >&2
printf '%s\n' "$UI_VALIDATION_OUTPUT" >&2
exit 1
}
printf '%s\n' "$UI_VALIDATION_OUTPUT"
APC_HOME="$TMP_DIR/home" "$PETCORE" preflight \
--home "$TMP_DIR/home" \
--manifest "$RUNTIME_MANIFEST" >/dev/null
APC_HOME="$TMP_DIR/home" "$PETCORE" init
BUNDLE_BUILD_ID="$(python3 - "$APP_CONTENTS/Info.plist" <<'PY'
import plistlib
import sys
with open(sys.argv[1], "rb") as file:
print(plistlib.load(file)["APCBuildID"])
PY
)"
PRODUCTION_INTERACTION="$("$PETCORE_CLI" petpack verify-production-interaction)"
JSON="$PRODUCTION_INTERACTION" BUNDLE_BUILD_ID="$BUNDLE_BUILD_ID" python3 - <<'PY'
import json
import os
value = json.loads(os.environ["JSON"])
expected_suites = [
"OverlayPlacementAuthorityTests",
"AppStoreOverlaySnapshotTests",
"OverlayGeometryTests",
"OverlayDisplayWidthTests",
"OverlayInteractionTelemetryTests",
]
assert value["ok"] is True, value
assert value["build_id"] == os.environ["BUNDLE_BUILD_ID"], value
assert value["interaction_evidence"] == expected_suites, value
assert len(value["interaction_contract_digest"]) == 64, value
PY
BUDGET="$("$PETCORE_CLI" renderer budget --quality standard --frame-count 40)"
JSON="$BUDGET" python3 - <<'PY'
import json
import os
data = json.loads(os.environ["JSON"])
assert data["quality"] == "standard", data
assert data["frame_count"] == 40, data
assert data["runtime_cache_frame_limit"] == 40, data
assert data["uses_ring_cache"] is False, data
assert data["decoded_state_mb"] > 0, data
PY
HIGH_BUDGET="$("$PETCORE_CLI" renderer budget --quality high --frame-count 40)"
JSON="$HIGH_BUDGET" python3 - <<'PY'
import json
import os
data = json.loads(os.environ["JSON"])
assert data["quality"] == "high", data
assert data["frame_count"] == 40, data
assert data["runtime_cache_frame_limit"] == 40, data
assert data["uses_ring_cache"] is False, data
assert data["decoded_state_mb"] > 0, data
PY
(
APC_HOME="$TMP_DIR/home" \
APC_AGENT_CONFIG_HOME="$TMP_DIR/agent-home" \
APC_DISABLE_CODEX_APP_SERVER_AUTO=1 \
APC_EXPECTED_BUILD_ID="$BUNDLE_BUILD_ID" \
APC_EXPECTED_RUNTIME_MANIFEST="$RUNTIME_MANIFEST" \
"$PETCORE" serve --ready-file "$TMP_DIR/ready"
) &
PETCORE_PID="$!"
for _ in {1..100}; do
[[ -f "$TMP_DIR/ready" ]] && break
sleep 0.05
done
[[ -f "$TMP_DIR/ready" ]]
HEALTH="$(APC_HOME="$TMP_DIR/home" "$PETCORE_CLI" health)"
HEALTH="$HEALTH" BUNDLE_BUILD_ID="$BUNDLE_BUILD_ID" RUNTIME_MANIFEST="$RUNTIME_MANIFEST" python3 - <<'PY'
import json
import os
health = json.loads(os.environ["HEALTH"])
expected = os.environ["BUNDLE_BUILD_ID"]
with open(os.environ["RUNTIME_MANIFEST"], "r", encoding="utf-8") as file:
manifest = json.load(file)
if health.get("build_id") != expected:
raise SystemExit(
f"app bundle validation failed: PetCore build_id={health.get('build_id')!r}, expected {expected!r}"
)
if health.get("runtime_manifest") != manifest:
raise SystemExit("app bundle validation failed: PetCore runtime manifest mismatch")
PY
# Exercise the packaged daemon, CLI and exact packaged resource directory as
# one clean-home seed path. Static digest checks above prove provenance; this
# closes the release gate by proving the installed summaries, active choice
# and database schema that the App's first snapshot consumes.
BUNDLED_SEED="$(
APC_HOME="$TMP_DIR/home" "$PETCORE_CLI" petpack seed-bundled \
--inventory-root "$BUNDLED_PETS_DIR"
)"
BUNDLED_PETS="$(APC_HOME="$TMP_DIR/home" "$PETCORE_CLI" pet list)"
BUNDLED_SEED="$BUNDLED_SEED" \
BUNDLED_PETS="$BUNDLED_PETS" \
BUNDLED_HOME="$TMP_DIR/home" \
BUNDLED_DB="$TMP_DIR/home/agent-pet.sqlite" \
python3 - <<'PY'
import json
import os
import pathlib
import sqlite3
import struct
PNG_SIGNATURE = b"\x89PNG\r\n\x1a\n"
RUNTIME_ASSET_SCHEMA = "apc.runtime-assets.v3"
REQUIRED_STATES = (
"idle",
"thinking",
"tool",
"waiting",
"done",
"failed",
"acknowledge",
"drag_left",
"drag_right",
)
def png_dimensions(path):
if path.is_symlink() or not path.is_file():
raise SystemExit(
f"app bundle validation failed: render asset is not a regular file: {path}"
)
with path.open("rb") as file:
header = file.read(24)
if (
len(header) != 24
or header[:8] != PNG_SIGNATURE
or header[12:16] != b"IHDR"
):
raise SystemExit(
f"app bundle validation failed: render asset is not a structurally valid PNG: {path}"
)
width, height = struct.unpack(">II", header[16:24])
if width <= 0 or height <= 0:
raise SystemExit(
f"app bundle validation failed: render asset has invalid dimensions: {path}"
)
return width, height
def require_managed(path, root, label, pet_id):
if path.is_symlink():
raise SystemExit(
f"app bundle validation failed: {label} must not be a symlink: {pet_id}"
)
resolved = path.resolve()
if root != resolved and root not in resolved.parents:
raise SystemExit(
f"app bundle validation failed: {label} is outside the managed pet store: {pet_id}"
)
return resolved
seed = json.loads(os.environ["BUNDLED_SEED"])
pets = json.loads(os.environ["BUNDLED_PETS"])
expected_ids = ["pet_xingwutuanzi", "pet_bytebudcodex", "pet_pinklace"]
outcomes = seed.get("outcomes")
if seed.get("inventory") != "apc.bundled-pets.v1":
raise SystemExit("app bundle validation failed: bundled seed inventory mismatch")
if not isinstance(outcomes, list) or [item.get("pet_id") for item in outcomes] != expected_ids:
raise SystemExit("app bundle validation failed: bundled seed outcomes mismatch")
if any(item.get("status") != "installed" for item in outcomes):
raise SystemExit("app bundle validation failed: clean-home bundled seed did not install all pets")
by_id = {pet.get("id"): pet for pet in pets if isinstance(pet, dict)}
if len(pets) != 3 or set(by_id) != set(expected_ids):
raise SystemExit("app bundle validation failed: clean-home library does not contain exactly all bundled pets")
managed_pets_root = pathlib.Path(os.environ["BUNDLED_HOME"]).resolve() / "pets"
for pet_id in expected_ids:
pet = by_id[pet_id]
if pet.get("origin") != "verified_skill_source":
raise SystemExit(f"app bundle validation failed: bundled origin mismatch: {pet_id}")
if pet.get("generator") != "agent-pet-companion.release-inventory":
raise SystemExit(f"app bundle validation failed: bundled generator mismatch: {pet_id}")
if pet.get("provenance") != "apc.bundled-pets.v1":
raise SystemExit(f"app bundle validation failed: bundled provenance mismatch: {pet_id}")
package_path = pathlib.Path(pet.get("petpack_path", ""))
if package_path.is_symlink() or not package_path.is_file():
raise SystemExit(f"app bundle validation failed: installed bundled package is unavailable: {pet_id}")
package_path = require_managed(
package_path, managed_pets_root, "installed bundled package", pet_id
)
cover_path = require_managed(
pathlib.Path(pet.get("cover_path", "")),
managed_pets_root,
"bundled cover",
pet_id,
)
expected_cover_path = package_path.parent / f"{pet_id}-cover.png"
if cover_path != expected_cover_path:
raise SystemExit(
"app bundle validation failed: bundled cover path is not canonical: "
f"{pet_id}; got {cover_path}, expected {expected_cover_path}"
)
png_dimensions(cover_path)
render_size = pet.get("render_size")
timings = pet.get("states")
if (
not isinstance(render_size, dict)
or not isinstance(render_size.get("width"), int)
or not isinstance(render_size.get("height"), int)
or not isinstance(timings, list)
or tuple(sorted(item.get("name") for item in timings if isinstance(item, dict)))
!= tuple(sorted(REQUIRED_STATES))
):
raise SystemExit(
f"app bundle validation failed: bundled render contract is malformed: {pet_id}"
)
frames_root = require_managed(
package_path.parent / f"{pet_id}-frames",
managed_pets_root,
"bundled runtime frames",
pet_id,
)
if frames_root.is_symlink() or not frames_root.is_dir():
raise SystemExit(
f"app bundle validation failed: bundled runtime frame directory is unavailable: {pet_id}"
)
marker_path = frames_root / ".apc-runtime-assets.json"
if marker_path.is_symlink() or not marker_path.is_file():
raise SystemExit(
f"app bundle validation failed: bundled runtime completion marker is unavailable: {pet_id}"
)
with marker_path.open("r", encoding="utf-8") as file:
marker = json.load(file)
if (
marker.get("schema_version") != RUNTIME_ASSET_SCHEMA
or marker.get("pet_id") != pet_id
or marker.get("render_size") != render_size
or marker.get("timing") != timings
or not isinstance(marker.get("frame_counts"), dict)
or tuple(sorted(marker["frame_counts"])) != tuple(sorted(REQUIRED_STATES))
):
raise SystemExit(
f"app bundle validation failed: bundled runtime marker mismatch: {pet_id}"
)
expected_dimensions = (render_size["width"], render_size["height"])
timing_by_state = {item["name"]: item for item in timings}
for state in REQUIRED_STATES:
timing = timing_by_state[state]
durations = timing.get("frame_durations_ms")
if (
not isinstance(durations, list)
or not (2 <= len(durations) <= 40)
or any(not isinstance(value, int) or not (50 <= value <= 2000) for value in durations)
or sum(durations) > 5000
):
raise SystemExit(
f"app bundle validation failed: bundled state timing is invalid: {pet_id}/{state}"
)
expected_count = len(durations)
state_dir = frames_root / state
if state_dir.is_symlink() or not state_dir.is_dir():
raise SystemExit(
f"app bundle validation failed: bundled runtime state is unavailable: {pet_id}/{state}"
)
frames = sorted(
path
for path in state_dir.iterdir()
if path.suffix.lower() == ".png"
)
if len(frames) != expected_count or marker["frame_counts"].get(state) != expected_count:
raise SystemExit(
f"app bundle validation failed: bundled runtime frame count mismatch: {pet_id}/{state}"
)
for frame in frames:
if png_dimensions(frame) != expected_dimensions:
raise SystemExit(
f"app bundle validation failed: bundled runtime frame dimensions mismatch: {pet_id}/{state}"
)
if by_id["pet_xingwutuanzi"].get("active") is not True:
raise SystemExit("app bundle validation failed: first clean-home bundled pet is not active")
if by_id["pet_bytebudcodex"].get("active") is not False:
raise SystemExit("app bundle validation failed: second clean-home bundled pet unexpectedly became active")
with sqlite3.connect(os.environ["BUNDLED_DB"]) as database:
schema_version = database.execute("PRAGMA user_version").fetchone()[0]
if schema_version != 7:
raise SystemExit(
f"app bundle validation failed: bundled seed changed database schema to {schema_version}, expected 7"
)
PY
for source in codex claude_code pi opencode dsh; do
APC_HOME="$TMP_DIR/home" "$PETCORE_CLI" connections repair --source "$source" >/dev/null
done
INSTALLED_CODEX_PLUGIN="$TMP_DIR/agent-home/.agents/plugins/plugins/agent-pet-companion"
if ! python3 - \
"$SOURCE_CODEX_PLUGIN_MANIFEST" \
"$INSTALLED_CODEX_PLUGIN/.codex-plugin/plugin.json" <<'PY'
import json
import pathlib
import sys
MAX_PLUGIN_MANIFEST_BYTES = 64 * 1024
def reject_duplicate_keys(pairs):
value = {}
for key, item in pairs:
if key in value:
raise ValueError("duplicate JSON object key")
value[key] = item
return value
def load_manifest(raw_path):
path = pathlib.Path(raw_path)
if path.is_symlink() or not path.is_file():
raise ValueError("plugin manifest is not a regular file")
size = path.stat().st_size
if size <= 0 or size > MAX_PLUGIN_MANIFEST_BYTES:
raise ValueError("plugin manifest has an invalid size")
return json.loads(
path.read_text(encoding="utf-8"),
object_pairs_hook=reject_duplicate_keys,
)
try:
source = load_manifest(sys.argv[1])
installed = load_manifest(sys.argv[2])
except (OSError, UnicodeError, ValueError, json.JSONDecodeError):
raise SystemExit(1)
raise SystemExit(0 if source == installed else 1)
PY
then
echo 'app bundle validation failed: packaged PetCore emitted a stale Codex plugin manifest' >&2
exit 1
fi
cmp -s \
"$BUNDLED_SKILL" \
"$INSTALLED_CODEX_PLUGIN/skills/agent-pet-studio/SKILL.md" || {
echo 'app bundle validation failed: packaged PetCore emitted a stale Studio Skill' >&2
exit 1
}
while IFS= read -r -d '' source_path; do
relative_path="${source_path#"$BUNDLED_PORTABLE_SKILL/"}"
cmp -s \
"$source_path" \
"$INSTALLED_CODEX_PLUGIN/skills/agent-pet-maker/$relative_path" || {
printf 'app bundle validation failed: packaged PetCore emitted stale Maker Skill file %s\n' \
"$relative_path" >&2
exit 1
}
done < <(
find "$BUNDLED_PORTABLE_SKILL" \
-type d -name __pycache__ -prune -o \
-type f ! -name '*.pyc' ! -name '*.pyo' -print0
)
grep -qF "$PETCORE_CLI" \
"$INSTALLED_CODEX_PLUGIN/hooks/hooks.json"
CLAUDE_HELPER="$TMP_DIR/home/connectors/claude-code/agent-pet-companion-hook.sh"
grep -qF "$CLAUDE_HELPER" "$TMP_DIR/agent-home/.claude/settings.json"
grep -qF "$PETCORE_CLI" "$CLAUDE_HELPER"
grep -qF "$PETCORE_CLI" "$TMP_DIR/agent-home/.pi/agent/extensions/agent-pet-companion.ts"
grep -qF "$PETCORE_CLI" "$TMP_DIR/agent-home/.config/opencode/plugins/agent-pet-companion.js"
fi
if [[ "$MODE" == "github-release" ]]; then
printf 'GitHub Release App bundle validation ok (%s, ad-hoc signature, %s)\n' \
"$EXPECTED_ARCH" "$RUNTIME_VALIDATION_SCOPE"
elif [[ "$SIGNATURE_PRESENT" == "1" ]]; then
if [[ "$STATIC_ONLY" == "1" ]]; then
echo 'Development app bundle static validation ok (signature present and strictly valid)'
else
echo 'Development app bundle validation ok (signature present and strictly valid)'
fi
else
if [[ "$STATIC_ONLY" == "1" ]]; then
echo 'Development app bundle static validation ok (no outer signature present)'
else
echo 'Development app bundle validation ok (no outer signature present)'
fi
fi