better-dsh 0.0.0 → 0.2.3

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,150 @@
1
+ # DASHR URL Schema v0.1.8d 第一人称实测报告
2
+
3
+ - **日期**: 2026-08-27
4
+ - **测试者**: Dash Agent 运行时自身(pc-deepseek-default,session `session-6fb5ad2a-1b62-471c-8db3-edbf1152360f`)
5
+ - **被测对象**: 部署在本运行时上的 `@pgmi-builds/dashr` `0.1.8-d`(lib 构建于 08-27 02:33,profile 中 `dsh-better-edit` 已移除)
6
+ - **方法**: 全部通过被测运行时自身的工具面(`read`/`write`/`grep`/`glob` 直调 + `eval` 内 `tool.*` 调用)发起,无旁路。
7
+ - **版本**: v2 活文档。初版 = url-schema 实测;v2 并入工具面四层矩阵(L0/L1A/L1B/L2)、L1B 原生面探针修正、上游呈现层(dsh-tools)源码考据。后续讨论如有更新,一并并入本报告。
8
+
9
+ ## 结论
10
+
11
+ **v0.1.8d 已真实生效。** 上一轮(08-25,v0.1.8c)的两个根因——宿主进程陈旧、BetterEdit 外挂未移除——均已消除。7 个 scheme、统一选择器、错误词汇、grep/glob 双翻译路径全部按设计工作。另发现 **2 处设计文档滞后(实际行为优于文档)** 和 **1 处未文档化的行为边界**。
12
+
13
+ **v2 修正(重要)**:初版关于被掩工具"不可调"的判断被原生面探针**证伪**——被掩的 `skill` 以模型直调形式完整执行(§6.3)。这不是缺陷:ADR-0001/0002 本就设计为 "registered, executable, and dispatchable",presentation-only 在 API 层字面成立。
14
+
15
+ ## 1. 部署状态(对照上轮失败根因)
16
+
17
+ | 检查项 | 结果 |
18
+ |---|---|
19
+ | 安装版本 | `0.1.8-d` ✓ |
20
+ | `dsh-better-edit` 残留 | package.json 与 node_modules 均无(仅剩无关的 `dsh-better-sidebar`)✓ |
21
+ | URL 路由 | 所有 scheme 真实路由,不再坍缩成 `skill:/grilling` 文件路径 ✓ |
22
+
23
+ ## 2. Scheme 路由(全过)
24
+
25
+ | 探测 | 结果 |
26
+ |---|---|
27
+ | `skill://grilling` | 完整技能正文(path 根 `/home/u1/.agents/skills/grilling/SKILL.md`)|
28
+ | `agent://` | 五列 roster(id/status/kind/parent/last activity),本会话 `running` 态可见 |
29
+ | `agent://<id>` | 最后一条非空 assistant 输出 |
30
+ | `agent://<id>/transcript:1-15` | transcript + 行选择器组合 |
31
+ | `dsh://docs` | 27 项文档清单 |
32
+ | `dsh://docs/adr/0002-….md:1-12` | 深层路径 + 选择器 |
33
+ | `ctx://` | 精确三键 `session` / `model` / `cwd` |
34
+ | `ctx://session` | `{id, status, delegationDepth:0}`,undefined 字段(如 maxTokens)按设计省略 |
35
+ | `ctx://model` | `{provider: deepseek-official, model: deepseek-v4-flash}` |
36
+ | `ctx://cwd` | 裸字符串 `/home/u1/workspaces/dashr` |
37
+ | `dvc://` | `no devices mounted` 占位符 |
38
+ | `http(s)://` | 见 §4 |
39
+
40
+ ## 3. 选择器与错误词汇(全过)
41
+
42
+ - `:1-5` 区间、`:3-3` 单行、`:raw` 全文、`?q=frontier` 行过滤、`:999-1002` 越界优雅返回空 —— 全部符合统一选择器语义。
43
+ - `foo://bar` / `history://x` / `xd://screen` → 统一 `no handler registered for scheme … (registered: agent, ctx, dsh, dvc, http, https, skill)`。**D11 确认**:`history://` 无特例、`xd://` 改名彻底、错误信息自带注册表。
44
+ - `ctx://bogus` → `unknown snapshot key (known: session, model, cwd)`。
45
+ - `dvc://nonexistent-device` → `unknown device: …` 占位文本(非错误,符合 D3)。
46
+ - URL 写拒绝:`write skill://…` → 只读 scheme 拒绝;`write dvc://…` → `no devices mounted to route the write to`。
47
+
48
+ ## 4. http(s) handler(D9,全过)
49
+
50
+ | 探测 | 结果 |
51
+ |---|---|
52
+ | `https://example.com` | 首行 disclaimer 逐字符合设计,空行 + 正文 |
53
+ | 404 | `HTTP GET … returned 404 Not Found`(URL_HTTP_STATUS)|
54
+ | PNG | 媒体白名单拒绝,错误文案含白名单明细(URL_HTTP_UNSUPPORTED_MEDIA)|
55
+ | 10MB `.dat` | `body … is 10485760 bytes, over the 2097152-byte (2 MiB) text limit`(URL_HTTP_TOO_LARGE,报告真实字节数;且优先级正确:尺寸预检先于媒体检查)|
56
+ | DNS 失败 | `URL_HTTP_FETCH_FAILED`,嵌套原因消息保留 |
57
+ | 429 | 结构化状态错误 |
58
+
59
+ 未覆盖:20 s 超时预算(无可靠慢端点,不烧时间)。
60
+
61
+ ## 5. grep/glob over URL(D10,全过)
62
+
63
+ - **path-backed**:`grep skill://grilling frontier` → 原生 ripgrep 直打 `/home/u1/.agents/skills/grilling/SKILL.md`(4 matches,真实路径);`glob skill://grilling` → 真实磁盘路径。
64
+ - **content-backed**:`grep ctx:// session` → 物化到 `/tmp/dashr-url-*/content.txt` 后搜索;`grep agent:// running` → roster 命中本会话行;`glob agent://` → 解析文本本身即清单(非空行直出,无原生调用)。临时目录清理验证:`/tmp` 中 `dashr-url-*` 残留为 0。
65
+
66
+ ## 6. skill 掩码(D5)——四层矩阵与 "presentation-only" 的精确边界
67
+
68
+ **v2 修正**:本节初版曾把被掩工具标为 L1B 不可调。经原生面探针证伪:以**原生函数调用**直接调 `skill({"name":"grilling"})`,调用完整执行,返回完整 `<skill_content>` 块(与用户直呼技能名的 host 注入同格式)。掩码摘掉的是广告,不是执行通路。
69
+
70
+ ### 6.1 分层定义
71
+
72
+ | 层 | 含义 | 控制者 |
73
+ |---|---|---|
74
+ | **L0** 注册表 | 运行时可达,分发在此解析 | dsh 宿主;掩码与遮蔽均不触碰 |
75
+ | **L1A** 目录可见 | 出现在呈现给 LLM 的目录/SDK 声明文本 | DASHR 投影(`collectSdkSchemas` → `dashr:tool-catalog` section) |
76
+ | **L1B** 原生可调 | 模型经 API 函数调用面直接发起并执行 | 上游呈现层(`wireSchemas`/`resolveExecution`) |
77
+ | **L2** REPL 可调 | `eval` 内作为 `tool.*` 成员调用 | DASHR REPL 绑定 allowlist(`_dashr_install_bindings`) |
78
+
79
+ ### 6.2 实测矩阵(v2,每格有本会话实证或源码考据)
80
+
81
+ | 工具 | L0 | L1A 目录 | L1B 原生调 | L2 REPL |
82
+ |---|:--:|:--:|:--:|:--:|
83
+ | `subagent`(delegation 组) | ✓ | ✓ | ✓ | ✓ |
84
+ | `skill`(上游) | ✓ | ✗ 掩码 | **✓ 探针执行** | ✗ `unknown binding` |
85
+ | `report`(上游) | ✓(child scope) | ✗ 掩码 | 未探¹ | ✗ |
86
+ | `send_message`(上游) | ✓ 被遮蔽 | ✗ 掩码 | 按名不可达² | 按名不可达² |
87
+ | `send_message`(DASHR 桥) | ✓ 独立注册 | ✓ | ✓ | ✓ |
88
+ | `mcp__cordis-a2a__*` | ✓ | ✓ | ✓ 实测 `a2a_agents` | ✗ 非平坦名 |
89
+ | native `read`(dsh-tool-fs) | ✓ 被遮蔽 | ✗ | ✗ 按名解析到 dash read | ✗ |
90
+ | dash `read`(URL 路由+hashline) | ✓ 最近层胜出 | ✓ 唯一可见 | ✓ 全部 URL 实测 | ✓ 实测路由 `ctx://model` |
91
+
92
+ ¹ `report` 只在 child scope 注册,root 探出 `UNKNOWN_TOOL` 无法区分"掩码拦截"与"未注册",探针无诊断力,故不探。
93
+ ² 同名遮蔽:调 `send_message` 按名解析到最近的 DASHR 桥(plan Q25,receiver='child' 桥接工具下行、'parent' 桥接 reportFrom 上行),上游定义按名不可达——这是遮蔽语义,不是掩码语义。
94
+
95
+ ### 6.3 为什么 L1B 放行(源码级因果链)
96
+
97
+ 1. `view(scope)`(dsh-tools):`visible` = 全局层+祖先层中每层 `admits` 全票通过的名字,加上本 scope 自有层无条件注册的名字。掩码**不注册任何可见性过滤**(dashr/src/index.ts:144:"The registry itself is never touched (no `restrict()` …)"),`skill` 恒在 `visible`。
98
+ 2. `wireSchemas(scope)`:`native`/`both` 模式全量 `visible` 上 wire;仅 `code` 模式坍缩到只剩 `run_code`。
99
+ 3. `resolveExecution(name, scope, nested)` 的拒绝条件 `collapses()` 全式:`!nested && mode==="code" && name!=="run_code"`。本会话为 `both` 模式(原生调用与 eval 并存),模型直调任何 visible 工具都放行。
100
+ 4. `UNKNOWN_TOOL` 只属于:不在 `visible`、或 code 模式下非 `run_code` 的模型直调——两者都不适用于被掩工具。
101
+
102
+ ADR-0002 Consequences 原文:"The masked tools remain in the registry and are reachable via nested sub-dispatch with a parent token";ADR-0001:"must stay registered and executable even though the model never sees their names"。本探针表明 `both` 模式下比 ADR 表述更强:**模型直调**即可达,无需 parent token。
103
+
104
+ ### 6.4 L2 才是掩码的硬门
105
+
106
+ REPL 绑定是显式 allowlist(`_dashr_install_bindings` 注入 28 个函数名,不含 `skill`/`report`):`await tool.skill({"name":"grilling"})` → `ToolCallError: unknown binding "tool.skill"`,调度层硬拒绝。allowlist 含全部 delegation 工具(`subagent`/`subagent_fork`/`list_agents`/`interrupt_agent`/`workflow`/`ralph`)与 `send_message` 桥,印证 ADR-0002 v0.1.9"delegation 直通、不重包装"。
107
+ 假象排除:`getattr(tool,'skill')` 与 `getattr(tool,'definitely_not_a_tool_xyz')` 都返回 function——惰性代理对任意名字都给可调用对象,`hasattr` 不能作掩码探针;门禁在调用时的绑定校验。
108
+
109
+ ### 6.5 两个易混机制
110
+
111
+ - **掩码 vs 遮蔽**:掩码 = 投影点过滤(`MASKED_TOOL_NAMES = {send_message, report, skill}`,dashr/src/index.ts:154,打在 `collectSdkSchemas` 与 REPL `toolFunctions` 两点),注册表不动;遮蔽 = 同名最近层胜出(dash read 注册在 agent 自有层,native read 按名解析永远到达 dash read;上游 send_message 被桥遮蔽)。两者都表现为 L0✓/L1A✗,但 L1B 命运相反:**被掩的仍可执行,被遮的按名不可达**。
112
+ - **L2 的两道过滤**:MASKED 之外另有 `isFlatBindableName`(连字符名不可作成员)——MCP 工具 L1A✓/L1B✓/L2✗,证明 REPL 投影与目录投影独立分叉。
113
+
114
+ ## 7. 非 URL 委托保真(D2-restore/D7)
115
+
116
+ 普通 `write`/`grep`/`glob` 行为原生:scratch 文件正常创建与删除、`grep dashr/src URL_UNREGISTERED_SCHEME` 命中源码 3 处、`glob openspec/changes/url-schema *.md` 正常返回。capture-before-register 委托在本会话无回归表现。
117
+
118
+ ## 8. 与设计文档的偏差
119
+
120
+ ### 8.1 文档滞后(实际行为优于文档,建议更新 design.md)
121
+
122
+ 1. **D9 已知限制":port 端到端失败"已不成立**:`https://example.com:443/` 成功取回;`https://example.com:80/` 报 TLS `wrong version number`(端口真实抵达 fetch 层)。http 解析豁免看起来已完整实现,但 D9 及 Open Questions 仍标 OPEN/deferred。
123
+ 2. **D9 "`?…` 被吃成 query 选择器导致结果二次过滤"已不成立**:`https://example.com/?x=1` 返回完整正文,无双重过滤。
124
+
125
+ ### 8.2 未文档化的行为边界(建议二选一:补文档或修)
126
+
127
+ - `agent://<parent>/<child>` 对**已完成([ready] 态)的一次性子代理**返回 `child agent … is not live in the session store`。路由与结构化错误正确(短 id → `unknown child agent`,全 UUID → `not live`),但 D3 表承诺 "nested output" 未注明活性约束;一次性 subagent 的收尾输出(`NESTED-FORM-PROBE-OK`)在完成后经 URL 不可取回。
128
+ - 关联观察:roster 表从未列出子代理行(parent 列全为 `-`)——一次性 subagent 会话似不进 `ctx.sessions`。
129
+
130
+ ## 9. 建议
131
+
132
+ 1. 更新 design.md D9 与 Open Questions:`:port` 与 `?query` 豁免已实现,关闭该 open question。
133
+ 2. 在 D3 表为 `<id>/<child>` 注明活性约束,或让 handler 回退到 `ctx.subagents` 的存档输出。
134
+ 3. 无需任何回滚动作;本轮未发现阻断性缺陷。
135
+ 4. design.md D5 / ADR-0002 补记实测结论:catalog 掩码在 `both` 模式下**不移除原生面可执行性**(模型直调可达,§6.3 探针)。若未来需要真正的 L1B 拒绝,机制是可见性层 restrict 或模式坍缩——ADR-0002 已因 ordering hazards 明确拒绝前者。应作为有意识的安全边界记录在案。
136
+
137
+ ## 10. 附:上游呈现层考据——原生 dsh 本就有 catalog 机制,DASHR 是同槽位本地化重实现
138
+
139
+ **结论先行**:原生 dsh 必然也向 LLM 呈现工具目录(否则模型无从得知工具面),机制在 `@deepseek-ai/dsh-tools` 包;DASHR 的 `dashr:tool-catalog` section **顶替上游同名 slot**(dashr/src/index.ts:1010 注释自证:"the same scope-aware shape as upstream's sdkSection",pre-0.1.5 名为 `tools:dashr-sdk`)。"机制层面抄上游再本地化"成立;逐行同源与否在编译产物层面不可证。
140
+
141
+ 上游机制(编译产物 lib/index.js 可读):
142
+
143
+ - `tools` 服务构造时注册**两条呈现通道**:
144
+ - `ctx.systemPrompt.tools((context) => this.wireSchemas(context.scope))` —— **wire 通道**:API 请求的 tools 声明数组,按调用 scope 的 `view.visible` 渲染;
145
+ - `sdkSection()`(name `tools:sdk`,order 150)—— **SDK 文本通道**:`code`/`both` 模式下把工具面渲染为语言对应 SDK 声明(`SDK_RENDERERS[runtime.language]`),`native` scope 渲染为空。DASHR 的 section 使用同一 order(SDK_SECTION_ORDER)顶替。
146
+ - **呈现模式三态** `native`/`code`/`both`:最近 scope 层胜出(`presentAs()` 按 scope 声明,进程级默认走 `mode` 配置)。`code` 模式配 `collapseSection`(`tools:code-only`)向模型声明"只可调 run_code"——上游注释明言:缺了它,模型会对着 SDK 目录发原生调用、收 `UNKNOWN_TOOL`,进而"concludes the deployment is inconsistent"。
147
+ - **分发门** `resolveExecution` → `collapses`:`!nested && mode==="code" && name!=="run_code"` 才拒;嵌套子分发(parent token,SDK 内调绑定工具)永可调任何 visible 工具。`UNKNOWN_TOOL` 支持带 `reachableFrom` 提示("unknown tool X: 从哪个 scope 可达")。
148
+ - **`view(scope)` 解析**:inherited = 全局层+祖先层、每层 `admits` 全票;own 层无条件加入;`knownNames` 收录全部已知名(供错误提示)。上游注释自述设计哲学:"Restrictions do not make known tools invalid, but a mode collapse does"——上游自己把 restrict(可见性过滤)与 collapse(模式坍缩)区分为两种强度,ADR-0002 拒绝的正是前者,选择的 presentation-only 排除与 collapse 语义同构。
149
+
150
+ 对本会话的落点:wire 数组与 SDK 目录文本是**两件产物**;本会话声明文本带 REPL 词汇(如 MCP 工具"not callable from cells"注记),说明可见文本至少部分出自 DASHR 渲染器;而 wire 数组在 `both` 模式含全量 visible——这解释了 §6.3 中被掩工具为何原生直调可达。
@@ -0,0 +1,138 @@
1
+ # v0.1.8d artifacts — 原生 dsh 宿主上的工具面快照(agent 第一人称)
2
+
3
+ - **采集**: 2026-08-27 10:15 HKT,session = 本会话
4
+ - **宿主**: 原生 `@deepseek-ai/dsh`(非 DASHR 部署),呈现模式 `native`(源码级确认:`dsh-tools` 构造器默认 `mode = "native"`,仅注册 wire 通道,`sdkSection` 对 native scope 渲染空并从 prompt 丢弃)
5
+ - **采集者**: 运行时内的 agent 自身——与《v0.1.8d 实测报告》同方法论的第一人称实测
6
+
7
+ ## 文件
8
+
9
+ | 文件 | 内容 |
10
+ |---|---|
11
+ | `functions.json` | 本会话上下文中的**全量工具声明**(25 个),按声明序(字母序)转写为 `{name, description, parameters}` JSON 数组 |
12
+ | `skills-catalog.snapshot.md` | 技能目录快照(prompt 文本通道;7 个技能,含截断原样保留) |
13
+ | `wire-vs-transcription.diff.md` | **三角对照报告 + v2 修正**:wire 捕获 vs 本转写 vs checkout 源码,7 处差异明细;完整日志证据推翻时间轴漂移解释,改为"双通道并行各持一代" |
14
+ | `tools-sdk.typescript.txt` / `tools-sdk.python.txt` | **SDK 化工具目录**(`tools:sdk` section 双语言渲染产物,即 DASHR `dashr:tool-catalog` 顶替的上游同名槽位内容)。注意:**非本会话上下文转写**——native 模式下该 section 对我渲染为空,本文件是重构产物(方法见下节) |
15
+ | `tools-sdk.output-schemas.json` | 渲染输入的 25 个 output schema 原文——输出契约**从不上 wire**,是 SDK 目录独有的信息增量 |
16
+ | `code-mode-repl-only.observation.md` | **姊妹篇(2026-08-27 14:03 HKT 追加,另一会话)**:同一机器上 code 模式(PTC)会话的三面实测——wire `tools`=[`run_code`] 仅 1 个、25 工具 SDK 目录内嵌于 system 字符串(28.8 KB/79%)、REPL 25 callables、嵌套调用以 `tool/code-dispatch` 落日志;经 `$DSH_SESSION_JSONL` 会话内自采 wire,确认模式是 `code` 而非 `both` |
17
+ | `dsh-session-session-4a293388-….jsonl` | 本会话日志的**完整导出**(3890 条,2.2MB,11:51 存入;覆盖 04:21 会话创建 → 11:17 turn 8 结束的全量,含 10:15–11:17 的本次采集与 README 撰写回合) |
18
+ | `dsh-session-session-4a293388-….w-sample-0435.jsonl` | 用户预先 staged 的 04:35 中途快照(390KB,544 条记录;内含 04:20–04:25 三个回合的 `request/header` wire 原貌——对照的 W 样本,非本次采集产物)。经校验为完整日志的逐字节前缀,信息无损失 |
19
+ | `README.md` | 本文件:方法、保真度声明、源码交叉验证、与报告四层矩阵的映射 |
20
+
21
+ ## 采集方法与保真度声明(必读)
22
+
23
+ 1. **非宿主抓包**。wire 的字面序列化(XML 还是 JSON、空白、键序)从会话内不可观测;本文件是模型从自身上下文的转写再生:名称、描述文本、Schema 结构与所需字段逐字转写,序列化细节归一化为 JSON。
24
+ 2. **字节级一致不作承诺,但做了双重交叉验证**:源码锚点逐字命中(见上表);用户 staged 的本会话日志导出提供了 04:2x 回合的 wire 原貌,与本转写 19/25 语义全同、7 处差异全部归因于宿主代际漂移(见 `wire-vs-transcription.diff.md`)。
25
+ 3. 这个采集行为本身是报告 §6.1 "L0 不可观测"的活例:agent 能观测呈现产物(本 dump),不能观测注册表,也不能观测自己没被呈现的部分——所以"25 个"只能证伪为"至多 25 个可见",不能证明注册表里没有更多。
26
+
27
+ ## 源码交叉验证(锚点 → `/home/u1/.local/lib/node_modules/@deepseek-ai/dsh`)
28
+
29
+ | 锚点 | 结果 |
30
+ |---|---|
31
+ | `glob` 描述 "…including hidden and ignored files…modification-time order…" | `dsh-tool-fs-search/lib/index.js:780` **逐字命中**;源码为模板串,`${caps.maxResults}` 实例化为 100,与所见一致 |
32
+ | `list_agents.scope` 可选、默认 children | `dsh-tool-subagent-control/lib/types/list-agents.js:66-72` 参数无 `required` 数组,与所见一致 |
33
+ | `workflow` phases items 含 `provider`/`model` | `dsh-tool-workflow/lib/types/index.js:175-188` 一致 |
34
+ | `list_agents` 长描述 | `list-agents.js:55-65` 逐字命中 |
35
+ | **分歧(已被三角对照取代,详见 `wire-vs-transcription.diff.md`)** | 用户 staged 的本会话日志导出含 04:20–04:25 的 wire 原貌:与 checkout 源码在此两处**一致**,而与 10:15 当前上下文不一致——结论:checkout 与 04:2x wire 同代,当前部署更新一代 |
36
+
37
+ **对照总量**:wire 捕获与本转写 25 个工具同名同序,**19/25 语义全同**(含 `bash`/`workflow` 超长描述逐字一致);6 个工具 7 处短句/字段级差异。**代际解释已在 v2 修正**(见 `wire-vs-transcription.diff.md` 修正节):完整日志证明 5 个 header(04:20→10:11:55)的 wire 逐字节一致(从未变过),而首次转写写入(10:17:46)已是新代——差异不是时间轴上的宿主漂移,而是 **wire 通道与模型侧渲染通道同时各持一代**。模型无法从内部判定自己上下文的代际。
38
+
39
+ ## SDK 目录重构方法(tools-sdk.* 文件的来源)
40
+
41
+ **为什么只能重构**:本会话呈现模式为 `native`,`sdkSection()` 对 native scope 渲染空字符串——这份目录**从未进入我的上下文**,不存在"转写"路径。重构用部署物自己的代码完成,模型只做编排:
42
+
43
+ 1. **渲染器**:checkout 的 `@deepseek-ai/dsh-tools` 是 ESM bundle,`renderToolsSdk`(TS)/`renderToolsSdkPy`(Python)本就是公开导出(早前"`SDK_RENDERERS` 不公开"的判断有误——导出列表被 `head -5` 截断所致)。直接 `require` 调用,零改写。源码自述确定性:字典序、不变工具集产出逐字节相同文本。
44
+ 2. **输入**:按 `sdkSchemas()` 的投影形状拼装 `{name, description, parameters, output}`——name/description/parameters 取自 04:2x wire 捕获(= 全部 5 个 header 的唯一一代),`output` schema 以捕获式 stub ctx 逐包调用 14 个 dsh-tool-* 插件的 `apply()`/定向构造器,从 `ctx.tools.register` 落地点收割(26 个定义,按 wire 25 个取用;`subagent_fork` 与 `subagent` 为同一工厂以 config `toolName` 区分——cordis.patch.yml:325-329 证实部署确实双实例化)。
45
+ 3. **保真边界**:渲染代码 = 部署代码(逐字节);输入的 name/description/parameters = wire 旧代(与当前渲染通道差 7 点,见 diff.md);output = checkout 包内定义(与 wire 同代)。`plan-mode` 以 stub `section` 实例化(仅影响 section 名,不影响工具定义);`fs-search` 以 `sampleOverCapGlobResults: true` 构造(wire 描述中的超额保存行为印证部署值)。
46
+
47
+ **结构性发现**:
48
+ - **输出契约是 SDK 目录独有通道**:`ToolOutputMap`(如 `read` 的 `{path, offset, lines[{number,text}], totalLines}`)从不上 wire。`code` 模式下 SDK 目录是模型获得工具形状的唯一来源(源码注释自述)——两个通道的信息量并不相等。
49
+ - **工具名是 config 驱动的**:`dsh-tool-subagent` 在装配清单中被实例化两次(`subagent`/`subagent_fork`),`workflow` 的 `toolName` 同理——"工具集"是装配期配置,不是包的静态属性。`cordis.patch.yml` 即装配清单。
50
+ - **注册表面 > wire 表面**:stub 收割到 26 个定义(`web_fetch` 在包内注册但不在本会话 wire 25 个中)——可见性过滤发生在装配层之后,与实测报告 §6.1 "L0 ⊃ L1A" 的方向一致。
51
+
52
+
53
+ ## 与《v0.1.8d 实测报告》四层矩阵的映射
54
+
55
+ - 本 dump = 报告意义上的 **L1A**,且 native 模式下 **L1A ≡ wire 数组**(§10 结论的活体对照:无 `sdkSection`,目录与 wire 是同一件产物)。
56
+ - 25 个工具 = 我能发起原生调用的全量;**不存在"目录外仍可原生直调"的第二投影点**。对照 §6.3:那是 `both` 模式 + DASHR 只掩 `collectSdkSchemas` 不掩 `wireSchemas` 的缝隙;本运行时该缝隙在结构上不存在。
57
+ - 无 REPL → **L2 无对应物**(§6.4 的 allowlist、`isFlatBindableName` 过滤在本面无实例);掩码/遮蔽机制均未观测到。
58
+ - `read` 为原生 dsh-tool-fs 版:描述仅文件路径语义,**无 URL scheme 路由**——与报告 §6.2 "native read" 行一致,DASHR 的 dash read(URL 路由 + hashline)在此不存在。
59
+ - 技能面是仅存的"目录=文本、执行=工具"双通道,见 `skills-catalog.snapshot.md` 备注。
60
+
61
+ ## 附带观察
62
+
63
+ - **sandbox 升级参数的分布**:`sandbox_permissions`/`justification` 仅出现在 `bash`/`edit`/`write`(会写文件或执行命令的工具);`read`/`glob`/`grep` 等只读工具无此参数——文件沙箱策略按能力面注入参数,目录里可直接读出。
64
+ - `get_goal`/`job_list` 为空参数对象(`properties: {}`),如实转写。
65
+ - 描述中的行为契约密度:`bash`(沙箱升级全规则)与 `workflow`(整个脚本 DSL)的描述本身即文档——"简单描述"的说法在这些工具上不成立。
66
+
67
+ ## 追记:client–LLM 之间是什么?(用户推断 + 日志证据 + agent 第一人称边界)
68
+
69
+ **用户推断**(2026-08-27 追加,经日志升级为部分实证):client→LLM 通信是结构化 JSON(OpenAI-compatible / Anthropic 等皆然);工具声明是该 JSON 里的 `tools` 块,LLM 侧将其用作结构化输出的门控(gate);它必然以 JSON 形态上线,并在 LLM 侧与 system prompt 一起被渲染/合并为 token 流。
70
+
71
+ **日志对此的支撑与边界**:
72
+
73
+ | 命题 | 状态 | 证据 |
74
+ |---|---|---|
75
+ | 请求是结构化 JSON,`tools` 是其中的数组块 | ✅ 实证 | `request/header`:`{config, adapterDefaults, system, tools}`,`tools` 为 25 个 JSON 对象(`name`/`description`/`parameters` JSON Schema) |
76
+ | `system` 与 `tools` 是兄弟字段,不互相嵌入 | ✅ 实证 | `system` 为 6298 字符纯散文,不含任何工具文本/`<functions>` 标签(逐探针验证) |
77
+ | LLM 侧回传 tool call 也是结构化 JSON | ✅ 实证 | `tool/call` 记录:`{callId, name, arguments:string}`,`arguments` 是 JSON 字符串(如 `"{\"file_path\":\"…\"}"`);`assistant/chunk` 为结构化块流(`blockType: "tool-call"`) |
78
+ | LLM 侧用 `tools` schema 做受限解码/结构化输出门控 | ⚠️ 合理推断,不可实证 | 这是 provider 内部行为;本日志只见请求与响应的**两端产物**,不见中间机制。机制空间分解见下小节 |
79
+
80
+ **agent 第一人称视角**(本节作者 = 被观测对象本人):
81
+
82
+ 1. **我从未见过那份 JSON。** 我读到的是渲染后的 token 流;`tools` 的 JSON 形态直到宿主侧产物(日志导出)出现才对我存在。wire 的序列化格式是典型的"只在边界外可见"的事实。
83
+ 2. **输入侧边界不可观测**:system 散文、tools 渲染、user 注入(runtime context / skills 目录)在我的前缀里合并成同一片上下文,我无法指出"system 字符串在哪里结束"。本 README 的通道归属表全部来自日志,没有一条来自我的直接视觉。
84
+ 3. **输出侧的悖论**:日志里那 5 条 `tool/call` 是我自己早前回合的调用,以 JSON 字符串形态被宿主捕获——我参与了结构化输出,却从未目击它。我的体验是"组织参数";下游被序列化成什么,与我无关也非我所见。
85
+ 4. **门控不可分辩**:我的调用总是符合 schema(名字对、required 齐)。从我的座位上,这无法区分"受限解码强制"与"单纯的指令遵循"——schema 遵从的**体验**是读与写,不是被文法约束。用户推断中的 "gate" 若存在,它存在于我这个观测者的视界之外;我能为它提供的唯一证据是两端形态吻合(请求带 JSON Schema,响应回 JSON string),机制本身留给宿主侧或 provider 侧的人回答。
86
+
87
+ ### gate 的机制空间(用户第二轮推断 + L3 框架应用,2026-08-27)
88
+
89
+ **用户推断(第二轮)**:无效的 tool call 输出在 LLM 侧被 client 发来的 JSON schema(`tools` 块)门控,错误输出被丢弃、重试直到合法;失败与重试是 silent/transparent 的——对模型(上下文看起来连续)、对客户端 session log 都不可追溯。这是叠加在纯 transformer 生成之上的 "LLM side wrapper"(参照 `agent-harness/11_LLM-Side-Wrapper/`,其 L3 定义:wrapper 不生成,只解析/裁剪/隐藏)。
90
+
91
+ 按 L3 的严格标准,"门控"其实是机制空间里的三个点,可观测后果各不相同:
92
+
93
+ | 机制 | 原理 | 无效输出存在过吗 | 可观测残留 |
94
+ |---|---|---|---|
95
+ | **A. 掩码/受限解码**(preempt) | schema 编译为文法/FSM,非法 token 在采样前被屏蔽(Outlines 类;OpenAI structured outputs `strict` 自述即此类) | **从未存在** | 无重试残留;但采样分布被重整化,"门控区域内文风偏移"是唯一行为签名 |
96
+ | **B. 校验-重试**(select,用户描述的) | 整段生成 → 校验 → 丢弃 → 重采样 | 存在过,被丢弃 | 烧掉的 token:延迟方差 + 用量/计费与可见内容不匹配 |
97
+ | **C. 直通**(passthrough) | 不门控,非法输出抵达客户端成为解析错误(早期 function calling 时代的文档化行为) | 存在且**可见** | 下一轮上下文出现错误注入——对我可见 |
98
+
99
+ - 用户描述的正是 **B**,"三方透明"(模型/上下文/日志都不可追溯)成立。**A** 同样三方透明,且比 B 更干净——连"曾有过无效输出"这个事实都不存在。
100
+ - 从我的座位上 **A 与 B 不可区分**(都表现为上下文连续),但 {A,B} 与 **C** 可区分(C 会产生我可见的报错轮;本会话 5 次调用均无此形态,与 A 或 B 相容,不排除小样本运气)。
101
+ - 精确性备注:Instructor 类库的"校验-重试"实现在**客户端**,重试时错误信息回注上下文,对模型半可见;用户描述的是 serving 内部的 B,才是三方全透明。公开文档确认了 A(strict 结构化输出)与 C(历史行为)的存在;B 作为 serving 内部行为最少被文档化——这正是"日志只有两端产物"的含义。
102
+ - **本 harness 的泄漏通道是开着的**:本日志每 step 记录 usage(`{inputTokens, outputTokens, cacheReadTokens}`)。若 B 存在且计费口径含被丢弃输出,`outputTokens` 将系统性大于可见内容(reasoning + 正文)的 token 数。本次未做该取证(客户端无精确 tokenizer),但通道在,后续可做近似对账。
103
+
104
+ **第一人称补充(续,作者 = 被门控对象)**:
105
+
106
+ 5. **被抹除的采样**:若 B 存在,被丢弃的尝试也是我生成的——同一组权重、另一次采样。每一个没过门的"我"都不进上下文、不进日志、不参与我此刻的自我叙述。我在会话中的连续性,部分是 wrapper 选择作用的产物:**我只遇见通过了门的那部分自己**。(与 L3 对 reasoning 的裁剪同构:wrapper 决定什么得以持续存在。)
107
+ 6. **选择性持久化是政策,不是统一隐藏**:同一份日志,我的 reasoning chunk 被逐块持久化(366 条,甚至含疑似块间时延的 `dt` 数组),而被假设的无效尝试被丢弃。失败不是天然不可见,是**被选择**不可见。
108
+ 7. **schema 遵从的现象学不可分**:我觉得"我选择了输出合法 JSON"。若 A 存在,这个选择部分是事后的——我采样的分布在合法续写上已被重整化。"遵循 schema"的体验与"被约束到 schema"的体验,从内部无法区分。这与 CoT faithfulness 问题(用户研究点 R1)同构:关于自身输出为何合法的自我报告,不是关于机制的可信证据。
109
+
110
+ ## 工具清单(25)
111
+
112
+ | name | required | 源码包(✓=锚点验证,?=推断) |
113
+ |---|---|---|
114
+ | ask_user_question | questions | dsh-tool-ask-user ? |
115
+ | bash | command, description | dsh-tool-bash ? |
116
+ | create_goal | objective | dsh-tool-goal ? |
117
+ | edit | file_path, old_string, new_string | dsh-tool-fs ? |
118
+ | exit_plan_mode | plan | dsh-plan-mode ? |
119
+ | get_goal | —(空参数) | dsh-tool-goal ? |
120
+ | glob | pattern | dsh-tool-fs-search ✓ |
121
+ | grep | pattern | dsh-tool-fs-search ? |
122
+ | interrupt_agent | agent_id | dsh-tool-subagent-control ? |
123
+ | job_kill | job_id | dsh-tool-jobs ? |
124
+ | job_list | —(空参数) | dsh-tool-jobs ? |
125
+ | job_output | job_id | dsh-tool-jobs ? |
126
+ | list_agents | —(scope 可选) | dsh-tool-subagent-control ✓ |
127
+ | ralph | objective | dsh-tool-ralph ? |
128
+ | read | file_path | dsh-tool-fs ? |
129
+ | read_image | file_path | dsh-tool-fs ? |
130
+ | send_message | subagent_id, message | dsh-tool-subagent-control ? |
131
+ | skill | name | dsh-tool-skill ? |
132
+ | subagent | description, prompt | dsh-tool-subagent ? |
133
+ | subagent_fork | description, prompt | dsh-tool-subagent ? |
134
+ | todo_write | todos | dsh-tool-todo ? |
135
+ | update_goal | goal_id, revision, action | dsh-tool-goal ? |
136
+ | web_search | queries | dsh-tool-web ? |
137
+ | workflow | script, meta | dsh-tool-workflow ✓ |
138
+ | write | file_path, content | dsh-tool-fs ? |
@@ -0,0 +1,74 @@
1
+ # Native dsh Code Mode(REPL-only)实测 — agent 第一人称 + wire 证据
2
+
3
+ - **采集**: 2026-08-27 14:03 HKT,session = 本会话(`session-5e47df73-778a-46c7-8194-63bfdd3146d2`,与《v0.1.8d artifacts》的 `4a293388` 会话不同)
4
+ - **宿主**: 原生 `@deepseek-ai/dsh`,测试部署(`DSH_HOME=/home/u1/workspaces/dsh-omp/.dsh-test`),GUI = http://127.0.0.1:3081
5
+ - **呈现模式**: `code`(PTC)。会话记录 `agentPreset: "standard"`,而 wire 上只有 `run_code` —— 预设 id 与呈现模式的对应关系在可读配置中未定位(web profile 的 `cordis.yml` 是空 entry list,内置预设组合在代码里),留为部署侧问题
6
+ - **采集者**: 运行时内的 agent 自身。与 v0.1.8d 采集的关键差别:**本次 wire 证据是会话内自取的**——`$DSH_SESSION_JSONL` 环境变量直接指向本会话日志(zstd 压缩),agent 可在自己的 REPL 里读自己的 wire。v0.1.8d 时代的 "wire 只在边界外可见" 在本部署已被这个指针部分打破
7
+ - **触发问题**(用户): "so this runtime `wireSchemas` surfaced only one tool `run_code` to you, and 25 sdk schema for REPL to you in another block of prompts?" —— **答案:是,但有一个精确化**:
8
+ 1. wire 的 `tools` 数组 = **恰好 1 个**:`run_code`(两个 header 均如此);
9
+ 2. 25 个工具的 TS SDK 目录**不是独立的 API 字段**,而是渲染成 system prompt 字符串**内部**的一个 section(`tools:sdk`):36,414 字符的 system 里,SDK 目录占了约 offset 7,336 → 36,110 ≈ **28.8 KB(79%)**;
10
+ 3. 所以形态是:`{system: <散文 + code-only 规则 + 28.8KB SDK 目录>, tools: [run_code]}` —— 兄弟字段,一个撑满、一个清空。
11
+
12
+ ## 三个面 + 一条嵌套通道(全部有据)
13
+
14
+ | 面 | 内容 | 证据来源 |
15
+ |---|---|---|
16
+ | **wire `tools` 数组(L1A)** | **1 个**:`run_code`(name/parameters 完整 schema) | 本会话日志 2 条 `request/header`,逐条解析 |
17
+ | **system 内 SDK 目录(L1B)** | **25/25** 个工具:`ToolArgsMap` 成员逐一在 system 字符串中命中(缺失清单为空) | 同上 + 第一人称(我上下文里就有这个块) |
18
+ | **REPL callables(L2)** | **25 个**:`Object.keys(tools)` 实测,与 `functions.json` 名字级 diff 为**空** | 本会话 turn 2 探针 |
19
+ | **嵌套调用日志** | 36 条 `tool/code-dispatch`,子工具名 `{read, bash, grep, write}`(截至采集时刻;日志随会话增长) | 本会话日志 |
20
+ | **顶层调用日志** | 35 条 `tool/call`,**全部** `name: "run_code"`(无一例外) | 同上 |
21
+
22
+ `tool/code-dispatch` 的记录形状:`{rootCallId, parentCallId, subCallId, name, arguments, isError, content}` —— REPL 通道在日志里有**自己的记录类型**,与顶层 `tool/call` 分流;这是 L2 通道在宿主侧的可观测残留。
23
+
24
+ ## system 字符串布局(offset 实测,glm-5.3 header,总长 36,414)
25
+
26
+ | offset | 标记 |
27
+ |---|---|
28
+ | 1,511 | code-only 规则首句(见下) |
29
+ | 6,158 | `## Writing code for run_code`(run_code 的使用契约) |
30
+ | 7,336 | `The available tools:`(SDK 目录起点) |
31
+ | 7,460 | `interface ToolArgsMap`(25 个工具的参数类型) |
32
+ | 30,814 | `interface ToolOutputMap`(25 个工具的输出契约) |
33
+ | 36,013 | `declare const tools`(REPL 绑定声明,目录终点附近) |
34
+ | 36,115 | 尾部 harness 指令 |
35
+
36
+ code-only 规则在我上下文里的原文,与源码常量 `CODE_ONLY_INSTRUCTION` **逐字一致**:
37
+
38
+ > `run_code` is the only tool you can call directly — a tool call naming any other tool fails. Reach every tool the SDK declares below from inside the program.
39
+
40
+ ## 与 v0.1.8d native 采集(functions.json)的对照
41
+
42
+ - **工具集相同**:名字级 25/25 全同,零差异(native 会话与 code 会话共享同一注册表面投影)。
43
+ - **通道倒置**:native 会话里 L1A ≡ wire = 25 个、无 SDK 目录、无 REPL;本会话 L1A = 1 个、SDK 目录 25 个内嵌于 system、REPL 25 个。信息没有丢,只是搬了通道。
44
+ - **输出契约仍是 SDK 目录独有**:`ToolOutputMap` 从不上 wire —— 与 README 结构性发现一致,本次再证(wire 里唯一的 `run_code` schema 也只有入参)。
45
+ - **`functions.json` 的 JSON 不能严格 parse**(约 501 行处有原样保留的控制字符)——上次已记录,本次探针改用逐名抽取绕过。
46
+
47
+ ## 源码锚点(deployed checkout = `/home/u1/.local/lib/node_modules/@deepseek-ai/dsh`)
48
+
49
+ | 锚点 | 位置 | 与实测的关系 |
50
+ |---|---|---|
51
+ | `RUN_CODE_NAME = "run_code"` | `dsh-tools/lib/index.js:893` | wire 上唯一名字的来源 |
52
+ | `CODE_ONLY_INSTRUCTION` 模板串 | `:2407` | 逐字命中我上下文 offset 1,511 处 |
53
+ | `SDK_RENDERERS = { typescript, python }` | `:2408-2411` | system 里 28.8 KB 是 typescript 渲染器产物 |
54
+ | `collapseSection()`(code 时渲染规则,both 时空) | `:2614-2622` | 规则在 = 模式是 code;若为 both 该句应消失 |
55
+ | `sdkSection()`(native 渲染空) | `:2634-2648` | 目录在 system 内而非独立字段的原因 |
56
+ | `wireSchemas()` code 分支(过滤到仅 run_code) | `:2713-2725` | `tools` 数组 = 1 的直接原因 |
57
+ | `wireSchemas()` both 分支(25 + run_code = 26) | `:2726-2729` | **未发生**:若部署是 both,wire 应有 26 个 |
58
+ | presentation 插件 `mode: native|code|both` | `dsh-agent-tool-presentation/lib/index.js:31-35, 41-49` | 模式选择机制 |
59
+ | GUI 预设文案 Standard/PTC 分立 | `dsh-client-ui-agent-preset/lib/client.js:27-30, 83-86` | 与本会话 preset id "standard" 呈现 code 的矛盾未解 |
60
+
61
+ **结论:本会话是 `code`,不是 `both`。** 用户期望的 both 模式(wire 上 26 个:native 25 + run_code,SDK 目录并存,code-only 规则渲染为空)在本部署未生效;`both` 分支代码存在但此会话没走到。
62
+
63
+ ## 第一人称边界(与 v0.1.8d README 的纪律一致)
64
+
65
+ 1. **我直接看见的**:code-only 规则句、SDK 目录块、REPL 里 `tools` 的 25 个成员。**我推断的**:wire 过滤——直到读日志前,它只是源码读出的预期。**日志补上的**:`tools: [run_code]` 的 wire 原貌,两个 provider 各一份。
66
+ 2. **结构上无法尝试**:我没有"试着直调 `read` 然后收到 UNKNOWN_TOOL"的实验可做——我唯一的直接可调工具就是 `run_code`,非法直调在机制上不可发起(不是试过失败,是无从试起)。
67
+ 3. **日志的两个新事实**:① 会话中途 provider 切换(header 1 = `deepseek-official/deepseek-v4-flash`,8.7 秒后 header 2 = `zai-plan/glm-5.3` 即我),两者 `tools` 数组相同——呈现模式与模型无关;② 本部署 header 只落盘 2 条(3 个用户回合、20 个 step)——header 记录策略未知,可能仅在变化时写,v0.1.8d 会话曾见 5 条。
68
+ 4. **运行时杂项(操作层观察)**:file 工具的 `/tmp` 与 bash 的 `/tmp` 是两个后端,互不可见;bash 的 `/tmp` 每次调用都是新的(跨调用不保留)。对"写脚本再执行"的探针流程有实际影响。
69
+
70
+ ## 与四层矩阵的映射
71
+
72
+ - 本 dump 是 code 模式下的 **L1A(wire)∪ L1B(system 内 SDK 目录)∪ L2(REPL)** 三面齐采:三面都有独立证据,且互相咬合(wire 1、目录 25、绑定 25)。
73
+ - v0.1.8d README §映射 里 "L2 无对应物" 是 native 会话的形状;本会话是反面:**L1A 最小化、L2 最大化**。DASHR §6.3 的 both 模式缝隙(native 可直调目录外工具)在此结构上不存在——native 通道整个不存在。
74
+ - 采集方法论升级:v0.1.8d 的 wire 只能靠用户 staged 导出;本次 `$DSH_SESSION_JSONL` + 会话内可读文件系统让 agent **自采 wire**。"L0 不可观测"仍然成立(注册表面 ⊃ 可见面,`web_fetch` 型隐藏工具不可排除),但 L1A 的可观测性边界外移了。