@a9i5k4/dsh-auto-memory 2.5.3 → 3.0.1

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 (167) hide show
  1. package/README.md +189 -7
  2. package/README.zh-CN.md +189 -7
  3. package/docs/CONTRIBUTORS.html +471 -0
  4. package/docs/FRONTEND-CO-CREATION.md +191 -0
  5. package/docs/GM53-HOMEPAGE-PROMPT.md +323 -0
  6. package/docs/HANDOFF-CRITERIA.md +92 -0
  7. package/docs/HOMEPAGE-CONTENT-FOR-GM53.md +299 -0
  8. package/docs/INTEGRATION-ANALYSIS.md +350 -348
  9. package/docs/PROMO-PROMPT-3.0.md +100 -0
  10. package/docs/USER-GUIDE.en.md +58 -3
  11. package/docs/USER-GUIDE.zh-CN.md +59 -4
  12. package/docs/WHITEPAPER.md +207 -0
  13. package/docs/internal/ACCEPT-35-LIVE.md +143 -0
  14. package/docs/internal/ACCEPTANCE-20260914.md +90 -0
  15. package/docs/internal/ARCH-REVIEW-BRIEF.md +411 -0
  16. package/docs/internal/ARCH-REVIEW-REQUEST.md +201 -0
  17. package/docs/internal/ARCH-REVIEW-ROUND2.md +169 -0
  18. package/docs/internal/ARCH-REVIEW-ROUND3.md +206 -0
  19. package/docs/internal/ARCHITECTURE-FOR-ZCODE-20260920.md +397 -0
  20. package/docs/internal/ART-DIRECTION-DEEPSEEK-20260920.md +351 -0
  21. package/docs/internal/ART-DIRECTION-WIREFRAME.md +191 -181
  22. package/docs/internal/ART-DIRECTION-WIREFRAME.md.bak-superseded +181 -0
  23. package/docs/internal/AUDIT-WB-GRAPH-FULL-20260916.md +314 -0
  24. package/docs/internal/BATTLE-PLAN-20260917.md +871 -0
  25. package/docs/internal/CONCURRENCY-INVESTIGATION-20260917.md +192 -0
  26. package/docs/internal/CROSS-SESSION-SEARCH-PATH-DECISION.md +72 -0
  27. package/docs/internal/CROSS-SESSION-SEARCH-RESEARCH.md +131 -0
  28. package/docs/internal/DECISIONS-20260914-SESSION.md +269 -0
  29. package/docs/internal/DESIGN-P1-STATE-COMMIT-20260915.md +219 -0
  30. package/docs/internal/DIRECTION-CHECK-WB-GRAPH-20260916.md +132 -0
  31. package/docs/internal/FEATURE-INVENTORY.md +531 -0
  32. package/docs/internal/FEEDBACK-TO-DSHAPI-RELAY.md +13 -0
  33. package/docs/internal/G-SERIES-EXECUTION-20260917.md +248 -0
  34. package/docs/internal/G3-DESIGN-20260918.md +82 -0
  35. package/docs/internal/G3-DISK-FORMAT-GAP-20260919.md +92 -0
  36. package/docs/internal/GH-DISCUSSION-5732-COMMENT.md +74 -0
  37. package/docs/internal/GPT-ACCEPTANCE-PROMPT-20260916.md +352 -0
  38. package/docs/internal/GPT-REVIEW-PROMPT.md +216 -0
  39. package/docs/internal/GROUP-WEBHOOK-SETUP.md +33 -0
  40. package/docs/internal/HANDOFF-TO-ZCODE-20260920.md +309 -0
  41. package/docs/internal/HERMES-DATA-VERIFICATION-20260919.md +120 -0
  42. package/docs/internal/HERMES-LEGACY-STATUS-20260919.md +74 -0
  43. package/docs/internal/ISSUE-55-58-VERIFICATION-20260918.md +175 -0
  44. package/docs/internal/ISSUE10-FIX-EXECUTION-20260919.md +389 -0
  45. package/docs/internal/ISSUE10-PLAN-20260919.md +254 -0
  46. package/docs/internal/ISSUE10B-FORENSICS-20260919.md +468 -0
  47. package/docs/internal/ISSUE9-PURGE-AND-R1-PLAIN-20260919.md +150 -0
  48. package/docs/internal/ISSUE9-RESIDUAL-FORENSICS-20260919.md +114 -0
  49. package/docs/internal/KICKOFF-P0.md +254 -0
  50. package/docs/internal/LESSON-TO-CANDIDATE-STATUS-20260919.md +79 -0
  51. package/docs/internal/MASTER-PLAN-3.0.md +411 -0
  52. package/docs/internal/MEMORY-GOVERNANCE-20260917.md +309 -0
  53. package/docs/internal/MEMORY-MUTATION-AND-INDEX-DESIGN.md +85 -0
  54. package/docs/internal/MERGE-CONFLICT-SCAN-20260914.md +222 -0
  55. package/docs/internal/PENDING-FIXES-20260916.md +289 -0
  56. package/docs/internal/PRE-FRONTEND-CHECKLIST-20260919.md +705 -0
  57. package/docs/internal/PRE-FRONTEND-CHECKLIST-20260919.md.bak-s10 +649 -0
  58. package/docs/internal/PROCEDURAL-MEMORY-AND-APPROVAL-DESIGN-20260918.md +225 -0
  59. package/docs/internal/PROGRESS-20260917.md +93 -0
  60. package/docs/internal/PROMPT-GAP-AUDIT-20260920.md +128 -0
  61. package/docs/internal/R1-DEGRADE-AUDIT-20260918.md +163 -0
  62. package/docs/internal/R1-READABILITY-FORENSICS-20260919.md +127 -0
  63. package/docs/internal/R2-EVIDENCE-DEEP-AUDIT-20260918.md +140 -0
  64. package/docs/internal/R3-DEGRADE-LEDGER-DESIGN-20260918.md +138 -0
  65. package/docs/internal/R4-RECALL-QUOTA-PLAN-20260918.md +218 -0
  66. package/docs/internal/RAG-KARPATHY-PROGRAM.md +229 -0
  67. package/docs/internal/REPORT-P0-NIGHTLY.md +212 -0
  68. package/docs/internal/REPORT-P5-ACCEPTANCE.md +31 -0
  69. package/docs/internal/REPORT-WB-GRAPH-NIGHTLY.md +153 -0
  70. package/docs/internal/RESUME-20260918.md +171 -0
  71. package/docs/internal/RESUME-20260919.md +104 -0
  72. package/docs/internal/REVIEW-WB-GRAPH-SELF.md +81 -0
  73. package/docs/internal/RHINELAB-TO-DEEPSEEK-FEASIBILITY.md +198 -0
  74. package/docs/internal/ROADMAP-20260917-WEEK.md +439 -0
  75. package/docs/internal/ROADMAP.md +106 -0
  76. package/docs/internal/RUN-P0-NIGHTLY.md +227 -0
  77. package/docs/internal/S10-CONSTRUCTION-HANDOFF-20260917.md +185 -0
  78. package/docs/internal/S10-GAP-INVENTORY-20260917.md +239 -0
  79. package/docs/internal/S10-GAPS-PLAIN-20260917.md +125 -0
  80. package/docs/internal/SEMANTIC-ARCHITECTURE-SPEC.md +360 -0
  81. package/docs/internal/SESSION-FILE-REPAIR-PROTOCOL.md +90 -0
  82. package/docs/internal/T6-EXECUTION-20260920.md +130 -0
  83. package/docs/internal/TELEMETRY-EFFECT-REPORT-DESIGN-20260918.md +146 -0
  84. package/docs/internal/THESIS-GAP-ANALYSIS-20260918.md +89 -0
  85. package/docs/internal/THESIS-OUTLINE-20260918.md +147 -0
  86. package/docs/internal/THREE-LAYER-CONTRACT.md +219 -0
  87. package/docs/internal/TODO-BACKLOG.md +263 -142
  88. package/docs/internal/TODO-GRAPH.html +715 -0
  89. package/docs/internal/TODO-GRAPH.html.bak-20260914-v2 +493 -0
  90. package/docs/internal/TODO-GRAPH.html.bak-20260915-alsfix +710 -0
  91. package/docs/internal/TODO-GRAPH.html.bak-20260915-p1 +710 -0
  92. package/docs/internal/TODO-GRAPH.html.bak-20260915-p6a-rev +703 -0
  93. package/docs/internal/TODO-GRAPH.html.bak-20260915-wshint +710 -0
  94. package/docs/internal/TODO-GRAPH.html.bak-20260916-batch +715 -0
  95. package/docs/internal/UPSTREAM-ISSUE-PR-TRIAGE-20260919.md +297 -0
  96. package/docs/internal/UPSTREAM-ISSUES-3RD-AUDIT-20260920.md +104 -0
  97. package/docs/internal/WB-FORMAT-CONVENTION.md +112 -0
  98. package/docs/internal/WB-GRAPH-DECISIONS-20260914.md +71 -0
  99. package/docs/internal/reviews/CLAIM-VERIFICATION-20260914.md +56 -0
  100. package/docs/internal/reviews/PLAN-gpt6astra-round2-20260914.md +787 -0
  101. package/docs/internal/reviews/REVIEW-gpt6astra-20260914.md +112 -0
  102. package/docs/internal/reviews/ROUND3-REVIEW-INTEGRATION-20260914.md +230 -0
  103. package/docs/prompts/M8-3-enable-verify.md +49 -49
  104. package/docs/screenshots/promo/promo-0-banner-v3.png +0 -0
  105. package/lib/acceptance.js +71 -0
  106. package/lib/activation-host.js +153 -18
  107. package/lib/activation-inbox.js +25 -7
  108. package/lib/board-mode.js +30 -0
  109. package/lib/client.js +1758 -90
  110. package/lib/config-io.js +156 -0
  111. package/lib/context-bridge.js +5 -2
  112. package/lib/context-host.js +86 -15
  113. package/lib/degrade.js +385 -0
  114. package/lib/dsh-home.js +143 -0
  115. package/lib/engine-identity.js +149 -0
  116. package/lib/engine-switch.js +247 -0
  117. package/lib/episodic-store.js +63 -12
  118. package/lib/evidence-store.js +10 -3
  119. package/lib/fact-store.js +22 -3
  120. package/lib/fs-retry.js +46 -0
  121. package/lib/index-sync.js +13 -1
  122. package/lib/index.js +3446 -263
  123. package/lib/intent-clean-safe.js +258 -0
  124. package/lib/intent-clean.js +12 -16
  125. package/lib/l0-extract.js +478 -149
  126. package/lib/l0-index-sync.js +195 -0
  127. package/lib/l0-index.js +349 -239
  128. package/lib/ledger-criteria.js +142 -0
  129. package/lib/m4-corpus.js +8 -2
  130. package/lib/m7-index-sync-host.js +73 -5
  131. package/lib/m7-wire.js +3 -3
  132. package/lib/memory-anchor.js +56 -1
  133. package/lib/memory-envelope.js +257 -0
  134. package/lib/memory-hub.js +138 -13
  135. package/lib/memory-index.js +4 -2
  136. package/lib/memory-mutation.js +246 -0
  137. package/lib/memory-writer.js +204 -24
  138. package/lib/note-status-apply.js +118 -0
  139. package/lib/note-status.js +196 -0
  140. package/lib/procedure-observation.js +48 -0
  141. package/lib/procedure-store.js +118 -20
  142. package/lib/python-setup.js +1 -1
  143. package/lib/python-sidecar-client.js +29 -3
  144. package/lib/recall-fusion.js +83 -12
  145. package/lib/rerank-host.js +160 -0
  146. package/lib/rules-edit.js +159 -0
  147. package/lib/rules-layer.js +261 -0
  148. package/lib/semantic-decide.js +41 -8
  149. package/lib/semantic-js.js +66 -6
  150. package/lib/shadow-host.js +3 -5
  151. package/lib/shadow-retrieval.js +3 -3
  152. package/lib/skill-export-host.js +153 -0
  153. package/lib/skill-export.js +239 -0
  154. package/lib/state-commit.js +245 -0
  155. package/lib/storage-manage.js +6 -0
  156. package/lib/subagent-gc.js +4 -8
  157. package/lib/temporal-parse.js +191 -159
  158. package/lib/tier-layer-inject.js +650 -0
  159. package/lib/tier0-catalog.js +735 -0
  160. package/lib/water-window.js +263 -186
  161. package/lib/wb-contract.js +691 -0
  162. package/lib/wb-sidecar.js +890 -0
  163. package/lib/ws-overview-rank.js +2 -2
  164. package/package.json +1 -1
  165. package/python/m7_embedding_v1.py +5 -5
  166. package/python/worker_semantic_v1.py +17 -6
  167. package/python/worker_v1.py +38 -4
@@ -0,0 +1,269 @@
1
+ # 规划层裁决记录 · 2026-09-14 夜(思维拟合会话)
2
+
3
+ > **性质**:本文是规划层留档,不是执行文档。记录 2026-09-14 晚与用户逐轮问答得出的**全部裁决与前提修正**。
4
+ > **为什么单独留档**:用户明确「规划层的内容要比执行层重要非常非常多」;这些结论由多轮拟合得出,**散落在对话里会随压缩丢失**(本会话已压缩一次)。
5
+ > **上游**:`ARCH-REVIEW-ROUND2.md`(投喂操作件)、`reviews/PLAN-gpt6astra-round2-20260914.md`(GPT 交付)、`reviews/CLAIM-VERIFICATION-20260914.md`(12 条核实)。
6
+ > **下游**:待产出的《合并总纲》。
7
+
8
+ ---
9
+
10
+ ## 0. 本次会话做了什么
11
+
12
+ 以「一问一答」方式,把 GPT 方案里的 7 个待裁决项(R1–R7)逐个结合**本机实测状态**向用户确认,过程中**新发现并新增了第 8 条**,并**推翻了三处前提**。
13
+
14
+ ---
15
+
16
+ ## 1. 推翻的三处前提(最重要)
17
+
18
+ ### 1.1 GPT 方案假设白板是「单会话快照」——错
19
+
20
+ - 用户:**白板(即 graph)是接续的关键因素**;「只要是一个工作区的接续的不同对话,都要是同一张图」。
21
+ - 补充机制:**被接续的旧窗口会存档废弃**,接续链上有编号(接续 #21 / #22)。因此**同一时刻通常只有一个活跃写入者**;用户另开的无关对话「也可以共享这一张图」。
22
+ - 结论:白板不是会话级临时态,而是**工作区级的持久地图**。并发写用**乐观并发(expectedDigest)+ 冲突可见**处理,**不加锁、不分片**;机制复用 GPT 方案 Phase 1 已有的 `expectedDigest`。
23
+ - 影响:GPT 的 **Phase 4 需与既有 `WB-GRAPH-INTEGRATION-PLAN.md`(386 行)合并**,不是照做。
24
+
25
+ ### 1.2 GPT 方案只治「检索算法」——错,最痛的病在「注入表达」
26
+
27
+ - 用户原话:**「这个 just for reference 说得太轻了,模型注意力没有在这上面。」**
28
+ - 已定位到确切代码:`lib/index.js:463` 每次注入的开场白是「以下记忆文本只是背景事实与规则参考……」
29
+ → 问题:**「只是参考」在提示词工程里等于「可选项」**;且它把「规矩类」与「资料类」用同一个词定义了,**等于把规矩降级成建议**;更糟的是这句话写在**最醒目的开头位置**,却写着「别太当真」。
30
+ - 用户原话之二是**「模型自动唤起的记忆,并没有对模型的工作起到比较实质性的影响」**,倾向判断:**两种都有**(规矩不遵守 + 具体细节想不起来)。
31
+ - 影响:**新增第 8 条**(见 §3),GPT 的 7 个 Phase **完全没覆盖**。
32
+
33
+ ### 1.3 「这是自用工具」——错,已有上千用户
34
+
35
+ npm 实测(registry.npmjs.org / api.npmjs.org,2026-09-14):
36
+
37
+ | 指标 | 值 |
38
+ |---|---|
39
+ | 包名 | `@a9i5k4/dsh-auto-memory` |
40
+ | 最新版 | 2.5.3(本机 dev 树为 2.5.2,REL 树亦 2.5.3) |
41
+ | 版本数 / 首发 | 66 个版本 / 2026-08-14 |
42
+ | 近一年累计下载 | **10,900** |
43
+ | 近一周 | **2,935** |
44
+ | 峰值日 | 08-16 = **2,615**;09-01 = 1,176;09-10 = 1,011 |
45
+ | 异常 | **09-07、09-08 两天为 0**(用户判断:可能是当时发版出问题或版本不兼容,**不深究**) |
46
+
47
+ - 用户反问「你觉得现在要给多少人做」——即**已经不是自用工具**。
48
+ - 影响:**兼容档必须真做**(弱机器降级要有实测上限);「新旧并存 + 开关回退」从「稳妥」升级为「必须」;错误提示、切档进度条属于必需品而非体验优化。
49
+
50
+ ---
51
+
52
+ ## 2. R1–R7 裁决结论(结合本机实测)
53
+
54
+ ### R1 排序展示 —— **双显示**(用户裁定)
55
+
56
+ - 用户:「两个都显示是非常好的。而且一般不会真的有人去点开上下文注入去看吧。这是给机器看的,又不是给人看的。」
57
+ - **实测澄清**:`memory_recall_pre` 返回的数字是**稠密余弦相似度**(`lib/index.js:4429`,过滤线 `minScore: 0.5`,按它降序);排序侧的 RRF 分与原始分**已在数据结构里**(`recall-fusion-pre.js:35` 明确「原始分数逐条保留供审计」)。
58
+ - 因此「双显示」接近**零成本**(数据已在手上,只是 UI 未显示)。
59
+ - **关键区分**:UI 上的分数是**给人调试**用的;模型看到的是**注入文本**。两条展示链路不应混。
60
+ - UI 上显示顺序:**相似度在前,融合排序分在后**。
61
+ - 与 S5.4 的关系:因为**没有拿融合分冒充相似度**(两个都摆出来),冲突不存在。
62
+
63
+ ### R2 margin / 决策阈值 —— **维持现有架构**(工程判断)
64
+
65
+ - 代码里已经做对了:`recall-fusion-pre.js:10-12` 明确「**融合分数只用于排序;是否注入的决策必须使用绝对分数(稠密余弦)与校准阈值比较**」。
66
+ - 实测记录(`lib/index.js:7254`):「bge-m3 校准的 0.03 对 e5 的压缩分布过严(live 实测 margin 0-0.0284 全被拦)」→ **两档的 margin 尺度不同,不能互相套用**。
67
+ - 裁决:新策略**消费带版本的融合间隔必须重新校准**(采纳 GPT 的 R2 推荐);旧 `margin` 定义与阈值**冻结**,新特征先跑 shadow。
68
+
69
+ ### R3 注入预算边界 —— **分开算**(用户裁定)
70
+
71
+ - 用户:「以目前的情况来说,分开算应该是非常好的。反正可以让用户在设置里随便改。」
72
+ - **实测修正**:本机 `injectBudgetChars` 实际为 **4800**,而 GPT 方案的成本模型假设是 **2000**——**方案建立在一个用户并未使用的数字上**。
73
+ - 裁决:**记忆条目一个额度,其他动态内容(白板 / 账本 / 日历 / 外部记忆)另一个总额度**。
74
+ - **但新增一条覆盖规则**:**规则类不参与任何预算裁剪**(见 §3)。
75
+ - 附带:设置页「大修、提升 UI 质感与可操作度」记为**独立排期项**,不塞进 Phase 0–6。
76
+
77
+ ### R4 共用契约 —— 按 GPT 推荐(无异议)
78
+
79
+ 两档共用流程、字段与判据,允许适配器、数量与预算不同;避免把「同路径」解释为「相同的模型调用」。
80
+
81
+ ### R5 白板 lint —— **要做,且归属变更**(用户裁定)
82
+
83
+ - 用户:「这个白板后面我要 combine 进 dsh graph 这个开源项目……这个用户是肯定要看的,而且这个肯定是需要改的。甚至有些不明白的时候,AI 可以主动去向用户提问。」
84
+ - 裁决:lint **要做**,且**不只是报告**——有问题要能改;AI 不明白时可**主动向用户提问**。
85
+ - **归属**:并入 WB-GRAPH 重构,**不单独作为 Phase 4 的一部分**。
86
+
87
+ ### R6 白板人机分区 —— **需要用户手写区**(用户裁定,推翻了「全 AI 维护」的初答)
88
+
89
+ - 用户先说「全是 AI 写的,由 AI 来维护」,随后**自我修正**:「确实需要有用户手写区来保护用户,或许有时候确实需要手动去改。然后 AI 应该也会有和用户共同编辑。」
90
+ - **实测现状(关键)**:`WB-FORMAT-CONVENTION.md` §5 **早已定义人机分区**(每张卡片分 `<!-- model -->` / 用户区,永不互相覆盖),但**实际 PLAN.md 里一个锚点、一个分区标记都没有**——规范已批准、**代码从未实现**。
91
+ - **这解释了今天早些时候那个事故**:没有锚点、没有分区 ⇒ **整篇覆盖是唯一可行的写入方式** ⇒ 系统自动快照一写,白板全貌就没了。
92
+ - 裁决:分区要真做,并入 WB-GRAPH 重构 P1/P2。
93
+
94
+ ### R7 数值与计量 —— 按 GPT 推荐(无异议)
95
+
96
+ 定义源记录已批准数值,行为测试独立验证;字符估计只标「估计」,真实 tokenizer 计量另报。
97
+
98
+ ---
99
+
100
+ ## 3. 新增第 8 条(GPT 方案完全没有)
101
+
102
+ ### 8.1 病症
103
+
104
+ 用户原话(本次会话最有价值的信号):
105
+
106
+ > **「just for reference 说得太轻了,模型注意力没有在这上面。」**
107
+ > **「模型自动唤起的记忆,并没有对模型的工作起到比较实质性的影响。」**
108
+
109
+ ### 8.2 两条独立病因
110
+
111
+ | | 病因 | 证据 |
112
+ |---|---|---|
113
+ | **A. 措辞** | 注入开场白把「规矩」与「资料」统一降格为「参考」;且写在最醒目位置却写着「别太当真」 | `lib/index.js:463` |
114
+ | **B. 节奏** | `snapshotMinGapRounds = 5` ⇒ **规矩在第 2–5 轮不在场**;模型不是不听话,是**没收到** | `lib/index.js:326`、`7455` |
115
+
116
+ ### 8.3 裁决:规则/参考分层
117
+
118
+ | 层级 | 存放 | 注入节奏 | 预算 | 谁写 |
119
+ |---|---|---|---|---|
120
+ | **用户级规则** | 用户级记忆(现有 `~/.dsh/memory/MEMORY.md`) | **每个工作区、每轮都注入**(相当于用户画像) | **不参与预算裁剪** | AI 写入,用户可改 |
121
+ | **工作区级规则** | 工作区自己的规则文件 | **每轮都注入** | **不参与预算裁剪** | AI 写入,用户可改 |
122
+ | **参考类** | 现有 `MEMORY.md` / 日志 / 反思 | 三层漏斗(目录常驻 → 摘要 → 原文) | 受 R3 的额度约束 | 现有机制不变 |
123
+
124
+ - 用户裁定:**两层都要**(工作区级 + 用户级)。换工作区 = 换工作区级规则;用户级跨工作区恒定。
125
+ - 用户补充的**膨胀对策**:「让规则写得稍微克制一点,以每个工作区为锚点」。
126
+ - **成本可行性**:规则几乎不变 ⇒ 位于注入前缀 ⇒ **命中 DeepSeek 前缀缓存(约原价 1/10)** ⇒ **每轮注入的边际成本极小**。用户判断「注入这点东西用不了多少缓存预算」**成立**。
127
+ - **分类时机(用户裁定,重要)**:**不做成独立 LLM 调用**。`memory_log` 本来就在**本轮内由模型直接写**(「这个是直接写的,就在本轮当中确定什么是规则、什么是参考」),顺手打标 = **零额外成本**。将来 procedural memory 同理。
128
+ - **反驳与保留(我的建议,待用户确认)**:AI 分类的风险是**漏判**——真规则被判成「偏好」就会掉进参考类,**而这正是要修的病**。建议**前缀双保险**:出现 `【用户硬性规则】`/「严禁」/「必须」/「绝不」等字样时,**无论 AI 怎么判一律强制进规则类**。规则集小,多塞代价低;漏一条的代价是反复纠正。
129
+
130
+ ### 8.4 附带的 UI 缺口(用户提出)
131
+
132
+ - 用户:「这个约束性的东西**必须得让用户看到**,并且让用户能进行精修。比如在记忆窗格的可视化里面,能够让用户看到目前模型有什么约束。」
133
+ - **实测**:记忆窗格现有 **12 个标签页**(概览 / 日志 / 精炼 / 记忆中枢 / 存储 / 笔记 / 白板 / 反思 / 连接 / 日历 / 工作区……),**没有任何一页显示「当前模型受什么约束」**。
134
+ - 裁决:新增「约束」视图,归入**UI 提质排期**。
135
+
136
+ ---
137
+
138
+ ## 4. 引擎隔离与切换(用户裁定)
139
+
140
+ - 用户:「本来它们就是分隔的,只要在切换的时候强制前排(全量重建)就可以了。直接给用户显示一个进度条。」
141
+ - **实测两档用的是两个不同模型**:C2 = `Xenova/multilingual-e5-small` q8(端侧);C3 = `Xenova/bge-m3` int8(Python sidecar,555MB)。**向量空间不通用**。
142
+ - 代码已有意识(`PROVIDER_ID_INT8 = 'bge-m3-onnx-int8-pre-v1'`),**但没做成硬约束**。
143
+ - **新增能失败断言 T2-9(引擎隔离)**:用 e5 建的索引,切到 bge-m3 后**必须整体失效并重建**;若出现两套向量参与同一次排序,**判失败**。成本为零(仅加身份校验)。
144
+ - **用户强调的耦合约束**:切档进度条**必须并进现有「引导 / 向导」体系**(Python BGE 下载、venv 建环境已有可视化指导),**不得另起一套**。
145
+
146
+ ---
147
+
148
+ ## 5. 精排(H2)——方案被实测数据推翻,需重写
149
+
150
+ ### 5.1 方案假设 vs 实测
151
+
152
+ | | GPT 方案假设 | 本机实测(`artifacts/m7-rerank-pre/results.json`) |
153
+ |---|---|---|
154
+ | 额外等待 | **≤750 ms** | **bge-reranker-v2-m3:P95 37.4 秒;qwen3-reranker-0.6b:P95 8.8 秒** |
155
+ | 模型资产 | U5「缺,阻塞」 | **已下载**(bge-reranker-v2-m3 2.1GB / qwen3-reranker-0.6b 1.1GB,各带 tokenizer) |
156
+ | 精度收益 | 未量化 | **recall@1:0.739 → 0.898(bge)/ 0.800(qwen)** |
157
+
158
+ ### 5.2 硬件实测(我最初查错了,此处更正)
159
+
160
+ - **有可用显卡**:`NVIDIA GeForce RTX 4070 Ti SUPER`,**16GB 显存**,驱动 616.64。
161
+ - (我最初只列了前 3 个显示适配器就误判「无 GPU」,**此处更正并留痕**。另有 AMD Radeon 集显 + 3 个虚拟适配器。)
162
+ - 当前 Python 环境:`torch 2.13.0+cpu`(**CPU 版**)、`transformers 5.15.1`、`onnxruntime 1.23.2`、16 核 CPU、31GB 内存。
163
+
164
+ ### 5.3 用户裁定:改为「多级选项」
165
+
166
+ 用户原话:「这恐怕是一个**可以多级选项**的问题。发烧友、追求高质量的人或者研究人员,可以打开显卡加速进行精排……普通用户的话,用粗排就可以……(或者只在主动翻记忆的时候跑。亦或者拉长自动注入的时间。反正目前自动注入的时间窗口间隔是 1 分钟,也是可以改的。)」
167
+
168
+ | 档 | 谁用 | 跑在哪 | 触发时机 |
169
+ |---|---|---|---|
170
+ | **关** | 默认 | — | 不精排,纯粗筛 |
171
+ | **快档** | 普通用户 | int8 量化 / ONNX / CPU | 主动翻记忆时 |
172
+ | **发烧档** | 作者 / 研究者 | 完整模型 + RTX 4070 Ti SUPER | 主动翻记忆 + 可选自动注入 |
173
+
174
+ **并且新增方案里没有的机制**:精排改为 **1 分钟异步窗口** —— 本轮先用现有排序,精排在后台跑完,**结果留给下一次注入**。「准确率」与「不卡等待」不必二选一。
175
+
176
+ ### 5.4 两个开发中遇到的实测坑(保留)
177
+
178
+ - **精排模型量化后更小更快**:用户提到 `multilingual` 100 多 MB、`bge` 500 多 MB(= `models-xenova-bge-m3-int8`,实测 555MB),比完整版快很多。
179
+ - **已有 int8 vs fp32 对照脚本**:`python/bench/l2_bench_int8_vs_fp32.py`(尚未读到结果,待补)。
180
+
181
+ ---
182
+
183
+ ## 6. 用户级判断:成本模型的正确算法
184
+
185
+ 用户反问:「你觉得这个成本模型的成本要怎么算?反正付钱的又不是我给这几千人一起付,是他们自己付自己的钱。」
186
+
187
+ **结论:我原先的推理有隐含错误**——把「上千用户 × 每轮注入」当成**一张账单**来吓自己。真实情况:
188
+
189
+ | 项目 | 谁付钱 | 对作者的成本 |
190
+ |---|---|---|
191
+ | 记忆注入 token | 用户自己的 API key | **0** |
192
+ | 精排算力 | 用户自己的机器(本地推理) | **0** |
193
+ | 嵌入建索引 | 用户自己的机器(一次性 + 增量) | **0** |
194
+
195
+ - 「上千用户」对**成本模型的影响为 0**;真正的影响是**代码质量**(bug 被放大)与**兼容档必须真做**。
196
+ - 推论:**该省的地方是「别浪费」(不重复注入同样内容),不该省的地方是准确性**;而前缀缓存让「规则每轮注入」的边际成本极小。
197
+
198
+ ---
199
+
200
+ ## 7. 白板 / graph 的战略裁决(用户裁定:(乙))
201
+
202
+ 用户裁定:**「(乙) 两者合并:把 GPT 的『写入门 + 引擎隔离 + 状态过滤』这套通用原则,注入到你 WB-GRAPH 方案的 P1/P2 里。」**
203
+ 并补充:**「我认为这个 dsh graph 正是我想要的 Karpathy 模块。」**
204
+
205
+ 查证结果(仓内既有资产):
206
+
207
+ | 文档 | 规模 | 状态 |
208
+ |---|---|---|
209
+ | `WB-GRAPH-INTEGRATION-PLAN.md` | 386 行 | 2026-09-13 完成,含判据 Schema、sidecar 设计、两工具方案 |
210
+ | `WB-GRAPH-DECISIONS-20260914.md` | 54 行 | 一页纸拍板点(A1–A8 / B1–B7),**大部分仍标 🎯 未拍板** |
211
+
212
+ **GPT 的 Phase 4 与既有 WB-GRAPH 方案的差异**:
213
+
214
+ | | GPT Phase 4 | WB-GRAPH 方案 |
215
+ |---|---|---|
216
+ | 目标 | 白板进语料 + 写入门 + lint | 白板 → **看板化**(combine dsh-graph) |
217
+ | 判据 | 卡片集合比对 | 完整判据表(H1–Hn) |
218
+ | 存储 | 直接改 Markdown | **Markdown = 人读真相源,sidecar JSON = 机读派生件** |
219
+ | 检索 | 进 L0 语料 | **新增两工具**(expand / trace),工具数 14 → 16 |
220
+ | 人机 | 用户区保护(一整块) | **每卡片分区**(模型区 / 用户备注区) |
221
+
222
+ **合并后的分工(我的建议,待确认)**:
223
+ - GPT Phase 4 中**真正新增**的只有 **lint** 一项 → **挂到 WB-GRAPH 的 P1 上**;
224
+ - 「写入门的前后比对」与 WB-GRAPH 的 **B1 同源** → 合并实现;
225
+ - 「用户区保护」与 **B4 选项 (c)** 同源 → 按 WB-GRAPH 的每卡片分区做;
226
+ - GPT 的 **引擎隔离(T2-9)与状态过滤(C8)** 属 Phase 0/2,**不随白板走**。
227
+
228
+ ---
229
+
230
+ ## 8. 评测题集(U3)
231
+
232
+ - 用户:题集是**很早期初创算法时做的**,后面需要**结合已有记忆(现在记忆量已丰富)继续优化算法,或再整一套丰富的测试题和标准答案**。
233
+ - 待查:`python/bench/results/m7-2-results.json`(799KB)与 `m7-2-l2-results.json`(468KB)的内容形态。
234
+ - **建议方向(待确认)**:新题集应当**从真实记忆语料出发**(用户已有大量真实记忆),而不是凭空造题——这样才测得出「真实使用中的召回质量」。
235
+
236
+ ---
237
+
238
+ ## 9. 开工节奏与风险(用户裁定)
239
+
240
+ - 用户裁定:**要新旧并存 + 开关切换,随时能退回**。
241
+ - 用户裁定第一步:**先出《合并总纲》**。
242
+ - 用户追问:现在可以开工了吗?还是先找 GPT 再咨询 / 总纲出来再让 GPT 审一遍?
243
+
244
+ **我的建议(写作本文时给出)**:
245
+
246
+ > **总纲 → 我方先做「矛盾扫描」→ GPT 审 → 开工**
247
+
248
+ 理由:GPT 审之前,两份方案(它的 7 Phase 与 WB-GRAPH)之间的**表面对齐**应由我方先做;否则它会花大量篇幅指出「你这跟我的 Phase 4 不一样」——那是**已知信息**。让它审「调和是否正确」,比让它审「自己的方案」有效得多:**它能发现自己没考虑的整合问题,发现不了自己没想到的东西**——后者今天这场对话已经做了。
249
+
250
+ **开工前必须先补的三件**:
251
+ 1. 《合并总纲》(含 GPT 7 Phase + 第 8 条 + WB-GRAPH 的合并与排序);
252
+ 2. 矛盾扫描结果(两份方案冲突清单 + 调和方案);
253
+ 3. **不做**:在总纲出来前动 `lib/index.js` 的注入链。
254
+
255
+ **唯一的例外(可以立刻做、且建议做)**:
256
+ - **C8 缺陷修复**——`superseded` / `retracted` 条目**现在真的会进入注入文本**(本会话已用 `tools/_redproof/red-proof-phase0-t01.mjs` 跑出 4/4 报红)。这是一个**正在发生的真实危害**,且修复范围极小、可独立回滚。
257
+
258
+ ---
259
+
260
+ ## 10. 本次会话产出的文件
261
+
262
+ | 文件 | 内容 |
263
+ |---|---|
264
+ | `docs/internal/reviews/REVIEW-gpt6astra-20260914.md` | 第一轮评审原文(补录,此前并未真正落盘) |
265
+ | `docs/internal/reviews/CLAIM-VERIFICATION-20260914.md` | 12 条主张逐条核实(12/12 成立) |
266
+ | `docs/internal/ARCH-REVIEW-ROUND2.md` | 第二轮投喂操作件 |
267
+ | `docs/internal/reviews/PLAN-gpt6astra-round2-20260914.md` | GPT 第二轮交付:RAG+Karpathy 实施方案 v1(37071 字) |
268
+ | `tools/_redproof/red-proof-phase0-t01.mjs` | T0-1 断言的「能红」证明(4/4 报红) |
269
+ | **本文** | 规划层裁决记录 |
@@ -0,0 +1,219 @@
1
+ # P1 设计稿 · 统一状态提交与快照(miv 单源)+ 并发原子边界
2
+
3
+ > 状态:**待审**(先审后写代码 —— 用户裁定顺序:设计稿是必审点)
4
+ > 依据:`MASTER-PLAN-3.0.md` Phase 1(§216-227)、`TODO-GRAPH.html` 卡 `V2-P1`、`ROUND3-REVIEW-INTEGRATION-20260914.md` §3.2
5
+ > 作者:执行方 · 日期:2026-09-15 · 全部 file:line 为**本机实测**取值,非转述
6
+
7
+ ---
8
+
9
+ ## 0. 一句话目标
10
+
11
+ 把「谁在写、写的什么版本、写完算不算数」收敛成**一个提交边界**:所有窗口经同一工作区 owner 提交,
12
+ 提交时在边界**内**校验 `expectedDigest` 与 `miv`;快照的 `miv` 成为**唯一事实源**(内容身份 + 状态清单摘要,
13
+ 哈希身份、不递增、不比较)。并发不加锁,靠「队列串行 + 边界内比较」保证恰好一项成功、另一项收到**可见冲突**。
14
+
15
+ ---
16
+
17
+ ## 1. 现码取证(每条都可在本机复现)
18
+
19
+ ### 1.1 已有的好东西(**不要重造**)
20
+
21
+ | 机制 | 位置 | 实测语义 |
22
+ |---|---|---|
23
+ | 短提交队列 | `lib/memory-writer-pre.js:235 _queue` | 按 `path.resolve(filePath)` 分键串行;空闲即回收 Map 条目(`:242`),无界增长已处理 |
24
+ | 原子写 | `lib/memory-writer-pre.js:199 atomicReplace` | 同目录 tmp + fsync + rename。**签名里没有 `expectedDigest`** —— 它**不是** CAS,只做原子写 |
25
+ | 边界内 digest 校验 | `lib/memory-writer-pre.js:344 replace` / `:332` / `:357` / `:369` / `:380` | 五个提交方法**都在 `_queue` 内部**先比 `expectedDigest`,不匹配返回 `{ok:false, reason:…}`;**这是当前唯一正确的并发保护** |
26
+ | 无 BOM 闸 | `lib/memory-writer-pre.js:287` | 提交前拒 BOM(用户硬性规则的代码级保障) |
27
+ | 写入门 | `lib/memory-mutation-pre.js:76 validateMutationBoundaryPre` | 只收规范化投影(`beforeIds`/`afterIds`/`archivedIds`);`M1 丢卡保护`无条件生效(`:99-101`) |
28
+ | 门调用点 | `lib/index.js:1984` | **全仓唯一实调**(`memory-mutation-pre.js:231` 是自身内部调用) |
29
+
30
+ ### 1.2 缺口(P1 要修的)
31
+
32
+ **(a) `miv` 有生成、无单源,且**没有被提交边界校验****
33
+
34
+ - 生成:`lib/shadow-retrieval-pre.js:144` —— `idx_pre_ + first32hex(sha256(canonical corpus tuples))`;经 `lib/m4-corpus-pre.js:128` → `context-host-pre.js:216/393` 装配进快照。
35
+ - 消费:`lib/activation-host-pre.js:102 setMiv` / `:252 currentMiv` 只做**缓存**(`mivCache = {wsRef, miv}`),`setMiv` 是**显式写入口**(`:111`)——即"谁调谁说了算",**没有单一权威计算点**。
36
+ - **关键缺口**:`memory-writer-pre.js` 的提交方法**只比 `expectedDigest`,完全不看 `miv`**。⇒ 图内容变了但 digest 恰好相等(或调用方没传 digest)时,快照仍可能带着**旧 miv** 发出去。
37
+
38
+ **(b) ~~复用命中只查 `contextVersion`,不查 `miv` ⇒ 契约 I6 失守~~ —— ★施工期核实:本条已过时,撤销**
39
+
40
+ > **勘误(实测取证,非推断)**:以下三行是**当时**(09-14 评审 C9 口径)的判断;动手前逐行复核,现状已是:
41
+ > - 投影**已携带** miv —— `lib/activation-host-pre.js:165`:`miv: String(req.memoryIndexVersion || '') || undefined`(同处 `:164/166/167` 带 `contextVersion`/`observationId`/`requestKey`);
42
+ > - 版本门**已含 miv 两道 fail-closed** —— `lib/tier-layer-inject-pre.js:200-204`:`if (!curMiv || !projMiv) return no('version-unknown')` / `if (curMiv !== projMiv) return no('miv-changed')`;
43
+ > - 调用方**已传当前 miv** —— `lib/index.js:4269`:`miv: this.tierCurrentMivPre()`;
44
+ > - **且有专项测试** —— `tests/smoke/smoke-test-t0-2-version-gate-pre.mjs:75`(`miv-changed`)、`:96/:103`(`version-unknown` 两侧)。
45
+ >
46
+ > **结论**:I6 在 P1 开工前**已由 P0 的 T0-2 守住**。§3 表中「I6 失守 → 守住」一栏作废;原 §2.4(版本门补 miv)**从改动清单撤销** —— 重复实现只会引入回归风险。
47
+ > **教训**:外部评审结论带时间戳,动手前必须用**当前**代码复核,不得把评审描述当现状直接排进施工项。
48
+
49
+ *(以下为当时的分析原文,仅作留痕,勿据此施工)*
50
+
51
+ - 契约原文 `docs/internal/THREE-LAYER-CONTRACT.md:184`:**I6** 三层来自同一份快照(同一 `miv`),混版视为错误。
52
+ - 实测 `lib/tier-layer-inject-pre.js:169 selectReusableTierHitsPre`:① 时间门(`:186`)② 身份门 session/workspace(`:188-194`)③ **版本门只有 `contextVersion`**(`:195-198`)。**`gh.miv` 虽被读入快照字段(`:177`)却不参与判定** ⇒ 语料换了、miv 变了,只要 contextVersion 没变就**照样复用旧命中**,三层可能混版。
53
+ - 这与我方 09-14 外部评审 **C9** 结论一致(`lib/index.js:3894/3896/3901` 复用命中只查时间与会话)。
54
+
55
+ **(c) 提交接口没有来源身份**
56
+
57
+ - 现签名(`memory-writer-pre.js:344`)只收 `expectedDigest` + `replacement` + `idFactory`。
58
+ - 缺 `workspaceKey / boardId / txId / actor` ⇒ 冲突被拒时**说不出"谁和谁撞了"**,`mutationRefusalTextPre`(`:212`)也拿不到 actor 信息。
59
+
60
+ **(d) 共享 vs 隔离虽已分开,但缺显式声明**
61
+
62
+ - 图(共享):按工作区分键(`_queue` 的 key 是文件路径;工作区文件路径天然隔离)✓
63
+ - 激活/冷却/已交付标记(隔离):`lib/activation-host-pre.js` 的 `registry.forRuntime(sessionId, workspaceKey, …)`(`:132/248`)已按会话隔离 ✓
64
+ - **缺**:这个"哪些共享、哪些隔离"的边界目前只存在于代码直觉里,没有写成常量表 ⇒ 后续 P6B 容易越界。
65
+
66
+ **(e) 三种状态目前无类型隔离**
67
+
68
+ - 记忆有效状态:`current / superseded / retracted`(契约 I5,`index.js` 注入侧过滤)
69
+ - 任务进度:`done / passed / archived`(看板语义)
70
+ - 归档位置:`archived`(同时也是任务态 —— **同名不同义**)
71
+ - 风险:`archived` 一词两义,跨线传递时会误判。P1 只做**命名隔离**(见 §2.3),不做语义合并。
72
+
73
+ ---
74
+
75
+ ## 2. 改动清单(按依赖序,每步可独立回归)
76
+
77
+ ### 2.1 【新增】`lib/state-commit-pre.js` —— 统一提交契约(纯函数,零依赖)
78
+
79
+ ```js
80
+ export const STATE_COMMIT_VERSION_PRE = 'state_commit_pre_v1'
81
+
82
+ // 提交单据(P1 唯一的写入契约)
83
+ // { workspaceKey, boardId, txId, expectedDigest, expectedStateVersion,
84
+ // actor: { sessionId, contSeq, kind }, // kind: 'user' | 'plugin' | 'model' | 'system'
85
+ // writes: [{ path, content, expectedDigest }],
86
+ // stateChanges: [{ target, from, to }] }
87
+
88
+ export function buildStateCommitPre(input) // 归一化 + 必填校验,缺字段 fail-closed
89
+ export function commitConflictPre(commit, observed) // → { ok:false, reason, detail:{ expected, observed, actor, boardId } }
90
+ export function commitReceiptPre(commit, result) // → { txId, boardId, miv, digest, at, actor }
91
+ ```
92
+
93
+ **`boardId` 硬约束(卡内明确要求)**:在工作区内**稳定**、**不含当前会话号**
94
+ ⇒ 由 `sha256(workspaceKey + '|' + scope)` 派生,**不得**掺 `sessionId`。理由:接续后新窗口换 sessionId,
95
+ 若 boardId 跟着变,图就会被当成两块,共享语义直接崩。
96
+
97
+ ### 2.2 【新增】`miv` 单源:`memoryIndexVersionPre(projection)`
98
+
99
+ > **★2026-09-15 施工期核实:§6 第 2 步「收敛 `activation-host-pre.js:111 setMiv`」已撤销。**
100
+ > 实测 `setMiv`(`lib/activation-host-pre.js:111` + 孪生 `lib/activation-host.js:111`)**全仓零调用者**(`lib/`、`tests/`、`lib/client.js` 全量检索仅命中其自身定义行)⇒ 它是**死代码**,
101
+ > **没有"活跃写者"需要收敛**。真实 miv 更新路径是 `:100-104` 的 `corpusRegistry.get(catalog)` 分支(`mivCache = { wsRef: ws, miv: res.snapshot.memoryIndexVersion }`),
102
+ > 而该 `memoryIndexVersion` 来自契约 §8 的 `shadow-retrieval-pre.js:145 memoryIndexVersion(sources)` —— **它才是建索引侧真源**。
103
+ > 结论:P1 **不删死代码、不动 `mivCache`**(删死代码属独立清理项,不混进 P1;动了反而扩大回归面)。
104
+
105
+ ```js
106
+ // lib/state-commit-pre.js
107
+ export function memoryIndexVersionPre(projection) {
108
+ // 输入:{ records:[{id, status, l0?}], boardCards?:[{id, status}], scope }
109
+ // 输出:'idx_pre_' + first32hex(sha256(canonical))
110
+ // canonical = 按 id 升序的 [id, status, contentDigest] 三元组(换行拼接,无尾随空白)
111
+ }
112
+ ```
113
+
114
+ **三条硬规则**(卡内 T1-5 扩展口径):
115
+
116
+ 1. **内容身份 + 状态清单摘要**:`status` 进摘要 ⇒ 仅状态变化(`current→superseded`)**miv 必变**。
117
+ 2. **不递增、不比较**:miv 是哈希身份,**不是版本序**。任何代码不得写 `if (miv > lastMiv)`。
118
+ 3. **白板卡片状态也进摘要**:`boardCards` 参与 canonical ⇒ 扩到白板。
119
+
120
+ **必须废弃的口径**:WB-GRAPH 的 `index.json` 里 `rebuilt_at` **不得**当版本序。它是时间戳,重建时间变但内容没变时它会变 ⇒ 用它当版本序会造成**假失效 + 真混版**。P1 交付物里包含一条断言专门钉死它。
121
+
122
+ ### 2.3 【改动】`memory-writer-pre.js`:提交方法收 `expectedStateVersion` + actor
123
+
124
+ - `replace` / `append` / `migrate` 等五个方法(`:332/344/357/369/380`)在 `_queue` **内部**、`expectedDigest` 校验**之后**,追加:
125
+ ```
126
+ if (opts.expectedStateVersion != null && state.stateVersion !== opts.expectedStateVersion)
127
+ return commitConflictPre(...) // 可见冲突,不写
128
+ ```
129
+ - **不改 `atomicReplace` 签名**(它不是 CAS,别给它加语义)。
130
+ - **不引入长期编辑锁、不按会话分片**(卡内明确否决)。队列 key 仍是文件路径。
131
+
132
+ ### 2.4 【撤销】~~`tier-layer-inject-pre.js:195` 版本门补 `miv`~~
133
+
134
+ **★2026-09-15 施工期核实后撤销**:该检查**已存在**(`:200-204`,含 `version-unknown` 与 `miv-changed` 两条 fail-closed),
135
+ 投影与调用方亦已就位(`activation-host-pre.js:165` / `index.js:4269`),并有专项测试
136
+ `tests/smoke/smoke-test-t0-2-version-gate-pre.mjs`。**I6 已守住,此处不改任何代码。**
137
+
138
+ *(以下原始改动设想作废,仅留痕)*
139
+ - ~~现:只比 `contextVersion`。改:`contextVersion` 且 `miv` 两侧可得且相等;任一侧缺 `miv` ⇒ 不复用。~~
140
+ - ~~新增拒绝原因 `miv-mismatch` / `miv-unknown`~~ ⇒ 既有实现用的是 **`version-unknown`** 与 **`miv-changed`**(`tier-layer-inject-pre.js:200-204`),命名不同因而已有测试可依。
141
+
142
+ ### 2.5 【新增】状态命名隔离常量
143
+
144
+ ```js
145
+ export const MEMORY_STATUS_PRE = Object.freeze(['current', 'superseded', 'retracted'])
146
+ export const TASK_STATE_PRE = Object.freeze(['open', 'done', 'passed'])
147
+ export const ARCHIVE_STATE_PRE = Object.freeze(['active', 'archived'])
148
+ ```
149
+
150
+ 三者**不得互转**(卡内"三种状态不能混")。`archived` 一词两义的问题以 `ARCHIVE_STATE_PRE` 独立命名解决,
151
+ **映射由白板线适配器负责**(KICKOFF §3.4 边界约定:3.0 不自行解释图格式)。
152
+
153
+ ### 2.6 【改动】冲突可见性
154
+
155
+ - `mutationRefusalTextPre`(`memory-mutation-pre.js:212`)扩字段:拒绝文本必须带**当前版本 + 冲突目标**(卡内 T1-7C 要求),形如
156
+ `[提交被拒] tx=<txId> 目标=<path> 期望 miv=<a> 实测 miv=<b> 冲突方=<actor.sessionId>@<contSeq>`
157
+
158
+ ---
159
+
160
+ ## 3. 契约影响
161
+
162
+ | 契约 | 现状 | P1 后 | 是否接口改动 |
163
+ |---|---|---|---|
164
+ | **I5** 非 current 两处过滤 | P0 已达标(注入侧 import 检索侧 `isCurrentPre`) | 不变 | 否 |
165
+ | **I6** 三层同快照(同一 miv) | **已守住**(P0 的 T0-2 已修,见 §1.2b 勘误) | **不变**(P1 不动此路径) | 否 |
166
+ | **I7** 降级必须显式标注 | 达标 | 新增 `miv-unknown` 降级行 | 否(复用既有降级通道 `index.js:4246`) |
167
+ | T1-5 仅状态变化 miv 必变 | 未覆盖白板 | 覆盖(§2.2 规则 3) | 否 |
168
+ | `validateMutationBoundaryPre` | 只收投影 | **不变**(3.0 只接收规范化投影,不解释图格式) | 否 |
169
+
170
+ **兼容档**:~~`memoryMutationMode='readonly'`(既有开关)~~ **★2026-09-15 施工期核实:该键在代码中不存在**
171
+ (`lib/`、`tests/`、`lib/client.js`、本机 `~/.dsh/dsh-auto-memory-pre.json` 全量检索均无命中;仅出现在 4 份文档里:
172
+ `PLAN-gpt6astra-round2-20260914.md:458/696`、`MASTER-PLAN-3.0.md:227`、本稿)。
173
+ ⇒ **P1 的实际回滚面 = 新增字段全部可选**:不传 `expectedStateVersion`(也不传 `expectedDigest`)时,
174
+ `_checkCommitBoundary` 两个闸都不触发,行为与 P1 前**逐字节一致** —— 这是已实测的(见 T1-8)。
175
+ `readonly` 若要落地,属**独立新功能**(需实现 + 配置项 + GUI),**不在 P1 范围**,另行排期。
176
+
177
+ ---
178
+
179
+ ## 4. 验收断言(**能失败**,逐条对应卡片 crit)
180
+
181
+ | ID | 断言 | 对应 crit |
182
+ |---|---|---|
183
+ | **T1-1** | 两窗口读同一 digest 后**同时**提交替换 → 恰好一项 `ok:true`,另一项 `ok:false` 且 `reason` 可见 | 卡内 T1-4 |
184
+ | **T1-2** | 成功版本内容**未被覆盖**(终态 == 成功者写入内容) | 卡内 T1-4 |
185
+ | **T1-3** | A、B 会话共享图节点;**A 的激活包与交付记录不出现在 B** | 卡内 T1-7B |
186
+ | **T1-4** | 旧接续窗口迟到写入**不能覆盖新图**;拒绝信息带**当前版本 + 冲突目标** | 卡内 T1-7C |
187
+ | **T1-5a** | 业务内容改变 ⇒ miv 变 | 卡内 T1-5 |
188
+ | **T1-5b** | **仅**状态变化(`current→superseded`)⇒ miv **必变** | 卡内 T1-5 |
189
+ | **T1-5c** | 仅切换会话、仅更新 `rebuilt_at` ⇒ miv **不变** | 卡内 T1-5 |
190
+ | **T1-5d** | 白板卡片状态变化 ⇒ miv **必变** | Phase 1 扩展 |
191
+ | **T1-6** | `boardId` 不含 sessionId:同一工作区两个不同 sessionId ⇒ `boardId` 相等 | 卡内接口要求 |
192
+ | **T1-7** | 复用命中 `miv` 不等 ⇒ **不复用**(三层不混版);任一侧缺 miv ⇒ 不复用 | 卡内 T1-5 / I6 |
193
+ | **T1-8** | `expectedStateVersion` 缺省 ⇒ 行为与 P1 前**逐字节一致**(回归守卫) | 兼容档 |
194
+ | **T1-9** | ~~`memoryMutationMode='readonly'` ⇒ 所有提交被拒~~ **★核实:该键不存在,本条改写为兼容档真值表**:① 不传 `expectedStateVersion` ⇒ 提交照常成功(零行为变化)② 传入且匹配 ⇒ 成功 ③ 传入且不符 ⇒ 拒绝且可见 | 兼容档 |
195
+
196
+ **注入式沙箱纪律**(本项目已踩 3 次):新方法被抽进 `new Function` 沙箱时,
197
+ 其引用的**所有**模块级符号必须显式列入 helpers,否则 `ReferenceError` 会被外层 `catch` 吞成"静默空内容"。
198
+
199
+ ---
200
+
201
+ ## 5. 明确**不做**的事(防止范围蔓延)
202
+
203
+ - ✗ 不加长期编辑锁、不按会话分片(卡内否决)
204
+ - ✗ 不改 `atomicReplace` 语义(它不是 CAS)
205
+ - ✗ 不引入 `miv` 序比较(哈希身份,不递增)
206
+ - ✗ 不在 3.0 内解析白板格式(KICKOFF §3.4:白板线拥有 `parseWhiteboardPre`)
207
+ - ✗ 多宿主同目录 —— **留给 U2 单独认证**;若要多进程直写同一文件,必须另加跨进程原子提交或单写者路由
208
+
209
+ ---
210
+
211
+ ## 6. 施工顺序(每步跑全量回归)
212
+
213
+ 1. `state-commit-pre.js` + 单测(纯函数,无接入风险)
214
+ 2. ~~`miv` 单源接线(`setMiv` 收敛到单一计算点)+ T1-5a/b/c/d~~ **已撤销**(见 §2.2 勘误:`setMiv` 为死代码,无对象可收敛)+ T1-5a/b/c/d ✅ **已完成**(`smoke-test-state-commit-pre.mjs`)
215
+ 3. 队列内 `expectedStateVersion` 校验 + T1-1/T1-2/T1-4/T1-8/T1-9
216
+ 4. ~~`tier-layer-inject-pre.js` 版本门补 miv + T1-7(修 I6)~~ **已撤销**(I6 由 P0 的 T0-2 守住,见 §2.4)
217
+ 5. 状态命名隔离 + T1-3
218
+ 6. 冲突可见性(拒绝文本)+ T1-4
219
+ 7. 全量回归 + 更新 `TODO-GRAPH.html` V2-P1 卡
@@ -0,0 +1,132 @@
1
+ # 方向核对清单 · WB-GRAPH 白板线(2026-09-16)
2
+
3
+ > **用途**:任务二材料。本文件是**给 GPT 及协作方核对"答题方向"**的清单——不是让 GPT 重新找 bug(那部分见 `GPT-REVIEW-PROMPT.md`),而是**确认修复方向是否正确、优先级是否合理、有没有更该做的事**。
4
+ > **前置**:任务一全量粗检已完成,结论见 `AUDIT-WB-GRAPH-FULL-20260916.md`。
5
+ > **当前状态**:**尚未动手修**。以下每一项都需要"确认/否决/改方向"三类裁决之一。
6
+
7
+ ---
8
+
9
+ ## 一、给 GPT 的三句话背景
10
+
11
+ 1. 这个插件(`dsh-auto-memory`)已在 npm 有真实用户(年下载约 10,900),**legacy 档必须字节级不变**是硬约束——任何修复都不能让老用户行为漂移。
12
+ 2. 白板线(WB-GRAPH)是"新功能 + 一键开关回退",开关默认 `legacy`。用户拍板过"一口气全做完,但线先别急着接"。
13
+ 3. 15 日下午→16 日凌晨这一批改动**不够严谨**:新代码全在闸门后、回归跑不到,于是 **PASS 95/0/0 完全掩盖了 4 条致命缺陷**。这次核对的核心问题是:**修复方向对不对**。
14
+
15
+ ---
16
+
17
+ ## 二、需要裁决的方向性问题(共 6 条)
18
+
19
+ ### Q1 ★ 注册闸门的修法:三选一
20
+
21
+ **问题**:`lib/index.js:7633` 是 `export function apply(ctx, config)`(**非 async**),而工具数组在 `apply()` 内**同步**构建(`:8506`),此刻 `engine.config` 仍是 `DEFAULT_CONFIG`(`boardMode:'legacy'`)⇒ 注册闸门**恒假**。
22
+
23
+ | 方案 | 做法 | 优点 | 风险 |
24
+ | --- | --- | --- | --- |
25
+ | A1-a | 工具无条件注册,闸门降到 **execute 内** | 改动最小 | legacy 档工具数变 16 ⇒ **违反"legacy 字节级不变"**,模型能看到不可用工具 |
26
+ | **A1-b(推荐)** | 新增**同步**读取器 `loadConfigSync()`(`readFileSync`+同合并逻辑),在 tools 构建前调用一次 | 保持 async 语义不动;启动期拿到真配置;闸门仍在注册层 ⇒ legacy 工具数仍 14 | 需保证 `loadConfigSync` 与 `loadConfig` **共用合并逻辑**,否则双源漂移 |
27
+ | A1-c | `apply` 改 `export async function apply` | 最"正统" | **需先确认 cordis 是否 await 插件 apply 的返回值**——未证实,风险最高 |
28
+
29
+ **请裁决**:A1-b 是否可行?有无第四条路(如 cordis 的 `inject`/配置注入机制本该提供启动期配置)?
30
+
31
+ > 附:本项目此前已把「工具注册须先 `await loadConfig()`」写进项目约定——**该约定本身表述有误**(apply 非 async),本次须一并更正为「启动期需要真配置时必须用同步读取器」。
32
+
33
+ ### Q2 ★ 修复顺序:先改代码还是先补测试?
34
+
35
+ **问题**:4 条致命里,**BUG-10(id 不一致)**和 **BUG-1(注册闸门)**都能被一条新测试稳定抓住。当前 20 个套件里没有一个测过 "graph 档端到端"。
36
+
37
+ **两种顺序**:
38
+ - **(a) 先补 graph 档端到端套件(红)→ 再修**(TDD 式,修复可信度高,但先要造出能过 `apply()` 的测试夹具)
39
+ - **(b) 先修 → 再补套件**(快,但容易重蹈"改完不知道有没有真修好")
40
+
41
+ **请裁决**:推荐 (a) 还是 (b)?若 (a),`apply()` 的测试夹具成本是否可控(现有 20 个套件已能调 `apply(`,说明夹具模式已存在)?
42
+
43
+ ### Q3 ★ 规划里 5 项"未做"(P2-3/P2-4/P2-5/P3-2/P3-3)是否本批一律补齐?
44
+
45
+ **背景**:这 5 项在 `WB-GRAPH-INTEGRATION-PLAN.md §5` 里**明确列了**,但 16 日凌晨没做。其中:
46
+ - **P3-3(三处工具数硬锁 14→16)被规划标为"必须项"**——不补则 graph 档测试必红。
47
+ - **P2-5(GUI 放行 `.json`)** 影响用户能否在面板里看到 `index.json`。
48
+ - **P2-3/P2-4** 是检索端与注入端的增强,**不做也不影响"能用"**,只是没兑现规划承诺。
49
+ - **P3-2** 只是一句 guide 文案。
50
+
51
+ **请裁决**:是"全补齐(严格按规划)",还是"先补齐 ①必须项(P3-3)+ ②让功能真正可用的(P2-5),其余(P2-3/P2-4/P3-2)另开批次"?
52
+
53
+ ### Q4 ★ 用户的核心诉求"实时可视化看板"(dsh-graph 接线)该不该在本批做?
54
+
55
+ **背景**:`vendor/dsh-graph/` 已搬入(MIT,含 NOTICE-VENDOR.md),但**cordis 接线未做**——因为要改**用户 profile 配置**(`~/.dsh/profiles/web/`),属高风险动作,需要先备份 + 用户明确同意。
56
+
57
+ **关键事实**:**即使前面 9 条全修完,只要 dsh-graph 不接线,用户依然"看不到看板"**——他最初的抱怨就没有真正解决。
58
+
59
+ **请裁决**:是
60
+ - (a) 本批就把 profile 接线做了(先备份,用户同意后执行),还是
61
+ - (b) 先把 memory_* 侧修干净、接线另立一步(用户可先验证 sidecar/遍历工具是否好用)?
62
+
63
+ ### Q5 ★ "白板锚点未写入 Markdown"算不算规划未兑现?
64
+
65
+ **背景**:`WB-FORMAT-CONVENTION §2` 承诺的收益是"**白板内容凭锚点自动进入检索语料**(L0 抽取按锚点切条),无需任何新机制"。实测:`wbEntryIdPre` 只把 `mem_<32hex>` 写进 **sidecar 的 id 字段**,**从未写入 `PLAN.md`/账本的 Markdown 正文**(`WB-FORMAT-CONVENTION §2` 要求标题行下方紧跟 `<!-- memory:mem_... -->`)。
66
+
67
+ ⇒ **该收益目前为零**:白板内容不会因锚点进检索。
68
+
69
+ **请裁决**:这是"实现 bug(应补写锚点到 Markdown)"还是"可以延期(先让 sidecar 跑通)"?若补写,会改动用户可见的 Markdown 内容,需确认是否可接受。
70
+
71
+ ### Q6 ★ 交付报告的高报要不要更正留痕?
72
+
73
+ **背景**:`REPORT-WB-GRAPH-NIGHTLY.md` 把 `events.jsonl`、遍历工具返回正文、dsh-graph 接线、工具数硬锁都标 ✅,实际均未完成。
74
+
75
+ **请裁决**:是
76
+ - (a) 直接改写该报告为"如实版"(丢失原始误报的痕迹),还是
77
+ - (b) **保留原报告不动 + 追加一份勘误节**("原始报告哪些项高报、实测如何")——**倾向 (b)**,因为能保留"为什么会误报"的教训?
78
+
79
+ ---
80
+
81
+ ## 三、我方的初步判断(供对方否决)
82
+
83
+ | 项 | 我的判断 | 置信度 |
84
+ | --- | --- | --- |
85
+ | Q1 修法 | **A1-b** | 中(未验证 cordis 是否提供启动期配置,故需 GPT 确认 A1-c 是否更正统) |
86
+ | Q2 顺序 | **(a) 先补 graph 端到端套件** | 高(否则无法证明修好了) |
87
+ | Q3 范围 | **补 P3-3 + P2-5 必修项;P2-3/P2-4/P3-2 看本批余量** | 中 |
88
+ | Q4 接线 | **(b) 另立一步**——但必须让用户明确知道"不接线 = 看不到看板" | 高(改 profile 风险高,且用户硬规矩要求先备份+同意) |
89
+ | Q5 锚点 | **算未兑现,建议补**(否则 §2 收益条款是空头承诺) | 中高 |
90
+ | Q6 报告 | **(b) 追加勘误节** | 高 |
91
+
92
+ ---
93
+
94
+ ## 四、我方**不做**的事(边界声明)
95
+
96
+ - 不改用户 profile(Q4 未裁决前)。
97
+ - 不 commit/push/publish(代码全留 pre 线)。
98
+ - 不重启 dsh web 宿主(用户自行重启)。
99
+ - 不为了"让测试变绿"而放宽断言——尤其不能把三处工具数硬锁从 `!== 14` 直接改成"随便多少"。
100
+
101
+ ---
102
+
103
+ ## 五、对方回复的期望格式
104
+
105
+ 请逐条回:
106
+
107
+ ```
108
+ Q1: 采纳 <A1-a|A1-b|A1-c|其他:____>,理由 <一句话>
109
+ Q2: <a|b>,理由 <一句话>
110
+ Q3: 本批范围 = <列出项号>,其余延后
111
+ Q4: <a|b>,理由 <一句话>
112
+ Q5: <补写锚点|延期>,理由 <一句话>
113
+ Q6: <a|b>
114
+ 补充意见: <如果有我漏掉的方向性问题>
115
+ ```
116
+
117
+ ---
118
+
119
+ ## 六、附:材料索引
120
+
121
+ | 文件 | 内容 |
122
+ | --- | --- |
123
+ | `docs/internal/AUDIT-WB-GRAPH-FULL-20260916.md` | 任务一全量粗检报告(4 致命 + 5 新缺陷 + 规划三态对账 + 修复方案 + 证据清单) |
124
+ | `docs/internal/REVIEW-WB-GRAPH-SELF.md` | 16 日凌晨自审(3 致命 + 6 高/中危,**其中 BUG-4 已被本次推翻**) |
125
+ | `docs/internal/GPT-REVIEW-PROMPT.md` | 找 bug 的任务书(与本文互补:那份找 bug,这份定方向) |
126
+ | `docs/internal/WB-GRAPH-INTEGRATION-PLAN.md` §5 | 改动清单原表(P0-P1/P2/P3 全部条目) |
127
+ | `docs/internal/WB-FORMAT-CONVENTION.md` | §2 锚点契约 / §3 索引派生 / §4 写入门 / §8 验收清单 |
128
+ | `docs/internal/WB-GRAPH-DECISIONS-20260914.md` §E | 16 日凌晨拍板留痕(A1-A8/B4/B7/P1 范围) |
129
+ | `docs/internal/REPORT-WB-GRAPH-NIGHTLY.md` | 交付报告(**含高报项,Q6 待裁决**) |
130
+ | `artifacts/_audit-p23-probe.mjs` | 可复跑:BUG-4 推翻 / tag 正则 / 返回契约 / boardMode 解析 |
131
+ | `artifacts/_audit-id-repro.mjs` | 可复跑:BUG-10 两条路径 id 对撞 |
132
+ | `artifacts/_audit-apply-await.mjs` | 可复跑:apply 函数体花括号配对 + await 深度分布 |