smol-symphony 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +41 -22
- package/DESIGN.md +494 -273
- package/README.md +109 -57
- package/SPEC.md +33 -24
- package/WORKFLOW.minimal.yaml +34 -0
- package/{WORKFLOW.template.md → WORKFLOW.template.yaml} +409 -256
- package/WORKFLOW.yaml +487 -0
- package/assets/skills/symphony-issues/SKILL.md +136 -0
- package/assets/symphony-mise.system.toml +68 -0
- package/dist/bin/symphony.js +22 -786
- package/dist/bin/symphony.js.map +1 -1
- package/dist/core/actions/context.js +109 -0
- package/dist/core/actions/context.js.map +1 -0
- package/dist/{actions/parsing.js → core/actions/parse.js} +33 -114
- package/dist/core/actions/parse.js.map +1 -0
- package/dist/core/actions/plan.js +197 -0
- package/dist/core/actions/plan.js.map +1 -0
- package/dist/core/actions/predicates.js +111 -0
- package/dist/core/actions/predicates.js.map +1 -0
- package/dist/core/actions/run-fold.js +248 -0
- package/dist/core/actions/run-fold.js.map +1 -0
- package/dist/core/actions/template.js +118 -0
- package/dist/core/actions/template.js.map +1 -0
- package/dist/core/cli/args.js +116 -0
- package/dist/core/cli/args.js.map +1 -0
- package/dist/core/coerce.js +75 -0
- package/dist/core/coerce.js.map +1 -0
- package/dist/core/credential/account-id.js +20 -0
- package/dist/core/credential/account-id.js.map +1 -0
- package/dist/core/credential/adapter-config.js +136 -0
- package/dist/core/credential/adapter-config.js.map +1 -0
- package/dist/core/credential/availability.js +98 -0
- package/dist/core/credential/availability.js.map +1 -0
- package/dist/core/credential/extract.js +228 -0
- package/dist/core/credential/extract.js.map +1 -0
- package/dist/core/credential/fake-creds.js +171 -0
- package/dist/core/credential/fake-creds.js.map +1 -0
- package/dist/core/credential/identity.js +125 -0
- package/dist/core/credential/identity.js.map +1 -0
- package/dist/core/credential/shape.js +230 -0
- package/dist/core/credential/shape.js.map +1 -0
- package/dist/core/credential/strings.js +15 -0
- package/dist/core/credential/strings.js.map +1 -0
- package/dist/core/doctor/checks.js +303 -0
- package/dist/core/doctor/checks.js.map +1 -0
- package/dist/core/git/result.js +107 -0
- package/dist/core/git/result.js.map +1 -0
- package/dist/core/http/decisions.js +225 -0
- package/dist/core/http/decisions.js.map +1 -0
- package/dist/{http.js → core/http/render.js} +472 -738
- package/dist/core/http/render.js.map +1 -0
- package/dist/{http-handlers.js → core/http/routes.js} +52 -87
- package/dist/core/http/routes.js.map +1 -0
- package/dist/core/http/views.js +181 -0
- package/dist/core/http/views.js.map +1 -0
- package/dist/core/image/managed-image.js +95 -0
- package/dist/core/image/managed-image.js.map +1 -0
- package/dist/core/issue/file.js +149 -0
- package/dist/core/issue/file.js.map +1 -0
- package/dist/core/issue/parse.js +210 -0
- package/dist/core/issue/parse.js.map +1 -0
- package/dist/core/mcp/dispatch.js +239 -0
- package/dist/core/mcp/dispatch.js.map +1 -0
- package/dist/core/mcp/post-move.js +92 -0
- package/dist/core/mcp/post-move.js.map +1 -0
- package/dist/core/mcp/protocol.js +293 -0
- package/dist/core/mcp/protocol.js.map +1 -0
- package/dist/core/mcp/url.js +162 -0
- package/dist/core/mcp/url.js.map +1 -0
- package/dist/core/path.js +63 -0
- package/dist/core/path.js.map +1 -0
- package/dist/core/reconcile/image-decide.js +48 -0
- package/dist/core/reconcile/image-decide.js.map +1 -0
- package/dist/core/reconcile/ledger.js +142 -0
- package/dist/core/reconcile/ledger.js.map +1 -0
- package/dist/core/reconcile/pr-classify.js +62 -0
- package/dist/core/reconcile/pr-classify.js.map +1 -0
- package/dist/{reconciler → core/reconcile}/pr-decide.js +25 -12
- package/dist/core/reconcile/pr-decide.js.map +1 -0
- package/dist/core/reconcile/pr-loop.js +161 -0
- package/dist/core/reconcile/pr-loop.js.map +1 -0
- package/dist/core/reconcile/pr-notes.js +35 -0
- package/dist/core/reconcile/pr-notes.js.map +1 -0
- package/dist/core/reconcile/vm-decide.js +70 -0
- package/dist/core/reconcile/vm-decide.js.map +1 -0
- package/dist/core/reconcile/vm-reap.js +207 -0
- package/dist/core/reconcile/vm-reap.js.map +1 -0
- package/dist/core/reconcile/workspace-decide.js +162 -0
- package/dist/core/reconcile/workspace-decide.js.map +1 -0
- package/dist/core/runlog/summary.js +231 -0
- package/dist/core/runlog/summary.js.map +1 -0
- package/dist/core/runner/dispatch-config.js +95 -0
- package/dist/core/runner/dispatch-config.js.map +1 -0
- package/dist/core/runner/injection.js +61 -0
- package/dist/core/runner/injection.js.map +1 -0
- package/dist/core/runner/mise.js +210 -0
- package/dist/core/runner/mise.js.map +1 -0
- package/dist/core/runner/prompt.js +720 -0
- package/dist/core/runner/prompt.js.map +1 -0
- package/dist/core/runner/turn.js +242 -0
- package/dist/core/runner/turn.js.map +1 -0
- package/dist/core/runner/vm-plan.js +390 -0
- package/dist/core/runner/vm-plan.js.map +1 -0
- package/dist/core/schedule/admission.js +123 -0
- package/dist/core/schedule/admission.js.map +1 -0
- package/dist/core/schedule/circuit-breaker.js +111 -0
- package/dist/core/schedule/circuit-breaker.js.map +1 -0
- package/dist/core/schedule/eligibility.js +83 -0
- package/dist/core/schedule/eligibility.js.map +1 -0
- package/dist/core/schedule/reconcile-issue.js +82 -0
- package/dist/core/schedule/reconcile-issue.js.map +1 -0
- package/dist/core/schedule/retry.js +96 -0
- package/dist/core/schedule/retry.js.map +1 -0
- package/dist/core/schedule/sleep-cycle.js +133 -0
- package/dist/core/schedule/sleep-cycle.js.map +1 -0
- package/dist/core/schedule/slots.js +124 -0
- package/dist/core/schedule/slots.js.map +1 -0
- package/dist/core/schedule/tick.js +553 -0
- package/dist/core/schedule/tick.js.map +1 -0
- package/dist/core/schedule/token-fold.js +181 -0
- package/dist/core/schedule/token-fold.js.map +1 -0
- package/dist/core/state-resolve.js +86 -0
- package/dist/core/state-resolve.js.map +1 -0
- package/dist/core/vm-guards.js +278 -0
- package/dist/core/vm-guards.js.map +1 -0
- package/dist/core/workflow/derive.js +107 -0
- package/dist/core/workflow/derive.js.map +1 -0
- package/dist/core/workflow/parse.js +687 -0
- package/dist/core/workflow/parse.js.map +1 -0
- package/dist/core/workflow/prompt-probe.js +78 -0
- package/dist/core/workflow/prompt-probe.js.map +1 -0
- package/dist/core/workflow/validate.js +189 -0
- package/dist/core/workflow/validate.js.map +1 -0
- package/dist/core/workspace-key.js +19 -0
- package/dist/core/workspace-key.js.map +1 -0
- package/dist/shell/actions-runner.js +356 -0
- package/dist/shell/actions-runner.js.map +1 -0
- package/dist/shell/adapter/adapter-registry.js +45 -0
- package/dist/shell/adapter/adapter-registry.js.map +1 -0
- package/dist/shell/adapter/clock-random.js +96 -0
- package/dist/shell/adapter/clock-random.js.map +1 -0
- package/dist/shell/adapter/gondolin-dispatch-helpers.js +158 -0
- package/dist/shell/adapter/gondolin-dispatch-helpers.js.map +1 -0
- package/dist/shell/adapter/gondolin-dispatch.js +385 -0
- package/dist/shell/adapter/gondolin-dispatch.js.map +1 -0
- package/dist/shell/adapter/gondolin-image-converter.js +233 -0
- package/dist/shell/adapter/gondolin-image-converter.js.map +1 -0
- package/dist/shell/adapter/gondolin-image-fetch.js +180 -0
- package/dist/shell/adapter/gondolin-image-fetch.js.map +1 -0
- package/dist/shell/adapter/launcher-asset.js +57 -0
- package/dist/shell/adapter/launcher-asset.js.map +1 -0
- package/dist/shell/adapter/mise-config-asset.js +65 -0
- package/dist/shell/adapter/mise-config-asset.js.map +1 -0
- package/dist/shell/adapter/workflow-loader.js +304 -0
- package/dist/shell/adapter/workflow-loader.js.map +1 -0
- package/dist/shell/cli/doctor.js +268 -0
- package/dist/shell/cli/doctor.js.map +1 -0
- package/dist/shell/effect-interpreter-families.js +314 -0
- package/dist/shell/effect-interpreter-families.js.map +1 -0
- package/dist/shell/effect-interpreter.js +29 -0
- package/dist/shell/effect-interpreter.js.map +1 -0
- package/dist/shell/interp/acp-frame.js +137 -0
- package/dist/shell/interp/acp-frame.js.map +1 -0
- package/dist/shell/interp/acp-ws-conn.js +320 -0
- package/dist/shell/interp/acp-ws-conn.js.map +1 -0
- package/dist/shell/interp/acp-ws-frames.js +159 -0
- package/dist/shell/interp/acp-ws-frames.js.map +1 -0
- package/dist/shell/interp/acp-ws.js +197 -0
- package/dist/shell/interp/acp-ws.js.map +1 -0
- package/dist/shell/interp/acp.js +319 -0
- package/dist/shell/interp/acp.js.map +1 -0
- package/dist/shell/interp/credential-defaults.js +128 -0
- package/dist/shell/interp/credential-defaults.js.map +1 -0
- package/dist/shell/interp/credential-hooks.js +149 -0
- package/dist/shell/interp/credential-hooks.js.map +1 -0
- package/dist/shell/interp/credential-registry.js +226 -0
- package/dist/shell/interp/credential-registry.js.map +1 -0
- package/dist/shell/interp/credential.js +103 -0
- package/dist/shell/interp/credential.js.map +1 -0
- package/dist/shell/interp/gh.js +163 -0
- package/dist/shell/interp/gh.js.map +1 -0
- package/dist/shell/interp/git.js +28 -0
- package/dist/shell/interp/git.js.map +1 -0
- package/dist/shell/interp/log.js +213 -0
- package/dist/shell/interp/log.js.map +1 -0
- package/dist/shell/interp/process.js +178 -0
- package/dist/shell/interp/process.js.map +1 -0
- package/dist/shell/interp/runlog.js +193 -0
- package/dist/shell/interp/runlog.js.map +1 -0
- package/dist/shell/interp/timer.js +64 -0
- package/dist/shell/interp/timer.js.map +1 -0
- package/dist/shell/interp/tracker-disk.js +99 -0
- package/dist/shell/interp/tracker-disk.js.map +1 -0
- package/dist/shell/interp/tracker-parse.js +71 -0
- package/dist/shell/interp/tracker-parse.js.map +1 -0
- package/dist/shell/interp/tracker-scan.js +238 -0
- package/dist/shell/interp/tracker-scan.js.map +1 -0
- package/dist/shell/interp/tracker-write.js +91 -0
- package/dist/shell/interp/tracker-write.js.map +1 -0
- package/dist/shell/interp/tracker.js +41 -0
- package/dist/shell/interp/tracker.js.map +1 -0
- package/dist/shell/interp/tty.js +48 -0
- package/dist/shell/interp/tty.js.map +1 -0
- package/dist/shell/interp/vm.js +199 -0
- package/dist/shell/interp/vm.js.map +1 -0
- package/dist/shell/interp/workspace.js +310 -0
- package/dist/shell/interp/workspace.js.map +1 -0
- package/dist/shell/main-acp.js +78 -0
- package/dist/shell/main-acp.js.map +1 -0
- package/dist/shell/main-adapters.js +222 -0
- package/dist/shell/main-adapters.js.map +1 -0
- package/dist/shell/main-credential.js +122 -0
- package/dist/shell/main-credential.js.map +1 -0
- package/dist/shell/main-doctor.js +22 -0
- package/dist/shell/main-doctor.js.map +1 -0
- package/dist/shell/main-entry.js +46 -0
- package/dist/shell/main-entry.js.map +1 -0
- package/dist/shell/main-http-csrf.js +45 -0
- package/dist/shell/main-http-csrf.js.map +1 -0
- package/dist/shell/main-http-handler.js +389 -0
- package/dist/shell/main-http-handler.js.map +1 -0
- package/dist/shell/main-http-mcp.js +122 -0
- package/dist/shell/main-http-mcp.js.map +1 -0
- package/dist/shell/main-http-views.js +253 -0
- package/dist/shell/main-http-views.js.map +1 -0
- package/dist/shell/main-http.js +76 -0
- package/dist/shell/main-http.js.map +1 -0
- package/dist/shell/main-loops.js +130 -0
- package/dist/shell/main-loops.js.map +1 -0
- package/dist/shell/main-mcp.js +129 -0
- package/dist/shell/main-mcp.js.map +1 -0
- package/dist/shell/main-orchestrator.js +120 -0
- package/dist/shell/main-orchestrator.js.map +1 -0
- package/dist/shell/main-preflight.js +43 -0
- package/dist/shell/main-preflight.js.map +1 -0
- package/dist/shell/main-reconcilers-helpers.js +244 -0
- package/dist/shell/main-reconcilers-helpers.js.map +1 -0
- package/dist/shell/main-reconcilers-pr.js +148 -0
- package/dist/shell/main-reconcilers-pr.js.map +1 -0
- package/dist/shell/main-reconcilers.js +225 -0
- package/dist/shell/main-reconcilers.js.map +1 -0
- package/dist/shell/main-runner.js +355 -0
- package/dist/shell/main-runner.js.map +1 -0
- package/dist/shell/main-scaffold.js +116 -0
- package/dist/shell/main-scaffold.js.map +1 -0
- package/dist/shell/main-shutdown.js +115 -0
- package/dist/shell/main-shutdown.js.map +1 -0
- package/dist/shell/main-startup.js +48 -0
- package/dist/shell/main-startup.js.map +1 -0
- package/dist/shell/main-substrates.js +43 -0
- package/dist/shell/main-substrates.js.map +1 -0
- package/dist/shell/main.js +385 -0
- package/dist/shell/main.js.map +1 -0
- package/dist/shell/orchestrator-feedback.js +69 -0
- package/dist/shell/orchestrator-feedback.js.map +1 -0
- package/dist/shell/orchestrator-image.js +167 -0
- package/dist/shell/orchestrator-image.js.map +1 -0
- package/dist/shell/orchestrator-loop.js +468 -0
- package/dist/shell/orchestrator-loop.js.map +1 -0
- package/dist/shell/orchestrator-reconcile.js +36 -0
- package/dist/shell/orchestrator-reconcile.js.map +1 -0
- package/dist/shell/reconciler-loop.js +228 -0
- package/dist/shell/reconciler-loop.js.map +1 -0
- package/dist/shell/runner-loop-turn.js +301 -0
- package/dist/shell/runner-loop-turn.js.map +1 -0
- package/dist/shell/runner-loop.js +338 -0
- package/dist/shell/runner-loop.js.map +1 -0
- package/dist/shell/server/http.js +208 -0
- package/dist/shell/server/http.js.map +1 -0
- package/dist/shell/server/mcp-runtime-effects.js +237 -0
- package/dist/shell/server/mcp-runtime-effects.js.map +1 -0
- package/dist/shell/server/mcp-runtime.js +99 -0
- package/dist/shell/server/mcp-runtime.js.map +1 -0
- package/dist/shell/workspace-key.js +14 -0
- package/dist/shell/workspace-key.js.map +1 -0
- package/dist/types/acp.js +8 -0
- package/dist/types/acp.js.map +1 -0
- package/dist/types/actions/plan.js +6 -0
- package/dist/types/actions/plan.js.map +1 -0
- package/dist/types/actions/predicates.js +6 -0
- package/dist/types/actions/predicates.js.map +1 -0
- package/dist/types/actions/run-fold.js +8 -0
- package/dist/types/actions/run-fold.js.map +1 -0
- package/dist/types/actions.js +7 -0
- package/dist/types/actions.js.map +1 -0
- package/dist/types/adapter/clock-random.js +4 -0
- package/dist/types/adapter/clock-random.js.map +1 -0
- package/dist/types/adapter/gondolin-image-converter.js +5 -0
- package/dist/types/adapter/gondolin-image-converter.js.map +1 -0
- package/dist/types/adapter/gondolin-image-fetch.js +5 -0
- package/dist/types/adapter/gondolin-image-fetch.js.map +1 -0
- package/dist/types/adapter/workflow-loader.js +4 -0
- package/dist/types/adapter/workflow-loader.js.map +1 -0
- package/dist/types/cli/args.js +8 -0
- package/dist/types/cli/args.js.map +1 -0
- package/dist/types/config.js +8 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/credential-interp.js +6 -0
- package/dist/types/credential-interp.js.map +1 -0
- package/dist/types/credentials.js +10 -0
- package/dist/types/credentials.js.map +1 -0
- package/dist/types/doctor.js +7 -0
- package/dist/types/doctor.js.map +1 -0
- package/dist/types/domain.js +7 -0
- package/dist/types/domain.js.map +1 -0
- package/dist/types/effect.js +15 -0
- package/dist/types/effect.js.map +1 -0
- package/dist/types/errors.js +39 -0
- package/dist/types/errors.js.map +1 -0
- package/dist/types/http/decisions.js +6 -0
- package/dist/types/http/decisions.js.map +1 -0
- package/dist/types/http/render.js +10 -0
- package/dist/types/http/render.js.map +1 -0
- package/dist/types/http/views.js +6 -0
- package/dist/types/http/views.js.map +1 -0
- package/dist/types/http.js +9 -0
- package/dist/types/http.js.map +1 -0
- package/dist/types/image/managed-image.js +7 -0
- package/dist/types/image/managed-image.js.map +1 -0
- package/dist/types/interp/effect-interpreter.js +8 -0
- package/dist/types/interp/effect-interpreter.js.map +1 -0
- package/dist/types/interp/tracker.js +7 -0
- package/dist/types/interp/tracker.js.map +1 -0
- package/dist/types/issue/file.js +6 -0
- package/dist/types/issue/file.js.map +1 -0
- package/dist/types/issue/parse.js +8 -0
- package/dist/types/issue/parse.js.map +1 -0
- package/dist/types/main-acp.js +13 -0
- package/dist/types/main-acp.js.map +1 -0
- package/dist/types/main-adapters.js +5 -0
- package/dist/types/main-adapters.js.map +1 -0
- package/dist/types/main-credential.js +21 -0
- package/dist/types/main-credential.js.map +1 -0
- package/dist/types/main-doctor.js +6 -0
- package/dist/types/main-doctor.js.map +1 -0
- package/dist/types/main-http-handler.js +12 -0
- package/dist/types/main-http-handler.js.map +1 -0
- package/dist/types/main-http.js +5 -0
- package/dist/types/main-http.js.map +1 -0
- package/dist/types/main-loops.js +5 -0
- package/dist/types/main-loops.js.map +1 -0
- package/dist/types/main-mcp.js +12 -0
- package/dist/types/main-mcp.js.map +1 -0
- package/dist/types/main-orchestrator.js +5 -0
- package/dist/types/main-orchestrator.js.map +1 -0
- package/dist/types/main-reconcilers.js +11 -0
- package/dist/types/main-reconcilers.js.map +1 -0
- package/dist/types/main-runner.js +13 -0
- package/dist/types/main-runner.js.map +1 -0
- package/dist/types/main-startup.js +5 -0
- package/dist/types/main-startup.js.map +1 -0
- package/dist/types/main-substrates.js +5 -0
- package/dist/types/main-substrates.js.map +1 -0
- package/dist/types/mcp/dispatch.js +4 -0
- package/dist/types/mcp/dispatch.js.map +1 -0
- package/dist/types/mcp/post-move.js +7 -0
- package/dist/types/mcp/post-move.js.map +1 -0
- package/dist/types/mcp.js +9 -0
- package/dist/types/mcp.js.map +1 -0
- package/dist/types/ports.js +12 -0
- package/dist/types/ports.js.map +1 -0
- package/dist/types/reconcile/image-decide.js +5 -0
- package/dist/types/reconcile/image-decide.js.map +1 -0
- package/dist/types/reconcile/ledger.js +7 -0
- package/dist/types/reconcile/ledger.js.map +1 -0
- package/dist/types/reconcile/pr-loop.js +8 -0
- package/dist/types/reconcile/pr-loop.js.map +1 -0
- package/dist/types/reconcile/vm-reap.js +8 -0
- package/dist/types/reconcile/vm-reap.js.map +1 -0
- package/dist/types/reconcile/workspace-decide.js +7 -0
- package/dist/types/reconcile/workspace-decide.js.map +1 -0
- package/dist/types/reconcile.js +9 -0
- package/dist/types/reconcile.js.map +1 -0
- package/dist/types/runlog.js +7 -0
- package/dist/types/runlog.js.map +1 -0
- package/dist/types/runner/actions-runner.js +12 -0
- package/dist/types/runner/actions-runner.js.map +1 -0
- package/dist/types/runner/gondolin-dispatch.js +5 -0
- package/dist/types/runner/gondolin-dispatch.js.map +1 -0
- package/dist/types/runner/injection.js +6 -0
- package/dist/types/runner/injection.js.map +1 -0
- package/dist/types/runner/runner-loop.js +5 -0
- package/dist/types/runner/runner-loop.js.map +1 -0
- package/dist/types/runner/turn.js +4 -0
- package/dist/types/runner/turn.js.map +1 -0
- package/dist/types/runner/vm-plan.js +4 -0
- package/dist/types/runner/vm-plan.js.map +1 -0
- package/dist/types/runtime.js +9 -0
- package/dist/types/runtime.js.map +1 -0
- package/dist/types/schedule/admission.js +7 -0
- package/dist/types/schedule/admission.js.map +1 -0
- package/dist/types/schedule/circuit-breaker.js +2 -0
- package/dist/types/schedule/circuit-breaker.js.map +1 -0
- package/dist/types/schedule/eligibility.js +9 -0
- package/dist/types/schedule/eligibility.js.map +1 -0
- package/dist/types/schedule/orchestrator-loop.js +10 -0
- package/dist/types/schedule/orchestrator-loop.js.map +1 -0
- package/dist/types/schedule/sleep-cycle.js +4 -0
- package/dist/types/schedule/sleep-cycle.js.map +1 -0
- package/dist/types/schedule/slots.js +8 -0
- package/dist/types/schedule/slots.js.map +1 -0
- package/dist/types/schedule/tick.js +9 -0
- package/dist/types/schedule/tick.js.map +1 -0
- package/dist/types/server/mcp-runtime.js +8 -0
- package/dist/types/server/mcp-runtime.js.map +1 -0
- package/dist/types/workflow/parse.js +4 -0
- package/dist/types/workflow/parse.js.map +1 -0
- package/package.json +22 -10
- package/patches/@earendil-works+gondolin+0.12.0.patch +173 -0
- package/prompts/Reflect.md +91 -0
- package/prompts/Review.md +97 -0
- package/prompts/Todo.md +96 -0
- package/prompts/_footer.md +41 -0
- package/prompts/_preamble.md +42 -0
- package/prompts-minimal/Todo.md +26 -0
- package/scripts/postinstall.mjs +63 -0
- package/scripts/vm-agent.mjs +312 -90
- package/WORKFLOW.md +0 -744
- package/dist/acp-bridge.js +0 -324
- package/dist/acp-bridge.js.map +0 -1
- package/dist/actions/cache.js +0 -191
- package/dist/actions/cache.js.map +0 -1
- package/dist/actions/effects.js +0 -41
- package/dist/actions/effects.js.map +0 -1
- package/dist/actions/executor.js +0 -570
- package/dist/actions/executor.js.map +0 -1
- package/dist/actions/index.js +0 -13
- package/dist/actions/index.js.map +0 -1
- package/dist/actions/parsing.js.map +0 -1
- package/dist/actions/predicate-env.js +0 -27
- package/dist/actions/predicate-env.js.map +0 -1
- package/dist/actions/predicates.js +0 -49
- package/dist/actions/predicates.js.map +0 -1
- package/dist/actions/templating.js +0 -66
- package/dist/actions/templating.js.map +0 -1
- package/dist/actions/types.js +0 -15
- package/dist/actions/types.js.map +0 -1
- package/dist/agent/acp.js +0 -473
- package/dist/agent/acp.js.map +0 -1
- package/dist/agent/adapter-names.js +0 -159
- package/dist/agent/adapter-names.js.map +0 -1
- package/dist/agent/adapters.js +0 -511
- package/dist/agent/adapters.js.map +0 -1
- package/dist/agent/credential-extractors.js +0 -342
- package/dist/agent/credential-extractors.js.map +0 -1
- package/dist/agent/credential-secrets.js +0 -628
- package/dist/agent/credential-secrets.js.map +0 -1
- package/dist/agent/credential-ticker.js +0 -57
- package/dist/agent/credential-ticker.js.map +0 -1
- package/dist/agent/gondolin-creds-staging.js +0 -356
- package/dist/agent/gondolin-creds-staging.js.map +0 -1
- package/dist/agent/gondolin-dispatch.js +0 -375
- package/dist/agent/gondolin-dispatch.js.map +0 -1
- package/dist/agent/gondolin.js +0 -124
- package/dist/agent/gondolin.js.map +0 -1
- package/dist/agent/runner-decisions.js +0 -134
- package/dist/agent/runner-decisions.js.map +0 -1
- package/dist/agent/runner.js +0 -1456
- package/dist/agent/runner.js.map +0 -1
- package/dist/agent/tool-call-summary.js +0 -102
- package/dist/agent/tool-call-summary.js.map +0 -1
- package/dist/agent/vm-acp-mapping.js +0 -73
- package/dist/agent/vm-acp-mapping.js.map +0 -1
- package/dist/agent/vm-guards.js +0 -262
- package/dist/agent/vm-guards.js.map +0 -1
- package/dist/agent/vm-port.js +0 -22
- package/dist/agent/vm-port.js.map +0 -1
- package/dist/agent/vm-process-registry.js +0 -79
- package/dist/agent/vm-process-registry.js.map +0 -1
- package/dist/bin/cli-args.js +0 -105
- package/dist/bin/cli-args.js.map +0 -1
- package/dist/errors.js +0 -15
- package/dist/errors.js.map +0 -1
- package/dist/http-disk.js +0 -135
- package/dist/http-disk.js.map +0 -1
- package/dist/http-handlers.js.map +0 -1
- package/dist/http.js.map +0 -1
- package/dist/issues.js +0 -178
- package/dist/issues.js.map +0 -1
- package/dist/logging.js +0 -203
- package/dist/logging.js.map +0 -1
- package/dist/mcp.js +0 -706
- package/dist/mcp.js.map +0 -1
- package/dist/memory.js +0 -85
- package/dist/memory.js.map +0 -1
- package/dist/orchestrator-decisions.js +0 -331
- package/dist/orchestrator-decisions.js.map +0 -1
- package/dist/orchestrator.js +0 -1569
- package/dist/orchestrator.js.map +0 -1
- package/dist/prompt.js +0 -65
- package/dist/prompt.js.map +0 -1
- package/dist/reconciler/cache.js +0 -65
- package/dist/reconciler/cache.js.map +0 -1
- package/dist/reconciler/index.js +0 -448
- package/dist/reconciler/index.js.map +0 -1
- package/dist/reconciler/ledger.js +0 -131
- package/dist/reconciler/ledger.js.map +0 -1
- package/dist/reconciler/pr-adapters.js +0 -174
- package/dist/reconciler/pr-adapters.js.map +0 -1
- package/dist/reconciler/pr-decide.js.map +0 -1
- package/dist/reconciler/pr.js +0 -422
- package/dist/reconciler/pr.js.map +0 -1
- package/dist/reconciler/types.js +0 -12
- package/dist/reconciler/types.js.map +0 -1
- package/dist/reconciler/vm.js +0 -243
- package/dist/reconciler/vm.js.map +0 -1
- package/dist/reconciler/workspace-defaults.js +0 -83
- package/dist/reconciler/workspace-defaults.js.map +0 -1
- package/dist/reconciler/workspace.js +0 -272
- package/dist/reconciler/workspace.js.map +0 -1
- package/dist/runlog.js +0 -403
- package/dist/runlog.js.map +0 -1
- package/dist/scaffold.js +0 -165
- package/dist/scaffold.js.map +0 -1
- package/dist/trackers/local.js +0 -445
- package/dist/trackers/local.js.map +0 -1
- package/dist/trackers/types.js +0 -10
- package/dist/trackers/types.js.map +0 -1
- package/dist/types.js +0 -3
- package/dist/types.js.map +0 -1
- package/dist/util/clock.js +0 -12
- package/dist/util/clock.js.map +0 -1
- package/dist/util/crypto.js +0 -25
- package/dist/util/crypto.js.map +0 -1
- package/dist/util/frontmatter.js +0 -70
- package/dist/util/frontmatter.js.map +0 -1
- package/dist/util/fs-issues.js +0 -22
- package/dist/util/fs-issues.js.map +0 -1
- package/dist/util/process.js +0 -152
- package/dist/util/process.js.map +0 -1
- package/dist/util/workspace-key.js +0 -10
- package/dist/util/workspace-key.js.map +0 -1
- package/dist/workflow-loader.js +0 -147
- package/dist/workflow-loader.js.map +0 -1
- package/dist/workflow.js +0 -822
- package/dist/workflow.js.map +0 -1
- package/dist/workspace-types.js +0 -8
- package/dist/workspace-types.js.map +0 -1
- package/dist/workspace.js +0 -443
- package/dist/workspace.js.map +0 -1
package/dist/reconciler/vm.js
DELETED
|
@@ -1,243 +0,0 @@
|
|
|
1
|
-
// VM reaper resource (issue 33 / reconciler stage 2; Gondolin migration Phase 4).
|
|
2
|
-
// Owns the lifecycle of `symphony-*` VMs: anything outside the orchestrator's
|
|
3
|
-
// intended set is an orphan and gets reaped.
|
|
4
|
-
//
|
|
5
|
-
// Observation source = Gondolin's session registry, NOT the earlier CLI machine
|
|
6
|
-
// registry + `_boot-vm` /proc scraping. Gondolin owns one host runner process
|
|
7
|
-
// per VM and tracks it in a session registry keyed by uuid, carrying the
|
|
8
|
-
// `sessionLabel` the orchestrator minted (`symphony-<identifier>`) and the host
|
|
9
|
-
// `pid`. The reaper reaps in two complementary ways:
|
|
10
|
-
//
|
|
11
|
-
// 1. STALE sessions (dead-pid orphans + orphan socket files) are collected by
|
|
12
|
-
// Gondolin's own `gc()` — the shell calls it at the start of each pass.
|
|
13
|
-
// This subsumes the old "`machine delete -f` succeeded but left the worker
|
|
14
|
-
// alive" cleanup: Gondolin reconciles its own registry against live pids.
|
|
15
|
-
// 2. LIVE orphans — a session whose host process is still alive but whose
|
|
16
|
-
// `symphony-` label is NOT in the intended set (a botched teardown, or a
|
|
17
|
-
// SIGKILL'd symphony whose runner child survived) — are reaped HERE by
|
|
18
|
-
// SIGTERM→SIGKILL on the host `pid`. `gc()` can't touch these because the
|
|
19
|
-
// pid is alive; only the orchestrator knows the intended set.
|
|
20
|
-
//
|
|
21
|
-
// Label safety: a session with no label, or a label outside the
|
|
22
|
-
// `symphony-` namespace (an operator's own VM, a sibling tool's session), is
|
|
23
|
-
// never touched. The reaper acts only on confidently-symphony-owned, never-
|
|
24
|
-
// intended sessions.
|
|
25
|
-
//
|
|
26
|
-
// Effects-as-data (issue 69): the decision of WHAT to do is a pure function
|
|
27
|
-
// (`decideVm`) of the observed session state; HOW it's done (Gondolin gc,
|
|
28
|
-
// listSessions, process.kill, sleep) is the shell's job. This module is
|
|
29
|
-
// import-pure: no `node:fs`, no timers, no adapter imports. The reaper's local
|
|
30
|
-
// session shape (`ReaperSession`) is declared here — mirroring the existing
|
|
31
|
-
// `VmRegistryPort` local-interface convention — so vm.ts never reaches for the
|
|
32
|
-
// concrete `VmClient` adapter or the `vm-port` module; the shell adapts
|
|
33
|
-
// `VmClient.listSessions()` → `ReaperSession[]`.
|
|
34
|
-
import { log } from '../logging.js';
|
|
35
|
-
import { ResourceActionLedger } from './ledger.js';
|
|
36
|
-
// Domain constant. Every VM the orchestrator creates is labelled with this
|
|
37
|
-
// prefix (the runner mints `sessionLabel = symphony-<identifier>`); the reaper
|
|
38
|
-
// only acts on labels that match. The vm-port adapter mirrors the same value —
|
|
39
|
-
// keep them in sync.
|
|
40
|
-
export const SYMPHONY_VM_PREFIX = 'symphony-';
|
|
41
|
-
const DEFAULT_KILL_GRACE_MS = 3_000;
|
|
42
|
-
const MAX_ACTION_HISTORY = 32;
|
|
43
|
-
/**
|
|
44
|
-
* Pure decision: given the observed Gondolin session state, return the effects
|
|
45
|
-
* the shell should apply. No IO, no clock reads, no logging.
|
|
46
|
-
*
|
|
47
|
-
* Effect rule:
|
|
48
|
-
* • Session has a `label` that starts with SYMPHONY_VM_PREFIX and isn't
|
|
49
|
-
* intended, AND a sane, non-self host pid → `kill_session` (SIGTERM→SIGKILL
|
|
50
|
-
* its host pid).
|
|
51
|
-
*
|
|
52
|
-
* Pid safety: a host signal is only ever emitted for a `pid` that is a safe
|
|
53
|
-
* positive integer and is NOT the reaper's own pid. This matters because the
|
|
54
|
-
* shell delivers the signal with `process.kill(pid, sig)`, which signals the
|
|
55
|
-
* whole PROCESS GROUP for `pid <= 0` and would target the orchestrator itself
|
|
56
|
-
* for `pid === selfPid`. A session carrying a `0`/`NaN`/negative/self pid is a
|
|
57
|
-
* registry anomaly, never a legitimate orphan, so it is left untouched here.
|
|
58
|
-
*
|
|
59
|
-
* Anything outside the symphony-prefixed namespace — a session with no label,
|
|
60
|
-
* or a label that doesn't start with the prefix — is left untouched (operator
|
|
61
|
-
* VMs, sibling tools' sessions). STALE/dead-pid sessions and orphan sockets are
|
|
62
|
-
* NOT this function's concern; Gondolin's `gc()` collects them in the shell
|
|
63
|
-
* before the live session set reaches here.
|
|
64
|
-
*/
|
|
65
|
-
export function decideVm(state) {
|
|
66
|
-
const out = [];
|
|
67
|
-
for (const s of state.sessions) {
|
|
68
|
-
const label = s.label;
|
|
69
|
-
if (label === undefined)
|
|
70
|
-
continue;
|
|
71
|
-
if (!label.startsWith(SYMPHONY_VM_PREFIX))
|
|
72
|
-
continue;
|
|
73
|
-
if (state.intended.has(label))
|
|
74
|
-
continue;
|
|
75
|
-
// Pid safety: skip anomalous pids (0/NaN/negative — process-group / invalid)
|
|
76
|
-
// and never signal the reaper's own process.
|
|
77
|
-
if (!Number.isSafeInteger(s.pid) || s.pid <= 0)
|
|
78
|
-
continue;
|
|
79
|
-
if (s.pid === state.selfPid)
|
|
80
|
-
continue;
|
|
81
|
-
out.push({ kind: 'kill_session', pid: s.pid, label });
|
|
82
|
-
}
|
|
83
|
-
return out;
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* VM resource. Desired = orchestrator's intended VM (session-label) set.
|
|
87
|
-
* Actual = Gondolin's live session set (filtered by `symphony-` label).
|
|
88
|
-
* `reconcile()` is the thin shell loop: gc → observe → `decideVm` → apply.
|
|
89
|
-
*
|
|
90
|
-
* Independent of bake (`dependsOn: []`). Doesn't gate dispatch.
|
|
91
|
-
*/
|
|
92
|
-
export class VmResource {
|
|
93
|
-
opts;
|
|
94
|
-
id = 'vm';
|
|
95
|
-
dependsOn = [];
|
|
96
|
-
gc;
|
|
97
|
-
listSessions;
|
|
98
|
-
killProcess;
|
|
99
|
-
killGraceMs;
|
|
100
|
-
selfPid;
|
|
101
|
-
ledger = new ResourceActionLedger(this.id, { maxHistory: MAX_ACTION_HISTORY });
|
|
102
|
-
lastError = null;
|
|
103
|
-
constructor(opts) {
|
|
104
|
-
this.opts = opts;
|
|
105
|
-
this.gc = opts.gc;
|
|
106
|
-
this.listSessions = opts.listSessions;
|
|
107
|
-
this.killProcess = opts.killProcess;
|
|
108
|
-
this.killGraceMs = opts.killGraceMs ?? DEFAULT_KILL_GRACE_MS;
|
|
109
|
-
this.selfPid = opts.selfPid;
|
|
110
|
-
}
|
|
111
|
-
ready() {
|
|
112
|
-
// VM reaping is a janitorial task — it doesn't gate dispatch. The bake
|
|
113
|
-
// resource is the only thing dispatch waits on today; reaping just runs
|
|
114
|
-
// alongside.
|
|
115
|
-
return true;
|
|
116
|
-
}
|
|
117
|
-
async reconcile() {
|
|
118
|
-
const desired = this.opts.intended.intendedVmNames();
|
|
119
|
-
// Gondolin's own GC first: collect STALE (dead-pid) sessions + orphan
|
|
120
|
-
// sockets. This subsumes the earlier "worker survived the daemon
|
|
121
|
-
// destroy" cleanup — Gondolin reconciles its registry against live pids.
|
|
122
|
-
await this.runGc();
|
|
123
|
-
// Now enumerate the LIVE session set. `decideVm` compares it against the
|
|
124
|
-
// intended set; survivors with a never-intended `symphony-` label are
|
|
125
|
-
// LIVE orphans (alive pid, so gc() can't reach them) and get SIGTERM'd.
|
|
126
|
-
const sessions = await this.observeSessions();
|
|
127
|
-
const effects = decideVm({ intended: desired, sessions, selfPid: this.selfPid });
|
|
128
|
-
if (effects.length === 0)
|
|
129
|
-
return;
|
|
130
|
-
log.info('vm reaper: killing orphan sessions', { orphans: effects.length });
|
|
131
|
-
await Promise.all(effects.map((e) => this.killSession(e)));
|
|
132
|
-
}
|
|
133
|
-
snapshot() {
|
|
134
|
-
return {
|
|
135
|
-
id: this.id,
|
|
136
|
-
ready: true,
|
|
137
|
-
desired_hash: null,
|
|
138
|
-
last_error: this.lastError,
|
|
139
|
-
actions: this.ledger.snapshot(),
|
|
140
|
-
};
|
|
141
|
-
}
|
|
142
|
-
async runGc() {
|
|
143
|
-
try {
|
|
144
|
-
const reaped = await this.gc();
|
|
145
|
-
if (reaped > 0)
|
|
146
|
-
log.info('vm reaper: gondolin gc collected stale sessions', { reaped });
|
|
147
|
-
}
|
|
148
|
-
catch (err) {
|
|
149
|
-
const msg = err.message;
|
|
150
|
-
this.lastError = `gondolin gc failed: ${msg}`;
|
|
151
|
-
log.warn('vm reaper: gondolin gc failed', { error: msg });
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
async observeSessions() {
|
|
155
|
-
try {
|
|
156
|
-
return await this.listSessions();
|
|
157
|
-
}
|
|
158
|
-
catch (err) {
|
|
159
|
-
const msg = err.message;
|
|
160
|
-
this.lastError = `session enumeration failed: ${msg}`;
|
|
161
|
-
log.warn('vm reaper: session enumeration failed', { error: msg });
|
|
162
|
-
return [];
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
async killSession(e) {
|
|
166
|
-
const key = `kill_session:${e.pid}`;
|
|
167
|
-
// Belt-and-suspenders: `decideVm` already excludes self / anomalous pids,
|
|
168
|
-
// but a bad pid reaching the actual `process.kill` is catastrophic
|
|
169
|
-
// (`pid <= 0` signals the whole process group; `selfPid` signals the
|
|
170
|
-
// orchestrator). Guard once more before the signal ever leaves the shell.
|
|
171
|
-
if (e.pid === this.selfPid || !Number.isSafeInteger(e.pid) || e.pid <= 0) {
|
|
172
|
-
const msg = `refused to signal unsafe pid ${e.pid}`;
|
|
173
|
-
this.lastError = msg;
|
|
174
|
-
this.ledger.start(key);
|
|
175
|
-
this.ledger.error(key, msg);
|
|
176
|
-
log.warn('vm reaper: refused unsafe pid', { pid: e.pid, label: e.label, self_pid: this.selfPid });
|
|
177
|
-
return;
|
|
178
|
-
}
|
|
179
|
-
this.ledger.start(key);
|
|
180
|
-
// SIGTERM. If the process is already gone (ESRCH) treat as success.
|
|
181
|
-
try {
|
|
182
|
-
this.killProcess(e.pid, 'SIGTERM');
|
|
183
|
-
}
|
|
184
|
-
catch (err) {
|
|
185
|
-
const code = err.code;
|
|
186
|
-
if (code === 'ESRCH') {
|
|
187
|
-
this.ledger.done(key);
|
|
188
|
-
return;
|
|
189
|
-
}
|
|
190
|
-
const msg = err.message;
|
|
191
|
-
this.lastError = msg;
|
|
192
|
-
this.ledger.error(key, msg);
|
|
193
|
-
log.warn('vm reaper: SIGTERM failed', { pid: e.pid, label: e.label, error: msg });
|
|
194
|
-
return;
|
|
195
|
-
}
|
|
196
|
-
// Inline timer (rather than `node:timers/promises`) keeps the file
|
|
197
|
-
// adapter-import-free for the functional-core lint.
|
|
198
|
-
await new Promise((resolve) => { setTimeout(resolve, this.killGraceMs); });
|
|
199
|
-
// Probe with signal 0 — throws ESRCH if the process has exited. If it's
|
|
200
|
-
// still alive, escalate to SIGKILL.
|
|
201
|
-
let alive = false;
|
|
202
|
-
try {
|
|
203
|
-
this.killProcess(e.pid, 0);
|
|
204
|
-
alive = true;
|
|
205
|
-
}
|
|
206
|
-
catch (err) {
|
|
207
|
-
const code = err.code;
|
|
208
|
-
if (code !== 'ESRCH') {
|
|
209
|
-
// EPERM and friends — assume alive but unkillable; surface as an error.
|
|
210
|
-
const msg = err.message;
|
|
211
|
-
this.lastError = msg;
|
|
212
|
-
this.ledger.error(key, msg);
|
|
213
|
-
log.warn('vm reaper: alive-probe failed', { pid: e.pid, error: msg });
|
|
214
|
-
return;
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
if (!alive) {
|
|
218
|
-
this.ledger.done(key);
|
|
219
|
-
return;
|
|
220
|
-
}
|
|
221
|
-
try {
|
|
222
|
-
this.killProcess(e.pid, 'SIGKILL');
|
|
223
|
-
this.ledger.done(key);
|
|
224
|
-
log.info('vm reaper: SIGKILL applied after grace', {
|
|
225
|
-
pid: e.pid,
|
|
226
|
-
label: e.label,
|
|
227
|
-
grace_ms: this.killGraceMs,
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
catch (err) {
|
|
231
|
-
const code = err.code;
|
|
232
|
-
if (code === 'ESRCH') {
|
|
233
|
-
this.ledger.done(key);
|
|
234
|
-
return;
|
|
235
|
-
}
|
|
236
|
-
const msg = err.message;
|
|
237
|
-
this.lastError = msg;
|
|
238
|
-
this.ledger.error(key, msg);
|
|
239
|
-
log.warn('vm reaper: SIGKILL failed', { pid: e.pid, label: e.label, error: msg });
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
//# sourceMappingURL=vm.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"vm.js","sourceRoot":"","sources":["../../src/reconciler/vm.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
// Workspace resource adapters (shell). Concrete fs + git implementations of
|
|
2
|
-
// the listing / inspection / removal ports declared on {@link WorkspaceResource}.
|
|
3
|
-
// Lifted from workspace.ts (issue 86) so the core resource no longer imports
|
|
4
|
-
// `node:fs/promises` or `util/process`. Production wiring lives in
|
|
5
|
-
// `reconciler/index.ts`; tests pass stubs and reach for these helpers only
|
|
6
|
-
// when they want the real fs/git path.
|
|
7
|
-
import { readdir, rm, stat } from 'node:fs/promises';
|
|
8
|
-
import path from 'node:path';
|
|
9
|
-
import { runProcess } from '../util/process.js';
|
|
10
|
-
/**
|
|
11
|
-
* Enumerate workspace dirs under `root`. Non-directories are filtered out.
|
|
12
|
-
* ENOENT on the root → empty list (cold start). Other errors propagate so the
|
|
13
|
-
* resource records them in `last_error` rather than reaping every workspace
|
|
14
|
-
* on a transient FS hiccup.
|
|
15
|
-
*/
|
|
16
|
-
export async function defaultListWorkspaceDirs(root) {
|
|
17
|
-
let entries;
|
|
18
|
-
try {
|
|
19
|
-
entries = await readdir(root);
|
|
20
|
-
}
|
|
21
|
-
catch (err) {
|
|
22
|
-
if (err.code === 'ENOENT')
|
|
23
|
-
return [];
|
|
24
|
-
throw err;
|
|
25
|
-
}
|
|
26
|
-
const out = [];
|
|
27
|
-
for (const name of entries) {
|
|
28
|
-
const p = path.join(root, name);
|
|
29
|
-
try {
|
|
30
|
-
const st = await stat(p);
|
|
31
|
-
if (st.isDirectory())
|
|
32
|
-
out.push({ name, path: p });
|
|
33
|
-
}
|
|
34
|
-
catch {
|
|
35
|
-
// Entry vanished mid-pass; next reconcile picks it up.
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
return out;
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Default inspector. All git invocations are workspace-local; drift detection
|
|
42
|
-
* lives in the resource (compares `workspaceBaseSha` to the source repo's
|
|
43
|
-
* current base SHA). Returns `head: null` for anything that doesn't look like
|
|
44
|
-
* a git repo — the caller treats that as "don't touch this dir."
|
|
45
|
-
*/
|
|
46
|
-
export async function defaultInspectWorkspace(workspacePath, baseBranch) {
|
|
47
|
-
const head = await runGitCapture(workspacePath, ['rev-parse', 'HEAD']);
|
|
48
|
-
if (head.exit !== 0 || head.stdout.trim().length === 0) {
|
|
49
|
-
return { head: null, workspaceBaseSha: null, hasUncommitted: false, commitsAheadOfBase: 0 };
|
|
50
|
-
}
|
|
51
|
-
const headSha = head.stdout.trim();
|
|
52
|
-
const status = await runGitCapture(workspacePath, ['status', '--porcelain']);
|
|
53
|
-
const hasUncommitted = status.exit === 0 && status.stdout.length > 0;
|
|
54
|
-
// Workspace's frozen view of the base branch — the SHA that was current in
|
|
55
|
-
// the source repo at clone time. The setup pipeline cuts the agent branch
|
|
56
|
-
// from this ref, so it's always present unless an operator manually deleted it.
|
|
57
|
-
const wsBase = await runGitCapture(workspacePath, ['rev-parse', baseBranch]);
|
|
58
|
-
const workspaceBaseSha = wsBase.exit === 0 && wsBase.stdout.trim().length > 0 ? wsBase.stdout.trim() : null;
|
|
59
|
-
let aheadCount = 0;
|
|
60
|
-
if (workspaceBaseSha !== null) {
|
|
61
|
-
// `<base>..HEAD` walks only objects the workspace itself owns — no cross-repo
|
|
62
|
-
// reachability needed. Exits non-zero only for malformed refs; treat that
|
|
63
|
-
// as 0 commits ahead rather than poisoning the snapshot.
|
|
64
|
-
const ahead = await runGitCapture(workspacePath, [
|
|
65
|
-
'rev-list',
|
|
66
|
-
'--count',
|
|
67
|
-
`${workspaceBaseSha}..${headSha}`,
|
|
68
|
-
]);
|
|
69
|
-
aheadCount = ahead.exit === 0 ? Number(ahead.stdout.trim()) || 0 : 0;
|
|
70
|
-
}
|
|
71
|
-
return { head: headSha, workspaceBaseSha, hasUncommitted, commitsAheadOfBase: aheadCount };
|
|
72
|
-
}
|
|
73
|
-
/** Default removal: `rm -rf` the dir. Production wraps `WorkspaceManager.remove`; the two-callback design lets tests pass a stub. */
|
|
74
|
-
export async function defaultRemoveWorkspace(workspaceRoot, identifier) {
|
|
75
|
-
await rm(path.join(workspaceRoot, identifier), { recursive: true, force: true });
|
|
76
|
-
}
|
|
77
|
-
// Thin shape adapter over runProcess: the inspector reads `result.exit`
|
|
78
|
-
// (vs. `exit_code`) and uses a tighter 16 KiB cap than runProcess's default.
|
|
79
|
-
async function runGitCapture(cwd, args) {
|
|
80
|
-
const r = await runProcess('git', args, { cwd, maxBytes: 16_384, appendErrorToStderr: false });
|
|
81
|
-
return { exit: r.exit_code ?? -1, stdout: r.stdout, stderr: r.stderr };
|
|
82
|
-
}
|
|
83
|
-
//# sourceMappingURL=workspace-defaults.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"workspace-defaults.js","sourceRoot":"","sources":["../../src/reconciler/workspace-defaults.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,272 +0,0 @@
|
|
|
1
|
-
// Workspace resource (issue 34 / reconciler stage 3). Owns the lifecycle of
|
|
2
|
-
// per-issue workspace directories under `workspace.root`. Replaces the
|
|
3
|
-
// orchestrator's old `startupTerminalCleanup` sweep with a continuous-converge
|
|
4
|
-
// resource that also surfaces drift between an active workspace's HEAD and the
|
|
5
|
-
// current base branch tip.
|
|
6
|
-
//
|
|
7
|
-
// What this resource owns:
|
|
8
|
-
// • Removing workspace dirs that no longer correspond to any non-terminal
|
|
9
|
-
// issue file. The old startup sweep only fired once on boot; here it runs
|
|
10
|
-
// on every reconcile tick.
|
|
11
|
-
// • Creating workspace dirs for non-terminal issues that don't yet have one
|
|
12
|
-
// on disk. The action body (clone source repo, cut `agent/<id>`, optional
|
|
13
|
-
// origin restore) is delegated to `WorkspaceManager.ensureFor` so
|
|
14
|
-
// dispatch-time and reconciler-driven eager creation share a single code
|
|
15
|
-
// path. Idempotency / race safety is enforced inside `ensureFor` via a
|
|
16
|
-
// per-identifier in-flight promise lock.
|
|
17
|
-
// • Reporting drift between an active workspace's HEAD and the current
|
|
18
|
-
// base-branch tip (e.g. base advanced while the issue was paused). v1 is
|
|
19
|
-
// non-destructive: drift is surfaced as a `stale` / `stuck` annotation in
|
|
20
|
-
// the snapshot and the workspace is left on disk. Re-clone (or any other
|
|
21
|
-
// destructive recovery) is explicitly opt-in via an operator action or
|
|
22
|
-
// per-issue label and is out of scope for this stage.
|
|
23
|
-
//
|
|
24
|
-
// Race-condition rule (same shape as VmResource): the intended set comes
|
|
25
|
-
// from a provider the orchestrator implements. It returns both the active
|
|
26
|
-
// issue identifiers (long-lived desired set) AND the identifiers currently
|
|
27
|
-
// in-flight (running + claimed). The in-flight slice covers the window
|
|
28
|
-
// between "tick claims an issue" and "tracker shows it as active" — without
|
|
29
|
-
// it, a brand-new issue's workspace could be reaped seconds after creation
|
|
30
|
-
// because the reconciler raced ahead of the tracker read.
|
|
31
|
-
import { sanitizeWorkspaceKey } from '../util/workspace-key.js';
|
|
32
|
-
import { log } from '../logging.js';
|
|
33
|
-
import { ResourceActionLedger } from './ledger.js';
|
|
34
|
-
const MAX_ACTION_HISTORY = 32;
|
|
35
|
-
/**
|
|
36
|
-
* Workspace resource. Desired = active issue workspaces (set of sanitized
|
|
37
|
-
* identifiers from the tracker plus in-flight allocations). Actual = dirs
|
|
38
|
-
* under `workspace.root`. Diff drives two converging actions plus two
|
|
39
|
-
* snapshot annotations:
|
|
40
|
-
*
|
|
41
|
-
* • create_workspace — identifier in the desired set with no matching dir
|
|
42
|
-
* on disk. Delegates to `WorkspaceManager.ensureFor`,
|
|
43
|
-
* which runs the canonical clone+branch+remote setup.
|
|
44
|
-
* • remove_workspace — dir has no matching non-terminal issue.
|
|
45
|
-
* • mark_stale — dir matches but HEAD is behind base and the
|
|
46
|
-
* workspace has no uncommitted / ahead work. Non-
|
|
47
|
-
* destructive: re-clone is operator-triggered in v1.
|
|
48
|
-
* • mark_stuck — dir matches but HEAD is behind base AND has
|
|
49
|
-
* uncommitted changes or commits ahead of base. Non-
|
|
50
|
-
* destructive; surfaced so the operator can intervene
|
|
51
|
-
* before any rebuild attempt.
|
|
52
|
-
*
|
|
53
|
-
* `dependsOn: ['base_ref']` is informational. v1 doesn't ship a base_ref
|
|
54
|
-
* resource; the BaseRefProvider is a direct dependency call.
|
|
55
|
-
*/
|
|
56
|
-
export class WorkspaceResource {
|
|
57
|
-
opts;
|
|
58
|
-
id = 'workspace';
|
|
59
|
-
dependsOn = [];
|
|
60
|
-
ledger = new ResourceActionLedger(this.id, { maxHistory: MAX_ACTION_HISTORY });
|
|
61
|
-
lastError = null;
|
|
62
|
-
staleCount = 0;
|
|
63
|
-
stuckCount = 0;
|
|
64
|
-
createdCount = 0;
|
|
65
|
-
constructor(opts) {
|
|
66
|
-
this.opts = opts;
|
|
67
|
-
}
|
|
68
|
-
ready() {
|
|
69
|
-
// Janitorial; doesn't gate dispatch (bake is the only dispatch gate today).
|
|
70
|
-
return true;
|
|
71
|
-
}
|
|
72
|
-
async reconcile() {
|
|
73
|
-
// Read the desired set up front. Even if `listWorkspaces` returns the
|
|
74
|
-
// empty set (workspace.root not yet created), we still want to create
|
|
75
|
-
// dirs for every active identifier — the create path will mkdir the root
|
|
76
|
-
// via `ensureFor`. Pulling this before the listing collapses the two
|
|
77
|
-
// branches into one flow.
|
|
78
|
-
//
|
|
79
|
-
// Fail closed when the tracker read throws: we must NOT treat the empty
|
|
80
|
-
// set as the desired state. Reaping every workspace on a transient
|
|
81
|
-
// tracker hiccup is the regression this contract closes. Catch here,
|
|
82
|
-
// surface as last_error, and bail — the next pass retries.
|
|
83
|
-
let active;
|
|
84
|
-
try {
|
|
85
|
-
active = await this.opts.intended.activeIdentifiers();
|
|
86
|
-
}
|
|
87
|
-
catch (err) {
|
|
88
|
-
const msg = err.message;
|
|
89
|
-
this.lastError = `active_fetch_failed: ${msg}`;
|
|
90
|
-
log.warn('workspace reconcile: active fetch failed', { error: msg });
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
const inFlight = this.opts.intended.inFlightIdentifiers();
|
|
94
|
-
// Map sanitized key → { identifier, state } so the create callback gets
|
|
95
|
-
// the operator-visible identifier AND the current state name (used by the
|
|
96
|
-
// orchestrator's merge-state guard). Sanitize-then-set so
|
|
97
|
-
// the dir-name comparison matches `workspacePathFor`'s post-sanitize
|
|
98
|
-
// layout. Active issues take precedence over in-flight in case of
|
|
99
|
-
// overlap so the tracker's authoritative state wins over an in-flight
|
|
100
|
-
// entry that may carry a target_state (where the issue is going, not
|
|
101
|
-
// where it currently lives).
|
|
102
|
-
const wanted = new Map();
|
|
103
|
-
for (const [id, state] of inFlight) {
|
|
104
|
-
wanted.set(sanitizeWorkspaceKey(id), { identifier: id, state });
|
|
105
|
-
}
|
|
106
|
-
for (const [id, state] of active) {
|
|
107
|
-
wanted.set(sanitizeWorkspaceKey(id), { identifier: id, state });
|
|
108
|
-
}
|
|
109
|
-
let entries;
|
|
110
|
-
try {
|
|
111
|
-
entries = await this.opts.listWorkspaces();
|
|
112
|
-
}
|
|
113
|
-
catch (err) {
|
|
114
|
-
this.lastError = `workspace_root_read_failed: ${err.message}`;
|
|
115
|
-
log.warn('workspace reconcile: list failed', { error: err.message });
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
let baseRef = null;
|
|
119
|
-
if (this.opts.baseRef) {
|
|
120
|
-
try {
|
|
121
|
-
baseRef = await this.opts.baseRef.currentBaseRef();
|
|
122
|
-
}
|
|
123
|
-
catch (err) {
|
|
124
|
-
log.debug('workspace reconcile: base ref lookup failed', {
|
|
125
|
-
error: err.message,
|
|
126
|
-
});
|
|
127
|
-
baseRef = null;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
this.staleCount = 0;
|
|
131
|
-
this.stuckCount = 0;
|
|
132
|
-
this.createdCount = 0;
|
|
133
|
-
// Reset lastError at the start of every pass so a transient stale/stuck
|
|
134
|
-
// condition that has since resolved doesn't keep haunting the snapshot.
|
|
135
|
-
// Errors raised during this pass below will repopulate it.
|
|
136
|
-
this.lastError = null;
|
|
137
|
-
// Track which desired identifiers already exist on disk so the
|
|
138
|
-
// create-loop below only fires for the missing ones.
|
|
139
|
-
const present = new Set();
|
|
140
|
-
for (const { name, path: dirPath } of entries) {
|
|
141
|
-
if (!wanted.has(name)) {
|
|
142
|
-
await this.runRemove(name, 'stale_issue');
|
|
143
|
-
continue;
|
|
144
|
-
}
|
|
145
|
-
present.add(name);
|
|
146
|
-
// In the desired set. Check for drift (non-destructive). No baseRef
|
|
147
|
-
// means we can't compare; just skip and treat the workspace as ok.
|
|
148
|
-
if (baseRef === null)
|
|
149
|
-
continue;
|
|
150
|
-
let inspection;
|
|
151
|
-
try {
|
|
152
|
-
inspection = await this.opts.inspect(dirPath, baseRef.branch);
|
|
153
|
-
}
|
|
154
|
-
catch (err) {
|
|
155
|
-
log.debug('workspace reconcile: inspect failed', {
|
|
156
|
-
identifier: name,
|
|
157
|
-
error: err.message,
|
|
158
|
-
});
|
|
159
|
-
continue;
|
|
160
|
-
}
|
|
161
|
-
if (inspection.head === null)
|
|
162
|
-
continue;
|
|
163
|
-
// Workspace has no local copy of the base branch — operator likely
|
|
164
|
-
// deleted it. Skip drift detection rather than guess.
|
|
165
|
-
if (inspection.workspaceBaseSha === null)
|
|
166
|
-
continue;
|
|
167
|
-
// Drift = workspace's frozen base SHA disagrees with source's current
|
|
168
|
-
// base SHA. Any disagreement counts (fast-forward, divergence, rewind
|
|
169
|
-
// all surface as "the operator's base moved out from under us"); the
|
|
170
|
-
// operator can decide what to do.
|
|
171
|
-
if (inspection.workspaceBaseSha === baseRef.sha)
|
|
172
|
-
continue;
|
|
173
|
-
// Drift detected. v1 never auto-removes for drift; we annotate and move
|
|
174
|
-
// on so the operator can decide whether to relaunch the workspace.
|
|
175
|
-
if (inspection.hasUncommitted || inspection.commitsAheadOfBase > 0) {
|
|
176
|
-
this.stuckCount += 1;
|
|
177
|
-
const reason = inspection.hasUncommitted
|
|
178
|
-
? 'uncommitted changes present'
|
|
179
|
-
: `${inspection.commitsAheadOfBase} commit(s) ahead of base`;
|
|
180
|
-
const msg = `workspace ${name} stuck: base advanced and ${reason}`;
|
|
181
|
-
this.lastError = msg;
|
|
182
|
-
this.recordMark(name, 'stuck', reason);
|
|
183
|
-
log.warn('workspace reconcile: stuck (drift, agent work present)', {
|
|
184
|
-
identifier: name,
|
|
185
|
-
reason,
|
|
186
|
-
});
|
|
187
|
-
continue;
|
|
188
|
-
}
|
|
189
|
-
this.staleCount += 1;
|
|
190
|
-
const staleReason = 'base advanced past workspace HEAD; re-clone is opt-in';
|
|
191
|
-
this.lastError = `workspace ${name} stale: ${staleReason}`;
|
|
192
|
-
this.recordMark(name, 'stale', staleReason);
|
|
193
|
-
log.info('workspace reconcile: stale (drift, no agent work to lose)', {
|
|
194
|
-
identifier: name,
|
|
195
|
-
reason: staleReason,
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
|
-
// Create any desired identifier that has no dir on disk. The create
|
|
199
|
-
// callback is optional so test harnesses that exercise only the reaper
|
|
200
|
-
// can skip it; production wires `WorkspaceManager.ensureFor`, which is
|
|
201
|
-
// idempotent (per-identifier lock + dir-exists check) so a concurrent
|
|
202
|
-
// dispatch call coalesces into the same setup pass.
|
|
203
|
-
if (this.opts.create) {
|
|
204
|
-
for (const [key, { identifier, state }] of wanted) {
|
|
205
|
-
if (present.has(key))
|
|
206
|
-
continue;
|
|
207
|
-
await this.runCreate(identifier, key, state);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
snapshot() {
|
|
212
|
-
return {
|
|
213
|
-
id: this.id,
|
|
214
|
-
ready: true,
|
|
215
|
-
desired_hash: null,
|
|
216
|
-
last_error: this.lastError,
|
|
217
|
-
actions: this.ledger.snapshot(),
|
|
218
|
-
};
|
|
219
|
-
}
|
|
220
|
-
/** Test helper: number of workspaces marked stale on the last reconcile pass. */
|
|
221
|
-
staleOnLastPass() {
|
|
222
|
-
return this.staleCount;
|
|
223
|
-
}
|
|
224
|
-
/** Test helper: number of workspaces marked stuck on the last reconcile pass. */
|
|
225
|
-
stuckOnLastPass() {
|
|
226
|
-
return this.stuckCount;
|
|
227
|
-
}
|
|
228
|
-
/** Test helper: number of workspaces created on the last reconcile pass. */
|
|
229
|
-
createdOnLastPass() {
|
|
230
|
-
return this.createdCount;
|
|
231
|
-
}
|
|
232
|
-
async runCreate(identifier, sanitizedKey, state) {
|
|
233
|
-
if (!this.opts.create)
|
|
234
|
-
return;
|
|
235
|
-
// Action key uses the sanitized identifier (matches what
|
|
236
|
-
// remove_workspace uses) so dashboards can correlate the two
|
|
237
|
-
// operations on the same workspace dir.
|
|
238
|
-
const actionKey = `create_workspace:${sanitizedKey}`;
|
|
239
|
-
const res = await this.ledger.run(actionKey, () => this.opts.create(identifier, state));
|
|
240
|
-
if (res.ok) {
|
|
241
|
-
this.createdCount += 1;
|
|
242
|
-
log.info('workspace reconcile: created', { identifier, state });
|
|
243
|
-
}
|
|
244
|
-
else {
|
|
245
|
-
this.lastError = res.error;
|
|
246
|
-
log.warn('workspace reconcile: create failed', { identifier, state, error: res.error });
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
async runRemove(identifier, reason) {
|
|
250
|
-
const actionKey = `remove_workspace:${identifier}`;
|
|
251
|
-
const res = await this.ledger.run(actionKey, () => this.opts.remove(identifier, reason));
|
|
252
|
-
if (res.ok) {
|
|
253
|
-
log.info('workspace reconcile: removed', { identifier, reason });
|
|
254
|
-
}
|
|
255
|
-
else {
|
|
256
|
-
this.lastError = res.error;
|
|
257
|
-
log.warn('workspace reconcile: remove failed', { identifier, reason, error: res.error });
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
/**
|
|
261
|
-
* Record a non-destructive drift annotation in the action ledger so the
|
|
262
|
-
* dashboard can render "stale" / "stuck" badges per workspace without the
|
|
263
|
-
* janitor touching disk. `mark_stale:<id>` and `mark_stuck:<id>` are the
|
|
264
|
-
* v1 surfaces; the reason rides on the action's `error` field for parity
|
|
265
|
-
* with the existing snapshot-error shape, even though it isn't a hard
|
|
266
|
-
* failure.
|
|
267
|
-
*/
|
|
268
|
-
recordMark(identifier, status, reason) {
|
|
269
|
-
this.ledger.record(`mark_${status}:${identifier}`, 'done', reason);
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
//# sourceMappingURL=workspace.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../src/reconciler/workspace.ts"],"names":[],"mappings":"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"}
|