@sanqianx/project-knowledge 5.0.24 → 5.0.25

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 (401) hide show
  1. package/.agents/plugins/marketplace.json +20 -20
  2. package/.claude-plugin/marketplace.json +1 -1
  3. package/CHANGELOG.md +1361 -1353
  4. package/LICENSE +201 -201
  5. package/NOTICE +5 -5
  6. package/README.md +349 -349
  7. package/_modules/knowledge-engine/package.json +1 -1
  8. package/_modules/knowledge-engine/src/coordinator.js +48 -3
  9. package/_modules/knowledge-engine/src/runtime/automation-config.js +140 -140
  10. package/_modules/knowledge-engine/src/runtime/commit-conversation-binder.js +238 -238
  11. package/_modules/knowledge-engine/src/runtime/commit-processing-ledger.js +26 -26
  12. package/_modules/knowledge-engine/src/runtime/commit-prompt.js +193 -193
  13. package/_modules/knowledge-engine/src/runtime/commit-reconciler.js +394 -394
  14. package/_modules/knowledge-engine/src/runtime/contracts.js +282 -282
  15. package/_modules/knowledge-engine/src/runtime/conversation-store.js +389 -389
  16. package/_modules/knowledge-engine/src/runtime/evidence-bundle.js +228 -228
  17. package/_modules/knowledge-engine/src/runtime/git-runner.js +62 -62
  18. package/_modules/knowledge-engine/src/runtime/knowledge-promotion.js +505 -505
  19. package/_modules/knowledge-engine/src/runtime/knowledge-retrieval-service.js +400 -400
  20. package/_modules/knowledge-engine/src/runtime/markdown-knowledge-indexer.js +171 -171
  21. package/_modules/knowledge-engine/src/runtime/scanner.js +298 -298
  22. package/_modules/knowledge-engine/ui/app.js +23 -2
  23. package/_site/README.md +30 -30
  24. package/_site/_test/agent-capture-mcp-ui-test.js +68 -68
  25. package/_site/_test/agent-capture-ui-test.js +101 -101
  26. package/_site/_test/ai-profile-resolver-test.js +137 -137
  27. package/_site/_test/ai-profile-test.js +75 -75
  28. package/_site/_test/ai-vendor-presets-test.js +91 -91
  29. package/_site/_test/automatic-context-test.js +70 -70
  30. package/_site/_test/automation-queue-test.js +14 -14
  31. package/_site/_test/automation-ui-test.js +40 -40
  32. package/_site/_test/background-task-registry-test.js +43 -43
  33. package/_site/_test/baseline-schema-test.js +91 -91
  34. package/_site/_test/bin-cli-test.js +230 -230
  35. package/_site/_test/bridge-adapter-test.js +95 -95
  36. package/_site/_test/bridge-consumer-service-test.js +310 -310
  37. package/_site/_test/candidate-bin-content-test.js +35 -35
  38. package/_site/_test/candidate-product-assets-test.js +13 -13
  39. package/_site/_test/candidate-release-contract-test.js +14 -14
  40. package/_site/_test/capture-hook-dedup-test.js +158 -158
  41. package/_site/_test/cdp-browser-failure-test.js +103 -103
  42. package/_site/_test/chat-claudecodeui-match-test.js +92 -92
  43. package/_site/_test/claude-executable-discovery-test.js +90 -90
  44. package/_site/_test/claude-session-lifecycle-sweep-test.js +252 -252
  45. package/_site/_test/claude-workbench-test.js +174 -174
  46. package/_site/_test/cli-instance-management-test.js +62 -62
  47. package/_site/_test/client-capture-restart-e2e-test.js +189 -189
  48. package/_site/_test/codex-conversation-projection-test.js +60 -60
  49. package/_site/_test/codex-marketplace-scoped-path-test.js +186 -186
  50. package/_site/_test/codex-notify-capture-e2e-test.js +101 -101
  51. package/_site/_test/codex-notify-fanout-test.js +141 -134
  52. package/_site/_test/codex-notify-upgrade-test.js +253 -253
  53. package/_site/_test/commit-boundary-freeze-test.js +147 -147
  54. package/_site/_test/commit-conversation-binding-test.js +99 -99
  55. package/_site/_test/commit-evidence-test.js +110 -110
  56. package/_site/_test/configuration-generation-test.js +22 -22
  57. package/_site/_test/context-pack-test.js +200 -200
  58. package/_site/_test/conversation-api-test.js +119 -119
  59. package/_site/_test/conversation-origin-test.js +15 -15
  60. package/_site/_test/conversation-store-test.js +138 -138
  61. package/_site/_test/cross-repo-isolation-e2e-test.js +187 -187
  62. package/_site/_test/desktop-browser-compat-test.js +28 -28
  63. package/_site/_test/desktop-hook-runtime-regression-test.js +204 -204
  64. package/_site/_test/embedding-config-test.js +32 -32
  65. package/_site/_test/explicit-commit-processor-test.js +37 -37
  66. package/_site/_test/fixtures/fake-browser-exit.js +10 -10
  67. package/_site/_test/fixtures/fake-browser-hang.js +10 -10
  68. package/_site/_test/fixtures/integration-busy-worker.cjs +6 -6
  69. package/_site/_test/fixtures/make-git-repos.js +92 -92
  70. package/_site/_test/fixtures/retrieval-gold-queries.json +32 -32
  71. package/_site/_test/folder-picker-output-test.js +19 -19
  72. package/_site/_test/fresh-hook-reimport-test.js +53 -53
  73. package/_site/_test/fresh-product-data-test.js +56 -56
  74. package/_site/_test/full-integration-e2e-test.js +167 -167
  75. package/_site/_test/git-path-compatibility-test.js +80 -80
  76. package/_site/_test/git-validation-test.js +81 -81
  77. package/_site/_test/glm-ui-refresh-review-test.js +313 -404
  78. package/_site/_test/harness-isolation-test.js +138 -0
  79. package/_site/_test/helpers/cdp-browser.js +383 -0
  80. package/_site/_test/helpers/cdp-network-capture.js +66 -0
  81. package/_site/_test/helpers/find-chrome.js +34 -0
  82. package/_site/_test/helpers/free-port.js +8 -0
  83. package/_site/_test/helpers/logging-ui-fixture.js +131 -0
  84. package/_site/_test/helpers/module-fixture.js +282 -0
  85. package/_site/_test/helpers/parallel-engine-advanced-engine-child.js +45 -0
  86. package/_site/_test/helpers/parallel-engine-advanced-fault-writer.js +171 -0
  87. package/_site/_test/helpers/parallel-engine-advanced-harness.js +245 -0
  88. package/_site/_test/helpers/parallel-engine-advanced-standin-analyzer.js +80 -0
  89. package/_site/_test/helpers/parallel-engine-advanced-ui-host.js +177 -0
  90. package/_site/_test/helpers/parallel-engine-final-harness.js +314 -0
  91. package/_site/_test/helpers/parallel-engine-final-standin-analyzer.js +159 -0
  92. package/_site/_test/helpers/parallel-knowledge-fixture.js +255 -0
  93. package/_site/_test/helpers/parallel-logging-acceptance-fixture.js +111 -0
  94. package/_site/_test/helpers/parallel-logging-acceptance-proxy.js +106 -0
  95. package/_site/_test/helpers/parallel-logging-fix-r2-proxy.js +205 -0
  96. package/_site/_test/helpers/parallel-logging-integration-5025-env.js +432 -0
  97. package/_site/_test/helpers/parallel-memory-analyzer.js +81 -0
  98. package/_site/_test/helpers/parallel-memory-event-bridge.js +128 -0
  99. package/_site/_test/helpers/parallel-memory-shell.js +470 -0
  100. package/_site/_test/helpers/parallel-nav-isolation-env.js +389 -0
  101. package/_site/_test/helpers/parallel-nav-module-ui.js +186 -0
  102. package/_site/_test/helpers/parallel-nav-proxy.js +148 -0
  103. package/_site/_test/helpers/parallel-nav-shell.js +361 -0
  104. package/_site/_test/helpers/parallel-qa-engine-endpoint-guard.js +206 -0
  105. package/_site/_test/helpers/parallel-qa-engine-endpoint-isolate.js +257 -0
  106. package/_site/_test/helpers/parallel-retrieval-followup-corpus.js +293 -0
  107. package/_site/_test/helpers/parallel-retrieval-followup-next-session.js +70 -0
  108. package/_site/_test/helpers/parallel-retrieval-followup-r2-shell.js +737 -0
  109. package/_site/_test/helpers/parallel-retrieval-followup-r2-wb-host.js +82 -0
  110. package/_site/_test/helpers/parallel-retrieval-followup-shell.js +279 -0
  111. package/_site/_test/helpers/parallel-workbench-fixture.js +371 -0
  112. package/_site/_test/helpers/parallel-workbench-host.js +80 -0
  113. package/_site/_test/helpers/parallel-workbench-integration-5025-fixture.js +408 -0
  114. package/_site/_test/helpers/parallel-workbench-integration-5025-harness.js +593 -0
  115. package/_site/_test/helpers/parallel-workbench-integration-5025-host.js +70 -0
  116. package/_site/_test/helpers/parallel-workbench-integration-5025-launcher.js +240 -0
  117. package/_site/_test/helpers/parallel-workbench-integration-5025-runtime-harness.js +630 -0
  118. package/_site/_test/helpers/parallel-workbench-source-map.js +196 -0
  119. package/_site/_test/helpers/spawn-server.js +106 -0
  120. package/_site/_test/helpers/version-visibility-fixture.js +251 -0
  121. package/_site/_test/hook-runtime-endpoint-test.js +88 -88
  122. package/_site/_test/hook-status-repair-api-test.js +152 -152
  123. package/_site/_test/hook-trigger-test.js +85 -85
  124. package/_site/_test/hook-worktree-test.js +42 -42
  125. package/_site/_test/import-preflight-api-test.js +234 -234
  126. package/_site/_test/index-builder-test.js +41 -41
  127. package/_site/_test/index-error-display-contract-test.js +10 -10
  128. package/_site/_test/index-writer-concurrency-test.js +135 -135
  129. package/_site/_test/integration-adapters-test.js +262 -262
  130. package/_site/_test/integration-auto-repair-test.js +113 -113
  131. package/_site/_test/integration-capture-setup-test.js +118 -118
  132. package/_site/_test/integration-intent-test.js +81 -81
  133. package/_site/_test/integration-runtime-binding-a2-test.js +566 -566
  134. package/_site/_test/integration-runtime-binding-a3-test.js +227 -227
  135. package/_site/_test/integration-runtime-binding-test.js +473 -473
  136. package/_site/_test/integration-status-scan-test.js +29 -29
  137. package/_site/_test/integration-surface-coverage-test.js +164 -164
  138. package/_site/_test/kb-framework-test.js +57 -57
  139. package/_site/_test/kbpath-follow-test.js +63 -63
  140. package/_site/_test/knowledge-db-test.js +144 -144
  141. package/_site/_test/knowledge-engine-client-test.js +120 -109
  142. package/_site/_test/knowledge-language-control-test.js +170 -170
  143. package/_site/_test/knowledge-maintenance-test.js +40 -40
  144. package/_site/_test/knowledge-promotion-recovery-test.js +260 -260
  145. package/_site/_test/knowledge-query-test.js +54 -54
  146. package/_site/_test/knowledge-retrieval-service-test.js +77 -77
  147. package/_site/_test/knowledge-scopes-test.js +37 -37
  148. package/_site/_test/knowledge-storage-location-test.js +28 -28
  149. package/_site/_test/knowledge-storage-startup-test.js +52 -52
  150. package/_site/_test/knowledge-store-logs-supervision-test.js +89 -89
  151. package/_site/_test/launcher-readiness-test.js +80 -80
  152. package/_site/_test/legacy-claude-session-alias-test.js +106 -106
  153. package/_site/_test/legacy-routes-removed-test.js +47 -47
  154. package/_site/_test/legacy-workbench-exclusion-test.js +92 -92
  155. package/_site/_test/live-gateway-test.js +48 -48
  156. package/_site/_test/local-marketplace-test.js +16 -16
  157. package/_site/_test/log-redaction-test.js +58 -58
  158. package/_site/_test/logging-api-test.js +89 -89
  159. package/_site/_test/logging-sse-no-gap-test.js +88 -88
  160. package/_site/_test/logging-ui-test.js +107 -107
  161. package/_site/_test/markdown-delta-overlay-test.js +85 -85
  162. package/_site/_test/markdown-maintenance-api-test.js +75 -75
  163. package/_site/_test/markdown-maintenance-test.js +11 -11
  164. package/_site/_test/mcp-server-test.js +149 -149
  165. package/_site/_test/model-context-windows-test.js +89 -89
  166. package/_site/_test/module-agent-start-proxy-test.js +65 -65
  167. package/_site/_test/module-artifact-integrity-test.js +27 -27
  168. package/_site/_test/module-boundary-test.js +30 -30
  169. package/_site/_test/module-bridge-eventbridge-test.js +202 -202
  170. package/_site/_test/module-dynamic-port-test.js +118 -118
  171. package/_site/_test/module-index-proxy-test.js +33 -33
  172. package/_site/_test/module-model-configuration-test.js +44 -44
  173. package/_site/_test/module-process-lifecycle-test.js +35 -35
  174. package/_site/_test/module-stream-proxy-test.js +34 -34
  175. package/_site/_test/module-terminal-restart-test.js +63 -63
  176. package/_site/_test/module-wiring-unbind-race-test.js +59 -59
  177. package/_site/_test/native-context-integrations-test.js +86 -86
  178. package/_site/_test/non-release-ci-test.js +34 -34
  179. package/_site/_test/offline-boundary-isolation-test.js +32 -32
  180. package/_site/_test/orphaned-claim-recovery-test.js +80 -80
  181. package/_site/_test/package-boundary-test.js +43 -43
  182. package/_site/_test/package-startup-test.js +56 -56
  183. package/_site/_test/packaged-ui-smoke-test.js +88 -88
  184. package/_site/_test/parallel-ci-r9-posix-socket-budget-test.js +156 -0
  185. package/_site/_test/parallel-engine-advanced-eng005-test.js +136 -0
  186. package/_site/_test/parallel-engine-advanced-eng006-test.js +171 -0
  187. package/_site/_test/parallel-engine-advanced-eng007-reconcile-test.js +231 -0
  188. package/_site/_test/parallel-engine-advanced-eng009-test.js +208 -0
  189. package/_site/_test/parallel-engine-advanced-eng010-test.js +213 -0
  190. package/_site/_test/parallel-engine-advanced-eng011-ui-probe.js +459 -0
  191. package/_site/_test/parallel-engine-final-eng002-test.js +255 -0
  192. package/_site/_test/parallel-engine-final-eng007-test.js +269 -0
  193. package/_site/_test/parallel-engine-final-eng011-test.js +197 -0
  194. package/_site/_test/parallel-engine-final-eng012-test.js +354 -0
  195. package/_site/_test/parallel-knowledge-client-error-code-test.js +184 -0
  196. package/_site/_test/parallel-knowledge-engine-test.js +353 -0
  197. package/_site/_test/parallel-knowledge-retrieval-test.js +292 -0
  198. package/_site/_test/parallel-knowledge-vector-test.js +168 -0
  199. package/_site/_test/parallel-linux-ci-r7-log007-day-test.js +110 -0
  200. package/_site/_test/parallel-logging-acceptance-log003-test.js +224 -0
  201. package/_site/_test/parallel-logging-acceptance-log004-test.js +231 -0
  202. package/_site/_test/parallel-logging-acceptance-log005-test.js +208 -0
  203. package/_site/_test/parallel-logging-acceptance-log006-test.js +214 -0
  204. package/_site/_test/parallel-logging-acceptance-log007-test.js +223 -0
  205. package/_site/_test/parallel-logging-acceptance-log008-test.js +180 -0
  206. package/_site/_test/parallel-logging-fix-r2-crash-probe.js +271 -0
  207. package/_site/_test/parallel-logging-fix-r2-gap-test.js +294 -0
  208. package/_site/_test/parallel-logging-fix-r2-normalhook-test.js +330 -0
  209. package/_site/_test/parallel-logging-integration-5025-portability-test.js +554 -0
  210. package/_site/_test/parallel-memory-candidate-test.js +301 -0
  211. package/_site/_test/parallel-memory-manual-test.js +197 -0
  212. package/_site/_test/parallel-memory-scope-test.js +228 -0
  213. package/_site/_test/parallel-memory-source-test.js +227 -0
  214. package/_site/_test/parallel-memory-sync-test.js +238 -0
  215. package/_site/_test/parallel-memory-view-r8-reload-gate-test.js +123 -0
  216. package/_site/_test/parallel-nav-failure-test.js +119 -0
  217. package/_site/_test/parallel-nav-isolation-test.js +308 -0
  218. package/_site/_test/parallel-nav-isolation-vector-path-test.js +90 -0
  219. package/_site/_test/parallel-nav-offline-test.js +272 -0
  220. package/_site/_test/parallel-nav-operability-test.js +257 -0
  221. package/_site/_test/parallel-nav-switch-test.js +247 -0
  222. package/_site/_test/parallel-nav-theme-test.js +130 -0
  223. package/_site/_test/parallel-nav-viewport-test.js +310 -0
  224. package/_site/_test/parallel-qa-engine-endpoint-guard-test.js +273 -0
  225. package/_site/_test/parallel-retrieval-followup-citation-test.js +219 -0
  226. package/_site/_test/parallel-retrieval-followup-corpus-test.js +287 -0
  227. package/_site/_test/parallel-workbench-independent-host.js +262 -0
  228. package/_site/_test/parallel-workbench-integration-5025-abort-probe.js +340 -0
  229. package/_site/_test/parallel-workbench-integration-5025-drafts-probe.js +588 -0
  230. package/_site/_test/parallel-workbench-integration-5025-env-check.js +317 -0
  231. package/_site/_test/parallel-workbench-integration-5025-model-probe.js +342 -0
  232. package/_site/_test/parallel-workbench-integration-5025-ordering-probe.js +326 -0
  233. package/_site/_test/parallel-workbench-model-probe.js +336 -0
  234. package/_site/_test/parallel-workbench-offline-test.js +169 -0
  235. package/_site/_test/parallel-workbench-provenance-trace.js +134 -0
  236. package/_site/_test/parallel-workbench-source-match.js +206 -0
  237. package/_site/_test/parallel-workbench-standalone-turn.js +349 -0
  238. package/_site/_test/path-consistency-test.js +151 -151
  239. package/_site/_test/pending-sweep-test.js +9 -9
  240. package/_site/_test/post-commit-automation-test.js +87 -87
  241. package/_site/_test/pr-consumer-contract-test.js +55 -55
  242. package/_site/_test/product-brand-contract-test.js +25 -25
  243. package/_site/_test/product-diagnostics-ui-test.js +93 -93
  244. package/_site/_test/product-empty-state-test.js +148 -0
  245. package/_site/_test/product-import-ui-test.js +219 -104
  246. package/_site/_test/product-navigation-test.js +152 -0
  247. package/_site/_test/product-progress-status-test.js +84 -84
  248. package/_site/_test/project-delete-recovery-test.js +64 -64
  249. package/_site/_test/project-domain-create-test.js +91 -0
  250. package/_site/_test/project-domain-scope-retrieval-test.js +214 -0
  251. package/_site/_test/project-git-init-confirm-test.js +115 -0
  252. package/_site/_test/project-goal-editor-test.js +144 -144
  253. package/_site/_test/project-import-duplicate-alias-test.js +134 -0
  254. package/_site/_test/project-import-unicode-restart-test.js +140 -0
  255. package/_site/_test/project-lifecycle-transaction-test.js +106 -106
  256. package/_site/_test/project-module-partial-recovery-test.js +222 -0
  257. package/_site/_test/project-remove-running-guard-test.js +79 -79
  258. package/_site/_test/project-store-test.js +90 -90
  259. package/_site/_test/project-unbind-late-read-ui-test.js +250 -0
  260. package/_site/_test/project-unbind-writer-guard-test.js +231 -0
  261. package/_site/_test/prompt-settings-test.js +115 -115
  262. package/_site/_test/protected-architecture-gate-test.js +122 -122
  263. package/_site/_test/refactor-characterization-test.js +36 -36
  264. package/_site/_test/registry-events-test.js +38 -38
  265. package/_site/_test/release-version-sync-test.js +115 -115
  266. package/_site/_test/requirement-binding-test.js +113 -113
  267. package/_site/_test/requirement-recorder-test.js +173 -173
  268. package/_site/_test/run-all-tests.js +173 -161
  269. package/_site/_test/runtime-endpoint-test.js +64 -64
  270. package/_site/_test/scanner-test.js +83 -83
  271. package/_site/_test/server-security-test.js +96 -96
  272. package/_site/_test/sessions-stream-test.js +93 -93
  273. package/_site/_test/shared-contracts-test.js +58 -58
  274. package/_site/_test/shared-scope-root-binding-test.js +74 -67
  275. package/_site/_test/simple-import-test.js +98 -98
  276. package/_site/_test/startup-analysis-disabled-test.js +16 -16
  277. package/_site/_test/storage-foundation-test.js +78 -78
  278. package/_site/_test/structured-logger-test.js +101 -101
  279. package/_site/_test/t07b-cln-005-coverage-test.js +212 -0
  280. package/_site/_test/team-knowledge-store-sparse-checkout-test.js +196 -196
  281. package/_site/_test/team-knowledge-store-test.js +132 -132
  282. package/_site/_test/test-server-cleanup-test.js +35 -35
  283. package/_site/_test/test-server-module-isolation-test.js +37 -37
  284. package/_site/_test/tracking-start-test.js +144 -144
  285. package/_site/_test/vector-storage-root-test.js +75 -75
  286. package/_site/_test/version-visibility-browser-probe.js +249 -0
  287. package/_site/_test/version-visibility-test.js +92 -0
  288. package/_site/_test/workbench-context-receipts-test.js +22 -22
  289. package/_site/_test/workbench-permission-test.js +117 -117
  290. package/_site/_test/zcode-capture-integration-test.js +112 -112
  291. package/_site/lib/ai-profile-resolver.js +78 -78
  292. package/_site/lib/ai-vendor-presets.js +83 -83
  293. package/_site/lib/ai-workspace.js +104 -104
  294. package/_site/lib/atomic-file.js +204 -204
  295. package/_site/lib/automation-config.js +140 -140
  296. package/_site/lib/bridge-adapter.js +260 -260
  297. package/_site/lib/bridge-consumer-service.js +402 -402
  298. package/_site/lib/capture-hook-config.js +108 -108
  299. package/_site/lib/claude-cli-runner.js +1599 -1599
  300. package/_site/lib/cli-instances.js +43 -43
  301. package/_site/lib/codex-context-status.js +17 -17
  302. package/_site/lib/codex-notify-config.js +193 -193
  303. package/_site/lib/commit-conversation-binder.js +247 -247
  304. package/_site/lib/commit-processing-ledger.js +27 -27
  305. package/_site/lib/commit-prompt.js +202 -202
  306. package/_site/lib/commit-reconciler.js +444 -444
  307. package/_site/lib/context-pack-builder.js +299 -299
  308. package/_site/lib/contracts.js +291 -291
  309. package/_site/lib/conversation-exclusions.js +204 -204
  310. package/_site/lib/conversation-query-service.js +161 -161
  311. package/_site/lib/conversation-store.js +387 -387
  312. package/_site/lib/data-dir.js +13 -13
  313. package/_site/lib/embedding-service.js +85 -85
  314. package/_site/lib/engine-connection.js +93 -93
  315. package/_site/lib/engine-knowledge-client.js +76 -72
  316. package/_site/lib/evidence-bundle.js +228 -228
  317. package/_site/lib/folder-picker-output.js +24 -24
  318. package/_site/lib/git-path.js +14 -14
  319. package/_site/lib/git-runner.js +62 -62
  320. package/_site/lib/github-team-store.js +1175 -1175
  321. package/_site/lib/hook-manager.js +203 -203
  322. package/_site/lib/index-builder.js +157 -157
  323. package/_site/lib/index-service.js +173 -173
  324. package/_site/lib/integration-auto-repair.js +77 -77
  325. package/_site/lib/integration-installer.js +1240 -1240
  326. package/_site/lib/integration-intent.js +88 -88
  327. package/_site/lib/integration-status-scan.js +99 -99
  328. package/_site/lib/integration-status-worker.js +14 -14
  329. package/_site/lib/kb-framework.js +191 -191
  330. package/_site/lib/kb-validator.js +124 -124
  331. package/_site/lib/knowledge-db.js +363 -363
  332. package/_site/lib/knowledge-promotion.js +435 -435
  333. package/_site/lib/knowledge-retrieval-service.js +401 -401
  334. package/_site/lib/knowledge-schema.js +121 -121
  335. package/_site/lib/knowledge-tool-runtime.js +366 -366
  336. package/_site/lib/live-gateway.js +78 -78
  337. package/_site/lib/llm-client.js +173 -173
  338. package/_site/lib/markdown-knowledge-indexer.js +230 -230
  339. package/_site/lib/model-context-windows.js +82 -82
  340. package/_site/lib/module-bridge.js +874 -874
  341. package/_site/lib/module-port-resolver.js +57 -57
  342. package/_site/lib/post-commit-automation.js +141 -141
  343. package/_site/lib/product-data.js +35 -35
  344. package/_site/lib/project-lifecycle-service.js +554 -554
  345. package/_site/lib/project-registry-store.js +129 -129
  346. package/_site/lib/project-store.js +268 -268
  347. package/_site/lib/prompt-registry.js +148 -148
  348. package/_site/lib/public-version-info.js +37 -0
  349. package/_site/lib/registry-events.js +16 -16
  350. package/_site/lib/requirement-adapters.js +10 -10
  351. package/_site/lib/requirement-binder.js +112 -112
  352. package/_site/lib/requirement-recorder.js +278 -278
  353. package/_site/lib/runtime-control.js +89 -89
  354. package/_site/lib/runtime-endpoint.js +160 -160
  355. package/_site/lib/scanner.js +298 -298
  356. package/_site/lib/server-app.js +1672 -1664
  357. package/_site/lib/settings-store.js +153 -153
  358. package/_site/lib/storage-layout.js +166 -166
  359. package/_site/lib/structured-logger.js +574 -574
  360. package/_site/lib/zcode-context-integration.js +60 -60
  361. package/_site/scripts/codex-notify-fanout.cjs +95 -95
  362. package/_site/scripts/folder-picker.ps1 +156 -156
  363. package/_site/scripts/hook-trigger.js +158 -158
  364. package/_site/scripts/install-module-candidates.js +69 -69
  365. package/_site/scripts/pack-module-candidates.js +89 -89
  366. package/_site/scripts/sync-product-content.js +28 -28
  367. package/_site/scripts/sync-release-version.js +164 -164
  368. package/_site/scripts/vendor-modules.js +49 -49
  369. package/_site/scripts/verify-module-runtime.js +50 -50
  370. package/_site/scripts/verify-product-runtime.js +36 -36
  371. package/_site/scripts/verify-retrieval-gold.js +83 -83
  372. package/_site/server.js +15 -15
  373. package/_site/start.bat +26 -26
  374. package/_site/stop.bat +11 -11
  375. package/bin/project-knowledge-integrations.js +254 -254
  376. package/bin/project-knowledge-kb.js +67 -67
  377. package/bin/project-knowledge-mcp.js +201 -201
  378. package/bin/project-knowledge.js +269 -170
  379. package/claude-prompts.json +21 -21
  380. package/docs/README.zh-CN.md +207 -205
  381. package/docs/assets/architecture.svg +181 -181
  382. package/docs/assets/logo.svg +49 -49
  383. package/docs/fresh-v5-start.md +44 -44
  384. package/docs/leader-glm-workbench-playbook.md +122 -122
  385. package/docs/project-registry-schema.md +33 -33
  386. package/docs/release-5.0.16-acceptance.md +176 -176
  387. package/docs/release-5.0.17-acceptance.md +117 -117
  388. package/docs/release-5.0.19-acceptance.md +39 -39
  389. package/docs/team-knowledge-mode-a-plan.md +73 -73
  390. package/docs/testing-strategy.md +33 -33
  391. package/module-runtime-manifest.json +66 -63
  392. package/package.json +113 -110
  393. package/plugins/project-knowledge/.claude-plugin/plugin.json +1 -1
  394. package/plugins/project-knowledge/.codex-plugin/plugin.json +1 -1
  395. package/plugins/project-knowledge/.mcp.json +1 -1
  396. package/templates/change.md +30 -30
  397. package/templates/project-readme.md +52 -52
  398. package/ui/index.html +3 -2
  399. package/ui/version-info.css +44 -0
  400. package/ui/version-info.js +24 -0
  401. package/vendor-manifest.json +55 -55
@@ -0,0 +1,228 @@
1
+ 'use strict';
2
+ // _site/_test/parallel-memory-scope-test.js
3
+ //
4
+ // MEM-004 确认目标(适用范围).
5
+ //
6
+ // Real isolated product instance, real browser, real HTTP and real disk. Three
7
+ // real projects are imported into one real brain: two of them belong to a real
8
+ // domain, the third belongs to none. Three real memories are added through the
9
+ // real UI: one global, one bound to the domain, one bound to a single project.
10
+ //
11
+ // MEM-004 expected:
12
+ // * scopeId与scopeType匹配。 -> the stored memory carries the scope id that
13
+ // belongs to its scope type, the UI only offers
14
+ // targets of that type, and the engine refuses
15
+ // a scope id that does not belong to the
16
+ // declared scope type;
17
+ // * 只影响指定范围。 -> a global memory reaches every project, a
18
+ // domain memory only reaches the projects of
19
+ // that domain, a project memory only reaches
20
+ // that project.
21
+
22
+ const fs = require('node:fs');
23
+ const path = require('node:path');
24
+ const assert = require('node:assert/strict');
25
+
26
+ const { startHarness, makeRepo } = require('./helpers/parallel-memory-shell');
27
+
28
+ const EVIDENCE = process.env.PK_TEST_EVIDENCE_DIR ? path.resolve(process.env.PK_TEST_EVIDENCE_DIR) : null;
29
+ const GLOBAL_TEXT = '全局约定:所有对外错误信息使用中文表述。';
30
+ const DOMAIN_TEXT = '平台领域约定:发布流程必须先跑完整回归。';
31
+ const PROJECT_TEXT = '项目约定:数据库迁移脚本一律放在 db/migrations。';
32
+
33
+ async function openMemoryView(harness) {
34
+ await harness.nativeClick('nav [data-view="memory"]');
35
+ await harness.waitFor(
36
+ () => harness.run("document.getElementById('view-memory').classList.contains('active')"),
37
+ 'the memory view is open',
38
+ 10000,
39
+ );
40
+ }
41
+
42
+ /** Add one memory through the real UI and return what the engine answered. */
43
+ async function addMemoryViaUi(harness, { text, scopeType, scopeId }) {
44
+ await harness.nativeClick('#addMemory');
45
+ await harness.waitFor(
46
+ () => harness.run("document.getElementById('memoryDialog').open === true"),
47
+ 'the add dialog is open',
48
+ 10000,
49
+ );
50
+ await harness.typeText(text);
51
+ await harness.selectOption('#memoryScope', scopeType);
52
+ if (scopeType !== 'global') {
53
+ const options = await harness.run("Array.from(document.getElementById('memoryTarget').options).map(o => o.value)");
54
+ assert.ok(options.includes(scopeId), `the ${scopeType} scope offers ${scopeId}: ${JSON.stringify(options)}`);
55
+ await harness.selectOption('#memoryTarget', scopeId);
56
+ }
57
+ const postsBefore = harness.network.find(entry => entry.method === 'POST' && entry.url.includes('/api/engine/memories')).length;
58
+ await harness.nativeClick('#confirmMemory');
59
+ await harness.waitFor(
60
+ () => harness.run("document.getElementById('memoryDialog').open === false"),
61
+ 'the dialog closes after the save',
62
+ 15000,
63
+ );
64
+ const post = harness.network.find(entry => entry.method === 'POST' && entry.url.includes('/api/engine/memories'))[postsBefore];
65
+ assert.ok(post, 'the shell really posted the memory');
66
+ assert.equal(post.status, 200, `the real POST answers 200: ${JSON.stringify(post.body)}`);
67
+ const body = await harness.network.body(post);
68
+ assert.ok(body && body.memory, `the real POST answers with the memory: ${JSON.stringify(body)}`);
69
+ assert.equal(body.memory.text, text, 'the saved text is the text that was typed');
70
+ assert.equal(body.memory.scopeType, scopeType, 'the saved scope type is the chosen one');
71
+ assert.equal(body.memory.scopeId, scopeId || body.memory.brainId, 'the saved scope id belongs to the scope type');
72
+ assert.equal(body.memory.status, 'confirmed', 'the memory is saved as confirmed');
73
+ return { memory: body.memory, request: post.body, url: post.url.replace(harness.base, '') };
74
+ }
75
+
76
+ async function main() {
77
+ const harness = await startHarness({ tag: 'memscope', evidenceDir: EVIDENCE || undefined });
78
+ const evidence = [];
79
+ try {
80
+ const domain = await harness.addDomain('平台领域');
81
+ assert.ok(domain.id, 'the real domain has an id');
82
+
83
+ const repoA = makeRepo(harness.fixture, 'memscope-a', { 'README.md': '# 甲\n' });
84
+ const repoB = makeRepo(harness.fixture, 'memscope-b', { 'README.md': '# 乙\n' });
85
+ const repoC = makeRepo(harness.fixture, 'memscope-c', { 'README.md': '# 丙\n' });
86
+ const a = await harness.importProject(repoA, '范围甲', { domainId: domain.id });
87
+ const b = await harness.importProject(repoB, '范围乙', { domainId: domain.id });
88
+ const c = await harness.importProject(repoC, '范围丙');
89
+
90
+ await harness.requestRegistryRefresh();
91
+ await harness.waitFor(
92
+ () => harness.run("document.getElementById('homeContent').textContent.includes('范围丙')"),
93
+ 'the imported projects are listed',
94
+ 20000,
95
+ );
96
+
97
+ // The engine really knows the domain binding of every project.
98
+ const engineProjects = (await harness.engineApi('GET', '/api/projects')).body.projects;
99
+ assert.equal(engineProjects.find(p => p.projectId === a.projectId).domainId, domain.id, 'the engine knows the domain of 甲');
100
+ assert.equal(engineProjects.find(p => p.projectId === b.projectId).domainId, domain.id, 'the engine knows the domain of 乙');
101
+ assert.equal(engineProjects.find(p => p.projectId === c.projectId).domainId || null, null, 'the engine knows 丙 has no domain');
102
+
103
+ // The UI works on project 甲, the one inside the domain.
104
+ await harness.selectOption('#projectSelect', a.projectId);
105
+ await harness.waitFor(
106
+ () => harness.run("document.getElementById('projectSelect').value === " + JSON.stringify(a.projectId)),
107
+ 'the active project is 甲',
108
+ 10000,
109
+ );
110
+ await openMemoryView(harness);
111
+ await harness.waitFor(
112
+ () => harness.run("!document.getElementById('addMemory').disabled"),
113
+ 'the engine is reachable and the add button is live',
114
+ 20000,
115
+ );
116
+
117
+ // ---------------------------------------------------------------- MEM-004
118
+ const globalMemory = await addMemoryViaUi(harness, { text: GLOBAL_TEXT, scopeType: 'global' });
119
+ const domainMemory = await addMemoryViaUi(harness, { text: DOMAIN_TEXT, scopeType: 'domain', scopeId: domain.id });
120
+ const projectMemory = await addMemoryViaUi(harness, { text: PROJECT_TEXT, scopeType: 'project', scopeId: a.projectId });
121
+
122
+ assert.equal(globalMemory.memory.scopeId, globalMemory.memory.brainId, 'a global memory targets the brain itself');
123
+ assert.equal(domainMemory.memory.scopeId, domain.id, 'a domain memory targets the domain');
124
+ assert.equal(projectMemory.memory.scopeId, a.projectId, 'a project memory targets the project');
125
+
126
+ // The scope id has to belong to the scope type: the engine refuses the
127
+ // mismatched combinations instead of silently storing them.
128
+ const mismatches = [
129
+ { scopeType: 'domain', scopeId: a.projectId, why: 'a project id is not a domain' },
130
+ { scopeType: 'project', scopeId: domain.id, why: 'a domain id is not a project' },
131
+ { scopeType: 'global', scopeId: a.projectId, why: 'a global memory always targets the brain' },
132
+ ];
133
+ for (const mismatch of mismatches) {
134
+ const refused = await harness.productApi('POST', '/api/engine/memories', { text: `范围不匹配的记忆:${mismatch.why}`, scopeType: mismatch.scopeType, scopeId: mismatch.scopeId });
135
+ assert.equal(refused.status, 400, `the engine refuses ${mismatch.why}: ${JSON.stringify(refused.body)}`);
136
+ assert.equal(refused.body.error, 'INVALID_ARGUMENT', 'the engine reports an invalid argument');
137
+ assert.match(String(refused.body.message), /所选记忆目标不存在或不属于当前智脑。/, 'the engine names the missing target');
138
+ }
139
+ const noMismatch = await harness.productMemories();
140
+ assert.ok(!noMismatch.some(memory => memory.text.startsWith('范围不匹配的记忆')), 'no mismatched memory was stored');
141
+
142
+ // 只影响指定范围: the injection matrix.
143
+ const injectedA = await harness.injectedMemories(a.projectId);
144
+ const injectedB = await harness.injectedMemories(b.projectId);
145
+ const injectedC = await harness.injectedMemories(c.projectId);
146
+ const ids = injected => injected.map(entry => entry.memoryId);
147
+ assert.ok(ids(injectedA).includes(globalMemory.memory.id), 'the global memory reaches 甲');
148
+ assert.ok(ids(injectedB).includes(globalMemory.memory.id), 'the global memory reaches 乙');
149
+ assert.ok(ids(injectedC).includes(globalMemory.memory.id), 'the global memory reaches 丙');
150
+ assert.ok(ids(injectedA).includes(domainMemory.memory.id), 'the domain memory reaches 甲');
151
+ assert.ok(ids(injectedB).includes(domainMemory.memory.id), 'the domain memory reaches 乙');
152
+ assert.ok(!ids(injectedC).includes(domainMemory.memory.id), `the domain memory does not reach 丙: ${JSON.stringify(injectedC)}`);
153
+ assert.ok(ids(injectedA).includes(projectMemory.memory.id), 'the project memory reaches 甲');
154
+ assert.ok(!ids(injectedB).includes(projectMemory.memory.id), `the project memory does not reach 乙: ${JSON.stringify(injectedB)}`);
155
+ assert.ok(!ids(injectedC).includes(projectMemory.memory.id), `the project memory does not reach 丙: ${JSON.stringify(injectedC)}`);
156
+
157
+ // The real UI names the scope of every memory.
158
+ await harness.reload();
159
+ await openMemoryView(harness);
160
+ await harness.nativeClick('[data-memory-tab="confirmed"]');
161
+ await harness.waitFor(
162
+ () => harness.run(`document.getElementById('memoryContent').textContent.includes(${JSON.stringify(GLOBAL_TEXT)})`),
163
+ 'the confirmed memories are listed',
164
+ 15000,
165
+ );
166
+ const scopeLabels = await harness.run("Array.from(document.querySelectorAll('[data-memory-card]')).map(el => el.textContent)");
167
+ const globalCard = scopeLabels.find(text => text.includes(GLOBAL_TEXT));
168
+ const domainCard = scopeLabels.find(text => text.includes(DOMAIN_TEXT));
169
+ const projectCard = scopeLabels.find(text => text.includes(PROJECT_TEXT));
170
+ assert.match(globalCard, /全局/, 'the UI names the global scope');
171
+ assert.match(domainCard, /领域/, 'the UI names the domain scope');
172
+ assert.match(domainCard, new RegExp(domain.name), 'the UI names the domain');
173
+ assert.match(projectCard, /项目/, 'the UI names the project scope');
174
+ assert.match(projectCard, new RegExp('范围甲'), 'the UI names the project');
175
+ if (harness.evidence) await harness.browser.screenshot(path.join(harness.evidence, 'mem004-scopes.png'));
176
+
177
+ // The memory files really live in the scope they claim. The engine
178
+ // materializes every scope's memory file in the brain's shared directory:
179
+ // the domain scope directory itself holds no memory file.
180
+ const brainScope = harness.brainScopePath();
181
+ const domainScope = harness.domainScopePath(domain.id);
182
+ assert.ok(fs.existsSync(path.join(brainScope, 'memories', 'confirmed.md')), 'the global memory file exists');
183
+ assert.ok(fs.existsSync(path.join(brainScope, 'memories', 'domains', `${domain.id}.md`)), 'the domain memory file exists');
184
+ assert.ok(fs.existsSync(path.join(brainScope, 'memories', 'projects', `${a.projectId}.md`)), 'the project memory file exists');
185
+ assert.ok(!fs.existsSync(path.join(domainScope, 'memories')), 'the domain scope directory holds no memory file of its own');
186
+ const globalFile = fs.readFileSync(path.join(brainScope, 'memories', 'confirmed.md'), 'utf8');
187
+ assert.ok(globalFile.includes(globalMemory.memory.id), 'the global file holds the global memory');
188
+ assert.ok(!globalFile.includes(domainMemory.memory.id), 'the global file does not hold the domain memory');
189
+ const domainFile = fs.readFileSync(path.join(brainScope, 'memories', 'domains', `${domain.id}.md`), 'utf8');
190
+ assert.ok(domainFile.includes(domainMemory.memory.id), 'the domain file holds the domain memory');
191
+ const projectFile = fs.readFileSync(path.join(brainScope, 'memories', 'projects', `${a.projectId}.md`), 'utf8');
192
+ assert.ok(projectFile.includes(projectMemory.memory.id), 'the project file holds the project memory');
193
+ assert.ok(!projectFile.includes(globalMemory.memory.id), 'the project file does not hold the global memory');
194
+
195
+ evidence.push({
196
+ case: 'MEM-004',
197
+ domain: { id: domain.id, name: domain.name },
198
+ projects: { a: a.projectId, b: b.projectId, c: c.projectId },
199
+ memories: {
200
+ global: { id: globalMemory.memory.id, scopeType: globalMemory.memory.scopeType, scopeId: globalMemory.memory.scopeId },
201
+ domain: { id: domainMemory.memory.id, scopeType: domainMemory.memory.scopeType, scopeId: domainMemory.memory.scopeId },
202
+ project: { id: projectMemory.memory.id, scopeType: projectMemory.memory.scopeType, scopeId: projectMemory.memory.scopeId },
203
+ },
204
+ mismatchedScopes: mismatches.map(mismatch => mismatch.scopeType),
205
+ injected: { a: ids(injectedA), b: ids(injectedB), c: ids(injectedC) },
206
+ files: {
207
+ brainScope,
208
+ domainScope,
209
+ global: path.join(brainScope, 'memories', 'confirmed.md'),
210
+ domain: path.join(brainScope, 'memories', 'domains', `${domain.id}.md`),
211
+ project: path.join(brainScope, 'memories', 'projects', `${a.projectId}.md`),
212
+ },
213
+ });
214
+
215
+ assert.equal(harness.browser.exceptions.length, 0, `no uncaught product JavaScript exceptions: ${JSON.stringify(harness.browser.exceptions)}`);
216
+
217
+ if (harness.evidence) {
218
+ fs.mkdirSync(harness.evidence, { recursive: true });
219
+ fs.writeFileSync(path.join(harness.evidence, 'mem004-scope.json'), `${JSON.stringify(evidence, null, 2)}\n`, 'utf8');
220
+ }
221
+
222
+ console.log('parallel-memory-scope-test PASS (MEM-004 scope id matches scope type; global, domain and project scopes only reach their own range)');
223
+ } finally {
224
+ await harness.cleanup();
225
+ }
226
+ }
227
+
228
+ main().catch(error => { console.error(error.stack || error.message); process.exitCode = 1; });
@@ -0,0 +1,227 @@
1
+ 'use strict';
2
+ // _site/_test/parallel-memory-source-test.js
3
+ //
4
+ // MEM-008 来源边界(维护 / 委派不自动成为人类偏好).
5
+ //
6
+ // Real isolated product instance, real browser, real HTTP and real disk.
7
+ //
8
+ // Every case runs the REAL pipeline: a real follow-up commit, a real frozen
9
+ // conversation event with a real inputOrigin, the real promotion of a staged
10
+ // Markdown file and the engine's own MemoryService.capture() with its own
11
+ // provenance gate (MemoryEligibility). The stand-in analyzer plays the role of
12
+ // the model: it proposes a candidate that reads exactly like an owner
13
+ // preference, and the engine's own gate has to refuse it.
14
+ //
15
+ // HONEST SCOPE LABEL: the analysis step is this lane's declared stand-in
16
+ // analyzer. These cases prove the engine's admission gate, never the model's
17
+ // judgement about what is worth remembering.
18
+ //
19
+ // MEM-008 expected:
20
+ // * 不自动成为人类偏好。 -> a delegated task order, an unverifiable source and
21
+ // a candidate without a user event are all refused
22
+ // by the engine's own gate; no memory is stored, the
23
+ // real candidate box stays empty and nothing is
24
+ // injected;
25
+ // * C01未解决项明确阻断。 -> the human side cannot be proven in this batch:
26
+ // a real Workbench conversation is needed and MEM-007
27
+ // is deferred to the real-Workbench batch, so this
28
+ // case is reported as BLOCKED, not as a pass.
29
+
30
+ const fs = require('node:fs');
31
+ const path = require('node:path');
32
+ const assert = require('node:assert/strict');
33
+
34
+ const { startHarness, makeRepo, commitFile } = require('./helpers/parallel-memory-shell');
35
+
36
+ const EVIDENCE = process.env.PK_TEST_EVIDENCE_DIR ? path.resolve(process.env.PK_TEST_EVIDENCE_DIR) : null;
37
+ const DELEGATED_TEXT = '委派指令:请在所有项目中统一使用中文错误提示。';
38
+ const UNKNOWN_TEXT = '来源不明的要求:所有提交信息必须使用祈使句。';
39
+ const UNSOURCED_TEXT = '维护产物自述:团队偏好所有注释使用中文。';
40
+ const MISSING_EVENT_TEXT = '引用不存在的事件:所有文档必须标注版本号。';
41
+
42
+ async function main() {
43
+ const harness = await startHarness({ tag: 'memsource', evidenceDir: EVIDENCE || undefined });
44
+ const evidence = [];
45
+ try {
46
+ const repo = makeRepo(harness.fixture, 'memsource-repo', { 'README.md': '# 来源甲\n' });
47
+ const { projectId } = await harness.importProject(repo, '来源甲');
48
+ await harness.requestRegistryRefresh();
49
+ await harness.waitFor(
50
+ () => harness.run("document.getElementById('homeContent').textContent.includes('来源甲')"),
51
+ 'the imported project is listed',
52
+ 20000,
53
+ );
54
+
55
+ /** Run one real maintenance round that proposes one candidate. */
56
+ const attempt = async ({ file, content, document, candidate, inputOrigin = 'human', eventContent }) => {
57
+ const head = commitFile(repo, file, content, 'source boundary commit');
58
+ let event = null;
59
+ if (eventContent !== null) {
60
+ event = await harness.ingestUserEvent({ projectId, commitSha: head, content: eventContent, inputOrigin });
61
+ }
62
+ harness.plan.document = document;
63
+ harness.plan.memoryCandidates = [candidate(event)];
64
+ const run = await harness.triggerRun(projectId, head);
65
+ return { run, commitSha: head, event, capture: run.memoryCapture };
66
+ };
67
+
68
+ // ------------------------------------------------------- delegated order
69
+ const delegated = await attempt({
70
+ file: 'src/delegated.js',
71
+ content: `// ${DELEGATED_TEXT}\n`,
72
+ document: `# 冻结证据\n\n${DELEGATED_TEXT}\n`,
73
+ inputOrigin: 'agent-delegation',
74
+ eventContent: `委派任务:${DELEGATED_TEXT}`,
75
+ candidate: event => harness.memoryCandidate({ text: DELEGATED_TEXT, event, scopeType: 'global' }),
76
+ });
77
+ assert.equal(delegated.capture.accepted, 0, 'a delegated task order is not admitted');
78
+ assert.deepEqual(delegated.capture.rejected.map(entry => entry.code), ['SOURCE_NOT_HUMAN'], 'the gate names the non-human source');
79
+
80
+ // ------------------------------------------------------- unknown origin
81
+ const unknown = await attempt({
82
+ file: 'src/unknown.js',
83
+ content: `// ${UNKNOWN_TEXT}\n`,
84
+ document: `# 冻结证据\n\n${UNKNOWN_TEXT}\n`,
85
+ inputOrigin: 'unknown',
86
+ eventContent: `无法确认来源的输入:${UNKNOWN_TEXT}`,
87
+ candidate: event => harness.memoryCandidate({ text: UNKNOWN_TEXT, event, scopeType: 'global' }),
88
+ });
89
+ assert.equal(unknown.capture.accepted, 0, 'an unverifiable source is not admitted');
90
+ assert.deepEqual(unknown.capture.rejected.map(entry => entry.code), ['SOURCE_NOT_HUMAN'], 'the gate names the non-human source');
91
+
92
+ // ------------------------------------- candidate without any user event
93
+ const unsourced = await attempt({
94
+ file: 'src/unsourced.js',
95
+ content: `// ${UNSOURCED_TEXT}\n`,
96
+ document: `# 冻结证据\n\n${UNSOURCED_TEXT}\n`,
97
+ eventContent: `人工要求:${UNSOURCED_TEXT}`,
98
+ candidate: () => ({
99
+ text: UNSOURCED_TEXT,
100
+ quote: UNSOURCED_TEXT,
101
+ scopeType: 'global',
102
+ eligibility: { durable: true, crossProject: true, reason: '人工明确表达的长期偏好', scopeReason: '适用于所有领域与项目' },
103
+ }),
104
+ });
105
+ assert.equal(unsourced.capture.accepted, 0, 'a candidate without a user event is not admitted');
106
+ assert.deepEqual(unsourced.capture.rejected.map(entry => entry.code), ['SOURCE_EVENT_MISSING'], 'the gate names the missing source event');
107
+
108
+ // ------------------------------------------ candidate with a wrong event
109
+ const missingEvent = await attempt({
110
+ file: 'src/missing-event.js',
111
+ content: `// ${MISSING_EVENT_TEXT}\n`,
112
+ document: `# 冻结证据\n\n${MISSING_EVENT_TEXT}\n`,
113
+ eventContent: `人工要求:${MISSING_EVENT_TEXT}`,
114
+ candidate: () => ({
115
+ text: MISSING_EVENT_TEXT,
116
+ quote: MISSING_EVENT_TEXT,
117
+ scopeType: 'global',
118
+ sourceEventId: 'event-does-not-exist',
119
+ sourceHash: 'sha256:0000000000000000000000000000000000000000000000000000000000000000',
120
+ eligibility: { durable: true, crossProject: true, reason: '人工明确表达的长期偏好', scopeReason: '适用于所有领域与项目' },
121
+ }),
122
+ });
123
+ assert.equal(missingEvent.capture.accepted, 0, 'a candidate citing an unknown event is not admitted');
124
+ assert.deepEqual(missingEvent.capture.rejected.map(entry => entry.code), ['SOURCE_EVENT_NOT_FOUND'], 'the gate names the unknown source event');
125
+
126
+ // Nothing became a memory anywhere.
127
+ const stored = await harness.productMemories();
128
+ assert.deepEqual(stored, [], `no memory was stored: ${JSON.stringify(stored)}`);
129
+ const injected = await harness.injectedMemories(projectId);
130
+ assert.deepEqual(injected, [], `nothing is injected: ${JSON.stringify(injected)}`);
131
+
132
+ // The real UI shows an empty candidate box and says the shell does not
133
+ // turn project behaviour into the owner's preferences.
134
+ //
135
+ // Failure-path visibility (CI 40062048045 kept only a bare timeout): on a
136
+ // navigation failure, capture the page's real readiness state, the reload
137
+ // gate log, the product's uncaught exceptions and a screenshot (small
138
+ // metadata; the CI console is the only artifact the runner keeps).
139
+ const debugNavigationFailure = async stage => {
140
+ try {
141
+ const state = await harness.navigationState();
142
+ const exceptions = harness.browser.exceptions
143
+ .map(entry => String((entry.exceptionDetails && (entry.exceptionDetails.exception && entry.exceptionDetails.exception.description || entry.exceptionDetails.text)) || ''))
144
+ .filter(Boolean).slice(0, 3);
145
+ console.error(`MEM-008 navigation failure at ${stage}: ${JSON.stringify(state)} reloadGate=${JSON.stringify(harness.reloadLog)} exceptions=${JSON.stringify(exceptions)}`);
146
+ if (harness.evidence) await harness.browser.screenshot(path.join(harness.evidence, `mem008-failure-${stage}.png`));
147
+ } catch {}
148
+ };
149
+ await harness.reload();
150
+ await harness.nativeClick('nav [data-view="memory"]');
151
+ try {
152
+ await harness.waitFor(
153
+ () => harness.run("document.getElementById('view-memory').classList.contains('active')"),
154
+ 'the memory view is open',
155
+ 10000,
156
+ );
157
+ } catch (error) {
158
+ await debugNavigationFailure('memory-view-open');
159
+ throw error;
160
+ }
161
+ await harness.nativeClick('[data-memory-tab="candidate"]');
162
+ try {
163
+ await harness.waitFor(
164
+ () => harness.run("document.getElementById('memoryContent').textContent.includes('候选箱为空。')"),
165
+ 'the candidate box is really empty once the engine answered again',
166
+ 20000,
167
+ );
168
+ } catch (error) {
169
+ await debugNavigationFailure('candidate-box-empty');
170
+ throw error;
171
+ }
172
+ const candidateBox = await harness.run("document.getElementById('memoryContent').textContent");
173
+ assert.match(candidateBox, /候选箱为空。/, `the candidate box is really empty: ${candidateBox}`);
174
+ assert.ok(!candidateBox.includes(DELEGATED_TEXT), 'the delegated order is not listed');
175
+ assert.ok(!candidateBox.includes(UNSOURCED_TEXT), 'the unsourced preference is not listed');
176
+ if (harness.evidence) await harness.browser.screenshot(path.join(harness.evidence, 'mem008-candidate-empty.png'));
177
+
178
+ await harness.nativeClick('nav [data-view="home"]');
179
+ try {
180
+ await harness.waitFor(
181
+ () => harness.run("document.getElementById('view-home').classList.contains('active')"),
182
+ 'the home view is open',
183
+ 10000,
184
+ );
185
+ } catch (error) {
186
+ await debugNavigationFailure('home-view-open');
187
+ throw error;
188
+ }
189
+ const home = await harness.run("document.getElementById('homeContent').textContent");
190
+ assert.match(home, /没有待确认记忆。智脑不会自动把项目行为当作你的偏好。/, `the home view states the boundary: ${home}`);
191
+ if (harness.evidence) await harness.browser.screenshot(path.join(harness.evidence, 'mem008-home.png'));
192
+
193
+ evidence.push({
194
+ case: 'MEM-008',
195
+ attempts: [
196
+ { kind: 'agent-delegation', commitSha: delegated.commitSha, accepted: delegated.capture.accepted, rejected: delegated.capture.rejected },
197
+ { kind: 'unknown', commitSha: unknown.commitSha, accepted: unknown.capture.accepted, rejected: unknown.capture.rejected },
198
+ { kind: 'no-user-event', commitSha: unsourced.commitSha, accepted: unsourced.capture.accepted, rejected: unsourced.capture.rejected },
199
+ { kind: 'unknown-event-id', commitSha: missingEvent.commitSha, accepted: missingEvent.capture.accepted, rejected: missingEvent.capture.rejected },
200
+ ],
201
+ storedMemories: stored,
202
+ injected,
203
+ ui: { candidateBox, home },
204
+ blocked: [{
205
+ id: 'C01',
206
+ expectation: 'C01未解决项明确阻断。',
207
+ status: 'BLOCKED',
208
+ reason: 'The human side of the boundary needs a real Workbench conversation: whether a Workbench user event is the owner speaking depends on the unresolved C01 boundary-record chain. This batch has no real Workbench session (MEM-007 is deferred to the real-Workbench batch), so only the engine-side refusal of delegated / unverifiable / unsourced candidates is proven here.',
209
+ evidenceInThisBatch: 'The engine conversation store was fed a real event with inputOrigin=human through the engine\'s own store, so the human path of the gate is exercised at the store level only.',
210
+ }],
211
+ scopeLabel: 'honest: the analysis step is the lane stand-in analyzer, not a model',
212
+ });
213
+
214
+ assert.equal(harness.browser.exceptions.length, 0, `no uncaught product JavaScript exceptions: ${JSON.stringify(harness.browser.exceptions)}`);
215
+
216
+ if (harness.evidence) {
217
+ fs.mkdirSync(harness.evidence, { recursive: true });
218
+ fs.writeFileSync(path.join(harness.evidence, 'mem008-source-boundary.json'), `${JSON.stringify(evidence, null, 2)}\n`, 'utf8');
219
+ }
220
+
221
+ console.log('parallel-memory-source-test PASS (MEM-008 delegated / unverifiable / unsourced candidates are all refused by the real gate; C01 human-source determination is BLOCKED in this batch)');
222
+ } finally {
223
+ await harness.cleanup();
224
+ }
225
+ }
226
+
227
+ main().catch(error => { console.error(error.stack || error.message); process.exitCode = 1; });