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,159 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const crypto = require('node:crypto');
|
|
4
|
-
|
|
5
|
-
const SALIENCE_DECAY = 0.05;
|
|
6
|
-
const SALIENCE_FLOOR = 0.1;
|
|
7
|
-
const SALIENCE_REINFORCEMENT = 0.25;
|
|
8
|
-
const FOCUS_DOMAINS = new Set([
|
|
9
|
-
'self', 'world', 'team', 'goal', 'open_thread', 'assumption', 'knowledge_gap',
|
|
10
|
-
'next_trigger', 'expected_evidence',
|
|
11
|
-
]);
|
|
12
|
-
const ACCESS_KEY_RE = /^focus:access:([a-f0-9]{40})$/u;
|
|
13
|
-
const SAFE_ID_RE = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u;
|
|
14
|
-
|
|
15
|
-
function clean(value, max = 128) {
|
|
16
|
-
const text = String(value ?? '').replace(/[\u0000-\u001f\u007f]+/gu, ' ').replace(/\s+/gu, ' ').trim();
|
|
17
|
-
return text && text.length <= max ? text : '';
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function safeId(value) {
|
|
21
|
-
const text = String(value ?? '').trim();
|
|
22
|
-
return SAFE_ID_RE.test(text) ? text : '';
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function cognitiveEntity(value) {
|
|
26
|
-
const scope = clean(value?.scope, 128);
|
|
27
|
-
const domain = String(value?.domain ?? '');
|
|
28
|
-
const key = clean(value?.key, 128);
|
|
29
|
-
return scope && scope !== 'runtime' && FOCUS_DOMAINS.has(domain) && key
|
|
30
|
-
? { scope, domain, key } : null;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function cognitiveEntityKey(value) {
|
|
34
|
-
const entity = cognitiveEntity(value);
|
|
35
|
-
return entity === null ? '' : `${entity.scope}\0${entity.domain}\0${entity.key}`;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function accessPayload(entity) {
|
|
39
|
-
return JSON.stringify(entity);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function accessDigest(entity) {
|
|
43
|
-
return crypto.createHash('sha256').update(accessPayload(entity)).digest('hex').slice(0, 40);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function focusAccessObservation(value) {
|
|
47
|
-
const entity = cognitiveEntity(value);
|
|
48
|
-
if (entity === null) {
|
|
49
|
-
const error = new Error('COGNITIVE_SALIENCE_INVALID_ENTITY');
|
|
50
|
-
error.code = 'COGNITIVE_SALIENCE_INVALID_ENTITY';
|
|
51
|
-
throw error;
|
|
52
|
-
}
|
|
53
|
-
return {
|
|
54
|
-
domain: 'world',
|
|
55
|
-
key: `focus:access:${accessDigest(entity)}`,
|
|
56
|
-
value: accessPayload(entity),
|
|
57
|
-
confidence: 1,
|
|
58
|
-
scope: 'runtime',
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function parseAccess(item) {
|
|
63
|
-
const match = ACCESS_KEY_RE.exec(String(item?.key ?? ''));
|
|
64
|
-
if (match === null || item?.scope !== 'runtime') return null;
|
|
65
|
-
let parsed;
|
|
66
|
-
try { parsed = JSON.parse(String(item?.value ?? '')); } catch { return null; }
|
|
67
|
-
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)
|
|
68
|
-
|| Object.keys(parsed).sort().join('\0') !== 'domain\0key\0scope') return null;
|
|
69
|
-
const entity = cognitiveEntity(parsed);
|
|
70
|
-
return entity !== null && accessDigest(entity) === match[1] ? entity : null;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
function roundedScore(value) {
|
|
74
|
-
return Math.round(Math.max(SALIENCE_FLOOR, Math.min(1, value)) * 1e12) / 1e12;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function buildCognitiveSalienceIndex(state, { currentSessionId } = {}) {
|
|
78
|
-
const observations = Array.isArray(state?.observations) ? state.observations : [];
|
|
79
|
-
const currentSession = safeId(currentSessionId);
|
|
80
|
-
const sessions = new Map();
|
|
81
|
-
const modifications = new Map();
|
|
82
|
-
const accessBySession = new Map();
|
|
83
|
-
|
|
84
|
-
for (const item of observations) {
|
|
85
|
-
const occurredAt = Date.parse(String(item?.occurred_at ?? ''));
|
|
86
|
-
const contextId = safeId(item?.source?.context_id);
|
|
87
|
-
const runtime = item?.scope === 'runtime' && item?.source?.provider === 'runtime' && contextId;
|
|
88
|
-
if (runtime && Number.isFinite(occurredAt)) {
|
|
89
|
-
const previous = sessions.get(contextId);
|
|
90
|
-
if (previous === undefined || occurredAt < previous) sessions.set(contextId, occurredAt);
|
|
91
|
-
const access = parseAccess(item);
|
|
92
|
-
if (access !== null) {
|
|
93
|
-
const keys = accessBySession.get(contextId) ?? new Set();
|
|
94
|
-
keys.add(cognitiveEntityKey(access));
|
|
95
|
-
accessBySession.set(contextId, keys);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
const entityKey = cognitiveEntityKey(item);
|
|
100
|
-
if (!entityKey || !Number.isFinite(occurredAt)) continue;
|
|
101
|
-
const previous = modifications.get(entityKey);
|
|
102
|
-
if (previous === undefined || occurredAt >= previous.occurredAt) {
|
|
103
|
-
modifications.set(entityKey, { occurredAt, contextId });
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
if (currentSession && !sessions.has(currentSession)) {
|
|
108
|
-
const latest = Math.max(0, ...sessions.values());
|
|
109
|
-
sessions.set(currentSession, latest + 1);
|
|
110
|
-
}
|
|
111
|
-
const timeline = [...sessions.entries()]
|
|
112
|
-
.map(([id, startedAt]) => ({ id, startedAt }))
|
|
113
|
-
.sort((left, right) => left.startedAt - right.startedAt || left.id.localeCompare(right.id));
|
|
114
|
-
const index = new Map();
|
|
115
|
-
|
|
116
|
-
for (const [entityKey, modification] of modifications) {
|
|
117
|
-
let score = 1;
|
|
118
|
-
let active = false;
|
|
119
|
-
const knownModificationSession = modification.contextId && sessions.has(modification.contextId)
|
|
120
|
-
? modification.contextId : '';
|
|
121
|
-
let inferredModificationSession = '';
|
|
122
|
-
if (!knownModificationSession) {
|
|
123
|
-
for (const session of timeline) {
|
|
124
|
-
if (session.startedAt <= modification.occurredAt) inferredModificationSession = session.id;
|
|
125
|
-
else break;
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
const modificationSession = knownModificationSession || inferredModificationSession;
|
|
129
|
-
|
|
130
|
-
for (const session of timeline) {
|
|
131
|
-
if (!active) {
|
|
132
|
-
if (modificationSession) {
|
|
133
|
-
if (session.id !== modificationSession) continue;
|
|
134
|
-
active = true;
|
|
135
|
-
} else {
|
|
136
|
-
if (session.startedAt <= modification.occurredAt) continue;
|
|
137
|
-
active = true;
|
|
138
|
-
score = roundedScore(score - SALIENCE_DECAY);
|
|
139
|
-
}
|
|
140
|
-
} else if (session.id !== modificationSession) {
|
|
141
|
-
score = roundedScore(score - SALIENCE_DECAY);
|
|
142
|
-
}
|
|
143
|
-
if (accessBySession.get(session.id)?.has(entityKey)) {
|
|
144
|
-
score = roundedScore(score + SALIENCE_REINFORCEMENT * (1 - score));
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
index.set(entityKey, roundedScore(score));
|
|
148
|
-
}
|
|
149
|
-
return index;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
module.exports = {
|
|
153
|
-
SALIENCE_DECAY,
|
|
154
|
-
SALIENCE_FLOOR,
|
|
155
|
-
SALIENCE_REINFORCEMENT,
|
|
156
|
-
buildCognitiveSalienceIndex,
|
|
157
|
-
cognitiveEntityKey,
|
|
158
|
-
focusAccessObservation,
|
|
159
|
-
};
|
|
@@ -1,508 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const crypto = require('node:crypto');
|
|
4
|
-
const fs = require('node:fs');
|
|
5
|
-
const path = require('node:path');
|
|
6
|
-
const { DatabaseSync } = require('node:sqlite');
|
|
7
|
-
|
|
8
|
-
const SAFE_ID_RE = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u;
|
|
9
|
-
const DOMAINS = new Set([
|
|
10
|
-
'self', 'world', 'team', 'goal', 'open_thread', 'assumption', 'knowledge_gap',
|
|
11
|
-
'next_trigger', 'expected_evidence',
|
|
12
|
-
]);
|
|
13
|
-
const EPISTEMIC_STATES = new Set([
|
|
14
|
-
'verified', 'credible_unverified', 'hypothesis', 'uncertain_memory', 'stale', 'unknown', 'legacy_unknown',
|
|
15
|
-
]);
|
|
16
|
-
const RETENTION_CLASSES = new Set(['operational', 'durable', 'relationship', 'audit']);
|
|
17
|
-
const FORBIDDEN_KEY_RE = /(?:^|_)(?:acl|api_key|capability|password|permission|secret|token)(?:_|$)/iu;
|
|
18
|
-
const MAX_EVENT_BYTES = 64 * 1024;
|
|
19
|
-
const MAX_OBSERVATIONS = 32;
|
|
20
|
-
|
|
21
|
-
function fail(code) {
|
|
22
|
-
const error = new Error(code);
|
|
23
|
-
error.code = code;
|
|
24
|
-
throw error;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function safeId(value) {
|
|
28
|
-
const text = String(value ?? '').trim();
|
|
29
|
-
return SAFE_ID_RE.test(text) ? text : '';
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function cleanText(value, max = 512) {
|
|
33
|
-
const text = String(value ?? '').replace(/[\u0000-\u001f\u007f]+/gu, ' ').replace(/\s+/gu, ' ').trim();
|
|
34
|
-
return text && text.length <= max ? text : '';
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function hasForbiddenKey(value) {
|
|
38
|
-
if (!value || typeof value !== 'object') return false;
|
|
39
|
-
if (Array.isArray(value)) return value.some(hasForbiddenKey);
|
|
40
|
-
return Object.entries(value).some(([key, child]) => FORBIDDEN_KEY_RE.test(key) || hasForbiddenKey(child));
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function exactKeys(value, keys) {
|
|
44
|
-
return value && typeof value === 'object' && !Array.isArray(value)
|
|
45
|
-
&& Object.keys(value).every((key) => keys.has(key));
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function normalizeSource(source) {
|
|
49
|
-
const allowed = new Set(['provider', 'channel_id', 'actor_id', 'context_id', 'message_id']);
|
|
50
|
-
if (!exactKeys(source, allowed) || hasForbiddenKey(source)) fail('COGNITIVE_FORBIDDEN_FIELD');
|
|
51
|
-
const normalized = {
|
|
52
|
-
provider: safeId(source.provider),
|
|
53
|
-
channel_id: safeId(source.channel_id),
|
|
54
|
-
actor_id: safeId(source.actor_id),
|
|
55
|
-
context_id: safeId(source.context_id),
|
|
56
|
-
message_id: safeId(source.message_id),
|
|
57
|
-
};
|
|
58
|
-
if (Object.values(normalized).some((value) => !value)) fail('COGNITIVE_INVALID_EVENT');
|
|
59
|
-
return normalized;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function normalizeObservation(value) {
|
|
63
|
-
const allowed = new Set(['observation_id', 'domain', 'key', 'value', 'confidence', 'epistemic_state', 'scope', 'supersedes', 'withdraws']);
|
|
64
|
-
if (!exactKeys(value, allowed) || hasForbiddenKey(value)) fail('COGNITIVE_FORBIDDEN_FIELD');
|
|
65
|
-
const observation = {
|
|
66
|
-
observation_id: safeId(value.observation_id),
|
|
67
|
-
domain: String(value.domain ?? ''),
|
|
68
|
-
key: cleanText(value.key, 128),
|
|
69
|
-
value: cleanText(value.value, 2048),
|
|
70
|
-
confidence: Number(value.confidence),
|
|
71
|
-
epistemic_state: value.epistemic_state === undefined
|
|
72
|
-
? 'legacy_unknown' : String(value.epistemic_state),
|
|
73
|
-
scope: cleanText(value.scope, 128),
|
|
74
|
-
};
|
|
75
|
-
if (!observation.observation_id || !DOMAINS.has(observation.domain) || !observation.key
|
|
76
|
-
|| !observation.value || !Number.isFinite(observation.confidence)
|
|
77
|
-
|| observation.confidence < 0 || observation.confidence > 1
|
|
78
|
-
|| !EPISTEMIC_STATES.has(observation.epistemic_state) || !observation.scope) {
|
|
79
|
-
fail('COGNITIVE_INVALID_EVENT');
|
|
80
|
-
}
|
|
81
|
-
if (FORBIDDEN_KEY_RE.test(observation.key)) fail('COGNITIVE_FORBIDDEN_FIELD');
|
|
82
|
-
if (value.supersedes !== undefined && value.supersedes !== null) {
|
|
83
|
-
observation.supersedes = safeId(value.supersedes);
|
|
84
|
-
if (!observation.supersedes || observation.confidence !== 1) fail('COGNITIVE_INVALID_CORRECTION');
|
|
85
|
-
}
|
|
86
|
-
if (value.withdraws !== undefined && value.withdraws !== null) {
|
|
87
|
-
observation.withdraws = safeId(value.withdraws);
|
|
88
|
-
if (!observation.withdraws || observation.confidence !== 1 || observation.value !== 'withdrawn') {
|
|
89
|
-
fail('COGNITIVE_INVALID_WITHDRAWAL');
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
if (observation.supersedes && observation.withdraws) fail('COGNITIVE_INVALID_EVENT');
|
|
93
|
-
return observation;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
function normalizeEvent(input) {
|
|
97
|
-
const allowed = new Set([
|
|
98
|
-
'tenantId', 'agentId', 'eventId', 'expectedVersion', 'occurredAt', 'receivedAt',
|
|
99
|
-
'retentionClass', 'source', 'observations',
|
|
100
|
-
]);
|
|
101
|
-
if (!exactKeys(input, allowed) || hasForbiddenKey(input)) fail('COGNITIVE_FORBIDDEN_FIELD');
|
|
102
|
-
const tenantId = safeId(input.tenantId);
|
|
103
|
-
const agentId = safeId(input.agentId);
|
|
104
|
-
const eventId = safeId(input.eventId);
|
|
105
|
-
const expectedVersion = Number(input.expectedVersion);
|
|
106
|
-
const occurredAt = String(input.occurredAt ?? '').trim();
|
|
107
|
-
const receivedAt = String(input.receivedAt ?? '').trim();
|
|
108
|
-
const retentionClass = String(input.retentionClass ?? '').trim();
|
|
109
|
-
if (!tenantId || !agentId || !eventId || !Number.isSafeInteger(expectedVersion)
|
|
110
|
-
|| expectedVersion < 0 || Number.isNaN(Date.parse(occurredAt))
|
|
111
|
-
|| Number.isNaN(Date.parse(receivedAt)) || !RETENTION_CLASSES.has(retentionClass)
|
|
112
|
-
|| !Array.isArray(input.observations) || input.observations.length < 1
|
|
113
|
-
|| input.observations.length > MAX_OBSERVATIONS) fail('COGNITIVE_INVALID_EVENT');
|
|
114
|
-
const normalized = {
|
|
115
|
-
tenant_id: tenantId,
|
|
116
|
-
agent_id: agentId,
|
|
117
|
-
event_id: eventId,
|
|
118
|
-
expected_version: expectedVersion,
|
|
119
|
-
occurred_at: new Date(occurredAt).toISOString(),
|
|
120
|
-
received_at: new Date(receivedAt).toISOString(),
|
|
121
|
-
retention_class: retentionClass,
|
|
122
|
-
source: normalizeSource(input.source),
|
|
123
|
-
observations: input.observations.map(normalizeObservation),
|
|
124
|
-
};
|
|
125
|
-
const ids = new Set(normalized.observations.map((item) => item.observation_id));
|
|
126
|
-
if (ids.size !== normalized.observations.length) fail('COGNITIVE_INVALID_EVENT');
|
|
127
|
-
const payload = JSON.stringify(normalized);
|
|
128
|
-
if (Buffer.byteLength(payload) > MAX_EVENT_BYTES) fail('COGNITIVE_INVALID_EVENT');
|
|
129
|
-
return { normalized, payload };
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
function ensureHome(home) {
|
|
133
|
-
const root = path.resolve(String(home ?? ''));
|
|
134
|
-
try {
|
|
135
|
-
const stat = fs.lstatSync(root);
|
|
136
|
-
if (!stat.isDirectory() || stat.isSymbolicLink()) fail('COGNITIVE_UNSAFE_HOME');
|
|
137
|
-
return fs.realpathSync(root);
|
|
138
|
-
} catch (error) {
|
|
139
|
-
if (error?.code === 'COGNITIVE_UNSAFE_HOME') throw error;
|
|
140
|
-
fail('COGNITIVE_UNSAFE_HOME');
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
function initialize(db) {
|
|
145
|
-
db.exec(`
|
|
146
|
-
PRAGMA foreign_keys = ON;
|
|
147
|
-
PRAGMA journal_mode = WAL;
|
|
148
|
-
PRAGMA busy_timeout = 5000;
|
|
149
|
-
CREATE TABLE IF NOT EXISTS cognitive_streams (
|
|
150
|
-
tenant_id TEXT NOT NULL,
|
|
151
|
-
agent_id TEXT NOT NULL,
|
|
152
|
-
version INTEGER NOT NULL,
|
|
153
|
-
updated_at TEXT NOT NULL,
|
|
154
|
-
PRIMARY KEY (tenant_id, agent_id)
|
|
155
|
-
);
|
|
156
|
-
CREATE TABLE IF NOT EXISTS cognitive_events (
|
|
157
|
-
event_id TEXT PRIMARY KEY,
|
|
158
|
-
tenant_id TEXT NOT NULL,
|
|
159
|
-
agent_id TEXT NOT NULL,
|
|
160
|
-
expected_version INTEGER NOT NULL,
|
|
161
|
-
new_version INTEGER NOT NULL,
|
|
162
|
-
occurred_at TEXT NOT NULL,
|
|
163
|
-
received_at TEXT NOT NULL,
|
|
164
|
-
retention_class TEXT NOT NULL,
|
|
165
|
-
payload_json TEXT NOT NULL,
|
|
166
|
-
previous_hash TEXT NOT NULL,
|
|
167
|
-
event_hash TEXT NOT NULL UNIQUE
|
|
168
|
-
);
|
|
169
|
-
CREATE TABLE IF NOT EXISTS cognitive_observations (
|
|
170
|
-
observation_id TEXT PRIMARY KEY,
|
|
171
|
-
event_id TEXT NOT NULL REFERENCES cognitive_events(event_id),
|
|
172
|
-
tenant_id TEXT NOT NULL,
|
|
173
|
-
agent_id TEXT NOT NULL,
|
|
174
|
-
domain TEXT NOT NULL,
|
|
175
|
-
fact_key TEXT NOT NULL,
|
|
176
|
-
value_text TEXT NOT NULL,
|
|
177
|
-
confidence REAL NOT NULL,
|
|
178
|
-
epistemic_state TEXT NOT NULL DEFAULT 'legacy_unknown',
|
|
179
|
-
scope TEXT NOT NULL,
|
|
180
|
-
source_json TEXT NOT NULL,
|
|
181
|
-
occurred_at TEXT NOT NULL,
|
|
182
|
-
received_at TEXT NOT NULL,
|
|
183
|
-
retention_class TEXT NOT NULL,
|
|
184
|
-
supersedes_observation_id TEXT,
|
|
185
|
-
withdraws_observation_id TEXT
|
|
186
|
-
);
|
|
187
|
-
CREATE INDEX IF NOT EXISTS cognitive_observations_stream
|
|
188
|
-
ON cognitive_observations (tenant_id, agent_id, occurred_at, observation_id);
|
|
189
|
-
CREATE INDEX IF NOT EXISTS cognitive_observations_visibility
|
|
190
|
-
ON cognitive_observations (tenant_id, agent_id, scope, occurred_at, observation_id);
|
|
191
|
-
CREATE TABLE IF NOT EXISTS cognitive_attention_claims (
|
|
192
|
-
tenant_id TEXT NOT NULL,
|
|
193
|
-
candidate_id TEXT NOT NULL,
|
|
194
|
-
claimed_by TEXT NOT NULL,
|
|
195
|
-
claimed_at TEXT NOT NULL,
|
|
196
|
-
next_allowed_at TEXT NOT NULL,
|
|
197
|
-
PRIMARY KEY (tenant_id, candidate_id)
|
|
198
|
-
);
|
|
199
|
-
CREATE TABLE IF NOT EXISTS cognitive_attention_authorizations (
|
|
200
|
-
tenant_id TEXT NOT NULL,
|
|
201
|
-
receipt_id TEXT NOT NULL,
|
|
202
|
-
candidate_id TEXT NOT NULL,
|
|
203
|
-
authority TEXT NOT NULL,
|
|
204
|
-
authorized_at TEXT NOT NULL,
|
|
205
|
-
accepted INTEGER NOT NULL,
|
|
206
|
-
claimed_by TEXT NOT NULL,
|
|
207
|
-
next_allowed_at TEXT NOT NULL,
|
|
208
|
-
PRIMARY KEY (tenant_id, receipt_id)
|
|
209
|
-
);
|
|
210
|
-
`);
|
|
211
|
-
const observationColumns = db.prepare('PRAGMA table_info(cognitive_observations)').all();
|
|
212
|
-
if (!observationColumns.some((column) => column.name === 'supersedes_observation_id')) {
|
|
213
|
-
db.exec('ALTER TABLE cognitive_observations ADD COLUMN supersedes_observation_id TEXT');
|
|
214
|
-
}
|
|
215
|
-
if (!observationColumns.some((column) => column.name === 'withdraws_observation_id')) {
|
|
216
|
-
db.exec('ALTER TABLE cognitive_observations ADD COLUMN withdraws_observation_id TEXT');
|
|
217
|
-
}
|
|
218
|
-
if (!observationColumns.some((column) => column.name === 'epistemic_state')) {
|
|
219
|
-
db.exec("ALTER TABLE cognitive_observations ADD COLUMN epistemic_state TEXT NOT NULL DEFAULT 'legacy_unknown'");
|
|
220
|
-
}
|
|
221
|
-
if (!observationColumns.some((column) => column.name === 'received_at')) {
|
|
222
|
-
db.exec("ALTER TABLE cognitive_observations ADD COLUMN received_at TEXT NOT NULL DEFAULT ''");
|
|
223
|
-
}
|
|
224
|
-
if (!observationColumns.some((column) => column.name === 'retention_class')) {
|
|
225
|
-
db.exec("ALTER TABLE cognitive_observations ADD COLUMN retention_class TEXT NOT NULL DEFAULT 'legacy_unknown'");
|
|
226
|
-
}
|
|
227
|
-
const eventColumns = db.prepare('PRAGMA table_info(cognitive_events)').all();
|
|
228
|
-
if (!eventColumns.some((column) => column.name === 'received_at')) {
|
|
229
|
-
db.exec("ALTER TABLE cognitive_events ADD COLUMN received_at TEXT NOT NULL DEFAULT ''");
|
|
230
|
-
}
|
|
231
|
-
if (!eventColumns.some((column) => column.name === 'retention_class')) {
|
|
232
|
-
db.exec("ALTER TABLE cognitive_events ADD COLUMN retention_class TEXT NOT NULL DEFAULT 'legacy_unknown'");
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
function openCognitiveStateStore({ home } = {}) {
|
|
237
|
-
const root = ensureHome(home);
|
|
238
|
-
const stateRoot = path.join(root, 'state');
|
|
239
|
-
fs.mkdirSync(stateRoot, { recursive: true });
|
|
240
|
-
if (!fs.realpathSync(stateRoot).startsWith(`${root}${path.sep}`)) fail('COGNITIVE_UNSAFE_HOME');
|
|
241
|
-
const db = new DatabaseSync(path.join(stateRoot, 'cognitive-state.sqlite'));
|
|
242
|
-
initialize(db);
|
|
243
|
-
|
|
244
|
-
function commit(input) {
|
|
245
|
-
const { normalized, payload } = normalizeEvent(input);
|
|
246
|
-
const existing = db.prepare('SELECT payload_json, new_version, event_hash FROM cognitive_events WHERE event_id = ?').get(normalized.event_id);
|
|
247
|
-
if (existing) {
|
|
248
|
-
if (existing.payload_json !== payload) fail('COGNITIVE_EVENT_ID_REUSE');
|
|
249
|
-
return { version: existing.new_version, event_hash: existing.event_hash, idempotent: true };
|
|
250
|
-
}
|
|
251
|
-
db.exec('BEGIN IMMEDIATE');
|
|
252
|
-
try {
|
|
253
|
-
const stream = db.prepare('SELECT version FROM cognitive_streams WHERE tenant_id = ? AND agent_id = ?').get(normalized.tenant_id, normalized.agent_id);
|
|
254
|
-
const actualVersion = Number(stream?.version ?? 0);
|
|
255
|
-
if (actualVersion !== normalized.expected_version) fail('COGNITIVE_VERSION_CONFLICT');
|
|
256
|
-
const previous = db.prepare('SELECT event_hash FROM cognitive_events WHERE tenant_id = ? AND agent_id = ? ORDER BY new_version DESC LIMIT 1').get(normalized.tenant_id, normalized.agent_id);
|
|
257
|
-
const previousHash = String(previous?.event_hash ?? '0'.repeat(64));
|
|
258
|
-
const eventHash = crypto.createHash('sha256').update(`${previousHash}\0${payload}`).digest('hex');
|
|
259
|
-
const newVersion = actualVersion + 1;
|
|
260
|
-
db.prepare(`INSERT INTO cognitive_events
|
|
261
|
-
(event_id, tenant_id, agent_id, expected_version, new_version, occurred_at, received_at, retention_class, payload_json, previous_hash, event_hash)
|
|
262
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
|
|
263
|
-
.run(normalized.event_id, normalized.tenant_id, normalized.agent_id, actualVersion, newVersion,
|
|
264
|
-
normalized.occurred_at, normalized.received_at, normalized.retention_class, payload, previousHash, eventHash);
|
|
265
|
-
const insertObservation = db.prepare(`INSERT INTO cognitive_observations
|
|
266
|
-
(observation_id, event_id, tenant_id, agent_id, domain, fact_key, value_text, confidence, epistemic_state, scope, source_json, occurred_at, received_at, retention_class, supersedes_observation_id, withdraws_observation_id)
|
|
267
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);
|
|
268
|
-
const sourceJson = JSON.stringify(normalized.source);
|
|
269
|
-
for (const observation of normalized.observations) {
|
|
270
|
-
if (observation.supersedes) {
|
|
271
|
-
const target = db.prepare(`SELECT tenant_id, agent_id, domain, fact_key, scope
|
|
272
|
-
FROM cognitive_observations WHERE observation_id = ?`).get(observation.supersedes);
|
|
273
|
-
if (!target || target.tenant_id !== normalized.tenant_id || target.agent_id !== normalized.agent_id
|
|
274
|
-
|| target.domain !== observation.domain || target.fact_key !== observation.key
|
|
275
|
-
|| target.scope !== observation.scope) fail('COGNITIVE_INVALID_CORRECTION');
|
|
276
|
-
}
|
|
277
|
-
if (observation.withdraws) {
|
|
278
|
-
const target = db.prepare(`SELECT tenant_id, agent_id, domain, fact_key, scope
|
|
279
|
-
FROM cognitive_observations WHERE observation_id = ?`).get(observation.withdraws);
|
|
280
|
-
if (!target || target.tenant_id !== normalized.tenant_id || target.agent_id !== normalized.agent_id
|
|
281
|
-
|| target.domain !== observation.domain || target.fact_key !== observation.key
|
|
282
|
-
|| target.scope !== observation.scope) fail('COGNITIVE_INVALID_WITHDRAWAL');
|
|
283
|
-
}
|
|
284
|
-
insertObservation.run(observation.observation_id, normalized.event_id, normalized.tenant_id, normalized.agent_id,
|
|
285
|
-
observation.domain, observation.key, observation.value, observation.confidence, observation.epistemic_state,
|
|
286
|
-
observation.scope, sourceJson,
|
|
287
|
-
normalized.occurred_at, normalized.received_at, normalized.retention_class,
|
|
288
|
-
observation.supersedes ?? null, observation.withdraws ?? null);
|
|
289
|
-
}
|
|
290
|
-
db.prepare(`INSERT INTO cognitive_streams (tenant_id, agent_id, version, updated_at) VALUES (?, ?, ?, ?)
|
|
291
|
-
ON CONFLICT(tenant_id, agent_id) DO UPDATE SET version = excluded.version, updated_at = excluded.updated_at`)
|
|
292
|
-
.run(normalized.tenant_id, normalized.agent_id, newVersion, normalized.occurred_at);
|
|
293
|
-
db.exec('COMMIT');
|
|
294
|
-
return { version: newVersion, event_hash: eventHash };
|
|
295
|
-
} catch (error) {
|
|
296
|
-
try { db.exec('ROLLBACK'); } catch {}
|
|
297
|
-
throw error;
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
function read({ tenantId, agentId, visibilityScope } = {}) {
|
|
302
|
-
const tenant = safeId(tenantId);
|
|
303
|
-
const agent = safeId(agentId);
|
|
304
|
-
const requestedVisibility = visibilityScope === undefined ? '' : safeId(visibilityScope);
|
|
305
|
-
if (!tenant || !agent || (visibilityScope !== undefined && !requestedVisibility)) {
|
|
306
|
-
fail('COGNITIVE_INVALID_EVENT');
|
|
307
|
-
}
|
|
308
|
-
const stream = db.prepare('SELECT version, updated_at FROM cognitive_streams WHERE tenant_id = ? AND agent_id = ?').get(tenant, agent);
|
|
309
|
-
const select = `SELECT domain, fact_key, value_text, confidence, epistemic_state, scope, source_json, occurred_at, received_at,
|
|
310
|
-
retention_class, observation_id,
|
|
311
|
-
supersedes_observation_id, withdraws_observation_id FROM cognitive_observations`;
|
|
312
|
-
const rows = requestedVisibility && requestedVisibility !== 'agent:memory'
|
|
313
|
-
? db.prepare(`${select} WHERE tenant_id = ? AND agent_id = ? AND scope = ? ORDER BY occurred_at, rowid`)
|
|
314
|
-
.all(tenant, agent, requestedVisibility)
|
|
315
|
-
: db.prepare(`${select} WHERE tenant_id = ? AND agent_id = ? ORDER BY occurred_at, rowid`).all(tenant, agent);
|
|
316
|
-
return {
|
|
317
|
-
version: Number(stream?.version ?? 0),
|
|
318
|
-
...(stream?.updated_at ? { updated_at: stream.updated_at } : {}),
|
|
319
|
-
observations: rows.map((row) => ({
|
|
320
|
-
observation_id: row.observation_id,
|
|
321
|
-
domain: row.domain,
|
|
322
|
-
key: row.fact_key,
|
|
323
|
-
value: row.value_text,
|
|
324
|
-
confidence: row.confidence,
|
|
325
|
-
epistemic_state: row.epistemic_state,
|
|
326
|
-
scope: row.scope,
|
|
327
|
-
source: JSON.parse(row.source_json),
|
|
328
|
-
occurred_at: row.occurred_at,
|
|
329
|
-
received_at: row.received_at || row.occurred_at,
|
|
330
|
-
retention_class: row.retention_class || 'legacy_unknown',
|
|
331
|
-
supersedes: row.supersedes_observation_id ?? null,
|
|
332
|
-
withdraws: row.withdraws_observation_id ?? null,
|
|
333
|
-
})),
|
|
334
|
-
};
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
function hasEvent(input) {
|
|
338
|
-
if (input && typeof input === 'object' && !Array.isArray(input)) {
|
|
339
|
-
const keys = Object.keys(input);
|
|
340
|
-
const event = safeId(input.eventId);
|
|
341
|
-
const tenant = safeId(input.tenantId);
|
|
342
|
-
const agent = safeId(input.agentId);
|
|
343
|
-
const visibilityScope = safeId(input.visibilityScope);
|
|
344
|
-
if (keys.length !== 4
|
|
345
|
-
|| !keys.every((key) => ['agentId', 'eventId', 'tenantId', 'visibilityScope'].includes(key))
|
|
346
|
-
|| !event || !tenant || !agent || !visibilityScope) fail('COGNITIVE_INVALID_EVENT');
|
|
347
|
-
if (visibilityScope !== 'agent:memory') {
|
|
348
|
-
return Boolean(db.prepare(`SELECT 1 AS found FROM cognitive_events AS event
|
|
349
|
-
INNER JOIN cognitive_observations AS observation ON observation.event_id = event.event_id
|
|
350
|
-
WHERE event.event_id = ? AND event.tenant_id = ? AND event.agent_id = ? AND observation.scope = ?
|
|
351
|
-
LIMIT 1`).get(event, tenant, agent, visibilityScope));
|
|
352
|
-
}
|
|
353
|
-
return Boolean(db.prepare(`SELECT 1 AS found FROM cognitive_events
|
|
354
|
-
WHERE event_id = ? AND tenant_id = ? AND agent_id = ?`).get(event, tenant, agent));
|
|
355
|
-
}
|
|
356
|
-
const event = safeId(input);
|
|
357
|
-
if (!event) fail('COGNITIVE_INVALID_EVENT');
|
|
358
|
-
return Boolean(db.prepare('SELECT 1 AS found FROM cognitive_events WHERE event_id = ?').get(event));
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
function verify({ tenantId, agentId } = {}) {
|
|
362
|
-
const tenant = safeId(tenantId);
|
|
363
|
-
const agent = safeId(agentId);
|
|
364
|
-
if (!tenant || !agent) fail('COGNITIVE_INVALID_EVENT');
|
|
365
|
-
const rows = db.prepare(`SELECT payload_json, previous_hash, event_hash FROM cognitive_events
|
|
366
|
-
WHERE tenant_id = ? AND agent_id = ? ORDER BY new_version`).all(tenant, agent);
|
|
367
|
-
let previousHash = '0'.repeat(64);
|
|
368
|
-
for (const row of rows) {
|
|
369
|
-
const calculated = crypto.createHash('sha256').update(`${previousHash}\0${row.payload_json}`).digest('hex');
|
|
370
|
-
if (row.previous_hash !== previousHash || row.event_hash !== calculated) return { valid: false, events: rows.length };
|
|
371
|
-
previousHash = row.event_hash;
|
|
372
|
-
}
|
|
373
|
-
return { valid: true, events: rows.length, head_hash: previousHash };
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
function claimAttention(input) {
|
|
377
|
-
const allowedInput = new Set(['tenantId', 'candidate', 'claimedBy', 'claimedAt']);
|
|
378
|
-
const allowedCandidate = new Set([
|
|
379
|
-
'candidate_id', 'subject_kind', 'subject_id', 'reason', 'responsible_agent',
|
|
380
|
-
'evidence_id', 'evidence_scope', 'evidence_at', 'confidence', 'allowed_channel',
|
|
381
|
-
'detected_at', 'cooldown_ms', 'requires_runtime_authorization',
|
|
382
|
-
]);
|
|
383
|
-
if (!exactKeys(input, allowedInput) || !exactKeys(input.candidate, allowedCandidate)
|
|
384
|
-
|| hasForbiddenKey(input)) fail('COGNITIVE_FORBIDDEN_FIELD');
|
|
385
|
-
const tenant = safeId(input.tenantId);
|
|
386
|
-
const candidateId = safeId(input.candidate.candidate_id);
|
|
387
|
-
const claimedBy = safeId(input.claimedBy);
|
|
388
|
-
const claimedAtMs = Date.parse(String(input.claimedAt ?? ''));
|
|
389
|
-
const cooldownMs = Number(input.candidate.cooldown_ms);
|
|
390
|
-
if (!tenant || !candidateId || !claimedBy || !Number.isFinite(claimedAtMs)
|
|
391
|
-
|| !Number.isSafeInteger(cooldownMs) || cooldownMs < 1000
|
|
392
|
-
|| input.candidate.requires_runtime_authorization !== true) fail('COGNITIVE_INVALID_EVENT');
|
|
393
|
-
const claimedAt = new Date(claimedAtMs).toISOString();
|
|
394
|
-
const nextAllowedAt = new Date(claimedAtMs + cooldownMs).toISOString();
|
|
395
|
-
db.exec('BEGIN IMMEDIATE');
|
|
396
|
-
try {
|
|
397
|
-
const existing = db.prepare(`SELECT claimed_by, next_allowed_at FROM cognitive_attention_claims
|
|
398
|
-
WHERE tenant_id = ? AND candidate_id = ?`).get(tenant, candidateId);
|
|
399
|
-
if (existing && Date.parse(existing.next_allowed_at) > claimedAtMs) {
|
|
400
|
-
db.exec('COMMIT');
|
|
401
|
-
return {
|
|
402
|
-
claimed: false,
|
|
403
|
-
claimed_by: existing.claimed_by,
|
|
404
|
-
next_allowed_at: existing.next_allowed_at,
|
|
405
|
-
};
|
|
406
|
-
}
|
|
407
|
-
db.prepare(`INSERT INTO cognitive_attention_claims
|
|
408
|
-
(tenant_id, candidate_id, claimed_by, claimed_at, next_allowed_at) VALUES (?, ?, ?, ?, ?)
|
|
409
|
-
ON CONFLICT(tenant_id, candidate_id) DO UPDATE SET
|
|
410
|
-
claimed_by = excluded.claimed_by,
|
|
411
|
-
claimed_at = excluded.claimed_at,
|
|
412
|
-
next_allowed_at = excluded.next_allowed_at`)
|
|
413
|
-
.run(tenant, candidateId, claimedBy, claimedAt, nextAllowedAt);
|
|
414
|
-
db.exec('COMMIT');
|
|
415
|
-
return { claimed: true, claimed_by: claimedBy, next_allowed_at: nextAllowedAt };
|
|
416
|
-
} catch (error) {
|
|
417
|
-
try { db.exec('ROLLBACK'); } catch {}
|
|
418
|
-
throw error;
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
function authorizeAttention(input) {
|
|
423
|
-
const allowedInput = new Set([
|
|
424
|
-
'tenantId', 'candidate', 'claimedBy', 'claimedAt', 'receiptId', 'authority', 'authorizedAt',
|
|
425
|
-
]);
|
|
426
|
-
const allowedCandidate = new Set([
|
|
427
|
-
'candidate_id', 'subject_kind', 'subject_id', 'reason', 'responsible_agent',
|
|
428
|
-
'evidence_id', 'evidence_scope', 'evidence_at', 'confidence', 'allowed_channel',
|
|
429
|
-
'detected_at', 'cooldown_ms', 'requires_runtime_authorization',
|
|
430
|
-
]);
|
|
431
|
-
if (!exactKeys(input, allowedInput) || !exactKeys(input.candidate, allowedCandidate)
|
|
432
|
-
|| hasForbiddenKey({ candidate: input.candidate })) fail('COGNITIVE_FORBIDDEN_FIELD');
|
|
433
|
-
const tenant = safeId(input.tenantId);
|
|
434
|
-
const candidateId = safeId(input.candidate.candidate_id);
|
|
435
|
-
const claimedBy = safeId(input.claimedBy);
|
|
436
|
-
const receiptId = safeId(input.receiptId);
|
|
437
|
-
const authority = safeId(input.authority);
|
|
438
|
-
const claimedAtMs = Date.parse(String(input.claimedAt ?? ''));
|
|
439
|
-
const authorizedAtMs = Date.parse(String(input.authorizedAt ?? ''));
|
|
440
|
-
const cooldownMs = Number(input.candidate.cooldown_ms);
|
|
441
|
-
if (!tenant || !candidateId || !claimedBy || !receiptId || !authority
|
|
442
|
-
|| !Number.isFinite(claimedAtMs) || !Number.isFinite(authorizedAtMs)
|
|
443
|
-
|| !Number.isSafeInteger(cooldownMs) || cooldownMs < 1000
|
|
444
|
-
|| input.candidate.requires_runtime_authorization !== true) fail('COGNITIVE_INVALID_EVENT');
|
|
445
|
-
const claimedAt = new Date(claimedAtMs).toISOString();
|
|
446
|
-
const authorizedAt = new Date(authorizedAtMs).toISOString();
|
|
447
|
-
const nextAllowedAt = new Date(claimedAtMs + cooldownMs).toISOString();
|
|
448
|
-
db.exec('BEGIN IMMEDIATE');
|
|
449
|
-
try {
|
|
450
|
-
const receipt = db.prepare(`SELECT candidate_id, accepted, claimed_by, next_allowed_at
|
|
451
|
-
FROM cognitive_attention_authorizations WHERE tenant_id = ? AND receipt_id = ?`).get(tenant, receiptId);
|
|
452
|
-
if (receipt) {
|
|
453
|
-
if (receipt.candidate_id !== candidateId) fail('COGNITIVE_ATTENTION_RECEIPT_REUSE');
|
|
454
|
-
db.exec('COMMIT');
|
|
455
|
-
return {
|
|
456
|
-
claimed: receipt.accepted === 1,
|
|
457
|
-
claimed_by: receipt.claimed_by,
|
|
458
|
-
next_allowed_at: receipt.next_allowed_at,
|
|
459
|
-
idempotent: true,
|
|
460
|
-
};
|
|
461
|
-
}
|
|
462
|
-
const existing = db.prepare(`SELECT claimed_by, next_allowed_at FROM cognitive_attention_claims
|
|
463
|
-
WHERE tenant_id = ? AND candidate_id = ?`).get(tenant, candidateId);
|
|
464
|
-
const accepted = !(existing && Date.parse(existing.next_allowed_at) > claimedAtMs);
|
|
465
|
-
const effectiveClaimedBy = accepted ? claimedBy : existing.claimed_by;
|
|
466
|
-
const effectiveNextAllowedAt = accepted ? nextAllowedAt : existing.next_allowed_at;
|
|
467
|
-
if (accepted) {
|
|
468
|
-
db.prepare(`INSERT INTO cognitive_attention_claims
|
|
469
|
-
(tenant_id, candidate_id, claimed_by, claimed_at, next_allowed_at) VALUES (?, ?, ?, ?, ?)
|
|
470
|
-
ON CONFLICT(tenant_id, candidate_id) DO UPDATE SET
|
|
471
|
-
claimed_by = excluded.claimed_by,
|
|
472
|
-
claimed_at = excluded.claimed_at,
|
|
473
|
-
next_allowed_at = excluded.next_allowed_at`)
|
|
474
|
-
.run(tenant, candidateId, claimedBy, claimedAt, nextAllowedAt);
|
|
475
|
-
}
|
|
476
|
-
db.prepare(`INSERT INTO cognitive_attention_authorizations
|
|
477
|
-
(tenant_id, receipt_id, candidate_id, authority, authorized_at, accepted, claimed_by, next_allowed_at)
|
|
478
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`)
|
|
479
|
-
.run(tenant, receiptId, candidateId, authority, authorizedAt, accepted ? 1 : 0,
|
|
480
|
-
effectiveClaimedBy, effectiveNextAllowedAt);
|
|
481
|
-
db.exec('COMMIT');
|
|
482
|
-
return {
|
|
483
|
-
claimed: accepted,
|
|
484
|
-
claimed_by: effectiveClaimedBy,
|
|
485
|
-
next_allowed_at: effectiveNextAllowedAt,
|
|
486
|
-
idempotent: false,
|
|
487
|
-
};
|
|
488
|
-
} catch (error) {
|
|
489
|
-
try { db.exec('ROLLBACK'); } catch {}
|
|
490
|
-
throw error;
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
return {
|
|
495
|
-
commit,
|
|
496
|
-
hasEvent,
|
|
497
|
-
read,
|
|
498
|
-
verify,
|
|
499
|
-
claimAttention,
|
|
500
|
-
authorizeAttention,
|
|
501
|
-
close: () => {
|
|
502
|
-
try { db.exec('PRAGMA wal_checkpoint(TRUNCATE)'); } catch {}
|
|
503
|
-
db.close();
|
|
504
|
-
},
|
|
505
|
-
};
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
module.exports = { openCognitiveStateStore };
|