@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
|
@@ -7,22 +7,13 @@ export type TaskExecutionClass =
|
|
|
7
7
|
| 'high_risk_change'
|
|
8
8
|
| 'destructive_change';
|
|
9
9
|
|
|
10
|
-
export type ApprovalRequirement = 'auto' | '
|
|
10
|
+
export type ApprovalRequirement = 'auto' | 'manual-only';
|
|
11
11
|
|
|
12
12
|
export interface TaskExecutionPolicy {
|
|
13
13
|
risk: TaskRisk;
|
|
14
14
|
executionClass: TaskExecutionClass;
|
|
15
15
|
approval: ApprovalRequirement;
|
|
16
|
-
requiresScopedPaths: boolean;
|
|
17
|
-
requiresDiffEvidence: boolean;
|
|
18
|
-
requiresAnyVerificationEvidence: boolean;
|
|
19
|
-
requiresAcceptanceEvidence: boolean;
|
|
20
|
-
requiresHumanAcceptance: boolean;
|
|
21
|
-
autoRunDeclaredChecks: boolean;
|
|
22
|
-
autoCompleteAfterSuccessfulRun: boolean;
|
|
23
16
|
warnings: string[];
|
|
24
|
-
sensitivePaths: string[];
|
|
25
|
-
destructiveSignals: string[];
|
|
26
17
|
}
|
|
27
18
|
|
|
28
19
|
export interface CompletionReceiptExpectation {
|
|
@@ -140,139 +131,39 @@ export function completionEvidenceComplete(
|
|
|
140
131
|
&& cleanup.noDirtyDiff);
|
|
141
132
|
}
|
|
142
133
|
|
|
143
|
-
const READ_ONLY_INTENT = /\b(read|inspect|analy[sz]e|audit|review|summari[sz]e|explain|diagnose|investigate|search|find|report|compare|trace)\b|只读|分析|审计|检查|排查|调查|搜索|查找|报告|对比|梳理/i;
|
|
144
|
-
const CHANGE_INTENT = /\b(edit|change|modify|implement|fix|refactor|write|create|update|migrate|replace|delete|remove)\b|修改|实现|修复|重构|写入|创建|更新|迁移|替换|删除/i;
|
|
145
|
-
const DESTRUCTIVE_INTENT = /\b(rm\s+-rf|reset\s+--hard|force[- ]?push|rewrite\s+history|drop\s+(table|database)|truncate\s+table|delete\s+all|purge|destroy|irreversible|production\s+data|prod\s+data)\b|强制推送|重写历史|清空数据库|删除全部|不可逆|生产数据/i;
|
|
146
|
-
const SENSITIVE_PATH_PATTERNS: Array<[RegExp, string]> = [
|
|
147
|
-
[/(^|\/)\.github\/workflows(\/|$)/i, 'CI workflow'],
|
|
148
|
-
[/(^|\/)(deploy|infra|terraform|k8s|helm)(\/|$)/i, 'deployment or infrastructure'],
|
|
149
|
-
[/(^|\/)(migrations?|schema|database|db)(\/|$)/i, 'database or migration'],
|
|
150
|
-
[/(^|\/)(auth|security|permissions?|billing|payments?)(\/|$)/i, 'security or billing'],
|
|
151
|
-
[/(^|\/)(package-lock\.json|pnpm-lock\.yaml|yarn\.lock|bun\.lock)$/i, 'dependency lockfile'],
|
|
152
|
-
];
|
|
153
|
-
|
|
154
134
|
function normalizeRisk(value: TaskRisk | undefined): TaskRisk {
|
|
155
135
|
return value ?? 'medium';
|
|
156
136
|
}
|
|
157
137
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
return [...labels];
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
export function classifyTaskExecution(task: Pick<ControllerTask, 'objective' | 'title' | 'risk' | 'allowedPaths' | 'forbiddenPaths'>): {
|
|
138
|
+
/**
|
|
139
|
+
* Legacy Task risk is explicit model-authored metadata only. Forge does not infer
|
|
140
|
+
* risk or destructive authority from objective text, path names, or keywords.
|
|
141
|
+
*/
|
|
142
|
+
export function classifyTaskExecution(task: Pick<ControllerTask, 'risk'>): {
|
|
169
143
|
risk: TaskRisk;
|
|
170
144
|
executionClass: TaskExecutionClass;
|
|
171
|
-
sensitivePaths: string[];
|
|
172
|
-
destructiveSignals: string[];
|
|
173
145
|
} {
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
if (
|
|
179
|
-
|
|
180
|
-
destructiveSignals.push('high-risk data mutation');
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
let risk = normalizeRisk(task.risk);
|
|
184
|
-
if (destructiveSignals.length > 0) risk = 'destructive';
|
|
185
|
-
else if (risk !== 'destructive' && sensitivePaths.length > 0 && (risk === 'readonly' || risk === 'low')) risk = 'medium';
|
|
186
|
-
|
|
187
|
-
if (risk === 'readonly') return { risk, executionClass: 'read_only', sensitivePaths, destructiveSignals };
|
|
188
|
-
if (risk === 'destructive') return { risk, executionClass: 'destructive_change', sensitivePaths, destructiveSignals };
|
|
189
|
-
if (risk === 'high') return { risk, executionClass: 'high_risk_change', sensitivePaths, destructiveSignals };
|
|
190
|
-
if (risk === 'medium') return { risk, executionClass: 'medium_risk_change', sensitivePaths, destructiveSignals };
|
|
191
|
-
|
|
192
|
-
const inferredReadOnly = READ_ONLY_INTENT.test(text) && !CHANGE_INTENT.test(text) && task.allowedPaths.length === 0;
|
|
193
|
-
return {
|
|
194
|
-
risk: inferredReadOnly ? 'readonly' : risk,
|
|
195
|
-
executionClass: inferredReadOnly ? 'read_only' : 'low_risk_change',
|
|
196
|
-
sensitivePaths,
|
|
197
|
-
destructiveSignals,
|
|
198
|
-
};
|
|
146
|
+
const risk = normalizeRisk(task.risk);
|
|
147
|
+
if (risk === 'readonly') return { risk, executionClass: 'read_only' };
|
|
148
|
+
if (risk === 'destructive') return { risk, executionClass: 'destructive_change' };
|
|
149
|
+
if (risk === 'high') return { risk, executionClass: 'high_risk_change' };
|
|
150
|
+
if (risk === 'medium') return { risk, executionClass: 'medium_risk_change' };
|
|
151
|
+
return { risk, executionClass: 'low_risk_change' };
|
|
199
152
|
}
|
|
200
153
|
|
|
201
|
-
export function taskExecutionPolicy(task: Pick<ControllerTask, '
|
|
154
|
+
export function taskExecutionPolicy(task: Pick<ControllerTask, 'risk' | 'allowedPaths' | 'checks' | 'acceptanceCriteria'>): TaskExecutionPolicy {
|
|
202
155
|
const classification = classifyTaskExecution(task);
|
|
203
156
|
const warnings: string[] = [];
|
|
204
|
-
if (task.checks.length === 0) warnings.push('No named checks are declared;
|
|
157
|
+
if (task.checks.length === 0) warnings.push('No named checks are declared; completion relies on concrete execution or delivery evidence when present.');
|
|
205
158
|
if (task.acceptanceCriteria.length === 0) warnings.push('No Task-level acceptance criteria are declared.');
|
|
206
|
-
if (task.allowedPaths.length === 0 && classification.executionClass !== 'read_only') warnings.push('No allowed path scope is declared; runtime path and conflict guards remain authoritative.');
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
requiresDiffEvidence: false,
|
|
215
|
-
requiresAnyVerificationEvidence: false,
|
|
216
|
-
requiresAcceptanceEvidence: false,
|
|
217
|
-
requiresHumanAcceptance: false,
|
|
218
|
-
autoRunDeclaredChecks: false,
|
|
219
|
-
autoCompleteAfterSuccessfulRun: true,
|
|
220
|
-
warnings,
|
|
221
|
-
};
|
|
222
|
-
case 'low_risk_change':
|
|
223
|
-
return {
|
|
224
|
-
...classification,
|
|
225
|
-
approval: 'auto',
|
|
226
|
-
requiresScopedPaths: false,
|
|
227
|
-
requiresDiffEvidence: false,
|
|
228
|
-
requiresAnyVerificationEvidence: false,
|
|
229
|
-
requiresAcceptanceEvidence: false,
|
|
230
|
-
requiresHumanAcceptance: false,
|
|
231
|
-
autoRunDeclaredChecks: task.checks.length > 0,
|
|
232
|
-
autoCompleteAfterSuccessfulRun: true,
|
|
233
|
-
warnings,
|
|
234
|
-
};
|
|
235
|
-
case 'medium_risk_change':
|
|
236
|
-
return {
|
|
237
|
-
...classification,
|
|
238
|
-
approval: 'auto',
|
|
239
|
-
requiresScopedPaths: false,
|
|
240
|
-
requiresDiffEvidence: false,
|
|
241
|
-
requiresAnyVerificationEvidence: task.checks.length > 0,
|
|
242
|
-
requiresAcceptanceEvidence: task.acceptanceCriteria.length > 0,
|
|
243
|
-
requiresHumanAcceptance: false,
|
|
244
|
-
autoRunDeclaredChecks: task.checks.length > 0,
|
|
245
|
-
autoCompleteAfterSuccessfulRun: true,
|
|
246
|
-
warnings,
|
|
247
|
-
};
|
|
248
|
-
case 'high_risk_change':
|
|
249
|
-
return {
|
|
250
|
-
...classification,
|
|
251
|
-
// V8 treats risk as execution metadata, not as a local approval gate.
|
|
252
|
-
approval: 'auto',
|
|
253
|
-
requiresScopedPaths: false,
|
|
254
|
-
requiresDiffEvidence: true,
|
|
255
|
-
requiresAnyVerificationEvidence: task.checks.length > 0,
|
|
256
|
-
requiresAcceptanceEvidence: task.acceptanceCriteria.length > 0,
|
|
257
|
-
requiresHumanAcceptance: true,
|
|
258
|
-
autoRunDeclaredChecks: task.checks.length > 0,
|
|
259
|
-
autoCompleteAfterSuccessfulRun: false,
|
|
260
|
-
warnings,
|
|
261
|
-
};
|
|
262
|
-
case 'destructive_change':
|
|
263
|
-
return {
|
|
264
|
-
...classification,
|
|
265
|
-
approval: 'manual-only',
|
|
266
|
-
requiresScopedPaths: true,
|
|
267
|
-
requiresDiffEvidence: true,
|
|
268
|
-
requiresAnyVerificationEvidence: true,
|
|
269
|
-
requiresAcceptanceEvidence: true,
|
|
270
|
-
requiresHumanAcceptance: true,
|
|
271
|
-
autoRunDeclaredChecks: task.checks.length > 0,
|
|
272
|
-
autoCompleteAfterSuccessfulRun: false,
|
|
273
|
-
warnings,
|
|
274
|
-
};
|
|
275
|
-
}
|
|
159
|
+
if (task.allowedPaths.length === 0 && classification.executionClass !== 'read_only') warnings.push('No allowed path scope is declared; concrete runtime path and conflict guards remain authoritative.');
|
|
160
|
+
return {
|
|
161
|
+
...classification,
|
|
162
|
+
// Only an explicitly authored destructive risk retains a legacy Task-level
|
|
163
|
+
// authorization boundary. Ordinary risk classes are descriptive metadata.
|
|
164
|
+
approval: classification.risk === 'destructive' ? 'manual-only' : 'auto',
|
|
165
|
+
warnings,
|
|
166
|
+
};
|
|
276
167
|
}
|
|
277
168
|
|
|
278
169
|
|
|
@@ -336,7 +227,7 @@ export function taskAcceptanceOutcome(result: TaskAcceptanceResult | undefined):
|
|
|
336
227
|
return result.ok ? 'passed' : 'failed';
|
|
337
228
|
}
|
|
338
229
|
|
|
339
|
-
export function verificationEvidencePassed(task: Pick<ControllerTask, 'checks' | 'acceptanceCriteria'>, verification: TaskVerification | undefined
|
|
230
|
+
export function verificationEvidencePassed(task: Pick<ControllerTask, 'checks' | 'acceptanceCriteria'>, verification: TaskVerification | undefined): {
|
|
340
231
|
status: 'passed' | 'failed' | 'incomplete';
|
|
341
232
|
ok: boolean;
|
|
342
233
|
checksOk: boolean;
|
|
@@ -344,49 +235,41 @@ export function verificationEvidencePassed(task: Pick<ControllerTask, 'checks' |
|
|
|
344
235
|
hasEvidence: boolean;
|
|
345
236
|
reasons: string[];
|
|
346
237
|
} {
|
|
238
|
+
const checksRequired = task.checks.length > 0;
|
|
239
|
+
const acceptanceRequired = task.acceptanceCriteria.length > 0;
|
|
347
240
|
if (!verification) {
|
|
348
|
-
const ok = !
|
|
241
|
+
const ok = !checksRequired && !acceptanceRequired;
|
|
349
242
|
return {
|
|
350
243
|
status: ok ? 'passed' : 'incomplete',
|
|
351
244
|
ok,
|
|
352
|
-
checksOk: !
|
|
353
|
-
acceptanceOk: !
|
|
245
|
+
checksOk: !checksRequired,
|
|
246
|
+
acceptanceOk: !acceptanceRequired,
|
|
354
247
|
hasEvidence: false,
|
|
355
|
-
reasons: ok ? [] : ['
|
|
248
|
+
reasons: ok ? [] : ['Explicitly declared check or acceptance evidence is missing.'],
|
|
356
249
|
};
|
|
357
250
|
}
|
|
358
251
|
const reportedCommands = verification.commandEvidence ?? [];
|
|
359
252
|
const hasEvidence = verification.checkResults.length > 0 || reportedCommands.length > 0 || Boolean(verification.runId);
|
|
360
253
|
const evidenceFailed = verification.checkResults.some((entry) => !entry.ok)
|
|
361
254
|
|| reportedCommands.some((entry) => !entry.ok);
|
|
362
|
-
const namedChecksComplete =
|
|
255
|
+
const namedChecksComplete = !checksRequired || task.checks.every((checkId) =>
|
|
363
256
|
verification.checkResults.some((entry) => entry.checkId === checkId && entry.ok),
|
|
364
257
|
);
|
|
365
|
-
const
|
|
366
|
-
const checksOk = !evidenceFailed && (declaredChecksRequired
|
|
367
|
-
? namedChecksComplete
|
|
368
|
-
: policy.requiresAnyVerificationEvidence
|
|
369
|
-
? hasEvidence
|
|
370
|
-
: true);
|
|
258
|
+
const checksOk = !evidenceFailed && namedChecksComplete;
|
|
371
259
|
|
|
372
260
|
const acceptanceOutcomes = task.acceptanceCriteria.map((criterion) => taskAcceptanceOutcome(
|
|
373
261
|
verification.acceptanceResults.find((entry) => entry.criterion === criterion),
|
|
374
262
|
));
|
|
375
|
-
const acceptanceFailed =
|
|
376
|
-
const acceptanceComplete = !
|
|
377
|
-
|| task.acceptanceCriteria.length === 0
|
|
378
|
-
|| acceptanceOutcomes.every((outcome) => outcome === 'passed');
|
|
263
|
+
const acceptanceFailed = acceptanceOutcomes.some((outcome) => outcome === 'failed');
|
|
264
|
+
const acceptanceComplete = !acceptanceRequired || acceptanceOutcomes.every((outcome) => outcome === 'passed');
|
|
379
265
|
const acceptanceOk = acceptanceComplete && !acceptanceFailed;
|
|
380
|
-
const diffOk = !policy.requiresDiffEvidence || Boolean(verification.reviewedDiffHash || verification.integratedRevision);
|
|
381
266
|
const failed = evidenceFailed || acceptanceFailed;
|
|
382
|
-
const complete = checksOk && acceptanceOk
|
|
267
|
+
const complete = checksOk && acceptanceOk;
|
|
383
268
|
const status = failed ? 'failed' : complete ? 'passed' : 'incomplete';
|
|
384
269
|
const reasons: string[] = [];
|
|
385
270
|
if (evidenceFailed) reasons.push('One or more executed checks or reported commands failed.');
|
|
386
|
-
else if (!checksOk) reasons.push('
|
|
271
|
+
else if (!checksOk) reasons.push('One or more explicitly declared checks are missing.');
|
|
387
272
|
if (acceptanceFailed) reasons.push('One or more acceptance criteria explicitly failed.');
|
|
388
|
-
else if (!acceptanceOk) reasons.push('One or more acceptance criteria are missing or not evaluated.');
|
|
389
|
-
if (policy.requiresAnyVerificationEvidence && !hasEvidence) reasons.push('This risk class requires persisted verification evidence.');
|
|
390
|
-
if (!diffOk) reasons.push('This risk class requires reviewed Diff or integrated revision evidence.');
|
|
273
|
+
else if (!acceptanceOk) reasons.push('One or more explicitly declared acceptance criteria are missing or not evaluated.');
|
|
391
274
|
return { status, ok: status === 'passed', checksOk, acceptanceOk, hasEvidence, reasons };
|
|
392
275
|
}
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
} from "./issue-store";
|
|
12
12
|
import { clearCurrentIssue, loadControllerProjectState, saveControllerProjectState } from "./project-state";
|
|
13
13
|
import type { ControllerIssue, ControllerTask } from "./types";
|
|
14
|
-
import { completionEvidenceComplete
|
|
14
|
+
import { completionEvidenceComplete } from "./execution-policy";
|
|
15
15
|
import { resolveCompletionTargetBranch } from "./completion-target";
|
|
16
16
|
import { readIssueRunEvidence } from "./run-evidence";
|
|
17
17
|
import { resolveEffectiveTaskState, resolveIssueTaskStates, resolveTaskDependencies, type EffectiveTaskState } from "./task-status-resolver";
|
|
@@ -200,8 +200,7 @@ function shouldAutoAcceptVerifiedTask(repoRoot: string, issue: ControllerIssue,
|
|
|
200
200
|
taskId: task.id,
|
|
201
201
|
targetBranch: resolveCompletionTargetBranch(repoRoot),
|
|
202
202
|
})) return false;
|
|
203
|
-
|
|
204
|
-
return policy.autoCompleteAfterSuccessfulRun && !policy.requiresHumanAcceptance;
|
|
203
|
+
return task.acceptanceCriteria.length === 0;
|
|
205
204
|
}
|
|
206
205
|
|
|
207
206
|
function taskQueueItem(issue: ControllerIssue, task: ControllerTask, state: EffectiveTaskState): ExecutionQueueItem | undefined {
|
|
@@ -30,9 +30,6 @@ import { completionEvidenceComplete, executionScopesConflict, taskExecutionPolic
|
|
|
30
30
|
import { resolveCompletionTargetBranch } from './completion-target';
|
|
31
31
|
import { listControllerChecks } from './check-runner';
|
|
32
32
|
import { normalizeCheckIds } from '../../runtime/control-plane/facade/check-normalization';
|
|
33
|
-
import { getWorkContract } from '../../../packages/kernel/work/api/index';
|
|
34
|
-
import { projectControllerTaskFromWork } from '../../runtime/control-plane/facade/work-task-projection';
|
|
35
|
-
import type { WorkContract } from '../../runtime/control-plane/facade/types';
|
|
36
33
|
import { resolveRepoPreferredControllerHome } from '../repositories/controller-home';
|
|
37
34
|
import { markControllerContextProjectionDirty } from '../../runtime/projections/controller-context';
|
|
38
35
|
import {
|
|
@@ -239,32 +236,8 @@ export function getIssue(repoRoot: string, id: string): ControllerIssue {
|
|
|
239
236
|
return issue;
|
|
240
237
|
}
|
|
241
238
|
|
|
242
|
-
function projectIssueTasksFromWork(repoRoot: string, issue: ControllerIssue): ControllerTask[] {
|
|
243
|
-
const controllerHomes = [...new Set([
|
|
244
|
-
resolveRepoPreferredControllerHome(repoRoot),
|
|
245
|
-
join(repoRoot, '_ops', 'controller-home'),
|
|
246
|
-
])];
|
|
247
|
-
return issue.tasks.map((task) => {
|
|
248
|
-
if (!task.workId) return task;
|
|
249
|
-
const repoId = task.repoId ?? issue.repoId;
|
|
250
|
-
if (!repoId) return task.status === 'done' ? task : { ...task, status: 'launch_blocked' };
|
|
251
|
-
for (const controllerHome of controllerHomes) {
|
|
252
|
-
try {
|
|
253
|
-
const work = getWorkContract({ controllerHome, repoId }, task.workId);
|
|
254
|
-
if (!work || (work.issueId && work.issueId !== issue.id) || (work.taskId && work.taskId !== task.id)) continue;
|
|
255
|
-
if (work.status === 'completed' && !work.completionReceipt) continue;
|
|
256
|
-
return projectControllerTaskFromWork(task, work);
|
|
257
|
-
} catch {
|
|
258
|
-
// A compatibility read never manufactures state from an unavailable
|
|
259
|
-
// Work authority. Try the bounded repo-local authority, then close.
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
return task.status === 'done' ? task : { ...task, status: 'launch_blocked' };
|
|
263
|
-
});
|
|
264
|
-
}
|
|
265
|
-
|
|
266
239
|
export function projectIssueEffectiveView(repoRoot: string, issue: ControllerIssue) {
|
|
267
|
-
const projectedIssue =
|
|
240
|
+
const projectedIssue = issue;
|
|
268
241
|
const states = resolveIssueTaskStates(projectedIssue, readIssueRunEvidence(repoRoot, projectedIssue));
|
|
269
242
|
return {
|
|
270
243
|
...projectedIssue,
|
|
@@ -509,12 +482,6 @@ function buildTaskReadiness(
|
|
|
509
482
|
add('SUPERSEDED_DEPENDENCY_MIGRATION', 'warning', `Dependency ${migration.dependencyTaskId} was superseded by ${migration.replacementTaskIds.join(', ')}; replacement states are authoritative.`);
|
|
510
483
|
}
|
|
511
484
|
|
|
512
|
-
if (policy.requiresScopedPaths && task.allowedPaths.length === 0) {
|
|
513
|
-
add('TASK_SCOPE_REQUIRED', 'blocker', `${policy.executionClass} requires an explicit allowed path scope.`);
|
|
514
|
-
}
|
|
515
|
-
if (policy.approval === 'confirm' && !options.approveRisk) {
|
|
516
|
-
add('RISK_CONFIRMATION_ADVISORY', 'warning', `${policy.executionClass} is marked for extra review, but local execution is not approval-gated in V8.`);
|
|
517
|
-
}
|
|
518
485
|
if (policy.approval === 'manual-only' && !options.approveDestructive) {
|
|
519
486
|
add('DESTRUCTIVE_APPROVAL_REQUIRED', 'blocker', 'A destructive or irreversible operation requires explicit authorization.');
|
|
520
487
|
}
|
|
@@ -585,7 +552,7 @@ function refreshReadiness(repoRoot: string, issue: ControllerIssue): void {
|
|
|
585
552
|
);
|
|
586
553
|
task.status = nonApprovalBlockers.length === 0
|
|
587
554
|
? 'ready'
|
|
588
|
-
: nonApprovalBlockers.some((entry) => ['CANCELLED_DEPENDENCY', 'MISSING_DEPENDENCY'
|
|
555
|
+
: nonApprovalBlockers.some((entry) => ['CANCELLED_DEPENDENCY', 'MISSING_DEPENDENCY'].includes(entry.code))
|
|
589
556
|
? 'launch_blocked'
|
|
590
557
|
: 'planned';
|
|
591
558
|
}
|
|
@@ -942,63 +909,6 @@ export function bindTaskToWork(
|
|
|
942
909
|
return written;
|
|
943
910
|
}
|
|
944
911
|
|
|
945
|
-
/**
|
|
946
|
-
* Pre-cutover compatibility writer retained only for an unmigrated repository.
|
|
947
|
-
* Once the SQLite migration marker exists this function fails before reading or
|
|
948
|
-
* mutating legacy Issue/Task files; Work remains the sole execution writer.
|
|
949
|
-
*/
|
|
950
|
-
export function projectTaskFromWork(
|
|
951
|
-
repoRoot: string,
|
|
952
|
-
issueIdValue: string,
|
|
953
|
-
taskId: string,
|
|
954
|
-
work: WorkContract,
|
|
955
|
-
input: { verification?: TaskVerification; note?: string } = {},
|
|
956
|
-
): ControllerIssue {
|
|
957
|
-
assertLegacyIssueWritesAllowed(repoRoot, { id: issueIdValue });
|
|
958
|
-
const issue = getIssue(repoRoot, issueIdValue);
|
|
959
|
-
const task = issue.tasks.find((entry) => entry.id === taskId);
|
|
960
|
-
if (!task) throw new Error(`task not found: ${issueIdValue}/${taskId}`);
|
|
961
|
-
if (!task.workId || task.workId !== work.workId) {
|
|
962
|
-
throw new Error(`TASK_WORK_PROJECTION_IDENTITY_MISMATCH: ${task.workId ?? 'unbound'} != ${work.workId}`);
|
|
963
|
-
}
|
|
964
|
-
if (task.repoId && task.repoId !== work.repoId) {
|
|
965
|
-
throw new Error(`TASK_WORK_PROJECTION_REPO_MISMATCH: ${task.repoId} != ${work.repoId}`);
|
|
966
|
-
}
|
|
967
|
-
if (work.issueId && work.issueId !== issue.id) throw new Error(`TASK_WORK_PROJECTION_ISSUE_MISMATCH: ${work.issueId} != ${issue.id}`);
|
|
968
|
-
if (work.taskId && work.taskId !== task.id) throw new Error(`TASK_WORK_PROJECTION_TASK_MISMATCH: ${work.taskId} != ${task.id}`);
|
|
969
|
-
if (input.verification?.completionReceipt && input.verification.completionReceipt.receiptId !== work.completionReceipt?.receiptId) {
|
|
970
|
-
throw new Error('TASK_WORK_PROJECTION_RECEIPT_MISMATCH');
|
|
971
|
-
}
|
|
972
|
-
const projected = projectControllerTaskFromWork(task, work);
|
|
973
|
-
if (projected.status === 'done' && !work.completionReceipt) {
|
|
974
|
-
throw new Error('TASK_WORK_PROJECTION_COMPLETION_RECEIPT_REQUIRED');
|
|
975
|
-
}
|
|
976
|
-
task.repoId = work.repoId;
|
|
977
|
-
task.objective = projected.objective;
|
|
978
|
-
task.status = projected.status;
|
|
979
|
-
task.allowedPaths = projected.allowedPaths;
|
|
980
|
-
task.forbiddenPaths = projected.forbiddenPaths;
|
|
981
|
-
task.checks = projected.checks;
|
|
982
|
-
task.acceptanceCriteria = projected.acceptanceCriteria;
|
|
983
|
-
task.risk = projected.risk;
|
|
984
|
-
task.verification = input.verification ?? projected.verification;
|
|
985
|
-
if (input.note?.trim()) task.notes.push(input.note.trim());
|
|
986
|
-
task.updatedAt = new Date().toISOString();
|
|
987
|
-
issue.updatedAt = task.updatedAt;
|
|
988
|
-
refreshReadiness(repoRoot, issue);
|
|
989
|
-
const written = writeIssue(repoRoot, issue);
|
|
990
|
-
tryAppendControllerWorklogEvent(repoRoot, {
|
|
991
|
-
category: 'task',
|
|
992
|
-
action: 'task_projected_from_work',
|
|
993
|
-
summary: `Projected ${task.id} from Work ${work.workId} (${work.phase}/${work.status}).`,
|
|
994
|
-
issueId: issue.id,
|
|
995
|
-
taskId: task.id,
|
|
996
|
-
statusTo: task.status,
|
|
997
|
-
details: { workId: work.workId, phase: work.phase, workStatus: work.status, receiptId: work.completionReceipt?.receiptId },
|
|
998
|
-
});
|
|
999
|
-
return written;
|
|
1000
|
-
}
|
|
1001
|
-
|
|
1002
912
|
function finding(code: string, level: 'blocker' | 'warning', message: string, taskId?: string): IssueReadinessFinding {
|
|
1003
913
|
return { code, level, message, taskId };
|
|
1004
914
|
}
|
|
@@ -1142,8 +1052,7 @@ function historicalTaskCompletionReceipt(
|
|
|
1142
1052
|
verification: TaskVerification | undefined = task.verification,
|
|
1143
1053
|
): CompletionReceipt | undefined {
|
|
1144
1054
|
if (!verification || taskHasActiveRun(repoRoot, task)) return undefined;
|
|
1145
|
-
const
|
|
1146
|
-
const outcome = verificationEvidencePassed(task, verification, policy);
|
|
1055
|
+
const outcome = verificationEvidencePassed(task, verification);
|
|
1147
1056
|
if (!outcome.ok) return undefined;
|
|
1148
1057
|
const currentBranch = gitText(repoRoot, ['branch', '--show-current']);
|
|
1149
1058
|
const targetBranch = verification.integrationEvidence?.targetBranch ?? resolveCompletionTargetBranch(repoRoot);
|
|
@@ -1259,13 +1168,9 @@ export function recordTaskVerification(
|
|
|
1259
1168
|
if ((verification.commandEvidence ?? []).some((entry) => entry.command.length === 0 || entry.command.some((part) => !part.trim()))) {
|
|
1260
1169
|
throw new Error('reported command evidence must contain a non-empty argv');
|
|
1261
1170
|
}
|
|
1262
|
-
const policy = taskExecutionPolicy(task);
|
|
1263
|
-
if (policy.requiresScopedPaths && task.allowedPaths.length === 0) {
|
|
1264
|
-
throw new Error(`${policy.executionClass} cannot be verified without an explicit allowed path scope`);
|
|
1265
|
-
}
|
|
1266
1171
|
const normalizedDeclaredChecks = normalizeCheckIds(task.checks, listControllerChecks(repoRoot));
|
|
1267
1172
|
const verificationTask = { ...task, checks: normalizedDeclaredChecks.validCheckIds };
|
|
1268
|
-
const outcome = verificationEvidencePassed(verificationTask, verification
|
|
1173
|
+
const outcome = verificationEvidencePassed(verificationTask, verification);
|
|
1269
1174
|
const successful = outcome.status === 'passed';
|
|
1270
1175
|
if (doneEvidenceBackfill) {
|
|
1271
1176
|
if (!successful) {
|
|
@@ -178,26 +178,17 @@ export async function safeLaunchdHandoff(
|
|
|
178
178
|
portChecks: [],
|
|
179
179
|
};
|
|
180
180
|
|
|
181
|
-
// Step 1:
|
|
181
|
+
// Step 1: Request bootout of the old service. launchctl is an effectful
|
|
182
|
+
// helper, so a non-zero/timeout result is not proof that the bootout did not
|
|
183
|
+
// happen. Reconcile the physical launchd state below before deciding whether
|
|
184
|
+
// this handoff may proceed.
|
|
182
185
|
const target = `${options.domain}/${options.label}`;
|
|
183
186
|
const bootoutResult = run(['bootout', target]);
|
|
184
187
|
diagnostics.bootoutResult = bootoutResult;
|
|
185
188
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
return {
|
|
190
|
-
bootstrapAttempts: 0,
|
|
191
|
-
bootoutClean: false,
|
|
192
|
-
pidWaitClean: true,
|
|
193
|
-
portWaitClean: true,
|
|
194
|
-
plistInstalled: false,
|
|
195
|
-
serviceRegistered: false,
|
|
196
|
-
diagnostics,
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// Step 2: Wait for service to disappear from launchd
|
|
189
|
+
// Step 2: Reconcile the bootout effect by waiting for the exact service to
|
|
190
|
+
// disappear from launchd. This is authoritative even when the helper returned
|
|
191
|
+
// an error after dispatching the effect.
|
|
201
192
|
const bootoutDeadline = Date.now() + maxBootoutWaitMs;
|
|
202
193
|
let serviceGone = false;
|
|
203
194
|
while (Date.now() < bootoutDeadline) {
|
|
@@ -347,6 +338,45 @@ export interface RetiredConflictingLaunchAgent {
|
|
|
347
338
|
backupPath: string;
|
|
348
339
|
}
|
|
349
340
|
|
|
341
|
+
export interface ExactLaunchAgentRetirementResult {
|
|
342
|
+
label: string;
|
|
343
|
+
plistPath: string;
|
|
344
|
+
serviceWasPresent: boolean;
|
|
345
|
+
plistWasPresent: boolean;
|
|
346
|
+
absentAfter: boolean;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
export async function retireLaunchAgentExact(
|
|
350
|
+
input: { label: string; accountHome?: string },
|
|
351
|
+
dependencies: {
|
|
352
|
+
run?: LaunchctlCommandRunner;
|
|
353
|
+
bootout?: typeof bootoutLaunchAgentWithRetryV2;
|
|
354
|
+
} = {},
|
|
355
|
+
): Promise<ExactLaunchAgentRetirementResult> {
|
|
356
|
+
const label = input.label.trim();
|
|
357
|
+
if (!label) throw new Error('FORGE_LAUNCH_AGENT_RETIRE_LABEL_REQUIRED');
|
|
358
|
+
const plistPath = launchAgentPath(label, input.accountHome);
|
|
359
|
+
const plistWasPresent = existsSync(plistPath);
|
|
360
|
+
const domain = currentUserLaunchdDomain();
|
|
361
|
+
const runner = dependencies.run ?? defaultRunner;
|
|
362
|
+
const target = `${domain}/${label}`;
|
|
363
|
+
const serviceWasPresent = runner(['print', target]).ok;
|
|
364
|
+
if (serviceWasPresent) {
|
|
365
|
+
const stopped = await (dependencies.bootout ?? bootoutLaunchAgentWithRetryV2)({
|
|
366
|
+
label,
|
|
367
|
+
plistPath,
|
|
368
|
+
domain,
|
|
369
|
+
});
|
|
370
|
+
if (!stopped.ok) {
|
|
371
|
+
throw new Error(`FORGE_LAUNCH_AGENT_EXACT_RETIRE_FAILED: ${label}: ${stopped.diagnostics.join('; ')}`);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
rmSync(plistPath, { force: true });
|
|
375
|
+
const absentAfter = !runner(['print', target]).ok && !existsSync(plistPath);
|
|
376
|
+
if (!absentAfter) throw new Error(`FORGE_LAUNCH_AGENT_EXACT_RETIRE_VERIFY_FAILED: ${label}`);
|
|
377
|
+
return { label, plistPath, serviceWasPresent, plistWasPresent, absentAfter };
|
|
378
|
+
}
|
|
379
|
+
|
|
350
380
|
function decodePlistString(value: string): string {
|
|
351
381
|
return value
|
|
352
382
|
.replaceAll('<', '<')
|
|
@@ -439,9 +469,20 @@ export async function bootstrapLaunchAgentWithRetryV2(
|
|
|
439
469
|
},
|
|
440
470
|
dependencies,
|
|
441
471
|
);
|
|
442
|
-
const diagnostics =
|
|
472
|
+
const diagnostics: string[] = [];
|
|
473
|
+
const bootout = result.diagnostics.bootoutResult;
|
|
474
|
+
if (bootout && !bootout.ok && !isBootoutAlreadyGone(bootout)) {
|
|
475
|
+
diagnostics.push(`bootout: ${(bootout.stderr || bootout.stdout || `exit=${bootout.exitCode}`).trim()}`);
|
|
476
|
+
if (result.bootoutClean) diagnostics.push('bootout-reconciled: exact launchd service is absent despite helper failure');
|
|
477
|
+
}
|
|
478
|
+
if (!result.bootoutClean && result.diagnostics.serviceProbeResults.length > 0) {
|
|
479
|
+
diagnostics.push('bootout-reconcile: exact launchd service remained registered after bounded observation');
|
|
480
|
+
}
|
|
481
|
+
if (!result.pidWaitClean) diagnostics.push('bootout-reconcile: prior service PID remained live after bounded observation');
|
|
482
|
+
if (!result.portWaitClean) diagnostics.push('bootout-reconcile: prior service port remained occupied after bounded observation');
|
|
483
|
+
diagnostics.push(...result.diagnostics.bootstrapResults.map((entry, index) =>
|
|
443
484
|
`bootstrap-${index + 1}: ${(entry.stderr || entry.stdout || `exit=${entry.exitCode}`).trim()}`,
|
|
444
|
-
);
|
|
485
|
+
));
|
|
445
486
|
return {
|
|
446
487
|
ok: result.bootoutClean && result.pidWaitClean && result.portWaitClean && result.serviceRegistered,
|
|
447
488
|
attempts: result.bootstrapAttempts,
|