Summary
Pressing k (kill) or K (kill all) in the conductor fleet TUI shows an empty red box instead of the kill-confirmation dialog. The dialog is ConfirmKillModal (src/conductor/fleet/tui/actions.py), and it renders as nothing but its own border: thick $error — its content is laid out at zero size.
The keybindings still work (y confirms, n/esc cancels), so the kill itself functions. But the user is asked to confirm the destruction of a running workflow by a box that names nothing, shows no hint keys, and — for a foreground run — omits the checkpoint-recoverability warning that is the entire reason D1 made the TUI confirm unconditionally.
Present since the Fleet Manager PR (#431, d785a28). It has never rendered.
Reproduction
conductor fleet # with at least one run listed
# press k
Reproduced deterministically in App.run_test() against textual 8.2.8:
dialog region: Region(x=47, y=13, width=6, height=4)
#confirm-message size=Size(width=0, height=0)
#confirm-hint size=Size(width=0, height=0)
█▀▀▀▀█
█ █
█ █
█▄▄▄▄█
6×4 is exactly border (2) + padding: 1 2 (4 cols / 2 rows) around a 0×0 interior. $error is #ba3c5b in the default theme, hence "red box".
Root cause
src/conductor/fleet/tui/actions.py:229-238:
#confirm-dialog {
width: auto;
height: auto;
border: thick $error;
padding: 1 2;
}
#confirm-dialog is a Vertical whose two children are Static widgets. Static.DEFAULT_CSS sets only height: auto; its width falls back to Textual's base default of 1fr. An auto-width container whose children are all 1fr resolves to 0, so both Statics collapse to 0×0 — and the auto height then has zero-width content to measure, collapsing too.
Label does not have this problem because Label.DEFAULT_CSS sets width: auto.
Verification of the fix direction
Same harness, same CSS, only the child widget/width changed:
| Variant |
Result |
Static, as shipped |
Region(width=6, height=4), children 0×0 |
Label instead of Static |
Region(width=34, height=6), renders correctly |
Static + #confirm-message, #confirm-hint { width: auto } |
Region(width=34, height=6), renders correctly |
Correct render:
█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█
█ █
█ Kill 1 run(s): plan? █
█ [y] Confirm [n/esc] Cancel █
█ █
█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█
Note the multi-line foreground-run message (build_kill_confirmation_message appends _foreground_stop_warning_lines) also needs to survive the fix — an auto-width Static sizes to its longest line, which is correct, but the fix should be checked against that case rather than only the one-line bg case.
Scope
ConfirmKillModal only. GateOptionsModal in the same file is unaffected: it uses explicit width: 90%; max-width: 120; height: 80%. Its CSS comment already documents that auto-sizing was found broken for that modal and fixed there — the same class of defect was never revisited for the kill modal.
- The markup escape in the hint (
"[bold]\\[y][/bold] ...") is fine and renders as [y] Confirm [n/esc] Cancel.
Why the tests miss it
tests/test_fleet/test_tui_actions.py drives the modal by pressing y/n and asserts on os.kill call counts/PIDs and on the message string passed to ConfirmKillModal.__init__ (test_kill_all_names_foreground_runs_in_confirmation). Nothing asserts that the modal has non-zero size or that its text reaches the screen, so a completely invisible confirmation dialog passes the entire suite.
A regression test should assert against rendered geometry/content, e.g. that #confirm-message has non-zero size and that the workflow name appears in the composited screen text — not merely that the string was constructed. The same assertion would be worth having for GateOptionsModal, since it is the one other ModalScreen in the codebase and was fixed for a related sizing failure without a test.
Summary
Pressing
k(kill) orK(kill all) in theconductor fleetTUI shows an empty red box instead of the kill-confirmation dialog. The dialog isConfirmKillModal(src/conductor/fleet/tui/actions.py), and it renders as nothing but its ownborder: thick $error— its content is laid out at zero size.The keybindings still work (
yconfirms,n/esccancels), so the kill itself functions. But the user is asked to confirm the destruction of a running workflow by a box that names nothing, shows no hint keys, and — for a foreground run — omits the checkpoint-recoverability warning that is the entire reason D1 made the TUI confirm unconditionally.Present since the Fleet Manager PR (#431,
d785a28). It has never rendered.Reproduction
Reproduced deterministically in
App.run_test()againsttextual 8.2.8:6×4 is exactly
border(2) +padding: 1 2(4 cols / 2 rows) around a 0×0 interior.$erroris#ba3c5bin the default theme, hence "red box".Root cause
src/conductor/fleet/tui/actions.py:229-238:#confirm-dialogis aVerticalwhose two children areStaticwidgets.Static.DEFAULT_CSSsets onlyheight: auto; its width falls back to Textual's base default of1fr. Anauto-width container whose children are all1frresolves to 0, so bothStatics collapse to 0×0 — and theautoheight then has zero-width content to measure, collapsing too.Labeldoes not have this problem becauseLabel.DEFAULT_CSSsetswidth: auto.Verification of the fix direction
Same harness, same CSS, only the child widget/width changed:
Static, as shippedRegion(width=6, height=4), children 0×0Labelinstead ofStaticRegion(width=34, height=6), renders correctlyStatic+#confirm-message, #confirm-hint { width: auto }Region(width=34, height=6), renders correctlyCorrect render:
Note the multi-line foreground-run message (
build_kill_confirmation_messageappends_foreground_stop_warning_lines) also needs to survive the fix — anauto-widthStaticsizes to its longest line, which is correct, but the fix should be checked against that case rather than only the one-linebgcase.Scope
ConfirmKillModalonly.GateOptionsModalin the same file is unaffected: it uses explicitwidth: 90%; max-width: 120; height: 80%. Its CSS comment already documents that auto-sizing was found broken for that modal and fixed there — the same class of defect was never revisited for the kill modal."[bold]\\[y][/bold] ...") is fine and renders as[y] Confirm [n/esc] Cancel.Why the tests miss it
tests/test_fleet/test_tui_actions.pydrives the modal by pressingy/nand asserts onos.killcall counts/PIDs and on the message string passed toConfirmKillModal.__init__(test_kill_all_names_foreground_runs_in_confirmation). Nothing asserts that the modal has non-zero size or that its text reaches the screen, so a completely invisible confirmation dialog passes the entire suite.A regression test should assert against rendered geometry/content, e.g. that
#confirm-messagehas non-zero size and that the workflow name appears in the composited screen text — not merely that the string was constructed. The same assertion would be worth having forGateOptionsModal, since it is the one otherModalScreenin the codebase and was fixed for a related sizing failure without a test.