Add macOS arm64 release artifact target

ober

727fd386f506d0bd516e6d10590f168ec5fa130e

diff --git a/Makefile b/Makefile
index 444f1f7..45273a6 100644
--- a/Makefile
+++ b/Makefile
@@ -80,7 +80,7 @@ help:
 	@echo "  install-policy-check Enforce no install-time code policy"
 	@echo "  tcb-report       Emit machine-readable TCB inventory"
 	@echo "  unification-check Run manifest/report/provenance/diff/audit checks"
-	@echo "  jerboa-portable  Build multicall release targets: linux-amd64, linux-arm64, freebsd-amd64"
+	@echo "  jerboa-portable  Build multicall release targets: macos-arm64, linux-amd64, linux-arm64, freebsd-amd64"
 	@echo "                   (cross targets need: make chez-cross CHEZ_TARGET_MACHINE=ta6le|tarm64le|ta6fb ...)"
 	@echo "  release-artifact Package one built target: RELEASE_VERSION=v0.1.0 RELEASE_TARGET=linux-amd64"
 	@echo "  release-artifacts Build/package all release targets"
@@ -106,13 +106,14 @@ help:
 	@echo "  pure-audit       Scan jerboa-* repos for non-pure runtime surfaces"
 	@echo ""
 	@echo "Cross-platform binaries (one static jerboa + jerbuild/jmcp/jlsp symlinks):"
+	@echo "  jerboa-macos-arm64    Build for macOS arm64                 -> dist/macos-arm64/"
 	@echo "  jerboa-linux-amd64    Cross-build for Linux x86_64 (musl)   -> dist/linux-amd64/"
 	@echo "  jerboa-linux-arm64    Cross-build for Linux arm64 (musl)     -> dist/linux-arm64/"
 	@echo "  jerboa-freebsd-amd64  Cross-build for FreeBSD amd64          -> dist/freebsd-amd64/"
 	@echo "  jerboa-cross          Generic: CHEZ_TARGET_MACHINE=<mt> CROSS_CC=<cc>"
 	@echo "                        (e.g. tarm64le -> dist/linux-arm64/, ta6fb -> freebsd-amd64)"
 	@echo "  jerbuild-cross        Cross-build standalone jerbuild-<mt>  (same args)"
-	@echo "  jerboa-portable       linux-amd64 + linux-arm64 + freebsd-amd64 in one shot"
+	@echo "  jerboa-portable       macos-arm64 + linux-amd64 + linux-arm64 + freebsd-amd64 in one shot"
 	@echo "  NOTE one-time per target: build the cross Chez first, e.g."
 	@echo "    make chez-cross CHEZ_TARGET_MACHINE=ta6le CROSS_CC=x86_64-linux-musl-gcc   # Linux amd64"
 	@echo ""
@@ -383,7 +384,7 @@ install:
 #
 # Generic form (builds the cross Chez on demand via chez-cross):
 #   make jerboa-cross CHEZ_TARGET_MACHINE=ta6le CROSS_CC=x86_64-linux-musl-gcc
-.PHONY: jerboa-cross jerboa-linux-amd64 jerboa-linux-arm64 jerboa-freebsd-amd64 jerboa-portable
+.PHONY: jerboa-cross jerboa-macos-arm64 jerboa-linux-amd64 jerboa-linux-arm64 jerboa-freebsd-amd64 jerboa-portable
 jerboa-cross: chez build mcp-check lsp-gen chez-cross
 	@test -n "$(CHEZ_TARGET_MACHINE)" \
 		|| { echo "ERROR: set CHEZ_TARGET_MACHINE=<machine-type>" >&2; exit 1; }
@@ -396,6 +397,17 @@ jerboa-cross: chez build mcp-check lsp-gen chez-cross
 
 # Convenience targets: build the cross Chez on demand (only if absent), then
 # the multicall. Re-running is fast once `.chez-cross-<m>` exists.
+jerboa-macos-arm64: jerboa
+	@case "$$(uname -s)-$$(uname -m)" in \
+		Darwin-arm64) ;; \
+		*) echo "ERROR: macos-arm64 release artifact must be built on macOS arm64" >&2; exit 1 ;; \
+	esac
+	@mkdir -p dist/macos-arm64
+	@cp -f dist/jerboa dist/macos-arm64/jerboa
+	@chmod 0755 dist/macos-arm64/jerboa
+	@for link in jmcp jlsp jerbuild jpkg; do ln -sf jerboa dist/macos-arm64/$$link; done
+	@echo "=== Staged jerboa multicall: macos-arm64 -> dist/macos-arm64/ ==="
+
 jerboa-linux-amd64: chez build mcp-check lsp-gen
 	@command -v x86_64-linux-musl-gcc >/dev/null 2>&1 || { echo "ERROR: x86_64-linux-musl-gcc not on PATH" >&2; exit 1; }
 	@if test ! -d "$(JERBOA_HOME)/.chez-cross-ta6le" || test ! -f "$(CHEZ_BUILD_DIR)/xc-ta6le/s/xpatch"; then \
@@ -436,15 +448,15 @@ jerboa-freebsd-amd64: chez build mcp-check lsp-gen
 		$(SCHEME) --script support/build-jerboa-multicall.ss
 
 # Release targets.
-jerboa-portable: jerboa-linux-amd64 jerboa-linux-arm64 jerboa-freebsd-amd64
+jerboa-portable: jerboa-macos-arm64 jerboa-linux-amd64 jerboa-linux-arm64 jerboa-freebsd-amd64
 
 # ── Release packaging for SourceHut tag artifacts ───────────────────────────
 # Native SourceHut jobs call `release-artifact` after `make jerboa`. Local
 # maintainers can call `release-artifacts` to cross-build and package all
 # supported bootstrap toolchains in one pass.
 RELEASE_VERSION ?= $(shell git describe --tags --exact-match 2>/dev/null || git describe --tags --always --dirty 2>/dev/null || echo dev)
-RELEASE_TARGET ?= $(shell case "$$(uname -s)-$$(uname -m)" in Linux-x86_64) echo linux-amd64 ;; Linux-aarch64|Linux-arm64) echo linux-arm64 ;; FreeBSD-amd64|FreeBSD-x86_64) echo freebsd-amd64 ;; *) echo unknown ;; esac)
-RELEASE_TARGETS ?= linux-amd64 linux-arm64 freebsd-amd64
+RELEASE_TARGET ?= $(shell case "$$(uname -s)-$$(uname -m)" in Darwin-arm64) echo macos-arm64 ;; Linux-x86_64) echo linux-amd64 ;; Linux-aarch64|Linux-arm64) echo linux-arm64 ;; FreeBSD-amd64|FreeBSD-x86_64) echo freebsd-amd64 ;; *) echo unknown ;; esac)
+RELEASE_TARGETS ?= macos-arm64 linux-amd64 linux-arm64 freebsd-amd64
 RELEASE_DIR ?= dist/release
 RELEASE_REPO ?= ~lisp/jerboa
 
diff --git a/docs/release-artifacts.md b/docs/release-artifacts.md
index 725d9e0..1c5cb8d 100644
--- a/docs/release-artifacts.md
+++ b/docs/release-artifacts.md
@@ -6,6 +6,7 @@ build without cloning and compiling this repository first.
 Each release target produces:
 
 ```text
+jerboa-vX.Y.Z-macos-arm64.tar.gz
 jerboa-vX.Y.Z-linux-amd64.tar.gz
 jerboa-vX.Y.Z-linux-arm64.tar.gz
 jerboa-vX.Y.Z-freebsd-amd64.tar.gz
@@ -30,6 +31,7 @@ make release-artifacts RELEASE_VERSION=v0.1.0
 This cross-builds and packages:
 
 ```text
+macos-arm64
 linux-amd64
 linux-arm64
 freebsd-amd64
@@ -39,8 +41,8 @@ The output lands in `dist/release/`.
 
 ## SourceHut CI
 
-The `.builds/release-*.yml` manifests build each release target natively on
-SourceHut:
+The `.builds/release-*.yml` manifests build Linux and FreeBSD release targets
+natively on SourceHut:
 
 ```text
 .builds/release-linux-amd64.yml
@@ -48,6 +50,10 @@ SourceHut:
 .builds/release-freebsd-amd64.yml
 ```
 
+The `macos-arm64` artifact is produced on an Apple Silicon macOS host with the
+same `make release-artifact RELEASE_TARGET=macos-arm64` packaging path, then
+uploaded to the release tag with `make release-upload`.
+
 They are constrained to `refs/tags/v*`, so ordinary branch pushes do not run
 the release builders. The build job uses SourceHut's `GIT_REF` environment
 variable to name the artifact, because the checkout itself is pinned by commit
diff --git a/support/ensure-jerboa.sh b/support/ensure-jerboa.sh
index 5700d7c..fcb7006 100755
--- a/support/ensure-jerboa.sh
+++ b/support/ensure-jerboa.sh
@@ -9,7 +9,7 @@
 # or the SourceHut repo with:
 #   JERBOA_RELEASE_REPO=~lisp/jerboa
 # For testing or unusual hosts, override target detection with:
-#   JERBOA_RELEASE_TARGET=linux-amd64
+#   JERBOA_RELEASE_TARGET=macos-arm64
 
 set -eu
 
@@ -30,6 +30,7 @@ else
     os=$(uname -s)
     arch=$(uname -m)
     case "$os-$arch" in
+        Darwin-arm64) target=macos-arm64 ;;
         Linux-x86_64|Linux-amd64) target=linux-amd64 ;;
         Linux-aarch64|Linux-arm64) target=linux-arm64 ;;
         FreeBSD-amd64|FreeBSD-x86_64) target=freebsd-amd64 ;;
@@ -41,7 +42,7 @@ else
 fi
 
 case "$target" in
-    linux-amd64|linux-arm64|freebsd-amd64) ;;
+    macos-arm64|linux-amd64|linux-arm64|freebsd-amd64) ;;
     *)
         echo "ERROR: unsupported release target: $target" >&2
         exit 1
diff --git a/support/package-jerboa-release.sh b/support/package-jerboa-release.sh
index 631a8c5..fa12464 100755
--- a/support/package-jerboa-release.sh
+++ b/support/package-jerboa-release.sh
@@ -5,7 +5,7 @@ set -eu
 
 usage() {
     echo "Usage: $0 VERSION TARGET [RELEASE_DIR]" >&2
-    echo "  TARGET: linux-amd64 | linux-arm64 | freebsd-amd64" >&2
+    echo "  TARGET: macos-arm64 | linux-amd64 | linux-arm64 | freebsd-amd64" >&2
 }
 
 [ "${1:-}" ] || { usage; exit 2; }
@@ -19,7 +19,7 @@ versioned="${release_dir}/${name}.tar.gz"
 alias_tar="${release_dir}/jerboa-${target}.tar.gz"
 
 case "$target" in
-    linux-amd64|linux-arm64|freebsd-amd64) ;;
+    macos-arm64|linux-amd64|linux-arm64|freebsd-amd64) ;;
     *)
         echo "ERROR: unsupported release target: $target" >&2
         exit 1
@@ -38,6 +38,7 @@ fi
 
 file_desc=$(file "$source_bin")
 case "$target:$file_desc" in
+    macos-arm64:*"Mach-O 64-bit executable arm64"*) ;;
     linux-amd64:*"ELF 64-bit LSB executable, x86-64"*) ;;
     linux-arm64:*"ELF 64-bit LSB executable, ARM aarch64"*) ;;
     freebsd-amd64:*"ELF 64-bit LSB executable, x86-64"*"FreeBSD"*) ;;