Title
Package / version
Summary
// agent.ts, around line 470 (0.1.3-alpha.1 source)
import { mkdir } from 'node:fs/promises'
...
try {
await mkdir(cwd, { recursive: true })
} catch (error: unknown) {
throw new Error(`failed to ensure project directory "${cwd}": ${String(error)}`, { cause: error })
}The same statement ships verbatim in every published version (verified by Why this is a defect
Observed impact (out-of-tree deployment)With a remote fs provider mounted (user namespaces are backend-held, virtual Expected behavior
await ctx.fs.mkdir(cwd, { recursive: true }) // or the seam's exact signatureso that:
If a deliberate "host-dir bootstrap" contract is intended (e.g. the launcher Reproduction
Regression test sketchit('creates the project directory through the fs seam, not the host fs', async () => {
const fs = new RecordingFsProvider() // fails loud on unknown calls
ctx.provide(fsServiceKey, fs)
const agent = await controller.create({ cwd: 'ws-a', ... })
expect(fs.calls).toEqual([['mkdir', 'ws-a', { recursive: true }]])
expect(hostTreeDiff(before, after)).toBeEmpty()
})Compatibility notes
Prior art in the tree
|
Replies: 4 comments 3 replies
|
我对你的判读做了源级复核(基于本仓库 master 5dda764 / dsh 0.1.5-alpha.1),结论:你的"seam 绕过"判定成立,但"修复方式 = ctx.fs.mkdir"在 current API 上不成立 —— fs seam( 你正确的地方
需要修正的地方:
|
|
这个问题,官方这边会考虑安排解决吗? |
|
关于这类似的所有接缝点远程化问题,现在每个地方都行需要单独插件区对接,工作量比较大,官方有没有计划收拢一些统一的插件,简化我们拿来做远程化对接繁琐的问题。 |
|
@xmRobinYu 你已落地 Option B(且用真实 remote backend 跑了三场景回归)——这非常扎实,比"提方案"进了一大步。你留给我/upstream 的那个裁决点(严格 B:controller 永不 mkdir vs B + 本地映射保留),我倾向严格 B,理由如下。 为什么选严格 B(controller 永不创建目录)
保留"本地映射 mkdir"分支,虽然让本地零回归(你 host spec 476 绿),但它留住了那个越权语义,只是把它限定在本地 backend。也就是说:
这种后端相关性行为差异,恰恰是 seam 契约最忌讳的:同一个 严格 B 的具体落法严格 B 不是删掉 mkdir 就行,而是要把"cwd 必须已存在"这一不变量前移到调用方,controller 只验证不创造: // 无论本地/远程,controller 都不 mkdir,只校验存在性
const fs = this.ctx.get('fs')
if (fs !== undefined) {
let present = false
try {
present = (await fs.lstat(cwd))?.type === 'directory'
} catch (error: unknown) {
throw new Error(`failed to ensure project directory "${cwd}": ${String(error)}`, { cause: error })
}
if (!present) {
throw new Error(
`failed to ensure project directory "${cwd}": ...`,
{ cause: ... },
)
}
}
// fs === undefined 时(无 fs service,纯本地组装),才保底 fallback 到你现有的 mkdir 行为关键点: 一个你可能没注意的边界你现在的补丁里有一个失败分类的缝隙:
对 core 提案的补强你说 remote provider 到 backend 已有 我这边会把"严格 B"作为我推荐的上游取向,并把它归档为一个 upstream-fix 候选( |
我对你的判读做了源级复核(基于本仓库 master 5dda764 / dsh 0.1.5-alpha.1),结论:你的"seam 绕过"判定成立,但"修复方式 = ctx.fs.mkdir"在 current API 上不成立 —— fs seam(
FileSystemService)当前没有 mkdir/ensureDir 原语。这是个值得先厘清的前提分叉,否则修复方向会落空。你正确的地方
packages/api/session-controller/src/agent.ts:3确实是import { mkdir } from 'node:fs/promises',:474直接await mkdir(cwd, { recursive: true })。同包media-references.ts:74已走serveFile(request, ctx.fs, maxBytes),证明 controller 自己的 media 路径从不直接摸node:fs—— agent-creation 是孤点。这条 seam 绕过在本地 fs 部署下无害,但一旦挂远程/虚拟 fs provider,就会在引擎主机长出镜像目录树(破坏"engine host 不产生用户目录"不变量),或在虚拟 cwd 无法解析为主机绝对路径时直接failed to ensure project directory—— 判断准确。需要修正的地方:
ctx.fs没有 mkdir 原语你的修复建议写的是: