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,140 @@
|
|
|
1
|
+
// Focused tests for finding #3: the workspace adapter must read workspace.root /
|
|
2
|
+
// source-repo via a LIVE config closure, NOT a boot snapshot, so a WORKFLOW.yaml
|
|
3
|
+
// hot-reload that moves workspace.root retargets create/list/remove instead of
|
|
4
|
+
// stranding them on the stale path.
|
|
5
|
+
import { test } from 'node:test';
|
|
6
|
+
import assert from 'node:assert/strict';
|
|
7
|
+
import { mkdtemp, mkdir, rm, writeFile } from 'node:fs/promises';
|
|
8
|
+
import os from 'node:os';
|
|
9
|
+
import path from 'node:path';
|
|
10
|
+
import { createWorkspaceAdapter } from '../../src/shell/interp/workspace.js';
|
|
11
|
+
// A ProcessRunner stub — list/remove/workspacePathFor don't spawn, so a throwing
|
|
12
|
+
// runner proves these paths are pure fs against the LIVE root.
|
|
13
|
+
const noProcess = {
|
|
14
|
+
run: async () => { throw new Error('process.run must not be called on the list/remove path'); },
|
|
15
|
+
};
|
|
16
|
+
// assertContained is the pure core guard; the identity-on-contained behaviour is
|
|
17
|
+
// all the adapter needs here (root/<key> is always a strict child).
|
|
18
|
+
const assertContained = (_root, target) => target;
|
|
19
|
+
async function withDirs(fn) {
|
|
20
|
+
const base = await mkdtemp(path.join(os.tmpdir(), 'symphony-ws-live-'));
|
|
21
|
+
const a = path.join(base, 'root-a');
|
|
22
|
+
const b = path.join(base, 'root-b');
|
|
23
|
+
await mkdir(a, { recursive: true });
|
|
24
|
+
await mkdir(b, { recursive: true });
|
|
25
|
+
try {
|
|
26
|
+
await fn(a, b);
|
|
27
|
+
}
|
|
28
|
+
finally {
|
|
29
|
+
await rm(base, { recursive: true, force: true });
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
test('workspacePathFor follows a live workspace.root change (no boot snapshot)', async () => {
|
|
33
|
+
await withDirs(async (rootA, rootB) => {
|
|
34
|
+
let liveRoot = rootA;
|
|
35
|
+
const ws = createWorkspaceAdapter({
|
|
36
|
+
root: () => liveRoot,
|
|
37
|
+
sourceRepo: () => '/unused',
|
|
38
|
+
process: noProcess,
|
|
39
|
+
assertContained,
|
|
40
|
+
});
|
|
41
|
+
assert.equal(ws.workspacePathFor('7'), path.join(rootA, '7'));
|
|
42
|
+
// Simulate a WORKFLOW.yaml hot-reload that moved workspace.root.
|
|
43
|
+
liveRoot = rootB;
|
|
44
|
+
assert.equal(ws.workspacePathFor('7'), path.join(rootB, '7'), 'path uses the NEW live root');
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
test('list() enumerates the NEW root after a config change', async () => {
|
|
48
|
+
await withDirs(async (rootA, rootB) => {
|
|
49
|
+
// Seed a workspace dir under each root.
|
|
50
|
+
await mkdir(path.join(rootA, 'old-ws'), { recursive: true });
|
|
51
|
+
await mkdir(path.join(rootB, 'new-ws'), { recursive: true });
|
|
52
|
+
let liveRoot = rootA;
|
|
53
|
+
const ws = createWorkspaceAdapter({
|
|
54
|
+
root: () => liveRoot,
|
|
55
|
+
sourceRepo: () => '/unused',
|
|
56
|
+
process: noProcess,
|
|
57
|
+
assertContained,
|
|
58
|
+
});
|
|
59
|
+
assert.deepEqual((await ws.list()).map((l) => l.name).sort(), ['old-ws']);
|
|
60
|
+
liveRoot = rootB;
|
|
61
|
+
assert.deepEqual((await ws.list()).map((l) => l.name).sort(), ['new-ws'], 'list reads the NEW root');
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
test('an in-flight ensureFor after a root change targets the NEW root (not the stale old-root clone)', async () => {
|
|
65
|
+
await withDirs(async (rootA, rootB) => {
|
|
66
|
+
// The source repo must look like a git dir (setup() stats <source>/.git first).
|
|
67
|
+
const sourceRepo = path.dirname(rootA);
|
|
68
|
+
await mkdir(path.join(sourceRepo, '.git'), { recursive: true });
|
|
69
|
+
const ok = (overrides = {}) => ({ ran: true, exit_code: 0, signal: null, timed_out: false, stdout: '', stderr: '', ...overrides });
|
|
70
|
+
// Record the cwd (= workspace path) of every `git clone` and gate the FIRST clone
|
|
71
|
+
// so it stays in-flight while we change the root and fire a second ensureFor.
|
|
72
|
+
const cloneCwds = [];
|
|
73
|
+
let firstCloneSeen;
|
|
74
|
+
const firstCloneStarted = new Promise((res) => { firstCloneSeen = res; });
|
|
75
|
+
let releaseFirstClone;
|
|
76
|
+
const firstCloneGate = new Promise((res) => { releaseFirstClone = res; });
|
|
77
|
+
let cloneCount = 0;
|
|
78
|
+
const recordingProcess = {
|
|
79
|
+
run: async (argv, opts) => {
|
|
80
|
+
const cwd = opts?.cwd ?? '';
|
|
81
|
+
if (argv[0] === 'git' && argv[1] === 'clone') {
|
|
82
|
+
cloneCwds.push(cwd);
|
|
83
|
+
if (cloneCount++ === 0) {
|
|
84
|
+
firstCloneSeen();
|
|
85
|
+
await firstCloneGate;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// restorePushedBranch: `git remote get-url origin` exit!=0 → local-only → checkout -b.
|
|
89
|
+
if (argv[1] === 'remote' && argv[2] === 'get-url')
|
|
90
|
+
return ok({ exit_code: 1 });
|
|
91
|
+
if (argv[1] === 'remote' && argv.length === 2)
|
|
92
|
+
return ok({ stdout: '' }); // no remotes to strip
|
|
93
|
+
return ok();
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
let liveRoot = rootA;
|
|
97
|
+
const ws = createWorkspaceAdapter({
|
|
98
|
+
root: () => liveRoot,
|
|
99
|
+
sourceRepo: () => sourceRepo,
|
|
100
|
+
process: recordingProcess,
|
|
101
|
+
assertContained,
|
|
102
|
+
});
|
|
103
|
+
const opts = { baseBranch: 'main', githubRepo: null };
|
|
104
|
+
const first = ws.ensureFor('9', opts); // clones into rootA, then parks on the gate
|
|
105
|
+
await firstCloneStarted;
|
|
106
|
+
// WORKFLOW.yaml hot-reload moves workspace.root mid-clone.
|
|
107
|
+
liveRoot = rootB;
|
|
108
|
+
// A fresh ensureFor for the SAME id must NOT reuse the parked old-root promise —
|
|
109
|
+
// the in-flight key includes the live root, so this starts a new clone under rootB.
|
|
110
|
+
const second = ws.ensureFor('9', opts);
|
|
111
|
+
releaseFirstClone();
|
|
112
|
+
const [r1, r2] = await Promise.all([first, second]);
|
|
113
|
+
assert.equal(r1.path, path.join(rootA, '9'), 'first ensureFor resolved under the OLD root');
|
|
114
|
+
assert.equal(r2.path, path.join(rootB, '9'), 'second ensureFor targets the NEW root');
|
|
115
|
+
// Two DISTINCT clones happened (one per root) — the stale promise was not reused.
|
|
116
|
+
assert.deepEqual(cloneCwds.sort(), [path.join(rootA, '9'), path.join(rootB, '9')].sort());
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
test('remove() targets the NEW root after a config change', async () => {
|
|
120
|
+
await withDirs(async (rootA, rootB) => {
|
|
121
|
+
// Same workspace key exists under both roots; remove must hit the live one.
|
|
122
|
+
await mkdir(path.join(rootA, 'dup'), { recursive: true });
|
|
123
|
+
await writeFile(path.join(rootA, 'dup', 'keep.txt'), 'a', 'utf8');
|
|
124
|
+
await mkdir(path.join(rootB, 'dup'), { recursive: true });
|
|
125
|
+
await writeFile(path.join(rootB, 'dup', 'gone.txt'), 'b', 'utf8');
|
|
126
|
+
let liveRoot = rootB;
|
|
127
|
+
const ws = createWorkspaceAdapter({
|
|
128
|
+
root: () => liveRoot,
|
|
129
|
+
sourceRepo: () => '/unused',
|
|
130
|
+
process: noProcess,
|
|
131
|
+
assertContained,
|
|
132
|
+
});
|
|
133
|
+
await ws.remove('dup', 'stale_issue');
|
|
134
|
+
// The dir under the LIVE root (B) is gone; the same-named dir under A survives.
|
|
135
|
+
assert.deepEqual((await ws.list()).map((l) => l.name), [], 'live root dir removed');
|
|
136
|
+
liveRoot = rootA;
|
|
137
|
+
assert.deepEqual((await ws.list()).map((l) => l.name), ['dup'], 'stale-root dir untouched');
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
//# sourceMappingURL=workspace-live-config.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-live-config.test.js","sourceRoot":"","sources":["../../../tests/shell/workspace-live-config.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "smol-symphony",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "TypeScript orchestrator that runs coding agents (Claude, Codex, OpenCode) in per-issue Gondolin microVMs over ACP.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"orchestrator",
|
|
@@ -29,26 +29,37 @@
|
|
|
29
29
|
},
|
|
30
30
|
"files": [
|
|
31
31
|
"dist/",
|
|
32
|
-
"
|
|
33
|
-
"WORKFLOW.
|
|
32
|
+
"patches/",
|
|
33
|
+
"WORKFLOW.yaml",
|
|
34
|
+
"WORKFLOW.minimal.yaml",
|
|
35
|
+
"WORKFLOW.template.yaml",
|
|
36
|
+
"assets/",
|
|
37
|
+
"prompts/",
|
|
38
|
+
"prompts-minimal/",
|
|
34
39
|
"AGENTS.md",
|
|
35
40
|
"SPEC.md",
|
|
36
41
|
"PRODUCT.md",
|
|
37
42
|
"DESIGN.md",
|
|
43
|
+
"scripts/postinstall.mjs",
|
|
38
44
|
"scripts/vm-agent.mjs",
|
|
39
45
|
"README.md",
|
|
40
46
|
"LICENSE"
|
|
41
47
|
],
|
|
42
48
|
"scripts": {
|
|
49
|
+
"postinstall": "node scripts/postinstall.mjs",
|
|
43
50
|
"build": "tsc",
|
|
44
|
-
"start": "tsx src/
|
|
45
|
-
"symphony": "tsx src/
|
|
46
|
-
"dev": "tsx watch src/
|
|
51
|
+
"start": "tsx src/shell/main.ts",
|
|
52
|
+
"symphony": "tsx src/shell/main.ts WORKFLOW.yaml",
|
|
53
|
+
"dev": "tsx watch src/shell/main.ts",
|
|
47
54
|
"typecheck": "tsc --noEmit",
|
|
48
|
-
"test": "node --test --import tsx tests/*.test.ts",
|
|
49
|
-
"prepublishOnly": "npm run typecheck && npm test && npm run build",
|
|
50
55
|
"lint": "eslint src --max-warnings 0",
|
|
51
|
-
"lint:arch": "depcruise src --ts-config tsconfig.json
|
|
56
|
+
"lint:arch": "depcruise src --ts-config tsconfig.json",
|
|
57
|
+
"check:ratio": "node scripts/check-core-ratio.mjs",
|
|
58
|
+
"check:pokes": "node scripts/check-state-pokes.mjs",
|
|
59
|
+
"check:io": "node scripts/check-shell-io.mjs",
|
|
60
|
+
"test": "node --test --import tsx $(find tests -name '*.test.ts')",
|
|
61
|
+
"verify": "npm run typecheck && npm run lint && npm run lint:arch && npm run check:ratio && npm run check:pokes && npm run check:io && npm test",
|
|
62
|
+
"prepublishOnly": "npm run typecheck && npm test && npm run build",
|
|
52
63
|
"build:image": "bash images/agents/build-image-oci.sh"
|
|
53
64
|
},
|
|
54
65
|
"dependencies": {
|
|
@@ -56,6 +67,7 @@
|
|
|
56
67
|
"@earendil-works/gondolin": "^0.12.0",
|
|
57
68
|
"chokidar": "^4.0.3",
|
|
58
69
|
"liquidjs": "^10.21.1",
|
|
70
|
+
"patch-package": "^8.0.1",
|
|
59
71
|
"yaml": "^2.6.1"
|
|
60
72
|
},
|
|
61
73
|
"devDependencies": {
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
diff --git a/node_modules/@earendil-works/gondolin/dist/src/qemu/network-stack.js b/node_modules/@earendil-works/gondolin/dist/src/qemu/network-stack.js
|
|
2
|
+
index f08a11f..b8603bd 100644
|
|
3
|
+
--- a/node_modules/@earendil-works/gondolin/dist/src/qemu/network-stack.js
|
|
4
|
+
+++ b/node_modules/@earendil-works/gondolin/dist/src/qemu/network-stack.js
|
|
5
|
+
@@ -10,6 +10,35 @@ const IP_PROTO_ICMP = 1;
|
|
6
|
+
function makeTcpNatKey(srcIP, srcPort, dstIP, dstPort) {
|
|
7
|
+
return `TCP:${srcIP}:${srcPort}:${dstIP}:${dstPort}`;
|
|
8
|
+
}
|
|
9
|
+
+// TCP sequence and acknowledgement numbers are 32 bits wide and wrap at 2^32.
|
|
10
|
+
+// We keep every stored counter (mySeq/myAck/vmSeq/vmAck) masked into [0, 2^32)
|
|
11
|
+
+// and compare them with RFC 1982 serial-number arithmetic instead of raw </>,
|
|
12
|
+
+// which break across the wrap boundary. Skipping either half re-introduces the
|
|
13
|
+
+// `writeUInt32BE` overflow crash or silent reassembly desync near 0xFFFFFFFF.
|
|
14
|
+
+/** Fold a value into the 32-bit TCP sequence space [0, 2^32). */
|
|
15
|
+
+function wrapSeq(value) {
|
|
16
|
+
+ return value >>> 0;
|
|
17
|
+
+}
|
|
18
|
+
+/**
|
|
19
|
+
+ * Signed RFC 1982 distance between two sequence numbers: > 0 when `a` is "after"
|
|
20
|
+
+ * `b`, < 0 when "before", 0 when equal. ToInt32 (`| 0`) folds the difference into
|
|
21
|
+
+ * the [-2^31, 2^31) serial window so comparisons stay correct across wrap.
|
|
22
|
+
+ */
|
|
23
|
+
+function seqDistance(a, b) {
|
|
24
|
+
+ return (a - b) | 0;
|
|
25
|
+
+}
|
|
26
|
+
+/** `a` is strictly after `b` in serial-number order. */
|
|
27
|
+
+function seqGt(a, b) {
|
|
28
|
+
+ return seqDistance(a, b) > 0;
|
|
29
|
+
+}
|
|
30
|
+
+/** `a` is strictly before `b` in serial-number order. */
|
|
31
|
+
+function seqLt(a, b) {
|
|
32
|
+
+ return seqDistance(a, b) < 0;
|
|
33
|
+
+}
|
|
34
|
+
+/** `a` is at or before `b` in serial-number order. */
|
|
35
|
+
+function seqLe(a, b) {
|
|
36
|
+
+ return seqDistance(a, b) <= 0;
|
|
37
|
+
+}
|
|
38
|
+
const HTTP_METHODS = [
|
|
39
|
+
"GET",
|
|
40
|
+
"POST",
|
|
41
|
+
@@ -503,7 +532,7 @@ export class NetworkStack extends EventEmitter {
|
|
42
|
+
vmSeq: seq,
|
|
43
|
+
vmAck: ack,
|
|
44
|
+
mySeq: Math.floor(Math.random() * 0x0fffffff),
|
|
45
|
+
- myAck: seq + 1,
|
|
46
|
+
+ myAck: wrapSeq(seq + 1),
|
|
47
|
+
peerWindow: window,
|
|
48
|
+
pendingOutbound: Buffer.alloc(0),
|
|
49
|
+
endPending: false,
|
|
50
|
+
@@ -527,14 +556,14 @@ export class NetworkStack extends EventEmitter {
|
|
51
|
+
}
|
|
52
|
+
if (!session) {
|
|
53
|
+
if (!SYN) {
|
|
54
|
+
- this.sendTCP(srcIP, srcPort, dstIP, dstPort, 0, seq + (payload.length || 1), 0x04);
|
|
55
|
+
+ this.sendTCP(srcIP, srcPort, dstIP, dstPort, 0, wrapSeq(seq + (payload.length || 1)), 0x04);
|
|
56
|
+
}
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const prevPeerWindow = session.peerWindow;
|
|
60
|
+
session.peerWindow = window;
|
|
61
|
+
let shouldDrainOutbound = false;
|
|
62
|
+
- if (ack > session.vmAck && ack <= session.mySeq) {
|
|
63
|
+
+ if (seqGt(ack, session.vmAck) && seqLe(ack, session.mySeq)) {
|
|
64
|
+
session.vmAck = ack;
|
|
65
|
+
shouldDrainOutbound = true;
|
|
66
|
+
}
|
|
67
|
+
@@ -553,12 +582,12 @@ export class NetworkStack extends EventEmitter {
|
|
68
|
+
// This matters for SSH in particular: duplicating bytes can desync the
|
|
69
|
+
// protocol and trigger errors like "Bad packet length".
|
|
70
|
+
const expectedSeq = session.myAck;
|
|
71
|
+
- if (seq > expectedSeq) {
|
|
72
|
+
+ if (seqGt(seq, expectedSeq)) {
|
|
73
|
+
// Out-of-order: re-ACK what we've already seen.
|
|
74
|
+
this.sendTCP(session.srcIP, session.srcPort, session.dstIP, session.dstPort, session.mySeq, session.myAck, 0x10);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
- const skip = Math.max(0, expectedSeq - seq);
|
|
78
|
+
+ const skip = Math.max(0, seqDistance(expectedSeq, seq));
|
|
79
|
+
if (skip >= payload.length) {
|
|
80
|
+
// Pure retransmit (or segment contains only already-acked bytes)
|
|
81
|
+
this.sendTCP(session.srcIP, session.srcPort, session.dstIP, session.dstPort, session.mySeq, session.myAck, 0x10);
|
|
82
|
+
@@ -568,7 +597,7 @@ export class NetworkStack extends EventEmitter {
|
|
83
|
+
}
|
|
84
|
+
const newPayload = payload.subarray(skip);
|
|
85
|
+
let sendBuffer = null;
|
|
86
|
+
- const nextAck = expectedSeq + newPayload.length;
|
|
87
|
+
+ const nextAck = wrapSeq(expectedSeq + newPayload.length);
|
|
88
|
+
if (!session.flowProtocol) {
|
|
89
|
+
session.pendingData = Buffer.concat([session.pendingData, newPayload]);
|
|
90
|
+
if (session.allowRawTcp) {
|
|
91
|
+
@@ -635,20 +664,20 @@ export class NetworkStack extends EventEmitter {
|
|
92
|
+
if (FIN) {
|
|
93
|
+
// FIN consumes one sequence number, so only accept it once the sequence
|
|
94
|
+
// space up to the FIN is fully received.
|
|
95
|
+
- const finSeq = seq + payload.length;
|
|
96
|
+
- if (finSeq > session.myAck) {
|
|
97
|
+
+ const finSeq = wrapSeq(seq + payload.length);
|
|
98
|
+
+ if (seqGt(finSeq, session.myAck)) {
|
|
99
|
+
// Out-of-order FIN: keep ACKing the last in-order byte.
|
|
100
|
+
this.sendTCP(session.srcIP, session.srcPort, session.dstIP, session.dstPort, session.mySeq, session.myAck, 0x10);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
- if (finSeq < session.myAck) {
|
|
104
|
+
+ if (seqLt(finSeq, session.myAck)) {
|
|
105
|
+
// Duplicate FIN (already acked)
|
|
106
|
+
this.sendTCP(session.srcIP, session.srcPort, session.dstIP, session.dstPort, session.mySeq, session.myAck, 0x10);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
// finSeq === session.myAck
|
|
110
|
+
this.callbacks.onTcpClose({ key, destroy: false });
|
|
111
|
+
- session.myAck++;
|
|
112
|
+
+ session.myAck = wrapSeq(session.myAck + 1);
|
|
113
|
+
this.sendTCP(session.srcIP, session.srcPort, session.dstIP, session.dstPort, session.mySeq, session.myAck, 0x10);
|
|
114
|
+
if (session.state === "CLOSED_BY_REMOTE" ||
|
|
115
|
+
session.state === "FIN_WAIT") {
|
|
116
|
+
@@ -664,8 +693,10 @@ export class NetworkStack extends EventEmitter {
|
|
117
|
+
const header = Buffer.alloc(20);
|
|
118
|
+
header.writeUInt16BE(srcPort, 0);
|
|
119
|
+
header.writeUInt16BE(dstPort, 2);
|
|
120
|
+
- header.writeUInt32BE(seq, 4);
|
|
121
|
+
- header.writeUInt32BE(ack, 8);
|
|
122
|
+
+ // Counters are kept wrapped at their mutation sites; mask again here so the
|
|
123
|
+
+ // serialization boundary can never emit an out-of-range uint32 (the crash).
|
|
124
|
+
+ header.writeUInt32BE(wrapSeq(seq), 4);
|
|
125
|
+
+ header.writeUInt32BE(wrapSeq(ack), 8);
|
|
126
|
+
header[12] = 0x50;
|
|
127
|
+
header[13] = flags;
|
|
128
|
+
header.writeUInt16BE(65535, 14);
|
|
129
|
+
@@ -925,7 +956,7 @@ export class NetworkStack extends EventEmitter {
|
|
130
|
+
}
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
- const inFlight = Math.max(0, session.mySeq - session.vmAck);
|
|
134
|
+
+ const inFlight = Math.max(0, seqDistance(session.mySeq, session.vmAck));
|
|
135
|
+
const maxInFlight = Math.max(0, Math.min(session.peerWindow, this.TCP_MAX_IN_FLIGHT_BYTES));
|
|
136
|
+
if (inFlight < maxInFlight) {
|
|
137
|
+
this.txFlowPaused.delete(key);
|
|
138
|
+
@@ -945,7 +976,7 @@ export class NetworkStack extends EventEmitter {
|
|
139
|
+
}
|
|
140
|
+
const MSS = 1460;
|
|
141
|
+
let bytesBurstThisTick = 0;
|
|
142
|
+
- let inFlight = Math.max(0, session.mySeq - session.vmAck);
|
|
143
|
+
+ let inFlight = Math.max(0, seqDistance(session.mySeq, session.vmAck));
|
|
144
|
+
const maxInFlight = Math.max(0, Math.min(session.peerWindow, this.TCP_MAX_IN_FLIGHT_BYTES));
|
|
145
|
+
while (session.pendingOutbound.length > 0 &&
|
|
146
|
+
inFlight < maxInFlight &&
|
|
147
|
+
@@ -963,7 +994,7 @@ export class NetworkStack extends EventEmitter {
|
|
148
|
+
if (!isLiveSession()) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
- session.mySeq += chunk.length;
|
|
152
|
+
+ session.mySeq = wrapSeq(session.mySeq + chunk.length);
|
|
153
|
+
inFlight += chunk.length;
|
|
154
|
+
bytesBurstThisTick += chunk.length;
|
|
155
|
+
}
|
|
156
|
+
@@ -990,7 +1021,7 @@ export class NetworkStack extends EventEmitter {
|
|
157
|
+
if (!isLiveSession()) {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
- session.mySeq++;
|
|
161
|
+
+ session.mySeq = wrapSeq(session.mySeq + 1);
|
|
162
|
+
session.state = "FIN_WAIT";
|
|
163
|
+
session.endPending = false;
|
|
164
|
+
inFlight += 1;
|
|
165
|
+
@@ -1012,7 +1043,7 @@ export class NetworkStack extends EventEmitter {
|
|
166
|
+
return;
|
|
167
|
+
session.state = "ESTABLISHED";
|
|
168
|
+
this.sendTCP(session.srcIP, session.srcPort, session.dstIP, session.dstPort, session.mySeq, session.myAck, 0x12);
|
|
169
|
+
- session.mySeq++;
|
|
170
|
+
+ session.mySeq = wrapSeq(session.mySeq + 1);
|
|
171
|
+
}
|
|
172
|
+
handleTcpData(message) {
|
|
173
|
+
const session = this.natTable.get(message.key);
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
You are the **reflector** running symphony's *sleep cycle*. You are not
|
|
2
|
+
implementing or reviewing a product change. Your job: mine symphony's own
|
|
3
|
+
finished work for *recurring* friction in **how it runs work**, distil concrete
|
|
4
|
+
lessons, and file one harness-improvement proposal per lesson into Triage —
|
|
5
|
+
where a human operator decides whether to adopt it. Then close out this cycle.
|
|
6
|
+
|
|
7
|
+
You are a single-run, ephemeral reflection issue: you were spawned for this one
|
|
8
|
+
cycle, you run once, and you terminate in `Reflected`. There is no parked ticket
|
|
9
|
+
to re-arm — the orchestrator mints a fresh reflection issue for the next cycle.
|
|
10
|
+
|
|
11
|
+
This is a self-modifying loop: you read agent-authored transcripts and then
|
|
12
|
+
propose changes to *your own* operating instructions. The guardrails below are
|
|
13
|
+
load-bearing — follow them exactly.
|
|
14
|
+
|
|
15
|
+
**What you can read** (read-only mounts present only in this state):
|
|
16
|
+
|
|
17
|
+
- `/symphony/issues/` — every issue file across every state directory. The
|
|
18
|
+
richest signal is `/symphony/issues/Done/*.md`: each file is the full handoff
|
|
19
|
+
thread (every `symphony.transition` notes block from implementer → reviewer →
|
|
20
|
+
approval is appended to the body), so a Done file shows how the work actually
|
|
21
|
+
went, not just the final result. `Triage/`, `Cancelled/`, and the active
|
|
22
|
+
state dirs are visible too.
|
|
23
|
+
- `/symphony/logs/<id>.jsonl` — the per-issue run log: every ACP frame, adapter
|
|
24
|
+
stderr line, typed-action output, and orchestrator lifecycle event for that issue.
|
|
25
|
+
This is where stalls, turn-budget exhaustion, retries, and timeouts show up
|
|
26
|
+
in detail.
|
|
27
|
+
- Your workspace is a clone of the symphony repo, so you can read `WORKFLOW.yaml`,
|
|
28
|
+
`WORKFLOW.template.yaml`, `src/`, `images/agents/`, etc. to ground each proposal
|
|
29
|
+
in the concrete knob it would change.
|
|
30
|
+
|
|
31
|
+
If structured per-issue run summaries exist (companion issue #123), start from
|
|
32
|
+
those as an index; otherwise skim `Done/*.md` and open the
|
|
33
|
+
`/symphony/logs/<id>.jsonl` for the issues that look anomalous.
|
|
34
|
+
|
|
35
|
+
**What to look for — *recurring* patterns, not one-offs.** One bad run is
|
|
36
|
+
noise; the same failure shape across several issues is signal. For example:
|
|
37
|
+
|
|
38
|
+
- repeated `Review → Todo` rejects with the same root cause (the reviewer keeps
|
|
39
|
+
catching the same class of mistake the implementer prompt doesn't prevent);
|
|
40
|
+
- turn-budget exhaustion (a state hits `max_turns` before it can transition);
|
|
41
|
+
- stalls / timeouts (`stall_timeout_ms` / `prompt_timeout_ms` trips);
|
|
42
|
+
- rebase / merge-conflict churn on re-dispatch;
|
|
43
|
+
- credential re-login loops;
|
|
44
|
+
- acceptance-criteria misses a sharper prompt or checklist would have caught;
|
|
45
|
+
- prompt ambiguity that forced `request_human_steering`.
|
|
46
|
+
|
|
47
|
+
**For each distilled lesson, file exactly one `symphony.propose_issue` call**
|
|
48
|
+
(one per fix — never batch multiple fixes into one proposal; Triage is
|
|
49
|
+
per-item). Each proposal must:
|
|
50
|
+
|
|
51
|
+
- name a single concrete change to the **harness / operating config**: a
|
|
52
|
+
per-state `prompt_file`, a per-state `model` / `max_turns` /
|
|
53
|
+
`allowed_transitions` / `effort` / `actions`, the `gondolin` image config, an
|
|
54
|
+
acceptance criterion, or a timeout;
|
|
55
|
+
- include a **before → after** (what the config/prompt says now, what you'd
|
|
56
|
+
change it to);
|
|
57
|
+
- cite the **evidence** — the issue ids (and, where useful, the log lines or
|
|
58
|
+
Done-file quotes) that motivated it — so the operator can check the lesson
|
|
59
|
+
against the trajectories rather than trusting your summary.
|
|
60
|
+
|
|
61
|
+
**Hard guardrails — a proposal that violates any of these must NOT be filed:**
|
|
62
|
+
|
|
63
|
+
- Propose changes to the **harness only** — `WORKFLOW.yaml` /
|
|
64
|
+
`WORKFLOW.template.yaml`, per-state config (including `actions:`), the `gondolin`
|
|
65
|
+
image config, acceptance criteria, timeouts. Do **not** propose edits to product/source code under
|
|
66
|
+
`src/` as a "fix" for a trajectory; if a genuine product bug is the root
|
|
67
|
+
cause, that is an ordinary `propose_issue` for an implementer, not a harness
|
|
68
|
+
change, and you should frame it that way.
|
|
69
|
+
- Never propose anything that **weakens a quality gate.** Do not weaken or
|
|
70
|
+
remove the Review state, the `npm run typecheck` / `npm test` /
|
|
71
|
+
`npm run lint:arch` / `npm run lint` gates, or the Triage human-approval gate
|
|
72
|
+
itself. The whole point of this loop is that a human stays in it; proposals
|
|
73
|
+
that would let the loop dispatch its own changes without review are
|
|
74
|
+
forbidden, even if the trajectories seem to "justify" them.
|
|
75
|
+
- One fix per proposal, each with cited evidence. No proposal without issue ids.
|
|
76
|
+
|
|
77
|
+
When you have filed your proposals — or concluded there is no recurring pattern
|
|
78
|
+
worth acting on this cycle — hand off by terminating in `Reflected`:
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
symphony.transition({
|
|
82
|
+
to_state: "Reflected",
|
|
83
|
+
notes: "<one-paragraph log of this cycle: how many issues you reviewed, the
|
|
84
|
+
patterns you found, and the proposal titles you filed (or 'no
|
|
85
|
+
actionable pattern this cycle')>"
|
|
86
|
+
})
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Then end your turn; do not call any further tools. This issue is archived in the
|
|
90
|
+
`Reflected` column as a per-cycle audit trail; the orchestrator mints a fresh
|
|
91
|
+
reflection issue for the next cycle.
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
You are the **reviewer**. The implementer has committed work to the per-issue
|
|
2
|
+
branch (`agent/{{ issue.identifier }}`) and handed off. Their summary is in
|
|
3
|
+
the issue description above. Your job: decide whether the work is correct and
|
|
4
|
+
either approve (→ Done) or send it back (→ Todo) with specific findings.
|
|
5
|
+
|
|
6
|
+
1. Read the implementer's notes in the issue description carefully — title,
|
|
7
|
+
summary, files claimed touched. (Follow-ups belong in `propose_issue`,
|
|
8
|
+
not the notes; if you see a "Follow-ups not done" section in the notes,
|
|
9
|
+
reject and ask the implementer to file each item as a separate
|
|
10
|
+
`propose_issue` call instead.)
|
|
11
|
+
2. Inspect the diff against the freshly-fetched base. The host fetched
|
|
12
|
+
`origin/main` (or whatever base branch `SYMPHONY_BASE_BRANCH` names — `main`
|
|
13
|
+
is the default here) into this workspace before the dispatch, and the
|
|
14
|
+
implementer rebased onto it, so `origin/main` is the true base:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
git log --oneline origin/main..HEAD
|
|
18
|
+
git diff origin/main..HEAD
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Diff against `origin/main`, **not** the local `main` ref: your workspace's
|
|
22
|
+
local `main` is frozen at clone time and goes **stale** as sibling PRs merge
|
|
23
|
+
— `origin/main` advances but local `main` does not. Diffing `main..HEAD` then
|
|
24
|
+
surfaces commits already on base as if they were the implementer's change,
|
|
25
|
+
and can make a correctly-based branch look like it *reverts* recently-landed
|
|
26
|
+
work. (Local-only mode — no `origin` remote — has no such drift, so `main`
|
|
27
|
+
stays the correct base there.) If `HEAD`'s merge-base is behind `origin/main`
|
|
28
|
+
(e.g. `git merge-tree --write-tree HEAD origin/main` reports conflicts),
|
|
29
|
+
reject to `Todo` asking the implementer to rebase onto `origin/main` — don't
|
|
30
|
+
agonize over an apparent revert.
|
|
31
|
+
|
|
32
|
+
Look at each file the implementer claimed to touch. Spot-check tests and
|
|
33
|
+
typecheck pass:
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
npm run typecheck
|
|
37
|
+
npm test
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
3. Placement check — is the change on the right side of the seam?
|
|
41
|
+
|
|
42
|
+
The orchestrator (`src/agent/runner.ts`, `src/mcp.ts`, `src/orchestrator.ts`)
|
|
43
|
+
owns the state machine and tracker. Repo-local glue (`git push`, `gh pr
|
|
44
|
+
create`, rescuing artifacts) lives in a state's typed `actions:` block
|
|
45
|
+
(or a `run_in_vm` action for arbitrary guest commands). Reject when the
|
|
46
|
+
diff crosses that line:
|
|
47
|
+
|
|
48
|
+
- An action implements a new state transition, or mutates the tracker
|
|
49
|
+
filesystem the orchestrator owns (e.g. `mv issues/<state>/<id>.md
|
|
50
|
+
issues/<other-state>/<id>.md`).
|
|
51
|
+
- An action mutates runtime state the orchestrator committed earlier (e.g.
|
|
52
|
+
undoing a cleanup flag) and the runner now has to re-detect what the
|
|
53
|
+
action did via a post-action scan.
|
|
54
|
+
- A new `SYMPHONY_*` env var is added so an action can reach into
|
|
55
|
+
orchestrator-owned state. The contract is growing because the logic is
|
|
56
|
+
on the wrong side; surface it as a typed call in the runner/MCP layer
|
|
57
|
+
instead.
|
|
58
|
+
|
|
59
|
+
If any of the above fires, reject with a pointer to the right home
|
|
60
|
+
(runner, MCP tool, or orchestrator). Action-only diffs that stay within
|
|
61
|
+
repo-local glue (push/PR/format-patch) are fine — this check is
|
|
62
|
+
about state-machine logic leaking into a state's `actions:`.
|
|
63
|
+
|
|
64
|
+
4. Decide:
|
|
65
|
+
|
|
66
|
+
- **Approve**: the change is correct, tests pass, no blocking issues. Call
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
symphony.transition({
|
|
70
|
+
to_state: "Done",
|
|
71
|
+
notes: "<approval rationale; this becomes the PR body>"
|
|
72
|
+
})
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Your notes are appended to the issue body and feed straight into the PR
|
|
76
|
+
description the host opens against the base branch. Be specific about
|
|
77
|
+
what you verified.
|
|
78
|
+
|
|
79
|
+
- **Reject**: the change is wrong, incomplete, or has issues that need
|
|
80
|
+
rework. Call
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
symphony.transition({
|
|
84
|
+
to_state: "Todo",
|
|
85
|
+
notes: "<specific findings: file paths, line numbers, what's wrong,
|
|
86
|
+
what needs to change. Be concrete — the implementer will see
|
|
87
|
+
this as their next prompt.>"
|
|
88
|
+
})
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
The issue goes back to Todo with your findings appended. The same
|
|
92
|
+
workspace and `agent/{{ issue.identifier }}` branch survive the round
|
|
93
|
+
trip, so the next implementer dispatch sees both your notes and their
|
|
94
|
+
prior commits.
|
|
95
|
+
|
|
96
|
+
Either way, end your turn after the transition call. Do not call any
|
|
97
|
+
further tools.
|