create-principles-disciple 1.144.27 → 1.145.1
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/LICENSE +73 -21
- package/NOTICE +2 -0
- package/README.md +1 -1
- package/_release/product-identity.json +2 -2
- package/codex-adapter/dist/index.d.ts +2 -2
- package/codex-adapter/dist/index.js +1 -1
- package/codex-adapter/dist/ingestion/admission.js +16 -0
- package/codex-adapter/dist/ingestion/codex-version.d.ts +10 -4
- package/codex-adapter/dist/ingestion/codex-version.js +10 -4
- package/codex-adapter/dist/ingestion/explicit-owner-statement.d.ts +48 -0
- package/codex-adapter/dist/ingestion/explicit-owner-statement.js +123 -0
- package/codex-adapter/dist/ingestion/ingestion.js +50 -1
- package/codex-adapter/dist/pd-hook.js +66 -3
- package/codex-adapter/dist/worker/workspace-worker.d.ts +14 -0
- package/codex-adapter/dist/worker/workspace-worker.js +194 -11
- package/codex-adapter/package.json +6 -4
- package/console/dist/server/models/ApprovalsConsoleModel.d.ts +2 -2
- package/console/dist/server/models/ApprovalsConsoleModel.js +1 -1
- package/console/dist/server/models/ApprovalsGroupedConsoleModel.js +1 -1
- package/console/dist/server/models/PrinciplesConsoleModel.d.ts +26 -1
- package/console/dist/server/models/PrinciplesConsoleModel.js +18 -1
- package/console/dist/server/routes/activations.js +4 -4
- package/console/dist/server/routes/approvals.js +2 -2
- package/console/dist/server/routes/failed-tasks.d.ts +9 -0
- package/console/dist/server/routes/failed-tasks.js +116 -7
- package/console/dist/server/routes/principles.js +73 -1
- package/console/dist/shared/prompt-injection-contract.d.ts +1 -1
- package/console/dist/ui/api.d.ts +5 -5
- package/console/dist/ui/i18n/en.json +13 -2
- package/console/dist/ui/i18n/zh-CN.json +13 -2
- package/console/dist/ui/pages/activation/ActivationPage.js +2 -1
- package/console/dist/ui/pages/failed-tasks/FailedTasksPage.js +42 -4
- package/console/dist/ui/pages/focus/FocusPage.js +3 -3
- package/console/dist/ui/pages/principles/PrinciplesPage.js +7 -2
- package/console/dist/ui/utils/validators.d.ts +6 -2
- package/console/dist/ui/utils/validators.js +19 -4
- package/console/dist/web/assets/app.css +26 -0
- package/console/dist/web/assets/app.js +24 -24
- package/console/package.json +6 -5
- package/core/dist/host/host-installer.d.ts +3 -1
- package/core/dist/host/host-installer.d.ts.map +1 -1
- package/core/dist/host/host-installer.js.map +1 -1
- package/core/dist/runtime-v2/admission-gate.d.ts +8 -0
- package/core/dist/runtime-v2/admission-gate.d.ts.map +1 -1
- package/core/dist/runtime-v2/admission-gate.js +3 -2
- package/core/dist/runtime-v2/admission-gate.js.map +1 -1
- package/core/dist/runtime-v2/config/pd-config-defaults.d.ts.map +1 -1
- package/core/dist/runtime-v2/config/pd-config-defaults.js +16 -1
- package/core/dist/runtime-v2/config/pd-config-defaults.js.map +1 -1
- package/core/dist/runtime-v2/context-payload.d.ts +43 -3
- package/core/dist/runtime-v2/context-payload.d.ts.map +1 -1
- package/core/dist/runtime-v2/context-payload.js +15 -1
- package/core/dist/runtime-v2/context-payload.js.map +1 -1
- package/core/dist/runtime-v2/evidence-guards.d.ts +6 -0
- package/core/dist/runtime-v2/evidence-guards.d.ts.map +1 -1
- package/core/dist/runtime-v2/evidence-guards.js +11 -0
- package/core/dist/runtime-v2/evidence-guards.js.map +1 -1
- package/core/dist/runtime-v2/evolution/evolution-types.d.ts +4 -4
- package/core/dist/runtime-v2/evolution/evolution-types.d.ts.map +1 -1
- package/core/dist/runtime-v2/evolution/evolution-types.js +1 -1
- package/core/dist/runtime-v2/evolution/evolution-types.js.map +1 -1
- 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 +6 -0
- package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js.map +1 -1
- package/core/dist/runtime-v2/feature-flags/feature-flag-lifecycle.d.ts.map +1 -1
- package/core/dist/runtime-v2/feature-flags/feature-flag-lifecycle.js +8 -0
- package/core/dist/runtime-v2/feature-flags/feature-flag-lifecycle.js.map +1 -1
- package/core/dist/runtime-v2/index.d.ts +5 -2
- package/core/dist/runtime-v2/index.d.ts.map +1 -1
- package/core/dist/runtime-v2/index.js +3 -1
- package/core/dist/runtime-v2/index.js.map +1 -1
- package/core/dist/runtime-v2/internalization/evaluator-output.d.ts +11 -0
- package/core/dist/runtime-v2/internalization/evaluator-output.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/evaluator-output.js +10 -0
- package/core/dist/runtime-v2/internalization/evaluator-output.js.map +1 -1
- package/core/dist/runtime-v2/internalization/evaluator-prompt-builder.d.ts +3 -3
- package/core/dist/runtime-v2/internalization/evaluator-prompt-builder.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/evaluator-prompt-builder.js +49 -5
- package/core/dist/runtime-v2/internalization/evaluator-prompt-builder.js.map +1 -1
- package/core/dist/runtime-v2/internalization/evaluator-runner.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/evaluator-runner.js +13 -16
- package/core/dist/runtime-v2/internalization/evaluator-runner.js.map +1 -1
- package/core/dist/runtime-v2/internalization/owner-decision-review.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/owner-decision-review.js +5 -1
- package/core/dist/runtime-v2/internalization/owner-decision-review.js.map +1 -1
- package/core/dist/runtime-v2/internalization/owner-review.d.ts +2 -2
- package/core/dist/runtime-v2/internalization/owner-review.js +2 -2
- package/core/dist/runtime-v2/internalization/scribe-output.d.ts +12 -0
- package/core/dist/runtime-v2/internalization/scribe-output.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/scribe-output.js +20 -0
- package/core/dist/runtime-v2/internalization/scribe-output.js.map +1 -1
- package/core/dist/runtime-v2/internalization/scribe-prompt-builder.d.ts +32 -1
- package/core/dist/runtime-v2/internalization/scribe-prompt-builder.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/scribe-prompt-builder.js +38 -1
- package/core/dist/runtime-v2/internalization/scribe-prompt-builder.js.map +1 -1
- package/core/dist/runtime-v2/internalization-queue-read-model.d.ts +6 -0
- package/core/dist/runtime-v2/internalization-queue-read-model.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization-queue-read-model.js +8 -1
- package/core/dist/runtime-v2/internalization-queue-read-model.js.map +1 -1
- package/core/dist/runtime-v2/intervention-evidence-normalizer.d.ts.map +1 -1
- package/core/dist/runtime-v2/intervention-evidence-normalizer.js +10 -3
- package/core/dist/runtime-v2/intervention-evidence-normalizer.js.map +1 -1
- package/core/dist/runtime-v2/pain-ingress.d.ts +1 -1
- package/core/dist/runtime-v2/pain-ingress.d.ts.map +1 -1
- package/core/dist/runtime-v2/pain-signal-bridge.d.ts +68 -2
- package/core/dist/runtime-v2/pain-signal-bridge.d.ts.map +1 -1
- package/core/dist/runtime-v2/pain-signal-bridge.js +541 -18
- package/core/dist/runtime-v2/pain-signal-bridge.js.map +1 -1
- package/core/dist/runtime-v2/pain-signal-runtime-factory.d.ts.map +1 -1
- package/core/dist/runtime-v2/pain-signal-runtime-factory.js +4 -0
- package/core/dist/runtime-v2/pain-signal-runtime-factory.js.map +1 -1
- package/core/dist/runtime-v2/product-telemetry/snapshot-contract.d.ts +2 -2
- package/core/dist/runtime-v2/product-telemetry/snapshot-contract.d.ts.map +1 -1
- package/core/dist/runtime-v2/product-telemetry/snapshot-contract.js +2 -2
- package/core/dist/runtime-v2/product-telemetry/snapshot-contract.js.map +1 -1
- package/core/dist/runtime-v2/store/candidate/admission-document.d.ts +90 -0
- package/core/dist/runtime-v2/store/candidate/admission-document.d.ts.map +1 -0
- package/core/dist/runtime-v2/store/candidate/admission-document.js +142 -0
- package/core/dist/runtime-v2/store/candidate/admission-document.js.map +1 -0
- package/core/dist/runtime-v2/store/candidate/candidate-store.d.ts +53 -0
- package/core/dist/runtime-v2/store/candidate/candidate-store.d.ts.map +1 -1
- package/core/dist/runtime-v2/store/candidate/memory-candidate-store.d.ts +35 -0
- package/core/dist/runtime-v2/store/candidate/memory-candidate-store.d.ts.map +1 -1
- package/core/dist/runtime-v2/store/candidate/memory-candidate-store.js +48 -0
- package/core/dist/runtime-v2/store/candidate/memory-candidate-store.js.map +1 -1
- package/core/dist/runtime-v2/store/candidate/sqlite-candidate-store.d.ts +44 -0
- package/core/dist/runtime-v2/store/candidate/sqlite-candidate-store.d.ts.map +1 -1
- package/core/dist/runtime-v2/store/candidate/sqlite-candidate-store.js +136 -0
- package/core/dist/runtime-v2/store/candidate/sqlite-candidate-store.js.map +1 -1
- package/core/dist/runtime-v2/store/context/sqlite-context-assembler.js.map +1 -1
- package/core/dist/runtime-v2/store/intervention-evidence-schema.js +1 -1
- package/core/dist/runtime-v2/store/runtime-state-manager.d.ts +65 -0
- package/core/dist/runtime-v2/store/runtime-state-manager.d.ts.map +1 -1
- package/core/dist/runtime-v2/store/runtime-state-manager.js +46 -0
- package/core/dist/runtime-v2/store/runtime-state-manager.js.map +1 -1
- package/core/dist/runtime-v2/store/sqlite-connection.d.ts.map +1 -1
- package/core/dist/runtime-v2/store/sqlite-connection.js +42 -0
- package/core/dist/runtime-v2/store/sqlite-connection.js.map +1 -1
- package/core/dist/runtime-v2/store/sqlite-intervention-evidence-store.d.ts +1 -1
- package/core/dist/runtime-v2/store/sqlite-intervention-evidence-store.d.ts.map +1 -1
- package/core/dist/runtime-v2/store/sqlite-intervention-evidence-store.js.map +1 -1
- package/core/dist/runtime-v2/store/task/sqlite-family-reopen.d.ts +19 -0
- package/core/dist/runtime-v2/store/task/sqlite-family-reopen.d.ts.map +1 -0
- package/core/dist/runtime-v2/store/task/sqlite-family-reopen.js +36 -0
- package/core/dist/runtime-v2/store/task/sqlite-family-reopen.js.map +1 -0
- package/core/dist/runtime-v2/store/task/sqlite-task-store.d.ts +23 -0
- package/core/dist/runtime-v2/store/task/sqlite-task-store.d.ts.map +1 -1
- package/core/dist/runtime-v2/store/task/sqlite-task-store.js +50 -0
- package/core/dist/runtime-v2/store/task/sqlite-task-store.js.map +1 -1
- package/core/dist/runtime-v2/task-status.d.ts +3 -1
- package/core/dist/runtime-v2/task-status.d.ts.map +1 -1
- package/core/dist/runtime-v2/task-status.js +1 -1
- package/core/dist/runtime-v2/task-status.js.map +1 -1
- package/core/dist/runtime-v2/trajectory-schema.d.ts.map +1 -1
- package/core/dist/runtime-v2/trajectory-schema.js +11 -0
- package/core/dist/runtime-v2/trajectory-schema.js.map +1 -1
- package/core/dist/runtime-v2/types/event-types.d.ts +2 -2
- package/core/dist/runtime-v2/types/event-types.d.ts.map +1 -1
- package/core/dist/runtime-v2/types/event-types.js +1 -1
- package/core/dist/runtime-v2/types/event-types.js.map +1 -1
- package/core/dist/runtime-v2/types/evidence-chain-contract.d.ts +1 -1
- package/core/dist/runtime-v2/types/evidence-chain-contract.d.ts.map +1 -1
- package/core/dist/runtime-v2/types/evidence-chain-contract.js +2 -2
- package/core/dist/runtime-v2/types/evidence-chain-contract.js.map +1 -1
- package/core/dist/runtime-v2/types/intervention-evidence-contract.d.ts +3 -3
- package/core/dist/runtime-v2/types/intervention-evidence-contract.d.ts.map +1 -1
- package/core/dist/runtime-v2/types/intervention-evidence-contract.js +1 -0
- package/core/dist/runtime-v2/types/intervention-evidence-contract.js.map +1 -1
- package/core/dist/telemetry-event.d.ts +2 -2
- package/core/dist/telemetry-event.d.ts.map +1 -1
- package/core/dist/telemetry-event.js +4 -0
- package/core/dist/telemetry-event.js.map +1 -1
- package/core/dist/trajectory-types.d.ts +2 -2
- package/core/dist/trajectory-types.d.ts.map +1 -1
- package/core/package.json +7 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +84 -8
- package/dist/index.js.map +1 -1
- package/dist/installer.d.ts +42 -11
- package/dist/installer.d.ts.map +1 -1
- package/dist/installer.js +140 -36
- package/dist/installer.js.map +1 -1
- package/dist/installers/index.d.ts +18 -7
- package/dist/installers/index.d.ts.map +1 -1
- package/dist/installers/index.js +13 -4
- package/dist/installers/index.js.map +1 -1
- package/dist/installers/workbuddy-host-installer.d.ts +246 -0
- package/dist/installers/workbuddy-host-installer.d.ts.map +1 -0
- package/dist/installers/workbuddy-host-installer.js +1419 -0
- package/dist/installers/workbuddy-host-installer.js.map +1 -0
- package/dist/mvp-config.d.ts +24 -0
- package/dist/mvp-config.d.ts.map +1 -1
- package/dist/mvp-config.js +36 -0
- package/dist/mvp-config.js.map +1 -1
- package/dist/prompts.d.ts +13 -0
- package/dist/prompts.d.ts.map +1 -1
- package/dist/prompts.js +45 -8
- package/dist/prompts.js.map +1 -1
- package/dist/uninstaller.d.ts +1 -1
- package/dist/uninstaller.d.ts.map +1 -1
- package/dist/uninstaller.js +29 -4
- package/dist/uninstaller.js.map +1 -1
- package/host-runtime/dist/governance-signal-admission.d.ts +63 -0
- package/host-runtime/dist/governance-signal-admission.js +322 -53
- package/host-runtime/dist/host-liveness-contract.js +7 -1
- package/host-runtime/dist/index.d.ts +1 -0
- package/host-runtime/dist/index.js +5 -1
- package/host-runtime/dist/internalization-consumer-cycle.d.ts +12 -0
- package/host-runtime/dist/internalization-consumer-cycle.js +43 -1
- package/host-runtime/dist/intervention-evidence-ingress.d.ts +1 -1
- package/host-runtime/dist/product-telemetry/service.js +1 -1
- package/host-runtime/dist/production-pain-evidence.d.ts +59 -1
- package/host-runtime/dist/production-pain-evidence.js +200 -17
- package/host-runtime/dist/prompt-activation-deliverability.js +5 -4
- package/host-runtime/dist/prompt-injection-event-evidence.d.ts +1 -1
- package/host-runtime/dist/prompt-injection-event-evidence.js +5 -1
- package/host-runtime/dist/prompt-injection-projection.d.ts +14 -5
- package/host-runtime/dist/prompt-injection-projection.js +30 -16
- package/host-runtime/dist/workbuddy-worker-status.d.ts +24 -0
- package/host-runtime/dist/workbuddy-worker-status.js +52 -0
- package/host-runtime/package.json +7 -5
- package/install-layout/dist/index.d.ts +18 -1
- package/install-layout/dist/index.js +15 -2
- package/install-layout/package.json +5 -3
- package/package.json +9 -7
- package/pd-cli/dist/commands/candidate.d.ts.map +1 -1
- package/pd-cli/dist/commands/candidate.js +44 -4
- package/pd-cli/dist/commands/candidate.js.map +1 -1
- package/pd-cli/dist/commands/codex-worker.d.ts.map +1 -1
- package/pd-cli/dist/commands/codex-worker.js +30 -1
- package/pd-cli/dist/commands/codex-worker.js.map +1 -1
- package/pd-cli/dist/commands/config-doctor.d.ts.map +1 -1
- package/pd-cli/dist/commands/config-doctor.js +19 -4
- package/pd-cli/dist/commands/config-doctor.js.map +1 -1
- package/pd-cli/dist/commands/diagnose.d.ts.map +1 -1
- package/pd-cli/dist/commands/diagnose.js +4 -1
- package/pd-cli/dist/commands/diagnose.js.map +1 -1
- package/pd-cli/dist/commands/health-codex-install.d.ts +85 -0
- package/pd-cli/dist/commands/health-codex-install.d.ts.map +1 -0
- package/pd-cli/dist/commands/health-codex-install.js +207 -0
- package/pd-cli/dist/commands/health-codex-install.js.map +1 -0
- package/pd-cli/dist/commands/health-codex.d.ts.map +1 -1
- package/pd-cli/dist/commands/health-codex.js +78 -0
- package/pd-cli/dist/commands/health-codex.js.map +1 -1
- package/pd-cli/dist/commands/pain-list.d.ts +3 -2
- package/pd-cli/dist/commands/pain-list.d.ts.map +1 -1
- package/pd-cli/dist/commands/pain-list.js +10 -10
- package/pd-cli/dist/commands/pain-list.js.map +1 -1
- package/pd-cli/dist/commands/pain-record.d.ts +2 -0
- package/pd-cli/dist/commands/pain-record.d.ts.map +1 -1
- package/pd-cli/dist/commands/pain-record.js +36 -0
- package/pd-cli/dist/commands/pain-record.js.map +1 -1
- package/pd-cli/dist/commands/pain-retry.d.ts +6 -0
- package/pd-cli/dist/commands/pain-retry.d.ts.map +1 -1
- package/pd-cli/dist/commands/pain-retry.js +152 -5
- package/pd-cli/dist/commands/pain-retry.js.map +1 -1
- package/pd-cli/dist/commands/runtime-activation.d.ts +1 -1
- package/pd-cli/dist/commands/runtime-activation.d.ts.map +1 -1
- package/pd-cli/dist/commands/runtime-activation.js +3 -3
- package/pd-cli/dist/commands/runtime-activation.js.map +1 -1
- package/pd-cli/dist/commands/workbuddy-worker.d.ts +19 -0
- package/pd-cli/dist/commands/workbuddy-worker.d.ts.map +1 -0
- package/pd-cli/dist/commands/workbuddy-worker.js +168 -0
- package/pd-cli/dist/commands/workbuddy-worker.js.map +1 -0
- package/pd-cli/dist/index.js +29 -1
- package/pd-cli/dist/index.js.map +1 -1
- package/pd-cli/dist/resolve-workspace.d.ts +14 -2
- package/pd-cli/dist/resolve-workspace.d.ts.map +1 -1
- package/pd-cli/dist/resolve-workspace.js +88 -21
- package/pd-cli/dist/resolve-workspace.js.map +1 -1
- package/pd-cli/dist/services/admission-write-gate.d.ts +24 -0
- package/pd-cli/dist/services/admission-write-gate.d.ts.map +1 -0
- package/pd-cli/dist/services/admission-write-gate.js +41 -0
- package/pd-cli/dist/services/admission-write-gate.js.map +1 -0
- package/pd-cli/dist/services/pd-config-loader.d.ts +39 -7
- package/pd-cli/dist/services/pd-config-loader.d.ts.map +1 -1
- package/pd-cli/dist/services/pd-config-loader.js +111 -18
- package/pd-cli/dist/services/pd-config-loader.js.map +1 -1
- package/pd-cli/dist/services/rulehost-pipeline-runner.d.ts +10 -0
- package/pd-cli/dist/services/rulehost-pipeline-runner.d.ts.map +1 -1
- package/pd-cli/dist/services/rulehost-pipeline-runner.js +59 -4
- package/pd-cli/dist/services/rulehost-pipeline-runner.js.map +1 -1
- package/pd-cli/package.json +8 -5
- package/plugin/dist/bundle.js +564 -509
- package/plugin/dist/governance-audit.js +1 -1
- package/plugin/dist/openclaw.plugin.json +1 -1
- package/plugin/dist/rulehost-evidence.js +1 -1
- package/plugin/openclaw.plugin.json +1 -1
- package/plugin/package.json +7 -5
- package/release-manager/dist/index.d.ts.map +1 -1
- package/release-manager/dist/index.js +84 -8
- package/release-manager/dist/index.js.map +1 -1
- package/release-manager/dist/installer.d.ts +42 -11
- package/release-manager/dist/installer.d.ts.map +1 -1
- package/release-manager/dist/installer.js +140 -36
- package/release-manager/dist/installer.js.map +1 -1
- package/release-manager/dist/installers/index.d.ts +18 -7
- package/release-manager/dist/installers/index.d.ts.map +1 -1
- package/release-manager/dist/installers/index.js +13 -4
- package/release-manager/dist/installers/index.js.map +1 -1
- package/release-manager/dist/installers/workbuddy-host-installer.d.ts +246 -0
- package/release-manager/dist/installers/workbuddy-host-installer.d.ts.map +1 -0
- package/release-manager/dist/installers/workbuddy-host-installer.js +1419 -0
- package/release-manager/dist/installers/workbuddy-host-installer.js.map +1 -0
- package/release-manager/dist/mvp-config.d.ts +24 -0
- package/release-manager/dist/mvp-config.d.ts.map +1 -1
- package/release-manager/dist/mvp-config.js +36 -0
- package/release-manager/dist/mvp-config.js.map +1 -1
- package/release-manager/dist/prompts.d.ts +13 -0
- package/release-manager/dist/prompts.d.ts.map +1 -1
- package/release-manager/dist/prompts.js +45 -8
- package/release-manager/dist/prompts.js.map +1 -1
- package/release-manager/dist/uninstaller.d.ts +1 -1
- package/release-manager/dist/uninstaller.d.ts.map +1 -1
- package/release-manager/dist/uninstaller.js +29 -4
- package/release-manager/dist/uninstaller.js.map +1 -1
- package/release-manager/package.json +8 -6
- package/workbuddy-adapter/dist/codec/index.d.ts +2 -0
- package/workbuddy-adapter/dist/codec/index.js +2 -0
- package/workbuddy-adapter/dist/codec/input-decoder.d.ts +30 -0
- package/workbuddy-adapter/dist/codec/input-decoder.js +232 -0
- package/workbuddy-adapter/dist/codec/output-encoder.d.ts +62 -0
- package/workbuddy-adapter/dist/codec/output-encoder.js +75 -0
- package/workbuddy-adapter/dist/host-adapter.d.ts +33 -0
- package/workbuddy-adapter/dist/host-adapter.js +23 -0
- package/workbuddy-adapter/dist/index.d.ts +16 -0
- package/workbuddy-adapter/dist/index.js +16 -0
- package/workbuddy-adapter/dist/pd-hook.d.ts +17 -0
- package/workbuddy-adapter/dist/pd-hook.js +505 -0
- package/workbuddy-adapter/dist/tool-semantics.d.ts +22 -0
- package/workbuddy-adapter/dist/tool-semantics.js +33 -0
- package/workbuddy-adapter/dist/workbuddy-evidence-recorder.d.ts +50 -0
- package/workbuddy-adapter/dist/workbuddy-evidence-recorder.js +238 -0
- package/workbuddy-adapter/dist/worker/workspace-worker.d.ts +41 -0
- package/workbuddy-adapter/dist/worker/workspace-worker.js +219 -0
- package/workbuddy-adapter/dist/workspace-resolution.d.ts +15 -0
- package/workbuddy-adapter/dist/workspace-resolution.js +53 -0
- package/workbuddy-adapter/package.json +64 -0
- package/workbuddy-adapter/plugin/.codebuddy-plugin/plugin.json +6 -0
- package/workbuddy-adapter/plugin/hooks/hooks.json +62 -0
- package/workbuddy-adapter/plugin/scripts/wrapper.cjs +79 -0
- package/console/dist/ui/utils/navigation.d.ts +0 -9
- package/console/dist/ui/utils/navigation.js +0 -7
- package/core/dist/runtime-v2/internalization/dimension-coverage-policy.d.ts +0 -54
- package/core/dist/runtime-v2/internalization/dimension-coverage-policy.d.ts.map +0 -1
- package/core/dist/runtime-v2/internalization/dimension-coverage-policy.js +0 -70
- package/core/dist/runtime-v2/internalization/dimension-coverage-policy.js.map +0 -1
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @principles/workbuddy-adapter — the WorkBuddy host adapter for Principles
|
|
3
|
+
* Disciple (ADR-0020 third host, SPEC workbuddy-host-adapter v0.3.0).
|
|
4
|
+
*
|
|
5
|
+
* Public surface mirrors the codex-adapter layout: the HostAdapter
|
|
6
|
+
* implementation, the codec, the governance-workspace resolution, the tool
|
|
7
|
+
* semantic declaration, and the evidence recorder. The process entry lives
|
|
8
|
+
* at ./pd-hook (spawned per hook event by plugin/scripts/wrapper.cjs).
|
|
9
|
+
*/
|
|
10
|
+
export { WorkBuddyHooksHostAdapter } from './host-adapter.js';
|
|
11
|
+
export { decodeWorkbuddyInput, normalizeWorkbuddyToolResponse, encodeWorkbuddyOutput, workbuddyOutputFieldsAreWhitelisted, WorkBuddyDecoderError, WorkBuddyEncoderError, WORKBUDDY_EVENT_PRE_TOOL_USE, WORKBUDDY_EVENT_POST_TOOL_USE, WORKBUDDY_EVENT_POST_TOOL_USE_FAILURE, WORKBUDDY_EVENT_USER_PROMPT_SUBMIT, WORKBUDDY_EVENT_SESSION_START, type WorkBuddyHookOutput, } from './codec/index.js';
|
|
12
|
+
export { resolveWorkbuddyWorkspace, type WorkbuddyWorkspaceResolution, } from './workspace-resolution.js';
|
|
13
|
+
export { WORKBUDDY_TOOL_SEMANTICS, WORKBUDDY_TOOL_SEMANTIC_MAPPINGS, } from './tool-semantics.js';
|
|
14
|
+
export { recordWorkbuddyPromptDeliveryEvidence, recordWorkbuddyDenyEvidence, workbuddyCapabilityDeclarations, WORKBUDDY_EVIDENCE_ADAPTER_VERSION, } from './workbuddy-evidence-recorder.js';
|
|
15
|
+
export { processWorkbuddyHookInvocation, annotateContextWarnings, type WorkBuddyPdHookResult, } from './pd-hook.js';
|
|
16
|
+
export { runWorkbuddyWorkspaceWorkerCycle, type WorkbuddyWorkerCycleResult, type WorkbuddyWorkerCycleOptions, type WorkbuddyWorkerCycleStepReport, type WorkbuddyWorkerMode, } from './worker/workspace-worker.js';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @principles/workbuddy-adapter — the WorkBuddy host adapter for Principles
|
|
3
|
+
* Disciple (ADR-0020 third host, SPEC workbuddy-host-adapter v0.3.0).
|
|
4
|
+
*
|
|
5
|
+
* Public surface mirrors the codex-adapter layout: the HostAdapter
|
|
6
|
+
* implementation, the codec, the governance-workspace resolution, the tool
|
|
7
|
+
* semantic declaration, and the evidence recorder. The process entry lives
|
|
8
|
+
* at ./pd-hook (spawned per hook event by plugin/scripts/wrapper.cjs).
|
|
9
|
+
*/
|
|
10
|
+
export { WorkBuddyHooksHostAdapter } from './host-adapter.js';
|
|
11
|
+
export { decodeWorkbuddyInput, normalizeWorkbuddyToolResponse, encodeWorkbuddyOutput, workbuddyOutputFieldsAreWhitelisted, WorkBuddyDecoderError, WorkBuddyEncoderError, WORKBUDDY_EVENT_PRE_TOOL_USE, WORKBUDDY_EVENT_POST_TOOL_USE, WORKBUDDY_EVENT_POST_TOOL_USE_FAILURE, WORKBUDDY_EVENT_USER_PROMPT_SUBMIT, WORKBUDDY_EVENT_SESSION_START, } from './codec/index.js';
|
|
12
|
+
export { resolveWorkbuddyWorkspace, } from './workspace-resolution.js';
|
|
13
|
+
export { WORKBUDDY_TOOL_SEMANTICS, WORKBUDDY_TOOL_SEMANTIC_MAPPINGS, } from './tool-semantics.js';
|
|
14
|
+
export { recordWorkbuddyPromptDeliveryEvidence, recordWorkbuddyDenyEvidence, workbuddyCapabilityDeclarations, WORKBUDDY_EVIDENCE_ADAPTER_VERSION, } from './workbuddy-evidence-recorder.js';
|
|
15
|
+
export { processWorkbuddyHookInvocation, annotateContextWarnings, } from './pd-hook.js';
|
|
16
|
+
export { runWorkbuddyWorkspaceWorkerCycle, } from './worker/workspace-worker.js';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { type WorkBuddyHookOutput } from './codec/index.js';
|
|
3
|
+
type EnvMap = Record<string, string | undefined>;
|
|
4
|
+
export interface WorkBuddyPdHookResult {
|
|
5
|
+
stdout: WorkBuddyHookOutput | null;
|
|
6
|
+
exitCode: number;
|
|
7
|
+
stderr: string[];
|
|
8
|
+
}
|
|
9
|
+
/** Evidence context the emitters need (subprocess-local, best-effort). */
|
|
10
|
+
export interface WorkbuddyEvidenceContext {
|
|
11
|
+
workspaceDir: string;
|
|
12
|
+
evidenceEnabled: boolean;
|
|
13
|
+
warn: (diagnosticLine: string) => void;
|
|
14
|
+
}
|
|
15
|
+
export declare function annotateContextWarnings(warnings: readonly string[]): string[];
|
|
16
|
+
export declare function processWorkbuddyHookInvocation(rawStdin: string, channelEventName: string | undefined, _env?: EnvMap): Promise<WorkBuddyPdHookResult>;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,505 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* WorkBuddy pd-hook — the process entry WorkBuddy invokes per hook event
|
|
4
|
+
* (through plugin/scripts/wrapper.cjs, which forwards stdin/stdout/exit code).
|
|
5
|
+
*
|
|
6
|
+
* FAILURE POLICY (SPEC §4.4 / OD-01, frozen by Phase 0 probe P02):
|
|
7
|
+
* WorkBuddy exit codes have PER-EVENT effects, so unlike the Codex belt
|
|
8
|
+
* ("always exit 0") the channel matters:
|
|
9
|
+
*
|
|
10
|
+
* flag-off / uninitialized / degraded workspace
|
|
11
|
+
* → EMPTY stdout + exit 0 + observable stderr skip/degrade record
|
|
12
|
+
* (rc-9; never escalated to blocking — the Owner has not opted in);
|
|
13
|
+
* PreToolUse INSIDE the supported governance path whose decode/dispatch/
|
|
14
|
+
* encode/serialization fails
|
|
15
|
+
* → exit 2 + bounded stderr + EMPTY stdout (P02 verified exit 2 blocks
|
|
16
|
+
* the tool even when stdout is closed);
|
|
17
|
+
* UserPromptSubmit ANY failure
|
|
18
|
+
* → EMPTY stdout + exit 0 + degraded stderr (P02: exit 2 would CLEAR the
|
|
19
|
+
* user's prompt — protecting the prompt outranks reporting);
|
|
20
|
+
* PostToolUse ANY failure
|
|
21
|
+
* → EMPTY stdout + exit 0 + evidence-degradation stderr (the tool already
|
|
22
|
+
* ran; nothing can be blocked, so blocking language is never used);
|
|
23
|
+
* SessionStart ANY failure
|
|
24
|
+
* → EMPTY stdout + exit 0 + status stderr (non-blocking for the session).
|
|
25
|
+
*
|
|
26
|
+
* An ALREADY-COMPUTED deny always survives evidence-write failure (encode
|
|
27
|
+
* first, record evidence after — P02: deny is the real blocking signal).
|
|
28
|
+
*
|
|
29
|
+
* OUTPUT: stdout carries AT MOST ONE JSON document (the whitelisted
|
|
30
|
+
* hookSpecificOutput) and ONLY when there is something whitelisted to say —
|
|
31
|
+
* the host injects any raw stdout text into model-visible context (P04), so
|
|
32
|
+
* neutral means EMPTY stdout, never `{}`. Diagnostics go to stderr only.
|
|
33
|
+
*/
|
|
34
|
+
import { readFileSync, realpathSync } from 'node:fs';
|
|
35
|
+
import os from 'node:os';
|
|
36
|
+
import path from 'node:path';
|
|
37
|
+
import process from 'node:process';
|
|
38
|
+
import { pathToFileURL, fileURLToPath } from 'node:url';
|
|
39
|
+
import { appendEventLogLine, redactTelemetryString, isRuleHostEvaluatedEventData } from '@principles/core/runtime-v2';
|
|
40
|
+
import { createProductionHostRuntime, loadPdConfigForPlugin } from '@principles/host-runtime';
|
|
41
|
+
import { computeFeatureFlagsFromConfig } from '@principles/core/runtime-v2';
|
|
42
|
+
import { WorkBuddyHooksHostAdapter } from './host-adapter.js';
|
|
43
|
+
import { WORKBUDDY_TOOL_SEMANTICS } from './tool-semantics.js';
|
|
44
|
+
import { resolveWorkbuddyWorkspace } from './workspace-resolution.js';
|
|
45
|
+
import { WorkBuddyDecoderError, WorkBuddyEncoderError, isWorkBuddyHookOutput, WORKBUDDY_EVENT_PRE_TOOL_USE } from './codec/index.js';
|
|
46
|
+
import { recordWorkbuddyPromptDeliveryEvidence, recordWorkbuddyDenyEvidence } from './workbuddy-evidence-recorder.js';
|
|
47
|
+
const MAX_DIAGNOSTIC = 500;
|
|
48
|
+
function bound(text) {
|
|
49
|
+
return text.replace(/\s+/g, ' ').trim().slice(0, MAX_DIAGNOSTIC);
|
|
50
|
+
}
|
|
51
|
+
/** rc-8/rc-9: bounded, single-line, machine-greppable diagnostic on stderr. */
|
|
52
|
+
function diagnostic(status, reason, nextAction) {
|
|
53
|
+
return `[PD] status=${status} reason=${bound(reason)} nextAction=${bound(nextAction)}`;
|
|
54
|
+
}
|
|
55
|
+
function errorMessage(error) {
|
|
56
|
+
return error instanceof Error ? error.message.slice(0, MAX_DIAGNOSTIC) : 'unknown_error';
|
|
57
|
+
}
|
|
58
|
+
function redactStringFields(data) {
|
|
59
|
+
// rc-8: telemetry redacted field by field (same policy as the Codex emitter).
|
|
60
|
+
const redacted = {};
|
|
61
|
+
for (const [key, value] of Object.entries(data)) {
|
|
62
|
+
redacted[key] = typeof value === 'string' ? redactTelemetryString(value) : value;
|
|
63
|
+
}
|
|
64
|
+
return redacted;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Event emitter for the WorkBuddy subprocess: writes the same
|
|
68
|
+
* `events_<date>.jsonl` line shape as the Codex/OpenClaw paths through the
|
|
69
|
+
* core writer, so the WorkBuddy host path carries the host's natural ids
|
|
70
|
+
* (generation_id → runId/turnId, call_id → toolCallId).
|
|
71
|
+
*/
|
|
72
|
+
function workbuddyEventEmitter(stateDir, evidence) {
|
|
73
|
+
return {
|
|
74
|
+
recordRuntimeV2ActivationsInjected(data) {
|
|
75
|
+
appendEventLogLine(stateDir, {
|
|
76
|
+
ts: new Date().toISOString(),
|
|
77
|
+
type: 'runtime_v2_prompt_activations_injected',
|
|
78
|
+
category: 'injected',
|
|
79
|
+
sessionId: data.sessionId,
|
|
80
|
+
data,
|
|
81
|
+
});
|
|
82
|
+
// Delivery evidence AFTER the durable source line exists; degrades to a
|
|
83
|
+
// bounded diagnostic and never affects the hook result.
|
|
84
|
+
if (evidence) {
|
|
85
|
+
try {
|
|
86
|
+
const injected = data.principleIds
|
|
87
|
+
.map((principleId, index) => ({
|
|
88
|
+
principleId,
|
|
89
|
+
activationId: data.activationIds[index] ?? '',
|
|
90
|
+
artifactId: data.artifactIds[index],
|
|
91
|
+
}))
|
|
92
|
+
.filter((entry) => entry.activationId.length > 0);
|
|
93
|
+
recordWorkbuddyPromptDeliveryEvidence({
|
|
94
|
+
workspaceDir: evidence.workspaceDir,
|
|
95
|
+
sessionId: data.sessionId,
|
|
96
|
+
...(data.runId ? { turnId: data.runId } : {}),
|
|
97
|
+
injected,
|
|
98
|
+
evidenceEnabled: evidence.evidenceEnabled,
|
|
99
|
+
warn: evidence.warn,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
evidence.warn(diagnostic('degraded', `workbuddy_evidence_delivery_failed:${errorMessage(error)}`, 'The raw injected event is durable; replay is safe. The hook result is unaffected.'));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
recordToolCall(sessionId, data) {
|
|
108
|
+
appendEventLogLine(stateDir, {
|
|
109
|
+
ts: new Date().toISOString(),
|
|
110
|
+
type: 'tool_call',
|
|
111
|
+
category: data.error || (data.exitCode !== undefined && data.exitCode !== 0) ? 'failure' : 'success',
|
|
112
|
+
sessionId,
|
|
113
|
+
data: redactStringFields(data),
|
|
114
|
+
});
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Persist the shared gate's per-activation evaluation facts
|
|
120
|
+
* (metadata.evaluations — shadow observations plus the live aggregate) as
|
|
121
|
+
* canonical `rulehost_evaluated` events (PRI-813 pattern). One bounded
|
|
122
|
+
* diagnostic per failure CLASS; never throws into the caller's fail-open /
|
|
123
|
+
* fail-closed handling.
|
|
124
|
+
*/
|
|
125
|
+
function recordRuleHostEvaluations(stateDir, sessionId, evaluations) {
|
|
126
|
+
if (!Array.isArray(evaluations))
|
|
127
|
+
return [];
|
|
128
|
+
const diagnostics = [];
|
|
129
|
+
let sawInvalidEntry = false;
|
|
130
|
+
let sawPersistFailure = false;
|
|
131
|
+
for (const entry of evaluations) {
|
|
132
|
+
if (!isRuleHostEvaluatedEventData(entry)) {
|
|
133
|
+
// rc-9: a skipped evidence row must be observable, never silent.
|
|
134
|
+
if (!sawInvalidEntry) {
|
|
135
|
+
sawInvalidEntry = true;
|
|
136
|
+
diagnostics.push(diagnostic('degraded', 'rulehost_evaluation_entry_invalid', 'Inspect host-runtime gate metadata contract; the evaluation event was not persisted.'));
|
|
137
|
+
}
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
try {
|
|
141
|
+
appendEventLogLine(stateDir, {
|
|
142
|
+
ts: new Date().toISOString(),
|
|
143
|
+
type: 'rulehost_evaluated',
|
|
144
|
+
category: 'evaluated',
|
|
145
|
+
sessionId,
|
|
146
|
+
data: redactStringFields(entry),
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
if (!sawPersistFailure) {
|
|
151
|
+
sawPersistFailure = true;
|
|
152
|
+
diagnostics.push(diagnostic('degraded', `rulehost_evaluation_persist_failed:${errorMessage(error)}`, 'Inspect workspace .state/logs writability; the evaluation event was not persisted, the tool decision is unaffected.'));
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return diagnostics;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* PRI-780 pattern (WorkBuddy boundary, same as Codex): this host supplies no
|
|
160
|
+
* runtime context provider, and the "unavailable → allow" contract is prompt
|
|
161
|
+
* discipline, NOT a runtime-enforced invariant. Handing v2 rules a truthy
|
|
162
|
+
* context would let a persisted rule evaluate context-blind and deny calls
|
|
163
|
+
* that were previously suspended — a silent governance change. The gate skips
|
|
164
|
+
* v2 rules with its structured `rule_context_v2_unavailable` warning and this
|
|
165
|
+
* hook annotates the warning with the explicit host-unsupported reason before
|
|
166
|
+
* it reaches stderr (明确 unsupported, never a silent skip).
|
|
167
|
+
*/
|
|
168
|
+
const WORKBUDDY_CONTEXT_UNSUPPORTED_NOTE = 'workbuddy_runtime_context_unsupported: the WorkBuddy host provides no runtime context provider; v2 rules stay suspended on this host';
|
|
169
|
+
export function annotateContextWarnings(warnings) {
|
|
170
|
+
return warnings.map((warning) => warning.startsWith('rule_context_v2_unavailable')
|
|
171
|
+
? `${warning}; ${WORKBUDDY_CONTEXT_UNSUPPORTED_NOTE}`
|
|
172
|
+
: warning);
|
|
173
|
+
}
|
|
174
|
+
/** The wrapper's event argument names the registration context; only a
|
|
175
|
+
* PreToolUse registration channel may escalate a failure to a blocking exit 2. */
|
|
176
|
+
function channelBlocksOnFailure(channelEventName) {
|
|
177
|
+
return channelEventName === WORKBUDDY_EVENT_PRE_TOOL_USE;
|
|
178
|
+
}
|
|
179
|
+
function neutralWithDiagnostics(stderr) {
|
|
180
|
+
return { stdout: null, exitCode: 0, stderr };
|
|
181
|
+
}
|
|
182
|
+
/** Pre-decode failures (bad JSON / decode) route per registration channel. */
|
|
183
|
+
function channelFailure(channelEventName, reason, nextAction) {
|
|
184
|
+
const line = diagnostic('degraded', reason, nextAction);
|
|
185
|
+
if (channelBlocksOnFailure(channelEventName)) {
|
|
186
|
+
// P02: exit 2 blocks the tool even with an empty stdout / closed pipe.
|
|
187
|
+
return { stdout: null, exitCode: 2, stderr: [line] };
|
|
188
|
+
}
|
|
189
|
+
// UserPromptSubmit: exit 2 would clear the user's prompt (P02) — protect it.
|
|
190
|
+
// PostToolUse/SessionStart: nothing blockable exists on those channels.
|
|
191
|
+
return neutralWithDiagnostics([line]);
|
|
192
|
+
}
|
|
193
|
+
export async function processWorkbuddyHookInvocation(rawStdin, channelEventName, _env = process.env) {
|
|
194
|
+
let parsed;
|
|
195
|
+
try {
|
|
196
|
+
parsed = JSON.parse(rawStdin);
|
|
197
|
+
}
|
|
198
|
+
catch (error) {
|
|
199
|
+
return channelFailure(channelEventName, `stdin_json_invalid:${errorMessage(error)}`, 'Verify the WorkBuddy hook passes one JSON object on stdin.');
|
|
200
|
+
}
|
|
201
|
+
const adapter = new WorkBuddyHooksHostAdapter();
|
|
202
|
+
let event;
|
|
203
|
+
try {
|
|
204
|
+
event = adapter.decodeEvent(parsed);
|
|
205
|
+
}
|
|
206
|
+
catch (error) {
|
|
207
|
+
const reason = error instanceof WorkBuddyDecoderError ? error.reason : `decode_threw:${errorMessage(error)}`;
|
|
208
|
+
const nextAction = error instanceof WorkBuddyDecoderError ? error.nextAction : 'Inspect the WorkBuddy hook payload against the Phase 0 host contract.';
|
|
209
|
+
return channelFailure(channelEventName, reason, nextAction);
|
|
210
|
+
}
|
|
211
|
+
// OD-07/P06 governance workspace: explicit, user-level, shared across
|
|
212
|
+
// projects; never auto-created here and never falling back to another host.
|
|
213
|
+
const resolution = resolveWorkbuddyWorkspace(os.homedir());
|
|
214
|
+
if (resolution.status === 'uninitialized') {
|
|
215
|
+
return neutralWithDiagnostics([diagnostic('skipped', resolution.reason, resolution.nextAction)]);
|
|
216
|
+
}
|
|
217
|
+
if (resolution.status === 'degraded') {
|
|
218
|
+
return neutralWithDiagnostics([diagnostic('degraded', resolution.reason, resolution.nextAction)]);
|
|
219
|
+
}
|
|
220
|
+
const config = loadPdConfigForPlugin(resolution.workspaceDir);
|
|
221
|
+
if (!config.ok) {
|
|
222
|
+
const [first] = config.errors;
|
|
223
|
+
return neutralWithDiagnostics([diagnostic('degraded', first?.reason ?? 'pd_config_invalid', first?.nextAction ?? 'Repair the governance workspace .pd/config.yaml.')]);
|
|
224
|
+
}
|
|
225
|
+
const { flags } = computeFeatureFlagsFromConfig(config.effective);
|
|
226
|
+
if (flags['host.workbuddy']?.enabled !== true) {
|
|
227
|
+
// OD-03: default OFF; observable skip, no dispatch, no workspace writes.
|
|
228
|
+
return neutralWithDiagnostics([diagnostic('skipped', 'host.workbuddy_disabled', 'Set features.host.workbuddy.enabled=true in the WorkBuddy governance workspace config to enable PD for WorkBuddy.')]);
|
|
229
|
+
}
|
|
230
|
+
const evidenceEnabled = flags.principle_receipt_ledger?.enabled === true;
|
|
231
|
+
// projectDir = the host cwd (payload cwd; SessionStart carries none);
|
|
232
|
+
// workspaceDir = the governance directory (OD-07). The decoder placed the
|
|
233
|
+
// payload cwd in context.workspaceDir as the pre-rewrite carrier — capture
|
|
234
|
+
// it before replacing with the governance workspace.
|
|
235
|
+
const projectDir = event.context.workspaceDir.length > 0 ? event.context.workspaceDir : undefined;
|
|
236
|
+
event = { ...event, context: { ...event.context, workspaceDir: resolution.workspaceDir } };
|
|
237
|
+
try {
|
|
238
|
+
if (event.kind === 'session_start') {
|
|
239
|
+
// SPEC §4.2: health check only — first version injects NO body, and the
|
|
240
|
+
// neutral result is an EMPTY stdout (any stdout is context-injected).
|
|
241
|
+
const health = await createProductionHostRuntime({ hostKind: 'workbuddy' }).health(resolution.workspaceDir);
|
|
242
|
+
if (!health.ok)
|
|
243
|
+
return neutralWithDiagnostics([diagnostic('degraded', health.reason ?? 'runtime_unhealthy', health.nextAction ?? 'Inspect the governance workspace runtime.')]);
|
|
244
|
+
return neutralWithDiagnostics([]);
|
|
245
|
+
}
|
|
246
|
+
const evidenceDiagnostics = [];
|
|
247
|
+
const evidenceContext = {
|
|
248
|
+
workspaceDir: resolution.workspaceDir,
|
|
249
|
+
evidenceEnabled,
|
|
250
|
+
warn: (line) => evidenceDiagnostics.push(diagnostic('degraded', line.replace(/^\[PD:Evidence\] /, 'workbuddy_evidence:'), 'Inspect workspace state.db evidence ledger; the durable raw source allows safe replay.')),
|
|
251
|
+
};
|
|
252
|
+
const stateDir = path.join(resolution.workspaceDir, '.state');
|
|
253
|
+
const result = await createProductionHostRuntime({
|
|
254
|
+
...(projectDir !== undefined ? { projectDir } : {}),
|
|
255
|
+
hostKind: 'workbuddy',
|
|
256
|
+
toolSemantics: WORKBUDDY_TOOL_SEMANTICS,
|
|
257
|
+
events: workbuddyEventEmitter(stateDir, evidenceContext),
|
|
258
|
+
// Remediation R2 (candidate-level admission): the diagnostician's
|
|
259
|
+
// candidates are admitted ONLY with input evidence (needs_evidence
|
|
260
|
+
// otherwise), and Codex-style transcript promotion does not exist on
|
|
261
|
+
// this host. OpenClaw-parity: the HOOK supplies the evidence — a
|
|
262
|
+
// sourceRef to the durable raw event line (idempotent replay source,
|
|
263
|
+
// SPEC §13.7) plus a bounded failure note. No raw tool output is copied
|
|
264
|
+
// (ADR-0027 hook-log content rule).
|
|
265
|
+
painEnrichmentProvider: (hostEvent) => {
|
|
266
|
+
if (hostEvent.kind !== 'after_tool_call')
|
|
267
|
+
return {};
|
|
268
|
+
const toolName = hostEvent.context.toolName ?? 'unknown-tool';
|
|
269
|
+
const output = hostEvent.context.toolOutput;
|
|
270
|
+
const detail = typeof output === 'object' && output !== null && !Array.isArray(output)
|
|
271
|
+
? Object.hasOwn(output, 'tool_error_code')
|
|
272
|
+
? `tool_error_code=${String(output.tool_error_code)}`
|
|
273
|
+
: Object.hasOwn(output, 'exitCode')
|
|
274
|
+
? `exitCode=${String(output.exitCode)}`
|
|
275
|
+
: 'failure'
|
|
276
|
+
: 'failure';
|
|
277
|
+
return {
|
|
278
|
+
evidence: [{
|
|
279
|
+
sourceRef: `workbuddy-pd-hook-event-log:${hostEvent.context.sessionId}`,
|
|
280
|
+
note: `${toolName} failed (${detail}); raw payload in the durable workbuddy hook event log for this session`,
|
|
281
|
+
}],
|
|
282
|
+
};
|
|
283
|
+
},
|
|
284
|
+
// PRI-780 boundary: NO context provider — v2 rules stay SUSPENDED on
|
|
285
|
+
// WorkBuddy (never loaded context-blind). See annotateContextWarnings.
|
|
286
|
+
}).dispatch(event);
|
|
287
|
+
const evaluationDiagnostics = recordRuleHostEvaluations(stateDir, event.context.sessionId, result.metadata?.evaluations);
|
|
288
|
+
// Encode BEFORE recording an attributed deny: a runtime_verified
|
|
289
|
+
// application claims only what reached the stdout channel (P02: the
|
|
290
|
+
// encoded permissionDecision is the verified blocking boundary).
|
|
291
|
+
const encodedUnknown = adapter.encodeOutput(result, event.kind);
|
|
292
|
+
if (encodedUnknown !== null && !isWorkBuddyHookOutput(encodedUnknown)) {
|
|
293
|
+
throw new WorkBuddyEncoderError('encodeOutput produced a non-whitelisted document', 'Encode only the frozen hookSpecificOutput contract.');
|
|
294
|
+
}
|
|
295
|
+
const encoded = encodedUnknown;
|
|
296
|
+
if (result.decision === 'deny') {
|
|
297
|
+
try {
|
|
298
|
+
let liveActivationId;
|
|
299
|
+
const evaluations = result.metadata?.evaluations;
|
|
300
|
+
if (Array.isArray(evaluations)) {
|
|
301
|
+
for (const entry of evaluations) {
|
|
302
|
+
if (typeof entry !== 'object' || entry === null || Array.isArray(entry))
|
|
303
|
+
continue;
|
|
304
|
+
const record = entry;
|
|
305
|
+
const activationMode = Object.hasOwn(record, 'activationMode') ? record.activationMode : undefined;
|
|
306
|
+
const activationId = Object.hasOwn(record, 'activationId') ? record.activationId : undefined;
|
|
307
|
+
if (activationMode === 'live' && typeof activationId === 'string' && activationId.length > 0) {
|
|
308
|
+
liveActivationId = activationId;
|
|
309
|
+
break;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
const { metadata } = result;
|
|
314
|
+
const principleId = typeof metadata?.principleId === 'string' ? metadata.principleId : undefined;
|
|
315
|
+
const ruleId = typeof metadata?.ruleId === 'string' ? metadata.ruleId : undefined;
|
|
316
|
+
recordWorkbuddyDenyEvidence({
|
|
317
|
+
workspaceDir: resolution.workspaceDir,
|
|
318
|
+
sessionId: event.context.sessionId,
|
|
319
|
+
...(event.context.toolCallId !== undefined ? { toolCallId: event.context.toolCallId } : {}),
|
|
320
|
+
toolName: event.context.toolName ?? 'unknown-tool',
|
|
321
|
+
activationId: liveActivationId,
|
|
322
|
+
principleId,
|
|
323
|
+
ruleId,
|
|
324
|
+
reason: result.reason,
|
|
325
|
+
evidenceEnabled,
|
|
326
|
+
warn: evidenceContext.warn,
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
catch (error) {
|
|
330
|
+
// P02: the deny was already encoded — an evidence failure must never
|
|
331
|
+
// turn it into a release.
|
|
332
|
+
evidenceDiagnostics.push(diagnostic('degraded', `workbuddy_evidence_deny_failed:${errorMessage(error)}`, 'The deny decision was already encoded; evidence replay from the durable source is safe.'));
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
const stderr = [
|
|
336
|
+
...annotateContextWarnings(result.warnings ?? []).slice(0, 16).map((warning) => diagnostic('degraded', warning, 'Inspect the PD governance workspace state and retry; the hook stayed permissive (allow+warnings is degraded health, not fail-closed).')),
|
|
337
|
+
...evaluationDiagnostics,
|
|
338
|
+
...evidenceDiagnostics,
|
|
339
|
+
];
|
|
340
|
+
return { stdout: encoded, exitCode: 0, stderr };
|
|
341
|
+
}
|
|
342
|
+
catch (error) {
|
|
343
|
+
const reason = error instanceof WorkBuddyEncoderError ? error.reason : `runtime_failed:${errorMessage(error)}`;
|
|
344
|
+
const nextAction = error instanceof WorkBuddyEncoderError ? error.nextAction : 'Inspect the PD governance workspace state and retry.';
|
|
345
|
+
if (event.kind === 'before_tool_call') {
|
|
346
|
+
// P02: exit 2 on the PreToolUse channel genuinely blocks the tool —
|
|
347
|
+
// the only honest failure posture inside the supported governance path.
|
|
348
|
+
return { stdout: null, exitCode: 2, stderr: [diagnostic('degraded', reason, `${nextAction} The tool call was blocked because PD could not verify it.`)] };
|
|
349
|
+
}
|
|
350
|
+
// UserPromptSubmit: protect the prompt (exit 2 clears it — P02).
|
|
351
|
+
// after_tool_call: the tool already ran — report evidence degradation only.
|
|
352
|
+
return neutralWithDiagnostics([diagnostic('degraded', reason, nextAction)]);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
// ─── Process-boundary belt (PRI-943 pattern, WorkBuddy exit-code semantics) ──
|
|
356
|
+
// No unrejected promise, unwritable stream, or unserializable result may reach
|
|
357
|
+
// node's default handling. Three failure modes (reproduced from spawned
|
|
358
|
+
// processes in tests/pd-hook-entry.test.ts):
|
|
359
|
+
// * a write that THROWS synchronously — caught per write below;
|
|
360
|
+
// * the host closing the pipe — an ASYNC 'error' event only a listener can
|
|
361
|
+
// contain (ERR-156);
|
|
362
|
+
// * the stdout JSON failing to SERIALIZE — per SPEC §4.4 never a silent
|
|
363
|
+
// `{} + exit 0`: an undeliverable deny becomes exit 2 (P02: exit 2 blocks
|
|
364
|
+
// even with stdout closed); every other channel keeps its exit code and
|
|
365
|
+
// degrades observably on stderr.
|
|
366
|
+
let beltReported = false;
|
|
367
|
+
/**
|
|
368
|
+
* Set once main() knows the registration channel: a STDOUT delivery failure
|
|
369
|
+
* on the PreToolUse channel means a computed deny was lost, and P02 proved
|
|
370
|
+
* exit 2 blocks the tool even with a dead stdout — so the belt escalates the
|
|
371
|
+
* exit code instead of letting the tool run unblocked.
|
|
372
|
+
*/
|
|
373
|
+
let blockingChannelArmed = false;
|
|
374
|
+
function writeBeltDiagnostic(reason, nextAction) {
|
|
375
|
+
if (beltReported)
|
|
376
|
+
return;
|
|
377
|
+
beltReported = true;
|
|
378
|
+
try {
|
|
379
|
+
process.stderr.write(`${diagnostic('degraded', reason, nextAction)}\n`);
|
|
380
|
+
}
|
|
381
|
+
catch {
|
|
382
|
+
// Both streams gone: no channel remains inside the belt's contract.
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
function reportStdoutFailure(error) {
|
|
386
|
+
writeBeltDiagnostic(`hook_stream_failed:${errorMessage(error)}`, 'The host closed the pipe; retry the hook invocation.');
|
|
387
|
+
// The deny bytes could not be delivered — the exit code is the only
|
|
388
|
+
// remaining real blocker (P02: stdout-closed exit 2 still blocks).
|
|
389
|
+
if (blockingChannelArmed && (process.exitCode ?? 0) === 0)
|
|
390
|
+
process.exitCode = 2;
|
|
391
|
+
}
|
|
392
|
+
function reportStderrFailure(error) {
|
|
393
|
+
// stderr loss never loses a decision — stdout remains the contract channel.
|
|
394
|
+
writeBeltDiagnostic(`hook_stream_failed:${errorMessage(error)}`, 'The host closed the pipe; retry the hook invocation.');
|
|
395
|
+
}
|
|
396
|
+
function writeStream(stream, line) {
|
|
397
|
+
try {
|
|
398
|
+
process[stream].write(`${line}\n`);
|
|
399
|
+
return true;
|
|
400
|
+
}
|
|
401
|
+
catch (error) {
|
|
402
|
+
if (stream === 'stdout')
|
|
403
|
+
reportStdoutFailure(error);
|
|
404
|
+
else
|
|
405
|
+
reportStderrFailure(error);
|
|
406
|
+
return false;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
function armStreamBelts() {
|
|
410
|
+
process.stdout.on('error', reportStdoutFailure);
|
|
411
|
+
process.stderr.on('error', reportStderrFailure);
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* rc-8 + SPEC §4.4: serialization failure of the stdout contract is never a
|
|
415
|
+
* silent `{} + exit 0`. Returns the serialized line, or null when nothing can
|
|
416
|
+
* be delivered — plus whether an undeliverable deny must escalate this
|
|
417
|
+
* invocation to a blocking exit 2 (PreToolUse channel only).
|
|
418
|
+
*/
|
|
419
|
+
function serializeStdout(value, channelEventName) {
|
|
420
|
+
try {
|
|
421
|
+
return { line: JSON.stringify(value), escalateToBlocking: false };
|
|
422
|
+
}
|
|
423
|
+
catch (error) {
|
|
424
|
+
writeBeltDiagnostic(`hook_stdout_serialize_failed:${errorMessage(error)}`, 'Retry the invocation; the stdout contract could not be serialized.');
|
|
425
|
+
// An undeliverable deny loses the P02-verified blocking channel — the
|
|
426
|
+
// exit code is the only remaining real blocker, so use it (PreToolUse
|
|
427
|
+
// registration channel only; a UserPromptSubmit additionalContext loss
|
|
428
|
+
// degrades without blocking so the prompt is preserved).
|
|
429
|
+
return { line: null, escalateToBlocking: channelBlocksOnFailure(channelEventName) };
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
async function main() {
|
|
433
|
+
// argv[2] is the wrapper's event argument (argv[0]=node, argv[1]=script).
|
|
434
|
+
// Double-hole destructuring — eslint's member-access fix `[, x]` would
|
|
435
|
+
// silently read argv[1] (the SCRIPT PATH) as the channel.
|
|
436
|
+
const [, , channelEventName] = process.argv;
|
|
437
|
+
blockingChannelArmed = channelBlocksOnFailure(channelEventName);
|
|
438
|
+
let raw;
|
|
439
|
+
try {
|
|
440
|
+
raw = readFileSync(0, 'utf8');
|
|
441
|
+
}
|
|
442
|
+
catch (error) {
|
|
443
|
+
writeStream('stderr', diagnostic('degraded', `stdin_read_failed:${errorMessage(error)}`, 'Run the hook from WorkBuddy with JSON stdin.'));
|
|
444
|
+
process.exitCode = 0;
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
let result;
|
|
448
|
+
try {
|
|
449
|
+
result = await processWorkbuddyHookInvocation(raw, channelEventName);
|
|
450
|
+
}
|
|
451
|
+
catch (error) {
|
|
452
|
+
// Belt for an unexpected pre-dispatch throw: the host still gets a clean
|
|
453
|
+
// neutral (empty stdout) instead of a bare crash — never stdout noise.
|
|
454
|
+
writeStream('stderr', diagnostic('degraded', `hook_pipeline_unexpected:${errorMessage(error)}`, 'Retry the hook invocation; if it repeats, inspect PD stderr and the governance workspace config.'));
|
|
455
|
+
result = { stdout: null, exitCode: 0, stderr: [] };
|
|
456
|
+
}
|
|
457
|
+
for (const line of result.stderr) {
|
|
458
|
+
if (!writeStream('stderr', line))
|
|
459
|
+
break;
|
|
460
|
+
}
|
|
461
|
+
let { exitCode } = result;
|
|
462
|
+
if (result.stdout !== null) {
|
|
463
|
+
const { line, escalateToBlocking } = serializeStdout(result.stdout, channelEventName);
|
|
464
|
+
const delivered = line !== null && writeStream('stdout', line);
|
|
465
|
+
if (escalateToBlocking && exitCode === 0)
|
|
466
|
+
exitCode = 2;
|
|
467
|
+
// A serialized deny whose bytes could not REACH stdout (sync write throw)
|
|
468
|
+
// must not degrade to exit 0: on the blocking channel the exit code is
|
|
469
|
+
// then the only real blocker left (P02: stdout-closed exit 2 blocks).
|
|
470
|
+
// The belt's reportStdoutFailure covers the ASYNC stream-error variant.
|
|
471
|
+
if (!delivered && blockingChannelArmed && exitCode === 0)
|
|
472
|
+
exitCode = 2;
|
|
473
|
+
}
|
|
474
|
+
process.exitCode = exitCode;
|
|
475
|
+
}
|
|
476
|
+
// Node resolves the main module through symlinks/junctions while argv[1]
|
|
477
|
+
// keeps the unresolved link path (npm shims, junctioned runtime dirs — the
|
|
478
|
+
// install layout junctions ~/.pd/runtime), so compare the raw URL first,
|
|
479
|
+
// then canonicalize through realpath (PRI-892 pattern).
|
|
480
|
+
function isMainModuleEntry() {
|
|
481
|
+
const [, entry] = process.argv;
|
|
482
|
+
if (!entry)
|
|
483
|
+
return false;
|
|
484
|
+
if (pathToFileURL(entry).href === import.meta.url)
|
|
485
|
+
return true;
|
|
486
|
+
try {
|
|
487
|
+
return pathToFileURL(realpathSync(entry)).href === import.meta.url;
|
|
488
|
+
}
|
|
489
|
+
catch (error) {
|
|
490
|
+
if (path.basename(entry) !== path.basename(fileURLToPath(import.meta.url)))
|
|
491
|
+
return false;
|
|
492
|
+
writeStream('stderr', diagnostic('degraded', `entry_identity_unverified:${errorMessage(error)}`, 'Reinstall the WorkBuddy adapter; if it repeats, report this line together with the command that invoked the hook.'));
|
|
493
|
+
return true;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
if (isMainModuleEntry()) {
|
|
497
|
+
armStreamBelts();
|
|
498
|
+
void main().catch((error) => {
|
|
499
|
+
writeBeltDiagnostic(`hook_fatal:${errorMessage(error)}`, 'Retry the hook invocation; if it repeats, report this line together with the command that invoked the hook.');
|
|
500
|
+
// The WorkBuddy neutral is EMPTY stdout — nothing to write here; the
|
|
501
|
+
// process must terminate with a real exit code on every path.
|
|
502
|
+
if (process.exitCode === undefined)
|
|
503
|
+
process.exitCode = 0;
|
|
504
|
+
});
|
|
505
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WorkBuddy Tool Semantic Declaration (SPEC §4.5, ADR-0020 third host).
|
|
3
|
+
*
|
|
4
|
+
* PURPOSE: the WorkBuddy host layer of the Tool Semantic Registry
|
|
5
|
+
* (PRI-634-F pattern, mirroring codex-adapter's declaration). WorkBuddy
|
|
6
|
+
* names its tools with a capitalized vocabulary the core baseline never
|
|
7
|
+
* matches — a rule generated against `write` would pass replay and never
|
|
8
|
+
* fire on a real `Write` event.
|
|
9
|
+
*
|
|
10
|
+
* EVIDENCE BOUND: only names with in-repo evidence are declared —
|
|
11
|
+
* Read/Write/Bash appear as real tool names in the frozen Phase 0 fixtures
|
|
12
|
+
* (tests/fixtures/host-contract/events/*.json, probes P03); Glob/Grep/Edit
|
|
13
|
+
* are documented core tools in the official hooks reference snapshot
|
|
14
|
+
* (docs/plans/2026-10-12-workbuddy-official-hooks-reference.md §PreToolUse
|
|
15
|
+
* common matchers). Extending beyond this surface is a follow-up once real
|
|
16
|
+
* sessions sample more names — a wrong guess is worse than a gap (unknown
|
|
17
|
+
* names resolve to 'other' and are never fabricated into Write/Bash
|
|
18
|
+
* equivalences).
|
|
19
|
+
*/
|
|
20
|
+
import { type ToolSemanticMappingV1, type ToolSemanticRegistry } from '@principles/core/runtime-v2';
|
|
21
|
+
export declare const WORKBUDDY_TOOL_SEMANTIC_MAPPINGS: readonly ToolSemanticMappingV1[];
|
|
22
|
+
export declare const WORKBUDDY_TOOL_SEMANTICS: ToolSemanticRegistry;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WorkBuddy Tool Semantic Declaration (SPEC §4.5, ADR-0020 third host).
|
|
3
|
+
*
|
|
4
|
+
* PURPOSE: the WorkBuddy host layer of the Tool Semantic Registry
|
|
5
|
+
* (PRI-634-F pattern, mirroring codex-adapter's declaration). WorkBuddy
|
|
6
|
+
* names its tools with a capitalized vocabulary the core baseline never
|
|
7
|
+
* matches — a rule generated against `write` would pass replay and never
|
|
8
|
+
* fire on a real `Write` event.
|
|
9
|
+
*
|
|
10
|
+
* EVIDENCE BOUND: only names with in-repo evidence are declared —
|
|
11
|
+
* Read/Write/Bash appear as real tool names in the frozen Phase 0 fixtures
|
|
12
|
+
* (tests/fixtures/host-contract/events/*.json, probes P03); Glob/Grep/Edit
|
|
13
|
+
* are documented core tools in the official hooks reference snapshot
|
|
14
|
+
* (docs/plans/2026-10-12-workbuddy-official-hooks-reference.md §PreToolUse
|
|
15
|
+
* common matchers). Extending beyond this surface is a follow-up once real
|
|
16
|
+
* sessions sample more names — a wrong guess is worse than a gap (unknown
|
|
17
|
+
* names resolve to 'other' and are never fabricated into Write/Bash
|
|
18
|
+
* equivalences).
|
|
19
|
+
*/
|
|
20
|
+
import { buildToolSemanticRegistry } from '@principles/core/runtime-v2';
|
|
21
|
+
export const WORKBUDDY_TOOL_SEMANTIC_MAPPINGS = Object.freeze([
|
|
22
|
+
{ rawToolName: 'Read', canonicalKind: 'read' },
|
|
23
|
+
{ rawToolName: 'Glob', canonicalKind: 'search' },
|
|
24
|
+
{ rawToolName: 'Grep', canonicalKind: 'search' },
|
|
25
|
+
{ rawToolName: 'Write', canonicalKind: 'write' },
|
|
26
|
+
{ rawToolName: 'Edit', canonicalKind: 'write' },
|
|
27
|
+
{ rawToolName: 'Bash', canonicalKind: 'execute' },
|
|
28
|
+
]);
|
|
29
|
+
const built = buildToolSemanticRegistry(WORKBUDDY_TOOL_SEMANTIC_MAPPINGS);
|
|
30
|
+
if (!built.ok) {
|
|
31
|
+
throw new Error(`[PD] WorkBuddy tool semantic declaration is invalid: ${built.errors.join('; ')}`);
|
|
32
|
+
}
|
|
33
|
+
export const WORKBUDDY_TOOL_SEMANTICS = built.registry;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { InterventionCapabilityDeclaration } from '@principles/core/runtime-v2';
|
|
2
|
+
/** Evidence adapter surface version (matches the frozen core contract test expectations). */
|
|
3
|
+
export declare const WORKBUDDY_EVIDENCE_ADAPTER_VERSION = "workbuddy-adapter@0.1.0";
|
|
4
|
+
export type EvidenceWarn = (diagnosticLine: string) => void;
|
|
5
|
+
export declare function workbuddyCapabilityDeclarations(): InterventionCapabilityDeclaration[];
|
|
6
|
+
export interface WorkbuddyPromptDeliveryEvidenceInput {
|
|
7
|
+
workspaceDir: string;
|
|
8
|
+
sessionId: string;
|
|
9
|
+
/** WorkBuddy generation_id as carried by the injected-event runId (optional). */
|
|
10
|
+
turnId?: string;
|
|
11
|
+
/** Index-aligned per-principle injection facts from the injected event. */
|
|
12
|
+
injected: readonly {
|
|
13
|
+
principleId: string;
|
|
14
|
+
activationId: string;
|
|
15
|
+
artifactId?: string;
|
|
16
|
+
}[];
|
|
17
|
+
evidenceEnabled: boolean;
|
|
18
|
+
warn: EvidenceWarn;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Record one agent-context delivery attempt per injected principle after the
|
|
22
|
+
* raw injected-event line has been appended to the durable WorkBuddy event
|
|
23
|
+
* log — confirmation 'submitted', outcome 'attempted' (submitted ≠ delivered,
|
|
24
|
+
* SPEC §4.6).
|
|
25
|
+
*/
|
|
26
|
+
export declare function recordWorkbuddyPromptDeliveryEvidence(input: WorkbuddyPromptDeliveryEvidenceInput): void;
|
|
27
|
+
export interface WorkbuddyDenyEvidenceInput {
|
|
28
|
+
workspaceDir: string;
|
|
29
|
+
sessionId?: string;
|
|
30
|
+
toolCallId?: string;
|
|
31
|
+
toolName: string;
|
|
32
|
+
activationId?: string;
|
|
33
|
+
principleId?: string;
|
|
34
|
+
ruleId?: string;
|
|
35
|
+
reason?: string;
|
|
36
|
+
evidenceEnabled: boolean;
|
|
37
|
+
warn: EvidenceWarn;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Record the enforcement chain for an ATTRIBUTED deny that was successfully
|
|
41
|
+
* encoded to the WorkBuddy stdout channel. The proof boundary is the encoded
|
|
42
|
+
* permissionDecision (probe P02 verified the host honors it by blocking the
|
|
43
|
+
* tool) — PD claims exactly that, nothing broader.
|
|
44
|
+
*
|
|
45
|
+
* Episode identity requires the per-call toolCallId (WorkBuddy call_id).
|
|
46
|
+
* Without it the chain is skipped: a hash fallback would mint an episode
|
|
47
|
+
* with NO native event key, which the normalizer rejects and drops the
|
|
48
|
+
* whole batch.
|
|
49
|
+
*/
|
|
50
|
+
export declare function recordWorkbuddyDenyEvidence(input: WorkbuddyDenyEvidenceInput): void;
|