Repository navigation
[BUG] DSH 0.2.1:hide-official 的组装校验仍假设载荷带 tools,启用该行后每个作用域都被 READINESS_BLOCKED 拦下 #413
Copy link
Copy link
Closed
Description
环境
- DSH
0.2.1-rc.3(macOS arm64) - dsh-ops
0.4.1(发布版)/main@dfafddc(含 [BUG] dsh-ops 0.4.1 在 DSH 0.2.1-rc.3 下每轮 prompt 装配崩溃:isPtc 读取 undefined.tools.length #387 的211dc3e,两处都复现) - profile 启用
dsh-ops-hide-official,replaceTools: ['read', 'glob', 'grep']
现象
dsh-ops-ptc 那条崩溃(#387 / #412)修好之后,只要同时启用 hide-official,每一次带 scope 的 prompt 组装都会被拦下:
READINESS_BLOCKED (EXECUTOR_UNAVAILABLE): dsh-ops hide-official cannot verify selected replacements:
assembled tool schemas unavailable. Restore the selected OPS tools, remove the selection from
replaceTools, or disable the dsh-ops-hide-official row.
不是某个工具不可用,是所有回合都起不来。
根因
src/official-tool-hiding.ts 的组装校验仍然假设瀑布返回值里有工具数组:
ctx.on('system-prompt/assemble', async (assembly, context, next) => {
...
const wire = Array.isArray(result?.tools) ? result.tools.map(schema => schema.name) : []
const collapsed = wire.length > 0 && wire.every(name => name === RUN_CODE)
...
if (!Array.isArray(result?.tools)) throw block(context.scope, 'assembled tool schemas unavailable')
const leaked = result.tools.map(schema => schema.name).filter(hideable)DSH 0.2.1 的 9d0c97b9d2 feat(tools): admit conditional tools per step 改成瀑布只变换 PromptPresentation,tools 由 SystemPrompt.assemble() 在瀑布之后才追加,#387 已经在 PTC 侧按这个事实改了(hasPtcInstruction / text-only hooks),同一条契约在 hide-official 里没有跟进。
结果:result.tools 恒为 undefined → 恒抛 assembled tool schemas unavailable。顺带一提,wire 也是空数组,所以 collapsed 恒为 false,PTC 折叠作用域的宽容分支同样失效。
复现(真实载荷形状)
在测试宿主上注册一个瀑布监听,模拟 0.2.1 的形状(进入前删掉 tools,返回前补回,与宿主 return { ...transformed, tools } 等价):
ctx.on('system-prompt/assemble', async (assembly, _context, next) => {
const tools = assembly.tools
delete assembly.tools
return { ...await next(), tools }
})
await mount(ctx) // 启用了 read/glob/grep 的替换
const agent = await mint(ctx, 'presentation-payload')
await assemble(ctx, agent) // 这里抛 READINESS_BLOCKED ... assembled tool schemas unavailablemain@dfafddc:失败,消息同上- 0.2.0-rc.2(不删
tools)的同一场景:通过
期望行为
- 载荷里有工具数组时:保留现在这条更严格的"组装面里还有已选官方工具"断言,行为不变
- 载荷里没有工具数组时(0.2.1+):改用作用域视图逐项确认已选官方工具是否仍然可见(
tools.get(<官方名>, scope)),仍然可见就照旧 fail closed - 不要因为"看不到数组"就无条件 block —— 那是把"无法证明"当成"证明有泄漏"
影响面
- 启用 hide-official(
replaceTools非空)的用户在 DSH 0.2.1 上等于整会话不可用 - 与 [BUG] DSH 0.2.1-rc.3 + dsh-ops 0.4.1:PTC 回合第二次组装抛 Cannot read properties of undefined (reading 'length'),整轮中断 #412 是同一契约变更的两处,但 [BUG] DSH 0.2.1-rc.3 + dsh-ops 0.4.1:PTC 回合第二次组装抛 Cannot read properties of undefined (reading 'length'),整轮中断 #412 的 PTC 部分已由 [BUG] dsh-ops 0.4.1 在 DSH 0.2.1-rc.3 下每轮 prompt 装配崩溃:isPtc 读取 undefined.tools.length #387 /
211dc3e修好;这一处main上仍然存在
关联
Metadata
Metadata
Assignees
Labels
No labels
Activity
Gaudi-XIX commentedon Oct 26, 2026
Windows reproduction (win32-x64) — confirms it is not platform-specific
Environment
0.2.1-rc.3(Windows, win32-x64, Electron 44.7.0 / bundled node 24.21.0)0.4.1(npm release)dsh-ops-hide-officialenabled,replaceTools: ['grep'](single selection, not the full triple)Observed
Same failure, same message shape as the macOS report:
Two independent details worth noting:
missing OPS surface: grep -> ops_grepfires even withalwaysLoaded: [grep]configured on discovery — the single-selection path reaches the assembled-surface guard and still cannot see the replacement, consistent withresult.toolsbeing unconditionallyundefinedunder9d0c97b9d2. (First attempt was withoutalwaysLoaded; both fail, so the guard, not the publication, is the blocking step.)disabled: truewhile keepingconfig.replaceTools: ['grep']. After manually restoringdisabled: falsewith an empty selection, the row is inert (no masks, no errors), matching the documented zero-selection behavior.No new failure mode — this is a straight Windows confirmation of #413. Regression fix in #414 should cover it; happy to re-test on win32-x64 once it lands or a pre-release npm tag is published.
Gaudi-XIX commentedon Oct 26, 2026
Correction to this comment (I misattributed one detail):
That rewrite was not an automatic host fail-closed action — it was the user manually toggling the row off in the plugin settings UI after seeing the error. Everything else in this reproduction (the
READINESS_BLOCKEDmessage text, firing withreplaceTools: ['grep']both with and withoutalwaysLoaded: [grep], DSH0.2.1-rc.3+ dsh-ops0.4.1on win32-x64) stands unchanged. Apologies for the noise; the root-cause analysis in #413 and the fix in #414 are unaffected.fix(hide-official): verify the assembled surface without a tool array