Skip to content

fix: resolve file names against *home-directory*; per-user kernel cache (#86, #87) - #89

Merged
pyrex41 merged 3 commits into
mainfrom
capcov/fix-86-87-home-dir-cache
Oct 19, 2026
Merged

pyrex41 merged 3 commits into
mainfrom
capcov/fix-86-87-home-dir-cache

Conversation

@pyrex41

@pyrex41 pyrex41 commented Oct 18, 2026 •

Copy link
Copy Markdown
Owner

Two low-risk fixes from the capcov cross-port run, one commit each.

Fixes #86
Fixes #87

#86: relative file names resolve against *home-directory* (82afe27)

(cd Dir) sets *home-directory* (sys.kl:164), but open and the native fast paths for read-file, read-file-as-string, read-file-as-bytelist and the fasl load wrapper passed relative names straight to io.open, so they still read from the process cwd.

  • New P.home_path(name) in prims.lua prepends *home-directory* to every name, as a plain string join. open and all four fast paths use it. The fast paths therefore can no longer open a same-named file in the cwd that open would not.
  • The fasl load wrapper (boot.lua) reads and records the resolved path.
  • Absolute names (decided, c349fff): *home-directory* is prepended unconditionally, matching shen-scheme d037ae6 and shen-go 1f587de. After (cd "/a"), (read-file "/b/x.shen") opens /a//b/x.shen and fails, as on both of them.

#87: kernel cache moves to the per-user cache dir (7ad7ae4)

When SHEN_KERNEL_CACHE was unset, cache_path() returned the relative .shen-kernel-cache.<build>.bin. Every directory shen ran from got about 1.8 MB of cache plus the .stlib sidecar, and recompiled the kernel.

  • The default is now ${XDG_CACHE_HOME:-$HOME/.cache}/shen-lua/kernel-<build>.bin, with the sidecar next to it. The directory is created on first write (open_for_write).
  • If the location is unwritable, caching is skipped, as before. If neither XDG_CACHE_HOME nor HOME is set, there is no cache.
  • SHEN_KERNEL_CACHE=<path>|off is unchanged. The fasl default (~/.cache/shen-lua-fasl, SHEN_FASL_DIR) is untouched.
  • The old cleanup of ./.shen-kernel-cache.bin only ran for the relative default, so it was removed along with it. Stale .shen-kernel-cache.* files in project dirs are gitignored and can be deleted.

Tests

Base is e3dec8b (main) and head is 7ad7ae4. Commands:

make test      # scripts/run-tests.lua
make certify   # run-kernel-tests.lua

Both were run with GIT_DIR/GIT_WORK_TREE/GIT_INDEX_FILE unset, a private TMPDIR and a private XDG_CACHE_HOME.

make test make certify (43.1 suite)
base e3dec8b TOTAL: 1210 pass, 0 fail across 23 specs passed ... 154 / failed ... 0
head 7ad7ae4 TOTAL: 1225 pass, 0 fail across 23 specs passed ... 154 / failed ... 0

New checks (15):

  • test/io_spec.lua (+7). cd, then each of read-file, read-file-as-string, read-file-as-bytelist, open and load, with a decoy file of the same name in the cwd. Also an absolute name after cd (joined, so it fails as on shen-scheme), and (cd "") restoring cwd resolution. On base the spec dies at the first open (open: cannot open ...).
  • test/boot_cache_spec.lua (+8). Boot in an empty cwd with SHEN_KERNEL_CACHE unset: nothing lands in the cwd, the cache and sidecar land in $XDG_CACHE_HOME/shen-lua, else $HOME/.cache/shen-lua, a warm boot works, and an unwritable dir still boots. On base, 4 of these fail (got .shen-kernel-cache.bdd98551.bin .shen-kernel-cache.bdd98551.bin.stlib).

Repros from the issues, at head:

cd/repro.shen :: home=".../cd/sub/"|read-file: [[+ 1 2]]|open: ok|loaded data|load: ok|
cache-cwd: cwd listing: hello.shen home   (base: .shen-kernel-cache.bdd98551.bin .shen-kernel-cache.bdd98551.bin.stlib hello.shen home)
           D/home/.cache/shen-lua/kernel-bdd98551.bin(.stlib)

Cross-port check (capcov workloads)

Payloads were extracted with capcov's bench.py payload filter and compared byte for byte with shen-go 1f587de (kernel 42.2).

🤖 Generated with Claude Code

pyrex41 and others added 2 commits October 18, 2026 17:00
open, read-file, read-file-as-string, read-file-as-bytelist and the fasl
load wrapper passed relative names straight to io.open, so after (cd Dir)
they still read from the process cwd. They now prepend *home-directory*
(set by cd) to non-absolute names, as the kernel's open contract and
shen-go/shen-scheme do. The native fast paths share one resolver
(P.home_path) with open, so they can no longer pick up a same-named file
in the cwd that open would not.

Fixes #86

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With SHEN_KERNEL_CACHE unset, cache_path() returned the relative
".shen-kernel-cache.<build>.bin", so every directory shen ran from got a
~1.8 MB cache plus its .stlib sidecar and recompiled the kernel. The
default is now ${XDG_CACHE_HOME:-$HOME/.cache}/shen-lua/kernel-<build>.bin;
the directory is created on the first write, and an unwritable location
skips caching as before. SHEN_KERNEL_CACHE=<path>|off is unchanged.

The cleanup of the pre-per-build ".shen-kernel-cache.bin" in the cwd only
ran for the old relative default, so it is removed with it.

Fixes #87

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…me does (#86)

shen-scheme and shen-go join *home-directory* and the file name as plain
strings, so after a non-empty cd an absolute name is joined as well. Match
that instead of passing absolute names through.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@pyrex41
pyrex41 merged commit 2bbaa25 into main Oct 19, 2026
2 checks passed
pyrex41 added a commit that referenced this pull request Oct 19, 2026
fix(fasl): replay a nested (load) once on a warm hit (#92; stacked on #89)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant