mirror of
https://github.com/harvard-edge/cs249r_book.git
synced 2026-05-07 18:18:42 -05:00
[GH-ISSUE #1347] refactor labs to remove widget-in-gated-cell pattern across all 33 labs #4380
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @profvjreddi on GitHub (Apr 16, 2026).
Original GitHub issue: https://github.com/harvard-edge/cs249r_book/issues/1347
context
an ast audit of all 33 labs (via the new
TestMarimoDataflow.test_no_widget_defined_in_gated_cellcheck in #1346) finds that 32 of 33 labs have the widget-in-gated-cell anti-pattern. the one clean lab,vol2/lab_05_dist_train.py, is the canonical reference for the proper pattern.the pattern looks like this:
when
partA_predictionis unanswered,mo.stop()halts the cell.partB_predictionnever gets defined. every cell that depends on it cascades into an undefined state. in lab_01's pre-fix state, this cascade was severe enough to block all instrument widgets; #1339 fixed lab_01 specifically. other labs tolerate the pattern only because users answer predictions in order.the proper pattern
from
vol2/lab_05_dist_train.py:each widget lives in its own un-gated cell. gate cells are pure
mo.stop()statements with no side-effect widget definitions.scope of work
per the audit:
each lab needs gate cells split from widget-definition cells. this is mechanical per cell but the right structure per lab depends on UX (should users see all predictions at once, or unlock sequentially?).
acceptance
pytest labs/tests/test_static.py::TestMarimoDataflowpasses with no xpass/xfail mismatchxfailmark in #1346'stest_no_widget_defined_in_gated_cellmarimo checkremains clean across all 33 labssuggested approach
vol2/lab_05_dist_trainas the templatethis is a larger cleanup sprint, not urgent for today's issues. the check landed in #1346 will prevent new labs from introducing the pattern while this refactor proceeds.
@profvjreddi commented on GitHub (Apr 16, 2026):
scope correction after more careful analysis.
the original framing treated any widget-in-gated-cell as a violation (32 of 33 labs). but the sequential-unlock idiom (one widget per gated cell) actually works correctly in practice: test_engine.py passes 70/70 against dev, and lab_02 through lab_16 use this pattern as-designed.
the REAL bug this tracks is gated cells that leak MULTIPLE widgets. when one such cell's gate fires, all its widgets go undefined and downstream cells cascade. that's what broke lab_01 pre-#1339.
per the refined
test_no_multi_widget_leak_in_gated_cellcheck landing in #1350, these 14 labs are the actual debt:(vol1/lab_01 already fixed by #1339 but still flagged here because other cells still leak multiple widgets.)
the refactor template is #1339: split each gated cell so it defines at most ONE new widget (usually the next prediction). bundle all instruments into the final gated cell, gated on the last prediction, or move them entirely into the tabs cell.
the remaining 19 labs are already clean by this criterion. the grandfather set in the test will shrink as each of these 14 gets refactored; when empty, the bug class is closed and
_KNOWN_MULTI_LEAK_LABScan be deleted.re #1349: i closed that PR without merging. it was the wrong direction (removed gates entirely rather than splitting widgets per cell).