rdmsm4x-changelog-20260902-1734-tyrell-build11-headless-version-guard
Implemented and verified a source-only Tyrell Build 11 lifecycle guard so headless diagnostics return before SwiftUI/AppKit startup, while normal GUI launches retain single-instance enforcement.
Scope and why it matters
- Host changed:
rdmsm4xonly. - Project: Tyrell, Production mode.
- Ticket/owner:
ISSUE-20260902-15,codex@rdmsm4x/build11-headless-version-guard. - Exact base:
a5b057e1ebf5a461740f9df4997bf8f9f9ee5dbf. - Isolated worktree:
/Users/richh/dev/_worktrees/tyrell-build11-headless-version-guard-20260902. - Source/test commit:
23f3b4c1646c8f583f5a64aed3575683a7cdb8cf. - Expanded lifecycle-test commit:
4ce78d3e8169d0523450f4d19ae1769de1a9dc71. - Final HEAD:
817853e7e0d11e33b53c2690eb7700c7dab57a31.
The prior version check lived inside TyrellApp.init(),
after SwiftUI's application entry. Remote diagnostic shells exposed that
ordering by creating extra GUI trees on five Macs. The new executable
entry handles version, permission-health JSON, and canary modes first;
only normal GUI launch acquires and retains the app lock.
Files changed
/Users/richh/dev/_worktrees/tyrell-build11-headless-version-guard-20260902/Package.swift/Users/richh/dev/_worktrees/tyrell-build11-headless-version-guard-20260902/Sources/TyrellAppSupport/TyrellAppLaunchPolicy.swift/Users/richh/dev/_worktrees/tyrell-build11-headless-version-guard-20260902/Sources/tyrell-app/AppCanaryProbeRunner.swift/Users/richh/dev/_worktrees/tyrell-build11-headless-version-guard-20260902/Sources/tyrell-app/PermissionHealthDumpRunner.swift/Users/richh/dev/_worktrees/tyrell-build11-headless-version-guard-20260902/Sources/tyrell-app/TyrellAppMain.swift/Users/richh/dev/_worktrees/tyrell-build11-headless-version-guard-20260902/Sources/tyrell-app/TyrellExecutableMain.swift/Users/richh/dev/_worktrees/tyrell-build11-headless-version-guard-20260902/Tests/ScriptTests/tyrell_app_headless_lifecycle_test.zsh/Users/richh/dev/_worktrees/tyrell-build11-headless-version-guard-20260902/Tests/TyrellAppSupportTests/TyrellAppLaunchPolicyTests.swift/Users/richh/dev/_worktrees/tyrell-build11-headless-version-guard-20260902/SESSION-STATE.md/Users/richh/dev/_worktrees/tyrell-build11-headless-version-guard-20260902/ISSUES.md/Users/richh/dev/_handoff/tyrell-build11-headless-version-guard-20260902.md/Users/richh/dev/_handoff/tyrell-build11-headless-version-guard-evidence-20260902//Users/richh/.agent-coordination/checkins/codex-rdmsm4x-tyrell-build11-headless-version-guard-20260902.json
Commands and verification
swift build— exit 0.swift test— exit 0, 235 XCTest + 389 Swift Testing = 624/624, zero failures.swift build -c release --arch arm64 --arch x86_64 --product tyrell-app— exit 0.lipo -archs <release tyrell-app>—x86_64 arm64.zsh Tests/ScriptTests/tyrell_app_headless_lifecycle_test.zsh <candidate> "Tyrell 0.2.0 (8)"— passed for the universal release executable and independently thinned arm64 and x86_64 slices. Each run proved exact bounded version output, bounded valid permission-health JSON, bounded fail-closed canary usage exit 64, no diagnostic GUI lock or surviving PID, and normal duplicate-guard behavior.git diff --check— exit 0.
Final universal release executable SHA-256:
e46889f75a29dc577627a0b5c050a0cff140b892c549db69f398a59332243f12.
Evidence and exact log hashes are in
/Users/richh/dev/_handoff/tyrell-build11-headless-version-guard-20260902.md.
Backups, exclusions, and undo
No backup of a live artifact was needed because no installed app,
service, configuration, database, or canonical checkout changed. The
accepted Build 8 runtime remained untouched. Undo the source-only work
by reverting or discarding commits 23f3b4c,
25304a5, 4ce78d3, and 817853e
before integration.
No signing, installation, deployment, canary operation, credential
access, production network/CloudKit write, or installed-binary
diagnostic occurred. The next owner action is review/integration
followed by a new immutable signed universal artifact and the designated
rdmbair15m5 canary. Do not re-run installed
--version until a build containing the repair is
deployed.