updates
ober
fb0db34a6fb012f46ba9849319d1c4d6d49b105c
--- a/.jerbuild +++ b/.jerbuild @@ -3,38 +3,29 @@ ;; jerbuild bundles Chez Scheme + the jerboa stdlib, so NO jerboa source ;; checkout or external Chez is required. The only external input is the native ;; Rust lib (libjerboa_native), built from vendor/jerboa-native-rs with the -;; features jcode needs (tls + crypto). SQLite comes from jerboa-sqlite's C -;; shim so the binary does not link duplicate jerboa_sqlite_* symbols. -;; -;; Static FFI needs NO source patching: jerboa-sqlite.sls falls through to (void) -;; and tui-ffi.ss honors JERBOA_STATIC=1 (set by support/jcode-main.c), so the -;; linked-in shim symbols resolve via the registered FFI symbols below. +;; features jcode needs (tls + crypto). SQLite session storage comes from the +;; pure Scheme jsqlite library in ../jsqlite/src. (entry "main-binary.ss") (output "jcode") ;; do-binary-build auto-appends the bundled stdlib; list only project + vendor. (libdirs "lib" - "vendor/jerboa-sqlite/lib" + "../jsqlite/src" "vendor/jerboa-websearch/src") -;; Symbols statically registered via Sforeign_symbol (sqlite shim, termbox TUI -;; shim, jerboa-native tls+crypto). The custom main.c #includes + calls them. +;; Symbols statically registered via Sforeign_symbol (termbox TUI shim and +;; jerboa-native tls+crypto). The custom main.c #includes + calls them. (ffi-symbols "support/ffi-symbols.list") ;; Stock jerbuild main.c + setenv(JERBOA_STATIC=1); see the file's header. (main-c "support/jcode-main.c") -;; C shims compiled into the binary. SQLite comes from the Cargo-built bundled -;; archive below, with support/sqlite3.h providing the small C API surface used -;; by the shim. +;; C shims compiled into the binary. (extra-sources - ("vendor/jerboa-sqlite/jerboa_sqlite_shim.c" cflags: "-Isupport") ("src/jcode/ui/jcode_tui_shim.c" cflags: "-DTB_OPT_ATTR_W=32 -Ivendor/termbox2") ("support/debug-repl-socket-shim.c") ("support/landlock-shim.c")) -(extra-archives "support/sqlite-bundled/target/release/libjcode_sqlite_bundled.a") - ;; jerboa-native (Rust): tls + crypto only (no sqlite/duckdb/pcap/postgres). jerbuild ;; runs cargo and links the resulting libjerboa_native.a. (rust-crates --- a/AGENTS.md +++ b/AGENTS.md @@ -433,6 +433,21 @@ Jerboa is niche — every non-trivial pattern you discover prevents future sessi **Recipe format**: `id` (kebab-case), `tags` (4-6 search keywords incl. module name), `imports` (all required), `code` (complete working example), `notes` (gotchas/alternatives). +### Save anti-patterns (`~/mine/jerboa/data/anti-patterns.sexp`) whenever you: +- See a plausible local-model strategy that failed verification +- Find a weak verifier pattern that allowed false success +- See a repeated repair loop, such as broad-reading after a concrete error +- Find a generic runtime mistake, such as missing lower-bound checks before vector access + +**Before saving**: check `jerboa_anti_pattern_lookup` to avoid duplicates. If none exists, call `jerboa_anti_pattern_add`; only edit `data/anti-patterns.sexp` directly if the writer tool is unavailable. + +### Save error fixes (`jerboa_error_fix_add`) whenever you: +- See exact compiler/runtime/verifier text with a repeatable repair +- Hit an error that `jerboa_failure_advisor` should classify better next time +- Debug a local-model generated-code failure where a short diagnosis prevents another failed iteration + +**Before saving**: check `jerboa_error_fix_lookup` with the exact error text. + ### Suggest tooling improvements (`jerboa_suggest_feature`) whenever you: - Make multiple sequential tool calls that could be one tool - Fall back to bash because an MCP tool is missing or insufficient @@ -440,7 +455,7 @@ Jerboa is niche — every non-trivial pattern you discover prevents future sessi **Before suggesting**: check `jerboa_list_features`; vote with `jerboa_vote_feature` if it already exists. ### Save Discoveries Mechanisms -- **`/save-discoveries` skill**: invoke anytime to review session and save patterns + suggestions +- **`/save-discoveries` skill**: invoke anytime to review session and save recipes, anti-patterns, error fixes, feature suggestions, and security patterns - **PreCompact hook**: add `PreCompact` hook with `type: "prompt"` in `.claude/settings.json` to auto-save before context compaction --- --- a/Makefile +++ b/Makefile @@ -14,19 +14,18 @@ JERBUILD ?= $(shell if [ -x ./jerbuild ] && [ -x ./jerboa ]; then echo ./jerbuil # asking the jerbuild binary where it unpacked its bundle. JH = $(shell "$(JERBUILD)" --jerboa-home 2>/dev/null) -LIBDIRS = --libdirs ./lib:vendor/jerboa-sqlite/lib:vendor/jerboa-websearch/src:$(JH)/lib +JSQLITE_DIR ?= $(HOME)/mine/jsqlite +JSQLITE_LIBDIR ?= $(JSQLITE_DIR)/src + +LIBDIRS = --libdirs ./lib:$(JSQLITE_LIBDIR):vendor/jerboa-websearch/src:$(JH)/lib JEXEC = $(JERBUILD) exec $(LIBDIRS) # Library paths for FFI shared objects (macOS: dylib, Linux: so). The native # Rust lib now lives in ./lib (dropped by the native-rs target), matching the # (std crypto native-rust) loader's CWD-relative "lib/" fallback. -SHIM_DIR := $(CURDIR)/vendor/jerboa-sqlite -SQLITE_STAGE := vendor/jerboa-sqlite/.jcode-src -SQLITE_BUNDLED_DIR := support/sqlite-bundled -SQLITE_BUNDLED_A := $(SQLITE_BUNDLED_DIR)/target/release/libjcode_sqlite_bundled.a TUI_SHIM_DIR := $(CURDIR)/vendor/termbox2 NATIVE_LIB_DIR := $(CURDIR)/lib -LDPATH := $(SHIM_DIR):$(TUI_SHIM_DIR):$(NATIVE_LIB_DIR) +LDPATH := $(TUI_SHIM_DIR):$(NATIVE_LIB_DIR) # Native Rust lib (vendored crate, built with cargo). Only the features jcode # uses — tls + crypto; no duckdb/pcap/postgres. @@ -50,7 +49,7 @@ else JCODE_OS_LIBS := -lm -ldl -lpthread -luuid -lncurses -lstdc++ endif -.PHONY: all help ensure-jerboa-tools build gen run test test-providers local-eval clean repl binary install tui-shim run-tui native-rs sqlite-bundled linux linux-check linux-amd64 linux-arm64 jcode-linux-amd64 jcode-linux-arm64 test-linux test-linux-amd64 freebsd freebsd-amd64 jcode-freebsd-amd64 purge-stale sqlite-shim sqlite-lib android android-clean vendor-deps vendor-clean +.PHONY: all help ensure-jerboa-tools build gen run test test-providers local-eval clean repl binary install tui-shim run-tui native-rs linux linux-check linux-amd64 linux-arm64 jcode-linux-amd64 jcode-linux-arm64 test-linux test-linux-amd64 freebsd freebsd-amd64 jcode-freebsd-amd64 purge-stale android android-clean vendor-deps vendor-clean all: help @@ -64,9 +63,8 @@ help: @echo " run Start interactive agent REPL" @echo " run-tui Start TUI mode" @echo " repl Open a bare Scheme REPL with project libdirs" - @echo " gen Transpile src/ → lib/ + rebuild sqlite shim (jerbuild)" + @echo " gen Transpile src/ → lib/ (jerbuild)" @echo " native-rs Build vendored libjerboa_native (cargo, tls+crypto)" - @echo " sqlite-bundled Build bundled SQLite archive via cargo" @echo " binary Build native binary via 'jerbuild build' (.jerbuild)" @echo " install Install binary to ~/.local/bin" @echo " binary Build jcode for THIS host's os/arch (jerbuild, native)" @@ -77,8 +75,6 @@ help: @echo " linux-check Fast drift check of the cross-build (no link, ~10s)" @echo " clean Remove compiled artifacts and binaries" @echo " purge-stale Remove stale .so/.wpo files" - @echo " sqlite-shim Rebuild jerboa_sqlite_shim.so" - @echo " sqlite-lib Transpile vendor/jerboa-sqlite src/ → lib/" @echo " tui-shim Rebuild jcode_tui_shim" @echo " android Build Android APK in Termux (android/build/*.apk)" @echo " android-clean Remove android/build/" @@ -108,9 +104,6 @@ ensure-jerboa-tools: # source no longer exists). This makes "make build" idempotent and immune # to the class of bug where a stale .so silently linked against an old # shim causes a runtime "no entry for X" foreign-procedure error. -# -# Always also clear the prebuilt vendor/jerboa-sqlite artifacts — they pin -# absolute paths to the shim and are cheap to recompile. purge-stale: @find lib -name "*.so" -o -name "*.wpo" 2>/dev/null | while read f; do \ src=$$(echo $$f | sed -e 's|^lib/|src/|' -e 's|\.so$$|.ss|' -e 's|\.wpo$$|.ss|'); \ @@ -129,39 +122,6 @@ purge-stale: break; \ fi; \ done - @rm -f vendor/jerboa-sqlite/lib/jerboa-sqlite.so vendor/jerboa-sqlite/lib/jerboa-sqlite.wpo - -# ── jerboa-sqlite shim build ────────────────────────────────────────────────── -# Rebuild the FFI shim if its C source is newer than the .so. This catches -# the case where vendor/jerboa-sqlite is updated but the .so isn't refreshed. -sqlite-bundled: - @command -v cargo >/dev/null 2>&1 || { \ - echo "ERROR: cargo not found on PATH. Install rustup from rustup.rs"; exit 1; } - @if [ ! -f "$(SQLITE_BUNDLED_A)" ] || \ - [ "$(SQLITE_BUNDLED_DIR)/Cargo.toml" -nt "$(SQLITE_BUNDLED_A)" ] || \ - [ -n "$$(find $(SQLITE_BUNDLED_DIR)/src -name '*.rs' -newer $(SQLITE_BUNDLED_A) 2>/dev/null)" ]; then \ - echo "=== Building bundled SQLite archive ==="; \ - ( cd $(SQLITE_BUNDLED_DIR) && cargo build --release ); \ - fi - -sqlite-shim: vendor/jerboa-sqlite sqlite-bundled - @if [ ! -f vendor/jerboa-sqlite/jerboa_sqlite_shim.so ] || \ - [ vendor/jerboa-sqlite/jerboa_sqlite_shim.c -nt vendor/jerboa-sqlite/jerboa_sqlite_shim.so ] || \ - [ support/sqlite3.h -nt vendor/jerboa-sqlite/jerboa_sqlite_shim.so ] || \ - [ "$(SQLITE_BUNDLED_A)" -nt vendor/jerboa-sqlite/jerboa_sqlite_shim.so ]; then \ - echo "=== Rebuilding jerboa_sqlite_shim.so ==="; \ - cc -shared -fPIC -O2 \ - -Isupport \ - -o vendor/jerboa-sqlite/jerboa_sqlite_shim.so \ - vendor/jerboa-sqlite/jerboa_sqlite_shim.c $(SQLITE_BUNDLED_A); \ - fi - -sqlite-lib: ensure-jerboa-tools vendor/jerboa-sqlite - @rm -rf $(SQLITE_STAGE) - @mkdir -p $(SQLITE_STAGE) - @sed '/^(import (jerboa prelude))$$/d' \ - vendor/jerboa-sqlite/src/jerboa-sqlite.ss > $(SQLITE_STAGE)/jerboa-sqlite.ss - $(JERBUILD) transpile $(SQLITE_STAGE) vendor/jerboa-sqlite/lib --force # ── libjerboa_native (Rust FFI) ───────────────────────────────────────────── # secrets.ss + std/net/request + std/regex etc. all bind FFI symbols from @@ -201,13 +161,7 @@ native-rs: $(NATIVE_DIR) # we do NOT use git submodules — every target that needs vendor/<x> depends on # vendor-deps so a fresh checkout populates itself. -vendor-deps: vendor/jerboa-sqlite vendor/termbox2 vendor/jerboa-websearch - -vendor/jerboa-sqlite: - @mkdir -p vendor - @echo "=== Cloning jerboa-sqlite into vendor/ ===" - @git clone --depth 1 https://git.sr.ht/~lisp/jerboa-sqlite vendor/jerboa-sqlite - @rm -f vendor/jerboa-sqlite/jerboa_sqlite_shim.so +vendor-deps: vendor/termbox2 vendor/jerboa-websearch vendor/termbox2: @mkdir -p vendor @@ -242,7 +196,7 @@ $(REPL_TOKEN_FILE): @head -c 16 /dev/urandom | od -An -tx1 | tr -d ' \n' > $@ @echo "Generated debug-REPL auth token in $(REPL_TOKEN_FILE)" -gen: ensure-jerboa-tools vendor-deps purge-stale sqlite-shim sqlite-lib $(REPL_TOKEN_FILE) +gen: ensure-jerboa-tools vendor-deps purge-stale $(REPL_TOKEN_FILE) JCODE_REPL_TOKEN=$$(cat $(REPL_TOKEN_FILE)) $(JERBUILD) transpile src lib build: ensure-jerboa-tools gen native-rs @@ -321,7 +275,7 @@ install: binary JERBOA_HOME ?= $(HOME)/mine/jerboa SCHEME ?= $(JERBOA_HOME)/.chez/bin/scheme FREEBSD_AMD64_CC ?= $(JERBOA_HOME)/support/cross-cc-freebsd-amd64 -XC_LIBDIRS = ./lib:vendor/jerboa-sqlite/lib:vendor/jerboa-websearch/src:$(JH)/lib:$(JERBOA_HOME)/lib +XC_LIBDIRS = ./lib:$(JSQLITE_LIBDIR):vendor/jerboa-websearch/src:$(JH)/lib:$(JERBOA_HOME)/lib # `make linux` defaults to the linux amd64 cross-build. linux: linux-amd64 --- a/build-jcode-cross.ss +++ b/build-jcode-cross.ss @@ -56,11 +56,8 @@ ;; jcode uses only this subset of jerboa-native-rs features: ;; tls — provider/provider.ss (rustls) ;; crypto — secrets.ss, hashing, hmac, aead, scrypt, argon2id -;; -;; SQLite is linked through vendor/jerboa-sqlite/jerboa_sqlite_shim.c plus -;; support/sqlite-bundled. The Rust crate's sqlite feature exports a different -;; jerboa_sqlite_* surface, so enabling it here creates duplicate symbols and -;; still does not provide the int64/bytes/constants API the Scheme module uses. +;; Session storage uses pure Scheme jsqlite from the libdirs; no sqlite C shim +;; or jerboa-native sqlite feature is linked here. (define cargo-features "tls,crypto") (define jerboa-native-a @@ -68,10 +65,6 @@ (format "~a/jerboa-native-rs/target/~a/release/libjerboa_native.a" jerboa-home rust-target))) -(define sqlite-bundled-a - (format "support/sqlite-bundled/target/~a/release/libjcode_sqlite_bundled.a" - rust-target)) - (define cross-csv-dir (let ([lib (format "~a/lib" cross-prefix)]) (unless (file-directory? lib) @@ -102,8 +95,7 @@ (printf " xpatch: ~a~n" xpatch) (printf " cross-cc: ~a~n" cross-cc) (printf " output: ~a~n" output) -(printf " features: ~a~n" cargo-features) -(printf " sqlite archive: ~a~n~n" sqlite-bundled-a) +(printf " features: ~a~n~n" cargo-features) ;; ── Step 0: Build/rebuild jerboa-native-rs for x86_64-linux-musl ─────────── ;; libjerboa_native.a is shared across jerboa-shell, jerboa-code, etc. If a @@ -169,30 +161,6 @@ (printf " $ ~a~n" cmd) (zero? (system cmd))) -(define (build-sqlite-bundled!) - (require-file "support/sqlite-bundled/Cargo.toml") - (let* ([sqlite-dir "support/sqlite-bundled"] - [cargo-args (format "build --release --target ~a" rust-target)] - [cc-env (format "CARGO_TARGET_~a_LINKER='~a' CC_~a='~a' AR_~a='~a' " - rust-target-env-upper cross-cc - rust-target-env-lower cross-cc - rust-target-env-lower cross-ar)] - [via-rustup - (and rustup-bin-dir - (format "cd '~a' && env ~aPATH='~a':$PATH RUSTC='~a/rustc' '~a/cargo' ~a" - sqlite-dir cc-env rustup-bin-dir rustup-bin-dir rustup-bin-dir cargo-args))] - [via-path (format "cd '~a' && env ~acargo ~a" sqlite-dir cc-env cargo-args)] - [ok? (or (and via-rustup (try-cargo-build via-rustup)) - (try-cargo-build via-path))]) - (unless ok? - (error 'build-jcode-cross - (format "failed to build bundled SQLite for ~a with ~a" - rust-target cross-cc))) - (unless (file-exists? sqlite-bundled-a) - (error 'build-jcode-cross - "cargo succeeded but bundled SQLite archive is missing" - sqlite-bundled-a)))) - (define (rebuild-native-lib!) (let* ([nrs-dir (format "~a/jerboa-native-rs" jerboa-home)] [cargo-args (format "build --release --no-default-features --features ~a --target ~a" @@ -230,8 +198,7 @@ (file-modification-time native-features-sentinel)) ;; The .a is shared across sibling repos (jerboa-shell, etc.). A newer .a ;; than our sentinel means someone rebuilt it — possibly with different - ;; features — so our tag can't be trusted. Rebuild to be sure (prevents - ;; the silent "undefined reference to jerboa_sqlite_*" cross-link break). + ;; features — so our tag can't be trusted. Rebuild to be sure. (printf "==> jerboa-native-rs .a newer than sentinel (foreign rebuild?) — rebuilding (features=~a)~n" cargo-features) (rebuild-native-lib!)] [(rs-source-newer-than? jerboa-native-a) @@ -240,11 +207,6 @@ [else (printf "==> jerboa-native-rs up to date (features=~a)~n" cargo-features)]) -(printf "==> building bundled SQLite archive (~a)~n" rust-target) -(build-sqlite-bundled!) - -(printf "~n") - ;; ── Step 0.5: isolate cross-compiled objects ─────────────────────────────── ;; Never patch source libraries in-place. Chez xpatch can compile target ;; objects while `library-directories` maps source directories to a separate @@ -319,20 +281,7 @@ ;; Chez's load-shared-object error path strlen()s it. (define ffi-shim-symbols - '(;; jerboa-sqlite shim (vendor/jerboa-sqlite/jerboa_sqlite_shim.c) - "jerboa_sqlite_open" "jerboa_sqlite_close" "jerboa_sqlite_exec" - "jerboa_sqlite_prepare" "jerboa_sqlite_finalize" "jerboa_sqlite_reset" - "jerboa_sqlite_clear_bindings" "jerboa_sqlite_step" - "jerboa_sqlite_column_count" "jerboa_sqlite_column_name" - "jerboa_sqlite_column_type" "jerboa_sqlite_column_int64" - "jerboa_sqlite_column_double" "jerboa_sqlite_column_text" - "jerboa_sqlite_column_bytes" "jerboa_sqlite_column_blob" - "jerboa_sqlite_bind_int64" "jerboa_sqlite_bind_double" - "jerboa_sqlite_bind_text" "jerboa_sqlite_bind_blob" - "jerboa_sqlite_bind_null" "jerboa_sqlite_last_insert_rowid" - "jerboa_sqlite_changes" "jerboa_sqlite_errmsg" - "jerboa_SQLITE_ROW" "jerboa_SQLITE_DONE" "jerboa_SQLITE_OK" - ;; termbox2 TUI shim (src/jcode/ui/jcode_tui_shim.c) + '(;; termbox2 TUI shim (src/jcode/ui/jcode_tui_shim.c) "jcode_tb_init" "jcode_tb_shutdown" "jcode_tb_width" "jcode_tb_height" "jcode_tb_clear" "jcode_tb_present" @@ -394,9 +343,10 @@ "getuid" "geteuid" "getgid" "getegid" "sigemptyset" "sigfillset" "sigaddset" "sigdelset" "sigismember" "sigprocmask" - ;; terminal/fd — TUI + REPL + ;; terminal/fd — TUI + REPL + jsqlite locking/WAL shm "isatty" "tcgetattr" "tcsetattr" "tcgetpgrp" "tcsetpgrp" "pipe" "dup" "dup2" "lseek" + "open" "ftruncate" "mmap" "munmap" "flock" "usleep" ;; env/misc — std/os/env, std/text/time "setenv" "unsetenv" "strerror" "localtime" "strftime" "sysconf" "getpagesize" "getrlimit" @@ -421,6 +371,7 @@ (display "#include <sys/wait.h>\n" out) (display "#include <sys/resource.h>\n" out) (display "#include <sys/prctl.h>\n" out) + (display "#include <sys/file.h>\n" out) (display "#include <sys/socket.h>\n" out) (display "#include <netinet/in.h>\n" out) (display "#include <arpa/inet.h>\n" out) @@ -454,7 +405,7 @@ (display "static char dlerror_msg[] = \"static binary: dlopen of named libraries is stubbed\";\n" out) (display "char *dlerror(void) { return dlerror_msg; }\n\n" out) ;; extern decls for shim functions linked via .c files - (display "/* Shim function decls — jerboa_sqlite_shim.c + jcode_tui_shim.c + landlock-shim.c */\n" out) + (display "/* Shim function decls — jcode_tui_shim.c + landlock-shim.c */\n" out) (for-each (lambda (n) (fprintf out "extern void ~a();\n" n)) ffi-shim-symbols) ;; extern decls for libjerboa_native.a symbols (display "\n/* libjerboa_native.a — features=tls,crypto */\n" out) @@ -521,20 +472,14 @@ ;; ── Stage 6: compile + link with cross-cc ────────────────────────────────── (printf "==> [6/6] compile + link with ~a~n" cross-cc) -(define sqlite-shim-c "vendor/jerboa-sqlite/jerboa_sqlite_shim.c") (define jcode-tui-shim-c "src/jcode/ui/jcode_tui_shim.c") (define landlock-shim-c "support/landlock-shim.c") -(define sqlite-include-dir "support") -(require-file sqlite-shim-c) (require-file jcode-tui-shim-c) (require-file landlock-shim-c) (require-file jerboa-native-a) -(require-file sqlite-bundled-a) -(require-file "support/sqlite3.h") -(printf " sqlite3.h: support/sqlite3.h~n") -(printf " tls/crypto via libjerboa_native.a; sqlite via jerboa_sqlite_shim.c + bundled SQLite~n") +(printf " tls/crypto via libjerboa_native.a; sessions via jsqlite Scheme sources~n") ;; -Wl,--export-dynamic exports symbols into the dynamic symbol table so ;; Chez's foreign-procedure / dlsym(RTLD_DEFAULT) can find them in a @@ -544,20 +489,18 @@ (string-append "~a -O2 -static -Wl,--export-dynamic " "-I~a " ;; scheme.h - "-I~a " ;; sqlite3.h "-Ivendor/termbox2 -DTB_OPT_ATTR_W=32 " ;; jcode_tui_shim "-o ~a " ;; output - "~a ~a ~a ~a " ;; main.c + 3 shims + "~a ~a ~a " ;; main.c + 2 shims "~a/libkernel.a ~a/libz.a ~a/liblz4.a " ;; chez kernel "~a " ;; libjerboa_native.a - "~a " ;; bundled sqlite3 "-Wl,--allow-multiple-definition " "-Wl,--defsym=_dl_find_object=0 " "-lm -ldl -lpthread") - cross-cc cross-csv-dir sqlite-include-dir output - main-c-path sqlite-shim-c jcode-tui-shim-c landlock-shim-c + cross-cc cross-csv-dir output + main-c-path jcode-tui-shim-c landlock-shim-c cross-csv-dir cross-csv-dir cross-csv-dir - jerboa-native-a sqlite-bundled-a)) + jerboa-native-a)) (printf " ~a~n" link-cmd) (let ([rc (system link-cmd)]) (unless (zero? rc) --- a/build-jcode-freebsd-cross.ss +++ b/build-jcode-freebsd-cross.ss @@ -35,11 +35,8 @@ ;; jcode uses only this subset of jerboa-native-rs features: ;; tls — provider/provider.ss (rustls) ;; crypto — secrets.ss, hashing, hmac, aead, scrypt, argon2id -;; -;; SQLite is linked through vendor/jerboa-sqlite/jerboa_sqlite_shim.c plus -;; support/sqlite-bundled. The Rust crate's sqlite feature exports a different -;; jerboa_sqlite_* surface, so enabling it here creates duplicate symbols and -;; still does not provide the int64/bytes/constants API the Scheme module uses. +;; Session storage uses pure Scheme jsqlite from the libdirs; no sqlite C shim +;; or jerboa-native sqlite feature is linked here. (define cargo-features "tls,crypto") (define jerboa-native-a @@ -47,9 +44,6 @@ (format "~a/jerboa-native-rs/target/x86_64-unknown-freebsd/release/libjerboa_native.a" jerboa-home))) -(define sqlite-bundled-a - "support/sqlite-bundled/target/x86_64-unknown-freebsd/release/libjcode_sqlite_bundled.a") - (define cross-csv-dir (let ([lib (format "~a/lib" cross-prefix)]) (unless (file-directory? lib) @@ -80,8 +74,7 @@ (printf " xpatch: ~a~n" xpatch) (printf " cross-cc: ~a~n" cross-cc) (printf " output: ~a~n" output) -(printf " features: ~a~n" cargo-features) -(printf " sqlite archive: ~a~n~n" sqlite-bundled-a) +(printf " features: ~a~n~n" cargo-features) ;; ── Step 0: Build/rebuild jerboa-native-rs for x86_64-unknown-freebsd ────── ;; libjerboa_native.a is shared across jerboa-shell, jerboa-code, etc. If a @@ -152,26 +145,6 @@ "CARGO_TARGET_X86_64_UNKNOWN_FREEBSD_LINKER='~a' CC_x86_64_unknown_freebsd='~a' AR_x86_64_unknown_freebsd=/opt/homebrew/opt/llvm/bin/llvm-ar " cross-cc cross-cc)) -(define (build-sqlite-bundled!) - (require-file "support/sqlite-bundled/Cargo.toml") - (let* ([sqlite-dir "support/sqlite-bundled"] - [cargo-args "build --release --target x86_64-unknown-freebsd"] - [via-rustup - (and rustup-bin-dir - (format "cd '~a' && env ~aPATH='~a':$PATH RUSTC='~a/rustc' '~a/cargo' ~a" - sqlite-dir freebsd-cc-env rustup-bin-dir rustup-bin-dir rustup-bin-dir cargo-args))] - [via-path (format "cd '~a' && env ~acargo ~a" sqlite-dir freebsd-cc-env cargo-args)] - [ok? (or (and via-rustup (try-cargo-build via-rustup)) - (try-cargo-build via-path))]) - (unless ok? - (error 'build-jcode-freebsd-cross - (string-append "failed to build bundled SQLite for x86_64-unknown-freebsd with " - cross-cc))) - (unless (file-exists? sqlite-bundled-a) - (error 'build-jcode-freebsd-cross - "cargo succeeded but bundled SQLite archive is missing" - sqlite-bundled-a)))) - (define (rebuild-native-lib!) (let* ([nrs-dir (format "~a/jerboa-native-rs" jerboa-home)] [cargo-args (format "build --release --no-default-features --features ~a --target x86_64-unknown-freebsd" @@ -209,11 +182,6 @@ [else (printf "==> jerboa-native-rs up to date (features=~a)~n" cargo-features)]) -(printf "==> building bundled SQLite archive (x86_64-unknown-freebsd)~n") -(build-sqlite-bundled!) - -(printf "~n") - ;; ── Step 0.5: isolate cross-compiled objects ─────────────────────────────── ;; Never patch source libraries in-place. Chez xpatch can compile target ;; objects while `library-directories` maps source directories to a separate @@ -288,20 +256,7 @@ ;; Chez's load-shared-object error path strlen()s it. (define ffi-shim-symbols - '(;; jerboa-sqlite shim (vendor/jerboa-sqlite/jerboa_sqlite_shim.c) - "jerboa_sqlite_open" "jerboa_sqlite_close" "jerboa_sqlite_exec" - "jerboa_sqlite_prepare" "jerboa_sqlite_finalize" "jerboa_sqlite_reset" - "jerboa_sqlite_clear_bindings" "jerboa_sqlite_step" - "jerboa_sqlite_column_count" "jerboa_sqlite_column_name" - "jerboa_sqlite_column_type" "jerboa_sqlite_column_int64" - "jerboa_sqlite_column_double" "jerboa_sqlite_column_text" - "jerboa_sqlite_column_bytes" "jerboa_sqlite_column_blob" - "jerboa_sqlite_bind_int64" "jerboa_sqlite_bind_double" - "jerboa_sqlite_bind_text" "jerboa_sqlite_bind_blob" - "jerboa_sqlite_bind_null" "jerboa_sqlite_last_insert_rowid" - "jerboa_sqlite_changes" "jerboa_sqlite_errmsg" - "jerboa_SQLITE_ROW" "jerboa_SQLITE_DONE" "jerboa_SQLITE_OK" - ;; termbox2 TUI shim (src/jcode/ui/jcode_tui_shim.c) + '(;; termbox2 TUI shim (src/jcode/ui/jcode_tui_shim.c) "jcode_tb_init" "jcode_tb_shutdown" "jcode_tb_width" "jcode_tb_height" "jcode_tb_clear" "jcode_tb_present" @@ -377,9 +332,10 @@ "getuid" "geteuid" "getgid" "getegid" "sigemptyset" "sigfillset" "sigaddset" "sigdelset" "sigismember" "sigprocmask" - ;; terminal/fd — TUI + REPL + ;; terminal/fd — TUI + REPL + jsqlite locking/WAL shm "isatty" "tcgetattr" "tcsetattr" "tcgetpgrp" "tcsetpgrp" "pipe" "dup" "dup2" "lseek" + "open" "ftruncate" "mmap" "munmap" "flock" "usleep" ;; env/misc — std/os/env, std/text/time "setenv" "unsetenv" "strerror" "localtime" "strftime" "sysconf" "getpagesize" "getrlimit" @@ -398,6 +354,8 @@ (display "#include <sys/stat.h>\n" out) (display "#include <sys/wait.h>\n" out) (display "#include <sys/resource.h>\n" out) + (display "#include <sys/mman.h>\n" out) + (display "#include <sys/file.h>\n" out) (display "#include <sys/socket.h>\n" out) (display "#include <netinet/in.h>\n" out) (display "#include <arpa/inet.h>\n" out) @@ -425,7 +383,7 @@ (fprintf out "static int ~a() { return -1; }\n" n)) freebsd-stub-symbols) ;; extern decls for shim functions linked via .c files - (display "\n/* Shim function decls — jerboa_sqlite_shim.c + jcode_tui_shim.c */\n" out) + (display "\n/* Shim function decls — jcode_tui_shim.c */\n" out) (for-each (lambda (n) (fprintf out "extern void ~a();\n" n)) ffi-shim-symbols) ;; extern decls for libjerboa_native.a symbols (display "\n/* libjerboa_native.a — features=tls,crypto */\n" out) @@ -494,20 +452,14 @@ ;; ── Stage 6: compile + link with cross-cc ────────────────────────────────── (printf "==> [6/6] compile + link with ~a~n" cross-cc) -(define sqlite-shim-c "vendor/jerboa-sqlite/jerboa_sqlite_shim.c") (define jcode-tui-shim-c "src/jcode/ui/jcode_tui_shim.c") -(define sqlite-include-dir "support") ;; landlock-shim is Linux-only (sys/prctl.h, __NR_landlock_create_ruleset); ;; on FreeBSD jerboa_landlock_sandbox is provided by a static stub above. -(require-file sqlite-shim-c) (require-file jcode-tui-shim-c) (require-file jerboa-native-a) -(require-file sqlite-bundled-a) -(require-file "support/sqlite3.h") -(printf " sqlite3.h: support/sqlite3.h~n") -(printf " tls/crypto via libjerboa_native.a; sqlite via jerboa_sqlite_shim.c + bundled SQLite~n") +(printf " tls/crypto via libjerboa_native.a; sessions via jsqlite Scheme sources~n") ;; FreeBSD link differences from Linux musl: ;; - Dynamic, not static (FreeBSD libc symbol versioning blocks libc.a) @@ -521,18 +473,16 @@ (string-append "~a -O2 -Wl,--export-dynamic " "-I~a " ;; scheme.h - "-I~a " ;; sqlite3.h "-Ivendor/termbox2 -DTB_OPT_ATTR_W=32 " ;; jcode_tui_shim "-o ~a " ;; output - "~a ~a ~a " ;; main.c + 2 shims + "~a ~a " ;; main.c + TUI shim "~a/libkernel.a ~a/libz.a ~a/liblz4.a " ;; chez kernel "~a " ;; libjerboa_native.a - "~a " ;; bundled sqlite3 "-lm -lpthread -lutil") - cross-cc cross-csv-dir sqlite-include-dir output - main-c-path sqlite-shim-c jcode-tui-shim-c + cross-cc cross-csv-dir output + main-c-path jcode-tui-shim-c cross-csv-dir cross-csv-dir cross-csv-dir - jerboa-native-a sqlite-bundled-a)) + jerboa-native-a)) (printf " ~a~n" link-cmd) (let ([rc (system link-cmd)]) (unless (zero? rc) --- a/build-jcode-musl.sh +++ b/build-jcode-musl.sh @@ -17,6 +17,8 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" HOME_DIR="${HOME:-/root}" JERBOA_HOME="${JERBOA_HOME:-${HOME_DIR}/mine/jerboa}" JERBOA_LIB="${JERBOA_HOME}/lib" +JSQLITE_DIR="${JSQLITE_DIR:-${HOME_DIR}/mine/jsqlite}" +JSQLITE_LIBDIR="${JSQLITE_LIBDIR:-${JSQLITE_DIR}/src}" SCHEME="${SCHEME:-${JERBOA_HOME}/.chez/bin/scheme}" if [ ! -x "${SCHEME}" ]; then @@ -30,6 +32,7 @@ echo "Building jcode with musl libc (static)" echo "===================================" echo "" echo "Jerboa: $JERBOA_LIB" +echo "jsqlite: $JSQLITE_LIBDIR" echo "" # Check musl availability @@ -85,10 +88,10 @@ VALIDATE echo "" echo "[2/2] Running musl build..." -LD_LIBRARY_PATH="${SCRIPT_DIR}/vendor/jerboa-sqlite:${SCRIPT_DIR}/vendor/termbox2:${JERBOA_LIB}:." \ +LD_LIBRARY_PATH="${SCRIPT_DIR}/vendor/termbox2:${JERBOA_LIB}:." \ JERBOA_HOME="${JERBOA_HOME}" \ JERBOA_MUSL_CHEZ_PREFIX="${MUSL_CHEZ_PREFIX}" \ -"${SCHEME}" -q --libdirs "${JERBOA_LIB}:./lib:vendor/jerboa-sqlite/src:vendor/jerboa-websearch/src" \ +"${SCHEME}" -q --libdirs "${JERBOA_LIB}:./lib:${JSQLITE_LIBDIR}:vendor/jerboa-websearch/src" \ <build-jcode-musl.ss # Verify --- a/build-jcode-musl.ss +++ b/build-jcode-musl.ss @@ -1,7 +1,7 @@ #!chezscheme ;;; build-jcode-musl.ss — Build a fully static jcode binary using musl libc ;;; -;;; Usage: scheme -q --libdirs <jerboa-lib>:./lib:vendor/jerboa-sqlite/src < build-jcode-musl.ss +;;; Usage: scheme -q --libdirs <jerboa-lib>:./lib:$HOME/mine/jsqlite/src:vendor/jerboa-websearch/src < build-jcode-musl.ss ;;; ;;; This script: ;;; 1. Compiles jcode modules (using stock scheme with glibc) @@ -194,9 +194,8 @@ ;; libc symbols needed by std/net/* and std/os/* (already linked from musl). ;; All are real libc functions, not macros — straight (void*)foo casts work. -;; Variadic/macro ones (open/fcntl/ioctl/umask) are intentionally omitted; -;; the modules that need them either run through the std/os shims (ffi_*) -;; or call into the patched (load-shared-object) path that no longer fires. +;; jsqlite uses open/flock/mmap directly through foreign-procedure; register +;; those libc entry points here so the static binary can resolve them. (define libc-symbols '(;; sockets — std/net/tcp, std/net/udp "socket" "bind" "listen" "accept" "connect" "close" @@ -211,9 +210,10 @@ "getuid" "geteuid" "getgid" "getegid" "sigemptyset" "sigfillset" "sigaddset" "sigdelset" "sigismember" "sigprocmask" - ;; terminal / fd — TUI + REPL + ;; terminal / fd — TUI + REPL + jsqlite locking/WAL shm "isatty" "tcgetattr" "tcsetattr" "tcgetpgrp" "tcsetpgrp" "pipe" "dup" "dup2" "lseek" + "open" "ftruncate" "mmap" "munmap" "flock" "usleep" ;; env / misc — std/os/env, std/text/time "setenv" "unsetenv" "strerror" "localtime" "strftime" "sysconf" "getpagesize" "getrlimit" @@ -225,20 +225,7 @@ ;; FFI symbols that need Sforeign_symbol registration (define ffi-symbols - '(;; jerboa-sqlite shim - "jerboa_sqlite_open" "jerboa_sqlite_close" "jerboa_sqlite_exec" - "jerboa_sqlite_prepare" "jerboa_sqlite_finalize" "jerboa_sqlite_reset" - "jerboa_sqlite_clear_bindings" "jerboa_sqlite_step" - "jerboa_sqlite_column_count" "jerboa_sqlite_column_name" - "jerboa_sqlite_column_type" "jerboa_sqlite_column_int64" - "jerboa_sqlite_column_double" "jerboa_sqlite_column_text" - "jerboa_sqlite_column_bytes" "jerboa_sqlite_column_blob" - "jerboa_sqlite_bind_int64" "jerboa_sqlite_bind_double" - "jerboa_sqlite_bind_text" "jerboa_sqlite_bind_blob" - "jerboa_sqlite_bind_null" "jerboa_sqlite_last_insert_rowid" - "jerboa_sqlite_changes" "jerboa_sqlite_errmsg" - "jerboa_SQLITE_ROW" "jerboa_SQLITE_DONE" "jerboa_SQLITE_OK" - ;; termbox2 TUI shim + '(;; termbox2 TUI shim "jcode_tb_init" "jcode_tb_shutdown" "jcode_tb_width" "jcode_tb_height" "jcode_tb_clear" "jcode_tb_present" @@ -276,17 +263,6 @@ ;; jerboa-native (aproc) — used by (std os aproc) for bash tool "jerboa_aproc_spawn" "jerboa_aproc_spawn_pty" "jerboa_aproc_set_nonblock" "jerboa_aproc_killpg" "jerboa_aproc_wait4" - ;; jerboa-native (sqlite) — used by (std db sqlite) via sqlite-native.sls - "jerboa_sqlite_open" "jerboa_sqlite_close" "jerboa_sqlite_exec" - "jerboa_sqlite_prepare" "jerboa_sqlite_finalize" "jerboa_sqlite_reset" - "jerboa_sqlite_step" "jerboa_sqlite_changes" "jerboa_sqlite_errmsg" - "jerboa_sqlite_last_insert_rowid" - "jerboa_sqlite_bind_int" "jerboa_sqlite_bind_double" - "jerboa_sqlite_bind_text" "jerboa_sqlite_bind_blob" "jerboa_sqlite_bind_null" - "jerboa_sqlite_column_count" "jerboa_sqlite_column_type" - "jerboa_sqlite_column_int" "jerboa_sqlite_column_double" - "jerboa_sqlite_column_text" "jerboa_sqlite_column_blob" - "jerboa_sqlite_column_name" ;; jerboa-native (net/io) — vectored I/O wrapper used by (std net io) "jerboa_writev2" ;; landlock-shim (support/landlock-shim.c) @@ -404,8 +380,8 @@ ;; Rust native library — build a project-specific musl static lib with ONLY ;; the cargo features jcode actually uses. jcode's FFI surface is: ;; - jerboa_tls_* (provider/provider.ss) => feature `tls` -;; - sqlite3_* (via jerboa-sqlite shim) => feature `sqlite` -;; That's it. `crypto`, `duckdb_feat`, `pcap`, `spidermonkey`, `wasm`, +;; - jerboa_crypto_* / hashing / secret-store => feature `crypto` +;; That's it. `duckdb_feat`, `pcap`, `spidermonkey`, `wasm`, and ;; `postgres_feat` are not referenced from any jcode source. ;; ;; The old fall-back-to-glibc behaviour was the recurring source of "works on @@ -423,7 +399,7 @@ ;; A sentinel file under target/ records the exact feature set that produced ;; the .a, so future builds rebuild iff features changed or any .rs source ;; is newer than the .a (jerboa-shell uses the same pattern). -(define jcode-cargo-features "tls,sqlite,crypto") +(define jcode-cargo-features "tls,crypto") (define native-lib-path (format "~a/jerboa-native-rs/target/x86_64-unknown-linux-musl/release/libjerboa_native.a" jerboa-dir-base)) @@ -554,6 +530,7 @@ (display "#include <sys/wait.h>\n" out) ;; waitpid (display "#include <sys/resource.h>\n" out) ;; getrlimit (display "#include <sys/prctl.h>\n" out) ;; prctl + (display "#include <sys/file.h>\n" out) ;; flock (display "#include <termios.h>\n" out) ;; tcgetattr/tcsetattr/tcgetpgrp/tcsetpgrp (display "#include <signal.h>\n" out) ;; kill, sigemptyset/sigprocmask family (display "#include <time.h>\n" out) ;; localtime, strftime @@ -626,20 +603,6 @@ gcc harden-cflags scheme-h-dir build-dir program-c)) -;; Compile jerboa-sqlite shim -;; Copy sqlite3.h to build dir (can't use -I/usr/include with musl-gcc — glibc conflict) -(let ([shim-src "vendor/jerboa-sqlite/jerboa_sqlite_shim.c"] - [sqlite3-h "/usr/include/sqlite3.h"]) - (if (file-exists? shim-src) - (begin - (when (file-exists? sqlite3-h) - (system (format "cp '~a' '~a/'" sqlite3-h build-dir))) - (run-cmd (format "~a -c -O2 ~a -I'~a' -o '~a/jerboa-sqlite-shim.o' '~a' -Wall" - gcc harden-cflags build-dir build-dir shim-src))) - (begin - (printf " Note: jerboa-sqlite shim not found — creating stub~n") - (system (format "echo '' | ~a -c -x c -o '~a/jerboa-sqlite-shim.o' -" gcc build-dir))))) - ;; Compile termbox2 TUI shim (run-cmd (format "~a -c -O2 ~a -DTB_OPT_ATTR_W=32 -Ivendor/termbox2 -o '~a/jcode-tui-shim.o' src/jcode/ui/jcode_tui_shim.c -Wall" gcc harden-cflags build-dir)) @@ -661,13 +624,10 @@ "jcode-musl" (list (format "~a/jcode_main_musl.o" build-dir) (format "~a/static_boot.o" build-dir) - (format "~a/jerboa-sqlite-shim.o" build-dir) (format "~a/jcode-tui-shim.o" build-dir) (format "~a/landlock-shim.o" build-dir)) - ;; Rust native lib includes sqlite3, TLS (rustls), regex, etc. - (if has-native-lib? - (list native-lib-path) - (list "/usr/lib/x86_64-linux-gnu/libsqlite3.a")) + ;; Rust native lib includes TLS, crypto, regex, aproc, etc. + (list native-lib-path) '(no-harden: #t))]) ;; GCC 13+ libgcc_eh.a references _dl_find_object (glibc 2.35+) which ;; doesn't exist in musl. Stub it out with --defsym. --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -40,12 +40,14 @@ prerequisites, building on each platform, configuration, and your first session. ## Vendored dependencies -Three repos are cloned into `vendor/` at build time (the directory is -git-ignored — these are **not** submodules): +Two repos are cloned into `vendor/` at build time (the directory is git-ignored +— these are **not** submodules). Session storage uses the sibling `jsqlite` +checkout at `~/mine/jsqlite` by default; set `JSQLITE_DIR=/path/to/jsqlite` if +it lives elsewhere. | Dependency | Source | |---|---| -| `jerboa-sqlite` | `git.sr.ht/~lisp/jerboa-sqlite` — SQLite FFI shim for session storage | +| `jsqlite` | `~/mine/jsqlite` — pure Scheme SQLite-compatible session storage | | `termbox2` | `github.com/termbox/termbox2` — the TUI's terminal backend | | `jerboa-websearch` | `git.sr.ht/~lisp/jerboa-websearch` — in-process web search | @@ -54,7 +56,6 @@ over HTTPS: ```bash mkdir -p vendor -git clone --depth 1 https://git.sr.ht/~lisp/jerboa-sqlite vendor/jerboa-sqlite git clone --depth 1 https://github.com/termbox/termbox2.git vendor/termbox2 git clone --depth 1 https://git.sr.ht/~lisp/jerboa-websearch vendor/jerboa-websearch ``` --- a/docs/local-model-smartness-plan.md +++ b/docs/local-model-smartness-plan.md @@ -115,7 +115,8 @@ As of this plan, the harness already has: - MCP tool discovery and MCP-origin workflow tool exposure. - Automatic `jerboa_request_advisor` preflight for Jerboa-looking verified tasks. -- MCP failure advisor on failing verify results. +- Failed verify augmentation with source targets, MCP failure advice, MCP + error-fix lookup, and MCP anti-pattern lookup. - Native edit aliases for `old_str`/`new_str` and `old_string`/`new_string`. This plan builds on those capabilities. @@ -764,7 +765,7 @@ Add a trace summarizer that extracts: ### Failure Pattern Data -Create a local data file: +For raw eval summaries, create a local data file: ```text data/local-model-failures.sexp @@ -787,6 +788,17 @@ Example entry: (tests . ("verified-run: exact replacement aliases can repair rejected draft"))) ``` +For reusable lessons, update the persistent Jerboa knowledge bases instead of +only keeping local eval notes: + +- working pattern: `~/mine/jerboa/data/cookbooks.sexp` via `jerboa_howto_add` +- plausible failed strategy: `~/mine/jerboa/data/anti-patterns.sexp` after + checking `jerboa_anti_pattern_lookup` +- exact repeated error text: `~/mine/jerboa/data/error-fixes.sexp` via + `jerboa_error_fix_add` +- missing harness or MCP capability: `~/mine/jerboa/data/features.sexp` via + `jerboa_suggest_feature` + ### Automated Recommendations The summarizer should produce suggestions: @@ -1082,22 +1094,25 @@ For `jerboa_failure_advisor`, support: On failing verify: 1. Run internal classifiers. -2. Call MCP failure advisor. -3. Merge advice. -4. Set required action if the diagnosis is concrete. -5. Include compact explanation in model context. +2. Add source call-site targets for runtime primitive failures when the failing + file or write-scope target is available. +3. Call MCP failure advisor, error-fix lookup, and anti-pattern lookup. +4. Merge advice. +5. Set required action if the diagnosis is concrete. +6. Include compact explanation in model context. Conflict rule: - Internal verifier diagnosis wins for exact line/range. -- MCP can add anti-pattern guidance. +- MCP can add failure, error-fix, and anti-pattern guidance. - If MCP suggests a different exact repair, log both and choose the safer one. ### Tests - structured MCP repair sets required action - internal repair overrides vague MCP advice -- passing verify does not call failure advisor +- passing verify does not call failure advisors/lookups +- runtime primitive errors point at likely source call sites - malformed MCP response does not crash ### Acceptance Criteria --- a/docs/verified.md +++ b/docs/verified.md @@ -261,8 +261,9 @@ There are four current integration paths: 1. Automatic preflight: for Jerboa-looking tasks, `jcode verified` calls a registered MCP `jerboa_request_advisor` before the first model turn. -2. Failure repair: failed verifier output is augmented with - `jerboa_failure_advisor` when that MCP tool is available. +2. Failure repair: failed verifier output is augmented with source target + call sites plus `jerboa_failure_advisor`, `jerboa_error_fix_lookup`, and + `jerboa_anti_pattern_lookup` when those MCP tools are available. 3. Manual guidance: pre-generate a cookbook/task bundle and pass it with `--guidance-file`. 4. Let the model call MCP tools during the verified workflow. @@ -395,7 +396,10 @@ For Jerboa coding tasks, use this pattern: - the guidance file, - MCP enabled. 4. Let the model repair against actual Scheme/Jerboa errors. -5. If it fails, improve the cookbook with the failure pattern you saw. +5. If it fails, save the lesson in the right knowledge base: + - working reusable pattern -> `cookbooks.sexp` / `jerboa_howto_add` + - plausible bad strategy -> `anti-patterns.sexp` + - exact error text with reusable repair -> `error-fixes.sexp` / `jerboa_error_fix_add` ``` Example: @@ -494,7 +498,7 @@ If this still loops: - narrow the task, - add a better `--guidance-file`, - use `--no-run-aliases`, -- increase cookbook anti-pattern coverage for the failure you saw. +- increase anti-pattern or error-fix coverage for the failure you saw. ### The run passes but the behavior is wrong --- a/linux-check.ss +++ b/linux-check.ss @@ -18,7 +18,7 @@ ;;; make linux-check ;;; ;;; Direct: -;;; scheme -q --libdirs "$JERBOA_HOME/lib:./lib:vendor/jerboa-sqlite/src" \ +;;; scheme -q --libdirs "$JERBOA_HOME/lib:./lib:$HOME/mine/jsqlite/src:vendor/jerboa-websearch/src" \ ;;; --script linux-check.ss (import (chezscheme)) --- a/src/jcode/core/builtin-skills.ss +++ b/src/jcode/core/builtin-skills.ss @@ -15,13 +15,14 @@ (def *save-discoveries-prompt* (string-append -"Review what was learned during this session and save it in three ways.\n" +"Review what was learned during this session and save it in five ways.\n" "\n" -"All discoveries are written to the jerboa-mcp repository at\n" -"~/mine/jerboa-mcp via the jerboa MCP tools (jerboa_howto_add,\n" -"jerboa_suggest_feature, jerboa_security_pattern_add). Pass NO\n" -"cookbook_path / features_path / rules_path arguments — let them default\n" -"to the global jerboa-mcp paths.\n" +"All discoveries are written to the Jerboa repository at ~/mine/jerboa.\n" +"Use jerboa MCP writer tools when they exist (jerboa_howto_add,\n" +"jerboa_anti_pattern_add, jerboa_error_fix_add, jerboa_suggest_feature,\n" +"jerboa_security_pattern_add). Pass NO cookbook_path / anti_patterns_path /\n" +"error_fixes_path / features_path / rules_path arguments —\n" +"let them default to the global Jerboa data paths.\n" "\n" "## Step 1: Save Cookbook Recipes\n" "\n" @@ -39,7 +40,44 @@ "\n" "Skip trivial one-liners and project-specific business logic.\n" "\n" -"## Step 2: Suggest Tooling Improvements\n" +"## Step 2: Save Anti-Patterns\n" +"\n" +"For each plausible model mistake, failed strategy, weak verifier, or repeated\n" +"bad edit pattern noticed during this session:\n" +"\n" +"1. Call `jerboa_anti_pattern_lookup` with relevant keywords to check if an entry already exists.\n" +"2. If not found, call `jerboa_anti_pattern_add` with:\n" +" - `id`: kebab-case identifier\n" +" - `title`: human-readable title\n" +" - `kinds`: one or more of `all`, `script`, `module`, `debug-error`, `docs`, `test`, `security`, `ffi`\n" +" - `severity`: `high` | `medium` | `low`\n" +" - `tags`: 4-6 search keywords\n" +" - `pattern`: regex or compact text pattern that identifies the mistake or error\n" +" - `avoid`: what the model should stop doing\n" +" - `advice`: the concrete replacement behavior\n" +" - `tools`: MCP tools or workflow tools that help avoid or repair it\n" +"\n" +"Save the normalized reusable mistake, not the whole failed trace. For example,\n" +"save upper-bound-only grid checks before vector-ref rather than a benchmark name.\n" +"\n" +"## Step 3: Save Error Fixes\n" +"\n" +"For each concrete compiler, verifier, runtime, or tool error where the repair\n" +"is reusable:\n" +"\n" +"1. Call `jerboa_error_fix_lookup` with the exact error text to check for duplicates.\n" +"2. If not found, call `jerboa_error_fix_add` with:\n" +" - `id`: kebab-case identifier\n" +" - `pattern`: regex matching the important error text\n" +" - `fix`: concise repair instruction\n" +" - Optional `type`: category such as `syntax`, `arity`, `runtime`, `module-resolution`, `vector-bounds`\n" +" - Optional `explanation`: why the error happens\n" +" - Optional `code_example`: minimal before/after or fixed snippet\n" +"\n" +"Save error fixes when the same error is likely to recur. Do not save one-off\n" +"project business logic failures.\n" +"\n" +"## Step 4: Suggest Tooling Improvements\n" "\n" "For each workflow friction point or missing tool capability noticed\n" "during this session:\n" @@ -56,7 +94,7 @@ " - `example_scenario`: concrete example of the problem\n" " - `estimated_token_reduction`: e.g. \"~500 tokens per invocation\", \"eliminates 3 tool calls\"\n" "\n" -"## Step 3: Add Security Patterns\n" +"## Step 5: Add Security Patterns\n" "\n" "For each new vulnerability pattern, unsafe coding practice, or FFI misuse\n" "discovered during this session:\n" @@ -84,6 +122,13 @@ "- Arity or signature discoveries that weren't obvious\n" "- Module path conventions (e.g. `(std text json)` not `:std/text/json`)\n" "\n" +"Anti-patterns to save:\n" +"- Repeated local-model mistakes that look plausible but fail verification\n" +"- Weak verifier patterns that allow false success\n" +"- Failed repair loops such as broad reading after a concrete verifier error\n" +"- Runtime mistakes such as missing lower-bound checks before vector access\n" +"- Hidden benchmark-specific shortcuts that invalidate evaluation\n" +"\n" "Features to suggest or vote for:\n" "- Multiple sequential tool calls that could be a single tool\n" "- Missing tool parameters or modes\n" @@ -91,6 +136,12 @@ "- Repeated cross-session patterns that could be automated\n" "- If the friction matches an existing feature suggestion, vote for it instead of creating a duplicate\n" "\n" +"Error fixes to save:\n" +"- Exact compiler/runtime/verifier messages with a repeatable repair\n" +"- Error text that `jerboa_failure_advisor` could classify better next time\n" +"- Errors from local-model generated code where a short diagnosis prevents another failed iteration\n" +"- Tool-output failures that need a known workaround\n" +"\n" "Security patterns to add:\n" "- New vulnerability patterns found during code review or debugging\n" "- Unsafe FFI calling conventions (missing null checks, type mismatches with `foreign-procedure`)\n" @@ -98,7 +149,8 @@ "- Resource leaks (ports, fds, mutexes) without `unwind-protect` / `dynamic-wind`\n" "- Unsafe C shim patterns (buffer overflows, static globals, missing error checks)\n" "\n" -"Report what was saved, suggested, voted for, and security patterns added when done.\n")) +"Report what recipes, anti-patterns, error fixes, feature suggestions/votes,\n" +"and security patterns were saved when done.\n")) ;; ── Plan-lifecycle skills ──────────────────────────────────────────── ;; Ported from opencode-processing-skills: a file-based plan workflow