@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,191 @@
|
|
|
1
|
+
import { randomBytes } from 'crypto';
|
|
2
|
+
import { existsSync, mkdirSync, rmSync, statSync, writeFileSync } from 'fs';
|
|
3
|
+
import { chmodSync } from 'fs';
|
|
4
|
+
import { basename, dirname, join, resolve } from 'path';
|
|
5
|
+
import { backupControlPlaneDatabase, type ControlPlaneDatabaseInspection } from '../control-plane/persistence/sqlite-store';
|
|
6
|
+
import { normalizeRuntimeDeploymentTopology } from './deployment-topology';
|
|
7
|
+
import { forgeRuntimeServicePaths, readForgeRuntimeServiceConfig, writeForgeRuntimeServiceConfig, type ForgeRuntimeServiceConfig } from './service';
|
|
8
|
+
|
|
9
|
+
export interface StableExecutionLane {
|
|
10
|
+
schemaVersion: 1;
|
|
11
|
+
kind: 'stable';
|
|
12
|
+
controllerHome: string;
|
|
13
|
+
serviceLabel: string;
|
|
14
|
+
port: number;
|
|
15
|
+
authTokenFile: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface CandidateExecutionLane {
|
|
19
|
+
schemaVersion: 1;
|
|
20
|
+
kind: 'candidate';
|
|
21
|
+
sessionId: string;
|
|
22
|
+
controllerHome: string;
|
|
23
|
+
serviceLabel: string;
|
|
24
|
+
port: number;
|
|
25
|
+
authTokenFile: string;
|
|
26
|
+
databaseSnapshotPath: string;
|
|
27
|
+
sourceStableControllerHome: string;
|
|
28
|
+
createdAt: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function requireSessionId(value: string): string {
|
|
32
|
+
const sessionId = value.trim();
|
|
33
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9_-]{7,119}$/.test(sessionId)) {
|
|
34
|
+
throw new Error('RUNTIME_CANDIDATE_SESSION_ID_INVALID');
|
|
35
|
+
}
|
|
36
|
+
return sessionId;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function requireCandidatePort(port: number, stablePort: number): number {
|
|
40
|
+
if (!Number.isInteger(port) || port < 1 || port > 65_535) throw new Error('RUNTIME_CANDIDATE_PORT_INVALID');
|
|
41
|
+
if (port === stablePort) throw new Error('RUNTIME_CANDIDATE_PORT_COLLIDES_WITH_STABLE');
|
|
42
|
+
return port;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function candidateTokenPath(controllerHome: string): string {
|
|
46
|
+
return join(controllerHome, 'mcp', 'runtime-token');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function readStableExecutionLane(controllerHome: string): StableExecutionLane {
|
|
50
|
+
const home = resolve(controllerHome);
|
|
51
|
+
const paths = forgeRuntimeServicePaths(home);
|
|
52
|
+
const config = readForgeRuntimeServiceConfig(paths.configPath, { missingRepositoryRoot: 'omit' });
|
|
53
|
+
return {
|
|
54
|
+
schemaVersion: 1,
|
|
55
|
+
kind: 'stable',
|
|
56
|
+
controllerHome: home,
|
|
57
|
+
serviceLabel: paths.label,
|
|
58
|
+
port: config.port,
|
|
59
|
+
authTokenFile: config.authTokenFile,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Pure lane derivation. It never starts a service or writes either Home. */
|
|
64
|
+
export function planCandidateExecutionLane(input: {
|
|
65
|
+
stable: StableExecutionLane;
|
|
66
|
+
candidateControllerHome: string;
|
|
67
|
+
candidatePort: number;
|
|
68
|
+
sessionId: string;
|
|
69
|
+
}): CandidateExecutionLane {
|
|
70
|
+
const candidateHome = resolve(input.candidateControllerHome);
|
|
71
|
+
if (candidateHome === resolve(input.stable.controllerHome)) {
|
|
72
|
+
throw new Error('RUNTIME_CANDIDATE_CONTROLLER_HOME_COLLIDES_WITH_STABLE');
|
|
73
|
+
}
|
|
74
|
+
const port = requireCandidatePort(input.candidatePort, input.stable.port);
|
|
75
|
+
const paths = forgeRuntimeServicePaths(candidateHome);
|
|
76
|
+
if (paths.label === input.stable.serviceLabel) throw new Error('RUNTIME_CANDIDATE_SERVICE_LABEL_COLLIDES_WITH_STABLE');
|
|
77
|
+
return {
|
|
78
|
+
schemaVersion: 1,
|
|
79
|
+
kind: 'candidate',
|
|
80
|
+
sessionId: requireSessionId(input.sessionId),
|
|
81
|
+
controllerHome: candidateHome,
|
|
82
|
+
serviceLabel: paths.label,
|
|
83
|
+
port,
|
|
84
|
+
authTokenFile: candidateTokenPath(candidateHome),
|
|
85
|
+
databaseSnapshotPath: join(candidateHome, 'control-plane.sqlite'),
|
|
86
|
+
sourceStableControllerHome: resolve(input.stable.controllerHome),
|
|
87
|
+
createdAt: new Date().toISOString(),
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function createPrivateCandidateToken(stableTokenPath: string, destination: string): void {
|
|
92
|
+
if (!existsSync(stableTokenPath) || !statSync(stableTokenPath).isFile()) {
|
|
93
|
+
throw new Error('RUNTIME_CANDIDATE_STABLE_AUTH_TOKEN_MISSING');
|
|
94
|
+
}
|
|
95
|
+
mkdirSync(dirname(destination), { recursive: true, mode: 0o700 });
|
|
96
|
+
writeFileSync(destination, `${randomBytes(32).toString('base64url')}\n`, { encoding: 'utf8', mode: 0o600, flag: 'wx' });
|
|
97
|
+
try { chmodSync(destination, 0o600); } catch { /* platform best effort */ }
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function candidateServiceConfig(stable: ForgeRuntimeServiceConfig, lane: CandidateExecutionLane): ForgeRuntimeServiceConfig {
|
|
101
|
+
const topology = normalizeRuntimeDeploymentTopology(stable.topology);
|
|
102
|
+
return {
|
|
103
|
+
...stable,
|
|
104
|
+
controllerHome: lane.controllerHome,
|
|
105
|
+
port: lane.port,
|
|
106
|
+
authTokenFile: lane.authTokenFile,
|
|
107
|
+
// Candidate B may verify the Supervisor socket and internal lifecycle,
|
|
108
|
+
// but it must never submit external browser effects against Stable A's
|
|
109
|
+
// real conversation during an isolated canary.
|
|
110
|
+
topology: {
|
|
111
|
+
...topology,
|
|
112
|
+
components: { ...topology.components },
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Create the only permitted Candidate B mutable foundation: a fresh Controller
|
|
119
|
+
* Home with a consistent SQLite snapshot and an independent declarative
|
|
120
|
+
* service contract. It deliberately does not copy Stable A's Runtime release
|
|
121
|
+
* authority and never starts/stops a service; portable artifacts are published into B under B's own authority.
|
|
122
|
+
*/
|
|
123
|
+
export function createCandidateExecutionLane(input: {
|
|
124
|
+
stableControllerHome: string;
|
|
125
|
+
candidateControllerHome: string;
|
|
126
|
+
candidatePort: number;
|
|
127
|
+
sessionId: string;
|
|
128
|
+
}): { stable: StableExecutionLane; candidate: CandidateExecutionLane; database: ControlPlaneDatabaseInspection } {
|
|
129
|
+
const stable = readStableExecutionLane(input.stableControllerHome);
|
|
130
|
+
const candidate = planCandidateExecutionLane({
|
|
131
|
+
stable,
|
|
132
|
+
candidateControllerHome: input.candidateControllerHome,
|
|
133
|
+
candidatePort: input.candidatePort,
|
|
134
|
+
sessionId: input.sessionId,
|
|
135
|
+
});
|
|
136
|
+
if (existsSync(candidate.controllerHome)) throw new Error('RUNTIME_CANDIDATE_CONTROLLER_HOME_ALREADY_EXISTS');
|
|
137
|
+
try {
|
|
138
|
+
createPrivateCandidateToken(stable.authTokenFile, candidate.authTokenFile);
|
|
139
|
+
const database = backupControlPlaneDatabase(stable.controllerHome, candidate.databaseSnapshotPath);
|
|
140
|
+
writeForgeRuntimeServiceConfig(candidateServiceConfig(
|
|
141
|
+
readForgeRuntimeServiceConfig(forgeRuntimeServicePaths(stable.controllerHome).configPath, { missingRepositoryRoot: 'omit' }),
|
|
142
|
+
candidate,
|
|
143
|
+
));
|
|
144
|
+
assertCandidateExecutionLaneIsolation(stable, candidate);
|
|
145
|
+
return { stable, candidate, database };
|
|
146
|
+
} catch (error) {
|
|
147
|
+
// No recursive cleanup is attempted here: this function never guesses at
|
|
148
|
+
// a pre-existing user directory. The only writable target was required to
|
|
149
|
+
// be absent, so the caller can inspect or explicitly retire a partial B.
|
|
150
|
+
throw error;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export function assertCandidateExecutionLaneIsolation(
|
|
155
|
+
stable: StableExecutionLane,
|
|
156
|
+
candidate: CandidateExecutionLane,
|
|
157
|
+
): void {
|
|
158
|
+
if (resolve(stable.controllerHome) === resolve(candidate.controllerHome)) {
|
|
159
|
+
throw new Error('RUNTIME_CANDIDATE_CONTROLLER_HOME_COLLIDES_WITH_STABLE');
|
|
160
|
+
}
|
|
161
|
+
if (stable.port === candidate.port) throw new Error('RUNTIME_CANDIDATE_PORT_COLLIDES_WITH_STABLE');
|
|
162
|
+
if (stable.serviceLabel === candidate.serviceLabel) throw new Error('RUNTIME_CANDIDATE_SERVICE_LABEL_COLLIDES_WITH_STABLE');
|
|
163
|
+
if (resolve(stable.authTokenFile) === resolve(candidate.authTokenFile)) {
|
|
164
|
+
throw new Error('RUNTIME_CANDIDATE_AUTH_TOKEN_COLLIDES_WITH_STABLE');
|
|
165
|
+
}
|
|
166
|
+
if (resolve(candidate.databaseSnapshotPath) !== resolve(candidate.controllerHome, 'control-plane.sqlite')) {
|
|
167
|
+
throw new Error('RUNTIME_CANDIDATE_DATABASE_PATH_INVALID');
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Remove one retired Candidate B home after its ReleaseSession has reached a
|
|
173
|
+
* terminal state. The path fence is deliberately derived from Stable A and
|
|
174
|
+
* the session identity so terminal cleanup can never target an arbitrary
|
|
175
|
+
* Controller Home.
|
|
176
|
+
*/
|
|
177
|
+
export function removeRetiredCandidateExecutionLane(
|
|
178
|
+
stable: StableExecutionLane,
|
|
179
|
+
candidate: Pick<CandidateExecutionLane, 'controllerHome' | 'sessionId'>,
|
|
180
|
+
): boolean {
|
|
181
|
+
const stableHome = resolve(stable.controllerHome);
|
|
182
|
+
const candidateHome = resolve(candidate.controllerHome);
|
|
183
|
+
const candidateRoot = resolve(dirname(stableHome), 'candidate-runtime-lanes');
|
|
184
|
+
if (candidateHome === stableHome) throw new Error('RUNTIME_CANDIDATE_CLEANUP_STABLE_COLLISION');
|
|
185
|
+
if (resolve(dirname(candidateHome)) !== candidateRoot || basename(candidateHome) !== candidate.sessionId) {
|
|
186
|
+
throw new Error('RUNTIME_CANDIDATE_CLEANUP_PATH_INVALID');
|
|
187
|
+
}
|
|
188
|
+
if (!existsSync(candidateHome)) return false;
|
|
189
|
+
rmSync(candidateHome, { recursive: true, force: true });
|
|
190
|
+
return true;
|
|
191
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { randomUUID } from 'crypto';
|
|
2
|
-
import {
|
|
2
|
+
import { statSync } from 'fs';
|
|
3
3
|
import { writeJsonAtomic } from '../shared/json-files';
|
|
4
4
|
import { ensureForgeInstanceIdentity } from '../../../packages/kernel/identity/api/index';
|
|
5
5
|
import { dirname, join } from 'path';
|
|
@@ -10,7 +10,6 @@ import {
|
|
|
10
10
|
enableControlPlaneReadConnectionReuse,
|
|
11
11
|
inspectControlPlaneDatabase,
|
|
12
12
|
} from '../control-plane/persistence/sqlite-store';
|
|
13
|
-
import { activateExclusiveWorkAdmission } from '../control-plane/facade/work-admission-policy';
|
|
14
13
|
import { closeCodeGraphReadProviderSessions } from '../context/codegraph-read-provider';
|
|
15
14
|
import { cancelAllLightweightProcesses } from '../execution/process-runtime/lightweight-managed';
|
|
16
15
|
import {
|
|
@@ -24,11 +23,14 @@ import { acquireRuntimeOwnership, type RuntimeOwnershipHandle } from './ownershi
|
|
|
24
23
|
import { RuntimeReadinessState } from './readiness';
|
|
25
24
|
import { loadRuntimeReleaseManifest, requireCompleteCompiledRuntimeReleaseManifest } from './release-manifest';
|
|
26
25
|
import { ensureActiveRuntimeRelease, readRuntimeReleaseAuthority, type RuntimeReleaseAuthority } from './release-store';
|
|
26
|
+
import { migrateReleaseDurableState } from '../release/release-state-migration';
|
|
27
27
|
import { bindRuntimeWriteClaim, clearRuntimeWriteClaim } from './write-fence';
|
|
28
28
|
import { startInProcessScheduler, type RuntimeSchedulerHandle } from './scheduler';
|
|
29
29
|
import { startConfiguredRuntimeLocalBridge, type RuntimeLocalBridgeHandle } from './local-bridge';
|
|
30
30
|
import { startActiveExecutionPowerAssertion, type RuntimePowerAssertionHandle } from './active-execution-power-assertion';
|
|
31
|
-
import {
|
|
31
|
+
import { startWorkflowSupervisorRuntime, type RuntimeWorkflowSupervisorHandle } from './workflow-supervisor-runtime';
|
|
32
|
+
import { normalizeRuntimeDeploymentTopology, type RuntimeDeploymentTopology } from './deployment-topology';
|
|
33
|
+
import { removeRuntimeStartupFailureEvidence, removeRuntimeStatusSnapshot, writeRuntimeStartupFailureEvidence, writeRuntimeStatusSnapshot } from './status';
|
|
32
34
|
import type {
|
|
33
35
|
CanonicalRuntimeConfig,
|
|
34
36
|
CanonicalRuntimeStatusSnapshot,
|
|
@@ -43,6 +45,7 @@ export interface RuntimeReleaseAuthorityMonitor {
|
|
|
43
45
|
|
|
44
46
|
export interface CanonicalRuntimeDependencies {
|
|
45
47
|
loadReleaseManifest(path: string, controllerHome: string): RuntimeReleaseManifest;
|
|
48
|
+
migrateReleaseState(controllerHome: string): void;
|
|
46
49
|
ensureReleaseAuthority(controllerHome: string, manifestPath: string): RuntimeReleaseAuthority;
|
|
47
50
|
readReleaseAuthority(controllerHome: string): RuntimeReleaseAuthority | undefined;
|
|
48
51
|
startReleaseAuthorityMonitor(observe: () => void): RuntimeReleaseAuthorityMonitor;
|
|
@@ -52,6 +55,7 @@ export interface CanonicalRuntimeDependencies {
|
|
|
52
55
|
startScheduler(input: Parameters<typeof startInProcessScheduler>[0]): RuntimeSchedulerHandle;
|
|
53
56
|
startLocalBridge(input: { controllerHome: string; repositoryRoot?: string }): Promise<RuntimeLocalBridgeHandle | undefined>;
|
|
54
57
|
startPowerAssertion(input: { controllerHome: string; runtimePid: number }): RuntimePowerAssertionHandle;
|
|
58
|
+
startWorkflowSupervisor(controllerHome: string, options?: { nativeBrowserAdapter?: boolean }): Promise<RuntimeWorkflowSupervisorHandle>;
|
|
55
59
|
startTransport(options: Parameters<typeof startRuntimeMcpTransport>[0]): Promise<RuntimeMcpTransportHandle>;
|
|
56
60
|
runMcpProbe(endpoint: string, authToken: string): Promise<void>;
|
|
57
61
|
collectRuntimeSourceIdentity: typeof collectRuntimeSourceIdentity;
|
|
@@ -60,7 +64,20 @@ export interface CanonicalRuntimeDependencies {
|
|
|
60
64
|
stopContextReadHelpers(): Promise<void>;
|
|
61
65
|
computeToolSurfaceFingerprint: typeof runtimeGatewayToolSurfaceFingerprint;
|
|
62
66
|
ensureForgeInstanceIdentity: typeof ensureForgeInstanceIdentity;
|
|
63
|
-
|
|
67
|
+
captureJscSamplingProfile(options: { durationMs: number; sampleIntervalUs: number }): Promise<{
|
|
68
|
+
requestedDurationMs: number;
|
|
69
|
+
elapsedMs: number;
|
|
70
|
+
sampleIntervalUs: number;
|
|
71
|
+
functions: string;
|
|
72
|
+
bytecodes: string;
|
|
73
|
+
stackTraces: {
|
|
74
|
+
interval: number | null;
|
|
75
|
+
totalTraceCount: number;
|
|
76
|
+
retainedTraceCount: number;
|
|
77
|
+
traces: Array<{ timestamp: number | null; frames: Array<Record<string, unknown>> }>;
|
|
78
|
+
sources: Array<Record<string, unknown>>;
|
|
79
|
+
};
|
|
80
|
+
}>;
|
|
64
81
|
}
|
|
65
82
|
|
|
66
83
|
async function defaultMcpProbe(endpoint: string, authToken: string): Promise<void> {
|
|
@@ -87,6 +104,12 @@ async function defaultMcpProbe(endpoint: string, authToken: string): Promise<voi
|
|
|
87
104
|
}
|
|
88
105
|
|
|
89
106
|
const DEFAULT_RELEASE_AUTHORITY_MONITOR_INTERVAL_MS = 1_000;
|
|
107
|
+
const JSC_SAMPLING_DURATION_MS = 2_000;
|
|
108
|
+
const JSC_SAMPLING_INTERVAL_US = 1_000;
|
|
109
|
+
const JSC_SAMPLING_TRACE_LIMIT = 2_000;
|
|
110
|
+
const JSC_SAMPLING_FRAME_LIMIT = 32;
|
|
111
|
+
const JSC_SAMPLING_SOURCE_LIMIT = 512;
|
|
112
|
+
const JSC_SAMPLING_REPORT_CHAR_LIMIT = 128 * 1024;
|
|
90
113
|
|
|
91
114
|
function startDefaultReleaseAuthorityMonitor(observe: () => void): RuntimeReleaseAuthorityMonitor {
|
|
92
115
|
const timer = setInterval(observe, DEFAULT_RELEASE_AUTHORITY_MONITOR_INTERVAL_MS);
|
|
@@ -94,14 +117,70 @@ function startDefaultReleaseAuthorityMonitor(observe: () => void): RuntimeReleas
|
|
|
94
117
|
return { stop: () => clearInterval(timer) };
|
|
95
118
|
}
|
|
96
119
|
|
|
97
|
-
async function
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
120
|
+
async function captureDefaultJscSamplingProfile(options: { durationMs: number; sampleIntervalUs: number }): Promise<{
|
|
121
|
+
requestedDurationMs: number;
|
|
122
|
+
elapsedMs: number;
|
|
123
|
+
sampleIntervalUs: number;
|
|
124
|
+
functions: string;
|
|
125
|
+
bytecodes: string;
|
|
126
|
+
stackTraces: {
|
|
127
|
+
interval: number | null;
|
|
128
|
+
totalTraceCount: number;
|
|
129
|
+
retainedTraceCount: number;
|
|
130
|
+
traces: Array<{ timestamp: number | null; frames: Array<Record<string, unknown>> }>;
|
|
131
|
+
sources: Array<Record<string, unknown>>;
|
|
132
|
+
};
|
|
133
|
+
}> {
|
|
134
|
+
const { profile } = await import('bun:jsc');
|
|
135
|
+
const startedAt = performance.now();
|
|
136
|
+
const sampling = await profile(
|
|
137
|
+
() => new Promise<void>((resolve) => setTimeout(resolve, options.durationMs)),
|
|
138
|
+
options.sampleIntervalUs,
|
|
139
|
+
);
|
|
140
|
+
// Bun's current runtime returns an object here even though bun-types still
|
|
141
|
+
// declares SamplingProfile.stackTraces as string[]. Treat the runtime value
|
|
142
|
+
// as diagnostic input and normalize it defensively instead of trusting that
|
|
143
|
+
// stale declaration at the production boundary.
|
|
144
|
+
const rawStackTraces = sampling.stackTraces as unknown as {
|
|
145
|
+
interval?: unknown;
|
|
146
|
+
traces?: unknown;
|
|
147
|
+
sources?: unknown;
|
|
148
|
+
};
|
|
149
|
+
const rawTraces = Array.isArray(rawStackTraces?.traces) ? rawStackTraces.traces : [];
|
|
150
|
+
const traces = rawTraces.slice(-JSC_SAMPLING_TRACE_LIMIT).map((trace) => {
|
|
151
|
+
const record = trace && typeof trace === 'object' && !Array.isArray(trace)
|
|
152
|
+
? trace as Record<string, unknown>
|
|
153
|
+
: {};
|
|
154
|
+
const frames = Array.isArray(record.frames)
|
|
155
|
+
? record.frames.filter((frame): frame is Record<string, unknown> => Boolean(frame) && typeof frame === 'object' && !Array.isArray(frame)).slice(0, JSC_SAMPLING_FRAME_LIMIT)
|
|
156
|
+
: [];
|
|
157
|
+
return {
|
|
158
|
+
timestamp: typeof record.timestamp === 'number' ? record.timestamp : null,
|
|
159
|
+
frames,
|
|
160
|
+
};
|
|
161
|
+
});
|
|
162
|
+
const sources = Array.isArray(rawStackTraces?.sources)
|
|
163
|
+
? rawStackTraces.sources.filter((source): source is Record<string, unknown> => Boolean(source) && typeof source === 'object' && !Array.isArray(source)).slice(0, JSC_SAMPLING_SOURCE_LIMIT)
|
|
164
|
+
: [];
|
|
165
|
+
return {
|
|
166
|
+
requestedDurationMs: options.durationMs,
|
|
167
|
+
elapsedMs: Math.max(0, performance.now() - startedAt),
|
|
168
|
+
sampleIntervalUs: options.sampleIntervalUs,
|
|
169
|
+
functions: sampling.functions.slice(0, JSC_SAMPLING_REPORT_CHAR_LIMIT),
|
|
170
|
+
bytecodes: sampling.bytecodes.slice(0, JSC_SAMPLING_REPORT_CHAR_LIMIT),
|
|
171
|
+
stackTraces: {
|
|
172
|
+
interval: typeof rawStackTraces?.interval === 'number' ? rawStackTraces.interval : null,
|
|
173
|
+
totalTraceCount: rawTraces.length,
|
|
174
|
+
retainedTraceCount: traces.length,
|
|
175
|
+
traces,
|
|
176
|
+
sources,
|
|
177
|
+
},
|
|
178
|
+
};
|
|
101
179
|
}
|
|
102
180
|
|
|
103
181
|
const DEFAULT_DEPENDENCIES: CanonicalRuntimeDependencies = {
|
|
104
182
|
loadReleaseManifest: loadRuntimeReleaseManifest,
|
|
183
|
+
migrateReleaseState: migrateReleaseDurableState,
|
|
105
184
|
ensureReleaseAuthority: ensureActiveRuntimeRelease,
|
|
106
185
|
readReleaseAuthority: readRuntimeReleaseAuthority,
|
|
107
186
|
startReleaseAuthorityMonitor: startDefaultReleaseAuthorityMonitor,
|
|
@@ -111,6 +190,7 @@ const DEFAULT_DEPENDENCIES: CanonicalRuntimeDependencies = {
|
|
|
111
190
|
startScheduler: startInProcessScheduler,
|
|
112
191
|
startLocalBridge: startConfiguredRuntimeLocalBridge,
|
|
113
192
|
startPowerAssertion: startActiveExecutionPowerAssertion,
|
|
193
|
+
startWorkflowSupervisor: startWorkflowSupervisorRuntime,
|
|
114
194
|
startTransport: startRuntimeMcpTransport,
|
|
115
195
|
runMcpProbe: defaultMcpProbe,
|
|
116
196
|
collectRuntimeSourceIdentity,
|
|
@@ -119,18 +199,20 @@ const DEFAULT_DEPENDENCIES: CanonicalRuntimeDependencies = {
|
|
|
119
199
|
stopContextReadHelpers: closeCodeGraphReadProviderSessions,
|
|
120
200
|
computeToolSurfaceFingerprint: runtimeGatewayToolSurfaceFingerprint,
|
|
121
201
|
ensureForgeInstanceIdentity,
|
|
122
|
-
|
|
202
|
+
captureJscSamplingProfile: captureDefaultJscSamplingProfile,
|
|
123
203
|
};
|
|
124
204
|
|
|
125
205
|
export class CanonicalForgeRuntime {
|
|
126
206
|
readonly forgeInstanceId: string;
|
|
127
207
|
readonly runtimeInstanceId: string;
|
|
208
|
+
readonly topology: RuntimeDeploymentTopology;
|
|
128
209
|
private readonly readinessState = new RuntimeReadinessState();
|
|
129
210
|
private readonly dependencies: CanonicalRuntimeDependencies;
|
|
130
211
|
private ownership?: RuntimeOwnershipHandle;
|
|
131
212
|
private scheduler?: RuntimeSchedulerHandle;
|
|
132
213
|
private localBridge?: RuntimeLocalBridgeHandle;
|
|
133
214
|
private powerAssertion?: RuntimePowerAssertionHandle;
|
|
215
|
+
private workflowSupervisor?: RuntimeWorkflowSupervisorHandle;
|
|
134
216
|
private toolSurfaceFingerprint?: string;
|
|
135
217
|
private transport?: RuntimeMcpTransportHandle;
|
|
136
218
|
private controller?: RuntimeControllerServices;
|
|
@@ -144,8 +226,7 @@ export class CanonicalForgeRuntime {
|
|
|
144
226
|
private jscHeapDiagnosticsSignalHandler?: () => void;
|
|
145
227
|
private jscHeapDiagnosticsCaptureInFlight = false;
|
|
146
228
|
private jscSamplingProfilerSignalHandler?: () => void;
|
|
147
|
-
private
|
|
148
|
-
private jscSamplingProfilerStarted = false;
|
|
229
|
+
private jscSamplingProfileCaptureInFlight = false;
|
|
149
230
|
lastExit?: RuntimeExitEvidence;
|
|
150
231
|
|
|
151
232
|
constructor(
|
|
@@ -153,6 +234,7 @@ export class CanonicalForgeRuntime {
|
|
|
153
234
|
dependencies: Partial<CanonicalRuntimeDependencies> = {},
|
|
154
235
|
) {
|
|
155
236
|
this.runtimeInstanceId = config.runtimeInstanceId?.trim() || `runtime_${randomUUID().replaceAll('-', '')}`;
|
|
237
|
+
this.topology = normalizeRuntimeDeploymentTopology(config.topology);
|
|
156
238
|
this.dependencies = { ...DEFAULT_DEPENDENCIES, ...dependencies };
|
|
157
239
|
if (!config.controllerHome.trim()) throw new Error('RUNTIME_CONFIG_REQUIRED: controllerHome');
|
|
158
240
|
if (config.repositoryRoot?.trim()) {
|
|
@@ -183,7 +265,10 @@ export class CanonicalForgeRuntime {
|
|
|
183
265
|
const handler = () => {
|
|
184
266
|
if (this.jscHeapDiagnosticsCaptureInFlight) return;
|
|
185
267
|
this.jscHeapDiagnosticsCaptureInFlight = true;
|
|
186
|
-
void import('bun:jsc').then(({ heapStats, memoryUsage }) => {
|
|
268
|
+
void import('bun:jsc').then(({ fullGC, heapStats, memoryUsage }) => {
|
|
269
|
+
const gcStartedAt = performance.now();
|
|
270
|
+
const fullGcResult = fullGC();
|
|
271
|
+
const fullGcDurationMs = Math.max(0, performance.now() - gcStartedAt);
|
|
187
272
|
const heap = heapStats();
|
|
188
273
|
const topTypes = (counts: Record<string, number>, limit: number) => Object.entries(counts)
|
|
189
274
|
.sort((left, right) => right[1] - left[1])
|
|
@@ -195,6 +280,12 @@ export class CanonicalForgeRuntime {
|
|
|
195
280
|
pid: process.pid,
|
|
196
281
|
runtimeInstanceId: this.runtimeInstanceId,
|
|
197
282
|
releaseId: this.release?.releaseId,
|
|
283
|
+
gc: {
|
|
284
|
+
forced: true,
|
|
285
|
+
kind: 'full',
|
|
286
|
+
durationMs: fullGcDurationMs,
|
|
287
|
+
result: fullGcResult,
|
|
288
|
+
},
|
|
198
289
|
heap: {
|
|
199
290
|
heapSize: heap.heapSize,
|
|
200
291
|
heapCapacity: heap.heapCapacity,
|
|
@@ -235,26 +326,41 @@ export class CanonicalForgeRuntime {
|
|
|
235
326
|
private installJscSamplingProfilerSignal(): void {
|
|
236
327
|
if (process.platform === 'win32' || this.jscSamplingProfilerSignalHandler) return;
|
|
237
328
|
const handler = () => {
|
|
238
|
-
if (this.
|
|
239
|
-
this.
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
329
|
+
if (this.jscSamplingProfileCaptureInFlight) return;
|
|
330
|
+
this.jscSamplingProfileCaptureInFlight = true;
|
|
331
|
+
void this.dependencies.captureJscSamplingProfile({
|
|
332
|
+
durationMs: JSC_SAMPLING_DURATION_MS,
|
|
333
|
+
sampleIntervalUs: JSC_SAMPLING_INTERVAL_US,
|
|
334
|
+
}).then((sampling) => {
|
|
335
|
+
const path = join(this.config.controllerHome, 'diagnostics', 'jsc-sampling-profile.json');
|
|
336
|
+
writeJsonAtomic(path, {
|
|
337
|
+
schemaVersion: 1,
|
|
338
|
+
capturedAt: new Date().toISOString(),
|
|
339
|
+
pid: process.pid,
|
|
340
|
+
runtimeInstanceId: this.runtimeInstanceId,
|
|
341
|
+
releaseId: this.release?.releaseId,
|
|
342
|
+
bounded: true,
|
|
343
|
+
...sampling,
|
|
344
|
+
});
|
|
243
345
|
process.stderr.write(`${JSON.stringify({
|
|
244
|
-
event: '
|
|
346
|
+
event: 'forge_runtime_jsc_sampling_profile_captured',
|
|
245
347
|
runtimeInstanceId: this.runtimeInstanceId,
|
|
246
|
-
|
|
348
|
+
path,
|
|
349
|
+
requestedDurationMs: sampling.requestedDurationMs,
|
|
350
|
+
elapsedMs: sampling.elapsedMs,
|
|
351
|
+
sampleIntervalUs: sampling.sampleIntervalUs,
|
|
352
|
+
retainedTraceCount: sampling.stackTraces.retainedTraceCount,
|
|
247
353
|
observedAt: new Date().toISOString(),
|
|
248
354
|
})}\n`);
|
|
249
355
|
}).catch((error) => {
|
|
250
356
|
process.stderr.write(`${JSON.stringify({
|
|
251
|
-
event: '
|
|
357
|
+
event: 'forge_runtime_jsc_sampling_profile_failed',
|
|
252
358
|
runtimeInstanceId: this.runtimeInstanceId,
|
|
253
359
|
message: error instanceof Error ? error.message : String(error),
|
|
254
360
|
observedAt: new Date().toISOString(),
|
|
255
361
|
})}\n`);
|
|
256
362
|
}).finally(() => {
|
|
257
|
-
this.
|
|
363
|
+
this.jscSamplingProfileCaptureInFlight = false;
|
|
258
364
|
});
|
|
259
365
|
};
|
|
260
366
|
process.on('SIGUSR1', handler);
|
|
@@ -339,7 +445,7 @@ export class CanonicalForgeRuntime {
|
|
|
339
445
|
if (this.started) throw new Error('RUNTIME_ALREADY_STARTED');
|
|
340
446
|
this.started = true;
|
|
341
447
|
this.readinessState.markNotReady();
|
|
342
|
-
let stage: 'release' | 'ownership' | 'source' | 'database' | 'scheduler' | 'localBridge' | 'transport' | 'probe' = 'release';
|
|
448
|
+
let stage: 'release' | 'ownership' | 'source' | 'database' | 'supervisor' | 'scheduler' | 'localBridge' | 'transport' | 'probe' = 'release';
|
|
343
449
|
try {
|
|
344
450
|
this.release = this.dependencies.loadReleaseManifest(this.config.releaseManifestPath, this.config.controllerHome);
|
|
345
451
|
|
|
@@ -347,6 +453,7 @@ export class CanonicalForgeRuntime {
|
|
|
347
453
|
this.ownership = this.dependencies.acquireOwnership(this.config.controllerHome, this.runtimeInstanceId);
|
|
348
454
|
|
|
349
455
|
stage = 'release';
|
|
456
|
+
this.dependencies.migrateReleaseState(this.config.controllerHome);
|
|
350
457
|
const releaseAuthority = this.dependencies.ensureReleaseAuthority(this.config.controllerHome, this.config.releaseManifestPath);
|
|
351
458
|
stage = 'source';
|
|
352
459
|
// A compiled release is a closed execution surface. Fail before Scheduler
|
|
@@ -400,11 +507,15 @@ export class CanonicalForgeRuntime {
|
|
|
400
507
|
this.installJscSamplingProfilerSignal();
|
|
401
508
|
this.readinessState.setDiagnostic('database', 'pass');
|
|
402
509
|
this.publishStatus();
|
|
403
|
-
if (this.
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
510
|
+
if (this.topology.components.workflowSupervisor) {
|
|
511
|
+
stage = 'supervisor';
|
|
512
|
+
this.workflowSupervisor = await this.dependencies.startWorkflowSupervisor(this.config.controllerHome, {
|
|
513
|
+
nativeBrowserAdapter: this.topology.components.workflowSupervisorNativeBrowser,
|
|
407
514
|
});
|
|
515
|
+
void this.workflowSupervisor.done.then(
|
|
516
|
+
() => this.failCore('WORKFLOW_SUPERVISOR_STOPPED', 'Workflow Supervisor stopped while Runtime was active.'),
|
|
517
|
+
(error) => this.failCore('WORKFLOW_SUPERVISOR_FAILED', error instanceof Error ? error.message : String(error)),
|
|
518
|
+
);
|
|
408
519
|
}
|
|
409
520
|
|
|
410
521
|
stage = 'scheduler';
|
|
@@ -464,12 +575,30 @@ export class CanonicalForgeRuntime {
|
|
|
464
575
|
this.readinessState.setDiagnostic('mcpEndToEnd', 'pass');
|
|
465
576
|
this.readinessState.markReady();
|
|
466
577
|
this.publishStatus();
|
|
578
|
+
removeRuntimeStartupFailureEvidence(this.config.controllerHome);
|
|
467
579
|
stage = 'release';
|
|
468
580
|
this.startReleaseAuthorityMonitor();
|
|
469
581
|
} catch (error) {
|
|
470
582
|
const reason = this.startupReason(stage);
|
|
583
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
471
584
|
this.markStartupFailure(stage, reason);
|
|
472
|
-
|
|
585
|
+
try {
|
|
586
|
+
writeRuntimeStartupFailureEvidence(this.config.controllerHome, {
|
|
587
|
+
schemaVersion: 1,
|
|
588
|
+
runtimeInstanceId: this.runtimeInstanceId,
|
|
589
|
+
stage,
|
|
590
|
+
reasonCode: reason,
|
|
591
|
+
message,
|
|
592
|
+
...(this.release ? {
|
|
593
|
+
releaseId: this.release.releaseId,
|
|
594
|
+
artifactIdentity: this.release.artifactIdentity,
|
|
595
|
+
} : {}),
|
|
596
|
+
observedAt: new Date().toISOString(),
|
|
597
|
+
});
|
|
598
|
+
} catch {
|
|
599
|
+
// Diagnostic persistence must never replace the original startup failure.
|
|
600
|
+
}
|
|
601
|
+
await this.stop(reason, message);
|
|
473
602
|
throw error;
|
|
474
603
|
}
|
|
475
604
|
}
|
|
@@ -479,6 +608,7 @@ export class CanonicalForgeRuntime {
|
|
|
479
608
|
if (stage === 'ownership') return 'RUNTIME_OWNERSHIP_CONFLICT';
|
|
480
609
|
if (stage === 'source') return 'RUNTIME_SOURCE_SNAPSHOT_FAILED';
|
|
481
610
|
if (stage === 'database') return 'DATABASE_UNAVAILABLE';
|
|
611
|
+
if (stage === 'supervisor') return 'WORKFLOW_SUPERVISOR_INITIALIZATION_FAILED';
|
|
482
612
|
if (stage === 'scheduler') return 'SCHEDULER_INITIALIZATION_FAILED';
|
|
483
613
|
if (stage === 'localBridge') return 'LOCAL_BRIDGE_STARTUP_FAILED';
|
|
484
614
|
if (stage === 'transport') return 'MCP_LISTENER_FAILED';
|
|
@@ -525,6 +655,8 @@ export class CanonicalForgeRuntime {
|
|
|
525
655
|
this.removeJscSamplingProfilerSignal();
|
|
526
656
|
// Stop accepting new MCP work before quiescing Scheduler activity, then
|
|
527
657
|
// release the Controller Home claim only after all in-process services stop.
|
|
658
|
+
await this.workflowSupervisor?.close().catch(() => undefined);
|
|
659
|
+
this.workflowSupervisor = undefined;
|
|
528
660
|
await this.transport?.close().catch(() => undefined);
|
|
529
661
|
await this.dependencies.stopLightweightProcesses(this.config.controllerHome).catch(() => undefined);
|
|
530
662
|
await this.dependencies.stopContextReadHelpers().catch(() => undefined);
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
bindControllerSessionBinding,
|
|
3
|
+
getRequirementControllerRoundRelay,
|
|
3
4
|
type ControllerBinding,
|
|
4
5
|
type ControllerHost,
|
|
5
6
|
type ControllerSession,
|
|
6
7
|
} from '../../../packages/kernel/controller/api/index';
|
|
7
|
-
import { createChatgptControllerHost } from '../../../adapters/chatgpt/controller-host';
|
|
8
8
|
import { upsertChatgptControllerBinding } from '../../../adapters/chatgpt/controller-binding-store';
|
|
9
|
+
import { getWorkContract } from '../../../packages/kernel/work/api/index';
|
|
10
|
+
import { inheritWorkflowSupervisorConversationBinding } from './workflow-supervisor-composition';
|
|
9
11
|
import { getChatgptWorkConversationBinding } from '../../../adapters/chatgpt/work-conversation-binding-store';
|
|
10
12
|
import { createProcessControllerHost } from '../../../adapters/controller-process/controller-host';
|
|
11
13
|
import { upsertProcessControllerBinding, type ProcessControllerType } from '../../../adapters/controller-process/binding-store';
|
|
@@ -22,9 +24,13 @@ export function ensureScheduledControllerBinding(
|
|
|
22
24
|
workId: input.workId, sessionId: input.session.sessionId,
|
|
23
25
|
browserSessionId: durable?.latestBrowserSessionId ?? (typeof input.args.browser_session_id === 'string' ? input.args.browser_session_id : undefined),
|
|
24
26
|
conversationUrl: durable?.conversationUrl ?? (typeof input.args.conversation_url === 'string' ? input.args.conversation_url : undefined),
|
|
27
|
+
authorizationGrantRefs: [
|
|
28
|
+
...(durable?.authorizationGrantRefs ?? []),
|
|
29
|
+
...(Array.isArray(input.args.authorization_grant_refs) ? input.args.authorization_grant_refs.map(String) : []),
|
|
30
|
+
].map(value => value.trim()).filter(Boolean).filter((value, index, values) => values.indexOf(value) === index),
|
|
25
31
|
title: input.scheduleName,
|
|
26
32
|
model: typeof input.args.model === 'string' ? input.args.model : 'gpt-5.6',
|
|
27
|
-
reasoning: input.args.reasoning === 'medium' || input.args.reasoning === 'xhigh' ? input.args.reasoning : '
|
|
33
|
+
reasoning: input.args.reasoning === 'medium' || input.args.reasoning === 'high' || input.args.reasoning === 'xhigh' ? input.args.reasoning : 'medium',
|
|
28
34
|
tabPolicy: input.args.tab_policy === 'reuse' || input.args.tab_policy === 'new' ? input.args.tab_policy : 'auto',
|
|
29
35
|
timeoutMs: typeof input.args.timeout_ms === 'number' ? input.args.timeout_ms : undefined,
|
|
30
36
|
}).binding;
|
|
@@ -43,9 +49,28 @@ export function ensureScheduledControllerBinding(
|
|
|
43
49
|
return binding;
|
|
44
50
|
}
|
|
45
51
|
|
|
52
|
+
export function ensureScheduledControllerBindingForWork(
|
|
53
|
+
options: { controllerHome: string; repoId: string },
|
|
54
|
+
input: { workId: string; session: ControllerSession; scheduleName?: string; args: Record<string, unknown> },
|
|
55
|
+
): ControllerBinding {
|
|
56
|
+
if (input.session.controllerType === 'chatgpt') {
|
|
57
|
+
const work = getWorkContract(options, input.workId);
|
|
58
|
+
if (work?.requirementId && !getChatgptWorkConversationBinding(options, input.workId)) {
|
|
59
|
+
const requirementRelay = getRequirementControllerRoundRelay(options, work.requirementId);
|
|
60
|
+
if (requirementRelay?.originWorkId && requirementRelay.originWorkId !== input.workId) {
|
|
61
|
+
inheritWorkflowSupervisorConversationBinding(options, requirementRelay.originWorkId, input.workId);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return ensureScheduledControllerBinding(options, input);
|
|
66
|
+
}
|
|
67
|
+
|
|
46
68
|
export function controllerHostForScheduledBinding(
|
|
47
69
|
options: { controllerHome: string; repoId: string; repoRoot: string },
|
|
48
70
|
binding: ControllerBinding,
|
|
49
71
|
): ControllerHost {
|
|
50
|
-
|
|
72
|
+
if (binding.hostKind === 'chatgpt') {
|
|
73
|
+
throw new Error('CHATGPT_CONTROLLER_HOST_SUPERVISOR_OWNED');
|
|
74
|
+
}
|
|
75
|
+
return createProcessControllerHost(options);
|
|
51
76
|
}
|
|
@@ -4,6 +4,7 @@ import { spawn, type ChildProcess } from 'child_process';
|
|
|
4
4
|
import { loadRuntimeReleaseManifest } from './release-manifest';
|
|
5
5
|
import { readRuntimeReleaseAuthority } from './release-store';
|
|
6
6
|
import { readForgeRuntimeServiceConfig } from './service';
|
|
7
|
+
import { runtimeAuthorityFreeEnvironment } from '../shared/process-environment';
|
|
7
8
|
|
|
8
9
|
export interface ForgeRuntimeServiceCommand {
|
|
9
10
|
executable: string;
|
|
@@ -31,10 +32,9 @@ export function resolveForgeRuntimeServiceCommand(controllerHome: string, config
|
|
|
31
32
|
'--port', String(config.port),
|
|
32
33
|
'--auth-token-file', config.authTokenFile,
|
|
33
34
|
...activeRuntimeReleaseManifest.arguments,
|
|
34
|
-
...(config.exclusiveWorkId ? ['--exclusive-work-id', config.exclusiveWorkId] : []),
|
|
35
35
|
],
|
|
36
36
|
env: {
|
|
37
|
-
...process.env,
|
|
37
|
+
...runtimeAuthorityFreeEnvironment(process.env),
|
|
38
38
|
FORGE_CONTROLLER_HOME: home,
|
|
39
39
|
FORGE_CONTROLLER_RUNTIME_SOURCE_ROOT: releaseRoot,
|
|
40
40
|
FORGE_RELEASE_PATH: releaseRoot,
|