Skip to content

fix(wasi): component get-directories returns a guest-usable preopen list (SR-37, #405) - #406

Merged
avrabe merged 1 commit into
mainfrom
fix/sr-37-get-directories-preopen
Jul 9, 2026
Merged

fix(wasi): component get-directories returns a guest-usable preopen list (SR-37, #405)#406
avrabe merged 1 commit into
mainfrom
fix/sr-37-get-directories-preopen

Conversation

@avrabe

@avrabe avrabe commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

What

Fixes the get-directories layer of #405: a WASI Preview2 component run via kilnd --wasi --component --wasi-fs <dir> could not use any preopen — wasi:filesystem/preopens::get-directories returned a list backed by memory the guest never allocated, so preview2 libc registered no usable preopen and every file op returned ENOENT without ever calling open-at.

Root cause (measured, not guessed)

For the maintainer's single wasm32-wasip2 component:

  • nested_component_instances.len() == 0 → the InterComponentHandler override does not fire (ruling out the dispatcher-swap hypothesis).
  • the queried dispatcher already held the preopen (preopens.len() == 1).

So the defect was the canonical-ABI return encoding: get-directories wrote its list<tuple<descriptor,string>> entries at retptr+8 and path strings at retptr+20, but the return area for func() -> list<…> is only 8 bytes. The list must be backed by cabi_realloc'd guest memory — exactly how the working get-arguments path does it.

Fix (mirrors the proven get-arguments machinery, 5 sites)

  • kiln-foundation HostImportHandler: get_preopens + set_preopens_allocation.
  • kiln-runtime: pre_allocate_wasi_preopens + allocate_wasi_preopens_memory (N×12 entry buffer + per-path string buffers via cabi_realloc) + CapabilityAware wrapper.
  • kiln-wasi WasiDispatcher: preopens_alloc; get-directories writes into the allocation and fails loud if it was not set (no more unowned scribble).
  • kiln-component ComponentInstance::pre_allocate_wasi_preopens.
  • kilnd: call it before the entry point, beside pre_allocate_wasi_args.

Verification

  • 2 new unit oracles (// rivet: verifies SR-37): the encoding uses the allocation (header points at list_ptr, not retptr+8) and fails loud without it.
  • Integration trace confirms the guest now registers the . preopen and successfully open-at + stat's a file under it (before: rejected immediately).

Scope / honesty

This lands the prerequisite. Full end-to-end file read for #405 is still blocked on SR-38 (input-stream.blocking-read writes list<u8> to a fixed unowned address — a distinct, harder defect needing on-demand cabi_realloc). #405 stays open; v0.4.1 will cut once SR-38 also lands.

Trace: SR-37

🤖 Generated with Claude Code

…-37, #405)

A WASI Preview2 component run via `kilnd --wasi --component --wasi-fs <dir>`
could not use any preopen: `wasi:filesystem/preopens::get-directories` wrote its
`list<tuple<descriptor,string>>` result into memory adjacent to the 8-byte
canonical-ABI return area (retptr+8 / retptr+20) — memory the guest never
allocated. preview2 libc then registered no usable preopen and every file op
returned ENOENT, without ever calling open-at.

Measured (single wasm32-wasip2 component): nested_component_instances=0 (the
InterComponentHandler override does not fire) and the queried dispatcher already
held the preopen (preopens.len()=1) — so the defect was the return encoding, not
the wiring. The working get-arguments path proves the fix: back the list return
with cabi_realloc'd guest memory.

This mirrors the args machinery across five sites:
- kiln-foundation: HostImportHandler gains get_preopens + set_preopens_allocation.
- kiln-runtime: pre_allocate_wasi_preopens + allocate_wasi_preopens_memory
  (N*12 entry buffer + per-path string buffers via cabi_realloc); CapabilityAware
  wrapper.
- kiln-wasi: WasiDispatcher.preopens_alloc; get-directories writes entries into
  the allocation and FAILS LOUD if it was not set (no more unowned scribble).
- kiln-component: ComponentInstance::pre_allocate_wasi_preopens.
- kilnd: call it before the entry point, next to pre_allocate_wasi_args.

With this, the guest registers the "." preopen and successfully open-at/stat's a
file under it (verified by trace). Two unit oracles assert the encoding uses the
allocation (not retptr+8) and fails loud without it.

Note: full end-to-end file READ for #405 remains blocked on SR-38 (input-stream
blocking-read writes list<u8> to a fixed unowned address — a distinct, harder
defect needing on-demand cabi_realloc). #405 stays open; this lands its
prerequisite.

Trace: SR-37
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown

🔍 Build Diagnostics Report

Summary

Metric Base Branch This PR Change
Errors 0 0 0
Warnings 5 5 0

🎯 Impact Analysis

Issues in Files You Modified

  • 0 new errors introduced by your changes
  • 0 new warnings introduced by your changes
  • 0 total errors in modified files
  • 0 total warnings in modified files
  • 0 files you modified

Cascading Issues (Your Changes Breaking Other Files)

  • 0 new errors in unchanged files
  • 0 new warnings in unchanged files
  • 0 unchanged files now affected

Note: "Cascading issues" are errors in files you didn't modify, caused by your changes (e.g., breaking API changes, dependency issues).

✅ No Issues Detected

Perfect! Your changes don't introduce any new errors or warnings, and don't break any existing code.


📊 Full diagnostic data available in workflow artifacts

🔧 To reproduce locally:

# Install cargo-kiln
cargo install --path cargo-kiln

# Analyze your changes
cargo-kiln build --output json --filter-severity error
cargo-kiln check --output json --filter-severity warning

@codecov

codecov Bot commented Jul 9, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@avrabe
avrabe merged commit 30373fe into main Jul 9, 2026
21 checks passed
@avrabe
avrabe deleted the fix/sr-37-get-directories-preopen branch July 9, 2026 07:50
avrabe added a commit that referenced this pull request Jul 10, 2026
…) (#410)

Version bump 0.4.0 → 0.4.1. Ships the complete component filesystem read/list
fix for WASI Preview2 components under kilnd --wasi --component --wasi-fs:
- SR-37 (#406): get-directories returns a guest-usable preopen list.
- SR-38 (#407): file read (blocking-read) returns bytes in a guest-owned buffer
  with offset/EOF tracking.
- SR-39 (#409): directory enumeration (read-directory / read-directory-entry).

Together these make a preview2 component read and list files under a preopen,
matching `wasmtime run --dir`. Closes #405.

Trace: SR-39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant