Implement update features
ober
8237f0c305423bd4648b57656848e7c79e4c8d3a
--- a/AGENTS.md +++ b/AGENTS.md @@ -519,6 +519,9 @@ of silently skipping scanner coverage. **The knowledge base is `data/*.sexp` in THIS repo**, embedded into `jmcp` at build time. The write tools above edit it live — the server reads `data/` from disk first, with the embedded copy as fallback (`JERBOA_MCP_REPO` points every client at this repo). When you add a stdlib/language feature, also update `data/` (a cookbook recipe + `api-signatures.sexp` + `changelog.sexp`) and **commit it**. Run `make jmcp` (or `make jmcp-portable`) only to refresh the embedded copy shipped in portable binaries. +If an MCP client reports `Transport closed`, reconnecting is client-side. Use a fresh local stdio fallback instead of guessing tool syntax: +`printf '%s\n' '<json-rpc-tools-call>' | JERBOA_MCP_REPO=/Users/user/mine/jerboa /Users/user/mine/jerboa/jmcp` + ### Code Generation & Refactoring `jerboa_rename_symbol`, `jerboa_balanced_replace`, `jerboa_balanced_insert`, `jerboa_write_file`, `jerboa_repair_balance`, `jerboa_wrap_form`, `jerboa_splice_form`, `jerboa_scaffold_test`, `jerboa_generate_module`, `jerboa_translate_scheme`, `jerboa_project_template`, `jerboa_httpd_handler_scaffold`, `jerboa_db_pattern_scaffold`, `jerboa_actor_ensemble_scaffold` --- a/Makefile +++ b/Makefile @@ -6,6 +6,14 @@ export SOURCE_DATE_EPOCH HOST_UNAME_S := $(shell uname -s) HOST_UNAME_M := $(shell uname -m) HOST_UNAME_O := $(shell uname -o 2>/dev/null || true) +# Use ditto on macOS to preserve metadata (resource forks, extended attributes) +# which is critical for code signing. Falls back to cp on other systems. +ifeq ($(HOST_UNAME_S),Darwin) +CP := ditto +else +CP := cp +endif +ATOMIC_CP = tmp="$2.tmp.$$PPID"; $(CP) "$1" "$$tmp" && mv -f "$$tmp" "$2" # SQLite is fetched from the revision-pinned jerboa-sqlite Forgejo repository. # Packet capture remains explicit opt-in because rscap 0.3 does not compile # with the supported Rust toolchain. @@ -742,7 +750,11 @@ BINDIR ?= $(PREFIX)/bin install: @test -x "$(CURDIR)/dist/jerboa" || { echo "ERROR: dist/jerboa not built — run 'make jerboa' first" >&2; exit 1; } @mkdir -p "$(BINDIR)" - @install -m 0755 "$(CURDIR)/dist/jerboa" "$(BINDIR)/jerboa" + @# Use ditto on macOS to preserve metadata (critical for code signing) + @case "$$(uname -s)" in \ + Darwin) ditto "$(CURDIR)/dist/jerboa" "$(BINDIR)/jerboa" ;; \ + *) install -m 0755 "$(CURDIR)/dist/jerboa" "$(BINDIR)/jerboa" ;; \ + esac @# macOS: overwriting a Mach-O in place invalidates its (ad-hoc) code @# signature, so the kernel SIGKILLs it ("Killed: 9"). Re-sign ad-hoc. @case "$$(uname -s)" in Darwin) \ @@ -791,7 +803,7 @@ jerboa-macos-arm64: jerboa *) 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 + @$(CP) 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/ ===" @@ -828,7 +840,7 @@ jerboa-android-arm64: jerboa *) echo "ERROR: android-arm64 release artifact must be built on Termux/Android arm64" >&2; exit 1 ;; \ esac @mkdir -p dist/android-arm64 - @cp -f dist/jerboa dist/android-arm64/jerboa + @$(CP) dist/jerboa dist/android-arm64/jerboa @chmod 0755 dist/android-arm64/jerboa @for link in jmcp jlsp jerbuild jpkg; do ln -sf jerboa dist/android-arm64/$$link; done @echo "=== Staged jerboa multicall: android-arm64 -> dist/android-arm64/ ===" @@ -1012,8 +1024,8 @@ release-evidence: tools/tcb-report.ss .jerboa-system \ > "$(EVIDENCE_DIR)/release-inputs-sha256.txt" rm -rf "$(EVIDENCE_DIR)/sbom" "$(EVIDENCE_DIR)/reproducibility" - cp -R "$(SBOM_DIR)" "$(EVIDENCE_DIR)/sbom" - cp -R "$(REPRO_DIR)" "$(EVIDENCE_DIR)/reproducibility" + $(CP) -R "$(SBOM_DIR)" "$(EVIDENCE_DIR)/sbom" + $(CP) -R "$(REPRO_DIR)" "$(EVIDENCE_DIR)/reproducibility" grep -q '^signature_status=' "$(EVIDENCE_DIR)/signing/status.txt" grep -q '^path_leak_status=pass$$' "$(EVIDENCE_DIR)/path-leaks.txt" grep -q '^status=match$$' "$(EVIDENCE_DIR)/reproducibility/result.txt" @@ -1143,9 +1155,9 @@ chez-cross: $(SCHEME) @echo "==> [chez-cross] stage target boot files + generated headers into cross dir" @mkdir -p $(CHEZ_CROSS_BUILD_DIR)/boot/$(CHEZ_TARGET_MACHINE) @mkdir -p $(CHEZ_CROSS_BUILD_DIR)/$(CHEZ_TARGET_MACHINE)/boot/$(CHEZ_TARGET_MACHINE) - cp $(CHEZ_BUILD_DIR)/boot/$(CHEZ_TARGET_MACHINE)/* \ + $(CP) $(CHEZ_BUILD_DIR)/boot/$(CHEZ_TARGET_MACHINE)/* \ $(CHEZ_CROSS_BUILD_DIR)/boot/$(CHEZ_TARGET_MACHINE)/ - cp $(CHEZ_BUILD_DIR)/boot/$(CHEZ_TARGET_MACHINE)/* \ + $(CP) $(CHEZ_BUILD_DIR)/boot/$(CHEZ_TARGET_MACHINE)/* \ $(CHEZ_CROSS_BUILD_DIR)/$(CHEZ_TARGET_MACHINE)/boot/$(CHEZ_TARGET_MACHINE)/ @echo "==> [chez-cross] build target libkernel.a" @# CHOST tells the bundled zlib's configure to use the cross-prefix toolchain @@ -1226,8 +1238,7 @@ native-cross: --no-default-features \ $(if $(CROSS_NATIVE_FEATURES),--features $(CROSS_NATIVE_FEATURES)) @mkdir -p lib-cross/$(CHEZ_TARGET_MACHINE) - cp $(RUST_NATIVE_DIR)/target/$(RUST_TARGET)/release/libjerboa_native.$(CROSS_NATIVE_EXT_$(CHEZ_TARGET_MACHINE)) \ - lib-cross/$(CHEZ_TARGET_MACHINE)/ + $(call ATOMIC_CP,$(RUST_NATIVE_DIR)/target/$(RUST_TARGET)/release/libjerboa_native.$(CROSS_NATIVE_EXT_$(CHEZ_TARGET_MACHINE)),lib-cross/$(CHEZ_TARGET_MACHINE)/libjerboa_native.$(CROSS_NATIVE_EXT_$(CHEZ_TARGET_MACHINE))) @echo "==> [native-cross] -> lib-cross/$(CHEZ_TARGET_MACHINE)/libjerboa_native.$(CROSS_NATIVE_EXT_$(CHEZ_TARGET_MACHINE))" # Cross-compiled binary. Drives support/build-binary.sh with TARGET_* env. @@ -2894,7 +2905,7 @@ $(RUST_NATIVE_LIB): $(RUST_NATIVE_DIR)/src/*.rs $(RUST_NATIVE_DIR)/Cargo.toml native: cd $(RUST_NATIVE_DIR) && cargo build --locked --release --features $(JERBOA_NATIVE_FEATURES) - cp $(RUST_NATIVE_LIB) lib/ + $(call ATOMIC_CP,$(RUST_NATIVE_LIB),lib/libjerboa_native.$(NATIVE_LIB_EXT)) ifeq ($(UNAME_S),Darwin) @# Re-sign ad-hoc so dyld accepts the freshly-copied dylib. @# Without this, Cargo's linker-signed signature can be left in an --- a/data/anti-patterns.sexp +++ b/data/anti-patterns.sexp @@ -4973,8 +4973,9 @@ ("id" . "typed-android-missing-asset-dir") ("kinds" "android" "typed" "build") ("pattern" + . "FileNotFoundException.*\\.csv|AssetManager.*open|box_types") - ("severity" "critical") + ("severity" . "critical") ("tags" "android" "assets" "crash" "runtime" "typed" "generator") ("title" @@ -4990,8 +4991,9 @@ ("id" . "typed-android-intent-chaining") ("kinds" "android" "typed" "code") ("pattern" + . "intentAddFlagsRaw.*intentDataSetRaw|intentDataSetRaw.*intentTypeSetRaw") - ("severity" "high") + ("severity" . "high") ("tags" "android" "intent" "typed" "unit" "side-effect" "begin") ("title" @@ -5006,8 +5008,8 @@ "Do not ship APKs to the user without emulator testing. Do not scp to termux as the only verification step. The human should never discover a crash by installing the APK themselves.") ("id" . "typed-android-skip-emulator-test") ("kinds" "android" "typed" "workflow") - ("pattern" "scp.*termux.*apk|push.*apk.*device") - ("severity" "critical") + ("pattern" . "scp.*termux.*apk|push.*apk.*device") + ("severity" . "critical") ("tags" "android" "emulator" "adb" "test" "workflow" "mandatory") ("title" @@ -5022,8 +5024,10 @@ "Do not define functions in typed-library forms without adding them to the (export ...) list. Unexported functions cause cryptic unknown-value errors at compile time, not at the definition site but at the call site in other modules.") ("id" . "typed-android-missing-export") ("kinds" "android" "typed" "code") - ("pattern" "unknown-value.*typed modules have check errors") - ("severity" "high") + ("pattern" + . + "unknown-value.*typed modules have check errors") + ("severity" . "high") ("tags" "android" "typed" "export" "unknown-value" "compile") ("title" @@ -6003,4 +6007,43 @@ ("title" . "Never purge the jerbuild toolchain-home cache as 'stale artifacts'") - ("tools" "jerboa_compile_check" "jerboa_make"))) + ("tools" "jerboa_compile_check" "jerboa_make")) + (("advice" + . + "Before using convenience string APIs, confirm the symbol in the exact import set with jerboa_eval, jerboa_apropos, or jerboa_module_exports. Prefer an existing local helper such as replace-all when present, or add a verified helper instead of relying on cross-dialect names.") + ("avoid" + . + "Do not use string-replace in Jerboa server or tooling code just because a quick reference or another Scheme dialect suggests it exists. In current MCP server imports it can be unbound and only fail when the code path is exercised.") + ("id" . "assume-prelude-string-replace-exists") + ("kinds" "code" "debug-error") + ("pattern" . "string-replace") ("severity" . "medium") + ("tags" "jerboa" "prelude" "string" "unbound" "mcp") + ("title" + . + "Do Not Assume string-replace Is Available In Jerboa Server Code") + ("tools" + "jerboa_eval" + "jerboa_apropos" + "jerboa_module_exports" + "jerboa_verify")) + (("advice" + . + "In Jerboa source, pass aproc option keys as explicit symbols, e.g. `(aproc-spawn* argv (string->symbol \"stdin:\") 'null (string->symbol \"stdout:\") 'null)`, or verify the exact convention with existing aproc tests/source before using keyword-looking arguments.") + ("avoid" + . + "Do not pass aproc-spawn* options in Jerboa .ss source with reader keyword syntax such as stdin: or new-pgroup:. The Jerboa reader turns those into keyword objects, while (std os aproc) expects symbols named \"stdin:\", \"new-pgroup:\", etc.") + ("id" . "aproc-spawn-star-symbol-keywords-in-jerboa-source") + ("kinds" "code" "script" "debug-error") + ("pattern" + . + "aproc-spawn\\*.*\\b(stdin|stdout|stderr|dir|new-pgroup):") + ("severity" . "medium") + ("tags" "aproc" "keywords" "jerboa" "subprocess" "mcp") + ("title" + . + "Use Symbol Keys For aproc-spawn* In Jerboa Source") + ("tools" + "jerboa_eval" + "jerboa_verify" + "jerboa_module_exports" + "jerboa_error_fix_lookup"))) --- a/data/api-signatures.sexp +++ b/data/api-signatures.sexp @@ -4152,7 +4152,8 @@ ("exports" "MADV_DONTNEED" "MADV_RANDOM" "MADV_SEQUENTIAL" "MADV_WILLNEED" "madvise" "mmap->bytevector" "mmap-bytes-search" "mmap-bytes=?" "mmap-copy-in!" - "mmap-file" "mmap-find-byte" "mmap-region-addr" + "mmap-copy-out!" "mmap-file" "mmap-find-byte" + "mmap-range->bytevector" "mmap-region-addr" "mmap-region-mode" "mmap-region-size" "mmap-region?" "mmap-s16-ref" "mmap-s32-ref" "mmap-s64-ref" "mmap-s8-ref" "mmap-u16-ref" "mmap-u16-set!" "mmap-u32-ref" @@ -5102,7 +5103,8 @@ "MADV_WILLNEED" "MAP_ANONYMOUS" "MAP_PRIVATE" "MAP_SHARED" "MS_ASYNC" "MS_INVALIDATE" "MS_SYNC" "PROT_EXEC" "PROT_READ" "PROT_WRITE" "madvise" "mmap" "mmap->bytevector" - "mmap-copy-in!" "mmap-region-addr" "mmap-region-mode" + "mmap-copy-in!" "mmap-copy-out!" "mmap-range->bytevector" + "mmap-region-addr" "mmap-region-mode" "mmap-region-size" "mmap-region?" "mmap-s16-ref" "mmap-s32-ref" "mmap-s64-ref" "mmap-s8-ref" "mmap-u16-ref" "mmap-u16-set!" "mmap-u32-ref" "mmap-u32-set!" @@ -14256,7 +14258,9 @@ ("mmap-bytes-search" "(std mmap)") ("mmap-bytes=?" "(std mmap)") ("mmap-copy-in!" "(std mmap)" "(std os mmap)") + ("mmap-copy-out!" "(std mmap)" "(std os mmap)") ("mmap-file" "(std mmap)") ("mmap-find-byte" "(std mmap)") + ("mmap-range->bytevector" "(std mmap)" "(std os mmap)") ("mmap-region-addr" "(std mmap)" "(std os mmap)") ("mmap-region-mode" "(std mmap)" "(std os mmap)") ("mmap-region-size" "(std mmap)" "(std os mmap)") --- a/data/changelog.sexp +++ b/data/changelog.sexp @@ -2,6 +2,97 @@ . "Machine-readable changelog of Jerboa API drift. Consumers (LLM tooling, lints, jerboa_verify) use this to invalidate stale recommendations and to suggest migrations when a symbol is renamed or relocated.") ("entries" + (("added" "jerboa_stale_static extensions/include_vendored" + "jerboa script runtime shebang tolerance" + "multicall jerboa run script alias" + "jerboa_check_syntax file_path" + "jerboa_verify project-file command diagnostics" + "jerboa_compile_check Gerbil-style import diagnostics" + "jerboa_verify project-derived libdirs" + "jerboa_verify prelude shadow excepts" + "jerboa_verify jerbuild source parity" + "jerboa_write_file typed-library fixture verification" + "jerboa_run_tests project_path cache staleness guard" + "jerboa_security_scan generated-code context markers" + "jerboa_security_scan u8star foreign-alloc dataflow precision" + "jerboa_benchmark_guard model preflight port isolation process guard" + "atomic native artifact install temp-rename" + "jerboa_visual_regression_check TUI buffer and Qt geometry assertions" + "jerboa_goal_checklist_runner handoff next-item benchmark delta" + "jerboa_ai_scaffold_ml Rust ML FFI scaffold drafts" + "jerboa_mux_pty_regression_helper consumed-buffer PTY flow" + "jerboa_target_evidence_privacy_scaffold" + "jerboa_trusted_file_metadata stat preflight" + "std mmap-copy-out! and mmap-range->bytevector" + "multicall bundle tar .incbin embedding" + "jerboa_security_scan changed_only git diff fallback" + "jerboa_security_scan data-driven rule exclusions" + "jerboa_apropos patterns batch mode" + "jerboa_howto_verify bounded failure diagnostics" + "jerboa_repair_error direct helper" + "MCP tool result void/null guard" + "ffi no-entry preload failure advice" + "balance repair action hints" + "jerboa_make completion status tail" + "request advisor compact signatures and workflow gotchas" + "bounded jerboa_read_source line-range reader" + "MCP introspection stale-artifact recovery" + "jerboa_verify stale compilation-instance diagnosis" + "jerboa_verify WPO export-resolution failures" + "jerboa_verify entry-file import-closure mode" + "jerboa_fleet_security_scan workspace/fleet/make-target audit" + "jerboa_repo_snapshot source-only copy" + "entry-aware static symbol audit" + "ffi ABI manifest and canary generator" + "ffi provider symbol closure audit" + "packaged entry import closure audit" + "jcode verified explicit tool manifest" + "jcode rejected draft quarantine" + "jcode verified local text-response hard stop" + "jcode verified mid-run immutable diff policy" + "jcode verified inferred greenfield write scope" + "jcode verified local targeted MCP allowlist and budgets" + "jcode verified dependency context bundle" + "jcode trace health summary" + "jcode child process registry and exit reaper" + "jcode repl-reader direct loopback TCP" + "jcode verified outcome no-progress breaker" + "jcode verified exact next-command hints" + "jcode subprocess hang diagnostic bundle" + "feature manifest drift checker" + "test target baseline diff helper" + "chez builtin shadow except predictor" + "generated SLS source layout audit" + "invalid context definition diagnoser" + "source form span repair helper" + "MCP timeout phase progress reports" + "MCP transport closed stdio fallback guidance" + "jerboa_prompt_to_code local LLM verification loop" + "source-backed macro signatures" + "jerboa_verify Chez reader spelling normalization" + "MCP project src libdir probing" + "jerboa_verify generated jerbuild module diagnostics" + "jerboa_process_resource_usage" + "jerboa_verify top-level form failure locations" + "jerboa_check_syntax dynamic-wind regression coverage" + "release evidence status summarizer" + "release evidence stale core toolchain verifier" + "cross-repo release evidence matrix" + "target proof marker verifier" + "release evidence privacy audit" + "canonical jerboa file.ss script guidance" + "JSON UTF-16 surrogate-pair escape decoding") + ("date" . "2026-08-02") + ("modules_added") + ("moved") + ("notes" + . + "Hardened anti-pattern lookup against list-valued string fields, corrected malformed anti-pattern data entries, made stale_static scan compiled artifacts directly with mtime/platform reporting, taught the runtime script loader to skip non-Chez shebang lines, added file_path support for check_syntax, made changed_only security scans infer changed lines from git diff HEAD when no explicit diff/base_ref/changed_lines are supplied, moved path-prefix security-scan false-positive suppressions into data-driven rule metadata, added cached batch pattern search to jerboa_apropos, made jerboa_howto_verify preserve bounded multi-line syntax-check diagnostics on failures, exposed direct error repair through jerboa_repair_error and critical jerboa_explain_error, added MCP tool result validation plus jerboa_tool_result_audit for void-tail handlers, taught jerboa_failure_advisor to diagnose FFI no-entry preload failures, added balance repair action hints to check_balance and repair_balance outputs, made jerboa_make report completion status, exit status, and bounded final output tails, extended jerboa_request_advisor with compact signature lookups, workflow gotchas, and debug repair ladders, added bounded jerboa_read_source/jerboa_read/read line-range source reads for large files, made module export/signature introspection detect stale compilation-instance mismatches and optionally clean stale compiled artifacts before retrying, made jerboa_verify and WPO verify diagnose stale compilation-instance mismatches and optionally clean stale artifacts before one retry, made jerboa_verify WPO mode catch export-resolution failures from source-file compilation and report compile-whole-program missing libraries as structured closure errors, made jerboa_verify entry_file/closure_entry imply import-closure WPO verification without a separate file_path, added jerboa_fleet_security_scan for multi-repo security scanning, workspace status interleaving, conventional Makefile target auditing, markdown rollups, and fenced JSON output, added jerboa_repo_snapshot for dry-run or explicit source-only tracked-file snapshots that exclude generated build artifacts and normalize target modes, added jerboa_generated_sls_source_layout_audit to find tracked non-vendor .sls files, .ss files under generated output roots, and top-level library forms in .ss source, added jerboa_invalid_context_definition_diagnoser to locate enclosing top-level definitions and replace ranges for invalid-context definition errors, added jerboa_source_form_spans for top-level/focused form spans, nested definition lines, swallowing indicators, and paste-ready replace_range JSON, made MCP subprocess timeouts emit tool.phase progress logs plus structured JERBOA-MCP-TIMEOUT-REPORT details with phase, target, timeout, command, and fallback guidance, made closed MCP transport recovery explicit by guarding/logging response-write failures and documenting the fresh local jmcp stdio JSON-RPC fallback in compact manifests and AGENTS.md, added jerboa_prompt_to_code for local/OpenAI-compatible LLM code generation with cookbook context, fenced-code extraction, verify/repair retries, and a non-error no-endpoint skip path, made jerboa_function_signature return source-backed macro usage for defrule/defrules, syntax-rules, syntax-case, and ir-macro-transformer definitions with Kind: macro, full ellipsis-preserving usage, and source file:line fallback from project libdirs, made jerboa_verify normalize Chez reader token spellings such as #\\escape and #!void before syntax reading, made project-aware MCP module introspection probe project/src in addition to lib and build/lib, made jerboa_verify report jerbuild-module verification phase and generated library form when generated-library compilation fails, added jerboa_process_resource_usage for argv-only wait4 resource metrics including wall time, CPU time, raw max RSS, minor/major page faults, and context switches without /usr/bin/time, added check_syntax protocol coverage proving top-level dynamic-wind cleanup snippets remain valid through file_path/project_path, made jerboa_static_symbol_audit accept entry roots/imports and compute missing registrations from entry-reachable Scheme FFI declarations while keeping C-side registrations project-wide, added jerboa_ffi_abi_manifest for versioned required-symbol manifests, nm provider diffs, and generated fail-closed canary source, added jerboa_ffi_provider_symbol_closure_audit to compare declared FFI/provider symbols against readiness probes and static C registrations, added jerboa_packaged_entry_import_closure_audit for source/generated entry closure drift, object-cache coverage checks, and optional packaged-binary smoke output, added a canonical jcode verified tool manifest shared by prompt generation, visible/executable filtering, availability override notes, and unknown-tool ToolResolutionError guidance, added jcode rejected-draft quarantine persistence with sidecar metadata, retention caps, blind-loop path guidance, and status JSON exposure, added a local-model verified text-response hard stop that raises ToolCallHardStopError after repeated prose responses with zero tool calls and reports tool_call_hard_stop in status JSON, added mid-run jcode verified policy checks that fail the verify step after a passing command if immutable/forbidden/allowed diff policy is violated and include git diff --stat evidence, added env-gated jcode verified greenfield write-scope inference that narrows clean no-scope runs to a single .ss target or src/ and records inferred_write_scope in status JSON, added jerboa_builtin_shadow_except to predict Chez builtin shadows from Jerboa/std imports and emit the exact except clause, added jerboa_release_evidence_status to summarize readiness, stale evidence, and residual blockers in release evidence trees, added jerboa_release_evidence_toolchain_staleness to fail closed when a dependent repo's selected release-evidence toolchain is missing, older than core source changes, or paired with dirty core files, added jerboa_cross_repo_release_evidence_matrix to classify release-evidence target/evidence/security gate state across repos with markdown and JSON output, added jerboa_target_proof_marker_verifier to generate and validate fail-closed target proof scripts from policy.releaseEvidence marker specs, added jerboa_release_evidence_privacy_audit to scan evidence trees for private paths, SSH remotes, host identifiers, raw account/API output, stale nested copies, and redact-only sanitizers, normalized script guidance around canonical `jerboa file.ss` execution with `jerboa run file.ss` as a compatibility alias, and fixed (std text json) to decode valid UTF-16 surrogate-pair escapes while rejecting malformed pairs.") + ("removed") + ("renamed") + ("tier_changes") + ("tools_added") + ("version" . #f)) (("added") ("date" . "2026-08-01") ("modules_added") --- a/data/cookbooks.sexp +++ b/data/cookbooks.sexp @@ -171,7 +171,7 @@ ("title" . "File I/O")) (("code" . - "(import (std test))\n\n; Define a test suite\n(test-suite \"my-module tests\"\n \n (test \"basic arithmetic\"\n (check (+ 1 2) => 3)\n (check (- 10 3) => 7))\n \n (test \"string operations\"\n (check (string-length \"hello\") => 5)\n (check (string-append \"foo\" \"bar\") => \"foobar\"))\n \n (test \"list operations\"\n (check (length '(1 2 3)) => 3)\n (check (car '(1 2 3)) => 1)))\n\n; Run with: jerboa run test.ss") ("id" . "jerboa-test-suite") ("imports" "(std test)") + "(import (std test))\n\n; Define a test suite\n(test-suite \"my-module tests\"\n \n (test \"basic arithmetic\"\n (check (+ 1 2) => 3)\n (check (- 10 3) => 7))\n \n (test \"string operations\"\n (check (string-length \"hello\") => 5)\n (check (string-append \"foo\" \"bar\") => \"foobar\"))\n \n (test \"list operations\"\n (check (length '(1 2 3)) => 3)\n (check (car '(1 2 3)) => 1)))\n\n; Run with: jerboa test.ss") ("id" . "jerboa-test-suite") ("imports" "(std test)") ("notes" . "Tests use (std test) module. check compares with =>, string= for strings, equal? for structures.") @@ -179,10 +179,10 @@ ("title" . "Writing Tests")) (("code" . - "#!/usr/bin/env -S jerboa run\n\n; Or run manually:\n; jerboa run myscript.ss\n\n; Compile imported libraries for speed:\n; jerboa build\n\n(import (jerboa prelude))\n\n; Command-line args\n(def args (cdr (command-line)))\n\n(display \"Hello from Jerboa!\")\n(newline)") ("id" . "jerboa-run-script") ("imports") + "#!/usr/bin/env jerboa\n\n; Or run manually:\n; jerboa myscript.ss\n; Compatibility alias also works: jerboa run myscript.ss\n\n; Compile imported libraries for speed:\n; jerboa build\n\n(import (jerboa prelude))\n\n; Command-line args\n(def args (cdr (command-line)))\n\n(display \"Hello from Jerboa!\")\n(newline)") ("id" . "jerboa-run-script") ("imports") ("notes" . - "Set JERBOA_HOME to point to your Jerboa installation. Direct scripts run with the safe application prelude by default: raw foreign-procedure, system, eval, and fork-thread are unavailable. Use jerboa run --unsafe-prelude myscript.ss or (import (jerboa prelude unsafe)) only when raw Chez bindings are explicitly required; both paths warn. The --compile-imported-libraries flag pre-compiles .sls to .so for faster startup.") + "Set JERBOA_HOME to point to your Jerboa installation. Direct scripts run with the safe application prelude by default: raw foreign-procedure, system, eval, and fork-thread are unavailable. Use jerboa --unsafe-prelude myscript.ss or (import (jerboa prelude unsafe)) only when raw Chez bindings are explicitly required; both paths warn. The --compile-imported-libraries flag pre-compiles .sls to .so for faster startup.") ("tags" "run" "script" "scheme" "command line" "execute") ("title" . "Running a Jerboa Script")) (("code" @@ -448,7 +448,7 @@ ("title" . "Format String Directives")) (("code" . - "; File: lib/my-project/utils.sls\n(library (my-project utils)\n (export helper square greet)\n (import (jerboa prelude))\n\n (def (helper x) (* x 2))\n (def (square x) (* x x))\n (def (greet name) (format \"Hello, ~a!\" name)))\n\n; File: main.ss (script)\n(import (my-project utils))\n\n(displayln (greet \"World\")) ; => Hello, World!\n(displayln (square 5)) ; => 25\n\n; Run with:\n; jerboa run main.ss\n\n; Selective import in another module\n(import (only (my-project utils) square))\n(import (except (my-project utils) greet))\n(import (rename (my-project utils) (helper h)))") ("id" . "jerboa-library-definition") ("imports") + "; File: lib/my-project/utils.sls\n(library (my-project utils)\n (export helper square greet)\n (import (jerboa prelude))\n\n (def (helper x) (* x 2))\n (def (square x) (* x x))\n (def (greet name) (format \"Hello, ~a!\" name)))\n\n; File: main.ss (script)\n(import (my-project utils))\n\n(displayln (greet \"World\")) ; => Hello, World!\n(displayln (square 5)) ; => 25\n\n; Run with:\n; jerboa main.ss\n\n; Selective import in another module\n(import (only (my-project utils) square))\n(import (except (my-project utils) greet))\n(import (rename (my-project utils) (helper h)))") ("id" . "jerboa-library-definition") ("imports") ("notes" . "Jerboa uses R6RS library system. Files use .sls extension. Module path matches directory structure: (my-project utils) -> lib/my-project/utils.sls. Must explicitly list exports (no export-all). Use --libdirs to point to the lib/ directory.") @@ -487,7 +487,7 @@ ("title" . "Read errno value from Chez Scheme FFI")) (("code" . - ";;; BUG: Split top-level threaded setup can hang under jerboa run.\n;;; The forked thread may not run before the next top-level form evaluates.\n\n;; (define server (start-tcp-server! 0)) ;; forks thread\n;; (sleep-ms 200) ;; thread still hasn't run\n;; (define conn (tcp-connect \"127.0.0.1\" server)) ;; HANGS - nobody accepts\n\n;;; FIX 1: Wrap in begin (acts like a single top-level expression)\n(begin\n (define server (start-tcp-server! 0))\n (sleep (make-time 'time-duration 200000000 0))\n (define-values (in out) (tcp-connect \"127.0.0.1\" server))\n (get-line in))\n\n;;; FIX 2: Use let instead of define\n(let* ((server (start-tcp-server! 0))\n (dummy (sleep (make-time 'time-duration 200000000 0))))\n (define-values (in out) (tcp-connect \"127.0.0.1\" server))\n (get-line in))") ("id" . "jerboa-script-mode-threads") + ";;; BUG: Split top-level threaded setup can hang in Jerboa script mode.\n;;; The forked thread may not run before the next top-level form evaluates.\n\n;; (define server (start-tcp-server! 0)) ;; forks thread\n;; (sleep-ms 200) ;; thread still hasn't run\n;; (define conn (tcp-connect \"127.0.0.1\" server)) ;; HANGS - nobody accepts\n\n;;; FIX 1: Wrap in begin (acts like a single top-level expression)\n(begin\n (define server (start-tcp-server! 0))\n (sleep (make-time 'time-duration 200000000 0))\n (define-values (in out) (tcp-connect \"127.0.0.1\" server))\n (get-line in))\n\n;;; FIX 2: Use let instead of define\n(let* ((server (start-tcp-server! 0))\n (dummy (sleep (make-time 'time-duration 200000000 0))))\n (define-values (in out) (tcp-connect \"127.0.0.1\" server))\n (get-line in))") ("id" . "jerboa-script-mode-threads") ("imports" "(chezscheme)") ("notes" . @@ -527,7 +527,7 @@ ("imports" "(chezscheme)" "(std net tcp)") ("notes" . - "TCP server tests that reuse a single server instance accumulate stale connections/fds and eventually hang. Limit connections per server to 2-3, or use a fresh server per test group. Also: keep fork-thread setup and use in one top-level begin/let form under jerboa run, because split top-level forms may run before the helper thread is scheduled.") + "TCP server tests that reuse a single server instance accumulate stale connections/fds and eventually hang. Limit connections per server to 2-3, or use a fresh server per test group. Also: keep fork-thread setup and use in one top-level begin/let form under Jerboa script mode, because split top-level forms may run before the helper thread is scheduled.") ("tags" "tcp" "test" "server" "fork-thread" "pattern" "debug-repl") ("title" @@ -1349,7 +1349,7 @@ ("imports" "(std security import-audit)") ("notes" . - "Use in CI/build pipeline to prevent AI-generated code from bypassing the capability system via direct (chezscheme) imports. Trusted infrastructure modules (lib/jerboa/, lib/std/security/, etc.) are automatically exempt. Add to Makefile: jerboa run tools/audit-imports.ss") + "Use in CI/build pipeline to prevent AI-generated code from bypassing the capability system via direct (chezscheme) imports. Trusted infrastructure modules (lib/jerboa/, lib/std/security/, etc.) are automatically exempt. Add to Makefile: jerboa tools/audit-imports.ss") ("tags" "audit" "import" "security" "build" "policy" "chezscheme") ("title" . "Audit Source Files for Forbidden Imports")) @@ -2566,7 +2566,7 @@ ("imports" "(jerboa reader)") ("notes" . - "The #r\"...\" syntax is available when using the Jerboa reader (e.g. in the Jerboa REPL or when reading files with jerboa-read-all). In tests run via jerboa run, use jerboa-read-string to verify raw string parsing. The annotated-datum-value function only works when jerboa-read-string is called WITH a path argument (second arg); without it, values are returned plain.") + "The #r\"...\" syntax is available when using the Jerboa reader (e.g. in the Jerboa REPL or when reading files with jerboa-read-all). In script tests, use jerboa-read-string to verify raw string parsing. The annotated-datum-value function only works when jerboa-read-string is called WITH a path argument (second arg); without it, values are returned plain.") ("tags" "reader" "raw-string" "jerboa-read-string" "annotated-datum" "test") ("title" @@ -6948,15 +6948,13 @@ (("code" . "(import (jerboa prelude) (std pregexp))\n\n(def (normalize-json-surrogate-pairs text)\n (let loop ([start 0] [pieces '()])\n (let ([match-result\n (pregexp-match-positions \"\\\\\\\\u([dD][89aAbB][0-9A-Fa-f]{2})\\\\\\\\u([dD][c-fC-F][0-9A-Fa-f]{2})\" text start)])\n (if (not match-result)\n (apply string-append\n (reverse (cons (substring text start (string-length text)) pieces)))\n (let* ([whole (car match-result)]\n [high-span (list-ref match-result 1)]\n [low-span (list-ref match-result 2)]\n [high (string->number\n (substring text (car high-span) (cdr high-span)) 16)]\n [low (string->number\n (substring text (car low-span) (cdr low-span)) 16)]\n [codepoint (+ #x10000\n (* (- high #xD800) #x400)\n (- low #xDC00))])\n (loop (cdr whole)\n (cons (string (integer->char codepoint))\n (cons (substring text start (car whole)) pieces))))))))\n\n(def document\n (string->json-object\n (normalize-json-surrogate-pairs \"{\\\"emoji\\\":\\\"\\\\uD83E\\\\uDD86\\\"}\")))\n(displayln (hash-ref document \"emoji\"))") ("id" . "json-surrogate-pair-normalization") - ("imports" "(jerboa prelude)" "(std pregexp)") + ("imports" "(jerboa prelude)" "(std text json)") ("notes" . - "The current Jerboa JSON reader can raise 'expected low surrogate after high surrogate' for valid adjacent \\\\uD800-DBFF/\\\\uDC00-DFFF escapes. This bounded pre-pass converts only well-formed pairs to their scalar character, then leaves structured JSON parsing to string->json-object. Keep malformed or unpaired surrogates unchanged so the JSON parser rejects them.") + "(std text json) decodes valid adjacent UTF-16 high/low surrogate escapes directly in read-json/string->json-object. Malformed or unpaired surrogates still raise: lone high surrogates, low-first pairs, and high+non-low pairs are rejected.") ("tags" "json" "unicode" "surrogate-pair" "read-json" "pregexp" "duckdb") - ("title" - . - "Normalize JSON UTF-16 surrogate-pair escapes before parsing")) + ("title" . "Parse JSON UTF-16 surrogate-pair escapes")) (("code" . "(import (chezscheme))\n\n;; Pure-Scheme constant-time bytevector comparison.\n;; Does NOT short-circuit: always scans all n bytes, so runtime does\n;; not depend on WHERE the first difference is (no timing oracle).\n(define (constant-time-bytevector=? a b)\n (let ([n (bytevector-length a)])\n (and (= n (bytevector-length b))\n (let loop ([i 0] [acc 0])\n (if (= i n)\n (zero? acc)\n (loop (+ i 1)\n (bitwise-ior acc\n (bitwise-xor (bytevector-u8-ref a i)\n (bytevector-u8-ref b i)))))))))\n\n;; For strings (tokens, hex digests), compare their UTF-8 bytes:\n(define (constant-time-string=? a b)\n (constant-time-bytevector=? (string->utf8 a) (string->utf8 b)))\n\n;; Preferred when OpenSSL is already linked (jerboa-ssh C shim does this):\n;; CRYPTO_memcmp returns 0 on equal.\n;; (define crypto-memcmp\n;; (foreign-procedure \"CRYPTO_memcmp\" (uptr uptr size_t) integer))\n;; equal? => (= 0 (crypto-memcmp ptr-a ptr-b len))") ("id" . "constant-time-secret-comparison") @@ -8907,10 +8905,10 @@ ("title" . "Guard typed JSON scanner corpus coverage")) (("code" . - "# jerboa 0.2.8's safe-prelude script loader rejects BOTH `#!/usr/bin/env ...`\n# shebang lines and direct (scheme)/(chezscheme) imports. To run a legacy\n# test/script (e.g. test/run.ss):\ntail -n +2 test/run.ss > /tmp/run-noshebang.ss # strip the shebang line\njerbuild exec --unsafe-prelude --libdirs ./lib /tmp/run-noshebang.ss\n") ("id" . "run-raw-scheme-test-jerboa-028") ("imports") + "# Current Jerboa script mode tolerates a leading non-Chez shebang. To run a legacy\n# raw Chez-style test/script (e.g. test/run.ss), prefer converting it to Jerboa-facing\n# imports. If it must use direct Chez bindings, run through the Jerboa toolchain with\n# the unsafe prelude explicitly enabled:\njerbuild exec --unsafe-prelude --libdirs ./lib test/run.ss\n") ("id" . "run-raw-scheme-test-jerboa-028") ("imports") ("notes" . - "jerbuild is a symlink to the jerboa multicall binary. Script mode (`jerboa file.ss`) has no --libdirs flag in 0.2.8, and `jerboa run` does not exist in this release despite older docs. `#!chezscheme` as first line IS accepted by the reader, but a direct (scheme) import still needs --unsafe-prelude. If the file can be edited, prefer importing jerboa modules ((jerboa core) + project libs) over (scheme) and drop the flag.") + "jerbuild is a symlink to the jerboa multicall binary. Script mode (`jerboa file.ss`) is the canonical user-facing form, and `jerboa run file.ss` is accepted as a compatibility alias in current builds. `#!chezscheme` as first line IS accepted by the reader, but a direct (chezscheme) import still needs --unsafe-prelude. If the file can be edited, prefer importing jerboa modules ((jerboa core) + project libs) over (chezscheme) and drop the flag.") ("tags" "jerbuild" "exec" "unsafe-prelude" "scheme" "shebang" "test") ("title" @@ -8938,4 +8936,14 @@ "list") ("title" . - "jerboa_eval: write expressions with plain parens only — [x y] reads as (list x y)"))) + "jerboa_eval: write expressions with plain parens only — [x y] reads as (list x y)")) + (("code" + . + ";; Configure a local OpenAI-compatible endpoint, then ask for verified Jerboa code:\n;; JERBOA_MCP_LLM_ENDPOINT=http://localhost:11434/v1\n\n;; MCP call shape:\n;; jerboa_prompt_to_code {\n;; \"prompt\": \"define a function that adds two numbers\",\n;; \"model\": \"qwen2.5-coder\",\n;; \"max_iterations\": 3\n;; }\n\n;; Without endpoint/env, the tool returns a non-error Skipped result so\n;; mandatory verification workflows do not hang or attempt network access.") ("id" . "jerboa-prompt-to-code-local-llm") ("imports") + ("notes" + . + "The tool injects compact cookbook context, asks for one fenced Scheme block, prepends (import (jerboa prelude)) when missing, and runs jerboa_verify after each generation. Pass endpoint explicitly or set JERBOA_MCP_LLM_ENDPOINT; use_default_endpoint=true opts into http://localhost:11434/v1.") + ("tags" "mcp" "llm" "codegen" "verify" "prompt-to-code") + ("title" + . + "Generate verified Jerboa code with a local LLM endpoint"))) --- a/data/error-fixes.sexp +++ b/data/error-fixes.sexp @@ -103,13 +103,13 @@ ("type" . "Import Conflict")) (("code_example" . - "# Run with explicit libdirs:\njerboa run my-script.ss") + "# Run with explicit libdirs:\njerboa my-script.ss") ("explanation" . "A file or library path could not be resolved. Check JERBOA_HOME and libdirs.") ("fix" . - "Set JERBOA_HOME to the Jerboa repo root and run: jerboa run file.ss") + "Set JERBOA_HOME to the Jerboa repo root and run: jerboa file.ss") ("id" . "file-not-found") ("imports") ("message" . "File or module not found") ("pattern" @@ -119,7 +119,7 @@ ("type" . "File Not Found")) (("code_example" . - "(import (jerboa prelude))\n(import (std sort))\n; Run: jerboa run <file>.ss") + "(import (jerboa prelude))\n(import (std sort))\n; Run: jerboa <file>.ss") ("explanation" . "Jerboa can't find the requested library. The JERBOA_HOME/lib directory isn't in the search path.") @@ -338,11 +338,11 @@ ("type" . "FFI Type Mismatch")) (("code_example" . - "# Run through the Jerboa CLI:\njerboa run my-script.ss") + "# Run through the Jerboa CLI:\njerboa my-script.ss") ("explanation" . "Jerboa cannot find its libraries because JERBOA_HOME is wrong or the repo-local runtime has not been bootstrapped.") - ("fix" . "Run with: jerboa run your-file.ss.") + ("fix" . "Run with: jerboa your-file.ss.") ("id" . "missing-libdirs") ("imports") ("message" . "Library search path not configured") ("pattern" @@ -479,7 +479,7 @@ ("type" . "GC Double-Close fd Bug")) (("code_example" . - ";; HANG when top-level threaded setup is split across forms:\n;; (define srv (start-server! 0)) ;; forks thread\n;; (define conn (connect 127.0.0.1 srv)) ;; hangs!\n\n;; FIX: wrap setup and use in one top-level expression under jerboa run.\n(begin\n (define srv (start-server! 0))\n (sleep-ms 100) ;; thread gets to run\n (define conn (connect \"127.0.0.1\" srv)))") + ";; HANG when top-level threaded setup is split across forms:\n;; (define srv (start-server! 0)) ;; forks thread\n;; (define conn (connect 127.0.0.1 srv)) ;; hangs!\n\n;; FIX: wrap setup and use in one top-level expression under Jerboa script mode.\n(begin\n (define srv (start-server! 0))\n (sleep-ms 100) ;; thread gets to run\n (define conn (connect \"127.0.0.1\" srv)))") ("explanation" . "Jerboa run uses Chez script evaluation internally, where each top-level form is compiled and evaluated independently. A fork-thread in one form may not get CPU time before the next top-level form tries to use its result.") @@ -489,7 +489,7 @@ ("id" . "jerboa-script-thread-hang") ("imports") ("message" . - "Forked thread doesn't run between separate top-level forms under jerboa run") + "Forked thread doesn't run between separate top-level forms under Jerboa script mode") ("pattern" . "thread.*hang|fork-thread.*connect|server.*not.*accepting|accept.*never") @@ -2121,7 +2121,7 @@ ("type" . "api")) (("code_example" . - ";; Supporting sanity check:\n;; jerboa_verify {\"file_path\":\"script.ss\"}\n;;\n;; Final behavioral check for a CLI script:\n;; jerboa run script.ss ARG < input.txt\n;; or the repository's configured `make test` target.") + ";; Supporting sanity check:\n;; jerboa_verify {\"file_path\":\"script.ss\"}\n;;\n;; Final behavioral check for a CLI script:\n;; jerboa script.ss ARG < input.txt\n;; or the repository's configured `make test` target.") ("explanation" . "`jerboa_verify` can execute enough top-level script code to trigger argument validation without the task's required argv/stdin. That output is useful context, but it is not the final behavioral verifier for executable CLI scripts.") @@ -2285,13 +2285,13 @@ ("type" . "module-resolution")) (("code_example" . - "make chez\njerboa run tests/test-core.ss") + "make chez\njerboa tests/test-core.ss") ("explanation" . "MCP verifier tools use the repo-local Chez runtime internally. In a fresh checkout or client environment, that runtime may not have been bootstrapped yet.") ("fix" . - "Run `make chez` if the repo-local runtime has not been built, then use `jerboa run <file>.ss` for manual verification. MCP verifier tools may still use the repo-local Chez binary internally.") + "Run `make chez` if the repo-local runtime has not been built, then use `jerboa <file>.ss` for manual verification. MCP verifier tools may still use the repo-local Chez binary internally.") ("id" . "scheme-command-not-found-verifier") ("pattern" . "/bin/sh: scheme: command not found") ("type" . "tooling")) @@ -3407,7 +3407,7 @@ ("type" . "runtime")) (("fix" . - "The jerboa 0.2.8 script loader does not skip a leading #!/usr/bin/env ... shebang line (only #!chezscheme is accepted as a magic token). Strip the shebang first (tail -n +2 file.ss > tmp.ss) or remove the line before jerbuild exec / jerboa file.ss.") + "Current Jerboa script loading skips a leading non-Chez shebang line before reading script forms. If this error appears, rebuild/update the Jerboa launcher or verify the failure is not from invoking raw Chez directly; then run through jerboa file.ss or jerbuild exec.") ("id" . "jerboa-script-loader-shebang-invalid-syntax") ("pattern" . "invalid syntax #!/usr/bin/env at char 0") ("type" . "read")) --- a/data/features.sexp +++ b/data/features.sexp @@ -86,10 +86,15 @@ . "User: \"Write a function to sort a list and compute sum.\" Tool: Generates def/sort/sum code, verifies, returns verified snippet.") ("id" . "ai-prompt-to-jerboa-code") ("impact" . "high") + ("implemented_in" . "mcp/server.ss; mcp/test/protocol-test.ss; data/cookbooks.sexp") + ("implemented_tool" . "jerboa_prompt_to_code") ("note" . - "Requires calling an LLM API from within an MCP tool — not practical without Anthropic API integration.") - ("status" . "proposed") + "Implemented against a configured local/OpenAI-compatible endpoint rather than a hosted Anthropic-only integration; absent endpoint returns a non-error skip.") + ("status" . "implemented") + ("closed_reason" + . + "Implemented as jerboa_prompt_to_code: it reads endpoint/model from args or JERBOA_MCP_LLM_ENDPOINT/JERBOA_MCP_LLM_MODEL, injects compact cookbook context, requests a fenced Jerboa code block from a local OpenAI-compatible chat endpoint, prepends the prelude when needed, runs jerboa_verify, and retries with verifier diagnostics for up to three iterations. Protocol coverage verifies direct exposure and the no-endpoint skip path.") ("tags" "ai" "codegen" "verification" "prompt") ("title" . @@ -111,8 +116,14 @@ ("note" . "Requires LLM API + knowledge of Rust crate APIs — too domain-specific without crate introspection tooling.") - ("status" . "proposed") + ("implemented_in" "mcp/server.ss" "mcp/test/protocol-test.ss") + ("implemented_tool" . "jerboa_ai_scaffold_ml") + ("status" . "implemented") + ("closed_reason" + . + "Implemented as jerboa_ai_scaffold_ml: it generates Jerboa Scheme wrapper and Rust extern stub drafts for ML-oriented crates/ops, including library/module metadata and requested operation names. Protocol coverage verifies ndarray/tensor scaffold output.") ("tags" "ai" "ml" "ffi" "rust" "scaffold") + ("tests" "make mcp-test") ("title" . "jerboa_ai_scaffold: Generate ML/AI patterns from Rust crates") @@ -1001,7 +1012,12 @@ . "Audit /Users/example/mine/chez* and /Users/example/mine/jerboa* while excluding target, vendor, .venv, model artifacts, generated parser output, and bare git backup repos, then generate a fix plan for another agent.") ("id" . "cross-repo-security-review") ("impact" . "high") - ("status" . "proposed") + ("status" . "implemented") + ("closed_reason" + . + "Implemented through jerboa_fleet_security_scan: expands directories and trailing-* root globs, skips generated/vendor/artifact-style repo names, runs per-repo security scans with guarded error rows, aggregates deduped findings by rule/repo/severity, and emits grouped markdown plus fenced JSON.") + ("implemented_in" "mcp/server.ss" "mcp/test/protocol-test.ss") + ("implemented_tool" "jerboa_fleet_security_scan") ("tags" "security" "multi-repo" "audit" "report") ("title" . @@ -1495,18 +1511,29 @@ . "Importing (std text base64) with (chezscheme) fails with 'multiple definitions for base64-encode in body'; the fix is (except (chezscheme) base64-encode base64-decode) but you only learn the names one compile at a time.") ("id" . "predict-builtin-shadow-except") - ("impact" . "medium") ("status" . "proposed") + ("implemented_in" . "mcp/server.ss; mcp/test/protocol-test.ss") + ("implemented_tool" . "jerboa_builtin_shadow_except") + ("impact" . "medium") ("status" . "implemented") + ("closed_reason" + . + "Implemented as jerboa_builtin_shadow_except, a static MCP predictor that normalizes import clauses, detects (chezscheme) plus known Jerboa/std modules that shadow Chez builtins, and emits the exact (except ...) clause; protocol coverage includes (std text base64) => base64-encode/base64-decode.") ("tags" "import" "except" "chezscheme" "shadow" "conflict") ("title" . "Predict (chezscheme) builtin shadowing and emit the (except ...) fix") + ("description" + . + "jerboa_builtin_shadow_except accepts import clauses, reports known Chez builtin names re-exported by Jerboa/std imports, and emits the suggested (except (chezscheme) NAME ...) clause.") ("use_case" . "Writing any library that imports (chezscheme) alongside std modules that wrap Chez builtins (base64, crypto digests, sort, etc.).") ("votes" . 0)) - (("description" + (("closed_reason" + . + "Implemented as jerboa_test_baseline_diff in mcp/server.ss with protocol coverage. It runs a make target, parses PASS/FAIL lines, compares current failures against .jerboa/test-baseline.txt or an explicit baseline_path, supports update mode, and reports new regressions, fixed baseline entries, and unchanged-failing count.") + ("description" . - "A tool that runs a named test or make target (e.g. via jerboa_run_tests / jerboa_make) and compares the pass/fail set against a committed baseline of KNOWN pre-existing failures, reporting only NEW failures. The repo has pre-existing/environmental failures (test-nrepl-auth: missing (std nrepl) on libdirs; test-limits-primitives supervise-timeout: load-sensitive flake that passes standalone but fails under full 'make test' load). Distinguishing 'my change broke this' from 'this was already broken/flaky' currently requires manual `git stash` + rerun on clean master, repeatedly.") + "Implemented as jerboa_test_baseline_diff. It runs a named make target, parses PASS/FAIL lines, compares current failures against .jerboa/test-baseline.txt or an explicit baseline_path, supports update mode for clean-master regeneration, and reports only new failures as regressions while listing fixed and unchanged-known failures.") ("estimated_token_reduction" . "~2-4 stash/rerun cycles per gating step (~1-3k tokens) on any repo whose suite isn't clean-green") @@ -1514,7 +1541,9 @@ . "After each of 8 phases, `make test` exited non-zero solely due to the pre-existing nrepl + supervise failures; confirming that meant stashing changes and rerunning the suite on master several times.") ("id" . "test-target-baseline-diff") ("impact" . "medium") - ("status" . "proposed") + ("implemented_in" . "mcp/server.ss; mcp/test/protocol-test.ss") + ("implemented_tool" . "jerboa_test_baseline_diff") + ("status" . "implemented") ("tags" "testing" "baseline" "regression" "flaky" "make") ("title" . @@ -1533,7 +1562,7 @@ . "An app using jsqlite works under `jerbuild exec` but the standalone binary fails with `Exception in foreign-procedure: no entry for \"open\"`. The maintainer has to write support/main.c, support/gen-ffi-symbols.sh, and run jerbuild twice.") ("id" . "jerbuild-binary-auto-ffi-symbol-registration") - ("impact" . "medium") ("status" . "proposed") + ("impact" . "medium") ("status" . "implemented") ("tags" "jerbuild" "ffi" "binary" "foreign-procedure" "native") ("title" @@ -1655,8 +1684,15 @@ . "A manually inspected screenshot showed the sidebar section dividers and bottom edge were uneven. Build/tests passed, but only visual review exposed the missing bottom border and inconsistent separator rows.") ("id" . "tui-screenshot-layout-regression-harness") - ("impact" . "medium") ("status" . "proposed") + ("impact" . "medium") + ("implemented_in" "mcp/server.ss" "mcp/test/protocol-test.ss") + ("implemented_tool" . "jerboa_visual_regression_check") + ("status" . "implemented") + ("closed_reason" + . + "Implemented as jerboa_visual_regression_check: deterministic rendered terminal buffers can be checked for exact line width, required strings, forbidden overlap/stale-cell markers, and stable geometry snapshots. Protocol coverage verifies border-width and required/forbidden text checks on a TUI-style buffer.") ("tags" "tui" "screenshot" "layout" "regression" "termbox") + ("tests" "make mcp-test") ("title" . "TUI screenshot and layout regression harness") ("use_case" . @@ -1825,7 +1861,15 @@ . "During a local MLX run, manual greps showed prompt growth from tokens-in=2509 to 8997 before compaction fixes, then later bounded tokens-in around 2999 with a clean no-progress-break exit. A summary tool could have shown that in one call.") ("id" . "jcode-trace-health-summary") ("impact" . "high") - ("status" . "open") + ("status" . "implemented") + ("implemented_in" + "src/jcode/core/log.ss" + "src/jcode/core/debug-repl.ss" + "src/jcode/ui/cli.ss" + "test/run.ss") + ("closed_reason" + . + "jcode now parses trace files into a trace-health summary with usage-growth metric line counts, compaction/no-progress/tool-error counters, live/exited/over-budget/tool-loop/hung/leaking-child classification, close-time [HEALTH] trailers, a jcode diagnose/diag command with text/JSON/status-file output, and debug REPL status trace_health.") ("tags" "jcode" "trace" "hang-debugging" "tokens" "process-health") ("title" . "Add a jcode trace health summary tool") @@ -1843,7 +1887,16 @@ . "After multiple monitored runs, ps showed many /Users/example/.local/bin/jmcp processes with PPID 1 plus newer active jmcp/jlsp children. They were not causing the prompt hang directly, but they make live diagnosis noisy and can waste resources.") ("id" . "jcode-reap-child-processes-on-exit") - ("impact" . "medium") ("status" . "open") + ("impact" . "medium") ("status" . "implemented") + ("implemented_in" + "src/jcode/core/child-registry.ss" + "src/jcode/mcp/client.ss" + "src/jcode/tool/lsp.ss" + "src/jcode/ui/cli.ss" + "test/run.ss") + ("closed_reason" + . + "jcode now has a shared child registry for aproc handles, registers MCP and LSP children, reaps individual children on MCP/LSP stop, reaps all registered children on CLI and one-shot exit/error paths, installs SIGINT/SIGTERM handlers that reap before exiting, and verifies registry cleanup with a spawned child test.") ("tags" "jcode" "process-cleanup" "mcp" "watchdog" "resource-leak") ("title" . "Reap jcode child processes on exit and restart") @@ -1892,9 +1945,16 @@ ("example_scenario" . "While editing src/jcode/core/agent.ss and test/run.ss, jerboa_verify and jerboa_compile_check returned empty Unexpected output messages. I had to fall back to check_balance plus make build/test to confirm validity.") + ("closed_reason" + . + "The verifier subprocess path now preserves no-marker output with Command detail, command, temp script, libdirs, project_path/module_path, stdout/stderr state, and nonzero exit status; jerboa_check_syntax accepts file_path. Existing protocol coverage checks file_path syntax validation and markerless command-detail diagnostics.") ("id" . "verify-project-file-diagnostics") - ("impact" . "medium") ("status" . "proposed") + ("impact" . "medium") + ("implemented_in" "mcp/server.ss" "mcp/test/protocol-test.ss") + ("implemented_tool" . "jerboa_verify") + ("status" . "implemented") ("tags" "verify" "compile-check" "diagnostics" "file-path") + ("tests" "make mcp-test" "make mcp-test-binary" "make binary") ("title" . "Improve project-file diagnostics for verify and compile checks") @@ -1911,10 +1971,17 @@ ("example_scenario" . "Edited provider.ss (5 hunks), ran jerboa_compile_check with project_path set -> 'Unexpected output:' (empty). Had to fall back to `make test` (full build + 633 tests, minutes) just to learn the edits compiled.") + ("closed_reason" + . + "jerboa_compile_check now supports file-based jerbuild-style modules with bare (export ...) headers and Gerbil-style :pkg/path imports, and missing import failures include Jerbuild import resolution detail with derived_module, missing_library, checked_libdirs, project_path, and source_imports instead of an opaque Unexpected output.") ("id" . "compile-check-gerbil-style-imports") - ("impact" . "medium") ("status" . "proposed") + ("impact" . "medium") + ("implemented_in" "mcp/server.ss" "mcp/test/protocol-test.ss") + ("implemented_tool" . "jerboa_compile_check") + ("status" . "implemented") ("tags" "compile-check" "gerbil-imports" "module-resolution" "error-reporting" "jerboa-code") + ("tests" "make mcp-test") ("title" . "compile_check fails opaquely on modules with (export ...) headers + :pkg/path imports") @@ -1992,7 +2059,12 @@ . "Editing `vendor/jerboa-awk/lib/jerboa-awk/runtime.sls` left `runtime.tarm64osx` older than the source, but `stale_static` reported zero artifacts for both the root project and the vendor project.") ("id" . "stale-static-sls-platform-artifacts") - ("impact" . "medium") ("status" . "proposed") + ("closed_reason" + . + "Implemented with a dedicated stale-static artifact walk, .sls source matching, mtime comparison, platform grouping, extensions, and include_vendored support.") + ("implemented_in" . "mcp/server.ss") + ("implemented_tool" . "jerboa_stale_static") + ("impact" . "medium") ("status" . "implemented") ("tags" "stale" "sls" "artifacts" "chez" "vendor") ("title" . @@ -2011,7 +2083,13 @@ . "A multicall binary imports jpkg, which reaches (std os posix) at visit time and needs strerror registered. Project-wide static_symbol_audit also reports test-only FFI symbols and generated example strings, obscuring the actionable registration set.") ("id" . "entry-aware-static-symbol-audit") - ("impact" . "medium") ("status" . "proposed") + ("impact" . "medium") + ("implemented_in" . "mcp/server.ss") + ("implemented_tool" . "jerboa_static_symbol_audit") + ("note" + . + "jerboa_static_symbol_audit now accepts roots, entry_paths, entry_path/file_path, and entry_imports, resolves the boot-library closure through module-source-file, scans only entry-reachable Scheme FFI declarations for missing registrations, and keeps C registrations/archive checks project-wide with labeled output.") + ("status" . "implemented") ("tags" "static" "ffi" "audit" "multicall" "Sforeign_symbol") ("title" . "Entry-aware static symbol audit") @@ -2053,9 +2131,16 @@ ("example_scenario" . "Editing src/jcode/core/models.ss and running jerboa_verify with project_path=/Users/example/mine/jerboa-code reports library (jcode core log) not found, while make build succeeds with ./lib and vendor libdirs.") + ("closed_reason" + . + "Project-aware verifier libdirs now derive from Makefile LIBDIRS assignments, project src/lib/build/lib roots, and vendor/*/lib roots. External-lib regression coverage verifies Makefile LIBDIRS variants, build/lib, vendor/*/lib, and project_path-only jerboa_verify resolution without explicit extra_libdirs.") ("id" . "verify-jerbuild-project-libdirs") - ("impact" . "medium") ("status" . "proposed") + ("impact" . "medium") + ("implemented_in" "mcp/server.ss" "mcp/test/external-lib-test.ss") + ("implemented_tool" . "jerboa_verify") + ("status" . "implemented") ("tags" "verify" "jerbuild" "libdirs" "project_path") + ("tests" "make mcp-test") ("title" . "Make jerboa_verify honor jerbuild project libdirs") @@ -2072,9 +2157,16 @@ ("example_scenario" . "Editing src/jcode/tool/external-llm.ss, jerboa_verify file_path+project_path failed to find (jcode core log), so the session had to rely on check_balance plus make build for compile verification.") + ("closed_reason" + . + "jerboa_verify file mode now uses project-derived libdirs from Makefile LIBDIRS, src, lib, build/lib, and vendor/*/lib. Missing-import diagnostics report checked libdirs and import context, and external-lib regression coverage verifies project_path-only resolution for local project libraries.") ("id" . "verify-file-project-libdirs-resolution") - ("impact" . "medium") ("status" . "proposed") + ("impact" . "medium") + ("implemented_in" "mcp/server.ss" "mcp/test/external-lib-test.ss") + ("implemented_tool" . "jerboa_verify") + ("status" . "implemented") ("tags" "verify" "project_path" "libdirs" "compile_check") + ("tests" "make mcp-test") ("title" . "Make jerboa_verify file mode honor project libdirs reliably") @@ -2082,9 +2174,12 @@ . "Focused verification after editing a project .ss file should work without falling back to make build when local project modules are imported.") ("votes" . 0)) - (("description" + (("closed_reason" . - "jcode --repl-port N binds 127.0.0.1 and starts the debug REPL with tls=off and no token gate. The repo repl-reader.ss always uses openssl s_client and sends a token, which fails with EOF in this common local debugging mode. It should auto-detect loopback/port-only usage or expose a --plain mode using nc/open TCP ports without token.") + "Implemented in repl-reader.ss with direct Jerboa TCP API loopback connections, no nc/timeout shell dependency, clearer missing credential diagnostics, and explicit TLS-absent SSH-tunnel guidance.") + ("description" + . + "repl-reader.ss now opens plain loopback TCP connections through Jerboa's TCP API instead of shelling out to nc/timeout, refuses non-loopback targets, reports the exact missing credential file path with startup guidance, and documents that TLS is intentionally absent for local/SSH-tunneled diagnostics.") ("estimated_token_reduction" . "~300 tokens per debugging session by avoiding rediscovery of TLS/token mode differences.") @@ -2092,7 +2187,8 @@ . "A developer launches ./jcode --repl-port 5555 and tries ./repl-reader.ss 127.0.0.1:5555 '(+ 1 2)'; the helper uses TLS/token and gets EOF, while printf '(+ 1 2)\\n' | nc 127.0.0.1 5555 succeeds.") ("id" . "jcode-repl-reader-plain-loopback-mode") - ("impact" . "medium") ("status" . "proposed") + ("impact" . "medium") ("implemented_in" . "repl-reader.ss") + ("status" . "implemented") ("tags" "jcode" "debug-repl" "repl-reader" "loopback" "tooling") ("title" @@ -2127,6 +2223,9 @@ (("description" . "Expose jerboa_explain_error and jerboa_error_fix_lookup as direct jcode-visible MCP tools, or add a compact direct alias, so local models can classify compiler/runtime errors without discovering the generic dispatcher. The tool result should include a concise diagnosis, corrected form, and one suggested verification command.") + ("closed_reason" + . + "Closed by making jerboa_explain_error a critical direct tool, adding jerboa_repair_error as a compact diagnosis/fix/advisor/verification helper, and syncing the critical-tools metadata.") ("estimated_token_reduction" . "~1k-4k tokens per failed verify cycle.") @@ -2134,7 +2233,10 @@ . "A verified workflow saw only 'exit 1' or a terse Jerboa condition and the model repeatedly edited the same broken file, then tried unavailable run tools. A direct error-repair MCP tool would make the repair path obvious.") ("id" . "jmcp-direct-error-repair-tools-for-jcode") - ("impact" . "medium") ("status" . "proposed") + ("impact" . "medium") + ("implemented_in" . "mcp/server.ss") + ("implemented_tool" . "jerboa_repair_error") + ("status" . "implemented") ("tags" "jmcp" "errors" "repair" "jcode" "local-llm") ("title" . @@ -2176,8 +2278,14 @@ ("example_scenario" . "While fixing build scripts, changed_only=true without base_ref produced an error, and passing the full unified diff as a payload later crashed/aborted. Retrying with base_ref=HEAD worked. The scanner could make that retry unnecessary.") - ("id" . "security-scan-auto-git-diff") ("impact" . "medium") - ("status" . "proposed") + ("id" . "security-scan-auto-git-diff") + ("closed_reason" + . + "Implemented by deriving changed-line specs from git diff --unified=0 HEAD when changed_only is true and no explicit changed-line source is supplied; clean git diffs now return a pass instead of an error.") + ("implemented_in" . "mcp/server.ss mcp/test/protocol-test.ss") + ("implemented_tool" . "jerboa_security_scan") + ("impact" . "medium") + ("status" . "implemented") ("tags" "security-scan" "changed-only" "git" "diff" "workflow") ("title" @@ -2187,9 +2295,12 @@ . "After editing Jerboa/C/Rust code, agents often want a changed-line security scan before final verification. The natural call is changed_only=true with project_path, but it currently errors unless the caller supplies diff/base_ref/changed_lines.") ("votes" . 0)) - (("description" + (("closed_reason" + . + "Implemented in jcode diagnose/diag with trace health, registered child process pid/kind/label/alive/rss/cmdline/open-file evidence, recent MCP call age/duration/status, JSON/text/status-file output, and debug REPL `(diag)` support.") + ("description" . - "Add a Jerboa/tooling helper that gathers the common evidence for a hung child process in one call: process tree, command line, open files, recent stderr/stdout log tail, known lock-holder files, launchctl service status on macOS, and elapsed time since spawn. The output should be compact and redact obvious secrets in command lines.") + "jcode diagnose/diag now gathers compact subprocess hang evidence in one report: trace health, registered child processes with redacted command lines, RSS and bounded lsof output, recent MCP call age/duration/status, JSON/text/status-file output, and `(diag)` support in the loopback debug REPL.") ("estimated_token_reduction" . "~1000-2000 tokens per debugging session; eliminates 4-6 separate shell/tool calls.") @@ -2197,7 +2308,13 @@ . "A TUI spawned signal-cli jsonRpc and waited for its version response. The real cause was a separate launchctl-started signal-cli daemon holding the account database lock, visible only after checking ps, lsof, logs, and LaunchAgents separately.") ("id" . "subprocess-hang-diagnostic-bundle") - ("impact" . "medium") ("status" . "proposed") + ("impact" . "medium") + ("implemented_in" + "src/jcode/ui/cli.ss" + "src/jcode/ui/tui-memstats.ss" + "src/jcode/core/debug-repl.ss" + "test/run.ss") + ("status" . "implemented") ("tags" "subprocess" "diagnostics" "process" "lock" "launchctl") ("title" . "Bundle subprocess hang diagnostics") @@ -2205,9 +2322,12 @@ . "When a Jerboa app starts a long-lived subprocess and appears to hang before its own UI or prompt is ready.") ("votes" . 0)) - (("description" + (("closed_reason" . - "Observed the local model ignore an exact command and search for Scheme/Gerbil interpreters after a failed bare `scheme` attempt. jcode could add a lightweight policy hint around tool results containing `Run exactly:` or `Use this command shape:` to prefer those commands over exploratory PATH searches.") + "Implemented in jcode workflow runner with centralized command-hint text appended to verified repair/error tool results plus an ablation-controlled command-hints switch.") + ("description" + . + "jcode verified workflows now append `NEXT: exactly one ...` command hints to repair-pending tool results, centralize the wording in workflow-runner command-hint helpers, and expose command-hints-enabled through eval ablation presets.") ("estimated_token_reduction" . "~1000-3000 tokens on command-verification tasks") @@ -2215,7 +2335,13 @@ . "The model spent many calls searching /opt and Gerbil paths before using /Users/example/mine/jerboa/.chez/bin/scheme; stronger command-result affordances could avoid that.") ("id" . "jcode-absolute-command-following-hints") - ("impact" . "medium") ("status" . "proposed") + ("impact" . "medium") + ("implemented_in" + "src/jcode/core/workflow-runner.ss" + "src/jcode/eval/ablation.ss" + "src/jcode/eval/runner.ss" + "test/run.ss") + ("status" . "implemented") ("tags" "jcode" "tool-results" "local-model" "commands") ("title" . @@ -2259,7 +2385,12 @@ . "With a bad parenthesis placement in src/jcode/ui/tui-sidebar.ss, jerboa_make target=test showed compile output but omitted the later unbound identifier error; direct make test failed with exit code 2.") ("id" . "make-target-completion-status-tail") - ("impact" . "medium") ("status" . "proposed") + ("impact" . "medium") ("status" . "implemented") + ("closed_reason" + . + "jerboa_make now requests an opt-in process status tail, reports completion status, exit status, and final command output lines, and marks timeout/nonzero make completion as isError.") + ("implemented_in" "mcp/server.ss" "mcp/test/protocol-test.ss") + ("implemented_tool" "jerboa_make") ("tags" "make" "tests" "timeout" "output" "status") ("title" . @@ -2382,6 +2513,9 @@ (("description" . "When howto_verify fails with \"Unexpected syntax-check output\", include the captured stdout/stderr or the exact syntax checker result. Without that, the caller has to fetch the recipe, manually reconstruct the snippet, and run a separate syntax check to diagnose whether the failure is from imports, reader syntax, project context, or verifier parsing.") + ("closed_reason" + . + "Closed by preserving bounded multi-line syntax-check output in jerboa_howto_verify failures, adding a verbose option for longer diagnostics, and keeping FAIL prefixes for failure filtering.") ("estimated_token_reduction" . "~800-1500 tokens per failed recipe verification") @@ -2389,7 +2523,10 @@ . "A recipe importing a project-local module failed verification with only \"Unexpected syntax-check output\". The fix required fetching the recipe and running jerboa_check_syntax manually to infer that the recipe needed to be self-contained.") ("id" . "howto-verify-show-syntax-output") - ("impact" . "medium") ("status" . "proposed") + ("impact" . "medium") + ("implemented_in" . "mcp/server.ss") + ("implemented_tool" . "jerboa_howto_verify") + ("status" . "implemented") ("tags" "howto" "verify" "diagnostics" "syntax-check") ("title" . @@ -2432,7 +2569,12 @@ . "A generated main.ss has `Unexpected close ) at line 57`. The model calls balance and reads the same line range many times. A balance hint saying `Use line_edit(path,line=57,content=...) or replace_range for the enclosing function` would likely save the loop.") ("id" . "balance-repair-action-hints") ("impact" . "medium") - ("status" . "proposed") + ("status" . "implemented") + ("closed_reason" + . + "jerboa_check_balance now emits per-error action hints for unexpected closers and unclosed delimiters, and jerboa_repair_balance dry-runs include an enclosing top-level jerboa_balanced_replace recommendation.") + ("implemented_in" "mcp/server.ss" "mcp/test/protocol-test.ss") + ("implemented_tool" "jerboa_check_balance" "jerboa_repair_balance") ("tags" "balance" "local-model" "repair" "line-edit" "replace-range") ("title" . "Add actionable repair hints to balance reports") @@ -2450,7 +2592,7 @@ . "A local model repeatedly tries unknown write tools, then uses brittle old_str replacement after it fails. The exporter turns the real transcript into a rejected example and the eventual verified line_edit/replace_range flow into the chosen example.") ("id" . "jcode-repair-trace-sft-dpo-exporter") - ("impact" . "high") ("status" . "proposed") + ("impact" . "high") ("status" . "implemented") ("tags" "jcode" "training-data" "sft" "dpo" "repair-traces") ("title" . @@ -2469,7 +2611,12 @@ . "A security review across ~/mine/jerboa* required dozens of repeated git status, diff, build, test, and push checks. A single multi-repo audit could have summarized clean/dirty/ahead/blocked state and reduced manual orchestration.") ("id" . "multi-repo-jerboa-audit") ("impact" . "high") - ("status" . "open") + ("status" . "implemented") + ("closed_reason" + . + "Implemented through jerboa_fleet_security_scan include_status:true, which interleaves per-repo git branch/dirty/untracked/stale status with the multi-repo security/make-target matrix and keeps dirty-tree state per repository.") + ("implemented_in" "mcp/server.ss" "mcp/test/protocol-test.ss") + ("implemented_tool" "jerboa_fleet_security_scan") ("tags" "multi-repo" "audit" "status" "build-test" "security") ("title" . "Audit multiple Jerboa repos in one run") @@ -2513,7 +2660,12 @@ . "A jerboa-shell migration needs to verify that no non-vendor .sls files remain tracked, no .ss files sit under src/lib/vault-stage libdirs, and no user-facing .ss still contains a top-level (library ...) form.") ("id" . "generated-sls-source-layout-audit") - ("impact" . "medium") ("status" . "proposed") + ("implemented_in" . "mcp/server.ss; mcp/test/protocol-test.ss") + ("implemented_tool" . "jerboa_generated_sls_source_layout_audit") + ("impact" . "medium") ("status" . "implemented") + ("closed_reason" + . + "Implemented as jerboa_generated_sls_source_layout_audit, a read-only MCP tool that uses git ls-files to report tracked non-vendor .sls files, tracked .ss files under configured libdir/output roots, and top-level library forms in tracked .ss source.") ("tags" "audit" "jerbuild" "generated-sls" "git" "source-layout") ("title" @@ -2532,10 +2684,17 @@ ("example_scenario"