@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
|
@@ -4,15 +4,46 @@ import { existsSync, readFileSync } from 'fs';
|
|
|
4
4
|
import { isAbsolute, join, resolve } from 'path';
|
|
5
5
|
import { pathToFileURL } from 'url';
|
|
6
6
|
import { resolveControllerHome } from '../src/cli/repositories/controller-home.ts';
|
|
7
|
-
import { findRegisteredRepositoryByCheckoutRoot } from '../src/cli/repositories/registry.ts';
|
|
7
|
+
import { findRegisteredRepositoryByCheckoutRoot, getRepository } from '../src/cli/repositories/registry.ts';
|
|
8
8
|
import { createRecoveryConfig, gatewayToken, loadRecoveryConfig } from '../src/runtime/standalone-recovery/core.ts';
|
|
9
9
|
|
|
10
10
|
export const PLUGIN_ID = 'local_recovery';
|
|
11
11
|
export const PLUGIN_VERSION = '0.1.0';
|
|
12
12
|
export const PROTOCOL_VERSION = 1;
|
|
13
13
|
export const CAPABILITIES = ['forge.local_recovery.transport.v1'];
|
|
14
|
-
export const ACTIONS = [
|
|
15
|
-
|
|
14
|
+
export const ACTIONS = [
|
|
15
|
+
'runtime_status',
|
|
16
|
+
'list_releases',
|
|
17
|
+
'verify_stable_runtime',
|
|
18
|
+
'stage_and_activate_runtime_release',
|
|
19
|
+
'release_session_status',
|
|
20
|
+
'advance_runtime_release_session',
|
|
21
|
+
'verify_runtime_release_session_static',
|
|
22
|
+
'verify_runtime_release_session_candidate',
|
|
23
|
+
'cutover_runtime_release_session',
|
|
24
|
+
'cancel_runtime_release_session',
|
|
25
|
+
'rollback_runtime_release_session',
|
|
26
|
+
'promote_runtime_release_session_known_good',
|
|
27
|
+
];
|
|
28
|
+
const RELEASE_SESSION_ACTIONS = new Set([
|
|
29
|
+
'release_session_status',
|
|
30
|
+
'verify_runtime_release_session_static',
|
|
31
|
+
'verify_runtime_release_session_candidate',
|
|
32
|
+
'cutover_runtime_release_session',
|
|
33
|
+
'cancel_runtime_release_session',
|
|
34
|
+
'rollback_runtime_release_session',
|
|
35
|
+
'promote_runtime_release_session_known_good',
|
|
36
|
+
]);
|
|
37
|
+
const MUTATING_ACTIONS = new Set([
|
|
38
|
+
'stage_and_activate_runtime_release',
|
|
39
|
+
'advance_runtime_release_session',
|
|
40
|
+
'verify_runtime_release_session_static',
|
|
41
|
+
'verify_runtime_release_session_candidate',
|
|
42
|
+
'cutover_runtime_release_session',
|
|
43
|
+
'cancel_runtime_release_session',
|
|
44
|
+
'rollback_runtime_release_session',
|
|
45
|
+
'promote_runtime_release_session_known_good',
|
|
46
|
+
]);
|
|
16
47
|
const LOOPBACK_HOSTS = new Set(['127.0.0.1', 'localhost', '::1']);
|
|
17
48
|
|
|
18
49
|
function providerError(code, message, retryable = false, details) {
|
|
@@ -91,8 +122,7 @@ export async function callRecoveryTool(controllerHome, toolName, args = {}, inje
|
|
|
91
122
|
protocolVersion: '2025-06-18', capabilities: {}, clientInfo: { name: 'forge-local-recovery-provider', version: PLUGIN_VERSION },
|
|
92
123
|
},
|
|
93
124
|
});
|
|
94
|
-
const sessionId = initialized.response.headers.get('mcp-session-id');
|
|
95
|
-
if (!sessionId) throw providerError('LOCAL_RECOVERY_MCP_SESSION_MISSING', 'Recovery MCP initialize did not return a session id.');
|
|
125
|
+
const sessionId = initialized.response.headers.get('mcp-session-id') || undefined;
|
|
96
126
|
try {
|
|
97
127
|
await postRpc(fetchImpl, endpoint, token, { jsonrpc: '2.0', method: 'notifications/initialized' }, sessionId);
|
|
98
128
|
const called = await postRpc(fetchImpl, endpoint, token, {
|
|
@@ -101,15 +131,21 @@ export async function callRecoveryTool(controllerHome, toolName, args = {}, inje
|
|
|
101
131
|
if (called.payload?.error) throw providerError('LOCAL_RECOVERY_TOOL_FAILED', String(called.payload.error?.message ?? 'Recovery tool failed.'), false);
|
|
102
132
|
const content = called.payload?.result?.content;
|
|
103
133
|
const text = Array.isArray(content) ? content.find((entry) => entry?.type === 'text' && typeof entry.text === 'string')?.text : undefined;
|
|
134
|
+
if (called.payload?.result?.isError === true) {
|
|
135
|
+
const message = typeof text === 'string' && text.trim() ? text.trim().slice(0, 4000) : 'Recovery tool failed.';
|
|
136
|
+
throw providerError('LOCAL_RECOVERY_TOOL_FAILED', message, false);
|
|
137
|
+
}
|
|
104
138
|
if (text) return parseJson(text, 'LOCAL_RECOVERY_TOOL_RESULT_INVALID');
|
|
105
139
|
return called.payload?.result ?? {};
|
|
106
140
|
} finally {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
141
|
+
if (sessionId) {
|
|
142
|
+
try {
|
|
143
|
+
await fetchImpl(endpoint, {
|
|
144
|
+
method: 'DELETE',
|
|
145
|
+
headers: { authorization: `Bearer ${token}`, accept: 'application/json, text/event-stream', 'mcp-session-id': sessionId },
|
|
146
|
+
});
|
|
147
|
+
} catch { /* Session cleanup is best effort; ReleaseSession durability is independent from this transport session. */ }
|
|
148
|
+
}
|
|
113
149
|
}
|
|
114
150
|
}
|
|
115
151
|
|
|
@@ -119,6 +155,17 @@ function assertEmptyInput(input) {
|
|
|
119
155
|
}
|
|
120
156
|
}
|
|
121
157
|
|
|
158
|
+
function releaseSessionInput(input) {
|
|
159
|
+
if (!input || typeof input !== 'object' || Array.isArray(input) || Object.keys(input).length !== 1 || typeof input.session_id !== 'string') {
|
|
160
|
+
throw providerError('LOCAL_RECOVERY_RELEASE_SESSION_ARGUMENTS_INVALID', 'ReleaseSession actions accept only session_id.');
|
|
161
|
+
}
|
|
162
|
+
const sessionId = input.session_id.trim();
|
|
163
|
+
if (sessionId.length < 8 || sessionId.length > 120) {
|
|
164
|
+
throw providerError('LOCAL_RECOVERY_RELEASE_SESSION_ID_INVALID', 'ReleaseSession session_id must be 8 to 120 characters.');
|
|
165
|
+
}
|
|
166
|
+
return { session_id: sessionId };
|
|
167
|
+
}
|
|
168
|
+
|
|
122
169
|
function mutationRequestId(requestId) {
|
|
123
170
|
return `local-recovery:${createHash('sha256').update(String(requestId)).digest('hex').slice(0, 32)}`;
|
|
124
171
|
}
|
|
@@ -127,9 +174,36 @@ export function ensureSourceRepositoryProvenance(controllerHome, injected = {})
|
|
|
127
174
|
const loadConfig = injected.loadRecoveryConfig ?? loadRecoveryConfig;
|
|
128
175
|
const persistConfig = injected.createRecoveryConfig ?? createRecoveryConfig;
|
|
129
176
|
const findRepository = injected.findRegisteredRepositoryByCheckoutRoot ?? findRegisteredRepositoryByCheckoutRoot;
|
|
177
|
+
const readRepository = injected.getRepository ?? getRepository;
|
|
130
178
|
const recoveryConfig = loadConfig(controllerHome);
|
|
131
|
-
|
|
179
|
+
const repositoryId = typeof recoveryConfig.primaryRuntimeSourceRepositoryId === 'string'
|
|
180
|
+
? recoveryConfig.primaryRuntimeSourceRepositoryId.trim()
|
|
181
|
+
: '';
|
|
132
182
|
const sourceRoot = typeof recoveryConfig.primaryRuntimeSourceRoot === 'string' ? recoveryConfig.primaryRuntimeSourceRoot.trim() : '';
|
|
183
|
+
|
|
184
|
+
if (repositoryId) {
|
|
185
|
+
let repository;
|
|
186
|
+
try {
|
|
187
|
+
repository = readRepository(repositoryId, controllerHome);
|
|
188
|
+
} catch {
|
|
189
|
+
throw providerError('LOCAL_RECOVERY_SOURCE_REPOSITORY_UNRESOLVED', 'Configured primary Runtime source repository id is not one enabled registered repository.');
|
|
190
|
+
}
|
|
191
|
+
if (!repository || repository.repoId !== repositoryId || repository.enabled === false || repository.removedAt) {
|
|
192
|
+
throw providerError('LOCAL_RECOVERY_SOURCE_REPOSITORY_UNRESOLVED', 'Configured primary Runtime source repository id is not one enabled registered repository.');
|
|
193
|
+
}
|
|
194
|
+
const canonicalRoot = typeof repository.canonicalRoot === 'string' && repository.canonicalRoot.trim()
|
|
195
|
+
? resolve(repository.canonicalRoot.trim())
|
|
196
|
+
: '';
|
|
197
|
+
if (!canonicalRoot || !isAbsolute(canonicalRoot) || !existsSync(canonicalRoot)) {
|
|
198
|
+
throw providerError('LOCAL_RECOVERY_SOURCE_CANONICAL_ROOT_UNAVAILABLE', 'Configured primary Runtime source repository canonical root is unavailable.');
|
|
199
|
+
}
|
|
200
|
+
if (sourceRoot && resolve(sourceRoot) === canonicalRoot) return recoveryConfig;
|
|
201
|
+
return persistConfig(controllerHome, {
|
|
202
|
+
primaryRuntimeSourceRoot: canonicalRoot,
|
|
203
|
+
primaryRuntimeSourceRepositoryId: repositoryId,
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
|
|
133
207
|
if (!sourceRoot) throw providerError('LOCAL_RECOVERY_SOURCE_ROOT_UNAVAILABLE', 'Installed Recovery config does not identify the primary Runtime source root.');
|
|
134
208
|
const repository = findRepository(sourceRoot, controllerHome);
|
|
135
209
|
if (!repository?.repoId) throw providerError('LOCAL_RECOVERY_SOURCE_REPOSITORY_UNRESOLVED', 'Configured primary Runtime source root is not owned by one registered repository.');
|
|
@@ -142,10 +216,14 @@ export function ensureSourceRepositoryProvenance(controllerHome, injected = {})
|
|
|
142
216
|
export async function executeAction(actionId, input, providerConfig, injected = {}) {
|
|
143
217
|
const config = validateProviderConfig(providerConfig);
|
|
144
218
|
if (!ACTIONS.includes(actionId)) throw providerError('LOCAL_RECOVERY_ACTION_UNSUPPORTED', 'Unsupported Local Recovery action.');
|
|
145
|
-
|
|
219
|
+
const sessionArgs = RELEASE_SESSION_ACTIONS.has(actionId) ? releaseSessionInput(input) : undefined;
|
|
220
|
+
if (!sessionArgs) assertEmptyInput(input);
|
|
146
221
|
const callTool = injected.callRecoveryTool ?? callRecoveryTool;
|
|
147
|
-
if (actionId === 'stage_and_activate_runtime_release') ensureSourceRepositoryProvenance(config.controllerHome, injected);
|
|
148
|
-
const args =
|
|
222
|
+
if (actionId === 'stage_and_activate_runtime_release' || actionId === 'advance_runtime_release_session') ensureSourceRepositoryProvenance(config.controllerHome, injected);
|
|
223
|
+
const args = {
|
|
224
|
+
...(sessionArgs ?? {}),
|
|
225
|
+
...(MUTATING_ACTIONS.has(actionId) ? { request_id: mutationRequestId(injected.requestId ?? actionId) } : {}),
|
|
226
|
+
};
|
|
149
227
|
return await callTool(config.controllerHome, actionId, args, injected);
|
|
150
228
|
}
|
|
151
229
|
|
|
@@ -1825,6 +1825,9 @@ This is the root routing contract for Claude Code and Codex.
|
|
|
1825
1825
|
- Keep root context concise; route durable human-authored detail into product, architecture, research, or intentional project documents.
|
|
1826
1826
|
- Treat `_ref/` as ignored external reference material and `_ops/` as ignored local operations residue.
|
|
1827
1827
|
- Use Controller Home for mutable workflow state instead of recreating repo-local task/workstream/session projections.
|
|
1828
|
+
- For architecture migrations, use one bounded Delivery Transaction: batch discovery -> architecture/root-cause decision -> freeze scope -> coherent implementation -> whole-diff review -> focused validation wave -> canonical gates -> one delivery/cleanup.
|
|
1829
|
+
- Do not create sibling Work, per-file commits, repeated broad validation, or release/canary cycles for same-root-cause discoveries while the current candidate is still moving.
|
|
1830
|
+
- Treat release as a source-complete candidate boundary. Defer workflow/lifecycle machinery improvements to a post-release Plan when they are not required to converge the current version safely.
|
|
1828
1831
|
EOF_ROOT_CONTEXT
|
|
1829
1832
|
}
|
|
1830
1833
|
|
|
@@ -45,8 +45,6 @@ tests/runtime/target-architecture.test.ts
|
|
|
45
45
|
# and installation locations to prove discovery and identity fencing.
|
|
46
46
|
scripts/portability-bindings.mjs
|
|
47
47
|
tests/runtime/browser-product-discovery.test.ts
|
|
48
|
-
tests/runtime/chatgpt-work-continuation.test.ts
|
|
49
|
-
tests/runtime/frozen-tool-contract-abi.test.ts
|
|
50
48
|
tests/runtime/windows-host-discovery.test.ts
|
|
51
49
|
tests/runtime/standalone-recovery.test.ts
|
|
52
50
|
# Secret-marker rejection tests use non-secret synthetic values by design.
|
|
@@ -55,3 +53,4 @@ tests/runtime/context-plane.test.ts
|
|
|
55
53
|
# Supervisor service unit tests use synthetic homeDir placeholders for PATH assembly.
|
|
56
54
|
# Local monitor bridge defaults may reference a development repository id.
|
|
57
55
|
scripts/run-mobile-monitor-bridge.ts
|
|
56
|
+
tests/runtime/browser-session-authority.test.ts # Intentional placeholder user profile used to prove foreign Chrome profiles are never reclaimed.
|
|
@@ -49,6 +49,11 @@ if (!Number.isInteger(timeoutMs) || timeoutMs < 1 || commandArgs.length === 0) {
|
|
|
49
49
|
});
|
|
50
50
|
child.once('close', (code) => {
|
|
51
51
|
clearTimeout(timeout);
|
|
52
|
+
// The direct child can exit on SIGTERM while a stubborn descendant remains
|
|
53
|
+
// alive in its detached process group. Before dropping the escalation timer,
|
|
54
|
+
// synchronously send SIGKILL to that process group once more so timeout
|
|
55
|
+
// completion cannot orphan compiler/test descendants.
|
|
56
|
+
if (timedOut && process.platform !== 'win32') stop('SIGKILL');
|
|
52
57
|
if (escalation) clearTimeout(escalation);
|
|
53
58
|
process.exitCode = launchFailed ? 1 : (timedOut ? 124 : code ?? 1);
|
|
54
59
|
});
|
|
@@ -22,7 +22,6 @@ export function stepsFor(gate: Gate): Step[] {
|
|
|
22
22
|
{ label: 'repository hygiene', command: 'node', args: ['scripts/check-repository-hygiene.mjs'], timeoutMs: 2 * 60_000 },
|
|
23
23
|
{ label: 'generated authority', command: 'node', args: ['scripts/sync-generated-authority.mjs', '--check'], timeoutMs: 2 * 60_000 },
|
|
24
24
|
{ label: 'source duplication', command: 'node', args: ['scripts/check-source-duplication.mjs'], timeoutMs: 2 * 60_000 },
|
|
25
|
-
{ label: 'controller UI bundle', command: 'bun', args: ['run', 'check:controller-ui'], timeoutMs: 5 * 60_000 },
|
|
26
25
|
{ label: 'test manifest', command: 'bun', args: ['run', 'check:test-governance'], timeoutMs: 5 * 60_000 },
|
|
27
26
|
{ label: 'affected tests', command: 'bun', args: ['run', 'test'], timeoutMs: 30 * 60_000 },
|
|
28
27
|
];
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { strict as assert } from 'node:assert';
|
|
2
|
+
import { mkdtempSync, rmSync } from 'node:fs';
|
|
3
|
+
import { tmpdir } from 'node:os';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import {
|
|
6
|
+
FORGE_RECOVERY_DAEMON_LABEL,
|
|
7
|
+
FORGE_RECOVERY_GATEWAY_LABEL,
|
|
8
|
+
forgeConnectorPersistentServiceLabel,
|
|
9
|
+
forgeRuntimePersistentServiceLabel,
|
|
10
|
+
} from '../src/runtime/platform/service-inventory';
|
|
11
|
+
import {
|
|
12
|
+
classifyRecoveryMcpRequest,
|
|
13
|
+
recoveryRuntimeRoleFromExecutable,
|
|
14
|
+
} from '../src/runtime/standalone-recovery/entry';
|
|
15
|
+
import { recentMcpTransportEvidence } from '../adapters/mcp/transports/http-observation';
|
|
16
|
+
import { recordMcpTransportEvent, readRecentMcpTransportEvents } from '../src/runtime/diagnostics/mcp-timing';
|
|
17
|
+
|
|
18
|
+
const controllerHome = mkdtempSync(join(tmpdir(), 'forge-control-plane-failure-domain-'));
|
|
19
|
+
try {
|
|
20
|
+
// Main Runtime/MCP and Recovery must have distinct service identities. A
|
|
21
|
+
// restart or crash fence for one must not name the other lifecycle owner.
|
|
22
|
+
const runtimeLabel = forgeRuntimePersistentServiceLabel(controllerHome);
|
|
23
|
+
const connectorLabel = forgeConnectorPersistentServiceLabel(controllerHome);
|
|
24
|
+
assert.notEqual(runtimeLabel, FORGE_RECOVERY_DAEMON_LABEL);
|
|
25
|
+
assert.notEqual(runtimeLabel, FORGE_RECOVERY_GATEWAY_LABEL);
|
|
26
|
+
assert.notEqual(connectorLabel, FORGE_RECOVERY_DAEMON_LABEL);
|
|
27
|
+
assert.notEqual(connectorLabel, FORGE_RECOVERY_GATEWAY_LABEL);
|
|
28
|
+
assert.notEqual(FORGE_RECOVERY_DAEMON_LABEL, FORGE_RECOVERY_GATEWAY_LABEL);
|
|
29
|
+
assert.equal(recoveryRuntimeRoleFromExecutable('/tmp/forge-recovery-gateway'), 'gateway');
|
|
30
|
+
assert.equal(recoveryRuntimeRoleFromExecutable('/tmp/forge-recovery-watchdog'), 'watchdog');
|
|
31
|
+
|
|
32
|
+
// Recovery owns its own MCP route. Main MCP being unavailable must not turn a
|
|
33
|
+
// valid Recovery request into a route-level 404; authorization is evaluated
|
|
34
|
+
// by the Recovery gateway itself.
|
|
35
|
+
assert.equal(classifyRecoveryMcpRequest({
|
|
36
|
+
method: 'POST',
|
|
37
|
+
url: '/recovery/mcp',
|
|
38
|
+
headers: { authorization: 'Bearer recovery-token' },
|
|
39
|
+
} as any, 'recovery-token'), 'mcp');
|
|
40
|
+
assert.equal(classifyRecoveryMcpRequest({
|
|
41
|
+
method: 'POST',
|
|
42
|
+
url: '/recovery/mcp',
|
|
43
|
+
headers: {},
|
|
44
|
+
} as any, 'recovery-token'), 'auth_required');
|
|
45
|
+
assert.equal(classifyRecoveryMcpRequest({
|
|
46
|
+
method: 'POST',
|
|
47
|
+
url: '/main/mcp',
|
|
48
|
+
headers: { authorization: 'Bearer recovery-token' },
|
|
49
|
+
} as any, 'recovery-token'), 'not_mcp');
|
|
50
|
+
|
|
51
|
+
// Current health and recent incident evidence are separate dimensions. A
|
|
52
|
+
// successful reconnect does not erase the interruption that immediately
|
|
53
|
+
// preceded it, and a later health probe may still truthfully be green.
|
|
54
|
+
const interruptedAt = '2026-09-22T12:00:00.000Z';
|
|
55
|
+
const recoveredAt = '2026-09-22T12:00:05.000Z';
|
|
56
|
+
recordMcpTransportEvent(controllerHome, {
|
|
57
|
+
kind: 'interruption',
|
|
58
|
+
sessionId: 'mcp-before-outage',
|
|
59
|
+
connectionId: 'connection-before-outage',
|
|
60
|
+
route: '/mcp',
|
|
61
|
+
principalId: 'chatgpt-controller',
|
|
62
|
+
reason: 'transport_close',
|
|
63
|
+
at: interruptedAt,
|
|
64
|
+
});
|
|
65
|
+
recordMcpTransportEvent(controllerHome, {
|
|
66
|
+
kind: 'session_initialized',
|
|
67
|
+
sessionId: 'mcp-after-outage',
|
|
68
|
+
connectionId: 'connection-after-outage',
|
|
69
|
+
route: '/mcp',
|
|
70
|
+
principalId: 'chatgpt-controller',
|
|
71
|
+
at: recoveredAt,
|
|
72
|
+
});
|
|
73
|
+
const evidence = recentMcpTransportEvidence(
|
|
74
|
+
readRecentMcpTransportEvents(controllerHome),
|
|
75
|
+
'2026-09-22T11:00:00.000Z',
|
|
76
|
+
Date.parse('2026-09-22T12:01:00.000Z'),
|
|
77
|
+
);
|
|
78
|
+
assert.equal(evidence.current, 'healthy');
|
|
79
|
+
assert.equal(evidence.recentStatus, 'recovered');
|
|
80
|
+
assert.equal(evidence.lastInterruption?.at, interruptedAt);
|
|
81
|
+
assert.equal(evidence.lastRecoveryAt, recoveredAt);
|
|
82
|
+
|
|
83
|
+
console.log(JSON.stringify({
|
|
84
|
+
status: 'ok',
|
|
85
|
+
mainRuntimeLabel: runtimeLabel,
|
|
86
|
+
mainConnectorLabel: connectorLabel,
|
|
87
|
+
recoveryDaemonLabel: FORGE_RECOVERY_DAEMON_LABEL,
|
|
88
|
+
recoveryGatewayLabel: FORGE_RECOVERY_GATEWAY_LABEL,
|
|
89
|
+
recoveryRouteIndependent: true,
|
|
90
|
+
health: evidence,
|
|
91
|
+
}, null, 2));
|
|
92
|
+
} finally {
|
|
93
|
+
rmSync(controllerHome, { recursive: true, force: true });
|
|
94
|
+
}
|
|
@@ -148,6 +148,11 @@ try {
|
|
|
148
148
|
throw new Error(`GATEWAY_START_FAILED: ${error instanceof Error ? error.message : String(error)} ${stderr}`);
|
|
149
149
|
}
|
|
150
150
|
if (health.status !== 200 || health.body.status !== 'ok') throw new Error(`HEALTH_FAILED: ${JSON.stringify(health)} ${stderr}`);
|
|
151
|
+
const initialTransportEvidence = health.body.transportEvidence as Record<string, unknown> | undefined;
|
|
152
|
+
if (initialTransportEvidence?.current !== 'healthy') throw new Error(`TRANSPORT_CURRENT_HEALTH_MISSING: ${JSON.stringify(initialTransportEvidence)}`);
|
|
153
|
+
if (!['stable', 'recovering', 'recovered'].includes(String(initialTransportEvidence?.recentStatus))) {
|
|
154
|
+
throw new Error(`TRANSPORT_RECENT_STATUS_INVALID: ${JSON.stringify(initialTransportEvidence)}`);
|
|
155
|
+
}
|
|
151
156
|
const expectedPolicy = runtimePolicy(repoRoot, {
|
|
152
157
|
repo: repoRoot,
|
|
153
158
|
controllerHome,
|
|
@@ -9,11 +9,8 @@ import {
|
|
|
9
9
|
getWorkContract,
|
|
10
10
|
getWorkContractByRequestId,
|
|
11
11
|
recordWorkCompletionReceipt,
|
|
12
|
-
recordWorkImplementationReview,
|
|
13
|
-
requestWorkImplementationReview,
|
|
14
|
-
transitionWorkContractPhase,
|
|
15
12
|
} from '../src/runtime/control-plane/facade/work-contract-store';
|
|
16
|
-
import {
|
|
13
|
+
import { reviseWorkSemanticContext } from '../packages/kernel/work/api/index';
|
|
17
14
|
import {
|
|
18
15
|
claimControllerSession,
|
|
19
16
|
getControllerSession,
|
|
@@ -70,6 +67,7 @@ try {
|
|
|
70
67
|
semanticKey: operation.semanticKey,
|
|
71
68
|
operation,
|
|
72
69
|
objective: 'Verify WorkContract and Process Runtime recovery without ExecutionJobs',
|
|
70
|
+
workKind: 'completed_no_change' as const,
|
|
73
71
|
checks: [],
|
|
74
72
|
};
|
|
75
73
|
const accepted = acceptSubmittedWorkContract(controllerHome, request);
|
|
@@ -89,13 +87,6 @@ try {
|
|
|
89
87
|
sessionId: 'session-recovery-a',
|
|
90
88
|
leaseMs: 60_000,
|
|
91
89
|
});
|
|
92
|
-
// Recovery smoke follows the same Work-only phase API enforced in production.
|
|
93
|
-
transitionWorkContractPhase({ controllerHome, repoId: repository.repoId }, accepted.contract.workId, {
|
|
94
|
-
phase: 'implementation',
|
|
95
|
-
status: 'running',
|
|
96
|
-
state: 'active',
|
|
97
|
-
summary: 'Process Runtime recovery smoke started implementation.',
|
|
98
|
-
});
|
|
99
90
|
const handle = await spawnManagedProcess({
|
|
100
91
|
controllerHome,
|
|
101
92
|
repoId: repository.repoId,
|
|
@@ -135,42 +126,13 @@ try {
|
|
|
135
126
|
assert(getControllerSession({ controllerHome, repoId: repository.repoId }, accepted.contract.workId)?.sessionId === 'session-recovery-b', 'replacement Controller session missing');
|
|
136
127
|
const completionRecordedAt = new Date().toISOString();
|
|
137
128
|
const completionRevision = String(spawnSync('git', ['-C', repoRoot, 'rev-parse', 'HEAD'], { encoding: 'utf8' }).stdout).trim();
|
|
138
|
-
|
|
139
|
-
phase: 'verification',
|
|
140
|
-
status: 'running',
|
|
141
|
-
state: 'satisfied',
|
|
142
|
-
summary: 'Recovered Process completed successfully for the exact no-change candidate.',
|
|
143
|
-
});
|
|
144
|
-
requestWorkImplementationReview(
|
|
145
|
-
{ controllerHome, repoId: repository.repoId },
|
|
146
|
-
accepted.contract.workId,
|
|
147
|
-
'Recovery smoke verification completed; implementation review is required before completion.',
|
|
148
|
-
);
|
|
149
|
-
recordWorkImplementationReview({ controllerHome, repoId: repository.repoId }, accepted.contract.workId, {
|
|
150
|
-
schemaVersion: 1,
|
|
151
|
-
reviewId: `REV-smoke-${accepted.contract.workId}`,
|
|
152
|
-
workId: accepted.contract.workId,
|
|
153
|
-
reviewerPrincipalId: replacement.principalId ?? replacement.controllerId,
|
|
154
|
-
reviewerControllerSessionId: replacement.sessionId,
|
|
155
|
-
decision: 'approved',
|
|
156
|
-
rationale: 'Recovery smoke reviewed the exact recovered no-change candidate before terminal completion.',
|
|
157
|
-
findings: [],
|
|
158
|
-
sourceRevision: completionRevision,
|
|
159
|
-
workspaceFingerprint: 'runtime-recovery-smoke-no-change-content',
|
|
160
|
-
verificationWorkspaceFingerprint: 'runtime-recovery-smoke-no-change-verification',
|
|
161
|
-
changedPaths: [],
|
|
162
|
-
changedPathDigest: implementationReviewChangedPathDigest([]),
|
|
163
|
-
acceptanceCriteriaSummary: 'Managed Process recovery, Controller reclaim, and no-change Work completion remain coherent.',
|
|
164
|
-
verificationEvidence: [],
|
|
165
|
-
architectureEvidence: [],
|
|
166
|
-
recordedAt: completionRecordedAt,
|
|
167
|
-
});
|
|
129
|
+
const completionReceiptId = `REC-smoke-${accepted.contract.workId}`;
|
|
168
130
|
recordWorkCompletionReceipt(
|
|
169
131
|
{ controllerHome, repoId: repository.repoId },
|
|
170
132
|
accepted.contract.workId,
|
|
171
133
|
{
|
|
172
134
|
schemaVersion: 1,
|
|
173
|
-
receiptId:
|
|
135
|
+
receiptId: completionReceiptId,
|
|
174
136
|
source: 'direct_edit',
|
|
175
137
|
issueId: 'ISS-runtime-recovery-smoke',
|
|
176
138
|
taskId: 'T1',
|
|
@@ -186,7 +148,14 @@ try {
|
|
|
186
148
|
'completed_no_change',
|
|
187
149
|
'completed_no_change',
|
|
188
150
|
);
|
|
189
|
-
|
|
151
|
+
const delivered = getWorkContract({ controllerHome, repoId: repository.repoId }, accepted.contract.workId);
|
|
152
|
+
assert(delivered?.semanticState !== 'completed', 'delivery receipt must not implicitly complete semantic Work');
|
|
153
|
+
reviseWorkSemanticContext(
|
|
154
|
+
{ controllerHome, repoId: repository.repoId },
|
|
155
|
+
accepted.contract.workId,
|
|
156
|
+
{ expectedRevision: Number(delivered?.semanticRevision ?? 1), state: 'completed', resultRefs: [`receipt:${completionReceiptId}`] },
|
|
157
|
+
);
|
|
158
|
+
assert(getWorkContract({ controllerHome, repoId: repository.repoId }, accepted.contract.workId)?.semanticState === 'completed', 'explicit semantic Work completion was not persisted');
|
|
190
159
|
assert(listExecutionJobs(controllerHome, repository.repoId, 20).length === 0, 'runtime recovery created an ExecutionJob');
|
|
191
160
|
|
|
192
161
|
const scheduleInput = {
|
|
@@ -71,8 +71,8 @@ try {
|
|
|
71
71
|
manualOccurrence?.status === 'skipped'
|
|
72
72
|
&& manualOccurrence.decision === 'operation_blocked'
|
|
73
73
|
&& manualOccurrence.decisionId
|
|
74
|
-
&& manualOccurrence.handoffId,
|
|
75
|
-
'manual semantic Schedule
|
|
74
|
+
&& !manualOccurrence.handoffId,
|
|
75
|
+
'manual semantic Schedule manufactured a human blocker instead of recording a trigger',
|
|
76
76
|
);
|
|
77
77
|
assert(
|
|
78
78
|
getScheduleDecision(controllerHome, repository.repoId, manualOccurrence.decisionId)?.decision === 'operation_blocked',
|
|
@@ -105,7 +105,7 @@ try {
|
|
|
105
105
|
{ source: 'repository-event', eventName: 'git.push', eventId: 'evt-1' },
|
|
106
106
|
);
|
|
107
107
|
assert(eventA?.occurrenceId === eventB?.occurrenceId, 'repository event was not idempotent');
|
|
108
|
-
assert(eventA?.
|
|
108
|
+
assert(eventA?.decisionId === eventB?.decisionId, 'repository event created a duplicate occurrence decision');
|
|
109
109
|
|
|
110
110
|
const missingDependency = createSchedule(controllerHome, {
|
|
111
111
|
...semanticBase,
|
|
@@ -132,8 +132,8 @@ try {
|
|
|
132
132
|
assert(
|
|
133
133
|
conditionOccurrence?.status === 'skipped'
|
|
134
134
|
&& conditionOccurrence.decision === 'operation_blocked'
|
|
135
|
-
&& conditionOccurrence.handoffId,
|
|
136
|
-
'condition Schedule
|
|
135
|
+
&& !conditionOccurrence.handoffId,
|
|
136
|
+
'condition Schedule manufactured a human blocker instead of recording a trigger',
|
|
137
137
|
);
|
|
138
138
|
|
|
139
139
|
const cron = createSchedule(controllerHome, {
|
|
@@ -143,7 +143,7 @@ try {
|
|
|
143
143
|
trigger: { type: 'cron', cronExpression: '* * * * *' },
|
|
144
144
|
});
|
|
145
145
|
const cronOccurrence = await evaluateSchedule(controllerHome, cron);
|
|
146
|
-
assert(cronOccurrence?.decision === 'operation_blocked' && cronOccurrence.handoffId, 'cron Schedule did not
|
|
146
|
+
assert(cronOccurrence?.decision === 'operation_blocked' && !cronOccurrence.handoffId, 'cron Schedule did not record a bounded trigger');
|
|
147
147
|
|
|
148
148
|
const calendar = createSchedule(controllerHome, {
|
|
149
149
|
...semanticBase,
|
|
@@ -153,8 +153,8 @@ try {
|
|
|
153
153
|
});
|
|
154
154
|
const calendarOccurrence = await evaluateSchedule(controllerHome, calendar);
|
|
155
155
|
assert(
|
|
156
|
-
calendarOccurrence?.decision === 'operation_blocked' && calendarOccurrence.handoffId,
|
|
157
|
-
'calendar Schedule did not
|
|
156
|
+
calendarOccurrence?.decision === 'operation_blocked' && !calendarOccurrence.handoffId,
|
|
157
|
+
'calendar Schedule did not record a bounded trigger',
|
|
158
158
|
);
|
|
159
159
|
|
|
160
160
|
const staleJobPath = writeLocalJob('JOB-stale', {
|
|
@@ -231,9 +231,9 @@ try {
|
|
|
231
231
|
assert(
|
|
232
232
|
blockedOccurrence?.status === 'skipped'
|
|
233
233
|
&& blockedOccurrence.decision === 'maintenance_not_ready'
|
|
234
|
-
&& blockedOccurrence.handoffId
|
|
234
|
+
&& !blockedOccurrence.handoffId
|
|
235
235
|
&& !blockedOccurrence.jobId,
|
|
236
|
-
'
|
|
236
|
+
'retryable maintenance blocker was incorrectly promoted to a human handoff',
|
|
237
237
|
);
|
|
238
238
|
assert(readFileSync(brokenJobPath, 'utf8') === brokenBefore, 'blocked maintenance modified an unreadable candidate');
|
|
239
239
|
const backedOff = getSchedule(controllerHome, repository.repoId, blockedMaintenance.scheduleId);
|
|
@@ -243,17 +243,25 @@ try {
|
|
|
243
243
|
);
|
|
244
244
|
|
|
245
245
|
const handoffs = listHandoffItems({ controllerHome, repoId: repository.repoId, status: 'all' });
|
|
246
|
-
|
|
246
|
+
// Semantic Schedule triggers are continuation input, not human blockers. Only
|
|
247
|
+
// a real authorization/judgement boundary may persist a Handoff projection.
|
|
248
|
+
assert(
|
|
249
|
+
!manualOccurrence.handoffId && !conditionOccurrence.handoffId && !cronOccurrence.handoffId && !calendarOccurrence.handoffId,
|
|
250
|
+
'semantic Schedule triggers manufactured human blockers',
|
|
251
|
+
);
|
|
252
|
+
assert(
|
|
253
|
+
!blockedOccurrence.handoffId && handoffs.length === 0,
|
|
254
|
+
'retryable mechanical maintenance failure manufactured a human blocker',
|
|
255
|
+
);
|
|
247
256
|
assert(listExecutionJobs(controllerHome, repository.repoId, 100).length === 0, 'Schedule smoke created an ExecutionJob');
|
|
248
257
|
|
|
249
258
|
console.log(JSON.stringify({
|
|
250
259
|
status: 'ok',
|
|
251
|
-
|
|
260
|
+
manualTriggerRecorded: manualOccurrence.decisionId,
|
|
252
261
|
repositoryEventIdempotent: eventA?.occurrenceId === eventB?.occurrenceId,
|
|
253
262
|
missingDependencySuppressed: true,
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
calendarHandoff: calendarOccurrence.handoffId,
|
|
263
|
+
semanticScheduleHandoffs: 0,
|
|
264
|
+
maintenanceMechanicalBlockerHasHandoff: Boolean(blockedOccurrence.handoffId),
|
|
257
265
|
maintenance: maintenanceOccurrence.status,
|
|
258
266
|
maintenanceBackoffUntil: backedOff.nextEligibleAt,
|
|
259
267
|
handoffCount: handoffs.length,
|