@moretea-labs/forge 1.8.0 → 1.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +70 -7
- package/CHANGELOG.md +14 -0
- package/CLAUDE.md +17 -2
- package/CONTRIBUTING.md +3 -2
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/adapters/chatgpt/browser-delivery-host.ts +7 -1
- package/adapters/chatgpt/browser-delivery-runtime.ts +529 -56
- package/adapters/chatgpt/controller-binding-store.ts +101 -22
- package/adapters/chatgpt/controller-round-host.ts +15 -25
- package/adapters/chatgpt/controller-round-settlement-store.ts +58 -4
- package/adapters/chatgpt/provider-delivery.ts +228 -1
- package/adapters/chatgpt/work-conversation-binding-store.ts +79 -53
- package/adapters/computer/chatgpt-extension-target.ts +463 -0
- package/adapters/computer/chatgpt-target-router.ts +103 -0
- package/adapters/computer/chrome-extension/background.js +385 -0
- package/adapters/computer/chrome-extension/content.js +378 -0
- package/adapters/computer/chrome-extension/core.js +24 -0
- package/adapters/computer/chrome-extension/manifest.json +30 -0
- package/adapters/computer/desktop-operator-discovery.ts +11 -31
- package/adapters/computer/interaction-target-authority.ts +142 -18
- package/adapters/mcp/auth.ts +0 -1
- package/adapters/mcp/instructions.ts +5 -4
- package/adapters/mcp/multi-repository.ts +3 -19
- package/adapters/mcp/oauth.ts +73 -0
- package/adapters/mcp/paths.ts +4 -1
- package/adapters/mcp/runtime-gateway/automation-receipt-adapter.ts +87 -0
- package/adapters/mcp/runtime-gateway/bounded-result-runtime.ts +62 -0
- package/adapters/mcp/runtime-gateway/cognition-settlement.ts +201 -0
- package/adapters/mcp/runtime-gateway/context-adapter.ts +411 -73
- package/adapters/mcp/runtime-gateway/context-pack-sidecar.ts +91 -0
- package/adapters/mcp/runtime-gateway/controller-authority-adapter.ts +20 -5
- package/adapters/mcp/runtime-gateway/core-capability-adapter.ts +258 -0
- package/adapters/mcp/runtime-gateway/engineering-preconditions.ts +10 -27
- package/adapters/mcp/runtime-gateway/engineering-tool-contract.ts +15 -0
- package/adapters/mcp/runtime-gateway/execution-tools.ts +8 -42
- package/adapters/mcp/runtime-gateway/gateway-execution-adapter.ts +2 -1
- package/adapters/mcp/runtime-gateway/plugin-adapter.ts +117 -45
- package/adapters/mcp/runtime-gateway/process-tools.ts +190 -22
- package/adapters/mcp/runtime-gateway/protected-computer-adapter.ts +16 -4
- package/adapters/mcp/runtime-gateway/recovery-adapter.ts +69 -52
- package/adapters/mcp/runtime-gateway/repository-compat-adapter.ts +4 -35
- package/adapters/mcp/runtime-gateway/result-adapter.ts +10 -4
- package/adapters/mcp/runtime-gateway/router.ts +18 -504
- package/adapters/mcp/runtime-gateway/routing-policy.ts +499 -0
- package/adapters/mcp/runtime-gateway/runtime-observation-adapter.ts +14 -65
- package/adapters/mcp/runtime-gateway/runtime-readiness-observation.ts +218 -0
- package/adapters/mcp/runtime-gateway/runtime-tool-definitions.ts +113 -173
- package/adapters/mcp/runtime-gateway/runtime-tools.ts +15 -5
- package/adapters/mcp/runtime-gateway/scheduler-adapter.ts +1 -0
- package/adapters/mcp/runtime-gateway/shared-adapter.ts +20 -0
- package/adapters/mcp/runtime-gateway/status-inbox-adapter.ts +358 -266
- package/adapters/mcp/runtime-gateway/typescript-navigation-sidecar.ts +136 -0
- package/adapters/mcp/runtime-gateway/work-adapter.ts +261 -3122
- package/adapters/mcp/runtime-gateway/work-controller-operations.ts +257 -0
- package/adapters/mcp/runtime-gateway/work-detail-projection.ts +60 -0
- package/adapters/mcp/runtime-gateway/work-input-wire-migration.ts +246 -0
- package/adapters/mcp/runtime-gateway/work-learning-operations.ts +145 -0
- package/adapters/mcp/runtime-gateway/work-list-projection.ts +38 -0
- package/adapters/mcp/runtime-gateway/work-plan-operations.ts +382 -0
- package/adapters/mcp/runtime-gateway/work-repair-adapter.ts +308 -0
- package/adapters/mcp/runtime-gateway/work-requirement-operations.ts +148 -0
- package/adapters/mcp/runtime-gateway/work-semantic-operations.ts +263 -0
- package/adapters/mcp/runtime-gateway/work-workflow-operations.ts +113 -0
- package/adapters/mcp/runtime-gateway/workflow-supervisor-adapter.ts +156 -0
- package/adapters/mcp/server.ts +67 -23
- package/adapters/mcp/setup.ts +1 -3
- package/adapters/mcp/tool-mapping/legacy-tool-service.ts +44 -170
- package/adapters/mcp/tool-mapping/post-finalize-work-attribution.ts +4 -9
- package/adapters/mcp/tool-mapping/repository-tools.ts +133 -142
- package/adapters/mcp/toolset-names.ts +5 -0
- package/adapters/mcp/toolset.ts +6 -5
- package/adapters/mcp/transports/http-observation.ts +365 -0
- package/adapters/mcp/transports/http.ts +154 -677
- package/adapters/mcp/transports/oauth-http.ts +322 -0
- package/adapters/mcp/transports/session-registry.ts +6 -0
- package/adapters/mcp/tunnels/openai-secure-tunnel.ts +89 -5
- package/assets/plugin-registry.v1.json +6 -4
- package/assets/reference-configs/agentic-development-flow.md +25 -0
- package/assets/reference-configs/global-working-rules.md +19 -0
- package/assets/skill-version.json +2 -2
- package/docs/architecture/CURRENT.md +111 -41
- package/docs/architecture/decisions/20260803-release-identity-binding-and-exit-policy.md +14 -5
- package/docs/architecture/decisions/20260823-immediate-controller-relay.md +6 -3
- package/docs/architecture/decisions/20260907-assistant-learning-loop.md +2 -0
- package/docs/architecture/decisions/20260907-controller-round-transition-policy.md +19 -4
- package/docs/architecture/decisions/20260916-workflow-supervisor-authority.md +249 -0
- package/docs/architecture/decisions/20260917-cognitive-memory-foundation.md +82 -0
- package/docs/architecture/decisions/20260918-stable-candidate-release-lifecycle.md +221 -0
- package/docs/architecture/decisions/20260919-autonomous-work-liveness.md +62 -0
- package/docs/architecture/decisions/20260924-thin-semantic-working-context.md +72 -0
- package/docs/architecture/decisions/20261001-supervisor-turn-authority.md +237 -0
- package/docs/architecture/decisions/20261005-forge-v3-desktop-client-boundary.md +77 -0
- package/docs/architecture/domains/verification.md +1 -0
- package/docs/architecture/domains/workflow-engine.md +6 -0
- package/docs/architecture/modules/controller-runtime/transport-lifecycle.md +1 -1
- package/docs/forge-plugin-management.md +2 -2
- package/docs/operations/controller-performance-and-502.md +17 -0
- package/docs/operations/controller-reliability-runbook.md +2 -2
- package/docs/operations/features.md +1 -1
- package/docs/operations/features.zh-CN.md +1 -1
- package/docs/operations/homebrew.md +2 -2
- package/docs/operations/mcp-tool-exposure.md +2 -0
- package/docs/operations/releasing.md +2 -0
- package/docs/operations/standalone-disaster-recovery.md +14 -6
- package/docs/wiki/Implementation.md +1 -1
- package/package.json +25 -14
- package/packages/kernel/cognition/api/index.ts +6 -0
- package/packages/kernel/cognition/application/activation-service.ts +451 -0
- package/packages/kernel/cognition/application/consolidation-service.ts +185 -0
- package/packages/kernel/cognition/application/legacy-experience-adapter.ts +38 -0
- package/packages/kernel/cognition/application/memory-service.ts +64 -0
- package/packages/kernel/cognition/domain/learning.ts +106 -0
- package/packages/kernel/cognition/domain/memory.ts +254 -0
- package/packages/kernel/controller/api/index.ts +1 -0
- package/packages/kernel/controller/application/continuation-service.ts +281 -0
- package/packages/kernel/controller/application/controller-round-service.ts +12 -0
- package/packages/kernel/controller/domain/controller-round-transition-policy.ts +242 -21
- package/packages/kernel/controller/domain/controller-round.ts +4 -1
- package/packages/kernel/controller/domain/execution-quality.ts +3 -1
- package/packages/kernel/controller/infrastructure/controller-round-store.ts +689 -103
- package/packages/kernel/controller/infrastructure/controller-session-store.ts +297 -71
- package/packages/kernel/controller/ports/controller-host.ts +2 -0
- package/packages/kernel/identity/api/index.ts +10 -0
- package/packages/kernel/identity/domain/activity-projection.ts +43 -0
- package/packages/kernel/identity/domain/capability-broker.ts +60 -0
- package/packages/kernel/identity/domain/grant.ts +72 -0
- package/packages/kernel/identity/domain/owned-resource.ts +116 -0
- package/packages/kernel/identity/domain/user-request.ts +93 -0
- package/packages/kernel/identity/infrastructure/activity-projection-store.ts +77 -0
- package/packages/kernel/identity/infrastructure/capability-broker.ts +81 -0
- package/packages/kernel/identity/infrastructure/grant-store.ts +284 -0
- package/packages/kernel/identity/infrastructure/owned-resource-store.ts +259 -0
- package/packages/kernel/identity/infrastructure/user-request-store.ts +182 -0
- package/packages/kernel/scheduler/api/index.ts +0 -2
- package/packages/kernel/scheduler/application/schedule-service.ts +3 -0
- package/packages/kernel/scheduler/application/settlement.ts +0 -15
- package/packages/kernel/scheduler/domain/schedule.ts +87 -0
- package/packages/kernel/scheduler/infrastructure/schedule-store.ts +153 -133
- package/packages/kernel/work/api/index.ts +3 -2
- package/packages/kernel/work/application/work-service.ts +17 -42
- package/packages/kernel/work/domain/current-task-lineage.ts +104 -0
- package/packages/kernel/work/domain/engineering-design.ts +10 -5
- package/packages/kernel/work/domain/engineering-profile.ts +8 -12
- package/packages/kernel/work/domain/evaluation-promotion-receipt.ts +186 -0
- package/packages/kernel/work/domain/execution-concurrency.ts +19 -26
- package/packages/kernel/work/domain/execution-snapshot.ts +0 -31
- package/packages/kernel/work/domain/implementation-review.ts +14 -331
- package/packages/kernel/work/domain/objective-graph.ts +119 -0
- package/packages/kernel/work/domain/project-engineering-contract.ts +23 -1
- package/packages/kernel/work/domain/repository-completion-receipt.ts +1 -1
- package/packages/kernel/work/domain/state-machine.ts +25 -63
- package/packages/kernel/work/domain/types.ts +57 -51
- package/packages/kernel/work/infrastructure/work-contract-store.ts +819 -728
- package/packages/kernel/work/ports/work-contract-store.ts +5 -2
- package/packages/plugin-runtime/browser/session-authority.ts +2 -1
- package/packages/plugin-runtime/computer/chatgpt-identity.ts +24 -0
- package/packages/plugin-runtime/computer/conversation-target.ts +143 -0
- package/packages/plugin-runtime/computer/index.ts +2 -0
- package/packages/plugin-runtime/computer/target-authority.ts +26 -1
- package/packages/plugin-runtime/external/unix-jsonl-transport.ts +142 -18
- package/packages/protocols/computer/contract.ts +27 -1
- package/scripts/activate-source-baseline.ts +7 -9
- package/scripts/canary-controller-semantic-wait.ts +12 -24
- package/scripts/check-mcp-compatibility.ts +48 -136
- package/scripts/check-runtime-architecture.mjs +622 -217
- package/scripts/forge-local-recovery-helper.mjs +93 -15
- package/scripts/lib/project-init-lib.sh +3 -0
- package/scripts/open-source-audit-allowlist.txt +1 -2
- package/scripts/run-bounded-command.mjs +5 -0
- package/scripts/run-governed-gate.ts +0 -1
- package/scripts/run-mobile-monitor-bridge.ts +0 -1
- package/scripts/smoke-control-plane-failure-domain.ts +94 -0
- package/scripts/smoke-mcp-http-runtime.ts +5 -0
- package/scripts/smoke-runtime-recovery.ts +12 -43
- package/scripts/smoke-schedule-engine.ts +23 -15
- package/scripts/smoke-unattended-transport-recovery.ts +223 -0
- package/scripts/smoke-user-request-continuation-restart.ts +232 -0
- package/scripts/smoke-workflow-supervisor-chrome-adapter.ts +92 -0
- package/scripts/smoke-workflow-supervisor-process-restart.ts +276 -0
- package/scripts/smoke-workflow-supervisor-restart-recovery.ts +150 -0
- package/scripts/smoke-workflow-supervisor.ts +103 -0
- package/scripts/verify-forge-runtime.sh +2 -1
- package/src/cli/agent-jobs/executor-health.ts +11 -34
- package/src/cli/agent-jobs/integration.ts +18 -49
- package/src/cli/agent-jobs/job-manager.ts +7 -3
- package/src/cli/commands/brain-assistant.ts +27 -13
- package/src/cli/commands/brain.ts +13 -15
- package/src/cli/commands/chatgpt.ts +1 -163
- package/src/cli/commands/recovery.ts +135 -121
- package/src/cli/commands/runtime.ts +3 -3
- package/src/cli/commands/setup-profile.ts +8 -0
- package/src/cli/controller/check-runner.ts +13 -2
- package/src/cli/controller/completion-backlog.ts +3 -3
- package/src/cli/controller/completion-orchestrator.ts +4 -43
- package/src/cli/controller/completion-target.ts +3 -72
- package/src/cli/controller/context/source-materializer.ts +81 -100
- package/src/cli/controller/context-pack.ts +10 -8
- package/src/cli/controller/execution-completion.ts +4 -7
- package/src/cli/controller/execution-policy.ts +36 -153
- package/src/cli/controller/governance.ts +2 -3
- package/src/cli/controller/issue-store.ts +4 -99
- package/src/cli/controller/launch-agents.ts +59 -18
- package/src/cli/controller/operational-plan.ts +24 -51
- package/src/cli/controller/runtime-config.ts +5 -1
- package/src/cli/controller/stuck-state-migration.ts +2 -3
- package/src/cli/controller/systemd-user.ts +39 -1
- package/src/cli/editing/edit-session.ts +1 -7
- package/src/cli/local-bridge/console-automations.ts +18 -13
- package/src/cli/local-bridge/console-view-models.ts +3 -12
- package/src/cli/local-bridge/facade-api.ts +64 -191
- package/src/cli/local-bridge/server.ts +24 -147
- package/src/cli/local-bridge/types.ts +0 -1
- package/src/cli/mcp/oauth-client-retirement.ts +74 -0
- package/src/cli/repositories/command-executor.ts +29 -23
- package/src/cli/repositories/command-scope.ts +35 -16
- package/src/cli/repositories/controller-home.ts +48 -0
- package/src/cli/repositories/ephemeral-workspace.ts +20 -30
- package/src/cli/repositories/git-command-executor.ts +2 -2
- package/src/cli/repositories/registry.ts +77 -11
- package/src/cli/repositories/structured-git.ts +62 -2
- package/src/cli/repository/session-cache.ts +92 -6
- package/src/runtime/context/assistant-context.ts +20 -7
- package/src/runtime/context/assistant-work-context.ts +89 -27
- package/src/runtime/context/automatic-learning.ts +565 -0
- package/src/runtime/context/cognitive-attention.ts +173 -0
- package/src/runtime/context/cognitive-skill-canary.ts +158 -0
- package/src/runtime/context/context-closure.ts +46 -9
- package/src/runtime/context/context-pack-process.ts +103 -0
- package/src/runtime/context/context-plane.ts +1 -9
- package/src/runtime/context/direct-controller-learning.ts +298 -0
- package/src/runtime/context/semantic-navigation-contract.ts +9 -0
- package/src/runtime/context/semantic-navigation.ts +6 -34
- package/src/runtime/context/typescript-navigation-process.ts +145 -0
- package/src/runtime/context/typescript-navigation.ts +89 -3
- package/src/runtime/control-plane/cleanup-artifact-retention.ts +212 -9
- package/src/runtime/control-plane/concurrency/work-execution-concurrency.ts +9 -47
- package/src/runtime/control-plane/execution/controller-authority-recovery.ts +34 -4
- package/src/runtime/control-plane/execution/edit-validation-coordinator.ts +29 -20
- package/src/runtime/control-plane/execution/execution-identity.ts +23 -3
- package/src/runtime/control-plane/execution/repository-work-attribution.ts +7 -30
- package/src/runtime/control-plane/execution/retained-work-resume.ts +206 -199
- package/src/runtime/control-plane/execution/session-store.ts +31 -1
- package/src/runtime/control-plane/execution/validation.ts +6 -8
- package/src/runtime/control-plane/execution/work-authority-reconciler.ts +13 -42
- package/src/runtime/control-plane/execution/work-check-evidence.ts +137 -0
- package/src/runtime/control-plane/execution/work-completion-authority.ts +30 -85
- package/src/runtime/control-plane/execution/work-delivery-service.ts +497 -0
- package/src/runtime/control-plane/execution/work-evidence-policy.ts +12 -50
- package/src/runtime/control-plane/execution/work-execution-support.ts +50 -149
- package/src/runtime/control-plane/execution/work-handle-authority.ts +188 -109
- package/src/runtime/control-plane/execution/work-handle-store.ts +19 -43
- package/src/runtime/control-plane/execution/work-head-settlement.ts +53 -20
- package/src/runtime/control-plane/execution/work-lifecycle-audit.ts +52 -29
- package/src/runtime/control-plane/execution/work-operation-service.ts +43 -27
- package/src/runtime/control-plane/execution/work-preparation-service.ts +126 -266
- package/src/runtime/control-plane/execution/work-remote-delivery.ts +2 -3
- package/src/runtime/control-plane/execution/work-revision-diff.ts +39 -0
- package/src/runtime/control-plane/execution/work-terminal-cleanup.ts +173 -186
- package/src/runtime/control-plane/execution/work-validation-reconciler.ts +28 -84
- package/src/runtime/control-plane/execution/work-verification-service.ts +406 -50
- package/src/runtime/control-plane/execution/work-verification-snapshot.ts +5 -1
- package/src/runtime/control-plane/facade/capability-registry.ts +362 -37
- package/src/runtime/control-plane/facade/check-normalization.ts +3 -9
- package/src/runtime/control-plane/facade/codex-delegation.ts +10 -11
- package/src/runtime/control-plane/facade/controller-connection.ts +135 -0
- package/src/runtime/control-plane/facade/goal-workloop-access.ts +1 -20
- package/src/runtime/control-plane/facade/goal-workloop.ts +281 -1753
- package/src/runtime/control-plane/facade/handoff-inbox-application.ts +12 -25
- package/src/runtime/control-plane/facade/handoff-inbox-store.ts +256 -52
- package/src/runtime/control-plane/facade/index.ts +0 -1
- package/src/runtime/control-plane/facade/operation-digest.ts +12 -15
- package/src/runtime/control-plane/facade/plan-contract-store.ts +451 -991
- package/src/runtime/control-plane/facade/policy-gate.ts +0 -23
- package/src/runtime/control-plane/facade/repository-work-admission.ts +12 -22
- package/src/runtime/control-plane/facade/requirement-authority.ts +102 -199
- package/src/runtime/control-plane/facade/requirement-board.ts +3 -3
- package/src/runtime/control-plane/facade/rh-work-operation-contract.ts +51 -14
- package/src/runtime/control-plane/facade/self-healing-loop.ts +18 -53
- package/src/runtime/control-plane/facade/suggested-actions.ts +15 -18
- package/src/runtime/control-plane/facade/types.ts +49 -108
- package/src/runtime/control-plane/facade/work-continuation.ts +8 -8
- package/src/runtime/control-plane/generated-cache-retention.ts +97 -1
- package/src/runtime/control-plane/global-scheduler/autonomous-continuation.ts +248 -0
- package/src/runtime/control-plane/global-scheduler/durable-admission.ts +1 -1
- package/src/runtime/control-plane/global-scheduler/maintenance.ts +239 -112
- package/src/runtime/control-plane/global-scheduler/reconciliation.ts +2 -1
- package/src/runtime/control-plane/global-scheduler/scheduler.ts +66 -40
- package/src/runtime/control-plane/global-scheduler/wake-signal.ts +42 -2
- package/src/runtime/control-plane/governance/access-policy.ts +19 -2
- package/src/runtime/control-plane/governance/authorization.ts +20 -3
- package/src/runtime/control-plane/launcher/chatgpt-round-continuation.ts +63 -300
- package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +28 -300
- package/src/runtime/control-plane/launcher/local-conversation-controller.ts +238 -0
- package/src/runtime/control-plane/launcher/provider-mcp-bootstrap.ts +5 -2
- package/src/runtime/control-plane/launcher/thin-launcher.ts +96 -240
- package/src/runtime/control-plane/persistence/cognition-store.ts +820 -0
- package/src/runtime/control-plane/persistence/experience-store.ts +162 -29
- package/src/runtime/control-plane/persistence/requirement-store.ts +216 -74
- package/src/runtime/control-plane/persistence/sqlite-store.ts +113 -6
- package/src/runtime/control-plane/release-retention.ts +135 -47
- package/src/runtime/control-plane/repository-namespace-retention.ts +2 -2
- package/src/runtime/control-plane/runtime-cleanup.ts +290 -21
- package/src/runtime/control-plane/workspace/project-onboarding.ts +80 -0
- package/src/runtime/control-plane/workspace/semantic-sync-service.ts +19 -5
- package/src/runtime/control-plane/workspace/workspace-store.ts +169 -0
- package/src/runtime/diagnostics/incident-repair.ts +313 -146
- package/src/runtime/diagnostics/mcp-timing.ts +114 -0
- package/src/runtime/evidence/artifact-store.ts +158 -40
- package/src/runtime/evidence/evidence-store.ts +112 -8
- package/src/runtime/evidence/output-handle-index.ts +225 -0
- package/src/runtime/evidence/result-store.ts +158 -44
- package/src/runtime/execution/jobs/store.ts +3 -4
- package/src/runtime/execution/managed-workspace.ts +57 -0
- package/src/runtime/execution/process-runtime/check-facade.ts +1 -1
- package/src/runtime/execution/process-runtime/check-result-retention.ts +2 -2
- package/src/runtime/execution/process-runtime/check-result.ts +105 -1
- package/src/runtime/execution/process-runtime/check-runner-sidecar.ts +18 -8
- package/src/runtime/execution/process-runtime/command-facade.ts +79 -27
- package/src/runtime/execution/process-runtime/gc.ts +15 -2
- package/src/runtime/execution/process-runtime/handle-index.ts +176 -0
- package/src/runtime/execution/process-runtime/host-command-lane.ts +139 -0
- package/src/runtime/execution/process-runtime/index.ts +3 -0
- package/src/runtime/execution/process-runtime/lightweight-managed.ts +251 -72
- package/src/runtime/execution/process-runtime/persisted-check.ts +3 -3
- package/src/runtime/execution/process-runtime/process-runner-entry.ts +47 -5
- package/src/runtime/execution/process-runtime/process-scope.ts +160 -0
- package/src/runtime/execution/process-runtime/resource-claims.ts +65 -61
- package/src/runtime/execution/process-runtime/runtime.ts +35 -2
- package/src/runtime/execution/process-runtime/store.ts +30 -2
- package/src/runtime/execution/process-runtime/types.ts +6 -1
- package/src/runtime/execution/workers/executor.ts +2 -6
- package/src/runtime/platform/service-inventory.ts +130 -0
- package/src/runtime/platform/service-manager.ts +8 -0
- package/src/runtime/plugins/action-application.ts +85 -28
- package/src/runtime/plugins/app-store-connect-adapter.ts +38 -14
- package/src/runtime/plugins/browser-adapter.ts +757 -34
- package/src/runtime/plugins/browser-automation-service.ts +23 -3
- package/src/runtime/plugins/browser-macos-bridge.ts +321 -29
- package/src/runtime/plugins/browser-manifest-surface.ts +45 -11
- package/src/runtime/plugins/browser-native-session-service.ts +63 -13
- package/src/runtime/plugins/browser-registration.ts +16 -0
- package/src/runtime/plugins/browser-runtime.ts +14 -1
- package/src/runtime/plugins/browser-session-authority.ts +2 -2
- package/src/runtime/plugins/browser-session-store.ts +46 -76
- package/src/runtime/plugins/capability-authorization-grants.ts +258 -62
- package/src/runtime/plugins/computer-chatgpt-browser-adapter-installer.ts +219 -0
- package/src/runtime/plugins/computer-chatgpt-macos-target.ts +891 -0
- package/src/runtime/plugins/computer-registration.ts +222 -11
- package/src/runtime/plugins/desktop-operator-external-policy.ts +36 -4
- package/src/runtime/plugins/desktop-operator-registration.ts +12 -4
- package/src/runtime/plugins/external-adapter.ts +42 -6
- package/src/runtime/plugins/external-registration.ts +21 -1
- package/src/runtime/plugins/gmail-adapter.ts +23 -2
- package/src/runtime/plugins/google-calendar-adapter.ts +2 -2
- package/src/runtime/plugins/google-shared.ts +14 -7
- package/src/runtime/plugins/google-tasks-adapter.ts +2 -2
- package/src/runtime/plugins/ios-adapter.ts +1 -1
- package/src/runtime/plugins/lightweight-action.ts +208 -2
- package/src/runtime/plugins/local-system-adapter.ts +12 -2
- package/src/runtime/plugins/managed-process-adapter.ts +12 -5
- package/src/runtime/plugins/plugin-action-sidecar.ts +17 -13
- package/src/runtime/plugins/plugin-management-adapter.ts +1 -1
- package/src/runtime/plugins/store.ts +602 -428
- package/src/runtime/plugins/types.ts +20 -0
- package/src/runtime/plugins/xiaohongshu-publish.ts +16 -0
- package/src/runtime/projections/invalidation.ts +7 -3
- package/src/runtime/projections/materialized-view.ts +80 -36
- package/src/runtime/recovery/actions.ts +3 -3
- package/src/runtime/recovery/capability-action-application.ts +46 -45
- package/src/runtime/recovery/lifecycle-inventory.ts +29 -29
- package/src/runtime/recovery/maintenance-executor.ts +374 -123
- package/src/runtime/recovery/store.ts +29 -11
- package/src/runtime/release/release-coordinator.ts +296 -0
- package/src/runtime/release/release-session.ts +716 -0
- package/src/runtime/release/release-state-migration.ts +25 -0
- package/src/runtime/resources/leases/store.ts +56 -25
- package/src/runtime/root/computer-composition.ts +191 -6
- package/src/runtime/root/controller-progression-composition.ts +192 -0
- package/src/runtime/root/controller-round-composition.ts +20 -1
- package/src/runtime/root/deployment-topology.ts +106 -0
- package/src/runtime/root/entry.ts +4 -3
- package/src/runtime/root/known-good-recovery.ts +184 -0
- package/src/runtime/root/local-bridge.ts +0 -1
- package/src/runtime/root/mcp-transport.ts +111 -18
- package/src/runtime/root/ownership.ts +261 -9
- package/src/runtime/root/package-connector-service.ts +105 -19
- package/src/runtime/root/package-runtime-release.ts +117 -18
- package/src/runtime/root/package-runtime-service.ts +17 -11
- package/src/runtime/root/release-execution-canary.ts +44 -12
- package/src/runtime/root/release-loader.ts +90 -8
- package/src/runtime/root/release-manifest.ts +80 -6
- package/src/runtime/root/release-materialize.ts +372 -28
- package/src/runtime/root/release-store.ts +395 -36
- package/src/runtime/root/runtime-lane.ts +191 -0
- package/src/runtime/root/runtime.ts +159 -27
- package/src/runtime/root/scheduled-controller-composition.ts +28 -3
- package/src/runtime/root/service-runner.ts +2 -2
- package/src/runtime/root/service.ts +36 -33
- package/src/runtime/root/status.ts +48 -0
- package/src/runtime/root/types.ts +32 -3
- package/src/runtime/root/workflow-supervisor-composition.ts +493 -0
- package/src/runtime/root/workflow-supervisor-runtime.ts +209 -0
- package/src/runtime/root/write-fence.ts +50 -2
- package/src/runtime/safe-tooling/google-credential-store.ts +76 -21
- package/src/runtime/safe-tooling/google-oauth-broker.ts +25 -7
- package/src/runtime/safe-tooling/workspace-auth.ts +1 -1
- package/src/runtime/shared/bounded-child-supervisor.ts +9 -1
- package/src/runtime/shared/process-environment.ts +20 -9
- package/src/runtime/shared/response-budget.ts +1 -3
- package/src/runtime/standalone-recovery/controller-home-migration.ts +16 -24
- package/src/runtime/standalone-recovery/core.ts +3702 -342
- package/src/runtime/standalone-recovery/entry.ts +469 -39
- package/src/runtime/standalone-recovery/installer.ts +262 -148
- package/src/runtime/standalone-recovery/mcp-server.ts +29 -193
- package/src/runtime/standalone-recovery/operation-lock.ts +1 -1
- package/src/runtime/standalone-recovery/performance.ts +54 -16
- package/src/runtime/standalone-recovery/release.ts +53 -5
- package/src/runtime/standalone-recovery/service-labels.ts +5 -2
- package/src/runtime/standalone-recovery/watchdog-heartbeat.ts +5 -2
- package/src/runtime/workflow/schedules/browser-probe.ts +17 -6
- package/src/runtime/workflow/schedules/chatgpt-automation-migration.ts +10 -3
- package/src/runtime/workflow/schedules/engine.ts +138 -172
- package/src/runtime/workflow/schedules/work-continuation.ts +44 -5
- package/src/runtime/workflows/runtime.ts +15 -19
- package/src/testing/test-governance.ts +5 -1
- package/supervisor/chatgpt-conversation.ts +23 -0
- package/supervisor/client.ts +201 -0
- package/supervisor/control-plane.ts +868 -0
- package/supervisor/entry.ts +15 -0
- package/supervisor/forge-validators.ts +80 -0
- package/supervisor/index.ts +5 -0
- package/supervisor/native-browser-adapter.ts +786 -0
- package/supervisor/native-messaging/host.ts +39 -0
- package/supervisor/native-messaging/manifest.ts +26 -0
- package/supervisor/native-messaging/protocol.ts +27 -0
- package/supervisor/paths.ts +18 -0
- package/supervisor/protocol.ts +202 -0
- package/supervisor/server.ts +404 -0
- package/supervisor/store.ts +1451 -0
- package/supervisor/tsconfig.json +8 -0
- package/supervisor/types.ts +255 -0
- package/adapters/chatgpt/controller-host.ts +0 -119
- package/adapters/mcp/controller-round-compatibility.ts +0 -184
- package/adapters/mcp/frozen-client-semantic-compatibility.ts +0 -292
- package/adapters/mcp/runtime-gateway/work-compat-adapter.ts +0 -502
- package/packages/kernel/progression/api/index.ts +0 -2
- package/packages/kernel/progression/application/projector.ts +0 -211
- package/packages/kernel/progression/domain/types.ts +0 -116
- package/packages/kernel/progression/index.ts +0 -1
- package/packages/kernel/scheduler/application/continuation-service.ts +0 -212
- package/packages/kernel/scheduler/domain/continuation.ts +0 -38
- package/packages/kernel/scheduler/infrastructure/continuation-dispatch-store.ts +0 -38
- package/packages/kernel/work/domain/admission-policy.ts +0 -34
- package/scripts/benchmark-background-check-overlap.ts +0 -228
- package/scripts/benchmark-computer-hotpath.ts +0 -255
- package/scripts/benchmark-controller-hotpath.ts +0 -212
- package/scripts/benchmark-controller-round2.ts +0 -191
- package/scripts/benchmark-ios-agent-device.ts +0 -511
- package/scripts/benchmark-mcp-host.sh +0 -117
- package/scripts/benchmark-mcp-transport.ts +0 -169
- package/scripts/benchmark-operational-memory-activation.ts +0 -235
- package/scripts/benchmark-operational-shadow.ts +0 -28
- package/scripts/benchmark-quality-harness.ts +0 -146
- package/scripts/benchmark-route-session-concurrency.ts +0 -915
- package/scripts/benchmark-thin-harness-gateway-ab.ts +0 -632
- package/scripts/benchmark-thin-harness-mcp-e2e.ts +0 -498
- package/scripts/benchmark-thin-harness.ts +0 -251
- package/scripts/benchmark-typescript-navigation.ts +0 -186
- package/scripts/benchmark-work-efficiency.ts +0 -334
- package/scripts/build-controller-ui.ts +0 -28
- package/scripts/check-npm-release.sh +0 -32
- package/scripts/check-public-release-surface.sh +0 -19
- package/scripts/check-release-published.sh +0 -57
- package/scripts/check-release-readiness.sh +0 -37
- package/scripts/check-release-version.mjs +0 -74
- package/scripts/check-tarball-install-smoke.sh +0 -150
- package/scripts/package-source-archive.sh +0 -147
- package/scripts/public-release-files.txt +0 -39
- package/scripts/public-release.ts +0 -174
- package/scripts/publish-release-tarball.sh +0 -27
- package/scripts/route-nl-vs-ts-eval.ts +0 -679
- package/scripts/stage-runtime-release.ts +0 -44
- package/src/cli/controller/progress.ts +0 -656
- package/src/cli/controller/work-mode.ts +0 -181
- package/src/cli/local-bridge/console-assets.ts +0 -17
- package/src/cli/local-bridge/dashboard.ts +0 -17
- package/src/cli/local-bridge/frontend/src/App.tsx +0 -10
- package/src/cli/local-bridge/frontend/src/components/Button.tsx +0 -1
- package/src/cli/local-bridge/frontend/src/components/DetailPane.tsx +0 -3
- package/src/cli/local-bridge/frontend/src/components/SearchField.tsx +0 -1
- package/src/cli/local-bridge/frontend/src/components/SectionHeader.tsx +0 -1
- package/src/cli/local-bridge/frontend/src/components/Segmented.tsx +0 -1
- package/src/cli/local-bridge/frontend/src/components/StatusText.tsx +0 -3
- package/src/cli/local-bridge/frontend/src/design/icons.tsx +0 -11
- package/src/cli/local-bridge/frontend/src/design/tokens.css +0 -8
- package/src/cli/local-bridge/frontend/src/features/automations/AutomationsView.tsx +0 -153
- package/src/cli/local-bridge/frontend/src/features/capabilities/CapabilitiesView.tsx +0 -37
- package/src/cli/local-bridge/frontend/src/features/overview/OverviewView.tsx +0 -183
- package/src/cli/local-bridge/frontend/src/features/repositories/RepositoriesView.tsx +0 -2
- package/src/cli/local-bridge/frontend/src/features/system/SystemView.tsx +0 -2
- package/src/cli/local-bridge/frontend/src/features/work/WorkView.tsx +0 -4
- package/src/cli/local-bridge/frontend/src/lib/api.ts +0 -30
- package/src/cli/local-bridge/frontend/src/lib/format.ts +0 -4
- package/src/cli/local-bridge/frontend/src/lib/routes.ts +0 -7
- package/src/cli/local-bridge/frontend/src/main.tsx +0 -1
- package/src/cli/local-bridge/frontend/src/shell/AppShell.tsx +0 -1
- package/src/cli/local-bridge/frontend/src/shell/CommandBar.tsx +0 -2
- package/src/cli/local-bridge/frontend/src/shell/Sidebar.tsx +0 -4
- package/src/cli/local-bridge/frontend/src/styles.css +0 -28
- package/src/cli/local-bridge/frontend/src/types.ts +0 -15
- package/src/cli/local-bridge/frontend/src/vite-env.d.ts +0 -1
- package/src/cli/local-bridge/frontend/vite.config.ts +0 -27
- package/src/cli/local-bridge/ui-dist/app.css +0 -1
- package/src/cli/local-bridge/ui-dist/app.js +0 -11228
- package/src/runtime/control-plane/execution/content-equivalent-commit-authority.ts +0 -169
- package/src/runtime/control-plane/execution/direct-canonical-work-reconciliation.ts +0 -85
- package/src/runtime/control-plane/execution/direct-edit-work-completion.ts +0 -655
- package/src/runtime/control-plane/execution/work-finalization-service.ts +0 -2850
- package/src/runtime/control-plane/execution/work-path-scope.ts +0 -37
- package/src/runtime/control-plane/execution/work-task-receipt.ts +0 -468
- package/src/runtime/control-plane/facade/controller-round-relay.ts +0 -3
- package/src/runtime/control-plane/facade/work-admission-policy.ts +0 -142
- package/src/runtime/control-plane/facade/work-implementation-review.ts +0 -2
- package/src/runtime/control-plane/facade/work-state-machine.ts +0 -2
- package/src/runtime/control-plane/facade/work-task-projection.ts +0 -66
- package/src/runtime/control-plane/routing/index.ts +0 -1
- package/src/runtime/control-plane/routing/route-policy.ts +0 -401
- package/src/runtime/control-plane/routing/workspace-admission.ts +0 -70
|
@@ -0,0 +1,820 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
4
|
+
import type { ScopeRef } from '../../../../packages/kernel/identity/api/index';
|
|
5
|
+
import {
|
|
6
|
+
activateMemory,
|
|
7
|
+
cognitiveTerms,
|
|
8
|
+
memoryAddressKey,
|
|
9
|
+
validateMemoryEdge,
|
|
10
|
+
validateMemoryPayloadRef,
|
|
11
|
+
validateMemoryUnit,
|
|
12
|
+
type ActivationOptions,
|
|
13
|
+
type ActivationPack,
|
|
14
|
+
type CognitiveMemoryStorePort,
|
|
15
|
+
type CognitiveReadPort,
|
|
16
|
+
type CognitiveUsageFeedback,
|
|
17
|
+
type MemoryAddress,
|
|
18
|
+
type MemoryEdge,
|
|
19
|
+
type MemoryPayloadRef,
|
|
20
|
+
type MemoryUnit,
|
|
21
|
+
} from '../../../../packages/kernel/cognition/api/index';
|
|
22
|
+
import {
|
|
23
|
+
controlPlaneDatabasePath,
|
|
24
|
+
withControlPlaneReadDatabase,
|
|
25
|
+
withControlPlaneTransaction,
|
|
26
|
+
type SqliteDatabase,
|
|
27
|
+
} from './sqlite-store';
|
|
28
|
+
|
|
29
|
+
export const COGNITION_STORE_SCHEMA_VERSION = 1 as const;
|
|
30
|
+
const MAX_PAYLOAD_BYTES = 4 * 1024 * 1024;
|
|
31
|
+
const CANONICAL_TABLES = [
|
|
32
|
+
'cognition_memory_units',
|
|
33
|
+
'cognition_memory_evidence',
|
|
34
|
+
'cognition_memory_edges',
|
|
35
|
+
] as const;
|
|
36
|
+
const CONCEPT_INDEX_TABLE = 'cognition_concept_index' as const;
|
|
37
|
+
const TERM_INDEX_TABLE = 'cognition_term_index' as const;
|
|
38
|
+
|
|
39
|
+
interface Statement {
|
|
40
|
+
get(...parameters: unknown[]): unknown;
|
|
41
|
+
all(...parameters: unknown[]): unknown[];
|
|
42
|
+
run(...parameters: unknown[]): unknown;
|
|
43
|
+
finalize?(): void;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function statement<T>(database: SqliteDatabase, sql: string, operation: (prepared: Statement) => T): T {
|
|
47
|
+
const prepared = database.prepare(sql) as Statement;
|
|
48
|
+
try { return operation(prepared); } finally { prepared.finalize?.(); }
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function scopeKey(scope: ScopeRef): [string, string] {
|
|
52
|
+
return [scope.kind, scope.id];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function tablesAvailable(database: SqliteDatabase, tables: readonly string[]): boolean {
|
|
56
|
+
const placeholders = tables.map(() => '?').join(',');
|
|
57
|
+
const row = statement(database,
|
|
58
|
+
`SELECT COUNT(*) AS count FROM sqlite_master WHERE type = 'table' AND name IN (${placeholders})`,
|
|
59
|
+
prepared => prepared.get(...tables) as { count?: number } | undefined);
|
|
60
|
+
return Number(row?.count ?? 0) === tables.length;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function canonicalSchemaAvailable(database: SqliteDatabase): boolean {
|
|
64
|
+
return tablesAvailable(database, CANONICAL_TABLES);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function conceptIndexAvailable(database: SqliteDatabase): boolean {
|
|
68
|
+
return tablesAvailable(database, [CONCEPT_INDEX_TABLE]);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function termIndexAvailable(database: SqliteDatabase): boolean {
|
|
72
|
+
return tablesAvailable(database, [TERM_INDEX_TABLE]);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function derivedIndexesHealthy(database: SqliteDatabase): boolean {
|
|
76
|
+
if (!conceptIndexAvailable(database) || !termIndexAvailable(database)) return false;
|
|
77
|
+
try {
|
|
78
|
+
statement(database,
|
|
79
|
+
'SELECT scope_kind, scope_id, concept_id, memory_id FROM cognition_concept_index LIMIT 1',
|
|
80
|
+
prepared => prepared.get());
|
|
81
|
+
statement(database,
|
|
82
|
+
'SELECT scope_kind, scope_id, term, memory_id FROM cognition_term_index LIMIT 1',
|
|
83
|
+
prepared => prepared.get());
|
|
84
|
+
return true;
|
|
85
|
+
} catch {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function ensureSchema(database: SqliteDatabase): void {
|
|
91
|
+
database.exec(`
|
|
92
|
+
CREATE TABLE IF NOT EXISTS cognition_memory_units (
|
|
93
|
+
scope_kind TEXT NOT NULL,
|
|
94
|
+
scope_id TEXT NOT NULL,
|
|
95
|
+
memory_id TEXT NOT NULL,
|
|
96
|
+
schema_version INTEGER NOT NULL,
|
|
97
|
+
revision INTEGER NOT NULL,
|
|
98
|
+
canonical_text TEXT NOT NULL,
|
|
99
|
+
facets_json TEXT NOT NULL,
|
|
100
|
+
concepts_json TEXT NOT NULL,
|
|
101
|
+
confidence REAL NOT NULL,
|
|
102
|
+
utility REAL NOT NULL,
|
|
103
|
+
tier TEXT NOT NULL,
|
|
104
|
+
payload_digest TEXT,
|
|
105
|
+
payload_media_type TEXT,
|
|
106
|
+
payload_bytes INTEGER,
|
|
107
|
+
source_kind TEXT NOT NULL,
|
|
108
|
+
source_id TEXT,
|
|
109
|
+
source_work_id TEXT,
|
|
110
|
+
source_round_id TEXT,
|
|
111
|
+
recorded_at TEXT NOT NULL,
|
|
112
|
+
valid_from TEXT NOT NULL,
|
|
113
|
+
expires_at TEXT,
|
|
114
|
+
supersedes_id TEXT,
|
|
115
|
+
retracted_at TEXT,
|
|
116
|
+
retraction_reason TEXT,
|
|
117
|
+
PRIMARY KEY (scope_kind, scope_id, memory_id)
|
|
118
|
+
);
|
|
119
|
+
CREATE INDEX IF NOT EXISTS cognition_memory_units_rank
|
|
120
|
+
ON cognition_memory_units (scope_kind, scope_id, tier, utility DESC, confidence DESC, recorded_at DESC);
|
|
121
|
+
|
|
122
|
+
CREATE TABLE IF NOT EXISTS cognition_memory_evidence (
|
|
123
|
+
scope_kind TEXT NOT NULL,
|
|
124
|
+
scope_id TEXT NOT NULL,
|
|
125
|
+
memory_id TEXT NOT NULL,
|
|
126
|
+
evidence_ref TEXT NOT NULL,
|
|
127
|
+
evidence_kind TEXT NOT NULL,
|
|
128
|
+
PRIMARY KEY (scope_kind, scope_id, memory_id, evidence_ref, evidence_kind),
|
|
129
|
+
FOREIGN KEY (scope_kind, scope_id, memory_id)
|
|
130
|
+
REFERENCES cognition_memory_units(scope_kind, scope_id, memory_id) ON DELETE CASCADE
|
|
131
|
+
);
|
|
132
|
+
CREATE INDEX IF NOT EXISTS cognition_memory_evidence_ref ON cognition_memory_evidence (evidence_ref);
|
|
133
|
+
|
|
134
|
+
CREATE TABLE IF NOT EXISTS cognition_memory_edges (
|
|
135
|
+
scope_kind TEXT NOT NULL,
|
|
136
|
+
scope_id TEXT NOT NULL,
|
|
137
|
+
edge_id TEXT NOT NULL,
|
|
138
|
+
from_memory_id TEXT NOT NULL,
|
|
139
|
+
to_memory_id TEXT NOT NULL,
|
|
140
|
+
relation TEXT NOT NULL,
|
|
141
|
+
weight REAL NOT NULL,
|
|
142
|
+
evidence_json TEXT NOT NULL,
|
|
143
|
+
source_work_id TEXT,
|
|
144
|
+
source_round_id TEXT,
|
|
145
|
+
recorded_at TEXT NOT NULL,
|
|
146
|
+
expires_at TEXT,
|
|
147
|
+
retracted_at TEXT,
|
|
148
|
+
PRIMARY KEY (scope_kind, scope_id, edge_id)
|
|
149
|
+
);
|
|
150
|
+
CREATE INDEX IF NOT EXISTS cognition_memory_edges_from
|
|
151
|
+
ON cognition_memory_edges (scope_kind, scope_id, from_memory_id);
|
|
152
|
+
CREATE INDEX IF NOT EXISTS cognition_memory_edges_to
|
|
153
|
+
ON cognition_memory_edges (scope_kind, scope_id, to_memory_id);
|
|
154
|
+
|
|
155
|
+
CREATE TABLE IF NOT EXISTS cognition_memory_usage (
|
|
156
|
+
scope_kind TEXT NOT NULL,
|
|
157
|
+
scope_id TEXT NOT NULL,
|
|
158
|
+
memory_id TEXT NOT NULL,
|
|
159
|
+
observation_id TEXT NOT NULL,
|
|
160
|
+
actor_id TEXT NOT NULL,
|
|
161
|
+
decision TEXT NOT NULL,
|
|
162
|
+
rejection_kind TEXT,
|
|
163
|
+
reason TEXT NOT NULL,
|
|
164
|
+
observed_at TEXT NOT NULL,
|
|
165
|
+
PRIMARY KEY (scope_kind, scope_id, memory_id, observation_id),
|
|
166
|
+
FOREIGN KEY (scope_kind, scope_id, memory_id)
|
|
167
|
+
REFERENCES cognition_memory_units(scope_kind, scope_id, memory_id) ON DELETE CASCADE
|
|
168
|
+
);
|
|
169
|
+
CREATE INDEX IF NOT EXISTS cognition_memory_usage_rank
|
|
170
|
+
ON cognition_memory_usage (scope_kind, scope_id, memory_id, observed_at DESC);
|
|
171
|
+
|
|
172
|
+
CREATE TABLE IF NOT EXISTS cognition_concept_index (
|
|
173
|
+
scope_kind TEXT NOT NULL,
|
|
174
|
+
scope_id TEXT NOT NULL,
|
|
175
|
+
concept_id TEXT NOT NULL,
|
|
176
|
+
memory_id TEXT NOT NULL,
|
|
177
|
+
PRIMARY KEY (scope_kind, scope_id, concept_id, memory_id)
|
|
178
|
+
);
|
|
179
|
+
CREATE INDEX IF NOT EXISTS cognition_concept_lookup
|
|
180
|
+
ON cognition_concept_index (scope_kind, scope_id, concept_id);
|
|
181
|
+
|
|
182
|
+
CREATE TABLE IF NOT EXISTS cognition_term_index (
|
|
183
|
+
scope_kind TEXT NOT NULL,
|
|
184
|
+
scope_id TEXT NOT NULL,
|
|
185
|
+
term TEXT NOT NULL,
|
|
186
|
+
memory_id TEXT NOT NULL,
|
|
187
|
+
PRIMARY KEY (scope_kind, scope_id, term, memory_id)
|
|
188
|
+
);
|
|
189
|
+
CREATE INDEX IF NOT EXISTS cognition_term_lookup
|
|
190
|
+
ON cognition_term_index (scope_kind, scope_id, term);
|
|
191
|
+
`);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function rowToMemory(row: Record<string, unknown>, evidenceRefs: string[], counterEvidenceRefs: string[]): MemoryUnit {
|
|
195
|
+
const payloadDigest = row.payload_digest as string | null;
|
|
196
|
+
const payloadRef: MemoryPayloadRef | undefined = payloadDigest ? validateMemoryPayloadRef({
|
|
197
|
+
algorithm: 'sha256',
|
|
198
|
+
digest: payloadDigest,
|
|
199
|
+
mediaType: row.payload_media_type as string,
|
|
200
|
+
bytes: Number(row.payload_bytes),
|
|
201
|
+
}) : undefined;
|
|
202
|
+
return validateMemoryUnit({
|
|
203
|
+
schemaVersion: 1,
|
|
204
|
+
id: row.memory_id as string,
|
|
205
|
+
revision: Number(row.revision),
|
|
206
|
+
scope: { schemaVersion: 1, kind: row.scope_kind as ScopeRef['kind'], id: row.scope_id as string },
|
|
207
|
+
facets: JSON.parse(row.facets_json as string) as string[],
|
|
208
|
+
canonicalText: row.canonical_text as string,
|
|
209
|
+
concepts: JSON.parse(row.concepts_json as string) as string[],
|
|
210
|
+
...(payloadRef ? { payloadRef } : {}),
|
|
211
|
+
provenance: {
|
|
212
|
+
sourceKind: row.source_kind as MemoryUnit['provenance']['sourceKind'],
|
|
213
|
+
...(row.source_id ? { sourceId: row.source_id as string } : {}),
|
|
214
|
+
...(row.source_work_id ? { sourceWorkId: row.source_work_id as string } : {}),
|
|
215
|
+
...(row.source_round_id ? { sourceRoundId: row.source_round_id as string } : {}),
|
|
216
|
+
recordedAt: row.recorded_at as string,
|
|
217
|
+
evidenceRefs,
|
|
218
|
+
},
|
|
219
|
+
confidence: Number(row.confidence),
|
|
220
|
+
utility: Number(row.utility),
|
|
221
|
+
tier: row.tier as MemoryUnit['tier'],
|
|
222
|
+
validFrom: row.valid_from as string,
|
|
223
|
+
...(row.expires_at ? { expiresAt: row.expires_at as string } : {}),
|
|
224
|
+
...(row.supersedes_id ? { supersedesId: row.supersedes_id as string } : {}),
|
|
225
|
+
counterEvidenceRefs,
|
|
226
|
+
...(row.retracted_at ? { retractedAt: row.retracted_at as string, retractionReason: row.retraction_reason as string } : {}),
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function evidenceFor(database: SqliteDatabase, scope: ScopeRef, memoryId: string): { evidence: string[]; counter: string[] } {
|
|
231
|
+
const [kind, id] = scopeKey(scope);
|
|
232
|
+
const rows = statement(database,
|
|
233
|
+
`SELECT evidence_ref, evidence_kind FROM cognition_memory_evidence
|
|
234
|
+
WHERE scope_kind = ? AND scope_id = ? AND memory_id = ?
|
|
235
|
+
ORDER BY evidence_kind, evidence_ref`,
|
|
236
|
+
prepared => prepared.all(kind, id, memoryId) as Array<{ evidence_ref: string; evidence_kind: string }>);
|
|
237
|
+
return {
|
|
238
|
+
evidence: rows.filter(row => row.evidence_kind === 'support').map(row => row.evidence_ref),
|
|
239
|
+
counter: rows.filter(row => row.evidence_kind === 'counter').map(row => row.evidence_ref),
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
function readMemory(database: SqliteDatabase, scope: ScopeRef, memoryId: string): MemoryUnit | undefined {
|
|
244
|
+
if (!canonicalSchemaAvailable(database)) return undefined;
|
|
245
|
+
const [kind, id] = scopeKey(scope);
|
|
246
|
+
const row = statement(database,
|
|
247
|
+
`SELECT * FROM cognition_memory_units WHERE scope_kind = ? AND scope_id = ? AND memory_id = ?`,
|
|
248
|
+
prepared => prepared.get(kind, id, memoryId) as Record<string, unknown> | undefined);
|
|
249
|
+
if (!row) return undefined;
|
|
250
|
+
const refs = evidenceFor(database, scope, memoryId);
|
|
251
|
+
return rowToMemory(row, refs.evidence, refs.counter);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function readAddresses(database: SqliteDatabase, addresses: readonly MemoryAddress[]): MemoryUnit[] {
|
|
255
|
+
if (!addresses.length || !canonicalSchemaAvailable(database)) return [];
|
|
256
|
+
const unique = [...new Map(addresses.map(address => [memoryAddressKey(address), address])).values()].slice(0, 512);
|
|
257
|
+
const predicate = unique.map(() => '(scope_kind = ? AND scope_id = ? AND memory_id = ?)').join(' OR ');
|
|
258
|
+
const params = unique.flatMap(address => [address.scope.kind, address.scope.id, address.id]);
|
|
259
|
+
const rows = statement(database,
|
|
260
|
+
`SELECT * FROM cognition_memory_units WHERE ${predicate}`,
|
|
261
|
+
prepared => prepared.all(...params) as Array<Record<string, unknown>>);
|
|
262
|
+
return rows.map(row => {
|
|
263
|
+
const scope = { schemaVersion: 1 as const, kind: row.scope_kind as ScopeRef['kind'], id: row.scope_id as string };
|
|
264
|
+
const refs = evidenceFor(database, scope, row.memory_id as string);
|
|
265
|
+
return rowToMemory(row, refs.evidence, refs.counter);
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
function readByIds(database: SqliteDatabase, scopes: readonly ScopeRef[], ids: readonly string[]): MemoryUnit[] {
|
|
270
|
+
const addresses = scopes.flatMap(scope => [...new Set(ids)].slice(0, 512).map(id => ({ scope, id })));
|
|
271
|
+
return readAddresses(database, addresses);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
function replaceDerivedIndexes(database: SqliteDatabase, memory: MemoryUnit): void {
|
|
275
|
+
const [kind, id] = scopeKey(memory.scope);
|
|
276
|
+
statement(database,
|
|
277
|
+
`DELETE FROM cognition_concept_index WHERE scope_kind = ? AND scope_id = ? AND memory_id = ?`,
|
|
278
|
+
prepared => prepared.run(kind, id, memory.id));
|
|
279
|
+
statement(database,
|
|
280
|
+
`DELETE FROM cognition_term_index WHERE scope_kind = ? AND scope_id = ? AND memory_id = ?`,
|
|
281
|
+
prepared => prepared.run(kind, id, memory.id));
|
|
282
|
+
|
|
283
|
+
const concepts = database.prepare(
|
|
284
|
+
`INSERT OR IGNORE INTO cognition_concept_index (scope_kind, scope_id, concept_id, memory_id) VALUES (?, ?, ?, ?)`) as Statement;
|
|
285
|
+
const terms = database.prepare(
|
|
286
|
+
`INSERT OR IGNORE INTO cognition_term_index (scope_kind, scope_id, term, memory_id) VALUES (?, ?, ?, ?)`) as Statement;
|
|
287
|
+
try {
|
|
288
|
+
for (const concept of memory.concepts) concepts.run(kind, id, concept, memory.id);
|
|
289
|
+
for (const term of cognitiveTerms(`${memory.canonicalText}\n${memory.concepts.join(' ')}\n${memory.facets.join(' ')}`)) {
|
|
290
|
+
terms.run(kind, id, term, memory.id);
|
|
291
|
+
}
|
|
292
|
+
} finally {
|
|
293
|
+
concepts.finalize?.();
|
|
294
|
+
terms.finalize?.();
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
function writeCognitiveMemoryUnitWithinTransaction(
|
|
299
|
+
database: SqliteDatabase,
|
|
300
|
+
memory: MemoryUnit,
|
|
301
|
+
expectedRevision?: number | null,
|
|
302
|
+
): MemoryUnit {
|
|
303
|
+
ensureSchema(database);
|
|
304
|
+
validateMemoryUnit(memory);
|
|
305
|
+
const existing = readMemory(database, memory.scope, memory.id);
|
|
306
|
+
if (expectedRevision !== undefined) {
|
|
307
|
+
const matches = expectedRevision === null ? existing === undefined : existing?.revision === expectedRevision;
|
|
308
|
+
if (!matches) throw new Error('COGNITION_MEMORY_REVISION_CONFLICT');
|
|
309
|
+
}
|
|
310
|
+
const requiredRevision = (existing?.revision ?? 0) + 1;
|
|
311
|
+
if (memory.revision !== requiredRevision) throw new Error('COGNITION_MEMORY_REVISION_INVALID');
|
|
312
|
+
|
|
313
|
+
const [kind, id] = scopeKey(memory.scope);
|
|
314
|
+
statement(database, `
|
|
315
|
+
INSERT INTO cognition_memory_units (
|
|
316
|
+
scope_kind, scope_id, memory_id, schema_version, revision, canonical_text, facets_json, concepts_json,
|
|
317
|
+
confidence, utility, tier, payload_digest, payload_media_type, payload_bytes, source_kind, source_id,
|
|
318
|
+
source_work_id, source_round_id, recorded_at, valid_from, expires_at, supersedes_id, retracted_at, retraction_reason
|
|
319
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
320
|
+
ON CONFLICT(scope_kind, scope_id, memory_id) DO UPDATE SET
|
|
321
|
+
schema_version=excluded.schema_version, revision=excluded.revision, canonical_text=excluded.canonical_text,
|
|
322
|
+
facets_json=excluded.facets_json, concepts_json=excluded.concepts_json, confidence=excluded.confidence,
|
|
323
|
+
utility=excluded.utility, tier=excluded.tier, payload_digest=excluded.payload_digest,
|
|
324
|
+
payload_media_type=excluded.payload_media_type, payload_bytes=excluded.payload_bytes,
|
|
325
|
+
source_kind=excluded.source_kind, source_id=excluded.source_id, source_work_id=excluded.source_work_id,
|
|
326
|
+
source_round_id=excluded.source_round_id, recorded_at=excluded.recorded_at, valid_from=excluded.valid_from,
|
|
327
|
+
expires_at=excluded.expires_at, supersedes_id=excluded.supersedes_id, retracted_at=excluded.retracted_at,
|
|
328
|
+
retraction_reason=excluded.retraction_reason`, prepared => prepared.run(
|
|
329
|
+
kind, id, memory.id, memory.schemaVersion, memory.revision, memory.canonicalText,
|
|
330
|
+
JSON.stringify(memory.facets), JSON.stringify(memory.concepts), memory.confidence, memory.utility, memory.tier,
|
|
331
|
+
memory.payloadRef?.digest ?? null, memory.payloadRef?.mediaType ?? null, memory.payloadRef?.bytes ?? null,
|
|
332
|
+
memory.provenance.sourceKind, memory.provenance.sourceId ?? null, memory.provenance.sourceWorkId ?? null,
|
|
333
|
+
memory.provenance.sourceRoundId ?? null, memory.provenance.recordedAt, memory.validFrom, memory.expiresAt ?? null,
|
|
334
|
+
memory.supersedesId ?? null, memory.retractedAt ?? null, memory.retractionReason ?? null));
|
|
335
|
+
|
|
336
|
+
statement(database,
|
|
337
|
+
`DELETE FROM cognition_memory_evidence WHERE scope_kind = ? AND scope_id = ? AND memory_id = ?`,
|
|
338
|
+
prepared => prepared.run(kind, id, memory.id));
|
|
339
|
+
const evidence = database.prepare(
|
|
340
|
+
`INSERT OR IGNORE INTO cognition_memory_evidence (scope_kind, scope_id, memory_id, evidence_ref, evidence_kind)
|
|
341
|
+
VALUES (?, ?, ?, ?, ?)`) as Statement;
|
|
342
|
+
try {
|
|
343
|
+
for (const ref of memory.provenance.evidenceRefs) evidence.run(kind, id, memory.id, ref, 'support');
|
|
344
|
+
for (const ref of memory.counterEvidenceRefs) evidence.run(kind, id, memory.id, ref, 'counter');
|
|
345
|
+
} finally {
|
|
346
|
+
evidence.finalize?.();
|
|
347
|
+
}
|
|
348
|
+
replaceDerivedIndexes(database, memory);
|
|
349
|
+
return memory;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
function writeCognitiveMemoryEdgeWithinTransaction(database: SqliteDatabase, edge: MemoryEdge): MemoryEdge {
|
|
353
|
+
ensureSchema(database);
|
|
354
|
+
validateMemoryEdge(edge);
|
|
355
|
+
if (!readMemory(database, edge.scope, edge.fromId) || !readMemory(database, edge.scope, edge.toId)) {
|
|
356
|
+
throw new Error('COGNITION_EDGE_ENDPOINT_MISSING');
|
|
357
|
+
}
|
|
358
|
+
const [kind, id] = scopeKey(edge.scope);
|
|
359
|
+
statement(database, `
|
|
360
|
+
INSERT INTO cognition_memory_edges (
|
|
361
|
+
scope_kind, scope_id, edge_id, from_memory_id, to_memory_id, relation, weight, evidence_json,
|
|
362
|
+
source_work_id, source_round_id, recorded_at, expires_at, retracted_at
|
|
363
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
364
|
+
ON CONFLICT(scope_kind, scope_id, edge_id) DO UPDATE SET
|
|
365
|
+
from_memory_id=excluded.from_memory_id, to_memory_id=excluded.to_memory_id,
|
|
366
|
+
relation=excluded.relation, weight=excluded.weight, evidence_json=excluded.evidence_json,
|
|
367
|
+
source_work_id=excluded.source_work_id, source_round_id=excluded.source_round_id,
|
|
368
|
+
recorded_at=excluded.recorded_at, expires_at=excluded.expires_at, retracted_at=excluded.retracted_at`,
|
|
369
|
+
prepared => prepared.run(kind, id, edge.id, edge.fromId, edge.toId, edge.relation, edge.weight,
|
|
370
|
+
JSON.stringify(edge.evidenceRefs), edge.sourceWorkId ?? null, edge.sourceRoundId ?? null,
|
|
371
|
+
edge.recordedAt, edge.expiresAt ?? null, edge.retractedAt ?? null));
|
|
372
|
+
return edge;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/** Trusted persistence port. Callers still require a CognitiveWriteAuthorityPort. */
|
|
376
|
+
export type CognitiveUsageDecision = 'used' | 'rejected';
|
|
377
|
+
export type CognitiveUsageRejectionKind = 'irrelevant' | 'stale' | 'contradicted';
|
|
378
|
+
|
|
379
|
+
export interface CognitiveUsageObservation {
|
|
380
|
+
observationId: string;
|
|
381
|
+
address: MemoryAddress;
|
|
382
|
+
actorId: string;
|
|
383
|
+
decision: CognitiveUsageDecision;
|
|
384
|
+
reason: string;
|
|
385
|
+
rejectionKind?: CognitiveUsageRejectionKind;
|
|
386
|
+
observedAt: string;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
export function recordCognitiveUsageObservation(
|
|
390
|
+
controllerHome: string,
|
|
391
|
+
input: CognitiveUsageObservation,
|
|
392
|
+
): CognitiveUsageObservation {
|
|
393
|
+
const observationId = input.observationId.trim();
|
|
394
|
+
const actorId = input.actorId.trim();
|
|
395
|
+
const reason = input.reason.trim();
|
|
396
|
+
if (!observationId || observationId.length > 512) throw new Error('COGNITION_USAGE_OBSERVATION_ID_INVALID');
|
|
397
|
+
if (!actorId || actorId.length > 512) throw new Error('COGNITION_USAGE_ACTOR_INVALID');
|
|
398
|
+
if (!reason || reason.length > 1_000) throw new Error('COGNITION_USAGE_REASON_INVALID');
|
|
399
|
+
if (!['used', 'rejected'].includes(input.decision)) throw new Error('COGNITION_USAGE_DECISION_INVALID');
|
|
400
|
+
if (input.decision === 'rejected' && !['irrelevant', 'stale', 'contradicted'].includes(input.rejectionKind ?? '')) {
|
|
401
|
+
throw new Error('COGNITION_USAGE_REJECTION_KIND_REQUIRED');
|
|
402
|
+
}
|
|
403
|
+
if (input.decision === 'used' && input.rejectionKind !== undefined) throw new Error('COGNITION_USAGE_REJECTION_KIND_UNEXPECTED');
|
|
404
|
+
if (!Number.isFinite(Date.parse(input.observedAt))) throw new Error('COGNITION_USAGE_TIME_INVALID');
|
|
405
|
+
memoryAddressKey(input.address);
|
|
406
|
+
|
|
407
|
+
return withControlPlaneTransaction(controllerHome, database => {
|
|
408
|
+
ensureSchema(database);
|
|
409
|
+
if (!readMemory(database, input.address.scope, input.address.id)) throw new Error('COGNITION_USAGE_MEMORY_NOT_FOUND');
|
|
410
|
+
const [kind, id] = scopeKey(input.address.scope);
|
|
411
|
+
statement(database, `
|
|
412
|
+
INSERT OR IGNORE INTO cognition_memory_usage (
|
|
413
|
+
scope_kind, scope_id, memory_id, observation_id, actor_id, decision,
|
|
414
|
+
rejection_kind, reason, observed_at
|
|
415
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
416
|
+
prepared => prepared.run(
|
|
417
|
+
kind,
|
|
418
|
+
id,
|
|
419
|
+
input.address.id,
|
|
420
|
+
observationId,
|
|
421
|
+
actorId,
|
|
422
|
+
input.decision,
|
|
423
|
+
input.rejectionKind ?? null,
|
|
424
|
+
reason,
|
|
425
|
+
input.observedAt,
|
|
426
|
+
));
|
|
427
|
+
return {
|
|
428
|
+
...input,
|
|
429
|
+
observationId,
|
|
430
|
+
actorId,
|
|
431
|
+
reason,
|
|
432
|
+
};
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
export function readCognitiveUsageFeedback(
|
|
437
|
+
controllerHome: string,
|
|
438
|
+
scopes: readonly ScopeRef[],
|
|
439
|
+
): CognitiveUsageFeedback[] {
|
|
440
|
+
const uniqueScopes = [...new Map(scopes.map(scope => [`${scope.kind}:${scope.id}`, scope])).values()].slice(0, 32);
|
|
441
|
+
if (!uniqueScopes.length) return [];
|
|
442
|
+
return withControlPlaneReadDatabase(controllerHome, database => {
|
|
443
|
+
if (!tablesAvailable(database, ['cognition_memory_usage'])) return [];
|
|
444
|
+
const predicate = scopePredicate(uniqueScopes);
|
|
445
|
+
const rows = statement(database, `
|
|
446
|
+
SELECT scope_kind, scope_id, memory_id,
|
|
447
|
+
SUM(CASE WHEN decision = 'used' THEN 1 ELSE 0 END) AS used_count,
|
|
448
|
+
SUM(CASE WHEN decision = 'rejected' THEN 1 ELSE 0 END) AS rejected_count,
|
|
449
|
+
SUM(CASE WHEN rejection_kind = 'contradicted' THEN 1 ELSE 0 END) AS conflict_count,
|
|
450
|
+
SUM(CASE WHEN rejection_kind = 'stale' THEN 1 ELSE 0 END) AS stale_count
|
|
451
|
+
FROM cognition_memory_usage
|
|
452
|
+
WHERE ${predicate.sql}
|
|
453
|
+
GROUP BY scope_kind, scope_id, memory_id
|
|
454
|
+
ORDER BY scope_kind ASC, scope_id ASC, memory_id ASC
|
|
455
|
+
LIMIT 512`,
|
|
456
|
+
prepared => prepared.all(...predicate.params) as Array<{
|
|
457
|
+
scope_kind: ScopeRef['kind'];
|
|
458
|
+
scope_id: string;
|
|
459
|
+
memory_id: string;
|
|
460
|
+
used_count: number;
|
|
461
|
+
rejected_count: number;
|
|
462
|
+
conflict_count: number;
|
|
463
|
+
stale_count: number;
|
|
464
|
+
}>);
|
|
465
|
+
return rows.map(row => ({
|
|
466
|
+
address: {
|
|
467
|
+
scope: { schemaVersion: 1, kind: row.scope_kind, id: row.scope_id },
|
|
468
|
+
id: row.memory_id,
|
|
469
|
+
},
|
|
470
|
+
usedCount: Number(row.used_count),
|
|
471
|
+
rejectedCount: Number(row.rejected_count),
|
|
472
|
+
conflictCount: Number(row.conflict_count),
|
|
473
|
+
staleCount: Number(row.stale_count),
|
|
474
|
+
}));
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
export function cognitionMemoryStore(controllerHome: string): CognitiveMemoryStorePort {
|
|
479
|
+
let transaction: SqliteDatabase | undefined;
|
|
480
|
+
return {
|
|
481
|
+
transaction(operation) {
|
|
482
|
+
if (transaction) return operation();
|
|
483
|
+
return withControlPlaneTransaction(controllerHome, database => {
|
|
484
|
+
transaction = database;
|
|
485
|
+
try { return operation(); } finally { transaction = undefined; }
|
|
486
|
+
});
|
|
487
|
+
},
|
|
488
|
+
read(scope, id) {
|
|
489
|
+
if (transaction) return readMemory(transaction, scope, id);
|
|
490
|
+
return withControlPlaneReadDatabase(controllerHome, database => readMemory(database, scope, id));
|
|
491
|
+
},
|
|
492
|
+
write(memory, expectedRevision) {
|
|
493
|
+
if (!transaction) throw new Error('COGNITION_TRANSACTION_REQUIRED');
|
|
494
|
+
return writeCognitiveMemoryUnitWithinTransaction(transaction, memory, expectedRevision);
|
|
495
|
+
},
|
|
496
|
+
writeEdge(edge) {
|
|
497
|
+
if (!transaction) throw new Error('COGNITION_TRANSACTION_REQUIRED');
|
|
498
|
+
return writeCognitiveMemoryEdgeWithinTransaction(transaction, edge);
|
|
499
|
+
},
|
|
500
|
+
};
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
function casRoot(controllerHome: string): string {
|
|
504
|
+
return join(dirname(controlPlaneDatabasePath(controllerHome)), 'cognition-cas', 'sha256');
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
export function putCognitivePayload(
|
|
508
|
+
controllerHome: string,
|
|
509
|
+
payload: Uint8Array | string,
|
|
510
|
+
mediaType = 'text/plain; charset=utf-8',
|
|
511
|
+
): MemoryPayloadRef {
|
|
512
|
+
const bytes = typeof payload === 'string' ? Buffer.from(payload, 'utf8') : Buffer.from(payload);
|
|
513
|
+
if (bytes.byteLength > MAX_PAYLOAD_BYTES) throw new Error('COGNITION_PAYLOAD_TOO_LARGE');
|
|
514
|
+
const ref = validateMemoryPayloadRef({
|
|
515
|
+
algorithm: 'sha256',
|
|
516
|
+
digest: createHash('sha256').update(bytes).digest('hex'),
|
|
517
|
+
mediaType,
|
|
518
|
+
bytes: bytes.byteLength,
|
|
519
|
+
});
|
|
520
|
+
const root = casRoot(controllerHome);
|
|
521
|
+
mkdirSync(root, { recursive: true, mode: 0o700 });
|
|
522
|
+
const target = join(root, ref.digest);
|
|
523
|
+
const temp = `${target}.${process.pid}.${Date.now()}.tmp`;
|
|
524
|
+
if (!existsSync(target)) {
|
|
525
|
+
writeFileSync(temp, bytes, { flag: 'wx', mode: 0o600 });
|
|
526
|
+
try {
|
|
527
|
+
renameSync(temp, target);
|
|
528
|
+
} catch (error) {
|
|
529
|
+
if (!existsSync(target)) throw error;
|
|
530
|
+
if (existsSync(temp)) unlinkSync(temp);
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
return ref;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
export function readCognitivePayload(controllerHome: string, input: MemoryPayloadRef): Buffer {
|
|
537
|
+
const ref = validateMemoryPayloadRef(input);
|
|
538
|
+
const bytes = readFileSync(join(casRoot(controllerHome), ref.digest));
|
|
539
|
+
if (bytes.byteLength !== ref.bytes || createHash('sha256').update(bytes).digest('hex') !== ref.digest) {
|
|
540
|
+
throw new Error('COGNITION_PAYLOAD_CORRUPT');
|
|
541
|
+
}
|
|
542
|
+
return bytes;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
function scopePredicate(scopes: readonly ScopeRef[]): { sql: string; params: unknown[] } {
|
|
546
|
+
if (!scopes.length) return { sql: '0', params: [] };
|
|
547
|
+
return {
|
|
548
|
+
sql: scopes.map(() => '(scope_kind = ? AND scope_id = ?)').join(' OR '),
|
|
549
|
+
params: scopes.flatMap(scope => [scope.kind, scope.id]),
|
|
550
|
+
};
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
function readPortForDatabase(database: SqliteDatabase): CognitiveReadPort {
|
|
554
|
+
return {
|
|
555
|
+
readByIds(scopes, ids) {
|
|
556
|
+
return readByIds(database, scopes, [...new Set(ids)].slice(0, 512));
|
|
557
|
+
},
|
|
558
|
+
readByAddresses(addresses) {
|
|
559
|
+
return readAddresses(database, addresses);
|
|
560
|
+
},
|
|
561
|
+
exactByConcept(scopes, concepts, limit, activeAt = new Date().toISOString()) {
|
|
562
|
+
if (!conceptIndexAvailable(database) || !scopes.length || !concepts.length) return [];
|
|
563
|
+
const scope = scopePredicate(scopes);
|
|
564
|
+
const uniqueConcepts = [...new Set(concepts)].slice(0, 128);
|
|
565
|
+
const placeholders = uniqueConcepts.map(() => '?').join(',');
|
|
566
|
+
const rows = statement(database, `
|
|
567
|
+
SELECT scope_kind, scope_id, memory_id, COUNT(*) AS hits
|
|
568
|
+
FROM cognition_concept_index c
|
|
569
|
+
WHERE (${scope.sql}) AND concept_id IN (${placeholders})
|
|
570
|
+
AND EXISTS (
|
|
571
|
+
SELECT 1 FROM cognition_memory_units m
|
|
572
|
+
WHERE m.scope_kind = c.scope_kind AND m.scope_id = c.scope_id AND m.memory_id = c.memory_id
|
|
573
|
+
AND m.retracted_at IS NULL AND m.valid_from <= ? AND (m.expires_at IS NULL OR m.expires_at > ?)
|
|
574
|
+
)
|
|
575
|
+
GROUP BY scope_kind, scope_id, memory_id
|
|
576
|
+
ORDER BY hits DESC, scope_kind ASC, scope_id ASC, memory_id ASC
|
|
577
|
+
LIMIT ?`, prepared => prepared.all(...scope.params, ...uniqueConcepts, activeAt, activeAt, limit) as Array<{ scope_kind: ScopeRef['kind']; scope_id: string; memory_id: string }>);
|
|
578
|
+
return readAddresses(database, rows.map(row => ({ scope: { schemaVersion: 1, kind: row.scope_kind, id: row.scope_id }, id: row.memory_id })));
|
|
579
|
+
},
|
|
580
|
+
lexical(scopes, terms, limit, activeAt = new Date().toISOString()) {
|
|
581
|
+
if (!termIndexAvailable(database) || !scopes.length || !terms.length) return [];
|
|
582
|
+
const scope = scopePredicate(scopes);
|
|
583
|
+
const uniqueTerms = [...new Set(terms)].slice(0, 128);
|
|
584
|
+
const placeholders = uniqueTerms.map(() => '?').join(',');
|
|
585
|
+
const rows = statement(database, `
|
|
586
|
+
SELECT scope_kind, scope_id, memory_id, COUNT(*) AS hits
|
|
587
|
+
FROM cognition_term_index t
|
|
588
|
+
WHERE (${scope.sql}) AND term IN (${placeholders})
|
|
589
|
+
AND EXISTS (
|
|
590
|
+
SELECT 1 FROM cognition_memory_units m
|
|
591
|
+
WHERE m.scope_kind = t.scope_kind AND m.scope_id = t.scope_id AND m.memory_id = t.memory_id
|
|
592
|
+
AND m.retracted_at IS NULL AND m.valid_from <= ? AND (m.expires_at IS NULL OR m.expires_at > ?)
|
|
593
|
+
)
|
|
594
|
+
GROUP BY scope_kind, scope_id, memory_id
|
|
595
|
+
ORDER BY hits DESC, scope_kind ASC, scope_id ASC, memory_id ASC
|
|
596
|
+
LIMIT ?`, prepared => prepared.all(...scope.params, ...uniqueTerms, activeAt, activeAt, limit) as Array<{ scope_kind: ScopeRef['kind']; scope_id: string; memory_id: string }>);
|
|
597
|
+
return readAddresses(database, rows.map(row => ({ scope: { schemaVersion: 1, kind: row.scope_kind, id: row.scope_id }, id: row.memory_id })));
|
|
598
|
+
},
|
|
599
|
+
neighbors(seeds, limit, activeAt = new Date().toISOString()) {
|
|
600
|
+
if (!canonicalSchemaAvailable(database) || !seeds.length) return [];
|
|
601
|
+
const uniqueSeeds = [...new Map(seeds.map(seed => [memoryAddressKey(seed), seed])).values()].slice(0, 128);
|
|
602
|
+
const seedValues = uniqueSeeds.map(() => '(?, ?, ?)').join(',');
|
|
603
|
+
const seedParams = uniqueSeeds.flatMap(seed => [seed.scope.kind, seed.scope.id, seed.id]);
|
|
604
|
+
const rows = statement(database, `
|
|
605
|
+
WITH seeds(scope_kind, scope_id, memory_id) AS (VALUES ${seedValues})
|
|
606
|
+
SELECT e.*, s.memory_id AS seed_memory_id,
|
|
607
|
+
CASE WHEN e.from_memory_id = s.memory_id THEN e.to_memory_id ELSE e.from_memory_id END AS target_memory_id
|
|
608
|
+
FROM seeds s
|
|
609
|
+
JOIN cognition_memory_edges e
|
|
610
|
+
ON e.scope_kind = s.scope_kind AND e.scope_id = s.scope_id
|
|
611
|
+
AND (e.from_memory_id = s.memory_id OR e.to_memory_id = s.memory_id)
|
|
612
|
+
JOIN cognition_memory_units m
|
|
613
|
+
ON m.scope_kind = e.scope_kind AND m.scope_id = e.scope_id
|
|
614
|
+
AND m.memory_id = CASE WHEN e.from_memory_id = s.memory_id THEN e.to_memory_id ELSE e.from_memory_id END
|
|
615
|
+
WHERE e.retracted_at IS NULL AND (e.expires_at IS NULL OR e.expires_at > ?)
|
|
616
|
+
AND m.retracted_at IS NULL AND m.valid_from <= ? AND (m.expires_at IS NULL OR m.expires_at > ?)
|
|
617
|
+
ORDER BY e.weight DESC, e.recorded_at DESC, e.scope_kind ASC, e.scope_id ASC, e.edge_id ASC, s.memory_id ASC
|
|
618
|
+
LIMIT ?`, prepared => prepared.all(...seedParams, activeAt, activeAt, activeAt, limit) as Array<Record<string, unknown>>);
|
|
619
|
+
const seedKeys = new Map(uniqueSeeds.map(seed => [memoryAddressKey(seed), seed]));
|
|
620
|
+
const expansions: Array<{ edge: MemoryEdge; from: MemoryAddress; target: MemoryAddress }> = [];
|
|
621
|
+
for (const row of rows) {
|
|
622
|
+
const scope = { schemaVersion: 1 as const, kind: row.scope_kind as ScopeRef['kind'], id: row.scope_id as string };
|
|
623
|
+
const seed = seedKeys.get(memoryAddressKey({ scope, id: row.seed_memory_id as string }));
|
|
624
|
+
if (!seed) continue;
|
|
625
|
+
const target = { scope, id: row.target_memory_id as string };
|
|
626
|
+
const edge = validateMemoryEdge({
|
|
627
|
+
schemaVersion: 1,
|
|
628
|
+
id: row.edge_id as string,
|
|
629
|
+
scope,
|
|
630
|
+
fromId: row.from_memory_id as string,
|
|
631
|
+
toId: row.to_memory_id as string,
|
|
632
|
+
relation: row.relation as string,
|
|
633
|
+
weight: Number(row.weight),
|
|
634
|
+
evidenceRefs: JSON.parse(row.evidence_json as string) as string[],
|
|
635
|
+
...(row.source_work_id ? { sourceWorkId: row.source_work_id as string } : {}),
|
|
636
|
+
...(row.source_round_id ? { sourceRoundId: row.source_round_id as string } : {}),
|
|
637
|
+
recordedAt: row.recorded_at as string,
|
|
638
|
+
...(row.expires_at ? { expiresAt: row.expires_at as string } : {}),
|
|
639
|
+
...(row.retracted_at ? { retractedAt: row.retracted_at as string } : {}),
|
|
640
|
+
});
|
|
641
|
+
expansions.push({ edge, from: seed, target });
|
|
642
|
+
}
|
|
643
|
+
const memoryByAddress = new Map(readAddresses(database, expansions.map(item => item.target))
|
|
644
|
+
.map(memory => [memoryAddressKey({ scope: memory.scope, id: memory.id }), memory]));
|
|
645
|
+
return expansions.flatMap(item => {
|
|
646
|
+
const memory = memoryByAddress.get(memoryAddressKey(item.target));
|
|
647
|
+
return memory ? [{ edge: item.edge, from: item.from, memory }] : [];
|
|
648
|
+
});
|
|
649
|
+
},
|
|
650
|
+
};
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
|
|
654
|
+
export interface CognitiveAuditQuery {
|
|
655
|
+
scopes: readonly ScopeRef[];
|
|
656
|
+
query?: string;
|
|
657
|
+
memoryId?: string;
|
|
658
|
+
concept?: string;
|
|
659
|
+
facet?: string;
|
|
660
|
+
sourceKind?: MemoryUnit['provenance']['sourceKind'];
|
|
661
|
+
sourceWorkId?: string;
|
|
662
|
+
limit?: number;
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
export interface CognitiveAuditEntry {
|
|
666
|
+
memory: MemoryUnit;
|
|
667
|
+
relations: MemoryEdge[];
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
export interface CognitiveAuditResult {
|
|
671
|
+
items: CognitiveAuditEntry[];
|
|
672
|
+
inspected: number;
|
|
673
|
+
truncated: boolean;
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
function auditEdgeFromRow(row: Record<string, unknown>): MemoryEdge {
|
|
677
|
+
return validateMemoryEdge({
|
|
678
|
+
schemaVersion: 1,
|
|
679
|
+
id: row.edge_id as string,
|
|
680
|
+
scope: { schemaVersion: 1, kind: row.scope_kind as ScopeRef['kind'], id: row.scope_id as string },
|
|
681
|
+
fromId: row.from_memory_id as string,
|
|
682
|
+
toId: row.to_memory_id as string,
|
|
683
|
+
relation: row.relation as string,
|
|
684
|
+
weight: Number(row.weight),
|
|
685
|
+
evidenceRefs: JSON.parse(row.evidence_json as string) as string[],
|
|
686
|
+
...(row.source_work_id ? { sourceWorkId: row.source_work_id as string } : {}),
|
|
687
|
+
...(row.source_round_id ? { sourceRoundId: row.source_round_id as string } : {}),
|
|
688
|
+
recordedAt: row.recorded_at as string,
|
|
689
|
+
...(row.expires_at ? { expiresAt: row.expires_at as string } : {}),
|
|
690
|
+
...(row.retracted_at ? { retractedAt: row.retracted_at as string } : {}),
|
|
691
|
+
});
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
export function auditCognitiveMemory(controllerHome: string, input: CognitiveAuditQuery): CognitiveAuditResult {
|
|
695
|
+
const limit = Math.max(1, Math.min(Math.trunc(input.limit ?? 24), 100));
|
|
696
|
+
const uniqueScopes = [...new Map(input.scopes.map(scope => [`${scope.kind}:${scope.id}`, scope])).values()].slice(0, 32);
|
|
697
|
+
if (!uniqueScopes.length) return { items: [], inspected: 0, truncated: false };
|
|
698
|
+
return withControlPlaneReadDatabase(controllerHome, database => {
|
|
699
|
+
if (!canonicalSchemaAvailable(database)) return { items: [], inspected: 0, truncated: false };
|
|
700
|
+
const scopePredicate = uniqueScopes.map(() => '(scope_kind = ? AND scope_id = ?)').join(' OR ');
|
|
701
|
+
const params: unknown[] = uniqueScopes.flatMap(scope => [scope.kind, scope.id]);
|
|
702
|
+
const clauses = [`(${scopePredicate})`];
|
|
703
|
+
if (input.memoryId?.trim()) {
|
|
704
|
+
clauses.push('memory_id = ?');
|
|
705
|
+
params.push(input.memoryId.trim());
|
|
706
|
+
}
|
|
707
|
+
if (input.sourceKind) {
|
|
708
|
+
clauses.push('source_kind = ?');
|
|
709
|
+
params.push(input.sourceKind);
|
|
710
|
+
}
|
|
711
|
+
if (input.sourceWorkId?.trim()) {
|
|
712
|
+
clauses.push('source_work_id = ?');
|
|
713
|
+
params.push(input.sourceWorkId.trim());
|
|
714
|
+
}
|
|
715
|
+
const scanLimit = Math.min(512, Math.max(limit * 8, 64));
|
|
716
|
+
const rows = statement(database, `
|
|
717
|
+
SELECT * FROM cognition_memory_units
|
|
718
|
+
WHERE ${clauses.join(' AND ')}
|
|
719
|
+
ORDER BY utility DESC, confidence DESC, recorded_at DESC, scope_kind ASC, scope_id ASC, memory_id ASC
|
|
720
|
+
LIMIT ?`, prepared => prepared.all(...params, scanLimit) as Array<Record<string, unknown>>);
|
|
721
|
+
const exactMemoryId = input.memoryId?.trim();
|
|
722
|
+
const queryTerms = cognitiveTerms(input.query?.slice(0, 8_192) ?? '');
|
|
723
|
+
const concept = input.concept?.trim();
|
|
724
|
+
const facet = input.facet?.trim();
|
|
725
|
+
const memories = rows.map(row => {
|
|
726
|
+
const scope = { schemaVersion: 1 as const, kind: row.scope_kind as ScopeRef['kind'], id: row.scope_id as string };
|
|
727
|
+
const refs = evidenceFor(database, scope, row.memory_id as string);
|
|
728
|
+
return rowToMemory(row, refs.evidence, refs.counter);
|
|
729
|
+
}).filter(memory => !concept || memory.concepts.includes(concept))
|
|
730
|
+
.filter(memory => !facet || memory.facets.includes(facet))
|
|
731
|
+
.filter(memory => {
|
|
732
|
+
if (!queryTerms.size || exactMemoryId === memory.id) return true;
|
|
733
|
+
const terms = cognitiveTerms([
|
|
734
|
+
memory.id,
|
|
735
|
+
memory.canonicalText,
|
|
736
|
+
...memory.concepts,
|
|
737
|
+
...memory.facets,
|
|
738
|
+
memory.provenance.sourceId ?? '',
|
|
739
|
+
memory.provenance.sourceWorkId ?? '',
|
|
740
|
+
memory.provenance.sourceRoundId ?? '',
|
|
741
|
+
].join('\n'));
|
|
742
|
+
for (const term of queryTerms) if (terms.has(term)) return true;
|
|
743
|
+
return false;
|
|
744
|
+
});
|
|
745
|
+
const selected = memories.slice(0, limit);
|
|
746
|
+
const relationRows = selected.length ? statement(database, `
|
|
747
|
+
SELECT * FROM cognition_memory_edges
|
|
748
|
+
WHERE ${selected.map(() => '(scope_kind = ? AND scope_id = ? AND (from_memory_id = ? OR to_memory_id = ?))').join(' OR ')}
|
|
749
|
+
ORDER BY recorded_at DESC, weight DESC, edge_id ASC
|
|
750
|
+
LIMIT 512`, prepared => prepared.all(...selected.flatMap(memory => [
|
|
751
|
+
memory.scope.kind, memory.scope.id, memory.id, memory.id,
|
|
752
|
+
])) as Array<Record<string, unknown>>) : [];
|
|
753
|
+
const relations = relationRows.map(auditEdgeFromRow);
|
|
754
|
+
return {
|
|
755
|
+
items: selected.map(memory => ({
|
|
756
|
+
memory,
|
|
757
|
+
relations: relations.filter(edge => edge.scope.kind === memory.scope.kind
|
|
758
|
+
&& edge.scope.id === memory.scope.id
|
|
759
|
+
&& (edge.fromId === memory.id || edge.toId === memory.id)).slice(0, 32),
|
|
760
|
+
})),
|
|
761
|
+
inspected: rows.length,
|
|
762
|
+
truncated: memories.length > limit || rows.length >= scanLimit,
|
|
763
|
+
};
|
|
764
|
+
});
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
export function cognitionReadPort(controllerHome: string): CognitiveReadPort {
|
|
768
|
+
return {
|
|
769
|
+
readByIds: (scopes, ids) => withControlPlaneReadDatabase(controllerHome, database => readPortForDatabase(database).readByIds(scopes, ids)),
|
|
770
|
+
readByAddresses: addresses => withControlPlaneReadDatabase(controllerHome, database => readPortForDatabase(database).readByAddresses(addresses)),
|
|
771
|
+
exactByConcept: (scopes, concepts, limit, activeAt) => withControlPlaneReadDatabase(controllerHome, database => readPortForDatabase(database).exactByConcept(scopes, concepts, limit, activeAt)),
|
|
772
|
+
lexical: (scopes, terms, limit, activeAt) => withControlPlaneReadDatabase(controllerHome, database => readPortForDatabase(database).lexical(scopes, terms, limit, activeAt)),
|
|
773
|
+
neighbors: (seeds, limit, activeAt) => withControlPlaneReadDatabase(controllerHome, database => readPortForDatabase(database).neighbors(seeds, limit, activeAt)),
|
|
774
|
+
};
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
export function activateCognitiveMemory(
|
|
778
|
+
controllerHome: string,
|
|
779
|
+
scopes: readonly ScopeRef[],
|
|
780
|
+
query: string,
|
|
781
|
+
options: ActivationOptions = {},
|
|
782
|
+
): ActivationPack {
|
|
783
|
+
const derivedState = withControlPlaneReadDatabase(controllerHome, database => {
|
|
784
|
+
if (!canonicalSchemaAvailable(database)) return 'empty' as const;
|
|
785
|
+
return derivedIndexesHealthy(database) ? 'ready' as const : 'degraded' as const;
|
|
786
|
+
});
|
|
787
|
+
let rebuilt = false;
|
|
788
|
+
if (derivedState === 'degraded') {
|
|
789
|
+
try {
|
|
790
|
+
rebuildCognitionDerivedIndexes(controllerHome);
|
|
791
|
+
rebuilt = true;
|
|
792
|
+
} catch (error) {
|
|
793
|
+
throw new Error(`COGNITION_DERIVED_INDEX_RECOVERY_FAILED:${error instanceof Error ? error.message : String(error)}`);
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
const pack = withControlPlaneReadDatabase(controllerHome, database =>
|
|
797
|
+
activateMemory(readPortForDatabase(database), scopes, query, options));
|
|
798
|
+
return rebuilt ? { ...pack, gaps: [...new Set([...pack.gaps, 'derived_index_rebuilt'])] } : pack;
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
export function rebuildCognitionDerivedIndexes(controllerHome: string): number {
|
|
802
|
+
return withControlPlaneTransaction(controllerHome, database => {
|
|
803
|
+
database.exec(`
|
|
804
|
+
DROP INDEX IF EXISTS cognition_concept_lookup;
|
|
805
|
+
DROP INDEX IF EXISTS cognition_term_lookup;
|
|
806
|
+
DROP TABLE IF EXISTS cognition_concept_index;
|
|
807
|
+
DROP TABLE IF EXISTS cognition_term_index;
|
|
808
|
+
`);
|
|
809
|
+
ensureSchema(database);
|
|
810
|
+
const rows = statement(database,
|
|
811
|
+
'SELECT * FROM cognition_memory_units ORDER BY scope_kind, scope_id, memory_id',
|
|
812
|
+
prepared => prepared.all() as Array<Record<string, unknown>>);
|
|
813
|
+
for (const row of rows) {
|
|
814
|
+
const scope = { schemaVersion: 1 as const, kind: row.scope_kind as ScopeRef['kind'], id: row.scope_id as string };
|
|
815
|
+
const refs = evidenceFor(database, scope, row.memory_id as string);
|
|
816
|
+
replaceDerivedIndexes(database, rowToMemory(row, refs.evidence, refs.counter));
|
|
817
|
+
}
|
|
818
|
+
return rows.length;
|
|
819
|
+
});
|
|
820
|
+
}
|