build: build gitsafe with installed jerbuild (no ~/mine/jerboa dependency)

ober

eef45f2feda3ae80f57c87107f16035caea3ede7

diff --git a/.jerbuild b/.jerbuild
index d6c38b5..4e2286b 100644
--- a/.jerbuild
+++ b/.jerbuild
@@ -1,8 +1,10 @@
-;; jerbuild build config for gitsafe.
+;; jerbuild build config for gitsafe: `jerbuild build`.
 ;; All paths are relative to this file.
+;;
+;; jerbuild bundles Chez Scheme + the jerboa stdlib, so this needs only
+;; jerbuild + a C compiler — no jerboa source checkout. Pure Jerboa: no
+;; jerboa-native-rs and no DuckDB.
 
 (entry  "gitsafe/main-binary.ss")
 (output "gitsafe-bin")
-(requires "cc")
-(notes "Pure Jerboa binary build. No jerboa-native-rs archive and no DuckDB are required.")
 (libdirs ".")
diff --git a/Dockerfile b/Dockerfile
deleted file mode 100644
index a8c5bbe..0000000
--- a/Dockerfile
+++ /dev/null
@@ -1,50 +0,0 @@
-# Dockerfile — Build gitsafe-musl using the jerboa21/jerboa base image
-#
-# Produces a fully static binary with zero runtime dependencies.
-# No Chez Scheme or Jerboa installation needed on the target host.
-#
-# The base image (jerboa21/jerboa) provides stock Chez, musl Chez,
-# jerboa libs, and all build dependencies pre-installed.
-#
-# Usage:
-#   docker build -t gitsafe-builder .
-#   docker run --rm gitsafe-builder > gitsafe-musl && chmod +x gitsafe-musl
-#
-# Or extract via docker cp:
-#   docker build -t gitsafe-builder .
-#   id=$(docker create gitsafe-builder)
-#   docker cp $id:/out/gitsafe-musl ./gitsafe-musl
-#   docker cp $id:/out/gitsafe-musl.sha256 ./gitsafe-musl.sha256
-#   docker rm $id
-
-FROM jerboa21/jerboa AS builder
-
-# ── Override stale baked-in Jerboa with host version ────────────────────────
-# The base image ships an older Jerboa; overlay it so the build sees the same
-# prelude exports (meta, atom?, etc.) as the local macOS build.
-COPY --from=jerboa . /build/mine/jerboa/
-
-# ── Copy gitsafe source ─────────────────────────────────────────────────────
-COPY . /build/mine/jerboa-gitsafe
-
-# ── Build gitsafe-musl ───────────────────────────────────────────────────────
-WORKDIR /build/mine/jerboa-gitsafe
-RUN make linux-local
-
-# ── Verify ───────────────────────────────────────────────────────────────────
-RUN ./gitsafe-musl --version
-RUN echo "--- Binary info ---" && \
-    ls -lh gitsafe-musl && \
-    file gitsafe-musl && \
-    echo "--- Hardening checks ---" && \
-    { file gitsafe-musl | grep -qE 'stripped|no section header' && echo "  PASS: stripped" || echo "  FAIL: not stripped"; } && \
-    { test -f gitsafe-musl.sha256 && echo "  PASS: integrity hash present" || echo "  FAIL: no hash"; } && \
-    echo "--- Path leak check ---" && \
-    count=$(strings gitsafe-musl | grep -c '/home/' || true) && \
-    { [ "$count" -gt 0 ] && echo "  WARNING: home paths found ($count)" || echo "  PASS: no home path leaks"; }
-
-# ── Output ───────────────────────────────────────────────────────────────────
-FROM ubuntu:24.04
-COPY --from=builder /build/mine/jerboa-gitsafe/gitsafe-musl /out/gitsafe-musl
-COPY --from=builder /build/mine/jerboa-gitsafe/gitsafe-musl.sha256 /out/gitsafe-musl.sha256
-CMD ["cat", "/out/gitsafe-musl"]
diff --git a/Makefile b/Makefile
index 21b7f82..1932d93 100644
--- a/Makefile
+++ b/Makefile
@@ -1,153 +1,56 @@
-JERBOA_HOME ?= $(realpath $(CURDIR)/../jerboa)
-SCHEME ?= $(JERBOA_HOME)/.chez/bin/scheme
+# jerbuild bundles Chez Scheme + the jerboa stdlib, so building gitsafe needs
+# only `jerbuild` + a C compiler — no jerboa source checkout and no separately
+# built Chez.
+JERBUILD ?= jerbuild
+JH := $(shell $(JERBUILD) --jerboa-home 2>/dev/null)
+ifeq ($(JH),)
+$(error jerbuild not found on PATH (or '$(JERBUILD) --jerboa-home' failed). Install jerbuild, or set JERBUILD=/path/to/jerbuild)
+endif
+
+LIBDIRS := --libdirs $(CURDIR):$(JH)/lib
+JEXEC   := $(JERBUILD) exec $(LIBDIRS)
+BIN     := gitsafe-bin
 BIN_DIR := $(HOME)/.local/bin
 TEMPLATE_DIR := $(HOME)/.git-templates
 HOOK_DIR := $(TEMPLATE_DIR)/hooks
 
-.PHONY: run test binary install clean linux linux-local docker \
-        verify-harden help install-native macos gitsafe-macos \
-        jerbuild-run jerbuild-test jerbuild-binary
-
+.PHONY: all build binary run test install clean help
 .DEFAULT_GOAL := help
 
-run:
-	JERBOA_HOME=$(JERBOA_HOME) \
-		$(SCHEME) -q --libdirs $(CURDIR):$(JERBOA_HOME)/lib --script gitsafe/main.ss -- $(ARGS)
+all: binary
 
+# Standalone native binary via .jerbuild (entry gitsafe/main-binary.ss).
 binary:
-	JERBOA_HOME=$(JERBOA_HOME) \
-		$(SCHEME) -q --libdirs $(CURDIR):$(JERBOA_HOME)/lib --script build-binary.ss
-
-test:
-	JERBOA_HOME=$(JERBOA_HOME) \
-		$(SCHEME) -q --libdirs $(CURDIR):$(JERBOA_HOME)/lib --script test/test-gitsafe.ss
-
-# ── jerbuild path: standalone, no jerboa checkout required ───────────────────
-# Uses a single self-contained `jerbuild` binary (Chez + Jerboa stdlib bundled).
-# Override JERBUILD=/path/to/jerbuild to point at it.
-JERBUILD ?= jerbuild
+	$(JERBUILD) build
 
-jerbuild-run:
-	@JH=$$($(JERBUILD) --jerboa-home); \
-	  env -u JERBOA_HOME $(JERBUILD) exec \
-	    --libdirs $(CURDIR):$$JH/lib gitsafe/main.ss -- $(ARGS)
+build: binary
 
-jerbuild-test:
-	@JH=$$($(JERBUILD) --jerboa-home); \
-	  env -u JERBOA_HOME $(JERBUILD) exec \
-	    --libdirs $(CURDIR):$$JH/lib test/test-gitsafe.ss
+run: binary
+	./$(BIN) $(ARGS)
 
-# Produce a standalone native gitsafe binary using only the jerbuild bundle
-# (no jerboa checkout, no Chez install). The resulting binary is self-contained.
-jerbuild-binary:
-	@JH=$$($(JERBUILD) --jerboa-home); \
-	  env -u JERBOA_HOME $(JERBUILD) binary \
-	    --libdirs $(CURDIR):$$JH/lib gitsafe/main.ss gitsafe-jerbuild
-	@echo ""
-	@ls -lh gitsafe-jerbuild
-	@file gitsafe-jerbuild
+test:
+	$(JEXEC) test/test-gitsafe.ss
 
-install: $(if $(filter Darwin,$(shell uname -s)),gitsafe-macos,linux)
+install: binary
 	mkdir -p $(BIN_DIR)
-ifeq ($(shell uname -s),Darwin)
-	cp gitsafe-macos $(BIN_DIR)/gitsafe
-	@echo "Installed gitsafe to $(BIN_DIR)/gitsafe (macOS binary)"
-else
-	cp gitsafe-musl $(BIN_DIR)/gitsafe
-	@echo "Installed gitsafe to $(BIN_DIR)/gitsafe (static binary)"
-endif
+	install -m 0755 $(BIN) $(BIN_DIR)/gitsafe
 	mkdir -p $(HOOK_DIR)
 	printf '#!/bin/sh\nexec gitsafe pre-commit\n' > $(HOOK_DIR)/pre-commit
 	chmod +x $(HOOK_DIR)/pre-commit
 	printf '#!/bin/sh\nwhile read local_ref local_sha remote_ref remote_sha; do\n  gitsafe pre-push --local-ref "$$local_ref" --remote-ref "$$remote_ref" || exit $$?\ndone\n' > $(HOOK_DIR)/pre-push
 	chmod +x $(HOOK_DIR)/pre-push
 	git config --global init.templateDir $(TEMPLATE_DIR)
-	@echo ""
-	@echo "Global git hooks installed:"
-	@echo "  $(HOOK_DIR)/pre-commit"
-	@echo "  $(HOOK_DIR)/pre-push"
-	@echo "  git config --global init.templateDir = $(TEMPLATE_DIR)"
-	@echo ""
-	@echo "All new repos (git init / git clone) will use gitsafe automatically."
-	@echo "To add to an existing repo: cd repo && git init"
+	@echo "Installed gitsafe to $(BIN_DIR)/gitsafe + global git hooks."
 
-install-native: binary
-	mkdir -p $(BIN_DIR)
-	cp gitsafe-bin $(BIN_DIR)/gitsafe
-	@echo "Installed gitsafe-bin to $(BIN_DIR)/gitsafe (native, requires Chez runtime)"
-
-# ── macOS binary (maximally static) ─────────────────────────────────────────
-# Statically links Chez kernel, lz4, zlib, ncurses.
-# Only libSystem (always present on macOS) and libiconv are dynamic.
-# Use `make macos` or `make gitsafe-macos` to build on macOS.
-
-macos: gitsafe-macos
-
-gitsafe-macos:
-	JERBOA_HOME=$(JERBOA_HOME) \
-		./build-gitsafe-macos.sh
-
-# ── Static musl binary ──────────────────────────────────────────────────────
-# Use `make linux` to build in Docker (canonical, reproducible).
-# Use `make linux-local` to build directly on the host (requires
-# musl-gcc and a musl-built Chez at ~/chez-musl or JERBOA_MUSL_CHEZ_PREFIX).
-
-linux: docker
-
-linux-local:
-	JERBOA_HOME=$(JERBOA_HOME) \
-		./build-gitsafe-musl.sh
-
-docker:
-	@echo "=== Building gitsafe-musl in Docker ==="
-	docker build --platform linux/amd64 --build-arg CACHE_BUST=$$(date +%s) --build-context jerboa=$(JERBOA_HOME) -t gitsafe-builder .
-	@id=$$(docker create --platform linux/amd64 gitsafe-builder) && \
-	docker cp $$id:/out/gitsafe-musl ./gitsafe-musl && \
-	docker cp $$id:/out/gitsafe-musl.sha256 ./gitsafe-musl.sha256 && \
-	docker rm $$id >/dev/null && \
-	chmod +x gitsafe-musl
-	@echo ""
-	@ls -lh gitsafe-musl
-	@file gitsafe-musl
-
-verify-harden: linux
-	@echo "=== Hardening verification ==="
-	@(file gitsafe-musl | grep -qE 'stripped|no section header') && echo "  PASS: binary is stripped" || echo "  FAIL: binary not stripped"
-	@if strings gitsafe-musl | grep -q "$(HOME)"; then \
-		echo "  WARN: home directory path found in binary"; \
-	else \
-		echo "  PASS: no home directory paths leaked"; \
-	fi
-	@if [ -f gitsafe-musl.sha256 ]; then \
-		echo "  PASS: gitsafe-musl.sha256 exists ($$(wc -c < gitsafe-musl.sha256) bytes)"; \
-	else \
-		echo "  FAIL: gitsafe-musl.sha256 not found"; \
-	fi
-	@./gitsafe-musl --version >/dev/null 2>&1 && echo "  PASS: binary runs" || echo "  FAIL: binary doesn't run"
-
-# ── Cleanup ──────────────────────────────────────────────────────────────────
 clean:
-	find . -name '*.so' -delete
-	find . -name '*.wpo' -delete
-	rm -f gitsafe-bin gitsafe-musl gitsafe-musl.sha256 gitsafe-macos gitsafe-macos.sha256 gitsafe-jerbuild
+	find . \( -name '*.so' -o -name '*.wpo' \) -delete 2>/dev/null || true
+	rm -f gitsafe-bin gitsafe-jerbuild
 
-# ── Help ─────────────────────────────────────────────────────────────────────
 help:
-	@echo "gitsafe — secret-scanning git hooks"
-	@echo ""
-	@echo "Development:"
-	@echo "  make run ARGS='...'           Run gitsafe in interpreter mode"
-	@echo "  make test                     Run test suite"
-	@echo ""
-	@echo "Build & install:"
-	@echo "  make macos                    macOS build (statically linked, no runtime deps)"
-	@echo "  make linux                    Linux static build via Docker (canonical)"
-	@echo "  make linux-local              Linux static build locally (requires musl-gcc)"
-	@echo "  make install                  Build + install to ~/.local/bin (auto-detects OS)"
-	@echo "  make verify-harden            Verify binary hardening (stripped, no leaks)"
-	@echo ""
-	@echo "Native binary (requires local Chez + Jerboa):"
-	@echo "  make binary                   Build gitsafe-bin (dynamic, native)"
-	@echo "  make install-native           Build native + install to ~/.local/bin"
+	@echo "gitsafe — secret-scanning git hooks (jerbuild + cc only)"
 	@echo ""
-	@echo "  make clean                    Remove all build artifacts"
+	@echo "  make binary           Build the standalone ./gitsafe-bin"
+	@echo "  make run ARGS='...'    Build + run ./gitsafe-bin"
+	@echo "  make test             Run the test suite"
+	@echo "  make install          Build + install to ~/.local/bin + global git hooks"
+	@echo "  make clean            Remove build artifacts"
diff --git a/build-gitsafe-macos.sh b/build-gitsafe-macos.sh
deleted file mode 100755
index 2c58b3f..0000000
--- a/build-gitsafe-macos.sh
+++ /dev/null
@@ -1,92 +0,0 @@
-#!/bin/bash
-# build-gitsafe-macos.sh — Build gitsafe as a maximally-static macOS binary
-#
-# Statically links: Chez kernel, lz4, zlib, ncurses
-# Dynamically links: libSystem (libc/libpthread — always present on macOS), libiconv
-#
-# Prerequisites:
-#   - Chez Scheme installed (brew install chezscheme)
-#   - Jerboa libraries available
-#   - Homebrew ncurses (brew install ncurses)
-#
-# Produces: ./gitsafe-macos (single binary, no Chez runtime needed at run time)
-set -euo pipefail
-
-SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
-
-# Resolve jerboa
-if [ -n "${JERBOA_HOME:-}" ]; then
-    JERBOA_LIB="${JERBOA_HOME}/lib"
-elif [ -d "${SCRIPT_DIR}/../jerboa/lib" ]; then
-    JERBOA_LIB="$(realpath "${SCRIPT_DIR}/../jerboa/lib")"
-elif [ -d "${HOME}/mine/jerboa/lib" ]; then
-    JERBOA_LIB="${HOME}/mine/jerboa/lib"
-else
-    echo "ERROR: Cannot find Jerboa. Set JERBOA_HOME."
-    exit 1
-fi
-export JERBOA_HOME="${JERBOA_HOME:-$(dirname "$JERBOA_LIB")}"
-SCHEME="${SCHEME:-${JERBOA_HOME}/.chez/bin/scheme}"
-
-echo "==================================="
-echo "Building gitsafe-macos (static libs)"
-echo "==================================="
-echo ""
-echo "Jerboa: $JERBOA_LIB"
-
-# Verify macOS
-if [ "$(uname -s)" != "Darwin" ]; then
-    echo "ERROR: This build script is for macOS only."
-    exit 1
-fi
-
-# Check Chez
-if [ ! -x "$SCHEME" ]; then
-    echo "ERROR: scheme not found at $SCHEME"
-    echo "Run 'make chez' in ${JERBOA_HOME} (or set SCHEME=... to override)."
-    exit 1
-fi
-
-echo "  scheme: $SCHEME ($("$SCHEME" --version 2>&1))"
-echo ""
-
-echo "[1/2] Validating macOS build environment..."
-
-# Check for ncurses static lib
-NCURSES_A=""
-for p in /opt/homebrew/opt/ncurses/lib /usr/local/opt/ncurses/lib; do
-    if [ -f "$p/libncurses.a" ]; then
-        NCURSES_A="$p/libncurses.a"
-        break
-    fi
-done
-if [ -z "$NCURSES_A" ]; then
-    echo "WARNING: static libncurses.a not found, will use dynamic -lncurses"
-    echo "  Install: brew install ncurses"
-fi
-export NCURSES_STATIC_PATH="${NCURSES_A}"
-echo "  ncurses: ${NCURSES_A:-dynamic}"
-echo ""
-
-echo "[2/2] Running macOS build..."
-"$SCHEME" -q --libdirs "${SCRIPT_DIR}:${JERBOA_LIB}" --script build-gitsafe-macos.ss
-
-# Verify
-if [ -f "gitsafe-macos" ]; then
-    echo ""
-    echo "==================================="
-    echo "gitsafe-macos built successfully!"
-    echo "==================================="
-    ls -lh gitsafe-macos
-    echo ""
-    file gitsafe-macos
-    echo ""
-    echo "Dynamic dependencies:"
-    otool -L gitsafe-macos 2>/dev/null | tail -n +2 || true
-    echo ""
-    echo "Test: ./gitsafe-macos --version"
-    ./gitsafe-macos --version || { echo "ERROR: binary smoke test failed"; exit 1; }
-else
-    echo "ERROR: gitsafe-macos not created"
-    exit 1
-fi
diff --git a/build-gitsafe-macos.ss b/build-gitsafe-macos.ss
deleted file mode 100644
index 4f1b887..0000000
--- a/build-gitsafe-macos.ss
+++ /dev/null
@@ -1,159 +0,0 @@
-#!chezscheme
-;; Build gitsafe as a maximally-static macOS binary.
-;;
-;; Usage: make macos
-;;   (runs via build-gitsafe-macos.sh -> this script)
-;;
-;; Statically links: Chez kernel, lz4, zlib, ncurses
-;; Dynamically links: libSystem (always present), libiconv
-;;
-;; macOS does not support fully static binaries (Apple linker requires
-;; libSystem.B.dylib), but this binary has zero third-party runtime deps.
-;;
-;; Produces: ./gitsafe-macos (single Mach-O binary, self-contained)
-
-(import (chezscheme))
-
-;; Load shared build logic (defines find-csv-dir and all step functions).
-;; jerboa-dir must be defined before any of the shared step functions are CALLED
-;; (not before this include — lambdas capture it lazily).
-(include "build-common.ss")
-
-;; --- Locate Chez install directory (macOS) ---
-(define chez-dir
-  (or (getenv "CHEZ_DIR")
-      (let ([mt   (symbol->string (machine-type))]
-            [home (getenv "HOME")])
-        (or (find-csv-dir (format "~a/.local/lib" home) mt)
-            (find-csv-dir "/opt/homebrew/lib" mt)
-            (find-csv-dir "/usr/local/lib" mt)))))
-
-(unless chez-dir
-  (display "Error: Cannot find Chez install dir. Set CHEZ_DIR.\n")
-  (exit 1))
-
-;; --- Locate Jerboa ---
-(define jerboa-dir
-  (or (getenv "JERBOA_HOME")
-      (let ([sibling (format "~a/../jerboa" (current-directory))])
-        (and (file-exists? sibling) sibling))
-      (begin
-        (display "Error: Cannot find Jerboa. Set JERBOA_HOME.\n")
-        (exit 1))))
-
-(printf "=== gitsafe macOS build ===\n")
-(printf "Chez dir:      ~a\n" chez-dir)
-(printf "Jerboa dir:    ~a\n" jerboa-dir)
-(printf "Machine type:  ~a\n" (machine-type))
-
-;; --- Steps 0–3: shared compile + WPO + boot file ---
-(setup-library-dirs!)
-(do-compile!)
-(define wpo-missing (do-wpo!))
-(do-boot! wpo-missing chez-dir)
-
-;; --- Step 4: Generate C main (macOS — no dlopen stubs needed) ---
-(printf "[4/6] Generating C main...\n")
-
-(call-with-output-file "gitsafe-main-macos.c"
-  (lambda (out)
-    (fprintf out "/* Auto-generated — do not edit */\n")
-    (fprintf out "#include <stdlib.h>\n")
-    (fprintf out "#include <stdio.h>\n")
-    (fprintf out "#include <string.h>\n")
-    (fprintf out "#include <unistd.h>\n")
-    (fprintf out "#include \"scheme.h\"\n")
-    (fprintf out "#include \"gitsafe_petite_boot.h\"\n")
-    (fprintf out "#include \"gitsafe_scheme_boot.h\"\n")
-    (fprintf out "#include \"gitsafe_boot.h\"\n")
-    (fprintf out "#include \"gitsafe_program.h\"\n")
-    (fprintf out "\n")
-    (fprintf out "int main(int argc, char *argv[]) {\n")
-    (fprintf out "  char prog_path[256];\n")
-    (fprintf out "  const char *tmpdir = getenv(\"TMPDIR\");\n")
-    (fprintf out "  if (!tmpdir) tmpdir = \"/tmp\";\n")
-    (display  "  snprintf(prog_path, sizeof(prog_path), \"%s/gitsafe-XXXXXX\", tmpdir);\n" out)
-    (fprintf out "  int fd = mkstemp(prog_path);\n")
-    (fprintf out "  if (fd < 0) { perror(\"mkstemp\"); return 1; }\n")
-    (fprintf out "  if (write(fd, gitsafe_program_data, gitsafe_program_size)\n")
-    (fprintf out "      != (ssize_t)gitsafe_program_size) {\n")
-    (fprintf out "    perror(\"write\"); close(fd); unlink(prog_path); return 1;\n")
-    (fprintf out "  }\n")
-    (fprintf out "  close(fd);\n")
-    (fprintf out "\n")
-    (fprintf out "  Sscheme_init(NULL);\n")
-    (fprintf out "  Sregister_boot_file_bytes(\"petite\", (void*)petite_boot_data, petite_boot_size);\n")
-    (fprintf out "  Sregister_boot_file_bytes(\"scheme\", (void*)scheme_boot_data, scheme_boot_size);\n")
-    (fprintf out "  Sregister_boot_file_bytes(\"gitsafe\", (void*)gitsafe_boot_data, gitsafe_boot_size);\n")
-    (fprintf out "  Sbuild_heap(NULL, NULL);\n")
-    (fprintf out "  int status = Sscheme_script(prog_path, argc, (const char **)argv);\n")
-    (fprintf out "  unlink(prog_path);\n")
-    (fprintf out "  Sscheme_deinit();\n")
-    (fprintf out "  return status;\n")
-    (fprintf out "}\n"))
-  'replace)
-
-;; --- Step 5: Compile and link (maximally static, macOS) ---
-(printf "[5/6] Compiling and linking (maximally static)...\n")
-
-(define kernel-a (format "~a/libkernel.a" chez-dir))
-(define chez-lz4-a (format "~a/liblz4.a" chez-dir))
-(define chez-z-a (format "~a/libz.a" chez-dir))
-
-(for-each
-  (lambda (pair)
-    (unless (file-exists? (cdr pair))
-      (printf "Error: ~a not found at ~a\n" (car pair) (cdr pair))
-      (exit 1)))
-  (list (cons "libkernel.a" kernel-a)
-        (cons "liblz4.a" chez-lz4-a)
-        (cons "libz.a" chez-z-a)))
-
-(define ncurses-a
-  (or (let ([p (getenv "NCURSES_STATIC_PATH")])
-        (and p (> (string-length p) 0) (file-exists? p) p))
-      (let ([p "/opt/homebrew/opt/ncurses/lib/libncurses.a"])
-        (and (file-exists? p) p))
-      (let ([p "/usr/local/opt/ncurses/lib/libncurses.a"])
-        (and (file-exists? p) p))))
-
-(printf "  Static libs:\n")
-(printf "    kernel:  ~a\n" kernel-a)
-(printf "    lz4:     ~a\n" chez-lz4-a)
-(printf "    zlib:    ~a\n" chez-z-a)
-(printf "    ncurses: ~a\n" (or ncurses-a "(dynamic fallback)"))
-
-(define static-libs
-  (string-append
-    kernel-a " " chez-lz4-a " " chez-z-a
-    (if ncurses-a (string-append " " ncurses-a) "")))
-
-(define dynamic-libs
-  (string-append
-    (if ncurses-a "" " -lncurses")
-    " -liconv -lpthread -lm"))
-
-(let ([cc (or (getenv "CC") "cc")])
-  (let ([rc (system (format "~a -c -O2 -I~a -o gitsafe-main-macos.o gitsafe-main-macos.c"
-                            cc chez-dir))])
-    (unless (= rc 0) (printf "Error: C compilation failed\n") (exit 1)))
-  (let* ([cmd (format "~a -o gitsafe-macos gitsafe-main-macos.o ~a~a"
-                      cc static-libs dynamic-libs)])
-    (printf "  Link: ~a\n" cmd)
-    (let ([rc (system cmd)])
-      (unless (= rc 0) (printf "Error: linking failed\n") (exit 1)))))
-
-(printf "  Stripping binary...\n")
-(system "strip -x gitsafe-macos")
-(system "shasum -a 256 gitsafe-macos > gitsafe-macos.sha256")
-
-;; --- Step 6: Cleanup ---
-(do-cleanup! "macos")
-
-(printf "\nDone! Binary: ./gitsafe-macos\n")
-(printf "  Size:   ")
-(system "ls -lh gitsafe-macos | awk '{print $5}'")
-(printf "  SHA256: ")
-(system "cat gitsafe-macos.sha256")
-(printf "\n  Test:   ./gitsafe-macos --version\n")
-(printf "  Deps:   otool -L gitsafe-macos\n")
diff --git a/build-gitsafe-musl.sh b/build-gitsafe-musl.sh
deleted file mode 100755
index 59ec647..0000000
--- a/build-gitsafe-musl.sh
+++ /dev/null
@@ -1,73 +0,0 @@
-#!/bin/bash
-# build-gitsafe-musl.sh — Build gitsafe as a fully static binary using musl libc
-#
-# Prerequisites:
-#   - musl-gcc installed (apt install musl-tools)
-#   - Chez Scheme built with: ./configure --threads --static CC=musl-gcc
-#     and installed to ~/chez-musl (or set JERBOA_MUSL_CHEZ_PREFIX)
-#   - Jerboa libraries available
-#
-# The build uses stock scheme (glibc) for the Scheme compilation steps,
-# then musl-gcc for the C compilation and linking steps.
-set -euo pipefail
-
-SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
-
-# Resolve jerboa
-if [ -n "${JERBOA_HOME:-}" ]; then
-    JERBOA_LIB="${JERBOA_HOME}/lib"
-elif [ -d "${SCRIPT_DIR}/../jerboa/lib" ]; then
-    JERBOA_LIB="$(realpath "${SCRIPT_DIR}/../jerboa/lib")"
-elif [ -d "${HOME}/mine/jerboa/lib" ]; then
-    JERBOA_LIB="${HOME}/mine/jerboa/lib"
-else
-    echo "ERROR: Cannot find Jerboa. Set JERBOA_HOME."
-    exit 1
-fi
-export JERBOA_HOME="${JERBOA_HOME:-$(dirname "$JERBOA_LIB")}"
-SCHEME="${SCHEME:-${JERBOA_HOME}/.chez/bin/scheme}"
-if [ ! -x "$SCHEME" ]; then
-    echo "ERROR: scheme not found at $SCHEME" >&2
-    echo "Run 'make chez' in ${JERBOA_HOME} (or set SCHEME=... to override)." >&2
-    exit 1
-fi
-
-echo "==================================="
-echo "Building gitsafe-musl (static)"
-echo "==================================="
-echo ""
-echo "Jerboa: $JERBOA_LIB"
-echo ""
-
-# Check musl availability
-if ! command -v musl-gcc &>/dev/null; then
-    echo "ERROR: musl-gcc not found"
-    echo "Install: sudo apt install musl-tools"
-    exit 1
-fi
-
-echo "[1/2] Validating musl toolchain..."
-echo "  musl-gcc: $(command -v musl-gcc)"
-echo ""
-
-echo "[2/2] Running musl build..."
-"$SCHEME" -q --libdirs "${SCRIPT_DIR}:${JERBOA_LIB}" --script build-gitsafe-musl.ss
-
-# Verify
-if [ -f "gitsafe-musl" ]; then
-    echo ""
-    echo "==================================="
-    echo "gitsafe-musl built successfully!"
-    echo "==================================="
-    ls -lh gitsafe-musl
-    echo ""
-    file gitsafe-musl
-    echo ""
-    ldd gitsafe-musl 2>&1 || echo "  (Fully static — no dynamic dependencies)"
-    echo ""
-    echo "Test: ./gitsafe-musl --version"
-    ./gitsafe-musl --version || { echo "ERROR: binary smoke test failed"; exit 1; }
-else
-    echo "ERROR: gitsafe-musl not created"
-    exit 1
-fi
diff --git a/build-gitsafe-musl.ss b/build-gitsafe-musl.ss
deleted file mode 100644
index d12ec6c..0000000
--- a/build-gitsafe-musl.ss
+++ /dev/null
@@ -1,164 +0,0 @@
-#!chezscheme
-;; Build gitsafe as a fully static binary using musl libc.
-;;
-;; Usage: make linux-local
-;;   (runs via build-gitsafe-musl.sh → this script)
-;;
-;; Prerequisites:
-;;   - musl-gcc installed (apt install musl-tools)
-;;   - Chez Scheme built with: ./configure --threads --static CC=musl-gcc
-;;     installed to ~/chez-musl (or set JERBOA_MUSL_CHEZ_PREFIX)
-;;   - Stock scheme (glibc) for the compilation steps
-;;
-;; Produces: ./gitsafe-musl (fully static ELF binary, zero runtime dependencies)
-
-(import (chezscheme))
-
-;; Load shared build logic (defines find-csv-dir and all step functions).
-;; jerboa-dir must be defined before any of the shared step functions are CALLED
-;; (not before this include — lambdas capture it lazily).
-(include "build-common.ss")
-
-;; --- Locate musl-built Chez Scheme ---
-(define musl-chez-prefix
-  (or (getenv "JERBOA_MUSL_CHEZ_PREFIX")
-      (let* ([home (getenv "HOME")]
-             [p (format "~a/chez-musl" home)])
-        (and (file-exists? p) p))))
-
-(unless musl-chez-prefix
-  (display "Error: Cannot find musl Chez install.\n")
-  (display "  Set JERBOA_MUSL_CHEZ_PREFIX or install to ~/chez-musl\n")
-  (display "  See: https://git.sr.ht/~lisp/jerboa (vendor/ChezScheme — build with --static CC=musl-gcc)\n")
-  (exit 1))
-
-(define musl-chez-dir
-  (let ([mt (symbol->string (machine-type))])
-    (or (find-csv-dir (format "~a/lib" musl-chez-prefix) mt)
-        (begin
-          (printf "Error: Cannot find Chez ~a dir under ~a/lib\n"
-                  (machine-type) musl-chez-prefix)
-          (printf "  Expected: ~a/lib/csv<version>/~a/main.o\n"
-                  musl-chez-prefix mt)
-          (exit 1)))))
-
-;; --- Locate Jerboa ---
-(define jerboa-dir
-  (or (getenv "JERBOA_HOME")
-      (let ([sibling (format "~a/../jerboa" (current-directory))])
-        (and (file-exists? sibling) sibling))
-      (begin
-        (display "Error: Cannot find Jerboa. Set JERBOA_HOME.\n")
-        (exit 1))))
-
-(printf "=== gitsafe musl static build ===\n")
-(printf "Musl Chez dir: ~a\n" musl-chez-dir)
-(printf "Jerboa dir:    ~a\n" jerboa-dir)
-(printf "Machine type:  ~a\n" (machine-type))
-
-;; --- Steps 0–3: shared compile + WPO + boot file ---
-;; Boot files come from the musl Chez (ABI must match the musl kernel).
-(setup-library-dirs!)
-(do-compile!)
-(define wpo-missing (do-wpo!))
-(do-boot! wpo-missing musl-chez-dir)
-
-;; --- Step 4: Generate C main (musl — with dlopen stubs + Sforeign_symbol) ---
-;;
-;; dlopen(NULL, ...) returns a fake self-handle so Chez can query its own
-;; symbol table. All other dlopen calls return NULL, causing
-;; (load-shared-object "libjerboa_native.so") in (std regex) to throw an
-;; exception that the guard catches → native-available? = #f → all regex
-;; falls back to the pure-Scheme pregexp engine.
-;;
-;; Sforeign_symbol MUST be called after Sbuild_heap (the foreign entry table
-;; is not initialized until then). We register the three Rust regex symbols
-;; with a harmless C stub so (std regex)'s (foreign-procedure ...) forms
-;; succeed at WPO program init. The stub returns -1 but is never called
-;; because native-available? = #f prevents all native regex code paths.
-(printf "[4/6] Generating C main...\n")
-
-(call-with-output-file "gitsafe-main-musl.c"
-  (lambda (out)
-    (fprintf out "/* Auto-generated — do not edit */\n")
-    (fprintf out "#define _GNU_SOURCE\n")
-    (fprintf out "#include <stdlib.h>\n")
-    (fprintf out "#include <stdio.h>\n")
-    (fprintf out "#include <string.h>\n")
-    (fprintf out "#include <unistd.h>\n")
-    (fprintf out "#include \"scheme.h\"\n")
-    (fprintf out "#include \"gitsafe_petite_boot.h\"\n")
-    (fprintf out "#include \"gitsafe_scheme_boot.h\"\n")
-    (fprintf out "#include \"gitsafe_boot.h\"\n")
-    (fprintf out "#include \"gitsafe_program.h\"\n")
-    (fprintf out "\n")
-    (fprintf out "/* dlopen/dlsym stubs — fully static musl binary, no dynamic libraries */\n")
-    (fprintf out "static int _jerboa_native_stub(void) { return -1; }\n")
-    (fprintf out "void *dlopen(const char *f, int m) { (void)m; return (!f) ? (void*)1 : NULL; }\n")
-    (fprintf out "void *dlsym(void *h, const char *s) {\n")
-    (fprintf out "  (void)h;\n")
-    (fprintf out "  if (s && (strcmp(s, \"jerboa_regex_compile\") == 0 ||\n")
-    (fprintf out "            strcmp(s, \"jerboa_regex_find\") == 0 ||\n")
-    (fprintf out "            strcmp(s, \"jerboa_regex_free\") == 0))\n")
-    (fprintf out "    return (void *)_jerboa_native_stub;\n")
-    (fprintf out "  return NULL;\n")
-    (fprintf out "}\n")
-    (fprintf out "int dlclose(void *h) { (void)h; return 0; }\n")
-    (fprintf out "char *dlerror(void) { return \"static build\"; }\n")
-    (fprintf out "\n")
-    (fprintf out "int main(int argc, char *argv[]) {\n")
-    (fprintf out "  char prog_path[256];\n")
-    (fprintf out "  const char *tmpdir = getenv(\"TMPDIR\");\n")
-    (fprintf out "  if (!tmpdir) tmpdir = \"/tmp\";\n")
-    (display  "  snprintf(prog_path, sizeof(prog_path), \"%s/gitsafe-XXXXXX\", tmpdir);\n" out)
-    (fprintf out "  int fd = mkstemp(prog_path);\n")
-    (fprintf out "  if (fd < 0) { perror(\"mkstemp\"); return 1; }\n")
-    (fprintf out "  if (write(fd, gitsafe_program_data, gitsafe_program_size)\n")
-    (fprintf out "      != (ssize_t)gitsafe_program_size) {\n")
-    (fprintf out "    perror(\"write\"); close(fd); unlink(prog_path); return 1;\n")
-    (fprintf out "  }\n")
-    (fprintf out "  close(fd);\n")
-    (fprintf out "\n")
-    (fprintf out "  Sscheme_init(NULL);\n")
-    (fprintf out "  Sregister_boot_file_bytes(\"petite\", (void*)petite_boot_data, petite_boot_size);\n")
-    (fprintf out "  Sregister_boot_file_bytes(\"scheme\", (void*)scheme_boot_data, scheme_boot_size);\n")
-    (fprintf out "  Sregister_boot_file_bytes(\"gitsafe\", (void*)gitsafe_boot_data, gitsafe_boot_size);\n")
-    (fprintf out "  Sbuild_heap(NULL, NULL);\n")
-    (fprintf out "  /* Register regex native symbols AFTER Sbuild_heap */\n")
-    (fprintf out "  Sforeign_symbol(\"jerboa_regex_compile\", (void *)_jerboa_native_stub);\n")
-    (fprintf out "  Sforeign_symbol(\"jerboa_regex_find\",    (void *)_jerboa_native_stub);\n")
-    (fprintf out "  Sforeign_symbol(\"jerboa_regex_free\",    (void *)_jerboa_native_stub);\n")
-    (fprintf out "  int status = Sscheme_script(prog_path, argc, (const char **)argv);\n")
-    (fprintf out "  unlink(prog_path);\n")
-    (fprintf out "  Sscheme_deinit();\n")
-    (fprintf out "  return status;\n")
-    (fprintf out "}\n"))
-  'replace)
-
-;; --- Step 5: Compile and link with musl-gcc (fully static) ---
-(printf "[5/6] Compiling and linking with musl-gcc (static)...\n")
-
-(define link-libs "-lkernel -llz4 -lz -lm -ldl -lpthread")
-
-(let ([rc (system (format "musl-gcc -c -O2 -I~a -o gitsafe-main-musl.o gitsafe-main-musl.c"
-                          musl-chez-dir))])
-  (unless (= rc 0) (printf "Error: C compilation failed\n") (exit 1)))
-
-(let ([rc (system (format "musl-gcc -o gitsafe-musl gitsafe-main-musl.o -L~a ~a -static -Wl,--allow-multiple-definition"
-                          musl-chez-dir link-libs))])
-  (unless (= rc 0) (printf "Error: linking failed\n") (exit 1)))
-
-(printf "  Stripping binary...\n")
-(system "strip --strip-all gitsafe-musl")
-(system "sha256sum gitsafe-musl > gitsafe-musl.sha256")
-
-;; --- Step 6: Cleanup ---
-(do-cleanup! "musl")
-
-(printf "\nDone! Binary: ./gitsafe-musl\n")
-(printf "  Size:   ")
-(system "ls -lh gitsafe-musl | awk '{print $5}'")
-(printf "  SHA256: ")
-(system "cat gitsafe-musl.sha256")
-(printf "\n  Test:   ./gitsafe-musl --version\n")
-(printf "  Verify: file gitsafe-musl && ldd gitsafe-musl\n")