diff --git a/manager/core/board.html b/manager/core/board.html
index 67c2327..4cd0d44 100644
--- a/manager/core/board.html
+++ b/manager/core/board.html
@@ -2303,16 +2303,18 @@ async function unarchiveLast() {
/* Where a lane sits in the stack: a halt first, because it is the one
thing on this page waiting on a person and it must not be below the
- fold; then a run in flight; then the phases nobody has started; then the
- ones that are over. Every phase card draws a lane — a phase whose
- members are all merged and which is waiting on its own PR still owns
- them, and a lane that vanished exactly when it needed merging would be
- a view you could not trust. */
+ fold; then a run in flight; then a run a person held, which is still
+ theirs to resume and so belongs above the phases nobody has started;
+ then the ones that are over. Every phase card draws a lane — a phase
+ whose members are all merged and which is waiting on its own PR still
+ owns them, and a lane that vanished exactly when it needed merging
+ would be a view you could not trust. */
function laneRank(task) {
const snap = (S.state.phases || {})[task.file];
if (snap && snap.halted) return 0;
if (snap && snap.running) return 1;
- return task.stage === 'done' ? 3 : 2;
+ if (snap && snap.stopped) return 2;
+ return task.stage === 'done' ? 4 : 3;
}
function lanePhases() {
diff --git a/tests/test_phases_view.py b/tests/test_phases_view.py
index 57d7ecc..e46b996 100644
--- a/tests/test_phases_view.py
+++ b/tests/test_phases_view.py
@@ -202,6 +202,27 @@ class OneLanePerPhase(LaneCase):
self.assertEqual(self.lanes(phases=self.snapshot()),
["40-the-site.md", "39-earlier.md"])
+ def test_a_held_run_sorts_above_a_phase_nobody_has_started(self):
+ """A person held it, so it is theirs to resume — it belongs near the
+ top, not lumped in with the phases nobody has started."""
+ self.a_phase_of_three()
+ self.write("41-the-docs.md", card("41 — Ship the docs", kind="Phase",
+ cards="- 33 — The landing page\n",
+ status="In Progress"), "in-progress")
+ self.write("39-earlier.md", card("39 — An earlier phase", kind="Phase",
+ cards="- 33 — The landing page\n",
+ status="To Do"), "to-do")
+ phases = self.snapshot()
+ phases["41-the-docs.md"] = {"file": "41-the-docs.md", "members": [],
+ "running": False, "started": True,
+ "halted": "", "haltedAt": None,
+ "haltedWhy": None, "stopped": True,
+ "stoppedBy": "held by ronald"}
+
+ self.assertEqual(self.lanes(phases=phases),
+ ["40-the-site.md", "41-the-docs.md", "39-earlier.md"],
+ "running, then the held run, then the unstarted one")
+
def test_a_finished_phase_sorts_last(self):
self.a_phase_of_three(phase_stage="done")
self.write("41-the-docs.md", card("41 — Ship the docs", kind="Phase",