@moretea-labs/forge 1.6.0 → 1.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +4 -0
- package/CHANGELOG.md +39 -0
- package/CLAUDE.md +4 -0
- package/README.md +2 -2
- package/README.zh-CN.md +1 -1
- package/SKILL.md +2 -2
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/agents/openai.yaml +1 -1
- package/assets/hooks/hook-input.sh +11 -8
- package/assets/hooks/lib/session-state.sh +10 -7
- package/assets/hooks/lib/workflow-state.sh +13 -177
- package/assets/hooks/post-tool-observer.sh +8 -2
- package/assets/hooks/prompt-guard.sh +5 -81
- package/assets/hooks/session-start-context.sh +56 -1
- package/assets/partials/05-workflow.partial.md +1 -1
- package/assets/partials-agents/02-operating-mode.partial.md +2 -0
- package/assets/partials-agents/03-orchestration.partial.md +1 -1
- package/assets/plugin-registry.v1.json +3 -3
- package/assets/reference-configs/document-generation.md +1 -1
- package/assets/reference-configs/harness-overview.md +1 -1
- package/assets/reference-configs/sprint-contracts.md +3 -3
- package/assets/skill-version.json +2 -2
- package/assets/templates/contract.template.md +2 -7
- package/assets/templates/helpers/capture-plan.sh +2 -2
- package/assets/templates/helpers/check-architecture-sync.sh +17 -0
- package/assets/templates/helpers/check-task-workflow.sh +4 -4
- package/assets/templates/helpers/contract-worktree.sh +1 -21
- package/assets/templates/helpers/ensure-task-workflow.sh +11 -36
- package/assets/templates/helpers/inspect-project-state.ts +8 -6
- package/assets/templates/helpers/migrate-project-template.sh +22 -45
- package/assets/templates/helpers/migrate-workflow-docs.ts +9 -7
- package/assets/templates/helpers/new-plan.sh +1 -1
- package/assets/templates/helpers/plan-to-todo.sh +12 -37
- package/assets/templates/helpers/ship-worktrees.sh +2 -29
- package/assets/templates/helpers/verify-contract.sh +1 -111
- package/assets/templates/helpers/verify-sprint.sh +3 -180
- package/assets/templates/helpers/workflow-contract.ts +5 -1
- package/assets/templates/plan.template.md +1 -1
- package/assets/templates/review.template.md +9 -34
- package/assets/workflow-contract.v1.json +10 -19
- package/docs/README.md +10 -10
- package/docs/architecture/CURRENT.md +178 -0
- package/docs/architecture/EVOLUTION.md +42 -0
- package/docs/architecture/current/README.md +4 -156
- package/docs/architecture/decisions/20260803-release-identity-binding-and-exit-policy.md +2 -2
- package/docs/architecture/decisions/20260823-immediate-controller-relay.md +53 -0
- package/docs/architecture/decisions/20260826-browser-runtime-v2.md +73 -0
- package/docs/architecture/history/README.md +7 -0
- package/docs/architecture/{chatgpt-handoff-facade.md → history/chatgpt-handoff-facade.md} +4 -0
- package/docs/architecture/{global-hook-runtime.md → history/global-hook-runtime.md} +7 -3
- package/docs/architecture/{ios-semantic-automation-provider-v2.md → history/ios-semantic-automation-provider-v2.md} +6 -2
- package/docs/architecture/history.md +3 -34
- package/docs/architecture/index.md +15 -98
- package/docs/architecture/modules/controller-runtime/transport-lifecycle.md +1 -1
- package/docs/architecture/reviews/2026-08-22-semantic-harness-convergence-acceptance.md +39 -0
- package/docs/architecture/versions/1.6.md +38 -0
- package/docs/architecture/versions/1.7.md +41 -0
- package/docs/forge-chatgpt-browser-engine.md +2 -2
- package/docs/forge-chatgpt-mcp-setup.md +4 -28
- package/docs/forge-chatgpt-supervised-automation.md +3 -3
- package/docs/forge-github-issue-launcher.md +1 -1
- package/docs/forge-plugin-management.md +1 -1
- package/docs/forge-runtime-self-healing-loop.md +1 -1
- package/docs/operations/controller-browser-plugin.md +26 -6
- package/docs/operations/controller-performance-and-502.md +143 -0
- package/docs/operations/controller-reliability-runbook.md +1 -1
- package/docs/operations/features.md +2 -2
- package/docs/operations/github-repository.md +1 -1
- package/docs/operations/homebrew.md +2 -2
- package/docs/operations/mcp-tool-exposure.md +5 -3
- package/docs/wiki/Architecture.md +6 -6
- package/docs/wiki/Implementation.md +2 -2
- package/docs/wiki/Integrations.md +2 -2
- package/docs/wiki/Work-Lifecycle.md +1 -1
- package/package.json +33 -11
- package/scripts/activate-source-baseline.ts +17 -13
- package/scripts/architecture-event.ts +2 -820
- package/scripts/architecture-queue.sh +2 -645
- package/scripts/archive-architecture-request.sh +2 -242
- package/scripts/archive-workflow.sh +1 -291
- package/scripts/benchmark-background-check-overlap.ts +228 -0
- package/scripts/benchmark-mcp-host.sh +117 -0
- package/scripts/benchmark-mcp-transport.ts +170 -0
- package/scripts/benchmark-quality-harness.ts +146 -0
- package/scripts/benchmark-route-session-concurrency.ts +207 -6
- package/scripts/benchmark-thin-harness-mcp-e2e.ts +7 -1
- package/scripts/benchmark-typescript-navigation.ts +186 -0
- package/scripts/benchmark-work-efficiency.ts +334 -0
- package/scripts/capability-config.ts +2 -392
- package/scripts/capability-resolver.ts +2 -503
- package/scripts/capture-plan.sh +1 -332
- package/scripts/check-agent-tooling.sh +2 -1558
- package/scripts/check-architecture-sync.sh +2 -371
- package/scripts/check-brain-manifest.sh +2 -253
- package/scripts/check-context-files.sh +2 -47
- package/scripts/check-deploy-sql-order.sh +2 -115
- package/scripts/check-mcp-compatibility.ts +14 -0
- package/scripts/check-runtime-architecture.mjs +349 -79
- package/scripts/check-skill-version.ts +3 -191
- package/scripts/check-source-duplication.mjs +61 -0
- package/scripts/check-stable-baseline.ts +92 -0
- package/scripts/check-task-sync.sh +2 -63
- package/scripts/check-task-workflow.sh +2 -1000
- package/scripts/codex-handoff-resume.sh +2 -267
- package/scripts/context-contract-sync.sh +2 -514
- package/scripts/contract-run.ts +2 -463
- package/scripts/contract-worktree.sh +1 -722
- package/scripts/ensure-task-workflow.sh +1 -1225
- package/scripts/host-temporary-cloud-mcp-e2e.sh +265 -0
- package/scripts/inspect-project-state.ts +4 -279
- package/scripts/install-standalone-recovery.ts +24 -0
- package/scripts/lib/project-init-lib.sh +22 -46
- package/scripts/lib/run-forge-helper.sh +19 -0
- package/scripts/lib/run-forge-helper.ts +26 -0
- package/scripts/migrate-project-template.sh +1 -1189
- package/scripts/migrate-workflow-docs.ts +4 -412
- package/scripts/new-plan.sh +1 -180
- package/scripts/new-spec.sh +1 -47
- package/scripts/new-sprint.sh +1 -46
- package/scripts/plan-to-todo.sh +1 -796
- package/scripts/prepare-codex-handoff.sh +2 -201
- package/scripts/prepare-handoff.sh +1 -78
- package/scripts/refresh-current-status.sh +2 -467
- package/scripts/run-governed-gate.ts +5 -1
- package/scripts/select-agent-context-blocks.sh +2 -64
- package/scripts/ship-worktrees.sh +1 -558
- package/scripts/smoke-ios-physical-device.ts +4 -2
- package/scripts/smoke-runtime-recovery.ts +1 -35
- package/scripts/smoke-schedule-engine.ts +1 -20
- package/scripts/sprint-backlog.sh +1 -834
- package/scripts/stage-runtime-release.ts +2 -1
- package/scripts/summarize-failures.sh +2 -123
- package/scripts/switch-plan.sh +1 -150
- package/scripts/sync-brain-docs.sh +2 -379
- package/scripts/sync-generated-authority.mjs +175 -0
- package/scripts/verify-contract.sh +2 -703
- package/scripts/verify-forge-runtime.sh +0 -1
- package/scripts/verify-sprint.sh +1 -677
- package/scripts/workflow-contract.ts +4 -205
- package/scripts/workstream-sync.sh +2 -261
- package/src/cli/agent-jobs/executor-health.ts +1 -1
- package/src/cli/commands/init-hook.ts +3 -3
- package/src/cli/commands/mcp.ts +9 -5
- package/src/cli/commands/plugin.ts +12 -3
- package/src/cli/commands/recovery.ts +25 -3
- package/src/cli/commands/runtime.ts +55 -3
- package/src/cli/commands/security.ts +12 -1
- package/src/cli/commands/setup-profile.ts +31 -21
- package/src/cli/controller/check-runner.ts +113 -5
- package/src/cli/controller/composite-result.ts +1 -1
- package/src/cli/controller/context/focus.ts +51 -0
- package/src/cli/controller/context/instruction-context.ts +114 -0
- package/src/cli/controller/context/known-paths.ts +76 -0
- package/src/cli/controller/context/query-planning.ts +110 -0
- package/src/cli/controller/context/rule-resolution.ts +532 -0
- package/src/cli/controller/context/source-materializer.ts +278 -0
- package/src/cli/controller/context/structural.ts +16 -0
- package/src/cli/controller/context/types.ts +286 -0
- package/src/cli/controller/context-pack.ts +828 -487
- package/src/cli/controller/launch-agents.ts +77 -2
- package/src/cli/controller/operational-plan.ts +2 -2
- package/src/cli/controller/work-mode.ts +6 -4
- package/src/cli/editing/edit-session.ts +60 -7
- package/src/cli/github/contracts.ts +16 -0
- package/src/cli/github/github.ts +135 -16
- package/src/cli/github/session.ts +2 -1
- package/src/cli/installer/managed-entries.ts +15 -1
- package/src/cli/local-bridge/console-automations.ts +54 -78
- package/src/cli/local-bridge/console-view-models.ts +1 -35
- package/src/cli/local-bridge/facade-api.ts +37 -264
- package/src/cli/local-bridge/frontend/src/App.tsx +3 -3
- package/src/cli/local-bridge/frontend/src/features/automations/AutomationsView.tsx +23 -13
- package/src/cli/local-bridge/frontend/src/features/capabilities/CapabilitiesView.tsx +37 -4
- package/src/cli/local-bridge/frontend/src/features/overview/OverviewView.tsx +6 -4
- package/src/cli/local-bridge/frontend/src/lib/api.ts +1 -6
- package/src/cli/local-bridge/frontend/src/lib/routes.ts +1 -1
- package/src/cli/local-bridge/frontend/src/shell/Sidebar.tsx +2 -2
- package/src/cli/local-bridge/frontend/src/styles.css +1 -1
- package/src/cli/local-bridge/frontend/src/types.ts +5 -8
- package/src/cli/local-bridge/job-store.ts +1 -490
- package/src/cli/local-bridge/server.ts +2 -515
- package/src/cli/local-bridge/ui-dist/app.css +1 -1
- package/src/cli/local-bridge/ui-dist/app.js +3703 -3757
- package/src/cli/mcp/auth.ts +5 -5
- package/src/cli/mcp/instructions.ts +3 -2
- package/src/cli/mcp/legacy-tool-service.ts +10 -222
- package/src/cli/mcp/multi-repository.ts +16 -5
- package/src/cli/mcp/oauth.ts +175 -26
- package/src/cli/mcp/post-finalize-work-attribution.ts +150 -0
- package/src/cli/mcp/repository-tools.ts +282 -146
- package/src/cli/mcp/server.ts +586 -116
- package/src/cli/mcp/tool-capability-cache.ts +1 -1
- package/src/cli/mcp/tool-contract.ts +14 -0
- package/src/cli/mcp/toolset-selection.ts +1 -1
- package/src/cli/mcp/toolset.ts +44 -7
- package/src/cli/mcp/transports/http.ts +124 -14
- package/src/cli/mcp/transports/session-registry.ts +43 -5
- package/src/cli/mcp/types.ts +3 -3
- package/src/cli/repositories/command-classifier.ts +103 -21
- package/src/cli/repositories/command-executor.ts +78 -526
- package/src/cli/repositories/command-process.ts +108 -0
- package/src/cli/repositories/command-scope.ts +99 -41
- package/src/cli/repositories/controller-home.ts +7 -8
- package/src/cli/repositories/git-command-executor.ts +2 -0
- package/src/cli/repositories/locks.ts +53 -16
- package/src/cli/repositories/repository-snapshot.ts +124 -0
- package/src/cli/repositories/selected-path-actions.ts +17 -9
- package/src/cli/repositories/structured-git.ts +118 -6
- package/src/cli/repository/inspector.ts +563 -65
- package/src/cli/repository/session-cache.ts +58 -17
- package/src/cli/v81-entry.ts +1 -4
- package/src/effects/fs-transaction.ts +85 -17
- package/src/runtime/context/codegraph-read-provider.ts +233 -2
- package/src/runtime/context/codegraph-sidecar.cjs +74 -40
- package/src/runtime/context/generic-lsp-provider.ts +355 -0
- package/src/runtime/context/lsp-client.ts +283 -0
- package/src/runtime/context/semantic-navigation-contract.ts +61 -0
- package/src/runtime/context/semantic-navigation.ts +223 -0
- package/src/runtime/context/swift-navigation.ts +565 -0
- package/src/runtime/context/typescript-navigation.ts +226 -0
- package/src/runtime/control-plane/dispatch-priority.ts +28 -0
- package/src/runtime/control-plane/execution/direct-edit-work-completion.ts +48 -16
- package/src/runtime/control-plane/execution/edit-validation-coordinator.ts +86 -24
- package/src/runtime/control-plane/execution/repository-work-attribution.ts +106 -0
- package/src/runtime/control-plane/execution/retained-work-resume.ts +203 -0
- package/src/runtime/control-plane/execution/session-store.ts +18 -0
- package/src/runtime/control-plane/execution/verification-evidence.ts +58 -3
- package/src/runtime/control-plane/execution/work-completion-authority.ts +58 -0
- package/src/runtime/control-plane/execution/work-evidence-policy.ts +200 -0
- package/src/runtime/control-plane/execution/work-execution-support.ts +386 -0
- package/src/runtime/control-plane/execution/work-finalization-service.ts +1913 -0
- package/src/runtime/control-plane/execution/work-handle-authority.ts +96 -0
- package/src/runtime/control-plane/execution/work-handle-store.ts +27 -2
- package/src/runtime/control-plane/execution/work-lifecycle-audit.ts +258 -0
- package/src/runtime/control-plane/execution/work-operation-service.ts +468 -0
- package/src/runtime/control-plane/execution/work-path-scope.ts +37 -0
- package/src/runtime/control-plane/execution/work-preparation-service.ts +479 -0
- package/src/runtime/control-plane/execution/work-process-evidence.ts +129 -0
- package/src/runtime/control-plane/execution/work-remote-delivery.ts +215 -0
- package/src/runtime/control-plane/execution/work-task-receipt.ts +22 -18
- package/src/runtime/control-plane/execution/work-terminal-cleanup.ts +156 -11
- package/src/runtime/control-plane/execution/work-validation-reconciler.ts +22 -14
- package/src/runtime/control-plane/execution/work-verification-context.ts +56 -0
- package/src/runtime/control-plane/execution/work-verification-service.ts +388 -0
- package/src/runtime/control-plane/execution/work-verification-snapshot.ts +90 -9
- package/src/runtime/control-plane/facade/capability-registry.ts +129 -25
- package/src/runtime/control-plane/facade/controller-round-relay.ts +1118 -0
- package/src/runtime/control-plane/facade/controller-session-store.ts +302 -12
- package/src/runtime/control-plane/facade/goal-workloop-access.ts +17 -1
- package/src/runtime/control-plane/facade/goal-workloop.ts +928 -190
- package/src/runtime/control-plane/facade/index.ts +3 -0
- package/src/runtime/control-plane/facade/plan-contract-store.ts +275 -42
- package/src/runtime/control-plane/facade/repository-work-admission.ts +147 -0
- package/src/runtime/control-plane/facade/requirement-authority.ts +83 -0
- package/src/runtime/control-plane/facade/semantic-admission.ts +205 -0
- package/src/runtime/control-plane/facade/suggested-actions.ts +5 -1
- package/src/runtime/control-plane/facade/types.ts +90 -10
- package/src/runtime/control-plane/facade/work-contract-store.ts +157 -261
- package/src/runtime/control-plane/facade/work-state-machine.ts +250 -0
- package/src/runtime/control-plane/generated-cache-retention.ts +271 -0
- package/src/runtime/control-plane/global-scheduler/config.ts +44 -0
- package/src/runtime/control-plane/global-scheduler/dispatch-capacity.ts +80 -0
- package/src/runtime/control-plane/global-scheduler/durable-admission.ts +46 -0
- package/src/runtime/control-plane/global-scheduler/maintenance.ts +152 -0
- package/src/runtime/control-plane/global-scheduler/projection-refresh.ts +84 -0
- package/src/runtime/control-plane/global-scheduler/reconciliation.ts +3 -3
- package/src/runtime/control-plane/global-scheduler/scheduler.ts +278 -543
- package/src/runtime/control-plane/global-scheduler/source-scan.ts +59 -0
- package/src/runtime/control-plane/global-scheduler/state.ts +88 -0
- package/src/runtime/control-plane/global-scheduler/worker-attachment.ts +57 -0
- package/src/runtime/control-plane/global-scheduler/worker-exit-decision.ts +38 -0
- package/src/runtime/control-plane/global-scheduler/worker-exit-reconciler.ts +175 -0
- package/src/runtime/control-plane/global-scheduler/worker-launch.ts +111 -0
- package/src/runtime/control-plane/global-scheduler/worker-lifecycle-store.ts +64 -0
- package/src/runtime/control-plane/global-scheduler/worker-lifecycle.ts +150 -0
- package/src/runtime/control-plane/global-scheduler/worker-process.ts +119 -0
- package/src/runtime/control-plane/global-scheduler/worker-stderr.ts +60 -0
- package/src/runtime/control-plane/launcher/chatgpt-work-binding-store.ts +63 -0
- package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +365 -117
- package/src/runtime/control-plane/launcher/launch-reservation-store.ts +89 -0
- package/src/runtime/control-plane/launcher/thin-launcher.ts +244 -11
- package/src/runtime/control-plane/persistence/controller-home-migration.ts +487 -0
- package/src/runtime/control-plane/persistence/requirement-store.ts +0 -12
- package/src/runtime/control-plane/persistence/sqlite-store.ts +33 -2
- package/src/runtime/control-plane/release-retention.ts +62 -2
- package/src/runtime/control-plane/repo-actor/registry.ts +4 -2
- package/src/runtime/control-plane/routing/route-policy.ts +24 -21
- package/src/runtime/control-plane/routing/workspace-admission.ts +70 -0
- package/src/runtime/control-plane/runtime-status-client.ts +0 -2
- package/src/runtime/diagnostics/mcp-timing.ts +13 -0
- package/src/runtime/diagnostics/mcp-transport-benchmark.ts +129 -0
- package/src/runtime/diagnostics/performance.ts +24 -1
- package/src/runtime/evidence/event-ledger.ts +1 -1
- package/src/runtime/evidence/process-check-execution.ts +18 -0
- package/src/runtime/execution/jobs/child-reference.ts +6 -2
- package/src/runtime/execution/jobs/store.ts +58 -4
- package/src/runtime/execution/jobs/types.ts +1 -1
- package/src/runtime/execution/managed-workspace.ts +203 -1
- package/src/runtime/execution/process-runtime/check-facade.ts +51 -4
- package/src/runtime/execution/process-runtime/check-result.ts +88 -0
- package/src/runtime/execution/process-runtime/check-runner-sidecar.ts +7 -1
- package/src/runtime/execution/process-runtime/check-scheduling.ts +114 -0
- package/src/runtime/execution/process-runtime/command-facade.ts +367 -40
- package/src/runtime/execution/process-runtime/gc.ts +38 -6
- package/src/runtime/execution/process-runtime/lightweight-managed.ts +1201 -0
- package/src/runtime/execution/process-runtime/persisted-check.ts +51 -5
- package/src/runtime/execution/process-runtime/resource-claims.ts +10 -6
- package/src/runtime/execution/process-runtime/runtime.ts +53 -3
- package/src/runtime/execution/process-runtime/store.ts +1 -0
- package/src/runtime/execution/process-runtime/types.ts +4 -12
- package/src/runtime/execution/thin-harness/async-process.ts +12 -2
- package/src/runtime/execution/thin-harness/search-worker.ts +54 -5
- package/src/runtime/execution/work-activity.ts +21 -0
- package/src/runtime/execution/workers/executor.ts +18 -61
- package/src/runtime/gateway/mcp/execution-tools.ts +35 -1852
- package/src/runtime/gateway/mcp/legacy-ios-tool-adapter.ts +61 -0
- package/src/runtime/gateway/mcp/process-tools.ts +83 -37
- package/src/runtime/gateway/mcp/router.ts +186 -84
- package/src/runtime/gateway/mcp/runtime-tool-definitions.ts +565 -0
- package/src/runtime/gateway/mcp/runtime-tools.ts +2378 -1947
- package/src/runtime/plugins/app-store-connect-adapter.ts +216 -47
- package/src/runtime/plugins/browser-adapter.ts +2662 -829
- package/src/runtime/plugins/browser-automation-service.ts +10 -0
- package/src/runtime/plugins/browser-handoff-host.ts +2 -25
- package/src/runtime/plugins/browser-handoff.ts +110 -5
- package/src/runtime/plugins/browser-macos-bridge.ts +701 -63
- package/src/runtime/plugins/browser-manifest-surface.ts +603 -0
- package/src/runtime/plugins/browser-native-session-service.ts +222 -0
- package/src/runtime/plugins/browser-node-bridge.ts +6 -34
- package/src/runtime/plugins/browser-provider-registry.ts +109 -0
- package/src/runtime/plugins/browser-runtime-contract.ts +154 -0
- package/src/runtime/plugins/browser-runtime.ts +193 -0
- package/src/runtime/plugins/browser-session-authority.ts +332 -0
- package/src/runtime/plugins/browser-session-store.ts +121 -0
- package/src/runtime/plugins/browser-session-types.ts +98 -0
- package/src/runtime/plugins/capability-authorization-grants.ts +354 -0
- package/src/runtime/plugins/desktop-operator-registration.ts +10 -4
- package/src/runtime/plugins/external-adapter.ts +358 -3
- package/src/runtime/plugins/external-unix-socket.ts +7 -1
- package/src/runtime/plugins/first-party-registry.ts +2 -0
- package/src/runtime/plugins/github-adapter.ts +125 -0
- package/src/runtime/plugins/ios/agent-device-provider.ts +1 -1
- package/src/runtime/plugins/ios/agent-device-typed-provider.ts +52 -9
- package/src/runtime/plugins/ios/remote-xpc-hid.ts +1171 -0
- package/src/runtime/plugins/ios-adapter.ts +106 -16
- package/src/runtime/plugins/ios-agent-device.ts +234 -64
- package/src/runtime/plugins/ios-physical-device.ts +1143 -392
- package/src/runtime/plugins/lightweight-action.ts +153 -0
- package/src/runtime/plugins/local-system-adapter.ts +123 -6
- package/src/runtime/plugins/macos-capability-broker.ts +47 -9
- package/src/runtime/plugins/plugin-action-sidecar.ts +59 -0
- package/src/runtime/plugins/plugin-management-adapter.ts +49 -8
- package/src/runtime/plugins/resend-adapter.ts +1 -1
- package/src/runtime/plugins/store.ts +330 -33
- package/src/runtime/plugins/types.ts +38 -3
- package/src/runtime/plugins/xiaohongshu-publish.ts +515 -0
- package/src/runtime/projections/git-status-sampler.ts +16 -16
- package/src/runtime/projections/materialized-view.ts +28 -10
- package/src/runtime/recovery/maintenance-executor.ts +426 -25
- package/src/runtime/root/mcp-transport.ts +180 -10
- package/src/runtime/root/package-connector-service.ts +230 -10
- package/src/runtime/root/package-runtime-release.ts +143 -17
- package/src/runtime/root/package-runtime-service.ts +461 -22
- package/src/runtime/root/release-manifest.ts +144 -18
- package/src/runtime/root/release-materialize.ts +125 -32
- package/src/runtime/root/release-store.ts +48 -11
- package/src/runtime/root/runtime.ts +23 -5
- package/src/runtime/root/service.ts +100 -29
- package/src/runtime/root/types.ts +12 -0
- package/src/runtime/safe-tooling/ios-development.ts +321 -63
- package/src/runtime/shared/trusted-executable.ts +62 -0
- package/src/runtime/shared/trusted-node-executable.ts +48 -0
- package/src/runtime/standalone-recovery/core.ts +1079 -240
- package/src/runtime/standalone-recovery/entry.ts +100 -24
- package/src/runtime/standalone-recovery/installer.ts +20 -4
- package/src/runtime/standalone-recovery/service-labels.ts +2 -0
- package/src/runtime/standalone-recovery/watchdog-heartbeat.ts +160 -0
- package/src/runtime/workflow/schedules/browser-probe.ts +81 -3
- package/src/runtime/workflow/schedules/engine.ts +364 -202
- package/src/runtime/workflow/schedules/github-issue-watch.ts +158 -0
- package/src/runtime/workflow/schedules/settlement.ts +64 -17
- package/src/runtime/workflow/schedules/store.ts +209 -19
- package/src/runtime/workflow/schedules/types.ts +2 -4
- package/src/runtime/workflow/schedules/work-continuation.ts +26 -13
- package/src/testing/test-governance.ts +8 -40
- package/assets/reference-configs/heartbeat-triage.md +0 -57
- package/assets/templates/helpers/harness-trace-grade.sh +0 -150
- package/assets/templates/helpers/heartbeat-triage.sh +0 -361
- package/assets/templates/helpers/maintenance-triage.sh +0 -167
- package/docs/architecture/current/approved-target-architecture.zh-CN.md +0 -1501
- package/docs/architecture/current/architecture-invariants.md +0 -331
- package/docs/architecture/current/automation-and-schedule-engine.md +0 -459
- package/docs/architecture/current/codegraph-context-provider.md +0 -238
- package/docs/architecture/current/control-plane-authority-inventory.md +0 -94
- package/docs/architecture/current/controller-repository-decoupling.md +0 -148
- package/docs/architecture/current/dispatch-and-agent-strategy.md +0 -373
- package/docs/architecture/current/entity-model.md +0 -612
- package/docs/architecture/current/external-plugin-governance.md +0 -396
- package/docs/architecture/current/failure-recovery.md +0 -447
- package/docs/architecture/current/governance.md +0 -213
- package/docs/architecture/current/human-interaction-plane.md +0 -87
- package/docs/architecture/current/implementation-status.md +0 -128
- package/docs/architecture/current/job-and-run-lifecycle.md +0 -413
- package/docs/architecture/current/legacy-governance.md +0 -58
- package/docs/architecture/current/local-workspace-target-grants.md +0 -70
- package/docs/architecture/current/migration-roadmap.md +0 -105
- package/docs/architecture/current/multi-repository-execution.md +0 -371
- package/docs/architecture/current/operations-runbook.md +0 -45
- package/docs/architecture/current/peer-supercontroller-runtime.md +0 -32
- package/docs/architecture/current/personal-assistant-plugin-baseline.md +0 -206
- package/docs/architecture/current/repository-access-modes.md +0 -102
- package/docs/architecture/current/route-policy.md +0 -15
- package/docs/architecture/current/route-session-concurrency.md +0 -85
- package/docs/architecture/current/runtime-architecture-simplification.md +0 -214
- package/docs/architecture/current/runtime-directory-map.md +0 -49
- package/docs/architecture/current/runtime-health-and-resource-lifecycle.md +0 -85
- package/docs/architecture/current/scheduler-and-resource-claims.md +0 -422
- package/docs/architecture/current/session-aware-execution-and-authorization.md +0 -77
- package/docs/architecture/current/system-overview.md +0 -169
- package/docs/architecture/current/target-requirements-traceability.md +0 -202
- package/docs/architecture/current/thin-harness-governance-policy.md +0 -32
- package/docs/architecture/current/thin-harness-v1.md +0 -321
- package/docs/architecture/current/verification-and-release-gates.md +0 -391
- package/docs/forge-autonomous-goal-loop.md +0 -9
- package/docs/forge-provider-configuration.md +0 -7
- package/docs/operations/chatgpt-personal-assistant-runtime.md +0 -93
- package/docs/operations/gmail-assistant-routines.md +0 -186
- package/docs/operations/personal-assistant-operator-guide.md +0 -61
- package/docs/operations/provider-configuration.md +0 -31
- package/scripts/harness-trace-grade.sh +0 -150
- package/scripts/heartbeat-triage.sh +0 -361
- package/scripts/maintenance-triage.sh +0 -167
- package/src/cli/local-bridge/frontend/src/features/settings/SettingsView.tsx +0 -2
- package/src/cli/repositories/goal-registry.ts +0 -239
- package/src/runtime/assistant/action-proposals.ts +0 -279
- package/src/runtime/assistant/intent.ts +0 -395
- package/src/runtime/assistant/model-provider.ts +0 -460
- package/src/runtime/assistant/openapi.ts +0 -223
- package/src/runtime/assistant/policy.ts +0 -89
- package/src/runtime/assistant/readiness.ts +0 -258
- package/src/runtime/assistant/routine-runtime.ts +0 -477
- package/src/runtime/assistant/schedule-binding.ts +0 -171
- package/src/runtime/assistant/standing-grants.ts +0 -375
- package/src/runtime/assistant/store.ts +0 -243
- package/src/runtime/assistant/types.ts +0 -135
- package/src/runtime/control-plane/goal-loop/config-facade.ts +0 -700
- package/src/runtime/control-plane/goal-loop/config-store.ts +0 -570
- package/src/runtime/control-plane/goal-loop/config-types.ts +0 -213
- package/src/runtime/control-plane/goal-loop/executor-router.ts +0 -109
- package/src/runtime/control-plane/goal-loop/failure-taxonomy.ts +0 -149
- package/src/runtime/control-plane/goal-loop/goal-contract-store.ts +0 -304
- package/src/runtime/control-plane/goal-loop/goal-loop-engine.ts +0 -1001
- package/src/runtime/control-plane/goal-loop/handoff-packet.ts +0 -160
- package/src/runtime/control-plane/goal-loop/index.ts +0 -13
- package/src/runtime/control-plane/goal-loop/local-tools.ts +0 -290
- package/src/runtime/control-plane/goal-loop/policy-gates.ts +0 -203
- package/src/runtime/control-plane/goal-loop/provider-dispatch.ts +0 -93
- package/src/runtime/control-plane/goal-loop/provider-registry.ts +0 -545
- package/src/runtime/control-plane/goal-loop/types.ts +0 -378
- package/src/runtime/control-plane/startup-recovery.ts +0 -198
- package/src/runtime/gateway/mcp/resource-policy.ts +0 -186
- package/src/runtime/personal-assistant/gmail-triage-manager.ts +0 -231
- package/src/runtime/personal-assistant/reporting-runtime.ts +0 -344
- package/src/runtime/personal-assistant/triage-runtime.ts +0 -748
- package/src/runtime/workflow/findings/store.ts +0 -204
- package/src/runtime/workflow/findings/types.ts +0 -58
- package/src/runtime/workflow/portfolio/engine.ts +0 -20
- package/src/runtime/workflow/portfolio/store.ts +0 -185
- package/src/runtime/workflow/portfolio/types.ts +0 -29
|
@@ -24,9 +24,18 @@ import {
|
|
|
24
24
|
type RunCheckFacadeResult,
|
|
25
25
|
} from './check-facade';
|
|
26
26
|
import { claimsForCheck, toProcessClaims } from './resource-claims';
|
|
27
|
-
import { spawnManagedProcess } from './runtime';
|
|
27
|
+
import { getProcessHandle, spawnManagedProcess } from './runtime';
|
|
28
|
+
import { getProcessRecord, getProcessRequestBinding } from './store';
|
|
28
29
|
import { allocatePersistedCheckResultReceiptPath } from './check-result';
|
|
29
30
|
import { durationAwareInteractiveWaitMs } from './interactive-admission';
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Work verification may overlap another Work's repository-wide build cache.
|
|
34
|
+
* Wait through one ordinary sibling check, but never past Process Runtime's
|
|
35
|
+
* bounded lease-admission ceiling; explicit callers may still choose less.
|
|
36
|
+
*/
|
|
37
|
+
export const DEFAULT_WORK_CHECK_LEASE_WAIT_MS = 30_000;
|
|
38
|
+
|
|
30
39
|
const PERSISTED_CHECK_SOURCE_ENTRY = 'src/runtime/execution/process-runtime/check-runner-sidecar.ts';
|
|
31
40
|
|
|
32
41
|
export function resolvePersistedCheckCliInvocation(
|
|
@@ -82,7 +91,7 @@ export function resolvePersistedCheckRuntimeExecutable(
|
|
|
82
91
|
entryExists: (path: string) => boolean = existsSync,
|
|
83
92
|
): string {
|
|
84
93
|
if (cliTarget.runtimeKind !== 'compiled_bun_release') return runtimeExecutable;
|
|
85
|
-
const checkRunner = resolve(
|
|
94
|
+
const checkRunner = resolve(cliTarget.cwd, 'forge-check-runner');
|
|
86
95
|
if (!entryExists(checkRunner)) {
|
|
87
96
|
throw new Error(`PERSISTED_CHECK_RUNNER_MISSING: ${checkRunner}`);
|
|
88
97
|
}
|
|
@@ -128,6 +137,38 @@ export async function runPersistedCheckViaProcessRuntime(
|
|
|
128
137
|
workerSpawnCount: 0,
|
|
129
138
|
projectionUpdateCount: 0,
|
|
130
139
|
};
|
|
140
|
+
const requestId = input.requestId?.trim();
|
|
141
|
+
const requestSemanticFingerprint = input.requestSemanticFingerprint?.trim();
|
|
142
|
+
if (requestId && requestSemanticFingerprint) {
|
|
143
|
+
const binding = getProcessRequestBinding(input.controllerHome, input.repoId, input.checkoutId, requestId);
|
|
144
|
+
if (binding) {
|
|
145
|
+
const record = getProcessRecord(input.controllerHome, input.repoId, binding.processId);
|
|
146
|
+
const exactIdentity = Boolean(
|
|
147
|
+
record
|
|
148
|
+
&& record.repoId === input.repoId
|
|
149
|
+
&& (record.checkoutId?.trim() || undefined) === (input.checkoutId?.trim() || undefined)
|
|
150
|
+
&& (record.workId?.trim() || undefined) === (input.workId?.trim() || undefined)
|
|
151
|
+
&& record.origin?.surface === 'check'
|
|
152
|
+
&& record.origin.requestId === requestId
|
|
153
|
+
&& record.origin.checkId === input.checkId
|
|
154
|
+
&& record.origin.requestSemanticFingerprint === requestSemanticFingerprint,
|
|
155
|
+
);
|
|
156
|
+
if (!exactIdentity) throw new Error(`PROCESS_REQUEST_ID_CONFLICT: ${requestId}`);
|
|
157
|
+
const existing = getProcessHandle(input.controllerHome, input.repoId, binding.processId);
|
|
158
|
+
if (!existing) {
|
|
159
|
+
throw new Error(`PROCESS_REQUEST_INCOMPLETE: request ${requestId} is bound to missing process ${binding.processId}; refusing re-execution`);
|
|
160
|
+
}
|
|
161
|
+
const check = listControllerChecks(input.repoRoot).find((entry) => entry.id === input.checkId);
|
|
162
|
+
return {
|
|
163
|
+
mode: existing.completed ? 'direct' : 'managed',
|
|
164
|
+
checkId: input.checkId,
|
|
165
|
+
check,
|
|
166
|
+
process: { ...existing, deduplicated: true, requestId },
|
|
167
|
+
ok: existing.completed ? existing.ok : undefined,
|
|
168
|
+
durableSideEffects: emptyEffects,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
}
|
|
131
172
|
const verificationSnapshot = input.verificationSnapshot
|
|
132
173
|
? materializeWorkVerificationSnapshot({
|
|
133
174
|
controllerHome: input.controllerHome,
|
|
@@ -153,7 +194,7 @@ export async function runPersistedCheckViaProcessRuntime(
|
|
|
153
194
|
durableSideEffects: emptyEffects,
|
|
154
195
|
};
|
|
155
196
|
}
|
|
156
|
-
if (input.forceDurable || checkRequiresDurableWorkflow(input.checkId, check)) {
|
|
197
|
+
if (input.forceDurable || (checkRequiresDurableWorkflow(input.checkId, check) && input.allowDurableCheckExecution !== true)) {
|
|
157
198
|
cleanupVerificationSnapshot();
|
|
158
199
|
return {
|
|
159
200
|
mode: 'durable',
|
|
@@ -168,7 +209,8 @@ export async function runPersistedCheckViaProcessRuntime(
|
|
|
168
209
|
}
|
|
169
210
|
|
|
170
211
|
const interactiveWaitMs = durationAwareInteractiveWaitMs(check.command, input.interactiveWaitMs);
|
|
171
|
-
const leaseWaitMs = input.leaseWaitMs
|
|
212
|
+
const leaseWaitMs = input.leaseWaitMs
|
|
213
|
+
?? (input.workId?.trim() ? DEFAULT_WORK_CHECK_LEASE_WAIT_MS : undefined);
|
|
172
214
|
const timeoutMs = Math.min(
|
|
173
215
|
check.timeoutMs,
|
|
174
216
|
typeof input.timeoutMs === 'number' && Number.isFinite(input.timeoutMs)
|
|
@@ -234,7 +276,10 @@ export async function runPersistedCheckViaProcessRuntime(
|
|
|
234
276
|
checkFingerprint,
|
|
235
277
|
'--result-receipt',
|
|
236
278
|
checkResultReceiptPath,
|
|
237
|
-
...(verificationSnapshot ? [
|
|
279
|
+
...(verificationSnapshot ? [
|
|
280
|
+
'--isolated-controller-home', verificationSnapshot.isolatedControllerHome,
|
|
281
|
+
'--cleanup-root', verificationSnapshot.root,
|
|
282
|
+
] : []),
|
|
238
283
|
];
|
|
239
284
|
const invocation = resolvePersistedCheckProcessInvocation(cliTarget, checkArgs);
|
|
240
285
|
let handle;
|
|
@@ -262,6 +307,7 @@ export async function runPersistedCheckViaProcessRuntime(
|
|
|
262
307
|
toolName: 'run_check',
|
|
263
308
|
checkId: input.checkId,
|
|
264
309
|
requestId: input.requestId,
|
|
310
|
+
requestSemanticFingerprint: input.requestSemanticFingerprint,
|
|
265
311
|
correlationId: input.workId,
|
|
266
312
|
executionSessionId: input.verificationBinding?.executionSessionId,
|
|
267
313
|
editSessionId: input.verificationBinding?.editSessionId,
|
|
@@ -511,12 +511,16 @@ export function claimsForCheck(
|
|
|
511
511
|
): ResourceClaimSpec[] {
|
|
512
512
|
const heavy = /(?:^|:)(?:test(?::coverage)?|check:(?:ci|forge-runtime|public-export|release(?:-[a-z0-9-]+)?))$/.test(checkId)
|
|
513
513
|
|| /release|migration|integrate/i.test(checkId);
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
514
|
+
const baseClaims = effects
|
|
515
|
+
? claimsForDeclaredCheckEffects(checkId, effects, repoId, checkoutId)
|
|
516
|
+
: staticAnalysisCheckId(checkId)
|
|
517
|
+
? [claimWorkspaceRead(checkoutId), claimBuildCacheWrite(repoId)]
|
|
518
|
+
: command && command.length > 0
|
|
519
|
+
? claimsForRepositoryCommand(command, repoId, checkoutId)
|
|
520
|
+
: [claimWorkspaceWrite(checkoutId)];
|
|
521
|
+
// Heavy-check is an additional cross-check serialization fence, not a
|
|
522
|
+
// substitute for the resources the check actually reads or writes.
|
|
523
|
+
return heavy ? normalizeClaims([claimHeavyCheck(repoId), ...baseClaims]) : baseClaims;
|
|
520
524
|
}
|
|
521
525
|
|
|
522
526
|
export function scopeResourceClaims(
|
|
@@ -306,8 +306,9 @@ function identityStillMatches(identity: ManagedProcessRecord['identity'] | undef
|
|
|
306
306
|
}
|
|
307
307
|
if (!isProcessAlive(identity.pid)) return false;
|
|
308
308
|
const probe = defaultProcessIdentityProbe;
|
|
309
|
-
const
|
|
310
|
-
const
|
|
309
|
+
const inspected = probe.inspect?.(identity.pid);
|
|
310
|
+
const startTime = inspected?.startTime ?? probe.startTime(identity.pid);
|
|
311
|
+
const command = inspected?.command ?? probe.command(identity.pid);
|
|
311
312
|
if (!startTime || !command) return false;
|
|
312
313
|
if (startTime !== identity.processStartTime) return false;
|
|
313
314
|
if (executableFingerprint(command) !== identity.executableFingerprint) return false;
|
|
@@ -541,7 +542,7 @@ export function completeProcessFromEvidence(
|
|
|
541
542
|
stdoutTail?: string;
|
|
542
543
|
stderrTail?: string;
|
|
543
544
|
},
|
|
544
|
-
options: { authority?: 'runtime_writer' | 'durable_exit_receipt' | 'durable_pre_spawn_abandonment' } = {},
|
|
545
|
+
options: { authority?: 'runtime_writer' | 'durable_exit_receipt' | 'durable_pre_spawn_abandonment' | 'durable_stale_active_reconciliation' } = {},
|
|
545
546
|
): ManagedProcessRecord | undefined {
|
|
546
547
|
// Validated independent evidence may only perform the monotonic,
|
|
547
548
|
// fence-token-bound terminal CAS below. It does not grant general writer
|
|
@@ -627,6 +628,45 @@ export function reconcileAbandonedPreSpawnProcess(
|
|
|
627
628
|
}, { authority: 'durable_pre_spawn_abandonment' });
|
|
628
629
|
}
|
|
629
630
|
|
|
631
|
+
/**
|
|
632
|
+
* Bounded maintenance reconciliation for stale active Process records that are
|
|
633
|
+
* no longer reachable through the v2 recovery index. This never deletes an
|
|
634
|
+
* active record and never re-executes a command: it first consumes any durable
|
|
635
|
+
* Runner receipt, preserves live monitors / matching process identities, and
|
|
636
|
+
* only then commits a monotonic terminal state for a provably dead identity.
|
|
637
|
+
*/
|
|
638
|
+
export function reconcileStaleManagedProcessForMaintenance(
|
|
639
|
+
controllerHome: string,
|
|
640
|
+
repoId: string,
|
|
641
|
+
processId: string,
|
|
642
|
+
options: { nowMs?: number; minAgeMs?: number } = {},
|
|
643
|
+
): ManagedProcessRecord | undefined {
|
|
644
|
+
let record = getProcessRecord(controllerHome, repoId, processId);
|
|
645
|
+
if (!record || !isManagedProcessActive(record)) return record;
|
|
646
|
+
|
|
647
|
+
const nowMs = options.nowMs ?? Date.now();
|
|
648
|
+
const minAgeMs = Math.max(1_000, options.minAgeMs ?? DEFAULT_PRE_SPAWN_ABANDONMENT_MS);
|
|
649
|
+
const updatedAtMs = Date.parse(record.updatedAt || record.startedAt);
|
|
650
|
+
if (!Number.isFinite(updatedAtMs) || nowMs - updatedAtMs < minAgeMs) return record;
|
|
651
|
+
|
|
652
|
+
const fromReceipt = applyReceiptIfPresent(controllerHome, repoId, processId, record);
|
|
653
|
+
if (fromReceipt) return fromReceipt;
|
|
654
|
+
|
|
655
|
+
if (record.status === 'starting' && !record.identity) {
|
|
656
|
+
return reconcileAbandonedPreSpawnProcess(controllerHome, repoId, processId, { nowMs, minAgeMs });
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
record = getProcessRecord(controllerHome, repoId, processId) ?? record;
|
|
660
|
+
if (!isManagedProcessActive(record) || liveMonitors.has(processId)) return record;
|
|
661
|
+
if (identityStillMatches(record.identity, record.identityUntrusted)) return record;
|
|
662
|
+
|
|
663
|
+
return completeProcessFromEvidence(controllerHome, repoId, processId, record.terminalFenceToken, {
|
|
664
|
+
status: 'completed_unknown',
|
|
665
|
+
finishedAt: new Date(nowMs).toISOString(),
|
|
666
|
+
errorMessage: 'PROCESS_STALE_ACTIVE_RECONCILED: stale active record has no live matching process identity or durable exit receipt',
|
|
667
|
+
}, { authority: 'durable_stale_active_reconciliation' });
|
|
668
|
+
}
|
|
669
|
+
|
|
630
670
|
async function killTree(child: ChildProcess): Promise<void> {
|
|
631
671
|
const pid = child.pid;
|
|
632
672
|
if (!pid) return;
|
|
@@ -654,6 +694,16 @@ export function resolveProcessRunnerEntryPath(
|
|
|
654
694
|
const configured = env.FORGE_PROCESS_RUNNER_ENTRY?.trim();
|
|
655
695
|
if (configured && existsSync(configured)) return configured;
|
|
656
696
|
|
|
697
|
+
// macOS launchd runs the immutable Runtime through a stable mirrored
|
|
698
|
+
// executable path for TCC identity. In that mode process.execPath is not a
|
|
699
|
+
// sibling of the active release sidecars, so use the release authority path
|
|
700
|
+
// exported by the launch contract before any executable/source fallback.
|
|
701
|
+
const releaseRoot = env.FORGE_RELEASE_PATH?.trim();
|
|
702
|
+
if (releaseRoot) {
|
|
703
|
+
const releaseRunner = join(releaseRoot, 'process-runner.js');
|
|
704
|
+
if (existsSync(releaseRunner)) return releaseRunner;
|
|
705
|
+
}
|
|
706
|
+
|
|
657
707
|
// Compiled daemon/Gateway entrypoints and process-runner.js are siblings in
|
|
658
708
|
// every immutable release. Prefer that closed release surface before looking
|
|
659
709
|
// at source paths recorded only for diagnostics and development fallback.
|
|
@@ -299,6 +299,7 @@ function sanitizeProcessRecord(record: ManagedProcessRecord): { record: ManagedP
|
|
|
299
299
|
toolName: safeText(record.origin.toolName),
|
|
300
300
|
requestId: safeText(record.origin.requestId),
|
|
301
301
|
checkId: safeText(record.origin.checkId),
|
|
302
|
+
requestSemanticFingerprint: safeText(record.origin.requestSemanticFingerprint),
|
|
302
303
|
correlationId: safeText(record.origin.correlationId),
|
|
303
304
|
} : undefined,
|
|
304
305
|
};
|
|
@@ -140,18 +140,8 @@ export interface ProcessRequestBinding {
|
|
|
140
140
|
createdAt: string;
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
schemaVersion: 1;
|
|
146
|
-
checkId: string;
|
|
147
|
-
cacheKey: string;
|
|
148
|
-
revision: string;
|
|
149
|
-
definitionDigest: string;
|
|
150
|
-
environmentFingerprint: string;
|
|
151
|
-
timeoutMs: number;
|
|
152
|
-
reuseScope: 'repository' | 'checkout';
|
|
153
|
-
scopeKey: string;
|
|
154
|
-
}
|
|
143
|
+
export type { ProcessCheckExecutionIdentity } from '../../evidence/process-check-execution';
|
|
144
|
+
import type { ProcessCheckExecutionIdentity } from '../../evidence/process-check-execution';
|
|
155
145
|
|
|
156
146
|
/** Persistent semantic Check binding to one physical Process record. */
|
|
157
147
|
export interface ProcessCheckExecutionBinding {
|
|
@@ -239,6 +229,8 @@ export interface ManagedProcessRecord {
|
|
|
239
229
|
toolName?: string;
|
|
240
230
|
requestId?: string;
|
|
241
231
|
checkId?: string;
|
|
232
|
+
/** Stable semantic identity supplied by a facade for exact request reattachment. */
|
|
233
|
+
requestSemanticFingerprint?: string;
|
|
242
234
|
correlationId?: string;
|
|
243
235
|
/** Controller MCP session that initiated this check, when applicable. */
|
|
244
236
|
executionSessionId?: string;
|
|
@@ -10,6 +10,9 @@ export interface BoundedProcessOptions {
|
|
|
10
10
|
signal?: AbortSignal;
|
|
11
11
|
/** When true (default on non-Windows), create a new process group for tree kill. */
|
|
12
12
|
processGroup?: boolean;
|
|
13
|
+
onSpawn?: (pid: number) => void;
|
|
14
|
+
onStdout?: (chunk: string) => void;
|
|
15
|
+
onStderr?: (chunk: string) => void;
|
|
13
16
|
}
|
|
14
17
|
|
|
15
18
|
export interface BoundedProcessResult {
|
|
@@ -114,6 +117,7 @@ export async function runBoundedProcess(
|
|
|
114
117
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
115
118
|
detached: useProcessGroup,
|
|
116
119
|
});
|
|
120
|
+
if (child.pid) options.onSpawn?.(child.pid);
|
|
117
121
|
|
|
118
122
|
const finish = (exitCode: number) => {
|
|
119
123
|
if (settled) return;
|
|
@@ -150,8 +154,14 @@ export async function runBoundedProcess(
|
|
|
150
154
|
|
|
151
155
|
options.signal?.addEventListener('abort', onAbort, { once: true });
|
|
152
156
|
|
|
153
|
-
child.stdout?.on('data', (chunk: Buffer) =>
|
|
154
|
-
|
|
157
|
+
child.stdout?.on('data', (chunk: Buffer) => {
|
|
158
|
+
stdout.write(chunk);
|
|
159
|
+
options.onStdout?.(chunk.toString('utf8'));
|
|
160
|
+
});
|
|
161
|
+
child.stderr?.on('data', (chunk: Buffer) => {
|
|
162
|
+
stderr.write(chunk);
|
|
163
|
+
options.onStderr?.(chunk.toString('utf8'));
|
|
164
|
+
});
|
|
155
165
|
child.on('error', (error) => {
|
|
156
166
|
spawnError = error.message;
|
|
157
167
|
});
|
|
@@ -5,7 +5,12 @@
|
|
|
5
5
|
import { isMainThread, parentPort, workerData, Worker } from 'worker_threads';
|
|
6
6
|
import { fileURLToPath } from 'url';
|
|
7
7
|
import { getMcpPolicy } from '../../../cli/mcp/policy';
|
|
8
|
-
import {
|
|
8
|
+
import type { McpPolicy } from '../../../cli/mcp/types';
|
|
9
|
+
import {
|
|
10
|
+
searchRepository,
|
|
11
|
+
searchRepositoryMany,
|
|
12
|
+
type SearchRepositoryManyResult,
|
|
13
|
+
} from '../../../cli/repository/inspector';
|
|
9
14
|
|
|
10
15
|
export interface SearchWorkerInput {
|
|
11
16
|
repoRoot: string;
|
|
@@ -14,14 +19,44 @@ export interface SearchWorkerInput {
|
|
|
14
19
|
maxFiles: number;
|
|
15
20
|
}
|
|
16
21
|
|
|
22
|
+
export interface SearchManyWorkerInput {
|
|
23
|
+
repoRoot: string;
|
|
24
|
+
policy: McpPolicy;
|
|
25
|
+
queries: string[];
|
|
26
|
+
files?: string[];
|
|
27
|
+
includeGlobs?: string[];
|
|
28
|
+
excludeGlobs?: string[];
|
|
29
|
+
maxResultsPerQuery?: number;
|
|
30
|
+
maxFiles?: number;
|
|
31
|
+
caseSensitive?: boolean;
|
|
32
|
+
cacheKey?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
17
35
|
export interface SearchWorkerResult {
|
|
18
36
|
ok: boolean;
|
|
19
37
|
payload?: Record<string, unknown>;
|
|
20
38
|
error?: string;
|
|
21
39
|
}
|
|
22
40
|
|
|
23
|
-
function
|
|
41
|
+
function isManySearch(input: SearchWorkerInput | SearchManyWorkerInput): input is SearchManyWorkerInput {
|
|
42
|
+
return Array.isArray((input as SearchManyWorkerInput).queries);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function runSearchSync(input: SearchWorkerInput | SearchManyWorkerInput): SearchWorkerResult {
|
|
24
46
|
try {
|
|
47
|
+
if (isManySearch(input)) {
|
|
48
|
+
const result = searchRepositoryMany(input.repoRoot, input.policy, {
|
|
49
|
+
queries: input.queries,
|
|
50
|
+
files: input.files,
|
|
51
|
+
includeGlobs: input.includeGlobs,
|
|
52
|
+
excludeGlobs: input.excludeGlobs,
|
|
53
|
+
maxResultsPerQuery: input.maxResultsPerQuery,
|
|
54
|
+
maxFiles: input.maxFiles,
|
|
55
|
+
caseSensitive: input.caseSensitive,
|
|
56
|
+
cacheKey: input.cacheKey,
|
|
57
|
+
}) as unknown as Record<string, unknown>;
|
|
58
|
+
return { ok: true, payload: result };
|
|
59
|
+
}
|
|
25
60
|
const result = searchRepository(input.repoRoot, getMcpPolicy('controller', { repoRoot: input.repoRoot }), {
|
|
26
61
|
query: input.query,
|
|
27
62
|
maxResults: input.maxResults,
|
|
@@ -36,8 +71,8 @@ function runSearchSync(input: SearchWorkerInput): SearchWorkerResult {
|
|
|
36
71
|
}
|
|
37
72
|
}
|
|
38
73
|
|
|
39
|
-
|
|
40
|
-
input: SearchWorkerInput,
|
|
74
|
+
async function runSearchWorker(
|
|
75
|
+
input: SearchWorkerInput | SearchManyWorkerInput,
|
|
41
76
|
options: { timeoutMs?: number; signal?: AbortSignal } = {},
|
|
42
77
|
): Promise<Record<string, unknown>> {
|
|
43
78
|
if (options.signal?.aborted) throw new Error('CANCELLED: search aborted');
|
|
@@ -108,7 +143,21 @@ export async function runInspectorSearchInWorker(
|
|
|
108
143
|
});
|
|
109
144
|
}
|
|
110
145
|
|
|
146
|
+
export async function runInspectorSearchInWorker(
|
|
147
|
+
input: SearchWorkerInput,
|
|
148
|
+
options: { timeoutMs?: number; signal?: AbortSignal } = {},
|
|
149
|
+
): Promise<Record<string, unknown>> {
|
|
150
|
+
return await runSearchWorker(input, options);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export async function runInspectorSearchManyInWorker(
|
|
154
|
+
input: SearchManyWorkerInput,
|
|
155
|
+
options: { timeoutMs?: number; signal?: AbortSignal } = {},
|
|
156
|
+
): Promise<SearchRepositoryManyResult> {
|
|
157
|
+
return await runSearchWorker(input, options) as unknown as SearchRepositoryManyResult;
|
|
158
|
+
}
|
|
159
|
+
|
|
111
160
|
if (!isMainThread && parentPort) {
|
|
112
|
-
const input = workerData as SearchWorkerInput;
|
|
161
|
+
const input = workerData as SearchWorkerInput | SearchManyWorkerInput;
|
|
113
162
|
parentPort.postMessage(runSearchSync(input));
|
|
114
163
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { listActiveExecutionJobs } from './jobs/store';
|
|
2
|
+
import type { ExecutionJob } from './jobs/types';
|
|
3
|
+
import { listRecoverableProcessRecords } from './process-runtime/store';
|
|
4
|
+
import { isManagedProcessActive } from './process-runtime/types';
|
|
5
|
+
|
|
6
|
+
export function executionJobBelongsToWork(job: ExecutionJob, workId: string): boolean {
|
|
7
|
+
if (job.resourceClaims.some((claim) => claim.workId === workId)) return true;
|
|
8
|
+
const payload = job.payload as Record<string, unknown>;
|
|
9
|
+
const args = payload.arguments && typeof payload.arguments === 'object' && !Array.isArray(payload.arguments)
|
|
10
|
+
? payload.arguments as Record<string, unknown>
|
|
11
|
+
: undefined;
|
|
12
|
+
return [payload.workId, payload.work_id, args?.workId, args?.work_id].some((value) => value === workId);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function workHasActiveExecution(controllerHome: string, repoId: string, workId: string): boolean {
|
|
16
|
+
const activeProcess = listRecoverableProcessRecords(controllerHome, repoId)
|
|
17
|
+
.some((record) => record.workId === workId && isManagedProcessActive(record));
|
|
18
|
+
if (activeProcess) return true;
|
|
19
|
+
return listActiveExecutionJobs(controllerHome, repoId)
|
|
20
|
+
.some((job) => executionJobBelongsToWork(job, workId));
|
|
21
|
+
}
|
|
@@ -21,7 +21,6 @@ import {
|
|
|
21
21
|
} from '../jobs/child-reference';
|
|
22
22
|
import { markOperationDelegated } from '../jobs/receipt-store';
|
|
23
23
|
import { assertAutomatedOperationAllowed } from '../../control-plane/governance/external-effects';
|
|
24
|
-
import { recordCandidateFinding, updateCandidateFinding } from '../../workflow/findings/store';
|
|
25
24
|
import { triggerWorkspaceAgent } from '../workspace-agent';
|
|
26
25
|
import { executeAssistantPluginAction } from '../../plugins/store';
|
|
27
26
|
import { CONTROLLER_SCOPE_REPO_ID, controllerSystemRoot, repositoryControllerRoot } from '../../../cli/repositories/controller-home';
|
|
@@ -29,7 +28,8 @@ import { writeExecutionArtifact } from '../../evidence/artifact-store';
|
|
|
29
28
|
import { existsSync } from 'fs';
|
|
30
29
|
import { isAbsolute, relative, resolve, sep } from 'path';
|
|
31
30
|
import { isAssistantPluginError } from '../../plugins/errors';
|
|
32
|
-
import {
|
|
31
|
+
import { executeWork, validateWork } from '../../control-plane/execution/work-operation-service';
|
|
32
|
+
import { finalizeWork } from '../../control-plane/execution/work-finalization-service';
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
function childReferenceFromLocalJob(
|
|
@@ -445,20 +445,6 @@ export async function executeExecutionJob(controllerHome: string, job: Execution
|
|
|
445
445
|
}
|
|
446
446
|
bindRepositoryEntities(repository);
|
|
447
447
|
|
|
448
|
-
if (job.payload.target === 'runtime' && job.payload.operation === 'assistant_routine_execute') {
|
|
449
|
-
const routineId = String(job.payload.arguments?.routineId ?? job.payload.arguments?.routine_id ?? '').trim();
|
|
450
|
-
if (!routineId) throw new Error('ASSISTANT_ROUTINE_ID_REQUIRED');
|
|
451
|
-
const routineResult = await executeAssistantRoutineRuntime({
|
|
452
|
-
controllerHome,
|
|
453
|
-
repository,
|
|
454
|
-
routineId,
|
|
455
|
-
requestId: job.requestId,
|
|
456
|
-
origin: job.origin,
|
|
457
|
-
occurrenceId: typeof job.payload.occurrenceId === 'string' ? job.payload.occurrenceId : undefined,
|
|
458
|
-
});
|
|
459
|
-
return { ok: true, result: { assistantRoutine: routineResult }, repoRoot };
|
|
460
|
-
}
|
|
461
|
-
|
|
462
448
|
if (job.payload.target === 'runtime' && job.payload.operation === 'legacy-local-job') {
|
|
463
449
|
const localJobId = String(job.payload.arguments?.localJobId ?? '').trim();
|
|
464
450
|
if (!localJobId) throw new Error('LEGACY_JOB_ID_REQUIRED');
|
|
@@ -511,26 +497,6 @@ export async function executeExecutionJob(controllerHome: string, job: Execution
|
|
|
511
497
|
: { ok: false, error: { code: 'RELEASE_GATE_BLOCKED', message: 'Release gate has blockers.', retryable: false, details: { gate } }, repoRoot };
|
|
512
498
|
}
|
|
513
499
|
|
|
514
|
-
if (job.payload.operation === 'record_candidate_finding') {
|
|
515
|
-
const args = job.payload.arguments ?? {};
|
|
516
|
-
const finding = recordCandidateFinding(controllerHome, {
|
|
517
|
-
repoId: job.repoId,
|
|
518
|
-
requestId: job.requestId,
|
|
519
|
-
semanticKey: String(args.semantic_key ?? args.semanticKey ?? '').trim(),
|
|
520
|
-
title: String(args.title ?? '').trim(),
|
|
521
|
-
summary: typeof args.summary === 'string' ? args.summary : undefined,
|
|
522
|
-
severity: ['low', 'medium', 'high', 'critical'].includes(String(args.severity))
|
|
523
|
-
? String(args.severity) as 'low' | 'medium' | 'high' | 'critical'
|
|
524
|
-
: 'medium',
|
|
525
|
-
evidence: {
|
|
526
|
-
source: job.origin.surface,
|
|
527
|
-
reference: typeof args.reference === 'string' ? args.reference : job.origin.correlationId,
|
|
528
|
-
details: args.evidence && typeof args.evidence === 'object' ? args.evidence as Record<string, unknown> : undefined,
|
|
529
|
-
},
|
|
530
|
-
});
|
|
531
|
-
return { ok: true, result: { finding }, repoRoot };
|
|
532
|
-
}
|
|
533
|
-
|
|
534
500
|
const allowedAgents = Array.isArray(job.payload.allowedAgents)
|
|
535
501
|
? job.payload.allowedAgents.filter((value): value is string => typeof value === 'string')
|
|
536
502
|
: [];
|
|
@@ -560,23 +526,26 @@ export async function executeExecutionJob(controllerHome: string, job: Execution
|
|
|
560
526
|
toolset: job.payload.toolset === 'core' || job.payload.toolset === 'full' ? job.payload.toolset : 'advanced',
|
|
561
527
|
toolsetLocked: true,
|
|
562
528
|
};
|
|
563
|
-
//
|
|
564
|
-
//
|
|
565
|
-
// creation while preserving the existing Work validation/authorization path.
|
|
529
|
+
// Durable Work mutations execute through control-plane application services.
|
|
530
|
+
// The Worker must never import MCP transport to obtain Work semantics.
|
|
566
531
|
const durableWorkOperation = job.payload.operation === 'work_execute'
|
|
567
532
|
|| job.payload.operation === 'work_validate'
|
|
568
533
|
|| job.payload.operation === 'work_finalize';
|
|
569
|
-
// Load the Work implementation only for Work Jobs. A static import here
|
|
570
|
-
// creates an initialization cycle through repository command and Local Bridge
|
|
571
|
-
// modules, changing unrelated execution behavior.
|
|
572
534
|
const toolArguments = { ...(job.payload.arguments ?? {}) };
|
|
573
|
-
const
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
535
|
+
const workArguments = {
|
|
536
|
+
...toolArguments,
|
|
537
|
+
__from_durable_worker: true,
|
|
538
|
+
__execution_job_id: job.jobId,
|
|
539
|
+
};
|
|
540
|
+
const executionRecord = job.payload.operation === 'work_execute'
|
|
541
|
+
? await executeWork(runtimeContext, workArguments)
|
|
542
|
+
: job.payload.operation === 'work_validate'
|
|
543
|
+
? await validateWork(runtimeContext, workArguments)
|
|
544
|
+
: job.payload.operation === 'work_finalize'
|
|
545
|
+
? await finalizeWork(runtimeContext, workArguments)
|
|
546
|
+
: undefined;
|
|
547
|
+
const executionResult: CallToolResult | undefined = durableWorkOperation && executionRecord
|
|
548
|
+
? { structuredContent: executionRecord, content: [] }
|
|
580
549
|
: undefined;
|
|
581
550
|
const runtimeResult = executionResult ?? (policy.profile === 'controller'
|
|
582
551
|
? await callRuntimeTool(runtimeContext, job.payload.operation, toolArguments)
|
|
@@ -651,18 +620,6 @@ export async function executeExecutionJob(controllerHome: string, job: Execution
|
|
|
651
620
|
);
|
|
652
621
|
}
|
|
653
622
|
|
|
654
|
-
if (job.origin.actor === 'promote_candidate_finding' && job.origin.correlationId) {
|
|
655
|
-
try {
|
|
656
|
-
updateCandidateFinding(controllerHome, job.repoId, job.origin.correlationId, (current) => ({
|
|
657
|
-
...current,
|
|
658
|
-
status: result.isError ? 'candidate' : 'promoted',
|
|
659
|
-
promotedJobId: job.jobId,
|
|
660
|
-
}), job.requestId, result.isError ? 'candidate_promotion_failed' : 'candidate_finding_promoted');
|
|
661
|
-
} catch {
|
|
662
|
-
// The Issue result remains authoritative even if the candidate projection needs reconciliation.
|
|
663
|
-
}
|
|
664
|
-
}
|
|
665
|
-
|
|
666
623
|
if (result.isError) {
|
|
667
624
|
return { ok: false, error: { code: 'MCP_TOOL_FAILED', message: JSON.stringify(record), retryable: false }, repoRoot };
|
|
668
625
|
}
|