feat(harness): auto-configure launches from --env alone - #202
Conversation
spinloop harness --env <name> now configures and launches the harness from what is actually deployed to that environment when no Spinloop is applied: the env Lambda reports the runner, served model and context size alongside base_url/api_key, so a second machine only needs the environment registered (not a copy of the Spinloop) to launch against it. Nothing deployed, or a control plane predating this, fails loudly with the fix (deploy, or `remote bootstrap`) rather than launching unconfigured. Alongside this, fix spinloop harness's own flag parsing: --env (and its other flags) previously had to appear before a leading alias or path to be recognised, and an unrecognised flag anywhere before that point caused a hard "unknown flag" failure. Flags are now recognised wherever they sit relative to the Spinloop name.
The env Lambda's role was never given ssm:GetParameter on the deploy-config parameter, so its new deploy-config read (added for spinloop harness --env's auto-configure) always threw AccessDenied. That was caught by the read's own best-effort handling — the same path that covers "nothing deployed yet" — so a running, deployed environment was silently reported as having nothing deployed to configure the harness with. Found via a live run against a deployed fleet node.
|
Found and fixed a real bug during live testing against a deployed environment: the This does mean the fix needs |
Merges the harness-remote-env and remote-env deltas into the main specs, and moves the change to archive/2026-09-13-harness-env-autoconfig.
spinloop harness --env <name>now configures and launches the harness from what is actually deployed to that environment when no Spinloop is applied, and its flag parsing no longer depends on argument order.Summary
spinloop harness --env <name>with no Spinloop applied fetches the environment's live deploy-config (runner, served model, context size — read from the same SSM statedeployalready writes) and configures the harness from it, exactly as an equivalent Spinloop would. This means a second machine only needs the environment registered locally (remote.json), not a copy of the Spinloop that was deployed — and a later redeploy is picked up automatically on the next launch rather than requiring anyone to re-copy anything.envLambda predates this change, fails the launch before writing any config, naming the fix (spinloop remote deploy ... --env <name>, orspinloop remote bootstrapto update the control plane).--envis unaffected — itsPROVIDER/ALIAS/MODEL/CONTEXTstill win over the environment's deploy-config.spinloop harness's flag parsing: previously,--env(and the command's other flags) had to appear before a leading Spinloop alias/path to be recognised —spinloop harness dev-3 --env dev-1 ...silently forwarded--env dev-1to the harness instead of consuming it, with no error. Worse, an unrecognised flag (e.g.--prompt) appearing before the Spinloop name caused a hardunknown flagfailure. Flags are now recognised wherever they sit relative to the Spinloop name.Implementation details
envLambda (remote/lambda/env/index.ts) now best-effort reads the environment's deploy-config from SSM (the same helperstart/statsalready use) and includesdeployed/runner/modelId/servedName/contextSizein its reply when one is registered and parses; a missing or unparsable deploy-config just omits the fields rather than failing the call. Existing deployed accounts needspinloop remote bootstrapre-run to pick up the updated Lambda.cmd/spinloop/remote.gogainsproviderForRunner, the reverse of the existingrunnerFormapping (llamacpp/vllmare both identity mappings, so nothing else can ever reach a deploy-config).applyRoutedSpinloopgains anautoConfigurepath that synthesises aspinloop.Selectionfrom the fetched environment's deploy-config immediately before the existingapplySelectioncall, so the auto-configured path and the Spinloop-driven path write config through the exact same code.harnessCmd's singlefs.Parsecall (which stopped recognising flags at the first positional, perSetInterspersed(false)) with a hand-rolled scanner (splitHarnessArgs) that recognises the command's own flags and at most one Spinloop-naming positional in any order, and treats the first genuinely unrecognised token as the start of the harness's own arguments rather than erroring.openspec/changes/harness-env-autoconfig/(not yet archived).