@moretea-labs/forge 1.7.2 → 1.8.0
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 +58 -62
- package/CHANGELOG.md +26 -0
- package/CLAUDE.md +42 -62
- package/README.md +2 -2
- package/SKILL.md +0 -1
- package/THIRD_PARTY_NOTICES.md +5 -2
- package/adapters/browser/index.ts +2 -0
- package/adapters/chatgpt/browser-delivery-host.ts +71 -0
- package/adapters/chatgpt/browser-delivery-runtime.ts +783 -0
- package/adapters/chatgpt/controller-binding-store.ts +55 -0
- package/adapters/chatgpt/controller-host.ts +119 -0
- package/adapters/chatgpt/controller-round-host.ts +78 -0
- package/adapters/chatgpt/controller-round-settlement-store.ts +45 -0
- package/adapters/chatgpt/provider-delivery.ts +113 -0
- package/adapters/chatgpt/work-conversation-binding-store.ts +192 -0
- package/adapters/chatgpt/wsl-bridge-delivery-host.ts +63 -0
- package/adapters/computer/desktop-operator-contract.ts +7 -0
- package/adapters/computer/desktop-operator-discovery.ts +201 -0
- package/adapters/computer/desktop-operator-negotiation.ts +174 -0
- package/adapters/computer/desktop-operator-provider.ts +312 -0
- package/adapters/computer/index.ts +1 -0
- package/adapters/computer/interaction-target-authority.ts +944 -0
- package/adapters/controller-process/binding-store.ts +34 -0
- package/adapters/controller-process/controller-host.ts +26 -0
- package/adapters/mcp/access-mode.ts +132 -0
- package/adapters/mcp/audit.ts +32 -0
- package/adapters/mcp/auth.ts +407 -0
- package/adapters/mcp/controller-round-compatibility.ts +184 -0
- package/adapters/mcp/frozen-client-semantic-compatibility.ts +292 -0
- package/adapters/mcp/instructions.ts +36 -0
- package/adapters/mcp/legacy-context.ts +18 -0
- package/adapters/mcp/multi-repository.ts +437 -0
- package/adapters/mcp/oauth.ts +391 -0
- package/adapters/mcp/paths.ts +140 -0
- package/adapters/mcp/policy.ts +232 -0
- package/adapters/mcp/proxy-env.ts +62 -0
- package/adapters/mcp/readiness-projection.ts +24 -0
- package/adapters/mcp/redaction.ts +21 -0
- package/adapters/mcp/repo.ts +24 -0
- package/adapters/mcp/runtime-gateway/artifact-adapter.ts +52 -0
- package/adapters/mcp/runtime-gateway/context-adapter.ts +829 -0
- package/adapters/mcp/runtime-gateway/controller-authority-adapter.ts +191 -0
- package/adapters/mcp/runtime-gateway/engineering-preconditions.ts +147 -0
- package/adapters/mcp/runtime-gateway/execution-control-adapter.ts +28 -0
- package/adapters/mcp/runtime-gateway/execution-tools.ts +207 -0
- package/adapters/mcp/runtime-gateway/filesystem-adapter.ts +38 -0
- package/adapters/mcp/runtime-gateway/gateway-execution-adapter.ts +411 -0
- package/adapters/mcp/runtime-gateway/legacy-ios-tool-adapter.ts +105 -0
- package/adapters/mcp/runtime-gateway/maintenance-adapter.ts +44 -0
- package/adapters/mcp/runtime-gateway/model-adapter.ts +63 -0
- package/adapters/mcp/runtime-gateway/persisted-check-process.ts +3 -0
- package/adapters/mcp/runtime-gateway/plugin-adapter.ts +308 -0
- package/adapters/mcp/runtime-gateway/process-tools.ts +289 -0
- package/adapters/mcp/runtime-gateway/protected-computer-adapter.ts +76 -0
- package/adapters/mcp/runtime-gateway/recovery-adapter.ts +268 -0
- package/adapters/mcp/runtime-gateway/recovery-client-adapter.ts +70 -0
- package/adapters/mcp/runtime-gateway/recovery-tool-contract.ts +99 -0
- package/adapters/mcp/runtime-gateway/repository-compat-adapter.ts +110 -0
- package/adapters/mcp/runtime-gateway/result-adapter.ts +108 -0
- package/adapters/mcp/runtime-gateway/router.ts +728 -0
- package/adapters/mcp/runtime-gateway/runtime-observation-adapter.ts +1251 -0
- package/adapters/mcp/runtime-gateway/runtime-tool-definitions.ts +634 -0
- package/adapters/mcp/runtime-gateway/runtime-tool-shared.ts +27 -0
- package/adapters/mcp/runtime-gateway/runtime-tools.ts +68 -0
- package/adapters/mcp/runtime-gateway/scheduler-adapter.ts +186 -0
- package/adapters/mcp/runtime-gateway/shared-adapter.ts +25 -0
- package/adapters/mcp/runtime-gateway/status-inbox-adapter.ts +870 -0
- package/adapters/mcp/runtime-gateway/work-adapter.ts +3186 -0
- package/adapters/mcp/runtime-gateway/work-compat-adapter.ts +502 -0
- package/adapters/mcp/runtime-gateway/work-validation-reconciler.ts +1 -0
- package/adapters/mcp/server.ts +1048 -0
- package/adapters/mcp/setup.ts +791 -0
- package/adapters/mcp/tool-capability-cache.ts +87 -0
- package/adapters/mcp/tool-mapping/access-tools.ts +387 -0
- package/adapters/mcp/tool-mapping/legacy-tool-service.ts +5265 -0
- package/adapters/mcp/tool-mapping/post-finalize-work-attribution.ts +150 -0
- package/adapters/mcp/tool-mapping/repository-tools.ts +1691 -0
- package/adapters/mcp/tool-mapping/tools.ts +9 -0
- package/adapters/mcp/tool-mapping/umbrella-tools.ts +117 -0
- package/adapters/mcp/toolset-names.ts +74 -0
- package/adapters/mcp/toolset-selection.ts +41 -0
- package/adapters/mcp/toolset.ts +336 -0
- package/adapters/mcp/transports/http.ts +1456 -0
- package/adapters/mcp/transports/session-registry.ts +513 -0
- package/adapters/mcp/transports/stdio.ts +8 -0
- package/adapters/mcp/tunnels/openai-secure-tunnel.ts +139 -0
- package/adapters/mcp/types.ts +41 -0
- package/assets/AGENTS.md +2 -16
- package/assets/CLAUDE.md +2 -16
- package/assets/hooks/AGENTS.md +3 -14
- package/assets/hooks/CLAUDE.md +3 -14
- package/assets/hooks/hook-input.sh +9 -2
- package/assets/hooks/lib/workflow-state.sh +28 -10
- package/assets/hooks/prompt-guard.sh +63 -37
- package/assets/hooks/security-sentinel.sh +2 -1
- package/assets/hooks/session-start-context.sh +7 -5
- package/assets/hooks/stop-orchestrator.sh +13 -3
- package/assets/initializer-question-pack.v4.json +11 -7
- package/assets/partials/05-workflow.partial.md +18 -73
- package/assets/partials/07-footer.partial.md +1 -1
- package/assets/partials-agents/02-operating-mode.partial.md +1 -2
- package/assets/partials-agents/04-task-protocol.partial.md +14 -59
- package/assets/partials-agents/06-quality-safety.partial.md +11 -16
- package/assets/partials-agents/08-deep-docs.partial.md +1 -2
- package/assets/plan-map.json +11 -11
- package/assets/plugin-registry.v1.json +9 -3
- package/assets/plugin-trust-policy.v1.json +6 -0
- package/assets/recovery/ForgeRecovery.ps1 +100 -0
- package/assets/recovery/forge-wsl-rescue +271 -0
- package/assets/reference-configs/development-protocol.md +11 -15
- package/assets/reference-configs/document-generation.md +1 -1
- package/assets/reference-configs/global-working-rules.md +9 -1
- package/assets/reference-configs/harness-overview.md +22 -112
- package/assets/reference-configs/hook-operations.md +1 -1
- package/assets/reference-configs/sprint-contracts.md +2 -2
- package/assets/skill-version.json +2 -2
- package/assets/templates/helpers/architecture-event.ts +3 -34
- package/assets/templates/helpers/architecture-queue.sh +61 -10
- package/assets/templates/helpers/archive-workflow.sh +90 -180
- package/assets/templates/helpers/capability-config.ts +8 -11
- package/assets/templates/helpers/capability-resolver.ts +37 -19
- package/assets/templates/helpers/capture-plan.sh +2 -2
- package/assets/templates/helpers/check-architecture-sync.sh +1 -9
- package/assets/templates/helpers/check-task-sync.sh +82 -11
- package/assets/templates/helpers/check-task-workflow.sh +1 -3
- package/assets/templates/helpers/context-contract-sync.sh +1 -12
- package/assets/templates/helpers/contract-worktree.sh +26 -24
- package/assets/templates/helpers/ensure-task-workflow.sh +6 -8
- package/assets/templates/helpers/inspect-project-state.ts +1 -1
- package/assets/templates/helpers/migrate-project-template.sh +1 -1
- package/assets/templates/helpers/migrate-workflow-docs.ts +53 -239
- package/assets/templates/helpers/new-plan.sh +2 -2
- package/assets/templates/helpers/plan-to-todo.sh +3 -31
- package/assets/templates/helpers/sprint-backlog.sh +1 -1
- package/assets/templates/helpers/switch-plan.sh +1 -1
- package/assets/templates/helpers/workflow-contract.ts +1 -0
- package/assets/workflow-contract.v1.json +63 -171
- package/assets/workflows/xiaohongshu/xiaohongshu.collect-metrics.v1.draft.json +118 -0
- package/assets/workflows/xiaohongshu/xiaohongshu.publish-image-note.v1.draft.json +316 -0
- package/assets/workflows/xiaohongshu/xiaohongshu.publish-long-text.v1.draft.json +324 -0
- package/docs/architecture/CURRENT.md +148 -13
- package/docs/architecture/EVOLUTION.md +13 -0
- package/docs/architecture/decisions/20260801-controller-home-sqlite-state.md +2 -1
- package/docs/architecture/decisions/20260831-independent-windows-wsl-host-rescue.md +59 -0
- package/docs/architecture/decisions/20260904-ios-device-migration-baseline.md +120 -0
- package/docs/architecture/decisions/20260904-repository-runtime-data-boundary.md +42 -0
- package/docs/architecture/decisions/20260907-assistant-learning-loop.md +35 -0
- package/docs/architecture/decisions/20260907-controller-round-transition-policy.md +296 -0
- package/docs/architecture/decisions/20260907-maintenance-diagnosis-bounded-read.md +39 -0
- package/docs/architecture/domains/verification.md +7 -0
- package/docs/architecture/domains/workflow-engine.md +1 -1
- package/docs/architecture/index.md +3 -3
- package/docs/architecture/modules/controller-runtime/transport-lifecycle.md +19 -8
- package/docs/architecture/requests/2026-09-04-computer-plugin-workflow-taxonomy.md +124 -0
- package/docs/forge-chatgpt-mcp-setup.md +5 -3
- package/docs/forge-plugin-management.md +20 -4
- package/docs/forge-runtime-self-healing-loop.md +2 -0
- package/docs/operations/benchmark-cross-version-freeze.md +38 -0
- package/docs/operations/controller-browser-plugin.md +3 -1
- package/docs/operations/homebrew.md +2 -2
- package/docs/operations/platform-support.md +16 -8
- package/docs/operations/platform-support.zh-CN.md +2 -2
- package/docs/operations/standalone-disaster-recovery.md +26 -1
- package/docs/operations/uu-remote-rescue.md +41 -0
- package/docs/operations/windows-wsl-host-rescue.md +133 -0
- package/docs/public-usage-guide.md +1 -1
- package/docs/public-usage-guide.zh-CN.md +1 -1
- package/docs/tutorials/01-install-and-start.md +1 -1
- package/docs/tutorials/01-install-and-start.zh-CN.md +1 -1
- package/docs/tutorials/02-connect-chatgpt.md +4 -4
- package/docs/tutorials/02-connect-chatgpt.zh-CN.md +4 -4
- package/docs/wiki/Implementation.md +1 -1
- package/package.json +23 -14
- package/packages/kernel/controller/api/index.ts +2 -0
- package/packages/kernel/controller/application/controller-round-service.ts +29 -0
- package/packages/kernel/controller/application/controller-service.ts +30 -0
- package/packages/kernel/controller/domain/controller-round-transition-policy.ts +308 -0
- package/packages/kernel/controller/domain/controller-round.ts +107 -0
- package/packages/kernel/controller/domain/execution-quality.ts +133 -0
- package/packages/kernel/controller/domain/types.ts +56 -0
- package/packages/kernel/controller/index.ts +1 -0
- package/packages/kernel/controller/infrastructure/controller-binding-store.ts +84 -0
- package/packages/kernel/controller/infrastructure/controller-round-store.ts +1384 -0
- package/packages/kernel/controller/infrastructure/controller-session-store.ts +578 -0
- package/packages/kernel/controller/ports/controller-host.ts +16 -0
- package/packages/kernel/goal/api/index.ts +1 -0
- package/packages/kernel/goal/domain/types.ts +40 -0
- package/packages/kernel/goal/index.ts +1 -0
- package/packages/kernel/identity/api/index.ts +5 -0
- package/packages/kernel/identity/application/identity-service.ts +67 -0
- package/packages/kernel/identity/domain/scope.ts +63 -0
- package/packages/kernel/identity/domain/semantic-sync.ts +81 -0
- package/packages/kernel/identity/domain/types.ts +44 -0
- package/packages/kernel/identity/domain/workspace.ts +56 -0
- package/packages/kernel/identity/index.ts +1 -0
- package/packages/kernel/identity/infrastructure/identity-store.ts +75 -0
- package/packages/kernel/memory/api/index.ts +5 -0
- package/packages/kernel/memory/application/experience-service.ts +118 -0
- package/packages/kernel/memory/application/outcome-service.ts +77 -0
- package/packages/kernel/memory/domain/experience.ts +103 -0
- package/packages/kernel/memory/domain/operational-prior.ts +92 -0
- package/packages/kernel/memory/index.ts +1 -0
- package/packages/kernel/progression/api/index.ts +2 -0
- package/packages/kernel/progression/application/projector.ts +211 -0
- package/packages/kernel/progression/domain/types.ts +116 -0
- package/packages/kernel/progression/index.ts +1 -0
- package/packages/kernel/scheduler/api/index.ts +6 -0
- package/packages/kernel/scheduler/application/continuation-service.ts +212 -0
- package/packages/kernel/scheduler/application/eligibility.ts +252 -0
- package/packages/kernel/scheduler/application/schedule-service.ts +24 -0
- package/packages/kernel/scheduler/application/settlement.ts +197 -0
- package/packages/kernel/scheduler/domain/continuation.ts +38 -0
- package/packages/kernel/scheduler/domain/schedule.ts +149 -0
- package/packages/kernel/scheduler/index.ts +1 -0
- package/packages/kernel/scheduler/infrastructure/continuation-dispatch-store.ts +38 -0
- package/packages/kernel/scheduler/infrastructure/schedule-store.ts +785 -0
- package/packages/kernel/work/api/index.ts +15 -0
- package/packages/kernel/work/application/work-service.ts +148 -0
- package/packages/kernel/work/domain/admission-policy.ts +34 -0
- package/packages/kernel/work/domain/check-receipt.ts +43 -0
- package/packages/kernel/work/domain/context-closure-receipt.ts +32 -0
- package/packages/kernel/work/domain/engineering-contracts.ts +157 -0
- package/packages/kernel/work/domain/engineering-design.ts +281 -0
- package/packages/kernel/work/domain/engineering-profile.ts +242 -0
- package/packages/kernel/work/domain/execution-concurrency.ts +254 -0
- package/packages/kernel/work/domain/execution-snapshot.ts +33 -0
- package/packages/kernel/work/domain/implementation-review.ts +510 -0
- package/packages/kernel/work/domain/project-engineering-contract.ts +202 -0
- package/packages/kernel/work/domain/repository-completion-receipt.ts +73 -0
- package/packages/kernel/work/domain/state-machine.ts +259 -0
- package/packages/kernel/work/domain/types.ts +528 -0
- package/packages/kernel/work/index.ts +1 -0
- package/packages/kernel/work/infrastructure/work-contract-store.ts +1876 -0
- package/packages/kernel/work/ports/work-contract-store.ts +18 -0
- package/packages/plugin-runtime/browser/index.ts +3 -0
- package/packages/plugin-runtime/browser/provider-registry.ts +110 -0
- package/packages/plugin-runtime/browser/runtime-contract.ts +150 -0
- package/packages/plugin-runtime/browser/session-authority.ts +61 -0
- package/packages/plugin-runtime/computer/index.ts +6 -0
- package/packages/plugin-runtime/computer/provider-error.ts +26 -0
- package/packages/plugin-runtime/computer/provider-registration.ts +52 -0
- package/packages/plugin-runtime/computer/provider-registry.ts +63 -0
- package/packages/plugin-runtime/computer/provider.ts +19 -0
- package/packages/plugin-runtime/computer/target-authority.ts +190 -0
- package/packages/plugin-runtime/computer/target-persistence.ts +54 -0
- package/packages/plugin-runtime/external/index.ts +1 -0
- package/packages/plugin-runtime/external/unix-jsonl-transport.ts +457 -0
- package/packages/plugin-runtime/index.ts +3 -0
- package/packages/protocols/browser/index.ts +1 -0
- package/packages/protocols/browser/session.ts +98 -0
- package/packages/protocols/computer/contract.ts +199 -0
- package/packages/protocols/computer/index.ts +1 -0
- package/packages/protocols/failure/contract.ts +158 -0
- package/packages/protocols/failure/index.ts +1 -0
- package/packages/protocols/handoff/index.ts +1 -0
- package/packages/protocols/handoff/status.ts +22 -0
- package/packages/protocols/mcp/execution-context.ts +11 -0
- package/packages/protocols/mcp/index.ts +2 -0
- package/packages/protocols/mcp/tool-contract.ts +42 -0
- package/packages/workflow-runtime/api/index.ts +2 -0
- package/packages/workflow-runtime/application/interpreter.ts +342 -0
- package/packages/workflow-runtime/domain/workflow-asset.ts +223 -0
- package/packages/workflow-runtime/index.ts +1 -0
- package/scripts/assemble-template.ts +1 -1
- package/scripts/benchmark-computer-hotpath.ts +255 -0
- package/scripts/benchmark-controller-round2.ts +54 -2
- package/scripts/benchmark-ios-agent-device.ts +3 -6
- package/scripts/benchmark-mcp-transport.ts +3 -4
- package/scripts/benchmark-operational-memory-activation.ts +235 -0
- package/scripts/benchmark-operational-shadow.ts +28 -0
- package/scripts/bootstrap-runtime-maintenance-recovery.sh +4 -1
- package/scripts/canary-chatgpt-provider-delivery.ts +97 -0
- package/scripts/canary-controller-semantic-wait.ts +195 -0
- package/scripts/canary-global-hook.sh +2 -2
- package/scripts/check-mcp-compatibility.ts +173 -7
- package/scripts/check-platform-support.mjs +28 -2
- package/scripts/check-public-docs.sh +1 -1
- package/scripts/check-release-readiness.sh +1 -1
- package/scripts/check-repository-hygiene.mjs +92 -0
- package/scripts/check-runtime-architecture.mjs +1206 -95
- package/scripts/check-source-duplication.mjs +9 -1
- package/scripts/check-tarball-install-smoke.sh +98 -15
- package/scripts/controller-ngrok-rotation.sh +5 -4
- package/scripts/create-project-dirs.sh +10 -74
- package/scripts/forge-local-recovery-helper.mjs +204 -0
- package/scripts/forge-uu-remote-rescue-helper.d.mts +31 -0
- package/scripts/forge-uu-remote-rescue-helper.mjs +409 -0
- package/scripts/forge-windows-host-recovery-helper.mjs +136 -0
- package/scripts/hook-shim.sh +2 -2
- package/scripts/init-project.sh +12 -70
- package/scripts/install-desktop-operator-registration.ts +4 -2
- package/scripts/install-independent-windows-wsl-recovery.ts +125 -0
- package/scripts/install-standalone-recovery.ts +122 -10
- package/scripts/install-uu-remote-rescue-registration.ts +74 -0
- package/scripts/install-windows-host-recovery-registration.ts +22 -0
- package/scripts/lib/controller-home-env.sh +6 -3
- package/scripts/lib/project-init-lib.sh +39 -582
- package/scripts/migrate-chatgpt-automation-schedules.ts +2 -2
- package/scripts/migrate-windows-wsl-controller-home.ts +306 -0
- package/scripts/open-source-audit-allowlist.txt +12 -1
- package/scripts/portability-bindings.mjs +70 -0
- package/scripts/run-bounded-command.mjs +55 -0
- package/scripts/run-bun-test-file.ts +22 -6
- package/scripts/run-governed-gate.ts +4 -1
- package/scripts/smoke-mcp-http-runtime.ts +1 -1
- package/scripts/smoke-runtime-recovery.ts +34 -1
- package/scripts/smoke-schedule-engine.ts +1 -1
- package/scripts/stage-runtime-release.ts +6 -1
- package/scripts/test-governance.ts +51 -2
- package/src/cli/agent-jobs/job-manager.ts +10 -1
- package/src/cli/chatgpt-browser/bind-server.ts +2 -1
- package/src/cli/chatgpt-browser/binding.ts +20 -10
- package/src/cli/chatgpt-browser/bridge-extension.ts +75 -0
- package/src/cli/chatgpt-browser/bridge-provider.ts +376 -11
- package/src/cli/chatgpt-browser/engine.ts +10 -11
- package/src/cli/chatgpt-browser/native-provider.ts +24 -83
- package/src/cli/chatgpt-browser/oracle-provider.ts +5 -3
- package/src/cli/chatgpt-browser/types.ts +1 -0
- package/src/cli/commands/bootstrap-control.ts +334 -0
- package/src/cli/commands/brain-assistant.ts +38 -0
- package/src/cli/commands/brain.ts +193 -40
- package/src/cli/commands/chatgpt.ts +127 -0
- package/src/cli/commands/computer.ts +437 -0
- package/src/cli/commands/doctor.ts +18 -1
- package/src/cli/commands/init-hook.ts +71 -61
- package/src/cli/commands/init.ts +3 -1
- package/src/cli/commands/mcp.ts +16 -10
- package/src/cli/commands/plugin.ts +38 -12
- package/src/cli/commands/recovery.ts +493 -80
- package/src/cli/commands/runtime.ts +9 -4
- package/src/cli/commands/setup-profile.ts +89 -39
- package/src/cli/commands/status.ts +2 -1
- package/src/cli/controller/check-runner.ts +487 -98
- package/src/cli/controller/context/types.ts +7 -1
- package/src/cli/controller/context-pack.ts +23 -3
- package/src/cli/controller/issue-store.ts +1 -1
- package/src/cli/controller/systemd-user.ts +110 -0
- package/src/cli/controller/types.ts +10 -70
- package/src/cli/controller/worklog.ts +67 -13
- package/src/cli/editing/edit-operation-contract.ts +92 -0
- package/src/cli/editing/edit-session.ts +289 -13
- package/src/cli/github/plugin.ts +17 -12
- package/src/cli/hook/route-registry.ts +3 -5
- package/src/cli/hook/runtime.ts +49 -3
- package/src/cli/index.ts +3 -0
- package/src/cli/local-bridge/connector-freshness.ts +2 -2
- package/src/cli/local-bridge/console-automations.ts +2 -2
- package/src/cli/local-bridge/facade-api.ts +41 -14
- package/src/cli/local-bridge/job-store.ts +1 -1
- package/src/cli/local-bridge/server.ts +24 -27
- package/src/cli/mcp/access-mode.ts +2 -132
- package/src/cli/mcp/access-tools.ts +2 -387
- package/src/cli/mcp/audit.ts +2 -32
- package/src/cli/mcp/auth.ts +2 -404
- package/src/cli/mcp/instructions.ts +2 -34
- package/src/cli/mcp/legacy-context.ts +2 -16
- package/src/cli/mcp/legacy-tool-service.ts +2 -5308
- package/src/cli/mcp/multi-repository.ts +2 -436
- package/src/cli/mcp/oauth.ts +2 -375
- package/src/cli/mcp/openai-secure-tunnel.ts +2 -0
- package/src/cli/mcp/paths.ts +2 -140
- package/src/cli/mcp/policy.ts +2 -232
- package/src/cli/mcp/post-finalize-work-attribution.ts +2 -150
- package/src/cli/mcp/proxy-env.ts +2 -62
- package/src/cli/mcp/readiness-projection.ts +2 -24
- package/src/cli/mcp/redaction.ts +2 -21
- package/src/cli/mcp/repo.ts +2 -24
- package/src/cli/mcp/repository-tools.ts +2 -1613
- package/src/cli/mcp/server.ts +2 -951
- package/src/cli/mcp/setup.ts +2 -737
- package/src/cli/mcp/tool-capability-cache.ts +2 -87
- package/src/cli/mcp/tool-contract.ts +2 -14
- package/src/cli/mcp/tools.ts +2 -9
- package/src/cli/mcp/toolset-names.ts +2 -70
- package/src/cli/mcp/toolset-selection.ts +2 -41
- package/src/cli/mcp/toolset.ts +2 -336
- package/src/cli/mcp/transports/AGENTS.md +1 -10
- package/src/cli/mcp/transports/CLAUDE.md +1 -10
- package/src/cli/mcp/transports/http.ts +2 -1414
- package/src/cli/mcp/transports/session-registry.ts +2 -490
- package/src/cli/mcp/transports/stdio.ts +2 -8
- package/src/cli/mcp/types.ts +2 -41
- package/src/cli/mcp/umbrella-tools.ts +2 -117
- package/src/cli/repositories/command-executor.ts +64 -18
- package/src/cli/repositories/command-scope.ts +117 -1
- package/src/cli/repositories/controller-home.ts +119 -1
- package/src/cli/repositories/identity.ts +13 -0
- package/src/cli/repositories/registry.ts +68 -49
- package/src/cli/repositories/repository-snapshot.ts +53 -7
- package/src/cli/repositories/runtime-storage.ts +27 -2
- package/src/cli/repositories/safe-patch.ts +34 -38
- package/src/cli/repositories/selected-path-actions.ts +22 -2
- package/src/cli/repositories/structured-git.ts +105 -25
- package/src/cli/runtime/helper-runner.ts +7 -0
- package/src/cli/runtime-invocation.ts +8 -1
- package/src/cli/tools/codegraph.ts +44 -25
- package/src/core/adoption/manifest-templates.ts +1 -1
- package/src/core/adoption/plan.ts +3 -26
- package/src/core/adoption/workflow-contract-plan.ts +17 -9
- package/src/effects/process-runner.ts +8 -14
- package/src/runtime/context/assistant-context.ts +154 -0
- package/src/runtime/context/assistant-work-context.ts +147 -0
- package/src/runtime/context/codegraph-cache-boundary.ts +255 -0
- package/src/runtime/context/codegraph-read-provider.ts +55 -22
- package/src/runtime/context/codegraph-sidecar.cjs +8 -1
- package/src/runtime/context/context-closure.ts +268 -0
- package/src/runtime/context/context-plane.ts +211 -0
- package/src/runtime/context/project-engineering-contract.ts +60 -0
- package/src/runtime/control-plane/bootstrap/capability-provider.ts +74 -0
- package/src/runtime/control-plane/bootstrap/control-api.ts +57 -0
- package/src/runtime/control-plane/bootstrap/index.ts +5 -0
- package/src/runtime/control-plane/bootstrap/state-machine.ts +141 -0
- package/src/runtime/control-plane/bootstrap/store.ts +21 -0
- package/src/runtime/control-plane/bootstrap/types.ts +87 -0
- package/src/runtime/control-plane/cleanup-artifact-retention.ts +328 -0
- package/src/runtime/control-plane/codegraph-cache-retention.ts +164 -0
- package/src/runtime/control-plane/concurrency/work-execution-concurrency.ts +320 -0
- package/src/runtime/control-plane/execution/content-equivalent-commit-authority.ts +169 -0
- package/src/runtime/control-plane/execution/controller-authority-recovery.ts +350 -0
- package/src/runtime/control-plane/execution/direct-canonical-work-reconciliation.ts +85 -0
- package/src/runtime/control-plane/execution/direct-edit-work-completion.ts +369 -99
- package/src/runtime/control-plane/execution/edit-validation-coordinator.ts +103 -15
- package/src/runtime/control-plane/execution/implementation-review-content.ts +95 -0
- package/src/runtime/control-plane/execution/repository-work-attribution.ts +2 -2
- package/src/runtime/control-plane/execution/retained-work-resume.ts +336 -6
- package/src/runtime/control-plane/execution/validation.ts +28 -3
- package/src/runtime/control-plane/execution/work-authority-reconciler.ts +116 -0
- package/src/runtime/control-plane/execution/work-completion-authority.ts +44 -2
- package/src/runtime/control-plane/execution/work-evidence-policy.ts +34 -3
- package/src/runtime/control-plane/execution/work-execution-support.ts +42 -22
- package/src/runtime/control-plane/execution/work-finalization-service.ts +1103 -166
- package/src/runtime/control-plane/execution/work-handle-authority.ts +219 -22
- package/src/runtime/control-plane/execution/work-handle-store.ts +77 -0
- package/src/runtime/control-plane/execution/work-head-settlement.ts +75 -0
- package/src/runtime/control-plane/execution/work-lifecycle-audit.ts +145 -23
- package/src/runtime/control-plane/execution/work-operation-service.ts +49 -13
- package/src/runtime/control-plane/execution/work-preparation-service.ts +31 -15
- package/src/runtime/control-plane/execution/work-remote-delivery.ts +1 -1
- package/src/runtime/control-plane/execution/work-task-receipt.ts +20 -1
- package/src/runtime/control-plane/execution/work-terminal-cleanup.ts +407 -76
- package/src/runtime/control-plane/execution/work-validation-reconciler.ts +88 -18
- package/src/runtime/control-plane/execution/work-verification-context.ts +1 -1
- package/src/runtime/control-plane/execution/work-verification-service.ts +258 -4
- package/src/runtime/control-plane/execution/work-verification-snapshot.ts +200 -15
- package/src/runtime/control-plane/facade/capability-registry.ts +21 -10
- package/src/runtime/control-plane/facade/controller-round-relay.ts +3 -1118
- package/src/runtime/control-plane/facade/controller-session-store.ts +2 -488
- package/src/runtime/control-plane/facade/goal-workloop-access.ts +6 -3
- package/src/runtime/control-plane/facade/goal-workloop.ts +972 -137
- package/src/runtime/control-plane/facade/handoff-inbox-application.ts +158 -0
- package/src/runtime/control-plane/facade/handoff-inbox-store.ts +10 -0
- package/src/runtime/control-plane/facade/index.ts +4 -2
- package/src/runtime/control-plane/facade/operation-digest.ts +22 -58
- package/src/runtime/control-plane/facade/plan-contract-store.ts +1004 -38
- package/src/runtime/control-plane/facade/repository-work-admission.ts +19 -1
- package/src/runtime/control-plane/facade/requirement-authority.ts +218 -0
- package/src/runtime/control-plane/facade/requirement-board.ts +6 -1
- package/src/runtime/control-plane/facade/rh-work-operation-contract.ts +48 -0
- package/src/runtime/control-plane/facade/semantic-admission.ts +8 -16
- package/src/runtime/control-plane/facade/suggested-actions.ts +4 -1
- package/src/runtime/control-plane/facade/types.ts +189 -532
- package/src/runtime/control-plane/facade/work-admission-policy.ts +84 -35
- package/src/runtime/control-plane/facade/work-contract-store.ts +2 -1043
- package/src/runtime/control-plane/facade/work-implementation-review.ts +2 -0
- package/src/runtime/control-plane/facade/work-state-machine.ts +2 -250
- package/src/runtime/control-plane/generated-cache-retention.ts +239 -18
- package/src/runtime/control-plane/global-scheduler/durable-admission.ts +12 -1
- package/src/runtime/control-plane/global-scheduler/maintenance.ts +76 -13
- package/src/runtime/control-plane/global-scheduler/periodic-cleanup-entry.ts +55 -0
- package/src/runtime/control-plane/global-scheduler/periodic-cleanup-process.ts +98 -0
- package/src/runtime/control-plane/global-scheduler/reconciliation.ts +1 -1
- package/src/runtime/control-plane/global-scheduler/scheduler-worker-entry.ts +10 -0
- package/src/runtime/control-plane/global-scheduler/scheduler.ts +173 -81
- package/src/runtime/control-plane/global-scheduler/worker-launch.ts +18 -6
- package/src/runtime/control-plane/launcher/chatgpt-round-continuation.ts +397 -0
- package/src/runtime/control-plane/launcher/chatgpt-work-binding-store.ts +2 -177
- package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +301 -560
- package/src/runtime/control-plane/launcher/provider-mcp-bootstrap.ts +20 -4
- package/src/runtime/control-plane/launcher/thin-launcher.ts +50 -4
- package/src/runtime/control-plane/lifecycle-retention-metrics.ts +60 -0
- package/src/runtime/control-plane/persistence/experience-store.ts +169 -0
- package/src/runtime/control-plane/persistence/operational-prior-store.ts +348 -0
- package/src/runtime/control-plane/persistence/requirement-store.ts +30 -22
- package/src/runtime/control-plane/persistence/sqlite-store.ts +545 -76
- package/src/runtime/control-plane/persistence/workflow-content-store.ts +98 -0
- package/src/runtime/control-plane/persistence/workflow-registry-store.ts +186 -0
- package/src/runtime/control-plane/persistence/workflow-run-store.ts +123 -0
- package/src/runtime/control-plane/release-retention.ts +56 -16
- package/src/runtime/control-plane/repository-namespace-retention.ts +208 -0
- package/src/runtime/control-plane/routing/route-policy.ts +19 -0
- package/src/runtime/control-plane/runtime-cleanup.ts +574 -37
- package/src/runtime/control-plane/runtime-generation.ts +6 -0
- package/src/runtime/control-plane/workspace/semantic-sync-service.ts +465 -0
- package/src/runtime/control-plane/workspace/workspace-store.ts +80 -0
- package/src/runtime/diagnostics/incident-repair.ts +406 -0
- package/src/runtime/diagnostics/mcp-timing.ts +125 -6
- package/src/runtime/diagnostics/performance.ts +6 -14
- package/src/runtime/diagnostics/read-only-tool.ts +1 -1
- package/src/runtime/evidence/artifact-store.ts +65 -2
- package/src/runtime/evidence/operational-shadow.ts +38 -0
- package/src/runtime/evidence/process-check-receipt.ts +5 -43
- package/src/runtime/evidence/sensitive-output.ts +4 -4
- package/src/runtime/execution/jobs/receipt-recovery.ts +1 -1
- package/src/runtime/execution/jobs/store.ts +121 -2
- package/src/runtime/execution/managed-workspace.ts +55 -5
- package/src/runtime/execution/process-runtime/canary.ts +19 -5
- package/src/runtime/execution/process-runtime/check-classification.ts +48 -0
- package/src/runtime/execution/process-runtime/check-facade.ts +23 -9
- package/src/runtime/execution/process-runtime/check-receipt.ts +1 -1
- package/src/runtime/execution/process-runtime/check-result-retention.ts +132 -0
- package/src/runtime/execution/process-runtime/check-result.ts +73 -2
- package/src/runtime/execution/process-runtime/check-runner-sidecar.ts +42 -3
- package/src/runtime/execution/process-runtime/check-storage.ts +187 -0
- package/src/runtime/execution/process-runtime/command-facade.ts +38 -87
- package/src/runtime/execution/process-runtime/index.ts +1 -0
- package/src/runtime/execution/process-runtime/interactive-admission.ts +2 -1
- package/src/runtime/execution/process-runtime/lightweight-managed.ts +32 -1
- package/src/runtime/execution/process-runtime/persisted-check.ts +128 -21
- package/src/runtime/execution/process-runtime/resource-claims.ts +60 -3
- package/src/runtime/execution/process-runtime/runtime.ts +132 -15
- package/src/runtime/execution/process-runtime/types.ts +22 -0
- package/src/runtime/execution/workers/executor.ts +16 -13
- package/src/runtime/execution/workers/worker-entry.ts +1 -1
- package/src/runtime/gateway/mcp/execution-tools.ts +2 -207
- package/src/runtime/gateway/mcp/legacy-ios-tool-adapter.ts +2 -61
- package/src/runtime/gateway/mcp/persisted-check-process.ts +2 -3
- package/src/runtime/gateway/mcp/process-tools.ts +2 -289
- package/src/runtime/gateway/mcp/router.ts +2 -1125
- package/src/runtime/gateway/mcp/runtime-tool-definitions.ts +2 -565
- package/src/runtime/gateway/mcp/runtime-tools.ts +2 -6655
- package/src/runtime/gateway/mcp/work-validation-reconciler.ts +2 -1
- package/src/runtime/maintenance/cleanup.ts +38 -24
- package/src/runtime/platform/browser-product-discovery.ts +174 -0
- package/src/runtime/platform/computer-platform.ts +14 -0
- package/src/runtime/platform/executable-discovery.ts +54 -0
- package/src/runtime/platform/fetch-http-server.ts +90 -0
- package/src/runtime/platform/service-manager.ts +138 -0
- package/src/runtime/platform/windows-host-discovery.ts +118 -0
- package/src/runtime/platform/windows-recovery-deployment.ts +67 -0
- package/src/runtime/plugins/action-application.ts +135 -0
- package/src/runtime/plugins/app-store-connect-adapter.ts +9 -21
- package/src/runtime/plugins/browser-adapter.ts +140 -100
- package/src/runtime/plugins/browser-automation-service.ts +15 -36
- package/src/runtime/plugins/browser-macos-bridge.ts +69 -21
- package/src/runtime/plugins/browser-manifest-surface.ts +30 -6
- package/src/runtime/plugins/browser-native-session-service.ts +1 -1
- package/src/runtime/plugins/browser-provider-registry.ts +2 -109
- package/src/runtime/plugins/browser-registration.ts +16 -0
- package/src/runtime/plugins/browser-runtime-contract.ts +2 -154
- package/src/runtime/plugins/browser-runtime.ts +41 -9
- package/src/runtime/plugins/browser-session-authority.ts +101 -291
- package/src/runtime/plugins/browser-session-legacy-migration.ts +203 -0
- package/src/runtime/plugins/browser-session-store.ts +229 -36
- package/src/runtime/plugins/browser-session-types.ts +2 -98
- package/src/runtime/plugins/capability-authorization-grants.ts +17 -0
- package/src/runtime/plugins/catalog-trust.ts +82 -0
- package/src/runtime/plugins/computer-registration.ts +839 -0
- package/src/runtime/plugins/config-store.ts +119 -0
- package/src/runtime/plugins/desktop-operator-external-policy.ts +932 -0
- package/src/runtime/plugins/desktop-operator-registration.ts +111 -8
- package/src/runtime/plugins/errors.ts +8 -1
- package/src/runtime/plugins/external-adapter.ts +45 -322
- package/src/runtime/plugins/external-provider-policy.ts +48 -0
- package/src/runtime/plugins/external-registration.ts +9 -1
- package/src/runtime/plugins/external-unix-socket-probe.cjs +9 -3
- package/src/runtime/plugins/external-unix-socket.ts +64 -193
- package/src/runtime/plugins/first-party-external-registration.ts +163 -0
- package/src/runtime/plugins/first-party-registry.ts +3 -1
- package/src/runtime/plugins/github-adapter.ts +1 -2
- package/src/runtime/plugins/gmail-adapter.ts +6 -6
- package/src/runtime/plugins/google-calendar-adapter.ts +6 -6
- package/src/runtime/plugins/google-shared.ts +31 -46
- package/src/runtime/plugins/google-tasks-adapter.ts +6 -6
- package/src/runtime/plugins/ios-adapter.ts +1 -2
- package/src/runtime/plugins/local-system-adapter.ts +180 -0
- package/src/runtime/plugins/macos-capability-broker.ts +15 -105
- package/src/runtime/plugins/resend-adapter.ts +15 -24
- package/src/runtime/plugins/store.ts +493 -51
- package/src/runtime/plugins/types.ts +8 -1
- package/src/runtime/plugins/uu-remote-rescue-registration.ts +155 -0
- package/src/runtime/plugins/windows-host-recovery-install.ts +68 -0
- package/src/runtime/plugins/windows-host-recovery-registration.ts +85 -0
- package/src/runtime/plugins/xiaohongshu-publish.ts +86 -430
- package/src/runtime/projections/controller-context.ts +12 -6
- package/src/runtime/projections/git-status-sampler.ts +73 -22
- package/src/runtime/projections/materialized-view.ts +14 -8
- package/src/runtime/recovery/capability-action-application.ts +228 -0
- package/src/runtime/recovery/index.ts +3 -0
- package/src/runtime/recovery/lifecycle-inventory.ts +338 -0
- package/src/runtime/recovery/local-jobs-repair.ts +14 -14
- package/src/runtime/recovery/maintenance-executor.ts +358 -76
- package/src/runtime/recovery/quarantine-retention.ts +256 -0
- package/src/runtime/release/identity.ts +6 -0
- package/src/runtime/resources/leases/store.ts +1 -1
- package/src/runtime/root/active-execution-power-assertion.ts +139 -0
- package/src/runtime/root/assistant-learning-loop.ts +45 -0
- package/src/runtime/root/browser-session-composition.ts +59 -0
- package/src/runtime/root/computer-composition.ts +191 -0
- package/src/runtime/root/computer-target-composition.ts +16 -0
- package/src/runtime/root/computer-target-persistence.ts +39 -0
- package/src/runtime/root/controller-round-composition.ts +107 -0
- package/src/runtime/root/controller-services.ts +2 -0
- package/src/runtime/root/entry.ts +4 -3
- package/src/runtime/root/gateway-adapter.ts +3 -3
- package/src/runtime/root/local-bridge.ts +5 -2
- package/src/runtime/root/mcp-transport.ts +5 -5
- package/src/runtime/root/package-connector-service.ts +108 -56
- package/src/runtime/root/package-runtime-release.ts +85 -18
- package/src/runtime/root/package-runtime-service.ts +60 -97
- package/src/runtime/root/release-execution-canary.ts +71 -0
- package/src/runtime/root/release-loader.ts +68 -0
- package/src/runtime/root/release-manifest.ts +106 -2
- package/src/runtime/root/release-materialize.ts +103 -4
- package/src/runtime/root/release-store.ts +31 -2
- package/src/runtime/root/runtime.ts +240 -25
- package/src/runtime/root/scheduled-controller-composition.ts +51 -0
- package/src/runtime/root/scheduler.ts +12 -4
- package/src/runtime/root/service-runner.ts +1 -1
- package/src/runtime/root/service.ts +41 -16
- package/src/runtime/root/status.ts +1 -0
- package/src/runtime/root/types.ts +24 -1
- package/src/runtime/shared/local-bridge-surface.ts +1 -1
- package/src/runtime/shared/process-environment.ts +19 -4
- package/src/runtime/shared/storage-capacity.ts +68 -0
- package/src/runtime/standalone-recovery/controller-home-migration.ts +1116 -0
- package/src/runtime/standalone-recovery/core.ts +984 -230
- package/src/runtime/standalone-recovery/entry.ts +182 -51
- package/src/runtime/standalone-recovery/independent-host-rescue.ts +172 -0
- package/src/runtime/standalone-recovery/installer.ts +212 -104
- package/src/runtime/standalone-recovery/mcp-server.ts +243 -0
- package/src/runtime/standalone-recovery/mutation-identity-contract.ts +21 -0
- package/src/runtime/standalone-recovery/operation-lock.ts +160 -0
- package/src/runtime/standalone-recovery/performance.ts +135 -0
- package/src/runtime/standalone-recovery/release.ts +5 -0
- package/src/runtime/watchdog/workflow-watchdog.ts +1 -1
- package/src/runtime/workflow/schedules/chatgpt-automation-migration.ts +1 -1
- package/src/runtime/workflow/schedules/engine.ts +191 -343
- package/src/runtime/workflow/schedules/pending-activation.ts +1 -1
- package/src/runtime/workflow/schedules/settlement.ts +2 -191
- package/src/runtime/workflow/schedules/store.ts +2 -607
- package/src/runtime/workflow/schedules/types.ts +2 -127
- package/src/runtime/workflow/schedules/work-continuation.ts +180 -15
- package/src/runtime/workflows/first-party/xiaohongshu.ts +122 -0
- package/src/runtime/workflows/runtime.ts +486 -0
- package/src/testing/test-governance.ts +90 -29
- package/assets/templates/helpers/archive-architecture-request.sh +0 -244
- package/docs/architecture/history/README.md +0 -7
- package/docs/architecture/history/chatgpt-handoff-facade.md +0 -397
- package/docs/architecture/history/global-hook-runtime.md +0 -166
- package/docs/architecture/history/ios-semantic-automation-provider-v2.md +0 -170
- package/docs/architecture/requests/archive/2026/20260528-154740-ai-hooks-ai-hooks-hook-input-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-154816-assets-hooks-assets-hooks-hook-input-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-161851-ai-harness-workflow-contract-json-ai-harness-workflow-contract-json.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-161853-scripts-check-task-workflow-sh-scripts-check-task-workflow-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-161911-assets-workflow-contract-v1-json-assets-workflow-contract-v1-json.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-222416-ai-hooks-ai-hooks-hook-input-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-222444-ai-hooks-ai-hooks-pre-edit-guard-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-222457-ai-hooks-ai-hooks-pre-edit-guard-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-222648-ai-hooks-ai-hooks-pre-edit-guard-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-222705-ai-hooks-ai-hooks-worktree-guard-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-222726-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-222727-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-224736-ai-hooks-ai-hooks-hook-input-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-233259-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-233335-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-233456-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-233457-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-233637-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260528-233638-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260529-000322-root-package-json.md +0 -59
- package/docs/architecture/requests/archive/2026/20260529-004238-ai-hooks-ai-hooks-lib-workflow-state-sh.md +0 -59
- package/docs/architecture/requests/archive/2026/20260529-020654-ai-harness-policy-json-ai-harness-policy-json.md +0 -63
- package/docs/architecture/requests/archive/2026/20260529-094236-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -60
- package/docs/architecture/requests/archive/2026/20260529-094323-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -60
- package/docs/architecture/requests/archive/2026/20260529-094331-ai-hooks-ai-hooks-prompt-guard-sh.md +0 -60
- package/docs/architecture/requests/archive/2026/20260529-094339-assets-hooks-assets-hooks-prompt-guard-sh.md +0 -60
- package/docs/architecture/requests/archive/2026/20260529-094430-assets-hooks-assets-hooks-session-start-context-sh.md +0 -60
- package/docs/architecture/requests/archive/2026/20260529-094446-ai-hooks-ai-hooks-session-start-context-sh.md +0 -60
- package/docs/architecture/requests/archive/2026/20260613-002040-runtime-harness-hook-adapters.md +0 -68
- package/docs/architecture/requests/archive/2026/root.md +0 -68
- package/docs/architecture/requests/archive/2026/runtime-harness-hook-adapters.md +0 -76
- package/docs/architecture/requests/archive/2026/verification-evals-checks.md +0 -68
- package/docs/architecture/requests/archive/2026/workflow-engine-contract-assets.md +0 -69
- package/scripts/archive-architecture-request.sh +0 -4
- package/scripts/run-skill-evals.ts +0 -1022
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { createHash } from 'crypto';
|
|
2
|
-
import {
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'fs';
|
|
3
3
|
import { homedir } from 'os';
|
|
4
4
|
import { basename, dirname, join, resolve } from 'path';
|
|
5
|
-
import {
|
|
6
|
-
import { bootstrapLaunchAgentWithRetryV2, installLaunchAgent, launchAgentPath, retireConflictingForgeLaunchAgents } from '../../cli/controller/launch-agents';
|
|
5
|
+
import { loadMcpServiceLocalConfig } from '../../cli/mcp/auth';
|
|
7
6
|
import type { PackageRuntimeRelease } from './package-runtime-release';
|
|
7
|
+
import { createPlatformServiceManagerHost, platformLaunchdInstalledPath, type PlatformServiceManagerHost, type SystemdUserUnitInput } from '../platform/service-manager';
|
|
8
8
|
|
|
9
9
|
export interface PackageConnectorServicePaths {
|
|
10
10
|
label: string;
|
|
@@ -41,6 +41,8 @@ export interface PackageConnectorServiceResult {
|
|
|
41
41
|
releaseRoot?: string;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
+
export type PackageConnectorAuthMode = 'oauth' | 'none';
|
|
45
|
+
|
|
44
46
|
function xml(value: string): string {
|
|
45
47
|
return value.replaceAll('&', '&').replaceAll('<', '<').replaceAll('>', '>').replaceAll('"', '"');
|
|
46
48
|
}
|
|
@@ -61,7 +63,7 @@ export function packageConnectorServicePaths(controllerHome: string, accountHome
|
|
|
61
63
|
label,
|
|
62
64
|
serviceRoot,
|
|
63
65
|
sourcePlistPath: join(serviceRoot, `${label}.plist`),
|
|
64
|
-
installedPlistPath:
|
|
66
|
+
installedPlistPath: platformLaunchdInstalledPath(label, accountHome),
|
|
65
67
|
stdoutPath: join(serviceRoot, 'logs', 'stdout.log'),
|
|
66
68
|
stderrPath: join(serviceRoot, 'logs', 'stderr.log'),
|
|
67
69
|
authorityPath: join(serviceRoot, 'authority.json'),
|
|
@@ -101,20 +103,34 @@ function writePackageConnectorServiceAuthority(input: { release: PackageConnecto
|
|
|
101
103
|
atomicWrite(paths.authorityPath, `${JSON.stringify(authority, null, 2)}\n`);
|
|
102
104
|
}
|
|
103
105
|
|
|
104
|
-
export function packageConnectorEndpointStatusHealthy(status: number): boolean {
|
|
105
|
-
//
|
|
106
|
-
//
|
|
107
|
-
//
|
|
108
|
-
//
|
|
109
|
-
return status === 200 || status === 401;
|
|
106
|
+
export function packageConnectorEndpointStatusHealthy(status: number, authMode: PackageConnectorAuthMode = 'oauth'): boolean {
|
|
107
|
+
// A Secure Tunnel owns external authentication and therefore its loopback
|
|
108
|
+
// Connector must answer directly. Accepting an OAuth challenge in `none`
|
|
109
|
+
// mode hides a stale service unit that was rewritten by an older lifecycle
|
|
110
|
+
// path, then makes every tunneled request fail remotely with 401.
|
|
111
|
+
return status === 200 || (authMode === 'oauth' && status === 401);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export function packageConnectorReadinessEndpoint(endpoint: string): string {
|
|
115
|
+
const parsed = new URL(endpoint);
|
|
116
|
+
if (parsed.protocol !== 'http:' || parsed.hostname !== '127.0.0.1' || parsed.pathname !== '/mcp') {
|
|
117
|
+
throw new Error('FORGE_PACKAGE_CONNECTOR_ENDPOINT_INVALID');
|
|
118
|
+
}
|
|
119
|
+
parsed.pathname = '/transport-ready';
|
|
120
|
+
parsed.search = '';
|
|
121
|
+
parsed.hash = '';
|
|
122
|
+
return parsed.toString();
|
|
110
123
|
}
|
|
111
124
|
|
|
112
125
|
async function defaultConnectorEndpointProbe(endpoint: string): Promise<boolean> {
|
|
113
126
|
const controller = new AbortController();
|
|
114
127
|
const timeout = setTimeout(() => controller.abort(), 1_500);
|
|
115
128
|
try {
|
|
116
|
-
|
|
117
|
-
|
|
129
|
+
// GET /mcp is a protocol request, not a liveness request: in auth:none it
|
|
130
|
+
// correctly responds 400 without an MCP session. /transport-ready is the
|
|
131
|
+
// in-memory, transport-scoped readiness surface used by Recovery.
|
|
132
|
+
const response = await fetch(packageConnectorReadinessEndpoint(endpoint), { method: 'GET', redirect: 'manual', signal: controller.signal });
|
|
133
|
+
return response.status === 200;
|
|
118
134
|
} catch {
|
|
119
135
|
return false;
|
|
120
136
|
} finally {
|
|
@@ -127,6 +143,7 @@ export async function waitForPackageConnectorEndpointReady(
|
|
|
127
143
|
options: {
|
|
128
144
|
timeoutMs?: number;
|
|
129
145
|
pollIntervalMs?: number;
|
|
146
|
+
authMode?: PackageConnectorAuthMode;
|
|
130
147
|
probeEndpoint?: (endpoint: string) => Promise<boolean>;
|
|
131
148
|
wait?: (ms: number) => Promise<void>;
|
|
132
149
|
now?: () => number;
|
|
@@ -146,7 +163,17 @@ export async function waitForPackageConnectorEndpointReady(
|
|
|
146
163
|
return false;
|
|
147
164
|
}
|
|
148
165
|
|
|
149
|
-
export function
|
|
166
|
+
export function packageConnectorAuthMode(controllerHome: string): PackageConnectorAuthMode {
|
|
167
|
+
// OpenAI Secure MCP Tunnels authenticate the tunnel itself. The local
|
|
168
|
+
// Connector must not advertise a loopback OAuth issuer to ChatGPT in that
|
|
169
|
+
// topology. Keep OAuth as the default for existing HTTPS Connectors, and
|
|
170
|
+
// require an explicit per-instance opt-in before disabling it.
|
|
171
|
+
return loadMcpServiceLocalConfig(controllerHome)?.auth?.mode?.trim().toLowerCase() === 'none'
|
|
172
|
+
? 'none'
|
|
173
|
+
: 'oauth';
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export function packageConnectorLaunchSpec(input: { release: PackageConnectorReleaseBinding; controllerHome: string; endpoint: string; executable?: string }): { executable: string; args: string[]; environment: Record<string, string>; port: number; authMode: PackageConnectorAuthMode } {
|
|
150
177
|
const parsed = new URL(input.endpoint);
|
|
151
178
|
const port = Number(parsed.port);
|
|
152
179
|
if (parsed.protocol !== 'http:' || parsed.hostname !== '127.0.0.1' || parsed.pathname !== '/mcp' || !Number.isInteger(port) || port < 1 || port > 65_535) {
|
|
@@ -159,19 +186,29 @@ export function packageConnectorLaunchSpec(input: { release: PackageConnectorRel
|
|
|
159
186
|
const packageRoot = resolve(input.release.packageRoot);
|
|
160
187
|
const cliEntry = join(packageRoot, 'src', 'cli', 'index.ts');
|
|
161
188
|
const nodeLoader = join(packageRoot, 'src', 'runtime', 'shared', 'node-ts-loader.mjs');
|
|
162
|
-
const
|
|
189
|
+
const executableName = basename(executable);
|
|
190
|
+
const executableIsCurrentProcess = resolve(executable) === resolve(process.execPath);
|
|
191
|
+
const isBun = /(?:^|[/\\-])bun(?:$|[/\\]|\.exe$)/i.test(executableName)
|
|
192
|
+
|| (executableIsCurrentProcess && Boolean(process.versions.bun));
|
|
193
|
+
const instanceId = loadMcpServiceLocalConfig(input.controllerHome)?.identity?.forgeInstanceId?.trim();
|
|
194
|
+
const authMode = packageConnectorAuthMode(input.controllerHome);
|
|
163
195
|
const cliArgs = [
|
|
164
196
|
// The package snapshot is executable code, never an adopted repository.
|
|
165
197
|
// Supplying it as --repo makes the Gateway try to register a non-Git
|
|
166
198
|
// directory and fail before it can proxy the Canonical Runtime.
|
|
167
199
|
'mcp', 'serve', '--controller-home', resolve(input.controllerHome),
|
|
168
|
-
'--transport', 'http', '--host', '127.0.0.1', '--port', String(port), '--profile', 'controller', '--auth',
|
|
200
|
+
'--transport', 'http', '--host', '127.0.0.1', '--port', String(port), '--profile', 'controller', '--auth', authMode,
|
|
169
201
|
];
|
|
170
202
|
return {
|
|
171
203
|
executable,
|
|
172
204
|
args: isBun ? [cliEntry, ...cliArgs] : ['--loader', nodeLoader, cliEntry, ...cliArgs],
|
|
173
|
-
environment: {
|
|
205
|
+
environment: {
|
|
206
|
+
FORGE_CONTROLLER_HOME: resolve(input.controllerHome),
|
|
207
|
+
FORGE_CONTROLLER_LIFECYCLE_OWNER: '1',
|
|
208
|
+
...(instanceId ? { FORGE_MCP_INSTANCE_ID: instanceId } : {}),
|
|
209
|
+
},
|
|
174
210
|
port,
|
|
211
|
+
authMode,
|
|
175
212
|
};
|
|
176
213
|
}
|
|
177
214
|
|
|
@@ -182,10 +219,28 @@ export function renderPackageConnectorLaunchAgent(input: { paths: PackageConnect
|
|
|
182
219
|
return `<?xml version="1.0" encoding="UTF-8"?>\n<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n<plist version="1.0">\n<dict>\n <key>Label</key>\n <string>${xml(input.paths.label)}</string>\n <key>ProgramArguments</key>\n <array>\n${args.map((arg) => ` <string>${xml(arg)}</string>`).join('\n')}\n </array>\n <key>EnvironmentVariables</key>\n <dict>\n${environmentXml}\n </dict>\n <key>RunAtLoad</key>\n <true/>\n <key>KeepAlive</key>\n <dict><key>SuccessfulExit</key><false/></dict>\n <key>ThrottleInterval</key><integer>5</integer>\n <key>StandardOutPath</key><string>${xml(input.paths.stdoutPath)}</string>\n <key>StandardErrorPath</key><string>${xml(input.paths.stderrPath)}</string>\n</dict>\n</plist>\n`;
|
|
183
220
|
}
|
|
184
221
|
|
|
222
|
+
export function packageConnectorSystemdUserUnitInput(input: { launch: ReturnType<typeof packageConnectorLaunchSpec> }): SystemdUserUnitInput {
|
|
223
|
+
const description = input.launch.authMode === 'oauth'
|
|
224
|
+
? 'Forge ChatGPT OAuth Gateway'
|
|
225
|
+
: 'Forge ChatGPT Secure Tunnel Connector';
|
|
226
|
+
return {
|
|
227
|
+
description,
|
|
228
|
+
executable: input.launch.executable,
|
|
229
|
+
args: input.launch.args,
|
|
230
|
+
environment: input.launch.environment,
|
|
231
|
+
restart: 'on-failure',
|
|
232
|
+
restartSec: 5,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
|
|
185
236
|
export function renderPackageConnectorSystemdUserUnit(input: { launch: ReturnType<typeof packageConnectorLaunchSpec> }): string {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
237
|
+
return createPlatformServiceManagerHost({ platform: 'linux', systemdUserAvailable: true })
|
|
238
|
+
.renderSystemdUserUnit(packageConnectorSystemdUserUnitInput(input));
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/** A rewritten user unit needs an explicit restart; enable --now preserves an already-running old process. */
|
|
242
|
+
export function packageConnectorSystemdInstallCommands(unitName: string): string[][] {
|
|
243
|
+
return [['--user', 'daemon-reload'], ['--user', 'enable', unitName], ['--user', 'restart', unitName]];
|
|
189
244
|
}
|
|
190
245
|
|
|
191
246
|
export function packageConnectorServiceMatchesRelease(input: {
|
|
@@ -228,35 +283,31 @@ export function packageConnectorServiceMatchesRelease(input: {
|
|
|
228
283
|
}
|
|
229
284
|
}
|
|
230
285
|
|
|
231
|
-
function installSystemd(paths: PackageConnectorServicePaths, launch: ReturnType<typeof packageConnectorLaunchSpec>, env: NodeJS.ProcessEnv): string {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
}
|
|
239
|
-
return unitPath;
|
|
286
|
+
function installSystemd(paths: PackageConnectorServicePaths, launch: ReturnType<typeof packageConnectorLaunchSpec>, env: NodeJS.ProcessEnv, host: PlatformServiceManagerHost): string {
|
|
287
|
+
return host.installSystemdUserUnit({
|
|
288
|
+
unitName: `${paths.label}.service`,
|
|
289
|
+
unit: packageConnectorSystemdUserUnitInput({ launch }),
|
|
290
|
+
env,
|
|
291
|
+
errorPrefix: 'FORGE_PACKAGE_CONNECTOR_SYSTEMD_INSTALL_FAILED',
|
|
292
|
+
});
|
|
240
293
|
}
|
|
241
294
|
|
|
242
|
-
function startPortable(paths: PackageConnectorServicePaths, launch: ReturnType<typeof packageConnectorLaunchSpec>, env: NodeJS.ProcessEnv): number {
|
|
243
|
-
mkdirSync(join(paths.serviceRoot, 'logs'), { recursive: true, mode: 0o700 });
|
|
244
|
-
const stdout = openSync(paths.stdoutPath, 'a', 0o600), stderr = openSync(paths.stderrPath, 'a', 0o600);
|
|
295
|
+
function startPortable(paths: PackageConnectorServicePaths, launch: ReturnType<typeof packageConnectorLaunchSpec>, env: NodeJS.ProcessEnv, host: PlatformServiceManagerHost): number {
|
|
245
296
|
// A connector is not the Canonical Runtime writer. Never let a transient
|
|
246
|
-
// installer/worker write claim escape into this long-lived process
|
|
247
|
-
// would become stale as soon as its parent exits. Keep only the explicit
|
|
248
|
-
// Controller Home and lifecycle-role marker from launch.environment.
|
|
297
|
+
// installer/worker write claim escape into this long-lived process.
|
|
249
298
|
const childEnv = { ...env };
|
|
250
299
|
for (const key of [
|
|
251
300
|
'FORGE_RUNTIME_INSTANCE_ID', 'FORGE_RUNTIME_OWNER_PID', 'FORGE_RELEASE_AUTHORITY_REVISION',
|
|
252
301
|
'FORGE_RELEASE_FENCING_TOKEN', 'FORGE_RELEASE_ID', 'FORGE_ARTIFACT_IDENTITY', 'FORGE_WORKER_PROTOCOL_VERSION',
|
|
253
302
|
]) delete childEnv[key];
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
303
|
+
return host.startDetached({
|
|
304
|
+
executable: launch.executable,
|
|
305
|
+
args: launch.args,
|
|
306
|
+
environment: { ...childEnv, ...launch.environment },
|
|
307
|
+
stdoutPath: paths.stdoutPath,
|
|
308
|
+
stderrPath: paths.stderrPath,
|
|
309
|
+
errorCode: 'FORGE_PACKAGE_CONNECTOR_START_FAILED',
|
|
310
|
+
});
|
|
260
311
|
}
|
|
261
312
|
|
|
262
313
|
export async function installPackageConnectorService(input: { release: PackageConnectorReleaseBinding; controllerHome: string; endpoint: string; executable?: string; platform?: NodeJS.Platform; env?: NodeJS.ProcessEnv; forcePortable?: boolean; probeEndpoint?: (endpoint: string) => Promise<boolean> }): Promise<PackageConnectorServiceResult> {
|
|
@@ -269,33 +320,32 @@ export async function installPackageConnectorService(input: { release: PackageCo
|
|
|
269
320
|
executable: input.executable,
|
|
270
321
|
});
|
|
271
322
|
const platform = input.platform ?? process.platform, env = input.env ?? process.env;
|
|
272
|
-
|
|
273
|
-
|
|
323
|
+
const serviceHost = createPlatformServiceManagerHost({ platform, env, forcePortable: input.forcePortable });
|
|
324
|
+
const serviceManager = serviceHost.selection;
|
|
325
|
+
if (serviceManager.kind === 'launchd') {
|
|
326
|
+
await serviceHost.retireConflictingLaunchd({
|
|
274
327
|
accountHome: env.HOME,
|
|
275
328
|
desiredLabel: paths.label,
|
|
276
329
|
labelPrefix: 'com.moretea.forge.mcp-gateway',
|
|
277
330
|
port: launch.port,
|
|
278
|
-
requiredArguments: ['mcp', 'serve', '--auth',
|
|
331
|
+
requiredArguments: ['mcp', 'serve', '--auth', launch.authMode],
|
|
279
332
|
});
|
|
280
333
|
atomicWrite(paths.sourcePlistPath, renderPackageConnectorLaunchAgent({ paths, launch }), 0o600);
|
|
281
|
-
|
|
282
|
-
const result = await
|
|
334
|
+
serviceHost.installLaunchd(paths.sourcePlistPath, paths.label);
|
|
335
|
+
const result = await serviceHost.bootstrapLaunchd({ label: paths.label, plistPath: paths.installedPlistPath });
|
|
283
336
|
if (!result.ok) throw new Error(`FORGE_PACKAGE_CONNECTOR_LAUNCHD_INSTALL_FAILED: ${result.diagnostics.join('; ')}`);
|
|
284
|
-
const endpointReady = await waitForPackageConnectorEndpointReady(input.endpoint, { probeEndpoint: input.probeEndpoint });
|
|
337
|
+
const endpointReady = await waitForPackageConnectorEndpointReady(input.endpoint, { authMode: launch.authMode, probeEndpoint: input.probeEndpoint });
|
|
285
338
|
if (!endpointReady) throw new Error(`FORGE_PACKAGE_CONNECTOR_ENDPOINT_NOT_READY: ${input.endpoint}`);
|
|
286
339
|
const installed = { endpoint: input.endpoint, mode: 'launchd' as const, persistent: true, servicePath: paths.installedPlistPath, releaseId: input.release.releaseId, releaseRoot: input.release.releaseRoot };
|
|
287
340
|
writePackageConnectorServiceAuthority({ release: input.release, controllerHome: input.controllerHome, result: installed });
|
|
288
341
|
return installed;
|
|
289
342
|
}
|
|
290
|
-
if (
|
|
291
|
-
const
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
writePackageConnectorServiceAuthority({ release: input.release, controllerHome: input.controllerHome, result: installed });
|
|
295
|
-
return installed;
|
|
296
|
-
}
|
|
343
|
+
if (serviceManager.kind === 'systemd-user') {
|
|
344
|
+
const installed = { endpoint: input.endpoint, mode: 'systemd-user' as const, persistent: true, servicePath: installSystemd(paths, launch, env, serviceHost), releaseId: input.release.releaseId, releaseRoot: input.release.releaseRoot };
|
|
345
|
+
writePackageConnectorServiceAuthority({ release: input.release, controllerHome: input.controllerHome, result: installed });
|
|
346
|
+
return installed;
|
|
297
347
|
}
|
|
298
|
-
const portable = { endpoint: input.endpoint, mode: 'portable' as const, persistent: false, pid: startPortable(paths, launch, env), releaseId: input.release.releaseId, releaseRoot: input.release.releaseRoot };
|
|
348
|
+
const portable = { endpoint: input.endpoint, mode: 'portable' as const, persistent: false, pid: startPortable(paths, launch, env, serviceHost), releaseId: input.release.releaseId, releaseRoot: input.release.releaseRoot };
|
|
299
349
|
writePackageConnectorServiceAuthority({ release: input.release, controllerHome: input.controllerHome, result: portable });
|
|
300
350
|
return portable;
|
|
301
351
|
}
|
|
@@ -312,15 +362,17 @@ export async function ensurePackageConnectorService(input: {
|
|
|
312
362
|
probeEndpoint?: (endpoint: string) => Promise<boolean>;
|
|
313
363
|
}): Promise<PackageConnectorServiceResult> {
|
|
314
364
|
const platform = input.platform ?? process.platform;
|
|
365
|
+
const authMode = packageConnectorAuthMode(input.controllerHome);
|
|
315
366
|
if (!input.refresh && !input.forcePortable && platform === 'darwin') {
|
|
316
367
|
const paths = packageConnectorServicePaths(input.controllerHome, input.env?.HOME);
|
|
317
368
|
const port = Number(new URL(input.endpoint).port);
|
|
318
|
-
|
|
369
|
+
const serviceHost = createPlatformServiceManagerHost({ platform, env: input.env });
|
|
370
|
+
await serviceHost.retireConflictingLaunchd({
|
|
319
371
|
accountHome: input.env?.HOME,
|
|
320
372
|
desiredLabel: paths.label,
|
|
321
373
|
labelPrefix: 'com.moretea.forge.mcp-gateway',
|
|
322
374
|
port,
|
|
323
|
-
requiredArguments: ['mcp', 'serve', '--auth',
|
|
375
|
+
requiredArguments: ['mcp', 'serve', '--auth', authMode],
|
|
324
376
|
});
|
|
325
377
|
}
|
|
326
378
|
if (!input.refresh && !input.forcePortable) {
|
|
@@ -6,7 +6,10 @@ import { CONTROL_PLANE_SCHEMA_VERSION } from '../control-plane/persistence/sqlit
|
|
|
6
6
|
import { packageRuntimeSourceRoot } from '../control-plane/runtime-generation';
|
|
7
7
|
import { FORGE_VERSION } from '../../version';
|
|
8
8
|
import { publishRuntimeRelease, type RuntimeReleaseAuthority } from './release-store';
|
|
9
|
+
import { assertRuntimeReleaseExecutionSurface } from './release-manifest';
|
|
10
|
+
import { assertRuntimeReleaseExecutionCanaries } from './release-execution-canary';
|
|
9
11
|
import type { RuntimeReleaseManifest } from './types';
|
|
12
|
+
import { assertStorageHeadroom } from '../shared/storage-capacity';
|
|
10
13
|
|
|
11
14
|
export interface PackageRuntimeFileRecord {
|
|
12
15
|
path: string;
|
|
@@ -28,12 +31,13 @@ export interface PackageRuntimeRelease {
|
|
|
28
31
|
authority: RuntimeReleaseAuthority;
|
|
29
32
|
}
|
|
30
33
|
|
|
31
|
-
// A package Runtime is an immutable, independently launchable release.
|
|
32
|
-
// TypeScript entrypoints import
|
|
33
|
-
// only
|
|
34
|
-
// after the installed package moves or disappears.
|
|
35
|
-
const PACKAGE_RUNTIME_ROOTS = ['src', 'bin', 'assets', 'scripts', 'node_modules'] as const;
|
|
34
|
+
// A package Runtime is an immutable, independently launchable release. Its
|
|
35
|
+
// TypeScript entrypoints import both `src/` and the top-level modular-monolith
|
|
36
|
+
// roots at runtime, so retaining only `src/` creates a release that passes
|
|
37
|
+
// staging but cannot start after the installed package moves or disappears.
|
|
38
|
+
const PACKAGE_RUNTIME_ROOTS = ['src', 'adapters', 'packages', 'bin', 'assets', 'scripts', 'node_modules'] as const;
|
|
36
39
|
const PACKAGE_RUNTIME_FILES = ['package.json'] as const;
|
|
40
|
+
const PACKAGE_RUNTIME_STAGING_RESERVE_BYTES = 256 * 1024 * 1024;
|
|
37
41
|
|
|
38
42
|
function sha256(value: Buffer | string): string {
|
|
39
43
|
return createHash('sha256').update(value).digest('hex');
|
|
@@ -138,25 +142,32 @@ function packageVersion(root: string): string {
|
|
|
138
142
|
}
|
|
139
143
|
}
|
|
140
144
|
|
|
141
|
-
function launcherSource(input: {
|
|
145
|
+
function launcherSource(input: {
|
|
146
|
+
indexSha256: string;
|
|
147
|
+
entryRelativePath?: string;
|
|
148
|
+
managerSignalsProcessGroup?: boolean;
|
|
149
|
+
}): string {
|
|
150
|
+
const entryRelativePath = input.entryRelativePath ?? 'src/runtime/root/entry.ts';
|
|
142
151
|
return `#!${process.execPath}\n`
|
|
143
152
|
+ `import { createHash } from 'node:crypto';\n`
|
|
144
153
|
+ `import { existsSync, readFileSync } from 'node:fs';\n`
|
|
145
|
-
+ `import { join } from 'node:path';\n`
|
|
154
|
+
+ `import { dirname, join } from 'node:path';\n`
|
|
155
|
+
+ `import { fileURLToPath } from 'node:url';\n`
|
|
146
156
|
+ `import { spawn } from 'node:child_process';\n`
|
|
147
|
-
+ `const
|
|
148
|
-
+ `const
|
|
157
|
+
+ `const releaseRoot=dirname(fileURLToPath(import.meta.url));\n`
|
|
158
|
+
+ `const packageRoot=join(releaseRoot,'package');\n`
|
|
159
|
+
+ `const indexPath=join(releaseRoot,'package-files.json');\n`
|
|
149
160
|
+ `const expectedIndex=${JSON.stringify(input.indexSha256)};\n`
|
|
150
161
|
+ `const digest=(v)=>createHash('sha256').update(v).digest('hex');\n`
|
|
151
162
|
+ `let raw; try { raw=readFileSync(indexPath); } catch (error) { console.error('FORGE_PACKAGE_RUNTIME_INDEX_MISSING: '+error.message); process.exit(78); }\n`
|
|
152
163
|
+ `if(digest(raw)!==expectedIndex){console.error('FORGE_PACKAGE_RUNTIME_INDEX_CHANGED');process.exit(78);}\n`
|
|
153
164
|
+ `let records; try { records=JSON.parse(raw.toString('utf8')).files; } catch { console.error('FORGE_PACKAGE_RUNTIME_INDEX_INVALID'); process.exit(78); }\n`
|
|
154
165
|
+ `for(const record of records){const path=join(packageRoot,record.path);if(!existsSync(path)||digest(readFileSync(path))!==record.sha256){console.error('FORGE_PACKAGE_RUNTIME_SOURCE_CHANGED: '+record.path);process.exit(78);}}\n`
|
|
155
|
-
+ `const entry=join(packageRoot
|
|
166
|
+
+ `const entry=join(packageRoot,...${JSON.stringify(entryRelativePath.split('/'))});\n`
|
|
156
167
|
+ `const loader=join(packageRoot,'src','runtime','shared','node-ts-loader.mjs');\n`
|
|
157
168
|
+ `const args=process.versions?.bun?[entry,...process.argv.slice(2)]:['--loader',loader,entry,...process.argv.slice(2)];\n`
|
|
158
169
|
+ `const child=spawn(process.execPath,args,{stdio:'inherit',env:process.env});\n`
|
|
159
|
-
+ `const managerSignalsProcessGroup
|
|
170
|
+
+ `const managerSignalsProcessGroup=${input.managerSignalsProcessGroup ? "process.platform==='linux'&&Boolean(process.env.INVOCATION_ID)" : "false"};\n`
|
|
160
171
|
+ `for(const signal of ['SIGINT','SIGTERM','SIGHUP']){try{process.on(signal,()=>{if(!managerSignalsProcessGroup)child.kill(signal);});}catch{}}\n`
|
|
161
172
|
+ `child.on('error',(error)=>{console.error('FORGE_PACKAGE_RUNTIME_LAUNCH_FAILED: '+error.message);process.exit(1);});\n`
|
|
162
173
|
+ `child.on('exit',(code)=>process.exit(code??1));\n`;
|
|
@@ -170,21 +181,28 @@ function assertImmutablePackageRuntimeRelease(input: {
|
|
|
170
181
|
indexJson: string;
|
|
171
182
|
entrypointPath: string;
|
|
172
183
|
launcher: string;
|
|
184
|
+
processRunnerPath: string;
|
|
185
|
+
processRunnerLauncher: string;
|
|
186
|
+
checkRunnerPath: string;
|
|
187
|
+
checkRunnerLauncher: string;
|
|
173
188
|
manifestPath: string;
|
|
174
189
|
expectedManifest: Omit<RuntimeReleaseManifest, 'createdAt'>;
|
|
175
190
|
}): void {
|
|
176
191
|
const rootStat = lstatSync(input.releaseRoot);
|
|
177
192
|
if (!rootStat.isDirectory() || rootStat.isSymbolicLink()) throw new Error('PACKAGE_RUNTIME_RELEASE_IMMUTABILITY_VIOLATION: release root is not a regular directory');
|
|
178
193
|
assertPackageRuntimeSnapshot(input.packageRoot, input.records);
|
|
179
|
-
const assertFile = (path: string, expected: string, label: string) => {
|
|
194
|
+
const assertFile = (path: string, expected: string, label: string, executable = false) => {
|
|
180
195
|
if (!existsSync(path)) throw new Error(`PACKAGE_RUNTIME_RELEASE_IMMUTABILITY_VIOLATION: ${label} is missing`);
|
|
181
196
|
const stat = lstatSync(path);
|
|
182
|
-
if (!stat.isFile() || stat.isSymbolicLink() || readFileSync(path, 'utf8') !== expected
|
|
197
|
+
if (!stat.isFile() || stat.isSymbolicLink() || readFileSync(path, 'utf8') !== expected
|
|
198
|
+
|| (executable && process.platform !== 'win32' && (stat.mode & 0o111) === 0)) {
|
|
183
199
|
throw new Error(`PACKAGE_RUNTIME_RELEASE_IMMUTABILITY_VIOLATION: ${label} changed`);
|
|
184
200
|
}
|
|
185
201
|
};
|
|
186
202
|
assertFile(input.indexPath, input.indexJson, 'package file index');
|
|
187
|
-
assertFile(input.entrypointPath, input.launcher, 'runtime launcher');
|
|
203
|
+
assertFile(input.entrypointPath, input.launcher, 'runtime launcher', true);
|
|
204
|
+
assertFile(input.processRunnerPath, input.processRunnerLauncher, 'process runner launcher', true);
|
|
205
|
+
assertFile(input.checkRunnerPath, input.checkRunnerLauncher, 'check runner launcher', true);
|
|
188
206
|
if (!existsSync(input.manifestPath)) throw new Error('PACKAGE_RUNTIME_RELEASE_IMMUTABILITY_VIOLATION: manifest is missing');
|
|
189
207
|
const manifestStat = lstatSync(input.manifestPath);
|
|
190
208
|
if (!manifestStat.isFile() || manifestStat.isSymbolicLink()) throw new Error('PACKAGE_RUNTIME_RELEASE_IMMUTABILITY_VIOLATION: manifest is not a regular file');
|
|
@@ -199,6 +217,11 @@ function assertImmutablePackageRuntimeRelease(input: {
|
|
|
199
217
|
&& manifest.releaseId === expected.releaseId
|
|
200
218
|
&& manifest.artifactIdentity === expected.artifactIdentity
|
|
201
219
|
&& manifest.entrypoint === expected.entrypoint
|
|
220
|
+
&& manifest.executionMode === expected.executionMode
|
|
221
|
+
&& manifest.processRunnerEntrypoint === expected.processRunnerEntrypoint
|
|
222
|
+
&& manifest.processRunnerArtifactIdentity === expected.processRunnerArtifactIdentity
|
|
223
|
+
&& manifest.checkRunnerEntrypoint === expected.checkRunnerEntrypoint
|
|
224
|
+
&& manifest.checkRunnerArtifactIdentity === expected.checkRunnerArtifactIdentity
|
|
202
225
|
&& JSON.stringify(manifest.arguments ?? []) === JSON.stringify(expected.arguments ?? [])
|
|
203
226
|
&& manifest.configurationSchemaVersion === expected.configurationSchemaVersion
|
|
204
227
|
&& resolve(manifest.controllerHome) === resolve(expected.controllerHome)
|
|
@@ -209,6 +232,7 @@ function assertImmutablePackageRuntimeRelease(input: {
|
|
|
209
232
|
&& typeof manifest.createdAt === 'string'
|
|
210
233
|
&& Number.isFinite(Date.parse(manifest.createdAt));
|
|
211
234
|
if (!compatible) throw new Error('PACKAGE_RUNTIME_RELEASE_IMMUTABILITY_VIOLATION: manifest identity changed');
|
|
235
|
+
assertRuntimeReleaseExecutionSurface(input.manifestPath, expected.controllerHome);
|
|
212
236
|
}
|
|
213
237
|
|
|
214
238
|
export function materializePackageRuntimeRelease(input: {
|
|
@@ -222,7 +246,7 @@ export function materializePackageRuntimeRelease(input: {
|
|
|
222
246
|
const records = packageRuntimeFileIndex(sourcePackageRoot);
|
|
223
247
|
const fingerprint = packageRuntimeFingerprint(records);
|
|
224
248
|
const safeVersion = version.replace(/[^A-Za-z0-9._-]+/g, '-');
|
|
225
|
-
const launcherBinding = sha256(`${resolve(process.execPath)}\0package-launcher-
|
|
249
|
+
const launcherBinding = sha256(`${resolve(process.execPath)}\0package-launcher-v5`);
|
|
226
250
|
const releaseId = `package-${safeVersion}-${fingerprint.slice(0, 16)}-${launcherBinding.slice(0, 12)}`;
|
|
227
251
|
const releasesRoot = join(controllerHome, 'runtime', 'releases');
|
|
228
252
|
const releaseRoot = join(releasesRoot, releaseId);
|
|
@@ -230,13 +254,32 @@ export function materializePackageRuntimeRelease(input: {
|
|
|
230
254
|
const indexPath = join(releaseRoot, 'package-files.json');
|
|
231
255
|
const indexJson = `${JSON.stringify({ schemaVersion: 1, package: '@moretea-labs/forge', version, fingerprint, files: records }, null, 2)}\n`;
|
|
232
256
|
const entrypointPath = join(releaseRoot, 'forge-runtime');
|
|
233
|
-
const
|
|
257
|
+
const indexSha256 = sha256(Buffer.from(indexJson));
|
|
258
|
+
const launcher = launcherSource({ indexSha256, managerSignalsProcessGroup: true });
|
|
234
259
|
const artifactIdentity = `sha256:${sha256(Buffer.from(launcher))}`;
|
|
260
|
+
const processRunnerEntrypoint = 'process-runner.js' as const;
|
|
261
|
+
const processRunnerPath = join(releaseRoot, processRunnerEntrypoint);
|
|
262
|
+
const processRunnerLauncher = launcherSource({
|
|
263
|
+
indexSha256,
|
|
264
|
+
entryRelativePath: 'src/runtime/execution/process-runtime/process-runner-entry.ts',
|
|
265
|
+
});
|
|
266
|
+
const processRunnerArtifactIdentity = `sha256:${sha256(Buffer.from(processRunnerLauncher))}`;
|
|
267
|
+
const checkRunnerEntrypoint = 'forge-check-runner' as const;
|
|
268
|
+
const checkRunnerPath = join(releaseRoot, checkRunnerEntrypoint);
|
|
269
|
+
const checkRunnerLauncher = launcherSource({
|
|
270
|
+
indexSha256,
|
|
271
|
+
entryRelativePath: 'src/runtime/execution/process-runtime/check-runner-sidecar.ts',
|
|
272
|
+
});
|
|
273
|
+
const checkRunnerArtifactIdentity = `sha256:${sha256(Buffer.from(checkRunnerLauncher))}`;
|
|
235
274
|
const expectedManifest: Omit<RuntimeReleaseManifest, 'createdAt'> = {
|
|
236
275
|
schemaVersion: 1,
|
|
237
276
|
releaseId,
|
|
238
277
|
artifactIdentity,
|
|
239
278
|
entrypoint: 'forge-runtime',
|
|
279
|
+
processRunnerEntrypoint,
|
|
280
|
+
processRunnerArtifactIdentity,
|
|
281
|
+
checkRunnerEntrypoint,
|
|
282
|
+
checkRunnerArtifactIdentity,
|
|
240
283
|
arguments: [],
|
|
241
284
|
configurationSchemaVersion: 1,
|
|
242
285
|
controllerHome,
|
|
@@ -246,13 +289,26 @@ export function materializePackageRuntimeRelease(input: {
|
|
|
246
289
|
cleanWorkspace: true,
|
|
247
290
|
};
|
|
248
291
|
const manifestPath = join(releaseRoot, 'manifest.json');
|
|
292
|
+
const stagedBytes = records.reduce((total, record) => total + record.bytes, 0)
|
|
293
|
+
+ Buffer.byteLength(indexJson)
|
|
294
|
+
+ Buffer.byteLength(launcher)
|
|
295
|
+
+ Buffer.byteLength(processRunnerLauncher)
|
|
296
|
+
+ Buffer.byteLength(checkRunnerLauncher)
|
|
297
|
+
+ Buffer.byteLength(JSON.stringify({ ...expectedManifest, createdAt: new Date(0).toISOString() }));
|
|
298
|
+
let executionCanariesValidated = false;
|
|
249
299
|
const assertExisting = () => assertImmutablePackageRuntimeRelease({
|
|
250
|
-
releaseRoot, packageRoot, records, indexPath, indexJson, entrypointPath, launcher,
|
|
300
|
+
releaseRoot, packageRoot, records, indexPath, indexJson, entrypointPath, launcher,
|
|
301
|
+
processRunnerPath, processRunnerLauncher, checkRunnerPath, checkRunnerLauncher, manifestPath, expectedManifest,
|
|
251
302
|
});
|
|
252
303
|
|
|
253
304
|
if (existsSync(releaseRoot)) {
|
|
254
305
|
assertExisting();
|
|
255
306
|
} else {
|
|
307
|
+
assertStorageHeadroom(controllerHome, {
|
|
308
|
+
operation: 'materialize_package_runtime_release',
|
|
309
|
+
requiredBytes: stagedBytes,
|
|
310
|
+
reserveBytes: PACKAGE_RUNTIME_STAGING_RESERVE_BYTES,
|
|
311
|
+
});
|
|
256
312
|
mkdirSync(releasesRoot, { recursive: true, mode: 0o700 });
|
|
257
313
|
const stagingRoot = join(releasesRoot, `.staging-${releaseId}-${process.pid}-${randomUUID().slice(0, 8)}`);
|
|
258
314
|
try {
|
|
@@ -261,9 +317,19 @@ export function materializePackageRuntimeRelease(input: {
|
|
|
261
317
|
atomicWrite(join(stagingRoot, 'package-files.json'), indexJson);
|
|
262
318
|
atomicWrite(join(stagingRoot, 'forge-runtime'), launcher, 0o700);
|
|
263
319
|
chmodSync(join(stagingRoot, 'forge-runtime'), 0o700);
|
|
320
|
+
atomicWrite(join(stagingRoot, processRunnerEntrypoint), processRunnerLauncher, 0o700);
|
|
321
|
+
chmodSync(join(stagingRoot, processRunnerEntrypoint), 0o700);
|
|
322
|
+
atomicWrite(join(stagingRoot, checkRunnerEntrypoint), checkRunnerLauncher, 0o700);
|
|
323
|
+
chmodSync(join(stagingRoot, checkRunnerEntrypoint), 0o700);
|
|
264
324
|
const manifest: RuntimeReleaseManifest = { ...expectedManifest, createdAt: new Date().toISOString() };
|
|
265
|
-
|
|
325
|
+
const stagingManifestPath = join(stagingRoot, 'manifest.json');
|
|
326
|
+
atomicWrite(stagingManifestPath, `${JSON.stringify(manifest, null, 2)}\n`);
|
|
327
|
+
// A failed execution surface is still a staging failure. Do not promote an
|
|
328
|
+
// immutable release directory until both manifest-owned runners execute
|
|
329
|
+
// their bounded no-op canary successfully.
|
|
330
|
+
assertRuntimeReleaseExecutionCanaries(stagingManifestPath, controllerHome);
|
|
266
331
|
renameSync(stagingRoot, releaseRoot);
|
|
332
|
+
executionCanariesValidated = true;
|
|
267
333
|
} catch (error) {
|
|
268
334
|
rmSync(stagingRoot, { recursive: true, force: true });
|
|
269
335
|
if (!existsSync(releaseRoot)) throw error;
|
|
@@ -271,6 +337,7 @@ export function materializePackageRuntimeRelease(input: {
|
|
|
271
337
|
}
|
|
272
338
|
}
|
|
273
339
|
|
|
340
|
+
if (!executionCanariesValidated) assertRuntimeReleaseExecutionCanaries(manifestPath, controllerHome);
|
|
274
341
|
const authority = publishRuntimeRelease(controllerHome, manifestPath, input.operationId ?? `package-runtime-${FORGE_VERSION}-${Date.now()}`);
|
|
275
342
|
return {
|
|
276
343
|
releaseId,
|