fix(operate): make Start say which of four things it will do - #156
Merged
pskeshu merged 1 commit intoSep 5, 2026
Merged
Conversation
`startRun` branches on `_mode` into four different verbs. The button said
"Start" for all four, and the mode selector lives in a block above it, so an
operator who chose a mode and then looked away had nothing on the button to
read.
single Acquire one volume acquires one volume and finishes
adaptive Start timelapse
library Run tactic
agent Brief the agent
`single` is the one that matters: it takes a single volume and stops. Calling
that "Start" invited an operator to believe they had started an experiment. The
markup now ships single's verb so there is no flash of the wrong one on load,
and the label is restored after a run rather than reverting to "Start".
## The fallback that was exactly backwards
const subs = _embryos.filter(e => e.role !== 'calibration').map(e => e.id);
return subs.length ? subs : _embryos.map(e => e.id);
The fallback was meant to be kind to a roster with no roles assigned. It could
never do that: an embryo with no role, or role 'test', or 'unassigned' already
passes the filter, so `subs` is empty in exactly ONE case — every embryo is
marked `calibration`. So it fired only when the operator had said "these are
all references", and answered by imaging all of them as subjects. The precise
opposite of the instruction, and silent.
Gone. `haveSubjects()` now refuses at the single point both roster-driven modes
pass through, and distinguishes the two states, because "no embryos" and "no
subjects among your embryos" need different fixes.
## Checks
Four source assertions: every mode has a verb (a mode added to `setMode` but
not to `RUN_VERB` silently falls back to "Start"), single's label does not
contain "start", `subjectIds` keeps no fallback, and the guard names both
states rather than emitting one message.
Verified in the running app: labels track the mode with no flash on load, and
all three roster states produce the right answer — every-reference refused by
name, empty roster refused differently, one real subject allowed through.
Audit findings 4 and 5 in docs/devices-tab-audit.md.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Audit findings 4 and 5.
The button
startRunbranches on_modeinto four different verbs. The button said "Start" for all four, and the mode selector lives in a block above it — so an operator who chose a mode and then looked away had nothing on the button to read.singleadaptivelibraryagentsingleis the one that matters — calling it "Start" invited an operator to believe they had started an experiment. The markup ships single's verb so there's no flash of the wrong one on load, and the label is restored after a run rather than reverting to "Start".The fallback that was exactly backwards
Meant to be kind to a roster with no roles assigned. It could never do that: an embryo with no role, or
'test', or'unassigned'already passes the filter — sosubsis empty in exactly one case, when every embryo is markedcalibration.So it fired only when the operator had said "these are all references", and answered by imaging all of them as subjects. The precise opposite of the instruction, silently.
Gone.
haveSubjects()refuses at the single point both roster-driven modes pass through, and distinguishes the two states — "no embryos" and "no subjects among your embryos" need different fixes.Checks
Four source assertions: every mode has a verb (a mode added to
setModebut notRUN_VERBsilently falls back to "Start"), single's label contains no "start",subjectIdskeeps no fallback, and the guard names both states.Verified in the running app — labels track the mode with no flash, and all three roster states answer correctly: every-reference refused by name, empty roster refused differently, one real subject allowed through.