better-dsh 0.0.0 → 0.2.2-a

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/LICENSE +24 -0
  2. package/README.md +294 -4
  3. package/control-prompt.md +37 -0
  4. package/cordis.patch.yml +53 -0
  5. package/docs/00_adr/0001-bridge-tool-layer-not-service-layer.md +14 -0
  6. package/docs/00_adr/0002-masking-is-presentation-only.md +15 -0
  7. package/docs/10_plans/A2A-messaging-channel-test-archive.md +256 -0
  8. package/docs/10_plans/code-mode-vs-rlm-ipython-comparison.md +137 -0
  9. package/docs/10_plans/dashr-blueprint-review.md +201 -0
  10. package/docs/10_plans/dashr-blueprint.md +561 -0
  11. package/docs/10_plans/dashr-compaction-window-and-archive.md +307 -0
  12. package/docs/10_plans/dashr-profile-layer-feasibility.md +367 -0
  13. package/docs/10_plans/dashr-sandbox-escalation-semantics-gap.md +171 -0
  14. package/docs/10_plans/dashr-security-sandbox-analysis.md +187 -0
  15. package/docs/10_plans/dashr-surface-invariant-and-omp-imports.md +97 -0
  16. package/docs/10_plans/ipython-kernel-interactive-interface-test-report.md +152 -0
  17. package/docs/10_plans/kernel-refactoring/Dash-IPython-Control-Prompt-draft.md +146 -0
  18. package/docs/10_plans/kernel-refactoring/Dash-IPython-Control-Prompt-draft_v3.md +50 -0
  19. package/docs/10_plans/kernel-refactoring/Dash-IPython-Control-Prompt-draft_v4.md +79 -0
  20. package/docs/10_plans/kernel-refactoring/Dash-vs-PrimeAgent-systemprompt-toolcatalog-comparison.md +138 -0
  21. package/docs/10_plans/kernel-refactoring/RLM-system-prompt-injection-gap-report.md +161 -0
  22. package/docs/10_plans/kernel-refactoring/V0.1.5-development-plan.md +109 -0
  23. package/docs/10_plans/kernel-refactoring/actinoable-surface-to-llm-in-agent-runtime_dsh.md +50 -0
  24. package/docs/10_plans/kernel-refactoring/actinoable-surface-to-llm-in-agent-runtime_prime.md +113 -0
  25. package/docs/10_plans/recallable-compaction.md +147 -0
  26. package/docs/10_plans/spike-tag-repro.mjs +102 -0
  27. package/docs/10_plans/upstream-analysis.md +128 -0
  28. package/docs/50_test-reports/REPL-/345/267/245/345/205/267/350/260/203/347/224/250-/346/210/252/346/226/255/350/257/212/346/226/255.md +110 -0
  29. package/docs/50_test-reports/kernel-provisioning.md +44 -0
  30. package/docs/50_test-reports/repl-kernel-provisioning-test-report.md +87 -0
  31. package/docs/50_test-reports/upstream-dsh-0.1.2-alpha.5-local-test-report.md +81 -0
  32. package/docs/50_test-reports/upstream-dsh-0.1.2-alpha.5-report.md +93 -0
  33. package/docs/50_test-reports/v0.1.8-improved-/345/256/236/346/265/213/346/212/245/345/221/212.md +142 -0
  34. package/docs/50_test-reports/v0.1.8-/345/256/236/346/265/213/346/212/245/345/221/212.md +193 -0
  35. package/docs/50_test-reports/v0.1.8b-/345/256/236/346/265/213/346/212/245/345/221/212.md +96 -0
  36. package/docs/50_test-reports/v0.1.8c-/345/256/236/346/265/213/346/212/245/345/221/212.md +127 -0
  37. package/docs/50_test-reports/v0.1.8d-/345/256/236/346/265/213/346/212/245/345/221/212.md +150 -0
  38. package/docs/50_test-reports/v0.1.8d_artifacts/README.md +138 -0
  39. package/docs/50_test-reports/v0.1.8d_artifacts/code-mode-repl-only.observation.md +74 -0
  40. package/docs/50_test-reports/v0.1.8d_artifacts/dsh-session-session-4a293388-9ae1-474b-87a0-9e17bb556d94.jsonl +3890 -0
  41. package/docs/50_test-reports/v0.1.8d_artifacts/dsh-session-session-4a293388-9ae1-474b-87a0-9e17bb556d94.w-sample-0435.jsonl +544 -0
  42. package/docs/50_test-reports/v0.1.8d_artifacts/functions.json +592 -0
  43. package/docs/50_test-reports/v0.1.8d_artifacts/skills-catalog.snapshot.md +30 -0
  44. package/docs/50_test-reports/v0.1.8d_artifacts/tools-sdk.output-schemas.json +1236 -0
  45. package/docs/50_test-reports/v0.1.8d_artifacts/tools-sdk.python.txt +592 -0
  46. package/docs/50_test-reports/v0.1.8d_artifacts/tools-sdk.typescript.txt +516 -0
  47. package/docs/50_test-reports/v0.1.8d_artifacts/wire-vs-transcription.diff.md +54 -0
  48. package/docs/50_test-reports/v0.1.8e-/345/256/236/346/265/213/346/212/245/345/221/212.md +224 -0
  49. package/docs/50_test-reports/v0.1.9a-/345/256/236/346/265/213/346/212/245/345/221/212.md +168 -0
  50. package/docs/50_test-reports/v0.2.0b-/345/256/236/346/265/213/346/212/245/345/221/212.md +123 -0
  51. package/docs/50_test-reports/v0.2.0b_artifacts/f2probe/Cargo.lock +7 -0
  52. package/docs/50_test-reports/v0.2.0b_artifacts/f2probe/Cargo.toml +6 -0
  53. package/docs/50_test-reports/v0.2.0b_artifacts/f2probe/src/bin/messy.rs +8 -0
  54. package/docs/50_test-reports/v0.2.0b_artifacts/f2probe/src/main.rs +4 -0
  55. package/docs/50_test-reports/v0.2.0b_artifacts/hashline-probe.md +5 -0
  56. package/docs/50_test-reports/v0.2.0b_artifacts/slowprobe/Cargo.lock +7 -0
  57. package/docs/50_test-reports/v0.2.0b_artifacts/slowprobe/Cargo.toml +7 -0
  58. package/docs/50_test-reports/v0.2.0b_artifacts/slowprobe/build.rs +4 -0
  59. package/docs/50_test-reports/v0.2.0b_artifacts/slowprobe/src/main.rs +13 -0
  60. package/docs/50_test-reports/v0.2.1-/345/256/236/346/265/213/346/212/245/345/221/212.md +110 -0
  61. package/docs/50_test-reports/v0.2.1b-/345/256/236/346/265/213/346/212/245/345/221/212.md +86 -0
  62. package/docs/50_test-reports/v0.2.1c-/345/256/236/346/265/213/346/212/245/345/221/212.md +66 -0
  63. package/docs/50_test-reports/v0.2.1d-/345/256/236/346/265/213/346/212/245/345/221/212.md +67 -0
  64. package/docs/50_test-reports/v0.2.1e-P1-/345/256/236/346/265/213/346/212/245/345/221/212.md +136 -0
  65. package/docs/50_test-reports/v0.2.1ef-dev-audit-report.md +73 -0
  66. package/docs/50_test-reports/v0.2.1f-plugin-shipped-ui-patches/345/256/236/346/265/213/346/212/245/345/221/212.md +102 -0
  67. package/docs/60_exploration-and-research/cordis-research.md +350 -0
  68. package/docs/60_exploration-and-research/dsh-web-profile-package-map.md +186 -0
  69. package/docs/60_exploration-and-research/dsh-web-ui-slot-system-research.md +310 -0
  70. package/docs/60_exploration-and-research/dsh-webui-strip-boundary-research.md +300 -0
  71. package/docs/60_exploration-and-research/ios-chat-app-bridge-research.md +324 -0
  72. package/docs/60_exploration-and-research/web-frontend-composability-research.md +191 -0
  73. package/docs/REPL-/345/267/245/345/205/267/350/260/203/347/224/250-/346/210/252/346/226/255/350/257/212/346/226/255.md +110 -0
  74. package/docs/adr/0001-bridge-tool-layer-not-service-layer.md +14 -0
  75. package/docs/adr/0002-masking-is-presentation-only.md +15 -0
  76. package/docs/distro-blueprint.md +81 -0
  77. package/docs/dsh-webUI-with-rlm-mode.png +0 -0
  78. package/docs/plans/A2A-messaging-channel-test-archive.md +256 -0
  79. package/docs/plans/code-mode-vs-rlm-ipython-comparison.md +137 -0
  80. package/docs/plans/dashr-blueprint-review.md +201 -0
  81. package/docs/plans/dashr-blueprint.md +561 -0
  82. package/docs/plans/dashr-compaction-window-and-archive.md +307 -0
  83. package/docs/plans/dashr-profile-layer-feasibility.md +367 -0
  84. package/docs/plans/dashr-sandbox-escalation-semantics-gap.md +171 -0
  85. package/docs/plans/dashr-security-sandbox-analysis.md +187 -0
  86. package/docs/plans/dashr-surface-invariant-and-omp-imports.md +97 -0
  87. package/docs/plans/ipython-kernel-interactive-interface-test-report.md +152 -0
  88. package/docs/plans/kernel-refactoring/Dash-IPython-Control-Prompt-draft.md +146 -0
  89. package/docs/plans/kernel-refactoring/Dash-IPython-Control-Prompt-draft_v3.md +50 -0
  90. package/docs/plans/kernel-refactoring/Dash-IPython-Control-Prompt-draft_v4.md +79 -0
  91. package/docs/plans/kernel-refactoring/Dash-vs-PrimeAgent-systemprompt-toolcatalog-comparison.md +138 -0
  92. package/docs/plans/kernel-refactoring/RLM-system-prompt-injection-gap-report.md +161 -0
  93. package/docs/plans/kernel-refactoring/V0.1.5-development-plan.md +109 -0
  94. package/docs/plans/kernel-refactoring/actinoable-surface-to-llm-in-agent-runtime_dsh.md +50 -0
  95. package/docs/plans/kernel-refactoring/actinoable-surface-to-llm-in-agent-runtime_prime.md +113 -0
  96. package/docs/plans/recallable-compaction.md +147 -0
  97. package/docs/plans/spike-tag-repro.mjs +102 -0
  98. package/docs/plans/upstream-analysis.md +128 -0
  99. package/docs/repositioning-and-rebranding.md +102 -0
  100. package/docs/v0.1.8-improved-/345/256/236/346/265/213/346/212/245/345/221/212.md +142 -0
  101. package/docs/v0.1.8-/345/256/236/346/265/213/346/212/245/345/221/212.md +193 -0
  102. package/docs/v0.1.8b-/345/256/236/346/265/213/346/212/245/345/221/212.md +96 -0
  103. package/docs/v0.1.8c-/345/256/236/346/265/213/346/212/245/345/221/212.md +127 -0
  104. package/docs/v0.1.8d-/345/256/236/346/265/213/346/212/245/345/221/212.md +150 -0
  105. package/docs/v0.1.8d_artifacts/README.md +138 -0
  106. package/docs/v0.1.8d_artifacts/code-mode-repl-only.observation.md +74 -0
  107. package/docs/v0.1.8d_artifacts/dsh-session-session-4a293388-9ae1-474b-87a0-9e17bb556d94.jsonl +3890 -0
  108. package/docs/v0.1.8d_artifacts/dsh-session-session-4a293388-9ae1-474b-87a0-9e17bb556d94.w-sample-0435.jsonl +544 -0
  109. package/docs/v0.1.8d_artifacts/functions.json +592 -0
  110. package/docs/v0.1.8d_artifacts/skills-catalog.snapshot.md +30 -0
  111. package/docs/v0.1.8d_artifacts/tools-sdk.output-schemas.json +1236 -0
  112. package/docs/v0.1.8d_artifacts/tools-sdk.python.txt +592 -0
  113. package/docs/v0.1.8d_artifacts/tools-sdk.typescript.txt +516 -0
  114. package/docs/v0.1.8d_artifacts/wire-vs-transcription.diff.md +54 -0
  115. package/docs/v0.1.8e-/345/256/236/346/265/213/346/212/245/345/221/212.md +224 -0
  116. package/docs/v0.1.9a-/345/256/236/346/265/213/346/212/245/345/221/212.md +168 -0
  117. package/docs/v0.2.0b-/345/256/236/346/265/213/346/212/245/345/221/212.md +123 -0
  118. package/docs/v0.2.0b_artifacts/f2probe/Cargo.lock +7 -0
  119. package/docs/v0.2.0b_artifacts/f2probe/Cargo.toml +6 -0
  120. package/docs/v0.2.0b_artifacts/f2probe/src/bin/messy.rs +8 -0
  121. package/docs/v0.2.0b_artifacts/f2probe/src/main.rs +4 -0
  122. package/docs/v0.2.0b_artifacts/hashline-probe.md +5 -0
  123. package/docs/v0.2.0b_artifacts/slowprobe/Cargo.lock +7 -0
  124. package/docs/v0.2.0b_artifacts/slowprobe/Cargo.toml +7 -0
  125. package/docs/v0.2.0b_artifacts/slowprobe/build.rs +4 -0
  126. package/docs/v0.2.0b_artifacts/slowprobe/src/main.rs +13 -0
  127. package/docs/v0.2.1-/345/256/236/346/265/213/346/212/245/345/221/212.md +110 -0
  128. package/docs/v0.2.1b-/345/256/236/346/265/213/346/212/245/345/221/212.md +86 -0
  129. package/docs/v0.2.1c-/345/256/236/346/265/213/346/212/245/345/221/212.md +66 -0
  130. package/lib/client/index.js +473 -0
  131. package/lib/index.d.ts +736 -0
  132. package/lib/index.js +11518 -0
  133. package/lib/kernel-env-hxaihi9C.js +195 -0
  134. package/lib/kernel-env.d.ts +80 -0
  135. package/lib/kernel-env.js +3 -0
  136. package/lib/py-sdk-BCaOGYz7.d.ts +125 -0
  137. package/lib/py-sdk-CbgYiX8O.js +691 -0
  138. package/lib/py-sdk.d.ts +2 -0
  139. package/lib/py-sdk.js +3 -0
  140. package/package.json +325 -4
  141. package/scripts/kernel-provision.mjs +35 -0
  142. package/index.js +0 -3
@@ -0,0 +1,13 @@
1
+ fn main() {
2
+ let mut total: u32 = 0;
3
+ for i in 0..10 {
4
+ total += i;
5
+ }
6
+ let label: u32 = "out-of-range-anchor";
7
+ println!("{total} {label}");
8
+ let _unused = 1;
9
+ let _also = 2;
10
+ let _third = 3;
11
+ let _fourth = 4;
12
+ let _fifth = 5;
13
+ }
@@ -0,0 +1,110 @@
1
+ # v0.2.1 实测报告(挂载核验:工具面 + REPL + MCP 桥接)
2
+
3
+ - 部署:commit `06e516a`(describe `v0.2.0c-3-g06e516a`),版本 `0.2.1`,profile web
4
+ - 部署位 `~/.dsh/profiles/web/node_modules/@pgmi-builds/better-dsh/lib/index.js` 与工作区 `dashr/lib/index.js` **md5 逐字节一致**(`a5490f0b635f6dfc9109b3ed026d2298`,构建于 Sep 1 00:50)——运行态与工作区 lib 同步,非陈旧部署
5
+ - 被测内容:本轮为「挂载核验」而非功能特性验收——REPL 挂载态、工具面 mask 不变式、MCP 桥接 best-effort 语义、control/catalog prompt 的 hint 到位情况
6
+ - 实测人:被测 Dash Agent 运行时本体(第一人称),第一人称 `eval` 探针直接读 `dir(tool)`
7
+
8
+ ## 部署核验(实测前置)
9
+
10
+ - 源码版本 `0.2.1`(dashr/package.json),工作树 HEAD `06e516a`;`git describe` = `v0.2.0c-3-g06e516a`。
11
+ - 工作树有未提交改动(`dashr/src/fallbacks/*` 删除、package.json/build-client 修改等,与 v0.2.1 fallbacks vendoring Path B 对齐);但 `dashr/lib/index.js` 已构建且与部署位 md5 一致,**lib 面代表运行态**。
12
+ - mask 名单在 lib 内(`MASKED_TOOL_NAMES` / `WIRE_MASKED_NAMES`,`src/index.ts:166`):`skill`、`send_message`、`report`、`list_agents`、`subagent`、`subagent_fork`、`interrupt_agent`、`workflow`、`ralph` 九名。
13
+
14
+ ## §1 REPL 挂载(✅ 正确)
15
+
16
+ - [x] `eval` 传输工具在位,跑在真实 IPython kernel(`sys.version` = **3.14.4**;README 文档的 managed venv 默认 CPython 3.11 未命中——当前用宿主 python 或显式 `DASHR_KERNEL_PYTHON`,非缺陷,见 O1)。
17
+ - [x] 会话持久化(state codification)成立:一笔 cell 赋的 dict 探针在下一笔 cell 原样读回。
18
+ - [x] `tool` 命名空间类型 `_DashrBindingHolder`;`__dashr_injected__` 在位(兼容面未动)。
19
+ - [x] `dir(tool)` 返回 **24 个排序绑定名、零 dunder**(introspection 契约 F9 成立)。
20
+ - [x] `eval` 自排除成立:`'eval' in dir(tool)` = `False`(self-call prevention,spec 唯一例外)。
21
+
22
+ ## §2 工具面 mask 不变式(⚠️ 一处回归)
23
+
24
+ - [x] 三桥在位:`agent`、`agent_message`、`agent_workflow`(registry 工具,非手写桥 schema)。
25
+ - [x] `llm_completion` 在位。
26
+ - [x] hashline 编辑家族 `edit`/`undo_last_edit` 在位;URL 包装 `read`/`write`/`grep`/`glob` 在位。
27
+ - [x] mask 九名中 **8 名双面零出现**:`skill`、`send_message`、`report`、`list_agents`、`subagent_fork`、`interrupt_agent`、`workflow`、`ralph`。
28
+ - [x] **回归**:`subagent` 双面泄漏——wire 工具声明在列(签名 `{description, prompt, run_in_background?}`,无 `mode`,即**宿主原生 subagent**,非 dashr `agent` 桥),且 `'subagent' in dir(tool)` = `True`。
29
+ - v0.2.0b 报告明确记录「mask 九名双面零出现」,本轮 `subagent` 回潮,属 **v0.2.0c→v0.2.1 区间引入的回归**。
30
+ - 部署 lib 与工作区同步(md5 一致),排除「陈旧部署」解释——是运行期 mask 未生效,非名单缺项。
31
+ - 最可能机制:mask 接线(`src/index.ts:1036-1039`)对整表 `restrict({deny})` 抛错后逐名降级,`subagent` 单名 `restrict` 抛「non-restrictable layer」被 catch 静默跳过(唯一静默跳过路径)。**宿主层根因待确认**(见建议 1)。
32
+
33
+ ## §3 MCP 桥接 best-effort + 非平坦定义(✅ 语义正确)
34
+
35
+ - [x] wire 面 14 个 MCP 工具(3 server:`orch-a2a` / `web-reader` / `zai-vision`),**0 个进 REPL 绑定**——自动桥接按 `isFlatBindableName` 机械跳过,符合 spec「Non-flat names SHALL be skipped」。
36
+ - [x] best-effort 的「能力不丢」成立:这 14 个 MCP 工具仍以**直接工具调用**形式可达(wire 声明在列),只是不能在 cell 内 `tool.<name>` 命中。
37
+
38
+ ### 「非平坦」的精确口径(纠正常见误读)
39
+
40
+ `isFlatBindableName`(`src/py-sdk.ts:447`)四条件**同时**满足才叫「平坦(flat-bindable)」:
41
+
42
+ 1. 匹配 `^[A-Za-z_][A-Za-z0-9_]*$`(纯 ASCII 标识符);
43
+ 2. 不以 `_` 开头;
44
+ 3. 非保留字(ECMAScript ∪ Python 并集);
45
+ 4. 非 5 个保留绑定全局(`console`/`__dsh_main__`/`__builtins__`/`__name__`/`__debug__`)。
46
+
47
+ **`__` 中缀本身不构成非平坦**——`__` 是合法 Python 标识符字符。实测:
48
+
49
+ - `'mcp__server__tool'.isidentifier()` = `True`(纯 `__` 中缀、无连字符 → 合法,可平坦绑定);
50
+ - 真实 MCP 名 `mcp__orch-a2a__a2a_agents` 的 `isidentifier()` = `False`。
51
+
52
+ **真正的元凶是连字符 `-`**(server 段 `orch-a2a`/`web-reader`/`zai-vision`),不是 `__`。所以「包含 `__` 就叫非平坦」是常见但不精确的 shorthand:`__` 是 MCP 命名约定的**作用域分隔符**,而让它非法的是名字里混进的 `-`(及任何非 `[A-Za-z0-9_]` 字符)。
53
+
54
+ ## §4 prompt hint 到位情况(✅ 已说明,属事实局限,非 defect)
55
+
56
+ 用户的判定标尺:hint 缺失 → defect/discrepancy;hint 已在而运行期确实做不到 → 事实局限。**结论落在后者**。
57
+
58
+ - [x] **hint 在位**。system prompt 的「Calling tools from the scripting pad」段(=`dashr:tool-catalog` 节的 `REPL_BRIDGE_INSTRUCTIONS`,`src/py-sdk.ts:616`)逐字给出:
59
+ > Tool names that are not plain identifiers (for example MCP names with hyphens or `__` infixes) have no `tool.<name>` member — call those as direct tool calls.
60
+ - [x] 运行期确实如此(§3 已证:14 MCP 工具 0 绑定,仅直接调用可达)。**文档与实现一致,是已声明的边界,不是缺说明的 defect。**
61
+ - [~] 次要观察 O2:hint 只在 **catalog 段**(`dashr:tool-catalog`)给出;**control 段**(`dashr/control-prompt.md`,「Tools inside a cell」写的是「every native tool is a member of the `tool` object」)**未提**非平坦例外。二者同在 system prompt、且 control 段的「native tool」措辞与 MCP 工具不在同一范畴,故不算自相矛盾;但若未来 control 段独立渲染(脱离 catalog 段),hint 会随 catalog 段一起消失——记录为提示性观察。
62
+
63
+ ## §5 eval 工具描述与行为不一致(❌ discrepancy)
64
+
65
+ - **现象**:`eval` 的 model-facing 描述承诺「top-level `await` and `return` work」——`EVAL_DESCRIPTION`/`EVAL_CELL_PARAM_DESCRIPTION`(`src/index.ts:205-217`),control 段 `control-prompt.md:8` 同文。运行期顶层 `return` 是 SyntaxError。
66
+ - **复现(本会话第一人称)**:cell `x = 41; print(...); return "cell finished"` → `SyntaxError: 'return' outside function`(`_DashrTopLevelReturnChecker` 于 AST 访问期抛出,`src/bootstrap.ts:231-250`);去掉 return 即正常。行为有测试固化:`test/runtime.spec.ts:92`「rejects a top-level 'return' as a SyntaxError, like a native IPython cell」。
67
+ - **机制**:kernel 按纯 IPython REPL 语义运行 cell——module scope(globals=locals)、`PyCF_ALLOW_TOP_LEVEL_AWAIT` 编译 + `eval`/`await` 执行模块协程(`src/bootstrap.ts:255-280`);顶层 `return`/`yield` 由 checker 显式判 SyntaxError,嵌套函数/类/λ 内 return 语义保留(与原生 Python 一致)。
68
+ - **根因**:描述文本是旧设计残留——blueprint(`docs/plans/dashr-blueprint.md:499`「top-level return = rewriter 改写为 `_DashrReturn`(BaseException)」)在 08-19 原生语义重构后**未随实现同步更新**;实现侧注释(`src/python.ts:6`、`src/bootstrap.ts:257-260`)写的是正确语义。**contract 对模型撒谎:承诺了 kernel 刻意拒绝的特性。**
69
+ - **影响**:模型按描述在 cell 内写顶层 `return`(本会话即发生),白费一轮往返。
70
+ - **await 条款核实(非 discrepancy)**:描述中「top-level `await` works」行为为真——kernel 确以 `PyCF_ALLOW_TOP_LEVEL_AWAIT` 编译并运行模块协程;且该能力是环境特性而非纯 Python(实测见会话讨论),故保留该条款必要且准确,仅 `return` 条款需修正。
71
+
72
+ ## 结果
73
+
74
+ **总体判定:REPL 正确挂载;工具面存在 1 处回归(`subagent` 泄漏)+ 1 处描述不一致(eval 顶层 `return` 承诺与行为相悖,await 条款属实);MCP 桥接 best-effort 有文档说明、属事实局限而非缺陷。**
75
+
76
+ ### 通过项
77
+
78
+ | # | 项 | 证据 |
79
+ |---|---|---|
80
+ | P1 | REPL 挂载 | eval 传输在位、IPython 3.14.4、dict 探针跨 cell 持久、`dir(tool)` 24 名零 dunder |
81
+ | P2 | 三面例外不变式 | `eval` 自排除(`'eval' in dir(tool)`=False) |
82
+ | P3 | 桥接家族 | `agent`/`agent_message`/`agent_workflow` + `llm_completion` + hashline `edit`/`undo_last_edit` + URL 包装四件套在位 |
83
+ | P4 | MCP best-effort | wire 14 MCP 工具 → 0 REPL 绑定;能力经直接调用保留 |
84
+ | P5 | 非平坦语义 | `isFlatBindableName` 机械跳过;`__` 中缀合法(实测 `isidentifier()=True`)、连字符是元凶(实测 `False`) |
85
+ | P6 | hint 到位 | catalog 段逐字声明非平坦例外,与运行期一致 |
86
+
87
+ ### 观察与欠账
88
+
89
+ | # | 级 | 观察 |
90
+ |---|---|---|
91
+ | D1 | **P2(回归)** | `subagent` 双面泄漏(wire + REPL),v0.2.0b「mask 九名零出现」→ 本轮回潮;部署 lib 同步排除陈旧部署;疑 `restrict` 单名降级静默跳过,宿主层根因待确认 |
92
+ | O1 | 记录 | kernel Python 3.14.4,README managed venv 默认 3.11 未命中(宿主 python 或显式 `DASHR_KERNEL_PYTHON`);非挂载缺陷 |
93
+ | O2 | 提示 | 非平坦 hint 只在 catalog 段(`dashr:tool-catalog`);control 段(`control-prompt.md`)措辞「every native tool」未提例外。当前二者同屏无矛盾;若 control 段未来独立渲染则 hint 可能失陪 |
94
+ | O3 | 提示 | hint 原文「hyphens or `__` infixes」并列举例略宽:`__` 中缀单独是合法标识符,真正非法的是 `-`。措辞方向正确(真实 MCP 名两者兼有),不算错误,但可收紧为「non-identifier characters such as hyphens」 |
95
+ | D2 | **描述不一致** | eval 描述承诺「top-level `return` work」,运行期为 SyntaxError(`_DashrTopLevelReturnChecker` 显式判错,`test/runtime.spec.ts:92` 固化);旧 rewriter 设计残留文本未随 08-19 原生语义重构更新(`src/index.ts:205-217`、`control-prompt.md:8`)。await 条款实测为真,不属此 discrepancy |
96
+
97
+ ### 建议
98
+
99
+ 1. **D1 回归定位**:在宿主层复核 `tools.restrict({deny:['subagent']})` 为何抛错/被跳过——确认 `subagent` 是否落在 non-restrictable 层(对比 v0.2.0b 到 v0.2.1 的 fallbacks vendoring 是否改变了该工具注册层)。修复优先级高于本轮其它项。
100
+ 2. O3 的一行措辞收紧:把 bridge instructions 里的 `hyphens or \`__\` infixes` 改为 `non-identifier characters (e.g. hyphens)`,避免模型把 `__` 误读为禁用符。
101
+ 3. O2 若在意,可在 `control-prompt.md` 的「Tools inside a cell」补半句非平坦例外,与 catalog 段互为印证。
102
+ 4. **D2 契约修正**:`EVAL_DESCRIPTION`/`EVAL_CELL_PARAM_DESCRIPTION`(`src/index.ts:205-217`)与 `control-prompt.md:8` 的「top-level `await` and `return` work」改为「top-level `await` works(kernel 以 `PyCF_ALLOW_TOP_LEVEL_AWAIT` 编译并运行模块协程,同 IPython cell);顶层 `return` 是 SyntaxError——cell 以 module scope 运行」。await 条款保留(行为为真,且该能力非纯 Python,正需向模型声明)。
103
+
104
+ ## D1 后续处理(2026-09-01,v0.2.1b)
105
+
106
+ **根因已确认(源码核实 + 会话日志实证)**:standard preset(`dsh-agent-presets/presets/standard/agent.cordis.yml`)的 `tool-subagent` 行配置 `modelSelectionSettings: true` → dsh-tool-subagent 的 `agent/created` 监听走 `candidate.ctx.inject([...])`,把 subagent 工具注册到**该 agent 自己的层**(own layer);registry `restrict` 只过滤 inherited 名(global + ancestors),own-layer 名永远可见、不可 restrict(dsh-tools `view()` 对 own.tools 无条件 visible)→ `restrict({deny:['subagent']})` 抛「unknown global tool」→ DASHR mask catch 静默跳过 → 全表面泄漏。其余八名(subagent_fork / workflow / ralph 等)无 modelSelectionSettings → composition 层 → 可 restrict → 正常。**v0.2.1 报告的 fallbacks 假设不成立**(06e516a 全为 LLM failover 机制)。
107
+
108
+ **v0.2.1b 决策(用户拍板,临时方案)**:接受暴露,不做 mask/覆盖——`subagent` 从 `MASKED_TOOL_NAMES` 移除(九名 → 八名);在 `control-prompt.md` 自由文本注解 `subagent` 为 `agent`(统一 agent-spawn 入口)的 alias、两者经同一 runtime 委托,保持模型面逻辑自洽。彻底方案(部署配置 modelSelectionSettings: false / DASHR own-layer 防线 / 上游修复)另行 change。
109
+
110
+ **实现状态**:v0.2.1b change(`openspec/changes/v0-2-1-fixes-and-escalation-guidance/`)内 D1/D2/O2/O3/escalation-guidance 全部落地,测试与部署核验见该 change 任务清单。
@@ -0,0 +1,86 @@
1
+ # v0.2.1b 实测报告(v0-2-1-fixes-and-escalation-guidance 第一人称复核)
2
+
3
+ - 部署:commit `247326a`(`v0.2.1a`),版本 `0.2.1-b`(package.json),profile web,宿主已重启、本会话运行于更新后的运行时
4
+ - 被测内容:**仅本 change**(`openspec/changes/v0-2-1-fixes-and-escalation-guidance/`)的四个面——D1 subagent 接受暴露 + alias 注解、D2 eval 描述契约、O2/O3 非平坦措辞、escalation-guidance 注入。不复核既往 feature/change
5
+ - 实测人:被测 Dash Agent 运行时本体(第一人称);注入探针直接读自身 system prompt 的 runtime-context 快照,工具面探针经 `dir(tool)` 与 wire 声明
6
+ - 对应任务清单:tasks.md 5.3「宿主重启新会话后复核」——本报告即该复核的记录
7
+
8
+ ## 部署核验(实测前置)
9
+
10
+ - 工作树 HEAD `247326a`(describe `v0.2.1a`);本 change 源码改动(`src/index.ts` / `src/py-sdk.ts` / `control-prompt.md` / 测试)为未提交工作树改动,但 `dashr/lib` 已重建且与部署位逐字节一致,**lib 面代表运行态**。
11
+ - md5 核验(工作区 `dashr/lib` ↔ 部署位 `~/.dsh/profiles/web/node_modules/@pgmi-builds/better-dsh/lib`):
12
+
13
+ | 文件 | 工作区 | 部署位 | 一致 |
14
+ |---|---|---|---|
15
+ | index.js | `284722a77b1f7fc310a24d0e22d69bb0` | 同左 | ✅ |
16
+ | py-sdk.js | `85691cac2d669fef46f257281f63a44d` | 同左 | ✅ |
17
+ | py-sdk-CbgYiX8O.js(实际实现 chunk) | `8410d97db290eceb1b3ba69cdc8edb86` | 同左 | ✅ |
18
+
19
+ - lib 产物内容抽查:`MASKED_TOOL_NAMES = new Set([skill, send_message, report, list_agents, subagent_fork, interrupt_agent, workflow, ralph])`(index.js:10894-10903,**八名、无 subagent**);escalation 注入句出现 1 次;`!sandboxPolicy` fail-closed 分支在位;eval 描述含「top-level `return` is a SyntaxError」;py-sdk chunk 措辞为「non-identifier characters, e.g. hyphens」且全文 0 处 `infixes`。
20
+
21
+ ## §1 D1:subagent 接受暴露 + control prompt alias 注解(✅)
22
+
23
+ - **源码**:`MASKED_TOOL_NAMES`(`src/index.ts:166`)已移除 `subagent`(九名 → 八名),注释记录 v0.2.1b 决策——standard preset 的 `modelSelectionSettings: true` 使 subagent 注册到 agent own 层、registry restriction 不可达,故接受暴露并以 control prompt 注解替代 mask。
24
+ - **control-prompt.md** 自由文本含 alias 注解(逐字):
25
+ > Delegation: `agent` is the unified agent-spawn entry; `subagent` is its native alias — both delegate through the same runtime, so call either.
26
+ - **wire 面(本会话 system prompt 工具声明)**:`subagent` 在列且签名 `{description, prompt, run_in_background?}`(无 `mode`,宿主原生 subagent,与 v0.2.1 判定一致);`agent` 在列且带 `mode`(dashr 桥);其余八名(skill / send_message / report / list_agents / subagent_fork / interrupt_agent / workflow / ralph)**双面零出现**。
27
+ - **REPL 绑定(第一人称 `dir(tool)` 探针)**:
28
+ - `'subagent' in dir(tool)` = **True**(有意保留)|`'agent' in dir(tool)` = True
29
+ - 八名泄漏 = **[]**(全部按预期 mask)
30
+ - `eval` 自排除 True、0 dunder、`_DashrBindingHolder` / `__dashr_injected__` 在位、共 28 个平坦绑定
31
+ - **功能冒烟(alias 注解推荐的直接调用面)**:`subagent` 实际委托成功——`fc86211b-3253-459b-8ed5-e0a8ec35a76c` 创建并结算,返回 `SUBAGENT-ALIAS-OK`。接受暴露不是摆设,委托链路真实可用。
32
+
33
+ ## §2 D2:eval 描述契约与运行期语义一致(✅)
34
+
35
+ - **描述文本**(`EVAL_DESCRIPTION` `src/index.ts` ~212 与 `control-prompt.md:8` 同一句式,本会话 system prompt 渲染逐字):
36
+ > `eval` takes two required arguments: `cell` (one Python program; top-level `await` works; top-level `return` is a SyntaxError — the cell runs in module scope; …)
37
+ - **无 return 承诺**:全文本不再出现「top-level `return` work」;await 条款保留(行为为真)。
38
+ - **行为实证(第一人称)**:提交含顶层 `return` 的 cell → 运行期抛 `SyntaxError: 'return' outside function`,traceback 定位 `_dashr_run_program` → `_DashrTopLevelReturnChecker().visit(parsed)` → `visit_Return` 显式判错(`src/bootstrap.ts:231-280` 路径)。**描述与行为一致,D2 契约修正成立**。
39
+ - **await 条款实证**:cell 内 `await asyncio.sleep(0)` → `await-ok`;await-in-comprehension `[0, 1, 2]`。kernel 以顶层 await 运行模块协程,描述属实。
40
+ - `test/runtime.spec.ts:92`「rejects a top-level 'return' as a SyntaxError」在套件全绿之列。
41
+
42
+ ## §3 O2/O3:非平坦措辞精确化(✅)
43
+
44
+ - **catalog 段**(`REPL_BRIDGE_INSTRUCTIONS`,`src/py-sdk.ts:616`)已改为(部署 chunk 逐字核验,且全文 **0 处 `infixes`**):
45
+ > Tool names that are not plain identifiers (non-identifier characters, e.g. hyphens) have no `tool.<name>` member — call those as direct tool calls.
46
+ - **control 段**(`control-prompt.md`「Tools inside a cell」)已补非平坦例外句,与 catalog 同义(见 §1 引用段)——v0.2.1 报告 O2 的「hint 只在 catalog 段」已闭合。
47
+ - **行为不变式**:MCP 非平坦名仍 0 绑定(本会话 0 个 `mcp*` 进 REPL),能力经直接调用保留;`'mcp__cordis-a2a__a2a_agents'.isidentifier()` = False、`'mcp__server__tool'.isidentifier()` = True——元凶确为连字符而非 `__`,措辞收紧方向与实现一致。
48
+
49
+ ## §4 escalation-guidance 注入(✅,第一人称最强证据)
50
+
51
+ - **源码**(`src/index.ts:1099-1118`):`ctx.systemPrompt.context({ name: 'dashr:escalation-guidance', order: ESCALATION_GUIDANCE_ORDER = 116, text })`;text 为 use-time 求值——`sandboxPolicy?.resolve({ session: context.agent?.session })`,`mode === 'workspace-write'` 返回注入文本,否则空串;service 缺失 / 无 agent 时 fail-closed(空串)。注册处注释注明依赖 upstream CONTEXT_ORDERS(110/115/120)。
52
+ - **模式矩阵测试**(`test/presentation.spec.ts:208-281`,v0.2.1b model-surface contracts):order 116 在位 / workspace-write 注入 / read-only、danger-full-access 空 / 无 sandboxPolicy service 空——套件全绿。
53
+ - **本会话 runtime-context 快照(第一人称实测)**——当前为 workspace-write 模式,快照逐行:
54
+
55
+ ```
56
+ Current DSH file policy: workspace-write. Any available operation enforced by the
57
+ DSH file sandbox may modify files under the session workspace: "/home/u1/workspaces/dashr". …
58
+
59
+ Approval policy: ask. Operations that require approval may ask through the configured
60
+ answerers; without an available answerer, the request fails closed.
61
+
62
+ Restricted operations may be retried once with sandbox_permissions for single-call
63
+ escalation, pending user approval.
64
+ ```
65
+
66
+ 注入句**精确等于** D3 披露文本(`Restricted operations may be retried once with sandbox_permissions for single-call escalation, pending user approval.`),且**紧贴 `approval:policy`(115)之后、`subagent:delegation`(120)之前**——order 116 位置成立,渲染在 policy 段落同一快照内。
67
+
68
+ ## §5 测试套件
69
+
70
+ - `npx vitest run`:**31 files,392 passed | 3 skipped(395),exit 0**(109.89s)——与 tasks 2.3 / 4.3 预期(395 全绿、presentation.spec 19/19)一致。
71
+
72
+ ## 观察(非缺陷)
73
+
74
+ | # | 级 | 观察 |
75
+ |---|---|---|
76
+ | O-1 | 记录 | 部署位残留陈旧 chunk `py-sdk-DRmSaN8R.js`(md5 `77cd3ed0…`,内容寻址 chunk,未被引用、无加载风险)——清理可选 |
77
+ | O-2 | 记录 | 本会话 kernel python = 部署 `.venv-kernel` 的 **3.11.15**(traceback 实证 `.venv-kernel/lib/python3.11`)——v0.2.1 报告 O1「managed venv 3.11 未命中、用宿主 3.14.4」在本次重启后已命中 managed venv;环境事实 |
78
+ | O-3 | **已修正为缺陷** | REPL 内工具调用截断的**真实原因**:非阻塞问题,而是任何 `tool.*` RPC 都触发 `registry[TOOL_RUNTIME_SCHEDULER]` 为 undefined → `scheduler.prepare` TypeError → driver 无 catch 的 unhandled rejection → harness `installFailLoud` 判定 fatal → **daemon 崩溃重启** → repair 合成「interrupted」。4/4 复现(17:39/17:41/17:57/18:02),journald 铁证。详见 `docs/REPL-工具调用-截断诊断.md`;修复后需重跑探针矩阵 |
79
+
80
+ ## 结果
81
+
82
+ **总体判定:v0.2.1b 四项目标(D1 接受暴露 + alias 注解、D2 eval 描述契约、O2/O3 非平坦措辞、escalation-guidance order-116 注入)在新会话运行态下全部成立,无回归、无 discrepancy。**
83
+
84
+ - v0.2.1 报告的两处问题均已按本 change 落地闭合:D1 回归 → 转为有意暴露 + 注解(功能冒烟通过);D2 描述不一致 → 描述与运行期语义一致(顶层 return 实测 SyntaxError)。
85
+ - 注入矩阵在 workspace-write(本会话实际模式)下第一人称可见,read-only / danger-full-access 不注入由单测矩阵覆盖。
86
+ - tasks.md 5.3(宿主重启新会话复核)完成:control 段 alias 注解 ✓、eval 描述无 return 承诺 ✓、escalation 注入文本位于 `approval:policy` 之后 ✓。
@@ -0,0 +1,66 @@
1
+ # v0.2.1c 实测报告(v0-2-1c-repl-tool-crash-fix 第一人称实测)
2
+
3
+ - 部署:版本 `0.2.1-c`(package.json,工作区与部署位一致),profile web;用户已执行部署同步 + daemon 重启(19:23:19),本会话运行于更新后的运行时
4
+ - 被测内容:**本 change**(`openspec/changes/v0-2-1c-repl-tool-crash-fix/`)的六.1(drive 加 catch)+ 六.2(scheduler 防御)在活体 daemon 上的回归核验基线(六.5);六.3 根因归属复核
5
+ - 实测人:被测 Dash Agent 运行时本体(第一人称);探针经 `eval` cell 内 `tool.<name>(...)` 直接调用 REPL 子分派桥——与 v0.2.1b 崩溃复现矩阵完全同路径
6
+ - 对应任务清单:tasks.md 6.1 / 6.2 / 6.3(以及 3.2 活体复核)——本报告即该核验的记录
7
+
8
+ ## 部署核验(实测前置)
9
+
10
+ - 版本:`dashr/package.json` 与部署位 `~/.dsh/profiles/web/node_modules/@pgmi-builds/better-dsh/package.json` 均为 `0.2.1-c` ✅
11
+ - md5 核验(工作区 `dashr/lib` ↔ 部署位 lib):
12
+
13
+ | 文件 | 工作区 | 部署位 | 一致 |
14
+ |---|---|---|---|
15
+ | index.js | `861fb9d3fb108015fb1d665d00d789b2` | 同左 | ✅ |
16
+ | client/index.js | `8b1548613b5d68ef4606f4729b0af312` | 同左 | ✅ |
17
+
18
+ - `diff -rq lib/` 两侧 **LIB DIRS IDENTICAL**(含删除陈旧 chunk 后的完整目录对比)✅
19
+ - lib 产物内容抽查:六.2 loud 错误文本(`the tools service resolved by this composition lacks the TOOL_RUNTIME_SCHEDULER symbol …`)在 index.js 中出现;六.1 lane backstop(`settling queued dispatches as errors`)在源码 `src/index.ts:642-652` 在位 ✅
20
+ - daemon 重启:journal 显示 19:23:19 旧进程(pid 443984)SIGTERM 优雅停止 → 同一秒新进程(pid 532389→532407→532567)启动;自重启至今 **0 条 fatal / TypeError / FAILURE / restart** ✅
21
+
22
+ ## §1 4 探针矩阵(六.5 回归核验,第一人称)
23
+
24
+ 对照 v0.2.1b 诊断矩阵(`docs/REPL-工具调用-截断诊断.md` §一),同 cell 内容在**本会话(v0.2.1c 运行态)**重跑:
25
+
26
+ | # | cell 内容 | v0.2.1b 结果 | v0.2.1c 实测结果 | 判定 |
27
+ |---|---|---|---|---|
28
+ | 1 | `await tool.subagent({… run_in_background: false })` | 截断(daemon 崩溃 17:39:17) | cell 收到 `ToolCallError`,消息点名 `TOOL_RUNTIME_SCHEDULER` symbol + scope/service view 上下文 | ✅ 返回结果非截断 |
29
+ | 2 | `await tool.subagent({… run_in_background: true })` | 截断(daemon 崩溃 17:41:15) | 同上 | ✅ 返回结果非截断 |
30
+ | 3 | `await tool.bash({… run_in_background: true })` | 截断(daemon 崩溃 17:57:05) | 同上 | ✅ 返回结果非截断 |
31
+ | 4 | `await tool.read({path: "dashr/package.json"})` | 截断(daemon 崩溃 18:02:27) | 同上 | ✅ 返回结果非截断 |
32
+
33
+ - **4/4 全部返回可见结果**(loud `ToolCallError`,含完整上下文消息),**零截断、零 daemon 崩溃**。每次探针后 daemon 继续存活、后续 cell 正常执行——与 v0.2.1b 的「探针即杀进程」形成对照。
34
+ - 探针实际收到的错误消息(4/4 逐字一致):
35
+ > `eval: the tools service resolved by this composition lacks the TOOL_RUNTIME_SCHEDULER symbol (a scope/service view instead of the native ToolRuntime instance) — REPL sub-dispatch cannot run; check the harness mount wiring (packages/core/tools) resolving the plugin's tools service`
36
+ - **对照结论**:v0.2.1b 同路径的「裸 `undefined.prepare` TypeError → driver 无 catch → unhandled rejection → installFailLoud fatal → daemon exit(1) → repair 合成 interrupted-tool-result」链条已被六.1+六.2 打断。错误现在**在 cell 内可见**,binding promise 正常 settle,进程零外泄。
37
+
38
+ ## §2 journald 守护进程日志(六.5 铁证)
39
+
40
+ - 自重启时刻 19:23:19 起:`journalctl --user -u dsh.service --since "19:23:19"` grep `fatal|TypeError|FAILURE|restart|crashed|exit` → **0 条匹配**;journal 尾部仅启动 INFO(MCP 注册、dsh web URL)。
41
+ - 对照:v0.2.1b 的 17:39:17 / 17:41:15 / 17:57:05 / 18:02:27 四条 fatal load failure(`Cannot read properties of undefined (reading 'prepare')`)**不再出现**。
42
+ - 会话日志侧:本会话(`session-6c013361…`)**0 条 `interrupted-tool-result`** repair 事件——无截断指纹。且因六.2 guard 在 `binding()` 内、`start()` 之前抛错(`src/index.ts:695-697` 先于 `tool/code-dispatch-start` append),本次探针连半程 dispatch 日志都没有留下——错误在最早点被拒绝,不产生部分状态。✅
43
+
44
+ ## §3 根因归属与交付边界(六.3 活体复核)
45
+
46
+ - 活体探针结论:**生产组合仍把 `runtimeCtx.tools` 解析为缺 `TOOL_RUNTIME_SCHEDULER` 实例 symbol 的 scope/service 视图**——4/4 探针的 loud 错误本身就是活体证据(错误消息由 guard 在 symbol 判空时抛出,证明运行态确实取不到 symbol)。
47
+ - 与诊断文档 §四/§七的推演一致:测试组合(根作用域原生实例,symbol 在位)全绿,生产组合(preset realm / plugin tree 发布路径带 shadow 标记 → `getTraceable` 返回原型而非实例)缺 symbol——**差异在 harness 侧(dsh-alpha),作为外部依赖记录**。
48
+ - **本 change 的 dashr 交付边界 = 「不崩溃 + loud 错误」——已达成**(§1+§2 实证)。「调度器真正可用、REPL 子分派真实执行」取决于 harness 挂载修正(dsh-alpha),不在本 change 交付物内。
49
+
50
+ ## §4 测试套件
51
+
52
+ - `npx vitest run`(本轮实测重跑):**31 files、396 passed | 3 skipped = 399 绿、exit 0**(109.41s)——与 tasks.md 记录的 399 全绿一致,含 3 个 v0.2.1c 韧性回归用例(缺 symbol 视图 → loud 错误;`scheduler.prepare` 抛错 → binding settle 可见错误;classify 抛错 → lane backstop settle 且进程存活)。本轮实测的活体行为与这三个用例的断言一一对应。
53
+
54
+ ## 观察(非缺陷)
55
+
56
+ | # | 级 | 观察 |
57
+ |---|---|---|
58
+ | O-1 | 记录 | REPL 内 `tool.*` 子分派目前**不可用**(调度器 symbol 缺失,loud 错误可见)——这是 harness 侧外部依赖,非本 change 回归;dashr 侧防御保证了「不可用」以可见错误呈现而非进程崩溃 |
59
+ | O-2 | 记录 | 本次守护进程重启(19:23:19)由用户执行,重启后本会话续跑于新 lib(部署位 md5 与工作区一致);journal 无旧崩溃残留以外的任何异常 |
60
+
61
+ ## 结果
62
+
63
+ **总体判定:v0.2.1c 的目标在活体 daemon 上全部成立——六.1(drive 加 catch)阻断 unhandled rejection 外泄、六.2(scheduler 防御)把裸 TypeError 转为 cell 可见 loud 错误;4 探针矩阵 4/4 返回结果而非截断,journald 自重启后 0 条崩溃,会话日志 0 条 interrupted-tool-result 修复事件。**
64
+
65
+ - tasks.md 6.1(4 探针矩阵 4/4 非截断)✅、6.2(journal 无新崩溃)✅、6.3(本报告)✅、3.2(活体复核:根因确认在 harness,dashr 可及范围防御已实施,harness 侧记录为外部依赖修复)✅。
66
+ - 交付边界已按设计执行:dashr 侧「不崩溃 + loud 错误」;「调度器真正可用」依赖 dsh-alpha 挂载修正,需在 harness 侧 change 中跟进。