@moretea-labs/forge 1.8.0 → 1.8.2
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 +73 -7
- package/CHANGELOG.md +34 -0
- package/CLAUDE.md +17 -2
- package/CONTRIBUTING.md +3 -2
- package/README.en.md +24 -3
- package/README.md +10 -6
- package/README.zh-CN.md +5 -3
- package/THIRD_PARTY_NOTICES.md +1 -2
- package/adapters/chatgpt/browser-delivery-host.ts +7 -1
- package/adapters/chatgpt/browser-delivery-runtime.ts +531 -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 +229 -2
- package/adapters/chatgpt/work-conversation-binding-store.ts +99 -54
- package/adapters/computer/chatgpt-extension-target.ts +708 -0
- package/adapters/computer/chrome-extension/background.js +541 -0
- package/adapters/computer/chrome-extension/content.js +402 -0
- package/adapters/computer/chrome-extension/core.js +24 -0
- package/adapters/computer/chrome-extension/manifest.json +32 -0
- package/adapters/computer/desktop-operator-discovery.ts +11 -31
- package/adapters/computer/desktop-operator-provider.ts +18 -6
- package/adapters/computer/interaction-target-authority.ts +178 -24
- package/adapters/mcp/access-mode.ts +18 -39
- package/adapters/mcp/auth.ts +2 -7
- package/adapters/mcp/instructions.ts +6 -5
- package/adapters/mcp/multi-repository.ts +10 -47
- package/adapters/mcp/oauth.ts +73 -0
- package/adapters/mcp/paths.ts +4 -1
- 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 +490 -113
- package/adapters/mcp/runtime-gateway/context-pack-sidecar.ts +83 -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 +14 -54
- package/adapters/mcp/runtime-gateway/gateway-execution-adapter.ts +2 -1
- package/adapters/mcp/runtime-gateway/plugin-adapter.ts +132 -47
- package/adapters/mcp/runtime-gateway/process-tools.ts +173 -23
- 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 +19 -507
- package/adapters/mcp/runtime-gateway/routing-policy.ts +506 -0
- package/adapters/mcp/runtime-gateway/runtime-observation-adapter.ts +15 -66
- package/adapters/mcp/runtime-gateway/runtime-readiness-observation.ts +218 -0
- package/adapters/mcp/runtime-gateway/runtime-tool-definitions.ts +123 -178
- package/adapters/mcp/runtime-gateway/runtime-tools.ts +11 -5
- package/adapters/mcp/runtime-gateway/scheduler-adapter.ts +37 -1
- package/adapters/mcp/runtime-gateway/shared-adapter.ts +20 -0
- package/adapters/mcp/runtime-gateway/status-inbox-adapter.ts +416 -270
- package/adapters/mcp/runtime-gateway/typescript-navigation-sidecar.ts +140 -0
- package/adapters/mcp/runtime-gateway/work-adapter.ts +262 -3123
- 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 +229 -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 +320 -0
- package/adapters/mcp/runtime-gateway/work-workflow-operations.ts +113 -0
- package/adapters/mcp/runtime-gateway/workflow-supervisor-adapter.ts +180 -0
- package/adapters/mcp/server.ts +91 -26
- package/adapters/mcp/setup.ts +5 -13
- package/adapters/mcp/tool-mapping/access-tools.ts +0 -6
- package/adapters/mcp/tool-mapping/legacy-tool-service.ts +703 -3092
- package/adapters/mcp/tool-mapping/post-finalize-work-attribution.ts +5 -10
- package/adapters/mcp/tool-mapping/repository-tools.ts +170 -213
- package/adapters/mcp/toolset-names.ts +11 -37
- package/adapters/mcp/toolset.ts +19 -92
- package/{src/cli → adapters}/mcp/transports/AGENTS.md +5 -5
- package/{src/cli → adapters}/mcp/transports/CLAUDE.md +5 -5
- package/adapters/mcp/transports/http-observation.ts +377 -0
- package/adapters/mcp/transports/http-post-lifecycle.ts +19 -0
- package/adapters/mcp/transports/http.ts +200 -683
- 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/adapters/mcp/types.ts +0 -6
- package/assets/hooks/lib/session-state.sh +0 -38
- package/assets/hooks/post-bash.sh +1 -1
- package/assets/hooks/post-tool-observer.sh +0 -5
- package/assets/hooks/prompt-guard.sh +0 -55
- package/assets/partials/04-project-structure.partial.md +1 -1
- package/assets/partials/07-footer.partial.md +1 -1
- package/assets/partials-agents/02-operating-mode.partial.md +1 -1
- package/assets/partials-agents/08-deep-docs.partial.md +1 -1
- package/assets/plugin-registry.v1.json +6 -4
- package/assets/reference-configs/agentic-development-flow.md +26 -1
- package/assets/reference-configs/external-tooling.md +0 -76
- package/assets/reference-configs/global-working-rules.md +19 -0
- package/assets/reference-configs/release-deploy.md +1 -1
- package/assets/templates/helpers/architecture-queue.sh +1 -1
- package/assets/templates/helpers/check-agent-tooling.sh +1 -327
- package/assets/templates/helpers/check-task-workflow.sh +1 -1
- package/assets/templates/helpers/ensure-task-workflow.sh +0 -14
- package/assets/templates/helpers/migrate-project-template.sh +2 -2
- package/assets/workflow-contract.v1.json +0 -2
- package/docs/README.md +5 -2
- package/docs/architecture/CURRENT.md +205 -51
- 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/20260904-ios-device-migration-baseline.md +42 -0
- 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 +234 -0
- package/docs/architecture/decisions/20260919-autonomous-work-liveness.md +62 -0
- package/docs/architecture/decisions/20260924-thin-semantic-working-context.md +74 -0
- package/docs/architecture/decisions/20261001-supervisor-turn-authority.md +342 -0
- package/docs/architecture/decisions/20261005-forge-v3-desktop-client-boundary.md +77 -0
- package/docs/architecture/decisions/20261009-exact-code-context-discovery.md +19 -0
- package/docs/architecture/decisions/20261009-generated-xcode-cache-retention.md +37 -0
- package/docs/architecture/decisions/20261011-autonomous-continuation-convergence.md +597 -0
- package/docs/architecture/decisions/20261017-edit-session-finalization-reconciliation.md +17 -0
- package/docs/architecture/decisions/20261019-retire-host-skills.md +16 -0
- package/docs/architecture/diagrams/agentic-dev-plugin-architecture.html +1 -1
- package/docs/architecture/domains/public-surface.md +3 -5
- package/docs/architecture/domains/verification.md +6 -5
- package/docs/architecture/domains/workflow-engine.md +6 -0
- package/docs/architecture/modules/controller-runtime/transport-lifecycle.md +3 -3
- package/docs/architecture/requests/2026-09-04-computer-plugin-workflow-taxonomy.md +4 -4
- package/docs/architecture/reviews/20261015-code-search-runtime-acceptance.md +75 -0
- package/docs/forge-plugin-management.md +16 -4
- package/docs/operations/controller-browser-plugin.md +23 -0
- package/docs/operations/controller-performance-and-502.md +17 -0
- package/docs/operations/controller-reliability-runbook.md +2 -2
- package/docs/operations/features.md +6 -7
- package/docs/operations/features.zh-CN.md +1 -1
- package/docs/operations/github-repository.md +4 -4
- package/docs/operations/github-semantic-release-projection.md +20 -0
- package/docs/operations/homebrew.md +2 -2
- package/docs/operations/mcp-tool-exposure.md +13 -52
- package/docs/operations/releasing.md +2 -0
- package/docs/operations/runtime-performance-diagnostics.md +8 -0
- package/docs/operations/standalone-disaster-recovery.md +15 -7
- package/docs/tutorials/01-install-and-start.zh-CN.md +1 -1
- package/docs/tutorials/03-first-repository-task.md +2 -0
- package/docs/wiki/Computer-and-Plugins.md +78 -0
- package/docs/wiki/Computer-and-Plugins.zh-CN.md +88 -0
- package/docs/wiki/Home.md +16 -2
- package/docs/wiki/Implementation.md +25 -13
- package/docs/wiki/Installation.md +28 -32
- package/docs/wiki/Integrations.md +4 -0
- package/docs/wiki/Quick-Start.md +35 -22
- package/docs/wiki/Releases-and-Upgrades.md +15 -25
- package/docs/wiki/_Sidebar.md +5 -1
- package/package.json +25 -25
- 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 +348 -97
- 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 +87 -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/eligibility.ts +4 -1
- 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 +166 -143
- package/packages/kernel/work/api/index.ts +3 -2
- package/packages/kernel/work/application/work-service.ts +18 -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 +34 -65
- package/packages/kernel/work/domain/types.ts +57 -51
- package/packages/kernel/work/infrastructure/work-contract-store.ts +847 -729
- package/packages/kernel/work/ports/work-contract-store.ts +5 -2
- package/packages/plugin-runtime/browser/provider-registry.ts +12 -36
- 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 +153 -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/assemble-template.ts +11 -72
- package/scripts/canary-controller-semantic-wait.ts +12 -24
- package/scripts/check-mcp-compatibility.ts +94 -201
- package/scripts/check-package-identity.mjs +0 -5
- package/scripts/check-runtime-architecture.mjs +921 -239
- package/scripts/forge-local-recovery-helper.mjs +93 -15
- package/scripts/init-project.sh +0 -46
- package/scripts/install-ios-hid-toolchain.sh +60 -0
- package/scripts/install-standalone-recovery.ts +1 -1
- package/scripts/lib/project-init-lib.sh +6 -3
- package/scripts/migrate-windows-wsl-controller-home.ts +2 -0
- package/scripts/open-source-audit-allowlist.txt +1 -3
- package/scripts/run-bounded-command.mjs +5 -0
- package/scripts/run-governed-gate.ts +2 -1
- package/scripts/run-mobile-monitor-bridge.ts +0 -1
- package/scripts/smoke-control-plane-failure-domain.ts +94 -0
- package/scripts/smoke-ios-physical-device.ts +38 -10
- package/scripts/smoke-mcp-http-runtime.ts +12 -8
- package/scripts/smoke-mcp-tool-surface.ts +27 -41
- 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 +95 -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/sync-generated-authority.mjs +0 -1
- package/scripts/verify-forge-runtime.sh +2 -1
- package/src/cli/agent-jobs/executor-health.ts +12 -35
- package/src/cli/agent-jobs/integration.ts +20 -51
- package/src/cli/agent-jobs/job-manager.ts +7 -3
- package/src/cli/chatgpt-browser/file-policy.ts +2 -2
- 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/doctor.ts +1 -143
- package/src/cli/commands/global-runtime.ts +3 -196
- package/src/cli/commands/init-hook.ts +6 -23
- package/src/cli/commands/init.ts +3 -252
- package/src/cli/commands/mcp.ts +0 -5
- package/src/cli/commands/prompt-guard-decision.ts +0 -2
- package/src/cli/commands/recovery.ts +137 -135
- package/src/cli/commands/repository.ts +17 -1
- package/src/cli/commands/runtime.ts +3 -3
- package/src/cli/commands/setup-execution.ts +41 -0
- 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 +5 -44
- package/src/cli/controller/completion-target.ts +3 -72
- package/src/cli/controller/composite-operations.ts +1 -1
- package/src/cli/controller/context/instruction-context.ts +1 -1
- package/src/cli/controller/context/known-paths.ts +2 -2
- package/src/cli/controller/context/query-planning.ts +11 -4
- package/src/cli/controller/context/rule-resolution.ts +2 -2
- package/src/cli/controller/context/source-materializer.ts +83 -102
- package/src/cli/controller/context/structural-provider.ts +84 -0
- package/src/cli/controller/context/structural.ts +6 -6
- package/src/cli/controller/context/types.ts +8 -9
- package/src/cli/controller/context-pack.ts +107 -84
- 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 +25 -52
- 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 +42 -10
- package/src/cli/editing/edit-session.ts +18 -12
- package/src/cli/github/github.ts +4 -4
- package/src/cli/github/semantic-projection.ts +174 -0
- package/src/cli/hook/prompt-intents.ts +0 -9
- package/src/cli/index.ts +1 -43
- package/src/cli/local-bridge/connector-freshness.ts +1 -12
- package/src/cli/local-bridge/console-automations.ts +19 -14
- package/src/cli/local-bridge/console-view-models.ts +4 -13
- package/src/cli/local-bridge/facade-api.ts +64 -193
- 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-classifier.ts +0 -9
- package/src/cli/repositories/command-executor.ts +29 -23
- package/src/cli/repositories/command-scope.ts +37 -18
- 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/locks.ts +20 -0
- package/src/cli/repositories/registry.ts +79 -12
- package/src/cli/repositories/safe-patch.ts +2 -12
- package/src/cli/repositories/structured-git.ts +101 -5
- package/src/cli/repository/inspector.ts +185 -343
- package/src/cli/repository/session-cache.ts +92 -6
- package/src/effects/process-runner.ts +17 -1
- 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/generic-lsp-provider.ts +1 -1
- package/src/runtime/context/semantic-navigation-contract.ts +16 -0
- package/src/runtime/context/semantic-navigation.ts +7 -35
- 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 +215 -12
- 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 +616 -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 +197 -110
- package/src/runtime/control-plane/execution/work-handle-store.ts +72 -44
- 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 +60 -34
- package/src/runtime/control-plane/execution/work-preparation-service.ts +231 -267
- package/src/runtime/control-plane/execution/work-process-evidence.ts +2 -2
- 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 +201 -199
- package/src/runtime/control-plane/execution/work-validation-reconciler.ts +33 -85
- package/src/runtime/control-plane/execution/work-verification-service.ts +406 -50
- package/src/runtime/control-plane/execution/work-verification-snapshot.ts +6 -2
- package/src/runtime/control-plane/facade/capability-registry.ts +364 -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 +9 -9
- package/src/runtime/control-plane/generated-cache-retention.ts +206 -59
- 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 +256 -117
- package/src/runtime/control-plane/global-scheduler/reconciliation.ts +3 -12
- 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/governance/external-effects.ts +1 -1
- package/src/runtime/control-plane/launcher/chatgpt-round-continuation.ts +63 -300
- package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +29 -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 +295 -107
- 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/evidence/sensitive-output.ts +22 -2
- package/src/runtime/execution/jobs/child-reference.ts +11 -0
- package/src/runtime/execution/jobs/receipt-recovery.ts +1 -11
- 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 +82 -30
- 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 +55 -18
- package/src/runtime/execution/process-runtime/store.ts +30 -2
- package/src/runtime/execution/process-runtime/types.ts +6 -1
- package/src/runtime/execution/thin-harness/execution-router.ts +16 -16
- package/src/runtime/execution/thin-harness/fast-executor.ts +2 -2
- package/src/runtime/execution/thin-harness/search-worker.ts +2 -2
- package/src/runtime/execution/workers/executor.ts +3 -8
- package/src/runtime/maintenance/cleanup.ts +41 -5
- 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 +97 -29
- package/src/runtime/plugins/app-store-connect-adapter.ts +290 -18
- package/src/runtime/plugins/browser-adapter.ts +1124 -333
- package/src/runtime/plugins/browser-automation-service.ts +23 -3
- package/src/runtime/plugins/browser-macos-bridge.ts +431 -137
- package/src/runtime/plugins/browser-manifest-surface.ts +47 -12
- package/src/runtime/plugins/browser-native-session-service.ts +63 -13
- package/src/runtime/plugins/browser-registration.ts +18 -0
- package/src/runtime/plugins/browser-runtime.ts +40 -36
- 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 +228 -0
- package/src/runtime/plugins/computer-registration.ts +298 -20
- 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/github-adapter.ts +30 -3
- package/src/runtime/plugins/gmail-adapter.ts +189 -3
- package/src/runtime/plugins/google-calendar-adapter.ts +2 -2
- package/src/runtime/plugins/google-shared.ts +24 -12
- package/src/runtime/plugins/google-tasks-adapter.ts +2 -2
- package/src/runtime/plugins/ios/remote-xpc-hid.ts +70 -30
- package/src/runtime/plugins/ios-adapter.ts +46 -41
- package/src/runtime/plugins/ios-agent-device.ts +54 -4
- package/src/runtime/plugins/ios-device-ownership.ts +103 -0
- package/src/runtime/plugins/ios-physical-device.ts +497 -79
- package/src/runtime/plugins/lightweight-action.ts +208 -2
- package/src/runtime/plugins/local-system-adapter.ts +12 -100
- 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 +682 -435
- package/src/runtime/plugins/types.ts +24 -0
- package/src/runtime/plugins/xiaohongshu-publish.ts +16 -0
- package/src/runtime/projections/git-status-sampler.ts +2 -19
- package/src/runtime/projections/invalidation.ts +7 -3
- package/src/runtime/projections/materialized-view.ts +80 -36
- package/src/runtime/recovery/actions.ts +4 -4
- package/src/runtime/recovery/capability-action-application.ts +46 -45
- package/src/runtime/recovery/lifecycle-inventory.ts +30 -40
- package/src/runtime/recovery/maintenance-executor.ts +374 -123
- package/src/runtime/recovery/probe.ts +2 -2
- package/src/runtime/recovery/store.ts +29 -11
- package/src/runtime/release/release-coordinator.ts +312 -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 +254 -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 +227 -29
- package/src/runtime/root/package-runtime-release.ts +117 -30
- package/src/runtime/root/package-runtime-service.ts +24 -24
- package/src/runtime/root/release-execution-canary.ts +57 -12
- package/src/runtime/root/release-loader.ts +90 -8
- package/src/runtime/root/release-manifest.ts +80 -40
- package/src/runtime/root/release-materialize.ts +372 -106
- package/src/runtime/root/release-store.ts +395 -36
- package/src/runtime/root/runtime-lane.ts +191 -0
- package/src/runtime/root/runtime.ts +160 -29
- package/src/runtime/root/scheduled-controller-composition.ts +29 -3
- package/src/runtime/root/service-runner.ts +2 -2
- package/src/runtime/root/service.ts +126 -44
- package/src/runtime/root/status.ts +48 -0
- package/src/runtime/root/types.ts +32 -9
- package/src/runtime/root/workflow-supervisor-composition.ts +681 -0
- package/src/runtime/root/workflow-supervisor-runtime.ts +564 -0
- package/src/runtime/root/write-fence.ts +50 -2
- package/src/runtime/safe-tooling/google-credential-store.ts +67 -22
- package/src/runtime/safe-tooling/google-oauth-broker.ts +25 -7
- package/src/runtime/safe-tooling/ios-development.ts +22 -8
- package/src/runtime/safe-tooling/job-summary.ts +1 -1
- package/src/runtime/safe-tooling/workspace-auth.ts +5 -2
- package/src/runtime/shared/atomic-text-file.ts +21 -0
- package/src/runtime/shared/bounded-child-supervisor.ts +9 -1
- package/src/runtime/shared/json-files.ts +8 -3
- 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 +3792 -417
- package/src/runtime/standalone-recovery/entry.ts +507 -45
- 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 +12 -2
- 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 +11 -3
- package/src/runtime/workflow/schedules/engine.ts +166 -178
- package/src/runtime/workflow/schedules/pending-activation.ts +11 -4
- package/src/runtime/workflow/schedules/work-continuation.ts +95 -11
- 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 +218 -0
- package/supervisor/control-plane.ts +963 -0
- package/supervisor/entry.ts +15 -0
- package/supervisor/forge-validators.ts +147 -0
- package/supervisor/index.ts +5 -0
- package/supervisor/native-browser-adapter.ts +1151 -0
- package/supervisor/native-messaging/host.ts +58 -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 +250 -0
- package/supervisor/server.ts +412 -0
- package/supervisor/store.ts +1870 -0
- package/supervisor/tsconfig.json +8 -0
- package/supervisor/types.ts +261 -0
- package/SKILL.md +0 -427
- 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/adapters/mcp/runtime-gateway/work-validation-reconciler.ts +0 -1
- package/adapters/mcp/toolset-selection.ts +0 -41
- package/agents/openai.yaml +0 -4
- package/assets/skill-hooks.json +0 -41
- package/assets/skill-version.json +0 -189
- package/assets/skills/claude-review/SKILL.md +0 -231
- package/assets/skills/codex-review/SKILL.md +0 -103
- package/assets/templates/helpers/check-skill-version.ts +0 -193
- 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-skill-version.ts +0 -5
- package/scripts/check-tarball-install-smoke.sh +0 -150
- package/scripts/ensure-codegraph.sh +0 -16
- 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/run-skill-hook.ts +0 -244
- package/scripts/stage-runtime-release.ts +0 -44
- package/scripts/sync-codex-installed-copies.sh +0 -182
- package/src/cli/commands/tools.ts +0 -167
- 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/cli/mcp/access-mode.ts +0 -2
- package/src/cli/mcp/access-tools.ts +0 -2
- package/src/cli/mcp/audit.ts +0 -2
- package/src/cli/mcp/auth.ts +0 -2
- package/src/cli/mcp/instructions.ts +0 -2
- package/src/cli/mcp/legacy-context.ts +0 -2
- package/src/cli/mcp/legacy-tool-service.ts +0 -2
- package/src/cli/mcp/multi-repository.ts +0 -2
- package/src/cli/mcp/oauth.ts +0 -2
- package/src/cli/mcp/openai-secure-tunnel.ts +0 -2
- package/src/cli/mcp/paths.ts +0 -2
- package/src/cli/mcp/policy.ts +0 -2
- package/src/cli/mcp/post-finalize-work-attribution.ts +0 -2
- package/src/cli/mcp/proxy-env.ts +0 -2
- package/src/cli/mcp/readiness-projection.ts +0 -2
- package/src/cli/mcp/redaction.ts +0 -2
- package/src/cli/mcp/repo.ts +0 -2
- package/src/cli/mcp/repository-tools.ts +0 -2
- package/src/cli/mcp/server.ts +0 -2
- package/src/cli/mcp/setup.ts +0 -2
- package/src/cli/mcp/tool-capability-cache.ts +0 -2
- package/src/cli/mcp/tool-contract.ts +0 -2
- package/src/cli/mcp/tools.ts +0 -2
- package/src/cli/mcp/toolset-names.ts +0 -2
- package/src/cli/mcp/toolset-selection.ts +0 -2
- package/src/cli/mcp/toolset.ts +0 -2
- package/src/cli/mcp/transports/http.ts +0 -2
- package/src/cli/mcp/transports/session-registry.ts +0 -2
- package/src/cli/mcp/transports/stdio.ts +0 -2
- package/src/cli/mcp/types.ts +0 -2
- package/src/cli/mcp/umbrella-tools.ts +0 -2
- package/src/cli/tools/codegraph.ts +0 -695
- package/src/core/adoption/helper-wrapper-plan.ts +0 -159
- package/src/runtime/context/codegraph-cache-boundary.ts +0 -255
- package/src/runtime/context/codegraph-read-provider.ts +0 -611
- package/src/runtime/context/codegraph-sidecar.cjs +0 -248
- package/src/runtime/control-plane/codegraph-cache-retention.ts +0 -164
- 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
- package/src/runtime/gateway/mcp/execution-tools.ts +0 -2
- package/src/runtime/gateway/mcp/legacy-ios-tool-adapter.ts +0 -2
- package/src/runtime/gateway/mcp/persisted-check-process.ts +0 -2
- package/src/runtime/gateway/mcp/process-tools.ts +0 -2
- package/src/runtime/gateway/mcp/router.ts +0 -2
- package/src/runtime/gateway/mcp/runtime-tool-definitions.ts +0 -2
- package/src/runtime/gateway/mcp/runtime-tools.ts +0 -2
- package/src/runtime/gateway/mcp/work-validation-reconciler.ts +0 -2
- package/src/runtime/plugins/browser-provider-registry.ts +0 -2
|
@@ -0,0 +1,150 @@
|
|
|
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 { WorkflowSupervisorControlPlane } from '../supervisor/control-plane';
|
|
6
|
+
import { SUPERVISOR_BLOCK_END, SUPERVISOR_BLOCK_START } from '../supervisor/protocol';
|
|
7
|
+
import { WORKFLOW_SUPERVISOR_MIN_TURN_INTERVAL_MS, WorkflowSupervisorStore } from '../supervisor/store';
|
|
8
|
+
|
|
9
|
+
const home = mkdtempSync(join(tmpdir(), 'forge-supervisor-recovery-'));
|
|
10
|
+
let mechanicalNowMs = Date.now();
|
|
11
|
+
const TURN_ADVANCE_MS = WORKFLOW_SUPERVISOR_MIN_TURN_INTERVAL_MS + 1_000;
|
|
12
|
+
const validators = { completionContract: async () => ({ valid: true, reason: 'ok' }), userBlockerPolicy: async () => ({ valid: true, reason: 'ok' }) };
|
|
13
|
+
const control = () => new WorkflowSupervisorControlPlane(new WorkflowSupervisorStore(home, { now: () => mechanicalNowMs }), validators);
|
|
14
|
+
const block = (
|
|
15
|
+
action: 'CONTINUE' | 'DONE',
|
|
16
|
+
effectId: string,
|
|
17
|
+
checkpoint: string,
|
|
18
|
+
conversationId: string,
|
|
19
|
+
taskId: string,
|
|
20
|
+
) => `${SUPERVISOR_BLOCK_START}\n${JSON.stringify({
|
|
21
|
+
action,
|
|
22
|
+
source_effect_id: effectId,
|
|
23
|
+
checkpoint,
|
|
24
|
+
reason: action === 'DONE' ? 'complete' : 'continue',
|
|
25
|
+
evidence: ['recovery-smoke'],
|
|
26
|
+
conversation_id: conversationId,
|
|
27
|
+
task_id: taskId,
|
|
28
|
+
supervisor_state: action === 'DONE' ? 'done' : 'running',
|
|
29
|
+
active_scope: `goal:${taskId}`,
|
|
30
|
+
})}\n${SUPERVISOR_BLOCK_END}`;
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
let supervisor = control();
|
|
34
|
+
const conversationId = '99999999-8888-7777-6666-555555555555';
|
|
35
|
+
const conversationUrl = `https://chatgpt.com/c/${conversationId}`;
|
|
36
|
+
supervisor.registerTask({ taskId: 'recovery-task', conversationId, conversationUrl, objective: 'Prove restart recovery.', completionContract: {}, continuationPolicy: {}, userBlockerPolicy: {} });
|
|
37
|
+
const enrollment = supervisor.reserveEnrollment('recovery-task');
|
|
38
|
+
let poll = supervisor.browserPoll({ conversationId, conversationUrl });
|
|
39
|
+
assert.equal(poll.command?.mode, 'send'); assert.equal(poll.command?.dispatchGeneration, 1);
|
|
40
|
+
assert.equal(supervisor.browserBeginEffect({ conversationId, conversationUrl, effectId: enrollment.effectId, dispatchId: 'enroll-g1', dispatchGeneration: 1, evidence: { latest_user_text: 'before enrollment', latest_assistant_response: 'existing assistant text' } }).started, true);
|
|
41
|
+
|
|
42
|
+
supervisor = control();
|
|
43
|
+
assert.throws(() => supervisor.observeEffect({ effectId: enrollment.effectId, observationId: 'forged-not-applied', outcome: 'not_applied', evidence: { latest_user_text: 'forged' } }), /NOT_APPLIED_PROOF_REQUIRED/);
|
|
44
|
+
poll = supervisor.browserPoll({ conversationId, conversationUrl });
|
|
45
|
+
assert.equal(poll.command?.mode, 'reconcile'); assert.equal(poll.command?.dispatchGeneration, 1);
|
|
46
|
+
supervisor.browserObserveEffect({ conversationId, conversationUrl, effectId: enrollment.effectId, observationId: 'enroll-not-applied', outcome: 'not_applied', evidence: { latest_user_text: 'before enrollment', latest_assistant_response: 'existing assistant text', target_marker_present: false, provider_surface_rendered: true, reason: 'composer_proven_empty' } });
|
|
47
|
+
mechanicalNowMs += 30_000;
|
|
48
|
+
poll = supervisor.browserPoll({ conversationId, conversationUrl });
|
|
49
|
+
assert.equal(poll.command?.mode, 'reconcile'); assert.equal(poll.command?.dispatchGeneration, 1); assert.equal(poll.command?.effectId, enrollment.effectId);
|
|
50
|
+
assert.equal(supervisor.store.effectDispatchBudget(enrollment.effectId).generations, 1);
|
|
51
|
+
supervisor.browserObserveEffect({ conversationId, conversationUrl, effectId: enrollment.effectId, observationId: 'enroll-applied', outcome: 'applied', evidence: { exact_user_message: true } });
|
|
52
|
+
const response1 = block('CONTINUE', enrollment.effectId, 'checkpoint-1', conversationId, 'recovery-task');
|
|
53
|
+
const turn1 = await supervisor.browserObserveAssistant({ conversationId, conversationUrl, responseText: response1 });
|
|
54
|
+
const continuation = turn1.successorEffect!;
|
|
55
|
+
|
|
56
|
+
mechanicalNowMs += TURN_ADVANCE_MS;
|
|
57
|
+
poll = supervisor.browserPoll({ conversationId, conversationUrl });
|
|
58
|
+
assert.equal(poll.command?.effectId, continuation.effectId); assert.equal(poll.command?.dispatchGeneration, 1);
|
|
59
|
+
assert.equal(supervisor.browserBeginEffect({ conversationId, conversationUrl, effectId: continuation.effectId, dispatchId: 'continue-g1', dispatchGeneration: 1, evidence: { latest_user_text: enrollment.prompt, latest_assistant_response: response1 } }).started, true);
|
|
60
|
+
supervisor = control();
|
|
61
|
+
poll = supervisor.browserPoll({ conversationId, conversationUrl }); assert.equal(poll.command?.mode, 'reconcile');
|
|
62
|
+
supervisor.browserObserveEffect({ conversationId, conversationUrl, effectId: continuation.effectId, observationId: 'bad-proof', outcome: 'not_applied', evidence: { latest_user_text: 'conversation drifted', latest_assistant_response: response1, target_marker_present: false, provider_surface_rendered: true, reason: 'composer_proven_empty' } });
|
|
63
|
+
poll = supervisor.browserPoll({ conversationId, conversationUrl }); assert.equal(poll.command?.mode, 'reconcile'); assert.equal(poll.command?.dispatchGeneration, 1);
|
|
64
|
+
// Even the exact pre-send baseline on a rendered page can be stale. A
|
|
65
|
+
// reopened observer cannot turn provider outcome uncertainty into a resend.
|
|
66
|
+
supervisor.browserObserveEffect({ conversationId, conversationUrl, effectId: continuation.effectId, observationId: 'stale-baseline-observation', outcome: 'not_applied', evidence: { latest_user_text: enrollment.prompt, latest_assistant_response: response1, target_marker_present: false, provider_surface_rendered: true, reason: 'composer_proven_empty' } });
|
|
67
|
+
mechanicalNowMs += 30_000;
|
|
68
|
+
poll = supervisor.browserPoll({ conversationId, conversationUrl }); assert.equal(poll.command?.mode, 'reconcile'); assert.equal(poll.command?.dispatchGeneration, 1); assert.equal(poll.command?.effectId, continuation.effectId);
|
|
69
|
+
assert.equal(supervisor.browserBeginEffect({ conversationId, conversationUrl, effectId: continuation.effectId, dispatchId: 'continue-g1-duplicate', dispatchGeneration: 1, evidence: { latest_user_text: enrollment.prompt, latest_assistant_response: response1 } }).started, false);
|
|
70
|
+
assert.equal(supervisor.store.effectDispatchBudget(continuation.effectId).generations, 1);
|
|
71
|
+
supervisor.browserObserveEffect({ conversationId, conversationUrl, effectId: continuation.effectId, observationId: 'continue-applied', outcome: 'applied', evidence: { exact_user_message: true } });
|
|
72
|
+
|
|
73
|
+
const response2 = block('CONTINUE', continuation.effectId, 'checkpoint-2', conversationId, 'recovery-task');
|
|
74
|
+
const turn2a = await supervisor.browserObserveAssistant({ conversationId, conversationUrl, responseText: response2 });
|
|
75
|
+
const turn2b = await supervisor.browserObserveAssistant({ conversationId, conversationUrl, responseText: response2 });
|
|
76
|
+
assert.equal(turn2a.successorEffect?.effectId, turn2b.successorEffect?.effectId); assert.equal(turn2b.deduplicated, true);
|
|
77
|
+
const terminalEffect = turn2a.successorEffect!;
|
|
78
|
+
mechanicalNowMs += TURN_ADVANCE_MS;
|
|
79
|
+
poll = supervisor.browserPoll({ conversationId, conversationUrl });
|
|
80
|
+
assert.equal(supervisor.browserBeginEffect({ conversationId, conversationUrl, effectId: terminalEffect.effectId, dispatchId: 'terminal-g1', dispatchGeneration: poll.command!.dispatchGeneration, evidence: { latest_user_text: continuation.prompt, latest_assistant_response: response2 } }).started, true);
|
|
81
|
+
supervisor.browserObserveEffect({ conversationId, conversationUrl, effectId: terminalEffect.effectId, observationId: 'terminal-applied', outcome: 'applied', evidence: { exact_user_message: true } });
|
|
82
|
+
const done = await supervisor.browserObserveAssistant({ conversationId, conversationUrl, responseText: block('DONE', terminalEffect.effectId, 'done', conversationId, 'recovery-task') });
|
|
83
|
+
assert.equal(done.terminal, true);
|
|
84
|
+
supervisor = control();
|
|
85
|
+
assert.equal(supervisor.browserTasks().length, 0);
|
|
86
|
+
const terminalPoll = supervisor.browserPoll({ conversationId, conversationUrl });
|
|
87
|
+
assert.equal(terminalPoll.terminal, 'DONE'); assert.equal(terminalPoll.command, undefined);
|
|
88
|
+
|
|
89
|
+
// Prove the unattended contract across repeated supervisor process/repository
|
|
90
|
+
// re-openings. Every round reconstructs the control plane from durable state,
|
|
91
|
+
// applies exactly one effect, emits CONTINUE, and must publish exactly one
|
|
92
|
+
// successor effect without a user-authored "continue" turn.
|
|
93
|
+
const unattendedTaskId = 'unattended-ten-round-task';
|
|
94
|
+
const unattendedConversationId = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee';
|
|
95
|
+
const unattendedConversationUrl = `https://chatgpt.com/c/${unattendedConversationId}`;
|
|
96
|
+
supervisor.registerTask({
|
|
97
|
+
taskId: unattendedTaskId,
|
|
98
|
+
conversationId: unattendedConversationId,
|
|
99
|
+
conversationUrl: unattendedConversationUrl,
|
|
100
|
+
objective: 'Complete ten autonomous continuation rounds across supervisor restart.',
|
|
101
|
+
completionContract: {}, continuationPolicy: {}, userBlockerPolicy: {},
|
|
102
|
+
});
|
|
103
|
+
let effect = supervisor.reserveEnrollment(unattendedTaskId);
|
|
104
|
+
const observedEffectIds = new Set<string>();
|
|
105
|
+
for (let round = 1; round <= 10; round += 1) {
|
|
106
|
+
supervisor = control();
|
|
107
|
+
assert.equal(observedEffectIds.has(effect.effectId), false);
|
|
108
|
+
observedEffectIds.add(effect.effectId);
|
|
109
|
+
supervisor.observeEffect({
|
|
110
|
+
effectId: effect.effectId,
|
|
111
|
+
observationId: `unattended-applied-${round}`,
|
|
112
|
+
outcome: 'applied',
|
|
113
|
+
evidence: { exact_user_message: true },
|
|
114
|
+
});
|
|
115
|
+
const responseText = block('CONTINUE', effect.effectId, `unattended-checkpoint-${round}`, unattendedConversationId, unattendedTaskId);
|
|
116
|
+
const advanced = await supervisor.observeAssistantTurn({
|
|
117
|
+
taskId: unattendedTaskId,
|
|
118
|
+
conversationId: unattendedConversationId,
|
|
119
|
+
responseText,
|
|
120
|
+
});
|
|
121
|
+
assert.equal(advanced.terminal, false);
|
|
122
|
+
assert.ok(advanced.successorEffect);
|
|
123
|
+
const replay = await supervisor.observeAssistantTurn({
|
|
124
|
+
taskId: unattendedTaskId,
|
|
125
|
+
conversationId: unattendedConversationId,
|
|
126
|
+
responseText,
|
|
127
|
+
});
|
|
128
|
+
assert.equal(replay.deduplicated, true);
|
|
129
|
+
assert.equal(replay.successorEffect?.effectId, advanced.successorEffect.effectId);
|
|
130
|
+
effect = advanced.successorEffect;
|
|
131
|
+
}
|
|
132
|
+
assert.equal(observedEffectIds.size, 10);
|
|
133
|
+
supervisor = control();
|
|
134
|
+
supervisor.observeEffect({
|
|
135
|
+
effectId: effect.effectId,
|
|
136
|
+
observationId: 'unattended-terminal-applied',
|
|
137
|
+
outcome: 'applied',
|
|
138
|
+
evidence: { exact_user_message: true },
|
|
139
|
+
});
|
|
140
|
+
const unattendedDone = await supervisor.observeAssistantTurn({
|
|
141
|
+
taskId: unattendedTaskId,
|
|
142
|
+
conversationId: unattendedConversationId,
|
|
143
|
+
responseText: block('DONE', effect.effectId, 'unattended-done', unattendedConversationId, unattendedTaskId),
|
|
144
|
+
});
|
|
145
|
+
assert.equal(unattendedDone.terminal, true);
|
|
146
|
+
supervisor = control();
|
|
147
|
+
assert.equal(supervisor.browserPoll({ conversationId: unattendedConversationId, conversationUrl: unattendedConversationUrl }).terminal, 'DONE');
|
|
148
|
+
|
|
149
|
+
console.log('[workflow-supervisor-restart-recovery-smoke] OK');
|
|
150
|
+
} finally { rmSync(home, { recursive: true, force: true }); }
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { mkdtempSync, rmSync } from 'node:fs';
|
|
2
|
+
import { tmpdir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { strict as assert } from 'node:assert';
|
|
5
|
+
import { createConnection } from 'node:net';
|
|
6
|
+
import { createRequirement, updateRequirement } from '../src/runtime/control-plane/persistence/requirement-store';
|
|
7
|
+
import {
|
|
8
|
+
registerWorkflowSupervisorTask,
|
|
9
|
+
reserveWorkflowSupervisorEnrollment,
|
|
10
|
+
} from '../supervisor/client';
|
|
11
|
+
import { WorkflowSupervisorControlPlane } from '../supervisor/control-plane';
|
|
12
|
+
import { forgeWorkflowSupervisorValidators } from '../supervisor/forge-validators';
|
|
13
|
+
import { workflowSupervisorSocketPath } from '../supervisor/paths';
|
|
14
|
+
import { renderSupervisorReceipt } from '../supervisor/protocol';
|
|
15
|
+
import { WorkflowSupervisorStore, workflowSupervisorDatabasePath } from '../supervisor/store';
|
|
16
|
+
import { createWorkflowSupervisorServer } from '../supervisor/server';
|
|
17
|
+
|
|
18
|
+
const home = mkdtempSync(join(tmpdir(), 'forge-workflow-supervisor-'));
|
|
19
|
+
try {
|
|
20
|
+
assert.equal(workflowSupervisorDatabasePath(home), join(home, 'supervisor', 'supervisor.sqlite'));
|
|
21
|
+
let allowDone = false;
|
|
22
|
+
const control = new WorkflowSupervisorControlPlane(new WorkflowSupervisorStore(home), {
|
|
23
|
+
completionContract: async () => ({ valid: allowDone, reason: allowDone ? 'verified' : 'missing_goal_evidence' }),
|
|
24
|
+
userBlockerPolicy: async () => ({ valid: false, reason: 'not_user_only' }),
|
|
25
|
+
});
|
|
26
|
+
const taskInput = { taskId: 'task-smoke', conversationId: 'conv-smoke', conversationUrl: 'https://chatgpt.com/c/conv-smoke', objective: 'finish smoke goal', completionContract: {}, continuationPolicy: { active_scope: 'goal:task-smoke' }, userBlockerPolicy: {} };
|
|
27
|
+
control.registerTask(taskInput);
|
|
28
|
+
assert.throws(() => control.registerTask({ ...taskInput, completionContract: { changed: true } }), /WORKFLOW_SUPERVISOR_TASK_ID_CONFLICT/);
|
|
29
|
+
const enrollment = control.reserveEnrollment('task-smoke');
|
|
30
|
+
assert.match(enrollment.prompt, new RegExp(enrollment.effectId));
|
|
31
|
+
control.observeEffect({ effectId: enrollment.effectId, observationId: 'obs-1', outcome: 'applied' });
|
|
32
|
+
const response = (effect: string, action: 'CONTINUE'|'DONE') => renderSupervisorReceipt(taskInput, effect, action);
|
|
33
|
+
const first = await control.observeAssistantTurn({ taskId: 'task-smoke', conversationId: 'conv-smoke', responseText: response(enrollment.effectId, 'CONTINUE') });
|
|
34
|
+
assert(first.successorEffect); assert.equal(first.terminal, false);
|
|
35
|
+
const duplicate = await control.observeAssistantTurn({ taskId: 'task-smoke', conversationId: 'conv-smoke', responseText: response(enrollment.effectId, 'CONTINUE') });
|
|
36
|
+
assert.equal(duplicate.successorEffect?.effectId, first.successorEffect.effectId); assert.equal(duplicate.deduplicated, true);
|
|
37
|
+
assert.throws(() => control.registerTask({ taskId: 'task-smoke', conversationId: 'conv-smoke', conversationUrl: 'https://chatgpt.com/c/conv-smoke', objective: 'changed objective', completionContract: {}, continuationPolicy: {}, userBlockerPolicy: {} }), /WORKFLOW_SUPERVISOR_TASK_ID_CONFLICT/);
|
|
38
|
+
control.observeEffect({ effectId: first.successorEffect.effectId, observationId: 'obs-2', outcome: 'applied' });
|
|
39
|
+
const rejected = await control.observeAssistantTurn({ taskId: 'task-smoke', conversationId: 'conv-smoke', responseText: response(first.successorEffect.effectId, 'DONE') });
|
|
40
|
+
assert.equal(rejected.terminal, false); assert.equal(rejected.validation?.valid, false); assert(rejected.successorEffect);
|
|
41
|
+
control.observeEffect({ effectId: rejected.successorEffect.effectId, observationId: 'obs-3', outcome: 'applied' });
|
|
42
|
+
allowDone = true;
|
|
43
|
+
const done = await control.observeAssistantTurn({ taskId: 'task-smoke', conversationId: 'conv-smoke', responseText: response(rejected.successorEffect.effectId, 'DONE') });
|
|
44
|
+
assert.equal(done.terminal, true); assert.equal(done.successorEffect, undefined);
|
|
45
|
+
|
|
46
|
+
const socketPath = workflowSupervisorSocketPath(home);
|
|
47
|
+
const server = createWorkflowSupervisorServer({ controlPlane: control, socketPath });
|
|
48
|
+
await new Promise<void>((resolve) => server.once('listening', resolve));
|
|
49
|
+
const health = await new Promise<Record<string, any>>((resolve, reject) => {
|
|
50
|
+
const socket = createConnection(socketPath);
|
|
51
|
+
let buffer = '';
|
|
52
|
+
socket.once('error', reject);
|
|
53
|
+
socket.on('data', (chunk) => {
|
|
54
|
+
buffer += chunk.toString('utf8');
|
|
55
|
+
const newline = buffer.indexOf('\n');
|
|
56
|
+
if (newline < 0) return;
|
|
57
|
+
socket.end();
|
|
58
|
+
resolve(JSON.parse(buffer.slice(0, newline)) as Record<string, any>);
|
|
59
|
+
});
|
|
60
|
+
socket.once('connect', () => socket.write(`${JSON.stringify({ id: 'health-1', method: 'health', params: {} })}\n`));
|
|
61
|
+
});
|
|
62
|
+
assert.equal(health.ok, true); assert.equal(health.result.status, 'ready');
|
|
63
|
+
|
|
64
|
+
const rpcTaskInput = {
|
|
65
|
+
taskId: 'task-rpc-smoke', conversationId: 'conv-rpc-smoke', conversationUrl: 'https://chatgpt.com/c/conv-rpc-smoke', objective: 'rpc enrollment smoke',
|
|
66
|
+
completionContract: { kind: 'smoke' }, continuationPolicy: { kind: 'smoke' }, userBlockerPolicy: { kind: 'smoke' },
|
|
67
|
+
};
|
|
68
|
+
const rpcTask = await registerWorkflowSupervisorTask(home, rpcTaskInput);
|
|
69
|
+
assert.equal(rpcTask.taskId, rpcTaskInput.taskId);
|
|
70
|
+
const rpcEnrollment = await reserveWorkflowSupervisorEnrollment(home, rpcTask.taskId);
|
|
71
|
+
const rpcEnrollmentReplay = await reserveWorkflowSupervisorEnrollment(home, rpcTask.taskId);
|
|
72
|
+
assert.equal(rpcEnrollmentReplay.effectId, rpcEnrollment.effectId);
|
|
73
|
+
|
|
74
|
+
const controllerHome = join(home, 'controller');
|
|
75
|
+
const validators = forgeWorkflowSupervisorValidators();
|
|
76
|
+
createRequirement({ controllerHome }, { requirementId: 'REQ-SUPERVISOR-DONE', title: 'Supervisor done validator', outcomeStatement: 'Validate canonical semantic completion.' });
|
|
77
|
+
updateRequirement({ controllerHome }, { requirementId: 'REQ-SUPERVISOR-DONE', action: 'smoke_activate', mutate: (current) => ({ ...current, state: 'active' }) });
|
|
78
|
+
const doneTask = {
|
|
79
|
+
...rpcTaskInput,
|
|
80
|
+
taskId: 'task-validator-done',
|
|
81
|
+
completionContract: { kind: 'forge_requirement_done', controller_home: controllerHome, requirement_id: 'REQ-SUPERVISOR-DONE' },
|
|
82
|
+
userBlockerPolicy: { kind: 'forge_requirement_waiting_for_user', controller_home: controllerHome, requirement_id: 'REQ-SUPERVISOR-DONE' },
|
|
83
|
+
createdAt: new Date().toISOString(),
|
|
84
|
+
};
|
|
85
|
+
assert.equal((await validators.completionContract(doneTask, { action: 'DONE', sourceEffectId: 'fx_smokevalidator', checkpoint: 'done', reason: 'done', evidence: [] })).valid, false);
|
|
86
|
+
updateRequirement({ controllerHome }, {
|
|
87
|
+
requirementId: 'REQ-SUPERVISOR-DONE', action: 'smoke_semantic_acceptance',
|
|
88
|
+
mutate: (current) => ({ ...current, state: 'done', semanticAcceptance: { reviewer: 'smoke', rationale: 'validated', planIds: [], acceptedAt: new Date().toISOString() } }),
|
|
89
|
+
});
|
|
90
|
+
assert.equal((await validators.completionContract(doneTask, { action: 'DONE', sourceEffectId: 'fx_smokevalidator', checkpoint: 'done', reason: 'done', evidence: [] })).valid, true);
|
|
91
|
+
|
|
92
|
+
createRequirement({ controllerHome }, { requirementId: 'REQ-SUPERVISOR-USER', title: 'Supervisor user validator', outcomeStatement: 'Validate genuine user-only wait.' });
|
|
93
|
+
updateRequirement({ controllerHome }, { requirementId: 'REQ-SUPERVISOR-USER', action: 'smoke_activate', mutate: (current) => ({ ...current, state: 'active' }) });
|
|
94
|
+
updateRequirement({ controllerHome }, {
|
|
95
|
+
requirementId: 'REQ-SUPERVISOR-USER', action: 'smoke_user_wait',
|
|
96
|
+
mutate: (current) => ({ ...current, state: 'waiting_for_user', needsAttention: true, attentionSummary: 'User authorization is required.' }),
|
|
97
|
+
});
|
|
98
|
+
const userTask = { ...doneTask, taskId: 'task-validator-user', completionContract: { kind: 'forge_requirement_done', controller_home: controllerHome, requirement_id: 'REQ-SUPERVISOR-USER' }, userBlockerPolicy: { kind: 'forge_requirement_waiting_for_user', controller_home: controllerHome, requirement_id: 'REQ-SUPERVISOR-USER' } };
|
|
99
|
+
assert.equal((await validators.userBlockerPolicy(userTask, { action: 'NEEDS_USER', sourceEffectId: 'fx_smokevalidator', checkpoint: 'user', reason: 'user action', evidence: [] })).valid, true);
|
|
100
|
+
|
|
101
|
+
await new Promise<void>((resolve) => server.close(() => resolve()));
|
|
102
|
+
console.log('[workflow-supervisor-smoke] OK');
|
|
103
|
+
} finally { rmSync(home, { recursive: true, force: true }); }
|
|
@@ -11,11 +11,12 @@ command -v bun >/dev/null 2>&1 || {
|
|
|
11
11
|
|
|
12
12
|
TEST_FILES=(
|
|
13
13
|
"tests/runtime/facade-contracts.test.ts"
|
|
14
|
-
"tests/runtime/route-policy.test.ts"
|
|
15
14
|
"tests/runtime/forge-runtime-service.test.ts"
|
|
16
15
|
"tests/cli/local-bridge.test.ts"
|
|
17
16
|
"tests/runtime/thin-harness-gateway-routing.test.ts"
|
|
18
17
|
"tests/runtime/runtime-observability.test.ts"
|
|
18
|
+
"tests/runtime/release-session.test.ts"
|
|
19
|
+
"tests/runtime/local-recovery-plugin.test.ts"
|
|
19
20
|
"tests/unit/test-governance.test.ts"
|
|
20
21
|
)
|
|
21
22
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { GitHubStatus } from "../github/contracts";
|
|
2
|
-
import type { McpAgentRunnerName } from "
|
|
3
|
-
import type { ControllerAgent
|
|
2
|
+
import type { McpAgentRunnerName } from "../../../adapters/mcp/types";
|
|
3
|
+
import type { ControllerAgent } from "../controller/types";
|
|
4
4
|
|
|
5
5
|
export type ExecutorHealthStatus =
|
|
6
6
|
| "available"
|
|
@@ -24,7 +24,6 @@ export type ExecutorHealthReason =
|
|
|
24
24
|
| "unknown";
|
|
25
25
|
|
|
26
26
|
export type ExecutorHealthFallback =
|
|
27
|
-
| "use_direct_edit"
|
|
28
27
|
| "enable_local_agent"
|
|
29
28
|
| "run_gh_auth_login"
|
|
30
29
|
| "enable_copilot_coding_agent"
|
|
@@ -64,19 +63,6 @@ function normalize(value: string): string {
|
|
|
64
63
|
return value.toLowerCase().replace(/\s+/g, " ").trim();
|
|
65
64
|
}
|
|
66
65
|
|
|
67
|
-
function isSmallScopedTask(task: Pick<ControllerTask, "allowedPaths"> | undefined): boolean {
|
|
68
|
-
return Array.isArray(task?.allowedPaths) && task.allowedPaths.length > 0 && task.allowedPaths.length <= 3;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function localUnavailableMessage(base: string, task?: Pick<ControllerTask, "allowedPaths">): string {
|
|
72
|
-
if (!isSmallScopedTask(task)) return base;
|
|
73
|
-
return `${base} Use begin_edit_session/apply_patch/run_check instead of retrying unavailable agents.`;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function localUnavailableFallback(task?: Pick<ControllerTask, "allowedPaths">): ExecutorHealthFallback {
|
|
77
|
-
return isSmallScopedTask(task) ? "use_direct_edit" : "enable_local_agent";
|
|
78
|
-
}
|
|
79
|
-
|
|
80
66
|
export function executorHealthCode(health: ExecutorHealth): string {
|
|
81
67
|
switch (health.reason) {
|
|
82
68
|
case "local_dev_runner_disabled":
|
|
@@ -104,19 +90,15 @@ export function executorHealthCode(health: ExecutorHealth): string {
|
|
|
104
90
|
export function classifyLocalExecutorHealth(
|
|
105
91
|
agent: Exclude<ControllerAgent, "github-copilot">,
|
|
106
92
|
policy: LocalExecutorPolicy,
|
|
107
|
-
task?: Pick<ControllerTask, "allowedPaths">,
|
|
108
93
|
): ExecutorHealth | null {
|
|
109
94
|
if (!policy.agentRunner) {
|
|
110
95
|
return {
|
|
111
96
|
agent,
|
|
112
97
|
status: "disabled",
|
|
113
98
|
reason: "local_dev_runner_disabled",
|
|
114
|
-
message:
|
|
115
|
-
`Local ${agent} runs are disabled because the dev runner is not enabled.`,
|
|
116
|
-
task,
|
|
117
|
-
),
|
|
99
|
+
message: `Local ${agent} runs are disabled because the dev runner is not enabled.`,
|
|
118
100
|
remediation: "Enable the controller dev runner before dispatching local Codex or Claude runs.",
|
|
119
|
-
fallback:
|
|
101
|
+
fallback: "enable_local_agent",
|
|
120
102
|
};
|
|
121
103
|
}
|
|
122
104
|
if (!policy.allowedAgents.includes(agent)) {
|
|
@@ -124,12 +106,9 @@ export function classifyLocalExecutorHealth(
|
|
|
124
106
|
agent,
|
|
125
107
|
status: "disabled",
|
|
126
108
|
reason: "local_agent_disabled",
|
|
127
|
-
message:
|
|
128
|
-
`Local agent is not enabled: ${agent}.`,
|
|
129
|
-
task,
|
|
130
|
-
),
|
|
109
|
+
message: `Local agent is not enabled: ${agent}.`,
|
|
131
110
|
remediation: `Enable ${agent} in the controller dev-runner allowedAgents list before retrying.`,
|
|
132
|
-
fallback:
|
|
111
|
+
fallback: "enable_local_agent",
|
|
133
112
|
};
|
|
134
113
|
}
|
|
135
114
|
return null;
|
|
@@ -137,7 +116,6 @@ export function classifyLocalExecutorHealth(
|
|
|
137
116
|
|
|
138
117
|
export function classifyGitHubCopilotPreflight(
|
|
139
118
|
status: GitHubStatus,
|
|
140
|
-
task?: Pick<ControllerTask, "allowedPaths">,
|
|
141
119
|
): ExecutorHealth | null {
|
|
142
120
|
if (!status.available) {
|
|
143
121
|
return {
|
|
@@ -146,7 +124,7 @@ export function classifyGitHubCopilotPreflight(
|
|
|
146
124
|
reason: "github_cli_unavailable",
|
|
147
125
|
message: "GitHub CLI (gh) is unavailable, so GitHub Copilot cloud sessions cannot start.",
|
|
148
126
|
remediation: "Install GitHub CLI and ensure `gh --version` works in this repository environment.",
|
|
149
|
-
fallback:
|
|
127
|
+
fallback: "install_github_cli",
|
|
150
128
|
};
|
|
151
129
|
}
|
|
152
130
|
if (!status.authenticated) {
|
|
@@ -175,7 +153,6 @@ export function classifyGitHubCopilotPreflight(
|
|
|
175
153
|
export function classifyExecutorFailure(
|
|
176
154
|
agent: ControllerAgent,
|
|
177
155
|
message: string,
|
|
178
|
-
task?: Pick<ControllerTask, "allowedPaths">,
|
|
179
156
|
): ExecutorHealth | null {
|
|
180
157
|
const text = normalize(message);
|
|
181
158
|
if (!text) return null;
|
|
@@ -193,7 +170,7 @@ export function classifyExecutorFailure(
|
|
|
193
170
|
reason: "copilot_cca_disabled",
|
|
194
171
|
message: "GitHub Copilot cloud agent is not enabled for this account or repository.",
|
|
195
172
|
remediation: "Enable GitHub Copilot Coding Agent / CCA for the account and repository before retrying cloud sessions.",
|
|
196
|
-
fallback:
|
|
173
|
+
fallback: "enable_copilot_coding_agent",
|
|
197
174
|
};
|
|
198
175
|
}
|
|
199
176
|
return null;
|
|
@@ -207,7 +184,7 @@ export function classifyExecutorFailure(
|
|
|
207
184
|
reason: "codex_insufficient_balance",
|
|
208
185
|
message: "Codex execution is unavailable because the configured API account has insufficient balance.",
|
|
209
186
|
remediation: "Restore API balance or correct the Codex base URL/account configuration before retrying.",
|
|
210
|
-
fallback:
|
|
187
|
+
fallback: "fix_codex_api_balance_or_base_url",
|
|
211
188
|
};
|
|
212
189
|
}
|
|
213
190
|
if (text.includes("usage limit")) {
|
|
@@ -217,7 +194,7 @@ export function classifyExecutorFailure(
|
|
|
217
194
|
reason: "codex_usage_limit",
|
|
218
195
|
message: "Codex execution is unavailable because the configured account has reached a usage limit.",
|
|
219
196
|
remediation: "Raise or wait for the Codex usage limit, or correct the API account/base URL configuration before retrying.",
|
|
220
|
-
fallback:
|
|
197
|
+
fallback: "fix_codex_api_balance_or_base_url",
|
|
221
198
|
};
|
|
222
199
|
}
|
|
223
200
|
if (
|
|
@@ -232,7 +209,7 @@ export function classifyExecutorFailure(
|
|
|
232
209
|
reason: "codex_auth_required",
|
|
233
210
|
message: "Codex execution is unavailable because authentication is required.",
|
|
234
211
|
remediation: "Authenticate the Codex executor or correct the configured credentials/base URL before retrying.",
|
|
235
|
-
fallback:
|
|
212
|
+
fallback: "authenticate_codex",
|
|
236
213
|
};
|
|
237
214
|
}
|
|
238
215
|
}
|
|
@@ -243,7 +220,7 @@ export function classifyExecutorFailure(
|
|
|
243
220
|
reason: "unknown",
|
|
244
221
|
message: `${agent} execution failed for an unclassified reason.`,
|
|
245
222
|
remediation: "Inspect the bounded run error and executor configuration before retrying.",
|
|
246
|
-
fallback:
|
|
223
|
+
fallback: "inspect_executor_configuration",
|
|
247
224
|
};
|
|
248
225
|
}
|
|
249
226
|
|
|
@@ -13,14 +13,11 @@ import {
|
|
|
13
13
|
type EditOperation,
|
|
14
14
|
type EditSession,
|
|
15
15
|
} from "../editing/edit-session";
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import { resolveEffectiveTaskState } from "../controller/task-status-resolver";
|
|
19
|
-
import { resolveMcpPath } from "../mcp/paths";
|
|
20
|
-
import type { McpPolicy } from "../mcp/types";
|
|
16
|
+
import { resolveMcpPath } from "../../../adapters/mcp/paths";
|
|
17
|
+
import type { McpPolicy } from "../../../adapters/mcp/types";
|
|
21
18
|
import { getAgentJob, markAgentJobClosure, markAgentJobIntegrated, markAgentJobIntegrationReview } from "./job-manager";
|
|
22
19
|
import type { AgentJobMeta, AgentJobPreservationReason } from "./types";
|
|
23
|
-
import { assertRuntimeMayWriteOrThrow } from "../../runtime/root/write-fence";
|
|
20
|
+
import { assertRuntimeMayWriteOrThrow, isRuntimeWriteFenceError } from "../../runtime/root/write-fence";
|
|
24
21
|
|
|
25
22
|
type IntegrationChangeOutcome = "changed" | "already_integrated";
|
|
26
23
|
|
|
@@ -509,21 +506,22 @@ export function integrateAgentJob(
|
|
|
509
506
|
?? undefined;
|
|
510
507
|
assertRuntimeMayWriteOrThrow('integrate_worktree', controllerHome);
|
|
511
508
|
} catch (error) {
|
|
512
|
-
if (error
|
|
509
|
+
if (isRuntimeWriteFenceError(error)) throw error;
|
|
513
510
|
/* unbound legacy single-runtime */
|
|
514
511
|
}
|
|
515
512
|
let run: AgentJobMeta = getAgentJob(repoRoot, runId);
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
run.executionMode === "worktree"
|
|
523
|
-
|
|
524
|
-
|
|
513
|
+
// Integration is an explicit decision, so an ordinary Run must have finished
|
|
514
|
+
// successfully. One state is still integrable: a Run that a previous explicit
|
|
515
|
+
// integration attempt preserved after a failure or a required review. That
|
|
516
|
+
// preserved worktree is the durable product of that attempt, and refusing to
|
|
517
|
+
// retry it stranded the isolated work with no path forward.
|
|
518
|
+
const preservedIntegrationRetry = run.status === "waiting_for_user"
|
|
519
|
+
&& run.executionMode === "worktree"
|
|
520
|
+
&& (run.closureState === "preserved" || run.closureState === "integration_blocked")
|
|
521
|
+
&& Boolean(run.autoIntegrationError || run.preservationReason);
|
|
522
|
+
if (run.status !== "succeeded" && !preservedIntegrationRetry)
|
|
525
523
|
throw new Error(
|
|
526
|
-
`only succeeded
|
|
524
|
+
`only a succeeded Run (or an explicitly preserved integration attempt) can be integrated (current: ${run.status})`,
|
|
527
525
|
);
|
|
528
526
|
if (run.provider !== "local")
|
|
529
527
|
throw new Error(
|
|
@@ -531,7 +529,7 @@ export function integrateAgentJob(
|
|
|
531
529
|
);
|
|
532
530
|
if (run.worktree === repoRoot || !run.branch || !run.baseRevision)
|
|
533
531
|
throw new Error(
|
|
534
|
-
"Run did not use an isolated Git worktree; its changes are already in the
|
|
532
|
+
"Run did not use an isolated Git worktree; its changes are already in the dispatch checkout",
|
|
535
533
|
);
|
|
536
534
|
if (run.integratedSessionId) {
|
|
537
535
|
const existing = getEditSession(repoRoot, run.integratedSessionId);
|
|
@@ -548,28 +546,12 @@ export function integrateAgentJob(
|
|
|
548
546
|
|
|
549
547
|
run = markAgentJobClosure(repoRoot, runId, {
|
|
550
548
|
state: "integrating",
|
|
551
|
-
details: "Applying isolated Run changes to the
|
|
549
|
+
details: "Applying isolated Run changes to the dispatch checkout.",
|
|
552
550
|
});
|
|
553
551
|
|
|
554
|
-
const issue = getIssue(repoRoot, run.issueId);
|
|
555
|
-
const task = issue.tasks.find((entry) => entry.id === run.taskId);
|
|
556
|
-
if (!task) throw new Error(`task not found: ${run.issueId}/${run.taskId}`);
|
|
557
|
-
const state = resolveEffectiveTaskState({ issue, task, runs: readTaskRunEvidence(repoRoot, task) });
|
|
558
|
-
const taskReady = autoFinalizing || userResolvableIntegration
|
|
559
|
-
? !state.terminal && !state.inactive && ["review", "ready_to_integrate", "integrating", "integration_blocked", "integrated", "verified"].includes(task.status)
|
|
560
|
-
: !state.terminal && !state.inactive && ["review", "ready_to_integrate", "integrating", "integration_blocked", "verified"].includes(state.effectiveStatus);
|
|
561
|
-
if (!taskReady)
|
|
562
|
-
throw new Error(
|
|
563
|
-
`task must be active and in review before integration (declared: ${task.status}, effective: ${state.effectiveStatus})`,
|
|
564
|
-
);
|
|
565
|
-
|
|
566
552
|
const initialPlan = planFromCurrentWorkspace(repoRoot, run, policy);
|
|
567
553
|
if (initialPlan.changedPaths.length === 0)
|
|
568
554
|
throw new Error("task worktree has no changes to integrate");
|
|
569
|
-
if (initialPlan.changedPaths.length > 25)
|
|
570
|
-
throw new Error(
|
|
571
|
-
`task changed ${initialPlan.changedPaths.length} files; split or manually integrate work larger than 25 files`,
|
|
572
|
-
);
|
|
573
555
|
if (initialPlan.conflicts.length > 0)
|
|
574
556
|
throw createReviewPacket(
|
|
575
557
|
repoRoot,
|
|
@@ -578,10 +560,9 @@ export function integrateAgentJob(
|
|
|
578
560
|
initialPlan.conflicts,
|
|
579
561
|
);
|
|
580
562
|
|
|
581
|
-
const allowedPaths =
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
: initialPlan.changedPaths;
|
|
563
|
+
const allowedPaths = run.allowedPaths?.length
|
|
564
|
+
? run.allowedPaths
|
|
565
|
+
: initialPlan.changedPaths;
|
|
585
566
|
if (initialPlan.operations.length === 0) {
|
|
586
567
|
const applied = finalizeAlreadyIntegratedSession(
|
|
587
568
|
repoRoot,
|
|
@@ -592,10 +573,6 @@ export function integrateAgentJob(
|
|
|
592
573
|
changedFiles: initialPlan.changedPaths,
|
|
593
574
|
changeOutcome: "already_integrated",
|
|
594
575
|
});
|
|
595
|
-
updateTask(repoRoot, run.issueId, run.taskId, {
|
|
596
|
-
status: "integrated",
|
|
597
|
-
note: `${runId} already matched the main workspace and was recorded through edit session ${applied.sessionId}; run focused checks and record verification before acceptance.`,
|
|
598
|
-
});
|
|
599
576
|
return {
|
|
600
577
|
session: applied,
|
|
601
578
|
changedPaths: initialPlan.changedPaths,
|
|
@@ -644,10 +621,6 @@ export function integrateAgentJob(
|
|
|
644
621
|
changedFiles: refreshedPlan.changedPaths,
|
|
645
622
|
changeOutcome: "already_integrated",
|
|
646
623
|
});
|
|
647
|
-
updateTask(repoRoot, run.issueId, run.taskId, {
|
|
648
|
-
status: "integrated",
|
|
649
|
-
note: `${runId} became already integrated while finish was running and was recorded through edit session ${alreadyIntegrated.sessionId}; run focused checks and record verification before acceptance.`,
|
|
650
|
-
});
|
|
651
624
|
return {
|
|
652
625
|
session: alreadyIntegrated,
|
|
653
626
|
changedPaths: refreshedPlan.changedPaths,
|
|
@@ -683,10 +656,6 @@ export function integrateAgentJob(
|
|
|
683
656
|
changedFiles: initialPlan.operations.map((operation) => operation.path),
|
|
684
657
|
changeOutcome: "changed",
|
|
685
658
|
});
|
|
686
|
-
updateTask(repoRoot, run.issueId, run.taskId, {
|
|
687
|
-
status: "integrated",
|
|
688
|
-
note: `${runId} integrated through edit session ${applied.sessionId}; run focused checks and record verification before acceptance.`,
|
|
689
|
-
});
|
|
690
659
|
return {
|
|
691
660
|
session: applied,
|
|
692
661
|
changedPaths: initialPlan.operations.map((operation) => operation.path),
|
|
@@ -122,7 +122,10 @@ function normalizeAgentMeta(
|
|
|
122
122
|
: meta.worktree === repoRoot
|
|
123
123
|
? "workspace"
|
|
124
124
|
: "worktree");
|
|
125
|
-
|
|
125
|
+
// Integration is an explicit model decision. Historical worktree Runs may
|
|
126
|
+
// retain this field for read compatibility, but a missing value must never
|
|
127
|
+
// turn a completed execution into a workflow transition.
|
|
128
|
+
meta.autoIntegrate = meta.autoIntegrate ?? false;
|
|
126
129
|
meta.closureState = meta.closureState ?? (
|
|
127
130
|
meta.provider === "local" && meta.executionMode === "worktree"
|
|
128
131
|
? meta.worktreeCleanedAt
|
|
@@ -1105,7 +1108,7 @@ function attachExecutorFailureHealth(meta: AgentJobMeta, stdoutTail?: string, st
|
|
|
1105
1108
|
}
|
|
1106
1109
|
if (meta.executorHealth) return meta;
|
|
1107
1110
|
const message = executorFailureMessage(meta, stdoutTail, stderrTail);
|
|
1108
|
-
const health = classifyExecutorFailure(meta.agent, message
|
|
1111
|
+
const health = classifyExecutorFailure(meta.agent, message);
|
|
1109
1112
|
if (health) meta.executorHealth = health;
|
|
1110
1113
|
return meta;
|
|
1111
1114
|
}
|
|
@@ -1261,7 +1264,8 @@ function baseMeta(
|
|
|
1261
1264
|
eventsPath: relative(opts.repoRoot, paths.eventsPath).replace(/\\/g, "/"),
|
|
1262
1265
|
timeoutMs: opts.timeoutMs,
|
|
1263
1266
|
startupDeadlineAt: new Date(Date.now() + agentStartupTimeoutMs()).toISOString(),
|
|
1264
|
-
|
|
1267
|
+
// A worktree contains concurrent writes; it does not authorize delivery.
|
|
1268
|
+
autoIntegrate: false,
|
|
1265
1269
|
progress: {
|
|
1266
1270
|
phase: "starting",
|
|
1267
1271
|
currentActivity: "已受理,等待异步启动",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { createHash } from 'crypto';
|
|
2
2
|
import { existsSync, readFileSync, statSync } from 'fs';
|
|
3
3
|
import { isAbsolute, resolve } from 'path';
|
|
4
|
-
import { resolveMcpPath } from '
|
|
5
|
-
import type { McpPolicy } from '
|
|
4
|
+
import { resolveMcpPath } from '../../../adapters/mcp/paths';
|
|
5
|
+
import type { McpPolicy } from '../../../adapters/mcp/types';
|
|
6
6
|
import type { BrowserWriteOutputPolicy, PromptBundleFile } from './types';
|
|
7
7
|
|
|
8
8
|
const READ_ALLOW_GLOBS = [
|