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
package/README.md
CHANGED
|
@@ -19,9 +19,9 @@ workspace for review.
|
|
|
19
19
|
┌──────────────────────────────────────────────────────────────────────────┐
|
|
20
20
|
│ symphony (node host) │
|
|
21
21
|
│ │
|
|
22
|
-
│ ./issues/<state>/*.md
|
|
23
|
-
│ ./WORKFLOW.
|
|
24
|
-
│ ./WORKFLOW.template.
|
|
22
|
+
│ ./issues/<state>/*.md ──┐ │
|
|
23
|
+
│ ./WORKFLOW.yaml ├──▶ orchestrator ──▶ agent runner │
|
|
24
|
+
│ ./WORKFLOW.template.yaml ──┘ poll · reconcile · dispatch │
|
|
25
25
|
│ │ │
|
|
26
26
|
│ ▼ ACP/RPC │
|
|
27
27
|
│ ┌───────────────────────────────┐ │
|
|
@@ -45,46 +45,96 @@ original architectural narrative, see
|
|
|
45
45
|
|
|
46
46
|
## Quick start
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
- The agent rootfs image. Gondolin is the in-process microVM substrate
|
|
52
|
-
(`@earendil-works/gondolin`), so there is no separate VM daemon to run. The
|
|
53
|
-
agent image is built **once** from `images/agents/` via `npm run build:image`:
|
|
54
|
-
it starts from `node:24-bookworm-slim`, installs base CLI tooling, npm-installs
|
|
55
|
-
every ACP-capable coding agent (`claude-agent-acp`, `codex-acp`, `opencode`),
|
|
56
|
-
and bakes the in-VM stdio launcher at `/opt/symphony/vm-agent.mjs` into the
|
|
57
|
-
image. The build prints a content-addressed build id; pin it (or a
|
|
58
|
-
`name:tag` ref like `symphony-agents:latest`) in `WORKFLOW.md`'s
|
|
59
|
-
`gondolin.image`. See [images/agents/README.md](./images/agents/README.md)
|
|
60
|
-
for the build steps and requirements.
|
|
61
|
-
- For the default `acp.adapter: claude`: a credentials file at
|
|
62
|
-
`~/.claude/.credentials.json` on the host. Symphony reads it only on the
|
|
63
|
-
host side: the guest holds only a token-shaped placeholder, and the host
|
|
64
|
-
substitutes the real OAuth access token into the outbound request at
|
|
65
|
-
Gondolin egress (TLS-MITM). The credential file itself is never staged into
|
|
66
|
-
the VM.
|
|
67
|
-
|
|
68
|
-
Run, against an existing workflow file in the current directory:
|
|
48
|
+
The golden path from zero to your first dispatched issue. The details behind
|
|
49
|
+
each step live in [Prerequisites in detail](#prerequisites-in-detail) below — you
|
|
50
|
+
should not need them to get here.
|
|
69
51
|
|
|
70
52
|
```bash
|
|
71
|
-
|
|
53
|
+
# 1. Build the agent rootfs image once. This ships only `mise` (jdx/mise) — node +
|
|
54
|
+
# the coding-agent CLIs are mise-installed at dispatch, the launcher is injected —
|
|
55
|
+
# and tags the result `symphony-agents:latest` — the tag the scaffolded
|
|
56
|
+
# WORKFLOW.yaml pins, so a first run needs no edit.
|
|
57
|
+
git clone https://github.com/dizk/smol-symphony.git
|
|
58
|
+
cd smol-symphony && npm install && npm run build:image
|
|
59
|
+
|
|
60
|
+
# 2. In your project, scaffold the minimal WORKFLOW.yaml. With no workflow file
|
|
61
|
+
# present, symphony offers to write a ~30-line starter (every key required,
|
|
62
|
+
# no power features), then exits so you can glance at it.
|
|
63
|
+
cd /path/to/your/project
|
|
64
|
+
npx smol-symphony WORKFLOW.yaml
|
|
65
|
+
|
|
66
|
+
# 3. Verify the whole setup in one pass before the first dispatch. `symphony
|
|
67
|
+
# doctor` runs every adoption-prerequisite probe — Node version, the
|
|
68
|
+
# `gondolin.image` pin, each configured adapter's host credential, a
|
|
69
|
+
# writable `tracker.root`, and a bindable dashboard port — and prints a
|
|
70
|
+
# PASS/FAIL line per check with a one-line fix for each failure, exiting 0
|
|
71
|
+
# iff every check passes. Unlike startup (which bails on the first failure),
|
|
72
|
+
# it runs all probes so you see the whole picture at once.
|
|
73
|
+
npx smol-symphony doctor WORKFLOW.yaml
|
|
74
|
+
|
|
75
|
+
# 4. Drop one issue into the tracker.
|
|
76
|
+
mkdir -p issues/Todo
|
|
77
|
+
printf -- '---\ntitle: "Say hi"\n---\nAdd a hi() that returns "hi".\n' > issues/Todo/1.md
|
|
78
|
+
|
|
79
|
+
# 5. Run symphony and watch it dispatch.
|
|
80
|
+
npx smol-symphony WORKFLOW.yaml --port 8787
|
|
81
|
+
# Open http://127.0.0.1:8787/ — issue 1 moves from "on disk" into a running
|
|
82
|
+
# session as symphony boots a per-issue microVM and dispatches the agent.
|
|
72
83
|
```
|
|
73
84
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
`
|
|
85
|
+
The same first-run scaffold also installs an issue-filing skill at
|
|
86
|
+
`.claude/skills/symphony-issues/SKILL.md` (best-effort — it never blocks the
|
|
87
|
+
workflow scaffold), so a coding agent in the freshly-onboarded repo can file
|
|
88
|
+
well-formed tracker issues and decompose a large task into a `blocked_by` DAG
|
|
89
|
+
from day one.
|
|
90
|
+
|
|
91
|
+
The scaffolded file ([WORKFLOW.minimal.yaml](./WORKFLOW.minimal.yaml) is the shipped
|
|
92
|
+
copy) runs as-is once `symphony-agents:latest` exists; the only edits a different
|
|
93
|
+
setup needs are `gondolin.image` (if you pinned a build id) and the adapter
|
|
94
|
+
credential for your chosen agent. When you want a power feature it omits — typed
|
|
95
|
+
action DAGs, PR autopilot, per-state adapters, egress allowlists — graduate to
|
|
96
|
+
the annotated [WORKFLOW.template.yaml](./WORKFLOW.template.yaml).
|
|
97
|
+
|
|
98
|
+
(Or `npm i -g smol-symphony` and then `symphony doctor` / `symphony WORKFLOW.yaml`
|
|
99
|
+
to skip the `npx` fetch — both invoke the `symphony` bin shipped in this
|
|
100
|
+
package.)
|
|
101
|
+
|
|
102
|
+
### Prerequisites in detail
|
|
103
|
+
|
|
104
|
+
- **Node.js ≥ 20.**
|
|
105
|
+
- **The agent rootfs image** (step 1). Gondolin is the in-process microVM
|
|
106
|
+
substrate (`@earendil-works/gondolin`), so there is no separate VM daemon to
|
|
107
|
+
run. The image is built **once** from `images/agents/` via
|
|
108
|
+
`npm run build:image`: it starts from `node:24-bookworm-slim`, installs base
|
|
109
|
+
CLI tooling, and ships only the `mise` (jdx/mise) binary. node + every
|
|
110
|
+
ACP-capable coding agent (`claude-agent-acp`, `codex-acp`, …) are
|
|
111
|
+
NO LONGER baked — they come from a mise SYSTEM config symphony stages into the
|
|
112
|
+
guest at dispatch (`assets/symphony-mise.system.toml`) and installs via
|
|
113
|
+
`mise install` into a warm-cached data dir; a consuming repo's own `mise.toml`
|
|
114
|
+
adds project toolchains (rust, go, kotlin+gradle, …) on top. The in-VM stdio
|
|
115
|
+
launcher is likewise injected at dispatch, not baked. So bumping an agent CLI is
|
|
116
|
+
a one-line edit to the staged mise config + a restart — no image rebuild + repin.
|
|
117
|
+
The build prints a content-addressed build id; pin it (or the
|
|
118
|
+
`symphony-agents:latest` tag) in `WORKFLOW.yaml`'s `gondolin.image`. See
|
|
119
|
+
[images/agents/README.md](./images/agents/README.md) for the build steps and
|
|
120
|
+
requirements, and `gondolin.mise` in
|
|
121
|
+
[WORKFLOW.template.yaml](./WORKFLOW.template.yaml) to tune the data dir or opt out.
|
|
122
|
+
- **An adapter credential.** For the default `acp.adapter: claude`: a
|
|
123
|
+
credentials file at `~/.claude/.credentials.json` on the host. Symphony reads
|
|
124
|
+
it only on the host side: the guest holds only a token-shaped placeholder, and
|
|
125
|
+
the host substitutes the real OAuth access token into the outbound request at
|
|
126
|
+
Gondolin egress (TLS-MITM). The credential file itself is never staged into
|
|
127
|
+
the VM. (For `acp.adapter: codex`, see [WORKFLOW.template.yaml](./WORKFLOW.template.yaml).)
|
|
128
|
+
- **Skipping the `npx` fetch.** `npm i -g smol-symphony` installs the `symphony`
|
|
129
|
+
bin globally so `symphony WORKFLOW.yaml` works without re-fetching; the image
|
|
130
|
+
build still needs a checkout (it lives in `images/agents/`).
|
|
131
|
+
- **Console output.** With the default log file configured, symphony prints a
|
|
132
|
+
one-line-per-field startup banner (workflow, tracker root, dashboard URL,
|
|
133
|
+
log-file path) and routes the structured `key=value` stream to
|
|
134
|
+
`.symphony/logs/symphony.log` only. `tail -f` that file to follow the detail.
|
|
135
|
+
Pass `--verbose` (alias `--foreground`) to mirror the structured stream back
|
|
136
|
+
to the console for interactive debugging. With no log file configured (the
|
|
137
|
+
`SYMPHONY_LOG_FILE=""` override), the structured stream stays on stderr.
|
|
88
138
|
|
|
89
139
|
### From a checkout
|
|
90
140
|
|
|
@@ -95,7 +145,7 @@ git clone https://github.com/dizk/smol-symphony.git
|
|
|
95
145
|
cd smol-symphony
|
|
96
146
|
npm install
|
|
97
147
|
npm run build
|
|
98
|
-
npx symphony WORKFLOW.
|
|
148
|
+
npx symphony WORKFLOW.yaml # the local bin
|
|
99
149
|
```
|
|
100
150
|
|
|
101
151
|
`npm run dev` (via `tsx watch`) reruns on source edits.
|
|
@@ -104,7 +154,7 @@ npx symphony WORKFLOW.md # the local bin
|
|
|
104
154
|
|
|
105
155
|
Issues live as `.md` files under `tracker.root`. The parent directory is the
|
|
106
156
|
issue state; the set of valid state directories comes from the `states:` block
|
|
107
|
-
in `WORKFLOW.
|
|
157
|
+
in `WORKFLOW.yaml` (see below) and is auto-mkdir'd on startup.
|
|
108
158
|
|
|
109
159
|
```
|
|
110
160
|
issues/
|
|
@@ -143,12 +193,14 @@ itself in response to `symphony.transition`. The agent inside the VM does
|
|
|
143
193
|
**not** have filesystem access to the tracker root: it signals progress
|
|
144
194
|
through the MCP server and the orchestrator does the file move.
|
|
145
195
|
|
|
146
|
-
## WORKFLOW.
|
|
196
|
+
## WORKFLOW.yaml
|
|
147
197
|
|
|
148
|
-
`WORKFLOW.
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
198
|
+
`WORKFLOW.yaml` is a pure YAML config file (the orchestrator config). Each
|
|
199
|
+
active state's prompt lives in its own `prompt_file` — a
|
|
200
|
+
[Liquid](https://liquidjs.com/)-templated file under `prompts/`, wrapped in the
|
|
201
|
+
shared `prompt.preamble_file`/`footer_file`. The shipped file in this repo is
|
|
202
|
+
the canonical project workflow; see
|
|
203
|
+
[WORKFLOW.template.yaml](./WORKFLOW.template.yaml) for the annotated reference
|
|
152
204
|
covering every supported option, its type, default, and example.
|
|
153
205
|
|
|
154
206
|
The workflow is a **state machine**. A required top-level `states:` block
|
|
@@ -156,14 +208,14 @@ declares every state an issue can occupy, its `role` (`active` — dispatched;
|
|
|
156
208
|
`terminal` — triggers cleanup and handoff; `holding` — sits outside the
|
|
157
209
|
dispatch loop, e.g. `Triage`), and optional per-state `adapter`, `model`,
|
|
158
210
|
`max_turns`, and `allowed_transitions` overrides. A single issue can travel
|
|
159
|
-
through any number of states with distinct adapters and instructions;
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
`Todo → Review → Done` flow (Claude implements, Codex reviews).
|
|
211
|
+
through any number of states with distinct adapters and instructions; each
|
|
212
|
+
active state names its own `prompt_file`, so the agent in each state sees only
|
|
213
|
+
that state's instructions plus the shared preamble/footer. The shipped workflow
|
|
214
|
+
uses a two-stage `Todo → Review → Done` flow (Claude implements, Codex reviews).
|
|
163
215
|
|
|
164
|
-
Symphony watches the file and re-applies poll interval,
|
|
165
|
-
|
|
166
|
-
In-flight runs keep the settings they started with.
|
|
216
|
+
Symphony watches the file and its prompt files, and re-applies poll interval,
|
|
217
|
+
concurrency, typed actions, prompts, gondolin settings, etc. on change without
|
|
218
|
+
restart. In-flight runs keep the settings they started with.
|
|
167
219
|
|
|
168
220
|
## Dashboard
|
|
169
221
|
|
|
@@ -233,7 +285,7 @@ the adapter reaches for inside the VM:
|
|
|
233
285
|
| `claude` | `claude-agent-acp` | placeholder + host egress swap |
|
|
234
286
|
| `codex` | `codex-acp` | placeholder + host egress swap |
|
|
235
287
|
|
|
236
|
-
`WORKFLOW.
|
|
288
|
+
`WORKFLOW.yaml`:
|
|
237
289
|
|
|
238
290
|
```yaml
|
|
239
291
|
acp:
|
|
@@ -269,7 +321,7 @@ holds only the placeholder.
|
|
|
269
321
|
On transition into the Done state the orchestrator runs that state's typed
|
|
270
322
|
`actions:` block — two records, `push_branch` then `create_pr_if_missing` —
|
|
271
323
|
which push the per-issue branch and open a PR when a GitHub repo is configured:
|
|
272
|
-
set `workspace.github_repo: <owner>/<repo>` in `WORKFLOW.
|
|
324
|
+
set `workspace.github_repo: <owner>/<repo>` in `WORKFLOW.yaml` (or export
|
|
273
325
|
`SYMPHONY_REPO=<owner>/<repo>`, which overrides the file). Each action's
|
|
274
326
|
`if: $repo` predicate short-circuits to a no-op in local-only mode (neither
|
|
275
327
|
set), so the branch is simply left in the workspace until cleanup; pick the
|
|
@@ -286,8 +338,8 @@ and snapshot plumbing replaces the old opaque shell-exit surface: on a
|
|
|
286
338
|
rate-limit the `create_pr_if_missing` action surfaces "retrying in 60s" on the
|
|
287
339
|
dashboard rather than failing silently.
|
|
288
340
|
|
|
289
|
-
See `states.Done.actions` in [WORKFLOW.
|
|
290
|
-
record pair and [WORKFLOW.template.
|
|
341
|
+
See `states.Done.actions` in [WORKFLOW.yaml](./WORKFLOW.yaml) for the canonical
|
|
342
|
+
record pair and [WORKFLOW.template.yaml](./WORKFLOW.template.yaml) for the
|
|
291
343
|
typed-action reference.
|
|
292
344
|
|
|
293
345
|
## Trust posture
|
package/SPEC.md
CHANGED
|
@@ -34,7 +34,7 @@ The service solves four operational problems:
|
|
|
34
34
|
scripts.
|
|
35
35
|
- It isolates agent execution in per-issue workspaces so agent commands run
|
|
36
36
|
only inside per-issue workspace directories.
|
|
37
|
-
- It keeps the workflow policy in-repo (`WORKFLOW.
|
|
37
|
+
- It keeps the workflow policy in-repo (`WORKFLOW.yaml`) so teams version the
|
|
38
38
|
agent prompt and runtime settings with their code.
|
|
39
39
|
- It provides enough observability to operate and debug multiple concurrent
|
|
40
40
|
agent runs.
|
|
@@ -59,7 +59,7 @@ Boundary:
|
|
|
59
59
|
- Create deterministic per-issue workspaces and preserve them across runs.
|
|
60
60
|
- Stop active runs when issue state changes make them ineligible.
|
|
61
61
|
- Recover from transient failures with exponential backoff.
|
|
62
|
-
- Load runtime behavior from a repository-owned `WORKFLOW.
|
|
62
|
+
- Load runtime behavior from a repository-owned `WORKFLOW.yaml` contract.
|
|
63
63
|
- Expose operator-visible observability (at minimum structured logs).
|
|
64
64
|
- Support tracker/filesystem-driven restart recovery without requiring a
|
|
65
65
|
persistent database; exact in-memory scheduler state is not restored.
|
|
@@ -108,10 +108,12 @@ Fields:
|
|
|
108
108
|
|
|
109
109
|
#### 3.1.2 Workflow Definition
|
|
110
110
|
|
|
111
|
-
Parsed `WORKFLOW.
|
|
111
|
+
Parsed `WORKFLOW.yaml` payload:
|
|
112
112
|
|
|
113
|
-
- `config` (map) — YAML
|
|
114
|
-
- `
|
|
113
|
+
- `config` (map) — the decoded YAML config root object.
|
|
114
|
+
- `prompt_templates` (map of state name → string, optional) — the per-state
|
|
115
|
+
prompt templates the loader assembles from each active state's `prompt_file`
|
|
116
|
+
(wrapped in the shared `prompt.preamble_file`/`footer_file`).
|
|
115
117
|
|
|
116
118
|
#### 3.1.3 Service Config (Typed View)
|
|
117
119
|
|
|
@@ -160,7 +162,7 @@ attempt dispatches into).
|
|
|
160
162
|
Workflow file path precedence:
|
|
161
163
|
|
|
162
164
|
1. Explicit application/runtime setting (set by CLI startup path).
|
|
163
|
-
2. Default: `WORKFLOW.
|
|
165
|
+
2. Default: `WORKFLOW.yaml` in the current process working directory.
|
|
164
166
|
|
|
165
167
|
Loader behavior:
|
|
166
168
|
|
|
@@ -169,22 +171,22 @@ Loader behavior:
|
|
|
169
171
|
|
|
170
172
|
### 4.2 File Format
|
|
171
173
|
|
|
172
|
-
`WORKFLOW.
|
|
174
|
+
`WORKFLOW.yaml` is a pure YAML config file. There is no inline prompt body;
|
|
175
|
+
each active state's prompt lives in its own `prompt_file` (a Liquid template).
|
|
173
176
|
|
|
174
177
|
Parsing rules:
|
|
175
178
|
|
|
176
|
-
-
|
|
177
|
-
|
|
178
|
-
-
|
|
179
|
-
-
|
|
180
|
-
|
|
181
|
-
- YAML front matter MUST decode to a map/object; non-map YAML is an error.
|
|
182
|
-
- Prompt body is trimmed before use.
|
|
179
|
+
- The whole file decodes as a single YAML document → the config map.
|
|
180
|
+
- The decoded YAML MUST be a map/object; a list or bare scalar is an error.
|
|
181
|
+
- An empty/whitespace-only file decodes to an empty config map.
|
|
182
|
+
- A leading `---` YAML document marker is tolerated (decoded as YAML), but
|
|
183
|
+
there is no front-matter fence and no Markdown body.
|
|
183
184
|
|
|
184
185
|
Returned workflow object:
|
|
185
186
|
|
|
186
|
-
- `config`:
|
|
187
|
-
- `
|
|
187
|
+
- `config`: the decoded YAML config root object (not nested under a `config` key).
|
|
188
|
+
- `prompt_templates`: per-state assembled prompt templates (built by the shell
|
|
189
|
+
loader from each active state's `prompt_file`; see §3.1.2).
|
|
188
190
|
|
|
189
191
|
### 4.3 Front Matter Schema
|
|
190
192
|
|
|
@@ -192,7 +194,7 @@ Top-level keys: `tracker`, `states`, `polling`, `workspace`, `agent`,
|
|
|
192
194
|
`acp`. Unknown keys SHOULD be ignored for forward compatibility. Extensions
|
|
193
195
|
MAY define additional top-level keys without changing the core schema.
|
|
194
196
|
|
|
195
|
-
`WORKFLOW.template.
|
|
197
|
+
`WORKFLOW.template.yaml` is the annotated reference for every recognized field;
|
|
196
198
|
this section captures the contract the loader enforces.
|
|
197
199
|
|
|
198
200
|
#### 4.3.1 `tracker` (object)
|
|
@@ -216,7 +218,7 @@ supported kind.
|
|
|
216
218
|
|
|
217
219
|
- `root` (path string or `$VAR`, default `<system-temp>/symphony_workspaces`)
|
|
218
220
|
- `~` is expanded; relative paths are resolved relative to the directory
|
|
219
|
-
containing `WORKFLOW.
|
|
221
|
+
containing `WORKFLOW.yaml`. The effective workspace root is normalized to an
|
|
220
222
|
absolute path before use.
|
|
221
223
|
|
|
222
224
|
#### 4.3.4 `agent` (object)
|
|
@@ -235,7 +237,7 @@ supported kind.
|
|
|
235
237
|
Coding-agent launch is mediated by the Agent Client Protocol. The runtime
|
|
236
238
|
selects an adapter profile and runs it inside the per-issue sandbox; the host
|
|
237
239
|
opens an authenticated TCP bridge that the in-sandbox proxy dials back over
|
|
238
|
-
to carry ACP frames. See `WORKFLOW.template.
|
|
240
|
+
to carry ACP frames. See `WORKFLOW.template.yaml` (`acp:` section) for the full
|
|
239
241
|
annotated field list. Adapter credentials are handled out of band of this
|
|
240
242
|
config — there is no credential-mode knob; see §6.3 for the host credential
|
|
241
243
|
proxy and identity-staging contract.
|
|
@@ -251,7 +253,7 @@ Fields read by the runtime:
|
|
|
251
253
|
- `stall_timeout_ms` (integer, default `300000`; `<= 0` disables stall
|
|
252
254
|
detection)
|
|
253
255
|
- `bridge` (object) — `bind_host`, `bind_port`, `reach_host`, `reach_url`,
|
|
254
|
-
`connect_timeout_ms`; see `WORKFLOW.template.
|
|
256
|
+
`connect_timeout_ms`; see `WORKFLOW.template.yaml`.
|
|
255
257
|
|
|
256
258
|
#### 4.3.6 `states` (map)
|
|
257
259
|
|
|
@@ -315,7 +317,8 @@ states, not named here.
|
|
|
315
317
|
|
|
316
318
|
### 4.4 Prompt Template Contract
|
|
317
319
|
|
|
318
|
-
|
|
320
|
+
Each active state's `prompt_file` (wrapped in the shared
|
|
321
|
+
`prompt.preamble_file`/`footer_file`) is that state's per-issue prompt template.
|
|
319
322
|
|
|
320
323
|
Rendering requirements:
|
|
321
324
|
|
|
@@ -332,8 +335,9 @@ Template input variables:
|
|
|
332
335
|
|
|
333
336
|
Fallback prompt behavior:
|
|
334
337
|
|
|
335
|
-
- If
|
|
336
|
-
|
|
338
|
+
- If a dispatched state has no assembled template (no `prompt_file`), or the
|
|
339
|
+
template renders empty, the runtime MAY use a minimal default prompt
|
|
340
|
+
(`You are working on an issue.`).
|
|
337
341
|
- Workflow file read/parse failures are configuration/validation errors and
|
|
338
342
|
SHOULD NOT silently fall back to a prompt.
|
|
339
343
|
|
|
@@ -660,7 +664,12 @@ active → holding); cleanup is driven by the target state's role
|
|
|
660
664
|
|
|
661
665
|
Inputs to prompt rendering:
|
|
662
666
|
|
|
663
|
-
- `workflow.
|
|
667
|
+
- `workflow.prompt_templates[issue.state]` — the assembled prompt template for
|
|
668
|
+
the issue's current state, selected from the per-state `prompt_templates` map
|
|
669
|
+
(each entry built by the loader from that state's `prompt_file`, wrapped in
|
|
670
|
+
the shared `prompt.preamble_file`/`footer_file`; see §3.1.2 / §4.2). When no
|
|
671
|
+
template exists for the state (or it is empty), rendering falls back to the
|
|
672
|
+
generic prompt `You are working on an issue.`
|
|
664
673
|
- normalized `issue` object
|
|
665
674
|
- OPTIONAL `attempt` integer (retry/continuation metadata)
|
|
666
675
|
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# WORKFLOW.yaml — minimal starter scaffolded by smol-symphony.
|
|
2
|
+
#
|
|
3
|
+
# Run: npx smol-symphony WORKFLOW.yaml --port 8787
|
|
4
|
+
#
|
|
5
|
+
# A workflow file is pure YAML config; each active state's prompt lives in its
|
|
6
|
+
# own `prompt_file`. `npx smol-symphony` scaffolds this file plus prompts/Todo.md
|
|
7
|
+
# next to it. For the full annotated reference — per-state adapters/models, typed
|
|
8
|
+
# action DAGs, egress allowlists, PR autopilot, sleep-cycle reflection, and every
|
|
9
|
+
# other optional power feature — see WORKFLOW.template.yaml:
|
|
10
|
+
# https://github.com/dizk/smol-symphony/blob/main/WORKFLOW.template.yaml
|
|
11
|
+
|
|
12
|
+
tracker:
|
|
13
|
+
kind: local # issues are markdown files under <tracker.root>/<state>/
|
|
14
|
+
# default root: ~/.symphony/trackers/<project> (outside
|
|
15
|
+
# the repo; set tracker.root: to override)
|
|
16
|
+
|
|
17
|
+
states:
|
|
18
|
+
Todo:
|
|
19
|
+
role: active # dispatched — an agent picks the issue up here
|
|
20
|
+
adapter: claude # the coding agent to run (claude | codex)
|
|
21
|
+
prompt_file: prompts/Todo.md # this state's prompt template
|
|
22
|
+
Done:
|
|
23
|
+
role: terminal # transitioning here ends the run and cleans up
|
|
24
|
+
Triage:
|
|
25
|
+
role: holding # propose_issue lands here; never auto-dispatched
|
|
26
|
+
|
|
27
|
+
gondolin:
|
|
28
|
+
# The agent rootfs each per-issue microVM boots. `managed` (the default) FETCHES a
|
|
29
|
+
# prebuilt asset from a published symphony release on first run — no docker, no
|
|
30
|
+
# `npm run build:image`. The image ships only `mise`; node + the agent CLIs are always
|
|
31
|
+
# mise-installed at dispatch (see gondolin.mise in WORKFLOW.template.yaml — mise
|
|
32
|
+
# provisioning is the only toolchain path). To pin your own asset instead, set this to a build id / name:tag from
|
|
33
|
+
# `npm run build:image`, or use gondolin.oci_image for an auto-converted OCI ref.
|
|
34
|
+
image: managed
|