@a9i5k4/dsh-auto-memory 3.0.0 → 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 (90) hide show
  1. package/README.md +19 -7
  2. package/README.zh-CN.md +19 -7
  3. package/docs/FRONTEND-CO-CREATION.md +191 -0
  4. package/docs/GM53-HOMEPAGE-PROMPT.md +323 -0
  5. package/docs/HOMEPAGE-CONTENT-FOR-GM53.md +299 -0
  6. package/docs/PROMO-PROMPT-3.0.md +100 -0
  7. package/docs/USER-GUIDE.en.md +2 -2
  8. package/docs/USER-GUIDE.zh-CN.md +2 -2
  9. package/docs/WHITEPAPER.md +207 -0
  10. package/docs/internal/ARCHITECTURE-FOR-ZCODE-20260920.md +397 -0
  11. package/docs/internal/ART-DIRECTION-DEEPSEEK-20260920.md +351 -0
  12. package/docs/internal/ART-DIRECTION-WIREFRAME.md +191 -181
  13. package/docs/internal/ART-DIRECTION-WIREFRAME.md.bak-superseded +181 -0
  14. package/docs/internal/BATTLE-PLAN-20260917.md +871 -0
  15. package/docs/internal/FEATURE-INVENTORY.md +531 -0
  16. package/docs/internal/G-SERIES-EXECUTION-20260917.md +248 -0
  17. package/docs/internal/G3-DESIGN-20260918.md +82 -0
  18. package/docs/internal/G3-DISK-FORMAT-GAP-20260919.md +92 -0
  19. package/docs/internal/HANDOFF-TO-ZCODE-20260920.md +309 -0
  20. package/docs/internal/HERMES-DATA-VERIFICATION-20260919.md +120 -0
  21. package/docs/internal/HERMES-LEGACY-STATUS-20260919.md +74 -0
  22. package/docs/internal/ISSUE-55-58-VERIFICATION-20260918.md +175 -0
  23. package/docs/internal/ISSUE10-FIX-EXECUTION-20260919.md +389 -0
  24. package/docs/internal/ISSUE10-PLAN-20260919.md +254 -0
  25. package/docs/internal/ISSUE10B-FORENSICS-20260919.md +468 -0
  26. package/docs/internal/ISSUE9-PURGE-AND-R1-PLAIN-20260919.md +150 -0
  27. package/docs/internal/ISSUE9-RESIDUAL-FORENSICS-20260919.md +114 -0
  28. package/docs/internal/LESSON-TO-CANDIDATE-STATUS-20260919.md +79 -0
  29. package/docs/internal/MEMORY-GOVERNANCE-20260917.md +309 -0
  30. package/docs/internal/PRE-FRONTEND-CHECKLIST-20260919.md +705 -0
  31. package/docs/internal/PRE-FRONTEND-CHECKLIST-20260919.md.bak-s10 +649 -0
  32. package/docs/internal/PROCEDURAL-MEMORY-AND-APPROVAL-DESIGN-20260918.md +225 -0
  33. package/docs/internal/PROGRESS-20260917.md +93 -0
  34. package/docs/internal/PROMPT-GAP-AUDIT-20260920.md +128 -0
  35. package/docs/internal/R1-DEGRADE-AUDIT-20260918.md +163 -0
  36. package/docs/internal/R1-READABILITY-FORENSICS-20260919.md +127 -0
  37. package/docs/internal/R2-EVIDENCE-DEEP-AUDIT-20260918.md +140 -0
  38. package/docs/internal/R3-DEGRADE-LEDGER-DESIGN-20260918.md +138 -0
  39. package/docs/internal/R4-RECALL-QUOTA-PLAN-20260918.md +218 -0
  40. package/docs/internal/RESUME-20260918.md +171 -0
  41. package/docs/internal/RESUME-20260919.md +104 -0
  42. package/docs/internal/RHINELAB-TO-DEEPSEEK-FEASIBILITY.md +198 -0
  43. package/docs/internal/ROADMAP-20260917-WEEK.md +134 -0
  44. package/docs/internal/S10-CONSTRUCTION-HANDOFF-20260917.md +13 -3
  45. package/docs/internal/S10-GAP-INVENTORY-20260917.md +239 -0
  46. package/docs/internal/T6-EXECUTION-20260920.md +130 -0
  47. package/docs/internal/TELEMETRY-EFFECT-REPORT-DESIGN-20260918.md +146 -0
  48. package/docs/internal/THESIS-GAP-ANALYSIS-20260918.md +89 -0
  49. package/docs/internal/THESIS-OUTLINE-20260918.md +147 -0
  50. package/docs/internal/THREE-LAYER-CONTRACT.md +10 -1
  51. package/docs/internal/UPSTREAM-ISSUE-PR-TRIAGE-20260919.md +297 -0
  52. package/docs/internal/UPSTREAM-ISSUES-3RD-AUDIT-20260920.md +104 -0
  53. package/docs/screenshots/promo/promo-0-banner-v3.png +0 -0
  54. package/lib/activation-host.js +63 -9
  55. package/lib/board-mode.js +1 -1
  56. package/lib/client.js +892 -27
  57. package/lib/config-io.js +156 -0
  58. package/lib/context-bridge.js +3 -0
  59. package/lib/context-host.js +16 -9
  60. package/lib/degrade.js +385 -0
  61. package/lib/dsh-home.js +143 -0
  62. package/lib/episodic-store.js +52 -2
  63. package/lib/evidence-store.js +8 -1
  64. package/lib/fact-store.js +21 -2
  65. package/lib/index-sync.js +13 -1
  66. package/lib/index.js +1507 -158
  67. package/lib/intent-clean-safe.js +258 -40
  68. package/lib/l0-extract.js +231 -16
  69. package/lib/m4-corpus.js +8 -2
  70. package/lib/m7-index-sync-host.js +8 -1
  71. package/lib/memory-envelope.js +6 -1
  72. package/lib/memory-hub.js +127 -12
  73. package/lib/memory-index.js +4 -2
  74. package/lib/note-status-apply.js +118 -0
  75. package/lib/note-status.js +196 -0
  76. package/lib/procedure-store.js +84 -3
  77. package/lib/python-sidecar-client.js +29 -3
  78. package/lib/recall-fusion.js +83 -12
  79. package/lib/rules-edit.js +159 -0
  80. package/lib/semantic-decide.js +41 -8
  81. package/lib/semantic-js.js +51 -6
  82. package/lib/shadow-host.js +3 -5
  83. package/lib/skill-export-host.js +153 -0
  84. package/lib/skill-export.js +239 -0
  85. package/lib/storage-manage.js +6 -0
  86. package/lib/temporal-parse.js +191 -159
  87. package/lib/tier0-catalog.js +45 -3
  88. package/lib/wb-contract.js +198 -2
  89. package/lib/wb-sidecar.js +54 -3
  90. package/package.json +1 -1
@@ -19,6 +19,7 @@ import {
19
19
  import { createActivationInboxPre, ActivationInboxRegistry, REFERENCE_TAIL_COOLDOWN_STEPS_V1 } from './activation-inbox-state.js'
20
20
  import { createAccessEvidencePre } from './context-bridge.js'
21
21
  import path from 'node:path'
22
+ import { resolveDshHomeForEnginePre } from './dsh-home.js'
22
23
  import { buildSourceCatalog, loadCorpusSnapshot, CorpusRegistry, canonicalize } from './m4-corpus.js'
23
24
 
24
25
  /** §11 capability 快照版本。 */
@@ -49,7 +50,12 @@ export function createActivationHost(opts = {}) {
49
50
  // 现改为按身份分片:投影按 sessionId、miv 按 wsRef。**只增 key 维度,不改任何判定口径**。
50
51
  const mivCacheByWs = new Map() // wsRef -> miv(每个工作区各记一份,不再互相踢)
51
52
  const pathsByKey = new Map()
53
+ // ★#84(2026-09-20):`≤16 最小投影` —— 原实现在超出上限时**静默 shift**,
54
+ // 于是「诊断面看不到最近事件」没有任何痕迹;排查时会误判成「压根没产生事件」。
55
+ // 现补 `volatileDropped` 计数并具名化上限。
52
56
  const volatileEvents = [] // ≤16 最小投影
57
+ let volatileDropped = 0
58
+ const VOLATILE_MAX_V1 = 16
53
59
  const stats = { injected: 0, injectedAccepted: 0, injectedRejected: 0, claims: 0, claimFails: 0, rendered: 0, delivered: 0, seenCreated: 0, seenSkippedNoProv: 0, errors: 0 }
54
60
 
55
61
  function effectiveEnabled() {
@@ -69,14 +75,17 @@ export function createActivationHost(opts = {}) {
69
75
  return 'invalid'
70
76
  }
71
77
  function dshHome() {
72
- const env = process.env.DSH_HOME
73
- if (env && env.trim()) return env.trim()
74
- const base = engine.__homedirFn ? engine.__homedirFn() : (process.env.USERPROFILE || process.env.HOME || '')
75
- return base ? path.join(base, '.dsh') : '.'
78
+ // ★#86-3:统一口径。原实现全失败时返回 '.'(**与其余站点不同**);
79
+ // __homedirFn 注入点由 resolveDshHomeForEnginePre 保留,测试兼容。
80
+ return resolveDshHomeForEnginePre(engine)
76
81
  }
77
82
  function pushEvent(entry) {
78
83
  volatileEvents.push({ at: Date.now(), ...entry })
79
- if (volatileEvents.length > 16) volatileEvents.shift()
84
+ if (volatileEvents.length > VOLATILE_MAX_V1) {
85
+ volatileEvents.shift()
86
+ // ★#84:丢弃必须留痕(否则「看不到事件」无法区分「没产生」与「被挤掉」)
87
+ volatileDropped++
88
+ }
80
89
  }
81
90
  function capturePaths(runtimeKey, p) {
82
91
  pathsByKey.set(String(runtimeKey || ''), {
@@ -202,6 +211,9 @@ export function createActivationHost(opts = {}) {
202
211
  if (!engine._tierGateHitsBySession || typeof engine._tierGateHitsBySession.set !== 'function') {
203
212
  engine._tierGateHitsBySession = new Map()
204
213
  }
214
+ // ★2026-09-20 移植(issue #94⑤ / PR #100):Map.set 对既有键**不刷新插入序** ⇒
215
+ // keys().next() 淘汰的是「最老创建」而非「最久未用」,最活跃会话反被逐出。
216
+ engine._tierGateHitsBySession.delete(sid)
205
217
  engine._tierGateHitsBySession.set(sid, projection)
206
218
  // 兼容投影:保留旧字段指向"最近一次投递",供旧诊断面板/测试继续可读(只增不改语义)。
207
219
  engine._tierGateHits = projection
@@ -234,7 +246,10 @@ export function createActivationHost(opts = {}) {
234
246
  */
235
247
  function pumpClaimed(box, req) {
236
248
  const c2 = box.claim({
237
- nowStep: stepFor(req.sessionId, req.workspaceKey),
249
+ // ★ issue #75 CC-11 修复:用**只读**步号,不再自增。
250
+ // pump 总是紧跟在同键 `stepFor`(offer 时)之后同步调用 ⇒ 读到的就是刚烘焙 TTL 的那个步。
251
+ // 旧实现此处再 `stepFor` 一次 ⇒ 同一步内凭空消耗 2 步 TTL(见 currentStepOf 注释)。
252
+ nowStep: currentStepOf(req.sessionId, req.workspaceKey),
238
253
  currentContextVersion: req.contextVersion,
239
254
  currentMemoryIndexVersion: req.memoryIndexVersion,
240
255
  })
@@ -348,12 +363,39 @@ export function createActivationHost(opts = {}) {
348
363
  return { ok: true, request }
349
364
  }
350
365
  const stepsByRuntime = new Map()
366
+ /**
367
+ * 步进计数器的**唯一键格式**(issue#58 修复,2026-09-19)。
368
+ * 旧实现:写入侧用 `sessionId + '|ws:' + workspaceKey`,而删除侧 `disposeRuntime` 用
369
+ * `String(runtimeKey)`(= `session:<sid>`)⇒ **两个键空间永不相交** ⇒ 删除是空操作,
370
+ * `stepsByRuntime` 只增不减(「会话×工作区」一条,进程内永不回收)。
371
+ * 现在格式收敛到这一处,写入与删除共用,杜绝再次漂移。
372
+ */
373
+ function stepKeyOf(sessionId, workspaceKey) {
374
+ return String(sessionId || '') + '|ws:' + String(workspaceKey || '')
375
+ }
351
376
  function stepFor(sessionId, workspaceKey) {
352
- const key = sessionId + '|ws:' + workspaceKey
377
+ const key = stepKeyOf(sessionId, workspaceKey)
353
378
  const n = (stepsByRuntime.get(key) || 0) + 1
354
379
  stepsByRuntime.set(key, n)
355
380
  return n
356
381
  }
382
+ /**
383
+ * ★ issue #75 CC-11 修复(2026-09-19):**只读**当前步(不自增)。
384
+ *
385
+ * 动机:`stepFor` 是自增器(+1 写回)。而「注入即泵」路径是
386
+ * `finishInject` 先 `offerActivation({nowStep: stepFor(...)})` 烘焙 TTL 起点,
387
+ * 紧接着**同一同步块内** `pumpClaimed` 又调一次 `stepFor` 去 claim
388
+ * ⇒ **offer 与 pump 各消耗 1 步而零时间流逝** ⇒ `expiresAtStep` 按第一次烘焙、
389
+ * 判定却用第二次 ⇒ TTL 窗口凭空少 1 步(实测 ttl=3 的自然投递窗由 2 次机会缩为 1;
390
+ * ttl=2 的 rollback 场景整包必死)。
391
+ *
392
+ * 语义上「同步 offer + pump」是**同一步内**的投递动作,不该消耗 2 步 TTL。
393
+ * 因此给 pump 侧提供只读版本:它总是紧跟在同键的 `stepFor` 之后调用,
394
+ * 读到的必然是刚自增过的那个值(≥1),不会读到 0。
395
+ */
396
+ function currentStepOf(sessionId, workspaceKey) {
397
+ return stepsByRuntime.get(stepKeyOf(sessionId, workspaceKey)) || 0
398
+ }
357
399
 
358
400
  /**
359
401
  * agent/pre-step(§8):先校验当前 cursor/index/TTL 再 claim;claimed packet 存 runtime 态,
@@ -371,6 +413,8 @@ export function createActivationHost(opts = {}) {
371
413
  const miv = currentMiv(identity.workspaceKey)
372
414
  box.setCursor({ contextVersion: runtime.contextVersion, memoryIndexVersion: miv || undefined })
373
415
  const nowStep = stepFor(identity.sessionId, identity.workspaceKey)
416
+ // issue#58:把步进键登记进 runtime 态,供 disposeRuntime 精确回收(否则计数器只增不减)。
417
+ const stepKeyHere = stepKeyOf(identity.sessionId, identity.workspaceKey)
374
418
  const c = box.claim({
375
419
  nowStep,
376
420
  currentContextVersion: runtime.contextVersion,
@@ -379,6 +423,7 @@ export function createActivationHost(opts = {}) {
379
423
  let st = runtimeState.get(runtime.key)
380
424
  if (!st) { st = { step: 0, claimed: null }; runtimeState.set(runtime.key, st) }
381
425
  st.step = nowStep
426
+ st.stepKey = stepKeyHere
382
427
  if (c.ok) { st.claimed = { packet: c.packet, inbox: box }; stats.claims++ }
383
428
  else {
384
429
  // 2026-08-28 浏览器实测修复:claim 失败(none-pending 等)不得清掉已存在的 claimed——
@@ -505,9 +550,18 @@ export function createActivationHost(opts = {}) {
505
550
  } catch (e) { stats.errors++; return { ok: false, reason: 'internal-error' } }
506
551
  }
507
552
 
553
+ /**
554
+ * 单 runtime 清理。issue#58 修复(2026-09-19):**必须清掉步进计数器**。
555
+ * 旧实现 `stepsByRuntime.delete(String(runtimeKey))` 是坏键(见 `stepKeyOf` 注释)⇒ 空操作。
556
+ * 现在优先用创建时登记的 `stepKey`;同时保留 runtimeKey 形态的删除,
557
+ * 兼容「调用方直接传 step-key」的情况(两条都删,代价为零)。
558
+ */
508
559
  function disposeRuntime(runtimeKey) {
509
- runtimeState.delete(runtimeKey)
510
- stepsByRuntime.delete(String(runtimeKey))
560
+ const k = String(runtimeKey)
561
+ const st = runtimeState.get(k)
562
+ runtimeState.delete(k)
563
+ if (st && st.stepKey) stepsByRuntime.delete(st.stepKey)
564
+ stepsByRuntime.delete(k)
511
565
  }
512
566
  function disposeAll(reason) {
513
567
  runtimeState.clear()
package/lib/board-mode.js CHANGED
@@ -8,7 +8,7 @@
8
8
  * - boardMode = 'legacy'(默认) | 'graph'(新版看板 dsh-graph + sidecar + 遍历工具)。
9
9
  * - **开关解耦**(用户硬性规则): boardMode 只决定"白板线新能力是否激活",
10
10
  * 不顺带改变任何其他功能行为; legacy 模式下一切行为与 P5 收官时**字节级一致**。
11
- * - graph_* 工具(dsh-graph vendor)与 memory_expand_pre/memory_trace_pre(P3)
11
+ * - graph_* 工具(dsh-graph vendor)与 memory_expand/memory_trace(P3)
12
12
  * 仅在 boardMode='graph' 时注册; P2 sidecar 仅在 'graph' 时写盘。
13
13
  * - fail closed: 非法值一律按 legacy(旧行为), 绝不猜。
14
14
  */