Conversation
This was referenced Sep 13, 2026
MaxRink
force-pushed
the
feature/guarded-plugin-scale-actions
branch
from
September 13, 2026 21:39
45e764a to
9320595
Compare
1 task
MaxRink
force-pushed
the
feature/guarded-plugin-scale-actions
branch
from
September 14, 2026 08:58
9320595 to
5962990
Compare
MaxRink
force-pushed
the
feature/guarded-plugin-scale-actions
branch
from
September 14, 2026 11:55
5962990 to
96ae92b
Compare
15 tasks
Member
|
Maintainer direction: keep this held for human review, not as a 0.9.0 generic runtime/grinder release gate. See #853 and tracker #890. The guarded-action idea is useful for Skale button behavior, but it is safety-sensitive machine-control API work with deliberate compatibility changes. Please do not let this block or become a prerequisite for the P0 generic runtime work while maintainer availability is limited. |
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.
Summary
Add an opt-in guarded form to the machine state route so a plugin action is checked again when it reaches the hardware.
GET /api/v1/machine/statenow includes the currentdeviceIdandconnectionGeneration; the guarded request carries the expected machine identity, generation, state, GHC condition, and primary scale identity tokens. Stale or reassigned context is rejected before any machine write.For example, a plugin can observe machine A idle and primary scale S selected, then queue a start; if A reconnects or S is reassigned before execution, the generation and selection tokens reject that stale start instead of writing to the replacement context.
GET /api/v1/scale/connectionsexposes the current primary connection as{"primary": null}or{"primary": {...}}. The guarded action accepts only theprimarysource role. A non-primary source is rejected with400; stale machine or scale tokens return409.Only
idle -> espressostarts andespresso -> idlestops are guarded. Stops use the direct stop path and invalidate older queued guarded starts. Legacy unguarded requests retain their existing path.Linked Issue
Related #853. Related #715 for the accepted Skale button behavior. The single-device Skale consumer is #846; multi-scale host work is #843/#859.
Verification
Combined Linux Flutter gate for the current publication stack: 4,315 passed, 1 skipped, 0 failed; analyzer clean (48.0s). Source was unchanged during the gate.
This combined gate covers the primary-only guarded-action contract together with its current consumers; the primary-only API remains independently reviewable from the auxiliary-scale consumer.
Primary guarded-action and reload smoke passed primary start/stop, stale-context rejection, auxiliary-source rejection, and legacy bodyless stop.
Primary guarded-action and reload smoke passed primary start/stop, stale-context rejection, auxiliary-source rejection, and legacy bodyless stop.
Impact
The guarded form is opt-in and introduces no auxiliary machine-action role. It prevents a plugin from acting on a machine or primary scale context that changed after the button decision. Bodyless requests, valid legacy JSON without
guarded, JSONnull, andguarded: falseretain the unguarded path; malformed nonempty JSON and a non-booleanguardedvalue now return400rather than falling through to an unguarded write.Contributor Responsibility
AI-assisted development is allowed. The submitter remains responsible for the submitted work.