@moretea-labs/forge 1.8.0 → 1.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +70 -7
- package/CHANGELOG.md +14 -0
- package/CLAUDE.md +17 -2
- package/CONTRIBUTING.md +3 -2
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/adapters/chatgpt/browser-delivery-host.ts +7 -1
- package/adapters/chatgpt/browser-delivery-runtime.ts +529 -56
- package/adapters/chatgpt/controller-binding-store.ts +101 -22
- package/adapters/chatgpt/controller-round-host.ts +15 -25
- package/adapters/chatgpt/controller-round-settlement-store.ts +58 -4
- package/adapters/chatgpt/provider-delivery.ts +228 -1
- package/adapters/chatgpt/work-conversation-binding-store.ts +79 -53
- package/adapters/computer/chatgpt-extension-target.ts +463 -0
- package/adapters/computer/chatgpt-target-router.ts +103 -0
- package/adapters/computer/chrome-extension/background.js +385 -0
- package/adapters/computer/chrome-extension/content.js +378 -0
- package/adapters/computer/chrome-extension/core.js +24 -0
- package/adapters/computer/chrome-extension/manifest.json +30 -0
- package/adapters/computer/desktop-operator-discovery.ts +11 -31
- package/adapters/computer/interaction-target-authority.ts +142 -18
- package/adapters/mcp/auth.ts +0 -1
- package/adapters/mcp/instructions.ts +5 -4
- package/adapters/mcp/multi-repository.ts +3 -19
- package/adapters/mcp/oauth.ts +73 -0
- package/adapters/mcp/paths.ts +4 -1
- package/adapters/mcp/runtime-gateway/automation-receipt-adapter.ts +87 -0
- package/adapters/mcp/runtime-gateway/bounded-result-runtime.ts +62 -0
- package/adapters/mcp/runtime-gateway/cognition-settlement.ts +201 -0
- package/adapters/mcp/runtime-gateway/context-adapter.ts +411 -73
- package/adapters/mcp/runtime-gateway/context-pack-sidecar.ts +91 -0
- package/adapters/mcp/runtime-gateway/controller-authority-adapter.ts +20 -5
- package/adapters/mcp/runtime-gateway/core-capability-adapter.ts +258 -0
- package/adapters/mcp/runtime-gateway/engineering-preconditions.ts +10 -27
- package/adapters/mcp/runtime-gateway/engineering-tool-contract.ts +15 -0
- package/adapters/mcp/runtime-gateway/execution-tools.ts +8 -42
- package/adapters/mcp/runtime-gateway/gateway-execution-adapter.ts +2 -1
- package/adapters/mcp/runtime-gateway/plugin-adapter.ts +117 -45
- package/adapters/mcp/runtime-gateway/process-tools.ts +190 -22
- package/adapters/mcp/runtime-gateway/protected-computer-adapter.ts +16 -4
- package/adapters/mcp/runtime-gateway/recovery-adapter.ts +69 -52
- package/adapters/mcp/runtime-gateway/repository-compat-adapter.ts +4 -35
- package/adapters/mcp/runtime-gateway/result-adapter.ts +10 -4
- package/adapters/mcp/runtime-gateway/router.ts +18 -504
- package/adapters/mcp/runtime-gateway/routing-policy.ts +499 -0
- package/adapters/mcp/runtime-gateway/runtime-observation-adapter.ts +14 -65
- package/adapters/mcp/runtime-gateway/runtime-readiness-observation.ts +218 -0
- package/adapters/mcp/runtime-gateway/runtime-tool-definitions.ts +113 -173
- package/adapters/mcp/runtime-gateway/runtime-tools.ts +15 -5
- package/adapters/mcp/runtime-gateway/scheduler-adapter.ts +1 -0
- package/adapters/mcp/runtime-gateway/shared-adapter.ts +20 -0
- package/adapters/mcp/runtime-gateway/status-inbox-adapter.ts +358 -266
- package/adapters/mcp/runtime-gateway/typescript-navigation-sidecar.ts +136 -0
- package/adapters/mcp/runtime-gateway/work-adapter.ts +261 -3122
- package/adapters/mcp/runtime-gateway/work-controller-operations.ts +257 -0
- package/adapters/mcp/runtime-gateway/work-detail-projection.ts +60 -0
- package/adapters/mcp/runtime-gateway/work-input-wire-migration.ts +246 -0
- package/adapters/mcp/runtime-gateway/work-learning-operations.ts +145 -0
- package/adapters/mcp/runtime-gateway/work-list-projection.ts +38 -0
- package/adapters/mcp/runtime-gateway/work-plan-operations.ts +382 -0
- package/adapters/mcp/runtime-gateway/work-repair-adapter.ts +308 -0
- package/adapters/mcp/runtime-gateway/work-requirement-operations.ts +148 -0
- package/adapters/mcp/runtime-gateway/work-semantic-operations.ts +263 -0
- package/adapters/mcp/runtime-gateway/work-workflow-operations.ts +113 -0
- package/adapters/mcp/runtime-gateway/workflow-supervisor-adapter.ts +156 -0
- package/adapters/mcp/server.ts +67 -23
- package/adapters/mcp/setup.ts +1 -3
- package/adapters/mcp/tool-mapping/legacy-tool-service.ts +44 -170
- package/adapters/mcp/tool-mapping/post-finalize-work-attribution.ts +4 -9
- package/adapters/mcp/tool-mapping/repository-tools.ts +133 -142
- package/adapters/mcp/toolset-names.ts +5 -0
- package/adapters/mcp/toolset.ts +6 -5
- package/adapters/mcp/transports/http-observation.ts +365 -0
- package/adapters/mcp/transports/http.ts +154 -677
- package/adapters/mcp/transports/oauth-http.ts +322 -0
- package/adapters/mcp/transports/session-registry.ts +6 -0
- package/adapters/mcp/tunnels/openai-secure-tunnel.ts +89 -5
- package/assets/plugin-registry.v1.json +6 -4
- package/assets/reference-configs/agentic-development-flow.md +25 -0
- package/assets/reference-configs/global-working-rules.md +19 -0
- package/assets/skill-version.json +2 -2
- package/docs/architecture/CURRENT.md +111 -41
- package/docs/architecture/decisions/20260803-release-identity-binding-and-exit-policy.md +14 -5
- package/docs/architecture/decisions/20260823-immediate-controller-relay.md +6 -3
- package/docs/architecture/decisions/20260907-assistant-learning-loop.md +2 -0
- package/docs/architecture/decisions/20260907-controller-round-transition-policy.md +19 -4
- package/docs/architecture/decisions/20260916-workflow-supervisor-authority.md +249 -0
- package/docs/architecture/decisions/20260917-cognitive-memory-foundation.md +82 -0
- package/docs/architecture/decisions/20260918-stable-candidate-release-lifecycle.md +221 -0
- package/docs/architecture/decisions/20260919-autonomous-work-liveness.md +62 -0
- package/docs/architecture/decisions/20260924-thin-semantic-working-context.md +72 -0
- package/docs/architecture/decisions/20261001-supervisor-turn-authority.md +237 -0
- package/docs/architecture/decisions/20261005-forge-v3-desktop-client-boundary.md +77 -0
- package/docs/architecture/domains/verification.md +1 -0
- package/docs/architecture/domains/workflow-engine.md +6 -0
- package/docs/architecture/modules/controller-runtime/transport-lifecycle.md +1 -1
- package/docs/forge-plugin-management.md +2 -2
- package/docs/operations/controller-performance-and-502.md +17 -0
- package/docs/operations/controller-reliability-runbook.md +2 -2
- package/docs/operations/features.md +1 -1
- package/docs/operations/features.zh-CN.md +1 -1
- package/docs/operations/homebrew.md +2 -2
- package/docs/operations/mcp-tool-exposure.md +2 -0
- package/docs/operations/releasing.md +2 -0
- package/docs/operations/standalone-disaster-recovery.md +14 -6
- package/docs/wiki/Implementation.md +1 -1
- package/package.json +25 -14
- package/packages/kernel/cognition/api/index.ts +6 -0
- package/packages/kernel/cognition/application/activation-service.ts +451 -0
- package/packages/kernel/cognition/application/consolidation-service.ts +185 -0
- package/packages/kernel/cognition/application/legacy-experience-adapter.ts +38 -0
- package/packages/kernel/cognition/application/memory-service.ts +64 -0
- package/packages/kernel/cognition/domain/learning.ts +106 -0
- package/packages/kernel/cognition/domain/memory.ts +254 -0
- package/packages/kernel/controller/api/index.ts +1 -0
- package/packages/kernel/controller/application/continuation-service.ts +281 -0
- package/packages/kernel/controller/application/controller-round-service.ts +12 -0
- package/packages/kernel/controller/domain/controller-round-transition-policy.ts +242 -21
- package/packages/kernel/controller/domain/controller-round.ts +4 -1
- package/packages/kernel/controller/domain/execution-quality.ts +3 -1
- package/packages/kernel/controller/infrastructure/controller-round-store.ts +689 -103
- package/packages/kernel/controller/infrastructure/controller-session-store.ts +297 -71
- package/packages/kernel/controller/ports/controller-host.ts +2 -0
- package/packages/kernel/identity/api/index.ts +10 -0
- package/packages/kernel/identity/domain/activity-projection.ts +43 -0
- package/packages/kernel/identity/domain/capability-broker.ts +60 -0
- package/packages/kernel/identity/domain/grant.ts +72 -0
- package/packages/kernel/identity/domain/owned-resource.ts +116 -0
- package/packages/kernel/identity/domain/user-request.ts +93 -0
- package/packages/kernel/identity/infrastructure/activity-projection-store.ts +77 -0
- package/packages/kernel/identity/infrastructure/capability-broker.ts +81 -0
- package/packages/kernel/identity/infrastructure/grant-store.ts +284 -0
- package/packages/kernel/identity/infrastructure/owned-resource-store.ts +259 -0
- package/packages/kernel/identity/infrastructure/user-request-store.ts +182 -0
- package/packages/kernel/scheduler/api/index.ts +0 -2
- package/packages/kernel/scheduler/application/schedule-service.ts +3 -0
- package/packages/kernel/scheduler/application/settlement.ts +0 -15
- package/packages/kernel/scheduler/domain/schedule.ts +87 -0
- package/packages/kernel/scheduler/infrastructure/schedule-store.ts +153 -133
- package/packages/kernel/work/api/index.ts +3 -2
- package/packages/kernel/work/application/work-service.ts +17 -42
- package/packages/kernel/work/domain/current-task-lineage.ts +104 -0
- package/packages/kernel/work/domain/engineering-design.ts +10 -5
- package/packages/kernel/work/domain/engineering-profile.ts +8 -12
- package/packages/kernel/work/domain/evaluation-promotion-receipt.ts +186 -0
- package/packages/kernel/work/domain/execution-concurrency.ts +19 -26
- package/packages/kernel/work/domain/execution-snapshot.ts +0 -31
- package/packages/kernel/work/domain/implementation-review.ts +14 -331
- package/packages/kernel/work/domain/objective-graph.ts +119 -0
- package/packages/kernel/work/domain/project-engineering-contract.ts +23 -1
- package/packages/kernel/work/domain/repository-completion-receipt.ts +1 -1
- package/packages/kernel/work/domain/state-machine.ts +25 -63
- package/packages/kernel/work/domain/types.ts +57 -51
- package/packages/kernel/work/infrastructure/work-contract-store.ts +819 -728
- package/packages/kernel/work/ports/work-contract-store.ts +5 -2
- package/packages/plugin-runtime/browser/session-authority.ts +2 -1
- package/packages/plugin-runtime/computer/chatgpt-identity.ts +24 -0
- package/packages/plugin-runtime/computer/conversation-target.ts +143 -0
- package/packages/plugin-runtime/computer/index.ts +2 -0
- package/packages/plugin-runtime/computer/target-authority.ts +26 -1
- package/packages/plugin-runtime/external/unix-jsonl-transport.ts +142 -18
- package/packages/protocols/computer/contract.ts +27 -1
- package/scripts/activate-source-baseline.ts +7 -9
- package/scripts/canary-controller-semantic-wait.ts +12 -24
- package/scripts/check-mcp-compatibility.ts +48 -136
- package/scripts/check-runtime-architecture.mjs +622 -217
- package/scripts/forge-local-recovery-helper.mjs +93 -15
- package/scripts/lib/project-init-lib.sh +3 -0
- package/scripts/open-source-audit-allowlist.txt +1 -2
- package/scripts/run-bounded-command.mjs +5 -0
- package/scripts/run-governed-gate.ts +0 -1
- package/scripts/run-mobile-monitor-bridge.ts +0 -1
- package/scripts/smoke-control-plane-failure-domain.ts +94 -0
- package/scripts/smoke-mcp-http-runtime.ts +5 -0
- package/scripts/smoke-runtime-recovery.ts +12 -43
- package/scripts/smoke-schedule-engine.ts +23 -15
- package/scripts/smoke-unattended-transport-recovery.ts +223 -0
- package/scripts/smoke-user-request-continuation-restart.ts +232 -0
- package/scripts/smoke-workflow-supervisor-chrome-adapter.ts +92 -0
- package/scripts/smoke-workflow-supervisor-process-restart.ts +276 -0
- package/scripts/smoke-workflow-supervisor-restart-recovery.ts +150 -0
- package/scripts/smoke-workflow-supervisor.ts +103 -0
- package/scripts/verify-forge-runtime.sh +2 -1
- package/src/cli/agent-jobs/executor-health.ts +11 -34
- package/src/cli/agent-jobs/integration.ts +18 -49
- package/src/cli/agent-jobs/job-manager.ts +7 -3
- package/src/cli/commands/brain-assistant.ts +27 -13
- package/src/cli/commands/brain.ts +13 -15
- package/src/cli/commands/chatgpt.ts +1 -163
- package/src/cli/commands/recovery.ts +135 -121
- package/src/cli/commands/runtime.ts +3 -3
- package/src/cli/commands/setup-profile.ts +8 -0
- package/src/cli/controller/check-runner.ts +13 -2
- package/src/cli/controller/completion-backlog.ts +3 -3
- package/src/cli/controller/completion-orchestrator.ts +4 -43
- package/src/cli/controller/completion-target.ts +3 -72
- package/src/cli/controller/context/source-materializer.ts +81 -100
- package/src/cli/controller/context-pack.ts +10 -8
- package/src/cli/controller/execution-completion.ts +4 -7
- package/src/cli/controller/execution-policy.ts +36 -153
- package/src/cli/controller/governance.ts +2 -3
- package/src/cli/controller/issue-store.ts +4 -99
- package/src/cli/controller/launch-agents.ts +59 -18
- package/src/cli/controller/operational-plan.ts +24 -51
- package/src/cli/controller/runtime-config.ts +5 -1
- package/src/cli/controller/stuck-state-migration.ts +2 -3
- package/src/cli/controller/systemd-user.ts +39 -1
- package/src/cli/editing/edit-session.ts +1 -7
- package/src/cli/local-bridge/console-automations.ts +18 -13
- package/src/cli/local-bridge/console-view-models.ts +3 -12
- package/src/cli/local-bridge/facade-api.ts +64 -191
- package/src/cli/local-bridge/server.ts +24 -147
- package/src/cli/local-bridge/types.ts +0 -1
- package/src/cli/mcp/oauth-client-retirement.ts +74 -0
- package/src/cli/repositories/command-executor.ts +29 -23
- package/src/cli/repositories/command-scope.ts +35 -16
- package/src/cli/repositories/controller-home.ts +48 -0
- package/src/cli/repositories/ephemeral-workspace.ts +20 -30
- package/src/cli/repositories/git-command-executor.ts +2 -2
- package/src/cli/repositories/registry.ts +77 -11
- package/src/cli/repositories/structured-git.ts +62 -2
- package/src/cli/repository/session-cache.ts +92 -6
- package/src/runtime/context/assistant-context.ts +20 -7
- package/src/runtime/context/assistant-work-context.ts +89 -27
- package/src/runtime/context/automatic-learning.ts +565 -0
- package/src/runtime/context/cognitive-attention.ts +173 -0
- package/src/runtime/context/cognitive-skill-canary.ts +158 -0
- package/src/runtime/context/context-closure.ts +46 -9
- package/src/runtime/context/context-pack-process.ts +103 -0
- package/src/runtime/context/context-plane.ts +1 -9
- package/src/runtime/context/direct-controller-learning.ts +298 -0
- package/src/runtime/context/semantic-navigation-contract.ts +9 -0
- package/src/runtime/context/semantic-navigation.ts +6 -34
- package/src/runtime/context/typescript-navigation-process.ts +145 -0
- package/src/runtime/context/typescript-navigation.ts +89 -3
- package/src/runtime/control-plane/cleanup-artifact-retention.ts +212 -9
- package/src/runtime/control-plane/concurrency/work-execution-concurrency.ts +9 -47
- package/src/runtime/control-plane/execution/controller-authority-recovery.ts +34 -4
- package/src/runtime/control-plane/execution/edit-validation-coordinator.ts +29 -20
- package/src/runtime/control-plane/execution/execution-identity.ts +23 -3
- package/src/runtime/control-plane/execution/repository-work-attribution.ts +7 -30
- package/src/runtime/control-plane/execution/retained-work-resume.ts +206 -199
- package/src/runtime/control-plane/execution/session-store.ts +31 -1
- package/src/runtime/control-plane/execution/validation.ts +6 -8
- package/src/runtime/control-plane/execution/work-authority-reconciler.ts +13 -42
- package/src/runtime/control-plane/execution/work-check-evidence.ts +137 -0
- package/src/runtime/control-plane/execution/work-completion-authority.ts +30 -85
- package/src/runtime/control-plane/execution/work-delivery-service.ts +497 -0
- package/src/runtime/control-plane/execution/work-evidence-policy.ts +12 -50
- package/src/runtime/control-plane/execution/work-execution-support.ts +50 -149
- package/src/runtime/control-plane/execution/work-handle-authority.ts +188 -109
- package/src/runtime/control-plane/execution/work-handle-store.ts +19 -43
- package/src/runtime/control-plane/execution/work-head-settlement.ts +53 -20
- package/src/runtime/control-plane/execution/work-lifecycle-audit.ts +52 -29
- package/src/runtime/control-plane/execution/work-operation-service.ts +43 -27
- package/src/runtime/control-plane/execution/work-preparation-service.ts +126 -266
- package/src/runtime/control-plane/execution/work-remote-delivery.ts +2 -3
- package/src/runtime/control-plane/execution/work-revision-diff.ts +39 -0
- package/src/runtime/control-plane/execution/work-terminal-cleanup.ts +173 -186
- package/src/runtime/control-plane/execution/work-validation-reconciler.ts +28 -84
- package/src/runtime/control-plane/execution/work-verification-service.ts +406 -50
- package/src/runtime/control-plane/execution/work-verification-snapshot.ts +5 -1
- package/src/runtime/control-plane/facade/capability-registry.ts +362 -37
- package/src/runtime/control-plane/facade/check-normalization.ts +3 -9
- package/src/runtime/control-plane/facade/codex-delegation.ts +10 -11
- package/src/runtime/control-plane/facade/controller-connection.ts +135 -0
- package/src/runtime/control-plane/facade/goal-workloop-access.ts +1 -20
- package/src/runtime/control-plane/facade/goal-workloop.ts +281 -1753
- package/src/runtime/control-plane/facade/handoff-inbox-application.ts +12 -25
- package/src/runtime/control-plane/facade/handoff-inbox-store.ts +256 -52
- package/src/runtime/control-plane/facade/index.ts +0 -1
- package/src/runtime/control-plane/facade/operation-digest.ts +12 -15
- package/src/runtime/control-plane/facade/plan-contract-store.ts +451 -991
- package/src/runtime/control-plane/facade/policy-gate.ts +0 -23
- package/src/runtime/control-plane/facade/repository-work-admission.ts +12 -22
- package/src/runtime/control-plane/facade/requirement-authority.ts +102 -199
- package/src/runtime/control-plane/facade/requirement-board.ts +3 -3
- package/src/runtime/control-plane/facade/rh-work-operation-contract.ts +51 -14
- package/src/runtime/control-plane/facade/self-healing-loop.ts +18 -53
- package/src/runtime/control-plane/facade/suggested-actions.ts +15 -18
- package/src/runtime/control-plane/facade/types.ts +49 -108
- package/src/runtime/control-plane/facade/work-continuation.ts +8 -8
- package/src/runtime/control-plane/generated-cache-retention.ts +97 -1
- package/src/runtime/control-plane/global-scheduler/autonomous-continuation.ts +248 -0
- package/src/runtime/control-plane/global-scheduler/durable-admission.ts +1 -1
- package/src/runtime/control-plane/global-scheduler/maintenance.ts +239 -112
- package/src/runtime/control-plane/global-scheduler/reconciliation.ts +2 -1
- package/src/runtime/control-plane/global-scheduler/scheduler.ts +66 -40
- package/src/runtime/control-plane/global-scheduler/wake-signal.ts +42 -2
- package/src/runtime/control-plane/governance/access-policy.ts +19 -2
- package/src/runtime/control-plane/governance/authorization.ts +20 -3
- package/src/runtime/control-plane/launcher/chatgpt-round-continuation.ts +63 -300
- package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +28 -300
- package/src/runtime/control-plane/launcher/local-conversation-controller.ts +238 -0
- package/src/runtime/control-plane/launcher/provider-mcp-bootstrap.ts +5 -2
- package/src/runtime/control-plane/launcher/thin-launcher.ts +96 -240
- package/src/runtime/control-plane/persistence/cognition-store.ts +820 -0
- package/src/runtime/control-plane/persistence/experience-store.ts +162 -29
- package/src/runtime/control-plane/persistence/requirement-store.ts +216 -74
- package/src/runtime/control-plane/persistence/sqlite-store.ts +113 -6
- package/src/runtime/control-plane/release-retention.ts +135 -47
- package/src/runtime/control-plane/repository-namespace-retention.ts +2 -2
- package/src/runtime/control-plane/runtime-cleanup.ts +290 -21
- package/src/runtime/control-plane/workspace/project-onboarding.ts +80 -0
- package/src/runtime/control-plane/workspace/semantic-sync-service.ts +19 -5
- package/src/runtime/control-plane/workspace/workspace-store.ts +169 -0
- package/src/runtime/diagnostics/incident-repair.ts +313 -146
- package/src/runtime/diagnostics/mcp-timing.ts +114 -0
- package/src/runtime/evidence/artifact-store.ts +158 -40
- package/src/runtime/evidence/evidence-store.ts +112 -8
- package/src/runtime/evidence/output-handle-index.ts +225 -0
- package/src/runtime/evidence/result-store.ts +158 -44
- package/src/runtime/execution/jobs/store.ts +3 -4
- package/src/runtime/execution/managed-workspace.ts +57 -0
- package/src/runtime/execution/process-runtime/check-facade.ts +1 -1
- package/src/runtime/execution/process-runtime/check-result-retention.ts +2 -2
- package/src/runtime/execution/process-runtime/check-result.ts +105 -1
- package/src/runtime/execution/process-runtime/check-runner-sidecar.ts +18 -8
- package/src/runtime/execution/process-runtime/command-facade.ts +79 -27
- package/src/runtime/execution/process-runtime/gc.ts +15 -2
- package/src/runtime/execution/process-runtime/handle-index.ts +176 -0
- package/src/runtime/execution/process-runtime/host-command-lane.ts +139 -0
- package/src/runtime/execution/process-runtime/index.ts +3 -0
- package/src/runtime/execution/process-runtime/lightweight-managed.ts +251 -72
- package/src/runtime/execution/process-runtime/persisted-check.ts +3 -3
- package/src/runtime/execution/process-runtime/process-runner-entry.ts +47 -5
- package/src/runtime/execution/process-runtime/process-scope.ts +160 -0
- package/src/runtime/execution/process-runtime/resource-claims.ts +65 -61
- package/src/runtime/execution/process-runtime/runtime.ts +35 -2
- package/src/runtime/execution/process-runtime/store.ts +30 -2
- package/src/runtime/execution/process-runtime/types.ts +6 -1
- package/src/runtime/execution/workers/executor.ts +2 -6
- package/src/runtime/platform/service-inventory.ts +130 -0
- package/src/runtime/platform/service-manager.ts +8 -0
- package/src/runtime/plugins/action-application.ts +85 -28
- package/src/runtime/plugins/app-store-connect-adapter.ts +38 -14
- package/src/runtime/plugins/browser-adapter.ts +757 -34
- package/src/runtime/plugins/browser-automation-service.ts +23 -3
- package/src/runtime/plugins/browser-macos-bridge.ts +321 -29
- package/src/runtime/plugins/browser-manifest-surface.ts +45 -11
- package/src/runtime/plugins/browser-native-session-service.ts +63 -13
- package/src/runtime/plugins/browser-registration.ts +16 -0
- package/src/runtime/plugins/browser-runtime.ts +14 -1
- package/src/runtime/plugins/browser-session-authority.ts +2 -2
- package/src/runtime/plugins/browser-session-store.ts +46 -76
- package/src/runtime/plugins/capability-authorization-grants.ts +258 -62
- package/src/runtime/plugins/computer-chatgpt-browser-adapter-installer.ts +219 -0
- package/src/runtime/plugins/computer-chatgpt-macos-target.ts +891 -0
- package/src/runtime/plugins/computer-registration.ts +222 -11
- package/src/runtime/plugins/desktop-operator-external-policy.ts +36 -4
- package/src/runtime/plugins/desktop-operator-registration.ts +12 -4
- package/src/runtime/plugins/external-adapter.ts +42 -6
- package/src/runtime/plugins/external-registration.ts +21 -1
- package/src/runtime/plugins/gmail-adapter.ts +23 -2
- package/src/runtime/plugins/google-calendar-adapter.ts +2 -2
- package/src/runtime/plugins/google-shared.ts +14 -7
- package/src/runtime/plugins/google-tasks-adapter.ts +2 -2
- package/src/runtime/plugins/ios-adapter.ts +1 -1
- package/src/runtime/plugins/lightweight-action.ts +208 -2
- package/src/runtime/plugins/local-system-adapter.ts +12 -2
- package/src/runtime/plugins/managed-process-adapter.ts +12 -5
- package/src/runtime/plugins/plugin-action-sidecar.ts +17 -13
- package/src/runtime/plugins/plugin-management-adapter.ts +1 -1
- package/src/runtime/plugins/store.ts +602 -428
- package/src/runtime/plugins/types.ts +20 -0
- package/src/runtime/plugins/xiaohongshu-publish.ts +16 -0
- package/src/runtime/projections/invalidation.ts +7 -3
- package/src/runtime/projections/materialized-view.ts +80 -36
- package/src/runtime/recovery/actions.ts +3 -3
- package/src/runtime/recovery/capability-action-application.ts +46 -45
- package/src/runtime/recovery/lifecycle-inventory.ts +29 -29
- package/src/runtime/recovery/maintenance-executor.ts +374 -123
- package/src/runtime/recovery/store.ts +29 -11
- package/src/runtime/release/release-coordinator.ts +296 -0
- package/src/runtime/release/release-session.ts +716 -0
- package/src/runtime/release/release-state-migration.ts +25 -0
- package/src/runtime/resources/leases/store.ts +56 -25
- package/src/runtime/root/computer-composition.ts +191 -6
- package/src/runtime/root/controller-progression-composition.ts +192 -0
- package/src/runtime/root/controller-round-composition.ts +20 -1
- package/src/runtime/root/deployment-topology.ts +106 -0
- package/src/runtime/root/entry.ts +4 -3
- package/src/runtime/root/known-good-recovery.ts +184 -0
- package/src/runtime/root/local-bridge.ts +0 -1
- package/src/runtime/root/mcp-transport.ts +111 -18
- package/src/runtime/root/ownership.ts +261 -9
- package/src/runtime/root/package-connector-service.ts +105 -19
- package/src/runtime/root/package-runtime-release.ts +117 -18
- package/src/runtime/root/package-runtime-service.ts +17 -11
- package/src/runtime/root/release-execution-canary.ts +44 -12
- package/src/runtime/root/release-loader.ts +90 -8
- package/src/runtime/root/release-manifest.ts +80 -6
- package/src/runtime/root/release-materialize.ts +372 -28
- package/src/runtime/root/release-store.ts +395 -36
- package/src/runtime/root/runtime-lane.ts +191 -0
- package/src/runtime/root/runtime.ts +159 -27
- package/src/runtime/root/scheduled-controller-composition.ts +28 -3
- package/src/runtime/root/service-runner.ts +2 -2
- package/src/runtime/root/service.ts +36 -33
- package/src/runtime/root/status.ts +48 -0
- package/src/runtime/root/types.ts +32 -3
- package/src/runtime/root/workflow-supervisor-composition.ts +493 -0
- package/src/runtime/root/workflow-supervisor-runtime.ts +209 -0
- package/src/runtime/root/write-fence.ts +50 -2
- package/src/runtime/safe-tooling/google-credential-store.ts +76 -21
- package/src/runtime/safe-tooling/google-oauth-broker.ts +25 -7
- package/src/runtime/safe-tooling/workspace-auth.ts +1 -1
- package/src/runtime/shared/bounded-child-supervisor.ts +9 -1
- package/src/runtime/shared/process-environment.ts +20 -9
- package/src/runtime/shared/response-budget.ts +1 -3
- package/src/runtime/standalone-recovery/controller-home-migration.ts +16 -24
- package/src/runtime/standalone-recovery/core.ts +3702 -342
- package/src/runtime/standalone-recovery/entry.ts +469 -39
- package/src/runtime/standalone-recovery/installer.ts +262 -148
- package/src/runtime/standalone-recovery/mcp-server.ts +29 -193
- package/src/runtime/standalone-recovery/operation-lock.ts +1 -1
- package/src/runtime/standalone-recovery/performance.ts +54 -16
- package/src/runtime/standalone-recovery/release.ts +53 -5
- package/src/runtime/standalone-recovery/service-labels.ts +5 -2
- package/src/runtime/standalone-recovery/watchdog-heartbeat.ts +5 -2
- package/src/runtime/workflow/schedules/browser-probe.ts +17 -6
- package/src/runtime/workflow/schedules/chatgpt-automation-migration.ts +10 -3
- package/src/runtime/workflow/schedules/engine.ts +138 -172
- package/src/runtime/workflow/schedules/work-continuation.ts +44 -5
- package/src/runtime/workflows/runtime.ts +15 -19
- package/src/testing/test-governance.ts +5 -1
- package/supervisor/chatgpt-conversation.ts +23 -0
- package/supervisor/client.ts +201 -0
- package/supervisor/control-plane.ts +868 -0
- package/supervisor/entry.ts +15 -0
- package/supervisor/forge-validators.ts +80 -0
- package/supervisor/index.ts +5 -0
- package/supervisor/native-browser-adapter.ts +786 -0
- package/supervisor/native-messaging/host.ts +39 -0
- package/supervisor/native-messaging/manifest.ts +26 -0
- package/supervisor/native-messaging/protocol.ts +27 -0
- package/supervisor/paths.ts +18 -0
- package/supervisor/protocol.ts +202 -0
- package/supervisor/server.ts +404 -0
- package/supervisor/store.ts +1451 -0
- package/supervisor/tsconfig.json +8 -0
- package/supervisor/types.ts +255 -0
- package/adapters/chatgpt/controller-host.ts +0 -119
- package/adapters/mcp/controller-round-compatibility.ts +0 -184
- package/adapters/mcp/frozen-client-semantic-compatibility.ts +0 -292
- package/adapters/mcp/runtime-gateway/work-compat-adapter.ts +0 -502
- package/packages/kernel/progression/api/index.ts +0 -2
- package/packages/kernel/progression/application/projector.ts +0 -211
- package/packages/kernel/progression/domain/types.ts +0 -116
- package/packages/kernel/progression/index.ts +0 -1
- package/packages/kernel/scheduler/application/continuation-service.ts +0 -212
- package/packages/kernel/scheduler/domain/continuation.ts +0 -38
- package/packages/kernel/scheduler/infrastructure/continuation-dispatch-store.ts +0 -38
- package/packages/kernel/work/domain/admission-policy.ts +0 -34
- package/scripts/benchmark-background-check-overlap.ts +0 -228
- package/scripts/benchmark-computer-hotpath.ts +0 -255
- package/scripts/benchmark-controller-hotpath.ts +0 -212
- package/scripts/benchmark-controller-round2.ts +0 -191
- package/scripts/benchmark-ios-agent-device.ts +0 -511
- package/scripts/benchmark-mcp-host.sh +0 -117
- package/scripts/benchmark-mcp-transport.ts +0 -169
- package/scripts/benchmark-operational-memory-activation.ts +0 -235
- package/scripts/benchmark-operational-shadow.ts +0 -28
- package/scripts/benchmark-quality-harness.ts +0 -146
- package/scripts/benchmark-route-session-concurrency.ts +0 -915
- package/scripts/benchmark-thin-harness-gateway-ab.ts +0 -632
- package/scripts/benchmark-thin-harness-mcp-e2e.ts +0 -498
- package/scripts/benchmark-thin-harness.ts +0 -251
- package/scripts/benchmark-typescript-navigation.ts +0 -186
- package/scripts/benchmark-work-efficiency.ts +0 -334
- package/scripts/build-controller-ui.ts +0 -28
- package/scripts/check-npm-release.sh +0 -32
- package/scripts/check-public-release-surface.sh +0 -19
- package/scripts/check-release-published.sh +0 -57
- package/scripts/check-release-readiness.sh +0 -37
- package/scripts/check-release-version.mjs +0 -74
- package/scripts/check-tarball-install-smoke.sh +0 -150
- package/scripts/package-source-archive.sh +0 -147
- package/scripts/public-release-files.txt +0 -39
- package/scripts/public-release.ts +0 -174
- package/scripts/publish-release-tarball.sh +0 -27
- package/scripts/route-nl-vs-ts-eval.ts +0 -679
- package/scripts/stage-runtime-release.ts +0 -44
- package/src/cli/controller/progress.ts +0 -656
- package/src/cli/controller/work-mode.ts +0 -181
- package/src/cli/local-bridge/console-assets.ts +0 -17
- package/src/cli/local-bridge/dashboard.ts +0 -17
- package/src/cli/local-bridge/frontend/src/App.tsx +0 -10
- package/src/cli/local-bridge/frontend/src/components/Button.tsx +0 -1
- package/src/cli/local-bridge/frontend/src/components/DetailPane.tsx +0 -3
- package/src/cli/local-bridge/frontend/src/components/SearchField.tsx +0 -1
- package/src/cli/local-bridge/frontend/src/components/SectionHeader.tsx +0 -1
- package/src/cli/local-bridge/frontend/src/components/Segmented.tsx +0 -1
- package/src/cli/local-bridge/frontend/src/components/StatusText.tsx +0 -3
- package/src/cli/local-bridge/frontend/src/design/icons.tsx +0 -11
- package/src/cli/local-bridge/frontend/src/design/tokens.css +0 -8
- package/src/cli/local-bridge/frontend/src/features/automations/AutomationsView.tsx +0 -153
- package/src/cli/local-bridge/frontend/src/features/capabilities/CapabilitiesView.tsx +0 -37
- package/src/cli/local-bridge/frontend/src/features/overview/OverviewView.tsx +0 -183
- package/src/cli/local-bridge/frontend/src/features/repositories/RepositoriesView.tsx +0 -2
- package/src/cli/local-bridge/frontend/src/features/system/SystemView.tsx +0 -2
- package/src/cli/local-bridge/frontend/src/features/work/WorkView.tsx +0 -4
- package/src/cli/local-bridge/frontend/src/lib/api.ts +0 -30
- package/src/cli/local-bridge/frontend/src/lib/format.ts +0 -4
- package/src/cli/local-bridge/frontend/src/lib/routes.ts +0 -7
- package/src/cli/local-bridge/frontend/src/main.tsx +0 -1
- package/src/cli/local-bridge/frontend/src/shell/AppShell.tsx +0 -1
- package/src/cli/local-bridge/frontend/src/shell/CommandBar.tsx +0 -2
- package/src/cli/local-bridge/frontend/src/shell/Sidebar.tsx +0 -4
- package/src/cli/local-bridge/frontend/src/styles.css +0 -28
- package/src/cli/local-bridge/frontend/src/types.ts +0 -15
- package/src/cli/local-bridge/frontend/src/vite-env.d.ts +0 -1
- package/src/cli/local-bridge/frontend/vite.config.ts +0 -27
- package/src/cli/local-bridge/ui-dist/app.css +0 -1
- package/src/cli/local-bridge/ui-dist/app.js +0 -11228
- package/src/runtime/control-plane/execution/content-equivalent-commit-authority.ts +0 -169
- package/src/runtime/control-plane/execution/direct-canonical-work-reconciliation.ts +0 -85
- package/src/runtime/control-plane/execution/direct-edit-work-completion.ts +0 -655
- package/src/runtime/control-plane/execution/work-finalization-service.ts +0 -2850
- package/src/runtime/control-plane/execution/work-path-scope.ts +0 -37
- package/src/runtime/control-plane/execution/work-task-receipt.ts +0 -468
- package/src/runtime/control-plane/facade/controller-round-relay.ts +0 -3
- package/src/runtime/control-plane/facade/work-admission-policy.ts +0 -142
- package/src/runtime/control-plane/facade/work-implementation-review.ts +0 -2
- package/src/runtime/control-plane/facade/work-state-machine.ts +0 -2
- package/src/runtime/control-plane/facade/work-task-projection.ts +0 -66
- package/src/runtime/control-plane/routing/index.ts +0 -1
- package/src/runtime/control-plane/routing/route-policy.ts +0 -401
- package/src/runtime/control-plane/routing/workspace-admission.ts +0 -70
|
@@ -269,7 +269,7 @@ export async function runPersistedCheckViaProcessRuntime(
|
|
|
269
269
|
check,
|
|
270
270
|
durable: {
|
|
271
271
|
reason: 'multi_phase_or_release_check_requires_durable_workflow',
|
|
272
|
-
suggestedOperation: '
|
|
272
|
+
suggestedOperation: 'Run this check through a Work-bound durable verification workflow.',
|
|
273
273
|
},
|
|
274
274
|
durableSideEffects: emptyEffects,
|
|
275
275
|
};
|
|
@@ -312,7 +312,7 @@ export async function runPersistedCheckViaProcessRuntime(
|
|
|
312
312
|
const liveCertification = check.executionAuthority === 'live_controller_home';
|
|
313
313
|
if (liveCertification && input.allowDurableCheckExecution !== true) {
|
|
314
314
|
cleanupVerificationSnapshot();
|
|
315
|
-
throw new Error('
|
|
315
|
+
throw new Error('LIVE_CHECK_DURABLE_AUTHORITY_REQUIRED');
|
|
316
316
|
}
|
|
317
317
|
const liveExecutionStateFingerprint = liveCertification
|
|
318
318
|
? controllerCheckLiveExecutionStateFingerprint(input.controllerHome)
|
|
@@ -422,7 +422,7 @@ export async function runPersistedCheckViaProcessRuntime(
|
|
|
422
422
|
issueId: input.verificationBinding?.issueId,
|
|
423
423
|
taskId: input.verificationBinding?.taskId,
|
|
424
424
|
checkResultReceiptPath,
|
|
425
|
-
workVerificationSnapshot:
|
|
425
|
+
...(verificationSnapshot ? { workVerificationSnapshot: true } : {}),
|
|
426
426
|
},
|
|
427
427
|
signal: input.signal,
|
|
428
428
|
});
|
|
@@ -33,9 +33,11 @@ import {
|
|
|
33
33
|
rmSync,
|
|
34
34
|
writeFileSync,
|
|
35
35
|
} from 'fs';
|
|
36
|
-
import { dirname, join } from 'path';
|
|
36
|
+
import { dirname, join, resolve } from 'path';
|
|
37
37
|
import { spawn, type ChildProcess } from 'child_process';
|
|
38
38
|
import { repositoryChildProcessEnvironment } from '../../shared/process-environment.ts';
|
|
39
|
+
import { currentRuntimeWriteClaimEnvironment } from '../../root/write-fence.ts';
|
|
40
|
+
import { readRuntimeReleaseAuthority } from '../../root/release-store.ts';
|
|
39
41
|
import { StreamingSensitiveTextRedactor } from '../../evidence/sensitive-output.ts';
|
|
40
42
|
import { PROCESS_RUNNER_RELEASE_CANARY_CHILD_ARG } from './canary.ts';
|
|
41
43
|
|
|
@@ -44,6 +46,7 @@ export interface ProcessCommandDescriptor {
|
|
|
44
46
|
processId: string;
|
|
45
47
|
repoId: string;
|
|
46
48
|
controllerHome: string;
|
|
49
|
+
trustedRuntimeChild?: 'plugin_action_sidecar';
|
|
47
50
|
command: {
|
|
48
51
|
kind: 'argv' | 'shell';
|
|
49
52
|
executable?: string;
|
|
@@ -101,9 +104,26 @@ function loadDescriptor(path: string): ProcessCommandDescriptor {
|
|
|
101
104
|
return value;
|
|
102
105
|
}
|
|
103
106
|
|
|
104
|
-
function
|
|
107
|
+
function commandEnvironment(descriptor: ProcessCommandDescriptor): NodeJS.ProcessEnv {
|
|
108
|
+
const command = descriptor.command;
|
|
109
|
+
const sanitized = repositoryChildProcessEnvironment({ ...process.env, ...(command.env ?? {}) });
|
|
110
|
+
if (descriptor.trustedRuntimeChild !== 'plugin_action_sidecar') return sanitized;
|
|
111
|
+
if (command.kind !== 'argv' || !command.executable) {
|
|
112
|
+
throw new Error('PROCESS_RUNNER_TRUSTED_RUNTIME_CHILD_INVALID: plugin action sidecar requires argv executable');
|
|
113
|
+
}
|
|
114
|
+
const authority = readRuntimeReleaseAuthority(descriptor.controllerHome);
|
|
115
|
+
if (!authority) throw new Error('PROCESS_RUNNER_TRUSTED_RUNTIME_CHILD_INVALID: Runtime release authority is missing');
|
|
116
|
+
const expected = resolve(dirname(authority.active.manifestPath), 'forge-plugin-action-sidecar');
|
|
117
|
+
if (resolve(command.executable) !== expected) {
|
|
118
|
+
throw new Error(`PROCESS_RUNNER_TRUSTED_RUNTIME_CHILD_INVALID: expected ${expected}`);
|
|
119
|
+
}
|
|
120
|
+
return { ...sanitized, ...currentRuntimeWriteClaimEnvironment(descriptor.controllerHome) };
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function spawnCommand(descriptor: ProcessCommandDescriptor): ChildProcess {
|
|
124
|
+
const command = descriptor.command;
|
|
105
125
|
const useProcessGroup = process.platform !== 'win32';
|
|
106
|
-
const env =
|
|
126
|
+
const env = commandEnvironment(descriptor);
|
|
107
127
|
if (command.kind === 'shell') {
|
|
108
128
|
const shell = process.platform === 'win32' ? 'cmd.exe' : '/bin/bash';
|
|
109
129
|
const shellArgs = process.platform === 'win32'
|
|
@@ -316,15 +336,37 @@ export async function runProcessRunnerFromDescriptor(
|
|
|
316
336
|
|
|
317
337
|
let spawnedChild: ChildProcess;
|
|
318
338
|
try {
|
|
319
|
-
spawnedChild = spawnCommand(descriptor
|
|
339
|
+
spawnedChild = spawnCommand(descriptor);
|
|
320
340
|
child = spawnedChild;
|
|
321
341
|
if (pendingSignal) void killTree(spawnedChild);
|
|
322
342
|
} catch (error) {
|
|
323
343
|
process.removeListener('SIGTERM', onSigterm);
|
|
324
344
|
process.removeListener('SIGINT', onSigint);
|
|
345
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
346
|
+
stderr.write(Buffer.from(`\n[process-runner] pre-spawn error: ${message}\n`));
|
|
325
347
|
stdout.close();
|
|
326
348
|
stderr.close();
|
|
327
|
-
|
|
349
|
+
const outStats = stdout.stats();
|
|
350
|
+
const errStats = stderr.stats();
|
|
351
|
+
const receipt: ProcessRunnerExitReceipt = {
|
|
352
|
+
schemaVersion: 1,
|
|
353
|
+
processId: descriptor.processId,
|
|
354
|
+
exitCode: 1,
|
|
355
|
+
finishedAt: new Date().toISOString(),
|
|
356
|
+
startedAt: descriptor.startedAt,
|
|
357
|
+
stdoutBytes: outStats.totalBytes,
|
|
358
|
+
stderrBytes: errStats.totalBytes,
|
|
359
|
+
stdoutStoredBytes: outStats.storedBytes,
|
|
360
|
+
stderrStoredBytes: errStats.storedBytes,
|
|
361
|
+
logTruncated: outStats.truncated || errStats.truncated,
|
|
362
|
+
runnerPid: process.pid,
|
|
363
|
+
// The exactly-once logical Process attempt reached a deterministic terminal
|
|
364
|
+
// result before an external child could be spawned; the started claim is
|
|
365
|
+
// therefore consumed and must never authorize replay.
|
|
366
|
+
commandExecutedOnce: true,
|
|
367
|
+
};
|
|
368
|
+
atomicWrite(descriptor.exitReceiptPath, receipt);
|
|
369
|
+
return receipt;
|
|
328
370
|
}
|
|
329
371
|
|
|
330
372
|
const timeoutHandle = setTimeout(() => {
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical Process/Operation storage scope.
|
|
3
|
+
*
|
|
4
|
+
* Repository placement is optional context for a process, never its address
|
|
5
|
+
* space. A process whose target is the Forge instance itself (host-local
|
|
6
|
+
* command, controller-global operation, ephemeral workspace command) is stored
|
|
7
|
+
* in the instance partition and is addressed by its process handle only.
|
|
8
|
+
*
|
|
9
|
+
* Scope keys are stable partition identifiers:
|
|
10
|
+
* - repository scope key is the registered repository id (unchanged on disk)
|
|
11
|
+
* - instance scope key is `instance`, which cannot collide with a registered
|
|
12
|
+
* repository id (`repo_*`) or workspace id (`workspace_*`)
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { join } from 'path';
|
|
16
|
+
import {
|
|
17
|
+
isWorkspaceScopeKey,
|
|
18
|
+
repositoryControllerRoot,
|
|
19
|
+
workspaceScopeRoot,
|
|
20
|
+
} from '../../../cli/repositories/controller-home';
|
|
21
|
+
import {
|
|
22
|
+
forgeInstanceExecutionTarget,
|
|
23
|
+
repositoryExecutionTarget,
|
|
24
|
+
resolveProcessExecutionTarget,
|
|
25
|
+
workspaceExecutionTarget,
|
|
26
|
+
type ProcessExecutionTarget,
|
|
27
|
+
} from './handle-index';
|
|
28
|
+
|
|
29
|
+
export const FORGE_INSTANCE_PROCESS_SCOPE_KEY = 'instance';
|
|
30
|
+
/** Reserved prefix for workspace process scopes; registered repository ids are `repo_*`. */
|
|
31
|
+
export { WORKSPACE_SCOPE_PREFIX as WORKSPACE_PROCESS_SCOPE_PREFIX } from '../../../cli/repositories/controller-home';
|
|
32
|
+
|
|
33
|
+
export interface RepositoryProcessScope {
|
|
34
|
+
schemaVersion: 1;
|
|
35
|
+
kind: 'repository';
|
|
36
|
+
repositoryId: string;
|
|
37
|
+
checkoutId?: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface ForgeInstanceProcessScope {
|
|
41
|
+
schemaVersion: 1;
|
|
42
|
+
kind: 'forge_instance';
|
|
43
|
+
forgeInstanceId?: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* An arbitrary workspace target has no repository semantics, so its processes
|
|
48
|
+
* live in a workspace partition instead of a repository partition.
|
|
49
|
+
*/
|
|
50
|
+
export interface WorkspaceProcessScope {
|
|
51
|
+
schemaVersion: 1;
|
|
52
|
+
kind: 'workspace';
|
|
53
|
+
workspaceId: string;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export type ProcessScope = RepositoryProcessScope | ForgeInstanceProcessScope | WorkspaceProcessScope;
|
|
57
|
+
|
|
58
|
+
function requireSegment(value: string, code: string): string {
|
|
59
|
+
const normalized = value.trim();
|
|
60
|
+
if (!normalized || normalized.length > 512) throw new Error(code);
|
|
61
|
+
return normalized;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function repositoryProcessScope(repositoryId: string, checkoutId?: string): RepositoryProcessScope {
|
|
65
|
+
const repository = requireSegment(repositoryId, 'PROCESS_SCOPE_REPOSITORY_ID_REQUIRED');
|
|
66
|
+
if (repository === FORGE_INSTANCE_PROCESS_SCOPE_KEY) throw new Error('PROCESS_SCOPE_REPOSITORY_ID_RESERVED');
|
|
67
|
+
if (isWorkspaceScopeKey(repository)) throw new Error('PROCESS_SCOPE_REPOSITORY_ID_RESERVED');
|
|
68
|
+
const checkout = checkoutId?.trim();
|
|
69
|
+
return { schemaVersion: 1, kind: 'repository', repositoryId: repository, ...(checkout ? { checkoutId: checkout } : {}) };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function forgeInstanceProcessScope(forgeInstanceId?: string): ForgeInstanceProcessScope {
|
|
73
|
+
const instanceId = forgeInstanceId?.trim();
|
|
74
|
+
return { schemaVersion: 1, kind: 'forge_instance', ...(instanceId ? { forgeInstanceId: instanceId } : {}) };
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function workspaceProcessScope(workspaceId: string): WorkspaceProcessScope {
|
|
78
|
+
return { schemaVersion: 1, kind: 'workspace', workspaceId: requireSegment(workspaceId, 'PROCESS_SCOPE_WORKSPACE_ID_REQUIRED') };
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** Stable storage/attachment partition key for one process scope. */
|
|
82
|
+
export function processScopeKey(scope: ProcessScope): string {
|
|
83
|
+
if (scope.kind === 'forge_instance') return FORGE_INSTANCE_PROCESS_SCOPE_KEY;
|
|
84
|
+
if (scope.kind === 'workspace') return requireSegment(scope.workspaceId, 'PROCESS_SCOPE_WORKSPACE_ID_REQUIRED');
|
|
85
|
+
if (isWorkspaceScopeKey(scope.repositoryId)) throw new Error('PROCESS_SCOPE_REPOSITORY_ID_RESERVED');
|
|
86
|
+
return requireSegment(scope.repositoryId, 'PROCESS_SCOPE_REPOSITORY_ID_REQUIRED');
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Normalize a scope key supplied by a caller. A bare repository id keeps its
|
|
91
|
+
* established meaning as the repository scope key; `instance` selects the
|
|
92
|
+
* ForgeInstance partition.
|
|
93
|
+
*/
|
|
94
|
+
export function normalizeProcessScopeKey(value: string): string {
|
|
95
|
+
const key = requireSegment(value, 'PROCESS_SCOPE_KEY_REQUIRED');
|
|
96
|
+
return key;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export function processScopeFromKey(key: string): ProcessScope {
|
|
100
|
+
const normalized = normalizeProcessScopeKey(key);
|
|
101
|
+
if (normalized === FORGE_INSTANCE_PROCESS_SCOPE_KEY) return forgeInstanceProcessScope();
|
|
102
|
+
if (isWorkspaceScopeKey(normalized)) return workspaceProcessScope(normalized);
|
|
103
|
+
return repositoryProcessScope(normalized);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function isForgeInstanceProcessScopeKey(key: string): boolean {
|
|
107
|
+
return key.trim() === FORGE_INSTANCE_PROCESS_SCOPE_KEY;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** An arbitrary workspace target is addressed by its workspace id, never by a repository id. */
|
|
111
|
+
export function isWorkspaceProcessScopeKey(key: string): boolean {
|
|
112
|
+
return isWorkspaceScopeKey(key);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** True when the scope key addresses a registered repository partition. */
|
|
116
|
+
export function isRepositoryProcessScopeKey(key: string): boolean {
|
|
117
|
+
const normalized = key.trim();
|
|
118
|
+
return normalized.length > 0
|
|
119
|
+
&& normalized !== FORGE_INSTANCE_PROCESS_SCOPE_KEY
|
|
120
|
+
&& !isWorkspaceProcessScopeKey(normalized);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Controller-Home root for one process scope. Repository scopes keep their
|
|
125
|
+
* existing per-repository layout; instance and workspace scopes own ordinary
|
|
126
|
+
* sibling partitions so non-repository processes never require a synthetic
|
|
127
|
+
* repository identity.
|
|
128
|
+
*/
|
|
129
|
+
export function processScopeRoot(controllerHome: string, scopeKey: string): string {
|
|
130
|
+
const key = normalizeProcessScopeKey(scopeKey);
|
|
131
|
+
if (isForgeInstanceProcessScopeKey(key)) return join(controllerHome, FORGE_INSTANCE_PROCESS_SCOPE_KEY);
|
|
132
|
+
if (isWorkspaceProcessScopeKey(key)) return workspaceScopeRoot(controllerHome, key);
|
|
133
|
+
return repositoryControllerRoot(controllerHome, key);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/** Read-only legacy location for workspace-scoped facts written before the workspace partition existed. */
|
|
137
|
+
export function legacyWorkspaceScopeRoot(controllerHome: string, scopeKey: string): string | undefined {
|
|
138
|
+
const key = normalizeProcessScopeKey(scopeKey);
|
|
139
|
+
return isWorkspaceProcessScopeKey(key) ? repositoryControllerRoot(controllerHome, key) : undefined;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/** Handle-index target for one scope, pinned to the serving ForgeInstance when available. */
|
|
143
|
+
export function processScopeExecutionTarget(controllerHome: string, scope: ProcessScope): ProcessExecutionTarget {
|
|
144
|
+
if (scope.kind === 'repository') return repositoryExecutionTarget(controllerHome, scope.repositoryId, scope.checkoutId);
|
|
145
|
+
if (scope.kind === 'workspace') return workspaceExecutionTarget(controllerHome, scope.workspaceId);
|
|
146
|
+
return forgeInstanceExecutionTarget(controllerHome);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Scope key recorded for one process handle. The Process Runtime owns this
|
|
151
|
+
* instance-level index, so attachment resolves the target from the handle
|
|
152
|
+
* instead of scanning repositories or replaying placement inputs.
|
|
153
|
+
*/
|
|
154
|
+
export function processScopeKeyForHandle(controllerHome: string, processId: string): string | undefined {
|
|
155
|
+
const target = resolveProcessExecutionTarget(controllerHome, processId);
|
|
156
|
+
if (!target) return undefined;
|
|
157
|
+
if (target.scope === 'forge_instance') return FORGE_INSTANCE_PROCESS_SCOPE_KEY;
|
|
158
|
+
if (target.scope === 'workspace') return target.workspaceId;
|
|
159
|
+
return target.repositoryId;
|
|
160
|
+
}
|
|
@@ -35,8 +35,12 @@ export type ResourceClaimKind =
|
|
|
35
35
|
| 'heavy_check'
|
|
36
36
|
| 'workspace_write';
|
|
37
37
|
|
|
38
|
-
function checkoutScope(checkoutId?: string): string {
|
|
39
|
-
|
|
38
|
+
function checkoutScope(checkoutId?: string, repoId?: string): string {
|
|
39
|
+
const checkout = checkoutId?.trim();
|
|
40
|
+
if (checkout) return checkout;
|
|
41
|
+
const repository = repoId?.trim();
|
|
42
|
+
if (repository) return `repository-${repository.replace(/[^a-zA-Z0-9._-]+/g, '-')}`;
|
|
43
|
+
throw new Error('RESOURCE_CLAIM_PLACEMENT_REQUIRED');
|
|
40
44
|
}
|
|
41
45
|
|
|
42
46
|
/**
|
|
@@ -44,24 +48,24 @@ function checkoutScope(checkoutId?: string): string {
|
|
|
44
48
|
* Conflict is expressed via mode (read vs write), not a separate key.
|
|
45
49
|
* Legacy workspace-read:* keys are normalized in claims/conflicts.ts.
|
|
46
50
|
*/
|
|
47
|
-
export function claimWorkspaceRead(checkoutId?: string): ResourceClaimSpec {
|
|
48
|
-
return { resourceKey: `workspace:${checkoutScope(checkoutId)}`, mode: 'read' };
|
|
51
|
+
export function claimWorkspaceRead(checkoutId?: string, repoId?: string): ResourceClaimSpec {
|
|
52
|
+
return { resourceKey: `workspace:${checkoutScope(checkoutId, repoId)}`, mode: 'read' };
|
|
49
53
|
}
|
|
50
54
|
|
|
51
|
-
export function claimPathRead(path: string, checkoutId?: string): ResourceClaimSpec {
|
|
52
|
-
if (path === '.') return claimWorkspaceRead(checkoutId);
|
|
55
|
+
export function claimPathRead(path: string, checkoutId?: string, repoId?: string): ResourceClaimSpec {
|
|
56
|
+
if (path === '.') return claimWorkspaceRead(checkoutId, repoId);
|
|
53
57
|
const normalized = normalizeClaimPath(path);
|
|
54
|
-
if (!normalized) return claimWorkspaceRead(checkoutId);
|
|
55
|
-
return { resourceKey: `path:${checkoutScope(checkoutId)}:${normalized}`, mode: 'read' };
|
|
58
|
+
if (!normalized) return claimWorkspaceRead(checkoutId, repoId);
|
|
59
|
+
return { resourceKey: `path:${checkoutScope(checkoutId, repoId)}:${normalized}`, mode: 'read' };
|
|
56
60
|
}
|
|
57
61
|
|
|
58
|
-
export function claimPathWrite(path: string, checkoutId?: string): ResourceClaimSpec {
|
|
62
|
+
export function claimPathWrite(path: string, checkoutId?: string, repoId?: string): ResourceClaimSpec {
|
|
59
63
|
const normalized = normalizeClaimPath(path);
|
|
60
64
|
if (!normalized) {
|
|
61
65
|
// Unsafe / ambiguous path → escalate to whole-checkout workspace write.
|
|
62
|
-
return claimWorkspaceWrite(checkoutId);
|
|
66
|
+
return claimWorkspaceWrite(checkoutId, repoId);
|
|
63
67
|
}
|
|
64
|
-
return { resourceKey: `path:${checkoutScope(checkoutId)}:${normalized}`, mode: 'write' };
|
|
68
|
+
return { resourceKey: `path:${checkoutScope(checkoutId, repoId)}:${normalized}`, mode: 'write' };
|
|
65
69
|
}
|
|
66
70
|
|
|
67
71
|
export function claimBuildCacheRead(repoId: string): ResourceClaimSpec {
|
|
@@ -72,12 +76,12 @@ export function claimBuildCacheWrite(repoId: string): ResourceClaimSpec {
|
|
|
72
76
|
return { resourceKey: `build-cache:${repoId}`, mode: 'write' };
|
|
73
77
|
}
|
|
74
78
|
|
|
75
|
-
export function claimGitIndexRead(checkoutId?: string): ResourceClaimSpec {
|
|
76
|
-
return { resourceKey: `git-index:${checkoutScope(checkoutId)}`, mode: 'read' };
|
|
79
|
+
export function claimGitIndexRead(checkoutId?: string, repoId?: string): ResourceClaimSpec {
|
|
80
|
+
return { resourceKey: `git-index:${checkoutScope(checkoutId, repoId)}`, mode: 'read' };
|
|
77
81
|
}
|
|
78
82
|
|
|
79
|
-
export function claimGitIndex(checkoutId?: string): ResourceClaimSpec {
|
|
80
|
-
return { resourceKey: `git-index:${checkoutScope(checkoutId)}`, mode: 'exclusive' };
|
|
83
|
+
export function claimGitIndex(checkoutId?: string, repoId?: string): ResourceClaimSpec {
|
|
84
|
+
return { resourceKey: `git-index:${checkoutScope(checkoutId, repoId)}`, mode: 'exclusive' };
|
|
81
85
|
}
|
|
82
86
|
|
|
83
87
|
export function claimGitRefsRead(repoId: string): ResourceClaimSpec {
|
|
@@ -92,16 +96,12 @@ export function claimIntegration(repoId: string): ResourceClaimSpec {
|
|
|
92
96
|
return { resourceKey: `integration:${repoId}`, mode: 'exclusive' };
|
|
93
97
|
}
|
|
94
98
|
|
|
95
|
-
export function claimRelease(
|
|
96
|
-
return { resourceKey:
|
|
99
|
+
export function claimRelease(_repoId: string): ResourceClaimSpec {
|
|
100
|
+
return { resourceKey: 'release:runtime-authority', mode: 'exclusive' };
|
|
97
101
|
}
|
|
98
102
|
|
|
99
|
-
export function
|
|
100
|
-
return { resourceKey: `
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
export function claimWorkspaceWrite(checkoutId?: string): ResourceClaimSpec {
|
|
104
|
-
return { resourceKey: `workspace:${checkoutScope(checkoutId)}`, mode: 'write' };
|
|
103
|
+
export function claimWorkspaceWrite(checkoutId?: string, repoId?: string): ResourceClaimSpec {
|
|
104
|
+
return { resourceKey: `workspace:${checkoutScope(checkoutId, repoId)}`, mode: 'write' };
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
export function claimHeavyCheck(repoId: string): ResourceClaimSpec {
|
|
@@ -158,7 +158,7 @@ function iosSimulatorTestCommandClaims(
|
|
|
158
158
|
}
|
|
159
159
|
if (!matches) return undefined;
|
|
160
160
|
return normalizeClaims([
|
|
161
|
-
claimWorkspaceRead(checkoutId),
|
|
161
|
+
claimWorkspaceRead(checkoutId, repoId),
|
|
162
162
|
claimBuildCacheWrite(repoId),
|
|
163
163
|
claimHostService('ios-simulator-test', 'write'),
|
|
164
164
|
]);
|
|
@@ -182,7 +182,7 @@ function localHttpServerClaims(command: string | readonly string[]): ResourceCla
|
|
|
182
182
|
return [claimHostService(`tcp-listen:${bind}:${port}`, 'write')];
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
-
function loopbackCurlClaims(command: string | readonly string[],
|
|
185
|
+
function loopbackCurlClaims(command: string | readonly string[], _repoId: string): ResourceClaimSpec[] | undefined {
|
|
186
186
|
const canonical = normalizeRepositoryCommand(command);
|
|
187
187
|
if (canonical.kind !== 'argv') return undefined;
|
|
188
188
|
const program = (canonical.executable ?? '').split(/[\\/]/).at(-1)?.toLowerCase();
|
|
@@ -198,7 +198,7 @@ function loopbackCurlClaims(command: string | readonly string[], repoId: string)
|
|
|
198
198
|
return !['127.0.0.1', 'localhost', '::1'].includes(host);
|
|
199
199
|
} catch { return true; }
|
|
200
200
|
})) return undefined;
|
|
201
|
-
return [
|
|
201
|
+
return [claimHostService('tcp-client:loopback', 'read')];
|
|
202
202
|
}
|
|
203
203
|
|
|
204
204
|
function simpleViteScript(script: string): boolean {
|
|
@@ -236,7 +236,7 @@ function viteServiceClaims(
|
|
|
236
236
|
if (!vite) return undefined;
|
|
237
237
|
return normalizeClaims([
|
|
238
238
|
claimBuildCacheWrite(repoId),
|
|
239
|
-
claimHostService(`vite:${checkoutScope(checkoutId)}`, 'write'),
|
|
239
|
+
claimHostService(`vite:${checkoutScope(checkoutId, repoId)}`, 'write'),
|
|
240
240
|
]);
|
|
241
241
|
}
|
|
242
242
|
|
|
@@ -331,13 +331,10 @@ function hostOnlyCommandClaims(command: string | readonly string[], repoId: stri
|
|
|
331
331
|
return undefined;
|
|
332
332
|
}
|
|
333
333
|
|
|
334
|
-
function claimTemp(checkId: string, repoId: string, scope: 'isolated' | 'shared'): ResourceClaimSpec {
|
|
334
|
+
function claimTemp(checkId: string, repoId: string, scope: 'isolated' | 'shared', checkoutId?: string): ResourceClaimSpec {
|
|
335
335
|
const identity = checkId.replace(/[^a-zA-Z0-9._-]+/g, '-');
|
|
336
|
-
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
function claimNetwork(repoId: string, mode: 'read' | 'write'): ResourceClaimSpec {
|
|
340
|
-
return { resourceKey: `network:${repoId}`, mode };
|
|
336
|
+
const placement = checkoutScope(checkoutId, repoId);
|
|
337
|
+
return { resourceKey: scope === 'shared' ? `temp:${placement}:shared` : `temp:${placement}:${identity}`, mode: 'write' };
|
|
341
338
|
}
|
|
342
339
|
|
|
343
340
|
function staticAnalysisCheckId(checkId: string): boolean {
|
|
@@ -356,22 +353,23 @@ function claimsForDeclaredCheckEffects(
|
|
|
356
353
|
): ResourceClaimSpec[] {
|
|
357
354
|
const claims: ResourceClaimSpec[] = [];
|
|
358
355
|
const hasDeclaredField = Object.keys(effects).length > 0;
|
|
359
|
-
if (!hasDeclaredField) return [claimWorkspaceWrite(checkoutId)];
|
|
356
|
+
if (!hasDeclaredField) return [claimWorkspaceWrite(checkoutId, repoId)];
|
|
360
357
|
|
|
361
358
|
// Missing read scope is unknown, so custom checks fail closed. An explicit
|
|
362
359
|
// reads: [] means the command does not inspect repository content.
|
|
363
|
-
if (effects.reads === undefined) claims.push(claimWorkspaceWrite(checkoutId));
|
|
364
|
-
else for (const path of effects.reads) claims.push(claimPathRead(path, checkoutId));
|
|
365
|
-
for (const path of effects.writes ?? []) claims.push(claimPathWrite(path, checkoutId));
|
|
360
|
+
if (effects.reads === undefined) claims.push(claimWorkspaceWrite(checkoutId, repoId));
|
|
361
|
+
else for (const path of effects.reads) claims.push(claimPathRead(path, checkoutId, repoId));
|
|
362
|
+
for (const path of effects.writes ?? []) claims.push(claimPathWrite(path, checkoutId, repoId));
|
|
366
363
|
|
|
367
364
|
if (effects.cache === 'read') claims.push(claimBuildCacheRead(repoId));
|
|
368
365
|
if (effects.cache === 'write') claims.push(claimBuildCacheWrite(repoId));
|
|
369
|
-
if (effects.temp) claims.push(claimTemp(checkId, repoId, effects.temp));
|
|
370
|
-
if (effects.git === 'read') claims.push(claimGitIndexRead(checkoutId), claimGitRefsRead(repoId));
|
|
371
|
-
if (effects.git === 'index') claims.push(claimGitIndex(checkoutId));
|
|
366
|
+
if (effects.temp) claims.push(claimTemp(checkId, repoId, effects.temp, checkoutId));
|
|
367
|
+
if (effects.git === 'read') claims.push(claimGitIndexRead(checkoutId, repoId), claimGitRefsRead(repoId));
|
|
368
|
+
if (effects.git === 'index') claims.push(claimGitIndex(checkoutId, repoId));
|
|
372
369
|
if (effects.git === 'refs') claims.push(claimGitRefs(repoId));
|
|
373
|
-
if (effects.git === 'write') claims.push(claimWorkspaceWrite(checkoutId), claimGitIndex(checkoutId), claimGitRefs(repoId));
|
|
374
|
-
|
|
370
|
+
if (effects.git === 'write') claims.push(claimWorkspaceWrite(checkoutId, repoId), claimGitIndex(checkoutId, repoId), claimGitRefs(repoId));
|
|
371
|
+
// A generic network bit has no concrete endpoint/provider identity. Checks
|
|
372
|
+
// that need serialization must name the real shared target in hostServices.
|
|
375
373
|
for (const service of effects.hostServices ?? []) claims.push(claimHostService(service, 'write'));
|
|
376
374
|
|
|
377
375
|
return normalizeClaims(claims, { readOnly: claims.every((claim) => claim.mode === 'read') });
|
|
@@ -495,15 +493,18 @@ export function claimsForRepositoryCommand(
|
|
|
495
493
|
if (hostClaims) return hostClaims;
|
|
496
494
|
|
|
497
495
|
if (classification.risk === 'readonly') {
|
|
498
|
-
return [claimWorkspaceRead(checkoutId)];
|
|
496
|
+
return [claimWorkspaceRead(checkoutId, repoId)];
|
|
499
497
|
}
|
|
500
498
|
if (classification.risk === 'remote_write') {
|
|
501
|
-
|
|
499
|
+
// Raw command text cannot prove the external provider/account target. Keep
|
|
500
|
+
// the concrete local Git-ref fence; typed domain APIs own remote-effect
|
|
501
|
+
// identity, idempotency and provider-target serialization.
|
|
502
|
+
return [claimGitRefs(repoId)];
|
|
502
503
|
}
|
|
503
504
|
if (classification.risk === 'destructive') {
|
|
504
505
|
return [
|
|
505
|
-
claimWorkspaceWrite(checkoutId),
|
|
506
|
-
claimGitIndex(checkoutId),
|
|
506
|
+
claimWorkspaceWrite(checkoutId, repoId),
|
|
507
|
+
claimGitIndex(checkoutId, repoId),
|
|
507
508
|
claimGitRefs(repoId),
|
|
508
509
|
];
|
|
509
510
|
}
|
|
@@ -512,22 +513,22 @@ export function claimsForRepositoryCommand(
|
|
|
512
513
|
// while ordinary focused tests are observation unless snapshot-update mode is
|
|
513
514
|
// explicit. Both can share repository source reads without a workspace writer.
|
|
514
515
|
if (isTypedTypeScriptNoEmit(command)) {
|
|
515
|
-
return [claimWorkspaceRead(checkoutId), claimBuildCacheWrite(repoId)];
|
|
516
|
+
return [claimWorkspaceRead(checkoutId, repoId), claimBuildCacheWrite(repoId)];
|
|
516
517
|
}
|
|
517
518
|
if (focused) {
|
|
518
|
-
if (!focusedTestRequestsWorkspaceMutation(command)) return [claimWorkspaceRead(checkoutId)];
|
|
519
|
-
const claims: ResourceClaimSpec[] = [claimWorkspaceRead(checkoutId)];
|
|
520
|
-
for (const path of extractLikelyPaths(command).slice(0, 16)) claims.push(claimPathWrite(path, checkoutId));
|
|
519
|
+
if (!focusedTestRequestsWorkspaceMutation(command)) return [claimWorkspaceRead(checkoutId, repoId)];
|
|
520
|
+
const claims: ResourceClaimSpec[] = [claimWorkspaceRead(checkoutId, repoId)];
|
|
521
|
+
for (const path of extractLikelyPaths(command).slice(0, 16)) claims.push(claimPathWrite(path, checkoutId, repoId));
|
|
521
522
|
return normalizeClaims(claims);
|
|
522
523
|
}
|
|
523
524
|
if (looksLikeBuildOrTest(command)) {
|
|
524
525
|
const paths = extractLikelyPaths(command);
|
|
525
526
|
if (paths.length === 0) {
|
|
526
527
|
// Broad or opaque build/test commands may create arbitrary artifacts.
|
|
527
|
-
return [claimWorkspaceWrite(checkoutId), claimBuildCacheWrite(repoId)];
|
|
528
|
+
return [claimWorkspaceWrite(checkoutId, repoId), claimBuildCacheWrite(repoId)];
|
|
528
529
|
}
|
|
529
|
-
const claims: ResourceClaimSpec[] = [claimWorkspaceRead(checkoutId), claimBuildCacheWrite(repoId)];
|
|
530
|
-
for (const path of paths.slice(0, 16)) claims.push(claimPathWrite(path, checkoutId));
|
|
530
|
+
const claims: ResourceClaimSpec[] = [claimWorkspaceRead(checkoutId, repoId), claimBuildCacheWrite(repoId)];
|
|
531
|
+
for (const path of paths.slice(0, 16)) claims.push(claimPathWrite(path, checkoutId, repoId));
|
|
531
532
|
return normalizeClaims(claims);
|
|
532
533
|
}
|
|
533
534
|
|
|
@@ -537,23 +538,26 @@ export function claimsForRepositoryCommand(
|
|
|
537
538
|
const sub = canonical.kind === 'argv' ? canonical.args?.[0]?.toLowerCase() : undefined;
|
|
538
539
|
if (program === 'git') {
|
|
539
540
|
if (sub === 'add' || sub === 'rm' || sub === 'mv' || sub === 'restore' || sub === 'apply') {
|
|
540
|
-
return [claimGitIndex(checkoutId), claimWorkspaceWrite(checkoutId)];
|
|
541
|
+
return [claimGitIndex(checkoutId, repoId), claimWorkspaceWrite(checkoutId, repoId)];
|
|
541
542
|
}
|
|
542
543
|
if (sub === 'commit' || sub === 'merge' || sub === 'rebase' || sub === 'cherry-pick' || sub === 'revert') {
|
|
543
|
-
return [claimGitIndex(checkoutId), claimGitRefs(repoId), claimWorkspaceWrite(checkoutId)];
|
|
544
|
+
return [claimGitIndex(checkoutId, repoId), claimGitRefs(repoId), claimWorkspaceWrite(checkoutId, repoId)];
|
|
544
545
|
}
|
|
545
546
|
if (sub === 'checkout' || sub === 'switch' || sub === 'branch' || sub === 'tag') {
|
|
546
|
-
return [claimGitRefs(repoId), claimWorkspaceWrite(checkoutId)];
|
|
547
|
+
return [claimGitRefs(repoId), claimWorkspaceWrite(checkoutId, repoId)];
|
|
547
548
|
}
|
|
548
549
|
}
|
|
549
550
|
|
|
550
551
|
// Unknown mutating command — workspace write, not heavy-check exclusive.
|
|
551
|
-
return [claimWorkspaceWrite(checkoutId)];
|
|
552
|
+
return [claimWorkspaceWrite(checkoutId, repoId)];
|
|
552
553
|
}
|
|
553
554
|
|
|
554
555
|
/**
|
|
555
556
|
* Claims for run_check by check id / command.
|
|
556
|
-
*
|
|
557
|
+
* Full CI/release/multi-phase checks and compiler-intensive latency gates take
|
|
558
|
+
* heavy-check exclusive. The latter fence protects performance assertions from
|
|
559
|
+
* same-repository CPU/JSC contention; it does not replace their real read/cache
|
|
560
|
+
* claims.
|
|
557
561
|
*/
|
|
558
562
|
export function claimsForCheck(
|
|
559
563
|
checkId: string,
|
|
@@ -563,15 +567,15 @@ export function claimsForCheck(
|
|
|
563
567
|
effects?: ControllerCheckEffects,
|
|
564
568
|
executionAuthority?: ControllerCheckExecutionAuthority,
|
|
565
569
|
): ResourceClaimSpec[] {
|
|
566
|
-
const heavy = /(?:^|:)(?:test(?::coverage)?|check:(?:ci|forge-runtime|public-export|release(?:-[a-z0-9-]+)
|
|
570
|
+
const heavy = /(?:^|:)(?:test(?::coverage)?|check:(?:ci|forge-runtime|public-export|release(?:-[a-z0-9-]+)?|type|typescript-navigation))$/.test(checkId)
|
|
567
571
|
|| /release|migration|integrate/i.test(checkId);
|
|
568
572
|
const baseClaims = effects
|
|
569
573
|
? claimsForDeclaredCheckEffects(checkId, effects, repoId, checkoutId)
|
|
570
574
|
: staticAnalysisCheckId(checkId)
|
|
571
|
-
? [claimWorkspaceRead(checkoutId), claimBuildCacheWrite(repoId)]
|
|
575
|
+
? [claimWorkspaceRead(checkoutId, repoId), claimBuildCacheWrite(repoId)]
|
|
572
576
|
: command && command.length > 0
|
|
573
577
|
? claimsForRepositoryCommand(command, repoId, checkoutId)
|
|
574
|
-
: [claimWorkspaceWrite(checkoutId)];
|
|
578
|
+
: [claimWorkspaceWrite(checkoutId, repoId)];
|
|
575
579
|
// Heavy-check is an additional cross-check serialization fence, not a
|
|
576
580
|
// substitute for the resources the check actually reads or writes.
|
|
577
581
|
const liveAuthorityClaims = executionAuthority === 'live_controller_home' ? [claimRelease(repoId)] : [];
|
|
@@ -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,
|
|
@@ -1627,6 +1641,18 @@ function applyReceiptIfPresent(
|
|
|
1627
1641
|
}, { authority: 'durable_exit_receipt' });
|
|
1628
1642
|
}
|
|
1629
1643
|
|
|
1644
|
+
|
|
1645
|
+
function reconcileObservedTerminalProcess(
|
|
1646
|
+
controllerHome: string,
|
|
1647
|
+
repoId: string,
|
|
1648
|
+
record: ManagedProcessRecord,
|
|
1649
|
+
): ManagedProcessRecord {
|
|
1650
|
+
if (record.terminalWritten !== true) return record;
|
|
1651
|
+
const reconciled = releaseProcessLeasesOnce(controllerHome, repoId, record.processId) ?? record;
|
|
1652
|
+
cleanupTerminalRunnerReceipts(reconciled);
|
|
1653
|
+
return reconciled;
|
|
1654
|
+
}
|
|
1655
|
+
|
|
1630
1656
|
export function getProcessHandle(
|
|
1631
1657
|
controllerHome: string,
|
|
1632
1658
|
repoId: string,
|
|
@@ -1634,6 +1660,9 @@ export function getProcessHandle(
|
|
|
1634
1660
|
): ProcessHandle | undefined {
|
|
1635
1661
|
const record = getProcessRecord(controllerHome, repoId, processId);
|
|
1636
1662
|
if (!record) return undefined;
|
|
1663
|
+
if (record.terminalWritten === true) {
|
|
1664
|
+
return recordToHandle(reconcileObservedTerminalProcess(controllerHome, repoId, record), { completed: true });
|
|
1665
|
+
}
|
|
1637
1666
|
if (isManagedProcessActive(record) && !liveMonitors.has(processId)) {
|
|
1638
1667
|
const fromReceipt = applyReceiptIfPresent(controllerHome, repoId, processId, record);
|
|
1639
1668
|
if (fromReceipt) return recordToHandle(fromReceipt, { completed: true });
|
|
@@ -1656,7 +1685,9 @@ export async function waitForProcess(
|
|
|
1656
1685
|
): Promise<ProcessHandle> {
|
|
1657
1686
|
const existing = getProcessRecord(controllerHome, repoId, processId);
|
|
1658
1687
|
if (!existing) throw new Error(`PROCESS_NOT_FOUND: ${processId}`);
|
|
1659
|
-
if (existing.terminalWritten)
|
|
1688
|
+
if (existing.terminalWritten) {
|
|
1689
|
+
return recordToHandle(reconcileObservedTerminalProcess(controllerHome, repoId, existing), { completed: true });
|
|
1690
|
+
}
|
|
1660
1691
|
|
|
1661
1692
|
const monitor = liveMonitors.get(processId);
|
|
1662
1693
|
if (monitor) {
|
|
@@ -1744,7 +1775,9 @@ export async function cancelProcess(
|
|
|
1744
1775
|
): Promise<ProcessHandle> {
|
|
1745
1776
|
const record = getProcessRecord(controllerHome, repoId, processId);
|
|
1746
1777
|
if (!record) throw new Error(`PROCESS_NOT_FOUND: ${processId}`);
|
|
1747
|
-
if (record.terminalWritten)
|
|
1778
|
+
if (record.terminalWritten) {
|
|
1779
|
+
return recordToHandle(reconcileObservedTerminalProcess(controllerHome, repoId, record), { completed: true });
|
|
1780
|
+
}
|
|
1748
1781
|
|
|
1749
1782
|
// Process control is itself a writer mutation. Fence BEFORE sending any
|
|
1750
1783
|
// signal so a passive/stale runtime cannot kill the active runtime's work.
|