feat(remote): require a named environment, drop the implicit default - #229
Merged
Merged
Conversation
`spinloop remote stop` with no flag stopped something — whichever instance happened to be registered as `default`. Five subcommands changed the state of a cloud instance while naming no target. `remote deploy` already required --env for exactly this reason, rejecting an optional flag as a footgun; that reasoning was applied to one command and not its siblings. Every remote subcommand now requires --env <name>, failing with the flag and the registered environment names rather than acting on one nobody chose. `default` stays a legal name and loses only its privilege. Two things fall out of the same root and go with it. The legacy ~/.config/spinloop/remote.json was a second path only the default environment consulted, and the reason resolving a name needed a special case; it and its readers are gone, so LoadDefault, LoadConfig and ConfigPath delete and internal/fleet resolves an environment the one way everything else does. And the documented no-remote.json workflow now works properly. It reached the control plane with an empty Config.Environment — set only by unmarshalling a file — which the shared Lambdas reject. Requiring the flag supplies the missing piece: where a named environment has no file and the SPINLOOP_REMOTE_* overrides are complete, the name given is the identifier.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Removes the environment a
remotecommand falls back to when none is named — and, with it, the legacy config path that was the reason resolving an environment name had a special case.Summary
remotesubcommand requires--env <name>. A command given none fails naming the flag and listing the registered environments, rather than acting on one the user did not choose.defaultloses its special status. The name stays legal and resolves like any other; it is simply never assumed.~/.config/spinloop/remote.jsonis no longer read.LoadDefault,LoadConfigandConfigPathare deleted.remote.jsonworkflow keeps working and starts carrying an identifier: where--env <name>names an environment with no file, completeSPINLOOP_REMOTE_*overrides configure it and the name given becomes the environment identifier.internal/fleetresolves akind: remotenode the one way everything else does — no default-environment special case.Implementation details
The danger was already on record.
remote deployhas required--envsince theREMOTE-keyword removal, whose design says why: "Creating an environment binds a name to a machine; a silent default would hide that binding and risk clobbering thedefaultenvironment" — rejecting an optional flag as a footgun. That applies to stopping an instance as much as deploying one; it had simply been applied to one command. Five others (start,stop,pause,restart,keep) still changed instance state with no target named.A latent bug this fixes rather than deepens.
docs/env-vars.mddocuments running the remote commands with noremote.jsonat all, configured entirely bySPINLOOP_REMOTE_*. ButConfig.Environmentis set only by unmarshalling a file, and that field's own comment says the shared Lambdas "reject a call without one" — so that path reached the control plane with no identifier. Requiring the flag supplies exactly the missing piece:--env ciwith complete overrides now works properly, where before it was quietly broken. That is why option 3 (no implicit target at all) ends up more capable than the narrower fixes, not merely stricter.Two decisions worth a look, recorded in the design:
start/stop/pause/restart/keep. Rejected: a rule with an exception list is one an operator has to remember, and the read is the rehearsal for the write — someone who runsremote statusthenremote stopin the same shell should not find the second means something the first did not warn about.defaultstays a legal name. The risk was never the string, it was commands assuming it. So--env defaultkeeps working for anyone who has one.Explicit non-goal: no stored "current environment" to make the flag optional again. That is the implicit target under another name. A shell alias or a fleet file does the job without the CLI holding hidden state.
The failure reads:
Coverage 90.5%, unchanged.