smol-symphony 0.2.0 → 0.3.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 +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/src/bin/symphony.js +30 -0
- package/dist/src/bin/symphony.js.map +1 -0
- package/dist/src/core/actions/context.js +109 -0
- package/dist/src/core/actions/context.js.map +1 -0
- package/dist/{actions/parsing.js → src/core/actions/parse.js} +33 -114
- package/dist/src/core/actions/parse.js.map +1 -0
- package/dist/src/core/actions/plan.js +197 -0
- package/dist/src/core/actions/plan.js.map +1 -0
- package/dist/src/core/actions/predicates.js +111 -0
- package/dist/src/core/actions/predicates.js.map +1 -0
- package/dist/src/core/actions/run-fold.js +248 -0
- package/dist/src/core/actions/run-fold.js.map +1 -0
- package/dist/src/core/actions/template.js +118 -0
- package/dist/src/core/actions/template.js.map +1 -0
- package/dist/src/core/cli/args.js +116 -0
- package/dist/src/core/cli/args.js.map +1 -0
- package/dist/src/core/coerce.js +75 -0
- package/dist/src/core/coerce.js.map +1 -0
- package/dist/src/core/credential/account-id.js +20 -0
- package/dist/src/core/credential/account-id.js.map +1 -0
- package/dist/src/core/credential/adapter-config.js +136 -0
- package/dist/src/core/credential/adapter-config.js.map +1 -0
- package/dist/src/core/credential/availability.js +98 -0
- package/dist/src/core/credential/availability.js.map +1 -0
- package/dist/src/core/credential/extract.js +228 -0
- package/dist/src/core/credential/extract.js.map +1 -0
- package/dist/src/core/credential/fake-creds.js +171 -0
- package/dist/src/core/credential/fake-creds.js.map +1 -0
- package/dist/src/core/credential/identity.js +125 -0
- package/dist/src/core/credential/identity.js.map +1 -0
- package/dist/src/core/credential/shape.js +230 -0
- package/dist/src/core/credential/shape.js.map +1 -0
- package/dist/src/core/credential/strings.js +15 -0
- package/dist/src/core/credential/strings.js.map +1 -0
- package/dist/src/core/doctor/checks.js +303 -0
- package/dist/src/core/doctor/checks.js.map +1 -0
- package/dist/src/core/git/result.js +107 -0
- package/dist/src/core/git/result.js.map +1 -0
- package/dist/src/core/http/decisions.js +225 -0
- package/dist/src/core/http/decisions.js.map +1 -0
- package/dist/{http.js → src/core/http/render.js} +472 -738
- package/dist/src/core/http/render.js.map +1 -0
- package/dist/{http-handlers.js → src/core/http/routes.js} +52 -87
- package/dist/src/core/http/routes.js.map +1 -0
- package/dist/src/core/http/views.js +181 -0
- package/dist/src/core/http/views.js.map +1 -0
- package/dist/src/core/image/managed-image.js +95 -0
- package/dist/src/core/image/managed-image.js.map +1 -0
- package/dist/src/core/issue/file.js +149 -0
- package/dist/src/core/issue/file.js.map +1 -0
- package/dist/src/core/issue/parse.js +210 -0
- package/dist/src/core/issue/parse.js.map +1 -0
- package/dist/src/core/mcp/dispatch.js +239 -0
- package/dist/src/core/mcp/dispatch.js.map +1 -0
- package/dist/src/core/mcp/post-move.js +92 -0
- package/dist/src/core/mcp/post-move.js.map +1 -0
- package/dist/src/core/mcp/protocol.js +293 -0
- package/dist/src/core/mcp/protocol.js.map +1 -0
- package/dist/src/core/mcp/url.js +162 -0
- package/dist/src/core/mcp/url.js.map +1 -0
- package/dist/src/core/path.js +63 -0
- package/dist/src/core/path.js.map +1 -0
- package/dist/src/core/reconcile/image-decide.js +48 -0
- package/dist/src/core/reconcile/image-decide.js.map +1 -0
- package/dist/src/core/reconcile/ledger.js +142 -0
- package/dist/src/core/reconcile/ledger.js.map +1 -0
- package/dist/src/core/reconcile/pr-classify.js +62 -0
- package/dist/src/core/reconcile/pr-classify.js.map +1 -0
- package/dist/{reconciler → src/core/reconcile}/pr-decide.js +25 -12
- package/dist/src/core/reconcile/pr-decide.js.map +1 -0
- package/dist/src/core/reconcile/pr-loop.js +161 -0
- package/dist/src/core/reconcile/pr-loop.js.map +1 -0
- package/dist/src/core/reconcile/pr-notes.js +35 -0
- package/dist/src/core/reconcile/pr-notes.js.map +1 -0
- package/dist/src/core/reconcile/vm-decide.js +70 -0
- package/dist/src/core/reconcile/vm-decide.js.map +1 -0
- package/dist/src/core/reconcile/vm-reap.js +207 -0
- package/dist/src/core/reconcile/vm-reap.js.map +1 -0
- package/dist/src/core/reconcile/workspace-decide.js +162 -0
- package/dist/src/core/reconcile/workspace-decide.js.map +1 -0
- package/dist/src/core/runlog/summary.js +231 -0
- package/dist/src/core/runlog/summary.js.map +1 -0
- package/dist/src/core/runner/dispatch-config.js +95 -0
- package/dist/src/core/runner/dispatch-config.js.map +1 -0
- package/dist/src/core/runner/injection.js +61 -0
- package/dist/src/core/runner/injection.js.map +1 -0
- package/dist/src/core/runner/mise.js +210 -0
- package/dist/src/core/runner/mise.js.map +1 -0
- package/dist/src/core/runner/prompt.js +720 -0
- package/dist/src/core/runner/prompt.js.map +1 -0
- package/dist/src/core/runner/turn.js +242 -0
- package/dist/src/core/runner/turn.js.map +1 -0
- package/dist/src/core/runner/vm-plan.js +390 -0
- package/dist/src/core/runner/vm-plan.js.map +1 -0
- package/dist/src/core/schedule/admission.js +123 -0
- package/dist/src/core/schedule/admission.js.map +1 -0
- package/dist/src/core/schedule/circuit-breaker.js +111 -0
- package/dist/src/core/schedule/circuit-breaker.js.map +1 -0
- package/dist/src/core/schedule/eligibility.js +83 -0
- package/dist/src/core/schedule/eligibility.js.map +1 -0
- package/dist/src/core/schedule/reconcile-issue.js +82 -0
- package/dist/src/core/schedule/reconcile-issue.js.map +1 -0
- package/dist/src/core/schedule/retry.js +96 -0
- package/dist/src/core/schedule/retry.js.map +1 -0
- package/dist/src/core/schedule/sleep-cycle.js +133 -0
- package/dist/src/core/schedule/sleep-cycle.js.map +1 -0
- package/dist/src/core/schedule/slots.js +124 -0
- package/dist/src/core/schedule/slots.js.map +1 -0
- package/dist/src/core/schedule/tick.js +553 -0
- package/dist/src/core/schedule/tick.js.map +1 -0
- package/dist/src/core/schedule/token-fold.js +181 -0
- package/dist/src/core/schedule/token-fold.js.map +1 -0
- package/dist/src/core/state-resolve.js +86 -0
- package/dist/src/core/state-resolve.js.map +1 -0
- package/dist/src/core/vm-guards.js +278 -0
- package/dist/src/core/vm-guards.js.map +1 -0
- package/dist/src/core/workflow/derive.js +107 -0
- package/dist/src/core/workflow/derive.js.map +1 -0
- package/dist/src/core/workflow/parse.js +687 -0
- package/dist/src/core/workflow/parse.js.map +1 -0
- package/dist/src/core/workflow/prompt-probe.js +78 -0
- package/dist/src/core/workflow/prompt-probe.js.map +1 -0
- package/dist/src/core/workflow/validate.js +189 -0
- package/dist/src/core/workflow/validate.js.map +1 -0
- package/dist/src/core/workspace-key.js +19 -0
- package/dist/src/core/workspace-key.js.map +1 -0
- package/dist/src/shell/actions-runner.js +356 -0
- package/dist/src/shell/actions-runner.js.map +1 -0
- package/dist/src/shell/adapter/adapter-registry.js +45 -0
- package/dist/src/shell/adapter/adapter-registry.js.map +1 -0
- package/dist/src/shell/adapter/clock-random.js +96 -0
- package/dist/src/shell/adapter/clock-random.js.map +1 -0
- package/dist/src/shell/adapter/gondolin-dispatch-helpers.js +158 -0
- package/dist/src/shell/adapter/gondolin-dispatch-helpers.js.map +1 -0
- package/dist/src/shell/adapter/gondolin-dispatch.js +385 -0
- package/dist/src/shell/adapter/gondolin-dispatch.js.map +1 -0
- package/dist/src/shell/adapter/gondolin-image-converter.js +233 -0
- package/dist/src/shell/adapter/gondolin-image-converter.js.map +1 -0
- package/dist/src/shell/adapter/gondolin-image-fetch.js +180 -0
- package/dist/src/shell/adapter/gondolin-image-fetch.js.map +1 -0
- package/dist/src/shell/adapter/launcher-asset.js +57 -0
- package/dist/src/shell/adapter/launcher-asset.js.map +1 -0
- package/dist/src/shell/adapter/mise-config-asset.js +65 -0
- package/dist/src/shell/adapter/mise-config-asset.js.map +1 -0
- package/dist/src/shell/adapter/workflow-loader.js +304 -0
- package/dist/src/shell/adapter/workflow-loader.js.map +1 -0
- package/dist/src/shell/cli/doctor.js +268 -0
- package/dist/src/shell/cli/doctor.js.map +1 -0
- package/dist/src/shell/effect-interpreter-families.js +314 -0
- package/dist/src/shell/effect-interpreter-families.js.map +1 -0
- package/dist/src/shell/effect-interpreter.js +29 -0
- package/dist/src/shell/effect-interpreter.js.map +1 -0
- package/dist/src/shell/interp/acp-frame.js +137 -0
- package/dist/src/shell/interp/acp-frame.js.map +1 -0
- package/dist/src/shell/interp/acp-ws-conn.js +320 -0
- package/dist/src/shell/interp/acp-ws-conn.js.map +1 -0
- package/dist/src/shell/interp/acp-ws-frames.js +159 -0
- package/dist/src/shell/interp/acp-ws-frames.js.map +1 -0
- package/dist/src/shell/interp/acp-ws.js +197 -0
- package/dist/src/shell/interp/acp-ws.js.map +1 -0
- package/dist/src/shell/interp/acp.js +319 -0
- package/dist/src/shell/interp/acp.js.map +1 -0
- package/dist/src/shell/interp/credential-defaults.js +128 -0
- package/dist/src/shell/interp/credential-defaults.js.map +1 -0
- package/dist/src/shell/interp/credential-hooks.js +149 -0
- package/dist/src/shell/interp/credential-hooks.js.map +1 -0
- package/dist/src/shell/interp/credential-registry.js +226 -0
- package/dist/src/shell/interp/credential-registry.js.map +1 -0
- package/dist/src/shell/interp/credential.js +103 -0
- package/dist/src/shell/interp/credential.js.map +1 -0
- package/dist/src/shell/interp/gh.js +163 -0
- package/dist/src/shell/interp/gh.js.map +1 -0
- package/dist/src/shell/interp/git.js +28 -0
- package/dist/src/shell/interp/git.js.map +1 -0
- package/dist/src/shell/interp/log.js +213 -0
- package/dist/src/shell/interp/log.js.map +1 -0
- package/dist/src/shell/interp/process.js +178 -0
- package/dist/src/shell/interp/process.js.map +1 -0
- package/dist/src/shell/interp/runlog.js +193 -0
- package/dist/src/shell/interp/runlog.js.map +1 -0
- package/dist/src/shell/interp/timer.js +64 -0
- package/dist/src/shell/interp/timer.js.map +1 -0
- package/dist/src/shell/interp/tracker-disk.js +99 -0
- package/dist/src/shell/interp/tracker-disk.js.map +1 -0
- package/dist/src/shell/interp/tracker-parse.js +71 -0
- package/dist/src/shell/interp/tracker-parse.js.map +1 -0
- package/dist/src/shell/interp/tracker-scan.js +238 -0
- package/dist/src/shell/interp/tracker-scan.js.map +1 -0
- package/dist/src/shell/interp/tracker-write.js +91 -0
- package/dist/src/shell/interp/tracker-write.js.map +1 -0
- package/dist/src/shell/interp/tracker.js +41 -0
- package/dist/src/shell/interp/tracker.js.map +1 -0
- package/dist/src/shell/interp/tty.js +48 -0
- package/dist/src/shell/interp/tty.js.map +1 -0
- package/dist/src/shell/interp/vm.js +199 -0
- package/dist/src/shell/interp/vm.js.map +1 -0
- package/dist/src/shell/interp/workspace.js +310 -0
- package/dist/src/shell/interp/workspace.js.map +1 -0
- package/dist/src/shell/main-acp.js +78 -0
- package/dist/src/shell/main-acp.js.map +1 -0
- package/dist/src/shell/main-adapters.js +222 -0
- package/dist/src/shell/main-adapters.js.map +1 -0
- package/dist/src/shell/main-credential.js +122 -0
- package/dist/src/shell/main-credential.js.map +1 -0
- package/dist/src/shell/main-doctor.js +22 -0
- package/dist/src/shell/main-doctor.js.map +1 -0
- package/dist/src/shell/main-entry.js +46 -0
- package/dist/src/shell/main-entry.js.map +1 -0
- package/dist/src/shell/main-http-csrf.js +45 -0
- package/dist/src/shell/main-http-csrf.js.map +1 -0
- package/dist/src/shell/main-http-handler.js +389 -0
- package/dist/src/shell/main-http-handler.js.map +1 -0
- package/dist/src/shell/main-http-mcp.js +122 -0
- package/dist/src/shell/main-http-mcp.js.map +1 -0
- package/dist/src/shell/main-http-views.js +253 -0
- package/dist/src/shell/main-http-views.js.map +1 -0
- package/dist/src/shell/main-http.js +76 -0
- package/dist/src/shell/main-http.js.map +1 -0
- package/dist/src/shell/main-loops.js +130 -0
- package/dist/src/shell/main-loops.js.map +1 -0
- package/dist/src/shell/main-mcp.js +129 -0
- package/dist/src/shell/main-mcp.js.map +1 -0
- package/dist/src/shell/main-orchestrator.js +120 -0
- package/dist/src/shell/main-orchestrator.js.map +1 -0
- package/dist/src/shell/main-preflight.js +43 -0
- package/dist/src/shell/main-preflight.js.map +1 -0
- package/dist/src/shell/main-reconcilers-helpers.js +244 -0
- package/dist/src/shell/main-reconcilers-helpers.js.map +1 -0
- package/dist/src/shell/main-reconcilers-pr.js +148 -0
- package/dist/src/shell/main-reconcilers-pr.js.map +1 -0
- package/dist/src/shell/main-reconcilers.js +225 -0
- package/dist/src/shell/main-reconcilers.js.map +1 -0
- package/dist/src/shell/main-runner.js +355 -0
- package/dist/src/shell/main-runner.js.map +1 -0
- package/dist/src/shell/main-scaffold.js +116 -0
- package/dist/src/shell/main-scaffold.js.map +1 -0
- package/dist/src/shell/main-shutdown.js +115 -0
- package/dist/src/shell/main-shutdown.js.map +1 -0
- package/dist/src/shell/main-startup.js +48 -0
- package/dist/src/shell/main-startup.js.map +1 -0
- package/dist/src/shell/main-substrates.js +43 -0
- package/dist/src/shell/main-substrates.js.map +1 -0
- package/dist/src/shell/main.js +385 -0
- package/dist/src/shell/main.js.map +1 -0
- package/dist/src/shell/orchestrator-feedback.js +69 -0
- package/dist/src/shell/orchestrator-feedback.js.map +1 -0
- package/dist/src/shell/orchestrator-image.js +167 -0
- package/dist/src/shell/orchestrator-image.js.map +1 -0
- package/dist/src/shell/orchestrator-loop.js +468 -0
- package/dist/src/shell/orchestrator-loop.js.map +1 -0
- package/dist/src/shell/orchestrator-reconcile.js +36 -0
- package/dist/src/shell/orchestrator-reconcile.js.map +1 -0
- package/dist/src/shell/reconciler-loop.js +228 -0
- package/dist/src/shell/reconciler-loop.js.map +1 -0
- package/dist/src/shell/runner-loop-turn.js +301 -0
- package/dist/src/shell/runner-loop-turn.js.map +1 -0
- package/dist/src/shell/runner-loop.js +338 -0
- package/dist/src/shell/runner-loop.js.map +1 -0
- package/dist/src/shell/server/http.js +208 -0
- package/dist/src/shell/server/http.js.map +1 -0
- package/dist/src/shell/server/mcp-runtime-effects.js +237 -0
- package/dist/src/shell/server/mcp-runtime-effects.js.map +1 -0
- package/dist/src/shell/server/mcp-runtime.js +99 -0
- package/dist/src/shell/server/mcp-runtime.js.map +1 -0
- package/dist/src/shell/workspace-key.js +14 -0
- package/dist/src/shell/workspace-key.js.map +1 -0
- package/dist/src/types/acp.js +8 -0
- package/dist/src/types/acp.js.map +1 -0
- package/dist/src/types/actions/plan.js +6 -0
- package/dist/src/types/actions/plan.js.map +1 -0
- package/dist/src/types/actions/predicates.js +6 -0
- package/dist/src/types/actions/predicates.js.map +1 -0
- package/dist/src/types/actions/run-fold.js +8 -0
- package/dist/src/types/actions/run-fold.js.map +1 -0
- package/dist/src/types/actions.js +7 -0
- package/dist/src/types/actions.js.map +1 -0
- package/dist/src/types/adapter/clock-random.js +4 -0
- package/dist/src/types/adapter/clock-random.js.map +1 -0
- package/dist/src/types/adapter/gondolin-image-converter.js +5 -0
- package/dist/src/types/adapter/gondolin-image-converter.js.map +1 -0
- package/dist/src/types/adapter/gondolin-image-fetch.js +5 -0
- package/dist/src/types/adapter/gondolin-image-fetch.js.map +1 -0
- package/dist/src/types/adapter/workflow-loader.js +4 -0
- package/dist/src/types/adapter/workflow-loader.js.map +1 -0
- package/dist/src/types/cli/args.js +8 -0
- package/dist/src/types/cli/args.js.map +1 -0
- package/dist/src/types/config.js +8 -0
- package/dist/src/types/config.js.map +1 -0
- package/dist/src/types/credential-interp.js +6 -0
- package/dist/src/types/credential-interp.js.map +1 -0
- package/dist/src/types/credentials.js +10 -0
- package/dist/src/types/credentials.js.map +1 -0
- package/dist/src/types/doctor.js +7 -0
- package/dist/src/types/doctor.js.map +1 -0
- package/dist/src/types/domain.js +7 -0
- package/dist/src/types/domain.js.map +1 -0
- package/dist/src/types/effect.js +15 -0
- package/dist/src/types/effect.js.map +1 -0
- package/dist/src/types/errors.js +39 -0
- package/dist/src/types/errors.js.map +1 -0
- package/dist/src/types/http/decisions.js +6 -0
- package/dist/src/types/http/decisions.js.map +1 -0
- package/dist/src/types/http/render.js +10 -0
- package/dist/src/types/http/render.js.map +1 -0
- package/dist/src/types/http/views.js +6 -0
- package/dist/src/types/http/views.js.map +1 -0
- package/dist/src/types/http.js +9 -0
- package/dist/src/types/http.js.map +1 -0
- package/dist/src/types/image/managed-image.js +7 -0
- package/dist/src/types/image/managed-image.js.map +1 -0
- package/dist/src/types/interp/effect-interpreter.js +8 -0
- package/dist/src/types/interp/effect-interpreter.js.map +1 -0
- package/dist/src/types/interp/tracker.js +7 -0
- package/dist/src/types/interp/tracker.js.map +1 -0
- package/dist/src/types/issue/file.js +6 -0
- package/dist/src/types/issue/file.js.map +1 -0
- package/dist/src/types/issue/parse.js +8 -0
- package/dist/src/types/issue/parse.js.map +1 -0
- package/dist/src/types/main-acp.js +13 -0
- package/dist/src/types/main-acp.js.map +1 -0
- package/dist/src/types/main-adapters.js +5 -0
- package/dist/src/types/main-adapters.js.map +1 -0
- package/dist/src/types/main-credential.js +21 -0
- package/dist/src/types/main-credential.js.map +1 -0
- package/dist/src/types/main-doctor.js +6 -0
- package/dist/src/types/main-doctor.js.map +1 -0
- package/dist/src/types/main-http-handler.js +12 -0
- package/dist/src/types/main-http-handler.js.map +1 -0
- package/dist/src/types/main-http.js +5 -0
- package/dist/src/types/main-http.js.map +1 -0
- package/dist/src/types/main-loops.js +5 -0
- package/dist/src/types/main-loops.js.map +1 -0
- package/dist/src/types/main-mcp.js +12 -0
- package/dist/src/types/main-mcp.js.map +1 -0
- package/dist/src/types/main-orchestrator.js +5 -0
- package/dist/src/types/main-orchestrator.js.map +1 -0
- package/dist/src/types/main-reconcilers.js +11 -0
- package/dist/src/types/main-reconcilers.js.map +1 -0
- package/dist/src/types/main-runner.js +13 -0
- package/dist/src/types/main-runner.js.map +1 -0
- package/dist/src/types/main-startup.js +5 -0
- package/dist/src/types/main-startup.js.map +1 -0
- package/dist/src/types/main-substrates.js +5 -0
- package/dist/src/types/main-substrates.js.map +1 -0
- package/dist/src/types/mcp/dispatch.js +4 -0
- package/dist/src/types/mcp/dispatch.js.map +1 -0
- package/dist/src/types/mcp/post-move.js +7 -0
- package/dist/src/types/mcp/post-move.js.map +1 -0
- package/dist/src/types/mcp.js +9 -0
- package/dist/src/types/mcp.js.map +1 -0
- package/dist/src/types/ports.js +12 -0
- package/dist/src/types/ports.js.map +1 -0
- package/dist/src/types/reconcile/image-decide.js +5 -0
- package/dist/src/types/reconcile/image-decide.js.map +1 -0
- package/dist/src/types/reconcile/ledger.js +7 -0
- package/dist/src/types/reconcile/ledger.js.map +1 -0
- package/dist/src/types/reconcile/pr-loop.js +8 -0
- package/dist/src/types/reconcile/pr-loop.js.map +1 -0
- package/dist/src/types/reconcile/vm-reap.js +8 -0
- package/dist/src/types/reconcile/vm-reap.js.map +1 -0
- package/dist/src/types/reconcile/workspace-decide.js +7 -0
- package/dist/src/types/reconcile/workspace-decide.js.map +1 -0
- package/dist/src/types/reconcile.js +9 -0
- package/dist/src/types/reconcile.js.map +1 -0
- package/dist/src/types/runlog.js +7 -0
- package/dist/src/types/runlog.js.map +1 -0
- package/dist/src/types/runner/actions-runner.js +12 -0
- package/dist/src/types/runner/actions-runner.js.map +1 -0
- package/dist/src/types/runner/gondolin-dispatch.js +5 -0
- package/dist/src/types/runner/gondolin-dispatch.js.map +1 -0
- package/dist/src/types/runner/injection.js +6 -0
- package/dist/src/types/runner/injection.js.map +1 -0
- package/dist/src/types/runner/runner-loop.js +5 -0
- package/dist/src/types/runner/runner-loop.js.map +1 -0
- package/dist/src/types/runner/turn.js +4 -0
- package/dist/src/types/runner/turn.js.map +1 -0
- package/dist/src/types/runner/vm-plan.js +4 -0
- package/dist/src/types/runner/vm-plan.js.map +1 -0
- package/dist/src/types/runtime.js +9 -0
- package/dist/src/types/runtime.js.map +1 -0
- package/dist/src/types/schedule/admission.js +7 -0
- package/dist/src/types/schedule/admission.js.map +1 -0
- package/dist/src/types/schedule/circuit-breaker.js +2 -0
- package/dist/src/types/schedule/circuit-breaker.js.map +1 -0
- package/dist/src/types/schedule/eligibility.js +9 -0
- package/dist/src/types/schedule/eligibility.js.map +1 -0
- package/dist/src/types/schedule/orchestrator-loop.js +10 -0
- package/dist/src/types/schedule/orchestrator-loop.js.map +1 -0
- package/dist/src/types/schedule/sleep-cycle.js +4 -0
- package/dist/src/types/schedule/sleep-cycle.js.map +1 -0
- package/dist/src/types/schedule/slots.js +8 -0
- package/dist/src/types/schedule/slots.js.map +1 -0
- package/dist/src/types/schedule/tick.js +9 -0
- package/dist/src/types/schedule/tick.js.map +1 -0
- package/dist/src/types/server/mcp-runtime.js +8 -0
- package/dist/src/types/server/mcp-runtime.js.map +1 -0
- package/dist/src/types/workflow/parse.js +4 -0
- package/dist/src/types/workflow/parse.js.map +1 -0
- package/dist/tests/core/account-id.test.js +35 -0
- package/dist/tests/core/account-id.test.js.map +1 -0
- package/dist/tests/core/actions-parse.test.js +176 -0
- package/dist/tests/core/actions-parse.test.js.map +1 -0
- package/dist/tests/core/adapter-config.test.js +133 -0
- package/dist/tests/core/adapter-config.test.js.map +1 -0
- package/dist/tests/core/admission.test.js +215 -0
- package/dist/tests/core/admission.test.js.map +1 -0
- package/dist/tests/core/args.test.js +132 -0
- package/dist/tests/core/args.test.js.map +1 -0
- package/dist/tests/core/availability.test.js +62 -0
- package/dist/tests/core/availability.test.js.map +1 -0
- package/dist/tests/core/checks.test.js +395 -0
- package/dist/tests/core/checks.test.js.map +1 -0
- package/dist/tests/core/circuit-breaker.test.js +172 -0
- package/dist/tests/core/circuit-breaker.test.js.map +1 -0
- package/dist/tests/core/coerce.test.js +87 -0
- package/dist/tests/core/coerce.test.js.map +1 -0
- package/dist/tests/core/context.test.js +228 -0
- package/dist/tests/core/context.test.js.map +1 -0
- package/dist/tests/core/decisions.test.js +310 -0
- package/dist/tests/core/decisions.test.js.map +1 -0
- package/dist/tests/core/derive.test.js +205 -0
- package/dist/tests/core/derive.test.js.map +1 -0
- package/dist/tests/core/dispatch-config.test.js +164 -0
- package/dist/tests/core/dispatch-config.test.js.map +1 -0
- package/dist/tests/core/dispatch.test.js +302 -0
- package/dist/tests/core/dispatch.test.js.map +1 -0
- package/dist/tests/core/eligibility.test.js +163 -0
- package/dist/tests/core/eligibility.test.js.map +1 -0
- package/dist/tests/core/extract.test.js +139 -0
- package/dist/tests/core/extract.test.js.map +1 -0
- package/dist/tests/core/fake-creds.test.js +134 -0
- package/dist/tests/core/fake-creds.test.js.map +1 -0
- package/dist/tests/core/file.test.js +197 -0
- package/dist/tests/core/file.test.js.map +1 -0
- package/dist/tests/core/git-result.test.js +113 -0
- package/dist/tests/core/git-result.test.js.map +1 -0
- package/dist/tests/core/identity.test.js +180 -0
- package/dist/tests/core/identity.test.js.map +1 -0
- package/dist/tests/core/image-decide.test.js +59 -0
- package/dist/tests/core/image-decide.test.js.map +1 -0
- package/dist/tests/core/injection.test.js +163 -0
- package/dist/tests/core/injection.test.js.map +1 -0
- package/dist/tests/core/ledger.test.js +218 -0
- package/dist/tests/core/ledger.test.js.map +1 -0
- package/dist/tests/core/managed-image.test.js +68 -0
- package/dist/tests/core/managed-image.test.js.map +1 -0
- package/dist/tests/core/mise.test.js +138 -0
- package/dist/tests/core/mise.test.js.map +1 -0
- package/dist/tests/core/parse.test.js +174 -0
- package/dist/tests/core/parse.test.js.map +1 -0
- package/dist/tests/core/path.test.js +50 -0
- package/dist/tests/core/path.test.js.map +1 -0
- package/dist/tests/core/plan.test.js +218 -0
- package/dist/tests/core/plan.test.js.map +1 -0
- package/dist/tests/core/post-move.test.js +162 -0
- package/dist/tests/core/post-move.test.js.map +1 -0
- package/dist/tests/core/pr-classify.test.js +117 -0
- package/dist/tests/core/pr-classify.test.js.map +1 -0
- package/dist/tests/core/pr-decide.test.js +298 -0
- package/dist/tests/core/pr-decide.test.js.map +1 -0
- package/dist/tests/core/pr-loop.test.js +301 -0
- package/dist/tests/core/pr-loop.test.js.map +1 -0
- package/dist/tests/core/pr-notes.test.js +165 -0
- package/dist/tests/core/pr-notes.test.js.map +1 -0
- package/dist/tests/core/predicates.test.js +154 -0
- package/dist/tests/core/predicates.test.js.map +1 -0
- package/dist/tests/core/prompt.test.js +189 -0
- package/dist/tests/core/prompt.test.js.map +1 -0
- package/dist/tests/core/protocol.test.js +195 -0
- package/dist/tests/core/protocol.test.js.map +1 -0
- package/dist/tests/core/reconcile-issue.test.js +116 -0
- package/dist/tests/core/reconcile-issue.test.js.map +1 -0
- package/dist/tests/core/render.test.js +549 -0
- package/dist/tests/core/render.test.js.map +1 -0
- package/dist/tests/core/retry.test.js +186 -0
- package/dist/tests/core/retry.test.js.map +1 -0
- package/dist/tests/core/routes.test.js +247 -0
- package/dist/tests/core/routes.test.js.map +1 -0
- package/dist/tests/core/run-fold.test.js +299 -0
- package/dist/tests/core/run-fold.test.js.map +1 -0
- package/dist/tests/core/shape.test.js +185 -0
- package/dist/tests/core/shape.test.js.map +1 -0
- package/dist/tests/core/sleep-cycle.test.js +150 -0
- package/dist/tests/core/sleep-cycle.test.js.map +1 -0
- package/dist/tests/core/slots.test.js +201 -0
- package/dist/tests/core/slots.test.js.map +1 -0
- package/dist/tests/core/state-resolve.test.js +80 -0
- package/dist/tests/core/state-resolve.test.js.map +1 -0
- package/dist/tests/core/summary.test.js +200 -0
- package/dist/tests/core/summary.test.js.map +1 -0
- package/dist/tests/core/template.test.js +116 -0
- package/dist/tests/core/template.test.js.map +1 -0
- package/dist/tests/core/tick.test.js +558 -0
- package/dist/tests/core/tick.test.js.map +1 -0
- package/dist/tests/core/token-fold.test.js +176 -0
- package/dist/tests/core/token-fold.test.js.map +1 -0
- package/dist/tests/core/turn.test.js +388 -0
- package/dist/tests/core/turn.test.js.map +1 -0
- package/dist/tests/core/url.test.js +118 -0
- package/dist/tests/core/url.test.js.map +1 -0
- package/dist/tests/core/validate.test.js +247 -0
- package/dist/tests/core/validate.test.js.map +1 -0
- package/dist/tests/core/views.test.js +252 -0
- package/dist/tests/core/views.test.js.map +1 -0
- package/dist/tests/core/vm-decide.test.js +110 -0
- package/dist/tests/core/vm-decide.test.js.map +1 -0
- package/dist/tests/core/vm-guards.test.js +153 -0
- package/dist/tests/core/vm-guards.test.js.map +1 -0
- package/dist/tests/core/vm-plan.test.js +332 -0
- package/dist/tests/core/vm-plan.test.js.map +1 -0
- package/dist/tests/core/vm-reap.test.js +196 -0
- package/dist/tests/core/vm-reap.test.js.map +1 -0
- package/dist/tests/core/workflow-parse.test.js +493 -0
- package/dist/tests/core/workflow-parse.test.js.map +1 -0
- package/dist/tests/core/workspace-decide.test.js +236 -0
- package/dist/tests/core/workspace-decide.test.js.map +1 -0
- package/dist/tests/helpers/fixtures.js +167 -0
- package/dist/tests/helpers/fixtures.js.map +1 -0
- package/dist/tests/shell/acp-substrate.test.js +101 -0
- package/dist/tests/shell/acp-substrate.test.js.map +1 -0
- package/dist/tests/shell/actions-runner-push.test.js +203 -0
- package/dist/tests/shell/actions-runner-push.test.js.map +1 -0
- package/dist/tests/shell/credential-hooks.test.js +36 -0
- package/dist/tests/shell/credential-hooks.test.js.map +1 -0
- package/dist/tests/shell/credential-registry.test.js +165 -0
- package/dist/tests/shell/credential-registry.test.js.map +1 -0
- package/dist/tests/shell/credential-substrate.test.js +179 -0
- package/dist/tests/shell/credential-substrate.test.js.map +1 -0
- package/dist/tests/shell/dockerfile-mise-pin.test.js +51 -0
- package/dist/tests/shell/dockerfile-mise-pin.test.js.map +1 -0
- package/dist/tests/shell/doctor.test.js +101 -0
- package/dist/tests/shell/doctor.test.js.map +1 -0
- package/dist/tests/shell/effect-vm-create.test.js +52 -0
- package/dist/tests/shell/effect-vm-create.test.js.map +1 -0
- package/dist/tests/shell/gh-port.test.js +63 -0
- package/dist/tests/shell/gh-port.test.js.map +1 -0
- package/dist/tests/shell/gondolin-dispatch-guard.test.js +144 -0
- package/dist/tests/shell/gondolin-dispatch-guard.test.js.map +1 -0
- package/dist/tests/shell/gondolin-dispatch-shquote.test.js +168 -0
- package/dist/tests/shell/gondolin-dispatch-shquote.test.js.map +1 -0
- package/dist/tests/shell/gondolin-image-converter.test.js +208 -0
- package/dist/tests/shell/gondolin-image-converter.test.js.map +1 -0
- package/dist/tests/shell/gondolin-image-fetch.test.js +93 -0
- package/dist/tests/shell/gondolin-image-fetch.test.js.map +1 -0
- package/dist/tests/shell/http-handler.test.js +608 -0
- package/dist/tests/shell/http-handler.test.js.map +1 -0
- package/dist/tests/shell/http-server.test.js +53 -0
- package/dist/tests/shell/http-server.test.js.map +1 -0
- package/dist/tests/shell/mcp-runtime.test.js +366 -0
- package/dist/tests/shell/mcp-runtime.test.js.map +1 -0
- package/dist/tests/shell/mise-config-asset.test.js +87 -0
- package/dist/tests/shell/mise-config-asset.test.js.map +1 -0
- package/dist/tests/shell/orchestrator-loop.test.js +583 -0
- package/dist/tests/shell/orchestrator-loop.test.js.map +1 -0
- package/dist/tests/shell/reconciler-passes.test.js +314 -0
- package/dist/tests/shell/reconciler-passes.test.js.map +1 -0
- package/dist/tests/shell/runner-loop-turn.test.js +97 -0
- package/dist/tests/shell/runner-loop-turn.test.js.map +1 -0
- package/dist/tests/shell/runner-slice.test.js +536 -0
- package/dist/tests/shell/runner-slice.test.js.map +1 -0
- package/dist/tests/shell/scaffold.test.js +65 -0
- package/dist/tests/shell/scaffold.test.js.map +1 -0
- package/dist/tests/shell/tick-config.test.js +83 -0
- package/dist/tests/shell/tick-config.test.js.map +1 -0
- package/dist/tests/shell/tracker-parse-dates.test.js +44 -0
- package/dist/tests/shell/tracker-parse-dates.test.js.map +1 -0
- package/dist/tests/shell/tracker-write-issue.test.js +154 -0
- package/dist/tests/shell/tracker-write-issue.test.js.map +1 -0
- package/dist/tests/shell/workflow-prompt-split.test.js +208 -0
- package/dist/tests/shell/workflow-prompt-split.test.js.map +1 -0
- package/dist/tests/shell/workspace-live-config.test.js +140 -0
- package/dist/tests/shell/workspace-live-config.test.js.map +1 -0
- package/package.json +21 -9
- 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/bin/symphony.js +0 -794
- package/dist/bin/symphony.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
|
@@ -0,0 +1,583 @@
|
|
|
1
|
+
// Focused unit test for the orchestrator loop's worker.cancel interpretation
|
|
2
|
+
// (src/shell/orchestrator-loop.ts). The reducer EMITS a `worker.cancel` effect for
|
|
3
|
+
// an operator move onto a live attempt (issue 199); the loop is the ONE place that
|
|
4
|
+
// interprets it, performing the cancel via its own terminateRunning — the same path
|
|
5
|
+
// the stall reaper drives. core holds no live handles, so this is the loop's job.
|
|
6
|
+
//
|
|
7
|
+
// We drive the loop with a stubbed pure reducer so the test exercises only the
|
|
8
|
+
// effect-interpreter seam: seed a running entry via a dispatch plan, then fold an
|
|
9
|
+
// event whose result carries a worker.cancel effect, and assert the live entry's
|
|
10
|
+
// cancel closure fired and the workspace-cleanup flag was set from the effect.
|
|
11
|
+
import { test } from 'node:test';
|
|
12
|
+
import assert from 'node:assert/strict';
|
|
13
|
+
import { OrchestratorLoop } from '../../src/shell/orchestrator-loop.js';
|
|
14
|
+
import { decideReconcileForIssue } from '../../src/core/schedule/reconcile-issue.js';
|
|
15
|
+
import { tick } from '../../src/core/schedule/tick.js';
|
|
16
|
+
const POLL_TIMER_ID = 'orchestrator_poll';
|
|
17
|
+
function tickConfig() {
|
|
18
|
+
return {
|
|
19
|
+
pollIntervalMs: 5_000,
|
|
20
|
+
staticCap: 3,
|
|
21
|
+
memoryAdmissionEnabled: false,
|
|
22
|
+
hostMemoryReserveMib: 0,
|
|
23
|
+
perVmMib: 0,
|
|
24
|
+
maxRetryBackoffMs: 60_000,
|
|
25
|
+
circuitBreakerThreshold: 0,
|
|
26
|
+
activeStates: new Set(['todo']),
|
|
27
|
+
terminalStates: new Set(['done']),
|
|
28
|
+
states: { Todo: { role: 'active' }, Done: { role: 'terminal' } },
|
|
29
|
+
spawn: { spawnState: null, onIdle: false, afterTerminal: 0, title: 'Reflection {{ stamp }}', body: null, maxInFlight: 1 },
|
|
30
|
+
holdingState: null,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function issue(id) {
|
|
34
|
+
return {
|
|
35
|
+
id, identifier: id, title: id, description: null, priority: null, state: 'Todo',
|
|
36
|
+
branch_name: null, url: null, labels: [], blocked_by: [], created_at: null, updated_at: null,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/** A minimal RunningEntry whose cancel closure records its invocation. */
|
|
40
|
+
function buildEntry(plan, cancel) {
|
|
41
|
+
let cancelled = false;
|
|
42
|
+
const entry = {
|
|
43
|
+
issue_id: plan.issue.id,
|
|
44
|
+
identifier: plan.issue.identifier,
|
|
45
|
+
issue: plan.issue,
|
|
46
|
+
cleanup_workspace_on_exit: false,
|
|
47
|
+
cancel: () => {
|
|
48
|
+
cancelled = true;
|
|
49
|
+
cancel();
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
return { entry, cancelled: () => cancelled };
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Build a loop wired to a programmable reducer. `results` is consumed one per
|
|
56
|
+
* dispatch; everything the loop needs from the composition root is a thin stub
|
|
57
|
+
* (no timers fire — start() is never called).
|
|
58
|
+
*/
|
|
59
|
+
function makeLoop(results, extra = {}) {
|
|
60
|
+
const entries = [];
|
|
61
|
+
const executed = [];
|
|
62
|
+
const snapshots = [];
|
|
63
|
+
let i = 0;
|
|
64
|
+
const deps = {
|
|
65
|
+
tick: (event, snapshot) => {
|
|
66
|
+
executed.push(event);
|
|
67
|
+
snapshots.push(snapshot);
|
|
68
|
+
return results[i++] ?? { dispatch: [], effects: [], claim: [], release: [] };
|
|
69
|
+
},
|
|
70
|
+
interpreter: { execute: async () => ({ ok: true }) },
|
|
71
|
+
timers: { sleep: async () => undefined, setTimer: () => undefined, clearTimer: () => undefined },
|
|
72
|
+
memProbe: { read: () => null },
|
|
73
|
+
clock: { now: () => 1_700_000_000_000, iso: () => '2023-11-14T22:13:20.000Z' },
|
|
74
|
+
readConfig: () => tickConfig(),
|
|
75
|
+
// Default to a tracker miss (poll bails right after the move-reconcile); a test
|
|
76
|
+
// that drives a real poll-tick fold overrides this via `extra`.
|
|
77
|
+
fetchCandidates: async () => null,
|
|
78
|
+
...extra,
|
|
79
|
+
runWorker: () => new Promise(() => undefined), // never resolves ⇒ entry stays live
|
|
80
|
+
buildEntry: (plan, cancel) => {
|
|
81
|
+
const built = buildEntry(plan, cancel);
|
|
82
|
+
entries.push(built);
|
|
83
|
+
return built.entry;
|
|
84
|
+
},
|
|
85
|
+
tokenFold: {},
|
|
86
|
+
stall: { detectStall: () => ({ stalled: false }), stallTimeoutMs: () => 0 },
|
|
87
|
+
backoff: () => 0,
|
|
88
|
+
pollTimerId: POLL_TIMER_ID,
|
|
89
|
+
spawnActor: 'symphony/sleep-cycle',
|
|
90
|
+
};
|
|
91
|
+
return { loop: new OrchestratorLoop(deps), entries, executed, snapshots };
|
|
92
|
+
}
|
|
93
|
+
/** Seed one live running entry into the loop via the first (dispatch-plan) result. */
|
|
94
|
+
function seedRunning(loop) {
|
|
95
|
+
// Any event triggers the fold; the stubbed reducer returns the queued dispatch
|
|
96
|
+
// plan, so the loop spawns the (never-resolving) worker and keeps the entry live.
|
|
97
|
+
loop.dispatch({ kind: 'operator_nudge' });
|
|
98
|
+
}
|
|
99
|
+
test('worker.cancel onto a terminal target fires the live cancel closure AND sets the cleanup flag', () => {
|
|
100
|
+
const plan = { issue: issue('i1'), attempt: null, trackerRoot: '/tracker' };
|
|
101
|
+
const { loop, entries } = makeLoop([
|
|
102
|
+
{ dispatch: [plan], effects: [], claim: ['i1'], release: [] },
|
|
103
|
+
{
|
|
104
|
+
dispatch: [],
|
|
105
|
+
effects: [{ family: 'worker', kind: 'cancel', issueId: 'i1', cleanupWorkspace: true }],
|
|
106
|
+
claim: [],
|
|
107
|
+
release: [],
|
|
108
|
+
},
|
|
109
|
+
]);
|
|
110
|
+
seedRunning(loop);
|
|
111
|
+
assert.equal(loop.runningEntries().length, 1, 'the dispatch plan seeded a live entry');
|
|
112
|
+
const { entry, cancelled } = entries[0];
|
|
113
|
+
// Fold the operator_move-shaped result whose effect is worker.cancel.
|
|
114
|
+
loop.dispatch({ kind: 'operator_move', issueId: 'i1', identifier: 'i1', toState: 'Done', toTerminal: true, toActive: false });
|
|
115
|
+
assert.equal(cancelled(), true, 'the live cancel closure fired');
|
|
116
|
+
assert.equal(entry.cleanup_workspace_on_exit, true, 'a terminal target flags workspace cleanup');
|
|
117
|
+
});
|
|
118
|
+
test('worker.cancel onto an active target cancels WITHOUT flagging workspace cleanup', () => {
|
|
119
|
+
const plan = { issue: issue('i2'), attempt: null, trackerRoot: '/tracker' };
|
|
120
|
+
const { loop, entries } = makeLoop([
|
|
121
|
+
{ dispatch: [plan], effects: [], claim: ['i2'], release: [] },
|
|
122
|
+
{
|
|
123
|
+
dispatch: [],
|
|
124
|
+
effects: [{ family: 'worker', kind: 'cancel', issueId: 'i2', cleanupWorkspace: false }],
|
|
125
|
+
claim: [],
|
|
126
|
+
release: [],
|
|
127
|
+
},
|
|
128
|
+
]);
|
|
129
|
+
seedRunning(loop);
|
|
130
|
+
const { entry, cancelled } = entries[0];
|
|
131
|
+
loop.dispatch({ kind: 'operator_move', issueId: 'i2', identifier: 'i2', toState: 'Review', toTerminal: false, toActive: true });
|
|
132
|
+
assert.equal(cancelled(), true, 'the live cancel closure fired');
|
|
133
|
+
assert.equal(entry.cleanup_workspace_on_exit, false, 'an active target keeps the workspace for the redispatch');
|
|
134
|
+
});
|
|
135
|
+
test('worker.cancel for an issue with no live entry is a safe no-op', () => {
|
|
136
|
+
const { loop, entries } = makeLoop([
|
|
137
|
+
{
|
|
138
|
+
dispatch: [],
|
|
139
|
+
effects: [{ family: 'worker', kind: 'cancel', issueId: 'ghost', cleanupWorkspace: true }],
|
|
140
|
+
claim: [],
|
|
141
|
+
release: [],
|
|
142
|
+
},
|
|
143
|
+
]);
|
|
144
|
+
// No dispatch plan seeded ⇒ nothing in the running map; terminateRunning no-ops.
|
|
145
|
+
loop.dispatch({ kind: 'operator_move', issueId: 'ghost', identifier: 'ghost', toState: 'Done', toTerminal: true, toActive: false });
|
|
146
|
+
assert.equal(entries.length, 0);
|
|
147
|
+
assert.equal(loop.runningEntries().length, 0);
|
|
148
|
+
});
|
|
149
|
+
// ─── sleep-cycle recurring spawn: success-gated counter reset ───────────────
|
|
150
|
+
// The reducer EMITS a tracker.write_issue create effect (actor = the spawn actor)
|
|
151
|
+
// and optimistically resets the doneSinceReflect counter to 0; the loop routes
|
|
152
|
+
// that effect through the guarded mint path, which restores the PRE-reset counter
|
|
153
|
+
// if the create fails. We observe the counter via the NEXT fold's snapshot.
|
|
154
|
+
const SPAWN_ACTOR = 'symphony/sleep-cycle';
|
|
155
|
+
function writeIssueResult() {
|
|
156
|
+
return {
|
|
157
|
+
dispatch: [],
|
|
158
|
+
effects: [
|
|
159
|
+
{
|
|
160
|
+
family: 'tracker',
|
|
161
|
+
kind: 'write_issue',
|
|
162
|
+
trackerRoot: '/tracker',
|
|
163
|
+
state: 'Reflect',
|
|
164
|
+
title: 'Reflection 2023-11-14 22:13',
|
|
165
|
+
description: 'Auto-spawned reflection cycle.',
|
|
166
|
+
actor: SPAWN_ACTOR,
|
|
167
|
+
},
|
|
168
|
+
],
|
|
169
|
+
claim: [],
|
|
170
|
+
release: [],
|
|
171
|
+
doneSinceReflect: 0, // core's optimistic reset
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
test('spawn mint: a SUCCESSFUL create keeps the counter reset to 0', async () => {
|
|
175
|
+
const { loop, snapshots } = makeLoop([
|
|
176
|
+
{ dispatch: [], effects: [], claim: [], release: [], doneSinceReflect: 5 }, // seed the counter
|
|
177
|
+
writeIssueResult(),
|
|
178
|
+
], { interpreter: { execute: async () => ({ kind: 'write_issue', path: '/tracker/Reflect/1.md', identifier: '1', state: 'Reflect' }) } });
|
|
179
|
+
loop.dispatch({ kind: 'operator_nudge' }); // counter → 5
|
|
180
|
+
loop.dispatch({ kind: 'operator_nudge' }); // counter → 0 + run the (successful) mint
|
|
181
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
182
|
+
loop.dispatch({ kind: 'operator_nudge' }); // observe via the next snapshot
|
|
183
|
+
assert.equal(snapshots.at(-1).doneSinceReflect, 0, 'a successful mint leaves the counter reset');
|
|
184
|
+
});
|
|
185
|
+
test('spawn mint: a FAILED create restores the pre-reset counter', async () => {
|
|
186
|
+
const { loop, snapshots } = makeLoop([
|
|
187
|
+
{ dispatch: [], effects: [], claim: [], release: [], doneSinceReflect: 5 }, // seed the counter
|
|
188
|
+
writeIssueResult(),
|
|
189
|
+
], { interpreter: { execute: async () => ({ ok: false, error: 'disk full' }) } });
|
|
190
|
+
loop.dispatch({ kind: 'operator_nudge' }); // counter → 5
|
|
191
|
+
loop.dispatch({ kind: 'operator_nudge' }); // counter → 0 then RESTORE to 5 (mint failed)
|
|
192
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
193
|
+
loop.dispatch({ kind: 'operator_nudge' }); // observe via the next snapshot
|
|
194
|
+
assert.equal(snapshots.at(-1).doneSinceReflect, 5, 'a failed mint restores the accumulated count');
|
|
195
|
+
});
|
|
196
|
+
// ─── pending-mint guard: an in-flight (unlanded) write_issue counts toward max_in_flight ──
|
|
197
|
+
// Review finding (Review→Todo): the immortal-ticket `armingReflection` latch was
|
|
198
|
+
// removed, and core's `max_in_flight` guard only counts issues VISIBLE in the on-disk
|
|
199
|
+
// candidate scan + the running set. A `write_issue` the loop has emitted but whose disk
|
|
200
|
+
// write hasn't landed yet is in NEITHER, so a worker exit + poll racing between emit and
|
|
201
|
+
// landing could mint a SECOND reflection. The shell now surfaces an in-flight mint as
|
|
202
|
+
// `pendingSpawnMints`; this drives the REAL reducer end-to-end (not a stub) to prove the
|
|
203
|
+
// race is closed.
|
|
204
|
+
/** A spawn-configured TickConfig: Reflect mints on a single terminal transition. */
|
|
205
|
+
function spawnTickConfig() {
|
|
206
|
+
return {
|
|
207
|
+
...tickConfig(),
|
|
208
|
+
activeStates: new Set(['todo', 'reflect']),
|
|
209
|
+
terminalStates: new Set(['done', 'reflected']),
|
|
210
|
+
states: { Todo: { role: 'active' }, Reflect: { role: 'active' }, Reflected: { role: 'terminal' }, Done: { role: 'terminal' } },
|
|
211
|
+
spawn: { spawnState: 'Reflect', onIdle: false, afterTerminal: 1, title: 'Reflection {{ stamp }}', body: null, maxInFlight: 1 },
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
/** A clean worker exit carrying a TERMINAL transition OUT of an active state (bumps the counter). */
|
|
215
|
+
function terminalExit(issueId) {
|
|
216
|
+
return {
|
|
217
|
+
...exitEvent(issueId),
|
|
218
|
+
targetState: 'Done',
|
|
219
|
+
progress: {
|
|
220
|
+
issue_id: issueId,
|
|
221
|
+
identifier: issueId,
|
|
222
|
+
last_transition: { from_state: 'Todo', to_state: 'Done', notes: '', actor: null, terminal: true },
|
|
223
|
+
},
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
test('spawn mint: an in-flight (unlanded) write_issue suppresses a second mint across a racing poll (max_in_flight)', async () => {
|
|
227
|
+
const writes = [];
|
|
228
|
+
const seen = [];
|
|
229
|
+
let releaseWrite;
|
|
230
|
+
// The mint's disk write is HELD unresolved for the whole race window below.
|
|
231
|
+
const held = new Promise((resolve) => {
|
|
232
|
+
releaseWrite = () => resolve({ ok: true });
|
|
233
|
+
});
|
|
234
|
+
const interpreter = {
|
|
235
|
+
execute: async (effect) => {
|
|
236
|
+
if (effect.family === 'tracker' && effect.kind === 'write_issue') {
|
|
237
|
+
writes.push(effect.state);
|
|
238
|
+
return held; // never lands during the test ⇒ the mint stays pending
|
|
239
|
+
}
|
|
240
|
+
return { ok: true };
|
|
241
|
+
},
|
|
242
|
+
};
|
|
243
|
+
const { loop } = makeLoop([], {
|
|
244
|
+
readConfig: spawnTickConfig,
|
|
245
|
+
// Record every snapshot the REAL reducer folds, then delegate to it.
|
|
246
|
+
tick: (event, snap) => {
|
|
247
|
+
seen.push(snap);
|
|
248
|
+
return tick(event, snap);
|
|
249
|
+
},
|
|
250
|
+
fetchCandidates: async () => ({ issues: [], root: '/tracker' }),
|
|
251
|
+
interpreter,
|
|
252
|
+
});
|
|
253
|
+
// 1. A finished non-reflection issue bumps the terminal counter to the threshold.
|
|
254
|
+
loop.onWorkerExit(terminalExit('w1'));
|
|
255
|
+
// 2. Poll: the done-threshold trigger mints exactly one reflection; its write is HELD.
|
|
256
|
+
await pollOnce(loop);
|
|
257
|
+
assert.equal(writes.length, 1, 'the first poll minted exactly one reflection');
|
|
258
|
+
// 3. Another finished issue pushes the counter back over the threshold WHILE the first
|
|
259
|
+
// mint is still in flight (not yet on disk, not running, not a candidate).
|
|
260
|
+
loop.onWorkerExit(terminalExit('w2'));
|
|
261
|
+
// 4. Poll again: the in-flight mint is invisible to the candidate scan + running set,
|
|
262
|
+
// but `pendingSpawnMints` keeps it in the max_in_flight count ⇒ no second write.
|
|
263
|
+
await pollOnce(loop);
|
|
264
|
+
assert.equal(writes.length, 1, 'the in-flight mint suppressed a second reflection');
|
|
265
|
+
assert.equal(seen.at(-1).pendingSpawnMints, 1, 'the racing poll saw the pending mint in its snapshot');
|
|
266
|
+
// Let the held write settle so the pending count drops (no leak) before the test ends.
|
|
267
|
+
releaseWrite();
|
|
268
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
269
|
+
});
|
|
270
|
+
// ─── per-poll cancel-on-move reconcile (issue 211) ──────────────────────────
|
|
271
|
+
// The poll loop reconciles every LIVE running entry against its FRESH tracker view
|
|
272
|
+
// via the REAL decideReconcileForIssue (wired from production), so a disk `mv` /
|
|
273
|
+
// external move out of an active state cancels the in-flight attempt even when no
|
|
274
|
+
// dashboard move-event fired. We seed a live entry, hand the loop a fresh view
|
|
275
|
+
// through fetchRunningViews, drive ONE poll (fetchCandidates returns null so the poll
|
|
276
|
+
// bails right after the reconcile), and assert the cancel/cleanup/refresh decision.
|
|
277
|
+
const RECONCILE_STATES = {
|
|
278
|
+
Todo: { role: 'active' },
|
|
279
|
+
Triage: { role: 'holding' },
|
|
280
|
+
Done: { role: 'terminal' },
|
|
281
|
+
};
|
|
282
|
+
/** Invoke the private poll once (the production path that fires reconcileRunning). */
|
|
283
|
+
function pollOnce(loop) {
|
|
284
|
+
return loop.poll();
|
|
285
|
+
}
|
|
286
|
+
function freshIssue(state) {
|
|
287
|
+
return { ...issue('i1'), state };
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Seed one live `i1` entry, then drive a poll whose move-reconcile sees `fresh`
|
|
291
|
+
* (or, when undefined, an EMPTY map ⇒ `i1` is missing from the tracker). Returns the
|
|
292
|
+
* seeded entry handle so the test can assert cancel/cleanup/refresh.
|
|
293
|
+
*/
|
|
294
|
+
async function reconcilePoll(fresh) {
|
|
295
|
+
const plan = { issue: issue('i1'), attempt: null, trackerRoot: '/tracker' };
|
|
296
|
+
const { loop, entries } = makeLoop([{ dispatch: [plan], effects: [], claim: ['i1'], release: [] }], {
|
|
297
|
+
readConfig: () => ({ ...tickConfig(), states: RECONCILE_STATES }),
|
|
298
|
+
reconcileIssue: decideReconcileForIssue,
|
|
299
|
+
fetchRunningViews: async () => new Map(fresh ? [['i1', fresh]] : []),
|
|
300
|
+
});
|
|
301
|
+
seedRunning(loop);
|
|
302
|
+
assert.equal(loop.runningEntries().length, 1, 'the dispatch plan seeded a live entry');
|
|
303
|
+
await pollOnce(loop);
|
|
304
|
+
return entries[0];
|
|
305
|
+
}
|
|
306
|
+
test('poll reconcile: a running entry moved to a HOLDING state is cancelled WITHOUT cleanup (issue 211)', async () => {
|
|
307
|
+
const { entry, cancelled } = await reconcilePoll(freshIssue('Triage'));
|
|
308
|
+
assert.equal(cancelled(), true, 'the move out of an active state cancelled the live attempt');
|
|
309
|
+
assert.equal(entry.cleanup_workspace_on_exit, false, 'a holding target keeps the workspace');
|
|
310
|
+
});
|
|
311
|
+
test('poll reconcile: a running entry moved to a TERMINAL state is cancelled WITH cleanup (issue 211)', async () => {
|
|
312
|
+
const { entry, cancelled } = await reconcilePoll(freshIssue('Done'));
|
|
313
|
+
assert.equal(cancelled(), true, 'the move to a terminal state cancelled the live attempt');
|
|
314
|
+
assert.equal(entry.cleanup_workspace_on_exit, true, 'a terminal-role target reaps the workspace');
|
|
315
|
+
});
|
|
316
|
+
test('poll reconcile: a running entry still in an ACTIVE state is refreshed, NOT cancelled (issue 211)', async () => {
|
|
317
|
+
const refreshed = { ...freshIssue('Todo'), title: 'fresh title' };
|
|
318
|
+
const { entry, cancelled } = await reconcilePoll(refreshed);
|
|
319
|
+
assert.equal(cancelled(), false, 'an active fresh state keeps the attempt running');
|
|
320
|
+
assert.equal(entry.issue.title, 'fresh title', 'the in-memory snapshot was refreshed from the fresh view');
|
|
321
|
+
});
|
|
322
|
+
test('poll reconcile: a running entry missing from the tracker is terminated WITHOUT cleanup (issue 211)', async () => {
|
|
323
|
+
const { entry, cancelled } = await reconcilePoll(undefined);
|
|
324
|
+
assert.equal(cancelled(), true, 'a vanished tracker row terminates the live attempt');
|
|
325
|
+
assert.equal(entry.cleanup_workspace_on_exit, false, 'a missing row leaves the workspace (safety)');
|
|
326
|
+
});
|
|
327
|
+
test('poll reconcile: an entry the agent itself transitioned is SKIPPED (worker_exit owns cleanup) (issue 211)', async () => {
|
|
328
|
+
const plan = { issue: issue('i1'), attempt: null, trackerRoot: '/tracker' };
|
|
329
|
+
let viewsFetched = 0;
|
|
330
|
+
const { loop, entries } = makeLoop([{ dispatch: [plan], effects: [], claim: ['i1'], release: [] }], {
|
|
331
|
+
readConfig: () => ({ ...tickConfig(), states: RECONCILE_STATES }),
|
|
332
|
+
reconcileIssue: decideReconcileForIssue,
|
|
333
|
+
fetchRunningViews: async () => {
|
|
334
|
+
viewsFetched += 1;
|
|
335
|
+
return new Map([['i1', freshIssue('Done')]]);
|
|
336
|
+
},
|
|
337
|
+
});
|
|
338
|
+
seedRunning(loop);
|
|
339
|
+
entries[0].entry.transitioned = true; // the agent transitioned to Done itself
|
|
340
|
+
await pollOnce(loop);
|
|
341
|
+
assert.equal(entries[0].cancelled(), false, 'a self-transitioned entry is not re-cancelled by the net');
|
|
342
|
+
assert.equal(viewsFetched, 0, 'no fresh-view fetch when every running entry already transitioned');
|
|
343
|
+
});
|
|
344
|
+
test('image.ensure runs the converter, exposes the build banner state, then marks the ref ready (issue 206)', async () => {
|
|
345
|
+
let resolveBuild;
|
|
346
|
+
const buildDone = new Promise((res) => {
|
|
347
|
+
resolveBuild = res;
|
|
348
|
+
});
|
|
349
|
+
let ensureCalls = 0;
|
|
350
|
+
const ref = 'ghcr.io/acme/agent:1';
|
|
351
|
+
// Readiness is digest-based: the probe resolves the ref's CURRENT digest + looks up
|
|
352
|
+
// its cached selector from a store the converter populates (issue 206 rework). Here
|
|
353
|
+
// the digest is fixed; the store is empty until the (gated) build finishes.
|
|
354
|
+
const store = new Map(); // digest → selector
|
|
355
|
+
const digest = 'sha256:AAAA';
|
|
356
|
+
const ociCfg = () => ({ ...tickConfig(), ociImage: ref });
|
|
357
|
+
const { loop, snapshots } = makeLoop([
|
|
358
|
+
// The reducer emitted an ensure_image effect (oci_image set + not yet converted).
|
|
359
|
+
{ dispatch: [], effects: [{ family: 'image', kind: 'ensure', ref }], claim: [], release: [] },
|
|
360
|
+
], {
|
|
361
|
+
readConfig: ociCfg,
|
|
362
|
+
probeImage: (r) => {
|
|
363
|
+
assert.equal(r, ref);
|
|
364
|
+
return { digest, selector: store.get(digest) ?? null };
|
|
365
|
+
},
|
|
366
|
+
ensureImage: async (r) => {
|
|
367
|
+
ensureCalls += 1;
|
|
368
|
+
assert.equal(r, ref);
|
|
369
|
+
await buildDone;
|
|
370
|
+
const selector = 'build-converted-1';
|
|
371
|
+
store.set(digest, selector); // the converter tagged the asset at this digest
|
|
372
|
+
return selector;
|
|
373
|
+
},
|
|
374
|
+
});
|
|
375
|
+
loop.dispatch({ kind: 'operator_nudge' });
|
|
376
|
+
// Before the build resolves, the probe finds no cached asset → no selector to boot.
|
|
377
|
+
assert.equal(loop.effectiveImageSelector(), null);
|
|
378
|
+
// The converter fired once (the effect ran in applyResult) and is in flight →
|
|
379
|
+
// the dashboard banner state is live. (The snapshot the reducer just folded was
|
|
380
|
+
// built BEFORE the effect ran, so its `building` is still false — the in-flight
|
|
381
|
+
// hold shows on the NEXT fold below.)
|
|
382
|
+
assert.equal(ensureCalls, 1);
|
|
383
|
+
assert.deepEqual(loop.imageBuildState(), {
|
|
384
|
+
ref,
|
|
385
|
+
since: '2023-11-14T22:13:20.000Z',
|
|
386
|
+
});
|
|
387
|
+
assert.equal(snapshots.at(-1).image?.ociConfigured, true);
|
|
388
|
+
assert.equal(snapshots.at(-1).image?.ready, false);
|
|
389
|
+
// A fold while the build is in flight sees `building: true` (the gate holds) and
|
|
390
|
+
// does NOT probe the half-written store.
|
|
391
|
+
loop.dispatch({ kind: 'operator_nudge' });
|
|
392
|
+
assert.equal(snapshots.at(-1).image?.building, true);
|
|
393
|
+
assert.equal(snapshots.at(-1).image?.ready, false);
|
|
394
|
+
assert.equal(ensureCalls, 1, 'no second converter run while one is in flight');
|
|
395
|
+
// Finish the build; drain microtasks so ensureImage's continuation runs.
|
|
396
|
+
resolveBuild();
|
|
397
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
398
|
+
// Banner cleared; a fresh fold re-probes and now finds the cached asset (gate releases).
|
|
399
|
+
assert.equal(loop.imageBuildState(), null);
|
|
400
|
+
loop.dispatch({ kind: 'operator_nudge' });
|
|
401
|
+
assert.equal(snapshots.at(-1).image?.ready, true);
|
|
402
|
+
assert.equal(snapshots.at(-1).image?.building, false);
|
|
403
|
+
// The converter's resolved selector is now live: the runner threads this into the
|
|
404
|
+
// VmPlan so a workflow that sets only `oci_image` boots the cached asset (#206).
|
|
405
|
+
assert.equal(loop.effectiveImageSelector(), 'build-converted-1');
|
|
406
|
+
});
|
|
407
|
+
test('image readiness is digest-based: a moving tag whose digest changed reconverts (issue 206 rework)', async () => {
|
|
408
|
+
// The blocker the prior review flagged: readiness keyed on the ref STRING reported
|
|
409
|
+
// "ready" forever once a ref converted once, so a moving tag (`repo:latest`) whose
|
|
410
|
+
// underlying image changed kept booting the stale selector. Here the SAME ref
|
|
411
|
+
// resolves first to digest A (selector A), then to digest B — and reconcile must
|
|
412
|
+
// stop dispatching A, hold + ensure for B, and resume with selector B.
|
|
413
|
+
const ref = 'repo:latest';
|
|
414
|
+
const store = new Map(); // digest → selector (the converter's cache)
|
|
415
|
+
let currentDigest = 'sha256:AAAA';
|
|
416
|
+
const ociCfg = () => ({ ...tickConfig(), ociImage: ref });
|
|
417
|
+
const ensure = () => ({
|
|
418
|
+
dispatch: [],
|
|
419
|
+
effects: [{ family: 'image', kind: 'ensure', ref }],
|
|
420
|
+
claim: [],
|
|
421
|
+
release: [],
|
|
422
|
+
});
|
|
423
|
+
const idle = () => ({ dispatch: [], effects: [], claim: [], release: [] });
|
|
424
|
+
const { loop, snapshots } = makeLoop([ensure(), idle(), idle(), ensure(), idle()], {
|
|
425
|
+
readConfig: ociCfg,
|
|
426
|
+
probeImage: () => ({ digest: currentDigest, selector: store.get(currentDigest) ?? null }),
|
|
427
|
+
ensureImage: async () => {
|
|
428
|
+
const selector = `selector-${currentDigest}`;
|
|
429
|
+
store.set(currentDigest, selector); // convert + tag the asset at the live digest
|
|
430
|
+
return selector;
|
|
431
|
+
},
|
|
432
|
+
});
|
|
433
|
+
// Tick 1: digest A, nothing cached → core emits ensure (we drive it via the canned
|
|
434
|
+
// result); the converter builds + tags A. Drain microtasks so it completes.
|
|
435
|
+
loop.dispatch({ kind: 'operator_nudge' });
|
|
436
|
+
assert.equal(snapshots.at(-1).image?.ready, false);
|
|
437
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
438
|
+
// Tick 2: a fresh probe finds A cached → ready, and dispatch boots selector A.
|
|
439
|
+
loop.dispatch({ kind: 'operator_nudge' });
|
|
440
|
+
assert.equal(snapshots.at(-1).image?.ready, true);
|
|
441
|
+
assert.equal(loop.effectiveImageSelector(), 'selector-sha256:AAAA');
|
|
442
|
+
// The tag MOVES: the same ref now resolves to digest B (B is not yet converted).
|
|
443
|
+
currentDigest = 'sha256:BBBB';
|
|
444
|
+
// Tick 3: readiness re-probes the LIVE digest → B has no cached asset → NOT ready,
|
|
445
|
+
// so the gate holds dispatch and effectiveImageSelector drops the stale A selector.
|
|
446
|
+
loop.dispatch({ kind: 'operator_nudge' });
|
|
447
|
+
assert.equal(snapshots.at(-1).image?.ready, false, 'stale digest A is no longer reported ready');
|
|
448
|
+
assert.equal(snapshots.at(-1).image?.building, false);
|
|
449
|
+
assert.equal(snapshots.at(-1).image?.failed, false, 'a fresh digest is not failure-suppressed');
|
|
450
|
+
assert.equal(loop.effectiveImageSelector(), null, 'dispatch stops booting the stale selector A');
|
|
451
|
+
// Tick 4: core emits ensure for B (canned); the converter builds + tags B.
|
|
452
|
+
loop.dispatch({ kind: 'operator_nudge' });
|
|
453
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
454
|
+
// Tick 5: B is now cached → ready again, and dispatch resumes with selector B.
|
|
455
|
+
loop.dispatch({ kind: 'operator_nudge' });
|
|
456
|
+
assert.equal(snapshots.at(-1).image?.ready, true);
|
|
457
|
+
assert.equal(loop.effectiveImageSelector(), 'selector-sha256:BBBB', 'dispatch resumes with the new digest B selector');
|
|
458
|
+
});
|
|
459
|
+
test('image conversion failure: the failure banner stays visible while dispatch is held, then a moved tag clears it (issue 206 review)', async () => {
|
|
460
|
+
// The blocker the prior review flagged: a failed conversion cleared the in-flight
|
|
461
|
+
// build state but left dispatch HELD with NO dashboard-visible failure. Here the
|
|
462
|
+
// converter THROWS; the loop must (a) clear the in-flight banner, (b) expose a
|
|
463
|
+
// persistent failure banner carrying the ref + error, and (c) keep readiness
|
|
464
|
+
// `failed` so the core gate holds dispatch + suppresses an auto-retry — until the
|
|
465
|
+
// tag moves to a fresh digest, which supersedes the failure and lets the gate retry.
|
|
466
|
+
const ref = 'ghcr.io/acme/agent:1';
|
|
467
|
+
let currentDigest = 'sha256:AAAA';
|
|
468
|
+
const ociCfg = () => ({ ...tickConfig(), ociImage: ref });
|
|
469
|
+
const idle = () => ({ dispatch: [], effects: [], claim: [], release: [] });
|
|
470
|
+
const ensure = () => ({
|
|
471
|
+
dispatch: [],
|
|
472
|
+
effects: [{ family: 'image', kind: 'ensure', ref }],
|
|
473
|
+
claim: [],
|
|
474
|
+
release: [],
|
|
475
|
+
});
|
|
476
|
+
let ensureCalls = 0;
|
|
477
|
+
const { loop, snapshots } = makeLoop([ensure(), idle(), idle()], {
|
|
478
|
+
readConfig: ociCfg,
|
|
479
|
+
probeImage: () => ({ digest: currentDigest, selector: null }), // never cached (the build fails)
|
|
480
|
+
ensureImage: async () => {
|
|
481
|
+
ensureCalls += 1;
|
|
482
|
+
throw new Error('manifest unknown');
|
|
483
|
+
},
|
|
484
|
+
});
|
|
485
|
+
// Tick 1: core emitted ensure (canned); the converter runs and THROWS. Drain microtasks.
|
|
486
|
+
loop.dispatch({ kind: 'operator_nudge' });
|
|
487
|
+
assert.equal(ensureCalls, 1);
|
|
488
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
489
|
+
// The in-flight banner cleared, but the failure banner is now live with ref + error.
|
|
490
|
+
assert.equal(loop.imageBuildState(), null, 'the in-flight build banner cleared');
|
|
491
|
+
assert.deepEqual(loop.imageFailureState(), {
|
|
492
|
+
ref,
|
|
493
|
+
since: '2023-11-14T22:13:20.000Z',
|
|
494
|
+
message: 'manifest unknown',
|
|
495
|
+
});
|
|
496
|
+
// Tick 2: a fresh fold re-probes the SAME digest → still not cached → readiness
|
|
497
|
+
// reports `failed` (the core gate then holds dispatch + suppresses an auto-retry,
|
|
498
|
+
// covered by image-decide.test.ts), and the failure banner stays visible.
|
|
499
|
+
loop.dispatch({ kind: 'operator_nudge' });
|
|
500
|
+
assert.equal(snapshots.at(-1).image?.ready, false);
|
|
501
|
+
assert.equal(snapshots.at(-1).image?.failed, true, 'a failed digest keeps dispatch held + suppresses re-emit');
|
|
502
|
+
assert.equal(loop.imageFailureState()?.message, 'manifest unknown', 'the failure banner persists while held');
|
|
503
|
+
assert.equal(ensureCalls, 1, 'no auto-retry while the same digest is failure-suppressed');
|
|
504
|
+
// The tag MOVES to a fresh digest: the failure is superseded → readiness flips off
|
|
505
|
+
// `failed` (so the gate re-emits ensure) and the failure banner clears.
|
|
506
|
+
currentDigest = 'sha256:BBBB';
|
|
507
|
+
loop.dispatch({ kind: 'operator_nudge' });
|
|
508
|
+
assert.equal(snapshots.at(-1).image?.failed, false, 'a fresh digest is not failure-suppressed');
|
|
509
|
+
assert.equal(loop.imageFailureState(), null, 'the failure banner cleared once the digest moved');
|
|
510
|
+
});
|
|
511
|
+
test('both image keys set: the snapshot carries the escape hatch so the gate can give it precedence (issue 206)', () => {
|
|
512
|
+
// The prior review's blocker: the poll snapshot only fed core the oci_image
|
|
513
|
+
// readiness, so a not-yet-converted oci_image held dispatch even when the
|
|
514
|
+
// `gondolin.image` escape hatch was set and WINS the runtime selector. The loop's
|
|
515
|
+
// job is to BUILD the snapshot; the reducer (tick.test.ts) decides. Here we prove
|
|
516
|
+
// the snapshot now carries BOTH selectors, so the real reducer can short-circuit.
|
|
517
|
+
const ref = 'ghcr.io/acme/agent:1';
|
|
518
|
+
const bothCfg = () => ({ ...tickConfig(), image: 'prebuilt-asset:1', ociImage: ref });
|
|
519
|
+
let probes = 0;
|
|
520
|
+
const { loop, snapshots } = makeLoop([], {
|
|
521
|
+
readConfig: bothCfg,
|
|
522
|
+
// oci_image is NOT converted (no cached selector) — yet the escape hatch wins.
|
|
523
|
+
probeImage: () => {
|
|
524
|
+
probes += 1;
|
|
525
|
+
return { digest: 'sha256:AAAA', selector: null };
|
|
526
|
+
},
|
|
527
|
+
});
|
|
528
|
+
loop.dispatch({ kind: 'operator_nudge' });
|
|
529
|
+
const snap = snapshots.at(-1);
|
|
530
|
+
// The escape hatch rides in the reducer's config input (so it can take precedence)…
|
|
531
|
+
assert.equal(snap.cfg.image, 'prebuilt-asset:1');
|
|
532
|
+
assert.equal(snap.cfg.ociImage, ref);
|
|
533
|
+
// …alongside the (not-ready) oci readiness the shell still projects.
|
|
534
|
+
assert.equal(snap.image?.ociConfigured, true);
|
|
535
|
+
assert.equal(snap.image?.ready, false);
|
|
536
|
+
assert.ok(probes >= 1, 'the shell projected the oci readiness for the reducer to weigh');
|
|
537
|
+
});
|
|
538
|
+
/** A worker-exit event for the seeded entry; the breaker/retry fields are inert here. */
|
|
539
|
+
function exitEvent(issueId) {
|
|
540
|
+
return {
|
|
541
|
+
kind: 'worker_exit',
|
|
542
|
+
issueId,
|
|
543
|
+
identifier: issueId,
|
|
544
|
+
normal: true,
|
|
545
|
+
reason: 'done',
|
|
546
|
+
priorAttempt: null,
|
|
547
|
+
targetState: 'Review',
|
|
548
|
+
progress: { issue_id: issueId, identifier: issueId, last_transition: null },
|
|
549
|
+
trackerRootAtDispatch: '/tracker',
|
|
550
|
+
resolvedActor: null,
|
|
551
|
+
};
|
|
552
|
+
}
|
|
553
|
+
test('onWorkerExit removes the live entry (frees the slot) and folds the exit excluding it', () => {
|
|
554
|
+
const plan = { issue: issue('i1'), attempt: null, trackerRoot: '/tracker' };
|
|
555
|
+
const { loop, executed, snapshots } = makeLoop([
|
|
556
|
+
{ dispatch: [plan], effects: [], claim: ['i1'], release: [] },
|
|
557
|
+
// The worker_exit fold result — its exact shape is core's job (tick.test.ts);
|
|
558
|
+
// here we assert the loop removed the entry and folded the exit through core.
|
|
559
|
+
{ dispatch: [], effects: [], claim: [], release: [], breaker: { op: 'clear', issueId: 'i1' } },
|
|
560
|
+
]);
|
|
561
|
+
seedRunning(loop);
|
|
562
|
+
assert.equal(loop.runningEntries().length, 1, 'the dispatch plan seeded a live entry');
|
|
563
|
+
loop.onWorkerExit(exitEvent('i1'));
|
|
564
|
+
// The entry was removed (slot freed) BEFORE the reducer folded the exit, so the
|
|
565
|
+
// snapshot the reducer saw — and thus its slot accounting — excludes it.
|
|
566
|
+
assert.equal(loop.runningEntries().length, 0, 'worker exit removed the entry, freeing its slot');
|
|
567
|
+
assert.equal(executed.at(-1)?.kind, 'worker_exit', 'the exit folded through the reducer');
|
|
568
|
+
assert.ok(!snapshots.at(-1).running.some((r) => r.issue_id === 'i1'), 'the folded snapshot excluded the exited entry');
|
|
569
|
+
});
|
|
570
|
+
test('onWorkerExit after stop(): drops claim + entry without folding a retry', () => {
|
|
571
|
+
const plan = { issue: issue('i2'), attempt: null, trackerRoot: '/tracker' };
|
|
572
|
+
const { loop, executed } = makeLoop([
|
|
573
|
+
{ dispatch: [plan], effects: [], claim: ['i2'], release: [] },
|
|
574
|
+
]);
|
|
575
|
+
seedRunning(loop);
|
|
576
|
+
assert.equal(loop.runningEntries().length, 1);
|
|
577
|
+
loop.stop(); // races the worker unwind; running map is cleared here
|
|
578
|
+
loop.onWorkerExit(exitEvent('i2'));
|
|
579
|
+
// stop() already cleared running; the exit must not fold a new tick (no retry armed).
|
|
580
|
+
assert.equal(loop.runningEntries().length, 0);
|
|
581
|
+
assert.equal(executed.filter((e) => e.kind === 'worker_exit').length, 0, 'no fold after stop()');
|
|
582
|
+
});
|
|
583
|
+
//# sourceMappingURL=orchestrator-loop.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrator-loop.test.js","sourceRoot":"","sources":["../../../tests/shell/orchestrator-loop.test.ts"],"names":[],"mappings":"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"}
|