fix(codesign): Debug must sign WITHOUT runtime flag — AMFI rejects HR + adhoc

Debug builds were silently coming out (adhoc,runtime) despite project.yml
setting ENABLE_HARDENED_RUNTIME: NO and OTHER_CODE_SIGN_FLAGS: "" on the
Debug config. Two compounding bugs:

  1. project.yml's Debug-config OTHER_CODE_SIGN_FLAGS="" override didn't
     consistently propagate to the codesign.sh build-phase env (the
     parent Run Script env vs xcodegen-generated PBX project setting
     scope diverges).
  2. codesign.sh's ${OTHER_CODE_SIGN_FLAGS:-default} treats empty same as
     unset, re-introducing --options=runtime even if the override DID
     reach the script.

The combined effect: Hardened Runtime stayed ON, AMFI's strict
non-platform-Team-IDs-must-match rule fired against the adhoc-signed
Jarvis.debug.dylib, dyld aborted at __abort_with_payload (svc 0x209)
before any user code ran. App couldn't launch from Xcode (⌘R) or open.

Fix: explicit ${CONFIGURATION:-Release} == Debug branch in codesign.sh
that signs Debug with --timestamp=none and no runtime flag at all.
Result: Debug bundle is flags=0x2(adhoc) only — AMFI accepts it, app
launches, writes 'Jarvis launching' to system.log.

Also tried SWIFT_ENABLE_DEBUG_DYLIB: NO on Debug — the setting didn't
take in Xcode 26 (dylib still produced) but the codesign fix made that
moot. Kept the project.yml line as documentation; harmless if Xcode
ignores it.

Next blocker (Phase 1 self-check): app reaches main and logs
'Jarvis launching' but then hard-blocks on JarvisEntitlementsVerified
missing from Info.plist. That marker is supposed to be written by
verify-entitlements.sh --post-codesign. Investigate that script's
post-codesign Info.plist write path next session.
This commit is contained in:
james.maes committed 2026-04-26 07:18:21 -05:00
1 parent fa76fc64e6
commit 21644001b5
2 files changed
+20 -1

No files matched your search

+9
View File
@@ -111,6 +111,15 @@ targets:
# OTHER_CODE_SIGN_FLAGS must not carry `--options=runtime` on Debug —
# that flag enables HR regardless of ENABLE_HARDENED_RUNTIME. Strip it.
OTHER_CODE_SIGN_FLAGS: ""
# Disable Swift 6 / Xcode 26 incremental-link `Jarvis.debug.dylib`
# artifact entirely on Debug. The dylib gets a Team-ID context
# (from how Xcode's compile cache signs it) that diverges from the
# ad-hoc outer bundle; dyld then aborts at __abort_with_payload
# when the app tries to load it. With NO, Swift links the binary
# statically and there's no separate dylib to load.
# Trade-off: ~5-15% slower incremental Debug compile, but the app
# actually launches from Xcode's Run scheme (⌘R).
SWIFT_ENABLE_DEBUG_DYLIB: NO
Release:
DEVELOPMENT_TEAM: 7UC2HETAN9
CODE_SIGNING_ALLOWED: NO
+11 -1
View File
@@ -14,7 +14,17 @@ set -euo pipefail
APP="${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}"
HELPERS_DIR="${APP}/Contents/Helpers"
IDENTITY="${EXPANDED_CODE_SIGN_IDENTITY:-}"
FLAGS="${OTHER_CODE_SIGN_FLAGS:---options=runtime --timestamp}"
# Hardened Runtime + ad-hoc + restricted-entitlement-free Debug bundles
# still get rejected by AMFI on launch because the kernel's
# "non-platform Team IDs must match" rule fires when HR is on. Debug must
# sign WITHOUT --options=runtime regardless of what OTHER_CODE_SIGN_FLAGS
# inheritance produced (xcodegen Debug overrides don't always reach
# this script's env). Explicit per-config branch is the clearest fix.
if [ "${CONFIGURATION:-Release}" = "Debug" ]; then
FLAGS="--timestamp=none"
else
FLAGS="${OTHER_CODE_SIGN_FLAGS---options=runtime --timestamp}"
fi
if [ -z "${IDENTITY:-}" ]; then
echo "error: EXPANDED_CODE_SIGN_IDENTITY is empty — is CODE_SIGN_IDENTITY configured?" >&2