@a9i5k4/dsh-auto-memory 2.5.3 → 3.0.0

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 (104) hide show
  1. package/README.md +171 -1
  2. package/README.zh-CN.md +171 -1
  3. package/docs/CONTRIBUTORS.html +471 -0
  4. package/docs/HANDOFF-CRITERIA.md +92 -0
  5. package/docs/INTEGRATION-ANALYSIS.md +350 -348
  6. package/docs/USER-GUIDE.en.md +56 -1
  7. package/docs/USER-GUIDE.zh-CN.md +57 -2
  8. package/docs/internal/ACCEPT-35-LIVE.md +143 -0
  9. package/docs/internal/ACCEPTANCE-20260914.md +90 -0
  10. package/docs/internal/ARCH-REVIEW-BRIEF.md +411 -0
  11. package/docs/internal/ARCH-REVIEW-REQUEST.md +201 -0
  12. package/docs/internal/ARCH-REVIEW-ROUND2.md +169 -0
  13. package/docs/internal/ARCH-REVIEW-ROUND3.md +206 -0
  14. package/docs/internal/AUDIT-WB-GRAPH-FULL-20260916.md +314 -0
  15. package/docs/internal/CONCURRENCY-INVESTIGATION-20260917.md +192 -0
  16. package/docs/internal/CROSS-SESSION-SEARCH-PATH-DECISION.md +72 -0
  17. package/docs/internal/CROSS-SESSION-SEARCH-RESEARCH.md +131 -0
  18. package/docs/internal/DECISIONS-20260914-SESSION.md +269 -0
  19. package/docs/internal/DESIGN-P1-STATE-COMMIT-20260915.md +219 -0
  20. package/docs/internal/DIRECTION-CHECK-WB-GRAPH-20260916.md +132 -0
  21. package/docs/internal/FEEDBACK-TO-DSHAPI-RELAY.md +13 -0
  22. package/docs/internal/GH-DISCUSSION-5732-COMMENT.md +74 -0
  23. package/docs/internal/GPT-ACCEPTANCE-PROMPT-20260916.md +352 -0
  24. package/docs/internal/GPT-REVIEW-PROMPT.md +216 -0
  25. package/docs/internal/GROUP-WEBHOOK-SETUP.md +33 -0
  26. package/docs/internal/KICKOFF-P0.md +254 -0
  27. package/docs/internal/MASTER-PLAN-3.0.md +411 -0
  28. package/docs/internal/MEMORY-MUTATION-AND-INDEX-DESIGN.md +85 -0
  29. package/docs/internal/MERGE-CONFLICT-SCAN-20260914.md +222 -0
  30. package/docs/internal/PENDING-FIXES-20260916.md +289 -0
  31. package/docs/internal/RAG-KARPATHY-PROGRAM.md +229 -0
  32. package/docs/internal/REPORT-P0-NIGHTLY.md +212 -0
  33. package/docs/internal/REPORT-P5-ACCEPTANCE.md +31 -0
  34. package/docs/internal/REPORT-WB-GRAPH-NIGHTLY.md +153 -0
  35. package/docs/internal/REVIEW-WB-GRAPH-SELF.md +81 -0
  36. package/docs/internal/ROADMAP-20260917-WEEK.md +305 -0
  37. package/docs/internal/ROADMAP.md +106 -0
  38. package/docs/internal/RUN-P0-NIGHTLY.md +227 -0
  39. package/docs/internal/S10-CONSTRUCTION-HANDOFF-20260917.md +175 -0
  40. package/docs/internal/S10-GAPS-PLAIN-20260917.md +125 -0
  41. package/docs/internal/SEMANTIC-ARCHITECTURE-SPEC.md +360 -0
  42. package/docs/internal/SESSION-FILE-REPAIR-PROTOCOL.md +90 -0
  43. package/docs/internal/THREE-LAYER-CONTRACT.md +210 -0
  44. package/docs/internal/TODO-BACKLOG.md +263 -142
  45. package/docs/internal/TODO-GRAPH.html +715 -0
  46. package/docs/internal/TODO-GRAPH.html.bak-20260914-v2 +493 -0
  47. package/docs/internal/TODO-GRAPH.html.bak-20260915-alsfix +710 -0
  48. package/docs/internal/TODO-GRAPH.html.bak-20260915-p1 +710 -0
  49. package/docs/internal/TODO-GRAPH.html.bak-20260915-p6a-rev +703 -0
  50. package/docs/internal/TODO-GRAPH.html.bak-20260915-wshint +710 -0
  51. package/docs/internal/TODO-GRAPH.html.bak-20260916-batch +715 -0
  52. package/docs/internal/WB-FORMAT-CONVENTION.md +112 -0
  53. package/docs/internal/WB-GRAPH-DECISIONS-20260914.md +71 -0
  54. package/docs/internal/reviews/CLAIM-VERIFICATION-20260914.md +56 -0
  55. package/docs/internal/reviews/PLAN-gpt6astra-round2-20260914.md +787 -0
  56. package/docs/internal/reviews/REVIEW-gpt6astra-20260914.md +112 -0
  57. package/docs/internal/reviews/ROUND3-REVIEW-INTEGRATION-20260914.md +230 -0
  58. package/docs/prompts/M8-3-enable-verify.md +49 -49
  59. package/lib/acceptance.js +71 -0
  60. package/lib/activation-host.js +90 -9
  61. package/lib/activation-inbox.js +25 -7
  62. package/lib/board-mode.js +30 -0
  63. package/lib/client.js +878 -75
  64. package/lib/context-bridge.js +2 -2
  65. package/lib/context-host.js +70 -6
  66. package/lib/engine-identity.js +149 -0
  67. package/lib/engine-switch.js +247 -0
  68. package/lib/episodic-store.js +11 -10
  69. package/lib/evidence-store.js +2 -2
  70. package/lib/fact-store.js +1 -1
  71. package/lib/fs-retry.js +46 -0
  72. package/lib/index.js +1987 -153
  73. package/lib/intent-clean-safe.js +40 -0
  74. package/lib/intent-clean.js +12 -16
  75. package/lib/l0-extract.js +263 -149
  76. package/lib/l0-index-sync.js +195 -0
  77. package/lib/l0-index.js +349 -239
  78. package/lib/ledger-criteria.js +142 -0
  79. package/lib/m7-index-sync-host.js +65 -4
  80. package/lib/m7-wire.js +3 -3
  81. package/lib/memory-anchor.js +56 -1
  82. package/lib/memory-envelope.js +252 -0
  83. package/lib/memory-hub.js +14 -4
  84. package/lib/memory-mutation.js +246 -0
  85. package/lib/memory-writer.js +204 -24
  86. package/lib/procedure-observation.js +48 -0
  87. package/lib/procedure-store.js +34 -17
  88. package/lib/python-setup.js +1 -1
  89. package/lib/rerank-host.js +160 -0
  90. package/lib/rules-layer.js +261 -0
  91. package/lib/semantic-js.js +15 -0
  92. package/lib/shadow-retrieval.js +3 -3
  93. package/lib/state-commit.js +245 -0
  94. package/lib/subagent-gc.js +4 -8
  95. package/lib/tier-layer-inject.js +650 -0
  96. package/lib/tier0-catalog.js +693 -0
  97. package/lib/water-window.js +263 -186
  98. package/lib/wb-contract.js +495 -0
  99. package/lib/wb-sidecar.js +839 -0
  100. package/lib/ws-overview-rank.js +2 -2
  101. package/package.json +1 -1
  102. package/python/m7_embedding_v1.py +5 -5
  103. package/python/worker_semantic_v1.py +17 -6
  104. package/python/worker_v1.py +38 -4
@@ -0,0 +1,153 @@
1
+ # REPORT · WB-GRAPH 白板线一夜完工(2026-09-16 凌晨)
2
+
3
+ > 权威依据:`WB-GRAPH-DECISIONS-20260914.md` §E(拍板留痕)+ `WB-GRAPH-INTEGRATION-PLAN.md` §5 + `WB-FORMAT-CONVENTION.md` v1
4
+ > 用户裁定:一口气全做完,但**线先别接**——设置页/接续面板一键切换「旧版白板 / 新版看板」,默认旧版。
5
+
6
+ ## 交付总览
7
+
8
+ | # | 交付物 | 状态 |
9
+ | --- | --- | --- |
10
+ | ① | `board_mode_pre_v1` 总开关(`lib/board-mode-pre.js`):legacy(默认)/ graph,非法值 fail closed | ✅ |
11
+ | ② | P1 判据门对账 + 单一真源再导出(`lib/ledger-criteria-pre.js`) | ✅ 10/10 |
12
+ | ③ | P2 sidecar(`lib/wb-sidecar-pre.js` + index.js 两咽喉挂接):index.json 完全可重建 | ✅ 10/10 |
13
+ | ④ | P3 两遍历工具 `memory_expand_pre`/`memory_trace_pre`(仅 graph 档注册,工具数 14→16) | ✅ |
14
+ | ⑤ | dsh-graph v0.11.0 vendor 搬入(`vendor/dsh-graph/`,MIT 留痕 NOTICE-VENDOR.md) | ✅ |
15
+ | ⑥ | GUI 一键切换(设置页双按钮 + 接续面板快捷键,同键 boardMode,即时回显) | ✅ |
16
+ | ⑦ | 验收套件 `smoke-test-p1-ledger-criteria-pre.mjs` / `smoke-test-p23-wb-sidecar-pre.mjs` | ✅ 10+10 |
17
+
18
+ ## 验证证据
19
+
20
+ - 定向套件:P1 判据 **10/10**、P2/P3 sidecar **10/10** 全绿。
21
+ - 变异演示(`artifacts/_mutate-p23-sidecar.mjs`):**3/3 真失败**(删工具注册/tag 丢前缀/撤 sidecar 闸门),SHA256 逐字节还原。
22
+ - **全量回归:PASS 95 / FAIL 0 / TIMEOUT 0(145.4s)**,套件 92→95,零破坏。
23
+ - 施工中发现并修复 2 处抽取式测试套件缺 sidecar 桩(`smoke-test-handoff-pre.mjs` / `smoke-test-p7-write-fix-pre.mjs`,fake engine 无 `writeSidecarEntryPre` → TypeError);修复后 53/53、40/40。
24
+
25
+ ## 关键勘误(施工实测推翻方案假设)
26
+
27
+ 1. **P1 判据门主体在 P0 已交付**:`wb-contract-pre.js` 已实现 H1-H4/S1-S4,`checkMutationPre`(index.js:1990)已接线两咽喉 + skipCriteria 降级 + 丢卡门 + 人机分区——本窗口=对账验证+转发再导出,不重复造轮。
28
+ 2. tag 提取须**保留前缀**(`type:dead-end` 整串),否则 expand 按 tag 查不到(M3 变异实证)。
29
+ 3. 抽取式套件(bindMethod 沙箱)的 fake engine 需与新方法同步补桩——新增引擎方法时要排查所有 `bindMethod('async write…')` 套件。
30
+
31
+ ## 用户使用方式
32
+
33
+ - **默认**:什么都不做 = 旧版白板,行为与 3.0 收官时完全一致(sidecar 不写、新工具不注册、graph_* 不激活)。
34
+ - **切新版**:设置页「记忆窗口→白板模式」或接续面板按钮 → 「新版看板(dsh-graph)」→ 重启 dsh web(用户自行重启)→ 生效:P2 sidecar 开始写 `handoff/index.json`、`memory_expand_pre`/`memory_trace_pre` 注册(14→16)。dsh-graph vendor 的 cordis 接线步骤见 `vendor/dsh-graph/NOTICE-VENDOR.md`(需在 profile patch 加 insert 行,升级动作待用户明示)。
35
+ - **回滚**:切回「旧版白板」+ 重启 = 完全回滚;sidecar 是派生物,删 `handoff/index.json` 不丢任何信息。
36
+
37
+ ## 未做与待用户(如实)
38
+
39
+ - dsh-graph cordis patch 接线(profile 层动作,涉及用户配置文件,待用户明示节奏)。
40
+ - T6-7 发行产物测试、compat-U1 实测(沿用 P5 结论,releaseReady=false 不变)。
41
+ - 代码全部 pre 线,未 commit/push/publish。
42
+
43
+ ---
44
+
45
+ # 勘误节 · 次日全量复检与修复(2026-09-16 白天)
46
+
47
+ > 触发:用户指出「15 号下午到 16 号凌晨的修改比较不严谨」,要求全量粗检 + 修 bug + 与规划对账。
48
+ > 本节**追加**、不修改上文(保留当时的判断,便于回溯)。
49
+
50
+ ## 一、上文三处结论被实测推翻
51
+
52
+ | 上文原文 | 实测结论 | 证据 |
53
+ | --- | --- | --- |
54
+ | ③「P2 sidecar:index.json **完全可重建**」✅ | **不成立**。write 与 rebuild 两条路径算出**两个不同 id**(write 传 `path.relative` 反斜杠 + title 含 `handoff-` 前缀;rebuild 传正斜杠 + 去前缀)⇒ 同一条目在索引里出现两份 | `artifacts/_audit-id-repro.mjs`:write id `mem_95fc2c2404de55c0…` ≠ rebuild id `mem_7329b82cde69f937…` |
55
+ | ④「P3 两工具(仅 graph 档注册,工具数 14→16)」✅ | **永不注册**(两道独立致命缺陷叠加):① `apply()` **非 async** 且 cordis **不 await 其返回值**,构建 tools 时 `engine.config` 仍是构造期默认 `legacy` ⇒ 闸门恒假;② 闸门块里的 `defineTool(...)` 返回值**从未 push 进 tools 数组**(数组已在 `]` 处闭合) | `dsh-cordis-host-runner/lib/index.js` 的 `guardedPlugin`(`return objectPlugin.apply(...)`,无 await)+ 探针;修复后 graph 档实测 **16 tools** |
56
+ | ⑥「GUI 一键切换…即时回显」✅ | **设置页那条路径不落盘**:`pick()` 只改本地 React 态再 `location.reload()`,配置从未写到服务端 ⇒ 刷新后回跳原档,用户会判定"开关坏了" | 代码对照:接续面板走 `saveConfigPatch({boardMode})`(正确),设置页走 `set()`(缺陷) |
57
+ | ⑤「dsh-graph vendor 搬入」✅ | ✅ **成立**(唯一经受住复检的一条) | 目录与 `NOTICE-VENDOR.md` 均在,默认关闭声明完整 |
58
+
59
+ ## 二、复检新发现(自审与首次交付均漏报)
60
+
61
+ - **BUG-15(致命,本轮新发现)**:即上表第二行的第 ② 条缺陷。**它比 BUG-1 更隐蔽**——修好「读到真配置」也仍然不注册;若不是补了 graph 档端到端套件,这条会带着"已修复"的标签活到发布。
62
+ - **BUG-12/13/14**:遍历工具返回契约与工具描述不符(缺 `preview/mtime/cues/criteria`);`index.json` 缺 `by_tag/by_cue/versions/ws` ⇒ 工具描述承诺的「版本链」**根本没有数据可返回**;tag 正则漏采中文标点紧邻写法(`(topic:登录流程)` → `[]`)。
63
+ - **BUG-2/4/8**:遍历工具用不存在的 `agent.cwd` 取路径(应为 `await this.resolvePaths(agent)`);`this.wsDirKey` 不存在(真名 `wsKey(ws)`,且对 `projectDir` 而言 `basename` 恰好恒等);tag 无命中时没有词法回落。
64
+ - **结构性**:`WB-FORMAT-CONVENTION §2` 的锚点**从未写进 Markdown**(只写进 sidecar)⇒ 规范承诺的"白板自动进 L0 语料"收益恒为零。
65
+
66
+ ## 三、为何「全量回归 PASS 95 / FAIL 0」没抓到上面任何一条
67
+
68
+ 这是本次最值得留档的一条**方法论教训**:
69
+
70
+ 1. 新工具全部挂在 `boardMode==='graph'` 闸门后,而**回归整体跑 legacy 档** ⇒ graph 分支**一行都没执行**;
71
+ 2. P23 套件的 M6 只比「**同源 rebuild 自洽**」(拿 rebuild 的输出和 rebuild 比),抓不到 write≠rebuild;
72
+ 3. M7 端到端**手工拼 `index.json`**,绕过了引擎两个咽喉 ⇒ 接线通不通它不知道;
73
+ 4. `client.js` 是浏览器侧,套件只做了源码字符串守卫(M10)⇒ 逻辑错也照样绿。
74
+
75
+ ⇒ **结论:绿灯不是证据,覆盖率才是。** 本轮据此新增 `smoke-test-graph-mode-pre.mjs`(graph 档端到端,**13/13**),它一跑就抓出 BUG-15。
76
+
77
+ ## 四、本轮修复清单(落点到函数名)
78
+
79
+ | # | 缺陷 | 修复落点 |
80
+ | --- | --- | --- |
81
+ | 1 | 闸门读到默认配置 | 新增 `MemoryEngine.loadConfigSync()`(与 `loadConfig` 共用 `_mergeConfigPre`);`apply` 构建 tools 前调用 |
82
+ | 2 | 注册返回值被丢弃 | `apply` 内 `tools.push(defineTool(...))` |
83
+ | 3 | write/rebuild 两个 id | 新增 `wbRefPre()` 作**唯一构造口径**;`writeSidecarEntryPre` / `rebuildSidecarIndexPre` 共用 |
84
+ | 4 | 契约缺字段 | `buildSidecarEntryPre` / `rebuildSidecarIndexPre` 补齐 §3.3+§4.1 全字段 |
85
+ | 5 | tag 正则漏采 | `extractTagsPre` 改左边界判定(拒绝 `xxxtype:` 假阳性,接受中文标点紧邻) |
86
+ | 6 | 路径取错 | `expandWhiteboardByTagPre` / `traceWhiteboardByIdPre` 改走 `resolvePaths` |
87
+ | 7 | 死分支 | 新增 `wbWsKeyPre(projectDir)` 并注明恒等依据 |
88
+ | 8 | 无词法回落 | `expandWhiteboardByTagPre` 无命中时回落 `searchHandoffCorpus` |
89
+ | 9 | 锚点从未写入 | 新增 `applyAnchorsPre()`(纯函数、幂等、重排不变 id);两咽喉在 graph 档写入 |
90
+ | 10 | events.jsonl 未实现 | 新增 `appendSidecarEventPre()`;两咽喉写入后追加事件 |
91
+ | 11 | 设置页不落盘 | `client.js` 的 `pick()` 改走 `saveConfigPatch(…, {onSaved, onError})` |
92
+ | 12 | 面板看不到 sidecar | `handoffPanelData` 的 `fileQ` 白名单放行 `index.json` / `events.jsonl`(仍是枚举式,不通配) |
93
+
94
+ **关于 P3-3(三处工具数硬锁 14→16)的一处主动偏离**:规划写这条时**闸门还不存在**。现设计要求「legacy 默认档字节级不变」⇒ 三处硬锁**保持 14**,graph 档的 16 由新套件独立断言。这是对规划的**有意修正**,不是漏做。
95
+
96
+ ## 四点五、P2/P3 输入端与检索端补线(2026-09-16 第二批)
97
+
98
+ 第一轮审计的结论是「白板线只做完**存储/写入**半边,**消费/检索**半边整体缺失」。本批补齐这半边,**默认仍走 legacy**。
99
+
100
+ | 项 | 规划原文要求 | 本次落点 | 验证 |
101
+ | --- | --- | --- | --- |
102
+ | **P0-1** | 新建 `docs/HANDOFF-CRITERIA.md`(判据表 + 正反例 + 引用关系) | 新文件(H1-H4/P-H1/P-S1 全表 + 正反例 + 5 处引用关系) | 文件存在 |
103
+ | **P2-3** | `searchHandoffCorpus` 升 **tag/段级优先 + 词法兜底** | 改为**两段式**:结构化臂消费 `by_tag`/`by_cue` 倒排(label `白板结构化/<source> [<id8>]`),词法臂原样保留作兜底 | E3 |
104
+ | **P2-4** | 注入端锚点表区扩展 **tag 摘要行** | `buildContinueCarry` 内调 `whiteboardTagMapPre(null, p)` 注入「【白板 tag 地图(结构化导航)】」+ 工具用法提示 | E1 |
105
+ | **P2-5** | GUI 加 **tag/段视图**;fileQ 放行 `.json` | 后端 `handoffPanelData` 返回 `structured`(tags 倒排 + 按 kind 段视图)与 `boardMode`;前端**条件渲染**两张卡 | E4 |
106
+ | **P3-2** | 第3层 guide 加**唤醒句** | 注入「【白板结构化检索(优先于通读第3层)】」并点名两工具与参数 | E2 |
107
+ | 白板页切换按键 | — | 复核确认**已存在**(`switchCard` 内 `data-dam-key: 'boardMode'`,走 `saveConfigPatch` + `location.reload`) | E5 |
108
+
109
+ **闸门纪律**:P2-3/P2-4/P3-2 与 `structured` **全部只在 `boardMode==='graph'` 生效**;
110
+ legacy 档注入文本与面板返回结构**逐字节不变**(后端 `structured:null` + 前端 `if (data.structured)` 双重保证)。
111
+
112
+ ### 变异演示(第二批,3/3 真失败,逐字节还原)
113
+
114
+ | 变异 | 期望 | 实测 |
115
+ | --- | --- | --- |
116
+ | ① P2-4 调用点改成常量(退回「只定义不调用」) | E1 红 | **exit=1**,`实为 0 处` |
117
+ | ② 删掉 P3-2 唤醒句文案 | E2 红 | **exit=1**,`唤醒句不在场` |
118
+ | ③ 前端条件渲染改 `if (true)`(legacy 也渲染) | E4 红 | **exit=1**,`必须条件渲染` |
119
+
120
+ 三次变异后 `lib/index.js` 与 `lib/client.js` **SHA256 均逐字节还原**。
121
+
122
+ ### 套件
123
+
124
+ `smoke-test-graph-mode-pre.mjs` **13 → 18 断言**(新增 E1-E5)。
125
+ 新增断言的**口径**值得记录:这四条缺陷的共同特征是「**函数写了但没人调用**」——无副作用,任何行为测试都测不出来。
126
+ 所以 E 组断言的是**调用点在场**(`this.whiteboardTagMapPre(` 出现次数 ≥1、唤醒句字面量在场、`if (data.structured)` 在场),
127
+ 而不是「函数存在」。
128
+
129
+ ### 回归
130
+
131
+ **全量回归 PASS 96 / FAIL 0 / TIMEOUT 0(149.9s)**,无 BOM。
132
+
133
+ ## 五、验证
134
+
135
+ - 新增套件 `smoke-test-graph-mode-pre.mjs`:**13 passed / 0 failed**(含 A1 graph=16、D1 legacy=14、D2 非法值 fail-closed=14、C1 两路径同 id、B6 锚点幂等/重排/改名)。
136
+ - 既有套件 P23 的 M9 断言语式随 BUG-15 修复同步更新(从「裸 `defineTool` 在场」升级为「`tools.push(defineTool(...))`」——前者会被注释骗过)。
137
+ - 补 2 处抽取式沙箱缺桩(`handoff-pre` / `p7-write-fix` 的 fake engine 加 `appendSidecarEventPre`)——**同类坑第二次踩**,已在本节留档。
138
+ - **全量回归:PASS 96 / FAIL 0 / TIMEOUT 0(143.2s)**,套件 95→96(新增 graph 套件),零破坏。
139
+
140
+ ### 变异演示(§6 交付纪律:新增守卫必须演示变红后按字节还原)
141
+
142
+ | 变异 | 期望 | 实测 |
143
+ | --- | --- | --- |
144
+ | ① 把 `tools.push(defineTool('memory_expand_pre'…))` 还原成裸 `defineTool(…)`(BUG-15 复发) | graph 套件变红 | **exit=1,真失败** |
145
+ | ② 删掉 `engine.loadConfigSync()` 调用(BUG-1/11 复发) | graph 套件变红,且应看到 `ready: engine + 14 tools`(回落 legacy) | **exit=1,真失败**;A1/A2/A3 三条同时红,日志实证退化为 14 工具 |
146
+
147
+ 两次变异后 `lib/index.js` **SHA256 逐字节还原**(`0E36650A08DF616B19C46CE65AD110CD72C8FD3BFFD86AEEFE916A0A6026898B`)。
148
+
149
+ ## 六、仍未做(如实)
150
+
151
+ - dsh-graph profile 接线:**用户裁定「先不接线,先把 memory 侧修干净」**,故本轮不碰 `~/.dsh/profiles/web/`。
152
+ - 三处工具数硬锁仍为 14:系上节所述**有意偏离**。
153
+ - 全量回归复跑结果见本轮对话记录(本节写作时后台进行中)。
@@ -0,0 +1,81 @@
1
+ # REVIEW · WB-GRAPH 白板线自审(2026-09-16 凌晨,施工方自审)
2
+
3
+ > 自审立场:**假设自己有错**,逐行回读本窗口写下的代码,只采信代码/配置/日志证据。
4
+ > 结论先行:**P1 判据对账是扎实的;P2/P3 与 GUI 开关存在 3 个致命 bug + 6 项未按规划完成**。"切了没反应"不是环境问题,是代码问题。
5
+
6
+ ---
7
+
8
+ ## 一、致命 bug(会让功能整体失效)
9
+
10
+ ### BUG-1 ★ 工具注册时机早于配置加载 ⇒ graph 档永不生效
11
+
12
+ **证据链**:
13
+ - `lib/index.js:8506` `const tools = [...]` 在 `apply()`(`:7633`)内**同步构建**;`:9763` `for (const tool of tools)` → `:9772 ctx.tools.register(tool)`。
14
+ - P3 注册闸门写的是 `resolveBoardModePre(engine.config.boardMode)`。而 `engine.config` 在 `MemoryEngine` 构造时(`:982` `this.config = { ...DEFAULT_CONFIG }`)是**默认值**,`DEFAULT_CONFIG.boardMode = 'legacy'`。
15
+ - 真配置只在 `loadConfig()` 里合并(`:1597`),而 `loadConfig()` 是**懒加载**:全仓唯一自动调用点是 `resolvePaths()`(`:1739` `if (!this.configLoaded) await this.loadConfig()`)——即"首次工具调用"才发生。
16
+ - 取证:`apply()` 段(7632–8510)内 **无** `await engine.loadConfig()`。
17
+
18
+ **后果**:不管配置里写 `graph` 还是 `legacy`,插件启动时读到的永远是默认 `legacy` ⇒ **`memory_expand_pre` / `memory_trace_pre` 永远不注册**。用户配置里 `"boardMode": "graph"` 是真写进去了(见 §四证据),但工具从未出现。
19
+
20
+ **修法**:`apply()` 内在构建 tools 之前 `await engine.loadConfig()`(必要时兜底 catch);或把注册闸门的判定改为"延迟到首次调用时再判"。
21
+
22
+ ### BUG-2 ★ P2/P3 取工作区路径的 API 用错了 ⇒ 跑到 DSH 安装目录
23
+
24
+ **证据链**:
25
+ - 我写的 `expandWhiteboardByTagPre` / `traceWhiteboardByIdPre`(`:2041`、`:2054`)用 `agent && agent.cwd ? agent.cwd : process.cwd()`。
26
+ - 全仓 grep `agent.cwd` **只有这 2 处命中**(就是我新加的两行)⇒ 该字段不是本仓库既有约定,**几乎必然为 undefined**。
27
+ - 既有权威写法是 `await this.resolvePaths(agent)` → 返回 `{ ws, projectDir, planPath, handoffDir, ... }`(`:1738-1790`)。全仓 20+ 处都这么写(`:1835`/`:2483`/`:3809`/`:3990`/`:4062`…)。
28
+ - 于是回退到 `process.cwd()`:dsh web 宿主的工作目录是 **DSH 自己的安装/启动目录**,不是用户工作区。
29
+
30
+ **后果**:两个工具会在错误目录找 `handoff/index.json`,找不到就触发 `rebuildSidecarIndexPre` 在**错误目录建 handoff/**;即便 sidecar 已生成,查询也永远返回 0 条。
31
+
32
+ ### BUG-3 ★ 设置页按钮"改了不保存就刷新" ⇒ 用户点完等于没点
33
+
34
+ **证据链**:
35
+ - 我在设置页加的双按钮调的是 `set('boardMode', m)`,然后 `setTimeout(() => window.location.reload(), 350)`。
36
+ - `set()` 的实现(`lib/client.js:4047`)是:`var next = {...cfg}; next[key]=value; setCfg(next); setDirty(true)` —— **只改本地 state 并标脏,不写盘**。真正写盘要靠设置页的"保存"按钮。
37
+ - 350ms 后 `location.reload()` ⇒ **脏数据被丢弃**,配置文件不变。
38
+ - 接续面板那个按钮用的是 `saveConfigPatch({...})`(立即写盘)⇒ 那个是对的。
39
+
40
+ **后果**:用户在**设置页**切换 = 无任何效果(连配置都没改)。用户看到配置里是 `graph`,说明他点的是**接续面板**那个按钮(或另有写入路径)。
41
+
42
+ ---
43
+
44
+ ## 二、高/中危缺陷
45
+
46
+ | # | 缺陷 | 证据 | 影响 |
47
+ | --- | --- | --- | --- |
48
+ | BUG-4 | sidecar 用了不存在的 `this.wsDirKey` | grep `wsDirKey` 全仓 0 命中;真名是 `wsKey(ws)`(`:1686`) | `workspaceKey` 退化为 `path.basename(projectDir)`,与 `WB-FORMAT-CONVENTION §2` 锚点契约的 workspaceKey 口径不一致;同一工作区换路径写法会算出不同 id |
49
+ | BUG-5 | 三处工具数硬锁未同步 | `smoke-test.mjs:67` / `smoke-test-m3b3-pre.mjs:43` / `smoke-test-context-observer.mjs:107` 仍是 `!== 14` | 方案 P3-3 标为"**必须项**"(漏改任一处即红)。当前全绿只因测试跑在 legacy 档、工具数确实是 14 —— **graph 档下这三个套件会红**,属"锁没建全"而非"锁对了" |
50
+ | BUG-6 | `events.jsonl` 未实现 | 方案 A2 与 P2-1 明确要求 `index.json` + `events.jsonl`(append-only `{ts,actor,event,target,details}`);实际只写了 index.json | P2 未按规划完成;`criteria.passed/warned` 确认事件链缺失(方案 §2.4 第 2 层) |
51
+ | BUG-7 | 遍历工具不返回正文 | 方案 §4.1 要求返回条目 Content;`expandByTagPre` 只回 `{id,title,source,tags,cue,chars,ts}` | "主动重建上下文"的核心价值(省去通读 18000 carryText)没落地 |
52
+ | BUG-8 | 无正文级检索兜底 | 方案 P3-1 要求"index.json 缺失时 fail-soft 回落 `searchHandoffCorpus`";实际只做重建,未回落词法检索 | 与规划不符 |
53
+ | BUG-9 | 未接线 dsh-graph | `vendor/dsh-graph/NOTICE-VENDOR.md` 自述"待用户明示" | 用户的核心诉求(可视化看板)未兑现;用户对此的抱怨成立 |
54
+
55
+ ---
56
+
57
+ ## 三、确认「做对了」的部分(避免自审只挑刺)
58
+
59
+ - **P1 判据门对账**:`wb-contract-pre.js` 的 H1–H4/S1–S4 实现与 `checkMutationPre` 两咽喉接线**经实测确认存在**(不是假设),`ledger-criteria-pre.js` 只做转发再导出(单一真源),10/10 断言绿。
60
+ - **legacy 档零行为**:`writeSidecarEntryPre` 首行闸门 + 工具注册闸门 + `DEFAULT_CONFIG.boardMode='legacy'` 三处齐备;全量回归 **95/0/0(145.4s)** 证明既有 92 套件未破。
61
+ - **变异演示有效**:3/3 真失败(且发现 M9 断言被注释串骗过,已改用行首锚定 `/^\s*defineTool\(/`)—— 这个自我纠错是真实的。
62
+ - **抽取式套件补桩**:handoff-pre 53/53、p7-write-fix 40/40 修复到位(新增引擎方法必须同步补 fake engine 桩)。
63
+
64
+ ---
65
+
66
+ ## 四、外部可复核证据
67
+
68
+ | 项 | 值 |
69
+ | --- | --- |
70
+ | 用户配置文件 | `C:\Users\JH Z\.dsh\dsh-auto-memory-pre.json` 内 `"boardMode": "graph"`(**已落盘**) |
71
+ | 全量回归 | `PASS 95 / FAIL 0 / TIMEOUT 0(145.4s)`(`node tools/run-smoke.mjs`) |
72
+ | 工具数硬锁 | 三处仍 `!== 14` |
73
+ | `agent.cwd` | 全仓仅 2 处,均为本次新增 |
74
+ | `wsDirKey` | 全仓 0 处 |
75
+ | `apply()` 内 loadConfig | 0 处 |
76
+
77
+ ---
78
+
79
+ ## 五、为什么"切了也什么都没有发生"(一句话归因)
80
+
81
+ **三重叠加**:① 设置页按钮不保存(BUG-3);② 即便保存了,工具注册时机早于配置加载(BUG-1)⇒ 新工具永不注册;③ 即便工具注册了,取路径 API 用错(BUG-2)⇒ 查询也查不到东西。**再加上 dsh-graph 看板本身还没接线(BUG-9)**,所以从用户视角"什么都没发生"是完全符合代码现状的。
@@ -0,0 +1,305 @@
1
+ # 明日 → 周末作战图(2026-09-17 ~ 09-20)
2
+
3
+ > **来源**:用户 2026-09-17 00:5x 口述的本周计划;01:3x 用户裁定「先把 PR 全 merge、issue 读完做好回应就关掉」。
4
+ > **纪律**:本文件是这批工作的**唯一排期依据**;与旧规划冲突时以本文件为准。
5
+ > **前置**:送审批已完工(回归 PASS 105/0/0);**远端 7 个 PR 已全部 merge、9 个 issue 已全部回应并关闭**(见 §6)。
6
+ > **注意**:远端 merge 属**礼节性**——本机 pre 线不受其影响;上传时以本机版本强制覆盖。pre 线纪律(§4.4)不变。
7
+
8
+ ---
9
+
10
+ ## 0. 用户已定夺的事项(不再讨论)
11
+
12
+ | # | 事项 | 裁定 |
13
+ |---|---|---|
14
+ | 1 | **PR #37**(自动接续 idle 门) | ❌ **不做**。用户原话:「就先不做了,反正冲突了,就按我自己做的新的做,没问题就行」⇒ 保留 pre 线现有 `sessionController.cancel()` 方案(2026-09-14 裁定),**冻结**,不再评估 PR 方案 |
15
+ | 2 | 记忆窗格位置 | 挪到看板上集成,**旧位置(左下角)与新看板可共存**,设置里可调位置(**类比 literature 插件的理念**) |
16
+ | 3 | 看板定位 | 看板**只是其中一项功能**,不是全部(当前看板=白板,需升级为"集成容器") |
17
+
18
+ ---
19
+
20
+ ## 1. UI 重构 + 看板重构(主任务)
21
+
22
+ ### 1.1 背景与痛点
23
+ - **左下角位置太紧张**:记忆按钮 + 浮层 + 欢迎卡 + 更新卡都在争左下角(`client.js` 里
24
+ `overlay = { position:'fixed', left:'10px', bottom:'64px' }` 一类的堆叠)。
25
+ - 用户思路:**把记忆窗格挪到看板上集成**,看板升级为"承载面",只把看板当其中一个功能。
26
+
27
+ ### 1.2 可复用资产(已建成的)
28
+ | 资产 | 位置 | 用途 |
29
+ |---|---|---|
30
+ | 整页看板 + 矩阵视图(双承载面) | `lib/client.js`(`KanbanView`/`KanbanBoard`)+ `lib/wb-sidecar-pre.js`(`buildKanbanMatrixPre`) | 新承载面的**现成宿主** |
31
+ | `conversation.view` 槽位注册 | `client.js`:`slots.register({ name:'conversation.view', id:'auto-memory-pre-kanban', order:80 })` | 上栏承载面已通 |
32
+ | `sidebar.right.pane.tab` | 侧边面板承载面 | 另一承载面 |
33
+ | portal 浮层配方 | `kxPortal()` + `createPortal(node, document.body)` | 浮层定位正解(见记忆:三阶段教训) |
34
+ | CSS 令牌权威清单 | 见项目笔记(label-*/bg-layer-*/border-l*/state-*) | **禁止凭印象拼令牌** |
35
+
36
+ ### 1.3 literature 插件的"理念"具体指什么(**待用户确认细节**)
37
+ 用户说"这类似于 Literature 插件的理念"。**已查:`~/.dsh/profiles/web/node_modules` 下
38
+ 未找到 `dsh-literature`**(可能装在别处或未装本机)。
39
+ ⇒ **需用户澄清**:是指 (a) **同一功能多处可挂载**(用户自选承载面),还是
40
+ (b) **设置内切换"功能归属面板"**,还是 (c) 别的?
41
+ > 若指 (a):实现=每个功能注册成一个"可挂载组件",设置里选挂载点(左下浮层/侧边栏/看板 Tab),
42
+ > 默认值保持现状(向后兼容),改动即时回显。
43
+
44
+ ### 1.4 建议的实施顺序(待用户拍板)
45
+ 1. **先定架构**:功能清单 → 每个功能的"可挂载"改造点 → 位置配置键设计
46
+ 2. 看板升级为容器(Tab / 分区),把记忆窗格作为其中一个功能页
47
+ 3. 位置设置项 + 即时回显(用户硬规则:开关类改动必须即时回显)
48
+ 4. 旧位置保留为可选项(共存,非替换)
49
+ 5. 回归 + 变异演示 + 看板回写
50
+
51
+ ---
52
+
53
+ ## 2. 项目主页 HTML 重做(次任务)
54
+
55
+ | 项 | 状态 |
56
+ |---|---|
57
+ | 风格/设计 | ✅ **已写好**(用户原话:「那个已经把风格等都写好了」) |
58
+ | **README / 手册文案** | ✅ **本轮完工**(见 §2.2) |
59
+ | 排版(主页 HTML) | ⬜ **待开工**(用户原话:「就差开始做排版」) |
60
+ | 图片 / 截图 | ⏸ **用户指示等前端重构完成后再改** |
61
+ | 细节定夺 | ⬜ **待用户逐项定夺** |
62
+
63
+ ### 2.1 「一两周前写的主页风格 Markdown 文档」已定位 ✅
64
+
65
+ 用户 01:2x 补充的指令已执行,文件系统里找到**三份**同族文档(`docs/` 根,时间戳 2026-09-06 02:1x–02:3x,即**11 天前**):
66
+
67
+ | 文档 | 大小 | 作用(据其自述) |
68
+ |---|---|---|
69
+ | **`docs/NEXT-MAJOR-README-DRAFT.zh.md`** | 12.9 KB | ⭐ **主页骨架**——「下一大版本 README 替换草稿(中文版)」,hero copy + 段落结构;标注【保留区】(从现 README 原样迁移)与【占位】(随大版本落地替换) |
70
+ | `docs/NEXT-MAJOR-PROMO.md` | 24.9 KB | **全量文案库**——品牌句/开场/每个功能的成稿/工程说明/场景物料/发布公告;「组装 README / landing / npm 简介 / QQ 公告时从这里取材」 |
71
+ | `docs/PROMO-STYLE-GUIDE.md` | 5.4 KB | **文风守则**(「热叙述体」,产品拟人作「她」=可靠/克制);自称**可整套复用到其他项目主页** |
72
+
73
+ > **判定**:用户说的应是 **`NEXT-MAJOR-README-DRAFT.zh.md`**(唯一同时具备「主页风格」与「Markdown」两个属性的骨架稿);
74
+ > `NEXT-MAJOR-PROMO.md` 是它的**素材库**,`PROMO-STYLE-GUIDE.md` 是**文风依据**。三份互有交叉引用,排版时应**成套使用**。
75
+
76
+ ⚠️ **两份文档都带硬约束**(原文):`NEXT-MAJOR-VISION.md` 声明「**本文档是愿景与 README 宣传方案的唯一权威来源。大版本完成前禁止改 README**」;
77
+ `NEXT-MAJOR-PROMO.md` 亦写「**大版本完成前禁改 README**」。
78
+
79
+ ✅ **2026-09-17 02:1x 该禁令已被用户解除**:用户裁定「**你觉得现在不是大版本吗?先按照大版本的标准把这个 README 修改一下**」
80
+ ⇒ 承认当前即大版本,README 按大版本标准改写(**文案层**先行,图片待前端重构后另行处理)。
81
+
82
+ ### 2.2 本次 README / 手册改动(2026-09-17 02:1x–02:3x 完工)
83
+
84
+ **用户原话拆解**(三轮澄清后的准确理解):
85
+ 1. 「按大版本标准改 README」= 正文已是大版本骨架(`【占位】/【保留区】` 标记已全部清空),**真实缺口是 3.0 后端成果零覆盖**;
86
+ 2. 「README 里的那些按钮,比如说切中英文那样的」= **顶部按钮行**,不是插件 UI;
87
+ 3. 「用户手册也记着用最新的办法来改」= 手册同样补 3.0 内容 + 换按钮样式;
88
+ 4. 「图片什么的等前端重构后再改」= **本轮不动图片**。
89
+
90
+ | 改动 | 文件 |
91
+ |---|---|
92
+ | **按钮行换成 for-the-badge 徽章**(语言切换 2 枚 + npm/许可证/零依赖/平台 4 枚 + 导航行) | `README.md` · `README.zh-CN.md` |
93
+ | 新增「**3.0 底层重建**」段(8 项机制对照表,中英各一份) | 两个 README |
94
+ | 30 秒亮点表补「**多工作区不串线**」一行 | 两个 README |
95
+ | 手册顶部加同款徽章 + 返回 README 链接;版本号 `2.2.7+` → `3.0+` | `docs/USER-GUIDE.zh-CN.md` · `docs/USER-GUIDE.en.md` |
96
+ | 手册新增 **§13「3.0 底层重建:对你意味着什么」**(5 小节,面向用户解释边界)+ 目录项 | 同上 |
97
+
98
+ **参照物**:`D:\dsh-memory-fitting\README.md`(用户 2026-09-16 23:40 上传的「思维拟合插件」)。
99
+ 徽章写法照抄其 `for-the-badge` 语言切换块 + 独立徽章行;手册顶部也照抄其「语言切换 + 返回 README」结构。
100
+
101
+ **自检(已过)**:6 个徽章 URL 全部 HTTP 200;4 个文件均无 BOM;4 个文件站内锚点 0 处断裂(用 github-slugger 算法逐条核验);
102
+ 链接目标(LICENSE / CHANGELOG.md / CONTRIBUTORS.html / docs/internal)全部存在;两 README 标题数对称(各 50)、两手册对称(各 36)。
103
+
104
+ **未做**:图片与截图(等前端重构);`docs/promo/homepage.html` 排版(另案)。
105
+
106
+ > 纪律**仍然有效**的部分:`NEXT-MAJOR-VISION.md` 作为**愿景与宣传文案的权威来源**这一条不变;
107
+ > 本轮只改文案层,未动 README 里的任何图片引用(`promo-*.png` 原样保留)。
108
+
109
+ **其它参考**:`docs/promo/homepage.html`(既有主页)、`docs/CONTRIBUTORS.html`(本轮新建,
110
+ liquid-glass 深色主题、zh/en 切换、单文件零依赖)。
111
+ **纪律**:单文件零依赖、无 BOM、GitHub 上须用 `htmlpreview.github.io` 包裹链接(`.md` 不包裹)。
112
+
113
+ ---
114
+
115
+ ## 3. 之前提到但未做的(结转项)可以重新排期,看是先做主页,还是先做这一方面的内容。
116
+
117
+ ### 3.1 本批明确排除的(用户此前同意)
118
+ | 项 | 内容 | 备注 |
119
+ |---|---|---|
120
+ | 群反馈 #7 | 日历太粗糙 → 换开源方案(`fullcalendar`/`tui-calendar`) | 新功能,需排期 |
121
+ | 群反馈 #9 | webhook CI 安全收口(签名/限流/密钥);`.github/cloud/qq-webhook/index.zip` 仍入库 | 运维项 |
122
+ | subagent 智能调度 | `shouldSpawn`/`judgeSubagent` **零命中** ⇒ 未实现 | **是功能缺失,不是验证缺口** |
123
+
124
+ ### 3.2 P0-4e(已实测复现,未修)★ 与并发问题强相关
125
+ 索引同步防抖:持续写入 ⇒ 索引永远不就绪(实测卡死 20 分钟)。
126
+ **本次并发调查补充**:`mivCache` 单槽会放大该效应(见 `CONCURRENCY-INVESTIGATION-20260917.md` §5)。
127
+
128
+ ### 3.3 并发缺陷(本次调查新发现)✅ **已修完并验证**
129
+ 4 个单槽共享点:`_tierGateHits` / `mivCache` / `lastIndexDegrade` / `_lastTierQuery`。
130
+ 采用**方案 A(分片化)**,2026-09-17 01:1x 完工:
131
+
132
+ | 单槽 | 改为 | 主因 |
133
+ |---|---|---|
134
+ | `engine._tierGateHits` | `_tierGateHitsBySession.set(sessionId, …)` | A 投递后被 B 覆盖 ⇒ A 取到 B 的投影 ⇒ 身份门 session-mismatch ⇒ **A 永远不下探 Tier-1** |
135
+ | `mivCache` | `mivCacheByWs`(按工作区) | 两工作区互相踢缓存 ⇒ 每次必然重算,放大 P0-4e |
136
+ | `lastIndexDegrade` | `indexDegradeBySession` | 读方原只判 10 分钟窗、不判会话 ⇒ **跨会话假降级** |
137
+ | `_lastTierQuery` | `_lastTierQueryBySession` | 无条件覆盖,读取侧退回 `triggerText` |
138
+
139
+ - 判定口径(T0-2 五道门)**一字未改**;三处分片容器加 `size>32` 有界淘汰。
140
+ - 兼容投影保留(`engine._tierGateHits` / `engine._lastIndexDegrade` / `debugView.memoryIndexVersion`),只增字段。
141
+ - 新增套件 `tests/smoke/smoke-test-multiworkspace-pre.mjs` **22 断言**(S 源码守卫 7 + B 分片语义 6 + R 真实现抽取执行 6 + C 兼容 3);
142
+ 变异演示**真失败 5 条**(含行为测试 R1/R2 抓住)。
143
+ - 全量回归 **PASS 105 / FAIL 0 / TIMEOUT 0(160.5s)**。
144
+
145
+ > ⚠️ 验收要点:R 组是**从源码抽取真实 `recordTierGateHits` 执行**的;B 组测的是套件内本地辅助函数,**属"假绿风险"**,不能单独作为守卫。
146
+
147
+ ### 3.4 其他结转
148
+ - **合并远程 60 提交** → 已由本轮 PR 全部 merge 覆盖(远端 `main` = `43c5492`);本机 pre 线**不受影响**,上传时强制覆盖
149
+ - **送审**:任务书 `docs/internal/GPT-ACCEPTANCE-PROMPT-20260916.md` 已就绪,待用户投喂 GPT
150
+ - **看板卡片**:三张已回写(P0-A 已解耦 / P0-B 已修 / P0-4d 已完工)
151
+ - `docs/internal/TODO-GRAPH.html` 里可能还有其它"待开工/待调研"卡片未清点
152
+ - **PR/issue 批**:已完成(见 §6)
153
+
154
+ ---
155
+
156
+ ## 3.5 S10「Karpathy 模块」实现缺口审计(2026-09-17 02:1x,用户点名的送审重点)
157
+
158
+ **触发**:用户指出「这正好就是我准备让 GPT 审的部分,说明有些东西还是漏做了,**尤其是接续这部分**」。
159
+ **方法**:以「契约声称 vs 代码真实调用链」为准逐条 grep,**有调用点才算已实现**。全部结论附行号。
160
+
161
+ ### ✅ 结论先行:接续主链是通的,工程质量高于契约文档给人的印象
162
+
163
+ | 环节 | 状态 | 证据 |
164
+ |---|---|---|
165
+ | 水位触发 → 写交接账本 | ✅ 已实现 | `index.js:2789` `writeHandoffLedger` |
166
+ | 判据门(四段式硬门) | ✅ **真接线** | `index.js:2302` `checkHandoffCriteriaPre`;两咽喉 `:1939` / `:2020` 都过同一入口 |
167
+ | 骨架降级只跳判据门 | ✅ 正确 | `index.js:2804` 的 `skipCriteria:true` 注释与实现一致(丢卡门绕不过) |
168
+ | 保护门(丢卡/用户区/重复 id) | ✅ 已实现 | `index.js:2325` `validateMutationBoundaryPre` |
169
+ | 新会话收交接材料 | ✅ 已实现 | `index.js:3118` `buildContinueCarry` → `:3144` `sc.prompt` 投递 `carryText` |
170
+ | 先停旧回合(PR#37 争议点) | ✅ 已实现 | `index.js:3099` `sc.cancel({sessionId: oldSid})`,降级路径也留痕 `:3105` |
171
+ | 接续序号标题 | ✅ 已实现 | `index.js:3129-3131` rename 为「接续 #N · 工作区」 |
172
+ | requestId 必填坑 | ✅ 已修 | `index.js:3141-3143` 铸造 `randomUUID`(缺失会导致材料从未送达) |
173
+
174
+ ### ❌ 真缺口(用户说「漏做了」,这是实证)
175
+
176
+ **缺口 1(P0)· 白板**注入**通路依赖 `boardMode='graph'`,而默认是 `legacy`**
177
+ - 默认值:`index.js:219` `boardMode: 'legacy'`;客户端初值 `client.js:2869` 同为 `'legacy'`。
178
+ - 锚点写入被 graph 档门控:`index.js:1988`(PLAN)与 `:2032`(账本)——**非 graph 档完全不写锚点**;
179
+ sidecar 同样在 `:2076` 直接 `return`。
180
+ - ⇒ **默认配置下 S10.1 的「页面即语料」整条链不生效**。契约文档 `WB-FORMAT-CONVENTION.md` §2 把它写成无条件收益,与实现不符。
181
+ - **严重度**:P0(送审友好度)——这是"契约声称 vs 默认行为"的直接冲突,GPT 一定会问。
182
+
183
+ **缺口 2(P0)· 白板**检索**通路从未接入(与缺口 1 独立)**
184
+ - 注入路径 ✅:`index.js:4701` `add('whiteboard', s.planText, s.planPath)` → Tier-0 目录(五来源之一,且有保底配额)。
185
+ - 检索路径 ❌:`pushL0` 仅四个来源(`:5505` 日志 / `:5506` 反思 / `:5507` 项目笔记 / `:5508` 用户级);
186
+ `semSources` 同样四个(`:5704-5707`)。**白板一处都没有**。
187
+ - ⇒ **白板每轮被注入,但 `memory_recall` 搜不到它**。契约 §2 承诺的"自动进入检索语料"目前只兑现了注入那一半。
188
+ - **严重度**:P0。
189
+
190
+ **缺口 3(P1)· S10.2「索引自动生成」零实现**
191
+ - `indexMd` / `renderIndex` / `buildIndexMd` / `index.md` **全 0 命中**;`derive` 的 13 处命中全是别的语义
192
+ (`_waterDeriveCache`、`derived-fact`、`.md` 去后缀)。
193
+ - ⇒ 契约 §3「index 由页面派生、与白板不得各写一份」**只有契约,无实现**。
194
+
195
+ **缺口 4(P1)· S10.3「lint 四类 + 矛盾检测」零实现**
196
+ - `lint` 全仓仅 11 处,且无任何 `function/export` 定义 —— 非 semantic 的 4 处是**注释里的提及**
197
+ (`wb-contract-pre.js:261`、`wb-sidecar-pre.js:517` 都写着"供 lint 用",但**没有 lint 本体**)。
198
+ - ⇒ 四类零 token 检查与矛盾检测(手动触发)均未实现。
199
+
200
+ **缺口 5(P2)· 账本跳过用户区保护**
201
+ - `index.js:2313` `if (target === 'handoff') return { ok: true }` —— **账本的共同保护门被无条件放行**。
202
+ - 与同一函数 docblock 的声明直接矛盾:`:2062` 写着「共同保护门(`validateMutationBoundaryPre`)= 丢卡 / 用户区 / 重复 id,
203
+ **无条件生效**,`criteriaGate=false` 与"骨架 fail-soft"都绕不过」;`:2308` 行内注释亦写「(无条件;只在"重写既有目标"时有意义)」。
204
+ - 另 `:332` 的模块级注释同样声称「`validateMutationBoundaryPre` 里无条件生效」。
205
+ - **判定**:三处注释声称"无条件",实现却在 `:2313` 对 `handoff` 提前放行。
206
+ 影响面有限(账本走 `:2022` 的 `beforeText: ''`,本就不涉及"重写既有目标"的丢卡语义),
207
+ 但**注释与实现不一致本身即缺陷**,且若将来账本改为可覆盖写,这里会成为静默漏洞。
208
+
209
+ **缺口 6(P2)· 死导出**
210
+ - `wb-contract-pre.js` 12 个导出、`wb-sidecar-pre.js` 16 个导出、`ledger-criteria-pre.js` 7 个、`memory-mutation-pre.js` 5 个
211
+ **在 `index.js` 里零引用**(如 `computeWhiteboardCardIdPre`、`buildByCuePre`、`collectAnchorIdsPre`、`checkWriteCriteriaPre`)。
212
+ - 部分可能被 client.js 或测试消费,属"疑似死代码"而非确证死代码 —— **建议 GPT 复核**。
213
+
214
+ ### 修复建议(按优先级)
215
+
216
+ 1. **P0**:让白板进 `memory_recall` 语料 —— 在 `pushL0` 与 `semSources` 各补一条白板来源(路径 `p.planPath` 已存在),
217
+ 并给 `whiteboard` 层同样的配额保护。**这是最小、最高性价比的一改。**
218
+ 2. **P0**:`boardMode` 默认值决策 —— 二选一:① 改默认 `graph`(需评估既有用户兼容);② 让锚点写入**不依赖** boardMode
219
+ (锚点是格式契约,与看板渲染形态无关)。**倾向 ②**,因为锚点属写入契约、看板属渲染形态,本不该耦合。
220
+ 3. **P1**:S10.2 / S10.3 二选一:补实现,或在契约文档标注「**未实现**」并降级为规划项。
221
+ **送审前必须至少做到标注**,否则就是又一次"契约已定说成已实现"。
222
+ 4. **P2**:修正 `:2313` 注释与实现的不一致(或补上账本保护门)。
223
+
224
+ ---
225
+
226
+ ## 4. 硬约束(贯穿全程)
227
+
228
+ 1. **禁止无差别杀 node 进程**(DSH harness 与插件宿主都在 node 上,2026-09-14 出过事故)
229
+ 2. **`dsh web` 宿主由用户自行重启**;agent 只改文件 + 说明需重启,严禁 Stop/Start-Process
230
+ 3. **无 BOM**;大文件分块写;改前备份 `*.bak-YYYYMMDD-<tag>`
231
+ 4. **代码留在 pre 线**,未经明确同意不 commit/push/publish
232
+ 5. **单一开关不得顺带改变其他功能的行为**(解耦)
233
+ 6. **开关类改动必须即时回显**(写盘成功但界面无变化 = "功能坏了")
234
+ 7. **CSS 令牌必须查权威清单**,不得凭记忆拼写
235
+ 8. 结论附代码/日志证据;推断显式标注
236
+
237
+ ---
238
+
239
+ ## 5. PR #37 说明(留痕,避免下个窗口重开)
240
+
241
+ - **原裁定**:用户 2026-09-17 明确「就先不做了,反正冲突了,就按我自己做的新的做,没问题就行」。
242
+ - **理由**:PR #37 的 `continuation-safety.js` 文件头明写 `no cancel of source work`,
243
+ 走 idle 门;而 pre 线按用户 2026-09-14 裁定走 `sessionController.cancel()` **先停旧回合**
244
+ (`lib/index.js` 注释记录用户反对 idle 门方向)。
245
+ 两者方向**直接相反** ⇒ 不移植到 pre 线。
246
+ - **pre 线方案状态**:**完好**。`smoke-test-autocont-host-pre.mjs` 钉死调用顺序
247
+ `cancel → prompt → create`,并覆盖降级路径(无 cancel / cancel 抛错)。
248
+
249
+ ### 5.1 但**远端**已礼节性 merge(2026-09-17 01:5x)⚠️
250
+ 用户 01:3x 补充裁定:**「远端 merge 也无所谓,最后推 NPM 和 GitHub 时我会把统一的最新版本强制拉上去」**。
251
+ ⇒ 本轮把 #37 与其余 6 个 PR 一并 merge 到远端 `main`(冲突在 worktree 内解决:`lib/index.js` 两处 import 行取并集)。
252
+
253
+ **关键结论(避免下个窗口误判)**:
254
+ **远端 merge 不改变 pre 线任何一行代码。** pre 线 `D:\dsh-auto-memory` 仍是 §5 原裁定方向
255
+ (`cancel()` 先停旧回合),**不得**因为「#37 已经 merge 了」就把 idle 门方案搬进来。
256
+ 上传时以**本机版本强制覆盖**远端,被顶掉是预期行为。
257
+ > 遗留观察(非阻塞):远端 `main` 现在同时含 idle 门方案与本机将来要推的 `cancel()` 方案,
258
+ > 两者在远端**并存**——但这只是中间态,最终由强制推送收敛。
259
+
260
+ ---
261
+
262
+ ## 6. PR / Issue 批(✅ 2026-09-17 01:3x–02:0x 完工)
263
+
264
+ 用户 01:3x 裁定:「**把这些 pull request 和 issue 都回复了,然后 merge 了**……**这个 issue 读完了,做好回应。关掉就可以。**」
265
+ 质量要求明确被豁免(「反正 main 里面 merge 管不到我本机的系统……所以不用管质量」)——**本轮以礼节性处理为准**。
266
+
267
+ ### 6.1 7 个 PR 全部 merge 到远端 `main`
268
+
269
+ | PR | 标题 | 处理 |
270
+ |---|---|---|
271
+ | #36 | fix(procedure): episode 候选如实标记 observation-only | ✅ 直接 merge `dc76373` |
272
+ | #44 | fix(capacity): 按最终序列化结果计费,整段归档 fsync+读回验证 | ✅ 直接 merge `c12d023` |
273
+ | #46 | fix(tour): 欢迎向导自动弹出全链路等宿主配置 | ✅ 直接 merge `8d63bc8` |
274
+ | #49 | fix(recall): 取消排名前的记录截断(issue #45) | ✅ 直接 merge `b1f4abe` |
275
+ | #53 | fix(issue51): anchor workspace overview log-date matching | ✅ 直接 merge `3d92a67` |
276
+ | #50 | fix(issue48): atomicReplace EPERM 退避重试 | ⚠️ **有冲突** → worktree 内解决 `25a7c7b` |
277
+ | #37 | fix(issue35): 自动接续重做为真实空闲闸 + 可证仪式 | ⚠️ **有冲突** → worktree 内解决 `43c5492` |
278
+
279
+ **冲突处理方式**(两个 PR 的冲突**都只在 `lib/index.js` 的 import 行**,取并集即可):
280
+ - `#50`:3 处 —— import 行补入 `memoryWriteError` + `fs-retry.js`;两处 `throw` 改用 `memoryWriteError('append'/'replace', r)`。
281
+ - `#37`:2 处 —— import 行同时保留 `memory-capacity-safe.js` 与 `continuation-host.js`;`memory-writer.js` 那行保留 HEAD 具名导入并**追加** `atomicReplace`。
282
+ - 解法统一用「取并集 + 保留 HEAD 已有符号」,`node --check` 通过后才 commit/push。
283
+
284
+ ### 6.2 工作流(可复用)
285
+
286
+ **`gh` CLI 未安装** ⇒ 全程走 GitHub REST API + `git credential fill` 取 token(`credential.helper=manager`)。
287
+ **冲突不得在主仓库解**:先在 `D:\_merge-wt` 建 `git worktree --detach origin/main`,全部解决 + 语法检查 + commit 后 `git push origin HEAD:main`。
288
+ (踩坑提醒:`lib/index.js` 是 **CRLF** 文件,写解析脚本必须按 `\r\n` 拼串,否则替换「3 处命中 0 处」。)
289
+
290
+ ### 6.3 9 个 issue 全部「回应 + 关闭(completed)」
291
+
292
+ | Issue | 标题要点 | 回应要点 |
293
+ |---|---|---|
294
+ | #54 | 写入侧缺保留语法过滤(自提 P0) | 采纳方案 a;补 `conflict:<type>@<line>` 行号;顺带修 `stripAnchorLines()` 收口的既有静默损坏 |
295
+ | #52 | 子代理模型被旧 cfg 覆盖 | `set()` 改函数式 + 新增 `setMany()`;5 条回归用例落地 |
296
+ | #51 | `DATE_RE` 未锚定 | 取最小修复(完整锚定)+ 修正误导性注释;含「与 index.js 行为一致」护栏断言 |
297
+ | #48 | `atomicReplace` 缺 EPERM 退避 | 建议 4 条全落地;**并确认了报告者「自查」的 `_queue()` 大小写 key 问题** |
298
+ | #45 | recall 256 截断(英文报告) | 取消查询前截断 + 保留排名后 limit;加 `[本地检索范围受限]` 提示;性能优化明确不在本 PR |
299
+ | #40 | `welcomeTourEnabled=false` 无效 | 4 条建议全落地;向导真源定为宿主配置 |
300
+ | #38 | 容量整理净增长 +10/轮 | 建议 1+3;`replace` 改按最终序列化结果计费 |
301
+ | #35 | 自动接续绕过活跃防护 | Defect A/B/C 全修;heartbeat 路径同覆盖 |
302
+ | #30 | Procedural skill 永不晋升 | 标记 observation-only + 原因码全链透出;去重改指纹;手动激活与可配阈值**明确未纳入** |
303
+
304
+ **回应纪律**:每个 issue 都写明「根因是否确认 / 采纳了哪几条建议 / **哪些没采纳及原因** / 回归套件与断言数」——
305
+ 对报告者的准确之处**明确致谢**(如 #45「索引存在 ≠ 可检索」、#51「注释说是同源、实际不同源」),不揽功也不含糊。