blun-king-cli 9.1.587 → 9.1.588
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/CHANGELOG.md +11 -185
- package/LIESMICH.txt +51 -13
- package/README.md +44 -47
- package/agent-spine-plugin/.codex-plugin/plugin.json +16 -4
- package/agent-spine-plugin/CHANGELOG.md +37 -5
- package/agent-spine-plugin/README.md +3 -3
- package/agent-spine-plugin/blun.plugin.json +45 -10
- package/agent-spine-plugin/docs/artifact-evaluation.md +93 -0
- package/agent-spine-plugin/docs/host-integration.md +42 -27
- package/agent-spine-plugin/docs/preflight-recall.md +4 -2
- package/agent-spine-plugin/docs/session-timeline.md +97 -236
- package/agent-spine-plugin/docs/world-model.md +25 -0
- package/agent-spine-plugin/hooks/codex.json +1 -1
- package/agent-spine-plugin/hooks/hooks.json +1 -1
- package/agent-spine-plugin/package.json +1 -3
- package/agent-spine-plugin/scripts/check-hosts.js +3 -3
- package/agent-spine-plugin/scripts/release-check.js +10 -5
- package/agent-spine-plugin/scripts/run-checks.js +4 -1
- package/agent-spine-plugin/scripts/run-tests-hermetic.js +32 -6
- package/agent-spine-plugin/src/cli-learning.js +15 -0
- package/agent-spine-plugin/src/cli.js +2 -0
- package/agent-spine-plugin/src/hook.js +32 -32
- package/agent-spine-plugin/src/lib/action-lesson-recall.js +73 -8
- package/agent-spine-plugin/src/lib/briefing.js +146 -36
- package/agent-spine-plugin/src/lib/channel-continuity.js +19 -0
- package/agent-spine-plugin/src/lib/delivery-agent-usage.js +14 -7
- package/agent-spine-plugin/src/lib/gateway-group-response.js +128 -0
- package/agent-spine-plugin/src/lib/gateway-runs.js +24 -15
- package/agent-spine-plugin/src/lib/hook-briefing-use.js +13 -3
- package/agent-spine-plugin/src/lib/hook-context.js +16 -3
- package/agent-spine-plugin/src/lib/hook-output.js +129 -5
- package/agent-spine-plugin/src/lib/hook-timeline.js +5 -3
- package/agent-spine-plugin/src/lib/indexed-memory.js +2 -2
- package/agent-spine-plugin/src/lib/learning-artifact-evaluator.js +114 -0
- package/agent-spine-plugin/src/lib/learning-context.js +11 -4
- package/agent-spine-plugin/src/lib/learning-measurements.js +2 -2
- package/agent-spine-plugin/src/lib/mcp-runtime.js +89 -3
- package/agent-spine-plugin/src/lib/mcp-source-context.js +12 -2
- package/agent-spine-plugin/src/lib/mcp-timeline-tools.js +91 -8
- package/agent-spine-plugin/src/lib/mcp-world-tools.js +2 -2
- package/agent-spine-plugin/src/lib/owned-file-lock.js +20 -1
- package/agent-spine-plugin/src/lib/persona-runtime.js +2 -2
- package/agent-spine-plugin/src/lib/preflight-delivery-id.js +27 -0
- package/agent-spine-plugin/src/lib/preflight.js +4 -4
- package/agent-spine-plugin/src/lib/session-timeline-codex.js +15 -0
- package/agent-spine-plugin/src/lib/session-timeline-contract.js +12 -4
- package/agent-spine-plugin/src/lib/session-timeline-event-extract.js +36 -7
- package/agent-spine-plugin/src/lib/session-timeline-host-origin.js +13 -10
- package/agent-spine-plugin/src/lib/session-timeline-invocation.js +1 -1
- package/agent-spine-plugin/src/lib/session-timeline-king.js +14 -0
- package/agent-spine-plugin/src/lib/session-timeline-prior.js +18 -12
- package/agent-spine-plugin/src/lib/session-timeline-provider.js +5 -0
- package/agent-spine-plugin/src/lib/session-timeline-query.js +2 -0
- package/agent-spine-plugin/src/lib/session-timeline-results.js +35 -10
- package/agent-spine-plugin/src/lib/session-timeline-source-open.js +30 -0
- package/agent-spine-plugin/src/lib/session-timeline.js +122 -75
- package/agent-spine-plugin/src/lib/source-roots.js +3 -2
- package/agent-spine-plugin/src/lib/task-knowledge-context.js +22 -1
- package/agent-spine-plugin/src/lib/timeline-continuation-update.js +100 -0
- package/agent-spine-plugin/src/lib/timeline-tool-guard.js +30 -7
- package/agent-spine-plugin/src/lib/timeline-user-feedback.js +217 -0
- package/agent-spine-plugin/src/lib/timeline-world-capture.js +233 -0
- package/agent-spine-plugin/src/lib/world-knowledge.js +59 -2
- package/agent-spine-plugin/src/lib/world-model.js +64 -9
- package/agent-spine-plugin/src/worker.js +13 -1
- package/bin/blun.js +43 -28
- package/bin/core-bootstrap.js +5 -4
- package/bin/king.js +43 -28
- package/bin/launcher-mode.js +1 -10
- package/bin/launcher-runtime.js +128 -295
- package/bin/managed-node.js +0 -0
- package/bin/managed-plugin-selection.cjs +0 -1
- package/bin/native-module-repair.js +0 -0
- package/bin/node-runtime.js +0 -0
- package/bin/node-version.js +0 -0
- package/bin/plugin-bootstrap.js +56 -120
- package/bin/private-paths.js +11 -34
- package/bin/standard-tools-bootstrap.js +34 -114
- package/bin/turn-thinking-policy.cjs +3 -11
- package/bin/update-copy.js +200 -0
- package/bin/update-lease.js +0 -0
- package/bin/update-notice.js +136 -289
- package/bin/verify-agent-behavior.cjs +122 -0
- package/bin/verify-agent-components.cjs +104 -0
- package/bin/verify-bundled-agent-sources.cjs +57 -0
- package/blun.mjs +143076 -135288
- package/bundled-agent-sources.json +701 -0
- package/package.json +12 -15
- package/standard-skills/translate-native/README.md +1293 -0
- package/standard-skills/translate-native/SKILL.md +172 -22
- package/standard-skills/translate-native/VERSION +1 -1
- package/standard-skills/translate-native/agents/openai.yaml +18 -0
- package/standard-skills/translate-native/assets/icon.svg +8 -0
- package/standard-skills/translate-native/docs/BLUN_CODE_INTEGRATION.md +76 -0
- package/standard-skills/translate-native/docs/PREMORTEM.md +489 -0
- package/standard-skills/translate-native/docs/WEBSITE_LOCALIZATION.md +2035 -0
- package/standard-skills/translate-native/docs/WEBSITE_LOCALIZATION_API.md +1302 -0
- package/standard-skills/translate-native/docs/WEBSITE_LOCALIZATION_EVIDENCE_HTTP.md +136 -0
- package/standard-skills/translate-native/docs/WEBSITE_LOCALIZATION_HEALTH_HTTP.md +130 -0
- package/standard-skills/translate-native/docs/WEBSITE_LOCALIZATION_HTTP_PROVIDER.md +175 -0
- package/standard-skills/translate-native/docs/WEBSITE_LOCALIZATION_RECEIPT_VERIFIER_HTTP.md +86 -0
- package/standard-skills/translate-native/integrations/AGENT_RULES.md +32 -0
- package/standard-skills/translate-native/integrations/adapters/blun-code-language-guard.js +514 -0
- package/standard-skills/translate-native/integrations/adapters/node-language-guard.js +230 -0
- package/standard-skills/translate-native/integrations/audit_log.py +327 -0
- package/standard-skills/translate-native/integrations/claude_language_hook.js +1536 -0
- package/standard-skills/translate-native/integrations/commercial_localization_profile.py +42 -0
- package/standard-skills/translate-native/integrations/delivery-policy.example.json +28 -0
- package/standard-skills/translate-native/integrations/enforced_delivery.py +543 -0
- package/standard-skills/translate-native/integrations/guard_service.py +435 -0
- package/standard-skills/translate-native/integrations/language_gateway.py +67 -0
- package/standard-skills/translate-native/integrations/mcp_auth_headers.py +198 -0
- package/standard-skills/translate-native/integrations/mcp_http_gateway.py +429 -0
- package/standard-skills/translate-native/integrations/non_language_html_entities.js +1485 -0
- package/standard-skills/translate-native/integrations/pre_output_guard.py +65 -0
- package/standard-skills/translate-native/integrations/task_router.py +101 -0
- package/standard-skills/translate-native/integrations/website_localization.py +401 -0
- package/standard-skills/translate-native/integrations/website_localization_api.py +581 -0
- package/standard-skills/translate-native/integrations/website_localization_benchmark.py +1885 -0
- package/standard-skills/translate-native/integrations/website_localization_benchmark_campaign.py +1772 -0
- package/standard-skills/translate-native/integrations/website_localization_benchmark_candidate.py +506 -0
- package/standard-skills/translate-native/integrations/website_localization_benchmark_http.py +400 -0
- package/standard-skills/translate-native/integrations/website_localization_benchmark_review_store.py +781 -0
- package/standard-skills/translate-native/integrations/website_localization_benchmark_reviewer_http.py +500 -0
- package/standard-skills/translate-native/integrations/website_localization_benchmark_runtime.py +1107 -0
- package/standard-skills/translate-native/integrations/website_localization_benchmark_suite.py +463 -0
- package/standard-skills/translate-native/integrations/website_localization_cms.py +2835 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_client.py +875 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_dispatch.py +805 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_http.py +588 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_lifecycle_monitor.py +991 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_receiver.py +1441 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_receiver_runtime.py +414 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_receiver_store.py +1073 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_removal_dispatch.py +865 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_client.py +583 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery.py +964 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery_runtime.py +665 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_http.py +1153 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_runtime.py +675 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_service.py +1125 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_terminal_notification.py +674 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_terminal_notification_http.py +444 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_terminal_notification_receiver.py +1469 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_terminal_notification_receiver_runtime.py +1142 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_terminal_processing_monitor.py +634 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_terminal_receiver_client.py +804 -0
- package/standard-skills/translate-native/integrations/website_localization_deepl_baseline.py +922 -0
- package/standard-skills/translate-native/integrations/website_localization_evidence_http.py +482 -0
- package/standard-skills/translate-native/integrations/website_localization_health.py +1541 -0
- package/standard-skills/translate-native/integrations/website_localization_health_http.py +372 -0
- package/standard-skills/translate-native/integrations/website_localization_http_provider.py +297 -0
- package/standard-skills/translate-native/integrations/website_localization_native_reference_http.py +479 -0
- package/standard-skills/translate-native/integrations/website_localization_native_reference_intake.py +363 -0
- package/standard-skills/translate-native/integrations/website_localization_native_reference_queue.py +1449 -0
- package/standard-skills/translate-native/integrations/website_localization_native_reference_store.py +420 -0
- package/standard-skills/translate-native/integrations/website_localization_quality_profiles.py +235 -0
- package/standard-skills/translate-native/integrations/website_localization_queue.py +671 -0
- package/standard-skills/translate-native/integrations/website_localization_receipt_verifier_http.py +516 -0
- package/standard-skills/translate-native/integrations/website_localization_release.py +928 -0
- package/standard-skills/translate-native/integrations/website_localization_release_coordinator.py +1008 -0
- package/standard-skills/translate-native/integrations/website_localization_runner.py +276 -0
- package/standard-skills/translate-native/integrations/website_localization_runtime.py +862 -0
- package/standard-skills/translate-native/integrations/website_localization_service.py +350 -0
- package/standard-skills/translate-native/integrations/website_localization_supervisor.py +511 -0
- package/standard-skills/translate-native/integrations/website_localization_worker.py +663 -0
- package/standard-skills/translate-native/provenance.json +3 -4
- package/standard-skills/translate-native/references/commercial-localization.md +177 -0
- package/standard-skills/translate-native/scripts/blun_language_guard.py +7 -1
- package/standard-skills/translate-native/scripts/check_commercial_review.py +80 -0
- package/standard-skills/translate-native/scripts/commercial_localization_profile.py +333 -0
- package/standard-tools/language-guard/LICENSE +21 -0
- package/standard-tools/language-guard/VERSION +1 -0
- package/standard-tools/language-guard/blun_language_guard.py +7 -1
- package/standard-tools/language-guard/check_commercial_review.py +80 -0
- package/standard-tools/language-guard/commercial_localization_profile.py +333 -0
- package/standard-tools/language-guard/language_gateway.py +62 -0
- package/standard-tools/language-guard/pre_output_guard.py +64 -0
- package/standard-tools/language-guard/provenance.json +4 -11
- package/standard-tools/manifest.json +34 -11
- package/telegram-plugin/commands/access.md +2 -10
- package/telegram-plugin/dist/bridge.mjs +64041 -687
- package/telegram-plugin/dist/mcp-server.mjs +72810 -9027
- package/telegram-plugin/dist/noise.mjs +28 -63511
- package/agent-spine-plugin/CONTRIBUTING.md +0 -52
- package/agent-spine-plugin/SECURITY.md +0 -47
- package/agent-spine-plugin/docs/assignment-continuation.md +0 -48
- package/agent-spine-plugin/docs/releasing.md +0 -85
- package/agent-spine-plugin/docs/structured-completion.md +0 -67
- package/bin/abort-listener-policy.cjs +0 -43
- package/bin/active-steer-priority-policy.cjs +0 -24
- package/bin/agent-api-http-adapter.mjs +0 -446
- package/bin/agent-api-private-http-server.mjs +0 -288
- package/bin/agent-api-runtime.mjs +0 -252
- package/bin/agent-api-service-environment.mjs +0 -236
- package/bin/agent-api-service-host.mjs +0 -209
- package/bin/agent-api-service-process.mjs +0 -171
- package/bin/agent-api-session-registry.mjs +0 -428
- package/bin/agent-api-tool-broker.cjs +0 -248
- package/bin/agent-api-turn-controller.mjs +0 -461
- package/bin/agent-api-usage-journal.cjs +0 -259
- package/bin/agent-resume-snapshot.cjs +0 -241
- package/bin/agentspine-king-goal-inbox.mjs +0 -111
- package/bin/agentspine-king-goal-intake.mjs +0 -106
- package/bin/approval-rejection-stop.cjs +0 -15
- package/bin/assistant-message-offload-policy.cjs +0 -284
- package/bin/baseline-skill-performance-policy.cjs +0 -39
- package/bin/bash-search-scope-policy.cjs +0 -49
- package/bin/codebase-search-runtime.cjs +0 -23
- package/bin/cognitive-action-checkpoint.cjs +0 -1104
- package/bin/cognitive-attention-delivery.cjs +0 -76
- package/bin/cognitive-attention-policy.cjs +0 -143
- package/bin/cognitive-attention-runtime.cjs +0 -91
- package/bin/cognitive-context-projection.cjs +0 -73
- package/bin/cognitive-cross-portal-acceptance.cjs +0 -443
- package/bin/cognitive-effective-view.cjs +0 -77
- package/bin/cognitive-focus-projection.cjs +0 -206
- package/bin/cognitive-focus-scope.cjs +0 -37
- package/bin/cognitive-goal-autostart-policy.cjs +0 -72
- package/bin/cognitive-goal-time-trigger-controller.cjs +0 -146
- package/bin/cognitive-memory-adapter.cjs +0 -282
- package/bin/cognitive-memory-command.cjs +0 -293
- package/bin/cognitive-memory-provider.cjs +0 -92
- package/bin/cognitive-salience-policy.cjs +0 -159
- package/bin/cognitive-state-store.cjs +0 -508
- package/bin/cognitive-turn-lifecycle.cjs +0 -624
- package/bin/cognitive-work-focus.cjs +0 -180
- package/bin/compaction-history-archive.cjs +0 -166
- package/bin/compaction-history-startup.cjs +0 -50
- package/bin/compaction-model-policy.cjs +0 -31
- package/bin/compaction-stage-policy.cjs +0 -21
- package/bin/compaction-transaction-policy.cjs +0 -122
- package/bin/config-write-dedup-policy.cjs +0 -27
- package/bin/context-budget-ledger.cjs +0 -31
- package/bin/context-doctor-policy.cjs +0 -70
- package/bin/context-insight-policy.cjs +0 -36
- package/bin/context-performance-policy.cjs +0 -19
- package/bin/context-pressure-policy.cjs +0 -20
- package/bin/cron-run-output.cjs +0 -45
- package/bin/cron-run-store.cjs +0 -145
- package/bin/curiosity-scout-policy.cjs +0 -49
- package/bin/default-model-output-budget-policy.cjs +0 -28
- package/bin/durable-task-resume-policy.cjs +0 -130
- package/bin/durable-task-resume-runtime.cjs +0 -117
- package/bin/durable-task-resume-store.cjs +0 -88
- package/bin/editable-tool-approval-policy.cjs +0 -540
- package/bin/editable-tool-approval-runtime.cjs +0 -99
- package/bin/effective-system-prompt-cache-policy.cjs +0 -33
- package/bin/error-memory-performance-policy.cjs +0 -113
- package/bin/file-observation-policy.cjs +0 -133
- package/bin/foreground-output-capture-policy.cjs +0 -41
- package/bin/generated-source-health.cjs +0 -142
- package/bin/glob-pattern-policy.cjs +0 -13
- package/bin/goal-completion-evidence-policy.cjs +0 -120
- package/bin/grep-output-limit-policy.cjs +0 -39
- package/bin/historical-media-projection-policy.cjs +0 -48
- package/bin/history-offload-pressure-policy.cjs +0 -33
- package/bin/html-to-research-markdown.cjs +0 -147
- package/bin/identity-context-policy.cjs +0 -764
- package/bin/identity-journal-policy.cjs +0 -107
- package/bin/input-draft-persistence.cjs +0 -77
- package/bin/king-tui-function-contract.json +0 -33
- package/bin/launcher-restart-policy.cjs +0 -150
- package/bin/live-response-repetition-guard.cjs +0 -196
- package/bin/llm-config-log-dedup-policy.cjs +0 -76
- package/bin/loop-event-record-policy.cjs +0 -174
- package/bin/managed-context-startup-policy.cjs +0 -27
- package/bin/media-activity-layout-policy.cjs +0 -34
- package/bin/media-auto-retrieval-policy.cjs +0 -90
- package/bin/media-result-policy.cjs +0 -59
- package/bin/micro-compaction-policy.cjs +0 -145
- package/bin/mistake-relevance-policy.cjs +0 -319
- package/bin/model-retry-progress-policy.cjs +0 -46
- package/bin/native-large-file-io.cjs +0 -42
- package/bin/native-runtime-cache.cjs +0 -76
- package/bin/natural-presence-policy.cjs +0 -28
- package/bin/noninteractive-shell-env-policy.cjs +0 -19
- package/bin/observer-hooks.cjs +0 -14
- package/bin/outbound-claim-provenance.cjs +0 -150
- package/bin/oversized-context-offload-policy.cjs +0 -86
- package/bin/pending-media-policy.cjs +0 -182
- package/bin/pending-token-estimate-policy.cjs +0 -41
- package/bin/personal-memory-consent-policy.cjs +0 -72
- package/bin/personal-memory-performance-policy.cjs +0 -12
- package/bin/personality-choice-policy.cjs +0 -101
- package/bin/personality-memory-adapter.cjs +0 -379
- package/bin/personality-mode.cjs +0 -46
- package/bin/personality-setup-policy.cjs +0 -197
- package/bin/proactive-compaction-policy.cjs +0 -25
- package/bin/profile-identity-resolution.cjs +0 -136
- package/bin/profile-runtime.cjs +0 -318
- package/bin/profile-tool-exclusion-policy.cjs +0 -37
- package/bin/programmatic-context-isolation.cjs +0 -25
- package/bin/programmatic-tool-runtime.mjs +0 -627
- package/bin/provider-idle-timeout-policy.cjs +0 -14
- package/bin/provider-model-refresh-deadline.cjs +0 -53
- package/bin/provider-model-refresh-policy.cjs +0 -107
- package/bin/rate-limit-recovery-policy.cjs +0 -47
- package/bin/read-batch-policy.cjs +0 -32
- package/bin/read-continuation-policy.cjs +0 -59
- package/bin/recurring-cron-history-policy.cjs +0 -124
- package/bin/relationship-continuity-policy.cjs +0 -143
- package/bin/relationship-curiosity-policy.cjs +0 -107
- package/bin/relationship-learning-policy.cjs +0 -168
- package/bin/release-artifact-freeze-policy.cjs +0 -30
- package/bin/reload-plugin-bootstrap.cjs +0 -18
- package/bin/reload-queue-policy.cjs +0 -38
- package/bin/repeated-assistant-response-policy.cjs +0 -232
- package/bin/repeated-injection-projection.cjs +0 -107
- package/bin/repeated-user-message-projection.cjs +0 -8
- package/bin/research-page-result.cjs +0 -74
- package/bin/retry-checkpoint-policy.cjs +0 -13
- package/bin/runtime-exit-ledger.cjs +0 -144
- package/bin/scoped-cron-run-policy.cjs +0 -358
- package/bin/session-checkpoint-policy.cjs +0 -25
- package/bin/session-compaction-policy.cjs +0 -84
- package/bin/session-replay-policy.cjs +0 -20
- package/bin/session-replay-window-policy.cjs +0 -40
- package/bin/session-resume-checkpoint.cjs +0 -254
- package/bin/session-scrollback-archive.cjs +0 -229
- package/bin/skill-activation-performance-policy.cjs +0 -69
- package/bin/skill-listing-performance-policy.cjs +0 -92
- package/bin/soul-organization-policy.cjs +0 -78
- package/bin/soul-preservation-policy.cjs +0 -20
- package/bin/startup-preferences.cjs +0 -131
- package/bin/streaming-flush-performance-policy.cjs +0 -28
- package/bin/structured-agent-swarm-output.cjs +0 -325
- package/bin/structured-subagent-output.cjs +0 -252
- package/bin/subagent-context-fork-policy.cjs +0 -155
- package/bin/subagent-max-tokens-handoff-policy.cjs +0 -69
- package/bin/subagent-parent-responsiveness.cjs +0 -19
- package/bin/subagent-skill-policy.cjs +0 -206
- package/bin/subagent-timeout-policy.cjs +0 -182
- package/bin/subagent-tool-policy.cjs +0 -60
- package/bin/subagent-usage-rollup-policy.cjs +0 -29
- package/bin/system-prompt-context-policy.cjs +0 -124
- package/bin/system-prompt-token-cache-policy.cjs +0 -60
- package/bin/telegram-addressed-focus.cjs +0 -55
- package/bin/telegram-addressed-priority.cjs +0 -12
- package/bin/telegram-approval-relay.cjs +0 -290
- package/bin/telegram-bot-priority.cjs +0 -17
- package/bin/telegram-console-status-policy.cjs +0 -174
- package/bin/telegram-context-projection-policy.cjs +0 -141
- package/bin/telegram-delivery-lifecycle.cjs +0 -125
- package/bin/telegram-direct-focus-policy.cjs +0 -273
- package/bin/telegram-mcp-compatibility.cjs +0 -49
- package/bin/telegram-media-delivery-policy.cjs +0 -42
- package/bin/telegram-private-conversation-policy.cjs +0 -185
- package/bin/telegram-queue-handoff-policy.cjs +0 -73
- package/bin/telegram-remote-status-policy.cjs +0 -120
- package/bin/telegram-session-queue-runtime.mjs +0 -306
- package/bin/telegram-text-chunk-policy.cjs +0 -63
- package/bin/telegram-truncated-reply-policy.cjs +0 -37
- package/bin/telegram-urgent-policy.cjs +0 -45
- package/bin/telemetry-spool-policy.cjs +0 -57
- package/bin/thinking-activity-status-policy.cjs +0 -132
- package/bin/thinking-only-guard.cjs +0 -80
- package/bin/todo-list-turn-policy.cjs +0 -131
- package/bin/tool-call-loop-policy.cjs +0 -51
- package/bin/tool-file-persistence.cjs +0 -141
- package/bin/tool-result-offload-policy.cjs +0 -359
- package/bin/tool-result-offload-telemetry.cjs +0 -12
- package/bin/tool-schema-token-cache-policy.cjs +0 -41
- package/bin/tool-stream-preview-policy.cjs +0 -9
- package/bin/tui-functional-contract.cjs +0 -55
- package/bin/turn-tool-performance-policy.cjs +0 -486
- package/bin/usage-cache-efficiency-policy.cjs +0 -26
- package/bin/user-home-path-policy.cjs +0 -13
- package/bin/user-message-offload-policy.cjs +0 -103
- package/bin/user-prompt-hook-origin-policy.cjs +0 -34
- package/bin/user-tool-record-policy.cjs +0 -7
- package/bin/validated-learning-insight-policy.cjs +0 -58
- package/bin/validated-learning-outcome-trace.cjs +0 -107
- package/bin/validated-learning-performance-policy.cjs +0 -53
- package/bin/validated-learning-signal.cjs +0 -463
- package/bin/windows-bash-dialect-policy.cjs +0 -25
- package/bin/windows-node-crash-dump.cjs +0 -110
- package/bin/write-continuation-policy.cjs +0 -69
- package/codebase-index/README.md +0 -82
- package/codebase-index/codebase_index.py +0 -470
- package/standard-skills/agent-browser/SKILL.md +0 -19
- package/standard-skills/agent-browser/references/runtime.md +0 -8
- package/standard-skills/blun-session-inspector/SKILL.md +0 -41
- package/standard-skills/blun-session-inspector/scripts/inspect-session.cjs +0 -437
- package/standard-skills/design-taste-frontend/SKILL.md +0 -1206
- package/standard-skills/full-output-enforcement/SKILL.md +0 -49
- package/standard-skills/high-end-visual-design/SKILL.md +0 -98
- package/standard-skills/image-to-code/SKILL.md +0 -1228
- package/standard-skills/industrial-brutalist-ui/SKILL.md +0 -92
- package/standard-skills/minimalist-ui/SKILL.md +0 -85
- package/standard-skills/motion-design-taste/SKILL.md +0 -74
- package/standard-skills/playwright-testing/SKILL.md +0 -19
- package/standard-skills/playwright-testing/references/runtime.md +0 -7
- package/standard-skills/premortem/SKILL.md +0 -148
- package/standard-skills/redesign-existing-projects/SKILL.md +0 -178
- package/standard-skills/research-evidence/SKILL.md +0 -39
- package/standard-skills/research-evidence/references/evidence-format.md +0 -104
- package/standard-skills/research-evidence/scripts/evidence-collection.cjs +0 -260
- package/standard-skills/research-evidence/scripts/score-report.cjs +0 -130
- package/standard-skills/screenshot-lesen/SKILL.md +0 -52
- package/standard-skills/stitch-design-taste/DESIGN.md +0 -121
- package/standard-skills/stitch-design-taste/SKILL.md +0 -184
- package/standard-skills/telegram-channel/SKILL.md +0 -18
- package/standard-skills/telegram-channel/references/runtime.md +0 -7
- package/standard-skills/venture-flywheel/SKILL.md +0 -32
- package/standard-skills/venture-flywheel/identity/project-identity.cjs +0 -146
- package/standard-skills/venture-flywheel/policy/capability-engine.cjs +0 -114
- package/standard-skills/venture-flywheel/policy/repository-trust.cjs +0 -229
- package/standard-skills/venture-flywheel/references/BEISPIELE-phase0.md +0 -146
- package/standard-skills/venture-flywheel/references/CAPABILITY-MAP.md +0 -34
- package/standard-skills/venture-flywheel/references/SPEC-phase0-identity-trust.md +0 -77
- package/standard-skills/venture-flywheel/references/SPEC-phase0-state-events.md +0 -93
- package/standard-skills/venture-flywheel/schemas/capability-decision.schema.json +0 -13
- package/standard-skills/venture-flywheel/schemas/execution-event.schema.json +0 -44
- package/standard-skills/venture-flywheel/schemas/project-identity.schema.json +0 -32
- package/standard-skills/venture-flywheel/schemas/repository-trust.schema.json +0 -57
- package/standard-skills/venture-flywheel/schemas/run-transition.schema.json +0 -59
- package/standard-skills/venture-flywheel/state/execution-event.cjs +0 -191
- package/standard-skills/venture-flywheel/state/task-state-machine.cjs +0 -190
- package/standard-skills/web-lesen/SKILL.md +0 -73
- package/standard-skills/web-lesen/scripts/crawl_public.py +0 -379
- package/standard-skills/windows-mcp/SKILL.md +0 -19
- package/standard-skills/windows-mcp/references/runtime.md +0 -9
- package/telegram-plugin/DELIVERY.md +0 -36
- package/telegram-plugin/bin/telegram-approval-relay.cjs +0 -290
- package/telegram-plugin/bin/telegram-console-status-policy.cjs +0 -175
- package/telegram-plugin/bin/telegram-delivery-lifecycle.cjs +0 -125
- package/telegram-plugin/bin/telegram-direct-reply-policy.cjs +0 -48
- package/telegram-plugin/bin/telegram-launcher-status-queue.cjs +0 -122
- package/telegram-plugin/bin/telegram-private-conversation-policy.cjs +0 -186
- package/telegram-plugin/bin/telegram-remote-status-policy.cjs +0 -121
- package/telegram-plugin/bin/telegram-reply-parts.cjs +0 -149
- package/telegram-plugin/bin/telegram-text-chunk-policy.cjs +0 -63
- package/telegram-plugin/bin/telegram-typing-keepalive.cjs +0 -89
- package/telegram-plugin/compat/mcp-server-fa511cd1.mjs +0 -73825
- /package/{bin → scripts}/fix-node-pty-perms.js +0 -0
|
@@ -1,1104 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const crypto = require('node:crypto');
|
|
4
|
-
const { extractChecksumClaims } = require('./outbound-claim-provenance.cjs');
|
|
5
|
-
|
|
6
|
-
const PHASES = new Set(['orient', 'plan', 'act', 'verify', 'learn', 'wait']);
|
|
7
|
-
const EVIDENCE_BASES = new Set([
|
|
8
|
-
'runtime_tool', 'user_statement', 'external_report', 'carried_forward',
|
|
9
|
-
]);
|
|
10
|
-
const EPISTEMIC_STATES = new Set([
|
|
11
|
-
'verified', 'credible_unverified', 'hypothesis', 'uncertain_memory', 'stale', 'unknown',
|
|
12
|
-
]);
|
|
13
|
-
const TRIGGER_KINDS = new Set([
|
|
14
|
-
'immediate', 'external_event', 'time', 'dependency', 'user_decision',
|
|
15
|
-
]);
|
|
16
|
-
const VERIFICATION_SUBJECTS = new Set(['result', 'verifier']);
|
|
17
|
-
const VERIFICATION_KINDS = new Set(['inspection', 'integrity', 'syntax', 'test', 'reachability']);
|
|
18
|
-
const EXTERNAL_REPORT_SOURCES = new Set(['telegram']);
|
|
19
|
-
const MODEL_KEYS = new Set([
|
|
20
|
-
'revision', 'phase', 'evidenceBasis', 'epistemicState', 'lastVerified', 'nextAction', 'expectedEvidence', 'verificationProof', 'nextTrigger', 'problemFrame', 'externalReportSource', 'updatedAt',
|
|
21
|
-
]);
|
|
22
|
-
const RUNTIME_KEYS = new Set([...MODEL_KEYS, 'evidenceReceipt', 'externalReportOrigin']);
|
|
23
|
-
const PROBLEM_FRAME_KEYS = new Set([
|
|
24
|
-
'successCriterion', 'missingKnowledge', 'candidateActions', 'selectedAction',
|
|
25
|
-
'selectionReason', 'supportChoice', 'risk', 'reversibility', 'decisionBasis',
|
|
26
|
-
]);
|
|
27
|
-
const NEXT_TRIGGER_KEYS = new Set(['kind', 'condition', 'dueAt']);
|
|
28
|
-
const EXTERNAL_REPORT_SELECTOR_KEYS = new Set(['source', 'chatId', 'messageId']);
|
|
29
|
-
const EXTERNAL_REPORT_ORIGIN_KEYS = new Set([
|
|
30
|
-
'source', 'reporter', 'reporterRef', 'eventRef', 'occurredAt',
|
|
31
|
-
]);
|
|
32
|
-
const EVIDENCE_INPUT_KEYS = new Set([
|
|
33
|
-
'turnId', 'toolCallId', 'toolName', 'decision', 'outcome', 'durationMs', 'toolArgs',
|
|
34
|
-
'resultEvidenceKinds', 'resultEvidenceScopes',
|
|
35
|
-
]);
|
|
36
|
-
const REQUIRED_EVIDENCE_INPUT_KEYS = new Set([
|
|
37
|
-
'turnId', 'toolCallId', 'toolName', 'decision', 'outcome', 'durationMs',
|
|
38
|
-
]);
|
|
39
|
-
const EVIDENCE_DIGEST_RE = /^[a-f0-9]{16}$/u;
|
|
40
|
-
const EVIDENCE_PRODUCER_REF_RE = /^[a-f0-9]{16}$/u;
|
|
41
|
-
const EXTERNAL_REPORT_REF_RE = /^[a-f0-9]{16}$/u;
|
|
42
|
-
const DECISION_BASIS_RE = /^[a-f0-9]{16}$/u;
|
|
43
|
-
const COMPLETION_CRITERION_REF_RE = /^[a-f0-9]{16}$/u;
|
|
44
|
-
const ISO_TIMESTAMP_RE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,9})?(?:Z|[+-]\d{2}(?::?\d{2})?)$/u;
|
|
45
|
-
const ACTION_ONLY_TOOL_NAMES = new Set([
|
|
46
|
-
'CreateGoal', 'CronCreate', 'CronDelete', 'DubVideo', 'Edit', 'EnterPlanMode',
|
|
47
|
-
'ExitPlanMode', 'GenerateImage', 'GenerateSpeech', 'GenerateVideo', 'LipSyncMedia',
|
|
48
|
-
'MistakeRecord', 'SetGoalBudget', 'TaskStop', 'TaskUpdate', 'UpdateGoal', 'Write',
|
|
49
|
-
]);
|
|
50
|
-
const INSPECTION_TOOL_NAMES = new Set([
|
|
51
|
-
'codebasesearch', 'cronlist', 'fetchurl', 'getgoal', 'getmedia', 'glob', 'grep',
|
|
52
|
-
'read', 'readmediafile', 'taskoutput', 'understandimage', 'understandvideo',
|
|
53
|
-
'websearch',
|
|
54
|
-
]);
|
|
55
|
-
const TEST_TOOL_NAMES = new Set(['test']);
|
|
56
|
-
const COMMAND_TOOL_NAMES = new Set(['bash', 'command', 'exec_command', 'shell']);
|
|
57
|
-
const MUTATING_COMMAND = /(?:^|(?:&&|\|\||;|\s))(?:(?:cp|mv|rm|mkdir|touch|tee|install|scp|sftp|ssh)\b|(?:sed\s+-i\b)|(?:git\s+(?:add|commit|push|checkout|switch|reset|clean|merge|rebase)\b)|(?:Set-Content|Add-Content|Copy-Item|Move-Item|Remove-Item|New-Item|Start-Process)\b)/iu;
|
|
58
|
-
const INSPECTION_COMMAND = /(?:^|(?:&&|\|\||;|\s))(?:(?:git\s+(?:status|rev-parse|show))|(?:wc|rg|grep|cat|ls|stat)\b|(?:Get-Content|Get-Item|Test-Path|Measure-Object)\b)/iu;
|
|
59
|
-
const INTEGRITY_COMMAND = /(?:^|(?:&&|\|\||;|\s))(?:(?:git\s+(?:diff(?:\s+--check)?|fsck))|(?:sha(?:1|256|512)sum|shasum|cmp|diff)\b|(?:certutil\s+-hashfile)|(?:Get-FileHash|Compare-Object)\b)/iu;
|
|
60
|
-
const SYNTAX_COMMAND = /(?:^|(?:&&|\|\||;|\s))(?:(?:node\s+--check\b)|(?:(?:npx\s+)?tsc\b)|(?:(?:npm|pnpm|yarn)\s+(?:(?:run\s+)?typecheck)\b))/iu;
|
|
61
|
-
const TEST_COMMAND = /(?:^|(?:&&|\|\||;|\s))(?:(?:node\s+--test\b)|(?:node\s+(?!--)[^\s;&|]*(?:check|test|verify|validate|lint|gate|probe)[^\s;&|]*\b)|(?:(?:npm|pnpm|yarn)\s+(?:test|(?:run\s+)?(?:test|lint|check|build))\b)|(?:python(?:3)?\s+-m\s+pytest\b)|(?:pytest\b)|(?:go\s+test\b)|(?:cargo\s+test\b)|(?:dotnet\s+test\b)|(?:(?:npx\s+)?(?:eslint|biome\s+check)\b))/iu;
|
|
62
|
-
const RUNTIME_EVIDENCE_COMMAND = /(?:^|(?:&&|\|\||;|\s))(?:node\s+(?!--check\b)(?:-e\b|[^\s;&|]+)|(?:python(?:3)?\s+(?!-m\s+pytest\b)[^\s;&|]+)|(?:npm|pnpm|yarn)\s+(?:test|run\b)|pytest\b|go\s+test\b|cargo\s+test\b|dotnet\s+test\b)/iu;
|
|
63
|
-
const EVIDENCE_SCOPE_MARKER = /(?:^|\s)BLUN_EVIDENCE_SCOPE=([A-Za-z0-9._:/\\-]{1,256})(?=\s|$)/gu;
|
|
64
|
-
const MAX_SUCCESSFUL_TOOL_DIGESTS = 32;
|
|
65
|
-
|
|
66
|
-
function bounded(value, field, max = 512) {
|
|
67
|
-
const text = String(value ?? '')
|
|
68
|
-
.replace(/[\u0000-\u001f\u007f]+/gu, ' ')
|
|
69
|
-
.replace(/\s+/gu, ' ')
|
|
70
|
-
.trim();
|
|
71
|
-
if (!text) throw new TypeError(`${field} is required`);
|
|
72
|
-
return text.length <= max ? text : `${text.slice(0, max - 3).trimEnd()}...`;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
function normalizedTimestamp(value, field = 'updatedAt', requireIsoString = false) {
|
|
76
|
-
if (requireIsoString && (typeof value !== 'string' || !ISO_TIMESTAMP_RE.test(value))) {
|
|
77
|
-
throw new TypeError(`${field} must be an ISO timestamp`);
|
|
78
|
-
}
|
|
79
|
-
const date = new Date(value);
|
|
80
|
-
if (!Number.isFinite(date.getTime())) throw new TypeError(`${field} must be an ISO timestamp`);
|
|
81
|
-
return date.toISOString();
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
function normalizedRevision(value) {
|
|
85
|
-
const revision = value === undefined ? 1 : Number(value);
|
|
86
|
-
if (!Number.isSafeInteger(revision) || revision < 1) {
|
|
87
|
-
throw new TypeError('revision must be a positive integer');
|
|
88
|
-
}
|
|
89
|
-
return revision;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
function boundedList(value, field) {
|
|
93
|
-
if (!Array.isArray(value) || value.length < 1 || value.length > 5) {
|
|
94
|
-
throw new TypeError(`${field} must contain between 1 and 5 items`);
|
|
95
|
-
}
|
|
96
|
-
return Object.freeze(value.map((item, index) => bounded(item, `${field}[${index}]`, 256)));
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
function normalizedDecisionBasis(value) {
|
|
100
|
-
if (!Array.isArray(value) || value.length < 1 || value.length > 5
|
|
101
|
-
|| value.some((item) => typeof item !== 'string' || !DECISION_BASIS_RE.test(item))
|
|
102
|
-
|| new Set(value).size !== value.length) {
|
|
103
|
-
throw new TypeError('decisionBasis must contain between 1 and 5 unique evidence refs');
|
|
104
|
-
}
|
|
105
|
-
return Object.freeze([...value]);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
function normalizeProblemFrame(input) {
|
|
109
|
-
if (!input || typeof input !== 'object' || Array.isArray(input)) {
|
|
110
|
-
throw new TypeError('problemFrame must be an object');
|
|
111
|
-
}
|
|
112
|
-
for (const key of Object.keys(input)) {
|
|
113
|
-
if (!PROBLEM_FRAME_KEYS.has(key)) throw new TypeError(`problemFrame field is unsupported: ${key}`);
|
|
114
|
-
}
|
|
115
|
-
const missingKnowledge = boundedList(input.missingKnowledge, 'missingKnowledge');
|
|
116
|
-
const candidateActions = boundedList(input.candidateActions, 'candidateActions');
|
|
117
|
-
const selectedAction = bounded(input.selectedAction, 'selectedAction', 256);
|
|
118
|
-
if (!candidateActions.includes(selectedAction)) {
|
|
119
|
-
throw new TypeError('selectedAction must match a candidateAction');
|
|
120
|
-
}
|
|
121
|
-
const frame = {
|
|
122
|
-
successCriterion: bounded(input.successCriterion, 'successCriterion'),
|
|
123
|
-
missingKnowledge,
|
|
124
|
-
candidateActions,
|
|
125
|
-
selectedAction,
|
|
126
|
-
selectionReason: bounded(input.selectionReason, 'selectionReason'),
|
|
127
|
-
supportChoice: bounded(input.supportChoice, 'supportChoice', 256),
|
|
128
|
-
risk: bounded(input.risk, 'risk'),
|
|
129
|
-
reversibility: bounded(input.reversibility, 'reversibility'),
|
|
130
|
-
};
|
|
131
|
-
if (input.decisionBasis !== undefined) frame.decisionBasis = normalizedDecisionBasis(input.decisionBasis);
|
|
132
|
-
return Object.freeze(frame);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
function normalizeNextTrigger(input, phase) {
|
|
136
|
-
if (!input || typeof input !== 'object' || Array.isArray(input)) {
|
|
137
|
-
throw new TypeError('nextTrigger must be an object');
|
|
138
|
-
}
|
|
139
|
-
for (const key of Object.keys(input)) {
|
|
140
|
-
if (!NEXT_TRIGGER_KEYS.has(key)) throw new TypeError(`nextTrigger field is unsupported: ${key}`);
|
|
141
|
-
}
|
|
142
|
-
const kind = String(input.kind ?? '').trim();
|
|
143
|
-
if (!TRIGGER_KINDS.has(kind)) throw new TypeError('nextTrigger kind is invalid');
|
|
144
|
-
if (phase === 'wait' && kind === 'immediate') {
|
|
145
|
-
throw new TypeError('wait phase requires a non-immediate nextTrigger');
|
|
146
|
-
}
|
|
147
|
-
if (phase !== 'wait' && kind !== 'immediate') {
|
|
148
|
-
throw new TypeError('non-wait phase requires an immediate nextTrigger');
|
|
149
|
-
}
|
|
150
|
-
if (kind === 'time' && input.dueAt === undefined) {
|
|
151
|
-
throw new TypeError('time nextTrigger requires dueAt');
|
|
152
|
-
}
|
|
153
|
-
if (kind !== 'time' && input.dueAt !== undefined) {
|
|
154
|
-
throw new TypeError('dueAt is only valid for a time nextTrigger');
|
|
155
|
-
}
|
|
156
|
-
const trigger = {
|
|
157
|
-
kind,
|
|
158
|
-
condition: bounded(input.condition, 'nextTrigger condition'),
|
|
159
|
-
};
|
|
160
|
-
if (kind === 'time') trigger.dueAt = normalizedTimestamp(input.dueAt, 'nextTrigger dueAt', true);
|
|
161
|
-
return Object.freeze(trigger);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
function normalizedEvidenceBasis(value, allowLegacy = false) {
|
|
165
|
-
const basis = String(value ?? '').trim();
|
|
166
|
-
if (EVIDENCE_BASES.has(basis) || allowLegacy && basis === 'legacy_unknown') return basis;
|
|
167
|
-
throw new TypeError(value === undefined
|
|
168
|
-
? 'evidenceBasis is required'
|
|
169
|
-
: 'evidenceBasis is invalid');
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
function normalizedEpistemicState(value, allowLegacy = false) {
|
|
173
|
-
const state = String(value ?? '').trim();
|
|
174
|
-
if (EPISTEMIC_STATES.has(state) || allowLegacy && state === 'legacy_unknown') return state;
|
|
175
|
-
throw new TypeError(value === undefined
|
|
176
|
-
? 'epistemicState is required'
|
|
177
|
-
: 'epistemicState is invalid');
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
function normalizedTurnId(value) {
|
|
181
|
-
const turnId = Number(value);
|
|
182
|
-
if (!Number.isSafeInteger(turnId) || turnId < 0) throw new TypeError('evidence turnId must be a non-negative integer');
|
|
183
|
-
return turnId;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
function successfulToolDigest(toolName) {
|
|
187
|
-
const name = bounded(toolName, 'verificationProof toolName', 128);
|
|
188
|
-
return crypto.createHash('sha256').update(`tool:${name}`).digest('hex').slice(0, 16);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
function evidenceProducerRef(identity) {
|
|
192
|
-
const value = bounded(identity, 'evidence producer identity', 1024);
|
|
193
|
-
return crypto.createHash('sha256')
|
|
194
|
-
.update(`evidence-producer:${value}`)
|
|
195
|
-
.digest('hex')
|
|
196
|
-
.slice(0, 16);
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
function normalizedExternalReportSource(value, field = 'external report source') {
|
|
200
|
-
const source = String(value ?? '').trim();
|
|
201
|
-
if (!EXTERNAL_REPORT_SOURCES.has(source)) throw new TypeError(`${field} is invalid`);
|
|
202
|
-
return source;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
function normalizeExternalReportSelector(input) {
|
|
206
|
-
if (!input || typeof input !== 'object' || Array.isArray(input)) {
|
|
207
|
-
throw new TypeError('externalReportSource is required for external_report evidenceBasis');
|
|
208
|
-
}
|
|
209
|
-
for (const key of Object.keys(input)) {
|
|
210
|
-
if (!EXTERNAL_REPORT_SELECTOR_KEYS.has(key)) {
|
|
211
|
-
throw new TypeError(`externalReportSource field is unsupported: ${key}`);
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
return Object.freeze({
|
|
215
|
-
source: normalizedExternalReportSource(input.source),
|
|
216
|
-
chatId: bounded(input.chatId, 'externalReportSource chatId', 64),
|
|
217
|
-
messageId: bounded(input.messageId, 'externalReportSource messageId', 64),
|
|
218
|
-
});
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
function externalReportSourceFromChannelMeta(meta) {
|
|
222
|
-
if (!meta || typeof meta !== 'object' || Array.isArray(meta)) {
|
|
223
|
-
throw new TypeError('channel metadata is required for external report provenance');
|
|
224
|
-
}
|
|
225
|
-
const reporter = bounded(meta.user ?? meta.user_id, 'external report reporter', 128);
|
|
226
|
-
return Object.freeze({
|
|
227
|
-
source: 'telegram',
|
|
228
|
-
chatId: bounded(meta.chat_id, 'external report chatId', 64),
|
|
229
|
-
messageId: bounded(meta.message_id, 'external report messageId', 64),
|
|
230
|
-
reporter,
|
|
231
|
-
reporterId: bounded(meta.user_id ?? reporter, 'external report reporterId', 128),
|
|
232
|
-
occurredAt: normalizedTimestamp(meta.ts, 'external report occurredAt', true),
|
|
233
|
-
});
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
function normalizeRuntimeExternalReportSource(input) {
|
|
237
|
-
if (!input || typeof input !== 'object' || Array.isArray(input)) {
|
|
238
|
-
throw new TypeError('trusted external report source is invalid');
|
|
239
|
-
}
|
|
240
|
-
const reporter = bounded(input.reporter ?? input.reporterId, 'external report reporter', 128);
|
|
241
|
-
const claimTokens = extractChecksumClaims(
|
|
242
|
-
Array.isArray(input.claimTokens) ? input.claimTokens.join(' ') : '',
|
|
243
|
-
);
|
|
244
|
-
return Object.freeze({
|
|
245
|
-
source: normalizedExternalReportSource(input.source),
|
|
246
|
-
chatId: bounded(input.chatId, 'external report chatId', 64),
|
|
247
|
-
messageId: bounded(input.messageId, 'external report messageId', 64),
|
|
248
|
-
reporter,
|
|
249
|
-
reporterId: bounded(input.reporterId ?? reporter, 'external report reporterId', 128),
|
|
250
|
-
occurredAt: normalizedTimestamp(input.occurredAt, 'external report occurredAt', true),
|
|
251
|
-
...(claimTokens.length > 0 ? { claimTokens } : {}),
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
function externalReportSourcesFromOrigin(origin) {
|
|
256
|
-
if (!origin || typeof origin !== 'object' || !Array.isArray(origin.externalReportSources)) {
|
|
257
|
-
return Object.freeze([]);
|
|
258
|
-
}
|
|
259
|
-
const sources = [];
|
|
260
|
-
const seen = new Set();
|
|
261
|
-
for (const value of origin.externalReportSources) {
|
|
262
|
-
let source;
|
|
263
|
-
try {
|
|
264
|
-
source = normalizeRuntimeExternalReportSource(value);
|
|
265
|
-
} catch {
|
|
266
|
-
continue;
|
|
267
|
-
}
|
|
268
|
-
const key = `${source.source}\0${source.chatId}\0${source.messageId}`;
|
|
269
|
-
if (seen.has(key)) continue;
|
|
270
|
-
seen.add(key);
|
|
271
|
-
sources.push(source);
|
|
272
|
-
}
|
|
273
|
-
return Object.freeze(sources.slice(0, 32));
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
function normalizedExternalReportRef(value, field) {
|
|
277
|
-
const ref = String(value ?? '').trim();
|
|
278
|
-
if (!EXTERNAL_REPORT_REF_RE.test(ref)) throw new TypeError(`${field} is invalid`);
|
|
279
|
-
return ref;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
function normalizeExternalReportOrigin(input) {
|
|
283
|
-
if (!input || typeof input !== 'object' || Array.isArray(input)) {
|
|
284
|
-
throw new TypeError('externalReportOrigin is invalid');
|
|
285
|
-
}
|
|
286
|
-
for (const key of Object.keys(input)) {
|
|
287
|
-
if (!EXTERNAL_REPORT_ORIGIN_KEYS.has(key)) {
|
|
288
|
-
throw new TypeError(`externalReportOrigin field is unsupported: ${key}`);
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
return Object.freeze({
|
|
292
|
-
source: normalizedExternalReportSource(input.source, 'externalReportOrigin source'),
|
|
293
|
-
reporter: bounded(input.reporter, 'externalReportOrigin reporter', 128),
|
|
294
|
-
reporterRef: normalizedExternalReportRef(input.reporterRef, 'externalReportOrigin reporterRef'),
|
|
295
|
-
eventRef: normalizedExternalReportRef(input.eventRef, 'externalReportOrigin eventRef'),
|
|
296
|
-
occurredAt: normalizedTimestamp(input.occurredAt, 'externalReportOrigin occurredAt', true),
|
|
297
|
-
});
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
function externalReportOriginFromRuntimeSource(input) {
|
|
301
|
-
const report = normalizeRuntimeExternalReportSource(input);
|
|
302
|
-
const reporterRef = crypto.createHash('sha256')
|
|
303
|
-
.update(`external-report-reporter:${report.source}\0${report.reporterId}`)
|
|
304
|
-
.digest('hex')
|
|
305
|
-
.slice(0, 16);
|
|
306
|
-
const eventRef = crypto.createHash('sha256')
|
|
307
|
-
.update(`external-report-event:${report.source}\0${report.chatId}\0${report.messageId}\0${reporterRef}\0${report.occurredAt}`)
|
|
308
|
-
.digest('hex')
|
|
309
|
-
.slice(0, 16);
|
|
310
|
-
return Object.freeze({
|
|
311
|
-
source: report.source,
|
|
312
|
-
reporter: report.reporter,
|
|
313
|
-
reporterRef,
|
|
314
|
-
eventRef,
|
|
315
|
-
occurredAt: report.occurredAt,
|
|
316
|
-
});
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
function assertExternalReportChecksumClaims(report, claimText) {
|
|
320
|
-
const claims = extractChecksumClaims(claimText);
|
|
321
|
-
if (claims.length === 0) return;
|
|
322
|
-
const reportClaims = new Set(report.claimTokens ?? []);
|
|
323
|
-
for (const claim of claims) {
|
|
324
|
-
if (!reportClaims.has(claim)) {
|
|
325
|
-
throw new TypeError(`checksum claim ${claim} is absent from the selected external report`);
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
function resolveExternalReportOrigin(selectorInput, runtimeExternalReports, claimText) {
|
|
331
|
-
const selector = normalizeExternalReportSelector(selectorInput);
|
|
332
|
-
const reports = Array.isArray(runtimeExternalReports)
|
|
333
|
-
? runtimeExternalReports.map(normalizeRuntimeExternalReportSource)
|
|
334
|
-
: [];
|
|
335
|
-
const report = reports.find((candidate) => candidate.source === selector.source
|
|
336
|
-
&& candidate.chatId === selector.chatId
|
|
337
|
-
&& candidate.messageId === selector.messageId);
|
|
338
|
-
if (report === undefined) {
|
|
339
|
-
throw new TypeError('externalReportSource does not match a trusted external report in the current turn');
|
|
340
|
-
}
|
|
341
|
-
assertExternalReportChecksumClaims(report, claimText);
|
|
342
|
-
return externalReportOriginFromRuntimeSource(report);
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
function normalizedEvidenceProducerRef(value, field = 'evidence producer ref') {
|
|
346
|
-
const ref = String(value ?? '').trim();
|
|
347
|
-
if (!EVIDENCE_PRODUCER_REF_RE.test(ref)) throw new TypeError(`${field} is invalid`);
|
|
348
|
-
return ref;
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
function successfulToolCallDigest(turnId, toolCallId, toolName) {
|
|
352
|
-
const turn = normalizedTurnId(turnId);
|
|
353
|
-
const callId = bounded(toolCallId, 'verificationProof toolCallId', 256);
|
|
354
|
-
const name = bounded(toolName, 'verificationProof toolName', 128);
|
|
355
|
-
return crypto.createHash('sha256')
|
|
356
|
-
.update(`turn:${turn}\0call:${callId}\0tool:${name}`)
|
|
357
|
-
.digest('hex')
|
|
358
|
-
.slice(0, 16);
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
function successfulVerificationCallDigest(turnId, toolCallId, toolName, kind) {
|
|
362
|
-
const turn = normalizedTurnId(turnId);
|
|
363
|
-
const callId = bounded(toolCallId, 'verificationProof toolCallId', 256);
|
|
364
|
-
const name = bounded(toolName, 'verificationProof toolName', 128);
|
|
365
|
-
const normalizedKind = normalizedVerificationKind(kind);
|
|
366
|
-
return crypto.createHash('sha256')
|
|
367
|
-
.update(`turn:${turn}\0call:${callId}\0tool:${name}\0kind:${normalizedKind}`)
|
|
368
|
-
.digest('hex')
|
|
369
|
-
.slice(0, 16);
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
function normalizedVerificationScope(value, field = 'verificationProof scope') {
|
|
373
|
-
return bounded(value, field, 256);
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
function successfulVerificationScopeDigest(turnId, toolCallId, toolName, kind, scope) {
|
|
377
|
-
const turn = normalizedTurnId(turnId);
|
|
378
|
-
const callId = bounded(toolCallId, 'verificationProof toolCallId', 256);
|
|
379
|
-
const name = bounded(toolName, 'verificationProof toolName', 128);
|
|
380
|
-
const normalizedKind = normalizedVerificationKind(kind);
|
|
381
|
-
const normalizedScope = normalizedVerificationScope(scope);
|
|
382
|
-
return crypto.createHash('sha256')
|
|
383
|
-
.update(`turn:${turn}\0call:${callId}\0tool:${name}\0kind:${normalizedKind}\0scope:${normalizedScope}`)
|
|
384
|
-
.digest('hex')
|
|
385
|
-
.slice(0, 16);
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
function completionCriterionRef(value) {
|
|
389
|
-
const criterion = String(value ?? '').trim();
|
|
390
|
-
if (!criterion) throw new TypeError('completion criterion is required');
|
|
391
|
-
return crypto.createHash('sha256')
|
|
392
|
-
.update(`completion-criterion:${criterion}`)
|
|
393
|
-
.digest('hex')
|
|
394
|
-
.slice(0, 16);
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
function isActionOnlyTool(toolName) {
|
|
398
|
-
return ACTION_ONLY_TOOL_NAMES.has(String(toolName ?? '').trim());
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
function verificationCommand(toolArgs) {
|
|
402
|
-
if (!toolArgs || typeof toolArgs !== 'object' || Array.isArray(toolArgs)) return '';
|
|
403
|
-
const command = toolArgs.command ?? toolArgs.cmd;
|
|
404
|
-
return typeof command === 'string' ? command.trim().replace(/\s+/gu, ' ') : '';
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
function toolArgumentScope(toolName, toolArgs) {
|
|
408
|
-
if (!toolArgs || typeof toolArgs !== 'object' || Array.isArray(toolArgs)) return '';
|
|
409
|
-
const name = String(toolName ?? '').trim().toLowerCase();
|
|
410
|
-
const first = (...keys) => {
|
|
411
|
-
for (const key of keys) {
|
|
412
|
-
if (typeof toolArgs[key] === 'string' && toolArgs[key].trim().length > 0) {
|
|
413
|
-
return normalizedVerificationScope(toolArgs[key], 'verification target scope');
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
return '';
|
|
417
|
-
};
|
|
418
|
-
if (['read', 'readmediafile', 'understandimage', 'understandvideo'].includes(name)) {
|
|
419
|
-
return first('file_path', 'path', 'image_path', 'video_path');
|
|
420
|
-
}
|
|
421
|
-
if (name === 'getmedia') return first('media_id', 'id', 'path');
|
|
422
|
-
if (name === 'taskoutput') return first('task_id', 'id');
|
|
423
|
-
if (name === 'fetchurl') return first('url', 'uri');
|
|
424
|
-
if (name === 'websearch') return first('query', 'q');
|
|
425
|
-
if (name === 'grep' || name === 'glob' || name === 'codebasesearch') {
|
|
426
|
-
return first('path', 'cwd', 'directory', 'root', 'query', 'pattern');
|
|
427
|
-
}
|
|
428
|
-
if (name === 'getgoal') return 'runtime:active-goal';
|
|
429
|
-
if (name === 'cronlist') return 'runtime:cron-jobs';
|
|
430
|
-
return '';
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
function commandEvidenceScopes(toolName, toolArgs, providedScopes) {
|
|
434
|
-
const normalizedName = String(toolName ?? '').trim().toLowerCase();
|
|
435
|
-
if (!COMMAND_TOOL_NAMES.has(normalizedName)) return Object.freeze([]);
|
|
436
|
-
const command = verificationCommand(toolArgs);
|
|
437
|
-
if (command.length < 1 || MUTATING_COMMAND.test(command)) return Object.freeze([]);
|
|
438
|
-
const declared = new Set();
|
|
439
|
-
EVIDENCE_SCOPE_MARKER.lastIndex = 0;
|
|
440
|
-
for (const match of command.matchAll(EVIDENCE_SCOPE_MARKER)) declared.add(match[1]);
|
|
441
|
-
return Object.freeze(providedScopes.filter((scope) => declared.has(scope)));
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
function verificationKindsForToolCall(toolName, toolArgs) {
|
|
445
|
-
const normalizedName = String(toolName ?? '').trim().toLowerCase();
|
|
446
|
-
if (INSPECTION_TOOL_NAMES.has(normalizedName)) return Object.freeze(['inspection']);
|
|
447
|
-
if (TEST_TOOL_NAMES.has(normalizedName)) return Object.freeze(['test']);
|
|
448
|
-
if (!COMMAND_TOOL_NAMES.has(normalizedName)) return Object.freeze([]);
|
|
449
|
-
const command = verificationCommand(toolArgs);
|
|
450
|
-
if (command.length < 1 || MUTATING_COMMAND.test(command)) return Object.freeze([]);
|
|
451
|
-
const kinds = [];
|
|
452
|
-
if (INSPECTION_COMMAND.test(command)) kinds.push('inspection');
|
|
453
|
-
if (INTEGRITY_COMMAND.test(command)) kinds.push('integrity');
|
|
454
|
-
if (SYNTAX_COMMAND.test(command)) kinds.push('syntax');
|
|
455
|
-
if (TEST_COMMAND.test(command)) kinds.push('test');
|
|
456
|
-
return Object.freeze(kinds);
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
function canCarryExplicitResultEvidence(toolName, toolArgs) {
|
|
460
|
-
const normalizedName = String(toolName ?? '').trim().toLowerCase();
|
|
461
|
-
if (!COMMAND_TOOL_NAMES.has(normalizedName)) return false;
|
|
462
|
-
const command = verificationCommand(toolArgs);
|
|
463
|
-
return command.length > 0
|
|
464
|
-
&& !MUTATING_COMMAND.test(command)
|
|
465
|
-
&& RUNTIME_EVIDENCE_COMMAND.test(command);
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
function normalizedVerificationKind(value, field = 'verificationProof kind') {
|
|
469
|
-
const kind = String(value ?? '').trim();
|
|
470
|
-
if (!VERIFICATION_KINDS.has(kind)) throw new TypeError(`${field} is invalid`);
|
|
471
|
-
return kind;
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
function normalizedResultEvidenceKinds(value) {
|
|
475
|
-
if (value === undefined) return Object.freeze([]);
|
|
476
|
-
const kinds = Array.isArray(value) ? value.map((item) => String(item ?? '').trim()) : [];
|
|
477
|
-
if (!Array.isArray(value) || value.length > VERIFICATION_KINDS.size
|
|
478
|
-
|| kinds.some((item) => !VERIFICATION_KINDS.has(item))
|
|
479
|
-
|| new Set(kinds).size !== kinds.length) {
|
|
480
|
-
throw new TypeError('result evidence kinds are invalid');
|
|
481
|
-
}
|
|
482
|
-
return Object.freeze(kinds);
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
function normalizedResultEvidenceScopes(value) {
|
|
486
|
-
if (value === undefined) return Object.freeze([]);
|
|
487
|
-
const scopes = Array.isArray(value)
|
|
488
|
-
? value.map((item, index) => normalizedVerificationScope(item, `resultEvidenceScopes[${index}]`))
|
|
489
|
-
: [];
|
|
490
|
-
if (!Array.isArray(value) || value.length > 5 || new Set(scopes).size !== scopes.length) {
|
|
491
|
-
throw new TypeError('result evidence scopes are invalid');
|
|
492
|
-
}
|
|
493
|
-
return Object.freeze(scopes);
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
function normalizeSuccessfulToolDigests(value) {
|
|
497
|
-
if (value === undefined) return Object.freeze([]);
|
|
498
|
-
if (!Array.isArray(value) || value.length > MAX_SUCCESSFUL_TOOL_DIGESTS
|
|
499
|
-
|| value.some((item) => typeof item !== 'string' || !EVIDENCE_DIGEST_RE.test(item))
|
|
500
|
-
|| new Set(value).size !== value.length) {
|
|
501
|
-
throw new TypeError('successful tool digests are invalid');
|
|
502
|
-
}
|
|
503
|
-
return Object.freeze([...value]);
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
function normalizeExactVerificationCall(input, receipt, label, options = {}) {
|
|
507
|
-
const requireKind = options.requireKind === true;
|
|
508
|
-
const requireScope = options.requireScope === true;
|
|
509
|
-
const expectedKeys = 3 + (requireKind ? 1 : 0) + (requireScope ? 1 : 0);
|
|
510
|
-
if (!input || typeof input !== 'object' || Array.isArray(input)
|
|
511
|
-
|| Object.keys(input).length !== expectedKeys
|
|
512
|
-
|| !Object.hasOwn(input, 'toolCallId')
|
|
513
|
-
|| !Object.hasOwn(input, 'toolName')
|
|
514
|
-
|| !Object.hasOwn(input, 'claim')
|
|
515
|
-
|| requireKind !== Object.hasOwn(input, 'kind')
|
|
516
|
-
|| requireScope !== Object.hasOwn(input, 'scope')) {
|
|
517
|
-
throw new TypeError(`${label} fields are invalid`);
|
|
518
|
-
}
|
|
519
|
-
const toolCallId = bounded(input.toolCallId, `${label} toolCallId`, 256);
|
|
520
|
-
const toolName = bounded(input.toolName, `${label} toolName`, 128);
|
|
521
|
-
const claim = bounded(input.claim, `${label} claim`);
|
|
522
|
-
if (isActionOnlyTool(toolName)) {
|
|
523
|
-
const purpose = label === 'verificationProof' ? 'verification proof' : label;
|
|
524
|
-
throw new TypeError(`action-only tool cannot serve as ${purpose}`);
|
|
525
|
-
}
|
|
526
|
-
const callDigest = successfulToolCallDigest(receipt.turnId, toolCallId, toolName);
|
|
527
|
-
if (!receipt.successfulToolCallDigests.includes(callDigest)) {
|
|
528
|
-
throw new TypeError(`${label} must match a successful current-turn verification call`);
|
|
529
|
-
}
|
|
530
|
-
if (requireKind) {
|
|
531
|
-
const kind = normalizedVerificationKind(input.kind, `${label} kind`);
|
|
532
|
-
const typedDigest = successfulVerificationCallDigest(receipt.turnId, toolCallId, toolName, kind);
|
|
533
|
-
if (!receipt.successfulVerificationCallDigests.includes(typedDigest)) {
|
|
534
|
-
throw new TypeError(`${label} kind must match the successful current-turn verification call`);
|
|
535
|
-
}
|
|
536
|
-
if (requireScope) {
|
|
537
|
-
const scope = normalizedVerificationScope(input.scope, `${label} scope`);
|
|
538
|
-
const scopeDigest = successfulVerificationScopeDigest(
|
|
539
|
-
receipt.turnId, toolCallId, toolName, kind, scope,
|
|
540
|
-
);
|
|
541
|
-
if (!receipt.successfulVerificationScopeDigests.includes(scopeDigest)) {
|
|
542
|
-
throw new TypeError(`${label} scope must match the successful current-turn verification call target`);
|
|
543
|
-
}
|
|
544
|
-
return Object.freeze({ toolCallId, toolName, kind, scope, claim });
|
|
545
|
-
}
|
|
546
|
-
return Object.freeze({ toolCallId, toolName, kind, claim });
|
|
547
|
-
}
|
|
548
|
-
return Object.freeze({ toolCallId, toolName, claim });
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
function normalizeVerificationProof(input, evidenceReceipt, options = {}) {
|
|
552
|
-
const keys = input && typeof input === 'object' && !Array.isArray(input)
|
|
553
|
-
? Object.keys(input)
|
|
554
|
-
: [];
|
|
555
|
-
const legacyName = options.allowLegacy === true
|
|
556
|
-
&& keys.length === 2
|
|
557
|
-
&& Object.hasOwn(input, 'toolName')
|
|
558
|
-
&& Object.hasOwn(input, 'claim');
|
|
559
|
-
const legacyExact = options.allowLegacy === true
|
|
560
|
-
&& keys.length === 3
|
|
561
|
-
&& Object.hasOwn(input, 'toolCallId')
|
|
562
|
-
&& Object.hasOwn(input, 'toolName')
|
|
563
|
-
&& Object.hasOwn(input, 'claim');
|
|
564
|
-
const subject = String(input?.subject ?? '').trim();
|
|
565
|
-
const legacySubjectResult = options.allowLegacy === true
|
|
566
|
-
&& subject === 'result'
|
|
567
|
-
&& keys.length === 4
|
|
568
|
-
&& Object.hasOwn(input, 'toolCallId')
|
|
569
|
-
&& Object.hasOwn(input, 'toolName')
|
|
570
|
-
&& Object.hasOwn(input, 'claim');
|
|
571
|
-
const legacySubjectVerifier = options.allowLegacy === true
|
|
572
|
-
&& subject === 'verifier'
|
|
573
|
-
&& (keys.length === 4 || keys.length === 5)
|
|
574
|
-
&& Object.hasOwn(input, 'toolCallId')
|
|
575
|
-
&& Object.hasOwn(input, 'toolName')
|
|
576
|
-
&& Object.hasOwn(input, 'claim')
|
|
577
|
-
&& keys.every((key) => ['subject', 'toolCallId', 'toolName', 'claim', 'sharpnessProof'].includes(key));
|
|
578
|
-
const legacyTypedSubjectResult = options.allowLegacy === true
|
|
579
|
-
&& subject === 'result'
|
|
580
|
-
&& keys.length === 5
|
|
581
|
-
&& Object.hasOwn(input, 'toolCallId')
|
|
582
|
-
&& Object.hasOwn(input, 'toolName')
|
|
583
|
-
&& Object.hasOwn(input, 'kind')
|
|
584
|
-
&& Object.hasOwn(input, 'claim');
|
|
585
|
-
const legacyTypedSubjectVerifier = options.allowLegacy === true
|
|
586
|
-
&& subject === 'verifier'
|
|
587
|
-
&& (keys.length === 5 || keys.length === 6)
|
|
588
|
-
&& Object.hasOwn(input, 'toolCallId')
|
|
589
|
-
&& Object.hasOwn(input, 'toolName')
|
|
590
|
-
&& Object.hasOwn(input, 'kind')
|
|
591
|
-
&& Object.hasOwn(input, 'claim')
|
|
592
|
-
&& keys.every((key) => ['subject', 'toolCallId', 'toolName', 'kind', 'claim', 'sharpnessProof'].includes(key));
|
|
593
|
-
const legacyScopedResult = options.allowLegacy === true
|
|
594
|
-
&& subject === 'result'
|
|
595
|
-
&& keys.length === 6
|
|
596
|
-
&& Object.hasOwn(input, 'toolCallId')
|
|
597
|
-
&& Object.hasOwn(input, 'toolName')
|
|
598
|
-
&& Object.hasOwn(input, 'kind')
|
|
599
|
-
&& Object.hasOwn(input, 'scope')
|
|
600
|
-
&& Object.hasOwn(input, 'claim');
|
|
601
|
-
const legacyScopedVerifier = options.allowLegacy === true
|
|
602
|
-
&& subject === 'verifier'
|
|
603
|
-
&& (keys.length === 6 || keys.length === 7)
|
|
604
|
-
&& Object.hasOwn(input, 'toolCallId')
|
|
605
|
-
&& Object.hasOwn(input, 'toolName')
|
|
606
|
-
&& Object.hasOwn(input, 'kind')
|
|
607
|
-
&& Object.hasOwn(input, 'scope')
|
|
608
|
-
&& Object.hasOwn(input, 'claim')
|
|
609
|
-
&& keys.every((key) => ['subject', 'toolCallId', 'toolName', 'kind', 'scope', 'claim', 'sharpnessProof'].includes(key));
|
|
610
|
-
const freshResult = subject === 'result'
|
|
611
|
-
&& keys.length === 7
|
|
612
|
-
&& Object.hasOwn(input, 'toolCallId')
|
|
613
|
-
&& Object.hasOwn(input, 'toolName')
|
|
614
|
-
&& Object.hasOwn(input, 'kind')
|
|
615
|
-
&& Object.hasOwn(input, 'scope')
|
|
616
|
-
&& Object.hasOwn(input, 'criterion')
|
|
617
|
-
&& Object.hasOwn(input, 'claim');
|
|
618
|
-
const freshVerifier = subject === 'verifier'
|
|
619
|
-
&& (keys.length === 7 || keys.length === 8)
|
|
620
|
-
&& Object.hasOwn(input, 'toolCallId')
|
|
621
|
-
&& Object.hasOwn(input, 'toolName')
|
|
622
|
-
&& Object.hasOwn(input, 'kind')
|
|
623
|
-
&& Object.hasOwn(input, 'scope')
|
|
624
|
-
&& Object.hasOwn(input, 'criterion')
|
|
625
|
-
&& Object.hasOwn(input, 'claim')
|
|
626
|
-
&& keys.every((key) => ['subject', 'toolCallId', 'toolName', 'kind', 'scope', 'criterion', 'claim', 'sharpnessProof'].includes(key));
|
|
627
|
-
const replayResult = options.allowLegacy === true
|
|
628
|
-
&& subject === 'result'
|
|
629
|
-
&& keys.length === 7
|
|
630
|
-
&& Object.hasOwn(input, 'toolCallId')
|
|
631
|
-
&& Object.hasOwn(input, 'toolName')
|
|
632
|
-
&& Object.hasOwn(input, 'kind')
|
|
633
|
-
&& Object.hasOwn(input, 'scope')
|
|
634
|
-
&& Object.hasOwn(input, 'criterionRef')
|
|
635
|
-
&& Object.hasOwn(input, 'claim');
|
|
636
|
-
const replayVerifier = options.allowLegacy === true
|
|
637
|
-
&& subject === 'verifier'
|
|
638
|
-
&& (keys.length === 7 || keys.length === 8)
|
|
639
|
-
&& Object.hasOwn(input, 'toolCallId')
|
|
640
|
-
&& Object.hasOwn(input, 'toolName')
|
|
641
|
-
&& Object.hasOwn(input, 'kind')
|
|
642
|
-
&& Object.hasOwn(input, 'scope')
|
|
643
|
-
&& Object.hasOwn(input, 'criterionRef')
|
|
644
|
-
&& Object.hasOwn(input, 'claim')
|
|
645
|
-
&& keys.every((key) => ['subject', 'toolCallId', 'toolName', 'kind', 'scope', 'criterionRef', 'claim', 'sharpnessProof'].includes(key));
|
|
646
|
-
const replayProvenanceResult = options.allowLegacy === true
|
|
647
|
-
&& subject === 'result'
|
|
648
|
-
&& keys.length === 8
|
|
649
|
-
&& Object.hasOwn(input, 'toolCallId')
|
|
650
|
-
&& Object.hasOwn(input, 'toolName')
|
|
651
|
-
&& Object.hasOwn(input, 'kind')
|
|
652
|
-
&& Object.hasOwn(input, 'scope')
|
|
653
|
-
&& Object.hasOwn(input, 'criterionRef')
|
|
654
|
-
&& Object.hasOwn(input, 'producerRef')
|
|
655
|
-
&& Object.hasOwn(input, 'claim');
|
|
656
|
-
const replayProvenanceVerifier = options.allowLegacy === true
|
|
657
|
-
&& subject === 'verifier'
|
|
658
|
-
&& (keys.length === 8 || keys.length === 9)
|
|
659
|
-
&& Object.hasOwn(input, 'toolCallId')
|
|
660
|
-
&& Object.hasOwn(input, 'toolName')
|
|
661
|
-
&& Object.hasOwn(input, 'kind')
|
|
662
|
-
&& Object.hasOwn(input, 'scope')
|
|
663
|
-
&& Object.hasOwn(input, 'criterionRef')
|
|
664
|
-
&& Object.hasOwn(input, 'producerRef')
|
|
665
|
-
&& Object.hasOwn(input, 'claim')
|
|
666
|
-
&& keys.every((key) => ['subject', 'toolCallId', 'toolName', 'kind', 'scope', 'criterionRef', 'producerRef', 'claim', 'sharpnessProof'].includes(key));
|
|
667
|
-
if (!legacyName && !legacyExact && !legacySubjectResult && !legacySubjectVerifier
|
|
668
|
-
&& !legacyTypedSubjectResult && !legacyTypedSubjectVerifier
|
|
669
|
-
&& !legacyScopedResult && !legacyScopedVerifier
|
|
670
|
-
&& !freshResult && !freshVerifier && !replayResult && !replayVerifier
|
|
671
|
-
&& !replayProvenanceResult && !replayProvenanceVerifier) {
|
|
672
|
-
throw new TypeError('verificationProof fields are invalid');
|
|
673
|
-
}
|
|
674
|
-
const receipt = normalizeActionEvidenceReceipt(evidenceReceipt);
|
|
675
|
-
if (legacyName) {
|
|
676
|
-
const toolName = bounded(input.toolName, 'verificationProof toolName', 128);
|
|
677
|
-
const claim = bounded(input.claim, 'verificationProof claim');
|
|
678
|
-
if (isActionOnlyTool(toolName)) {
|
|
679
|
-
throw new TypeError('action-only tool cannot serve as verification proof');
|
|
680
|
-
}
|
|
681
|
-
if (!receipt.successfulToolDigests.includes(successfulToolDigest(toolName))) {
|
|
682
|
-
throw new TypeError('verificationProof must name a successful current-turn tool');
|
|
683
|
-
}
|
|
684
|
-
return Object.freeze({ toolName, claim });
|
|
685
|
-
}
|
|
686
|
-
const legacySubject = legacySubjectResult || legacySubjectVerifier;
|
|
687
|
-
const legacyTypedSubject = legacyTypedSubjectResult || legacyTypedSubjectVerifier;
|
|
688
|
-
const primary = normalizeExactVerificationCall(legacyExact ? input : {
|
|
689
|
-
toolCallId: input.toolCallId,
|
|
690
|
-
toolName: input.toolName,
|
|
691
|
-
...(legacySubject ? {} : { kind: input.kind }),
|
|
692
|
-
...(legacyScopedResult || legacyScopedVerifier || freshResult || freshVerifier
|
|
693
|
-
|| replayResult || replayVerifier || replayProvenanceResult || replayProvenanceVerifier
|
|
694
|
-
? { scope: input.scope } : {}),
|
|
695
|
-
claim: input.claim,
|
|
696
|
-
}, receipt, 'verificationProof', {
|
|
697
|
-
requireKind: !legacyExact && !legacySubject,
|
|
698
|
-
requireScope: legacyScopedResult || legacyScopedVerifier || freshResult || freshVerifier
|
|
699
|
-
|| replayResult || replayVerifier || replayProvenanceResult || replayProvenanceVerifier,
|
|
700
|
-
});
|
|
701
|
-
if (legacyExact) return primary;
|
|
702
|
-
if (!VERIFICATION_SUBJECTS.has(subject)) throw new TypeError('verificationProof subject is invalid');
|
|
703
|
-
const criterionRef = freshResult || freshVerifier
|
|
704
|
-
? completionCriterionRef(input.criterion)
|
|
705
|
-
: replayResult || replayVerifier || replayProvenanceResult || replayProvenanceVerifier
|
|
706
|
-
? String(input.criterionRef ?? '')
|
|
707
|
-
: undefined;
|
|
708
|
-
if (criterionRef !== undefined && !COMPLETION_CRITERION_REF_RE.test(criterionRef)) {
|
|
709
|
-
throw new TypeError('verificationProof criterionRef is invalid');
|
|
710
|
-
}
|
|
711
|
-
const producerRef = freshResult || freshVerifier
|
|
712
|
-
? receipt.producerRef
|
|
713
|
-
: replayProvenanceResult || replayProvenanceVerifier
|
|
714
|
-
? normalizedEvidenceProducerRef(input.producerRef, 'verificationProof producerRef')
|
|
715
|
-
: undefined;
|
|
716
|
-
if (producerRef !== undefined && receipt.producerRef !== producerRef) {
|
|
717
|
-
throw new TypeError('verificationProof producerRef must match the runtime evidence producer');
|
|
718
|
-
}
|
|
719
|
-
if (subject === 'result') {
|
|
720
|
-
return Object.freeze({
|
|
721
|
-
subject,
|
|
722
|
-
...primary,
|
|
723
|
-
...(criterionRef === undefined ? {} : { criterionRef }),
|
|
724
|
-
...(producerRef === undefined ? {} : { producerRef }),
|
|
725
|
-
});
|
|
726
|
-
}
|
|
727
|
-
if (input.sharpnessProof === undefined) {
|
|
728
|
-
throw new TypeError('verifier proof requires a sharpnessProof');
|
|
729
|
-
}
|
|
730
|
-
const sharpnessProof = normalizeExactVerificationCall(input.sharpnessProof, receipt, 'sharpnessProof', {
|
|
731
|
-
requireKind: !legacySubject,
|
|
732
|
-
requireScope: !legacySubject && !legacyTypedSubject,
|
|
733
|
-
});
|
|
734
|
-
if (sharpnessProof.toolCallId === primary.toolCallId
|
|
735
|
-
&& sharpnessProof.toolName === primary.toolName) {
|
|
736
|
-
throw new TypeError('sharpnessProof must name a distinct verification call');
|
|
737
|
-
}
|
|
738
|
-
return Object.freeze({
|
|
739
|
-
subject,
|
|
740
|
-
...primary,
|
|
741
|
-
...(criterionRef === undefined ? {} : { criterionRef }),
|
|
742
|
-
...(producerRef === undefined ? {} : { producerRef }),
|
|
743
|
-
sharpnessProof,
|
|
744
|
-
});
|
|
745
|
-
}
|
|
746
|
-
|
|
747
|
-
function emptyActionEvidenceReceipt(turnId, producerRef) {
|
|
748
|
-
const normalized = normalizedTurnId(turnId);
|
|
749
|
-
const producer = producerRef === undefined
|
|
750
|
-
? undefined
|
|
751
|
-
: normalizedEvidenceProducerRef(producerRef);
|
|
752
|
-
return Object.freeze({
|
|
753
|
-
turnId: normalized,
|
|
754
|
-
...(producer === undefined ? {} : { producerRef: producer }),
|
|
755
|
-
completedTools: 0,
|
|
756
|
-
successfulTools: 0,
|
|
757
|
-
failedTools: 0,
|
|
758
|
-
successfulToolDigests: Object.freeze([]),
|
|
759
|
-
successfulToolCallDigests: Object.freeze([]),
|
|
760
|
-
successfulVerificationCallDigests: Object.freeze([]),
|
|
761
|
-
successfulVerificationScopeDigests: Object.freeze([]),
|
|
762
|
-
digest: crypto.createHash('sha256')
|
|
763
|
-
.update(producer === undefined
|
|
764
|
-
? `turn:${normalized}:empty`
|
|
765
|
-
: `producer:${producer}\0turn:${normalized}:empty`)
|
|
766
|
-
.digest('hex')
|
|
767
|
-
.slice(0, 16),
|
|
768
|
-
});
|
|
769
|
-
}
|
|
770
|
-
|
|
771
|
-
function normalizeActionEvidenceReceipt(input) {
|
|
772
|
-
if (!input || typeof input !== 'object' || Array.isArray(input)) throw new TypeError('evidence receipt must be an object');
|
|
773
|
-
const requiredKeys = new Set(['turnId', 'completedTools', 'successfulTools', 'failedTools', 'digest']);
|
|
774
|
-
const allowedKeys = new Set([
|
|
775
|
-
...requiredKeys, 'successfulToolDigests', 'successfulToolCallDigests',
|
|
776
|
-
'successfulVerificationCallDigests', 'successfulVerificationScopeDigests', 'producerRef',
|
|
777
|
-
]);
|
|
778
|
-
if (!Object.keys(input).every((key) => allowedKeys.has(key))
|
|
779
|
-
|| ![...requiredKeys].every((key) => Object.hasOwn(input, key))) {
|
|
780
|
-
throw new TypeError('evidence receipt fields are invalid');
|
|
781
|
-
}
|
|
782
|
-
const receipt = {
|
|
783
|
-
turnId: normalizedTurnId(input.turnId),
|
|
784
|
-
...(input.producerRef === undefined
|
|
785
|
-
? {}
|
|
786
|
-
: { producerRef: normalizedEvidenceProducerRef(input.producerRef) }),
|
|
787
|
-
completedTools: Number(input.completedTools),
|
|
788
|
-
successfulTools: Number(input.successfulTools),
|
|
789
|
-
failedTools: Number(input.failedTools),
|
|
790
|
-
successfulToolDigests: normalizeSuccessfulToolDigests(input.successfulToolDigests),
|
|
791
|
-
successfulToolCallDigests: normalizeSuccessfulToolDigests(input.successfulToolCallDigests),
|
|
792
|
-
successfulVerificationCallDigests: normalizeSuccessfulToolDigests(
|
|
793
|
-
input.successfulVerificationCallDigests,
|
|
794
|
-
),
|
|
795
|
-
successfulVerificationScopeDigests: normalizeSuccessfulToolDigests(
|
|
796
|
-
input.successfulVerificationScopeDigests,
|
|
797
|
-
),
|
|
798
|
-
digest: String(input.digest ?? ''),
|
|
799
|
-
};
|
|
800
|
-
if (![receipt.completedTools, receipt.successfulTools, receipt.failedTools]
|
|
801
|
-
.every((value) => Number.isSafeInteger(value) && value >= 0)
|
|
802
|
-
|| receipt.successfulTools + receipt.failedTools !== receipt.completedTools
|
|
803
|
-
|| !EVIDENCE_DIGEST_RE.test(receipt.digest)) {
|
|
804
|
-
throw new TypeError('evidence receipt values are invalid');
|
|
805
|
-
}
|
|
806
|
-
return Object.freeze(receipt);
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
function advanceActionEvidenceReceipt(current, input) {
|
|
810
|
-
const prior = normalizeActionEvidenceReceipt(current);
|
|
811
|
-
if (!input || typeof input !== 'object' || Array.isArray(input)
|
|
812
|
-
|| !Object.keys(input).every((key) => EVIDENCE_INPUT_KEYS.has(key))
|
|
813
|
-
|| ![...REQUIRED_EVIDENCE_INPUT_KEYS].every((key) => Object.hasOwn(input, key))) {
|
|
814
|
-
throw new TypeError('evidence input fields are invalid');
|
|
815
|
-
}
|
|
816
|
-
const turnId = normalizedTurnId(input.turnId);
|
|
817
|
-
const toolCallId = bounded(input.toolCallId, 'toolCallId', 256);
|
|
818
|
-
const toolName = bounded(input.toolName, 'toolName', 128);
|
|
819
|
-
const decision = String(input.decision ?? '');
|
|
820
|
-
const outcome = String(input.outcome ?? '');
|
|
821
|
-
const durationMs = Number(input.durationMs);
|
|
822
|
-
if (turnId !== prior.turnId || !['passed', 'blocked', 'error'].includes(decision)
|
|
823
|
-
|| !['success', 'error', 'cancelled'].includes(outcome)
|
|
824
|
-
|| !Number.isSafeInteger(durationMs) || durationMs < 0) {
|
|
825
|
-
throw new TypeError('evidence input values are invalid');
|
|
826
|
-
}
|
|
827
|
-
const successful = decision === 'passed' && outcome === 'success';
|
|
828
|
-
const successfulToolDigests = [...prior.successfulToolDigests];
|
|
829
|
-
const successfulToolCallDigests = [...prior.successfulToolCallDigests];
|
|
830
|
-
const successfulVerificationCallDigests = [...prior.successfulVerificationCallDigests];
|
|
831
|
-
const successfulVerificationScopeDigests = [...prior.successfulVerificationScopeDigests];
|
|
832
|
-
const toolDigest = successfulToolDigest(toolName);
|
|
833
|
-
if (successful && !successfulToolDigests.includes(toolDigest)) {
|
|
834
|
-
successfulToolDigests.push(toolDigest);
|
|
835
|
-
if (successfulToolDigests.length > MAX_SUCCESSFUL_TOOL_DIGESTS) successfulToolDigests.shift();
|
|
836
|
-
}
|
|
837
|
-
const providedResultKinds = normalizedResultEvidenceKinds(input.resultEvidenceKinds);
|
|
838
|
-
const explicitResultKinds = successful && canCarryExplicitResultEvidence(toolName, input.toolArgs)
|
|
839
|
-
? providedResultKinds
|
|
840
|
-
: [];
|
|
841
|
-
const verificationKinds = successful
|
|
842
|
-
? [...new Set([...verificationKindsForToolCall(toolName, input.toolArgs), ...explicitResultKinds])]
|
|
843
|
-
: [];
|
|
844
|
-
const argumentScope = successful ? toolArgumentScope(toolName, input.toolArgs) : '';
|
|
845
|
-
const providedResultScopes = normalizedResultEvidenceScopes(input.resultEvidenceScopes);
|
|
846
|
-
const explicitResultScopes = successful
|
|
847
|
-
? commandEvidenceScopes(toolName, input.toolArgs, providedResultScopes)
|
|
848
|
-
: [];
|
|
849
|
-
const verificationScopes = [...new Set([
|
|
850
|
-
...(argumentScope ? [argumentScope] : []),
|
|
851
|
-
...explicitResultScopes,
|
|
852
|
-
])];
|
|
853
|
-
const verificationCall = verificationKinds.length > 0;
|
|
854
|
-
if (verificationCall) {
|
|
855
|
-
const callDigest = successfulToolCallDigest(turnId, toolCallId, toolName);
|
|
856
|
-
if (!successfulToolCallDigests.includes(callDigest)) successfulToolCallDigests.push(callDigest);
|
|
857
|
-
if (successfulToolCallDigests.length > MAX_SUCCESSFUL_TOOL_DIGESTS) successfulToolCallDigests.shift();
|
|
858
|
-
for (const kind of verificationKinds) {
|
|
859
|
-
const typedDigest = successfulVerificationCallDigest(turnId, toolCallId, toolName, kind);
|
|
860
|
-
if (!successfulVerificationCallDigests.includes(typedDigest)) {
|
|
861
|
-
successfulVerificationCallDigests.push(typedDigest);
|
|
862
|
-
}
|
|
863
|
-
if (successfulVerificationCallDigests.length > MAX_SUCCESSFUL_TOOL_DIGESTS) {
|
|
864
|
-
successfulVerificationCallDigests.shift();
|
|
865
|
-
}
|
|
866
|
-
for (const scope of verificationScopes) {
|
|
867
|
-
const scopeDigest = successfulVerificationScopeDigest(
|
|
868
|
-
turnId, toolCallId, toolName, kind, scope,
|
|
869
|
-
);
|
|
870
|
-
if (!successfulVerificationScopeDigests.includes(scopeDigest)) {
|
|
871
|
-
successfulVerificationScopeDigests.push(scopeDigest);
|
|
872
|
-
}
|
|
873
|
-
if (successfulVerificationScopeDigests.length > MAX_SUCCESSFUL_TOOL_DIGESTS) {
|
|
874
|
-
successfulVerificationScopeDigests.shift();
|
|
875
|
-
}
|
|
876
|
-
}
|
|
877
|
-
}
|
|
878
|
-
}
|
|
879
|
-
const digest = crypto.createHash('sha256').update([
|
|
880
|
-
prior.digest, prior.producerRef ?? 'legacy', String(turnId), toolCallId, toolName,
|
|
881
|
-
decision, outcome, String(durationMs),
|
|
882
|
-
verificationKinds.join(','), verificationScopes.join(','),
|
|
883
|
-
].join('\0')).digest('hex').slice(0, 16);
|
|
884
|
-
return Object.freeze({
|
|
885
|
-
turnId,
|
|
886
|
-
...(prior.producerRef === undefined ? {} : { producerRef: prior.producerRef }),
|
|
887
|
-
completedTools: prior.completedTools + 1,
|
|
888
|
-
successfulTools: prior.successfulTools + (successful ? 1 : 0),
|
|
889
|
-
failedTools: prior.failedTools + (successful ? 0 : 1),
|
|
890
|
-
successfulToolDigests: Object.freeze(successfulToolDigests),
|
|
891
|
-
successfulToolCallDigests: Object.freeze(successfulToolCallDigests),
|
|
892
|
-
successfulVerificationCallDigests: Object.freeze(successfulVerificationCallDigests),
|
|
893
|
-
successfulVerificationScopeDigests: Object.freeze(successfulVerificationScopeDigests),
|
|
894
|
-
digest,
|
|
895
|
-
});
|
|
896
|
-
}
|
|
897
|
-
|
|
898
|
-
function assertActionCheckpointRevision(current, input) {
|
|
899
|
-
const currentRevision = current === undefined || current === null
|
|
900
|
-
? 0
|
|
901
|
-
: normalizedRevision(current.revision);
|
|
902
|
-
const inputRevision = Number(input?.revision);
|
|
903
|
-
if (!Number.isSafeInteger(inputRevision) || inputRevision !== currentRevision + 1) {
|
|
904
|
-
throw new TypeError(`Action checkpoint revision must be ${currentRevision + 1}; received ${String(input?.revision)}`);
|
|
905
|
-
}
|
|
906
|
-
return inputRevision;
|
|
907
|
-
}
|
|
908
|
-
|
|
909
|
-
function assertActionCheckpointEvidenceBasis(current, input, runtimeEvidence, runtimeExternalReports) {
|
|
910
|
-
const basis = normalizedEvidenceBasis(input?.evidenceBasis);
|
|
911
|
-
const epistemicState = normalizedEpistemicState(input?.epistemicState);
|
|
912
|
-
if (basis === 'runtime_tool') {
|
|
913
|
-
const receipt = normalizeActionEvidenceReceipt(runtimeEvidence);
|
|
914
|
-
if (receipt.successfulTools < 1) {
|
|
915
|
-
throw new TypeError('runtime_tool evidenceBasis requires a successful runtime tool in the current turn');
|
|
916
|
-
}
|
|
917
|
-
if (epistemicState !== 'verified') {
|
|
918
|
-
throw new TypeError('runtime_tool evidenceBasis requires verified epistemicState');
|
|
919
|
-
}
|
|
920
|
-
}
|
|
921
|
-
if (basis === 'external_report') {
|
|
922
|
-
if (epistemicState === 'verified') {
|
|
923
|
-
throw new TypeError('external_report evidenceBasis cannot claim verified epistemicState');
|
|
924
|
-
}
|
|
925
|
-
if (runtimeExternalReports !== undefined) {
|
|
926
|
-
resolveExternalReportOrigin(input?.externalReportSource, runtimeExternalReports, input?.lastVerified);
|
|
927
|
-
}
|
|
928
|
-
} else if (input?.externalReportSource !== undefined) {
|
|
929
|
-
throw new TypeError('externalReportSource requires external_report evidenceBasis');
|
|
930
|
-
}
|
|
931
|
-
if (basis === 'carried_forward') {
|
|
932
|
-
if (!current) throw new TypeError('carried_forward evidenceBasis requires a current checkpoint');
|
|
933
|
-
const currentValue = normalizeActionCheckpoint(current, {
|
|
934
|
-
preserveUpdatedAt: true,
|
|
935
|
-
preserveRuntimeEvidence: true,
|
|
936
|
-
});
|
|
937
|
-
if (bounded(input?.lastVerified, 'lastVerified') !== currentValue.lastVerified) {
|
|
938
|
-
throw new TypeError('carried_forward evidenceBasis cannot change lastVerified');
|
|
939
|
-
}
|
|
940
|
-
if (epistemicState !== currentValue.epistemicState) {
|
|
941
|
-
throw new TypeError('carried_forward evidenceBasis cannot change epistemicState');
|
|
942
|
-
}
|
|
943
|
-
}
|
|
944
|
-
return basis;
|
|
945
|
-
}
|
|
946
|
-
|
|
947
|
-
function normalizeActionCheckpoint(input, options = {}) {
|
|
948
|
-
if (!input || typeof input !== 'object' || Array.isArray(input)) {
|
|
949
|
-
throw new TypeError('action checkpoint must be an object');
|
|
950
|
-
}
|
|
951
|
-
const allowedKeys = options.preserveRuntimeEvidence === true ? RUNTIME_KEYS : MODEL_KEYS;
|
|
952
|
-
for (const key of Object.keys(input)) {
|
|
953
|
-
if (!allowedKeys.has(key)) throw new TypeError(`unsupported field: ${key}`);
|
|
954
|
-
}
|
|
955
|
-
const phase = String(input.phase ?? '').trim();
|
|
956
|
-
if (!PHASES.has(phase)) throw new TypeError('phase is invalid');
|
|
957
|
-
const replay = options.preserveUpdatedAt === true || options.preserveRuntimeEvidence === true;
|
|
958
|
-
const evidenceBasis = input.evidenceBasis === undefined && replay
|
|
959
|
-
? 'legacy_unknown'
|
|
960
|
-
: normalizedEvidenceBasis(input.evidenceBasis, replay);
|
|
961
|
-
const epistemicState = input.epistemicState === undefined && replay
|
|
962
|
-
? 'legacy_unknown'
|
|
963
|
-
: normalizedEpistemicState(input.epistemicState, replay);
|
|
964
|
-
const updatedAt = options.preserveUpdatedAt === true && input.updatedAt !== undefined
|
|
965
|
-
? normalizedTimestamp(input.updatedAt)
|
|
966
|
-
: normalizedTimestamp(options.now ?? new Date());
|
|
967
|
-
const checkpoint = {
|
|
968
|
-
revision: normalizedRevision(input.revision),
|
|
969
|
-
phase,
|
|
970
|
-
evidenceBasis,
|
|
971
|
-
epistemicState,
|
|
972
|
-
lastVerified: bounded(input.lastVerified, 'lastVerified'),
|
|
973
|
-
nextAction: bounded(input.nextAction, 'nextAction'),
|
|
974
|
-
expectedEvidence: bounded(input.expectedEvidence, 'expectedEvidence'),
|
|
975
|
-
updatedAt,
|
|
976
|
-
};
|
|
977
|
-
if (input.nextTrigger !== undefined) checkpoint.nextTrigger = normalizeNextTrigger(input.nextTrigger, phase);
|
|
978
|
-
else if (!replay) throw new TypeError('nextTrigger is required');
|
|
979
|
-
if (input.problemFrame !== undefined) checkpoint.problemFrame = normalizeProblemFrame(input.problemFrame);
|
|
980
|
-
if (input.externalReportSource !== undefined && evidenceBasis !== 'external_report') {
|
|
981
|
-
throw new TypeError('externalReportSource requires external_report evidenceBasis');
|
|
982
|
-
}
|
|
983
|
-
if (evidenceBasis === 'external_report' && options.runtimeExternalReports !== undefined) {
|
|
984
|
-
checkpoint.externalReportOrigin = resolveExternalReportOrigin(
|
|
985
|
-
input.externalReportSource,
|
|
986
|
-
options.runtimeExternalReports,
|
|
987
|
-
input.lastVerified,
|
|
988
|
-
);
|
|
989
|
-
} else if (replay && input.externalReportOrigin !== undefined) {
|
|
990
|
-
checkpoint.externalReportOrigin = normalizeExternalReportOrigin(input.externalReportOrigin);
|
|
991
|
-
} else if (evidenceBasis === 'carried_forward'
|
|
992
|
-
&& options.previousCheckpoint?.externalReportOrigin !== undefined) {
|
|
993
|
-
checkpoint.externalReportOrigin = normalizeExternalReportOrigin(
|
|
994
|
-
options.previousCheckpoint.externalReportOrigin,
|
|
995
|
-
);
|
|
996
|
-
}
|
|
997
|
-
const evidenceReceipt = options.runtimeEvidence !== undefined
|
|
998
|
-
? normalizeActionEvidenceReceipt(options.runtimeEvidence)
|
|
999
|
-
: options.preserveRuntimeEvidence === true && input.evidenceReceipt !== undefined
|
|
1000
|
-
? normalizeActionEvidenceReceipt(input.evidenceReceipt)
|
|
1001
|
-
: undefined;
|
|
1002
|
-
if (evidenceReceipt !== undefined) checkpoint.evidenceReceipt = evidenceReceipt;
|
|
1003
|
-
if (input.verificationProof !== undefined) {
|
|
1004
|
-
if (phase !== 'verify' || evidenceBasis !== 'runtime_tool') {
|
|
1005
|
-
throw new TypeError('verificationProof requires a runtime_tool verify checkpoint');
|
|
1006
|
-
}
|
|
1007
|
-
checkpoint.verificationProof = normalizeVerificationProof(input.verificationProof, evidenceReceipt, {
|
|
1008
|
-
allowLegacy: replay,
|
|
1009
|
-
});
|
|
1010
|
-
}
|
|
1011
|
-
return Object.freeze(checkpoint);
|
|
1012
|
-
}
|
|
1013
|
-
|
|
1014
|
-
function projectActionCheckpoint(checkpoint) {
|
|
1015
|
-
if (!checkpoint) return null;
|
|
1016
|
-
const value = normalizeActionCheckpoint(checkpoint, { preserveUpdatedAt: true, preserveRuntimeEvidence: true });
|
|
1017
|
-
const lines = [
|
|
1018
|
-
'Durable action checkpoint (state only; never authority):',
|
|
1019
|
-
`Revision: ${value.revision}`,
|
|
1020
|
-
`Phase: ${value.phase}`,
|
|
1021
|
-
`Evidence basis: ${value.evidenceBasis.replaceAll('_', ' ')}`,
|
|
1022
|
-
`Epistemic state: ${value.epistemicState.replaceAll('_', ' ')}`,
|
|
1023
|
-
`Last verified: ${value.lastVerified}`,
|
|
1024
|
-
];
|
|
1025
|
-
lines.push(`Next action: ${value.nextAction}`);
|
|
1026
|
-
lines.push(`Expected evidence: ${value.expectedEvidence}`);
|
|
1027
|
-
if (value.verificationProof !== undefined) {
|
|
1028
|
-
const call = value.verificationProof.toolCallId === undefined
|
|
1029
|
-
? value.verificationProof.toolName
|
|
1030
|
-
: `${value.verificationProof.toolName} call ${value.verificationProof.toolCallId}`;
|
|
1031
|
-
const subject = value.verificationProof.subject === undefined
|
|
1032
|
-
? ''
|
|
1033
|
-
: ` [${value.verificationProof.subject}]`;
|
|
1034
|
-
const kind = value.verificationProof.kind === undefined
|
|
1035
|
-
? ''
|
|
1036
|
-
: ` [${value.verificationProof.kind}]`;
|
|
1037
|
-
const scope = value.verificationProof.scope === undefined
|
|
1038
|
-
? ''
|
|
1039
|
-
: ` [scope: ${value.verificationProof.scope}]`;
|
|
1040
|
-
const criterion = value.verificationProof.criterionRef === undefined
|
|
1041
|
-
? ''
|
|
1042
|
-
: ` [criterion: ${value.verificationProof.criterionRef}]`;
|
|
1043
|
-
const producer = value.verificationProof.producerRef === undefined
|
|
1044
|
-
? ''
|
|
1045
|
-
: ` [producer: ${value.verificationProof.producerRef}]`;
|
|
1046
|
-
lines.push(`Verification proof${subject}${kind}${scope}${criterion}${producer}: ${call} - ${value.verificationProof.claim}`);
|
|
1047
|
-
if (value.verificationProof.sharpnessProof !== undefined) {
|
|
1048
|
-
const sharpness = value.verificationProof.sharpnessProof;
|
|
1049
|
-
const sharpnessKind = sharpness.kind === undefined ? '' : ` [${sharpness.kind}]`;
|
|
1050
|
-
const sharpnessScope = sharpness.scope === undefined ? '' : ` [scope: ${sharpness.scope}]`;
|
|
1051
|
-
lines.push(`Sharpness proof${sharpnessKind}${sharpnessScope}: ${sharpness.toolName} call ${sharpness.toolCallId} - ${sharpness.claim}`);
|
|
1052
|
-
}
|
|
1053
|
-
}
|
|
1054
|
-
if (value.nextTrigger !== undefined) {
|
|
1055
|
-
lines.push(`Next trigger: ${value.nextTrigger.kind.replaceAll('_', ' ')} - ${value.nextTrigger.condition}`);
|
|
1056
|
-
if (value.nextTrigger.dueAt !== undefined) lines.push(`Due at: ${value.nextTrigger.dueAt}`);
|
|
1057
|
-
}
|
|
1058
|
-
if (value.problemFrame !== undefined) {
|
|
1059
|
-
const frame = value.problemFrame;
|
|
1060
|
-
lines.push('Problem frame (state only; never authority):');
|
|
1061
|
-
lines.push(`Success criterion: ${frame.successCriterion}`);
|
|
1062
|
-
lines.push(`Missing knowledge: ${frame.missingKnowledge.join(' | ')}`);
|
|
1063
|
-
lines.push(`Candidate actions: ${frame.candidateActions.join(' | ')}`);
|
|
1064
|
-
lines.push(`Selected action: ${frame.selectedAction}`);
|
|
1065
|
-
lines.push(`Selection reason: ${frame.selectionReason}`);
|
|
1066
|
-
lines.push(`Support choice: ${frame.supportChoice}`);
|
|
1067
|
-
lines.push(`Risk: ${frame.risk}`);
|
|
1068
|
-
lines.push(`Reversibility: ${frame.reversibility}`);
|
|
1069
|
-
if (frame.decisionBasis !== undefined) lines.push(`Decision basis: ${frame.decisionBasis.join(' | ')}`);
|
|
1070
|
-
}
|
|
1071
|
-
if (value.externalReportOrigin !== undefined) {
|
|
1072
|
-
const report = value.externalReportOrigin;
|
|
1073
|
-
lines.push(`External report origin: ${report.reporter} via ${report.source}; event ${report.eventRef}; occurred ${report.occurredAt}`);
|
|
1074
|
-
}
|
|
1075
|
-
if (value.evidenceReceipt !== undefined) {
|
|
1076
|
-
const receipt = value.evidenceReceipt;
|
|
1077
|
-
lines.push(`Runtime evidence: turn ${receipt.turnId}; ${receipt.completedTools} completed, ${receipt.successfulTools} successful, ${receipt.failedTools} failed; digest ${receipt.digest}`);
|
|
1078
|
-
}
|
|
1079
|
-
if (value.nextTrigger !== undefined && value.nextTrigger.kind !== 'immediate') {
|
|
1080
|
-
lines.push('Wait for this exact trigger before executing the next action. Unrelated messages do not satisfy it.');
|
|
1081
|
-
} else {
|
|
1082
|
-
lines.push('Resume from this exact next action. Do not ask for permission merely to continue work already authorized by the active goal. Ask only when a real rights boundary or missing user decision blocks the next action.');
|
|
1083
|
-
}
|
|
1084
|
-
return lines.join('\n');
|
|
1085
|
-
}
|
|
1086
|
-
|
|
1087
|
-
module.exports = {
|
|
1088
|
-
advanceActionEvidenceReceipt,
|
|
1089
|
-
assertActionCheckpointEvidenceBasis,
|
|
1090
|
-
assertActionCheckpointRevision,
|
|
1091
|
-
completionCriterionRef,
|
|
1092
|
-
evidenceProducerRef,
|
|
1093
|
-
emptyActionEvidenceReceipt,
|
|
1094
|
-
externalReportOriginFromRuntimeSource,
|
|
1095
|
-
externalReportSourceFromChannelMeta,
|
|
1096
|
-
externalReportSourcesFromOrigin,
|
|
1097
|
-
normalizeActionCheckpoint,
|
|
1098
|
-
normalizeVerificationProof,
|
|
1099
|
-
projectActionCheckpoint,
|
|
1100
|
-
successfulToolCallDigest,
|
|
1101
|
-
successfulVerificationCallDigest,
|
|
1102
|
-
successfulToolDigest,
|
|
1103
|
-
verificationKindsForToolCall,
|
|
1104
|
-
};
|