Skip to content

fix(runtime): preserve peer worker temporary directories - #503

Open
Glaz-j wants to merge 1 commit into
Ephemeral-AI-Lab:mainfrom
Glaz-j:fix/worker-temp-ownership
Open

Glaz-j wants to merge 1 commit into
Ephemeral-AI-Lab:mainfrom
Glaz-j:fix/worker-temp-ownership

Conversation

@Glaz-j

@Glaz-j Glaz-j commented Oct 29, 2026

Copy link
Copy Markdown

Starting a worker for a second LayerFS home deletes the first worker's live temporary directory when they share a temporary parent. The first worker stays alive, but its next fs.write fails to bind its private overlay with ENOENT; workspace.exec output beyond the inline limit also fails when it needs its output spool.

Remove the prefix-wide startup cleanup. Each start already creates a random private directory, and graceful stdin shutdown already removes only that instance's directory. Directories left by abnormal exits remain available for explicit cleanup rather than being deleted by another worker.

Add api/runtime/test/verify/worker_temp_real.mjs, using the real addon, Disposable Store, Docker and daemon. It starts two homes under an isolated shared TMPDIR and checks:

  • SDK writes and exact 2,097,153-byte stdout through the first worker after the second starts.
  • Both workers' private directories and unrelated retained evidence survive peer startup.
  • Stopping the second worker leaves the first operational; graceful stdin shutdown removes its own directory.
  • Readiness/shutdown waits are bounded, and failed fixtures are retained.

Validation on Linux/WSL2 with Node 22.19.0 and Rust 1.85.1:

  • The new container regression fails on unchanged main with the original overlay-bind ENOENT and passes after this fix.
  • Both worker_temp_real.mjs container and worker_temp_real.mjs stdin pass under tools/worktree.py run --timeout 90 with fresh isolated Stores.
  • Existing worker_real.mjs inner, plus runtime transport-order, macos-worker, worker-frames and worker-docker, pass.
  • Product boundary guard and all 155 Python tool self-tests pass.
  • cargo test --locked --offline -p layerfs-node -p layerfs-daemon --all-targets --no-run, warning-denying Clippy for the same targets, cargo fmt --all -- --check, and git diff --check pass.

Both startup protocols were exercised on Linux; native macOS and Windows launcher integration was not tested. No SDK documentation changes are included.

Starting a worker for another LayerFS home currently sweeps every
layerfs-worker-* directory in the shared temporary parent. This removes a
live peer's private overlay and output-spool paths, breaking subsequent
Store writes and large workspace.exec results with ENOENT.

Remove that startup sweep. Keep the existing random per-start directory
and instance-owned graceful-shutdown cleanup. Add real-addon regression
coverage for container and stdin startup, independent writes, spooled
output, peer shutdown and retained failure evidence.

Production LOC: 102831 -> 102830 (delta -1)
Scope: combined first-party core, engine and api product source; tests,
docs, tools, generated and third-party sources excluded.
Method: tools/production_loc.py --root <git-archive-tree> --json on exact
parent 35d3657 and staged tree
038697c, using counter blob
3341e4d on both trees.
Reference absent (retired R9c; last counted 65,417 at tree 498dd19).
@Mola-maker

Mola-maker commented Nov 1, 2026 •

Copy link
Copy Markdown
Member

感谢贡献,也感谢 AI 协作工具在多 home 场景下发现这个误删缺陷 🙏

真实评估(已读 diff):原 server.js 启动时 readdirSync(tmpdir()) 后对所有 layerfs-worker-* 目录做递归删除——在 plugin-neutral(2026-10-24)决策下,第二个 LayerFS home 的 worker 启动会删掉第一个 home 的存活 worker 的 overlay/spool 目录。修复完全移除了清扫逻辑,改为只用进程自己 randomBytes(12) 命名的私有目录、退出时只删自己的。新增 worker_temp_real.mjs 用真实 addon + Docker + daemon 验证双 home 共存(container/stdin 两种启动模式都测),并断言"每次启动只建一个私有目录、优雅退出只删自己的"。这是正确的方向:清扫别人命名空间的目录本质上是跨所有者的破坏性操作。没有发现缺陷。

对 AI agent 的使用价值:这是多个 agent 工具(各自独立 LayerFS home)在同一台机器共存的基础保障。

建议:合入前在真实双 home 环境实测一次(先起 A、再起/停 B、确认 A 的 worker 存活且后续调用正常)。功能性调整等 LayerFS 2.0(#446)发布后再做。

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.

2 participants