feat(protocol): native macOS arm64 support, Vervain-native AgentId #152

Merged
David merged 1 commit from feat/macos-arm64-agent-id into main 2026-07-28 10:26:02 +02:00
Owner

Apple Silicon had no AgentId at all. detect_agent_id() matched only macOS + x86_64, so a natively built arm64 agent fell through to Unknown = 0, which no self-update target matches. The build-macos recipe hardcoded x86_64-apple-darwin on the assumption Apple Silicon would run it under Rosetta 2, but Rosetta is not installed by default, so on a stock Apple Silicon Mac that binary fails to exec with bad CPU type in executable.

Replaces the MeshCentral-inherited agentcore.h id values with Vervain's own numbering, derived rather than arbitrary: id = os_base + arch, where os_base is linux-gnu 100 / linux-musl 110 / windows 200 / macos 300 and arch is x86_64 1 / aarch64 2 / x86 3 / arm 4. A new target's id now follows from its triple instead of being looked up in a header this project does not own, which is what let the macOS arm64 gap exist in the first place.

The mapping moves next to the enum as AgentId::for_build_target(), and an unmapped target is now a compile_error! naming what to add rather than a silent Unknown. Two tests pin the behaviour: the full value table (an existing id must never move, since it is both the self-update wire value and the vervainagent-<id> filename) and the os_base + arch rule itself.

build-macos now defaults to the host arch and adds the rustup target itself, so it produces a binary that runs on the machine you are on; pass a target explicitly to cross-build. build-macos.yml derives its target and published id from the runner's own uname -m (Apple Silicon publishes 302, Intel publishes 301) instead of hardcoding one id in twelve places, which also keeps the build native so the sign step can execute the binary it just built without needing Rosetta. check-macos-features.yml now compile-checks both arches.

Requires the matching vervain-server change (same-named branch): the server keeps its own copy of this enum plus a DEFAULT_AGENT_IDS fetch list, and both must move in lockstep or the published binary is never served.

Co-Authored-By: Claude Opus 5 noreply@anthropic.com

Apple Silicon had no `AgentId` at all. `detect_agent_id()` matched only macOS + x86_64, so a natively built arm64 agent fell through to `Unknown = 0`, which no self-update target matches. The `build-macos` recipe hardcoded `x86_64-apple-darwin` on the assumption Apple Silicon would run it under Rosetta 2, but Rosetta is not installed by default, so on a stock Apple Silicon Mac that binary fails to exec with `bad CPU type in executable`. Replaces the MeshCentral-inherited `agentcore.h` id values with Vervain's own numbering, derived rather than arbitrary: `id = os_base + arch`, where os_base is linux-gnu 100 / linux-musl 110 / windows 200 / macos 300 and arch is x86_64 1 / aarch64 2 / x86 3 / arm 4. A new target's id now follows from its triple instead of being looked up in a header this project does not own, which is what let the macOS arm64 gap exist in the first place. The mapping moves next to the enum as `AgentId::for_build_target()`, and an unmapped target is now a `compile_error!` naming what to add rather than a silent `Unknown`. Two tests pin the behaviour: the full value table (an existing id must never move, since it is both the self-update wire value and the `vervainagent-<id>` filename) and the `os_base + arch` rule itself. `build-macos` now defaults to the host arch and adds the rustup target itself, so it produces a binary that runs on the machine you are on; pass a target explicitly to cross-build. `build-macos.yml` derives its target and published id from the runner's own `uname -m` (Apple Silicon publishes 302, Intel publishes 301) instead of hardcoding one id in twelve places, which also keeps the build native so the sign step can execute the binary it just built without needing Rosetta. `check-macos-features.yml` now compile-checks both arches. Requires the matching vervain-server change (same-named branch): the server keeps its own copy of this enum plus a `DEFAULT_AGENT_IDS` fetch list, and both must move in lockstep or the published binary is never served. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
feat(protocol): native macOS arm64 support, Vervain-native AgentId
All checks were successful
Check / fmt + clippy + tests (pull_request) Successful in 5m8s
Create release / Create release from merged PR (pull_request) Has been skipped
4679268753
Apple Silicon had no `AgentId` at all. `detect_agent_id()` matched only macOS + x86_64, so a natively built arm64 agent fell through to `Unknown = 0`, which no self-update target matches. The `build-macos` recipe hardcoded `x86_64-apple-darwin` on the assumption Apple Silicon would run it under Rosetta 2, but Rosetta is not installed by default, so on a stock Apple Silicon Mac that binary fails to exec with `bad CPU type in executable`.

Replaces the MeshCentral-inherited `agentcore.h` id values with Vervain's own numbering, derived rather than arbitrary: `id = os_base + arch`, where os_base is linux-gnu 100 / linux-musl 110 / windows 200 / macos 300 and arch is x86_64 1 / aarch64 2 / x86 3 / arm 4. A new target's id now follows from its triple instead of being looked up in a header this project does not own, which is what let the macOS arm64 gap exist in the first place.

The mapping moves next to the enum as `AgentId::for_build_target()`, and an unmapped target is now a `compile_error!` naming what to add rather than a silent `Unknown`. Two tests pin the behaviour: the full value table (an existing id must never move, since it is both the self-update wire value and the `vervainagent-<id>` filename) and the `os_base + arch` rule itself.

`build-macos` now defaults to the host arch and adds the rustup target itself, so it produces a binary that runs on the machine you are on; pass a target explicitly to cross-build. `build-macos.yml` derives its target and published id from the runner's own `uname -m` (Apple Silicon publishes 302, Intel publishes 301) instead of hardcoding one id in twelve places, which also keeps the build native so the sign step can execute the binary it just built without needing Rosetta. `check-macos-features.yml` now compile-checks both arches.

Requires the matching vervain-server change (same-named branch): the server keeps its own copy of this enum plus a `DEFAULT_AGENT_IDS` fetch list, and both must move in lockstep or the published binary is never served.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
David scheduled this pull request to auto merge when all checks succeed 2026-07-28 10:21:00 +02:00
David merged commit 1a76d824e0 into main 2026-07-28 10:26:02 +02:00
David deleted branch feat/macos-arm64-agent-id 2026-07-28 10:26:02 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/vervain-agent!152
No description provided.