@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.
- package/.agents/plugins/marketplace.json +20 -20
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +1361 -1353
- package/LICENSE +201 -201
- package/NOTICE +5 -5
- package/README.md +349 -349
- package/_modules/knowledge-engine/package.json +1 -1
- package/_modules/knowledge-engine/src/coordinator.js +48 -3
- package/_modules/knowledge-engine/src/runtime/automation-config.js +140 -140
- package/_modules/knowledge-engine/src/runtime/commit-conversation-binder.js +238 -238
- package/_modules/knowledge-engine/src/runtime/commit-processing-ledger.js +26 -26
- package/_modules/knowledge-engine/src/runtime/commit-prompt.js +193 -193
- package/_modules/knowledge-engine/src/runtime/commit-reconciler.js +394 -394
- package/_modules/knowledge-engine/src/runtime/contracts.js +282 -282
- package/_modules/knowledge-engine/src/runtime/conversation-store.js +389 -389
- package/_modules/knowledge-engine/src/runtime/evidence-bundle.js +228 -228
- package/_modules/knowledge-engine/src/runtime/git-runner.js +62 -62
- package/_modules/knowledge-engine/src/runtime/knowledge-promotion.js +505 -505
- package/_modules/knowledge-engine/src/runtime/knowledge-retrieval-service.js +400 -400
- package/_modules/knowledge-engine/src/runtime/markdown-knowledge-indexer.js +171 -171
- package/_modules/knowledge-engine/src/runtime/scanner.js +298 -298
- package/_modules/knowledge-engine/ui/app.js +23 -2
- package/_site/README.md +30 -30
- package/_site/_test/agent-capture-mcp-ui-test.js +68 -68
- package/_site/_test/agent-capture-ui-test.js +101 -101
- package/_site/_test/ai-profile-resolver-test.js +137 -137
- package/_site/_test/ai-profile-test.js +75 -75
- package/_site/_test/ai-vendor-presets-test.js +91 -91
- package/_site/_test/automatic-context-test.js +70 -70
- package/_site/_test/automation-queue-test.js +14 -14
- package/_site/_test/automation-ui-test.js +40 -40
- package/_site/_test/background-task-registry-test.js +43 -43
- package/_site/_test/baseline-schema-test.js +91 -91
- package/_site/_test/bin-cli-test.js +230 -230
- package/_site/_test/bridge-adapter-test.js +95 -95
- package/_site/_test/bridge-consumer-service-test.js +310 -310
- package/_site/_test/candidate-bin-content-test.js +35 -35
- package/_site/_test/candidate-product-assets-test.js +13 -13
- package/_site/_test/candidate-release-contract-test.js +14 -14
- package/_site/_test/capture-hook-dedup-test.js +158 -158
- package/_site/_test/cdp-browser-failure-test.js +103 -103
- package/_site/_test/chat-claudecodeui-match-test.js +92 -92
- package/_site/_test/claude-executable-discovery-test.js +90 -90
- package/_site/_test/claude-session-lifecycle-sweep-test.js +252 -252
- package/_site/_test/claude-workbench-test.js +174 -174
- package/_site/_test/cli-instance-management-test.js +62 -62
- package/_site/_test/client-capture-restart-e2e-test.js +189 -189
- package/_site/_test/codex-conversation-projection-test.js +60 -60
- package/_site/_test/codex-marketplace-scoped-path-test.js +186 -186
- package/_site/_test/codex-notify-capture-e2e-test.js +101 -101
- package/_site/_test/codex-notify-fanout-test.js +141 -134
- package/_site/_test/codex-notify-upgrade-test.js +253 -253
- package/_site/_test/commit-boundary-freeze-test.js +147 -147
- package/_site/_test/commit-conversation-binding-test.js +99 -99
- package/_site/_test/commit-evidence-test.js +110 -110
- package/_site/_test/configuration-generation-test.js +22 -22
- package/_site/_test/context-pack-test.js +200 -200
- package/_site/_test/conversation-api-test.js +119 -119
- package/_site/_test/conversation-origin-test.js +15 -15
- package/_site/_test/conversation-store-test.js +138 -138
- package/_site/_test/cross-repo-isolation-e2e-test.js +187 -187
- package/_site/_test/desktop-browser-compat-test.js +28 -28
- package/_site/_test/desktop-hook-runtime-regression-test.js +204 -204
- package/_site/_test/embedding-config-test.js +32 -32
- package/_site/_test/explicit-commit-processor-test.js +37 -37
- package/_site/_test/fixtures/fake-browser-exit.js +10 -10
- package/_site/_test/fixtures/fake-browser-hang.js +10 -10
- package/_site/_test/fixtures/integration-busy-worker.cjs +6 -6
- package/_site/_test/fixtures/make-git-repos.js +92 -92
- package/_site/_test/fixtures/retrieval-gold-queries.json +32 -32
- package/_site/_test/folder-picker-output-test.js +19 -19
- package/_site/_test/fresh-hook-reimport-test.js +53 -53
- package/_site/_test/fresh-product-data-test.js +56 -56
- package/_site/_test/full-integration-e2e-test.js +167 -167
- package/_site/_test/git-path-compatibility-test.js +80 -80
- package/_site/_test/git-validation-test.js +81 -81
- package/_site/_test/glm-ui-refresh-review-test.js +313 -404
- package/_site/_test/harness-isolation-test.js +138 -0
- package/_site/_test/helpers/cdp-browser.js +383 -0
- package/_site/_test/helpers/cdp-network-capture.js +66 -0
- package/_site/_test/helpers/find-chrome.js +34 -0
- package/_site/_test/helpers/free-port.js +8 -0
- package/_site/_test/helpers/logging-ui-fixture.js +131 -0
- package/_site/_test/helpers/module-fixture.js +282 -0
- package/_site/_test/helpers/parallel-engine-advanced-engine-child.js +45 -0
- package/_site/_test/helpers/parallel-engine-advanced-fault-writer.js +171 -0
- package/_site/_test/helpers/parallel-engine-advanced-harness.js +245 -0
- package/_site/_test/helpers/parallel-engine-advanced-standin-analyzer.js +80 -0
- package/_site/_test/helpers/parallel-engine-advanced-ui-host.js +177 -0
- package/_site/_test/helpers/parallel-engine-final-harness.js +314 -0
- package/_site/_test/helpers/parallel-engine-final-standin-analyzer.js +159 -0
- package/_site/_test/helpers/parallel-knowledge-fixture.js +255 -0
- package/_site/_test/helpers/parallel-logging-acceptance-fixture.js +111 -0
- package/_site/_test/helpers/parallel-logging-acceptance-proxy.js +106 -0
- package/_site/_test/helpers/parallel-logging-fix-r2-proxy.js +205 -0
- package/_site/_test/helpers/parallel-logging-integration-5025-env.js +432 -0
- package/_site/_test/helpers/parallel-memory-analyzer.js +81 -0
- package/_site/_test/helpers/parallel-memory-event-bridge.js +128 -0
- package/_site/_test/helpers/parallel-memory-shell.js +470 -0
- package/_site/_test/helpers/parallel-nav-isolation-env.js +389 -0
- package/_site/_test/helpers/parallel-nav-module-ui.js +186 -0
- package/_site/_test/helpers/parallel-nav-proxy.js +148 -0
- package/_site/_test/helpers/parallel-nav-shell.js +361 -0
- package/_site/_test/helpers/parallel-qa-engine-endpoint-guard.js +206 -0
- package/_site/_test/helpers/parallel-qa-engine-endpoint-isolate.js +257 -0
- package/_site/_test/helpers/parallel-retrieval-followup-corpus.js +293 -0
- package/_site/_test/helpers/parallel-retrieval-followup-next-session.js +70 -0
- package/_site/_test/helpers/parallel-retrieval-followup-r2-shell.js +737 -0
- package/_site/_test/helpers/parallel-retrieval-followup-r2-wb-host.js +82 -0
- package/_site/_test/helpers/parallel-retrieval-followup-shell.js +279 -0
- package/_site/_test/helpers/parallel-workbench-fixture.js +371 -0
- package/_site/_test/helpers/parallel-workbench-host.js +80 -0
- package/_site/_test/helpers/parallel-workbench-integration-5025-fixture.js +408 -0
- package/_site/_test/helpers/parallel-workbench-integration-5025-harness.js +593 -0
- package/_site/_test/helpers/parallel-workbench-integration-5025-host.js +70 -0
- package/_site/_test/helpers/parallel-workbench-integration-5025-launcher.js +240 -0
- package/_site/_test/helpers/parallel-workbench-integration-5025-runtime-harness.js +630 -0
- package/_site/_test/helpers/parallel-workbench-source-map.js +196 -0
- package/_site/_test/helpers/spawn-server.js +106 -0
- package/_site/_test/helpers/version-visibility-fixture.js +251 -0
- package/_site/_test/hook-runtime-endpoint-test.js +88 -88
- package/_site/_test/hook-status-repair-api-test.js +152 -152
- package/_site/_test/hook-trigger-test.js +85 -85
- package/_site/_test/hook-worktree-test.js +42 -42
- package/_site/_test/import-preflight-api-test.js +234 -234
- package/_site/_test/index-builder-test.js +41 -41
- package/_site/_test/index-error-display-contract-test.js +10 -10
- package/_site/_test/index-writer-concurrency-test.js +135 -135
- package/_site/_test/integration-adapters-test.js +262 -262
- package/_site/_test/integration-auto-repair-test.js +113 -113
- package/_site/_test/integration-capture-setup-test.js +118 -118
- package/_site/_test/integration-intent-test.js +81 -81
- package/_site/_test/integration-runtime-binding-a2-test.js +566 -566
- package/_site/_test/integration-runtime-binding-a3-test.js +227 -227
- package/_site/_test/integration-runtime-binding-test.js +473 -473
- package/_site/_test/integration-status-scan-test.js +29 -29
- package/_site/_test/integration-surface-coverage-test.js +164 -164
- package/_site/_test/kb-framework-test.js +57 -57
- package/_site/_test/kbpath-follow-test.js +63 -63
- package/_site/_test/knowledge-db-test.js +144 -144
- package/_site/_test/knowledge-engine-client-test.js +120 -109
- package/_site/_test/knowledge-language-control-test.js +170 -170
- package/_site/_test/knowledge-maintenance-test.js +40 -40
- package/_site/_test/knowledge-promotion-recovery-test.js +260 -260
- package/_site/_test/knowledge-query-test.js +54 -54
- package/_site/_test/knowledge-retrieval-service-test.js +77 -77
- package/_site/_test/knowledge-scopes-test.js +37 -37
- package/_site/_test/knowledge-storage-location-test.js +28 -28
- package/_site/_test/knowledge-storage-startup-test.js +52 -52
- package/_site/_test/knowledge-store-logs-supervision-test.js +89 -89
- package/_site/_test/launcher-readiness-test.js +80 -80
- package/_site/_test/legacy-claude-session-alias-test.js +106 -106
- package/_site/_test/legacy-routes-removed-test.js +47 -47
- package/_site/_test/legacy-workbench-exclusion-test.js +92 -92
- package/_site/_test/live-gateway-test.js +48 -48
- package/_site/_test/local-marketplace-test.js +16 -16
- package/_site/_test/log-redaction-test.js +58 -58
- package/_site/_test/logging-api-test.js +89 -89
- package/_site/_test/logging-sse-no-gap-test.js +88 -88
- package/_site/_test/logging-ui-test.js +107 -107
- package/_site/_test/markdown-delta-overlay-test.js +85 -85
- package/_site/_test/markdown-maintenance-api-test.js +75 -75
- package/_site/_test/markdown-maintenance-test.js +11 -11
- package/_site/_test/mcp-server-test.js +149 -149
- package/_site/_test/model-context-windows-test.js +89 -89
- package/_site/_test/module-agent-start-proxy-test.js +65 -65
- package/_site/_test/module-artifact-integrity-test.js +27 -27
- package/_site/_test/module-boundary-test.js +30 -30
- package/_site/_test/module-bridge-eventbridge-test.js +202 -202
- package/_site/_test/module-dynamic-port-test.js +118 -118
- package/_site/_test/module-index-proxy-test.js +33 -33
- package/_site/_test/module-model-configuration-test.js +44 -44
- package/_site/_test/module-process-lifecycle-test.js +35 -35
- package/_site/_test/module-stream-proxy-test.js +34 -34
- package/_site/_test/module-terminal-restart-test.js +63 -63
- package/_site/_test/module-wiring-unbind-race-test.js +59 -59
- package/_site/_test/native-context-integrations-test.js +86 -86
- package/_site/_test/non-release-ci-test.js +34 -34
- package/_site/_test/offline-boundary-isolation-test.js +32 -32
- package/_site/_test/orphaned-claim-recovery-test.js +80 -80
- package/_site/_test/package-boundary-test.js +43 -43
- package/_site/_test/package-startup-test.js +56 -56
- package/_site/_test/packaged-ui-smoke-test.js +88 -88
- package/_site/_test/parallel-ci-r9-posix-socket-budget-test.js +156 -0
- package/_site/_test/parallel-engine-advanced-eng005-test.js +136 -0
- package/_site/_test/parallel-engine-advanced-eng006-test.js +171 -0
- package/_site/_test/parallel-engine-advanced-eng007-reconcile-test.js +231 -0
- package/_site/_test/parallel-engine-advanced-eng009-test.js +208 -0
- package/_site/_test/parallel-engine-advanced-eng010-test.js +213 -0
- package/_site/_test/parallel-engine-advanced-eng011-ui-probe.js +459 -0
- package/_site/_test/parallel-engine-final-eng002-test.js +255 -0
- package/_site/_test/parallel-engine-final-eng007-test.js +269 -0
- package/_site/_test/parallel-engine-final-eng011-test.js +197 -0
- package/_site/_test/parallel-engine-final-eng012-test.js +354 -0
- package/_site/_test/parallel-knowledge-client-error-code-test.js +184 -0
- package/_site/_test/parallel-knowledge-engine-test.js +353 -0
- package/_site/_test/parallel-knowledge-retrieval-test.js +292 -0
- package/_site/_test/parallel-knowledge-vector-test.js +168 -0
- package/_site/_test/parallel-linux-ci-r7-log007-day-test.js +110 -0
- package/_site/_test/parallel-logging-acceptance-log003-test.js +224 -0
- package/_site/_test/parallel-logging-acceptance-log004-test.js +231 -0
- package/_site/_test/parallel-logging-acceptance-log005-test.js +208 -0
- package/_site/_test/parallel-logging-acceptance-log006-test.js +214 -0
- package/_site/_test/parallel-logging-acceptance-log007-test.js +223 -0
- package/_site/_test/parallel-logging-acceptance-log008-test.js +180 -0
- package/_site/_test/parallel-logging-fix-r2-crash-probe.js +271 -0
- package/_site/_test/parallel-logging-fix-r2-gap-test.js +294 -0
- package/_site/_test/parallel-logging-fix-r2-normalhook-test.js +330 -0
- package/_site/_test/parallel-logging-integration-5025-portability-test.js +554 -0
- package/_site/_test/parallel-memory-candidate-test.js +301 -0
- package/_site/_test/parallel-memory-manual-test.js +197 -0
- package/_site/_test/parallel-memory-scope-test.js +228 -0
- package/_site/_test/parallel-memory-source-test.js +227 -0
- package/_site/_test/parallel-memory-sync-test.js +238 -0
- package/_site/_test/parallel-memory-view-r8-reload-gate-test.js +123 -0
- package/_site/_test/parallel-nav-failure-test.js +119 -0
- package/_site/_test/parallel-nav-isolation-test.js +308 -0
- package/_site/_test/parallel-nav-isolation-vector-path-test.js +90 -0
- package/_site/_test/parallel-nav-offline-test.js +272 -0
- package/_site/_test/parallel-nav-operability-test.js +257 -0
- package/_site/_test/parallel-nav-switch-test.js +247 -0
- package/_site/_test/parallel-nav-theme-test.js +130 -0
- package/_site/_test/parallel-nav-viewport-test.js +310 -0
- package/_site/_test/parallel-qa-engine-endpoint-guard-test.js +273 -0
- package/_site/_test/parallel-retrieval-followup-citation-test.js +219 -0
- package/_site/_test/parallel-retrieval-followup-corpus-test.js +287 -0
- package/_site/_test/parallel-workbench-independent-host.js +262 -0
- package/_site/_test/parallel-workbench-integration-5025-abort-probe.js +340 -0
- package/_site/_test/parallel-workbench-integration-5025-drafts-probe.js +588 -0
- package/_site/_test/parallel-workbench-integration-5025-env-check.js +317 -0
- package/_site/_test/parallel-workbench-integration-5025-model-probe.js +342 -0
- package/_site/_test/parallel-workbench-integration-5025-ordering-probe.js +326 -0
- package/_site/_test/parallel-workbench-model-probe.js +336 -0
- package/_site/_test/parallel-workbench-offline-test.js +169 -0
- package/_site/_test/parallel-workbench-provenance-trace.js +134 -0
- package/_site/_test/parallel-workbench-source-match.js +206 -0
- package/_site/_test/parallel-workbench-standalone-turn.js +349 -0
- package/_site/_test/path-consistency-test.js +151 -151
- package/_site/_test/pending-sweep-test.js +9 -9
- package/_site/_test/post-commit-automation-test.js +87 -87
- package/_site/_test/pr-consumer-contract-test.js +55 -55
- package/_site/_test/product-brand-contract-test.js +25 -25
- package/_site/_test/product-diagnostics-ui-test.js +93 -93
- package/_site/_test/product-empty-state-test.js +148 -0
- package/_site/_test/product-import-ui-test.js +219 -104
- package/_site/_test/product-navigation-test.js +152 -0
- package/_site/_test/product-progress-status-test.js +84 -84
- package/_site/_test/project-delete-recovery-test.js +64 -64
- package/_site/_test/project-domain-create-test.js +91 -0
- package/_site/_test/project-domain-scope-retrieval-test.js +214 -0
- package/_site/_test/project-git-init-confirm-test.js +115 -0
- package/_site/_test/project-goal-editor-test.js +144 -144
- package/_site/_test/project-import-duplicate-alias-test.js +134 -0
- package/_site/_test/project-import-unicode-restart-test.js +140 -0
- package/_site/_test/project-lifecycle-transaction-test.js +106 -106
- package/_site/_test/project-module-partial-recovery-test.js +222 -0
- package/_site/_test/project-remove-running-guard-test.js +79 -79
- package/_site/_test/project-store-test.js +90 -90
- package/_site/_test/project-unbind-late-read-ui-test.js +250 -0
- package/_site/_test/project-unbind-writer-guard-test.js +231 -0
- package/_site/_test/prompt-settings-test.js +115 -115
- package/_site/_test/protected-architecture-gate-test.js +122 -122
- package/_site/_test/refactor-characterization-test.js +36 -36
- package/_site/_test/registry-events-test.js +38 -38
- package/_site/_test/release-version-sync-test.js +115 -115
- package/_site/_test/requirement-binding-test.js +113 -113
- package/_site/_test/requirement-recorder-test.js +173 -173
- package/_site/_test/run-all-tests.js +173 -161
- package/_site/_test/runtime-endpoint-test.js +64 -64
- package/_site/_test/scanner-test.js +83 -83
- package/_site/_test/server-security-test.js +96 -96
- package/_site/_test/sessions-stream-test.js +93 -93
- package/_site/_test/shared-contracts-test.js +58 -58
- package/_site/_test/shared-scope-root-binding-test.js +74 -67
- package/_site/_test/simple-import-test.js +98 -98
- package/_site/_test/startup-analysis-disabled-test.js +16 -16
- package/_site/_test/storage-foundation-test.js +78 -78
- package/_site/_test/structured-logger-test.js +101 -101
- package/_site/_test/t07b-cln-005-coverage-test.js +212 -0
- package/_site/_test/team-knowledge-store-sparse-checkout-test.js +196 -196
- package/_site/_test/team-knowledge-store-test.js +132 -132
- package/_site/_test/test-server-cleanup-test.js +35 -35
- package/_site/_test/test-server-module-isolation-test.js +37 -37
- package/_site/_test/tracking-start-test.js +144 -144
- package/_site/_test/vector-storage-root-test.js +75 -75
- package/_site/_test/version-visibility-browser-probe.js +249 -0
- package/_site/_test/version-visibility-test.js +92 -0
- package/_site/_test/workbench-context-receipts-test.js +22 -22
- package/_site/_test/workbench-permission-test.js +117 -117
- package/_site/_test/zcode-capture-integration-test.js +112 -112
- package/_site/lib/ai-profile-resolver.js +78 -78
- package/_site/lib/ai-vendor-presets.js +83 -83
- package/_site/lib/ai-workspace.js +104 -104
- package/_site/lib/atomic-file.js +204 -204
- package/_site/lib/automation-config.js +140 -140
- package/_site/lib/bridge-adapter.js +260 -260
- package/_site/lib/bridge-consumer-service.js +402 -402
- package/_site/lib/capture-hook-config.js +108 -108
- package/_site/lib/claude-cli-runner.js +1599 -1599
- package/_site/lib/cli-instances.js +43 -43
- package/_site/lib/codex-context-status.js +17 -17
- package/_site/lib/codex-notify-config.js +193 -193
- package/_site/lib/commit-conversation-binder.js +247 -247
- package/_site/lib/commit-processing-ledger.js +27 -27
- package/_site/lib/commit-prompt.js +202 -202
- package/_site/lib/commit-reconciler.js +444 -444
- package/_site/lib/context-pack-builder.js +299 -299
- package/_site/lib/contracts.js +291 -291
- package/_site/lib/conversation-exclusions.js +204 -204
- package/_site/lib/conversation-query-service.js +161 -161
- package/_site/lib/conversation-store.js +387 -387
- package/_site/lib/data-dir.js +13 -13
- package/_site/lib/embedding-service.js +85 -85
- package/_site/lib/engine-connection.js +93 -93
- package/_site/lib/engine-knowledge-client.js +76 -72
- package/_site/lib/evidence-bundle.js +228 -228
- package/_site/lib/folder-picker-output.js +24 -24
- package/_site/lib/git-path.js +14 -14
- package/_site/lib/git-runner.js +62 -62
- package/_site/lib/github-team-store.js +1175 -1175
- package/_site/lib/hook-manager.js +203 -203
- package/_site/lib/index-builder.js +157 -157
- package/_site/lib/index-service.js +173 -173
- package/_site/lib/integration-auto-repair.js +77 -77
- package/_site/lib/integration-installer.js +1240 -1240
- package/_site/lib/integration-intent.js +88 -88
- package/_site/lib/integration-status-scan.js +99 -99
- package/_site/lib/integration-status-worker.js +14 -14
- package/_site/lib/kb-framework.js +191 -191
- package/_site/lib/kb-validator.js +124 -124
- package/_site/lib/knowledge-db.js +363 -363
- package/_site/lib/knowledge-promotion.js +435 -435
- package/_site/lib/knowledge-retrieval-service.js +401 -401
- package/_site/lib/knowledge-schema.js +121 -121
- package/_site/lib/knowledge-tool-runtime.js +366 -366
- package/_site/lib/live-gateway.js +78 -78
- package/_site/lib/llm-client.js +173 -173
- package/_site/lib/markdown-knowledge-indexer.js +230 -230
- package/_site/lib/model-context-windows.js +82 -82
- package/_site/lib/module-bridge.js +874 -874
- package/_site/lib/module-port-resolver.js +57 -57
- package/_site/lib/post-commit-automation.js +141 -141
- package/_site/lib/product-data.js +35 -35
- package/_site/lib/project-lifecycle-service.js +554 -554
- package/_site/lib/project-registry-store.js +129 -129
- package/_site/lib/project-store.js +268 -268
- package/_site/lib/prompt-registry.js +148 -148
- package/_site/lib/public-version-info.js +37 -0
- package/_site/lib/registry-events.js +16 -16
- package/_site/lib/requirement-adapters.js +10 -10
- package/_site/lib/requirement-binder.js +112 -112
- package/_site/lib/requirement-recorder.js +278 -278
- package/_site/lib/runtime-control.js +89 -89
- package/_site/lib/runtime-endpoint.js +160 -160
- package/_site/lib/scanner.js +298 -298
- package/_site/lib/server-app.js +1672 -1664
- package/_site/lib/settings-store.js +153 -153
- package/_site/lib/storage-layout.js +166 -166
- package/_site/lib/structured-logger.js +574 -574
- package/_site/lib/zcode-context-integration.js +60 -60
- package/_site/scripts/codex-notify-fanout.cjs +95 -95
- package/_site/scripts/folder-picker.ps1 +156 -156
- package/_site/scripts/hook-trigger.js +158 -158
- package/_site/scripts/install-module-candidates.js +69 -69
- package/_site/scripts/pack-module-candidates.js +89 -89
- package/_site/scripts/sync-product-content.js +28 -28
- package/_site/scripts/sync-release-version.js +164 -164
- package/_site/scripts/vendor-modules.js +49 -49
- package/_site/scripts/verify-module-runtime.js +50 -50
- package/_site/scripts/verify-product-runtime.js +36 -36
- package/_site/scripts/verify-retrieval-gold.js +83 -83
- package/_site/server.js +15 -15
- package/_site/start.bat +26 -26
- package/_site/stop.bat +11 -11
- package/bin/project-knowledge-integrations.js +254 -254
- package/bin/project-knowledge-kb.js +67 -67
- package/bin/project-knowledge-mcp.js +201 -201
- package/bin/project-knowledge.js +269 -170
- package/claude-prompts.json +21 -21
- package/docs/README.zh-CN.md +207 -205
- package/docs/assets/architecture.svg +181 -181
- package/docs/assets/logo.svg +49 -49
- package/docs/fresh-v5-start.md +44 -44
- package/docs/leader-glm-workbench-playbook.md +122 -122
- package/docs/project-registry-schema.md +33 -33
- package/docs/release-5.0.16-acceptance.md +176 -176
- package/docs/release-5.0.17-acceptance.md +117 -117
- package/docs/release-5.0.19-acceptance.md +39 -39
- package/docs/team-knowledge-mode-a-plan.md +73 -73
- package/docs/testing-strategy.md +33 -33
- package/module-runtime-manifest.json +66 -63
- package/package.json +113 -110
- package/plugins/project-knowledge/.claude-plugin/plugin.json +1 -1
- package/plugins/project-knowledge/.codex-plugin/plugin.json +1 -1
- package/plugins/project-knowledge/.mcp.json +1 -1
- package/templates/change.md +30 -30
- package/templates/project-readme.md +52 -52
- package/ui/index.html +3 -2
- package/ui/version-info.css +44 -0
- package/ui/version-info.js +24 -0
- 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; });
|