create-principles-disciple 1.94.0 → 1.95.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/console/dist/server/config/WorkspaceConfigStore.js +2 -1
- package/console/dist/server/config/pd-config-store.d.ts +33 -0
- package/console/dist/server/config/pd-config-store.js +159 -0
- package/console/dist/server/index.js +18 -4
- package/console/dist/server/models/EvidenceChainConsoleModel.d.ts +0 -2
- package/console/dist/server/models/EvidenceChainConsoleModel.js +36 -2
- package/console/dist/server/models/HealthCheckModel.js +5 -3
- package/console/dist/server/models/IntentDecisionModel.d.ts +66 -0
- package/console/dist/server/models/IntentDecisionModel.js +207 -0
- package/console/dist/server/models/IntentPageModel.d.ts +18 -0
- package/console/dist/server/models/IntentPageModel.js +90 -0
- package/console/dist/server/models/PrinciplesConsoleModel.d.ts +2 -0
- package/console/dist/server/models/PrinciplesConsoleModel.js +37 -1
- package/console/dist/server/models/WorkspaceService.d.ts +0 -28
- package/console/dist/server/models/WorkspaceService.js +0 -115
- package/console/dist/server/routes/config.js +55 -1
- package/console/dist/server/routes/intent-decisions.d.ts +33 -0
- package/console/dist/server/routes/intent-decisions.js +499 -0
- package/console/dist/server/routes/intent.d.ts +3 -0
- package/console/dist/server/routes/intent.js +35 -0
- package/console/dist/server/routes/principles.js +67 -1
- package/console/dist/server/routes/update.d.ts +0 -1
- package/console/dist/server/routes/update.js +14 -11
- package/console/dist/ui/App.js +2 -7
- package/console/dist/ui/api.d.ts +44 -18
- package/console/dist/ui/api.js +44 -5
- package/console/dist/ui/components/layout/app-sidebar.js +2 -1
- package/console/dist/ui/components/ui/badge.d.ts +1 -1
- package/console/dist/ui/components/ui/button.d.ts +1 -1
- package/console/dist/ui/components/ui/shiny-text.d.ts +28 -0
- package/console/dist/ui/components/ui/shiny-text.js +46 -0
- package/console/dist/ui/i18n/en.json +167 -3
- package/console/dist/ui/i18n/zh-CN.json +167 -3
- package/console/dist/ui/pages/activation/ActivationPage.js +2 -1
- package/console/dist/ui/pages/control-center/ControlCenterPage.js +28 -2
- package/console/dist/ui/pages/control-center/EmpathyObserverCostHint.d.ts +28 -0
- package/console/dist/ui/pages/control-center/EmpathyObserverCostHint.js +38 -0
- package/console/dist/ui/pages/debt/DebtPage.js +219 -2
- package/console/dist/ui/pages/focus/FocusPage.js +2 -1
- package/console/dist/ui/pages/intent/IntentPage.d.ts +1 -0
- package/console/dist/ui/pages/intent/IntentPage.js +147 -0
- package/console/dist/ui/pages/pain/PainPage.js +234 -4
- package/console/dist/ui/pages/pain/pain-card-helpers.d.ts +75 -0
- package/console/dist/ui/pages/pain/pain-card-helpers.js +78 -0
- package/console/dist/ui/pages/principles/PrinciplesPage.js +2 -1
- package/console/dist/ui/utils/validators.d.ts +163 -0
- package/console/dist/ui/utils/validators.js +433 -0
- package/console/dist/web/assets/app.css +138 -0
- package/console/dist/web/assets/app.js +3124 -1288
- package/console/package.json +3 -0
- package/core/dist/principle-tree-ledger.d.ts +55 -4
- package/core/dist/principle-tree-ledger.d.ts.map +1 -1
- package/core/dist/principle-tree-ledger.js +472 -13
- package/core/dist/principle-tree-ledger.js.map +1 -1
- package/core/dist/prompt-builder/__tests__/prompt-builder-core.test.js +58 -0
- package/core/dist/prompt-builder/__tests__/prompt-builder-core.test.js.map +1 -1
- package/core/dist/prompt-builder/empathy-keyword-matching.d.ts.map +1 -1
- package/core/dist/prompt-builder/empathy-keyword-matching.js +9 -6
- package/core/dist/prompt-builder/empathy-keyword-matching.js.map +1 -1
- package/core/dist/prompt-builder/size-guard.d.ts +1 -0
- package/core/dist/prompt-builder/size-guard.d.ts.map +1 -1
- package/core/dist/prompt-builder/size-guard.js +21 -0
- package/core/dist/prompt-builder/size-guard.js.map +1 -1
- package/core/dist/prompt-builder/types.d.ts +2 -0
- package/core/dist/prompt-builder/types.d.ts.map +1 -1
- package/core/dist/runtime-v2/__tests__/architecture-regression.test.js +118 -32
- package/core/dist/runtime-v2/__tests__/architecture-regression.test.js.map +1 -1
- package/core/dist/runtime-v2/__tests__/evidence-chain-intent-tension.test.d.ts +2 -0
- package/core/dist/runtime-v2/__tests__/evidence-chain-intent-tension.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/__tests__/evidence-chain-intent-tension.test.js +284 -0
- package/core/dist/runtime-v2/__tests__/evidence-chain-intent-tension.test.js.map +1 -0
- package/core/dist/runtime-v2/__tests__/pain-signal-bridge-result-shaping.test.js +105 -0
- package/core/dist/runtime-v2/__tests__/pain-signal-bridge-result-shaping.test.js.map +1 -1
- package/core/dist/runtime-v2/__tests__/pain-signal-observability.test.js +7 -5
- package/core/dist/runtime-v2/__tests__/pain-signal-observability.test.js.map +1 -1
- package/core/dist/runtime-v2/__tests__/pi-artifact-store.test.js +11 -0
- package/core/dist/runtime-v2/__tests__/pi-artifact-store.test.js.map +1 -1
- package/core/dist/runtime-v2/__tests__/proven-channel-baseline.test.js +15 -2
- package/core/dist/runtime-v2/__tests__/proven-channel-baseline.test.js.map +1 -1
- package/core/dist/runtime-v2/__tests__/schema-float-precision.test.d.ts +2 -0
- package/core/dist/runtime-v2/__tests__/schema-float-precision.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/__tests__/schema-float-precision.test.js +290 -0
- package/core/dist/runtime-v2/__tests__/schema-float-precision.test.js.map +1 -0
- package/core/dist/runtime-v2/__tests__/schema-orphan-detection.test.d.ts +2 -0
- package/core/dist/runtime-v2/__tests__/schema-orphan-detection.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/__tests__/schema-orphan-detection.test.js +158 -0
- package/core/dist/runtime-v2/__tests__/schema-orphan-detection.test.js.map +1 -0
- package/core/dist/runtime-v2/activation/__tests__/approval-store-extended.test.js +15 -1
- package/core/dist/runtime-v2/activation/__tests__/approval-store-extended.test.js.map +1 -1
- package/core/dist/runtime-v2/activation/__tests__/sqlite-activation-state-store-fk.test.d.ts +2 -0
- package/core/dist/runtime-v2/activation/__tests__/sqlite-activation-state-store-fk.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/activation/__tests__/sqlite-activation-state-store-fk.test.js +62 -0
- package/core/dist/runtime-v2/activation/__tests__/sqlite-activation-state-store-fk.test.js.map +1 -0
- package/core/dist/runtime-v2/activation/__tests__/sqlite-activation-state-store.test.js +12 -2
- package/core/dist/runtime-v2/activation/__tests__/sqlite-activation-state-store.test.js.map +1 -1
- package/core/dist/runtime-v2/activation/__tests__/sqlite-approval-store-fk.test.d.ts +2 -0
- package/core/dist/runtime-v2/activation/__tests__/sqlite-approval-store-fk.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/activation/__tests__/sqlite-approval-store-fk.test.js +56 -0
- package/core/dist/runtime-v2/activation/__tests__/sqlite-approval-store-fk.test.js.map +1 -0
- package/core/dist/runtime-v2/activation/__tests__/sqlite-approval-store.test.js +8 -0
- package/core/dist/runtime-v2/activation/__tests__/sqlite-approval-store.test.js.map +1 -1
- package/core/dist/runtime-v2/activation/__tests__/story-a-acceptance.test.js +20 -0
- package/core/dist/runtime-v2/activation/__tests__/story-a-acceptance.test.js.map +1 -1
- package/core/dist/runtime-v2/activation/sqlite-activation-state-store.d.ts.map +1 -1
- package/core/dist/runtime-v2/activation/sqlite-activation-state-store.js +6 -0
- package/core/dist/runtime-v2/activation/sqlite-activation-state-store.js.map +1 -1
- package/core/dist/runtime-v2/activation/sqlite-approval-store.d.ts.map +1 -1
- package/core/dist/runtime-v2/activation/sqlite-approval-store.js +86 -32
- package/core/dist/runtime-v2/activation/sqlite-approval-store.js.map +1 -1
- package/core/dist/runtime-v2/activation/writers/__tests__/rule-host-writer.test.js +65 -1
- package/core/dist/runtime-v2/activation/writers/__tests__/rule-host-writer.test.js.map +1 -1
- package/core/dist/runtime-v2/activation/writers/rule-host-writer.d.ts.map +1 -1
- package/core/dist/runtime-v2/activation/writers/rule-host-writer.js +33 -11
- package/core/dist/runtime-v2/activation/writers/rule-host-writer.js.map +1 -1
- package/core/dist/runtime-v2/diagnostician/__tests__/diag-rootcause-output.test.js +134 -15
- package/core/dist/runtime-v2/diagnostician/__tests__/diag-rootcause-output.test.js.map +1 -1
- package/core/dist/runtime-v2/diagnostician/__tests__/intent-tension-schema.test.d.ts +18 -0
- package/core/dist/runtime-v2/diagnostician/__tests__/intent-tension-schema.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/diagnostician/__tests__/intent-tension-schema.test.js +251 -0
- package/core/dist/runtime-v2/diagnostician/__tests__/intent-tension-schema.test.js.map +1 -0
- package/core/dist/runtime-v2/diagnostician/__tests__/rootcause-prompt-builder.test.js +73 -0
- package/core/dist/runtime-v2/diagnostician/__tests__/rootcause-prompt-builder.test.js.map +1 -1
- package/core/dist/runtime-v2/diagnostician/diag-rootcause-output.d.ts +98 -0
- package/core/dist/runtime-v2/diagnostician/diag-rootcause-output.d.ts.map +1 -1
- package/core/dist/runtime-v2/diagnostician/diag-rootcause-output.js +131 -0
- package/core/dist/runtime-v2/diagnostician/diag-rootcause-output.js.map +1 -1
- package/core/dist/runtime-v2/diagnostician/rootcause-prompt-builder.d.ts +8 -0
- package/core/dist/runtime-v2/diagnostician/rootcause-prompt-builder.d.ts.map +1 -1
- package/core/dist/runtime-v2/diagnostician/rootcause-prompt-builder.js +66 -3
- package/core/dist/runtime-v2/diagnostician/rootcause-prompt-builder.js.map +1 -1
- package/core/dist/runtime-v2/diagnostician-output.d.ts +23 -0
- package/core/dist/runtime-v2/diagnostician-output.d.ts.map +1 -1
- package/core/dist/runtime-v2/diagnostician-output.js +16 -0
- package/core/dist/runtime-v2/diagnostician-output.js.map +1 -1
- package/core/dist/runtime-v2/diagnostician-prompt-builder.d.ts +32 -0
- package/core/dist/runtime-v2/diagnostician-prompt-builder.d.ts.map +1 -1
- package/core/dist/runtime-v2/diagnostician-prompt-builder.js.map +1 -1
- package/core/dist/runtime-v2/evidence-triage/source-descriptors.d.ts +1 -1
- package/core/dist/runtime-v2/evidence-triage/source-descriptors.js +1 -1
- package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js +23 -0
- package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js.map +1 -1
- package/core/dist/runtime-v2/feature-flags/__tests__/intent-engineering-flag.test.d.ts +2 -0
- package/core/dist/runtime-v2/feature-flags/__tests__/intent-engineering-flag.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/feature-flags/__tests__/intent-engineering-flag.test.js +30 -0
- package/core/dist/runtime-v2/feature-flags/__tests__/intent-engineering-flag.test.js.map +1 -0
- package/core/dist/runtime-v2/feature-flags/feature-flag-contract.d.ts.map +1 -1
- package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js +2 -0
- package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js.map +1 -1
- package/core/dist/runtime-v2/feature-flags/plugin-surface-registry.d.ts.map +1 -1
- package/core/dist/runtime-v2/feature-flags/plugin-surface-registry.js +0 -9
- package/core/dist/runtime-v2/feature-flags/plugin-surface-registry.js.map +1 -1
- package/core/dist/runtime-v2/index.d.ts +9 -4
- package/core/dist/runtime-v2/index.d.ts.map +1 -1
- package/core/dist/runtime-v2/index.js +12 -3
- package/core/dist/runtime-v2/index.js.map +1 -1
- package/core/dist/runtime-v2/intent/__tests__/intent-decision-record.test.d.ts +2 -0
- package/core/dist/runtime-v2/intent/__tests__/intent-decision-record.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/intent/__tests__/intent-decision-record.test.js +185 -0
- package/core/dist/runtime-v2/intent/__tests__/intent-decision-record.test.js.map +1 -0
- package/core/dist/runtime-v2/intent/__tests__/intent-doc.test.d.ts +2 -0
- package/core/dist/runtime-v2/intent/__tests__/intent-doc.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/intent/__tests__/intent-doc.test.js +91 -0
- package/core/dist/runtime-v2/intent/__tests__/intent-doc.test.js.map +1 -0
- package/core/dist/runtime-v2/intent/__tests__/intent-friction-block.test.d.ts +2 -0
- package/core/dist/runtime-v2/intent/__tests__/intent-friction-block.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/intent/__tests__/intent-friction-block.test.js +168 -0
- package/core/dist/runtime-v2/intent/__tests__/intent-friction-block.test.js.map +1 -0
- package/core/dist/runtime-v2/intent/__tests__/intent-patch-proposal.test.d.ts +2 -0
- package/core/dist/runtime-v2/intent/__tests__/intent-patch-proposal.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/intent/__tests__/intent-patch-proposal.test.js +121 -0
- package/core/dist/runtime-v2/intent/__tests__/intent-patch-proposal.test.js.map +1 -0
- package/core/dist/runtime-v2/intent/index.d.ts +6 -0
- package/core/dist/runtime-v2/intent/index.d.ts.map +1 -0
- package/core/dist/runtime-v2/intent/index.js +6 -0
- package/core/dist/runtime-v2/intent/index.js.map +1 -0
- package/core/dist/runtime-v2/intent/intent-decision-record.d.ts +125 -0
- package/core/dist/runtime-v2/intent/intent-decision-record.d.ts.map +1 -0
- package/core/dist/runtime-v2/intent/intent-decision-record.js +21 -0
- package/core/dist/runtime-v2/intent/intent-decision-record.js.map +1 -0
- package/core/dist/runtime-v2/intent/intent-doc-reader-port.d.ts +95 -0
- package/core/dist/runtime-v2/intent/intent-doc-reader-port.d.ts.map +1 -0
- package/core/dist/runtime-v2/intent/intent-doc-reader-port.js +43 -0
- package/core/dist/runtime-v2/intent/intent-doc-reader-port.js.map +1 -0
- package/core/dist/runtime-v2/intent/intent-doc.d.ts +19 -0
- package/core/dist/runtime-v2/intent/intent-doc.d.ts.map +1 -0
- package/core/dist/runtime-v2/intent/intent-doc.js +70 -0
- package/core/dist/runtime-v2/intent/intent-doc.js.map +1 -0
- package/core/dist/runtime-v2/intent/intent-friction-block.d.ts +63 -0
- package/core/dist/runtime-v2/intent/intent-friction-block.d.ts.map +1 -0
- package/core/dist/runtime-v2/intent/intent-friction-block.js +129 -0
- package/core/dist/runtime-v2/intent/intent-friction-block.js.map +1 -0
- package/core/dist/runtime-v2/intent/intent-patch-proposal.d.ts +42 -0
- package/core/dist/runtime-v2/intent/intent-patch-proposal.d.ts.map +1 -0
- package/core/dist/runtime-v2/intent/intent-patch-proposal.js +81 -0
- package/core/dist/runtime-v2/intent/intent-patch-proposal.js.map +1 -0
- package/core/dist/runtime-v2/internalization/__tests__/__fixtures__/intent-tension-cases.d.ts +54 -0
- package/core/dist/runtime-v2/internalization/__tests__/__fixtures__/intent-tension-cases.d.ts.map +1 -0
- package/core/dist/runtime-v2/internalization/__tests__/__fixtures__/intent-tension-cases.js +219 -0
- package/core/dist/runtime-v2/internalization/__tests__/__fixtures__/intent-tension-cases.js.map +1 -0
- package/core/dist/runtime-v2/internalization/__tests__/diag-rootcause-intent-tension.test.d.ts +2 -0
- package/core/dist/runtime-v2/internalization/__tests__/diag-rootcause-intent-tension.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/internalization/__tests__/diag-rootcause-intent-tension.test.js +360 -0
- package/core/dist/runtime-v2/internalization/__tests__/diag-rootcause-intent-tension.test.js.map +1 -0
- package/core/dist/runtime-v2/internalization/__tests__/diag-router-intent-tension.test.d.ts +2 -0
- package/core/dist/runtime-v2/internalization/__tests__/diag-router-intent-tension.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/internalization/__tests__/diag-router-intent-tension.test.js +333 -0
- package/core/dist/runtime-v2/internalization/__tests__/diag-router-intent-tension.test.js.map +1 -0
- package/core/dist/runtime-v2/internalization/__tests__/intent-tension-cases.test.d.ts +2 -0
- package/core/dist/runtime-v2/internalization/__tests__/intent-tension-cases.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/internalization/__tests__/intent-tension-cases.test.js +113 -0
- package/core/dist/runtime-v2/internalization/__tests__/intent-tension-cases.test.js.map +1 -0
- package/core/dist/runtime-v2/internalization/diag-rootcause-runner.d.ts +13 -0
- package/core/dist/runtime-v2/internalization/diag-rootcause-runner.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/diag-rootcause-runner.js +42 -0
- package/core/dist/runtime-v2/internalization/diag-rootcause-runner.js.map +1 -1
- package/core/dist/runtime-v2/internalization/diag-router-runner.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/diag-router-runner.js +27 -0
- package/core/dist/runtime-v2/internalization/diag-router-runner.js.map +1 -1
- package/core/dist/runtime-v2/pain-signal-observability.d.ts.map +1 -1
- package/core/dist/runtime-v2/pain-signal-observability.js +257 -56
- package/core/dist/runtime-v2/pain-signal-observability.js.map +1 -1
- package/core/dist/runtime-v2/pain-signal-runtime-factory.d.ts +12 -0
- package/core/dist/runtime-v2/pain-signal-runtime-factory.d.ts.map +1 -1
- package/core/dist/runtime-v2/pain-signal-runtime-factory.js +1 -1
- package/core/dist/runtime-v2/pain-signal-runtime-factory.js.map +1 -1
- package/core/dist/runtime-v2/pain-to-principle-service.d.ts +6 -0
- package/core/dist/runtime-v2/pain-to-principle-service.d.ts.map +1 -1
- package/core/dist/runtime-v2/pain-to-principle-service.js +2 -0
- package/core/dist/runtime-v2/pain-to-principle-service.js.map +1 -1
- package/core/dist/runtime-v2/principle-tree/ledger-codec.js.map +1 -1
- package/core/dist/runtime-v2/proven-channel-baseline.js +1 -1
- package/core/dist/runtime-v2/proven-channel-baseline.js.map +1 -1
- package/core/dist/runtime-v2/store/artifact/__tests__/sqlite-pi-artifact-store-fk.test.d.ts +2 -0
- package/core/dist/runtime-v2/store/artifact/__tests__/sqlite-pi-artifact-store-fk.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/store/artifact/__tests__/sqlite-pi-artifact-store-fk.test.js +55 -0
- package/core/dist/runtime-v2/store/artifact/__tests__/sqlite-pi-artifact-store-fk.test.js.map +1 -0
- package/core/dist/runtime-v2/store/artifact/sqlite-pi-artifact-store.d.ts.map +1 -1
- package/core/dist/runtime-v2/store/artifact/sqlite-pi-artifact-store.js +6 -0
- package/core/dist/runtime-v2/store/artifact/sqlite-pi-artifact-store.js.map +1 -1
- package/core/dist/runtime-v2/store/intent/__tests__/sqlite-intent-decision-store.test.d.ts +2 -0
- package/core/dist/runtime-v2/store/intent/__tests__/sqlite-intent-decision-store.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/store/intent/__tests__/sqlite-intent-decision-store.test.js +272 -0
- package/core/dist/runtime-v2/store/intent/__tests__/sqlite-intent-decision-store.test.js.map +1 -0
- package/core/dist/runtime-v2/store/intent/index.d.ts +6 -0
- package/core/dist/runtime-v2/store/intent/index.d.ts.map +1 -0
- package/core/dist/runtime-v2/store/intent/index.js +5 -0
- package/core/dist/runtime-v2/store/intent/index.js.map +1 -0
- package/core/dist/runtime-v2/store/intent/sqlite-intent-decision-store.d.ts +51 -0
- package/core/dist/runtime-v2/store/intent/sqlite-intent-decision-store.d.ts.map +1 -0
- package/core/dist/runtime-v2/store/intent/sqlite-intent-decision-store.js +306 -0
- package/core/dist/runtime-v2/store/intent/sqlite-intent-decision-store.js.map +1 -0
- package/core/dist/runtime-v2/store/sqlite-connection-pragma.test.js +14 -3
- package/core/dist/runtime-v2/store/sqlite-connection-pragma.test.js.map +1 -1
- package/core/dist/runtime-v2/store/sqlite-connection-schema-version.test.d.ts +2 -0
- package/core/dist/runtime-v2/store/sqlite-connection-schema-version.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/store/sqlite-connection-schema-version.test.js +72 -0
- package/core/dist/runtime-v2/store/sqlite-connection-schema-version.test.js.map +1 -0
- package/core/dist/runtime-v2/store/sqlite-connection.d.ts +27 -0
- package/core/dist/runtime-v2/store/sqlite-connection.d.ts.map +1 -1
- package/core/dist/runtime-v2/store/sqlite-connection.js +124 -12
- package/core/dist/runtime-v2/store/sqlite-connection.js.map +1 -1
- package/core/dist/runtime-v2/types/event-payload.d.ts +1 -20
- package/core/dist/runtime-v2/types/event-payload.d.ts.map +1 -1
- package/core/dist/runtime-v2/types/event-payload.js +0 -12
- package/core/dist/runtime-v2/types/event-payload.js.map +1 -1
- package/core/dist/runtime-v2/types/event-types.d.ts +5 -34
- package/core/dist/runtime-v2/types/event-types.d.ts.map +1 -1
- package/core/dist/runtime-v2/types/event-types.js +0 -19
- package/core/dist/runtime-v2/types/event-types.js.map +1 -1
- package/core/dist/runtime-v2/types/evidence-chain-contract.d.ts +63 -0
- package/core/dist/runtime-v2/types/evidence-chain-contract.d.ts.map +1 -1
- package/core/dist/runtime-v2/types/evidence-chain-contract.js +234 -9
- package/core/dist/runtime-v2/types/evidence-chain-contract.js.map +1 -1
- package/core/dist/runtime-v2/types/index.d.ts +5 -5
- package/core/dist/runtime-v2/types/index.d.ts.map +1 -1
- package/core/dist/runtime-v2/types/index.js +5 -3
- package/core/dist/runtime-v2/types/index.js.map +1 -1
- package/core/dist/runtime-v2/types/ledger-store.d.ts +30 -30
- package/core/dist/runtime-v2/types/ledger-store.d.ts.map +1 -1
- package/core/dist/runtime-v2/types/ledger-store.js +10 -5
- package/core/dist/runtime-v2/types/ledger-store.js.map +1 -1
- package/core/dist/workflow-funnel-loader.d.ts +2 -2
- package/core/dist/workflow-funnel-loader.d.ts.map +1 -1
- package/dist/installer.d.ts.map +1 -1
- package/dist/installer.js +16 -0
- package/dist/installer.js.map +1 -1
- package/package.json +1 -1
- package/pd-cli/dist/commands/__tests__/intent-flag-wiring.test.d.ts +9 -0
- package/pd-cli/dist/commands/__tests__/intent-flag-wiring.test.d.ts.map +1 -0
- package/pd-cli/dist/commands/__tests__/intent-flag-wiring.test.js +166 -0
- package/pd-cli/dist/commands/__tests__/intent-flag-wiring.test.js.map +1 -0
- package/pd-cli/dist/commands/intent.d.ts +59 -0
- package/pd-cli/dist/commands/intent.d.ts.map +1 -0
- package/pd-cli/dist/commands/intent.js +350 -0
- package/pd-cli/dist/commands/intent.js.map +1 -0
- package/pd-cli/dist/commands/runtime-init.d.ts +43 -0
- package/pd-cli/dist/commands/runtime-init.d.ts.map +1 -0
- package/pd-cli/dist/commands/runtime-init.js +264 -0
- package/pd-cli/dist/commands/runtime-init.js.map +1 -0
- package/pd-cli/dist/index.js +25 -0
- package/pd-cli/dist/index.js.map +1 -1
- package/pd-cli/dist/services/demo-story-a-runner.d.ts.map +1 -1
- package/pd-cli/dist/services/demo-story-a-runner.js +6 -0
- package/pd-cli/dist/services/demo-story-a-runner.js.map +1 -1
- package/pd-cli/package.json +1 -0
- package/plugin/dist/commands/pain.js +2 -0
- package/plugin/dist/core/control-ui-db.d.ts +11 -0
- package/plugin/dist/core/control-ui-db.js +40 -16
- package/plugin/dist/core/event-log.js +0 -5
- package/plugin/dist/core/intent-doc-reader-adapter.d.ts +28 -0
- package/plugin/dist/core/intent-doc-reader-adapter.js +56 -0
- package/plugin/dist/core/intent-doc-reader.d.ts +80 -0
- package/plugin/dist/core/intent-doc-reader.js +189 -0
- package/plugin/dist/core/principle-tree-ledger.d.ts +27 -79
- package/plugin/dist/core/principle-tree-ledger.js +39 -524
- package/plugin/dist/core/reflection/reflection-context.d.ts +2 -2
- package/plugin/dist/core/trajectory.d.ts +16 -0
- package/plugin/dist/core/trajectory.js +332 -254
- package/plugin/dist/core/workspace-context.d.ts +2 -3
- package/plugin/dist/hooks/pain.js +5 -0
- package/plugin/dist/hooks/prompt-helpers.d.ts +19 -1
- package/plugin/dist/hooks/prompt-helpers.js +39 -2
- package/plugin/dist/hooks/prompt-types.d.ts +8 -0
- package/plugin/dist/hooks/prompt.js +80 -21
- package/plugin/dist/index.d.ts +3 -1
- package/plugin/dist/index.js +9 -5
- package/plugin/dist/service/runtime-summary-service.js +1 -1
- package/plugin/dist/service/subagent-workflow/workflow-store.d.ts +14 -0
- package/plugin/dist/service/subagent-workflow/workflow-store.js +91 -2
- package/plugin/dist/types/event-types.d.ts +1 -1
- package/plugin/package.json +6 -3
- package/plugin/scripts/acceptance-test.mjs +3 -3
- package/plugin/dist/core/principle-tree-ledger-adapter.d.ts +0 -32
- package/plugin/dist/core/principle-tree-ledger-adapter.js +0 -125
- package/plugin/dist/service/central-database.d.ts +0 -138
- package/plugin/dist/service/central-database.js +0 -731
- package/plugin/dist/service/central-sync-service.d.ts +0 -8
- package/plugin/dist/service/central-sync-service.js +0 -71
- package/plugin/scripts/validate-live-path.ts +0 -462
|
@@ -138,4 +138,37 @@ export declare function getPrinciplesOutputLanguage(workspaceDir: string): Outpu
|
|
|
138
138
|
* Safe partial write: preserves unknown sections, validates before write.
|
|
139
139
|
*/
|
|
140
140
|
export declare function updatePrinciplesOutputLanguage(workspaceDir: string, payload: unknown): OutputLanguageResult;
|
|
141
|
+
export interface FeatureFlagUpdateResultOk {
|
|
142
|
+
ok: true;
|
|
143
|
+
feature: string;
|
|
144
|
+
enabled: boolean;
|
|
145
|
+
}
|
|
146
|
+
export interface FeatureFlagUpdateResultErr {
|
|
147
|
+
ok: false;
|
|
148
|
+
statusCode: number;
|
|
149
|
+
error: string;
|
|
150
|
+
message: string;
|
|
151
|
+
nextAction?: string;
|
|
152
|
+
}
|
|
153
|
+
export type FeatureFlagUpdateResult = FeatureFlagUpdateResultOk | FeatureFlagUpdateResultErr;
|
|
154
|
+
/**
|
|
155
|
+
* Update a feature flag's `enabled` field in .pd/config.yaml.
|
|
156
|
+
*
|
|
157
|
+
* Safe partial write: preserves unknown sections, validates before write.
|
|
158
|
+
* Follows the load → validate → merge → atomic write pattern of
|
|
159
|
+
* updateAgentBinding / updatePrinciplesOutputLanguage.
|
|
160
|
+
*
|
|
161
|
+
* Constraints (spec §13.4):
|
|
162
|
+
* - featureName must be in the registered flag set (DEFAULT_FEATURE_FLAGS)
|
|
163
|
+
* - Does NOT create a new `features:` section if absent (rejects)
|
|
164
|
+
* - Atomic write + validates merged yaml can be re-parsed by loadPdConfig
|
|
165
|
+
*
|
|
166
|
+
* ERR entries (spec §13.9):
|
|
167
|
+
* - ERR-001/ERR-005: enabled strictly typeof === 'boolean'; featureName
|
|
168
|
+
* strictly checked against whitelist
|
|
169
|
+
* - ERR-009: unknown featureName → ok:false with reason
|
|
170
|
+
* - ERR-013: Object.hasOwn for features section existence check
|
|
171
|
+
* - ERR-015/018/019: load-validate-merge-write-reload, no stale cache
|
|
172
|
+
*/
|
|
173
|
+
export declare function updateFeatureFlag(workspaceDir: string, featureName: string, enabled: boolean): FeatureFlagUpdateResult;
|
|
141
174
|
export declare function checkReadiness(workspaceDir: string, agentName: string, getEnvVar?: (name: string) => string | undefined): ReadinessResult | ReadinessError;
|
|
@@ -606,6 +606,165 @@ export function updatePrinciplesOutputLanguage(workspaceDir, payload) {
|
|
|
606
606
|
}
|
|
607
607
|
return { ok: true, outputLanguage: outputLangRaw, source: 'user_config' };
|
|
608
608
|
}
|
|
609
|
+
// ── Update Feature Flag (spec 2026-06-27 §13.4) ────────────────────────────
|
|
610
|
+
/**
|
|
611
|
+
* Whitelist of registered feature flag names. A PATCH request may only
|
|
612
|
+
* toggle flags that already exist in the registry. Built from the default
|
|
613
|
+
* effective config's computed flags — this is the authoritative source of
|
|
614
|
+
* registered flag IDs (avoids ambiguity between the array and Record
|
|
615
|
+
* forms of DEFAULT_FEATURE_FLAGS in the core barrel).
|
|
616
|
+
*/
|
|
617
|
+
const _DEFAULT_FLAGS_RESULT = computeFeatureFlagsFromConfig(computeEffectivePdConfig(null));
|
|
618
|
+
const REGISTERED_FEATURE_FLAG_NAMES = new Set(Object.keys(_DEFAULT_FLAGS_RESULT.flags));
|
|
619
|
+
/** Map of flag ID → category, for preserving category when writing. */
|
|
620
|
+
const DEFAULT_FLAG_CATEGORY = new Map(Object.entries(_DEFAULT_FLAGS_RESULT.flags).map(([id, flag]) => [id, flag.category]));
|
|
621
|
+
/**
|
|
622
|
+
* Update a feature flag's `enabled` field in .pd/config.yaml.
|
|
623
|
+
*
|
|
624
|
+
* Safe partial write: preserves unknown sections, validates before write.
|
|
625
|
+
* Follows the load → validate → merge → atomic write pattern of
|
|
626
|
+
* updateAgentBinding / updatePrinciplesOutputLanguage.
|
|
627
|
+
*
|
|
628
|
+
* Constraints (spec §13.4):
|
|
629
|
+
* - featureName must be in the registered flag set (DEFAULT_FEATURE_FLAGS)
|
|
630
|
+
* - Does NOT create a new `features:` section if absent (rejects)
|
|
631
|
+
* - Atomic write + validates merged yaml can be re-parsed by loadPdConfig
|
|
632
|
+
*
|
|
633
|
+
* ERR entries (spec §13.9):
|
|
634
|
+
* - ERR-001/ERR-005: enabled strictly typeof === 'boolean'; featureName
|
|
635
|
+
* strictly checked against whitelist
|
|
636
|
+
* - ERR-009: unknown featureName → ok:false with reason
|
|
637
|
+
* - ERR-013: Object.hasOwn for features section existence check
|
|
638
|
+
* - ERR-015/018/019: load-validate-merge-write-reload, no stale cache
|
|
639
|
+
*/
|
|
640
|
+
export function updateFeatureFlag(workspaceDir, featureName, enabled) {
|
|
641
|
+
// 1. Validate featureName against the registered whitelist
|
|
642
|
+
if (!REGISTERED_FEATURE_FLAG_NAMES.has(featureName)) {
|
|
643
|
+
return {
|
|
644
|
+
ok: false,
|
|
645
|
+
statusCode: 400,
|
|
646
|
+
error: 'unknown_feature',
|
|
647
|
+
message: `Unknown feature flag '${featureName}'. Registered flags: ${Array.from(REGISTERED_FEATURE_FLAG_NAMES).join(', ')}`,
|
|
648
|
+
nextAction: `Use one of: ${Array.from(REGISTERED_FEATURE_FLAG_NAMES).join(', ')}`,
|
|
649
|
+
};
|
|
650
|
+
}
|
|
651
|
+
// 2. Validate enabled is boolean (typeof check, no `as` — ERR-001)
|
|
652
|
+
if (typeof enabled !== 'boolean') {
|
|
653
|
+
return {
|
|
654
|
+
ok: false,
|
|
655
|
+
statusCode: 400,
|
|
656
|
+
error: 'bad_request',
|
|
657
|
+
message: `enabled must be a boolean. Got: ${typeof enabled}`,
|
|
658
|
+
nextAction: 'Send { enabled: true } or { enabled: false }',
|
|
659
|
+
};
|
|
660
|
+
}
|
|
661
|
+
// 3. Read raw config to preserve unknown sections + check features section
|
|
662
|
+
// Check features section BEFORE loadPdConfig malformed check: a config
|
|
663
|
+
// without a features section is rejected with 422 regardless of whether
|
|
664
|
+
// the rest is valid or malformed (spec §13.4: 不允许新增).
|
|
665
|
+
const configPath = getPdConfigPath(workspaceDir);
|
|
666
|
+
let rawConfig;
|
|
667
|
+
if (fs.existsSync(configPath)) {
|
|
668
|
+
let rawContent;
|
|
669
|
+
try {
|
|
670
|
+
rawContent = fs.readFileSync(configPath, 'utf8');
|
|
671
|
+
}
|
|
672
|
+
catch (err) {
|
|
673
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
674
|
+
return { ok: false, statusCode: 500, error: 'read_error', message: `Failed to read config for update: ${message}` };
|
|
675
|
+
}
|
|
676
|
+
let rawParsed;
|
|
677
|
+
try {
|
|
678
|
+
rawParsed = yaml.load(rawContent, { schema: yaml.JSON_SCHEMA });
|
|
679
|
+
}
|
|
680
|
+
catch (err) {
|
|
681
|
+
// YAML syntax error = malformed config (409, not 500). Consistent with
|
|
682
|
+
// updateAgentBinding which treats loadPdConfig failures as conflict.
|
|
683
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
684
|
+
return { ok: false, statusCode: 409, error: 'conflict', message: `Cannot update feature flag: existing .pd/config.yaml is malformed. YAML parse error: ${message}` };
|
|
685
|
+
}
|
|
686
|
+
if (isRecord(rawParsed)) {
|
|
687
|
+
rawConfig = { ...rawParsed };
|
|
688
|
+
}
|
|
689
|
+
else {
|
|
690
|
+
rawConfig = {};
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
else {
|
|
694
|
+
rawConfig = {};
|
|
695
|
+
}
|
|
696
|
+
// 4. Refuse to CREATE a features section if absent (spec §13.4: 不允许新增)
|
|
697
|
+
// Use Object.hasOwn for untrusted key check (ERR-013)
|
|
698
|
+
if (!Object.hasOwn(rawConfig, 'features') || !isRecord(rawConfig.features)) {
|
|
699
|
+
return {
|
|
700
|
+
ok: false,
|
|
701
|
+
statusCode: 422,
|
|
702
|
+
error: 'no_features_section',
|
|
703
|
+
message: `Cannot update feature flag: .pd/config.yaml has no 'features:' section. This API does not create new feature sections.`,
|
|
704
|
+
nextAction: 'Manually add a features: section to .pd/config.yaml first, or set the flag via yaml directly.',
|
|
705
|
+
};
|
|
706
|
+
}
|
|
707
|
+
// 5. Load existing config — if malformed, refuse to write
|
|
708
|
+
const loadResult = loadPdConfig(workspaceDir);
|
|
709
|
+
if (!loadResult.ok) {
|
|
710
|
+
return {
|
|
711
|
+
ok: false,
|
|
712
|
+
statusCode: 409,
|
|
713
|
+
error: 'conflict',
|
|
714
|
+
message: `Cannot update feature flag: existing .pd/config.yaml is malformed. Fix config errors first. Errors: ${loadResult.errors.map(e => e.reason).join('; ')}`,
|
|
715
|
+
};
|
|
716
|
+
}
|
|
717
|
+
// 6. Merge: update features[featureName].enabled, preserving other flags
|
|
718
|
+
const existingFeatures = { ...rawConfig.features };
|
|
719
|
+
const existingEntry = Object.hasOwn(existingFeatures, featureName)
|
|
720
|
+
? existingFeatures[featureName]
|
|
721
|
+
: undefined;
|
|
722
|
+
// Preserve existing category if present; otherwise use the registered default
|
|
723
|
+
const category = (isRecord(existingEntry) && Object.hasOwn(existingEntry, 'category') && typeof existingEntry.category === 'string')
|
|
724
|
+
? existingEntry.category
|
|
725
|
+
: (DEFAULT_FLAG_CATEGORY.get(featureName) ?? 'quiet');
|
|
726
|
+
existingFeatures[featureName] = { category, enabled };
|
|
727
|
+
rawConfig.features = existingFeatures;
|
|
728
|
+
// 7. Validate the updated config before writing
|
|
729
|
+
const validation = validatePdConfig(rawConfig);
|
|
730
|
+
if (!validation.ok) {
|
|
731
|
+
return {
|
|
732
|
+
ok: false,
|
|
733
|
+
statusCode: 400,
|
|
734
|
+
error: 'validation_error',
|
|
735
|
+
message: `Updated config would be invalid: ${validation.errors.map(e => e.reason).join('; ')}`,
|
|
736
|
+
nextAction: 'Fix config validation errors before retrying',
|
|
737
|
+
};
|
|
738
|
+
}
|
|
739
|
+
// 8. Atomic write
|
|
740
|
+
try {
|
|
741
|
+
writeConfigAtomic(configPath, rawConfig);
|
|
742
|
+
}
|
|
743
|
+
catch (err) {
|
|
744
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
745
|
+
return { ok: false, statusCode: 500, error: 'write_error', message: `Failed to write config: ${message}`, nextAction: 'Check disk space and file permissions for .pd/config.yaml' };
|
|
746
|
+
}
|
|
747
|
+
// 9. Re-read to confirm actual persisted state (ERR-002: fail loud on re-read failure)
|
|
748
|
+
const confirmResult = loadPdConfig(workspaceDir);
|
|
749
|
+
if (!confirmResult.ok) {
|
|
750
|
+
return {
|
|
751
|
+
ok: false,
|
|
752
|
+
statusCode: 500,
|
|
753
|
+
error: 'confirm_read_failed',
|
|
754
|
+
message: `Write succeeded but re-read failed: config is now malformed`,
|
|
755
|
+
nextAction: 'Inspect .pd/config.yaml manually for corruption',
|
|
756
|
+
};
|
|
757
|
+
}
|
|
758
|
+
// Use computeFlagsFromLoadResult (not computeFeatureFlagsFromConfig) because
|
|
759
|
+
// confirmResult is a ConfigLoadResult, not an EffectivePdConfig.
|
|
760
|
+
const confirmFlags = computeFlagsFromLoadResult(confirmResult);
|
|
761
|
+
const confirmedEnabled = confirmFlags.flags[featureName]?.enabled === true;
|
|
762
|
+
return {
|
|
763
|
+
ok: true,
|
|
764
|
+
feature: featureName,
|
|
765
|
+
enabled: confirmedEnabled,
|
|
766
|
+
};
|
|
767
|
+
}
|
|
609
768
|
// ── Check Readiness ──────────────────────────────────────────────────────────
|
|
610
769
|
export function checkReadiness(workspaceDir, agentName, getEnvVar = (name) => process.env[name]) {
|
|
611
770
|
// 1. Validate agent name
|
|
@@ -15,6 +15,8 @@ import { handleActivationsRoute, disposeActivationsModels } from './routes/activ
|
|
|
15
15
|
import { handleApprovalsGroupedRoute, disposeApprovalsGroupedModels } from './routes/approvals-grouped.js';
|
|
16
16
|
import { handleGovernanceRoute, disposeGovernanceModels } from './routes/governance.js';
|
|
17
17
|
import { handleEvidenceChainRoute, disposeEvidenceChainModels } from './routes/evidence-chain.js';
|
|
18
|
+
import { handleIntentRoute, disposeIntentModels } from './routes/intent.js';
|
|
19
|
+
import { handleIntentDecisionsRoute, disposeIntentDecisionModels } from './routes/intent-decisions.js';
|
|
18
20
|
import { createWorkspacesRoutes } from './routes/workspaces.js';
|
|
19
21
|
import { handleUpdateRoute } from './routes/update.js';
|
|
20
22
|
import { handleUpdateHistoryRoute } from './routes/update-history.js';
|
|
@@ -215,7 +217,7 @@ async function initServices(workspaceDir, authConfig) {
|
|
|
215
217
|
feedbackFlags,
|
|
216
218
|
};
|
|
217
219
|
}
|
|
218
|
-
async function closeServices(
|
|
220
|
+
async function closeServices() {
|
|
219
221
|
disposeFeedbackReportModels();
|
|
220
222
|
disposeApprovalsModels();
|
|
221
223
|
disposeApprovalsGroupedModels();
|
|
@@ -225,7 +227,8 @@ async function closeServices(services) {
|
|
|
225
227
|
disposeActivationsModels();
|
|
226
228
|
disposeGovernanceModels();
|
|
227
229
|
disposeEvidenceChainModels();
|
|
228
|
-
|
|
230
|
+
disposeIntentModels();
|
|
231
|
+
disposeIntentDecisionModels();
|
|
229
232
|
}
|
|
230
233
|
// ── Route handler ───────────────────────────────────────────────────────────
|
|
231
234
|
function handleRequest(services) {
|
|
@@ -294,7 +297,7 @@ function handleRequest(services) {
|
|
|
294
297
|
asyncHandler(() => handleUpdateHistoryRoute(req, res, services.workspaceDir, ''))(req, res);
|
|
295
298
|
return;
|
|
296
299
|
}
|
|
297
|
-
// Update routes: GET /api/update/check, POST /api/update/apply,
|
|
300
|
+
// Update routes: GET /api/update/check, POST /api/update/apply, POST /api/update/rollback
|
|
298
301
|
if (urlPath === '/api/update' || urlPath.startsWith('/api/update/')) {
|
|
299
302
|
const subPath = urlPath.slice('/api/update'.length);
|
|
300
303
|
const isApply = subPath === '/apply';
|
|
@@ -325,6 +328,17 @@ function handleRequest(services) {
|
|
|
325
328
|
asyncHandler(() => handleGovernanceRoute(req, res, services.workspaceDir))(req, res);
|
|
326
329
|
return;
|
|
327
330
|
}
|
|
331
|
+
// PRI-466: GET /api/v1/intent
|
|
332
|
+
if (urlPath === '/api/v1/intent') {
|
|
333
|
+
asyncHandler(() => handleIntentRoute(req, res, services.workspaceDir))(req, res);
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
// PRI-470: IntentDecisionRecord (POST/GET /api/v1/intent-decisions, /:id, /summary)
|
|
337
|
+
if (urlPath === '/api/v1/intent-decisions' || urlPath.startsWith('/api/v1/intent-decisions/')) {
|
|
338
|
+
const subPath = urlPath.slice('/api/v1/intent-decisions'.length);
|
|
339
|
+
asyncHandler(() => handleIntentDecisionsRoute(req, res, services.workspaceDir, subPath))(req, res);
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
328
342
|
// PRI-331: GET /api/v1/evidence-chain
|
|
329
343
|
if (urlPath === '/api/v1/evidence-chain') {
|
|
330
344
|
asyncHandler(() => handleEvidenceChainRoute(req, res, services.workspaceDir))(req, res);
|
|
@@ -359,7 +373,7 @@ export async function main() {
|
|
|
359
373
|
const shutdown = async (signal) => {
|
|
360
374
|
console.log(`[pd-console] Received ${signal}, shutting down...`);
|
|
361
375
|
await new Promise((resolve) => { server.close(() => resolve()); });
|
|
362
|
-
await closeServices(
|
|
376
|
+
await closeServices();
|
|
363
377
|
process.exit(0);
|
|
364
378
|
};
|
|
365
379
|
process.on('SIGTERM', () => { void shutdown('SIGTERM'); });
|
|
@@ -22,10 +22,8 @@
|
|
|
22
22
|
* - ERR-014/016/017: Evidence previews bounded via sanitizeString
|
|
23
23
|
* - ERR-013: Use Object.hasOwn() for untrusted object keys
|
|
24
24
|
*/
|
|
25
|
-
import { crossReferenceByTimestamp, resolveSummary } from '@principles/core/runtime-v2';
|
|
26
25
|
import type { EvidenceChainState, EvidenceChainRecord, EvidenceChainResponse } from '@principles/core/runtime-v2';
|
|
27
26
|
export type { EvidenceChainState, EvidenceChainRecord, EvidenceChainResponse, };
|
|
28
|
-
export { crossReferenceByTimestamp, resolveSummary, };
|
|
29
27
|
export declare class EvidenceChainConsoleModel {
|
|
30
28
|
private readonly workspaceDir;
|
|
31
29
|
constructor(workspaceDir: string);
|
|
@@ -22,11 +22,10 @@
|
|
|
22
22
|
* - ERR-014/016/017: Evidence previews bounded via sanitizeString
|
|
23
23
|
* - ERR-013: Use Object.hasOwn() for untrusted object keys
|
|
24
24
|
*/
|
|
25
|
-
import { SqliteConnection, sanitizeString, assembleEvidenceChain,
|
|
25
|
+
import { SqliteConnection, sanitizeString, assembleEvidenceChain, } from '@principles/core/runtime-v2';
|
|
26
26
|
import * as fs from 'node:fs';
|
|
27
27
|
import * as path from 'node:path';
|
|
28
28
|
import Database from 'better-sqlite3';
|
|
29
|
-
export { crossReferenceByTimestamp, resolveSummary, };
|
|
30
29
|
// ── Helpers ────────────────────────────────────────────────────────────────────
|
|
31
30
|
function isRecord(value) {
|
|
32
31
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
@@ -180,6 +179,7 @@ export class EvidenceChainConsoleModel {
|
|
|
180
179
|
let tasks = [];
|
|
181
180
|
let dreamerTasks = [];
|
|
182
181
|
let candidates = [];
|
|
182
|
+
let diagnosticArtifacts = [];
|
|
183
183
|
let stateDbAvailable = false;
|
|
184
184
|
if (fs.existsSync(stateDbPath)) {
|
|
185
185
|
const conn = new SqliteConnection({ workspaceDir: this.workspaceDir, readonly: true });
|
|
@@ -230,6 +230,27 @@ export class EvidenceChainConsoleModel {
|
|
|
230
230
|
throw colErr;
|
|
231
231
|
}
|
|
232
232
|
}
|
|
233
|
+
// PRI-469: Read diagnostician artifacts from the artifacts table.
|
|
234
|
+
// In production, DiagnosticianCommitter writes Stage C output (rootCause +
|
|
235
|
+
// intentTension) to artifacts.content_json with artifact_kind =
|
|
236
|
+
// 'diagnostician_output'. This is the canonical source for intentTension.
|
|
237
|
+
// The tasks.diagnostic_json column is kept as a fallback for test fixtures.
|
|
238
|
+
// Graceful degradation: if the artifacts table is missing (older workspace),
|
|
239
|
+
// we simply skip it — assembleEvidenceChain falls back to diagnostic_json.
|
|
240
|
+
try {
|
|
241
|
+
diagnosticArtifacts = db.prepare("SELECT task_id, content_json FROM artifacts WHERE artifact_kind = 'diagnostician_output' ORDER BY created_at DESC").all();
|
|
242
|
+
}
|
|
243
|
+
catch (artifactsErr) {
|
|
244
|
+
if (isMissingTableError(artifactsErr)) {
|
|
245
|
+
// Artifacts table not present in older workspaces — not an error,
|
|
246
|
+
// just no intentTension data available from artifacts.
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
// ERR-002: degrade with reason for unexpected errors.
|
|
250
|
+
degradedReasons.push('Failed to read diagnostician artifacts table');
|
|
251
|
+
degradedNextActions.push('Check state database artifacts table integrity.');
|
|
252
|
+
}
|
|
253
|
+
}
|
|
233
254
|
stateDbAvailable = true;
|
|
234
255
|
}
|
|
235
256
|
catch (err) {
|
|
@@ -272,6 +293,7 @@ export class EvidenceChainConsoleModel {
|
|
|
272
293
|
stateDbAvailable,
|
|
273
294
|
degradedReasons,
|
|
274
295
|
degradedNextActions,
|
|
296
|
+
diagnosticArtifacts,
|
|
275
297
|
});
|
|
276
298
|
// ── 5. Sanitize strings in place ─────────────────────────────────
|
|
277
299
|
for (const record of response.records) {
|
|
@@ -288,6 +310,18 @@ export class EvidenceChainConsoleModel {
|
|
|
288
310
|
if (record.candidateSummary) {
|
|
289
311
|
record.candidateSummary = sanitizeString(record.candidateSummary, this.workspaceDir);
|
|
290
312
|
}
|
|
313
|
+
// PRI-469: Sanitize intentTension free-text fields.
|
|
314
|
+
// Enum fields (source, evidenceStrength, suggestedOwnerAction) and
|
|
315
|
+
// relatedIntentFields are controlled vocabularies validated by the core,
|
|
316
|
+
// so they don't need sanitization. The explanation, evidence items,
|
|
317
|
+
// and intentDocHash may contain user/system-generated text.
|
|
318
|
+
if (record.intentTension) {
|
|
319
|
+
record.intentTension.explanation = sanitizeString(record.intentTension.explanation, this.workspaceDir);
|
|
320
|
+
record.intentTension.evidence = record.intentTension.evidence.map((item) => sanitizeString(item, this.workspaceDir));
|
|
321
|
+
if (record.intentTension.intentDocHash) {
|
|
322
|
+
record.intentTension.intentDocHash = sanitizeString(record.intentTension.intentDocHash, this.workspaceDir);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
291
325
|
}
|
|
292
326
|
return response;
|
|
293
327
|
}
|
|
@@ -240,8 +240,9 @@ export class HealthCheckModel {
|
|
|
240
240
|
lastPrincipleAdded = latestSignal?.updatedAt ?? null;
|
|
241
241
|
}
|
|
242
242
|
}
|
|
243
|
-
catch {
|
|
244
|
-
// Pruning not available — leave as null
|
|
243
|
+
catch (e) {
|
|
244
|
+
// Pruning not available — leave as null, but log for observability (ERR-002)
|
|
245
|
+
console.warn('HealthCheckModel.getPipelineTimestamps: pruning read failed, lastPrincipleAdded left null:', e);
|
|
245
246
|
}
|
|
246
247
|
return {
|
|
247
248
|
lastPainSignal,
|
|
@@ -250,7 +251,8 @@ export class HealthCheckModel {
|
|
|
250
251
|
lastPrincipleAdded,
|
|
251
252
|
};
|
|
252
253
|
}
|
|
253
|
-
catch {
|
|
254
|
+
catch (e) {
|
|
255
|
+
console.warn('HealthCheckModel.getPipelineTimestamps: failed to read pipeline timestamps, returning all null:', e);
|
|
254
256
|
return {
|
|
255
257
|
lastPainSignal: null,
|
|
256
258
|
lastTaskCreated: null,
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IntentDecisionModel — Console model for IntentDecisionRecord (PRI-470).
|
|
3
|
+
*
|
|
4
|
+
* Holds the workspaceDir (like ApprovalsConsoleModel) and opens a per-request
|
|
5
|
+
* SqliteConnection inside each method: open → delegate to SqliteIntentDecisionStore
|
|
6
|
+
* → close. This keeps each operation isolated and safe across workspaces.
|
|
7
|
+
*
|
|
8
|
+
* Graceful degradation (SPEC §21.7 / ERR-002):
|
|
9
|
+
* - Missing state.db → reads return null/empty/zero summary; writes return a
|
|
10
|
+
* structured `not_initialized` result so the route can map to a clear HTTP
|
|
11
|
+
* error instead of silently creating a half-initialized workspace.
|
|
12
|
+
* - Missing intent_decisions table → reads degrade to empty; writes re-throw
|
|
13
|
+
* (the table is created by SqliteConnection.initSchema, so its absence
|
|
14
|
+
* signals a corrupted or pre-PD workspace that should not be written to).
|
|
15
|
+
*
|
|
16
|
+
* ERR checklist:
|
|
17
|
+
* - EP-01 / ERR-001, ERR-005: store rows validated via core type guards
|
|
18
|
+
* - EP-03 / ERR-002: every degraded path carries reason + nextAction
|
|
19
|
+
* - EP-09: model is a thin I/O adapter over the pure store contract
|
|
20
|
+
*/
|
|
21
|
+
import type { IntentDecisionInput, IntentDecisionRecord, IntentDecisionSummary, FollowUpPatch } from '@principles/core/runtime-v2';
|
|
22
|
+
export type IntentDecisionRecordResultModel = {
|
|
23
|
+
ok: true;
|
|
24
|
+
record: IntentDecisionRecord;
|
|
25
|
+
created: boolean;
|
|
26
|
+
} | {
|
|
27
|
+
ok: false;
|
|
28
|
+
reason: string;
|
|
29
|
+
nextAction: string;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Result of a follow-up dispatch (PRI-471, SPEC §22.1.4).
|
|
33
|
+
*
|
|
34
|
+
* - ok:true + record — the existing record was updated with the follow-up
|
|
35
|
+
* field (e.g. `patchProposalId`, `resultingCandidateId`).
|
|
36
|
+
* - ok:false + reason 'decision_not_found' — no IntentDecisionRecord with
|
|
37
|
+
* the given id exists; the route maps this to 404.
|
|
38
|
+
* - ok:false + reason 'state_db_not_found' / 'intent_decisions_table_missing'
|
|
39
|
+
* — same degradation as the record() path.
|
|
40
|
+
*/
|
|
41
|
+
export type FollowUpDispatchResultModel = {
|
|
42
|
+
ok: true;
|
|
43
|
+
record: IntentDecisionRecord;
|
|
44
|
+
} | {
|
|
45
|
+
ok: false;
|
|
46
|
+
reason: 'decision_not_found' | 'state_db_not_found' | 'intent_decisions_table_missing';
|
|
47
|
+
nextAction: string;
|
|
48
|
+
};
|
|
49
|
+
export declare class IntentDecisionModel {
|
|
50
|
+
private readonly workspaceDir;
|
|
51
|
+
constructor(workspaceDir: string);
|
|
52
|
+
record(input: IntentDecisionInput): Promise<IntentDecisionRecordResultModel>;
|
|
53
|
+
getById(id: string): Promise<IntentDecisionRecord | null>;
|
|
54
|
+
listByPainId(painId: string): Promise<IntentDecisionRecord[]>;
|
|
55
|
+
listByTaskId(taskId: string): Promise<IntentDecisionRecord[]>;
|
|
56
|
+
getSummary(): Promise<IntentDecisionSummary>;
|
|
57
|
+
/**
|
|
58
|
+
* Update follow-up action fields on an existing IntentDecisionRecord
|
|
59
|
+
* (PRI-471, SPEC §22.1.4).
|
|
60
|
+
*
|
|
61
|
+
* Called by the follow-up route after the Owner decision has been
|
|
62
|
+
* persisted. Only fields present in `patch` are written; the rest stay
|
|
63
|
+
* unchanged. Returns the updated record or a structured failure.
|
|
64
|
+
*/
|
|
65
|
+
updateFollowUp(id: string, patch: FollowUpPatch): Promise<FollowUpDispatchResultModel>;
|
|
66
|
+
}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IntentDecisionModel — Console model for IntentDecisionRecord (PRI-470).
|
|
3
|
+
*
|
|
4
|
+
* Holds the workspaceDir (like ApprovalsConsoleModel) and opens a per-request
|
|
5
|
+
* SqliteConnection inside each method: open → delegate to SqliteIntentDecisionStore
|
|
6
|
+
* → close. This keeps each operation isolated and safe across workspaces.
|
|
7
|
+
*
|
|
8
|
+
* Graceful degradation (SPEC §21.7 / ERR-002):
|
|
9
|
+
* - Missing state.db → reads return null/empty/zero summary; writes return a
|
|
10
|
+
* structured `not_initialized` result so the route can map to a clear HTTP
|
|
11
|
+
* error instead of silently creating a half-initialized workspace.
|
|
12
|
+
* - Missing intent_decisions table → reads degrade to empty; writes re-throw
|
|
13
|
+
* (the table is created by SqliteConnection.initSchema, so its absence
|
|
14
|
+
* signals a corrupted or pre-PD workspace that should not be written to).
|
|
15
|
+
*
|
|
16
|
+
* ERR checklist:
|
|
17
|
+
* - EP-01 / ERR-001, ERR-005: store rows validated via core type guards
|
|
18
|
+
* - EP-03 / ERR-002: every degraded path carries reason + nextAction
|
|
19
|
+
* - EP-09: model is a thin I/O adapter over the pure store contract
|
|
20
|
+
*/
|
|
21
|
+
import * as fs from 'node:fs';
|
|
22
|
+
import * as path from 'node:path';
|
|
23
|
+
import { SqliteConnection, SqliteIntentDecisionStore, } from '@principles/core/runtime-v2';
|
|
24
|
+
function stateDbExists(workspaceDir) {
|
|
25
|
+
return fs.existsSync(path.join(workspaceDir, '.pd', 'state.db'));
|
|
26
|
+
}
|
|
27
|
+
function isMissingTableError(err) {
|
|
28
|
+
if (!(err instanceof Error))
|
|
29
|
+
return false;
|
|
30
|
+
return err.message.includes('no such table');
|
|
31
|
+
}
|
|
32
|
+
function emptySummary() {
|
|
33
|
+
return {
|
|
34
|
+
counts: {
|
|
35
|
+
confirm_drift: 0,
|
|
36
|
+
revise_intent: 0,
|
|
37
|
+
observe: 0,
|
|
38
|
+
dismiss: 0,
|
|
39
|
+
promote_to_principle: 0,
|
|
40
|
+
promote_to_rulehost: 0,
|
|
41
|
+
},
|
|
42
|
+
lastDecisionAt: null,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export class IntentDecisionModel {
|
|
46
|
+
workspaceDir;
|
|
47
|
+
constructor(workspaceDir) {
|
|
48
|
+
this.workspaceDir = workspaceDir;
|
|
49
|
+
}
|
|
50
|
+
async record(input) {
|
|
51
|
+
if (!stateDbExists(this.workspaceDir)) {
|
|
52
|
+
return {
|
|
53
|
+
ok: false,
|
|
54
|
+
reason: 'state_db_not_found',
|
|
55
|
+
nextAction: 'Initialize the workspace with PD (run a diagnosis or pd config) before recording intent decisions.',
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
const connection = new SqliteConnection({ workspaceDir: this.workspaceDir });
|
|
59
|
+
try {
|
|
60
|
+
const store = new SqliteIntentDecisionStore(connection);
|
|
61
|
+
const result = await store.record(input);
|
|
62
|
+
return { ok: true, record: result.record, created: result.created };
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
if (isMissingTableError(err)) {
|
|
66
|
+
return {
|
|
67
|
+
ok: false,
|
|
68
|
+
reason: 'intent_decisions_table_missing',
|
|
69
|
+
nextAction: 'Run pd config doctor or re-initialize the workspace so the intent_decisions table is created.',
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
throw err;
|
|
73
|
+
}
|
|
74
|
+
finally {
|
|
75
|
+
try {
|
|
76
|
+
connection.close();
|
|
77
|
+
}
|
|
78
|
+
catch { /* best-effort */ }
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
async getById(id) {
|
|
82
|
+
if (!stateDbExists(this.workspaceDir))
|
|
83
|
+
return null;
|
|
84
|
+
const connection = new SqliteConnection({ workspaceDir: this.workspaceDir, readonly: true });
|
|
85
|
+
try {
|
|
86
|
+
const store = new SqliteIntentDecisionStore(connection);
|
|
87
|
+
return await store.getById(id);
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
if (isMissingTableError(err))
|
|
91
|
+
return null;
|
|
92
|
+
throw err;
|
|
93
|
+
}
|
|
94
|
+
finally {
|
|
95
|
+
try {
|
|
96
|
+
connection.close();
|
|
97
|
+
}
|
|
98
|
+
catch { /* best-effort */ }
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
async listByPainId(painId) {
|
|
102
|
+
if (!stateDbExists(this.workspaceDir))
|
|
103
|
+
return [];
|
|
104
|
+
const connection = new SqliteConnection({ workspaceDir: this.workspaceDir, readonly: true });
|
|
105
|
+
try {
|
|
106
|
+
const store = new SqliteIntentDecisionStore(connection);
|
|
107
|
+
return await store.listByPainId(painId);
|
|
108
|
+
}
|
|
109
|
+
catch (err) {
|
|
110
|
+
if (isMissingTableError(err))
|
|
111
|
+
return [];
|
|
112
|
+
throw err;
|
|
113
|
+
}
|
|
114
|
+
finally {
|
|
115
|
+
try {
|
|
116
|
+
connection.close();
|
|
117
|
+
}
|
|
118
|
+
catch { /* best-effort */ }
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
async listByTaskId(taskId) {
|
|
122
|
+
if (!stateDbExists(this.workspaceDir))
|
|
123
|
+
return [];
|
|
124
|
+
const connection = new SqliteConnection({ workspaceDir: this.workspaceDir, readonly: true });
|
|
125
|
+
try {
|
|
126
|
+
const store = new SqliteIntentDecisionStore(connection);
|
|
127
|
+
return await store.listByTaskId(taskId);
|
|
128
|
+
}
|
|
129
|
+
catch (err) {
|
|
130
|
+
if (isMissingTableError(err))
|
|
131
|
+
return [];
|
|
132
|
+
throw err;
|
|
133
|
+
}
|
|
134
|
+
finally {
|
|
135
|
+
try {
|
|
136
|
+
connection.close();
|
|
137
|
+
}
|
|
138
|
+
catch { /* best-effort */ }
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
async getSummary() {
|
|
142
|
+
if (!stateDbExists(this.workspaceDir))
|
|
143
|
+
return emptySummary();
|
|
144
|
+
const connection = new SqliteConnection({ workspaceDir: this.workspaceDir, readonly: true });
|
|
145
|
+
try {
|
|
146
|
+
const store = new SqliteIntentDecisionStore(connection);
|
|
147
|
+
return await store.getSummary();
|
|
148
|
+
}
|
|
149
|
+
catch (err) {
|
|
150
|
+
if (isMissingTableError(err))
|
|
151
|
+
return emptySummary();
|
|
152
|
+
throw err;
|
|
153
|
+
}
|
|
154
|
+
finally {
|
|
155
|
+
try {
|
|
156
|
+
connection.close();
|
|
157
|
+
}
|
|
158
|
+
catch { /* best-effort */ }
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Update follow-up action fields on an existing IntentDecisionRecord
|
|
163
|
+
* (PRI-471, SPEC §22.1.4).
|
|
164
|
+
*
|
|
165
|
+
* Called by the follow-up route after the Owner decision has been
|
|
166
|
+
* persisted. Only fields present in `patch` are written; the rest stay
|
|
167
|
+
* unchanged. Returns the updated record or a structured failure.
|
|
168
|
+
*/
|
|
169
|
+
async updateFollowUp(id, patch) {
|
|
170
|
+
if (!stateDbExists(this.workspaceDir)) {
|
|
171
|
+
return {
|
|
172
|
+
ok: false,
|
|
173
|
+
reason: 'state_db_not_found',
|
|
174
|
+
nextAction: 'Initialize the workspace with PD (run a diagnosis or pd config) before dispatching follow-up actions.',
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
const connection = new SqliteConnection({ workspaceDir: this.workspaceDir });
|
|
178
|
+
try {
|
|
179
|
+
const store = new SqliteIntentDecisionStore(connection);
|
|
180
|
+
const record = await store.updateFollowUp(id, patch);
|
|
181
|
+
if (record === null) {
|
|
182
|
+
return {
|
|
183
|
+
ok: false,
|
|
184
|
+
reason: 'decision_not_found',
|
|
185
|
+
nextAction: 'Intent decision ' + id + ' does not exist. Refresh the page and try again.',
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
return { ok: true, record };
|
|
189
|
+
}
|
|
190
|
+
catch (err) {
|
|
191
|
+
if (isMissingTableError(err)) {
|
|
192
|
+
return {
|
|
193
|
+
ok: false,
|
|
194
|
+
reason: 'intent_decisions_table_missing',
|
|
195
|
+
nextAction: 'Run pd config doctor or re-initialize the workspace so the intent_decisions table is created.',
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
throw err;
|
|
199
|
+
}
|
|
200
|
+
finally {
|
|
201
|
+
try {
|
|
202
|
+
connection.close();
|
|
203
|
+
}
|
|
204
|
+
catch { /* best-effort */ }
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|