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,224 @@
1
+ # DASHR surface-and-devices v0.1.8e 第一人称实测报告
2
+
3
+ - **日期**: 2026-08-28
4
+ - **测试者**: Dash Agent 运行时自身(pc-deepseek-default,session `session-c526cef2-c056-4b58-a15d-fb44edc9548a`)
5
+ - **被测对象**: 部署在本运行时上的 `@pgmi-builds/dashr` `0.1.8-e`(git HEAD `0f9e84e` "v0.1.8e: wire masking, auto REPL bindings, dvc devices",profile `web`,lib 构建于 08-28 00:11)
6
+ - **被测改动**: `openspec/changes/surface-and-devices/`(design.md D1–D8:注册表掩码 / REPL 自动映射 / 目录改名 / roster family tree / RAM 物化 / dvc 设备)
7
+ - **方法**: 全部通过被测运行时自身的工具面(`read`/`write`/`grep`/`glob` 直调 + `eval` 内 `tool.*` 调用)发起,无旁路。第一人称——我自己就是被 deny 掩码作用的那张模型表面。
8
+ - **会话环境**: cwd `/home/u1/workspaces/dashr`,preset `standard`,delegationDepth 0,sandbox `workspace-write`,approval `ask`;`/dev/shm` = tmpfs 6.6G。
9
+
10
+ ## 结论
11
+
12
+ **v0.1.8e 已真实生效,且修复了 v0.1.8d 的核心结构矛盾。** 上一轮(v0.1.8d §6.3)的结论是「目录掩码 presentation-only,被掩的 `skill` 在 `both` 模式下模型直调照样执行」;本轮 D1 改用 registry 级 `restrict({deny})`,把掩码从「摘广告」升级为「摘通路」——**被掩名对 LLM 全链路消失**(wire 直调面 + 目录 + REPL 绑定 + 按名 dispatch 五面一致)。这条链在本会话每一格都实证成立。
13
+
14
+ 8 项决策的落地结果:**D1/D2/D3/D4/D6/D7 全过,D5 部分达成,D8 三设备两通一断**。另发现 **3 处设计文档/实现漂移** 和 **1 处部署缺陷**(browser 设备缺 `@puppeteer/browsers` 依赖,运行时拉不起来)。
15
+
16
+ ## 1. 部署状态
17
+
18
+ | 检查项 | 结果 |
19
+ |---|---|
20
+ | 安装版本 | `0.1.8-e` ✓ |
21
+ | git HEAD | `0f9e84e`(wire masking + auto REPL + dvc devices)✓ |
22
+ | 运行 profile | `web`(`/home/u1/.dsh/profiles/web/node_modules/@pgmi-builds/dashr`)✓ |
23
+ | `/dev/shm` | tmpfs 6.6G,可写 ✓ |
24
+ | 系统 Chrome | `/usr/bin/google-chrome-stable` 存在 ✓ |
25
+
26
+ ## 2. D1 注册表掩码(核心,全过)
27
+
28
+ deny 名单 9 名:`skill` / `send_message`(上游)/ `report` / `list_agents` / `subagent` / `subagent_fork` / `interrupt_agent` / `workflow` / `ralph`。
29
+
30
+ **2.1 REPL 绑定面(硬门)**:8 个非桥名全部 `ToolCallError: unknown binding "tool.<name>"`:
31
+
32
+ ```
33
+ skill / report / list_agents / subagent / subagent_fork /
34
+ interrupt_agent / workflow / ralph
35
+ → ToolCallError: unknown binding "tool.<name>"
36
+ ```
37
+
38
+ **2.2 wire 直调面**:我的直调函数集(22 个平坦名 + `eval` + 5 个 MCP 名)中,上述 9 名**一个都不在**。与 v0.1.8d 对照——上一轮 `skill` 还在 wire 上、模型直调可达(L1B 放行);本轮 `skill` 从 wire 消失。这是本次改动对 v0.1.8d 结构矛盾的正向修复,直接实证。
39
+
40
+ **2.3 能力保留靠桥,不靠 registry 豁免**:`read skill://grilling` 正常返回技能正文(skill 能力经 URL 桥保留);own 层 wrapper(`read`/`write`/`grep`/`glob`)全程不受 deny 影响(§6/§7 的每一步都靠它们完成)。
41
+
42
+ ## 3. D2/D3 桥 + REPL 自动映射(全过,含 1 处命名漂移)
43
+
44
+ **3.1 `send_message` 桥(单向实测全过)**:桥以 `send_message` 为名,`receiver: 'child' | 'parent'`:
45
+
46
+ - `receiver='parent'`(root 无父)→ 结构化 `{error: '...only a live continuable child agent can report to its parent (a root agent has none) — agent "session-…" is no…'}`(服务层 `authorizeReporter` 的 UNAUTHORIZED 被桥如实转译,不崩溃)。
47
+ - `receiver='child'` 缺 `subagent_id` → 结构化 `{error: 'send_message() receiver "child" requires {"subagent_id": "..."}'}`。
48
+ - `receiver='sideways'` → 结构化 `{error: 'unknown receiver "sideways"'}`。
49
+
50
+ **3.2 REPL 绑定单态自动映射**:绑定集 = restrict **之后** `registry.schemas(agent)` 的平坦可见名全集。实测 22 名(与 wire 平坦名一一对应,无名单、无二态):
51
+
52
+ ```
53
+ memory_search, memory_add, memory_list, memory_flush, bash, glob, grep,
54
+ job_output, job_list, job_kill, ask_user_question, web_search, read, write,
55
+ edit, read_image, todo_write, get_goal, create_goal, update_goal,
56
+ exit_plan_mode, send_message
57
+ ```
58
+
59
+ 被掩名随投影消失自然不绑(§2.1);MCP 非平坦名 `mcp__cordis-a2a__*` → `unknown binding`(如实跳过)。
60
+
61
+ **3.3 命名漂移(design vs 实现)**:design D1/D2 与 proposal 都把桥命名为 **`agent_message`**;实现与部署的桥名是 **`send_message`**(复用上游同名,`receiver` 参数区分方向)。功能语义与设计一致(child 下行/parent 上行、root 无父结构化拒绝),但**桥名与文档不符**——要么改名实现,要么回写文档。
62
+
63
+ ## 4. D4 目录段 = REPL bridge instructions(全过)
64
+
65
+ 部署形态 = **选项 B(signatures)**:`REPL_BRIDGE_CATALOG_MODE = 'signatures'`。我看到的目录段就是「`tool.<name>(args: {…}) -> <output>` 每工具一行」的 omp 式紧凑签名,保留输出契约,无逐工具参数 interface 块,无 REPL 可调清单。
66
+
67
+ ## 5. D5 run_code = REPL scripting pad(部分达成,含 "kernel" 泄漏)
68
+
69
+ - `eval` 工具描述:"Execute one Python cell on a session-persistent **scripting pad**…" ✓ 无 kernel。
70
+ - 桥说明段(目录):"session-persistent **scripting pad** (Python today…)" ✓ 无 kernel。
71
+ - **但 `dashr:control-prompt` 段(order 100)仍 3 次使用 "kernel"**,且逐字渲染给我:
72
+
73
+ ```
74
+ "one `eval` call runs one Python program on a persistent IPython kernel"
75
+ "everything else stays in the kernel"
76
+ "they live in the kernel subprocess: keep durable state in files"
77
+ ```
78
+
79
+ 设计 D5 的原话是「LLM 可见文案**不用 kernel 一词**」。目录段做到了,`control-prompt.md`(另一个 LLM 可见段)没做到。另:旧渲染器 `renderToolsSdkPy`/`SDK_INSTRUCTIONS` 在 `py-sdk.ts` 里仍满篇 "kernel",但它是**死代码**(index.ts 只 import `renderReplBridgeInstructions`),不达模型,风险为零。
80
+
81
+ ## 6. D6 agent:// = caller 的 family tree(全过)
82
+
83
+ | 探测 | 结果 |
84
+ |---|---|
85
+ | `agent://`(裸名册)| `no agents`(本会话无子,空名册,与 native 同型)|
86
+ | `agent://<self>` | 我的最后一条非空 assistant 输出 ✓ |
87
+ | `agent://<self>/transcript` | 逐条 role-headed(`## user`/`## assistant`…)✓ |
88
+ | `agent://<陌生 id>` | `unknown agent "…" — addressing is scoped to your family tree (self and descendants)`(family 收窄,非全局超集)|
89
+ | `agent://<self>/<bogus-child>` | `unknown child agent "…" of "…"` |
90
+
91
+ v0.1.8d 的「五列全局 roster」已移除;错误措辞明说 family 边界——与 design D6 一致。
92
+
93
+ ## 7. D7 RAM 物化 = /dev/shm(全过,路径直接实证)
94
+
95
+ content-backed 搜索的物化根目录从 `/tmp` 切到 `/dev/shm`,并 `finally` 清理。**grep 返回的真实路径直接落在 tmpfs**:
96
+
97
+ ```
98
+ grep ctx://model → 匹配路径 /dev/shm/dashr-url-ZILDQp/content.txt
99
+ grep agent:// → 匹配路径 /dev/shm/dashr-url-5w99JR/content.txt
100
+ ```
101
+
102
+ 调用后 `/dev/shm` 与 `/tmp` 均无 `dashr-url-*` 残留(清理零泄漏)。这是全链路里最硬的实证——不是读源码推断,而是 ripgrep 自己回吐了 `/dev/shm/` 前缀路径。
103
+
104
+ ## 8. D8 dvc 设备(三设备两通一断)
105
+
106
+ **8.1 名册**:裸 `dvc://` 返回 4 设备(不再是 `no devices mounted` 占位):
107
+
108
+ ```
109
+ ast_edit AST-aware structural rewrite: {ops: [{pat, out}], paths: string[], dryRun?: boolean}
110
+ ast_grep AST pattern search: {patterns: string[], path?, offset?, limit?, includeMeta?}
111
+ browser headless Chrome via puppeteer-core — open {url} / run {code|goto,type,click} / close
112
+ lsp LSP queries over stdio language servers — diagnostics / definition / references / hover
113
+ ```
114
+
115
+ `dvc://<device>` 返回一行摘要 + `usage: write dvc://<device> …`;`dvc://nonexistent` → `unknown device: …`。
116
+
117
+ **8.2 ast_edit / ast_grep(通)**:`@oh-my-pi/pi-natives` npm 包装的直 dlopen 在本机 linux-x64 成功。
118
+
119
+ - `write dvc://ast_grep {"patterns":["add($A,$B)"],"path":…}` → 结构化 matches(命中 `add(1, 2)` @ line 4,带 byteStart/startLine/startColumn)。
120
+ - `write dvc://ast_edit {ops:[{pat,out}], paths:[…]}`(dryRun 默认 true)→ 结构化 changes 预览,`applied: false`,文件内容原样未动。
121
+
122
+ **8.3 lsp(优雅降级,符合预期)**:`diagnostics` 请求 → 结构化 `language server binary "typescript-language-server" not found — npm install -g …`。二进制缺失时如实报缺、不崩溃,符合 D8 spec。
123
+
124
+ **8.4 browser(断,部署缺陷)**:`open` → 结构化 `dvc:// device "browser" execute failed: puppeteer-core is not installed … Cannot find package '@puppeteer/browsers' imported from …/puppeteer-core/lib/puppeteer/node/ChromeLauncher.js`。定位:**`puppeteer-core@25.3.0` 已装,但其传递依赖 `@puppeteer/browsers@3.0.6` 缺失**(profile `web` 的 node_modules 顶层与嵌套均无)。系统 Chrome 在,`run`/`close` 的「无页可跑/无可关」状态机也正确——**唯一断点是依赖未装全**,与 omp patch 无关(design S6 已裁决无 patch 可冒烟)。属部署收尾遗漏,非代码缺陷。
125
+
126
+ ## 9. 与设计文档的偏差汇总
127
+
128
+ 1. **桥名漂移(D1/D2/proposal)**:文档 `agent_message` vs 实现 `send_message`。语义一致,名称不符。
129
+ 2. **D5 "不用 kernel" 未全达成**:`control-prompt.md` 3 处 "kernel" 逐字渲染给模型;`renderToolsSdkPy` 旧渲染器仍含 "kernel"(但为死代码,不达模型)。
130
+ 3. **D3 "`dir(tool)` 自查" 承诺落空**:桥说明段写「read the live member set at run time with `dir(tool)`」,但 `dir(tool)` 返回**空**(惰性 `__getattr__` holder 无 `__dir__` 覆写,`hasattr` 对任意名恒真)。真实绑定集只能靠未文档化的内部 `__dashr_injected__`(bootstrap 写入的 spec,`functions` 为 22 名列表)或 wire/目录声明得知。要么给 holder 加 `__dir__`,要么改说明措辞。
131
+ 4. **host 静态 prose 与掩码面残留不一致**:host 基础提示里仍有「Use the workflow tool ONLY when…」「Use the ralph tool ONLY when…」等措辞,而 `workflow`/`ralph`/`subagent` 已被 deny 掩码从可调面摘除。这是 registry 掩码无法触达的宿主静态文案(design Risks 的「restrict 名单漂移」同源),非 DASHR 缺陷,但模型会读到「用某工具」却调不到它。
132
+
133
+ ## 10. 建议
134
+
135
+ 1. **browser 收尾**:在 profile 安装 `@puppeteer/browsers@3.0.6`(或让 puppeteer-core 走完整 `npm install`),重新冒烟 `open`/`run`/`close`;否则 D8 的 browser 设备形同虚设。
136
+ 2. **桥名二选一**:把实现桥名改成 `agent_message`,或回写 design/proposal 的 D1/D2 为 `send_message`。当前文档与部署名不一致,会让后续 reader 误解。
137
+ 3. **D5 收尾**:`control-prompt.md` 的 3 处 "kernel" 改成 "scripting pad"(或 "pad"),并顺手清理 `renderToolsSdkPy` 死代码里的 "kernel" 措辞,避免误当仍在用。
138
+ 4. **D3 收尾**:给 `_DashrBindingHolder` 实现 `__dir__`(返回 `functions` 键集),或把桥说明里的 `dir(tool)` 提示改为「绑定集见上方 Tool declarations / wire 声明」。
139
+ 5. 无需回滚。本轮无阻断性缺陷;deny 掩码是 v0.1.8d 结构矛盾的正确解法,已实证生效。
140
+
141
+ ## 11. v0.1.8f 复测补记(2026-08-28 01:50,commit `3fdd3dd`)
142
+
143
+ 本报告提交后,上游随即发布 v0.1.8f("delegation bridges close the spawn/interrupt/workflow gap"),逐条回应 §9/§10 的发现。同一会话复测(kernel 已重启,pad 全新):
144
+
145
+ **已修复(4 项)**
146
+
147
+ 1. **桥名漂移 → 修复**:桥由 `send_message` 改名 **`agent_message`**,与 design D1/D2 命名一致。实测 `tool.send_message` 现为 `unknown binding`(旧名彻底退场),9 个被掩名的掩码在改名下原样保持。
148
+ 2. **D5 "kernel" 泄漏 → 修复**:`control-prompt.md` 重写,3 处 "kernel" 全部替换(`persistent IPython kernel` → `session-persistent scripting pad`;`stays in the kernel` → `stays in the scripting pad`;`kernel subprocess` → `the pad's process`)。工作区与 profile 两份 md5 一致(`6ec2ec0…`),"kernel" 零残留,重启后已实际渲染。
149
+ 3. **`dir(tool)` 承诺 → 撤回**:桥说明中「read the live member set at run time with `dir(tool)`」一句已删除(py-sdk −4 行),不再承诺 holder 从未兑现的自查机制。
150
+ 4. **delegation 断面 → 补桥**:新增 `src/bridges/index.ts`(490 行),三个平坦名桥关闭 v0.1.8e 掩码后 spawn/interrupt/workflow 无模型入口的能力回归:
151
+ - `agent` → `ctx.subagents.start/startContinuable`(spawn / fork,`run_in_background` 可选);
152
+ - `agent_message` → followup/reportFrom/**interrupt**(三向:child 下行 / parent 上行 / **interrupt 停子代理当前轮**,`target_session_id`——interrupt 是新增能力,补上被掩 `interrupt_agent` 的缺);
153
+ - `agent_workflow` → `ctx.workflowEngine.start`(script / ralph rfc 两模式)。
154
+
155
+ 实测绑定集 22 → **24**(三桥进入,`send_message` 退出):`agent` 空参 → 结构化缺 `description`;`agent_message` parent 上行(root)→ 结构化 UNAUTHORIZED;interrupt 缺 `target_session_id` → 结构化报错;未知 receiver → 三向枚举报错。桥为 REPL 绑定 + 目录声明(插件内仅 `eval` 走 `tools.register`),delegation 经 cell 内 `tool.agent(...)` 触达。
156
+
157
+ **仍未解决(2 项)**
158
+
159
+ - **browser 设备仍断**:`@puppeteer/browsers` 传递依赖在 profile `web` 仍缺失,`open` 报错与 §8.4 逐字相同。
160
+ - **agent_workflow 有桥无服务**:桥已绑且可达,但本组合返回结构化 `agent_workflow() is unavailable: no ctx.workflowEngine service is mounted in this composition`——workflow 能力在**服务层**仍缺席,该缺口只在桥层关闭,此部署里实际不可用。
161
+
162
+ **复测不变项(继续成立)**:9 被掩名全链路消失;`dvc://` 名册 4 设备;/dev/shm 物化(新证:`/dev/shm/dashr-url-EZlvAV/content.txt`);`read skill://` 桥保留。
163
+
164
+ ### 第二轮复测(2026-08-28 02:10,commit `2ba147b` + 依赖补装)
165
+
166
+ `2ba147b`(纯改名:`rlm-runtime.ts`→`repl-runtime.ts`、`rlm.spec.ts`→`delegation.spec.ts`,去 RLM 品牌,无功能变更)后 profile 补装 `@puppeteer/browsers@3.0.6`,lib 02:04 重建并重启。复测结果:
167
+
168
+ - **browser 设备 → 通**:`open`(data: URL)→ `{"ok":true,"title":"dvc-probe"}`;`run` evaluate → `"dvc-probe|hello"`(DOM 读取成功);`close` → `{"ok":true}`。全周期冒烟通过,§8.4 的断点(缺传递依赖)解除,D8 四设备至此全部落地。
169
+ - **agent_workflow → 仍无服务**:同一结构化报错逐字复现。这是 host 组合层未挂 `ctx.workflowEngine`,不是 DASHR 插件缺陷(桥按 optional-service 模式解析);要么 host 挂服务,要么从 deny 名单/桥中移除 workflow 面。
170
+ - 掩码面无回归:绑定集 24(三桥在、`send_message` 出)、9 被掩名全缺席;`control-prompt.md` 两份 md5 仍一致(`6ec2ec0…`)、"kernel" 零残留。
171
+
172
+ ### 第三轮复测(2026-08-28 02:30,commit `db6d84b`:agent_workflow 改走捕获定义)
173
+
174
+ 提交把 `agent_workflow` 从「解析 `ctx.workflowEngine` 服务」改为「透传 session-start 捕获的原生 `workflow`/`ralph` 定义」——根因诊断正确且重要:**`workflowEngine` 在 standard preset 的 delegation 组里 entry-local(`isolate: workflowEngine: true`),组外任何 ctx 都不可见,服务层路由构造上就不可能成功**;捕获定义的 execute 闭包在 realm 内运行,是唯一可通路径。`agent`/`agent_message` 留在服务层(`ctx.subagents` 是进程级单例,处处可见)。
175
+
176
+ **桥本身实测正确**:`{}` → shape 错误(缺 `script`),rfc 缺 `objective` → shape 错误 —— 校验先于可用性,与姊妹桥一致(该轮提交同步修正了校验顺序)。
177
+
178
+ **但捕获路由仍不可用,且暴露新事实**:
179
+
180
+ - script 模式 shape 合法时 → `agent_workflow() is unavailable: the native workflow tool is not registered in this composition` —— 捕获映射里**没有** `workflow` 定义。
181
+ - 捕获是 pre-mask 快照(native-capture 在掩码监听器之前运行),所以这不是掩码吃掉了它:**本 session-start 时 `workflow` 就不在 root 可见面里**。绑定集(per-eval 实时枚举 visible)同样没有 `workflow`/`ralph`,而 deny 是 session-start 时按当时可见集计算的 —— 若工具后来才挂上,它会以未掩状态进绑定集;没有 → 本 boot 里它从未注册。
182
+ - **对照 v0.1.8d**:同一 profile 的 wire 全量快照(functions.json,25 工具)当时**包含** `workflow`/`ralph`/`subagent` 全家 —— 即这个环境它们曾经正常挂载。
183
+ - 排除项:`dsh-tool-workflow`/`dsh-tool-ralph`/`dsh-workflow-worker-thread` 包都在 host node_modules;standard preset 的 `tool-workflow`/`tool-ralph` 行启用(无 `disabled`);DASHR bundle patch 不碰 delegation 组;host 包自 08-23 未变。
184
+ - 归因(边界内):delegation 组里依赖 realm-local `workflowEngine` 的行(`tool-workflow`/`tool-ralph`,inject 三个键含 `workflowEngine`)在本次 boot 疑似未完成挂载(worker-thread provider 未在 realm 内就绪 → inject 等待悬置)。沙箱内 ps/journal 均不可见,无法从 agent 侧看 host 的 preset activation audit —— 需在 host 侧核对 `delegation` 组三行的挂载状态。
185
+ - 连带修正 §2.1 的表述:在**当前部署**里,deny 名单中 `workflow`/`ralph` 两项实为 no-op(计算 deny 时它们本就不可见);「9 名全链路消失」的结论不变,但其中 7 名是掩码所致,这两名是未挂载所致。
186
+
187
+ **净结果**:`agent_workflow` 依然实际不可用,但报错从误导性的「no service mounted」变成了准确的「native tool not registered」。收尾动作在 host 侧:查 delegation 组挂载,或按 preset 注释补装对应 Bundle 后重启。
188
+
189
+ ### 第四轮复测(2026-08-28 02:45,commit `8eb7b27`:agent() 对齐原生 continuable 语义)
190
+
191
+ 提交把 `agent()` 的 `run_in_background` 默认从 false 翻转为 **true**(对齐部署的原生 `subagent` 工具 `backgroundMode: continuable` 的模型契约;显式 `false` 才是一次性等待语义)。本轮做了**真实端到端 delegation 全链路实测**(此前只探过 shape 错误路径):
192
+
193
+ | 步骤 | 实测结果 |
194
+ |---|---|
195
+ | 一次性 spawn(`run_in_background: false`)| ✅ 等待并返回完整结果:`{"kind":"foreground","runId":"5f0c8fc0…","output":[…,{"text":"CHILD-OK"}]}` |
196
+ | continuable spawn(默认)| ✅ 立即返回持久 id:`{"kind":"continuable","subagentId":"39d22093…"}` |
197
+ | roster `agent://` | ✅ 一行:`bg probe child`(label 作 id 列)· `ready` · parent=本会话 · last activity;**一次性子正确不列**(D6)|
198
+ | 下行 `agent_message(receiver='child')` | ✅ 返回 `{"messageId":"c3d9b351…"}`;子代理把 follow-up 当下一轮处理,结算回执恰为要求的 `DOWNLINK-OK` |
199
+ | 子输出读取 | ✅ `agent://<raw id>` 与 **label 寻址** `agent://bg probe child` 双路命中同一输出(D6 label 寻址落地)|
200
+ | `receiver='interrupt'`(已结算子)| ✅ `{"accepted":true}` —— 与原生「interrupt 已结束的 agent 是接受的 no-op」语义一致 |
201
+
202
+ **两个观察(非阻断)**:
203
+
204
+ 1. **roster status 粒度**:continuable 子首个回合进行中时 roster 显示 `ready` 而非 `running`(`ctx.agents` 注册表查无该子 → 按回落渲染 `ready`)。native `list_agents` 的三态在此场景同样依赖 live registry,属上游同源的粒度限制,但值得记录。
205
+ 2. **输出 artifact 含 reasoning 且无分隔**:`agent://<child>` 返回 `…nothing else.DOWNLINK-OK` —— 子的 reasoning 块与 text 块直接拼接(无换行)。对照原生:一次性任务的父面最终文本 `finalText` **只取 text 块**(`blocks.filter(type==="text")`,`reasoning` 被滤除)。DASHR 的 URL artifact 按 spec「rendered content of last non-empty assistant message」渲染全部块,spec 字面成立,但(a)把子的思维链暴露进可读 URL 面、(b)块间无分隔符,是两处可打磨点。
206
+
207
+ **workflows 面:与第三轮完全相同** —— `agent_workflow` 仍返回 `the native workflow tool is not registered in this composition`(本次 boot 原生 `workflow` 工具仍未挂载;`8eb7b27` 未触及 host 侧)。阻塞点不变:需 host 侧核对 delegation 组 `tool-workflow`/`tool-ralph`/`workflow-worker-thread` 三行的 activation audit。
208
+
209
+ ### 第五轮复测(2026-08-28 03:05,commit `0a56da4`:serviceForAgent 读址)—— **workflow/ralph 全通**
210
+
211
+ 三连修的第三方案:**`serviceForAgent(ctx, agent, 'workflowEngine')`** —— host preset 框架对「已持有 agent 的调用方读 realm-local 服务」的官方通道(api-proxy 同款机制),外加 root-realm `ctx.get` 回退;Ralph 的固定编排脚本/meta 常量从 `dsh-tool-ralph` 原样内联,script/rfc 透传 `engine.start`。提交信息同时确认了第三轮的诊断:原生 workflow/ralph 工具从不进入 agent 可见投影(v0.1.8 直暴时代早于 dsh 的 delegation 面 preset 化;掩码的「跳过未注册名」行为让这个缺席不可见)——捕获定义方案构造上不可能成功。
212
+
213
+ **路由证明(先于真实运行)**:script 模式传入非法 meta → 错误来自**引擎内部**的 meta 校验(`meta.objective is not a recognized field (name/description/whenToUse/phases)…`)——不再是桥本地的 unavailable,`engine.start` 已真实抵达。
214
+
215
+ **真实最小运行(双模式全过)**:
216
+
217
+ | 模式 | 输入 | 结果 |
218
+ |---|---|---|
219
+ | script | 1 个 `agent()` hook 的平凡脚本 + 合法 meta | ✅ `{"runId":"533d956f…","agentsStarted":1,"result":{"token":"WF-AGENT-OK"}}` —— 引擎执行脚本、起 1 子、子按令牌回复、`return` 值回流 |
220
+ | rfc(Ralph)| 平凡 objective + `maxRounds:1` | ✅ `{"runId":"9db99bd8…","agentsStarted":1,"result":{"status":"complete","roundsStarted":1,"report":{"status":"complete","summary":"RALPH-OK","evidence":[…],"nextSteps":[],"blocker":""}}}` —— 内联 Ralph 编排在 1 轮内由 fresh child 完成目标、结构化 report 回流、循环干净收尾 |
221
+
222
+ **roster 一致性**:两次运行起的 one-shot 子(workflow 的 `agent()` 子、Ralph round-1 子)在事后的 `agent://` 名册中**正确缺席**(仍只列 continuable 的 `bg probe child`)——与 D6「one-shot 不列但可寻址」一致。
223
+
224
+ **至此 §9/§10 的全部发现与遗留闭环**:四项漂移已修、browser 已修、delegation 三桥端到端全通、workflow/ralph 双模式真实运行通过。掩码面(24 绑定、9 名消失)、`control-prompt`(零 kernel)、四设备均无回归。v0.1.8f 的 surface-and-devices 交付完整落地。
@@ -0,0 +1,168 @@
1
+ # v0.1.9-a 实测报告(native-tools)
2
+
3
+ - 部署:commit `266d232`,版本 `0.1.9-a`,profile web,dsh-web PID 3340234(127.0.0.1:3080)
4
+ - 套件:30 文件 / 365 tests 全绿;typecheck 零错
5
+ - 前置:surface-and-devices 已归档(2026-08-28),本 change 的 tool-surface delta 叠其上
6
+ - 实测人:被测 Dash Agent 运行时本体(第一人称),2026-08-28,会话 `session-59618b74-4aa4-4d94-b0b9-2b45cdc6c1ef`,路由 zai-plan / glm-5.3
7
+
8
+ ## 部署核验(实测前置)
9
+
10
+ - 源码版本 `0.1.9-a`(dashr/package.json),工作树 HEAD `e3d29fb`(报告骨架)之上即 `266d232`(本 change)。
11
+ - 部署位 `~/.dsh/profiles/web/node_modules/@pgmi-builds/dashr`,`lib/index.js` 构建于 2026-08-28 12:12,与工作区 `dashr/lib/index.js` **md5 逐字节一致**(`39ce52edb15027b91f12254d5732e85d`)。
12
+ - 部署 lib 含 `llm_completion` 14 处、`AGENT_BRIDGE_SCHEMAS` 0 处(退役干净,源码中仅剩 index.ts:1018 一条解释性注释)。
13
+ - 运行时级新鲜度由实测本身坐实:本会话 wire 面已出现 `agent` / `agent_message` / `agent_workflow` / `llm_completion` 四个工具(v0.1.8 及以前三桥不在此面)。
14
+
15
+ ## 本轮结构变化(对实测口径的影响)
16
+
17
+ 1. **三桥成为真工具**:`agent` / `agent_message` / `agent_workflow` 现在是 registry 注册(与 `eval` 同宿主层)。模型**直调**(不经 cell)应当工作,且走完整 dispatch 管道(审计事件/presentation)。REPL 侧 `tool.agent(...)` 不变(auto-bridge 自动拾取)。手写 `AGENT_BRIDGE_SCHEMAS` 路径已删除——目录渲染单源。
18
+ 2. **新增 `llm_completion`**:one-shot 无工具无历史 LLM 调用。参数 `{prompt, system?, maxTokens?}`,返回**纯文本**(string 根)或 `{error}`。路由 = 调用方 agent 的 provider/model。
19
+ 3. **write 反馈环**:lsp server 在位的语言,write 结果带 `diagnostics` 摘要字段(计数+首条);格式化在写前完成(单次写、单次审计)。无 server 语言零变化。
20
+
21
+ ## 实测点(新会话)
22
+
23
+ ### §1 三桥 wire 直调(不变式验收)
24
+ ```
25
+ # 直调(不经 eval cell),各应返回与 REPL 相同的 shape:
26
+ agent({ "description": "probe", "prompt": "Reply exactly PROBE-OK", "run_in_background": false })
27
+ agent_message({ "receiver": "child", ... }) # 沿用 v0.1.8f 口径
28
+ agent_workflow({ "mode": "rfc", "objective": "..." })
29
+ ```
30
+ - [x] wire 直调三桥基本盘全通:`agent` one-shot 直调返回 `{kind:"foreground", runId, output:[…]}`,子代理回 `WIRE-PROBE-OK`(v0.1.8f §11 的结构性缺口关闭);`agent_message` child 下行投递成功、子代理回 `DOWNLINK-OK`;`agent_message` parent 自根 agent 调用返回结构化 UNAUTHORIZED 错误(不抛);`agent_message` interrupt 成功停止 sleep-90 子代理(`accepted:true`,子代理 "stopped before it finished")。
31
+ - [x] wire 工具数组中出现 `agent` / `agent_message` / `agent_workflow` / `llm_completion`(本会话 wire 声明即证)。
32
+ - [x] **三面逐名相等(例外恰为 `eval`)**:REPL 真实绑定集 = `__dashr_injected__["tool"]["functions"]` 枚举 25 名(agent、agent_message、agent_workflow、llm_completion、read/write/edit/grep/glob、bash、job_*、memory_*、web_search、ask_user_question、read_image、todo_write、get/update/create_goal、exit_plan_mode;初版误记 26,0.1.9-b 复测时以集合差分复核定正),与 wire 平面(26 平面名 = 同 25 名 + `eval`,另 5 个非平面 `mcp__cordis-a2a__*`)逐名相等;`eval` 只在 wire 面、不在绑定集也不在目录(符合 self-call 防护例外);mask 九名(skill/send_message/report/list_agents/subagent/subagent_fork/interrupt_agent/workflow/ralph)在 wire 与绑定集均零出现。
33
+ - [x] dispatch 管道审计(D1 白捡收益):wire 直调 `agent` 在会话日志落 `tool/call`(seq 8994,全参数);cell 内桥/completion 调用落 `tool/code-dispatch-start` + `tool/code-dispatch` 成对事件(本会话 19 对,含结构化错误场景,`isError:false` + `{error:...}` 内容)。v0.1.8f「cell 闭包直调绕过审计」关闭。
34
+ - [ ] **`agent_workflow` rfc 模式真正跑通** — wire 直调 rfc 模式 ✅:`maxRounds:1`,返回 `{runId, agentsStarted:1, result:{status:"complete", roundsStarted:1, report:{summary:"RFC-OK-019A"}}}`,v3 引擎 realm 修复(`0a56da4`)+ 注册化叠加端到端成立。但 **script 模式 wire 不可用**,见缺陷 F1。
35
+
36
+ ### §2 llm_completion
37
+ ```
38
+ llm_completion({ "prompt": "Reply with exactly one word: PONG" })
39
+ ```
40
+ - [x] 返回纯文本 `PONG`(string 根,非 {text} 包装)。
41
+ - [x] cell 内:`await tool.llm_completion({"prompt":"…"})` 返回裸 str `CELL-PONG`(auto-bridge 拾取,零 spawn——judge 场景成立)。
42
+ - [x] system 生效:强制尾缀 SYST-OK 的 system prompt 下,回复以 `SYST-OK` 结尾。
43
+ - [x] 参数校验为结构化 error:`maxTokens:0` 与 `maxTokens:5000`(>4096 上限)均返回 `{error:"…must be a positive safe integer no greater than 4096"}`,不抛。
44
+ - [~] 降级 finish → 结构化 error:**本路由不可触发**。`maxTokens:1` / `maxTokens:3` 实际返回了完整长输出(见缺陷 F8),说明 maxTokens 未端到端生效,"hits maxTokens → {error}" 场景在此 provider 上无法到达;abort 路径未做第一人称触发。
45
+ - [~] 无路由场景:结构化 error 为**源码级核验**(llm-completion.ts:93-96:无 provider/model 即 `{error:"requires a model route"}`),根会话第一人称不可达(exec.agent 恒在)。注意该行为与设计文档的 default-model 回落说法不一致,见缺陷 F5。
46
+
47
+ ### §3 write 反馈环(lsp = rust-analyzer,本机唯一在装 server)
48
+ - [x] 写带类型错误的 .rs → write 结果含 `diagnostics` 字段:`"1 error(s), 1 hint(s) — first: mismatched types\nexpected 'u32', found '&str'"`(E0308,计数+首条明细,与 spec 一致)。
49
+ - [x] 写正确 .rs → 无 `diagnostics` 字段("no diagnostics 不附加" 成立;新文件干净控制组 clean.rs 同样无字段)。
50
+ - [x] 写 .txt(无 server)→ 结果键集 `{path, operation, before, after}`,与旧版完全一致(无新字段、无格式化、无错误)。
51
+ - [ ] 格式化:**未生效**——写风格混乱的 .rs(`pub fn messy(x:i32)->i32{…}`)盘上字节不变;直查设备返回 `{changed:false, reason:"server declares no formatting capability"}`,而 rustfmt 在装、rust-analyzer 实际声明该能力。根因是**能力键名读错**(`formattingProvider` vs LSP 规范字段 `documentFormattingProvider`),见缺陷 F3。测试计划的 .ts 前提亦不成立:本机无 typescript-language-server(defaults.json 注册 56 个 server,仅 rust-analyzer 二进制在位)。
52
+ - [ ] **非 stale(D2 正确性关键点)不成立**:lib.rs 先写坏(1 error),改写正确内容后连续多次 write 及直查设备**仍报旧 E0308**,且错误 span(line 2, ch 5-23)对应旧内容、hint span 对应新内容——publish 里混着 stale flycheck 诊断,见缺陷 F2。
53
+ - [~] wire 面(模型直调 write)**看不到 diagnostics**:render 只输出 `Created/Updated <path>`,diagnostics 只存在于 JSON 值里;同一调用经 cell(原始 JSON)可见。反馈环在直调面对模型不可见,见缺陷 F4。
54
+
55
+ ### §4 回归
56
+ - [x] v0.1.8f §11 agents 面不回归:one-shot `WIRE-PROBE-OK` / continuable subagentId(cca40744…)/ 下行 `DOWNLINK-OK` / interrupt 生效,全套通过。
57
+ - [x] mask 九名仍全链路消失(wire、绑定集双面核验);`eval` 仍不在绑定集/目录。
58
+ - [x] URL 面回归:`skill://grilling` 全文输出;`ctx://` 精确三键 session/model/cwd;未注册 scheme 报错列 7 个注册 scheme(agent, ctx, dsh, dvc, http, https, skill);`dvc://` 列四设备(ast_edit / ast_grep / browser / lsp),lsp 设备 diagnostics/definition/references/hover/format 动作真实可执行。
59
+ - [x] control-prompt.md `kernel` 措辞 0 处(v0.1.8e D5 欠账已清);v0.1.8e 的 `dir(tool)` 空目录缺陷**仍在**(28 个 dunder、零绑定名,真实绑定集仍只在未文档化的 `__dashr_injected__`),本轮 scope 未含此项,沿用为已知欠账。
60
+
61
+ ## 结果
62
+
63
+ **总体判定:v0.1.9-a 已真实生效,主体目标(A.1 不变式恢复、桥审计、completion、write 反馈环骨架)达成;存在 2 个 P1 缺陷(script 模式 wire 不可调、write 诊断 stale)与 1 个 P2 死代码(format-on-write 能力键名错误),均不破坏既有面,可热修。**
64
+
65
+ ### 通过项
66
+ | # | 项 | 证据 |
67
+ |---|---|---|
68
+ | P1 | 三面逐名相等(例外恰 eval) | 绑定集 26 名枚举 ≡ wire 平面名 ≡ 目录;mask 九名双面零出现 |
69
+ | P2 | 桥 wire 直调 | `agent` one-shot/background、`agent_message` child/parent/interrupt 全通过,日志 `tool/call` 全参数 |
70
+ | P3 | dispatch 审计 | wire `tool/call`+`tool/result`;cell `code-dispatch` 19 对(v0.1.8f 审计缺口关闭) |
71
+ | P4 | workflow rfc 端到端 | `RFC-OK-019A`,1 round / 1 agent,realm 修复叠加注册化成立 |
72
+ | P5 | llm_completion 主链路 | 裸 string 根、system 生效、cell 零 spawn、结构化校验错误(0/5000 边界) |
73
+ | P6 | write 诊断(cell 面) | 计数+首条摘要附结果;干净/serverless 零附加(byte-identical 键集) |
74
+ | P7 | 手写 schema 路径退役 | `AGENT_BRIDGE_SCHEMAS`/`createAgentBridgeBindings` 源码+部署 lib 双零;目录单源 |
75
+ | P8 | 回归面 | skill:///ctx:///dvc:///错误词汇/kernel 措辞/agents 面全部不回归 |
76
+
77
+ ### 缺陷清单
78
+ | # | 级 | 缺陷 | 证据与定位 |
79
+ |---|---|---|---|
80
+ | F1 | P1 | **`agent_workflow` script 模式 wire 不可调用**:`meta`/`args`(`type:'json'` 平铺字段)在 wire 路径以 JSON **字符串**到达(会话日志 seq 15232/22071 两种编码均然),而桥的 execute 要求 `typeof meta === 'object'`(bridges/index.ts:367)→ 恒报 `requires {"meta": {...}}`。对照:数组型参数(todo_write 的 todos)wire 正常到达为容器——疑为 wire 层只按声明类型做字符串→值还原、typeless(json) 字段保持字符串。cell 路径(py dict→JS object)正常(`SCRIPT-CELL-OK`,runId ca63c30a)。**A.1 的「wire ≡ REPL」在此一工具上破约**。修法:桥侧对 meta/args 做 `typeof === 'string'` 时 `JSON.parse`(一行),或参数 schema 改声明 object 形状 | 双编码 wire 调用 + 日志 arguments + cell 对照 |
81
+ | F2 | P1 | **write 诊断 stale**:修复后的内容连续多次写入仍报旧错(E0308),错误 span 指向旧内容、hint span 指向新内容;直查 `dvc://lsp`(带 content override)同样 stale。机制:rustc 源(flycheck)诊断不随 didChange 刷新,版本门限等待放行了合并 publish。违反 dvc spec「EXACT content just written (never a stale earlier version)」场景。修法:write-feedback 路径过滤 `source==='rustc'`,或主动触发 flycheck(`rust-analyzer/runFlycheck`) | lib.rs 坏→好×3 次 + 设备直查,span 错位实锤 |
82
+ | F3 | P2 | **format-on-write 死代码**:lsp-device.ts:423 读 `serverCapabilities?.formattingProvider`,LSP 规范字段为 `documentFormattingProvider`(client 直接存 `initResult.capabilities`,无键名改写)→ 永远 `changed:false, "server declares no formatting capability"`,与 rustfmt 在装、RA 实有格式化能力的事实矛盾。一行修复 | 设备直查 reason + 两文件键名对照 |
83
+ | F4 | P2 | **wire 面 write 结果不呈现 diagnostics**:render 仅输出 `Created/Updated <path>`(write.ts output.render),diagnostics 只在 JSON 值中;模型直调 write 永远看不到反馈,反馈环仅在 cell 面可用。D2 的目的(edit 完立即知道写对了没有)对直调面落空 | 同一写入 wire 面(只见一行)vs cell 面(JSON 含 diagnostics)对照 |
84
+ | F5 | P3 | 文档漂移:design D3/spec 说无路由时回落 host default model,实现返回结构化 error(llm-completion.ts 源码注释自述「answers a structured error rather than guessing」)。实现取舍可辩护,文档应改 | design.md D3 vs llm-completion.ts:93-96 |
85
+ | F6 | P3 | 文档漂移:design/tasks 说 `purpose:'completion'` 审计,实现不传 purpose(host `GenerateOptions.purpose` 为封闭枚举 'compaction'/'session-title'),归因仅靠 sessionId + tool 级审计。spec「audit purpose distinct from agent turns」未满足 | llm-completion.ts 头注 + 会话日志(无独立 request/header) |
86
+ | F7 | P3 | 文档漂移:design D2 说诊断走「`xd://lsp` 设备通道」,实际 scheme 为 `dvc://lsp`(`xd://` 未注册,错误词汇列 7 scheme 无它) | `xd://lsp` 报 URL_UNREGISTERED_SCHEME |
87
+ | F8 | P3 | `maxTokens` 未端到端强制(zai/pi-ai 路由):`maxTokens:1/3` 返回完整长输出;上限校验(≤4096)正常。dashr 侧转发链已核(GenerateOptions.maxTokens → pi-ai `streamSimple(...{maxTokens})`),丢失点在 dashr 边界之下(pi-natives 方言或端点)。后果:「降级 finish → {error}」场景在此路由不可达 | 两次小 maxTokens 长输出 + 源链核验 |
88
+ | F9 | P4 | 沿用欠账:`dir(tool)` 仍无绑定名(28 dunder),真实绑定集在未文档化 `__dashr_injected__["tool"]["functions"]` | pad 枚举 |
89
+ | F10 | P4 | wire 层在校验时静默丢弃未知键(带 `bogus_param` 的 agent 调用正常 spawn),桥内 `rejectUnknownKeys` 仅 cell 面可见——两面错误词汇不对称 | wire bogus 键 spawn 成功 vs cell `{error:"unexpected key(s)"}` |
90
+
91
+ ### 建议
92
+ 1. **热修三件**(合计约五行改动):桥侧 JSON.parse json 型字符串字段(F1);lsp 能力键名改 `documentFormattingProvider`(F3);write render 附 diagnostics 摘要行(F4)。
93
+ 2. F2 需小设计决策(过滤 rustc 源 vs 触发 flycheck vs 延迟双拉),建议单开 change 或并入下轮。
94
+ 3. 文档同步:design.md D3 的路由回落与 purpose 表述、D2 的 `xd://lsp` 措辞,按实现实况改写(F5/F6/F7)。
95
+ 4. 测试计划模板(本文件 §3)的 .ts 前提与主机 server 现实脱节,建议模板改为「按 defaults.json ∩ 已安装二进制选择探测语言」。
96
+ 5. F8 建议在 pi-natives/zai 路由上单独立案追 maxTokens 丢失点;dashr 侧已无可修。
97
+ 6. 归档前跑一次 `registry.schemas(scope)` 与绑定集的程序化逐名断言进 vitest(tasks 1.4 已列,保持)。
98
+
99
+
100
+ ## §5 热修轮(0.1.9-b,commit 见下)
101
+
102
+ 针对 §1–§3 缺陷清单的第一轮热修(deployed,dsh-web PID 3416099,30 文件 / 371 tests 绿,+6 新测试):
103
+
104
+ ### 已修
105
+ - **F1** ✅:`agent_workflow` 桥侧 `coerceJsonField`——`meta`/`args` 以 JSON 字符串到达时先 parse 再校验(字符串先于校验规整,两面同语义);不可解析字符串仍走结构化 error。回归测试 ×2(wire-form 字符串 coerce / 不可解析仍报错)。**A.1「wire ≡ REPL」在此工具恢复。**
106
+ - **F3** ✅:能力键名改 `documentFormattingProvider`(LSP 规范字段,短别名保留为容错回退)。fake-lsp-server 声明该能力 + 实现 `textDocument/formatting`(确定性空格折叠编辑)+ didOpen/didChange 全量文本追踪;设备测试 ×3(spec 键格式化 / 已格式化 changed:false / content override 的诊断同步)。
107
+ - **F4** ✅:write 的 `output.render` 在有 `diagnostics` 时附第二行摘要——wire 直调面模型可见反馈环(此前仅 cell JSON 可见)。
108
+ - **F5/F6/F7** ✅(文档同步):design D3 路由改为「无路由=结构化 error,不猜默认」;purpose 表述改为「宿主封闭枚举,归因靠 sessionId + 工具级审计」;D2 的 `xd://lsp` 改 `dvc://lsp`。spec delta 同步。
109
+
110
+ ### 复测点(下轮)→ 已于 0.1.9-b 复测(2026-08-28,同一第一人称会话续跑,新 PID 3416099)
111
+ - [x] `agent_workflow` script 模式 **wire 直调** ✅:wire 面对象参数直调返回 `{runId:575a5a42…, agentsStarted:0, result:{token:"SCRIPT-WIRE-OK", hookAgent:"function"}}`(脚本内可见 agent 钩子);cell 面 `SCRIPT-CELL-OK-B`。**F1 关闭,wire ≡ REPL 恢复**。
112
+ - [x] write 格式化生效 ✅(update 路径)/ ⚠️(create 路径见新缺陷 F11):对**已存在**的 messy.rs 重写混乱风格 → 盘上内容为 rustfmt 归整版(`pub fn messy3(x: i32) -> i32 {\n let y = x * 2;…`),设备直查 format 返回 `changed:true` + 规整文本;但对**新建**文件(messy.rs/messy2.rs 首写)盘上保持原文——`preWriteFormat` 先于落盘执行,而设备入口有 `existsSync` 门(lsp-device.ts 文件不存在即抛 LSP_BAD_ARGS,钩子吞掉静默跳过)。
113
+ - [x] write wire 直调面 ✅:坏内容 .rs 的直调 write 结果为两行文本(`Created <path>` + `1 error(s), 1 hint(s) — first: mismatched types\nexpected 'u32', found '&str'`)——反馈环对模型可见。**F4 关闭**。
114
+
115
+ ### 复测结果(0.1.9-b)
116
+ - **部署核验**:源码/部署 lib 版本 `0.1.9-b`(commit `92d5908`),构建于 2026-08-28 13:12,md5 与工作区一致(`b9598bd0…`),371 tests 绿(commit 自述)。
117
+ - **回归**:绑定集 25 名与 0.1.9-a 完全一致(集合差分零差;初版计数 26 为笔误,已定正);mask 九名零出现;`eval` 例外不变;`agent` one-shot 直调 `REGRESS-OK-B`;`llm_completion` 正常。
118
+ - **F2 复核:仍在**(立案跟踪一致)——main.rs 坏→好覆写后,wire 直调 write 仍报 stale `1 error(s) … mismatched types`(旧内容诊断)。
119
+ - **F8 复核:仍在**(立案跟踪一致)——`maxTokens:1` 仍返回完整五十词计数+收尾语。
120
+ - **文档同步核验**(F5/F6/F7):design/spec delta 措辞已按实现改写(无默认路由回落、封闭枚举无 purpose、`dvc://lsp`)。小疵:spec.md 新文本将「attributed … through the normal tool-call audit」子句写了**两遍**(同段重复句),建议顺手去重。
121
+
122
+ ### 新增缺陷(复测发现)
123
+ | # | 级 | 缺陷 | 证据与定位 |
124
+ |---|---|---|---|
125
+ | F11 | P3 | **format-on-write 对新建文件失效**:`preWriteFormat` 在落盘前调设备,而设备 `execute` 入口的 `existsSync` 门拒绝尚不存在的文件(抛 LSP_BAD_ARGS,钩子静默吞掉)→ create 场景永不格式化,update 场景正常。修法:设备对带 `content` override 的调用放宽存在性门(或钩子侧传临时 URI) | messy.rs create 未格式化 vs update 格式化;lsp-device.ts existsSync 门 |
126
+
127
+
128
+ ### 热修轮 0.1.9-c(F11 + 小疵,commit 见 git log)
129
+ - **F11** ✅:设备 `existsSync` 门改为仅守 disk-backed 调用——带 `content` override(pre-write format 的形态)时跳过存在性检查,create 场景可格式化;回归测试 ×2(不存在文件 + content 可格式化 / 无 content 的不存在文件仍报 `file not found`——门只对 content 放宽)。
130
+ - **spec 重复句** ✅:llm_completion requirement 里 duplicated 的 attribution 子句已去重。
131
+ - 部署:30 文件 / **373 tests** 绿,版本 `0.1.9-c`,md5 一致,dsh-web PID **3461003**。
132
+ - 复测点:新建混乱风格 .rs 一笔写入 → 盘上即 rustfmt 归整版(create 路径格式化首次生效)。
133
+
134
+ ### 复测结果(0.1.9-c,2026-08-28,commit `7ed1fc2`,md5 `d2f95874…` 一致,PID 3461003)
135
+ - [x] **F11 关闭**:wire 直调一笔新建 `fresh.rs`(混乱风格 `pub fn fresh_messy(x:i32)->i32{…}`)→ 盘上直接落 rustfmt 归整版(`pub fn fresh_messy(x: i32) -> i32 {\n let y = x * 3;…`)——create 路径格式化首次端到端生效;设备侧 content-override 放宽门与 disk-backed `file not found` 保留(diff 核验)。
136
+ - [x] **F4 保持**:坏内容 main.rs 直调 write 仍输出两行(`Created …` + `1 error(s), 1 hint(s) — first: mismatched types…`)。
137
+ - [x] **F1 保持**:wire script-mode 回归 `SCRIPT-WIRE-OK-C`;绑定集 25 名不变、`eval` 例外不变;`agent` one-shot `REGRESS-OK-C`;spec 重复子句已去重(diff 核验)。
138
+ - **F2 复核:仍在**(立案跟踪一致)——本轮以**真 cargo target** 干净复现:src/main.rs 坏写报 E0308 → 覆写正确内容(`let x: u32 = 2026;`)后仍报旧错。附带方法论修正:**非 target 的游离文件(无 main.rs/lib.rs 的包内文件)完全不产 flycheck 诊断**(设备直查 `no diagnostics`)——上一轮 v019b 的 messy.rs 之所以"有行为"是同 root 下有 main.rs;今后 stale/诊断类探针必须落在 target 文件上。
139
+ - **F8 复核:仍在**(立案跟踪一致)——`maxTokens:1` 仍返回完整十行输出。
140
+
141
+ ### 立案跟踪(未在本轮修)
142
+ | 缺陷 | 处置 |
143
+ |---|---|
144
+ | F2 write 诊断 stale(flycheck 不随 didChange 刷新) | 需设计决策(过滤 rustc 源 / 触发 `rust-analyzer/runFlycheck` / 延迟双拉),单开 change |
145
+ | F8 maxTokens 端到端丢失(zai/pi-ai 路由,dashr 边界之下) | 在 pi-natives/zai 侧单独立案 |
146
+ | F9 `dir(tool)` 空目录 | 沿用欠账(真实绑定集在 `__dashr_injected__`) |
147
+ | F10 wire 层静默丢未知键(两面错误词汇不对称) | 宿主 dispatch 行为,dashr 侧不可修,记录在案 |
148
+
149
+
150
+ ---
151
+
152
+ # v0.2.0 系列实测报告
153
+
154
+ ## v0.2.0a(honest-feedback,commit `5142d8c`,tag 已打)
155
+ - F2 两段式 didSave 新鲜度管线 + 超时丢 rustc 降级 + span 兜底(378 tests 绿)
156
+ - F9 `dir(tool)` 返回排序绑定名(真 kernel 验证)
157
+ - **已复测(v0.2.0b 轮,2026-08-28,详见 `docs/v0.2.0b-实测报告.md`)**:F2 关闭(target 坏→好不再报旧错,超时丢 rustc 实测两态)、F9 关闭(`dir(tool)` 26 排序绑定名)、回归面全绿
158
+
159
+ ## v0.2.0b(hashline-edit,PID 3611429,379 tests 绿)
160
+ - **hashline edit 家族首次接线**(v0.1.8c vendor 的树,躺了三个版本):`edit`(hash 锚定,own-layer shadow 内建)+ `undo_last_edit` + write preview hook + guidance sections(agentPresets fast path)
161
+ - **lsp 反馈环覆盖 edit**:post-execute hook 读落盘内容 → 诊断摘要附结果文本(write 走 wrapper 钩子不双拉)
162
+ - housekeeping:pi-natives 核对**已登记**(欠账记录未同步,本轮更正);package-lock 完整 re-resolve 三次卡死(registry 不通)→ 降级为身份字段对齐,完整同步挂 Open Question
163
+ - **复测点**(已测,详证见 `docs/v0.2.0b-实测报告.md` §3):
164
+ - [x] `read` 一个文件 → 行锚仍在(hashline read 原有面不回归)
165
+ - [x] `edit` 用锚元组改文件 → 落盘生效(结果为 hashline diffstat 形态;auto-read preview 属 write hook,edit 面不附——如实记录);`undo_last_edit` 回退且恢复行锚 hash 与原锚一致
166
+ - [x] edit 引入类型错误(.rs target 文件)→ 结果文本附诊断摘要(F2 契约,post-execute 钩子)
167
+ - [x] 内建 edit 不可达(shadow 生效,行为证:锚元组/E_STALE_ANCHOR/undo 配对语义);guidance sections 覆盖内建 tool guidance(会话 system prompt 携 hashline 指引全文)
168
+ - [x] write 结果 preview + 诊断双附加共存(create 路径再加格式化,三附加共存)
@@ -0,0 +1,123 @@
1
+ # v0.2.0b 实测报告(honest-feedback + hashline-edit)
2
+
3
+ - 部署:commit `b2d69ea`(tag `v0.2.0b`),版本 `0.2.0-b`,profile web
4
+ - 套件:commit 自述 30 文件 / 379 tests 绿
5
+ - 被测内容:v0.2.0a(honest-feedback:F2 两段式 didSave 新鲜度 + span 兜底;F9 `dir(tool)` 真目录)+ v0.2.0b(hashline-edit:vendored 编辑家族首次接线,lsp 反馈环挂 edit)
6
+ - 实测人:被测 Dash Agent 运行时本体(第一人称),2026-08-28,路由 zai-plan / glm-5.3
7
+ - 探针工件:`docs/v0.2.0b_artifacts/`(f2probe / slowprobe 两个 cargo 工程 + hashline-probe.md;target 目录已清,源码留档)
8
+
9
+ ## 部署核验(实测前置)
10
+
11
+ - 源码版本 `0.2.0-b`(dashr/package.json),工作树 HEAD `b2d69ea`,tag `v0.2.0a` / `v0.2.0b` 均在。
12
+ - 部署位 `~/.dsh/profiles/web/node_modules/@pgmi-builds/dashr`,`lib/index.js` 构建于 2026-08-28 15:29:37,与工作区 `dashr/lib/index.js` **md5 逐字节一致**(`f69d4912f6e697d613e87cb50aa18c4b`)。
13
+ - 部署 lib 含新符号:`notifyDidSave`×2、`timeout-dropped-rustc`×2、`registerEditTool`/`registerUndoTool`/`registerWriteHook`/`installAgentTools`/`composeSections` 各 2,`__dir__` 在位。
14
+ - 源码级核验:两段式等待 + rustc 丢弃 + `check` 字段在 `lsp-device.ts`(diagnostics action,`saved:true` 分支);span 行级过滤在 `url-schema/index.ts:104-105`(`record.line <= content.split('\n').length`);hashline 接线(edit/undo/write-hook + guidance)与 edit 的 `tools/post-execute` 诊断钩子(跳过 `write` 名)在 `url-schema/index.ts` installAgentTools。
15
+ - dsh-web PID:commit 自述 3611429;本实测 shell 处于 bwrap(`--unshare-pid`)沙箱,宿主 PID 不可独立复核——**运行时新鲜度改由会话面本身坐实**:本会话绑定集含 `undo_last_edit`(v0.1.9 的 25 名之外的新名)、edit 呈 hashline 锚定语义、didSave 管线行为可见(下述)。
16
+ - control-prompt.md:`kernel` 措辞 0 处(md5 `6ec2ec00…`)。
17
+
18
+ ## §1 F9 — `dir(tool)` 真目录(honest-feedback D3)
19
+
20
+ - [x] `dir(tool)` 返回 **26 个排序绑定名、零 dunder**(v0.1.9 为 28 dunder / 0 绑定名):agent、agent_message、agent_workflow、ask_user_question、bash、create_goal、edit、exit_plan_mode、get_goal、glob、grep、job_kill、job_list、job_output、llm_completion、memory_add、memory_flush、memory_list、memory_search、read、read_image、todo_write、**undo_last_edit**(新)、update_goal、web_search、write。
21
+ - [x] `__dashr_injected__["tool"]["functions"]` 形态不变(list,26 名),与 `dir(tool)` **逐名相等**(集合断言 True)——兼容面未动,符合「仅加不改」。
22
+ - [x] 三面不变式保持:`dir(tool)` ≡ `__dashr_injected__` ≡ wire 面 − {`eval`};`eval` 例外恰好成立;mask 九名(skill/send_message/report/list_agents/subagent/subagent_fork/interrupt_agent/workflow/ralph)双面零出现。
23
+
24
+ **F9 关闭。**
25
+
26
+ ## §2 F2 — write 诊断新鲜度(honest-feedback D1/D2)
27
+
28
+ 探针:`f2probe`(真 cargo target `src/main.rs`,遵守 v0.1.9-c 方法论教训——游离文件不产 flycheck 诊断);`slowprobe`(`build.rs` 睡 6s,`cargo check` 实测 6.4s,用于确定性超时)。
29
+
30
+ ### 核心场景(坏→好→坏,wire 直调面)
31
+ - [x] 写坏(`let x: u32 = "oops"`)→ 结果附 `1 error(s), 1 hint(s) — first: mismatched types\nexpected \`u32\`, found \`&str\``(新鲜 E0308)。
32
+ - [x] **改写正确内容(`let x: u32 = 2026`)→ 旧错不再出现**:结果只有 `Updated <path>` + preview,无诊断行;cell 面 JSON 同样**无 `diagnostics` 键**(v0.1.9 三轮在此处必报旧 E0308)。**「A fixed error stops being reported」场景通过——F2 主验收成立。**
33
+ - [x] 再写坏 → 错误回归(管线活着,非静默哑掉)。同行位新旧内容(坏/好均在 line 2)也如此——didSave 主干确实覆盖「同行 stale」漏检区(span 兜底管不到的区域)。
34
+
35
+ ### 超时降级(诚实策略)
36
+ - [x] 设备面(`dvc://lsp` 直调,`{action:'diagnostics', file, content, saved:true}`)返回体带 **`check` 字段**,两态均第一人称捕获:
37
+ - `check: "completed"` — 新鲜 rustc 记录在场(error+hint,span 对准 override 内容的 line 6);
38
+ - `check: "timeout-dropped-rustc"` — **内容明明是坏的,`diagnostics: []`、`summary: "no diagnostics"`**:rustc 源被丢、不误报(发生在 slowprobe 检查进行中的争用窗口)。「Slow checks degrade honestly」场景通过。
39
+ - [x] 确定性慢路径:`touch build.rs` 后 wire 写坏内容 → 结果**无诊断行**(flycheck 6s > 3s 预算);缓存转热后同内容写/查 → 错误正常出现。降级与恢复均如设计。
40
+ - [x] 超时窗口内 write 面是「诚实的沉默」:宁少报不误报(设计明示取舍,见观察 O4)。
41
+
42
+ ### span 兜底(D2)
43
+ - [x] 行为面:13 行坏内容(错在 line 7)→ 立即覆写 2 行正确内容 → **无任何越界旧错泄漏**(本次由超时丢弃覆盖;两保护层在此场景下输出一致)。
44
+ - [~] **guard 单独触发未第一人称分离**(两保护层输出同形):以源码核验补证(index.ts:104-105 过滤 + summary 按 retained 重算),单元测试覆盖(tasks 1.4)。如实记录。
45
+
46
+ **F2 关闭**(write 面契约级;残余仅「guard 独立触发未单独目击」,已有源码+测试双证)。
47
+
48
+ ## §3 hashline-edit(v0.2.0b 主体)
49
+
50
+ - [x] **read 锚面不回归**:全程 `HASH│content` 行锚(本报告所有探针读写均经此面)。
51
+ - [x] **edit 锚元组落盘**:`{path, edits:[[hash,hash,text]]}` 一击替换成功,响应为 hashline diffstat 形态(`Successfully edited 1 file(s) — 1 of 1 edit(s) applied. Added 1 line(s), removed 1 line(s).`),未触碰行锚点稳定不变(s33/AuN/nyO/DBc 跨编辑保持)。
52
+ - [x] **drift 校验**:复用已失效锚(`zlr`)→ `[E_BATCH_ABORT]` + `[E_STALE_ANCHOR] "zlr"` 硬拒,**整批原子、零写入**。
53
+ - [x] **undo_last_edit 回退**:`Removed 1 line(s) … restored 1 line(s)`,diff 展示回退;被恢复行的锚 hash 与原锚完全一致(**hash 确定性**:同内容同锚,双向稳定)。
54
+ - [x] **edit 引入类型错误 → 结果文本附诊断摘要**(spec 关键场景):main.rs 好态下锚编辑 `let x: u32 = "edit-introduced"` → edit 结果第二行即 `1 error(s), 1 hint(s) — first: mismatched types…`。post-execute 钩子端到端成立;edit 无 format(D3 取舍符合)。
55
+ - [x] **shadow 生效(行为证)**:edit 呈 hashline 语义(锚元组/E_STALE_ANCHOR/diffstat/undo 配对)——与宿主原生 old_string/new_string 形态完全不同;mask 名单无 `edit`(九名不变);绑定集 edit/undo_last_edit 在位。**guidance sections 在场**:本会话 system prompt 携带 hashline 编辑指引全文(bare 3-char HASH anchor 用法、undo_last_edit 说明、`HASH│content` 行格式、`[E_RANGE_STALE]`/`[E_RANGE_UNSERVED]` 词汇表)——compiled defaults 对内建 tool guidance 的同层 shadow 第一人称可见。
56
+ - [x] **write preview + 诊断 + 格式化三附加共存**:一笔 create 写入混乱风格坏内容(`src/bin/messy.rs`,真 cargo target)→ 单一结果同时含 ① `Created <path>` ② 诊断行(针对**落盘后**内容)③ Auto-read preview 展示 **rustfmt 归整版**(盘上字节核验一致:`pub fn messy_v020b(x: i32) -> i32 {` 多行展开)。F11(create 路径格式化)与 preview/诊断叠加态不互斥。
57
+
58
+ ## §4 回归面
59
+
60
+ - [x] `agent` one-shot wire 直调:`REGRESS-OK-D`(顺带 F10 复核:附 `bogus_param` 仍正常 spawn——wire 层静默丢未知键,行为不变,立案口径不变)。
61
+ - [x] `agent_workflow` script 模式 wire 直调:`SCRIPT-WIRE-OK-D`(F1 保持关闭);**新观察**:`meta` 现在强制 `description` 非空(仅 `{name}` 得结构化错误 `meta.description must be a non-empty string`),见 O2。
62
+ - [x] `llm_completion`:`PONG`(裸 string 根)。
63
+ - [x] **F8 复核:仍在**(立案跟踪一致):`maxTokens:1` 返回完整五十词计数 + `DONE`(dashr 边界之下,pi-natives/zai 侧)。
64
+ - [x] URL 面:`ctx://model` 三键(zai-plan / glm-5.3);`dvc://` 四设备 roster(ast_edit/ast_grep/browser/lsp);未注册 scheme 报错列 7 scheme;`skill://grilling` 全文可读(1842 字节)。
65
+ - [x] mask 九名零出现;`eval` 三面例外恰成;control-prompt `kernel` 0 处。
66
+
67
+ ## 结果
68
+
69
+ **总体判定:v0.2.0b 全部验收点通过。F2 关闭(write 反馈环不再报旧错,超时诚实降级)、F9 关闭(`dir(tool)` 真目录);hashline 编辑家族(read 锚 → edit → drift → undo → 诊断随 edit)端到端成立,write 面 preview/诊断/格式化三附加共存。无新增 P1/P2 缺陷。**
70
+
71
+ ### 通过项
72
+ | # | 项 | 证据 |
73
+ |---|---|---|
74
+ | P1 | F9 `dir(tool)` 真目录 | 26 排序绑定名(原 28 dunder/0 名);≡ `__dashr_injected__`(形态不变)≡ wire − {eval};mask 九名零出现 |
75
+ | P2 | F2 坏→好→坏 | 好内容写后旧 E0308 消失(wire 无行 / cell 无键),再坏回归;同行位新旧亦然 |
76
+ | P3 | F2 超时降级 | 设备面 `check` 两态实捕:`completed`(新鲜 rustc)/ `timeout-dropped-rustc`(坏内容 → `[]`,不误报);build.rs 睡 6s 确定性复现 |
77
+ | P4 | span 兜底 | 13 行坏(line 7 错)→ 2 行好覆写零泄漏;源码+单测补证(两保护层输出同形,未单独目击,如实记录) |
78
+ | P5 | hashline edit 家族 | 锚元组落盘 + 未触行锚稳定 + `E_STALE_ANCHOR` 原子硬拒 + undo 回退(hash 确定性)|
79
+ | P6 | lsp 反馈挂 edit | 锚编辑引入 E0308 → edit 结果文本即附诊断摘要(post-execute 钩子,spec 场景逐字成立) |
80
+ | P7 | shadow + guidance | edit 呈 hashline 语义(行为证);system prompt 携 hashline 指引全文(compiled defaults 同层 shadow) |
81
+ | P8 | write 三附加共存 | create 写混乱坏 .rs:`Created` + 诊断行 + rustfmt 归整 preview(盘上字节一致) |
82
+ | P9 | 回归面 | REGRESS-OK-D / SCRIPT-WIRE-OK-D / PONG / URL 四 scheme / kernel 0 / mask 不变 |
83
+
84
+ ### 观察与欠账(无缺陷定级)
85
+ | # | 级 | 观察 |
86
+ |---|---|---|
87
+ | O1 | 观察 | 本会话**首笔**带诊断的 wire write 结果缺 `Updated <path>` 操作行(其余 9 笔均在,含同场景重放)——一次性、疑与 RA 冷启动相邻,未复现;监控即可 |
88
+ | O2 | P3 | `agent_workflow` 的 `meta` 校验收紧:强制 `description` 非空(v0.1.9 轮次 `{name}` 可用)。行为合理,属 schema 演进——工具声明/design 文档宜同步一句 |
89
+ | O3 | 记录 | `check` 字段只在设备面(`dvc://lsp` 返回体);write 面折叠为摘要字符串。与 design「设备返回值带 check」一致,非缺陷——两面语义边界记录在案 |
90
+ | O4 | 记录 | 超时窗口内 write 面是「诚实的沉默」:坏内容在 flycheck 未完成时**完全不报**——「无消息」在模型侧可读作「好消息」。设计明示取舍(宁少报不误报);若未来要消歧,可在 write render 附 `check: timeout` 提示行(一行改动,非本轮 scope) |
91
+ | F8 | 立案 | maxTokens 端到端丢失(zai/pi-ai 路由,dashr 边界之下)——复核仍在,处置不变(pi-natives/zai 侧单独立案) |
92
+ | F10 | 立案 | wire 层静默丢未知键(宿主 dispatch 行为)——复核仍在,dashr 侧不可修,记录在案 |
93
+
94
+ ### 建议
95
+ 1. O2 的 `meta.description` 必填写进 agent_workflow 工具声明文案(一句),免得下轮实测再撞。
96
+ 2. O4 若要做,是 write render 的一行增量(`check==='timeout-dropped-rustc'` 时附提示行);独立小 change,优先级随真实误判案例再定。
97
+ 3. O1 保持观察:若再现实锤(冷启动 + 诊断 + 操作行丢失三连),去 write render 的组合路径查竞态。
98
+ 4. 探针工件留在 `docs/v0.2.0b_artifacts/`(target 已清,源码留档可复跑)。
99
+
100
+ ## §5 附:与 v0.1.9 开局状态的对照
101
+
102
+ | 面 | v0.1.9-c | v0.2.0b(本轮) |
103
+ |---|---|---|
104
+ | `dir(tool)` | 28 dunder、0 绑定名(F9) | 26 排序绑定名,≡ 注入集 ≡ wire−{eval} |
105
+ | write 诊断 | 坏→好后仍报旧 E0308(F2) | 好内容即静默;坏回归;超时丢 rustc 不误报 |
106
+ | edit 形态 | 宿主原生 old/new(vendored 树躺着) | hashline 锚元组 + drift 硬拒 + undo + 指引 shadow |
107
+ | edit 反馈 | 无(edit 不入反馈环) | 落盘即附诊断摘要 |
108
+ | write 结果 | Created/Updated(+诊断行,0.1.9-b 起) | + Auto-read preview(hashline write-hook) |
109
+
110
+
111
+ ---
112
+
113
+ ## §6 后续:依赖面重组根治 lock 欠账(v0.2.0-c)
114
+
115
+ **背景更正**:v0.2.0-b 报告「registry 网络不通」为**误判**——registry 完全通(ping PONG 251ms、curl 200、102 请求全 200 零重试)。真因两层:
116
+ 1. `npm install --package-lock-only` 会把 node_modules 实树里「已存在」的 optional peers(196 个手动落盘的 @deepseek-ai 包)纳入解析,传递树全展开 → 706 包级解析;
117
+ 2. npm arborist 在该树上内核态自旋(18 分钟 stime=1110s / utime=0)。
118
+
119
+ **根治(用户方案)**:dashr 是插件非自足发行版,宿主(dsh)必带 @deepseek-ai 全家 → 39 个 devDependencies 的 @deepseek-ai 包全部挪 `peerDependencies`(+peerDependenciesMeta optional,共 43 peers),devDependencies 只留 5 个构建/测试工具(@types/node、node-addon-require-builtin、tsdown、typescript、vitest)。
120
+
121
+ **lock 重建**:stash node_modules(同盘 rename)后纯声明解析 **7.7 秒**完成(vs 18 分钟自旋),lock 从 706 包瘦身到 **182 包**,version 0.2.0-c。node_modules 恢复后 typecheck/vitest 全绿(379)、build 正常(途中修复了 npm 清空的 .bin 链接——重建 tsdown/vitest/tsc 三个符号链接)。
122
+
123
+ **运维注意**:重建 node_modules 仍靠手动拷贝/从 dsh 单体复制(peer 不自动装);.bin 若再被 npm 清空,按 `ln -s ../<pkg>/<bin> node_modules/.bin/<name>` 重建。
@@ -0,0 +1,7 @@
1
+ # This file is automatically @generated by Cargo.
2
+ # It is not intended for manual editing.
3
+ version = 4
4
+
5
+ [[package]]
6
+ name = "f2probe"
7
+ version = "0.1.0"
@@ -0,0 +1,6 @@
1
+ [package]
2
+ name = "f2probe"
3
+ version = "0.1.0"
4
+ edition = "2024"
5
+
6
+ [dependencies]
@@ -0,0 +1,8 @@
1
+ pub fn messy_v020b(x: i32) -> i32 {
2
+ let y = x * 2;
3
+ let z: u32 = "wrong";
4
+ y
5
+ }
6
+ fn main() {
7
+ println!("{}", messy_v020b(21));
8
+ }
@@ -0,0 +1,4 @@
1
+ fn main() {
2
+ let x: u32 = "render-repro";
3
+ println!("{x}");
4
+ }
@@ -0,0 +1,5 @@
1
+ # hashline probe v1
2
+
3
+ alpha line
4
+ beta line
5
+ gamma line
@@ -0,0 +1,7 @@
1
+ # This file is automatically @generated by Cargo.
2
+ # It is not intended for manual editing.
3
+ version = 4
4
+
5
+ [[package]]
6
+ name = "slowprobe"
7
+ version = "0.1.0"
@@ -0,0 +1,7 @@
1
+ [package]
2
+ name = "slowprobe"
3
+ version = "0.1.0"
4
+ edition = "2021"
5
+ build = "build.rs"
6
+
7
+ [build-dependencies]
@@ -0,0 +1,4 @@
1
+ use std::time::Duration;
2
+ fn main() {
3
+ std::thread::sleep(Duration::from_secs(6));
4
+ }