From 94e3fd8358bbdb5d6ed81aed475fab7fc73e2097 Mon Sep 17 00:00:00 2001 From: t Date: Tue, 18 Aug 2026 16:37:31 -0600 Subject: Fix workflow progress pin lifecycle --- spec/test_init.lua | 27 +++++++++++++++++++++++---- spec/test_progress.lua | 26 ++++++++++++++++++++++++++ spec/test_progress_replay.lua | 1 + 3 files changed, 50 insertions(+), 4 deletions(-) (limited to 'spec') diff --git a/spec/test_init.lua b/spec/test_init.lua index 2d5e7d1..97f0eba 100644 --- a/spec/test_init.lua +++ b/spec/test_init.lua @@ -175,9 +175,24 @@ return { "the result restores the component's transcript position") local claimed, pins = nil, {} + handle.emit("tool_call_complete", { + id = "replayed-call", + tool_name = "subagents.workflow", + set_component = function(_, component) + claimed = component + return { + invalidate = function() end, + alive = function() return true end, + set_pinned = function(_, value) pins[#pins + 1] = value end, + } + end, + }) + assert(#pins == 0, "a workflow restored during startup stays in transcript order") + + handle.emit("turn_start", {}) handle.emit("tool_call_complete", { id = "call-1", - tool_name = "subagents.run", + tool_name = "subagents.workflow", set_component = function(_, component) claimed = component return { @@ -189,9 +204,13 @@ return { }) assert(type(claimed) == "table" and type(claimed.render) == "function", "the entry is given a component that renders the cards") - assert(pins[1] == true, "the progress component pins after claim") - handle.emit("tool_result", { id = "call-1", tool_name = "subagents.run" }) - assert(pins[2] == false, "the matching result unpins it") + assert(pins[1] == true, "the live progress component pins after claim") + local output = handle.tools_by_name["subagents.workflow"].handler( + { prompt = "", steps = {} }, { tool_call_id = "call-1" }) + assert(type(output) == "string", "the workflow handler returned its result") + assert(pins[2] == false, "handler completion unpins before the next model action") + handle.emit("tool_result", { id = "call-1", tool_name = "subagents.workflow" }) + assert(#pins == 2, "the later host result is an inert fallback") local foreign handle.emit("tool_call_complete", { diff --git a/spec/test_progress.lua b/spec/test_progress.lua index 06509bf..5788998 100644 --- a/spec/test_progress.lua +++ b/spec/test_progress.lua @@ -20,6 +20,32 @@ local function plain(lines) end return { + { "startup replay stays in transcript order while live calls pin", function() + progress.reset() + progress.begin_replay() + local pins = {} + local function claim(id) + progress.claim({ + id = id, + tool_name = "subagents.workflow", + set_component = function() + return { + alive = function() return true end, + invalidate = function() end, + set_pinned = function(_, value) pins[#pins + 1] = value end, + } + end, + }) + end + claim("historical") + assert(#pins == 0, "replayed workflows must never pin") + progress.begin_live_turn() + claim("live") + assert(pins[1] == true, "a live workflow pins while it runs") + progress.reset() + assert(pins[2] == false, "reset releases the live workflow") + end }, + { "concurrent boards pin independently until their matching result", function() progress.reset() local pins = { a = {}, b = {} } diff --git a/spec/test_progress_replay.lua b/spec/test_progress_replay.lua index aba8e33..cf2925e 100644 --- a/spec/test_progress_replay.lua +++ b/spec/test_progress_replay.lua @@ -62,6 +62,7 @@ end local function with_host(fn, opts) local handle = fake.install(opts) + progress.begin_replay() local ok, err = pcall(fn, handle) progress.reset() handle.restore() -- cgit v1.3