@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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { copyFileSync, existsSync, mkdirSync, renameSync, statSync, unlinkSync } from 'fs';
|
|
3
|
+
import { closeSync, copyFileSync, existsSync, mkdirSync, openSync, readSync, renameSync, statSync, unlinkSync } from 'fs';
|
|
4
4
|
import { dirname, join } from 'path';
|
|
5
5
|
import { durableControllerHome } from '../../../cli/repositories/controller-home';
|
|
6
6
|
|
|
@@ -62,6 +62,36 @@ export interface ControlPlaneDatabaseInspection {
|
|
|
62
62
|
orphanRecordCount: number;
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
+
/**
|
|
66
|
+
* Ephemeral database-wide change fence. SQLite data_version changes whenever a
|
|
67
|
+
* different connection commits to the same database, including domain tables
|
|
68
|
+
* that do not participate in control_plane_audit.
|
|
69
|
+
*/
|
|
70
|
+
export interface ControlPlaneDatabaseChangeObserver {
|
|
71
|
+
path: string;
|
|
72
|
+
dataVersion(): number;
|
|
73
|
+
close(): void;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const CONTROL_PLANE_DATABASE_HASH_CHUNK_BYTES = 1024 * 1024;
|
|
77
|
+
|
|
78
|
+
/** Full snapshot identity without allocating the whole SQLite file. */
|
|
79
|
+
export function sha256ControlPlaneDatabaseFile(path: string): string {
|
|
80
|
+
const descriptor = openSync(path, 'r');
|
|
81
|
+
const hash = createHash('sha256');
|
|
82
|
+
const buffer = Buffer.allocUnsafe(CONTROL_PLANE_DATABASE_HASH_CHUNK_BYTES);
|
|
83
|
+
try {
|
|
84
|
+
for (;;) {
|
|
85
|
+
const bytesRead = readSync(descriptor, buffer, 0, buffer.length, null);
|
|
86
|
+
if (bytesRead === 0) break;
|
|
87
|
+
hash.update(buffer.subarray(0, bytesRead));
|
|
88
|
+
}
|
|
89
|
+
return hash.digest('hex');
|
|
90
|
+
} finally {
|
|
91
|
+
closeSync(descriptor);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
65
95
|
export const CONTROL_PLANE_SQLITE_MAINTENANCE_POLICY_VERSION = 'control-plane-sqlite-maintenance-v1' as const;
|
|
66
96
|
export const DEFAULT_CONTROL_PLANE_SQLITE_VACUUM_MIN_RECLAIMABLE_BYTES = 64 * 1024 * 1024;
|
|
67
97
|
export const DEFAULT_CONTROL_PLANE_SQLITE_VACUUM_MIN_RECLAIMABLE_RATIO = 0.20;
|
|
@@ -294,9 +324,10 @@ function openDatabase(controllerHome: string): SqliteDatabase {
|
|
|
294
324
|
// inspectOpenDatabase(), which is the authoritative integrity boundary.
|
|
295
325
|
// Keep schema fail-closed on every open, but reserve the full integrity scan
|
|
296
326
|
// for those lifecycle/inspection boundaries.
|
|
327
|
+
let schemaVersion: number | undefined;
|
|
297
328
|
if (existed) {
|
|
298
329
|
try {
|
|
299
|
-
assertSupportedSchema(database, path);
|
|
330
|
+
schemaVersion = assertSupportedSchema(database, path);
|
|
300
331
|
} catch (error) {
|
|
301
332
|
const busy = sqliteBusyError(path, error);
|
|
302
333
|
if (busy) throw busy;
|
|
@@ -306,8 +337,14 @@ function openDatabase(controllerHome: string): SqliteDatabase {
|
|
|
306
337
|
}
|
|
307
338
|
}
|
|
308
339
|
database.exec('PRAGMA journal_mode = WAL;');
|
|
309
|
-
|
|
310
|
-
|
|
340
|
+
// Schema DDL is bootstrap work, not transaction work. Existing supported
|
|
341
|
+
// databases have already crossed the fail-closed schema boundary above;
|
|
342
|
+
// rerunning CREATE INDEX/TABLE + INSERT OR IGNORE on every write only burns
|
|
343
|
+
// allocations/SQLite preparation and then validates the same schema twice.
|
|
344
|
+
if (schemaVersion === undefined) {
|
|
345
|
+
initializeSchema(database);
|
|
346
|
+
assertSupportedSchema(database, path, true);
|
|
347
|
+
}
|
|
311
348
|
return database;
|
|
312
349
|
} catch (error) {
|
|
313
350
|
database.close();
|
|
@@ -346,6 +383,27 @@ function openDatabaseForRead(controllerHome: string): SqliteDatabase {
|
|
|
346
383
|
return openDatabase(controllerHome);
|
|
347
384
|
}
|
|
348
385
|
|
|
386
|
+
export function openControlPlaneDatabaseChangeObserver(controllerHome: string): ControlPlaneDatabaseChangeObserver {
|
|
387
|
+
const path = controlPlaneDatabasePath(controllerHome);
|
|
388
|
+
const database = openDatabaseForRead(controllerHome);
|
|
389
|
+
let closed = false;
|
|
390
|
+
const dataVersion = () => {
|
|
391
|
+
if (closed) throw new Error('CONTROL_PLANE_DATABASE_CHANGE_OBSERVER_CLOSED');
|
|
392
|
+
return integerPragma(database, 'PRAGMA data_version', 'data_version');
|
|
393
|
+
};
|
|
394
|
+
// Prime the connection before returning it so the first caller observation
|
|
395
|
+
// is relative to an established SQLite connection, not connection startup.
|
|
396
|
+
dataVersion();
|
|
397
|
+
return {
|
|
398
|
+
path,
|
|
399
|
+
dataVersion,
|
|
400
|
+
close() {
|
|
401
|
+
if (closed) return;
|
|
402
|
+
closed = true;
|
|
403
|
+
database.close();
|
|
404
|
+
},
|
|
405
|
+
};
|
|
406
|
+
}
|
|
349
407
|
|
|
350
408
|
function withDatabaseForRead<T>(controllerHome: string, operation: (database: SqliteDatabase) => T): T {
|
|
351
409
|
const path = controlPlaneDatabasePath(controllerHome);
|
|
@@ -382,6 +440,11 @@ function withDatabaseForRead<T>(controllerHome: string, operation: (database: Sq
|
|
|
382
440
|
}
|
|
383
441
|
}
|
|
384
442
|
|
|
443
|
+
/** Read-only snapshot boundary for domain stores that need several indexed lookups in one hot-path operation. */
|
|
444
|
+
export function withControlPlaneReadDatabase<T>(controllerHome: string, operation: (database: SqliteDatabase) => T): T {
|
|
445
|
+
return withDatabaseForRead(controllerHome, operation);
|
|
446
|
+
}
|
|
447
|
+
|
|
385
448
|
function rowToRecord<T>(row: StoredRecordRow): ControlPlaneRecord<T> {
|
|
386
449
|
let value: T;
|
|
387
450
|
try {
|
|
@@ -508,6 +571,22 @@ export function readControlPlaneRecord<T>(controllerHome: string, namespace: str
|
|
|
508
571
|
selectRecord<T>(database, namespace, scope, key));
|
|
509
572
|
}
|
|
510
573
|
|
|
574
|
+
export function listControlPlaneRecordKeys(
|
|
575
|
+
controllerHome: string,
|
|
576
|
+
input: { namespace: string; scope: string; limit?: number },
|
|
577
|
+
): string[] {
|
|
578
|
+
const limit = Math.max(1, Math.min(Math.trunc(input.limit ?? 5_000), 5_000));
|
|
579
|
+
return withDatabaseForRead(controllerHome, (database) =>
|
|
580
|
+
withSqliteStatement(database, `
|
|
581
|
+
SELECT record_key
|
|
582
|
+
FROM control_plane_records
|
|
583
|
+
WHERE namespace = ? AND scope = ?
|
|
584
|
+
ORDER BY record_key ASC
|
|
585
|
+
LIMIT ?
|
|
586
|
+
`, (statement) => (statement.all(input.namespace, input.scope, limit) as Array<{ record_key: string }>)
|
|
587
|
+
.map((row) => row.record_key)));
|
|
588
|
+
}
|
|
589
|
+
|
|
511
590
|
export function writeControlPlaneRecord<T>(
|
|
512
591
|
controllerHome: string,
|
|
513
592
|
input: {
|
|
@@ -633,6 +712,24 @@ export function listControlPlaneRecords<T>(
|
|
|
633
712
|
listControlPlaneRecordsWithinTransaction<T>(database, input));
|
|
634
713
|
}
|
|
635
714
|
|
|
715
|
+
/** Exact stable-key lookup across scopes. This is a read of the existing Control Plane authority, not a second id registry. */
|
|
716
|
+
export function findControlPlaneRecordsByKey<T>(
|
|
717
|
+
controllerHome: string,
|
|
718
|
+
input: { namespace: string; key: string; limit?: number },
|
|
719
|
+
): ControlPlaneRecord<T>[] {
|
|
720
|
+
const limit = Math.max(1, Math.min(Math.trunc(input.limit ?? 2), 100));
|
|
721
|
+
return withDatabaseForRead(controllerHome, (database) => {
|
|
722
|
+
const rows = withSqliteStatement(database, `
|
|
723
|
+
SELECT namespace, scope, record_key, schema_version, revision, payload, created_at, updated_at
|
|
724
|
+
FROM control_plane_records
|
|
725
|
+
WHERE namespace = ? AND record_key = ?
|
|
726
|
+
ORDER BY scope ASC
|
|
727
|
+
LIMIT ?
|
|
728
|
+
`, (statement) => statement.all(input.namespace, input.key, limit));
|
|
729
|
+
return (rows as StoredRecordRow[]).map((row) => rowToRecord<T>(row));
|
|
730
|
+
});
|
|
731
|
+
}
|
|
732
|
+
|
|
636
733
|
/**
|
|
637
734
|
* Candidate-only read optimization for top-level JSON text fields. This never
|
|
638
735
|
* establishes domain authority: missing/null/non-text values remain candidates,
|
|
@@ -660,6 +757,11 @@ function payloadTextExclusionPredicate(input: PayloadTextExclusion): string {
|
|
|
660
757
|
return `${namespace} AND (${extraction} IS NULL OR ${extraction} NOT IN (${values.map(literal).join(', ')}))`;
|
|
661
758
|
}
|
|
662
759
|
|
|
760
|
+
function payloadTextExclusionIndexName(input: PayloadTextExclusion, predicate = payloadTextExclusionPredicate(input)): string {
|
|
761
|
+
const prefix = `control_plane_candidate_${createHash('sha256').update(`${input.namespace}/${input.field}`).digest('hex').slice(0, 16)}_`;
|
|
762
|
+
return `${prefix}${createHash('sha256').update(predicate).digest('hex').slice(0, 16)}`;
|
|
763
|
+
}
|
|
764
|
+
|
|
663
765
|
/** Explicit startup DDL. JSON remains authority; SQLite maintains the derived index in every write transaction. */
|
|
664
766
|
export function initializeControlPlanePayloadTextExclusionIndex(
|
|
665
767
|
controllerHome: string,
|
|
@@ -667,7 +769,7 @@ export function initializeControlPlanePayloadTextExclusionIndex(
|
|
|
667
769
|
): void {
|
|
668
770
|
const predicate = payloadTextExclusionPredicate(input);
|
|
669
771
|
const prefix = `control_plane_candidate_${createHash('sha256').update(`${input.namespace}/${input.field}`).digest('hex').slice(0, 16)}_`;
|
|
670
|
-
const name =
|
|
772
|
+
const name = payloadTextExclusionIndexName(input, predicate);
|
|
671
773
|
withControlPlaneTransaction(controllerHome, (database) => {
|
|
672
774
|
database.exec(`CREATE INDEX IF NOT EXISTS ${name} ON control_plane_records (scope, updated_at, record_key) WHERE ${predicate}`);
|
|
673
775
|
// Retire obsolete predicates for this domain field in the same transaction.
|
|
@@ -686,11 +788,16 @@ export function listControlPlaneRecordsExcludingPayloadTextValues<T>(
|
|
|
686
788
|
input: PayloadTextExclusion & { scope: string; limit?: number },
|
|
687
789
|
): ControlPlaneRecord<T>[] {
|
|
688
790
|
const predicate = payloadTextExclusionPredicate(input);
|
|
791
|
+
const candidateIndex = payloadTextExclusionIndexName(input, predicate);
|
|
689
792
|
const limit = Math.max(1, Math.min(Math.trunc(input.limit ?? 1_000), 5_000));
|
|
690
793
|
return withDatabaseForRead(controllerHome, (database) => {
|
|
794
|
+
const candidateIndexExists = withSqliteStatement(database,
|
|
795
|
+
"SELECT 1 AS present FROM sqlite_master WHERE type = 'index' AND name = ? LIMIT 1",
|
|
796
|
+
(statement) => statement.get(candidateIndex) != null);
|
|
797
|
+
const indexHint = candidateIndexExists ? ` INDEXED BY ${candidateIndex}` : '';
|
|
691
798
|
const rows = withSqliteStatement(database, `
|
|
692
799
|
SELECT namespace, scope, record_key, schema_version, revision, payload, created_at, updated_at
|
|
693
|
-
FROM control_plane_records
|
|
800
|
+
FROM control_plane_records${indexHint}
|
|
694
801
|
WHERE ${predicate} AND scope = ?
|
|
695
802
|
ORDER BY updated_at ASC, record_key ASC
|
|
696
803
|
LIMIT ?
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
} from 'fs';
|
|
9
9
|
import { basename, dirname, join, relative, resolve } from 'path';
|
|
10
10
|
import { measureReclaimablePath } from './lifecycle-retention-metrics';
|
|
11
|
+
import { inspectKnownGoodRecoveryBundle, type KnownGoodReleaseIdentity } from '../root/known-good-recovery';
|
|
11
12
|
|
|
12
13
|
const DEFAULT_RELEASE_RETENTION_GRACE_MS = 30 * 60_000;
|
|
13
14
|
const DEFAULT_STAGING_RETENTION_GRACE_MS = 6 * 60 * 60_000;
|
|
@@ -48,6 +49,14 @@ interface RuntimeProtection {
|
|
|
48
49
|
backupAuthoritySafe: boolean;
|
|
49
50
|
}
|
|
50
51
|
|
|
52
|
+
interface RuntimeReleasePublicationLease {
|
|
53
|
+
schemaVersion: 1;
|
|
54
|
+
pid: number;
|
|
55
|
+
operationId: string;
|
|
56
|
+
candidateReleasePath: string;
|
|
57
|
+
backupPath?: string;
|
|
58
|
+
}
|
|
59
|
+
|
|
51
60
|
interface LinkedReleaseProtection {
|
|
52
61
|
releasesRoot: string;
|
|
53
62
|
releasePaths: Set<string>;
|
|
@@ -61,26 +70,17 @@ function canonical(path: string): string {
|
|
|
61
70
|
}
|
|
62
71
|
}
|
|
63
72
|
|
|
64
|
-
/**
|
|
65
|
-
* Canonicalize a path even when its leaf has already been removed by resolving
|
|
66
|
-
* the nearest existing ancestor first and then projecting the missing suffix.
|
|
67
|
-
* This preserves filesystem identity across logical aliases such as macOS
|
|
68
|
-
* /var -> /private/var without requiring historical artifacts to still exist.
|
|
69
|
-
*/
|
|
70
|
-
function canonicalProjectedPath(path: string): string {
|
|
71
|
-
let cursor = resolve(path);
|
|
72
|
-
const missingSuffix: string[] = [];
|
|
73
|
-
while (!existsSync(cursor)) {
|
|
74
|
-
const parent = dirname(cursor);
|
|
75
|
-
if (parent === cursor) return resolve(path);
|
|
76
|
-
missingSuffix.unshift(basename(cursor));
|
|
77
|
-
cursor = parent;
|
|
78
|
-
}
|
|
79
|
-
return resolve(canonical(cursor), ...missingSuffix);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
73
|
function directChild(root: string, path: string): boolean {
|
|
83
|
-
|
|
74
|
+
// Resolve the parent rather than the child: a reclaimed path may no longer
|
|
75
|
+
// exist, while its managed parent still does (and may itself be a symlink).
|
|
76
|
+
// An existing child must not itself be a symlink; otherwise a lexical child
|
|
77
|
+
// under Controller Home could retain or delete an external target.
|
|
78
|
+
if (canonical(dirname(path)) !== canonical(root)) return false;
|
|
79
|
+
try {
|
|
80
|
+
return !lstatSync(path).isSymbolicLink();
|
|
81
|
+
} catch {
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
function entryExists(path: string): boolean {
|
|
@@ -151,31 +151,81 @@ function loadPackageConnectorReleaseProtection(controllerHome: string, releasesR
|
|
|
151
151
|
return canonical(releaseRoot);
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
-
function
|
|
154
|
+
function loadRecoveryKnownGoodProtection(
|
|
155
|
+
controllerHome: string,
|
|
156
|
+
releasesRoot: string,
|
|
157
|
+
rollbackReleasePaths: ReadonlySet<string>,
|
|
158
|
+
): Set<string> {
|
|
159
|
+
const protectedPaths = new Set<string>();
|
|
155
160
|
const knownGoodPath = join(controllerHome, 'recovery', 'state', 'known-good.json');
|
|
156
|
-
if (!existsSync(knownGoodPath)) return;
|
|
161
|
+
if (!existsSync(knownGoodPath)) return protectedPaths;
|
|
157
162
|
const parsed = JSON.parse(readFileSync(knownGoodPath, 'utf8')) as Record<string, unknown>;
|
|
158
|
-
|
|
163
|
+
// Schema v1 was metadata-only evidence. It deliberately has no retention
|
|
164
|
+
// authority: only v2 entries pass the same release + DB + service-contract
|
|
165
|
+
// recoverability check that Recovery uses before attesting known-good.
|
|
166
|
+
if (parsed.schemaVersion === 1) return protectedPaths;
|
|
167
|
+
if (parsed.schemaVersion !== 2 || !Array.isArray(parsed.releases)) {
|
|
159
168
|
throw new Error('standalone recovery known-good authority is invalid');
|
|
160
169
|
}
|
|
161
170
|
for (const raw of parsed.releases) {
|
|
162
171
|
if (!raw || typeof raw !== 'object' || Array.isArray(raw)) throw new Error('standalone recovery known-good release record is invalid');
|
|
163
|
-
const
|
|
164
|
-
const
|
|
165
|
-
const
|
|
166
|
-
|
|
167
|
-
const manifestPath = resolve(manifestPathValue);
|
|
168
|
-
const releaseRoot = dirname(manifestPath);
|
|
169
|
-
const exactHistoricalManifestPath = resolve(canonical(releasesRoot), releaseId, 'manifest.json');
|
|
170
|
-
const historicalManifestPath = canonicalProjectedPath(manifestPath);
|
|
172
|
+
const entry = raw as Record<string, unknown>;
|
|
173
|
+
const manifestPath = typeof entry.path === 'string' ? entry.path.trim() : '';
|
|
174
|
+
const revision = typeof entry.revision === 'string' ? entry.revision.trim() : '';
|
|
175
|
+
const releaseRoot = manifestPath ? dirname(resolve(manifestPath)) : '';
|
|
171
176
|
if (
|
|
172
|
-
|
|
173
|
-
||
|
|
174
|
-
||
|
|
175
|
-
|
|
177
|
+
!manifestPath
|
|
178
|
+
|| !revision
|
|
179
|
+
|| basename(manifestPath) !== 'manifest.json'
|
|
180
|
+
|| basename(releaseRoot) !== revision
|
|
181
|
+
|| !directChild(releasesRoot, releaseRoot)
|
|
182
|
+
) throw new Error('standalone recovery known-good release is outside runtime releases');
|
|
183
|
+
// Historical records are not protection. Do not inspect them after their
|
|
184
|
+
// release tree has been reclaimed, or one old record would block cleanup
|
|
185
|
+
// of every later candidate in the same pass.
|
|
186
|
+
if (!rollbackReleasePaths.has(canonical(releaseRoot))) continue;
|
|
187
|
+
let inspected;
|
|
188
|
+
try {
|
|
189
|
+
inspected = inspectKnownGoodRecoveryBundle(controllerHome, raw as KnownGoodReleaseIdentity);
|
|
190
|
+
} catch (error) {
|
|
191
|
+
throw new Error(`standalone recovery known-good bundle is not recoverable: ${error instanceof Error ? error.message : String(error)}`);
|
|
192
|
+
}
|
|
193
|
+
const inspectedReleaseRoot = canonical(dirname(inspected.releaseRoot));
|
|
194
|
+
if (inspectedReleaseRoot !== canonical(releasesRoot)) {
|
|
176
195
|
throw new Error('standalone recovery known-good release is outside runtime releases');
|
|
177
196
|
}
|
|
197
|
+
// Historical attestations are evidence, not rollback authority. Recovery
|
|
198
|
+
// can only target releases currently named by the committed Runtime.
|
|
199
|
+
protectedPaths.add(canonical(inspected.releaseRoot));
|
|
178
200
|
}
|
|
201
|
+
return protectedPaths;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function loadPinnedRuntimeReleaseProtection(controllerHome: string, releasesRoot: string): string | undefined {
|
|
205
|
+
const pinPath = join(controllerHome, 'recovery', 'state', 'runtime-pin.json');
|
|
206
|
+
if (!existsSync(pinPath)) return undefined;
|
|
207
|
+
let parsed: Record<string, unknown>;
|
|
208
|
+
try { parsed = JSON.parse(readFileSync(pinPath, 'utf8')) as Record<string, unknown>; }
|
|
209
|
+
catch (error) { throw new Error(`runtime pin authority is invalid: ${error instanceof Error ? error.message : String(error)}`); }
|
|
210
|
+
const release = parsed.release;
|
|
211
|
+
if (parsed.schemaVersion !== 1 || !release || typeof release !== 'object' || Array.isArray(release)) {
|
|
212
|
+
throw new Error('runtime pin authority is invalid');
|
|
213
|
+
}
|
|
214
|
+
const record = release as Record<string, unknown>;
|
|
215
|
+
const releaseId = typeof record.revision === 'string' ? record.revision.trim() : '';
|
|
216
|
+
const manifestPathValue = typeof record.path === 'string' ? record.path.trim() : '';
|
|
217
|
+
if (!releaseId || !manifestPathValue) throw new Error('runtime pin release identity is incomplete');
|
|
218
|
+
const manifestPath = resolve(manifestPathValue);
|
|
219
|
+
const releaseRoot = dirname(manifestPath);
|
|
220
|
+
if (
|
|
221
|
+
basename(manifestPath) !== 'manifest.json'
|
|
222
|
+
|| basename(releaseRoot) !== releaseId
|
|
223
|
+
|| !directChild(releasesRoot, releaseRoot)
|
|
224
|
+
|| !existsSync(releaseRoot)
|
|
225
|
+
) {
|
|
226
|
+
throw new Error('runtime pin release is outside runtime release authority or missing');
|
|
227
|
+
}
|
|
228
|
+
return canonical(releaseRoot);
|
|
179
229
|
}
|
|
180
230
|
|
|
181
231
|
function loadRuntimeProtection(controllerHome: string): RuntimeProtection | undefined {
|
|
@@ -186,11 +236,12 @@ function loadRuntimeProtection(controllerHome: string): RuntimeProtection | unde
|
|
|
186
236
|
if (!existsSync(authorityPath)) throw new Error('runtime release authority is missing');
|
|
187
237
|
|
|
188
238
|
const parsed = JSON.parse(readFileSync(authorityPath, 'utf8')) as Record<string, unknown>;
|
|
189
|
-
if (parsed.schemaVersion !==
|
|
190
|
-
throw new Error('runtime release authority is not committed schemaVersion=
|
|
239
|
+
if (parsed.schemaVersion !== 2 || parsed.status !== 'committed') {
|
|
240
|
+
throw new Error('runtime release authority is not committed schemaVersion=2');
|
|
191
241
|
}
|
|
192
242
|
|
|
193
243
|
const releasePaths = new Set<string>();
|
|
244
|
+
const backupPaths = new Set<string>();
|
|
194
245
|
releasePaths.add(releasePathFromAuthorityRecord(releasesRoot, parsed.active, 'active'));
|
|
195
246
|
const previous = parsed.previous;
|
|
196
247
|
if (previous !== undefined) {
|
|
@@ -198,17 +249,54 @@ function loadRuntimeProtection(controllerHome: string): RuntimeProtection | unde
|
|
|
198
249
|
}
|
|
199
250
|
const connectorRelease = loadPackageConnectorReleaseProtection(controllerHome, releasesRoot);
|
|
200
251
|
if (connectorRelease) releasePaths.add(connectorRelease);
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
//
|
|
204
|
-
//
|
|
205
|
-
//
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
252
|
+
const pinnedRelease = loadPinnedRuntimeReleaseProtection(controllerHome, releasesRoot);
|
|
253
|
+
if (pinnedRelease) releasePaths.add(pinnedRelease);
|
|
254
|
+
// Only known-good entries that are also named by the committed Runtime
|
|
255
|
+
// authority are rollback protection. Older attestations are historical
|
|
256
|
+
// evidence and must not pin immutable release trees.
|
|
257
|
+
for (const knownGoodRelease of loadRecoveryKnownGoodProtection(controllerHome, releasesRoot, releasePaths)) {
|
|
258
|
+
releasePaths.add(knownGoodRelease);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// A publication writes the rollback backup before it atomically updates
|
|
262
|
+
// authority.json. Keep both the candidate tree and backup leased for the
|
|
263
|
+
// lifetime of that publication, so periodic cleanup cannot win the race.
|
|
264
|
+
const publicationLeasesRoot = join(releasesRoot, '.publication-leases');
|
|
265
|
+
if (existsSync(publicationLeasesRoot)) {
|
|
266
|
+
for (const entry of readdirSync(publicationLeasesRoot, { withFileTypes: true })) {
|
|
267
|
+
if (!entry.isFile() || !entry.name.endsWith('.json')) continue;
|
|
268
|
+
const leasePath = join(publicationLeasesRoot, entry.name);
|
|
269
|
+
let lease: RuntimeReleasePublicationLease;
|
|
270
|
+
try {
|
|
271
|
+
lease = JSON.parse(readFileSync(leasePath, 'utf8')) as RuntimeReleasePublicationLease;
|
|
272
|
+
} catch (error) {
|
|
273
|
+
throw new Error(`runtime release publication lease is invalid: ${error instanceof Error ? error.message : String(error)}`);
|
|
274
|
+
}
|
|
275
|
+
if (
|
|
276
|
+
lease.schemaVersion !== 1
|
|
277
|
+
|| !Number.isInteger(lease.pid)
|
|
278
|
+
|| lease.pid <= 0
|
|
279
|
+
|| typeof lease.operationId !== 'string'
|
|
280
|
+
|| !lease.operationId.trim()
|
|
281
|
+
|| typeof lease.candidateReleasePath !== 'string'
|
|
282
|
+
|| !directChild(releasesRoot, resolve(lease.candidateReleasePath))
|
|
283
|
+
) throw new Error('runtime release publication lease is invalid');
|
|
284
|
+
let alive = true;
|
|
285
|
+
try { process.kill(lease.pid, 0); } catch (error) {
|
|
286
|
+
alive = (error as NodeJS.ErrnoException).code === 'EPERM';
|
|
287
|
+
}
|
|
288
|
+
if (!alive) {
|
|
289
|
+
rmSync(leasePath, { force: true });
|
|
290
|
+
continue;
|
|
291
|
+
}
|
|
292
|
+
releasePaths.add(canonical(lease.candidateReleasePath));
|
|
293
|
+
if (lease.backupPath !== undefined) {
|
|
294
|
+
if (!directChild(backupsRoot, resolve(lease.backupPath))) throw new Error('runtime release publication lease backup is invalid');
|
|
295
|
+
backupPaths.add(canonical(lease.backupPath));
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
210
299
|
|
|
211
|
-
const backupPaths = new Set<string>();
|
|
212
300
|
let backupAuthoritySafe = true;
|
|
213
301
|
if (previous && typeof previous === 'object' && !Array.isArray(previous)) {
|
|
214
302
|
const databaseBackup = (previous as Record<string, unknown>).databaseBackup;
|
|
@@ -321,7 +409,7 @@ function scanRuntimeReleases(
|
|
|
321
409
|
if (!protection) return;
|
|
322
410
|
|
|
323
411
|
for (const entry of readdirSync(protection.releasesRoot, { withFileTypes: true })) {
|
|
324
|
-
if (entry.name === 'backups' || entry.name === 'authority.json') continue;
|
|
412
|
+
if (entry.name === 'backups' || entry.name === 'authority.json' || entry.name === '.publication-leases') continue;
|
|
325
413
|
const path = join(protection.releasesRoot, entry.name);
|
|
326
414
|
state.inspected += 1;
|
|
327
415
|
|
|
@@ -5,7 +5,7 @@ import { listRepositories } from '../../cli/repositories/registry';
|
|
|
5
5
|
import { listActiveExecutionJobs } from '../execution/jobs/store';
|
|
6
6
|
import { listActiveProcessIds } from '../execution/process-runtime/store';
|
|
7
7
|
import { listActiveLeases } from '../resources/leases/store';
|
|
8
|
-
import {
|
|
8
|
+
import { isTerminalSemanticWorkState, readWorkContractStore } from '../../../packages/kernel/work/api/index';
|
|
9
9
|
import { listControlPlaneRecords } from './persistence/sqlite-store';
|
|
10
10
|
import { measureReclaimablePath } from './lifecycle-retention-metrics';
|
|
11
11
|
|
|
@@ -88,7 +88,7 @@ function activeAuthorityBlockers(controllerHome: string, repoId: string): string
|
|
|
88
88
|
|
|
89
89
|
const workStore = readWorkContractStore({ controllerHome, repoId });
|
|
90
90
|
for (const work of workStore.contracts) {
|
|
91
|
-
if (!
|
|
91
|
+
if (!isTerminalSemanticWorkState(work.semanticState)) {
|
|
92
92
|
blockers.push('active_work');
|
|
93
93
|
break;
|
|
94
94
|
}
|