@productbrain/cli 0.1.0-beta.978 → 0.1.0-beta.9791
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/README.md +11 -2
- package/dist/__tests__/adapters.test.js +79 -53
- package/dist/__tests__/adapters.test.js.map +1 -1
- package/dist/__tests__/adminConfig.test.d.ts +18 -0
- package/dist/__tests__/adminConfig.test.d.ts.map +1 -0
- package/dist/__tests__/adminConfig.test.js +221 -0
- package/dist/__tests__/adminConfig.test.js.map +1 -0
- package/dist/__tests__/batch-transformations.test.js +2 -26
- package/dist/__tests__/batch-transformations.test.js.map +1 -1
- package/dist/__tests__/capture-receipt-coaching.test.d.ts +2 -0
- package/dist/__tests__/capture-receipt-coaching.test.d.ts.map +1 -0
- package/dist/__tests__/capture-receipt-coaching.test.js +109 -0
- package/dist/__tests__/capture-receipt-coaching.test.js.map +1 -0
- package/dist/__tests__/capture-receipt-role-hint.test.d.ts +2 -0
- package/dist/__tests__/capture-receipt-role-hint.test.d.ts.map +1 -0
- package/dist/__tests__/capture-receipt-role-hint.test.js +66 -0
- package/dist/__tests__/capture-receipt-role-hint.test.js.map +1 -0
- package/dist/__tests__/capture-receipt-spine-floor.test.d.ts +2 -0
- package/dist/__tests__/capture-receipt-spine-floor.test.d.ts.map +1 -0
- package/dist/__tests__/capture-receipt-spine-floor.test.js +45 -0
- package/dist/__tests__/capture-receipt-spine-floor.test.js.map +1 -0
- package/dist/__tests__/capture.test.js +1337 -181
- package/dist/__tests__/capture.test.js.map +1 -1
- package/dist/__tests__/client-binding-guard.test.d.ts +2 -0
- package/dist/__tests__/client-binding-guard.test.d.ts.map +1 -0
- package/dist/__tests__/client-binding-guard.test.js +84 -0
- package/dist/__tests__/client-binding-guard.test.js.map +1 -0
- package/dist/__tests__/coaching-mirror-drift.test.d.ts +2 -0
- package/dist/__tests__/coaching-mirror-drift.test.d.ts.map +1 -0
- package/dist/__tests__/coaching-mirror-drift.test.js +47 -0
- package/dist/__tests__/coaching-mirror-drift.test.js.map +1 -0
- package/dist/__tests__/codex-prep-parity.test.d.ts +2 -0
- package/dist/__tests__/codex-prep-parity.test.d.ts.map +1 -0
- package/dist/__tests__/codex-prep-parity.test.js +84 -0
- package/dist/__tests__/codex-prep-parity.test.js.map +1 -0
- package/dist/__tests__/collection-registry-seed-drift.test.d.ts +2 -0
- package/dist/__tests__/collection-registry-seed-drift.test.d.ts.map +1 -0
- package/dist/__tests__/collection-registry-seed-drift.test.js +102 -0
- package/dist/__tests__/collection-registry-seed-drift.test.js.map +1 -0
- package/dist/__tests__/config-prod-fallthrough.test.d.ts +2 -0
- package/dist/__tests__/config-prod-fallthrough.test.d.ts.map +1 -0
- package/dist/__tests__/config-prod-fallthrough.test.js +93 -0
- package/dist/__tests__/config-prod-fallthrough.test.js.map +1 -0
- package/dist/__tests__/config.test.js +559 -40
- package/dist/__tests__/config.test.js.map +1 -1
- package/dist/__tests__/constellation.test.js +26 -14
- package/dist/__tests__/constellation.test.js.map +1 -1
- package/dist/__tests__/conversation.test.d.ts +2 -0
- package/dist/__tests__/conversation.test.d.ts.map +1 -0
- package/dist/__tests__/conversation.test.js +113 -0
- package/dist/__tests__/conversation.test.js.map +1 -0
- package/dist/__tests__/entry-formatter.test.d.ts +2 -0
- package/dist/__tests__/entry-formatter.test.d.ts.map +1 -0
- package/dist/__tests__/entry-formatter.test.js +159 -0
- package/dist/__tests__/entry-formatter.test.js.map +1 -0
- package/dist/__tests__/entry-preflight.test.d.ts +2 -0
- package/dist/__tests__/entry-preflight.test.d.ts.map +1 -0
- package/dist/__tests__/entry-preflight.test.js +58 -0
- package/dist/__tests__/entry-preflight.test.js.map +1 -0
- package/dist/__tests__/entryAccept-batch.test.d.ts +2 -0
- package/dist/__tests__/entryAccept-batch.test.d.ts.map +1 -0
- package/dist/__tests__/entryAccept-batch.test.js +305 -0
- package/dist/__tests__/entryAccept-batch.test.js.map +1 -0
- package/dist/__tests__/entryAccept.test.d.ts +2 -0
- package/dist/__tests__/entryAccept.test.d.ts.map +1 -0
- package/dist/__tests__/entryAccept.test.js +506 -0
- package/dist/__tests__/entryAccept.test.js.map +1 -0
- package/dist/__tests__/entryDiscardResolve.test.d.ts +2 -0
- package/dist/__tests__/entryDiscardResolve.test.d.ts.map +1 -0
- package/dist/__tests__/entryDiscardResolve.test.js +28 -0
- package/dist/__tests__/entryDiscardResolve.test.js.map +1 -0
- package/dist/__tests__/entryOwn.test.d.ts +2 -0
- package/dist/__tests__/entryOwn.test.d.ts.map +1 -0
- package/dist/__tests__/entryOwn.test.js +50 -0
- package/dist/__tests__/entryOwn.test.js.map +1 -0
- package/dist/__tests__/entryTick.test.d.ts +2 -0
- package/dist/__tests__/entryTick.test.d.ts.map +1 -0
- package/dist/__tests__/entryTick.test.js +40 -0
- package/dist/__tests__/entryTick.test.js.map +1 -0
- package/dist/__tests__/envelope-contract.test.js +2 -0
- package/dist/__tests__/envelope-contract.test.js.map +1 -1
- package/dist/__tests__/errors.test.js +41 -0
- package/dist/__tests__/errors.test.js.map +1 -1
- package/dist/__tests__/fields.test.js +14 -3
- package/dist/__tests__/fields.test.js.map +1 -1
- package/dist/__tests__/gateway-dry-run-timeout.test.d.ts +2 -0
- package/dist/__tests__/gateway-dry-run-timeout.test.d.ts.map +1 -0
- package/dist/__tests__/gateway-dry-run-timeout.test.js +70 -0
- package/dist/__tests__/gateway-dry-run-timeout.test.js.map +1 -0
- package/dist/__tests__/gateway-timeout-body-phase.test.d.ts +2 -0
- package/dist/__tests__/gateway-timeout-body-phase.test.d.ts.map +1 -0
- package/dist/__tests__/gateway-timeout-body-phase.test.js +121 -0
- package/dist/__tests__/gateway-timeout-body-phase.test.js.map +1 -0
- package/dist/__tests__/handshake-augment.test.js +4 -20
- package/dist/__tests__/handshake-augment.test.js.map +1 -1
- package/dist/__tests__/handshake-dormancy.test.js +10 -193
- package/dist/__tests__/handshake-dormancy.test.js.map +1 -1
- package/dist/__tests__/handshake-formatter.test.js +44 -0
- package/dist/__tests__/handshake-formatter.test.js.map +1 -1
- package/dist/__tests__/handshake-preview.test.js +271 -612
- package/dist/__tests__/handshake-preview.test.js.map +1 -1
- package/dist/__tests__/handshake-session-threading.test.d.ts +2 -0
- package/dist/__tests__/handshake-session-threading.test.d.ts.map +1 -0
- package/dist/__tests__/handshake-session-threading.test.js +185 -0
- package/dist/__tests__/handshake-session-threading.test.js.map +1 -0
- package/dist/__tests__/handshake.e2e.test.js +7 -1033
- package/dist/__tests__/handshake.e2e.test.js.map +1 -1
- package/dist/__tests__/handshake.test.js +523 -308
- package/dist/__tests__/handshake.test.js.map +1 -1
- package/dist/__tests__/health-gap-kinds-drift.test.d.ts +2 -0
- package/dist/__tests__/health-gap-kinds-drift.test.d.ts.map +1 -0
- package/dist/__tests__/health-gap-kinds-drift.test.js +43 -0
- package/dist/__tests__/health-gap-kinds-drift.test.js.map +1 -0
- package/dist/__tests__/hook-intents.test.js +3 -3
- package/dist/__tests__/hook-intents.test.js.map +1 -1
- package/dist/__tests__/ingest.test.js +9 -0
- package/dist/__tests__/ingest.test.js.map +1 -1
- package/dist/__tests__/init.test.js +51 -14
- package/dist/__tests__/init.test.js.map +1 -1
- package/dist/__tests__/kernel-value-sets-drift.test.d.ts +2 -0
- package/dist/__tests__/kernel-value-sets-drift.test.d.ts.map +1 -0
- package/dist/__tests__/kernel-value-sets-drift.test.js +46 -0
- package/dist/__tests__/kernel-value-sets-drift.test.js.map +1 -0
- package/dist/__tests__/kernel-value-sets-generator.test.d.ts +2 -0
- package/dist/__tests__/kernel-value-sets-generator.test.d.ts.map +1 -0
- package/dist/__tests__/kernel-value-sets-generator.test.js +108 -0
- package/dist/__tests__/kernel-value-sets-generator.test.js.map +1 -0
- package/dist/__tests__/login.test.js +18 -1
- package/dist/__tests__/login.test.js.map +1 -1
- package/dist/__tests__/method-registry.integration.test.js +2 -3
- package/dist/__tests__/method-registry.integration.test.js.map +1 -1
- package/dist/__tests__/method-registry.test.d.ts +6 -8
- package/dist/__tests__/method-registry.test.d.ts.map +1 -1
- package/dist/__tests__/method-registry.test.js +22 -70
- package/dist/__tests__/method-registry.test.js.map +1 -1
- package/dist/__tests__/missingPin.test.d.ts +11 -0
- package/dist/__tests__/missingPin.test.d.ts.map +1 -0
- package/dist/__tests__/missingPin.test.js +232 -0
- package/dist/__tests__/missingPin.test.js.map +1 -0
- package/dist/__tests__/notice-marker.test.js +146 -11
- package/dist/__tests__/notice-marker.test.js.map +1 -1
- package/dist/__tests__/onboarding.test.js +29 -5
- package/dist/__tests__/onboarding.test.js.map +1 -1
- package/dist/__tests__/onboardingFallback.test.d.ts +2 -0
- package/dist/__tests__/onboardingFallback.test.d.ts.map +1 -0
- package/dist/__tests__/onboardingFallback.test.js +74 -0
- package/dist/__tests__/onboardingFallback.test.js.map +1 -0
- package/dist/__tests__/orient.test.js +380 -39
- package/dist/__tests__/orient.test.js.map +1 -1
- package/dist/__tests__/perimeter.test.js +1 -1
- package/dist/__tests__/perimeter.test.js.map +1 -1
- package/dist/__tests__/preview-key-refresh.test.d.ts +2 -0
- package/dist/__tests__/preview-key-refresh.test.d.ts.map +1 -0
- package/dist/__tests__/preview-key-refresh.test.js +126 -0
- package/dist/__tests__/preview-key-refresh.test.js.map +1 -0
- package/dist/__tests__/profiles.test.js +498 -8
- package/dist/__tests__/profiles.test.js.map +1 -1
- package/dist/__tests__/prompts.test.js +18 -1
- package/dist/__tests__/prompts.test.js.map +1 -1
- package/dist/__tests__/proof-run.test.d.ts +2 -0
- package/dist/__tests__/proof-run.test.d.ts.map +1 -0
- package/dist/__tests__/proof-run.test.js +255 -0
- package/dist/__tests__/proof-run.test.js.map +1 -0
- package/dist/__tests__/rate-limit-resilience.test.d.ts +7 -0
- package/dist/__tests__/rate-limit-resilience.test.d.ts.map +1 -0
- package/dist/__tests__/rate-limit-resilience.test.js +209 -0
- package/dist/__tests__/rate-limit-resilience.test.js.map +1 -0
- package/dist/__tests__/read-target-notice.test.d.ts +2 -0
- package/dist/__tests__/read-target-notice.test.d.ts.map +1 -0
- package/dist/__tests__/read-target-notice.test.js +129 -0
- package/dist/__tests__/read-target-notice.test.js.map +1 -0
- package/dist/__tests__/relate.test.js +246 -14
- package/dist/__tests__/relate.test.js.map +1 -1
- package/dist/__tests__/reply-commands-registered.test.d.ts +2 -0
- package/dist/__tests__/reply-commands-registered.test.d.ts.map +1 -0
- package/dist/__tests__/reply-commands-registered.test.js +81 -0
- package/dist/__tests__/reply-commands-registered.test.js.map +1 -0
- package/dist/__tests__/repo-detect.test.js +18 -38
- package/dist/__tests__/repo-detect.test.js.map +1 -1
- package/dist/__tests__/reportedProfile.test.d.ts +2 -0
- package/dist/__tests__/reportedProfile.test.d.ts.map +1 -0
- package/dist/__tests__/reportedProfile.test.js +328 -0
- package/dist/__tests__/reportedProfile.test.js.map +1 -0
- package/dist/__tests__/restore.test.d.ts +2 -0
- package/dist/__tests__/restore.test.d.ts.map +1 -0
- package/dist/__tests__/restore.test.js +85 -0
- package/dist/__tests__/restore.test.js.map +1 -0
- package/dist/__tests__/route-latency-budget.test.d.ts +2 -0
- package/dist/__tests__/route-latency-budget.test.d.ts.map +1 -0
- package/dist/__tests__/route-latency-budget.test.js +106 -0
- package/dist/__tests__/route-latency-budget.test.js.map +1 -0
- package/dist/__tests__/runner.test.js +59 -44
- package/dist/__tests__/runner.test.js.map +1 -1
- package/dist/__tests__/session-binding-refusal-tenant.test.d.ts +2 -0
- package/dist/__tests__/session-binding-refusal-tenant.test.d.ts.map +1 -0
- package/dist/__tests__/session-binding-refusal-tenant.test.js +112 -0
- package/dist/__tests__/session-binding-refusal-tenant.test.js.map +1 -0
- package/dist/__tests__/session-close-loop.test.d.ts +2 -0
- package/dist/__tests__/session-close-loop.test.d.ts.map +1 -0
- package/dist/__tests__/session-close-loop.test.js +213 -0
- package/dist/__tests__/session-close-loop.test.js.map +1 -0
- package/dist/__tests__/session-label.test.d.ts +2 -0
- package/dist/__tests__/session-label.test.d.ts.map +1 -0
- package/dist/__tests__/session-label.test.js +46 -0
- package/dist/__tests__/session-label.test.js.map +1 -0
- package/dist/__tests__/session-list-show.test.d.ts +2 -0
- package/dist/__tests__/session-list-show.test.d.ts.map +1 -0
- package/dist/__tests__/session-list-show.test.js +173 -0
- package/dist/__tests__/session-list-show.test.js.map +1 -0
- package/dist/__tests__/session-pinned-role.test.d.ts +2 -0
- package/dist/__tests__/session-pinned-role.test.d.ts.map +1 -0
- package/dist/__tests__/session-pinned-role.test.js +257 -0
- package/dist/__tests__/session-pinned-role.test.js.map +1 -0
- package/dist/__tests__/session-reset.test.d.ts +2 -0
- package/dist/__tests__/session-reset.test.d.ts.map +1 -0
- package/dist/__tests__/session-reset.test.js +138 -0
- package/dist/__tests__/session-reset.test.js.map +1 -0
- package/dist/__tests__/session-resume-backstop.test.d.ts +2 -0
- package/dist/__tests__/session-resume-backstop.test.d.ts.map +1 -0
- package/dist/__tests__/session-resume-backstop.test.js +139 -0
- package/dist/__tests__/session-resume-backstop.test.js.map +1 -0
- package/dist/__tests__/session-role-name-sanitize.test.d.ts +2 -0
- package/dist/__tests__/session-role-name-sanitize.test.d.ts.map +1 -0
- package/dist/__tests__/session-role-name-sanitize.test.js +129 -0
- package/dist/__tests__/session-role-name-sanitize.test.js.map +1 -0
- package/dist/__tests__/session-start-key-refresh.test.d.ts +2 -0
- package/dist/__tests__/session-start-key-refresh.test.d.ts.map +1 -0
- package/dist/__tests__/session-start-key-refresh.test.js +197 -0
- package/dist/__tests__/session-start-key-refresh.test.js.map +1 -0
- package/dist/__tests__/session-state-machine.test.js +190 -9
- package/dist/__tests__/session-state-machine.test.js.map +1 -1
- package/dist/__tests__/session-switch.test.js +218 -4
- package/dist/__tests__/session-switch.test.js.map +1 -1
- package/dist/__tests__/session-touch.test.js +6 -1
- package/dist/__tests__/session-touch.test.js.map +1 -1
- package/dist/__tests__/sessionBinding.test.d.ts +2 -0
- package/dist/__tests__/sessionBinding.test.d.ts.map +1 -0
- package/dist/__tests__/sessionBinding.test.js +118 -0
- package/dist/__tests__/sessionBinding.test.js.map +1 -0
- package/dist/__tests__/sessionByIdLookup.test.d.ts +2 -0
- package/dist/__tests__/sessionByIdLookup.test.d.ts.map +1 -0
- package/dist/__tests__/sessionByIdLookup.test.js +63 -0
- package/dist/__tests__/sessionByIdLookup.test.js.map +1 -0
- package/dist/__tests__/skill-vocabulary.test.d.ts +1 -1
- package/dist/__tests__/skill-vocabulary.test.js +7 -2
- package/dist/__tests__/skill-vocabulary.test.js.map +1 -1
- package/dist/__tests__/state.test.js +21 -1
- package/dist/__tests__/state.test.js.map +1 -1
- package/dist/__tests__/stillTrue.test.d.ts +2 -0
- package/dist/__tests__/stillTrue.test.d.ts.map +1 -0
- package/dist/__tests__/stillTrue.test.js +52 -0
- package/dist/__tests__/stillTrue.test.js.map +1 -0
- package/dist/__tests__/strip.test.js +57 -3
- package/dist/__tests__/strip.test.js.map +1 -1
- package/dist/__tests__/tenant-notice-write-path.test.d.ts +2 -0
- package/dist/__tests__/tenant-notice-write-path.test.d.ts.map +1 -0
- package/dist/__tests__/tenant-notice-write-path.test.js +169 -0
- package/dist/__tests__/tenant-notice-write-path.test.js.map +1 -0
- package/dist/__tests__/update.test.js +458 -8
- package/dist/__tests__/update.test.js.map +1 -1
- package/dist/__tests__/verify-formatter.test.d.ts +2 -0
- package/dist/__tests__/verify-formatter.test.d.ts.map +1 -0
- package/dist/__tests__/verify-formatter.test.js +85 -0
- package/dist/__tests__/verify-formatter.test.js.map +1 -0
- package/dist/__tests__/vocabulary-leak.test.d.ts +1 -7
- package/dist/__tests__/vocabulary-leak.test.d.ts.map +1 -1
- package/dist/__tests__/vocabulary-leak.test.js +7 -114
- package/dist/__tests__/vocabulary-leak.test.js.map +1 -1
- package/dist/__tests__/workspace.test.js +11 -72
- package/dist/__tests__/workspace.test.js.map +1 -1
- package/dist/__tests__/workspaceNotice.test.d.ts +2 -0
- package/dist/__tests__/workspaceNotice.test.d.ts.map +1 -0
- package/dist/__tests__/workspaceNotice.test.js +571 -0
- package/dist/__tests__/workspaceNotice.test.js.map +1 -0
- package/dist/commands/__tests__/quality.test.d.ts +2 -0
- package/dist/commands/__tests__/quality.test.d.ts.map +1 -0
- package/dist/commands/__tests__/quality.test.js +156 -0
- package/dist/commands/__tests__/quality.test.js.map +1 -0
- package/dist/commands/__tests__/rework.test.d.ts +2 -0
- package/dist/commands/__tests__/rework.test.d.ts.map +1 -0
- package/dist/commands/__tests__/rework.test.js +149 -0
- package/dist/commands/__tests__/rework.test.js.map +1 -0
- package/dist/commands/__tests__/tensionsList.test.d.ts +2 -0
- package/dist/commands/__tests__/tensionsList.test.d.ts.map +1 -0
- package/dist/commands/__tests__/tensionsList.test.js +63 -0
- package/dist/commands/__tests__/tensionsList.test.js.map +1 -0
- package/dist/commands/accept-policy.d.ts +10 -0
- package/dist/commands/accept-policy.d.ts.map +1 -0
- package/dist/commands/accept-policy.js +107 -0
- package/dist/commands/accept-policy.js.map +1 -0
- package/dist/commands/admin/cockpit.d.ts +2 -13
- package/dist/commands/admin/cockpit.d.ts.map +1 -1
- package/dist/commands/admin/cockpit.js +5 -5
- package/dist/commands/admin/cockpit.js.map +1 -1
- package/dist/commands/admin/index.d.ts +49 -0
- package/dist/commands/admin/index.d.ts.map +1 -1
- package/dist/commands/admin/index.js +148 -29
- package/dist/commands/admin/index.js.map +1 -1
- package/dist/commands/admin/index.test.d.ts +2 -0
- package/dist/commands/admin/index.test.d.ts.map +1 -0
- package/dist/commands/admin/index.test.js +94 -0
- package/dist/commands/admin/index.test.js.map +1 -0
- package/dist/commands/admin/inspect.d.ts.map +1 -1
- package/dist/commands/admin/inspect.js +2 -7
- package/dist/commands/admin/inspect.js.map +1 -1
- package/dist/commands/admin/probe.d.ts +75 -0
- package/dist/commands/admin/probe.d.ts.map +1 -0
- package/dist/commands/admin/probe.js +224 -0
- package/dist/commands/admin/probe.js.map +1 -0
- package/dist/commands/admin/probe.test.d.ts +2 -0
- package/dist/commands/admin/probe.test.d.ts.map +1 -0
- package/dist/commands/admin/probe.test.js +193 -0
- package/dist/commands/admin/probe.test.js.map +1 -0
- package/dist/commands/admin/run.d.ts +43 -0
- package/dist/commands/admin/run.d.ts.map +1 -0
- package/dist/commands/admin/run.js +78 -0
- package/dist/commands/admin/run.js.map +1 -0
- package/dist/commands/admin/run.test.d.ts +18 -0
- package/dist/commands/admin/run.test.d.ts.map +1 -0
- package/dist/commands/admin/run.test.js +168 -0
- package/dist/commands/admin/run.test.js.map +1 -0
- package/dist/commands/admin/seed.d.ts +6 -21
- package/dist/commands/admin/seed.d.ts.map +1 -1
- package/dist/commands/admin/seed.js +41 -310
- package/dist/commands/admin/seed.js.map +1 -1
- package/dist/commands/admin/seed.test.d.ts +3 -4
- package/dist/commands/admin/seed.test.d.ts.map +1 -1
- package/dist/commands/admin/seed.test.js +26 -76
- package/dist/commands/admin/seed.test.js.map +1 -1
- package/dist/commands/admin/seedRegistryEntries.generated.d.ts.map +1 -1
- package/dist/commands/admin/seedRegistryEntries.generated.js +3 -84
- package/dist/commands/admin/seedRegistryEntries.generated.js.map +1 -1
- package/dist/commands/admin/seedRegistryEntries.test.d.ts +5 -3
- package/dist/commands/admin/seedRegistryEntries.test.d.ts.map +1 -1
- package/dist/commands/admin/seedRegistryEntries.test.js +60 -26
- package/dist/commands/admin/seedRegistryEntries.test.js.map +1 -1
- package/dist/commands/admin/seedRowType.d.ts +22 -0
- package/dist/commands/admin/seedRowType.d.ts.map +1 -0
- package/dist/commands/admin/seedRowType.js +2 -0
- package/dist/commands/admin/seedRowType.js.map +1 -0
- package/dist/commands/admin/seedStatusColor.d.ts +9 -0
- package/dist/commands/admin/seedStatusColor.d.ts.map +1 -0
- package/dist/commands/admin/seedStatusColor.js +19 -0
- package/dist/commands/admin/seedStatusColor.js.map +1 -0
- package/dist/commands/admin/seedStatusColor.test.d.ts +2 -0
- package/dist/commands/admin/seedStatusColor.test.d.ts.map +1 -0
- package/dist/commands/admin/seedStatusColor.test.js +31 -0
- package/dist/commands/admin/seedStatusColor.test.js.map +1 -0
- package/dist/commands/brief.d.ts.map +1 -1
- package/dist/commands/brief.js +24 -2
- package/dist/commands/brief.js.map +1 -1
- package/dist/commands/capture.d.ts +17 -9
- package/dist/commands/capture.d.ts.map +1 -1
- package/dist/commands/capture.js +173 -228
- package/dist/commands/capture.js.map +1 -1
- package/dist/commands/chain-walk.d.ts.map +1 -1
- package/dist/commands/chain-walk.js.map +1 -1
- package/dist/commands/changes.d.ts.map +1 -1
- package/dist/commands/changes.js.map +1 -1
- package/dist/commands/codex-prep.d.ts +11 -1
- package/dist/commands/codex-prep.d.ts.map +1 -1
- package/dist/commands/codex-prep.js +14 -83
- package/dist/commands/codex-prep.js.map +1 -1
- package/dist/commands/collections.d.ts +1 -1
- package/dist/commands/collections.d.ts.map +1 -1
- package/dist/commands/collections.js +1 -1
- package/dist/commands/collections.js.map +1 -1
- package/dist/commands/conflicts.d.ts +35 -0
- package/dist/commands/conflicts.d.ts.map +1 -0
- package/dist/commands/conflicts.js +194 -0
- package/dist/commands/conflicts.js.map +1 -0
- package/dist/commands/conflicts.test.d.ts +2 -0
- package/dist/commands/conflicts.test.d.ts.map +1 -0
- package/dist/commands/conflicts.test.js +179 -0
- package/dist/commands/conflicts.test.js.map +1 -0
- package/dist/commands/connect-config.test.js +11 -3
- package/dist/commands/connect-config.test.js.map +1 -1
- package/dist/commands/connect-context.d.ts +27 -17
- package/dist/commands/connect-context.d.ts.map +1 -1
- package/dist/commands/connect-context.js +45 -31
- package/dist/commands/connect-context.js.map +1 -1
- package/dist/commands/connect-context.test.js +91 -53
- package/dist/commands/connect-context.test.js.map +1 -1
- package/dist/commands/connect-decline.test.d.ts +2 -0
- package/dist/commands/connect-decline.test.d.ts.map +1 -0
- package/dist/commands/connect-decline.test.js +70 -0
- package/dist/commands/connect-decline.test.js.map +1 -0
- package/dist/commands/connect-integration.test.js +24 -7
- package/dist/commands/connect-integration.test.js.map +1 -1
- package/dist/commands/connect-legacy-migration.test.d.ts +2 -0
- package/dist/commands/connect-legacy-migration.test.d.ts.map +1 -0
- package/dist/commands/connect-legacy-migration.test.js +109 -0
- package/dist/commands/connect-legacy-migration.test.js.map +1 -0
- package/dist/commands/connect-redeem-failure.test.d.ts +2 -0
- package/dist/commands/connect-redeem-failure.test.d.ts.map +1 -0
- package/dist/commands/connect-redeem-failure.test.js +134 -0
- package/dist/commands/connect-redeem-failure.test.js.map +1 -0
- package/dist/commands/connect-screens.d.ts +14 -3
- package/dist/commands/connect-screens.d.ts.map +1 -1
- package/dist/commands/connect-screens.js +62 -9
- package/dist/commands/connect-screens.js.map +1 -1
- package/dist/commands/connect-seal.test.d.ts +2 -0
- package/dist/commands/connect-seal.test.d.ts.map +1 -0
- package/dist/commands/connect-seal.test.js +55 -0
- package/dist/commands/connect-seal.test.js.map +1 -0
- package/dist/commands/connect.d.ts +14 -11
- package/dist/commands/connect.d.ts.map +1 -1
- package/dist/commands/connect.js +236 -69
- package/dist/commands/connect.js.map +1 -1
- package/dist/commands/connect.test.js +226 -23
- package/dist/commands/connect.test.js.map +1 -1
- package/dist/commands/constellation.d.ts.map +1 -1
- package/dist/commands/constellation.js.map +1 -1
- package/dist/commands/context.d.ts.map +1 -1
- package/dist/commands/context.js.map +1 -1
- package/dist/commands/cross-cut.d.ts.map +1 -1
- package/dist/commands/cross-cut.js.map +1 -1
- package/dist/commands/digest.d.ts +17 -0
- package/dist/commands/digest.d.ts.map +1 -0
- package/dist/commands/digest.js +58 -0
- package/dist/commands/digest.js.map +1 -0
- package/dist/commands/digest.test.d.ts +2 -0
- package/dist/commands/digest.test.d.ts.map +1 -0
- package/dist/commands/digest.test.js +36 -0
- package/dist/commands/digest.test.js.map +1 -0
- package/dist/commands/direction.d.ts +10 -0
- package/dist/commands/direction.d.ts.map +1 -0
- package/dist/commands/direction.js +79 -0
- package/dist/commands/direction.js.map +1 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +105 -35
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/doctor.test.js +202 -6
- package/dist/commands/doctor.test.js.map +1 -1
- package/dist/commands/entryAccept.d.ts +24 -0
- package/dist/commands/entryAccept.d.ts.map +1 -0
- package/dist/commands/entryAccept.js +296 -0
- package/dist/commands/entryAccept.js.map +1 -0
- package/dist/commands/entryDiscardResolve.d.ts +9 -0
- package/dist/commands/entryDiscardResolve.d.ts.map +1 -0
- package/dist/commands/entryDiscardResolve.js +27 -0
- package/dist/commands/entryDiscardResolve.js.map +1 -0
- package/dist/commands/entryOwn.d.ts +5 -0
- package/dist/commands/entryOwn.d.ts.map +1 -0
- package/dist/commands/entryOwn.js +17 -0
- package/dist/commands/entryOwn.js.map +1 -0
- package/dist/commands/entryPreflight.d.ts +8 -0
- package/dist/commands/entryPreflight.d.ts.map +1 -0
- package/dist/commands/entryPreflight.js +48 -0
- package/dist/commands/entryPreflight.js.map +1 -0
- package/dist/commands/entryTick.d.ts +8 -0
- package/dist/commands/entryTick.d.ts.map +1 -0
- package/dist/commands/entryTick.js +43 -0
- package/dist/commands/entryTick.js.map +1 -0
- package/dist/commands/feedback.d.ts +36 -0
- package/dist/commands/feedback.d.ts.map +1 -0
- package/dist/commands/feedback.js +174 -0
- package/dist/commands/feedback.js.map +1 -0
- package/dist/commands/feedback.test.d.ts +2 -0
- package/dist/commands/feedback.test.d.ts.map +1 -0
- package/dist/commands/feedback.test.js +110 -0
- package/dist/commands/feedback.test.js.map +1 -0
- package/dist/commands/fields.d.ts.map +1 -1
- package/dist/commands/fields.js +1 -1
- package/dist/commands/fields.js.map +1 -1
- package/dist/commands/files.d.ts +26 -0
- package/dist/commands/files.d.ts.map +1 -0
- package/dist/commands/files.js +160 -0
- package/dist/commands/files.js.map +1 -0
- package/dist/commands/files.test.d.ts +2 -0
- package/dist/commands/files.test.d.ts.map +1 -0
- package/dist/commands/files.test.js +278 -0
- package/dist/commands/files.test.js.map +1 -0
- package/dist/commands/handshake.d.ts +42 -186
- package/dist/commands/handshake.d.ts.map +1 -1
- package/dist/commands/handshake.js +469 -1539
- package/dist/commands/handshake.js.map +1 -1
- package/dist/commands/handshakeCursorSkillCleanup.d.ts +36 -0
- package/dist/commands/handshakeCursorSkillCleanup.d.ts.map +1 -0
- package/dist/commands/handshakeCursorSkillCleanup.js +110 -0
- package/dist/commands/handshakeCursorSkillCleanup.js.map +1 -0
- package/dist/commands/handshakeDriftClassification.d.ts +33 -0
- package/dist/commands/handshakeDriftClassification.d.ts.map +1 -0
- package/dist/commands/handshakeDriftClassification.js +62 -0
- package/dist/commands/handshakeDriftClassification.js.map +1 -0
- package/dist/commands/history.d.ts +30 -0
- package/dist/commands/history.d.ts.map +1 -0
- package/dist/commands/history.js +62 -0
- package/dist/commands/history.js.map +1 -0
- package/dist/commands/history.test.d.ts +2 -0
- package/dist/commands/history.test.d.ts.map +1 -0
- package/dist/commands/history.test.js +106 -0
- package/dist/commands/history.test.js.map +1 -0
- package/dist/commands/ingest.d.ts.map +1 -1
- package/dist/commands/ingest.js +9 -0
- package/dist/commands/ingest.js.map +1 -1
- package/dist/commands/init.d.ts +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +22 -13
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +15 -11
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/organisation.d.ts +12 -0
- package/dist/commands/organisation.d.ts.map +1 -0
- package/dist/commands/organisation.js +162 -0
- package/dist/commands/organisation.js.map +1 -0
- package/dist/commands/organisation.test.d.ts +2 -0
- package/dist/commands/organisation.test.d.ts.map +1 -0
- package/dist/commands/organisation.test.js +196 -0
- package/dist/commands/organisation.test.js.map +1 -0
- package/dist/commands/organisationHierarchy.d.ts +8 -0
- package/dist/commands/organisationHierarchy.d.ts.map +1 -0
- package/dist/commands/organisationHierarchy.js +75 -0
- package/dist/commands/organisationHierarchy.js.map +1 -0
- package/dist/commands/organisationHierarchy.test.d.ts +2 -0
- package/dist/commands/organisationHierarchy.test.d.ts.map +1 -0
- package/dist/commands/organisationHierarchy.test.js +72 -0
- package/dist/commands/organisationHierarchy.test.js.map +1 -0
- package/dist/commands/organisationWrite.d.ts +18 -0
- package/dist/commands/organisationWrite.d.ts.map +1 -0
- package/dist/commands/organisationWrite.js +71 -0
- package/dist/commands/organisationWrite.js.map +1 -0
- package/dist/commands/orient.d.ts +49 -96
- package/dist/commands/orient.d.ts.map +1 -1
- package/dist/commands/orient.js +135 -29
- package/dist/commands/orient.js.map +1 -1
- package/dist/commands/outcome.d.ts +91 -0
- package/dist/commands/outcome.d.ts.map +1 -0
- package/dist/commands/outcome.js +204 -0
- package/dist/commands/outcome.js.map +1 -0
- package/dist/commands/outcome.test.d.ts +2 -0
- package/dist/commands/outcome.test.d.ts.map +1 -0
- package/dist/commands/outcome.test.js +308 -0
- package/dist/commands/outcome.test.js.map +1 -0
- package/dist/commands/people.d.ts +6 -0
- package/dist/commands/people.d.ts.map +1 -0
- package/dist/commands/people.js +22 -0
- package/dist/commands/people.js.map +1 -0
- package/dist/commands/people.test.d.ts +2 -0
- package/dist/commands/people.test.d.ts.map +1 -0
- package/dist/commands/people.test.js +61 -0
- package/dist/commands/people.test.js.map +1 -0
- package/dist/commands/profile.d.ts +23 -2
- package/dist/commands/profile.d.ts.map +1 -1
- package/dist/commands/profile.js +192 -35
- package/dist/commands/profile.js.map +1 -1
- package/dist/commands/proof-run.d.ts +51 -0
- package/dist/commands/proof-run.d.ts.map +1 -0
- package/dist/commands/proof-run.js +209 -0
- package/dist/commands/proof-run.js.map +1 -0
- package/dist/commands/quality.d.ts +16 -0
- package/dist/commands/quality.d.ts.map +1 -0
- package/dist/commands/quality.js +29 -0
- package/dist/commands/quality.js.map +1 -0
- package/dist/commands/questions.d.ts +23 -0
- package/dist/commands/questions.d.ts.map +1 -0
- package/dist/commands/questions.js +238 -0
- package/dist/commands/questions.js.map +1 -0
- package/dist/commands/questions.test.d.ts +2 -0
- package/dist/commands/questions.test.d.ts.map +1 -0
- package/dist/commands/questions.test.js +159 -0
- package/dist/commands/questions.test.js.map +1 -0
- package/dist/commands/relate.d.ts +1 -0
- package/dist/commands/relate.d.ts.map +1 -1
- package/dist/commands/relate.js +89 -15
- package/dist/commands/relate.js.map +1 -1
- package/dist/commands/restore.d.ts +2 -0
- package/dist/commands/restore.d.ts.map +1 -0
- package/dist/commands/restore.js +83 -0
- package/dist/commands/restore.js.map +1 -0
- package/dist/commands/rework.d.ts +24 -0
- package/dist/commands/rework.d.ts.map +1 -0
- package/dist/commands/rework.js +97 -0
- package/dist/commands/rework.js.map +1 -0
- package/dist/commands/role.d.ts +67 -0
- package/dist/commands/role.d.ts.map +1 -0
- package/dist/commands/role.js +164 -0
- package/dist/commands/role.js.map +1 -0
- package/dist/commands/role.test.d.ts +2 -0
- package/dist/commands/role.test.d.ts.map +1 -0
- package/dist/commands/role.test.js +290 -0
- package/dist/commands/role.test.js.map +1 -0
- package/dist/commands/scoreboard.d.ts +26 -0
- package/dist/commands/scoreboard.d.ts.map +1 -0
- package/dist/commands/scoreboard.js +40 -0
- package/dist/commands/scoreboard.js.map +1 -0
- package/dist/commands/search.d.ts +3 -0
- package/dist/commands/search.d.ts.map +1 -1
- package/dist/commands/search.js +7 -1
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/session.d.ts +60 -7
- package/dist/commands/session.d.ts.map +1 -1
- package/dist/commands/session.js +409 -98
- package/dist/commands/session.js.map +1 -1
- package/dist/commands/shape.d.ts +16 -0
- package/dist/commands/shape.d.ts.map +1 -0
- package/dist/commands/shape.js +149 -0
- package/dist/commands/shape.js.map +1 -0
- package/dist/commands/shape.test.d.ts +2 -0
- package/dist/commands/shape.test.d.ts.map +1 -0
- package/dist/commands/shape.test.js +148 -0
- package/dist/commands/shape.test.js.map +1 -0
- package/dist/commands/status.d.ts +7 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +102 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/status.test.d.ts +2 -0
- package/dist/commands/status.test.d.ts.map +1 -0
- package/dist/commands/status.test.js +75 -0
- package/dist/commands/status.test.js.map +1 -0
- package/dist/commands/stillTrue.d.ts +14 -0
- package/dist/commands/stillTrue.d.ts.map +1 -0
- package/dist/commands/stillTrue.js +48 -0
- package/dist/commands/stillTrue.js.map +1 -0
- package/dist/commands/tensionsList.d.ts +5 -0
- package/dist/commands/tensionsList.d.ts.map +1 -0
- package/dist/commands/tensionsList.js +27 -0
- package/dist/commands/tensionsList.js.map +1 -0
- package/dist/commands/update.d.ts +21 -0
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +157 -42
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/usage.d.ts.map +1 -1
- package/dist/commands/usage.js +0 -18
- package/dist/commands/usage.js.map +1 -1
- package/dist/commands/verify.d.ts.map +1 -1
- package/dist/commands/verify.js +7 -1
- package/dist/commands/verify.js.map +1 -1
- package/dist/commands/welcome.d.ts.map +1 -1
- package/dist/commands/welcome.js +5 -2
- package/dist/commands/welcome.js.map +1 -1
- package/dist/commands/whoami.d.ts +10 -2
- package/dist/commands/whoami.d.ts.map +1 -1
- package/dist/commands/whoami.js +76 -20
- package/dist/commands/whoami.js.map +1 -1
- package/dist/commands/whoami.test.js +86 -6
- package/dist/commands/whoami.test.js.map +1 -1
- package/dist/commands/workspace.d.ts +7 -74
- package/dist/commands/workspace.d.ts.map +1 -1
- package/dist/commands/workspace.js +9 -70
- package/dist/commands/workspace.js.map +1 -1
- package/dist/formatters/__tests__/orient-plannedWorkCut.test.d.ts +2 -0
- package/dist/formatters/__tests__/orient-plannedWorkCut.test.d.ts.map +1 -0
- package/dist/formatters/__tests__/orient-plannedWorkCut.test.js +49 -0
- package/dist/formatters/__tests__/orient-plannedWorkCut.test.js.map +1 -0
- package/dist/formatters/__tests__/orient-provenance.test.d.ts +2 -3
- package/dist/formatters/__tests__/orient-provenance.test.d.ts.map +1 -1
- package/dist/formatters/__tests__/orient-provenance.test.js +39 -174
- package/dist/formatters/__tests__/orient-provenance.test.js.map +1 -1
- package/dist/formatters/__tests__/orient-ruleLists.test.d.ts +2 -0
- package/dist/formatters/__tests__/orient-ruleLists.test.d.ts.map +1 -0
- package/dist/formatters/__tests__/orient-ruleLists.test.js +93 -0
- package/dist/formatters/__tests__/orient-ruleLists.test.js.map +1 -0
- package/dist/formatters/__tests__/session-list-show.test.d.ts +2 -0
- package/dist/formatters/__tests__/session-list-show.test.d.ts.map +1 -0
- package/dist/formatters/__tests__/session-list-show.test.js +195 -0
- package/dist/formatters/__tests__/session-list-show.test.js.map +1 -0
- package/dist/formatters/__tests__/session.test.d.ts +2 -0
- package/dist/formatters/__tests__/session.test.d.ts.map +1 -0
- package/dist/formatters/__tests__/session.test.js +193 -0
- package/dist/formatters/__tests__/session.test.js.map +1 -0
- package/dist/formatters/__tests__/tensionsList.test.d.ts +2 -0
- package/dist/formatters/__tests__/tensionsList.test.d.ts.map +1 -0
- package/dist/formatters/__tests__/tensionsList.test.js +30 -0
- package/dist/formatters/__tests__/tensionsList.test.js.map +1 -0
- package/dist/formatters/brief.d.ts +6 -15
- package/dist/formatters/brief.d.ts.map +1 -1
- package/dist/formatters/brief.js +16 -14
- package/dist/formatters/brief.js.map +1 -1
- package/dist/formatters/brief.test.d.ts +2 -0
- package/dist/formatters/brief.test.d.ts.map +1 -0
- package/dist/formatters/brief.test.js +21 -0
- package/dist/formatters/brief.test.js.map +1 -0
- package/dist/formatters/capture.d.ts +17 -10
- package/dist/formatters/capture.d.ts.map +1 -1
- package/dist/formatters/capture.js +32 -10
- package/dist/formatters/capture.js.map +1 -1
- package/dist/formatters/coaching.d.ts +53 -0
- package/dist/formatters/coaching.d.ts.map +1 -0
- package/dist/formatters/coaching.js +51 -0
- package/dist/formatters/coaching.js.map +1 -0
- package/dist/formatters/collections.d.ts +0 -1
- package/dist/formatters/collections.d.ts.map +1 -1
- package/dist/formatters/collections.js +14 -5
- package/dist/formatters/collections.js.map +1 -1
- package/dist/formatters/conflicts.d.ts +69 -0
- package/dist/formatters/conflicts.d.ts.map +1 -0
- package/dist/formatters/conflicts.js +87 -0
- package/dist/formatters/conflicts.js.map +1 -0
- package/dist/formatters/conflicts.test.d.ts +2 -0
- package/dist/formatters/conflicts.test.d.ts.map +1 -0
- package/dist/formatters/conflicts.test.js +136 -0
- package/dist/formatters/conflicts.test.js.map +1 -0
- package/dist/formatters/context.d.ts +1 -1
- package/dist/formatters/context.d.ts.map +1 -1
- package/dist/formatters/context.js.map +1 -1
- package/dist/formatters/digest.d.ts +13 -0
- package/dist/formatters/digest.d.ts.map +1 -0
- package/dist/formatters/digest.js +98 -0
- package/dist/formatters/digest.js.map +1 -0
- package/dist/formatters/digest.test.d.ts +2 -0
- package/dist/formatters/digest.test.d.ts.map +1 -0
- package/dist/formatters/digest.test.js +166 -0
- package/dist/formatters/digest.test.js.map +1 -0
- package/dist/formatters/direction.d.ts +48 -0
- package/dist/formatters/direction.d.ts.map +1 -0
- package/dist/formatters/direction.js +75 -0
- package/dist/formatters/direction.js.map +1 -0
- package/dist/formatters/direction.test.d.ts +2 -0
- package/dist/formatters/direction.test.d.ts.map +1 -0
- package/dist/formatters/direction.test.js +70 -0
- package/dist/formatters/direction.test.js.map +1 -0
- package/dist/formatters/entry.d.ts +46 -3
- package/dist/formatters/entry.d.ts.map +1 -1
- package/dist/formatters/entry.js +57 -7
- package/dist/formatters/entry.js.map +1 -1
- package/dist/formatters/entryAccept.d.ts +77 -0
- package/dist/formatters/entryAccept.d.ts.map +1 -0
- package/dist/formatters/entryAccept.js +76 -0
- package/dist/formatters/entryAccept.js.map +1 -0
- package/dist/formatters/feedback.d.ts +58 -0
- package/dist/formatters/feedback.d.ts.map +1 -0
- package/dist/formatters/feedback.js +91 -0
- package/dist/formatters/feedback.js.map +1 -0
- package/dist/formatters/feedback.test.d.ts +2 -0
- package/dist/formatters/feedback.test.d.ts.map +1 -0
- package/dist/formatters/feedback.test.js +123 -0
- package/dist/formatters/feedback.test.js.map +1 -0
- package/dist/formatters/fields.d.ts +7 -1
- package/dist/formatters/fields.d.ts.map +1 -1
- package/dist/formatters/fields.js +9 -3
- package/dist/formatters/fields.js.map +1 -1
- package/dist/formatters/fields.test.d.ts +2 -0
- package/dist/formatters/fields.test.d.ts.map +1 -0
- package/dist/formatters/fields.test.js +42 -0
- package/dist/formatters/fields.test.js.map +1 -0
- package/dist/formatters/handshake.d.ts +24 -6
- package/dist/formatters/handshake.d.ts.map +1 -1
- package/dist/formatters/handshake.js +34 -15
- package/dist/formatters/handshake.js.map +1 -1
- package/dist/formatters/orient.coherencyCheckTag.test.d.ts +2 -0
- package/dist/formatters/orient.coherencyCheckTag.test.d.ts.map +1 -0
- package/dist/formatters/orient.coherencyCheckTag.test.js +22 -0
- package/dist/formatters/orient.coherencyCheckTag.test.js.map +1 -0
- package/dist/formatters/orient.d.ts +108 -144
- package/dist/formatters/orient.d.ts.map +1 -1
- package/dist/formatters/orient.js +157 -181
- package/dist/formatters/orient.js.map +1 -1
- package/dist/formatters/orient.rcrtMiss.test.d.ts +2 -0
- package/dist/formatters/orient.rcrtMiss.test.d.ts.map +1 -0
- package/dist/formatters/orient.rcrtMiss.test.js +77 -0
- package/dist/formatters/orient.rcrtMiss.test.js.map +1 -0
- package/dist/formatters/orient.rituals.test.d.ts +2 -0
- package/dist/formatters/orient.rituals.test.d.ts.map +1 -0
- package/dist/formatters/orient.rituals.test.js +73 -0
- package/dist/formatters/orient.rituals.test.js.map +1 -0
- package/dist/formatters/orient.shapeAdvisorySummary.test.d.ts +2 -0
- package/dist/formatters/orient.shapeAdvisorySummary.test.d.ts.map +1 -0
- package/dist/formatters/orient.shapeAdvisorySummary.test.js +59 -0
- package/dist/formatters/orient.shapeAdvisorySummary.test.js.map +1 -0
- package/dist/formatters/orientDegradation.d.ts +38 -0
- package/dist/formatters/orientDegradation.d.ts.map +1 -0
- package/dist/formatters/orientDegradation.js +50 -0
- package/dist/formatters/orientDegradation.js.map +1 -0
- package/dist/formatters/orientDegradation.test.d.ts +2 -0
- package/dist/formatters/orientDegradation.test.d.ts.map +1 -0
- package/dist/formatters/orientDegradation.test.js +28 -0
- package/dist/formatters/orientDegradation.test.js.map +1 -0
- package/dist/formatters/orientDirection.d.ts +47 -0
- package/dist/formatters/orientDirection.d.ts.map +1 -0
- package/dist/formatters/orientDirection.js +23 -0
- package/dist/formatters/orientDirection.js.map +1 -0
- package/dist/formatters/orientDirection.test.d.ts +2 -0
- package/dist/formatters/orientDirection.test.d.ts.map +1 -0
- package/dist/formatters/orientDirection.test.js +70 -0
- package/dist/formatters/orientDirection.test.js.map +1 -0
- package/dist/formatters/orientRetrievalMiss.d.ts +22 -0
- package/dist/formatters/orientRetrievalMiss.d.ts.map +1 -0
- package/dist/formatters/orientRetrievalMiss.js +17 -0
- package/dist/formatters/orientRetrievalMiss.js.map +1 -0
- package/dist/formatters/plannedWorkCounts.d.ts +19 -0
- package/dist/formatters/plannedWorkCounts.d.ts.map +1 -0
- package/dist/formatters/plannedWorkCounts.js +17 -0
- package/dist/formatters/plannedWorkCounts.js.map +1 -0
- package/dist/formatters/questions.d.ts +72 -0
- package/dist/formatters/questions.d.ts.map +1 -0
- package/dist/formatters/questions.js +116 -0
- package/dist/formatters/questions.js.map +1 -0
- package/dist/formatters/questions.test.d.ts +2 -0
- package/dist/formatters/questions.test.d.ts.map +1 -0
- package/dist/formatters/questions.test.js +144 -0
- package/dist/formatters/questions.test.js.map +1 -0
- package/dist/formatters/relate.d.ts +13 -2
- package/dist/formatters/relate.d.ts.map +1 -1
- package/dist/formatters/relate.js +15 -5
- package/dist/formatters/relate.js.map +1 -1
- package/dist/formatters/relate.test.d.ts +2 -0
- package/dist/formatters/relate.test.d.ts.map +1 -0
- package/dist/formatters/relate.test.js +91 -0
- package/dist/formatters/relate.test.js.map +1 -0
- package/dist/formatters/scoreboard.d.ts +11 -0
- package/dist/formatters/scoreboard.d.ts.map +1 -0
- package/dist/formatters/scoreboard.js +162 -0
- package/dist/formatters/scoreboard.js.map +1 -0
- package/dist/formatters/scoreboard.test.d.ts +2 -0
- package/dist/formatters/scoreboard.test.d.ts.map +1 -0
- package/dist/formatters/scoreboard.test.js +301 -0
- package/dist/formatters/scoreboard.test.js.map +1 -0
- package/dist/formatters/search.d.ts +3 -0
- package/dist/formatters/search.d.ts.map +1 -1
- package/dist/formatters/search.js +15 -1
- package/dist/formatters/search.js.map +1 -1
- package/dist/formatters/search.test.d.ts +2 -0
- package/dist/formatters/search.test.d.ts.map +1 -0
- package/dist/formatters/search.test.js +76 -0
- package/dist/formatters/search.test.js.map +1 -0
- package/dist/formatters/session-feedback.test.d.ts +2 -0
- package/dist/formatters/session-feedback.test.d.ts.map +1 -0
- package/dist/formatters/session-feedback.test.js +146 -0
- package/dist/formatters/session-feedback.test.js.map +1 -0
- package/dist/formatters/session.d.ts +122 -5
- package/dist/formatters/session.d.ts.map +1 -1
- package/dist/formatters/session.js +312 -21
- package/dist/formatters/session.js.map +1 -1
- package/dist/formatters/shape.d.ts +54 -0
- package/dist/formatters/shape.d.ts.map +1 -0
- package/dist/formatters/shape.js +97 -0
- package/dist/formatters/shape.js.map +1 -0
- package/dist/formatters/shape.test.d.ts +2 -0
- package/dist/formatters/shape.test.d.ts.map +1 -0
- package/dist/formatters/shape.test.js +80 -0
- package/dist/formatters/shape.test.js.map +1 -0
- package/dist/formatters/spineCheck.d.ts +14 -0
- package/dist/formatters/spineCheck.d.ts.map +1 -0
- package/dist/formatters/spineCheck.js +113 -0
- package/dist/formatters/spineCheck.js.map +1 -0
- package/dist/formatters/spineCheck.test.d.ts +2 -0
- package/dist/formatters/spineCheck.test.d.ts.map +1 -0
- package/dist/formatters/spineCheck.test.js +76 -0
- package/dist/formatters/spineCheck.test.js.map +1 -0
- package/dist/formatters/tensionsList.d.ts +17 -0
- package/dist/formatters/tensionsList.d.ts.map +1 -0
- package/dist/formatters/tensionsList.js +33 -0
- package/dist/formatters/tensionsList.js.map +1 -0
- package/dist/formatters/update.d.ts +22 -0
- package/dist/formatters/update.d.ts.map +1 -1
- package/dist/formatters/update.js +36 -7
- package/dist/formatters/update.js.map +1 -1
- package/dist/formatters/update.test.d.ts +2 -0
- package/dist/formatters/update.test.d.ts.map +1 -0
- package/dist/formatters/update.test.js +59 -0
- package/dist/formatters/update.test.js.map +1 -0
- package/dist/formatters/verify.d.ts +12 -4
- package/dist/formatters/verify.d.ts.map +1 -1
- package/dist/formatters/verify.js +20 -2
- package/dist/formatters/verify.js.map +1 -1
- package/dist/generated/healthGapKinds.generated.d.ts +12 -0
- package/dist/generated/healthGapKinds.generated.d.ts.map +1 -0
- package/dist/generated/healthGapKinds.generated.js +16 -0
- package/dist/generated/healthGapKinds.generated.js.map +1 -0
- package/dist/generated/organisationalAuthorityRefusalCodes.generated.d.ts +12 -0
- package/dist/generated/organisationalAuthorityRefusalCodes.generated.d.ts.map +1 -0
- package/dist/generated/organisationalAuthorityRefusalCodes.generated.js +11 -0
- package/dist/generated/organisationalAuthorityRefusalCodes.generated.js.map +1 -0
- package/dist/generated/relationTypes.generated.d.ts +12 -0
- package/dist/generated/relationTypes.generated.d.ts.map +1 -0
- package/dist/generated/relationTypes.generated.js +11 -0
- package/dist/generated/relationTypes.generated.js.map +1 -0
- package/dist/generated/routeLatencyBudget.generated.d.ts +56 -0
- package/dist/generated/routeLatencyBudget.generated.d.ts.map +1 -0
- package/dist/generated/routeLatencyBudget.generated.js +278 -0
- package/dist/generated/routeLatencyBudget.generated.js.map +1 -0
- package/dist/generated/sourceSurfaces.generated.d.ts +12 -0
- package/dist/generated/sourceSurfaces.generated.d.ts.map +1 -0
- package/dist/generated/sourceSurfaces.generated.js +11 -0
- package/dist/generated/sourceSurfaces.generated.js.map +1 -0
- package/dist/generators/adapters.d.ts +39 -6
- package/dist/generators/adapters.d.ts.map +1 -1
- package/dist/generators/adapters.js +88 -89
- package/dist/generators/adapters.js.map +1 -1
- package/dist/generators/adapters.test.js +14 -6
- package/dist/generators/adapters.test.js.map +1 -1
- package/dist/generators/boundary-manifest.real-file.test.d.ts +2 -0
- package/dist/generators/boundary-manifest.real-file.test.d.ts.map +1 -0
- package/dist/generators/boundary-manifest.real-file.test.js +70 -0
- package/dist/generators/boundary-manifest.real-file.test.js.map +1 -0
- package/dist/generators/briefing-projections.test.d.ts +2 -0
- package/dist/generators/briefing-projections.test.d.ts.map +1 -0
- package/dist/generators/briefing-projections.test.js +98 -0
- package/dist/generators/briefing-projections.test.js.map +1 -0
- package/dist/generators/context-md.d.ts +7 -2
- package/dist/generators/context-md.d.ts.map +1 -1
- package/dist/generators/context-md.js +14 -53
- package/dist/generators/context-md.js.map +1 -1
- package/dist/generators/everyone-rules-md.d.ts +9 -0
- package/dist/generators/everyone-rules-md.d.ts.map +1 -0
- package/dist/generators/everyone-rules-md.js +21 -0
- package/dist/generators/everyone-rules-md.js.map +1 -0
- package/dist/generators/noProjectionAssets.d.ts +15 -0
- package/dist/generators/noProjectionAssets.d.ts.map +1 -0
- package/dist/generators/noProjectionAssets.js +6 -0
- package/dist/generators/noProjectionAssets.js.map +1 -0
- package/dist/generators/portable-knowledge.d.ts +9 -26
- package/dist/generators/portable-knowledge.d.ts.map +1 -1
- package/dist/generators/portable-knowledge.js +11 -125
- package/dist/generators/portable-knowledge.js.map +1 -1
- package/dist/generators/portable-knowledge.test.js +82 -267
- package/dist/generators/portable-knowledge.test.js.map +1 -1
- package/dist/generators/region-projections.d.ts +0 -1
- package/dist/generators/region-projections.d.ts.map +1 -1
- package/dist/generators/region-projections.js +7 -5
- package/dist/generators/region-projections.js.map +1 -1
- package/dist/generators/region-projections.test.js +10 -15
- package/dist/generators/region-projections.test.js.map +1 -1
- package/dist/generators/retired-projections.d.ts +12 -0
- package/dist/generators/retired-projections.d.ts.map +1 -0
- package/dist/generators/retired-projections.js +75 -0
- package/dist/generators/retired-projections.js.map +1 -0
- package/dist/generators/retired-projections.test.d.ts +2 -0
- package/dist/generators/retired-projections.test.d.ts.map +1 -0
- package/dist/generators/retired-projections.test.js +64 -0
- package/dist/generators/retired-projections.test.js.map +1 -0
- package/dist/handleCliError.d.ts +2 -0
- package/dist/handleCliError.d.ts.map +1 -0
- package/dist/handleCliError.js +56 -0
- package/dist/handleCliError.js.map +1 -0
- package/dist/index.d.ts +0 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +185 -541
- package/dist/index.js.map +1 -1
- package/dist/lib/__tests__/legalRelationTypes.test.d.ts +2 -0
- package/dist/lib/__tests__/legalRelationTypes.test.d.ts.map +1 -0
- package/dist/lib/__tests__/legalRelationTypes.test.js +61 -0
- package/dist/lib/__tests__/legalRelationTypes.test.js.map +1 -0
- package/dist/lib/__tests__/parseFields.test.d.ts +2 -0
- package/dist/lib/__tests__/parseFields.test.d.ts.map +1 -0
- package/dist/lib/__tests__/parseFields.test.js +40 -0
- package/dist/lib/__tests__/parseFields.test.js.map +1 -0
- package/dist/lib/adminConfig.d.ts +48 -0
- package/dist/lib/adminConfig.d.ts.map +1 -0
- package/dist/lib/adminConfig.js +130 -0
- package/dist/lib/adminConfig.js.map +1 -0
- package/dist/lib/canonicalRefs.d.ts +27 -8
- package/dist/lib/canonicalRefs.d.ts.map +1 -1
- package/dist/lib/canonicalRefs.js +25 -6
- package/dist/lib/canonicalRefs.js.map +1 -1
- package/dist/lib/captureGrounding.d.ts +48 -0
- package/dist/lib/captureGrounding.d.ts.map +1 -0
- package/dist/lib/captureGrounding.js +54 -0
- package/dist/lib/captureGrounding.js.map +1 -0
- package/dist/lib/captureGrounding.test.d.ts +2 -0
- package/dist/lib/captureGrounding.test.d.ts.map +1 -0
- package/dist/lib/captureGrounding.test.js +74 -0
- package/dist/lib/captureGrounding.test.js.map +1 -0
- package/dist/lib/captureLink.d.ts +26 -0
- package/dist/lib/captureLink.d.ts.map +1 -0
- package/dist/lib/captureLink.js +110 -0
- package/dist/lib/captureLink.js.map +1 -0
- package/dist/lib/checklist.d.ts +32 -0
- package/dist/lib/checklist.d.ts.map +1 -0
- package/dist/lib/checklist.js +77 -0
- package/dist/lib/checklist.js.map +1 -0
- package/dist/lib/client.d.ts +46 -19
- package/dist/lib/client.d.ts.map +1 -1
- package/dist/lib/client.js +221 -66
- package/dist/lib/client.js.map +1 -1
- package/dist/lib/collectionRegistry.d.ts +40 -5
- package/dist/lib/collectionRegistry.d.ts.map +1 -1
- package/dist/lib/collectionRegistry.js +71 -48
- package/dist/lib/collectionRegistry.js.map +1 -1
- package/dist/lib/commanderOptions.d.ts +8 -0
- package/dist/lib/commanderOptions.d.ts.map +1 -0
- package/dist/lib/commanderOptions.js +10 -0
- package/dist/lib/commanderOptions.js.map +1 -0
- package/dist/lib/compose-wrapup-view.d.ts +48 -0
- package/dist/lib/compose-wrapup-view.d.ts.map +1 -0
- package/dist/lib/compose-wrapup-view.js +37 -0
- package/dist/lib/compose-wrapup-view.js.map +1 -0
- package/dist/lib/config.d.ts +65 -102
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +164 -286
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/configResult.d.ts +102 -0
- package/dist/lib/configResult.d.ts.map +1 -0
- package/dist/lib/configResult.js +179 -0
- package/dist/lib/configResult.js.map +1 -0
- package/dist/lib/connectProfileName.d.ts +36 -0
- package/dist/lib/connectProfileName.d.ts.map +1 -0
- package/dist/lib/connectProfileName.js +72 -0
- package/dist/lib/connectProfileName.js.map +1 -0
- package/dist/lib/connectProfileName.test.d.ts +2 -0
- package/dist/lib/connectProfileName.test.d.ts.map +1 -0
- package/dist/lib/connectProfileName.test.js +100 -0
- package/dist/lib/connectProfileName.test.js.map +1 -0
- package/dist/lib/constants.d.ts +3 -1
- package/dist/lib/constants.d.ts.map +1 -1
- package/dist/lib/constants.js +6 -1
- package/dist/lib/constants.js.map +1 -1
- package/dist/lib/conversation.d.ts +36 -0
- package/dist/lib/conversation.d.ts.map +1 -0
- package/dist/lib/conversation.js +66 -0
- package/dist/lib/conversation.js.map +1 -0
- package/dist/lib/createEntryResult.d.ts +34 -0
- package/dist/lib/createEntryResult.d.ts.map +1 -0
- package/dist/lib/createEntryResult.js +12 -0
- package/dist/lib/createEntryResult.js.map +1 -0
- package/dist/lib/deployment.js +2 -2
- package/dist/lib/deployment.js.map +1 -1
- package/dist/lib/deployment.test.js +20 -1
- package/dist/lib/deployment.test.js.map +1 -1
- package/dist/lib/envKeySnapshot.d.ts +10 -0
- package/dist/lib/envKeySnapshot.d.ts.map +1 -0
- package/dist/lib/envKeySnapshot.js +30 -0
- package/dist/lib/envKeySnapshot.js.map +1 -0
- package/dist/lib/errors.d.ts +90 -0
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/errors.js +83 -0
- package/dist/lib/errors.js.map +1 -1
- package/dist/lib/frontmatter.d.ts +55 -0
- package/dist/lib/frontmatter.d.ts.map +1 -0
- package/dist/lib/frontmatter.js +92 -0
- package/dist/lib/frontmatter.js.map +1 -0
- package/dist/lib/frontmatter.test.d.ts +15 -0
- package/dist/lib/frontmatter.test.d.ts.map +1 -0
- package/dist/lib/frontmatter.test.js +98 -0
- package/dist/lib/frontmatter.test.js.map +1 -0
- package/dist/lib/gatewayTimeout.d.ts +88 -0
- package/dist/lib/gatewayTimeout.d.ts.map +1 -0
- package/dist/lib/gatewayTimeout.js +118 -0
- package/dist/lib/gatewayTimeout.js.map +1 -0
- package/dist/lib/gitEnvLeakKeysParity.test.d.ts +2 -0
- package/dist/lib/gitEnvLeakKeysParity.test.d.ts.map +1 -0
- package/dist/lib/gitEnvLeakKeysParity.test.js +73 -0
- package/dist/lib/gitEnvLeakKeysParity.test.js.map +1 -0
- package/dist/lib/glossary.js +1 -1
- package/dist/lib/glossary.js.map +1 -1
- package/dist/lib/hook-intents.js +3 -3
- package/dist/lib/hook-intents.js.map +1 -1
- package/dist/lib/judgeWait.d.ts +50 -0
- package/dist/lib/judgeWait.d.ts.map +1 -0
- package/dist/lib/judgeWait.js +64 -0
- package/dist/lib/judgeWait.js.map +1 -0
- package/dist/lib/kernelEnvelope.d.ts +42 -0
- package/dist/lib/kernelEnvelope.d.ts.map +1 -0
- package/dist/lib/kernelEnvelope.js +67 -0
- package/dist/lib/kernelEnvelope.js.map +1 -0
- package/dist/lib/legalRelationTypes.d.ts +19 -0
- package/dist/lib/legalRelationTypes.d.ts.map +1 -0
- package/dist/lib/legalRelationTypes.js +64 -0
- package/dist/lib/legalRelationTypes.js.map +1 -0
- package/dist/lib/localBinding.d.ts +86 -0
- package/dist/lib/localBinding.d.ts.map +1 -0
- package/dist/lib/localBinding.js +173 -0
- package/dist/lib/localBinding.js.map +1 -0
- package/dist/lib/method-registry.d.ts +16 -11
- package/dist/lib/method-registry.d.ts.map +1 -1
- package/dist/lib/method-registry.js +13 -25
- package/dist/lib/method-registry.js.map +1 -1
- package/dist/lib/normalizeMaterializedFilename.d.ts +3 -3
- package/dist/lib/normalizeMaterializedFilename.js +3 -3
- package/dist/lib/notice-marker.d.ts.map +1 -1
- package/dist/lib/notice-marker.js +186 -16
- package/dist/lib/notice-marker.js.map +1 -1
- package/dist/lib/onboarding-path-b.d.ts.map +1 -1
- package/dist/lib/onboarding-path-b.js +39 -14
- package/dist/lib/onboarding-path-b.js.map +1 -1
- package/dist/lib/onboarding-shared.d.ts +27 -4
- package/dist/lib/onboarding-shared.d.ts.map +1 -1
- package/dist/lib/onboarding-shared.js +54 -20
- package/dist/lib/onboarding-shared.js.map +1 -1
- package/dist/lib/onboarding-shared.test.d.ts +2 -0
- package/dist/lib/onboarding-shared.test.d.ts.map +1 -0
- package/dist/lib/onboarding-shared.test.js +131 -0
- package/dist/lib/onboarding-shared.test.js.map +1 -0
- package/dist/lib/onboarding-topics.js +1 -1
- package/dist/lib/onboarding.d.ts +5 -1
- package/dist/lib/onboarding.d.ts.map +1 -1
- package/dist/lib/onboarding.js +62 -25
- package/dist/lib/onboarding.js.map +1 -1
- package/dist/lib/ownerLine.d.ts +73 -0
- package/dist/lib/ownerLine.d.ts.map +1 -0
- package/dist/lib/ownerLine.js +57 -0
- package/dist/lib/ownerLine.js.map +1 -0
- package/dist/lib/parseFields.d.ts +19 -0
- package/dist/lib/parseFields.d.ts.map +1 -0
- package/dist/lib/parseFields.js +49 -0
- package/dist/lib/parseFields.js.map +1 -0
- package/dist/lib/pinnedRole.d.ts +28 -0
- package/dist/lib/pinnedRole.d.ts.map +1 -0
- package/dist/lib/pinnedRole.js +105 -0
- package/dist/lib/pinnedRole.js.map +1 -0
- package/dist/lib/platformGlossary.d.ts +19 -0
- package/dist/lib/platformGlossary.d.ts.map +1 -0
- package/dist/lib/platformGlossary.js +21 -0
- package/dist/lib/platformGlossary.js.map +1 -0
- package/dist/lib/previewBanner.d.ts +9 -0
- package/dist/lib/previewBanner.d.ts.map +1 -0
- package/dist/lib/previewBanner.js +37 -0
- package/dist/lib/previewBanner.js.map +1 -0
- package/dist/lib/productbrain-files.d.ts +108 -0
- package/dist/lib/productbrain-files.d.ts.map +1 -0
- package/dist/lib/productbrain-files.js +240 -0
- package/dist/lib/productbrain-files.js.map +1 -0
- package/dist/lib/productbrain-files.test.d.ts +2 -0
- package/dist/lib/productbrain-files.test.d.ts.map +1 -0
- package/dist/lib/productbrain-files.test.js +518 -0
- package/dist/lib/productbrain-files.test.js.map +1 -0
- package/dist/lib/profiles.d.ts +52 -4
- package/dist/lib/profiles.d.ts.map +1 -1
- package/dist/lib/profiles.js +72 -21
- package/dist/lib/profiles.js.map +1 -1
- package/dist/lib/projectConfig.d.ts +96 -0
- package/dist/lib/projectConfig.d.ts.map +1 -0
- package/dist/lib/projectConfig.js +185 -0
- package/dist/lib/projectConfig.js.map +1 -0
- package/dist/lib/prompts.d.ts +2 -0
- package/dist/lib/prompts.d.ts.map +1 -1
- package/dist/lib/prompts.js +2 -0
- package/dist/lib/prompts.js.map +1 -1
- package/dist/lib/proseBody.d.ts +14 -0
- package/dist/lib/proseBody.d.ts.map +1 -0
- package/dist/lib/proseBody.js +25 -0
- package/dist/lib/proseBody.js.map +1 -0
- package/dist/lib/rate-limit.d.ts +38 -0
- package/dist/lib/rate-limit.d.ts.map +1 -0
- package/dist/lib/rate-limit.js +83 -0
- package/dist/lib/rate-limit.js.map +1 -0
- package/dist/lib/readinessNotices.d.ts +12 -0
- package/dist/lib/readinessNotices.d.ts.map +1 -0
- package/dist/lib/readinessNotices.js +15 -0
- package/dist/lib/readinessNotices.js.map +1 -0
- package/dist/lib/repo-detect.d.ts +8 -2
- package/dist/lib/repo-detect.d.ts.map +1 -1
- package/dist/lib/repo-detect.js +11 -6
- package/dist/lib/repo-detect.js.map +1 -1
- package/dist/lib/reportedProfile.d.ts +18 -0
- package/dist/lib/reportedProfile.d.ts.map +1 -0
- package/dist/lib/reportedProfile.js +144 -0
- package/dist/lib/reportedProfile.js.map +1 -0
- package/dist/lib/ruleListRender.d.ts +188 -0
- package/dist/lib/ruleListRender.d.ts.map +1 -0
- package/dist/lib/ruleListRender.js +273 -0
- package/dist/lib/ruleListRender.js.map +1 -0
- package/dist/lib/runner.d.ts +9 -1
- package/dist/lib/runner.d.ts.map +1 -1
- package/dist/lib/runner.js +30 -4
- package/dist/lib/runner.js.map +1 -1
- package/dist/lib/seatSentence.d.ts +42 -0
- package/dist/lib/seatSentence.d.ts.map +1 -0
- package/dist/lib/seatSentence.js +25 -0
- package/dist/lib/seatSentence.js.map +1 -0
- package/dist/lib/session.d.ts +86 -12
- package/dist/lib/session.d.ts.map +1 -1
- package/dist/lib/session.js +255 -25
- package/dist/lib/session.js.map +1 -1
- package/dist/lib/sessionBinding.d.ts +61 -0
- package/dist/lib/sessionBinding.d.ts.map +1 -0
- package/dist/lib/sessionBinding.js +125 -0
- package/dist/lib/sessionBinding.js.map +1 -0
- package/dist/lib/sessionNotices.d.ts +54 -0
- package/dist/lib/sessionNotices.d.ts.map +1 -0
- package/dist/lib/sessionNotices.js +130 -0
- package/dist/lib/sessionNotices.js.map +1 -0
- package/dist/lib/sessionNotices.test.d.ts +2 -0
- package/dist/lib/sessionNotices.test.d.ts.map +1 -0
- package/dist/lib/sessionNotices.test.js +55 -0
- package/dist/lib/sessionNotices.test.js.map +1 -0
- package/dist/lib/spineVerdictRead.d.ts +70 -0
- package/dist/lib/spineVerdictRead.d.ts.map +1 -0
- package/dist/lib/spineVerdictRead.js +73 -0
- package/dist/lib/spineVerdictRead.js.map +1 -0
- package/dist/lib/spinner.js +2 -2
- package/dist/lib/spinner.js.map +1 -1
- package/dist/lib/startup-resolution-signals.d.ts +34 -0
- package/dist/lib/startup-resolution-signals.d.ts.map +1 -0
- package/dist/lib/startup-resolution-signals.js +116 -0
- package/dist/lib/startup-resolution-signals.js.map +1 -0
- package/dist/lib/startup-resolution-signals.test.d.ts +2 -0
- package/dist/lib/startup-resolution-signals.test.d.ts.map +1 -0
- package/dist/lib/startup-resolution-signals.test.js +113 -0
- package/dist/lib/startup-resolution-signals.test.js.map +1 -0
- package/dist/lib/startup-signals.d.ts +12 -0
- package/dist/lib/startup-signals.d.ts.map +1 -0
- package/dist/lib/startup-signals.js +179 -0
- package/dist/lib/startup-signals.js.map +1 -0
- package/dist/lib/startup-signals.test.d.ts +2 -0
- package/dist/lib/startup-signals.test.d.ts.map +1 -0
- package/dist/lib/startup-signals.test.js +165 -0
- package/dist/lib/startup-signals.test.js.map +1 -0
- package/dist/lib/state.d.ts +11 -2
- package/dist/lib/state.d.ts.map +1 -1
- package/dist/lib/state.js +11 -4
- package/dist/lib/state.js.map +1 -1
- package/dist/lib/statusCategories.d.ts +160 -0
- package/dist/lib/statusCategories.d.ts.map +1 -0
- package/dist/lib/statusCategories.js +284 -0
- package/dist/lib/statusCategories.js.map +1 -0
- package/dist/lib/strip.d.ts +17 -0
- package/dist/lib/strip.d.ts.map +1 -1
- package/dist/lib/strip.js +48 -1
- package/dist/lib/strip.js.map +1 -1
- package/dist/lib/style.d.ts +8 -2
- package/dist/lib/style.d.ts.map +1 -1
- package/dist/lib/style.js +24 -17
- package/dist/lib/style.js.map +1 -1
- package/dist/lib/tokenConstants.d.ts +2 -0
- package/dist/lib/tokenConstants.d.ts.map +1 -1
- package/dist/lib/tokenConstants.js +2 -0
- package/dist/lib/tokenConstants.js.map +1 -1
- package/dist/lib/workspaceNotice.d.ts +202 -0
- package/dist/lib/workspaceNotice.d.ts.map +1 -0
- package/dist/lib/workspaceNotice.js +345 -0
- package/dist/lib/workspaceNotice.js.map +1 -0
- package/dist/{setup/perimeter.d.ts → lib/writePerimeter.d.ts} +11 -11
- package/dist/lib/writePerimeter.d.ts.map +1 -0
- package/dist/{setup/perimeter.js → lib/writePerimeter.js} +11 -11
- package/dist/lib/writePerimeter.js.map +1 -0
- package/dist/registerEntryCommands.d.ts +18 -0
- package/dist/registerEntryCommands.d.ts.map +1 -0
- package/dist/registerEntryCommands.js +123 -0
- package/dist/registerEntryCommands.js.map +1 -0
- package/dist/registerHistoryCommand.d.ts +8 -0
- package/dist/registerHistoryCommand.d.ts.map +1 -0
- package/dist/registerHistoryCommand.js +14 -0
- package/dist/registerHistoryCommand.js.map +1 -0
- package/dist/registerOutcomeCommands.d.ts +27 -0
- package/dist/registerOutcomeCommands.d.ts.map +1 -0
- package/dist/registerOutcomeCommands.js +27 -0
- package/dist/registerOutcomeCommands.js.map +1 -0
- package/dist/registerRoleCommands.d.ts +11 -0
- package/dist/registerRoleCommands.d.ts.map +1 -0
- package/dist/registerRoleCommands.js +38 -0
- package/dist/registerRoleCommands.js.map +1 -0
- package/dist/registerTensionsCommands.d.ts +10 -0
- package/dist/registerTensionsCommands.d.ts.map +1 -0
- package/dist/registerTensionsCommands.js +15 -0
- package/dist/registerTensionsCommands.js.map +1 -0
- package/dist/scoreboard/diagnose.d.ts +190 -0
- package/dist/scoreboard/diagnose.d.ts.map +1 -0
- package/dist/scoreboard/diagnose.js +282 -0
- package/dist/scoreboard/diagnose.js.map +1 -0
- package/dist/scoreboard/diagnose.test.d.ts +15 -0
- package/dist/scoreboard/diagnose.test.d.ts.map +1 -0
- package/dist/scoreboard/diagnose.test.js +288 -0
- package/dist/scoreboard/diagnose.test.js.map +1 -0
- package/dist/scoreboard/floors.d.ts +47 -0
- package/dist/scoreboard/floors.d.ts.map +1 -0
- package/dist/scoreboard/floors.js +33 -0
- package/dist/scoreboard/floors.js.map +1 -0
- package/dist/scoreboard/localDrift.d.ts +23 -0
- package/dist/scoreboard/localDrift.d.ts.map +1 -0
- package/dist/scoreboard/localDrift.js +111 -0
- package/dist/scoreboard/localDrift.js.map +1 -0
- package/dist/scoreboard/localDrift.test.d.ts +9 -0
- package/dist/scoreboard/localDrift.test.d.ts.map +1 -0
- package/dist/scoreboard/localDrift.test.js +82 -0
- package/dist/scoreboard/localDrift.test.js.map +1 -0
- package/dist/surfaces/__tests__/adapter.test.js +2 -6
- package/dist/surfaces/__tests__/adapter.test.js.map +1 -1
- package/dist/surfaces/__tests__/claude-skill-pointer-drift.test.d.ts +2 -0
- package/dist/surfaces/__tests__/claude-skill-pointer-drift.test.d.ts.map +1 -0
- package/dist/surfaces/__tests__/claude-skill-pointer-drift.test.js +179 -0
- package/dist/surfaces/__tests__/claude-skill-pointer-drift.test.js.map +1 -0
- package/dist/surfaces/adapters/claude.d.ts.map +1 -1
- package/dist/surfaces/adapters/claude.js +30 -25
- package/dist/surfaces/adapters/claude.js.map +1 -1
- package/package.json +9 -7
- package/dist/__tests__/audit.test.d.ts +0 -2
- package/dist/__tests__/audit.test.d.ts.map +0 -1
- package/dist/__tests__/audit.test.js +0 -399
- package/dist/__tests__/audit.test.js.map +0 -1
- package/dist/__tests__/authority-domains.test.d.ts +0 -2
- package/dist/__tests__/authority-domains.test.d.ts.map +0 -1
- package/dist/__tests__/authority-domains.test.js +0 -48
- package/dist/__tests__/authority-domains.test.js.map +0 -1
- package/dist/__tests__/promote.test.d.ts +0 -2
- package/dist/__tests__/promote.test.d.ts.map +0 -1
- package/dist/__tests__/promote.test.js +0 -230
- package/dist/__tests__/promote.test.js.map +0 -1
- package/dist/__tests__/proposals.test.d.ts +0 -2
- package/dist/__tests__/proposals.test.d.ts.map +0 -1
- package/dist/__tests__/proposals.test.js +0 -167
- package/dist/__tests__/proposals.test.js.map +0 -1
- package/dist/__tests__/setup-ingest.test.d.ts +0 -2
- package/dist/__tests__/setup-ingest.test.d.ts.map +0 -1
- package/dist/__tests__/setup-ingest.test.js +0 -71
- package/dist/__tests__/setup-ingest.test.js.map +0 -1
- package/dist/__tests__/setup-resolver.test.d.ts +0 -14
- package/dist/__tests__/setup-resolver.test.d.ts.map +0 -1
- package/dist/__tests__/setup-resolver.test.js +0 -228
- package/dist/__tests__/setup-resolver.test.js.map +0 -1
- package/dist/commands/__tests__/setup-detect-surfaces.test.d.ts +0 -15
- package/dist/commands/__tests__/setup-detect-surfaces.test.d.ts.map +0 -1
- package/dist/commands/__tests__/setup-detect-surfaces.test.js +0 -149
- package/dist/commands/__tests__/setup-detect-surfaces.test.js.map +0 -1
- package/dist/commands/__tests__/setup-state.test.d.ts +0 -2
- package/dist/commands/__tests__/setup-state.test.d.ts.map +0 -1
- package/dist/commands/__tests__/setup-state.test.js +0 -194
- package/dist/commands/__tests__/setup-state.test.js.map +0 -1
- package/dist/commands/accept.d.ts +0 -18
- package/dist/commands/accept.d.ts.map +0 -1
- package/dist/commands/accept.js +0 -76
- package/dist/commands/accept.js.map +0 -1
- package/dist/commands/audit.d.ts +0 -25
- package/dist/commands/audit.d.ts.map +0 -1
- package/dist/commands/audit.js +0 -215
- package/dist/commands/audit.js.map +0 -1
- package/dist/commands/authority-domains.d.ts +0 -146
- package/dist/commands/authority-domains.d.ts.map +0 -1
- package/dist/commands/authority-domains.js +0 -282
- package/dist/commands/authority-domains.js.map +0 -1
- package/dist/commands/method.d.ts +0 -99
- package/dist/commands/method.d.ts.map +0 -1
- package/dist/commands/method.js +0 -784
- package/dist/commands/method.js.map +0 -1
- package/dist/commands/migrate-setup.d.ts +0 -18
- package/dist/commands/migrate-setup.d.ts.map +0 -1
- package/dist/commands/migrate-setup.js +0 -198
- package/dist/commands/migrate-setup.js.map +0 -1
- package/dist/commands/promote.d.ts +0 -12
- package/dist/commands/promote.d.ts.map +0 -1
- package/dist/commands/promote.js +0 -113
- package/dist/commands/promote.js.map +0 -1
- package/dist/commands/proposals.d.ts +0 -9
- package/dist/commands/proposals.d.ts.map +0 -1
- package/dist/commands/proposals.js +0 -24
- package/dist/commands/proposals.js.map +0 -1
- package/dist/commands/reject.d.ts +0 -14
- package/dist/commands/reject.d.ts.map +0 -1
- package/dist/commands/reject.js +0 -43
- package/dist/commands/reject.js.map +0 -1
- package/dist/commands/setup-audit.d.ts +0 -59
- package/dist/commands/setup-audit.d.ts.map +0 -1
- package/dist/commands/setup-audit.js +0 -250
- package/dist/commands/setup-audit.js.map +0 -1
- package/dist/commands/setup-detect-surfaces.d.ts +0 -38
- package/dist/commands/setup-detect-surfaces.d.ts.map +0 -1
- package/dist/commands/setup-detect-surfaces.js +0 -76
- package/dist/commands/setup-detect-surfaces.js.map +0 -1
- package/dist/commands/setup-ingest.d.ts +0 -17
- package/dist/commands/setup-ingest.d.ts.map +0 -1
- package/dist/commands/setup-ingest.js +0 -226
- package/dist/commands/setup-ingest.js.map +0 -1
- package/dist/commands/setup-resolver.d.ts +0 -58
- package/dist/commands/setup-resolver.d.ts.map +0 -1
- package/dist/commands/setup-resolver.js +0 -150
- package/dist/commands/setup-resolver.js.map +0 -1
- package/dist/commands/setup-state.d.ts +0 -42
- package/dist/commands/setup-state.d.ts.map +0 -1
- package/dist/commands/setup-state.js +0 -93
- package/dist/commands/setup-state.js.map +0 -1
- package/dist/commands/setup.d.ts +0 -23
- package/dist/commands/setup.d.ts.map +0 -1
- package/dist/commands/setup.js +0 -69
- package/dist/commands/setup.js.map +0 -1
- package/dist/formatters/audit.d.ts +0 -52
- package/dist/formatters/audit.d.ts.map +0 -1
- package/dist/formatters/audit.js +0 -81
- package/dist/formatters/audit.js.map +0 -1
- package/dist/formatters/promote.d.ts +0 -30
- package/dist/formatters/promote.d.ts.map +0 -1
- package/dist/formatters/promote.js +0 -39
- package/dist/formatters/promote.js.map +0 -1
- package/dist/formatters/proposals.d.ts +0 -45
- package/dist/formatters/proposals.d.ts.map +0 -1
- package/dist/formatters/proposals.js +0 -62
- package/dist/formatters/proposals.js.map +0 -1
- package/dist/generators/archetypes.d.ts +0 -52
- package/dist/generators/archetypes.d.ts.map +0 -1
- package/dist/generators/archetypes.js +0 -153
- package/dist/generators/archetypes.js.map +0 -1
- package/dist/generators/archetypes.test.d.ts +0 -2
- package/dist/generators/archetypes.test.d.ts.map +0 -1
- package/dist/generators/archetypes.test.js +0 -237
- package/dist/generators/archetypes.test.js.map +0 -1
- package/dist/generators/chain-classifier.d.ts +0 -49
- package/dist/generators/chain-classifier.d.ts.map +0 -1
- package/dist/generators/chain-classifier.js +0 -180
- package/dist/generators/chain-classifier.js.map +0 -1
- package/dist/generators/chain-classifier.test.d.ts +0 -2
- package/dist/generators/chain-classifier.test.d.ts.map +0 -1
- package/dist/generators/chain-classifier.test.js +0 -257
- package/dist/generators/chain-classifier.test.js.map +0 -1
- package/dist/generators/chain-rules.d.ts +0 -42
- package/dist/generators/chain-rules.d.ts.map +0 -1
- package/dist/generators/chain-rules.js +0 -144
- package/dist/generators/chain-rules.js.map +0 -1
- package/dist/generators/chain-rules.test.d.ts +0 -2
- package/dist/generators/chain-rules.test.d.ts.map +0 -1
- package/dist/generators/chain-rules.test.js +0 -179
- package/dist/generators/chain-rules.test.js.map +0 -1
- package/dist/generators/handshake-diff.d.ts +0 -67
- package/dist/generators/handshake-diff.d.ts.map +0 -1
- package/dist/generators/handshake-diff.js +0 -183
- package/dist/generators/handshake-diff.js.map +0 -1
- package/dist/generators/handshake-diff.test.d.ts +0 -2
- package/dist/generators/handshake-diff.test.d.ts.map +0 -1
- package/dist/generators/handshake-diff.test.js +0 -264
- package/dist/generators/handshake-diff.test.js.map +0 -1
- package/dist/lib/activation.d.ts +0 -28
- package/dist/lib/activation.d.ts.map +0 -1
- package/dist/lib/activation.js +0 -57
- package/dist/lib/activation.js.map +0 -1
- package/dist/lib/activation.test.d.ts +0 -6
- package/dist/lib/activation.test.d.ts.map +0 -1
- package/dist/lib/activation.test.js +0 -121
- package/dist/lib/activation.test.js.map +0 -1
- package/dist/lib/inferSourceDate.d.ts +0 -12
- package/dist/lib/inferSourceDate.d.ts.map +0 -1
- package/dist/lib/inferSourceDate.js +0 -44
- package/dist/lib/inferSourceDate.js.map +0 -1
- package/dist/setup/__tests__/coach-traces.test.d.ts +0 -2
- package/dist/setup/__tests__/coach-traces.test.d.ts.map +0 -1
- package/dist/setup/__tests__/coach-traces.test.js +0 -189
- package/dist/setup/__tests__/coach-traces.test.js.map +0 -1
- package/dist/setup/__tests__/setup-commands.test.d.ts +0 -2
- package/dist/setup/__tests__/setup-commands.test.d.ts.map +0 -1
- package/dist/setup/__tests__/setup-commands.test.js +0 -177
- package/dist/setup/__tests__/setup-commands.test.js.map +0 -1
- package/dist/setup/__tests__/state-machine.test.d.ts +0 -2
- package/dist/setup/__tests__/state-machine.test.d.ts.map +0 -1
- package/dist/setup/__tests__/state-machine.test.js +0 -341
- package/dist/setup/__tests__/state-machine.test.js.map +0 -1
- package/dist/setup/detect-surfaces.d.ts +0 -21
- package/dist/setup/detect-surfaces.d.ts.map +0 -1
- package/dist/setup/detect-surfaces.js +0 -39
- package/dist/setup/detect-surfaces.js.map +0 -1
- package/dist/setup/manifest-writer.d.ts +0 -17
- package/dist/setup/manifest-writer.d.ts.map +0 -1
- package/dist/setup/manifest-writer.js +0 -153
- package/dist/setup/manifest-writer.js.map +0 -1
- package/dist/setup/perimeter.d.ts.map +0 -1
- package/dist/setup/perimeter.js.map +0 -1
- package/dist/setup/state-machine.d.ts +0 -67
- package/dist/setup/state-machine.d.ts.map +0 -1
- package/dist/setup/state-machine.js +0 -124
- package/dist/setup/state-machine.js.map +0 -1
- package/dist/surfaces/__tests__/pb-setup-passthrough.test.d.ts +0 -2
- package/dist/surfaces/__tests__/pb-setup-passthrough.test.d.ts.map +0 -1
- package/dist/surfaces/__tests__/pb-setup-passthrough.test.js +0 -132
- package/dist/surfaces/__tests__/pb-setup-passthrough.test.js.map +0 -1
- package/templates/archetypes/boundary.md +0 -23
- package/templates/archetypes/constraint.md +0 -23
- package/templates/archetypes/convention.md +0 -23
- package/templates/archetypes/policy.md +0 -23
- package/templates/archetypes/quality-gate.md +0 -23
- package/templates/archetypes/workflow.md +0 -23
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* pb capture extensions — --link, --json flags, WP-319 grounding.
|
|
3
3
|
* TEN-341 test contract: capture --link calls createEntryRelation, capture --json outputs JSON.
|
|
4
|
-
* WP-319 S3: grounding fires in parallel, fail-open, --
|
|
4
|
+
* WP-319 S3: grounding fires in parallel, fail-open, --strict, PB_GROUNDING_MODE.
|
|
5
5
|
*/
|
|
6
|
-
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
6
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
7
7
|
import { runCapture } from '../commands/capture.js';
|
|
8
|
+
import { formatCaptureReceipt } from '../formatters/capture.js';
|
|
9
|
+
import { CLIError, ErrorCode } from '../lib/errors.js';
|
|
10
|
+
import { setOutputMode } from '../lib/runner.js';
|
|
8
11
|
const kernelCallWithSessionMock = vi.fn();
|
|
9
12
|
vi.mock('../lib/client.js', () => ({
|
|
10
13
|
kernelCallWithSession: (...args) => kernelCallWithSessionMock(...args),
|
|
@@ -22,119 +25,1237 @@ describe('runCapture --link', () => {
|
|
|
22
25
|
kernelCallWithSessionMock.mockReset();
|
|
23
26
|
mockSession = { sessionId: 'sess-test' };
|
|
24
27
|
});
|
|
25
|
-
|
|
26
|
-
|
|
28
|
+
// WP-688 S4 (TASK-105, element 11): --link with no --link-type no longer defaults to
|
|
29
|
+
// surfaces_tension_in — it refuses instead. The capture itself still succeeds (createEntry
|
|
30
|
+
// ran for real); only the relation write is skipped, replaced by a PREVIEW probe used to
|
|
31
|
+
// list the source entry's legal verbs in the refusal message.
|
|
32
|
+
it('--link without --link-type refuses (no default), preserving the created entry', async () => {
|
|
33
|
+
kernelCallWithSessionMock.mockImplementation((fn, args) => {
|
|
34
|
+
if (fn === 'chain.capture')
|
|
35
|
+
return Promise.resolve(null);
|
|
36
|
+
if (fn === 'chain.createEntry')
|
|
37
|
+
return Promise.resolve({ docId: 'doc-1', entryId: 'TEN-710' });
|
|
38
|
+
if (fn === 'chain.getEntry') {
|
|
39
|
+
const entryId = args?.entryId;
|
|
40
|
+
if (entryId === 'TEN-710')
|
|
41
|
+
return Promise.resolve({ entryId: 'TEN-710', name: 'x', status: 'draft', canonicalKey: 'tension' });
|
|
42
|
+
return Promise.resolve(null);
|
|
43
|
+
}
|
|
44
|
+
// bdABL: the type row is resolved by scanning the semantic-types collection and
|
|
45
|
+
// matching on data.canonical_key — NOT by guessing entryId === `TYPE-<key>`. This
|
|
46
|
+
// row deliberately uses a non-conventional entryId (`ST-1`) to prove that.
|
|
47
|
+
if (fn === 'chain.listEntries') {
|
|
48
|
+
return Promise.resolve([{ entryId: 'ST-1', name: 'tension', status: 'active', data: { canonical_key: 'tension', valid_relation_types: ['related_to', 'depends_on', 'surfaces_tension_in'], description: 'x', cardinality_rule: 'multiple' } }]);
|
|
49
|
+
}
|
|
50
|
+
return Promise.resolve({});
|
|
51
|
+
});
|
|
52
|
+
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
53
|
+
await expect(runCapture({ text: 'TEN: missing validation', link: 'BET-151' })).rejects.toThrow(CLIError);
|
|
54
|
+
// The entry was created for real — only the LINK is refused.
|
|
55
|
+
expect(kernelCallWithSessionMock).toHaveBeenCalledWith('chain.createEntry', expect.objectContaining({
|
|
56
|
+
collectionSlug: 'tensions',
|
|
57
|
+
name: 'missing validation',
|
|
58
|
+
}));
|
|
59
|
+
// Legal verbs are READ by scanning the semantic-types collection (chain.listEntries)
|
|
60
|
+
// and matching data.canonical_key — the same resolution loadTypeMap itself uses,
|
|
61
|
+
// never a probe, never a guessed entryId.
|
|
62
|
+
expect(kernelCallWithSessionMock).toHaveBeenCalledWith('chain.getEntry', { entryId: 'TEN-710' });
|
|
63
|
+
expect(kernelCallWithSessionMock).toHaveBeenCalledWith('chain.listEntries', { collectionSlug: 'semantic-types' });
|
|
64
|
+
// Never a createEntryRelation call at all — a real write, preview, or probe.
|
|
65
|
+
expect(kernelCallWithSessionMock).not.toHaveBeenCalledWith('chain.createEntryRelation', expect.anything());
|
|
66
|
+
writeSpy.mockRestore();
|
|
67
|
+
});
|
|
68
|
+
it('--link without --link-type: refusal message lists the source entry\'s declared relation types', async () => {
|
|
69
|
+
kernelCallWithSessionMock.mockImplementation((fn, args) => {
|
|
70
|
+
if (fn === 'chain.capture')
|
|
71
|
+
return Promise.resolve(null);
|
|
72
|
+
if (fn === 'chain.createEntry')
|
|
73
|
+
return Promise.resolve({ docId: 'doc-1b', entryId: 'TEN-711' });
|
|
74
|
+
if (fn === 'chain.getEntry') {
|
|
75
|
+
const entryId = args?.entryId;
|
|
76
|
+
if (entryId === 'TEN-711')
|
|
77
|
+
return Promise.resolve({ entryId: 'TEN-711', name: 'x', status: 'draft', canonicalKey: 'tension' });
|
|
78
|
+
// bcRUMR: the target must actually resolve for this test to exercise the
|
|
79
|
+
// pb-relate-guidance branch rather than the target-missing branch.
|
|
80
|
+
if (entryId === 'BET-151')
|
|
81
|
+
return Promise.resolve({ entryId: 'BET-151', name: 'y', status: 'active', canonicalKey: 'work_package' });
|
|
82
|
+
return Promise.resolve(null);
|
|
83
|
+
}
|
|
84
|
+
if (fn === 'chain.listEntries') {
|
|
85
|
+
return Promise.resolve([{ entryId: 'TYPE-tension', name: 'tension', status: 'active', data: { canonical_key: 'tension', valid_relation_types: ['related_to', 'depends_on', 'surfaces_tension_in'], description: 'x', cardinality_rule: 'multiple' } }]);
|
|
86
|
+
}
|
|
87
|
+
return Promise.resolve({});
|
|
88
|
+
});
|
|
89
|
+
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
90
|
+
let caught;
|
|
91
|
+
try {
|
|
92
|
+
await runCapture({ text: 'TEN: missing validation', link: 'BET-151' });
|
|
93
|
+
}
|
|
94
|
+
catch (e) {
|
|
95
|
+
caught = e;
|
|
96
|
+
}
|
|
97
|
+
writeSpy.mockRestore();
|
|
98
|
+
expect(caught).toBeInstanceOf(CLIError);
|
|
99
|
+
expect(caught?.code).toBe(ErrorCode.VALIDATION_FAILED);
|
|
100
|
+
expect(caught?.message).toContain('related_to, depends_on, surfaces_tension_in');
|
|
101
|
+
expect(caught?.guidance).toContain('TEN-711');
|
|
102
|
+
expect(caught?.guidance).toContain('pb relate TEN-711');
|
|
103
|
+
});
|
|
104
|
+
// WP-688 S4 review round 5 (bcRUML): a whitespace-only --link must not silently no-op —
|
|
105
|
+
// the entry still gets created, but the link itself must be explicitly refused.
|
|
106
|
+
it('--link " " (whitespace-only) refuses instead of silently dropping the link', async () => {
|
|
107
|
+
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
108
|
+
if (fn === 'chain.capture')
|
|
109
|
+
return Promise.resolve(null);
|
|
110
|
+
if (fn === 'chain.createEntry')
|
|
111
|
+
return Promise.resolve({ docId: 'doc-ws', entryId: 'TEN-720' });
|
|
112
|
+
return Promise.resolve({});
|
|
113
|
+
});
|
|
114
|
+
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
115
|
+
let caught;
|
|
116
|
+
try {
|
|
117
|
+
await runCapture({ text: 'TEN: whitespace link', link: ' ' });
|
|
118
|
+
}
|
|
119
|
+
catch (e) {
|
|
120
|
+
caught = e;
|
|
121
|
+
}
|
|
122
|
+
writeSpy.mockRestore();
|
|
123
|
+
expect(caught).toBeInstanceOf(CLIError);
|
|
124
|
+
expect(caught?.message).toContain('--link requires a non-empty entry ID');
|
|
125
|
+
// Never a relate/probe call — the target never resolved to anything real.
|
|
126
|
+
expect(kernelCallWithSessionMock).not.toHaveBeenCalledWith('chain.createEntryRelation', expect.anything());
|
|
127
|
+
});
|
|
128
|
+
// WP-688 S4 review round 5 (bcRpJQ): --link "" is falsy at the outer `if (options.link)` —
|
|
129
|
+
// must check `!== undefined` instead, or this whole block (and the bcRUML refusal) never runs.
|
|
130
|
+
it('--link "" (empty string) refuses instead of silently dropping the link', async () => {
|
|
131
|
+
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
132
|
+
if (fn === 'chain.capture')
|
|
133
|
+
return Promise.resolve(null);
|
|
134
|
+
if (fn === 'chain.createEntry')
|
|
135
|
+
return Promise.resolve({ docId: 'doc-empty', entryId: 'TEN-722' });
|
|
136
|
+
return Promise.resolve({});
|
|
137
|
+
});
|
|
138
|
+
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
139
|
+
let caught;
|
|
140
|
+
try {
|
|
141
|
+
await runCapture({ text: 'TEN: empty link', link: '' });
|
|
142
|
+
}
|
|
143
|
+
catch (e) {
|
|
144
|
+
caught = e;
|
|
145
|
+
}
|
|
146
|
+
writeSpy.mockRestore();
|
|
147
|
+
expect(caught).toBeInstanceOf(CLIError);
|
|
148
|
+
expect(caught?.message).toContain('--link requires a non-empty entry ID');
|
|
149
|
+
expect(kernelCallWithSessionMock).not.toHaveBeenCalledWith('chain.createEntryRelation', expect.anything());
|
|
150
|
+
});
|
|
151
|
+
// WP-688 S4 review round 5 (bcRUMR): the target entry doesn't exist — the recovery
|
|
152
|
+
// guidance must say so rather than recommending `pb relate <verb> <missing-id>`.
|
|
153
|
+
it('--link <missing-id> without --link-type reports the target was not found, not a verb-recovery command', async () => {
|
|
154
|
+
kernelCallWithSessionMock.mockImplementation((fn, args) => {
|
|
155
|
+
if (fn === 'chain.capture')
|
|
156
|
+
return Promise.resolve(null);
|
|
157
|
+
if (fn === 'chain.createEntry')
|
|
158
|
+
return Promise.resolve({ docId: 'doc-miss', entryId: 'TEN-721' });
|
|
159
|
+
if (fn === 'chain.getEntry') {
|
|
160
|
+
const entryId = args?.entryId;
|
|
161
|
+
if (entryId === 'TEN-721')
|
|
162
|
+
return Promise.resolve({ entryId: 'TEN-721', name: 'x', status: 'draft', canonicalKey: 'tension' });
|
|
163
|
+
return Promise.resolve(null); // GHOST-1 does not exist
|
|
164
|
+
}
|
|
165
|
+
if (fn === 'chain.listEntries') {
|
|
166
|
+
return Promise.resolve([{ entryId: 'TYPE-tension', name: 'tension', status: 'active', data: { canonical_key: 'tension', valid_relation_types: ['informs'], description: 'x', cardinality_rule: 'multiple' } }]);
|
|
167
|
+
}
|
|
168
|
+
return Promise.resolve({});
|
|
169
|
+
});
|
|
170
|
+
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
171
|
+
let caught;
|
|
172
|
+
try {
|
|
173
|
+
await runCapture({ text: 'TEN: bad target', link: 'GHOST-1' });
|
|
174
|
+
}
|
|
175
|
+
catch (e) {
|
|
176
|
+
caught = e;
|
|
177
|
+
}
|
|
178
|
+
writeSpy.mockRestore();
|
|
179
|
+
expect(caught?.guidance).toContain('not found');
|
|
180
|
+
expect(caught?.guidance).toContain('GHOST-1');
|
|
181
|
+
expect(caught?.guidance).not.toContain('pb relate');
|
|
182
|
+
});
|
|
183
|
+
// WP-688 S4 review round 3 (bc4Pj): `replaces`/`do_not_confuse_with` are declared for
|
|
184
|
+
// scoring but hard-refused at the generic relate door with a DIFFERENT recovery command
|
|
185
|
+
// (setSupersededBy / addDoNotConfuseWith, guards.ts:308-321) — listing them as usable via
|
|
186
|
+
// `pb relate` would name a guaranteed-to-fail re-run.
|
|
187
|
+
it('excludes replaces and do_not_confuse_with from the refusal\'s legal-verb list (both are door-blocked)', async () => {
|
|
188
|
+
kernelCallWithSessionMock.mockImplementation((fn, args) => {
|
|
189
|
+
if (fn === 'chain.capture')
|
|
190
|
+
return Promise.resolve(null);
|
|
191
|
+
if (fn === 'chain.createEntry')
|
|
192
|
+
return Promise.resolve({ docId: 'doc-1c', entryId: 'DEC-1' });
|
|
193
|
+
if (fn === 'chain.getEntry') {
|
|
194
|
+
const entryId = args?.entryId;
|
|
195
|
+
if (entryId === 'DEC-1')
|
|
196
|
+
return Promise.resolve({ entryId: 'DEC-1', name: 'x', status: 'draft', canonicalKey: 'decision' });
|
|
197
|
+
return Promise.resolve(null);
|
|
198
|
+
}
|
|
199
|
+
if (fn === 'chain.listEntries') {
|
|
200
|
+
return Promise.resolve([{ entryId: 'TYPE-decision', name: 'decision', status: 'active', data: { canonical_key: 'decision', valid_relation_types: ['informs', 'governs', 'replaces', 'conflicts_with'], description: 'x', cardinality_rule: 'multiple' } }]);
|
|
201
|
+
}
|
|
202
|
+
return Promise.resolve({});
|
|
203
|
+
});
|
|
204
|
+
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
205
|
+
let caught;
|
|
206
|
+
try {
|
|
207
|
+
await runCapture({ text: 'DEC: no link-type', link: 'STD-1' });
|
|
208
|
+
}
|
|
209
|
+
catch (e) {
|
|
210
|
+
caught = e;
|
|
211
|
+
}
|
|
212
|
+
writeSpy.mockRestore();
|
|
213
|
+
expect(caught?.message).toContain('informs, governs, conflicts_with');
|
|
214
|
+
expect(caught?.message).not.toContain('replaces');
|
|
215
|
+
});
|
|
216
|
+
// WP-688 S4 review round 5 (bdB5K): a type's declared valid_relation_types may name a verb outside
|
|
217
|
+
// the kernel ALLOWED_RELATION_TYPES allowlist. guardRelation still refuses it (guards.ts:302-307),
|
|
218
|
+
// so it must never be listed as a `pb relate`-usable recovery verb.
|
|
219
|
+
it('excludes a declared verb outside the kernel allowlist from the refusal\'s legal-verb list', async () => {
|
|
220
|
+
kernelCallWithSessionMock.mockImplementation((fn, args) => {
|
|
221
|
+
if (fn === 'chain.capture')
|
|
222
|
+
return Promise.resolve(null);
|
|
223
|
+
if (fn === 'chain.createEntry')
|
|
224
|
+
return Promise.resolve({ docId: 'doc-1d', entryId: 'GOAL-1' });
|
|
225
|
+
if (fn === 'chain.getEntry') {
|
|
226
|
+
const entryId = args?.entryId;
|
|
227
|
+
if (entryId === 'GOAL-1')
|
|
228
|
+
return Promise.resolve({ entryId: 'GOAL-1', name: 'x', status: 'draft', canonicalKey: 'goal' });
|
|
229
|
+
return Promise.resolve(null);
|
|
230
|
+
}
|
|
231
|
+
if (fn === 'chain.listEntries') {
|
|
232
|
+
return Promise.resolve([{ entryId: 'TYPE-goal', name: 'goal', status: 'active', data: { canonical_key: 'goal', valid_relation_types: ['informs', 'depends_on', 'custom_hand_added'], description: 'x', cardinality_rule: 'multiple' } }]);
|
|
233
|
+
}
|
|
234
|
+
return Promise.resolve({});
|
|
235
|
+
});
|
|
236
|
+
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
237
|
+
let caught;
|
|
238
|
+
try {
|
|
239
|
+
await runCapture({ text: 'GOAL: no link-type', link: 'BET-1' });
|
|
240
|
+
}
|
|
241
|
+
catch (e) {
|
|
242
|
+
caught = e;
|
|
243
|
+
}
|
|
244
|
+
writeSpy.mockRestore();
|
|
245
|
+
expect(caught?.message).toContain('informs, depends_on');
|
|
246
|
+
expect(caught?.message).not.toContain('custom_hand_added');
|
|
247
|
+
});
|
|
248
|
+
// WP-688 S4 review round 5 (cQFZ_): belongs_to/authority_domain toward a domain-tagged
|
|
249
|
+
// target require ratification metadata (stagingEntryId + source) that `pb relate` cannot
|
|
250
|
+
// supply (guards.ts:349-363) — never recommend them as recovery verbs for such a target.
|
|
251
|
+
it('excludes domain-tag verbs from the refusal\'s legal-verb list when the target is a domain', async () => {
|
|
252
|
+
kernelCallWithSessionMock.mockImplementation((fn, args) => {
|
|
253
|
+
if (fn === 'chain.capture')
|
|
254
|
+
return Promise.resolve(null);
|
|
255
|
+
if (fn === 'chain.createEntry')
|
|
256
|
+
return Promise.resolve({ docId: 'doc-1e', entryId: 'INS-1' });
|
|
257
|
+
if (fn === 'chain.getEntry') {
|
|
258
|
+
const entryId = args?.entryId;
|
|
259
|
+
if (entryId === 'INS-1')
|
|
260
|
+
return Promise.resolve({ entryId: 'INS-1', name: 'x', status: 'draft', canonicalKey: 'insight' });
|
|
261
|
+
if (entryId === 'DOM-1')
|
|
262
|
+
return Promise.resolve({ entryId: 'DOM-1', name: 'product-design', status: 'active', canonicalKey: 'domain' });
|
|
263
|
+
return Promise.resolve(null);
|
|
264
|
+
}
|
|
265
|
+
if (fn === 'chain.listEntries') {
|
|
266
|
+
return Promise.resolve([{ entryId: 'TYPE-insight', name: 'insight', status: 'active', data: { canonical_key: 'insight', valid_relation_types: ['informs', 'belongs_to', 'authority_domain'], description: 'x', cardinality_rule: 'multiple' } }]);
|
|
267
|
+
}
|
|
268
|
+
return Promise.resolve({});
|
|
269
|
+
});
|
|
270
|
+
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
271
|
+
let caught;
|
|
272
|
+
try {
|
|
273
|
+
await runCapture({ text: 'INS: no link-type', link: 'DOM-1' });
|
|
274
|
+
}
|
|
275
|
+
catch (e) {
|
|
276
|
+
caught = e;
|
|
277
|
+
}
|
|
278
|
+
writeSpy.mockRestore();
|
|
279
|
+
expect(caught?.message).toContain('Legal relation types for this entry: informs.');
|
|
280
|
+
expect(caught?.message).not.toContain('belongs_to');
|
|
281
|
+
expect(caught?.message).not.toContain('authority_domain');
|
|
282
|
+
});
|
|
283
|
+
it('uses the supplied relation type when --link-type provided (no probe, real write)', async () => {
|
|
284
|
+
// Prefix "INS:" is extracted → skips classification, routes directly to insights
|
|
285
|
+
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
286
|
+
if (fn === 'chain.capture')
|
|
287
|
+
return Promise.resolve(null);
|
|
288
|
+
if (fn === 'chain.createEntry')
|
|
289
|
+
return Promise.resolve({ docId: 'doc-2', entryId: 'INS-50' });
|
|
290
|
+
if (fn === 'chain.createEntryRelation')
|
|
291
|
+
return Promise.resolve({ relationId: 'rel-1' });
|
|
292
|
+
return Promise.resolve({});
|
|
293
|
+
});
|
|
294
|
+
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
295
|
+
await runCapture({ text: 'INS: discovered X', link: 'DEC-264', linkType: 'informed_by' });
|
|
296
|
+
expect(kernelCallWithSessionMock).not.toHaveBeenCalledWith('chain.resolveCollection', expect.anything());
|
|
297
|
+
// A REAL (non-preview) write — the exact verb supplied, echoed verbatim, no probe call.
|
|
298
|
+
expect(kernelCallWithSessionMock).toHaveBeenCalledWith('chain.createEntryRelation', {
|
|
299
|
+
fromEntryId: 'INS-50',
|
|
300
|
+
toEntryId: 'DEC-264',
|
|
301
|
+
type: 'informed_by',
|
|
302
|
+
});
|
|
303
|
+
const previewCalls = kernelCallWithSessionMock.mock.calls.filter(([fn, args]) => fn === 'chain.createEntryRelation' && args?.preview);
|
|
304
|
+
expect(previewCalls).toHaveLength(0);
|
|
305
|
+
writeSpy.mockRestore();
|
|
306
|
+
});
|
|
307
|
+
// WP-745 review (Codex P1): a relate-door refusal (e.g. REL-LEGAL-2) at the --link-type
|
|
308
|
+
// branch must not escape as an unhandled rejection — the entry above was ALREADY persisted,
|
|
309
|
+
// so the capture reports it, naming only the link as refused (same shape as the
|
|
310
|
+
// --link-without---link-type branch above).
|
|
311
|
+
it('a relate-door refusal during --link is deferred, naming the persisted entry — never an unhandled rejection', async () => {
|
|
312
|
+
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
313
|
+
if (fn === 'chain.capture')
|
|
314
|
+
return Promise.resolve(null);
|
|
315
|
+
if (fn === 'chain.createEntry')
|
|
316
|
+
return Promise.resolve({ docId: 'doc-wp', entryId: 'WP-6' });
|
|
317
|
+
if (fn === 'chain.createEntryRelation') {
|
|
318
|
+
return Promise.reject(Object.assign(new Error('A work package is never part_of another work package — capture the smaller piece as a task and relate it part_of this work package.'), { name: 'McpError' }));
|
|
319
|
+
}
|
|
320
|
+
return Promise.resolve({});
|
|
321
|
+
});
|
|
322
|
+
let caught;
|
|
323
|
+
try {
|
|
324
|
+
await runCapture({ text: 'WP: child work package', link: 'WP-5', linkType: 'part_of' });
|
|
325
|
+
}
|
|
326
|
+
catch (e) {
|
|
327
|
+
caught = e;
|
|
328
|
+
}
|
|
329
|
+
expect(caught).toBeInstanceOf(CLIError);
|
|
330
|
+
expect(caught?.message).toContain('A work package is never part_of another work package');
|
|
331
|
+
expect(caught?.guidance).toContain('WP-6 was captured');
|
|
332
|
+
expect(caught?.guidance).toContain('only the link was refused');
|
|
333
|
+
});
|
|
334
|
+
// WP-745 round 3 (PR #896 review, PRRT_kwDORS4ils6h0CCc): a NON-REL-LEGAL-2 relate-door
|
|
335
|
+
// failure (auth denial, rate limit) must keep its OWN code/category — the earlier fix
|
|
336
|
+
// unconditionally relabeled every deferred link failure VALIDATION_FAILED, discarding the
|
|
337
|
+
// real error's identity.
|
|
338
|
+
it('a non-validation relate-door failure during --link preserves its own code/category, not a relabeled VALIDATION_FAILED', async () => {
|
|
339
|
+
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
340
|
+
if (fn === 'chain.capture')
|
|
341
|
+
return Promise.resolve(null);
|
|
342
|
+
if (fn === 'chain.createEntry')
|
|
343
|
+
return Promise.resolve({ docId: 'doc-wp7', entryId: 'WP-7' });
|
|
344
|
+
if (fn === 'chain.createEntryRelation') {
|
|
345
|
+
return Promise.reject(new CLIError('Rate limit exceeded', { code: ErrorCode.RATE_LIMITED, category: 'network', guidance: 'Wait and retry.' }));
|
|
346
|
+
}
|
|
347
|
+
if (fn === 'quality.evaluateHeuristicAndSchedule')
|
|
348
|
+
return Promise.resolve(undefined);
|
|
349
|
+
return Promise.resolve({});
|
|
350
|
+
});
|
|
351
|
+
let caught;
|
|
352
|
+
try {
|
|
353
|
+
await runCapture({ text: 'WP: child work package', link: 'WP-5', linkType: 'part_of' });
|
|
354
|
+
}
|
|
355
|
+
catch (e) {
|
|
356
|
+
caught = e;
|
|
357
|
+
}
|
|
358
|
+
expect(caught).toBeInstanceOf(CLIError);
|
|
359
|
+
expect(caught?.code).toBe(ErrorCode.RATE_LIMITED);
|
|
360
|
+
expect(caught?.category).toBe('network');
|
|
361
|
+
expect(caught?.message).toBe('Rate limit exceeded');
|
|
362
|
+
expect(caught?.guidance).toContain('WP-7 was captured');
|
|
363
|
+
});
|
|
364
|
+
// WP-745 round 3 (PR #896 review, PRRT_kwDORS4ils6h0VPP): a NETWORK_TIMEOUT relate failure is
|
|
365
|
+
// outcome-UNKNOWN (the write may have landed server-side) — the guidance must say so, never
|
|
366
|
+
// the "was refused, re-run" template, which would prompt a blind duplicate-risking retry.
|
|
367
|
+
it('a NETWORK_TIMEOUT relate-door failure during --link says outcome-unknown, never "was refused"', async () => {
|
|
368
|
+
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
369
|
+
if (fn === 'chain.capture')
|
|
370
|
+
return Promise.resolve(null);
|
|
371
|
+
if (fn === 'chain.createEntry')
|
|
372
|
+
return Promise.resolve({ docId: 'doc-wp9', entryId: 'WP-9' });
|
|
373
|
+
if (fn === 'chain.createEntryRelation') {
|
|
374
|
+
return Promise.reject(new CLIError('"chain.createEntryRelation" exceeded its budget.', { code: ErrorCode.NETWORK_TIMEOUT, category: 'network', guidance: 'Check before retrying.' }));
|
|
375
|
+
}
|
|
376
|
+
if (fn === 'quality.evaluateHeuristicAndSchedule')
|
|
377
|
+
return Promise.resolve(undefined);
|
|
378
|
+
return Promise.resolve({});
|
|
379
|
+
});
|
|
380
|
+
let caught;
|
|
381
|
+
try {
|
|
382
|
+
await runCapture({ text: 'WP: child work package', link: 'WP-5', linkType: 'part_of' });
|
|
383
|
+
}
|
|
384
|
+
catch (e) {
|
|
385
|
+
caught = e;
|
|
386
|
+
}
|
|
387
|
+
expect(caught).toBeInstanceOf(CLIError);
|
|
388
|
+
expect(caught?.code).toBe(ErrorCode.NETWORK_TIMEOUT);
|
|
389
|
+
expect(caught?.guidance).toContain('outcome is UNKNOWN');
|
|
390
|
+
expect(caught?.guidance).not.toContain('was refused');
|
|
391
|
+
});
|
|
392
|
+
// WP-745 round 3 (PR #896 review, PRRT_kwDORS4ils6h0CCc): the quality re-eval must still run
|
|
393
|
+
// (un-defers deferLLMSchedule) even when the relate call itself throws — previously the
|
|
394
|
+
// re-eval sat INSIDE the same try as the relate call, so a thrown refusal skipped it
|
|
395
|
+
// entirely, leaving the entry stuck at llmStatus:'skipped' with no background judgment ever
|
|
396
|
+
// scheduled.
|
|
397
|
+
it('the quality re-eval still runs after a relate-door refusal — the entry is not left permanently deferred', async () => {
|
|
398
|
+
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
399
|
+
if (fn === 'chain.capture')
|
|
400
|
+
return Promise.resolve(null);
|
|
401
|
+
if (fn === 'chain.createEntry')
|
|
402
|
+
return Promise.resolve({ docId: 'doc-wp8', entryId: 'WP-8' });
|
|
403
|
+
if (fn === 'chain.createEntryRelation') {
|
|
404
|
+
return Promise.reject(Object.assign(new Error('refused'), { name: 'McpError' }));
|
|
405
|
+
}
|
|
406
|
+
if (fn === 'quality.evaluateHeuristicAndSchedule')
|
|
407
|
+
return Promise.resolve({ verdict: 'pass' });
|
|
408
|
+
return Promise.resolve({});
|
|
409
|
+
});
|
|
410
|
+
try {
|
|
411
|
+
await runCapture({ text: 'WP: child work package', link: 'WP-5', linkType: 'part_of' });
|
|
412
|
+
}
|
|
413
|
+
catch {
|
|
414
|
+
// The refusal itself is expected — asserted by the sibling test above; this test only
|
|
415
|
+
// cares that the re-eval call happened before/regardless of it.
|
|
416
|
+
}
|
|
417
|
+
expect(kernelCallWithSessionMock).toHaveBeenCalledWith('quality.evaluateHeuristicAndSchedule', {
|
|
418
|
+
entryId: 'WP-8',
|
|
419
|
+
context: 'capture',
|
|
420
|
+
});
|
|
421
|
+
});
|
|
422
|
+
// WP-688 S4 (element 11): the human receipt prints the REAL verb — no `?? 'surfaces_tension_in'`
|
|
423
|
+
// fallback (formatters/capture.ts:105).
|
|
424
|
+
it('the human-readable receipt prints the real relation type, never the dead surfaces_tension_in fallback', async () => {
|
|
425
|
+
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
426
|
+
if (fn === 'chain.capture')
|
|
427
|
+
return Promise.resolve(null);
|
|
428
|
+
if (fn === 'chain.createEntry')
|
|
429
|
+
return Promise.resolve({ docId: 'doc-2b', entryId: 'INS-51' });
|
|
430
|
+
if (fn === 'chain.createEntryRelation')
|
|
431
|
+
return Promise.resolve({ relationId: 'rel-1' });
|
|
432
|
+
return Promise.resolve({});
|
|
433
|
+
});
|
|
434
|
+
let stdoutOutput = '';
|
|
435
|
+
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation((chunk) => {
|
|
436
|
+
stdoutOutput += String(chunk);
|
|
437
|
+
return true;
|
|
438
|
+
});
|
|
439
|
+
setOutputMode('pretty'); // force the human receipt path (test harness's stdout is non-TTY)
|
|
440
|
+
try {
|
|
441
|
+
await runCapture({ text: 'INS: discovered Y', link: 'DEC-265', linkType: 'validates' });
|
|
442
|
+
}
|
|
443
|
+
finally {
|
|
444
|
+
setOutputMode('auto');
|
|
445
|
+
writeSpy.mockRestore();
|
|
446
|
+
}
|
|
447
|
+
expect(stdoutOutput).toContain('Linked: → DEC-265 (validates)');
|
|
448
|
+
expect(stdoutOutput).not.toContain('surfaces_tension_in');
|
|
449
|
+
});
|
|
450
|
+
// WP-688 S4 review round 2 (bc04z): a diverted relation call (the DEC-1399 auto-link gate
|
|
451
|
+
// routing an edge to a pending suggestion instead of writing it — WP-776 S2a, DEC-1771
|
|
452
|
+
// deletes the OTHER diversion this once named, the governs-consent proposal) returns
|
|
453
|
+
// WITHOUT a relationId — only a real, persisted write may claim `linkedTo`/`relationType`.
|
|
454
|
+
it('an auto-link-gate diversion (no relationId) is never reported as a persisted link', async () => {
|
|
455
|
+
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
456
|
+
if (fn === 'chain.capture')
|
|
457
|
+
return Promise.resolve(null);
|
|
458
|
+
if (fn === 'chain.createEntry')
|
|
459
|
+
return Promise.resolve({ docId: 'doc-3', entryId: 'WPKG-1' });
|
|
460
|
+
if (fn === 'chain.createEntryRelation') {
|
|
461
|
+
return Promise.resolve({ ok: false, status: 'advised', advised: true });
|
|
462
|
+
}
|
|
463
|
+
return Promise.resolve({});
|
|
464
|
+
});
|
|
465
|
+
let stdoutOutput = '';
|
|
466
|
+
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation((chunk) => {
|
|
467
|
+
stdoutOutput += String(chunk);
|
|
468
|
+
return true;
|
|
469
|
+
});
|
|
470
|
+
await runCapture({ text: 'WPKG: governance test', link: 'STD-1', linkType: 'governs', json: true });
|
|
471
|
+
writeSpy.mockRestore();
|
|
472
|
+
const output = JSON.parse(stdoutOutput.split('\n').find((line) => {
|
|
473
|
+
try {
|
|
474
|
+
JSON.parse(line);
|
|
475
|
+
return true;
|
|
476
|
+
}
|
|
477
|
+
catch {
|
|
478
|
+
return false;
|
|
479
|
+
}
|
|
480
|
+
}));
|
|
481
|
+
expect(output.relationType).toBeUndefined();
|
|
482
|
+
// WP-688 S4 review fix (bc7cr): the re-eval call STILL fires — it's the only thing that
|
|
483
|
+
// un-defers the LLM schedule deferLLMSchedule set (a relate WAS attempted) — but its
|
|
484
|
+
// verdict is discarded: no relation landed, so relation-dependent criteria stay unscored.
|
|
485
|
+
expect(kernelCallWithSessionMock).toHaveBeenCalledWith('quality.evaluateHeuristicAndSchedule', {
|
|
486
|
+
entryId: 'WPKG-1',
|
|
487
|
+
context: 'capture',
|
|
488
|
+
});
|
|
489
|
+
expect(output.coaching).toBeUndefined();
|
|
490
|
+
});
|
|
491
|
+
// WP-688 S4 review round 2 (bc045): --link without --link-type must not defer the LLM
|
|
492
|
+
// schedule — the refusal branch never runs the re-eval that would un-defer it, so a
|
|
493
|
+
// deferred-then-never-run schedule would leave the entry permanently stuck.
|
|
494
|
+
it('--link without --link-type does NOT defer the LLM schedule (nothing will ever un-defer it)', async () => {
|
|
495
|
+
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
496
|
+
if (fn === 'chain.capture')
|
|
497
|
+
return Promise.resolve(null);
|
|
498
|
+
if (fn === 'chain.createEntry')
|
|
499
|
+
return Promise.resolve({ docId: 'doc-4', entryId: 'TEN-20' });
|
|
500
|
+
if (fn === 'chain.createEntryRelation')
|
|
501
|
+
return Promise.resolve({ preview: true, advisories: [] });
|
|
502
|
+
return Promise.resolve({});
|
|
503
|
+
});
|
|
504
|
+
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
505
|
+
await expect(runCapture({ text: 'TEN: refused link, no defer', link: 'BET-1' })).rejects.toThrow(CLIError);
|
|
506
|
+
writeSpy.mockRestore();
|
|
507
|
+
const createCall = kernelCallWithSessionMock.mock.calls.find(([fn]) => fn === 'chain.createEntry');
|
|
508
|
+
expect(createCall?.[1]).not.toHaveProperty('deferLLMSchedule');
|
|
509
|
+
});
|
|
510
|
+
// WP-688 S4 review round 2 (bc049): a dropped field and a --link-type refusal can both be true
|
|
511
|
+
// on the SAME capture — the entry was created either way, so both must reach the operator.
|
|
512
|
+
// TASK-584 (WP-802, TEN-4312): the dropped field is a warning on the landed reply, the link
|
|
513
|
+
// refusal is the only error.
|
|
514
|
+
it('prints the dropped-field warning AND throws the link-type refusal when they co-occur', async () => {
|
|
515
|
+
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
516
|
+
if (fn === 'chain.capture')
|
|
517
|
+
return Promise.resolve(null);
|
|
518
|
+
if (fn === 'chain.createEntry') {
|
|
519
|
+
return Promise.resolve({
|
|
520
|
+
docId: 'doc-5', entryId: 'TEN-21',
|
|
521
|
+
normalization: { remapped: {}, rejected: ['badField'], accepted: [] },
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
if (fn === 'chain.createEntryRelation')
|
|
525
|
+
return Promise.resolve({ preview: true, advisories: [] });
|
|
526
|
+
return Promise.resolve({});
|
|
527
|
+
});
|
|
528
|
+
const out = [];
|
|
529
|
+
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation((chunk) => { out.push(String(chunk)); return true; });
|
|
530
|
+
let caught;
|
|
531
|
+
try {
|
|
532
|
+
await runCapture({ text: 'TEN: both failures at once', link: 'BET-1', json: true });
|
|
533
|
+
}
|
|
534
|
+
catch (e) {
|
|
535
|
+
caught = e;
|
|
536
|
+
}
|
|
537
|
+
writeSpy.mockRestore();
|
|
538
|
+
expect(caught).toBeInstanceOf(CLIError);
|
|
539
|
+
expect(JSON.parse(out.join(''))).toMatchObject({ id: 'TEN-21', droppedFields: ['badField'] });
|
|
540
|
+
expect(caught?.message).not.toContain('Fields rejected');
|
|
541
|
+
expect(caught?.message).toContain('--link requires --link-type');
|
|
542
|
+
expect(caught?.guidance).toContain('TEN-21');
|
|
543
|
+
});
|
|
544
|
+
// WP-745 round 3 (PR #896 review, PRRT_kwDORS4ils6h0e82): the link-refused error beside a
|
|
545
|
+
// dropped field must preserve the link failure's OWN code/category (e.g. NETWORK_TIMEOUT)
|
|
546
|
+
// rather than always relabeling the aggregate VALIDATION_FAILED — automation branching on the
|
|
547
|
+
// error code must still see the timeout, not a generic validation failure.
|
|
548
|
+
it('the link-refused error beside a dropped field keeps the link failure\'s own code (NETWORK_TIMEOUT), not VALIDATION_FAILED', async () => {
|
|
549
|
+
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
550
|
+
if (fn === 'chain.capture')
|
|
551
|
+
return Promise.resolve(null);
|
|
552
|
+
if (fn === 'chain.createEntry') {
|
|
553
|
+
return Promise.resolve({
|
|
554
|
+
docId: 'doc-10', entryId: 'TEN-22',
|
|
555
|
+
normalization: { remapped: {}, rejected: ['badField'], accepted: [] },
|
|
556
|
+
});
|
|
557
|
+
}
|
|
558
|
+
if (fn === 'chain.createEntryRelation') {
|
|
559
|
+
return Promise.reject(new CLIError('"chain.createEntryRelation" exceeded its budget.', { code: ErrorCode.NETWORK_TIMEOUT, category: 'network', guidance: 'Check before retrying.' }));
|
|
560
|
+
}
|
|
561
|
+
if (fn === 'quality.evaluateHeuristicAndSchedule')
|
|
562
|
+
return Promise.resolve(undefined);
|
|
563
|
+
return Promise.resolve({});
|
|
564
|
+
});
|
|
565
|
+
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
566
|
+
let caught;
|
|
567
|
+
try {
|
|
568
|
+
await runCapture({ text: 'TEN: both failures, timeout link', link: 'BET-1', linkType: 'part_of' });
|
|
569
|
+
}
|
|
570
|
+
catch (e) {
|
|
571
|
+
caught = e;
|
|
572
|
+
}
|
|
573
|
+
writeSpy.mockRestore();
|
|
574
|
+
expect(caught).toBeInstanceOf(CLIError);
|
|
575
|
+
expect(caught?.code).toBe(ErrorCode.NETWORK_TIMEOUT);
|
|
576
|
+
expect(caught?.message).not.toContain('Fields rejected');
|
|
577
|
+
});
|
|
578
|
+
});
|
|
579
|
+
// WP-684 TASK-77 (E1.3): one-step typed create — --entry-type forwards to chain.createEntry's
|
|
580
|
+
// existing `canonicalKey` arg. Named --entry-type since -t/--type is the --link relation type.
|
|
581
|
+
describe('runCapture --entry-type', () => {
|
|
582
|
+
beforeEach(() => {
|
|
583
|
+
kernelCallWithSessionMock.mockReset();
|
|
584
|
+
mockSession = { sessionId: 'sess-test' };
|
|
585
|
+
});
|
|
586
|
+
it('forwards --entry-type as canonicalKey on the chain.createEntry payload', async () => {
|
|
587
|
+
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
588
|
+
if (fn === 'chain.capture')
|
|
589
|
+
return Promise.resolve(null);
|
|
590
|
+
if (fn === 'chain.createEntry')
|
|
591
|
+
return Promise.resolve({ docId: 'doc-3', entryId: 'OBJ-1' });
|
|
592
|
+
return Promise.resolve({});
|
|
593
|
+
});
|
|
594
|
+
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
595
|
+
await runCapture({ text: 'the objective', collection: 'key-results', entryType: 'objective' });
|
|
596
|
+
expect(kernelCallWithSessionMock).toHaveBeenCalledWith('chain.createEntry', expect.objectContaining({
|
|
597
|
+
collectionSlug: 'key-results',
|
|
598
|
+
canonicalKey: 'objective',
|
|
599
|
+
}));
|
|
600
|
+
writeSpy.mockRestore();
|
|
601
|
+
});
|
|
602
|
+
it('omits canonicalKey entirely when --entry-type is absent (byte-identical default path)', async () => {
|
|
603
|
+
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
604
|
+
if (fn === 'chain.capture')
|
|
605
|
+
return Promise.resolve(null);
|
|
606
|
+
if (fn === 'chain.createEntry')
|
|
607
|
+
return Promise.resolve({ docId: 'doc-4', entryId: 'OBJ-1' });
|
|
608
|
+
return Promise.resolve({});
|
|
609
|
+
});
|
|
610
|
+
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
611
|
+
await runCapture({ text: 'a key result', collection: 'key-results' });
|
|
612
|
+
const call = kernelCallWithSessionMock.mock.calls.find(([fn]) => fn === 'chain.createEntry');
|
|
613
|
+
expect(call?.[1]).not.toHaveProperty('canonicalKey');
|
|
614
|
+
writeSpy.mockRestore();
|
|
615
|
+
});
|
|
616
|
+
// Review round 2 (bcI42): --entry-type's help text promises it "bypasses classification",
|
|
617
|
+
// but without an ALSO-explicit --collection, the resolution chain fell through to
|
|
618
|
+
// chain.resolveCollection anyway — objective/key_result text could classify into the wrong
|
|
619
|
+
// collection (e.g. strategy) and then fail the placement guard. --entry-type alone must route
|
|
620
|
+
// straight to the shared Objectives drawer with no classification call at all.
|
|
621
|
+
it('--entry-type objective alone (no --collection) skips classification and routes to the Objectives drawer (bcI42)', async () => {
|
|
622
|
+
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
623
|
+
if (fn === 'chain.capture')
|
|
624
|
+
return Promise.resolve(null);
|
|
625
|
+
if (fn === 'chain.createEntry')
|
|
626
|
+
return Promise.resolve({ docId: 'doc-5', entryId: 'OBJ-2' });
|
|
627
|
+
return Promise.resolve({});
|
|
628
|
+
});
|
|
629
|
+
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
630
|
+
await runCapture({ text: 'another objective', entryType: 'objective' });
|
|
631
|
+
expect(kernelCallWithSessionMock).not.toHaveBeenCalledWith('chain.resolveCollection', expect.anything());
|
|
632
|
+
// PR #713 post-merge review (PRRT_kwDORS4ils6cQP_I, P1): 'key-results' is the RETIRED slug —
|
|
633
|
+
// the fix derives the drawer's current slug from the live registry (OBJ idPrefix), which is
|
|
634
|
+
// 'objectives' post-WP-686.
|
|
635
|
+
expect(kernelCallWithSessionMock).toHaveBeenCalledWith('chain.createEntry', expect.objectContaining({
|
|
636
|
+
collectionSlug: 'objectives',
|
|
637
|
+
canonicalKey: 'objective',
|
|
638
|
+
}));
|
|
639
|
+
writeSpy.mockRestore();
|
|
640
|
+
});
|
|
641
|
+
// WP-707 S1 round 2 (DEC-1622, Codex PRRT_kwDORS4ils6dUxaz): key_result now files into its
|
|
642
|
+
// OWN 1:1 drawer (key-results, idPrefix KR) — it no longer shares the Objectives drawer.
|
|
643
|
+
it('--entry-type key_result alone (no --collection) routes to the Key Results drawer (DEC-1622)', async () => {
|
|
644
|
+
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
645
|
+
if (fn === 'chain.capture')
|
|
646
|
+
return Promise.resolve(null);
|
|
647
|
+
if (fn === 'chain.createEntry')
|
|
648
|
+
return Promise.resolve({ docId: 'doc-6', entryId: 'KR-2' });
|
|
649
|
+
return Promise.resolve({});
|
|
650
|
+
});
|
|
651
|
+
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
652
|
+
await runCapture({ text: 'another key result', entryType: 'key_result' });
|
|
653
|
+
expect(kernelCallWithSessionMock).not.toHaveBeenCalledWith('chain.resolveCollection', expect.anything());
|
|
654
|
+
expect(kernelCallWithSessionMock).toHaveBeenCalledWith('chain.createEntry', expect.objectContaining({
|
|
655
|
+
collectionSlug: 'key-results',
|
|
656
|
+
canonicalKey: 'key_result',
|
|
657
|
+
}));
|
|
658
|
+
writeSpy.mockRestore();
|
|
659
|
+
});
|
|
660
|
+
// Review round 3 (bclZ9): --entry-type Objective (mixed case) or " objective " (whitespace)
|
|
661
|
+
// must route to the drawer too -- the server normalizes explicit keys with
|
|
662
|
+
// toLowerCase().trim() downstream, so client-side routing must match or it falls through to
|
|
663
|
+
// classification (often landing in 'strategy') and the placement guard then rejects it.
|
|
664
|
+
it('--entry-type with mixed case/whitespace still routes to the Objectives drawer, no classification call (bclZ9)', async () => {
|
|
665
|
+
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
666
|
+
if (fn === 'chain.capture')
|
|
667
|
+
return Promise.resolve(null);
|
|
668
|
+
if (fn === 'chain.createEntry')
|
|
669
|
+
return Promise.resolve({ docId: 'doc-7', entryId: 'OBJ-3' });
|
|
670
|
+
return Promise.resolve({});
|
|
671
|
+
});
|
|
672
|
+
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
673
|
+
await runCapture({ text: 'a padded objective', entryType: ' Objective ' });
|
|
674
|
+
expect(kernelCallWithSessionMock).not.toHaveBeenCalledWith('chain.resolveCollection', expect.anything());
|
|
675
|
+
expect(kernelCallWithSessionMock).toHaveBeenCalledWith('chain.createEntry', expect.objectContaining({
|
|
676
|
+
collectionSlug: 'objectives',
|
|
677
|
+
}));
|
|
678
|
+
writeSpy.mockRestore();
|
|
679
|
+
});
|
|
680
|
+
// WP-707 S1 round 3 (operator ruling #13): the fast path is now a GENERAL derivation off the
|
|
681
|
+
// registry's defaultCanonicalKey (getCanonicalKeyToCollection), not two hardcoded
|
|
682
|
+
// objective/key_result branches — this proves a THIRD kind that was never one of those two
|
|
683
|
+
// branches (strategy) still skips classification and routes to its own drawer.
|
|
684
|
+
it('--entry-type strategy alone (no --collection) skips classification and routes to the Strategy drawer — proves the derivation is general, not a hardcoded pair', async () => {
|
|
685
|
+
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
686
|
+
if (fn === 'chain.capture')
|
|
687
|
+
return Promise.resolve(null);
|
|
688
|
+
if (fn === 'chain.createEntry')
|
|
689
|
+
return Promise.resolve({ docId: 'doc-8', entryId: 'STR-1' });
|
|
690
|
+
return Promise.resolve({});
|
|
691
|
+
});
|
|
692
|
+
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
693
|
+
await runCapture({ text: 'our approach to winning', entryType: 'strategy' });
|
|
694
|
+
expect(kernelCallWithSessionMock).not.toHaveBeenCalledWith('chain.resolveCollection', expect.anything());
|
|
695
|
+
expect(kernelCallWithSessionMock).toHaveBeenCalledWith('chain.createEntry', expect.objectContaining({
|
|
696
|
+
collectionSlug: 'strategy',
|
|
697
|
+
canonicalKey: 'strategy',
|
|
698
|
+
}));
|
|
699
|
+
writeSpy.mockRestore();
|
|
700
|
+
});
|
|
701
|
+
// WP-707 S1 round 3.1 (Codex post-round-3 P2): vision/purpose are brand-new drawers this same
|
|
702
|
+
// PR adds — the offline SEED fallback (collectionRegistry.ts) must carry them too, or the
|
|
703
|
+
// --entry-type derivation silently can't resolve them during a chain.listCollections outage.
|
|
704
|
+
it('--entry-type vision alone (no --collection) skips classification and routes to the Vision drawer, even offline', async () => {
|
|
705
|
+
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
706
|
+
if (fn === 'chain.capture')
|
|
707
|
+
return Promise.resolve(null);
|
|
708
|
+
if (fn === 'chain.createEntry')
|
|
709
|
+
return Promise.resolve({ docId: 'doc-9', entryId: 'VIS-1' });
|
|
710
|
+
return Promise.resolve({});
|
|
711
|
+
});
|
|
712
|
+
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
713
|
+
await runCapture({ text: 'a world where knowledge compounds', entryType: 'vision' });
|
|
714
|
+
expect(kernelCallWithSessionMock).not.toHaveBeenCalledWith('chain.resolveCollection', expect.anything());
|
|
715
|
+
expect(kernelCallWithSessionMock).toHaveBeenCalledWith('chain.createEntry', expect.objectContaining({
|
|
716
|
+
collectionSlug: 'vision',
|
|
717
|
+
canonicalKey: 'vision',
|
|
718
|
+
}));
|
|
719
|
+
writeSpy.mockRestore();
|
|
720
|
+
});
|
|
721
|
+
});
|
|
722
|
+
describe('runCapture --json', () => {
|
|
723
|
+
beforeEach(() => {
|
|
724
|
+
kernelCallWithSessionMock.mockReset();
|
|
725
|
+
mockSession = { sessionId: 'sess-test' };
|
|
726
|
+
});
|
|
727
|
+
it('outputs valid JSON with id field and no other stdout', async () => {
|
|
728
|
+
// Prefix "TEN:" is extracted → skips classification
|
|
729
|
+
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
730
|
+
if (fn === 'chain.capture')
|
|
731
|
+
return Promise.resolve(null);
|
|
732
|
+
if (fn === 'chain.createEntry')
|
|
733
|
+
return Promise.resolve({ docId: 'doc-1', entryId: 'TEN-711' });
|
|
734
|
+
return Promise.resolve({});
|
|
735
|
+
});
|
|
736
|
+
let stdoutOutput = '';
|
|
737
|
+
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation((chunk) => {
|
|
738
|
+
stdoutOutput += String(chunk);
|
|
739
|
+
return true;
|
|
740
|
+
});
|
|
741
|
+
await runCapture({ text: 'TEN: test', json: true });
|
|
742
|
+
writeSpy.mockRestore();
|
|
743
|
+
// Find JSON lines in stdout
|
|
744
|
+
const jsonLines = stdoutOutput.split('\n').filter(line => {
|
|
745
|
+
try {
|
|
746
|
+
JSON.parse(line);
|
|
747
|
+
return true;
|
|
748
|
+
}
|
|
749
|
+
catch {
|
|
750
|
+
return false;
|
|
751
|
+
}
|
|
752
|
+
});
|
|
753
|
+
expect(jsonLines).toHaveLength(1);
|
|
754
|
+
const output = JSON.parse(jsonLines[0]);
|
|
755
|
+
expect(output).toHaveProperty('id', 'TEN-711');
|
|
756
|
+
expect(output).toHaveProperty('collection', 'tensions');
|
|
757
|
+
expect(output).toHaveProperty('confidence');
|
|
758
|
+
});
|
|
759
|
+
});
|
|
760
|
+
describe('runCapture coaching passthrough (WP-475 E1)', () => {
|
|
761
|
+
beforeEach(() => {
|
|
762
|
+
kernelCallWithSessionMock.mockReset();
|
|
763
|
+
mockSession = { sessionId: 'sess-test' };
|
|
764
|
+
});
|
|
765
|
+
const coaching = {
|
|
766
|
+
source: 'heuristic',
|
|
767
|
+
verdict: {
|
|
768
|
+
entryId: 'DEC-77',
|
|
769
|
+
canonicalKey: 'decision',
|
|
770
|
+
tier: 'assertive',
|
|
771
|
+
context: 'capture',
|
|
772
|
+
passed: false,
|
|
773
|
+
criteria: [
|
|
774
|
+
{ id: 'specificity', passed: false, weight: 2, hint: 'Be specific.', questionTemplate: 'What exactly?' },
|
|
775
|
+
],
|
|
776
|
+
weakest: { criterion: 'specificity', hint: 'Be specific.', questionTemplate: 'What exactly?' },
|
|
777
|
+
overridden: false,
|
|
778
|
+
},
|
|
779
|
+
};
|
|
780
|
+
it('--json output includes the raw coaching object from the write response', async () => {
|
|
781
|
+
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
782
|
+
if (fn === 'chain.capture')
|
|
783
|
+
return Promise.resolve(null);
|
|
784
|
+
if (fn === 'chain.createEntry')
|
|
785
|
+
return Promise.resolve({ docId: 'doc-c1', entryId: 'DEC-77', coaching });
|
|
786
|
+
return Promise.resolve({});
|
|
787
|
+
});
|
|
788
|
+
let stdoutOutput = '';
|
|
789
|
+
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation((chunk) => {
|
|
790
|
+
stdoutOutput += String(chunk);
|
|
791
|
+
return true;
|
|
792
|
+
});
|
|
793
|
+
await runCapture({ text: 'DEC: chose something', json: true });
|
|
794
|
+
writeSpy.mockRestore();
|
|
795
|
+
const jsonLines = stdoutOutput.split('\n').filter((line) => {
|
|
796
|
+
try {
|
|
797
|
+
JSON.parse(line);
|
|
798
|
+
return true;
|
|
799
|
+
}
|
|
800
|
+
catch {
|
|
801
|
+
return false;
|
|
802
|
+
}
|
|
803
|
+
});
|
|
804
|
+
expect(jsonLines).toHaveLength(1);
|
|
805
|
+
const output = JSON.parse(jsonLines[0]);
|
|
806
|
+
expect(output.coaching).toEqual(coaching);
|
|
807
|
+
});
|
|
808
|
+
it('--json output omits coaching when the write response has none (backward compat)', async () => {
|
|
809
|
+
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
810
|
+
if (fn === 'chain.capture')
|
|
811
|
+
return Promise.resolve(null);
|
|
812
|
+
if (fn === 'chain.createEntry')
|
|
813
|
+
return Promise.resolve({ docId: 'doc-c2', entryId: 'DEC-78' });
|
|
814
|
+
return Promise.resolve({});
|
|
815
|
+
});
|
|
816
|
+
let stdoutOutput = '';
|
|
817
|
+
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation((chunk) => {
|
|
818
|
+
stdoutOutput += String(chunk);
|
|
819
|
+
return true;
|
|
820
|
+
});
|
|
821
|
+
await runCapture({ text: 'DEC: chose another thing', json: true });
|
|
822
|
+
writeSpy.mockRestore();
|
|
823
|
+
const jsonLines = stdoutOutput.split('\n').filter((line) => {
|
|
824
|
+
try {
|
|
825
|
+
JSON.parse(line);
|
|
826
|
+
return true;
|
|
827
|
+
}
|
|
828
|
+
catch {
|
|
829
|
+
return false;
|
|
830
|
+
}
|
|
831
|
+
});
|
|
832
|
+
expect(jsonLines).toHaveLength(1);
|
|
833
|
+
expect(JSON.parse(jsonLines[0])).not.toHaveProperty('coaching');
|
|
834
|
+
});
|
|
835
|
+
// ── WP-475 E1 fix: relation-aware receipt on --link ────────────────────────
|
|
836
|
+
// The create-response verdict is computed BEFORE the --link relation exists,
|
|
837
|
+
// so relation-dependent criteria (wired-in checks) read falsely failed. When
|
|
838
|
+
// the capture created a relation, the CLI re-evaluates AFTER it lands and
|
|
839
|
+
// renders THAT verdict.
|
|
840
|
+
const reEvalCoaching = {
|
|
841
|
+
source: 'heuristic',
|
|
842
|
+
verdict: {
|
|
843
|
+
...coaching.verdict,
|
|
844
|
+
passed: true,
|
|
845
|
+
criteria: [{ id: 'specificity', passed: true, weight: 2, hint: 'Be specific.', questionTemplate: 'What exactly?' }],
|
|
846
|
+
weakest: null,
|
|
847
|
+
},
|
|
848
|
+
};
|
|
849
|
+
it('--link: re-evaluates after the relation lands and renders the post-relation verdict', async () => {
|
|
850
|
+
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
851
|
+
if (fn === 'chain.capture')
|
|
852
|
+
return Promise.resolve(null);
|
|
853
|
+
if (fn === 'chain.createEntry')
|
|
854
|
+
return Promise.resolve({ docId: 'doc-c3', entryId: 'DEC-79', coaching });
|
|
855
|
+
if (fn === 'chain.createEntryRelation')
|
|
856
|
+
return Promise.resolve({ relationId: 'rel-1' });
|
|
857
|
+
if (fn === 'quality.evaluateHeuristicAndSchedule')
|
|
858
|
+
return Promise.resolve(reEvalCoaching);
|
|
859
|
+
return Promise.resolve({});
|
|
860
|
+
});
|
|
861
|
+
let stdoutOutput = '';
|
|
862
|
+
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation((chunk) => {
|
|
863
|
+
stdoutOutput += String(chunk);
|
|
864
|
+
return true;
|
|
865
|
+
});
|
|
866
|
+
await runCapture({ text: 'DEC: chose with a link', link: 'TEN-1', linkType: 'informs', json: true });
|
|
867
|
+
writeSpy.mockRestore();
|
|
868
|
+
// Deterministic --link fix: the CREATE call defers the LLM schedule (the
|
|
869
|
+
// post-relation re-eval owns the single LLM run)…
|
|
870
|
+
const createCall = kernelCallWithSessionMock.mock.calls.find(([fn]) => fn === 'chain.createEntry');
|
|
871
|
+
expect(createCall?.[1]).toMatchObject({ deferLLMSchedule: true });
|
|
872
|
+
// …and the re-eval fires with the created entry, AFTER the relation write,
|
|
873
|
+
// WITHOUT the defer flag (it schedules the LLM run as normal).
|
|
874
|
+
expect(kernelCallWithSessionMock).toHaveBeenCalledWith('quality.evaluateHeuristicAndSchedule', {
|
|
875
|
+
entryId: 'DEC-79',
|
|
876
|
+
context: 'capture',
|
|
877
|
+
});
|
|
878
|
+
const callOrder = kernelCallWithSessionMock.mock.calls.map(([fn]) => fn);
|
|
879
|
+
expect(callOrder.indexOf('chain.createEntryRelation')).toBeLessThan(callOrder.indexOf('quality.evaluateHeuristicAndSchedule'));
|
|
880
|
+
// The receipt carries the POST-relation verdict, not the create-response one.
|
|
881
|
+
const jsonLines = stdoutOutput.split('\n').filter((line) => {
|
|
882
|
+
try {
|
|
883
|
+
JSON.parse(line);
|
|
884
|
+
return true;
|
|
885
|
+
}
|
|
886
|
+
catch {
|
|
887
|
+
return false;
|
|
888
|
+
}
|
|
889
|
+
});
|
|
890
|
+
expect(jsonLines).toHaveLength(1);
|
|
891
|
+
expect(JSON.parse(jsonLines[0]).coaching).toEqual(reEvalCoaching);
|
|
892
|
+
});
|
|
893
|
+
it('--link: keeps the create-response verdict when the re-eval fails (fail-open, BR-144)', async () => {
|
|
27
894
|
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
28
|
-
if (fn === 'chain.
|
|
29
|
-
return Promise.resolve(
|
|
895
|
+
if (fn === 'chain.capture')
|
|
896
|
+
return Promise.resolve(null);
|
|
30
897
|
if (fn === 'chain.createEntry')
|
|
31
|
-
return Promise.resolve({ docId: 'doc-
|
|
898
|
+
return Promise.resolve({ docId: 'doc-c4', entryId: 'DEC-80', coaching });
|
|
32
899
|
if (fn === 'chain.createEntryRelation')
|
|
33
|
-
return Promise.resolve({});
|
|
900
|
+
return Promise.resolve({ relationId: 'rel-1' });
|
|
901
|
+
if (fn === 'quality.evaluateHeuristicAndSchedule')
|
|
902
|
+
return Promise.reject(new Error('network'));
|
|
903
|
+
return Promise.resolve({});
|
|
904
|
+
});
|
|
905
|
+
let stdoutOutput = '';
|
|
906
|
+
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation((chunk) => {
|
|
907
|
+
stdoutOutput += String(chunk);
|
|
908
|
+
return true;
|
|
909
|
+
});
|
|
910
|
+
await runCapture({ text: 'DEC: chose with a broken re-eval', link: 'TEN-2', linkType: 'informs', json: true });
|
|
911
|
+
writeSpy.mockRestore();
|
|
912
|
+
const jsonLines = stdoutOutput.split('\n').filter((line) => {
|
|
913
|
+
try {
|
|
914
|
+
JSON.parse(line);
|
|
915
|
+
return true;
|
|
916
|
+
}
|
|
917
|
+
catch {
|
|
918
|
+
return false;
|
|
919
|
+
}
|
|
920
|
+
});
|
|
921
|
+
expect(jsonLines).toHaveLength(1);
|
|
922
|
+
expect(JSON.parse(jsonLines[0]).coaching).toEqual(coaching);
|
|
923
|
+
});
|
|
924
|
+
it('no --link: does NOT call the re-evaluation and does NOT defer the LLM schedule (plain capture unchanged)', async () => {
|
|
925
|
+
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
926
|
+
if (fn === 'chain.capture')
|
|
927
|
+
return Promise.resolve(null);
|
|
928
|
+
if (fn === 'chain.createEntry')
|
|
929
|
+
return Promise.resolve({ docId: 'doc-c5', entryId: 'DEC-81', coaching });
|
|
34
930
|
return Promise.resolve({});
|
|
35
931
|
});
|
|
36
932
|
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
37
|
-
await runCapture({ text: '
|
|
38
|
-
|
|
39
|
-
expect(kernelCallWithSessionMock).not.toHaveBeenCalledWith('
|
|
40
|
-
|
|
933
|
+
await runCapture({ text: 'DEC: chose without a link', json: true });
|
|
934
|
+
writeSpy.mockRestore();
|
|
935
|
+
expect(kernelCallWithSessionMock).not.toHaveBeenCalledWith('quality.evaluateHeuristicAndSchedule', expect.anything());
|
|
936
|
+
const createCall = kernelCallWithSessionMock.mock.calls.find(([fn]) => fn === 'chain.createEntry');
|
|
937
|
+
expect(createCall?.[1]).not.toHaveProperty('deferLLMSchedule');
|
|
938
|
+
});
|
|
939
|
+
});
|
|
940
|
+
// WP-690 S7 (TASK-120): the 'runCapture description field routing' describe block (TEN-1258's
|
|
941
|
+
// ASM:-shortcode -> 'assumptions' collectionSlug routing test) is DELETED here — `assumption` is
|
|
942
|
+
// one of the 15 genuinely-retired canonicalKeys (collectionRegistry.ts no longer carries an
|
|
943
|
+
// 'assumptions'/ASM entry at all), so the scenario this test asserted can no longer occur: an
|
|
944
|
+
// 'ASM:' capture now falls through to auto-classification (collectionSlug: undefined) instead of
|
|
945
|
+
// the old explicit-shortcode routing. Found via the CI Quality Gate on this PR (new failure caused
|
|
946
|
+
// by the S7 registry purge, fixed at root per the standing "fix new failures at root" contract —
|
|
947
|
+
// not deferred, not papered over).
|
|
948
|
+
describe('runCapture --field passthrough', () => {
|
|
949
|
+
beforeEach(() => {
|
|
950
|
+
kernelCallWithSessionMock.mockReset();
|
|
951
|
+
mockSession = { sessionId: 'sess-test' };
|
|
952
|
+
});
|
|
953
|
+
it('merges --field pairs into data', async () => {
|
|
954
|
+
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
955
|
+
if (fn === 'chain.capture')
|
|
956
|
+
return Promise.resolve(null);
|
|
957
|
+
if (fn === 'chain.createEntry')
|
|
958
|
+
return Promise.resolve({ docId: 'doc-6', entryId: 'STD-1' });
|
|
959
|
+
return Promise.resolve({});
|
|
960
|
+
});
|
|
961
|
+
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
962
|
+
await runCapture({
|
|
963
|
+
text: 'touched-code stewardship',
|
|
964
|
+
collection: 'standards',
|
|
965
|
+
field: ['rationale=signed specs define scope but agents need permission'],
|
|
966
|
+
});
|
|
41
967
|
expect(kernelCallWithSessionMock).toHaveBeenCalledWith('chain.createEntry', expect.objectContaining({
|
|
42
|
-
|
|
43
|
-
|
|
968
|
+
data: expect.objectContaining({
|
|
969
|
+
description: 'touched-code stewardship',
|
|
970
|
+
rationale: 'signed specs define scope but agents need permission',
|
|
971
|
+
}),
|
|
44
972
|
}));
|
|
45
|
-
expect(kernelCallWithSessionMock).toHaveBeenCalledWith('chain.createEntryRelation', {
|
|
46
|
-
fromEntryId: 'TEN-710',
|
|
47
|
-
toEntryId: 'BET-151',
|
|
48
|
-
type: 'surfaces_tension_in',
|
|
49
|
-
});
|
|
50
973
|
writeSpy.mockRestore();
|
|
51
974
|
});
|
|
52
|
-
it('
|
|
53
|
-
// Prefix "INS:" is extracted → skips classification, routes directly to insights
|
|
975
|
+
it('--field description=X overrides the derived description', async () => {
|
|
54
976
|
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
55
|
-
if (fn === 'chain.
|
|
56
|
-
return Promise.resolve(
|
|
977
|
+
if (fn === 'chain.capture')
|
|
978
|
+
return Promise.resolve(null);
|
|
57
979
|
if (fn === 'chain.createEntry')
|
|
58
|
-
return Promise.resolve({ docId: 'doc-
|
|
59
|
-
if (fn === 'chain.createEntryRelation')
|
|
60
|
-
return Promise.resolve({});
|
|
980
|
+
return Promise.resolve({ docId: 'doc-7', entryId: 'TEN-1' });
|
|
61
981
|
return Promise.resolve({});
|
|
62
982
|
});
|
|
63
983
|
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
64
|
-
await runCapture({
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
toEntryId: 'DEC-264',
|
|
69
|
-
type: 'informed_by',
|
|
984
|
+
await runCapture({
|
|
985
|
+
text: 'derived',
|
|
986
|
+
collection: 'tensions',
|
|
987
|
+
field: ['description=explicit'],
|
|
70
988
|
});
|
|
989
|
+
expect(kernelCallWithSessionMock).toHaveBeenCalledWith('chain.createEntry', expect.objectContaining({
|
|
990
|
+
data: expect.objectContaining({ description: 'explicit' }),
|
|
991
|
+
}));
|
|
71
992
|
writeSpy.mockRestore();
|
|
72
993
|
});
|
|
73
994
|
});
|
|
74
|
-
|
|
995
|
+
// TASK-584 (WP-802, TEN-4312): the CLI sends only the fields the caller sent. The default
|
|
996
|
+
// description (the capture text) exists to be remapped into the collection's primary field;
|
|
997
|
+
// when -f already set that field and no -d was passed, it is left out.
|
|
998
|
+
describe('runCapture sends only caller fields (TASK-584)', () => {
|
|
75
999
|
beforeEach(() => {
|
|
76
1000
|
kernelCallWithSessionMock.mockReset();
|
|
77
1001
|
mockSession = { sessionId: 'sess-test' };
|
|
78
1002
|
});
|
|
79
|
-
|
|
80
|
-
|
|
1003
|
+
const bodyContract = { governed: false, whyField: null, minChars: 0, descriptionFieldKey: 'body' };
|
|
1004
|
+
const createData = () => kernelCallWithSessionMock.mock.calls.find(([fn]) => fn === 'chain.createEntry')?.[1]?.data;
|
|
1005
|
+
it('omits description when -f sets the primary field and no -d is given', async () => {
|
|
81
1006
|
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
82
|
-
if (fn === 'chain.
|
|
83
|
-
return Promise.resolve(
|
|
1007
|
+
if (fn === 'chain.capture')
|
|
1008
|
+
return Promise.resolve(null);
|
|
1009
|
+
if (fn === 'chain.getCollectionFields')
|
|
1010
|
+
return Promise.resolve(bodyContract);
|
|
84
1011
|
if (fn === 'chain.createEntry')
|
|
85
|
-
return Promise.resolve({ docId: '
|
|
1012
|
+
return Promise.resolve({ docId: 'd', entryId: 'INS-1', status: 'draft' });
|
|
86
1013
|
return Promise.resolve({});
|
|
87
1014
|
});
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
1015
|
+
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
1016
|
+
await runCapture({ text: 'an insight', collection: 'insights', field: ['body=the full body'] });
|
|
1017
|
+
writeSpy.mockRestore();
|
|
1018
|
+
expect(createData()).toEqual({ body: 'the full body' });
|
|
1019
|
+
});
|
|
1020
|
+
it('keeps description when -d is given, even with -f body', async () => {
|
|
1021
|
+
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
1022
|
+
if (fn === 'chain.capture')
|
|
1023
|
+
return Promise.resolve(null);
|
|
1024
|
+
if (fn === 'chain.getCollectionFields')
|
|
1025
|
+
return Promise.resolve(bodyContract);
|
|
1026
|
+
if (fn === 'chain.createEntry')
|
|
1027
|
+
return Promise.resolve({ docId: 'd', entryId: 'INS-2', status: 'draft' });
|
|
1028
|
+
return Promise.resolve({});
|
|
92
1029
|
});
|
|
93
|
-
|
|
1030
|
+
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
1031
|
+
await runCapture({ text: 'an insight', description: 'explicit', collection: 'insights', field: ['body=b'] });
|
|
94
1032
|
writeSpy.mockRestore();
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
return
|
|
1033
|
+
expect(createData()).toEqual({ description: 'explicit', body: 'b' });
|
|
1034
|
+
});
|
|
1035
|
+
it('keeps description on a bare capture so the server can remap it into body', async () => {
|
|
1036
|
+
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
1037
|
+
if (fn === 'chain.capture')
|
|
1038
|
+
return Promise.resolve(null);
|
|
1039
|
+
if (fn === 'chain.getCollectionFields')
|
|
1040
|
+
return Promise.resolve(bodyContract);
|
|
1041
|
+
if (fn === 'chain.createEntry')
|
|
1042
|
+
return Promise.resolve({ docId: 'd', entryId: 'INS-3', status: 'draft' });
|
|
1043
|
+
return Promise.resolve({});
|
|
1044
|
+
});
|
|
1045
|
+
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
1046
|
+
await runCapture({ text: 'an insight', collection: 'insights' });
|
|
1047
|
+
writeSpy.mockRestore();
|
|
1048
|
+
expect(createData()).toEqual({ description: 'an insight' });
|
|
1049
|
+
});
|
|
1050
|
+
it('sends description as before when the contract fetch fails', async () => {
|
|
1051
|
+
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
1052
|
+
if (fn === 'chain.capture')
|
|
1053
|
+
return Promise.resolve(null);
|
|
1054
|
+
if (fn === 'chain.getCollectionFields')
|
|
1055
|
+
return Promise.reject(new Error('network'));
|
|
1056
|
+
if (fn === 'chain.createEntry')
|
|
1057
|
+
return Promise.resolve({ docId: 'd', entryId: 'INS-4', status: 'draft' });
|
|
1058
|
+
return Promise.resolve({});
|
|
1059
|
+
});
|
|
1060
|
+
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
1061
|
+
await runCapture({ text: 'an insight', collection: 'insights', field: ['body=b'] });
|
|
1062
|
+
writeSpy.mockRestore();
|
|
1063
|
+
expect(createData()).toEqual({ description: 'an insight', body: 'b' });
|
|
1064
|
+
});
|
|
1065
|
+
it('a landed create with a dropped field resolves (exit 0) and names only that field as dropped', async () => {
|
|
1066
|
+
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
1067
|
+
if (fn === 'chain.capture')
|
|
1068
|
+
return Promise.resolve(null);
|
|
1069
|
+
if (fn === 'chain.getCollectionFields')
|
|
1070
|
+
return Promise.resolve(bodyContract);
|
|
1071
|
+
if (fn === 'chain.createEntry') {
|
|
1072
|
+
return Promise.resolve({
|
|
1073
|
+
docId: 'd', entryId: 'INS-5', status: 'draft', warnings: ['Unknown fields dropped: nosuchfield. Expected: body (text, required).'],
|
|
1074
|
+
normalization: { remapped: {}, rejected: ['nosuchfield'], accepted: ['body'] },
|
|
1075
|
+
});
|
|
103
1076
|
}
|
|
1077
|
+
return Promise.resolve({});
|
|
104
1078
|
});
|
|
105
|
-
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
expect(
|
|
1079
|
+
const out = [];
|
|
1080
|
+
const errOut = [];
|
|
1081
|
+
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation((chunk) => { out.push(String(chunk)); return true; });
|
|
1082
|
+
const errSpy = vi.spyOn(process.stderr, 'write').mockImplementation((chunk) => { errOut.push(String(chunk)); return true; });
|
|
1083
|
+
await expect(runCapture({ text: 'an insight', collection: 'insights', field: ['nosuchfield=x'], json: true })).resolves.toBeUndefined();
|
|
1084
|
+
writeSpy.mockRestore();
|
|
1085
|
+
errSpy.mockRestore();
|
|
1086
|
+
expect(JSON.parse(out.join(''))).toMatchObject({ id: 'INS-5', droppedFields: ['nosuchfield'] });
|
|
1087
|
+
expect(errOut.join('')).not.toContain('Fields rejected');
|
|
1088
|
+
});
|
|
1089
|
+
it('the human receipt names the dropped field as a warning, with pb fields for the collection', () => {
|
|
1090
|
+
const out = formatCaptureReceipt({
|
|
1091
|
+
entryId: 'INS-5', name: 'an insight', collection: 'insights', status: 'draft', classification: null,
|
|
1092
|
+
warnings: ['Unknown fields dropped: nosuchfield. Expected: body (text, required).'],
|
|
1093
|
+
normalization: { remapped: {}, rejected: ['nosuchfield'], accepted: [] },
|
|
1094
|
+
});
|
|
1095
|
+
expect(out).toContain('Warning: Unknown fields dropped: nosuchfield.');
|
|
1096
|
+
expect(out).toContain('pb fields insights');
|
|
1097
|
+
expect(out).not.toContain('Rejected fields');
|
|
110
1098
|
});
|
|
111
1099
|
});
|
|
112
|
-
describe('runCapture
|
|
1100
|
+
describe('runCapture WHY pre-flight', () => {
|
|
113
1101
|
beforeEach(() => {
|
|
114
1102
|
kernelCallWithSessionMock.mockReset();
|
|
115
1103
|
mockSession = { sessionId: 'sess-test' };
|
|
116
1104
|
});
|
|
117
|
-
it('
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
1105
|
+
it('blocks with guidance when governed and whyField is missing', async () => {
|
|
1106
|
+
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
1107
|
+
if (fn === 'chain.capture')
|
|
1108
|
+
return Promise.resolve(null);
|
|
1109
|
+
if (fn === 'chain.getCollectionFields') {
|
|
1110
|
+
return Promise.resolve({ governed: true, whyField: 'rationale', minChars: 12, fields: [] });
|
|
1111
|
+
}
|
|
1112
|
+
if (fn === 'chain.createEntry')
|
|
1113
|
+
return Promise.resolve({ docId: 'doc-8', entryId: 'STD-2' });
|
|
1114
|
+
return Promise.resolve({});
|
|
1115
|
+
});
|
|
1116
|
+
await expect(runCapture({ text: 'x', collection: 'standards' })).rejects.toThrow(/rationale/);
|
|
1117
|
+
expect(kernelCallWithSessionMock).not.toHaveBeenCalledWith('chain.createEntry', expect.anything());
|
|
1118
|
+
});
|
|
1119
|
+
it('blocks with guidance for a why-required, non-governed collection (WP-770 W2a, DEC-1787 ruling A)', async () => {
|
|
1120
|
+
// purpose/vision/strategy/objective are why-required but NOT `governed` (steering-shared
|
|
1121
|
+
// subject) — the gate must fire on `whyField` alone, since getCollectionFields now widens
|
|
1122
|
+
// `whyField` for these four independently of `governed`.
|
|
1123
|
+
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
1124
|
+
if (fn === 'chain.capture')
|
|
1125
|
+
return Promise.resolve(null);
|
|
1126
|
+
if (fn === 'chain.getCollectionFields') {
|
|
1127
|
+
return Promise.resolve({ governed: false, whyField: 'why', minChars: 12, fields: [] });
|
|
1128
|
+
}
|
|
1129
|
+
if (fn === 'chain.createEntry')
|
|
1130
|
+
return Promise.resolve({ docId: 'doc-10', entryId: 'STRAT-2' });
|
|
1131
|
+
return Promise.resolve({});
|
|
1132
|
+
});
|
|
1133
|
+
await expect(runCapture({ text: 'x', collection: 'strategy' })).rejects.toThrow(/why/);
|
|
1134
|
+
expect(kernelCallWithSessionMock).not.toHaveBeenCalledWith('chain.createEntry', expect.anything());
|
|
1135
|
+
});
|
|
1136
|
+
it('does not block when whyField is description', async () => {
|
|
121
1137
|
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
122
|
-
if (fn === 'chain.
|
|
123
|
-
return Promise.resolve(
|
|
1138
|
+
if (fn === 'chain.capture')
|
|
1139
|
+
return Promise.resolve(null);
|
|
1140
|
+
if (fn === 'chain.getCollectionFields') {
|
|
1141
|
+
return Promise.resolve({ governed: true, whyField: 'description', minChars: 12, fields: [] });
|
|
1142
|
+
}
|
|
124
1143
|
if (fn === 'chain.createEntry')
|
|
125
|
-
return Promise.resolve({ docId: 'doc-
|
|
1144
|
+
return Promise.resolve({ docId: 'doc-9', entryId: 'ARCH-1' });
|
|
126
1145
|
return Promise.resolve({});
|
|
127
1146
|
});
|
|
128
1147
|
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
129
|
-
await runCapture({ text: '
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
1148
|
+
await runCapture({ text: 'an architecture note body', collection: 'architecture' });
|
|
1149
|
+
expect(kernelCallWithSessionMock).toHaveBeenCalledWith('chain.createEntry', expect.anything());
|
|
1150
|
+
writeSpy.mockRestore();
|
|
1151
|
+
});
|
|
1152
|
+
it('does not block when description remaps to the whyField (descriptionFieldKey === whyField)', async () => {
|
|
1153
|
+
// TEN-1258 regression: `decisions` sets descriptionFieldKey='rationale' and the server
|
|
1154
|
+
// remaps data.description → rationale before the WHY gate. A bare `pb capture "DEC: …"`
|
|
1155
|
+
// (description set, no --field rationale) must NOT be false-blocked client-side.
|
|
1156
|
+
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
1157
|
+
if (fn === 'chain.capture')
|
|
1158
|
+
return Promise.resolve(null);
|
|
1159
|
+
if (fn === 'chain.getCollectionFields') {
|
|
1160
|
+
return Promise.resolve({
|
|
1161
|
+
governed: true,
|
|
1162
|
+
whyField: 'rationale',
|
|
1163
|
+
minChars: 12,
|
|
1164
|
+
descriptionFieldKey: 'rationale',
|
|
1165
|
+
fields: [],
|
|
1166
|
+
});
|
|
1167
|
+
}
|
|
1168
|
+
if (fn === 'chain.createEntry')
|
|
1169
|
+
return Promise.resolve({ docId: 'doc-12', entryId: 'DEC-5' });
|
|
1170
|
+
return Promise.resolve({});
|
|
1171
|
+
});
|
|
1172
|
+
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
1173
|
+
await runCapture({ text: 'chose X because it is simpler', collection: 'decisions' });
|
|
1174
|
+
expect(kernelCallWithSessionMock).toHaveBeenCalledWith('chain.createEntry', expect.anything());
|
|
1175
|
+
writeSpy.mockRestore();
|
|
1176
|
+
});
|
|
1177
|
+
it('still blocks a governed collection whose descriptionFieldKey does NOT map to the whyField', async () => {
|
|
1178
|
+
// proof_governed has whyField='rationale' but no descriptionFieldKey remap, so a bare
|
|
1179
|
+
// capture (no --field rationale) is correctly blocked — the description will not satisfy it.
|
|
1180
|
+
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
1181
|
+
if (fn === 'chain.capture')
|
|
1182
|
+
return Promise.resolve(null);
|
|
1183
|
+
if (fn === 'chain.getCollectionFields') {
|
|
1184
|
+
return Promise.resolve({
|
|
1185
|
+
governed: true,
|
|
1186
|
+
whyField: 'rationale',
|
|
1187
|
+
minChars: 12,
|
|
1188
|
+
descriptionFieldKey: null,
|
|
1189
|
+
fields: [],
|
|
1190
|
+
});
|
|
1191
|
+
}
|
|
1192
|
+
if (fn === 'chain.createEntry')
|
|
1193
|
+
return Promise.resolve({ docId: 'doc-13', entryId: 'PGV-9' });
|
|
1194
|
+
return Promise.resolve({});
|
|
1195
|
+
});
|
|
1196
|
+
await expect(runCapture({ text: 'x', collection: 'proof_governed' })).rejects.toThrow(/rationale/);
|
|
1197
|
+
expect(kernelCallWithSessionMock).not.toHaveBeenCalledWith('chain.createEntry', expect.anything());
|
|
1198
|
+
});
|
|
1199
|
+
it('fails open and proceeds when the contract fetch fails', async () => {
|
|
1200
|
+
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
1201
|
+
if (fn === 'chain.capture')
|
|
1202
|
+
return Promise.resolve(null);
|
|
1203
|
+
if (fn === 'chain.getCollectionFields')
|
|
1204
|
+
return Promise.reject(new Error('network'));
|
|
1205
|
+
if (fn === 'chain.createEntry')
|
|
1206
|
+
return Promise.resolve({ docId: 'doc-10', entryId: 'STD-3' });
|
|
1207
|
+
return Promise.resolve({});
|
|
1208
|
+
});
|
|
1209
|
+
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
1210
|
+
await runCapture({
|
|
1211
|
+
text: 'x',
|
|
1212
|
+
collection: 'standards',
|
|
1213
|
+
field: ['rationale=enough characters here ok'],
|
|
1214
|
+
});
|
|
1215
|
+
expect(kernelCallWithSessionMock).toHaveBeenCalledWith('chain.createEntry', expect.anything());
|
|
1216
|
+
writeSpy.mockRestore();
|
|
1217
|
+
});
|
|
1218
|
+
it('fails open when the contract fetch rejects with a CLIError (server 4xx/5xx surfaces as McpError, an instanceof CLIError)', async () => {
|
|
1219
|
+
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
1220
|
+
if (fn === 'chain.capture')
|
|
1221
|
+
return Promise.resolve(null);
|
|
1222
|
+
if (fn === 'chain.getCollectionFields') {
|
|
1223
|
+
return Promise.reject(new CLIError('Could not reach test.convex.site.', {
|
|
1224
|
+
code: ErrorCode.NETWORK_UNREACHABLE,
|
|
1225
|
+
category: 'network',
|
|
1226
|
+
}));
|
|
1227
|
+
}
|
|
1228
|
+
if (fn === 'chain.createEntry')
|
|
1229
|
+
return Promise.resolve({ docId: 'doc-11', entryId: 'STD-4' });
|
|
1230
|
+
return Promise.resolve({});
|
|
1231
|
+
});
|
|
1232
|
+
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
1233
|
+
await runCapture({
|
|
1234
|
+
text: 'x',
|
|
1235
|
+
collection: 'standards',
|
|
1236
|
+
field: ['rationale=enough characters here ok'],
|
|
135
1237
|
});
|
|
1238
|
+
expect(kernelCallWithSessionMock).toHaveBeenCalledWith('chain.createEntry', expect.anything());
|
|
136
1239
|
writeSpy.mockRestore();
|
|
137
1240
|
});
|
|
1241
|
+
it('surfaces the server WHY-gate reason on rejection', async () => {
|
|
1242
|
+
const serverReason = 'Governance entries (standard) require an explicit WHY before they can be created. Set "rationale" to at least 12 characters.';
|
|
1243
|
+
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
1244
|
+
if (fn === 'chain.capture')
|
|
1245
|
+
return Promise.resolve(null);
|
|
1246
|
+
if (fn === 'chain.getCollectionFields') {
|
|
1247
|
+
return Promise.resolve({ governed: true, whyField: 'rationale', minChars: 12, fields: [] });
|
|
1248
|
+
}
|
|
1249
|
+
if (fn === 'chain.createEntry')
|
|
1250
|
+
return Promise.reject(new Error(serverReason));
|
|
1251
|
+
return Promise.resolve({});
|
|
1252
|
+
});
|
|
1253
|
+
await expect(runCapture({
|
|
1254
|
+
text: 'x',
|
|
1255
|
+
collection: 'standards',
|
|
1256
|
+
field: ['rationale=short'],
|
|
1257
|
+
})).rejects.toThrow(/at least 12 characters/);
|
|
1258
|
+
});
|
|
138
1259
|
});
|
|
139
1260
|
describe('runCapture classification guard', () => {
|
|
140
1261
|
beforeEach(() => {
|
|
@@ -146,71 +1267,60 @@ describe('runCapture classification guard', () => {
|
|
|
146
1267
|
await expect(runCapture({ text: 'Ambiguous capture' })).rejects.toThrow('Classification needs review before capture can continue.');
|
|
147
1268
|
});
|
|
148
1269
|
});
|
|
149
|
-
describe('runCapture date
|
|
1270
|
+
describe('runCapture writes no date (TEN-4244, DEC-1787)', () => {
|
|
150
1271
|
beforeEach(() => {
|
|
151
1272
|
kernelCallWithSessionMock.mockReset();
|
|
152
1273
|
mockSession = { sessionId: 'sess-test' };
|
|
153
1274
|
});
|
|
154
|
-
it(
|
|
1275
|
+
it.each([
|
|
1276
|
+
['tasks', 'TASK-10', 'Task due April 1, 2026'],
|
|
1277
|
+
['decisions', 'DEC-10', 'Decision from April 1, 2026 steering meeting'],
|
|
1278
|
+
['tasks', 'TASK-11', 'Task without any date'],
|
|
1279
|
+
])('a %s capture carries no data.date, even when the text names a date', async (collection, entryId, text) => {
|
|
155
1280
|
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
156
|
-
if (fn === 'chain.
|
|
157
|
-
return Promise.resolve(
|
|
1281
|
+
if (fn === 'chain.capture')
|
|
1282
|
+
return Promise.resolve(null);
|
|
158
1283
|
if (fn === 'chain.resolveCollection')
|
|
159
|
-
return Promise.resolve({ collection
|
|
1284
|
+
return Promise.resolve({ collection, confidence: 0.9, tier: 'high' });
|
|
160
1285
|
if (fn === 'chain.createEntry')
|
|
161
|
-
return Promise.resolve({ docId: 'doc-3', entryId
|
|
1286
|
+
return Promise.resolve({ docId: 'doc-3', entryId });
|
|
162
1287
|
return Promise.resolve({});
|
|
163
1288
|
});
|
|
164
1289
|
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
165
|
-
await runCapture({ text
|
|
1290
|
+
await runCapture({ text });
|
|
166
1291
|
const createCall = kernelCallWithSessionMock.mock.calls.find(([fn]) => fn === 'chain.createEntry');
|
|
167
|
-
expect(createCall?.[1]).toMatchObject({
|
|
168
|
-
collectionSlug: 'decisions',
|
|
169
|
-
data: { description: 'Decision without explicit source date' },
|
|
170
|
-
});
|
|
1292
|
+
expect(createCall?.[1]).toMatchObject({ collectionSlug: collection });
|
|
171
1293
|
expect((createCall?.[1]).data).not.toHaveProperty('date');
|
|
172
1294
|
writeSpy.mockRestore();
|
|
173
1295
|
});
|
|
174
|
-
it('uses inferred source date when the capture text includes one', async () => {
|
|
175
|
-
kernelCallWithSessionMock.mockImplementation((fn) => {
|
|
176
|
-
if (fn === 'chain.suggestLinksForCapture')
|
|
177
|
-
return Promise.resolve([]);
|
|
178
|
-
if (fn === 'chain.resolveCollection')
|
|
179
|
-
return Promise.resolve({ collection: 'decisions', confidence: 0.9, tier: 'high' });
|
|
180
|
-
if (fn === 'chain.createEntry')
|
|
181
|
-
return Promise.resolve({ docId: 'doc-4', entryId: 'DEC-11' });
|
|
182
|
-
return Promise.resolve({});
|
|
183
|
-
});
|
|
184
|
-
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
185
|
-
await runCapture({ text: 'Decision from April 1, 2026 steering meeting' });
|
|
186
|
-
const createCall = kernelCallWithSessionMock.mock.calls.find(([fn]) => fn === 'chain.createEntry');
|
|
187
|
-
expect((createCall?.[1]).data.date).toBe('2026-04-01');
|
|
188
|
-
writeSpy.mockRestore();
|
|
189
|
-
});
|
|
190
1296
|
});
|
|
191
1297
|
// ---------------------------------------------------------------------------
|
|
192
|
-
// WP-319 S3: Pre-write grounding tests
|
|
1298
|
+
// WP-319 S3 / WP-755 C1a: Pre-write grounding tests (the one capture door)
|
|
193
1299
|
// ---------------------------------------------------------------------------
|
|
194
|
-
describe('runCapture WP-319 grounding', () => {
|
|
195
|
-
const
|
|
196
|
-
const
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
governance: [],
|
|
201
|
-
v: 1,
|
|
1300
|
+
describe('runCapture WP-319/WP-755 grounding', () => {
|
|
1301
|
+
const emptyVerdict = { kind: 'create', candidates: [], scanTruncated: false };
|
|
1302
|
+
const askVerdict = {
|
|
1303
|
+
kind: 'ask',
|
|
1304
|
+
candidates: [{ entryId: 'TEN-5', name: 'Similar tension', collectionSlug: 'tensions', score: 0.6 }],
|
|
1305
|
+
scanTruncated: false,
|
|
202
1306
|
};
|
|
203
1307
|
beforeEach(() => {
|
|
204
1308
|
kernelCallWithSessionMock.mockReset();
|
|
205
1309
|
mockSession = { sessionId: 'sess-test' };
|
|
206
1310
|
delete process.env.PB_GROUNDING_MODE;
|
|
1311
|
+
// Pre-existing gap this fix round's new --strict tests surfaced: runner.ts's outputMode is
|
|
1312
|
+
// module-level `let` state, set permanently by any earlier test in this file that passed
|
|
1313
|
+
// `json: true` (setOutputMode is never test-scoped). Reset it here so a later test's
|
|
1314
|
+
// `!json` branches (the --strict prompt gate) are never silently skipped by an earlier
|
|
1315
|
+
// test's leaked JSON mode.
|
|
1316
|
+
setOutputMode('auto');
|
|
207
1317
|
});
|
|
208
|
-
it('fires chain.
|
|
1318
|
+
it('fires chain.capture in parallel and still calls createEntry', async () => {
|
|
209
1319
|
// Prefix-based route skips classification; grounding fires for TEN prefix
|
|
210
1320
|
kernelCallWithSessionMock
|
|
211
1321
|
.mockImplementation((fn) => {
|
|
212
|
-
if (fn === 'chain.
|
|
213
|
-
return Promise.resolve(
|
|
1322
|
+
if (fn === 'chain.capture')
|
|
1323
|
+
return Promise.resolve(emptyVerdict);
|
|
214
1324
|
if (fn === 'chain.createEntry')
|
|
215
1325
|
return Promise.resolve({ docId: 'doc-1', entryId: 'TEN-720' });
|
|
216
1326
|
return Promise.resolve({});
|
|
@@ -218,8 +1328,8 @@ describe('runCapture WP-319 grounding', () => {
|
|
|
218
1328
|
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
219
1329
|
const stderrSpy = vi.spyOn(process.stderr, 'write').mockImplementation(() => true);
|
|
220
1330
|
await runCapture({ text: 'TEN: grounding test tension' });
|
|
221
|
-
expect(kernelCallWithSessionMock).toHaveBeenCalledWith('chain.
|
|
222
|
-
|
|
1331
|
+
expect(kernelCallWithSessionMock).toHaveBeenCalledWith('chain.capture', expect.objectContaining({
|
|
1332
|
+
name: 'grounding test tension',
|
|
223
1333
|
}));
|
|
224
1334
|
expect(kernelCallWithSessionMock).toHaveBeenCalledWith('chain.createEntry', expect.anything());
|
|
225
1335
|
writeSpy.mockRestore();
|
|
@@ -228,7 +1338,7 @@ describe('runCapture WP-319 grounding', () => {
|
|
|
228
1338
|
it('does NOT block capture when grounding call fails', async () => {
|
|
229
1339
|
kernelCallWithSessionMock
|
|
230
1340
|
.mockImplementation((fn) => {
|
|
231
|
-
if (fn === 'chain.
|
|
1341
|
+
if (fn === 'chain.capture')
|
|
232
1342
|
return Promise.reject(new Error('network error'));
|
|
233
1343
|
if (fn === 'chain.createEntry')
|
|
234
1344
|
return Promise.resolve({ docId: 'doc-2', entryId: 'TEN-721' });
|
|
@@ -242,70 +1352,11 @@ describe('runCapture WP-319 grounding', () => {
|
|
|
242
1352
|
writeSpy.mockRestore();
|
|
243
1353
|
stderrSpy.mockRestore();
|
|
244
1354
|
});
|
|
245
|
-
it('
|
|
246
|
-
// In test env (non-TTY), isJsonMode() returns true → JSON path is taken.
|
|
247
|
-
kernelCallWithSessionMock
|
|
248
|
-
.mockImplementation((fn) => {
|
|
249
|
-
if (fn === 'chain.suggestLinksForCapture')
|
|
250
|
-
return Promise.resolve([groundingWithDuplicate]);
|
|
251
|
-
return Promise.resolve({});
|
|
252
|
-
});
|
|
253
|
-
let stdoutOutput = '';
|
|
254
|
-
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation((chunk) => {
|
|
255
|
-
stdoutOutput += String(chunk);
|
|
256
|
-
return true;
|
|
257
|
-
});
|
|
258
|
-
const stderrSpy = vi.spyOn(process.stderr, 'write').mockImplementation(() => true);
|
|
259
|
-
await runCapture({ text: 'TEN: duplicate candidate', suggestOnly: true });
|
|
260
|
-
expect(kernelCallWithSessionMock).not.toHaveBeenCalledWith('chain.createEntry', expect.anything());
|
|
261
|
-
// JSON output contains suggestOnly flag and grounding report
|
|
262
|
-
const jsonLines = stdoutOutput.split('\n').filter((l) => { try {
|
|
263
|
-
JSON.parse(l);
|
|
264
|
-
return true;
|
|
265
|
-
}
|
|
266
|
-
catch {
|
|
267
|
-
return false;
|
|
268
|
-
} });
|
|
269
|
-
expect(jsonLines).toHaveLength(1);
|
|
270
|
-
const parsed = JSON.parse(jsonLines[0]);
|
|
271
|
-
expect(parsed.suggestOnly).toBe(true);
|
|
272
|
-
expect(parsed.groundingReport).toBeDefined();
|
|
273
|
-
writeSpy.mockRestore();
|
|
274
|
-
stderrSpy.mockRestore();
|
|
275
|
-
});
|
|
276
|
-
it('--suggest-only with --json outputs machine-readable object without calling createEntry', async () => {
|
|
277
|
-
kernelCallWithSessionMock
|
|
278
|
-
.mockImplementation((fn) => {
|
|
279
|
-
if (fn === 'chain.suggestLinksForCapture')
|
|
280
|
-
return Promise.resolve([emptyGrounding]);
|
|
281
|
-
return Promise.resolve({});
|
|
282
|
-
});
|
|
283
|
-
let stdoutOutput = '';
|
|
284
|
-
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation((chunk) => {
|
|
285
|
-
stdoutOutput += String(chunk);
|
|
286
|
-
return true;
|
|
287
|
-
});
|
|
288
|
-
const stderrSpy = vi.spyOn(process.stderr, 'write').mockImplementation(() => true);
|
|
289
|
-
await runCapture({ text: 'TEN: dry run json', json: true, suggestOnly: true });
|
|
290
|
-
expect(kernelCallWithSessionMock).not.toHaveBeenCalledWith('chain.createEntry', expect.anything());
|
|
291
|
-
const jsonLines = stdoutOutput.split('\n').filter((l) => { try {
|
|
292
|
-
JSON.parse(l);
|
|
293
|
-
return true;
|
|
294
|
-
}
|
|
295
|
-
catch {
|
|
296
|
-
return false;
|
|
297
|
-
} });
|
|
298
|
-
expect(jsonLines).toHaveLength(1);
|
|
299
|
-
const parsed = JSON.parse(jsonLines[0]);
|
|
300
|
-
expect(parsed.suggestOnly).toBe(true);
|
|
301
|
-
writeSpy.mockRestore();
|
|
302
|
-
stderrSpy.mockRestore();
|
|
303
|
-
});
|
|
304
|
-
it('banner is suppressed when grounding has no matches (zero-noise floor)', async () => {
|
|
1355
|
+
it('a create verdict prints no Related line and no how-it-connects list (TASK-608, DEC-1915)', async () => {
|
|
305
1356
|
kernelCallWithSessionMock
|
|
306
1357
|
.mockImplementation((fn) => {
|
|
307
|
-
if (fn === 'chain.
|
|
308
|
-
return Promise.resolve(
|
|
1358
|
+
if (fn === 'chain.capture')
|
|
1359
|
+
return Promise.resolve(emptyVerdict);
|
|
309
1360
|
if (fn === 'chain.createEntry')
|
|
310
1361
|
return Promise.resolve({ docId: 'doc-3', entryId: 'TEN-722' });
|
|
311
1362
|
return Promise.resolve({});
|
|
@@ -317,13 +1368,15 @@ describe('runCapture WP-319 grounding', () => {
|
|
|
317
1368
|
return true;
|
|
318
1369
|
});
|
|
319
1370
|
await runCapture({ text: 'TEN: no matches tension' });
|
|
320
|
-
// No "
|
|
321
|
-
const groundingInStderr = stderrLines.some((l) => l.includes('
|
|
1371
|
+
// No "Related"/"Possible match" banner in stderr, and no first-capture "how it connects" list.
|
|
1372
|
+
const groundingInStderr = stderrLines.some((l) => l.includes('Related') || l.includes('Possible match'));
|
|
322
1373
|
expect(groundingInStderr).toBe(false);
|
|
1374
|
+
const stdoutText = writeSpy.mock.calls.map(([chunk]) => String(chunk)).join('');
|
|
1375
|
+
expect(stdoutText).not.toContain('how it connects');
|
|
323
1376
|
writeSpy.mockRestore();
|
|
324
1377
|
stderrSpy.mockRestore();
|
|
325
1378
|
});
|
|
326
|
-
it('PB_GROUNDING_MODE=off skips
|
|
1379
|
+
it('PB_GROUNDING_MODE=off skips the door entirely', async () => {
|
|
327
1380
|
process.env.PB_GROUNDING_MODE = 'off';
|
|
328
1381
|
kernelCallWithSessionMock
|
|
329
1382
|
.mockImplementation((fn) => {
|
|
@@ -334,7 +1387,7 @@ describe('runCapture WP-319 grounding', () => {
|
|
|
334
1387
|
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
335
1388
|
const stderrSpy = vi.spyOn(process.stderr, 'write').mockImplementation(() => true);
|
|
336
1389
|
await runCapture({ text: 'TEN: no grounding env off' });
|
|
337
|
-
expect(kernelCallWithSessionMock).not.toHaveBeenCalledWith('chain.
|
|
1390
|
+
expect(kernelCallWithSessionMock).not.toHaveBeenCalledWith('chain.capture', expect.anything());
|
|
338
1391
|
expect(kernelCallWithSessionMock).toHaveBeenCalledWith('chain.createEntry', expect.anything());
|
|
339
1392
|
delete process.env.PB_GROUNDING_MODE;
|
|
340
1393
|
writeSpy.mockRestore();
|
|
@@ -343,8 +1396,8 @@ describe('runCapture WP-319 grounding', () => {
|
|
|
343
1396
|
it('--json output stdout is clean (no grounding on stdout)', async () => {
|
|
344
1397
|
kernelCallWithSessionMock
|
|
345
1398
|
.mockImplementation((fn) => {
|
|
346
|
-
if (fn === 'chain.
|
|
347
|
-
return Promise.resolve(
|
|
1399
|
+
if (fn === 'chain.capture')
|
|
1400
|
+
return Promise.resolve(askVerdict);
|
|
348
1401
|
if (fn === 'chain.createEntry')
|
|
349
1402
|
return Promise.resolve({ docId: 'doc-5', entryId: 'TEN-724' });
|
|
350
1403
|
return Promise.resolve({});
|
|
@@ -369,9 +1422,112 @@ describe('runCapture WP-319 grounding', () => {
|
|
|
369
1422
|
expect(parsed.id).toBe('TEN-724');
|
|
370
1423
|
// No grounding content in stdout
|
|
371
1424
|
expect(stdoutOutput).not.toContain('Grounding');
|
|
372
|
-
expect(stdoutOutput).not.toContain('
|
|
1425
|
+
expect(stdoutOutput).not.toContain('Possible match');
|
|
1426
|
+
writeSpy.mockRestore();
|
|
1427
|
+
stderrSpy.mockRestore();
|
|
1428
|
+
});
|
|
1429
|
+
// TASK-619: an automated --json caller must learn the close match (id, name, collection, score)
|
|
1430
|
+
// to update it deliberately — still one JSON line on stdout.
|
|
1431
|
+
it('--json on an ask verdict carries possibleMatches in the single JSON line', async () => {
|
|
1432
|
+
kernelCallWithSessionMock
|
|
1433
|
+
.mockImplementation((fn) => {
|
|
1434
|
+
if (fn === 'chain.capture')
|
|
1435
|
+
return Promise.resolve(askVerdict);
|
|
1436
|
+
if (fn === 'chain.createEntry')
|
|
1437
|
+
return Promise.resolve({ docId: 'doc-6', entryId: 'TEN-725' });
|
|
1438
|
+
return Promise.resolve({});
|
|
1439
|
+
});
|
|
1440
|
+
let stdoutOutput = '';
|
|
1441
|
+
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation((chunk) => { stdoutOutput += String(chunk); return true; });
|
|
1442
|
+
const stderrSpy = vi.spyOn(process.stderr, 'write').mockImplementation(() => true);
|
|
1443
|
+
await runCapture({ text: 'TEN: json ask shape', json: true });
|
|
1444
|
+
const lines = stdoutOutput.split('\n').filter((l) => l.trim());
|
|
1445
|
+
expect(lines).toHaveLength(1);
|
|
1446
|
+
const parsed = JSON.parse(lines[0]);
|
|
1447
|
+
expect(parsed.id).toBe('TEN-725');
|
|
1448
|
+
expect(parsed.possibleMatches).toEqual([{ entryId: 'TEN-5', name: 'Similar tension', collection: 'tensions', score: 0.6 }]);
|
|
1449
|
+
expect(kernelCallWithSessionMock).not.toHaveBeenCalledWith('chain.updateEntry', expect.anything());
|
|
1450
|
+
writeSpy.mockRestore();
|
|
1451
|
+
stderrSpy.mockRestore();
|
|
1452
|
+
});
|
|
1453
|
+
it('--json on a create verdict carries no possibleMatches field', async () => {
|
|
1454
|
+
kernelCallWithSessionMock
|
|
1455
|
+
.mockImplementation((fn) => {
|
|
1456
|
+
if (fn === 'chain.capture')
|
|
1457
|
+
return Promise.resolve(emptyVerdict);
|
|
1458
|
+
if (fn === 'chain.createEntry')
|
|
1459
|
+
return Promise.resolve({ docId: 'doc-7', entryId: 'TEN-726' });
|
|
1460
|
+
return Promise.resolve({});
|
|
1461
|
+
});
|
|
1462
|
+
let stdoutOutput = '';
|
|
1463
|
+
const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation((chunk) => { stdoutOutput += String(chunk); return true; });
|
|
1464
|
+
const stderrSpy = vi.spyOn(process.stderr, 'write').mockImplementation(() => true);
|
|
1465
|
+
await runCapture({ text: 'TEN: json create shape', json: true });
|
|
1466
|
+
const parsed = JSON.parse(stdoutOutput.split('\n').filter((l) => l.trim())[0]);
|
|
1467
|
+
expect(parsed).not.toHaveProperty('possibleMatches');
|
|
373
1468
|
writeSpy.mockRestore();
|
|
374
1469
|
stderrSpy.mockRestore();
|
|
375
1470
|
});
|
|
1471
|
+
const originalStdinIsTTY = process.stdin.isTTY;
|
|
1472
|
+
function mockInteractiveStdin(answer) {
|
|
1473
|
+
Object.defineProperty(process.stdin, 'isTTY', { value: true, configurable: true });
|
|
1474
|
+
vi.spyOn(process.stdin, 'once').mockImplementation((_event, cb) => {
|
|
1475
|
+
cb(Buffer.from(answer));
|
|
1476
|
+
return process.stdin;
|
|
1477
|
+
});
|
|
1478
|
+
}
|
|
1479
|
+
afterEach(() => {
|
|
1480
|
+
// vitest's own hook, not a manual end-of-test call — runs even when an assertion above threw,
|
|
1481
|
+
// so one failing case in this block can never leak its stdin mock into the next test.
|
|
1482
|
+
Object.defineProperty(process.stdin, 'isTTY', { value: originalStdinIsTTY, configurable: true });
|
|
1483
|
+
vi.restoreAllMocks();
|
|
1484
|
+
});
|
|
1485
|
+
it('--strict prompts on an "ask" verdict too (unchanged from before this fix round)', async () => {
|
|
1486
|
+
kernelCallWithSessionMock
|
|
1487
|
+
.mockImplementation((fn) => {
|
|
1488
|
+
if (fn === 'chain.capture')
|
|
1489
|
+
return Promise.resolve(askVerdict);
|
|
1490
|
+
if (fn === 'chain.createEntry')
|
|
1491
|
+
return Promise.resolve({ docId: 'doc-12', entryId: 'TEN-728' });
|
|
1492
|
+
return Promise.resolve({});
|
|
1493
|
+
});
|
|
1494
|
+
mockInteractiveStdin('y');
|
|
1495
|
+
vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
1496
|
+
const stderrLines = [];
|
|
1497
|
+
vi.spyOn(process.stderr, 'write').mockImplementation((chunk) => {
|
|
1498
|
+
stderrLines.push(String(chunk));
|
|
1499
|
+
return true;
|
|
1500
|
+
});
|
|
1501
|
+
await runCapture({ text: 'TEN: ask strict prompt', strict: true });
|
|
1502
|
+
expect(stderrLines.some((l) => l.includes('Proceed with capture?'))).toBe(true);
|
|
1503
|
+
expect(kernelCallWithSessionMock).toHaveBeenCalledWith('chain.createEntry', expect.anything());
|
|
1504
|
+
});
|
|
1505
|
+
// TASK-619 (TEN-4420): a close match never overwrites the matched entry. The CLI names the
|
|
1506
|
+
// match and writes only its own new draft; chain.updateEntry is never called from capture.
|
|
1507
|
+
it('a close same-collection match names the match and never updates it', async () => {
|
|
1508
|
+
const closeMatch = {
|
|
1509
|
+
kind: 'ask',
|
|
1510
|
+
candidates: [{ entryId: 'TEN-9', name: 'Existing near-duplicate tension', collectionSlug: 'tensions', score: 0.95 }],
|
|
1511
|
+
scanTruncated: false,
|
|
1512
|
+
};
|
|
1513
|
+
kernelCallWithSessionMock
|
|
1514
|
+
.mockImplementation((fn) => {
|
|
1515
|
+
if (fn === 'chain.capture')
|
|
1516
|
+
return Promise.resolve(closeMatch);
|
|
1517
|
+
if (fn === 'chain.createEntry')
|
|
1518
|
+
return Promise.resolve({ docId: 'doc-13', entryId: 'TEN-729' });
|
|
1519
|
+
return Promise.resolve({});
|
|
1520
|
+
});
|
|
1521
|
+
vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
1522
|
+
const stderrLines = [];
|
|
1523
|
+
vi.spyOn(process.stderr, 'write').mockImplementation((chunk) => {
|
|
1524
|
+
stderrLines.push(String(chunk));
|
|
1525
|
+
return true;
|
|
1526
|
+
});
|
|
1527
|
+
await runCapture({ text: 'TEN: existing near-duplicate tension' });
|
|
1528
|
+
expect(stderrLines.some((l) => l.includes('Possible match') && l.includes('TEN-9'))).toBe(true);
|
|
1529
|
+
expect(kernelCallWithSessionMock).not.toHaveBeenCalledWith('chain.updateEntry', expect.anything());
|
|
1530
|
+
expect(kernelCallWithSessionMock).toHaveBeenCalledWith('chain.createEntry', expect.anything());
|
|
1531
|
+
});
|
|
376
1532
|
});
|
|
377
1533
|
//# sourceMappingURL=capture.test.js.map
|