aboutsummaryrefslogtreecommitdiffziptar.gz
path: root/wf.py
diff options
context:
space:
mode:
Diffstat (limited to 'wf.py')
-rwxr-xr-xwf.py20
1 files changed, 15 insertions, 5 deletions
diff --git a/wf.py b/wf.py
index 122b7db..ac4aadc 100755
--- a/wf.py
+++ b/wf.py
@@ -1597,7 +1597,7 @@ def cmd_gate(args) -> int:
# ------------------------------------------------------------------ orchestrator
GO_ON = ("done", "done+gate-red", "sliced") # outcomes after which the lane picks its next task
-PARK = ("handback", "awaiting", "post-check-red") # block only that task (park_task), the lane keeps picking
+PARK = ("handback", "awaiting", "needs-owner", "post-check-red") # block only that task (park_task), lane keeps picking
def orch_main(args) -> tuple[Path, Project]:
@@ -1783,7 +1783,8 @@ ARCHIVED = "archived, nothing to mark"
def park_task(root: Path, id: str, final: str, words: list[str]) -> str:
- """Block only this task after a handback/awaiting/post-check-red: blocked on its open a-id, else
+ """Block only this task after a handback/awaiting/needs-owner/post-check-red: needs-owner → After: its
+ open Needs-human item (status cleared); awaiting → blocked on its open a-id; else
Sessions: owner (+ status cleared on a handback) and a note. Returns what it did (alert text)."""
p = load_project(argparse.Namespace(project=str(root)), write=True)
if id not in p.doc.ids():
@@ -1792,7 +1793,16 @@ def park_task(root: Path, id: str, final: str, words: list[str]) -> str:
why = " ".join(words[1:]) or "-"
open_a = {i.id for s in p.doc.sections if s.key == "awaiting" for i in s.items}
a = next((w for w in words[1:] if w.strip("[]") in open_a), None) if final == "awaiting" else None
- if (item.status or "").startswith("blocked:"):
+ open_h = {i.id for i in p.doc.section("human").items}
+ h = next((w.strip("[]") for w in words[1:] if w.strip("[]") in open_h), None) \
+ if final == "needs-owner" else None
+ if h: # owner-only step: After: it, picked again once the owner's wf done archives it
+ if h not in item.after:
+ tasks.set_fields(p.doc, id, after=item.after + [h])
+ if item.status:
+ tasks.set_status(p.doc, id, None)
+ done = f"after {h}"
+ elif (item.status or "").startswith("blocked:"):
done = f"already {item.status}"
elif a:
tasks.set_status(p.doc, id, f"blocked: [[{a.strip('[]')}]]")
@@ -1806,7 +1816,7 @@ def park_task(root: Path, id: str, final: str, words: list[str]) -> str:
tasks.add_note(p.doc, id, f"orch {datetime.date.today().isoformat()}: {final} ({why}) → {done}; "
"lane kept picking, owner decides")
p.save(False)
- if done.endswith("status cleared"):
+ if done.endswith("status cleared") or h:
unclaim(p.cfg, [id])
return done
@@ -2346,7 +2356,7 @@ def parser() -> argparse.ArgumentParser:
op.add_argument("--recovery", metavar="WHY", help="prompt gets 'Recovery: WHY' (crashed worker, one retry)")
op = osub.add_parser("post", help="after the worker's report: post-check (done: archive line, branch gone, "
"worktree clean and in master, else wf merge; wf check), leftover commit otherwise, "
- "out/wf-orch.log line, out/wf-cost.log line (--agent); awaiting/handback/post-check-red park only the task (blocked / Sessions: owner + note, 'alert:' line); then the next pick or 'stop lane'")
+ "out/wf-orch.log line, out/wf-cost.log line (--agent); awaiting/needs-owner/handback/post-check-red park only the task (blocked / After: h-task / Sessions: owner + note, 'alert:' line); then the next pick or 'stop lane'")
op.add_argument("id")
op.add_argument("lane")
op.add_argument("--result", metavar="LINE", help="the report's result line (default: done if archived, else no-report)")