@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,7 +1,7 @@
|
|
|
1
1
|
import { createHash } from 'crypto';
|
|
2
2
|
import { spawnSync } from 'child_process';
|
|
3
|
-
import { appendFileSync, mkdirSync } from 'fs';
|
|
4
|
-
import { dirname, join } from 'path';
|
|
3
|
+
import { appendFileSync, existsSync, lstatSync, mkdirSync } from 'fs';
|
|
4
|
+
import { dirname, join, relative, resolve } from 'path';
|
|
5
5
|
import { capProcessOutput, redactProcessOutput } from '../../effects/process-runner';
|
|
6
6
|
import { MAX_AGENT_TIMEOUT_MS, MIN_AGENT_TIMEOUT_MS } from '../controller/runtime-config';
|
|
7
7
|
import { repositoryControllerRoot } from './controller-home';
|
|
@@ -27,6 +27,7 @@ import { commandEnvironment, runCanonicalCommand, type RepositoryCommandAsyncHoo
|
|
|
27
27
|
import {
|
|
28
28
|
changedSnapshotPaths,
|
|
29
29
|
emptyWorkspaceSnapshot,
|
|
30
|
+
readonlyUnobservedRepositorySnapshot,
|
|
30
31
|
repositorySnapshot,
|
|
31
32
|
repositorySnapshotAsync,
|
|
32
33
|
snapshotChanged,
|
|
@@ -138,6 +139,36 @@ function boundedInteger(value: number | undefined, fallback: number, minimum: nu
|
|
|
138
139
|
return normalized;
|
|
139
140
|
}
|
|
140
141
|
|
|
142
|
+
function boundedSnapshotFingerprintPaths(
|
|
143
|
+
root: string,
|
|
144
|
+
cwd: string,
|
|
145
|
+
command: CanonicalRepositoryCommand,
|
|
146
|
+
): string[] | undefined {
|
|
147
|
+
if (command.kind !== 'argv') return undefined;
|
|
148
|
+
const program = (command.executable ?? '').split(/[\\/]/).at(-1)?.toLowerCase().replace(/\.exe$/, '');
|
|
149
|
+
const args = [...(command.args ?? [])];
|
|
150
|
+
if (program !== 'git' || args[0]?.toLowerCase() !== 'add') return undefined;
|
|
151
|
+
const separator = args.indexOf('--');
|
|
152
|
+
if (separator < 0 || separator === args.length - 1) return undefined;
|
|
153
|
+
const operands = args.slice(separator + 1);
|
|
154
|
+
if (operands.length > 32) return undefined;
|
|
155
|
+
|
|
156
|
+
const paths: string[] = [];
|
|
157
|
+
for (const operand of operands) {
|
|
158
|
+
if (!operand || operand.includes('\0') || operand.startsWith(':') || /[*?\[\]]/.test(operand)) return undefined;
|
|
159
|
+
const absolute = resolve(cwd, operand);
|
|
160
|
+
const path = relative(root, absolute).replace(/\\/g, '/');
|
|
161
|
+
if (!path || path === '..' || path.startsWith('../')) return undefined;
|
|
162
|
+
try {
|
|
163
|
+
if (existsSync(absolute) && lstatSync(absolute).isDirectory()) return undefined;
|
|
164
|
+
} catch {
|
|
165
|
+
return undefined;
|
|
166
|
+
}
|
|
167
|
+
paths.push(path);
|
|
168
|
+
}
|
|
169
|
+
return [...new Set(paths)].sort();
|
|
170
|
+
}
|
|
171
|
+
|
|
141
172
|
function approvalToken(
|
|
142
173
|
repository: RepositoryRecord,
|
|
143
174
|
relativeCwd: string,
|
|
@@ -265,7 +296,10 @@ function prepareRepositoryCommandExecution(
|
|
|
265
296
|
allowOpaqueLocalScript: input.allowOpaqueLocalScript,
|
|
266
297
|
});
|
|
267
298
|
const externalGrants = loadExternalFilesystemGrants(root).grants;
|
|
268
|
-
const externalPathUsages = assertCommandPathOperandsStayInRepository(command, cwd, root, externalGrants
|
|
299
|
+
const externalPathUsages = assertCommandPathOperandsStayInRepository(command, cwd, root, externalGrants, {
|
|
300
|
+
controllerHome,
|
|
301
|
+
repositoryId: repository.repoId,
|
|
302
|
+
});
|
|
269
303
|
const classification = classifyRepositoryCommand(command, repository.defaultBranch);
|
|
270
304
|
const before = input.reuseSnapshot ?? (input.allowNonGitWorkspace ? emptyWorkspaceSnapshot() : repositorySnapshot(root));
|
|
271
305
|
return finalizePreparedExecution(
|
|
@@ -286,6 +320,7 @@ async function prepareRepositoryCommandExecutionAsync(
|
|
|
286
320
|
repository: RepositoryRecord,
|
|
287
321
|
input: ExecuteRepositoryCommandInput,
|
|
288
322
|
controllerHome?: string,
|
|
323
|
+
mode: 'standard' | 'readonly_direct' = 'standard',
|
|
289
324
|
): Promise<{
|
|
290
325
|
root: string;
|
|
291
326
|
cwd: string;
|
|
@@ -302,17 +337,27 @@ async function prepareRepositoryCommandExecutionAsync(
|
|
|
302
337
|
allowOpaqueLocalScript: input.allowOpaqueLocalScript,
|
|
303
338
|
});
|
|
304
339
|
const externalGrants = loadExternalFilesystemGrants(root).grants;
|
|
305
|
-
const externalPathUsages = assertCommandPathOperandsStayInRepository(command, cwd, root, externalGrants
|
|
340
|
+
const externalPathUsages = assertCommandPathOperandsStayInRepository(command, cwd, root, externalGrants, {
|
|
341
|
+
controllerHome,
|
|
342
|
+
repositoryId: repository.repoId,
|
|
343
|
+
});
|
|
306
344
|
const classification = classifyRepositoryCommand(command, repository.defaultBranch);
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
345
|
+
if (mode === 'readonly_direct' && classification.risk !== 'readonly') {
|
|
346
|
+
throw new Error(`READONLY_DIRECT_ROUTE_REQUIRED: received ${classification.risk}`);
|
|
347
|
+
}
|
|
348
|
+
// The readonly-direct lane has already resolved repository identity, cwd/path
|
|
349
|
+
// scope, command input and readonly classification. Mutation snapshots are not
|
|
350
|
+
// authorization authority, so do not launch rev-parse/branch/status/show-ref
|
|
351
|
+
// merely to prove that a command selected for this lane did not mutate state.
|
|
352
|
+
// Write-capable lanes keep their complete observed snapshot semantics.
|
|
310
353
|
const before = input.reuseSnapshot ?? (input.allowNonGitWorkspace
|
|
311
354
|
? emptyWorkspaceSnapshot()
|
|
312
|
-
:
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
355
|
+
: mode === 'readonly_direct'
|
|
356
|
+
? readonlyUnobservedRepositorySnapshot()
|
|
357
|
+
: await repositorySnapshotAsync(root, input.signal, {
|
|
358
|
+
fingerprintTimeoutMs: input.snapshotFingerprintTimeoutMs,
|
|
359
|
+
fingerprintPaths: boundedSnapshotFingerprintPaths(root, cwd, command),
|
|
360
|
+
}));
|
|
316
361
|
return finalizePreparedExecution(
|
|
317
362
|
repository,
|
|
318
363
|
input,
|
|
@@ -449,9 +494,9 @@ export function executeRepositoryCommand(
|
|
|
449
494
|
*
|
|
450
495
|
* This path exists for short repository reads that must remain available while
|
|
451
496
|
* Runtime writer authority is fenced or rotating. It reuses the exact command
|
|
452
|
-
* input/scope classifier,
|
|
453
|
-
*
|
|
454
|
-
*
|
|
497
|
+
* input/scope classifier, bounded async process runner, cancellation,
|
|
498
|
+
* environment allowlist, output caps and redaction. It deliberately owns no
|
|
499
|
+
* mutation snapshot or Controller write state, Process records, Leases, Jobs or receipts.
|
|
455
500
|
*/
|
|
456
501
|
export async function executeRepositoryReadOnlyCommandDirect(
|
|
457
502
|
repository: RepositoryRecord,
|
|
@@ -461,6 +506,7 @@ export async function executeRepositoryReadOnlyCommandDirect(
|
|
|
461
506
|
repository,
|
|
462
507
|
{ ...input, dryRun: false },
|
|
463
508
|
undefined,
|
|
509
|
+
'readonly_direct',
|
|
464
510
|
);
|
|
465
511
|
const { root, cwd, command, timeoutMs, maxOutputBytes, before, execution: base, externalPathUsages } = prepared;
|
|
466
512
|
if (base.classification.risk !== 'readonly') {
|
|
@@ -490,10 +536,9 @@ export async function executeRepositoryReadOnlyCommandDirect(
|
|
|
490
536
|
|
|
491
537
|
const result = await runCanonicalCommand(command, cwd, timeoutMs, maxOutputBytes, { signal });
|
|
492
538
|
// This entry point is reachable only after the bounded classifier has proven
|
|
493
|
-
// the command readonly.
|
|
494
|
-
//
|
|
495
|
-
//
|
|
496
|
-
// the receipt; write-capable lanes still take independent before/after snapshots.
|
|
539
|
+
// the command readonly. Mutation evidence is explicitly unobserved rather than
|
|
540
|
+
// fabricated: no before/after Git snapshot is taken, while write-capable lanes
|
|
541
|
+
// still take independent observed before/after snapshots.
|
|
497
542
|
const after = before;
|
|
498
543
|
return {
|
|
499
544
|
...base,
|
|
@@ -576,6 +621,7 @@ export async function executeRepositoryCommandAsync(
|
|
|
576
621
|
try {
|
|
577
622
|
after = await repositorySnapshotAsync(root, signal?.aborted ? undefined : signal, {
|
|
578
623
|
fingerprintTimeoutMs: input.snapshotFingerprintTimeoutMs,
|
|
624
|
+
fingerprintPaths: boundedSnapshotFingerprintPaths(root, cwd, command),
|
|
579
625
|
});
|
|
580
626
|
} catch (error) {
|
|
581
627
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -7,7 +7,7 @@ import { normalizeRepositoryCommand, type CanonicalRepositoryCommand } from './c
|
|
|
7
7
|
|
|
8
8
|
const MAX_COMMAND_LENGTH = 32 * 1024;
|
|
9
9
|
|
|
10
|
-
export type RepositoryCommandExternalPathOperation = 'external_read' | 'external_copy_into_workspace';
|
|
10
|
+
export type RepositoryCommandExternalPathOperation = 'external_read' | 'external_copy_into_workspace' | 'controller_local_effect';
|
|
11
11
|
|
|
12
12
|
export interface RepositoryCommandExternalPathUsage {
|
|
13
13
|
token: string;
|
|
@@ -154,11 +154,30 @@ export function assertRepositoryCommandStableHostIdentity(input: unknown): Canon
|
|
|
154
154
|
return command;
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
+
function assertNoUnmanagedControllerWorktreeLifecycle(command: CanonicalRepositoryCommand): void {
|
|
158
|
+
const isGitWorktreeAdd = (words: string[]) => {
|
|
159
|
+
const executable = words[0]?.split(/[\\/]/).at(-1)?.toLowerCase();
|
|
160
|
+
return executable === 'git' && words[1]?.toLowerCase() === 'worktree' && words[2]?.toLowerCase() === 'add';
|
|
161
|
+
};
|
|
162
|
+
if (command.kind === 'argv') {
|
|
163
|
+
if (isGitWorktreeAdd([command.executable!, ...(command.args ?? [])])) {
|
|
164
|
+
throw new Error('MANAGED_WORKSPACE_REQUIRED: repository_command_execute must not create an unmanaged temporary git worktree; use rh_work so Forge persists checkout/worktree ownership and terminal cleanup authority');
|
|
165
|
+
}
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
for (const segment of shellSegments(command.shellCommand ?? '')) {
|
|
169
|
+
if (isGitWorktreeAdd(shellWords(segment))) {
|
|
170
|
+
throw new Error('MANAGED_WORKSPACE_REQUIRED: repository_command_execute must not create an unmanaged temporary git worktree; use rh_work so Forge persists checkout/worktree ownership and terminal cleanup authority');
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
157
175
|
export function assertRepositoryCommandInputAllowed(
|
|
158
176
|
input: unknown,
|
|
159
177
|
options: RepositoryCommandInputPolicyOptions = {},
|
|
160
178
|
): CanonicalRepositoryCommand {
|
|
161
179
|
const command = assertRepositoryCommandStableHostIdentity(input);
|
|
180
|
+
assertNoUnmanagedControllerWorktreeLifecycle(command);
|
|
162
181
|
if (command.kind === 'shell') {
|
|
163
182
|
assertRepositoryCommandAllowed(command.shellCommand!, options);
|
|
164
183
|
}
|
|
@@ -233,7 +252,74 @@ function readOnlyProgram(program: string | undefined): boolean {
|
|
|
233
252
|
].includes(program.toLowerCase()));
|
|
234
253
|
}
|
|
235
254
|
|
|
255
|
+
interface RepositoryCommandPathPolicyOptions {
|
|
256
|
+
controllerHome?: string;
|
|
257
|
+
repositoryId?: string;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
interface SourceControllerRoundCompatibilityScope {
|
|
261
|
+
operation: 'round-continue' | 'round-close';
|
|
262
|
+
controllerHome: string;
|
|
263
|
+
workId: string;
|
|
264
|
+
controllerAuthorityId: string;
|
|
265
|
+
relayScopeId: string;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function sourceControllerRoundCompatibilityScope(
|
|
269
|
+
command: CanonicalRepositoryCommand,
|
|
270
|
+
options: RepositoryCommandPathPolicyOptions,
|
|
271
|
+
): SourceControllerRoundCompatibilityScope | undefined {
|
|
272
|
+
if (command.kind !== 'argv' || !options.controllerHome || !options.repositoryId) return undefined;
|
|
273
|
+
const executable = command.executable?.split(/[\\/]/).at(-1)?.toLowerCase();
|
|
274
|
+
const args = command.args ?? [];
|
|
275
|
+
if (executable !== 'bun' || args[0] !== 'src/cli/index.ts' || args[1] !== 'chatgpt') return undefined;
|
|
276
|
+
const operation = args[2];
|
|
277
|
+
if (operation !== 'round-continue' && operation !== 'round-close') return undefined;
|
|
278
|
+
|
|
279
|
+
const allowedFlags = operation === 'round-continue'
|
|
280
|
+
? new Set(['--controller-home', '--repo-id', '--work-id', '--controller-authority-id', '--relay-scope-id', '--reason', '--timeout-ms'])
|
|
281
|
+
: new Set(['--controller-home', '--repo-id', '--work-id', '--controller-authority-id', '--relay-scope-id', '--disposition', '--handoff-id', '--reason']);
|
|
282
|
+
const values = new Map<string, string>();
|
|
283
|
+
for (let index = 3; index < args.length; index += 2) {
|
|
284
|
+
const flag = args[index];
|
|
285
|
+
const value = args[index + 1];
|
|
286
|
+
if (!flag || !allowedFlags.has(flag) || !value || value.startsWith('--') || values.has(flag)) {
|
|
287
|
+
throw new Error(`SOURCE_CONTROLLER_ROUND_COMMAND_CONTRACT_INVALID:${operation}:${flag ?? 'missing'}`);
|
|
288
|
+
}
|
|
289
|
+
values.set(flag, value);
|
|
290
|
+
}
|
|
291
|
+
const required = ['--controller-home', '--repo-id', '--work-id', '--controller-authority-id', '--relay-scope-id'];
|
|
292
|
+
for (const flag of required) {
|
|
293
|
+
if (!values.get(flag)?.trim()) throw new Error(`SOURCE_CONTROLLER_ROUND_COMMAND_CONTRACT_INVALID:${operation}:${flag}`);
|
|
294
|
+
}
|
|
295
|
+
if (values.get('--repo-id') !== options.repositoryId) {
|
|
296
|
+
throw new Error(`SOURCE_CONTROLLER_ROUND_COMMAND_REPOSITORY_MISMATCH:${values.get('--repo-id')}`);
|
|
297
|
+
}
|
|
298
|
+
const configuredControllerHome = realpathSync(options.controllerHome);
|
|
299
|
+
const requestedControllerHome = realpathSync(resolve(values.get('--controller-home')!));
|
|
300
|
+
if (requestedControllerHome !== configuredControllerHome) {
|
|
301
|
+
throw new Error(`SOURCE_CONTROLLER_ROUND_COMMAND_CONTROLLER_HOME_MISMATCH:${requestedControllerHome}`);
|
|
302
|
+
}
|
|
303
|
+
if (operation === 'round-close') {
|
|
304
|
+
const disposition = values.get('--disposition');
|
|
305
|
+
if (!disposition || !['wait', 'wait_for_user', 'goal_complete'].includes(disposition)) {
|
|
306
|
+
throw new Error(`SOURCE_CONTROLLER_ROUND_COMMAND_DISPOSITION_INVALID:${disposition ?? 'missing'}`);
|
|
307
|
+
}
|
|
308
|
+
if (disposition === 'wait_for_user' && !values.get('--handoff-id')?.trim()) {
|
|
309
|
+
throw new Error('SOURCE_CONTROLLER_ROUND_COMMAND_HANDOFF_REQUIRED');
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return {
|
|
313
|
+
operation,
|
|
314
|
+
controllerHome: configuredControllerHome,
|
|
315
|
+
workId: values.get('--work-id')!,
|
|
316
|
+
controllerAuthorityId: values.get('--controller-authority-id')!,
|
|
317
|
+
relayScopeId: values.get('--relay-scope-id')!,
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
|
|
236
321
|
function grantCoversPath(grant: ExternalFilesystemGrant, canonicalPath: string, operation: RepositoryCommandExternalPathOperation): boolean {
|
|
322
|
+
if (operation === 'controller_local_effect') return false;
|
|
237
323
|
if (externalFilesystemGrantExpired(grant)) return false;
|
|
238
324
|
if (operation === 'external_read' && grant.mode !== 'read') return false;
|
|
239
325
|
if (operation === 'external_copy_into_workspace' && grant.mode !== 'copy_into_repo') return false;
|
|
@@ -262,13 +348,27 @@ function operationForToken(words: string[], index: number, external: string, cwd
|
|
|
262
348
|
return 'external_write';
|
|
263
349
|
}
|
|
264
350
|
|
|
351
|
+
function gitIndexOnlyRepositoryOperand(words: string[], index: number, candidateToken: string, cwd: string, root: string): boolean {
|
|
352
|
+
const executable = words[0]?.split(/[\\/]/).at(-1)?.toLowerCase();
|
|
353
|
+
if (executable !== 'git') return false;
|
|
354
|
+
const subcommand = words[1];
|
|
355
|
+
const indexOnly = subcommand === 'update-index'
|
|
356
|
+
|| (subcommand === 'rm' && words.includes('--cached'))
|
|
357
|
+
|| (subcommand === 'restore' && words.includes('--staged') && !words.includes('--worktree'));
|
|
358
|
+
if (!indexOnly || index < 2) return false;
|
|
359
|
+
const lexical = candidateToken.startsWith('/') ? resolve(candidateToken) : resolve(cwd, candidateToken);
|
|
360
|
+
return pathInside(root, lexical);
|
|
361
|
+
}
|
|
362
|
+
|
|
265
363
|
export function assertCommandPathOperandsStayInRepository(
|
|
266
364
|
command: string | CanonicalRepositoryCommand,
|
|
267
365
|
cwd: string,
|
|
268
366
|
root: string,
|
|
269
367
|
externalGrants: ExternalFilesystemGrant[] = [],
|
|
368
|
+
options: RepositoryCommandPathPolicyOptions = {},
|
|
270
369
|
): RepositoryCommandExternalPathUsage[] {
|
|
271
370
|
const usages: RepositoryCommandExternalPathUsage[] = [];
|
|
371
|
+
const controllerRoundScope = typeof command === 'string' ? undefined : sourceControllerRoundCompatibilityScope(command, options);
|
|
272
372
|
const segments = typeof command === 'string'
|
|
273
373
|
? shellSegments(command).map((segment) => ({ raw: segment, words: shellWords(segment) }))
|
|
274
374
|
: command.kind === 'shell'
|
|
@@ -288,6 +388,10 @@ export function assertCommandPathOperandsStayInRepository(
|
|
|
288
388
|
const absoluteInput = candidateToken.startsWith('/');
|
|
289
389
|
if (!absoluteInput && !/[./\\*?]/.test(candidateToken) && !existsSync(join(cwd, candidateToken))) continue;
|
|
290
390
|
const candidate = absoluteInput ? resolve(candidateToken) : resolve(cwd, candidateToken);
|
|
391
|
+
// Git index-only operations address the repository entry itself and do not
|
|
392
|
+
// dereference its symlink target. Fence them lexically to the repository;
|
|
393
|
+
// all filesystem-affecting operations still use realpath below.
|
|
394
|
+
if (gitIndexOnlyRepositoryOperand(words, index, candidateToken, cwd, root)) continue;
|
|
291
395
|
const existing = nearestExistingPath(candidate);
|
|
292
396
|
if (!existing) continue;
|
|
293
397
|
const resolved = realpathSync(existing);
|
|
@@ -295,6 +399,18 @@ export function assertCommandPathOperandsStayInRepository(
|
|
|
295
399
|
if (!absoluteInput) {
|
|
296
400
|
throw new Error(`COMMAND_SCOPE_DENIED: command operand escapes repository root through a symlink or parent path: ${token}`);
|
|
297
401
|
}
|
|
402
|
+
if (controllerRoundScope
|
|
403
|
+
&& words[index - 1] === '--controller-home'
|
|
404
|
+
&& resolved === controllerRoundScope.controllerHome) {
|
|
405
|
+
usages.push({
|
|
406
|
+
token,
|
|
407
|
+
canonicalPath: resolved,
|
|
408
|
+
operation: 'controller_local_effect',
|
|
409
|
+
grantKey: `tool-contract-abi:${controllerRoundScope.operation}:${controllerRoundScope.workId}`,
|
|
410
|
+
grantRoot: controllerRoundScope.controllerHome,
|
|
411
|
+
});
|
|
412
|
+
continue;
|
|
413
|
+
}
|
|
298
414
|
if (sensitivePathDenied(resolved)) {
|
|
299
415
|
throw new Error(`COMMAND_SCOPE_DENIED: sensitive external path is never allowed in repository commands: ${token}`);
|
|
300
416
|
}
|
|
@@ -135,9 +135,115 @@ export function rollbackStoppedRepoLocalControllerHomeStorage(migration: Control
|
|
|
135
135
|
renameSync(physicalHome, logicalHome);
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
+
|
|
139
|
+
export interface StoppedControllerHomeAuthorityRelocation {
|
|
140
|
+
migrated: boolean;
|
|
141
|
+
sourceHome: string;
|
|
142
|
+
destinationHome: string;
|
|
143
|
+
archivedDestinationHome?: string;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function directoryEntryExists(path: string): boolean {
|
|
147
|
+
try { lstatSync(path); return true; } catch (error) {
|
|
148
|
+
if ((error as NodeJS.ErrnoException).code === 'ENOENT') return false;
|
|
149
|
+
throw error;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Atomically relocate one fully stopped Controller Home to a new durable path.
|
|
155
|
+
* The caller owns liveness fencing and must prove Runtime, Connector, Recovery
|
|
156
|
+
* Gateway, Recovery Watchdog, and any other writers are stopped before calling.
|
|
157
|
+
*
|
|
158
|
+
* Existing destination contents are never merged. A caller that has already
|
|
159
|
+
* proven the destination is an authority-free shell may request archival; the
|
|
160
|
+
* entire shell is renamed aside so rollback can restore it byte-for-byte.
|
|
161
|
+
*/
|
|
162
|
+
export function relocateStoppedControllerHomeAuthority(input: {
|
|
163
|
+
sourceHome: string;
|
|
164
|
+
destinationHome: string;
|
|
165
|
+
archiveExistingDestination?: boolean;
|
|
166
|
+
archiveSuffix?: string;
|
|
167
|
+
}): StoppedControllerHomeAuthorityRelocation {
|
|
168
|
+
const sourceHome = resolve(input.sourceHome);
|
|
169
|
+
const destinationHome = resolve(input.destinationHome);
|
|
170
|
+
if (sourceHome === destinationHome) throw new Error('CONTROLLER_HOME_RELOCATION_SAME_HOME');
|
|
171
|
+
if (!directoryEntryExists(sourceHome)) throw new Error(`CONTROLLER_HOME_RELOCATION_SOURCE_MISSING: ${sourceHome}`);
|
|
172
|
+
const sourceStat = lstatSync(sourceHome);
|
|
173
|
+
if (!sourceStat.isDirectory() || sourceStat.isSymbolicLink()) {
|
|
174
|
+
throw new Error(`CONTROLLER_HOME_RELOCATION_SOURCE_UNSUPPORTED: ${sourceHome}`);
|
|
175
|
+
}
|
|
176
|
+
mkdirSync(dirname(destinationHome), { recursive: true });
|
|
177
|
+
|
|
178
|
+
let archivedDestinationHome: string | undefined;
|
|
179
|
+
if (directoryEntryExists(destinationHome)) {
|
|
180
|
+
const destinationStat = lstatSync(destinationHome);
|
|
181
|
+
if (!destinationStat.isDirectory() || destinationStat.isSymbolicLink()) {
|
|
182
|
+
throw new Error(`CONTROLLER_HOME_RELOCATION_DESTINATION_UNSUPPORTED: ${destinationHome}`);
|
|
183
|
+
}
|
|
184
|
+
if (!input.archiveExistingDestination) {
|
|
185
|
+
throw new Error(`CONTROLLER_HOME_RELOCATION_DESTINATION_EXISTS: ${destinationHome}`);
|
|
186
|
+
}
|
|
187
|
+
const suffix = input.archiveSuffix?.trim() || `${Date.now()}-${process.pid}`;
|
|
188
|
+
if (!/^[A-Za-z0-9._-]{1,120}$/.test(suffix)) throw new Error('CONTROLLER_HOME_RELOCATION_ARCHIVE_SUFFIX_INVALID');
|
|
189
|
+
archivedDestinationHome = `${destinationHome}.pre-migration-${suffix}`;
|
|
190
|
+
if (directoryEntryExists(archivedDestinationHome)) {
|
|
191
|
+
throw new Error(`CONTROLLER_HOME_RELOCATION_ARCHIVE_EXISTS: ${archivedDestinationHome}`);
|
|
192
|
+
}
|
|
193
|
+
renameSync(destinationHome, archivedDestinationHome);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
try {
|
|
197
|
+
renameSync(sourceHome, destinationHome);
|
|
198
|
+
if (directoryEntryExists(sourceHome) || !lstatSync(destinationHome).isDirectory()) {
|
|
199
|
+
throw new Error('CONTROLLER_HOME_RELOCATION_POSTCHECK_FAILED');
|
|
200
|
+
}
|
|
201
|
+
return {
|
|
202
|
+
migrated: true,
|
|
203
|
+
sourceHome,
|
|
204
|
+
destinationHome,
|
|
205
|
+
...(archivedDestinationHome ? { archivedDestinationHome } : {}),
|
|
206
|
+
};
|
|
207
|
+
} catch (error) {
|
|
208
|
+
try {
|
|
209
|
+
if (!directoryEntryExists(sourceHome) && directoryEntryExists(destinationHome)) renameSync(destinationHome, sourceHome);
|
|
210
|
+
if (archivedDestinationHome && !directoryEntryExists(destinationHome) && directoryEntryExists(archivedDestinationHome)) {
|
|
211
|
+
renameSync(archivedDestinationHome, destinationHome);
|
|
212
|
+
}
|
|
213
|
+
} catch {
|
|
214
|
+
throw new Error(`CONTROLLER_HOME_RELOCATION_ROLLBACK_FAILED: ${error instanceof Error ? error.message : String(error)}`);
|
|
215
|
+
}
|
|
216
|
+
throw error;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/** Caller must keep all Controller Home writers stopped until rollback completes. */
|
|
221
|
+
export function rollbackStoppedControllerHomeAuthorityRelocation(
|
|
222
|
+
relocation: StoppedControllerHomeAuthorityRelocation,
|
|
223
|
+
): void {
|
|
224
|
+
if (!relocation.migrated) return;
|
|
225
|
+
const sourceHome = resolve(relocation.sourceHome);
|
|
226
|
+
const destinationHome = resolve(relocation.destinationHome);
|
|
227
|
+
const archivedDestinationHome = relocation.archivedDestinationHome ? resolve(relocation.archivedDestinationHome) : undefined;
|
|
228
|
+
if (directoryEntryExists(sourceHome)) throw new Error(`CONTROLLER_HOME_RELOCATION_ROLLBACK_SOURCE_EXISTS: ${sourceHome}`);
|
|
229
|
+
if (!directoryEntryExists(destinationHome) || !lstatSync(destinationHome).isDirectory()) {
|
|
230
|
+
throw new Error(`CONTROLLER_HOME_RELOCATION_ROLLBACK_DESTINATION_MISSING: ${destinationHome}`);
|
|
231
|
+
}
|
|
232
|
+
if (archivedDestinationHome && !directoryEntryExists(archivedDestinationHome)) {
|
|
233
|
+
throw new Error(`CONTROLLER_HOME_RELOCATION_ROLLBACK_ARCHIVE_MISSING: ${archivedDestinationHome}`);
|
|
234
|
+
}
|
|
235
|
+
renameSync(destinationHome, sourceHome);
|
|
236
|
+
try {
|
|
237
|
+
if (archivedDestinationHome) renameSync(archivedDestinationHome, destinationHome);
|
|
238
|
+
} catch (error) {
|
|
239
|
+
try { if (!directoryEntryExists(destinationHome) && directoryEntryExists(sourceHome)) renameSync(sourceHome, destinationHome); } catch { /* best effort */ }
|
|
240
|
+
throw new Error(`CONTROLLER_HOME_RELOCATION_ROLLBACK_RESTORE_FAILED: ${error instanceof Error ? error.message : String(error)}`);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
138
244
|
export function ensureControllerHome(explicit?: string): string {
|
|
139
245
|
const home = ensureControllerHomeStorage(resolveControllerHome(explicit));
|
|
140
|
-
for (const child of ['', 'repositories', 'system', 'locks', 'indexes', 'audit', 'mcp', 'sessions', 'work-handles']) {
|
|
246
|
+
for (const child of ['', 'repositories', 'system', 'locks', 'indexes', 'audit', 'mcp', 'sessions', 'work-handles', 'workflows']) {
|
|
141
247
|
mkdirSync(join(home, child), { recursive: true });
|
|
142
248
|
}
|
|
143
249
|
return home;
|
|
@@ -149,6 +255,17 @@ export function ensureRepoPreferredControllerHome(repoRoot?: string, explicit?:
|
|
|
149
255
|
|
|
150
256
|
export const CONTROLLER_SCOPE_REPO_ID = '__controller__';
|
|
151
257
|
|
|
258
|
+
/** Human-editable user Workflow Asset content. Machine workflow state stays in control-plane persistence. */
|
|
259
|
+
export function controllerWorkflowContentRoot(controllerHome: string): string {
|
|
260
|
+
return join(resolveControllerHome(controllerHome), 'workflows');
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
export function ensureControllerWorkflowContentRoot(controllerHome: string): string {
|
|
264
|
+
const root = controllerWorkflowContentRoot(ensureControllerHome(controllerHome));
|
|
265
|
+
mkdirSync(root, { recursive: true });
|
|
266
|
+
return root;
|
|
267
|
+
}
|
|
268
|
+
|
|
152
269
|
export function controllerSystemRoot(controllerHome: string): string {
|
|
153
270
|
return join(resolveControllerHome(controllerHome), 'system');
|
|
154
271
|
}
|
|
@@ -178,6 +295,7 @@ export function ensureRepositoryControllerLayout(controllerHome: string, repoId:
|
|
|
178
295
|
'indexes',
|
|
179
296
|
'edit-sessions',
|
|
180
297
|
'controller',
|
|
298
|
+
'hook-state',
|
|
181
299
|
'local-bridge',
|
|
182
300
|
'ephemeral-issues',
|
|
183
301
|
'work-handles',
|
|
@@ -39,6 +39,19 @@ export function stableRemoteRepoId(canonicalRemote: string): string {
|
|
|
39
39
|
return `repo_${digest(`remote\0${canonicalRemote}`).slice(0, 24)}`;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
/** Portable Project identity: stable across ForgeInstance/repository registrations for the same canonical remote. */
|
|
43
|
+
export function stablePortableProjectId(canonicalRemote: string): string {
|
|
44
|
+
const normalized = normalizeRemoteUrl(canonicalRemote);
|
|
45
|
+
if (!normalized) throw new Error('PROJECT_REMOTE_IDENTITY_REQUIRED');
|
|
46
|
+
return `project_${digest(`project\0${normalized}`).slice(0, 24)}`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function portableProjectSourceFingerprint(canonicalRemote: string): string {
|
|
50
|
+
const normalized = normalizeRemoteUrl(canonicalRemote);
|
|
51
|
+
if (!normalized) throw new Error('PROJECT_REMOTE_IDENTITY_REQUIRED');
|
|
52
|
+
return digest(`project-source\0${normalized}`);
|
|
53
|
+
}
|
|
54
|
+
|
|
42
55
|
export function newLocalRepoId(): string {
|
|
43
56
|
return `repo_local_${randomUUID().replace(/-/g, '')}`;
|
|
44
57
|
}
|