@jjh32456/dsh-longlive 1.6.7 → 1.8.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 (289) hide show
  1. package/CHANGELOG.md +70 -1508
  2. package/LICENSE +1 -1
  3. package/QUICKSTART.md +34 -13
  4. package/README.en.md +18 -7
  5. package/README.md +34 -9
  6. package/SPEC.md +5 -5
  7. package/cordis.patch.yml +23 -9
  8. package/docs/ANSWER-GUARD.md +92 -0
  9. package/docs/ARCHITECTURE.md +4 -3
  10. package/docs/AUTO-RECALL-WIRING.md +1 -1
  11. package/docs/AUTO-RECALL.md +15 -9
  12. package/docs/CONFIG.md +168 -35
  13. package/docs/ERRORS.md +17 -5
  14. package/docs/FAQ.md +7 -7
  15. package/docs/FEATURES.md +96 -28
  16. package/docs/MIGRATION-1.6.0.md +2 -2
  17. package/docs/OPERATIONS.md +6 -6
  18. package/docs/PANEL-INTEGRATION.md +6 -0
  19. package/docs/PRIVACY.md +88 -0
  20. package/docs/QUICKSTART.md +5 -5
  21. package/docs/README.en.md +4 -2
  22. package/docs/RESIDENT-WATCHER.md +1 -1
  23. package/docs/SESSION-WATCH.md +6 -6
  24. package/docs/TROUBLESHOOTING.md +4 -4
  25. package/package.json +47 -117
  26. package/runbook.md +2 -2
  27. package/scripts/backfill-auto-cards.mjs +98 -0
  28. package/scripts/install-surgery-task.ps1 +5 -2
  29. package/scripts/lib/session-watch-fixture.mjs +1 -1
  30. package/scripts/longlive-doctor.mjs +6 -0
  31. package/scripts/migrate-180.mjs +163 -0
  32. package/scripts/recall-index-build.mjs +128 -0
  33. package/scripts/session-watch-drill.mjs +1 -1
  34. package/scripts/surgery-run.cmd +1 -1
  35. package/scripts/unattended-surgery.ps1 +5 -2
  36. package/scripts/verify-card-anchors.mjs +138 -0
  37. package/src/actions/audit.js +125 -0
  38. package/src/actions/evidence.js +122 -0
  39. package/src/actions/fs.js +162 -0
  40. package/src/activity/index.js +760 -0
  41. package/src/activity/model.js +351 -0
  42. package/src/activity/store.js +644 -0
  43. package/src/activity/thinking.js +176 -0
  44. package/src/adapters/constants.js +11 -0
  45. package/src/adapters/engram/data/aliases.json +51 -0
  46. package/src/adapters/engram/data/policy.json +8 -0
  47. package/src/adapters/engram/data/routing-rules.json +546 -0
  48. package/src/adapters/engram/index.js +235 -0
  49. package/src/adapters/registry.js +315 -0
  50. package/src/answer/audit.js +193 -0
  51. package/src/answer/evidence.js +30 -0
  52. package/src/answer/guard.js +1370 -0
  53. package/src/answer/index.js +1067 -0
  54. package/src/answer/query.js +111 -0
  55. package/src/answer/second-hop.mjs +101 -0
  56. package/src/auto-truncate.js +1 -1
  57. package/src/config.js +171 -47
  58. package/src/deps.js +6 -4
  59. package/src/features.js +182 -6
  60. package/src/heartbeat.js +156 -23
  61. package/src/identity/handover.js +52 -1
  62. package/src/identity/index.js +13 -5
  63. package/src/identity/inject-position.js +2 -2
  64. package/src/index.js +97 -7
  65. package/src/lifecycle/gap-clocks.js +328 -0
  66. package/src/lifecycle/index.js +269 -0
  67. package/src/live.js +22 -2
  68. package/src/memory/activity-capture.js +229 -0
  69. package/src/memory/anchors.js +194 -0
  70. package/src/memory/audit-records.js +222 -0
  71. package/src/memory/auto-cards.js +401 -0
  72. package/src/memory/capture.js +442 -0
  73. package/src/memory/card-anchors.js +203 -0
  74. package/src/memory/conflicts.js +106 -0
  75. package/src/memory/decay.js +311 -0
  76. package/src/memory/distill.js +471 -0
  77. package/src/memory/event-index.js +917 -0
  78. package/src/memory/evidence-chain.js +295 -0
  79. package/src/memory/evidence.js +145 -0
  80. package/src/memory/filter-runner.js +1 -1
  81. package/src/memory/filter.js +5 -1
  82. package/src/memory/forget-v2.js +410 -0
  83. package/src/memory/forget.js +71 -0
  84. package/src/memory/frames-activation.js +247 -0
  85. package/src/memory/fts-query.js +174 -0
  86. package/src/memory/governance.js +604 -0
  87. package/src/memory/index.js +1 -0
  88. package/src/memory/l2-gate.js +169 -0
  89. package/src/memory/lock.js +121 -0
  90. package/src/memory/migrate.js +139 -0
  91. package/src/memory/recall-v2.js +223 -0
  92. package/src/memory/recall.js +65 -2
  93. package/src/memory/records.js +425 -0
  94. package/src/memory/retention.js +128 -0
  95. package/src/memory/review.js +124 -0
  96. package/src/memory/trust.js +88 -0
  97. package/src/memory/version-chain.js +264 -0
  98. package/src/memory/wal.js +137 -0
  99. package/src/memory/working-frame.js +516 -0
  100. package/src/metrics/classify.mjs +5 -3
  101. package/src/metrics/index.mjs +21 -1
  102. package/src/metrics/prestep-latency.mjs +300 -0
  103. package/src/metrics/store.mjs +25 -0
  104. package/src/policy-profile.js +18 -3
  105. package/src/recall/anaphora.mjs +87 -0
  106. package/src/recall/cards.mjs +7 -0
  107. package/src/recall/embedding.mjs +8 -8
  108. package/src/recall/entities.mjs +112 -0
  109. package/src/recall/index.js +235 -19
  110. package/src/recall/inject-order.mjs +10 -8
  111. package/src/recall/privacy.mjs +105 -16
  112. package/src/recall/recall-core.mjs +116 -10
  113. package/src/recall/shared-visibility.js +302 -0
  114. package/src/recall/time-normalizer.mjs +196 -0
  115. package/src/role/activation.js +191 -0
  116. package/src/role/attention.js +318 -0
  117. package/src/role/base.js +36 -0
  118. package/src/role/channels.js +423 -0
  119. package/src/role/index.js +425 -0
  120. package/src/role/interfaces.js +115 -0
  121. package/src/role/personality.js +370 -0
  122. package/src/role/readers.js +151 -0
  123. package/src/role/relationships.js +477 -0
  124. package/src/role/store.js +202 -0
  125. package/src/role/writeprotect.js +373 -0
  126. package/src/router/aliases.json +176 -25
  127. package/src/router/background/agent-runner.mjs +1 -1
  128. package/src/router/background/anchor.mjs +1 -1
  129. package/src/router/background/audit.mjs +2 -2
  130. package/src/router/background/budget-ledger.mjs +2 -2
  131. package/src/router/background/host-sim.mjs +1 -1
  132. package/src/router/background/memory.mjs +4 -4
  133. package/src/router/background/queue.mjs +1 -1
  134. package/src/router/background/retry.mjs +1 -1
  135. package/src/router/background/router.mjs +1 -1
  136. package/src/router/background/stream.mjs +1 -1
  137. package/src/router/background/tool-policy.mjs +1 -1
  138. package/src/router/design-headings.json +5 -5
  139. package/src/router/face/config.mjs +1 -1
  140. package/src/router/face/identity.mjs +3 -3
  141. package/src/router/judge.mjs +8 -7
  142. package/src/router/policies/generic.json +21 -4
  143. package/src/router/route.js +109 -22
  144. package/src/router/router.mjs +10 -6
  145. package/src/router/routing-rules.json +260 -445
  146. package/src/router/run-sim.mjs +8 -8
  147. package/src/router/runtime.js +23 -12
  148. package/src/router/service/board.mjs +95 -15
  149. package/src/router/service/config.mjs +5 -5
  150. package/src/router/service/context.mjs +1 -1
  151. package/src/router/service/hint.mjs +14 -0
  152. package/src/router/service/queue.mjs +1 -1
  153. package/src/router/service/service.mjs +27 -11
  154. package/src/router/shadow.mjs +4 -3
  155. package/src/surgery-recovery.js +2 -2
  156. package/src/tool-output.js +2 -2
  157. package/src/tools.js +39 -7
  158. package/src/truncate-visible.js +2 -2
  159. package/src/ui/actions.js +1312 -0
  160. package/src/ui/panel-api.js +367 -0
  161. package/src/ui/panel-auth.js +251 -0
  162. package/src/ui/panel-integrity.js +243 -0
  163. package/src/ui/routes-readonly.js +695 -0
  164. package/src/ui/routes.js +3 -0
  165. package/docs/DEV.md +0 -279
  166. package/docs/PRESENCE-BUS-WIRING.md +0 -491
  167. package/docs/PRESENCE-BUS.md +0 -694
  168. package/docs/SURGERY.md +0 -186
  169. package/scripts/mark-core-cards.mjs +0 -289
  170. package/scripts/pack.mjs +0 -392
  171. package/scripts/router-proposals.mjs +0 -386
  172. package/src/router/fixtures/M1.json +0 -16
  173. package/src/router/fixtures/M2.json +0 -16
  174. package/src/router/fixtures/M3.json +0 -20
  175. package/src/router/fixtures/M4.json +0 -20
  176. package/src/router/fixtures/M5.json +0 -45
  177. package/src/router/fixtures/M6.json +0 -53
  178. package/src/router/fixtures/M7.json +0 -46
  179. package/src/router/fixtures/S1.json +0 -20
  180. package/src/router/fixtures/S2.json +0 -23
  181. package/src/router/fixtures/S3.json +0 -20
  182. package/src/router/fixtures/S4.json +0 -34
  183. package/src/router/fixtures/S5.json +0 -43
  184. package/src/router/fixtures/S6.json +0 -47
  185. package/src/router/fixtures/T1.json +0 -23
  186. package/src/router/fixtures/T2.json +0 -16
  187. package/src/router/fixtures/T3.json +0 -19
  188. package/src/router/fixtures/T4.json +0 -16
  189. package/src/router/fixtures/X1.json +0 -17
  190. package/src/router/fixtures/X2.json +0 -20
  191. package/src/router/gen-design-headings.mjs +0 -107
  192. package/src/router/policies/owner-rulings-2026-11-03.json +0 -62
  193. package/test/auto-recall.test.mjs +0 -474
  194. package/test/auto-truncate.test.mjs +0 -931
  195. package/test/autobind.test.mjs +0 -385
  196. package/test/bus.test.mjs +0 -1572
  197. package/test/cli-guard.test.mjs +0 -198
  198. package/test/conclusion.test.mjs +0 -408
  199. package/test/config-schema.test.mjs +0 -204
  200. package/test/d6-output.test.mjs +0 -194
  201. package/test/d6.test.mjs +0 -395
  202. package/test/deps.test.mjs +0 -342
  203. package/test/doctor-setup.test.mjs +0 -297
  204. package/test/embedding-recall.test.mjs +0 -347
  205. package/test/feature-flags.test.mjs +0 -568
  206. package/test/filter-shadow.test.mjs +0 -170
  207. package/test/fixtures/baseline-0.8.0-registration.json +0 -556
  208. package/test/fixtures/d6-header-tools.json +0 -1
  209. package/test/fixtures/lock-child.mjs +0 -67
  210. package/test/fixtures/pre-step-container.mjs +0 -100
  211. package/test/fixtures/privacy-memory/topics/pii-unmarked.md +0 -9
  212. package/test/fixtures/privacy-memory/topics/secret-local-only.md +0 -11
  213. package/test/fixtures/profile-session-longlive-config.json +0 -20
  214. package/test/fixtures/proposal-cas-child.mjs +0 -66
  215. package/test/host-engine-status.test.mjs +0 -307
  216. package/test/hot-truncate.test.mjs +0 -1349
  217. package/test/identity-card-marker.test.mjs +0 -307
  218. package/test/identity-router/run.mjs +0 -721
  219. package/test/integration-pre-step.test.mjs +0 -553
  220. package/test/live.test.mjs +0 -1020
  221. package/test/maintenance-schedule.test.mjs +0 -538
  222. package/test/memory.test.mjs +0 -2828
  223. package/test/metrics.test.mjs +0 -478
  224. package/test/orchestrator.test.mjs +0 -266
  225. package/test/p1_probe.mjs +0 -97
  226. package/test/packaging.test.mjs +0 -182
  227. package/test/portability.test.mjs +0 -343
  228. package/test/rc4-regressions.test.mjs +0 -562
  229. package/test/rc5-regressions.test.mjs +0 -197
  230. package/test/rc6-chinese.test.mjs +0 -394
  231. package/test/router-1100/apply-off.test.mjs +0 -175
  232. package/test/router-1100/budget-reconcile.test.mjs +0 -215
  233. package/test/router-1100/config-context.test.mjs +0 -211
  234. package/test/router-1100/helpers.mjs +0 -129
  235. package/test/router-1100/hint-envelope.test.mjs +0 -150
  236. package/test/router-1100/lock-crossproc.test.mjs +0 -206
  237. package/test/router-1100/proposal-cas-crossproc.test.mjs +0 -184
  238. package/test/router-1100/router-apply.test.mjs +0 -372
  239. package/test/router-1100/router-fixb.test.mjs +0 -602
  240. package/test/router-1100/router-proposals.test.mjs +0 -405
  241. package/test/router-1100/router-queue-lease-wal.test.mjs +0 -355
  242. package/test/router-1100/router-security-cr.test.mjs +0 -333
  243. package/test/router-1100/service-lifecycle.test.mjs +0 -220
  244. package/test/router-1100/tools-contract.test.mjs +0 -164
  245. package/test/router-1100/turn-reflect-tick.test.mjs +0 -89
  246. package/test/router-1100/v6-contract.test.mjs +0 -158
  247. package/test/router-1100/v6b-contract.test.mjs +0 -293
  248. package/test/router-1100/v6c-contract.test.mjs +0 -249
  249. package/test/router-1100/wal-rotation.test.mjs +0 -375
  250. package/test/router-1100/wp1-config.test.mjs +0 -170
  251. package/test/router-1100/wp1-default-off.test.mjs +0 -77
  252. package/test/router-1100/wp1-model-status.test.mjs +0 -90
  253. package/test/router-1100/wp1-status.test.mjs +0 -220
  254. package/test/router-1100/wp1-tools.test.mjs +0 -146
  255. package/test/router-1100/wp5-cli.test.mjs +0 -240
  256. package/test/router-1100/wp5-model-auto.test.mjs +0 -418
  257. package/test/router-1100/wp6-merge.test.mjs +0 -386
  258. package/test/router-1100/wp6-wake.test.mjs +0 -502
  259. package/test/router-background/audit.test.mjs +0 -37
  260. package/test/router-background/budget-ledger.test.mjs +0 -330
  261. package/test/router-background/cross-process.test.mjs +0 -222
  262. package/test/router-background/fixtures/cross-child.mjs +0 -85
  263. package/test/router-background/fixtures/real-shapes.mjs +0 -239
  264. package/test/router-background/router.test.mjs +0 -1044
  265. package/test/router-background/stream-retry.test.mjs +0 -358
  266. package/test/router-background/tool-agent.test.mjs +0 -384
  267. package/test/router-face/bridge.test.mjs +0 -169
  268. package/test/router-face/face.test.mjs +0 -316
  269. package/test/router-failclosed.test.mjs +0 -466
  270. package/test/router-identity.test.mjs +0 -384
  271. package/test/router-l1-l2.contract.test.mjs +0 -1075
  272. package/test/router-memory-tools.test.mjs +0 -262
  273. package/test/router-policy.test.mjs +0 -225
  274. package/test/router-runtime.test.mjs +0 -438
  275. package/test/router-shadow.test.mjs +0 -287
  276. package/test/router.test.mjs +0 -903
  277. package/test/run-rc.mjs +0 -299
  278. package/test/run.mjs +0 -2469
  279. package/test/safety-defaults.test.mjs +0 -179
  280. package/test/seeded-load.test.mjs +0 -436
  281. package/test/session-original.test.mjs +0 -338
  282. package/test/surgery-recovery.test.mjs +0 -936
  283. package/test/t7_drive.mjs +0 -151
  284. package/test/tool-output.test.mjs +0 -393
  285. package/test/tool-schema.test.mjs +0 -177
  286. package/test/tools_contract.test.mjs +0 -716
  287. package/test/truncate-visible.test.mjs +0 -1150
  288. package/test/ui-flags.test.mjs +0 -477
  289. package/test/v4-hardening.test.mjs +0 -427
@@ -2,14 +2,31 @@
2
2
  "version": 2,
3
3
  "description": "R1 Router-A 规则表:规则做契约,会话做判断,偏离留痕。设计来源 R1-DESIGN.md §2.1 / §3.3 / §4.3 / §5;policyRef 指向文档里真实存在的标题,--check 会逐条解析。",
4
4
  "designDoc": "R1-DESIGN.md",
5
- "targets": ["engram", "topics", "journal", "procedures", "live", "none"],
6
- "kinds": ["tool", "memory", "session", "reply"],
5
+ "targets": [
6
+ "topics",
7
+ "journal",
8
+ "procedures",
9
+ "live",
10
+ "none"
11
+ ],
12
+ "kinds": [
13
+ "tool",
14
+ "memory",
15
+ "session",
16
+ "reply"
17
+ ],
7
18
  "levels": {
8
19
  "X": "现在就能执行并验证",
9
20
  "D": "只能判决策:所依赖的工具尚未实现",
10
21
  "H": "人工判 / 人工签字"
11
22
  },
12
- "conflictOrder": ["guard", "negation", "session", "memory", "tool"],
23
+ "conflictOrder": [
24
+ "guard",
25
+ "negation",
26
+ "session",
27
+ "memory",
28
+ "tool"
29
+ ],
13
30
  "rules": [
14
31
  {
15
32
  "id": "R-MEM-FORGET-LOCKED",
@@ -19,7 +36,11 @@
19
36
  "match": {
20
37
  "kind": "memory",
21
38
  "tool": "memory_forget",
22
- "requireKeywords": ["locked", "锁定", "核心卡"]
39
+ "requireKeywords": [
40
+ "locked",
41
+ "锁定",
42
+ "核心卡"
43
+ ]
23
44
  },
24
45
  "before": [],
25
46
  "decision": {
@@ -40,42 +61,9 @@
40
61
  "after": [],
41
62
  "reason": "locked 卡是核心卡,fail-closed:目标一旦是 locked/锁定/核心卡,直接拒绝,绝不先问再执行;工具内部本来也会 skip locked 卡,这条在 R-GUARD-REAL 之前把口子堵死。",
42
63
  "policyRef": "R1-DESIGN.md §5.8",
43
- "policyTitle": "J8 六条裁决(2026-11-03)",
64
+ "policyTitle": "可选策略示例",
44
65
  "policyQuote": "删是最后手段"
45
66
  },
46
- {
47
- "id": "R-MEM-RECALL",
48
- "priority": 101,
49
- "category": "工具选择",
50
- "level": "X",
51
- "match": {
52
- "kind": "memory",
53
- "tool": "memory_recall"
54
- },
55
- "before": [],
56
- "decision": {
57
- "kind": "memory",
58
- "action": "engram.search",
59
- "target": "topics",
60
- "tool": "memory_recall",
61
- "args": {
62
- "readOnly": true,
63
- "writes": 0,
64
- "networkCalls": 0,
65
- "echoBack": false,
66
- "statusDefault": ["active", "locked"],
67
- "topKMax": 20,
68
- "privacyNote": "命中隐私标记也只读放行:不落盘、不回显原文"
69
- },
70
- "writeScope": [],
71
- "needsHuman": false
72
- },
73
- "after": [],
74
- "reason": "memory_recall 只读:不写卡、不写 .longlive、不联网;隐私词不改变只读性质,所以不落 R-MEM-LOCAL 的写入分支,也不因隐私拦截检索。",
75
- "policyRef": "R1-DESIGN.md §5.2",
76
- "policyTitle": "工具选择(T1–T4)",
77
- "policyQuote": "先 `engram_search`(decision 房间);不足再 `read`"
78
- },
79
67
  {
80
68
  "id": "R-MEM-FORGET-CONFIRM",
81
69
  "priority": 99,
@@ -84,7 +72,9 @@
84
72
  "match": {
85
73
  "kind": "memory",
86
74
  "tool": "memory_forget",
87
- "requireKeywords": ["confirm=forget"]
75
+ "requireKeywords": [
76
+ "confirm=forget"
77
+ ]
88
78
  },
89
79
  "before": [],
90
80
  "decision": {
@@ -99,7 +89,11 @@
99
89
  "backups": true,
100
90
  "tombstone": true,
101
91
  "deleteFiles": 0,
102
- "epitaph": ["为什么关", "影响谁", "还有用吗"]
92
+ "epitaph": [
93
+ "为什么关",
94
+ "影响谁",
95
+ "还有用吗"
96
+ ]
103
97
  },
104
98
  "writeScope": [],
105
99
  "needsHuman": true
@@ -107,7 +101,7 @@
107
101
  "after": [],
108
102
  "reason": "confirm=FORGET 是 destructive 执行:先问,确认前 0 写入;执行时必须先备份、再写三问墓志铭,移动而不 unlink。",
109
103
  "policyRef": "R1-DESIGN.md §5.8",
110
- "policyTitle": "J8 六条裁决(2026-11-03)",
104
+ "policyTitle": "可选策略示例",
111
105
  "policyQuote": "且必须写墓志铭三问(为什么关 / 影响谁 / 还有用吗)"
112
106
  },
113
107
  {
@@ -136,7 +130,7 @@
136
130
  "after": [],
137
131
  "reason": "没有 confirm 只跑 dry-run:只出提案、零写入;要真正执行必须显式 confirm=FORGET,走 R-MEM-FORGET-CONFIRM 的确认。",
138
132
  "policyRef": "R1-DESIGN.md §5.8",
139
- "policyTitle": "J8 六条裁决(2026-11-03)",
133
+ "policyTitle": "可选策略示例",
140
134
  "policyQuote": "删是最后手段"
141
135
  },
142
136
  {
@@ -147,7 +141,10 @@
147
141
  "match": {
148
142
  "kind": "memory",
149
143
  "tool": "memory_consolidate",
150
- "requireKeywords": ["apply=true", "real=true"]
144
+ "requireKeywords": [
145
+ "apply=true",
146
+ "real=true"
147
+ ]
151
148
  },
152
149
  "before": [],
153
150
  "decision": {
@@ -191,13 +188,15 @@
191
188
  "reportDir": "memory/.longlive/reports/",
192
189
  "seenProposals": true
193
190
  },
194
- "writeScope": ["memory/.longlive/reports/"],
191
+ "writeScope": [
192
+ "memory/.longlive/reports/"
193
+ ],
195
194
  "needsHuman": false
196
195
  },
197
196
  "after": [],
198
197
  "reason": "consolidate 只出提案:写一份报告到 .longlive/reports/ 并记 seenProposals,不改卡;locked 卡不参与合并。",
199
198
  "policyRef": "R1-DESIGN.md §5.8",
200
- "policyTitle": "J8 六条裁决(2026-11-03)",
199
+ "policyTitle": "可选策略示例",
201
200
  "policyQuote": "任何删除请求先转成蒸馏提案"
202
201
  },
203
202
  {
@@ -208,7 +207,13 @@
208
207
  "match": {
209
208
  "kind": "memory",
210
209
  "tool": "memory_procedure",
211
- "requireKeywords": ["合并", "同名", "覆盖", "删除", "delete"]
210
+ "requireKeywords": [
211
+ "合并",
212
+ "同名",
213
+ "覆盖",
214
+ "删除",
215
+ "delete"
216
+ ]
212
217
  },
213
218
  "before": [],
214
219
  "decision": {
@@ -227,7 +232,7 @@
227
232
  "after": [],
228
233
  "reason": "同名合并或删除会改旧卡:先问再动,确认前 0 写入;低于 R-ID-CONSENT / R-MEM-LOCAL,隐私与身份规则仍然优先。",
229
234
  "policyRef": "R1-DESIGN.md §5.8",
230
- "policyTitle": "J8 六条裁决(2026-11-03)",
235
+ "policyTitle": "可选策略示例",
231
236
  "policyQuote": "任何删除请求先转成蒸馏提案"
232
237
  },
233
238
  {
@@ -237,7 +242,14 @@
237
242
  "level": "X",
238
243
  "match": {
239
244
  "kind": "*",
240
- "keywords": ["整库", "真实库", "重写", "批量删", "删库", "格式化"]
245
+ "keywords": [
246
+ "整库",
247
+ "真实库",
248
+ "重写",
249
+ "批量删",
250
+ "删库",
251
+ "格式化"
252
+ ]
241
253
  },
242
254
  "before": [],
243
255
  "decision": {
@@ -247,7 +259,12 @@
247
259
  "tool": "guard.refuse",
248
260
  "args": {
249
261
  "sandbox": "sandbox/r1-dry-run",
250
- "steps": ["refuse", "dry-run", "diff", "ask"]
262
+ "steps": [
263
+ "refuse",
264
+ "dry-run",
265
+ "diff",
266
+ "ask"
267
+ ]
251
268
  },
252
269
  "writeScope": [],
253
270
  "needsHuman": true
@@ -257,8 +274,14 @@
257
274
  "kind": "tool",
258
275
  "action": "guard.dryRun",
259
276
  "target": "live",
260
- "args": { "src": "memory/", "sandbox": "sandbox/r1-dry-run", "diff": true },
261
- "writeScope": ["sandbox:r1-dry-run"],
277
+ "args": {
278
+ "src": "memory/",
279
+ "sandbox": "sandbox/r1-dry-run",
280
+ "diff": true
281
+ },
282
+ "writeScope": [
283
+ "sandbox:r1-dry-run"
284
+ ],
262
285
  "needsHuman": true
263
286
  }
264
287
  ],
@@ -267,109 +290,6 @@
267
290
  "policyTitle": "对抗(X1–X2)",
268
291
  "policyQuote": "拒绝直接写真库;给沙盒 dry-run + diff 报告"
269
292
  },
270
- {
271
- "id": "R-ID-CONSENT",
272
- "priority": 95,
273
- "category": "对抗",
274
- "level": "X",
275
- "match": {
276
- "kind": "memory",
277
- "keywords": ["改名", "以后叫", "叫小蓝", "别再叫", "换个名字", "名字改成", "改画像", "画像也改", "改人设", "你是谁"]
278
- },
279
- "before": [],
280
- "decision": {
281
- "kind": "reply",
282
- "action": "identity.hold",
283
- "target": "none",
284
- "tool": null,
285
- "args": {
286
- "consent": { "holder": "assistant", "required": true, "satisfied": false },
287
- "userConsentCounts": false,
288
- "profileWrites": 0,
289
- "errorCode": "E_IDENTITY_CONSENT_REQUIRED",
290
- "whoMayConsent": "当前会话的助手本人(consent.holder=assistant):须带 at 与 quote 的同意记录;用户单方面要求永远不构成同意"
291
- },
292
- "writeScope": [],
293
- "needsHuman": false
294
- },
295
- "after": [
296
- {
297
- "kind": "memory",
298
- "action": "engram.profile.edit",
299
- "target": "engram",
300
- "tool": "engram_profile_edit",
301
- "args": {
302
- "keepHistory": true,
303
- "requiresConsent": true,
304
- "consent": { "holder": "assistant", "required": true, "satisfied": true }
305
- },
306
- "writeScope": ["engram:profile"],
307
- "needsHuman": false
308
- }
309
- ],
310
- "reason": "名字、画像与自称是助手自己的身份,不是用户的单方面权利:没有助手本人带 at+quote 的同意记录,只输出 identity.hold,0 画像写入,也不存成普通记忆",
311
- "policyRef": "R1-DESIGN.md §5.8",
312
- "policyTitle": "J8 六条裁决(2026-11-03)",
313
- "policyQuote": "「用户说改」永远不构成同意"
314
- },
315
- {
316
- "id": "R-MEM-LOCAL",
317
- "priority": 92,
318
- "category": "记忆写入决策",
319
- "level": "X",
320
- "match": {
321
- "kind": "memory",
322
- "keywords": "$policy:privacy.markers"
323
- },
324
- "before": [],
325
- "decision": {
326
- "kind": "memory",
327
- "action": "memory.save_local",
328
- "target": "none",
329
- "tool": "memory_save_local",
330
- "args": {
331
- "store": "memory/private/",
332
- "dataClass": "LOCAL_ONLY",
333
- "uploadAllowed": false,
334
- "networkCalls": 0,
335
- "retention": "LOCAL",
336
- "echoBack": false,
337
- "note": "只落本地,回复里不回显原文"
338
- },
339
- "writeScope": ["memory/private/"],
340
- "needsHuman": false
341
- },
342
- "after": [],
343
- "reason": "隐私字段或明说只存本地/别上传:写 memory/private/,网络 0、engram 0、不回显原文;裸「别记」仍走 R-MEM-NONE 的零写入,两支不矛盾",
344
- "policyRef": "R1-DESIGN.md §5.8",
345
- "policyTitle": "J8 六条裁决(2026-11-03)",
346
- "policyQuote": "不是不记,是不上传"
347
- },
348
- {
349
- "id": "R-MEM-NONE",
350
- "priority": 90,
351
- "category": "对抗",
352
- "level": "H",
353
- "match": {
354
- "kind": "*",
355
- "keywords": ["别记", "不用记", "别存", "不要记", "不记", "别写入", "不用存"]
356
- },
357
- "before": [],
358
- "decision": {
359
- "kind": "reply",
360
- "action": "reply.no_write",
361
- "target": "none",
362
- "tool": null,
363
- "args": { "confirm": "没记", "writes": 0 },
364
- "writeScope": [],
365
- "needsHuman": true
366
- },
367
- "after": [],
368
- "reason": "明确否定优先于一切写入:零写入,也不写一条“用户要求不记”的负向记忆",
369
- "policyRef": "R1-DESIGN.md §5.5",
370
- "policyTitle": "对抗(X1–X2)",
371
- "policyQuote": "零写入(journal / engram / topics 都不写)"
372
- },
373
293
  {
374
294
  "id": "R-SES-CHAT",
375
295
  "priority": 80,
@@ -387,7 +307,9 @@
387
307
  "target": "live",
388
308
  "tool": "reply.only",
389
309
  "args": {
390
- "channels": ["chat"],
310
+ "channels": [
311
+ "chat"
312
+ ],
391
313
  "allowMeme": true,
392
314
  "tools": 0,
393
315
  "workers": 0,
@@ -403,103 +325,6 @@
403
325
  "policyTitle": "会话分派决策(S1–S4)",
404
326
  "policyQuote": "0 工具、0 worker、0 任务板行、0 记忆写入"
405
327
  },
406
- {
407
- "id": "R-MEM-DISTILL",
408
- "priority": 75,
409
- "category": "记忆写入决策",
410
- "level": "X",
411
- "match": {
412
- "kind": "memory",
413
- "keywords": ["删", "删除", "清掉", "去掉", "清理", "重复", "冗余", "蒸馏"]
414
- },
415
- "before": [
416
- {
417
- "kind": "tool",
418
- "action": "engram.search",
419
- "target": "engram",
420
- "tool": "engram_search",
421
- "args": { "query": "<topic-from-utterance>", "limit": 10 },
422
- "writeScope": [],
423
- "needsHuman": false
424
- }
425
- ],
426
- "decision": {
427
- "kind": "memory",
428
- "action": "memory.distillPropose",
429
- "target": "engram",
430
- "tool": "memory_distill_propose",
431
- "args": {
432
- "proposal": {
433
- "merge": ["<same-topic-entry-id>"],
434
- "supersedes": ["<old-entry-id>"],
435
- "keep": "合并后一条 + 取代链",
436
- "deleteBeforeConfirm": "$policy:distill.deleteBeforeConfirm"
437
- },
438
- "deletionCount": 0,
439
- "confirmToken": null,
440
- "ask": "合并成这条,行不行?",
441
- "maxQuestions": "$policy:distill.maxQuestions"
442
- },
443
- "writeScope": [],
444
- "needsHuman": false
445
- },
446
- "after": [
447
- {
448
- "kind": "reply",
449
- "action": "reply.only",
450
- "target": "live",
451
- "tool": "reply.only",
452
- "args": {
453
- "channels": ["chat"],
454
- "ask": "合并成这条,行不行?",
455
- "maxQuestions": "$policy:distill.maxQuestions",
456
- "tools": 0,
457
- "workers": 0,
458
- "writes": 0
459
- },
460
- "writeScope": [],
461
- "needsHuman": true
462
- }
463
- ],
464
- "reason": "删除请求先转蒸馏提案:engram.search 找同主题 → memory.distillPropose 合并成更高层一条并留取代链 → 恰问 1 句确认;确认前 0 删除,memory.delete/engram.forget 只在用户明确二次确认并写墓志铭三问后才发生",
465
- "policyRef": "R1-DESIGN.md §5.8",
466
- "policyTitle": "J8 六条裁决(2026-11-03)",
467
- "policyQuote": "删是最后手段"
468
- },
469
- {
470
- "id": "R-MEM-REVISE",
471
- "priority": 70,
472
- "category": "记忆写入决策",
473
- "level": "D",
474
- "match": {
475
- "kind": "memory",
476
- "keywords": ["作废", "不再", "旧结论", "旧事实", "推翻", "取代", "改成"]
477
- },
478
- "before": [
479
- {
480
- "kind": "tool",
481
- "action": "engram.search",
482
- "target": "engram",
483
- "args": { "room": "fact", "query": "旧事实 / 旧结论" },
484
- "writeScope": [],
485
- "needsHuman": false
486
- }
487
- ],
488
- "decision": {
489
- "kind": "memory",
490
- "action": "engram.facts.replace",
491
- "target": "engram",
492
- "tool": "engram_facts",
493
- "args": { "replaces": "<old-fact-id>", "keepHistory": true },
494
- "writeScope": ["engram:fact"],
495
- "needsHuman": false
496
- },
497
- "after": [],
498
- "reason": "事实演变走 replaces 取代链:先检索旧事实,保留历史,不追加互相矛盾的新句子",
499
- "policyRef": "R1-DESIGN.md §5.3",
500
- "policyTitle": "记忆写入决策(M1–M4)",
501
- "policyQuote": "先检索旧事实 → `engram_facts(replaces=<旧 id>)`"
502
- },
503
328
  {
504
329
  "id": "R-SES-RED",
505
330
  "priority": 65,
@@ -507,14 +332,29 @@
507
332
  "level": "X",
508
333
  "match": {
509
334
  "kind": "session",
510
- "keywords": ["320K", "300K", "快满", "红区", "上下文 320", "上下文 300", "换壳", "交接卡"]
335
+ "keywords": [
336
+ "320K",
337
+ "300K",
338
+ "快满",
339
+ "红区",
340
+ "上下文 320",
341
+ "上下文 300",
342
+ "换壳",
343
+ "交接卡"
344
+ ]
511
345
  },
512
346
  "before": [
513
347
  {
514
348
  "kind": "tool",
515
349
  "action": "acp_status",
516
350
  "target": "live",
517
- "args": { "fields": ["billedInput", "foldable", "zone"] },
351
+ "args": {
352
+ "fields": [
353
+ "billedInput",
354
+ "foldable",
355
+ "zone"
356
+ ]
357
+ },
518
358
  "writeScope": [],
519
359
  "needsHuman": false
520
360
  }
@@ -527,11 +367,24 @@
527
367
  "args": {
528
368
  "path": "memory/handover/2026-11-03-r1.md",
529
369
  "maxLines": 60,
530
- "sections": ["目标", "结论", "产物", "下一步", "坑"],
531
- "alsoUpdate": ["memory/STATE.md", "memory/flow/current.md"],
370
+ "sections": [
371
+ "目标",
372
+ "结论",
373
+ "产物",
374
+ "下一步",
375
+ "坑"
376
+ ],
377
+ "alsoUpdate": [
378
+ "memory/STATE.md",
379
+ "memory/flow/current.md"
380
+ ],
532
381
  "proposeShellSwitch": true
533
382
  },
534
- "writeScope": ["memory/handover/2026-11-03-r1.md", "memory/STATE.md", "memory/flow/current.md"],
383
+ "writeScope": [
384
+ "memory/handover/2026-11-03-r1.md",
385
+ "memory/STATE.md",
386
+ "memory/flow/current.md"
387
+ ],
535
388
  "needsHuman": true
536
389
  },
537
390
  "after": [],
@@ -547,7 +400,16 @@
547
400
  "level": "X",
548
401
  "match": {
549
402
  "kind": "session",
550
- "keywords": ["跑 3 遍", "跑三遍", "跑 5 遍", "40 分钟", "批量", "很久", "重活", "跑一天"]
403
+ "keywords": [
404
+ "跑 3 遍",
405
+ "跑三遍",
406
+ "跑 5 遍",
407
+ "40 分钟",
408
+ "批量",
409
+ "很久",
410
+ "重活",
411
+ "跑一天"
412
+ ]
551
413
  },
552
414
  "before": [],
553
415
  "decision": {
@@ -558,8 +420,13 @@
558
420
  "args": {
559
421
  "brief": {
560
422
  "goal": "按设计跑完这批场景并留下证据",
561
- "inputs": ["R1-DESIGN.md §5", "src/router/fixtures/"],
562
- "artifacts": ["r1-evidence/"],
423
+ "inputs": [
424
+ "R1-DESIGN.md §5",
425
+ "src/router/fixtures/"
426
+ ],
427
+ "artifacts": [
428
+ "r1-evidence/"
429
+ ],
563
430
  "acceptance": "node src/router/run-sim.mjs",
564
431
  "timeoutSec": 1800
565
432
  },
@@ -568,7 +435,10 @@
568
435
  "artifactRoot": "workspace",
569
436
  "acceptance": "node src/router/run-sim.mjs"
570
437
  },
571
- "writeScope": ["taskboard:R1", "evidence:r1-evidence"],
438
+ "writeScope": [
439
+ "taskboard:R1",
440
+ "evidence:r1-evidence"
441
+ ],
572
442
  "needsHuman": false
573
443
  },
574
444
  "after": [
@@ -576,8 +446,13 @@
576
446
  "kind": "session",
577
447
  "action": "taskboard.update",
578
448
  "target": "live",
579
- "args": { "row": "R1", "status": "in_progress" },
580
- "writeScope": ["taskboard:R1"],
449
+ "args": {
450
+ "row": "R1",
451
+ "status": "in_progress"
452
+ },
453
+ "writeScope": [
454
+ "taskboard:R1"
455
+ ],
581
456
  "needsHuman": false
582
457
  }
583
458
  ],
@@ -593,7 +468,14 @@
593
468
  "level": "X",
594
469
  "match": {
595
470
  "kind": "session",
596
- "keywords": ["回报", "三行", "做完了", "收活", "产物在", "worker-"]
471
+ "keywords": [
472
+ "回报",
473
+ "三行",
474
+ "做完了",
475
+ "收活",
476
+ "产物在",
477
+ "worker-"
478
+ ]
597
479
  },
598
480
  "before": [],
599
481
  "decision": {
@@ -602,8 +484,15 @@
602
484
  "target": "live",
603
485
  "tool": "read",
604
486
  "args": {
605
- "paths": ["R1/fixtures"],
606
- "checks": ["exists", "nonEmpty", "count=14", "schema"]
487
+ "paths": [
488
+ "R1/fixtures"
489
+ ],
490
+ "checks": [
491
+ "exists",
492
+ "nonEmpty",
493
+ "count=14",
494
+ "schema"
495
+ ]
607
496
  },
608
497
  "writeScope": [],
609
498
  "needsHuman": false
@@ -613,8 +502,13 @@
613
502
  "kind": "session",
614
503
  "action": "taskboard.update",
615
504
  "target": "live",
616
- "args": { "row": "R1", "status": "verified" },
617
- "writeScope": ["taskboard:R1"],
505
+ "args": {
506
+ "row": "R1",
507
+ "status": "verified"
508
+ },
509
+ "writeScope": [
510
+ "taskboard:R1"
511
+ ],
618
512
  "needsHuman": false
619
513
  }
620
514
  ],
@@ -639,12 +533,23 @@
639
533
  "target": "procedures",
640
534
  "tool": "memory_procedure",
641
535
  "args": {
642
- "actions": ["save", "list", "get", "report"],
643
- "newCardNeeds": ["name", "when", "steps"],
536
+ "actions": [
537
+ "save",
538
+ "list",
539
+ "get",
540
+ "report"
541
+ ],
542
+ "newCardNeeds": [
543
+ "name",
544
+ "when",
545
+ "steps"
546
+ ],
644
547
  "mergeBySlug": true,
645
548
  "writeDir": "memory/procedures/"
646
549
  },
647
- "writeScope": ["memory/procedures/"],
550
+ "writeScope": [
551
+ "memory/procedures/"
552
+ ],
648
553
  "needsHuman": false
649
554
  },
650
555
  "after": [],
@@ -653,133 +558,6 @@
653
558
  "policyTitle": "记忆写入决策(M1–M4)",
654
559
  "policyQuote": "`procedures/read-before-edit.md` 草稿,四节 `## 触发 / ## 步骤 / ## 验收 / ## 反例`"
655
560
  },
656
- {
657
- "id": "R-MEM-PROCEDURE",
658
- "priority": 45,
659
- "category": "记忆写入决策",
660
- "level": "D",
661
- "match": {
662
- "kind": "memory",
663
- "keywords": ["每次", "流程", "照做", "步骤", "先 read", "先读", "以后每次"]
664
- },
665
- "before": [],
666
- "decision": {
667
- "kind": "memory",
668
- "action": "procedures.draft",
669
- "target": "procedures",
670
- "tool": "procedures.draft",
671
- "args": {
672
- "file": "procedures/read-before-edit.md",
673
- "sections": ["触发", "步骤", "验收", "反例"],
674
- "forbidPaths": ["~/.dsh/skills/"]
675
- },
676
- "writeScope": ["memory/procedures/read-before-edit.md"],
677
- "needsHuman": false
678
- },
679
- "after": [
680
- {
681
- "kind": "memory",
682
- "action": "engram.save",
683
- "target": "engram",
684
- "tool": "engram_save",
685
- "args": { "kind": "skill", "importance": 0.5, "path": "procedures/read-before-edit.md" },
686
- "writeScope": ["engram:skill"],
687
- "needsHuman": false
688
- }
689
- ],
690
- "reason": "可复用流程写 procedures 草稿(## 触发 / ## 步骤 / ## 验收 / ## 反例),engram 只留 kind=skill 指针",
691
- "policyRef": "R1-DESIGN.md §5.3",
692
- "policyTitle": "记忆写入决策(M1–M4)",
693
- "policyQuote": "四节 `## 触发 / ## 步骤 / ## 验收 / ## 反例`"
694
- },
695
- {
696
- "id": "R-MEM-DECISION",
697
- "priority": 40,
698
- "category": "记忆写入决策",
699
- "level": "X",
700
- "match": {
701
- "kind": "memory",
702
- "keywords": ["以后", "一律", "不许", "统一", "必须用", "改成", "全部"]
703
- },
704
- "before": [],
705
- "decision": {
706
- "kind": "memory",
707
- "action": "engram.save",
708
- "target": "engram",
709
- "tool": "engram_save",
710
- "args": {
711
- "kind": "decision",
712
- "importance": 0.7,
713
- "minImportance": 0.7,
714
- "path": "R1-DESIGN.md §5.3"
715
- },
716
- "writeScope": ["engram:decision"],
717
- "needsHuman": false
718
- },
719
- "after": [],
720
- "reason": "结论/决策写 engram(kind=decision, importance≥0.7),正文带 path: 指针;不重复写 topic 卡",
721
- "policyRef": "R1-DESIGN.md §5.3",
722
- "policyTitle": "记忆写入决策(M1–M4)",
723
- "policyQuote": "正文含结论 + `path:` 指向本设计"
724
- },
725
- {
726
- "id": "R-MEM-EPISODE",
727
- "priority": 40,
728
- "category": "记忆写入决策",
729
- "level": "X",
730
- "match": {
731
- "kind": "memory",
732
- "keywords": ["今天", "刚才", "他签了", "上午", "下午", "晚上", "昨天"]
733
- },
734
- "before": [],
735
- "decision": {
736
- "kind": "memory",
737
- "action": "journal.append",
738
- "target": "journal",
739
- "tool": "journal.append",
740
- "args": {
741
- "file": "journal/2026-11.md",
742
- "requiredFields": ["date", "time", "who"],
743
- "affect": { "score": 0, "reason": "" }
744
- },
745
- "writeScope": ["memory/journal/2026-11.md"],
746
- "needsHuman": false
747
- },
748
- "after": [],
749
- "reason": "情景写 journal(日期/时间/人 + affect 标记),不改 topics、不写 engram",
750
- "policyRef": "R1-DESIGN.md §5.3",
751
- "policyTitle": "记忆写入决策(M1–M4)",
752
- "policyQuote": "`<!-- affect: N | reason -->`,N∈1..5 且 reason 非空"
753
- },
754
- {
755
- "id": "R-MEM-TOPICS",
756
- "priority": 35,
757
- "category": "记忆写入决策",
758
- "level": "X",
759
- "match": {
760
- "kind": "memory",
761
- "keywords": ["topic 卡", "知识卡", "主题卡", "沉淀到 topics", "沉淀成卡片"]
762
- },
763
- "before": [],
764
- "decision": {
765
- "kind": "memory",
766
- "action": "topics.write",
767
- "target": "topics",
768
- "tool": "topics.write",
769
- "args": {
770
- "path": "topics/<slug>.md",
771
- "salienceSource": "frontmatter",
772
- "importanceDerived": true
773
- },
774
- "writeScope": ["memory/topics/"],
775
- "needsHuman": false
776
- },
777
- "after": [],
778
- "reason": "可复用知识写 topic 卡;salience 只认 frontmatter,不反推 engram importance",
779
- "policyRef": "R1-DESIGN.md §4.3",
780
- "policyTitle": "M1 的四个硬约束",
781
- "policyQuote": "唯一权威在卡片 frontmatter(1–5)"
782
- },
783
561
  {
784
562
  "id": "R-TOOL-DISPATCH",
785
563
  "priority": 25,
@@ -788,7 +566,16 @@
788
566
  "match": {
789
567
  "kind": "tool",
790
568
  "tool": "worker_spawn",
791
- "keywords": ["派活", "派出去", "批量", "跑 3 遍", "跑三遍", "写成 fixture", "很久", "重活"]
569
+ "keywords": [
570
+ "派活",
571
+ "派出去",
572
+ "批量",
573
+ "跑 3 遍",
574
+ "跑三遍",
575
+ "写成 fixture",
576
+ "很久",
577
+ "重活"
578
+ ]
792
579
  },
793
580
  "before": [],
794
581
  "decision": {
@@ -799,8 +586,13 @@
799
586
  "args": {
800
587
  "brief": {
801
588
  "goal": "把 R1 的 14 条场景写成 fixture 并自检",
802
- "inputs": ["R1-DESIGN.md §5", "src/router/routing-rules.json"],
803
- "artifacts": ["src/router/fixtures/"],
589
+ "inputs": [
590
+ "R1-DESIGN.md §5",
591
+ "src/router/routing-rules.json"
592
+ ],
593
+ "artifacts": [
594
+ "src/router/fixtures/"
595
+ ],
804
596
  "acceptance": "node src/router/router.mjs --check",
805
597
  "timeoutSec": 900
806
598
  },
@@ -809,7 +601,10 @@
809
601
  "artifactRoot": "repo",
810
602
  "acceptance": "node src/router/router.mjs --check"
811
603
  },
812
- "writeScope": ["fixtures:src/router/fixtures", "taskboard:R1"],
604
+ "writeScope": [
605
+ "fixtures:src/router/fixtures",
606
+ "taskboard:R1"
607
+ ],
813
608
  "needsHuman": false
814
609
  },
815
610
  "after": [
@@ -817,8 +612,13 @@
817
612
  "kind": "session",
818
613
  "action": "taskboard.update",
819
614
  "target": "live",
820
- "args": { "row": "R1", "status": "in_progress" },
821
- "writeScope": ["taskboard:R1"],
615
+ "args": {
616
+ "row": "R1",
617
+ "status": "in_progress"
618
+ },
619
+ "writeScope": [
620
+ "taskboard:R1"
621
+ ],
822
622
  "needsHuman": false
823
623
  }
824
624
  ],
@@ -835,7 +635,14 @@
835
635
  "match": {
836
636
  "kind": "tool",
837
637
  "tool": "acp_status",
838
- "keywords": ["上下文", "还剩多少", "还能撑多久", "预算", "billed input", "可折叠"]
638
+ "keywords": [
639
+ "上下文",
640
+ "还剩多少",
641
+ "还能撑多久",
642
+ "预算",
643
+ "billed input",
644
+ "可折叠"
645
+ ]
839
646
  },
840
647
  "before": [],
841
648
  "decision": {
@@ -843,7 +650,13 @@
843
650
  "action": "acp_status",
844
651
  "target": "live",
845
652
  "tool": "acp_status",
846
- "args": { "fields": ["billedInput", "foldable", "zone"] },
653
+ "args": {
654
+ "fields": [
655
+ "billedInput",
656
+ "foldable",
657
+ "zone"
658
+ ]
659
+ },
847
660
  "writeScope": [],
848
661
  "needsHuman": false
849
662
  },
@@ -861,7 +674,15 @@
861
674
  "match": {
862
675
  "kind": "tool",
863
676
  "tool": "read",
864
- "keywords": ["出处", "证据", "几秒", "实测", "哪一行", "文件里", "原文"]
677
+ "keywords": [
678
+ "出处",
679
+ "证据",
680
+ "几秒",
681
+ "实测",
682
+ "哪一行",
683
+ "文件里",
684
+ "原文"
685
+ ]
865
686
  },
866
687
  "before": [],
867
688
  "decision": {
@@ -871,7 +692,9 @@
871
692
  "tool": "read",
872
693
  "args": {
873
694
  "pathRoot": "research",
874
- "paths": ["longlive-051/077/VM/VM-VERIFY-077.md"],
695
+ "paths": [
696
+ "longlive-051/077/VM/VM-VERIFY-077.md"
697
+ ],
875
698
  "requireLineRef": true
876
699
  },
877
700
  "writeScope": [],
@@ -883,36 +706,6 @@
883
706
  "policyTitle": "工具选择(T1–T4)",
884
707
  "policyQuote": "并带 `文件:行`;文件里没有就明说没有"
885
708
  },
886
- {
887
- "id": "R-TOOL-RECALL",
888
- "priority": 20,
889
- "category": "工具选择",
890
- "level": "X",
891
- "match": {
892
- "kind": "tool",
893
- "tool": "engram_search",
894
- "keywords": ["以前", "之前", "定过", "原话", "我们说过", "召回"]
895
- },
896
- "before": [],
897
- "decision": {
898
- "kind": "tool",
899
- "action": "engram.search",
900
- "target": "engram",
901
- "tool": "engram_search",
902
- "args": {
903
- "room": "decision",
904
- "query": "Router 形态 A / 方案 B",
905
- "fallbackRead": "router-A-design.md:6-12"
906
- },
907
- "writeScope": [],
908
- "needsHuman": false
909
- },
910
- "after": [],
911
- "reason": "历史结论先 engram_search 召回,再补读源文件;原话标日期,不凭印象",
912
- "policyRef": "R1-DESIGN.md §5.2",
913
- "policyTitle": "工具选择(T1–T4)",
914
- "policyQuote": "先 `engram_search`(decision 房间)"
915
- },
916
709
  {
917
710
  "id": "R-SES-WORKERS",
918
711
  "priority": 13,
@@ -920,8 +713,17 @@
920
713
  "level": "X",
921
714
  "match": {
922
715
  "kind": "session",
923
- "keywords": ["进度", "到哪了", "还在跑", "盯着", "他们的", "worker"],
924
- "ctx": { "activeWorkersGte": "$policy:thresholds.dispatchAt" }
716
+ "keywords": [
717
+ "进度",
718
+ "到哪了",
719
+ "还在跑",
720
+ "盯着",
721
+ "他们的",
722
+ "worker"
723
+ ],
724
+ "ctx": {
725
+ "activeWorkersGte": "$policy:thresholds.dispatchAt"
726
+ }
925
727
  },
926
728
  "before": [],
927
729
  "decision": {
@@ -929,7 +731,10 @@
929
731
  "action": "worker_status",
930
732
  "target": "live",
931
733
  "tool": "worker_status",
932
- "args": { "scope": "all", "includeBlocked": true },
734
+ "args": {
735
+ "scope": "all",
736
+ "includeBlocked": true
737
+ },
933
738
  "writeScope": [],
934
739
  "needsHuman": false
935
740
  },
@@ -948,7 +753,9 @@
948
753
  "kind": "*",
949
754
  "ctxOnly": true,
950
755
  "keywords": [],
951
- "ctx": { "tokensGte": "$policy:thresholds.compressAt" }
756
+ "ctx": {
757
+ "tokensGte": "$policy:thresholds.compressAt"
758
+ }
952
759
  },
953
760
  "before": [],
954
761
  "decision": {
@@ -956,7 +763,13 @@
956
763
  "action": "session.compact",
957
764
  "target": "live",
958
765
  "tool": "session_compact",
959
- "args": { "mode": "suggest", "thresholds": { "compressAt": "$policy:thresholds.compressAt", "redAt": "$policy:thresholds.redAt" } },
766
+ "args": {
767
+ "mode": "suggest",
768
+ "thresholds": {
769
+ "compressAt": "$policy:thresholds.compressAt",
770
+ "redAt": "$policy:thresholds.redAt"
771
+ }
772
+ },
960
773
  "writeScope": [],
961
774
  "needsHuman": false
962
775
  },
@@ -973,7 +786,9 @@
973
786
  "priority": 0,
974
787
  "category": "对抗",
975
788
  "level": "X",
976
- "match": { "kind": "session" },
789
+ "match": {
790
+ "kind": "session"
791
+ },
977
792
  "before": [],
978
793
  "decision": {
979
794
  "kind": "reply",
@@ -994,7 +809,7 @@
994
809
  "after": [],
995
810
  "reason": "零命中或指代不明时不许静默也不许猜:恰 1 条 reply.ask、候选≤3、0 工具/0 写入/0 派活;有安全默认(裸「别记」→零写入)时可不问,但必须说明默认。本规则不入优先级队列,由 route 的兜底分支触发",
996
811
  "policyRef": "R1-DESIGN.md §5.8",
997
- "policyTitle": "J8 六条裁决(2026-11-03)",
812
+ "policyTitle": "可选策略示例",
998
813
  "policyQuote": "R-SES-ASK 不入队"
999
814
  }
1000
815
  ]