@@ -272,6 +272,68 @@ def test_headless_concurrent_panes():
272272 _wait_until (lambda : backend .list_panes () == [])
273273
274274
275+ # ── Parallel cases with sequential internal workflow ─────────────────────────
276+
277+
278+ def test_parallel_cases_with_sequential_steps (tmp_path ):
279+ """Verify openMax decomposes 'N parallel cases, each with sequential steps' correctly.
280+
281+ This models a render pipeline:
282+ Case 1: check → parse → render (sequential)
283+ Case 2: check → parse → render (sequential)
284+ Case 3: check → parse → render (sequential)
285+ All three cases run in parallel; steps within each case are sequential.
286+
287+ The lead agent should produce a plan with dependencies like:
288+ case1-check (no deps) → case1-parse (dep: case1-check) → case1-render (dep: case1-parse)
289+ case2-check (no deps) → case2-parse (dep: case2-check) → ...
290+ case3-check (no deps) → case3-parse (dep: case3-check) → ...
291+ With parallel_groups containing all check tasks.
292+ """
293+ marker = str (tmp_path / "done.marker" )
294+ pane_mgr = PaneManager (backend = HeadlessPaneBackend ())
295+
296+ task = (
297+ "Process 3 independent code samples in parallel. "
298+ "For EACH sample, execute these steps IN ORDER (sequential within each case):\n "
299+ " Step 1: Renderability check — verify the code is runnable\n "
300+ " Step 2: Parse the code into a structured format\n "
301+ " Step 3: Render the final output\n \n "
302+ "The 3 samples are completely independent — run all 3 cases in parallel, "
303+ "but within each case, step 1 must finish before step 2, "
304+ "and step 2 must finish before step 3.\n \n "
305+ "Use task-agent for all steps. Report results when all 3 cases complete."
306+ )
307+
308+ result = run_lead_agent (
309+ task = task ,
310+ pane_mgr = pane_mgr ,
311+ cwd = str (tmp_path ),
312+ allowed_agents = ["task-agent" ],
313+ agent_registry = _make_registry (marker ),
314+ max_turns = 40 ,
315+ plan_confirm = False ,
316+ )
317+
318+ # Verify: at least 3 subtasks were created (one per case minimum)
319+ assert len (result .subtasks ) >= 3 , (
320+ f"Expected ≥3 subtasks for 3 cases; got { len (result .subtasks )} : "
321+ f"{ [st .name for st in result .subtasks ]} "
322+ )
323+
324+ # Verify: at least some subtasks have dependencies (sequential chaining)
325+ deps_present = any (st .dependencies for st in result .subtasks )
326+ assert deps_present , (
327+ "Expected sequential dependencies within cases, but no subtask has dependencies: "
328+ f"{ [(st .name , st .dependencies ) for st in result .subtasks ]} "
329+ )
330+
331+ # Verify: at least 1 subtask completed
332+ done = sum (1 for t in result .subtasks if t .status .value == "done" )
333+ statuses = [f"{ st .name } :{ st .status .value } " for st in result .subtasks ]
334+ assert done >= 1 , f"Expected ≥1 done subtask; got: { statuses } "
335+
336+
275337# ── Error propagation ────────────────────────────────────────────────────────
276338
277339
0 commit comments