feat(operate): target a subset of embryos for a run - #161
Merged
Conversation
The orchestrator and the route have always taken an explicit `embryo_ids` list — `orchestrator.start(embryo_ids=[...])` images exactly those, and the route passes it straight through. The UI never offered it: `adaptive` and `library` sent every non-reference embryo, and there was no way to say "just this one". The only workaround was to mark the others as references, and `role` is not a selection mechanism. It decides what an embryo is FOR: `expression_monitoring` scopes to `role == 'test'`, and the orchestrator's `_is_eligible` reads `role.photodose_budget_multiplier` for the dose budget. So excluding an embryo from tonight's run by demoting it also changed its monitoring and its exposure allowance. Two different facts, one field. ## Selection is a set `_selected` stays the primary — the one the instrument panes act on, which is what it has always meant. `_targets` is every member. Plain click replaces, Ctrl/Cmd-click toggles, Shift-click ranges: the interaction every file manager, DAW and photo library already teaches, so the set needs no chrome of its own. With one embryo selected the two coincide, so single-embryo work is unchanged. Two row states, deliberately distinct: `is-sel` is membership, `is-primary` is the cursor. ## Narrowing is a thing you say Targets deliberately do NOT follow the selection implicitly. If they did, a plain click in the roster would narrow a timelapse from every subject to one, silently — a worse failure than not having the feature at all. So Acquisition carries a two-state control, `All subjects (n)` / `Selected (n)`, defaulting to All, which is exactly what this pane has always done. It also means the modifier keys do not have to be discovered for the scope to be readable, and "Selected" is disabled until something is. A reference is never a target however it is selected — role still decides what an embryo is for. The set drops members that no longer exist on a roster refresh, or it would silently target ghosts: the same class as the phantom row in gently-project#126. Verified live: plain/ctrl/shift produce `[2]`, `[2,4]`, `[1,2,3,4]`; the payload sent to `timelapse/start` is all three subjects under All, exactly the two selected under Selected, and all three again on switching back. The counts exclude a selected reference. Answers the question directly: yes, you can target one embryo — and the capability was in the orchestrator all along. 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.
Answers the question directly: yes, you can target one embryo — and the capability was in the orchestrator all along.
orchestrator.start(embryo_ids=[...])images exactly those, and the route passes it straight through. The UI never offered it:adaptiveandlibrarysent every non-reference embryo.The only workaround was to mark the others as references, and
roleis not a selection mechanism. It decides what an embryo is for —expression_monitoringscopes torole == 'test', and_is_eligiblereadsrole.photodose_budget_multiplierfor the dose budget. So excluding an embryo from tonight's run by demoting it also changed its monitoring and its exposure allowance. Two different facts, one field.Selection is a set
_selectedstays the primary — the one the instrument panes act on, unchanged in meaning._targetsis every member.The interaction every file manager, DAW and photo library already teaches, so the set needs no chrome of its own. With one embryo selected the two coincide — single-embryo work is identical to before. Two row states, deliberately distinct:
is-selis membership,is-primaryis the cursor.Narrowing is a thing you say
Targets deliberately do not follow the selection implicitly. If they did, a plain click in the roster would narrow a timelapse from every subject to one, silently — a worse failure than not having the feature.
So Acquisition carries a two-state control,
All subjects (n)/Selected (n), defaulting to All, which is exactly what this pane has always done. It also means the modifier keys need not be discovered for the scope to be readable, and Selected is disabled until something is.A reference is never a target however it is selected. And the set drops members that no longer exist on a roster refresh, or it would silently target ghosts — the same class as the phantom row in #126.
Verified live
Plain/Ctrl/Shift produce
[2],[2,4],[1,2,3,4]. The payload sent totimelapse/startis all three subjects under All, exactly the two selected under Selected, and all three again on switching back. Counts exclude a selected reference.Next: the orchestrator's live per-embryo state in the same pane — three fields (
cadence_phase,next_due_at,is_complete) are missing fromEmbryoState.to_dict(), and everything else it knows is already on the wire.