S105 · SOURCE-BOUND GATE EVIDENCE
S101 gerçek kart uyarlaması v1 bağımsız statik auditte reddedildi
S105 statik ret → audited G8h flash helper identity sabitleri Bu sayfa yalnız S105 kapısına aittir; komşu kapıların kaynakları bu kabulün içine katılmaz.
S105Komut / fiziksel sözleşmeOperations id exactsource SHA exact
operation: rpi5-g8h-s101-real-identity-v1-static-rejected
script/Makefile/config · Operations · 2 exact excerpt
sequence-bound=true · implementation-bound=false
01 · Yürütme / doğrulama kodu
Kapının gerçek repository sözleşmesi
tam dosyaL1–L2481
scripts/flash-rpi5-g8h-staged.sh::EXPECTED_IOREG_WHOLE_MEDIA_NAME
#!/bin/sh
# Sequence 101 source contract and separately authorized, write-once G8h card
# transaction. --verify-source-only and --self-test never inspect a device.
set -eu
PATH=/usr/bin:/bin:/usr/sbin:/sbin
export PATH
EXPECTED_PACKAGE_ENTRIES=4
EXPECTED_MANIFEST_ENTRIES=3
EXPECTED_PACKAGE_MODE=755
EXPECTED_FILE_MODE=444
EXPECTED_IMAGE_BYTES=316864
EXPECTED_IMAGE_SHA256=7e4b713a4ba4f45d572b61ca170cf7f5c89f9a4485f839dc12cc5a8c23570de1
EXPECTED_DTB_BYTES=78703
EXPECTED_DTB_SHA256=40a2fbe9c29e8b9a4912cf726a943068defb779fc052ec38e457a79c58abca00
EXPECTED_CONFIG_BYTES=501
EXPECTED_CONFIG_SHA256=1248275cdc6f6ce951ce0ff2183471d194c5b9bb58c3dc3f66efa9156f91d76b
EXPECTED_SUMS_BYTES=248
EXPECTED_SUMS_SHA256=dfc5eaac93367771df1e84be711032592a977f5a2c744e797150b5a0836c1f5f
EXPECTED_PACKAGE_AGGREGATE_BYTES=358
EXPECTED_PACKAGE_AGGREGATE_SHA256=c876c56742d5c38d539438396c93a585e389ff1d6d777aab750247c1746c3417
S89_IMAGE_BYTES=292256
S89_IMAGE_SHA256=985fbe1088566beb1f8a655dba7b06759f088256077446a1d542251f3683c747
S89_DTB_BYTES=78703
S89_DTB_SHA256=40a2fbe9c29e8b9a4912cf726a943068defb779fc052ec38e457a79c58abca00
S89_CONFIG_BYTES=501
S89_CONFIG_SHA256=1248275cdc6f6ce951ce0ff2183471d194c5b9bb58c3dc3f66efa9156f91d76b
S89_SUMS_BYTES=248
S89_SUMS_SHA256=fb112a41f2f55a2355e9a91d58fd2c2e74ad969a6fbf11b0a8ad6956fed3cb7a
EXPECTED_READER_MEDIA_NAME='Built In SDXC Reader'
EXPECTED_IOREG_WHOLE_MEDIA_NAME='Apple SDXC Reader Media'
EXPECTED_SP_READER_NAME=spcardreader
EXPECTED_SP_CARD_NAME='SDXC Card (Class 10)'
EXPECTED_SP_CARD_PRODUCT=TISD64G
EXPECTED_IOREG_CARD_PRODUCT=SD64G
EXPECTED_CARD_SERIAL_HEX=0x425001fa
EXPECTED_CARD_SERIAL_DECIMAL=1112539642
EXPECTED_DISK_BYTES=62549655552
EXPECTED_DEVICE_BLOCK_BYTES=512
EXPECTED_PARTITION_MEDIA_BYTES=62532878336
EXPECTED_DISKUTIL_VOLUME_BYTES=62517608448
EXPECTED_ROOT_WHOLE_DISK=disk3
EXPECTED_VOLUME_NAME=ASELSANBOOT
EXPECTED_VOLUME_UUID=44ABB50F-DB63-3DB8-A6B2-C5303E3211E9
EXPECTED_MOUNT=/Volumes/ASELSANBOOT
EXPECTED_SIDECAR_BYTES=4096
EXPECTED_SIDECAR_SHA256=fa3ce12351d3cd79afab888037a10f4c2570013c858f4d1b51acab2aa117b9a9
EXPECTED_SOURCE_XATTR_NAME=com.apple.provenance
EXPECTED_SOURCE_XATTR_HEX=010200e1a2d743c816d3a8
SIDECAR_FIXTURE_BASE64='AAUWBwACAABNYWMgT1MgWCAgICAgICAgAAIAAAAJAAAAMgAADrAAAAACAAAO4gAAAR4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQVRUUgAAAAAAAA7iAAAAmAAAAAsAAAAAAAAAAAAAAAAAAAABAAAAmAAAAAsAABVjb20uYXBwbGUucHJvdmVuYW5jZQABAgDhotdDyBbTqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAHlRoaXMgcmVzb3VyY2UgZm9yayBpbnRlbnRpb25hbGx5IGxlZnQgYmxhbmsgICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAB4AAAAAAAAAAAAcAB7//w=='
EXPECTED_AUTH=S101_WRITE_G8H_7e4b713a_425001fa_62549655552
LOCK_BASENAME=aselsanos-s101-g8h-425001fa-7e4b713a.lock
S101_LOCK_DIR=
fail() {
printf 'S101 HATA: %s\n' "$*" >&2
if [ -n "${S101_LOCK_DIR:-}" ]; then
printf 'S101_LOCK=%s RETAINED=YES REVIEW_REQUIRED=YES\n' "$S101_LOCK_DIR" >&2
if [ "${S101_TRANSACTION_SUCCESS:-0}" != 1 ]; then
printf 'NEVER_BOOT=YES RERUN_FORBIDDEN=YES AUTO_ROLLBACK=NO\n' >&2
printf 'RECOVERY_AUTH=REQUIRED HOST_JOURNAL_CRASH_DURABILITY=NOT_CLAIMED\n' >&2
fi
fi
exit 1
}
already_applied() {
printf 'S101 ALREADY_APPLIED: frozen S100 exact4 already present; WRITE=0\n' >&2
exit 3
}
sha256_file() {
shasum -a 256 "$1" | awk '{ print $1; exit }'
}
file_bytes() {
wc -c < "$1" | tr -d '[:space:]'
}
file_mode() {
if stat -f '%Lp' "$1" >/dev/null 2>&1; then
stat -f '%Lp' "$1"
else
stat -c '%a' "$1"
fi
}
file_nlink() {
if stat -f '%l' "$1" >/dev/null 2>&1; then
stat -f '%l' "$1"
else
stat -c '%h' "$1"
fi
}
file_dev_inode() {
if stat -f '%d:%i' "$1" >/dev/null 2>&1; then
stat -f '%d:%i' "$1"
else
stat -c '%d:%i' "$1"
fi
}
file_birth_mtime_ctime() {
if stat -f '%B:%m:%c' "$1" >/dev/null 2>&1; then
stat -f '%B:%m:%c' "$1"
else
stat -c '%W:%Y:%Z' "$1"
fi
}
package_metadata_snapshot() {
package=$1
[ -d "$package" ] && [ ! -L "$package" ] || fail "snapshot package directory missing"
printf 'ROOT %s %s %s %s\n' \
"$(file_dev_inode "$package")" "$(file_nlink "$package")" \
"$(file_mode "$package")" "$(file_birth_mtime_ctime "$package")"
for name in SHA256SUMS aselsanos-rpi5.img bcm2712-rpi-5-b.dtb config.txt; do
path="$package/$name"
require_regular "$path"
printf '%s %s %s %s %s %s %s\n' \
"$name" "$(file_dev_inode "$path")" "$(file_nlink "$path")" \
"$(file_mode "$path")" "$(file_bytes "$path")" \
"$(sha256_file "$path")" "$(file_birth_mtime_ctime "$path")"
source_xattr_snapshot "$path"
done
}
source_xattr_snapshot() {
xattr_path=$1
xattr_names=$(/usr/bin/xattr "$xattr_path") || fail "frozen source xattr names unreadable: $xattr_path"
[ "$xattr_names" = "$EXPECTED_SOURCE_XATTR_NAME" ] ||
fail "frozen source xattr name-set mismatch: $xattr_path"
xattr_hex=$(/usr/bin/xattr -px "$EXPECTED_SOURCE_XATTR_NAME" "$xattr_path" |
tr -d '[:space:]' | tr '[:upper:]' '[:lower:]') ||
fail "frozen source provenance xattr unreadable: $xattr_path"
[ "$xattr_hex" = "$EXPECTED_SOURCE_XATTR_HEX" ] ||
fail "frozen source provenance xattr mismatch: $xattr_path"
printf 'XATTR %s %s\n' "$xattr_names" "$xattr_hex"
}
validate_frozen_source_xattrs() {
xattr_package=$1
for xattr_name in SHA256SUMS aselsanos-rpi5.img bcm2712-rpi-5-b.dtb config.txt; do
source_xattr_snapshot "$xattr_package/$xattr_name" >/dev/null
done
}
assert_selftest_source_unchanged() {
[ -n "${SELFTEST_CANONICAL:-}" ] || fail "self-test canonical source unset"
[ -n "${SELFTEST_RECOVERY:-}" ] || fail "self-test recovery source unset"
if ! current_snapshot=$(package_metadata_snapshot "$SELFTEST_CANONICAL"); then
fail "frozen S100 package metadata unreadable during self-test"
fi
[ "$current_snapshot" = "$SELFTEST_CANONICAL_SNAPSHOT" ] ||
fail "frozen S100 package metadata changed during self-test"
if ! current_recovery_snapshot=$(package_metadata_snapshot "$SELFTEST_RECOVERY"); then
fail "frozen S89 recovery metadata unreadable during self-test"
fi
[ "$current_recovery_snapshot" = "$SELFTEST_RECOVERY_SNAPSHOT" ] ||
fail "frozen S89 recovery metadata changed during self-test"
}
selftest_exit_guard() {
guard_status=$1
trap - 0 1 2 15
if [ "${SELFTEST_GUARD_ACTIVE:-0}" = 1 ]; then
if ! current_snapshot=$(package_metadata_snapshot "$SELFTEST_CANONICAL"); then
printf 'S101 INCIDENT GUARD: frozen S100 package metadata unreadable\n' >&2
exit 1
fi
if [ "$current_snapshot" != "$SELFTEST_CANONICAL_SNAPSHOT" ]; then
printf 'S101 INCIDENT GUARD: frozen S100 package metadata changed\n' >&2
exit 1
fi
if ! current_recovery_snapshot=$(package_metadata_snapshot "$SELFTEST_RECOVERY"); then
printf 'S101 INCIDENT GUARD: frozen S89 recovery metadata unreadable\n' >&2
exit 1
fi
if [ "$current_recovery_snapshot" != "$SELFTEST_RECOVERY_SNAPSHOT" ]; then
printf 'S101 INCIDENT GUARD: frozen S89 recovery metadata changed\n' >&2
exit 1
fi
fi
exit "$guard_status"
}
begin_selftest_fixture() {
assert_selftest_source_unchanged
SELFTEST_TOTAL=$((SELFTEST_TOTAL + 1))
}
require_regular() {
[ -f "$1" ] || fail "regular file missing: $1"
[ ! -L "$1" ] || fail "symlink forbidden: $1"
}
require_exact_file() {
path=$1
bytes=$2
digest=$3
label=$4
require_regular "$path"
[ "$(file_nlink "$path")" -eq 1 ] || fail "$label hardlink forbidden"
[ "$(file_bytes "$path")" -eq "$bytes" ] || fail "$label byte count mismatch"
[ "$(sha256_file "$path")" = "$digest" ] || fail "$label SHA256 mismatch"
}
require_distinct_inodes() {
count=$(for path in "$@"; do file_dev_inode "$path"; done |
LC_ALL=C sort -u | wc -l | tr -d '[:space:]')
[ "$count" -eq "$#" ] || fail "package hardlink/duplicate inode"
}
validate_manifest_shape() {
manifest=$1
[ "$(wc -l < "$manifest" | tr -d '[:space:]')" -eq "$EXPECTED_MANIFEST_ENTRIES" ] ||
fail "manifest exact3 mismatch"
[ "$(tail -c 1 "$manifest" | od -An -tu1 | tr -d '[:space:]')" = 10 ] ||
fail "manifest final LF missing"
awk '
NF != 2 || length($1) != 64 || $1 !~ /^[0-9a-f]+$/ ||
substr($0, 65, 2) != " " || length($0) != 66 + length($2) { bad = 1 }
$2 == "aselsanos-rpi5.img" { image++ }
$2 == "bcm2712-rpi-5-b.dtb" { dtb++ }
$2 == "config.txt" { config++ }
$2 !~ /^(aselsanos-rpi5[.]img|bcm2712-rpi-5-b[.]dtb|config[.]txt)$/ { bad = 1 }
$2 ~ /\// || $2 ~ /^\./ || $2 ~ /\.\./ { bad = 1 }
END { if (image != 1 || dtb != 1 || config != 1) bad = 1; exit bad }
' "$manifest" || fail "manifest path/checksum grammar mismatch"
}
marker_count() {
LC_ALL=C strings "$1" | grep -Fo -- "$2" | wc -l | tr -d '[:space:]'
}
validate_markers() {
image=$1
for marker in \
ASELSAN/G8H0 ASELSAN/G8H1 ASELSAN/G8H2 ASELSAN/G8H3 \
ASELSAN/G8H4 ASELSAN/BOOT8H; do
[ "$(marker_count "$image" "$marker")" -eq 1 ] ||
fail "success marker exact-once mismatch: $marker"
done
[ "$(marker_count "$image" ASELSAN/G8HERR)" -eq 0 ] ||
fail "G8HERR forbidden"
counterfeit=$(LC_ALL=C strings "$image" |
grep -Eo 'ASELSAN/G8H[0-4][0-9]|ASELSAN/BOOT8H[0-9]' |
wc -l | tr -d '[:space:]')
[ "$counterfeit" -eq 0 ] || fail "success marker prefix counterfeit"
}
package_aggregate() {
package=$1
for name in SHA256SUMS aselsanos-rpi5.img bcm2712-rpi-5-b.dtb config.txt; do
path="$package/$name"
printf '%s %s %s %s\n' \
"$(file_mode "$path")" "$(file_bytes "$path")" \
"$(sha256_file "$path")" "$name"
done
}
validate_package_generic() {
package=$1
[ -d "$package" ] && [ ! -L "$package" ] || fail "package must be a non-symlink directory"
[ "$(file_mode "$package")" = "$EXPECTED_PACKAGE_MODE" ] ||
fail "package directory mode must be 0755"
entries=$(find "$package" -mindepth 1 -maxdepth 1 -print | wc -l | tr -d '[:space:]')
[ "$entries" -eq "$EXPECTED_PACKAGE_ENTRIES" ] || fail "package exact4 mismatch"
image="$package/aselsanos-rpi5.img"
dtb="$package/bcm2712-rpi-5-b.dtb"
config="$package/config.txt"
sums="$package/SHA256SUMS"
require_exact_file "$image" "$EXPECTED_IMAGE_BYTES" "$EXPECTED_IMAGE_SHA256" image
require_exact_file "$dtb" "$EXPECTED_DTB_BYTES" "$EXPECTED_DTB_SHA256" DTB
require_exact_file "$config" "$EXPECTED_CONFIG_BYTES" "$EXPECTED_CONFIG_SHA256" config
require_exact_file "$sums" "$EXPECTED_SUMS_BYTES" "$EXPECTED_SUMS_SHA256" SHA256SUMS
for path in "$sums" "$image" "$dtb" "$config"; do
[ "$(file_mode "$path")" = "$EXPECTED_FILE_MODE" ] ||
fail "package file mode must be 0444: $(basename "$path")"
done
require_distinct_inodes "$sums" "$image" "$dtb" "$config"
validate_manifest_shape "$sums"
(cd "$package" && shasum -a 256 -c SHA256SUMS >/dev/null) ||
fail "package manifest checksum mismatch"
validate_markers "$image"
aggregate_bytes=$(package_aggregate "$package" | wc -c | tr -d '[:space:]')
aggregate_sha=$(package_aggregate "$package" | shasum -a 256 | awk '{ print $1; exit }')
[ "$aggregate_bytes" -eq "$EXPECTED_PACKAGE_AGGREGATE_BYTES" ] ||
fail "package aggregate byte count mismatch"
[ "$aggregate_sha" = "$EXPECTED_PACKAGE_AGGREGATE_SHA256" ] ||
fail "package aggregate SHA256 mismatch"
}
validate_s89_recovery_package() {
recovery=$1
[ -d "$recovery" ] && [ ! -L "$recovery" ] || fail "S89 recovery must be a non-symlink directory"
[ "$(file_mode "$recovery")" = "$EXPECTED_PACKAGE_MODE" ] || fail "S89 recovery directory mode must be 0755"
entries=$(find "$recovery" -mindepth 1 -maxdepth 1 -print | wc -l | tr -d '[:space:]')
[ "$entries" -eq "$EXPECTED_PACKAGE_ENTRIES" ] || fail "S89 recovery exact4 mismatch"
image="$recovery/aselsanos-rpi5.img"
dtb="$recovery/bcm2712-rpi-5-b.dtb"
config="$recovery/config.txt"
sums="$recovery/SHA256SUMS"
require_exact_file "$image" "$S89_IMAGE_BYTES" "$S89_IMAGE_SHA256" 'S89 recovery image'
require_exact_file "$dtb" "$S89_DTB_BYTES" "$S89_DTB_SHA256" 'S89 recovery DTB'
require_exact_file "$config" "$S89_CONFIG_BYTES" "$S89_CONFIG_SHA256" 'S89 recovery config'
require_exact_file "$sums" "$S89_SUMS_BYTES" "$S89_SUMS_SHA256" 'S89 recovery SHA256SUMS'
for path in "$sums" "$image" "$dtb" "$config"; do
[ "$(file_mode "$path")" = "$EXPECTED_FILE_MODE" ] || fail "S89 recovery file mode must be 0444: $(basename "$path")"
done
require_distinct_inodes "$sums" "$image" "$dtb" "$config"
validate_manifest_shape "$sums"
(cd "$recovery" && shasum -a 256 -c SHA256SUMS >/dev/null) || fail "S89 recovery manifest checksum mismatch"
}
resolve_frozen_s89_recovery() {
recovery_script_dir=$(CDPATH= cd "$(dirname "$0")" && pwd -P) || fail "S89 recovery script directory unresolved"
expected_recovery=$(CDPATH= cd "$recovery_script_dir/../evidence/rpi5/g8g/sequence-89-package-staged/package" && pwd -P) ||
fail "canonical S89 recovery package unresolved"
[ -d "$expected_recovery" ] && [ ! -L "$expected_recovery" ] || fail "canonical S89 recovery path mismatch"
RECOVERY_ROOT=$expected_recovery
validate_s89_recovery_package "$RECOVERY_ROOT"
validate_frozen_source_xattrs "$RECOVERY_ROOT"
}
require_frozen_source_entry() {
name=$1
case "$name" in
aselsanos-rpi5.img)
bytes=$EXPECTED_IMAGE_BYTES
digest=$EXPECTED_IMAGE_SHA256
;;
bcm2712-rpi-5-b.dtb)
bytes=$EXPECTED_DTB_BYTES
digest=$EXPECTED_DTB_SHA256
;;
config.txt)
bytes=$EXPECTED_CONFIG_BYTES
digest=$EXPECTED_CONFIG_SHA256
;;
SHA256SUMS)
bytes=$EXPECTED_SUMS_BYTES
digest=$EXPECTED_SUMS_SHA256
;;
*) fail "unknown frozen source entry: $name" ;;
esac
if [ "${S101_FAKE_MODE:-0}" = 1 ] && [ -n "${S101_FAKE_SOURCE_VIEW:-}" ]; then
FROZEN_SOURCE_PATH="$S101_FAKE_SOURCE_VIEW/$name"
else
FROZEN_SOURCE_PATH="$PACKAGE_ROOT/$name"
fi
require_exact_file "$FROZEN_SOURCE_PATH" "$bytes" "$digest" "source $name"
[ "$(file_mode "$FROZEN_SOURCE_PATH")" = "$EXPECTED_FILE_MODE" ] ||
fail "source mode changed before copy: $name"
}
require_exact_temp_entry() {
name=$1
case "$name" in
aselsanos-rpi5.img)
bytes=$EXPECTED_IMAGE_BYTES
digest=$EXPECTED_IMAGE_SHA256
;;
bcm2712-rpi-5-b.dtb)
bytes=$EXPECTED_DTB_BYTES
digest=$EXPECTED_DTB_SHA256
;;
config.txt)
bytes=$EXPECTED_CONFIG_BYTES
digest=$EXPECTED_CONFIG_SHA256
;;
SHA256SUMS)
bytes=$EXPECTED_SUMS_BYTES
digest=$EXPECTED_SUMS_SHA256
;;
*) fail "unknown staged temp entry: $name" ;;
esac
require_exact_file "$(temp_path "$name")" "$bytes" "$digest" "temp $name"
}
validate_temp_payloads() {
temp_sums=$(temp_path SHA256SUMS)
temp_image=$(temp_path aselsanos-rpi5.img)
temp_dtb=$(temp_path bcm2712-rpi-5-b.dtb)
temp_config=$(temp_path config.txt)
for name in aselsanos-rpi5.img bcm2712-rpi-5-b.dtb config.txt SHA256SUMS; do
require_exact_temp_entry "$name"
done
require_distinct_inodes "$temp_sums" "$temp_image" "$temp_dtb" "$temp_config"
validate_manifest_shape "$temp_sums"
for name in aselsanos-rpi5.img bcm2712-rpi-5-b.dtb config.txt; do
recorded=$(awk -v wanted="$name" '$2 == wanted { print $1; found++ } END { if (found != 1) exit 1 }' "$temp_sums") ||
fail "staged temp manifest record mismatch: $name"
[ "$recorded" = "$(sha256_file "$(temp_path "$name")")" ] ||
fail "staged temp manifest checksum mismatch: $name"
done
validate_markers "$temp_image"
}
resolve_frozen_package() {
argument=$1
[ -f "$0" ] && [ ! -L "$0" ] || fail "helper entrypoint must be a regular non-symlink file"
script_dir=$(CDPATH= cd "$(dirname "$0")" && pwd -P) || fail "script directory unresolved"
script_entry="$script_dir/$(basename "$0")"
[ -f "$script_entry" ] && [ ! -L "$script_entry" ] ||
fail "helper entrypoint physical path mismatch"
expected=$(CDPATH= cd "$script_dir/../evidence/rpi5/g8h/sequence-100-package-staged/package" && pwd -P) ||
fail "canonical S100 package unresolved"
[ -d "$argument" ] && [ ! -L "$argument" ] || fail "source package must be a non-symlink directory"
actual=$(CDPATH= cd "$argument" && pwd -P) || fail "source package unresolved"
[ "$actual" = "$expected" ] || fail "alternate source package forbidden"
PACKAGE_ROOT=$actual
validate_package_generic "$PACKAGE_ROOT"
validate_frozen_source_xattrs "$PACKAGE_ROOT"
}
exact_file_matches() {
path=$1
bytes=$2
digest=$3
[ -f "$path" ] && [ ! -L "$path" ] &&
[ "$(file_bytes "$path")" -eq "$bytes" ] &&
[ "$(sha256_file "$path")" = "$digest" ]
}
temp_path() {
printf '%s/.aselsanos-s101-%s.tmp' "$SD_MOUNT" "$1"
}
temp_appledouble_path() {
printf '%s/._.aselsanos-s101-%s.tmp' "$SD_MOUNT" "$1"
}
exact_appledouble_matches() {
appledouble_path=$1
[ -f "$appledouble_path" ] && [ ! -L "$appledouble_path" ] &&
[ "$(file_nlink "$appledouble_path")" -eq 1 ] &&
[ "$(file_bytes "$appledouble_path")" -eq "$EXPECTED_SIDECAR_BYTES" ] &&
[ "$(sha256_file "$appledouble_path")" = "$EXPECTED_SIDECAR_SHA256" ]
}
card_inventory() {
find "$SD_MOUNT" -mindepth 1 -maxdepth 1 -print |
while IFS= read -r path; do basename "$path"; done | LC_ALL=C sort
}
metadata_namespace_matches() {
for metadata_sidecar_name in ._SHA256SUMS ._aselsanos-rpi5.img ._bcm2712-rpi-5-b.dtb ._config.txt; do
exact_appledouble_matches "$SD_MOUNT/$metadata_sidecar_name" || return 1
done
for metadata_dir_name in .Spotlight-V100 .fseventsd; do
metadata_path="$SD_MOUNT/$metadata_dir_name"
[ -d "$metadata_path" ] && [ ! -L "$metadata_path" ] || return 1
done
}
require_metadata_namespace() {
metadata_namespace_matches || fail "exact opaque metadata6 namespace mismatch"
}
exact_temp_appledouble_matches() {
exact_appledouble_matches "$(temp_appledouble_path "$1")"
}
require_exact_temp_appledouble() {
exact_temp_appledouble_matches "$1" || fail "staged temp AppleDouble mismatch: $1"
}
exact_final_appledouble_matches() {
exact_appledouble_matches "$SD_MOUNT/._$1"
}
base_card_inventory() {
printf '%s\n' \
.Spotlight-V100 \
._SHA256SUMS \
._aselsanos-rpi5.img \
._bcm2712-rpi-5-b.dtb \
._config.txt \
.fseventsd \
SHA256SUMS \
aselsanos-rpi5.img \
bcm2712-rpi-5-b.dtb \
config.txt
}
commit_prefix_inventory() {
prefix_inventory_committed=$1
case "$prefix_inventory_committed" in
0|1|2|3|4) ;;
*) fail "invalid commit prefix: $prefix_inventory_committed" ;;
esac
{
base_card_inventory
inventory_index=0
for inventory_name in aselsanos-rpi5.img bcm2712-rpi-5-b.dtb config.txt SHA256SUMS; do
inventory_index=$((inventory_index + 1))
if [ "$inventory_index" -gt "$prefix_inventory_committed" ]; then
basename "$(temp_path "$inventory_name")"
basename "$(temp_appledouble_path "$inventory_name")"
fi
done
} | LC_ALL=C sort
}
prepared_card_inventory() {
commit_prefix_inventory 0
}
classify_core_payload() {
for core_name in SHA256SUMS aselsanos-rpi5.img bcm2712-rpi-5-b.dtb config.txt; do
core_path="$SD_MOUNT/$core_name"
[ -f "$core_path" ] && [ ! -L "$core_path" ] || { printf 'MIXED\n'; return; }
done
if exact_file_matches "$SD_MOUNT/aselsanos-rpi5.img" "$S89_IMAGE_BYTES" "$S89_IMAGE_SHA256" &&
exact_file_matches "$SD_MOUNT/bcm2712-rpi-5-b.dtb" "$S89_DTB_BYTES" "$S89_DTB_SHA256" &&
exact_file_matches "$SD_MOUNT/config.txt" "$S89_CONFIG_BYTES" "$S89_CONFIG_SHA256" &&
exact_file_matches "$SD_MOUNT/SHA256SUMS" "$S89_SUMS_BYTES" "$S89_SUMS_SHA256"; then
printf 'S89\n'
return
fi
if exact_file_matches "$SD_MOUNT/aselsanos-rpi5.img" "$EXPECTED_IMAGE_BYTES" "$EXPECTED_IMAGE_SHA256" &&
exact_file_matches "$SD_MOUNT/bcm2712-rpi-5-b.dtb" "$EXPECTED_DTB_BYTES" "$EXPECTED_DTB_SHA256" &&
exact_file_matches "$SD_MOUNT/config.txt" "$EXPECTED_CONFIG_BYTES" "$EXPECTED_CONFIG_SHA256" &&
exact_file_matches "$SD_MOUNT/SHA256SUMS" "$EXPECTED_SUMS_BYTES" "$EXPECTED_SUMS_SHA256"; then
printf 'S100\n'
return
fi
printf 'MIXED\n'
}
exact_temp_matches() {
temp_match_name=$1
case "$temp_match_name" in
aselsanos-rpi5.img) bytes=$EXPECTED_IMAGE_BYTES; digest=$EXPECTED_IMAGE_SHA256 ;;
bcm2712-rpi-5-b.dtb) bytes=$EXPECTED_DTB_BYTES; digest=$EXPECTED_DTB_SHA256 ;;
config.txt) bytes=$EXPECTED_CONFIG_BYTES; digest=$EXPECTED_CONFIG_SHA256 ;;
SHA256SUMS) bytes=$EXPECTED_SUMS_BYTES; digest=$EXPECTED_SUMS_SHA256 ;;
*) return 1 ;;
esac
exact_file_matches "$(temp_path "$temp_match_name")" "$bytes" "$digest"
}
exact_s89_final_matches() {
s89_final_name=$1
case "$s89_final_name" in
aselsanos-rpi5.img) bytes=$S89_IMAGE_BYTES; digest=$S89_IMAGE_SHA256 ;;
bcm2712-rpi-5-b.dtb) bytes=$S89_DTB_BYTES; digest=$S89_DTB_SHA256 ;;
config.txt) bytes=$S89_CONFIG_BYTES; digest=$S89_CONFIG_SHA256 ;;
SHA256SUMS) bytes=$S89_SUMS_BYTES; digest=$S89_SUMS_SHA256 ;;
*) return 1 ;;
esac
exact_file_matches "$SD_MOUNT/$s89_final_name" "$bytes" "$digest"
}
exact_s100_final_matches() {
s100_final_name=$1
case "$s100_final_name" in
aselsanos-rpi5.img) bytes=$EXPECTED_IMAGE_BYTES; digest=$EXPECTED_IMAGE_SHA256 ;;
bcm2712-rpi-5-b.dtb) bytes=$EXPECTED_DTB_BYTES; digest=$EXPECTED_DTB_SHA256 ;;
config.txt) bytes=$EXPECTED_CONFIG_BYTES; digest=$EXPECTED_CONFIG_SHA256 ;;
SHA256SUMS) bytes=$EXPECTED_SUMS_BYTES; digest=$EXPECTED_SUMS_SHA256 ;;
*) return 1 ;;
esac
exact_file_matches "$SD_MOUNT/$s100_final_name" "$bytes" "$digest"
}
require_commit_prefix_state() {
prefix_committed=$1
case "$prefix_committed" in
0|1|2|3|4) ;;
*) fail "invalid commit prefix state: $prefix_committed" ;;
esac
prefix_actual=$(card_inventory)
prefix_expected=$(commit_prefix_inventory "$prefix_committed")
[ "$prefix_actual" = "$prefix_expected" ] || fail "commit prefix inventory mismatch at $prefix_committed"
require_metadata_namespace
prefix_state_index=0
for prefix_name in aselsanos-rpi5.img bcm2712-rpi-5-b.dtb config.txt SHA256SUMS; do
prefix_state_index=$((prefix_state_index + 1))
exact_final_appledouble_matches "$prefix_name" ||
fail "final AppleDouble mismatch at commit prefix $prefix_committed: $prefix_name"
if [ "$prefix_state_index" -le "$prefix_committed" ]; then
exact_s100_final_matches "$prefix_name" ||
fail "committed final is not exact S100 at prefix $prefix_committed: $prefix_name"
prefix_temp=$(temp_path "$prefix_name")
prefix_sidecar=$(temp_appledouble_path "$prefix_name")
[ ! -e "$prefix_temp" ] && [ ! -L "$prefix_temp" ] ||
fail "committed temp data remains at prefix $prefix_committed: $prefix_name"
[ ! -e "$prefix_sidecar" ] && [ ! -L "$prefix_sidecar" ] ||
fail "committed temp AppleDouble remains at prefix $prefix_committed: $prefix_name"
else
exact_s89_final_matches "$prefix_name" ||
fail "uncommitted final is not exact S89 at prefix $prefix_committed: $prefix_name"
require_exact_temp_entry "$prefix_name"
require_exact_temp_appledouble "$prefix_name"
fi
done
}
classify_card_state() {
card_actual=$(card_inventory)
if [ "$card_actual" = "$(base_card_inventory)" ]; then
metadata_namespace_matches || { printf 'MIXED\n'; return; }
case "$(classify_core_payload)" in
S89) printf 'S89_META\n'; return ;;
S100) printf 'S100_META\n'; return ;;
esac
elif [ "$card_actual" = "$(prepared_card_inventory)" ]; then
metadata_namespace_matches || { printf 'MIXED\n'; return; }
[ "$(classify_core_payload)" = S89 ] || { printf 'MIXED\n'; return; }
for prepared_name in SHA256SUMS aselsanos-rpi5.img bcm2712-rpi-5-b.dtb config.txt; do
exact_temp_matches "$prepared_name" || { printf 'MIXED\n'; return; }
exact_temp_appledouble_matches "$prepared_name" || { printf 'MIXED\n'; return; }
done
printf 'PREPARED\n'
return
fi
printf 'MIXED\n'
}
configure_real_tools() {
DISKUTIL=/usr/sbin/diskutil
PLUTIL=/usr/bin/plutil
IOREG=/usr/sbin/ioreg
SYSTEM_PROFILER=/usr/sbin/system_profiler
COPY_TOOL=/bin/cp
MOVE_TOOL=/bin/mv
COMPARE_TOOL=/usr/bin/cmp
SYNC_TOOL=/bin/sync
S101_LOCK_PARENT=/private/tmp
}
configure_fake_tools() {
fake_root=$1
DISKUTIL="$fake_root/bin/diskutil"
PLUTIL="$fake_root/bin/plutil"
IOREG="$fake_root/bin/ioreg"
SYSTEM_PROFILER="$fake_root/bin/system_profiler"
COPY_TOOL="$fake_root/bin/cp"
MOVE_TOOL="$fake_root/bin/mv"
COMPARE_TOOL="$fake_root/bin/cmp"
SYNC_TOOL="$fake_root/bin/sync"
S101_LOCK_PARENT="$fake_root/locks"
}
plist_snapshot_value() {
snapshot=$1
key=$2
type=$3
label=$4
printf '%s\n' "$snapshot" |
"$PLUTIL" -extract "$key" raw -expect "$type" -o - - 2>/dev/null ||
fail "missing or mistyped identity field $key for $label"
}
sp_snapshot_value() {
snapshot=$1
key=$2
type=$3
label=$4
printf '%s\n' "$snapshot" |
"$PLUTIL" -extract "$key" raw -expect "$type" -o - - 2>/dev/null ||
fail "missing or mistyped system_profiler field $key for $label"
}
sp_require_exact_one_dictionary() {
surface=$1
array_path=$2
label=$3
printf '%s\n' "$surface" |
"$PLUTIL" -extract "$array_path" xml1 -expect array -o - - >/dev/null 2>&1 ||
fail "system_profiler $label is not a typed array"
printf '%s\n' "$surface" |
"$PLUTIL" -extract "$array_path.0" xml1 -expect dictionary -o - - >/dev/null 2>&1 ||
fail "system_profiler $label item 0 is not a dictionary"
if printf '%s\n' "$surface" |
"$PLUTIL" -extract "$array_path.1" xml1 -o - - >/dev/null 2>&1; then
fail "system_profiler $label cardinality is not exact1"
fi
}
sp_require_root_array() {
surface=$1
normalized_sp=$(printf '%s\n' "$surface" |
"$PLUTIL" -convert xml1 -o - - 2>/dev/null) ||
fail "system_profiler root plist conversion failed"
printf '%s\n' "$normalized_sp" | awk '
{
line = $0
sub(/^[[:space:]]*/, "", line)
sub(/[[:space:]]*$/, "", line)
if (line == "" || line ~ /^<\?xml/ || line ~ /^<!DOCTYPE/ ||
line ~ /^<plist([[:space:]>])/) next
if (!seen) {
seen = 1
if (line == "<array>") root_array = 1
}
}
END { if (seen != 1 || root_array != 1) exit 1 }
' || fail "system_profiler root is not an explicit typed array"
}
require_system_profiler_binding() {
surface=$1
sp_require_root_array "$surface"
printf '%s\n' "$surface" |
"$PLUTIL" -extract 0 xml1 -expect dictionary -o - - >/dev/null 2>&1 ||
fail "system_profiler top-level item 0 missing"
if printf '%s\n' "$surface" |
"$PLUTIL" -extract 1 xml1 -o - - >/dev/null 2>&1; then
fail "system_profiler top-level cardinality is not exact1"
fi
sp_require_exact_one_dictionary "$surface" 0._items reader-list
[ "$(sp_snapshot_value "$surface" 0._items.0._name string reader)" = "$EXPECTED_SP_READER_NAME" ] ||
fail "system_profiler reader name mismatch"
sp_require_exact_one_dictionary "$surface" 0._items.0._items card-list
card=0._items.0._items.0
[ "$(sp_snapshot_value "$surface" "$card._name" string card)" = "$EXPECTED_SP_CARD_NAME" ] || fail "system_profiler card name mismatch"
[ "$(sp_snapshot_value "$surface" "$card.bsd_name" string card)" = "${SD_DISK#/dev/}" ] || fail "system_profiler card BSD mismatch"
[ "$(sp_snapshot_value "$surface" "$card.partition_map_type" string card)" = master_boot_record_partition_map_type ] || fail "system_profiler card partition map mismatch"
[ "$(sp_snapshot_value "$surface" "$card.removable_media" string card)" = yes ] || fail "system_profiler card is not removable"
[ "$(sp_snapshot_value "$surface" "$card.size_in_bytes" integer card)" = "$EXPECTED_DISK_BYTES" ] || fail "system_profiler card size mismatch"
[ "$(sp_snapshot_value "$surface" "$card.smart_status" string card)" = Verified ] || fail "system_profiler SMART mismatch"
[ "$(sp_snapshot_value "$surface" "$card.spcardreader_card_manufacturer-id" string card)" = 0x9f ] || fail "system_profiler manufacturer mismatch"
[ "$(sp_snapshot_value "$surface" "$card.spcardreader_card_manufacturing_date" string card)" = 2026-01 ] || fail "system_profiler manufacturing date mismatch"
[ "$(sp_snapshot_value "$surface" "$card.spcardreader_card_productname" string card)" = "$EXPECTED_SP_CARD_PRODUCT" ] || fail "system_profiler card product mismatch"
[ "$(sp_snapshot_value "$surface" "$card.spcardreader_card_productrevision" string card)" = 6.1 ] || fail "system_profiler card revision mismatch"
[ "$(sp_snapshot_value "$surface" "$card.spcardreader_card_serialnumber" string card)" = "$EXPECTED_CARD_SERIAL_HEX" ] || fail "system_profiler card serial mismatch"
[ "$(sp_snapshot_value "$surface" "$card.spcardreader_card_specversion" string card)" = 3.0 ] || fail "system_profiler card specification mismatch"
sp_require_exact_one_dictionary "$surface" "$card.volumes" volume-list
volume=$card.volumes.0
[ "$(sp_snapshot_value "$surface" "$volume._name" string volume)" = "$EXPECTED_VOLUME_NAME" ] || fail "system_profiler volume name mismatch"
[ "$(sp_snapshot_value "$surface" "$volume.bsd_name" string volume)" = "${SD_DISK#/dev/}s1" ] || fail "system_profiler volume BSD mismatch"
[ "$(sp_snapshot_value "$surface" "$volume.file_system" string volume)" = 'MS-DOS FAT32' ] || fail "system_profiler volume filesystem mismatch"
[ "$(sp_snapshot_value "$surface" "$volume.iocontent" string volume)" = DOS_FAT_32 ] || fail "system_profiler volume content mismatch"
[ "$(sp_snapshot_value "$surface" "$volume.mount_point" string volume)" = "$SD_MOUNT" ] || fail "system_profiler volume mount mismatch"
[ "$(sp_snapshot_value "$surface" "$volume.size_in_bytes" integer volume)" = "$EXPECTED_PARTITION_MEDIA_BYTES" ] || fail "system_profiler volume media size mismatch"
[ "$(sp_snapshot_value "$surface" "$volume.volume_uuid" string volume)" = "$EXPECTED_VOLUME_UUID" ] || fail "system_profiler volume UUID mismatch"
[ "$(sp_snapshot_value "$surface" "$volume.writable" string volume)" = yes ] || fail "system_profiler volume is not writable"
}
require_unique_ioreg_binding() {
surface=$1
printf '%s\n' "$surface" | awk \
-v serial="$EXPECTED_CARD_SERIAL_DECIMAL" \
-v product="$EXPECTED_IOREG_CARD_PRODUCT" \
-v disk="${SD_DISK#/dev/}" \
-v unit="$disk_suffix" \
-v bytes="$EXPECTED_DISK_BYTES" \
-v whole_name="$EXPECTED_IOREG_WHOLE_MEDIA_NAME" '
function cells_ok(s, i, cell) {
if (length(s) % 2 != 0) return 0
for (i = 1; i <= length(s); i += 2) {
cell = substr(s, i, 2)
if (cell != " " && cell != "| ") return 0
}
return 1
}
function literal_count(s, wanted, n, at) {
n = 0
while ((at = index(s, wanted)) != 0) {
n++
s = substr(s, at + length(wanted))
}
return n
}
/^[| ]*[+]-o / {
marker = index($0, "+-o ")
prefix = substr($0, 1, marker - 1)
if (!cells_ok(prefix)) { bad++; next }
depth_now = length(prefix) / 2
if (depth_now > 0 && !(depth_now - 1 in stack)) { bad++; next }
object++
depth[object] = depth_now
parent[object] = depth_now == 0 ? 0 : stack[depth_now - 1]
if (depth_now == 0) root_objects++
for (d = depth_now; d <= max_depth; d++) delete stack[d]
stack[depth_now] = object
if (depth_now > max_depth) max_depth = depth_now
header = substr($0, marker + 4)
class_at = index(header, " <class ")
if (class_at == 0) { bad++; next }
name[object] = substr(header, 1, class_at - 1)
class_text = substr(header, class_at + 9)
sub(/[,>].*$/, "", class_text)
class[object] = class_text
current = object
next
}
{
if (current == 0) next
first_quote = index($0, "\"")
if (first_quote == 0) next
property_prefix = substr($0, 1, first_quote - 1)
if (length(property_prefix) != 2 * depth[current] + 6) { bad++; next }
if (!cells_ok(property_prefix)) { bad++; next }
after_quote = substr($0, first_quote + 1)
second_quote = index(after_quote, "\"")
if (second_quote == 0) { bad++; next }
key = substr(after_quote, 1, second_quote - 1)
tail = substr(after_quote, second_quote + 1)
if (!match(tail, /^[[:space:]]*=[[:space:]]*/)) { bad++; next }
value = substr(tail, RLENGTH + 1)
sub(/[[:space:]]*$/, "", value)
slot = current SUBSEP key
property_count[slot]++
property_value[slot] = value
}
END {
for (i = 1; i <= object; i++) {
if (depth[i] == 0 && name[i] == "AppleSDXC" && class[i] == "AppleSDXC") {
root_node[i] = 1
roots++
}
if (name[i] == "Port-SD Card@1") {
card_nodes++
chars = property_value[i SUBSEP "Card Characteristics"]
if (class[i] == "AppleSDXCSlot" &&
property_count[i SUBSEP "Card Characteristics"] == 1 &&
chars ~ /^\{.*\}$/ &&
literal_count(chars, "\"Product Name\"=") == 1 &&
literal_count(chars, "\"Product Name\"=\"" product "\"") == 1 &&
literal_count(chars, "\"Serial Number\"=") == 1 &&
literal_count(chars, "\"Serial Number\"=" serial ",") == 1) {
if (root_node[parent[i]]) {
valid_card[i] = 1
valid_cards++
}
}
}
if (class[i] == "AppleSDXCSlot") slot_nodes++
}
for (i = 1; i <= object; i++) {
if (name[i] == "AppleSDXCBlockStorageDevice") {
block_nodes++
if (class[i] == "AppleSDXCBlockStorageDevice" &&
valid_card[parent[i]]) {
valid_block[i] = 1
valid_blocks++
}
}
}
for (i = 1; i <= object; i++) {
if (name[i] == "IOBlockStorageDriver") {
driver_nodes++
if (class[i] == "IOBlockStorageDriver" &&
valid_block[parent[i]]) {
valid_driver[i] = 1
valid_drivers++
}
}
}
for (i = 1; i <= object; i++) {
bsd_slot = i SUBSEP "BSD Name"
if (property_count[bsd_slot] > 0 && property_value[bsd_slot] == "\"" disk "\"") {
target_bsd_occurrences += property_count[bsd_slot]
if (class[i] == "IOMedia") target_media_nodes++
}
if (class[i] == "IOMedia" &&
property_count[i SUBSEP "Whole"] == 1 && property_value[i SUBSEP "Whole"] == "Yes") whole_media_nodes++
if (class[i] == "IOMedia" && name[i] == whole_name &&
property_count[i SUBSEP "Content"] == 1 && property_value[i SUBSEP "Content"] == "\"FDisk_partition_scheme\"" &&
property_count[i SUBSEP "Removable"] == 1 && property_value[i SUBSEP "Removable"] == "Yes" &&
property_count[i SUBSEP "Whole"] == 1 && property_value[i SUBSEP "Whole"] == "Yes" &&
property_count[bsd_slot] == 1 && property_value[bsd_slot] == "\"" disk "\"" &&
property_count[i SUBSEP "Ejectable"] == 1 && property_value[i SUBSEP "Ejectable"] == "Yes" &&
property_count[i SUBSEP "Writable"] == 1 && property_value[i SUBSEP "Writable"] == "Yes" &&
property_count[i SUBSEP "Size"] == 1 && property_value[i SUBSEP "Size"] == bytes &&
property_count[i SUBSEP "BSD Unit"] == 1 && property_value[i SUBSEP "BSD Unit"] == unit) {
valid_media++
if (valid_driver[parent[i]]) paths++
}
}
if (bad != 0 || root_objects != 1 || roots != 1 || slot_nodes != 1 ||
card_nodes != 1 || valid_cards != 1 ||
block_nodes != 1 || valid_blocks != 1 ||
driver_nodes != 1 || valid_drivers != 1 ||
whole_media_nodes != 1 ||
target_bsd_occurrences != 1 || target_media_nodes != 1 ||
valid_media != 1 || paths != 1) exit 1
}
' || fail "ioreg identity is not one exact card-ancestor/whole-IOMedia-descendant path"
}
require_partition_inventory() {
list_snapshot=$1
disk_id=${SD_DISK#/dev/}
printf '%s\n' "$list_snapshot" | awk \
-v disk="$disk_id" \
-v volume="$EXPECTED_VOLUME_NAME" '
NR == 1 {
if ($0 != "/dev/" disk " (internal, physical):") bad++
next
}
NR == 2 {
if (NF != 5 || $1 != "#:" || $2 != "TYPE" || $3 != "NAME" ||
$4 != "SIZE" || $5 != "IDENTIFIER") bad++
next
}
NR == 3 {
if (NF != 5 || $1 != "0:" || $2 != "FDisk_partition_scheme" ||
$3 != "*62.5" || $4 != "GB" || $5 != disk) bad++
next
}
NR == 4 {
if (NF != 6 || $1 != "1:" || $2 != "DOS_FAT_32" ||
$3 != volume || $4 != "62.5" || $5 != "GB" ||
$6 != disk "s1") bad++
next
}
{ bad++ }
END { if (NR != 4 || bad != 0) exit 1 }
' || fail "partition list is not the exact internal/physical whole row plus unique s1 row"
}
MOUNT_DEVICE_ID=
SP_IDENTITY_VERIFIED=0
verify_device_and_mount() {
validate_mount_path
if [ "$SP_IDENTITY_VERIFIED" -eq 0 ]; then
sp_snapshot=$("$SYSTEM_PROFILER" SPCardReaderDataType -xml -detailLevel full) || fail "system_profiler card snapshot failed"
require_system_profiler_binding "$sp_snapshot"
SP_IDENTITY_VERIFIED=1
fi
disk_snapshot=$("$DISKUTIL" info -plist "$SD_DISK") || fail "whole-disk snapshot failed"
root_snapshot=$("$DISKUTIL" info -plist /) || fail "root-disk snapshot failed"
mount_snapshot=$("$DISKUTIL" info -plist "$SD_MOUNT") || fail "mount snapshot failed"
list_snapshot=$("$DISKUTIL" list "$SD_DISK") || fail "partition-list snapshot failed"
ioreg_snapshot=$("$IOREG" -r -l -w 0 -c AppleSDXC) || fail "SD ioreg snapshot failed"
[ "$(plist_snapshot_value "$disk_snapshot" DeviceNode string whole-disk)" = "$SD_DISK" ] || fail "DeviceNode mismatch"
[ "$(plist_snapshot_value "$disk_snapshot" WholeDisk bool whole-disk)" = true ] || fail "target is not WholeDisk"
[ "$(plist_snapshot_value "$disk_snapshot" Content string whole-disk)" = FDisk_partition_scheme ] || fail "partition map is not FDisk/MBR"
[ "$(plist_snapshot_value "$disk_snapshot" OSInternalMedia bool whole-disk)" = false ] || fail "internal OS media forbidden"
[ "$(plist_snapshot_value "$disk_snapshot" RemovableMediaOrExternalDevice bool whole-disk)" = true ] || fail "media not removable/external"
[ "$(plist_snapshot_value "$disk_snapshot" Ejectable bool whole-disk)" = true ] || fail "media not ejectable"
[ "$(plist_snapshot_value "$disk_snapshot" BusProtocol string whole-disk)" = 'Secure Digital' ] || fail "bus is not Secure Digital"
[ "$(plist_snapshot_value "$disk_snapshot" MediaName string whole-disk)" = "$EXPECTED_READER_MEDIA_NAME" ] || fail "diskutil reader MediaName mismatch"
[ "$(plist_snapshot_value "$disk_snapshot" TotalSize integer whole-disk)" = "$EXPECTED_DISK_BYTES" ] || fail "media size mismatch"
[ "$(plist_snapshot_value "$disk_snapshot" DeviceBlockSize integer whole-disk)" = "$EXPECTED_DEVICE_BLOCK_BYTES" ] || fail "media block size mismatch"
[ "$(plist_snapshot_value "$disk_snapshot" VirtualOrPhysical string whole-disk)" = Physical ] || fail "virtual media forbidden"
root_parent=$(plist_snapshot_value "$root_snapshot" ParentWholeDisk string root-disk)
[ "$root_parent" = "$EXPECTED_ROOT_WHOLE_DISK" ] || fail "root whole disk changed from frozen disk3 contract"
[ "$root_parent" != "${SD_DISK#/dev/}" ] || fail "system/root whole disk forbidden"
require_unique_ioreg_binding "$ioreg_snapshot"
require_partition_inventory "$list_snapshot"
partition="${SD_DISK}s1"
[ "$(plist_snapshot_value "$mount_snapshot" DeviceNode string mount)" = "$partition" ] || fail "partition DeviceNode mismatch"
[ "$(plist_snapshot_value "$mount_snapshot" PartitionMapPartition bool mount)" = true ] || fail "partition-map membership is not boolean true"
[ "$(plist_snapshot_value "$mount_snapshot" ParentWholeDisk string mount)" = "${SD_DISK#/dev/}" ] || fail "ParentWholeDisk mismatch"
[ "$(plist_snapshot_value "$mount_snapshot" MountPoint string mount)" = "$SD_MOUNT" ] || fail "MountPoint mismatch"
[ "$(plist_snapshot_value "$mount_snapshot" FilesystemType string mount)" = msdos ] || fail "filesystem is not FAT/msdos"
[ "$(plist_snapshot_value "$mount_snapshot" VolumeName string mount)" = "$EXPECTED_VOLUME_NAME" ] || fail "volume name mismatch"
[ "$(plist_snapshot_value "$mount_snapshot" VolumeUUID string mount)" = "$EXPECTED_VOLUME_UUID" ] || fail "volume UUID mismatch"
[ "$(plist_snapshot_value "$mount_snapshot" TotalSize integer mount)" = "$EXPECTED_DISKUTIL_VOLUME_BYTES" ] || fail "diskutil mounted volume size mismatch"
[ "$(plist_snapshot_value "$mount_snapshot" WritableVolume bool mount)" = true ] || fail "volume not writable"
current_id=$(file_dev_inode "$SD_MOUNT" | cut -d: -f1)
if [ -z "$MOUNT_DEVICE_ID" ]; then
MOUNT_DEVICE_ID=$current_id
else
[ "$current_id" = "$MOUNT_DEVICE_ID" ] || fail "mount device identity changed"
fi
}
validate_mount_path() {
[ -d "$SD_MOUNT" ] && [ ! -L "$SD_MOUNT" ] || fail "mount must be a non-symlink directory"
mount_real=$(CDPATH= cd "$SD_MOUNT" && pwd -P) || fail "mount unresolved"
[ "$mount_real" = "$SD_MOUNT" ] || fail "mount path contains a symlink"
if [ "${S101_FAKE_MODE:-0}" != 1 ]; then
[ "$SD_MOUNT" = "$EXPECTED_MOUNT" ] || fail "mount must be exact /Volumes/ASELSANBOOT"
fi
}
require_s89_finals_and_temps() {
require_commit_prefix_state 0
}
classify_finals_only() {
if exact_file_matches "$SD_MOUNT/aselsanos-rpi5.img" "$S89_IMAGE_BYTES" "$S89_IMAGE_SHA256" &&
exact_file_matches "$SD_MOUNT/bcm2712-rpi-5-b.dtb" "$S89_DTB_BYTES" "$S89_DTB_SHA256" &&
exact_file_matches "$SD_MOUNT/config.txt" "$S89_CONFIG_BYTES" "$S89_CONFIG_SHA256" &&
exact_file_matches "$SD_MOUNT/SHA256SUMS" "$S89_SUMS_BYTES" "$S89_SUMS_SHA256"; then
printf 'S89\n'
else
printf 'MIXED\n'
fi
}
expected_journal_through() {
stop_phase=$1
for retained_phase in \
PREPARED STAGED \
COMMIT_INTENT_1 COMMIT_DONE_1 \
COMMIT_INTENT_2 COMMIT_DONE_2 \
COMMIT_INTENT_3 COMMIT_DONE_3 \
COMMIT_INTENT_4 COMMIT_DONE_4 SUCCESS; do
printf 'PHASE=%s\n' "$retained_phase"
[ "$retained_phase" != "$stop_phase" ] || return 0
done
return 1
}
inspect_retained_lock() {
RETAINED_LOCK_PRESENT=0
RETAINED_LOCK_PHASE=
retained_lock="$S101_LOCK_PARENT/$LOCK_BASENAME"
if [ ! -e "$retained_lock" ] && [ ! -L "$retained_lock" ]; then
return 0
fi
S101_LOCK_DIR=$retained_lock
[ -d "$retained_lock" ] && [ ! -L "$retained_lock" ] ||
fail "retained canonical host lock type invalid; review required"
retained_entries=$(find "$retained_lock" -mindepth 1 -maxdepth 1 -print |
while IFS= read -r retained_entry; do basename "$retained_entry"; done |
LC_ALL=C sort) || fail "retained canonical host lock inventory unreadable"
[ "$retained_entries" = "$(printf 'journal\nstatus\n')" ] ||
fail "retained canonical host lock inventory is not exact journal+status"
retained_status="$retained_lock/status"
retained_journal="$retained_lock/journal"
[ -f "$retained_status" ] && [ ! -L "$retained_status" ] ||
fail "retained canonical host status invalid; review required"
[ -f "$retained_journal" ] && [ ! -L "$retained_journal" ] ||
fail "retained canonical host journal invalid; review required"
RETAINED_LOCK_PHASE=$(awk -F= '$1 == "STATUS" { print $2; found++ } END { if (found != 1) exit 1 }' "$retained_status") ||
fail "retained canonical host status phase invalid; review required"
case "$RETAINED_LOCK_PHASE" in
PREPARED|STAGED|COMMIT_INTENT_[1-4]|COMMIT_DONE_[1-4]|SUCCESS) ;;
*) fail "retained canonical host status phase unknown; review required" ;;
esac
if [ "$RETAINED_LOCK_PHASE" = SUCCESS ]; then
retained_never_boot=NO
else
retained_never_boot=YES
fi
expected_status=$(printf '%s\n' \
"STATUS=$RETAINED_LOCK_PHASE" \
"PHASE=$RETAINED_LOCK_PHASE" \
"CARD=$EXPECTED_CARD_SERIAL_HEX" \
"IMAGE=$EXPECTED_IMAGE_SHA256" \
"RECOVERY_SOURCE=$RECOVERY_ROOT" \
'RECOVERY_AUTH=REQUIRED' \
"NEVER_BOOT=$retained_never_boot" \
'RERUN_FORBIDDEN=YES' \
'AUTO_ROLLBACK=NO' \
'HOST_JOURNAL_CRASH_DURABILITY=NOT_CLAIMED')
actual_status=$(/bin/cat "$retained_status") ||
fail "retained canonical host status unreadable; review required"
[ "$actual_status" = "$expected_status" ] ||
fail "retained canonical host status content invalid; review required"
expected_journal=$(expected_journal_through "$RETAINED_LOCK_PHASE") ||
fail "retained canonical host phase cannot map to journal"
actual_journal=$(/bin/cat "$retained_journal") ||
fail "retained canonical host journal unreadable; review required"
[ "$actual_journal" = "$expected_journal" ] ||
fail "retained canonical host journal/status mismatch; review required"
RETAINED_LOCK_PRESENT=1
}
acquire_host_lock() {
[ -d "$S101_LOCK_PARENT" ] && [ ! -L "$S101_LOCK_PARENT" ] ||
fail "canonical lock parent must be a non-symlink directory"
lock_parent_real=$(CDPATH= cd "$S101_LOCK_PARENT" && pwd -P) || fail "lock parent unresolved"
[ "$lock_parent_real" = "$S101_LOCK_PARENT" ] || fail "lock parent contains a symlink"
S101_LOCK_DIR="$S101_LOCK_PARENT/$LOCK_BASENAME"
[ ! -e "$S101_LOCK_DIR" ] && [ ! -L "$S101_LOCK_DIR" ] ||
fail "cooperating lock exists; review required"
mkdir "$S101_LOCK_DIR" 2>/dev/null || fail "cooperating lock exists; review required"
[ -d "$S101_LOCK_DIR" ] && [ ! -L "$S101_LOCK_DIR" ] || fail "cooperating lock type mismatch"
JOURNAL_PHASE=
journal_transition PREPARED
}
host_journal_fault() {
fault_phase=$1
fault_point=$2
[ "${S101_FAKE_MODE:-0}" = 1 ] || return 0
fault_file="$S101_FAKE_STATE/fail-host-journal"
[ ! -e "$fault_file" ] && [ ! -L "$fault_file" ] && return 0
[ -f "$fault_file" ] && [ ! -L "$fault_file" ] ||
fail "fake host journal fault selector invalid"
fault_value=$(/bin/cat "$fault_file") ||
fail "fake host journal fault selector unreadable"
[ "$fault_value" != "$fault_phase:$fault_point" ] ||
fail "injected host journal fault at $fault_phase:$fault_point"
}
journal_transition() {
next_phase=$1
case "${JOURNAL_PHASE:-}:$next_phase" in
:PREPARED|PREPARED:STAGED|STAGED:COMMIT_INTENT_1|\
COMMIT_INTENT_1:COMMIT_DONE_1|COMMIT_DONE_1:COMMIT_INTENT_2|\
COMMIT_INTENT_2:COMMIT_DONE_2|COMMIT_DONE_2:COMMIT_INTENT_3|\
COMMIT_INTENT_3:COMMIT_DONE_3|COMMIT_DONE_3:COMMIT_INTENT_4|\
COMMIT_INTENT_4:COMMIT_DONE_4|COMMIT_DONE_4:SUCCESS) ;;
*) fail "invalid host journal transition ${JOURNAL_PHASE:-NONE}->$next_phase" ;;
esac
journal="$S101_LOCK_DIR/journal"
journal_next="$S101_LOCK_DIR/journal.next"
status="$S101_LOCK_DIR/status"
status_next="$S101_LOCK_DIR/status.next"
[ ! -L "$journal" ] && [ ! -L "$status" ] && [ ! -L "$journal_next" ] && [ ! -L "$status_next" ] ||
fail "host journal symlink forbidden"
host_journal_fault "$next_phase" journal-next-write
{
if [ -f "$journal" ]; then
while IFS= read -r journal_line || [ -n "$journal_line" ]; do
printf '%s\n' "$journal_line"
done < "$journal"
fi
printf 'PHASE=%s\n' "$next_phase"
} > "$journal_next" || fail "host journal next write failed"
host_journal_fault "$next_phase" journal-publish
COPYFILE_DISABLE=1 /bin/mv -f "$journal_next" "$journal" || fail "host journal publish failed"
if [ "$next_phase" = SUCCESS ]; then
never_boot=NO
else
never_boot=YES
fi
host_journal_fault "$next_phase" status-next-write
{
printf 'STATUS=%s\n' "$next_phase"
printf 'PHASE=%s\n' "$next_phase"
printf 'CARD=%s\n' "$EXPECTED_CARD_SERIAL_HEX"
printf 'IMAGE=%s\n' "$EXPECTED_IMAGE_SHA256"
printf 'RECOVERY_SOURCE=%s\n' "$RECOVERY_ROOT"
printf 'RECOVERY_AUTH=REQUIRED\n'
printf 'NEVER_BOOT=%s\n' "$never_boot"
printf 'RERUN_FORBIDDEN=YES\n'
printf 'AUTO_ROLLBACK=NO\n'
printf 'HOST_JOURNAL_CRASH_DURABILITY=NOT_CLAIMED\n'
} > "$status_next" || fail "host status next write failed"
host_journal_fault "$next_phase" status-publish
COPYFILE_DISABLE=1 /bin/mv -f "$status_next" "$status" || fail "host status publish failed"
JOURNAL_PHASE=$next_phase
}
run_flash_transaction() {
package=$1
SD_DISK=$2
SD_MOUNT=$3
authorization=$4
S101_LOCK_DIR=
S101_TRANSACTION_SUCCESS=0
JOURNAL_PHASE=
MOUNT_DEVICE_ID=
SP_IDENTITY_VERIFIED=0
[ "$authorization" = "$EXPECTED_AUTH" ] || fail "explicit authorization token mismatch"
serial_hex=$(printf '0x%08x' "$EXPECTED_CARD_SERIAL_DECIMAL") || fail "card serial conversion failed"
[ "$serial_hex" = "$EXPECTED_CARD_SERIAL_HEX" ] || fail "card decimal/hex serial constants disagree"
resolve_frozen_package "$package"
resolve_frozen_s89_recovery
case "$SD_DISK" in
/dev/disk*) disk_suffix=${SD_DISK#/dev/disk} ;;
*) fail "SD_DISK must be explicit whole /dev/diskN" ;;
esac
case "$disk_suffix" in
''|*[!0-9]*) fail "SD_DISK must contain digits only after /dev/disk" ;;
esac
validate_mount_path
verify_device_and_mount
inspect_retained_lock
state=$(classify_card_state)
if [ "$RETAINED_LOCK_PRESENT" -eq 1 ]; then
case "$state:$RETAINED_LOCK_PHASE" in
S100_META:SUCCESS) already_applied ;;
S100_META:*)
fail "APPLIED_UNVERIFIED: S100 core exists under non-SUCCESS retained phase $RETAINED_LOCK_PHASE"
;;
MIXED:COMMIT_INTENT_*|MIXED:COMMIT_DONE_*)
fail "INCIDENT_MIXED: partially committed card retained at $RETAINED_LOCK_PHASE"
;;
S89_META:*|PREPARED:*)
fail "retained transaction state requires explicit recovery review; automatic rerun forbidden"
;;
*)
fail "retained lock/card state conflict requires review"
;;
esac
fi
case "$state" in
S100_META) already_applied ;;
S89_META) ;;
*) fail "card is mixed/unknown or metadata/core/temp inventory differs" ;;
esac
acquire_host_lock
validate_package_generic "$PACKAGE_ROOT"
validate_s89_recovery_package "$RECOVERY_ROOT"
validate_frozen_source_xattrs "$PACKAGE_ROOT"
validate_frozen_source_xattrs "$RECOVERY_ROOT"
verify_device_and_mount
[ "$(classify_card_state)" = S89_META ] || fail "metadata-preserving predecessor changed before lock recheck"
for name in aselsanos-rpi5.img bcm2712-rpi-5-b.dtb config.txt SHA256SUMS; do
tmp=$(temp_path "$name")
tmp_sidecar=$(temp_appledouble_path "$name")
[ ! -e "$tmp" ] && [ ! -L "$tmp" ] || fail "temp destination already exists"
[ ! -e "$tmp_sidecar" ] && [ ! -L "$tmp_sidecar" ] || fail "temp AppleDouble destination already exists"
verify_device_and_mount
require_frozen_source_entry "$name"
COPYFILE_DISABLE=1 "$COPY_TOOL" -X "$FROZEN_SOURCE_PATH" "$tmp" || fail "suppressed staged copy failed: $name"
require_exact_temp_appledouble "$name"
done
for name in aselsanos-rpi5.img bcm2712-rpi-5-b.dtb config.txt SHA256SUMS; do
"$COMPARE_TOOL" "$PACKAGE_ROOT/$name" "$(temp_path "$name")" || fail "staged compare failed: $name"
done
"$SYNC_TOOL" || fail "staged sync failed"
verify_device_and_mount
require_commit_prefix_state 0
validate_package_generic "$PACKAGE_ROOT"
validate_temp_payloads
validate_s89_recovery_package "$RECOVERY_ROOT"
validate_frozen_source_xattrs "$PACKAGE_ROOT"
validate_frozen_source_xattrs "$RECOVERY_ROOT"
journal_transition STAGED
commit_index=0
for commit_name in aselsanos-rpi5.img bcm2712-rpi-5-b.dtb config.txt SHA256SUMS; do
commit_index=$((commit_index + 1))
verify_device_and_mount
require_commit_prefix_state "$((commit_index - 1))"
require_exact_temp_entry "$commit_name"
require_exact_temp_appledouble "$commit_name"
journal_transition "COMMIT_INTENT_$commit_index"
COPYFILE_DISABLE=1 "$MOVE_TOOL" "$(temp_path "$commit_name")" "$SD_MOUNT/$commit_name" || fail "commit move failed at position $commit_index: $commit_name"
require_commit_prefix_state "$commit_index"
journal_transition "COMMIT_DONE_$commit_index"
done
"$SYNC_TOOL" || fail "post-commit sync failed"
verify_device_and_mount
[ "$(classify_card_state)" = S100_META ] || fail "final card state is not exact S100_META"
for name in aselsanos-rpi5.img bcm2712-rpi-5-b.dtb config.txt SHA256SUMS; do
"$COMPARE_TOOL" "$PACKAGE_ROOT/$name" "$SD_MOUNT/$name" || fail "final compare failed: $name"
done
validate_manifest_shape "$SD_MOUNT/SHA256SUMS"
(cd "$SD_MOUNT" && shasum -a 256 -c SHA256SUMS >/dev/null) || fail "final card manifest mismatch"
validate_package_generic "$PACKAGE_ROOT"
require_metadata_namespace
journal_transition SUCCESS
S101_TRANSACTION_SUCCESS=1
printf 'PASS: S101 core exact4 write-once cp4(-X,COPYFILE_DISABLE) temp-cmp4 sync1 identity-recheck mv4 sync2 final-cmp4 hash4/4 manifest3/3 metadata6-preserved\n'
printf 'S101_LOCK=%s RETAINED=YES DEVICE_EJECT=NOT_RUN UART=NOT_RUN POWER=NOT_RUN\n' "$S101_LOCK_DIR"
}
write_fake_tool() {
path=$1
body=$2
printf '%s\n' '#!/bin/sh' "$body" > "$path"
chmod 755 "$path"
}
prepare_fake_tools() {
root=$1
mkdir -p "$root/bin" "$root/state" "$root/locks"
printf '%s\n' \
'<?xml version="1.0" encoding="UTF-8"?>' \
'<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">' \
'<plist version="1.0"><dict>' \
'<key>DeviceNode</key><string>/dev/disk99</string>' \
'<key>WholeDisk</key><true/>' \
'<key>Content</key><string>FDisk_partition_scheme</string>' \
'<key>OSInternalMedia</key><false/>' \
'<key>RemovableMediaOrExternalDevice</key><true/>' \
'<key>Ejectable</key><true/>' \
'<key>BusProtocol</key><string>Secure Digital</string>' \
'<key>MediaName</key><string>Built In SDXC Reader</string>' \
'<key>TotalSize</key><integer>62549655552</integer>' \
'<key>DeviceBlockSize</key><integer>512</integer>' \
'<key>VirtualOrPhysical</key><string>Physical</string>' \
'</dict></plist>' > "$root/state/disk"
printf '%s\n' \
'<?xml version="1.0" encoding="UTF-8"?>' \
'<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">' \
'<plist version="1.0"><dict><key>ParentWholeDisk</key><string>disk3</string></dict></plist>' > "$root/state/root"
printf '%s\n' \
'<?xml version="1.0" encoding="UTF-8"?>' \
'<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">' \
'<plist version="1.0"><dict>' \
'<key>DeviceNode</key><string>/dev/disk99s1</string>' \
'<key>PartitionMapPartition</key><true/>' \
'<key>ParentWholeDisk</key><string>disk99</string>' \
"<key>MountPoint</key><string>$root/mount</string>" \
'<key>FilesystemType</key><string>msdos</string>' \
'<key>VolumeName</key><string>ASELSANBOOT</string>' \
'<key>VolumeUUID</key><string>44ABB50F-DB63-3DB8-A6B2-C5303E3211E9</string>' \
'<key>TotalSize</key><integer>62517608448</integer>' \
'<key>WritableVolume</key><true/>' \
'</dict></plist>' > "$root/state/mount"
printf '%s\n' \
'<?xml version="1.0" encoding="UTF-8"?>' \
'<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">' \
'<plist version="1.0"><array><dict>' \
'<key>_items</key><array><dict>' \
'<key>_name</key><string>spcardreader</string>' \
'<key>_items</key><array><dict>' \
'<key>_name</key><string>SDXC Card (Class 10)</string>' \
'<key>bsd_name</key><string>disk99</string>' \
'<key>partition_map_type</key><string>master_boot_record_partition_map_type</string>' \
'<key>removable_media</key><string>yes</string>' \
'<key>size_in_bytes</key><integer>62549655552</integer>' \
'<key>smart_status</key><string>Verified</string>' \
'<key>spcardreader_card_manufacturer-id</key><string>0x9f</string>' \
'<key>spcardreader_card_manufacturing_date</key><string>2026-01</string>' \
'<key>spcardreader_card_productname</key><string>TISD64G</string>' \
'<key>spcardreader_card_productrevision</key><string>6.1</string>' \
'<key>spcardreader_card_serialnumber</key><string>0x425001fa</string>' \
'<key>spcardreader_card_specversion</key><string>3.0</string>' \
'<key>free_space_in_bytes</key><integer>1</integer>' \
'<key>timestamp</key><string>DYNAMIC_IGNORED</string>' \
'<key>volumes</key><array><dict>' \
'<key>_name</key><string>ASELSANBOOT</string>' \
'<key>bsd_name</key><string>disk99s1</string>' \
'<key>file_system</key><string>MS-DOS FAT32</string>' \
'<key>iocontent</key><string>DOS_FAT_32</string>' \
"<key>mount_point</key><string>$root/mount</string>" \
'<key>size_in_bytes</key><integer>62532878336</integer>' \
'<key>volume_uuid</key><string>44ABB50F-DB63-3DB8-A6B2-C5303E3211E9</string>' \
'<key>writable</key><string>yes</string>' \
'<key>free_space_in_bytes</key><integer>1</integer>' \
'</dict></array>' \
'</dict></array></dict></array>' \
'</dict></array></plist>' > "$root/state/system-profiler"
printf '%s\n' \
'+-o AppleSDXC <class AppleSDXC, id 0x1>' \
' +-o Port-SD Card@1 <class AppleSDXCSlot, id 0x2>' \
' | "Card Characteristics" = {"Manufacturing Date"="2026-01","Card Type"="SDXC","Specification Version"="3.0","Product Name"="SD64G","UHS-II Supported"=No,"Write Protect Enabled"=No,"Serial Number"=1112539642,"CSD Protect Enabled"=No,"Product Revision Level"="6.1","UHS-II Mode Enabled"=No,"Manufacturer ID"=159,"Application ID"=21577,"Speed Class"=4,"Block Count"=122167296}' \
' +-o SD <class IOPortTransportStateSD, id 0x2a>' \
' | {' \
' | "TransportTypeDescription" = "SD"' \
' | }' \
' |' \
' +-o AppleSDXCBlockStorageDevice <class AppleSDXCBlockStorageDevice, id 0x3>' \
' +-o IOBlockStorageDriver <class IOBlockStorageDriver, id 0x4>' \
' +-o Apple SDXC Reader Media <class IOMedia, id 0x5>' \
' | "Content" = "FDisk_partition_scheme"' \
' | "Removable" = Yes' \
' | "Whole" = Yes' \
' | "BSD Name" = "disk99"' \
' | "Ejectable" = Yes' \
' | "Writable" = Yes' \
' | "Size" = 62549655552' \
' | "BSD Unit" = 99' \
' +-o ASELSANBOOT@1 <class IOMedia, id 0x6>' \
' | "Content" = "DOS_FAT_32"' \
' | "Whole" = No' \
' | "BSD Name" = "disk99s1"' \
' | "Partition ID" = 1' \
' | "Size" = 62532878336' > "$root/state/ioreg"
printf '/dev/disk99 (internal, physical):\n #: TYPE NAME SIZE IDENTIFIER\n 0: FDisk_partition_scheme *62.5 GB disk99\n 1: DOS_FAT_32 ASELSANBOOT 62.5 GB disk99s1\n' > "$root/state/list"
printf '%s' "$SIDECAR_FIXTURE_BASE64" | /usr/bin/base64 -D > "$root/state/sidecar" || fail "sidecar fixture decode failed"
[ "$(file_bytes "$root/state/sidecar")" -eq "$EXPECTED_SIDECAR_BYTES" ] || fail "sidecar fixture byte count mismatch"
[ "$(sha256_file "$root/state/sidecar")" = "$EXPECTED_SIDECAR_SHA256" ] || fail "sidecar fixture SHA256 mismatch"
: > "$root/tool.log"
: > "$root/trace.log"
: > "$root/state/sync.count"
write_fake_tool "$root/bin/diskutil" 'set -eu; printf "diskutil\\n" >> "$S101_FAKE_LOG"; printf "diskutil|argc=%s|%s|%s|%s\\n" "$#" "${1:-}" "${2:-}" "${3:-}" >> "${S101_FAKE_STATE%/state}/trace.log"; if [ "$#" -eq 3 ] && [ "$1" = info ] && [ "$2" = -plist ]; then case "$3" in /dev/disk99) /bin/cat "$S101_FAKE_STATE/disk";; /) /bin/cat "$S101_FAKE_STATE/root";; "${S101_FAKE_STATE%/state}/mount") /bin/cat "$S101_FAKE_STATE/mount";; *) exit 42;; esac; exit 0; fi; if [ "$#" -eq 2 ] && [ "$1" = list ] && [ "$2" = /dev/disk99 ]; then /bin/cat "$S101_FAKE_STATE/list"; exit 0; fi; exit 42'
write_fake_tool "$root/bin/plutil" 'exec /usr/bin/plutil "$@"'
write_fake_tool "$root/bin/ioreg" 'printf "ioreg\\n" >> "$S101_FAKE_LOG"; printf "ioreg|argc=%s|%s\\n" "$#" "$*" >> "${S101_FAKE_STATE%/state}/trace.log"; [ "$#" -eq 6 ] && [ "$*" = "-r -l -w 0 -c AppleSDXC" ] || exit 43; /bin/cat "$S101_FAKE_STATE/ioreg"'
write_fake_tool "$root/bin/system_profiler" 'printf "system_profiler\\n" >> "$S101_FAKE_LOG"; printf "system_profiler|argc=%s|%s\\n" "$#" "$*" >> "${S101_FAKE_STATE%/state}/trace.log"; [ "$#" -eq 4 ] && [ "$*" = "SPCardReaderDataType -xml -detailLevel full" ] || exit 44; /bin/cat "$S101_FAKE_STATE/system-profiler"'
write_fake_tool "$root/bin/cp" 'set -eu; count=$(awk '\''$0 == "cp" { count++ } END { print count + 0 }'\'' "$S101_FAKE_LOG"); printf "cp\\n" >> "$S101_FAKE_LOG"; [ "${COPYFILE_DISABLE:-}" = 1 ] || exit 45; [ "${1:-}" = -X ] || exit 46; shift; [ "$#" -eq 2 ] || exit 47; printf "cp|%s|%s\\n" "$1" "$2" >> "${S101_FAKE_STATE%/state}/trace.log"; if [ -f "$S101_FAKE_STATE/fail-cp-at" ] && [ "$count" -eq "$(/bin/cat "$S101_FAKE_STATE/fail-cp-at")" ]; then exit 7; fi; if [ -f "$S101_FAKE_STATE/source-swap-copy" ] && [ "$count" -eq 0 ]; then COPYFILE_DISABLE=1 /bin/cp -X "$(/bin/cat "$S101_FAKE_STATE/source-swap-copy")" "$2"; else COPYFILE_DISABLE=1 /bin/cp -X "$1" "$2"; fi; destination_dir=${2%/*}; destination_base=${2##*/}; COPYFILE_DISABLE=1 /bin/cp -X "$S101_FAKE_STATE/sidecar" "$destination_dir/._$destination_base"; if [ -f "$S101_FAKE_STATE/corrupt-appledouble-after-first-copy" ] && [ "$count" -eq 0 ]; then printf "wrong AppleDouble\\n" > "$destination_dir/._$destination_base"; fi; if [ -f "$S101_FAKE_STATE/swap-mount-after-first-copy" ] && [ "$count" -eq 0 ]; then current=$(/usr/bin/plutil -extract MountPoint raw "$S101_FAKE_STATE/mount"); /usr/bin/plutil -replace MountPoint -string "$current-SWAPPED" "$S101_FAKE_STATE/mount"; fi'
write_fake_tool "$root/bin/mv" 'set -eu; count=$(awk '\''$0 == "mv" { count++ } END { print count + 0 }'\'' "$S101_FAKE_LOG"); printf "mv\\n" >> "$S101_FAKE_LOG"; [ "${COPYFILE_DISABLE:-}" = 1 ] || exit 48; [ "$#" -eq 2 ] || exit 49; printf "mv|%s|%s\\n" "$1" "$2" >> "${S101_FAKE_STATE%/state}/trace.log"; if [ -f "$S101_FAKE_STATE/fail-mv-at" ] && [ "$count" -eq "$(/bin/cat "$S101_FAKE_STATE/fail-mv-at")" ]; then exit 10; fi; source_dir=${1%/*}; source_base=${1##*/}; destination_dir=${2%/*}; destination_base=${2##*/}; source_sidecar="$source_dir/._$source_base"; destination_sidecar="$destination_dir/._$destination_base"; [ -f "$source_sidecar" ] && [ ! -L "$source_sidecar" ] || exit 52; /bin/mv "$1" "$2"; if [ -f "$S101_FAKE_STATE/retain-temp-sidecar-after-first-move" ] && [ "$count" -eq 0 ]; then :; else /bin/mv "$source_sidecar" "$destination_sidecar"; fi; if [ -f "$S101_FAKE_STATE/swap-mount-after-first-move" ] && [ "$count" -eq 0 ]; then current=$(/usr/bin/plutil -extract MountPoint raw "$S101_FAKE_STATE/mount"); /usr/bin/plutil -replace MountPoint -string "$current-SWAPPED" "$S101_FAKE_STATE/mount"; fi'
write_fake_tool "$root/bin/cmp" 'set -eu; count=$(awk '\''$0 == "cmp" { count++ } END { print count + 0 }'\'' "$S101_FAKE_LOG"); printf "cmp\\n" >> "$S101_FAKE_LOG"; [ "$#" -eq 2 ] || exit 51; printf "cmp|%s|%s\\n" "$1" "$2" >> "${S101_FAKE_STATE%/state}/trace.log"; if [ -f "$S101_FAKE_STATE/fail-cmp-at" ] && [ "$count" -eq "$(/bin/cat "$S101_FAKE_STATE/fail-cmp-at")" ]; then exit 8; fi; if [ -f "$S101_FAKE_STATE/source-swap-compare" ]; then exit 0; fi; /usr/bin/cmp "$@"'
write_fake_tool "$root/bin/sync" 'set -eu; printf "sync\\n" >> "$S101_FAKE_LOG"; printf "sync|argc=%s|%s\\n" "$#" "$*" >> "${S101_FAKE_STATE%/state}/trace.log"; [ "$#" -eq 0 ] || exit 50; count=$(wc -l < "$S101_FAKE_STATE/sync.count" | tr -d "[:space:]"); if [ -f "$S101_FAKE_STATE/fail-sync-at" ] && [ "$count" -eq "$(/bin/cat "$S101_FAKE_STATE/fail-sync-at")" ]; then exit 9; fi; printf "x\\n" >> "$S101_FAKE_STATE/sync.count"; if [ -f "$S101_FAKE_STATE/swap-on-first-sync" ] && [ "$count" -eq 0 ]; then current=$(/usr/bin/plutil -extract MountPoint raw "$S101_FAKE_STATE/mount"); /usr/bin/plutil -replace MountPoint -string "$current-SWAPPED" "$S101_FAKE_STATE/mount"; fi; if [ -f "$S101_FAKE_STATE/corrupt-temp-after-first-sync" ] && [ "$count" -eq 0 ]; then target=$(/bin/cat "$S101_FAKE_STATE/corrupt-temp-after-first-sync"); LC_ALL=C /usr/bin/tr "\\000" "\\001" < "$target" > "$target.corrupt"; /bin/mv "$target.corrupt" "$target"; fi; if [ -f "$S101_FAKE_STATE/corrupt-final-after-second-sync" ] && [ "$count" -eq 1 ]; then target=$(/bin/cat "$S101_FAKE_STATE/corrupt-final-after-second-sync"); LC_ALL=C /usr/bin/tr "\\000" "\\001" < "$target" > "$target.corrupt"; /bin/mv "$target.corrupt" "$target"; fi'
}
copy_package_fixture() {
source=$1
destination=$2
mkdir -p "$destination"
chmod 755 "$destination"
for name in SHA256SUMS aselsanos-rpi5.img bcm2712-rpi-5-b.dtb config.txt; do
COPYFILE_DISABLE=1 /bin/cp -X -p "$source/$name" "$destination/$name"
done
}
prepare_card_state() {
root=$1
source=$2
mkdir -p "$root/mount/.Spotlight-V100/Store-V2" "$root/mount/.fseventsd"
printf 'opaque spotlight descendant\n' > "$root/mount/.Spotlight-V100/Store-V2/opaque"
printf 'opaque fseventsd descendant\n' > "$root/mount/.fseventsd/0000000000000001"
for name in SHA256SUMS aselsanos-rpi5.img bcm2712-rpi-5-b.dtb config.txt; do
COPYFILE_DISABLE=1 /bin/cp -X -p "$source/$name" "$root/mount/$name"
chmod 644 "$root/mount/$name"
done
for name in ._SHA256SUMS ._aselsanos-rpi5.img ._bcm2712-rpi-5-b.dtb ._config.txt; do
COPYFILE_DISABLE=1 /bin/cp -X "$root/state/sidecar" "$root/mount/$name"
chmod 644 "$root/mount/$name"
done
}
expect_red() {
label=$1
shift
assert_selftest_source_unchanged
set +e
( set -e; "$@" ) >/dev/null 2>&1
status=$?
set -e
[ "$status" -ne 0 ] || fail "self-test expected RED: $label"
assert_selftest_source_unchanged
SELFTEST_PASSED=$((SELFTEST_PASSED + 1))
}
fake_operation_count() {
root=$1
operation=$2
awk -v wanted="$operation" '$0 == wanted { count++ } END { print count + 0 }' "$root/tool.log"
}
fake_card_state() {
root=$1
(SD_MOUNT="$root/mount"; classify_card_state)
}
fake_lock_state() {
root=$1
lock="$root/locks/$LOCK_BASENAME"
if [ ! -e "$lock" ] && [ ! -L "$lock" ]; then
printf 'ABSENT\n'
elif [ -f "$lock/status" ] && [ ! -L "$lock/status" ]; then
awk -F= '$1 == "STATUS" { print $2; found++ } END { if (found != 1) exit 1 }' "$lock/status"
else
printf 'PRESENT\n'
fi
}
expected_fake_verify_trace() {
trace_root=$1
printf '%s\n' \
'diskutil|argc=3|info|-plist|/dev/disk99' \
'diskutil|argc=3|info|-plist|/' \
"diskutil|argc=3|info|-plist|$trace_root/mount" \
'diskutil|argc=2|list|/dev/disk99|' \
'ioreg|argc=6|-r -l -w 0 -c AppleSDXC'
}
expected_positive_full_trace() {
trace_root=$1
trace_source=$2
trace_mount=$trace_root/mount
printf '%s\n' 'system_profiler|argc=4|SPCardReaderDataType -xml -detailLevel full'
expected_fake_verify_trace "$trace_root"
expected_fake_verify_trace "$trace_root"
expected_fake_verify_trace "$trace_root"
for name in aselsanos-rpi5.img bcm2712-rpi-5-b.dtb config.txt; do
printf 'cp|%s|%s\n' "$trace_source/$name" "$trace_mount/.aselsanos-s101-$name.tmp"
expected_fake_verify_trace "$trace_root"
done
printf 'cp|%s|%s\n' \
"$trace_source/SHA256SUMS" "$trace_mount/.aselsanos-s101-SHA256SUMS.tmp"
for name in aselsanos-rpi5.img bcm2712-rpi-5-b.dtb config.txt SHA256SUMS; do
printf 'cmp|%s|%s\n' "$trace_source/$name" "$trace_mount/.aselsanos-s101-$name.tmp"
done
printf '%s\n' 'sync|argc=0|'
expected_fake_verify_trace "$trace_root"
expected_fake_verify_trace "$trace_root"
for name in aselsanos-rpi5.img bcm2712-rpi-5-b.dtb config.txt; do
printf 'mv|%s|%s\n' "$trace_mount/.aselsanos-s101-$name.tmp" "$trace_mount/$name"
expected_fake_verify_trace "$trace_root"
done
printf 'mv|%s|%s\n' \
"$trace_mount/.aselsanos-s101-SHA256SUMS.tmp" "$trace_mount/SHA256SUMS"
printf '%s\n' 'sync|argc=0|'
expected_fake_verify_trace "$trace_root"
for name in aselsanos-rpi5.img bcm2712-rpi-5-b.dtb config.txt SHA256SUMS; do
printf 'cmp|%s|%s\n' "$trace_source/$name" "$trace_mount/$name"
done
}
assert_two_phase_retained() {
root=$1
(SD_MOUNT="$root/mount"; require_s89_finals_and_temps)
}
require_expected_fake_layout() (
layout_root=$1
expected_layout=$2
SD_MOUNT="$layout_root/mount"
case "$expected_layout" in
S89)
[ "$(card_inventory)" = "$(base_card_inventory)" ] ||
fail "expected S89 layout inventory mismatch"
[ "$(classify_card_state)" = S89_META ] ||
fail "expected S89 layout state mismatch"
;;
P0|P1|P2|P3|P4)
require_commit_prefix_state "${expected_layout#P}"
;;
*) fail "unknown expected fake layout: $expected_layout" ;;
esac
)
expected_fake_verify_count() {
verify_label=$1
verify_cp=$2
verify_cmp=$3
verify_mv=$4
case "$verify_label" in
authorization|sp-*) printf '0\n' ;;
wrong-reader|internal|root-parent|partition-bool|disk-size|uuid|extra-partition|duplicate-partition|suffixed-partition|bad-list-*|ioreg-*|metadata-*|temp-appledouble|unexpected-*|already-applied|mixed|concurrency) printf '1\n' ;;
cp-failure-*|post-copy-appledouble-wrong)
printf '%s\n' "$((2 + verify_cp))"
;;
external-cp-failure) printf '3\n' ;;
cmp-failure-*|external-cmp-failure) printf '6\n' ;;
staged-sync-failure) printf '6\n' ;;
per-copy-mount-swap) printf '4\n' ;;
staged-mount-swap|temp-corruption) printf '7\n' ;;
post-move-temp-sidecar-retained) printf '8\n' ;;
mv-failure-*) printf '%s\n' "$((7 + verify_mv))" ;;
post-commit-sync-failure) printf '11\n' ;;
post-commit-corruption|final-cmp-failure-*|final-cmp-failure|journal-success-*)
printf '12\n'
;;
per-move-mount-swap) printf '9\n' ;;
source-view-corrupt) printf '3\n' ;;
journal-prepared-*) printf '1\n' ;;
journal-staged-*) printf '7\n' ;;
journal-intent-1-*|journal-done-1-*) printf '8\n' ;;
journal-intent-2-*|journal-done-2-*) printf '9\n' ;;
journal-intent-3-*|journal-done-3-*) printf '10\n' ;;
journal-intent-4-*|journal-done-4-*) printf '11\n' ;;
rerun-s89-*) printf '4\n' ;;
rerun-prepared-*) printf '7\n' ;;
rerun-applied-unverified) printf '12\n' ;;
rerun-incident-mixed) printf '13\n' ;;
rerun-success) printf '13\n' ;;
*) fail "missing exact fake verify-count contract: $verify_label" ;;
esac
}
expect_fake_status() {
label=$1
expected_status=$2
root=$3
expected_cp=$4
expected_cmp=$5
expected_mv=$6
expected_sync=$7
expected_sp=$8
expected_state=$9
shift 9
expected_lock=$1
shift
assert_selftest_source_unchanged
set +e
( set -e; "$@" ) >"$root/last.stdout" 2>"$root/last.stderr"
status=$?
set -e
[ "$status" -eq "$expected_status" ] ||
fail "self-test status mismatch: $label expected=$expected_status actual=$status"
[ "$(fake_operation_count "$root" cp)" -eq "$expected_cp" ] || fail "$label cp mutation count"
[ "$(fake_operation_count "$root" cmp)" -eq "$expected_cmp" ] || fail "$label cmp count"
[ "$(fake_operation_count "$root" mv)" -eq "$expected_mv" ] || fail "$label mv mutation count"
[ "$(fake_operation_count "$root" sync)" -eq "$expected_sync" ] || fail "$label sync mutation count"
[ "$(fake_operation_count "$root" system_profiler)" -eq "$expected_sp" ] || fail "$label system_profiler count"
expected_verify=$(expected_fake_verify_count "$label" "$expected_cp" "$expected_cmp" "$expected_mv")
[ "$(fake_operation_count "$root" diskutil)" -eq "$((expected_verify * 4))" ] || fail "$label diskutil exact call count"
[ "$(fake_operation_count "$root" ioreg)" -eq "$expected_verify" ] || fail "$label ioreg exact call count"
[ "$(fake_card_state "$root")" = "$expected_state" ] || fail "$label retained card state"
[ "$(fake_lock_state "$root")" = "$expected_lock" ] || fail "$label retained lock state"
if [ "$expected_lock" != ABSENT ] && [ "$expected_lock" != PRESENT ] && [ "$expected_lock" != SUCCESS ]; then
status="$root/locks/$LOCK_BASENAME/status"
[ -f "$status" ] && [ ! -L "$status" ] || fail "$label incident status missing"
[ "$(awk -F= '$1 == "NEVER_BOOT" { print $2; found++ } END { if (found != 1) exit 1 }' "$status")" = YES ] || fail "$label NEVER_BOOT journal flag"
[ "$(awk -F= '$1 == "RERUN_FORBIDDEN" { print $2; found++ } END { if (found != 1) exit 1 }' "$status")" = YES ] || fail "$label RERUN_FORBIDDEN journal flag"
[ "$(awk -F= '$1 == "AUTO_ROLLBACK" { print $2; found++ } END { if (found != 1) exit 1 }' "$status")" = NO ] || fail "$label AUTO_ROLLBACK journal flag"
fi
assert_selftest_source_unchanged
SELFTEST_PASSED=$((SELFTEST_PASSED + 1))
}
require_last_stderr_contains() {
stderr_root=$1
stderr_text=$2
stderr_surface=$(/bin/cat "$stderr_root/last.stderr") ||
fail "fake retained stderr unreadable"
case "$stderr_surface" in
*"$stderr_text"*) ;;
*) fail "fake retained stderr missing exact incident surface: $stderr_text" ;;
esac
}
run_fake_case() {
root=$1
package=$2
export S101_FAKE_LOG="$root/tool.log"
export S101_FAKE_STATE="$root/state"
S101_FAKE_MODE=1
unset S101_FAKE_SOURCE_VIEW || true
configure_fake_tools "$root"
run_flash_transaction "$package" /dev/disk99 "$root/mount" "$EXPECTED_AUTH"
}
run_fake_case_with_auth() {
root=$1
package=$2
authorization=$3
export S101_FAKE_LOG="$root/tool.log"
export S101_FAKE_STATE="$root/state"
S101_FAKE_MODE=1
unset S101_FAKE_SOURCE_VIEW || true
configure_fake_tools "$root"
run_flash_transaction "$package" /dev/disk99 "$root/mount" "$authorization"
}
run_fake_case_with_source_view() {
root=$1
package=$2
source_view=$3
export S101_FAKE_LOG="$root/tool.log"
export S101_FAKE_STATE="$root/state"
export S101_FAKE_SOURCE_VIEW="$source_view"
S101_FAKE_MODE=1
configure_fake_tools "$root"
run_flash_transaction "$package" /dev/disk99 "$root/mount" "$EXPECTED_AUTH"
}
run_fake_cp_without_suppression() {
fake_cp=$1
source=$2
destination=$3
unset COPYFILE_DISABLE || true
"$fake_cp" -X "$source" "$destination"
}
run_fake_cp_without_x() {
fake_cp=$1
source=$2
destination=$3
COPYFILE_DISABLE=1
export COPYFILE_DISABLE
"$fake_cp" "$source" "$destination"
}
prepare_fake_card_case() {
root=$1
source=$2
prepare_fake_tools "$root"
prepare_card_state "$root" "$source"
}
self_test() {
unset S101_FAKE_SOURCE_VIEW || true
script_dir=$(CDPATH= cd "$(dirname "$0")" && pwd -P)
canonical="$script_dir/../evidence/rpi5/g8h/sequence-100-package-staged/package"
s89="$script_dir/../evidence/rpi5/g8g/sequence-89-package-staged/package"
SELFTEST_CANONICAL=$canonical
SELFTEST_RECOVERY=$s89
if ! SELFTEST_CANONICAL_SNAPSHOT=$(package_metadata_snapshot "$SELFTEST_CANONICAL"); then
printf 'S101 INCIDENT GUARD: initial frozen S100 metadata snapshot failed\n' >&2
exit 1
fi
if ! SELFTEST_RECOVERY_SNAPSHOT=$(package_metadata_snapshot "$SELFTEST_RECOVERY"); then
printf 'S101 INCIDENT GUARD: initial frozen S89 metadata snapshot failed\n' >&2
exit 1
fi
SELFTEST_GUARD_ACTIVE=1
trap 'selftest_exit_guard $?' 0
trap 'exit 129' 1
trap 'exit 130' 2
trap 'exit 143' 15
selftest_root=$(mktemp -d /tmp/aselsanos-s101-flash-selftest.XXXXXX) || fail "self-test mktemp failed"
selftest_root=$(CDPATH= cd "$selftest_root" && pwd -P) || fail "self-test root unresolved"
SELFTEST_PASSED=0
SELFTEST_TOTAL=0
begin_selftest_fixture canonical-positive
validate_package_generic "$canonical"
assert_selftest_source_unchanged
SELFTEST_PASSED=$((SELFTEST_PASSED + 1))
begin_selftest_fixture recovery-positive
validate_s89_recovery_package "$s89"
assert_selftest_source_unchanged
SELFTEST_PASSED=$((SELFTEST_PASSED + 1))
begin_selftest_fixture alternate-source
mkdir "$selftest_root/alternate"
expect_red alternate-source resolve_frozen_package "$selftest_root/alternate"
begin_selftest_fixture recovery-missing
copy_package_fixture "$s89" "$selftest_root/recovery-missing"
COPYFILE_DISABLE=1 /bin/mv "$selftest_root/recovery-missing/config.txt" "$selftest_root/recovery-missing-config"
expect_red recovery-missing validate_s89_recovery_package "$selftest_root/recovery-missing"
begin_selftest_fixture recovery-extra
copy_package_fixture "$s89" "$selftest_root/recovery-extra"
: > "$selftest_root/recovery-extra/unexpected"
expect_red recovery-extra validate_s89_recovery_package "$selftest_root/recovery-extra"
begin_selftest_fixture recovery-mode
copy_package_fixture "$s89" "$selftest_root/recovery-mode"
chmod 644 "$selftest_root/recovery-mode/config.txt"
expect_red recovery-mode validate_s89_recovery_package "$selftest_root/recovery-mode"
begin_selftest_fixture recovery-hardlink
copy_package_fixture "$s89" "$selftest_root/recovery-hardlink"
/bin/ln "$selftest_root/recovery-hardlink/config.txt" "$selftest_root/recovery-hardlink-alias"
expect_red recovery-hardlink validate_s89_recovery_package "$selftest_root/recovery-hardlink"
begin_selftest_fixture recovery-hash
copy_package_fixture "$s89" "$selftest_root/recovery-hash"
chmod 644 "$selftest_root/recovery-hash/config.txt"
printf 'x' >> "$selftest_root/recovery-hash/config.txt"
chmod 444 "$selftest_root/recovery-hash/config.txt"
expect_red recovery-hash validate_s89_recovery_package "$selftest_root/recovery-hash"
begin_selftest_fixture recovery-symlink
copy_package_fixture "$s89" "$selftest_root/recovery-symlink"
COPYFILE_DISABLE=1 /bin/mv "$selftest_root/recovery-symlink/config.txt" "$selftest_root/recovery-symlink-target"
ln -s "$selftest_root/recovery-symlink-target" "$selftest_root/recovery-symlink/config.txt"
expect_red recovery-symlink validate_s89_recovery_package "$selftest_root/recovery-symlink"
begin_selftest_fixture extra-entry
copy_package_fixture "$canonical" "$selftest_root/extra"
: > "$selftest_root/extra/unexpected"
expect_red extra-entry validate_package_generic "$selftest_root/extra"
begin_selftest_fixture symlink
copy_package_fixture "$canonical" "$selftest_root/symlink"
/bin/rm "$selftest_root/symlink/config.txt"
COPYFILE_DISABLE=1 /bin/cp -X -p "$canonical/config.txt" "$selftest_root/symlink-target"
ln -s "$selftest_root/symlink-target" "$selftest_root/symlink/config.txt"
expect_red symlink validate_package_generic "$selftest_root/symlink"
begin_selftest_fixture mode
copy_package_fixture "$canonical" "$selftest_root/mode"
chmod 644 "$selftest_root/mode/config.txt"
expect_red mode validate_package_generic "$selftest_root/mode"
begin_selftest_fixture hash
copy_package_fixture "$canonical" "$selftest_root/hash"
chmod 644 "$selftest_root/hash/config.txt"
printf 'x' >> "$selftest_root/hash/config.txt"
expect_red hash validate_package_generic "$selftest_root/hash"
begin_selftest_fixture hardlink
COPYFILE_DISABLE=1 /bin/cp -X -p "$canonical/config.txt" "$selftest_root/hardlink-source"
/bin/ln "$selftest_root/hardlink-source" "$selftest_root/hardlink-alias"
expect_red hardlink require_distinct_inodes "$selftest_root/hardlink-source" "$selftest_root/hardlink-alias"
begin_selftest_fixture marker
printf 'ASELSAN/G8H0 ASELSAN/G8H1 ASELSAN/G8H2 ASELSAN/G8H3 ASELSAN/G8H4 ASELSAN/BOOT8H ASELSAN/G8HERR\n' > "$selftest_root/bad-markers"
expect_red markers validate_markers "$selftest_root/bad-markers"
begin_selftest_fixture manifest
printf 'bad manifest\n' > "$selftest_root/bad-manifest"
expect_red manifest validate_manifest_shape "$selftest_root/bad-manifest"
begin_selftest_fixture missing-copyfile-disable
missing_suppression="$selftest_root/missing-copyfile-disable"
prepare_fake_tools "$missing_suppression"
export S101_FAKE_LOG="$missing_suppression/tool.log"
export S101_FAKE_STATE="$missing_suppression/state"
expect_red missing-copyfile-disable run_fake_cp_without_suppression \
"$missing_suppression/bin/cp" "$missing_suppression/state/sidecar" "$missing_suppression/forbidden-output"
[ "$(fake_operation_count "$missing_suppression" cp)" -eq 1 ] || fail "missing suppression cp attempt count"
[ ! -e "$missing_suppression/forbidden-output" ] || fail "missing suppression mutated destination"
begin_selftest_fixture missing-copy-x
missing_x="$selftest_root/missing-copy-x"
prepare_fake_tools "$missing_x"
export S101_FAKE_LOG="$missing_x/tool.log"
export S101_FAKE_STATE="$missing_x/state"
expect_red missing-copy-x run_fake_cp_without_x \
"$missing_x/bin/cp" "$missing_x/state/sidecar" "$missing_x/forbidden-output"
[ "$(fake_operation_count "$missing_x" cp)" -eq 1 ] || fail "missing -X cp attempt count"
[ ! -e "$missing_x/forbidden-output" ] || fail "missing -X mutated destination"
begin_selftest_fixture fake-diskutil-argv
fake_diskutil_argv="$selftest_root/fake-diskutil-argv"
prepare_fake_tools "$fake_diskutil_argv"
export S101_FAKE_LOG="$fake_diskutil_argv/tool.log"
export S101_FAKE_STATE="$fake_diskutil_argv/state"
expect_red fake-diskutil-argv "$fake_diskutil_argv/bin/diskutil" info -plist /dev/disk98
[ "$(fake_operation_count "$fake_diskutil_argv" diskutil)" -eq 1 ] || fail "fake diskutil argv attempt count"
begin_selftest_fixture fake-ioreg-argv
fake_ioreg_argv="$selftest_root/fake-ioreg-argv"
prepare_fake_tools "$fake_ioreg_argv"
export S101_FAKE_LOG="$fake_ioreg_argv/tool.log"
export S101_FAKE_STATE="$fake_ioreg_argv/state"
expect_red fake-ioreg-argv "$fake_ioreg_argv/bin/ioreg" -r -l -w 0 -c WRONG
[ "$(fake_operation_count "$fake_ioreg_argv" ioreg)" -eq 1 ] || fail "fake ioreg argv attempt count"
begin_selftest_fixture fake-system-profiler-argv
fake_sp_argv="$selftest_root/fake-system-profiler-argv"
prepare_fake_tools "$fake_sp_argv"
export S101_FAKE_LOG="$fake_sp_argv/tool.log"
export S101_FAKE_STATE="$fake_sp_argv/state"
expect_red fake-system-profiler-argv "$fake_sp_argv/bin/system_profiler" SPCardReaderDataType -xml -detailLevel mini
[ "$(fake_operation_count "$fake_sp_argv" system_profiler)" -eq 1 ] || fail "fake system_profiler argv attempt count"
begin_selftest_fixture fake-sync-argv
fake_sync_argv="$selftest_root/fake-sync-argv"
prepare_fake_tools "$fake_sync_argv"
export S101_FAKE_LOG="$fake_sync_argv/tool.log"
export S101_FAKE_STATE="$fake_sync_argv/state"
expect_red fake-sync-argv "$fake_sync_argv/bin/sync" forbidden
[ "$(fake_operation_count "$fake_sync_argv" sync)" -eq 1 ] || fail "fake sync argv attempt count"
[ ! -s "$fake_sync_argv/state/sync.count" ] || fail "fake sync argv mutated sync state"
begin_selftest_fixture wrong-reader
wrong_reader="$selftest_root/wrong-reader"
prepare_fake_card_case "$wrong_reader" "$s89"
/usr/bin/plutil -replace MediaName -string SD64G "$wrong_reader/state/disk"
expect_fake_status wrong-reader 1 "$wrong_reader" 0 0 0 0 1 S89_META ABSENT \
run_fake_case "$wrong_reader" "$canonical"
begin_selftest_fixture internal
internal="$selftest_root/internal"
prepare_fake_card_case "$internal" "$s89"
/usr/bin/plutil -replace OSInternalMedia -bool true "$internal/state/disk"
expect_fake_status internal 1 "$internal" 0 0 0 0 1 S89_META ABSENT \
run_fake_case "$internal" "$canonical"
begin_selftest_fixture root-parent
root_parent="$selftest_root/root-parent"
prepare_fake_card_case "$root_parent" "$s89"
/usr/bin/plutil -replace ParentWholeDisk -string disk4 "$root_parent/state/root"
expect_fake_status root-parent 1 "$root_parent" 0 0 0 0 1 S89_META ABSENT \
run_fake_case "$root_parent" "$canonical"
begin_selftest_fixture partition-bool
partition_bool="$selftest_root/partition-bool"
prepare_fake_card_case "$partition_bool" "$s89"
/usr/bin/plutil -replace PartitionMapPartition -bool false "$partition_bool/state/mount"
expect_fake_status partition-bool 1 "$partition_bool" 0 0 0 0 1 S89_META ABSENT \
run_fake_case "$partition_bool" "$canonical"
begin_selftest_fixture disk-size
disk_size="$selftest_root/disk-size"
prepare_fake_card_case "$disk_size" "$s89"
/usr/bin/plutil -replace TotalSize -integer 1 "$disk_size/state/disk"
expect_fake_status disk-size 1 "$disk_size" 0 0 0 0 1 S89_META ABSENT \
run_fake_case "$disk_size" "$canonical"
begin_selftest_fixture uuid
uuid="$selftest_root/uuid"
prepare_fake_card_case "$uuid" "$s89"
/usr/bin/plutil -replace VolumeUUID -string 00000000-0000-0000-0000-000000000000 "$uuid/state/mount"
expect_fake_status uuid 1 "$uuid" 0 0 0 0 1 S89_META ABSENT \
run_fake_case "$uuid" "$canonical"
begin_selftest_fixture extra-partition
extra_partition="$selftest_root/extra-partition"
prepare_fake_card_case "$extra_partition" "$s89"
printf ' 2: DOS_FAT_32 EXTRA 16777216 B disk99s2\n' >> "$extra_partition/state/list"
expect_fake_status extra-partition 1 "$extra_partition" 0 0 0 0 1 S89_META ABSENT \
run_fake_case "$extra_partition" "$canonical"
begin_selftest_fixture duplicate-partition
duplicate_partition="$selftest_root/duplicate-partition"
prepare_fake_card_case "$duplicate_partition" "$s89"
printf ' 1: DOS_FAT_32 ASELSANBOOT 62532878336 B disk99s1\n' >> "$duplicate_partition/state/list"
expect_fake_status duplicate-partition 1 "$duplicate_partition" 0 0 0 0 1 S89_META ABSENT \
run_fake_case "$duplicate_partition" "$canonical"
begin_selftest_fixture suffixed-partition
suffixed_partition="$selftest_root/suffixed-partition"
prepare_fake_card_case "$suffixed_partition" "$s89"
sed 's/disk99s1$/disk99s1evil/' "$suffixed_partition/state/list" > "$suffixed_partition/state/list.new"
/bin/mv "$suffixed_partition/state/list.new" "$suffixed_partition/state/list"
expect_fake_status suffixed-partition 1 "$suffixed_partition" 0 0 0 0 1 S89_META ABSENT \
run_fake_case "$suffixed_partition" "$canonical"
begin_selftest_fixture bad-list-header
bad_list_header="$selftest_root/bad-list-header"
prepare_fake_card_case "$bad_list_header" "$s89"
sed '1s/(internal, physical)/(external, physical)/' "$bad_list_header/state/list" > "$bad_list_header/state/list.new"
COPYFILE_DISABLE=1 /bin/mv "$bad_list_header/state/list.new" "$bad_list_header/state/list"
expect_fake_status bad-list-header 1 "$bad_list_header" 0 0 0 0 1 S89_META ABSENT \
run_fake_case "$bad_list_header" "$canonical"
begin_selftest_fixture bad-list-whole-row
bad_list_whole="$selftest_root/bad-list-whole-row"
prepare_fake_card_case "$bad_list_whole" "$s89"
sed 's/FDisk_partition_scheme \*62.5 GB disk99/FDisk_partition_scheme *1.0 GB disk99/' \
"$bad_list_whole/state/list" > "$bad_list_whole/state/list.new"
COPYFILE_DISABLE=1 /bin/mv "$bad_list_whole/state/list.new" "$bad_list_whole/state/list"
expect_fake_status bad-list-whole-row 1 "$bad_list_whole" 0 0 0 0 1 S89_META ABSENT \
run_fake_case "$bad_list_whole" "$canonical"
begin_selftest_fixture sp-root-dict
sp_root_dict="$selftest_root/sp-root-dict"
prepare_fake_card_case "$sp_root_dict" "$s89"
sed -e 's#<plist version="1.0"><array><dict>#<plist version="1.0"><dict><key>0</key><dict>#' -e 's#</dict></array></plist>$#</dict></dict></plist>#' "$sp_root_dict/state/system-profiler" > "$sp_root_dict/state/system-profiler.new"
COPYFILE_DISABLE=1 /bin/mv "$sp_root_dict/state/system-profiler.new" "$sp_root_dict/state/system-profiler"
expect_fake_status sp-root-dict 1 "$sp_root_dict" 0 0 0 0 1 S89_META ABSENT \
run_fake_case "$sp_root_dict" "$canonical"
begin_selftest_fixture sp-wrong-reader
sp_wrong_reader="$selftest_root/sp-wrong-reader"
prepare_fake_card_case "$sp_wrong_reader" "$s89"
/usr/bin/plutil -replace 0._items.0._name -string spcardreader-wrong "$sp_wrong_reader/state/system-profiler"
expect_fake_status sp-wrong-reader 1 "$sp_wrong_reader" 0 0 0 0 1 S89_META ABSENT \
run_fake_case "$sp_wrong_reader" "$canonical"
begin_selftest_fixture sp-product
sp_product="$selftest_root/sp-product"
prepare_fake_card_case "$sp_product" "$s89"
/usr/bin/plutil -replace 0._items.0._items.0.spcardreader_card_productname -string TISD64GX "$sp_product/state/system-profiler"
expect_fake_status sp-product 1 "$sp_product" 0 0 0 0 1 S89_META ABSENT \
run_fake_case "$sp_product" "$canonical"
begin_selftest_fixture sp-serial
sp_serial="$selftest_root/sp-serial"
prepare_fake_card_case "$sp_serial" "$s89"
/usr/bin/plutil -replace 0._items.0._items.0.spcardreader_card_serialnumber -string 0x425001faDEAD "$sp_serial/state/system-profiler"
expect_fake_status sp-serial 1 "$sp_serial" 0 0 0 0 1 S89_META ABSENT \
run_fake_case "$sp_serial" "$canonical"
begin_selftest_fixture sp-card-bsd
sp_bsd="$selftest_root/sp-card-bsd"
prepare_fake_card_case "$sp_bsd" "$s89"
/usr/bin/plutil -replace 0._items.0._items.0.bsd_name -string disk98 "$sp_bsd/state/system-profiler"
expect_fake_status sp-card-bsd 1 "$sp_bsd" 0 0 0 0 1 S89_META ABSENT \
run_fake_case "$sp_bsd" "$canonical"
begin_selftest_fixture sp-volume-uuid
sp_uuid="$selftest_root/sp-volume-uuid"
prepare_fake_card_case "$sp_uuid" "$s89"
/usr/bin/plutil -replace 0._items.0._items.0.volumes.0.volume_uuid -string 00000000-0000-0000-0000-000000000000 "$sp_uuid/state/system-profiler"
expect_fake_status sp-volume-uuid 1 "$sp_uuid" 0 0 0 0 1 S89_META ABSENT \
run_fake_case "$sp_uuid" "$canonical"
begin_selftest_fixture sp-extra-card
sp_extra_card="$selftest_root/sp-extra-card"
prepare_fake_card_case "$sp_extra_card" "$s89"
/usr/bin/plutil -replace 0._items.0._items -json '[{},{}]' "$sp_extra_card/state/system-profiler"
expect_fake_status sp-extra-card 1 "$sp_extra_card" 0 0 0 0 1 S89_META ABSENT \
run_fake_case "$sp_extra_card" "$canonical"
begin_selftest_fixture sp-extra-reader
sp_extra_reader="$selftest_root/sp-extra-reader"
prepare_fake_card_case "$sp_extra_reader" "$s89"
/usr/bin/plutil -replace 0._items -json '[{},{}]' "$sp_extra_reader/state/system-profiler"
expect_fake_status sp-extra-reader 1 "$sp_extra_reader" 0 0 0 0 1 S89_META ABSENT \
run_fake_case "$sp_extra_reader" "$canonical"
begin_selftest_fixture sp-extra-volume
sp_extra_volume="$selftest_root/sp-extra-volume"
prepare_fake_card_case "$sp_extra_volume" "$s89"
/usr/bin/plutil -replace 0._items.0._items.0.volumes -json '[{},{}]' "$sp_extra_volume/state/system-profiler"
expect_fake_status sp-extra-volume 1 "$sp_extra_volume" 0 0 0 0 1 S89_META ABSENT \
run_fake_case "$sp_extra_volume" "$canonical"
begin_selftest_fixture ioreg-product
ioreg_product="$selftest_root/ioreg-product"
prepare_fake_card_case "$ioreg_product" "$s89"
sed 's/"Product Name"="SD64G"/"Product Name"="SD64GX"/' "$ioreg_product/state/ioreg" > "$ioreg_product/state/ioreg.new"
/bin/mv "$ioreg_product/state/ioreg.new" "$ioreg_product/state/ioreg"
expect_fake_status ioreg-product 1 "$ioreg_product" 0 0 0 0 1 S89_META ABSENT \
run_fake_case "$ioreg_product" "$canonical"
begin_selftest_fixture ioreg-serial
ioreg_serial="$selftest_root/ioreg-serial"
prepare_fake_card_case "$ioreg_serial" "$s89"
sed 's/"Serial Number"=1112539642,/"Serial Number"=0,/' "$ioreg_serial/state/ioreg" > "$ioreg_serial/state/ioreg.new"
/bin/mv "$ioreg_serial/state/ioreg.new" "$ioreg_serial/state/ioreg"
expect_fake_status ioreg-serial 1 "$ioreg_serial" 0 0 0 0 1 S89_META ABSENT \
run_fake_case "$ioreg_serial" "$canonical"
begin_selftest_fixture ioreg-serial-substring
ioreg_serial_substring="$selftest_root/ioreg-serial-substring"
prepare_fake_card_case "$ioreg_serial_substring" "$s89"
sed 's/"Serial Number"=1112539642,/"Serial Number"=11125396420,/' "$ioreg_serial_substring/state/ioreg" > "$ioreg_serial_substring/state/ioreg.new"
/bin/mv "$ioreg_serial_substring/state/ioreg.new" "$ioreg_serial_substring/state/ioreg"
expect_fake_status ioreg-serial-substring 1 "$ioreg_serial_substring" 0 0 0 0 1 S89_META ABSENT \
run_fake_case "$ioreg_serial_substring" "$canonical"
begin_selftest_fixture ioreg-sibling
ioreg_sibling="$selftest_root/ioreg-sibling"
prepare_fake_card_case "$ioreg_sibling" "$s89"
printf '%s\n' \
'+-o AppleSDXC <class AppleSDXC, id 0x1>' \
' +-o Port-SD Card@1 <class AppleSDXCSlot, id 0x2>' \
' | "Card Characteristics" = {"Product Name"="SD64G","Serial Number"=1112539642,"Other"=1}' \
' +-o Apple SDXC Reader Media <class IOMedia, id 0x5>' \
' | "Content" = "FDisk_partition_scheme"' \
' | "Removable" = Yes' \
' | "Whole" = Yes' \
' | "BSD Name" = "disk99"' \
' | "Ejectable" = Yes' \
' | "Writable" = Yes' \
' | "Size" = 62549655552' \
' | "BSD Unit" = 99' > "$ioreg_sibling/state/ioreg"
expect_fake_status ioreg-sibling 1 "$ioreg_sibling" 0 0 0 0 1 S89_META ABSENT \
run_fake_case "$ioreg_sibling" "$canonical"
begin_selftest_fixture ioreg-duplicate-property
ioreg_duplicate="$selftest_root/ioreg-duplicate-property"
prepare_fake_card_case "$ioreg_duplicate" "$s89"
sed 's/"Serial Number"=1112539642,/"Serial Number"=1112539642,"Serial Number"=1112539642,/' "$ioreg_duplicate/state/ioreg" > "$ioreg_duplicate/state/ioreg.new"
/bin/mv "$ioreg_duplicate/state/ioreg.new" "$ioreg_duplicate/state/ioreg"
expect_fake_status ioreg-duplicate-property 1 "$ioreg_duplicate" 0 0 0 0 1 S89_META ABSENT \
run_fake_case "$ioreg_duplicate" "$canonical"
begin_selftest_fixture ioreg-duplicate-bsd
ioreg_duplicate_bsd="$selftest_root/ioreg-duplicate-bsd"
prepare_fake_card_case "$ioreg_duplicate_bsd" "$s89"
awk '{ print; if ($0 == " | \"BSD Name\" = \"disk99\"") print " | \"BSD Name\" = \"disk99\"" }' \
"$ioreg_duplicate_bsd/state/ioreg" > "$ioreg_duplicate_bsd/state/ioreg.new"
/bin/mv "$ioreg_duplicate_bsd/state/ioreg.new" "$ioreg_duplicate_bsd/state/ioreg"
expect_fake_status ioreg-duplicate-bsd 1 "$ioreg_duplicate_bsd" 0 0 0 0 1 S89_META ABSENT \
run_fake_case "$ioreg_duplicate_bsd" "$canonical"
begin_selftest_fixture ioreg-wrong-class
ioreg_class="$selftest_root/ioreg-wrong-class"
prepare_fake_card_case "$ioreg_class" "$s89"
sed 's/Apple SDXC Reader Media <class IOMedia/Apple SDXC Reader Media <class IOService/' "$ioreg_class/state/ioreg" > "$ioreg_class/state/ioreg.new"
/bin/mv "$ioreg_class/state/ioreg.new" "$ioreg_class/state/ioreg"
expect_fake_status ioreg-wrong-class 1 "$ioreg_class" 0 0 0 0 1 S89_META ABSENT \
run_fake_case "$ioreg_class" "$canonical"
begin_selftest_fixture ioreg-whole-media-rename
ioreg_rename="$selftest_root/ioreg-whole-media-rename"
prepare_fake_card_case "$ioreg_rename" "$s89"
sed 's/Apple SDXC Reader Media <class IOMedia/Apple SDXC Reader Media Renamed <class IOMedia/' \
"$ioreg_rename/state/ioreg" > "$ioreg_rename/state/ioreg.new"
COPYFILE_DISABLE=1 /bin/mv "$ioreg_rename/state/ioreg.new" "$ioreg_rename/state/ioreg"
expect_fake_status ioreg-whole-media-rename 1 "$ioreg_rename" 0 0 0 0 1 S89_META ABSENT \
run_fake_case "$ioreg_rename" "$canonical"
begin_selftest_fixture ioreg-direct-child
ioreg_direct="$selftest_root/ioreg-direct-child"
prepare_fake_card_case "$ioreg_direct" "$s89"
awk '
/[+]-o Apple SDXC Reader Media/ { move = 1 }
move { sub(/^ /, "") }
{ print }
' "$ioreg_direct/state/ioreg" > "$ioreg_direct/state/ioreg.new"
COPYFILE_DISABLE=1 /bin/mv "$ioreg_direct/state/ioreg.new" "$ioreg_direct/state/ioreg"
expect_fake_status ioreg-direct-child 1 "$ioreg_direct" 0 0 0 0 1 S89_META ABSENT \
run_fake_case "$ioreg_direct" "$canonical"
begin_selftest_fixture ioreg-fake-bridge
ioreg_bridge="$selftest_root/ioreg-fake-bridge"
prepare_fake_card_case "$ioreg_bridge" "$s89"
awk '
/[+]-o Apple SDXC Reader Media/ {
print " +-o FakeBridge <class FakeBridge, id 0xdead>"
bridge = 1
}
bridge { print " " $0; next }
{ print }
' "$ioreg_bridge/state/ioreg" > "$ioreg_bridge/state/ioreg.new"
COPYFILE_DISABLE=1 /bin/mv "$ioreg_bridge/state/ioreg.new" "$ioreg_bridge/state/ioreg"
expect_fake_status ioreg-fake-bridge 1 "$ioreg_bridge" 0 0 0 0 1 S89_META ABSENT \
run_fake_case "$ioreg_bridge" "$canonical"
begin_selftest_fixture ioreg-wrong-intermediate
ioreg_intermediate="$selftest_root/ioreg-wrong-intermediate"
prepare_fake_card_case "$ioreg_intermediate" "$s89"
sed 's/IOBlockStorageDriver <class IOBlockStorageDriver/IOBlockStorageDriver <class IOService/' \
"$ioreg_intermediate/state/ioreg" > "$ioreg_intermediate/state/ioreg.new"
COPYFILE_DISABLE=1 /bin/mv "$ioreg_intermediate/state/ioreg.new" "$ioreg_intermediate/state/ioreg"
expect_fake_status ioreg-wrong-intermediate 1 "$ioreg_intermediate" 0 0 0 0 1 S89_META ABSENT \
run_fake_case "$ioreg_intermediate" "$canonical"
begin_selftest_fixture ioreg-size
ioreg_size="$selftest_root/ioreg-size"
prepare_fake_card_case "$ioreg_size" "$s89"
sed 's/"Size" = 62549655552/"Size" = 1/' "$ioreg_size/state/ioreg" > "$ioreg_size/state/ioreg.new"
/bin/mv "$ioreg_size/state/ioreg.new" "$ioreg_size/state/ioreg"
expect_fake_status ioreg-size 1 "$ioreg_size" 0 0 0 0 1 S89_META ABSENT \
run_fake_case "$ioreg_size" "$canonical"
begin_selftest_fixture metadata-missing
metadata_missing="$selftest_root/metadata-missing"
prepare_fake_card_case "$metadata_missing" "$s89"
/bin/mv "$metadata_missing/mount/._config.txt" "$metadata_missing/missing-sidecar"
expect_fake_status metadata-missing 1 "$metadata_missing" 0 0 0 0 1 MIXED ABSENT \
run_fake_case "$metadata_missing" "$canonical"
begin_selftest_fixture metadata-sidecar-wrong-size
sidecar_size="$selftest_root/metadata-sidecar-wrong-size"
prepare_fake_card_case "$sidecar_size" "$s89"
printf 'x' > "$sidecar_size/mount/._config.txt"
expect_fake_status metadata-sidecar-wrong-size 1 "$sidecar_size" 0 0 0 0 1 MIXED ABSENT \
run_fake_case "$sidecar_size" "$canonical"
begin_selftest_fixture metadata-sidecar-wrong-hash
sidecar_hash="$selftest_root/metadata-sidecar-wrong-hash"
prepare_fake_card_case "$sidecar_hash" "$s89"
LC_ALL=C /usr/bin/tr "\000" "\001" < "$sidecar_hash/mount/._config.txt" > "$sidecar_hash/sidecar-corrupt"
COPYFILE_DISABLE=1 /bin/mv "$sidecar_hash/sidecar-corrupt" "$sidecar_hash/mount/._config.txt"
expect_fake_status metadata-sidecar-wrong-hash 1 "$sidecar_hash" 0 0 0 0 1 MIXED ABSENT \
run_fake_case "$sidecar_hash" "$canonical"
begin_selftest_fixture metadata-sidecar-symlink
sidecar_symlink="$selftest_root/metadata-sidecar-symlink"
prepare_fake_card_case "$sidecar_symlink" "$s89"
COPYFILE_DISABLE=1 /bin/mv "$sidecar_symlink/mount/._config.txt" "$sidecar_symlink/original-sidecar"
ln -s "$sidecar_symlink/original-sidecar" "$sidecar_symlink/mount/._config.txt"
expect_fake_status metadata-sidecar-symlink 1 "$sidecar_symlink" 0 0 0 0 1 MIXED ABSENT \
run_fake_case "$sidecar_symlink" "$canonical"
begin_selftest_fixture metadata-sidecar-wrong-type
sidecar_type="$selftest_root/metadata-sidecar-wrong-type"
prepare_fake_card_case "$sidecar_type" "$s89"
COPYFILE_DISABLE=1 /bin/mv "$sidecar_type/mount/._config.txt" "$sidecar_type/original-sidecar"
mkdir "$sidecar_type/mount/._config.txt"
expect_fake_status metadata-sidecar-wrong-type 1 "$sidecar_type" 0 0 0 0 1 MIXED ABSENT \
run_fake_case "$sidecar_type" "$canonical"
begin_selftest_fixture metadata-sidecar-hardlink
sidecar_link="$selftest_root/metadata-sidecar-hardlink"
prepare_fake_card_case "$sidecar_link" "$s89"
/bin/ln "$sidecar_link/mount/._config.txt" "$sidecar_link/sidecar-alias"
expect_fake_status metadata-sidecar-hardlink 1 "$sidecar_link" 0 0 0 0 1 MIXED ABSENT \
run_fake_case "$sidecar_link" "$canonical"
begin_selftest_fixture metadata-spotlight-missing
spotlight_missing="$selftest_root/metadata-spotlight-missing"
prepare_fake_card_case "$spotlight_missing" "$s89"
COPYFILE_DISABLE=1 /bin/mv "$spotlight_missing/mount/.Spotlight-V100" "$spotlight_missing/missing-spotlight"
expect_fake_status metadata-spotlight-missing 1 "$spotlight_missing" 0 0 0 0 1 MIXED ABSENT \
run_fake_case "$spotlight_missing" "$canonical"
begin_selftest_fixture metadata-spotlight-wrong-type
spotlight_type="$selftest_root/metadata-spotlight-wrong-type"
prepare_fake_card_case "$spotlight_type" "$s89"
COPYFILE_DISABLE=1 /bin/mv "$spotlight_type/mount/.Spotlight-V100" "$spotlight_type/original-spotlight"
printf 'not a directory\n' > "$spotlight_type/mount/.Spotlight-V100"
expect_fake_status metadata-spotlight-wrong-type 1 "$spotlight_type" 0 0 0 0 1 MIXED ABSENT \
run_fake_case "$spotlight_type" "$canonical"
begin_selftest_fixture metadata-spotlight-symlink
spotlight_symlink="$selftest_root/metadata-spotlight-symlink"
prepare_fake_card_case "$spotlight_symlink" "$s89"
COPYFILE_DISABLE=1 /bin/mv "$spotlight_symlink/mount/.Spotlight-V100" "$spotlight_symlink/original-spotlight"
ln -s "$spotlight_symlink/original-spotlight" "$spotlight_symlink/mount/.Spotlight-V100"
expect_fake_status metadata-spotlight-symlink 1 "$spotlight_symlink" 0 0 0 0 1 MIXED ABSENT \
run_fake_case "$spotlight_symlink" "$canonical"
begin_selftest_fixture metadata-fseventsd-missing
fseventsd_missing="$selftest_root/metadata-fseventsd-missing"
prepare_fake_card_case "$fseventsd_missing" "$s89"
COPYFILE_DISABLE=1 /bin/mv "$fseventsd_missing/mount/.fseventsd" "$fseventsd_missing/missing-fseventsd"
expect_fake_status metadata-fseventsd-missing 1 "$fseventsd_missing" 0 0 0 0 1 MIXED ABSENT \
run_fake_case "$fseventsd_missing" "$canonical"
begin_selftest_fixture metadata-fseventsd-wrong-type
fseventsd_type="$selftest_root/metadata-fseventsd-wrong-type"
prepare_fake_card_case "$fseventsd_type" "$s89"
COPYFILE_DISABLE=1 /bin/mv "$fseventsd_type/mount/.fseventsd" "$fseventsd_type/original-fseventsd"
printf 'not a directory\n' > "$fseventsd_type/mount/.fseventsd"
expect_fake_status metadata-fseventsd-wrong-type 1 "$fseventsd_type" 0 0 0 0 1 MIXED ABSENT \
run_fake_case "$fseventsd_type" "$canonical"
begin_selftest_fixture metadata-fseventsd-symlink
fseventsd_symlink="$selftest_root/metadata-fseventsd-symlink"
prepare_fake_card_case "$fseventsd_symlink" "$s89"
COPYFILE_DISABLE=1 /bin/mv "$fseventsd_symlink/mount/.fseventsd" "$fseventsd_symlink/original-fseventsd"
ln -s "$fseventsd_symlink/original-fseventsd" "$fseventsd_symlink/mount/.fseventsd"
expect_fake_status metadata-fseventsd-symlink 1 "$fseventsd_symlink" 0 0 0 0 1 MIXED ABSENT \
run_fake_case "$fseventsd_symlink" "$canonical"
begin_selftest_fixture unexpected-ds-store
unexpected_ds="$selftest_root/unexpected-ds-store"
prepare_fake_card_case "$unexpected_ds" "$s89"
printf 'unexpected\n' > "$unexpected_ds/mount/.DS_Store"
expect_fake_status unexpected-ds-store 1 "$unexpected_ds" 0 0 0 0 1 MIXED ABSENT \
run_fake_case "$unexpected_ds" "$canonical"
begin_selftest_fixture post-move-temp-sidecar-retained
retained_temp_sidecar="$selftest_root/post-move-temp-sidecar-retained"
prepare_fake_card_case "$retained_temp_sidecar" "$s89"
: > "$retained_temp_sidecar/state/retain-temp-sidecar-after-first-move"
expect_fake_status post-move-temp-sidecar-retained 1 "$retained_temp_sidecar" 4 4 1 1 1 MIXED COMMIT_INTENT_1 \
run_fake_case "$retained_temp_sidecar" "$canonical"
begin_selftest_fixture temp-appledouble
temp_appledouble="$selftest_root/temp-appledouble"
prepare_fake_card_case "$temp_appledouble" "$s89"
COPYFILE_DISABLE=1 /bin/cp -X "$temp_appledouble/state/sidecar" \
"$temp_appledouble/mount/._.aselsanos-s101-aselsanos-rpi5.img.tmp"
expect_fake_status temp-appledouble 1 "$temp_appledouble" 0 0 0 0 1 MIXED ABSENT \
run_fake_case "$temp_appledouble" "$canonical"
begin_selftest_fixture post-copy-appledouble-wrong
post_copy_appledouble_wrong="$selftest_root/post-copy-appledouble-wrong"
prepare_fake_card_case "$post_copy_appledouble_wrong" "$s89"
: > "$post_copy_appledouble_wrong/state/corrupt-appledouble-after-first-copy"
expect_fake_status post-copy-appledouble-wrong 1 "$post_copy_appledouble_wrong" 1 0 0 0 1 MIXED PREPARED \
run_fake_case "$post_copy_appledouble_wrong" "$canonical"
begin_selftest_fixture authorization
authorization="$selftest_root/authorization"
prepare_fake_card_case "$authorization" "$s89"
expect_fake_status authorization 1 "$authorization" 0 0 0 0 0 S89_META ABSENT \
run_fake_case_with_auth "$authorization" "$canonical" WRONG_AUTH
begin_selftest_fixture already-applied
already="$selftest_root/already-applied"
prepare_fake_card_case "$already" "$canonical"
expect_fake_status already-applied 3 "$already" 0 0 0 0 1 S100_META ABSENT \
run_fake_case "$already" "$canonical"
begin_selftest_fixture mixed
mixed="$selftest_root/mixed"
prepare_fake_card_case "$mixed" "$s89"
COPYFILE_DISABLE=1 /bin/cp -X -p "$canonical/aselsanos-rpi5.img" "$mixed/mount/aselsanos-rpi5.img"
expect_fake_status mixed 1 "$mixed" 0 0 0 0 1 MIXED ABSENT \
run_fake_case "$mixed" "$canonical"
begin_selftest_fixture concurrency
concurrent="$selftest_root/concurrency"
prepare_fake_card_case "$concurrent" "$s89"
mkdir "$concurrent/locks/$LOCK_BASENAME"
expect_fake_status concurrency 1 "$concurrent" 0 0 0 0 1 S89_META PRESENT \
run_fake_case "$concurrent" "$canonical"
cp_position=0
while [ "$cp_position" -lt 4 ]; do
failure_position=$((cp_position + 1))
begin_selftest_fixture "cp-failure-$failure_position"
cp_failure="$selftest_root/cp-failure-$failure_position"
prepare_fake_card_case "$cp_failure" "$s89"
printf '%s\n' "$cp_position" > "$cp_failure/state/fail-cp-at"
if [ "$failure_position" -eq 1 ]; then
retained_state=S89_META
rerun_s89_root=$cp_failure
else
retained_state=MIXED
fi
expect_fake_status "cp-failure-$failure_position" 1 "$cp_failure" \
"$failure_position" 0 0 0 1 "$retained_state" PREPARED \
run_fake_case "$cp_failure" "$canonical"
cp_position=$((cp_position + 1))
done
cmp_position=0
while [ "$cmp_position" -lt 4 ]; do
failure_position=$((cmp_position + 1))
begin_selftest_fixture "cmp-failure-$failure_position"
cmp_failure="$selftest_root/cmp-failure-$failure_position"
prepare_fake_card_case "$cmp_failure" "$s89"
printf '%s\n' "$cmp_position" > "$cmp_failure/state/fail-cmp-at"
expect_fake_status "cmp-failure-$failure_position" 1 "$cmp_failure" \
4 "$failure_position" 0 0 1 PREPARED PREPARED \
run_fake_case "$cmp_failure" "$canonical"
assert_two_phase_retained "$cmp_failure"
[ "$failure_position" -ne 1 ] || rerun_prepared_root=$cmp_failure
cmp_position=$((cmp_position + 1))
done
begin_selftest_fixture staged-sync-failure
staged_sync="$selftest_root/staged-sync-failure"
prepare_fake_card_case "$staged_sync" "$s89"
printf '0\n' > "$staged_sync/state/fail-sync-at"
expect_fake_status staged-sync-failure 1 "$staged_sync" 4 4 0 1 1 PREPARED PREPARED \
run_fake_case "$staged_sync" "$canonical"
assert_two_phase_retained "$staged_sync"
begin_selftest_fixture per-copy-mount-swap
per_copy_swap="$selftest_root/per-copy-mount-swap"
prepare_fake_card_case "$per_copy_swap" "$s89"
: > "$per_copy_swap/state/swap-mount-after-first-copy"
expect_fake_status per-copy-mount-swap 1 "$per_copy_swap" 1 0 0 0 1 MIXED PREPARED \
run_fake_case "$per_copy_swap" "$canonical"
begin_selftest_fixture staged-mount-swap
staged_swap="$selftest_root/staged-mount-swap"
prepare_fake_card_case "$staged_swap" "$s89"
: > "$staged_swap/state/swap-on-first-sync"
expect_fake_status staged-mount-swap 1 "$staged_swap" 4 4 0 1 1 PREPARED PREPARED \
run_fake_case "$staged_swap" "$canonical"
begin_selftest_fixture temp-corruption
temp_corruption="$selftest_root/temp-corruption"
prepare_fake_card_case "$temp_corruption" "$s89"
printf '%s\n' "$temp_corruption/mount/.aselsanos-s101-aselsanos-rpi5.img.tmp" > "$temp_corruption/state/corrupt-temp-after-first-sync"
expect_fake_status temp-corruption 1 "$temp_corruption" 4 4 0 1 1 MIXED PREPARED \
run_fake_case "$temp_corruption" "$canonical"
mv_position=0
while [ "$mv_position" -lt 4 ]; do
failure_position=$((mv_position + 1))
begin_selftest_fixture "mv-failure-$failure_position"
mv_failure="$selftest_root/mv-failure-$failure_position"
prepare_fake_card_case "$mv_failure" "$s89"
printf '%s\n' "$mv_position" > "$mv_failure/state/fail-mv-at"
if [ "$failure_position" -eq 1 ]; then
retained_state=PREPARED
else
retained_state=MIXED
fi
expect_fake_status "mv-failure-$failure_position" 1 "$mv_failure" \
4 4 "$failure_position" 1 1 "$retained_state" "COMMIT_INTENT_$failure_position" \
run_fake_case "$mv_failure" "$canonical"
(SD_MOUNT="$mv_failure/mount"; require_commit_prefix_state "$mv_position")
mv_position=$((mv_position + 1))
done
begin_selftest_fixture post-commit-sync-failure
post_sync="$selftest_root/post-commit-sync-failure"
prepare_fake_card_case "$post_sync" "$s89"
printf '1\n' > "$post_sync/state/fail-sync-at"
expect_fake_status post-commit-sync-failure 1 "$post_sync" 4 4 4 2 1 S100_META COMMIT_DONE_4 \
run_fake_case "$post_sync" "$canonical"
begin_selftest_fixture post-commit-corruption
post_corruption="$selftest_root/post-commit-corruption"
prepare_fake_card_case "$post_corruption" "$s89"
printf '%s\n' "$post_corruption/mount/aselsanos-rpi5.img" > "$post_corruption/state/corrupt-final-after-second-sync"
expect_fake_status post-commit-corruption 1 "$post_corruption" 4 4 4 2 1 MIXED COMMIT_DONE_4 \
run_fake_case "$post_corruption" "$canonical"
final_cmp_position=0
while [ "$final_cmp_position" -lt 4 ]; do
failure_position=$((final_cmp_position + 1))
begin_selftest_fixture "final-cmp-failure-$failure_position"
final_cmp="$selftest_root/final-cmp-failure-$failure_position"
prepare_fake_card_case "$final_cmp" "$s89"
printf '%s\n' "$((4 + final_cmp_position))" > "$final_cmp/state/fail-cmp-at"
expect_fake_status "final-cmp-failure-$failure_position" 1 "$final_cmp" \
4 "$((4 + failure_position))" 4 2 1 S100_META COMMIT_DONE_4 \
run_fake_case "$final_cmp" "$canonical"
final_cmp_position=$((final_cmp_position + 1))
done
begin_selftest_fixture per-move-mount-swap
per_move_swap="$selftest_root/per-move-mount-swap"
prepare_fake_card_case "$per_move_swap" "$s89"
: > "$per_move_swap/state/swap-mount-after-first-move"
expect_fake_status per-move-mount-swap 1 "$per_move_swap" 4 4 1 1 1 MIXED COMMIT_DONE_1 \
run_fake_case "$per_move_swap" "$canonical"
begin_selftest_fixture source-view-corrupt
source_view="$selftest_root/source-view-corrupt"
prepare_fake_card_case "$source_view" "$s89"
copy_package_fixture "$canonical" "$source_view/source"
LC_ALL=C /usr/bin/tr "\000" "\001" < "$canonical/aselsanos-rpi5.img" > "$source_view/source/aselsanos-rpi5.img.corrupt"
/bin/mv "$source_view/source/aselsanos-rpi5.img.corrupt" "$source_view/source/aselsanos-rpi5.img"
chmod 444 "$source_view/source/aselsanos-rpi5.img"
expect_fake_status source-view-corrupt 1 "$source_view" 0 0 0 0 1 S89_META PREPARED \
run_fake_case_with_source_view "$source_view" "$canonical" "$source_view/source"
journal_fault_cases=0
while IFS='|' read -r fault_phase fault_slug expected_cp expected_cmp expected_mv expected_sync expected_card expected_lock expected_layout; do
for fault_point in journal-next-write journal-publish status-next-write status-publish; do
fault_label="journal-$fault_slug-$fault_point"
begin_selftest_fixture "$fault_label"
journal_fault="$selftest_root/$fault_label"
prepare_fake_card_case "$journal_fault" "$s89"
printf '%s:%s\n' "$fault_phase" "$fault_point" > "$journal_fault/state/fail-host-journal"
expect_fake_status "$fault_label" 1 "$journal_fault" \
"$expected_cp" "$expected_cmp" "$expected_mv" "$expected_sync" \
1 "$expected_card" "$expected_lock" \
run_fake_case "$journal_fault" "$canonical"
require_last_stderr_contains "$journal_fault" \
"injected host journal fault at $fault_phase:$fault_point"
require_expected_fake_layout "$journal_fault" "$expected_layout"
journal_fault_cases=$((journal_fault_cases + 1))
done
done <<'JOURNAL_FAULT_MATRIX'
PREPARED|prepared|0|0|0|0|S89_META|PRESENT|S89
STAGED|staged|4|4|0|1|PREPARED|PREPARED|P0
COMMIT_INTENT_1|intent-1|4|4|0|1|PREPARED|STAGED|P0
COMMIT_DONE_1|done-1|4|4|1|1|MIXED|COMMIT_INTENT_1|P1
COMMIT_INTENT_2|intent-2|4|4|1|1|MIXED|COMMIT_DONE_1|P1
COMMIT_DONE_2|done-2|4|4|2|1|MIXED|COMMIT_INTENT_2|P2
COMMIT_INTENT_3|intent-3|4|4|2|1|MIXED|COMMIT_DONE_2|P2
COMMIT_DONE_3|done-3|4|4|3|1|MIXED|COMMIT_INTENT_3|P3
COMMIT_INTENT_4|intent-4|4|4|3|1|MIXED|COMMIT_DONE_3|P3
COMMIT_DONE_4|done-4|4|4|4|1|S100_META|COMMIT_INTENT_4|P4
SUCCESS|success|4|8|4|2|S100_META|COMMIT_DONE_4|P4
JOURNAL_FAULT_MATRIX
[ "$journal_fault_cases" -eq 44 ] ||
fail "journal fault matrix mismatch: $journal_fault_cases/44"
begin_selftest_fixture rerun-s89-prepared-lock
expect_fake_status rerun-s89-prepared-lock 1 "$rerun_s89_root" 1 0 0 0 2 S89_META PREPARED \
run_fake_case "$rerun_s89_root" "$canonical"
require_last_stderr_contains "$rerun_s89_root" "retained transaction state requires explicit recovery review"
require_last_stderr_contains "$rerun_s89_root" "NEVER_BOOT=YES RERUN_FORBIDDEN=YES AUTO_ROLLBACK=NO"
begin_selftest_fixture rerun-prepared-card
expect_fake_status rerun-prepared-card 1 "$rerun_prepared_root" 4 1 0 0 2 PREPARED PREPARED \
run_fake_case "$rerun_prepared_root" "$canonical"
require_last_stderr_contains "$rerun_prepared_root" "retained transaction state requires explicit recovery review"
begin_selftest_fixture rerun-applied-unverified
expect_fake_status rerun-applied-unverified 1 "$post_sync" 4 4 4 2 2 S100_META COMMIT_DONE_4 \
run_fake_case "$post_sync" "$canonical"
require_last_stderr_contains "$post_sync" "APPLIED_UNVERIFIED"
require_last_stderr_contains "$post_sync" "NEVER_BOOT=YES RERUN_FORBIDDEN=YES AUTO_ROLLBACK=NO"
begin_selftest_fixture rerun-incident-mixed
expect_fake_status rerun-incident-mixed 1 "$post_corruption" 4 4 4 2 2 MIXED COMMIT_DONE_4 \
run_fake_case "$post_corruption" "$canonical"
require_last_stderr_contains "$post_corruption" "INCIDENT_MIXED"
require_last_stderr_contains "$post_corruption" "NEVER_BOOT=YES RERUN_FORBIDDEN=YES AUTO_ROLLBACK=NO"
begin_selftest_fixture positive
positive="$selftest_root/positive"
prepare_fake_card_case "$positive" "$s89"
printf 'opaque spotlight content changed and accepted\n' > "$positive/mount/.Spotlight-V100/Store-V2/opaque"
mkdir "$positive/mount/.fseventsd/opaque-subtree"
printf 'opaque descendant changed and accepted\n' > "$positive/mount/.fseventsd/opaque-subtree/content"
run_fake_case "$positive" "$canonical" >/dev/null
[ "$(fake_operation_count "$positive" cp)" -eq 4 ] || fail "self-test cp count"
[ "$(fake_operation_count "$positive" cmp)" -eq 8 ] || fail "self-test cmp count"
[ "$(fake_operation_count "$positive" mv)" -eq 4 ] || fail "self-test mv count"
[ "$(fake_operation_count "$positive" sync)" -eq 2 ] || fail "self-test sync count"
[ "$(fake_operation_count "$positive" system_profiler)" -eq 1 ] || fail "self-test system_profiler exact-once"
[ "$(fake_operation_count "$positive" diskutil)" -eq 48 ] || fail "self-test diskutil exact runtime count"
[ "$(fake_operation_count "$positive" ioreg)" -eq 12 ] || fail "self-test ioreg exact runtime count"
[ "$(classify_card_state)" = S100_META ] || fail "self-test positive final state"
[ "$(fake_lock_state "$positive")" = SUCCESS ] || fail "self-test positive retained lock state"
expected_full_trace=$(expected_positive_full_trace "$positive" "$PACKAGE_ROOT")
actual_full_trace=$(/bin/cat "$positive/trace.log")
[ "$actual_full_trace" = "$expected_full_trace" ] ||
fail "positive full exact 79-line interleaving transcript"
expected_positive_journal=$(expected_journal_through SUCCESS)
actual_positive_journal=$(/bin/cat "$positive/locks/$LOCK_BASENAME/journal")
[ "$actual_positive_journal" = "$expected_positive_journal" ] ||
fail "positive exact ordered 11-phase journal"
require_metadata_namespace
assert_selftest_source_unchanged
SELFTEST_PASSED=$((SELFTEST_PASSED + 1))
begin_selftest_fixture rerun-success
expect_fake_status rerun-success 3 "$positive" 4 8 4 2 2 S100_META SUCCESS \
run_fake_case "$positive" "$canonical"
require_last_stderr_contains "$positive" "S101 ALREADY_APPLIED"
[ "$SELFTEST_TOTAL" -eq 148 ] || fail "self-test fixture count mismatch: $SELFTEST_TOTAL"
[ "$SELFTEST_PASSED" -eq "$SELFTEST_TOTAL" ] || fail "self-test count mismatch: $SELFTEST_PASSED/$SELFTEST_TOTAL"
printf 'SELFTEST=148/148 POSITIVE=3/3 NEGATIVE=145/145 JOURNAL_FAULT_MATRIX=44/44 PHASES=11/11 POINTS=4/4\n'
printf 'SELFTEST_ROOT=%s RETAINED=YES REAL_DISKUTIL=0 REAL_IOREG=0 REAL_SYSTEM_PROFILER=0 REAL_VOLUMES=0 REAL_DEVICE_OPEN=0 REAL_SYNC=0 REAL_EJECT=0\n' "$selftest_root"
}
case "${1:-}" in
--verify-source-only)
[ "$#" -eq 2 ] || fail "--verify-source-only requires canonical package"
resolve_frozen_package "$2"
printf 'PASS: S101 frozen S100 source exact4 aggregate=%s markers6/6 G8HERR0\n' "$EXPECTED_PACKAGE_AGGREGATE_SHA256"
printf 'DEVICE_COMMANDS=0 DISKUTIL=0 IOREG=0 SYSTEM_PROFILER=0 VOLUMES=0 CP=0 MV=0 SYNC=0 CMP=0 DEVICE_OPEN=0 EJECT=0 UART=0 POWER=0\n'
;;
--self-test)
[ "$#" -eq 1 ] || fail "--self-test takes no arguments"
self_test
;;
--flash-from-env)
[ "$#" -eq 1 ] || fail "--flash-from-env takes no arguments"
[ "${S101_ENV_SD_DISK+x}" = x ] || fail "internal SD_DISK export missing"
[ "${S101_ENV_SD_MOUNT+x}" = x ] || fail "internal SD_MOUNT export missing"
[ "${S101_ENV_FLASH_AUTH+x}" = x ] || fail "internal authorization export missing"
unset S101_FAKE_MODE S101_FAKE_LOG S101_FAKE_STATE S101_FAKE_SOURCE_VIEW COPYFILE_DISABLE || true
configure_real_tools
script_dir=$(CDPATH= cd "$(dirname "$0")" && pwd -P) || fail "script directory unresolved"
canonical_package="$script_dir/../evidence/rpi5/g8h/sequence-100-package-staged/package"
run_flash_transaction "$canonical_package" \
"$S101_ENV_SD_DISK" "$S101_ENV_SD_MOUNT" "$S101_ENV_FLASH_AUTH"
;;
*)
printf 'Usage: %s --verify-source-only PACKAGE | --self-test | --flash-from-env\n' "$0" >&2
exit 2
;;
esac
snippet sha256: e6e76ea1e37c…file sha256: e6e76ea1e37c…
02 · Kapı kimlik kaydı
Operations sıra, kimlik ve başlık bağı
tam Operations kaydıL27739–L27773
website/src/lib/operations.ts::rpi5-g8h-s101-real-identity-v1-static-rejected
{
id: "rpi5-g8h-s101-real-identity-v1-static-rejected",
date: "2026-08-22",
sequence: 105,
status: "passed",
closure: {
status: "passed",
sequence: 110,
operation_id: "rpi5-g8h-s106-source-closure-green",
summary:
"S110 source closure, S105 v1 statik engellerini exact whole-media/provider zinciri, 44/44 fault matrisi, 79-line interleaving ve 13/13 + 148/148 kapılarıyla PASS olarak kapattı.",
},
title: "S101 gerçek kart uyarlaması v1 bağımsız statik auditte reddedildi",
summary:
"Salt-okunur S104 discovery olgularını helper'a taşıyan ilk gerçek-kimlik uyarlaması yürütülmeden donduruldu ve iki bağımsız reviewer tarafından adversarial incelendi. Typed system_profiler root/reader bağı, discovered ioreg ara provider zinciri ve gerçek diskutil komut grameri eksik olduğu için fake matrix gerçek macOS davranışını yanlış temsil edebilirdi. Metadata/journal tarafında da claim kapsamı test yüzeyinden genişti. Sonuç kaynak seviyesinde fail-closed STATIC STOP oldu; helper, self-test ve fiziksel kart yazma dalı hiç çalıştırılmadı.",
evidence: [
"Frozen v1 helper exact 88.939 B / 666172a7592daea183f35ae32b23b5e0a8b6f24b75720d881da1e7ead3eb4f4f.",
"Frozen v1 Rust source gate exact 40.236 B / f4abc49302b773b474e7a0042cbc527f6ac665ca9aa86e2940312609e3f298e0.",
"BLOCKER: system_profiler top-level array tipi ve exact reader `_name=spcardreader` bağı yoktu.",
"BLOCKER: ioreg yalnız kart ancestor'ını arıyor, discovered `AppleSDXC→AppleSDXCSlot→AppleSDXCBlockStorageDevice→IOBlockStorageDriver→IOMedia` immediate zincirini bağlamıyordu.",
"BLOCKER: fake diskutil arity/subcommand/target doğrulamadığından `info -plist` yerine yanlış bir komutu da testte kabul edebilirdi.",
"BLOCKER: diskutil list exact header/whole-disk satırı ve gerçek provider/client path olguları negative fixture'larda kapanmamıştı.",
"Transaction/metadata çekirdeğinde exact10/exact14, metadata6, cp suppression, manifest-last, recovery pointer ve no-cleanup yönleri olumlu; fakat bu alt GO'lar gerçek write GO değildir.",
"Reviewer verdict: STATIC STOP; source düzeltmesi ve yeni frozen audit olmadan fake/source rerun veya device branch yetkili değildir.",
],
commands: [
"read-only static audit frozen v1 flash helper",
"read-only static audit frozen v1 Rust source gate",
],
limitations: [
"Bu bir gerçek kart failure'ı değildir; kart üzerinde write=0, sync=0 ve eject=0'dır.",
"V1 üzerinde helper/self-test/device komutu çalıştırılmadı; yalnız source inspection yapıldı.",
"V1 bulguları v2 tasarım girdisidir; destructive microSD write yetkisi vermez.",
],
},snippet sha256: b21dec1b7dd5…file sha256: 9726dbf00f84…
Kayıtlı yürütme/kanıt komutu
read-only static audit frozen v1 flash helperRegistry schema v5 · generator
website/scripts/generate-code-gates.mjs · Tam SHA-256: 91d38c7b6222f0b4c117be786454853543da55a160e543d9b951057cc20dcc06