From 0ce99f01dd4e34a66451aebd354c2b9810cf1304 Mon Sep 17 00:00:00 2001 From: rsnetworkinginc Date: Fri, 24 Jul 2026 20:32:25 +0300 Subject: [PATCH] fix(fugu): accept a bare-int access index in the workflow parser (#225) The workflow parse-gate normalizes each step access entry via _normalize_access, which handled the string form ("0"), the list form ([0]) and "all"/empty shorthands, but a bare integer (0) fell through every branch and returned None, rejecting the whole workflow. A bare int is the natural shorthand for a single prior-step index, so the Conductor emitting access_list=["none", 0, 1] had its otherwise-valid workflow scored as a parse failure (r=0). Accept a bare int as a single index, validating 0 <= j < step_index (forward references still reject) and excluding bool. Adds a RED->GREEN regression test. --- src/trinity/fugu/workflow.py | 11 ++++++++--- tests/test_fugu_workflow.py | 17 +++++++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/trinity/fugu/workflow.py b/src/trinity/fugu/workflow.py index 6c2cd75..201edd3 100644 --- a/src/trinity/fugu/workflow.py +++ b/src/trinity/fugu/workflow.py @@ -192,9 +192,10 @@ def _list_candidates(text: str, names: tuple[str, ...]) -> list[tuple[int, list] def _normalize_access(acc: object, step_index: int) -> object | None: """Validate/normalize one access entry. Returns ``None`` if invalid. - Valid forms: ``"all"``, ``[]``/``None`` (query only), or a list of integer - indices that strictly precede ``step_index`` (a forward reference is an - invalid DAG and rejects the whole workflow). + Valid forms: ``"all"``, ``[]``/``None`` (query only), a bare integer index, + or a list of integer indices, each of which must strictly precede + ``step_index`` (a forward reference is an invalid DAG and rejects the whole + workflow). """ if acc is None: return [] @@ -208,6 +209,10 @@ def _normalize_access(acc: object, step_index: int) -> object | None: j = int(s) return [j] if j < step_index else None return None + if isinstance(acc, bool): + return None + if isinstance(acc, int): + return [acc] if 0 <= acc < step_index else None if isinstance(acc, (list, tuple)): if len(acc) == 1 and isinstance(acc[0], str) and acc[0].strip().lower() == "all": return "all" diff --git a/tests/test_fugu_workflow.py b/tests/test_fugu_workflow.py index 2d50f21..048c2a4 100644 --- a/tests/test_fugu_workflow.py +++ b/tests/test_fugu_workflow.py @@ -101,6 +101,23 @@ def test_parse_normalizes_common_access_shorthands(): assert [s.access for s in wf.steps] == [[], [0], [1]] +def test_parse_accepts_bare_int_access_index(): + # A bare integer access entry (0) is the natural shorthand for [0] and must + # be accepted just like the string "0" and the list [0] already are. + txt = """ +model_id = [0, 1, 2] +subtasks = ["solve", "check", "answer"] +access_list = ["none", 0, 1] +""" + wf, ok = parse_workflow(txt, n_workers=3) + assert ok and wf is not None + assert [s.access for s in wf.steps] == [[], [0], [1]] + + # A bare-int forward reference is still an invalid DAG. + fwd = "model_id=[0,1]\nsubtasks=['a','b']\naccess_list=[0, 1]" + assert parse_workflow(fwd, 3)[1] is False + + def test_parse_gate_rejects_bad_workflows(): # missing a list assert parse_workflow("model_id=[0]\nsubtasks=['x']", 3)[1] is False