@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
|
@@ -31,6 +31,8 @@ import { dirname, join } from 'path';
|
|
|
31
31
|
import { fileURLToPath } from 'url';
|
|
32
32
|
import { capProcessOutput } from '../../../effects/process-runner';
|
|
33
33
|
import { getRepository, selectRepositoryCheckout } from '../../../cli/repositories/registry';
|
|
34
|
+
import { recordProcessHandleIndexEntry } from './handle-index';
|
|
35
|
+
import { processScopeExecutionTarget, processScopeFromKey } from './process-scope';
|
|
34
36
|
import { redactSensitiveText, sanitizeSensitiveTextFileInPlace } from '../../evidence/sensitive-output';
|
|
35
37
|
import { isProcessAlive, terminateProcessTree } from '../../shared/process-tree';
|
|
36
38
|
import { repositoryChildProcessEnvironment, resolveBunExecutable } from '../../shared/process-environment';
|
|
@@ -1224,6 +1226,7 @@ export async function spawnManagedProcess(input: SpawnManagedProcessInput): Prom
|
|
|
1224
1226
|
processId,
|
|
1225
1227
|
repoId: input.repoId,
|
|
1226
1228
|
checkoutId: input.checkoutId,
|
|
1229
|
+
...(input.principalId ? { principalId: input.principalId } : {}),
|
|
1227
1230
|
workId: input.workId,
|
|
1228
1231
|
executionIdentity: input.executionIdentity,
|
|
1229
1232
|
commandId: input.commandId?.trim() || processId,
|
|
@@ -1253,6 +1256,16 @@ export async function spawnManagedProcess(input: SpawnManagedProcessInput): Prom
|
|
|
1253
1256
|
logPath: stdoutPath,
|
|
1254
1257
|
};
|
|
1255
1258
|
createProcessRecord(record);
|
|
1259
|
+
// Instance-level locator so attachment resolves the target from the handle
|
|
1260
|
+
// instead of replaying placement inputs or scanning repository partitions.
|
|
1261
|
+
recordProcessHandleIndexEntry(input.controllerHome, {
|
|
1262
|
+
processId,
|
|
1263
|
+
lane: 'managed',
|
|
1264
|
+
target: processScopeExecutionTarget(input.controllerHome, processScopeFromKey(input.repoId)),
|
|
1265
|
+
principalId: input.principalId,
|
|
1266
|
+
workId: input.workId,
|
|
1267
|
+
commandId: record.commandId,
|
|
1268
|
+
});
|
|
1256
1269
|
|
|
1257
1270
|
if (input.signal?.aborted) {
|
|
1258
1271
|
completeProcessFromEvidence(input.controllerHome, input.repoId, processId, fenceToken, {
|
|
@@ -1489,6 +1502,7 @@ export async function spawnManagedProcess(input: SpawnManagedProcessInput): Prom
|
|
|
1489
1502
|
repoId: input.repoId,
|
|
1490
1503
|
controllerHome: input.controllerHome,
|
|
1491
1504
|
command,
|
|
1505
|
+
...(input.trustedRuntimeChild ? { trustedRuntimeChild: input.trustedRuntimeChild } : {}),
|
|
1492
1506
|
timeoutMs,
|
|
1493
1507
|
maxStdoutBytes: maxOutputBytes,
|
|
1494
1508
|
maxStderrBytes: maxOutputBytes,
|
|
@@ -1570,17 +1584,19 @@ export async function spawnManagedProcess(input: SpawnManagedProcessInput): Prom
|
|
|
1570
1584
|
}
|
|
1571
1585
|
|
|
1572
1586
|
const completed = await new Promise<ManagedProcessRecord | 'timeout'>((resolve) => {
|
|
1573
|
-
const
|
|
1574
|
-
timer.unref?.();
|
|
1575
|
-
monitor.waiters.push((done) => {
|
|
1587
|
+
const finish = (done: ManagedProcessRecord | 'timeout') => {
|
|
1576
1588
|
clearTimeout(timer);
|
|
1589
|
+
const index = monitor.waiters.indexOf(finish);
|
|
1590
|
+
if (index >= 0) monitor.waiters.splice(index, 1);
|
|
1577
1591
|
resolve(done);
|
|
1578
|
-
}
|
|
1592
|
+
};
|
|
1593
|
+
const timer = setTimeout(() => finish('timeout'), interactiveWaitMs);
|
|
1594
|
+
timer.unref?.();
|
|
1595
|
+
monitor.waiters.push(finish);
|
|
1579
1596
|
if (monitor.settled) {
|
|
1580
1597
|
const current = getProcessRecord(input.controllerHome, input.repoId, processId);
|
|
1581
1598
|
if (current?.terminalWritten) {
|
|
1582
|
-
|
|
1583
|
-
resolve(current);
|
|
1599
|
+
finish(current);
|
|
1584
1600
|
}
|
|
1585
1601
|
}
|
|
1586
1602
|
});
|
|
@@ -1627,6 +1643,18 @@ function applyReceiptIfPresent(
|
|
|
1627
1643
|
}, { authority: 'durable_exit_receipt' });
|
|
1628
1644
|
}
|
|
1629
1645
|
|
|
1646
|
+
|
|
1647
|
+
function reconcileObservedTerminalProcess(
|
|
1648
|
+
controllerHome: string,
|
|
1649
|
+
repoId: string,
|
|
1650
|
+
record: ManagedProcessRecord,
|
|
1651
|
+
): ManagedProcessRecord {
|
|
1652
|
+
if (record.terminalWritten !== true) return record;
|
|
1653
|
+
const reconciled = releaseProcessLeasesOnce(controllerHome, repoId, record.processId) ?? record;
|
|
1654
|
+
cleanupTerminalRunnerReceipts(reconciled);
|
|
1655
|
+
return reconciled;
|
|
1656
|
+
}
|
|
1657
|
+
|
|
1630
1658
|
export function getProcessHandle(
|
|
1631
1659
|
controllerHome: string,
|
|
1632
1660
|
repoId: string,
|
|
@@ -1634,6 +1662,9 @@ export function getProcessHandle(
|
|
|
1634
1662
|
): ProcessHandle | undefined {
|
|
1635
1663
|
const record = getProcessRecord(controllerHome, repoId, processId);
|
|
1636
1664
|
if (!record) return undefined;
|
|
1665
|
+
if (record.terminalWritten === true) {
|
|
1666
|
+
return recordToHandle(reconcileObservedTerminalProcess(controllerHome, repoId, record), { completed: true });
|
|
1667
|
+
}
|
|
1637
1668
|
if (isManagedProcessActive(record) && !liveMonitors.has(processId)) {
|
|
1638
1669
|
const fromReceipt = applyReceiptIfPresent(controllerHome, repoId, processId, record);
|
|
1639
1670
|
if (fromReceipt) return recordToHandle(fromReceipt, { completed: true });
|
|
@@ -1656,33 +1687,37 @@ export async function waitForProcess(
|
|
|
1656
1687
|
): Promise<ProcessHandle> {
|
|
1657
1688
|
const existing = getProcessRecord(controllerHome, repoId, processId);
|
|
1658
1689
|
if (!existing) throw new Error(`PROCESS_NOT_FOUND: ${processId}`);
|
|
1659
|
-
if (existing.terminalWritten)
|
|
1690
|
+
if (existing.terminalWritten) {
|
|
1691
|
+
return recordToHandle(reconcileObservedTerminalProcess(controllerHome, repoId, existing), { completed: true });
|
|
1692
|
+
}
|
|
1660
1693
|
|
|
1661
1694
|
const monitor = liveMonitors.get(processId);
|
|
1662
1695
|
if (monitor) {
|
|
1663
1696
|
const waitMs = options.timeoutMs ?? existing.timeoutMs;
|
|
1664
1697
|
const done = await new Promise<ManagedProcessRecord | 'timeout'>((resolve) => {
|
|
1665
|
-
const
|
|
1698
|
+
const finish = (record: ManagedProcessRecord | 'timeout') => {
|
|
1699
|
+
clearTimeout(timer);
|
|
1700
|
+
options.signal?.removeEventListener('abort', onAbort);
|
|
1701
|
+
const index = monitor.waiters.indexOf(finish);
|
|
1702
|
+
if (index >= 0) monitor.waiters.splice(index, 1);
|
|
1703
|
+
resolve(record);
|
|
1704
|
+
};
|
|
1705
|
+
const timer = setTimeout(() => finish('timeout'), Math.max(1, waitMs));
|
|
1666
1706
|
timer.unref?.();
|
|
1667
1707
|
const onAbort = () => {
|
|
1668
1708
|
clearTimeout(timer);
|
|
1669
1709
|
void cancelProcess(controllerHome, repoId, processId).then(() => {
|
|
1670
1710
|
const current = getProcessRecord(controllerHome, repoId, processId);
|
|
1671
|
-
if (current)
|
|
1672
|
-
else
|
|
1711
|
+
if (current) finish(current);
|
|
1712
|
+
else finish('timeout');
|
|
1673
1713
|
});
|
|
1674
1714
|
};
|
|
1675
1715
|
options.signal?.addEventListener('abort', onAbort, { once: true });
|
|
1676
|
-
monitor.waiters.push(
|
|
1677
|
-
clearTimeout(timer);
|
|
1678
|
-
options.signal?.removeEventListener('abort', onAbort);
|
|
1679
|
-
resolve(record);
|
|
1680
|
-
});
|
|
1716
|
+
monitor.waiters.push(finish);
|
|
1681
1717
|
if (monitor.settled) {
|
|
1682
1718
|
const current = getProcessRecord(controllerHome, repoId, processId);
|
|
1683
1719
|
if (current?.terminalWritten) {
|
|
1684
|
-
|
|
1685
|
-
resolve(current);
|
|
1720
|
+
finish(current);
|
|
1686
1721
|
}
|
|
1687
1722
|
}
|
|
1688
1723
|
});
|
|
@@ -1744,7 +1779,9 @@ export async function cancelProcess(
|
|
|
1744
1779
|
): Promise<ProcessHandle> {
|
|
1745
1780
|
const record = getProcessRecord(controllerHome, repoId, processId);
|
|
1746
1781
|
if (!record) throw new Error(`PROCESS_NOT_FOUND: ${processId}`);
|
|
1747
|
-
if (record.terminalWritten)
|
|
1782
|
+
if (record.terminalWritten) {
|
|
1783
|
+
return recordToHandle(reconcileObservedTerminalProcess(controllerHome, repoId, record), { completed: true });
|
|
1784
|
+
}
|
|
1748
1785
|
|
|
1749
1786
|
// Process control is itself a writer mutation. Fence BEFORE sending any
|
|
1750
1787
|
// signal so a passive/stale runtime cannot kill the active runtime's work.
|
|
@@ -19,6 +19,8 @@ import { basename, dirname, join } from 'path';
|
|
|
19
19
|
import { ensureRepositoryControllerLayout, repositoryControllerRoot } from '../../../cli/repositories/controller-home';
|
|
20
20
|
import { mutateControlPlaneRecord, readOrImportControlPlaneRecord } from '../../control-plane/persistence/sqlite-store';
|
|
21
21
|
import { isSensitiveOutputKey, redactSensitiveText } from '../../evidence/sensitive-output';
|
|
22
|
+
import { touchSchedulerWakeSignal } from '../../control-plane/global-scheduler/wake-signal';
|
|
23
|
+
import { isRepositoryProcessScopeKey, legacyWorkspaceScopeRoot, processScopeRoot } from './process-scope';
|
|
22
24
|
import {
|
|
23
25
|
isManagedProcessActive,
|
|
24
26
|
isManagedProcessTerminal,
|
|
@@ -30,7 +32,12 @@ import {
|
|
|
30
32
|
} from './types';
|
|
31
33
|
|
|
32
34
|
function processesRoot(controllerHome: string, repoId: string): string {
|
|
33
|
-
|
|
35
|
+
// Repository scopes keep the established per-repository layout. Instance and
|
|
36
|
+
// workspace scopes own sibling partitions so a non-repository process never
|
|
37
|
+
// needs a synthetic repository identity or repository storage.
|
|
38
|
+
const root = isRepositoryProcessScopeKey(repoId)
|
|
39
|
+
? ensureRepositoryControllerLayout(controllerHome, repoId)
|
|
40
|
+
: processScopeRoot(controllerHome, repoId);
|
|
34
41
|
const dir = join(root, 'processes');
|
|
35
42
|
mkdirSync(dir, { recursive: true });
|
|
36
43
|
mkdirSync(join(dir, 'logs'), { recursive: true });
|
|
@@ -522,7 +529,13 @@ export function getProcessRecord(
|
|
|
522
529
|
repoId: string,
|
|
523
530
|
processId: string,
|
|
524
531
|
): ManagedProcessRecord | undefined {
|
|
525
|
-
|
|
532
|
+
const current = readProcessRecord(processPath(controllerHome, repoId, processId));
|
|
533
|
+
if (current) return current;
|
|
534
|
+
// Bounded migration read: workspace processes written before the workspace
|
|
535
|
+
// partition existed are still attachable instead of being reported missing.
|
|
536
|
+
const legacyRoot = legacyWorkspaceScopeRoot(controllerHome, repoId);
|
|
537
|
+
if (!legacyRoot) return undefined;
|
|
538
|
+
return readProcessRecord(join(legacyRoot, 'processes', `${processId}.json`));
|
|
526
539
|
}
|
|
527
540
|
|
|
528
541
|
/**
|
|
@@ -559,6 +572,21 @@ export function tryCompleteProcessRecord(
|
|
|
559
572
|
const sanitized = sanitizeProcessRecord(next).record;
|
|
560
573
|
atomicWrite(path, sanitized);
|
|
561
574
|
updateRecoveryIndexMembership(controllerHome, repoId, processId, processRecoveryMembership(sanitized));
|
|
575
|
+
// Terminal Process persistence remains the lifecycle authority. The scheduler
|
|
576
|
+
// notification is emitted only after durable terminal state exists, and only
|
|
577
|
+
// for Check-backed Processes whose receipts can unblock Work/Edit validation.
|
|
578
|
+
// Notification failure must never reinterpret or roll back the terminal CAS;
|
|
579
|
+
// the explicit schedule deadline still provides a bounded observation path.
|
|
580
|
+
if (sanitized.checkExecution || sanitized.origin?.surface === 'check' || sanitized.origin?.checkId) {
|
|
581
|
+
try {
|
|
582
|
+
touchSchedulerWakeSignal(controllerHome, `check-process-terminal:${processId}`);
|
|
583
|
+
} catch (error) {
|
|
584
|
+
console.error(
|
|
585
|
+
`[forge scheduler] Check Process terminal wake failed for ${processId}:`,
|
|
586
|
+
error instanceof Error ? error.message : String(error),
|
|
587
|
+
);
|
|
588
|
+
}
|
|
589
|
+
}
|
|
562
590
|
return { ok: true, record: sanitized };
|
|
563
591
|
}
|
|
564
592
|
|
|
@@ -17,7 +17,6 @@ export interface ExecutionConcurrencyWaitProjection {
|
|
|
17
17
|
wakeTrigger:
|
|
18
18
|
| { kind: 'work_terminal'; workId: string }
|
|
19
19
|
| { kind: 'resource_release'; resourceKeys: string[] }
|
|
20
|
-
| { kind: 'controller_release'; workId: string }
|
|
21
20
|
| { kind: 'scheduler_capacity'; capacityKey: string }
|
|
22
21
|
| { kind: 'work_contract_change'; workId: string };
|
|
23
22
|
observedAt: string;
|
|
@@ -186,6 +185,8 @@ export interface ManagedProcessRecord {
|
|
|
186
185
|
processId: string;
|
|
187
186
|
repoId: string;
|
|
188
187
|
checkoutId?: string;
|
|
188
|
+
/** Authenticated principal that owns the handle; opaque ids never authorize by themselves. */
|
|
189
|
+
principalId?: string;
|
|
189
190
|
/** Optional facade WorkContract that owns this command. */
|
|
190
191
|
workId?: string;
|
|
191
192
|
/** Immutable pre-spawn authority required for post-terminal Work reconciliation. */
|
|
@@ -288,6 +289,8 @@ export interface SpawnManagedProcessInput {
|
|
|
288
289
|
controllerHome: string;
|
|
289
290
|
repoId: string;
|
|
290
291
|
checkoutId?: string;
|
|
292
|
+
/** Authenticated principal recorded for principal-bound attachment. */
|
|
293
|
+
principalId?: string;
|
|
291
294
|
/** Immutable resolved execution identity — required; validated immediately before spawn. */
|
|
292
295
|
executionIdentity: ResolvedExecutionIdentity;
|
|
293
296
|
workId?: string;
|
|
@@ -306,6 +309,8 @@ export interface SpawnManagedProcessInput {
|
|
|
306
309
|
resourceClaims?: ProcessResourceClaim[];
|
|
307
310
|
checkExecution?: ProcessCheckExecutionIdentity;
|
|
308
311
|
origin?: ManagedProcessRecord['origin'];
|
|
312
|
+
/** Runtime-owned child allowed to rebind only the exact current Runtime write authority. */
|
|
313
|
+
trustedRuntimeChild?: 'plugin_action_sidecar';
|
|
309
314
|
runtimeInstanceId?: string;
|
|
310
315
|
releaseAuthorityRevision?: number;
|
|
311
316
|
releaseId?: string;
|
|
@@ -317,7 +317,7 @@ export function routeExecution(input: RouteExecutionInput): ExecutionDecision {
|
|
|
317
317
|
}
|
|
318
318
|
|
|
319
319
|
if (commandLooksDestructive(input.command) || operation.includes('destructive')) {
|
|
320
|
-
if (input.approvalContinuation === true && operation === '
|
|
320
|
+
if (input.approvalContinuation === true && operation === 'execute_command') {
|
|
321
321
|
return decisionBase({
|
|
322
322
|
mode: 'durable',
|
|
323
323
|
reasons: ['destructive_approval_continuation'],
|
|
@@ -325,7 +325,7 @@ export function routeExecution(input: RouteExecutionInput): ExecutionDecision {
|
|
|
325
325
|
estimatedClass: 'unknown',
|
|
326
326
|
requiresIsolation: true,
|
|
327
327
|
requiresRecovery: false,
|
|
328
|
-
suggestedOperation: '
|
|
328
|
+
suggestedOperation: 'execute_command through Durable Work / Local Job',
|
|
329
329
|
effects: {
|
|
330
330
|
readsWorkspace: true,
|
|
331
331
|
mutatesWorkspace: true,
|
|
@@ -342,7 +342,7 @@ export function routeExecution(input: RouteExecutionInput): ExecutionDecision {
|
|
|
342
342
|
requiresIsolation: true,
|
|
343
343
|
requiresRecovery: false,
|
|
344
344
|
rejectCode: 'DESTRUCTIVE_REJECTED',
|
|
345
|
-
suggestedOperation: '
|
|
345
|
+
suggestedOperation: 'execute_command(dry_run=true) + explicit strong confirmation via Durable Work',
|
|
346
346
|
effects: {
|
|
347
347
|
readsWorkspace: true,
|
|
348
348
|
mutatesWorkspace: true,
|
|
@@ -381,7 +381,7 @@ export function routeExecution(input: RouteExecutionInput): ExecutionDecision {
|
|
|
381
381
|
|
|
382
382
|
let commandEffectsValue: ExecutionEffects | undefined;
|
|
383
383
|
|
|
384
|
-
if (operation === '
|
|
384
|
+
if (operation === 'execute_command' || operation === 'run_short_command' || operation === 'run_focused_check') {
|
|
385
385
|
if (input.command !== undefined) {
|
|
386
386
|
const classification = classifyRepositoryCommand(input.command, input.defaultBranch);
|
|
387
387
|
const canonical = normalizeRepositoryCommand(input.command);
|
|
@@ -401,7 +401,7 @@ export function routeExecution(input: RouteExecutionInput): ExecutionDecision {
|
|
|
401
401
|
requiresIsolation: true,
|
|
402
402
|
requiresRecovery: false,
|
|
403
403
|
rejectCode: 'UNSAFE_SHELL',
|
|
404
|
-
suggestedOperation: '
|
|
404
|
+
suggestedOperation: 'execute_command(dry_run=true)',
|
|
405
405
|
effects: commandEffectsValue,
|
|
406
406
|
}, operation);
|
|
407
407
|
}
|
|
@@ -411,7 +411,7 @@ export function routeExecution(input: RouteExecutionInput): ExecutionDecision {
|
|
|
411
411
|
}
|
|
412
412
|
if (classification.risk === 'remote_write') reasons.push('command_classified_remote_write');
|
|
413
413
|
if (classification.risk === 'destructive') {
|
|
414
|
-
if (input.approvalContinuation === true && operation === '
|
|
414
|
+
if (input.approvalContinuation === true && operation === 'execute_command') {
|
|
415
415
|
return decisionBase({
|
|
416
416
|
mode: 'durable',
|
|
417
417
|
reasons: ['destructive_approval_continuation', ...classification.reasons],
|
|
@@ -419,7 +419,7 @@ export function routeExecution(input: RouteExecutionInput): ExecutionDecision {
|
|
|
419
419
|
estimatedClass: 'unknown',
|
|
420
420
|
requiresIsolation: true,
|
|
421
421
|
requiresRecovery: false,
|
|
422
|
-
suggestedOperation: '
|
|
422
|
+
suggestedOperation: 'execute_command through Durable Work / Local Job',
|
|
423
423
|
effects: commandEffectsValue,
|
|
424
424
|
}, operation);
|
|
425
425
|
}
|
|
@@ -431,7 +431,7 @@ export function routeExecution(input: RouteExecutionInput): ExecutionDecision {
|
|
|
431
431
|
requiresIsolation: true,
|
|
432
432
|
requiresRecovery: false,
|
|
433
433
|
rejectCode: 'DESTRUCTIVE_COMMAND',
|
|
434
|
-
suggestedOperation: '
|
|
434
|
+
suggestedOperation: 'execute_command(dry_run=true)',
|
|
435
435
|
effects: commandEffectsValue,
|
|
436
436
|
}, operation);
|
|
437
437
|
}
|
|
@@ -440,14 +440,14 @@ export function routeExecution(input: RouteExecutionInput): ExecutionDecision {
|
|
|
440
440
|
reasons.push('not_a_strict_focused_check');
|
|
441
441
|
}
|
|
442
442
|
if (classification.risk === 'workspace_write' && !focused && !safeShellCombo) {
|
|
443
|
-
if (operation === '
|
|
443
|
+
if (operation === 'execute_command' || operation === 'run_short_command' || operation === 'run_focused_check') {
|
|
444
444
|
reasons.push('mutating_or_unfocused_command');
|
|
445
445
|
}
|
|
446
446
|
}
|
|
447
447
|
if (classification.risk !== 'readonly' && !focused && !safeShellCombo && !FAST_OPERATIONS.has(operation)) {
|
|
448
448
|
reasons.push('untrusted_or_unclassified_command');
|
|
449
449
|
}
|
|
450
|
-
} else if (operation === '
|
|
450
|
+
} else if (operation === 'execute_command' || operation === 'run_focused_check') {
|
|
451
451
|
reasons.push('missing_command');
|
|
452
452
|
}
|
|
453
453
|
}
|
|
@@ -564,7 +564,7 @@ export function routeExecution(input: RouteExecutionInput): ExecutionDecision {
|
|
|
564
564
|
}, operation);
|
|
565
565
|
}
|
|
566
566
|
|
|
567
|
-
if (!FAST_OPERATIONS.has(operation) && operation !== '
|
|
567
|
+
if (!FAST_OPERATIONS.has(operation) && operation !== 'execute_command') {
|
|
568
568
|
return decisionBase({
|
|
569
569
|
mode: 'durable',
|
|
570
570
|
reasons: ['operation_not_in_fast_allowlist'],
|
|
@@ -576,7 +576,7 @@ export function routeExecution(input: RouteExecutionInput): ExecutionDecision {
|
|
|
576
576
|
}, operation);
|
|
577
577
|
}
|
|
578
578
|
|
|
579
|
-
if (operation === '
|
|
579
|
+
if (operation === 'execute_command' || operation === 'run_short_command' || operation === 'run_focused_check') {
|
|
580
580
|
if (input.command === undefined) {
|
|
581
581
|
return decisionBase({
|
|
582
582
|
mode: 'durable',
|
|
@@ -585,7 +585,7 @@ export function routeExecution(input: RouteExecutionInput): ExecutionDecision {
|
|
|
585
585
|
estimatedClass: 'unknown',
|
|
586
586
|
requiresIsolation: false,
|
|
587
587
|
requiresRecovery: false,
|
|
588
|
-
suggestedOperation: '
|
|
588
|
+
suggestedOperation: 'execute_command via Durable Work',
|
|
589
589
|
}, operation);
|
|
590
590
|
}
|
|
591
591
|
const classification = classifyRepositoryCommand(input.command, input.defaultBranch);
|
|
@@ -602,7 +602,7 @@ export function routeExecution(input: RouteExecutionInput): ExecutionDecision {
|
|
|
602
602
|
estimatedClass: 'long',
|
|
603
603
|
requiresIsolation: false,
|
|
604
604
|
requiresRecovery: false,
|
|
605
|
-
suggestedOperation: '
|
|
605
|
+
suggestedOperation: 'execute_command via Durable Work / Local Job',
|
|
606
606
|
effects,
|
|
607
607
|
}, operation);
|
|
608
608
|
}
|
|
@@ -632,7 +632,7 @@ export function routeExecution(input: RouteExecutionInput): ExecutionDecision {
|
|
|
632
632
|
estimatedClass: 'long',
|
|
633
633
|
requiresIsolation: false,
|
|
634
634
|
requiresRecovery: false,
|
|
635
|
-
suggestedOperation: '
|
|
635
|
+
suggestedOperation: 'execute_command via Durable Work / Local Job',
|
|
636
636
|
effects,
|
|
637
637
|
}, operation);
|
|
638
638
|
}
|
|
@@ -673,7 +673,7 @@ export function routeExecution(input: RouteExecutionInput): ExecutionDecision {
|
|
|
673
673
|
function durableSuggestion(operation: string): string {
|
|
674
674
|
if (operation === 'run_check' || operation === 'run_focused_check') return 'run_check through Durable Work';
|
|
675
675
|
if (operation.includes('patch')) return 'repository_safe_patch_apply with apply_mode=async or Durable Work';
|
|
676
|
-
if (operation.includes('command')) return '
|
|
676
|
+
if (operation.includes('command')) return 'execute_command through Durable Work / Local Job';
|
|
677
677
|
if (operation.includes('agent') || operation === 'quick_agent_session') return 'quick_agent_session / dispatch_task';
|
|
678
678
|
return 'Durable Work (ExecutionJob path)';
|
|
679
679
|
}
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
previewRepositoryCommandExecutionAsync,
|
|
7
7
|
type RepositoryCommandSnapshot,
|
|
8
8
|
} from '../../../cli/repositories/command-executor';
|
|
9
|
-
import { getMcpPolicy } from '
|
|
9
|
+
import { getMcpPolicy } from '../../../../adapters/mcp/policy';
|
|
10
10
|
import { readRepositoryRange } from '../../../cli/repository/inspector';
|
|
11
11
|
import type { RepositoryRecord } from '../../../cli/repositories/types';
|
|
12
12
|
import { getLeaseSideEffectMetrics } from '../../resources/leases/store';
|
|
@@ -878,7 +878,7 @@ export async function executeFast(
|
|
|
878
878
|
} else if (
|
|
879
879
|
operation === 'run_short_command'
|
|
880
880
|
|| operation === 'run_focused_check'
|
|
881
|
-
|| operation === '
|
|
881
|
+
|| operation === 'execute_command'
|
|
882
882
|
) {
|
|
883
883
|
const command = request.input.command as string | string[];
|
|
884
884
|
const preview = await trace.measure('policyMs', async () => previewRepositoryCommandExecutionAsync(ctx.repository, {
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { isMainThread, parentPort, workerData, Worker } from 'worker_threads';
|
|
6
6
|
import { fileURLToPath } from 'url';
|
|
7
|
-
import { getMcpPolicy } from '
|
|
8
|
-
import type { McpPolicy } from '
|
|
7
|
+
import { getMcpPolicy } from '../../../../adapters/mcp/policy';
|
|
8
|
+
import type { McpPolicy } from '../../../../adapters/mcp/types';
|
|
9
9
|
import {
|
|
10
10
|
searchRepository,
|
|
11
11
|
searchRepositoryMany,
|
|
@@ -29,7 +29,6 @@ import { existsSync } from 'fs';
|
|
|
29
29
|
import { isAbsolute, relative, resolve, sep } from 'path';
|
|
30
30
|
import { isAssistantPluginError } from '../../plugins/errors';
|
|
31
31
|
import { executeWork, validateWork } from '../../control-plane/execution/work-operation-service';
|
|
32
|
-
import { finalizeWork } from '../../control-plane/execution/work-finalization-service';
|
|
33
32
|
import { describeFailure } from '../../../../packages/protocols/failure';
|
|
34
33
|
|
|
35
34
|
|
|
@@ -519,14 +518,12 @@ export async function executeExecutionJob(controllerHome: string, job: Execution
|
|
|
519
518
|
...context,
|
|
520
519
|
controllerHome,
|
|
521
520
|
explicitRepository: repository,
|
|
522
|
-
toolset:
|
|
523
|
-
toolsetLocked: true,
|
|
521
|
+
toolset: 'full',
|
|
524
522
|
};
|
|
525
523
|
// Durable Work mutations execute through control-plane application services.
|
|
526
524
|
// The Worker must never import MCP transport to obtain Work semantics.
|
|
527
525
|
const durableWorkOperation = job.payload.operation === 'work_execute'
|
|
528
|
-
|| job.payload.operation === 'work_validate'
|
|
529
|
-
|| job.payload.operation === 'work_finalize';
|
|
526
|
+
|| job.payload.operation === 'work_validate';
|
|
530
527
|
const toolArguments = { ...(job.payload.arguments ?? {}) };
|
|
531
528
|
const workArguments = {
|
|
532
529
|
...toolArguments,
|
|
@@ -537,9 +534,7 @@ export async function executeExecutionJob(controllerHome: string, job: Execution
|
|
|
537
534
|
? await executeWork(runtimeContext, workArguments)
|
|
538
535
|
: job.payload.operation === 'work_validate'
|
|
539
536
|
? await validateWork(runtimeContext, workArguments)
|
|
540
|
-
:
|
|
541
|
-
? await finalizeWork(runtimeContext, workArguments)
|
|
542
|
-
: undefined;
|
|
537
|
+
: undefined;
|
|
543
538
|
const executionResult: CallToolResult | undefined = durableWorkOperation && executionRecord
|
|
544
539
|
? { structuredContent: executionRecord, content: [] }
|
|
545
540
|
: undefined;
|
|
@@ -88,12 +88,42 @@ function isSafeForgeTemp(path: string): boolean {
|
|
|
88
88
|
const name = basename(path);
|
|
89
89
|
if (!name.startsWith('forge')) return false;
|
|
90
90
|
const parent = dirname(path);
|
|
91
|
-
const allowedParents = new Set([
|
|
92
|
-
return allowedParents.has(
|
|
91
|
+
const allowedParents = new Set([tmpdir(), '/private/tmp', '/tmp'].filter((root) => existsSync(root)).map((root) => realpathSync(root)));
|
|
92
|
+
try { return allowedParents.has(realpathSync(parent)); } catch { return false; }
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Temp cleanup cannot dispose of a Git worktree just because its directory
|
|
96
|
+
// begins with "forge". Bounded traversal fails closed on nested repositories,
|
|
97
|
+
// symlinks and uninspectable or high-cardinality source.
|
|
98
|
+
function protectsGitSource(root: string): boolean {
|
|
99
|
+
const pending: Array<{ path: string; depth: number }> = [{ path: root, depth: 0 }];
|
|
100
|
+
let visited = 0;
|
|
101
|
+
while (pending.length > 0) {
|
|
102
|
+
const current = pending.pop()!;
|
|
103
|
+
if (++visited > 256) return true;
|
|
104
|
+
try {
|
|
105
|
+
const stat = lstatSync(current.path);
|
|
106
|
+
if (stat.isSymbolicLink()) return true;
|
|
107
|
+
if (!stat.isDirectory()) continue;
|
|
108
|
+
if (existsSync(join(current.path, '.git'))
|
|
109
|
+
|| (existsSync(join(current.path, 'HEAD')) && existsSync(join(current.path, 'objects')) && existsSync(join(current.path, 'refs')))) return true;
|
|
110
|
+
const entries = readdirSync(current.path, { withFileTypes: true });
|
|
111
|
+
if (entries.length + visited > 256) return true;
|
|
112
|
+
for (const entry of entries) {
|
|
113
|
+
if (entry.isSymbolicLink()) return true;
|
|
114
|
+
if (!entry.isDirectory()) continue;
|
|
115
|
+
if (current.depth >= 5) return true;
|
|
116
|
+
pending.push({ path: join(current.path, entry.name), depth: current.depth + 1 });
|
|
117
|
+
}
|
|
118
|
+
} catch {
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return false;
|
|
93
123
|
}
|
|
94
124
|
|
|
95
125
|
function scanTempDirs(minAgeMinutes: number, limit: number): RuntimeCleanupCandidate[] {
|
|
96
|
-
const roots = Array.from(new Set([tmpdir(), '/private/tmp', '/tmp'].filter((root) => existsSync(root)).map((root) =>
|
|
126
|
+
const roots = Array.from(new Set([tmpdir(), '/private/tmp', '/tmp'].filter((root) => existsSync(root)).map((root) => realpathSync(root))));
|
|
97
127
|
const processes = processCommands();
|
|
98
128
|
const at = Date.now();
|
|
99
129
|
const candidates: RuntimeCleanupCandidate[] = [];
|
|
@@ -108,11 +138,14 @@ function scanTempDirs(minAgeMinutes: number, limit: number): RuntimeCleanupCandi
|
|
|
108
138
|
if (!stat.isDirectory()) continue;
|
|
109
139
|
const occupied = processes.find((process) => process.command.includes(path));
|
|
110
140
|
const ageMinutes = Math.max(0, Math.round((at - stat.mtimeMs) / 60_000));
|
|
111
|
-
const
|
|
141
|
+
const gitSourceProtected = protectsGitSource(path);
|
|
142
|
+
const safe = !occupied && ageMinutes >= minAgeMinutes && !gitSourceProtected;
|
|
112
143
|
candidates.push({
|
|
113
144
|
kind: 'temp_dir',
|
|
114
145
|
path,
|
|
115
|
-
reason:
|
|
146
|
+
reason: gitSourceProtected
|
|
147
|
+
? 'Git worktree, repository, symlink or uninspectable source is protected; use its Work/Git owner.'
|
|
148
|
+
: safe
|
|
116
149
|
? `Forge temp directory is older than ${minAgeMinutes} minutes and not referenced by a running process.`
|
|
117
150
|
: 'Temp directory is too new or still referenced by a running process.',
|
|
118
151
|
ageMinutes,
|
|
@@ -368,6 +401,9 @@ export function applyRuntimeCleanup(repoRoot: string, options: RuntimeCleanupOpt
|
|
|
368
401
|
const applied: Array<RuntimeCleanupCandidate & { applied: boolean; error?: string }> = eligible.slice(0, normalized.maxRemovals).map((candidate) => {
|
|
369
402
|
try {
|
|
370
403
|
if (candidate.kind === 'temp_dir' && candidate.path && isSafeForgeTemp(candidate.path)) {
|
|
404
|
+
// A preview is not a mutation lease. Recheck source and liveness.
|
|
405
|
+
if (protectsGitSource(candidate.path)) throw new Error('RUNTIME_CLEANUP_GIT_SOURCE_PROTECTED');
|
|
406
|
+
if (processCommands().some((process) => process.command.includes(candidate.path!))) throw new Error('RUNTIME_CLEANUP_TEMP_PROCESS_OCCUPIED');
|
|
371
407
|
rmSync(candidate.path, { recursive: true, force: true });
|
|
372
408
|
return { ...candidate, applied: true };
|
|
373
409
|
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { createHash } from 'crypto';
|
|
2
|
+
import { resolve } from 'path';
|
|
3
|
+
import type { PlatformServiceManagerHost } from './service-manager';
|
|
4
|
+
|
|
5
|
+
export type ForgePersistentServiceOwner = 'forge-core' | 'provider';
|
|
6
|
+
export type ForgePersistentServiceState = 'current' | 'retired';
|
|
7
|
+
|
|
8
|
+
export interface ForgePersistentServiceIdentity {
|
|
9
|
+
id: string;
|
|
10
|
+
owner: ForgePersistentServiceOwner;
|
|
11
|
+
state: ForgePersistentServiceState;
|
|
12
|
+
launchdLabel: string;
|
|
13
|
+
systemdUnitName: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const FORGE_RECOVERY_DAEMON_LABEL = 'com.moretea.forge-recovery';
|
|
17
|
+
export const FORGE_RECOVERY_GATEWAY_LABEL = 'com.moretea.forge-recovery-gateway';
|
|
18
|
+
export const FORGE_RECOVERY_WATCHDOG_LABEL = 'com.moretea.forge-recovery-watchdog';
|
|
19
|
+
|
|
20
|
+
const RETIRED_CORE_LABELS = [
|
|
21
|
+
['legacy-runtime', 'com.moretea.forge.runtime'],
|
|
22
|
+
['legacy-mcp-gateway', 'com.moretea.forge.mcp-gateway'],
|
|
23
|
+
['bootstrap-supervisor', 'com.moretea.forge-bootstrap-supervisor'],
|
|
24
|
+
['evolution-supervisor', 'com.moretea.forge-evolution-supervisor'],
|
|
25
|
+
['legacy-recovery-gateway', FORGE_RECOVERY_GATEWAY_LABEL],
|
|
26
|
+
['legacy-recovery-watchdog', FORGE_RECOVERY_WATCHDOG_LABEL],
|
|
27
|
+
] as const;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* These identities are intentionally outside Forge core lifecycle authority.
|
|
31
|
+
* They are listed to make the negative ownership boundary machine-visible,
|
|
32
|
+
* not to authorize any retirement action.
|
|
33
|
+
*/
|
|
34
|
+
export const FORGE_PROVIDER_OWNED_PERSISTENT_SERVICES = [
|
|
35
|
+
'com.moretea.forge.desktop-operator',
|
|
36
|
+
'com.moretea.desktop-operator',
|
|
37
|
+
] as const;
|
|
38
|
+
|
|
39
|
+
function controllerHomeSuffix(controllerHome: string): string {
|
|
40
|
+
return createHash('sha256').update(resolve(controllerHome)).digest('hex').slice(0, 12);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function forgeRuntimePersistentServiceLabel(controllerHome: string): string {
|
|
44
|
+
return `com.moretea.forge.runtime.${controllerHomeSuffix(controllerHome)}`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function forgeConnectorPersistentServiceLabel(controllerHome: string): string {
|
|
48
|
+
return `com.moretea.forge.mcp-gateway.${controllerHomeSuffix(controllerHome)}`;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function identity(
|
|
52
|
+
id: string,
|
|
53
|
+
label: string,
|
|
54
|
+
state: ForgePersistentServiceState,
|
|
55
|
+
): ForgePersistentServiceIdentity {
|
|
56
|
+
return {
|
|
57
|
+
id,
|
|
58
|
+
owner: 'forge-core',
|
|
59
|
+
state,
|
|
60
|
+
launchdLabel: label,
|
|
61
|
+
systemdUnitName: `${label}.service`,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export const FORGE_RETIRED_PERSISTENT_SERVICES: readonly ForgePersistentServiceIdentity[] =
|
|
66
|
+
RETIRED_CORE_LABELS.map(([id, label]) => identity(id, label, 'retired'));
|
|
67
|
+
|
|
68
|
+
export function forgeOwnedPersistentServiceInventory(controllerHome: string): {
|
|
69
|
+
current: ForgePersistentServiceIdentity[];
|
|
70
|
+
retired: readonly ForgePersistentServiceIdentity[];
|
|
71
|
+
providerOwnedExcludedLabels: readonly string[];
|
|
72
|
+
} {
|
|
73
|
+
return {
|
|
74
|
+
current: [
|
|
75
|
+
identity('runtime', forgeRuntimePersistentServiceLabel(controllerHome), 'current'),
|
|
76
|
+
identity('mcp-gateway', forgeConnectorPersistentServiceLabel(controllerHome), 'current'),
|
|
77
|
+
identity('recovery', FORGE_RECOVERY_DAEMON_LABEL, 'current'),
|
|
78
|
+
],
|
|
79
|
+
retired: FORGE_RETIRED_PERSISTENT_SERVICES,
|
|
80
|
+
providerOwnedExcludedLabels: FORGE_PROVIDER_OWNED_PERSISTENT_SERVICES,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface ForgeRetiredServiceReconciliation {
|
|
85
|
+
id: string;
|
|
86
|
+
label: string;
|
|
87
|
+
platform: 'launchd' | 'systemd-user';
|
|
88
|
+
serviceWasPresent: boolean;
|
|
89
|
+
artifactWasPresent: boolean;
|
|
90
|
+
retired: boolean;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export async function reconcileRetiredForgePersistentServices(input: {
|
|
94
|
+
host: PlatformServiceManagerHost;
|
|
95
|
+
env?: NodeJS.ProcessEnv;
|
|
96
|
+
accountHome?: string;
|
|
97
|
+
}): Promise<ForgeRetiredServiceReconciliation[]> {
|
|
98
|
+
if (!input.host.selection.persistent || input.host.selection.kind === 'portable') return [];
|
|
99
|
+
const results: ForgeRetiredServiceReconciliation[] = [];
|
|
100
|
+
for (const service of FORGE_RETIRED_PERSISTENT_SERVICES) {
|
|
101
|
+
if (input.host.selection.kind === 'launchd') {
|
|
102
|
+
const result = await input.host.retireLaunchdExact({
|
|
103
|
+
label: service.launchdLabel,
|
|
104
|
+
accountHome: input.accountHome,
|
|
105
|
+
});
|
|
106
|
+
results.push({
|
|
107
|
+
id: service.id,
|
|
108
|
+
label: service.launchdLabel,
|
|
109
|
+
platform: 'launchd',
|
|
110
|
+
serviceWasPresent: result.serviceWasPresent,
|
|
111
|
+
artifactWasPresent: result.plistWasPresent,
|
|
112
|
+
retired: result.absentAfter,
|
|
113
|
+
});
|
|
114
|
+
} else {
|
|
115
|
+
const result = input.host.retireSystemdUserExact({
|
|
116
|
+
unitName: service.systemdUnitName,
|
|
117
|
+
env: input.env,
|
|
118
|
+
});
|
|
119
|
+
results.push({
|
|
120
|
+
id: service.id,
|
|
121
|
+
label: service.systemdUnitName,
|
|
122
|
+
platform: 'systemd-user',
|
|
123
|
+
serviceWasPresent: result.serviceWasPresent,
|
|
124
|
+
artifactWasPresent: result.unitFileWasPresent,
|
|
125
|
+
retired: result.absentAfter,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return results;
|
|
130
|
+
}
|