The corpus had ZERO bundler coverage (the stream's named top risk). Add a `.build`
`bundle` directive to the corpus runner: after a successful `aot` build it asserts
each `expect` entry exists under the produced `.app` (repo-relative), then `rm -rf`s
it. macOS-host only — the `.app` + codesign are Apple-specific, so the example is
skipped on other hosts.
`examples/1665-platform-macos-bundle-smoke.sx` sets `bundle_path`/`bundle_id` via a
`#run` config; `default_pipeline` auto-bundles (build.sx imports the bundler, no
explicit `on_build` needed). The directive asserts `Contents/MacOS`,
`Contents/Info.plist`, `Contents/_CodeSignature`. Verified: passes on BOTH gates
(the bundler runs on the legacy interp AND the VM), the `.app` is cleaned up, and a
bad `expect` entry correctly fails (the check is not vacuous). Unit test +
CLAUDE.md `.build`-directive docs updated. 706/0 both gates.
`zig build test -Dname=examples/0625-foo.sx[,examples/0626-bar.sx]` runs ONLY the
named example(s) — full repo-relative .sx paths, comma-separated (a leading `./`
is tolerated). Empty = run everything (unchanged default).
Why: a full `-Dupdate-goldens` re-runs and rewrites all ~690 snapshots, so one
flaky/host-divergent example (AOT links, cross-arch `target` examples) can clobber
a good snapshot. `-Dname` regenerates only the named example(s) and touches
nothing else. It also busts the cached test-run result — the corpus enumerates
.sx/expected files at runtime, so a bare snapshot edit alone is otherwise served
from cache.
- build.zig: new `name` option threaded onto corpus_paths.
- corpus_run.test.zig: `nameMatchesFilter` + a per-example skip in the run loop.
- CLAUDE.md: document the targeted-regen workflow under Snapshot integrity.
When a `.build` target doesn't match the host, the runner can't execute the
example here, so it verifies via `sx ir --target` only: asserts exit + the `.ir`
snapshot (stdout) + diagnostics (stderr), never `.stdout`. An `.ir` snapshot is
REQUIRED in ir-only mode — its absence is a loud failure, never a silent pass.
- corpus_run.test.zig: ir_only flag (target set & !hostMatchesTarget); first
dispatch arm runs `sx ir`, sets act_exit/act_err/act_ir; skip stdout in both
update and verify modes; require ir_raw.
- lock fixture 1639-platform-target-cross (asm-free main, target x86_64-linux,
checked-in .ir). Verified: corrupt .ir => IR mismatch; delete .ir => require
failure.
Test-infra only; no compiler code. zig build test green (647 corpus, 444 unit).
Phase 2 of the extern/export stream verifies `export` (define + expose a
C-ABI sx symbol) end-to-end. C->sx-by-name linkage cannot work under the
corpus's `sx run` JIT mode — a JIT-resident symbol is invisible to a
dlopen'd C dylib's flat-namespace lookup — so this lands a new AOT
execution mode for the corpus: an `expected/<name>.aot` marker switches an
example from JIT `sx run` to a `sx build` + execute flow, linking the sx
object with its C `#source` companions into a native binary.
example/1226 defines `sx_square :: (n: i32) -> i32 export { ... }` and a
companion .c that declares `extern int sx_square(int)` and calls it back.
RED: with `export` not yet lowered, the AOT link fails with an undefined
`_sx_square` (the define path still emits it `internal` + with an implicit
ctx slot, and lazy lowering leaves an uncalled export fn as a bodiless
declare). Phase 2.1 greens it.
Also retires the standalone `tests/run_examples.sh` runner — `zig build
test` (src/corpus_run.test.zig) is now the sole corpus runner, and the
shell mirror would have needed its own AOT-mode port to stay in lockstep.
verify-step.sh drops its redundant step (zig build test already runs the
corpus); CLAUDE.md documents the `.aot` mode.
`zig build test` now runs the full examples/ + issues/ regression corpus
alongside the Zig unit tests, driven by a pure-Zig test
(src/corpus_run.test.zig) — no shell script in the build path. It spawns
the installed `sx` per example (subprocess-isolated, per-run timeout),
diffs stdout/stderr/exit and optional `sx ir` snapshots, and fails the
build on any mismatch. The file list is enumerated at runtime, so new
examples are covered with no test edit.
- `sx ir` / `ir-dump` now write to stdout (fd 1) instead of stderr, so
the dumps can be piped/redirected.
- `zig build test -Dupdate-goldens` regenerates snapshots in-build,
byte-identical to the legacy `run_examples.sh --update`; on mismatch
the runner prints how to regenerate.
- run_examples.sh kept (still used by tools/verify-step.sh) and made
portable to a bare macOS: timeout/gtimeout fallback, bash 3.2-safe
empty-array handling.
- CLAUDE.md: document the new workflow.