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,207 @@
|
|
|
1
|
+
// FCIS rewrite — pure VM-reaper KILL state machine (the per-session
|
|
2
|
+
// SIGTERM → grace → probe → SIGKILL escalation).
|
|
3
|
+
//
|
|
4
|
+
// Ported faithfully from the reference `VmResource.killSession`
|
|
5
|
+
// (REF: src/reconciler/vm.ts). The reference was a single async method that
|
|
6
|
+
// interleaved IO (`process.kill`, an inline `setTimeout` grace) with ledger
|
|
7
|
+
// bookkeeping. Under FCIS that method splits into two halves:
|
|
8
|
+
//
|
|
9
|
+
// • the SHELL drives the loop and performs the IO — it sends each host signal
|
|
10
|
+
// (a `process.kill`-backed `ProcessEffect`), sleeps the grace window (a
|
|
11
|
+
// `TimerEffect`), and probes liveness (signal-0). After each it hands the
|
|
12
|
+
// observed `KillStepResult` back here.
|
|
13
|
+
// • this CORE owns every DECISION as a pure fold: given the current `KillStep`
|
|
14
|
+
// (which signal/probe is in flight) and the `KillStepResult` the shell just
|
|
15
|
+
// observed, it returns the NEXT `KillStep` (wrapped as a `ReaperEffect` +,
|
|
16
|
+
// for `wait_grace`, the matching `TimerEffect`) PLUS the ledger transition
|
|
17
|
+
// to record. No IO, no clock, no `process`.
|
|
18
|
+
//
|
|
19
|
+
// The escalation, branch-for-branch with the reference:
|
|
20
|
+
//
|
|
21
|
+
// ① SIGTERM (start key, send SIGTERM).
|
|
22
|
+
// gone(ESRCH) → already dead → ledger done. (ref: ESRCH→done)
|
|
23
|
+
// no_perm(EPERM)→ can't signal → ledger error. (ref: throw→error)
|
|
24
|
+
// signalled → enter the grace window (wait_grace). (ref: await sleep)
|
|
25
|
+
// ② wait_grace (sleep killGraceMs), then probe.
|
|
26
|
+
// signalled → grace elapsed → probe liveness.
|
|
27
|
+
// ③ probe (signal 0 — liveness test).
|
|
28
|
+
// gone(ESRCH) → exited during grace → ledger done. (ref: !alive→done)
|
|
29
|
+
// no_perm(EPERM)→ alive but unreachable → ledger error. (ref: code!==ESRCH→error)
|
|
30
|
+
// alive(signal0 ok) → still running → escalate to SIGKILL.
|
|
31
|
+
// ④ SIGKILL.
|
|
32
|
+
// gone(ESRCH) → raced to exit → ledger done. (ref: ESRCH→done)
|
|
33
|
+
// signalled → killed → ledger done. (ref: success→done)
|
|
34
|
+
// no_perm(EPERM)→ unkillable → ledger error. (ref: throw→error)
|
|
35
|
+
//
|
|
36
|
+
// Pid safety (the keystone): the host signal is delivered by `process.kill`,
|
|
37
|
+
// which signals the whole PROCESS GROUP for `pid <= 0` and would target the
|
|
38
|
+
// orchestrator itself for `pid === selfPid`. `decideVm` already excludes those,
|
|
39
|
+
// but the reference re-guards once more before any signal leaves the shell
|
|
40
|
+
// ("belt-and-suspenders"). That guard is reproduced PURELY here in
|
|
41
|
+
// {@link beginKill}: an unsafe pid never yields a `signal` step — it yields an
|
|
42
|
+
// immediate terminal error decision, so the shell has no path to call
|
|
43
|
+
// `process.kill` on a bad pid.
|
|
44
|
+
//
|
|
45
|
+
// 100% SYNCHRONOUS. No async / await / Promise. No IO, no node: imports, no
|
|
46
|
+
// wall clock or randomness. Imports ONLY from src/types. (NodeNext ESM → .js
|
|
47
|
+
// extensions on relative imports.)
|
|
48
|
+
/**
|
|
49
|
+
* SIGTERM-to-SIGKILL grace period (ms). A session runner that ignores SIGTERM is
|
|
50
|
+
* SIGKILL'd after this delay. Mirrors the reference `DEFAULT_KILL_GRACE_MS`.
|
|
51
|
+
* Tests pass a small value so the grace path is observable in fast suites; the
|
|
52
|
+
* value is injected into {@link beginKill} (core never reads a config or a clock).
|
|
53
|
+
*/
|
|
54
|
+
export const DEFAULT_KILL_GRACE_MS = 3_000;
|
|
55
|
+
/** The ledger key for one session's kill action — `kill_session:<pid>` (ref). */
|
|
56
|
+
export function killKey(pid) {
|
|
57
|
+
return `kill_session:${pid}`;
|
|
58
|
+
}
|
|
59
|
+
/** Wrap a `KillStep` as the `reaper` Effect the shell's interpreter drains. */
|
|
60
|
+
function reaperEffect(step) {
|
|
61
|
+
return { family: 'reaper', step };
|
|
62
|
+
}
|
|
63
|
+
/** The `timer.sleep` effect backing the grace window. */
|
|
64
|
+
function sleepEffect(ms) {
|
|
65
|
+
return { family: 'timer', kind: 'sleep', ms };
|
|
66
|
+
}
|
|
67
|
+
/** Whether a pid is safe to signal: a positive safe integer that isn't us. */
|
|
68
|
+
export function isSafeKillPid(pid, selfPid) {
|
|
69
|
+
// `process.kill(pid, sig)` signals the whole process group for `pid <= 0`
|
|
70
|
+
// and the orchestrator itself for `pid === selfPid` — both catastrophic.
|
|
71
|
+
return Number.isSafeInteger(pid) && pid > 0 && pid !== selfPid;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Begin the escalation for one `kill_session` action. Reproduces the reference
|
|
75
|
+
* belt-and-suspenders guard PURELY: an unsafe pid (self / `<= 0` / non-finite)
|
|
76
|
+
* never produces a `signal` step — it returns a terminal `done` state carrying
|
|
77
|
+
* an `error` ledger op, so the shell has no path to `process.kill` a bad pid.
|
|
78
|
+
*
|
|
79
|
+
* A safe pid yields the opening step: `start` the ledger row and emit the
|
|
80
|
+
* SIGTERM signal (the shell sends it, then folds the observed result via
|
|
81
|
+
* {@link foldKillStep}).
|
|
82
|
+
*
|
|
83
|
+
* @param graceMs Injected grace window (the shell read it from config). Carried
|
|
84
|
+
* into the eventual `wait_grace` step's sleep effect.
|
|
85
|
+
*/
|
|
86
|
+
export function beginKill(action, selfPid) {
|
|
87
|
+
const key = killKey(action.pid);
|
|
88
|
+
if (!isSafeKillPid(action.pid, selfPid)) {
|
|
89
|
+
// Reference: `start(key)` then `error(key, msg)` — surfaced as a row so the
|
|
90
|
+
// dashboard shows the refusal — and NO signal is ever emitted.
|
|
91
|
+
return {
|
|
92
|
+
next: { kind: 'done', pid: action.pid },
|
|
93
|
+
effects: [],
|
|
94
|
+
ledger: { op: 'error', key, message: `refused to signal unsafe pid ${action.pid}` },
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
next: { kind: 'signal', pid: action.pid, signal: 'SIGTERM' },
|
|
99
|
+
effects: [reaperEffect({ kind: 'signal', pid: action.pid, signal: 'SIGTERM' })],
|
|
100
|
+
ledger: { op: 'start', key },
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* The core fold: given the `step` whose effect was just executed and the
|
|
105
|
+
* `result` the shell observed, return the NEXT step + effects + ledger op.
|
|
106
|
+
*
|
|
107
|
+
* `graceMs` is the injected grace window (only consulted when transitioning into
|
|
108
|
+
* `wait_grace`). Every branch returns a fresh decision; nothing is mutated.
|
|
109
|
+
*
|
|
110
|
+
* Terminal states return `{ kind: 'done' }` with NO effects — the shell stops
|
|
111
|
+
* driving and applies the `ledger` op. Intermediate states return the next
|
|
112
|
+
* `reaper` step (and, for the grace window, the `timer.sleep`) and the loop
|
|
113
|
+
* continues.
|
|
114
|
+
*/
|
|
115
|
+
export function foldKillStep(step, result, graceMs = DEFAULT_KILL_GRACE_MS) {
|
|
116
|
+
const pid = step.pid;
|
|
117
|
+
const key = killKey(pid);
|
|
118
|
+
const terminalDone = { kind: 'done', pid };
|
|
119
|
+
switch (step.kind) {
|
|
120
|
+
// ── ① SIGTERM / ④ SIGKILL share the same signal-result table. ──────────
|
|
121
|
+
case 'signal': {
|
|
122
|
+
switch (result.kind) {
|
|
123
|
+
case 'gone':
|
|
124
|
+
// ESRCH: already gone — treat as success (ref: ESRCH → done).
|
|
125
|
+
return { next: terminalDone, effects: [], ledger: { op: 'done', key } };
|
|
126
|
+
case 'no_perm': {
|
|
127
|
+
// EPERM: can't deliver the signal — surface as an error and stop.
|
|
128
|
+
const phase = step.signal === 'SIGTERM' ? 'SIGTERM' : 'SIGKILL';
|
|
129
|
+
return {
|
|
130
|
+
next: terminalDone,
|
|
131
|
+
effects: [],
|
|
132
|
+
ledger: { op: 'error', key, message: `${phase} failed: EPERM` },
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
case 'signalled':
|
|
136
|
+
if (step.signal === 'SIGTERM') {
|
|
137
|
+
// Reference: `await sleep(graceMs)` then probe. Emit the grace
|
|
138
|
+
// window's sleep AND the next reaper step (wait_grace) so the shell
|
|
139
|
+
// sleeps before probing.
|
|
140
|
+
const next = { kind: 'wait_grace', pid, ms: graceMs };
|
|
141
|
+
return {
|
|
142
|
+
next,
|
|
143
|
+
effects: [sleepEffect(graceMs), reaperEffect(next)],
|
|
144
|
+
ledger: { op: 'none' },
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
// SIGKILL succeeded → terminal done (ref: success → done).
|
|
148
|
+
return { next: terminalDone, effects: [], ledger: { op: 'done', key } };
|
|
149
|
+
case 'alive':
|
|
150
|
+
// A `signal`/`SIGKILL` reporting "still alive" is not a normal result
|
|
151
|
+
// path (the shell maps signal-send success to `signalled`); treat a
|
|
152
|
+
// surviving SIGKILL target as terminal success to avoid a kill loop,
|
|
153
|
+
// matching the reference (post-SIGKILL it always lands in done).
|
|
154
|
+
return { next: terminalDone, effects: [], ledger: { op: 'done', key } };
|
|
155
|
+
}
|
|
156
|
+
// Exhaustive; unreachable.
|
|
157
|
+
return { next: terminalDone, effects: [], ledger: { op: 'none' } };
|
|
158
|
+
}
|
|
159
|
+
// ── ② grace window elapsed → probe liveness. ────────────────────────────
|
|
160
|
+
case 'wait_grace': {
|
|
161
|
+
// Reference: after the sleep, probe with signal 0. The sleep already ran
|
|
162
|
+
// (shell applied the timer.sleep); regardless of the observed result we
|
|
163
|
+
// advance to the probe step. No ledger change here.
|
|
164
|
+
const next = { kind: 'probe', pid };
|
|
165
|
+
return { next, effects: [reaperEffect(next)], ledger: { op: 'none' } };
|
|
166
|
+
}
|
|
167
|
+
// ── ③ probe (signal 0) → done / error / escalate to SIGKILL. ────────────
|
|
168
|
+
case 'probe': {
|
|
169
|
+
switch (result.kind) {
|
|
170
|
+
case 'gone':
|
|
171
|
+
// ESRCH from the probe: the process exited during the grace window
|
|
172
|
+
// (ref: `!alive` → done).
|
|
173
|
+
return { next: terminalDone, effects: [], ledger: { op: 'done', key } };
|
|
174
|
+
case 'no_perm':
|
|
175
|
+
// EPERM: alive but unreachable — surface as error (ref: code !== ESRCH
|
|
176
|
+
// → error, "assume alive but unkillable").
|
|
177
|
+
return {
|
|
178
|
+
next: terminalDone,
|
|
179
|
+
effects: [],
|
|
180
|
+
ledger: { op: 'error', key, message: 'alive-probe failed: EPERM' },
|
|
181
|
+
};
|
|
182
|
+
case 'alive':
|
|
183
|
+
case 'signalled': {
|
|
184
|
+
// Still alive after the grace → escalate to SIGKILL (ref: `alive` →
|
|
185
|
+
// SIGKILL). `signalled` from a signal-0 probe is treated the same as
|
|
186
|
+
// `alive` (the process accepted the no-op signal ⇒ it exists).
|
|
187
|
+
const next = { kind: 'signal', pid, signal: 'SIGKILL' };
|
|
188
|
+
return { next, effects: [reaperEffect(next)], ledger: { op: 'none' } };
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
// Exhaustive; unreachable.
|
|
192
|
+
return { next: terminalDone, effects: [], ledger: { op: 'none' } };
|
|
193
|
+
}
|
|
194
|
+
// ── terminal ─────────────────────────────────────────────────────────────
|
|
195
|
+
case 'done':
|
|
196
|
+
// No further work; a result observed against a terminal step is a no-op.
|
|
197
|
+
return { next: step, effects: [], ledger: { op: 'none' } };
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Whether a `KillStep` is terminal (the shell stops driving the per-session
|
|
202
|
+
* escalation when it reaches this).
|
|
203
|
+
*/
|
|
204
|
+
export function isKillTerminal(step) {
|
|
205
|
+
return step.kind === 'done';
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=vm-reap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vm-reap.js","sourceRoot":"","sources":["../../../../src/core/reconcile/vm-reap.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
// FCIS rewrite — pure workspace-janitor decision core.
|
|
2
|
+
//
|
|
3
|
+
// Functional-core port of the diff half of the original
|
|
4
|
+
// `src/reconciler/workspace.ts:WorkspaceResource.reconcile`. The original was an
|
|
5
|
+
// async class method that interleaved IO (tracker read, dir listing, base-ref
|
|
6
|
+
// lookup, per-dir git inspection, rm, create) with the diff logic and recorded
|
|
7
|
+
// every step into a `ResourceActionLedger`. In the FCIS layout ALL of that IO
|
|
8
|
+
// moves OUT into the shell:
|
|
9
|
+
//
|
|
10
|
+
// - The desired set (active non-terminal + in-flight identifiers with their
|
|
11
|
+
// current state) is SUPPLIED here as plain data (`WorkspaceObservedState.
|
|
12
|
+
// desired`). The shell does the (fail-closed) tracker read; if it throws,
|
|
13
|
+
// the shell never calls this decider — exactly matching the original's
|
|
14
|
+
// "bail and leave existing workspaces untouched" rule.
|
|
15
|
+
// - The dir listing, the source-repo base SHA, and the per-dir git inspection
|
|
16
|
+
// are SUPPLIED as plain data (`observed`, `baseRefSha`, `inspections`). When
|
|
17
|
+
// `baseRefSha` is null the shell couldn't resolve base → this decider skips
|
|
18
|
+
// drift detection entirely (orphan removal still fires), mirroring the
|
|
19
|
+
// original `if (baseRef === null) continue;`.
|
|
20
|
+
// - The merge-state guard the original applied INSIDE its create callback
|
|
21
|
+
// (`WorkspaceManager.ensureFor` skips eager recreation while the owning
|
|
22
|
+
// issue sits in the PR/merge state) is applied here as data: a desired
|
|
23
|
+
// entry whose `state === prMergeState` does NOT get a `create_workspace`.
|
|
24
|
+
//
|
|
25
|
+
// The decider RETURNS:
|
|
26
|
+
// - `actions`: `create_workspace` / `remove_workspace` `ReconcilerAction[]`
|
|
27
|
+
// the shell executes (each maps to a `workspace.ensure` / `workspace.remove`
|
|
28
|
+
// Effect). `remove` carries the sanitized dir name; `create` carries the raw
|
|
29
|
+
// operator-visible identifier (the shell's `ensure` re-sanitizes).
|
|
30
|
+
// - `marks`: non-destructive `mark_stale` / `mark_stuck` drift annotations the
|
|
31
|
+
// shell records into the ledger (the original never auto-removes for drift
|
|
32
|
+
// in v1 — it only annotates so the dashboard renders a badge).
|
|
33
|
+
// - `logs`: `LogEffect[]` so the shell can re-emit the same structured lines
|
|
34
|
+
// the original logged at each branch.
|
|
35
|
+
//
|
|
36
|
+
// Pure + synchronous: (data) -> data + Effect[]. Imports ONLY from src/types.
|
|
37
|
+
//
|
|
38
|
+
// HARD CONSTRAINTS (gate-enforced):
|
|
39
|
+
// - 100% SYNCHRONOUS. No async/await/Promise anywhere.
|
|
40
|
+
// - No IO, no node: imports, no process/fetch, no wall clock, no randomness.
|
|
41
|
+
// - Imports ONLY from src/types/**.
|
|
42
|
+
import { sanitizeWorkspaceKey } from '../workspace-key.js';
|
|
43
|
+
function log(level, message, fields) {
|
|
44
|
+
return fields === undefined
|
|
45
|
+
? { family: 'log', kind: 'emit', level, message }
|
|
46
|
+
: { family: 'log', kind: 'emit', level, message, fields };
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Pure janitor diff. Given the desired set (active + in-flight identifiers with
|
|
50
|
+
* state), the observed dirs on disk, the source repo's current base SHA, and the
|
|
51
|
+
* per-dir git inspections, return the create/remove actions, the drift marks,
|
|
52
|
+
* and the log effects.
|
|
53
|
+
*
|
|
54
|
+
* Branch parity with the original `WorkspaceResource.reconcile`:
|
|
55
|
+
* 1. Build `wanted`: sanitize in-flight ids first, then active ids (active
|
|
56
|
+
* wins on overlap so the tracker's authoritative state beats an in-flight
|
|
57
|
+
* target_state). Keyed by sanitized dir name → { identifier, state }.
|
|
58
|
+
* 2. For each observed dir: not in `wanted` ⇒ `remove_workspace` (stale_issue),
|
|
59
|
+
* UNLESS it carries a handoff-pending marker (`obs.handoffPending`) — a
|
|
60
|
+
* terminal issue whose push handoff failed, RETAINED so the only commit copy
|
|
61
|
+
* survives for recovery (234). Else mark present; if a base SHA is present,
|
|
62
|
+
* fold the inspection for drift (mark_stuck when there's agent work to lose,
|
|
63
|
+
* else mark_stale).
|
|
64
|
+
* 3. For each wanted id with no dir on disk ⇒ `create_workspace`, UNLESS the
|
|
65
|
+
* merge-state guard fires (its state === prMergeState).
|
|
66
|
+
*/
|
|
67
|
+
export function decideWorkspace(obs) {
|
|
68
|
+
const actions = [];
|
|
69
|
+
const marks = [];
|
|
70
|
+
const logs = [];
|
|
71
|
+
let staleCount = 0;
|
|
72
|
+
let stuckCount = 0;
|
|
73
|
+
let createdCount = 0;
|
|
74
|
+
let lastError = null;
|
|
75
|
+
// Step 1 — build the desired map keyed by sanitized dir name. The original
|
|
76
|
+
// iterated in-flight first then active so active (the tracker's authoritative
|
|
77
|
+
// state) overwrites any overlapping in-flight entry. `obs.desired` here is the
|
|
78
|
+
// already-merged sequence the shell hands us in that same precedence order;
|
|
79
|
+
// we sanitize and last-write-wins to reproduce the overlap rule even if a
|
|
80
|
+
// caller supplies raw (in-flight, active) pairs in order.
|
|
81
|
+
const wanted = new Map();
|
|
82
|
+
for (const entry of obs.desired) {
|
|
83
|
+
wanted.set(sanitizeWorkspaceKey(entry.identifier), {
|
|
84
|
+
identifier: entry.identifier,
|
|
85
|
+
state: entry.state,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
// Step 2 — reap orphans + annotate drift on the dirs that survive.
|
|
89
|
+
const present = new Set();
|
|
90
|
+
for (const { name } of obs.observed) {
|
|
91
|
+
if (!wanted.has(name)) {
|
|
92
|
+
// A terminal issue whose phase-8 handoff push FAILED left a marker: the only
|
|
93
|
+
// copy of its completed commit lives in this dir, so RETAIN it (skip the reap)
|
|
94
|
+
// until it's pushed/recovered — reaping it would be unrecoverable loss (234).
|
|
95
|
+
if (obs.handoffPending.has(name)) {
|
|
96
|
+
logs.push(log('warn', 'workspace reconcile: retained (handoff pending)', { identifier: name, reason: 'handoff_pending' }));
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
actions.push({ kind: 'remove_workspace', identifier: name });
|
|
100
|
+
logs.push(log('info', 'workspace reconcile: removed', { identifier: name, reason: 'stale_issue' }));
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
present.add(name);
|
|
104
|
+
// In the desired set. Drift detection needs a base SHA to compare against;
|
|
105
|
+
// null means the shell couldn't resolve base this pass — skip (workspace ok).
|
|
106
|
+
if (obs.baseRefSha === null)
|
|
107
|
+
continue;
|
|
108
|
+
const inspection = obs.inspections[name];
|
|
109
|
+
// No inspection supplied (shell skipped or the inspect call failed) — treat
|
|
110
|
+
// as ok, matching the original's `catch { continue; }` around inspect.
|
|
111
|
+
if (inspection === undefined)
|
|
112
|
+
continue;
|
|
113
|
+
if (inspection.head === null)
|
|
114
|
+
continue;
|
|
115
|
+
// Workspace has no local copy of the base branch — operator likely deleted
|
|
116
|
+
// it. Skip drift detection rather than guess.
|
|
117
|
+
if (inspection.workspaceBaseSha === null)
|
|
118
|
+
continue;
|
|
119
|
+
// Drift = workspace's frozen base SHA disagrees with source's current base
|
|
120
|
+
// SHA. Any disagreement counts (fast-forward, divergence, rewind all surface
|
|
121
|
+
// as "the operator's base moved out from under us").
|
|
122
|
+
if (inspection.workspaceBaseSha === obs.baseRefSha)
|
|
123
|
+
continue;
|
|
124
|
+
// Drift detected. v1 never auto-removes for drift; annotate and move on.
|
|
125
|
+
if (inspection.hasUncommitted || inspection.commitsAheadOfBase > 0) {
|
|
126
|
+
stuckCount += 1;
|
|
127
|
+
const reason = inspection.hasUncommitted
|
|
128
|
+
? 'uncommitted changes present'
|
|
129
|
+
: `${inspection.commitsAheadOfBase} commit(s) ahead of base`;
|
|
130
|
+
lastError = `workspace ${name} stuck: base advanced and ${reason}`;
|
|
131
|
+
marks.push({ status: 'stuck', identifier: name, reason });
|
|
132
|
+
logs.push(log('warn', 'workspace reconcile: stuck (drift, agent work present)', { identifier: name, reason }));
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
staleCount += 1;
|
|
136
|
+
const staleReason = 'base advanced past workspace HEAD; re-clone is opt-in';
|
|
137
|
+
lastError = `workspace ${name} stale: ${staleReason}`;
|
|
138
|
+
marks.push({ status: 'stale', identifier: name, reason: staleReason });
|
|
139
|
+
logs.push(log('info', 'workspace reconcile: stale (drift, no agent work to lose)', { identifier: name, reason: staleReason }));
|
|
140
|
+
}
|
|
141
|
+
// Step 3 — create any desired identifier with no dir on disk, modulo the
|
|
142
|
+
// merge-state guard. The original deferred to `WorkspaceManager.ensureFor`,
|
|
143
|
+
// which is idempotent; the guard (skip while the owning issue sits in the
|
|
144
|
+
// PR/merge state) was applied inside that create callback. Here it's data:
|
|
145
|
+
// `state === prMergeState` ⇒ no create_workspace.
|
|
146
|
+
for (const [key, { identifier, state }] of wanted) {
|
|
147
|
+
if (present.has(key))
|
|
148
|
+
continue;
|
|
149
|
+
if (obs.prMergeState !== null && state === obs.prMergeState) {
|
|
150
|
+
logs.push(log('debug', 'workspace reconcile: create skipped (merge-state guard)', {
|
|
151
|
+
identifier,
|
|
152
|
+
state,
|
|
153
|
+
}));
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
actions.push({ kind: 'create_workspace', identifier });
|
|
157
|
+
createdCount += 1;
|
|
158
|
+
logs.push(log('info', 'workspace reconcile: created', { identifier, state }));
|
|
159
|
+
}
|
|
160
|
+
return { actions, marks, logs, staleCount, stuckCount, createdCount, lastError };
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=workspace-decide.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-decide.js","sourceRoot":"","sources":["../../../../src/core/reconcile/workspace-decide.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
// FCIS rewrite — pure per-issue run-summary reducer.
|
|
2
|
+
//
|
|
3
|
+
// Functional core: the single export here is a pure, SYNCHRONOUS (data) -> data
|
|
4
|
+
// reduction. No IO, no async/Promise, no clock, no randomness, no node: imports.
|
|
5
|
+
// Imports ONLY from src/types. Ports src/runlog.ts:summarizeRunLog and its
|
|
6
|
+
// private helpers (buildAttemptSpans / collectTransitions / buildStatePath /
|
|
7
|
+
// perStateStats / collectRejections / collectTimeouts / terminalOf / prFrom /
|
|
8
|
+
// wallClockTotal) verbatim in behavior.
|
|
9
|
+
//
|
|
10
|
+
// WHAT MOVED to the shell vs the original:
|
|
11
|
+
// - The original `summarizeRunLog` defaulted `generatedAt` to
|
|
12
|
+
// `new Date().toISOString()`. A pure core cannot read the wall clock, so
|
|
13
|
+
// `generatedAt` is now a REQUIRED parameter. The composition root reads it
|
|
14
|
+
// from the injected Clock port (clock.iso()) and passes it in. Everything
|
|
15
|
+
// else (timestamp PARSING via the deterministic Date.parse on caller-
|
|
16
|
+
// supplied ISO strings) stays pure — it derives data from inputs only.
|
|
17
|
+
// - The RunLog class lifecycle (open/record/captureLifecycle/writeSummary/
|
|
18
|
+
// close, the JSONL stream, the *.summary.json fs write) is NOT here; that is
|
|
19
|
+
// RunLog Effect execution in the shell. This module is only the reducer the
|
|
20
|
+
// write_summary effect consumes.
|
|
21
|
+
//
|
|
22
|
+
// NOTE on Date.parse: parsing a caller-provided ISO-8601 string is deterministic
|
|
23
|
+
// and does not read the ambient clock, so it is permitted in core. We never call
|
|
24
|
+
// Date.now() / new Date() with no argument.
|
|
25
|
+
import { RUN_SUMMARY_SCHEMA_VERSION } from '../../types/runlog.js';
|
|
26
|
+
const NOTE_CAP = 4000;
|
|
27
|
+
const TIMEOUT_RE = /timeout|timed out|stall|prompt_timeout|did not connect|bridge/i;
|
|
28
|
+
const PR_URL_RE = /(https?:\/\/[^\s)]+\/pull\/(\d+))/;
|
|
29
|
+
function fieldsOf(e) {
|
|
30
|
+
return e.fields && typeof e.fields === 'object' ? e.fields : {};
|
|
31
|
+
}
|
|
32
|
+
function asStr(v) {
|
|
33
|
+
return typeof v === 'string' ? v : null;
|
|
34
|
+
}
|
|
35
|
+
function asNum(v) {
|
|
36
|
+
return typeof v === 'number' && Number.isFinite(v) ? v : null;
|
|
37
|
+
}
|
|
38
|
+
function isBudgetExhausted(reason) {
|
|
39
|
+
return reason !== null && /max_turns/i.test(reason);
|
|
40
|
+
}
|
|
41
|
+
function spanDurationMs(s) {
|
|
42
|
+
if (!s.ended_at)
|
|
43
|
+
return 0;
|
|
44
|
+
const a = Date.parse(s.started_at);
|
|
45
|
+
const b = Date.parse(s.ended_at);
|
|
46
|
+
return Number.isFinite(a) && Number.isFinite(b) && b >= a ? b - a : 0;
|
|
47
|
+
}
|
|
48
|
+
/** Pair `attempt_started`/`attempt_ended` events in order into per-attempt spans. */
|
|
49
|
+
function buildAttemptSpans(entries) {
|
|
50
|
+
const spans = [];
|
|
51
|
+
for (const e of entries) {
|
|
52
|
+
if (e.channel !== 'system')
|
|
53
|
+
continue;
|
|
54
|
+
const f = fieldsOf(e);
|
|
55
|
+
if (e.event === 'attempt_started') {
|
|
56
|
+
spans.push({
|
|
57
|
+
attempt: asNum(f.attempt) ?? spans.length,
|
|
58
|
+
state: asStr(f.issue_state) ?? 'unknown',
|
|
59
|
+
max_turns: asNum(f.max_turns),
|
|
60
|
+
turns_used: 0,
|
|
61
|
+
reason: null,
|
|
62
|
+
started_at: e.ts,
|
|
63
|
+
ended_at: null,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
else if (e.event === 'attempt_ended') {
|
|
67
|
+
const open = spans[spans.length - 1];
|
|
68
|
+
if (open && open.ended_at === null) {
|
|
69
|
+
open.turns_used = asNum(f.turns_completed) ?? 0;
|
|
70
|
+
open.reason = asStr(f.reason);
|
|
71
|
+
open.ended_at = e.ts;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return spans;
|
|
76
|
+
}
|
|
77
|
+
function collectTransitions(entries) {
|
|
78
|
+
const out = [];
|
|
79
|
+
for (const e of entries) {
|
|
80
|
+
if (e.channel !== 'system' || e.event !== 'transition')
|
|
81
|
+
continue;
|
|
82
|
+
const f = fieldsOf(e);
|
|
83
|
+
out.push({
|
|
84
|
+
from_state: asStr(f.from_state) ?? 'unknown',
|
|
85
|
+
to_state: asStr(f.to_state) ?? 'unknown',
|
|
86
|
+
notes: asStr(f.notes) ?? '',
|
|
87
|
+
actor: asStr(f.actor),
|
|
88
|
+
terminal: f.terminal === true,
|
|
89
|
+
rerouted: f.rerouted === true,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
return out;
|
|
93
|
+
}
|
|
94
|
+
function collapseConsecutive(seq) {
|
|
95
|
+
const out = [];
|
|
96
|
+
for (const s of seq) {
|
|
97
|
+
if (out[out.length - 1] !== s)
|
|
98
|
+
out.push(s);
|
|
99
|
+
}
|
|
100
|
+
return out;
|
|
101
|
+
}
|
|
102
|
+
/** State path backbone is the per-attempt states (every dispatch logs one); the terminal state is appended. */
|
|
103
|
+
function buildStatePath(spans, transitions, terminalState) {
|
|
104
|
+
let path = collapseConsecutive(spans.map((s) => s.state));
|
|
105
|
+
if (path.length === 0 && transitions.length > 0) {
|
|
106
|
+
path = collapseConsecutive([transitions[0].from_state, ...transitions.map((t) => t.to_state)]);
|
|
107
|
+
}
|
|
108
|
+
if (terminalState && path[path.length - 1] !== terminalState)
|
|
109
|
+
path.push(terminalState);
|
|
110
|
+
return path;
|
|
111
|
+
}
|
|
112
|
+
function perStateStats(spans) {
|
|
113
|
+
const order = [];
|
|
114
|
+
const byState = new Map();
|
|
115
|
+
for (const s of spans) {
|
|
116
|
+
let stat = byState.get(s.state);
|
|
117
|
+
if (!stat) {
|
|
118
|
+
stat = {
|
|
119
|
+
state: s.state,
|
|
120
|
+
attempts: 0,
|
|
121
|
+
turns_used: 0,
|
|
122
|
+
max_turns: null,
|
|
123
|
+
budget_exhausted: false,
|
|
124
|
+
wall_clock_ms: 0,
|
|
125
|
+
};
|
|
126
|
+
byState.set(s.state, stat);
|
|
127
|
+
order.push(s.state);
|
|
128
|
+
}
|
|
129
|
+
stat.attempts += 1;
|
|
130
|
+
stat.turns_used += s.turns_used;
|
|
131
|
+
if (s.max_turns !== null)
|
|
132
|
+
stat.max_turns = s.max_turns;
|
|
133
|
+
if (isBudgetExhausted(s.reason))
|
|
134
|
+
stat.budget_exhausted = true;
|
|
135
|
+
stat.wall_clock_ms += spanDurationMs(s);
|
|
136
|
+
}
|
|
137
|
+
return order.map((st) => byState.get(st));
|
|
138
|
+
}
|
|
139
|
+
function capNotes(notes) {
|
|
140
|
+
return notes.length > NOTE_CAP ? notes.slice(0, NOTE_CAP) + '…[truncated]' : notes;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* A review rejection is a non-reroute transition back to the INITIAL implementing
|
|
144
|
+
* state (where the issue started). In the shipped Todo→Review→Done flow that is
|
|
145
|
+
* exactly a Review→Todo kick-back; the definition stays workflow-agnostic.
|
|
146
|
+
*/
|
|
147
|
+
function collectRejections(transitions, initialState) {
|
|
148
|
+
if (initialState === null)
|
|
149
|
+
return [];
|
|
150
|
+
const out = [];
|
|
151
|
+
for (const t of transitions) {
|
|
152
|
+
if (t.rerouted)
|
|
153
|
+
continue;
|
|
154
|
+
if (t.to_state === initialState && t.from_state !== t.to_state) {
|
|
155
|
+
out.push({ from_state: t.from_state, to_state: t.to_state, actor: t.actor, notes: capNotes(t.notes) });
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return out;
|
|
159
|
+
}
|
|
160
|
+
function collectTimeouts(spans) {
|
|
161
|
+
const out = [];
|
|
162
|
+
for (const s of spans) {
|
|
163
|
+
if (s.reason !== null && TIMEOUT_RE.test(s.reason)) {
|
|
164
|
+
out.push({ attempt: s.attempt, state: s.state, reason: s.reason });
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return out;
|
|
168
|
+
}
|
|
169
|
+
function terminalOf(transitions) {
|
|
170
|
+
let terminal = null;
|
|
171
|
+
for (const t of transitions) {
|
|
172
|
+
if (t.terminal)
|
|
173
|
+
terminal = t;
|
|
174
|
+
}
|
|
175
|
+
if (!terminal)
|
|
176
|
+
return { state: null, outcome: 'incomplete' };
|
|
177
|
+
return { state: terminal.to_state, outcome: /cancel/i.test(terminal.to_state) ? 'cancelled' : 'completed' };
|
|
178
|
+
}
|
|
179
|
+
function prFrom(actionsStdout) {
|
|
180
|
+
const m = PR_URL_RE.exec(actionsStdout);
|
|
181
|
+
if (!m)
|
|
182
|
+
return { number: null, url: null };
|
|
183
|
+
return { url: m[1], number: Number.parseInt(m[2], 10) };
|
|
184
|
+
}
|
|
185
|
+
function wallClockTotal(entries) {
|
|
186
|
+
if (entries.length === 0)
|
|
187
|
+
return null;
|
|
188
|
+
const a = Date.parse(entries[0].ts);
|
|
189
|
+
const b = Date.parse(entries[entries.length - 1].ts);
|
|
190
|
+
return Number.isFinite(a) && Number.isFinite(b) && b >= a ? b - a : null;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Reduce a per-issue lifecycle event list into a {@link RunSummary}. Pure and
|
|
194
|
+
* deterministic. Tolerant of partial streams — every field degrades to a
|
|
195
|
+
* sensible empty/null value.
|
|
196
|
+
*/
|
|
197
|
+
export function summarizeRunLog(input) {
|
|
198
|
+
const spans = buildAttemptSpans(input.entries);
|
|
199
|
+
const transitions = collectTransitions(input.entries);
|
|
200
|
+
const term = terminalOf(transitions);
|
|
201
|
+
const statePath = buildStatePath(spans, transitions, term.state);
|
|
202
|
+
const initialState = statePath[0] ?? spans[0]?.state ?? null;
|
|
203
|
+
const rejections = collectRejections(transitions, initialState);
|
|
204
|
+
const perState = perStateStats(spans);
|
|
205
|
+
const pr = prFrom(input.actionsStdout);
|
|
206
|
+
const conflictRoutes = transitions
|
|
207
|
+
.filter((t) => t.rerouted)
|
|
208
|
+
.map((t) => ({ from_state: t.from_state, to_state: t.to_state }));
|
|
209
|
+
return {
|
|
210
|
+
schema_version: RUN_SUMMARY_SCHEMA_VERSION,
|
|
211
|
+
issue_id: input.issueId,
|
|
212
|
+
issue_identifier: input.issueIdentifier,
|
|
213
|
+
state_path: statePath,
|
|
214
|
+
attempts: spans.length,
|
|
215
|
+
per_state: perState,
|
|
216
|
+
review_rejections: rejections.length,
|
|
217
|
+
rejection_notes: rejections,
|
|
218
|
+
turn_budget_exhausted: perState.some((s) => s.budget_exhausted),
|
|
219
|
+
timeouts: collectTimeouts(spans),
|
|
220
|
+
conflict_routes: conflictRoutes,
|
|
221
|
+
terminal_state: term.state,
|
|
222
|
+
terminal_outcome: term.outcome,
|
|
223
|
+
pr_number: pr.number,
|
|
224
|
+
pr_url: pr.url,
|
|
225
|
+
first_event_at: input.entries[0]?.ts ?? null,
|
|
226
|
+
last_event_at: input.entries[input.entries.length - 1]?.ts ?? null,
|
|
227
|
+
wall_clock_ms_total: wallClockTotal(input.entries),
|
|
228
|
+
generated_at: input.generatedAt,
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
//# sourceMappingURL=summary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summary.js","sourceRoot":"","sources":["../../../../src/core/runlog/summary.ts"],"names":[],"mappings":"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"}
|