updates

ober

0d0271e8fee15d393dfd717f96f9860980fa64e6

diff --git a/data/cookbooks.sexp b/data/cookbooks.sexp
index 2155672..3ff3bc0 100644
--- a/data/cookbooks.sexp
+++ b/data/cookbooks.sexp
@@ -4469,4 +4469,16 @@
  (("code" . ";c") ("id" . "crash-repro-1") ("imports")
    ("notes" . "n") ("tags" "t") ("title" . "crash1"))
  (("code" . ";c") ("id" . "crash-repro-2") ("imports")
-   ("notes" . "n") ("tags" "t") ("title" . "crash2")))
+   ("notes" . "n") ("tags" "t") ("title" . "crash2"))
+ (("code"
+    .
+    "(import (jerboa prelude) (std net http))\n\n;; HTTPS pulls in (std net tls-rustls); wasm parsing pulls in (std wasm\n;; sandbox). Both load the Rust native lib at RUNTIME via a NAMED\n;; (load-shared-object \"libjerboa_native.dylib\") wrapped in try -- so if\n;; the dylib is not on the loader path, the FFI silently no-ops rather\n;; than erroring. The compiled binary needs it reachable at runtime.\n(def (main)\n  (let ([resp (http-fetch \"https://example.com\")])\n    (displayln (http-status resp))))   ;; 200 only when libjerboa_native is found\n\n(main)\n\n;; Build (jerbuild auto-wrap supplies the (chezscheme) base for the entry):\n;;   jerbuild binary --libdirs \"$PWD/src:$JERBOA_HOME/lib\" ./entry.ss myprog\n;;\n;; Run -- the dylib MUST be reachable or TLS/wasm FFI silently no-ops:\n;;   DYLD_LIBRARY_PATH=\"$JERBOA_HOME/lib\" ./myprog      # macOS\n;;   LD_LIBRARY_PATH=\"$JERBOA_HOME/lib\"   ./myprog      # Linux/BSD") ("id" . "jerbuild-binary-ffi-native-runtime")
+   ("imports" "(jerboa prelude)" "(std net http)")
+   ("notes"
+     .
+     "(std net tls-rustls) and (std wasm sandbox) resolve their Rust FFI at runtime via a NAMED (load-shared-object \"libjerboa_native.dylib\") (with .so and lib/ fallbacks), ALL wrapped in try -- so a missing dylib is swallowed and HTTPS/wasm calls silently no-op (return nothing) instead of erroring loudly. Fix: make the dylib reachable at runtime -- DYLD_LIBRARY_PATH=$JERBOA_HOME/lib on macOS, LD_LIBRARY_PATH on Linux/BSD. GOTCHA (tested on macOS 15): the ~/lib DYLD_FALLBACK_LIBRARY_PATH default does NOT resolve a leaf-name dlopen, so you cannot rely on ~/lib or /usr/local/lib fallbacks -- set DYLD_LIBRARY_PATH explicitly. For an MCP/stdio server, put DYLD_LIBRARY_PATH (plus any data-file env the app reads via getenv, e.g. a wasm path) in the MCP client's env block; it survives the client's direct execve spawn (verified with env -i). macOS install gotcha: after copying the binary, re-sign with `codesign --force --sign - <bin>`, because overwriting a Mach-O in place invalidates its ad-hoc signature and the kernel SIGKILLs it (Killed: 9 / exit 137 / no output). Self-contained alternative: `jerbuild binary --extra-archive .../libjerboa_native.a` statically links the lib and registers symbols via Sforeign_symbol (the std modules note: 'In static builds, symbols are pre-registered via Sforeign_symbol'), so NO runtime dylib or DYLD_* is needed. Companion to recipe jerbuild-binary-full-jerboa-entry, which covers the compile-time auto-wrap of an entry that imports no (chezscheme) base.")
+   ("tags" "jerbuild" "binary" "libjerboa_native" "dyld"
+     "load-shared-object" "tls" "wasm" "ffi")
+   ("title"
+     .
+     "Native jerbuild binary using TLS/wasm needs libjerboa_native at runtime")))
diff --git a/data/features.sexp b/data/features.sexp
index 7070503..62368df 100644
--- a/data/features.sexp
+++ b/data/features.sexp
@@ -689,4 +689,24 @@
    ("use_case"
      .
      "Every /save-discoveries invocation. Every manual howto_add / suggest_feature / vote_feature / security_pattern_add. Anything that needs to persist discoveries back to the .sexp data files.")
+   ("votes" . 0))
+ (("description"
+    .
+    "When `jerbuild binary` compiles a program importing (std net tls-rustls) or (std wasm sandbox), the resulting binary still needs libjerboa_native.dylib reachable at runtime via DYLD_LIBRARY_PATH/LD_LIBRARY_PATH, because those std modules do a NAMED (load-shared-object \"libjerboa_native.dylib\"). Add a flag (e.g. --static-native / --with-libjerboa-native) that links the prebuilt libjerboa_native.a via --extra-archive AND auto-emits the ffi-symbols registration header (Sforeign_symbol) for the archive's exported symbols, producing a self-contained binary needing no runtime dylib or DYLD_* env. jerbuild already supports --extra-archive plus a manual (ffi-symbols ...) mechanism; this packages the common case (the shipped libjerboa_native) behind one flag and auto-derives the symbol list (e.g. via nm) so the user need not enumerate jerboa_tls_*/jerboa_wasm_* by hand.")
+   ("estimated_token_reduction"
+     .
+     "eliminates manual --extra-archive + ffi-symbols wiring and per-config DYLD env setup (~3-5 config edits, ~400 tokens per packaging task)")
+   ("example_scenario"
+     .
+     "Built jerbsearch (an MCP server using HTTPS + the wasm HTML parser) to ~/.local/bin/jerbsearch; had to add DYLD_LIBRARY_PATH=$JERBOA_HOME/lib to all 4 MCP client configs (claude/codex/copilot/opencode) so load-shared-object would find libjerboa_native.dylib at runtime. A --static-native flag would have produced a fully self-contained binary needing none of that env.")
+   ("id" . "jerbuild-static-native-ffi-flag")
+   ("impact" . "medium")
+   ("tags" "jerbuild" "binary" "ffi" "libjerboa_native"
+     "static")
+   ("title"
+     .
+     "jerbuild flag to statically embed libjerboa_native (self-contained TLS/wasm binary)")
+   ("use_case"
+     .
+     "Shipping a self-contained Jerboa binary (e.g. an MCP server) that uses HTTPS or the wasm sandbox to a location like ~/.local/bin, without wiring DYLD_LIBRARY_PATH into every launcher/MCP-client config.")
    ("votes" . 0)))