@sanqianx/project-knowledge 5.0.23 → 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 -1346
- 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 +70 -67
- 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,308 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
// P-NAV-VECTOR-ISOLATION-R7 / P-NAV-POSIX-CI-R9 — offline negatives for the
|
|
3
|
+
// harness premise.
|
|
4
|
+
//
|
|
5
|
+
// The R7 incident: the engine constructor's built-in vectorUrl default
|
|
6
|
+
// (http://127.0.0.1:8787) is the developer's LIVE desktop vector-hub, and a
|
|
7
|
+
// NAV-007 core-source-regression run wrote a real collection through it. The
|
|
8
|
+
// R7 fix has three legs; this test breaks each one off-line:
|
|
9
|
+
//
|
|
10
|
+
// 1. poisoned-env whitelist: ambient module URLs / provider credentials /
|
|
11
|
+
// proxies / CLI injection / real-home directory variables set on the
|
|
12
|
+
// driver are all gone after enterNavIsolation(), every isolation key
|
|
13
|
+
// lands inside the short repo-external run root, and the required
|
|
14
|
+
// directories (Chrome default-profile shape, PS cache parent) exist;
|
|
15
|
+
// 2. explicit-URL retention: values the harness sets AFTER the whitelist
|
|
16
|
+
// (its explicit lane endpoints) are retained verbatim — the whitelist
|
|
17
|
+
// deletes ambient values, not explicit ones;
|
|
18
|
+
// 3. constructor vectorUrl must be set: the real engine created WITHOUT a
|
|
19
|
+
// vectorUrl really keeps the live-port default (the hazard, proven
|
|
20
|
+
// against the real constructor), the explicit value wins when given,
|
|
21
|
+
// and the nav shell source wires the stand-in before the engine.
|
|
22
|
+
//
|
|
23
|
+
// The R9 legs (CI 40011886791: Linux-only NAV failures, Windows green):
|
|
24
|
+
//
|
|
25
|
+
// 4. POSIX socket-byte budget: the CI-failed Chrome SingletonSocket path
|
|
26
|
+
// (120 UTF-8 bytes under the descriptive R7 component names) must be
|
|
27
|
+
// rejected by the budget verdict, and the short POSIX components must
|
|
28
|
+
// hold with margin, byte-for-byte including the Chrome suffix. Pure
|
|
29
|
+
// string-contract checks — they prove the budget math everywhere, and
|
|
30
|
+
// actual Linux proof stays with the next same-SHA CI run;
|
|
31
|
+
// 5. placement-aware real-home scan: values inside the OWNED root must not
|
|
32
|
+
// be flagged as leaks merely because the hosted runner places the temp
|
|
33
|
+
// root under the real home (the CI false positive on
|
|
34
|
+
// PSModuleAnalysisCachePath), while true leaks outside the owned root
|
|
35
|
+
// are still flagged.
|
|
36
|
+
//
|
|
37
|
+
// No browser, no product instance, no network: this is a driver-level test.
|
|
38
|
+
|
|
39
|
+
const fs = require('node:fs');
|
|
40
|
+
const os = require('node:os');
|
|
41
|
+
const path = require('node:path');
|
|
42
|
+
const assert = require('node:assert/strict');
|
|
43
|
+
|
|
44
|
+
const {
|
|
45
|
+
enterNavIsolation, navIsolationReport, ISOLATION_KEYS,
|
|
46
|
+
REAL_HOME, REAL_USERPROFILE,
|
|
47
|
+
realHomeReferenceKeys, posixSocketBudgetVerdict, worstCasePosixSocketPaths,
|
|
48
|
+
POSIX_SOCKET_CHAR_LIMIT,
|
|
49
|
+
} = require('./helpers/parallel-nav-isolation-env');
|
|
50
|
+
|
|
51
|
+
const ROOT = path.resolve(__dirname, '..', '..');
|
|
52
|
+
const ENGINE_ENTRY = path.join(ROOT, '_modules', 'knowledge-engine', 'src', 'server.js');
|
|
53
|
+
const SHELL_FILE = path.join(ROOT, '_site', '_test', 'helpers', 'parallel-nav-shell.js');
|
|
54
|
+
const EVIDENCE = process.env.PK_R7_EVIDENCE_DIR ? path.resolve(process.env.PK_R7_EVIDENCE_DIR) : null;
|
|
55
|
+
|
|
56
|
+
(async () => {
|
|
57
|
+
const proof = { startedAt: new Date().toISOString() };
|
|
58
|
+
|
|
59
|
+
// --- 1. a poisoned driver environment is fully whitelisted ---------------
|
|
60
|
+
const POISON = {
|
|
61
|
+
KB_VECTOR_HUB_URL: 'http://127.0.0.1:8787',
|
|
62
|
+
KB_VECTORHUB_URL: 'http://127.0.0.1:8787',
|
|
63
|
+
KB_KNOWLEDGE_ENGINE_URL: 'http://127.0.0.1:8787',
|
|
64
|
+
KB_TERMINAL_URL: 'http://127.0.0.1:8787',
|
|
65
|
+
KB_EVENT_BRIDGE_URL: 'http://127.0.0.1:8787',
|
|
66
|
+
MINIMAX_API_KEY: 'pk-r7-poison',
|
|
67
|
+
ANTHROPIC_API_KEY: 'pk-r7-poison',
|
|
68
|
+
ANTHROPIC_BASE_URL: 'http://127.0.0.1:8787',
|
|
69
|
+
NODE_OPTIONS: '--require pk-r7-poison.js',
|
|
70
|
+
NODE_PATH: 'C:\\pk-r7-poison',
|
|
71
|
+
HTTP_PROXY: 'http://127.0.0.1:8787',
|
|
72
|
+
CLAUDE_CODE_OAUTH_TOKEN: 'pk-r7-poison',
|
|
73
|
+
HOME: REAL_HOME,
|
|
74
|
+
USERPROFILE: REAL_USERPROFILE,
|
|
75
|
+
CODEX_HOME: path.join(REAL_HOME, '.codex'),
|
|
76
|
+
CLAUDE_CONFIG_DIR: path.join(REAL_HOME, '.claude'),
|
|
77
|
+
TEMP: path.join(REAL_HOME, 'AppData', 'Local', 'Temp'),
|
|
78
|
+
KB_DATA_DIR: path.join(REAL_HOME, '.project-knowledge'),
|
|
79
|
+
KB_KNOWLEDGE_DATA_DIR: path.join(REAL_HOME, '.project-knowledge-knowledge'),
|
|
80
|
+
};
|
|
81
|
+
const before = { ...process.env };
|
|
82
|
+
Object.assign(process.env, POISON);
|
|
83
|
+
try {
|
|
84
|
+
const isolation = enterNavIsolation({ tag: 'isolation-negative' });
|
|
85
|
+
const report = navIsolationReport(process.env, isolation);
|
|
86
|
+
|
|
87
|
+
// Directory keys are OVERWRITTEN to isolated values, ambient keys are
|
|
88
|
+
// DELETED outright — the poison must be gone either way.
|
|
89
|
+
for (const [key, poisonValue] of Object.entries(POISON)) {
|
|
90
|
+
if (ISOLATION_KEYS.includes(key)) {
|
|
91
|
+
assert.ok(key in process.env, `isolation key ${key} must be set`);
|
|
92
|
+
assert.notEqual(process.env[key], poisonValue, `poison value of ${key} must not survive the whitelist`);
|
|
93
|
+
} else {
|
|
94
|
+
assert.ok(!(key in process.env), `poison ${key} must not survive the whitelist`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
assert.ok(report.noAmbientSurvives, `ambient deletes all hold: ${JSON.stringify(report.ambientDeleted)}`);
|
|
98
|
+
assert.ok(report.allIsolationKeysInsideRoot, `every isolation key points inside the run root: ${JSON.stringify(report.isolationKeys)}`);
|
|
99
|
+
assert.deepEqual(report.referencesRealHome, [], 'no env value may reference the real home (outside the owned root; placement-aware since R9)');
|
|
100
|
+
assert.deepEqual(report.redirectionFailures, [],
|
|
101
|
+
'every isolation key that pointed at the real home before the whitelist must be redirected into the owned root');
|
|
102
|
+
assert.ok(report.chromeDefaultProfileDirExists, 'the Chrome default-profile shape exists under the isolated USERPROFILE');
|
|
103
|
+
assert.ok(report.psCacheParentExists, 'the PS module-analysis cache parent directory exists');
|
|
104
|
+
assert.deepEqual(report.osWhitelistHeld, [], `nothing outside the OS whitelist and the isolation map survives: ${JSON.stringify(report.osWhitelistHeld)}`);
|
|
105
|
+
// SystemRoot exists only on Windows; POSIX's OS floor is PATH alone.
|
|
106
|
+
const osCritical = process.platform === 'win32' ? ['SystemRoot', 'PATH'] : ['PATH'];
|
|
107
|
+
for (const key of osCritical) assert.ok(key in process.env, `OS-critical variable ${key} survives the whitelist (${process.platform})`);
|
|
108
|
+
assert.notEqual(process.env.HOME, REAL_HOME, 'HOME must not be the real home');
|
|
109
|
+
proof.poisonedEnvWhitelisted = {
|
|
110
|
+
poisonKeys: Object.keys(POISON).length,
|
|
111
|
+
isolationKeysInsideRoot: report.isolationKeys,
|
|
112
|
+
chromeDefaultProfileDir: isolation.layout.chromeDefaultProfileDir,
|
|
113
|
+
psCachePath: isolation.layout.psCachePath,
|
|
114
|
+
runRoot: isolation.root,
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
// --- 2. explicit lane endpoints set AFTER the whitelist are retained ---
|
|
118
|
+
const LANE_URL = 'http://127.0.0.1:9';
|
|
119
|
+
process.env.KB_VECTORHUB_URL = LANE_URL;
|
|
120
|
+
process.env.KB_KNOWLEDGE_ENGINE_URL = LANE_URL;
|
|
121
|
+
process.env.PK_R7_EXPLICIT_CANARY = 'explicit';
|
|
122
|
+
assert.equal(process.env.KB_VECTORHUB_URL, LANE_URL, 'an explicit lane endpoint must be retained, not the poisoned 8787');
|
|
123
|
+
assert.equal(process.env.KB_KNOWLEDGE_ENGINE_URL, LANE_URL, 'an explicit engine endpoint must be retained');
|
|
124
|
+
proof.explicitUrlRetention = { KB_VECTORHUB_URL: process.env.KB_VECTORHUB_URL, KB_KNOWLEDGE_ENGINE_URL: process.env.KB_KNOWLEDGE_ENGINE_URL };
|
|
125
|
+
|
|
126
|
+
isolation.restore();
|
|
127
|
+
// restore() must faithfully put back exactly what enterNavIsolation saw —
|
|
128
|
+
// which was the POISONED environment, not the pristine one. Compare by key
|
|
129
|
+
// names only: printing values would echo live secrets from the real env.
|
|
130
|
+
{
|
|
131
|
+
const expected = { ...before, ...POISON };
|
|
132
|
+
const actualKeys = new Set(Object.keys(process.env));
|
|
133
|
+
const onlyActual = [...actualKeys].filter(key => !(key in expected));
|
|
134
|
+
const onlyExpected = Object.keys(expected).filter(key => !actualKeys.has(key));
|
|
135
|
+
const changed = [...actualKeys].filter(key => key in expected && process.env[key] !== expected[key]);
|
|
136
|
+
assert.deepEqual({ onlyActual, onlyExpected, changedKeys: changed }, { onlyActual: [], onlyExpected: [], changedKeys: [] },
|
|
137
|
+
'restore() must put the entered (poisoned-input) environment back exactly');
|
|
138
|
+
}
|
|
139
|
+
assert.equal(process.env.KB_VECTORHUB_URL, POISON.KB_VECTORHUB_URL, 'restore puts the pre-enter value back');
|
|
140
|
+
assert.ok(!('PK_R7_EXPLICIT_CANARY' in process.env), 'keys added during isolation must not survive restore');
|
|
141
|
+
assert.ok(fs.existsSync(path.dirname(isolation.root)), 'the stable parent temp survives a serial run (no dangling os.tmpdir)');
|
|
142
|
+
proof.restoreFaithful = { canaryGone: true, stableParentSurvives: true };
|
|
143
|
+
} finally {
|
|
144
|
+
for (const key of Object.keys(POISON)) {
|
|
145
|
+
if (!(key in before)) delete process.env[key];
|
|
146
|
+
else process.env[key] = before[key];
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// --- 3. constructor vectorUrl must be set (the default IS the live port) --
|
|
151
|
+
const iso2 = enterNavIsolation({ tag: 'isolation-negative-engine' });
|
|
152
|
+
let engines = [];
|
|
153
|
+
try {
|
|
154
|
+
const { createEngineServer } = require(ENGINE_ENTRY);
|
|
155
|
+
const dirMissing = fs.mkdtempSync(path.join(os.tmpdir(), 'pk-nav-r7-engine-default-'));
|
|
156
|
+
const missing = createEngineServer({ dataDir: dirMissing, runtimeToken: 'pk-r7', debug: false, consume: false });
|
|
157
|
+
engines.push(missing);
|
|
158
|
+
assert.equal(missing.coordinator.vectorUrl, 'http://127.0.0.1:8787',
|
|
159
|
+
'an engine created without vectorUrl keeps the LIVE-port default — the exact incident premise');
|
|
160
|
+
|
|
161
|
+
const dirExplicit = fs.mkdtempSync(path.join(os.tmpdir(), 'pk-nav-r7-engine-explicit-'));
|
|
162
|
+
const explicit = createEngineServer({ dataDir: dirExplicit, runtimeToken: 'pk-r7', debug: false, consume: false, vectorUrl: 'http://127.0.0.1:9' });
|
|
163
|
+
engines.push(explicit);
|
|
164
|
+
assert.equal(explicit.coordinator.vectorUrl, 'http://127.0.0.1:9', 'an explicit vectorUrl wins over the default');
|
|
165
|
+
|
|
166
|
+
const shellSource = fs.readFileSync(SHELL_FILE, 'utf8');
|
|
167
|
+
assert.match(shellSource, /vectorUrl:\s*moduleUi\.url/, 'the nav shell must pass the stand-in URL to the engine constructor');
|
|
168
|
+
assert.match(shellSource, /bridgeUrl:\s*moduleUi\.url/, 'the nav shell must also override the live BridgeClient default');
|
|
169
|
+
assert.ok(shellSource.indexOf('await moduleUi.start()') < shellSource.indexOf('createEngineServer('),
|
|
170
|
+
'the vector stand-in must start before the engine is created');
|
|
171
|
+
assert.match(shellSource, /engine\.coordinator\.vectorUrl,\s*moduleUi\.url/, 'the harness asserts the live vectorUrl at every start');
|
|
172
|
+
proof.constructorVectorUrl = {
|
|
173
|
+
defaultWithoutOption: missing.coordinator.vectorUrl,
|
|
174
|
+
withExplicitOption: explicit.coordinator.vectorUrl,
|
|
175
|
+
shellWiresStandInBeforeEngine: true,
|
|
176
|
+
};
|
|
177
|
+
} finally {
|
|
178
|
+
for (const engine of engines) await engine.close().catch(() => {});
|
|
179
|
+
iso2.restore();
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// --- 4. POSIX socket-byte budget (offline string contract; CI stays the
|
|
183
|
+
// Linux proof of record — this leg does not pretend Windows proves
|
|
184
|
+
// Linux, it proves the byte math is right everywhere) ---------------
|
|
185
|
+
{
|
|
186
|
+
// The exact CI 40011886791 failure shape: descriptive R7 components under
|
|
187
|
+
// RUNNER_TEMP, Chrome's suffix rand observed at 6 chars.
|
|
188
|
+
const ciFailedRoot = '/home/runner/work/_temp/pk-nav-r7-9399-ChZLZ5/pk-parallel-nav-nav004-pUkYfU';
|
|
189
|
+
const ciFailedSocket = `${ciFailedRoot}/temp/com.google.Chrome.90mVLb/SingletonSocket`;
|
|
190
|
+
assert.equal(Buffer.byteLength(ciFailedSocket, 'utf8'), 121,
|
|
191
|
+
'the CI-failed SingletonSocket path is pinned at 121 UTF-8 bytes — 14 over the 107-char sun_path ceiling');
|
|
192
|
+
const failed = posixSocketBudgetVerdict(ciFailedRoot);
|
|
193
|
+
assert.ok(!failed.ok, 'the CI-failed root must be rejected by the POSIX socket budget');
|
|
194
|
+
assert.ok(failed.chromeSocketBytes > POSIX_SOCKET_CHAR_LIMIT,
|
|
195
|
+
`rejected with the computed worst case (${failed.chromeSocketBytes} bytes incl. the 12-char Chrome rand bound)`);
|
|
196
|
+
|
|
197
|
+
// The R9 short components under the SAME runner temp: pkn<pid36><rand6>/
|
|
198
|
+
// n<rand6>, with the 't' temp layout. pid 9399 → base36 '793'.
|
|
199
|
+
const shortRoot = '/home/runner/work/_temp/pkn793abcdef/ghijkl';
|
|
200
|
+
const worst = worstCasePosixSocketPaths(shortRoot);
|
|
201
|
+
assert.equal(worst.chromeSingletonSocket, `${shortRoot}/t/com.google.Chrome.xxxxxxxxxxxx/SingletonSocket`,
|
|
202
|
+
'the worst-case Chrome socket includes the full suffix, budgeted at the 12-char rand bound');
|
|
203
|
+
assert.equal(worst.productRuntimeControlSock, `${shortRoot}/data/runtime-control.sock`,
|
|
204
|
+
'the product runtime-control socket rides the same root (spawnServer dataDir = <fixture>/data)');
|
|
205
|
+
const held = posixSocketBudgetVerdict(shortRoot);
|
|
206
|
+
assert.ok(held.ok, `the short-component root must hold the budget: ${JSON.stringify({ chrome: held.chromeSocketBytes, control: held.controlSocketBytes })}`);
|
|
207
|
+
assert.ok(POSIX_SOCKET_CHAR_LIMIT - held.chromeSocketBytes >= 10,
|
|
208
|
+
`the short-component root holds with margin (limit ${POSIX_SOCKET_CHAR_LIMIT}, chrome worst case ${held.chromeSocketBytes})`);
|
|
209
|
+
|
|
210
|
+
// Boundary: exactly at the limit passes, one byte over fails. The tail is
|
|
211
|
+
// 49 ASCII bytes, so a 58-byte root lands exactly at the 107 ceiling.
|
|
212
|
+
assert.equal(worstCasePosixSocketPaths('/tmp').chromeSingletonSocket.length - '/tmp'.length, 49,
|
|
213
|
+
'the Chrome socket tail is pinned at 49 bytes (12-char rand bound)');
|
|
214
|
+
assert.ok(posixSocketBudgetVerdict('/tmp/' + 'a'.repeat(53)).ok, 'a root landing exactly at the byte ceiling is accepted');
|
|
215
|
+
assert.ok(!posixSocketBudgetVerdict('/tmp/' + 'a'.repeat(54)).ok, 'one byte over the ceiling is rejected');
|
|
216
|
+
proof.posixSocketBudget = {
|
|
217
|
+
ciFailedSocketBytes: Buffer.byteLength(ciFailedSocket, 'utf8'),
|
|
218
|
+
ciFailedRootRejected: true,
|
|
219
|
+
shortRoot,
|
|
220
|
+
shortRootVerdict: { chromeSocketBytes: held.chromeSocketBytes, controlSocketBytes: held.controlSocketBytes, limit: held.limit },
|
|
221
|
+
boundaryAcceptedBytes: posixSocketBudgetVerdict('/tmp/' + 'a'.repeat(53)).chromeSocketBytes,
|
|
222
|
+
boundaryRejectedBytes: posixSocketBudgetVerdict('/tmp/' + 'a'.repeat(54)).chromeSocketBytes,
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
// Byte, not char, accounting: 'π' is one char but two UTF-8 bytes, so the
|
|
226
|
+
// verdict must exceed the character count by exactly that delta.
|
|
227
|
+
const multibyte = posixSocketBudgetVerdict('/tmp/π');
|
|
228
|
+
assert.equal(multibyte.chromeSocketBytes, multibyte.paths.chromeSingletonSocket.length + 1,
|
|
229
|
+
'the budget counts UTF-8 bytes, not chars');
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// --- 5. placement-aware real-home scan (the CI false positive, offline) ---
|
|
233
|
+
{
|
|
234
|
+
// Hosted-runner placement: the owned temp root legitimately lives UNDER
|
|
235
|
+
// the real home. Owned values must NOT be flagged (the CI failure flagged
|
|
236
|
+
// PSModuleAnalysisCachePath exactly this way).
|
|
237
|
+
const ownedRoot = '/home/runner/work/_temp/pkn793abcdef/ghijkl';
|
|
238
|
+
const runnerHome = '/home/runner';
|
|
239
|
+
const ownedEnv = {
|
|
240
|
+
HOME: `${ownedRoot}/home`,
|
|
241
|
+
USERPROFILE: `${ownedRoot}/home`,
|
|
242
|
+
TEMP: `${ownedRoot}/t`,
|
|
243
|
+
PSModuleAnalysisCachePath: `${ownedRoot}/ps-module-analysis-cache.bin`,
|
|
244
|
+
CLAUDE_CONFIG_DIR: `${ownedRoot}/claude-config`,
|
|
245
|
+
CODEX_HOME: `${ownedRoot}/codex-home`,
|
|
246
|
+
};
|
|
247
|
+
assert.deepEqual(realHomeReferenceKeys(ownedEnv, { root: ownedRoot, realHome: runnerHome, realUserProfile: runnerHome }), [],
|
|
248
|
+
'owned values under a real-home-prefixed temp root are placement, not leaks (the R9 CI false positive)');
|
|
249
|
+
|
|
250
|
+
// True leaks — outside the owned root while referencing the real home —
|
|
251
|
+
// must still be flagged, both as canonical paths and as bare mentions.
|
|
252
|
+
const leaking = {
|
|
253
|
+
...ownedEnv,
|
|
254
|
+
CODEX_HOME: '/home/runner/.codex',
|
|
255
|
+
KB_DATA_DIR: '/home/runner/.project-knowledge',
|
|
256
|
+
RELEASE_NOTE: 'staged from /home/runner/real-secret.txt',
|
|
257
|
+
};
|
|
258
|
+
assert.deepEqual(
|
|
259
|
+
realHomeReferenceKeys(leaking, { root: ownedRoot, realHome: runnerHome, realUserProfile: runnerHome }).sort(),
|
|
260
|
+
['CODEX_HOME', 'KB_DATA_DIR', 'RELEASE_NOTE'],
|
|
261
|
+
'leaks outside the owned root stay flagged even when the owned root sits under the real home',
|
|
262
|
+
);
|
|
263
|
+
|
|
264
|
+
// R7: numeric and other NON-PATH values must never be classified as path
|
|
265
|
+
// leaks. On the Linux runners the test CWD is /home/runner/work/... —
|
|
266
|
+
// under the real home — so the unguarded path.resolve('0') of the R9
|
|
267
|
+
// classifier canonically landed inside /home/runner and flagged
|
|
268
|
+
// KB_MODULES_AUTOSTART at nav-isolation-test line 99. Path-shape gating
|
|
269
|
+
// removes the phantom; every real leak above stays flagged.
|
|
270
|
+
const flagsEnv = {
|
|
271
|
+
...ownedEnv,
|
|
272
|
+
KB_MODULES_AUTOSTART: '0',
|
|
273
|
+
KB_MODULES_REGISTER: '0',
|
|
274
|
+
KB_EMBEDDING_FAKE: '1',
|
|
275
|
+
FORCE_COLOR: '0',
|
|
276
|
+
CI: 'true',
|
|
277
|
+
KB_TERMINAL_URL: 'http://127.0.0.1:9',
|
|
278
|
+
KB_TERMINAL_COMMAND: '',
|
|
279
|
+
};
|
|
280
|
+
assert.deepEqual(realHomeReferenceKeys(flagsEnv, { root: ownedRoot, realHome: runnerHome, realUserProfile: runnerHome }), [],
|
|
281
|
+
'non-path values (numeric flags, booleans, dead URLs, empty strings) are never path leaks even when the CWD sits under the real home');
|
|
282
|
+
const flagsWithRealLeak = { ...flagsEnv, KB_DATA_DIR: '/home/runner/.project-knowledge' };
|
|
283
|
+
assert.deepEqual(
|
|
284
|
+
realHomeReferenceKeys(flagsWithRealLeak, { root: ownedRoot, realHome: runnerHome, realUserProfile: runnerHome }),
|
|
285
|
+
['KB_DATA_DIR'],
|
|
286
|
+
'the path-shape gate pardons flags without blinding the scan to a real home leak in the same environment',
|
|
287
|
+
);
|
|
288
|
+
proof.placementAwareRealHomeScan = {
|
|
289
|
+
ownedRootUnderRealHome: ownedRoot,
|
|
290
|
+
ownedValuesFlagged: 0,
|
|
291
|
+
trueLeaksFlagged: ['CODEX_HOME', 'KB_DATA_DIR', 'RELEASE_NOTE'],
|
|
292
|
+
nonPathFlagKeysUnflagged: Object.keys(flagsEnv).filter(key => !Object.keys(ownedEnv).includes(key)),
|
|
293
|
+
ciFalsePositiveShape: 'PSModuleAnalysisCachePath under the owned RUNNER_TEMP no longer fails isolation-test line 82',
|
|
294
|
+
r7CiFalsePositiveShape: "numeric flag '0' no longer resolves against the CWD into a phantom home leak (KB_MODULES_AUTOSTART at line 99)",
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
proof.finishedAt = new Date().toISOString();
|
|
299
|
+
proof.verdict = 'PASS — all three R7 negatives hold (poisoned env whitelisted with redirection proven, explicit URLs retained, constructor default proven live-port and always overridden by the shell) and both R9 contracts hold (POSIX socket-byte budget rejects the CI-failed root and holds with margin for the short components; the real-home scan is placement-aware without losing true-leak detection)';
|
|
300
|
+
if (EVIDENCE) {
|
|
301
|
+
fs.mkdirSync(EVIDENCE, { recursive: true });
|
|
302
|
+
fs.writeFileSync(path.join(EVIDENCE, 'isolation-negatives.json'), JSON.stringify(proof, null, 2) + '\n', 'utf8');
|
|
303
|
+
}
|
|
304
|
+
console.log(JSON.stringify(proof, null, 2));
|
|
305
|
+
})().catch(error => {
|
|
306
|
+
console.error(String(error && error.stack || error));
|
|
307
|
+
process.exitCode = 1;
|
|
308
|
+
});
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
// P-NAV-VECTOR-ISOLATION-R7 — the live incident path through the fixed wiring.
|
|
3
|
+
//
|
|
4
|
+
// The 2026-10-23T18:00:54Z overwrite of the real collection
|
|
5
|
+
// scope-brain-brain-default happened exactly here: a NAV harness run let the
|
|
6
|
+
// real engine keep its constructor-default vectorUrl (the LIVE desktop hub on
|
|
7
|
+
// 127.0.0.1:8787), the product registered its brain scope at boot, and the
|
|
8
|
+
// engine's syncSharedIndexes wrote the collection at that default.
|
|
9
|
+
//
|
|
10
|
+
// This probe replays the smallest faithful version: boot the REAL product and
|
|
11
|
+
// the REAL engine through the REAL startHarness wiring. The product registers
|
|
12
|
+
// the brain-default shared scope by itself (an explicit rebind is refused
|
|
13
|
+
// with IMMUTABLE_FIELD, which is itself correct engine behaviour), the
|
|
14
|
+
// engine's syncSharedIndexes runs for real, and every scope-index call must
|
|
15
|
+
// land on the lane stand-in with sourceDir inside the fixture root. The
|
|
16
|
+
// vector module is NOT the subject under test — it is the substituted part
|
|
17
|
+
// (see parallel-nav-module-ui.js); the engine, the routes and the routing
|
|
18
|
+
// decision stay real.
|
|
19
|
+
|
|
20
|
+
const fs = require('node:fs');
|
|
21
|
+
const path = require('node:path');
|
|
22
|
+
const assert = require('node:assert/strict');
|
|
23
|
+
|
|
24
|
+
const { startHarness } = require('./helpers/parallel-nav-shell');
|
|
25
|
+
const { waitFor } = require('./helpers/cdp-browser');
|
|
26
|
+
|
|
27
|
+
const EVIDENCE = process.env.PK_R7_EVIDENCE_DIR ? path.resolve(process.env.PK_R7_EVIDENCE_DIR) : null;
|
|
28
|
+
|
|
29
|
+
(async () => {
|
|
30
|
+
const proof = { startedAt: new Date().toISOString() };
|
|
31
|
+
const harness = await startHarness({ tag: 'nav-vector-path' });
|
|
32
|
+
try {
|
|
33
|
+
// The wiring assert already ran inside startHarness; hold the live values
|
|
34
|
+
// as evidence and re-state the two invariants this lane exists for.
|
|
35
|
+
assert.equal(harness.engine.coordinator.vectorUrl, harness.moduleUi.url,
|
|
36
|
+
'the live engine must hold the stand-in URL');
|
|
37
|
+
assert.notEqual(harness.engine.coordinator.vectorUrl, 'http://127.0.0.1:8787',
|
|
38
|
+
'the live-port default must never be the engine vectorUrl');
|
|
39
|
+
assert.equal(harness.engine.coordinator.bridge.url, harness.moduleUi.url,
|
|
40
|
+
'the real engine BridgeClient must also point at the owned fixture');
|
|
41
|
+
assert.deepEqual(await harness.engine.coordinator.bridge.listJournals(), [],
|
|
42
|
+
'a real bridge poll must receive the owned fixture empty journal contract');
|
|
43
|
+
assert.ok(harness.moduleUi.state.requests.some(entry => entry.path === '/api/journals'),
|
|
44
|
+
'the owned fixture must record the engine BridgeClient request');
|
|
45
|
+
|
|
46
|
+
// The product registers the brain-default shared scope by itself during
|
|
47
|
+
// boot and the engine indexes it for real — wait for that flow to reach
|
|
48
|
+
// the stand-in (this is the exact flow that wrote the real collection).
|
|
49
|
+
await waitFor(async () => harness.moduleUi.vectorImports().length > 0,
|
|
50
|
+
'the stand-in receiving the boot-time scope-index call', 30000);
|
|
51
|
+
|
|
52
|
+
const snapshot = await harness.engineApi('GET', '/api/snapshot');
|
|
53
|
+
assert.equal(snapshot.status, 200, `the engine snapshot must answer: ${JSON.stringify(snapshot.body)}`);
|
|
54
|
+
const brainScope = (snapshot.body.sharedScopes || []).find(scope => scope.id === 'brain-default');
|
|
55
|
+
assert.ok(brainScope, 'the product really registered the brain-default shared scope');
|
|
56
|
+
assert.ok(brainScope.knowledgePath.startsWith(harness.fixture + path.sep),
|
|
57
|
+
`the registered brain scope must live inside the fixture root: ${brainScope.knowledgePath}`);
|
|
58
|
+
|
|
59
|
+
const isolation = harness.assertVectorIsolation();
|
|
60
|
+
const incidentImports = harness.moduleUi.vectorImports().filter(entry => entry.body && entry.body.projectName === 'scope-brain-brain-default');
|
|
61
|
+
assert.ok(incidentImports.length >= 1, 'the incident collection name is built and routed by the real engine');
|
|
62
|
+
for (const entry of incidentImports) {
|
|
63
|
+
assert.equal(entry.body.sourceDir, brainScope.knowledgePath,
|
|
64
|
+
'the incident-path sourceDir is the product-registered scope, not a probe value');
|
|
65
|
+
assert.ok(entry.body.sourceDir.startsWith(harness.fixture + path.sep),
|
|
66
|
+
`the incident-path sourceDir must stay inside the fixture root: ${entry.body.sourceDir}`);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
proof.engineVectorUrl = harness.engine.coordinator.vectorUrl;
|
|
70
|
+
proof.engineBridgeUrl = harness.engine.coordinator.bridge.url;
|
|
71
|
+
proof.standInUrl = harness.moduleUi.url;
|
|
72
|
+
proof.fixtureRoot = harness.fixture;
|
|
73
|
+
proof.registeredBrainScope = brainScope.knowledgePath;
|
|
74
|
+
proof.incidentPathCalls = incidentImports.map(entry => ({ route: entry.path, body: entry.body }));
|
|
75
|
+
proof.containment = isolation;
|
|
76
|
+
proof.verdict = 'PASS — the real product registered the brain-default scope on the real engine, and the engine routed the real incident path (scope-brain-brain-default index) to the lane stand-in with every sourceDir inside the fixture root';
|
|
77
|
+
} finally {
|
|
78
|
+
await harness.cleanup();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
proof.finishedAt = new Date().toISOString();
|
|
82
|
+
if (EVIDENCE) {
|
|
83
|
+
fs.mkdirSync(EVIDENCE, { recursive: true });
|
|
84
|
+
fs.writeFileSync(path.join(EVIDENCE, 'vector-path.json'), JSON.stringify(proof, null, 2) + '\n', 'utf8');
|
|
85
|
+
}
|
|
86
|
+
console.log(JSON.stringify(proof, null, 2));
|
|
87
|
+
})().catch(error => {
|
|
88
|
+
console.error(String(error && error.stack || error));
|
|
89
|
+
process.exitCode = 1;
|
|
90
|
+
});
|