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,83 @@
|
|
|
1
|
+
// FCIS rewrite — pure dispatch-eligibility decisions.
|
|
2
|
+
//
|
|
3
|
+
// Ported faithfully from `src/orchestrator-decisions.ts`
|
|
4
|
+
// (computeEligibilityReason / hasNonTerminalBlocker / resolveActorString) of the
|
|
5
|
+
// reference orchestrator. These are deterministic, side-effect-free decision
|
|
6
|
+
// functions: every nondeterministic input (the active/terminal/running/claimed
|
|
7
|
+
// state sets and the per-state slot availability) is passed in as plain data,
|
|
8
|
+
// so the functions stay (data) -> data.
|
|
9
|
+
//
|
|
10
|
+
// The orchestrator shell holds the live tracker view and concurrency
|
|
11
|
+
// bookkeeping; it materialises an EligibilitySnapshot each poll and calls
|
|
12
|
+
// computeEligibilityReason to learn whether an issue may be dispatched. A null
|
|
13
|
+
// return means "dispatch it"; a non-null string is a short, human-facing reason
|
|
14
|
+
// the issue is currently ineligible (surfaced in the run log / dashboard).
|
|
15
|
+
//
|
|
16
|
+
// 100% SYNCHRONOUS. No IO, no clock, no randomness. Imports only from
|
|
17
|
+
// src/types. (NodeNext ESM: .js extension on the relative type import.)
|
|
18
|
+
import { resolveStateKey } from '../state-resolve.js';
|
|
19
|
+
/**
|
|
20
|
+
* Returns null when the issue is eligible to dispatch, otherwise a short reason
|
|
21
|
+
* string. `ignoreOwnClaim` is set by the retry path so an issue's own claim does
|
|
22
|
+
* not block its redispatch.
|
|
23
|
+
*
|
|
24
|
+
* Order of checks mirrors the reference exactly (callers and tests depend on
|
|
25
|
+
* the precedence): required-fields → state-active → already-running →
|
|
26
|
+
* already-claimed → per-state-slot → todo-blocker. The first failing check
|
|
27
|
+
* wins; later checks are not evaluated.
|
|
28
|
+
*/
|
|
29
|
+
export function computeEligibilityReason(issue, ignoreOwnClaim, snap) {
|
|
30
|
+
if (!issue.id || !issue.identifier || !issue.title || !issue.state) {
|
|
31
|
+
return 'missing required issue fields';
|
|
32
|
+
}
|
|
33
|
+
const state = issue.state.toLowerCase();
|
|
34
|
+
if (!snap.active.has(state) || snap.terminal.has(state))
|
|
35
|
+
return 'state not active';
|
|
36
|
+
if (snap.running.has(issue.id))
|
|
37
|
+
return 'already running';
|
|
38
|
+
if (!ignoreOwnClaim && snap.claimed.has(issue.id))
|
|
39
|
+
return 'already claimed';
|
|
40
|
+
if (!snap.perStateSlot(issue.state))
|
|
41
|
+
return 'no per-state slot';
|
|
42
|
+
if (state === 'todo' && hasNonTerminalBlocker(issue, snap.terminal)) {
|
|
43
|
+
return 'has non-terminal blocker';
|
|
44
|
+
}
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* True when the issue has at least one blocker that is NOT in a terminal state.
|
|
49
|
+
* An unresolvable blocker (null `state`) counts as non-terminal — we cannot
|
|
50
|
+
* prove it is done, so we keep the issue blocked. Blocker state membership is
|
|
51
|
+
* tested against the LOWERCASED terminal set.
|
|
52
|
+
*/
|
|
53
|
+
export function hasNonTerminalBlocker(issue, terminal) {
|
|
54
|
+
for (const b of issue.blocked_by) {
|
|
55
|
+
if (!b.state)
|
|
56
|
+
return true;
|
|
57
|
+
if (!terminal.has(b.state.toLowerCase()))
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Resolved actor string (`"<adapter>/<model or 'default'>"`) for the
|
|
64
|
+
* dispatch-time RunningEntry. When the state is not declared in the workflow,
|
|
65
|
+
* falls back to the workflow-level adapter/model (the reference returned null
|
|
66
|
+
* from the canonical-key lookup and substituted the defaults inline; we keep
|
|
67
|
+
* the same observable result — the function always returns a string).
|
|
68
|
+
*
|
|
69
|
+
* Per-state `adapter` overrides the workflow adapter when set. For the model,
|
|
70
|
+
* `undefined` inherits the workflow model while an explicit `null` clears it to
|
|
71
|
+
* `'default'` — matching the StateConfig.model "undefined inherits / null
|
|
72
|
+
* clears" contract.
|
|
73
|
+
*/
|
|
74
|
+
export function resolveActorString(states, workflowAdapter, workflowModel, state) {
|
|
75
|
+
const key = resolveStateKey(states, state);
|
|
76
|
+
if (key === null)
|
|
77
|
+
return `${workflowAdapter}/${workflowModel ?? 'default'}`;
|
|
78
|
+
const s = states[key];
|
|
79
|
+
const adapter = s.adapter ?? workflowAdapter;
|
|
80
|
+
const model = s.model === undefined ? workflowModel : s.model;
|
|
81
|
+
return `${adapter}/${model ?? 'default'}`;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=eligibility.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eligibility.js","sourceRoot":"","sources":["../../../../src/core/schedule/eligibility.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,EAAE;AACF,yDAAyD;AACzD,iFAAiF;AACjF,6EAA6E;AAC7E,+EAA+E;AAC/E,8EAA8E;AAC9E,wCAAwC;AACxC,EAAE;AACF,qEAAqE;AACrE,0EAA0E;AAC1E,+EAA+E;AAC/E,gFAAgF;AAChF,2EAA2E;AAC3E,EAAE;AACF,sEAAsE;AACtE,wEAAwE;AAIxE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAOtD;;;;;;;;;GASG;AACH,MAAM,UAAU,wBAAwB,CACtC,KAAY,EACZ,cAAuB,EACvB,IAAyB;IAEzB,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACnE,OAAO,+BAA+B,CAAC;IACzC,CAAC;IACD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;IACxC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC;QAAE,OAAO,kBAAkB,CAAC;IACnF,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QAAE,OAAO,iBAAiB,CAAC;IACzD,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QAAE,OAAO,iBAAiB,CAAC;IAC5E,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC;QAAE,OAAO,mBAAmB,CAAC;IAChE,IAAI,KAAK,KAAK,MAAM,IAAI,qBAAqB,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACpE,OAAO,0BAA0B,CAAC;IACpC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAY,EAAE,QAA6B;IAC/E,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;QACjC,IAAI,CAAC,CAAC,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QAC1B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YAAE,OAAO,IAAI,CAAC;IACxD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,kBAAkB,CAChC,MAAmC,EACnC,eAAuB,EACvB,aAAwC,EACxC,KAAa;IAEb,MAAM,GAAG,GAAG,eAAe,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC3C,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,GAAG,eAAe,IAAI,aAAa,IAAI,SAAS,EAAE,CAAC;IAC5E,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAE,CAAC;IACvB,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,IAAI,eAAe,CAAC;IAC7C,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAC9D,OAAO,GAAG,OAAO,IAAI,KAAK,IAAI,SAAS,EAAE,CAAC;AAC5C,CAAC"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
// FCIS rewrite — pure per-running-issue reconcile decision.
|
|
2
|
+
//
|
|
3
|
+
// Ported faithfully from `src/orchestrator-decisions.ts`
|
|
4
|
+
// (decideReconcileForIssue / ReconcileAction) of the reference orchestrator.
|
|
5
|
+
// Deterministic and side-effect free: the only inputs are the freshly-fetched
|
|
6
|
+
// tracker view of one running issue and the workflow `states:` map. The shell
|
|
7
|
+
// owns the running-issue bookkeeping and the actual terminate/refresh/cleanup
|
|
8
|
+
// IO; this function only DECIDES which of those to perform.
|
|
9
|
+
//
|
|
10
|
+
// 100% SYNCHRONOUS. No IO, no clock, no randomness, no node: imports. Imports
|
|
11
|
+
// only from src/types. (NodeNext ESM: .js extension on the relative type
|
|
12
|
+
// imports.)
|
|
13
|
+
//
|
|
14
|
+
// The role filters `activeStateNames` / `terminalStateNames` are the canonical
|
|
15
|
+
// pure folds in core/issue/parse.ts (the WIRED home for the state-role helpers);
|
|
16
|
+
// imported from there so the three former copies can't drift.
|
|
17
|
+
import { activeStateNames, terminalStateNames } from '../issue/parse.js';
|
|
18
|
+
/**
|
|
19
|
+
* Per-running-issue reconcile decision based on the freshly-fetched tracker
|
|
20
|
+
* view. Branch precedence is ported exactly from the reference (callers/tests
|
|
21
|
+
* depend on it):
|
|
22
|
+
*
|
|
23
|
+
* 1. Missing row (`fresh === undefined`) → terminate, NO cleanup
|
|
24
|
+
* (`reason: 'tracker_state_missing'`). The issue vanished from the tracker;
|
|
25
|
+
* we can't know whether its workspace is safe to reap, so leave it.
|
|
26
|
+
* 2. Terminal-role state → terminate, cleanup driven BY ROLE
|
|
27
|
+
* (`reason: 'tracker_state_terminal'`). Routing the cleanup flag through
|
|
28
|
+
* the canonical state's `role` (rather than hard-coding `true`) lets a
|
|
29
|
+
* future per-state `cleanup_workspace` flag flip without touching the
|
|
30
|
+
* orchestrator. A terminal-role state cleans up; anything else does not.
|
|
31
|
+
* 3. Active-role state → refresh the in-memory issue snapshot.
|
|
32
|
+
* 4. Anything else (holding, or a state not declared in the workflow) →
|
|
33
|
+
* terminate, NO cleanup (`reason: 'tracker_state_non_active'`).
|
|
34
|
+
*
|
|
35
|
+
* State membership is compared case-insensitively (the tracker may store a
|
|
36
|
+
* differently-cased directory name than the workflow declares), matching the
|
|
37
|
+
* rest of symphony's eligibility/reconcile paths.
|
|
38
|
+
*
|
|
39
|
+
* Thin wrapper over {@link decideReconcileForState}: the only field consulted is
|
|
40
|
+
* `fresh.state`, so the state-keyed decider holds the logic and the operator-move
|
|
41
|
+
* reducer (which has the moved-to state, not a full Issue) shares it verbatim —
|
|
42
|
+
* the poll-loop reconcile and the dashboard move path can't drift (issue 211).
|
|
43
|
+
*/
|
|
44
|
+
export function decideReconcileForIssue(fresh, states) {
|
|
45
|
+
return decideReconcileForState(fresh?.state, states);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* The state-keyed core of {@link decideReconcileForIssue}: decide the reconcile
|
|
49
|
+
* action from a freshly-resolved tracker STATE NAME (or `undefined` for a row that
|
|
50
|
+
* is no longer present). Same branch precedence + case-insensitive matching as the
|
|
51
|
+
* Issue-keyed wrapper; shared by the operator-move reducer, which holds the move
|
|
52
|
+
* target state rather than a full Issue.
|
|
53
|
+
*/
|
|
54
|
+
export function decideReconcileForState(state, states) {
|
|
55
|
+
if (state === undefined) {
|
|
56
|
+
return { kind: 'terminate', cleanup: false, reason: 'tracker_state_missing' };
|
|
57
|
+
}
|
|
58
|
+
const s = state.toLowerCase();
|
|
59
|
+
const terminal = new Set(terminalStateNames(states).map((n) => n.toLowerCase()));
|
|
60
|
+
if (terminal.has(s)) {
|
|
61
|
+
// Cleanup is driven by the canonical state's role: a terminal-role state
|
|
62
|
+
// reaps its workspace, anything matched here that somehow isn't terminal
|
|
63
|
+
// (it can't be, given `terminalStateNames`, but keep the reference's
|
|
64
|
+
// defensive null-handling) does not.
|
|
65
|
+
//
|
|
66
|
+
// Canonicalize via a declaration-order case-insensitive scan over the
|
|
67
|
+
// ALREADY-LOWERCASED `s` — matching the reference exactly
|
|
68
|
+
// (`Object.keys(states).find((n) => n.toLowerCase() === s)`). No
|
|
69
|
+
// exact-own-property short-circuit: the first declared name whose lowercased
|
|
70
|
+
// form equals `s` wins, so a (pathological) name declared twice resolves to
|
|
71
|
+
// the first declaration's role.
|
|
72
|
+
const canonical = Object.keys(states).find((n) => n.toLowerCase() === s);
|
|
73
|
+
const cleanup = canonical !== undefined ? states[canonical].role === 'terminal' : false;
|
|
74
|
+
return { kind: 'terminate', cleanup, reason: 'tracker_state_terminal' };
|
|
75
|
+
}
|
|
76
|
+
const active = new Set(activeStateNames(states).map((n) => n.toLowerCase()));
|
|
77
|
+
if (active.has(s)) {
|
|
78
|
+
return { kind: 'refresh' };
|
|
79
|
+
}
|
|
80
|
+
return { kind: 'terminate', cleanup: false, reason: 'tracker_state_non_active' };
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=reconcile-issue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reconcile-issue.js","sourceRoot":"","sources":["../../../../src/core/schedule/reconcile-issue.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,EAAE;AACF,yDAAyD;AACzD,6EAA6E;AAC7E,8EAA8E;AAC9E,8EAA8E;AAC9E,8EAA8E;AAC9E,4DAA4D;AAC5D,EAAE;AACF,8EAA8E;AAC9E,yEAAyE;AACzE,YAAY;AACZ,EAAE;AACF,+EAA+E;AAC/E,iFAAiF;AACjF,8DAA8D;AAK9D,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEzE;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,uBAAuB,CACrC,KAAwB,EACxB,MAAmC;IAEnC,OAAO,uBAAuB,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;AACvD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,uBAAuB,CACrC,KAAyB,EACzB,MAAmC;IAEnC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,uBAAuB,EAAE,CAAC;IAChF,CAAC;IAED,MAAM,CAAC,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IAE9B,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IACjF,IAAI,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACpB,yEAAyE;QACzE,yEAAyE;QACzE,qEAAqE;QACrE,qCAAqC;QACrC,EAAE;QACF,sEAAsE;QACtE,0DAA0D;QAC1D,iEAAiE;QACjE,6EAA6E;QAC7E,4EAA4E;QAC5E,gCAAgC;QAChC,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC;QACzE,MAAM,OAAO,GAAG,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAE,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC;QACzF,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,wBAAwB,EAAE,CAAC;IAC1E,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IAC7E,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAClB,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAC7B,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,0BAA0B,EAAE,CAAC;AACnF,CAAC"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// FCIS rewrite — pure retry/continuation scheduling core.
|
|
2
|
+
//
|
|
3
|
+
// Ported faithfully from the original `src/orchestrator-decisions.ts`
|
|
4
|
+
// (`decideExitRetry`, `decideRetryAfterIneligible`, `RetrySchedulePlan`). These
|
|
5
|
+
// are the deciders the orchestrator folds over a freshly-exited worker (clean vs
|
|
6
|
+
// abnormal exit) and over a re-polled-but-ineligible retry candidate.
|
|
7
|
+
//
|
|
8
|
+
// Every function here is pure and SYNCHRONOUS: (data) -> data. The only side
|
|
9
|
+
// effect the original orchestrator performed at these sites — arming a timer to
|
|
10
|
+
// redispatch — becomes a returned `timer.schedule_retry` Effect (see
|
|
11
|
+
// `scheduleRetryEffect`), which the shell EXECUTES. No clock, no randomness, no
|
|
12
|
+
// IO. Imports are restricted to src/types.
|
|
13
|
+
/**
|
|
14
|
+
* Exponential-backoff delay for a failure retry, capped at `maxBackoffMs`.
|
|
15
|
+
*
|
|
16
|
+
* `attempt` is the 1-based attempt number being scheduled, so the first failure
|
|
17
|
+
* (`attempt === 1`) waits `baseMs * 2^0 === baseMs`, the second `baseMs * 2`,
|
|
18
|
+
* and so on. Mirrors the inline `Math.min(base * 2^(attempt-1), max)` the
|
|
19
|
+
* original carried at both retry sites.
|
|
20
|
+
*/
|
|
21
|
+
export function backoffDelayMs(attempt, baseMs, maxBackoffMs) {
|
|
22
|
+
return Math.min(baseMs * Math.pow(2, attempt - 1), maxBackoffMs);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Retry schedule for a worker that just exited. A normal exit becomes a
|
|
26
|
+
* `continuation` (short, slot-holding, no error) so the same issue resumes its
|
|
27
|
+
* post-transition state; an abnormal exit becomes a `failure` with exponential
|
|
28
|
+
* backoff capped at `maxBackoffMs` (does NOT hold a slot). `target_state` is
|
|
29
|
+
* whatever state the running entry was carrying at exit time.
|
|
30
|
+
*
|
|
31
|
+
* A `continuation` always reports `attempt: 1` — it is a fresh handoff, not a
|
|
32
|
+
* retry of a prior attempt. A `failure` increments the prior attempt (or starts
|
|
33
|
+
* at 1 when there was none).
|
|
34
|
+
*/
|
|
35
|
+
export function decideExitRetry(input) {
|
|
36
|
+
if (input.normal) {
|
|
37
|
+
return {
|
|
38
|
+
attempt: 1,
|
|
39
|
+
delayMs: input.continuationDelayMs,
|
|
40
|
+
error: null,
|
|
41
|
+
kind: 'continuation',
|
|
42
|
+
target_state: input.targetState,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
const nextAttempt = input.priorAttempt !== null && input.priorAttempt !== undefined ? input.priorAttempt + 1 : 1;
|
|
46
|
+
return {
|
|
47
|
+
attempt: nextAttempt,
|
|
48
|
+
delayMs: backoffDelayMs(nextAttempt, input.failureBaseMs, input.maxBackoffMs),
|
|
49
|
+
error: input.reason,
|
|
50
|
+
kind: 'failure',
|
|
51
|
+
target_state: input.targetState,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/** The no-slot reason that the ineligible path treats as a transient reschedule. */
|
|
55
|
+
export const NO_SLOT_REASON = 'no per-state slot';
|
|
56
|
+
/**
|
|
57
|
+
* Retry-timer response when a re-polled issue is found ineligible. A
|
|
58
|
+
* `no per-state slot` reason yields a failure-backoff reschedule (the loop can
|
|
59
|
+
* dispatch other work during the wait); any other ineligibility releases the
|
|
60
|
+
* claim. Mirrors the inline switch the original orchestrator carried.
|
|
61
|
+
*
|
|
62
|
+
* The reschedule delay backs off on `priorAttempt` (NOT `priorAttempt + 1`):
|
|
63
|
+
* the original computed `base * 2^priorAttempt` for the new `attempt:
|
|
64
|
+
* priorAttempt + 1`, matching `backoffDelayMs(priorAttempt + 1, …)`.
|
|
65
|
+
*/
|
|
66
|
+
export function decideRetryAfterIneligible(input) {
|
|
67
|
+
if (input.reason !== NO_SLOT_REASON)
|
|
68
|
+
return { kind: 'release' };
|
|
69
|
+
const nextAttempt = input.priorAttempt + 1;
|
|
70
|
+
return {
|
|
71
|
+
kind: 'reschedule',
|
|
72
|
+
plan: {
|
|
73
|
+
attempt: nextAttempt,
|
|
74
|
+
delayMs: backoffDelayMs(nextAttempt, input.failureBaseMs, input.maxBackoffMs),
|
|
75
|
+
error: 'no available orchestrator slots',
|
|
76
|
+
kind: 'failure',
|
|
77
|
+
target_state: input.targetState,
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Fold a {@link RetrySchedulePlan} into the `timer.schedule_retry` Effect the
|
|
83
|
+
* shell executes to arm the (continuation or backoff) redispatch. This is the
|
|
84
|
+
* single seam where a retry decision becomes a side effect: core returns the
|
|
85
|
+
* Effect, the shell registers the actual timer.
|
|
86
|
+
*/
|
|
87
|
+
export function scheduleRetryEffect(issueId, identifier, plan) {
|
|
88
|
+
return {
|
|
89
|
+
family: 'timer',
|
|
90
|
+
kind: 'schedule_retry',
|
|
91
|
+
issueId,
|
|
92
|
+
identifier,
|
|
93
|
+
plan,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../../../src/core/schedule/retry.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAC1D,EAAE;AACF,sEAAsE;AACtE,gFAAgF;AAChF,iFAAiF;AACjF,sEAAsE;AACtE,EAAE;AACF,6EAA6E;AAC7E,gFAAgF;AAChF,qEAAqE;AACrE,gFAAgF;AAChF,2CAA2C;AAM3C;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,OAAe,EAAE,MAAc,EAAE,YAAoB;IAClF,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;AACnE,CAAC;AAmBD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,eAAe,CAAC,KAA2B;IACzD,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACjB,OAAO;YACL,OAAO,EAAE,CAAC;YACV,OAAO,EAAE,KAAK,CAAC,mBAAmB;YAClC,KAAK,EAAE,IAAI;YACX,IAAI,EAAE,cAAkC;YACxC,YAAY,EAAE,KAAK,CAAC,WAAW;SAChC,CAAC;IACJ,CAAC;IACD,MAAM,WAAW,GACf,KAAK,CAAC,YAAY,KAAK,IAAI,IAAI,KAAK,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/F,OAAO;QACL,OAAO,EAAE,WAAW;QACpB,OAAO,EAAE,cAAc,CAAC,WAAW,EAAE,KAAK,CAAC,aAAa,EAAE,KAAK,CAAC,YAAY,CAAC;QAC7E,KAAK,EAAE,KAAK,CAAC,MAAM;QACnB,IAAI,EAAE,SAA6B;QACnC,YAAY,EAAE,KAAK,CAAC,WAAW;KAChC,CAAC;AACJ,CAAC;AAED,oFAAoF;AACpF,MAAM,CAAC,MAAM,cAAc,GAAG,mBAAmB,CAAC;AAmBlD;;;;;;;;;GASG;AACH,MAAM,UAAU,0BAA0B,CACxC,KAAsC;IAEtC,IAAI,KAAK,CAAC,MAAM,KAAK,cAAc;QAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAChE,MAAM,WAAW,GAAG,KAAK,CAAC,YAAY,GAAG,CAAC,CAAC;IAC3C,OAAO;QACL,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE;YACJ,OAAO,EAAE,WAAW;YACpB,OAAO,EAAE,cAAc,CAAC,WAAW,EAAE,KAAK,CAAC,aAAa,EAAE,KAAK,CAAC,YAAY,CAAC;YAC7E,KAAK,EAAE,iCAAiC;YACxC,IAAI,EAAE,SAA6B;YACnC,YAAY,EAAE,KAAK,CAAC,WAAW;SAChC;KACF,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CACjC,OAAe,EACf,UAAkB,EAClB,IAAuB;IAEvB,OAAO;QACL,MAAM,EAAE,OAAO;QACf,IAAI,EAAE,gBAAgB;QACtB,OAAO;QACP,UAAU;QACV,IAAI;KACL,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
// FCIS rewrite — pure sleep-cycle (recurring reflection spawn) decisions.
|
|
2
|
+
//
|
|
3
|
+
// The sleep cycle is modelled as a recurring STATE that spawns ephemeral
|
|
4
|
+
// reflection issues, NOT as one immortal ticket parked in a holding state. When
|
|
5
|
+
// the orchestrator has accumulated enough finished work (a `done_threshold`
|
|
6
|
+
// trigger) or goes idle with at least one issue finished since the last cycle (an
|
|
7
|
+
// `idle` trigger), `decideSpawn` mints a FRESH issue into the spawn state. Each
|
|
8
|
+
// reflection is born there, runs once, and terminates in a dedicated terminal —
|
|
9
|
+
// like every other ticket. The shell folds each freshly-exited worker into a
|
|
10
|
+
// terminal-transition counter via `recordSleepCycleProgress`, then each poll asks
|
|
11
|
+
// `decideSpawn` whether a trigger fires; on a fire it returns the new issue's
|
|
12
|
+
// title + body (provenance the static prompt can't know), which the shell turns
|
|
13
|
+
// into a create-issue effect, resetting the counter only on a successful mint.
|
|
14
|
+
//
|
|
15
|
+
// 100% SYNCHRONOUS. No IO, no clock, no randomness, no node: imports. Every
|
|
16
|
+
// decision is (data) -> data; the only side effect the shell performs at these
|
|
17
|
+
// sites (the async create + counter reset) stays in the shell — core just returns
|
|
18
|
+
// the spawn intent / note text / next counter value. The "now" stamp is injected
|
|
19
|
+
// as `nowIso` data (the same "inject the clock as data" precedent as
|
|
20
|
+
// `summarizeRunLog`'s required `generatedAt`). Imports only from src/types.
|
|
21
|
+
// (NodeNext ESM: .js extension on the relative type import.)
|
|
22
|
+
/**
|
|
23
|
+
* Decide whether to mint a fresh reflection issue this tick, and on which
|
|
24
|
+
* trigger. Returns the spawn intent (trigger + derived title/body) or null when
|
|
25
|
+
* no trigger fires.
|
|
26
|
+
*
|
|
27
|
+
* The done-threshold trigger takes precedence over idle when both hold (it's
|
|
28
|
+
* the stronger, count-based signal — handy for the operator-visible log line).
|
|
29
|
+
*
|
|
30
|
+
* The idle trigger is deliberately gated on `doneSinceReflect > 0`: an idle
|
|
31
|
+
* orchestrator with nothing finished since the last cycle has nothing new to
|
|
32
|
+
* reflect on, and spawning anyway would spin (spawn -> reflect -> terminal ->
|
|
33
|
+
* idle -> spawn ...) forever. Requiring fresh terminal work breaks that loop
|
|
34
|
+
* while still honoring the "sleep when not busy" framing.
|
|
35
|
+
*
|
|
36
|
+
* `max_in_flight` is load-bearing: minting removed the immortal ticket's built-in
|
|
37
|
+
* "one location = one reflection" mutex, so without this guard a busy stretch's
|
|
38
|
+
* `after_terminal` trigger could mint a second cycle while one is still live.
|
|
39
|
+
* When `inFlight >= maxInFlight` no issue is minted, regardless of trigger.
|
|
40
|
+
*
|
|
41
|
+
* Returns null when spawning is disabled, the in-flight cap is reached, or no
|
|
42
|
+
* trigger fires.
|
|
43
|
+
*/
|
|
44
|
+
export function decideSpawn(input) {
|
|
45
|
+
if (!input.enabled)
|
|
46
|
+
return null;
|
|
47
|
+
// Never mint a second while one (or `maxInFlight`) is already live in the spawn
|
|
48
|
+
// state — the recurring-state replacement for the immortal ticket's mutex.
|
|
49
|
+
if (input.inFlight >= input.maxInFlight)
|
|
50
|
+
return null;
|
|
51
|
+
const trigger = decideTrigger(input);
|
|
52
|
+
if (trigger === null)
|
|
53
|
+
return null;
|
|
54
|
+
return {
|
|
55
|
+
trigger,
|
|
56
|
+
title: renderTitle(input.titleTemplate, input.nowIso),
|
|
57
|
+
body: spawnBody(trigger, input.doneSinceReflect, input.afterTerminal, input.nowIso, input.bodyLeadIn),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/** Which trigger (if any) fires this tick — the pure trigger half of {@link decideSpawn}. */
|
|
61
|
+
function decideTrigger(input) {
|
|
62
|
+
if (input.afterTerminal > 0 && input.doneSinceReflect >= input.afterTerminal) {
|
|
63
|
+
return 'done_threshold';
|
|
64
|
+
}
|
|
65
|
+
if (input.onIdle && input.idle && input.doneSinceReflect > 0)
|
|
66
|
+
return 'idle';
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Render the minted issue's title from the configured template, substituting a
|
|
71
|
+
* human-readable `{{ stamp }}` (e.g. `2026-06-03 13:56`) derived purely from the
|
|
72
|
+
* injected `nowIso`. A template with no placeholder is used verbatim.
|
|
73
|
+
*/
|
|
74
|
+
function renderTitle(template, nowIso) {
|
|
75
|
+
return template.replace(/\{\{\s*stamp\s*\}\}/g, readableStamp(nowIso));
|
|
76
|
+
}
|
|
77
|
+
/** `2026-06-03T13:56:12.000Z` → `2026-06-03 13:56` (date + HH:MM, no seconds/Z). Pure. */
|
|
78
|
+
function readableStamp(nowIso) {
|
|
79
|
+
return nowIso.slice(0, 16).replace('T', ' ');
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* The provenance body for the minted reflection issue. Plain text, generated once
|
|
83
|
+
* at mint — the point-in-time provenance the static `prompts/Reflect.md` can't
|
|
84
|
+
* know (the trigger, the counter, the timestamp). It exists for the human reading
|
|
85
|
+
* the archived issue later; the reflector itself works from the prompt + the
|
|
86
|
+
* eval_mode mounts, not from this body. NO instructions / guardrails (those live
|
|
87
|
+
* in the prompt) and NO templating (the issue body is inert data the prompt
|
|
88
|
+
* interpolates, not a Liquid template).
|
|
89
|
+
*/
|
|
90
|
+
function spawnBody(trigger, doneSinceReflect, afterTerminal, nowIso, leadIn) {
|
|
91
|
+
const why = trigger === 'done_threshold'
|
|
92
|
+
? `${doneSinceReflect} issues reached a terminal state since the last reflection cycle (threshold: ${afterTerminal}).`
|
|
93
|
+
: `the orchestrator went idle with ${doneSinceReflect} issue(s) finished since the last reflection cycle.`;
|
|
94
|
+
return [
|
|
95
|
+
leadIn && leadIn.length > 0 ? leadIn : 'Auto-spawned reflection cycle.',
|
|
96
|
+
'',
|
|
97
|
+
`Trigger: ${trigger} — ${why}`,
|
|
98
|
+
`Spawned at: ${nowIso}.`,
|
|
99
|
+
].join('\n');
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Fold a freshly-exited worker into the terminal-transition counter the sleep
|
|
103
|
+
* cycle triggers read, returning the NEXT counter value (the original mutated
|
|
104
|
+
* `this.doneSinceReflect`; here it is pure).
|
|
105
|
+
*
|
|
106
|
+
* Only the work the reflector mines counts — a transition into a `role: terminal`
|
|
107
|
+
* state (Done / Cancelled / the spawn's terminal), as recorded by
|
|
108
|
+
* `last_transition.terminal`. A reflection's OWN terminal move is excluded
|
|
109
|
+
* STRUCTURALLY — by its from-state, not a fixed issue id: with ephemeral
|
|
110
|
+
* reflections there is no immortal ticket to match, so any terminal transition
|
|
111
|
+
* ORIGINATING from the spawn state is a finished reflection's own move and must
|
|
112
|
+
* not count toward spawning the next cycle (else the cycle never settles). A
|
|
113
|
+
* non-terminal exit (a continuation, a reroute) never advances the counter.
|
|
114
|
+
*
|
|
115
|
+
* `spawnState` is the configured spawn state (`SpawnRouting.spawnState`); a null
|
|
116
|
+
* value means spawning is unconfigured, in which case the counter is left
|
|
117
|
+
* untouched (matching the original's disabled-block no-op).
|
|
118
|
+
*/
|
|
119
|
+
export function recordSleepCycleProgress(doneSinceReflect, entry, spawnState) {
|
|
120
|
+
// Spawning unconfigured: never advance the counter.
|
|
121
|
+
if (!spawnState)
|
|
122
|
+
return doneSinceReflect;
|
|
123
|
+
const t = entry.last_transition;
|
|
124
|
+
// Only a terminal transition (into a role: terminal state) is mineable work.
|
|
125
|
+
if (!t?.terminal)
|
|
126
|
+
return doneSinceReflect;
|
|
127
|
+
// A reflection's own terminal move (out of the spawn state) never counts toward
|
|
128
|
+
// spawning the next cycle — exclude it structurally by its from-state.
|
|
129
|
+
if (t.from_state.toLowerCase() === spawnState.toLowerCase())
|
|
130
|
+
return doneSinceReflect;
|
|
131
|
+
return doneSinceReflect + 1;
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=sleep-cycle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sleep-cycle.js","sourceRoot":"","sources":["../../../../src/core/schedule/sleep-cycle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
// FCIS rewrite — pure slot accounting (functional core).
|
|
2
|
+
//
|
|
3
|
+
// Ports the orchestrator's concurrency gate (REF: src/orchestrator.ts
|
|
4
|
+
// `availableGlobalSlots`, `hasPerStateSlot`, `perStateConcurrencyCap`,
|
|
5
|
+
// `sortForDispatch`) into pure, synchronous functions over plain-data
|
|
6
|
+
// snapshots.
|
|
7
|
+
//
|
|
8
|
+
// The keystone behaviour this module owns:
|
|
9
|
+
// - GLOBAL slots: max(0, effectiveCap - running - pendingContinuations)
|
|
10
|
+
// - PER-STATE slots: inState < cap && globalSlots > 0 (cap from config)
|
|
11
|
+
// - CONTINUATIONS HOLD A SLOT, FAILURES DO NOT. A continuation is the
|
|
12
|
+
// post-transition resume of an issue that just normal-exited; reserving its
|
|
13
|
+
// slot during the (short) continuation delay stops a tick that fires inside
|
|
14
|
+
// that window from dispatching a brand-new issue and stealing the slot the
|
|
15
|
+
// resuming worker is about to reclaim. Failure-backoff retries do NOT hold a
|
|
16
|
+
// slot, so the orchestrator is free to run other work during the backoff.
|
|
17
|
+
// - sortForDispatch: priority ASC (null last), created_at ASC (unparseable
|
|
18
|
+
// last), identifier localeCompare as the final tiebreak.
|
|
19
|
+
//
|
|
20
|
+
// This module is given the ALREADY-RESOLVED effective cap (the memory-admission
|
|
21
|
+
// clamp is a separate core concern that folds a /proc/meminfo probe + config
|
|
22
|
+
// into `effectiveCap`); slot accounting just reads it from the snapshot so the
|
|
23
|
+
// snapshot endpoint and the dispatch loop can never desync. Nothing here reads
|
|
24
|
+
// the clock, randomness, or any IO — `created_at` is parsed deterministically
|
|
25
|
+
// from the issue's ISO string via the injected `parseTimestamp` (default uses
|
|
26
|
+
// Date.parse, which is pure — it does not read the wall clock).
|
|
27
|
+
/** Count pending retries that hold a slot (continuations only). */
|
|
28
|
+
function pendingContinuationCount(pendingRetries) {
|
|
29
|
+
let n = 0;
|
|
30
|
+
for (const r of pendingRetries) {
|
|
31
|
+
if (r.kind === 'continuation')
|
|
32
|
+
n++;
|
|
33
|
+
}
|
|
34
|
+
return n;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Global available-slot count.
|
|
38
|
+
*
|
|
39
|
+
* REF: `availableGlobalSlots()` — `max(0, effective_cap - running - pendingContinuations)`.
|
|
40
|
+
* Pending continuations are reserved against the cap; failure-backoff retries
|
|
41
|
+
* are not (they are absent from the holding set by construction — only `kind ===
|
|
42
|
+
* 'continuation'` entries count).
|
|
43
|
+
*/
|
|
44
|
+
export function availableGlobalSlots(snapshot) {
|
|
45
|
+
const held = pendingContinuationCount(snapshot.pendingRetries);
|
|
46
|
+
return Math.max(0, snapshot.effectiveCap - snapshot.runningCount - held);
|
|
47
|
+
}
|
|
48
|
+
/** True iff the global gate has at least one free slot. */
|
|
49
|
+
export function hasGlobalSlot(snapshot) {
|
|
50
|
+
return availableGlobalSlots(snapshot) > 0;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Resolve a state's per-state concurrency cap (`states.<name>.max_concurrent`)
|
|
54
|
+
* with a case-insensitive name lookup, mirroring how issue states arrive from
|
|
55
|
+
* the tracker in arbitrary case.
|
|
56
|
+
*
|
|
57
|
+
* REF: `perStateConcurrencyCap()`. Returns `undefined` when the state is
|
|
58
|
+
* unknown, declares no cap, or declares a zero cap — in REF, `if (!cap)` treats
|
|
59
|
+
* both `undefined` and `0` as "no per-state cap, only the global ceiling
|
|
60
|
+
* applies," so we collapse them to `undefined` here.
|
|
61
|
+
*/
|
|
62
|
+
export function resolvePerStateCap(stateName, caps) {
|
|
63
|
+
const lower = stateName.toLowerCase();
|
|
64
|
+
for (const name of Object.keys(caps)) {
|
|
65
|
+
if (name.toLowerCase() === lower) {
|
|
66
|
+
const cap = caps[name]?.max_concurrent;
|
|
67
|
+
return cap ? cap : undefined;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Per-state slot accounting.
|
|
74
|
+
*
|
|
75
|
+
* REF: `hasPerStateSlot()`. With no per-state cap declared the global gate is
|
|
76
|
+
* the only constraint. With a cap, count the running attempts in that state
|
|
77
|
+
* PLUS any pending continuation whose target state matches (so the resuming
|
|
78
|
+
* worker is guaranteed its slot when the timer fires), and require both
|
|
79
|
+
* `inState < cap` and a free global slot.
|
|
80
|
+
*
|
|
81
|
+
* `caps` is the `states` config keyed by state name (case-insensitive lookup).
|
|
82
|
+
*/
|
|
83
|
+
export function hasPerStateSlot(stateName, snapshot, caps) {
|
|
84
|
+
const cap = resolvePerStateCap(stateName, caps);
|
|
85
|
+
if (cap === undefined)
|
|
86
|
+
return hasGlobalSlot(snapshot);
|
|
87
|
+
const lower = stateName.toLowerCase();
|
|
88
|
+
let inState = 0;
|
|
89
|
+
for (const s of snapshot.runningStates) {
|
|
90
|
+
if (s.toLowerCase() === lower)
|
|
91
|
+
inState++;
|
|
92
|
+
}
|
|
93
|
+
for (const r of snapshot.pendingRetries) {
|
|
94
|
+
if (r.kind === 'continuation' && r.target_state.toLowerCase() === lower) {
|
|
95
|
+
inState++;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return inState < cap && hasGlobalSlot(snapshot);
|
|
99
|
+
}
|
|
100
|
+
const defaultParseTimestamp = (iso) => iso ? Date.parse(iso) : Number.NaN;
|
|
101
|
+
/**
|
|
102
|
+
* Dispatch ordering.
|
|
103
|
+
*
|
|
104
|
+
* REF: `sortForDispatch()` — priority ASC with null priority ordered last,
|
|
105
|
+
* then created_at ASC with unparseable/null created_at ordered last, then
|
|
106
|
+
* identifier `localeCompare` as the final stable tiebreak. Returns a NEW array
|
|
107
|
+
* (does not mutate the input).
|
|
108
|
+
*/
|
|
109
|
+
export function sortForDispatch(issues, parseTimestamp = defaultParseTimestamp) {
|
|
110
|
+
return [...issues].sort((a, b) => {
|
|
111
|
+
const pa = a.priority ?? Number.POSITIVE_INFINITY;
|
|
112
|
+
const pb = b.priority ?? Number.POSITIVE_INFINITY;
|
|
113
|
+
if (pa !== pb)
|
|
114
|
+
return pa - pb;
|
|
115
|
+
const rawA = parseTimestamp(a.created_at);
|
|
116
|
+
const rawB = parseTimestamp(b.created_at);
|
|
117
|
+
const ca = Number.isFinite(rawA) ? rawA : Number.POSITIVE_INFINITY;
|
|
118
|
+
const cb = Number.isFinite(rawB) ? rawB : Number.POSITIVE_INFINITY;
|
|
119
|
+
if (Number.isFinite(ca) && Number.isFinite(cb) && ca !== cb)
|
|
120
|
+
return ca - cb;
|
|
121
|
+
return a.identifier.localeCompare(b.identifier);
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=slots.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slots.js","sourceRoot":"","sources":["../../../../src/core/schedule/slots.ts"],"names":[],"mappings":"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"}
|