@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
|
@@ -10,6 +10,7 @@ import { assertRuntimeReleaseExecutionSurface } from './release-manifest';
|
|
|
10
10
|
import { assertRuntimeReleaseExecutionCanaries } from './release-execution-canary';
|
|
11
11
|
import type { RuntimeReleaseManifest } from './types';
|
|
12
12
|
import { assertStorageHeadroom } from '../shared/storage-capacity';
|
|
13
|
+
import { PROCESS_RUNTIME_RELEASE_CANARY_ARG } from '../execution/process-runtime/canary';
|
|
13
14
|
|
|
14
15
|
export interface PackageRuntimeFileRecord {
|
|
15
16
|
path: string;
|
|
@@ -35,10 +36,33 @@ export interface PackageRuntimeRelease {
|
|
|
35
36
|
// TypeScript entrypoints import both `src/` and the top-level modular-monolith
|
|
36
37
|
// roots at runtime, so retaining only `src/` creates a release that passes
|
|
37
38
|
// staging but cannot start after the installed package moves or disappears.
|
|
38
|
-
const PACKAGE_RUNTIME_ROOTS = ['src', 'adapters', 'packages', 'bin', 'assets', 'scripts', 'node_modules'] as const;
|
|
39
|
+
const PACKAGE_RUNTIME_ROOTS = ['src', 'adapters', 'packages', 'supervisor', 'bin', 'assets', 'scripts', 'node_modules'] as const;
|
|
39
40
|
const PACKAGE_RUNTIME_FILES = ['package.json'] as const;
|
|
41
|
+
// Compiled releases execute only compiled/bundled artifacts. Keep a tiny package
|
|
42
|
+
// projection for browser-extension installation plus two legacy Recovery
|
|
43
|
+
// recognition sentinels; neither sentinel is executed when the compiled
|
|
44
|
+
// Connector sidecar is present.
|
|
45
|
+
const COMPILED_RUNTIME_PACKAGE_ROOTS = ['adapters/computer/chrome-extension'] as const;
|
|
46
|
+
const COMPILED_RUNTIME_PACKAGE_FILES = [
|
|
47
|
+
'package.json',
|
|
48
|
+
'src/cli/index.ts',
|
|
49
|
+
'src/runtime/shared/node-ts-loader.mjs',
|
|
50
|
+
] as const;
|
|
40
51
|
const PACKAGE_RUNTIME_STAGING_RESERVE_BYTES = 256 * 1024 * 1024;
|
|
41
52
|
|
|
53
|
+
function isNonRuntimePackageHelper(path: string): boolean {
|
|
54
|
+
if (path.startsWith('scripts/benchmark-')) return true;
|
|
55
|
+
if (path.startsWith('scripts/check-release-')) return true;
|
|
56
|
+
if (path.startsWith('scripts/public-release')) return true;
|
|
57
|
+
return path === 'scripts/route-nl-vs-ts-eval.ts'
|
|
58
|
+
|| path === 'scripts/check-npm-release.sh'
|
|
59
|
+
|| path === 'scripts/check-public-release-surface.sh'
|
|
60
|
+
|| path === 'scripts/check-tarball-install-smoke.sh'
|
|
61
|
+
|| path === 'scripts/publish-release-tarball.sh'
|
|
62
|
+
|| path === 'scripts/stage-runtime-release.ts'
|
|
63
|
+
|| path === 'scripts/package-source-archive.sh';
|
|
64
|
+
}
|
|
65
|
+
|
|
42
66
|
function sha256(value: Buffer | string): string {
|
|
43
67
|
return createHash('sha256').update(value).digest('hex');
|
|
44
68
|
}
|
|
@@ -50,7 +74,7 @@ function atomicWrite(path: string, content: string, mode = 0o600): void {
|
|
|
50
74
|
renameSync(temporary, path);
|
|
51
75
|
}
|
|
52
76
|
|
|
53
|
-
function walkRegularFiles(root: string, current: string, output: string[]): void {
|
|
77
|
+
function walkRegularFiles(root: string, current: string, output: string[], prefix = ''): void {
|
|
54
78
|
if (!existsSync(current)) return;
|
|
55
79
|
const stat = lstatSync(current);
|
|
56
80
|
// Package managers such as Bun can materialize dependency files as
|
|
@@ -59,38 +83,89 @@ function walkRegularFiles(root: string, current: string, output: string[]): void
|
|
|
59
83
|
// regular files beneath its own immutable package root.
|
|
60
84
|
if (stat.isSymbolicLink()) {
|
|
61
85
|
const target = statSync(current);
|
|
62
|
-
if (target.isFile())
|
|
86
|
+
if (target.isFile()) {
|
|
87
|
+
const relativePath = relative(root, current).split('\\').join('/');
|
|
88
|
+
output.push(prefix ? `${prefix}/${relativePath}` : relativePath);
|
|
89
|
+
}
|
|
63
90
|
return;
|
|
64
91
|
}
|
|
65
92
|
if (stat.isFile()) {
|
|
66
|
-
|
|
93
|
+
const relativePath = relative(root, current).split('\\').join('/');
|
|
94
|
+
output.push(prefix ? `${prefix}/${relativePath}` : relativePath);
|
|
67
95
|
return;
|
|
68
96
|
}
|
|
69
97
|
if (!stat.isDirectory()) return;
|
|
70
|
-
for (const entry of readdirSync(current).sort()) walkRegularFiles(root, join(current, entry), output);
|
|
98
|
+
for (const entry of readdirSync(current).sort()) walkRegularFiles(root, join(current, entry), output, prefix);
|
|
71
99
|
}
|
|
72
100
|
|
|
73
|
-
|
|
101
|
+
function packageSourcePath(packageRoot: string, path: string, dependencyRoot = packageRoot): string {
|
|
102
|
+
return path === 'node_modules' || path.startsWith('node_modules/')
|
|
103
|
+
? join(resolve(dependencyRoot), path)
|
|
104
|
+
: join(resolve(packageRoot), path);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function packageFileIndex(
|
|
108
|
+
packageRoot: string,
|
|
109
|
+
roots: readonly string[],
|
|
110
|
+
files: readonly string[],
|
|
111
|
+
dependencyRoot = packageRoot,
|
|
112
|
+
): PackageRuntimeFileRecord[] {
|
|
74
113
|
const root = resolve(packageRoot);
|
|
114
|
+
const dependencies = resolve(dependencyRoot);
|
|
75
115
|
const paths: string[] = [];
|
|
76
|
-
for (const directory of
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
116
|
+
for (const directory of roots) {
|
|
117
|
+
if (directory === 'node_modules' && dependencies !== root) {
|
|
118
|
+
const dependencyNodeModules = join(dependencies, 'node_modules');
|
|
119
|
+
walkRegularFiles(dependencyNodeModules, dependencyNodeModules, paths, 'node_modules');
|
|
120
|
+
} else {
|
|
121
|
+
walkRegularFiles(root, join(root, directory), paths);
|
|
122
|
+
}
|
|
81
123
|
}
|
|
82
|
-
|
|
83
|
-
|
|
124
|
+
for (const file of files) walkRegularFiles(root, join(root, file), paths);
|
|
125
|
+
return [...new Set(paths)].sort().map((path) => {
|
|
126
|
+
const bytes = readFileSync(packageSourcePath(root, path, dependencies));
|
|
84
127
|
return { path, sha256: sha256(bytes), bytes: bytes.length };
|
|
85
128
|
});
|
|
86
129
|
}
|
|
87
130
|
|
|
131
|
+
export function packageRuntimeFileIndex(packageRoot = packageRuntimeSourceRoot(), dependencyRoot = packageRoot): PackageRuntimeFileRecord[] {
|
|
132
|
+
const root = resolve(packageRoot);
|
|
133
|
+
const records = packageFileIndex(root, PACKAGE_RUNTIME_ROOTS, PACKAGE_RUNTIME_FILES, dependencyRoot)
|
|
134
|
+
.filter((record) => !isNonRuntimePackageHelper(record.path));
|
|
135
|
+
const paths = new Set(records.map((record) => record.path));
|
|
136
|
+
if (!paths.has('package.json') || !paths.has('bin/forge-runtime.mjs')) {
|
|
137
|
+
throw new Error(`PACKAGE_RUNTIME_SURFACE_INCOMPLETE: ${root}`);
|
|
138
|
+
}
|
|
139
|
+
return records;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export function compiledRuntimePackageFileIndex(packageRoot = packageRuntimeSourceRoot()): PackageRuntimeFileRecord[] {
|
|
143
|
+
const root = resolve(packageRoot);
|
|
144
|
+
const records = packageFileIndex(root, COMPILED_RUNTIME_PACKAGE_ROOTS, COMPILED_RUNTIME_PACKAGE_FILES);
|
|
145
|
+
const paths = new Set(records.map((record) => record.path));
|
|
146
|
+
for (const required of COMPILED_RUNTIME_PACKAGE_FILES) {
|
|
147
|
+
if (!paths.has(required)) throw new Error(`COMPILED_RUNTIME_PACKAGE_SURFACE_INCOMPLETE: ${required}`);
|
|
148
|
+
}
|
|
149
|
+
if (![...paths].some((path) => path.startsWith('adapters/computer/chrome-extension/'))) {
|
|
150
|
+
throw new Error('COMPILED_RUNTIME_PACKAGE_SURFACE_INCOMPLETE: adapters/computer/chrome-extension');
|
|
151
|
+
}
|
|
152
|
+
return records;
|
|
153
|
+
}
|
|
154
|
+
|
|
88
155
|
export function packageRuntimeFingerprint(records: PackageRuntimeFileRecord[]): string {
|
|
89
156
|
const hash = createHash('sha256');
|
|
90
157
|
for (const record of records) hash.update(record.path).update('\0').update(record.sha256).update('\0').update(String(record.bytes)).update('\n');
|
|
91
158
|
return hash.digest('hex');
|
|
92
159
|
}
|
|
93
160
|
|
|
161
|
+
function packageRuntimeArtifactIdentity(root: string, records: PackageRuntimeFileRecord[]): string {
|
|
162
|
+
const hash = createHash('sha256');
|
|
163
|
+
for (const record of records) {
|
|
164
|
+
hash.update(record.path).update('\0').update(readFileSync(join(root, record.path))).update('\0');
|
|
165
|
+
}
|
|
166
|
+
return `sha256:${hash.digest('hex')}`;
|
|
167
|
+
}
|
|
168
|
+
|
|
94
169
|
function assertPackageRuntimeSnapshot(snapshotRoot: string, records: PackageRuntimeFileRecord[]): void {
|
|
95
170
|
if (!existsSync(snapshotRoot)) throw new Error('PACKAGE_RUNTIME_RELEASE_IMMUTABILITY_VIOLATION: package snapshot is missing');
|
|
96
171
|
const rootStat = lstatSync(snapshotRoot);
|
|
@@ -111,10 +186,15 @@ function assertPackageRuntimeSnapshot(snapshotRoot: string, records: PackageRunt
|
|
|
111
186
|
}
|
|
112
187
|
}
|
|
113
188
|
|
|
114
|
-
export function stagePackageRuntimeSnapshot(
|
|
189
|
+
export function stagePackageRuntimeSnapshot(
|
|
190
|
+
sourceRoot: string,
|
|
191
|
+
snapshotRoot: string,
|
|
192
|
+
records: PackageRuntimeFileRecord[],
|
|
193
|
+
dependencyRoot = sourceRoot,
|
|
194
|
+
): void {
|
|
115
195
|
mkdirSync(snapshotRoot, { recursive: false, mode: 0o700 });
|
|
116
196
|
for (const record of records) {
|
|
117
|
-
const source =
|
|
197
|
+
const source = packageSourcePath(sourceRoot, record.path, dependencyRoot);
|
|
118
198
|
const link = lstatSync(source);
|
|
119
199
|
const stat = link.isSymbolicLink() ? statSync(source) : link;
|
|
120
200
|
if (!stat.isFile()) throw new Error(`PACKAGE_RUNTIME_SOURCE_CHANGED_DURING_STAGE: ${record.path}`);
|
|
@@ -146,6 +226,7 @@ function launcherSource(input: {
|
|
|
146
226
|
indexSha256: string;
|
|
147
227
|
entryRelativePath?: string;
|
|
148
228
|
managerSignalsProcessGroup?: boolean;
|
|
229
|
+
ownsProcessRuntimeCanary?: boolean;
|
|
149
230
|
}): string {
|
|
150
231
|
const entryRelativePath = input.entryRelativePath ?? 'src/runtime/root/entry.ts';
|
|
151
232
|
return `#!${process.execPath}\n`
|
|
@@ -154,7 +235,12 @@ function launcherSource(input: {
|
|
|
154
235
|
+ `import { dirname, join } from 'node:path';\n`
|
|
155
236
|
+ `import { fileURLToPath } from 'node:url';\n`
|
|
156
237
|
+ `import { spawn } from 'node:child_process';\n`
|
|
157
|
-
|
|
238
|
+
// macOS runs a byte-for-byte mirror of this launcher from its fixed,
|
|
239
|
+
// TCC-stable service path. The mirrored file is not its immutable release
|
|
240
|
+
// directory, so use the launch contract's attested release binding when it
|
|
241
|
+
// is present. Direct execution from the immutable release still derives
|
|
242
|
+
// the same root from the entrypoint location.
|
|
243
|
+
+ `const releaseRoot=process.env.FORGE_RELEASE_PATH?.trim()||dirname(fileURLToPath(import.meta.url));\n`
|
|
158
244
|
+ `const packageRoot=join(releaseRoot,'package');\n`
|
|
159
245
|
+ `const indexPath=join(releaseRoot,'package-files.json');\n`
|
|
160
246
|
+ `const expectedIndex=${JSON.stringify(input.indexSha256)};\n`
|
|
@@ -163,6 +249,8 @@ function launcherSource(input: {
|
|
|
163
249
|
+ `if(digest(raw)!==expectedIndex){console.error('FORGE_PACKAGE_RUNTIME_INDEX_CHANGED');process.exit(78);}\n`
|
|
164
250
|
+ `let records; try { records=JSON.parse(raw.toString('utf8')).files; } catch { console.error('FORGE_PACKAGE_RUNTIME_INDEX_INVALID'); process.exit(78); }\n`
|
|
165
251
|
+ `for(const record of records){const path=join(packageRoot,record.path);if(!existsSync(path)||digest(readFileSync(path))!==record.sha256){console.error('FORGE_PACKAGE_RUNTIME_SOURCE_CHANGED: '+record.path);process.exit(78);}}\n`
|
|
252
|
+
+ `const ownsProcessRuntimeCanary=${input.ownsProcessRuntimeCanary === true ? 'true' : 'false'};\n`
|
|
253
|
+
+ `if(ownsProcessRuntimeCanary&&process.argv.length===3&&process.argv[2]===${JSON.stringify(PROCESS_RUNTIME_RELEASE_CANARY_ARG)})process.exit(0);\n`
|
|
166
254
|
+ `const entry=join(packageRoot,...${JSON.stringify(entryRelativePath.split('/'))});\n`
|
|
167
255
|
+ `const loader=join(packageRoot,'src','runtime','shared','node-ts-loader.mjs');\n`
|
|
168
256
|
+ `const args=process.versions?.bun?[entry,...process.argv.slice(2)]:['--loader',loader,entry,...process.argv.slice(2)];\n`
|
|
@@ -224,7 +312,12 @@ function assertImmutablePackageRuntimeRelease(input: {
|
|
|
224
312
|
&& manifest.checkRunnerArtifactIdentity === expected.checkRunnerArtifactIdentity
|
|
225
313
|
&& JSON.stringify(manifest.arguments ?? []) === JSON.stringify(expected.arguments ?? [])
|
|
226
314
|
&& manifest.configurationSchemaVersion === expected.configurationSchemaVersion
|
|
227
|
-
&&
|
|
315
|
+
&& manifest.deploymentScope === expected.deploymentScope
|
|
316
|
+
&& (manifest.deploymentScope === 'portable'
|
|
317
|
+
? expected.deploymentScope === 'portable'
|
|
318
|
+
: typeof manifest.controllerHome === 'string'
|
|
319
|
+
&& typeof expected.controllerHome === 'string'
|
|
320
|
+
&& resolve(manifest.controllerHome) === resolve(expected.controllerHome))
|
|
228
321
|
&& JSON.stringify(manifest.databaseSchemaCompatibility) === JSON.stringify(expected.databaseSchemaCompatibility)
|
|
229
322
|
&& manifest.workerProtocolVersion === expected.workerProtocolVersion
|
|
230
323
|
&& manifest.releaseRevision === expected.releaseRevision
|
|
@@ -232,6 +325,7 @@ function assertImmutablePackageRuntimeRelease(input: {
|
|
|
232
325
|
&& typeof manifest.createdAt === 'string'
|
|
233
326
|
&& Number.isFinite(Date.parse(manifest.createdAt));
|
|
234
327
|
if (!compatible) throw new Error('PACKAGE_RUNTIME_RELEASE_IMMUTABILITY_VIOLATION: manifest identity changed');
|
|
328
|
+
if (!expected.controllerHome) throw new Error('PACKAGE_RUNTIME_RELEASE_IMMUTABILITY_VIOLATION: package release must remain ControllerHome-bound');
|
|
235
329
|
assertRuntimeReleaseExecutionSurface(input.manifestPath, expected.controllerHome);
|
|
236
330
|
}
|
|
237
331
|
|
|
@@ -245,8 +339,9 @@ export function materializePackageRuntimeRelease(input: {
|
|
|
245
339
|
const version = packageVersion(sourcePackageRoot);
|
|
246
340
|
const records = packageRuntimeFileIndex(sourcePackageRoot);
|
|
247
341
|
const fingerprint = packageRuntimeFingerprint(records);
|
|
342
|
+
const packageArtifactIdentity = packageRuntimeArtifactIdentity(sourcePackageRoot, records);
|
|
248
343
|
const safeVersion = version.replace(/[^A-Za-z0-9._-]+/g, '-');
|
|
249
|
-
const launcherBinding = sha256(`${resolve(process.execPath)}\0package-launcher-
|
|
344
|
+
const launcherBinding = sha256(`${resolve(process.execPath)}\0package-launcher-v9`);
|
|
250
345
|
const releaseId = `package-${safeVersion}-${fingerprint.slice(0, 16)}-${launcherBinding.slice(0, 12)}`;
|
|
251
346
|
const releasesRoot = join(controllerHome, 'runtime', 'releases');
|
|
252
347
|
const releaseRoot = join(releasesRoot, releaseId);
|
|
@@ -262,6 +357,7 @@ export function materializePackageRuntimeRelease(input: {
|
|
|
262
357
|
const processRunnerLauncher = launcherSource({
|
|
263
358
|
indexSha256,
|
|
264
359
|
entryRelativePath: 'src/runtime/execution/process-runtime/process-runner-entry.ts',
|
|
360
|
+
ownsProcessRuntimeCanary: true,
|
|
265
361
|
});
|
|
266
362
|
const processRunnerArtifactIdentity = `sha256:${sha256(Buffer.from(processRunnerLauncher))}`;
|
|
267
363
|
const checkRunnerEntrypoint = 'forge-check-runner' as const;
|
|
@@ -269,6 +365,7 @@ export function materializePackageRuntimeRelease(input: {
|
|
|
269
365
|
const checkRunnerLauncher = launcherSource({
|
|
270
366
|
indexSha256,
|
|
271
367
|
entryRelativePath: 'src/runtime/execution/process-runtime/check-runner-sidecar.ts',
|
|
368
|
+
ownsProcessRuntimeCanary: true,
|
|
272
369
|
});
|
|
273
370
|
const checkRunnerArtifactIdentity = `sha256:${sha256(Buffer.from(checkRunnerLauncher))}`;
|
|
274
371
|
const expectedManifest: Omit<RuntimeReleaseManifest, 'createdAt'> = {
|
|
@@ -280,6 +377,8 @@ export function materializePackageRuntimeRelease(input: {
|
|
|
280
377
|
processRunnerArtifactIdentity,
|
|
281
378
|
checkRunnerEntrypoint,
|
|
282
379
|
checkRunnerArtifactIdentity,
|
|
380
|
+
packageRoot: 'package',
|
|
381
|
+
packageArtifactIdentity,
|
|
283
382
|
arguments: [],
|
|
284
383
|
configurationSchemaVersion: 1,
|
|
285
384
|
controllerHome,
|
|
@@ -4,7 +4,8 @@ import { setTimeout as sleep } from 'timers/promises';
|
|
|
4
4
|
import { dirname, join, resolve } from 'path';
|
|
5
5
|
import { resolveControllerHome } from '../../cli/repositories/controller-home';
|
|
6
6
|
import { createPlatformServiceManagerHost, probeSystemdUserAvailable, type PlatformServiceManagerHost, type PlatformServiceManagerKind, type SystemdUserUnitInput } from '../platform/service-manager';
|
|
7
|
-
import {
|
|
7
|
+
import { reconcileRetiredForgePersistentServices, type ForgeRetiredServiceReconciliation } from '../platform/service-inventory';
|
|
8
|
+
import { runtimeAuthorityFreeEnvironment } from '../shared/process-environment';
|
|
8
9
|
import {
|
|
9
10
|
activeRuntimeEntrypoint,
|
|
10
11
|
activeRuntimeLaunchSpec,
|
|
@@ -19,6 +20,7 @@ import { materializePackageRuntimeRelease, type PackageRuntimeRelease } from './
|
|
|
19
20
|
import { readRuntimeReleaseAuthority, revertInitialRuntimeReleasePublication, rollbackRuntimeRelease } from './release-store';
|
|
20
21
|
import { loadMcpServiceLocalConfig } from '../../../adapters/mcp/auth';
|
|
21
22
|
import { ensurePackageConnectorService, type PackageConnectorServiceResult } from './package-connector-service';
|
|
23
|
+
import { normalizeRuntimeDeploymentTopology, type RuntimeDeploymentTopology } from './deployment-topology';
|
|
22
24
|
|
|
23
25
|
export type PackageRuntimeServiceMode = PlatformServiceManagerKind;
|
|
24
26
|
|
|
@@ -74,6 +76,7 @@ export interface PackageRuntimeServiceInstallResult {
|
|
|
74
76
|
pid?: number;
|
|
75
77
|
warnings: string[];
|
|
76
78
|
connector?: PackageConnectorServiceResult;
|
|
79
|
+
retiredServices?: ForgeRetiredServiceReconciliation[];
|
|
77
80
|
activation?: {
|
|
78
81
|
operationId: string;
|
|
79
82
|
status: 'activation_scheduled';
|
|
@@ -89,11 +92,11 @@ export interface PackageRuntimeServiceOptions {
|
|
|
89
92
|
host?: string;
|
|
90
93
|
port?: number;
|
|
91
94
|
authTokenFile: string;
|
|
92
|
-
exclusiveWorkId?: string;
|
|
93
95
|
platform?: NodeJS.Platform;
|
|
94
96
|
env?: NodeJS.ProcessEnv;
|
|
95
97
|
forcePortable?: boolean;
|
|
96
98
|
refreshConnector?: boolean;
|
|
99
|
+
topology?: RuntimeDeploymentTopology;
|
|
97
100
|
}
|
|
98
101
|
|
|
99
102
|
export interface PackageRuntimeServiceDependencies {
|
|
@@ -101,6 +104,7 @@ export interface PackageRuntimeServiceDependencies {
|
|
|
101
104
|
ensureConnectorService?: typeof ensurePackageConnectorService;
|
|
102
105
|
scheduleDarwinActivation?: (request: PackageRuntimeActivationRequest) => Promise<{ label: string; servicePath: string }>;
|
|
103
106
|
activationMode?: 'detached' | 'inline';
|
|
107
|
+
reconcileRetiredServices?: typeof reconcileRetiredForgePersistentServices;
|
|
104
108
|
}
|
|
105
109
|
|
|
106
110
|
export interface PackageRuntimeActivationDependencies {
|
|
@@ -131,14 +135,10 @@ export function systemdUserAvailable(env: NodeJS.ProcessEnv = process.env): bool
|
|
|
131
135
|
}
|
|
132
136
|
|
|
133
137
|
function cleanRuntimeInstallerEnvironment(env: NodeJS.ProcessEnv, releaseEnvironment: Record<string, string>): NodeJS.ProcessEnv {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
delete next.FORGE_RELEASE_REVISION;
|
|
139
|
-
delete next.FORGE_RELEASE_SOURCE_COMMIT;
|
|
140
|
-
delete next.FORGE_RELEASE_CLEAN_WORKSPACE;
|
|
141
|
-
return { ...next, ...releaseEnvironment };
|
|
138
|
+
// The selected immutable release is the only authority reintroduced below.
|
|
139
|
+
// Do not carry an installer, host Runtime or Supervisor writer claim across
|
|
140
|
+
// this service boundary.
|
|
141
|
+
return { ...runtimeAuthorityFreeEnvironment(env), ...releaseEnvironment };
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
export function systemdRuntimeInstallCommands(unitName: string): string[][] {
|
|
@@ -471,7 +471,7 @@ export async function installPackageRuntimeService(
|
|
|
471
471
|
host: options.host ?? '127.0.0.1',
|
|
472
472
|
port: options.port ?? 8765,
|
|
473
473
|
authTokenFile: options.authTokenFile,
|
|
474
|
-
|
|
474
|
+
topology: normalizeRuntimeDeploymentTopology(options.topology),
|
|
475
475
|
};
|
|
476
476
|
writeForgeRuntimeServiceConfig(config);
|
|
477
477
|
syncForgeRuntimeActiveEntrypoint(controllerHome);
|
|
@@ -479,6 +479,11 @@ export async function installPackageRuntimeService(
|
|
|
479
479
|
const env = options.env ?? process.env;
|
|
480
480
|
const serviceHost = createPlatformServiceManagerHost({ platform, env, forcePortable: options.forcePortable });
|
|
481
481
|
const serviceManager = serviceHost.selection;
|
|
482
|
+
const retiredServices = await (dependencies.reconcileRetiredServices ?? reconcileRetiredForgePersistentServices)({
|
|
483
|
+
host: serviceHost,
|
|
484
|
+
env,
|
|
485
|
+
accountHome: env.HOME,
|
|
486
|
+
});
|
|
482
487
|
const installDarwinService = dependencies.installDarwinService ?? installForgeRuntimeService;
|
|
483
488
|
const explicitInjectedInline = Boolean(dependencies.installDarwinService && !dependencies.scheduleDarwinActivation && !dependencies.activationMode);
|
|
484
489
|
const activationMode = dependencies.activationMode ?? (explicitInjectedInline ? 'inline' : 'detached');
|
|
@@ -592,6 +597,7 @@ export async function installPackageRuntimeService(
|
|
|
592
597
|
}
|
|
593
598
|
}
|
|
594
599
|
|
|
600
|
+
base = { ...base, retiredServices };
|
|
595
601
|
if (!connectorEndpoint || base.status === 'activation_scheduled') return base;
|
|
596
602
|
const ensureConnectorService = dependencies.ensureConnectorService ?? ensurePackageConnectorService;
|
|
597
603
|
const connector = await ensureConnectorService({
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
+
import { join } from 'path';
|
|
1
2
|
import { runProcess } from '../../effects/process-runner';
|
|
2
3
|
import { PROCESS_RUNTIME_RELEASE_CANARY_ARG } from '../execution/process-runtime/canary';
|
|
4
|
+
import { resolveBunExecutable } from '../shared/process-environment';
|
|
3
5
|
import {
|
|
4
6
|
assertRuntimeReleaseExecutionSurface,
|
|
5
7
|
type RuntimeReleaseExecutionSurface,
|
|
6
8
|
} from './release-manifest';
|
|
7
9
|
|
|
8
10
|
export interface RuntimeReleaseExecutionCanaryCommand {
|
|
9
|
-
name: RuntimeReleaseExecutionSurface['entries'][number]['name'];
|
|
11
|
+
name: RuntimeReleaseExecutionSurface['entries'][number]['name'] | 'connector_cli';
|
|
10
12
|
executable: string;
|
|
11
13
|
args: string[];
|
|
12
14
|
}
|
|
@@ -22,8 +24,10 @@ export interface RuntimeReleaseExecutionCanaryDependencies {
|
|
|
22
24
|
|
|
23
25
|
/**
|
|
24
26
|
* Release execution canaries deliberately do not inherit developer-tool PATH
|
|
25
|
-
* entries.
|
|
26
|
-
*
|
|
27
|
+
* entries. Standalone-binary artifacts must execute without Homebrew, Bun, nvm,
|
|
28
|
+
* or similar PATH dependencies. Legacy script releases predate the embedded
|
|
29
|
+
* Runtime interpreter and are probed through the same explicitly resolved Bun
|
|
30
|
+
* executable that their Process Runtime uses in production.
|
|
27
31
|
*/
|
|
28
32
|
export function runtimeReleaseCanaryEnvironment(
|
|
29
33
|
env: NodeJS.ProcessEnv = process.env,
|
|
@@ -39,7 +43,12 @@ export function runtimeReleaseCanaryEnvironment(
|
|
|
39
43
|
return { ...env, PATH: '/usr/bin:/bin:/usr/sbin:/sbin' };
|
|
40
44
|
}
|
|
41
45
|
|
|
42
|
-
/**
|
|
46
|
+
/**
|
|
47
|
+
* Execute the minimum immutable Runtime execution surface plus the package
|
|
48
|
+
* Connector CLI import graph. The latter is intentionally a help-only command:
|
|
49
|
+
* it loads the exact CLI dependency closure used by the persistent Connector
|
|
50
|
+
* without opening a listener or mutating Runtime authority.
|
|
51
|
+
*/
|
|
43
52
|
export function assertRuntimeReleaseExecutionCanaries(
|
|
44
53
|
manifestPath: string,
|
|
45
54
|
controllerHome: string,
|
|
@@ -52,20 +61,43 @@ export function assertRuntimeReleaseExecutionCanaries(
|
|
|
52
61
|
{
|
|
53
62
|
cwd: surface.releaseRoot,
|
|
54
63
|
env: runtimeReleaseCanaryEnvironment(),
|
|
55
|
-
timeoutMs:
|
|
64
|
+
timeoutMs: 30_000,
|
|
56
65
|
maxOutputBytes: 64 * 1024,
|
|
57
66
|
},
|
|
58
67
|
));
|
|
59
|
-
|
|
60
|
-
const canary: RuntimeReleaseExecutionCanaryCommand = {
|
|
61
|
-
name: entry.name,
|
|
62
|
-
executable: entry.path,
|
|
63
|
-
args: [PROCESS_RUNTIME_RELEASE_CANARY_ARG],
|
|
64
|
-
};
|
|
68
|
+
const assertCanary = (canary: RuntimeReleaseExecutionCanaryCommand): void => {
|
|
65
69
|
const result = runExecutionEntryCanary(canary);
|
|
66
70
|
if (!result.ok) {
|
|
67
|
-
|
|
71
|
+
const detail = result.stderr || result.stdout || result.error || 'unknown failure';
|
|
72
|
+
const legacyCheckRunnerUsageProbe = surface.manifest.executionMode !== 'standalone-binary'
|
|
73
|
+
&& canary.name === 'check_runner'
|
|
74
|
+
&& detail.trim() === 'PERSISTED_CHECK_USAGE: missing --repo';
|
|
75
|
+
if (legacyCheckRunnerUsageProbe) return;
|
|
76
|
+
throw new Error(`RUNTIME_RELEASE_EXECUTION_CANARY_FAILED: ${canary.name}: ${detail}`.slice(0, 2_000));
|
|
68
77
|
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
for (const entry of surface.entries) {
|
|
81
|
+
const args = entry.canary === 'runtime_interpreter' ? ['--version'] : [PROCESS_RUNTIME_RELEASE_CANARY_ARG];
|
|
82
|
+
const legacyScript = surface.manifest.executionMode !== 'standalone-binary'
|
|
83
|
+
&& /\.(?:[cm]?js|tsx?)$/i.test(entry.path);
|
|
84
|
+
assertCanary({
|
|
85
|
+
name: entry.name,
|
|
86
|
+
executable: legacyScript ? resolveBunExecutable(process.execPath, process.env) : entry.path,
|
|
87
|
+
args: legacyScript ? [entry.path, ...args] : args,
|
|
88
|
+
});
|
|
69
89
|
}
|
|
90
|
+
|
|
91
|
+
// Package launcher releases execute source-backed CLI code from their own
|
|
92
|
+
// immutable snapshot. Compiled standalone releases have a different closed
|
|
93
|
+
// artifact surface and therefore do not use this source CLI probe.
|
|
94
|
+
if (surface.manifest.executionMode !== 'standalone-binary' && surface.manifest.packageRoot) {
|
|
95
|
+
assertCanary({
|
|
96
|
+
name: 'connector_cli',
|
|
97
|
+
executable: resolveBunExecutable(process.execPath, process.env),
|
|
98
|
+
args: [join(surface.releaseRoot, 'package', 'src', 'cli', 'index.ts'), 'mcp', 'serve', '--help'],
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
70
102
|
return surface;
|
|
71
103
|
}
|
|
@@ -1,13 +1,18 @@
|
|
|
1
|
+
import { spawn } from 'child_process';
|
|
1
2
|
import { createHash } from 'crypto';
|
|
2
|
-
import { readFileSync } from 'fs';
|
|
3
|
+
import { lstatSync, readFileSync } from 'fs';
|
|
3
4
|
import { dirname, join, resolve } from 'path';
|
|
4
|
-
import { pathToFileURL } from 'url';
|
|
5
5
|
|
|
6
6
|
export const RUNTIME_BUNDLE_ENTRYPOINT = 'forge-runtime-bundle.js' as const;
|
|
7
|
+
export const RUNTIME_INTERPRETER_ENTRYPOINT = process.platform === 'win32'
|
|
8
|
+
? 'forge-runtime-bun.exe' as const
|
|
9
|
+
: 'forge-runtime-bun' as const;
|
|
7
10
|
|
|
8
11
|
interface RuntimeBundleManifestRecord {
|
|
9
12
|
runtimeBundleEntrypoint?: unknown;
|
|
10
13
|
runtimeBundleArtifactIdentity?: unknown;
|
|
14
|
+
runtimeInterpreterEntrypoint?: unknown;
|
|
15
|
+
runtimeInterpreterArtifactIdentity?: unknown;
|
|
11
16
|
}
|
|
12
17
|
|
|
13
18
|
function releaseManifestPath(argv: readonly string[]): string {
|
|
@@ -21,6 +26,8 @@ export function resolveCompiledRuntimeBundle(argv: readonly string[] = process.a
|
|
|
21
26
|
manifestPath: string;
|
|
22
27
|
bundlePath: string;
|
|
23
28
|
artifactIdentity: string;
|
|
29
|
+
interpreterPath: string;
|
|
30
|
+
interpreterArtifactIdentity: string;
|
|
24
31
|
} {
|
|
25
32
|
const manifestPath = releaseManifestPath(argv);
|
|
26
33
|
let manifest: RuntimeBundleManifestRecord;
|
|
@@ -38,9 +45,14 @@ export function resolveCompiledRuntimeBundle(argv: readonly string[] = process.a
|
|
|
38
45
|
if (!/^sha256:[a-f0-9]{64}$/.test(artifactIdentity)) {
|
|
39
46
|
throw new Error('RUNTIME_RELEASE_BUNDLE_IDENTITY_INVALID');
|
|
40
47
|
}
|
|
41
|
-
const
|
|
48
|
+
const releaseRoot = dirname(manifestPath);
|
|
49
|
+
const bundlePath = join(releaseRoot, RUNTIME_BUNDLE_ENTRYPOINT);
|
|
42
50
|
let actualIdentity: string;
|
|
43
51
|
try {
|
|
52
|
+
const status = lstatSync(bundlePath);
|
|
53
|
+
if (status.isSymbolicLink() || !status.isFile()) {
|
|
54
|
+
throw new Error('bundle must be a regular file');
|
|
55
|
+
}
|
|
44
56
|
actualIdentity = `sha256:${createHash('sha256').update(readFileSync(bundlePath)).digest('hex')}`;
|
|
45
57
|
} catch (error) {
|
|
46
58
|
throw new Error(`RUNTIME_RELEASE_BUNDLE_READ_FAILED: ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -48,16 +60,86 @@ export function resolveCompiledRuntimeBundle(argv: readonly string[] = process.a
|
|
|
48
60
|
if (actualIdentity !== artifactIdentity) {
|
|
49
61
|
throw new Error('RUNTIME_RELEASE_BUNDLE_ARTIFACT_IDENTITY_MISMATCH');
|
|
50
62
|
}
|
|
51
|
-
|
|
63
|
+
if (manifest.runtimeInterpreterEntrypoint !== RUNTIME_INTERPRETER_ENTRYPOINT) {
|
|
64
|
+
throw new Error(`RUNTIME_RELEASE_INTERPRETER_ENTRYPOINT_INVALID: expected ${RUNTIME_INTERPRETER_ENTRYPOINT}`);
|
|
65
|
+
}
|
|
66
|
+
const interpreterArtifactIdentity = typeof manifest.runtimeInterpreterArtifactIdentity === 'string'
|
|
67
|
+
? manifest.runtimeInterpreterArtifactIdentity.trim().toLowerCase()
|
|
68
|
+
: '';
|
|
69
|
+
if (!/^sha256:[a-f0-9]{64}$/.test(interpreterArtifactIdentity)) {
|
|
70
|
+
throw new Error('RUNTIME_RELEASE_INTERPRETER_IDENTITY_INVALID');
|
|
71
|
+
}
|
|
72
|
+
const interpreterPath = join(releaseRoot, RUNTIME_INTERPRETER_ENTRYPOINT);
|
|
73
|
+
let actualInterpreterIdentity: string;
|
|
74
|
+
try {
|
|
75
|
+
const status = lstatSync(interpreterPath);
|
|
76
|
+
if (status.isSymbolicLink() || !status.isFile() || (status.mode & 0o111) === 0) {
|
|
77
|
+
throw new Error('interpreter must be a regular executable file');
|
|
78
|
+
}
|
|
79
|
+
actualInterpreterIdentity = `sha256:${createHash('sha256').update(readFileSync(interpreterPath)).digest('hex')}`;
|
|
80
|
+
} catch (error) {
|
|
81
|
+
throw new Error(`RUNTIME_RELEASE_INTERPRETER_READ_FAILED: ${error instanceof Error ? error.message : String(error)}`);
|
|
82
|
+
}
|
|
83
|
+
if (actualInterpreterIdentity !== interpreterArtifactIdentity) {
|
|
84
|
+
throw new Error('RUNTIME_RELEASE_INTERPRETER_ARTIFACT_IDENTITY_MISMATCH');
|
|
85
|
+
}
|
|
86
|
+
return { manifestPath, bundlePath, artifactIdentity, interpreterPath, interpreterArtifactIdentity };
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function runtimeChildArgs(argv: readonly string[]): string[] {
|
|
90
|
+
const firstRuntimeArgument = argv.findIndex((argument) => argument.startsWith('--'));
|
|
91
|
+
if (firstRuntimeArgument < 0 || !argv.includes('--controller-home')) {
|
|
92
|
+
throw new Error('RUNTIME_CONTROLLER_HOME_ARGUMENT_REQUIRED');
|
|
93
|
+
}
|
|
94
|
+
return argv.slice(firstRuntimeArgument);
|
|
52
95
|
}
|
|
53
96
|
|
|
54
97
|
export async function runCompiledRuntimeLoader(argv: string[] = process.argv): Promise<void> {
|
|
55
98
|
const bundle = resolveCompiledRuntimeBundle(argv);
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
99
|
+
const child = spawn(bundle.interpreterPath, [bundle.bundlePath, ...runtimeChildArgs(argv)], {
|
|
100
|
+
cwd: dirname(bundle.manifestPath),
|
|
101
|
+
stdio: 'inherit',
|
|
102
|
+
env: process.env,
|
|
103
|
+
});
|
|
104
|
+
let childExited = false;
|
|
105
|
+
const forwardSignal = (signal: NodeJS.Signals): void => {
|
|
106
|
+
if (childExited) return;
|
|
107
|
+
try { child.kill(signal); } catch { /* child lifecycle reconciliation owns terminal state */ }
|
|
108
|
+
};
|
|
109
|
+
const terminateChildOnLauncherExit = (): void => {
|
|
110
|
+
if (childExited) return;
|
|
111
|
+
try { child.kill('SIGTERM'); } catch { /* launcher is already exiting */ }
|
|
112
|
+
};
|
|
113
|
+
const forwardedSignals: NodeJS.Signals[] = process.platform === 'win32'
|
|
114
|
+
? ['SIGINT', 'SIGTERM']
|
|
115
|
+
: ['SIGINT', 'SIGTERM', 'SIGUSR1', 'SIGUSR2'];
|
|
116
|
+
const signalHandlers = new Map<NodeJS.Signals, () => void>();
|
|
117
|
+
for (const signal of forwardedSignals) {
|
|
118
|
+
const handler = () => forwardSignal(signal);
|
|
119
|
+
signalHandlers.set(signal, handler);
|
|
120
|
+
process.on(signal, handler);
|
|
121
|
+
}
|
|
122
|
+
process.once('exit', terminateChildOnLauncherExit);
|
|
123
|
+
try {
|
|
124
|
+
const outcome = await new Promise<{ code: number | null; signal: NodeJS.Signals | null }>((resolveChild, rejectChild) => {
|
|
125
|
+
child.once('error', rejectChild);
|
|
126
|
+
child.once('exit', (code, signal) => {
|
|
127
|
+
childExited = true;
|
|
128
|
+
resolveChild({ code, signal });
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
if (outcome.signal) {
|
|
132
|
+
for (const [signal, handler] of signalHandlers) process.off(signal, handler);
|
|
133
|
+
signalHandlers.clear();
|
|
134
|
+
process.off('exit', terminateChildOnLauncherExit);
|
|
135
|
+
process.kill(process.pid, outcome.signal);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (outcome.code !== 0) process.exitCode = outcome.code ?? 1;
|
|
139
|
+
} finally {
|
|
140
|
+
for (const [signal, handler] of signalHandlers) process.off(signal, handler);
|
|
141
|
+
process.off('exit', terminateChildOnLauncherExit);
|
|
59
142
|
}
|
|
60
|
-
await loaded.runCanonicalRuntimeCli(argv);
|
|
61
143
|
}
|
|
62
144
|
|
|
63
145
|
if (import.meta.main) {
|