better-dsh 0.2.2-a → 0.2.2-c
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.
- package/docs/50_test-reports/2026-09-06-write/345/267/245/345/205/267sandbox/345/215/207/347/272/247/351/200/217/344/274/240bug/345/244/215/345/217/221/345/217/212/346/214/202/350/265/267-/344/272/213/344/273/266/346/212/245/345/221/212.md +43 -0
- package/docs/50_test-reports/v0.2.4-ios-focus-zoom-suppression/345/256/236/346/265/213/346/212/245/345/221/212.md +158 -0
- package/docs/60_exploration-and-research/01-cordis-runtime/bun-compile-cordis-runtime-bootstrap-research.md +536 -0
- package/docs/60_exploration-and-research/01-cordis-runtime/cordis-customization-and-override-mechanics.md +418 -0
- package/docs/60_exploration-and-research/01-cordis-runtime/cordis-research.md +350 -0
- package/docs/60_exploration-and-research/01-cordis-runtime/dsh-cordis-hotplug-mcp-patch-research.md +265 -0
- package/docs/60_exploration-and-research/02-dsh-webui/dsh-web-profile-package-map.md +186 -0
- package/docs/60_exploration-and-research/02-dsh-webui/dsh-web-ui-slot-system-research.md +310 -0
- package/docs/60_exploration-and-research/02-dsh-webui/dsh-webui-backend-data-inventory.md +633 -0
- package/docs/60_exploration-and-research/02-dsh-webui/dsh-webui-strip-boundary-research.md +300 -0
- package/docs/60_exploration-and-research/02-dsh-webui/dsh-webui-wire-appendix.md +3729 -0
- package/docs/60_exploration-and-research/02-dsh-webui/web-frontend-composability-research.md +191 -0
- package/docs/60_exploration-and-research/02-dsh-webui/webui-wire-data/capture-live-turn.json +1 -0
- package/docs/60_exploration-and-research/02-dsh-webui/webui-wire-data/observed-endpoints.json +224 -0
- package/docs/60_exploration-and-research/02-dsh-webui/webui-wire-data/remote-inventory.json +110954 -0
- package/docs/60_exploration-and-research/02-dsh-webui/webui-wire-data/served-index-sample.html +47 -0
- package/docs/60_exploration-and-research/02-dsh-webui/webui-wire-data/session-events.json +9411 -0
- package/docs/60_exploration-and-research/02-dsh-webui/webui-wire-data/ws-frame-examples.json +20 -0
- package/docs/60_exploration-and-research/03-mobile-ios/dsh-mobile-spa-ios-input-experience-research.md +160 -0
- package/docs/60_exploration-and-research/03-mobile-ios/ios-chat-app-bridge-research.md +324 -0
- package/docs/60_exploration-and-research/04-session-storage/alpha5-compaction-jsonl-mapping.md +1532 -0
- package/docs/60_exploration-and-research/04-session-storage/alpha5-compaction-sample/episode-failed.json +46 -0
- package/docs/60_exploration-and-research/04-session-storage/alpha5-compaction-sample/episode1.json +1124 -0
- package/docs/60_exploration-and-research/04-session-storage/alpha5-compaction-sample/episode2.json +1240 -0
- package/docs/60_exploration-and-research/05-dashr-dev/plugin-development.md +148 -0
- package/docs/60_exploration-and-research/05-dashr-dev/upstream-alignment.md +102 -0
- package/docs/60_exploration-and-research/README.md +87 -0
- package/docs/60_exploration-and-research/bun-compile-cordis-runtime-bootstrap-research.md +348 -0
- package/docs/60_exploration-and-research/dsh-mobile-spa-ios-input-experience-research.md +160 -0
- package/lib/index.d.ts +9 -1
- package/lib/index.js +258 -6
- package/package.json +1 -1
- 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 +0 -110
- package/docs/adr/0001-bridge-tool-layer-not-service-layer.md +0 -14
- package/docs/adr/0002-masking-is-presentation-only.md +0 -15
- package/docs/plans/A2A-messaging-channel-test-archive.md +0 -256
- package/docs/plans/code-mode-vs-rlm-ipython-comparison.md +0 -137
- package/docs/plans/dashr-blueprint-review.md +0 -201
- package/docs/plans/dashr-blueprint.md +0 -561
- package/docs/plans/dashr-compaction-window-and-archive.md +0 -307
- package/docs/plans/dashr-profile-layer-feasibility.md +0 -367
- package/docs/plans/dashr-sandbox-escalation-semantics-gap.md +0 -171
- package/docs/plans/dashr-security-sandbox-analysis.md +0 -187
- package/docs/plans/dashr-surface-invariant-and-omp-imports.md +0 -97
- package/docs/plans/ipython-kernel-interactive-interface-test-report.md +0 -152
- package/docs/plans/kernel-refactoring/Dash-IPython-Control-Prompt-draft.md +0 -146
- package/docs/plans/kernel-refactoring/Dash-IPython-Control-Prompt-draft_v3.md +0 -50
- package/docs/plans/kernel-refactoring/Dash-IPython-Control-Prompt-draft_v4.md +0 -79
- package/docs/plans/kernel-refactoring/Dash-vs-PrimeAgent-systemprompt-toolcatalog-comparison.md +0 -138
- package/docs/plans/kernel-refactoring/RLM-system-prompt-injection-gap-report.md +0 -161
- package/docs/plans/kernel-refactoring/V0.1.5-development-plan.md +0 -109
- package/docs/plans/kernel-refactoring/actinoable-surface-to-llm-in-agent-runtime_dsh.md +0 -50
- package/docs/plans/kernel-refactoring/actinoable-surface-to-llm-in-agent-runtime_prime.md +0 -113
- package/docs/plans/recallable-compaction.md +0 -147
- package/docs/plans/spike-tag-repro.mjs +0 -102
- package/docs/plans/upstream-analysis.md +0 -128
- package/docs/v0.1.8-improved-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -142
- package/docs/v0.1.8-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -193
- package/docs/v0.1.8b-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -96
- package/docs/v0.1.8c-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -127
- package/docs/v0.1.8d-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -150
- package/docs/v0.1.8d_artifacts/README.md +0 -138
- package/docs/v0.1.8d_artifacts/code-mode-repl-only.observation.md +0 -74
- package/docs/v0.1.8d_artifacts/dsh-session-session-4a293388-9ae1-474b-87a0-9e17bb556d94.jsonl +0 -3890
- package/docs/v0.1.8d_artifacts/dsh-session-session-4a293388-9ae1-474b-87a0-9e17bb556d94.w-sample-0435.jsonl +0 -544
- package/docs/v0.1.8d_artifacts/functions.json +0 -592
- package/docs/v0.1.8d_artifacts/skills-catalog.snapshot.md +0 -30
- package/docs/v0.1.8d_artifacts/tools-sdk.output-schemas.json +0 -1236
- package/docs/v0.1.8d_artifacts/tools-sdk.python.txt +0 -592
- package/docs/v0.1.8d_artifacts/tools-sdk.typescript.txt +0 -516
- package/docs/v0.1.8d_artifacts/wire-vs-transcription.diff.md +0 -54
- package/docs/v0.1.8e-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -224
- package/docs/v0.1.9a-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -168
- package/docs/v0.2.0b-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -123
- package/docs/v0.2.0b_artifacts/f2probe/Cargo.lock +0 -7
- package/docs/v0.2.0b_artifacts/f2probe/Cargo.toml +0 -6
- package/docs/v0.2.0b_artifacts/f2probe/src/bin/messy.rs +0 -8
- package/docs/v0.2.0b_artifacts/f2probe/src/main.rs +0 -4
- package/docs/v0.2.0b_artifacts/hashline-probe.md +0 -5
- package/docs/v0.2.0b_artifacts/slowprobe/Cargo.lock +0 -7
- package/docs/v0.2.0b_artifacts/slowprobe/Cargo.toml +0 -7
- package/docs/v0.2.0b_artifacts/slowprobe/build.rs +0 -4
- package/docs/v0.2.0b_artifacts/slowprobe/src/main.rs +0 -13
- package/docs/v0.2.1-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -110
- package/docs/v0.2.1b-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -86
- package/docs/v0.2.1c-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -66
|
@@ -1,193 +0,0 @@
|
|
|
1
|
-
# DASHR v0.1.8 实测报告
|
|
2
|
-
|
|
3
|
-
> 实测方式:以 DASHR agent 运行时自身(本会话,运行于 dsh Web GUI)作为被测对象,直接调用 `eval` 持久内核与 `tool.*` 绑定逐一实测,并运行仓库 `npm test` 测试套件交叉验证。
|
|
4
|
-
> 实测日期:2026-08-24
|
|
5
|
-
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## 0. 摘要(TL;DR)
|
|
9
|
-
|
|
10
|
-
| 结论 | 结果 |
|
|
11
|
-
|---|---|
|
|
12
|
-
| 核心 REPL 能力(`eval` 持久内核、`tool.*` 绑定、masking、`rlm` 递归、A2A) | ✅ **全部实测可用** |
|
|
13
|
-
| 测试套件 | ⚠️ **155/163 通过,8 个失败** |
|
|
14
|
-
| 失败根因 | 🔴 **snapshot 快照/恢复功能失效**(`dill` 缺失 + 内核运行在 Python 3.14.4 而非文档要求的 3.11) |
|
|
15
|
-
| 文档/命名漂移 | 🟡 若干(`agent_message` vs `send_message`、flat-global vs `tool.*`、`fgm` vs `pgmi` 等) |
|
|
16
|
-
|
|
17
|
-
**一句话结论**:v0.1.8 的「eval 持久内核 + 统一 `tool.*` 桥接」这条主线功能是**成立且可用的**,递归子代理(RLM)与 A2A 通信全链路走通;但 **snapshot 快照/恢复(README 标注的 `dill` 全命名空间快照)在当前环境是坏的**,且存在多处文档与代码的命名/架构漂移。
|
|
18
|
-
|
|
19
|
-
---
|
|
20
|
-
|
|
21
|
-
## 1. 被测对象与版本
|
|
22
|
-
|
|
23
|
-
| 项 | 值 |
|
|
24
|
-
|---|---|
|
|
25
|
-
| 插件包名 / 版本 | `@fgm-builds/dashr`(`dashr/package.json` `version: 0.1.8`) |
|
|
26
|
-
| 工作区 git 状态 | 工作区未提交改动;`git describe` = `v0.1.6-1-gec7b844`(v0.1.7/v0.1.8 均为未提交的开发产出) |
|
|
27
|
-
| 宿主运行时 | `dsh 0.1.1-rc.2`(`dsh --version`) |
|
|
28
|
-
| Node | v22.22.1 |
|
|
29
|
-
| 内核 Python(实测) | **3.14.4**(系统 `/usr/bin/python3`) |
|
|
30
|
-
| ipykernel | 7.3.0 |
|
|
31
|
-
| `dill` | ❌ **未安装**(`ModuleNotFoundError: No module named 'dill'`) |
|
|
32
|
-
| 内核 venv | `.venv-kernel/bin/python` → `/tmp/dashr-py311/bin/python3.11` **悬空**(目标已删) |
|
|
33
|
-
|
|
34
|
-
---
|
|
35
|
-
|
|
36
|
-
## 2. v0.1.8 相对 v0.1.6 的关键变化(读代码 + 文档得出)
|
|
37
|
-
|
|
38
|
-
1. **Rebrand**:`dsh-rlm-mode` → `@fgm-builds/dashr`,定位从「RLM 插件」转向「Better Dash 完整 App(distro)」(`docs/repositioning-and-rebranding.md`、`docs/distro-blueprint.md`)。
|
|
39
|
-
2. **架构升级(最大改动)**:`cordis.patch.yml` 从 `[]`(空壳)改为在 **HOST 平面** 挂载 `dashr-repl`(`eval` 工具 + 持久 kernel REPL 运行时落到全局作用域层,对所有 preset 可见)。旧的 `preset/rlm-mode/agent.cordis.yml`、`preset.yml` **删除**——这是 v0.1.5「DashrDaemon 空壳」的正式落地。
|
|
40
|
-
3. **传输工具改名**:`run_cell` → **`eval`**(`EVAL_NAME = 'eval'`)。
|
|
41
|
-
4. **绑定形态切换**:从 v0.1.5 的「平级 top-level global」切到 **统一 `tool.*` namespace**(每工具 = `await tool.name({...})` 成员 async callable),对应 distro-blueprint §2.2 的「dual exposure / both 模式」。
|
|
42
|
-
5. **Masking 名单扩充**:`MASKED_TOOL_NAMES` 含 **8 个名**(ADR-0002 只写 7 个,实际多了 `report`):`subagent, subagent_fork, send_message, list_agents, interrupt_agent, workflow, ralph, report`。
|
|
43
|
-
6. **桥接工具**(bridge tools,`BRIDGE_TOOL_SCHEMAS`):`rlm` / `send_message` / `agent_list` / `rlm_workflow` / `rlm_ralph`。
|
|
44
|
-
|
|
45
|
-
---
|
|
46
|
-
|
|
47
|
-
## 3. 实测结果 — 功能面(逐项亲测)
|
|
48
|
-
|
|
49
|
-
### ✅ 3.1 `eval` 持久内核 —— 通过
|
|
50
|
-
|
|
51
|
-
`eval` cell 正常执行,内核为真实 IPython 持久内核,`await` / 顶层表达式 / 变量跨 cell 存续均正常。
|
|
52
|
-
|
|
53
|
-
### ✅ 3.2 状态跨 cell 持久化 —— 通过
|
|
54
|
-
|
|
55
|
-
Cell 1 定义 `persist_probe`,Cell 4 仍可读:`persist_probe still alive: {'made_in': 'cell-1', 'answer': 42}`。
|
|
56
|
-
|
|
57
|
-
### ✅ 3.3 `tool.*` 统一绑定 —— 通过
|
|
58
|
-
|
|
59
|
-
`tool.read` / `tool.bash` / `tool.grep` / `tool.glob` / `tool.write` / `tool.edit` / `tool.web_search` / `tool.skill` / `tool.memory_*` / `tool.refine` / `tool.todo_write` / `tool.get_goal` 均可用(实测调用返回正确 JSON)。
|
|
60
|
-
|
|
61
|
-
### ✅ 3.4 `ToolCallError` 类型化拒绝 —— 通过
|
|
62
|
-
|
|
63
|
-
真实工具调用失败(文件不存在)抛 `ToolCallError`,`.toolName` 正确携带绑定名:
|
|
64
|
-
|
|
65
|
-
```
|
|
66
|
-
caught ToolCallError: ToolCallError | toolName = read
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
### ✅ 3.5 `asyncio.gather` fan-out —— 通过
|
|
70
|
-
|
|
71
|
-
并发 `tool.read` + `tool.bash` 同 cell 完成。
|
|
72
|
-
|
|
73
|
-
### ✅ 3.6 Masking(呈现层排除,host 端拒绝)—— 通过(REPL 内)
|
|
74
|
-
|
|
75
|
-
`tool.subagent` / `tool.list_agents` / `tool.interrupt_agent` / `tool.workflow` / `tool.ralph` / `tool.subagent_fork` / `tool.send_message`(上游工具名) → 全部返回 `ToolCallError: unknown binding`。
|
|
76
|
-
legacy 传输名 `tool.run_cell` / `tool.run_code` / `tool.ipython` / `tool.eval`(嵌套)→ 同样 `unknown binding`(`eval` 自身不可重入)。
|
|
77
|
-
|
|
78
|
-
> 关键机制:`_DashrBindingHolder.__getattr__` 对**任意**名字都返回 proxy(`getattr` 永不抛 AttributeError),真实「是否绑定」由 host 在**调用时**判定拒绝。因此 `dir(tool)` 为 0 成员、`getattr` 恒真——需要**调用**才能区分 masked 与否。
|
|
79
|
-
|
|
80
|
-
### ✅ 3.7 桥接工具 —— 通过
|
|
81
|
-
|
|
82
|
-
| 桥接名 | 实测 |
|
|
83
|
-
|---|---|
|
|
84
|
-
| `tool.rlm` | `rlm({"mode":"bogus"})` → 结构化错误值 `{'error': 'rlm() requires ...'}`(非异常) |
|
|
85
|
-
| `tool.agent_list` | 返回子代理列表 |
|
|
86
|
-
| `tool.send_message` | 上行/下行均走通(见 3.9/3.10) |
|
|
87
|
-
| `tool.rlm_workflow` | 校验失败抛 `ToolCallError`(missing meta.name) |
|
|
88
|
-
| `tool.rlm_ralph` | 实际触发一次 Ralph 循环(`status: blocked`) |
|
|
89
|
-
|
|
90
|
-
### ✅ 3.8 RLM 递归子代理全链路 —— 通过
|
|
91
|
-
|
|
92
|
-
```
|
|
93
|
-
rlm spawn → {'kind':'continuable','subagentId':'26e2842e-...'}
|
|
94
|
-
child 完成上报: "42"(6*7)
|
|
95
|
-
send_message 下行追问 7*8 → child 再上报: "56"
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
spawn → child 执行 → wakeup 上报 → parent 下行追问 → 再上报,**完整闭环走通**。
|
|
99
|
-
|
|
100
|
-
### ✅ 3.9 `agent_list` 状态流转 —— 通过
|
|
101
|
-
|
|
102
|
-
`running → ready`(`ready` = 空闲可续聊,非终结态)。
|
|
103
|
-
|
|
104
|
-
### ✅ 3.10 A2A 上行 guard —— 通过
|
|
105
|
-
|
|
106
|
-
root 调 `tool.send_message(receiver='parent')` → 结构化错误:`only a live continuable child agent can report to its parent`(`authorizeReporter` 的 `UNAUTHORIZED` 路径,root 不具上行资格)。
|
|
107
|
-
|
|
108
|
-
### ✅ 3.11 REPL 语义 —— 通过
|
|
109
|
-
|
|
110
|
-
顶层 `return` → `SyntaxError: 'return' outside function`(parse 期即拒绝,符合原生 IPython cell 语义)。
|
|
111
|
-
|
|
112
|
-
### ⚠️ 3.12 `compact` 压缩 —— 本环境不可用
|
|
113
|
-
|
|
114
|
-
`tool.compact` 返回 `{'context_tokens': 88407, 'error': 'compact() is unavailable: no ctx.compaction engine is ...'}`——宿主 `ctx.compaction` 引擎未在本部署加载,压缩能力无实际效果。
|
|
115
|
-
|
|
116
|
-
### 🔴 3.13 snapshot 快照/恢复 —— 失效
|
|
117
|
-
|
|
118
|
-
见 §5/§6,根因是 `dill` 缺失。
|
|
119
|
-
|
|
120
|
-
---
|
|
121
|
-
|
|
122
|
-
## 4. 测试套件结果(`npm test` = `vitest --run`)
|
|
123
|
-
|
|
124
|
-
```
|
|
125
|
-
Test Files 5 failed | 13 passed (18)
|
|
126
|
-
Tests 8 failed | 155 passed (163)
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
失败分布(8 个失败,7 个集中在 snapshot):
|
|
130
|
-
|
|
131
|
-
| 文件 | 失败数 | 失败用例 |
|
|
132
|
-
|---|---|---|
|
|
133
|
-
| `test/snapshot-revive.spec.ts` | 4 | 全部(revive/降级/超限快照/over-cap) |
|
|
134
|
-
| `test/lifecycle.spec.ts` | 1 | dispose 时写快照 |
|
|
135
|
-
| `test/session-keys.spec.ts` | 1 | 每 principal 快照独立子目录 |
|
|
136
|
-
| `test/snapshot-restore.spec.ts` | 1 | eval 快照路径 + 恢复纯用户态 |
|
|
137
|
-
| `test/runtime.spec.ts` | 1 | **keep function docstrings intact**(非快照,单独问题) |
|
|
138
|
-
|
|
139
|
-
> 注:`npm test` 进程退出码为 0(vitest 失败但外层 bash 收 0),CI 若直接依赖退出码会**漏报失败**——建议核对 vitest 的 exit-code 配置。
|
|
140
|
-
|
|
141
|
-
---
|
|
142
|
-
|
|
143
|
-
## 5. 根因分析
|
|
144
|
-
|
|
145
|
-
### 5.1 snapshot 失效(7 个失败)—— 环境链式断裂
|
|
146
|
-
|
|
147
|
-
```
|
|
148
|
-
.venv-kernel/bin/python → /tmp/dashr-py311/bin/python3.11 (悬空,目标已删)
|
|
149
|
-
↓ 测试 helper: existsSync(悬空 symlink)=false → 回退 'python3'
|
|
150
|
-
↓ 内核运行在 Python 3.14.4(系统解释器)
|
|
151
|
-
系统 python3.14 已装 ipykernel 7.3.0,但 ❌ 无 dill
|
|
152
|
-
↓ snapshot/restore 依赖 dill.dump/dill.load(src/python.ts:163,242)
|
|
153
|
-
↓ dump 失败 → manifest.json 从未写出 → 测试 ENOENT / assertion 失败
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
即:**文档承诺的「Python 3.11 内核(uv venv)+ dill」部署前提在本机已失效**,运行时静默回退到 3.14.4 且缺 dill,导致快照功能整体不可用。
|
|
157
|
-
|
|
158
|
-
### 5.2 docstring 失败(1 个)—— 疑似 Python 3.14 行为变化
|
|
159
|
-
|
|
160
|
-
`runtime.spec.ts`「keeps function docstrings intact」断言 `helper.__doc__` 精确等于 `'First summary line.\n Details follow.'`,在 3.14 下不成立。与 5.1 同源(内核 Python 版本漂移),需在 3.11 下复验。
|
|
161
|
-
|
|
162
|
-
---
|
|
163
|
-
|
|
164
|
-
## 6. 问题清单(按严重度)
|
|
165
|
-
|
|
166
|
-
### 🔴 P0 — 快照功能整体失效
|
|
167
|
-
README「State Snapshot & Revival 💾 Full Namespace Snapshot (dill)」在当前环境不可用。需修复内核 Python 环境(重建 3.11 venv + `ipykernel dill`),或让运行时在缺 dill 时显式告警而非静默跳过。
|
|
168
|
-
|
|
169
|
-
### 🟠 P1 — docstring 回归
|
|
170
|
-
可能由 Python 3.14 引入;需在 3.11 内核下确认是否仍存在。
|
|
171
|
-
|
|
172
|
-
### 🟡 P2 — 文档/命名漂移(多处)
|
|
173
|
-
1. **`agent_message` vs `send_message`**:`CONTEXT.md` 术语表写 A2A 函数为 `agent_message(receiver, message, *, subagent_id)`,但 v0.1.8 实际桥接名为 **`send_message`**(`tool.send_message`)。实测 `tool.agent_message` → `unknown binding`。
|
|
174
|
-
2. **flat-global vs `tool.*`**:`CONTEXT.md`「Binding = flat global」及 `V0.1.5-development-plan.md`(Q8 平级 globals)描述的是旧形态;v0.1.8 已切换为统一 `tool.*` namespace,`rlm`/`agent_list` 等**不再是裸全局**(实测 `rlm(...)` 裸调用 → `NameError`)。
|
|
175
|
-
3. **`subagents-surface.ts` 头注释**仍描述「preset 的 entry-local `isolate: { replRuntime: true }` realm」旧架构;v0.1.8 已改为 HOST 平面全局挂载,注释过时。
|
|
176
|
-
4. **`@fgm-builds/dashr` vs `pgmi-builds`**:最近一次 commit(`ec7b844`)把 GitHub namespace 从 fgm-builds 改成 pgmi-builds,但 `package.json` 的 `name` 仍是 `@fgm-builds/dashr`,仅 `repository.url` 是 pgmi-builds,未同步。
|
|
177
|
-
5. **masking 数量**:ADR-0002 / V0.1.5 plan 写 7 个 masked 名,代码 `MASKED_TOOL_NAMES` 实际 **8 个**(多了 `report`)。
|
|
178
|
-
|
|
179
|
-
### 🟡 P3 — 观察项(供决策,非必然 bug)
|
|
180
|
-
1. **masking 对「直接 function-calling 面」无效**:ADR-0002 意图是「模型看不到这 7/8 个名」,但实测 masking 只作用于 REPL 内 `tool.*`;作为 dual-exposure(both 模式)副作用,`subagent`/`send_message`/`list_agents`/`interrupt_agent`/`workflow`/`ralph`/`subagent_fork` 仍出现在模型**直接可调用的工具面**。这是 both 模式与 masking 意图的结构性张力,需 maintainer 决策(是否要在直接面也收敛)。
|
|
181
|
-
2. **桥接工具错误风格不一致**:`rlm()` 参数校验失败返回**结构化 error 值**,`rlm_workflow()` 校验失败抛 **ToolCallError**,两种风格并存。
|
|
182
|
-
3. **README/描述措辞**:`package.json` description 写 `tool.*`,README 正文仍写 `tools.*`(复数,旧名),需统一。
|
|
183
|
-
4. **`compact` 依赖宿主压缩引擎**:本部署无 `ctx.compaction` 引擎,DASHR 的「Global Context Recency Window / compact」压缩能力未在此环境生效,需在目标部署形态下复验。
|
|
184
|
-
|
|
185
|
-
---
|
|
186
|
-
|
|
187
|
-
## 7. 建议
|
|
188
|
-
|
|
189
|
-
1. **优先修复内核环境**:重建 `.venv-kernel`(Python 3.11 + `ipykernel` + `dill`),消除悬空 symlink;否则快照功能与 7 个测试持续红灯。
|
|
190
|
-
2. **为缺 dill / 版本漂移加显式护栏**:运行时启动时探测 `dill` 与 Python 版本,缺依赖时降级快照并**告警到模型/日志**,而非静默跳过。
|
|
191
|
-
3. **同步文档与命名**:统一 `CONTEXT.md`(`agent_message`→`send_message`、flat-global→`tool.*`)、`subagents-surface.ts` 头注释、`package.json` `name`(fgm→pgmi)、README 的 `tools.*`→`tool.*`。
|
|
192
|
-
4. **明确 masking 边界**:在 dual-exposure 下重新定义「masking 语义」——是只收敛 REPL 内 `tool.*`,还是也要在直接工具面收敛,形成 ADR。
|
|
193
|
-
5. **CI 退出码**:核对 vitest 失败时是否向 CI 返回非零退出码,避免「红测试绿流水线」。
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
# DASHR v0.1.8b 实测报告(决策记录 + 待拿掉缺口清单)
|
|
2
|
-
|
|
3
|
-
> 状态:决策已定,代码待落地。本文为**需求移交文档**:本会话只做实测/记录,不动代码;后续开发 agent 按 §4 一次性改。
|
|
4
|
-
> 日期:2026-08-24
|
|
5
|
-
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## 0. 结论摘要
|
|
9
|
-
|
|
10
|
-
| 项 | 决策 |
|
|
11
|
-
|---|---|
|
|
12
|
-
| `refine`(Continual Harness) | 🔴 **移除**(本轮定) |
|
|
13
|
-
| `compact`(`tool.compact` 上下文压缩 REPL 桥接) | 🔴 **移除**(上轮已定) |
|
|
14
|
-
| `recency`(被动 recency 压缩引擎,后台 auto) | ✅ **保留** |
|
|
15
|
-
| `send_message`(A2A 双向桥接) | ✅ 保留 |
|
|
16
|
-
| `eval`(传输工具) | ✅ 保留 |
|
|
17
|
-
|
|
18
|
-
DASHR 自登记的工具从 4 个(eval + send_message + refine + compact)收敛为 **2 个(eval + send_message)**——即「DASHR 独有、原生工具链没有的」两个桥接(refine/compact)全部拿掉。
|
|
19
|
-
|
|
20
|
-
---
|
|
21
|
-
|
|
22
|
-
## 1. 决策一:移除 `refine`(本轮,2026-08-24)
|
|
23
|
-
|
|
24
|
-
`refine` 是抄 Prime Agent 的 **Continual Harness**(Prime Agent 三大支柱:RLM / Context as variable / Continual harness)。移除理由(用户定):
|
|
25
|
-
|
|
26
|
-
**1.1 定位与界限不清**
|
|
27
|
-
- `refine` 功能上接近「记忆 / 技能」(memory / skill)。
|
|
28
|
-
- Hermes、openclaw 这类 Persona Agent 已经在做 cross-session enhancement(harness 跨 session persist)。
|
|
29
|
-
- DASHR 在 runtime 内重组 System Prompt 确实难得;但**同 session 重组后 persist 下来,下个 session 也会带着这个 harness**——这混淆了 **cross-session(跨会话)** 与 **per-session real-time(会话内实时)** 的界限。
|
|
30
|
-
- 很多「当时当地有用」的配置并不该跨 session 固化;做 coding/项目的 agent,用户更倾向**每次唤醒时外围 harness 固定、可控**,需要调整再走别的机制。
|
|
31
|
-
- 核心未决问题:**Dash 的定位到底是 Persona Agent(人格体、跨会话增强),还是 CLI 式(每次唤醒执行独立新任务)?** 定位不清,refine 的语义就悬空。
|
|
32
|
-
|
|
33
|
-
**1.2 有效性待测**
|
|
34
|
-
- real-time harness 的作用有多大未验证。
|
|
35
|
-
- 它是在 runtime 内由**旁路大模型**做总结,且 persist over session——多一次推理、多一层持久状态,收益不明确。
|
|
36
|
-
- Memory / Skill 已经有外围插件填补了生态位;唯一缺口只是「不能在 runtime 内实时重组」,而「实时重组」目前看偏超前、有效性存疑。
|
|
37
|
-
|
|
38
|
-
**1.3 模型没空主动调它(用户补充)**
|
|
39
|
-
- 大模型几乎**每一个 turn、每一个 user prompt 都有任务要做**,不会「有心思」在 runtime 里主动去调用 refine 这种自我维护动作。
|
|
40
|
-
- 让模型在忙正事的同时抽空做 harness 重组,是天方夜谭;它只会专注手头任务。
|
|
41
|
-
|
|
42
|
-
**可逆性**:项目有 Git 版本控制,随时可切回 v0.1.6 或更早查看源码;上游 Prime Agent 也在做相关探索,届时可再引入。故本次**暂不引入 Refine**。
|
|
43
|
-
|
|
44
|
-
---
|
|
45
|
-
|
|
46
|
-
## 2. 决策二:移除 `compact`(上轮已定)
|
|
47
|
-
|
|
48
|
-
`compact` 是把宿主 `ctx.compaction` 引擎硬桥进 REPL 的 DASHR 独有桥接。移除理由:
|
|
49
|
-
- 上下文压缩是**宿主运行时的事**,不属于 REPL(REPL 是 Agent 运行时的「外部环境」)。
|
|
50
|
-
- 原生工具链根本没有 `compact` 工具(只有 CLI 命令 + 压缩引擎 service),DASHR 是「无中生有」映射进来的。
|
|
51
|
-
- 实测 `tool.compact` 一调就返回 `no ctx.compaction engine is mounted`(本部署未挂引擎),映射了也没意义。
|
|
52
|
-
- 程序逻辑上「既不桥接、也不屏蔽」最简洁——上游不提供,删掉即自然缺位。
|
|
53
|
-
|
|
54
|
-
> 注意:移除的是 `tool.compact` 这个**模型可见的 REPL 桥接**;被动 recency 压缩引擎(`RecencyAwareCompactionEngine`,`auto: true` 后台自动压)**保留**——两者是两回事(见 §4)。
|
|
55
|
-
|
|
56
|
-
---
|
|
57
|
-
|
|
58
|
-
## 3. 全量「待拿掉缺口」清单
|
|
59
|
-
|
|
60
|
-
| # | 缺口 | 类型 | 状态 |
|
|
61
|
-
|---|---|---|---|
|
|
62
|
-
| 1 | `compact` REPL 桥接(`compactCallable` + catalog + bindings) | 代码 | 🔴 待落地 |
|
|
63
|
-
| 2 | `refine` REPL 桥接(`refineCallable` + catalog + bindings) | 代码 | 🔴 待落地 |
|
|
64
|
-
| 3 | `refine` 连带 machinery:`refineModel` 配置、`dashr:harness` prompt 段、`src/refine.ts`、`src/harness-store.ts`(注:`compactModel`/`src/compaction-surface.ts`/`src/compaction/recency-engine.ts` 属 recency,**保留**) | 代码 | 🔴 待落地(随 1/2 一并) |
|
|
65
|
-
| 4 | `dashr/README.md` 中后段仍描述旧架构(`ipython` 传输、FLAT callables、`rlm`/`agent_list`/`rlm_workflow`/`rlm_ralph`、`dsh-rlm-mode`、`rlm-mode` preset、`dashr-kernel` isolate realm) | 文档 | 🟡 待修 |
|
|
66
|
-
| 5 | 根 `README.md` 完全未 rebrand(仍「RLM Plugin for dsh」+ `dsh-rlm-mode` badge + `rlm()` API) | 文档 | 🟡 待修 |
|
|
67
|
-
| 6 | 持久会话热升级插件后 Tool Catalog 不刷新(system prompt 残留 `rlm`/`agent_list` 等旧名) | 运行时 | 🟡 待修(新开会话自愈,属会话续接边界) |
|
|
68
|
-
|
|
69
|
-
---
|
|
70
|
-
|
|
71
|
-
## 4. 落地范围(已定稿:refine 删、recency 保留)
|
|
72
|
-
|
|
73
|
-
**移除 —— refine(Continual Harness):**
|
|
74
|
-
1. `BRIDGE_TOOL_SCHEMAS` 删 `refine` 条目(留 `send_message`)。
|
|
75
|
-
2. 删 `refineCallable` 函数 + bindings 装配处 `refine: refineCallable`。
|
|
76
|
-
3. 删 `src/refine.ts`、`src/harness-store.ts`(及其测试)。
|
|
77
|
-
4. 删 `refineModel` 配置项 + `resolveRefineTarget` + `requireLlm` 相关 wiring。
|
|
78
|
-
5. 删 `dashr:harness` prompt 段(refine 是唯一写入方,删后必然为空)。
|
|
79
|
-
|
|
80
|
-
**移除 —— compact(仅 `tool.compact` 桥接,不动 recency):**
|
|
81
|
-
6. `BRIDGE_TOOL_SCHEMAS` 删 `compact` 条目。
|
|
82
|
-
7. 删 `compactCallable` 函数 + bindings 装配处 `compact: compactCallable`。
|
|
83
|
-
|
|
84
|
-
**保留:**
|
|
85
|
-
- `send_message` 桥接(A2A 双向)。
|
|
86
|
-
- `eval`(传输核心)。
|
|
87
|
-
- **被动 recency 压缩引擎**:`src/compaction/recency-engine.ts`(`RecencyAwareCompactionEngine`,`auto: true` step 间自动压)+ `compactModel` 配置 + `src/compaction-surface.ts` + `scopedCompaction` wiring —— **全部保留**(被动压缩有用,且不占 REPL 面)。
|
|
88
|
-
|
|
89
|
-
---
|
|
90
|
-
|
|
91
|
-
## 5. 复测计划(落地后执行)
|
|
92
|
-
|
|
93
|
-
1. 跑 `npm test`(预期原 156 用例中,refine/compact/harness 相关 spec 删除或转绿)。
|
|
94
|
-
2. 实测 `tool.*` 面:`tool.refine` / `tool.compact` → `unknown binding`;`tool.send_message` / `tool.eval` 正常。
|
|
95
|
-
3. 确认 `refine`/`compact` 不再出现在 Tool Catalog。
|
|
96
|
-
4. 文档缺口(#4/#5)核对 README 是否对齐 v0.1.8b 实际形态。
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
# DASHR v0.1.8c 实测报告(URL Schema 第一人称实测)
|
|
2
|
-
|
|
3
|
-
> 状态:URL schema 已部署到运行时,但**部分生效**——本报告为实测记录 + 待修缺口清单,只做实测/记录,不动代码。
|
|
4
|
-
> 日期:2026-08-26
|
|
5
|
-
> 变更对象:`openspec/changes/url-schema/`(proposal + design + specs + impl-contract)
|
|
6
|
-
> 发布包:`@pgmi-builds/dashr@0.1.10`(`package.json` 已升 0.1.10;本 openspec change 沿用 v0.1.8c 标签)
|
|
7
|
-
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
## 0. 结论摘要
|
|
11
|
-
|
|
12
|
-
| 验收面 | 结果 | 一句话 |
|
|
13
|
-
|---|---|---|
|
|
14
|
-
| URL resolver + read 路由 | ✅ 生效 | `read` 能把 `scheme://` 分流到 handler |
|
|
15
|
-
| `skill://` | 🔴 坏 | `ctx.skills` 注册表空,与 prompt 里的 skill 目录不同源 |
|
|
16
|
-
| `agent://`(名册 / 输出 / transcript / child) | ✅ 生效 | 四形态返回真实内容;但名册字段与 spec 不符 |
|
|
17
|
-
| `history://` 并入 `agent://` | ✅ 生效 | 返回「已并入」提示 |
|
|
18
|
-
| `dsh://config` | ✅ 生效 | 返回 resolved settings,无 secret 泄漏 |
|
|
19
|
-
| `dsh://docs` | 🔴 坏 | `docs/` 没打进发布包,`resolveDocsDir` 从安装路径向上找不到 |
|
|
20
|
-
| `ctx://` 读 | 🔴 坏 | URL 分支传空 env,落到 `AGENTLESS_KEY` 空内核 |
|
|
21
|
-
| `ctx://` 写 | 🔴 未接线 | `writeCtxVar` 是死代码,`defaultSchemeWrite` 直接抛不支持 |
|
|
22
|
-
| `xd://` 读 + 写 | ✅ 生效 | 空占位行为与 spec 一致 |
|
|
23
|
-
| selector 语法(`:N-M` / `:raw` / …) | ✅ 生效 | `dsh://config:1-3` 正确按行截断 |
|
|
24
|
-
| 未注册 scheme 报错 | ✅ 生效 | 结构化报错并列出 `registered: agent, ctx, dsh, skill, xd` |
|
|
25
|
-
| mask `skill` 工具(D5) | 🔴 未生效 | 只挡 REPL 的 `tool.*` 面,host 层原生 `skill` + `<available_skills>` 仍在 |
|
|
26
|
-
| **`write` 普通路径(透传)** | 🔴 **回归** | **`write` 工具对工作区任意路径一律拒绝,只放行 `/tmp`;`read`/`edit`/bash 均正常** |
|
|
27
|
-
|
|
28
|
-
**净结果:6 个 scheme 里 3 个半生效(agent / dsh:config / xd + selector/history),2 个半坏(skill / ctx 读),1 个彻底坏(ctx 写),1 个配套改造(dsh:docs)坏,1 个 BREAKING(mask skill)未生效;另有 1 处**非 URL 路径 `write` 的回归**(破坏「普通路径透传」spec)。**
|
|
29
|
-
|
|
30
|
-
---
|
|
31
|
-
|
|
32
|
-
## 1. 部署状态确认(不是 stale host)
|
|
33
|
-
|
|
34
|
-
上一轮 v0.1.8c 实测结论是「stale host + BetterEdit shadow 冲突」。本轮复核**推翻该结论**:
|
|
35
|
-
|
|
36
|
-
- 运行时实际加载的 DASHR 包 = `~/.dsh/profiles/web/node_modules/@pgmi-builds/dashr`,`package.json` version `0.1.10`。
|
|
37
|
-
- 部署 `lib/index.js`(2026-08-26 04:22 构建,210482 字节)与工作区 `dashr/lib/index.js`(04:21)**逐字节一致**——是最新构建,非旧代码。
|
|
38
|
-
- `dashr/src/url-schema/` 源码完整(resolver / selector / handlers×5 / tools×4 / vendored hashline)。
|
|
39
|
-
- 5 个 handler **都已注册**(未注册 scheme 报错里列得全:`agent, ctx, dsh, skill, xd`)。
|
|
40
|
-
|
|
41
|
-
所以剩余问题**不是代码没跑起来,是部署接线/打包缺口 + 一处 write 回归**。
|
|
42
|
-
|
|
43
|
-
---
|
|
44
|
-
|
|
45
|
-
## 2. 逐项实测记录
|
|
46
|
-
|
|
47
|
-
> 以下均为本人(Dash Agent 运行时)直接调用自身 `read`/`write`/`grep`/`glob` 工具得到的第一人称结果。
|
|
48
|
-
|
|
49
|
-
| scheme / 面 | 调用 | 实际返回 |
|
|
50
|
-
|---|---|---|
|
|
51
|
-
| skill:// 存在名 | `read skill://markitdown` | `skill "markitdown" is unknown or no longer available`(markitdown 在 `<available_skills>` 里真实存在) |
|
|
52
|
-
| skill:// 不存在名 | `read skill://__nonexistent__` | 同上结构化报错 |
|
|
53
|
-
| agent:// 裸 | `read agent://` | 名册表 `id / origin / depth / cwd`(4 条 session) |
|
|
54
|
-
| agent://<id> | `read agent://<session-id>` | 返回该 agent 最后一条非空 assistant 输出文本 |
|
|
55
|
-
| agent://<id>/transcript | `read agent://<id>/transcript` | 返回完整 transcript(role-headed) |
|
|
56
|
-
| history:// | `read history://` | `history:// 已并入 agent://:…` |
|
|
57
|
-
| dsh://config | `read dsh://config` | 6296 字节 resolved settings JSON;`api` 命中全为端点 URL(`api.z.ai` 等),无 key/token/secret |
|
|
58
|
-
| dsh://docs | `read dsh://docs` | `dsh://docs: no docs directory found (provide docsDir to createDshHandler)` |
|
|
59
|
-
| ctx:// 裸 | `read ctx://` | 空串(空命名空间) |
|
|
60
|
-
| ctx://<var> | `read ctx://probe_marker` | `ctx://probe_marker: no such variable in the kernel namespace`(该变量在 eval 内核里真实存在) |
|
|
61
|
-
| ctx:// 写 | `write ctx://test_var` | `write to ctx:// is not supported (read-only scheme, or its write channel is not wired yet)` |
|
|
62
|
-
| xd:// 裸 | `read xd://` | `no devices mounted` |
|
|
63
|
-
| xd://<device> | `read xd://lsp` | `unknown device: lsp` |
|
|
64
|
-
| xd:// 写 | `write xd://lsp` | `xd:// write dispatch: no devices mounted to route the write to` |
|
|
65
|
-
| 未注册 scheme | `read http://example.com/x` | `no handler registered for scheme "http" (registered: agent, ctx, dsh, skill, xd)` |
|
|
66
|
-
| selector | `read dsh://config:1-3` | 按 1–3 行截断返回 |
|
|
67
|
-
| grep/glob scheme | `grep skill://markitdown`、`glob skill://markitdown/**` | 均因 skill 未知而报错(路由生效,handler 上游失败) |
|
|
68
|
-
| read 普通文件 | `read docs/.__editprobe.md` | 正常返回 `HASH│content` 锚点 |
|
|
69
|
-
| edit 普通文件 | `edit`(先 read 后 edit) | 正常改写,锚点随内容更新 |
|
|
70
|
-
| **write 普通文件** | `write /home/u1/workspaces/dashr/docs/test-ascii.md` | `cannot write "…": file access denied under workspace-write mode` |
|
|
71
|
-
| **write 工作区根** | `write /home/u1/workspaces/dashr/test-root.md` | 同上被拒 |
|
|
72
|
-
| **write /tmp** | `write /tmp/dashr-test.md` | 成功 `{operation: 'create'}` |
|
|
73
|
-
| **bash 写工作区** | `printf … > docs/.__probe.md` | 成功(OS/bash 层不受影响) |
|
|
74
|
-
|
|
75
|
-
---
|
|
76
|
-
|
|
77
|
-
## 3. 失效点根因(已定位到源码)
|
|
78
|
-
|
|
79
|
-
1. **`skill://`** —— `dashr/src/url-schema/handlers/skill.ts` 查 `ctx.skills.get(name)`(`@deepseek-ai/dsh-skill` 的 `SkillRegistry`),但该注册表**为空**,与注入 prompt 的 harness session skill 目录(`<available_skills>`)不是同一来源。skill handler 本身逻辑正确(错误分支、`/path` 资源寻址、路径逃逸守卫都在),只是上游 `ctx.skills` 没被喂进实际可用的 skill。
|
|
80
|
-
|
|
81
|
-
2. **`dsh://docs`** —— `dashr/src/url-schema/index.ts` 的 `resolveDocsDir()` 从 `import.meta.url` 向上找 `docs/`。发布包 `@pgmi-builds/dashr` 里**没有 `docs/`**(`docs/` 在仓库根 `/home/u1/workspaces/dashr/docs`,位于包根 `dashr/` 之外,未进 npm 包)。运行时从 `~/.dsh/profiles/web/node_modules/...` 加载,向上走到 `/` 也够不着仓库里的 docs。dev 布局(`dashr/lib/index.js` 向上能到 `/home/u1/workspaces/dashr/docs`)能跑通,装进 node_modules 就断——纯打包缺口。
|
|
82
|
-
|
|
83
|
-
3. **`ctx://` 读** —— `dashr/src/url-schema/tools/read.ts` 的 URL 分支调 `resolver.resolve({}, rawPath)`,传**空 env**;`handlers/ctx.ts` 随之 `queryVar(name)` 不传 `principal`,`runtime.ts:393` 落到 `AGENTLESS_KEY`(共享默认内核)——而 eval cell 跑在**会话 principal 键**的内核上。所以永远读一个没人用的空内核,真实存在的变量也报 missing。对比:文件分支正确用了 `execSessionKey(exec)`,URL 分支没传。
|
|
84
|
-
|
|
85
|
-
4. **`ctx://` 写** —— `dashr/src/url-schema/tools/write.ts` 的 `defaultSchemeWrite` 对除 `xd` 外一律抛 `URL_WRITE_UNSUPPORTED`;`handlers/ctx.ts` 里已写好的 `writeCtxVar` 是**死代码**(`index.ts` 装 write 工具只传 `{ nativeWrite }`,没传 `writeScheme` 把 `ctx://` 路由到 `writeCtxVar`)。
|
|
86
|
-
|
|
87
|
-
5. **mask `skill`(D5)** —— `dashr/src/index.ts:154` 的 `MASKED_TOOL_NAMES` 确实含 `'skill'`,但它只作用于 REPL 自己的 `tool.*` 绑定面(`index.ts:761`)+ Tool Catalog(`index.ts:901`),所以 eval cell 里 `tool.skill` 确实没了;但**挡不住 host 层注入的原生 `skill` 工具 + `<available_skills>` 目录**,模型从原生工具面照样能看见并调用 `skill`。验收项「工具目录不含 skill」未达成。
|
|
88
|
-
|
|
89
|
-
6. **`write` 普通路径回归(新增)** —— 设计 D2 明确「不替换 write(write 保留原生,只挂 write-hook 装饰结果)」,但 v0.1.10 实际用 `tools/write.ts` 的 `createWriteTool` 以 `name: 'write'` **shadow 了原生 write**,其 `nativeWrite` 直接 `ctx.fs.resolve(...)` + `ctx.fs.writeText(...)`,**没走原生 write 工具的 write-intent 政策门**,于是对工作区路径被 sandbox 拒绝(`file access denied under workspace-write mode`),只放行 `/tmp`。对比:`read`/`edit` 走 vendored hashline 的 fs-bridge(含 `fs/write-intent` + `fs/observed` 政策门),工作区读写正常;bash 也正常。**这直接违反 spec「普通路径透传」——非 scheme 的 `write` 行为与引入 URL schema 之前不一致。**
|
|
90
|
-
|
|
91
|
-
---
|
|
92
|
-
|
|
93
|
-
## 4. 一处 spec 偏差(非阻断)
|
|
94
|
-
|
|
95
|
-
`agent://` 名册 schema 与 spec 不符:
|
|
96
|
-
|
|
97
|
-
- `specs/agent/spec.md` 要求:`id / status / kind / parent / last activity`
|
|
98
|
-
- `handlers/agent.ts` 的 `renderRoster` 实际:`id / origin / depth / cwd`
|
|
99
|
-
|
|
100
|
-
字段语义对不上(`origin`≠`kind`、`depth`≠`parent`、缺 `status`/`last activity`、多了 `cwd`)。
|
|
101
|
-
|
|
102
|
-
---
|
|
103
|
-
|
|
104
|
-
## 5. 最小修复清单
|
|
105
|
-
|
|
106
|
-
| # | 缺口 | 落点 | 类型 |
|
|
107
|
-
|---|---|---|---|
|
|
108
|
-
| 1 | URL 分支透传会话 `principal`(复用 `execSessionKey(exec)`)给 `queryVar`/`setVar` | `tools/read.ts`、`handlers/ctx.ts`、resolver env | 代码 |
|
|
109
|
-
| 2 | write 工具接上 `writeScheme`,把 `ctx://` 路由到 `writeCtxVar` | `tools/write.ts`、`index.ts` `installAgentTools` | 代码 |
|
|
110
|
-
| 3 | `ctx.skills` 注册表与 harness session skill 目录同源(或 skill handler 改读 `<available_skills>` 来源) | `handlers/skill.ts`、`index.ts` 接线 | 代码 |
|
|
111
|
-
| 4 | `docs/` 收进发布包(`package.json` files / 或 `docsDir` 指向随包路径) | `index.ts` `resolveDocsDir`、打包配置 | 打包 |
|
|
112
|
-
| 5 | mask `skill` 到 host 注入层(非只 REPL `tool.*` 面) | host 层 / `index.ts` mask 机制 | 代码 |
|
|
113
|
-
| 6 | `agent://` 名册字段对齐 spec(id/status/kind/parent/last activity) | `handlers/agent.ts` `renderRoster` | 代码/文档 |
|
|
114
|
-
| 7 | **修复 `write` 普通路径回归**:native 分支走原生 write-intent 政策门(或直接委托上游原生 write),而非裸 `ctx.fs.writeText` | `tools/write.ts` `nativeWrite`、`index.ts` | 代码 |
|
|
115
|
-
|
|
116
|
-
---
|
|
117
|
-
|
|
118
|
-
## 6. 复测计划(修复后执行)
|
|
119
|
-
|
|
120
|
-
1. `read skill://<真实 skill 名>` 返回正文;`skill://<name>/<path>` 返回内部资源;未注册名结构化报错。
|
|
121
|
-
2. 原生工具面不再出现 `skill`(且 `<available_skills>` 保留为发现层)。
|
|
122
|
-
3. `read dsh://docs` 返回文档清单,`dsh://docs/<doc>` 返回正文。
|
|
123
|
-
4. eval 里 `x = 1` 后 `read ctx://x` 返回 `1`;`write ctx://y` 后 `read ctx://y` 返回新值。
|
|
124
|
-
5. `read ctx://` 列出命名空间(含刚写的 y)。
|
|
125
|
-
6. `agent://` 名册含 status/kind/parent/last activity。
|
|
126
|
-
7. **`write <工作区普通路径>` 成功(回归修复)**。
|
|
127
|
-
8. 回归:`read`/`write`/`grep`/`glob` 普通路径 + hashline 锚点无回归;`npm test` 全绿。
|
|
@@ -1,150 +0,0 @@
|
|
|
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 中被掩工具为何原生直调可达。
|