@moretea-labs/forge 1.8.0 → 1.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +70 -7
- package/CHANGELOG.md +14 -0
- package/CLAUDE.md +17 -2
- package/CONTRIBUTING.md +3 -2
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/adapters/chatgpt/browser-delivery-host.ts +7 -1
- package/adapters/chatgpt/browser-delivery-runtime.ts +529 -56
- package/adapters/chatgpt/controller-binding-store.ts +101 -22
- package/adapters/chatgpt/controller-round-host.ts +15 -25
- package/adapters/chatgpt/controller-round-settlement-store.ts +58 -4
- package/adapters/chatgpt/provider-delivery.ts +228 -1
- package/adapters/chatgpt/work-conversation-binding-store.ts +79 -53
- package/adapters/computer/chatgpt-extension-target.ts +463 -0
- package/adapters/computer/chatgpt-target-router.ts +103 -0
- package/adapters/computer/chrome-extension/background.js +385 -0
- package/adapters/computer/chrome-extension/content.js +378 -0
- package/adapters/computer/chrome-extension/core.js +24 -0
- package/adapters/computer/chrome-extension/manifest.json +30 -0
- package/adapters/computer/desktop-operator-discovery.ts +11 -31
- package/adapters/computer/interaction-target-authority.ts +142 -18
- package/adapters/mcp/auth.ts +0 -1
- package/adapters/mcp/instructions.ts +5 -4
- package/adapters/mcp/multi-repository.ts +3 -19
- package/adapters/mcp/oauth.ts +73 -0
- package/adapters/mcp/paths.ts +4 -1
- package/adapters/mcp/runtime-gateway/automation-receipt-adapter.ts +87 -0
- package/adapters/mcp/runtime-gateway/bounded-result-runtime.ts +62 -0
- package/adapters/mcp/runtime-gateway/cognition-settlement.ts +201 -0
- package/adapters/mcp/runtime-gateway/context-adapter.ts +411 -73
- package/adapters/mcp/runtime-gateway/context-pack-sidecar.ts +91 -0
- package/adapters/mcp/runtime-gateway/controller-authority-adapter.ts +20 -5
- package/adapters/mcp/runtime-gateway/core-capability-adapter.ts +258 -0
- package/adapters/mcp/runtime-gateway/engineering-preconditions.ts +10 -27
- package/adapters/mcp/runtime-gateway/engineering-tool-contract.ts +15 -0
- package/adapters/mcp/runtime-gateway/execution-tools.ts +8 -42
- package/adapters/mcp/runtime-gateway/gateway-execution-adapter.ts +2 -1
- package/adapters/mcp/runtime-gateway/plugin-adapter.ts +117 -45
- package/adapters/mcp/runtime-gateway/process-tools.ts +190 -22
- package/adapters/mcp/runtime-gateway/protected-computer-adapter.ts +16 -4
- package/adapters/mcp/runtime-gateway/recovery-adapter.ts +69 -52
- package/adapters/mcp/runtime-gateway/repository-compat-adapter.ts +4 -35
- package/adapters/mcp/runtime-gateway/result-adapter.ts +10 -4
- package/adapters/mcp/runtime-gateway/router.ts +18 -504
- package/adapters/mcp/runtime-gateway/routing-policy.ts +499 -0
- package/adapters/mcp/runtime-gateway/runtime-observation-adapter.ts +14 -65
- package/adapters/mcp/runtime-gateway/runtime-readiness-observation.ts +218 -0
- package/adapters/mcp/runtime-gateway/runtime-tool-definitions.ts +113 -173
- package/adapters/mcp/runtime-gateway/runtime-tools.ts +15 -5
- package/adapters/mcp/runtime-gateway/scheduler-adapter.ts +1 -0
- package/adapters/mcp/runtime-gateway/shared-adapter.ts +20 -0
- package/adapters/mcp/runtime-gateway/status-inbox-adapter.ts +358 -266
- package/adapters/mcp/runtime-gateway/typescript-navigation-sidecar.ts +136 -0
- package/adapters/mcp/runtime-gateway/work-adapter.ts +261 -3122
- package/adapters/mcp/runtime-gateway/work-controller-operations.ts +257 -0
- package/adapters/mcp/runtime-gateway/work-detail-projection.ts +60 -0
- package/adapters/mcp/runtime-gateway/work-input-wire-migration.ts +246 -0
- package/adapters/mcp/runtime-gateway/work-learning-operations.ts +145 -0
- package/adapters/mcp/runtime-gateway/work-list-projection.ts +38 -0
- package/adapters/mcp/runtime-gateway/work-plan-operations.ts +382 -0
- package/adapters/mcp/runtime-gateway/work-repair-adapter.ts +308 -0
- package/adapters/mcp/runtime-gateway/work-requirement-operations.ts +148 -0
- package/adapters/mcp/runtime-gateway/work-semantic-operations.ts +263 -0
- package/adapters/mcp/runtime-gateway/work-workflow-operations.ts +113 -0
- package/adapters/mcp/runtime-gateway/workflow-supervisor-adapter.ts +156 -0
- package/adapters/mcp/server.ts +67 -23
- package/adapters/mcp/setup.ts +1 -3
- package/adapters/mcp/tool-mapping/legacy-tool-service.ts +44 -170
- package/adapters/mcp/tool-mapping/post-finalize-work-attribution.ts +4 -9
- package/adapters/mcp/tool-mapping/repository-tools.ts +133 -142
- package/adapters/mcp/toolset-names.ts +5 -0
- package/adapters/mcp/toolset.ts +6 -5
- package/adapters/mcp/transports/http-observation.ts +365 -0
- package/adapters/mcp/transports/http.ts +154 -677
- package/adapters/mcp/transports/oauth-http.ts +322 -0
- package/adapters/mcp/transports/session-registry.ts +6 -0
- package/adapters/mcp/tunnels/openai-secure-tunnel.ts +89 -5
- package/assets/plugin-registry.v1.json +6 -4
- package/assets/reference-configs/agentic-development-flow.md +25 -0
- package/assets/reference-configs/global-working-rules.md +19 -0
- package/assets/skill-version.json +2 -2
- package/docs/architecture/CURRENT.md +111 -41
- package/docs/architecture/decisions/20260803-release-identity-binding-and-exit-policy.md +14 -5
- package/docs/architecture/decisions/20260823-immediate-controller-relay.md +6 -3
- package/docs/architecture/decisions/20260907-assistant-learning-loop.md +2 -0
- package/docs/architecture/decisions/20260907-controller-round-transition-policy.md +19 -4
- package/docs/architecture/decisions/20260916-workflow-supervisor-authority.md +249 -0
- package/docs/architecture/decisions/20260917-cognitive-memory-foundation.md +82 -0
- package/docs/architecture/decisions/20260918-stable-candidate-release-lifecycle.md +221 -0
- package/docs/architecture/decisions/20260919-autonomous-work-liveness.md +62 -0
- package/docs/architecture/decisions/20260924-thin-semantic-working-context.md +72 -0
- package/docs/architecture/decisions/20261001-supervisor-turn-authority.md +237 -0
- package/docs/architecture/decisions/20261005-forge-v3-desktop-client-boundary.md +77 -0
- package/docs/architecture/domains/verification.md +1 -0
- package/docs/architecture/domains/workflow-engine.md +6 -0
- package/docs/architecture/modules/controller-runtime/transport-lifecycle.md +1 -1
- package/docs/forge-plugin-management.md +2 -2
- package/docs/operations/controller-performance-and-502.md +17 -0
- package/docs/operations/controller-reliability-runbook.md +2 -2
- package/docs/operations/features.md +1 -1
- package/docs/operations/features.zh-CN.md +1 -1
- package/docs/operations/homebrew.md +2 -2
- package/docs/operations/mcp-tool-exposure.md +2 -0
- package/docs/operations/releasing.md +2 -0
- package/docs/operations/standalone-disaster-recovery.md +14 -6
- package/docs/wiki/Implementation.md +1 -1
- package/package.json +25 -14
- package/packages/kernel/cognition/api/index.ts +6 -0
- package/packages/kernel/cognition/application/activation-service.ts +451 -0
- package/packages/kernel/cognition/application/consolidation-service.ts +185 -0
- package/packages/kernel/cognition/application/legacy-experience-adapter.ts +38 -0
- package/packages/kernel/cognition/application/memory-service.ts +64 -0
- package/packages/kernel/cognition/domain/learning.ts +106 -0
- package/packages/kernel/cognition/domain/memory.ts +254 -0
- package/packages/kernel/controller/api/index.ts +1 -0
- package/packages/kernel/controller/application/continuation-service.ts +281 -0
- package/packages/kernel/controller/application/controller-round-service.ts +12 -0
- package/packages/kernel/controller/domain/controller-round-transition-policy.ts +242 -21
- package/packages/kernel/controller/domain/controller-round.ts +4 -1
- package/packages/kernel/controller/domain/execution-quality.ts +3 -1
- package/packages/kernel/controller/infrastructure/controller-round-store.ts +689 -103
- package/packages/kernel/controller/infrastructure/controller-session-store.ts +297 -71
- package/packages/kernel/controller/ports/controller-host.ts +2 -0
- package/packages/kernel/identity/api/index.ts +10 -0
- package/packages/kernel/identity/domain/activity-projection.ts +43 -0
- package/packages/kernel/identity/domain/capability-broker.ts +60 -0
- package/packages/kernel/identity/domain/grant.ts +72 -0
- package/packages/kernel/identity/domain/owned-resource.ts +116 -0
- package/packages/kernel/identity/domain/user-request.ts +93 -0
- package/packages/kernel/identity/infrastructure/activity-projection-store.ts +77 -0
- package/packages/kernel/identity/infrastructure/capability-broker.ts +81 -0
- package/packages/kernel/identity/infrastructure/grant-store.ts +284 -0
- package/packages/kernel/identity/infrastructure/owned-resource-store.ts +259 -0
- package/packages/kernel/identity/infrastructure/user-request-store.ts +182 -0
- package/packages/kernel/scheduler/api/index.ts +0 -2
- package/packages/kernel/scheduler/application/schedule-service.ts +3 -0
- package/packages/kernel/scheduler/application/settlement.ts +0 -15
- package/packages/kernel/scheduler/domain/schedule.ts +87 -0
- package/packages/kernel/scheduler/infrastructure/schedule-store.ts +153 -133
- package/packages/kernel/work/api/index.ts +3 -2
- package/packages/kernel/work/application/work-service.ts +17 -42
- package/packages/kernel/work/domain/current-task-lineage.ts +104 -0
- package/packages/kernel/work/domain/engineering-design.ts +10 -5
- package/packages/kernel/work/domain/engineering-profile.ts +8 -12
- package/packages/kernel/work/domain/evaluation-promotion-receipt.ts +186 -0
- package/packages/kernel/work/domain/execution-concurrency.ts +19 -26
- package/packages/kernel/work/domain/execution-snapshot.ts +0 -31
- package/packages/kernel/work/domain/implementation-review.ts +14 -331
- package/packages/kernel/work/domain/objective-graph.ts +119 -0
- package/packages/kernel/work/domain/project-engineering-contract.ts +23 -1
- package/packages/kernel/work/domain/repository-completion-receipt.ts +1 -1
- package/packages/kernel/work/domain/state-machine.ts +25 -63
- package/packages/kernel/work/domain/types.ts +57 -51
- package/packages/kernel/work/infrastructure/work-contract-store.ts +819 -728
- package/packages/kernel/work/ports/work-contract-store.ts +5 -2
- package/packages/plugin-runtime/browser/session-authority.ts +2 -1
- package/packages/plugin-runtime/computer/chatgpt-identity.ts +24 -0
- package/packages/plugin-runtime/computer/conversation-target.ts +143 -0
- package/packages/plugin-runtime/computer/index.ts +2 -0
- package/packages/plugin-runtime/computer/target-authority.ts +26 -1
- package/packages/plugin-runtime/external/unix-jsonl-transport.ts +142 -18
- package/packages/protocols/computer/contract.ts +27 -1
- package/scripts/activate-source-baseline.ts +7 -9
- package/scripts/canary-controller-semantic-wait.ts +12 -24
- package/scripts/check-mcp-compatibility.ts +48 -136
- package/scripts/check-runtime-architecture.mjs +622 -217
- package/scripts/forge-local-recovery-helper.mjs +93 -15
- package/scripts/lib/project-init-lib.sh +3 -0
- package/scripts/open-source-audit-allowlist.txt +1 -2
- package/scripts/run-bounded-command.mjs +5 -0
- package/scripts/run-governed-gate.ts +0 -1
- package/scripts/run-mobile-monitor-bridge.ts +0 -1
- package/scripts/smoke-control-plane-failure-domain.ts +94 -0
- package/scripts/smoke-mcp-http-runtime.ts +5 -0
- package/scripts/smoke-runtime-recovery.ts +12 -43
- package/scripts/smoke-schedule-engine.ts +23 -15
- package/scripts/smoke-unattended-transport-recovery.ts +223 -0
- package/scripts/smoke-user-request-continuation-restart.ts +232 -0
- package/scripts/smoke-workflow-supervisor-chrome-adapter.ts +92 -0
- package/scripts/smoke-workflow-supervisor-process-restart.ts +276 -0
- package/scripts/smoke-workflow-supervisor-restart-recovery.ts +150 -0
- package/scripts/smoke-workflow-supervisor.ts +103 -0
- package/scripts/verify-forge-runtime.sh +2 -1
- package/src/cli/agent-jobs/executor-health.ts +11 -34
- package/src/cli/agent-jobs/integration.ts +18 -49
- package/src/cli/agent-jobs/job-manager.ts +7 -3
- package/src/cli/commands/brain-assistant.ts +27 -13
- package/src/cli/commands/brain.ts +13 -15
- package/src/cli/commands/chatgpt.ts +1 -163
- package/src/cli/commands/recovery.ts +135 -121
- package/src/cli/commands/runtime.ts +3 -3
- package/src/cli/commands/setup-profile.ts +8 -0
- package/src/cli/controller/check-runner.ts +13 -2
- package/src/cli/controller/completion-backlog.ts +3 -3
- package/src/cli/controller/completion-orchestrator.ts +4 -43
- package/src/cli/controller/completion-target.ts +3 -72
- package/src/cli/controller/context/source-materializer.ts +81 -100
- package/src/cli/controller/context-pack.ts +10 -8
- package/src/cli/controller/execution-completion.ts +4 -7
- package/src/cli/controller/execution-policy.ts +36 -153
- package/src/cli/controller/governance.ts +2 -3
- package/src/cli/controller/issue-store.ts +4 -99
- package/src/cli/controller/launch-agents.ts +59 -18
- package/src/cli/controller/operational-plan.ts +24 -51
- package/src/cli/controller/runtime-config.ts +5 -1
- package/src/cli/controller/stuck-state-migration.ts +2 -3
- package/src/cli/controller/systemd-user.ts +39 -1
- package/src/cli/editing/edit-session.ts +1 -7
- package/src/cli/local-bridge/console-automations.ts +18 -13
- package/src/cli/local-bridge/console-view-models.ts +3 -12
- package/src/cli/local-bridge/facade-api.ts +64 -191
- package/src/cli/local-bridge/server.ts +24 -147
- package/src/cli/local-bridge/types.ts +0 -1
- package/src/cli/mcp/oauth-client-retirement.ts +74 -0
- package/src/cli/repositories/command-executor.ts +29 -23
- package/src/cli/repositories/command-scope.ts +35 -16
- package/src/cli/repositories/controller-home.ts +48 -0
- package/src/cli/repositories/ephemeral-workspace.ts +20 -30
- package/src/cli/repositories/git-command-executor.ts +2 -2
- package/src/cli/repositories/registry.ts +77 -11
- package/src/cli/repositories/structured-git.ts +62 -2
- package/src/cli/repository/session-cache.ts +92 -6
- package/src/runtime/context/assistant-context.ts +20 -7
- package/src/runtime/context/assistant-work-context.ts +89 -27
- package/src/runtime/context/automatic-learning.ts +565 -0
- package/src/runtime/context/cognitive-attention.ts +173 -0
- package/src/runtime/context/cognitive-skill-canary.ts +158 -0
- package/src/runtime/context/context-closure.ts +46 -9
- package/src/runtime/context/context-pack-process.ts +103 -0
- package/src/runtime/context/context-plane.ts +1 -9
- package/src/runtime/context/direct-controller-learning.ts +298 -0
- package/src/runtime/context/semantic-navigation-contract.ts +9 -0
- package/src/runtime/context/semantic-navigation.ts +6 -34
- package/src/runtime/context/typescript-navigation-process.ts +145 -0
- package/src/runtime/context/typescript-navigation.ts +89 -3
- package/src/runtime/control-plane/cleanup-artifact-retention.ts +212 -9
- package/src/runtime/control-plane/concurrency/work-execution-concurrency.ts +9 -47
- package/src/runtime/control-plane/execution/controller-authority-recovery.ts +34 -4
- package/src/runtime/control-plane/execution/edit-validation-coordinator.ts +29 -20
- package/src/runtime/control-plane/execution/execution-identity.ts +23 -3
- package/src/runtime/control-plane/execution/repository-work-attribution.ts +7 -30
- package/src/runtime/control-plane/execution/retained-work-resume.ts +206 -199
- package/src/runtime/control-plane/execution/session-store.ts +31 -1
- package/src/runtime/control-plane/execution/validation.ts +6 -8
- package/src/runtime/control-plane/execution/work-authority-reconciler.ts +13 -42
- package/src/runtime/control-plane/execution/work-check-evidence.ts +137 -0
- package/src/runtime/control-plane/execution/work-completion-authority.ts +30 -85
- package/src/runtime/control-plane/execution/work-delivery-service.ts +497 -0
- package/src/runtime/control-plane/execution/work-evidence-policy.ts +12 -50
- package/src/runtime/control-plane/execution/work-execution-support.ts +50 -149
- package/src/runtime/control-plane/execution/work-handle-authority.ts +188 -109
- package/src/runtime/control-plane/execution/work-handle-store.ts +19 -43
- package/src/runtime/control-plane/execution/work-head-settlement.ts +53 -20
- package/src/runtime/control-plane/execution/work-lifecycle-audit.ts +52 -29
- package/src/runtime/control-plane/execution/work-operation-service.ts +43 -27
- package/src/runtime/control-plane/execution/work-preparation-service.ts +126 -266
- package/src/runtime/control-plane/execution/work-remote-delivery.ts +2 -3
- package/src/runtime/control-plane/execution/work-revision-diff.ts +39 -0
- package/src/runtime/control-plane/execution/work-terminal-cleanup.ts +173 -186
- package/src/runtime/control-plane/execution/work-validation-reconciler.ts +28 -84
- package/src/runtime/control-plane/execution/work-verification-service.ts +406 -50
- package/src/runtime/control-plane/execution/work-verification-snapshot.ts +5 -1
- package/src/runtime/control-plane/facade/capability-registry.ts +362 -37
- package/src/runtime/control-plane/facade/check-normalization.ts +3 -9
- package/src/runtime/control-plane/facade/codex-delegation.ts +10 -11
- package/src/runtime/control-plane/facade/controller-connection.ts +135 -0
- package/src/runtime/control-plane/facade/goal-workloop-access.ts +1 -20
- package/src/runtime/control-plane/facade/goal-workloop.ts +281 -1753
- package/src/runtime/control-plane/facade/handoff-inbox-application.ts +12 -25
- package/src/runtime/control-plane/facade/handoff-inbox-store.ts +256 -52
- package/src/runtime/control-plane/facade/index.ts +0 -1
- package/src/runtime/control-plane/facade/operation-digest.ts +12 -15
- package/src/runtime/control-plane/facade/plan-contract-store.ts +451 -991
- package/src/runtime/control-plane/facade/policy-gate.ts +0 -23
- package/src/runtime/control-plane/facade/repository-work-admission.ts +12 -22
- package/src/runtime/control-plane/facade/requirement-authority.ts +102 -199
- package/src/runtime/control-plane/facade/requirement-board.ts +3 -3
- package/src/runtime/control-plane/facade/rh-work-operation-contract.ts +51 -14
- package/src/runtime/control-plane/facade/self-healing-loop.ts +18 -53
- package/src/runtime/control-plane/facade/suggested-actions.ts +15 -18
- package/src/runtime/control-plane/facade/types.ts +49 -108
- package/src/runtime/control-plane/facade/work-continuation.ts +8 -8
- package/src/runtime/control-plane/generated-cache-retention.ts +97 -1
- package/src/runtime/control-plane/global-scheduler/autonomous-continuation.ts +248 -0
- package/src/runtime/control-plane/global-scheduler/durable-admission.ts +1 -1
- package/src/runtime/control-plane/global-scheduler/maintenance.ts +239 -112
- package/src/runtime/control-plane/global-scheduler/reconciliation.ts +2 -1
- package/src/runtime/control-plane/global-scheduler/scheduler.ts +66 -40
- package/src/runtime/control-plane/global-scheduler/wake-signal.ts +42 -2
- package/src/runtime/control-plane/governance/access-policy.ts +19 -2
- package/src/runtime/control-plane/governance/authorization.ts +20 -3
- package/src/runtime/control-plane/launcher/chatgpt-round-continuation.ts +63 -300
- package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +28 -300
- package/src/runtime/control-plane/launcher/local-conversation-controller.ts +238 -0
- package/src/runtime/control-plane/launcher/provider-mcp-bootstrap.ts +5 -2
- package/src/runtime/control-plane/launcher/thin-launcher.ts +96 -240
- package/src/runtime/control-plane/persistence/cognition-store.ts +820 -0
- package/src/runtime/control-plane/persistence/experience-store.ts +162 -29
- package/src/runtime/control-plane/persistence/requirement-store.ts +216 -74
- package/src/runtime/control-plane/persistence/sqlite-store.ts +113 -6
- package/src/runtime/control-plane/release-retention.ts +135 -47
- package/src/runtime/control-plane/repository-namespace-retention.ts +2 -2
- package/src/runtime/control-plane/runtime-cleanup.ts +290 -21
- package/src/runtime/control-plane/workspace/project-onboarding.ts +80 -0
- package/src/runtime/control-plane/workspace/semantic-sync-service.ts +19 -5
- package/src/runtime/control-plane/workspace/workspace-store.ts +169 -0
- package/src/runtime/diagnostics/incident-repair.ts +313 -146
- package/src/runtime/diagnostics/mcp-timing.ts +114 -0
- package/src/runtime/evidence/artifact-store.ts +158 -40
- package/src/runtime/evidence/evidence-store.ts +112 -8
- package/src/runtime/evidence/output-handle-index.ts +225 -0
- package/src/runtime/evidence/result-store.ts +158 -44
- package/src/runtime/execution/jobs/store.ts +3 -4
- package/src/runtime/execution/managed-workspace.ts +57 -0
- package/src/runtime/execution/process-runtime/check-facade.ts +1 -1
- package/src/runtime/execution/process-runtime/check-result-retention.ts +2 -2
- package/src/runtime/execution/process-runtime/check-result.ts +105 -1
- package/src/runtime/execution/process-runtime/check-runner-sidecar.ts +18 -8
- package/src/runtime/execution/process-runtime/command-facade.ts +79 -27
- package/src/runtime/execution/process-runtime/gc.ts +15 -2
- package/src/runtime/execution/process-runtime/handle-index.ts +176 -0
- package/src/runtime/execution/process-runtime/host-command-lane.ts +139 -0
- package/src/runtime/execution/process-runtime/index.ts +3 -0
- package/src/runtime/execution/process-runtime/lightweight-managed.ts +251 -72
- package/src/runtime/execution/process-runtime/persisted-check.ts +3 -3
- package/src/runtime/execution/process-runtime/process-runner-entry.ts +47 -5
- package/src/runtime/execution/process-runtime/process-scope.ts +160 -0
- package/src/runtime/execution/process-runtime/resource-claims.ts +65 -61
- package/src/runtime/execution/process-runtime/runtime.ts +35 -2
- package/src/runtime/execution/process-runtime/store.ts +30 -2
- package/src/runtime/execution/process-runtime/types.ts +6 -1
- package/src/runtime/execution/workers/executor.ts +2 -6
- package/src/runtime/platform/service-inventory.ts +130 -0
- package/src/runtime/platform/service-manager.ts +8 -0
- package/src/runtime/plugins/action-application.ts +85 -28
- package/src/runtime/plugins/app-store-connect-adapter.ts +38 -14
- package/src/runtime/plugins/browser-adapter.ts +757 -34
- package/src/runtime/plugins/browser-automation-service.ts +23 -3
- package/src/runtime/plugins/browser-macos-bridge.ts +321 -29
- package/src/runtime/plugins/browser-manifest-surface.ts +45 -11
- package/src/runtime/plugins/browser-native-session-service.ts +63 -13
- package/src/runtime/plugins/browser-registration.ts +16 -0
- package/src/runtime/plugins/browser-runtime.ts +14 -1
- package/src/runtime/plugins/browser-session-authority.ts +2 -2
- package/src/runtime/plugins/browser-session-store.ts +46 -76
- package/src/runtime/plugins/capability-authorization-grants.ts +258 -62
- package/src/runtime/plugins/computer-chatgpt-browser-adapter-installer.ts +219 -0
- package/src/runtime/plugins/computer-chatgpt-macos-target.ts +891 -0
- package/src/runtime/plugins/computer-registration.ts +222 -11
- package/src/runtime/plugins/desktop-operator-external-policy.ts +36 -4
- package/src/runtime/plugins/desktop-operator-registration.ts +12 -4
- package/src/runtime/plugins/external-adapter.ts +42 -6
- package/src/runtime/plugins/external-registration.ts +21 -1
- package/src/runtime/plugins/gmail-adapter.ts +23 -2
- package/src/runtime/plugins/google-calendar-adapter.ts +2 -2
- package/src/runtime/plugins/google-shared.ts +14 -7
- package/src/runtime/plugins/google-tasks-adapter.ts +2 -2
- package/src/runtime/plugins/ios-adapter.ts +1 -1
- package/src/runtime/plugins/lightweight-action.ts +208 -2
- package/src/runtime/plugins/local-system-adapter.ts +12 -2
- package/src/runtime/plugins/managed-process-adapter.ts +12 -5
- package/src/runtime/plugins/plugin-action-sidecar.ts +17 -13
- package/src/runtime/plugins/plugin-management-adapter.ts +1 -1
- package/src/runtime/plugins/store.ts +602 -428
- package/src/runtime/plugins/types.ts +20 -0
- package/src/runtime/plugins/xiaohongshu-publish.ts +16 -0
- package/src/runtime/projections/invalidation.ts +7 -3
- package/src/runtime/projections/materialized-view.ts +80 -36
- package/src/runtime/recovery/actions.ts +3 -3
- package/src/runtime/recovery/capability-action-application.ts +46 -45
- package/src/runtime/recovery/lifecycle-inventory.ts +29 -29
- package/src/runtime/recovery/maintenance-executor.ts +374 -123
- package/src/runtime/recovery/store.ts +29 -11
- package/src/runtime/release/release-coordinator.ts +296 -0
- package/src/runtime/release/release-session.ts +716 -0
- package/src/runtime/release/release-state-migration.ts +25 -0
- package/src/runtime/resources/leases/store.ts +56 -25
- package/src/runtime/root/computer-composition.ts +191 -6
- package/src/runtime/root/controller-progression-composition.ts +192 -0
- package/src/runtime/root/controller-round-composition.ts +20 -1
- package/src/runtime/root/deployment-topology.ts +106 -0
- package/src/runtime/root/entry.ts +4 -3
- package/src/runtime/root/known-good-recovery.ts +184 -0
- package/src/runtime/root/local-bridge.ts +0 -1
- package/src/runtime/root/mcp-transport.ts +111 -18
- package/src/runtime/root/ownership.ts +261 -9
- package/src/runtime/root/package-connector-service.ts +105 -19
- package/src/runtime/root/package-runtime-release.ts +117 -18
- package/src/runtime/root/package-runtime-service.ts +17 -11
- package/src/runtime/root/release-execution-canary.ts +44 -12
- package/src/runtime/root/release-loader.ts +90 -8
- package/src/runtime/root/release-manifest.ts +80 -6
- package/src/runtime/root/release-materialize.ts +372 -28
- package/src/runtime/root/release-store.ts +395 -36
- package/src/runtime/root/runtime-lane.ts +191 -0
- package/src/runtime/root/runtime.ts +159 -27
- package/src/runtime/root/scheduled-controller-composition.ts +28 -3
- package/src/runtime/root/service-runner.ts +2 -2
- package/src/runtime/root/service.ts +36 -33
- package/src/runtime/root/status.ts +48 -0
- package/src/runtime/root/types.ts +32 -3
- package/src/runtime/root/workflow-supervisor-composition.ts +493 -0
- package/src/runtime/root/workflow-supervisor-runtime.ts +209 -0
- package/src/runtime/root/write-fence.ts +50 -2
- package/src/runtime/safe-tooling/google-credential-store.ts +76 -21
- package/src/runtime/safe-tooling/google-oauth-broker.ts +25 -7
- package/src/runtime/safe-tooling/workspace-auth.ts +1 -1
- package/src/runtime/shared/bounded-child-supervisor.ts +9 -1
- package/src/runtime/shared/process-environment.ts +20 -9
- package/src/runtime/shared/response-budget.ts +1 -3
- package/src/runtime/standalone-recovery/controller-home-migration.ts +16 -24
- package/src/runtime/standalone-recovery/core.ts +3702 -342
- package/src/runtime/standalone-recovery/entry.ts +469 -39
- package/src/runtime/standalone-recovery/installer.ts +262 -148
- package/src/runtime/standalone-recovery/mcp-server.ts +29 -193
- package/src/runtime/standalone-recovery/operation-lock.ts +1 -1
- package/src/runtime/standalone-recovery/performance.ts +54 -16
- package/src/runtime/standalone-recovery/release.ts +53 -5
- package/src/runtime/standalone-recovery/service-labels.ts +5 -2
- package/src/runtime/standalone-recovery/watchdog-heartbeat.ts +5 -2
- package/src/runtime/workflow/schedules/browser-probe.ts +17 -6
- package/src/runtime/workflow/schedules/chatgpt-automation-migration.ts +10 -3
- package/src/runtime/workflow/schedules/engine.ts +138 -172
- package/src/runtime/workflow/schedules/work-continuation.ts +44 -5
- package/src/runtime/workflows/runtime.ts +15 -19
- package/src/testing/test-governance.ts +5 -1
- package/supervisor/chatgpt-conversation.ts +23 -0
- package/supervisor/client.ts +201 -0
- package/supervisor/control-plane.ts +868 -0
- package/supervisor/entry.ts +15 -0
- package/supervisor/forge-validators.ts +80 -0
- package/supervisor/index.ts +5 -0
- package/supervisor/native-browser-adapter.ts +786 -0
- package/supervisor/native-messaging/host.ts +39 -0
- package/supervisor/native-messaging/manifest.ts +26 -0
- package/supervisor/native-messaging/protocol.ts +27 -0
- package/supervisor/paths.ts +18 -0
- package/supervisor/protocol.ts +202 -0
- package/supervisor/server.ts +404 -0
- package/supervisor/store.ts +1451 -0
- package/supervisor/tsconfig.json +8 -0
- package/supervisor/types.ts +255 -0
- package/adapters/chatgpt/controller-host.ts +0 -119
- package/adapters/mcp/controller-round-compatibility.ts +0 -184
- package/adapters/mcp/frozen-client-semantic-compatibility.ts +0 -292
- package/adapters/mcp/runtime-gateway/work-compat-adapter.ts +0 -502
- package/packages/kernel/progression/api/index.ts +0 -2
- package/packages/kernel/progression/application/projector.ts +0 -211
- package/packages/kernel/progression/domain/types.ts +0 -116
- package/packages/kernel/progression/index.ts +0 -1
- package/packages/kernel/scheduler/application/continuation-service.ts +0 -212
- package/packages/kernel/scheduler/domain/continuation.ts +0 -38
- package/packages/kernel/scheduler/infrastructure/continuation-dispatch-store.ts +0 -38
- package/packages/kernel/work/domain/admission-policy.ts +0 -34
- package/scripts/benchmark-background-check-overlap.ts +0 -228
- package/scripts/benchmark-computer-hotpath.ts +0 -255
- package/scripts/benchmark-controller-hotpath.ts +0 -212
- package/scripts/benchmark-controller-round2.ts +0 -191
- package/scripts/benchmark-ios-agent-device.ts +0 -511
- package/scripts/benchmark-mcp-host.sh +0 -117
- package/scripts/benchmark-mcp-transport.ts +0 -169
- package/scripts/benchmark-operational-memory-activation.ts +0 -235
- package/scripts/benchmark-operational-shadow.ts +0 -28
- package/scripts/benchmark-quality-harness.ts +0 -146
- package/scripts/benchmark-route-session-concurrency.ts +0 -915
- package/scripts/benchmark-thin-harness-gateway-ab.ts +0 -632
- package/scripts/benchmark-thin-harness-mcp-e2e.ts +0 -498
- package/scripts/benchmark-thin-harness.ts +0 -251
- package/scripts/benchmark-typescript-navigation.ts +0 -186
- package/scripts/benchmark-work-efficiency.ts +0 -334
- package/scripts/build-controller-ui.ts +0 -28
- package/scripts/check-npm-release.sh +0 -32
- package/scripts/check-public-release-surface.sh +0 -19
- package/scripts/check-release-published.sh +0 -57
- package/scripts/check-release-readiness.sh +0 -37
- package/scripts/check-release-version.mjs +0 -74
- package/scripts/check-tarball-install-smoke.sh +0 -150
- package/scripts/package-source-archive.sh +0 -147
- package/scripts/public-release-files.txt +0 -39
- package/scripts/public-release.ts +0 -174
- package/scripts/publish-release-tarball.sh +0 -27
- package/scripts/route-nl-vs-ts-eval.ts +0 -679
- package/scripts/stage-runtime-release.ts +0 -44
- package/src/cli/controller/progress.ts +0 -656
- package/src/cli/controller/work-mode.ts +0 -181
- package/src/cli/local-bridge/console-assets.ts +0 -17
- package/src/cli/local-bridge/dashboard.ts +0 -17
- package/src/cli/local-bridge/frontend/src/App.tsx +0 -10
- package/src/cli/local-bridge/frontend/src/components/Button.tsx +0 -1
- package/src/cli/local-bridge/frontend/src/components/DetailPane.tsx +0 -3
- package/src/cli/local-bridge/frontend/src/components/SearchField.tsx +0 -1
- package/src/cli/local-bridge/frontend/src/components/SectionHeader.tsx +0 -1
- package/src/cli/local-bridge/frontend/src/components/Segmented.tsx +0 -1
- package/src/cli/local-bridge/frontend/src/components/StatusText.tsx +0 -3
- package/src/cli/local-bridge/frontend/src/design/icons.tsx +0 -11
- package/src/cli/local-bridge/frontend/src/design/tokens.css +0 -8
- package/src/cli/local-bridge/frontend/src/features/automations/AutomationsView.tsx +0 -153
- package/src/cli/local-bridge/frontend/src/features/capabilities/CapabilitiesView.tsx +0 -37
- package/src/cli/local-bridge/frontend/src/features/overview/OverviewView.tsx +0 -183
- package/src/cli/local-bridge/frontend/src/features/repositories/RepositoriesView.tsx +0 -2
- package/src/cli/local-bridge/frontend/src/features/system/SystemView.tsx +0 -2
- package/src/cli/local-bridge/frontend/src/features/work/WorkView.tsx +0 -4
- package/src/cli/local-bridge/frontend/src/lib/api.ts +0 -30
- package/src/cli/local-bridge/frontend/src/lib/format.ts +0 -4
- package/src/cli/local-bridge/frontend/src/lib/routes.ts +0 -7
- package/src/cli/local-bridge/frontend/src/main.tsx +0 -1
- package/src/cli/local-bridge/frontend/src/shell/AppShell.tsx +0 -1
- package/src/cli/local-bridge/frontend/src/shell/CommandBar.tsx +0 -2
- package/src/cli/local-bridge/frontend/src/shell/Sidebar.tsx +0 -4
- package/src/cli/local-bridge/frontend/src/styles.css +0 -28
- package/src/cli/local-bridge/frontend/src/types.ts +0 -15
- package/src/cli/local-bridge/frontend/src/vite-env.d.ts +0 -1
- package/src/cli/local-bridge/frontend/vite.config.ts +0 -27
- package/src/cli/local-bridge/ui-dist/app.css +0 -1
- package/src/cli/local-bridge/ui-dist/app.js +0 -11228
- package/src/runtime/control-plane/execution/content-equivalent-commit-authority.ts +0 -169
- package/src/runtime/control-plane/execution/direct-canonical-work-reconciliation.ts +0 -85
- package/src/runtime/control-plane/execution/direct-edit-work-completion.ts +0 -655
- package/src/runtime/control-plane/execution/work-finalization-service.ts +0 -2850
- package/src/runtime/control-plane/execution/work-path-scope.ts +0 -37
- package/src/runtime/control-plane/execution/work-task-receipt.ts +0 -468
- package/src/runtime/control-plane/facade/controller-round-relay.ts +0 -3
- package/src/runtime/control-plane/facade/work-admission-policy.ts +0 -142
- package/src/runtime/control-plane/facade/work-implementation-review.ts +0 -2
- package/src/runtime/control-plane/facade/work-state-machine.ts +0 -2
- package/src/runtime/control-plane/facade/work-task-projection.ts +0 -66
- package/src/runtime/control-plane/routing/index.ts +0 -1
- package/src/runtime/control-plane/routing/route-policy.ts +0 -401
- package/src/runtime/control-plane/routing/workspace-admission.ts +0 -70
|
@@ -1,105 +1,53 @@
|
|
|
1
|
-
import { randomUUID } from 'crypto';
|
|
2
1
|
import type { IncomingMessage, ServerResponse } from 'http';
|
|
3
|
-
import { Server, type Tool } from '@modelcontextprotocol/server';
|
|
4
|
-
import {
|
|
5
|
-
import { McpSessionRegistry, type McpSessionRoute, type McpSessionSnapshot } from '../../../adapters/mcp/transports/session-registry';
|
|
2
|
+
import { createMcpHandler, Server, type Tool } from '@modelcontextprotocol/server';
|
|
3
|
+
import { toNodeHandler } from '@modelcontextprotocol/node';
|
|
6
4
|
import { FORGE_VERSION } from '../../version';
|
|
7
5
|
|
|
8
|
-
export const RECOVERY_MCP_SESSION_ROUTE: McpSessionRoute = '/recovery/mcp';
|
|
9
|
-
const RECOVERY_MCP_PRINCIPAL_ID = 'standalone-recovery-oauth-client';
|
|
10
|
-
const RECOVERY_MCP_CONNECTION_ID = 'forge-standalone-recovery';
|
|
11
|
-
|
|
12
6
|
export interface RecoveryMcpRequestContext {
|
|
13
7
|
remoteAddress: string;
|
|
14
8
|
}
|
|
15
9
|
|
|
16
|
-
export interface
|
|
10
|
+
export interface RecoveryMcpServerOptions {
|
|
17
11
|
tools: readonly Tool[];
|
|
18
12
|
dispatchTool(name: string, args: Record<string, unknown>, context: RecoveryMcpRequestContext): Promise<unknown>;
|
|
19
13
|
}
|
|
20
14
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
function isInitialize(body: unknown): boolean {
|
|
30
|
-
return Boolean(body && typeof body === 'object' && !Array.isArray(body) && (body as { method?: unknown }).method === 'initialize');
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function initializeClientIdentity(body: unknown): string {
|
|
34
|
-
if (!body || typeof body !== 'object' || Array.isArray(body)) return 'unknown-client';
|
|
35
|
-
const params = (body as { params?: unknown }).params;
|
|
36
|
-
if (!params || typeof params !== 'object' || Array.isArray(params)) return 'unknown-client';
|
|
37
|
-
const clientInfo = (params as { clientInfo?: unknown }).clientInfo;
|
|
38
|
-
if (!clientInfo || typeof clientInfo !== 'object' || Array.isArray(clientInfo)) return 'unknown-client';
|
|
39
|
-
const name = typeof (clientInfo as { name?: unknown }).name === 'string' ? (clientInfo as { name: string }).name.trim() : 'unknown';
|
|
40
|
-
const version = typeof (clientInfo as { version?: unknown }).version === 'string' ? (clientInfo as { version: string }).version.trim() : 'unknown';
|
|
41
|
-
return `${name || 'unknown'}/${version || 'unknown'}`.slice(0, 200);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function sendSessionLookupError(response: ServerResponse, id: string | undefined): void {
|
|
45
|
-
const missing = !id?.trim();
|
|
46
|
-
response.statusCode = missing ? 400 : 404;
|
|
47
|
-
response.setHeader('content-type', 'application/json; charset=utf-8');
|
|
48
|
-
response.setHeader('cache-control', 'no-store');
|
|
49
|
-
response.setHeader('Mcp-Session-Reset', 'reinitialize');
|
|
50
|
-
response.setHeader('x-forge-session-reset', 'reinitialize');
|
|
51
|
-
response.end(JSON.stringify(missing ? {
|
|
52
|
-
error: 'missing_session',
|
|
53
|
-
code: 'MCP_SESSION_REQUIRED',
|
|
54
|
-
message: 'Mcp-Session-Id header is required for this request.',
|
|
55
|
-
recoverable: true,
|
|
56
|
-
action: 'reinitialize',
|
|
57
|
-
} : {
|
|
58
|
-
error: 'session_not_found',
|
|
59
|
-
code: 'MCP_SESSION_EXPIRED',
|
|
60
|
-
message: 'MCP session not found or expired; initialize a new session.',
|
|
61
|
-
recoverable: true,
|
|
62
|
-
action: 'reinitialize',
|
|
63
|
-
}));
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export class RecoveryMcpSessionServer {
|
|
67
|
-
private readonly registry: RecoveryMcpRegistry;
|
|
68
|
-
|
|
69
|
-
constructor(private readonly options: RecoveryMcpSessionServerOptions) {
|
|
70
|
-
this.registry = new McpSessionRegistry<NodeStreamableHTTPServerTransport, RecoveryMcpSessionContext>({
|
|
71
|
-
maximumSessions: 16,
|
|
72
|
-
maximumSessionsPerPrincipal: 16,
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
snapshot(): McpSessionSnapshot {
|
|
77
|
-
return this.registry.snapshot();
|
|
78
|
-
}
|
|
15
|
+
/**
|
|
16
|
+
* Standalone Recovery owns durable recovery/release authority, never MCP
|
|
17
|
+
* transport-session authority. Both MCP 2026-07-28 and the bounded 2025-era
|
|
18
|
+
* compatibility protocol are served statelessly so a Gateway process
|
|
19
|
+
* replacement cannot invalidate the Recovery control path.
|
|
20
|
+
*/
|
|
21
|
+
export class RecoveryMcpServer {
|
|
22
|
+
constructor(private readonly options: RecoveryMcpServerOptions) {}
|
|
79
23
|
|
|
80
24
|
async close(): Promise<void> {
|
|
81
|
-
|
|
25
|
+
// Stateless handlers retain no cross-request transport resources.
|
|
82
26
|
}
|
|
83
27
|
|
|
84
28
|
async handle(request: IncomingMessage, response: ServerResponse, body?: unknown): Promise<void> {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
if (request.method === 'GET') {
|
|
91
|
-
await this.handleGet(request, response);
|
|
29
|
+
if (request.method !== 'POST') {
|
|
30
|
+
response.statusCode = 405;
|
|
31
|
+
response.setHeader('allow', 'POST');
|
|
32
|
+
response.end();
|
|
92
33
|
return;
|
|
93
34
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
35
|
+
|
|
36
|
+
const context: RecoveryMcpRequestContext = {
|
|
37
|
+
remoteAddress: request.socket.remoteAddress ?? 'unknown',
|
|
38
|
+
};
|
|
39
|
+
const handler = createMcpHandler(async () => this.createServer(context), {
|
|
40
|
+
legacy: 'stateless',
|
|
41
|
+
responseMode: 'auto',
|
|
42
|
+
});
|
|
43
|
+
try {
|
|
44
|
+
await toNodeHandler(handler)(request, response, body);
|
|
45
|
+
} finally {
|
|
46
|
+
await handler.close();
|
|
97
47
|
}
|
|
98
|
-
response.statusCode = 405;
|
|
99
|
-
response.end();
|
|
100
48
|
}
|
|
101
49
|
|
|
102
|
-
private createServer(context:
|
|
50
|
+
private createServer(context: RecoveryMcpRequestContext): Server {
|
|
103
51
|
const server = new Server(
|
|
104
52
|
{ name: 'forge-standalone-recovery', version: FORGE_VERSION },
|
|
105
53
|
{ capabilities: { tools: {} } },
|
|
@@ -128,116 +76,4 @@ export class RecoveryMcpSessionServer {
|
|
|
128
76
|
});
|
|
129
77
|
return server;
|
|
130
78
|
}
|
|
131
|
-
|
|
132
|
-
private async handlePost(request: IncomingMessage, response: ServerResponse, body: unknown): Promise<void> {
|
|
133
|
-
const currentSessionId = sessionId(request);
|
|
134
|
-
if (isInitialize(body)) {
|
|
135
|
-
if (currentSessionId) {
|
|
136
|
-
response.setHeader('Mcp-Session-Reset', 'reinitialized');
|
|
137
|
-
response.setHeader('x-forge-session-reset', 'reinitialized');
|
|
138
|
-
}
|
|
139
|
-
const reservationId = await this.registry.reserveForInitialize({
|
|
140
|
-
principalId: RECOVERY_MCP_PRINCIPAL_ID,
|
|
141
|
-
connectionId: RECOVERY_MCP_CONNECTION_ID,
|
|
142
|
-
route: RECOVERY_MCP_SESSION_ROUTE,
|
|
143
|
-
...(currentSessionId ? { supersedeSessionId: currentSessionId } : {}),
|
|
144
|
-
});
|
|
145
|
-
if (!reservationId) {
|
|
146
|
-
response.statusCode = 503;
|
|
147
|
-
response.setHeader('retry-after', '1');
|
|
148
|
-
response.setHeader('content-type', 'application/json; charset=utf-8');
|
|
149
|
-
response.end(JSON.stringify({
|
|
150
|
-
error: 'session_capacity',
|
|
151
|
-
code: 'MCP_SESSION_CAPACITY',
|
|
152
|
-
recoverable: true,
|
|
153
|
-
retryable: true,
|
|
154
|
-
action: 'retry',
|
|
155
|
-
}));
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
const context: RecoveryMcpSessionContext = { remoteAddress: request.socket.remoteAddress ?? 'unknown' };
|
|
159
|
-
let transport: NodeStreamableHTTPServerTransport | undefined;
|
|
160
|
-
let initializedSessionId: string | undefined;
|
|
161
|
-
try {
|
|
162
|
-
transport = new NodeStreamableHTTPServerTransport({
|
|
163
|
-
sessionIdGenerator: () => randomUUID(),
|
|
164
|
-
onsessioninitialized: (newSessionId: string): void => {
|
|
165
|
-
this.registry.commitInitialize(reservationId, {
|
|
166
|
-
sessionId: newSessionId,
|
|
167
|
-
transport: transport!,
|
|
168
|
-
toolContext: context,
|
|
169
|
-
route: RECOVERY_MCP_SESSION_ROUTE,
|
|
170
|
-
principalId: RECOVERY_MCP_PRINCIPAL_ID,
|
|
171
|
-
connectionId: RECOVERY_MCP_CONNECTION_ID,
|
|
172
|
-
clientIdentity: initializeClientIdentity(body),
|
|
173
|
-
});
|
|
174
|
-
initializedSessionId = newSessionId;
|
|
175
|
-
},
|
|
176
|
-
});
|
|
177
|
-
transport.onclose = () => {
|
|
178
|
-
if (transport?.sessionId) this.registry.detach(transport.sessionId);
|
|
179
|
-
};
|
|
180
|
-
const server = this.createServer(context);
|
|
181
|
-
await server.connect(transport);
|
|
182
|
-
await transport.handleRequest(request, response, body);
|
|
183
|
-
} finally {
|
|
184
|
-
if (initializedSessionId) this.registry.endPost(initializedSessionId);
|
|
185
|
-
this.registry.releaseInitialize(reservationId);
|
|
186
|
-
if (!transport?.sessionId) await transport?.close().catch(() => undefined);
|
|
187
|
-
}
|
|
188
|
-
return;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
if (!currentSessionId) {
|
|
192
|
-
sendSessionLookupError(response, currentSessionId);
|
|
193
|
-
return;
|
|
194
|
-
}
|
|
195
|
-
const managed = this.registry.get(currentSessionId);
|
|
196
|
-
if (!managed || managed.route !== RECOVERY_MCP_SESSION_ROUTE || managed.principalId !== RECOVERY_MCP_PRINCIPAL_ID) {
|
|
197
|
-
sendSessionLookupError(response, currentSessionId);
|
|
198
|
-
return;
|
|
199
|
-
}
|
|
200
|
-
this.registry.beginPost(currentSessionId);
|
|
201
|
-
try {
|
|
202
|
-
await managed.transport.handleRequest(request, response, body);
|
|
203
|
-
} finally {
|
|
204
|
-
this.registry.endPost(currentSessionId);
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
private async handleGet(request: IncomingMessage, response: ServerResponse): Promise<void> {
|
|
209
|
-
const currentSessionId = sessionId(request);
|
|
210
|
-
const managed = currentSessionId ? this.registry.get(currentSessionId) : undefined;
|
|
211
|
-
if (!managed || managed.route !== RECOVERY_MCP_SESSION_ROUTE || managed.principalId !== RECOVERY_MCP_PRINCIPAL_ID) {
|
|
212
|
-
sendSessionLookupError(response, currentSessionId);
|
|
213
|
-
return;
|
|
214
|
-
}
|
|
215
|
-
this.registry.beginStream(currentSessionId!);
|
|
216
|
-
let released = false;
|
|
217
|
-
const release = (): void => {
|
|
218
|
-
if (released) return;
|
|
219
|
-
released = true;
|
|
220
|
-
this.registry.endStream(currentSessionId!);
|
|
221
|
-
};
|
|
222
|
-
request.once('aborted', release);
|
|
223
|
-
response.once('close', release);
|
|
224
|
-
try {
|
|
225
|
-
await managed.transport.handleRequest(request, response);
|
|
226
|
-
} catch (error) {
|
|
227
|
-
release();
|
|
228
|
-
throw error;
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
private async handleDelete(request: IncomingMessage, response: ServerResponse): Promise<void> {
|
|
233
|
-
const currentSessionId = sessionId(request);
|
|
234
|
-
const managed = currentSessionId ? this.registry.get(currentSessionId) : undefined;
|
|
235
|
-
if (!managed || managed.route !== RECOVERY_MCP_SESSION_ROUTE || managed.principalId !== RECOVERY_MCP_PRINCIPAL_ID) {
|
|
236
|
-
sendSessionLookupError(response, currentSessionId);
|
|
237
|
-
return;
|
|
238
|
-
}
|
|
239
|
-
this.registry.setPendingCloseReason(currentSessionId!, 'client_delete');
|
|
240
|
-
await managed.transport.handleRequest(request, response);
|
|
241
|
-
if (this.registry.get(currentSessionId!)) await this.registry.close(currentSessionId!, 'client_delete');
|
|
242
|
-
}
|
|
243
79
|
}
|
|
@@ -72,7 +72,7 @@ export function recoveryOperationLockOwnerAlive(lock: RecoveryOperationLockRecor
|
|
|
72
72
|
if (!isProcessAlive(lock.pid)) return false;
|
|
73
73
|
if (!lock.processStartTime) return true;
|
|
74
74
|
const observed = processStartTime(lock.pid);
|
|
75
|
-
return observed ===
|
|
75
|
+
return observed === lock.processStartTime;
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
export function acquireRecoveryOperationLock(input: {
|
|
@@ -10,7 +10,7 @@ export interface RuntimePerformanceIdentity {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export interface RuntimePerformanceEvidence extends RuntimePerformanceIdentity {
|
|
13
|
-
policy: '
|
|
13
|
+
policy: 'runaway-cpu-v4';
|
|
14
14
|
measuredFrom: string;
|
|
15
15
|
measuredUntil: string;
|
|
16
16
|
warmupMs: number;
|
|
@@ -18,10 +18,43 @@ export interface RuntimePerformanceEvidence extends RuntimePerformanceIdentity {
|
|
|
18
18
|
sampleCount: number;
|
|
19
19
|
meanCpuPercent: number;
|
|
20
20
|
p95CpuPercent: number;
|
|
21
|
+
/** Windows whose CPU consumption reached the per-window runaway ceiling. */
|
|
22
|
+
sustainedHighWindowCount: number;
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
export interface RuntimeCpuReading { cpuMs: number; processStartTime: string }
|
|
24
26
|
|
|
27
|
+
const PERFORMANCE_WINDOW_MS = 2_500;
|
|
28
|
+
const PERFORMANCE_MAX_WINDOW_MS = 3_750;
|
|
29
|
+
const PERFORMANCE_WARMUP_WINDOWS = 4;
|
|
30
|
+
const PERFORMANCE_SAMPLE_WINDOWS = 20;
|
|
31
|
+
const PERFORMANCE_WARMUP_MS = PERFORMANCE_WINDOW_MS * PERFORMANCE_WARMUP_WINDOWS;
|
|
32
|
+
const PERFORMANCE_DURATION_MS = PERFORMANCE_WINDOW_MS * PERFORMANCE_SAMPLE_WINDOWS;
|
|
33
|
+
|
|
34
|
+
// Recovery known-good is a runaway safety gate, not the comparative release benchmark.
|
|
35
|
+
// The v4 sampler keeps the same 60-second budget, the same twenty 2.5-second windows
|
|
36
|
+
// and the same 25%/50% ceilings as v2/v3, but decides runaway from *sustained*
|
|
37
|
+
// consumption instead of from nearest-rank p95.
|
|
38
|
+
//
|
|
39
|
+
// Why p95 cannot be the decision rule: the Canonical Runtime performs bounded,
|
|
40
|
+
// scheduled maintenance (the release-fenced periodic cleanup child and the in-process
|
|
41
|
+
// scheduler/recovery passes). Such a pass lasts several seconds and recurs about once
|
|
42
|
+
// per minute, so in any 50-second observation at least two windows necessarily land
|
|
43
|
+
// inside it. nearest-rank p95 is exactly the second-highest window, so a healthy
|
|
44
|
+
// Runtime with an ~11% mean was deterministically rejected (live evidence:
|
|
45
|
+
// mean=12.60% p95=65.05% and mean=11.41% p95=65.13%, both rolled back within minutes
|
|
46
|
+
// of cutover) and every automatic release progression converged on rollback.
|
|
47
|
+
//
|
|
48
|
+
// A watchdog duty must distinguish "unbounded spin" from "bounded periodic work", so
|
|
49
|
+
// v4 rejects a sample only when the process is high for at least half of the observed
|
|
50
|
+
// windows (sustainedHighWindowCount * 2 >= sampleCount) or when the mean exceeds the
|
|
51
|
+
// ceiling. The historical runaway population (mean >= 90.64%, p95 >= 104.72%) fails
|
|
52
|
+
// both tests by a wide margin, while a once-per-minute bounded pass (<= 4 of 20
|
|
53
|
+
// windows) can no longer be mistaken for runaway. p95 stays in the evidence for audit.
|
|
54
|
+
// Relative <=10% regression remains Benchmark/Release Evaluation authority.
|
|
55
|
+
export const RECOVERY_RUNAWAY_MEAN_CPU_PERCENT = 25;
|
|
56
|
+
export const RECOVERY_RUNAWAY_P95_CPU_PERCENT = 50;
|
|
57
|
+
|
|
25
58
|
/** Dependencies are in-process test seams; no transport accepts evidence or threshold overrides. */
|
|
26
59
|
export interface RuntimePerformanceDependencies {
|
|
27
60
|
readCpu?: (pid: number) => RuntimeCpuReading;
|
|
@@ -54,20 +87,24 @@ export function assertRuntimePerformanceEvidence(
|
|
|
54
87
|
now = Date.now(),
|
|
55
88
|
): void {
|
|
56
89
|
const age = now - Date.parse(evidence.measuredUntil);
|
|
57
|
-
if (evidence.policy !== '
|
|
90
|
+
if (evidence.policy !== 'runaway-cpu-v4' || !samePerformanceIdentity(evidence, identity)
|
|
58
91
|
|| !Number.isFinite(age) || age < 0 || age > 60_000
|
|
59
|
-
|| evidence.warmupMs <
|
|
60
|
-
|| evidence.durationMs <
|
|
92
|
+
|| evidence.warmupMs < PERFORMANCE_WARMUP_MS || evidence.warmupMs > PERFORMANCE_MAX_WINDOW_MS * PERFORMANCE_WARMUP_WINDOWS
|
|
93
|
+
|| evidence.durationMs < PERFORMANCE_DURATION_MS || evidence.durationMs > PERFORMANCE_MAX_WINDOW_MS * PERFORMANCE_SAMPLE_WINDOWS || evidence.sampleCount !== PERFORMANCE_SAMPLE_WINDOWS
|
|
61
94
|
|| !Number.isFinite(evidence.meanCpuPercent) || evidence.meanCpuPercent < 0
|
|
62
|
-
|| !Number.isFinite(evidence.p95CpuPercent) || evidence.p95CpuPercent < 0
|
|
95
|
+
|| !Number.isFinite(evidence.p95CpuPercent) || evidence.p95CpuPercent < 0
|
|
96
|
+
|| !Number.isInteger(evidence.sustainedHighWindowCount)
|
|
97
|
+
|| evidence.sustainedHighWindowCount < 0
|
|
98
|
+
|| evidence.sustainedHighWindowCount > evidence.sampleCount) {
|
|
63
99
|
throw new Error('RECOVERY_PERFORMANCE_UNKNOWN: incomplete, stale or mismatched performance evidence');
|
|
64
100
|
}
|
|
65
|
-
|
|
66
|
-
|
|
101
|
+
const sustained = evidence.sustainedHighWindowCount * 2 >= evidence.sampleCount;
|
|
102
|
+
if (evidence.meanCpuPercent > RECOVERY_RUNAWAY_MEAN_CPU_PERCENT || sustained) {
|
|
103
|
+
throw new Error(`RECOVERY_PERFORMANCE_REJECTED: mean=${evidence.meanCpuPercent.toFixed(2)}% p95=${evidence.p95CpuPercent.toFixed(2)}% sustained=${evidence.sustainedHighWindowCount}/${evidence.sampleCount}`);
|
|
67
104
|
}
|
|
68
105
|
}
|
|
69
106
|
|
|
70
|
-
/** Observe
|
|
107
|
+
/** Observe 10 seconds of warmup followed by twenty 2.5-second CPU-time delta windows. */
|
|
71
108
|
export async function measureRuntimePerformance(
|
|
72
109
|
observeIdentity: () => RuntimePerformanceIdentity,
|
|
73
110
|
dependencies: RuntimePerformanceDependencies = {},
|
|
@@ -90,12 +127,12 @@ export async function measureRuntimePerformance(
|
|
|
90
127
|
};
|
|
91
128
|
const warmingAt = monotonicNow();
|
|
92
129
|
let previousWarmupAt = warmingAt;
|
|
93
|
-
for (let i = 0; i <
|
|
94
|
-
await sleep(
|
|
130
|
+
for (let i = 0; i < PERFORMANCE_WARMUP_WINDOWS; i++) {
|
|
131
|
+
await sleep(PERFORMANCE_WINDOW_MS);
|
|
95
132
|
observe();
|
|
96
133
|
const nextWarmupAt = monotonicNow();
|
|
97
134
|
const elapsed = nextWarmupAt - previousWarmupAt;
|
|
98
|
-
if (elapsed <
|
|
135
|
+
if (elapsed < PERFORMANCE_WINDOW_MS || elapsed > PERFORMANCE_MAX_WINDOW_MS) {
|
|
99
136
|
throw new Error('RECOVERY_PERFORMANCE_UNKNOWN: interrupted CPU warmup window');
|
|
100
137
|
}
|
|
101
138
|
previousWarmupAt = nextWarmupAt;
|
|
@@ -107,14 +144,14 @@ export async function measureRuntimePerformance(
|
|
|
107
144
|
const startedAt = previousAt;
|
|
108
145
|
let totalCpuMs = 0;
|
|
109
146
|
const windows: number[] = [];
|
|
110
|
-
for (let i = 0; i <
|
|
111
|
-
await sleep(
|
|
147
|
+
for (let i = 0; i < PERFORMANCE_SAMPLE_WINDOWS; i++) {
|
|
148
|
+
await sleep(PERFORMANCE_WINDOW_MS);
|
|
112
149
|
const nextCpu = observe().cpuMs;
|
|
113
150
|
const nextAt = monotonicNow();
|
|
114
151
|
const elapsed = nextAt - previousAt;
|
|
115
152
|
const cpuDelta = nextCpu - previousCpu;
|
|
116
|
-
// Suspended/overloaded collectors cannot pass as
|
|
117
|
-
if (elapsed <
|
|
153
|
+
// Suspended/overloaded collectors cannot pass as ordinary sample windows.
|
|
154
|
+
if (elapsed < PERFORMANCE_WINDOW_MS || elapsed > PERFORMANCE_MAX_WINDOW_MS || cpuDelta < 0) {
|
|
118
155
|
throw new Error('RECOVERY_PERFORMANCE_UNKNOWN: interrupted CPU observation window');
|
|
119
156
|
}
|
|
120
157
|
windows.push(cpuDelta / elapsed * 100);
|
|
@@ -125,10 +162,11 @@ export async function measureRuntimePerformance(
|
|
|
125
162
|
const durationMs = previousAt - startedAt;
|
|
126
163
|
windows.sort((a, b) => a - b);
|
|
127
164
|
const evidence: RuntimePerformanceEvidence = {
|
|
128
|
-
...identity, policy: '
|
|
165
|
+
...identity, policy: 'runaway-cpu-v4', measuredFrom, measuredUntil: new Date(wallNow()).toISOString(),
|
|
129
166
|
warmupMs, durationMs, sampleCount: windows.length,
|
|
130
167
|
meanCpuPercent: totalCpuMs / durationMs * 100,
|
|
131
168
|
p95CpuPercent: windows[Math.ceil(windows.length * 0.95) - 1]!,
|
|
169
|
+
sustainedHighWindowCount: windows.filter((cpuPercent) => cpuPercent >= RECOVERY_RUNAWAY_P95_CPU_PERCENT).length,
|
|
132
170
|
};
|
|
133
171
|
assertRuntimePerformanceEvidence(evidence, observeIdentity(), wallNow());
|
|
134
172
|
return evidence;
|
|
@@ -15,8 +15,8 @@ import {
|
|
|
15
15
|
import { dirname, join, relative, resolve, sep } from 'path';
|
|
16
16
|
import { writeJsonAtomic } from '../shared/json-files';
|
|
17
17
|
|
|
18
|
-
export const RECOVERY_RELEASE_BINARIES = [
|
|
19
|
-
|
|
18
|
+
export const RECOVERY_RELEASE_BINARIES = ['forge-recovery'] as const;
|
|
19
|
+
export const RECOVERY_RELEASE_COMPATIBILITY_BINARIES = [
|
|
20
20
|
'forge-recovery-gateway',
|
|
21
21
|
'forge-recovery-watchdog',
|
|
22
22
|
] as const;
|
|
@@ -24,7 +24,8 @@ export const RECOVERY_RELEASE_BINARIES = [
|
|
|
24
24
|
export const RECOVERY_RELEASE_ROLE_CANARY_ARG = '--forge-release-role-canary';
|
|
25
25
|
|
|
26
26
|
export type RecoveryReleaseBinary = (typeof RECOVERY_RELEASE_BINARIES)[number];
|
|
27
|
-
|
|
27
|
+
/** daemon is the only current persistent owner; gateway/watchdog remain legacy CLI compatibility roles. */
|
|
28
|
+
export type RecoveryRuntimeRole = 'daemon' | 'gateway' | 'watchdog';
|
|
28
29
|
export interface RecoveryReleaseManifest {
|
|
29
30
|
schemaVersion: 1;
|
|
30
31
|
releaseRevision: string;
|
|
@@ -84,6 +85,49 @@ export function recoveryRuntimeStatePath(controllerHome: string, role: RecoveryR
|
|
|
84
85
|
return join(recoveryRoot(controllerHome), 'state', `${role}-runtime.json`);
|
|
85
86
|
}
|
|
86
87
|
|
|
88
|
+
export function recoveryGatewayDrainMarkerPath(controllerHome: string): string {
|
|
89
|
+
return join(recoveryRoot(controllerHome), 'state', 'gateway-draining.json');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const RECOVERY_GATEWAY_DRAIN_MARKER_TTL_MS = 5 * 60_000;
|
|
93
|
+
|
|
94
|
+
export function recoveryGatewayIsDraining(controllerHome: string, now = Date.now()): boolean {
|
|
95
|
+
const path = recoveryGatewayDrainMarkerPath(controllerHome);
|
|
96
|
+
if (!existsSync(path)) return false;
|
|
97
|
+
try {
|
|
98
|
+
const marker = JSON.parse(readFileSync(path, 'utf8')) as { pid?: unknown; at?: unknown };
|
|
99
|
+
const pid = Number(marker.pid);
|
|
100
|
+
const at = typeof marker.at === 'string' ? Date.parse(marker.at) : Number.NaN;
|
|
101
|
+
if (!Number.isInteger(pid) || pid <= 0 || !Number.isFinite(at) || now - at > RECOVERY_GATEWAY_DRAIN_MARKER_TTL_MS) {
|
|
102
|
+
rmSync(path, { force: true });
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
try {
|
|
106
|
+
process.kill(pid, 0);
|
|
107
|
+
return true;
|
|
108
|
+
} catch (error) {
|
|
109
|
+
const code = (error as NodeJS.ErrnoException).code;
|
|
110
|
+
if (code === 'EPERM') return true;
|
|
111
|
+
rmSync(path, { force: true });
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
} catch {
|
|
115
|
+
rmSync(path, { force: true });
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export function setRecoveryGatewayDraining(controllerHome: string, draining: boolean): void {
|
|
121
|
+
const path = recoveryGatewayDrainMarkerPath(controllerHome);
|
|
122
|
+
if (!draining) {
|
|
123
|
+
rmSync(path, { force: true });
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
|
|
127
|
+
writeJsonAtomic(path, { schemaVersion: 1, draining: true, pid: process.pid, at: new Date().toISOString() });
|
|
128
|
+
chmodSync(path, 0o600);
|
|
129
|
+
}
|
|
130
|
+
|
|
87
131
|
function fileSha256(path: string): string {
|
|
88
132
|
return createHash('sha256').update(readFileSync(path)).digest('hex');
|
|
89
133
|
}
|
|
@@ -184,11 +228,15 @@ export function publishRecoveryCompatibilityLinks(controllerHome: string): void
|
|
|
184
228
|
assertRecoveryReleaseContained(controllerHome, current);
|
|
185
229
|
const binRoot = join(recoveryRoot(controllerHome), 'bin');
|
|
186
230
|
mkdirSync(binRoot, { recursive: true, mode: 0o700 });
|
|
187
|
-
|
|
231
|
+
const compatibilityTargets = [
|
|
232
|
+
...RECOVERY_RELEASE_BINARIES.map((binary) => ({ binary, target: binary })),
|
|
233
|
+
...RECOVERY_RELEASE_COMPATIBILITY_BINARIES.map((binary) => ({ binary, target: 'forge-recovery' as const })),
|
|
234
|
+
];
|
|
235
|
+
for (const { binary, target } of compatibilityTargets) {
|
|
188
236
|
const destination = join(binRoot, binary);
|
|
189
237
|
const temporary = `${destination}.${process.pid}.tmp`;
|
|
190
238
|
rmSync(temporary, { force: true });
|
|
191
|
-
symlinkSync(join('..', 'current',
|
|
239
|
+
symlinkSync(join('..', 'current', target), temporary);
|
|
192
240
|
renameSync(temporary, destination);
|
|
193
241
|
}
|
|
194
242
|
}
|
|
@@ -1,2 +1,5 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
1
|
+
export {
|
|
2
|
+
FORGE_RECOVERY_DAEMON_LABEL as RECOVERY_DAEMON_LABEL,
|
|
3
|
+
FORGE_RECOVERY_GATEWAY_LABEL as RECOVERY_GATEWAY_LABEL,
|
|
4
|
+
FORGE_RECOVERY_WATCHDOG_LABEL as RECOVERY_WATCHDOG_LABEL,
|
|
5
|
+
} from '../platform/service-inventory';
|
|
@@ -151,10 +151,13 @@ export function evaluateRecoveryWatchdogHealth(input: {
|
|
|
151
151
|
return { ok: true, detail: 'Recovery Watchdog heartbeat, PID, and immutable release identity are current', pulseAgeMs, heartbeat, runtimeIdentity, currentReleaseRevision: current.releaseRevision };
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
-
export function observeRecoveryWatchdogHealth(controllerHome: string): RecoveryWatchdogHealth {
|
|
154
|
+
export function observeRecoveryWatchdogHealth(controllerHome: string, enabled = true): RecoveryWatchdogHealth {
|
|
155
|
+
if (!enabled) {
|
|
156
|
+
return { ok: true, detail: 'Recovery Watchdog is disabled by the configured install profile' };
|
|
157
|
+
}
|
|
155
158
|
return evaluateRecoveryWatchdogHealth({
|
|
156
159
|
heartbeat: readRecoveryWatchdogHeartbeat(controllerHome),
|
|
157
|
-
runtimeIdentity: readRecoveryRuntimeIdentity(controllerHome, '
|
|
160
|
+
runtimeIdentity: readRecoveryRuntimeIdentity(controllerHome, 'daemon'),
|
|
158
161
|
currentRelease: readCurrentRecoveryRelease(controllerHome),
|
|
159
162
|
});
|
|
160
163
|
}
|
|
@@ -82,6 +82,7 @@ async function browserAction(
|
|
|
82
82
|
occurrenceId: string,
|
|
83
83
|
actionId: string,
|
|
84
84
|
args: Record<string, unknown>,
|
|
85
|
+
authorizationGrantRefs: readonly string[],
|
|
85
86
|
): Promise<Record<string, unknown>> {
|
|
86
87
|
return executeBrowserPluginAction({
|
|
87
88
|
controllerHome,
|
|
@@ -92,9 +93,16 @@ async function browserAction(
|
|
|
92
93
|
requestId: `schedule-browser-probe:${occurrenceId}:${actionId}`,
|
|
93
94
|
args,
|
|
94
95
|
origin: { surface: 'schedule', actor: 'browser-probe', correlationId: occurrenceId },
|
|
96
|
+
authorizationGrantRefs,
|
|
95
97
|
});
|
|
96
98
|
}
|
|
97
99
|
|
|
100
|
+
/** Exact interactive grants attached to this Schedule; contents remain Controller-owned. */
|
|
101
|
+
export function scheduledBrowserProbeAuthorizationGrantRefs(args: Record<string, unknown>): string[] {
|
|
102
|
+
if (!Array.isArray(args.authorization_grant_refs)) return [];
|
|
103
|
+
return [...new Set(args.authorization_grant_refs.map(String).map((value) => value.trim()).filter(Boolean))];
|
|
104
|
+
}
|
|
105
|
+
|
|
98
106
|
interface ScheduledBrowserSessionMetadata {
|
|
99
107
|
url?: string;
|
|
100
108
|
ownership?: string;
|
|
@@ -137,8 +145,9 @@ async function scheduledBrowserSessionMetadata(
|
|
|
137
145
|
repository: RepositoryRecord,
|
|
138
146
|
occurrenceId: string,
|
|
139
147
|
sessionId: string,
|
|
148
|
+
authorizationGrantRefs: readonly string[],
|
|
140
149
|
): Promise<ScheduledBrowserSessionMetadata | undefined> {
|
|
141
|
-
const inventory = await browserAction(controllerHome, repository, occurrenceId, 'list_sessions', {});
|
|
150
|
+
const inventory = await browserAction(controllerHome, repository, occurrenceId, 'list_sessions', {}, authorizationGrantRefs);
|
|
142
151
|
const sessions = Array.isArray(inventory.sessions) ? inventory.sessions : [];
|
|
143
152
|
const saved = sessions
|
|
144
153
|
.map((entry) => recordValue(entry))
|
|
@@ -170,10 +179,12 @@ export async function executeScheduledBrowserProbe(input: {
|
|
|
170
179
|
const url = stringValue(input.args.probe_url) ?? stringValue(input.args.url);
|
|
171
180
|
if (!requestedSessionId && !url) throw new Error('SCHEDULE_BROWSER_PROBE_TARGET_REQUIRED');
|
|
172
181
|
|
|
182
|
+
const authorizationGrantRefs = scheduledBrowserProbeAuthorizationGrantRefs(input.args);
|
|
183
|
+
|
|
173
184
|
const waitUntil = stringValue(input.args.wait_until) ?? 'domcontentloaded';
|
|
174
185
|
const timeoutMs = boundedNumber(input.args.timeout_ms, 60_000, 1_000, 120_000);
|
|
175
186
|
const savedSession = requestedSessionId
|
|
176
|
-
? await scheduledBrowserSessionMetadata(input.controllerHome, input.repository, input.occurrenceId, requestedSessionId)
|
|
187
|
+
? await scheduledBrowserSessionMetadata(input.controllerHome, input.repository, input.occurrenceId, requestedSessionId, authorizationGrantRefs)
|
|
177
188
|
: undefined;
|
|
178
189
|
const navigationAction = scheduledBrowserProbeNavigationAction(savedSession?.ownership, Boolean(url));
|
|
179
190
|
const managedRehydrateIntent = scheduledBrowserProbeManagedRehydrateIntent(savedSession);
|
|
@@ -188,7 +199,7 @@ export async function executeScheduledBrowserProbe(input: {
|
|
|
188
199
|
state: waitUntil,
|
|
189
200
|
timeout_ms: timeoutMs,
|
|
190
201
|
...managedRehydrateIntent,
|
|
191
|
-
});
|
|
202
|
+
}, authorizationGrantRefs);
|
|
192
203
|
} else if (navigationAction === 'navigate') {
|
|
193
204
|
navigation = await browserAction(input.controllerHome, input.repository, input.occurrenceId, 'navigate', {
|
|
194
205
|
...(requestedSessionId ? { session_id: requestedSessionId } : {}),
|
|
@@ -197,14 +208,14 @@ export async function executeScheduledBrowserProbe(input: {
|
|
|
197
208
|
timeout_ms: timeoutMs,
|
|
198
209
|
retries: 1,
|
|
199
210
|
...managedRehydrateIntent,
|
|
200
|
-
});
|
|
211
|
+
}, authorizationGrantRefs);
|
|
201
212
|
} else {
|
|
202
213
|
navigation = await browserAction(input.controllerHome, input.repository, input.occurrenceId, 'reload', {
|
|
203
214
|
session_id: requestedSessionId!,
|
|
204
215
|
wait_until: waitUntil,
|
|
205
216
|
timeout_ms: timeoutMs,
|
|
206
217
|
...managedRehydrateIntent,
|
|
207
|
-
});
|
|
218
|
+
}, authorizationGrantRefs);
|
|
208
219
|
}
|
|
209
220
|
|
|
210
221
|
const session = recordValue(navigation.session);
|
|
@@ -224,7 +235,7 @@ export async function executeScheduledBrowserProbe(input: {
|
|
|
224
235
|
session_id: sessionId,
|
|
225
236
|
...(stringValue(input.args.selector) ? { selector: stringValue(input.args.selector) } : {}),
|
|
226
237
|
max_chars: boundedNumber(input.args.max_chars, 20_000, 256, 100_000),
|
|
227
|
-
});
|
|
238
|
+
}, authorizationGrantRefs);
|
|
228
239
|
rawText = stringValue(textResult.text) ?? '';
|
|
229
240
|
truncated = textResult.truncated === true;
|
|
230
241
|
}
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import type { RepositorySchedule } from '../../../../packages/kernel/scheduler/api/index';
|
|
2
|
+
import {
|
|
3
|
+
DEFAULT_CHATGPT_AUTOMATION_MODEL,
|
|
4
|
+
DEFAULT_CHATGPT_AUTOMATION_REASONING,
|
|
5
|
+
DEFAULT_CHATGPT_AUTOMATION_TAB_POLICY,
|
|
6
|
+
} from '../../../../adapters/chatgpt/provider-delivery';
|
|
2
7
|
|
|
3
8
|
export const CHATGPT_AUTOMATION_EXECUTION_PROFILE = 'chatgpt_browser_v1';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
export const
|
|
9
|
+
// Missing legacy Schedule preferences inherit the single provider defaults.
|
|
10
|
+
// Explicit saved preferences remain authoritative and are never overwritten.
|
|
11
|
+
export const CHATGPT_AUTOMATION_DEFAULT_MODEL = DEFAULT_CHATGPT_AUTOMATION_MODEL;
|
|
12
|
+
export const CHATGPT_AUTOMATION_DEFAULT_REASONING = DEFAULT_CHATGPT_AUTOMATION_REASONING;
|
|
13
|
+
export const CHATGPT_AUTOMATION_DEFAULT_TAB_POLICY = DEFAULT_CHATGPT_AUTOMATION_TAB_POLICY;
|
|
7
14
|
|
|
8
15
|
export interface ChatgptAutomationScheduleMigrationResult {
|
|
9
16
|
changed: boolean;
|