Skip to content

D2 · Embryo roles/strain + multi-embryo Operations observability#68

Closed
pskeshu wants to merge 11 commits into
feature/tactics-libraryfrom
feature/embryo-roles-observability
Closed

D2 · Embryo roles/strain + multi-embryo Operations observability#68
pskeshu wants to merge 11 commits into
feature/tactics-libraryfrom
feature/embryo-roles-observability

Conversation

@pskeshu

@pskeshu pskeshu commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator

Sub-project D2. Reuses gently's existing roles.REGISTRY; strain ⊥ use.

  • Per-embryo strain (free-form) + roles-as-use (adds lineaging + a subject/reference role_class) + the multi-embryo roster lens (population by class→role, real registry colors, strain shown) + role-scoped tactics.
  • Detector stays on role this pass; full detector→strain separation tracked as future work (spec §4).
  • 4 tasks + whole-branch review + fix; 54 tests; Chrome-audited.

Stack:feature/tactics-library (G).

pskeshu added 11 commits June 29, 2026 05:10
Add free-form `strain: str | None` to EmbryoInfo, EmbryoState,
register_embryo (create + coalesce-update), and the positions endpoint
— threaded exactly like the existing `role` field. Tests in
tests/test_embryo_strain.py (6/6 pass).
Add role_class field ("subject"|"reference") to EmbryoRole frozen dataclass.
Set on all existing entries: test/unassigned→subject, calibration→reference.
Add lineaging registry entry (role_class=reference, ui_color=#33cc88, icon=triangle,
detector=perception) — a distinct use even when the strain overlaps calibration.
Detector wiring is staged; strain→detector decoupling deferred to spec §4.
22 new tests in tests/test_roles_registry.py; 0 new failures in full suite.
- GET /api/roles returns REGISTRY as {roles:[{name,description,role_class,
  ui_color,ui_icon,default_cadence_seconds}]}; registered in routes/__init__.py
- resolve_scope_embryos() in gently/app/orchestration/role_scope.py maps
  scope.mode in {global,embryos,role} → list[embryo_id]; unknown → []
- _validate_tactics already passes scope through unmodified; role-scoped
  tactics (mode='role', role in REGISTRY) confirmed to pass declare_operation_plan
- Embryo id key confirmed as 'embryo_id' (from /api/embryos/positions)
- 22 new tests: 9 route + 13 resolver/validation; 0 new failures in suite
Add a population roster lens above the tactic spine in the Operations
view. Reads /api/embryos/positions (role, strain, cadence_phase) and
/api/roles (ui_color, ui_icon, role_class) fetched in parallel at init
and on each debounced refresh.

Roster structure:
- SUBJECTS section (role_class=subject, foregrounded, animated live dot)
- REFERENCES section (role_class=reference, compact/muted rows)
- Within each class: role groups with left-edge in real REGISTRY ui_color
- Each embryo row: id · role chip · strain · cadence-phase chip ·
  current tactic (cross-referenced from plan scope) · state

Tactic spine nodes gain role-scope badges when roster context is present:
  → test · E01, E02, E03  (role mode, magenta from API)
  → all embryos            (global, muted grey)
  → E01, E02              (explicit embryos, muted grey)

Role colors come from /api/roles ui_color at runtime via inline styles
(_hexToRgba helper); nothing role-specific is hardcoded in experiment.css.

Backward compat: if either endpoint is empty/absent, rosterCtx = null,
the lens is omitted, and the spine renders exactly as before D2. The
fifth rosterCtx argument on _renderOpsTactic defaults to null so all
existing callers (scenario mode etc.) are unaffected.

node --check: PASS
…ryos + resolver-coupling note

- timelapse_tracker.py: EMBRYO_DETECTED handler now sets emb["strain"] when
  "strain" key present in data (mirrors role handling); seed_from_experiment
  now passes strain=getattr(emb, "strain", None) in the EMBRYO_DETECTED
  payload — fixes strain always showing "—" in live roster.
- experiment-overview.js: rename _rosterEmbyros → _rosterEmbryos (9 sites,
  property + local variable); add coupling note on _resolveCurrentTactic
  pointing to role_scope.py resolve_scope_embryos.
- tests/test_embryo_strain.py: 4 new tracker tests (EMBRYO_DETECTED handler
  + seed_from_experiment with/without strain); all 10 pass.
@pskeshu

pskeshu commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator Author

Superseded by #72 — the temperature + Operations/tactics suite and the new Operate (bottom-cam→SPIM) surface are consolidated onto feature/temperature-operations-all (now targeting development). This increment's work is included there; its feature branch was deleted. Closing to keep a single main PR.

@pskeshu pskeshu closed this Jul 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant