@moretea-labs/forge 1.7.1 → 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 +39 -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 -1585
- 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 +417 -100
- 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 +267 -16
- 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 -6651
- 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 +86 -18
- package/src/runtime/root/package-runtime-service.ts +63 -86
- 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,33 @@ 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
|
-
+ `
|
|
170
|
+
+ `const managerSignalsProcessGroup=${input.managerSignalsProcessGroup ? "process.platform==='linux'&&Boolean(process.env.INVOCATION_ID)" : "false"};\n`
|
|
171
|
+
+ `for(const signal of ['SIGINT','SIGTERM','SIGHUP']){try{process.on(signal,()=>{if(!managerSignalsProcessGroup)child.kill(signal);});}catch{}}\n`
|
|
160
172
|
+ `child.on('error',(error)=>{console.error('FORGE_PACKAGE_RUNTIME_LAUNCH_FAILED: '+error.message);process.exit(1);});\n`
|
|
161
173
|
+ `child.on('exit',(code)=>process.exit(code??1));\n`;
|
|
162
174
|
}
|
|
@@ -169,21 +181,28 @@ function assertImmutablePackageRuntimeRelease(input: {
|
|
|
169
181
|
indexJson: string;
|
|
170
182
|
entrypointPath: string;
|
|
171
183
|
launcher: string;
|
|
184
|
+
processRunnerPath: string;
|
|
185
|
+
processRunnerLauncher: string;
|
|
186
|
+
checkRunnerPath: string;
|
|
187
|
+
checkRunnerLauncher: string;
|
|
172
188
|
manifestPath: string;
|
|
173
189
|
expectedManifest: Omit<RuntimeReleaseManifest, 'createdAt'>;
|
|
174
190
|
}): void {
|
|
175
191
|
const rootStat = lstatSync(input.releaseRoot);
|
|
176
192
|
if (!rootStat.isDirectory() || rootStat.isSymbolicLink()) throw new Error('PACKAGE_RUNTIME_RELEASE_IMMUTABILITY_VIOLATION: release root is not a regular directory');
|
|
177
193
|
assertPackageRuntimeSnapshot(input.packageRoot, input.records);
|
|
178
|
-
const assertFile = (path: string, expected: string, label: string) => {
|
|
194
|
+
const assertFile = (path: string, expected: string, label: string, executable = false) => {
|
|
179
195
|
if (!existsSync(path)) throw new Error(`PACKAGE_RUNTIME_RELEASE_IMMUTABILITY_VIOLATION: ${label} is missing`);
|
|
180
196
|
const stat = lstatSync(path);
|
|
181
|
-
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)) {
|
|
182
199
|
throw new Error(`PACKAGE_RUNTIME_RELEASE_IMMUTABILITY_VIOLATION: ${label} changed`);
|
|
183
200
|
}
|
|
184
201
|
};
|
|
185
202
|
assertFile(input.indexPath, input.indexJson, 'package file index');
|
|
186
|
-
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);
|
|
187
206
|
if (!existsSync(input.manifestPath)) throw new Error('PACKAGE_RUNTIME_RELEASE_IMMUTABILITY_VIOLATION: manifest is missing');
|
|
188
207
|
const manifestStat = lstatSync(input.manifestPath);
|
|
189
208
|
if (!manifestStat.isFile() || manifestStat.isSymbolicLink()) throw new Error('PACKAGE_RUNTIME_RELEASE_IMMUTABILITY_VIOLATION: manifest is not a regular file');
|
|
@@ -198,6 +217,11 @@ function assertImmutablePackageRuntimeRelease(input: {
|
|
|
198
217
|
&& manifest.releaseId === expected.releaseId
|
|
199
218
|
&& manifest.artifactIdentity === expected.artifactIdentity
|
|
200
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
|
|
201
225
|
&& JSON.stringify(manifest.arguments ?? []) === JSON.stringify(expected.arguments ?? [])
|
|
202
226
|
&& manifest.configurationSchemaVersion === expected.configurationSchemaVersion
|
|
203
227
|
&& resolve(manifest.controllerHome) === resolve(expected.controllerHome)
|
|
@@ -208,6 +232,7 @@ function assertImmutablePackageRuntimeRelease(input: {
|
|
|
208
232
|
&& typeof manifest.createdAt === 'string'
|
|
209
233
|
&& Number.isFinite(Date.parse(manifest.createdAt));
|
|
210
234
|
if (!compatible) throw new Error('PACKAGE_RUNTIME_RELEASE_IMMUTABILITY_VIOLATION: manifest identity changed');
|
|
235
|
+
assertRuntimeReleaseExecutionSurface(input.manifestPath, expected.controllerHome);
|
|
211
236
|
}
|
|
212
237
|
|
|
213
238
|
export function materializePackageRuntimeRelease(input: {
|
|
@@ -221,7 +246,7 @@ export function materializePackageRuntimeRelease(input: {
|
|
|
221
246
|
const records = packageRuntimeFileIndex(sourcePackageRoot);
|
|
222
247
|
const fingerprint = packageRuntimeFingerprint(records);
|
|
223
248
|
const safeVersion = version.replace(/[^A-Za-z0-9._-]+/g, '-');
|
|
224
|
-
const launcherBinding = sha256(`${resolve(process.execPath)}\0package-launcher-
|
|
249
|
+
const launcherBinding = sha256(`${resolve(process.execPath)}\0package-launcher-v5`);
|
|
225
250
|
const releaseId = `package-${safeVersion}-${fingerprint.slice(0, 16)}-${launcherBinding.slice(0, 12)}`;
|
|
226
251
|
const releasesRoot = join(controllerHome, 'runtime', 'releases');
|
|
227
252
|
const releaseRoot = join(releasesRoot, releaseId);
|
|
@@ -229,13 +254,32 @@ export function materializePackageRuntimeRelease(input: {
|
|
|
229
254
|
const indexPath = join(releaseRoot, 'package-files.json');
|
|
230
255
|
const indexJson = `${JSON.stringify({ schemaVersion: 1, package: '@moretea-labs/forge', version, fingerprint, files: records }, null, 2)}\n`;
|
|
231
256
|
const entrypointPath = join(releaseRoot, 'forge-runtime');
|
|
232
|
-
const
|
|
257
|
+
const indexSha256 = sha256(Buffer.from(indexJson));
|
|
258
|
+
const launcher = launcherSource({ indexSha256, managerSignalsProcessGroup: true });
|
|
233
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))}`;
|
|
234
274
|
const expectedManifest: Omit<RuntimeReleaseManifest, 'createdAt'> = {
|
|
235
275
|
schemaVersion: 1,
|
|
236
276
|
releaseId,
|
|
237
277
|
artifactIdentity,
|
|
238
278
|
entrypoint: 'forge-runtime',
|
|
279
|
+
processRunnerEntrypoint,
|
|
280
|
+
processRunnerArtifactIdentity,
|
|
281
|
+
checkRunnerEntrypoint,
|
|
282
|
+
checkRunnerArtifactIdentity,
|
|
239
283
|
arguments: [],
|
|
240
284
|
configurationSchemaVersion: 1,
|
|
241
285
|
controllerHome,
|
|
@@ -245,13 +289,26 @@ export function materializePackageRuntimeRelease(input: {
|
|
|
245
289
|
cleanWorkspace: true,
|
|
246
290
|
};
|
|
247
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;
|
|
248
299
|
const assertExisting = () => assertImmutablePackageRuntimeRelease({
|
|
249
|
-
releaseRoot, packageRoot, records, indexPath, indexJson, entrypointPath, launcher,
|
|
300
|
+
releaseRoot, packageRoot, records, indexPath, indexJson, entrypointPath, launcher,
|
|
301
|
+
processRunnerPath, processRunnerLauncher, checkRunnerPath, checkRunnerLauncher, manifestPath, expectedManifest,
|
|
250
302
|
});
|
|
251
303
|
|
|
252
304
|
if (existsSync(releaseRoot)) {
|
|
253
305
|
assertExisting();
|
|
254
306
|
} else {
|
|
307
|
+
assertStorageHeadroom(controllerHome, {
|
|
308
|
+
operation: 'materialize_package_runtime_release',
|
|
309
|
+
requiredBytes: stagedBytes,
|
|
310
|
+
reserveBytes: PACKAGE_RUNTIME_STAGING_RESERVE_BYTES,
|
|
311
|
+
});
|
|
255
312
|
mkdirSync(releasesRoot, { recursive: true, mode: 0o700 });
|
|
256
313
|
const stagingRoot = join(releasesRoot, `.staging-${releaseId}-${process.pid}-${randomUUID().slice(0, 8)}`);
|
|
257
314
|
try {
|
|
@@ -260,9 +317,19 @@ export function materializePackageRuntimeRelease(input: {
|
|
|
260
317
|
atomicWrite(join(stagingRoot, 'package-files.json'), indexJson);
|
|
261
318
|
atomicWrite(join(stagingRoot, 'forge-runtime'), launcher, 0o700);
|
|
262
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);
|
|
263
324
|
const manifest: RuntimeReleaseManifest = { ...expectedManifest, createdAt: new Date().toISOString() };
|
|
264
|
-
|
|
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);
|
|
265
331
|
renameSync(stagingRoot, releaseRoot);
|
|
332
|
+
executionCanariesValidated = true;
|
|
266
333
|
} catch (error) {
|
|
267
334
|
rmSync(stagingRoot, { recursive: true, force: true });
|
|
268
335
|
if (!existsSync(releaseRoot)) throw error;
|
|
@@ -270,6 +337,7 @@ export function materializePackageRuntimeRelease(input: {
|
|
|
270
337
|
}
|
|
271
338
|
}
|
|
272
339
|
|
|
340
|
+
if (!executionCanariesValidated) assertRuntimeReleaseExecutionCanaries(manifestPath, controllerHome);
|
|
273
341
|
const authority = publishRuntimeRelease(controllerHome, manifestPath, input.operationId ?? `package-runtime-${FORGE_VERSION}-${Date.now()}`);
|
|
274
342
|
return {
|
|
275
343
|
releaseId,
|