create-principles-disciple 1.144.26 → 1.145.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/_release/product-identity.json +2 -2
- package/codex-adapter/dist/codex-evidence-recorder.js +8 -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 +2 -2
- 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 +4 -4
- 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/adversarial-feedback.d.ts +3 -1
- package/core/dist/runtime-v2/internalization/adversarial-feedback.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/adversarial-feedback.js +10 -1
- package/core/dist/runtime-v2/internalization/adversarial-feedback.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 +3 -3
- 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 +3 -3
- package/install-layout/dist/index.d.ts +18 -1
- package/install-layout/dist/index.js +15 -2
- package/install-layout/package.json +1 -1
- package/package.json +6 -5
- 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 +4 -3
- 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 +3 -3
- 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 +5 -4
- 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 +62 -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
|
@@ -85,6 +85,37 @@ async function safeRunRecoverySweep(stateManager, ports) {
|
|
|
85
85
|
* - P1: 任何 reconcile_error 显式留痕 (不依赖 recovered>0)。
|
|
86
86
|
*/
|
|
87
87
|
const RECONCILIATION_BUDGET = 5;
|
|
88
|
+
/**
|
|
89
|
+
* PRI-954 (F10) oldest-ready-stage-first ordering. Returns the configured
|
|
90
|
+
* runner kinds reordered to start at the stage that owns the globally oldest
|
|
91
|
+
* ready task (by `createdAt`); later stages keep their relative priority
|
|
92
|
+
* order, so dependency order inside one stage scan is untouched. Tasks
|
|
93
|
+
* without a readable createdAt sort last for ordering purposes (their stage
|
|
94
|
+
* keeps the default position) — unknown age never jumps the queue.
|
|
95
|
+
*/
|
|
96
|
+
export function orderKindsByOldestReadyStage(runnerKinds, readyTasks) {
|
|
97
|
+
if (runnerKinds.length <= 1 || readyTasks.length === 0)
|
|
98
|
+
return [...runnerKinds];
|
|
99
|
+
const priorityIndex = new Map(runnerKinds.map((k, i) => [k, i]));
|
|
100
|
+
let oldest = null;
|
|
101
|
+
for (const task of readyTasks) {
|
|
102
|
+
if (typeof task.createdAt !== 'string' || task.createdAt.length === 0)
|
|
103
|
+
continue;
|
|
104
|
+
const index = priorityIndex.get(task.taskKind);
|
|
105
|
+
if (index === undefined)
|
|
106
|
+
continue; // stage outside this consumer's scope
|
|
107
|
+
if (oldest === null ||
|
|
108
|
+
task.createdAt < oldest.createdAt ||
|
|
109
|
+
(task.createdAt === oldest.createdAt && index < oldest.index)) {
|
|
110
|
+
oldest = { taskKind: task.taskKind, createdAt: task.createdAt, index };
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
const startKind = oldest?.taskKind;
|
|
114
|
+
const startIndex = startKind !== undefined ? runnerKinds.indexOf(startKind) : -1;
|
|
115
|
+
if (startIndex <= 0)
|
|
116
|
+
return [...runnerKinds];
|
|
117
|
+
return [...runnerKinds.slice(startIndex), ...runnerKinds.slice(0, startIndex)];
|
|
118
|
+
}
|
|
88
119
|
async function runReconciliationBudget(workspaceDir, orchestrator, ports) {
|
|
89
120
|
const { logger, emitEvent, logLabel } = ports;
|
|
90
121
|
try {
|
|
@@ -254,7 +285,18 @@ export async function runInternalizationConsumerCycle(workspaceDir, ports) {
|
|
|
254
285
|
let lastSkipDecision = 'no_ready_tasks';
|
|
255
286
|
let lastSkipReason;
|
|
256
287
|
let taskRuntimeConfig = null;
|
|
257
|
-
|
|
288
|
+
// PRI-954 (F10): oldest-ready-stage-first fairness. The fixed dreamer-first
|
|
289
|
+
// order plus one-task-per-cycle let a continuous stream of new dreamer
|
|
290
|
+
// tasks (each real Pain creates one) keep downstream stages waiting for an
|
|
291
|
+
// unbounded number of cycles — measured at 35+ minutes of philosopher
|
|
292
|
+
// starvation under sustained load (2026-10-13 dogfood, findings F10).
|
|
293
|
+
// Starting the stage scan at the stage owning the GLOBALLY OLDEST ready
|
|
294
|
+
// task bounds every stage's wait without concurrency, without persisted
|
|
295
|
+
// scheduler state (works across one-shot `--once` worker processes), and
|
|
296
|
+
// without touching leases, idempotency, dependency order, or the
|
|
297
|
+
// single-task-per-cycle semantics. Ties keep the original priority order.
|
|
298
|
+
const orderedRunnerKinds = orderKindsByOldestReadyStage(decision.runnerKinds, snapshot.readyTasks);
|
|
299
|
+
for (const kind of orderedRunnerKinds) {
|
|
258
300
|
const agentName = AGENT_NAME_FOR_TASK_KIND[kind];
|
|
259
301
|
if (agentName === undefined) {
|
|
260
302
|
lastSkipDecision = 'runtime_config_error';
|
|
@@ -8,7 +8,7 @@ export interface InterventionIngressAppendResult {
|
|
|
8
8
|
nextAction?: string;
|
|
9
9
|
}
|
|
10
10
|
export interface ExistingInterventionObservationSource {
|
|
11
|
-
sourceKind: 'openclaw_plugin_event_log' | 'codex_pd_hook_event_log';
|
|
11
|
+
sourceKind: 'openclaw_plugin_event_log' | 'codex_pd_hook_event_log' | 'workbuddy_pd_hook_event_log';
|
|
12
12
|
sourceLocator: string;
|
|
13
13
|
observationKey: string;
|
|
14
14
|
principleId: string;
|
|
@@ -193,7 +193,7 @@ function resolveInstallContext(homeDir) {
|
|
|
193
193
|
const legacyExtensionExists = fs.existsSync(paths.openClawExtensionDir);
|
|
194
194
|
const layout = resolveInstallLayout({ homeDir, manifest, canonicalRuntimeExists, legacyExtensionExists });
|
|
195
195
|
let hostKind = 'other';
|
|
196
|
-
if (manifest && manifest.hosts.length === 1 && (manifest.hosts[0] === 'codex' || manifest.hosts[0] === 'openclaw')) {
|
|
196
|
+
if (manifest && manifest.hosts.length === 1 && (manifest.hosts[0] === 'codex' || manifest.hosts[0] === 'openclaw' || manifest.hosts[0] === 'workbuddy')) {
|
|
197
197
|
[hostKind] = manifest.hosts;
|
|
198
198
|
}
|
|
199
199
|
else if (legacyExtensionExists) {
|
|
@@ -19,9 +19,14 @@ export interface ProductionPainEnrichment {
|
|
|
19
19
|
}
|
|
20
20
|
export type PainEnrichmentProvider = (event: HostEvent) => unknown | Promise<unknown>;
|
|
21
21
|
export type PainDatabaseFactory = (databasePath: string) => Database.Database;
|
|
22
|
+
/** SPEC-CODEX-PAIN-CLOSURE-001 CR-01: a tool result is success, failure or unknown. */
|
|
23
|
+
export type ToolOutcomeClassification = 'success' | 'failure' | 'unknown';
|
|
22
24
|
interface NormalizedOutcome {
|
|
25
|
+
outcome: ToolOutcomeClassification;
|
|
23
26
|
failure: boolean;
|
|
24
|
-
exitCode: number;
|
|
27
|
+
exitCode: number | null;
|
|
28
|
+
/** Bounded structured reason present when the outcome is unknown (rc-9). */
|
|
29
|
+
unknownReason?: string;
|
|
25
30
|
error?: string;
|
|
26
31
|
durationMs?: number;
|
|
27
32
|
params: unknown;
|
|
@@ -32,6 +37,16 @@ export interface ProductionToolEventFields {
|
|
|
32
37
|
workspaceDir: string;
|
|
33
38
|
sessionId: string;
|
|
34
39
|
turnId?: string;
|
|
40
|
+
/**
|
|
41
|
+
* I1: the host's real per-call identity (Codex `tool_use_id`, WorkBuddy
|
|
42
|
+
* `call_id`). Two calls with the same session/generation/tool/params/result
|
|
43
|
+
* but DIFFERENT call ids are two real occurrences and must derive two
|
|
44
|
+
* identities; a redelivery of the SAME call id is one occurrence. Optional:
|
|
45
|
+
* hosts that supply no call id keep the historical content-derived identity
|
|
46
|
+
* (identical-content calls then cannot be distinguished — a documented
|
|
47
|
+
* limitation, never fabricated precision).
|
|
48
|
+
*/
|
|
49
|
+
toolCallId?: string;
|
|
35
50
|
toolName?: string;
|
|
36
51
|
toolInput?: unknown;
|
|
37
52
|
toolOutput?: unknown;
|
|
@@ -51,6 +66,11 @@ export interface DerivedToolPainIdentity {
|
|
|
51
66
|
* fields fed to the live production handler derive the same deterministic
|
|
52
67
|
* `pain_host_<sha256>` id, so live and observation-delivered admissions of one
|
|
53
68
|
* tool call converge on one canonical pain.
|
|
69
|
+
*
|
|
70
|
+
* I1 parity obligation: when the host supplies a call id, BOTH paths must pass
|
|
71
|
+
* the same `toolCallId` (Codex admission candidates carry it from the same
|
|
72
|
+
* `tool_use_id` the live decoder required) — otherwise one real call would
|
|
73
|
+
* derive two canonical pains.
|
|
54
74
|
*/
|
|
55
75
|
export declare function deriveProductionToolPainIdentity(fields: ProductionToolEventFields & {
|
|
56
76
|
canonicalEventId?: string;
|
|
@@ -76,6 +96,44 @@ export declare function deriveProductionCorrectionPainIdentity(fields: {
|
|
|
76
96
|
painId: string;
|
|
77
97
|
};
|
|
78
98
|
declare function hasCanonicalSchema(db: Database.Database): boolean;
|
|
99
|
+
/** One host-verified tool outcome (SPEC-CODEX-PAIN-CLOSURE-001 CR-01). */
|
|
100
|
+
export interface VerifiedToolOutcomeInput {
|
|
101
|
+
/** Host tool-call id — the join key written by the live PostToolUse path. */
|
|
102
|
+
readonly toolUseId: string;
|
|
103
|
+
readonly toolName: string;
|
|
104
|
+
readonly params?: unknown;
|
|
105
|
+
/** Verified process exit code from the host's authoritative tool-fact record. */
|
|
106
|
+
readonly exitCode: number;
|
|
107
|
+
readonly outputPreview?: string;
|
|
108
|
+
}
|
|
109
|
+
export type VerifiedToolOutcomeStatus = {
|
|
110
|
+
status: 'updated';
|
|
111
|
+
id: number;
|
|
112
|
+
} | {
|
|
113
|
+
status: 'inserted';
|
|
114
|
+
id: number;
|
|
115
|
+
} | {
|
|
116
|
+
status: 'skipped_final';
|
|
117
|
+
id: number;
|
|
118
|
+
reason: 'outcome_already_final';
|
|
119
|
+
} | {
|
|
120
|
+
status: 'unavailable';
|
|
121
|
+
reason: 'trajectory_db_not_found' | 'trajectory_write_failed' | `trajectory_write_failed:${string}`;
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* SPEC-CODEX-PAIN-CLOSURE-001 CR-01: upgrade the live-hook observation of a
|
|
125
|
+
* tool call with the host-verified final result (exit code) read through the
|
|
126
|
+
* existing authorized transcript-facts path. Only rows still recorded as
|
|
127
|
+
* `unknown` (text-only live response) are upgraded — a structured live fact
|
|
128
|
+
* is never overwritten. Missing live rows are inserted so the verified fact
|
|
129
|
+
* is durable even when the live hook never fired.
|
|
130
|
+
*/
|
|
131
|
+
export declare function recordVerifiedToolOutcomes(args: {
|
|
132
|
+
workspaceDir: string;
|
|
133
|
+
sessionId: string;
|
|
134
|
+
outcomes: readonly VerifiedToolOutcomeInput[];
|
|
135
|
+
painDatabaseFactory?: PainDatabaseFactory;
|
|
136
|
+
}): VerifiedToolOutcomeStatus[];
|
|
79
137
|
/**
|
|
80
138
|
* PRI-640: host attribution is supplied by the host adapter that constructs
|
|
81
139
|
* this shared handler (OpenClaw / Codex adapters) — never guessed inside the
|
|
@@ -2,7 +2,7 @@ import { createHash } from 'node:crypto';
|
|
|
2
2
|
import fs from 'node:fs';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import Database from 'better-sqlite3';
|
|
5
|
-
import { buildToolFailureObservation, evaluateTriage, evaluateTriggerController, resolveSourceKind, sanitizeToolParams, sanitizeValue, } from '@principles/core/runtime-v2';
|
|
5
|
+
import { applyTrajectorySchemaBase, buildToolFailureObservation, evaluateTriage, evaluateTriggerController, resolveSourceKind, sanitizeToolParams, sanitizeValue, } from '@principles/core/runtime-v2';
|
|
6
6
|
const WRITE_TOOLS = new Set(['write', 'edit', 'apply_patch', 'write_file', 'edit_file', 'replace']);
|
|
7
7
|
/** Shared with the governance admission path so both gate tool failures identically. */
|
|
8
8
|
export const PRODUCTION_WRITE_TOOLS = WRITE_TOOLS;
|
|
@@ -17,19 +17,62 @@ function field(value, key) {
|
|
|
17
17
|
return undefined;
|
|
18
18
|
return Object.getOwnPropertyDescriptor(value, key)?.value;
|
|
19
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* SPEC-CODEX-PAIN-CLOSURE-001 CR-01 (PRI-960): classify a tool result as
|
|
22
|
+
* success / failure / unknown from structured facts only — a missing exit
|
|
23
|
+
* code must never become a fabricated 0, and text-only responses must never
|
|
24
|
+
* be guessed into success or failure by keyword scanning.
|
|
25
|
+
*
|
|
26
|
+
* Verified Codex facts (codex-rs core/src/tools/context.rs): PostToolUse
|
|
27
|
+
* `tool_response` for the shell tool is a plain string (the truncated output
|
|
28
|
+
* text); the exit code is only published to the transcript CommandExecution
|
|
29
|
+
* record. Plain-text responses therefore classify as unknown here and are
|
|
30
|
+
* upgraded later by the consent-gated transcript path (recordVerifiedToolOutcomes).
|
|
31
|
+
*
|
|
32
|
+
* Structured read tools (object/array results without an error field) are a
|
|
33
|
+
* legitimate completion of the tool contract and stay success (SPEC §5.1).
|
|
34
|
+
*/
|
|
20
35
|
function normalizeOutcome(event) {
|
|
21
36
|
const context = 'context' in event ? event.context : event;
|
|
22
37
|
const envelope = context.toolOutput;
|
|
23
38
|
const result = field(envelope, 'result') ?? envelope;
|
|
24
|
-
const errorValue = field(envelope, 'error');
|
|
25
|
-
const resultExit = field(result, 'exitCode');
|
|
26
|
-
const detailsExit = field(field(result, 'details'), 'exitCode');
|
|
27
|
-
const exitCode = typeof resultExit === 'number' ? resultExit : typeof detailsExit === 'number' ? detailsExit : 0;
|
|
39
|
+
const errorValue = field(envelope, 'error') ?? field(result, 'error');
|
|
28
40
|
const error = errorValue === undefined || errorValue === null || errorValue === '' ? undefined : String(errorValue);
|
|
41
|
+
// Exit-code candidates: camelCase AND snake_case at the envelope, result,
|
|
42
|
+
// details and metadata levels (Codex transcript facts arrive snake_case).
|
|
43
|
+
const exitCandidates = [
|
|
44
|
+
field(envelope, 'exitCode'), field(envelope, 'exit_code'),
|
|
45
|
+
field(result, 'exitCode'), field(result, 'exit_code'),
|
|
46
|
+
field(field(result, 'details'), 'exitCode'), field(field(result, 'details'), 'exit_code'),
|
|
47
|
+
field(field(result, 'metadata'), 'exitCode'), field(field(result, 'metadata'), 'exit_code'),
|
|
48
|
+
];
|
|
49
|
+
const exitCandidate = exitCandidates.find((value) => typeof value === 'number' && Number.isInteger(value));
|
|
50
|
+
const exitCode = typeof exitCandidate === 'number' ? exitCandidate : null;
|
|
29
51
|
const durationValue = field(envelope, 'durationMs');
|
|
52
|
+
let outcome;
|
|
53
|
+
let unknownReason;
|
|
54
|
+
if (error !== undefined) {
|
|
55
|
+
outcome = 'failure';
|
|
56
|
+
}
|
|
57
|
+
else if (exitCode !== null) {
|
|
58
|
+
outcome = exitCode === 0 ? 'success' : 'failure';
|
|
59
|
+
}
|
|
60
|
+
else if (typeof envelope === 'string' || typeof result === 'string') {
|
|
61
|
+
outcome = 'unknown';
|
|
62
|
+
unknownReason = 'text_only_response';
|
|
63
|
+
}
|
|
64
|
+
else if (isRecord(envelope) || Array.isArray(envelope)) {
|
|
65
|
+
outcome = 'success';
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
outcome = 'unknown';
|
|
69
|
+
unknownReason = 'unconfirmed_result_shape';
|
|
70
|
+
}
|
|
30
71
|
return {
|
|
31
|
-
|
|
72
|
+
outcome,
|
|
73
|
+
failure: outcome === 'failure',
|
|
32
74
|
exitCode,
|
|
75
|
+
...(unknownReason !== undefined ? { unknownReason } : {}),
|
|
33
76
|
...(error ? { error: error.slice(0, MAX_PREVIEW) } : {}),
|
|
34
77
|
...(typeof durationValue === 'number' && Number.isFinite(durationValue) && durationValue >= 0 ? { durationMs: durationValue } : {}),
|
|
35
78
|
params: context.toolInput ?? {},
|
|
@@ -104,6 +147,9 @@ function preview(value) {
|
|
|
104
147
|
}
|
|
105
148
|
function ids(input) {
|
|
106
149
|
const { outcome, sanitizedParams, canonicalEventId } = input;
|
|
150
|
+
// The toolCallId key is included ONLY when the host supplied one, so the
|
|
151
|
+
// canonical string of a no-call-id host is byte-identical to the historical
|
|
152
|
+
// derivation (persisted rows stay replay-stable across the upgrade).
|
|
107
153
|
const canonical = stable({
|
|
108
154
|
workspaceDir: path.resolve(input.workspaceDir),
|
|
109
155
|
sessionId: input.sessionId,
|
|
@@ -111,6 +157,7 @@ function ids(input) {
|
|
|
111
157
|
toolName: input.toolName,
|
|
112
158
|
source: input.source,
|
|
113
159
|
suppliedEventId: canonicalEventId ?? null,
|
|
160
|
+
...(input.toolCallId !== undefined ? { toolCallId: input.toolCallId } : {}),
|
|
114
161
|
params: sanitizedParams,
|
|
115
162
|
result: sanitizeValue(outcome.result, 0, input.workspaceDir),
|
|
116
163
|
error: outcome.error ?? null,
|
|
@@ -126,6 +173,11 @@ function ids(input) {
|
|
|
126
173
|
* fields fed to the live production handler derive the same deterministic
|
|
127
174
|
* `pain_host_<sha256>` id, so live and observation-delivered admissions of one
|
|
128
175
|
* tool call converge on one canonical pain.
|
|
176
|
+
*
|
|
177
|
+
* I1 parity obligation: when the host supplies a call id, BOTH paths must pass
|
|
178
|
+
* the same `toolCallId` (Codex admission candidates carry it from the same
|
|
179
|
+
* `tool_use_id` the live decoder required) — otherwise one real call would
|
|
180
|
+
* derive two canonical pains.
|
|
129
181
|
*/
|
|
130
182
|
export function deriveProductionToolPainIdentity(fields) {
|
|
131
183
|
const outcome = normalizeOutcome(fields);
|
|
@@ -137,6 +189,7 @@ export function deriveProductionToolPainIdentity(fields) {
|
|
|
137
189
|
...(fields.toolName !== undefined ? { toolName: fields.toolName } : {}),
|
|
138
190
|
source: fields.source,
|
|
139
191
|
...(fields.canonicalEventId !== undefined ? { canonicalEventId: fields.canonicalEventId } : {}),
|
|
192
|
+
...(fields.toolCallId !== undefined ? { toolCallId: fields.toolCallId } : {}),
|
|
140
193
|
outcome,
|
|
141
194
|
sanitizedParams,
|
|
142
195
|
});
|
|
@@ -220,13 +273,107 @@ function hasCanonicalSchema(db) {
|
|
|
220
273
|
return false;
|
|
221
274
|
// Preparing the exact production statements proves syntax/column readiness
|
|
222
275
|
// without executing mutation or invoking host enrichment side effects.
|
|
276
|
+
db.prepare('SELECT 1 FROM tool_calls WHERE session_id = ? AND tool_use_id = ?');
|
|
223
277
|
db.prepare('SELECT 1 FROM tool_calls WHERE session_id = ? AND tool_name = ? AND params_json = ? AND outcome = ? AND exit_code IS ? AND error_message IS ? AND result_preview IS ?');
|
|
224
278
|
db.prepare('SELECT 1 FROM pain_events WHERE canonical_pain_id = ?');
|
|
225
279
|
db.prepare('INSERT INTO sessions (session_id, started_at, updated_at) VALUES (?, ?, ?) ON CONFLICT(session_id) DO UPDATE SET updated_at = excluded.updated_at');
|
|
226
|
-
db.prepare('INSERT INTO tool_calls (session_id, tool_name, outcome, duration_ms, exit_code, error_type, error_message, gfi_before, gfi_after, params_json, result_preview, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
|
280
|
+
db.prepare('INSERT INTO tool_calls (session_id, tool_name, outcome, duration_ms, exit_code, error_type, error_message, gfi_before, gfi_after, params_json, result_preview, created_at, tool_use_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
|
227
281
|
db.prepare('INSERT INTO pain_events (session_id, source, score, reason, severity, origin, confidence, text, canonical_pain_id, runtime_task_id, host_kind, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
|
228
282
|
return true;
|
|
229
283
|
}
|
|
284
|
+
/**
|
|
285
|
+
* SPEC-CODEX-PAIN-CLOSURE-001 CR-01: additive migration for the host
|
|
286
|
+
* tool-call id join column. The schema-owning modules (trajectory-schema.ts
|
|
287
|
+
* applyTrajectorySchemaBase) add it for every fresh/managed open; this local
|
|
288
|
+
* ensure covers the raw production-handler open, which historically opens
|
|
289
|
+
* trajectory.db without running the schema apply.
|
|
290
|
+
*/
|
|
291
|
+
function ensureToolCallsToolUseIdColumn(db) {
|
|
292
|
+
const columns = db.prepare('PRAGMA table_info(tool_calls)').all();
|
|
293
|
+
if (columns.some((row) => pragmaField(row, 'name') === 'tool_use_id'))
|
|
294
|
+
return;
|
|
295
|
+
try {
|
|
296
|
+
db.exec('ALTER TABLE tool_calls ADD COLUMN tool_use_id TEXT');
|
|
297
|
+
db.exec('CREATE INDEX IF NOT EXISTS idx_tool_calls_session_tool_use_id ON tool_calls(session_id, tool_use_id)');
|
|
298
|
+
}
|
|
299
|
+
catch {
|
|
300
|
+
// A concurrent writer may have added it between the check and the ALTER;
|
|
301
|
+
// the prepared-statement readiness check below fails loud if it is truly absent.
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* SPEC-CODEX-PAIN-CLOSURE-001 CR-01: upgrade the live-hook observation of a
|
|
306
|
+
* tool call with the host-verified final result (exit code) read through the
|
|
307
|
+
* existing authorized transcript-facts path. Only rows still recorded as
|
|
308
|
+
* `unknown` (text-only live response) are upgraded — a structured live fact
|
|
309
|
+
* is never overwritten. Missing live rows are inserted so the verified fact
|
|
310
|
+
* is durable even when the live hook never fired.
|
|
311
|
+
*/
|
|
312
|
+
export function recordVerifiedToolOutcomes(args) {
|
|
313
|
+
const results = [];
|
|
314
|
+
if (args.outcomes.length === 0)
|
|
315
|
+
return results;
|
|
316
|
+
const dbPath = path.join(args.workspaceDir, '.state', 'trajectory.db');
|
|
317
|
+
if (!fs.existsSync(dbPath)) {
|
|
318
|
+
return args.outcomes.map(() => ({ status: 'unavailable', reason: 'trajectory_db_not_found' }));
|
|
319
|
+
}
|
|
320
|
+
let db;
|
|
321
|
+
try {
|
|
322
|
+
db = args.painDatabaseFactory ? args.painDatabaseFactory(dbPath) : new Database(dbPath);
|
|
323
|
+
db.pragma('busy_timeout = 5000');
|
|
324
|
+
// Workspaces whose trajectory.db only ever carried the governance tables
|
|
325
|
+
// (no live PostToolUse writer ran yet) lack tool_calls: apply the one
|
|
326
|
+
// canonical base schema before upgrading (idempotent, DDL authority stays
|
|
327
|
+
// with core's trajectory-schema).
|
|
328
|
+
const hasToolCalls = (db.prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'tool_calls'").get() !== undefined);
|
|
329
|
+
if (!hasToolCalls)
|
|
330
|
+
applyTrajectorySchemaBase(db);
|
|
331
|
+
ensureToolCallsToolUseIdColumn(db);
|
|
332
|
+
const findByToolUseId = db.prepare('SELECT id, outcome FROM tool_calls WHERE session_id = ? AND tool_use_id = ? ORDER BY id LIMIT 1');
|
|
333
|
+
const upgradeUnknown = db.prepare("UPDATE tool_calls SET outcome = ?, exit_code = ?, result_preview = COALESCE(?, result_preview) WHERE id = ? AND outcome = 'unknown'");
|
|
334
|
+
const insertVerified = db.prepare('INSERT INTO tool_calls (session_id, tool_name, outcome, duration_ms, exit_code, error_type, error_message, gfi_before, gfi_after, params_json, result_preview, created_at, tool_use_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
|
335
|
+
const upsertSession = db.prepare('INSERT INTO sessions (session_id, started_at, updated_at) VALUES (?, ?, ?) ON CONFLICT(session_id) DO UPDATE SET updated_at = excluded.updated_at');
|
|
336
|
+
const createdAt = new Date().toISOString();
|
|
337
|
+
db.transaction(() => {
|
|
338
|
+
for (const input of args.outcomes) {
|
|
339
|
+
if (typeof input.exitCode !== 'number' || !Number.isInteger(input.exitCode))
|
|
340
|
+
continue;
|
|
341
|
+
const finalOutcome = input.exitCode === 0 ? 'success' : 'failure';
|
|
342
|
+
const existing = findByToolUseId.get(args.sessionId, input.toolUseId);
|
|
343
|
+
const boundedPreview = typeof input.outputPreview === 'string' && input.outputPreview.length > 0
|
|
344
|
+
? input.outputPreview.slice(0, MAX_PREVIEW)
|
|
345
|
+
: null;
|
|
346
|
+
if (existing !== undefined) {
|
|
347
|
+
if (existing.outcome === 'unknown') {
|
|
348
|
+
upgradeUnknown.run(finalOutcome, input.exitCode, boundedPreview, existing.id);
|
|
349
|
+
results.push({ status: 'updated', id: existing.id });
|
|
350
|
+
}
|
|
351
|
+
else {
|
|
352
|
+
results.push({ status: 'skipped_final', id: existing.id, reason: 'outcome_already_final' });
|
|
353
|
+
}
|
|
354
|
+
continue;
|
|
355
|
+
}
|
|
356
|
+
upsertSession.run(args.sessionId, createdAt, createdAt);
|
|
357
|
+
const sanitizedParams = sanitizeToolParams(input.params ?? {}, args.workspaceDir);
|
|
358
|
+
const info = insertVerified.run(args.sessionId, input.toolName, finalOutcome, null, input.exitCode, null, null, null, null, stable(sanitizedParams), boundedPreview, createdAt, input.toolUseId);
|
|
359
|
+
results.push({ status: 'inserted', id: Number(info.lastInsertRowid) });
|
|
360
|
+
}
|
|
361
|
+
})();
|
|
362
|
+
}
|
|
363
|
+
catch (error) {
|
|
364
|
+
const reason = `trajectory_write_failed:${error instanceof Error ? error.message.slice(0, 200) : String(error).slice(0, 200)}`;
|
|
365
|
+
const filled = results.length;
|
|
366
|
+
for (let i = filled; i < args.outcomes.length; i += 1)
|
|
367
|
+
results.push({ status: 'unavailable', reason });
|
|
368
|
+
}
|
|
369
|
+
finally {
|
|
370
|
+
try {
|
|
371
|
+
db?.close();
|
|
372
|
+
}
|
|
373
|
+
catch { /* write result already determined; cleanup is best-effort */ }
|
|
374
|
+
}
|
|
375
|
+
return results;
|
|
376
|
+
}
|
|
230
377
|
/**
|
|
231
378
|
* PRI-640: host attribution is supplied by the host adapter that constructs
|
|
232
379
|
* this shared handler (OpenClaw / Codex adapters) — never guessed inside the
|
|
@@ -248,7 +395,7 @@ export function createProductionPainEvidenceHandler(options = {}) {
|
|
|
248
395
|
options.events?.recordToolCall(event.context.sessionId, {
|
|
249
396
|
toolName: event.context.toolName ?? '',
|
|
250
397
|
...(earlyOutcome.error ? { error: earlyOutcome.error } : {}),
|
|
251
|
-
...(earlyOutcome.exitCode !== 0 ? { exitCode: earlyOutcome.exitCode } : {}),
|
|
398
|
+
...(earlyOutcome.exitCode !== null && earlyOutcome.exitCode !== 0 ? { exitCode: earlyOutcome.exitCode } : {}),
|
|
252
399
|
...(event.context.turnId !== undefined ? { runId: event.context.turnId } : {}),
|
|
253
400
|
...(event.context.toolCallId !== undefined ? { toolCallId: event.context.toolCallId } : {}),
|
|
254
401
|
});
|
|
@@ -264,6 +411,7 @@ export function createProductionPainEvidenceHandler(options = {}) {
|
|
|
264
411
|
try {
|
|
265
412
|
db = options.painDatabaseFactory ? options.painDatabaseFactory(dbPath) : new Database(dbPath);
|
|
266
413
|
db.pragma('busy_timeout = 5000');
|
|
414
|
+
ensureToolCallsToolUseIdColumn(db);
|
|
267
415
|
if (!hasCanonicalSchema(db)) {
|
|
268
416
|
db.close();
|
|
269
417
|
db = undefined;
|
|
@@ -296,22 +444,43 @@ export function createProductionPainEvidenceHandler(options = {}) {
|
|
|
296
444
|
const outcome = normalizeOutcome(event);
|
|
297
445
|
const sanitizedParams = sanitizeToolParams(outcome.params, event.context.workspaceDir);
|
|
298
446
|
const toolName = event.context.toolName ?? '';
|
|
299
|
-
const sourceObservation = buildToolFailureObservation({ toolName, error: outcome.error, exitCode: outcome.exitCode });
|
|
447
|
+
const sourceObservation = buildToolFailureObservation({ toolName, error: outcome.error, exitCode: outcome.exitCode ?? undefined });
|
|
448
|
+
const nonZeroExit = outcome.exitCode !== null && outcome.exitCode !== 0;
|
|
300
449
|
const sourceKind = resolveSourceKind({
|
|
301
450
|
observedAt: new Date().toISOString(), workspaceId: event.context.workspaceDir,
|
|
302
451
|
sessionId: event.context.sessionId, toolName, failureSource: sourceObservation.failureSource,
|
|
303
|
-
toolNotFound: sourceObservation.toolNotFound, nonZeroExit
|
|
452
|
+
toolNotFound: sourceObservation.toolNotFound, nonZeroExit,
|
|
304
453
|
});
|
|
305
454
|
const relativePath = enrichment.relativePath ?? String(field(outcome.params, 'file_path') ?? field(outcome.params, 'path') ?? 'unknown').slice(0, 500);
|
|
306
455
|
const isRisky = enrichment.isRisky ?? (path.isAbsolute(relativePath) && !path.resolve(relativePath).startsWith(`${path.resolve(event.context.workspaceDir)}${path.sep}`));
|
|
307
|
-
|
|
456
|
+
// Merged scoring semantics (WorkBuddy admission floor × CR-01): the 70
|
|
457
|
+
// failure base requires a VERIFIED non-zero exit code (branch review
|
|
458
|
+
// round: a thrown error with no exit evidence stays at the risky-path
|
|
459
|
+
// bonus only, honestly below the GOVERNANCE_STRONG_PAIN_SCORE floor, so
|
|
460
|
+
// unverified error shapes never spawn diagnostician work on their own).
|
|
461
|
+
// Classification and RECORDING remain main's three-way contract — the
|
|
462
|
+
// row still records outcome='failure' with exit_code NULL (never a
|
|
463
|
+
// fabricated 0).
|
|
464
|
+
const verifiedNonZeroExit = outcome.exitCode !== null && outcome.exitCode !== 0;
|
|
465
|
+
const painScore = enrichment.painScore ?? Math.min(100, (verifiedNonZeroExit ? 70 : 0) + (isRisky ? 20 : 0));
|
|
308
466
|
const errorHash = enrichment.errorHash ?? createHash('sha256').update(outcome.error ?? String(outcome.exitCode)).digest('hex');
|
|
467
|
+
// Cooldown is DEBOUNCE, not event identity (I1): the key deliberately has
|
|
468
|
+
// NO toolCallId. Repeated failures of the same failureSource+error within
|
|
469
|
+
// the window suppress the diagnostic trigger storm, while each real call
|
|
470
|
+
// still earns its own tool_calls evidence row through call-id-sensitive
|
|
471
|
+
// identity below.
|
|
309
472
|
const cooldownKey = `${path.resolve(event.context.workspaceDir)}:${event.context.sessionId}:${sourceObservation.failureSource}:${errorHash}`;
|
|
310
473
|
const last = cooldowns.get(cooldownKey);
|
|
311
474
|
const cooldownActive = last !== undefined && Date.now() - last < PAIN_COOLDOWN_WINDOW_MS;
|
|
312
475
|
const triage = evaluateTriage({ sourceKind, score: painScore, consecutiveErrors: enrichment.consecutiveErrors, isRisky });
|
|
313
476
|
const trigger = evaluateTriggerController({ triageResult: triage, isOwnerManual: false, isCooldownActive: cooldownActive, isValid: true, score: painScore, sessionId: event.context.sessionId });
|
|
314
|
-
|
|
477
|
+
// Merged semantics (WorkBuddy × CR-01): the three-way classification from
|
|
478
|
+
// SPEC-CODEX-PAIN-CLOSURE-001 gates admission ('unknown' results are never
|
|
479
|
+
// pain), and WorkBuddy tool names are capitalized (Write/Edit — probe P03)
|
|
480
|
+
// while OpenClaw/Codex are lowercase; admission is about the tool FAMILY,
|
|
481
|
+
// so compare case-insensitively at this one boundary. tool_calls evidence
|
|
482
|
+
// above keeps the raw host name.
|
|
483
|
+
const admitted = outcome.outcome === 'failure' && WRITE_TOOLS.has(toolName.toLowerCase()) && trigger.shouldCreateDiagnosticTask;
|
|
315
484
|
const { eventId, painId } = ids({
|
|
316
485
|
workspaceDir: event.context.workspaceDir,
|
|
317
486
|
sessionId: event.context.sessionId,
|
|
@@ -319,6 +488,11 @@ export function createProductionPainEvidenceHandler(options = {}) {
|
|
|
319
488
|
...(toolName !== undefined ? { toolName } : {}),
|
|
320
489
|
source: event.source,
|
|
321
490
|
...(enrichment.eventId ? { canonicalEventId: enrichment.eventId } : {}),
|
|
491
|
+
// I1: the host's real call identity participates when supplied —
|
|
492
|
+
// distinct call ids are distinct events; a same-call-id redelivery
|
|
493
|
+
// derives the same identity and stays idempotent. Absent → historical
|
|
494
|
+
// content-derived identity (no fabricated precision).
|
|
495
|
+
...(event.context.toolCallId !== undefined ? { toolCallId: event.context.toolCallId } : {}),
|
|
322
496
|
outcome,
|
|
323
497
|
sanitizedParams,
|
|
324
498
|
});
|
|
@@ -329,14 +503,23 @@ export function createProductionPainEvidenceHandler(options = {}) {
|
|
|
329
503
|
let duplicateAdmitted = false;
|
|
330
504
|
try {
|
|
331
505
|
db.transaction(() => {
|
|
332
|
-
|
|
506
|
+
// CR-01: the host tool-call id is the stable join key for the
|
|
507
|
+
// consent-gated transcript upgrade (recordVerifiedToolOutcomes);
|
|
508
|
+
// content-shape probing stays the fallback for hosts without ids.
|
|
509
|
+
if (event.context.toolCallId !== undefined
|
|
510
|
+
&& db.prepare('SELECT 1 FROM tool_calls WHERE session_id = ? AND tool_use_id = ?').get(event.context.sessionId, event.context.toolCallId) !== undefined) {
|
|
511
|
+
duplicate = true;
|
|
512
|
+
duplicateAdmitted = db.prepare('SELECT 1 FROM pain_events WHERE canonical_pain_id = ?').get(painId) !== undefined;
|
|
513
|
+
return;
|
|
514
|
+
}
|
|
515
|
+
if (db.prepare('SELECT 1 FROM tool_calls WHERE session_id = ? AND tool_name = ? AND params_json = ? AND outcome = ? AND exit_code IS ? AND error_message IS ? AND result_preview IS ?').get(event.context.sessionId, toolName, paramsJson, outcome.outcome, outcome.exitCode, outcome.error ?? null, resultPreview)) {
|
|
333
516
|
duplicate = true;
|
|
334
517
|
duplicateAdmitted = db.prepare('SELECT 1 FROM pain_events WHERE canonical_pain_id = ?').get(painId) !== undefined;
|
|
335
518
|
return;
|
|
336
519
|
}
|
|
337
520
|
db.prepare(`INSERT INTO sessions (session_id, started_at, updated_at) VALUES (?, ?, ?) ON CONFLICT(session_id) DO UPDATE SET updated_at = excluded.updated_at`).run(event.context.sessionId, createdAt, createdAt);
|
|
338
|
-
db.prepare(`INSERT INTO tool_calls (session_id, tool_name, outcome, duration_ms, exit_code, error_type, error_message, gfi_before, gfi_after, params_json, result_preview, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
|
|
339
|
-
.run(event.context.sessionId, toolName, outcome.
|
|
521
|
+
db.prepare(`INSERT INTO tool_calls (session_id, tool_name, outcome, duration_ms, exit_code, error_type, error_message, gfi_before, gfi_after, params_json, result_preview, created_at, tool_use_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
|
|
522
|
+
.run(event.context.sessionId, toolName, outcome.outcome, outcome.durationMs ?? null, outcome.exitCode, outcome.error ? outcome.error.split(/[\s:]/, 1)[0] : null, outcome.error ?? null, null, null, paramsJson, resultPreview, createdAt, event.context.toolCallId ?? null);
|
|
340
523
|
if (admitted) {
|
|
341
524
|
// Raw observation only (Pain Diagnosis Persistence SPEC §8): the
|
|
342
525
|
// pain row must record WHAT happened, not WHY. Attribution
|
|
@@ -364,7 +547,7 @@ export function createProductionPainEvidenceHandler(options = {}) {
|
|
|
364
547
|
}
|
|
365
548
|
}
|
|
366
549
|
catch (error) {
|
|
367
|
-
return { decision: 'observe', source: event.source, warnings: [...(emissionWarning ? [emissionWarning] : []), `trajectory_write_failed:${error instanceof Error ? error.message.slice(0, 200) : String(error).slice(0, 200)}`], metadata: { outcome: outcome.
|
|
550
|
+
return { decision: 'observe', source: event.source, warnings: [...(emissionWarning ? [emissionWarning] : []), `trajectory_write_failed:${error instanceof Error ? error.message.slice(0, 200) : String(error).slice(0, 200)}`], metadata: { outcome: outcome.outcome, admitted: false, duplicate: false, nextAction: 'inspect the workspace trajectory database and retry' } };
|
|
368
551
|
}
|
|
369
552
|
finally {
|
|
370
553
|
try {
|
|
@@ -378,7 +561,7 @@ export function createProductionPainEvidenceHandler(options = {}) {
|
|
|
378
561
|
source: event.source,
|
|
379
562
|
...(emissionWarning ? { warnings: [emissionWarning] } : {}),
|
|
380
563
|
metadata: {
|
|
381
|
-
eventId, painId: effectiveAdmitted ? painId : null, outcome: outcome.
|
|
564
|
+
eventId, painId: effectiveAdmitted ? painId : null, outcome: outcome.outcome, ...(outcome.unknownReason !== undefined ? { outcomeReason: outcome.unknownReason } : {}), exitCode: outcome.exitCode, admitted: effectiveAdmitted, duplicate,
|
|
382
565
|
sourceKind, failureSource: sourceObservation.failureSource ?? null, triggerOutcome: trigger.outcome,
|
|
383
566
|
triggerReason: trigger.reason, painScore, isRisky, relativePath, agentId: enrichment.agentId ?? null,
|
|
384
567
|
evidence: enrichment.evidence ?? [],
|
|
@@ -3,7 +3,7 @@ import path from 'node:path';
|
|
|
3
3
|
import { RUNTIME_V2_PRINCIPLE_BUDGET, SqliteConnection, SqlitePIArtifactStore, computeFeatureFlagsFromConfig, listEntryLine, renderPrinciplesToDirectives, resolvePrincipleFromArtifact, trimToBudget, } from '@principles/core/runtime-v2';
|
|
4
4
|
import { escapeXml } from '@principles/core/prompt-builder';
|
|
5
5
|
import { loadPdConfigForPlugin } from './pd-config.js';
|
|
6
|
-
import { PROMPT_INJECTION_UNIT, promptRouteForHost, resolvePromptInjectionRouteDecision, } from './prompt-injection-projection.js';
|
|
6
|
+
import { PROMPT_INJECTION_TARGET_HOSTS, PROMPT_INJECTION_UNIT, promptRouteForHost, resolvePromptInjectionRouteDecision, } from './prompt-injection-projection.js';
|
|
7
7
|
function syntheticPendingActivation(artifactId) {
|
|
8
8
|
return {
|
|
9
9
|
activationId: `pending:${artifactId}`,
|
|
@@ -114,8 +114,9 @@ export async function checkPromptArtifactDeliverability(input) {
|
|
|
114
114
|
}
|
|
115
115
|
// Route unconfirmed: report per-host fit for every standard host instead of
|
|
116
116
|
// guessing (R-A1) — the write gate refuses, the UI can show both facts.
|
|
117
|
-
|
|
118
|
-
|
|
117
|
+
// Roster derives from the single SSoT list (review P3-1: a hand-typed
|
|
118
|
+
// two-host array dropped WorkBuddy from unconfirmed deliverability reports).
|
|
119
|
+
const perHost = PROMPT_INJECTION_TARGET_HOSTS.map((hostKind) => {
|
|
119
120
|
const route = promptRouteForHost(hostKind, decision.flagEnabled);
|
|
120
121
|
const { fits, costChars } = computePromptSingleItemFit({
|
|
121
122
|
principle: resolved.principle,
|
|
@@ -127,7 +128,7 @@ export async function checkPromptArtifactDeliverability(input) {
|
|
|
127
128
|
return {
|
|
128
129
|
status: 'unconfirmed',
|
|
129
130
|
reason: `route_unconfirmed: ${decision.unconfirmedReason ?? 'effective injection route cannot be confirmed'}`,
|
|
130
|
-
nextAction: decision.nextAction ?? 'pass an explicit target host (openclaw|codex)',
|
|
131
|
+
nextAction: decision.nextAction ?? 'pass an explicit target host (openclaw|codex|workbuddy)',
|
|
131
132
|
perHost,
|
|
132
133
|
};
|
|
133
134
|
}
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
export interface InjectionEvidenceRow {
|
|
26
26
|
workspaceDir: string;
|
|
27
27
|
activationId: string;
|
|
28
|
-
hostKind: 'openclaw' | 'codex' | 'unknown';
|
|
28
|
+
hostKind: 'openclaw' | 'codex' | 'workbuddy' | 'unknown';
|
|
29
29
|
hostIdentityComplete: boolean;
|
|
30
30
|
eventIdentityComplete: boolean;
|
|
31
31
|
/** Deduplicated injection facts: this activation appeared in the injected set. */
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
+
import { isPromptInjectionTargetHost } from './prompt-injection-projection.js';
|
|
3
4
|
function isRecord(value) {
|
|
4
5
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
5
6
|
}
|
|
@@ -63,7 +64,10 @@ export function readInjectionEventEvidence(input) {
|
|
|
63
64
|
const runId = nonEmptyString(data.runId);
|
|
64
65
|
const eventId = nonEmptyString(data.eventId);
|
|
65
66
|
const rawHostKind = data.hostKind;
|
|
66
|
-
|
|
67
|
+
// Known-host membership comes from the roster predicate (review R1: the
|
|
68
|
+
// hand-typed openclaw|codex check classified real WorkBuddy injection
|
|
69
|
+
// events as the unknown bucket, contradicting this row's own type).
|
|
70
|
+
const hostKind = isPromptInjectionTargetHost(rawHostKind) ? rawHostKind : 'unknown';
|
|
67
71
|
const { activationIds } = data;
|
|
68
72
|
if (workspaceDir === undefined || sessionId === undefined || !Array.isArray(activationIds)
|
|
69
73
|
|| !activationIds.every((id) => typeof id === 'string')) {
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import { type PromptSelectionPolicy } from '@principles/core/runtime-v2';
|
|
2
2
|
/** Hosts with a production prompt-injection path today (shared GovernanceHostKind boundary). */
|
|
3
|
-
export type PromptInjectionTargetHost = 'openclaw' | 'codex';
|
|
3
|
+
export type PromptInjectionTargetHost = 'openclaw' | 'codex' | 'workbuddy';
|
|
4
|
+
/** Single host roster (review P2): every consumer derives from this list, so a
|
|
5
|
+
* new host cannot fork route-unconfirmed per-host forecasts from the routes. */
|
|
4
6
|
export declare const PROMPT_INJECTION_TARGET_HOSTS: readonly PromptInjectionTargetHost[];
|
|
7
|
+
/** Runtime membership test derived from the roster (rc-2): the ONE guard for
|
|
8
|
+
* "is this untrusted host-kind string a host with a known prompt-injection
|
|
9
|
+
* route". Every consumer narrows with this — never by re-typing the literals
|
|
10
|
+
* (review R1: each re-typed list forked the roster and dropped WorkBuddy). */
|
|
11
|
+
export declare function isPromptInjectionTargetHost(kind: unknown): kind is PromptInjectionTargetHost;
|
|
5
12
|
export type PromptInjectionRouteName = 'legacy_trim' | 'shared_render';
|
|
6
13
|
/**
|
|
7
14
|
* Which serialization the budget is charged against (SPEC R-A2): the legacy
|
|
@@ -48,9 +55,11 @@ export interface PromptInjectionRouteDecision {
|
|
|
48
55
|
}
|
|
49
56
|
/**
|
|
50
57
|
* THE one route formula (P4): Codex always injects through the shared route
|
|
51
|
-
* (codex-adapter has no flag branch);
|
|
52
|
-
*
|
|
53
|
-
*
|
|
58
|
+
* (codex-adapter has no flag branch); so does WorkBuddy (workbuddy-adapter
|
|
59
|
+
* renders through the shared runtime unconditionally — it has no legacy
|
|
60
|
+
* route); OpenClaw routes by its `abstraction_layer_v1` gate. Every consumer
|
|
61
|
+
* that needs "which route would host X take" must call this — never re-type
|
|
62
|
+
* the ternary.
|
|
54
63
|
*/
|
|
55
64
|
export declare function promptRouteForHost(hostKind: PromptInjectionTargetHost, flagEnabled: boolean): PromptInjectionRouteName;
|
|
56
65
|
/**
|
|
@@ -175,7 +184,7 @@ export declare function buildLivePromptInjectionProjection(input: {
|
|
|
175
184
|
* rather than assuming FIFO.
|
|
176
185
|
*/
|
|
177
186
|
roundKey?: number;
|
|
178
|
-
/** AC-01: explicit route binding — 'codex' always shared, 'openclaw' by flag. */
|
|
187
|
+
/** AC-01: explicit route binding — 'codex'/'workbuddy' always shared, 'openclaw' by flag. */
|
|
179
188
|
targetHost?: PromptInjectionTargetHost;
|
|
180
189
|
}): Promise<PromptInjectionProjection>;
|
|
181
190
|
/**
|