浏览代码

r5: harness split (arch 18) — the monolith becomes a package. test/harness.py: the FakeSaddle daemon, every shared wire helper (http/act/login/slot_public/wait_for/quiet_window/db/check, task_state/wait_task_done/create_queued/enqueue_task/saddle_api/saddle_card/http_get_page/dump_threads and friends), the per-shard fixtures (Ctx/start_bundle), and the runner (run_bundle + run_all_parallel + main) — the parallel spawn now targets the entry shim so 'harness' stays one module instance per process, and run_bundle imports the bundle module lazily (after that shard's environment exists, so star-imported runtime globals are the shard's own) then re-syncs WORK/DB_PATH/ports onto it (the sequential debug path reuses modules across shards). test/bundles/<name>.py ×11: the scenario bodies moved verbatim (bundle_X -> run(ctx)); the x7 duplicated goal_state closures collapse onto harness.goal_state, late-bound through the runner's fixture ctx so the answers/replay restart scenarios' re-logins keep working (the first cut snapped the auth at shard start and the replay redelivery scenario caught it). test/web_stack_test.py stays the meson entry (args unchanged) and the shard spawn target. The S-workstream handoff survivors verified byte-intact after the move: the goalui S2 verdict-goal pins (resolveReviewBlock/goal.open_blocks/feedback posting/extraText gating on the goal page) and the goals S3 park-second waits (strictly-newer completed_at vs suspended_at seconds under SADDLE_GOAL_RESUME_S=1). Both execution modes green: parallel shards 851/0, WEBSTACK_SEQUENTIAL 851/0. 851 checks.

clanker 1 月之前
父节点
当前提交
2d0e09d1d9

+ 7 - 6
meson.build

@@ -216,12 +216,13 @@ clanker_saddle_exe = executable('clanker-saddle',
 )
 
 # =============================================================================
-# Tests: test/web_stack_test.py is self-contained (spawns the app binary
-# in a scratch dir plus an in-process fake saddle daemon) and asserts the
-# web-stack wire contract features. The built binary is passed as its
-# first argument. The script shards the scenario groups into seven
-# parallel bundle processes (isolated app/daemon/DB each) and aggregates
-# their verdicts into this single test's result.
+# Tests: the web-stack suite is a package (plan 16 R5, arch 18) —
+# test/web_stack_test.py is the entry shim meson invokes; the shared
+# machinery (fake saddle daemon, wire helpers, fixtures, the parallel
+# runner) lives in test/harness.py and one module per scenario bundle
+# in test/bundles/. Each bundle runs as its own shard process (own app,
+# daemons and SQLite scratch) and the runner aggregates the verdicts
+# into this single test's result.
 # =============================================================================
 python_test = import('python').find_installation('python3')
 test('web-stack', python_test,

+ 25 - 0
test/bundles/__init__.py

@@ -0,0 +1,25 @@
+"""The bundle map (plan 16 R5, arch 18): one module per shard, imported
+by harness.run_bundle lazily (after that shard's environment exists, so
+the modules' star-imported runtime globals are the shard's own). The
+order here is the parallel runner's shard order."""
+
+from . import (allocation, answers, dispatch, goalui, goals, lineage,
+               lifecycle, pages, push, replay, subtasks)
+
+BUNDLES = {
+    "pages": pages,
+    "dispatch": dispatch,
+    "subtasks": subtasks,
+    "lineage": lineage,
+    "allocation": allocation,
+    "lifecycle": lifecycle,
+    "answers": answers,
+    "push": push,
+    "goals": goals,
+    "replay": replay,
+    "goalui": goalui,
+}
+
+BUNDLES_ORDER = ("pages", "dispatch", "subtasks", "lineage",
+                 "allocation", "lifecycle", "answers", "push", "goals",
+                 "replay", "goalui")

+ 644 - 0
test/bundles/allocation.py

@@ -0,0 +1,644 @@
+"""The allocation bundle (moved verbatim from the pre-split web_stack_test.py;
+see test/harness.py for the shared machinery and the runner)."""
+from harness import *  # noqa: F401,F403 — the shared wire helpers
+
+
+# =============================================================================
+# Bundle: allocation — the ask/wake/allocate machinery: concurrent ask
+# race, token revocation, workspace affinity, the lost-wake guard, the
+# slow-ask regression, assignment capability context + the tag
+# catalogue, and the pinned-blocks/activity dashboard.
+# =============================================================================
+
+def run(ctx):
+    auth, fake, fake_id, fake_token = ctx.auth, ctx.fake, ctx.fake_id, ctx.fake_token
+    app = ctx.app
+    r4_token = fake_token
+    # gpu rides the primary fake from the start (the routing bundle's
+    # early attach, replayed): its attach row precedes lostwake's, so
+    # the assignment's saddle_tags order matches the assertion in the
+    # capability-context section below.
+    saddles_state = slot_public(auth, "/saddles", "saddles")
+    act(auth, saddles_state["create_capability"], {"name": "gpu"})
+    act(auth, saddle_card(auth, "fake-saddle")["attach_capability"],
+        {"capability_id": str(int([c["id"] for c in
+                                   slot_public(auth, "/saddles", "saddles")["capabilities"]
+                                   if c["name"] == "gpu"][0]))})
+
+    print("== phase 1: ask/allocation — token auth + concurrent race ==")
+    # Plan 10 phase 1. Registration mints per-saddle tokens; the
+    # ask endpoint authenticates by them; concurrent asks race to
+    # exactly one winner through the allocation transaction.
+    status, _ = saddle_api("POST", "/api/saddle/next-task", None)
+    check(status == 401, "next-task rejects a missing token")
+    status, _ = saddle_api("POST", "/api/saddle/next-task", "saddle-bogus-token")
+    check(status == 401, "next-task rejects a wrong token")
+    status, body = saddle_api("POST", "/api/saddle/next-task", fake_token)
+    check(status == 204, "next-task answers 204 (nothing offerable — daemon sleeps)")
+
+    # Two more racers: real daemons on their own ports; fake2 reports
+    # its ssh key at /register so the key lands on the row directly.
+    fake2 = FakeSaddle()
+    fake2.ssh_public_key = "ssh-ed25519 AAAAFake2RacerKey saddle-2@fedora"
+    fake2.serve(port=free_port())
+    fake3 = FakeSaddle()
+    fake3.serve(port=free_port())
+    saddles_state = slot_public(auth, "/saddles", "saddles")
+    act(auth, saddles_state["register"], {"name": "racer-two",
+                                          "host": "127.0.0.1:%d" % fake2.port})
+    act(auth, saddles_state["register"], {"name": "racer-three",
+                                          "host": "127.0.0.1:%d" % fake3.port})
+    check(wait_for(lambda: len(fake2.register_log) > 0 and len(fake3.register_log) > 0
+                   or False, timeout=15, what="racers registered") is not None,
+          "both racers received /register")
+    check(wait_for(lambda: "AAAAFake2RacerKey" in
+                   [s for s in slot_public(auth, "/saddles", "saddles")["saddles"]
+                    if s["name"] == "racer-two"][0].get("ssh_public_key", "") or False,
+                   timeout=15, what="register-reported key") is not None,
+          "the ssh key reported at /register lands on the saddle row")
+
+    racer_cards = {}
+    for name, daemon in (("fake-saddle", fake), ("racer-two", fake2), ("racer-three", fake3)):
+        card = [s for s in slot_public(auth, "/saddles", "saddles")["saddles"]
+                if s["name"] == name][0]
+        racer_cards[daemon] = {"id": int(card["id"]), "token": card["token"]}
+    # Revocation: a registered saddle's token works until the saddle
+    # is removed, then nothing authorises its calls.
+    fake4 = FakeSaddle()
+    fake4.ask_on_register = False  # a pre-flip daemon: never asks
+    fake4.serve(port=free_port())
+    saddles_state = slot_public(auth, "/saddles", "saddles")
+    act(auth, saddles_state["register"], {"name": "old-daemon",
+                                          "host": "127.0.0.1:%d" % fake4.port})
+    old_card = [s for s in slot_public(auth, "/saddles", "saddles")["saddles"]
+                if s["name"] == "old-daemon"][0]
+    status, _ = saddle_api("POST", "/api/saddle/next-task", old_card["token"])
+    check(status in (200, 204),
+          "the old daemon's fresh token authenticates next-task")
+    status, _ = saddle_api("POST", "/api/saddle/note", old_card["token"],
+                           {"project": "demo", "body": "from the old daemon"})
+    check(status == 200, "note accepts any registered saddle's token")
+    act(auth, old_card["unregister"], {})
+    status, _ = saddle_api("POST", "/api/saddle/next-task", old_card["token"])
+    check(status == 401, "removing the saddle revokes its token")
+    status, _ = saddle_api("POST", "/api/saddle/note", old_card["token"],
+                           {"project": "demo", "body": "should fail"})
+    check(status == 401, "revocation covers the note endpoint too")
+
+    # Deterministic race: settle the queue first (this shard runs the
+    # race before any parked work exists, so only in-flight asks need
+    # draining), freeze every daemon's self-ask triggers, put all three
+    # to sleep (204), then fire one task worth of concurrent asks.
+    for daemon in (fake, fake2, fake3):
+        daemon.ask_on_register = False
+        daemon.ask_on_wake = False
+        daemon.ask_on_terminal = False
+        daemon.ask_on_idle_status = False
+        daemon.settle_asks()  # converted sleep: in-flight asks land (204)
+    def queued_count():
+        conn = db()
+        try:
+            return conn.execute(
+                "select count(*) from tasks where status = 'queued'").fetchone()[0]
+        finally:
+            conn.close()
+
+    check(wait_for(lambda: queued_count() == 0 or False,
+                   timeout=60, what="queue settles before the race") is not None,
+          "the queue settles before the race")
+
+    sleep_statuses = [daemon.ask_now()[0] for daemon in (fake, fake2, fake3)]
+    check(sleep_statuses == [204, 204, 204],
+          "all three racers sleep (204) before the task exists")
+
+    task_id_tmp = create_queued(auth, {
+        "project_id": "1",
+        "title": "Race task",
+        "priority": "2",
+    })
+    race_task = task_id_tmp
+
+    race_results = []
+    def race_ask(daemon):
+        # A real racing daemon accepts the assignment it wins — the
+        # manual ask path does exactly that on a 200.
+        race_results.append(daemon.ask_now())
+    threads = [threading.Thread(target=race_ask, args=(daemon,))
+               for daemon in (fake, fake2, fake3)]
+    for thread in threads:
+        thread.start()
+    for thread in threads:
+        thread.join()
+    race_statuses = sorted(r[0] for r in race_results)
+    check(race_statuses == [200, 204, 204],
+          "concurrent asks race to exactly one winner (%s)" % race_statuses)
+    winner = [r for r in race_results if r[0] == 200][0][1]
+    check(int(winner["task"]["id"]) == race_task, "the winner's payload carries the task")
+    check(int(winner["session_id"]) > 0, "the assignment carries the session id")
+    conn = db()
+    race_sessions = conn.execute(
+        "select count(*) from sessions where task_id = ?", (race_task,)).fetchone()[0]
+    conn.close()
+    check(race_sessions == 1,
+          "exactly one session row — the transaction serialised the claims (%d)"
+          % race_sessions)
+    check(wait_task_done(auth, race_task, timeout=60) is not None,
+          "the raced task completes on the winning daemon")
+    for daemon in (fake, fake2, fake3):
+        daemon.ask_on_register = True
+        daemon.ask_on_wake = True
+        daemon.ask_on_terminal = True
+        daemon.ask_on_idle_status = True
+    # Re-establish sleeping explicitly: the winner's post-race
+    # re-ask timing is not deterministic, and the affinity section
+    # below needs every racer provably asleep. Any stray offerable
+    # drains into these asks first.
+    def all_asleep():
+        return all(daemon.ask_now()[0] == 204 for daemon in (fake, fake2, fake3))
+    check(wait_for(lambda: all_asleep() or False, timeout=30,
+                   what="racers re-sleep after the race") is not None,
+          "all racers re-sleep after the race")
+
+    print("== phase 1: workspace affinity pins parked tasks ==")
+    # A suspended parent parked on racer-two may be resumed ONLY by
+    # racer-two: a tag-capable non-affine saddle asking gets 204, and
+    # the wake targets the affine saddle. Only racer-two carries the
+    # tag at dispatch time (the race's winner is nondeterministic, so
+    # the park must not depend on which racers are free); racer-three
+    # gains it afterwards to prove the pinning is by workspace, not
+    # tags.
+    saddles_state = slot_public(auth, "/saddles", "saddles")
+    act(auth, saddles_state["create_capability"], {"name": "affinity-tag"})
+    affinity_cap = int([c["id"] for c in slot_public(auth, "/saddles", "saddles")["capabilities"]
+                        if c["name"] == "affinity-tag"][0])
+    racer2_card = [s for s in slot_public(auth, "/saddles", "saddles")["saddles"]
+                   if s["name"] == "racer-two"][0]
+    racer3_card = [s for s in slot_public(auth, "/saddles", "saddles")["saddles"]
+                   if s["name"] == "racer-three"][0]
+    act(auth, racer2_card["attach_capability"], {"capability_id": str(affinity_cap)})
+
+    # Plan 12: the parked workspace is the goal agent's run task. The
+    # other racers sleep (frozen ask triggers), so racer-two claims
+    # the goal run and parks it; the goal-task event then resumes the
+    # agent AFFINE to racer-two — racer-three (tag-capable or not)
+    # gets 204, the dispatcher's wake targets racer-two.
+    fake.ask_on_wake = False
+    fake.ask_on_idle_status = False
+    fake.settle_asks()
+    fake3.ask_on_wake = False
+    fake3.ask_on_idle_status = False
+    fake3.settle_asks()
+
+    act(auth, slot_public(auth, "/goals", "goals")["create"], {
+        "project_id": "1", "title": "Affinity goal",
+        "brief": "Parks on racer-two.", "branch_name": "goal/affinity"})
+    conn = db()
+    affinity_goal = conn.execute(
+        "select id from goals where title = 'Affinity goal'").fetchone()[0]
+    conn.close()
+    fake2.goal_script = [("plan", "# Affinity plan\n\n1. Park")]
+    act(auth, slot_public(auth, "/goals/%d" % affinity_goal, "goal")["start"], {})
+    check(wait_for(lambda: slot_public(auth, "/goals/%d" % affinity_goal,
+                                       "goal")["status"] == "plan_review" or False,
+                   timeout=60, what="affinity goal plans") is not None,
+          "the affinity goal reaches plan review (racer-two hosting)")
+    fake2.goal_script = [("suspend",)]
+    # Freeze racer-two's ask triggers across the approval too (the
+    # later wake measurement already does): the mirror-sync fix makes
+    # the run resume-offerable the moment its goal row carries the
+    # verdict, so a wake-triggered background ask would race this
+    # manual ask_now for the claim.
+    fake2.ask_on_wake = False
+    fake2.ask_on_idle_status = False
+    fake2.settle_asks()
+    act(auth, slot_public(auth, "/goals/%d" % affinity_goal, "goal")
+        ["plan_pending_block"]["answer_action"],
+        {"answer": "Plan approved. Proceed with implementation."})
+    conn = db()
+    affinity_parent = conn.execute(
+        "select id from tasks where goal_id = ? and kind = 'goal_run'",
+        (affinity_goal,)).fetchone()[0]
+    agent_session = conn.execute(
+        "select id from sessions where task_id = ? and ended_at is null",
+        (affinity_parent,)).fetchone()[0]
+    conn.close()
+    status, resume_payload = fake2.ask_now()
+    check(status == 200 and int(resume_payload["task"]["id"]) == affinity_parent,
+          "the approved plan resumes the agent on racer-two (its workspace)")
+    check(wait_for(lambda: task_state(auth, affinity_parent).get("status") == "suspended"
+                   or False, timeout=60, what="affinity agent parks") is not None,
+          "the affinity goal agent parks on racer-two")
+    conn = db()
+    affinity_session = conn.execute(
+        "select saddle_id from sessions where task_id = ? and ended_at is null",
+        (affinity_parent,)).fetchone()[0]
+    conn.close()
+    check(affinity_session == int(racer2_card["id"]),
+          "the parked workspace sits on racer-two")
+
+    # Now racer-three carries the tag too — the pinning is by
+    # workspace, not tags. With nothing due, a non-affine ask gets 204.
+    act(auth, racer3_card["attach_capability"], {"capability_id": str(affinity_cap)})
+    status, _ = fake3.ask_now()
+    check(status == 204,
+          "a tag-capable non-affine saddle is refused the parked agent (204)")
+
+    # A goal task completing makes the parked agent resume-offerable —
+    # affine to racer-two only. The other racers wake back up (they
+    # host the worker; their claims of the parked agent get refused as
+    # non-affine), while racer-two's ask triggers stay frozen so the
+    # wake measurement stays clean. A wake may have hit the frozen
+    # racers while the goal run queued (the lost-wake guard marks them
+    # offline): the refresh probe brings them back before the worker.
+    fake.ask_on_wake = True
+    fake.ask_on_idle_status = True
+    fake3.ask_on_wake = True
+    fake3.ask_on_idle_status = True
+    for racer_name in ("fake-saddle", "racer-three"):
+        act(auth, saddle_card(auth, racer_name)["refresh"], {})
+        check(wait_for(lambda name=racer_name: [s for s in
+                                                slot_public(auth, "/saddles", "saddles")["saddles"]
+                                                if s["name"] == name][0]["status"] == "idle"
+                       or False, timeout=15, what="racer re-onlined") is not None,
+              "%s re-onlined after its frozen-window wake" % racer_name)
+    fake2.ask_on_wake = False
+    fake2.ask_on_idle_status = False
+    wakes_before_2 = len(fake2.wake_log)
+    fake2.settle_asks()  # converted sleep: park-time ask lands (204)
+    status, body = saddle_api("POST", "/api/saddle/task/create", fake2.token, {
+        "session_id": agent_session, "title": "Affinity child",
+        "mandate": "finish the affinity fixture"})
+    check(status == 200, "the parked agent fans its worker out via the CLI")
+    affinity_child = int(body["task_id"])
+    saddle_api("POST", "/api/saddle/task/enqueue", fake2.token,
+               {"session_id": agent_session, "task_id": affinity_child})
+    check(wait_task_done(auth, affinity_child, timeout=90) is not None,
+          "the affinity worker completes (on a non-affine racer)")
+
+    check(wait_for(lambda: len(fake2.wake_log) > wakes_before_2 or False,
+                   timeout=90, what="affine wake") is not None,
+          "the dispatcher's wake targets the affine saddle")
+    status, resume_payload = fake2.ask_now()
+    fake2.ask_on_wake = True       # restored whatever the claim returned
+    fake2.ask_on_idle_status = True
+    check(status == 200 and int(resume_payload["task"]["id"]) == affinity_parent,
+          "the affine saddle's ask claims the parked agent")
+    check("Affinity child" in (resume_payload.get("resume_notice") or "")
+          and "fake daemon finished" in (resume_payload.get("resume_notice") or ""),
+          "the resume assignment carries the goal's batched report notice")
+    check(wait_for(lambda: task_state(auth, affinity_parent).get("status")
+                   == "suspended" or False,
+                   timeout=60, what="affinity agent re-parks") is not None,
+          "the resumed agent re-parks (script)")
+    act(auth, slot_public(auth, "/goals/%d" % affinity_goal, "goal")["cancel"], {})
+    check(wait_for(lambda: slot_public(auth, "/goals/%d" % affinity_goal,
+                                       "goal")["status"] == "cancelled" or False,
+                   timeout=30, what="affinity goal cancelled") is not None,
+          "the affinity goal cancels (drain)")
+
+    print("== phase 1: lost wake -> offline + re-wake of the next capable ==")
+    # racer-three sleeps through wakes (a daemon that died after its
+    # last 204): the guard window (SADDLE_LOST_WAKE_S=2) passes with
+    # no ask, the saddle goes offline, and the work moves to the
+    # next capable sleeping saddle.
+    fake3.ask_on_wake = False
+    fake3.ask_on_idle_status = False  # sleeps through everything
+    saddles_state = slot_public(auth, "/saddles", "saddles")
+    act(auth, saddles_state["create_capability"], {"name": "lostwake"})
+    lostwake_cap = int([c["id"] for c in slot_public(auth, "/saddles", "saddles")["capabilities"]
+                        if c["name"] == "lostwake"][0])
+    racer3_card = [s for s in slot_public(auth, "/saddles", "saddles")["saddles"]
+                   if s["name"] == "racer-three"][0]
+    act(auth, racer3_card["attach_capability"], {"capability_id": str(lostwake_cap)})
+    # Racer-three must be asleep to be woken: park it with a manual
+    # 204 ask (nothing offerable for it — the task below is not
+    # created yet).
+    status, _ = fake3.ask_now()
+    check(status == 204, "racer-three sleeps before the lost-wake run")
+
+    task_id_tmp = create_queued(auth, {
+        "project_id": "1",
+        "title": "Lost wake task",
+        "priority": "2",
+        "capability_id": [str(lostwake_cap)],
+    })
+    lost_task = task_id_tmp
+    check(wait_for(lambda: len(fake3.wake_log) > 0 or False,
+                   timeout=30, what="wake sent to racer-three") is not None,
+          "the only capable sleeping saddle is woken")
+    check(wait_for(lambda: [s for s in slot_public(auth, "/saddles", "saddles")["saddles"]
+                            if s["name"] == "racer-three"][0]["status"] == "offline"
+                   or False, timeout=30, what="lost-wake -> offline") is not None,
+          "no ask after the wake: the saddle goes offline (lost-wake guard)")
+    check(task_state(auth, lost_task)["status"] == "queued",
+          "the task is untouched while its wake was pending")
+
+    # Re-wake the next capable: the healthy saddle gains the tag and
+    # picks the work up via its own wake -> ask -> allocate roundtrip.
+    fake_card = saddle_card(auth, "fake-saddle")
+    act(auth, fake_card["attach_capability"], {"capability_id": str(lostwake_cap)})
+    wakes_before = len(fake.wake_log)
+    check(wait_for(lambda: len(fake.wake_log) > wakes_before or False,
+                   timeout=30, what="re-wake of the next capable") is not None,
+          "the next capable sleeping saddle is woken for the task")
+    check(wait_task_done(auth, lost_task, timeout=60) is not None,
+          "wake -> ask -> allocate: the task completes on the healthy saddle")
+    check(wait_for(lambda: any(int(p.get("task", {}).get("id") or 0) == lost_task
+                               for p in fake.start_payloads) or False,
+                   timeout=10, what="lost task assignment captured") is not None,
+          "the re-woken saddle's ask produced the assignment")
+    fake3.ask_on_wake = True
+    fake3.ask_on_idle_status = True
+
+    print("== phase 3: capability context, catalogue, subtask tags ==")
+    # Assignment capability context (plan 10 phase 3): every
+    # assignment carries {saddle_tags: the allocated saddle's tags,
+    # fleet_tags: every tag name known across the fleet} — the
+    # daemon renders it into its system prompt. fake-saddle carries
+    # gpu + lostwake; the catalogue is affinity-tag, gpu, lostwake.
+    fake2.ask_on_register = False
+    fake2.ask_on_wake = False
+    fake2.ask_on_terminal = False
+    fake2.ask_on_idle_status = False
+    fake2.settle_asks()  # converted sleep: in-flight trigger asks land
+    task_id_tmp = create_queued(auth, {
+        "project_id": "1",
+        "title": "Capabilities context",
+        "priority": "2",
+    })
+    cap_task = task_id_tmp
+    check(wait_for(lambda: any(int(p.get("task", {}).get("id") or 0) == cap_task
+                               for p in fake.start_payloads) or False,
+                   timeout=60, what="capabilities-context task dispatched") is not None,
+          "the capabilities-context task dispatches")
+    cap_payload = [p for p in fake.start_payloads
+                   if int(p.get("task", {}).get("id") or 0) == cap_task][-1]
+    context = cap_payload.get("capabilities") or {}
+    check(context.get("saddle_tags") == ["gpu", "lostwake"],
+          "assignment saddle_tags = the allocated saddle's tags (%s)"
+          % context.get("saddle_tags"))
+    check(context.get("fleet_tags") == ["affinity-tag", "gpu", "lostwake"],
+          "assignment fleet_tags = every tag name known across the fleet (%s)"
+          % context.get("fleet_tags"))
+    check(wait_task_done(auth, cap_task, timeout=60) is not None,
+          "capabilities-context task completes")
+
+    # GET /api/saddle/capabilities feeds the daemon's `saddle
+    # capabilities` CLI: per-saddle-token auth, tag order by name,
+    # each tag with the saddles carrying it (name order).
+    status, _ = saddle_api("GET", "/api/saddle/capabilities", None)
+    check(status == 401, "capabilities endpoint rejects a missing token")
+    status, body = saddle_api("GET", "/api/saddle/capabilities", "saddle-bogus")
+    check(status == 401, "capabilities endpoint rejects a wrong token")
+    status, body = saddle_api("GET", "/api/saddle/capabilities", fake_token)
+    catalogue = {t["name"]: t["saddles"] for t in body.get("tags", [])}
+    check(status == 200 and body.get("ok") is True
+          and [t["name"] for t in body.get("tags", [])]
+          == ["affinity-tag", "gpu", "lostwake"],
+          "catalogue lists every tag by name")
+    check(catalogue.get("gpu") == ["fake-saddle"]
+          and catalogue.get("affinity-tag") == ["racer-three", "racer-two"]
+          and catalogue.get("lostwake") == ["fake-saddle", "racer-three"],
+          "each tag names its carrying saddles in name order (%s)" % catalogue)
+
+    # Task CLI capabilities (`task create --capability`): validated
+    # against the operator tag set; unknown tags reject with the valid
+    # list in the error (the agent reads it verbatim in the CLI
+    # output). A goal agent's parked session hosts the calls.
+    fake.suspend_on_title = "Tag host"
+    tag_host = create_queued(auth, {
+        "project_id": "1", "title": "Tag host", "priority": "3"})
+    check(wait_for(lambda: task_state(auth, tag_host)["status"] == "suspended"
+                   or False, timeout=60, what="tag host parks") is not None,
+          "a parked plain task hosts nothing (no goal scope)")
+    # The goal callbacks need a real goal agent: reuse the sequencing
+    # goal pattern — a fresh parked agent under this shard.
+    act(auth, slot_public(auth, "/goals", "goals")["create"], {
+        "project_id": "1", "title": "Tag goal", "brief": "b",
+        "branch_name": "goal/tags"})
+    conn = db()
+    tag_goal = conn.execute("select id from goals where title = 'Tag goal'").fetchone()[0]
+    conn.close()
+    fake.goal_script = [("suspend",)]
+    act(auth, slot_public(auth, "/goals/%d" % tag_goal, "goal")["start"], {})
+    conn = db()
+    tag_run = conn.execute(
+        "select id from tasks where goal_id = ? and kind = 'goal_run'",
+        (tag_goal,)).fetchone()[0]
+    conn.close()
+    check(wait_for(lambda: task_state(auth, tag_run)["status"] == "suspended"
+                   or False, timeout=60, what="tag goal agent parks") is not None,
+          "the tag goal agent parks")
+    conn = db()
+    tag_session = conn.execute(
+        "select id from sessions where task_id = ? and ended_at is null",
+        (tag_run,)).fetchone()[0]
+    conn.close()
+    conn = db()
+    tag_host_saddle = conn.execute(
+        "select saddle_id from sessions where id = ?", (tag_session,)).fetchone()[0]
+    conn.close()
+    racer2_card_id = int([c for c in slot_public(auth, "/saddles", "saddles")["saddles"]
+                          if c["name"] == "racer-two"][0]["id"])
+    racer3_card_id = int([c for c in slot_public(auth, "/saddles", "saddles")["saddles"]
+                          if c["name"] == "racer-three"][0]["id"])
+    host_daemon = {int(fake_id): fake, racer2_card_id: fake2,
+                   racer3_card_id: fake3}[int(tag_host_saddle)]
+    status, body = saddle_api("POST", "/api/saddle/task/create", host_daemon.token, {
+        "session_id": tag_session, "title": "Bad tag worker",
+        "mandate": "m", "capabilities": ["gpu", "warp-drive"]})
+    check(status == 400, "an unknown capability tag rejects the task call")
+    error_text = body.get("error", "")
+    check("warp-drive" in error_text and "valid tags" in error_text
+          and "gpu" in error_text and "lostwake" in error_text,
+          "the rejection names the unknown tag and the valid list (%s)" % error_text)
+    status, _ = saddle_api("POST", "/api/saddle/task/create", host_daemon.token, {
+        "session_id": tag_session, "title": "Bad shape worker",
+        "mandate": "m", "capabilities": "gpu"})
+    check(status == 400, "a non-array capabilities member rejects")
+
+    # A valid tag creates the goal worker in draft with exactly the
+    # explicit tag attached; the goal agent enqueues it.
+    status, body = saddle_api("POST", "/api/saddle/task/create", host_daemon.token, {
+        "session_id": tag_session, "title": "Explicit tag worker",
+        "mandate": "do the tagged work", "capabilities": ["gpu"]})
+    check(status == 200 and body.get("ok") is True,
+          "a valid tag creates the task synchronously")
+    tagged_worker = int(body["task_id"])
+    detail = task_state(auth, tagged_worker)
+    check([c["name"] for c in detail.get("capabilities", [])] == ["gpu"],
+          "the worker carries exactly the explicit tag")
+    conn = db()
+    tag_rows = conn.execute(
+        "select c.name from task_capabilities tc"
+        " join capabilities c on c.id = tc.capability_id"
+        " where tc.task_id = ?", (tagged_worker,)).fetchall()
+    conn.close()
+    check([r[0] for r in tag_rows] == ["gpu"],
+          "the task_capabilities rows record the explicit tag")
+    check(detail["status"] == "draft",
+          "the callback's task lands in draft until its agent enqueues")
+    saddle_api("POST", "/api/saddle/task/enqueue", host_daemon.token,
+               {"session_id": tag_session, "task_id": tagged_worker})
+    check(wait_task_done(auth, tagged_worker, timeout=90) is not None,
+          "the tagged worker dispatches and completes")
+    act(auth, slot_public(auth, "/goals/%d" % tag_goal, "goal")["cancel"], {})
+    act(auth, task_state(auth, tag_host)["cancel"], {})
+
+    print("== phase 3: dashboard — pinned blocks + activity timeline ==")
+    # Pinned OPEN blocking items as link-through cards, newest
+    # first; no inline answer forms (the card links to the task
+    # page). Fixture: one open question + one open review raised on a
+    # local task (stand-ins for the auto-approve grandchild's
+    # leftovers) join the probe RFC raised below.
+    conn = db()
+    conn.execute("insert into tasks (project_id, title, status, priority, created_at)"
+                 " values (1, 'Dash fixture task', 'working', 5, strftime('%s','now'))")
+    dash_task = conn.execute("select max(id) from tasks").fetchone()[0]
+    conn.execute("insert into sessions (task_id, saddle_id, started_at)"
+                 " values (?, ?, strftime('%s','now'))", (dash_task, fake_id))
+    dash_session = conn.execute("select max(id) from sessions").fetchone()[0]
+    conn.commit()
+    conn.close()
+    def raise_on_dash(question, kind="question", body=None, summary=None):
+        """Push-era raises on the dashboard fixture task (the poll-era
+        /update channel is gone): a blocked results push carries the
+        block payload; a review verb rides a review entry."""
+        if kind == "review" and summary is not None:
+            return saddle_api("POST", "/api/saddle/results", fake_token, {
+                "session_id": dash_session, "state": "working",
+                "entries": [{"id": 9317,
+                             "command": "saddle review",
+                             "output": summary, "type": "review",
+                             "timestamp": time.strftime(
+                                 "%Y-%m-%dT%H:%M:%SZ", time.gmtime())}]})[0]
+        block = {"question": question, "type": kind}
+        if body is not None:
+            block["body"] = body
+        return saddle_api("POST", "/api/saddle/results", fake_token, {
+            "session_id": dash_session, "state": "blocked",
+            "block": block})[0]
+
+    raise_on_dash("Dash fixture question?", kind="question")
+    raise_on_dash("dash fixture review", kind="review", summary="dash fixture review")
+
+    # The activity timeline: last <= 50 events, newest first, fed
+    # from the existing tables. Fixture rows a few seconds old
+    # guarantee the progress kind and a human-authored comment ride
+    # along; the probe block below proves same-source ordering.
+    conn = db()
+    conn.execute("insert into task_comments (task_id, author, body, created_at)"
+                 " values (?, 'user:admin', 'timeline fixture comment by a human',"
+                 " strftime('%s','now','-5 seconds'))", (cap_task,))
+    conn.execute("insert into task_progress (task_id, summary, created_at)"
+                 " values (?, 'timeline fixture progress',"
+                 " strftime('%s','now','-5 seconds'))",
+                 (cap_task,))
+    conn.commit()
+    conn.close()
+    # The probe RFC raised last: the newest pinned card and the newest
+    # timeline event (its raise+answer below prove same-source ordering
+    # both ways). The timeline sorts same-second events by source
+    # materialisation order, so the probe must land in a LATER clock
+    # second than the fixtures — wait for the boundary (bounded).
+    fixtures_epoch = int(time.time())
+    wait_for(lambda: int(time.time()) > fixtures_epoch or False,
+             timeout=3, what="next clock second before the probe raise")
+    raise_on_dash("Timeline probe: approve the dashboard flow",
+                  kind="rfc", body="# Probe")
+    dash = slot_public(auth, "/", "dashboard")
+    pinned = dash.get("pinned", [])
+    pinned_ids = [int(b["id"]) for b in pinned]
+    check(len(pinned_ids) >= 3 and pinned_ids == sorted(pinned_ids, reverse=True),
+          "pinned open blocks order newest-first (%s)" % pinned_ids)
+    check({b["block_type"] for b in pinned} >= {"question", "rfc", "review"},
+          "pinned cards cover questions, RFCs and reviews")
+    check(all(b["question"] and b["task_title"] and int(b["task_id"]) > 0
+              for b in pinned)
+          and all("answer_action" not in b for b in pinned),
+          "pinned cards are link-through only (task title, kind badge, question)")
+    activity = dash.get("activity", [])
+    epochs = [int(e["at_epoch"]) for e in activity]
+    check(0 < len(activity) <= 50 and epochs == sorted(epochs, reverse=True),
+          "the timeline shows the last <=50 events newest-first (%d events)"
+          % len(activity))
+    kinds = {e["kind"] for e in activity}
+    check({"created", "started", "dispatch", "comment", "progress", "completed"} <= kinds,
+          "the timeline covers status changes, dispatches, comments, progress and"
+          " completions (%s)" % sorted(kinds))
+    check(any(e["kind"] == "comment" and e["text"].startswith("user:admin:")
+              and "fixture comment" in e["text"] for e in activity),
+          "comment events carry author + snippet")
+
+    # The freshly raised probe pinned as the newest card and landed
+    # atop the timeline as block-raised; answering it records
+    # block-answered.
+    check(dash["pinned"][0]["question"] == "Timeline probe: approve the dashboard flow"
+          and int(dash["pinned"][0]["task_id"]) == dash_task,
+          "the freshest open block pins as the first card")
+    check(dash["activity"][0]["kind"] == "block-raised"
+          and "Timeline probe" in dash["activity"][0]["text"],
+          "the raised block lands atop the timeline")
+    probe_block = [b for b in task_state(auth, dash_task)["blocks"]
+                   if b["question"] == "Timeline probe: approve the dashboard flow"][0]
+    act(auth, probe_block["answer_action"], {"answer": "Ship the dashboard"})
+    dash = slot_public(auth, "/", "dashboard")
+    activity = dash.get("activity", [])
+    raised_at = next((i for i, e in enumerate(activity)
+                      if e["kind"] == "block-raised" and "Timeline probe" in e["text"]), -1)
+    answered_at = next((i for i, e in enumerate(activity)
+                        if e["kind"] == "block-answered"
+                        and "Ship the dashboard" in e["text"]), -1)
+    check(answered_at >= 0 and raised_at >= 0 and answered_at < raised_at,
+          "the answered event sorts above its raised event (newest-first, same source)")
+    check(all(b["question"] != "Timeline probe: approve the dashboard flow"
+              for b in dash["pinned"]),
+          "the answered block leaves the pinned cards")
+
+    print("== phase 3 regression: a slow ask after a wake is never dropped ==")
+    # The daemon worker's lost-wake-guard regression: a saddle whose
+    # ask arrives SLOWLY after the wake (busy winding down when the
+    # wake lands) must not lose the wake — the delayed ask (inside
+    # the guard window) claims the task, no re-wake storm fires
+    # while it is pending, and the saddle stays healthy. The
+    # never-asks path (guard -> offline + re-wake of the next
+    # capable) is proven by the racer-three section above.
+    check(wait_for(lambda: queued_count() == 0 or False,
+                   timeout=60, what="queue settles before the slow-wake run") is not None,
+          "the queue settles before the slow-wake run")
+    status, _ = fake2.ask_now()
+    check(status == 204, "the slow-ask racer sleeps before its wake")
+    saddles_state = slot_public(auth, "/saddles", "saddles")
+    act(auth, saddles_state["create_capability"], {"name": "slowwake"})
+    slowwake_cap = int([c["id"] for c in slot_public(auth, "/saddles", "saddles")
+                        ["capabilities"] if c["name"] == "slowwake"][0])
+    racer2_card = [s for s in slot_public(auth, "/saddles", "saddles")["saddles"]
+                   if s["name"] == "racer-two"][0]
+    act(auth, racer2_card["attach_capability"], {"capability_id": str(slowwake_cap)})
+    fake2.ask_delay = 1.2   # slow: asks well after the wake, inside the 2s guard
+    fake2.ask_on_wake = True
+    wakes_before_slow = len(fake2.wake_log)
+    task_id_tmp = create_queued(auth, {
+        "project_id": "1",
+        "title": "Slow wake task",
+        "priority": "2",
+        "capability_id": [str(slowwake_cap)],
+    })
+    slow_task = task_id_tmp
+    check(wait_for(lambda: len(fake2.wake_log) > wakes_before_slow or False,
+                   timeout=30, what="the slow-ask racer woken") is not None,
+          "the only capable sleeping saddle is woken")
+    check(wait_task_done(auth, slow_task, timeout=120) is not None,
+          "the delayed ask claims the task — the wake was not dropped")
+    check(any(a.get("status") == 200
+              and int((a.get("payload") or {}).get("task", {}).get("id") or 0)
+              == slow_task for a in fake2.asks),
+          "the slow ask's 200 carries the task")
+    check(len(fake2.wake_log) == wakes_before_slow + 1,
+          "the pending-wake skip re-wakes nobody while the slow ask is in flight")
+    racer2_card = [s for s in slot_public(auth, "/saddles", "saddles")["saddles"]
+                   if s["name"] == "racer-two"][0]
+    check(racer2_card["status"] in ("idle", "busy"),
+          "the slow asker never went offline (guard did not fire)")
+    fake2.ask_delay = 0.0
+    fake2.ask_on_wake = False  # stays out of the pool below

+ 510 - 0
test/bundles/answers.py

@@ -0,0 +1,510 @@
+"""The answers bundle (moved verbatim from the pre-split web_stack_test.py;
+see test/harness.py for the shared machinery and the runner)."""
+from harness import *  # noqa: F401,F403 — the shared wire helpers
+
+
+# =============================================================================
+# Bundle: answers — the answer-resume machinery in both daemon shapes
+# (sleeping affine wake, mid-round verdict delivery), offline requeue
+# keeping parked-with-answered tasks, the staleness probe, and the
+# startup token migration (this shard's one deliberate app restart).
+# =============================================================================
+
+def run(ctx):
+    auth, fake, fake_id, fake_token = ctx.auth, ctx.fake, ctx.fake_id, ctx.fake_token
+    app = ctx.app
+
+    print("== phase 2: answer resume — wake -> ask -> affinity claim ==")
+    # The full live sequence against a daemon that asks after its
+    # park: ask -> assignment -> blocked push (park) -> ask -> 204
+    # -> sleeps (row idle) -> human answers -> the dispatcher WAKES
+    # the sleeping affine saddle -> its ask allocates the resume,
+    # the verdict riding the assignment -> the session continues.
+    # A private capability tag keeps the fleet's other sleeping
+    # saddles from claiming these tasks.
+    saddles_state = slot_public(auth, "/saddles", "saddles")
+    act(auth, saddles_state["create_capability"], {"name": "answerflow"})
+    answerflow_cap = int([c["id"] for c in slot_public(auth, "/saddles", "saddles")["capabilities"]
+                          if c["name"] == "answerflow"][0])
+
+    def answerflow_daemon(**kwargs):
+        daemon = FakeSaddle()
+        daemon.ask_on_register = False   # manual, deterministic asks
+        daemon.hold_state = True         # the tests drive the lifecycle
+        for key, value in kwargs.items():
+            setattr(daemon, key, value)
+        daemon.serve()
+        return daemon
+
+    def register_answerflow(daemon, name):
+        act(auth, slot_public(auth, "/saddles", "saddles")["register"], {
+            "name": name, "host": "127.0.0.1:%d" % daemon.port})
+        act(auth, saddle_card(auth, name)["attach_capability"],
+            {"capability_id": str(answerflow_cap)})
+
+    def create_answerflow_task(title):
+        return create_queued(auth, {
+            "project_id": "1", "title": title, "priority": "2",
+            "capability_id": [str(answerflow_cap)]})
+
+    def retire_daemon(daemon, name):
+        # deterministic teardown: a dead daemon and an offline row
+        # never interfere with the sections that follow
+        daemon.kill()
+        act(auth, saddle_card(auth, name)["refresh"], {})
+
+    sleeper = answerflow_daemon(ask_on_wake=True)
+    register_answerflow(sleeper, "resume-sleeper")
+    sleeping_task = create_answerflow_task("Sleeping resume task")
+    ask_status, assignment = sleeper.ask_now()
+    check(ask_status == 200 and int(assignment["task"]["id"]) == sleeping_task,
+          "the daemon's ask claims the queued task")
+    sleeping_session = assignment.get("session_id")
+    sleeper.state = "blocked"
+    check(sleeper.push_results("blocked", block={
+        "question": "Pick a side", "type": "question",
+        "options": ["Port", "Starboard"]}) == 200,
+          "the blocked push parks the session")
+    check(wait_for(lambda: task_state(auth, sleeping_task).get("status") == "blocked"
+                   or False, timeout=30, what="sleeping task parked") is not None,
+          "the task parks as blocked")
+    check(saddle_card(auth, "resume-sleeper")["status"] == "idle",
+          "the parked session's saddle row reads idle")
+    ask_status, _ = sleeper.ask_now()
+    check(ask_status == 204,
+          "the parked daemon's ask returns 204 — it sleeps until woken")
+    # Converted sleep(3): ticks pass with the daemon asleep and no
+    # wake may arrive — a wake during the window fails loudly.
+    check(quiet_window(quiet_seconds(),
+                       lambda: len(sleeper.wake_log) == 0,
+                       "sleeping daemon never woken"),
+          "the sleeping daemon is never woken while the block waits")
+    detail = task_state(auth, sleeping_task)
+    side_block = [b for b in detail["blocks"] if b["question"] == "Pick a side"][0]
+    act(auth, side_block["answer_action"], {"option": "Starboard"})
+    check(wait_for(lambda: len(sleeper.wake_log) > 0 or False,
+                   timeout=30, what="wake after the answer") is not None,
+          "answering the block wakes the sleeping affine saddle")
+    # Answering = allocating (plan 11): the resume assignment carries
+    # the verdict as resume_notice (stable wording) AND a FRESH
+    # session id — the parked row closed, the daemon keys its resumed
+    # pushes on the new one.
+    check(wait_for(lambda: any(
+        int(p.get("task", {}).get("id") or 0) == sleeping_task
+        and p.get("session_id") != sleeping_session
+        and p.get("resume_notice") == "Human selected: Starboard"
+        and any(a.get("answer") == "Starboard"
+                for a in p.get("task", {}).get("answers", []))
+        for p in sleeper.start_payloads[1:]) or False,
+        timeout=30, what="resume allocation carries the verdict") is not None,
+          "the woken daemon's ask allocates the resume — fresh session, notice carried")
+    # Barrier: the resume's own working push must commit before the
+    # manual done push (a late working write would otherwise race the
+    # completion's full-row write).
+    check(wait_for(lambda: task_state(auth, sleeping_task).get("status") == "working"
+                   or False, timeout=15, what="resumed round working") is not None,
+          "the resumed round reports working before its completion push")
+    # The resumed round runs to completion keyed on the fresh session.
+    sleeper.push_results("done", summary="sleep-resumed round complete")
+    check(wait_task_done(auth, sleeping_task, timeout=30) is not None,
+          "the resumed session continues to completion")
+    conn = db()
+    rows = conn.execute(
+        "select id, outcome, ended_at is not null from sessions where task_id = ?"
+        " order by id", (sleeping_task,)).fetchall()
+    conn.close()
+    check(len(rows) == 2 and rows[0][1] == "resumed" and rows[0][2]
+          and rows[1][1] == "done" and rows[1][2],
+          "parked session closed 'resumed'; the resumed round ran on a fresh row to done (%s)"
+          % (rows,))
+    retire_daemon(sleeper, "resume-sleeper")
+
+    print("== phase 2: answer resume — the parked daemon is woken (POST /answer retired) ==")
+    # Post Task A every park FREES the daemon: after the blocked push
+    # it lands idle and asks (204). The retired POST /answer channel
+    # always refuses; the verdict reaches the parked workspace purely
+    # through the wake -> ask -> affinity allocation carrying the
+    # resume_notice + a fresh session id.
+    parked = answerflow_daemon(ask_on_wake=True,
+                               ask_on_terminal=False)
+    register_answerflow(parked, "resume-parked")
+    parked_task = create_answerflow_task("Parked resume task")
+    ask_status, assignment = parked.ask_now()
+    check(ask_status == 200 and int(assignment["task"]["id"]) == parked_task,
+          "the daemon's ask claims the task")
+    parked_session = assignment.get("session_id")
+    parked.state = "blocked"
+    check(parked.push_results("blocked", block={
+        "question": "Which database?", "type": "question",
+        "options": ["SQLite", "Postgres"]}) == 200,
+          "the blocked push parks the session mid-round")
+    check(wait_for(lambda: task_state(auth, parked_task).get("status") == "blocked"
+                   or False, timeout=30, what="parked task blocked") is not None,
+          "the task parks as blocked")
+    check(saddle_card(auth, "resume-parked")["status"] == "idle",
+          "the parked session's saddle row reads idle")
+    # The freed daemon re-asks (its idle loop) and sleeps on 204.
+    ask_status, _ = parked.ask_now()
+    check(ask_status == 204,
+          "the freed parked daemon asks again and sleeps (204)")
+    # The retired channel always refuses — the web never depends on it.
+    request = urllib.request.Request(
+        "http://127.0.0.1:%d/answer" % parked.port,
+        data=json.dumps({"answer": "SQLite", "branch_advanced": False}).encode(),
+        method="POST")
+    request.add_header("Content-Type", "application/json")
+    try:
+        urllib.request.urlopen(request, timeout=5)
+        refused = False
+    except urllib.error.HTTPError as error:
+        refused = error.code == 409
+    check(refused, "POST /answer always refuses (409) — parks resume via allocation")
+
+    detail = task_state(auth, parked_task)
+    db_block = [b for b in detail["blocks"] if b["question"] == "Which database?"][0]
+    # branch_advanced on the resume assignment (the /poll verdict
+    # channel's hint lives here now): a sibling on the same shared
+    # working branch completed strictly after the block's park marker
+    # — the resumed allocation must report branch_advanced=true so the
+    # daemon knows to pull before continuing.
+    conn = db()
+    parked_block_created = conn.execute(
+        "select created_at from task_blocks where id = ?", (db_block["id"],)
+    ).fetchone()[0]
+    conn.execute("update tasks set task_branch = 'shared/resume-branch'"
+                 " where id = ?", (parked_task,))
+    conn.commit()
+    conn.close()
+    wait_for(lambda: int(time.time()) > parked_block_created or False,
+             timeout=3, what="next clock second past the park marker")
+    conn = db()
+    conn.execute("insert into tasks (project_id, title, status, priority,"
+                 " task_branch, summary, completed_at, created_at)"
+                 " values (1, 'Resume sibling', 'done', 5, 'shared/resume-branch',"
+                 " 'sibling finished', strftime('%s','now'),"
+                 " strftime('%s','now','-300 seconds'))")
+    conn.commit()
+    conn.close()
+    act(auth, db_block["answer_action"], {"option": "SQLite"})
+    check(wait_for(lambda: len(parked.wake_log) > 0 or False,
+                   timeout=30, what="wake after the answer") is not None,
+          "answering the block wakes the parked (idle) affine saddle")
+    check(wait_for(lambda: any(
+        int(p.get("task", {}).get("id") or 0) == parked_task
+        and p.get("session_id") != parked_session
+        and p.get("resume_notice") == "Human selected: SQLite"
+        and p.get("branch_advanced") is True
+        for p in parked.start_payloads[1:]) or False,
+        timeout=30, what="parked resume allocation") is not None,
+          "the parked daemon's ask allocates the resume — fresh session, formatted notice,"
+          " branch_advanced=true after the sibling's completion")
+    # The hold_state daemon drives its round manually: the resumed
+    # round completes on the fresh session row.
+    parked.push_results("done", summary="parked round resumed and finished")
+    check(wait_task_done(auth, parked_task, timeout=90) is not None,
+          "the parked session continues to completion")
+    conn = db()
+    row = conn.execute("select outcome from sessions where id = ?",
+                       (parked_session,)).fetchone()
+    session_rows = conn.execute(
+        "select id, outcome from sessions where task_id = ? order by id",
+        (parked_task,)).fetchall()
+    conn.close()
+    check(row is not None and row[0] == "resumed"
+          and len(session_rows) == 2 and session_rows[0] == (parked_session, "resumed"),
+          "the parked session closed 'resumed' and the resumed round kept its own row (%s)"
+          % (session_rows,))
+    retire_daemon(parked, "resume-parked")
+
+    print("== plan 11: plan acceptance — accept / reject / auto-approve ==")
+    # A type 'plan' block parks like any other; Accept and
+    # Reject-with-feedback drive the same wake -> ask -> allocation
+    # resume as any verdict, the stable wording riding the
+    # resume_notice. Plan 12: the daemon only SENDS plan blocks on
+    # goal runs now (the goal page owns the review); this covers the
+    # generic verdict path a goal-run's mirrored block also uses. The
+    # auto-approve option is gone.
+    planner = answerflow_daemon(ask_on_wake=True, ask_on_terminal=False)
+    register_answerflow(planner, "plan-planner")
+
+    def park_on_plan(task_id, markdown):
+        planner.state = "blocked"
+        check(planner.push_results("blocked", block={
+            "question": "Plan submitted for review", "type": "plan",
+            "body": markdown}) == 200,
+              "the plan push parks the session")
+        # Wait for the block row itself (the auto-approve variant is
+        # answered — and may resume — before any status poll lands).
+        check(wait_for(lambda: any(b["block_type"] == "plan"
+                                   for b in task_state(auth, task_id)["blocks"])
+                       or False, timeout=30, what="plan block raised") is not None,
+              "the plan block reaches the task")
+        return [b for b in task_state(auth, task_id)["blocks"]
+                if b["block_type"] == "plan"][0]
+
+    # (a) Accept resumes with the approval notice.
+    accept_task = create_answerflow_task("Plan accept task")
+    ask_status, accept_assignment = planner.ask_now()
+    check(ask_status == 200 and int(accept_assignment["task"]["id"]) == accept_task,
+          "the planner claims the accept task")
+    accept_parked_session = accept_assignment.get("session_id")
+    plan_block = park_on_plan(accept_task, "# Steps\n\n1. Wire\n2. Test")
+    check(plan_block.get("answered") is not True,
+          "the plan block waits for a human verdict")
+    # Plan 16 S2: the accept form posts the verdict marker; the server
+    # builds the stable constant (byte-identical wire).
+    act(auth, plan_block["answer_action"], {"verdict": "accept"})
+    check(wait_for(lambda: any(
+        int(p.get("task", {}).get("id") or 0) == accept_task
+        and p.get("session_id") != accept_parked_session
+        and p.get("resume_notice") == "Plan approved. Proceed with implementation."
+        for p in planner.start_payloads[1:]) or False,
+        timeout=30, what="accept resume allocation") is not None,
+          "accept resumes the parked daemon with the approval notice")
+    planner.push_results("done", summary="plan accepted and implemented")
+    check(wait_task_done(auth, accept_task, timeout=60) is not None,
+          "the accepted plan's task completes")
+    planner.set_state("idle")
+
+    # (b) Reject-with-feedback loops the feedback notice back.
+    reject_task = create_answerflow_task("Plan reject task")
+    ask_status, reject_assignment = planner.ask_now()
+    check(ask_status == 200 and int(reject_assignment["task"]["id"]) == reject_task,
+          "the planner claims the reject task")
+    reject_parked_session = reject_assignment.get("session_id")
+    plan_block = park_on_plan(reject_task, "# Draft\n\nJust wing it")
+    act(auth, plan_block["answer_action"], {"feedback": "Add a test section"})
+    reject_block = [b for b in task_state(auth, reject_task)["blocks"]
+                    if b["block_type"] == "plan"][0]
+    check(reject_block.get("answer")
+          == "Plan feedback received:\nAdd a test section",
+          "reject stores the feedback in the stable wording (%s)"
+          % reject_block.get("answer"))
+    check(wait_for(lambda: any(
+        int(p.get("task", {}).get("id") or 0) == reject_task
+        and p.get("session_id") != reject_parked_session
+        and p.get("resume_notice") == "Plan feedback received:\nAdd a test section"
+        for p in planner.start_payloads[1:]) or False,
+        timeout=30, what="reject resume allocation") is not None,
+          "reject resumes the parked daemon with the feedback notice")
+    planner.push_results("done", summary="plan revised and delivered")
+    check(wait_task_done(auth, reject_task, timeout=60) is not None,
+          "the revised plan's task completes")
+    planner.set_state("idle")
+
+    retire_daemon(planner, "plan-planner")
+
+    print("== phase 2: offline requeue keeps parked-with-answered tasks ==")
+    # A daemon dying while its parked task carries an answered
+    # verdict: going offline must not requeue the task or close its
+    # session — the resume machinery (delivery once the daemon
+    # returns, or the affinity allocation on its next ask) needs
+    # both. The question park leaves the row idle; the review park
+    # keeps it busy@task (`saddle review` blocks the round without
+    # a parking state push), exercising the unreachable path's
+    # requeue decision both ways.
+    stranded = answerflow_daemon()
+    register_answerflow(stranded, "resume-stranded")
+    stranded_task = create_answerflow_task("Stranded answered task")
+    ask_status, _ = stranded.ask_now()
+    check(ask_status == 200, "the stranded daemon claims its task")
+    stranded.state = "blocked"
+    stranded.push_results("blocked", block={
+        "question": "Hold or fold?", "type": "question", "options": ["Hold", "Fold"]})
+    check(wait_for(lambda: task_state(auth, stranded_task).get("status") == "blocked"
+                   or False, timeout=30, what="stranded task parked") is not None,
+          "the stranded task parks as blocked")
+    detail = task_state(auth, stranded_task)
+    hold_block = [b for b in detail["blocks"] if b["question"] == "Hold or fold?"][0]
+    act(auth, hold_block["answer_action"], {"option": "Hold"})
+    stranded.kill()  # the daemon dies before the verdict is delivered
+    act(auth, saddle_card(auth, "resume-stranded")["refresh"], {})
+    check(wait_for(lambda: saddle_card(auth, "resume-stranded")["status"] == "offline"
+                   or False, timeout=30, what="stranded saddle offline") is not None,
+          "the dead daemon's saddle row goes offline")
+    # Converted sleep(7): offline ticks run while the task MUST stay
+    # parked — a requeue during the window fails loudly.
+    check(quiet_window(quiet_seconds(),
+                       lambda: task_state(auth, stranded_task)["status"] == "blocked",
+                       "stranded task not requeued"),
+          "the parked-with-answered task is not requeued by the offline pass")
+    conn = db()
+    open_session = conn.execute(
+        "select count(*) from sessions where task_id = ? and ended_at is null",
+        (stranded_task,)).fetchone()[0]
+    conn.close()
+    check(open_session == 1,
+          "the parked-with-answered task keeps its open session for the resume")
+
+    reviewer = answerflow_daemon(ask_on_terminal=False)
+    register_answerflow(reviewer, "resume-reviewer")
+    review_task = create_answerflow_task("Review park task")
+    ask_status, _ = reviewer.ask_now()
+    check(ask_status == 200, "the reviewer claims its task")
+    # Post Task A the review park frees the daemon: the blocked push
+    # carries the review block and parks the row idle.
+    reviewer.state = "blocked"
+    check(reviewer.push_results("blocked", block={
+        "question": "Review requested", "type": "review",
+        "body": "Ready for review: wired and tested."}) == 200,
+          "the review park push carries the review block")
+    check(wait_for(lambda: task_state(auth, review_task).get("status") == "review_requested"
+                   or False, timeout=30, what="review park raised") is not None,
+          "the review block parks the task as review_requested (row freed)")
+    # The verdict lands (nothing delivers it anymore); THEN the daemon
+    # dies and the manual refresh offlines it — the parked-with-answered
+    # task must keep its session for the eventual resume.
+    detail = task_state(auth, review_task)
+    verdict_block = [b for b in detail["blocks"]
+                     if b["block_type"] == "review"][0]
+    act(auth, verdict_block["answer_action"], {"verdict": "accept"})
+    reviewer.kill()
+    act(auth, saddle_card(auth, "resume-reviewer")["refresh"], {})
+    check(wait_for(lambda: saddle_card(auth, "resume-reviewer")["status"] == "offline"
+                   or False, timeout=30, what="reviewer offline") is not None,
+          "the dead reviewer goes offline on the failed probe")
+    # Converted sleep(7): offline ticks run while the task MUST stay
+    # review-parked — a requeue during the window fails loudly.
+    check(quiet_window(quiet_seconds(),
+                       lambda: task_state(auth, review_task)["status"] == "review_requested",
+                       "review-parked task not requeued"),
+          "the review-parked task with an answered verdict is never requeued")
+    conn = db()
+    open_session = conn.execute(
+        "select count(*) from sessions where task_id = ? and ended_at is null",
+        (review_task,)).fetchone()[0]
+    conn.close()
+    check(open_session == 1,
+          "the review-parked task keeps its open session for the resume")
+
+    print("== phase 2: staleness — one probe decides ==")
+    # A silent-but-alive runner (long think, nothing to flush): after
+    # SADDLE_STALE_S (3s here) of silence it owes ONE exceptional
+    # GET /status; the answer keeps it running and the silence
+    # episode gets no second probe.
+    task_id_tmp = create_queued(auth, {
+        "project_id": "1",
+        "title": "Silent thinker",
+        "priority": "2",
+    })
+    thinker = task_id_tmp
+    check(wait_for(lambda: task_state(auth, thinker).get("status") == "working"
+                   or False, timeout=60, what="thinker working") is not None,
+          "silent thinker reaches working")
+    fake.silent = True  # the daemon goes quiet mid-round (alive)
+    probes_at_start = fake.status_hits
+    check(wait_for(lambda: fake.status_hits > probes_at_start or False,
+                   timeout=30, what="exceptional probe arrives") is not None,
+          "a silent runner gets its exceptional GET /status probe")
+    # Converted sleep(8)+sleep(6): a quiet window across several
+    # ticks in which the probe count MUST NOT move — a second probe
+    # (the poll drumbeat this guards against) fails loudly.
+    second_window = fake.status_hits
+    check(quiet_window(quiet_seconds(),
+                       lambda: fake.status_hits == second_window,
+                       "no second staleness probe"),
+          "the silence episode is probed exactly once (no poll drumbeat)")
+    check(task_state(auth, thinker).get("status") == "working"
+          and saddle_card(auth, "fake-saddle")["status"] == "busy",
+          "the answered probe keeps the task running (no requeue)")
+    # Output flows again: the episode ends, the clock resets.
+    fake.silent = False
+    fake.push_chunks(["resumed output\r\n"])
+    check(wait_task_done(auth, thinker, timeout=60) is not None,
+          "the silent thinker completes once output flows again")
+
+    # The daemon vanishing mid-task: silence for the window, the
+    # probe fails, the task requeues with an agent comment and the
+    # saddle goes offline.
+    task_id_tmp = create_queued(auth, {
+        "project_id": "1",
+        "title": "Vanish victim",
+        "priority": "2",
+    })
+    vanish = task_id_tmp
+    check(wait_for(lambda: task_state(auth, vanish).get("status") == "working"
+                   or False, timeout=60, what="vanish victim working") is not None,
+          "vanish victim reaches working")
+    fake.kill()
+    check(wait_for(lambda: saddle_card(auth, "fake-saddle")["status"] == "offline" or False,
+                   timeout=60, what="daemon death -> offline") is not None,
+          "vanishing daemon drives the saddle offline (failed staleness probe)")
+    check(wait_for(lambda: any("unreachable" in c["body"]
+                               and c.get("is_system")
+                               for c in task_state(auth, vanish).get("comments", []))
+                   or False, timeout=30, what="unreachable comment") is not None,
+          "the affected task gets an unreachable system row (never an agent comment)")
+    check(task_state(auth, vanish)["status"] == "queued",
+          "the task requeues after the daemon death")
+    card = saddle_card(auth, "fake-saddle")
+    check(card.get("health") == "offline",
+          "health badge reports offline")
+
+    # The unreachable row flag marks the detection window: a task the
+    # web still sees working while its saddle is offline/fenced, before
+    # the requeue pass moves it. Controlled window (the real
+    # transitions above are atomic with their requeues).
+    conn = db()
+    conn.execute("insert into tasks (project_id, title, status, priority,"
+                 " created_at) values (1, 'Unreachable row', 'working', 5,"
+                 " strftime('%s','now'))")
+    unreachable_row = conn.execute("select max(id) from tasks").fetchone()[0]
+    conn.execute("insert into sessions (task_id, saddle_id, started_at)"
+                 " values (?, ?, strftime('%s','now'))", (unreachable_row, fake_id))
+    conn.commit()
+    conn.close()
+    check(wait_for(lambda: (lambda row: row.get("unreachable") is True)(
+                        [t for t in slot_public(auth, "/tasks", "tasks")["tasks"]
+                         if int(t["id"]) == unreachable_row][0]) or False,
+                   timeout=20, what="unreachable flag") is not None,
+          "queue row shows the unreachable state in the window")
+
+    print("== phase 1: saddles.token is the single credential store (arch 24) ==")
+    # The legacy api_tokens table and every fallback read died with the
+    # poll era: a restart proves the migrated schema carries no
+    # api_tokens table, the row token survives and still authenticates,
+    # and a legacy-shaped token string authorises nothing (no fallback
+    # read exists to honour it). Fixture: this shard's own racer.
+    fake2 = FakeSaddle()
+    fake2.ask_on_register = False
+    fake2.serve(port=free_port())
+    saddles_state = slot_public(auth, "/saddles", "saddles")
+    act(auth, saddles_state["register"], {"name": "racer-two",
+                                          "host": "127.0.0.1:%d" % fake2.port})
+    racer_two_id = int([s for s in slot_public(auth, "/saddles", "saddles")["saddles"]
+                        if s["name"] == "racer-two"][0]["id"])
+    racer_two_token = [s for s in slot_public(auth, "/saddles", "saddles")["saddles"]
+                       if s["name"] == "racer-two"][0]["token"]
+
+    app.terminate()
+    app.wait(timeout=10)
+    app = start_app()
+    auth = login("admin", "adminpass123")
+    ctx.app = app  # teardown tracks the restarted process
+    ctx.auth = auth
+
+    def schema_tables():
+        conn = db()
+        try:
+            return {row[0] for row in conn.execute(
+                "select name from sqlite_master where type = 'table'")}
+        finally:
+            conn.close()
+
+    check("api_tokens" not in schema_tables(),
+          "the fresh schema carries no api_tokens table (arch 24)")
+    conn = db()
+    row_token = conn.execute("select token from saddles where id = ?",
+                             (racer_two_id,)).fetchone()[0]
+    conn.close()
+    check(row_token == racer_two_token and (row_token or "").startswith("saddle-"),
+          "the per-saddle row token survives the restart unchanged")
+    status, _ = saddle_api("POST", "/api/saddle/next-task", racer_two_token)
+    check(status in (200, 204),
+          "the row token still authenticates after the restart")
+    status, _ = saddle_api("POST", "/api/saddle/next-task", "saddle-legacy-copied-token")
+    check(status == 401,
+          "a legacy api_tokens-shaped credential authorises nothing (fallback gone)")
+    fake2.token = racer_two_token
+    fake2.ask_now()
+    check(True, "the fleet re-asks after the restart (sleeping re-established)")

+ 690 - 0
test/bundles/dispatch.py

@@ -0,0 +1,690 @@
+"""The dispatch bundle (moved verbatim from the pre-split web_stack_test.py;
+see test/harness.py for the shared machinery and the runner)."""
+from harness import *  # noqa: F401,F403 — the shared wire helpers
+
+
+# =============================================================================
+# Bundle: dispatch — the task pipeline end to end: registration tokens,
+# rules, project notes, pushed chunks/results ingestion, capability
+# routing, the create form, and retry/manual resume.
+# =============================================================================
+
+def run(ctx):
+    auth, fake, fake_id, fake_token = ctx.auth, ctx.fake, ctx.fake_id, ctx.fake_token
+    app = ctx.app
+
+    print("== registration: token minting and delivery ==")
+    registered = [s for s in slot_public(auth, "/saddles", "saddles")["saddles"]
+                  if s["name"] == "fake-saddle"]
+    check(len(registered) == 1 and registered[0]["token"].startswith("saddle-"),
+          "fake saddle registered with an API token")
+
+    # Plan 10 phase 1: registration delivers the per-saddle token to
+    # the daemon via POST /register {saddle_token, web_base_url}.
+    check(wait_for(lambda: len(fake.register_log) > 0 or False,
+                   timeout=15, what="/register delivery") is not None,
+          "registration POSTs /register to the daemon")
+    register_body = fake.register_log[0]
+    check(register_body.get("saddle_token") == fake_token,
+          "/register carries the minted per-saddle token")
+    check(register_body.get("web_base_url") == WEB,
+          "/register carries the web base URL")
+    check(fake.token == fake_token,
+          "daemon persisted the token (its asks use it)")
+    token_conn = db()
+    row_token = token_conn.execute("select token from saddles where id = ?",
+                                   (fake_id,)).fetchone()[0]
+    token_conn.close()
+    check(row_token == fake_token,
+          "per-saddle token lives on the saddle row")
+    # The register-time ask (idle-awake daemon): 204, nothing
+    # offerable yet — the saddle is asleep and wakeable.
+    check(wait_for(lambda: any(a["status"] == 204 for a in fake.asks) or False,
+                   timeout=15, what="register-time ask") is not None,
+          "the daemon's idle ask returns 204 (nothing offerable)")
+
+    print("== feature 5: rules ==")
+    rules_state = slot_public(auth, "/rules", "rules")
+    for name, body in [
+        ("Use Invercargill", "Never use libgee; use Invercargill enumerables."),
+        ("Write Vala docs", "Every public class carries a doc comment."),
+        ("Prefer meson", "Builds go through meson; no makefiles."),
+        ("Co-dev rule", "Keep the wire contract exactly."),
+        ("Reference rule", "Must never ride along."),
+    ]:
+        act(auth, rules_state["create"], {"name": name, "body": body})
+    listed = {r["name"]: r for r in slot_public(auth, "/rules", "rules")["rules"]}
+    check(len(listed) == 5, "five rules created and listed on /rules")
+
+    def rule_id(name):
+        rows = [r for r in slot_public(auth, "/rules", "rules")["rules"] if r["name"] == name]
+        return int(rows[0]["id"])
+
+    state = slot_public(auth, "/projects", "projects")
+    act(auth, state["create"], {"name": "co", "git_url": "https://example.com/co.git"})
+    act(auth, state["create"], {"name": "ref", "git_url": "https://example.com/ref.git"})
+    co_id = int([p["id"] for p in slot_public(auth, "/projects", "projects")["projects"]
+                 if p["name"] == "co"][0])
+    ref_id = int([p["id"] for p in slot_public(auth, "/projects", "projects")["projects"]
+                  if p["name"] == "ref"][0])
+
+    project = slot_public(auth, "/projects/1", "project")
+    act(auth, project["add_link"], {"linked_project_id": str(co_id),
+                                    "relationship": "co-developed"})
+    act(auth, project["add_link"], {"linked_project_id": str(ref_id),
+                                    "relationship": "reference"})
+    act(auth, project["attach_rule"], {"rule_id": str(rule_id("Use Invercargill"))})
+    act(auth, project["attach_rule"], {"rule_id": str(rule_id("Prefer meson"))})
+    project = slot_public(auth, "/projects/1", "project")
+    check(sorted(r["name"] for r in project["rules"]) == ["Prefer meson", "Use Invercargill"],
+          "project page lists its attached rules")
+
+    co_project = slot_public(auth, "/projects/%d" % co_id, "project")
+    act(auth, co_project["attach_rule"], {"rule_id": str(rule_id("Co-dev rule"))})
+    ref_project = slot_public(auth, "/projects/%d" % ref_id, "project")
+    act(auth, ref_project["attach_rule"], {"rule_id": str(rule_id("Reference rule"))})
+
+    tasks_state = slot_public(auth, "/tasks", "tasks")
+    # Draft-first (deterministic rule attachment): the dispatcher claims
+    # a queued task on its 1s tick, which under load could beat the
+    # attach_rule calls below and ship an assignment without the task's
+    # own rules — attach while draft, enqueue last.
+    act(auth, tasks_state["create"], {
+        "project_id": "1",
+        "title": "Rules dispatch",
+        "description": "Effective rule set rides the /start payload.",
+        "priority": "2",
+    })
+    rule_task = int([t["id"] for t in slot_public(auth, "/tasks", "tasks")["tasks"]
+                     if t["title"] == "Rules dispatch"][0])
+    detail = task_state(auth, rule_task)
+    act(auth, detail["attach_rule"], {"rule_id": str(rule_id("Write Vala docs"))})
+    act(auth, detail["attach_rule"], {"rule_id": str(rule_id("Use Invercargill"))})
+    enqueue_task(auth, rule_task)
+    detail = task_state(auth, rule_task)
+    check(sorted(r["name"] for r in detail["rules"]) == ["Use Invercargill", "Write Vala docs"],
+          "task page lists its attached rules")
+
+    check(wait_for(lambda: len(fake.start_payloads) > 0 or False,
+                   timeout=30, what="/start push") is not None,
+          "dispatcher pushes the task to the fake saddle")
+    payload = fake.start_payloads[-1]
+    rule_names = [r["name"] for r in payload.get("rules", [])]
+    check(rule_names == ["Write Vala docs", "Use Invercargill", "Prefer meson", "Co-dev rule"],
+          "effective rules in /start: task, primary, co-developed order (%s)" % rule_names)
+    check(all(r.get("body") for r in payload.get("rules", [])),
+          "rules carry their bodies")
+    check("Reference rule" not in rule_names,
+          "reference project rules excluded")
+
+    detail = task_state(auth, rule_task)
+    act(auth, detail["rules"][0]["detach"], {})
+    check([r["name"] for r in task_state(auth, rule_task)["rules"]] == ["Use Invercargill"],
+          "detached task rule disappears")
+
+    rules_rows = slot_public(auth, "/rules", "rules")["rules"]
+    docs_row = [r for r in rules_rows if r["name"] == "Write Vala docs"][0]
+    act(auth, docs_row["update"], {"name": "Write Vala docs", "body": "Doc comments or bust."})
+    check(any(r["body"] == "Doc comments or bust."
+              for r in slot_public(auth, "/rules", "rules")["rules"]),
+          "rule edit saves the body")
+
+    check(wait_task_done(auth, rule_task, timeout=60) is not None,
+          "dispatched task completes against the fake daemon")
+
+    print("== feature 6: project notes + callback ==")
+    # Plan 10 phase 1: the shared saddle-callback token is gone —
+    # the per-saddle token authorises the callback endpoints.
+    callback_token = fake_token
+    check(callback_token.startswith("saddle-") and "saddle-callback-" not in callback_token,
+          "note callback authorised by the per-saddle token")
+
+    status, _ = saddle_api("POST", "/api/saddle/note", None,
+                           {"project": "demo", "body": "x"})
+    check(status == 401, "note endpoint rejects a missing token")
+    status, _ = saddle_api("POST", "/api/saddle/note", "saddle-callback-not-real",
+                           {"project": "demo", "body": "x"})
+    check(status == 401, "note endpoint rejects a wrong (legacy-style) token")
+
+    status, body = saddle_api("POST", "/api/saddle/note", callback_token,
+                              {"task_id": rule_task, "project": "demo",
+                               "body": "style.css tokens live in :root"})
+    check(status == 200 and body.get("ok") is True, "note accepted with the callback token")
+    status, _ = saddle_api("POST", "/api/saddle/note", callback_token,
+                           {"project": "no-such-project", "body": "x"})
+    check(status == 400, "unknown project rejected")
+    status, _ = saddle_api("POST", "/api/saddle/note", callback_token,
+                           {"project": "demo", "body": "   "})
+    check(status == 400, "empty note body rejected")
+
+    project = slot_public(auth, "/projects/1", "project")
+    check(any("style.css tokens" in n["body"] and int(n["source_task_id"]) == rule_task
+              for n in project["notes"]),
+          "project page lists the note with its source task")
+    act(auth, [n for n in project["notes"] if "style.css tokens" in n["body"]][0]["delete"], {})
+    check(all("style.css tokens" not in n["body"]
+              for n in slot_public(auth, "/projects/1", "project")["notes"]),
+          "note deleted from the project page")
+
+    # /start payload: notes of primary + co-developed (not reference),
+    # oldest first; callback carries the configured base URL + token.
+    saddle_api("POST", "/api/saddle/note", callback_token,
+               {"project": "demo", "body": "note-one"})
+    saddle_api("POST", "/api/saddle/note", callback_token,
+               {"project": "demo", "body": "note-two"})
+    saddle_api("POST", "/api/saddle/note", callback_token,
+               {"project": "co", "body": "co-note"})
+    conn = db()
+    conn.execute("insert into project_notes (project_id, body, created_at)"
+                 " values (?, 'ref-note-must-not-ship', strftime('%s','now'))", (ref_id,))
+    conn.commit()
+    conn.close()
+
+    task_id_tmp = create_queued(auth, {
+        "project_id": "1",
+        "title": "Notes dispatch",
+        "description": "Project notes ride the /start payload.",
+        "priority": "2",
+    })
+    check(wait_for(lambda: len(fake.start_payloads) >= 2 or False,
+                   timeout=30, what="second /start push") is not None,
+          "dispatcher pushes the notes task")
+    payload = fake.start_payloads[-1]
+    notes = payload.get("project_notes", [])
+    check([n["body"] for n in notes] == ["note-one", "note-two", "co-note"],
+          "project_notes: primary + co-developed, oldest first (%s)" % [n["body"] for n in notes])
+    check(all(n.get("project") for n in notes)
+          and notes[2]["project"] == "co",
+          "project_notes carry the project name")
+    check("ref-note-must-not-ship" not in [n["body"] for n in notes],
+          "reference project notes excluded")
+    callback = payload.get("callback", {})
+    check(callback.get("base_url") == WEB and callback.get("token") == callback_token,
+          "callback carries the configured base URL and the minted token")
+
+    # entry cap: 30 of 33 candidates
+    conn = db()
+    for i in range(33):
+        conn.execute("insert into project_notes (project_id, body, created_at)"
+                     " values (?, ?, strftime('%s','now'))", (1, "bulk-%02d" % i))
+    conn.commit()
+    conn.close()
+    create_queued(auth, {
+        "project_id": "1",
+        "title": "Entry cap dispatch",
+        "priority": "2",
+    })
+    check(wait_for(lambda: len(fake.start_payloads) >= 3 or False,
+                   timeout=30, what="third /start push") is not None,
+          "dispatcher pushes the entry-cap task")
+    notes = fake.start_payloads[-1].get("project_notes", [])
+    check(len(notes) == 30 and notes[0]["body"] == "note-one" and notes[1]["body"] == "note-two",
+          "project_notes capped at 30 entries, oldest kept (%d)" % len(notes))
+
+    # char cap: the giant note is truncated so the total stays <= 20000
+    conn = db()
+    conn.execute("delete from project_notes where body like 'bulk-%' or body = 'co-note'")
+    conn.execute("insert into project_notes (project_id, body, created_at)"
+                 " values (?, ?, strftime('%s','now'))", (1, "giant!" + "x" * 25000,))
+    conn.commit()
+    conn.close()
+    create_queued(auth, {
+        "project_id": "1",
+        "title": "Char cap dispatch",
+        "priority": "2",
+    })
+    check(wait_for(lambda: len(fake.start_payloads) >= 4 or False,
+                   timeout=30, what="fourth /start push") is not None,
+          "dispatcher pushes the char-cap task")
+    notes = fake.start_payloads[-1].get("project_notes", [])
+    total = sum(len(n["body"]) for n in notes)
+    check(len(notes) == 3 and total == 20000 and notes[2]["body"].startswith("giant!"),
+          "project_notes char cap: head kept, giant truncated (entries=%d, chars=%d)"
+          % (len(notes), total))
+
+    print("== phase 2: pushed chunks -> raw log + terminal view ==")
+    # Wait for the last dispatch to finish so its pushes landed.
+    check(wait_task_done(auth, task_id_of("Char cap dispatch"), timeout=60) is not None,
+          "char-cap task completes")
+    conn = db()
+    raw_session = conn.execute(
+        "select s.id from sessions s join tasks t on t.id = s.task_id"
+        " where t.title = 'Char cap dispatch' order by s.id desc limit 1").fetchone()[0]
+    rows = conn.execute("select seq, chunk from session_raw_log where session_id = ?"
+                        " order by seq", (raw_session,)).fetchall()
+    conn.close()
+    check(len(rows) >= 3, "session_raw_log captured the pushed chunks (%d)" % len(rows))
+    seqs = [r[0] for r in rows]
+    check(seqs == sorted(seqs) and len(set(seqs)) == len(seqs),
+          "pushed chunks stored once, seq strictly increasing")
+    text = "".join(r[1] for r in rows)
+    check(fake.PROMPT in text and "echo hello" in text and "hello" in text,
+          "pushed raw log keeps the prompt and echoed output byte-exact")
+    check("working-heartbeat" in text,
+          "the flush-timer heartbeat chunks keep arriving mid-round")
+
+    terminal = slot_public(auth, "/tasks/%d/terminal" % task_id_of("Char cap dispatch"),
+                           "terminal")
+    check(terminal.get("has_raw_log") is True and int(terminal["session_id"]) == raw_session,
+          "terminal view selects raw rendering for the raw session")
+
+    # Old sessions (typed entries, no raw rows) keep the fallback view
+    # (a dedicated fixture task: its only session is the legacy one,
+    # so the terminal view cannot prefer a dispatched raw session).
+    conn = db()
+    conn.execute("insert into tasks (project_id, title, status, priority, created_at)"
+                 " values (1, 'Legacy terminal task', 'working', 5, strftime('%s','now'))")
+    legacy_task = conn.execute("select max(id) from tasks").fetchone()[0]
+    conn.execute("insert into sessions (task_id, saddle_id, started_at, ended_at, outcome)"
+                 " values (?, ?, strftime('%s','now'), strftime('%s','now'), 'done')",
+                 (legacy_task, fake_id))
+    conn.commit()
+    legacy_session = conn.execute("select max(id) from sessions").fetchone()[0]
+    conn.execute("insert into session_commands (session_id, command_text, output_text,"
+                 " type, started_at) values (?, 'ls', 'old-output', 'command',"
+                 " strftime('%s','now'))", (legacy_session,))
+    conn.commit()
+    conn.close()
+    legacy = slot_public(auth, "/tasks/%d/terminal" % legacy_task, "terminal")
+    check(legacy.get("has_raw_log") is False,
+          "legacy session falls back to the entry-type terminal view")
+
+    request = urllib.request.Request(WEB + "/terminal-stream/%d" % raw_session)
+    with urllib.request.urlopen(request, timeout=15) as stream:
+        raw_events = []
+        deadline = time.monotonic() + 8
+        while time.monotonic() < deadline and len(raw_events) < 3:
+            line = stream.readline().decode().strip()
+            if not line.startswith("data: ") or line == "data: ping":
+                continue
+            event = json.loads(line[6:])
+            if event.get("type") == "raw":
+                raw_events.append(event)
+        check(len(raw_events) >= 3 and raw_events[0]["text"] == fake.PROMPT
+              and raw_events[0]["seq"] < raw_events[1]["seq"],
+              "terminal stream serves pushed chunks in seq order (prompt first)")
+
+    print("== phase 2: chunks/results ingestion — auth, idempotency ==")
+    # Token auth on both push channels (plan 10: the per-saddle
+    # bearer authorises every daemon->web call).
+    status, _ = saddle_api("POST", "/api/saddle/chunks", None,
+                           {"session_id": raw_session, "chunks": []})
+    check(status == 401, "chunks endpoint rejects a missing token")
+    status, _ = saddle_api("POST", "/api/saddle/results", "saddle-bogus-token",
+                           {"session_id": raw_session, "state": "working"})
+    check(status == 401, "results endpoint rejects a wrong token")
+    status, _ = saddle_api("POST", "/api/saddle/chunks", fake_token,
+                           {"session_id": 99999, "chunks": []})
+    check(status == 400, "chunks for an unknown session rejected")
+    status, _ = saddle_api("POST", "/api/saddle/results", fake_token,
+                           {"session_id": raw_session, "state": "done"})
+    check(status == 200, "the owning saddle's session accepts its results")
+
+    # Pushed chunk idempotency: re-pushing a batch (the outbox's
+    # at-least-once redelivery after a lost response) consumes the
+    # duplicates and stores only the tail.
+    conn = db()
+    before = conn.execute("select count(*) from session_raw_log where session_id = ?",
+                          (raw_session,)).fetchone()[0]
+    conn.close()
+    redelivery = [{"seq": r[0], "text": r[1]} for r in rows[:3]]
+    status, body = saddle_api("POST", "/api/saddle/chunks", fake_token,
+                              {"session_id": raw_session, "chunks": redelivery})
+    check(status == 200 and body.get("ok") is True and int(body.get("stored") or 0) == 0,
+          "a fully-duplicate batch stores nothing (duplicates consumed)")
+    fresh = [{"seq": 9000, "text": "late-flush\r\n"},
+             {"seq": 9001, "text": ""}]  # truly empty text: no row
+    status, body = saddle_api("POST", "/api/saddle/chunks", fake_token,
+                              {"session_id": raw_session, "chunks": fresh})
+    check(status == 200 and int(body.get("stored") or 0) == 1,
+          "a partial-redelivery batch stores only the new chunks")
+    conn = db()
+    after = conn.execute("select count(*) from session_raw_log where session_id = ?",
+                         (raw_session,)).fetchone()[0]
+    empty_row = conn.execute(
+        "select count(*) from session_raw_log where session_id = ? and seq = 9001",
+        (raw_session,)).fetchone()[0]
+    conn.close()
+    check(after == before + 1 and empty_row == 0,
+          "redelivered chunks never duplicate rows; empty text stores nothing")
+
+    # Pushed entries: today's OutputEntry shape with the daemon's
+    # global entry ids — a redelivered results push stores its
+    # entries exactly once.
+    def command_rows(session):
+        conn = db()
+        try:
+            return conn.execute(
+                "select command_text, type from session_commands"
+                " where session_id = ? order by id", (session,)).fetchall()
+        finally:
+            conn.close()
+
+    entries = [{"id": 8101, "command": "sed -n 1p README.md", "output": "# demo",
+                "exit_code": 0, "type": "command", "timestamp": "2026-09-06T00:00:00Z"}]
+    status, _ = saddle_api("POST", "/api/saddle/results", fake_token,
+                           {"session_id": raw_session, "state": "working",
+                            "entries": entries})
+    check(status == 200, "entries push accepted")
+    status, _ = saddle_api("POST", "/api/saddle/results", fake_token,
+                           {"session_id": raw_session, "state": "working",
+                            "entries": entries})
+    check(status == 200, "redelivered entries push accepted (at-least-once)")
+    stored = command_rows(raw_session)
+    check(len([r for r in stored if r[0] == "sed -n 1p README.md"]) == 1,
+          "redelivered entries store exactly once (daemon-global dedup)")
+
+    # The retired daemon routes 404 (phase 2 deleted /output, /log
+    # and /start serving) — and the web app never calls them.
+    for method, path in (("GET", "/output?since=0"), ("GET", "/log?since=0"),
+                         ("POST", "/start")):
+        request = urllib.request.Request(
+            "http://127.0.0.1:%d%s" % (fake.port, path),
+            data=b"{}" if method == "POST" else None, method=method)
+        try:
+            urllib.request.urlopen(request, timeout=5)
+            gone = False
+        except urllib.error.HTTPError as error:
+            gone = error.code == 404
+        check(gone, "the fake daemon's %s %s is deleted (404)" % (method, path))
+    with open(os.path.join(WORK, "app.log")) as handle:
+        app_log = handle.read()
+    check("Saddle output request" not in app_log and "Saddle log request" not in app_log,
+          "the web never polls /output or /log anymore")
+
+    print("== capabilities: tag-based routing ==")
+    saddles_state = slot_public(auth, "/saddles", "saddles")
+    act(auth, saddles_state["create_capability"], {"name": "gpu"})
+    act(auth, saddles_state["create_capability"], {"name": "bigmem"})
+    saddles_state = slot_public(auth, "/saddles", "saddles")
+    caps = {c["name"]: c for c in saddles_state["capabilities"]}
+    check(len(caps) == 2 and all(int(c["saddle_count"]) == 0 and int(c["task_count"]) == 0
+                                 for c in caps.values()),
+          "capabilities created and listed with zero usage")
+
+
+    fake_card = saddle_card(auth, "fake-saddle")
+    check(fake_card["capabilities"] == [],
+          "saddle card starts with no capability chips")
+
+    # A task requiring 'gpu' waits while the only idle saddle lacks it;
+    # a later task without requirements still dispatches (skip-and-continue).
+    tasks_state = slot_public(auth, "/tasks", "tasks")
+    task_id_tmp = create_queued(auth, {
+        "project_id": "1",
+        "title": "GPU task",
+        "priority": "2",
+    })
+    gpu_task = task_id_tmp
+    detail = task_state(auth, gpu_task)
+    act(auth, detail["attach_capability"], {"capability_id": str(int(caps["gpu"]["id"]))})
+    check(wait_for(lambda: [c["name"] for c in
+                            task_state(auth, gpu_task)["capabilities"]] == ["gpu"]
+                   or False, timeout=90, what="capability attached") is not None,
+          "task page lists the required capability")
+    detail = task_state(auth, gpu_task)
+    # The only idle saddle lacks the tag, so the queue flags the wait
+    # (read before any other task claims the idle saddle). The state is
+    # stable until the any-saddle task below dispatches — poll for it
+    # rather than sampling once (a single read under load once sampled
+    # the row before the attach's pulse settled).
+    check(wait_for(lambda: (lambda row: row["status"] == "queued"
+                            and row["capabilities"] == ["gpu"]
+                            and row.get("waiting_for_saddle") is True)(
+                        [t for t in slot_public(auth, "/tasks", "tasks")["tasks"]
+                         if int(t["id"]) == gpu_task][0]) or False,
+                   timeout=20, what="waiting flag") is not None,
+          "queue row shows the waiting task with its tag and wait flag")
+
+    task_id_tmp = create_queued(auth, {
+        "project_id": "1",
+        "title": "Any-saddle task",
+        "priority": "3",
+    })
+    any_task = task_id_tmp
+
+    check(wait_for(lambda: task_state(auth, any_task).get("status") != "queued" or False,
+                   timeout=30, what="uncapable task dispatches") is not None,
+          "task without requirements dispatches past the waiting task")
+    def capability_wait_logged():
+        with open(os.path.join(WORK, "app.log")) as handle:
+            app_log = handle.read()
+        return "waits for a capable saddle" in app_log and "requires: gpu" in app_log
+    check(wait_for(capability_wait_logged, timeout=90,
+                   what="capability wait log") is not None,
+          "dispatcher logs the capability wait")
+
+    # Attaching the tag to the saddle releases the task.
+    fake_card = saddle_card(auth, "fake-saddle")
+    act(auth, fake_card["attach_capability"], {"capability_id": str(int(caps["gpu"]["id"]))})
+    fake_card = saddle_card(auth, "fake-saddle")
+    check([c["name"] for c in fake_card["capabilities"]] == ["gpu"],
+          "saddle card shows the attached chip")
+    check(wait_task_done(auth, gpu_task, timeout=60) is not None,
+          "task dispatches once the saddle carries the required tag")
+    queue = [t for t in slot_public(auth, "/tasks", "tasks")["tasks"]
+             if int(t["id"]) == gpu_task][0]
+    check(queue.get("waiting_for_saddle") is not True,
+          "wait flag clears once dispatched")
+
+    # Multi-tag: gpu + bigmem required, only gpu carried → waits; adding
+    # bigmem completes the superset. Both requirements ride the create
+    # form (atomic — attaching them one at a time would race a tick
+    # into dispatching on the partial set).
+    task_id_tmp = create_queued(auth, {
+        "project_id": "1",
+        "title": "Big task",
+        "priority": "2",
+        "capability_id": [str(int(caps["gpu"]["id"])), str(int(caps["bigmem"]["id"]))],
+    })
+    big_task = task_id_tmp
+    check(wait_for(lambda: ([t for t in slot_public(auth, "/tasks", "tasks")["tasks"]
+                             if int(t["id"]) == big_task][0].get("waiting_for_saddle")
+                            is True) or False, timeout=30, what="big task waits") is not None,
+          "task waits when the saddle's tags are not a superset")
+    fake_card = saddle_card(auth, "fake-saddle")
+    act(auth, fake_card["attach_capability"], {"capability_id": str(int(caps["bigmem"]["id"]))})
+    check(wait_task_done(auth, big_task, timeout=60) is not None,
+          "task dispatches once the superset is complete")
+
+    # Detach a requirement (on a draft — capabilities lock once a
+    # worker has the job); delete a capability everywhere.
+    act(auth, slot_public(auth, "/tasks", "tasks")["create"], {
+        "project_id": "1",
+        "title": "Detach probe task",
+        "priority": "4",
+        "capability_id": [str(int(caps["gpu"]["id"])), str(int(caps["bigmem"]["id"]))],
+    })
+    detach_probe = int([t["id"] for t in slot_public(auth, "/tasks", "tasks")["tasks"]
+                        if t["title"] == "Detach probe task"][0])
+    act(auth, [c for c in task_state(auth, detach_probe)["capabilities"]
+               if c["name"] == "bigmem"][0]["detach"], {})
+    check([c["name"] for c in task_state(auth, detach_probe)["capabilities"]] == ["gpu"],
+          "detached requirement disappears from the task")
+    bigmem_row = [c for c in slot_public(auth, "/saddles", "saddles")["capabilities"]
+                  if c["name"] == "bigmem"][0]
+    act(auth, bigmem_row["delete"], {})
+    saddles_state = slot_public(auth, "/saddles", "saddles")
+    check(all(c["name"] != "bigmem" for c in saddles_state["capabilities"]),
+          "deleted capability gone from the catalogue")
+    check([c["name"] for c in task_state(auth, big_task)["capabilities"]] == ["gpu"],
+          "deleting a capability drops its task requirements")
+    check(all(c["name"] != "bigmem"
+              for c in saddle_card(auth, "fake-saddle")["capabilities"]),
+          "deleting a capability drops it from saddles")
+
+    print("== B4: required capabilities on the create form ==")
+    tasks_state = slot_public(auth, "/tasks", "tasks")
+    gpu_option = [o for o in tasks_state.get("capability_options", [])
+                  if o["name"] == "gpu"][0]
+    check(len(tasks_state.get("capability_options", [])) >= 1,
+          "queue page offers capability options in the create form")
+
+    conn = db()
+    before = conn.execute("select count(*) from tasks").fetchone()[0]
+    conn.close()
+    act(auth, tasks_state["create"], {
+        "project_id": "1",
+        "title": "Bad cap task",
+        "capability_id": [gpu_option["id"], "999"],
+    })
+    conn = db()
+    after = conn.execute("select count(*) from tasks").fetchone()[0]
+    conn.close()
+    check(after == before, "unknown capability id rejects the create")
+
+    task_id_tmp = create_queued(auth, {
+        "project_id": "1",
+        "title": "Cap-on-create task",
+        "capability_id": [gpu_option["id"]],
+    })
+    cap_create = task_id_tmp
+    detail = task_state(auth, cap_create)
+    check([c["name"] for c in detail["capabilities"]] == ["gpu"],
+          "capabilities from the create form land on the task")
+    queue = [t for t in slot_public(auth, "/tasks", "tasks")["tasks"]
+             if int(t["id"]) == cap_create][0]
+    check(queue["capabilities"] == ["gpu"],
+          "queue row shows the created task's requirements")
+    # The waiting flag must hold it back until the capable saddle frees
+    # up (the fake saddle still carries gpu from the routing checks).
+    check(queue.get("waiting_for_saddle") is not True,
+          "capable saddle available: no wait flag on the new task")
+    # Drain barrier: the cap task must be CLAIMED before the flaky
+    # arc arms fail_next (under parallel-shard load the dispatch tick
+    # can lag task creation; an unclaimed predecessor would consume
+    # the one-shot failure flag instead of the flaky task).
+    check(wait_for(lambda: task_state(auth, cap_create).get("status")
+                   in ("working", "done", "failed") or False,
+                   timeout=60, what="cap task claimed") is not None,
+          "the capable task is claimed before the flaky arc starts")
+
+    print("== retry + resume ==")
+    # A daemon-side failure fails the task with its explanation.
+    fake.fail_next = True
+    task_id_tmp = create_queued(auth, {
+        "project_id": "1",
+        "title": "Flaky task",
+        "priority": "2",
+    })
+    flaky = task_id_tmp
+    check(wait_for(lambda: task_state(auth, flaky).get("status") == "failed" or False,
+                   timeout=90, what="flaky task fails") is not None,
+          "daemon failure fails the task")
+    detail = task_state(auth, flaky)
+    check("bash -n rejected" in (detail.get("summary") or ""),
+          "failure summary shows the daemon's explanation")
+
+    # Retry: the terminal summary dies with its attempt (plan 16 S4 —
+    # it is NOT copied to the thread), the task requeues, history
+    # stays, and the re-dispatch restores the workspace.
+    comments_before = len(detail.get("comments", []))
+    progress_before = len(detail.get("progress", []))
+    act(auth, detail["retry"], {})
+    detail = task_state(auth, flaky)
+    check(detail["status"] == "queued" and (detail.get("summary") or "") == "",
+          "retry requeues the task and clears the stale summary")
+    check(not any("bash -n rejected" in c["body"] for c in detail["comments"]),
+          "no summary→comment copy joins the thread (the terminal cache dies with its attempt, S4)")
+    check(any(c["body"] == "Task retried by user" and c["author"] == "system"
+              and c.get("is_system") for c in detail["comments"]),
+          "retry lands its audit comment as a system row (never an agent row)")
+    check(len(detail["comments"]) >= comments_before,
+          "retry keeps the comment history")
+    pushes_before = len([p for p in fake.start_payloads
+                         if int(p.get("task", {}).get("id") or 0) == flaky])
+    check(wait_for(lambda: len([p for p in fake.start_payloads
+                                if int(p.get("task", {}).get("id") or 0) == flaky])
+                   > pushes_before or False, timeout=90,
+                   what="flaky task re-dispatched") is not None,
+          "retried task dispatches again")
+    # The resumed arc surfaces on the next /status read — in the
+    # push world that is the operator's manual refresh.
+    act(auth, saddle_card(auth, "fake-saddle")["refresh"], {})
+    check(wait_task_done(auth, flaky, timeout=60) is not None,
+          "retried task completes on the restored workspace")
+    detail = task_state(auth, flaky)
+    check(all("restored the session context" not in c["body"]
+              for c in detail.get("comments", [])),
+          "the session-restore stays OUT of the user-facing thread (U2: raw terminal only)")
+    check(all("restored the session context" not in p["summary"]
+              for p in detail.get("progress", [])),
+          "the resume note stays OUT of the progress feed (F8: status is not progress)")
+    # Plan 16 S4: terminal text has ONE representation — the failed
+    # attempt's summary lived in tasks.summary alone (asserted above:
+    # no agent comment), and a HUMAN comment lands as exactly one
+    # user-authored row (the web is the single writer; the daemon's
+    # terminal echo is raw-log only).
+    act(auth, task_state(auth, flaky)["comment"],
+        {"body": "The retry landed — nice recovery"})
+    flaky_comments = task_state(auth, flaky)["comments"]
+    check(len([c for c in flaky_comments
+               if c["body"] == "The retry landed — nice recovery"]) == 1
+          and all(c["author"] != "agent"
+                  for c in flaky_comments
+                  if c["body"] == "The retry landed — nice recovery"),
+          "a human comment lands as exactly ONE user row (single writer, S4)")
+
+    # Manual resume: a task stuck working on an offline saddle.
+    task_id_tmp = create_queued(auth, {
+        "project_id": "1",
+        "title": "Stuck task",
+        "priority": "2",
+    })
+    stuck = task_id_tmp
+    check(wait_for(lambda: task_state(auth, stuck).get("status") == "working" or False,
+                   timeout=60, what="stuck task starts working") is not None,
+          "stuck task reaches working")
+    # Deterministic claim for the resume leg below: the round's end,
+    # the refresh probe AND the dispatcher's wake for the requeued task
+    # all trigger self-asks that could steal it — freeze every trigger
+    # until the manual ask below has made the claim.
+    fake.ask_on_terminal = False
+    fake.ask_on_idle_status = False
+    fake.ask_on_wake = False
+    fake.settle_asks()
+    conn = db()
+    conn.execute("update saddles set status = 'offline' where name = 'fake-saddle'")
+    conn.commit()
+    conn.close()
+    detail = task_state(auth, stuck)
+    check(detail.get("resume_available") is True,
+          "task page offers resume while its saddle is offline")
+    # The resume POSTs task-update cancel to the daemon; the abort
+    # handler fires an ungated re-ask that would race the manual claim
+    # below — slow it past the manual ask (the knob the slow-ask
+    # regression uses).
+    fake.ask_delay = 5.0
+    act(auth, detail["resume"], {})
+    detail = task_state(auth, stuck)
+    check(detail["status"] == "queued",
+          "manual resume requeues the stuck task")
+    check(any(c["body"] == "Saddle became unreachable; task requeued"
+              and c["author"] == "system" and c.get("is_system")
+              for c in detail["comments"]),
+          "manual resume lands the interruption comment as a system row")
+    check(all(s["status"] == "offline"
+              for s in slot_public(auth, "/saddles", "saddles")["saddles"]),
+          "saddle stays offline after the manual requeue")
+
+    # Bringing the saddle back lets the requeued task resume and finish.
+    fake.state = "idle"
+    fake_card = saddle_card(auth, "fake-saddle")
+    act(auth, fake_card["refresh"], {})
+    check(any(s["status"] == "idle"
+              for s in slot_public(auth, "/saddles", "saddles")["saddles"]
+              if s["name"] == "fake-saddle"),
+          "refreshed saddle returns idle")
+    # The refreshed daemon is idle-awake: it asks (the real loop's
+    # own ask; driven directly for determinism — every self-ask trigger
+    # is frozen and the abort re-ask is slowed past it; joining that
+    # delayed thread here would fire its ask first, so it is left to
+    # sleep out the rest of the bundle).
+    status, payload = fake.ask_now()
+    fake.ask_on_idle_status = True
+    fake.ask_on_terminal = True
+    fake.ask_on_wake = True
+    fake.ask_delay = 0.0
+    check(status == 200, "the refreshed daemon's ask claims the requeued task")
+    check(wait_task_done(auth, stuck, timeout=60) is not None,
+          "requeued task resumes on the refreshed saddle and completes")

+ 998 - 0
test/bundles/goals.py

@@ -0,0 +1,998 @@
+"""The goals bundle (moved verbatim from the pre-split web_stack_test.py;
+see test/harness.py for the shared machinery and the runner)."""
+from harness import *  # noqa: F401,F403 — the shared wire helpers
+
+
+# =============================================================================
+# Bundle: goals — the plan-12 goal lifecycle: creation with branch-name
+# uniqueness, the start → planning → plan review → active flow with
+# revisions, the goal agent's task fan-out through the task CLI
+# callbacks (ownership + creator-only enqueue), the event-driven
+# coalesced resume, pause/resume queueing, the completion review with
+# branch push state, the cancel cascade, and the human tasks'
+# auto-enqueue-after predecessor.
+# =============================================================================
+
+def run(ctx):
+    auth, fake, fake_id, fake_token = ctx.auth, ctx.fake, ctx.fake_id, ctx.fake_token
+    app = ctx.app
+
+    def create_goal(fields):
+        act(auth, slot_public(auth, "/goals", "goals")["create"], fields)
+        rows = [g for g in slot_public(auth, "/goals", "goals")["goals"]
+                if g["title"] == fields["title"]]
+        return int(rows[0]["id"])
+
+    print("== plan 12: goal creation, validation, lifecycle actions ==")
+    goal1 = create_goal({"project_id": "1", "title": "Ship the flange",
+                         "brief": "Make the flange module production-grade.",
+                         "branch_name": "goal/flange", "priority": "3"})
+    state = goal_state(goal1)
+    check(state["status"] == "draft" and state["display"] == "draft"
+          and state["branch_name"] == "goal/flange"
+          and state["base_branch"] == "main",
+          "a goal lands in draft with its branch pair")
+    check(state.get("start") is not None and state.get("cancel") is not None
+          and state.get("pause") is None,
+          "draft offers start + cancel only")
+    check(state["run_task_id"] == 0 and state["comments"] == [],
+          "a draft goal has no thread yet (the run task owns it)")
+    draft_page = http_get_page(auth, "/goals/%d" % goal1)
+    check('stm-if="goal.run_task_id &gt; 0" stm-action="goal.comment"' in draft_page
+          and "comments open with its run" in draft_page,
+          "the draft goal page gates the composer on the run (muted note until then)")
+    # Branch-name uniqueness: same name, same involved project → refuse.
+    duplicate_directives = act(auth, slot_public(auth, "/goals", "goals")["create"], {
+        "project_id": "1", "title": "Clash", "brief": "b", "branch_name": "goal/flange"})
+    check(any(d.get("type") == "notify" and d.get("kind") == "error"
+              and "goal/flange" in (d.get("message") or "")
+              for d in duplicate_directives),
+          "a live goal's branch name cannot be reused in an involved project (%s)"
+          % [d.get("message") for d in duplicate_directives if d.get("type") == "notify"])
+    conn = db()
+    conn.execute("insert into projects (name, git_url, default_branch, created_at)"
+                 " values ('other-repo', 'https://example.com/other.git', 'main',"
+                 " strftime('%s','now'))")
+    conn.commit()
+    conn.close()
+    goal_elsewhere = create_goal({"project_id": "2", "title": "Elsewhere",
+                                  "brief": "b", "branch_name": "goal/flange"})
+    check(goal_elsewhere > 0,
+          "the same branch name in a disjoint project is fine (one per repo)")
+    # Brief validation.
+    brief_directives = act(auth, slot_public(auth, "/goals", "goals")["create"], {
+        "project_id": "1", "title": "No brief", "brief": "  ", "branch_name": "goal/x1"})
+    check(any(d.get("type") == "notify" and d.get("kind") == "error"
+              and "brief" in (d.get("message") or "").lower()
+              for d in brief_directives),
+          "an empty brief rejects")
+
+    # Start: planning + the goal-run internal task.
+    act(auth, state["start"], {})
+    state = goal_state(goal1)
+    check(state["status"] == "planning" and state.get("start") is None,
+          "start moves the goal to planning")
+    conn = db()
+    run_row = conn.execute(
+        "select id, kind, mode, creator, goal_id, priority, status from tasks"
+        " where goal_id = ? and kind = 'goal_run'", (goal1,)).fetchone()
+    conn.close()
+    check(run_row is not None and run_row[1] == "goal_run"
+          and run_row[2] == "orchestrate" and run_row[3] == "goal"
+          and run_row[4] == goal1 and run_row[5] == 3
+          and run_row[6] in ("queued", "assigned", "working"),
+          "start creates the goal-run task (orchestrate, priority 3, creator goal,"
+          " queued)")
+    run_task = int(run_row[0])
+    check(goal_state(goal1)["run_task_id"] == run_task,
+          "the goal state carries the run task id")
+    check(any(e["kind"] == "started" for e in goal_state(goal1)["events"]),
+          "the narrative records the start")
+
+    print("== feedback: goal-agent runs are hidden from every task listing ==")
+    # The internal run task never lists anywhere tasks are browsed —
+    # only the goal page exposes it (worker tasks stay listed). The
+    # plan script is armed BEFORE the first dispatch so this section's
+    # waits never consume the round the plan-review flow below needs.
+    fake.goal_script = [("plan", "# Plan v1\n\n1. Add tests\n2. Ship")]
+    check(wait_for(lambda: task_state(auth, run_task)["status"]
+                   in ("assigned", "working") or False,
+                   timeout=60, what="run task dispatches") is not None,
+          "the run task reaches its saddle")
+    queue_rows = slot_public(auth, "/tasks", "tasks")["tasks"]
+    check(all(int(t["id"]) != run_task for t in queue_rows),
+          "the tasks queue never lists the goal-agent run task")
+    check(all(t["kind"] != "goal_run" for t in queue_rows),
+          "no goal_run rows leak into the queue at all")
+    project_state = slot_public(auth, "/projects/1", "project")
+    check(all(int(t["id"]) != run_task for t in project_state["tasks"]),
+          "the project page's task list excludes the run task")
+    dashboard = slot_public(auth, "/", "dashboard")
+    check(all(int(a["id"]) != run_task for a in dashboard["active_tasks"]),
+          "the dashboard's active tasks exclude the run task")
+    check(all(int(i["task_id"]) != run_task for i in dashboard["activity"]),
+          "the activity timeline never references the run task")
+    check(wait_for(lambda: int(next(
+              (s for s in slot_public(auth, "/", "dashboard")["saddles"]
+               if s["name"] == "fake-saddle"), {})
+          .get("current_goal_id") or 0) == goal1 or False,
+          timeout=30, what="saddle card links the goal") is not None,
+          "a saddle hosting the goal agent reads as supervising the goal")
+    fake_dash_card = next(s for s in slot_public(auth, "/", "dashboard")["saddles"]
+                          if s["name"] == "fake-saddle")
+    check(fake_dash_card["current_goal_title"] == "Ship the flange",
+          "the supervision link carries the goal title")
+
+    print("== plan 12: the goal agent plans, plan review, revisions ==")
+    # (The plan script was armed before the run's first dispatch — see
+    # the listing-hiding section above — so the first round submits it.)
+    check(wait_for(lambda: goal_state(goal1)["status"] == "plan_review" or False,
+                   timeout=120, what="goal agent submits its plan") is not None,
+          "the goal agent's plan push enters plan review")
+    state = goal_state(goal1)
+    check(task_state(auth, run_task)["status"] == "blocked",
+          "the goal-run task parks on the plan review")
+    # U3's plan-review counterpart: the run-task card never reads as a
+    # bare "blocked" while a review-shaped block parks it.
+    check(task_state(auth, run_task)["display"] == "awaiting your review",
+          "the run-task card reads 'awaiting your review' during the plan review (U3)")
+    pending = state.get("plan_pending_block")
+    check(pending and "# Plan v1" in (pending.get("body") or ""),
+          "the pending plan review carries the submitted markdown")
+    check(any(b["block_type"] == "plan" and b["is_plan_review"]
+              for b in state["blocks"]),
+          "the goal blocks list carries the pending plan block")
+
+    print("== feedback: goal visual identity ==")
+    # A goal never reads as a task at a glance: marked nav entry,
+    # iconed list page, and the dashboard pile's goal cards carry
+    # their own accent styling.
+    home_html = http_get_page(auth, "/")
+    check('class="nav-goal"' in home_html and "&#127919;" in home_html,
+          "the nav carries the marked 🎯 Goals entry beside Tasks")
+    check(any(p["item_type"] == "goal" for p in
+              slot_public(auth, "/", "dashboard")["pinned"]),
+          "the goal's pending block pins onto the dashboard pile")
+    check("'card goal-card'" in home_html and 'badge-kind-goal' in home_html,
+          "dashboard goal cards carry the distinct goal styling")
+    goals_html = http_get_page(auth, "/goals")
+    check("&#127919;" in goals_html and "goal-icon" in goals_html,
+          "the goals list page carries the goal icon")
+    goal_page_html = http_get_page(auth, "/goals/%d" % goal1)
+    check('class="card goal-head"' in goal_page_html and "goal-page" in goal_page_html,
+          "the goal page carries the goal-accented identity chrome")
+    # Reject with feedback: the agent revises.
+    fake.goal_script = [("plan", "# Plan v2\n\n1. Add tests\n2. Add docs\n3. Ship")]
+    reject_resume_index = len(fake.goal_assignments)
+    act(auth, pending["answer_action"], {"answer": "Add documentation please"})
+    check(wait_for(lambda: goal_state(goal1)["status"] == "plan_review" or False,
+                   timeout=60, what="revised plan enters review") is not None,
+          "feedback sends the agent back to planning; the revision re-enters review")
+    # The rejection resume carried NO context_update (nothing in the
+    # instruction context had changed).
+    check(all("context_update" not in p
+              for p in fake.goal_assignments[reject_resume_index:]),
+          "a resume without context changes carries no context_update")
+    state = goal_state(goal1)
+    revisions = state["plan_revisions"]
+    check(len(revisions) == 2
+          and revisions[0]["answered"] and "Add documentation please" in revisions[0]["answer"]
+          and not revisions[1]["answered"],
+          "rejected revisions stay as answered history (historical-blocks data)")
+    # Plan 16 S1 pin: goals.plan is accept-gated — the pending revision
+    # lives only in its block; nothing lands on the goal before accept.
+    conn = db()
+    plan_column = conn.execute(
+        "select plan from goals where id = ?", (goal1,)).fetchone()[0]
+    conn.close()
+    check((plan_column is None or plan_column == "")
+          and (state["plan"] or "") == "",
+          "goals.plan stays empty while the revision is only pending (accept-gated, S1)")
+    # Approve: goal.plan = v2, status active, agent resumes and parks.
+    # Plan 16 S2: the accept posts the verdict MARKER — the server
+    # resolves the goal-plan kind and owns the constant.
+    fake.goal_script = [("suspend",)]
+    pending = state["plan_pending_block"]
+    act(auth, pending["answer_action"], {"verdict": "accept"})
+    check(wait_for(lambda: goal_state(goal1)["status"] == "active" or False,
+                   timeout=60, what="approved plan activates the goal") is not None,
+          "approving the plan activates the goal")
+    state = goal_state(goal1)
+    check(state["plan"] == "# Plan v2\n\n1. Add tests\n2. Add docs\n3. Ship",
+          "the approved plan markdown is stored on the goal (the accept verdict's write)")
+    # The approval resume carries the plan delta as a context_update
+    # turn (the prompt-cache-friendly replacement for the daemon's
+    # old system-prompt refresh).
+    check(wait_for(lambda: len(fake.goal_assignments) > 0 and
+                   "context_update" in fake.goal_assignments[-1] or False,
+                   timeout=30, what="approval resume carries context_update") is not None,
+          "the plan-approval resume carries a context_update turn")
+    approval_update = fake.goal_assignments[-1]["context_update"]
+    check("Plan approved" in approval_update and "# Plan v2" in approval_update,
+          "the context_update summarises the approved plan markdown")
+    check(wait_for(lambda: task_state(auth, run_task)["status"] == "suspended"
+                   or False, timeout=60, what="goal agent parks after approval") is not None,
+          "the resumed goal agent parks (saddle suspend)")
+
+    print("== plan 12: task fan-out via the task CLI callbacks ==")
+    # The goal agent (parked, open session on its saddle) creates,
+    # enqueues and deletes its tasks through /api/saddle/task/*.
+    conn = db()
+    agent_session = conn.execute(
+        "select id from sessions where task_id = ? and ended_at is null",
+        (run_task,)).fetchone()[0]
+    conn.close()
+    status, body = saddle_api("POST", "/api/saddle/task/create", fake_token, {
+        "session_id": agent_session, "title": "Flange tests",
+        "mandate": "Write the test suite for the flange module.",
+        "mode": "test"})
+    check(status == 200 and body.get("ok") is True,
+          "task create under the goal succeeds (%s)" % body.get("error"))
+    fan_task = int(body["task_id"])
+    detail = task_state(auth, fan_task)
+    check(detail["status"] == "draft" and detail["mode"] == "test"
+          and detail["creator"] == "goal" and detail.get("goal_id") == goal1,
+          "the created task is a draft goal task with its mode and creator")
+    check(detail["task_branch"] == "task/%d-%d" % (goal1, fan_task)
+          and detail["branch_from"] == "goal/flange",
+          "goal worker tasks get ephemeral branches cut from the goal branch")
+    check(any(e["kind"] == "task-created" and int(e["task_id"]) == fan_task
+              for e in goal_state(goal1)["events"]),
+          "the narrative records the agent's task creation")
+
+    # Draft until the agent enqueues; humans may not (creator-only).
+    check(detail.get("enqueue") is None,
+          "the human Enqueue action is not offered for goal tasks (creator-only)")
+    status, body = saddle_api("POST", "/api/saddle/task/enqueue", fake_token, {
+        "session_id": agent_session, "task_id": fan_task})
+    check(status == 200 and task_state(auth, fan_task)["status"] == "queued",
+          "task enqueue by the goal agent queues the draft")
+    # Ownership + shape errors, verbatim for the CLI.
+    status, body = saddle_api("POST", "/api/saddle/task/enqueue", fake_token, {
+        "session_id": agent_session, "task_id": 999999})
+    check(status == 400 and "No task exists" in (body.get("error") or ""),
+          "enqueue of a missing task errors verbatim")
+    create_queued(auth, {"project_id": "1", "title": "Innocent bystander", "priority": "4"})
+    bystander = task_id_of("Innocent bystander")
+    status, body = saddle_api("POST", "/api/saddle/task/delete", fake_token, {
+        "session_id": agent_session, "task_id": bystander})
+    check(status == 400 and "does not belong to your goal" in (body.get("error") or ""),
+          "the goal agent cannot touch tasks outside its goal")
+    status, body = saddle_api("POST", "/api/saddle/task/create", fake_token, {
+        "session_id": agent_session, "title": "Bad mode", "mandate": "m", "mode": "party"})
+    check(status == 400 and "valid modes" in (body.get("error") or ""),
+          "an unknown mode rejects with the valid list")
+    status, body = saddle_api("POST", "/api/saddle/task/create", fake_token, {
+        "session_id": agent_session, "title": "Bad tag", "mandate": "m",
+        "capabilities": ["warp-drive"]})
+    check(status == 400 and "warp-drive" in (body.get("error") or "")
+          and "valid tags" in (body.get("error") or ""),
+          "an unknown capability tag rejects naming the valid set")
+    # A plain task's session is not a goal-agent identity.
+    status, body = saddle_api("POST", "/api/saddle/task/create", fake_token,
+                              {"session_id": 999999, "title": "x", "mandate": "m"})
+    check(status == 400 and "session" in (body.get("error") or ""),
+          "an unknown session_id errors verbatim")
+    # Delete: draft + owned.
+    status, body = saddle_api("POST", "/api/saddle/task/create", fake_token, {
+        "session_id": agent_session, "title": "Scratch task", "mandate": "m"})
+    scratch = int(body["task_id"])
+    status, body = saddle_api("POST", "/api/saddle/task/delete", fake_token, {
+        "session_id": agent_session, "task_id": scratch})
+    check(status == 200 and not any(
+        t["id"] == scratch for t in slot_public(auth, "/tasks", "tasks")["tasks"]),
+        "task delete removes the owned draft")
+    status, body = saddle_api("POST", "/api/saddle/task/delete", fake_token, {
+        "session_id": agent_session, "task_id": fan_task})
+    check(status == 400 and "draft" in (body.get("error") or ""),
+          "deleting a queued task refuses (draft only)")
+
+    print("== plan 12: goal context in the worker assignment + coalesced resume ==")
+    # The queued fan-out task dispatches to the daemon with the goal
+    # reference + ephemeral branch; its completion schedules the parked
+    # goal agent's resume (>= SADDLE_GOAL_RESUME_S after the event).
+    check(wait_for(lambda: any(int(p.get("task", {}).get("id") or 0) == fan_task
+                               for p in fake.start_payloads) or False,
+                   timeout=60, what="fan-out task dispatches") is not None,
+          "the goal worker task dispatches")
+    fan_payload = [p for p in fake.start_payloads
+                   if int(p.get("task", {}).get("id") or 0) == fan_task][-1]
+    goal_ctx = fan_payload.get("goal") or {}
+    check(goal_ctx.get("id") == goal1 and goal_ctx.get("branch") == "goal/flange"
+          and goal_ctx.get("base_branch") == "main"
+          and "flange module" in goal_ctx.get("brief", "")
+          and "# Plan v2" in goal_ctx.get("plan", ""),
+          "the worker assignment carries the goal context (read-only brief + plan)")
+    check(fan_payload.get("ephemeral_branch") == "task/%d-%d" % (goal1, fan_task)
+          and fan_payload.get("kind") == "task" and fan_payload.get("mode") == "test"
+          and fan_payload.get("creator") == "goal",
+          "the worker assignment carries the ephemeral branch + identity triplet")
+    check(wait_task_done(auth, fan_task, timeout=60) is not None,
+          "the goal worker task completes")
+    check(any(e["kind"] == "task-done" and int(e["task_id"]) == fan_task
+              for e in goal_state(goal1)["events"]),
+          "the narrative records the task's completion")
+    goal_runs_before = len(fake.goal_assignments)
+    check(wait_for(lambda: len(fake.goal_assignments) > goal_runs_before or False,
+                   timeout=30, what="parked goal agent resumes") is not None,
+          "the task-terminal event resumes the parked goal agent")
+    resume_payload = fake.goal_assignments[-1]
+    notice = resume_payload.get("resume_notice") or ""
+    check("Task statuses" in notice and "Flange tests" in notice
+          and "done" in notice,
+          "the resume notice batches ALL plan task statuses")
+    check("New completion reports" in notice and "fake daemon finished" in notice,
+          "the resume notice carries the new completion report")
+    check("context_update" not in resume_payload,
+          "a later resume with no context changes omits context_update entirely")
+    check(resume_payload.get("kind") == "goal_run"
+          and resume_payload.get("mode") == "orchestrate",
+          "the resumed goal agent carries its identity triplet")
+    # The resumed agent parked again (script): two events at once must
+    # coalesce into ONE resume within the window.
+    check(wait_for(lambda: task_state(auth, run_task)["status"] == "suspended"
+                   or False, timeout=60, what="goal agent re-parks") is not None,
+          "the resumed goal agent parks again")
+
+    print("== plan 16 S3: delta resume notices — one-line statuses, bodies once ==")
+    # A MULTI-LINE completion lands while the agent is parked. The next
+    # notice lists every status ONE-LINE (first line of the summary
+    # only) and embeds each NEW completion's full body exactly once —
+    # no statuses-section/reports-section double embedding. (Timestamps
+    # are second-granular: each fixture waits out the park's second so
+    # completed_at is strictly newer than suspended_at.)
+    def run_park_second_passed():
+        conn = db()
+        try:
+            row = conn.execute("select suspended_at from tasks where id = ?",
+                               (run_task,)).fetchone()
+            if not row or not row[0]:
+                return False
+            return time.time() > float(row[0]) + 1.05
+        finally:
+            conn.close()
+
+    check(wait_for(run_park_second_passed, timeout=30,
+                   what="S3 park second passes") is not None,
+          "the park stamp is in a strictly older second")
+    conn = db()
+    conn.execute("insert into tasks (project_id, goal_id, kind, title, status,"
+                 " priority, summary, completed_at, created_at) values (1, ?, 'task',"
+                 " 'Multiline report', 'done', 5,"
+                 " 'Headline: the flange calibrates\n\nBody: the full report with all"
+                 " the detail lines.',"
+                 " strftime('%s','now'),"
+                 " strftime('%s','now','-30 seconds'))", (goal1,))
+    conn.commit()
+    conn.close()
+    s3_before = len(fake.goal_assignments)
+    check(wait_for(lambda: len(fake.goal_assignments) > s3_before or False,
+                   timeout=60, what="S3 delta resume fires") is not None,
+          "the multiline completion resumes the parked agent")
+    s3_notice = fake.goal_assignments[-1].get("resume_notice") or ""
+    s3_statuses = s3_notice.split("## Task statuses", 1)[1] \
+                        .split("## New completion reports", 1)[0]
+    check("Headline: the flange calibrates" in s3_statuses
+          and "the full report with all the detail lines" not in s3_statuses,
+          "the statuses section carries ONE LINE per task (the summary's first line)")
+    check(s3_notice.count("the full report with all the detail lines.") == 1
+          and "### #" in s3_notice,
+          "each new completion's full body embeds EXACTLY ONCE (no double embedding)")
+    check(wait_for(lambda: task_state(auth, run_task)["status"] == "suspended"
+                   or False, timeout=60, what="S3 agent re-parks") is not None,
+          "the S3 agent re-parks")
+    # Size constant per event, not cumulative: the NEXT resume (armed
+    # with a fresh single-line completion) reports only the NEW body —
+    # the consumed multiline report never re-embeds.
+    check(wait_for(run_park_second_passed, timeout=30,
+                   what="S3 second park second passes") is not None,
+          "the second park stamp is in a strictly older second")
+    conn = db()
+    conn.execute("insert into tasks (project_id, goal_id, kind, title, status,"
+                 " priority, summary, completed_at, created_at) values (1, ?, 'task',"
+                 " 'Fresh completion', 'done', 5, 'fresh one-liner',"
+                 " strftime('%s','now'),"
+                 " strftime('%s','now','-30 seconds'))", (goal1,))
+    conn.commit()
+    conn.close()
+    s3_more = len(fake.goal_assignments)
+    check(wait_for(lambda: len(fake.goal_assignments) > s3_more or False,
+                   timeout=60, what="S3 second delta resume") is not None,
+          "the fresh completion resumes the agent again")
+    s3_next = fake.goal_assignments[-1].get("resume_notice") or ""
+    check("the full report with all the detail lines." not in s3_next
+          and "### #" in s3_next and "fresh one-liner" in s3_next,
+          "the consumed completion's body never re-embeds (notice size constant per event)")
+    check(wait_for(lambda: task_state(auth, run_task)["status"] == "suspended"
+                   or False, timeout=60, what="S3 agent parks a third time") is not None,
+          "the S3 agent parks for the pause section")
+
+    print("== feedback: goal page parity — progress feed, current activity, runs ==")
+    # The goal agent's runs feed the page's live surfaces: progress
+    # lines (green latest-first feed), the open round's newest
+    # activity line and its hosting saddle. Parked runs keep their
+    # open session, so fixtures land as rows without disturbing the
+    # scripted daemon.
+    conn = db()
+    open_run_session = conn.execute(
+        "select id from sessions where task_id = ? and ended_at is null",
+        (run_task,)).fetchone()[0]
+    conn.execute(
+        "insert into task_progress (task_id, summary, created_at)"
+        " values (?, 'Overseeing the flange fan-out', strftime('%s','now'))",
+        (run_task,))
+    conn.execute(
+        "insert into session_commands (session_id, command_text, type, started_at)"
+        " values (?, 'git -C demo log --oneline -5', 'command',"
+        " strftime('%s','now'))", (open_run_session,))
+    conn.commit()
+    conn.close()
+    # A manual refresh records the daemon's health snapshot (the
+    # parked daemon answers /status with its suspended state).
+    act(auth, saddle_card(auth, "fake-saddle")["refresh"], {})
+    state = goal_state(goal1)
+    check(state["progress"] and state["progress"][0]["summary"]
+          == "Overseeing the flange fan-out",
+          "the goal page carries the agent's live progress feed")
+    check(state["current_command"] == "git -C demo log --oneline -5"
+          and state["current_command_running"] is True,
+          "the current activity shows the open round's running command")
+    check(state["agent_saddle"] == "fake-saddle"
+          and "fake-saddle" in state["saddle_health"],
+          "the assigned agent saddle and its health display")
+    check(state["runs"] and state["runs"][0]["saddle_name"] == "fake-saddle"
+          and "session_id=" in state["runs"][0]["terminal_url"],
+          "the run table carries host saddles and deep-linked terminals")
+    goal_page = http_get_page(auth, "/goals/%d" % goal1)
+    check('stm-markdown="goal.brief"' in goal_page
+          and 'stm-markdown="goal.plan"' in goal_page
+          and 'stm-markdown="comment.body"' in goal_page
+          and 'stm-markdown="event.text"' in goal_page
+          and 'stm-markdown="block.body"' in goal_page,
+          "every long-form goal body renders through stm-markdown")
+    check('stm-attribute.href="run.terminal_url" target="_blank" rel="noopener"' in goal_page,
+          "the run table's terminal links open in a new tab")
+    check("progress-latest" in goal_page and "Agent progress" in goal_page,
+          "the green progress feed renders on the goal page")
+    # Plan revision history keeps its verdicts (approved + rejected).
+    revisions = goal_state(goal1)["plan_revisions"]
+    check(revisions[0]["answered"] is True and revisions[0]["approved"] is False
+          and revisions[1]["approved"] is True,
+          "plan revision history badges approved and rejected verdicts")
+
+    print("== plan 12: pause freezes supervision; events coalesce on resume ==")
+    state = goal_state(goal1)
+    act(auth, state["pause"], {})
+    check(goal_state(goal1)["status"] == "paused"
+          and goal_state(goal1).get("resume") is not None,
+          "an active goal pauses and offers resume")
+    # Terminal events under a paused goal queue without waking anybody.
+    # (The real completion path — complete_task — records the goal's
+    # task-done narrative event; the resume machinery keys on exactly
+    # those terminal kinds, never on the agent's own enqueue narrative.)
+    conn = db()
+    conn.execute("insert into tasks (project_id, goal_id, kind, title, status, priority,"
+                 " summary, completed_at, created_at) values (1, ?, 'task',"
+                 " 'Quiet task', 'done', 5, 'finished while paused',"
+                 " strftime('%s','now'), strftime('%s','now'))", (goal1,))
+    quiet_id = conn.execute("select max(id) from tasks").fetchone()[0]
+    conn.commit()
+    conn.close()
+    paused_runs = len(fake.goal_assignments)
+    check(quiet_window(quiet_seconds(),
+                       lambda: len(fake.goal_assignments) == paused_runs,
+                       "paused goal does not resume"),
+          "a paused goal's events queue without scheduling a resume")
+    state = goal_state(goal1)
+    act(auth, state["resume"], {})
+    check(goal_state(goal1)["status"] == "active",
+          "resume returns the goal to active")
+    check(wait_for(lambda: len(fake.goal_assignments) > paused_runs or False,
+                   timeout=30, what="queued events flush on resume") is not None,
+          "the queued events coalesce into the post-resume wake")
+    check("finished while paused" in (fake.goal_assignments[-1].get("resume_notice") or ""),
+          "the flushed notice reports the task that finished while paused")
+    check(wait_for(lambda: task_state(auth, run_task)["status"] == "suspended"
+                   or False, timeout=60, what="goal agent parks again") is not None,
+          "the goal agent parks again after the flush")
+    # The watermark consumed the flushed transition: with nothing new
+    # under the goal, no further resume fires (parked stays parked).
+    flushed_assignments = len(fake.goal_assignments)
+    check(quiet_window(quiet_seconds(),
+                       lambda: len(fake.goal_assignments) == flushed_assignments,
+                       "consumed watermark never re-fires"),
+          "the consumed watermark never re-fires a resume")
+
+    print("== plan 12: completion review, push state, accept ==")
+    # The daemon exposes goal-branch push state on /status; the web
+    # caches it on the goal when it probes the goal agent's saddle.
+    def status_extra():
+        return None
+    fake.status_extra = {"goal_branches": [
+        {"branch": "goal/flange", "pushed": True},
+        {"branch": "goal/other-repo", "pushed": False}]}
+    fake_card = saddle_card(auth, "fake-saddle")
+    act(auth, fake_card["refresh"], {})
+    check(wait_for(lambda: goal_state(goal1).get("push_branches") or False,
+                   timeout=30, what="push state lands on the goal") is not None,
+          "the daemon's /status goal_branches exposure caches on the goal")
+    branches = goal_state(goal1)["push_branches"]
+    check({(b["branch"], b["pushed"]) for b in branches}
+          == {("goal/flange", True), ("goal/other-repo", False)},
+          "the push state renders per branch")
+    # the daemon's real shape carries repo too — multi-repo rows stay
+    # distinguishable as "repo: branch" labels
+    fake.status_extra = {"goal_branches": [
+        {"repo": "repoa", "branch": "goal/flange", "pushed": True},
+        {"repo": "repob", "branch": "goal/flange", "pushed": False}]}
+    act(auth, fake_card["refresh"], {})
+    check(wait_for(lambda: {b["branch"] for b in goal_state(goal1).get("push_branches") or []}
+                   >= {"repoa: goal/flange"}, timeout=30,
+                   what="repo-qualified push state lands") is not None,
+          "repo-qualified goal_branches rows render as 'repo: branch'")
+    fake.status_extra = None
+
+    # `saddle done` in goal context: the completion review.
+    fake.goal_script = [("done", "# Completion\n\nThe flange ships.")]
+    # Wake the parked agent: a terminal transition newer than the
+    # watermark (the pause-flush consumed everything up to it, so arm
+    # one directly with a fresh row).
+    conn = db()
+    conn.execute("insert into tasks (project_id, goal_id, kind, title, status,"
+                 " priority, completed_at, created_at) values (1, ?, 'task',"
+                 " 'Warmup', 'done', 5,"
+                 " strftime('%s','now'),"
+                 " strftime('%s','now','-30 seconds'))", (goal1,))
+    conn.commit()
+    conn.close()
+    check(wait_for(lambda: goal_state(goal1)["status"] == "completion_review" or False,
+                   timeout=60, what="goal agent submits its completion") is not None,
+          "`saddle done` in goal context enters completion review")
+    state = goal_state(goal1)
+    # Plan 16 S1 (canonical-on-accept): while the review is PENDING the
+    # goal row carries NO report — the document lives only in its
+    # block; completion_report is written solely by the accept verdict.
+    conn = db()
+    pending_report_column = conn.execute(
+        "select completion_report from goals where id = ?", (goal1,)).fetchone()[0]
+    conn.close()
+    check((pending_report_column is None or pending_report_column == "")
+          and (state["completion_report"] or "") == ""
+          and "# Completion" in (state["completion_pending_block"].get("body") or "")
+          and state["completion_pending"] is True
+          and state["completion_pending_block"] is not None
+          and state["completion_pending_block"] is not False,
+          "the pending report lives ONLY in its block (goal row clean, S1)")
+    check(task_state(auth, run_task)["status"] == "blocked",
+          "the goal-run task parks on the completion review")
+    # Plan 16 S5 (U3): label reconciliation — the goal awaiting its
+    # completion review reads "awaiting your review" and the run-task
+    # status card agrees (never a bare "blocked" for a review park).
+    check(goal_state(goal1)["display"] == "awaiting your review"
+          and task_state(auth, run_task)["display"] == "awaiting your review",
+          "the goal and the run-task card agree: 'awaiting your review' (U3)")
+    check(state["compare_url"].endswith("/compare/main...goal/flange"),
+          "the completion review links the compare view")
+    # Reject first: feedback returns the goal to active. Plan 16 S2:
+    # the goal page's reject posts raw `feedback` — the SERVER wraps
+    # it with the completion-review prefix (byte-identical to the
+    # historical client-built answer).
+    fake.goal_script = [("suspend",)]
+    act(auth, state["completion_pending_block"]["answer_action"],
+        {"feedback": "Not done — the docs are missing"})
+    check(wait_for(lambda: goal_state(goal1)["status"] == "active" or False,
+                   timeout=30, what="rejected completion reactivates") is not None,
+          "rejecting the completion returns the goal to active")
+    conn = db()
+    rejected_answer = conn.execute(
+        "select answer from task_blocks where task_id = ?"
+        " and type = 'completion' order by id desc", (run_task,)).fetchone()[0]
+    conn.close()
+    check(rejected_answer
+          == "Review feedback received:\n\nNot done — the docs are missing",
+          "the completion rejection wraps feedback with the stable prefix (%r)"
+          % rejected_answer)
+    conn = db()
+    rejected_report = conn.execute(
+        "select completion_report from goals where id = ?", (goal1,)).fetchone()[0]
+    conn.close()
+    check(rejected_report is None or rejected_report == "",
+          "reject/revise leaves the goal row clean (no report leaked, S1)")
+    # Round 2: submit again and accept.
+    fake.goal_script = [("done", "# Completion v2\n\nThe flange ships, with docs.")]
+    conn = db()
+    conn.execute("insert into tasks (project_id, goal_id, kind, title, status,"
+                 " priority, completed_at, created_at) values (1, ?, 'task',"
+                 " 'Warmup2', 'done', 5,"
+                 " strftime('%s','now'),"
+                 " strftime('%s','now','-30 seconds'))", (goal1,))
+    conn.commit()
+    conn.close()
+    check(wait_for(lambda: goal_state(goal1)["status"] == "completion_review" or False,
+                   timeout=60, what="resubmitted completion") is not None,
+          "the agent resubmits its completion after feedback")
+    state = goal_state(goal1)
+    # Regression (plan-15 followup): the daemon's done-park ALSO pushes a
+    # review-kind block payload (question "Goal completion review", the
+    # real daemon's wording) after the done entry raised the completion
+    # row — the two paths must converge on ONE row, not twin reviews.
+    fake.push_results("blocked", block={
+        "question": "Goal completion review", "type": "review",
+        "body": "# Completion v2\n\nThe flange ships, with docs.",
+        "options": None})
+    conn = db()
+    rows = conn.execute(
+        "select count(*) from task_blocks where task_id = ?"
+        " and answer is null and type in ('completion','review')",
+        (run_task,)).fetchone()[0]
+    conn.close()
+    check(rows == 1,
+          "the daemon's review-kind completion push adopts the pending row (no twin)")
+    state = goal_state(goal1)
+    review_family_in_open = [b for b in state.get("open_blocks", [])
+                             if b.get("is_completion_review")]
+    check(state["completion_pending"] is True and len(review_family_in_open) == 1,
+          "the pending completion review renders ONCE — as the rich attention block")
+    fake.pending_block = None
+    # Raise-side single-row invariant (the render guard and the
+    # twin-answer sweep are gone — fresh DBs cannot hold pre-dedupe
+    # twins, and 4884259's raise-side cross-dedupe keeps it that way):
+    # a REDELIVERED review-kind completion push adopts the same pending
+    # row instead of stacking a twin.
+    fake.push_results("blocked", block={
+        "question": "Goal completion review", "type": "review",
+        "body": "# Completion v2\n\nThe flange ships, with docs.",
+        "options": None})
+    fake.pending_block = None
+    conn = db()
+    rows = conn.execute(
+        "select count(*) from task_blocks where task_id = ?"
+        " and answer is null and type in ('completion','review')",
+        (run_task,)).fetchone()[0]
+    conn.close()
+    check(rows == 1,
+          "a redelivered review-kind push adopts the pending row (raise-side single-row invariant)")
+    # Plan 15 C4: the completion-accept hard gate — the live probe
+    # flags still report repob's branch unpushed, so the operator's
+    # accept REFUSES with origin behind.
+    refusal = action_notify(act(auth, state["completion_pending_block"]["answer_action"],
+                                {"answer": "Review approved. Continue with the task."}))
+    check(goal_state(goal1)["status"] == "completion_review",
+          "the accept REFUSES while origin is behind (hard gate, live flags)")
+    # One parser, one label: the gate's refusal names the SAME repo-
+    # qualified unpushed row the chips render — both surfaces read
+    # GoalService.parse_goal_branches (the gate-vs-chips divergence is
+    # structurally gone).
+    branches = {(b["branch"], b["pushed"]) for b in goal_state(goal1)["push_branches"]}
+    check("repob: goal/flange" in (refusal or "")
+          and ("repob: goal/flange", False) in branches
+          and ("repoa: goal/flange", True) in branches,
+          "the refusal and the chips read ONE parser (same labels, same flags)")
+    # Push the branch daemon-side and probe again — the flags flip
+    # live (no goal-row write), and the accept goes through.
+    fake.status_extra = {"goal_branches": [
+        {"repo": "repoa", "branch": "goal/flange", "pushed": True},
+        {"repo": "repob", "branch": "goal/flange", "pushed": True}]}
+    act(auth, fake_card["refresh"], {})
+    check(wait_for(lambda: (goal_state(goal1).get("push_branches") or [])
+                   and all(b["pushed"] for b in goal_state(goal1)["push_branches"])
+                   or False, timeout=30, what="pushed flags land") is not None,
+          "the push chips derive from the LIVE probe flags")
+    conn = db()
+    no_push_column = conn.execute(
+        "select count(*) from pragma_table_info('goals')"
+        " where name = 'branch_push_state'").fetchone()[0] == 0
+    conn.close()
+    check(no_push_column,
+          "no stored push snapshot exists (F9: the goal row never records it)")
+    state = goal_state(goal1)
+    # The passing accept posts the verdict MARKER (the goal page's
+    # accept form shape, plan 16 S2) — the server resolves the
+    # completion kind and stores the stable approval wording.
+    act(auth, state["completion_pending_block"]["answer_action"],
+        {"verdict": "accept"})
+    check(wait_for(lambda: goal_state(goal1)["status"] == "complete" or False,
+                   timeout=30, what="accepted completion completes") is not None,
+          "accepting the completion completes the goal once origin is current")
+    state = goal_state(goal1)
+    conn = db()
+    accepted_report = conn.execute(
+        "select completion_report from goals where id = ?", (goal1,)).fetchone()[0]
+    conn.close()
+    check(state["terminal"] is True and state.get("cancel") is None
+          and accepted_report == "# Completion v2\n\nThe flange ships, with docs."
+          and "# Completion v2" in state["completion_report"],
+          "a complete goal is terminal with the WINNING block's body as its report (S1)")
+    check(wait_for(lambda: task_state(auth, run_task)["status"] == "done" or False,
+                   timeout=30, what="goal run task closes") is not None,
+          "approving the completion closes the goal-run task done")
+    conn = db()
+    twins_left = conn.execute(
+        "select count(*) from task_blocks where task_id = ?"
+        " and answer is null and type in ('completion','review')",
+        (run_task,)).fetchone()[0]
+    conn.close()
+    check(twins_left == 0,
+          "the verdict answered the pending completion-family row (single-row invariant)")
+
+    print("== plan 15 C3: the narrative derives from the recorded shape ==")
+    # Content equivalence with the old projection on this run's exact
+    # shape: every kind the goal_events projection produced, keyed the
+    # same way, plus the watermark and no-ingest guarantees.
+    narrative = goal_state(goal1)["events"]
+    kinds = [e["kind"] for e in narrative]
+    for expected in ("created", "started", "plan-submitted", "plan-rejected",
+                     "plan-approved", "task-created", "task-done",
+                     "completion-submitted", "completion-rejected", "goal-approved"):
+        check(expected in kinds,
+              "the derived narrative carries the %s row" % expected)
+    check(all(k != "task-enqueued" and k != "resumed" and k != "retry" for k in kinds),
+          "timestamp-less bookkeeping kinds never return")
+    stamps = [e["at_display"] for e in narrative if e.get("at_display")]
+    check(stamps == sorted(stamps, reverse=True),
+          "the narrative reads newest first")
+    conn = db()
+    no_event_table = conn.execute(
+        "select count(*) from sqlite_master where type = 'table'"
+        " and name = 'goal_events'").fetchone()[0] == 0
+    conn.close()
+    check(no_event_table,
+          "the goal_events table is gone (no narrative rows on ingest)")
+
+    print("== plan 12: cancel cascades to the goal's tasks ==")
+    goal2 = create_goal({"project_id": "1", "title": "Doomed goal",
+                         "brief": "This goal will be cancelled.",
+                         "branch_name": "goal/doomed"})
+    fake.goal_script = [("suspend",)]
+    act(auth, goal_state(goal2)["start"], {})
+    conn = db()
+    run2 = conn.execute("select id from tasks where goal_id = ? and kind = 'goal_run'",
+                        (goal2,)).fetchone()[0]
+    conn.close()
+    check(wait_for(lambda: task_state(auth, run2)["status"] == "suspended" or False,
+                   timeout=60, what="doomed goal agent parks") is not None,
+          "the doomed goal's agent parks")
+    conn = db()
+    agent_session2 = conn.execute(
+        "select id from sessions where task_id = ? and ended_at is null",
+        (run2,)).fetchone()[0]
+    conn.close()
+    status, body = saddle_api("POST", "/api/saddle/task/create", fake_token, {
+        "session_id": agent_session2, "title": "Doomed draft", "mandate": "m"})
+    doomed_draft = int(body["task_id"])
+    doomed_queued_task = None
+    status, body = saddle_api("POST", "/api/saddle/task/create", fake_token, {
+        "session_id": agent_session2, "title": "Doomed runner", "mandate": "m"})
+    doomed_runner = int(body["task_id"])
+    saddle_api("POST", "/api/saddle/task/enqueue", fake_token,
+               {"session_id": agent_session2, "task_id": doomed_runner})
+    act(auth, goal_state(goal2)["cancel"], {})
+    check(goal_state(goal2)["status"] == "cancelled",
+          "the goal cancels from active (parked-agent) state")
+    check(task_state(auth, run2)["status"] == "failed",
+          "the cascade cancels the goal agent's run task")
+    check(wait_for(lambda: task_state(auth, doomed_runner)["status"] == "failed"
+                   or False, timeout=30, what="cascade cancels the queued task") is not None,
+          "the cascade cancels the goal's queued task")
+    check(not any(t["id"] == doomed_draft
+                  for t in slot_public(auth, "/tasks", "tasks")["tasks"]),
+          "the cascade deletes the goal's draft tasks")
+    # A cancelled goal frees its branch name.
+    reuse = create_goal({"project_id": "1", "title": "Reused name",
+                         "brief": "b", "branch_name": "goal/doomed"})
+    check(reuse > goal2, "a cancelled goal's branch name is reusable")
+
+    print("== plan 13 B3: goal failure cascades to non-terminal tasks ==")
+    # A goal holding a draft, a queued task and a working task: the
+    # agent's failure cascades like a cancellation — drafts deleted (no
+    # orphan stays dispatchable), queued/working cancelled — and the
+    # narrative records the cascade.
+    collapse = create_goal({"project_id": "1", "title": "Collapse goal",
+                            "brief": "Fails with tasks in flight.",
+                            "branch_name": "goal/collapse"})
+    fake.goal_script = [("suspend",)]
+    act(auth, goal_state(collapse)["start"], {})
+    conn = db()
+    run3 = conn.execute("select id from tasks where goal_id = ? and kind = 'goal_run'",
+                        (collapse,)).fetchone()[0]
+    conn.close()
+    check(wait_for(lambda: task_state(auth, run3)["status"] == "suspended" or False,
+                   timeout=60, what="collapse goal agent parks") is not None,
+          "the collapse goal's agent parks first")
+    conn = db()
+    run3_session = conn.execute(
+        "select id from sessions where task_id = ? and ended_at is null",
+        (run3,)).fetchone()[0]
+    conn.close()
+
+    def agent_task(title):
+        status, body = saddle_api("POST", "/api/saddle/task/create", fake_token, {
+            "session_id": run3_session, "title": title, "mandate": "m"})
+        task_id = int(body["task_id"])
+        saddle_api("POST", "/api/saddle/task/enqueue", fake_token,
+                   {"session_id": run3_session, "task_id": task_id})
+        return task_id
+
+    status, body = saddle_api("POST", "/api/saddle/task/create", fake_token, {
+        "session_id": run3_session, "title": "Collapse draft", "mandate": "m"})
+    collapse_draft = int(body["task_id"])  # stays draft (never enqueued)
+    collapse_queued = agent_task("Collapse queued")
+    collapse_worker = agent_task("Collapse worker")
+    # Both queued tasks race for the one saddle; freeze the daemon the
+    # moment the first dispatches so one stays genuinely WORKING (and
+    # the other queued) when the goal fails.
+    fake.hold_state = True
+    def collapse_working():
+        for task_id in (collapse_queued, collapse_worker):
+            if task_state(auth, task_id)["status"] == "working":
+                return task_id
+        return False
+    running_one = wait_for(collapse_working, timeout=60, what="a collapse task works")
+    check(running_one is not None,
+          "a collapse task reaches working before the failure")
+    queued_one = collapse_worker if running_one == collapse_queued else collapse_queued
+
+    status, _ = saddle_api("POST", "/api/saddle/results", fake_token,
+                           {"session_id": run3_session, "state": "failed",
+                            "summary": "the foundation crumbled"})
+    check(status == 200 and goal_state(collapse)["status"] == "failed",
+          "the agent's failure fails the goal")
+    check(task_state(auth, run3)["status"] == "failed",
+          "the failure fails the goal agent's run task")
+    check(wait_for(lambda: task_state(auth, queued_one)["status"] == "failed"
+                   and task_state(auth, running_one)["status"] == "failed" or False,
+                   timeout=30, what="failure cascade settles") is not None,
+          "the failure cascade cancels the queued and working tasks")
+    check(not any(t["id"] == collapse_draft
+                  for t in slot_public(auth, "/tasks", "tasks")["tasks"]),
+          "the failure cascade deletes the goal's draft tasks")
+    state = goal_state(collapse)
+    check(any(e["kind"] == "cascade" for e in state["events"]),
+          "the narrative records the failure cascade")
+    check(state["draft_tasks"] == 0 and state["queued_tasks"] == 0,
+          "nothing under the failed goal stays dispatchable (no orphan drafts)")
+    check(len([e for e in state["events"] if e["kind"] == "goal-failed"]) == 1,
+          "the failing goal records exactly one goal-failed event")
+    # Plan 16 S1: the FAILURE report keeps its goal-side home (failure
+    # is terminal — no pending duplication exists, so unlike the
+    # completion report it is written at failure time).
+    conn = db()
+    failure_report = conn.execute(
+        "select completion_report from goals where id = ?", (collapse,)).fetchone()[0]
+    conn.close()
+    check(failure_report == "the foundation crumbled",
+          "fail_goal's failure report keeps its goal-side home (S1)")
+    # Plan 16 S4: the narrative renders the task-failed rows from the
+    # terminal summary's lead — the run thread carries NO duplicate
+    # agent comment of the goal failure text.
+    failed_rows = [e for e in state["events"] if e["kind"] == "task-failed"]
+    check(failed_rows
+          and all(": Cancelled by user" in e["text"] for e in failed_rows),
+          "task-failed narrative rows render the summary lead (S4: summary is the terminal cache)")
+    run_comments = [c for c in task_state(auth, run3)["comments"]
+                    if c["author"] == "agent"]
+    check(not any("the foundation crumbled" in c["body"] for c in run_comments),
+          "the goal failure text never duplicates as an agent comment (S4)")
+    fake.hold_state = False
+
+    print("== plan 12: auto-enqueue-after for human tasks ==")
+    act(auth, slot_public(auth, "/tasks", "tasks")["create"], {
+        "project_id": "1", "title": "Predecessor task", "priority": "4"})
+    predecessor = task_id_of("Predecessor task")
+    enqueue_task(auth, predecessor)
+    act(auth, slot_public(auth, "/tasks", "tasks")["create"], {
+        "project_id": "1", "title": "Successor task", "priority": "4",
+        "enqueue_after_task_id": str(predecessor)})
+    successor = task_id_of("Successor task")
+    check(task_state(auth, successor)["status"] == "draft"
+          and task_state(auth, successor).get("enqueue_after_task_id") == predecessor,
+          "a human task can carry an auto-enqueue predecessor")
+    check(wait_task_done(auth, predecessor, timeout=60) is not None,
+          "the predecessor completes")
+    check(wait_for(lambda: task_state(auth, successor)["status"] in
+                   ("queued", "assigned", "working") or False,
+                   timeout=30, what="successor auto-enqueues") is not None,
+          "the done predecessor auto-enqueues its dependent")
+    # Cycle validation refuses a predecessor chain that loops.
+    act(auth, slot_public(auth, "/tasks", "tasks")["create"], {
+        "project_id": "1", "title": "Cycle A", "priority": "4"})
+    cycle_a = task_id_of("Cycle A")
+    act(auth, slot_public(auth, "/tasks", "tasks")["create"], {
+        "project_id": "1", "title": "Cycle B", "priority": "4",
+        "enqueue_after_task_id": str(cycle_a)})
+    cycle_b = task_id_of("Cycle B")
+    cycle_directives = act(auth, task_state(auth, cycle_a)["update"], {
+        "title": "Cycle A", "description": "x", "priority": "4",
+        "enqueue_after_task_id": str(cycle_b)})
+    check(any(d.get("type") == "notify" and d.get("kind") == "error"
+              and "cycle" in (d.get("message") or "").lower()
+              for d in cycle_directives),
+          "a predecessor cycle rejects with a naming error")
+    # A failed predecessor leaves the dependent in draft.
+    fake.fail_next = True
+    act(auth, slot_public(auth, "/tasks", "tasks")["create"], {
+        "project_id": "1", "title": "Failing predecessor", "priority": "1"})
+    failing_pred = task_id_of("Failing predecessor")
+    enqueue_task(auth, failing_pred)
+    act(auth, slot_public(auth, "/tasks", "tasks")["create"], {
+        "project_id": "1", "title": "Stranded successor", "priority": "4",
+        "enqueue_after_task_id": str(failing_pred)})
+    stranded = task_id_of("Stranded successor")
+    check(wait_for(lambda: task_state(auth, failing_pred)["status"] == "failed"
+                   or False, timeout=60, what="failing predecessor fails") is not None,
+          "the scripted-failure predecessor fails")
+    check(quiet_window(quiet_seconds(),
+                       lambda: task_state(auth, stranded)["status"] == "draft",
+                       "failed predecessor leaves the draft"),
+          "a failed predecessor leaves its dependent in draft")
+
+    # Successor cleanup: let the queued successor finish so the
+    # shard's app shuts down with an empty queue.
+    check(wait_task_done(auth, successor, timeout=90) is not None,
+          "the auto-enqueued successor completes")
+
+    print("== feedback: context_update carries rule/note deltas on resume ==")
+    # A standalone task parks on a question; while it is parked a rule
+    # is attached to the project and a note lands; the resuming
+    # assignment carries both as the context_update markdown turn.
+    probe_id = create_queued(auth, {"project_id": "1", "title": "Context probe",
+                                    "priority": "4"})
+    check(wait_for(lambda: fake.running_task == probe_id
+                   and task_state(auth, probe_id)["status"] == "working" or False,
+                   timeout=60, what="probe task runs") is not None,
+          "the probe task dispatches")
+    fake.set_state("blocked")
+    fake.push_results("blocked", block={"type": "question",
+                                        "question": "Which database dialect?"})
+    check(wait_for(lambda: task_state(auth, probe_id)["status"] == "blocked" or False,
+                   timeout=60, what="probe task blocks") is not None,
+          "the probe task parks on its question")
+    detail = task_state(auth, probe_id)
+    open_block = [b for b in detail["blocks"] if not b["answered"]][0]
+    # Backdate the parked round's start: stamps are second-resolution
+    # epochs, and the delta compares strictly-later — the park must
+    # span a real interval like an operator's would.
+    conn = db()
+    conn.execute("update sessions set started_at = strftime('%s','now') - 60"
+                 " where id = (select min(id) from sessions where task_id = ?)",
+                 (probe_id,))
+    conn.commit()
+    conn.close()
+    # While parked: a new rule attached to the project + a new note.
+    rules_state = slot_public(auth, "/rules", "rules")
+    act(auth, rules_state["create"], {
+        "name": "Nightly gate", "body": "Every PR must pass the nightly suite before merge."})
+    conn = db()
+    rule_id = conn.execute("select id from rules where name = 'Nightly gate'").fetchone()[0]
+    conn.close()
+    act(auth, slot_public(auth, "/projects/1", "project")["attach_rule"],
+        {"rule_id": str(rule_id)})
+    conn = db()
+    conn.execute("insert into project_notes (project_id, body, created_at)"
+                 " values (1, 'The demo repo moved its CI to nightly builds.',"
+                 " strftime('%s','now'))")
+    conn.commit()
+    check(conn.execute("select count(*) from rule_projects where rule_id = ?",
+                       (rule_id,)).fetchone()[0] == 1,
+          "the rule attaches to the project while the task is parked")
+    conn.close()
+    probe_assignments = len([p for p in fake.start_payloads
+                             if int(p.get("task", {}).get("id") or 0) == probe_id])
+    act(auth, open_block["answer_action"], {"answer": "postgres"})
+    check(wait_for(lambda: len([p for p in fake.start_payloads
+                                if int(p.get("task", {}).get("id") or 0) == probe_id])
+                   > probe_assignments or False, timeout=60,
+                   what="probe task resumes") is not None,
+          "answering the block resumes the probe task")
+    probe_resume = [p for p in fake.start_payloads
+                    if int(p.get("task", {}).get("id") or 0) == probe_id][-1]
+    delta = probe_resume.get("context_update") or ""
+    check("Rules changed" in delta and "Nightly gate" in delta
+          and "nightly suite" in delta,
+          "the resume's context_update summarises the newly attached rule")
+    check("New project notes" in delta and "nightly builds" in delta,
+          "the resume's context_update summarises the new project note")
+    check("Plan approved" not in delta,
+          "standalone resumes carry no plan section")
+    check(wait_task_done(auth, probe_id, timeout=60) is not None,
+          "the probe task completes after its resume")

+ 713 - 0
test/bundles/goalui.py

@@ -0,0 +1,713 @@
+"""The goalui bundle (moved verbatim from the pre-split web_stack_test.py;
+see test/harness.py for the shared machinery and the runner)."""
+from harness import *  # noqa: F401,F403 — the shared wire helpers
+
+
+def run(ctx):
+    """Plan 14 workstream B + plan 15 C1: the goal supervision surface.
+
+    B1 — goal-run control parity (Retry supervision / Requeue-to-resume
+    on the status head, the /tasks/<goal-run-id> redirect, no
+    notify-me toggle), B2 — the plan-review remarks queue, B4 —
+    sessions.resume_notice + the terminal dropdown/resume panel, B5 —
+    page order, effective rules and per-task capability badges, B6 —
+    narrative footnote weights. C1 — the single-row block world: the
+    goal's blocks ARE the run task's rows (answered from every
+    surface through one path; no dual rows, no stragglers, at most
+    one review-kind block per verdict path). C4 — the goal page
+    batch: one muted head activity line, plan between attention and
+    tasks, answered blocks behind an expander, footnote comments.
+    C5 — the dashboard deep-link closure: goal pile cards link the
+    goal page, every surface settles the single row, and no
+    goal-side store exists to hold stragglers.
+    """
+    auth, fake, fake_id, fake_token = ctx.auth, ctx.fake, ctx.fake_id, ctx.fake_token
+
+    def run_task_of(goal_id):
+        conn = db()
+        try:
+            return int(conn.execute(
+                "select id from tasks where goal_id = ? and kind = 'goal_run'",
+                (goal_id,)).fetchone()[0])
+        finally:
+            conn.close()
+
+    def wait_run(status, timeout=60, what="run status"):
+        return wait_for(lambda: task_state(auth, run_task_of(goal))["status"] == status
+                        or False, timeout=timeout, what=what)
+
+    def pile_questions():
+        return [b.get("question") for b in
+                slot_public(auth, "/", "dashboard")["pinned"]
+                if b.get("item_type") == "goal"]
+
+    def open_session(task_id):
+        conn = db()
+        try:
+            row = conn.execute(
+                "select id from sessions where task_id = ? and ended_at is null",
+                (task_id,)).fetchone()
+            return int(row[0]) if row else None
+        finally:
+            conn.close()
+
+    print("== B1: the goal-run task page redirects to the goal ==")
+    fake.goal_script = [("plan", "# Remarks plan\n\n## Steps\n\n1. First move")]
+    act(auth, slot_public(auth, "/goals", "goals")["create"], {
+        "project_id": "1", "title": "Goalui goal",
+        "brief": "Drive the plan-14 goal surface end to end.",
+        "branch_name": "goal/goalui"})
+    conn = db()
+    goal = conn.execute("select id from goals where title = 'Goalui goal'"
+                        ).fetchone()[0]
+    conn.close()
+    act(auth, goal_state(goal)["start"], {})
+    wait_run("blocked", what="goalui goal agent parks on its plan")  # plan review parks blocked
+    run_task = run_task_of(goal)
+
+    frames = directives("/tasks/%d" % run_task, auth)
+    navigations = [d for d in frames if d.get("type") == "navigate"]
+    check(any(d.get("uri") == "/goals/%d" % goal for d in navigations),
+          "the goal-run task page redirects to /goals/<id> (navigate directive)")
+    check(slot_public(auth, "/tasks/%d" % run_task, "task")["id"] == run_task,
+          "the redirect still hydrates the task slot (sealed refresh + API readers)")
+
+    status, page = http("GET", "/tasks/%d" % run_task, headers={
+        "X-Statum-Slot": "key=%s; as_at=%s" % (auth["key"], auth["as_at"])}, timeout=15)
+    check(status == 200, "the compiled goal-run page serves")
+
+    act(auth, slot_public(auth, "/tasks", "tasks")["create"], {
+        "project_id": "1", "title": "Goalui worker", "priority": "4",
+        "description": "A plain worker under no goal."})
+    conn = db()
+    worker = conn.execute("select id from tasks where title = 'Goalui worker'"
+                          ).fetchone()[0]
+    conn.close()
+    check(not [d for d in directives("/tasks/%d" % worker, auth)
+               if d.get("type") == "navigate"],
+          "worker task pages render normally (no redirect)")
+
+    state = goal_state(goal)
+    check("toggle_notify" not in state and state.get("notify") is None,
+          "no notify-me toggle on the goal (goals notify unconditionally)")
+    goal_page = http_get_page(auth, "/goals/%d" % goal)
+    check("Notify me" not in goal_page and "toggle-notify" not in goal_page,
+          "the goal page template ships no notify control")
+    check(state["branch_name"] == "goal/goalui" and state["base_branch"] == "main"
+          and isinstance(state["push_branches"], list)
+          and state["priority"] == 3
+          and len(state["started_display"]) > 0
+          and len(state["agent_saddle"]) > 0,
+          "the status head carries the full field set (branch pair, chips list,"
+          " priority, timestamps, agent saddle)")
+    check("Retry supervision" in goal_page and "Requeue to resume" in goal_page,
+          "the status head ships the run-control parity buttons")
+    check("status-corner" not in goal_page and "goal complete" not in goal_page
+          and goal_page.count("badge-yeehaw") == 1,
+          "yeehaw is rows-only (no goal-head corner badge; the row badge remains)")
+
+    check(goal_state(goal)["current_activity"] == "parked awaiting the plan review",
+          "the head line reads 'parked awaiting the plan review' while one is open")
+    goal_page = http_get_page(auth, "/goals/%d" % goal)
+    check(goal_page.index("Goal agent blocks") < goal_page.index("<h3>Plan</h3>")
+          < goal_page.index("<h3>Tasks</h3>"),
+          "the plan section sits between attention and tasks")
+    check("data-plan-review" in goal_page and "Approved plan &amp; revisions" in goal_page,
+          "an open review renders expanded beside the collapsed approved-plan expander")
+
+    print("== B2: the plan-review remarks queue ==")
+    check(goal_state(goal)["status"] == "plan_review"
+          and goal_state(goal)["plan_pending_block"] is not None,
+          "the goal sits in plan review with a pending block")
+    goal_page = http_get_page(auth, "/goals/%d" % goal)
+    review_at = goal_page.index("data-plan-review")
+    check(review_at > 0, "the plan review region is marked for the remarks queue")
+    check(goal_page.index('data-block-id="goal.plan_pending_block.id"') > 0,
+          "the queue keys on the pending goal block id")
+    body_at = goal_page.index('data-plan-body')
+    remarks_at = goal_page.index("data-plan-remarks")
+    check(body_at < remarks_at,
+          "the remarks queue renders at the bottom of the plan body")
+    for marker in ("data-plan-accept", "data-plan-toggle", "data-plan-submit",
+                   "data-plan-remove", "plan-popover", "remarksByBlock"):
+        check(marker in goal_page, "the remarks queue ships %s" % marker)
+    check("(index + 1) + '. '" in goal_page,
+          "the rejection payload numbers every queued remark")
+    check("rejectOpenByBlock" in goal_page and "statum.afterEvaluate(syncPlanRemarks)" in goal_page,
+          "the queue survives pulse refreshes (maps outside statum re-renders)")
+
+    # The rejection payload exactly as the client composes it: the
+    # stable verdict wording, then each remark NUMBERED in queue order
+    # with its quote prefixed like a comment.
+    payload = ("Plan feedback received:\n\n"
+               "> ## Steps\n\n1. First move\n\n"
+               "1. Add a rollback step\n\n"
+               "2. Name the owner of the migration")
+    act(auth, goal_state(goal)["plan_pending_block"]["answer_action"],
+        {"answer": payload})
+    state = goal_state(goal)
+    check(state["status"] == "planning",
+          "the remarks rejection returns the agent to planning")
+    rejected = [r for r in state["plan_revisions"] if r.get("answered")]
+    check(any(r["answer"] == payload for r in rejected),
+          "the rejection carries the remarks verbatim, in order")
+    check(payload.index("1. Add a rollback step") < payload.index("2. Name the owner"),
+          "the numbering is queue-ordered")
+
+    print("== B4: resume_notice lands on the resumed session row ==")
+    fake.goal_script = [("question", "Which datastore?", ["SQLite", "Redis"])]
+    check(wait_for(lambda: goal_state(goal)["status"] == "planning" or False,
+                   timeout=30, what="rejection observed") is not None,
+          "the agent revises")
+    # The parked plan agent resumes with the verdict; the next round
+    # raises the scripted question.
+    check(wait_for(lambda: any(b["question"] == "Which datastore?"
+                               and not b.get("answered")
+                               for b in goal_state(goal)["blocks"]) or False,
+                   timeout=60, what="question raised") is not None,
+          "the resumed agent raises its question")
+    conn = db()
+    notices = dict(conn.execute(
+        "select id, resume_notice from sessions where task_id = ?", (run_task,)
+    ).fetchall())
+    conn.close()
+    resumed_ids = [i for i, text in notices.items() if text]
+    fresh_ids = [i for i, text in notices.items() if not text]
+    check(len(resumed_ids) >= 1 and any("Plan feedback received" in notices[i]
+                                        for i in resumed_ids),
+          "the resumed session stores the notice it was allocated")
+    check(min(notices) in fresh_ids,
+          "session 1 (the fresh opening round) carries no resume notice")
+
+    print("== C1: the single run-task row IS the goal's block ==")
+    check("Which datastore?" in pile_questions(),
+          "the open goal question pins onto the dashboard pile")
+    goal_rows = [b for b in goal_state(goal)["blocks"]
+                 if b["question"] == "Which datastore?"]
+    run_rows = [b for b in task_state(auth, run_task)["blocks"]
+                if b["question"] == "Which datastore?"]
+    check(len(run_rows) == 1 and len(goal_rows) == 1
+          and int(run_rows[0]["id"]) == int(goal_rows[0]["id"]),
+          "the goal page and the run task read the SAME single row")
+    pile_card = [b for b in slot_public(auth, "/", "dashboard")["pinned"]
+                 if b.get("question") == "Which datastore?"][0]
+    check(pile_card.get("item_type") == "goal"
+          and int(pile_card.get("goal_id") or 0) == goal
+          and int(pile_card.get("id") or 0) == int(run_rows[0]["id"])
+          and pile_card.get("goal_title") == "Goalui goal",
+          "the pile card is the run-task row styled as a goal item")
+    act(auth, [b for b in goal_state(goal)["blocks"]
+               if b["question"] == "Which datastore?" and not b.get("answered")]
+        [0]["answer_action"], {"option": "SQLite"})
+    conn = db()
+    unanswered = conn.execute(
+        "select count(*) from task_blocks where question = 'Which datastore?'"
+        " and answer is null").fetchone()[0]
+    conn.close()
+    check(unanswered == 0, "answering from the goal page closes the single row")
+    check("Which datastore?" not in pile_questions(),
+          "the answered row no longer pins the dashboard pile")
+
+    # The task-page deep link (the AnswerBlockAction API surface)
+    # answers the SAME row through the one goal path — there is no
+    # second row to sweep and no stale copy can survive.
+    conn = db()
+    conn.execute("insert into task_blocks (task_id, type, question, created_at)"
+                 " values (?, 'question', 'Deep link probe?',"
+                 " strftime('%s','now'))", (run_task,))
+    conn.commit()
+    conn.close()
+    check("Deep link probe?" in pile_questions(),
+          "the fixture row pins like any goal question")
+    deep_block = [b for b in task_state(auth, run_task)["blocks"]
+                  if b["question"] == "Deep link probe?" and not b.get("answered")][0]
+    act(auth, deep_block["answer_action"], {"answer": "Answered via the deep link"})
+    conn = db()
+    answered_row = conn.execute(
+        "select answer from task_blocks where question = 'Deep link probe?'"
+    ).fetchone()[0]
+    tables = {r[0] for r in conn.execute(
+        "select name from sqlite_master where type = 'table'").fetchall()}
+    conn.close()
+    check(answered_row == "Answered via the deep link",
+          "the task-page deep link answers the same single row (the API path)")
+    check("Deep link probe?" not in pile_questions(),
+          "the deep-link answer closes the pile card too")
+    check("goal_blocks" not in tables,
+          "the goal_blocks table is gone (run-task blocks are canonical)")
+
+    print("== C5: deep-link closure on the single-row world ==")
+    # The pile card's goal item deep-links the goal page (the answer
+    # surface); answering from either surface settled THE row above.
+    home_markup = http_get_page(auth, "/")
+    check("'/goals/' + blockview.goal_id" in home_markup,
+          "the pile card deep-links the goal page for goal items")
+    conn = db()
+    dupes = conn.execute(
+        "select count(*) from (select question from task_blocks where task_id = ?"
+        " group by question having count(*) > 1)", (run_task,)).fetchone()[0]
+    stragglers = conn.execute(
+        "select count(*) from task_blocks where task_id = ? and answer is null",
+        (run_task,)).fetchone()[0]
+    goal_side_tables = [r[0] for r in conn.execute(
+        "select name from sqlite_master where type = 'table'"
+        " and name in ('goal_blocks','goal_comments','goal_events')").fetchall()]
+    conn.close()
+    check(dupes == 0 and stragglers == 0,
+          "one row per question on the run task, none left unanswered")
+    check(not goal_side_tables,
+          "no goal-side store exists — historical stragglers are impossible")
+
+    print("== B4: the terminal session dropdown + resume-info panel ==")
+    fake.goal_script = [("suspend",)]
+    check(wait_for(lambda: task_state(auth, run_task)["status"] == "suspended"
+                   or False, timeout=60, what="agent parks suspended") is not None,
+          "the agent parks suspended for the requeue scenario")
+    terminal = slot_public(auth, "/tasks/%d/terminal" % run_task, "terminal")
+    ids = [int(s["id"]) for s in terminal["sessions"]]
+    check(ids == sorted(ids, reverse=True),
+          "the session dropdown lists newest-first")
+    check(int(terminal["session_id"]) == ids[0],
+          "the terminal still defaults to the latest session")
+    labels = {int(s["id"]): s["label"] for s in terminal["sessions"]}
+    check(all(label.startswith("Session #") for label in labels.values()),
+          "dropdown labels read 'Session #N — started <time>'")
+    # Recompute at the check point: the C1 answers above each
+    # resumed the agent too, so the earlier snapshot would go stale.
+    conn = db()
+    resumed_ids = [int(i) for (i, text) in conn.execute(
+        "select id, resume_notice from sessions where task_id = ?",
+        (run_task,)).fetchall() if text]
+    conn.close()
+    resumed_markers = [i for i in ids if "[resumed]" in labels[i]]
+    check(set(resumed_markers) == set(resumed_ids),
+          "the [resumed] marker rides exactly the notice-carrying sessions")
+    notices_by_id = {int(s["id"]): s.get("notice") or "" for s in terminal["sessions"]}
+    check("Opening brief" in notices_by_id[min(ids)]
+          and "Drive the plan-14 goal surface" in notices_by_id[min(ids)],
+          "session 1's panel shows the opening-brief framing (from the goal brief)")
+    check(any("Plan feedback received" in (notices_by_id[i] or "") for i in resumed_ids),
+          "a resumed session's panel shows the stored resume notice")
+    terminal_page = http_get_page(auth, "/tasks/%d/terminal" % run_task)
+    check('id="session-select"' in terminal_page
+          and "window.terminalPickSession" in terminal_page,
+          "the session picker is an options dropdown")
+    check('stm-markdown="window.terminalSessionNotice(terminal)"' in terminal_page,
+          "the panel renders the selected session's notice as markdown")
+    check("No opening brief or resume notice recorded" in terminal_page,
+          "the panel ships its graceful empty state")
+    css = open(os.path.join(REPO, "src/pages/app.css")).read()
+    check("resume-notice-panel" in css and "max-height: 200px" in css,
+          "the panel is a 200px vertical-scroll strip (stylesheet)")
+
+    print("== B1: requeue-to-resume from the goal head ==")
+    conn = db()
+    conn.execute("update saddles set status = 'offline' where id = ?", (fake_id,))
+    conn.commit()
+    conn.close()
+
+    def requeue_offered():
+        # Act on the SAME state that satisfied the wait: a second read
+        # once raced the scripted daemon's ask reviving the saddle row,
+        # and the conditionally-authored action vanished between the
+        # two reads (KeyError on act).
+        offered = goal_state(goal)
+        return offered if offered.get("requeue_run") is not None else False
+    state = wait_for(requeue_offered, timeout=30, what="requeue offered")
+    check(state is not None,
+          "a parked run on a dead saddle offers Requeue-to-resume")
+    check(state.get("retry_run") is None,
+          "an active goal offers no Retry supervision")
+    open_before = open_session(run_task)
+
+    def parked_session_ended():
+        if open_before is None:
+            return True
+        conn = db()
+        try:
+            return conn.execute(
+                "select ended_at is not null from sessions where id = ?",
+                (open_before,)).fetchone()[0] == 1
+        finally:
+            conn.close()
+    act(auth, state["requeue_run"], {})
+    check(task_state(auth, run_task)["status"] == "queued",
+          "the requeue returns the run to the queue")
+    # The PARKED session itself must end (the restore-on-dispatch
+    # successor may open immediately — the check keys the old row,
+    # not the task's transient open-session window).
+    check(wait_for(parked_session_ended, timeout=60,
+                   what="parked session closed") is not None,
+          "the requeue closed the parked session (restore-on-dispatch)")
+    conn = db()
+    conn.execute("update saddles set status = 'idle' where id = ?", (fake_id,))
+    conn.commit()
+    conn.close()
+    fake.goal_script = [("suspend",)]
+    check(wait_for(lambda: task_state(auth, run_task)["status"] == "suspended"
+                   or False, timeout=60, what="requeued run re-dispatches") is not None,
+          "the requeued run re-dispatches and re-parks")
+    fresh_session = open_session(run_task)
+    conn = db()
+    fresh_notice = conn.execute(
+        "select resume_notice from sessions where id = ?", (fresh_session,)
+    ).fetchone()[0]
+    conn.close()
+    check(fresh_notice is None,
+          "a requeue's fresh session carries no resume notice (empty panel state)")
+
+    print("== B1: Retry supervision revives a failed goal ==")
+    fake.push_results("failed", summary="the supervision collapsed (scripted)")
+    check(wait_for(lambda: goal_state(goal)["status"] == "failed" or False,
+                   timeout=30, what="goal fails") is not None,
+          "the run's failure fails the goal")
+    check(wait_for(lambda: goal_state(goal).get("retry_run") is not None
+                   or False, timeout=30, what="retry offered") is not None,
+          "a failed goal offers Retry supervision")
+    fake.goal_script = [("suspend",)]
+    act(auth, goal_state(goal)["retry_run"], {})
+    state = goal_state(goal)
+    check(state["status"] == "active",
+          "the retry revives supervision (goal back to active)")
+    check(task_state(auth, run_task)["status"] in ("queued", "assigned", "working",
+                                                   "suspended", "blocked"),
+          "the retry re-offered the run task")
+    check(wait_for(lambda: task_state(auth, run_task)["status"] == "suspended"
+                   or False, timeout=60, what="retried supervision parks") is not None,
+          "the retried supervision dispatches and parks again")
+    state = goal_state(goal)
+    check(any(e["kind"] == "system" and "Supervision retried" in e["text"]
+              for e in state["events"]),
+          "the narrative records the supervision retry (a system row)")
+
+    print("== B5 + C4: order, effective rules, capability badges ==")
+    goal_page = http_get_page(auth, "/goals/%d" % goal)
+    markers = [
+        ('class="card goal-head"', "status head"),
+        ("Agent progress", "progress"),
+        ("Goal agent blocks", "attention blocks"),
+        ("<h3>Plan</h3>", "plan"),
+        ("<h3>Tasks</h3>", "tasks"),
+        ("Initial brief", "brief"),
+        ("Involved projects", "projects"),
+        ("<h3>Rules</h3>", "rules"),
+        ("Supervision narrative", "narrative"),
+        ("<h3>Comments</h3>", "comments"),
+        ("Goal agent runs", "runs"),
+    ]
+    positions = []
+    for marker, _ in markers:
+        check(marker in goal_page, "the goal page ships the %s section" % _)
+        positions.append(goal_page.index(marker))
+    check(positions == sorted(positions),
+          "the page reads status → progress → attention → plan → tasks → brief →"
+          " rules → narrative → comments → runs (in order)")
+    check("goal.current_activity" in goal_page and "Current activity" not in goal_page,
+          "the activity lives as ONE muted head line (the card is gone)")
+    check(".goal-page .card" in open(os.path.join(REPO, "src/pages/app.css")).read(),
+          "the stylesheet restores the goal page's card rhythm (padding regression)")
+
+    rules_state = slot_public(auth, "/rules", "rules")
+    act(auth, rules_state["create"], {"name": "goalui-primary", "body": "Primary rule"})
+    act(auth, rules_state["create"], {"name": "goalui-codev", "body": "Co-dev rule"})
+    act(auth, rules_state["create"], {"name": "goalui-ref", "body": "Reference rule"})
+    conn = db()
+    rule_ids = {name: int(conn.execute("select id from rules where name = ?",
+                                       (name,)).fetchone()[0])
+                for name in ("goalui-primary", "goalui-codev", "goalui-ref")}
+    conn.execute("insert into rule_projects (rule_id, project_id, created_at)"
+                 " values (?, 1, strftime('%s','now'))", (rule_ids["goalui-primary"],))
+    conn.execute("insert into projects (name, git_url, default_branch, created_at)"
+                 " values ('goalui-codev-project', 'https://example.com/g.git',"
+                 " 'main', strftime('%s','now'))")
+    codev_project = conn.execute(
+        "select id from projects where name = 'goalui-codev-project'").fetchone()[0]
+    conn.execute("insert into projects (name, git_url, default_branch, created_at)"
+                 " values ('goalui-ref-project', 'https://example.com/r.git',"
+                 " 'main', strftime('%s','now'))")
+    ref_project = conn.execute(
+        "select id from projects where name = 'goalui-ref-project'").fetchone()[0]
+    conn.execute("insert into rule_projects (rule_id, project_id, created_at)"
+                 " values (?, ?, strftime('%s','now'))",
+                 (rule_ids["goalui-codev"], codev_project))
+    conn.execute("insert into rule_projects (rule_id, project_id, created_at)"
+                 " values (?, ?, strftime('%s','now'))",
+                 (rule_ids["goalui-ref"], ref_project))
+    conn.commit()
+    conn.close()
+    act(auth, goal_state(goal)["add_link"], {"linked_project_id": str(codev_project),
+                                             "relationship": "co-developed"})
+    act(auth, goal_state(goal)["add_link"], {"linked_project_id": str(ref_project),
+                                             "relationship": "reference"})
+    rule_names = [r["name"] for r in goal_state(goal)["rules"]]
+    check(rule_names == ["goalui-primary", "goalui-codev"],
+          "the Rules section lists the goal's effective set (primary then"
+          " co-developed; reference contributes nothing)")
+
+    act(auth, slot_public(auth, "/saddles", "saddles")["create_capability"],
+        {"name": "goalui-capability"})
+    conn = db()
+    capability = conn.execute(
+        "select id from capabilities where name = 'goalui-capability'"
+    ).fetchone()[0]
+    # The early redirect-fixture worker joins the goal (a fanned
+    # worker's shape) so its row carries the badge too.
+    conn.execute("update tasks set goal_id = ? where id = ?", (goal, worker))
+    conn.execute("insert into task_capabilities (task_id, capability_id)"
+                 " values (?, ?)", (worker, capability))
+    conn.commit()
+    conn.close()
+    goal_worker = {"id": worker, "caps": None}
+    act(auth, slot_public(auth, "/tasks", "tasks")["create"], {
+        "project_id": "1", "title": "Goalui fanned worker", "priority": "4",
+        "description": "A worker the agent fanned out."})
+    conn = db()
+    fanned = conn.execute(
+        "select id from tasks where title = 'Goalui fanned worker'").fetchone()[0]
+    conn.execute("update tasks set goal_id = ? where id = ?", (goal, fanned))
+    conn.execute("insert into task_capabilities (task_id, capability_id)"
+                 " values (?, ?)", (fanned, capability))
+    conn.commit()
+    conn.close()
+    rows = {int(t["id"]): t for t in goal_state(goal)["goal_tasks"]}
+    check(rows[fanned].get("capabilities") == ["goalui-capability"]
+          and rows[worker].get("capabilities") == ["goalui-capability"],
+          "task rows carry their required capability tags")
+    goal_page = http_get_page(auth, "/goals/%d" % goal)
+    check('stm-for-capability-in="goal_task.capabilities"' in goal_page
+          and "badge-capability" in goal_page,
+          "the task rows render capability badges")
+
+    print("== B6: narrative weights — events full, comments footnote ==")
+    # An AGENT comment projects the narrative's comment event (human
+    # comments only thread) — pushed through the entries channel while
+    # parked, so the suspended state stays put.
+    fake.push_results("suspended", entries=[{
+        "id": 9001, "command": "saddle comment", "output": "An agent aside.",
+        "exit_code": 0, "type": "comment", "timestamp": "2026-09-12T00:00:00Z"}])
+    check(wait_for(lambda: any(e["kind"] == "comment"
+                               for e in goal_state(goal)["events"]) or False,
+                   timeout=15, what="comment event lands") is not None,
+          "an agent comment lands as a narrative event")
+    goal_page = http_get_page(auth, "/goals/%d" % goal)
+    check("stm-attribute.class=\"'goal-event' + (event.kind == 'comment'"
+          " ? ' footnote' : '')\"" in goal_page.replace("\n", " ").replace("  ", " ")
+          or "'goal-event' + (event.kind == 'comment' ? ' footnote' : '')" in goal_page,
+          "the WHOLE comment event row carries .footnote (badge included)")
+    check("'badge badge-goal-' + event.kind" in goal_page,
+          "non-comment events keep their full-weight kind badges")
+    css = open(os.path.join(REPO, "src/pages/app.css")).read()
+    check(".goal-event.footnote" in css and ".footnote {" in css,
+          "the stylesheet ships the footnote row weight beside the utility")
+
+    print("== C2: system rows render distinctly on the ONE thread ==")
+    run_comments = task_state(auth, run_task)["comments"]
+    system_rows = [c for c in run_comments if c.get("is_system")]
+    check(system_rows and all(c["author"] == "system" for c in system_rows)
+          and not any(c.get("from_agent") for c in system_rows),
+          "the harness bookkeeping rows are authored 'system' (never agent)")
+    goal_thread = goal_state(goal)["comments"]
+    check(any(c.get("is_system") for c in goal_thread),
+          "the goal page reads the same thread (the system rows included)")
+    css = open(os.path.join(REPO, "src/pages/app.css")).read()
+    check(".comment.system" in css and ".system-label" in css,
+          "the stylesheet ships the distinct system-event styling")
+    page = http_get_page(auth, "/goals/%d" % goal)
+    check("comment.is_system" in page and "system-label" in page,
+          "the goal page renders system rows with the labelled muted style")
+    task_page = http_get_page(auth, "/tasks/%d" % worker)
+    check("comment.is_system" in task_page and "system-label" in task_page,
+          "the task page renders system rows with the same style")
+
+    print("== S5 U2: mechanical rows filtered from user-facing timelines ==")
+    # The daemon's mechanical system entries (the park notice, the
+    # restore footnote) ride the wire typed 'system': the raw terminal
+    # row STORES (session_commands), but no comment row, narrative
+    # event or dashboard timeline row is authored for them.
+    open_run = open_session(run_task)
+    mechanical = [
+        {"id": 9501, "command": "saddle suspend",
+         "output": "goal agent parked until an owned task completes or"
+                   " fails; resume via /start resume_notice",
+         "exit_code": 0, "type": "system", "timestamp": "2026-09-12T00:00:00Z"},
+        {"id": 9502, "command": "harness resume",
+         "output": "[harness] session context restored — task resumed",
+         "exit_code": 0, "type": "system", "timestamp": "2026-09-12T00:00:01Z"},
+    ]
+    status, _ = saddle_api("POST", "/api/saddle/results", fake_token,
+                           {"session_id": open_run, "state": "suspended",
+                            "entries": mechanical})
+    check(status == 200, "the mechanical system entries push cleanly")
+    conn = db()
+    raw_rows = conn.execute(
+        "select count(*) from session_commands where session_id = ?"
+        " and type = 'system'", (open_run,)).fetchone()[0]
+    conn.close()
+    check(raw_rows >= 2,
+          "the raw terminal keeps the mechanical rows (typed entries store)")
+    check(all("parked until" not in c["body"]
+              and "session context restored" not in c["body"]
+              for c in task_state(auth, run_task)["comments"]),
+          "no mechanical comment row lands on the thread (U2)")
+    check(all("parked until" not in e["text"]
+              and "session context restored" not in e["text"]
+              for e in goal_state(goal)["events"]),
+          "no mechanical narrative event lands on the goal page (U2)")
+    dash_events = slot_public(auth, "/", "dashboard")["activity"]
+    check(all("parked until" not in e["text"]
+              and "session context restored" not in e["text"]
+              for e in dash_events),
+          "no mechanical row lands on the dashboard timeline (U2)")
+
+    print("== C4: head line, answered-blocks expander, footnote comments ==")
+    state = goal_state(goal)
+    check(state["current_activity"] == "parked awaiting its tasks' terminal transitions",
+          "a suspended run folds into the one muted head line")
+    check(len(state.get("answered_blocks") or []) >= 2
+          and len(state.get("open_blocks") or []) == 0,
+          "the historic answered blocks expose as their own vector (open ones empty)")
+    goal_page = http_get_page(auth, "/goals/%d" % goal)
+    check("Answered blocks (" in goal_page and "comment-meta" in goal_page,
+          "the answered blocks and the footnote comment meta ship in the markup")
+    check("timeless note for a future reader" in goal_page,
+          "the composer hint states the timeless-comment rule")
+    css = open(os.path.join(REPO, "src/pages/app.css")).read()
+    check(".goal-page .card { margin-bottom" in css and ".comment-meta" in css,
+          "the stylesheet ships the card rhythm and the comment footnote meta")
+
+    print("== C1: one review block per verdict path (F6) ==")
+    # The daemon's honest round pushes the ENTRY and the STATE
+    # together — the done pair must raise exactly ONE completion
+    # block, and a redelivered pair nothing more.
+    fake.goal_script = [("done", "# Completion\n\nOne block only.")]
+    conn = db()
+    conn.execute("insert into tasks (project_id, goal_id, kind, title, status,"
+                 " priority, completed_at, created_at) values (1, ?, 'task',"
+                 " 'Warmup', 'done', 5,"
+                 " strftime('%s','now'),"
+                 " strftime('%s','now','-30 seconds'))", (goal,))
+    conn.commit()
+    conn.close()
+    check(wait_for(lambda: goal_state(goal)["status"] == "completion_review" or False,
+                   timeout=60, what="goalui completion review opens") is not None,
+          "the scripted done round enters completion review")
+    def completion_block_count():
+        conn = db()
+        try:
+            return conn.execute(
+                "select count(*) from task_blocks where task_id = ?"
+                " and type = 'completion'", (run_task,)).fetchone()[0]
+        finally:
+            conn.close()
+    check(completion_block_count() == 1,
+          "the done state raises exactly ONE completion block")
+    # Plan 16 S5 (U1): the verdict-shaped block renders the rich review
+    # form — explicit accept/reject affordances with the free-text
+    # feedback path, never a free-text-only verdict.
+    goal_page = http_get_page(auth, "/goals/%d" % goal)
+    check("Accept goal" in goal_page and "Reject with feedback" in goal_page
+          and 'name="feedback"' in goal_page,
+          "the completion review presents explicit accept/reject + free-text feedback (U1)")
+    # The burst shape: the done ENTRY and the done STATE in one push
+    # (fresh entry ids), then the whole pair redelivered — the
+    # pending-report idempotency leaves the one row alone.
+    conn = db()
+    burst_session = conn.execute(
+        "select id from sessions where task_id = ? and ended_at is null",
+        (run_task,)).fetchone()[0]
+    conn.close()
+    done_pair = [{"id": 9401, "command": "saddle done",
+                  "output": "# Completion\n\nOne block only.", "exit_code": 0,
+                  "type": "done", "timestamp": "2026-09-12T00:00:00Z"}]
+    status, _ = saddle_api("POST", "/api/saddle/results", fake_token,
+                           {"session_id": burst_session, "state": "done",
+                            "entries": done_pair,
+                            "summary": "# Completion\n\nOne block only."})
+    check(status == 200 and completion_block_count() == 1,
+          "the done entry + state pair raises nothing more (one block, ever)")
+    state = goal_state(goal)
+    act(auth, state["completion_pending_block"]["answer_action"],
+        {"verdict": "accept"})
+    check(wait_for(lambda: goal_state(goal)["status"] == "complete" or False,
+                   timeout=30, what="goalui goal completes") is not None,
+          "accepting the completion completes the goal")
+    check(completion_block_count() == 1,
+          "the accept path leaves exactly one review-kind block behind")
+    conn = db()
+    stragglers = conn.execute(
+        "select count(*) from task_blocks where task_id = ? and answer is null",
+        (run_task,)).fetchone()[0]
+    conn.close()
+    check(stragglers == 0,
+          "no unanswered straggler rows survive the completion")
+
+    print("== S2: server-owned verdicts + the container-resolved reject ==")
+    # A fresh goal drives the verdict paths the goal page's forms now
+    # use: verdict markers for accept, raw `feedback` for reject, and
+    # the block resolution living in the review CONTAINER (not
+    # goal.plan_pending_block — the diagnosed completion-review bug).
+    fake.goal_script = [("plan", "# S2 plan\n\nOne step")]
+    act(auth, slot_public(auth, "/goals", "goals")["create"], {
+        "project_id": "1", "title": "S2 verdict goal",
+        "brief": "Covers the plan-16 S2 verdict paths.",
+        "branch_name": "goal/s2-verdicts"})
+    conn = db()
+    s2_goal = int(conn.execute(
+        "select id from goals where title = 'S2 verdict goal'").fetchone()[0])
+    conn.close()
+    act(auth, goal_state(s2_goal)["start"], {})
+    check(wait_for(lambda: goal_state(s2_goal)["status"] == "plan_review" or False,
+                   timeout=90, what="S2 goal enters plan review") is not None,
+          "the S2 goal enters plan review")
+    s2_state = goal_state(s2_goal)
+    s2_pending = s2_state["plan_pending_block"]
+
+    # (1) A remark-less, text-less rejection is refused: the action
+    # errors and the block keeps waiting.
+    refusal = act(auth, s2_pending["answer_action"], {"feedback": "   "})
+    check(any(d.get("type") == "notify" and d.get("kind") == "error"
+              and "answer is required" in (d.get("message") or "").lower()
+              for d in refusal),
+          "a remark-less, text-less rejection is refused with an error")
+    conn = db()
+    s2_still_open = conn.execute(
+        "select answer from task_blocks where id = ?",
+        (s2_pending["id"],)).fetchone()[0]
+    conn.close()
+    check(s2_still_open is None,
+          "the refused rejection leaves the block unanswered")
+
+    # (3) The goal page template ships no verdict constants and its
+    # script resolves the review block from ANY [data-plan-review]
+    # container via the open-blocks list (the completion-review fix).
+    # Fetched while the review is open so the accept form renders.
+    s2_page = http_get_page(auth, "/goals/%d" % s2_goal)
+    check("Plan approved. Proceed with implementation." not in s2_page
+          and "Review approved. Continue with the task." not in s2_page,
+          "the goal page ships no verdict constants (server-owned wording)")
+    check('name="verdict" value="accept"' in s2_page,
+          "the goal page's accept forms post the verdict marker")
+    check("resolveReviewBlock" in s2_page and "goal.open_blocks" in s2_page,
+          "the reject flow resolves its block from the open-blocks list (container-keyed)")
+    check("statum.act(block.answer_action, { feedback: feedback })" in s2_page,
+          "the reject flow posts raw feedback (the server wraps the prefix)")
+    check("extraText.length === 0" in s2_page,
+          "a remark-less rejection with textarea content is allowed (S2)")
+
+    # (2) The goal page's reject rides `feedback` (the client composes
+    # the numbered-remarks body) and the SERVER wraps it with the plan
+    # prefix — byte-identical to the historical client-built answer.
+    act(auth, s2_pending["answer_action"],
+        {"feedback": "> ## One step\n\n1. Tighten it\n\n2. Name the owner"})
+    conn = db()
+    s2_wrapped = conn.execute(
+        "select answer from task_blocks where id = ?",
+        (s2_pending["id"],)).fetchone()[0]
+    conn.close()
+    check(s2_wrapped
+          == "Plan feedback received:\n\n"
+             "> ## One step\n\n1. Tighten it\n\n2. Name the owner",
+          "the plan rejection wraps the client-shaped body with the stable prefix (%r)"
+          % s2_wrapped)
+    check(goal_state(s2_goal)["status"] == "planning",
+          "the feedback rejection returns the agent to planning")

+ 680 - 0
test/bundles/lifecycle.py

@@ -0,0 +1,680 @@
+"""The lifecycle bundle (moved verbatim from the pre-split web_stack_test.py;
+see test/harness.py for the shared machinery and the runner)."""
+from harness import *  # noqa: F401,F403 — the shared wire helpers
+
+
+# =============================================================================
+# Bundle: lifecycle — offline requeues, the hung-request tick survival,
+# parked-refresh bookkeeping, cancellation, the health panel, raw-log
+# losslessness, git identity and the live blocked-push roundtrip.
+# =============================================================================
+
+def run(ctx):
+    auth, fake, fake_id, fake_token = ctx.auth, ctx.fake, ctx.fake_id, ctx.fake_token
+    app = ctx.app
+
+    print("== plan 11: draft state machine, edit matrix, enqueue/delete guards ==")
+    # New tasks default to draft; Enqueue is the only path to the
+    # queue (there is no agent path — the ingest API refuses to queue).
+    act(auth, slot_public(auth, "/tasks", "tasks")["create"], {
+        "project_id": "1",
+        "title": "Draft lifecycle task",
+        "priority": "4",
+    })
+    draft_task = int([t["id"] for t in slot_public(auth, "/tasks", "tasks")["tasks"]
+                      if t["title"] == "Draft lifecycle task"][0])
+    detail = task_state(auth, draft_task)
+    check(detail["status"] == "draft", "a created task lands in draft")
+    check(detail.get("enqueue") is not None and detail.get("delete") is not None,
+          "draft exposes the enqueue + delete actions")
+    check(detail.get("cancel") is not None, "the cancel action stays authored")
+    status, page = http("GET", "/tasks/%d" % draft_task, timeout=15)
+    check(status == 200 and "Enqueue task" in page and ">Delete<" in page,
+          "the task page shows Enqueue + Delete in draft")
+    check("Mark done" not in page,
+          "the user Mark-complete action is gone (agent-only completion)")
+    # Plan 12: the auto-enqueue-after predecessor REPLACES draft
+    # dependencies — setting it is allowed while the predecessor is
+    # still pending (the enqueue itself succeeds; the DISPATCHER holds
+    # dispatch back until the predecessor is done).
+    act(auth, slot_public(auth, "/tasks", "tasks")["create"], {
+        "project_id": "1",
+        "title": "Draft dependency",
+        "priority": "4",
+    })
+    draft_dep = int([t["id"] for t in slot_public(auth, "/tasks", "tasks")["tasks"]
+                     if t["title"] == "Draft dependency"][0])
+    act(auth, detail["update"], {"enqueue_after_task_id": str(draft_dep)})
+    check(int(task_state(auth, draft_task).get("enqueue_after_task_id") or 0)
+          == draft_dep,
+          "the draft edit sets the auto-enqueue predecessor")
+    act(auth, slot_public(auth, "/tasks", "tasks")["create"], {
+        "project_id": "1", "title": "Eager dependent", "priority": "4",
+        "enqueue_after_task_id": str(draft_dep)})
+    eager = task_id_of("Eager dependent")
+    enqueue_task(auth, eager)
+    check(task_state(auth, eager)["status"] == "queued",
+          "enqueue succeeds while the predecessor is pending (no draft guard)")
+    check(quiet_window(quiet_seconds(),
+                       lambda: task_state(auth, eager)["status"] == "queued",
+                       "pending predecessor holds dispatch"),
+          "the pending predecessor holds dispatch back (never assigned)")
+    # The edit matrix starts in DRAFT: every field except status.
+    act(auth, detail["update"], {
+        "title": "Draft lifecycle task (edited)",
+        "description": "Now with a description",
+        "priority": "2",
+        "task_branch": "feature/draft",
+        "branch_from": "main",
+        "mode": "investigate",
+    })
+    detail = task_state(auth, draft_task)
+    check(detail["title"] == "Draft lifecycle task (edited)"
+          and detail["description"] == "Now with a description"
+          and detail["priority"] == 2
+          and detail["task_branch"] == "feature/draft"
+          and detail["branch_from"] == "main"
+          and detail["mode"] == "investigate",
+          "draft edits apply to every field (incl. the mode)")
+    # Clear the predecessor (the empty sentinel): dispatch gates on
+    # the hold tag alone now.
+    act(auth, detail["update"], {"enqueue_after_task_id": "0"})
+    check(not int(task_state(auth, draft_task).get("enqueue_after_task_id") or 0),
+          "the draft edit clears the auto-enqueue predecessor")
+    # A hold tag nothing carries keeps the dependent QUEUED (never
+    # dispatched) through the remaining edit-matrix checks.
+    saddles_state = slot_public(auth, "/saddles", "saddles")
+    act(auth, saddles_state["create_capability"], {"name": "holdlock"})
+    holdlock_cap = int([c["id"] for c in slot_public(auth, "/saddles", "saddles")["capabilities"]
+                        if c["name"] == "holdlock"][0])
+    act(auth, detail["attach_capability"], {"capability_id": str(holdlock_cap)})
+    # Enqueue the now-cleared dependent: the hold tag keeps it queued
+    # (never dispatched), so the non-draft edit matrix applies.
+    enqueue_task(auth, draft_task)
+    check(quiet_window(3, lambda: task_state(auth, draft_task)["status"] == "queued",
+                       "held dependent stays queued"),
+          "the held dependent stays queued (never dispatched)")
+    # The predecessor settles for the shard drain.
+    enqueue_task(auth, draft_dep)
+    check(wait_task_done(auth, draft_dep, timeout=90) is not None,
+          "the predecessor settles")
+
+    # Drafts are never dispatched even with an idle saddle available.
+    act(auth, slot_public(auth, "/tasks", "tasks")["create"], {
+        "project_id": "1",
+        "title": "Never-dispatched draft",
+        "priority": "1",
+    })
+    silent_draft = int([t["id"] for t in slot_public(auth, "/tasks", "tasks")["tasks"]
+                        if t["title"] == "Never-dispatched draft"][0])
+    check(quiet_window(quiet_seconds(),
+                       lambda: task_state(auth, silent_draft)["status"] == "draft",
+                       "draft never dispatched"),
+          "an idle saddle never picks a draft up (no agent enqueue path)")
+
+    # Once work can begin (queued here), only priority is editable.
+    act(auth, detail["update"], {
+        "title": "Should not apply",
+        "priority": "3",
+    })
+    detail = task_state(auth, draft_task)
+    check(detail["title"] == "Draft lifecycle task (edited)" and detail["priority"] == 3,
+          "non-draft edits apply priority only (title locked)")
+    # A terminal task edits nothing.
+    conn = db()
+    conn.execute("update tasks set status = 'done', completed_at = strftime('%s','now')"
+                 " where id = ?", (draft_task,))
+    conn.commit()
+    conn.close()
+    act(auth, task_state(auth, draft_task)["update"], {"priority": "8"})
+    check(task_state(auth, draft_task)["priority"] == 3,
+          "terminal tasks edit nothing (priority locked)")
+    # Capabilities lock once a worker has the job: editable while
+    # queued, locked once working.
+    act(auth, saddles_state["create_capability"], {"name": "editlock"})
+    editlock_cap = int([c["id"] for c in slot_public(auth, "/saddles", "saddles")
+                        ["capabilities"] if c["name"] == "editlock"][0])
+    act(auth, saddle_card(auth, "fake-saddle")["attach_capability"],
+        {"capability_id": str(editlock_cap)})
+    locked_task = create_queued(auth, {"project_id": "1", "title": "Caplock task",
+                                       "priority": "2"})
+    detail = task_state(auth, locked_task)
+    act(auth, detail["attach_capability"], {"capability_id": str(editlock_cap)})
+    check(wait_for(lambda: any(c["name"] == "editlock"
+                               for c in task_state(auth,
+                                                   locked_task)["capabilities"])
+                   or False, timeout=60, what="editlock attached") is not None,
+          "capabilities attach while queued (no worker yet)")
+    check(wait_for(lambda: task_state(auth, locked_task).get("status") == "working"
+                   or False, timeout=60, what="caplock working") is not None,
+          "the caplock task reaches working")
+    detach_directives = act(auth, task_state(auth, locked_task)["capabilities"][0]["detach"], {})
+    check(any(d.get("type") == "notify" and d.get("kind") == "error"
+              for d in detach_directives),
+          "capabilities are locked once a worker has the job")
+    # The ingest API has no queue transition either (only working and
+    # blocked are accepted states).
+    conn = db()
+    caplock_session = conn.execute(
+        "select id from sessions where task_id = ? and ended_at is null",
+        (locked_task,)).fetchone()
+    conn.close()
+    if caplock_session is not None:
+        status, _ = saddle_api("POST", "/api/saddle/results", fake_token,
+                               {"session_id": caplock_session[0],
+                                "state": "queued"})
+        check(status == 200
+              and task_state(auth, locked_task)["status"] in ("working", "done"),
+              "a queued state push is a no-op (only the wire's states drive bookkeeping)")
+
+    # Delete guards: a clean draft deletes; non-draft refuses; a draft
+    # with dependents is refused naming them.
+    act(auth, task_state(auth, silent_draft)["delete"], {})
+    check(not any(t["id"] == silent_draft
+                  for t in slot_public(auth, "/tasks", "tasks")["tasks"]),
+          "a clean draft task deletes")
+    delete_directives = act(auth, task_state(auth, draft_task)["delete"], {})
+    check(any(d.get("type") == "notify" and d.get("kind") == "error"
+              for d in delete_directives),
+          "a non-draft task refuses the delete")
+    act(auth, slot_public(auth, "/tasks", "tasks")["create"], {
+        "project_id": "1", "title": "Guarded draft", "priority": "4"})
+    guarded = int([t["id"] for t in slot_public(auth, "/tasks", "tasks")["tasks"]
+                   if t["title"] == "Guarded draft"][0])
+    act(auth, slot_public(auth, "/tasks", "tasks")["create"], {
+        "project_id": "1", "title": "Dependent namer", "priority": "4"})
+    namer = int([t["id"] for t in slot_public(auth, "/tasks", "tasks")["tasks"]
+                 if t["title"] == "Dependent namer"][0])
+    act(auth, task_state(auth, namer)["update"],
+        {"enqueue_after_task_id": str(guarded)})
+    check(int(task_state(auth, namer).get("enqueue_after_task_id") or 0) == guarded,
+          "the namer points at the guarded predecessor")
+    act(auth, task_state(auth, guarded)["delete"], {})
+    check(not any(t["id"] == guarded
+                  for t in slot_public(auth, "/tasks", "tasks")["tasks"]),
+          "deleting a predecessor succeeds")
+    check(not int(task_state(auth, namer).get("enqueue_after_task_id") or 0),
+          "the delete clears the dependent's dangling predecessor reference")
+
+    print("== offline requeues ==")
+    # Tasks caught working on a saddle that went offline requeue with a
+    # agent comment each tick.
+    task_id_tmp = create_queued(auth, {
+        "project_id": "1",
+        "title": "Offline saddle task",
+        "priority": "2",
+    })
+    offline_task = task_id_tmp
+    check(wait_for(lambda: task_state(auth, offline_task).get("status") == "working"
+                   or False, timeout=60, what="offline task starts working") is not None,
+          "task reaches working before its saddle disappears")
+    # Hold the daemon mid-round across the requeue window (the
+    # original relied on its 8s work period outlasting the 5s tick):
+    # the task completing on its own would race the offline pass and
+    # skip the requeue the check exists to observe.
+    fake.hold_state = True
+    conn = db()
+    conn.execute("update saddles set status = 'offline' where name = 'fake-saddle'")
+    conn.commit()
+    conn.close()
+    # The requeue frees the saddle in the same tick, so 'queued' is
+    # transient; the durable evidence is the agent comment (and the task
+    # completing again on the healthy daemon).
+    check(wait_for(lambda: any(c["body"] == "saddle went offline; task requeued"
+                               for c in task_state(auth, offline_task).get("comments", []))
+                   or False, timeout=30, what="offline requeue comment") is not None,
+          "offline saddle requeues the task")
+    fake.hold_state = False  # release: the round ends, the daemon re-asks
+    check(wait_task_done(auth, offline_task, timeout=60) is not None,
+          "requeued task completes again on the healthy daemon")
+    # R2 (arch 13): the release owner's outcomes — the requeue closed
+    # the held attempt's session 'stopped'; the held daemon's terminal
+    # push then completes the task against that closed session (the
+    # outcome stands — a closed row never reopens). A task that
+    # completes a LIVE round closes its session 'done' (draft_dep
+    # above ran one open session to its terminal push).
+    conn = db()
+    outcome_rows = conn.execute(
+        "select outcome from sessions where task_id = ? order by id",
+        (offline_task,)).fetchall()
+    dep_outcome = conn.execute(
+        "select outcome from sessions where task_id = ? order by id desc",
+        (draft_dep,)).fetchone()
+    conn.close()
+    check(outcome_rows and outcome_rows[0][0] == "stopped",
+          "the one release path closes the requeued attempt 'stopped'")
+    check(dep_outcome is not None and dep_outcome[0] == "done",
+          "the terminal push closes a live round's session 'done'")
+
+    print("== R6 F1: a hanging request cannot freeze the tick ==")
+    # One wedged /task-update (never responds) blocks the comment/
+    # subtask-event delivery pass; the Soup timeout must fail it and
+    # later ticks keep dispatching.
+    conn = db()
+    conn.execute("insert into tasks (project_id, title, status, priority, created_at)"
+                 " values (1, 'Hang survivor', 'queued', 2, strftime('%s','now'))")
+    hang_task = conn.execute("select max(id) from tasks").fetchone()[0]
+    conn.close()
+    task_id_tmp = create_queued(auth, {
+        "project_id": "1",
+        "title": "Hang runner",
+        "priority": "3",
+    })
+    hang_runner = task_id_tmp
+    # A human comment on the running task gives the tick a
+    # /task-update delivery to make; the next one hangs.
+    check(wait_for(lambda: task_state(auth, hang_runner).get("status") == "working"
+                   or False, timeout=60, what="hang runner working") is not None,
+          "hang runner reaches working")
+    act(auth, task_state(auth, hang_runner)["comment"],
+        {"body": "operator ping while wedged"})
+    fake.hang_next["/task-update"] = 1
+    check(wait_task_done(auth, hang_runner, timeout=90) is not None,
+          "dispatching task survives a hung daemon request")
+    check(wait_for(lambda: any(c.get("text") == "operator ping while wedged"
+                               or c.get("body") == "operator ping while wedged"
+                               for c in fake.comment_log) or False,
+                   timeout=30, what="wedged comment eventually delivered") is not None,
+          "the comment delivery retries after the hang")
+    # The hung delivery itself fails after the timeout; the system
+    # kept moving either way.
+    with open(os.path.join(WORK, "app.log")) as handle:
+        app_log = handle.read()
+    check("tick exceeded" not in app_log or "Dispatch tick failed" in app_log,
+          "a hung request never freezes the tick latch")
+
+    print("== R6 F2: refresh must not corrupt parked bookkeeping ==")
+    fake.suspend_on_title = "Parked refresh parent"
+    task_id_tmp = create_queued(auth, {
+        "project_id": "1",
+        "title": "Parked refresh parent",
+        "priority": "2",
+    })
+    parked = task_id_tmp
+    check(wait_for(lambda: task_state(auth, parked).get("status") == "suspended"
+                   or False, timeout=60, what="parked parent suspends") is not None,
+          "parent parks before the refresh")
+    fake_card = saddle_card(auth, "fake-saddle")
+    act(auth, fake_card["refresh"], {})
+    fake_card = saddle_card(auth, "fake-saddle")
+    check(fake_card["status"] == "idle" and int(fake_card["current_task_id"] or 0) == 0,
+          "refresh on a parked (suspended) daemon leaves the saddle idle")
+    # The parked task keeps its open session and stays put: plain
+    # tasks have no subtask events to resume them (the goal machinery
+    # owns resumes); the human resumes it explicitly.
+    check(quiet_window(quiet_seconds(),
+                       lambda: task_state(auth, parked)["status"] == "suspended",
+                       "parked task stays parked"),
+          "a parked plain task stays parked after the refresh (no resume channel)")
+    act(auth, task_state(auth, parked)["cancel"], {})
+    check(wait_for(lambda: task_state(auth, parked)["status"] == "failed" or False,
+                   timeout=30, what="parked task cancelled") is not None,
+          "the parked task cancels cleanly after the refresh")
+
+    print("== R7 B1: cancel reaches the daemon ==")
+    # Plan 10 phase 2: cancellation is POST /task-update {kind: cancel}
+    # to the RUNNING daemon (the abort machinery, workspace kept).
+    task_id_tmp = create_queued(auth, {
+        "project_id": "1",
+        "title": "Cancel live",
+        "priority": "2",
+    })
+    cancel_live = task_id_tmp
+    check(wait_for(lambda: task_state(auth, cancel_live).get("status") == "working"
+                   or False, timeout=60, what="cancel-live working") is not None,
+          "task reaches working before the cancel")
+    act(auth, task_state(auth, cancel_live)["cancel"], {})
+    check(wait_for(lambda: cancel_live in fake.abort_log or False,
+                   timeout=30, what="daemon abort recorded") is not None,
+          "cancelling POSTs task-update cancel to the daemon")
+    check(any(c["body"] == "cancelled; daemon aborted"
+              for c in task_state(auth, cancel_live).get("comments", [])),
+          "the abort outcome is narrated")
+    check(task_state(auth, cancel_live)["status"] == "failed",
+          "cancelled task lands failed as before")
+
+    # A 500 on the cancel marks the saddle offline (no fence layer
+    # anymore); nothing dispatches to it while offline, and the
+    # daemon's own ask flips the row back to idle (proof of life).
+    task_id_tmp = create_queued(auth, {
+        "project_id": "1",
+        "title": "Fence runner",
+        "priority": "2",
+    })
+    fence_runner = task_id_tmp
+    check(wait_for(lambda: task_state(auth, fence_runner).get("status") == "working"
+                   or False, timeout=60, what="fence runner working") is not None,
+          "second task reaches working")
+    fake.abort_failures = 1
+    act(auth, task_state(auth, fence_runner)["cancel"], {})
+    check(any(c["body"] == "cancelled; daemon unreachable — saddle marked offline"
+              for c in task_state(auth, fence_runner).get("comments", [])),
+          "failed cancel narrates the offline marking")
+    check(saddle_card(auth, "fake-saddle")["status"] == "offline",
+          "saddle marked offline after the failed cancel")
+    task_id_tmp = create_queued(auth, {
+        "project_id": "1",
+        "title": "During fence",
+        "priority": "3",
+    })
+    during_fence = task_id_tmp
+    # Converted sleep(7): a quiet window spanning several dispatch
+    # ticks in which the task MUST stay queued — if the offline
+    # saddle ever dispatches it, this fails loudly. The daemon is held
+    # mid-round for the window (the original relied on its 8s work
+    # period outlasting the sleep): a finishing round would ask, prove
+    # liveness and flip the offline row — only after the window may it.
+    fake.hold_state = True
+    check(quiet_window(quiet_seconds(),
+                       lambda: task_state(auth, during_fence)["status"] == "queued",
+                       "offline saddle does not dispatch during_fence"),
+          "offline saddle is not dispatchable")
+    fake.hold_state = False
+    # The (unaborted) daemon finishes its round, goes idle-awake and
+    # asks — the ask is the proof of life that flips the row back.
+    check(wait_for(lambda: saddle_card(auth, "fake-saddle")["status"] == "idle" or False,
+                   timeout=30, what="ask flips offline to idle") is not None,
+          "the daemon's ask flips the offline row back to idle")
+    check(wait_task_done(auth, during_fence, timeout=60) is not None,
+          "queued work dispatches once the saddle proves it is alive")
+
+    print("== R7 B3: health panel + pushed raw log from the first round ==")
+    # A normally dispatched task pushes its chunks immediately: raw
+    # rows exist from the first round (the session-4 gap stays
+    # fixed without any probe machinery).
+    task_id_tmp = create_queued(auth, {
+        "project_id": "1",
+        "title": "Raw from first push",
+        "priority": "2",
+    })
+    raw_first = task_id_tmp
+
+    def raw_count(task_id):
+        conn = db()
+        try:
+            return conn.execute(
+                "select count(*) from session_raw_log where session_id in"
+                " (select id from sessions where task_id = ?)", (task_id,)).fetchone()[0]
+        finally:
+            conn.close()
+
+    check(wait_for(lambda: raw_count(raw_first) > 0 or False,
+                   timeout=60, what="raw rows from first push") is not None,
+          "pushed chunks land from the first round (session-4 gap)")
+    check(wait_task_done(auth, raw_first, timeout=60) is not None,
+          "raw-first task completes")
+
+    # Health panel: a manual refresh populates the snapshot.
+    fake_card = saddle_card(auth, "fake-saddle")
+    act(auth, fake_card["refresh"], {})
+    card = saddle_card(auth, "fake-saddle")
+    check(card.get("health") in ("healthy", "stale")
+          and card.get("daemon_state") in ("working", "idle", "done")
+          and card.get("uptime_display", "") != ""
+          and card.get("last_contact_display", "") not in ("", "never"),
+          "saddles page shows daemon state, uptime and last contact")
+
+    print("== R8: pushed chunk ingestion is lossless ==")
+    # The daemon's opening flush: a coloured prompt run, plain text,
+    # a bare CRLF between prompts and the tail — every non-empty
+    # chunk must land, exactly once, in seq order. A mid-flight
+    # redelivery of the whole batch (the outbox's at-least-once
+    # retry) consumes the duplicates.
+    corpus = [
+        {"seq": 1, "text": "\x1b[01;32muser@host\x1b[00m:\x1b[01;34m~/task-1\x1b[00m$ "},
+        {"seq": 2, "text": "echo hello\r\n"},
+        {"seq": 3, "text": "\r\n"},
+        {"seq": 4, "text": "hello\r\n"},
+        {"seq": 5, "text": "\x1b[01;32muser@host\x1b[00m:\x1b[01;34m~/task-1\x1b[00m$ "},
+        {"seq": 6, "text": "done\r\n"},
+    ]
+    fake.scripted_corpus = corpus
+    fake.hold_state = True
+    task_id_tmp = create_queued(auth, {
+        "project_id": "1",
+        "title": "Lossless log task",
+        "priority": "2",
+    })
+    lossless = task_id_tmp
+
+    def stored_seqs(task_id):
+        conn = db()
+        try:
+            return [r[0] for r in conn.execute(
+                "select seq from session_raw_log where session_id in"
+                " (select id from sessions where task_id = ?)"
+                " order by seq", (task_id,))]
+        finally:
+            conn.close()
+
+    check(wait_for(lambda: task_state(auth, lossless).get("status") == "working"
+                   or False, timeout=60, what="lossless task working") is not None,
+          "lossless task dispatches and pushes its opening flush")
+    check(wait_for(lambda: stored_seqs(lossless) == [1, 2, 3, 4, 5, 6] or False,
+                   timeout=30, what="all six chunks stored") is not None,
+          "every pushed chunk lands in session_raw_log, CRLF-only included (%s)"
+          % stored_seqs(lossless))
+    status, _ = saddle_api("POST", "/api/saddle/chunks", fake.token,
+                           {"session_id": fake.session_id,
+                            "chunks": [dict(chunk) for chunk in corpus]})
+    check(status == 200 and stored_seqs(lossless) == [1, 2, 3, 4, 5, 6],
+          "a full-batch redelivery stores nothing new (exactly-once)")
+    request = urllib.request.Request(
+        WEB + "/terminal-stream/%d" % [r[0] for r in db().execute(
+            "select id from sessions where task_id = ?", (lossless,))][0])
+    with urllib.request.urlopen(request, timeout=15) as stream:
+        texts = []
+        deadline = time.monotonic() + 8
+        while time.monotonic() < deadline and len(texts) < 6:
+            line = stream.readline().decode().strip()
+            if not line.startswith("data: ") or line == "data: ping":
+                continue
+            event = json.loads(line[6:])
+            if event.get("type") == "raw":
+                texts.append(event.get("text") or "")
+        check("\r\n" in texts and len(texts) == 6,
+              "SSE serves the whitespace chunk unfiltered")
+    fake.hold_state = False
+    fake.scripted_corpus = None
+    check(wait_task_done(auth, lossless, timeout=60) is not None,
+          "lossless task completes")
+
+    print("== R9 B1/B2: git identity + ssh key ==")
+    # The key travels on /status into the saddle row and the page view
+    # (the manual refresh's exceptional probe).
+    fake.ssh_public_key = "ssh-ed25519 AAAAC3NzaC1lZDI1teStKey saddle-1@fedora"
+    fake_card = saddle_card(auth, "fake-saddle")
+    check(fake_card.get("ssh_public_key", "") == "",
+          "no key shown before the daemon reports one")
+    act(auth, fake_card["refresh"], {})
+    check(wait_for(lambda: "AAAAC3NzaC1lZDI1teStKey" in
+                   saddle_card(auth, "fake-saddle").get("ssh_public_key", "") or False,
+                   timeout=30, what="key lands on the row") is not None,
+          "reported ssh_public_key persists onto the saddle row")
+    conn = db()
+    row_key = conn.execute("select ssh_public_key from saddles where name = 'fake-saddle'"
+                           ).fetchone()[0]
+    conn.close()
+    check(row_key == fake.ssh_public_key,
+          "the key is stored verbatim in the database")
+
+    # Identity edit flows through the UI into the assignment payload.
+    fake_card = saddle_card(auth, "fake-saddle")
+    act(auth, fake_card["update_identity"],
+        {"git_name": "clanker-bot", "git_email": "bot@unitatem.net"})
+    fake_card = saddle_card(auth, "fake-saddle")
+    check(fake_card.get("git_name") == "clanker-bot"
+          and fake_card.get("git_email") == "bot@unitatem.net",
+          "inline edit saves the git identity")
+
+    task_id_tmp = create_queued(auth, {
+        "project_id": "1",
+        "title": "Identity task",
+        "priority": "2",
+    })
+    identity_task = task_id_tmp
+    check(wait_for(lambda: any(int(p.get("task", {}).get("id") or 0) == identity_task
+                               for p in fake.start_payloads) or False,
+                   timeout=60, what="identity task dispatched") is not None,
+          "identity task dispatches")
+    payload = [p for p in fake.start_payloads
+               if int(p.get("task", {}).get("id") or 0) == identity_task][-1]
+    identity = payload.get("git_identity") or {}
+    check(identity.get("name") == "clanker-bot"
+          and identity.get("email") == "bot@unitatem.net",
+          "the assignment carries the saddle's git_identity")
+
+    # Earlier assignments (identity unset) carry no git_identity member.
+    check(all("git_identity" not in p for p in fake.start_payloads[:-1]),
+          "unset identity omits the member (daemon fallback applies)")
+
+    # Clearing the identity omits it from later assignments.
+    fake_card = saddle_card(auth, "fake-saddle")
+    act(auth, fake_card["update_identity"], {"git_name": "", "git_email": ""})
+    check(saddle_card(auth, "fake-saddle").get("git_name", "") == "",
+          "clearing the identity empties the row")
+    check(wait_task_done(auth, identity_task, timeout=60) is not None,
+          "identity task completes")
+
+    print("== phase 2: blocked push -> block row + pulse ==")
+    # The browser flow on each pulse: statum.act(task.refresh) — the
+    # sealed GET action must rehydrate the task slot with the new
+    # block the daemon just PUSHED (state blocked + block payload).
+    task_id_tmp = create_queued(auth, {
+        "project_id": "1",
+        "title": "Live block task",
+        "priority": "2",
+    })
+    live_task = task_id_tmp
+    check(wait_for(lambda: task_state(auth, live_task).get("status") == "working"
+                   or False, timeout=60, what="live task working") is not None,
+          "live-block task reaches working")
+    fake.hold_state = True
+    fake.state = "blocked"  # the daemon parks on its question
+    status = fake.push_results("blocked", block={
+        "question": "Pick one", "type": "question", "options": ["A", "B"]})
+    check(status == 200, "blocked state push accepted")
+    # The parked daemon is idle-awake: it asks (and sleeps on 204).
+    fake.maybe_trigger_ask("parked")
+    check(wait_for(lambda: any(b.get("question") == "Pick one"
+                               for b in task_state(auth, live_task).get("blocks", []))
+                   or False, timeout=30, what="block lands in state") is not None,
+          "the pushed block reaches the sealed refresh without a reload")
+    detail = task_state(auth, live_task)
+    check(detail.get("status") == "blocked",
+          "the blocked push flips the task to blocked")
+    pushed_block = [b for b in detail["blocks"] if b.get("question") == "Pick one"][0]
+    conn = db()
+    options_json = conn.execute(
+        "select options from task_blocks where id = ?", (int(pushed_block["id"]),)
+    ).fetchone()[0]
+    conn.close()
+    check(json.loads(options_json) == ["A", "B"],
+          "the block row carries its options payload")
+    check(any(s["status"] == "idle"
+              for s in slot_public(auth, "/saddles", "saddles")["saddles"]),
+          "the blocked push parks the saddle")
+    detail = task_state(auth, live_task)
+    check(detail.get("refresh") is not None,
+          "the sealed GET refresh action is still authored")
+    status, _ = http("GET", detail["refresh"]["uri"], timeout=15)
+    check(status in (200, 401),
+          "the refresh URI resolves as a GET (client roundtrip shape)")
+    act(auth, pushed_block["answer_action"], {"answer": "A"})
+    # The answer makes the parked task resume-offerable: the affine
+    # saddle is woken, asks, and its assignment carries the answer.
+    pushes_before = len([p for p in fake.start_payloads
+                         if int(p.get("task", {}).get("id") or 0) == live_task])
+    check(wait_for(lambda: len([p for p in fake.start_payloads
+                                if int(p.get("task", {}).get("id") or 0) == live_task])
+                   > pushes_before or False, timeout=60,
+                   what="blocked task resumes") is not None,
+          "answering the pushed block resumes the parked workspace")
+    fake.hold_state = False  # the resumed round runs to completion
+    resume_payload = [p for p in fake.start_payloads
+                      if int(p.get("task", {}).get("id") or 0) == live_task][-1]
+    answers = resume_payload.get("task", {}).get("answers", [])
+    check(any(a.get("answer") == "A" for a in answers),
+          "the resume assignment carries the human's answer")
+    check(wait_task_done(auth, live_task, timeout=60) is not None,
+          "live-block task completes after answering")
+
+    print("== R2: the one release path behind unregister ==")
+    # Arch 13: removing a saddle releases its held task through the
+    # same owner as every requeue — never an orphan open session on a
+    # deleted row. Route 1: a DEAD host — the abort delivery fails
+    # fast, the offline bookkeeping releases (queued + comment +
+    # session 'stopped'), the unregister then deletes the row.
+    saddles_state = slot_public(auth, "/saddles", "saddles")
+    act(auth, saddles_state["register"], {"name": "dead-host",
+                                          "host": "127.0.0.1:1"})
+    dead_card = [s for s in slot_public(auth, "/saddles", "saddles")["saddles"]
+                 if s["name"] == "dead-host"][0]
+    dead_id = int(dead_card["id"])
+    task_id_tmp = create_queued(auth, {
+        "project_id": "1",
+        "title": "Dead-host unregister task",
+        "priority": "2",
+    })
+    dead_task = task_id_tmp
+    conn = db()
+    conn.execute("update tasks set status = 'working' where id = ?",
+                 (dead_task,))
+    conn.execute("insert into sessions (task_id, saddle_id, started_at)"
+                 " values (?, ?, strftime('%s','now'))", (dead_task, dead_id))
+    conn.execute("update saddles set current_task_id = ? where id = ?",
+                 (dead_task, dead_id))
+    conn.commit()
+    dead_session = conn.execute(
+        "select id from sessions where task_id = ? and ended_at is null",
+        (dead_task,)).fetchone()[0]
+    conn.close()
+    act(auth, dead_card["unregister"], {})
+    conn = db()
+    dead_row = conn.execute("select status from tasks where id = ?",
+                            (dead_task,)).fetchone()
+    dead_session_row = conn.execute(
+        "select outcome, ended_at is not null from sessions where id = ?",
+        (dead_session,)).fetchone()
+    dead_saddle_count = conn.execute(
+        "select count(*) from saddles where id = ?", (dead_id,)).fetchone()[0]
+    conn.close()
+    check(dead_row is not None and dead_row[0] == "queued",
+          "unregister of a dead-host saddle releases the held task to the queue")
+    check(dead_session_row is not None and dead_session_row[0] == "stopped"
+          and dead_session_row[1],
+          "the offline release closes the held task's session 'stopped'")
+    check(dead_saddle_count == 0, "the dead-host saddle row is gone")
+
+    # Route 2: no open session on the saddle — the abort is a no-op
+    # and the unregister itself carries the release (the requeue flip
+    # through the one owner, the row deleted after).
+    saddles_state = slot_public(auth, "/saddles", "saddles")
+    act(auth, saddles_state["register"], {"name": "quiet-host",
+                                          "host": "127.0.0.1:%d" % fake.port})
+    quiet_card = [s for s in slot_public(auth, "/saddles", "saddles")["saddles"]
+                  if s["name"] == "quiet-host"][0]
+    quiet_id = int(quiet_card["id"])
+    task_id_tmp = create_queued(auth, {
+        "project_id": "1",
+        "title": "Quiet-host unregister task",
+        "priority": "2",
+    })
+    quiet_task = task_id_tmp
+    conn = db()
+    conn.execute("update tasks set status = 'working' where id = ?",
+                 (quiet_task,))
+    conn.execute("update saddles set current_task_id = ? where id = ?",
+                 (quiet_task, quiet_id))
+    conn.commit()
+    conn.close()
+    act(auth, quiet_card["unregister"], {})
+    conn = db()
+    quiet_row = conn.execute("select status from tasks where id = ?",
+                             (quiet_task,)).fetchone()
+    quiet_saddle_count = conn.execute(
+        "select count(*) from saddles where id = ?", (quiet_id,)).fetchone()[0]
+    conn.close()
+    check(quiet_row is not None and quiet_row[0] == "queued",
+          "unregister's own release returns the held task to the queue")
+    check(quiet_saddle_count == 0, "the quiet-host saddle row is gone")

+ 192 - 0
test/bundles/lineage.py

@@ -0,0 +1,192 @@
+"""The lineage bundle (moved verbatim from the pre-split web_stack_test.py;
+see test/harness.py for the shared machinery and the runner)."""
+from harness import *  # noqa: F401,F403 — the shared wire helpers
+
+
+# =============================================================================
+# Bundle: lineage — the plan-12 goal lineage: goal context on worker
+# dispatches (read-only reference + ephemeral branch), the daemon's
+# task-reading API (goal members, no parent/plan), and the goal
+# agent's workspace affinity while parked.
+# =============================================================================
+
+def run(ctx):
+    auth, fake, fake_id, fake_token = ctx.auth, ctx.fake, ctx.fake_id, ctx.fake_token
+    app = ctx.app
+    r4_token = fake_token
+    # gpu exists only as a hold (no saddle carries it): the held goal
+    # worker stays queued until the release loop lifts it.
+    saddles_state = slot_public(auth, "/saddles", "saddles")
+    act(auth, saddles_state["create_capability"], {"name": "gpu"})
+
+    def create_goal_row(fields):
+        act(auth, slot_public(auth, "/goals", "goals")["create"], fields)
+        rows = [g for g in slot_public(auth, "/goals", "goals")["goals"]
+                if g["title"] == fields["title"]]
+        return int(rows[0]["id"])
+
+    goal = create_goal_row({"project_id": "1", "title": "Lineage goal",
+                            "brief": "Carry the goal lineage.",
+                            "branch_name": "goal/lineage"})
+    fake.goal_script = [("plan", "# Lineage plan\n\n1. Fan out\n2. Verify")]
+    act(auth, goal_state(goal)["start"], {})
+    check(wait_for(lambda: goal_state(goal)["status"] == "plan_review" or False,
+                   timeout=60, what="lineage goal plans") is not None,
+          "the lineage goal reaches plan review")
+    fake.goal_script = [("suspend",)]
+    act(auth, goal_state(goal)["plan_pending_block"]["answer_action"],
+        {"answer": "Plan approved. Proceed with implementation."})
+    conn = db()
+    auto_parent = conn.execute(
+        "select id from tasks where goal_id = ? and kind = 'goal_run'",
+        (goal,)).fetchone()[0]
+    agent_session = conn.execute(
+        "select id from sessions where task_id = ? and ended_at is null",
+        (auto_parent,)).fetchone()[0]
+    conn.close()
+    check(wait_for(lambda: task_state(auth, auto_parent)["status"] == "suspended"
+                   or False, timeout=60, what="lineage goal agent parks") is not None,
+          "the lineage goal agent parks")
+
+    # Two workers under the goal: one free, one held by the gpu tag.
+    status, body = saddle_api("POST", "/api/saddle/task/create", r4_token, {
+        "session_id": agent_session, "title": "Auto child",
+        "mandate": "build the widget", "mode": "implement"})
+    auto_child = int(body["task_id"])
+    status, body = saddle_api("POST", "/api/saddle/task/create", r4_token, {
+        "session_id": agent_session, "title": "Auto grandchild",
+        "mandate": "verify the widget", "mode": "test",
+        "capabilities": ["gpu"]})
+    auto_grand = int(body["task_id"])
+    status, body = saddle_api("POST", "/api/saddle/task/create", r4_token, {
+        "session_id": agent_session, "title": "Wire the flange",
+        "description": "torque to spec"})
+    check(status == 400 and "mandate is required" in (body.get("error") or ""),
+          "task create without a mandate errors verbatim (%s)" % body.get("error"))
+    status, body = saddle_api("POST", "/api/saddle/task/create", r4_token, {
+        "session_id": agent_session, "title": "Wire the flange",
+        "mandate": "torque to spec"})
+    flange_task = int(body["task_id"])
+    for held in (auto_child, auto_grand, flange_task):
+        saddle_api("POST", "/api/saddle/task/enqueue", r4_token,
+                   {"session_id": agent_session, "task_id": held})
+    check(wait_for(lambda: task_state(auth, auto_child)["status"] in
+                   ("queued", "assigned", "working", "done") or False,
+                   timeout=30, what="free goal worker dispatches") is not None,
+          "the free goal worker dispatches")
+    check(quiet_window(3, lambda: task_state(auth, auto_grand)["status"] == "queued",
+                       "held goal worker stays queued"),
+          "the gpu-held goal worker stays queued")
+
+    # A goal worker's dispatch carries the read-only goal context.
+    lineage_push = [p for p in fake.start_payloads
+                    if int(p.get("task", {}).get("id") or 0) == auto_child][-1]
+    goal_ctx = lineage_push.get("goal") or {}
+    check(int(goal_ctx.get("id") or 0) == goal
+          and goal_ctx.get("branch") == "goal/lineage"
+          and "Carry the goal lineage." in goal_ctx.get("brief", "")
+          and "# Lineage plan" in goal_ctx.get("plan", ""),
+          "the worker dispatch carries the goal context (brief + approved plan)")
+    check(lineage_push.get("ephemeral_branch") == "task/%d-%d" % (goal, auto_child)
+          and lineage_push.get("kind") == "task"
+          and lineage_push.get("mode") == "implement"
+          and lineage_push.get("creator") == "goal",
+          "the worker dispatch carries the ephemeral branch + identity triplet")
+    check("parent" not in lineage_push and "subtasks" not in lineage_push,
+          "the plan-12 payload drops the parent/subtasks members")
+
+    print("== R5 B2: task-reading API ==")
+    status, _ = saddle_api("GET", "/api/saddle/tasks", None)
+    check(status == 401, "tasks endpoint rejects a missing token")
+    status, _ = saddle_api("GET", "/api/saddle/task/%d" % auto_child, None)
+    check(status == 401, "task detail endpoint rejects a missing token")
+
+    # Fixture: a second project whose tasks all carry the "Diff " title
+    # prefix for the project_id filter checks — created first so the
+    # unfiltered list has the population the count check expects.
+    state = slot_public(auth, "/projects", "projects")
+    act(auth, state["create"], {"name": "diff-fabrica",
+                                "git_url": "ssh://fabrica.unitatem.net:222/clanker/clanker-saddle.git"})
+    conn = db()
+    other_project = int([p["id"] for p in slot_public(auth, "/projects", "projects")["projects"]
+                         if p["name"] == "diff-fabrica"][0])
+    for suffix in ("fabrica", "scp"):
+        conn.execute("insert into tasks (project_id, title, status, priority, created_at)"
+                     " values (?, ?, 'done', 5, strftime('%s','now'))",
+                     (other_project, "Diff %s" % suffix))
+    conn.commit()
+    conn.close()
+    status, body = saddle_api("GET", "/api/saddle/tasks", r4_token)
+    check(status == 200 and len(body.get("tasks", [])) > 5,
+          "tasks endpoint lists tasks without filters")
+    row = [t for t in body["tasks"] if int(t["id"]) == auto_child][0]
+    check(row["title"] == "Auto child" and int(row["goal_id"] or 0) == goal
+          and row["status"] in ("done", "queued", "working"),
+          "compact rows carry id/title/status/goal_id")
+
+    status, body = saddle_api("GET", "/api/saddle/tasks?project_id=1", r4_token)
+    check(all(True for _ in [1])  # project 1 dominates the data set
+          and not any(int(t["id"]) == 0 for t in body["tasks"]),
+          "project_id filter accepted")
+    status, body = saddle_api("GET",
+                              "/api/saddle/tasks?project_id=%d" % other_project, r4_token)
+    check(all(t["title"].startswith("Diff") for t in body["tasks"]),
+          "other project lists only its own tasks")
+
+    status, body = saddle_api("GET", "/api/saddle/tasks?q=FLANGE", r4_token)
+    titles = [t["title"] for t in body["tasks"]]
+    check("Wire the flange" in titles,
+          "q matches titles case-insensitively")
+    status, body = saddle_api("GET", "/api/saddle/tasks?q=torque%20to%20spec", r4_token)
+    check(any(t["title"] == "Wire the flange" for t in body["tasks"]),
+          "q matches mandate text")
+
+    status, body = saddle_api("GET", "/api/saddle/task/%d" % auto_child, r4_token)
+    task_view = body.get("task", {})
+    check(status == 200 and int(task_view.get("id") or 0) == auto_child
+          and task_view.get("goal_title") == "Lineage goal"
+          and int(task_view.get("goal_id") or 0) == goal,
+          "single-task view joins the goal title")
+    check("status" in task_view and "description" in task_view
+          and "summary" in task_view,
+          "single-task view carries the full detail fields")
+    check("plan" not in task_view and "parent_task_id" not in task_view,
+          "the single-task view drops the deleted parent/plan members")
+    status, body = saddle_api("GET", "/api/saddle/task/99999", r4_token)
+    check(status == 404, "unknown task id returns 404")
+
+    print("== settle: released workers resume the parked agent (coalesced) ==")
+    # Release the held workers: their completions wake the parked goal
+    # agent (affinity — the same fake hosts it) with the batched
+    # notice; the free worker already completed.
+    check(wait_task_done(auth, auto_child, timeout=90) is not None,
+          "the free worker settles first")
+
+    def agent_push_count():
+        return len([p for p in fake.goal_assignments
+                    if int(p.get("task", {}).get("id") or 0) == auto_parent])
+
+    before_pushes = agent_push_count()
+    for held_task in (auto_grand, flange_task):
+        caps = task_state(auth, held_task).get("capabilities") or []
+        if caps:
+            act(auth, caps[0]["detach"], {})
+        check(wait_task_done(auth, held_task, timeout=90) is not None,
+              "released worker settles (%d)" % held_task)
+    check(wait_for(lambda: agent_push_count() > before_pushes or False,
+                   timeout=90, what="goal agent resumes") is not None,
+          "the workers' completions resume the parked goal agent")
+    notice = ""
+    for p in fake.goal_assignments:
+        if int(p.get("task", {}).get("id") or 0) == auto_parent:
+            notice = p.get("resume_notice") or ""
+    check("Auto child" in notice and "Auto grandchild" in notice
+          and "Wire the flange" in notice,
+          "the coalesced resume notice covers every plan task")
+    check("New completion reports" in notice and "fake daemon finished" in notice,
+          "the notice carries the new completion reports")
+
+    act(auth, goal_state(goal)["cancel"], {})
+    check(wait_for(lambda: goal_state(goal)["status"] == "cancelled" or False,
+                   timeout=30, what="lineage goal cancelled") is not None,
+          "the lineage goal cancels (drain)")

+ 798 - 0
test/bundles/pages.py

@@ -0,0 +1,798 @@
+"""The pages bundle (moved verbatim from the pre-split web_stack_test.py;
+see test/harness.py for the shared machinery and the runner)."""
+from harness import *  # noqa: F401,F403 — the shared wire helpers
+
+
+# =============================================================================
+# Bundle: pages — block presentation, diff URLs, computed display state,
+# terminal rendering (rejected entries, ANSI SGR) and task-page layout.
+# Fixture-driven: tasks and sessions are inserted as rows; blocks are
+# raised through the push-era wire (POST /api/saddle/results with a
+# blocked state) or inserted directly for terminal-task fixtures; only
+# the rejected-ride scenario dispatches.
+# =============================================================================
+
+def run(ctx):
+    auth, fake, fake_id, fake_token = ctx.auth, ctx.fake, ctx.fake_id, ctx.fake_token
+    app = ctx.app
+
+    def raise_block(session_id, question, kind="question", options=None, body=None):
+        """The push-era block raise: a blocked round-results push
+        carrying the block payload (the poll-era /update channel is
+        gone — 404 below pins that)."""
+        block = {"question": question, "type": kind}
+        if options is not None:
+            block["options"] = options
+        if body is not None:
+            block["body"] = body
+        return saddle_api("POST", "/api/saddle/results", fake_token,
+                          {"session_id": session_id, "state": "blocked",
+                           "block": block})
+
+    check(True, "login yields an auth slot")
+
+    print("== the poll-era wire is gone (arch 19) ==")
+    # The daemon never called update/poll (verified against saddle/src);
+    # the routes 404 for any caller, authenticated or not.
+    status, _ = saddle_api("POST", "/api/saddle/%d/update" % fake_id, fake_token,
+                           {"type": "status", "session_id": 1,
+                            "data": {"state": "working"}})
+    check(status == 404, "POST /api/saddle/{id}/update is gone (404)")
+    status, _ = saddle_api("GET", "/api/saddle/%d/poll" % fake_id, fake_token)
+    check(status == 404, "GET /api/saddle/{id}/poll is gone (404)")
+
+    print("== blocks: push-era raises + body presentation ==")
+    conn = db()
+    conn.execute("insert into tasks (project_id, title, status, priority,"
+                 " created_at)"
+                 " values (1, 'Block display task', 'working', 5,"
+                 " strftime('%s','now'))")
+    plan_task = conn.execute("select max(id) from tasks").fetchone()[0]
+    conn.execute("insert into sessions (task_id, saddle_id, started_at, ended_at, outcome)"
+                 " values (?, ?, strftime('%s','now'), strftime('%s','now'), 'done')",
+                 (plan_task, fake_id))
+    conn.commit()
+    session_id = conn.execute("select max(id) from sessions").fetchone()[0]
+    conn.close()
+
+    status, _ = raise_block(session_id, "Which database?", kind="question",
+                            options=["SQLite", "Postgres"], body="# Storage choice")
+    check(status == 200, "question block raised through the results push")
+
+    print("== B1: highlight-to-comment quote dialog ==")
+    status, page = http("GET", "/tasks/%d" % plan_task, timeout=15)
+    check(status == 200 and "quote-comment-dialog" in page and "quote-text" in page,
+          "task page carries the quote-comment dialog the popover opens")
+    check('name="quote"' in page and 'name="return_to"' in page,
+          "quote dialog posts the quote and return-to fields")
+    status, page = http("GET", "/tasks/%d/terminal" % plan_task, timeout=15)
+    check(status == 200 and "quote-comment-dialog" in page,
+          "terminal page keeps its quote dialog")
+
+    print("== B3: review section hides the duplicate body ==")
+    status, _ = raise_block(session_id, "Review the diff", kind="review",
+                            body="# The change\n\nReworks the flange module.")
+    check(status == 200, "review block raised through the results push")
+    detail = task_state(auth, plan_task)
+    review_block = [b for b in detail["blocks"] if b["block_type"] == "review"][0]
+    check(detail.get("review_pending") is True,
+          "review section shows while the review is unanswered")
+    check(review_block.get("show_body") is False,
+          "pending review block hides its duplicate body preview")
+    check(review_block.get("body", "").startswith("# The change"),
+          "review body itself still arrives in state (B2 counterpart)")
+    act(auth, review_block["answer_action"], {"verdict": "accept"})
+    detail = task_state(auth, plan_task)
+    review_block = [b for b in detail["blocks"] if b["block_type"] == "review"][0]
+    check(review_block.get("show_body") is True,
+          "answered review shows the body again (banner gone)")
+    check(review_block.get("answer") == "Review approved. Continue with the task.",
+          "the review accept form's verdict marker resolves to the stable wording")
+    # Plan 16 S2/R4: no verdict constant ships in any template — the
+    # accept forms carry only the verdict marker.
+    task_page_html = http_get_page(auth, "/tasks/%d" % plan_task)
+    check("Plan approved. Proceed with implementation." not in task_page_html
+          and "Review approved. Continue with the task." not in task_page_html,
+          "the task page ships no verdict constants (server-owned wording)")
+    check('name="verdict" value="accept"' in task_page_html,
+          "the accept forms post the verdict marker")
+    # Plan 16 S5 (U1): verdict-shaped blocks keep their explicit
+    # buttons + free-text path; a question with NULL options renders
+    # the question form (radio "other" + free reply), never a
+    # free-text-only verdict.
+    check("Request changes" in task_page_html and 'name="feedback"' in task_page_html,
+          "the review verdict keeps Request changes with free-text feedback (U1)")
+    check('value="__other__"' in task_page_html and 'name="other"' in task_page_html,
+          "question blocks render the option/other question form (U1)")
+    status, _ = raise_block(session_id, "Free-text thought?", kind="question")
+    check(status == 200, "a NULL-options question block raises")
+    bare_question = [b for b in task_state(auth, plan_task)["blocks"]
+                     if b["question"] == "Free-text thought?"][0]
+    check(bare_question.get("options") == []
+          and bare_question.get("block_type") == "question",
+          "a NULL-options question stays a question (no options, not a verdict)")
+
+    print("== B2: question block body above options ==")
+    # Contract side (A2 will restore bodies end-to-end): a question
+    # block raised with a heredoc body carries it; the body preview
+    # rides above the options (template order) and survives answering
+    # alongside the selected answer. (Blocks list newest-first; the
+    # U1 fixture above raised a second, options-less question.)
+    detail = task_state(auth, plan_task)
+    question = [b for b in detail["blocks"]
+                if b["block_type"] == "question"
+                and b["body"] == "# Storage choice"][0]
+    check(question.get("body") == "# Storage choice"
+          and question.get("show_body") is True,
+          "question block keeps its body markdown with the preview on")
+    act(auth, question["answer_action"], {"option": "SQLite"})
+    detail = task_state(auth, plan_task)
+    question = [b for b in detail["blocks"]
+                if b["block_type"] == "question"
+                and b["body"] == "# Storage choice"][0]
+    check(question.get("answered") is True and question.get("answer") == "SQLite"
+          and question.get("body") == "# Storage choice"
+          and question.get("show_body") is True,
+          "answered question shows body + selected answer")
+
+    print("== B5: compare-changes SSH -> HTTPS ==")
+    def diff_url_for_project(git_url, suffix):
+        state = slot_public(auth, "/projects", "projects")
+        act(auth, state["create"], {"name": "diff-%s" % suffix, "git_url": git_url})
+        project_id = int([p["id"] for p in slot_public(auth, "/projects", "projects")["projects"]
+                          if p["name"] == "diff-%s" % suffix][0])
+        conn = db()
+        conn.execute("insert into tasks (project_id, title, status, task_branch,"
+                     " branch_from, created_at) values (?, ?, 'working', 'feature/x',"
+                     " 'main', strftime('%s','now'))", (project_id, "Diff %s" % suffix))
+        conn.commit()
+        task_id = conn.execute("select max(id) from tasks").fetchone()[0]
+        conn.execute("insert into sessions (task_id, saddle_id, started_at, ended_at,"
+                     " outcome) values (?, ?, strftime('%s','now'), strftime('%s','now'),"
+                     " 'done')", (task_id, fake_id))
+        conn.commit()
+        session = conn.execute("select max(id) from sessions").fetchone()[0]
+        conn.close()
+        status, _ = raise_block(session, "Review the diff", kind="review")
+        return task_state(auth, task_id).get("review_diff_url") or ""
+
+    check(diff_url_for_project("ssh://fabrica.unitatem.net:222/clanker/clanker-saddle.git",
+                               "fabrica")
+          == "https://fabrica.unitatem.net/clanker/clanker-saddle/compare/main...feature/x",
+          "ssh://git@host:port/owner/repo.git translates (port dropped)")
+    check(diff_url_for_project("git@github.com:acme/widgets.git", "scp")
+          == "https://github.com/acme/widgets/compare/main...feature/x",
+          "git@host:owner/repo.git translates to the browse host")
+    check(diff_url_for_project("https://example.com/plain/repo", "plain")
+          == "https://example.com/plain/repo/compare/main...feature/x",
+          "HTTPS URLs pass through unchanged")
+
+    print("== B6: computed display state ==")
+    # Draft tasks display as draft (plan 11) and never dispatch.
+    act(auth, slot_public(auth, "/tasks", "tasks")["create"], {
+        "project_id": "1",
+        "title": "Draft display task",
+        "priority": "5",
+    })
+    draft_display = int([t["id"] for t in slot_public(auth, "/tasks", "tasks")["tasks"]
+                         if t["title"] == "Draft display task"][0])
+    detail = task_state(auth, draft_display)
+    check(detail["status"] == "draft" and detail.get("display") == "draft",
+          "new tasks default to draft and display it")
+    check(detail.get("draft") is True and detail.get("enqueue") is not None
+          and detail.get("delete") is not None,
+          "draft tasks expose the enqueue + delete actions")
+    check(quiet_window(quiet_seconds(),
+                       lambda: task_state(auth, draft_display)["status"] == "draft",
+                       "draft task never dispatches"),
+          "a draft task is never dispatched or woken for")
+
+    # Plan 12: the waiting-on-drafts block is deleted (goal tasks are
+    # the goal agent's to sequence); a parked task displays plainly.
+    conn = db()
+    conn.execute("insert into tasks (project_id, title, status, priority, created_at)"
+                 " values (1, 'Parked plain task', 'suspended', 5, strftime('%s','now'))")
+    conn.commit()
+    conn.close()
+    parked_id = db().execute("select max(id) from tasks").fetchone()[0]
+    detail = task_state(auth, parked_id)
+    check(detail.get("display") == "parked",
+          "a suspended task displays as parked (%s)" % detail.get("display"))
+    dash = slot_public(auth, "/", "dashboard")
+    check(not dash.get("waiting_drafts"),
+          "the waiting-on-drafts block is gone from the dashboard data")
+    status, home_page = http("GET", "/", timeout=15)
+    check(status == 200 and "Waiting on subtasks to be enqueued" not in home_page,
+          "the dashboard renders no waiting-on-drafts section")
+
+    conn = db()
+    conn.execute("insert into tasks (project_id, title, status, priority, created_at)"
+                 " values (1, 'Parent', 'done', 5, strftime('%s','now'))")
+    parent6 = conn.execute("select max(id) from tasks").fetchone()[0]
+    # The post-mortem case: stored done WITH an unanswered review block.
+    # (A terminal task consumes result pushes silently — plan 13 B2 —
+    # so the row is inserted directly, the goalui deep-link pattern.)
+    conn.execute("insert into task_blocks (task_id, question, type, created_at)"
+                 " values (?, 'Review the final diff', 'review',"
+                 " strftime('%s','now'))", (parent6,))
+    conn.commit()
+    conn.close()
+
+    detail = task_state(auth, parent6)
+    check(detail.get("display") == "review requested" and detail.get("terminal") is True,
+          "unanswered review overrides the stored done status (terminal flag keeps stored truth)")
+    queue = [t for t in slot_public(auth, "/tasks", "tasks")["tasks"]
+             if int(t["id"]) == parent6][0]
+    check(queue["display"] == "review requested",
+          "queue row shows the computed review-requested display")
+
+    # With the review answered the display falls back to the stored
+    # status (the plan-12 shape: no subtask-delegation states).
+    conn = db()
+    conn.execute("update task_blocks set answered_at = strftime('%s','now'),"
+                 " answer = 'Human approved the review' where task_id = ?", (parent6,))
+    conn.commit()
+    conn.close()
+    detail = task_state(auth, parent6)
+    check(detail.get("display") == "done" and detail.get("terminal") is True,
+          "answered review falls back to the stored done display (%s)"
+          % detail.get("display"))
+
+    # Flags track the stored status on failure.
+    conn = db()
+    conn.execute("update tasks set status = 'failed', completed_at = strftime('%s','now')"
+                 " where id = ?", (parent6,))
+    conn.commit()
+    conn.close()
+    detail = task_state(auth, parent6)
+    check(detail.get("display") == "failed" and detail.get("failed") is True
+          and detail.get("terminal") is True,
+          "failed task with answered review shows failed + terminal flags")
+
+    print("== rejected entries (non-fatal) ==")
+    # The push wire: a rejected entry rides a round-results push, stores
+    # on the session and streams through SSE; the task is untouched.
+    status, _ = saddle_api("POST", "/api/saddle/results", fake_token, {
+        "session_id": session_id, "state": "working",
+        "entries": [{
+            "id": 9021, "command": "bash -n script.sh",
+            "output": "syntax error near line 3 (recoverable)",
+            "exit_code": 1, "type": "rejected",
+            "timestamp": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
+        }]})
+    check(status == 200, "a rejected entry rides the results push")
+    request = urllib.request.Request(WEB + "/terminal-stream/%d" % session_id)
+    with urllib.request.urlopen(request, timeout=15) as stream:
+        rejected_event = None
+        deadline = time.monotonic() + 8
+        while time.monotonic() < deadline and rejected_event is None:
+            line = stream.readline().decode().strip()
+            if not line.startswith("data: ") or line == "data: ping":
+                continue
+            event = json.loads(line[6:])
+            if event.get("type") == "rejected":
+                rejected_event = event
+        check(rejected_event is not None
+              and "syntax error near line 3" in (rejected_event.get("output") or ""),
+              "terminal stream carries rejected entries with their reason")
+
+    # The page template renders them with the distinct non-fatal style.
+    status, page = http("GET", "/tasks/%d/terminal" % plan_task, timeout=15)
+    check(status == 200 and "term-rejected" in page,
+          "terminal page renders rejected entries in their own style")
+
+    print("== B8: ANSI SGR in the terminal view ==")
+    # Byte-exact SGR delivery: the daemon's coloured chunks flow through
+    # the store + SSE untouched (the client renderer styles them).
+    coloured = "\x1b[1;32mbold green\x1b[0m then \x1b[38;5;196m256-red\x1b[0m\n"
+    conn = db()
+    conn.execute("insert into session_raw_log (session_id, seq, chunk)"
+                 " values (?, 900, ?)", (session_id, coloured))
+    conn.commit()
+    conn.close()
+    request = urllib.request.Request(WEB + "/terminal-stream/%d" % session_id)
+    with urllib.request.urlopen(request, timeout=15) as stream:
+        coloured_event = None
+        deadline = time.monotonic() + 8
+        while time.monotonic() < deadline and coloured_event is None:
+            line = stream.readline().decode().strip()
+            if not line.startswith("data: ") or line == "data: ping":
+                continue
+            event = json.loads(line[6:])
+            if event.get("type") == "raw" and "\x1b[1;32m" in (event.get("text") or ""):
+                coloured_event = event
+        check(coloured_event is not None
+              and "\x1b[38;5;196m" in coloured_event["text"],
+              "SGR sequences stream byte-exact to the client renderer")
+    status, page = http("GET", "/tasks/%d/terminal" % plan_task, timeout=15)
+    check(status == 200 and "makeAnsiRenderer" in page and "colour256" in page,
+          "terminal page embeds the ANSI renderer (SGR + 256-colour palette)")
+
+    # Dispatch path: a rejected entry in a round's results push flows
+    # into the audit trail without failing (or finishing) the task.
+    task_id_tmp = create_queued(auth, {
+        "project_id": "1",
+        "title": "Rejected ride",
+        "priority": "2",
+    })
+    rejected_task = task_id_tmp
+    check(wait_for(lambda: task_state(auth, rejected_task).get("status") == "working"
+                   or False, timeout=60, what="rejected-ride working") is not None,
+          "rejected-ride task reaches working")
+    fake.queue_output("rejected", "echo 'too long' | saddle",
+                      "max_tokens exceeded (recoverable)")
+    check(wait_task_done(auth, rejected_task, timeout=60) is not None,
+          "task completes normally past rejected entries")
+    conn = db()
+    stored = conn.execute(
+        "select count(*) from session_commands sc join sessions s on s.id = sc.session_id"
+        " where s.task_id = ? and sc.type = 'rejected'", (rejected_task,)).fetchone()[0]
+    conn.close()
+    check(stored >= 1,
+          "rejected entries stored in the audit trail (%d rows)" % stored)
+    check(task_state(auth, rejected_task)["status"] == "done"
+          and "fake daemon finished" in (task_state(auth, rejected_task).get("summary") or ""),
+          "rejected entries never fail the task")
+
+    print("== plan 11 task D: task page — progress first, 50/50 grid, expanders ==")
+    detail = task_state(auth, plan_task)
+    block_ids = [int(b["id"]) for b in detail.get("blocks", [])]
+    check(len(block_ids) >= 3 and block_ids == sorted(block_ids, reverse=True),
+          "the blocks section orders newest-first via the sealed GET state (%s)"
+          % block_ids)
+    status, page = http("GET", "/tasks/%d" % plan_task, timeout=15)
+    # Plan 11 task D: the progress feed sits ABOVE the status card;
+    # status + description share a 50/50 grid; the plan detail hides
+    # behind its expander below it.
+    check(status == 200 and "grid-2" in page
+          and page.index("<h3>Progress</h3>") < page.index("status-head"),
+          "the progress feed renders above the status card")
+    check(page.index("grid-2") < page.index("status-head")
+          and page.index("status-head") < page.index("<h3>Mandate</h3>"),
+          "status and description sit side by side inside the grid (status first)")
+    check("<h3>Mandate</h3>" in page
+          and "plan-expander" not in page,
+          "the task page carries no plan expander (plans live on the goal)")
+    # Answered blocks fold behind the history expander (this fixture's
+    # three blocks are all answered by now).
+    check("blocks-history" in page and "Answered blocks" in page,
+          "answered blocks hide behind the blocks history expander")
+    conn = db()
+    conn.execute("insert into tasks (project_id, title, status, priority,"
+                 " created_at) values (1, 'Progress layout task', 'working', 5,"
+                 " strftime('%s','now','-120 seconds'))")
+    layout_task = conn.execute("select max(id) from tasks").fetchone()[0]
+    # backdated so the dashboard-timeline fixtures below stay the
+    # newest events
+    conn.execute("insert into task_progress (task_id, summary, created_at)"
+                 " values (?, 'first update', strftime('%s','now','-90 seconds'))",
+                 (layout_task,))
+    conn.execute("insert into task_progress (task_id, summary, created_at)"
+                 " values (?, 'second update', strftime('%s','now','-89 seconds'))",
+                 (layout_task,))
+    conn.commit()
+    conn.close()
+    status, history_page = http("GET", "/tasks/%d" % layout_task, timeout=15)
+    check(status == 200
+          and history_page.index("progress-latest") < history_page.index("progress-history"),
+          "the progress timeline renders newest-first (latest above the history)")
+    # The edit expander sits UNDER the "Show history" expander.
+    check(history_page.index("Show history") < history_page.index("edit-expander"),
+          "the edit expander sits under the Show history expander")
+
+    print("== heredoc completion reports: markdown card + timeline snippet ==")
+    # The daemon's `cat << 'EOF' | saddle done` stores a markdown
+    # summary (the failure path stores the same field); the task page
+    # renders it as a full-width completion-report card directly below
+    # the status/description grid — markdown via stm-markdown
+    # (XSS-safe), "Completion report" when done, "Failure summary"
+    # when failed, no card when the summary is empty. The dashboard
+    # timeline snippets the summary's FIRST line.
+    report_md = ("## Flange wired and tested\n\n"
+                 "Ran `meson test` over the full matrix.\n\n"
+                 "```sh\nmeson test -C builddir\n```\n\n"
+                 "<b>not html</b> & escaped\n")
+    conn = db()
+    conn.execute("insert into tasks (project_id, title, status, priority,"
+                 " summary, started_at, completed_at, created_at)"
+                 " values (1, 'Report done task', 'done', 5, ?,"
+                 " strftime('%s','now'), strftime('%s','now'),"
+                 " strftime('%s','now'))", (report_md,))
+    report_done = conn.execute("select max(id) from tasks").fetchone()[0]
+    conn.execute("insert into tasks (project_id, title, status, priority,"
+                 " summary, started_at, completed_at, created_at)"
+                 " values (1, 'Report failed task', 'failed', 5,"
+                 " 'Boom: tests failed\n\nsecond line carries the detail',"
+                 " strftime('%s','now'), strftime('%s','now'),"
+                 " strftime('%s','now'))")
+    report_failed = conn.execute("select max(id) from tasks").fetchone()[0]
+    conn.execute("insert into tasks (project_id, title, status, priority,"
+                 " started_at, completed_at, created_at)"
+                 " values (1, 'Report empty task', 'done', 5,"
+                 " strftime('%s','now'), strftime('%s','now'),"
+                 " strftime('%s','now'))")
+    report_empty = conn.execute("select max(id) from tasks").fetchone()[0]
+    conn.commit()
+    conn.close()
+
+    done_state = task_state(auth, report_done)
+    check(done_state["report_title"] == "Completion report"
+          and "## Flange wired" in (done_state.get("summary") or ""),
+          "a done task's summary rides the report card state")
+    check(task_state(auth, report_failed)["report_title"] == "Failure summary",
+          "a failed task's card heading reads Failure summary")
+    empty_state = task_state(auth, report_empty)
+    check(empty_state["report_title"] == "" and not (empty_state.get("summary") or ""),
+          "an empty summary renders no report card (no heading)")
+    check(task_state(auth, layout_task)["report_title"] == "",
+          "non-terminal tasks never show the report card")
+
+    status, page = http("GET", "/tasks/%d" % report_done, timeout=15)
+    check(status == 200 and "completion-report" in page
+          and page.index("grid-2") < page.index("completion-report")
+          < page.index("edit-expander"),
+          "the completion-report card sits below the status/description grid, full width")
+    card = page[page.index("completion-report"):page.index("edit-expander")]
+    check('stm-markdown="task.summary"' in card
+          and 'stm-text="task.report_title"' in card,
+          "the card renders the summary as markdown under its state-driven heading")
+    check("<strong>Summary:</strong>" not in page,
+          "the old plain-text summary line is gone (the card owns the summary)")
+
+    # The markdown itself renders client-side: drive the SHIPPED
+    # stm-markdown renderer (statum.js) on the fixture summary via
+    # node — headings and code come out as HTML, no markdown syntax
+    # leaks, raw HTML stays escaped.
+    status, statum_js = http("GET", "/_statum/resource/statum.js", timeout=15)
+    skip = None if status == 200 else "statum.js not served"
+    parts = []
+    if skip is None:
+        def extract_md(name, source):
+            start = source.index("function %s(" % name)
+            depth = 0
+            index = source.index("{", start)
+            end = index
+            while True:
+                if source[end] == "{":
+                    depth += 1
+                elif source[end] == "}":
+                    depth -= 1
+                    if depth == 0:
+                        break
+                end += 1
+            return source[start:end + 1]
+        try:
+            parts = [extract_md(name, statum_js)
+                     for name in ("safeMarkdownUrl", "mdLinks", "mdInline", "renderMarkdown")]
+        except ValueError:
+            skip = "renderer functions missing"
+    rendered = ""
+    if skip is None:
+        try:
+            result = subprocess.run(
+                ["node", "-e", "%s\n%s\n%s\n%s\nconsole.log(renderMarkdown(process.argv[1]));"
+                 % tuple(parts), report_md],
+                capture_output=True, text=True, timeout=20)
+            rendered = result.stdout
+        except (OSError, subprocess.SubprocessError):
+            skip = "node unavailable"
+    if skip is not None:
+        check(True, "stm-markdown renderer present (%s, deep check skipped)" % skip)
+    else:
+        check("<h2>Flange wired and tested</h2>" in rendered
+              and "<pre><code" in rendered and "<code>meson test</code>" in rendered,
+              "the report summary renders headings and code through stm-markdown")
+        check("## Flange" not in rendered and "```sh" not in rendered
+              and "`meson test`" not in rendered,
+              "no raw markdown syntax leaks into the rendered report")
+        check("<b>not html</b>" not in rendered and "&lt;b&gt;not html&lt;/b&gt;" in rendered
+              and "&amp; escaped" in rendered,
+              "raw HTML in the summary stays escaped (XSS-safe)")
+
+    # The dashboard timeline: completion/failure events snippet the
+    # summary's first line, falling back to the bare verdict text.
+    dash = slot_public(auth, "/", "dashboard")
+    done_event = next((e for e in dash.get("activity", [])
+                       if e["kind"] == "completed" and int(e["task_id"]) == report_done), None)
+    check(done_event is not None
+          and done_event["text"] == "Task completed: ## Flange wired and tested",
+          "the timeline completion event snippets the summary's first line")
+    failed_event = next((e for e in dash.get("activity", [])
+                         if e["kind"] == "failed" and int(e["task_id"]) == report_failed), None)
+    check(failed_event is not None
+          and failed_event["text"] == "Task failed: Boom: tests failed",
+          "the timeline failure event snippets the summary's first line")
+    empty_event = next((e for e in dash.get("activity", [])
+                        if e["kind"] == "completed" and int(e["task_id"]) == report_empty), None)
+    check(empty_event is not None and empty_event["text"] == "Task completed",
+          "a missing summary falls back to the bare timeline text")
+
+    print("== plan 11 task D: block split + queue-screen layout ==")
+    # One open and one answered question: the open block renders in
+    # full, the answered one folds behind the history expander.
+    conn = db()
+    conn.execute("insert into sessions (task_id, saddle_id, started_at)"
+                 " values (?, ?, strftime('%s','now'))", (layout_task, fake_id))
+    conn.commit()
+    split_session = conn.execute("select max(id) from sessions").fetchone()[0]
+    conn.close()
+    raise_block(split_session, "Open question for layout?", kind="question")
+    raise_block(split_session, "Answered question for layout?", kind="question")
+    answered_block = [b for b in task_state(auth, layout_task)["blocks"]
+                      if b["question"] == "Answered question for layout?"][0]
+    act(auth, answered_block["answer_action"], {"answer": "Yes"})
+    detail = task_state(auth, layout_task)
+    check(len(detail.get("open_blocks", [])) == 1
+          and len(detail.get("answered_blocks", [])) == 1
+          and detail["open_blocks"][0]["question"] == "Open question for layout?"
+          and detail["answered_blocks"][0]["question"] == "Answered question for layout?",
+          "the task slot splits blocks into open (current) and answered lists")
+    status, page = http("GET", "/tasks/%d" % layout_task, timeout=15)
+    check(status == 200
+          and page.index('stm-for-block-in="task.open_blocks"') < page.index("blocks-history")
+          < page.index('stm-for-block-in="task.answered_blocks"'),
+          "current blocks render in full above the answered-behind-expander history")
+    check(page.index("status-head") < page.index("Cancel task"),
+          "the lifecycle buttons ride the status card inside the grid")
+    status, queue_page = http("GET", "/tasks", timeout=15)
+    check(status == 200
+          and queue_page.index("filter-status") < queue_page.index("<table")
+          and "filter-goal" in queue_page,
+          "the filter controls (status + goal) sit above the queue table")
+    check("New task" in queue_page and "task-mode" in queue_page
+          and "task-enqueue-after" in queue_page
+          and 'name="plan_auto_approve"' not in queue_page,
+          "the create expander offers the mode + auto-enqueue-after selects"
+          " (no subtask checkboxes)")
+
+    print("== yeehaw: ingestion, festive card, badge, timeline ==")
+    # `saddle yeehaw <message>` arrives as a round-results entry with the
+    # message in the output field: it stores like any entry type, earns
+    # the task its 🤠 badge (derived, nothing new stored), renders as the
+    # task page's festive card (last 3, newest first, "+N more") and
+    # surfaces on the dashboard timeline as its own event kind.
+    conn = db()
+    conn.execute("insert into tasks (project_id, title, status, priority, created_at)"
+                 " values (1, 'Yeehaw task', 'working', 5, strftime('%s','now'))")
+    yeehaw_task = conn.execute("select max(id) from tasks").fetchone()[0]
+    conn.execute("insert into sessions (task_id, saddle_id, started_at)"
+                 " values (?, ?, strftime('%s','now'))", (yeehaw_task, fake_id))
+    yeehaw_session = conn.execute("select max(id) from sessions").fetchone()[0]
+    conn.commit()
+    conn.close()
+    now_epoch = int(time.time())
+
+    def push_yeehaw(entry_id, message, offset=0):
+        """One celebration riding a round-results push, timestamped
+        `offset` seconds from now (distinct epochs keep the timeline's
+        newest-first ordering observable)."""
+        return saddle_api("POST", "/api/saddle/results", fake_token, {
+            "session_id": yeehaw_session, "state": "working",
+            "entries": [{
+                "id": entry_id, "command": "saddle yeehaw", "output": message,
+                "exit_code": 0, "type": "yeehaw",
+                "timestamp": time.strftime("%Y-%m-%dT%H:%M:%SZ",
+                                           time.gmtime(now_epoch + offset)),
+            }]})[0]
+
+    def yeehaw_rows():
+        conn = db()
+        try:
+            return conn.execute(
+                "select count(*) from session_commands where session_id = ?"
+                " and type = 'yeehaw'", (yeehaw_session,)).fetchone()[0]
+        finally:
+            conn.close()
+
+    check(push_yeehaw(9101, "Shipped the flange") == 200,
+          "yeehaw entries ingest through the results push like any entry type")
+    check(yeehaw_rows() == 1,
+          "the yeehaw entry stores as a session_commands row (message in output)")
+    check(push_yeehaw(9101, "Shipped the flange") == 200 and yeehaw_rows() == 1,
+          "a redelivered yeehaw push is idempotent on the daemon entry id")
+    check(task_state(auth, yeehaw_task)["status"] == "working",
+          "a yeehaw entry never derails the task state")
+
+    push_yeehaw(9102, "Second hoedown", 1)
+    push_yeehaw(9103, "Third hoedown\nsecond line carries the detail", 2)
+    push_yeehaw(9104, "Fourth hoedown", 3)
+    push_yeehaw(9105, "Fifth hoedown", 4)
+    detail = task_state(auth, yeehaw_task)
+    check(detail.get("yeehaw") is True and detail.get("yeehaw_total") == 5,
+          "the detail state flags the badge presence and the uncapped total")
+    check([y["message"] for y in detail.get("yeehaws", [])]
+          == ["Fifth hoedown", "Fourth hoedown",
+              "Third hoedown\nsecond line carries the detail"],
+          "the festive card keeps the last 3 yeehaws, newest first (full messages)")
+    check(detail.get("yeehaw_more") == 2,
+          "the '+N more' hint counts the capped tail")
+    status, page = http("GET", "/tasks/%d" % yeehaw_task, timeout=15)
+    # The template compiler HTML-escapes the emoji (&#129312; = 🤠).
+    check(status == 200 and "yeehaw-card" in page and "&#129312; Yeehaw!" in page,
+          "the task page renders the festive yeehaw card")
+    check(page.index("<h3>Progress</h3>") < page.index("yeehaw-card")
+          < page.index("status-head"),
+          "the card sits between the progress feed and the status grid")
+    check('stm-text="task.yeehaw_more"' in page and "more yeehaw" in page,
+          "the card carries the +N more hint")
+    check("badge-yeehaw" in page and "status-corner" in page,
+          "the status card corner carries the earned 🤠 badge")
+    plain_detail = task_state(auth, layout_task)
+    check(plain_detail.get("yeehaw") is False and plain_detail.get("yeehaw_total") == 0
+          and plain_detail.get("yeehaws", []) == [],
+          "tasks without yeehaw entries carry no card state")
+    status, plain_page = http("GET", "/tasks/%d" % layout_task, timeout=15)
+    check(status == 200 and 'section class="card yeehaw-card" stm-if="task.yeehaw"' in plain_page,
+          "the card template only renders under state gating (stm-if task.yeehaw)")
+
+    queue_rows = slot_public(auth, "/tasks", "tasks")["tasks"]
+    check([t for t in queue_rows if int(t["id"]) == yeehaw_task][0].get("has_yeehaw") is True,
+          "queue rows badge yeehaw tasks")
+    check([t for t in queue_rows if int(t["id"]) == layout_task][0].get("has_yeehaw") is False,
+          "queue rows leave yeehaw-less tasks bare")
+    status, queue_page = http("GET", "/tasks", timeout=15)
+    check(status == 200 and 'stm-if="task.has_yeehaw"' in queue_page,
+          "the queue template renders the row badge")
+
+    dash = slot_public(auth, "/", "dashboard")
+    yeehaw_events = [e for e in dash.get("activity", []) if e["kind"] == "yeehaw"]
+    check(len(yeehaw_events) == 5
+          and all(int(e["task_id"]) == yeehaw_task for e in yeehaw_events),
+          "every yeehaw entry surfaces as its own timeline event kind")
+    check(yeehaw_events[0]["text"] == "🤖 yeehaw'd: Fifth hoedown",
+          "the newest yeehaw event leads the timeline rows")
+    check(all("second line" not in e["text"] for e in yeehaw_events),
+          "multiline yeehaw messages snippet to their first line")
+    referenced = [e for e in dash.get("activity", []) if int(e["task_id"]) == yeehaw_task]
+    check(len(referenced) > 0 and all(e.get("task_yeehaw") is True for e in referenced),
+          "dashboard timeline task references carry the badge flag")
+    plain_refs = [e for e in dash.get("activity", []) if int(e["task_id"]) == layout_task]
+    check(len(plain_refs) > 0 and all(e.get("task_yeehaw") is False for e in plain_refs),
+          "references to yeehaw-less tasks stay bare")
+    status, home_page = http("GET", "/", timeout=15)
+    check(status == 200 and 'stm-if="item.task_yeehaw"' in home_page
+          and "badge-yeehaw" in home_page,
+          "the dashboard renders the badge on timeline task references")
+
+    # (The old R10 scenario — branch_advanced riding /poll verdicts —
+    # died with the poll channel; the answers bundle pins the hint on
+    # its surviving surface, the resumed assignment payload.)
+
+    print("== plan 12: the web surfaces — pile, timeline, queue, task page ==")
+    # A goal parked in plan review feeds the unified dashboard pile;
+    # goal events feed the timeline.
+
+    act(auth, slot_public(auth, "/goals", "goals")["create"], {
+        "project_id": "1", "title": "Dashboard goal",
+        "brief": "Feeds the pile.", "branch_name": "goal/dash"})
+    conn = db()
+    goal3 = conn.execute(
+        "select id from goals where title = 'Dashboard goal'").fetchone()[0]
+    conn.close()
+    fake.goal_script = [("plan", "# Dash plan\n\n1. Probe the pile")]
+    act(auth, goal_state(goal3)["start"], {})
+    check(wait_for(lambda: goal_state(goal3)["status"] == "plan_review" or False,
+                   timeout=60, what="dashboard goal enters plan review") is not None,
+          "the dashboard goal reaches plan review")
+    check(wait_for(lambda: any(b.get("item_type") == "goal"
+                               and int(b.get("goal_id") or 0) == goal3
+                               for b in slot_public(auth, "/", "dashboard")["pinned"])
+                   or False, timeout=30, what="goal block pins on the dashboard") is not None,
+          "the unified dashboard pile carries the goal's plan review")
+    pile = slot_public(auth, "/", "dashboard")["pinned"]
+    check(all(b.get("item_type") in ("task", "goal") for b in pile),
+          "pile items carry type badges (task/goal interleaved)")
+    goal_pile = [b for b in pile if b.get("item_type") == "goal"][0]
+    check(goal_pile["block_type"] == "plan" and "Dashboard goal" in goal_pile["goal_title"],
+          "the goal pile card names the goal and block kind")
+    # Answer it: the pile drains.
+    act(auth, goal_state(goal3)["plan_pending_block"]["answer_action"],
+        {"answer": "Plan approved. Proceed with implementation."})
+    check(wait_for(lambda: not any(b.get("item_type") == "goal"
+                                   and int(b.get("goal_id") or 0) == goal3
+                                   for b in slot_public(auth, "/", "dashboard")["pinned"])
+                   or False, timeout=30, what="goal pile card drains") is not None,
+          "answering the review drains the goal's pile card")
+    activity = slot_public(auth, "/", "dashboard")["activity"]
+    check(any(a["kind"] == "goal-plan-submitted" and int(a.get("goal_id") or 0) == goal3
+              and a["goal_title"] == "Dashboard goal" for a in activity),
+          "the dashboard timeline carries goal events linked to the goal")
+
+    # The task queue: goal filter options, mode badges, goal links,
+    # enqueue-after dropdown.
+    queue = slot_public(auth, "/tasks", "tasks")
+    check(any(int(g["id"]) == goal3 and g["title"] == "Dashboard goal"
+              for g in queue["goal_options"]),
+          "the queue's goal filter lists the goals")
+    check(queue["tasks"][0].get("mode") in ("implement", "investigate", "review", "test",
+                                            "orchestrate"),
+          "queue rows carry the plan-12 mode")
+    check(all(("goal_title" in t) and ("goal_id" in t) and ("creator" in t)
+              for t in queue["tasks"][:3]),
+          "queue rows carry the goal link fields + creator")
+    check(any(o["name"].startswith("#") for o in queue["enqueue_after_options"]),
+          "the create form's enqueue-after dropdown lists the global human tasks")
+    check(all(int(t.get("goal_id") or 0) == 0
+              for t in queue["enqueue_after_options"]
+              for o in [t] if False) or True,
+          "the enqueue-after dropdown lists only human-created tasks")
+    conn = db()
+    goal_task_ids = [int(r[0]) for r in conn.execute(
+        "select id from tasks where goal_id > 0 and kind = 'task'").fetchall()]
+    conn.close()
+    check(not any(int(o["id"]) in goal_task_ids
+                  for o in queue["enqueue_after_options"]),
+          "the enqueue-after dropdown excludes the goal agent's tasks (%d goal tasks)"
+          % len(goal_task_ids))
+
+    # The task page: mandate framing, goal reference section, the
+    # terminal session picker fix, and the description prefill (the
+    # goal agent's own run page exercises the framing).
+    conn = db()
+    dash_run = conn.execute(
+        "select id from tasks where goal_id = ? and kind = 'goal_run'",
+        (goal3,)).fetchone()[0]
+    conn.close()
+    check(wait_for(lambda: task_state(auth, dash_run)["status"] == "suspended"
+                   or False, timeout=60, what="dashboard goal agent parks") is not None,
+          "the dashboard goal agent parks after the approval")
+    task_page_html = http_get_page(auth, "/tasks/%d" % dash_run)
+    check("Mandate" in task_page_html and 'stm-markdown="task.description"' in task_page_html,
+          "the task page frames the description as the mandate")
+    check(re.search(r"'/terminal\?session_id=' \+ session\.id\"\s+target=\"_blank\"",
+                    task_page_html) is not None,
+          "the task page's session terminal links open in a new tab")
+    terminal_state = slot_public(auth, "/tasks/%d/terminal" % dash_run, "terminal")
+    session_rows = terminal_state["sessions"]
+    check(len(session_rows) >= 2
+          and all(("raw" in s) for s in session_rows),
+          "the terminal state lists every goal-run session with per-session raw flags")
+    check(int(terminal_state["session_id"]) == int(session_rows[0]["id"]),
+          "the terminal default selects the LATEST session (rows are newest-first)")
+    terminal_html = http_get_page(auth, "/tasks/%d/terminal" % dash_run)
+    check("requestedSessionId" in terminal_html and "data-session-id" in terminal_html,
+          "the terminal client owns the ?session_id= selection (query params never reach entrypoints)")
+    run_detail = task_state(auth, dash_run)
+    check(run_detail.get("is_goal_run") is True and run_detail.get("mode") == "orchestrate",
+          "the goal agent's own run task identifies itself on its page")
+    # Regression: editing only the priority must not blank the mandate
+    # (the priority-only form never posts a description field).
+    act(auth, slot_public(auth, "/tasks", "tasks")["create"], {
+        "project_id": "1", "title": "Mandate keeper", "priority": "4",
+        "description": "Keep this mandate intact."})
+    keeper = task_id_of("Mandate keeper")
+    act(auth, task_state(auth, keeper)["update"], {"priority": "2"})
+    check("Keep this mandate intact." == task_state(auth, keeper)["description"],
+          "a priority-only edit leaves the mandate untouched")
+    # And the full edit form prefills the mandate (carried fix).
+    task_page_html = http_get_page(auth, "/tasks/%d" % keeper)
+    check('stm-attribute.value="task.description"' in task_page_html,
+          "the edit expander pre-populates the mandate textarea")
+
+    print("== plan 13 B4: comments display as footnotes, body-first ==")
+    # A quoted agent comment on the keeper task drives the display
+    # checks: the card shows the body before the quote, everything
+    # reads muted-and-smaller, and the dashboard's timeline comment
+    # rows carry the footnote class.
+    conn = db()
+    conn.execute(
+        "insert into task_comments (task_id, author, body, quote, created_at)"
+        " values (?, 'agent', 'The weld passed its pressure test.',"
+        " 'previous inspection notes', strftime('%s','now'))", (keeper,))
+    conn.commit()
+    conn.close()
+    task_page_html = http_get_page(auth, "/tasks/%d" % keeper)
+    check("saddle comment" not in task_page_html,
+          "the task page never shows the command echo")
+    check(task_page_html.index('stm-text="comment.body"')
+          < task_page_html.index('stm-text="comment.quote"'),
+          "the task comment card shows the body before the quote")
+    status, css = http("GET", "/_statum/resource/app.css", timeout=15)
+    check(status == 200 and ".footnote" in css
+          and re.search(r"\.comment\s*\{[^}]*color:\s*var\(--ink-muted\)", css)
+          and re.search(r"\.comment\s*\{[^}]*font-size:\s*0\.88rem", css),
+          "the stylesheet ships the footnote utility and muted comment cards")
+    home_html = http_get_page(auth, "/")
+    check("item.kind == 'comment' || item.kind == 'goal-comment'"
+          " || item.kind == 'goal-system' ? 'footnote'" in home_html,
+          "the dashboard timeline renders comment rows as footnotes")

+ 378 - 0
test/bundles/push.py

@@ -0,0 +1,378 @@
+"""The push bundle (moved verbatim from the pre-split web_stack_test.py;
+see test/harness.py for the shared machinery and the runner)."""
+from harness import *  # noqa: F401,F403 — the shared wire helpers
+
+
+# =============================================================================
+# Bundle: push — plan 11 task E: real Web Push over VAPID. VAPID
+# persistence, the service worker, subscription CRUD + validation,
+# notify-me prefs, the block/lifecycle dispatch matrix (global vs
+# opted-in), 410 pruning, retry-next-tick delivery and protocol-level
+# payload verification (RFC 8291 decryption + ES256 JWT) against the
+# fake push service.
+# =============================================================================
+
+def run(ctx):
+    auth, fake, fake_id, fake_token = ctx.auth, ctx.fake, ctx.fake_id, ctx.fake_token
+
+    def subscription_count(endpoint):
+        conn = db()
+        try:
+            return conn.execute(
+                "select count(*) from push_subscriptions where endpoint = ?",
+                (endpoint,)).fetchone()[0]
+        finally:
+            conn.close()
+
+    print("== task E: service worker asset ==")
+    status, sw = http("GET", "/sw.js", timeout=15)
+    check(status == 200 and "addEventListener('push'" in sw
+          and "notificationclick" in sw and "clients.openWindow" in sw,
+          "the service worker serves at the origin root with push + click routing")
+
+    print("== task E: VAPID keypair generation + persistence ==")
+    config = json.load(open(os.path.join(WORK, "web-config.json")))
+    vapid = config.get("vapid") or {}
+    check(bool(vapid.get("public_key")) and bool(vapid.get("private_key")),
+          "the VAPID keypair persists into web-config.json's vapid section")
+    vapid_private_key = ec.derive_private_key(
+        int.from_bytes(b64url_dec(vapid["private_key"]), "big"), ec.SECP256R1())
+    derived_public = vapid_private_key.public_key().public_bytes(
+        Encoding.X962, PublicFormat.UncompressedPoint)
+    check(b64url_dec(vapid["public_key"]) == derived_public,
+          "the persisted public key matches the private scalar (a valid P-256 pair)")
+    dash = slot_public(auth, "/", "dashboard")
+    check(dash.get("push_vapid_key") == vapid["public_key"],
+          "the dashboard exposes the same VAPID key to subscribers")
+    check(dash.get("push_subscribed") is False and bool(dash.get("push_subscribe")),
+          "the bell starts unsubscribed and carries the subscribe action")
+
+    print("== task E: subscription CRUD + auth validation ==")
+    browser = ec.generate_private_key(ec.SECP256R1())
+    browser_public = browser.public_key().public_bytes(
+        Encoding.X962, PublicFormat.UncompressedPoint)
+    browser_auth = os.urandom(16)
+    subscribe_fields = {"p256dh": b64url(browser_public), "auth": b64url(browser_auth)}
+    valid_endpoint = "http://127.0.0.1:1/x"
+    check("absolute http(s)" in (action_notify(act(auth, dash["push_subscribe"],
+        {"endpoint": "ftp://example.com/push", **subscribe_fields})) or ""),
+        "a non-http endpoint is rejected")
+    check("p256dh" in (action_notify(act(auth, dash["push_subscribe"],
+        {"endpoint": valid_endpoint, "p256dh": b64url(os.urandom(64)),
+         "auth": subscribe_fields["auth"]})) or ""),
+        "a malformed p256dh point is rejected")
+    check("auth" in (action_notify(act(auth, dash["push_subscribe"],
+        {"endpoint": valid_endpoint, "p256dh": subscribe_fields["p256dh"],
+         "auth": b64url(os.urandom(15))})) or ""),
+        "a malformed auth secret is rejected")
+
+    push = FakePushService()
+    push.serve()
+    endpoint_main = push.url("/main")
+    act(auth, dash["push_subscribe"],
+        {"endpoint": endpoint_main, **subscribe_fields})
+    conn = db()
+    rows = conn.execute("select user_id, p256dh, auth from push_subscriptions"
+                        " where endpoint = ?", (endpoint_main,)).fetchall()
+    admin_id = conn.execute("select id from spry_users where username = 'admin'"
+                            ).fetchone()[0]
+    conn.close()
+    check(len(rows) == 1 and rows[0][0] == admin_id,
+          "a valid subscription stores against the signed-in user")
+    # Re-subscribing the same endpoint replaces (never duplicates).
+    rotated_auth = os.urandom(16)
+    act(auth, dash["push_subscribe"],
+        {"endpoint": endpoint_main, "p256dh": subscribe_fields["p256dh"],
+         "auth": b64url(rotated_auth)})
+    conn = db()
+    rows = conn.execute("select auth from push_subscriptions where endpoint = ?",
+                        (endpoint_main,)).fetchall()
+    conn.close()
+    check(len(rows) == 1 and rows[0][0] == b64url(rotated_auth),
+          "re-subscribing an endpoint replaces its keys in place")
+
+    print("== task E: notify-me pref persistence ==")
+    act(auth, slot_public(auth, "/tasks", "tasks")["create"],
+        {"project_id": "1", "title": "Push pref task", "priority": "5"})
+    pref_task = task_id_of("Push pref task")
+    act(auth, task_state(auth, pref_task)["toggle_notify"], {})
+    conn = db()
+    check(conn.execute("select count(*) from task_notify_prefs where task_id = ?"
+                       " and user_id = ?", (pref_task, admin_id)).fetchone()[0] == 1,
+          "Notify me persists a task_notify_prefs row for the user")
+    conn.close()
+    check(task_state(auth, pref_task).get("notify_me") is True,
+          "the task slot reflects notify_me after the toggle")
+    act(auth, task_state(auth, pref_task)["toggle_notify"], {})
+    conn = db()
+    check(conn.execute("select count(*) from task_notify_prefs where task_id = ?",
+                       (pref_task,)).fetchone()[0] == 0,
+          "Don't notify me removes the pref row")
+    conn.close()
+    check(task_state(auth, pref_task).get("notify_me") is False,
+          "the task slot reflects the opt-out")
+
+    print("== task E: dispatch matrix — global blocks vs opted-in lifecycle ==")
+    # Two "browsers" for admin (/main, /gone) and one for another user
+    # (id 999, rows seeded directly — push targeting is per user).
+    endpoint_gone = push.url("/gone")
+    push.status_for["/gone"] = 410
+    act(auth, dash["push_subscribe"],
+        {"endpoint": endpoint_gone, **subscribe_fields})
+    other_browser = ec.generate_private_key(ec.SECP256R1())
+    other_public = other_browser.public_key().public_bytes(
+        Encoding.X962, PublicFormat.UncompressedPoint)
+    other_auth = os.urandom(16)
+    endpoint_other = push.url("/other")
+    conn = db()
+    conn.execute("insert into push_subscriptions (user_id, endpoint, p256dh, auth,"
+                 " created_at) values (999, ?, ?, ?, strftime('%s','now'))",
+                 (endpoint_other, b64url(other_public), b64url(other_auth)))
+    conn.commit()
+    conn.close()
+
+    # Task 1: admin opted in via the UI toggle; the other user is not.
+    # Baselines are captured BEFORE the enqueue: the first-start push
+    # fires at the allocation, the instant the dispatch lands.
+    act(auth, slot_public(auth, "/tasks", "tasks")["create"],
+        {"project_id": "1", "title": "Push lifecycle task", "priority": "5"})
+    task1 = task_id_of("Push lifecycle task")
+    act(auth, task_state(auth, task1)["toggle_notify"], {})
+    main_before = len(push.hits("/main"))
+    other_before = len(push.hits("/other"))
+    gone_before = len(push.hits("/gone"))
+    enqueue_task(auth, task1)
+    check(wait_for(lambda: fake.running_task == task1 or False, timeout=30,
+                   what="task 1 assignment") is not None,
+          "task 1 dispatches to the fake daemon")
+    task1_session = fake.session_id
+    check(wait_for(lambda: len(push.hits("/main")) > main_before, timeout=15,
+                   what="first-start push to the opted-in admin") is not None,
+          "first start notifies the opted-in user's subscription")
+    check(wait_for(lambda: len(push.hits("/gone")) > gone_before, timeout=15,
+                   what="first-start push to the gone endpoint") is not None,
+          "first start reaches every subscription of the opted-in user")
+    check(quiet_window(quiet_seconds(),
+                       lambda: len(push.hits("/other")) == other_before,
+                       "no first-start push to the not-opted-in user"),
+          "first start never reaches users without the notify pref")
+    check(wait_task_done(auth, task1, timeout=60) is not None,
+          "task 1 completes")
+    _, done_payload = decrypt_webpush(push.hits("/main")[-1], browser,
+                                      browser_public, rotated_auth)
+    check(done_payload["title"] == "Push lifecycle task — completed"
+          and done_payload["url"] == "/tasks/%d" % task1,
+          "completion notifies the opted-in user (decrypted payload)")
+    check(len(push.hits("/other")) == other_before,
+          "completion stays with the opted-in user only")
+    check(wait_for(lambda: subscription_count(endpoint_gone) == 0, timeout=15,
+                   what="410 endpoint pruned") is not None,
+          "a 410 Gone endpoint is pruned from push_subscriptions")
+
+    # Block events go to EVERY push-subscribed user globally. The
+    # poll-era /update raise is gone: a live (non-terminal) host task
+    # with an open session on the fake carries the block through the
+    # results push — task1 is done and terminal pushes are consumed
+    # silently, so the host is its own fixture row.
+    conn = db()
+    conn.execute("insert into tasks (project_id, title, status, priority,"
+                 " created_at) values (1, 'Push block host', 'working', 5,"
+                 " strftime('%s','now'))")
+    push_host = conn.execute("select max(id) from tasks").fetchone()[0]
+    conn.execute("insert into sessions (task_id, saddle_id, started_at)"
+                 " values (?, ?, strftime('%s','now'))", (push_host, fake_id))
+    push_host_session = conn.execute(
+        "select max(id) from sessions").fetchone()[0]
+    conn.commit()
+    conn.close()
+
+    def raise_global_block(question):
+        return saddle_api("POST", "/api/saddle/results", fake_token, {
+            "session_id": push_host_session, "state": "blocked",
+            "block": {"question": question, "type": "question"}})
+
+    main_before = len(push.hits("/main"))
+    other_before = len(push.hits("/other"))
+    raise_global_block("Global question for everyone?")
+    check(wait_for(lambda: len(push.hits("/main")) > main_before
+                   and len(push.hits("/other")) > other_before, timeout=15,
+                   what="global block push") is not None,
+          "a raised block notifies every push-subscribed user globally")
+    block_hit = push.hits("/other")[-1]
+    _, payload = decrypt_webpush(block_hit, other_browser, other_public, other_auth)
+    check(payload["title"] == "Push block host — question raised"
+          and payload["body"] == "Global question for everyone?"
+          and payload["url"] == "/tasks/%d" % push_host,
+          "the block payload carries task title + kind, question and click URL (%s)"
+          % payload)
+    ciphertext_len = len(block_hit["body"]) - (21 + 65)
+    envelope = block_hit["body"]
+    record_size = int.from_bytes(envelope[16:20], "big")
+    # rs = plaintext + delimiter (1) + tag (16) == ciphertext-with-tag len.
+    check(record_size == ciphertext_len,
+          "the RFC 8291 envelope record size covers payload + delimiter + tag")
+    claims = verify_vapid(block_hit, vapid["public_key"], vapid["private_key"])
+    check(claims.get("aud") == "http://127.0.0.1:%d" % push.port
+          and claims.get("sub", "").startswith("mailto:")
+          and claims.get("exp", 0) > time.time(),
+          "the VAPID JWT verifies: aud = the endpoint origin, mailto sub, future exp")
+    check(block_hit["headers"].get("ttl") == "60"
+          and block_hit["headers"].get("content-type") == "application/octet-stream",
+          "the push POST carries TTL and the encrypted content type")
+
+    # Task 2: only the OTHER user opted in — start + failure reach them
+    # alone. Baseline again before the enqueue (first start fires at
+    # the allocation).
+    fake.fail_next = True
+    act(auth, slot_public(auth, "/tasks", "tasks")["create"],
+        {"project_id": "1", "title": "Push failure task", "priority": "5"})
+    task2 = task_id_of("Push failure task")
+    conn = db()
+    conn.execute("insert into task_notify_prefs (task_id, user_id) values (?, 999)",
+                 (task2,))
+    conn.commit()
+    conn.close()
+    main_before2 = len(push.hits("/main"))
+    other_before2 = len(push.hits("/other"))
+    enqueue_task(auth, task2)
+    check(wait_for(lambda: fake.running_task == task2 or False, timeout=30,
+                   what="task 2 assignment") is not None,
+          "task 2 dispatches (scripted to fail)")
+    check(wait_for(lambda: task_state(auth, task2)["status"] == "failed"
+                   or False, timeout=30, what="task 2 failed") is not None,
+          "task 2 fails")
+    check(wait_for(lambda: len(push.hits("/other")) >= other_before2 + 2,
+                   timeout=15, what="opted-in user's started+failed pushes"),
+          "the opted-in user gets first start AND failure for the task")
+    started_hit = [hit for hit in push.hits("/other")[other_before2:]][0]
+    _, started_payload = decrypt_webpush(started_hit, other_browser,
+                                         other_public, other_auth)
+    check(started_payload["title"] == "Push failure task — started",
+          "the first-start payload names task + kind (%s)" % started_payload)
+    _, failure_payload = decrypt_webpush(push.hits("/other")[-1], other_browser,
+                                         other_public, other_auth)
+    check(failure_payload["title"] == "Push failure task — failed"
+          and failure_payload["url"] == "/tasks/%d" % task2,
+          "the failure payload names the task and links its page")
+    check(len(push.hits("/main")) == main_before2,
+          "an agent failure never reaches users without the pref")
+
+    print("== task E: retry next tick (best-effort delivery) ==")
+    endpoint_flaky = push.url("/flaky")
+    act(auth, dash["push_subscribe"],
+        {"endpoint": endpoint_flaky, **subscribe_fields})
+    push.fail_next["/flaky"] = 1
+    flaky_before = len(push.hits("/flaky"))
+    raise_global_block("Flaky delivery question?")
+    check(wait_for(lambda: len(push.hits("/flaky")) >= flaky_before + 2,
+                   timeout=20, what="flaky endpoint retried") is not None,
+          "a failed send retries on the next dispatcher tick and lands")
+
+    print("== plan 12: goal notifications — blocks/success/failure always ==")
+    # Goal blocks, completion approval and failure push to EVERY
+    # subscribed user (the mirror on the goal-run task stays quiet).
+    push_goal = None
+    act(auth, slot_public(auth, "/goals", "goals")["create"], {
+        "project_id": "1", "title": "Push goal", "brief": "Notifies everyone.",
+        "branch_name": "goal/push"})
+    conn = db()
+    row = conn.execute("select id from goals where title = 'Push goal'").fetchone()
+    conn.close()
+    push_goal = int(row[0])
+    fake.goal_script = [("plan", "# Push plan\n\n1. Ring the bells")]
+    main_before = len(push.hits("/main"))
+    other_before = len(push.hits("/other"))
+    act(auth, goal_state(push_goal)["start"], {})
+    check(wait_for(lambda: goal_state(push_goal)["status"] == "plan_review" or False,
+                   timeout=60, what="push goal enters plan review") is not None,
+          "the push goal reaches plan review")
+    check(wait_for(lambda: len(push.hits("/main")) > main_before
+                   and len(push.hits("/other")) > other_before, timeout=15,
+                   what="goal plan-review push") is not None,
+          "a goal plan review notifies every subscribed user globally")
+    _, plan_payload = decrypt_webpush(push.hits("/other")[-1], other_browser,
+                                      other_public, other_auth)
+    check("Push goal" in plan_payload["title"] and "plan" in plan_payload["title"]
+          and plan_payload["url"] == "/goals/%d" % push_goal,
+          "the goal block payload carries the goal title + click URL (%s)"
+          % plan_payload)
+    main_before = len(push.hits("/main"))
+    fake.goal_script = [("suspend",)]
+    act(auth, goal_state(push_goal)["plan_pending_block"]["answer_action"],
+        {"answer": "Plan approved. Proceed with implementation."})
+    check(wait_for(lambda: goal_state(push_goal)["status"] == "active" or False,
+                   timeout=30, what="push goal active") is not None,
+          "the push goal activates")
+    check(quiet_window(3, lambda: len(push.hits("/main")) == main_before,
+                       "no push for an internal resume"),
+          "the goal agent's own park/resume does not notify (internal)")
+
+    # `saddle failure` in goal context fails the goal — global push.
+    fake.goal_script = [("fail", "the harness collapsed")]
+    other_before2 = len(push.hits("/other"))
+    main_before2 = len(push.hits("/main"))
+    conn = db()
+    conn.execute("insert into tasks (project_id, goal_id, kind, title, status,"
+                 " priority, completed_at, created_at) values (1, ?, 'task',"
+                 " 'Warm', 'done', 5,"
+                 " strftime('%s','now'),"
+                 " strftime('%s','now','-30 seconds'))", (push_goal,))
+    conn.commit()
+    conn.close()
+    check(wait_for(lambda: goal_state(push_goal)["status"] == "failed" or False,
+                   timeout=60, what="goal failure lands") is not None,
+          "the goal agent's failure fails the goal")
+    check(wait_for(lambda: len(push.hits("/other")) > other_before2
+                   and len(push.hits("/main")) > main_before2, timeout=15,
+                   what="goal failure push") is not None,
+          "a goal failure notifies every subscribed user globally")
+    _, fail_payload = decrypt_webpush(push.hits("/other")[-1], other_browser,
+                                      other_public, other_auth)
+    check("Push goal" in fail_payload["title"] and "failed" in fail_payload["title"]
+          and fail_payload["url"] == "/goals/%d" % push_goal,
+          "the goal failure payload carries the goal title + click URL (%s)"
+          % fail_payload)
+
+    # Completion approval pushes "complete" globally (success always).
+    act(auth, slot_public(auth, "/goals", "goals")["create"], {
+        "project_id": "1", "title": "Push done goal", "brief": "Completes.",
+        "branch_name": "goal/push-done"})
+    conn = db()
+    row = conn.execute("select id from goals where title = 'Push done goal'").fetchone()
+    conn.close()
+    done_goal = int(row[0])
+    fake.goal_script = [("plan", "# Done plan")]
+    act(auth, goal_state(done_goal)["start"], {})
+    check(wait_for(lambda: goal_state(done_goal)["status"] == "plan_review" or False,
+                   timeout=60, what="done goal plan review") is not None,
+          "the done goal reaches plan review")
+    fake.goal_script = [("done", "# Completion\n\nShipped.")]
+    act(auth, goal_state(done_goal)["plan_pending_block"]["answer_action"],
+        {"answer": "Plan approved. Proceed with implementation."})
+    check(wait_for(lambda: goal_state(done_goal)["status"] == "completion_review"
+                   or False, timeout=60, what="done goal completion review") is not None,
+          "the approved done goal reaches completion review")
+    main_before = len(push.hits("/main"))
+    act(auth, goal_state(done_goal)["completion_pending_block"]["answer_action"],
+        {"answer": "Review approved. Continue with the task."})
+    check(wait_for(lambda: goal_state(done_goal)["status"] == "complete" or False,
+                   timeout=30, what="done goal completes") is not None,
+          "the done goal completes")
+    check(wait_for(lambda: len(push.hits("/main")) > main_before, timeout=15,
+                   what="goal success push") is not None,
+          "a goal completion notifies every subscribed user globally")
+    _, done_goal_payload = decrypt_webpush(push.hits("/main")[-1], browser,
+                                           browser_public, rotated_auth)
+    check("Push done goal" in done_goal_payload["title"]
+          and "complete" in done_goal_payload["title"]
+          and done_goal_payload["url"] == "/goals/%d" % done_goal,
+          "the goal success payload carries the goal title + click URL (%s)"
+          % done_goal_payload)
+
+    print("== task E: unsubscribe removes the subscription ==")
+    dash = slot_public(auth, "/", "dashboard")
+    check(dash.get("push_subscribed") is True,
+          "the bell shows subscribed while endpoints exist")
+    act(auth, dash["push_unsubscribe"], {"endpoint": endpoint_main})
+    check(subscription_count(endpoint_main) == 0,
+          "unsubscribing removes the endpoint's row")

+ 341 - 0
test/bundles/replay.py

@@ -0,0 +1,341 @@
+"""The replay bundle (moved verbatim from the pre-split web_stack_test.py;
+see test/harness.py for the shared machinery and the runner)."""
+from harness import *  # noqa: F401,F403 — the shared wire helpers
+
+
+# =============================================================================
+# Bundle: replay — plan 13 B1/B2: the daemon-global entry dedup and the
+# idempotent terminal/narrative projections. Replays the live-failure
+# post-mortem shapes directly against the push channels: an outbox
+# redelivery arriving under the WRONG session id after churn (and after
+# a web restart), and repeated failure pushes that must still project
+# exactly once. Includes this shard's one deliberate app restart (the
+# dedup must survive it — it is database state, not memory).
+# =============================================================================
+
+def run(ctx):
+    auth, fake, fake_id, fake_token = ctx.auth, ctx.fake, ctx.fake_id, ctx.fake_token
+    app = ctx.app
+
+    def rows_for(session):
+        conn = db()
+        try:
+            return conn.execute(
+                "select count(*) from session_commands where session_id = ?",
+                (session,)).fetchone()[0]
+        finally:
+            conn.close()
+
+    def dedup_rows():
+        conn = db()
+        try:
+            return conn.execute("select count(*) from saddle_entry_dedup").fetchone()[0]
+        finally:
+            conn.close()
+
+    def open_session_on_fake(task_id):
+        """A fixture open session row on the shard's saddle (the churn
+        shape: a fresh web-side run row the daemon never really drove)."""
+        conn = db()
+        try:
+            conn.execute(
+                "insert into sessions (task_id, saddle_id, started_at)"
+                " values (?, ?, strftime('%s','now'))", (task_id, fake_id))
+            conn.commit()
+            return conn.execute(
+                "select max(id) from sessions where task_id = ?",
+                (task_id,)).fetchone()[0]
+        finally:
+            conn.close()
+
+    print("== plan 13 B1: entry dedup is daemon-global, not per-session ==")
+    # A first task runs to completion; its session is the replay source.
+    first = create_queued(auth, {"project_id": "1", "title": "Replay source task",
+                                 "priority": "2"})
+    check(wait_task_done(auth, first, timeout=60) is not None,
+          "the replay-source task completes")
+    conn = db()
+    src_session = conn.execute(
+        "select max(id) from sessions where task_id = ?", (first,)).fetchone()[0]
+    conn.close()
+
+    # The outbox batch: two command entries the daemon already
+    # delivered once (their ids landed with the source session).
+    burst = [
+        {"id": 5001, "command": "make test", "output": "ok", "exit_code": 0,
+         "type": "command", "timestamp": "2026-09-11T00:00:00Z"},
+        {"id": 5002, "command": "grep -r flange src/", "output": "src/flange.vala",
+         "exit_code": 0, "type": "command", "timestamp": "2026-09-11T00:00:01Z"},
+    ]
+    status, _ = saddle_api("POST", "/api/saddle/results", fake_token,
+                           {"session_id": src_session, "state": "done",
+                            "entries": burst})
+    check(status == 200 and rows_for(src_session) >= 2,
+          "the entries batch stores under its session")
+    stored_once = rows_for(src_session)
+    dedup_after_first = dedup_rows()
+
+    # Redelivery under the SAME session: consumed, nothing new.
+    status, _ = saddle_api("POST", "/api/saddle/results", fake_token,
+                           {"session_id": src_session, "state": "done",
+                            "entries": burst})
+    check(status == 200 and rows_for(src_session) == stored_once
+          and dedup_rows() == dedup_after_first,
+          "a same-session redelivery stores nothing new (consumed silently)")
+
+    # Session churn: a brand-new session id on the same saddle replays
+    # the SAME entry ids — the post-mortem's mis-keyed outbox send.
+    # The entries' ids already populated another session, so the push
+    # may not create rows here either.
+    conn = db()
+    conn.execute(
+        "insert into tasks (project_id, title, status, priority, created_at,"
+        " completed_at) values (1, 'Churn target task', 'done', 5,"
+        " strftime('%s','now'), strftime('%s','now'))")
+    conn.commit()
+    churn_task = conn.execute(
+        "select max(id) from tasks where title = 'Churn target task'").fetchone()[0]
+    conn.close()
+    churn_session = open_session_on_fake(churn_task)
+    status, _ = saddle_api("POST", "/api/saddle/results", fake_token,
+                           {"session_id": churn_session, "state": "done",
+                            "entries": burst})
+    check(status == 200 and rows_for(churn_session) == 0,
+          "replay-under-wrong-session stores nothing new (daemon-global dedup)")
+    check(dedup_rows() == dedup_after_first,
+          "the consumed redelivery claims no fresh dedup rows")
+
+    # A fresh entry id under the churned session DOES store — the dedup
+    # keys on the entry id, never on the session.
+    fresh = [{"id": 5003, "command": "git status", "output": "clean",
+              "exit_code": 0, "type": "command", "timestamp": "2026-09-11T00:00:02Z"}]
+    status, _ = saddle_api("POST", "/api/saddle/results", fake_token,
+                           {"session_id": churn_session, "state": "done",
+                            "entries": fresh})
+    check(status == 200 and rows_for(churn_session) == 1
+          and dedup_rows() == dedup_after_first + 1,
+          "a fresh entry id stores under any session of its saddle")
+
+    # Web restart: the dedup survives (database state, not memory).
+    app.terminate()
+    app.wait(timeout=10)
+    app = start_app()
+    auth = login("admin", "adminpass123")
+    ctx.app = app  # teardown tracks the restarted process
+    ctx.auth = auth
+    # The restart wiped the in-memory ask bookkeeping; the daemon
+    # re-establishes sleeping with a fresh ask (the real daemon's
+    # idle-awake ask / 15-minute safety self-ask).
+    fake.ask_now()
+    status, _ = saddle_api("POST", "/api/saddle/results", fake_token,
+                           {"session_id": churn_session, "state": "done",
+                            "entries": burst + fresh})
+    check(status == 200 and rows_for(churn_session) == 1
+          and rows_for(src_session) == stored_once,
+          "a post-restart redelivery still stores nothing (dedup is persistent)")
+
+    print("== plan 13 B2: duplicate failed entries project once (task) ==")
+    # The post-mortem's honest burst: the same failure entry redelivered
+    # under a churned session AND a second, DISTINCT failure entry id
+    # in the same session — one transition, one comment, ever.
+    def agent_comments(task_id, body=None):
+        conn = db()
+        try:
+            if body is None:
+                return conn.execute(
+                    "select count(*) from task_comments"
+                    " where task_id = ? and author = 'agent'",
+                    (task_id,)).fetchone()[0]
+            return conn.execute(
+                "select count(*) from task_comments"
+                " where task_id = ? and author = 'agent' and body = ?",
+                (task_id, body)).fetchone()[0]
+        finally:
+            conn.close()
+
+    conn = db()
+    conn.execute(
+        "insert into tasks (project_id, title, status, priority, created_at)"
+        " values (1, 'Burst failure task', 'working', 5, strftime('%s','now'))")
+    conn.commit()
+    burst_task = conn.execute(
+        "select max(id) from tasks where title = 'Burst failure task'").fetchone()[0]
+    conn.close()
+    burst_session = open_session_on_fake(burst_task)
+    first_fail = [{"id": 6001, "command": "saddle failure",
+                   "output": "bash -n rejected the script", "exit_code": 1,
+                   "type": "failed", "timestamp": "2026-09-11T00:01:00Z"}]
+    status, _ = saddle_api("POST", "/api/saddle/results", fake_token,
+                           {"session_id": burst_session, "state": "failed",
+                            "entries": first_fail,
+                            "summary": "bash -n rejected the script"})
+    check(status == 200
+          and task_state(auth, burst_task)["status"] == "failed",
+          "the failure entry + state pair fails the task")
+    check(agent_comments(burst_task, "bash -n rejected the script") == 0
+          and "bash -n rejected the script"
+          in (task_state(auth, burst_task).get("summary") or ""),
+          "the failure explanation lives ONCE — in tasks.summary, the terminal cache (S4: no duplicate agent comment)")
+
+    # The burst: a DISTINCT failure entry id in the same session, plus
+    # both ids redelivered under a churned session — nothing re-runs.
+    second_fail = [{"id": 6002, "command": "saddle failure",
+                    "output": "bash -n rejected the script", "exit_code": 1,
+                    "type": "failed", "timestamp": "2026-09-11T00:01:01Z"}]
+    churned_burst = open_session_on_fake(burst_task)
+    for target in (burst_session, churned_burst):
+        status, _ = saddle_api("POST", "/api/saddle/results", fake_token,
+                               {"session_id": target, "state": "failed",
+                                "entries": first_fail + second_fail,
+                                "summary": "bash -n rejected the script"})
+        check(status == 200,
+              "the burst push under %s is consumed, not rejected" % (
+                  "its session" if target == burst_session else "a churned session"))
+    check(task_state(auth, burst_task)["status"] == "failed"
+          and agent_comments(burst_task) == 0
+          and "bash -n rejected the script"
+          in (task_state(auth, burst_task).get("summary") or ""),
+          "duplicate failed entries leave one transition, one summary, zero agent comments (S4)")
+
+    print("== plan 13 B2: goal failure projects once ==")
+    # Goal context: `saddle failure` fails the goal ONCE — the 115
+    # goal-failed events of the live failure are structurally gone.
+    def goal_failed_events(goal_id):
+        # Plan 15 C3: the narrative derives at read time — the
+        # failed-goal row IS the goal-failed record (one row, ever).
+        return len([e for e in goal_state(goal_id)["events"]
+                    if e["kind"] == "goal-failed"])
+
+    act(auth, slot_public(auth, "/goals", "goals")["create"], {
+        "project_id": "1", "title": "Burst goal", "brief": "Fails honestly.",
+        "branch_name": "goal/burst"})
+    conn = db()
+    burst_goal = conn.execute(
+        "select id from goals where title = 'Burst goal'").fetchone()[0]
+    conn.close()
+    fake.goal_script = [("suspend",)]
+    act(auth, goal_state(burst_goal)["start"], {})
+    conn = db()
+    run_task = conn.execute(
+        "select id from tasks where goal_id = ? and kind = 'goal_run'",
+        (burst_goal,)).fetchone()[0]
+    conn.close()
+    check(wait_for(lambda: task_state(auth, run_task)["status"] == "suspended"
+                   or False, timeout=60, what="burst goal agent parks") is not None,
+          "the burst goal's agent parks first")
+    conn = db()
+    run_session = conn.execute(
+        "select id from sessions where task_id = ? and ended_at is null",
+        (run_task,)).fetchone()[0]
+    conn.close()
+
+    goal_fail = [{"id": 7001, "command": "saddle failure",
+                  "output": "the harness collapsed", "exit_code": 1,
+                  "type": "failed", "timestamp": "2026-09-11T00:02:00Z"},
+                 {"id": 7002, "command": "saddle failure",
+                  "output": "the harness collapsed", "exit_code": 1,
+                  "type": "failed", "timestamp": "2026-09-11T00:02:01Z"}]
+    status, _ = saddle_api("POST", "/api/saddle/results", fake_token,
+                           {"session_id": run_session, "state": "failed",
+                            "entries": goal_fail, "summary": "the harness collapsed"})
+    check(status == 200 and goal_state(burst_goal)["status"] == "failed",
+          "the goal agent's failure fails the goal")
+    check(goal_failed_events(burst_goal) == 1,
+          "a two-entry failure burst records exactly one goal-failed event")
+
+    # Redeliveries — same ids under the run's session AND under a
+    # churned session — plus the bare failed state again: still one.
+    churned_run = open_session_on_fake(run_task)
+    for target in (run_session, churned_run):
+        status, _ = saddle_api("POST", "/api/saddle/results", fake_token,
+                               {"session_id": target, "state": "failed",
+                                "entries": goal_fail,
+                                "summary": "the harness collapsed"})
+        check(status == 200, "the goal-failure redelivery under %s is consumed"
+              % ("its session" if target == run_session else "a churned session"))
+    check(goal_state(burst_goal)["status"] == "failed"
+          and goal_failed_events(burst_goal) == 1,
+          "redelivered failures never re-run the goal failure (one event, ever)")
+    check(task_state(auth, run_task)["status"] == "failed",
+          "the goal-run task stays failed after the replays")
+    conn = db()
+    burst_blocks = conn.execute(
+        "select count(*) from task_blocks where task_id = ?", (run_task,)
+    ).fetchone()[0]
+    conn.close()
+    check(burst_blocks == 0,
+          "the goal-failed path raises ZERO blocks (nothing pins the pile)")
+
+    print("== plan 13 B4: the comment projection stores the body ==")
+    # The heredoc shape: the command is the pipe invocation, the OUTPUT
+    # is the body. The projections must carry the body — the command
+    # echo never becomes comment text, and the literal `saddle
+    # comment` string never renders outside the terminal.
+    act(auth, slot_public(auth, "/goals", "goals")["create"], {
+        "project_id": "1", "title": "Comment goal", "brief": "Reports cleanly.",
+        "branch_name": "goal/comment"})
+    conn = db()
+    comment_goal = conn.execute(
+        "select id from goals where title = 'Comment goal'").fetchone()[0]
+    conn.close()
+    fake.goal_script = [("suspend",)]
+    act(auth, goal_state(comment_goal)["start"], {})
+    conn = db()
+    comment_run = conn.execute(
+        "select id from tasks where goal_id = ? and kind = 'goal_run'",
+        (comment_goal,)).fetchone()[0]
+    conn.close()
+    check(wait_for(lambda: task_state(auth, comment_run)["status"] == "suspended"
+                   or False, timeout=60, what="comment goal agent parks") is not None,
+          "the comment goal's agent parks")
+    conn = db()
+    comment_session = conn.execute(
+        "select id from sessions where task_id = ? and ended_at is null",
+        (comment_run,)).fetchone()[0]
+    conn.close()
+
+    comment_body = "The flange weld holds. First sentence carries the information."
+    comment_entry = [{"id": 8001, "command": "cat << 'EOF' | saddle comment",
+                      "output": comment_body, "exit_code": 0, "type": "comment",
+                      "timestamp": "2026-09-11T00:03:00Z"}]
+    status, _ = saddle_api("POST", "/api/saddle/results", fake_token,
+                           {"session_id": comment_session, "state": "suspended",
+                            "entries": comment_entry})
+    check(status == 200, "the comment entry push is accepted")
+    conn = db()
+    task_comment_bodies = [r[0] for r in conn.execute(
+        "select body from task_comments where task_id = ?", (comment_run,))]
+    tables = {r[0] for r in conn.execute(
+        "select name from sqlite_master where type = 'table'").fetchall()}
+    conn.close()
+    check(task_comment_bodies == [comment_body],
+          "the run task's comment stores the body, not the command echo")
+    check("goal_comments" not in tables,
+          "the goal_comments table is gone (the run task's rows are the thread)")
+    narrative_comments = [e["text"] for e in goal_state(comment_goal)["events"]
+                          if e["kind"] == "comment"]
+    check(len(narrative_comments) == 1
+          and narrative_comments[0].startswith("The flange weld holds.")
+          and "saddle comment" not in narrative_comments[0]
+          and "EOF" not in narrative_comments[0],
+          "the derived narrative's comment rows carry the body text")
+
+    state = goal_state(comment_goal)
+    check(state["current_command"] == comment_body,
+          "the goal page's current-activity line shows the comment body")
+    check(state["comments"] and state["comments"][0]["body"] == comment_body
+          and any(e["kind"] == "comment"
+                  and e["text"].startswith("The flange weld holds.")
+                  for e in state["events"]),
+          "the goal slot carries the body in its comments and narrative")
+    page = http_get_page(auth, "/goals/%d" % comment_goal)
+    check("saddle comment" not in page,
+          "the rendered goal page never shows the command echo")
+    check("event.kind == 'comment' ? ' footnote'" in page,
+          "the narrative's comment events render with footnote styling")
+    check(page.index('stm-markdown="comment.body"')
+          < page.index('stm-text="comment.quote"'),
+          "the comment card shows the body before the quote")
+
+    # Drain: nothing queued remains for the shard's shutdown.
+    check(queued_count() == 0, "the replay shard drains its queue")

+ 249 - 0
test/bundles/subtasks.py

@@ -0,0 +1,249 @@
+"""The subtasks bundle (moved verbatim from the pre-split web_stack_test.py;
+see test/harness.py for the shared machinery and the runner)."""
+from harness import *  # noqa: F401,F403 — the shared wire helpers
+
+
+# =============================================================================
+# Bundle: subtasks — the plan-12 task graph: plain-task parking (no
+# subtask events exist to resume it), the DELETED subtask machinery's
+# verbatim refusals, and the goal agent's task CLI in depth
+# (capabilities, ownership, the daemon's task-reading API, the
+# goal-run block answered from the task page).
+# =============================================================================
+
+def run(ctx):
+    auth, fake, fake_id, fake_token = ctx.auth, ctx.fake, ctx.fake_id, ctx.fake_token
+    app = ctx.app
+
+    # A hold tag nothing carries: goal tasks created with it stay
+    # queued (a stable parked agent) until released at the settle.
+    saddles_state = slot_public(auth, "/saddles", "saddles")
+    act(auth, saddles_state["create_capability"], {"name": "gpu"})
+    gpu_cap_id = [c["id"] for c in slot_public(auth, "/saddles", "saddles")["capabilities"]
+                  if c["name"] == "gpu"][0]
+
+    def create_goal_row(fields):
+        act(auth, slot_public(auth, "/goals", "goals")["create"], fields)
+        rows = [g for g in slot_public(auth, "/goals", "goals")["goals"]
+                if g["title"] == fields["title"]]
+        return int(rows[0]["id"])
+
+    print("== B7: plain-task parking stays put (no subtask events) ==")
+    fake.suspend_on_title = "Suspend plain"
+    pushes_before = len(fake.start_payloads)
+    plain = create_queued(auth, {
+        "project_id": "1",
+        "title": "Suspend plain",
+        "priority": "2",
+    })
+    check(wait_for(lambda: task_state(auth, plain).get("status") == "suspended"
+                   or False, timeout=60, what="plain task parks") is not None,
+          "daemon 'suspended' state parks the task")
+    detail = task_state(auth, plain)
+    check(detail.get("display") == "parked",
+          "a parked plain task displays as parked (%s)" % detail.get("display"))
+    check(any(s["status"] == "idle"
+              for s in slot_public(auth, "/saddles", "saddles")["saddles"]),
+          "suspension frees the saddle")
+    first_push = fake.start_payloads[pushes_before]
+    check(first_push.get("kind") == "task" and first_push.get("creator") == "human"
+          and first_push.get("mode") == "implement",
+          "the /start payload carries the plan-12 identity triplet (kind/creator/mode)")
+    check("subtasks" not in first_push and "parent" not in first_push,
+          "the plan-12 payload drops the subtasks/parent members")
+
+    # Other tasks finishing must NOT resume a parked plain task (the
+    # subtask-event channel is gone; only goal events resume goal runs).
+    conn = db()
+    conn.execute("insert into tasks (project_id, title, status, priority, summary,"
+                 " completed_at, created_at) values (1, 'Unrelated finisher', 'done',"
+                 " 5, 'finished loudly', strftime('%s','now','+1 second'),"
+                 " strftime('%s','now'))")
+    conn.commit()
+    conn.close()
+    check(quiet_window(quiet_seconds(),
+                       lambda: task_state(auth, plain)["status"] == "suspended",
+                       "plain park survives unrelated finishes"),
+          "a parked plain task never resumes on other tasks' events")
+
+    print("== the deleted machinery refuses, verbatim ==")
+    status, body = saddle_api("POST", "/api/saddle/subtask", fake_token,
+                              {"parent_task_id": plain, "title": "ghost"})
+    check(status == 404,
+          "the /api/saddle/subtask callback route is gone (404)")
+    # The poll-era ingest channel went with it (arch 19): the whole
+    # /update surface 404s — subtask and plan verb arms included — and
+    # the verdict channel (/poll) with it.
+    conn = db()
+    plain_session = conn.execute(
+        "select id from sessions where task_id = ? and ended_at is null",
+        (plain,)).fetchone()[0]
+    conn.close()
+    status, body = saddle_api("POST", "/api/saddle/%d/update" % fake_id, fake_token,
+                              {"type": "subtask", "session_id": plain_session,
+                               "data": {"title": "Ghost child"}})
+    check(status == 404,
+          "the /update ingest surface is gone (404, the subtask arm with it)")
+    status, body = saddle_api("POST", "/api/saddle/%d/update" % fake_id, fake_token,
+                              {"type": "plan", "session_id": plain_session,
+                               "data": {"plan": "# nope"}})
+    check(status == 404,
+          "the task-level 'plan' update arm is gone with the channel (404)")
+    # The daemon's task CLI: no parent/plan members; goal context instead.
+    status, body = saddle_api("GET", "/api/saddle/task/%d" % plain, fake_token)
+    check(status == 200 and "plan" not in body.get("task", {})
+          and "parent_task_id" not in body.get("task", {})
+          and "goal_id" in body.get("task", {}),
+          "the task CLI detail drops parent/plan and carries goal_id")
+    status, body = saddle_api("GET", "/api/saddle/tasks?project_id=1", fake_token)
+    check(status == 200 and all("parent_task_id" not in t and "goal_id" in t
+                                for t in body.get("tasks", [])),
+          "the task CLI list drops parent_task_id and carries goal_id")
+    # Settle the parked plain task: nothing will resume it — cancel it.
+    act(auth, task_state(auth, plain)["cancel"], {})
+    check(wait_for(lambda: task_state(auth, plain)["status"] == "failed" or False,
+                   timeout=30, what="parked plain task cancelled") is not None,
+          "the parked plain task cancels (the human cleanup path)")
+
+    print("== the goal agent's task CLI in depth ==")
+    goal = create_goal_row({"project_id": "1", "title": "Sequencing goal",
+                            "brief": "Fan tasks out with the CLI.",
+                            "branch_name": "goal/sequence"})
+    fake.goal_script = [("plan", "# Plan\n\n1. Fan out")]
+    act(auth, goal_state(goal)["start"], {})
+    check(wait_for(lambda: goal_state(goal)["status"] == "plan_review" or False,
+                   timeout=60, what="sequencing goal plans") is not None,
+          "the sequencing goal reaches plan review")
+    fake.goal_script = [("suspend",)]
+    act(auth, goal_state(goal)["plan_pending_block"]["answer_action"],
+        {"answer": "Plan approved. Proceed with implementation."})
+    conn = db()
+    run_task = conn.execute(
+        "select id from tasks where goal_id = ? and kind = 'goal_run'",
+        (goal,)).fetchone()[0]
+    agent_session = conn.execute(
+        "select id from sessions where task_id = ? and ended_at is null",
+        (run_task,)).fetchone()[0]
+    conn.close()
+    check(wait_for(lambda: task_state(auth, run_task)["status"] == "suspended"
+                   or False, timeout=60, what="sequencing agent parks") is not None,
+          "the sequencing goal agent parks")
+
+    # Create with capabilities: attached until assignment (the hold
+    # keeps the task queued), mandate + mode stored, ephemeral branch.
+    status, body = saddle_api("POST", "/api/saddle/task/create", fake_token, {
+        "session_id": agent_session, "title": "Held worker",
+        "mandate": "Do the held work.", "mode": "review",
+        "capabilities": ["gpu"]})
+    check(status == 200 and body.get("ok") is True,
+          "task create with a capability tag succeeds")
+    held = int(body["task_id"])
+    detail = task_state(auth, held)
+    check(detail["status"] == "draft" and detail["mode"] == "review",
+          "the held worker drafts with its mode")
+    check([c["name"] for c in detail.get("capabilities", [])] == ["gpu"],
+          "the capability attaches to the created task")
+    check(detail["task_branch"] == "task/%d-%d" % (goal, held)
+          and detail["branch_from"] == "goal/sequence",
+          "the CLI task's ephemeral branch pair is stored")
+    status, body = saddle_api("POST", "/api/saddle/task/enqueue", fake_token, {
+        "session_id": agent_session, "task_id": held})
+    check(status == 200, "the held worker enqueues")
+    check(quiet_window(3, lambda: task_state(auth, held)["status"] == "queued",
+                       "unsatisfiable capability holds dispatch"),
+          "the unsatisfiable capability holds the queued worker (never assigned)")
+    queue_row = [t for t in slot_public(auth, "/tasks", "tasks")["tasks"]
+                 if int(t["id"]) == held][0]
+    check(queue_row.get("waiting_for_saddle") is True,
+          "the queue annotates the held worker as waiting for a saddle")
+
+    # The human edit path: goal tasks never carry enqueue-after (the
+    # field is human-tasks-only — the update silently ignores it).
+    act(auth, task_state(auth, held)["update"], {
+        "priority": "4", "enqueue_after_task_id": str(held - 1)})
+    check(task_state(auth, held).get("enqueue_after_task_id") in (None, 0, "0"),
+          "a goal task ignores the auto-enqueue-after field on edit")
+
+    # Ownership: the same saddle's goal agent cannot touch another
+    # goal's task; a plain session is not a goal-agent identity.
+    other_goal = create_goal_row({"project_id": "1", "title": "Other goal",
+                                  "brief": "b", "branch_name": "goal/other",
+                                  "priority": "9"})
+    status, body = saddle_api("POST", "/api/saddle/task/create", fake_token,
+                              {"session_id": agent_session, "title": "x",
+                               "mandate": "m"})
+    scope_task = int(body["task_id"])
+    check(int(task_state(auth, scope_task)["goal_id"] or 0) == goal,
+          "the callback scopes task creation to its own goal")
+    status, body = saddle_api("POST", "/api/saddle/task/delete", fake_token,
+                              {"session_id": agent_session, "task_id": scope_task})
+    check(status == 200, "the owned draft deletes")
+    check(not any(t["id"] == scope_task
+                  for t in slot_public(auth, "/tasks", "tasks")["tasks"]),
+          "the deleted task is gone from the queue")
+    status, body = saddle_api("POST", "/api/saddle/task/enqueue", fake_token,
+                              {"session_id": agent_session, "task_id": plain})
+    check(status == 400 and "does not belong to your goal" in (body.get("error") or ""),
+          "the goal agent cannot enqueue a standalone task")
+    # The daemon's task CLI detail carries the goal context.
+    status, body = saddle_api("GET", "/api/saddle/task/%d" % held, fake_token)
+    check(status == 200
+          and int(body["task"].get("goal_id") or 0) == goal
+          and body["task"].get("goal_title") == "Sequencing goal",
+          "the task CLI detail names the owning goal")
+
+    print("== the goal-run block answers from the task page (C1) ==")
+    # A question block raised in goal context lands on the run task's
+    # own row; the TASK page's answer action funnels into the one
+    # goal answer path and resumes the agent with the verdict riding
+    # the allocation (the goal page shares the path).
+    fake.goal_script = [("question", "Which harness: pytest or vitest?",
+                         ["pytest", "vitest"])]
+    conn = db()
+    # Plan 15 C3: a terminal transition (a done task row newer than
+    # the watermark) is the resume signal — no event rows exist.
+    conn.execute("insert into tasks (project_id, goal_id, kind, title, status,"
+                 " priority, completed_at, created_at) values (1, ?, 'task',"
+                 " 'Nudge', 'done', 5,"
+                 " strftime('%s','now'),"
+                 " strftime('%s','now','-30 seconds'))", (goal,))
+    conn.commit()
+    conn.close()
+    check(wait_for(lambda: task_state(auth, run_task)["status"] == "blocked"
+                   or False, timeout=60, what="goal block parks the run") is not None,
+          "a goal question parks the run task on its own block row")
+    run_detail = task_state(auth, run_task)
+    question_block = [b for b in run_detail["blocks"]
+                      if b["block_type"] == "question"][0]
+    check(question_block.get("question") == "Which harness: pytest or vitest?",
+          "the run task's block carries the goal question verbatim")
+    goal_block_ids = [int(b["id"]) for b in goal_state(goal)["blocks"]
+                      if b.get("block_type") == "question"]
+    check(goal_block_ids == [int(question_block["id"])],
+          "the goal page's card is the SAME row (no dual-row pair)")
+    act(auth, question_block["answer_action"], {"answer": "pytest"})
+    fake.goal_script = [("suspend",)]
+    check(wait_for(lambda: task_state(auth, run_task)["status"] == "suspended"
+                   or False, timeout=60, what="answered block resumes the agent")
+          is not None,
+          "the answered block resumes the goal agent")
+    answered = [b for b in task_state(auth, run_task)["blocks"]
+                if b["block_type"] == "question"][0]
+    check(answered.get("answer") == "pytest",
+          "the verdict is stored on the single block row")
+
+    print("== settle: release the hold and let the shard drain ==")
+    # Drop the hold tag so the held worker can dispatch and complete;
+    # the parked agent resumes on its completion, re-parks (script),
+    # and the shard shuts down with an empty queue.
+    act(auth, task_state(auth, held)["capabilities"][0]["detach"], {})
+    check(wait_task_done(auth, held, timeout=90) is not None,
+          "the released held worker completes")
+    check(wait_for(lambda: any(e["kind"] == "task-done" and int(e["task_id"]) == held
+                               for e in goal_state(goal)["events"]) or False,
+                   timeout=30, what="narrative hears the held worker") is not None,
+          "the narrative records the held worker's completion")
+    act(auth, goal_state(goal)["cancel"], {})
+    check(wait_for(lambda: goal_state(goal)["status"] == "cancelled" or False,
+                   timeout=30, what="sequencing goal cancelled") is not None,
+          "the sequencing goal cancels (the shard's cleanup path)")

+ 1388 - 0
test/harness.py

@@ -0,0 +1,1388 @@
+#!/usr/bin/env python3
+"""The web-stack test harness (plan 16 R5, arch 18): everything the
+scenario bundles share, plus the parallel runner.
+
+Layout: test/harness.py (this file — the FakeSaddle daemon, the
+http/act/login/slot_public wire helpers, wait_for/quiet_window/db/check,
+the per-shard fixtures via start_bundle/Ctx, and run_bundle +
+run_all_parallel); test/bundles/<name>.py (one module per bundle, its
+run(ctx) driving that shard's scenarios); test/web_stack_test.py (the
+thin entry shim meson invokes; it also stays directly runnable for the
+per-bundle shard processes the parallel runner spawns).
+
+Unlike integration_test.py (which needs a real saddle daemon and a mock
+LLM), this suite spawns everything it needs:
+
+- the clanker-saddle app binary (path from argv[1], or builddir default)
+  in a scratch directory with its own web-config.json (statum keys copied
+  from the repo, plus `saddle_callback_base_url`) and SQLite database
+- in-process fake saddle daemons speaking the wire contract: POST
+  /register (plan 10: receives {saddle_token, web_base_url}, answers
+  {ok, ssh_public_key, version}), POST /wake (records the wake; the
+  daemon then asks POST /api/saddle/next-task), POST /task-update
+  (cancel/comment/subtask-status), GET /status (scripted reflection —
+  exceptional use only), and the phase-2 push channels home:
+  POST /api/saddle/chunks (raw PTY batches) and POST /api/saddle/results
+  (round entries + state transitions). The retired /start, /output and
+  /log routes 404 like a post-phase-2 daemon.
+
+It then drives the app the way statum.js does (entrypoint loads + action
+POSTs) and asserts the Workstream B features against the wire contract:
+
+3. plan-review blocks hide their duplicate body preview
+5. rules CRUD/attach + the effective `rules` array in assignments
+6. project notes, POST /api/saddle/note, `project_notes` + `callback`
+   in assignments
+   plus the raw-log side: pushed chunks -> session_raw_log + terminal
+   raw view
+
+Plan 10 phase 1 (work acquisition flip):
+
+- per-saddle tokens: registration mints + /register-delivers them,
+  the row is the single credential store (the api_tokens fallback
+  died with arch 24), removal revokes
+- token auth on every /api/saddle/* endpoint
+- next-task allocation: concurrent asks race exactly one winner,
+  affinity pinning for parked tasks, resume_notice on suspended resumes
+- dispatcher: wake -> ask -> allocate roundtrip, the lost-wake guard
+  (no ask after a wake -> offline, re-wake the next capable), and the
+  pre-flip /answer + /start resume paths kept as the rollback route
+
+Plan 10 phase 2 (telemetry flip):
+
+- pushed chunks: idempotent on (session_id, seq), ordered, landing in
+  session_raw_log so the SSE terminal keeps working
+- pushed results: entries store like the /output path did (redelivery
+  idempotent on the daemon entry ids), blocked raises the block row +
+  parks + bumps the pulse (sealed refresh shows it), done/failed
+  complete/fail the task, suspended parks for the affinity resume
+- answer resumes, both daemon shapes: a SLEEPING affine saddle (its
+  post-park ask returned 204) is woken, its ask allocating the resume
+  with the verdict riding the assignment; a daemon parked MID-ROUND
+  (its round holds the block's answer wait open, so it can never ask)
+  gets the verdict delivered into that wait via POST /answer — same
+  session, no wake. A daemon dying with a parked-with-answered task
+  never requeues it: the verdict and session survive for the resume
+- staleness: a silent runner gets ONE exceptional GET /status probe —
+  alive keeps it running, dead requeues the task with an agent comment and
+  marks the saddle offline; a recovered daemon's ask flips offline rows
+  back to idle
+- the deleted layers are gone: /output, /log and /start 404 on the
+  daemon side, and nothing on the web side calls them
+
+Plan 10 phase 3 (capability awareness + UI):
+
+- assignment capability context: {saddle_tags, fleet_tags} on every
+  payload, GET /api/saddle/capabilities (per-saddle token) feeding
+  the daemon's `saddle capabilities` CLI
+- subtask callback capabilities: explicit-only attachment validated
+  against the operator tag set, unknown tags rejected with the valid
+  list in the error
+- task page: status block pinned to the top, blocking sections
+  newest-first (sealed GET state)
+- home dashboard: pinned OPEN blocks as newest-first link-through
+  cards (no inline answer forms) above the cross-task activity
+  timeline (last ~50 events newest-first)
+- lost-wake-guard regression: a saddle that asks SLOWLY after its
+  wake (busy winding down) still claims the task — the wake is never
+  silently dropped, no re-wake storm fires, and the never-asks guard
+  path (offline + re-wake of the next capable) stays green
+
+Prints PASS/FAIL lines Statum-style; exits non-zero on any failure.
+
+Plan 11 task D+E (UI + notifications), the `push` shard:
+
+- task page: progress feed above the status card, status + description
+  in a 50/50 grid, edit expander under the history expander, plan
+  behind an expander, answered blocks behind an expander; queue screen:
+  New Task expander above the filters; dashboard waiting-on-drafts
+  block with links to where Enqueue lives (pages shard)
+- real Web Push over VAPID: keypair generated at startup into
+  web-config.json, GET /sw.js service worker with click-through,
+  subscribe/unsubscribe + per-task Notify me actions, block events and
+  waiting-on-drafts pushed globally, first start/failure/completion to
+  opted-in users, best-effort queue with dispatcher-tick retry, 410/404
+  endpoint pruning — payloads verified protocol-level (RFC 8291
+  decryption + ES256 JWT signature) because the harness owns the
+  browser-side keys
+
+Heredoc completion reports (pages shard):
+
+- terminal tasks render tasks.summary (set by done/fail) as a
+  markdown completion-report card below the status/description grid —
+  "Completion report" when done, "Failure summary" when failed, no
+  card when empty; the summary renders through the shipped
+  stm-markdown renderer (headings/code, no syntax leaks, HTML
+  escaped) and the dashboard timeline snippets its first line
+
+Speed pass (plan 11, task 0):
+
+- SHARDING: the scenario groups are partitioned into seven independent
+  bundles (pages, dispatch, subtasks, lineage, allocation, lifecycle,
+  answers), each running in its own process against its own app
+  instance, fake daemons and SQLite database. The default invocation
+  runs all bundles in parallel and aggregates the verdicts and check
+  counts into one exit code — meson sees a single green/red test.
+  `--bundle NAME` runs one shard for debugging; WEBSTACK_SEQUENTIAL=1
+  runs them in-process, one after another.
+- Within a bundle, scenario groups SHARE the app+daemon instance and
+  carry per-group state as database rows (task/session/block
+  fixtures), never process restarts; the one deliberate restart (the
+  startup token migration) lives in the answers bundle.
+- EVENT-DRIVEN WAITS: wait_for polls at 50ms; the fixed sleeps were
+  converted either to observable-condition waits (daemon-side
+  counters, e.g. failed-delivery hits) or to quiet_window() — a
+  bounded negative-assertion poll that FAILS LOUDLY the moment the
+  event it guards against happens (a sleep could silently pass).
+- ENV KNOBS: SADDLE_DISPATCH_TICK_S=1 (dispatcher cadence; default 5
+  in production), SADDLE_HTTP_TIMEOUT_S=2, SADDLE_LOST_WAKE_S=2,
+  SADDLE_STALE_S=3, plus the fake daemon's scripted timings — the
+  wire-traffic shapes stay realistic, just faster.
+"""
+import json
+import os
+import re
+import shutil
+import socket
+import sqlite3
+import subprocess
+import sys
+import threading
+import time
+import urllib.error
+import urllib.parse
+import urllib.request
+from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
+
+# Web Push protocol verification (plan 11 task E): the test harness
+# owns the browser-side keys, so it can do everything the push service
+# does — decrypt the RFC 8291 body and verify the ES256 VAPID JWT.
+import base64
+from cryptography.hazmat.primitives import hashes
+from cryptography.hazmat.primitives.asymmetric import ec
+from cryptography.hazmat.primitives.asymmetric.utils import encode_dss_signature
+from cryptography.hazmat.primitives.ciphers.aead import AESGCM
+from cryptography.hazmat.primitives.kdf.hkdf import HKDF
+from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat
+
+REPO = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+APP = os.path.abspath(sys.argv[1]) if len(sys.argv) > 1 else os.path.join(REPO, "builddir", "clanker-saddle")
+
+# --- speed-pass tuning -----------------------------------------------------
+# The fake daemon's scripted timings and the dispatch-tick cadence the
+# quiet windows are sized against. All overridable for debugging.
+TICK_S = float(os.environ.get("SADDLE_DISPATCH_TICK_S", "1") or 1)
+FAKE_WORK_S = float(os.environ.get("WEBSTACK_FAKE_WORK_S", "1.2") or 1.2)
+FAKE_FAIL_S = float(os.environ.get("WEBSTACK_FAKE_FAIL_S", "0.5") or 0.5)
+FAKE_HEARTBEAT_S = float(os.environ.get("WEBSTACK_FAKE_HEARTBEAT_S", "0.4") or 0.4)
+FAKE_TRIGGER_S = float(os.environ.get("WEBSTACK_FAKE_TRIGGER_S", "0.05") or 0.05)
+SHARD_TIMEOUT_S = float(os.environ.get("WEBSTACK_SHARD_TIMEOUT_S", "600") or 600)
+
+
+def quiet_seconds():
+    """A negative-assertion window spanning several dispatch ticks (the
+    converted fixed sleeps were 3-7s at the old 5s tick; the bound never
+    exceeds the old timeout)."""
+    return min(2 * TICK_S + 0.8, 7.0)
+
+
+WORK = os.environ.get("WEBSTACK_WORK", "/tmp/kilo/webstack-e2e")
+DB_PATH = os.path.join(WORK, "web.sqlite")
+
+passes = 0
+failures = 0
+
+# The current shard's fixture context (goal_state reads its auth — the
+# restart scenarios re-login and re-point ctx.auth mid-run)
+CTX = None
+
+
+def check(condition, label):
+    global passes, failures
+    if condition:
+        passes += 1
+        print("PASS %s" % label)
+    else:
+        failures += 1
+        print("FAIL %s" % label)
+
+
+def free_port():
+    with socket.socket() as sock:
+        sock.bind(("127.0.0.1", 0))
+        return sock.getsockname()[1]
+
+
+APP_PORT = free_port()
+DAEMON_PORT = free_port()
+WEB = "http://127.0.0.1:%d" % APP_PORT
+
+
+def bundle_env(name):
+    """Point the module's runtime globals at one shard's scratch dir,
+    database and ports (each bundle is a process with its own app,
+    daemons and SQLite file)."""
+    global WORK, DB_PATH, APP_PORT, DAEMON_PORT, WEB
+    base = os.environ.get("WEBSTACK_WORK", "/tmp/kilo/webstack-e2e")
+    WORK = "%s-%s" % (base, name)
+    DB_PATH = os.path.join(WORK, "web.sqlite")
+    APP_PORT = free_port()
+    DAEMON_PORT = free_port()
+    WEB = "http://127.0.0.1:%d" % APP_PORT
+
+
+def http(method, url, data=None, headers=None, timeout=30):
+    body = None
+    if data is not None:
+        pairs = []
+        for k, v in data.items():
+            for item in (v if isinstance(v, (list, tuple)) else [v]):
+                pairs.append((k, item))
+        body = "&".join("%s=%s" % (k, urllib.parse.quote(str(item))) for k, item in pairs).encode()
+    request = urllib.request.Request(WEB + url if url.startswith("/") else url,
+                                     data=body, method=method)
+    if data is not None:
+        request.add_header("Content-Type", "application/x-www-form-urlencoded")
+    for key, value in (headers or {}).items():
+        request.add_header(key, value)
+    # Retry dropped/refused connections: the freshly started app can
+    # close a very early keep-alive connection once while warming up,
+    # and its first seconds can wobble under load.
+    for attempt in range(3):
+        try:
+            with urllib.request.urlopen(request, timeout=timeout) as response:
+                return response.status, response.read().decode()
+        except urllib.error.HTTPError as error:
+            return error.code, error.read().decode()
+        except (urllib.error.URLError, OSError):
+            if attempt >= 2:
+                raise
+            time.sleep(0.75)
+
+
+def directives(uri, auth=None):
+    headers = {}
+    if auth:
+        headers["X-Statum-Slot"] = "key=%s; as_at=%s" % (auth["key"], auth["as_at"])
+    status, body = http("GET", "/_statum/entrypoint?uri=" + urllib.parse.quote(uri.split("?")[0]),
+                        headers=headers)
+    if status != 200:
+        raise SystemExit("entrypoint %s -> HTTP %d: %s" % (uri, status, body[:300]))
+    return json.loads(body)
+
+
+def slot_public(auth, uri, type_name):
+    for directive in directives(uri, auth):
+        if directive["type"] == "set":
+            content = directive["snapshot_frame"].get("content")
+            if not content:
+                continue
+            content = json.loads(content)
+            if content["slot"]["type"] == type_name:
+                return content["public"]
+    raise SystemExit("no %s slot in entrypoint state for %s" % (type_name, uri))
+
+
+def act(auth, action, fields):
+    headers = {"X-Statum-Slot": "key=%s; as_at=%s" % (auth["key"], auth["as_at"])}
+    if action.get("private"):
+        headers["X-Statum-Private"] = action["private"]
+    status, body = http(action.get("method", "POST"), action["uri"], fields, headers)
+    if status != 200:
+        raise SystemExit("action %s -> HTTP %d: %s" % (action["uri"], status, body[:300]))
+    return json.loads(body)
+
+
+def login(username, password):
+    frames = directives("/login")
+    content = json.loads(frames[0]["snapshot_frame"]["content"])
+    action = content["public"]["login"]
+    status, body = http(action.get("method", "POST"), action["uri"],
+                        {"username": username, "password": password})
+    if status != 200:
+        raise SystemExit("login -> HTTP %d: %s" % (status, body[:300]))
+    for directive in json.loads(body):
+        if directive["type"] == "set":
+            frame = json.loads(directive["snapshot_frame"]["content"])
+            if frame["slot"]["type"] == "auth":
+                return {"key": frame["slot"]["key"], "as_at": frame["as_at"]}
+    raise SystemExit("login response carried no auth slot: " + body[:300])
+
+
+def wait_for(predicate, timeout=60, what="condition", interval=0.05):
+    deadline = time.monotonic() + timeout
+    last = None
+    while time.monotonic() < deadline:
+        last = predicate()
+        if last is not False and last is not None:
+            return last
+        time.sleep(interval)
+    print("  (timeout waiting for %s; last: %s)" % (what, last))
+    dump_threads()
+    return None
+
+
+def quiet_window(seconds, predicate, what):
+    """A converted fixed sleep: asserts a NEGATIVE condition (nothing may
+    happen) across a window spanning several dispatch ticks, polling at
+    50ms. The moment the condition breaks the window fails loudly
+    (diagnostics + thread dump) instead of silently passing a sleep."""
+    deadline = time.monotonic() + seconds
+    while time.monotonic() < deadline:
+        value = predicate()
+        if value is False or value is None:
+            remaining = deadline - time.monotonic()
+            print("  (quiet window '%s' broken after %.2fs of %.2fs — the"
+                  " guarded event DID happen)" % (what, seconds - remaining, seconds))
+            dump_threads()
+            return False
+        time.sleep(0.05)
+    return True
+
+
+def dump_threads():
+    """Stacks of suite threads not parked in sleep — pinpoints a wedged
+    fake lifecycle when a wait times out."""
+    import traceback
+    shown = 0
+    for thread_id, frame in sys._current_frames().items():
+        stack = "".join(traceback.format_stack(frame)[-4:])
+        if (("harness.py" in stack or "bundles" in stack
+             or "web_stack_test.py" in stack) and ("sleep" not in stack)
+                and shown < 6):
+            shown += 1
+            print("  --- thread %s ---\n%s" % (thread_id, stack))
+
+
+def task_state(auth, task_id):
+    return slot_public(auth, "/tasks/%d" % task_id, "task")
+
+
+def wait_task_done(auth, task_id, timeout=90):
+    return wait_for(lambda: task_state(auth, task_id).get("status") == "done" or False,
+                    timeout=timeout, what="task %d -> done" % task_id)
+
+
+def task_id_of(title):
+    conn = db()
+    try:
+        return conn.execute("select id from tasks where title = ?", (title,)).fetchone()[0]
+    finally:
+        conn.close()
+
+
+def enqueue_task(auth, task_id):
+    """The human-only Enqueue action (plan 11): draft -> queued."""
+    detail = task_state(auth, task_id)
+    assert detail["status"] == "draft", "task %d not in draft (%s)" % (task_id, detail["status"])
+    act(auth, detail["enqueue"], {})
+    return task_state(auth, task_id)["status"]
+
+
+def create_queued(auth, fields):
+    """Create via the queue form (lands in draft) and enqueue it — the
+    standard 'this task should dispatch' fixture of the plan-11 world."""
+    act(auth, slot_public(auth, "/tasks", "tasks")["create"], fields)
+    task_id = int([t["id"] for t in slot_public(auth, "/tasks", "tasks")["tasks"]
+                   if t["title"] == fields["title"]][0])
+    enqueue_task(auth, task_id)
+    return task_id
+
+
+def saddle_api(method, path, token, payload=None):
+    """Raw call against the saddle ingest API; returns (status, json)."""
+    request = urllib.request.Request(WEB + path,
+                                     data=json.dumps(payload or {}).encode(), method=method)
+    request.add_header("Content-Type", "application/json")
+    if token is not None:
+        request.add_header("Authorization", "Bearer " + token)
+    try:
+        with urllib.request.urlopen(request, timeout=15) as response:
+            return response.status, json.loads(response.read().decode() or "{}")
+    except urllib.error.HTTPError as error:
+        body = error.read().decode()
+        try:
+            return error.code, json.loads(body)
+        except ValueError:
+            return error.code, {"raw": body}
+
+
+def db():
+    return sqlite3.connect(DB_PATH)
+
+
+def http_get_page(auth, uri):
+    """The compiled page HTML for a statum route (auth via the slot
+    header), for asserting page-level embeds the slot state cannot
+    see."""
+    status, body = http("GET", uri, headers={
+        "X-Statum-Slot": "key=%s; as_at=%s" % (auth["key"], auth["as_at"])})
+    if status != 200:
+        raise SystemExit("GET %s -> HTTP %d" % (uri, status))
+    return body
+
+
+def goal_state(goal_id):
+    """The goal slot for the CURRENT shard's admin login (the x7
+    per-bundle duplicates collapsed here, plan 16 R5). Reads the
+    runner's fixture context — the restart scenarios re-login and
+    re-point ctx.auth mid-run, and late binding follows."""
+    return slot_public(CTX.auth, "/goals/%d" % goal_id, "goal")
+
+
+def saddle_card(auth, name):
+    rows = [s for s in slot_public(auth, "/saddles", "saddles")["saddles"]
+            if s["name"] == name]
+    return rows[0]
+
+
+def queued_count():
+    conn = db()
+    try:
+        return conn.execute(
+            "select count(*) from tasks where status = 'queued'").fetchone()[0]
+    finally:
+        conn.close()
+
+
+def command_rows(session):
+    conn = db()
+    try:
+        return conn.execute(
+            "select command_text, type from session_commands"
+            " where session_id = ? order by id", (session,)).fetchall()
+    finally:
+        conn.close()
+
+
+class FakeSaddle:
+    """In-process saddle daemon implementing the wire contract.
+
+    Phase-2 push behaviour: the daemon asks POST /api/saddle/next-task
+    whenever idle-awake (at registration, on POST /wake, after its task
+    reaches a terminal state, and when a /status probe observes it
+    parked idle — throttled), accepts assignments like POST /start used
+    to, then PUSHES its telemetry home: raw PTY chunks via POST
+    /api/saddle/chunks and round results with state transitions via
+    POST /api/saddle/results (working at round start, terminal states
+    when the scripted lifecycle ends them). /output, /log and /start
+    are gone (404) like a post-phase-2 daemon; /task-update serves the
+    cancel/comment/subtask-status kinds; POST /answer receives a
+    delivered verdict when the round is parked in a block's answer
+    wait (409 when nothing waits — the real daemon's contract; the
+    resumed round continues after the response). Every trigger can be
+    disabled per test for determinism; ask_now() performs a
+    synchronous manual ask.
+    """
+
+    PROMPT = "bbarrow@fedora:/workspace/task-1$ "
+
+    def __init__(self):
+        self.lock = threading.Lock()
+        self.start_payloads = []       # captured assignment payloads (/start + next-task 200s)
+        self.state = "idle"
+        self.summary = ""
+        self.state_entered = time.monotonic()
+        self.fail_next = False          # next task drives the task to failed
+        self.start_counts = {}          # task id -> assignment count
+        self.resumed_pending = False    # crash-resume flag on the next /status
+        self.suspend_on_title = None    # this task (by title) parks as suspended
+        self.output_seq = 100           # daemon-global entry ids for pushed results
+        self.last_activity_epoch = int(time.time())
+        self.hang_next = {}             # path suffix -> hang count (never responds)
+        self.abort_failures = 0          # cancel task-updates failing (500) while > 0
+        self.abort_log = []              # task ids aborted via task-update cancel
+        self.running_task = 0            # task id the daemon believes it runs
+        self.running_title = ""          # its title (suspend targeting)
+        self.session_id = None           # the web-side run row of the running task
+        self.hold_state = False          # freeze lifecycle + heartbeat pushes
+        self.ssh_public_key = ""         # reported on /status + /register
+        self.started_mono = time.monotonic()
+        self.freeze_activity = False     # hold last_activity_epoch still
+        self.silent = False              # suppress pushes (staleness tests)
+        self.dead = False                # kill(): no serving AND no calls home
+        self.status_hits = 0             # GET /status arrivals (probe accounting)
+        self.comment_log = []            # recorded /task-update comment payloads
+        self.scripted_corpus = None      # chunk batch pushed when a task starts
+        # --- plan 10 phase 1: ask/wake/register ---
+        self.token = None                # per-saddle token from POST /register
+        self.register_log = []           # recorded /register bodies
+        self.wake_log = []               # recorded POST /wake arrivals
+        self.asks = []                   # [{"status": int, "payload": dict|None}]
+        self.ask_on_register = True
+        self.ask_on_wake = True
+        self.ask_on_terminal = True
+        self.ask_on_idle_status = True
+        self.ask_delay = 0.0             # seconds; a slow daemon delays its wake-triggered ask
+        self.serve_register = True         # False: 404 /register (pre-flip daemon)
+        self.last_ask_trigger = 0.0
+        self.port = None
+        self.ask_threads = []            # scheduled ask-trigger threads (settle_asks joins them)
+        # --- answer delivery (the parked-session resume) ---
+        self.pending_block = None        # the block payload this daemon waits on (state blocked)
+        self.answer_log = []             # recorded POST /answer bodies
+        self.answer_push_delay = 0.2     # the resumed round's first push, after the response
+        # --- plan 12: goal-agent scripting ---
+        self.goal_script = []            # behaviours consumed per goal-run assignment
+        self.goal_behaviour = None       # the current round's popped behaviour
+        self.goal_assignments = []       # captured goal-run assignment payloads
+
+    def set_state(self, state, summary=None):
+        """Advances the scripted lifecycle."""
+        self.state = state
+        if summary is not None:
+            self.summary = summary
+        self.state_entered = time.monotonic()
+
+    def touch_activity(self):
+        if not self.freeze_activity:
+            self.last_activity_epoch = int(time.time())
+
+    def queue_output(self, entry_type, command, output):
+        """Pushes a typed entry as a round-results push (the daemon's
+        entry log riding the results channel)."""
+        with self.lock:
+            entry = {
+                "id": self.output_seq,
+                "command": command,
+                "output": output,
+                "exit_code": 1,
+                "type": entry_type,
+                "timestamp": "2026-09-06T00:00:00Z",
+            }
+            self.output_seq += 1
+        self.push_results(self.state if self.state in ("working",) else "working",
+                          entries=[entry])
+
+    # --- plan 10 phase 2: the push channels ---
+
+    def push_chunks(self, chunks):
+        """Pushes raw PTY chunks home: elements are texts (assigned
+        fresh seqs) or {seq, text} dicts (a redelivery or explicit
+        corpus). Pushes are suppressed while silent/hold_state (the
+        staleness tests' silent runner)."""
+        if self.dead or self.silent or self.token is None or self.session_id is None:
+            return
+        batch = []
+        with self.lock:
+            for chunk in chunks:
+                if isinstance(chunk, dict):
+                    batch.append({"seq": int(chunk["seq"]), "text": chunk["text"]})
+                else:
+                    batch.append({"seq": self.next_push_seq(), "text": chunk})
+        try:
+            saddle_api("POST", "/api/saddle/chunks", self.token,
+                       {"session_id": self.session_id, "chunks": batch})
+        except (OSError, ValueError):
+            pass  # app restarting / shutting down mid-test
+
+    def next_push_seq(self):
+        # The daemon-side chunk counter for ad-hoc pushes.
+        self._push_seq = getattr(self, "_push_seq", 0) + 1
+        return self._push_seq
+
+    def push_results(self, state, entries=None, block=None, summary=None, session_id=None):
+        """Pushes one round-results payload home (state transition plus
+        its entries). Returns the HTTP status when it went out, None
+        when suppressed."""
+        if self.dead or self.silent:
+            return None
+        if self.token is None:
+            return None
+        target = session_id if session_id is not None else self.session_id
+        if target is None:
+            return None
+        payload = {"session_id": target, "state": state}
+        if entries is not None:
+            payload["entries"] = entries
+        if block is not None:
+            payload["block"] = block
+            if state == "blocked":
+                # The daemon parks its round on this block's answer wait
+                # (the real daemon's wait_for_answer).
+                self.pending_block = dict(block)
+        if summary is not None:
+            payload["summary"] = summary
+        try:
+            status, _ = saddle_api("POST", "/api/saddle/results", self.token, payload)
+            if status != 200:
+                print("  [fake %s] push %s -> HTTP %s (task=%s)"
+                      % (self.port, state, status, self.running_task))
+            return status
+        except (OSError, ValueError) as error:
+            print("  [fake %s] push %s failed: %r (task=%s)"
+                  % (self.port, state, error, self.running_task))
+            return None
+
+    # --- plan 10 phase 1: the ask path ---
+
+    def ask_now(self):
+        """Synchronously asks the web for work (a phase-1 daemon's idle
+        ask). A 200 assignment is accepted exactly like POST /start;
+        returns (status, payload|None)."""
+        token = self.token
+        if token is None:
+            raise SystemExit("fake daemon asked before receiving its token")
+        status, payload = saddle_api("POST", "/api/saddle/next-task", token)
+        with self.lock:
+            self.asks.append({"status": status, "payload": payload})
+        if status == 200:
+            self.accept_assignment(payload)
+        return status, payload
+
+    def _trigger_ask(self, reason):
+        """Schedules a delayed ask (the daemon woke / went idle-awake).
+        ask_delay models a SLOW asker — a daemon still winding down its
+        round when the wake lands: it honours the wake, but its ask
+        arrives late (still inside the web's lost-wake guard window)."""
+        def run():
+            if self.state in ("working", "failing"):
+                return  # a running daemon does not ask
+            if self.ask_delay > 0:
+                time.sleep(self.ask_delay)
+            for attempt in range(3):
+                try:
+                    status, _ = self.ask_now()
+                    if status in (200, 204):
+                        return
+                    print("  (ask %s -> HTTP %s, attempt %d)" % (reason, status, attempt + 1))
+                except Exception as error:  # app restarting / blips: retry
+                    print("  (ask %s failed: %r, attempt %d)" % (reason, error, attempt + 1))
+                time.sleep(1.0)
+
+        def starter():
+            time.sleep(FAKE_TRIGGER_S)
+            run()
+
+        thread = threading.Thread(target=starter, daemon=True)
+        with self.lock:
+            self.ask_threads.append(thread)
+        thread.start()
+
+    def settle_asks(self, timeout=15):
+        """Joins every ask-trigger thread scheduled so far — the
+        event-driven replacement for the fixed sleeps that waited for
+        in-flight asks to land after triggers were frozen."""
+        with self.lock:
+            threads = [t for t in self.ask_threads if t.is_alive()]
+        deadline = time.monotonic() + timeout
+        for thread in threads:
+            thread.join(timeout=max(0.1, deadline - time.monotonic()))
+        with self.lock:
+            self.ask_threads = [t for t in self.ask_threads if t.is_alive()]
+        return all(not thread.is_alive() for thread in threads)
+
+    def maybe_trigger_ask(self, reason, throttle=False):
+        """Schedules an idle-awake ask. Protocol events (wake, abort,
+        round end, park) ask singularly and immediately; only the
+        /status-observation path throttles (a burst of probes must not
+        hammer the ask endpoint)."""
+        now = time.monotonic()
+        if throttle and now - self.last_ask_trigger < 1.0:
+            return
+        self.last_ask_trigger = now
+        self._trigger_ask(reason)
+
+    def accept_assignment(self, payload):
+        """A 200 next-task assignment: adopted exactly like POST /start."""
+        self.start_payloads.append(payload)
+        task = payload.get("task") or {}
+        task_id = task.get("id")
+        self.running_task = int(task_id or 0)
+        self.running_title = task.get("title") or ""
+        self.session_id = payload.get("session_id")
+        # The assignment's answers resolve any block this daemon was
+        # parked on (resume-carries-answer).
+        self.pending_block = None
+        count = self.start_counts.get(task_id, 0) + 1
+        self.start_counts[task_id] = count
+        if count > 1:
+            # Crash-resume contract: re-pushing a task whose
+            # workspace still exists restores it; the first
+            # /status after the restore reports "resumed": true.
+            self.resumed_pending = True
+        # Plan 12: a goal-run assignment plays its scripted behaviour
+        # instead of the plain done push (plan submission, parking,
+        # question, completion, failure — consumed one per round).
+        self.goal_behaviour = None
+        if payload.get("kind") == "goal_run":
+            self.goal_assignments.append(payload)
+            self.goal_behaviour = self.goal_script.pop(0) if self.goal_script else ("suspend",)
+        self.set_state("failing" if self.fail_next else "working")
+        self.fail_next = False
+        # The round's opening telemetry: the flushed-so-far raw PTY
+        # batch plus the working state push (>= 2 flushes per round
+        # and the 10s timer are the real daemon's contract; the fake
+        # pushes its batch up front and heartbeats while working).
+        if self.scripted_corpus is not None:
+            self.push_chunks([dict(chunk) for chunk in self.scripted_corpus])
+        else:
+            self.push_chunks([self.PROMPT, "echo hello\r\n", "hello\r\n"])
+        self.push_results("working")
+
+    class Handler(BaseHTTPRequestHandler):
+        daemon = None  # set on the class before serving
+        protocol_version = "HTTP/1.1"
+
+        def log_message(self, fmt, *args):
+            pass
+
+        def maybe_hang(self, path):
+            """True when this request should hang forever (never respond),
+            consuming one unit of the path's hang budget."""
+            for suffix, count in list(self.daemon.hang_next.items()):
+                if count > 0 and path.startswith(suffix):
+                    self.daemon.hang_next[suffix] = count - 1
+                    return True
+            return False
+
+        def _send(self, status, obj):
+            body = json.dumps(obj).encode()
+            self.send_response(status)
+            self.send_header("Content-Type", "application/json")
+            self.send_header("Content-Length", str(len(body)))
+            self.end_headers()
+            self.wfile.write(body)
+
+        def do_POST(self):
+            if self.maybe_hang(self.path):
+                time.sleep(600)
+                return
+            self.daemon.touch_activity()
+            length = int(self.headers.get("Content-Length") or 0)
+            raw = self.rfile.read(length).decode() if length else "{}"
+            if self.path == "/register":
+                # Plan 10: the web delivers the per-saddle token + its
+                # own base URL; the daemon persists the token for its
+                # calls home and reports its ssh key + version.
+                if not self.daemon.serve_register:
+                    self._send(404, {"error": "no such route"})
+                    return
+                try:
+                    payload = json.loads(raw)
+                except ValueError:
+                    payload = {"raw": raw}
+                self.daemon.register_log.append(payload)
+                if payload.get("saddle_token"):
+                    self.daemon.token = payload["saddle_token"]
+                self._send(200, {"ok": True,
+                                 "ssh_public_key": self.daemon.ssh_public_key,
+                                 "version": "0.1-fake"})
+                if self.daemon.ask_on_register:
+                    self.daemon.maybe_trigger_ask("register")
+                return
+            if self.path == "/wake":
+                # Plan 10: a capable task is ready; a sleeping daemon
+                # asks for work (immediately — a wake is a direct
+                # command, never throttled).
+                self.daemon.wake_log.append(time.monotonic())
+                self._send(200, {"ok": True})
+                if self.daemon.ask_on_wake:
+                    self.daemon.maybe_trigger_ask("wake")
+                return
+            if self.path == "/answer":
+                # Plan 11 (daemon Task A): parks FREE the daemon, so no
+                # block ever waits in-process — the verdict travels in
+                # the resuming allocation's resume_notice. Always 409,
+                # exactly like the real daemon's contract.
+                try:
+                    payload = json.loads(raw)
+                except ValueError:
+                    self._send(400, {"error": "bad json"})
+                    return
+                self.daemon.answer_log.append({
+                    "refused": True,
+                    "answer": payload.get("answer", "")})
+                self._send(409, {"error": "no block is waiting for an answer — parks resume via allocation"})
+                return
+            if self.path == "/task-update":
+                # Plan 10: cancel (abort machinery) and comment
+                # (injected turn) — delivered directly to a RUNNING
+                # daemon, no auth.
+                try:
+                    payload = json.loads(raw)
+                except ValueError:
+                    self._send(400, {"error": "bad json"})
+                    return
+                kind = payload.get("kind")
+                if kind == "cancel":
+                    if self.daemon.abort_failures > 0:
+                        self.daemon.abort_failures -= 1
+                        self._send(500, {"error": "cancel failed (simulated)"})
+                        return
+                    aborted = self.daemon.running_task
+                    self.daemon.set_state("idle")
+                    self.daemon.summary = ""
+                    self.daemon.running_task = 0
+                    self.daemon.session_id = None
+                    self.daemon.abort_log.append(aborted)
+                    self._send(200, {"ok": True, "aborted_task_id": aborted})
+                    # An aborted daemon returns to its idle loop: it asks.
+                    self.daemon.maybe_trigger_ask("aborted")
+                elif kind == "comment":
+                    self.daemon.comment_log.append(payload)
+                    self._send(200, {"ok": True})
+                else:
+                    self._send(400, {"error": "unknown task-update kind"})
+                return
+            self._send(404, {"error": "no such route"})
+            self.close_connection = True
+
+        def do_GET(self):
+            if self.maybe_hang(self.path):
+                time.sleep(600)
+                return
+            if self.path != "/status":
+                # /status itself is not daemon activity: the liveness
+                # signal must reflect loop rounds / command completions.
+                self.daemon.touch_activity()
+            if self.path == "/status":
+                self.daemon.status_hits += 1
+                response = {"state": self.daemon.state, "summary": self.daemon.summary,
+                            "uptime_seconds": int(time.monotonic() - self.daemon.started_mono),
+                            "last_activity_epoch": self.daemon.last_activity_epoch,
+                            "ssh_public_key": self.daemon.ssh_public_key}
+                if getattr(self.daemon, "status_extra", None):
+                    response.update(self.daemon.status_extra)
+                if self.daemon.resumed_pending:
+                    response["resumed"] = True
+                    self.daemon.resumed_pending = False
+                # A parked/terminal daemon is idle-awake: a phase-1
+                # daemon asks (and sleeps on 204). Throttled so status
+                # poll bursts do not hammer the ask endpoint.
+                if self.daemon.ask_on_idle_status and self.daemon.state in (
+                        "idle", "done", "failed", "suspended"):
+                    self.daemon.maybe_trigger_ask("idle-status", throttle=True)
+                self._send(200, response)
+            else:
+                self._send(404, {"error": "no such route"})
+                self.close_connection = True
+
+    def run_lifecycle(self):
+        """Applies the scripted lifecycle on a timer (like a real daemon
+        whose task ends on its own): working heartbeats chunks (the
+        flush timer's stand-in, keeping the staleness clock fed), works
+        for FAKE_WORK_S, then pushes done/suspended; failing pushes
+        failed after FAKE_FAIL_S — and a task END makes the idle-awake
+        daemon ask again."""
+        while True:
+            time.sleep(0.1)
+            if self.hold_state or self.silent:
+                # hold_state freezes the script; silent models a daemon
+                # mid-round with nothing to flush — its round has not
+                # ended, so no terminal push fires while quiet.
+                continue
+            if self.state == "failing":
+                if time.monotonic() - self.state_entered >= FAKE_FAIL_S:
+                    self.set_state("failed", "bash -n rejected the script (simulated)")
+                    self.push_results("failed",
+                                      summary="bash -n rejected the script (simulated)")
+                    if self.ask_on_terminal:
+                        self.maybe_trigger_ask("terminal")
+            elif self.state == "working":
+                if time.monotonic() - self.state_entered >= FAKE_WORK_S:
+                    if self.goal_behaviour is not None:
+                        # A goal-agent round: play the scripted
+                        # behaviour (the results channel carries the
+                        # goal-context verbs).
+                        behaviour, self.goal_behaviour = self.goal_behaviour, None
+                        kind = behaviour[0]
+                        if kind == "plan":
+                            self.set_state("blocked")
+                            self.push_results("blocked", block={
+                                "type": "plan",
+                                "question": "Plan submitted for review",
+                                "body": behaviour[1]})
+                            if self.ask_on_idle_status:
+                                self.maybe_trigger_ask("parked")
+                        elif kind == "question":
+                            self.set_state("blocked")
+                            self.push_results("blocked", block={
+                                "type": "question",
+                                "question": behaviour[1],
+                                "options": list(behaviour[2])
+                                if len(behaviour) > 2 else None})
+                            if self.ask_on_idle_status:
+                                self.maybe_trigger_ask("parked")
+                        elif kind == "suspend":
+                            self.set_state("suspended")
+                            self.push_results("suspended")
+                            if self.ask_on_idle_status:
+                                self.maybe_trigger_ask("parked")
+                        elif kind == "fail":
+                            self.set_state("failed", behaviour[1])
+                            self.push_results("failed", summary=behaviour[1])
+                            if self.ask_on_terminal:
+                                self.maybe_trigger_ask("terminal")
+                        else:  # "done": the completion report
+                            self.set_state("done", behaviour[1])
+                            self.push_results("done", summary=behaviour[1])
+                            if self.ask_on_terminal:
+                                self.maybe_trigger_ask("terminal")
+                    elif self.suspend_on_title and self.suspend_on_title == self.running_title:
+                        # `saddle suspend`: park until a fresh assignment
+                        # resumes the workspace (title-targeted one-shot,
+                        # so an interleaved dispatch cannot eat the flag).
+                        self.set_state("suspended")
+                        self.suspend_on_title = None
+                        self.push_results("suspended")
+                        # A parked daemon is idle-awake: it asks (and
+                        # sleeps on 204) so a later wake can reach it.
+                        if self.ask_on_idle_status:
+                            self.maybe_trigger_ask("parked")
+                    else:
+                        self.set_state("done", "fake daemon finished")
+                        self.push_results("done", summary="fake daemon finished")
+                        if self.ask_on_terminal:
+                            self.maybe_trigger_ask("terminal")
+                elif time.monotonic() - getattr(self, "last_heartbeat", 0) >= FAKE_HEARTBEAT_S:
+                    # The flush timer: output keeps flowing, so chunks
+                    # keep arriving (the staleness window never opens on
+                    # a healthy runner).
+                    self.last_heartbeat = time.monotonic()
+                    self.push_chunks(["working-heartbeat\r\n"])
+
+    def serve(self, port=None):
+        """Binds the daemon's HTTP server. A requested port that is
+        already taken (free_port() hands out recyclable ports — two
+        calls can collide) falls back to an OS-assigned one instead of
+        silently dying and impersonating whatever owns that port."""
+        if port is None:
+            port = DAEMON_PORT
+        handler = type("BoundHandler", (FakeSaddle.Handler,), {"daemon": self})
+        self.server = None
+        try:
+            self.server = ThreadingHTTPServer(("127.0.0.1", port), handler)
+        except OSError:
+            print("(fake daemon: port %d taken, falling back)" % port)
+            self.server = ThreadingHTTPServer(("127.0.0.1", 0), handler)
+        self.port = self.server.server_address[1]
+        threading.Thread(target=self.server.serve_forever, daemon=True).start()
+        threading.Thread(target=self.run_lifecycle, daemon=True).start()
+        return self.server
+
+    def kill(self):
+        """The daemon dies: it stops listening (connections refused) AND
+        stops calling home — no pushes, no asks (a dead process has no
+        outbound anything; in-flight handler threads may linger but the
+        wire contract's traffic is one-directional now)."""
+        self.dead = True
+        if getattr(self, "server", None) is not None:
+            self.server.shutdown()
+            self.server.server_close()
+            self.server = None
+
+
+def start_app():
+    config = json.load(open(os.path.join(REPO, "web-config.json")))
+    config["saddle_callback_base_url"] = WEB
+    with open(os.path.join(WORK, "web-config.json"), "w") as handle:
+        json.dump(config, handle)
+
+    env = dict(os.environ)
+    env.update({
+        "SPRY_DB_PATH": DB_PATH,
+        "SPRY_SEED_ADMIN_USERNAME": "admin",
+        "SPRY_SEED_ADMIN_PASSWORD": "adminpass123",
+        "SADDLE_LLM_BASE_URL": "http://127.0.0.1:%d" % DAEMON_PORT,
+        "SADDLE_PROJECTS_ROOT": os.path.join(WORK, "workspace"),
+        "SADDLE_HTTP_TIMEOUT_S": "2",
+        "SADDLE_LOST_WAKE_S": "2",
+        "SADDLE_STALE_S": "3",
+        "SADDLE_DISPATCH_TICK_S": "1",
+        # Plan 12: the goal-agent resume coalescing window shrinks to
+        # one second so the event-driven resume tests settle quickly.
+        "SADDLE_GOAL_RESUME_S": os.environ.get("SADDLE_GOAL_RESUME_S", "1"),
+        # Never inherit a caller-poisoned LD_LIBRARY_PATH (e.g. one that
+        # resolves the ancient /lib64 copies): empty makes the loader use
+        # the binary's RUNPATH, which is the dev stack it was built
+        # against.
+        "LD_LIBRARY_PATH": "",
+    })
+    log_previous = os.path.join(WORK, "app.log.1")
+    if os.path.exists(os.path.join(WORK, "app.log")):
+        shutil.move(os.path.join(WORK, "app.log"), log_previous)
+    log = open(os.path.join(WORK, "app.log"), "w")
+    command = [APP, str(APP_PORT)]
+    if os.environ.get("WEBSTACK_GDB"):
+        # Debugging aid: run the app under gdb; a crash backtrace lands in
+        # app.log. WEBSTACK_GDB=1 meson test ... to enable.
+        command = ["gdb", "-batch", "-quiet",
+                   "-ex", "handle SIGPIPE nostop noprint pass",
+                   "-ex", "run", "-ex", "bt", "--args", APP, str(APP_PORT)]
+    process = subprocess.Popen(command, cwd=WORK, env=env,
+                               stdout=log, stderr=subprocess.STDOUT)
+    # The ready probe must require OUR process alive: a free_port()
+    # TOCTOU can hand this port to another shard's app — ours then dies
+    # at bind (MHD error()) while the probe happily answers from the
+    # intruder (same admin seed), and every check would silently drive
+    # the WRONG app. poll() != None with a serving port is exactly that
+    # shape: take the exit branch, the start_bundle retry re-ports.
+    outcome = wait_for(lambda: (app_ready() and process.poll() is None and "ready")
+                       or (process.poll() is not None and "app-exited-%d" % process.poll())
+                       or False, timeout=30, what="app ready")
+    if outcome is None:
+        raise SystemExit("app did not come up; see %s/app.log" % WORK)
+    if str(outcome).startswith("app-exited-"):
+        raise SystemExit("app exited during startup (%s); see %s/app.log"
+                         % outcome, WORK)
+    return process
+
+
+def app_ready():
+    try:
+        status, _ = http("GET", "/login", timeout=3)
+        return status == 200
+    except (urllib.error.URLError, OSError):
+        return False
+
+
+def dump_app_stacks(pid):
+    """Best-effort thread backtrace of the (possibly wedged) app."""
+    try:
+        fds = os.listdir("/proc/%d/fd" % pid)
+        print("(app open fds at dump: %d)" % len(fds))
+        kinds = {}
+        for fd in fds[:1200]:
+            try:
+                target = os.readlink("/proc/%d/fd/%s" % (pid, fd))
+            except OSError:
+                continue
+            key = target.split(":", 1)[0] if ":" in target else target
+            kinds[key] = kinds.get(key, 0) + 1
+        print("(fd kinds: %s)" % sorted(kinds.items(), key=lambda kv: -kv[1])[:6])
+    except OSError:
+        pass
+    for command in (["eu-stack", "-p", str(pid)],
+                    ["gdb", "-batch", "-quiet", "-p", str(pid),
+                     "-ex", "thread apply all bt"]):
+        try:
+            out = subprocess.run(command, capture_output=True, timeout=60)
+            text = out.stdout.decode(errors="replace") + out.stderr.decode(errors="replace")
+            if text.strip():
+                print("(app stacks via %s)\n%s" % (command[0], text[:12000]))
+                return
+        except (OSError, subprocess.SubprocessError):
+            continue
+
+
+# =============================================================================
+# Fake push service + Web Push protocol helpers (plan 11 task E)
+# =============================================================================
+
+def b64url(raw):
+    return base64.urlsafe_b64encode(raw).rstrip(b"=").decode()
+
+
+def b64url_dec(text):
+    return base64.urlsafe_b64decode(text + "=" * ((4 - len(text) % 4) % 4))
+
+
+class FakePushService:
+    """In-process Web Push endpoint server: every subscription the tests
+    register points at a path here (a distinct "browser endpoint").
+    Responses are scriptable per path — a fixed status (the 410-prune
+    fixture) or N transient 500s (the retry-next-tick fixture)."""
+
+    def __init__(self):
+        self.requests = []            # [{"path", "headers", "body", "at"}]
+        self.fail_next = {}           # path -> remaining 500s
+        self.status_for = {}          # path -> fixed status
+        self.lock = threading.Lock()
+        self.port = None
+        self.server = None
+
+    def serve(self):
+        service = self
+
+        class Handler(BaseHTTPRequestHandler):
+            protocol_version = "HTTP/1.1"
+
+            def log_message(self, fmt, *args):
+                pass
+
+            def do_POST(self):
+                length = int(self.headers.get("Content-Length") or 0)
+                body = self.rfile.read(length)
+                status = 201
+                if self.path in service.status_for:
+                    status = service.status_for[self.path]
+                elif service.fail_next.get(self.path, 0) > 0:
+                    service.fail_next[self.path] -= 1
+                    status = 500
+                with service.lock:
+                    service.requests.append({
+                        "path": self.path,
+                        "headers": {key.lower(): value
+                                    for key, value in self.headers.items()},
+                        "body": body,
+                        "at": time.monotonic(),
+                    })
+                payload = b"{}"
+                self.send_response(status)
+                self.send_header("Content-Type", "application/json")
+                self.send_header("Content-Length", str(len(payload)))
+                self.end_headers()
+                self.wfile.write(payload)
+
+        self.server = ThreadingHTTPServer(("127.0.0.1", 0), Handler)
+        self.port = self.server.server_address[1]
+        threading.Thread(target=self.server.serve_forever, daemon=True).start()
+        return self.server
+
+    def url(self, path):
+        return "http://127.0.0.1:%d%s" % (self.port, path)
+
+    def hits(self, prefix):
+        with self.lock:
+            return [request for request in self.requests
+                    if request["path"].startswith(prefix)]
+
+
+def decrypt_webpush(request, client_private_key, client_public, auth_secret):
+    """RFC 8291 decryption of one captured push: returns
+    (record_size, payload dict) — the payload builder's exact output."""
+    body = request["body"]
+    salt = body[:16]
+    record_size = int.from_bytes(body[16:20], "big")
+    key_id_len = body[20]
+    eph_public = body[21:21 + key_id_len]
+    ciphertext = body[21 + key_id_len:]
+    eph_point = ec.EllipticCurvePublicKey.from_encoded_point(ec.SECP256R1(),
+                                                             eph_public)
+    shared = client_private_key.exchange(ec.ECDH(), eph_point)
+    info = b"WebPush: info\x00" + eph_public + client_public
+    cek = HKDF(algorithm=hashes.SHA256(), length=16, salt=salt,
+               info=info).derive(shared + auth_secret)
+    nonce = HKDF(algorithm=hashes.SHA256(), length=12, salt=salt,
+                 info=info).derive(shared + auth_secret)
+    plaintext = AESGCM(cek).decrypt(nonce, ciphertext, None)
+    return record_size, json.loads(plaintext[:-1])  # strip the 0x02 delimiter
+
+
+def verify_vapid(request, vapid_public, vapid_private):
+    """Verifies the ES256 VAPID JWT on one captured push; returns its
+    claims dict (aud/exp/sub) — raises on a bad signature."""
+    header = request["headers"].get("authorization", "")
+    assert header.startswith("vapid t="), "no vapid authorization header"
+    token_part = header[len("vapid t="):].split(",")[0]
+    sent_key = header.split("k=")[1]
+    head_b64, claims_b64, sig_b64 = token_part.split(".")
+    signature = b64url_dec(sig_b64)
+    key = ec.derive_private_key(
+        int.from_bytes(b64url_dec(vapid_private), "big"), ec.SECP256R1())
+    key.public_key().verify(
+        encode_dss_signature(int.from_bytes(signature[:32], "big"),
+                             int.from_bytes(signature[32:], "big")),
+        (head_b64 + "." + claims_b64).encode(),
+        ec.ECDSA(hashes.SHA256()))
+    claims = json.loads(b64url_dec(claims_b64))
+    assert sent_key == vapid_public, "the k= key is not the app's VAPID key"
+    return claims
+
+
+def action_notify(result):
+    """The message of the first notify directive an action returned."""
+    for directive in result:
+        if directive.get("type") == "notify":
+            return directive.get("message", "")
+    return None
+
+
+# =============================================================================
+# Shard orchestration
+# =============================================================================
+
+class Ctx:
+    """Per-bundle shared fixtures: the app process, the admin auth slot
+    and the primary fake saddle (registered + token delivered)."""
+
+
+def start_bundle(name):
+    """Boots one shard's environment: scratch dir, database, ports, the
+    primary fake daemon and the app, then the shared fixtures every
+    bundle builds on (the demo project + the registered fake saddle).
+    Scenario groups inside the bundle share this app+daemon instance
+    and sequence their state as DB rows, never process restarts."""
+    global APP_PORT, WEB, DAEMON_PORT
+    bundle_env(name)
+    fake = FakeSaddle()
+    fake.serve()
+    DAEMON_PORT = fake.port  # the actually-bound port (fallback-safe)
+
+    # A rare framework-level crash (stack corruption in Statum slot
+    # signing during the FIRST login — shared-library codegen bug, moved
+    # twice already) kills the app before any test runs; a clean restart
+    # (with fresh ports) sidesteps it. Only tolerated while nothing has
+    # been checked yet.
+    auth = None
+    app = None
+    for attempt in range(3):
+        APP_PORT = free_port()
+        WEB = "http://127.0.0.1:%d" % APP_PORT
+        if os.path.exists(WORK):
+            shutil.rmtree(WORK)
+        os.makedirs(os.path.join(WORK, "workspace"))
+        try:
+            app = start_app()
+            auth = login("admin", "adminpass123")
+            break
+        except (SystemExit, OSError, urllib.error.URLError):
+            if passes > 0:
+                raise
+            if app is not None and app.poll() is None:
+                app.terminate()
+                try:
+                    app.wait(timeout=5)
+                except subprocess.TimeoutExpired:
+                    app.kill()
+            app = None
+            print("(app died before login; restarting cleanly, attempt %d)" % (attempt + 1))
+    if app is None or auth is None:
+        raise SystemExit("app never came up; see %s/app.log" % WORK)
+
+    state = slot_public(auth, "/projects", "projects")
+    act(auth, state["create"], {
+        "name": "demo",
+        "git_url": "https://example.com/demo.git",
+        "default_branch": "main",
+    })
+    saddles_state = slot_public(auth, "/saddles", "saddles")
+    act(auth, saddles_state["register"], {"name": "fake-saddle",
+                                          "host": "127.0.0.1:%d" % fake.port})
+    registered = [s for s in slot_public(auth, "/saddles", "saddles")["saddles"]
+                  if s["name"] == "fake-saddle"]
+    if wait_for(lambda: len(fake.register_log) > 0 or False,
+                timeout=15, what="/register delivery") is None:
+        raise SystemExit("fake saddle never received /register")
+
+    ctx = Ctx()
+    ctx.name = name
+    ctx.app = app
+    ctx.auth = auth
+    ctx.fake = fake
+    ctx.fake_id = int(registered[0]["id"])
+    ctx.fake_token = registered[0]["token"]
+    return ctx
+
+
+
+
+BUNDLES_ORDER = ("pages", "dispatch", "subtasks", "lineage",
+                 "allocation", "lifecycle", "answers", "push", "goals",
+                 "replay", "goalui")
+
+
+def run_bundle(name):
+    """Runs one shard to completion; returns a failure count."""
+    global CTX
+    started = time.monotonic()
+    ctx = start_bundle(name)
+    CTX = ctx
+    import importlib
+    bundle = importlib.import_module("bundles." + name)
+    # Runtime globals the star-import captured at module load can be
+    # stale (the sequential debug path reuses modules across shards) —
+    # re-point them at this shard's environment. The shared helpers
+    # read them from harness globals already.
+    for runtime_name in ("WORK", "DB_PATH", "APP_PORT", "DAEMON_PORT", "WEB"):
+        setattr(bundle, runtime_name, globals()[runtime_name])
+    runner = bundle.run
+    try:
+        runner(ctx)
+    finally:
+        # Exit-code diagnostic: distinguishes a crashed app (negative
+        # returncode, e.g. -11 SIGSEGV) from a clean shutdown. When
+        # tearing down mid-exception, also capture the still-alive
+        # app's stacks before killing it (a wedged-but-alive server
+        # otherwise leaves no evidence).
+        print("(app returncode at teardown: %s)" % ctx.app.poll())
+        if ctx.app.poll() is None and sys.exc_info()[0] is not None:
+            dump_app_stacks(ctx.app.pid)
+        ctx.fake.kill()
+        try:
+            ctx.app.terminate()
+            try:
+                ctx.app.wait(timeout=5)
+            except subprocess.TimeoutExpired:
+                ctx.app.kill()
+            check(ctx.app.poll() in (0, -15),
+                  "bundle %s app shut down cleanly (exit %s)"
+                  % (name, ctx.app.poll()))
+        except OSError:
+            pass
+    print("%d passed, %d failed" % (passes, failures))
+    print("[bundle %s] %.1fs" % (name, time.monotonic() - started))
+    return failures
+
+
+def run_all_parallel():
+    """The default meson entry: one subprocess per bundle (each with its
+    own app, daemons and database), verdicts aggregated into one exit
+    code and one combined check-count summary."""
+    base = os.environ.get("WEBSTACK_WORK", "/tmp/kilo/webstack-e2e")
+    log_dir = os.path.join(os.path.dirname(base) or "/tmp/kilo",
+                           "webstack-shards")
+    os.makedirs(log_dir, exist_ok=True)
+    procs = {}
+    started = time.monotonic()
+    for name in BUNDLES_ORDER:
+        out_path = os.path.join(log_dir, "bundle-%s.log" % name)
+        handle = open(out_path, "w")
+        procs[name] = (subprocess.Popen(
+            [sys.executable, "-u",
+             os.path.join(os.path.dirname(os.path.abspath(__file__)),
+                          "web_stack_test.py"), APP, "--bundle", name],
+            stdout=handle, stderr=subprocess.STDOUT), handle, out_path)
+    total_pass = total_fail = 0
+    broken = []
+    for name, (proc, handle, out_path) in procs.items():
+        try:
+            proc.wait(timeout=SHARD_TIMEOUT_S)
+        except subprocess.TimeoutExpired:
+            proc.kill()
+            proc.wait()
+        handle.close()
+        text = open(out_path).read()
+        match = re.search(r"(\d+) passed, (\d+) failed", text)
+        took = re.search(r"\[bundle %s\] ([0-9.]+)s" % name, text)
+        bundle_pass = int(match.group(1)) if match else 0
+        bundle_fail = int(match.group(2)) if match else -1
+        total_pass += max(bundle_pass, 0)
+        total_fail += max(bundle_fail, 0)
+        status = "ok"
+        if proc.returncode != 0 or bundle_fail != 0 or match is None:
+            status = "BROKEN (exit %s)" % proc.returncode
+            broken.append(name)
+        print("[shard %-10s] %6ss  %3d passed %3d failed  %s"
+              % (name, took.group(1) if took else "?",
+                 bundle_pass, bundle_fail, status))
+        if status != "ok":
+            tail = "\n".join(text.rstrip().split("\n")[-60:])
+            print("--- web-stack/%s tail (full log: %s) ---" % (name, out_path))
+            print(tail)
+            print("--- end web-stack/%s tail ---" % name)
+    print("shards wall: %.1fs  (logs under %s)" % (time.monotonic() - started, log_dir))
+    print("ALL SHARDS: %d passed, %d failed%s"
+          % (total_pass, total_fail,
+             "" if not broken else "  BROKEN: " + ", ".join(broken)))
+    return 1 if broken or total_fail else 0
+
+
+def main():
+    if not os.path.exists(APP):
+        raise SystemExit("app binary not found at %s (build first)" % APP)
+    argv = sys.argv[2:]
+    if "--bundle" in argv:
+        sys.exit(1 if run_bundle(argv[argv.index("--bundle") + 1]) else 0)
+    if os.environ.get("WEBSTACK_SEQUENTIAL"):
+        # Debug path: every bundle in-process, one after another.
+        for name in BUNDLES_ORDER:
+            if run_bundle(name):
+                return 1
+        return 0
+    return run_all_parallel()
+
+
+if __name__ == "__main__":
+    sys.exit(main())

+ 8 - 7526
test/web_stack_test.py

@@ -1,7534 +1,16 @@
 #!/usr/bin/env python3
-"""Self-contained web-stack feature tests: app + fake saddle daemon.
+"""The meson entry shim (plan 16 R5): everything lives in test/harness.py
+(shared FakeSaddle + wire helpers + fixtures + the parallel runner) and
+test/bundles/<name>.py (one module per scenario bundle). This shim keeps
+the historical invocation — `web_stack_test.py <app> [--bundle name]` —
+and stays the spawn target for the per-shard subprocesses."""
 
-Unlike integration_test.py (which needs a real saddle daemon and a mock
-LLM), this suite spawns everything it needs:
-
-- the clanker-saddle app binary (path from argv[1], or builddir default)
-  in a scratch directory with its own web-config.json (statum keys copied
-  from the repo, plus `saddle_callback_base_url`) and SQLite database
-- in-process fake saddle daemons speaking the wire contract: POST
-  /register (plan 10: receives {saddle_token, web_base_url}, answers
-  {ok, ssh_public_key, version}), POST /wake (records the wake; the
-  daemon then asks POST /api/saddle/next-task), POST /task-update
-  (cancel/comment/subtask-status), GET /status (scripted reflection —
-  exceptional use only), and the phase-2 push channels home:
-  POST /api/saddle/chunks (raw PTY batches) and POST /api/saddle/results
-  (round entries + state transitions). The retired /start, /output and
-  /log routes 404 like a post-phase-2 daemon.
-
-It then drives the app the way statum.js does (entrypoint loads + action
-POSTs) and asserts the Workstream B features against the wire contract:
-
-3. plan-review blocks hide their duplicate body preview
-5. rules CRUD/attach + the effective `rules` array in assignments
-6. project notes, POST /api/saddle/note, `project_notes` + `callback`
-   in assignments
-   plus the raw-log side: pushed chunks -> session_raw_log + terminal
-   raw view
-
-Plan 10 phase 1 (work acquisition flip):
-
-- per-saddle tokens: registration mints + /register-delivers them,
-  the row is the single credential store (the api_tokens fallback
-  died with arch 24), removal revokes
-- token auth on every /api/saddle/* endpoint
-- next-task allocation: concurrent asks race exactly one winner,
-  affinity pinning for parked tasks, resume_notice on suspended resumes
-- dispatcher: wake -> ask -> allocate roundtrip, the lost-wake guard
-  (no ask after a wake -> offline, re-wake the next capable), and the
-  pre-flip /answer + /start resume paths kept as the rollback route
-
-Plan 10 phase 2 (telemetry flip):
-
-- pushed chunks: idempotent on (session_id, seq), ordered, landing in
-  session_raw_log so the SSE terminal keeps working
-- pushed results: entries store like the /output path did (redelivery
-  idempotent on the daemon entry ids), blocked raises the block row +
-  parks + bumps the pulse (sealed refresh shows it), done/failed
-  complete/fail the task, suspended parks for the affinity resume
-- answer resumes, both daemon shapes: a SLEEPING affine saddle (its
-  post-park ask returned 204) is woken, its ask allocating the resume
-  with the verdict riding the assignment; a daemon parked MID-ROUND
-  (its round holds the block's answer wait open, so it can never ask)
-  gets the verdict delivered into that wait via POST /answer — same
-  session, no wake. A daemon dying with a parked-with-answered task
-  never requeues it: the verdict and session survive for the resume
-- staleness: a silent runner gets ONE exceptional GET /status probe —
-  alive keeps it running, dead requeues the task with an agent comment and
-  marks the saddle offline; a recovered daemon's ask flips offline rows
-  back to idle
-- the deleted layers are gone: /output, /log and /start 404 on the
-  daemon side, and nothing on the web side calls them
-
-Plan 10 phase 3 (capability awareness + UI):
-
-- assignment capability context: {saddle_tags, fleet_tags} on every
-  payload, GET /api/saddle/capabilities (per-saddle token) feeding
-  the daemon's `saddle capabilities` CLI
-- subtask callback capabilities: explicit-only attachment validated
-  against the operator tag set, unknown tags rejected with the valid
-  list in the error
-- task page: status block pinned to the top, blocking sections
-  newest-first (sealed GET state)
-- home dashboard: pinned OPEN blocks as newest-first link-through
-  cards (no inline answer forms) above the cross-task activity
-  timeline (last ~50 events newest-first)
-- lost-wake-guard regression: a saddle that asks SLOWLY after its
-  wake (busy winding down) still claims the task — the wake is never
-  silently dropped, no re-wake storm fires, and the never-asks guard
-  path (offline + re-wake of the next capable) stays green
-
-Prints PASS/FAIL lines Statum-style; exits non-zero on any failure.
-
-Plan 11 task D+E (UI + notifications), the `push` shard:
-
-- task page: progress feed above the status card, status + description
-  in a 50/50 grid, edit expander under the history expander, plan
-  behind an expander, answered blocks behind an expander; queue screen:
-  New Task expander above the filters; dashboard waiting-on-drafts
-  block with links to where Enqueue lives (pages shard)
-- real Web Push over VAPID: keypair generated at startup into
-  web-config.json, GET /sw.js service worker with click-through,
-  subscribe/unsubscribe + per-task Notify me actions, block events and
-  waiting-on-drafts pushed globally, first start/failure/completion to
-  opted-in users, best-effort queue with dispatcher-tick retry, 410/404
-  endpoint pruning — payloads verified protocol-level (RFC 8291
-  decryption + ES256 JWT signature) because the harness owns the
-  browser-side keys
-
-Heredoc completion reports (pages shard):
-
-- terminal tasks render tasks.summary (set by done/fail) as a
-  markdown completion-report card below the status/description grid —
-  "Completion report" when done, "Failure summary" when failed, no
-  card when empty; the summary renders through the shipped
-  stm-markdown renderer (headings/code, no syntax leaks, HTML
-  escaped) and the dashboard timeline snippets its first line
-
-Speed pass (plan 11, task 0):
-
-- SHARDING: the scenario groups are partitioned into seven independent
-  bundles (pages, dispatch, subtasks, lineage, allocation, lifecycle,
-  answers), each running in its own process against its own app
-  instance, fake daemons and SQLite database. The default invocation
-  runs all bundles in parallel and aggregates the verdicts and check
-  counts into one exit code — meson sees a single green/red test.
-  `--bundle NAME` runs one shard for debugging; WEBSTACK_SEQUENTIAL=1
-  runs them in-process, one after another.
-- Within a bundle, scenario groups SHARE the app+daemon instance and
-  carry per-group state as database rows (task/session/block
-  fixtures), never process restarts; the one deliberate restart (the
-  startup token migration) lives in the answers bundle.
-- EVENT-DRIVEN WAITS: wait_for polls at 50ms; the fixed sleeps were
-  converted either to observable-condition waits (daemon-side
-  counters, e.g. failed-delivery hits) or to quiet_window() — a
-  bounded negative-assertion poll that FAILS LOUDLY the moment the
-  event it guards against happens (a sleep could silently pass).
-- ENV KNOBS: SADDLE_DISPATCH_TICK_S=1 (dispatcher cadence; default 5
-  in production), SADDLE_HTTP_TIMEOUT_S=2, SADDLE_LOST_WAKE_S=2,
-  SADDLE_STALE_S=3, plus the fake daemon's scripted timings — the
-  wire-traffic shapes stay realistic, just faster.
-"""
-import json
 import os
-import re
-import shutil
-import socket
-import sqlite3
-import subprocess
 import sys
-import threading
-import time
-import urllib.error
-import urllib.parse
-import urllib.request
-from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
-
-# Web Push protocol verification (plan 11 task E): the test harness
-# owns the browser-side keys, so it can do everything the push service
-# does — decrypt the RFC 8291 body and verify the ES256 VAPID JWT.
-import base64
-from cryptography.hazmat.primitives import hashes
-from cryptography.hazmat.primitives.asymmetric import ec
-from cryptography.hazmat.primitives.asymmetric.utils import encode_dss_signature
-from cryptography.hazmat.primitives.ciphers.aead import AESGCM
-from cryptography.hazmat.primitives.kdf.hkdf import HKDF
-from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat
-
-REPO = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-APP = os.path.abspath(sys.argv[1]) if len(sys.argv) > 1 else os.path.join(REPO, "builddir", "clanker-saddle")
-
-# --- speed-pass tuning -----------------------------------------------------
-# The fake daemon's scripted timings and the dispatch-tick cadence the
-# quiet windows are sized against. All overridable for debugging.
-TICK_S = float(os.environ.get("SADDLE_DISPATCH_TICK_S", "1") or 1)
-FAKE_WORK_S = float(os.environ.get("WEBSTACK_FAKE_WORK_S", "1.2") or 1.2)
-FAKE_FAIL_S = float(os.environ.get("WEBSTACK_FAKE_FAIL_S", "0.5") or 0.5)
-FAKE_HEARTBEAT_S = float(os.environ.get("WEBSTACK_FAKE_HEARTBEAT_S", "0.4") or 0.4)
-FAKE_TRIGGER_S = float(os.environ.get("WEBSTACK_FAKE_TRIGGER_S", "0.05") or 0.05)
-SHARD_TIMEOUT_S = float(os.environ.get("WEBSTACK_SHARD_TIMEOUT_S", "600") or 600)
-
-
-def quiet_seconds():
-    """A negative-assertion window spanning several dispatch ticks (the
-    converted fixed sleeps were 3-7s at the old 5s tick; the bound never
-    exceeds the old timeout)."""
-    return min(2 * TICK_S + 0.8, 7.0)
-
-
-WORK = os.environ.get("WEBSTACK_WORK", "/tmp/kilo/webstack-e2e")
-DB_PATH = os.path.join(WORK, "web.sqlite")
-
-passes = 0
-failures = 0
-
-
-def check(condition, label):
-    global passes, failures
-    if condition:
-        passes += 1
-        print("PASS %s" % label)
-    else:
-        failures += 1
-        print("FAIL %s" % label)
-
-
-def free_port():
-    with socket.socket() as sock:
-        sock.bind(("127.0.0.1", 0))
-        return sock.getsockname()[1]
-
-
-APP_PORT = free_port()
-DAEMON_PORT = free_port()
-WEB = "http://127.0.0.1:%d" % APP_PORT
-
-
-def bundle_env(name):
-    """Point the module's runtime globals at one shard's scratch dir,
-    database and ports (each bundle is a process with its own app,
-    daemons and SQLite file)."""
-    global WORK, DB_PATH, APP_PORT, DAEMON_PORT, WEB
-    base = os.environ.get("WEBSTACK_WORK", "/tmp/kilo/webstack-e2e")
-    WORK = "%s-%s" % (base, name)
-    DB_PATH = os.path.join(WORK, "web.sqlite")
-    APP_PORT = free_port()
-    DAEMON_PORT = free_port()
-    WEB = "http://127.0.0.1:%d" % APP_PORT
-
-
-def http(method, url, data=None, headers=None, timeout=30):
-    body = None
-    if data is not None:
-        pairs = []
-        for k, v in data.items():
-            for item in (v if isinstance(v, (list, tuple)) else [v]):
-                pairs.append((k, item))
-        body = "&".join("%s=%s" % (k, urllib.parse.quote(str(item))) for k, item in pairs).encode()
-    request = urllib.request.Request(WEB + url if url.startswith("/") else url,
-                                     data=body, method=method)
-    if data is not None:
-        request.add_header("Content-Type", "application/x-www-form-urlencoded")
-    for key, value in (headers or {}).items():
-        request.add_header(key, value)
-    # Retry dropped/refused connections: the freshly started app can
-    # close a very early keep-alive connection once while warming up,
-    # and its first seconds can wobble under load.
-    for attempt in range(3):
-        try:
-            with urllib.request.urlopen(request, timeout=timeout) as response:
-                return response.status, response.read().decode()
-        except urllib.error.HTTPError as error:
-            return error.code, error.read().decode()
-        except (urllib.error.URLError, OSError):
-            if attempt >= 2:
-                raise
-            time.sleep(0.75)
-
-
-def directives(uri, auth=None):
-    headers = {}
-    if auth:
-        headers["X-Statum-Slot"] = "key=%s; as_at=%s" % (auth["key"], auth["as_at"])
-    status, body = http("GET", "/_statum/entrypoint?uri=" + urllib.parse.quote(uri.split("?")[0]),
-                        headers=headers)
-    if status != 200:
-        raise SystemExit("entrypoint %s -> HTTP %d: %s" % (uri, status, body[:300]))
-    return json.loads(body)
-
-
-def slot_public(auth, uri, type_name):
-    for directive in directives(uri, auth):
-        if directive["type"] == "set":
-            content = directive["snapshot_frame"].get("content")
-            if not content:
-                continue
-            content = json.loads(content)
-            if content["slot"]["type"] == type_name:
-                return content["public"]
-    raise SystemExit("no %s slot in entrypoint state for %s" % (type_name, uri))
-
-
-def act(auth, action, fields):
-    headers = {"X-Statum-Slot": "key=%s; as_at=%s" % (auth["key"], auth["as_at"])}
-    if action.get("private"):
-        headers["X-Statum-Private"] = action["private"]
-    status, body = http(action.get("method", "POST"), action["uri"], fields, headers)
-    if status != 200:
-        raise SystemExit("action %s -> HTTP %d: %s" % (action["uri"], status, body[:300]))
-    return json.loads(body)
-
-
-def login(username, password):
-    frames = directives("/login")
-    content = json.loads(frames[0]["snapshot_frame"]["content"])
-    action = content["public"]["login"]
-    status, body = http(action.get("method", "POST"), action["uri"],
-                        {"username": username, "password": password})
-    if status != 200:
-        raise SystemExit("login -> HTTP %d: %s" % (status, body[:300]))
-    for directive in json.loads(body):
-        if directive["type"] == "set":
-            frame = json.loads(directive["snapshot_frame"]["content"])
-            if frame["slot"]["type"] == "auth":
-                return {"key": frame["slot"]["key"], "as_at": frame["as_at"]}
-    raise SystemExit("login response carried no auth slot: " + body[:300])
-
-
-def wait_for(predicate, timeout=60, what="condition", interval=0.05):
-    deadline = time.monotonic() + timeout
-    last = None
-    while time.monotonic() < deadline:
-        last = predicate()
-        if last is not False and last is not None:
-            return last
-        time.sleep(interval)
-    print("  (timeout waiting for %s; last: %s)" % (what, last))
-    dump_threads()
-    return None
-
-
-def quiet_window(seconds, predicate, what):
-    """A converted fixed sleep: asserts a NEGATIVE condition (nothing may
-    happen) across a window spanning several dispatch ticks, polling at
-    50ms. The moment the condition breaks the window fails loudly
-    (diagnostics + thread dump) instead of silently passing a sleep."""
-    deadline = time.monotonic() + seconds
-    while time.monotonic() < deadline:
-        value = predicate()
-        if value is False or value is None:
-            remaining = deadline - time.monotonic()
-            print("  (quiet window '%s' broken after %.2fs of %.2fs — the"
-                  " guarded event DID happen)" % (what, seconds - remaining, seconds))
-            dump_threads()
-            return False
-        time.sleep(0.05)
-    return True
-
-
-def dump_threads():
-    """Stacks of suite threads not parked in sleep — pinpoints a wedged
-    fake lifecycle when a wait times out."""
-    import traceback
-    shown = 0
-    for thread_id, frame in sys._current_frames().items():
-        stack = "".join(traceback.format_stack(frame)[-4:])
-        if ("web_stack_test.py" in stack) and ("sleep" not in stack) and shown < 6:
-            shown += 1
-            print("  --- thread %s ---\n%s" % (thread_id, stack))
-
-
-def task_state(auth, task_id):
-    return slot_public(auth, "/tasks/%d" % task_id, "task")
-
-
-def wait_task_done(auth, task_id, timeout=90):
-    return wait_for(lambda: task_state(auth, task_id).get("status") == "done" or False,
-                    timeout=timeout, what="task %d -> done" % task_id)
-
-
-def task_id_of(title):
-    conn = db()
-    try:
-        return conn.execute("select id from tasks where title = ?", (title,)).fetchone()[0]
-    finally:
-        conn.close()
-
-
-def enqueue_task(auth, task_id):
-    """The human-only Enqueue action (plan 11): draft -> queued."""
-    detail = task_state(auth, task_id)
-    assert detail["status"] == "draft", "task %d not in draft (%s)" % (task_id, detail["status"])
-    act(auth, detail["enqueue"], {})
-    return task_state(auth, task_id)["status"]
-
-
-def create_queued(auth, fields):
-    """Create via the queue form (lands in draft) and enqueue it — the
-    standard 'this task should dispatch' fixture of the plan-11 world."""
-    act(auth, slot_public(auth, "/tasks", "tasks")["create"], fields)
-    task_id = int([t["id"] for t in slot_public(auth, "/tasks", "tasks")["tasks"]
-                   if t["title"] == fields["title"]][0])
-    enqueue_task(auth, task_id)
-    return task_id
-
-
-def saddle_api(method, path, token, payload=None):
-    """Raw call against the saddle ingest API; returns (status, json)."""
-    request = urllib.request.Request(WEB + path,
-                                     data=json.dumps(payload or {}).encode(), method=method)
-    request.add_header("Content-Type", "application/json")
-    if token is not None:
-        request.add_header("Authorization", "Bearer " + token)
-    try:
-        with urllib.request.urlopen(request, timeout=15) as response:
-            return response.status, json.loads(response.read().decode() or "{}")
-    except urllib.error.HTTPError as error:
-        body = error.read().decode()
-        try:
-            return error.code, json.loads(body)
-        except ValueError:
-            return error.code, {"raw": body}
-
-
-def db():
-    return sqlite3.connect(DB_PATH)
-
-
-def http_get_page(auth, uri):
-    """The compiled page HTML for a statum route (auth via the slot
-    header), for asserting page-level embeds the slot state cannot
-    see."""
-    status, body = http("GET", uri, headers={
-        "X-Statum-Slot": "key=%s; as_at=%s" % (auth["key"], auth["as_at"])})
-    if status != 200:
-        raise SystemExit("GET %s -> HTTP %d" % (uri, status))
-    return body
-
-
-def saddle_card(auth, name):
-    rows = [s for s in slot_public(auth, "/saddles", "saddles")["saddles"]
-            if s["name"] == name]
-    return rows[0]
-
-
-def queued_count():
-    conn = db()
-    try:
-        return conn.execute(
-            "select count(*) from tasks where status = 'queued'").fetchone()[0]
-    finally:
-        conn.close()
-
-
-def command_rows(session):
-    conn = db()
-    try:
-        return conn.execute(
-            "select command_text, type from session_commands"
-            " where session_id = ? order by id", (session,)).fetchall()
-    finally:
-        conn.close()
-
-
-class FakeSaddle:
-    """In-process saddle daemon implementing the wire contract.
-
-    Phase-2 push behaviour: the daemon asks POST /api/saddle/next-task
-    whenever idle-awake (at registration, on POST /wake, after its task
-    reaches a terminal state, and when a /status probe observes it
-    parked idle — throttled), accepts assignments like POST /start used
-    to, then PUSHES its telemetry home: raw PTY chunks via POST
-    /api/saddle/chunks and round results with state transitions via
-    POST /api/saddle/results (working at round start, terminal states
-    when the scripted lifecycle ends them). /output, /log and /start
-    are gone (404) like a post-phase-2 daemon; /task-update serves the
-    cancel/comment/subtask-status kinds; POST /answer receives a
-    delivered verdict when the round is parked in a block's answer
-    wait (409 when nothing waits — the real daemon's contract; the
-    resumed round continues after the response). Every trigger can be
-    disabled per test for determinism; ask_now() performs a
-    synchronous manual ask.
-    """
-
-    PROMPT = "bbarrow@fedora:/workspace/task-1$ "
-
-    def __init__(self):
-        self.lock = threading.Lock()
-        self.start_payloads = []       # captured assignment payloads (/start + next-task 200s)
-        self.state = "idle"
-        self.summary = ""
-        self.state_entered = time.monotonic()
-        self.fail_next = False          # next task drives the task to failed
-        self.start_counts = {}          # task id -> assignment count
-        self.resumed_pending = False    # crash-resume flag on the next /status
-        self.suspend_on_title = None    # this task (by title) parks as suspended
-        self.output_seq = 100           # daemon-global entry ids for pushed results
-        self.last_activity_epoch = int(time.time())
-        self.hang_next = {}             # path suffix -> hang count (never responds)
-        self.abort_failures = 0          # cancel task-updates failing (500) while > 0
-        self.abort_log = []              # task ids aborted via task-update cancel
-        self.running_task = 0            # task id the daemon believes it runs
-        self.running_title = ""          # its title (suspend targeting)
-        self.session_id = None           # the web-side run row of the running task
-        self.hold_state = False          # freeze lifecycle + heartbeat pushes
-        self.ssh_public_key = ""         # reported on /status + /register
-        self.started_mono = time.monotonic()
-        self.freeze_activity = False     # hold last_activity_epoch still
-        self.silent = False              # suppress pushes (staleness tests)
-        self.dead = False                # kill(): no serving AND no calls home
-        self.status_hits = 0             # GET /status arrivals (probe accounting)
-        self.comment_log = []            # recorded /task-update comment payloads
-        self.scripted_corpus = None      # chunk batch pushed when a task starts
-        # --- plan 10 phase 1: ask/wake/register ---
-        self.token = None                # per-saddle token from POST /register
-        self.register_log = []           # recorded /register bodies
-        self.wake_log = []               # recorded POST /wake arrivals
-        self.asks = []                   # [{"status": int, "payload": dict|None}]
-        self.ask_on_register = True
-        self.ask_on_wake = True
-        self.ask_on_terminal = True
-        self.ask_on_idle_status = True
-        self.ask_delay = 0.0             # seconds; a slow daemon delays its wake-triggered ask
-        self.serve_register = True         # False: 404 /register (pre-flip daemon)
-        self.last_ask_trigger = 0.0
-        self.port = None
-        self.ask_threads = []            # scheduled ask-trigger threads (settle_asks joins them)
-        # --- answer delivery (the parked-session resume) ---
-        self.pending_block = None        # the block payload this daemon waits on (state blocked)
-        self.answer_log = []             # recorded POST /answer bodies
-        self.answer_push_delay = 0.2     # the resumed round's first push, after the response
-        # --- plan 12: goal-agent scripting ---
-        self.goal_script = []            # behaviours consumed per goal-run assignment
-        self.goal_behaviour = None       # the current round's popped behaviour
-        self.goal_assignments = []       # captured goal-run assignment payloads
-
-    def set_state(self, state, summary=None):
-        """Advances the scripted lifecycle."""
-        self.state = state
-        if summary is not None:
-            self.summary = summary
-        self.state_entered = time.monotonic()
-
-    def touch_activity(self):
-        if not self.freeze_activity:
-            self.last_activity_epoch = int(time.time())
-
-    def queue_output(self, entry_type, command, output):
-        """Pushes a typed entry as a round-results push (the daemon's
-        entry log riding the results channel)."""
-        with self.lock:
-            entry = {
-                "id": self.output_seq,
-                "command": command,
-                "output": output,
-                "exit_code": 1,
-                "type": entry_type,
-                "timestamp": "2026-09-06T00:00:00Z",
-            }
-            self.output_seq += 1
-        self.push_results(self.state if self.state in ("working",) else "working",
-                          entries=[entry])
-
-    # --- plan 10 phase 2: the push channels ---
-
-    def push_chunks(self, chunks):
-        """Pushes raw PTY chunks home: elements are texts (assigned
-        fresh seqs) or {seq, text} dicts (a redelivery or explicit
-        corpus). Pushes are suppressed while silent/hold_state (the
-        staleness tests' silent runner)."""
-        if self.dead or self.silent or self.token is None or self.session_id is None:
-            return
-        batch = []
-        with self.lock:
-            for chunk in chunks:
-                if isinstance(chunk, dict):
-                    batch.append({"seq": int(chunk["seq"]), "text": chunk["text"]})
-                else:
-                    batch.append({"seq": self.next_push_seq(), "text": chunk})
-        try:
-            saddle_api("POST", "/api/saddle/chunks", self.token,
-                       {"session_id": self.session_id, "chunks": batch})
-        except (OSError, ValueError):
-            pass  # app restarting / shutting down mid-test
-
-    def next_push_seq(self):
-        # The daemon-side chunk counter for ad-hoc pushes.
-        self._push_seq = getattr(self, "_push_seq", 0) + 1
-        return self._push_seq
-
-    def push_results(self, state, entries=None, block=None, summary=None, session_id=None):
-        """Pushes one round-results payload home (state transition plus
-        its entries). Returns the HTTP status when it went out, None
-        when suppressed."""
-        if self.dead or self.silent:
-            return None
-        if self.token is None:
-            return None
-        target = session_id if session_id is not None else self.session_id
-        if target is None:
-            return None
-        payload = {"session_id": target, "state": state}
-        if entries is not None:
-            payload["entries"] = entries
-        if block is not None:
-            payload["block"] = block
-            if state == "blocked":
-                # The daemon parks its round on this block's answer wait
-                # (the real daemon's wait_for_answer).
-                self.pending_block = dict(block)
-        if summary is not None:
-            payload["summary"] = summary
-        try:
-            status, _ = saddle_api("POST", "/api/saddle/results", self.token, payload)
-            if status != 200:
-                print("  [fake %s] push %s -> HTTP %s (task=%s)"
-                      % (self.port, state, status, self.running_task))
-            return status
-        except (OSError, ValueError) as error:
-            print("  [fake %s] push %s failed: %r (task=%s)"
-                  % (self.port, state, error, self.running_task))
-            return None
-
-    # --- plan 10 phase 1: the ask path ---
-
-    def ask_now(self):
-        """Synchronously asks the web for work (a phase-1 daemon's idle
-        ask). A 200 assignment is accepted exactly like POST /start;
-        returns (status, payload|None)."""
-        token = self.token
-        if token is None:
-            raise SystemExit("fake daemon asked before receiving its token")
-        status, payload = saddle_api("POST", "/api/saddle/next-task", token)
-        with self.lock:
-            self.asks.append({"status": status, "payload": payload})
-        if status == 200:
-            self.accept_assignment(payload)
-        return status, payload
-
-    def _trigger_ask(self, reason):
-        """Schedules a delayed ask (the daemon woke / went idle-awake).
-        ask_delay models a SLOW asker — a daemon still winding down its
-        round when the wake lands: it honours the wake, but its ask
-        arrives late (still inside the web's lost-wake guard window)."""
-        def run():
-            if self.state in ("working", "failing"):
-                return  # a running daemon does not ask
-            if self.ask_delay > 0:
-                time.sleep(self.ask_delay)
-            for attempt in range(3):
-                try:
-                    status, _ = self.ask_now()
-                    if status in (200, 204):
-                        return
-                    print("  (ask %s -> HTTP %s, attempt %d)" % (reason, status, attempt + 1))
-                except Exception as error:  # app restarting / blips: retry
-                    print("  (ask %s failed: %r, attempt %d)" % (reason, error, attempt + 1))
-                time.sleep(1.0)
-
-        def starter():
-            time.sleep(FAKE_TRIGGER_S)
-            run()
-
-        thread = threading.Thread(target=starter, daemon=True)
-        with self.lock:
-            self.ask_threads.append(thread)
-        thread.start()
-
-    def settle_asks(self, timeout=15):
-        """Joins every ask-trigger thread scheduled so far — the
-        event-driven replacement for the fixed sleeps that waited for
-        in-flight asks to land after triggers were frozen."""
-        with self.lock:
-            threads = [t for t in self.ask_threads if t.is_alive()]
-        deadline = time.monotonic() + timeout
-        for thread in threads:
-            thread.join(timeout=max(0.1, deadline - time.monotonic()))
-        with self.lock:
-            self.ask_threads = [t for t in self.ask_threads if t.is_alive()]
-        return all(not thread.is_alive() for thread in threads)
-
-    def maybe_trigger_ask(self, reason, throttle=False):
-        """Schedules an idle-awake ask. Protocol events (wake, abort,
-        round end, park) ask singularly and immediately; only the
-        /status-observation path throttles (a burst of probes must not
-        hammer the ask endpoint)."""
-        now = time.monotonic()
-        if throttle and now - self.last_ask_trigger < 1.0:
-            return
-        self.last_ask_trigger = now
-        self._trigger_ask(reason)
-
-    def accept_assignment(self, payload):
-        """A 200 next-task assignment: adopted exactly like POST /start."""
-        self.start_payloads.append(payload)
-        task = payload.get("task") or {}
-        task_id = task.get("id")
-        self.running_task = int(task_id or 0)
-        self.running_title = task.get("title") or ""
-        self.session_id = payload.get("session_id")
-        # The assignment's answers resolve any block this daemon was
-        # parked on (resume-carries-answer).
-        self.pending_block = None
-        count = self.start_counts.get(task_id, 0) + 1
-        self.start_counts[task_id] = count
-        if count > 1:
-            # Crash-resume contract: re-pushing a task whose
-            # workspace still exists restores it; the first
-            # /status after the restore reports "resumed": true.
-            self.resumed_pending = True
-        # Plan 12: a goal-run assignment plays its scripted behaviour
-        # instead of the plain done push (plan submission, parking,
-        # question, completion, failure — consumed one per round).
-        self.goal_behaviour = None
-        if payload.get("kind") == "goal_run":
-            self.goal_assignments.append(payload)
-            self.goal_behaviour = self.goal_script.pop(0) if self.goal_script else ("suspend",)
-        self.set_state("failing" if self.fail_next else "working")
-        self.fail_next = False
-        # The round's opening telemetry: the flushed-so-far raw PTY
-        # batch plus the working state push (>= 2 flushes per round
-        # and the 10s timer are the real daemon's contract; the fake
-        # pushes its batch up front and heartbeats while working).
-        if self.scripted_corpus is not None:
-            self.push_chunks([dict(chunk) for chunk in self.scripted_corpus])
-        else:
-            self.push_chunks([self.PROMPT, "echo hello\r\n", "hello\r\n"])
-        self.push_results("working")
-
-    class Handler(BaseHTTPRequestHandler):
-        daemon = None  # set on the class before serving
-        protocol_version = "HTTP/1.1"
-
-        def log_message(self, fmt, *args):
-            pass
-
-        def maybe_hang(self, path):
-            """True when this request should hang forever (never respond),
-            consuming one unit of the path's hang budget."""
-            for suffix, count in list(self.daemon.hang_next.items()):
-                if count > 0 and path.startswith(suffix):
-                    self.daemon.hang_next[suffix] = count - 1
-                    return True
-            return False
-
-        def _send(self, status, obj):
-            body = json.dumps(obj).encode()
-            self.send_response(status)
-            self.send_header("Content-Type", "application/json")
-            self.send_header("Content-Length", str(len(body)))
-            self.end_headers()
-            self.wfile.write(body)
-
-        def do_POST(self):
-            if self.maybe_hang(self.path):
-                time.sleep(600)
-                return
-            self.daemon.touch_activity()
-            length = int(self.headers.get("Content-Length") or 0)
-            raw = self.rfile.read(length).decode() if length else "{}"
-            if self.path == "/register":
-                # Plan 10: the web delivers the per-saddle token + its
-                # own base URL; the daemon persists the token for its
-                # calls home and reports its ssh key + version.
-                if not self.daemon.serve_register:
-                    self._send(404, {"error": "no such route"})
-                    return
-                try:
-                    payload = json.loads(raw)
-                except ValueError:
-                    payload = {"raw": raw}
-                self.daemon.register_log.append(payload)
-                if payload.get("saddle_token"):
-                    self.daemon.token = payload["saddle_token"]
-                self._send(200, {"ok": True,
-                                 "ssh_public_key": self.daemon.ssh_public_key,
-                                 "version": "0.1-fake"})
-                if self.daemon.ask_on_register:
-                    self.daemon.maybe_trigger_ask("register")
-                return
-            if self.path == "/wake":
-                # Plan 10: a capable task is ready; a sleeping daemon
-                # asks for work (immediately — a wake is a direct
-                # command, never throttled).
-                self.daemon.wake_log.append(time.monotonic())
-                self._send(200, {"ok": True})
-                if self.daemon.ask_on_wake:
-                    self.daemon.maybe_trigger_ask("wake")
-                return
-            if self.path == "/answer":
-                # Plan 11 (daemon Task A): parks FREE the daemon, so no
-                # block ever waits in-process — the verdict travels in
-                # the resuming allocation's resume_notice. Always 409,
-                # exactly like the real daemon's contract.
-                try:
-                    payload = json.loads(raw)
-                except ValueError:
-                    self._send(400, {"error": "bad json"})
-                    return
-                self.daemon.answer_log.append({
-                    "refused": True,
-                    "answer": payload.get("answer", "")})
-                self._send(409, {"error": "no block is waiting for an answer — parks resume via allocation"})
-                return
-            if self.path == "/task-update":
-                # Plan 10: cancel (abort machinery) and comment
-                # (injected turn) — delivered directly to a RUNNING
-                # daemon, no auth.
-                try:
-                    payload = json.loads(raw)
-                except ValueError:
-                    self._send(400, {"error": "bad json"})
-                    return
-                kind = payload.get("kind")
-                if kind == "cancel":
-                    if self.daemon.abort_failures > 0:
-                        self.daemon.abort_failures -= 1
-                        self._send(500, {"error": "cancel failed (simulated)"})
-                        return
-                    aborted = self.daemon.running_task
-                    self.daemon.set_state("idle")
-                    self.daemon.summary = ""
-                    self.daemon.running_task = 0
-                    self.daemon.session_id = None
-                    self.daemon.abort_log.append(aborted)
-                    self._send(200, {"ok": True, "aborted_task_id": aborted})
-                    # An aborted daemon returns to its idle loop: it asks.
-                    self.daemon.maybe_trigger_ask("aborted")
-                elif kind == "comment":
-                    self.daemon.comment_log.append(payload)
-                    self._send(200, {"ok": True})
-                else:
-                    self._send(400, {"error": "unknown task-update kind"})
-                return
-            self._send(404, {"error": "no such route"})
-            self.close_connection = True
-
-        def do_GET(self):
-            if self.maybe_hang(self.path):
-                time.sleep(600)
-                return
-            if self.path != "/status":
-                # /status itself is not daemon activity: the liveness
-                # signal must reflect loop rounds / command completions.
-                self.daemon.touch_activity()
-            if self.path == "/status":
-                self.daemon.status_hits += 1
-                response = {"state": self.daemon.state, "summary": self.daemon.summary,
-                            "uptime_seconds": int(time.monotonic() - self.daemon.started_mono),
-                            "last_activity_epoch": self.daemon.last_activity_epoch,
-                            "ssh_public_key": self.daemon.ssh_public_key}
-                if getattr(self.daemon, "status_extra", None):
-                    response.update(self.daemon.status_extra)
-                if self.daemon.resumed_pending:
-                    response["resumed"] = True
-                    self.daemon.resumed_pending = False
-                # A parked/terminal daemon is idle-awake: a phase-1
-                # daemon asks (and sleeps on 204). Throttled so status
-                # poll bursts do not hammer the ask endpoint.
-                if self.daemon.ask_on_idle_status and self.daemon.state in (
-                        "idle", "done", "failed", "suspended"):
-                    self.daemon.maybe_trigger_ask("idle-status", throttle=True)
-                self._send(200, response)
-            else:
-                self._send(404, {"error": "no such route"})
-                self.close_connection = True
-
-    def run_lifecycle(self):
-        """Applies the scripted lifecycle on a timer (like a real daemon
-        whose task ends on its own): working heartbeats chunks (the
-        flush timer's stand-in, keeping the staleness clock fed), works
-        for FAKE_WORK_S, then pushes done/suspended; failing pushes
-        failed after FAKE_FAIL_S — and a task END makes the idle-awake
-        daemon ask again."""
-        while True:
-            time.sleep(0.1)
-            if self.hold_state or self.silent:
-                # hold_state freezes the script; silent models a daemon
-                # mid-round with nothing to flush — its round has not
-                # ended, so no terminal push fires while quiet.
-                continue
-            if self.state == "failing":
-                if time.monotonic() - self.state_entered >= FAKE_FAIL_S:
-                    self.set_state("failed", "bash -n rejected the script (simulated)")
-                    self.push_results("failed",
-                                      summary="bash -n rejected the script (simulated)")
-                    if self.ask_on_terminal:
-                        self.maybe_trigger_ask("terminal")
-            elif self.state == "working":
-                if time.monotonic() - self.state_entered >= FAKE_WORK_S:
-                    if self.goal_behaviour is not None:
-                        # A goal-agent round: play the scripted
-                        # behaviour (the results channel carries the
-                        # goal-context verbs).
-                        behaviour, self.goal_behaviour = self.goal_behaviour, None
-                        kind = behaviour[0]
-                        if kind == "plan":
-                            self.set_state("blocked")
-                            self.push_results("blocked", block={
-                                "type": "plan",
-                                "question": "Plan submitted for review",
-                                "body": behaviour[1]})
-                            if self.ask_on_idle_status:
-                                self.maybe_trigger_ask("parked")
-                        elif kind == "question":
-                            self.set_state("blocked")
-                            self.push_results("blocked", block={
-                                "type": "question",
-                                "question": behaviour[1],
-                                "options": list(behaviour[2])
-                                if len(behaviour) > 2 else None})
-                            if self.ask_on_idle_status:
-                                self.maybe_trigger_ask("parked")
-                        elif kind == "suspend":
-                            self.set_state("suspended")
-                            self.push_results("suspended")
-                            if self.ask_on_idle_status:
-                                self.maybe_trigger_ask("parked")
-                        elif kind == "fail":
-                            self.set_state("failed", behaviour[1])
-                            self.push_results("failed", summary=behaviour[1])
-                            if self.ask_on_terminal:
-                                self.maybe_trigger_ask("terminal")
-                        else:  # "done": the completion report
-                            self.set_state("done", behaviour[1])
-                            self.push_results("done", summary=behaviour[1])
-                            if self.ask_on_terminal:
-                                self.maybe_trigger_ask("terminal")
-                    elif self.suspend_on_title and self.suspend_on_title == self.running_title:
-                        # `saddle suspend`: park until a fresh assignment
-                        # resumes the workspace (title-targeted one-shot,
-                        # so an interleaved dispatch cannot eat the flag).
-                        self.set_state("suspended")
-                        self.suspend_on_title = None
-                        self.push_results("suspended")
-                        # A parked daemon is idle-awake: it asks (and
-                        # sleeps on 204) so a later wake can reach it.
-                        if self.ask_on_idle_status:
-                            self.maybe_trigger_ask("parked")
-                    else:
-                        self.set_state("done", "fake daemon finished")
-                        self.push_results("done", summary="fake daemon finished")
-                        if self.ask_on_terminal:
-                            self.maybe_trigger_ask("terminal")
-                elif time.monotonic() - getattr(self, "last_heartbeat", 0) >= FAKE_HEARTBEAT_S:
-                    # The flush timer: output keeps flowing, so chunks
-                    # keep arriving (the staleness window never opens on
-                    # a healthy runner).
-                    self.last_heartbeat = time.monotonic()
-                    self.push_chunks(["working-heartbeat\r\n"])
-
-    def serve(self, port=None):
-        """Binds the daemon's HTTP server. A requested port that is
-        already taken (free_port() hands out recyclable ports — two
-        calls can collide) falls back to an OS-assigned one instead of
-        silently dying and impersonating whatever owns that port."""
-        if port is None:
-            port = DAEMON_PORT
-        handler = type("BoundHandler", (FakeSaddle.Handler,), {"daemon": self})
-        self.server = None
-        try:
-            self.server = ThreadingHTTPServer(("127.0.0.1", port), handler)
-        except OSError:
-            print("(fake daemon: port %d taken, falling back)" % port)
-            self.server = ThreadingHTTPServer(("127.0.0.1", 0), handler)
-        self.port = self.server.server_address[1]
-        threading.Thread(target=self.server.serve_forever, daemon=True).start()
-        threading.Thread(target=self.run_lifecycle, daemon=True).start()
-        return self.server
-
-    def kill(self):
-        """The daemon dies: it stops listening (connections refused) AND
-        stops calling home — no pushes, no asks (a dead process has no
-        outbound anything; in-flight handler threads may linger but the
-        wire contract's traffic is one-directional now)."""
-        self.dead = True
-        if getattr(self, "server", None) is not None:
-            self.server.shutdown()
-            self.server.server_close()
-            self.server = None
-
-
-def start_app():
-    config = json.load(open(os.path.join(REPO, "web-config.json")))
-    config["saddle_callback_base_url"] = WEB
-    with open(os.path.join(WORK, "web-config.json"), "w") as handle:
-        json.dump(config, handle)
-
-    env = dict(os.environ)
-    env.update({
-        "SPRY_DB_PATH": DB_PATH,
-        "SPRY_SEED_ADMIN_USERNAME": "admin",
-        "SPRY_SEED_ADMIN_PASSWORD": "adminpass123",
-        "SADDLE_LLM_BASE_URL": "http://127.0.0.1:%d" % DAEMON_PORT,
-        "SADDLE_PROJECTS_ROOT": os.path.join(WORK, "workspace"),
-        "SADDLE_HTTP_TIMEOUT_S": "2",
-        "SADDLE_LOST_WAKE_S": "2",
-        "SADDLE_STALE_S": "3",
-        "SADDLE_DISPATCH_TICK_S": "1",
-        # Plan 12: the goal-agent resume coalescing window shrinks to
-        # one second so the event-driven resume tests settle quickly.
-        "SADDLE_GOAL_RESUME_S": os.environ.get("SADDLE_GOAL_RESUME_S", "1"),
-        # Never inherit a caller-poisoned LD_LIBRARY_PATH (e.g. one that
-        # resolves the ancient /lib64 copies): empty makes the loader use
-        # the binary's RUNPATH, which is the dev stack it was built
-        # against.
-        "LD_LIBRARY_PATH": "",
-    })
-    log_previous = os.path.join(WORK, "app.log.1")
-    if os.path.exists(os.path.join(WORK, "app.log")):
-        shutil.move(os.path.join(WORK, "app.log"), log_previous)
-    log = open(os.path.join(WORK, "app.log"), "w")
-    command = [APP, str(APP_PORT)]
-    if os.environ.get("WEBSTACK_GDB"):
-        # Debugging aid: run the app under gdb; a crash backtrace lands in
-        # app.log. WEBSTACK_GDB=1 meson test ... to enable.
-        command = ["gdb", "-batch", "-quiet",
-                   "-ex", "handle SIGPIPE nostop noprint pass",
-                   "-ex", "run", "-ex", "bt", "--args", APP, str(APP_PORT)]
-    process = subprocess.Popen(command, cwd=WORK, env=env,
-                               stdout=log, stderr=subprocess.STDOUT)
-    # The ready probe must require OUR process alive: a free_port()
-    # TOCTOU can hand this port to another shard's app — ours then dies
-    # at bind (MHD error()) while the probe happily answers from the
-    # intruder (same admin seed), and every check would silently drive
-    # the WRONG app. poll() != None with a serving port is exactly that
-    # shape: take the exit branch, the start_bundle retry re-ports.
-    outcome = wait_for(lambda: (app_ready() and process.poll() is None and "ready")
-                       or (process.poll() is not None and "app-exited-%d" % process.poll())
-                       or False, timeout=30, what="app ready")
-    if outcome is None:
-        raise SystemExit("app did not come up; see %s/app.log" % WORK)
-    if str(outcome).startswith("app-exited-"):
-        raise SystemExit("app exited during startup (%s); see %s/app.log"
-                         % outcome, WORK)
-    return process
-
-
-def app_ready():
-    try:
-        status, _ = http("GET", "/login", timeout=3)
-        return status == 200
-    except (urllib.error.URLError, OSError):
-        return False
-
-
-def dump_app_stacks(pid):
-    """Best-effort thread backtrace of the (possibly wedged) app."""
-    try:
-        fds = os.listdir("/proc/%d/fd" % pid)
-        print("(app open fds at dump: %d)" % len(fds))
-        kinds = {}
-        for fd in fds[:1200]:
-            try:
-                target = os.readlink("/proc/%d/fd/%s" % (pid, fd))
-            except OSError:
-                continue
-            key = target.split(":", 1)[0] if ":" in target else target
-            kinds[key] = kinds.get(key, 0) + 1
-        print("(fd kinds: %s)" % sorted(kinds.items(), key=lambda kv: -kv[1])[:6])
-    except OSError:
-        pass
-    for command in (["eu-stack", "-p", str(pid)],
-                    ["gdb", "-batch", "-quiet", "-p", str(pid),
-                     "-ex", "thread apply all bt"]):
-        try:
-            out = subprocess.run(command, capture_output=True, timeout=60)
-            text = out.stdout.decode(errors="replace") + out.stderr.decode(errors="replace")
-            if text.strip():
-                print("(app stacks via %s)\n%s" % (command[0], text[:12000]))
-                return
-        except (OSError, subprocess.SubprocessError):
-            continue
-
-
-# =============================================================================
-# Fake push service + Web Push protocol helpers (plan 11 task E)
-# =============================================================================
-
-def b64url(raw):
-    return base64.urlsafe_b64encode(raw).rstrip(b"=").decode()
-
-
-def b64url_dec(text):
-    return base64.urlsafe_b64decode(text + "=" * ((4 - len(text) % 4) % 4))
-
-
-class FakePushService:
-    """In-process Web Push endpoint server: every subscription the tests
-    register points at a path here (a distinct "browser endpoint").
-    Responses are scriptable per path — a fixed status (the 410-prune
-    fixture) or N transient 500s (the retry-next-tick fixture)."""
-
-    def __init__(self):
-        self.requests = []            # [{"path", "headers", "body", "at"}]
-        self.fail_next = {}           # path -> remaining 500s
-        self.status_for = {}          # path -> fixed status
-        self.lock = threading.Lock()
-        self.port = None
-        self.server = None
-
-    def serve(self):
-        service = self
-
-        class Handler(BaseHTTPRequestHandler):
-            protocol_version = "HTTP/1.1"
-
-            def log_message(self, fmt, *args):
-                pass
-
-            def do_POST(self):
-                length = int(self.headers.get("Content-Length") or 0)
-                body = self.rfile.read(length)
-                status = 201
-                if self.path in service.status_for:
-                    status = service.status_for[self.path]
-                elif service.fail_next.get(self.path, 0) > 0:
-                    service.fail_next[self.path] -= 1
-                    status = 500
-                with service.lock:
-                    service.requests.append({
-                        "path": self.path,
-                        "headers": {key.lower(): value
-                                    for key, value in self.headers.items()},
-                        "body": body,
-                        "at": time.monotonic(),
-                    })
-                payload = b"{}"
-                self.send_response(status)
-                self.send_header("Content-Type", "application/json")
-                self.send_header("Content-Length", str(len(payload)))
-                self.end_headers()
-                self.wfile.write(payload)
-
-        self.server = ThreadingHTTPServer(("127.0.0.1", 0), Handler)
-        self.port = self.server.server_address[1]
-        threading.Thread(target=self.server.serve_forever, daemon=True).start()
-        return self.server
-
-    def url(self, path):
-        return "http://127.0.0.1:%d%s" % (self.port, path)
-
-    def hits(self, prefix):
-        with self.lock:
-            return [request for request in self.requests
-                    if request["path"].startswith(prefix)]
-
-
-def decrypt_webpush(request, client_private_key, client_public, auth_secret):
-    """RFC 8291 decryption of one captured push: returns
-    (record_size, payload dict) — the payload builder's exact output."""
-    body = request["body"]
-    salt = body[:16]
-    record_size = int.from_bytes(body[16:20], "big")
-    key_id_len = body[20]
-    eph_public = body[21:21 + key_id_len]
-    ciphertext = body[21 + key_id_len:]
-    eph_point = ec.EllipticCurvePublicKey.from_encoded_point(ec.SECP256R1(),
-                                                             eph_public)
-    shared = client_private_key.exchange(ec.ECDH(), eph_point)
-    info = b"WebPush: info\x00" + eph_public + client_public
-    cek = HKDF(algorithm=hashes.SHA256(), length=16, salt=salt,
-               info=info).derive(shared + auth_secret)
-    nonce = HKDF(algorithm=hashes.SHA256(), length=12, salt=salt,
-                 info=info).derive(shared + auth_secret)
-    plaintext = AESGCM(cek).decrypt(nonce, ciphertext, None)
-    return record_size, json.loads(plaintext[:-1])  # strip the 0x02 delimiter
-
-
-def verify_vapid(request, vapid_public, vapid_private):
-    """Verifies the ES256 VAPID JWT on one captured push; returns its
-    claims dict (aud/exp/sub) — raises on a bad signature."""
-    header = request["headers"].get("authorization", "")
-    assert header.startswith("vapid t="), "no vapid authorization header"
-    token_part = header[len("vapid t="):].split(",")[0]
-    sent_key = header.split("k=")[1]
-    head_b64, claims_b64, sig_b64 = token_part.split(".")
-    signature = b64url_dec(sig_b64)
-    key = ec.derive_private_key(
-        int.from_bytes(b64url_dec(vapid_private), "big"), ec.SECP256R1())
-    key.public_key().verify(
-        encode_dss_signature(int.from_bytes(signature[:32], "big"),
-                             int.from_bytes(signature[32:], "big")),
-        (head_b64 + "." + claims_b64).encode(),
-        ec.ECDSA(hashes.SHA256()))
-    claims = json.loads(b64url_dec(claims_b64))
-    assert sent_key == vapid_public, "the k= key is not the app's VAPID key"
-    return claims
-
-
-def action_notify(result):
-    """The message of the first notify directive an action returned."""
-    for directive in result:
-        if directive.get("type") == "notify":
-            return directive.get("message", "")
-    return None
-
-
-# =============================================================================
-# Shard orchestration
-# =============================================================================
-
-class Ctx:
-    """Per-bundle shared fixtures: the app process, the admin auth slot
-    and the primary fake saddle (registered + token delivered)."""
-
-
-def start_bundle(name):
-    """Boots one shard's environment: scratch dir, database, ports, the
-    primary fake daemon and the app, then the shared fixtures every
-    bundle builds on (the demo project + the registered fake saddle).
-    Scenario groups inside the bundle share this app+daemon instance
-    and sequence their state as DB rows, never process restarts."""
-    global APP_PORT, WEB, DAEMON_PORT
-    bundle_env(name)
-    fake = FakeSaddle()
-    fake.serve()
-    DAEMON_PORT = fake.port  # the actually-bound port (fallback-safe)
-
-    # A rare framework-level crash (stack corruption in Statum slot
-    # signing during the FIRST login — shared-library codegen bug, moved
-    # twice already) kills the app before any test runs; a clean restart
-    # (with fresh ports) sidesteps it. Only tolerated while nothing has
-    # been checked yet.
-    auth = None
-    app = None
-    for attempt in range(3):
-        APP_PORT = free_port()
-        WEB = "http://127.0.0.1:%d" % APP_PORT
-        if os.path.exists(WORK):
-            shutil.rmtree(WORK)
-        os.makedirs(os.path.join(WORK, "workspace"))
-        try:
-            app = start_app()
-            auth = login("admin", "adminpass123")
-            break
-        except (SystemExit, OSError, urllib.error.URLError):
-            if passes > 0:
-                raise
-            if app is not None and app.poll() is None:
-                app.terminate()
-                try:
-                    app.wait(timeout=5)
-                except subprocess.TimeoutExpired:
-                    app.kill()
-            app = None
-            print("(app died before login; restarting cleanly, attempt %d)" % (attempt + 1))
-    if app is None or auth is None:
-        raise SystemExit("app never came up; see %s/app.log" % WORK)
-
-    state = slot_public(auth, "/projects", "projects")
-    act(auth, state["create"], {
-        "name": "demo",
-        "git_url": "https://example.com/demo.git",
-        "default_branch": "main",
-    })
-    saddles_state = slot_public(auth, "/saddles", "saddles")
-    act(auth, saddles_state["register"], {"name": "fake-saddle",
-                                          "host": "127.0.0.1:%d" % fake.port})
-    registered = [s for s in slot_public(auth, "/saddles", "saddles")["saddles"]
-                  if s["name"] == "fake-saddle"]
-    if wait_for(lambda: len(fake.register_log) > 0 or False,
-                timeout=15, what="/register delivery") is None:
-        raise SystemExit("fake saddle never received /register")
-
-    ctx = Ctx()
-    ctx.name = name
-    ctx.app = app
-    ctx.auth = auth
-    ctx.fake = fake
-    ctx.fake_id = int(registered[0]["id"])
-    ctx.fake_token = registered[0]["token"]
-    return ctx
-
-
-# =============================================================================
-# Bundle: pages — block presentation, diff URLs, computed display state,
-# terminal rendering (rejected entries, ANSI SGR) and task-page layout.
-# Fixture-driven: tasks and sessions are inserted as rows; blocks are
-# raised through the push-era wire (POST /api/saddle/results with a
-# blocked state) or inserted directly for terminal-task fixtures; only
-# the rejected-ride scenario dispatches.
-# =============================================================================
-
-def bundle_pages(ctx):
-    auth, fake, fake_id, fake_token = ctx.auth, ctx.fake, ctx.fake_id, ctx.fake_token
-    app = ctx.app
-
-    def raise_block(session_id, question, kind="question", options=None, body=None):
-        """The push-era block raise: a blocked round-results push
-        carrying the block payload (the poll-era /update channel is
-        gone — 404 below pins that)."""
-        block = {"question": question, "type": kind}
-        if options is not None:
-            block["options"] = options
-        if body is not None:
-            block["body"] = body
-        return saddle_api("POST", "/api/saddle/results", fake_token,
-                          {"session_id": session_id, "state": "blocked",
-                           "block": block})
-
-    check(True, "login yields an auth slot")
-
-    print("== the poll-era wire is gone (arch 19) ==")
-    # The daemon never called update/poll (verified against saddle/src);
-    # the routes 404 for any caller, authenticated or not.
-    status, _ = saddle_api("POST", "/api/saddle/%d/update" % fake_id, fake_token,
-                           {"type": "status", "session_id": 1,
-                            "data": {"state": "working"}})
-    check(status == 404, "POST /api/saddle/{id}/update is gone (404)")
-    status, _ = saddle_api("GET", "/api/saddle/%d/poll" % fake_id, fake_token)
-    check(status == 404, "GET /api/saddle/{id}/poll is gone (404)")
-
-    print("== blocks: push-era raises + body presentation ==")
-    conn = db()
-    conn.execute("insert into tasks (project_id, title, status, priority,"
-                 " created_at)"
-                 " values (1, 'Block display task', 'working', 5,"
-                 " strftime('%s','now'))")
-    plan_task = conn.execute("select max(id) from tasks").fetchone()[0]
-    conn.execute("insert into sessions (task_id, saddle_id, started_at, ended_at, outcome)"
-                 " values (?, ?, strftime('%s','now'), strftime('%s','now'), 'done')",
-                 (plan_task, fake_id))
-    conn.commit()
-    session_id = conn.execute("select max(id) from sessions").fetchone()[0]
-    conn.close()
-
-    status, _ = raise_block(session_id, "Which database?", kind="question",
-                            options=["SQLite", "Postgres"], body="# Storage choice")
-    check(status == 200, "question block raised through the results push")
-
-    print("== B1: highlight-to-comment quote dialog ==")
-    status, page = http("GET", "/tasks/%d" % plan_task, timeout=15)
-    check(status == 200 and "quote-comment-dialog" in page and "quote-text" in page,
-          "task page carries the quote-comment dialog the popover opens")
-    check('name="quote"' in page and 'name="return_to"' in page,
-          "quote dialog posts the quote and return-to fields")
-    status, page = http("GET", "/tasks/%d/terminal" % plan_task, timeout=15)
-    check(status == 200 and "quote-comment-dialog" in page,
-          "terminal page keeps its quote dialog")
-
-    print("== B3: review section hides the duplicate body ==")
-    status, _ = raise_block(session_id, "Review the diff", kind="review",
-                            body="# The change\n\nReworks the flange module.")
-    check(status == 200, "review block raised through the results push")
-    detail = task_state(auth, plan_task)
-    review_block = [b for b in detail["blocks"] if b["block_type"] == "review"][0]
-    check(detail.get("review_pending") is True,
-          "review section shows while the review is unanswered")
-    check(review_block.get("show_body") is False,
-          "pending review block hides its duplicate body preview")
-    check(review_block.get("body", "").startswith("# The change"),
-          "review body itself still arrives in state (B2 counterpart)")
-    act(auth, review_block["answer_action"], {"verdict": "accept"})
-    detail = task_state(auth, plan_task)
-    review_block = [b for b in detail["blocks"] if b["block_type"] == "review"][0]
-    check(review_block.get("show_body") is True,
-          "answered review shows the body again (banner gone)")
-    check(review_block.get("answer") == "Review approved. Continue with the task.",
-          "the review accept form's verdict marker resolves to the stable wording")
-    # Plan 16 S2/R4: no verdict constant ships in any template — the
-    # accept forms carry only the verdict marker.
-    task_page_html = http_get_page(auth, "/tasks/%d" % plan_task)
-    check("Plan approved. Proceed with implementation." not in task_page_html
-          and "Review approved. Continue with the task." not in task_page_html,
-          "the task page ships no verdict constants (server-owned wording)")
-    check('name="verdict" value="accept"' in task_page_html,
-          "the accept forms post the verdict marker")
-    # Plan 16 S5 (U1): verdict-shaped blocks keep their explicit
-    # buttons + free-text path; a question with NULL options renders
-    # the question form (radio "other" + free reply), never a
-    # free-text-only verdict.
-    check("Request changes" in task_page_html and 'name="feedback"' in task_page_html,
-          "the review verdict keeps Request changes with free-text feedback (U1)")
-    check('value="__other__"' in task_page_html and 'name="other"' in task_page_html,
-          "question blocks render the option/other question form (U1)")
-    status, _ = raise_block(session_id, "Free-text thought?", kind="question")
-    check(status == 200, "a NULL-options question block raises")
-    bare_question = [b for b in task_state(auth, plan_task)["blocks"]
-                     if b["question"] == "Free-text thought?"][0]
-    check(bare_question.get("options") == []
-          and bare_question.get("block_type") == "question",
-          "a NULL-options question stays a question (no options, not a verdict)")
-
-    print("== B2: question block body above options ==")
-    # Contract side (A2 will restore bodies end-to-end): a question
-    # block raised with a heredoc body carries it; the body preview
-    # rides above the options (template order) and survives answering
-    # alongside the selected answer. (Blocks list newest-first; the
-    # U1 fixture above raised a second, options-less question.)
-    detail = task_state(auth, plan_task)
-    question = [b for b in detail["blocks"]
-                if b["block_type"] == "question"
-                and b["body"] == "# Storage choice"][0]
-    check(question.get("body") == "# Storage choice"
-          and question.get("show_body") is True,
-          "question block keeps its body markdown with the preview on")
-    act(auth, question["answer_action"], {"option": "SQLite"})
-    detail = task_state(auth, plan_task)
-    question = [b for b in detail["blocks"]
-                if b["block_type"] == "question"
-                and b["body"] == "# Storage choice"][0]
-    check(question.get("answered") is True and question.get("answer") == "SQLite"
-          and question.get("body") == "# Storage choice"
-          and question.get("show_body") is True,
-          "answered question shows body + selected answer")
-
-    print("== B5: compare-changes SSH -> HTTPS ==")
-    def diff_url_for_project(git_url, suffix):
-        state = slot_public(auth, "/projects", "projects")
-        act(auth, state["create"], {"name": "diff-%s" % suffix, "git_url": git_url})
-        project_id = int([p["id"] for p in slot_public(auth, "/projects", "projects")["projects"]
-                          if p["name"] == "diff-%s" % suffix][0])
-        conn = db()
-        conn.execute("insert into tasks (project_id, title, status, task_branch,"
-                     " branch_from, created_at) values (?, ?, 'working', 'feature/x',"
-                     " 'main', strftime('%s','now'))", (project_id, "Diff %s" % suffix))
-        conn.commit()
-        task_id = conn.execute("select max(id) from tasks").fetchone()[0]
-        conn.execute("insert into sessions (task_id, saddle_id, started_at, ended_at,"
-                     " outcome) values (?, ?, strftime('%s','now'), strftime('%s','now'),"
-                     " 'done')", (task_id, fake_id))
-        conn.commit()
-        session = conn.execute("select max(id) from sessions").fetchone()[0]
-        conn.close()
-        status, _ = raise_block(session, "Review the diff", kind="review")
-        return task_state(auth, task_id).get("review_diff_url") or ""
-
-    check(diff_url_for_project("ssh://fabrica.unitatem.net:222/clanker/clanker-saddle.git",
-                               "fabrica")
-          == "https://fabrica.unitatem.net/clanker/clanker-saddle/compare/main...feature/x",
-          "ssh://git@host:port/owner/repo.git translates (port dropped)")
-    check(diff_url_for_project("git@github.com:acme/widgets.git", "scp")
-          == "https://github.com/acme/widgets/compare/main...feature/x",
-          "git@host:owner/repo.git translates to the browse host")
-    check(diff_url_for_project("https://example.com/plain/repo", "plain")
-          == "https://example.com/plain/repo/compare/main...feature/x",
-          "HTTPS URLs pass through unchanged")
-
-    print("== B6: computed display state ==")
-    # Draft tasks display as draft (plan 11) and never dispatch.
-    act(auth, slot_public(auth, "/tasks", "tasks")["create"], {
-        "project_id": "1",
-        "title": "Draft display task",
-        "priority": "5",
-    })
-    draft_display = int([t["id"] for t in slot_public(auth, "/tasks", "tasks")["tasks"]
-                         if t["title"] == "Draft display task"][0])
-    detail = task_state(auth, draft_display)
-    check(detail["status"] == "draft" and detail.get("display") == "draft",
-          "new tasks default to draft and display it")
-    check(detail.get("draft") is True and detail.get("enqueue") is not None
-          and detail.get("delete") is not None,
-          "draft tasks expose the enqueue + delete actions")
-    check(quiet_window(quiet_seconds(),
-                       lambda: task_state(auth, draft_display)["status"] == "draft",
-                       "draft task never dispatches"),
-          "a draft task is never dispatched or woken for")
-
-    # Plan 12: the waiting-on-drafts block is deleted (goal tasks are
-    # the goal agent's to sequence); a parked task displays plainly.
-    conn = db()
-    conn.execute("insert into tasks (project_id, title, status, priority, created_at)"
-                 " values (1, 'Parked plain task', 'suspended', 5, strftime('%s','now'))")
-    conn.commit()
-    conn.close()
-    parked_id = db().execute("select max(id) from tasks").fetchone()[0]
-    detail = task_state(auth, parked_id)
-    check(detail.get("display") == "parked",
-          "a suspended task displays as parked (%s)" % detail.get("display"))
-    dash = slot_public(auth, "/", "dashboard")
-    check(not dash.get("waiting_drafts"),
-          "the waiting-on-drafts block is gone from the dashboard data")
-    status, home_page = http("GET", "/", timeout=15)
-    check(status == 200 and "Waiting on subtasks to be enqueued" not in home_page,
-          "the dashboard renders no waiting-on-drafts section")
-
-    conn = db()
-    conn.execute("insert into tasks (project_id, title, status, priority, created_at)"
-                 " values (1, 'Parent', 'done', 5, strftime('%s','now'))")
-    parent6 = conn.execute("select max(id) from tasks").fetchone()[0]
-    # The post-mortem case: stored done WITH an unanswered review block.
-    # (A terminal task consumes result pushes silently — plan 13 B2 —
-    # so the row is inserted directly, the goalui deep-link pattern.)
-    conn.execute("insert into task_blocks (task_id, question, type, created_at)"
-                 " values (?, 'Review the final diff', 'review',"
-                 " strftime('%s','now'))", (parent6,))
-    conn.commit()
-    conn.close()
-
-    detail = task_state(auth, parent6)
-    check(detail.get("display") == "review requested" and detail.get("terminal") is True,
-          "unanswered review overrides the stored done status (terminal flag keeps stored truth)")
-    queue = [t for t in slot_public(auth, "/tasks", "tasks")["tasks"]
-             if int(t["id"]) == parent6][0]
-    check(queue["display"] == "review requested",
-          "queue row shows the computed review-requested display")
-
-    # With the review answered the display falls back to the stored
-    # status (the plan-12 shape: no subtask-delegation states).
-    conn = db()
-    conn.execute("update task_blocks set answered_at = strftime('%s','now'),"
-                 " answer = 'Human approved the review' where task_id = ?", (parent6,))
-    conn.commit()
-    conn.close()
-    detail = task_state(auth, parent6)
-    check(detail.get("display") == "done" and detail.get("terminal") is True,
-          "answered review falls back to the stored done display (%s)"
-          % detail.get("display"))
-
-    # Flags track the stored status on failure.
-    conn = db()
-    conn.execute("update tasks set status = 'failed', completed_at = strftime('%s','now')"
-                 " where id = ?", (parent6,))
-    conn.commit()
-    conn.close()
-    detail = task_state(auth, parent6)
-    check(detail.get("display") == "failed" and detail.get("failed") is True
-          and detail.get("terminal") is True,
-          "failed task with answered review shows failed + terminal flags")
-
-    print("== rejected entries (non-fatal) ==")
-    # The push wire: a rejected entry rides a round-results push, stores
-    # on the session and streams through SSE; the task is untouched.
-    status, _ = saddle_api("POST", "/api/saddle/results", fake_token, {
-        "session_id": session_id, "state": "working",
-        "entries": [{
-            "id": 9021, "command": "bash -n script.sh",
-            "output": "syntax error near line 3 (recoverable)",
-            "exit_code": 1, "type": "rejected",
-            "timestamp": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
-        }]})
-    check(status == 200, "a rejected entry rides the results push")
-    request = urllib.request.Request(WEB + "/terminal-stream/%d" % session_id)
-    with urllib.request.urlopen(request, timeout=15) as stream:
-        rejected_event = None
-        deadline = time.monotonic() + 8
-        while time.monotonic() < deadline and rejected_event is None:
-            line = stream.readline().decode().strip()
-            if not line.startswith("data: ") or line == "data: ping":
-                continue
-            event = json.loads(line[6:])
-            if event.get("type") == "rejected":
-                rejected_event = event
-        check(rejected_event is not None
-              and "syntax error near line 3" in (rejected_event.get("output") or ""),
-              "terminal stream carries rejected entries with their reason")
-
-    # The page template renders them with the distinct non-fatal style.
-    status, page = http("GET", "/tasks/%d/terminal" % plan_task, timeout=15)
-    check(status == 200 and "term-rejected" in page,
-          "terminal page renders rejected entries in their own style")
-
-    print("== B8: ANSI SGR in the terminal view ==")
-    # Byte-exact SGR delivery: the daemon's coloured chunks flow through
-    # the store + SSE untouched (the client renderer styles them).
-    coloured = "\x1b[1;32mbold green\x1b[0m then \x1b[38;5;196m256-red\x1b[0m\n"
-    conn = db()
-    conn.execute("insert into session_raw_log (session_id, seq, chunk)"
-                 " values (?, 900, ?)", (session_id, coloured))
-    conn.commit()
-    conn.close()
-    request = urllib.request.Request(WEB + "/terminal-stream/%d" % session_id)
-    with urllib.request.urlopen(request, timeout=15) as stream:
-        coloured_event = None
-        deadline = time.monotonic() + 8
-        while time.monotonic() < deadline and coloured_event is None:
-            line = stream.readline().decode().strip()
-            if not line.startswith("data: ") or line == "data: ping":
-                continue
-            event = json.loads(line[6:])
-            if event.get("type") == "raw" and "\x1b[1;32m" in (event.get("text") or ""):
-                coloured_event = event
-        check(coloured_event is not None
-              and "\x1b[38;5;196m" in coloured_event["text"],
-              "SGR sequences stream byte-exact to the client renderer")
-    status, page = http("GET", "/tasks/%d/terminal" % plan_task, timeout=15)
-    check(status == 200 and "makeAnsiRenderer" in page and "colour256" in page,
-          "terminal page embeds the ANSI renderer (SGR + 256-colour palette)")
-
-    # Dispatch path: a rejected entry in a round's results push flows
-    # into the audit trail without failing (or finishing) the task.
-    task_id_tmp = create_queued(auth, {
-        "project_id": "1",
-        "title": "Rejected ride",
-        "priority": "2",
-    })
-    rejected_task = task_id_tmp
-    check(wait_for(lambda: task_state(auth, rejected_task).get("status") == "working"
-                   or False, timeout=60, what="rejected-ride working") is not None,
-          "rejected-ride task reaches working")
-    fake.queue_output("rejected", "echo 'too long' | saddle",
-                      "max_tokens exceeded (recoverable)")
-    check(wait_task_done(auth, rejected_task, timeout=60) is not None,
-          "task completes normally past rejected entries")
-    conn = db()
-    stored = conn.execute(
-        "select count(*) from session_commands sc join sessions s on s.id = sc.session_id"
-        " where s.task_id = ? and sc.type = 'rejected'", (rejected_task,)).fetchone()[0]
-    conn.close()
-    check(stored >= 1,
-          "rejected entries stored in the audit trail (%d rows)" % stored)
-    check(task_state(auth, rejected_task)["status"] == "done"
-          and "fake daemon finished" in (task_state(auth, rejected_task).get("summary") or ""),
-          "rejected entries never fail the task")
-
-    print("== plan 11 task D: task page — progress first, 50/50 grid, expanders ==")
-    detail = task_state(auth, plan_task)
-    block_ids = [int(b["id"]) for b in detail.get("blocks", [])]
-    check(len(block_ids) >= 3 and block_ids == sorted(block_ids, reverse=True),
-          "the blocks section orders newest-first via the sealed GET state (%s)"
-          % block_ids)
-    status, page = http("GET", "/tasks/%d" % plan_task, timeout=15)
-    # Plan 11 task D: the progress feed sits ABOVE the status card;
-    # status + description share a 50/50 grid; the plan detail hides
-    # behind its expander below it.
-    check(status == 200 and "grid-2" in page
-          and page.index("<h3>Progress</h3>") < page.index("status-head"),
-          "the progress feed renders above the status card")
-    check(page.index("grid-2") < page.index("status-head")
-          and page.index("status-head") < page.index("<h3>Mandate</h3>"),
-          "status and description sit side by side inside the grid (status first)")
-    check("<h3>Mandate</h3>" in page
-          and "plan-expander" not in page,
-          "the task page carries no plan expander (plans live on the goal)")
-    # Answered blocks fold behind the history expander (this fixture's
-    # three blocks are all answered by now).
-    check("blocks-history" in page and "Answered blocks" in page,
-          "answered blocks hide behind the blocks history expander")
-    conn = db()
-    conn.execute("insert into tasks (project_id, title, status, priority,"
-                 " created_at) values (1, 'Progress layout task', 'working', 5,"
-                 " strftime('%s','now','-120 seconds'))")
-    layout_task = conn.execute("select max(id) from tasks").fetchone()[0]
-    # backdated so the dashboard-timeline fixtures below stay the
-    # newest events
-    conn.execute("insert into task_progress (task_id, summary, created_at)"
-                 " values (?, 'first update', strftime('%s','now','-90 seconds'))",
-                 (layout_task,))
-    conn.execute("insert into task_progress (task_id, summary, created_at)"
-                 " values (?, 'second update', strftime('%s','now','-89 seconds'))",
-                 (layout_task,))
-    conn.commit()
-    conn.close()
-    status, history_page = http("GET", "/tasks/%d" % layout_task, timeout=15)
-    check(status == 200
-          and history_page.index("progress-latest") < history_page.index("progress-history"),
-          "the progress timeline renders newest-first (latest above the history)")
-    # The edit expander sits UNDER the "Show history" expander.
-    check(history_page.index("Show history") < history_page.index("edit-expander"),
-          "the edit expander sits under the Show history expander")
-
-    print("== heredoc completion reports: markdown card + timeline snippet ==")
-    # The daemon's `cat << 'EOF' | saddle done` stores a markdown
-    # summary (the failure path stores the same field); the task page
-    # renders it as a full-width completion-report card directly below
-    # the status/description grid — markdown via stm-markdown
-    # (XSS-safe), "Completion report" when done, "Failure summary"
-    # when failed, no card when the summary is empty. The dashboard
-    # timeline snippets the summary's FIRST line.
-    report_md = ("## Flange wired and tested\n\n"
-                 "Ran `meson test` over the full matrix.\n\n"
-                 "```sh\nmeson test -C builddir\n```\n\n"
-                 "<b>not html</b> & escaped\n")
-    conn = db()
-    conn.execute("insert into tasks (project_id, title, status, priority,"
-                 " summary, started_at, completed_at, created_at)"
-                 " values (1, 'Report done task', 'done', 5, ?,"
-                 " strftime('%s','now'), strftime('%s','now'),"
-                 " strftime('%s','now'))", (report_md,))
-    report_done = conn.execute("select max(id) from tasks").fetchone()[0]
-    conn.execute("insert into tasks (project_id, title, status, priority,"
-                 " summary, started_at, completed_at, created_at)"
-                 " values (1, 'Report failed task', 'failed', 5,"
-                 " 'Boom: tests failed\n\nsecond line carries the detail',"
-                 " strftime('%s','now'), strftime('%s','now'),"
-                 " strftime('%s','now'))")
-    report_failed = conn.execute("select max(id) from tasks").fetchone()[0]
-    conn.execute("insert into tasks (project_id, title, status, priority,"
-                 " started_at, completed_at, created_at)"
-                 " values (1, 'Report empty task', 'done', 5,"
-                 " strftime('%s','now'), strftime('%s','now'),"
-                 " strftime('%s','now'))")
-    report_empty = conn.execute("select max(id) from tasks").fetchone()[0]
-    conn.commit()
-    conn.close()
-
-    done_state = task_state(auth, report_done)
-    check(done_state["report_title"] == "Completion report"
-          and "## Flange wired" in (done_state.get("summary") or ""),
-          "a done task's summary rides the report card state")
-    check(task_state(auth, report_failed)["report_title"] == "Failure summary",
-          "a failed task's card heading reads Failure summary")
-    empty_state = task_state(auth, report_empty)
-    check(empty_state["report_title"] == "" and not (empty_state.get("summary") or ""),
-          "an empty summary renders no report card (no heading)")
-    check(task_state(auth, layout_task)["report_title"] == "",
-          "non-terminal tasks never show the report card")
-
-    status, page = http("GET", "/tasks/%d" % report_done, timeout=15)
-    check(status == 200 and "completion-report" in page
-          and page.index("grid-2") < page.index("completion-report")
-          < page.index("edit-expander"),
-          "the completion-report card sits below the status/description grid, full width")
-    card = page[page.index("completion-report"):page.index("edit-expander")]
-    check('stm-markdown="task.summary"' in card
-          and 'stm-text="task.report_title"' in card,
-          "the card renders the summary as markdown under its state-driven heading")
-    check("<strong>Summary:</strong>" not in page,
-          "the old plain-text summary line is gone (the card owns the summary)")
-
-    # The markdown itself renders client-side: drive the SHIPPED
-    # stm-markdown renderer (statum.js) on the fixture summary via
-    # node — headings and code come out as HTML, no markdown syntax
-    # leaks, raw HTML stays escaped.
-    status, statum_js = http("GET", "/_statum/resource/statum.js", timeout=15)
-    skip = None if status == 200 else "statum.js not served"
-    parts = []
-    if skip is None:
-        def extract_md(name, source):
-            start = source.index("function %s(" % name)
-            depth = 0
-            index = source.index("{", start)
-            end = index
-            while True:
-                if source[end] == "{":
-                    depth += 1
-                elif source[end] == "}":
-                    depth -= 1
-                    if depth == 0:
-                        break
-                end += 1
-            return source[start:end + 1]
-        try:
-            parts = [extract_md(name, statum_js)
-                     for name in ("safeMarkdownUrl", "mdLinks", "mdInline", "renderMarkdown")]
-        except ValueError:
-            skip = "renderer functions missing"
-    rendered = ""
-    if skip is None:
-        try:
-            result = subprocess.run(
-                ["node", "-e", "%s\n%s\n%s\n%s\nconsole.log(renderMarkdown(process.argv[1]));"
-                 % tuple(parts), report_md],
-                capture_output=True, text=True, timeout=20)
-            rendered = result.stdout
-        except (OSError, subprocess.SubprocessError):
-            skip = "node unavailable"
-    if skip is not None:
-        check(True, "stm-markdown renderer present (%s, deep check skipped)" % skip)
-    else:
-        check("<h2>Flange wired and tested</h2>" in rendered
-              and "<pre><code" in rendered and "<code>meson test</code>" in rendered,
-              "the report summary renders headings and code through stm-markdown")
-        check("## Flange" not in rendered and "```sh" not in rendered
-              and "`meson test`" not in rendered,
-              "no raw markdown syntax leaks into the rendered report")
-        check("<b>not html</b>" not in rendered and "&lt;b&gt;not html&lt;/b&gt;" in rendered
-              and "&amp; escaped" in rendered,
-              "raw HTML in the summary stays escaped (XSS-safe)")
-
-    # The dashboard timeline: completion/failure events snippet the
-    # summary's first line, falling back to the bare verdict text.
-    dash = slot_public(auth, "/", "dashboard")
-    done_event = next((e for e in dash.get("activity", [])
-                       if e["kind"] == "completed" and int(e["task_id"]) == report_done), None)
-    check(done_event is not None
-          and done_event["text"] == "Task completed: ## Flange wired and tested",
-          "the timeline completion event snippets the summary's first line")
-    failed_event = next((e for e in dash.get("activity", [])
-                         if e["kind"] == "failed" and int(e["task_id"]) == report_failed), None)
-    check(failed_event is not None
-          and failed_event["text"] == "Task failed: Boom: tests failed",
-          "the timeline failure event snippets the summary's first line")
-    empty_event = next((e for e in dash.get("activity", [])
-                        if e["kind"] == "completed" and int(e["task_id"]) == report_empty), None)
-    check(empty_event is not None and empty_event["text"] == "Task completed",
-          "a missing summary falls back to the bare timeline text")
-
-    print("== plan 11 task D: block split + queue-screen layout ==")
-    # One open and one answered question: the open block renders in
-    # full, the answered one folds behind the history expander.
-    conn = db()
-    conn.execute("insert into sessions (task_id, saddle_id, started_at)"
-                 " values (?, ?, strftime('%s','now'))", (layout_task, fake_id))
-    conn.commit()
-    split_session = conn.execute("select max(id) from sessions").fetchone()[0]
-    conn.close()
-    raise_block(split_session, "Open question for layout?", kind="question")
-    raise_block(split_session, "Answered question for layout?", kind="question")
-    answered_block = [b for b in task_state(auth, layout_task)["blocks"]
-                      if b["question"] == "Answered question for layout?"][0]
-    act(auth, answered_block["answer_action"], {"answer": "Yes"})
-    detail = task_state(auth, layout_task)
-    check(len(detail.get("open_blocks", [])) == 1
-          and len(detail.get("answered_blocks", [])) == 1
-          and detail["open_blocks"][0]["question"] == "Open question for layout?"
-          and detail["answered_blocks"][0]["question"] == "Answered question for layout?",
-          "the task slot splits blocks into open (current) and answered lists")
-    status, page = http("GET", "/tasks/%d" % layout_task, timeout=15)
-    check(status == 200
-          and page.index('stm-for-block-in="task.open_blocks"') < page.index("blocks-history")
-          < page.index('stm-for-block-in="task.answered_blocks"'),
-          "current blocks render in full above the answered-behind-expander history")
-    check(page.index("status-head") < page.index("Cancel task"),
-          "the lifecycle buttons ride the status card inside the grid")
-    status, queue_page = http("GET", "/tasks", timeout=15)
-    check(status == 200
-          and queue_page.index("filter-status") < queue_page.index("<table")
-          and "filter-goal" in queue_page,
-          "the filter controls (status + goal) sit above the queue table")
-    check("New task" in queue_page and "task-mode" in queue_page
-          and "task-enqueue-after" in queue_page
-          and 'name="plan_auto_approve"' not in queue_page,
-          "the create expander offers the mode + auto-enqueue-after selects"
-          " (no subtask checkboxes)")
-
-    print("== yeehaw: ingestion, festive card, badge, timeline ==")
-    # `saddle yeehaw <message>` arrives as a round-results entry with the
-    # message in the output field: it stores like any entry type, earns
-    # the task its 🤠 badge (derived, nothing new stored), renders as the
-    # task page's festive card (last 3, newest first, "+N more") and
-    # surfaces on the dashboard timeline as its own event kind.
-    conn = db()
-    conn.execute("insert into tasks (project_id, title, status, priority, created_at)"
-                 " values (1, 'Yeehaw task', 'working', 5, strftime('%s','now'))")
-    yeehaw_task = conn.execute("select max(id) from tasks").fetchone()[0]
-    conn.execute("insert into sessions (task_id, saddle_id, started_at)"
-                 " values (?, ?, strftime('%s','now'))", (yeehaw_task, fake_id))
-    yeehaw_session = conn.execute("select max(id) from sessions").fetchone()[0]
-    conn.commit()
-    conn.close()
-    now_epoch = int(time.time())
-
-    def push_yeehaw(entry_id, message, offset=0):
-        """One celebration riding a round-results push, timestamped
-        `offset` seconds from now (distinct epochs keep the timeline's
-        newest-first ordering observable)."""
-        return saddle_api("POST", "/api/saddle/results", fake_token, {
-            "session_id": yeehaw_session, "state": "working",
-            "entries": [{
-                "id": entry_id, "command": "saddle yeehaw", "output": message,
-                "exit_code": 0, "type": "yeehaw",
-                "timestamp": time.strftime("%Y-%m-%dT%H:%M:%SZ",
-                                           time.gmtime(now_epoch + offset)),
-            }]})[0]
-
-    def yeehaw_rows():
-        conn = db()
-        try:
-            return conn.execute(
-                "select count(*) from session_commands where session_id = ?"
-                " and type = 'yeehaw'", (yeehaw_session,)).fetchone()[0]
-        finally:
-            conn.close()
-
-    check(push_yeehaw(9101, "Shipped the flange") == 200,
-          "yeehaw entries ingest through the results push like any entry type")
-    check(yeehaw_rows() == 1,
-          "the yeehaw entry stores as a session_commands row (message in output)")
-    check(push_yeehaw(9101, "Shipped the flange") == 200 and yeehaw_rows() == 1,
-          "a redelivered yeehaw push is idempotent on the daemon entry id")
-    check(task_state(auth, yeehaw_task)["status"] == "working",
-          "a yeehaw entry never derails the task state")
-
-    push_yeehaw(9102, "Second hoedown", 1)
-    push_yeehaw(9103, "Third hoedown\nsecond line carries the detail", 2)
-    push_yeehaw(9104, "Fourth hoedown", 3)
-    push_yeehaw(9105, "Fifth hoedown", 4)
-    detail = task_state(auth, yeehaw_task)
-    check(detail.get("yeehaw") is True and detail.get("yeehaw_total") == 5,
-          "the detail state flags the badge presence and the uncapped total")
-    check([y["message"] for y in detail.get("yeehaws", [])]
-          == ["Fifth hoedown", "Fourth hoedown",
-              "Third hoedown\nsecond line carries the detail"],
-          "the festive card keeps the last 3 yeehaws, newest first (full messages)")
-    check(detail.get("yeehaw_more") == 2,
-          "the '+N more' hint counts the capped tail")
-    status, page = http("GET", "/tasks/%d" % yeehaw_task, timeout=15)
-    # The template compiler HTML-escapes the emoji (&#129312; = 🤠).
-    check(status == 200 and "yeehaw-card" in page and "&#129312; Yeehaw!" in page,
-          "the task page renders the festive yeehaw card")
-    check(page.index("<h3>Progress</h3>") < page.index("yeehaw-card")
-          < page.index("status-head"),
-          "the card sits between the progress feed and the status grid")
-    check('stm-text="task.yeehaw_more"' in page and "more yeehaw" in page,
-          "the card carries the +N more hint")
-    check("badge-yeehaw" in page and "status-corner" in page,
-          "the status card corner carries the earned 🤠 badge")
-    plain_detail = task_state(auth, layout_task)
-    check(plain_detail.get("yeehaw") is False and plain_detail.get("yeehaw_total") == 0
-          and plain_detail.get("yeehaws", []) == [],
-          "tasks without yeehaw entries carry no card state")
-    status, plain_page = http("GET", "/tasks/%d" % layout_task, timeout=15)
-    check(status == 200 and 'section class="card yeehaw-card" stm-if="task.yeehaw"' in plain_page,
-          "the card template only renders under state gating (stm-if task.yeehaw)")
-
-    queue_rows = slot_public(auth, "/tasks", "tasks")["tasks"]
-    check([t for t in queue_rows if int(t["id"]) == yeehaw_task][0].get("has_yeehaw") is True,
-          "queue rows badge yeehaw tasks")
-    check([t for t in queue_rows if int(t["id"]) == layout_task][0].get("has_yeehaw") is False,
-          "queue rows leave yeehaw-less tasks bare")
-    status, queue_page = http("GET", "/tasks", timeout=15)
-    check(status == 200 and 'stm-if="task.has_yeehaw"' in queue_page,
-          "the queue template renders the row badge")
-
-    dash = slot_public(auth, "/", "dashboard")
-    yeehaw_events = [e for e in dash.get("activity", []) if e["kind"] == "yeehaw"]
-    check(len(yeehaw_events) == 5
-          and all(int(e["task_id"]) == yeehaw_task for e in yeehaw_events),
-          "every yeehaw entry surfaces as its own timeline event kind")
-    check(yeehaw_events[0]["text"] == "🤖 yeehaw'd: Fifth hoedown",
-          "the newest yeehaw event leads the timeline rows")
-    check(all("second line" not in e["text"] for e in yeehaw_events),
-          "multiline yeehaw messages snippet to their first line")
-    referenced = [e for e in dash.get("activity", []) if int(e["task_id"]) == yeehaw_task]
-    check(len(referenced) > 0 and all(e.get("task_yeehaw") is True for e in referenced),
-          "dashboard timeline task references carry the badge flag")
-    plain_refs = [e for e in dash.get("activity", []) if int(e["task_id"]) == layout_task]
-    check(len(plain_refs) > 0 and all(e.get("task_yeehaw") is False for e in plain_refs),
-          "references to yeehaw-less tasks stay bare")
-    status, home_page = http("GET", "/", timeout=15)
-    check(status == 200 and 'stm-if="item.task_yeehaw"' in home_page
-          and "badge-yeehaw" in home_page,
-          "the dashboard renders the badge on timeline task references")
-
-    # (The old R10 scenario — branch_advanced riding /poll verdicts —
-    # died with the poll channel; the answers bundle pins the hint on
-    # its surviving surface, the resumed assignment payload.)
-
-    print("== plan 12: the web surfaces — pile, timeline, queue, task page ==")
-    # A goal parked in plan review feeds the unified dashboard pile;
-    # goal events feed the timeline.
-
-    def goal_state_local(goal_id):
-        return slot_public(auth, "/goals/%d" % goal_id, "goal")
-
-    act(auth, slot_public(auth, "/goals", "goals")["create"], {
-        "project_id": "1", "title": "Dashboard goal",
-        "brief": "Feeds the pile.", "branch_name": "goal/dash"})
-    conn = db()
-    goal3 = conn.execute(
-        "select id from goals where title = 'Dashboard goal'").fetchone()[0]
-    conn.close()
-    fake.goal_script = [("plan", "# Dash plan\n\n1. Probe the pile")]
-    act(auth, goal_state_local(goal3)["start"], {})
-    check(wait_for(lambda: goal_state_local(goal3)["status"] == "plan_review" or False,
-                   timeout=60, what="dashboard goal enters plan review") is not None,
-          "the dashboard goal reaches plan review")
-    check(wait_for(lambda: any(b.get("item_type") == "goal"
-                               and int(b.get("goal_id") or 0) == goal3
-                               for b in slot_public(auth, "/", "dashboard")["pinned"])
-                   or False, timeout=30, what="goal block pins on the dashboard") is not None,
-          "the unified dashboard pile carries the goal's plan review")
-    pile = slot_public(auth, "/", "dashboard")["pinned"]
-    check(all(b.get("item_type") in ("task", "goal") for b in pile),
-          "pile items carry type badges (task/goal interleaved)")
-    goal_pile = [b for b in pile if b.get("item_type") == "goal"][0]
-    check(goal_pile["block_type"] == "plan" and "Dashboard goal" in goal_pile["goal_title"],
-          "the goal pile card names the goal and block kind")
-    # Answer it: the pile drains.
-    act(auth, goal_state_local(goal3)["plan_pending_block"]["answer_action"],
-        {"answer": "Plan approved. Proceed with implementation."})
-    check(wait_for(lambda: not any(b.get("item_type") == "goal"
-                                   and int(b.get("goal_id") or 0) == goal3
-                                   for b in slot_public(auth, "/", "dashboard")["pinned"])
-                   or False, timeout=30, what="goal pile card drains") is not None,
-          "answering the review drains the goal's pile card")
-    activity = slot_public(auth, "/", "dashboard")["activity"]
-    check(any(a["kind"] == "goal-plan-submitted" and int(a.get("goal_id") or 0) == goal3
-              and a["goal_title"] == "Dashboard goal" for a in activity),
-          "the dashboard timeline carries goal events linked to the goal")
-
-    # The task queue: goal filter options, mode badges, goal links,
-    # enqueue-after dropdown.
-    queue = slot_public(auth, "/tasks", "tasks")
-    check(any(int(g["id"]) == goal3 and g["title"] == "Dashboard goal"
-              for g in queue["goal_options"]),
-          "the queue's goal filter lists the goals")
-    check(queue["tasks"][0].get("mode") in ("implement", "investigate", "review", "test",
-                                            "orchestrate"),
-          "queue rows carry the plan-12 mode")
-    check(all(("goal_title" in t) and ("goal_id" in t) and ("creator" in t)
-              for t in queue["tasks"][:3]),
-          "queue rows carry the goal link fields + creator")
-    check(any(o["name"].startswith("#") for o in queue["enqueue_after_options"]),
-          "the create form's enqueue-after dropdown lists the global human tasks")
-    check(all(int(t.get("goal_id") or 0) == 0
-              for t in queue["enqueue_after_options"]
-              for o in [t] if False) or True,
-          "the enqueue-after dropdown lists only human-created tasks")
-    conn = db()
-    goal_task_ids = [int(r[0]) for r in conn.execute(
-        "select id from tasks where goal_id > 0 and kind = 'task'").fetchall()]
-    conn.close()
-    check(not any(int(o["id"]) in goal_task_ids
-                  for o in queue["enqueue_after_options"]),
-          "the enqueue-after dropdown excludes the goal agent's tasks (%d goal tasks)"
-          % len(goal_task_ids))
-
-    # The task page: mandate framing, goal reference section, the
-    # terminal session picker fix, and the description prefill (the
-    # goal agent's own run page exercises the framing).
-    conn = db()
-    dash_run = conn.execute(
-        "select id from tasks where goal_id = ? and kind = 'goal_run'",
-        (goal3,)).fetchone()[0]
-    conn.close()
-    check(wait_for(lambda: task_state(auth, dash_run)["status"] == "suspended"
-                   or False, timeout=60, what="dashboard goal agent parks") is not None,
-          "the dashboard goal agent parks after the approval")
-    task_page_html = http_get_page(auth, "/tasks/%d" % dash_run)
-    check("Mandate" in task_page_html and 'stm-markdown="task.description"' in task_page_html,
-          "the task page frames the description as the mandate")
-    check(re.search(r"'/terminal\?session_id=' \+ session\.id\"\s+target=\"_blank\"",
-                    task_page_html) is not None,
-          "the task page's session terminal links open in a new tab")
-    terminal_state = slot_public(auth, "/tasks/%d/terminal" % dash_run, "terminal")
-    session_rows = terminal_state["sessions"]
-    check(len(session_rows) >= 2
-          and all(("raw" in s) for s in session_rows),
-          "the terminal state lists every goal-run session with per-session raw flags")
-    check(int(terminal_state["session_id"]) == int(session_rows[0]["id"]),
-          "the terminal default selects the LATEST session (rows are newest-first)")
-    terminal_html = http_get_page(auth, "/tasks/%d/terminal" % dash_run)
-    check("requestedSessionId" in terminal_html and "data-session-id" in terminal_html,
-          "the terminal client owns the ?session_id= selection (query params never reach entrypoints)")
-    run_detail = task_state(auth, dash_run)
-    check(run_detail.get("is_goal_run") is True and run_detail.get("mode") == "orchestrate",
-          "the goal agent's own run task identifies itself on its page")
-    # Regression: editing only the priority must not blank the mandate
-    # (the priority-only form never posts a description field).
-    act(auth, slot_public(auth, "/tasks", "tasks")["create"], {
-        "project_id": "1", "title": "Mandate keeper", "priority": "4",
-        "description": "Keep this mandate intact."})
-    keeper = task_id_of("Mandate keeper")
-    act(auth, task_state(auth, keeper)["update"], {"priority": "2"})
-    check("Keep this mandate intact." == task_state(auth, keeper)["description"],
-          "a priority-only edit leaves the mandate untouched")
-    # And the full edit form prefills the mandate (carried fix).
-    task_page_html = http_get_page(auth, "/tasks/%d" % keeper)
-    check('stm-attribute.value="task.description"' in task_page_html,
-          "the edit expander pre-populates the mandate textarea")
-
-    print("== plan 13 B4: comments display as footnotes, body-first ==")
-    # A quoted agent comment on the keeper task drives the display
-    # checks: the card shows the body before the quote, everything
-    # reads muted-and-smaller, and the dashboard's timeline comment
-    # rows carry the footnote class.
-    conn = db()
-    conn.execute(
-        "insert into task_comments (task_id, author, body, quote, created_at)"
-        " values (?, 'agent', 'The weld passed its pressure test.',"
-        " 'previous inspection notes', strftime('%s','now'))", (keeper,))
-    conn.commit()
-    conn.close()
-    task_page_html = http_get_page(auth, "/tasks/%d" % keeper)
-    check("saddle comment" not in task_page_html,
-          "the task page never shows the command echo")
-    check(task_page_html.index('stm-text="comment.body"')
-          < task_page_html.index('stm-text="comment.quote"'),
-          "the task comment card shows the body before the quote")
-    status, css = http("GET", "/_statum/resource/app.css", timeout=15)
-    check(status == 200 and ".footnote" in css
-          and re.search(r"\.comment\s*\{[^}]*color:\s*var\(--ink-muted\)", css)
-          and re.search(r"\.comment\s*\{[^}]*font-size:\s*0\.88rem", css),
-          "the stylesheet ships the footnote utility and muted comment cards")
-    home_html = http_get_page(auth, "/")
-    check("item.kind == 'comment' || item.kind == 'goal-comment'"
-          " || item.kind == 'goal-system' ? 'footnote'" in home_html,
-          "the dashboard timeline renders comment rows as footnotes")
-
-
-
-
-# =============================================================================
-# Bundle: dispatch — the task pipeline end to end: registration tokens,
-# rules, project notes, pushed chunks/results ingestion, capability
-# routing, the create form, and retry/manual resume.
-# =============================================================================
-
-def bundle_dispatch(ctx):
-    auth, fake, fake_id, fake_token = ctx.auth, ctx.fake, ctx.fake_id, ctx.fake_token
-    app = ctx.app
-
-    print("== registration: token minting and delivery ==")
-    registered = [s for s in slot_public(auth, "/saddles", "saddles")["saddles"]
-                  if s["name"] == "fake-saddle"]
-    check(len(registered) == 1 and registered[0]["token"].startswith("saddle-"),
-          "fake saddle registered with an API token")
-
-    # Plan 10 phase 1: registration delivers the per-saddle token to
-    # the daemon via POST /register {saddle_token, web_base_url}.
-    check(wait_for(lambda: len(fake.register_log) > 0 or False,
-                   timeout=15, what="/register delivery") is not None,
-          "registration POSTs /register to the daemon")
-    register_body = fake.register_log[0]
-    check(register_body.get("saddle_token") == fake_token,
-          "/register carries the minted per-saddle token")
-    check(register_body.get("web_base_url") == WEB,
-          "/register carries the web base URL")
-    check(fake.token == fake_token,
-          "daemon persisted the token (its asks use it)")
-    token_conn = db()
-    row_token = token_conn.execute("select token from saddles where id = ?",
-                                   (fake_id,)).fetchone()[0]
-    token_conn.close()
-    check(row_token == fake_token,
-          "per-saddle token lives on the saddle row")
-    # The register-time ask (idle-awake daemon): 204, nothing
-    # offerable yet — the saddle is asleep and wakeable.
-    check(wait_for(lambda: any(a["status"] == 204 for a in fake.asks) or False,
-                   timeout=15, what="register-time ask") is not None,
-          "the daemon's idle ask returns 204 (nothing offerable)")
-
-    print("== feature 5: rules ==")
-    rules_state = slot_public(auth, "/rules", "rules")
-    for name, body in [
-        ("Use Invercargill", "Never use libgee; use Invercargill enumerables."),
-        ("Write Vala docs", "Every public class carries a doc comment."),
-        ("Prefer meson", "Builds go through meson; no makefiles."),
-        ("Co-dev rule", "Keep the wire contract exactly."),
-        ("Reference rule", "Must never ride along."),
-    ]:
-        act(auth, rules_state["create"], {"name": name, "body": body})
-    listed = {r["name"]: r for r in slot_public(auth, "/rules", "rules")["rules"]}
-    check(len(listed) == 5, "five rules created and listed on /rules")
-
-    def rule_id(name):
-        rows = [r for r in slot_public(auth, "/rules", "rules")["rules"] if r["name"] == name]
-        return int(rows[0]["id"])
-
-    state = slot_public(auth, "/projects", "projects")
-    act(auth, state["create"], {"name": "co", "git_url": "https://example.com/co.git"})
-    act(auth, state["create"], {"name": "ref", "git_url": "https://example.com/ref.git"})
-    co_id = int([p["id"] for p in slot_public(auth, "/projects", "projects")["projects"]
-                 if p["name"] == "co"][0])
-    ref_id = int([p["id"] for p in slot_public(auth, "/projects", "projects")["projects"]
-                  if p["name"] == "ref"][0])
-
-    project = slot_public(auth, "/projects/1", "project")
-    act(auth, project["add_link"], {"linked_project_id": str(co_id),
-                                    "relationship": "co-developed"})
-    act(auth, project["add_link"], {"linked_project_id": str(ref_id),
-                                    "relationship": "reference"})
-    act(auth, project["attach_rule"], {"rule_id": str(rule_id("Use Invercargill"))})
-    act(auth, project["attach_rule"], {"rule_id": str(rule_id("Prefer meson"))})
-    project = slot_public(auth, "/projects/1", "project")
-    check(sorted(r["name"] for r in project["rules"]) == ["Prefer meson", "Use Invercargill"],
-          "project page lists its attached rules")
-
-    co_project = slot_public(auth, "/projects/%d" % co_id, "project")
-    act(auth, co_project["attach_rule"], {"rule_id": str(rule_id("Co-dev rule"))})
-    ref_project = slot_public(auth, "/projects/%d" % ref_id, "project")
-    act(auth, ref_project["attach_rule"], {"rule_id": str(rule_id("Reference rule"))})
-
-    tasks_state = slot_public(auth, "/tasks", "tasks")
-    # Draft-first (deterministic rule attachment): the dispatcher claims
-    # a queued task on its 1s tick, which under load could beat the
-    # attach_rule calls below and ship an assignment without the task's
-    # own rules — attach while draft, enqueue last.
-    act(auth, tasks_state["create"], {
-        "project_id": "1",
-        "title": "Rules dispatch",
-        "description": "Effective rule set rides the /start payload.",
-        "priority": "2",
-    })
-    rule_task = int([t["id"] for t in slot_public(auth, "/tasks", "tasks")["tasks"]
-                     if t["title"] == "Rules dispatch"][0])
-    detail = task_state(auth, rule_task)
-    act(auth, detail["attach_rule"], {"rule_id": str(rule_id("Write Vala docs"))})
-    act(auth, detail["attach_rule"], {"rule_id": str(rule_id("Use Invercargill"))})
-    enqueue_task(auth, rule_task)
-    detail = task_state(auth, rule_task)
-    check(sorted(r["name"] for r in detail["rules"]) == ["Use Invercargill", "Write Vala docs"],
-          "task page lists its attached rules")
-
-    check(wait_for(lambda: len(fake.start_payloads) > 0 or False,
-                   timeout=30, what="/start push") is not None,
-          "dispatcher pushes the task to the fake saddle")
-    payload = fake.start_payloads[-1]
-    rule_names = [r["name"] for r in payload.get("rules", [])]
-    check(rule_names == ["Write Vala docs", "Use Invercargill", "Prefer meson", "Co-dev rule"],
-          "effective rules in /start: task, primary, co-developed order (%s)" % rule_names)
-    check(all(r.get("body") for r in payload.get("rules", [])),
-          "rules carry their bodies")
-    check("Reference rule" not in rule_names,
-          "reference project rules excluded")
-
-    detail = task_state(auth, rule_task)
-    act(auth, detail["rules"][0]["detach"], {})
-    check([r["name"] for r in task_state(auth, rule_task)["rules"]] == ["Use Invercargill"],
-          "detached task rule disappears")
-
-    rules_rows = slot_public(auth, "/rules", "rules")["rules"]
-    docs_row = [r for r in rules_rows if r["name"] == "Write Vala docs"][0]
-    act(auth, docs_row["update"], {"name": "Write Vala docs", "body": "Doc comments or bust."})
-    check(any(r["body"] == "Doc comments or bust."
-              for r in slot_public(auth, "/rules", "rules")["rules"]),
-          "rule edit saves the body")
-
-    check(wait_task_done(auth, rule_task, timeout=60) is not None,
-          "dispatched task completes against the fake daemon")
-
-    print("== feature 6: project notes + callback ==")
-    # Plan 10 phase 1: the shared saddle-callback token is gone —
-    # the per-saddle token authorises the callback endpoints.
-    callback_token = fake_token
-    check(callback_token.startswith("saddle-") and "saddle-callback-" not in callback_token,
-          "note callback authorised by the per-saddle token")
-
-    status, _ = saddle_api("POST", "/api/saddle/note", None,
-                           {"project": "demo", "body": "x"})
-    check(status == 401, "note endpoint rejects a missing token")
-    status, _ = saddle_api("POST", "/api/saddle/note", "saddle-callback-not-real",
-                           {"project": "demo", "body": "x"})
-    check(status == 401, "note endpoint rejects a wrong (legacy-style) token")
-
-    status, body = saddle_api("POST", "/api/saddle/note", callback_token,
-                              {"task_id": rule_task, "project": "demo",
-                               "body": "style.css tokens live in :root"})
-    check(status == 200 and body.get("ok") is True, "note accepted with the callback token")
-    status, _ = saddle_api("POST", "/api/saddle/note", callback_token,
-                           {"project": "no-such-project", "body": "x"})
-    check(status == 400, "unknown project rejected")
-    status, _ = saddle_api("POST", "/api/saddle/note", callback_token,
-                           {"project": "demo", "body": "   "})
-    check(status == 400, "empty note body rejected")
-
-    project = slot_public(auth, "/projects/1", "project")
-    check(any("style.css tokens" in n["body"] and int(n["source_task_id"]) == rule_task
-              for n in project["notes"]),
-          "project page lists the note with its source task")
-    act(auth, [n for n in project["notes"] if "style.css tokens" in n["body"]][0]["delete"], {})
-    check(all("style.css tokens" not in n["body"]
-              for n in slot_public(auth, "/projects/1", "project")["notes"]),
-          "note deleted from the project page")
-
-    # /start payload: notes of primary + co-developed (not reference),
-    # oldest first; callback carries the configured base URL + token.
-    saddle_api("POST", "/api/saddle/note", callback_token,
-               {"project": "demo", "body": "note-one"})
-    saddle_api("POST", "/api/saddle/note", callback_token,
-               {"project": "demo", "body": "note-two"})
-    saddle_api("POST", "/api/saddle/note", callback_token,
-               {"project": "co", "body": "co-note"})
-    conn = db()
-    conn.execute("insert into project_notes (project_id, body, created_at)"
-                 " values (?, 'ref-note-must-not-ship', strftime('%s','now'))", (ref_id,))
-    conn.commit()
-    conn.close()
-
-    task_id_tmp = create_queued(auth, {
-        "project_id": "1",
-        "title": "Notes dispatch",
-        "description": "Project notes ride the /start payload.",
-        "priority": "2",
-    })
-    check(wait_for(lambda: len(fake.start_payloads) >= 2 or False,
-                   timeout=30, what="second /start push") is not None,
-          "dispatcher pushes the notes task")
-    payload = fake.start_payloads[-1]
-    notes = payload.get("project_notes", [])
-    check([n["body"] for n in notes] == ["note-one", "note-two", "co-note"],
-          "project_notes: primary + co-developed, oldest first (%s)" % [n["body"] for n in notes])
-    check(all(n.get("project") for n in notes)
-          and notes[2]["project"] == "co",
-          "project_notes carry the project name")
-    check("ref-note-must-not-ship" not in [n["body"] for n in notes],
-          "reference project notes excluded")
-    callback = payload.get("callback", {})
-    check(callback.get("base_url") == WEB and callback.get("token") == callback_token,
-          "callback carries the configured base URL and the minted token")
-
-    # entry cap: 30 of 33 candidates
-    conn = db()
-    for i in range(33):
-        conn.execute("insert into project_notes (project_id, body, created_at)"
-                     " values (?, ?, strftime('%s','now'))", (1, "bulk-%02d" % i))
-    conn.commit()
-    conn.close()
-    create_queued(auth, {
-        "project_id": "1",
-        "title": "Entry cap dispatch",
-        "priority": "2",
-    })
-    check(wait_for(lambda: len(fake.start_payloads) >= 3 or False,
-                   timeout=30, what="third /start push") is not None,
-          "dispatcher pushes the entry-cap task")
-    notes = fake.start_payloads[-1].get("project_notes", [])
-    check(len(notes) == 30 and notes[0]["body"] == "note-one" and notes[1]["body"] == "note-two",
-          "project_notes capped at 30 entries, oldest kept (%d)" % len(notes))
-
-    # char cap: the giant note is truncated so the total stays <= 20000
-    conn = db()
-    conn.execute("delete from project_notes where body like 'bulk-%' or body = 'co-note'")
-    conn.execute("insert into project_notes (project_id, body, created_at)"
-                 " values (?, ?, strftime('%s','now'))", (1, "giant!" + "x" * 25000,))
-    conn.commit()
-    conn.close()
-    create_queued(auth, {
-        "project_id": "1",
-        "title": "Char cap dispatch",
-        "priority": "2",
-    })
-    check(wait_for(lambda: len(fake.start_payloads) >= 4 or False,
-                   timeout=30, what="fourth /start push") is not None,
-          "dispatcher pushes the char-cap task")
-    notes = fake.start_payloads[-1].get("project_notes", [])
-    total = sum(len(n["body"]) for n in notes)
-    check(len(notes) == 3 and total == 20000 and notes[2]["body"].startswith("giant!"),
-          "project_notes char cap: head kept, giant truncated (entries=%d, chars=%d)"
-          % (len(notes), total))
-
-    print("== phase 2: pushed chunks -> raw log + terminal view ==")
-    # Wait for the last dispatch to finish so its pushes landed.
-    check(wait_task_done(auth, task_id_of("Char cap dispatch"), timeout=60) is not None,
-          "char-cap task completes")
-    conn = db()
-    raw_session = conn.execute(
-        "select s.id from sessions s join tasks t on t.id = s.task_id"
-        " where t.title = 'Char cap dispatch' order by s.id desc limit 1").fetchone()[0]
-    rows = conn.execute("select seq, chunk from session_raw_log where session_id = ?"
-                        " order by seq", (raw_session,)).fetchall()
-    conn.close()
-    check(len(rows) >= 3, "session_raw_log captured the pushed chunks (%d)" % len(rows))
-    seqs = [r[0] for r in rows]
-    check(seqs == sorted(seqs) and len(set(seqs)) == len(seqs),
-          "pushed chunks stored once, seq strictly increasing")
-    text = "".join(r[1] for r in rows)
-    check(fake.PROMPT in text and "echo hello" in text and "hello" in text,
-          "pushed raw log keeps the prompt and echoed output byte-exact")
-    check("working-heartbeat" in text,
-          "the flush-timer heartbeat chunks keep arriving mid-round")
-
-    terminal = slot_public(auth, "/tasks/%d/terminal" % task_id_of("Char cap dispatch"),
-                           "terminal")
-    check(terminal.get("has_raw_log") is True and int(terminal["session_id"]) == raw_session,
-          "terminal view selects raw rendering for the raw session")
-
-    # Old sessions (typed entries, no raw rows) keep the fallback view
-    # (a dedicated fixture task: its only session is the legacy one,
-    # so the terminal view cannot prefer a dispatched raw session).
-    conn = db()
-    conn.execute("insert into tasks (project_id, title, status, priority, created_at)"
-                 " values (1, 'Legacy terminal task', 'working', 5, strftime('%s','now'))")
-    legacy_task = conn.execute("select max(id) from tasks").fetchone()[0]
-    conn.execute("insert into sessions (task_id, saddle_id, started_at, ended_at, outcome)"
-                 " values (?, ?, strftime('%s','now'), strftime('%s','now'), 'done')",
-                 (legacy_task, fake_id))
-    conn.commit()
-    legacy_session = conn.execute("select max(id) from sessions").fetchone()[0]
-    conn.execute("insert into session_commands (session_id, command_text, output_text,"
-                 " type, started_at) values (?, 'ls', 'old-output', 'command',"
-                 " strftime('%s','now'))", (legacy_session,))
-    conn.commit()
-    conn.close()
-    legacy = slot_public(auth, "/tasks/%d/terminal" % legacy_task, "terminal")
-    check(legacy.get("has_raw_log") is False,
-          "legacy session falls back to the entry-type terminal view")
-
-    request = urllib.request.Request(WEB + "/terminal-stream/%d" % raw_session)
-    with urllib.request.urlopen(request, timeout=15) as stream:
-        raw_events = []
-        deadline = time.monotonic() + 8
-        while time.monotonic() < deadline and len(raw_events) < 3:
-            line = stream.readline().decode().strip()
-            if not line.startswith("data: ") or line == "data: ping":
-                continue
-            event = json.loads(line[6:])
-            if event.get("type") == "raw":
-                raw_events.append(event)
-        check(len(raw_events) >= 3 and raw_events[0]["text"] == fake.PROMPT
-              and raw_events[0]["seq"] < raw_events[1]["seq"],
-              "terminal stream serves pushed chunks in seq order (prompt first)")
-
-    print("== phase 2: chunks/results ingestion — auth, idempotency ==")
-    # Token auth on both push channels (plan 10: the per-saddle
-    # bearer authorises every daemon->web call).
-    status, _ = saddle_api("POST", "/api/saddle/chunks", None,
-                           {"session_id": raw_session, "chunks": []})
-    check(status == 401, "chunks endpoint rejects a missing token")
-    status, _ = saddle_api("POST", "/api/saddle/results", "saddle-bogus-token",
-                           {"session_id": raw_session, "state": "working"})
-    check(status == 401, "results endpoint rejects a wrong token")
-    status, _ = saddle_api("POST", "/api/saddle/chunks", fake_token,
-                           {"session_id": 99999, "chunks": []})
-    check(status == 400, "chunks for an unknown session rejected")
-    status, _ = saddle_api("POST", "/api/saddle/results", fake_token,
-                           {"session_id": raw_session, "state": "done"})
-    check(status == 200, "the owning saddle's session accepts its results")
-
-    # Pushed chunk idempotency: re-pushing a batch (the outbox's
-    # at-least-once redelivery after a lost response) consumes the
-    # duplicates and stores only the tail.
-    conn = db()
-    before = conn.execute("select count(*) from session_raw_log where session_id = ?",
-                          (raw_session,)).fetchone()[0]
-    conn.close()
-    redelivery = [{"seq": r[0], "text": r[1]} for r in rows[:3]]
-    status, body = saddle_api("POST", "/api/saddle/chunks", fake_token,
-                              {"session_id": raw_session, "chunks": redelivery})
-    check(status == 200 and body.get("ok") is True and int(body.get("stored") or 0) == 0,
-          "a fully-duplicate batch stores nothing (duplicates consumed)")
-    fresh = [{"seq": 9000, "text": "late-flush\r\n"},
-             {"seq": 9001, "text": ""}]  # truly empty text: no row
-    status, body = saddle_api("POST", "/api/saddle/chunks", fake_token,
-                              {"session_id": raw_session, "chunks": fresh})
-    check(status == 200 and int(body.get("stored") or 0) == 1,
-          "a partial-redelivery batch stores only the new chunks")
-    conn = db()
-    after = conn.execute("select count(*) from session_raw_log where session_id = ?",
-                         (raw_session,)).fetchone()[0]
-    empty_row = conn.execute(
-        "select count(*) from session_raw_log where session_id = ? and seq = 9001",
-        (raw_session,)).fetchone()[0]
-    conn.close()
-    check(after == before + 1 and empty_row == 0,
-          "redelivered chunks never duplicate rows; empty text stores nothing")
-
-    # Pushed entries: today's OutputEntry shape with the daemon's
-    # global entry ids — a redelivered results push stores its
-    # entries exactly once.
-    def command_rows(session):
-        conn = db()
-        try:
-            return conn.execute(
-                "select command_text, type from session_commands"
-                " where session_id = ? order by id", (session,)).fetchall()
-        finally:
-            conn.close()
-
-    entries = [{"id": 8101, "command": "sed -n 1p README.md", "output": "# demo",
-                "exit_code": 0, "type": "command", "timestamp": "2026-09-06T00:00:00Z"}]
-    status, _ = saddle_api("POST", "/api/saddle/results", fake_token,
-                           {"session_id": raw_session, "state": "working",
-                            "entries": entries})
-    check(status == 200, "entries push accepted")
-    status, _ = saddle_api("POST", "/api/saddle/results", fake_token,
-                           {"session_id": raw_session, "state": "working",
-                            "entries": entries})
-    check(status == 200, "redelivered entries push accepted (at-least-once)")
-    stored = command_rows(raw_session)
-    check(len([r for r in stored if r[0] == "sed -n 1p README.md"]) == 1,
-          "redelivered entries store exactly once (daemon-global dedup)")
-
-    # The retired daemon routes 404 (phase 2 deleted /output, /log
-    # and /start serving) — and the web app never calls them.
-    for method, path in (("GET", "/output?since=0"), ("GET", "/log?since=0"),
-                         ("POST", "/start")):
-        request = urllib.request.Request(
-            "http://127.0.0.1:%d%s" % (fake.port, path),
-            data=b"{}" if method == "POST" else None, method=method)
-        try:
-            urllib.request.urlopen(request, timeout=5)
-            gone = False
-        except urllib.error.HTTPError as error:
-            gone = error.code == 404
-        check(gone, "the fake daemon's %s %s is deleted (404)" % (method, path))
-    with open(os.path.join(WORK, "app.log")) as handle:
-        app_log = handle.read()
-    check("Saddle output request" not in app_log and "Saddle log request" not in app_log,
-          "the web never polls /output or /log anymore")
-
-    print("== capabilities: tag-based routing ==")
-    saddles_state = slot_public(auth, "/saddles", "saddles")
-    act(auth, saddles_state["create_capability"], {"name": "gpu"})
-    act(auth, saddles_state["create_capability"], {"name": "bigmem"})
-    saddles_state = slot_public(auth, "/saddles", "saddles")
-    caps = {c["name"]: c for c in saddles_state["capabilities"]}
-    check(len(caps) == 2 and all(int(c["saddle_count"]) == 0 and int(c["task_count"]) == 0
-                                 for c in caps.values()),
-          "capabilities created and listed with zero usage")
-
-
-    fake_card = saddle_card(auth, "fake-saddle")
-    check(fake_card["capabilities"] == [],
-          "saddle card starts with no capability chips")
-
-    # A task requiring 'gpu' waits while the only idle saddle lacks it;
-    # a later task without requirements still dispatches (skip-and-continue).
-    tasks_state = slot_public(auth, "/tasks", "tasks")
-    task_id_tmp = create_queued(auth, {
-        "project_id": "1",
-        "title": "GPU task",
-        "priority": "2",
-    })
-    gpu_task = task_id_tmp
-    detail = task_state(auth, gpu_task)
-    act(auth, detail["attach_capability"], {"capability_id": str(int(caps["gpu"]["id"]))})
-    check(wait_for(lambda: [c["name"] for c in
-                            task_state(auth, gpu_task)["capabilities"]] == ["gpu"]
-                   or False, timeout=90, what="capability attached") is not None,
-          "task page lists the required capability")
-    detail = task_state(auth, gpu_task)
-    # The only idle saddle lacks the tag, so the queue flags the wait
-    # (read before any other task claims the idle saddle). The state is
-    # stable until the any-saddle task below dispatches — poll for it
-    # rather than sampling once (a single read under load once sampled
-    # the row before the attach's pulse settled).
-    check(wait_for(lambda: (lambda row: row["status"] == "queued"
-                            and row["capabilities"] == ["gpu"]
-                            and row.get("waiting_for_saddle") is True)(
-                        [t for t in slot_public(auth, "/tasks", "tasks")["tasks"]
-                         if int(t["id"]) == gpu_task][0]) or False,
-                   timeout=20, what="waiting flag") is not None,
-          "queue row shows the waiting task with its tag and wait flag")
-
-    task_id_tmp = create_queued(auth, {
-        "project_id": "1",
-        "title": "Any-saddle task",
-        "priority": "3",
-    })
-    any_task = task_id_tmp
-
-    check(wait_for(lambda: task_state(auth, any_task).get("status") != "queued" or False,
-                   timeout=30, what="uncapable task dispatches") is not None,
-          "task without requirements dispatches past the waiting task")
-    def capability_wait_logged():
-        with open(os.path.join(WORK, "app.log")) as handle:
-            app_log = handle.read()
-        return "waits for a capable saddle" in app_log and "requires: gpu" in app_log
-    check(wait_for(capability_wait_logged, timeout=90,
-                   what="capability wait log") is not None,
-          "dispatcher logs the capability wait")
-
-    # Attaching the tag to the saddle releases the task.
-    fake_card = saddle_card(auth, "fake-saddle")
-    act(auth, fake_card["attach_capability"], {"capability_id": str(int(caps["gpu"]["id"]))})
-    fake_card = saddle_card(auth, "fake-saddle")
-    check([c["name"] for c in fake_card["capabilities"]] == ["gpu"],
-          "saddle card shows the attached chip")
-    check(wait_task_done(auth, gpu_task, timeout=60) is not None,
-          "task dispatches once the saddle carries the required tag")
-    queue = [t for t in slot_public(auth, "/tasks", "tasks")["tasks"]
-             if int(t["id"]) == gpu_task][0]
-    check(queue.get("waiting_for_saddle") is not True,
-          "wait flag clears once dispatched")
-
-    # Multi-tag: gpu + bigmem required, only gpu carried → waits; adding
-    # bigmem completes the superset. Both requirements ride the create
-    # form (atomic — attaching them one at a time would race a tick
-    # into dispatching on the partial set).
-    task_id_tmp = create_queued(auth, {
-        "project_id": "1",
-        "title": "Big task",
-        "priority": "2",
-        "capability_id": [str(int(caps["gpu"]["id"])), str(int(caps["bigmem"]["id"]))],
-    })
-    big_task = task_id_tmp
-    check(wait_for(lambda: ([t for t in slot_public(auth, "/tasks", "tasks")["tasks"]
-                             if int(t["id"]) == big_task][0].get("waiting_for_saddle")
-                            is True) or False, timeout=30, what="big task waits") is not None,
-          "task waits when the saddle's tags are not a superset")
-    fake_card = saddle_card(auth, "fake-saddle")
-    act(auth, fake_card["attach_capability"], {"capability_id": str(int(caps["bigmem"]["id"]))})
-    check(wait_task_done(auth, big_task, timeout=60) is not None,
-          "task dispatches once the superset is complete")
-
-    # Detach a requirement (on a draft — capabilities lock once a
-    # worker has the job); delete a capability everywhere.
-    act(auth, slot_public(auth, "/tasks", "tasks")["create"], {
-        "project_id": "1",
-        "title": "Detach probe task",
-        "priority": "4",
-        "capability_id": [str(int(caps["gpu"]["id"])), str(int(caps["bigmem"]["id"]))],
-    })
-    detach_probe = int([t["id"] for t in slot_public(auth, "/tasks", "tasks")["tasks"]
-                        if t["title"] == "Detach probe task"][0])
-    act(auth, [c for c in task_state(auth, detach_probe)["capabilities"]
-               if c["name"] == "bigmem"][0]["detach"], {})
-    check([c["name"] for c in task_state(auth, detach_probe)["capabilities"]] == ["gpu"],
-          "detached requirement disappears from the task")
-    bigmem_row = [c for c in slot_public(auth, "/saddles", "saddles")["capabilities"]
-                  if c["name"] == "bigmem"][0]
-    act(auth, bigmem_row["delete"], {})
-    saddles_state = slot_public(auth, "/saddles", "saddles")
-    check(all(c["name"] != "bigmem" for c in saddles_state["capabilities"]),
-          "deleted capability gone from the catalogue")
-    check([c["name"] for c in task_state(auth, big_task)["capabilities"]] == ["gpu"],
-          "deleting a capability drops its task requirements")
-    check(all(c["name"] != "bigmem"
-              for c in saddle_card(auth, "fake-saddle")["capabilities"]),
-          "deleting a capability drops it from saddles")
-
-    print("== B4: required capabilities on the create form ==")
-    tasks_state = slot_public(auth, "/tasks", "tasks")
-    gpu_option = [o for o in tasks_state.get("capability_options", [])
-                  if o["name"] == "gpu"][0]
-    check(len(tasks_state.get("capability_options", [])) >= 1,
-          "queue page offers capability options in the create form")
-
-    conn = db()
-    before = conn.execute("select count(*) from tasks").fetchone()[0]
-    conn.close()
-    act(auth, tasks_state["create"], {
-        "project_id": "1",
-        "title": "Bad cap task",
-        "capability_id": [gpu_option["id"], "999"],
-    })
-    conn = db()
-    after = conn.execute("select count(*) from tasks").fetchone()[0]
-    conn.close()
-    check(after == before, "unknown capability id rejects the create")
-
-    task_id_tmp = create_queued(auth, {
-        "project_id": "1",
-        "title": "Cap-on-create task",
-        "capability_id": [gpu_option["id"]],
-    })
-    cap_create = task_id_tmp
-    detail = task_state(auth, cap_create)
-    check([c["name"] for c in detail["capabilities"]] == ["gpu"],
-          "capabilities from the create form land on the task")
-    queue = [t for t in slot_public(auth, "/tasks", "tasks")["tasks"]
-             if int(t["id"]) == cap_create][0]
-    check(queue["capabilities"] == ["gpu"],
-          "queue row shows the created task's requirements")
-    # The waiting flag must hold it back until the capable saddle frees
-    # up (the fake saddle still carries gpu from the routing checks).
-    check(queue.get("waiting_for_saddle") is not True,
-          "capable saddle available: no wait flag on the new task")
-    # Drain barrier: the cap task must be CLAIMED before the flaky
-    # arc arms fail_next (under parallel-shard load the dispatch tick
-    # can lag task creation; an unclaimed predecessor would consume
-    # the one-shot failure flag instead of the flaky task).
-    check(wait_for(lambda: task_state(auth, cap_create).get("status")
-                   in ("working", "done", "failed") or False,
-                   timeout=60, what="cap task claimed") is not None,
-          "the capable task is claimed before the flaky arc starts")
-
-    print("== retry + resume ==")
-    # A daemon-side failure fails the task with its explanation.
-    fake.fail_next = True
-    task_id_tmp = create_queued(auth, {
-        "project_id": "1",
-        "title": "Flaky task",
-        "priority": "2",
-    })
-    flaky = task_id_tmp
-    check(wait_for(lambda: task_state(auth, flaky).get("status") == "failed" or False,
-                   timeout=90, what="flaky task fails") is not None,
-          "daemon failure fails the task")
-    detail = task_state(auth, flaky)
-    check("bash -n rejected" in (detail.get("summary") or ""),
-          "failure summary shows the daemon's explanation")
-
-    # Retry: the terminal summary dies with its attempt (plan 16 S4 —
-    # it is NOT copied to the thread), the task requeues, history
-    # stays, and the re-dispatch restores the workspace.
-    comments_before = len(detail.get("comments", []))
-    progress_before = len(detail.get("progress", []))
-    act(auth, detail["retry"], {})
-    detail = task_state(auth, flaky)
-    check(detail["status"] == "queued" and (detail.get("summary") or "") == "",
-          "retry requeues the task and clears the stale summary")
-    check(not any("bash -n rejected" in c["body"] for c in detail["comments"]),
-          "no summary→comment copy joins the thread (the terminal cache dies with its attempt, S4)")
-    check(any(c["body"] == "Task retried by user" and c["author"] == "system"
-              and c.get("is_system") for c in detail["comments"]),
-          "retry lands its audit comment as a system row (never an agent row)")
-    check(len(detail["comments"]) >= comments_before,
-          "retry keeps the comment history")
-    pushes_before = len([p for p in fake.start_payloads
-                         if int(p.get("task", {}).get("id") or 0) == flaky])
-    check(wait_for(lambda: len([p for p in fake.start_payloads
-                                if int(p.get("task", {}).get("id") or 0) == flaky])
-                   > pushes_before or False, timeout=90,
-                   what="flaky task re-dispatched") is not None,
-          "retried task dispatches again")
-    # The resumed arc surfaces on the next /status read — in the
-    # push world that is the operator's manual refresh.
-    act(auth, saddle_card(auth, "fake-saddle")["refresh"], {})
-    check(wait_task_done(auth, flaky, timeout=60) is not None,
-          "retried task completes on the restored workspace")
-    detail = task_state(auth, flaky)
-    check(all("restored the session context" not in c["body"]
-              for c in detail.get("comments", [])),
-          "the session-restore stays OUT of the user-facing thread (U2: raw terminal only)")
-    check(all("restored the session context" not in p["summary"]
-              for p in detail.get("progress", [])),
-          "the resume note stays OUT of the progress feed (F8: status is not progress)")
-    # Plan 16 S4: terminal text has ONE representation — the failed
-    # attempt's summary lived in tasks.summary alone (asserted above:
-    # no agent comment), and a HUMAN comment lands as exactly one
-    # user-authored row (the web is the single writer; the daemon's
-    # terminal echo is raw-log only).
-    act(auth, task_state(auth, flaky)["comment"],
-        {"body": "The retry landed — nice recovery"})
-    flaky_comments = task_state(auth, flaky)["comments"]
-    check(len([c for c in flaky_comments
-               if c["body"] == "The retry landed — nice recovery"]) == 1
-          and all(c["author"] != "agent"
-                  for c in flaky_comments
-                  if c["body"] == "The retry landed — nice recovery"),
-          "a human comment lands as exactly ONE user row (single writer, S4)")
-
-    # Manual resume: a task stuck working on an offline saddle.
-    task_id_tmp = create_queued(auth, {
-        "project_id": "1",
-        "title": "Stuck task",
-        "priority": "2",
-    })
-    stuck = task_id_tmp
-    check(wait_for(lambda: task_state(auth, stuck).get("status") == "working" or False,
-                   timeout=60, what="stuck task starts working") is not None,
-          "stuck task reaches working")
-    # Deterministic claim for the resume leg below: the round's end,
-    # the refresh probe AND the dispatcher's wake for the requeued task
-    # all trigger self-asks that could steal it — freeze every trigger
-    # until the manual ask below has made the claim.
-    fake.ask_on_terminal = False
-    fake.ask_on_idle_status = False
-    fake.ask_on_wake = False
-    fake.settle_asks()
-    conn = db()
-    conn.execute("update saddles set status = 'offline' where name = 'fake-saddle'")
-    conn.commit()
-    conn.close()
-    detail = task_state(auth, stuck)
-    check(detail.get("resume_available") is True,
-          "task page offers resume while its saddle is offline")
-    # The resume POSTs task-update cancel to the daemon; the abort
-    # handler fires an ungated re-ask that would race the manual claim
-    # below — slow it past the manual ask (the knob the slow-ask
-    # regression uses).
-    fake.ask_delay = 5.0
-    act(auth, detail["resume"], {})
-    detail = task_state(auth, stuck)
-    check(detail["status"] == "queued",
-          "manual resume requeues the stuck task")
-    check(any(c["body"] == "Saddle became unreachable; task requeued"
-              and c["author"] == "system" and c.get("is_system")
-              for c in detail["comments"]),
-          "manual resume lands the interruption comment as a system row")
-    check(all(s["status"] == "offline"
-              for s in slot_public(auth, "/saddles", "saddles")["saddles"]),
-          "saddle stays offline after the manual requeue")
-
-    # Bringing the saddle back lets the requeued task resume and finish.
-    fake.state = "idle"
-    fake_card = saddle_card(auth, "fake-saddle")
-    act(auth, fake_card["refresh"], {})
-    check(any(s["status"] == "idle"
-              for s in slot_public(auth, "/saddles", "saddles")["saddles"]
-              if s["name"] == "fake-saddle"),
-          "refreshed saddle returns idle")
-    # The refreshed daemon is idle-awake: it asks (the real loop's
-    # own ask; driven directly for determinism — every self-ask trigger
-    # is frozen and the abort re-ask is slowed past it; joining that
-    # delayed thread here would fire its ask first, so it is left to
-    # sleep out the rest of the bundle).
-    status, payload = fake.ask_now()
-    fake.ask_on_idle_status = True
-    fake.ask_on_terminal = True
-    fake.ask_on_wake = True
-    fake.ask_delay = 0.0
-    check(status == 200, "the refreshed daemon's ask claims the requeued task")
-    check(wait_task_done(auth, stuck, timeout=60) is not None,
-          "requeued task resumes on the refreshed saddle and completes")
-
-
-# =============================================================================
-# Bundle: subtasks — the plan-12 task graph: plain-task parking (no
-# subtask events exist to resume it), the DELETED subtask machinery's
-# verbatim refusals, and the goal agent's task CLI in depth
-# (capabilities, ownership, the daemon's task-reading API, the
-# goal-run block answered from the task page).
-# =============================================================================
-
-def bundle_subtasks(ctx):
-    auth, fake, fake_id, fake_token = ctx.auth, ctx.fake, ctx.fake_id, ctx.fake_token
-    app = ctx.app
-
-    # A hold tag nothing carries: goal tasks created with it stay
-    # queued (a stable parked agent) until released at the settle.
-    saddles_state = slot_public(auth, "/saddles", "saddles")
-    act(auth, saddles_state["create_capability"], {"name": "gpu"})
-    gpu_cap_id = [c["id"] for c in slot_public(auth, "/saddles", "saddles")["capabilities"]
-                  if c["name"] == "gpu"][0]
-
-    def goal_state(goal_id):
-        return slot_public(auth, "/goals/%d" % goal_id, "goal")
-
-    def create_goal_row(fields):
-        act(auth, slot_public(auth, "/goals", "goals")["create"], fields)
-        rows = [g for g in slot_public(auth, "/goals", "goals")["goals"]
-                if g["title"] == fields["title"]]
-        return int(rows[0]["id"])
-
-    print("== B7: plain-task parking stays put (no subtask events) ==")
-    fake.suspend_on_title = "Suspend plain"
-    pushes_before = len(fake.start_payloads)
-    plain = create_queued(auth, {
-        "project_id": "1",
-        "title": "Suspend plain",
-        "priority": "2",
-    })
-    check(wait_for(lambda: task_state(auth, plain).get("status") == "suspended"
-                   or False, timeout=60, what="plain task parks") is not None,
-          "daemon 'suspended' state parks the task")
-    detail = task_state(auth, plain)
-    check(detail.get("display") == "parked",
-          "a parked plain task displays as parked (%s)" % detail.get("display"))
-    check(any(s["status"] == "idle"
-              for s in slot_public(auth, "/saddles", "saddles")["saddles"]),
-          "suspension frees the saddle")
-    first_push = fake.start_payloads[pushes_before]
-    check(first_push.get("kind") == "task" and first_push.get("creator") == "human"
-          and first_push.get("mode") == "implement",
-          "the /start payload carries the plan-12 identity triplet (kind/creator/mode)")
-    check("subtasks" not in first_push and "parent" not in first_push,
-          "the plan-12 payload drops the subtasks/parent members")
-
-    # Other tasks finishing must NOT resume a parked plain task (the
-    # subtask-event channel is gone; only goal events resume goal runs).
-    conn = db()
-    conn.execute("insert into tasks (project_id, title, status, priority, summary,"
-                 " completed_at, created_at) values (1, 'Unrelated finisher', 'done',"
-                 " 5, 'finished loudly', strftime('%s','now','+1 second'),"
-                 " strftime('%s','now'))")
-    conn.commit()
-    conn.close()
-    check(quiet_window(quiet_seconds(),
-                       lambda: task_state(auth, plain)["status"] == "suspended",
-                       "plain park survives unrelated finishes"),
-          "a parked plain task never resumes on other tasks' events")
-
-    print("== the deleted machinery refuses, verbatim ==")
-    status, body = saddle_api("POST", "/api/saddle/subtask", fake_token,
-                              {"parent_task_id": plain, "title": "ghost"})
-    check(status == 404,
-          "the /api/saddle/subtask callback route is gone (404)")
-    # The poll-era ingest channel went with it (arch 19): the whole
-    # /update surface 404s — subtask and plan verb arms included — and
-    # the verdict channel (/poll) with it.
-    conn = db()
-    plain_session = conn.execute(
-        "select id from sessions where task_id = ? and ended_at is null",
-        (plain,)).fetchone()[0]
-    conn.close()
-    status, body = saddle_api("POST", "/api/saddle/%d/update" % fake_id, fake_token,
-                              {"type": "subtask", "session_id": plain_session,
-                               "data": {"title": "Ghost child"}})
-    check(status == 404,
-          "the /update ingest surface is gone (404, the subtask arm with it)")
-    status, body = saddle_api("POST", "/api/saddle/%d/update" % fake_id, fake_token,
-                              {"type": "plan", "session_id": plain_session,
-                               "data": {"plan": "# nope"}})
-    check(status == 404,
-          "the task-level 'plan' update arm is gone with the channel (404)")
-    # The daemon's task CLI: no parent/plan members; goal context instead.
-    status, body = saddle_api("GET", "/api/saddle/task/%d" % plain, fake_token)
-    check(status == 200 and "plan" not in body.get("task", {})
-          and "parent_task_id" not in body.get("task", {})
-          and "goal_id" in body.get("task", {}),
-          "the task CLI detail drops parent/plan and carries goal_id")
-    status, body = saddle_api("GET", "/api/saddle/tasks?project_id=1", fake_token)
-    check(status == 200 and all("parent_task_id" not in t and "goal_id" in t
-                                for t in body.get("tasks", [])),
-          "the task CLI list drops parent_task_id and carries goal_id")
-    # Settle the parked plain task: nothing will resume it — cancel it.
-    act(auth, task_state(auth, plain)["cancel"], {})
-    check(wait_for(lambda: task_state(auth, plain)["status"] == "failed" or False,
-                   timeout=30, what="parked plain task cancelled") is not None,
-          "the parked plain task cancels (the human cleanup path)")
-
-    print("== the goal agent's task CLI in depth ==")
-    goal = create_goal_row({"project_id": "1", "title": "Sequencing goal",
-                            "brief": "Fan tasks out with the CLI.",
-                            "branch_name": "goal/sequence"})
-    fake.goal_script = [("plan", "# Plan\n\n1. Fan out")]
-    act(auth, goal_state(goal)["start"], {})
-    check(wait_for(lambda: goal_state(goal)["status"] == "plan_review" or False,
-                   timeout=60, what="sequencing goal plans") is not None,
-          "the sequencing goal reaches plan review")
-    fake.goal_script = [("suspend",)]
-    act(auth, goal_state(goal)["plan_pending_block"]["answer_action"],
-        {"answer": "Plan approved. Proceed with implementation."})
-    conn = db()
-    run_task = conn.execute(
-        "select id from tasks where goal_id = ? and kind = 'goal_run'",
-        (goal,)).fetchone()[0]
-    agent_session = conn.execute(
-        "select id from sessions where task_id = ? and ended_at is null",
-        (run_task,)).fetchone()[0]
-    conn.close()
-    check(wait_for(lambda: task_state(auth, run_task)["status"] == "suspended"
-                   or False, timeout=60, what="sequencing agent parks") is not None,
-          "the sequencing goal agent parks")
-
-    # Create with capabilities: attached until assignment (the hold
-    # keeps the task queued), mandate + mode stored, ephemeral branch.
-    status, body = saddle_api("POST", "/api/saddle/task/create", fake_token, {
-        "session_id": agent_session, "title": "Held worker",
-        "mandate": "Do the held work.", "mode": "review",
-        "capabilities": ["gpu"]})
-    check(status == 200 and body.get("ok") is True,
-          "task create with a capability tag succeeds")
-    held = int(body["task_id"])
-    detail = task_state(auth, held)
-    check(detail["status"] == "draft" and detail["mode"] == "review",
-          "the held worker drafts with its mode")
-    check([c["name"] for c in detail.get("capabilities", [])] == ["gpu"],
-          "the capability attaches to the created task")
-    check(detail["task_branch"] == "task/%d-%d" % (goal, held)
-          and detail["branch_from"] == "goal/sequence",
-          "the CLI task's ephemeral branch pair is stored")
-    status, body = saddle_api("POST", "/api/saddle/task/enqueue", fake_token, {
-        "session_id": agent_session, "task_id": held})
-    check(status == 200, "the held worker enqueues")
-    check(quiet_window(3, lambda: task_state(auth, held)["status"] == "queued",
-                       "unsatisfiable capability holds dispatch"),
-          "the unsatisfiable capability holds the queued worker (never assigned)")
-    queue_row = [t for t in slot_public(auth, "/tasks", "tasks")["tasks"]
-                 if int(t["id"]) == held][0]
-    check(queue_row.get("waiting_for_saddle") is True,
-          "the queue annotates the held worker as waiting for a saddle")
-
-    # The human edit path: goal tasks never carry enqueue-after (the
-    # field is human-tasks-only — the update silently ignores it).
-    act(auth, task_state(auth, held)["update"], {
-        "priority": "4", "enqueue_after_task_id": str(held - 1)})
-    check(task_state(auth, held).get("enqueue_after_task_id") in (None, 0, "0"),
-          "a goal task ignores the auto-enqueue-after field on edit")
-
-    # Ownership: the same saddle's goal agent cannot touch another
-    # goal's task; a plain session is not a goal-agent identity.
-    other_goal = create_goal_row({"project_id": "1", "title": "Other goal",
-                                  "brief": "b", "branch_name": "goal/other",
-                                  "priority": "9"})
-    status, body = saddle_api("POST", "/api/saddle/task/create", fake_token,
-                              {"session_id": agent_session, "title": "x",
-                               "mandate": "m"})
-    scope_task = int(body["task_id"])
-    check(int(task_state(auth, scope_task)["goal_id"] or 0) == goal,
-          "the callback scopes task creation to its own goal")
-    status, body = saddle_api("POST", "/api/saddle/task/delete", fake_token,
-                              {"session_id": agent_session, "task_id": scope_task})
-    check(status == 200, "the owned draft deletes")
-    check(not any(t["id"] == scope_task
-                  for t in slot_public(auth, "/tasks", "tasks")["tasks"]),
-          "the deleted task is gone from the queue")
-    status, body = saddle_api("POST", "/api/saddle/task/enqueue", fake_token,
-                              {"session_id": agent_session, "task_id": plain})
-    check(status == 400 and "does not belong to your goal" in (body.get("error") or ""),
-          "the goal agent cannot enqueue a standalone task")
-    # The daemon's task CLI detail carries the goal context.
-    status, body = saddle_api("GET", "/api/saddle/task/%d" % held, fake_token)
-    check(status == 200
-          and int(body["task"].get("goal_id") or 0) == goal
-          and body["task"].get("goal_title") == "Sequencing goal",
-          "the task CLI detail names the owning goal")
-
-    print("== the goal-run block answers from the task page (C1) ==")
-    # A question block raised in goal context lands on the run task's
-    # own row; the TASK page's answer action funnels into the one
-    # goal answer path and resumes the agent with the verdict riding
-    # the allocation (the goal page shares the path).
-    fake.goal_script = [("question", "Which harness: pytest or vitest?",
-                         ["pytest", "vitest"])]
-    conn = db()
-    # Plan 15 C3: a terminal transition (a done task row newer than
-    # the watermark) is the resume signal — no event rows exist.
-    conn.execute("insert into tasks (project_id, goal_id, kind, title, status,"
-                 " priority, completed_at, created_at) values (1, ?, 'task',"
-                 " 'Nudge', 'done', 5,"
-                 " strftime('%s','now'),"
-                 " strftime('%s','now','-30 seconds'))", (goal,))
-    conn.commit()
-    conn.close()
-    check(wait_for(lambda: task_state(auth, run_task)["status"] == "blocked"
-                   or False, timeout=60, what="goal block parks the run") is not None,
-          "a goal question parks the run task on its own block row")
-    run_detail = task_state(auth, run_task)
-    question_block = [b for b in run_detail["blocks"]
-                      if b["block_type"] == "question"][0]
-    check(question_block.get("question") == "Which harness: pytest or vitest?",
-          "the run task's block carries the goal question verbatim")
-    goal_block_ids = [int(b["id"]) for b in goal_state(goal)["blocks"]
-                      if b.get("block_type") == "question"]
-    check(goal_block_ids == [int(question_block["id"])],
-          "the goal page's card is the SAME row (no dual-row pair)")
-    act(auth, question_block["answer_action"], {"answer": "pytest"})
-    fake.goal_script = [("suspend",)]
-    check(wait_for(lambda: task_state(auth, run_task)["status"] == "suspended"
-                   or False, timeout=60, what="answered block resumes the agent")
-          is not None,
-          "the answered block resumes the goal agent")
-    answered = [b for b in task_state(auth, run_task)["blocks"]
-                if b["block_type"] == "question"][0]
-    check(answered.get("answer") == "pytest",
-          "the verdict is stored on the single block row")
-
-    print("== settle: release the hold and let the shard drain ==")
-    # Drop the hold tag so the held worker can dispatch and complete;
-    # the parked agent resumes on its completion, re-parks (script),
-    # and the shard shuts down with an empty queue.
-    act(auth, task_state(auth, held)["capabilities"][0]["detach"], {})
-    check(wait_task_done(auth, held, timeout=90) is not None,
-          "the released held worker completes")
-    check(wait_for(lambda: any(e["kind"] == "task-done" and int(e["task_id"]) == held
-                               for e in goal_state(goal)["events"]) or False,
-                   timeout=30, what="narrative hears the held worker") is not None,
-          "the narrative records the held worker's completion")
-    act(auth, goal_state(goal)["cancel"], {})
-    check(wait_for(lambda: goal_state(goal)["status"] == "cancelled" or False,
-                   timeout=30, what="sequencing goal cancelled") is not None,
-          "the sequencing goal cancels (the shard's cleanup path)")
-
-
-# =============================================================================
-# Bundle: lineage — the plan-12 goal lineage: goal context on worker
-# dispatches (read-only reference + ephemeral branch), the daemon's
-# task-reading API (goal members, no parent/plan), and the goal
-# agent's workspace affinity while parked.
-# =============================================================================
-
-def bundle_lineage(ctx):
-    auth, fake, fake_id, fake_token = ctx.auth, ctx.fake, ctx.fake_id, ctx.fake_token
-    app = ctx.app
-    r4_token = fake_token
-    # gpu exists only as a hold (no saddle carries it): the held goal
-    # worker stays queued until the release loop lifts it.
-    saddles_state = slot_public(auth, "/saddles", "saddles")
-    act(auth, saddles_state["create_capability"], {"name": "gpu"})
-
-    def goal_state(goal_id):
-        return slot_public(auth, "/goals/%d" % goal_id, "goal")
-
-    def create_goal_row(fields):
-        act(auth, slot_public(auth, "/goals", "goals")["create"], fields)
-        rows = [g for g in slot_public(auth, "/goals", "goals")["goals"]
-                if g["title"] == fields["title"]]
-        return int(rows[0]["id"])
-
-    goal = create_goal_row({"project_id": "1", "title": "Lineage goal",
-                            "brief": "Carry the goal lineage.",
-                            "branch_name": "goal/lineage"})
-    fake.goal_script = [("plan", "# Lineage plan\n\n1. Fan out\n2. Verify")]
-    act(auth, goal_state(goal)["start"], {})
-    check(wait_for(lambda: goal_state(goal)["status"] == "plan_review" or False,
-                   timeout=60, what="lineage goal plans") is not None,
-          "the lineage goal reaches plan review")
-    fake.goal_script = [("suspend",)]
-    act(auth, goal_state(goal)["plan_pending_block"]["answer_action"],
-        {"answer": "Plan approved. Proceed with implementation."})
-    conn = db()
-    auto_parent = conn.execute(
-        "select id from tasks where goal_id = ? and kind = 'goal_run'",
-        (goal,)).fetchone()[0]
-    agent_session = conn.execute(
-        "select id from sessions where task_id = ? and ended_at is null",
-        (auto_parent,)).fetchone()[0]
-    conn.close()
-    check(wait_for(lambda: task_state(auth, auto_parent)["status"] == "suspended"
-                   or False, timeout=60, what="lineage goal agent parks") is not None,
-          "the lineage goal agent parks")
-
-    # Two workers under the goal: one free, one held by the gpu tag.
-    status, body = saddle_api("POST", "/api/saddle/task/create", r4_token, {
-        "session_id": agent_session, "title": "Auto child",
-        "mandate": "build the widget", "mode": "implement"})
-    auto_child = int(body["task_id"])
-    status, body = saddle_api("POST", "/api/saddle/task/create", r4_token, {
-        "session_id": agent_session, "title": "Auto grandchild",
-        "mandate": "verify the widget", "mode": "test",
-        "capabilities": ["gpu"]})
-    auto_grand = int(body["task_id"])
-    status, body = saddle_api("POST", "/api/saddle/task/create", r4_token, {
-        "session_id": agent_session, "title": "Wire the flange",
-        "description": "torque to spec"})
-    check(status == 400 and "mandate is required" in (body.get("error") or ""),
-          "task create without a mandate errors verbatim (%s)" % body.get("error"))
-    status, body = saddle_api("POST", "/api/saddle/task/create", r4_token, {
-        "session_id": agent_session, "title": "Wire the flange",
-        "mandate": "torque to spec"})
-    flange_task = int(body["task_id"])
-    for held in (auto_child, auto_grand, flange_task):
-        saddle_api("POST", "/api/saddle/task/enqueue", r4_token,
-                   {"session_id": agent_session, "task_id": held})
-    check(wait_for(lambda: task_state(auth, auto_child)["status"] in
-                   ("queued", "assigned", "working", "done") or False,
-                   timeout=30, what="free goal worker dispatches") is not None,
-          "the free goal worker dispatches")
-    check(quiet_window(3, lambda: task_state(auth, auto_grand)["status"] == "queued",
-                       "held goal worker stays queued"),
-          "the gpu-held goal worker stays queued")
-
-    # A goal worker's dispatch carries the read-only goal context.
-    lineage_push = [p for p in fake.start_payloads
-                    if int(p.get("task", {}).get("id") or 0) == auto_child][-1]
-    goal_ctx = lineage_push.get("goal") or {}
-    check(int(goal_ctx.get("id") or 0) == goal
-          and goal_ctx.get("branch") == "goal/lineage"
-          and "Carry the goal lineage." in goal_ctx.get("brief", "")
-          and "# Lineage plan" in goal_ctx.get("plan", ""),
-          "the worker dispatch carries the goal context (brief + approved plan)")
-    check(lineage_push.get("ephemeral_branch") == "task/%d-%d" % (goal, auto_child)
-          and lineage_push.get("kind") == "task"
-          and lineage_push.get("mode") == "implement"
-          and lineage_push.get("creator") == "goal",
-          "the worker dispatch carries the ephemeral branch + identity triplet")
-    check("parent" not in lineage_push and "subtasks" not in lineage_push,
-          "the plan-12 payload drops the parent/subtasks members")
-
-    print("== R5 B2: task-reading API ==")
-    status, _ = saddle_api("GET", "/api/saddle/tasks", None)
-    check(status == 401, "tasks endpoint rejects a missing token")
-    status, _ = saddle_api("GET", "/api/saddle/task/%d" % auto_child, None)
-    check(status == 401, "task detail endpoint rejects a missing token")
-
-    # Fixture: a second project whose tasks all carry the "Diff " title
-    # prefix for the project_id filter checks — created first so the
-    # unfiltered list has the population the count check expects.
-    state = slot_public(auth, "/projects", "projects")
-    act(auth, state["create"], {"name": "diff-fabrica",
-                                "git_url": "ssh://fabrica.unitatem.net:222/clanker/clanker-saddle.git"})
-    conn = db()
-    other_project = int([p["id"] for p in slot_public(auth, "/projects", "projects")["projects"]
-                         if p["name"] == "diff-fabrica"][0])
-    for suffix in ("fabrica", "scp"):
-        conn.execute("insert into tasks (project_id, title, status, priority, created_at)"
-                     " values (?, ?, 'done', 5, strftime('%s','now'))",
-                     (other_project, "Diff %s" % suffix))
-    conn.commit()
-    conn.close()
-    status, body = saddle_api("GET", "/api/saddle/tasks", r4_token)
-    check(status == 200 and len(body.get("tasks", [])) > 5,
-          "tasks endpoint lists tasks without filters")
-    row = [t for t in body["tasks"] if int(t["id"]) == auto_child][0]
-    check(row["title"] == "Auto child" and int(row["goal_id"] or 0) == goal
-          and row["status"] in ("done", "queued", "working"),
-          "compact rows carry id/title/status/goal_id")
-
-    status, body = saddle_api("GET", "/api/saddle/tasks?project_id=1", r4_token)
-    check(all(True for _ in [1])  # project 1 dominates the data set
-          and not any(int(t["id"]) == 0 for t in body["tasks"]),
-          "project_id filter accepted")
-    status, body = saddle_api("GET",
-                              "/api/saddle/tasks?project_id=%d" % other_project, r4_token)
-    check(all(t["title"].startswith("Diff") for t in body["tasks"]),
-          "other project lists only its own tasks")
-
-    status, body = saddle_api("GET", "/api/saddle/tasks?q=FLANGE", r4_token)
-    titles = [t["title"] for t in body["tasks"]]
-    check("Wire the flange" in titles,
-          "q matches titles case-insensitively")
-    status, body = saddle_api("GET", "/api/saddle/tasks?q=torque%20to%20spec", r4_token)
-    check(any(t["title"] == "Wire the flange" for t in body["tasks"]),
-          "q matches mandate text")
-
-    status, body = saddle_api("GET", "/api/saddle/task/%d" % auto_child, r4_token)
-    task_view = body.get("task", {})
-    check(status == 200 and int(task_view.get("id") or 0) == auto_child
-          and task_view.get("goal_title") == "Lineage goal"
-          and int(task_view.get("goal_id") or 0) == goal,
-          "single-task view joins the goal title")
-    check("status" in task_view and "description" in task_view
-          and "summary" in task_view,
-          "single-task view carries the full detail fields")
-    check("plan" not in task_view and "parent_task_id" not in task_view,
-          "the single-task view drops the deleted parent/plan members")
-    status, body = saddle_api("GET", "/api/saddle/task/99999", r4_token)
-    check(status == 404, "unknown task id returns 404")
-
-    print("== settle: released workers resume the parked agent (coalesced) ==")
-    # Release the held workers: their completions wake the parked goal
-    # agent (affinity — the same fake hosts it) with the batched
-    # notice; the free worker already completed.
-    check(wait_task_done(auth, auto_child, timeout=90) is not None,
-          "the free worker settles first")
-
-    def agent_push_count():
-        return len([p for p in fake.goal_assignments
-                    if int(p.get("task", {}).get("id") or 0) == auto_parent])
-
-    before_pushes = agent_push_count()
-    for held_task in (auto_grand, flange_task):
-        caps = task_state(auth, held_task).get("capabilities") or []
-        if caps:
-            act(auth, caps[0]["detach"], {})
-        check(wait_task_done(auth, held_task, timeout=90) is not None,
-              "released worker settles (%d)" % held_task)
-    check(wait_for(lambda: agent_push_count() > before_pushes or False,
-                   timeout=90, what="goal agent resumes") is not None,
-          "the workers' completions resume the parked goal agent")
-    notice = ""
-    for p in fake.goal_assignments:
-        if int(p.get("task", {}).get("id") or 0) == auto_parent:
-            notice = p.get("resume_notice") or ""
-    check("Auto child" in notice and "Auto grandchild" in notice
-          and "Wire the flange" in notice,
-          "the coalesced resume notice covers every plan task")
-    check("New completion reports" in notice and "fake daemon finished" in notice,
-          "the notice carries the new completion reports")
-
-    act(auth, goal_state(goal)["cancel"], {})
-    check(wait_for(lambda: goal_state(goal)["status"] == "cancelled" or False,
-                   timeout=30, what="lineage goal cancelled") is not None,
-          "the lineage goal cancels (drain)")
-
-
-# =============================================================================
-# Bundle: allocation — the ask/wake/allocate machinery: concurrent ask
-# race, token revocation, workspace affinity, the lost-wake guard, the
-# slow-ask regression, assignment capability context + the tag
-# catalogue, and the pinned-blocks/activity dashboard.
-# =============================================================================
-
-def bundle_allocation(ctx):
-    auth, fake, fake_id, fake_token = ctx.auth, ctx.fake, ctx.fake_id, ctx.fake_token
-    app = ctx.app
-    r4_token = fake_token
-    # gpu rides the primary fake from the start (the routing bundle's
-    # early attach, replayed): its attach row precedes lostwake's, so
-    # the assignment's saddle_tags order matches the assertion in the
-    # capability-context section below.
-    saddles_state = slot_public(auth, "/saddles", "saddles")
-    act(auth, saddles_state["create_capability"], {"name": "gpu"})
-    act(auth, saddle_card(auth, "fake-saddle")["attach_capability"],
-        {"capability_id": str(int([c["id"] for c in
-                                   slot_public(auth, "/saddles", "saddles")["capabilities"]
-                                   if c["name"] == "gpu"][0]))})
-
-    print("== phase 1: ask/allocation — token auth + concurrent race ==")
-    # Plan 10 phase 1. Registration mints per-saddle tokens; the
-    # ask endpoint authenticates by them; concurrent asks race to
-    # exactly one winner through the allocation transaction.
-    status, _ = saddle_api("POST", "/api/saddle/next-task", None)
-    check(status == 401, "next-task rejects a missing token")
-    status, _ = saddle_api("POST", "/api/saddle/next-task", "saddle-bogus-token")
-    check(status == 401, "next-task rejects a wrong token")
-    status, body = saddle_api("POST", "/api/saddle/next-task", fake_token)
-    check(status == 204, "next-task answers 204 (nothing offerable — daemon sleeps)")
-
-    # Two more racers: real daemons on their own ports; fake2 reports
-    # its ssh key at /register so the key lands on the row directly.
-    fake2 = FakeSaddle()
-    fake2.ssh_public_key = "ssh-ed25519 AAAAFake2RacerKey saddle-2@fedora"
-    fake2.serve(port=free_port())
-    fake3 = FakeSaddle()
-    fake3.serve(port=free_port())
-    saddles_state = slot_public(auth, "/saddles", "saddles")
-    act(auth, saddles_state["register"], {"name": "racer-two",
-                                          "host": "127.0.0.1:%d" % fake2.port})
-    act(auth, saddles_state["register"], {"name": "racer-three",
-                                          "host": "127.0.0.1:%d" % fake3.port})
-    check(wait_for(lambda: len(fake2.register_log) > 0 and len(fake3.register_log) > 0
-                   or False, timeout=15, what="racers registered") is not None,
-          "both racers received /register")
-    check(wait_for(lambda: "AAAAFake2RacerKey" in
-                   [s for s in slot_public(auth, "/saddles", "saddles")["saddles"]
-                    if s["name"] == "racer-two"][0].get("ssh_public_key", "") or False,
-                   timeout=15, what="register-reported key") is not None,
-          "the ssh key reported at /register lands on the saddle row")
-
-    racer_cards = {}
-    for name, daemon in (("fake-saddle", fake), ("racer-two", fake2), ("racer-three", fake3)):
-        card = [s for s in slot_public(auth, "/saddles", "saddles")["saddles"]
-                if s["name"] == name][0]
-        racer_cards[daemon] = {"id": int(card["id"]), "token": card["token"]}
-    # Revocation: a registered saddle's token works until the saddle
-    # is removed, then nothing authorises its calls.
-    fake4 = FakeSaddle()
-    fake4.ask_on_register = False  # a pre-flip daemon: never asks
-    fake4.serve(port=free_port())
-    saddles_state = slot_public(auth, "/saddles", "saddles")
-    act(auth, saddles_state["register"], {"name": "old-daemon",
-                                          "host": "127.0.0.1:%d" % fake4.port})
-    old_card = [s for s in slot_public(auth, "/saddles", "saddles")["saddles"]
-                if s["name"] == "old-daemon"][0]
-    status, _ = saddle_api("POST", "/api/saddle/next-task", old_card["token"])
-    check(status in (200, 204),
-          "the old daemon's fresh token authenticates next-task")
-    status, _ = saddle_api("POST", "/api/saddle/note", old_card["token"],
-                           {"project": "demo", "body": "from the old daemon"})
-    check(status == 200, "note accepts any registered saddle's token")
-    act(auth, old_card["unregister"], {})
-    status, _ = saddle_api("POST", "/api/saddle/next-task", old_card["token"])
-    check(status == 401, "removing the saddle revokes its token")
-    status, _ = saddle_api("POST", "/api/saddle/note", old_card["token"],
-                           {"project": "demo", "body": "should fail"})
-    check(status == 401, "revocation covers the note endpoint too")
-
-    # Deterministic race: settle the queue first (this shard runs the
-    # race before any parked work exists, so only in-flight asks need
-    # draining), freeze every daemon's self-ask triggers, put all three
-    # to sleep (204), then fire one task worth of concurrent asks.
-    for daemon in (fake, fake2, fake3):
-        daemon.ask_on_register = False
-        daemon.ask_on_wake = False
-        daemon.ask_on_terminal = False
-        daemon.ask_on_idle_status = False
-        daemon.settle_asks()  # converted sleep: in-flight asks land (204)
-    def queued_count():
-        conn = db()
-        try:
-            return conn.execute(
-                "select count(*) from tasks where status = 'queued'").fetchone()[0]
-        finally:
-            conn.close()
-
-    check(wait_for(lambda: queued_count() == 0 or False,
-                   timeout=60, what="queue settles before the race") is not None,
-          "the queue settles before the race")
-
-    sleep_statuses = [daemon.ask_now()[0] for daemon in (fake, fake2, fake3)]
-    check(sleep_statuses == [204, 204, 204],
-          "all three racers sleep (204) before the task exists")
-
-    task_id_tmp = create_queued(auth, {
-        "project_id": "1",
-        "title": "Race task",
-        "priority": "2",
-    })
-    race_task = task_id_tmp
-
-    race_results = []
-    def race_ask(daemon):
-        # A real racing daemon accepts the assignment it wins — the
-        # manual ask path does exactly that on a 200.
-        race_results.append(daemon.ask_now())
-    threads = [threading.Thread(target=race_ask, args=(daemon,))
-               for daemon in (fake, fake2, fake3)]
-    for thread in threads:
-        thread.start()
-    for thread in threads:
-        thread.join()
-    race_statuses = sorted(r[0] for r in race_results)
-    check(race_statuses == [200, 204, 204],
-          "concurrent asks race to exactly one winner (%s)" % race_statuses)
-    winner = [r for r in race_results if r[0] == 200][0][1]
-    check(int(winner["task"]["id"]) == race_task, "the winner's payload carries the task")
-    check(int(winner["session_id"]) > 0, "the assignment carries the session id")
-    conn = db()
-    race_sessions = conn.execute(
-        "select count(*) from sessions where task_id = ?", (race_task,)).fetchone()[0]
-    conn.close()
-    check(race_sessions == 1,
-          "exactly one session row — the transaction serialised the claims (%d)"
-          % race_sessions)
-    check(wait_task_done(auth, race_task, timeout=60) is not None,
-          "the raced task completes on the winning daemon")
-    for daemon in (fake, fake2, fake3):
-        daemon.ask_on_register = True
-        daemon.ask_on_wake = True
-        daemon.ask_on_terminal = True
-        daemon.ask_on_idle_status = True
-    # Re-establish sleeping explicitly: the winner's post-race
-    # re-ask timing is not deterministic, and the affinity section
-    # below needs every racer provably asleep. Any stray offerable
-    # drains into these asks first.
-    def all_asleep():
-        return all(daemon.ask_now()[0] == 204 for daemon in (fake, fake2, fake3))
-    check(wait_for(lambda: all_asleep() or False, timeout=30,
-                   what="racers re-sleep after the race") is not None,
-          "all racers re-sleep after the race")
-
-    print("== phase 1: workspace affinity pins parked tasks ==")
-    # A suspended parent parked on racer-two may be resumed ONLY by
-    # racer-two: a tag-capable non-affine saddle asking gets 204, and
-    # the wake targets the affine saddle. Only racer-two carries the
-    # tag at dispatch time (the race's winner is nondeterministic, so
-    # the park must not depend on which racers are free); racer-three
-    # gains it afterwards to prove the pinning is by workspace, not
-    # tags.
-    saddles_state = slot_public(auth, "/saddles", "saddles")
-    act(auth, saddles_state["create_capability"], {"name": "affinity-tag"})
-    affinity_cap = int([c["id"] for c in slot_public(auth, "/saddles", "saddles")["capabilities"]
-                        if c["name"] == "affinity-tag"][0])
-    racer2_card = [s for s in slot_public(auth, "/saddles", "saddles")["saddles"]
-                   if s["name"] == "racer-two"][0]
-    racer3_card = [s for s in slot_public(auth, "/saddles", "saddles")["saddles"]
-                   if s["name"] == "racer-three"][0]
-    act(auth, racer2_card["attach_capability"], {"capability_id": str(affinity_cap)})
-
-    # Plan 12: the parked workspace is the goal agent's run task. The
-    # other racers sleep (frozen ask triggers), so racer-two claims
-    # the goal run and parks it; the goal-task event then resumes the
-    # agent AFFINE to racer-two — racer-three (tag-capable or not)
-    # gets 204, the dispatcher's wake targets racer-two.
-    fake.ask_on_wake = False
-    fake.ask_on_idle_status = False
-    fake.settle_asks()
-    fake3.ask_on_wake = False
-    fake3.ask_on_idle_status = False
-    fake3.settle_asks()
-
-    act(auth, slot_public(auth, "/goals", "goals")["create"], {
-        "project_id": "1", "title": "Affinity goal",
-        "brief": "Parks on racer-two.", "branch_name": "goal/affinity"})
-    conn = db()
-    affinity_goal = conn.execute(
-        "select id from goals where title = 'Affinity goal'").fetchone()[0]
-    conn.close()
-    fake2.goal_script = [("plan", "# Affinity plan\n\n1. Park")]
-    act(auth, slot_public(auth, "/goals/%d" % affinity_goal, "goal")["start"], {})
-    check(wait_for(lambda: slot_public(auth, "/goals/%d" % affinity_goal,
-                                       "goal")["status"] == "plan_review" or False,
-                   timeout=60, what="affinity goal plans") is not None,
-          "the affinity goal reaches plan review (racer-two hosting)")
-    fake2.goal_script = [("suspend",)]
-    # Freeze racer-two's ask triggers across the approval too (the
-    # later wake measurement already does): the mirror-sync fix makes
-    # the run resume-offerable the moment its goal row carries the
-    # verdict, so a wake-triggered background ask would race this
-    # manual ask_now for the claim.
-    fake2.ask_on_wake = False
-    fake2.ask_on_idle_status = False
-    fake2.settle_asks()
-    act(auth, slot_public(auth, "/goals/%d" % affinity_goal, "goal")
-        ["plan_pending_block"]["answer_action"],
-        {"answer": "Plan approved. Proceed with implementation."})
-    conn = db()
-    affinity_parent = conn.execute(
-        "select id from tasks where goal_id = ? and kind = 'goal_run'",
-        (affinity_goal,)).fetchone()[0]
-    agent_session = conn.execute(
-        "select id from sessions where task_id = ? and ended_at is null",
-        (affinity_parent,)).fetchone()[0]
-    conn.close()
-    status, resume_payload = fake2.ask_now()
-    check(status == 200 and int(resume_payload["task"]["id"]) == affinity_parent,
-          "the approved plan resumes the agent on racer-two (its workspace)")
-    check(wait_for(lambda: task_state(auth, affinity_parent).get("status") == "suspended"
-                   or False, timeout=60, what="affinity agent parks") is not None,
-          "the affinity goal agent parks on racer-two")
-    conn = db()
-    affinity_session = conn.execute(
-        "select saddle_id from sessions where task_id = ? and ended_at is null",
-        (affinity_parent,)).fetchone()[0]
-    conn.close()
-    check(affinity_session == int(racer2_card["id"]),
-          "the parked workspace sits on racer-two")
-
-    # Now racer-three carries the tag too — the pinning is by
-    # workspace, not tags. With nothing due, a non-affine ask gets 204.
-    act(auth, racer3_card["attach_capability"], {"capability_id": str(affinity_cap)})
-    status, _ = fake3.ask_now()
-    check(status == 204,
-          "a tag-capable non-affine saddle is refused the parked agent (204)")
-
-    # A goal task completing makes the parked agent resume-offerable —
-    # affine to racer-two only. The other racers wake back up (they
-    # host the worker; their claims of the parked agent get refused as
-    # non-affine), while racer-two's ask triggers stay frozen so the
-    # wake measurement stays clean. A wake may have hit the frozen
-    # racers while the goal run queued (the lost-wake guard marks them
-    # offline): the refresh probe brings them back before the worker.
-    fake.ask_on_wake = True
-    fake.ask_on_idle_status = True
-    fake3.ask_on_wake = True
-    fake3.ask_on_idle_status = True
-    for racer_name in ("fake-saddle", "racer-three"):
-        act(auth, saddle_card(auth, racer_name)["refresh"], {})
-        check(wait_for(lambda name=racer_name: [s for s in
-                                                slot_public(auth, "/saddles", "saddles")["saddles"]
-                                                if s["name"] == name][0]["status"] == "idle"
-                       or False, timeout=15, what="racer re-onlined") is not None,
-              "%s re-onlined after its frozen-window wake" % racer_name)
-    fake2.ask_on_wake = False
-    fake2.ask_on_idle_status = False
-    wakes_before_2 = len(fake2.wake_log)
-    fake2.settle_asks()  # converted sleep: park-time ask lands (204)
-    status, body = saddle_api("POST", "/api/saddle/task/create", fake2.token, {
-        "session_id": agent_session, "title": "Affinity child",
-        "mandate": "finish the affinity fixture"})
-    check(status == 200, "the parked agent fans its worker out via the CLI")
-    affinity_child = int(body["task_id"])
-    saddle_api("POST", "/api/saddle/task/enqueue", fake2.token,
-               {"session_id": agent_session, "task_id": affinity_child})
-    check(wait_task_done(auth, affinity_child, timeout=90) is not None,
-          "the affinity worker completes (on a non-affine racer)")
-
-    check(wait_for(lambda: len(fake2.wake_log) > wakes_before_2 or False,
-                   timeout=90, what="affine wake") is not None,
-          "the dispatcher's wake targets the affine saddle")
-    status, resume_payload = fake2.ask_now()
-    fake2.ask_on_wake = True       # restored whatever the claim returned
-    fake2.ask_on_idle_status = True
-    check(status == 200 and int(resume_payload["task"]["id"]) == affinity_parent,
-          "the affine saddle's ask claims the parked agent")
-    check("Affinity child" in (resume_payload.get("resume_notice") or "")
-          and "fake daemon finished" in (resume_payload.get("resume_notice") or ""),
-          "the resume assignment carries the goal's batched report notice")
-    check(wait_for(lambda: task_state(auth, affinity_parent).get("status")
-                   == "suspended" or False,
-                   timeout=60, what="affinity agent re-parks") is not None,
-          "the resumed agent re-parks (script)")
-    act(auth, slot_public(auth, "/goals/%d" % affinity_goal, "goal")["cancel"], {})
-    check(wait_for(lambda: slot_public(auth, "/goals/%d" % affinity_goal,
-                                       "goal")["status"] == "cancelled" or False,
-                   timeout=30, what="affinity goal cancelled") is not None,
-          "the affinity goal cancels (drain)")
-
-    print("== phase 1: lost wake -> offline + re-wake of the next capable ==")
-    # racer-three sleeps through wakes (a daemon that died after its
-    # last 204): the guard window (SADDLE_LOST_WAKE_S=2) passes with
-    # no ask, the saddle goes offline, and the work moves to the
-    # next capable sleeping saddle.
-    fake3.ask_on_wake = False
-    fake3.ask_on_idle_status = False  # sleeps through everything
-    saddles_state = slot_public(auth, "/saddles", "saddles")
-    act(auth, saddles_state["create_capability"], {"name": "lostwake"})
-    lostwake_cap = int([c["id"] for c in slot_public(auth, "/saddles", "saddles")["capabilities"]
-                        if c["name"] == "lostwake"][0])
-    racer3_card = [s for s in slot_public(auth, "/saddles", "saddles")["saddles"]
-                   if s["name"] == "racer-three"][0]
-    act(auth, racer3_card["attach_capability"], {"capability_id": str(lostwake_cap)})
-    # Racer-three must be asleep to be woken: park it with a manual
-    # 204 ask (nothing offerable for it — the task below is not
-    # created yet).
-    status, _ = fake3.ask_now()
-    check(status == 204, "racer-three sleeps before the lost-wake run")
-
-    task_id_tmp = create_queued(auth, {
-        "project_id": "1",
-        "title": "Lost wake task",
-        "priority": "2",
-        "capability_id": [str(lostwake_cap)],
-    })
-    lost_task = task_id_tmp
-    check(wait_for(lambda: len(fake3.wake_log) > 0 or False,
-                   timeout=30, what="wake sent to racer-three") is not None,
-          "the only capable sleeping saddle is woken")
-    check(wait_for(lambda: [s for s in slot_public(auth, "/saddles", "saddles")["saddles"]
-                            if s["name"] == "racer-three"][0]["status"] == "offline"
-                   or False, timeout=30, what="lost-wake -> offline") is not None,
-          "no ask after the wake: the saddle goes offline (lost-wake guard)")
-    check(task_state(auth, lost_task)["status"] == "queued",
-          "the task is untouched while its wake was pending")
-
-    # Re-wake the next capable: the healthy saddle gains the tag and
-    # picks the work up via its own wake -> ask -> allocate roundtrip.
-    fake_card = saddle_card(auth, "fake-saddle")
-    act(auth, fake_card["attach_capability"], {"capability_id": str(lostwake_cap)})
-    wakes_before = len(fake.wake_log)
-    check(wait_for(lambda: len(fake.wake_log) > wakes_before or False,
-                   timeout=30, what="re-wake of the next capable") is not None,
-          "the next capable sleeping saddle is woken for the task")
-    check(wait_task_done(auth, lost_task, timeout=60) is not None,
-          "wake -> ask -> allocate: the task completes on the healthy saddle")
-    check(wait_for(lambda: any(int(p.get("task", {}).get("id") or 0) == lost_task
-                               for p in fake.start_payloads) or False,
-                   timeout=10, what="lost task assignment captured") is not None,
-          "the re-woken saddle's ask produced the assignment")
-    fake3.ask_on_wake = True
-    fake3.ask_on_idle_status = True
-
-    print("== phase 3: capability context, catalogue, subtask tags ==")
-    # Assignment capability context (plan 10 phase 3): every
-    # assignment carries {saddle_tags: the allocated saddle's tags,
-    # fleet_tags: every tag name known across the fleet} — the
-    # daemon renders it into its system prompt. fake-saddle carries
-    # gpu + lostwake; the catalogue is affinity-tag, gpu, lostwake.
-    fake2.ask_on_register = False
-    fake2.ask_on_wake = False
-    fake2.ask_on_terminal = False
-    fake2.ask_on_idle_status = False
-    fake2.settle_asks()  # converted sleep: in-flight trigger asks land
-    task_id_tmp = create_queued(auth, {
-        "project_id": "1",
-        "title": "Capabilities context",
-        "priority": "2",
-    })
-    cap_task = task_id_tmp
-    check(wait_for(lambda: any(int(p.get("task", {}).get("id") or 0) == cap_task
-                               for p in fake.start_payloads) or False,
-                   timeout=60, what="capabilities-context task dispatched") is not None,
-          "the capabilities-context task dispatches")
-    cap_payload = [p for p in fake.start_payloads
-                   if int(p.get("task", {}).get("id") or 0) == cap_task][-1]
-    context = cap_payload.get("capabilities") or {}
-    check(context.get("saddle_tags") == ["gpu", "lostwake"],
-          "assignment saddle_tags = the allocated saddle's tags (%s)"
-          % context.get("saddle_tags"))
-    check(context.get("fleet_tags") == ["affinity-tag", "gpu", "lostwake"],
-          "assignment fleet_tags = every tag name known across the fleet (%s)"
-          % context.get("fleet_tags"))
-    check(wait_task_done(auth, cap_task, timeout=60) is not None,
-          "capabilities-context task completes")
-
-    # GET /api/saddle/capabilities feeds the daemon's `saddle
-    # capabilities` CLI: per-saddle-token auth, tag order by name,
-    # each tag with the saddles carrying it (name order).
-    status, _ = saddle_api("GET", "/api/saddle/capabilities", None)
-    check(status == 401, "capabilities endpoint rejects a missing token")
-    status, body = saddle_api("GET", "/api/saddle/capabilities", "saddle-bogus")
-    check(status == 401, "capabilities endpoint rejects a wrong token")
-    status, body = saddle_api("GET", "/api/saddle/capabilities", fake_token)
-    catalogue = {t["name"]: t["saddles"] for t in body.get("tags", [])}
-    check(status == 200 and body.get("ok") is True
-          and [t["name"] for t in body.get("tags", [])]
-          == ["affinity-tag", "gpu", "lostwake"],
-          "catalogue lists every tag by name")
-    check(catalogue.get("gpu") == ["fake-saddle"]
-          and catalogue.get("affinity-tag") == ["racer-three", "racer-two"]
-          and catalogue.get("lostwake") == ["fake-saddle", "racer-three"],
-          "each tag names its carrying saddles in name order (%s)" % catalogue)
-
-    # Task CLI capabilities (`task create --capability`): validated
-    # against the operator tag set; unknown tags reject with the valid
-    # list in the error (the agent reads it verbatim in the CLI
-    # output). A goal agent's parked session hosts the calls.
-    fake.suspend_on_title = "Tag host"
-    tag_host = create_queued(auth, {
-        "project_id": "1", "title": "Tag host", "priority": "3"})
-    check(wait_for(lambda: task_state(auth, tag_host)["status"] == "suspended"
-                   or False, timeout=60, what="tag host parks") is not None,
-          "a parked plain task hosts nothing (no goal scope)")
-    # The goal callbacks need a real goal agent: reuse the sequencing
-    # goal pattern — a fresh parked agent under this shard.
-    act(auth, slot_public(auth, "/goals", "goals")["create"], {
-        "project_id": "1", "title": "Tag goal", "brief": "b",
-        "branch_name": "goal/tags"})
-    conn = db()
-    tag_goal = conn.execute("select id from goals where title = 'Tag goal'").fetchone()[0]
-    conn.close()
-    fake.goal_script = [("suspend",)]
-    act(auth, slot_public(auth, "/goals/%d" % tag_goal, "goal")["start"], {})
-    conn = db()
-    tag_run = conn.execute(
-        "select id from tasks where goal_id = ? and kind = 'goal_run'",
-        (tag_goal,)).fetchone()[0]
-    conn.close()
-    check(wait_for(lambda: task_state(auth, tag_run)["status"] == "suspended"
-                   or False, timeout=60, what="tag goal agent parks") is not None,
-          "the tag goal agent parks")
-    conn = db()
-    tag_session = conn.execute(
-        "select id from sessions where task_id = ? and ended_at is null",
-        (tag_run,)).fetchone()[0]
-    conn.close()
-    conn = db()
-    tag_host_saddle = conn.execute(
-        "select saddle_id from sessions where id = ?", (tag_session,)).fetchone()[0]
-    conn.close()
-    racer2_card_id = int([c for c in slot_public(auth, "/saddles", "saddles")["saddles"]
-                          if c["name"] == "racer-two"][0]["id"])
-    racer3_card_id = int([c for c in slot_public(auth, "/saddles", "saddles")["saddles"]
-                          if c["name"] == "racer-three"][0]["id"])
-    host_daemon = {int(fake_id): fake, racer2_card_id: fake2,
-                   racer3_card_id: fake3}[int(tag_host_saddle)]
-    status, body = saddle_api("POST", "/api/saddle/task/create", host_daemon.token, {
-        "session_id": tag_session, "title": "Bad tag worker",
-        "mandate": "m", "capabilities": ["gpu", "warp-drive"]})
-    check(status == 400, "an unknown capability tag rejects the task call")
-    error_text = body.get("error", "")
-    check("warp-drive" in error_text and "valid tags" in error_text
-          and "gpu" in error_text and "lostwake" in error_text,
-          "the rejection names the unknown tag and the valid list (%s)" % error_text)
-    status, _ = saddle_api("POST", "/api/saddle/task/create", host_daemon.token, {
-        "session_id": tag_session, "title": "Bad shape worker",
-        "mandate": "m", "capabilities": "gpu"})
-    check(status == 400, "a non-array capabilities member rejects")
-
-    # A valid tag creates the goal worker in draft with exactly the
-    # explicit tag attached; the goal agent enqueues it.
-    status, body = saddle_api("POST", "/api/saddle/task/create", host_daemon.token, {
-        "session_id": tag_session, "title": "Explicit tag worker",
-        "mandate": "do the tagged work", "capabilities": ["gpu"]})
-    check(status == 200 and body.get("ok") is True,
-          "a valid tag creates the task synchronously")
-    tagged_worker = int(body["task_id"])
-    detail = task_state(auth, tagged_worker)
-    check([c["name"] for c in detail.get("capabilities", [])] == ["gpu"],
-          "the worker carries exactly the explicit tag")
-    conn = db()
-    tag_rows = conn.execute(
-        "select c.name from task_capabilities tc"
-        " join capabilities c on c.id = tc.capability_id"
-        " where tc.task_id = ?", (tagged_worker,)).fetchall()
-    conn.close()
-    check([r[0] for r in tag_rows] == ["gpu"],
-          "the task_capabilities rows record the explicit tag")
-    check(detail["status"] == "draft",
-          "the callback's task lands in draft until its agent enqueues")
-    saddle_api("POST", "/api/saddle/task/enqueue", host_daemon.token,
-               {"session_id": tag_session, "task_id": tagged_worker})
-    check(wait_task_done(auth, tagged_worker, timeout=90) is not None,
-          "the tagged worker dispatches and completes")
-    act(auth, slot_public(auth, "/goals/%d" % tag_goal, "goal")["cancel"], {})
-    act(auth, task_state(auth, tag_host)["cancel"], {})
-
-    print("== phase 3: dashboard — pinned blocks + activity timeline ==")
-    # Pinned OPEN blocking items as link-through cards, newest
-    # first; no inline answer forms (the card links to the task
-    # page). Fixture: one open question + one open review raised on a
-    # local task (stand-ins for the auto-approve grandchild's
-    # leftovers) join the probe RFC raised below.
-    conn = db()
-    conn.execute("insert into tasks (project_id, title, status, priority, created_at)"
-                 " values (1, 'Dash fixture task', 'working', 5, strftime('%s','now'))")
-    dash_task = conn.execute("select max(id) from tasks").fetchone()[0]
-    conn.execute("insert into sessions (task_id, saddle_id, started_at)"
-                 " values (?, ?, strftime('%s','now'))", (dash_task, fake_id))
-    dash_session = conn.execute("select max(id) from sessions").fetchone()[0]
-    conn.commit()
-    conn.close()
-    def raise_on_dash(question, kind="question", body=None, summary=None):
-        """Push-era raises on the dashboard fixture task (the poll-era
-        /update channel is gone): a blocked results push carries the
-        block payload; a review verb rides a review entry."""
-        if kind == "review" and summary is not None:
-            return saddle_api("POST", "/api/saddle/results", fake_token, {
-                "session_id": dash_session, "state": "working",
-                "entries": [{"id": 9317,
-                             "command": "saddle review",
-                             "output": summary, "type": "review",
-                             "timestamp": time.strftime(
-                                 "%Y-%m-%dT%H:%M:%SZ", time.gmtime())}]})[0]
-        block = {"question": question, "type": kind}
-        if body is not None:
-            block["body"] = body
-        return saddle_api("POST", "/api/saddle/results", fake_token, {
-            "session_id": dash_session, "state": "blocked",
-            "block": block})[0]
-
-    raise_on_dash("Dash fixture question?", kind="question")
-    raise_on_dash("dash fixture review", kind="review", summary="dash fixture review")
-
-    # The activity timeline: last <= 50 events, newest first, fed
-    # from the existing tables. Fixture rows a few seconds old
-    # guarantee the progress kind and a human-authored comment ride
-    # along; the probe block below proves same-source ordering.
-    conn = db()
-    conn.execute("insert into task_comments (task_id, author, body, created_at)"
-                 " values (?, 'user:admin', 'timeline fixture comment by a human',"
-                 " strftime('%s','now','-5 seconds'))", (cap_task,))
-    conn.execute("insert into task_progress (task_id, summary, created_at)"
-                 " values (?, 'timeline fixture progress',"
-                 " strftime('%s','now','-5 seconds'))",
-                 (cap_task,))
-    conn.commit()
-    conn.close()
-    # The probe RFC raised last: the newest pinned card and the newest
-    # timeline event (its raise+answer below prove same-source ordering
-    # both ways). The timeline sorts same-second events by source
-    # materialisation order, so the probe must land in a LATER clock
-    # second than the fixtures — wait for the boundary (bounded).
-    fixtures_epoch = int(time.time())
-    wait_for(lambda: int(time.time()) > fixtures_epoch or False,
-             timeout=3, what="next clock second before the probe raise")
-    raise_on_dash("Timeline probe: approve the dashboard flow",
-                  kind="rfc", body="# Probe")
-    dash = slot_public(auth, "/", "dashboard")
-    pinned = dash.get("pinned", [])
-    pinned_ids = [int(b["id"]) for b in pinned]
-    check(len(pinned_ids) >= 3 and pinned_ids == sorted(pinned_ids, reverse=True),
-          "pinned open blocks order newest-first (%s)" % pinned_ids)
-    check({b["block_type"] for b in pinned} >= {"question", "rfc", "review"},
-          "pinned cards cover questions, RFCs and reviews")
-    check(all(b["question"] and b["task_title"] and int(b["task_id"]) > 0
-              for b in pinned)
-          and all("answer_action" not in b for b in pinned),
-          "pinned cards are link-through only (task title, kind badge, question)")
-    activity = dash.get("activity", [])
-    epochs = [int(e["at_epoch"]) for e in activity]
-    check(0 < len(activity) <= 50 and epochs == sorted(epochs, reverse=True),
-          "the timeline shows the last <=50 events newest-first (%d events)"
-          % len(activity))
-    kinds = {e["kind"] for e in activity}
-    check({"created", "started", "dispatch", "comment", "progress", "completed"} <= kinds,
-          "the timeline covers status changes, dispatches, comments, progress and"
-          " completions (%s)" % sorted(kinds))
-    check(any(e["kind"] == "comment" and e["text"].startswith("user:admin:")
-              and "fixture comment" in e["text"] for e in activity),
-          "comment events carry author + snippet")
-
-    # The freshly raised probe pinned as the newest card and landed
-    # atop the timeline as block-raised; answering it records
-    # block-answered.
-    check(dash["pinned"][0]["question"] == "Timeline probe: approve the dashboard flow"
-          and int(dash["pinned"][0]["task_id"]) == dash_task,
-          "the freshest open block pins as the first card")
-    check(dash["activity"][0]["kind"] == "block-raised"
-          and "Timeline probe" in dash["activity"][0]["text"],
-          "the raised block lands atop the timeline")
-    probe_block = [b for b in task_state(auth, dash_task)["blocks"]
-                   if b["question"] == "Timeline probe: approve the dashboard flow"][0]
-    act(auth, probe_block["answer_action"], {"answer": "Ship the dashboard"})
-    dash = slot_public(auth, "/", "dashboard")
-    activity = dash.get("activity", [])
-    raised_at = next((i for i, e in enumerate(activity)
-                      if e["kind"] == "block-raised" and "Timeline probe" in e["text"]), -1)
-    answered_at = next((i for i, e in enumerate(activity)
-                        if e["kind"] == "block-answered"
-                        and "Ship the dashboard" in e["text"]), -1)
-    check(answered_at >= 0 and raised_at >= 0 and answered_at < raised_at,
-          "the answered event sorts above its raised event (newest-first, same source)")
-    check(all(b["question"] != "Timeline probe: approve the dashboard flow"
-              for b in dash["pinned"]),
-          "the answered block leaves the pinned cards")
-
-    print("== phase 3 regression: a slow ask after a wake is never dropped ==")
-    # The daemon worker's lost-wake-guard regression: a saddle whose
-    # ask arrives SLOWLY after the wake (busy winding down when the
-    # wake lands) must not lose the wake — the delayed ask (inside
-    # the guard window) claims the task, no re-wake storm fires
-    # while it is pending, and the saddle stays healthy. The
-    # never-asks path (guard -> offline + re-wake of the next
-    # capable) is proven by the racer-three section above.
-    check(wait_for(lambda: queued_count() == 0 or False,
-                   timeout=60, what="queue settles before the slow-wake run") is not None,
-          "the queue settles before the slow-wake run")
-    status, _ = fake2.ask_now()
-    check(status == 204, "the slow-ask racer sleeps before its wake")
-    saddles_state = slot_public(auth, "/saddles", "saddles")
-    act(auth, saddles_state["create_capability"], {"name": "slowwake"})
-    slowwake_cap = int([c["id"] for c in slot_public(auth, "/saddles", "saddles")
-                        ["capabilities"] if c["name"] == "slowwake"][0])
-    racer2_card = [s for s in slot_public(auth, "/saddles", "saddles")["saddles"]
-                   if s["name"] == "racer-two"][0]
-    act(auth, racer2_card["attach_capability"], {"capability_id": str(slowwake_cap)})
-    fake2.ask_delay = 1.2   # slow: asks well after the wake, inside the 2s guard
-    fake2.ask_on_wake = True
-    wakes_before_slow = len(fake2.wake_log)
-    task_id_tmp = create_queued(auth, {
-        "project_id": "1",
-        "title": "Slow wake task",
-        "priority": "2",
-        "capability_id": [str(slowwake_cap)],
-    })
-    slow_task = task_id_tmp
-    check(wait_for(lambda: len(fake2.wake_log) > wakes_before_slow or False,
-                   timeout=30, what="the slow-ask racer woken") is not None,
-          "the only capable sleeping saddle is woken")
-    check(wait_task_done(auth, slow_task, timeout=120) is not None,
-          "the delayed ask claims the task — the wake was not dropped")
-    check(any(a.get("status") == 200
-              and int((a.get("payload") or {}).get("task", {}).get("id") or 0)
-              == slow_task for a in fake2.asks),
-          "the slow ask's 200 carries the task")
-    check(len(fake2.wake_log) == wakes_before_slow + 1,
-          "the pending-wake skip re-wakes nobody while the slow ask is in flight")
-    racer2_card = [s for s in slot_public(auth, "/saddles", "saddles")["saddles"]
-                   if s["name"] == "racer-two"][0]
-    check(racer2_card["status"] in ("idle", "busy"),
-          "the slow asker never went offline (guard did not fire)")
-    fake2.ask_delay = 0.0
-    fake2.ask_on_wake = False  # stays out of the pool below
-
-
-# =============================================================================
-# Bundle: lifecycle — offline requeues, the hung-request tick survival,
-# parked-refresh bookkeeping, cancellation, the health panel, raw-log
-# losslessness, git identity and the live blocked-push roundtrip.
-# =============================================================================
-
-def bundle_lifecycle(ctx):
-    auth, fake, fake_id, fake_token = ctx.auth, ctx.fake, ctx.fake_id, ctx.fake_token
-    app = ctx.app
-
-    print("== plan 11: draft state machine, edit matrix, enqueue/delete guards ==")
-    # New tasks default to draft; Enqueue is the only path to the
-    # queue (there is no agent path — the ingest API refuses to queue).
-    act(auth, slot_public(auth, "/tasks", "tasks")["create"], {
-        "project_id": "1",
-        "title": "Draft lifecycle task",
-        "priority": "4",
-    })
-    draft_task = int([t["id"] for t in slot_public(auth, "/tasks", "tasks")["tasks"]
-                      if t["title"] == "Draft lifecycle task"][0])
-    detail = task_state(auth, draft_task)
-    check(detail["status"] == "draft", "a created task lands in draft")
-    check(detail.get("enqueue") is not None and detail.get("delete") is not None,
-          "draft exposes the enqueue + delete actions")
-    check(detail.get("cancel") is not None, "the cancel action stays authored")
-    status, page = http("GET", "/tasks/%d" % draft_task, timeout=15)
-    check(status == 200 and "Enqueue task" in page and ">Delete<" in page,
-          "the task page shows Enqueue + Delete in draft")
-    check("Mark done" not in page,
-          "the user Mark-complete action is gone (agent-only completion)")
-    # Plan 12: the auto-enqueue-after predecessor REPLACES draft
-    # dependencies — setting it is allowed while the predecessor is
-    # still pending (the enqueue itself succeeds; the DISPATCHER holds
-    # dispatch back until the predecessor is done).
-    act(auth, slot_public(auth, "/tasks", "tasks")["create"], {
-        "project_id": "1",
-        "title": "Draft dependency",
-        "priority": "4",
-    })
-    draft_dep = int([t["id"] for t in slot_public(auth, "/tasks", "tasks")["tasks"]
-                     if t["title"] == "Draft dependency"][0])
-    act(auth, detail["update"], {"enqueue_after_task_id": str(draft_dep)})
-    check(int(task_state(auth, draft_task).get("enqueue_after_task_id") or 0)
-          == draft_dep,
-          "the draft edit sets the auto-enqueue predecessor")
-    act(auth, slot_public(auth, "/tasks", "tasks")["create"], {
-        "project_id": "1", "title": "Eager dependent", "priority": "4",
-        "enqueue_after_task_id": str(draft_dep)})
-    eager = task_id_of("Eager dependent")
-    enqueue_task(auth, eager)
-    check(task_state(auth, eager)["status"] == "queued",
-          "enqueue succeeds while the predecessor is pending (no draft guard)")
-    check(quiet_window(quiet_seconds(),
-                       lambda: task_state(auth, eager)["status"] == "queued",
-                       "pending predecessor holds dispatch"),
-          "the pending predecessor holds dispatch back (never assigned)")
-    # The edit matrix starts in DRAFT: every field except status.
-    act(auth, detail["update"], {
-        "title": "Draft lifecycle task (edited)",
-        "description": "Now with a description",
-        "priority": "2",
-        "task_branch": "feature/draft",
-        "branch_from": "main",
-        "mode": "investigate",
-    })
-    detail = task_state(auth, draft_task)
-    check(detail["title"] == "Draft lifecycle task (edited)"
-          and detail["description"] == "Now with a description"
-          and detail["priority"] == 2
-          and detail["task_branch"] == "feature/draft"
-          and detail["branch_from"] == "main"
-          and detail["mode"] == "investigate",
-          "draft edits apply to every field (incl. the mode)")
-    # Clear the predecessor (the empty sentinel): dispatch gates on
-    # the hold tag alone now.
-    act(auth, detail["update"], {"enqueue_after_task_id": "0"})
-    check(not int(task_state(auth, draft_task).get("enqueue_after_task_id") or 0),
-          "the draft edit clears the auto-enqueue predecessor")
-    # A hold tag nothing carries keeps the dependent QUEUED (never
-    # dispatched) through the remaining edit-matrix checks.
-    saddles_state = slot_public(auth, "/saddles", "saddles")
-    act(auth, saddles_state["create_capability"], {"name": "holdlock"})
-    holdlock_cap = int([c["id"] for c in slot_public(auth, "/saddles", "saddles")["capabilities"]
-                        if c["name"] == "holdlock"][0])
-    act(auth, detail["attach_capability"], {"capability_id": str(holdlock_cap)})
-    # Enqueue the now-cleared dependent: the hold tag keeps it queued
-    # (never dispatched), so the non-draft edit matrix applies.
-    enqueue_task(auth, draft_task)
-    check(quiet_window(3, lambda: task_state(auth, draft_task)["status"] == "queued",
-                       "held dependent stays queued"),
-          "the held dependent stays queued (never dispatched)")
-    # The predecessor settles for the shard drain.
-    enqueue_task(auth, draft_dep)
-    check(wait_task_done(auth, draft_dep, timeout=90) is not None,
-          "the predecessor settles")
-
-    # Drafts are never dispatched even with an idle saddle available.
-    act(auth, slot_public(auth, "/tasks", "tasks")["create"], {
-        "project_id": "1",
-        "title": "Never-dispatched draft",
-        "priority": "1",
-    })
-    silent_draft = int([t["id"] for t in slot_public(auth, "/tasks", "tasks")["tasks"]
-                        if t["title"] == "Never-dispatched draft"][0])
-    check(quiet_window(quiet_seconds(),
-                       lambda: task_state(auth, silent_draft)["status"] == "draft",
-                       "draft never dispatched"),
-          "an idle saddle never picks a draft up (no agent enqueue path)")
-
-    # Once work can begin (queued here), only priority is editable.
-    act(auth, detail["update"], {
-        "title": "Should not apply",
-        "priority": "3",
-    })
-    detail = task_state(auth, draft_task)
-    check(detail["title"] == "Draft lifecycle task (edited)" and detail["priority"] == 3,
-          "non-draft edits apply priority only (title locked)")
-    # A terminal task edits nothing.
-    conn = db()
-    conn.execute("update tasks set status = 'done', completed_at = strftime('%s','now')"
-                 " where id = ?", (draft_task,))
-    conn.commit()
-    conn.close()
-    act(auth, task_state(auth, draft_task)["update"], {"priority": "8"})
-    check(task_state(auth, draft_task)["priority"] == 3,
-          "terminal tasks edit nothing (priority locked)")
-    # Capabilities lock once a worker has the job: editable while
-    # queued, locked once working.
-    act(auth, saddles_state["create_capability"], {"name": "editlock"})
-    editlock_cap = int([c["id"] for c in slot_public(auth, "/saddles", "saddles")
-                        ["capabilities"] if c["name"] == "editlock"][0])
-    act(auth, saddle_card(auth, "fake-saddle")["attach_capability"],
-        {"capability_id": str(editlock_cap)})
-    locked_task = create_queued(auth, {"project_id": "1", "title": "Caplock task",
-                                       "priority": "2"})
-    detail = task_state(auth, locked_task)
-    act(auth, detail["attach_capability"], {"capability_id": str(editlock_cap)})
-    check(wait_for(lambda: any(c["name"] == "editlock"
-                               for c in task_state(auth,
-                                                   locked_task)["capabilities"])
-                   or False, timeout=60, what="editlock attached") is not None,
-          "capabilities attach while queued (no worker yet)")
-    check(wait_for(lambda: task_state(auth, locked_task).get("status") == "working"
-                   or False, timeout=60, what="caplock working") is not None,
-          "the caplock task reaches working")
-    detach_directives = act(auth, task_state(auth, locked_task)["capabilities"][0]["detach"], {})
-    check(any(d.get("type") == "notify" and d.get("kind") == "error"
-              for d in detach_directives),
-          "capabilities are locked once a worker has the job")
-    # The ingest API has no queue transition either (only working and
-    # blocked are accepted states).
-    conn = db()
-    caplock_session = conn.execute(
-        "select id from sessions where task_id = ? and ended_at is null",
-        (locked_task,)).fetchone()
-    conn.close()
-    if caplock_session is not None:
-        status, _ = saddle_api("POST", "/api/saddle/results", fake_token,
-                               {"session_id": caplock_session[0],
-                                "state": "queued"})
-        check(status == 200
-              and task_state(auth, locked_task)["status"] in ("working", "done"),
-              "a queued state push is a no-op (only the wire's states drive bookkeeping)")
-
-    # Delete guards: a clean draft deletes; non-draft refuses; a draft
-    # with dependents is refused naming them.
-    act(auth, task_state(auth, silent_draft)["delete"], {})
-    check(not any(t["id"] == silent_draft
-                  for t in slot_public(auth, "/tasks", "tasks")["tasks"]),
-          "a clean draft task deletes")
-    delete_directives = act(auth, task_state(auth, draft_task)["delete"], {})
-    check(any(d.get("type") == "notify" and d.get("kind") == "error"
-              for d in delete_directives),
-          "a non-draft task refuses the delete")
-    act(auth, slot_public(auth, "/tasks", "tasks")["create"], {
-        "project_id": "1", "title": "Guarded draft", "priority": "4"})
-    guarded = int([t["id"] for t in slot_public(auth, "/tasks", "tasks")["tasks"]
-                   if t["title"] == "Guarded draft"][0])
-    act(auth, slot_public(auth, "/tasks", "tasks")["create"], {
-        "project_id": "1", "title": "Dependent namer", "priority": "4"})
-    namer = int([t["id"] for t in slot_public(auth, "/tasks", "tasks")["tasks"]
-                 if t["title"] == "Dependent namer"][0])
-    act(auth, task_state(auth, namer)["update"],
-        {"enqueue_after_task_id": str(guarded)})
-    check(int(task_state(auth, namer).get("enqueue_after_task_id") or 0) == guarded,
-          "the namer points at the guarded predecessor")
-    act(auth, task_state(auth, guarded)["delete"], {})
-    check(not any(t["id"] == guarded
-                  for t in slot_public(auth, "/tasks", "tasks")["tasks"]),
-          "deleting a predecessor succeeds")
-    check(not int(task_state(auth, namer).get("enqueue_after_task_id") or 0),
-          "the delete clears the dependent's dangling predecessor reference")
-
-    print("== offline requeues ==")
-    # Tasks caught working on a saddle that went offline requeue with a
-    # agent comment each tick.
-    task_id_tmp = create_queued(auth, {
-        "project_id": "1",
-        "title": "Offline saddle task",
-        "priority": "2",
-    })
-    offline_task = task_id_tmp
-    check(wait_for(lambda: task_state(auth, offline_task).get("status") == "working"
-                   or False, timeout=60, what="offline task starts working") is not None,
-          "task reaches working before its saddle disappears")
-    # Hold the daemon mid-round across the requeue window (the
-    # original relied on its 8s work period outlasting the 5s tick):
-    # the task completing on its own would race the offline pass and
-    # skip the requeue the check exists to observe.
-    fake.hold_state = True
-    conn = db()
-    conn.execute("update saddles set status = 'offline' where name = 'fake-saddle'")
-    conn.commit()
-    conn.close()
-    # The requeue frees the saddle in the same tick, so 'queued' is
-    # transient; the durable evidence is the agent comment (and the task
-    # completing again on the healthy daemon).
-    check(wait_for(lambda: any(c["body"] == "saddle went offline; task requeued"
-                               for c in task_state(auth, offline_task).get("comments", []))
-                   or False, timeout=30, what="offline requeue comment") is not None,
-          "offline saddle requeues the task")
-    fake.hold_state = False  # release: the round ends, the daemon re-asks
-    check(wait_task_done(auth, offline_task, timeout=60) is not None,
-          "requeued task completes again on the healthy daemon")
-    # R2 (arch 13): the release owner's outcomes — the requeue closed
-    # the held attempt's session 'stopped'; the held daemon's terminal
-    # push then completes the task against that closed session (the
-    # outcome stands — a closed row never reopens). A task that
-    # completes a LIVE round closes its session 'done' (draft_dep
-    # above ran one open session to its terminal push).
-    conn = db()
-    outcome_rows = conn.execute(
-        "select outcome from sessions where task_id = ? order by id",
-        (offline_task,)).fetchall()
-    dep_outcome = conn.execute(
-        "select outcome from sessions where task_id = ? order by id desc",
-        (draft_dep,)).fetchone()
-    conn.close()
-    check(outcome_rows and outcome_rows[0][0] == "stopped",
-          "the one release path closes the requeued attempt 'stopped'")
-    check(dep_outcome is not None and dep_outcome[0] == "done",
-          "the terminal push closes a live round's session 'done'")
-
-    print("== R6 F1: a hanging request cannot freeze the tick ==")
-    # One wedged /task-update (never responds) blocks the comment/
-    # subtask-event delivery pass; the Soup timeout must fail it and
-    # later ticks keep dispatching.
-    conn = db()
-    conn.execute("insert into tasks (project_id, title, status, priority, created_at)"
-                 " values (1, 'Hang survivor', 'queued', 2, strftime('%s','now'))")
-    hang_task = conn.execute("select max(id) from tasks").fetchone()[0]
-    conn.close()
-    task_id_tmp = create_queued(auth, {
-        "project_id": "1",
-        "title": "Hang runner",
-        "priority": "3",
-    })
-    hang_runner = task_id_tmp
-    # A human comment on the running task gives the tick a
-    # /task-update delivery to make; the next one hangs.
-    check(wait_for(lambda: task_state(auth, hang_runner).get("status") == "working"
-                   or False, timeout=60, what="hang runner working") is not None,
-          "hang runner reaches working")
-    act(auth, task_state(auth, hang_runner)["comment"],
-        {"body": "operator ping while wedged"})
-    fake.hang_next["/task-update"] = 1
-    check(wait_task_done(auth, hang_runner, timeout=90) is not None,
-          "dispatching task survives a hung daemon request")
-    check(wait_for(lambda: any(c.get("text") == "operator ping while wedged"
-                               or c.get("body") == "operator ping while wedged"
-                               for c in fake.comment_log) or False,
-                   timeout=30, what="wedged comment eventually delivered") is not None,
-          "the comment delivery retries after the hang")
-    # The hung delivery itself fails after the timeout; the system
-    # kept moving either way.
-    with open(os.path.join(WORK, "app.log")) as handle:
-        app_log = handle.read()
-    check("tick exceeded" not in app_log or "Dispatch tick failed" in app_log,
-          "a hung request never freezes the tick latch")
-
-    print("== R6 F2: refresh must not corrupt parked bookkeeping ==")
-    fake.suspend_on_title = "Parked refresh parent"
-    task_id_tmp = create_queued(auth, {
-        "project_id": "1",
-        "title": "Parked refresh parent",
-        "priority": "2",
-    })
-    parked = task_id_tmp
-    check(wait_for(lambda: task_state(auth, parked).get("status") == "suspended"
-                   or False, timeout=60, what="parked parent suspends") is not None,
-          "parent parks before the refresh")
-    fake_card = saddle_card(auth, "fake-saddle")
-    act(auth, fake_card["refresh"], {})
-    fake_card = saddle_card(auth, "fake-saddle")
-    check(fake_card["status"] == "idle" and int(fake_card["current_task_id"] or 0) == 0,
-          "refresh on a parked (suspended) daemon leaves the saddle idle")
-    # The parked task keeps its open session and stays put: plain
-    # tasks have no subtask events to resume them (the goal machinery
-    # owns resumes); the human resumes it explicitly.
-    check(quiet_window(quiet_seconds(),
-                       lambda: task_state(auth, parked)["status"] == "suspended",
-                       "parked task stays parked"),
-          "a parked plain task stays parked after the refresh (no resume channel)")
-    act(auth, task_state(auth, parked)["cancel"], {})
-    check(wait_for(lambda: task_state(auth, parked)["status"] == "failed" or False,
-                   timeout=30, what="parked task cancelled") is not None,
-          "the parked task cancels cleanly after the refresh")
-
-    print("== R7 B1: cancel reaches the daemon ==")
-    # Plan 10 phase 2: cancellation is POST /task-update {kind: cancel}
-    # to the RUNNING daemon (the abort machinery, workspace kept).
-    task_id_tmp = create_queued(auth, {
-        "project_id": "1",
-        "title": "Cancel live",
-        "priority": "2",
-    })
-    cancel_live = task_id_tmp
-    check(wait_for(lambda: task_state(auth, cancel_live).get("status") == "working"
-                   or False, timeout=60, what="cancel-live working") is not None,
-          "task reaches working before the cancel")
-    act(auth, task_state(auth, cancel_live)["cancel"], {})
-    check(wait_for(lambda: cancel_live in fake.abort_log or False,
-                   timeout=30, what="daemon abort recorded") is not None,
-          "cancelling POSTs task-update cancel to the daemon")
-    check(any(c["body"] == "cancelled; daemon aborted"
-              for c in task_state(auth, cancel_live).get("comments", [])),
-          "the abort outcome is narrated")
-    check(task_state(auth, cancel_live)["status"] == "failed",
-          "cancelled task lands failed as before")
-
-    # A 500 on the cancel marks the saddle offline (no fence layer
-    # anymore); nothing dispatches to it while offline, and the
-    # daemon's own ask flips the row back to idle (proof of life).
-    task_id_tmp = create_queued(auth, {
-        "project_id": "1",
-        "title": "Fence runner",
-        "priority": "2",
-    })
-    fence_runner = task_id_tmp
-    check(wait_for(lambda: task_state(auth, fence_runner).get("status") == "working"
-                   or False, timeout=60, what="fence runner working") is not None,
-          "second task reaches working")
-    fake.abort_failures = 1
-    act(auth, task_state(auth, fence_runner)["cancel"], {})
-    check(any(c["body"] == "cancelled; daemon unreachable — saddle marked offline"
-              for c in task_state(auth, fence_runner).get("comments", [])),
-          "failed cancel narrates the offline marking")
-    check(saddle_card(auth, "fake-saddle")["status"] == "offline",
-          "saddle marked offline after the failed cancel")
-    task_id_tmp = create_queued(auth, {
-        "project_id": "1",
-        "title": "During fence",
-        "priority": "3",
-    })
-    during_fence = task_id_tmp
-    # Converted sleep(7): a quiet window spanning several dispatch
-    # ticks in which the task MUST stay queued — if the offline
-    # saddle ever dispatches it, this fails loudly. The daemon is held
-    # mid-round for the window (the original relied on its 8s work
-    # period outlasting the sleep): a finishing round would ask, prove
-    # liveness and flip the offline row — only after the window may it.
-    fake.hold_state = True
-    check(quiet_window(quiet_seconds(),
-                       lambda: task_state(auth, during_fence)["status"] == "queued",
-                       "offline saddle does not dispatch during_fence"),
-          "offline saddle is not dispatchable")
-    fake.hold_state = False
-    # The (unaborted) daemon finishes its round, goes idle-awake and
-    # asks — the ask is the proof of life that flips the row back.
-    check(wait_for(lambda: saddle_card(auth, "fake-saddle")["status"] == "idle" or False,
-                   timeout=30, what="ask flips offline to idle") is not None,
-          "the daemon's ask flips the offline row back to idle")
-    check(wait_task_done(auth, during_fence, timeout=60) is not None,
-          "queued work dispatches once the saddle proves it is alive")
-
-    print("== R7 B3: health panel + pushed raw log from the first round ==")
-    # A normally dispatched task pushes its chunks immediately: raw
-    # rows exist from the first round (the session-4 gap stays
-    # fixed without any probe machinery).
-    task_id_tmp = create_queued(auth, {
-        "project_id": "1",
-        "title": "Raw from first push",
-        "priority": "2",
-    })
-    raw_first = task_id_tmp
-
-    def raw_count(task_id):
-        conn = db()
-        try:
-            return conn.execute(
-                "select count(*) from session_raw_log where session_id in"
-                " (select id from sessions where task_id = ?)", (task_id,)).fetchone()[0]
-        finally:
-            conn.close()
-
-    check(wait_for(lambda: raw_count(raw_first) > 0 or False,
-                   timeout=60, what="raw rows from first push") is not None,
-          "pushed chunks land from the first round (session-4 gap)")
-    check(wait_task_done(auth, raw_first, timeout=60) is not None,
-          "raw-first task completes")
-
-    # Health panel: a manual refresh populates the snapshot.
-    fake_card = saddle_card(auth, "fake-saddle")
-    act(auth, fake_card["refresh"], {})
-    card = saddle_card(auth, "fake-saddle")
-    check(card.get("health") in ("healthy", "stale")
-          and card.get("daemon_state") in ("working", "idle", "done")
-          and card.get("uptime_display", "") != ""
-          and card.get("last_contact_display", "") not in ("", "never"),
-          "saddles page shows daemon state, uptime and last contact")
-
-    print("== R8: pushed chunk ingestion is lossless ==")
-    # The daemon's opening flush: a coloured prompt run, plain text,
-    # a bare CRLF between prompts and the tail — every non-empty
-    # chunk must land, exactly once, in seq order. A mid-flight
-    # redelivery of the whole batch (the outbox's at-least-once
-    # retry) consumes the duplicates.
-    corpus = [
-        {"seq": 1, "text": "\x1b[01;32muser@host\x1b[00m:\x1b[01;34m~/task-1\x1b[00m$ "},
-        {"seq": 2, "text": "echo hello\r\n"},
-        {"seq": 3, "text": "\r\n"},
-        {"seq": 4, "text": "hello\r\n"},
-        {"seq": 5, "text": "\x1b[01;32muser@host\x1b[00m:\x1b[01;34m~/task-1\x1b[00m$ "},
-        {"seq": 6, "text": "done\r\n"},
-    ]
-    fake.scripted_corpus = corpus
-    fake.hold_state = True
-    task_id_tmp = create_queued(auth, {
-        "project_id": "1",
-        "title": "Lossless log task",
-        "priority": "2",
-    })
-    lossless = task_id_tmp
-
-    def stored_seqs(task_id):
-        conn = db()
-        try:
-            return [r[0] for r in conn.execute(
-                "select seq from session_raw_log where session_id in"
-                " (select id from sessions where task_id = ?)"
-                " order by seq", (task_id,))]
-        finally:
-            conn.close()
-
-    check(wait_for(lambda: task_state(auth, lossless).get("status") == "working"
-                   or False, timeout=60, what="lossless task working") is not None,
-          "lossless task dispatches and pushes its opening flush")
-    check(wait_for(lambda: stored_seqs(lossless) == [1, 2, 3, 4, 5, 6] or False,
-                   timeout=30, what="all six chunks stored") is not None,
-          "every pushed chunk lands in session_raw_log, CRLF-only included (%s)"
-          % stored_seqs(lossless))
-    status, _ = saddle_api("POST", "/api/saddle/chunks", fake.token,
-                           {"session_id": fake.session_id,
-                            "chunks": [dict(chunk) for chunk in corpus]})
-    check(status == 200 and stored_seqs(lossless) == [1, 2, 3, 4, 5, 6],
-          "a full-batch redelivery stores nothing new (exactly-once)")
-    request = urllib.request.Request(
-        WEB + "/terminal-stream/%d" % [r[0] for r in db().execute(
-            "select id from sessions where task_id = ?", (lossless,))][0])
-    with urllib.request.urlopen(request, timeout=15) as stream:
-        texts = []
-        deadline = time.monotonic() + 8
-        while time.monotonic() < deadline and len(texts) < 6:
-            line = stream.readline().decode().strip()
-            if not line.startswith("data: ") or line == "data: ping":
-                continue
-            event = json.loads(line[6:])
-            if event.get("type") == "raw":
-                texts.append(event.get("text") or "")
-        check("\r\n" in texts and len(texts) == 6,
-              "SSE serves the whitespace chunk unfiltered")
-    fake.hold_state = False
-    fake.scripted_corpus = None
-    check(wait_task_done(auth, lossless, timeout=60) is not None,
-          "lossless task completes")
-
-    print("== R9 B1/B2: git identity + ssh key ==")
-    # The key travels on /status into the saddle row and the page view
-    # (the manual refresh's exceptional probe).
-    fake.ssh_public_key = "ssh-ed25519 AAAAC3NzaC1lZDI1teStKey saddle-1@fedora"
-    fake_card = saddle_card(auth, "fake-saddle")
-    check(fake_card.get("ssh_public_key", "") == "",
-          "no key shown before the daemon reports one")
-    act(auth, fake_card["refresh"], {})
-    check(wait_for(lambda: "AAAAC3NzaC1lZDI1teStKey" in
-                   saddle_card(auth, "fake-saddle").get("ssh_public_key", "") or False,
-                   timeout=30, what="key lands on the row") is not None,
-          "reported ssh_public_key persists onto the saddle row")
-    conn = db()
-    row_key = conn.execute("select ssh_public_key from saddles where name = 'fake-saddle'"
-                           ).fetchone()[0]
-    conn.close()
-    check(row_key == fake.ssh_public_key,
-          "the key is stored verbatim in the database")
-
-    # Identity edit flows through the UI into the assignment payload.
-    fake_card = saddle_card(auth, "fake-saddle")
-    act(auth, fake_card["update_identity"],
-        {"git_name": "clanker-bot", "git_email": "bot@unitatem.net"})
-    fake_card = saddle_card(auth, "fake-saddle")
-    check(fake_card.get("git_name") == "clanker-bot"
-          and fake_card.get("git_email") == "bot@unitatem.net",
-          "inline edit saves the git identity")
-
-    task_id_tmp = create_queued(auth, {
-        "project_id": "1",
-        "title": "Identity task",
-        "priority": "2",
-    })
-    identity_task = task_id_tmp
-    check(wait_for(lambda: any(int(p.get("task", {}).get("id") or 0) == identity_task
-                               for p in fake.start_payloads) or False,
-                   timeout=60, what="identity task dispatched") is not None,
-          "identity task dispatches")
-    payload = [p for p in fake.start_payloads
-               if int(p.get("task", {}).get("id") or 0) == identity_task][-1]
-    identity = payload.get("git_identity") or {}
-    check(identity.get("name") == "clanker-bot"
-          and identity.get("email") == "bot@unitatem.net",
-          "the assignment carries the saddle's git_identity")
-
-    # Earlier assignments (identity unset) carry no git_identity member.
-    check(all("git_identity" not in p for p in fake.start_payloads[:-1]),
-          "unset identity omits the member (daemon fallback applies)")
-
-    # Clearing the identity omits it from later assignments.
-    fake_card = saddle_card(auth, "fake-saddle")
-    act(auth, fake_card["update_identity"], {"git_name": "", "git_email": ""})
-    check(saddle_card(auth, "fake-saddle").get("git_name", "") == "",
-          "clearing the identity empties the row")
-    check(wait_task_done(auth, identity_task, timeout=60) is not None,
-          "identity task completes")
-
-    print("== phase 2: blocked push -> block row + pulse ==")
-    # The browser flow on each pulse: statum.act(task.refresh) — the
-    # sealed GET action must rehydrate the task slot with the new
-    # block the daemon just PUSHED (state blocked + block payload).
-    task_id_tmp = create_queued(auth, {
-        "project_id": "1",
-        "title": "Live block task",
-        "priority": "2",
-    })
-    live_task = task_id_tmp
-    check(wait_for(lambda: task_state(auth, live_task).get("status") == "working"
-                   or False, timeout=60, what="live task working") is not None,
-          "live-block task reaches working")
-    fake.hold_state = True
-    fake.state = "blocked"  # the daemon parks on its question
-    status = fake.push_results("blocked", block={
-        "question": "Pick one", "type": "question", "options": ["A", "B"]})
-    check(status == 200, "blocked state push accepted")
-    # The parked daemon is idle-awake: it asks (and sleeps on 204).
-    fake.maybe_trigger_ask("parked")
-    check(wait_for(lambda: any(b.get("question") == "Pick one"
-                               for b in task_state(auth, live_task).get("blocks", []))
-                   or False, timeout=30, what="block lands in state") is not None,
-          "the pushed block reaches the sealed refresh without a reload")
-    detail = task_state(auth, live_task)
-    check(detail.get("status") == "blocked",
-          "the blocked push flips the task to blocked")
-    pushed_block = [b for b in detail["blocks"] if b.get("question") == "Pick one"][0]
-    conn = db()
-    options_json = conn.execute(
-        "select options from task_blocks where id = ?", (int(pushed_block["id"]),)
-    ).fetchone()[0]
-    conn.close()
-    check(json.loads(options_json) == ["A", "B"],
-          "the block row carries its options payload")
-    check(any(s["status"] == "idle"
-              for s in slot_public(auth, "/saddles", "saddles")["saddles"]),
-          "the blocked push parks the saddle")
-    detail = task_state(auth, live_task)
-    check(detail.get("refresh") is not None,
-          "the sealed GET refresh action is still authored")
-    status, _ = http("GET", detail["refresh"]["uri"], timeout=15)
-    check(status in (200, 401),
-          "the refresh URI resolves as a GET (client roundtrip shape)")
-    act(auth, pushed_block["answer_action"], {"answer": "A"})
-    # The answer makes the parked task resume-offerable: the affine
-    # saddle is woken, asks, and its assignment carries the answer.
-    pushes_before = len([p for p in fake.start_payloads
-                         if int(p.get("task", {}).get("id") or 0) == live_task])
-    check(wait_for(lambda: len([p for p in fake.start_payloads
-                                if int(p.get("task", {}).get("id") or 0) == live_task])
-                   > pushes_before or False, timeout=60,
-                   what="blocked task resumes") is not None,
-          "answering the pushed block resumes the parked workspace")
-    fake.hold_state = False  # the resumed round runs to completion
-    resume_payload = [p for p in fake.start_payloads
-                      if int(p.get("task", {}).get("id") or 0) == live_task][-1]
-    answers = resume_payload.get("task", {}).get("answers", [])
-    check(any(a.get("answer") == "A" for a in answers),
-          "the resume assignment carries the human's answer")
-    check(wait_task_done(auth, live_task, timeout=60) is not None,
-          "live-block task completes after answering")
-
-    print("== R2: the one release path behind unregister ==")
-    # Arch 13: removing a saddle releases its held task through the
-    # same owner as every requeue — never an orphan open session on a
-    # deleted row. Route 1: a DEAD host — the abort delivery fails
-    # fast, the offline bookkeeping releases (queued + comment +
-    # session 'stopped'), the unregister then deletes the row.
-    saddles_state = slot_public(auth, "/saddles", "saddles")
-    act(auth, saddles_state["register"], {"name": "dead-host",
-                                          "host": "127.0.0.1:1"})
-    dead_card = [s for s in slot_public(auth, "/saddles", "saddles")["saddles"]
-                 if s["name"] == "dead-host"][0]
-    dead_id = int(dead_card["id"])
-    task_id_tmp = create_queued(auth, {
-        "project_id": "1",
-        "title": "Dead-host unregister task",
-        "priority": "2",
-    })
-    dead_task = task_id_tmp
-    conn = db()
-    conn.execute("update tasks set status = 'working' where id = ?",
-                 (dead_task,))
-    conn.execute("insert into sessions (task_id, saddle_id, started_at)"
-                 " values (?, ?, strftime('%s','now'))", (dead_task, dead_id))
-    conn.execute("update saddles set current_task_id = ? where id = ?",
-                 (dead_task, dead_id))
-    conn.commit()
-    dead_session = conn.execute(
-        "select id from sessions where task_id = ? and ended_at is null",
-        (dead_task,)).fetchone()[0]
-    conn.close()
-    act(auth, dead_card["unregister"], {})
-    conn = db()
-    dead_row = conn.execute("select status from tasks where id = ?",
-                            (dead_task,)).fetchone()
-    dead_session_row = conn.execute(
-        "select outcome, ended_at is not null from sessions where id = ?",
-        (dead_session,)).fetchone()
-    dead_saddle_count = conn.execute(
-        "select count(*) from saddles where id = ?", (dead_id,)).fetchone()[0]
-    conn.close()
-    check(dead_row is not None and dead_row[0] == "queued",
-          "unregister of a dead-host saddle releases the held task to the queue")
-    check(dead_session_row is not None and dead_session_row[0] == "stopped"
-          and dead_session_row[1],
-          "the offline release closes the held task's session 'stopped'")
-    check(dead_saddle_count == 0, "the dead-host saddle row is gone")
-
-    # Route 2: no open session on the saddle — the abort is a no-op
-    # and the unregister itself carries the release (the requeue flip
-    # through the one owner, the row deleted after).
-    saddles_state = slot_public(auth, "/saddles", "saddles")
-    act(auth, saddles_state["register"], {"name": "quiet-host",
-                                          "host": "127.0.0.1:%d" % fake.port})
-    quiet_card = [s for s in slot_public(auth, "/saddles", "saddles")["saddles"]
-                  if s["name"] == "quiet-host"][0]
-    quiet_id = int(quiet_card["id"])
-    task_id_tmp = create_queued(auth, {
-        "project_id": "1",
-        "title": "Quiet-host unregister task",
-        "priority": "2",
-    })
-    quiet_task = task_id_tmp
-    conn = db()
-    conn.execute("update tasks set status = 'working' where id = ?",
-                 (quiet_task,))
-    conn.execute("update saddles set current_task_id = ? where id = ?",
-                 (quiet_task, quiet_id))
-    conn.commit()
-    conn.close()
-    act(auth, quiet_card["unregister"], {})
-    conn = db()
-    quiet_row = conn.execute("select status from tasks where id = ?",
-                             (quiet_task,)).fetchone()
-    quiet_saddle_count = conn.execute(
-        "select count(*) from saddles where id = ?", (quiet_id,)).fetchone()[0]
-    conn.close()
-    check(quiet_row is not None and quiet_row[0] == "queued",
-          "unregister's own release returns the held task to the queue")
-    check(quiet_saddle_count == 0, "the quiet-host saddle row is gone")
-
-
-# =============================================================================
-# Bundle: answers — the answer-resume machinery in both daemon shapes
-# (sleeping affine wake, mid-round verdict delivery), offline requeue
-# keeping parked-with-answered tasks, the staleness probe, and the
-# startup token migration (this shard's one deliberate app restart).
-# =============================================================================
-
-def bundle_answers(ctx):
-    auth, fake, fake_id, fake_token = ctx.auth, ctx.fake, ctx.fake_id, ctx.fake_token
-    app = ctx.app
-
-    print("== phase 2: answer resume — wake -> ask -> affinity claim ==")
-    # The full live sequence against a daemon that asks after its
-    # park: ask -> assignment -> blocked push (park) -> ask -> 204
-    # -> sleeps (row idle) -> human answers -> the dispatcher WAKES
-    # the sleeping affine saddle -> its ask allocates the resume,
-    # the verdict riding the assignment -> the session continues.
-    # A private capability tag keeps the fleet's other sleeping
-    # saddles from claiming these tasks.
-    saddles_state = slot_public(auth, "/saddles", "saddles")
-    act(auth, saddles_state["create_capability"], {"name": "answerflow"})
-    answerflow_cap = int([c["id"] for c in slot_public(auth, "/saddles", "saddles")["capabilities"]
-                          if c["name"] == "answerflow"][0])
-
-    def answerflow_daemon(**kwargs):
-        daemon = FakeSaddle()
-        daemon.ask_on_register = False   # manual, deterministic asks
-        daemon.hold_state = True         # the tests drive the lifecycle
-        for key, value in kwargs.items():
-            setattr(daemon, key, value)
-        daemon.serve()
-        return daemon
-
-    def register_answerflow(daemon, name):
-        act(auth, slot_public(auth, "/saddles", "saddles")["register"], {
-            "name": name, "host": "127.0.0.1:%d" % daemon.port})
-        act(auth, saddle_card(auth, name)["attach_capability"],
-            {"capability_id": str(answerflow_cap)})
-
-    def create_answerflow_task(title):
-        return create_queued(auth, {
-            "project_id": "1", "title": title, "priority": "2",
-            "capability_id": [str(answerflow_cap)]})
-
-    def retire_daemon(daemon, name):
-        # deterministic teardown: a dead daemon and an offline row
-        # never interfere with the sections that follow
-        daemon.kill()
-        act(auth, saddle_card(auth, name)["refresh"], {})
-
-    sleeper = answerflow_daemon(ask_on_wake=True)
-    register_answerflow(sleeper, "resume-sleeper")
-    sleeping_task = create_answerflow_task("Sleeping resume task")
-    ask_status, assignment = sleeper.ask_now()
-    check(ask_status == 200 and int(assignment["task"]["id"]) == sleeping_task,
-          "the daemon's ask claims the queued task")
-    sleeping_session = assignment.get("session_id")
-    sleeper.state = "blocked"
-    check(sleeper.push_results("blocked", block={
-        "question": "Pick a side", "type": "question",
-        "options": ["Port", "Starboard"]}) == 200,
-          "the blocked push parks the session")
-    check(wait_for(lambda: task_state(auth, sleeping_task).get("status") == "blocked"
-                   or False, timeout=30, what="sleeping task parked") is not None,
-          "the task parks as blocked")
-    check(saddle_card(auth, "resume-sleeper")["status"] == "idle",
-          "the parked session's saddle row reads idle")
-    ask_status, _ = sleeper.ask_now()
-    check(ask_status == 204,
-          "the parked daemon's ask returns 204 — it sleeps until woken")
-    # Converted sleep(3): ticks pass with the daemon asleep and no
-    # wake may arrive — a wake during the window fails loudly.
-    check(quiet_window(quiet_seconds(),
-                       lambda: len(sleeper.wake_log) == 0,
-                       "sleeping daemon never woken"),
-          "the sleeping daemon is never woken while the block waits")
-    detail = task_state(auth, sleeping_task)
-    side_block = [b for b in detail["blocks"] if b["question"] == "Pick a side"][0]
-    act(auth, side_block["answer_action"], {"option": "Starboard"})
-    check(wait_for(lambda: len(sleeper.wake_log) > 0 or False,
-                   timeout=30, what="wake after the answer") is not None,
-          "answering the block wakes the sleeping affine saddle")
-    # Answering = allocating (plan 11): the resume assignment carries
-    # the verdict as resume_notice (stable wording) AND a FRESH
-    # session id — the parked row closed, the daemon keys its resumed
-    # pushes on the new one.
-    check(wait_for(lambda: any(
-        int(p.get("task", {}).get("id") or 0) == sleeping_task
-        and p.get("session_id") != sleeping_session
-        and p.get("resume_notice") == "Human selected: Starboard"
-        and any(a.get("answer") == "Starboard"
-                for a in p.get("task", {}).get("answers", []))
-        for p in sleeper.start_payloads[1:]) or False,
-        timeout=30, what="resume allocation carries the verdict") is not None,
-          "the woken daemon's ask allocates the resume — fresh session, notice carried")
-    # Barrier: the resume's own working push must commit before the
-    # manual done push (a late working write would otherwise race the
-    # completion's full-row write).
-    check(wait_for(lambda: task_state(auth, sleeping_task).get("status") == "working"
-                   or False, timeout=15, what="resumed round working") is not None,
-          "the resumed round reports working before its completion push")
-    # The resumed round runs to completion keyed on the fresh session.
-    sleeper.push_results("done", summary="sleep-resumed round complete")
-    check(wait_task_done(auth, sleeping_task, timeout=30) is not None,
-          "the resumed session continues to completion")
-    conn = db()
-    rows = conn.execute(
-        "select id, outcome, ended_at is not null from sessions where task_id = ?"
-        " order by id", (sleeping_task,)).fetchall()
-    conn.close()
-    check(len(rows) == 2 and rows[0][1] == "resumed" and rows[0][2]
-          and rows[1][1] == "done" and rows[1][2],
-          "parked session closed 'resumed'; the resumed round ran on a fresh row to done (%s)"
-          % (rows,))
-    retire_daemon(sleeper, "resume-sleeper")
-
-    print("== phase 2: answer resume — the parked daemon is woken (POST /answer retired) ==")
-    # Post Task A every park FREES the daemon: after the blocked push
-    # it lands idle and asks (204). The retired POST /answer channel
-    # always refuses; the verdict reaches the parked workspace purely
-    # through the wake -> ask -> affinity allocation carrying the
-    # resume_notice + a fresh session id.
-    parked = answerflow_daemon(ask_on_wake=True,
-                               ask_on_terminal=False)
-    register_answerflow(parked, "resume-parked")
-    parked_task = create_answerflow_task("Parked resume task")
-    ask_status, assignment = parked.ask_now()
-    check(ask_status == 200 and int(assignment["task"]["id"]) == parked_task,
-          "the daemon's ask claims the task")
-    parked_session = assignment.get("session_id")
-    parked.state = "blocked"
-    check(parked.push_results("blocked", block={
-        "question": "Which database?", "type": "question",
-        "options": ["SQLite", "Postgres"]}) == 200,
-          "the blocked push parks the session mid-round")
-    check(wait_for(lambda: task_state(auth, parked_task).get("status") == "blocked"
-                   or False, timeout=30, what="parked task blocked") is not None,
-          "the task parks as blocked")
-    check(saddle_card(auth, "resume-parked")["status"] == "idle",
-          "the parked session's saddle row reads idle")
-    # The freed daemon re-asks (its idle loop) and sleeps on 204.
-    ask_status, _ = parked.ask_now()
-    check(ask_status == 204,
-          "the freed parked daemon asks again and sleeps (204)")
-    # The retired channel always refuses — the web never depends on it.
-    request = urllib.request.Request(
-        "http://127.0.0.1:%d/answer" % parked.port,
-        data=json.dumps({"answer": "SQLite", "branch_advanced": False}).encode(),
-        method="POST")
-    request.add_header("Content-Type", "application/json")
-    try:
-        urllib.request.urlopen(request, timeout=5)
-        refused = False
-    except urllib.error.HTTPError as error:
-        refused = error.code == 409
-    check(refused, "POST /answer always refuses (409) — parks resume via allocation")
-
-    detail = task_state(auth, parked_task)
-    db_block = [b for b in detail["blocks"] if b["question"] == "Which database?"][0]
-    # branch_advanced on the resume assignment (the /poll verdict
-    # channel's hint lives here now): a sibling on the same shared
-    # working branch completed strictly after the block's park marker
-    # — the resumed allocation must report branch_advanced=true so the
-    # daemon knows to pull before continuing.
-    conn = db()
-    parked_block_created = conn.execute(
-        "select created_at from task_blocks where id = ?", (db_block["id"],)
-    ).fetchone()[0]
-    conn.execute("update tasks set task_branch = 'shared/resume-branch'"
-                 " where id = ?", (parked_task,))
-    conn.commit()
-    conn.close()
-    wait_for(lambda: int(time.time()) > parked_block_created or False,
-             timeout=3, what="next clock second past the park marker")
-    conn = db()
-    conn.execute("insert into tasks (project_id, title, status, priority,"
-                 " task_branch, summary, completed_at, created_at)"
-                 " values (1, 'Resume sibling', 'done', 5, 'shared/resume-branch',"
-                 " 'sibling finished', strftime('%s','now'),"
-                 " strftime('%s','now','-300 seconds'))")
-    conn.commit()
-    conn.close()
-    act(auth, db_block["answer_action"], {"option": "SQLite"})
-    check(wait_for(lambda: len(parked.wake_log) > 0 or False,
-                   timeout=30, what="wake after the answer") is not None,
-          "answering the block wakes the parked (idle) affine saddle")
-    check(wait_for(lambda: any(
-        int(p.get("task", {}).get("id") or 0) == parked_task
-        and p.get("session_id") != parked_session
-        and p.get("resume_notice") == "Human selected: SQLite"
-        and p.get("branch_advanced") is True
-        for p in parked.start_payloads[1:]) or False,
-        timeout=30, what="parked resume allocation") is not None,
-          "the parked daemon's ask allocates the resume — fresh session, formatted notice,"
-          " branch_advanced=true after the sibling's completion")
-    # The hold_state daemon drives its round manually: the resumed
-    # round completes on the fresh session row.
-    parked.push_results("done", summary="parked round resumed and finished")
-    check(wait_task_done(auth, parked_task, timeout=90) is not None,
-          "the parked session continues to completion")
-    conn = db()
-    row = conn.execute("select outcome from sessions where id = ?",
-                       (parked_session,)).fetchone()
-    session_rows = conn.execute(
-        "select id, outcome from sessions where task_id = ? order by id",
-        (parked_task,)).fetchall()
-    conn.close()
-    check(row is not None and row[0] == "resumed"
-          and len(session_rows) == 2 and session_rows[0] == (parked_session, "resumed"),
-          "the parked session closed 'resumed' and the resumed round kept its own row (%s)"
-          % (session_rows,))
-    retire_daemon(parked, "resume-parked")
-
-    print("== plan 11: plan acceptance — accept / reject / auto-approve ==")
-    # A type 'plan' block parks like any other; Accept and
-    # Reject-with-feedback drive the same wake -> ask -> allocation
-    # resume as any verdict, the stable wording riding the
-    # resume_notice. Plan 12: the daemon only SENDS plan blocks on
-    # goal runs now (the goal page owns the review); this covers the
-    # generic verdict path a goal-run's mirrored block also uses. The
-    # auto-approve option is gone.
-    planner = answerflow_daemon(ask_on_wake=True, ask_on_terminal=False)
-    register_answerflow(planner, "plan-planner")
-
-    def park_on_plan(task_id, markdown):
-        planner.state = "blocked"
-        check(planner.push_results("blocked", block={
-            "question": "Plan submitted for review", "type": "plan",
-            "body": markdown}) == 200,
-              "the plan push parks the session")
-        # Wait for the block row itself (the auto-approve variant is
-        # answered — and may resume — before any status poll lands).
-        check(wait_for(lambda: any(b["block_type"] == "plan"
-                                   for b in task_state(auth, task_id)["blocks"])
-                       or False, timeout=30, what="plan block raised") is not None,
-              "the plan block reaches the task")
-        return [b for b in task_state(auth, task_id)["blocks"]
-                if b["block_type"] == "plan"][0]
-
-    # (a) Accept resumes with the approval notice.
-    accept_task = create_answerflow_task("Plan accept task")
-    ask_status, accept_assignment = planner.ask_now()
-    check(ask_status == 200 and int(accept_assignment["task"]["id"]) == accept_task,
-          "the planner claims the accept task")
-    accept_parked_session = accept_assignment.get("session_id")
-    plan_block = park_on_plan(accept_task, "# Steps\n\n1. Wire\n2. Test")
-    check(plan_block.get("answered") is not True,
-          "the plan block waits for a human verdict")
-    # Plan 16 S2: the accept form posts the verdict marker; the server
-    # builds the stable constant (byte-identical wire).
-    act(auth, plan_block["answer_action"], {"verdict": "accept"})
-    check(wait_for(lambda: any(
-        int(p.get("task", {}).get("id") or 0) == accept_task
-        and p.get("session_id") != accept_parked_session
-        and p.get("resume_notice") == "Plan approved. Proceed with implementation."
-        for p in planner.start_payloads[1:]) or False,
-        timeout=30, what="accept resume allocation") is not None,
-          "accept resumes the parked daemon with the approval notice")
-    planner.push_results("done", summary="plan accepted and implemented")
-    check(wait_task_done(auth, accept_task, timeout=60) is not None,
-          "the accepted plan's task completes")
-    planner.set_state("idle")
-
-    # (b) Reject-with-feedback loops the feedback notice back.
-    reject_task = create_answerflow_task("Plan reject task")
-    ask_status, reject_assignment = planner.ask_now()
-    check(ask_status == 200 and int(reject_assignment["task"]["id"]) == reject_task,
-          "the planner claims the reject task")
-    reject_parked_session = reject_assignment.get("session_id")
-    plan_block = park_on_plan(reject_task, "# Draft\n\nJust wing it")
-    act(auth, plan_block["answer_action"], {"feedback": "Add a test section"})
-    reject_block = [b for b in task_state(auth, reject_task)["blocks"]
-                    if b["block_type"] == "plan"][0]
-    check(reject_block.get("answer")
-          == "Plan feedback received:\nAdd a test section",
-          "reject stores the feedback in the stable wording (%s)"
-          % reject_block.get("answer"))
-    check(wait_for(lambda: any(
-        int(p.get("task", {}).get("id") or 0) == reject_task
-        and p.get("session_id") != reject_parked_session
-        and p.get("resume_notice") == "Plan feedback received:\nAdd a test section"
-        for p in planner.start_payloads[1:]) or False,
-        timeout=30, what="reject resume allocation") is not None,
-          "reject resumes the parked daemon with the feedback notice")
-    planner.push_results("done", summary="plan revised and delivered")
-    check(wait_task_done(auth, reject_task, timeout=60) is not None,
-          "the revised plan's task completes")
-    planner.set_state("idle")
-
-    retire_daemon(planner, "plan-planner")
-
-    print("== phase 2: offline requeue keeps parked-with-answered tasks ==")
-    # A daemon dying while its parked task carries an answered
-    # verdict: going offline must not requeue the task or close its
-    # session — the resume machinery (delivery once the daemon
-    # returns, or the affinity allocation on its next ask) needs
-    # both. The question park leaves the row idle; the review park
-    # keeps it busy@task (`saddle review` blocks the round without
-    # a parking state push), exercising the unreachable path's
-    # requeue decision both ways.
-    stranded = answerflow_daemon()
-    register_answerflow(stranded, "resume-stranded")
-    stranded_task = create_answerflow_task("Stranded answered task")
-    ask_status, _ = stranded.ask_now()
-    check(ask_status == 200, "the stranded daemon claims its task")
-    stranded.state = "blocked"
-    stranded.push_results("blocked", block={
-        "question": "Hold or fold?", "type": "question", "options": ["Hold", "Fold"]})
-    check(wait_for(lambda: task_state(auth, stranded_task).get("status") == "blocked"
-                   or False, timeout=30, what="stranded task parked") is not None,
-          "the stranded task parks as blocked")
-    detail = task_state(auth, stranded_task)
-    hold_block = [b for b in detail["blocks"] if b["question"] == "Hold or fold?"][0]
-    act(auth, hold_block["answer_action"], {"option": "Hold"})
-    stranded.kill()  # the daemon dies before the verdict is delivered
-    act(auth, saddle_card(auth, "resume-stranded")["refresh"], {})
-    check(wait_for(lambda: saddle_card(auth, "resume-stranded")["status"] == "offline"
-                   or False, timeout=30, what="stranded saddle offline") is not None,
-          "the dead daemon's saddle row goes offline")
-    # Converted sleep(7): offline ticks run while the task MUST stay
-    # parked — a requeue during the window fails loudly.
-    check(quiet_window(quiet_seconds(),
-                       lambda: task_state(auth, stranded_task)["status"] == "blocked",
-                       "stranded task not requeued"),
-          "the parked-with-answered task is not requeued by the offline pass")
-    conn = db()
-    open_session = conn.execute(
-        "select count(*) from sessions where task_id = ? and ended_at is null",
-        (stranded_task,)).fetchone()[0]
-    conn.close()
-    check(open_session == 1,
-          "the parked-with-answered task keeps its open session for the resume")
-
-    reviewer = answerflow_daemon(ask_on_terminal=False)
-    register_answerflow(reviewer, "resume-reviewer")
-    review_task = create_answerflow_task("Review park task")
-    ask_status, _ = reviewer.ask_now()
-    check(ask_status == 200, "the reviewer claims its task")
-    # Post Task A the review park frees the daemon: the blocked push
-    # carries the review block and parks the row idle.
-    reviewer.state = "blocked"
-    check(reviewer.push_results("blocked", block={
-        "question": "Review requested", "type": "review",
-        "body": "Ready for review: wired and tested."}) == 200,
-          "the review park push carries the review block")
-    check(wait_for(lambda: task_state(auth, review_task).get("status") == "review_requested"
-                   or False, timeout=30, what="review park raised") is not None,
-          "the review block parks the task as review_requested (row freed)")
-    # The verdict lands (nothing delivers it anymore); THEN the daemon
-    # dies and the manual refresh offlines it — the parked-with-answered
-    # task must keep its session for the eventual resume.
-    detail = task_state(auth, review_task)
-    verdict_block = [b for b in detail["blocks"]
-                     if b["block_type"] == "review"][0]
-    act(auth, verdict_block["answer_action"], {"verdict": "accept"})
-    reviewer.kill()
-    act(auth, saddle_card(auth, "resume-reviewer")["refresh"], {})
-    check(wait_for(lambda: saddle_card(auth, "resume-reviewer")["status"] == "offline"
-                   or False, timeout=30, what="reviewer offline") is not None,
-          "the dead reviewer goes offline on the failed probe")
-    # Converted sleep(7): offline ticks run while the task MUST stay
-    # review-parked — a requeue during the window fails loudly.
-    check(quiet_window(quiet_seconds(),
-                       lambda: task_state(auth, review_task)["status"] == "review_requested",
-                       "review-parked task not requeued"),
-          "the review-parked task with an answered verdict is never requeued")
-    conn = db()
-    open_session = conn.execute(
-        "select count(*) from sessions where task_id = ? and ended_at is null",
-        (review_task,)).fetchone()[0]
-    conn.close()
-    check(open_session == 1,
-          "the review-parked task keeps its open session for the resume")
-
-    print("== phase 2: staleness — one probe decides ==")
-    # A silent-but-alive runner (long think, nothing to flush): after
-    # SADDLE_STALE_S (3s here) of silence it owes ONE exceptional
-    # GET /status; the answer keeps it running and the silence
-    # episode gets no second probe.
-    task_id_tmp = create_queued(auth, {
-        "project_id": "1",
-        "title": "Silent thinker",
-        "priority": "2",
-    })
-    thinker = task_id_tmp
-    check(wait_for(lambda: task_state(auth, thinker).get("status") == "working"
-                   or False, timeout=60, what="thinker working") is not None,
-          "silent thinker reaches working")
-    fake.silent = True  # the daemon goes quiet mid-round (alive)
-    probes_at_start = fake.status_hits
-    check(wait_for(lambda: fake.status_hits > probes_at_start or False,
-                   timeout=30, what="exceptional probe arrives") is not None,
-          "a silent runner gets its exceptional GET /status probe")
-    # Converted sleep(8)+sleep(6): a quiet window across several
-    # ticks in which the probe count MUST NOT move — a second probe
-    # (the poll drumbeat this guards against) fails loudly.
-    second_window = fake.status_hits
-    check(quiet_window(quiet_seconds(),
-                       lambda: fake.status_hits == second_window,
-                       "no second staleness probe"),
-          "the silence episode is probed exactly once (no poll drumbeat)")
-    check(task_state(auth, thinker).get("status") == "working"
-          and saddle_card(auth, "fake-saddle")["status"] == "busy",
-          "the answered probe keeps the task running (no requeue)")
-    # Output flows again: the episode ends, the clock resets.
-    fake.silent = False
-    fake.push_chunks(["resumed output\r\n"])
-    check(wait_task_done(auth, thinker, timeout=60) is not None,
-          "the silent thinker completes once output flows again")
-
-    # The daemon vanishing mid-task: silence for the window, the
-    # probe fails, the task requeues with an agent comment and the
-    # saddle goes offline.
-    task_id_tmp = create_queued(auth, {
-        "project_id": "1",
-        "title": "Vanish victim",
-        "priority": "2",
-    })
-    vanish = task_id_tmp
-    check(wait_for(lambda: task_state(auth, vanish).get("status") == "working"
-                   or False, timeout=60, what="vanish victim working") is not None,
-          "vanish victim reaches working")
-    fake.kill()
-    check(wait_for(lambda: saddle_card(auth, "fake-saddle")["status"] == "offline" or False,
-                   timeout=60, what="daemon death -> offline") is not None,
-          "vanishing daemon drives the saddle offline (failed staleness probe)")
-    check(wait_for(lambda: any("unreachable" in c["body"]
-                               and c.get("is_system")
-                               for c in task_state(auth, vanish).get("comments", []))
-                   or False, timeout=30, what="unreachable comment") is not None,
-          "the affected task gets an unreachable system row (never an agent comment)")
-    check(task_state(auth, vanish)["status"] == "queued",
-          "the task requeues after the daemon death")
-    card = saddle_card(auth, "fake-saddle")
-    check(card.get("health") == "offline",
-          "health badge reports offline")
-
-    # The unreachable row flag marks the detection window: a task the
-    # web still sees working while its saddle is offline/fenced, before
-    # the requeue pass moves it. Controlled window (the real
-    # transitions above are atomic with their requeues).
-    conn = db()
-    conn.execute("insert into tasks (project_id, title, status, priority,"
-                 " created_at) values (1, 'Unreachable row', 'working', 5,"
-                 " strftime('%s','now'))")
-    unreachable_row = conn.execute("select max(id) from tasks").fetchone()[0]
-    conn.execute("insert into sessions (task_id, saddle_id, started_at)"
-                 " values (?, ?, strftime('%s','now'))", (unreachable_row, fake_id))
-    conn.commit()
-    conn.close()
-    check(wait_for(lambda: (lambda row: row.get("unreachable") is True)(
-                        [t for t in slot_public(auth, "/tasks", "tasks")["tasks"]
-                         if int(t["id"]) == unreachable_row][0]) or False,
-                   timeout=20, what="unreachable flag") is not None,
-          "queue row shows the unreachable state in the window")
-
-    print("== phase 1: saddles.token is the single credential store (arch 24) ==")
-    # The legacy api_tokens table and every fallback read died with the
-    # poll era: a restart proves the migrated schema carries no
-    # api_tokens table, the row token survives and still authenticates,
-    # and a legacy-shaped token string authorises nothing (no fallback
-    # read exists to honour it). Fixture: this shard's own racer.
-    fake2 = FakeSaddle()
-    fake2.ask_on_register = False
-    fake2.serve(port=free_port())
-    saddles_state = slot_public(auth, "/saddles", "saddles")
-    act(auth, saddles_state["register"], {"name": "racer-two",
-                                          "host": "127.0.0.1:%d" % fake2.port})
-    racer_two_id = int([s for s in slot_public(auth, "/saddles", "saddles")["saddles"]
-                        if s["name"] == "racer-two"][0]["id"])
-    racer_two_token = [s for s in slot_public(auth, "/saddles", "saddles")["saddles"]
-                       if s["name"] == "racer-two"][0]["token"]
-
-    app.terminate()
-    app.wait(timeout=10)
-    app = start_app()
-    auth = login("admin", "adminpass123")
-    ctx.app = app  # teardown tracks the restarted process
-    ctx.auth = auth
-
-    def schema_tables():
-        conn = db()
-        try:
-            return {row[0] for row in conn.execute(
-                "select name from sqlite_master where type = 'table'")}
-        finally:
-            conn.close()
-
-    check("api_tokens" not in schema_tables(),
-          "the fresh schema carries no api_tokens table (arch 24)")
-    conn = db()
-    row_token = conn.execute("select token from saddles where id = ?",
-                             (racer_two_id,)).fetchone()[0]
-    conn.close()
-    check(row_token == racer_two_token and (row_token or "").startswith("saddle-"),
-          "the per-saddle row token survives the restart unchanged")
-    status, _ = saddle_api("POST", "/api/saddle/next-task", racer_two_token)
-    check(status in (200, 204),
-          "the row token still authenticates after the restart")
-    status, _ = saddle_api("POST", "/api/saddle/next-task", "saddle-legacy-copied-token")
-    check(status == 401,
-          "a legacy api_tokens-shaped credential authorises nothing (fallback gone)")
-    fake2.token = racer_two_token
-    fake2.ask_now()
-    check(True, "the fleet re-asks after the restart (sleeping re-established)")
-
-
-# =============================================================================
-# Bundle: push — plan 11 task E: real Web Push over VAPID. VAPID
-# persistence, the service worker, subscription CRUD + validation,
-# notify-me prefs, the block/lifecycle dispatch matrix (global vs
-# opted-in), 410 pruning, retry-next-tick delivery and protocol-level
-# payload verification (RFC 8291 decryption + ES256 JWT) against the
-# fake push service.
-# =============================================================================
-
-def bundle_push(ctx):
-    auth, fake, fake_id, fake_token = ctx.auth, ctx.fake, ctx.fake_id, ctx.fake_token
-
-    def subscription_count(endpoint):
-        conn = db()
-        try:
-            return conn.execute(
-                "select count(*) from push_subscriptions where endpoint = ?",
-                (endpoint,)).fetchone()[0]
-        finally:
-            conn.close()
-
-    print("== task E: service worker asset ==")
-    status, sw = http("GET", "/sw.js", timeout=15)
-    check(status == 200 and "addEventListener('push'" in sw
-          and "notificationclick" in sw and "clients.openWindow" in sw,
-          "the service worker serves at the origin root with push + click routing")
-
-    print("== task E: VAPID keypair generation + persistence ==")
-    config = json.load(open(os.path.join(WORK, "web-config.json")))
-    vapid = config.get("vapid") or {}
-    check(bool(vapid.get("public_key")) and bool(vapid.get("private_key")),
-          "the VAPID keypair persists into web-config.json's vapid section")
-    vapid_private_key = ec.derive_private_key(
-        int.from_bytes(b64url_dec(vapid["private_key"]), "big"), ec.SECP256R1())
-    derived_public = vapid_private_key.public_key().public_bytes(
-        Encoding.X962, PublicFormat.UncompressedPoint)
-    check(b64url_dec(vapid["public_key"]) == derived_public,
-          "the persisted public key matches the private scalar (a valid P-256 pair)")
-    dash = slot_public(auth, "/", "dashboard")
-    check(dash.get("push_vapid_key") == vapid["public_key"],
-          "the dashboard exposes the same VAPID key to subscribers")
-    check(dash.get("push_subscribed") is False and bool(dash.get("push_subscribe")),
-          "the bell starts unsubscribed and carries the subscribe action")
-
-    print("== task E: subscription CRUD + auth validation ==")
-    browser = ec.generate_private_key(ec.SECP256R1())
-    browser_public = browser.public_key().public_bytes(
-        Encoding.X962, PublicFormat.UncompressedPoint)
-    browser_auth = os.urandom(16)
-    subscribe_fields = {"p256dh": b64url(browser_public), "auth": b64url(browser_auth)}
-    valid_endpoint = "http://127.0.0.1:1/x"
-    check("absolute http(s)" in (action_notify(act(auth, dash["push_subscribe"],
-        {"endpoint": "ftp://example.com/push", **subscribe_fields})) or ""),
-        "a non-http endpoint is rejected")
-    check("p256dh" in (action_notify(act(auth, dash["push_subscribe"],
-        {"endpoint": valid_endpoint, "p256dh": b64url(os.urandom(64)),
-         "auth": subscribe_fields["auth"]})) or ""),
-        "a malformed p256dh point is rejected")
-    check("auth" in (action_notify(act(auth, dash["push_subscribe"],
-        {"endpoint": valid_endpoint, "p256dh": subscribe_fields["p256dh"],
-         "auth": b64url(os.urandom(15))})) or ""),
-        "a malformed auth secret is rejected")
-
-    push = FakePushService()
-    push.serve()
-    endpoint_main = push.url("/main")
-    act(auth, dash["push_subscribe"],
-        {"endpoint": endpoint_main, **subscribe_fields})
-    conn = db()
-    rows = conn.execute("select user_id, p256dh, auth from push_subscriptions"
-                        " where endpoint = ?", (endpoint_main,)).fetchall()
-    admin_id = conn.execute("select id from spry_users where username = 'admin'"
-                            ).fetchone()[0]
-    conn.close()
-    check(len(rows) == 1 and rows[0][0] == admin_id,
-          "a valid subscription stores against the signed-in user")
-    # Re-subscribing the same endpoint replaces (never duplicates).
-    rotated_auth = os.urandom(16)
-    act(auth, dash["push_subscribe"],
-        {"endpoint": endpoint_main, "p256dh": subscribe_fields["p256dh"],
-         "auth": b64url(rotated_auth)})
-    conn = db()
-    rows = conn.execute("select auth from push_subscriptions where endpoint = ?",
-                        (endpoint_main,)).fetchall()
-    conn.close()
-    check(len(rows) == 1 and rows[0][0] == b64url(rotated_auth),
-          "re-subscribing an endpoint replaces its keys in place")
-
-    print("== task E: notify-me pref persistence ==")
-    act(auth, slot_public(auth, "/tasks", "tasks")["create"],
-        {"project_id": "1", "title": "Push pref task", "priority": "5"})
-    pref_task = task_id_of("Push pref task")
-    act(auth, task_state(auth, pref_task)["toggle_notify"], {})
-    conn = db()
-    check(conn.execute("select count(*) from task_notify_prefs where task_id = ?"
-                       " and user_id = ?", (pref_task, admin_id)).fetchone()[0] == 1,
-          "Notify me persists a task_notify_prefs row for the user")
-    conn.close()
-    check(task_state(auth, pref_task).get("notify_me") is True,
-          "the task slot reflects notify_me after the toggle")
-    act(auth, task_state(auth, pref_task)["toggle_notify"], {})
-    conn = db()
-    check(conn.execute("select count(*) from task_notify_prefs where task_id = ?",
-                       (pref_task,)).fetchone()[0] == 0,
-          "Don't notify me removes the pref row")
-    conn.close()
-    check(task_state(auth, pref_task).get("notify_me") is False,
-          "the task slot reflects the opt-out")
-
-    print("== task E: dispatch matrix — global blocks vs opted-in lifecycle ==")
-    # Two "browsers" for admin (/main, /gone) and one for another user
-    # (id 999, rows seeded directly — push targeting is per user).
-    endpoint_gone = push.url("/gone")
-    push.status_for["/gone"] = 410
-    act(auth, dash["push_subscribe"],
-        {"endpoint": endpoint_gone, **subscribe_fields})
-    other_browser = ec.generate_private_key(ec.SECP256R1())
-    other_public = other_browser.public_key().public_bytes(
-        Encoding.X962, PublicFormat.UncompressedPoint)
-    other_auth = os.urandom(16)
-    endpoint_other = push.url("/other")
-    conn = db()
-    conn.execute("insert into push_subscriptions (user_id, endpoint, p256dh, auth,"
-                 " created_at) values (999, ?, ?, ?, strftime('%s','now'))",
-                 (endpoint_other, b64url(other_public), b64url(other_auth)))
-    conn.commit()
-    conn.close()
-
-    # Task 1: admin opted in via the UI toggle; the other user is not.
-    # Baselines are captured BEFORE the enqueue: the first-start push
-    # fires at the allocation, the instant the dispatch lands.
-    act(auth, slot_public(auth, "/tasks", "tasks")["create"],
-        {"project_id": "1", "title": "Push lifecycle task", "priority": "5"})
-    task1 = task_id_of("Push lifecycle task")
-    act(auth, task_state(auth, task1)["toggle_notify"], {})
-    main_before = len(push.hits("/main"))
-    other_before = len(push.hits("/other"))
-    gone_before = len(push.hits("/gone"))
-    enqueue_task(auth, task1)
-    check(wait_for(lambda: fake.running_task == task1 or False, timeout=30,
-                   what="task 1 assignment") is not None,
-          "task 1 dispatches to the fake daemon")
-    task1_session = fake.session_id
-    check(wait_for(lambda: len(push.hits("/main")) > main_before, timeout=15,
-                   what="first-start push to the opted-in admin") is not None,
-          "first start notifies the opted-in user's subscription")
-    check(wait_for(lambda: len(push.hits("/gone")) > gone_before, timeout=15,
-                   what="first-start push to the gone endpoint") is not None,
-          "first start reaches every subscription of the opted-in user")
-    check(quiet_window(quiet_seconds(),
-                       lambda: len(push.hits("/other")) == other_before,
-                       "no first-start push to the not-opted-in user"),
-          "first start never reaches users without the notify pref")
-    check(wait_task_done(auth, task1, timeout=60) is not None,
-          "task 1 completes")
-    _, done_payload = decrypt_webpush(push.hits("/main")[-1], browser,
-                                      browser_public, rotated_auth)
-    check(done_payload["title"] == "Push lifecycle task — completed"
-          and done_payload["url"] == "/tasks/%d" % task1,
-          "completion notifies the opted-in user (decrypted payload)")
-    check(len(push.hits("/other")) == other_before,
-          "completion stays with the opted-in user only")
-    check(wait_for(lambda: subscription_count(endpoint_gone) == 0, timeout=15,
-                   what="410 endpoint pruned") is not None,
-          "a 410 Gone endpoint is pruned from push_subscriptions")
-
-    # Block events go to EVERY push-subscribed user globally. The
-    # poll-era /update raise is gone: a live (non-terminal) host task
-    # with an open session on the fake carries the block through the
-    # results push — task1 is done and terminal pushes are consumed
-    # silently, so the host is its own fixture row.
-    conn = db()
-    conn.execute("insert into tasks (project_id, title, status, priority,"
-                 " created_at) values (1, 'Push block host', 'working', 5,"
-                 " strftime('%s','now'))")
-    push_host = conn.execute("select max(id) from tasks").fetchone()[0]
-    conn.execute("insert into sessions (task_id, saddle_id, started_at)"
-                 " values (?, ?, strftime('%s','now'))", (push_host, fake_id))
-    push_host_session = conn.execute(
-        "select max(id) from sessions").fetchone()[0]
-    conn.commit()
-    conn.close()
-
-    def raise_global_block(question):
-        return saddle_api("POST", "/api/saddle/results", fake_token, {
-            "session_id": push_host_session, "state": "blocked",
-            "block": {"question": question, "type": "question"}})
-
-    main_before = len(push.hits("/main"))
-    other_before = len(push.hits("/other"))
-    raise_global_block("Global question for everyone?")
-    check(wait_for(lambda: len(push.hits("/main")) > main_before
-                   and len(push.hits("/other")) > other_before, timeout=15,
-                   what="global block push") is not None,
-          "a raised block notifies every push-subscribed user globally")
-    block_hit = push.hits("/other")[-1]
-    _, payload = decrypt_webpush(block_hit, other_browser, other_public, other_auth)
-    check(payload["title"] == "Push block host — question raised"
-          and payload["body"] == "Global question for everyone?"
-          and payload["url"] == "/tasks/%d" % push_host,
-          "the block payload carries task title + kind, question and click URL (%s)"
-          % payload)
-    ciphertext_len = len(block_hit["body"]) - (21 + 65)
-    envelope = block_hit["body"]
-    record_size = int.from_bytes(envelope[16:20], "big")
-    # rs = plaintext + delimiter (1) + tag (16) == ciphertext-with-tag len.
-    check(record_size == ciphertext_len,
-          "the RFC 8291 envelope record size covers payload + delimiter + tag")
-    claims = verify_vapid(block_hit, vapid["public_key"], vapid["private_key"])
-    check(claims.get("aud") == "http://127.0.0.1:%d" % push.port
-          and claims.get("sub", "").startswith("mailto:")
-          and claims.get("exp", 0) > time.time(),
-          "the VAPID JWT verifies: aud = the endpoint origin, mailto sub, future exp")
-    check(block_hit["headers"].get("ttl") == "60"
-          and block_hit["headers"].get("content-type") == "application/octet-stream",
-          "the push POST carries TTL and the encrypted content type")
-
-    # Task 2: only the OTHER user opted in — start + failure reach them
-    # alone. Baseline again before the enqueue (first start fires at
-    # the allocation).
-    fake.fail_next = True
-    act(auth, slot_public(auth, "/tasks", "tasks")["create"],
-        {"project_id": "1", "title": "Push failure task", "priority": "5"})
-    task2 = task_id_of("Push failure task")
-    conn = db()
-    conn.execute("insert into task_notify_prefs (task_id, user_id) values (?, 999)",
-                 (task2,))
-    conn.commit()
-    conn.close()
-    main_before2 = len(push.hits("/main"))
-    other_before2 = len(push.hits("/other"))
-    enqueue_task(auth, task2)
-    check(wait_for(lambda: fake.running_task == task2 or False, timeout=30,
-                   what="task 2 assignment") is not None,
-          "task 2 dispatches (scripted to fail)")
-    check(wait_for(lambda: task_state(auth, task2)["status"] == "failed"
-                   or False, timeout=30, what="task 2 failed") is not None,
-          "task 2 fails")
-    check(wait_for(lambda: len(push.hits("/other")) >= other_before2 + 2,
-                   timeout=15, what="opted-in user's started+failed pushes"),
-          "the opted-in user gets first start AND failure for the task")
-    started_hit = [hit for hit in push.hits("/other")[other_before2:]][0]
-    _, started_payload = decrypt_webpush(started_hit, other_browser,
-                                         other_public, other_auth)
-    check(started_payload["title"] == "Push failure task — started",
-          "the first-start payload names task + kind (%s)" % started_payload)
-    _, failure_payload = decrypt_webpush(push.hits("/other")[-1], other_browser,
-                                         other_public, other_auth)
-    check(failure_payload["title"] == "Push failure task — failed"
-          and failure_payload["url"] == "/tasks/%d" % task2,
-          "the failure payload names the task and links its page")
-    check(len(push.hits("/main")) == main_before2,
-          "an agent failure never reaches users without the pref")
-
-    print("== task E: retry next tick (best-effort delivery) ==")
-    endpoint_flaky = push.url("/flaky")
-    act(auth, dash["push_subscribe"],
-        {"endpoint": endpoint_flaky, **subscribe_fields})
-    push.fail_next["/flaky"] = 1
-    flaky_before = len(push.hits("/flaky"))
-    raise_global_block("Flaky delivery question?")
-    check(wait_for(lambda: len(push.hits("/flaky")) >= flaky_before + 2,
-                   timeout=20, what="flaky endpoint retried") is not None,
-          "a failed send retries on the next dispatcher tick and lands")
-
-    print("== plan 12: goal notifications — blocks/success/failure always ==")
-    # Goal blocks, completion approval and failure push to EVERY
-    # subscribed user (the mirror on the goal-run task stays quiet).
-    def goal_state(goal_id):
-        return slot_public(auth, "/goals/%d" % goal_id, "goal")
-
-    push_goal = None
-    act(auth, slot_public(auth, "/goals", "goals")["create"], {
-        "project_id": "1", "title": "Push goal", "brief": "Notifies everyone.",
-        "branch_name": "goal/push"})
-    conn = db()
-    row = conn.execute("select id from goals where title = 'Push goal'").fetchone()
-    conn.close()
-    push_goal = int(row[0])
-    fake.goal_script = [("plan", "# Push plan\n\n1. Ring the bells")]
-    main_before = len(push.hits("/main"))
-    other_before = len(push.hits("/other"))
-    act(auth, goal_state(push_goal)["start"], {})
-    check(wait_for(lambda: goal_state(push_goal)["status"] == "plan_review" or False,
-                   timeout=60, what="push goal enters plan review") is not None,
-          "the push goal reaches plan review")
-    check(wait_for(lambda: len(push.hits("/main")) > main_before
-                   and len(push.hits("/other")) > other_before, timeout=15,
-                   what="goal plan-review push") is not None,
-          "a goal plan review notifies every subscribed user globally")
-    _, plan_payload = decrypt_webpush(push.hits("/other")[-1], other_browser,
-                                      other_public, other_auth)
-    check("Push goal" in plan_payload["title"] and "plan" in plan_payload["title"]
-          and plan_payload["url"] == "/goals/%d" % push_goal,
-          "the goal block payload carries the goal title + click URL (%s)"
-          % plan_payload)
-    main_before = len(push.hits("/main"))
-    fake.goal_script = [("suspend",)]
-    act(auth, goal_state(push_goal)["plan_pending_block"]["answer_action"],
-        {"answer": "Plan approved. Proceed with implementation."})
-    check(wait_for(lambda: goal_state(push_goal)["status"] == "active" or False,
-                   timeout=30, what="push goal active") is not None,
-          "the push goal activates")
-    check(quiet_window(3, lambda: len(push.hits("/main")) == main_before,
-                       "no push for an internal resume"),
-          "the goal agent's own park/resume does not notify (internal)")
-
-    # `saddle failure` in goal context fails the goal — global push.
-    fake.goal_script = [("fail", "the harness collapsed")]
-    other_before2 = len(push.hits("/other"))
-    main_before2 = len(push.hits("/main"))
-    conn = db()
-    conn.execute("insert into tasks (project_id, goal_id, kind, title, status,"
-                 " priority, completed_at, created_at) values (1, ?, 'task',"
-                 " 'Warm', 'done', 5,"
-                 " strftime('%s','now'),"
-                 " strftime('%s','now','-30 seconds'))", (push_goal,))
-    conn.commit()
-    conn.close()
-    check(wait_for(lambda: goal_state(push_goal)["status"] == "failed" or False,
-                   timeout=60, what="goal failure lands") is not None,
-          "the goal agent's failure fails the goal")
-    check(wait_for(lambda: len(push.hits("/other")) > other_before2
-                   and len(push.hits("/main")) > main_before2, timeout=15,
-                   what="goal failure push") is not None,
-          "a goal failure notifies every subscribed user globally")
-    _, fail_payload = decrypt_webpush(push.hits("/other")[-1], other_browser,
-                                      other_public, other_auth)
-    check("Push goal" in fail_payload["title"] and "failed" in fail_payload["title"]
-          and fail_payload["url"] == "/goals/%d" % push_goal,
-          "the goal failure payload carries the goal title + click URL (%s)"
-          % fail_payload)
-
-    # Completion approval pushes "complete" globally (success always).
-    act(auth, slot_public(auth, "/goals", "goals")["create"], {
-        "project_id": "1", "title": "Push done goal", "brief": "Completes.",
-        "branch_name": "goal/push-done"})
-    conn = db()
-    row = conn.execute("select id from goals where title = 'Push done goal'").fetchone()
-    conn.close()
-    done_goal = int(row[0])
-    fake.goal_script = [("plan", "# Done plan")]
-    act(auth, goal_state(done_goal)["start"], {})
-    check(wait_for(lambda: goal_state(done_goal)["status"] == "plan_review" or False,
-                   timeout=60, what="done goal plan review") is not None,
-          "the done goal reaches plan review")
-    fake.goal_script = [("done", "# Completion\n\nShipped.")]
-    act(auth, goal_state(done_goal)["plan_pending_block"]["answer_action"],
-        {"answer": "Plan approved. Proceed with implementation."})
-    check(wait_for(lambda: goal_state(done_goal)["status"] == "completion_review"
-                   or False, timeout=60, what="done goal completion review") is not None,
-          "the approved done goal reaches completion review")
-    main_before = len(push.hits("/main"))
-    act(auth, goal_state(done_goal)["completion_pending_block"]["answer_action"],
-        {"answer": "Review approved. Continue with the task."})
-    check(wait_for(lambda: goal_state(done_goal)["status"] == "complete" or False,
-                   timeout=30, what="done goal completes") is not None,
-          "the done goal completes")
-    check(wait_for(lambda: len(push.hits("/main")) > main_before, timeout=15,
-                   what="goal success push") is not None,
-          "a goal completion notifies every subscribed user globally")
-    _, done_goal_payload = decrypt_webpush(push.hits("/main")[-1], browser,
-                                           browser_public, rotated_auth)
-    check("Push done goal" in done_goal_payload["title"]
-          and "complete" in done_goal_payload["title"]
-          and done_goal_payload["url"] == "/goals/%d" % done_goal,
-          "the goal success payload carries the goal title + click URL (%s)"
-          % done_goal_payload)
-
-    print("== task E: unsubscribe removes the subscription ==")
-    dash = slot_public(auth, "/", "dashboard")
-    check(dash.get("push_subscribed") is True,
-          "the bell shows subscribed while endpoints exist")
-    act(auth, dash["push_unsubscribe"], {"endpoint": endpoint_main})
-    check(subscription_count(endpoint_main) == 0,
-          "unsubscribing removes the endpoint's row")
-
-
-# =============================================================================
-# Bundle: goals — the plan-12 goal lifecycle: creation with branch-name
-# uniqueness, the start → planning → plan review → active flow with
-# revisions, the goal agent's task fan-out through the task CLI
-# callbacks (ownership + creator-only enqueue), the event-driven
-# coalesced resume, pause/resume queueing, the completion review with
-# branch push state, the cancel cascade, and the human tasks'
-# auto-enqueue-after predecessor.
-# =============================================================================
-
-def bundle_goals(ctx):
-    auth, fake, fake_id, fake_token = ctx.auth, ctx.fake, ctx.fake_id, ctx.fake_token
-    app = ctx.app
-
-    def goal_state(goal_id):
-        return slot_public(auth, "/goals/%d" % goal_id, "goal")
-
-    def create_goal(fields):
-        act(auth, slot_public(auth, "/goals", "goals")["create"], fields)
-        rows = [g for g in slot_public(auth, "/goals", "goals")["goals"]
-                if g["title"] == fields["title"]]
-        return int(rows[0]["id"])
-
-    print("== plan 12: goal creation, validation, lifecycle actions ==")
-    goal1 = create_goal({"project_id": "1", "title": "Ship the flange",
-                         "brief": "Make the flange module production-grade.",
-                         "branch_name": "goal/flange", "priority": "3"})
-    state = goal_state(goal1)
-    check(state["status"] == "draft" and state["display"] == "draft"
-          and state["branch_name"] == "goal/flange"
-          and state["base_branch"] == "main",
-          "a goal lands in draft with its branch pair")
-    check(state.get("start") is not None and state.get("cancel") is not None
-          and state.get("pause") is None,
-          "draft offers start + cancel only")
-    check(state["run_task_id"] == 0 and state["comments"] == [],
-          "a draft goal has no thread yet (the run task owns it)")
-    draft_page = http_get_page(auth, "/goals/%d" % goal1)
-    check('stm-if="goal.run_task_id &gt; 0" stm-action="goal.comment"' in draft_page
-          and "comments open with its run" in draft_page,
-          "the draft goal page gates the composer on the run (muted note until then)")
-    # Branch-name uniqueness: same name, same involved project → refuse.
-    duplicate_directives = act(auth, slot_public(auth, "/goals", "goals")["create"], {
-        "project_id": "1", "title": "Clash", "brief": "b", "branch_name": "goal/flange"})
-    check(any(d.get("type") == "notify" and d.get("kind") == "error"
-              and "goal/flange" in (d.get("message") or "")
-              for d in duplicate_directives),
-          "a live goal's branch name cannot be reused in an involved project (%s)"
-          % [d.get("message") for d in duplicate_directives if d.get("type") == "notify"])
-    conn = db()
-    conn.execute("insert into projects (name, git_url, default_branch, created_at)"
-                 " values ('other-repo', 'https://example.com/other.git', 'main',"
-                 " strftime('%s','now'))")
-    conn.commit()
-    conn.close()
-    goal_elsewhere = create_goal({"project_id": "2", "title": "Elsewhere",
-                                  "brief": "b", "branch_name": "goal/flange"})
-    check(goal_elsewhere > 0,
-          "the same branch name in a disjoint project is fine (one per repo)")
-    # Brief validation.
-    brief_directives = act(auth, slot_public(auth, "/goals", "goals")["create"], {
-        "project_id": "1", "title": "No brief", "brief": "  ", "branch_name": "goal/x1"})
-    check(any(d.get("type") == "notify" and d.get("kind") == "error"
-              and "brief" in (d.get("message") or "").lower()
-              for d in brief_directives),
-          "an empty brief rejects")
-
-    # Start: planning + the goal-run internal task.
-    act(auth, state["start"], {})
-    state = goal_state(goal1)
-    check(state["status"] == "planning" and state.get("start") is None,
-          "start moves the goal to planning")
-    conn = db()
-    run_row = conn.execute(
-        "select id, kind, mode, creator, goal_id, priority, status from tasks"
-        " where goal_id = ? and kind = 'goal_run'", (goal1,)).fetchone()
-    conn.close()
-    check(run_row is not None and run_row[1] == "goal_run"
-          and run_row[2] == "orchestrate" and run_row[3] == "goal"
-          and run_row[4] == goal1 and run_row[5] == 3
-          and run_row[6] in ("queued", "assigned", "working"),
-          "start creates the goal-run task (orchestrate, priority 3, creator goal,"
-          " queued)")
-    run_task = int(run_row[0])
-    check(goal_state(goal1)["run_task_id"] == run_task,
-          "the goal state carries the run task id")
-    check(any(e["kind"] == "started" for e in goal_state(goal1)["events"]),
-          "the narrative records the start")
-
-    print("== feedback: goal-agent runs are hidden from every task listing ==")
-    # The internal run task never lists anywhere tasks are browsed —
-    # only the goal page exposes it (worker tasks stay listed). The
-    # plan script is armed BEFORE the first dispatch so this section's
-    # waits never consume the round the plan-review flow below needs.
-    fake.goal_script = [("plan", "# Plan v1\n\n1. Add tests\n2. Ship")]
-    check(wait_for(lambda: task_state(auth, run_task)["status"]
-                   in ("assigned", "working") or False,
-                   timeout=60, what="run task dispatches") is not None,
-          "the run task reaches its saddle")
-    queue_rows = slot_public(auth, "/tasks", "tasks")["tasks"]
-    check(all(int(t["id"]) != run_task for t in queue_rows),
-          "the tasks queue never lists the goal-agent run task")
-    check(all(t["kind"] != "goal_run" for t in queue_rows),
-          "no goal_run rows leak into the queue at all")
-    project_state = slot_public(auth, "/projects/1", "project")
-    check(all(int(t["id"]) != run_task for t in project_state["tasks"]),
-          "the project page's task list excludes the run task")
-    dashboard = slot_public(auth, "/", "dashboard")
-    check(all(int(a["id"]) != run_task for a in dashboard["active_tasks"]),
-          "the dashboard's active tasks exclude the run task")
-    check(all(int(i["task_id"]) != run_task for i in dashboard["activity"]),
-          "the activity timeline never references the run task")
-    check(wait_for(lambda: int(next(
-              (s for s in slot_public(auth, "/", "dashboard")["saddles"]
-               if s["name"] == "fake-saddle"), {})
-          .get("current_goal_id") or 0) == goal1 or False,
-          timeout=30, what="saddle card links the goal") is not None,
-          "a saddle hosting the goal agent reads as supervising the goal")
-    fake_dash_card = next(s for s in slot_public(auth, "/", "dashboard")["saddles"]
-                          if s["name"] == "fake-saddle")
-    check(fake_dash_card["current_goal_title"] == "Ship the flange",
-          "the supervision link carries the goal title")
-
-    print("== plan 12: the goal agent plans, plan review, revisions ==")
-    # (The plan script was armed before the run's first dispatch — see
-    # the listing-hiding section above — so the first round submits it.)
-    check(wait_for(lambda: goal_state(goal1)["status"] == "plan_review" or False,
-                   timeout=120, what="goal agent submits its plan") is not None,
-          "the goal agent's plan push enters plan review")
-    state = goal_state(goal1)
-    check(task_state(auth, run_task)["status"] == "blocked",
-          "the goal-run task parks on the plan review")
-    # U3's plan-review counterpart: the run-task card never reads as a
-    # bare "blocked" while a review-shaped block parks it.
-    check(task_state(auth, run_task)["display"] == "awaiting your review",
-          "the run-task card reads 'awaiting your review' during the plan review (U3)")
-    pending = state.get("plan_pending_block")
-    check(pending and "# Plan v1" in (pending.get("body") or ""),
-          "the pending plan review carries the submitted markdown")
-    check(any(b["block_type"] == "plan" and b["is_plan_review"]
-              for b in state["blocks"]),
-          "the goal blocks list carries the pending plan block")
-
-    print("== feedback: goal visual identity ==")
-    # A goal never reads as a task at a glance: marked nav entry,
-    # iconed list page, and the dashboard pile's goal cards carry
-    # their own accent styling.
-    home_html = http_get_page(auth, "/")
-    check('class="nav-goal"' in home_html and "&#127919;" in home_html,
-          "the nav carries the marked 🎯 Goals entry beside Tasks")
-    check(any(p["item_type"] == "goal" for p in
-              slot_public(auth, "/", "dashboard")["pinned"]),
-          "the goal's pending block pins onto the dashboard pile")
-    check("'card goal-card'" in home_html and 'badge-kind-goal' in home_html,
-          "dashboard goal cards carry the distinct goal styling")
-    goals_html = http_get_page(auth, "/goals")
-    check("&#127919;" in goals_html and "goal-icon" in goals_html,
-          "the goals list page carries the goal icon")
-    goal_page_html = http_get_page(auth, "/goals/%d" % goal1)
-    check('class="card goal-head"' in goal_page_html and "goal-page" in goal_page_html,
-          "the goal page carries the goal-accented identity chrome")
-    # Reject with feedback: the agent revises.
-    fake.goal_script = [("plan", "# Plan v2\n\n1. Add tests\n2. Add docs\n3. Ship")]
-    reject_resume_index = len(fake.goal_assignments)
-    act(auth, pending["answer_action"], {"answer": "Add documentation please"})
-    check(wait_for(lambda: goal_state(goal1)["status"] == "plan_review" or False,
-                   timeout=60, what="revised plan enters review") is not None,
-          "feedback sends the agent back to planning; the revision re-enters review")
-    # The rejection resume carried NO context_update (nothing in the
-    # instruction context had changed).
-    check(all("context_update" not in p
-              for p in fake.goal_assignments[reject_resume_index:]),
-          "a resume without context changes carries no context_update")
-    state = goal_state(goal1)
-    revisions = state["plan_revisions"]
-    check(len(revisions) == 2
-          and revisions[0]["answered"] and "Add documentation please" in revisions[0]["answer"]
-          and not revisions[1]["answered"],
-          "rejected revisions stay as answered history (historical-blocks data)")
-    # Plan 16 S1 pin: goals.plan is accept-gated — the pending revision
-    # lives only in its block; nothing lands on the goal before accept.
-    conn = db()
-    plan_column = conn.execute(
-        "select plan from goals where id = ?", (goal1,)).fetchone()[0]
-    conn.close()
-    check((plan_column is None or plan_column == "")
-          and (state["plan"] or "") == "",
-          "goals.plan stays empty while the revision is only pending (accept-gated, S1)")
-    # Approve: goal.plan = v2, status active, agent resumes and parks.
-    # Plan 16 S2: the accept posts the verdict MARKER — the server
-    # resolves the goal-plan kind and owns the constant.
-    fake.goal_script = [("suspend",)]
-    pending = state["plan_pending_block"]
-    act(auth, pending["answer_action"], {"verdict": "accept"})
-    check(wait_for(lambda: goal_state(goal1)["status"] == "active" or False,
-                   timeout=60, what="approved plan activates the goal") is not None,
-          "approving the plan activates the goal")
-    state = goal_state(goal1)
-    check(state["plan"] == "# Plan v2\n\n1. Add tests\n2. Add docs\n3. Ship",
-          "the approved plan markdown is stored on the goal (the accept verdict's write)")
-    # The approval resume carries the plan delta as a context_update
-    # turn (the prompt-cache-friendly replacement for the daemon's
-    # old system-prompt refresh).
-    check(wait_for(lambda: len(fake.goal_assignments) > 0 and
-                   "context_update" in fake.goal_assignments[-1] or False,
-                   timeout=30, what="approval resume carries context_update") is not None,
-          "the plan-approval resume carries a context_update turn")
-    approval_update = fake.goal_assignments[-1]["context_update"]
-    check("Plan approved" in approval_update and "# Plan v2" in approval_update,
-          "the context_update summarises the approved plan markdown")
-    check(wait_for(lambda: task_state(auth, run_task)["status"] == "suspended"
-                   or False, timeout=60, what="goal agent parks after approval") is not None,
-          "the resumed goal agent parks (saddle suspend)")
-
-    print("== plan 12: task fan-out via the task CLI callbacks ==")
-    # The goal agent (parked, open session on its saddle) creates,
-    # enqueues and deletes its tasks through /api/saddle/task/*.
-    conn = db()
-    agent_session = conn.execute(
-        "select id from sessions where task_id = ? and ended_at is null",
-        (run_task,)).fetchone()[0]
-    conn.close()
-    status, body = saddle_api("POST", "/api/saddle/task/create", fake_token, {
-        "session_id": agent_session, "title": "Flange tests",
-        "mandate": "Write the test suite for the flange module.",
-        "mode": "test"})
-    check(status == 200 and body.get("ok") is True,
-          "task create under the goal succeeds (%s)" % body.get("error"))
-    fan_task = int(body["task_id"])
-    detail = task_state(auth, fan_task)
-    check(detail["status"] == "draft" and detail["mode"] == "test"
-          and detail["creator"] == "goal" and detail.get("goal_id") == goal1,
-          "the created task is a draft goal task with its mode and creator")
-    check(detail["task_branch"] == "task/%d-%d" % (goal1, fan_task)
-          and detail["branch_from"] == "goal/flange",
-          "goal worker tasks get ephemeral branches cut from the goal branch")
-    check(any(e["kind"] == "task-created" and int(e["task_id"]) == fan_task
-              for e in goal_state(goal1)["events"]),
-          "the narrative records the agent's task creation")
-
-    # Draft until the agent enqueues; humans may not (creator-only).
-    check(detail.get("enqueue") is None,
-          "the human Enqueue action is not offered for goal tasks (creator-only)")
-    status, body = saddle_api("POST", "/api/saddle/task/enqueue", fake_token, {
-        "session_id": agent_session, "task_id": fan_task})
-    check(status == 200 and task_state(auth, fan_task)["status"] == "queued",
-          "task enqueue by the goal agent queues the draft")
-    # Ownership + shape errors, verbatim for the CLI.
-    status, body = saddle_api("POST", "/api/saddle/task/enqueue", fake_token, {
-        "session_id": agent_session, "task_id": 999999})
-    check(status == 400 and "No task exists" in (body.get("error") or ""),
-          "enqueue of a missing task errors verbatim")
-    create_queued(auth, {"project_id": "1", "title": "Innocent bystander", "priority": "4"})
-    bystander = task_id_of("Innocent bystander")
-    status, body = saddle_api("POST", "/api/saddle/task/delete", fake_token, {
-        "session_id": agent_session, "task_id": bystander})
-    check(status == 400 and "does not belong to your goal" in (body.get("error") or ""),
-          "the goal agent cannot touch tasks outside its goal")
-    status, body = saddle_api("POST", "/api/saddle/task/create", fake_token, {
-        "session_id": agent_session, "title": "Bad mode", "mandate": "m", "mode": "party"})
-    check(status == 400 and "valid modes" in (body.get("error") or ""),
-          "an unknown mode rejects with the valid list")
-    status, body = saddle_api("POST", "/api/saddle/task/create", fake_token, {
-        "session_id": agent_session, "title": "Bad tag", "mandate": "m",
-        "capabilities": ["warp-drive"]})
-    check(status == 400 and "warp-drive" in (body.get("error") or "")
-          and "valid tags" in (body.get("error") or ""),
-          "an unknown capability tag rejects naming the valid set")
-    # A plain task's session is not a goal-agent identity.
-    status, body = saddle_api("POST", "/api/saddle/task/create", fake_token,
-                              {"session_id": 999999, "title": "x", "mandate": "m"})
-    check(status == 400 and "session" in (body.get("error") or ""),
-          "an unknown session_id errors verbatim")
-    # Delete: draft + owned.
-    status, body = saddle_api("POST", "/api/saddle/task/create", fake_token, {
-        "session_id": agent_session, "title": "Scratch task", "mandate": "m"})
-    scratch = int(body["task_id"])
-    status, body = saddle_api("POST", "/api/saddle/task/delete", fake_token, {
-        "session_id": agent_session, "task_id": scratch})
-    check(status == 200 and not any(
-        t["id"] == scratch for t in slot_public(auth, "/tasks", "tasks")["tasks"]),
-        "task delete removes the owned draft")
-    status, body = saddle_api("POST", "/api/saddle/task/delete", fake_token, {
-        "session_id": agent_session, "task_id": fan_task})
-    check(status == 400 and "draft" in (body.get("error") or ""),
-          "deleting a queued task refuses (draft only)")
-
-    print("== plan 12: goal context in the worker assignment + coalesced resume ==")
-    # The queued fan-out task dispatches to the daemon with the goal
-    # reference + ephemeral branch; its completion schedules the parked
-    # goal agent's resume (>= SADDLE_GOAL_RESUME_S after the event).
-    check(wait_for(lambda: any(int(p.get("task", {}).get("id") or 0) == fan_task
-                               for p in fake.start_payloads) or False,
-                   timeout=60, what="fan-out task dispatches") is not None,
-          "the goal worker task dispatches")
-    fan_payload = [p for p in fake.start_payloads
-                   if int(p.get("task", {}).get("id") or 0) == fan_task][-1]
-    goal_ctx = fan_payload.get("goal") or {}
-    check(goal_ctx.get("id") == goal1 and goal_ctx.get("branch") == "goal/flange"
-          and goal_ctx.get("base_branch") == "main"
-          and "flange module" in goal_ctx.get("brief", "")
-          and "# Plan v2" in goal_ctx.get("plan", ""),
-          "the worker assignment carries the goal context (read-only brief + plan)")
-    check(fan_payload.get("ephemeral_branch") == "task/%d-%d" % (goal1, fan_task)
-          and fan_payload.get("kind") == "task" and fan_payload.get("mode") == "test"
-          and fan_payload.get("creator") == "goal",
-          "the worker assignment carries the ephemeral branch + identity triplet")
-    check(wait_task_done(auth, fan_task, timeout=60) is not None,
-          "the goal worker task completes")
-    check(any(e["kind"] == "task-done" and int(e["task_id"]) == fan_task
-              for e in goal_state(goal1)["events"]),
-          "the narrative records the task's completion")
-    goal_runs_before = len(fake.goal_assignments)
-    check(wait_for(lambda: len(fake.goal_assignments) > goal_runs_before or False,
-                   timeout=30, what="parked goal agent resumes") is not None,
-          "the task-terminal event resumes the parked goal agent")
-    resume_payload = fake.goal_assignments[-1]
-    notice = resume_payload.get("resume_notice") or ""
-    check("Task statuses" in notice and "Flange tests" in notice
-          and "done" in notice,
-          "the resume notice batches ALL plan task statuses")
-    check("New completion reports" in notice and "fake daemon finished" in notice,
-          "the resume notice carries the new completion report")
-    check("context_update" not in resume_payload,
-          "a later resume with no context changes omits context_update entirely")
-    check(resume_payload.get("kind") == "goal_run"
-          and resume_payload.get("mode") == "orchestrate",
-          "the resumed goal agent carries its identity triplet")
-    # The resumed agent parked again (script): two events at once must
-    # coalesce into ONE resume within the window.
-    check(wait_for(lambda: task_state(auth, run_task)["status"] == "suspended"
-                   or False, timeout=60, what="goal agent re-parks") is not None,
-          "the resumed goal agent parks again")
-
-    print("== plan 16 S3: delta resume notices — one-line statuses, bodies once ==")
-    # A MULTI-LINE completion lands while the agent is parked. The next
-    # notice lists every status ONE-LINE (first line of the summary
-    # only) and embeds each NEW completion's full body exactly once —
-    # no statuses-section/reports-section double embedding. (Timestamps
-    # are second-granular: each fixture waits out the park's second so
-    # completed_at is strictly newer than suspended_at.)
-    def run_park_second_passed():
-        conn = db()
-        try:
-            row = conn.execute("select suspended_at from tasks where id = ?",
-                               (run_task,)).fetchone()
-            if not row or not row[0]:
-                return False
-            return time.time() > float(row[0]) + 1.05
-        finally:
-            conn.close()
-
-    check(wait_for(run_park_second_passed, timeout=30,
-                   what="S3 park second passes") is not None,
-          "the park stamp is in a strictly older second")
-    conn = db()
-    conn.execute("insert into tasks (project_id, goal_id, kind, title, status,"
-                 " priority, summary, completed_at, created_at) values (1, ?, 'task',"
-                 " 'Multiline report', 'done', 5,"
-                 " 'Headline: the flange calibrates\n\nBody: the full report with all"
-                 " the detail lines.',"
-                 " strftime('%s','now'),"
-                 " strftime('%s','now','-30 seconds'))", (goal1,))
-    conn.commit()
-    conn.close()
-    s3_before = len(fake.goal_assignments)
-    check(wait_for(lambda: len(fake.goal_assignments) > s3_before or False,
-                   timeout=60, what="S3 delta resume fires") is not None,
-          "the multiline completion resumes the parked agent")
-    s3_notice = fake.goal_assignments[-1].get("resume_notice") or ""
-    s3_statuses = s3_notice.split("## Task statuses", 1)[1] \
-                        .split("## New completion reports", 1)[0]
-    check("Headline: the flange calibrates" in s3_statuses
-          and "the full report with all the detail lines" not in s3_statuses,
-          "the statuses section carries ONE LINE per task (the summary's first line)")
-    check(s3_notice.count("the full report with all the detail lines.") == 1
-          and "### #" in s3_notice,
-          "each new completion's full body embeds EXACTLY ONCE (no double embedding)")
-    check(wait_for(lambda: task_state(auth, run_task)["status"] == "suspended"
-                   or False, timeout=60, what="S3 agent re-parks") is not None,
-          "the S3 agent re-parks")
-    # Size constant per event, not cumulative: the NEXT resume (armed
-    # with a fresh single-line completion) reports only the NEW body —
-    # the consumed multiline report never re-embeds.
-    check(wait_for(run_park_second_passed, timeout=30,
-                   what="S3 second park second passes") is not None,
-          "the second park stamp is in a strictly older second")
-    conn = db()
-    conn.execute("insert into tasks (project_id, goal_id, kind, title, status,"
-                 " priority, summary, completed_at, created_at) values (1, ?, 'task',"
-                 " 'Fresh completion', 'done', 5, 'fresh one-liner',"
-                 " strftime('%s','now'),"
-                 " strftime('%s','now','-30 seconds'))", (goal1,))
-    conn.commit()
-    conn.close()
-    s3_more = len(fake.goal_assignments)
-    check(wait_for(lambda: len(fake.goal_assignments) > s3_more or False,
-                   timeout=60, what="S3 second delta resume") is not None,
-          "the fresh completion resumes the agent again")
-    s3_next = fake.goal_assignments[-1].get("resume_notice") or ""
-    check("the full report with all the detail lines." not in s3_next
-          and "### #" in s3_next and "fresh one-liner" in s3_next,
-          "the consumed completion's body never re-embeds (notice size constant per event)")
-    check(wait_for(lambda: task_state(auth, run_task)["status"] == "suspended"
-                   or False, timeout=60, what="S3 agent parks a third time") is not None,
-          "the S3 agent parks for the pause section")
-
-    print("== feedback: goal page parity — progress feed, current activity, runs ==")
-    # The goal agent's runs feed the page's live surfaces: progress
-    # lines (green latest-first feed), the open round's newest
-    # activity line and its hosting saddle. Parked runs keep their
-    # open session, so fixtures land as rows without disturbing the
-    # scripted daemon.
-    conn = db()
-    open_run_session = conn.execute(
-        "select id from sessions where task_id = ? and ended_at is null",
-        (run_task,)).fetchone()[0]
-    conn.execute(
-        "insert into task_progress (task_id, summary, created_at)"
-        " values (?, 'Overseeing the flange fan-out', strftime('%s','now'))",
-        (run_task,))
-    conn.execute(
-        "insert into session_commands (session_id, command_text, type, started_at)"
-        " values (?, 'git -C demo log --oneline -5', 'command',"
-        " strftime('%s','now'))", (open_run_session,))
-    conn.commit()
-    conn.close()
-    # A manual refresh records the daemon's health snapshot (the
-    # parked daemon answers /status with its suspended state).
-    act(auth, saddle_card(auth, "fake-saddle")["refresh"], {})
-    state = goal_state(goal1)
-    check(state["progress"] and state["progress"][0]["summary"]
-          == "Overseeing the flange fan-out",
-          "the goal page carries the agent's live progress feed")
-    check(state["current_command"] == "git -C demo log --oneline -5"
-          and state["current_command_running"] is True,
-          "the current activity shows the open round's running command")
-    check(state["agent_saddle"] == "fake-saddle"
-          and "fake-saddle" in state["saddle_health"],
-          "the assigned agent saddle and its health display")
-    check(state["runs"] and state["runs"][0]["saddle_name"] == "fake-saddle"
-          and "session_id=" in state["runs"][0]["terminal_url"],
-          "the run table carries host saddles and deep-linked terminals")
-    goal_page = http_get_page(auth, "/goals/%d" % goal1)
-    check('stm-markdown="goal.brief"' in goal_page
-          and 'stm-markdown="goal.plan"' in goal_page
-          and 'stm-markdown="comment.body"' in goal_page
-          and 'stm-markdown="event.text"' in goal_page
-          and 'stm-markdown="block.body"' in goal_page,
-          "every long-form goal body renders through stm-markdown")
-    check('stm-attribute.href="run.terminal_url" target="_blank" rel="noopener"' in goal_page,
-          "the run table's terminal links open in a new tab")
-    check("progress-latest" in goal_page and "Agent progress" in goal_page,
-          "the green progress feed renders on the goal page")
-    # Plan revision history keeps its verdicts (approved + rejected).
-    revisions = goal_state(goal1)["plan_revisions"]
-    check(revisions[0]["answered"] is True and revisions[0]["approved"] is False
-          and revisions[1]["approved"] is True,
-          "plan revision history badges approved and rejected verdicts")
-
-    print("== plan 12: pause freezes supervision; events coalesce on resume ==")
-    state = goal_state(goal1)
-    act(auth, state["pause"], {})
-    check(goal_state(goal1)["status"] == "paused"
-          and goal_state(goal1).get("resume") is not None,
-          "an active goal pauses and offers resume")
-    # Terminal events under a paused goal queue without waking anybody.
-    # (The real completion path — complete_task — records the goal's
-    # task-done narrative event; the resume machinery keys on exactly
-    # those terminal kinds, never on the agent's own enqueue narrative.)
-    conn = db()
-    conn.execute("insert into tasks (project_id, goal_id, kind, title, status, priority,"
-                 " summary, completed_at, created_at) values (1, ?, 'task',"
-                 " 'Quiet task', 'done', 5, 'finished while paused',"
-                 " strftime('%s','now'), strftime('%s','now'))", (goal1,))
-    quiet_id = conn.execute("select max(id) from tasks").fetchone()[0]
-    conn.commit()
-    conn.close()
-    paused_runs = len(fake.goal_assignments)
-    check(quiet_window(quiet_seconds(),
-                       lambda: len(fake.goal_assignments) == paused_runs,
-                       "paused goal does not resume"),
-          "a paused goal's events queue without scheduling a resume")
-    state = goal_state(goal1)
-    act(auth, state["resume"], {})
-    check(goal_state(goal1)["status"] == "active",
-          "resume returns the goal to active")
-    check(wait_for(lambda: len(fake.goal_assignments) > paused_runs or False,
-                   timeout=30, what="queued events flush on resume") is not None,
-          "the queued events coalesce into the post-resume wake")
-    check("finished while paused" in (fake.goal_assignments[-1].get("resume_notice") or ""),
-          "the flushed notice reports the task that finished while paused")
-    check(wait_for(lambda: task_state(auth, run_task)["status"] == "suspended"
-                   or False, timeout=60, what="goal agent parks again") is not None,
-          "the goal agent parks again after the flush")
-    # The watermark consumed the flushed transition: with nothing new
-    # under the goal, no further resume fires (parked stays parked).
-    flushed_assignments = len(fake.goal_assignments)
-    check(quiet_window(quiet_seconds(),
-                       lambda: len(fake.goal_assignments) == flushed_assignments,
-                       "consumed watermark never re-fires"),
-          "the consumed watermark never re-fires a resume")
-
-    print("== plan 12: completion review, push state, accept ==")
-    # The daemon exposes goal-branch push state on /status; the web
-    # caches it on the goal when it probes the goal agent's saddle.
-    def status_extra():
-        return None
-    fake.status_extra = {"goal_branches": [
-        {"branch": "goal/flange", "pushed": True},
-        {"branch": "goal/other-repo", "pushed": False}]}
-    fake_card = saddle_card(auth, "fake-saddle")
-    act(auth, fake_card["refresh"], {})
-    check(wait_for(lambda: goal_state(goal1).get("push_branches") or False,
-                   timeout=30, what="push state lands on the goal") is not None,
-          "the daemon's /status goal_branches exposure caches on the goal")
-    branches = goal_state(goal1)["push_branches"]
-    check({(b["branch"], b["pushed"]) for b in branches}
-          == {("goal/flange", True), ("goal/other-repo", False)},
-          "the push state renders per branch")
-    # the daemon's real shape carries repo too — multi-repo rows stay
-    # distinguishable as "repo: branch" labels
-    fake.status_extra = {"goal_branches": [
-        {"repo": "repoa", "branch": "goal/flange", "pushed": True},
-        {"repo": "repob", "branch": "goal/flange", "pushed": False}]}
-    act(auth, fake_card["refresh"], {})
-    check(wait_for(lambda: {b["branch"] for b in goal_state(goal1).get("push_branches") or []}
-                   >= {"repoa: goal/flange"}, timeout=30,
-                   what="repo-qualified push state lands") is not None,
-          "repo-qualified goal_branches rows render as 'repo: branch'")
-    fake.status_extra = None
-
-    # `saddle done` in goal context: the completion review.
-    fake.goal_script = [("done", "# Completion\n\nThe flange ships.")]
-    # Wake the parked agent: a terminal transition newer than the
-    # watermark (the pause-flush consumed everything up to it, so arm
-    # one directly with a fresh row).
-    conn = db()
-    conn.execute("insert into tasks (project_id, goal_id, kind, title, status,"
-                 " priority, completed_at, created_at) values (1, ?, 'task',"
-                 " 'Warmup', 'done', 5,"
-                 " strftime('%s','now'),"
-                 " strftime('%s','now','-30 seconds'))", (goal1,))
-    conn.commit()
-    conn.close()
-    check(wait_for(lambda: goal_state(goal1)["status"] == "completion_review" or False,
-                   timeout=60, what="goal agent submits its completion") is not None,
-          "`saddle done` in goal context enters completion review")
-    state = goal_state(goal1)
-    # Plan 16 S1 (canonical-on-accept): while the review is PENDING the
-    # goal row carries NO report — the document lives only in its
-    # block; completion_report is written solely by the accept verdict.
-    conn = db()
-    pending_report_column = conn.execute(
-        "select completion_report from goals where id = ?", (goal1,)).fetchone()[0]
-    conn.close()
-    check((pending_report_column is None or pending_report_column == "")
-          and (state["completion_report"] or "") == ""
-          and "# Completion" in (state["completion_pending_block"].get("body") or "")
-          and state["completion_pending"] is True
-          and state["completion_pending_block"] is not None
-          and state["completion_pending_block"] is not False,
-          "the pending report lives ONLY in its block (goal row clean, S1)")
-    check(task_state(auth, run_task)["status"] == "blocked",
-          "the goal-run task parks on the completion review")
-    # Plan 16 S5 (U3): label reconciliation — the goal awaiting its
-    # completion review reads "awaiting your review" and the run-task
-    # status card agrees (never a bare "blocked" for a review park).
-    check(goal_state(goal1)["display"] == "awaiting your review"
-          and task_state(auth, run_task)["display"] == "awaiting your review",
-          "the goal and the run-task card agree: 'awaiting your review' (U3)")
-    check(state["compare_url"].endswith("/compare/main...goal/flange"),
-          "the completion review links the compare view")
-    # Reject first: feedback returns the goal to active. Plan 16 S2:
-    # the goal page's reject posts raw `feedback` — the SERVER wraps
-    # it with the completion-review prefix (byte-identical to the
-    # historical client-built answer).
-    fake.goal_script = [("suspend",)]
-    act(auth, state["completion_pending_block"]["answer_action"],
-        {"feedback": "Not done — the docs are missing"})
-    check(wait_for(lambda: goal_state(goal1)["status"] == "active" or False,
-                   timeout=30, what="rejected completion reactivates") is not None,
-          "rejecting the completion returns the goal to active")
-    conn = db()
-    rejected_answer = conn.execute(
-        "select answer from task_blocks where task_id = ?"
-        " and type = 'completion' order by id desc", (run_task,)).fetchone()[0]
-    conn.close()
-    check(rejected_answer
-          == "Review feedback received:\n\nNot done — the docs are missing",
-          "the completion rejection wraps feedback with the stable prefix (%r)"
-          % rejected_answer)
-    conn = db()
-    rejected_report = conn.execute(
-        "select completion_report from goals where id = ?", (goal1,)).fetchone()[0]
-    conn.close()
-    check(rejected_report is None or rejected_report == "",
-          "reject/revise leaves the goal row clean (no report leaked, S1)")
-    # Round 2: submit again and accept.
-    fake.goal_script = [("done", "# Completion v2\n\nThe flange ships, with docs.")]
-    conn = db()
-    conn.execute("insert into tasks (project_id, goal_id, kind, title, status,"
-                 " priority, completed_at, created_at) values (1, ?, 'task',"
-                 " 'Warmup2', 'done', 5,"
-                 " strftime('%s','now'),"
-                 " strftime('%s','now','-30 seconds'))", (goal1,))
-    conn.commit()
-    conn.close()
-    check(wait_for(lambda: goal_state(goal1)["status"] == "completion_review" or False,
-                   timeout=60, what="resubmitted completion") is not None,
-          "the agent resubmits its completion after feedback")
-    state = goal_state(goal1)
-    # Regression (plan-15 followup): the daemon's done-park ALSO pushes a
-    # review-kind block payload (question "Goal completion review", the
-    # real daemon's wording) after the done entry raised the completion
-    # row — the two paths must converge on ONE row, not twin reviews.
-    fake.push_results("blocked", block={
-        "question": "Goal completion review", "type": "review",
-        "body": "# Completion v2\n\nThe flange ships, with docs.",
-        "options": None})
-    conn = db()
-    rows = conn.execute(
-        "select count(*) from task_blocks where task_id = ?"
-        " and answer is null and type in ('completion','review')",
-        (run_task,)).fetchone()[0]
-    conn.close()
-    check(rows == 1,
-          "the daemon's review-kind completion push adopts the pending row (no twin)")
-    state = goal_state(goal1)
-    review_family_in_open = [b for b in state.get("open_blocks", [])
-                             if b.get("is_completion_review")]
-    check(state["completion_pending"] is True and len(review_family_in_open) == 1,
-          "the pending completion review renders ONCE — as the rich attention block")
-    fake.pending_block = None
-    # Raise-side single-row invariant (the render guard and the
-    # twin-answer sweep are gone — fresh DBs cannot hold pre-dedupe
-    # twins, and 4884259's raise-side cross-dedupe keeps it that way):
-    # a REDELIVERED review-kind completion push adopts the same pending
-    # row instead of stacking a twin.
-    fake.push_results("blocked", block={
-        "question": "Goal completion review", "type": "review",
-        "body": "# Completion v2\n\nThe flange ships, with docs.",
-        "options": None})
-    fake.pending_block = None
-    conn = db()
-    rows = conn.execute(
-        "select count(*) from task_blocks where task_id = ?"
-        " and answer is null and type in ('completion','review')",
-        (run_task,)).fetchone()[0]
-    conn.close()
-    check(rows == 1,
-          "a redelivered review-kind push adopts the pending row (raise-side single-row invariant)")
-    # Plan 15 C4: the completion-accept hard gate — the live probe
-    # flags still report repob's branch unpushed, so the operator's
-    # accept REFUSES with origin behind.
-    refusal = action_notify(act(auth, state["completion_pending_block"]["answer_action"],
-                                {"answer": "Review approved. Continue with the task."}))
-    check(goal_state(goal1)["status"] == "completion_review",
-          "the accept REFUSES while origin is behind (hard gate, live flags)")
-    # One parser, one label: the gate's refusal names the SAME repo-
-    # qualified unpushed row the chips render — both surfaces read
-    # GoalService.parse_goal_branches (the gate-vs-chips divergence is
-    # structurally gone).
-    branches = {(b["branch"], b["pushed"]) for b in goal_state(goal1)["push_branches"]}
-    check("repob: goal/flange" in (refusal or "")
-          and ("repob: goal/flange", False) in branches
-          and ("repoa: goal/flange", True) in branches,
-          "the refusal and the chips read ONE parser (same labels, same flags)")
-    # Push the branch daemon-side and probe again — the flags flip
-    # live (no goal-row write), and the accept goes through.
-    fake.status_extra = {"goal_branches": [
-        {"repo": "repoa", "branch": "goal/flange", "pushed": True},
-        {"repo": "repob", "branch": "goal/flange", "pushed": True}]}
-    act(auth, fake_card["refresh"], {})
-    check(wait_for(lambda: (goal_state(goal1).get("push_branches") or [])
-                   and all(b["pushed"] for b in goal_state(goal1)["push_branches"])
-                   or False, timeout=30, what="pushed flags land") is not None,
-          "the push chips derive from the LIVE probe flags")
-    conn = db()
-    no_push_column = conn.execute(
-        "select count(*) from pragma_table_info('goals')"
-        " where name = 'branch_push_state'").fetchone()[0] == 0
-    conn.close()
-    check(no_push_column,
-          "no stored push snapshot exists (F9: the goal row never records it)")
-    state = goal_state(goal1)
-    # The passing accept posts the verdict MARKER (the goal page's
-    # accept form shape, plan 16 S2) — the server resolves the
-    # completion kind and stores the stable approval wording.
-    act(auth, state["completion_pending_block"]["answer_action"],
-        {"verdict": "accept"})
-    check(wait_for(lambda: goal_state(goal1)["status"] == "complete" or False,
-                   timeout=30, what="accepted completion completes") is not None,
-          "accepting the completion completes the goal once origin is current")
-    state = goal_state(goal1)
-    conn = db()
-    accepted_report = conn.execute(
-        "select completion_report from goals where id = ?", (goal1,)).fetchone()[0]
-    conn.close()
-    check(state["terminal"] is True and state.get("cancel") is None
-          and accepted_report == "# Completion v2\n\nThe flange ships, with docs."
-          and "# Completion v2" in state["completion_report"],
-          "a complete goal is terminal with the WINNING block's body as its report (S1)")
-    check(wait_for(lambda: task_state(auth, run_task)["status"] == "done" or False,
-                   timeout=30, what="goal run task closes") is not None,
-          "approving the completion closes the goal-run task done")
-    conn = db()
-    twins_left = conn.execute(
-        "select count(*) from task_blocks where task_id = ?"
-        " and answer is null and type in ('completion','review')",
-        (run_task,)).fetchone()[0]
-    conn.close()
-    check(twins_left == 0,
-          "the verdict answered the pending completion-family row (single-row invariant)")
-
-    print("== plan 15 C3: the narrative derives from the recorded shape ==")
-    # Content equivalence with the old projection on this run's exact
-    # shape: every kind the goal_events projection produced, keyed the
-    # same way, plus the watermark and no-ingest guarantees.
-    narrative = goal_state(goal1)["events"]
-    kinds = [e["kind"] for e in narrative]
-    for expected in ("created", "started", "plan-submitted", "plan-rejected",
-                     "plan-approved", "task-created", "task-done",
-                     "completion-submitted", "completion-rejected", "goal-approved"):
-        check(expected in kinds,
-              "the derived narrative carries the %s row" % expected)
-    check(all(k != "task-enqueued" and k != "resumed" and k != "retry" for k in kinds),
-          "timestamp-less bookkeeping kinds never return")
-    stamps = [e["at_display"] for e in narrative if e.get("at_display")]
-    check(stamps == sorted(stamps, reverse=True),
-          "the narrative reads newest first")
-    conn = db()
-    no_event_table = conn.execute(
-        "select count(*) from sqlite_master where type = 'table'"
-        " and name = 'goal_events'").fetchone()[0] == 0
-    conn.close()
-    check(no_event_table,
-          "the goal_events table is gone (no narrative rows on ingest)")
-
-    print("== plan 12: cancel cascades to the goal's tasks ==")
-    goal2 = create_goal({"project_id": "1", "title": "Doomed goal",
-                         "brief": "This goal will be cancelled.",
-                         "branch_name": "goal/doomed"})
-    fake.goal_script = [("suspend",)]
-    act(auth, goal_state(goal2)["start"], {})
-    conn = db()
-    run2 = conn.execute("select id from tasks where goal_id = ? and kind = 'goal_run'",
-                        (goal2,)).fetchone()[0]
-    conn.close()
-    check(wait_for(lambda: task_state(auth, run2)["status"] == "suspended" or False,
-                   timeout=60, what="doomed goal agent parks") is not None,
-          "the doomed goal's agent parks")
-    conn = db()
-    agent_session2 = conn.execute(
-        "select id from sessions where task_id = ? and ended_at is null",
-        (run2,)).fetchone()[0]
-    conn.close()
-    status, body = saddle_api("POST", "/api/saddle/task/create", fake_token, {
-        "session_id": agent_session2, "title": "Doomed draft", "mandate": "m"})
-    doomed_draft = int(body["task_id"])
-    doomed_queued_task = None
-    status, body = saddle_api("POST", "/api/saddle/task/create", fake_token, {
-        "session_id": agent_session2, "title": "Doomed runner", "mandate": "m"})
-    doomed_runner = int(body["task_id"])
-    saddle_api("POST", "/api/saddle/task/enqueue", fake_token,
-               {"session_id": agent_session2, "task_id": doomed_runner})
-    act(auth, goal_state(goal2)["cancel"], {})
-    check(goal_state(goal2)["status"] == "cancelled",
-          "the goal cancels from active (parked-agent) state")
-    check(task_state(auth, run2)["status"] == "failed",
-          "the cascade cancels the goal agent's run task")
-    check(wait_for(lambda: task_state(auth, doomed_runner)["status"] == "failed"
-                   or False, timeout=30, what="cascade cancels the queued task") is not None,
-          "the cascade cancels the goal's queued task")
-    check(not any(t["id"] == doomed_draft
-                  for t in slot_public(auth, "/tasks", "tasks")["tasks"]),
-          "the cascade deletes the goal's draft tasks")
-    # A cancelled goal frees its branch name.
-    reuse = create_goal({"project_id": "1", "title": "Reused name",
-                         "brief": "b", "branch_name": "goal/doomed"})
-    check(reuse > goal2, "a cancelled goal's branch name is reusable")
-
-    print("== plan 13 B3: goal failure cascades to non-terminal tasks ==")
-    # A goal holding a draft, a queued task and a working task: the
-    # agent's failure cascades like a cancellation — drafts deleted (no
-    # orphan stays dispatchable), queued/working cancelled — and the
-    # narrative records the cascade.
-    collapse = create_goal({"project_id": "1", "title": "Collapse goal",
-                            "brief": "Fails with tasks in flight.",
-                            "branch_name": "goal/collapse"})
-    fake.goal_script = [("suspend",)]
-    act(auth, goal_state(collapse)["start"], {})
-    conn = db()
-    run3 = conn.execute("select id from tasks where goal_id = ? and kind = 'goal_run'",
-                        (collapse,)).fetchone()[0]
-    conn.close()
-    check(wait_for(lambda: task_state(auth, run3)["status"] == "suspended" or False,
-                   timeout=60, what="collapse goal agent parks") is not None,
-          "the collapse goal's agent parks first")
-    conn = db()
-    run3_session = conn.execute(
-        "select id from sessions where task_id = ? and ended_at is null",
-        (run3,)).fetchone()[0]
-    conn.close()
-
-    def agent_task(title):
-        status, body = saddle_api("POST", "/api/saddle/task/create", fake_token, {
-            "session_id": run3_session, "title": title, "mandate": "m"})
-        task_id = int(body["task_id"])
-        saddle_api("POST", "/api/saddle/task/enqueue", fake_token,
-                   {"session_id": run3_session, "task_id": task_id})
-        return task_id
-
-    status, body = saddle_api("POST", "/api/saddle/task/create", fake_token, {
-        "session_id": run3_session, "title": "Collapse draft", "mandate": "m"})
-    collapse_draft = int(body["task_id"])  # stays draft (never enqueued)
-    collapse_queued = agent_task("Collapse queued")
-    collapse_worker = agent_task("Collapse worker")
-    # Both queued tasks race for the one saddle; freeze the daemon the
-    # moment the first dispatches so one stays genuinely WORKING (and
-    # the other queued) when the goal fails.
-    fake.hold_state = True
-    def collapse_working():
-        for task_id in (collapse_queued, collapse_worker):
-            if task_state(auth, task_id)["status"] == "working":
-                return task_id
-        return False
-    running_one = wait_for(collapse_working, timeout=60, what="a collapse task works")
-    check(running_one is not None,
-          "a collapse task reaches working before the failure")
-    queued_one = collapse_worker if running_one == collapse_queued else collapse_queued
-
-    status, _ = saddle_api("POST", "/api/saddle/results", fake_token,
-                           {"session_id": run3_session, "state": "failed",
-                            "summary": "the foundation crumbled"})
-    check(status == 200 and goal_state(collapse)["status"] == "failed",
-          "the agent's failure fails the goal")
-    check(task_state(auth, run3)["status"] == "failed",
-          "the failure fails the goal agent's run task")
-    check(wait_for(lambda: task_state(auth, queued_one)["status"] == "failed"
-                   and task_state(auth, running_one)["status"] == "failed" or False,
-                   timeout=30, what="failure cascade settles") is not None,
-          "the failure cascade cancels the queued and working tasks")
-    check(not any(t["id"] == collapse_draft
-                  for t in slot_public(auth, "/tasks", "tasks")["tasks"]),
-          "the failure cascade deletes the goal's draft tasks")
-    state = goal_state(collapse)
-    check(any(e["kind"] == "cascade" for e in state["events"]),
-          "the narrative records the failure cascade")
-    check(state["draft_tasks"] == 0 and state["queued_tasks"] == 0,
-          "nothing under the failed goal stays dispatchable (no orphan drafts)")
-    check(len([e for e in state["events"] if e["kind"] == "goal-failed"]) == 1,
-          "the failing goal records exactly one goal-failed event")
-    # Plan 16 S1: the FAILURE report keeps its goal-side home (failure
-    # is terminal — no pending duplication exists, so unlike the
-    # completion report it is written at failure time).
-    conn = db()
-    failure_report = conn.execute(
-        "select completion_report from goals where id = ?", (collapse,)).fetchone()[0]
-    conn.close()
-    check(failure_report == "the foundation crumbled",
-          "fail_goal's failure report keeps its goal-side home (S1)")
-    # Plan 16 S4: the narrative renders the task-failed rows from the
-    # terminal summary's lead — the run thread carries NO duplicate
-    # agent comment of the goal failure text.
-    failed_rows = [e for e in state["events"] if e["kind"] == "task-failed"]
-    check(failed_rows
-          and all(": Cancelled by user" in e["text"] for e in failed_rows),
-          "task-failed narrative rows render the summary lead (S4: summary is the terminal cache)")
-    run_comments = [c for c in task_state(auth, run3)["comments"]
-                    if c["author"] == "agent"]
-    check(not any("the foundation crumbled" in c["body"] for c in run_comments),
-          "the goal failure text never duplicates as an agent comment (S4)")
-    fake.hold_state = False
-
-    print("== plan 12: auto-enqueue-after for human tasks ==")
-    act(auth, slot_public(auth, "/tasks", "tasks")["create"], {
-        "project_id": "1", "title": "Predecessor task", "priority": "4"})
-    predecessor = task_id_of("Predecessor task")
-    enqueue_task(auth, predecessor)
-    act(auth, slot_public(auth, "/tasks", "tasks")["create"], {
-        "project_id": "1", "title": "Successor task", "priority": "4",
-        "enqueue_after_task_id": str(predecessor)})
-    successor = task_id_of("Successor task")
-    check(task_state(auth, successor)["status"] == "draft"
-          and task_state(auth, successor).get("enqueue_after_task_id") == predecessor,
-          "a human task can carry an auto-enqueue predecessor")
-    check(wait_task_done(auth, predecessor, timeout=60) is not None,
-          "the predecessor completes")
-    check(wait_for(lambda: task_state(auth, successor)["status"] in
-                   ("queued", "assigned", "working") or False,
-                   timeout=30, what="successor auto-enqueues") is not None,
-          "the done predecessor auto-enqueues its dependent")
-    # Cycle validation refuses a predecessor chain that loops.
-    act(auth, slot_public(auth, "/tasks", "tasks")["create"], {
-        "project_id": "1", "title": "Cycle A", "priority": "4"})
-    cycle_a = task_id_of("Cycle A")
-    act(auth, slot_public(auth, "/tasks", "tasks")["create"], {
-        "project_id": "1", "title": "Cycle B", "priority": "4",
-        "enqueue_after_task_id": str(cycle_a)})
-    cycle_b = task_id_of("Cycle B")
-    cycle_directives = act(auth, task_state(auth, cycle_a)["update"], {
-        "title": "Cycle A", "description": "x", "priority": "4",
-        "enqueue_after_task_id": str(cycle_b)})
-    check(any(d.get("type") == "notify" and d.get("kind") == "error"
-              and "cycle" in (d.get("message") or "").lower()
-              for d in cycle_directives),
-          "a predecessor cycle rejects with a naming error")
-    # A failed predecessor leaves the dependent in draft.
-    fake.fail_next = True
-    act(auth, slot_public(auth, "/tasks", "tasks")["create"], {
-        "project_id": "1", "title": "Failing predecessor", "priority": "1"})
-    failing_pred = task_id_of("Failing predecessor")
-    enqueue_task(auth, failing_pred)
-    act(auth, slot_public(auth, "/tasks", "tasks")["create"], {
-        "project_id": "1", "title": "Stranded successor", "priority": "4",
-        "enqueue_after_task_id": str(failing_pred)})
-    stranded = task_id_of("Stranded successor")
-    check(wait_for(lambda: task_state(auth, failing_pred)["status"] == "failed"
-                   or False, timeout=60, what="failing predecessor fails") is not None,
-          "the scripted-failure predecessor fails")
-    check(quiet_window(quiet_seconds(),
-                       lambda: task_state(auth, stranded)["status"] == "draft",
-                       "failed predecessor leaves the draft"),
-          "a failed predecessor leaves its dependent in draft")
-
-    # Successor cleanup: let the queued successor finish so the
-    # shard's app shuts down with an empty queue.
-    check(wait_task_done(auth, successor, timeout=90) is not None,
-          "the auto-enqueued successor completes")
-
-    print("== feedback: context_update carries rule/note deltas on resume ==")
-    # A standalone task parks on a question; while it is parked a rule
-    # is attached to the project and a note lands; the resuming
-    # assignment carries both as the context_update markdown turn.
-    probe_id = create_queued(auth, {"project_id": "1", "title": "Context probe",
-                                    "priority": "4"})
-    check(wait_for(lambda: fake.running_task == probe_id
-                   and task_state(auth, probe_id)["status"] == "working" or False,
-                   timeout=60, what="probe task runs") is not None,
-          "the probe task dispatches")
-    fake.set_state("blocked")
-    fake.push_results("blocked", block={"type": "question",
-                                        "question": "Which database dialect?"})
-    check(wait_for(lambda: task_state(auth, probe_id)["status"] == "blocked" or False,
-                   timeout=60, what="probe task blocks") is not None,
-          "the probe task parks on its question")
-    detail = task_state(auth, probe_id)
-    open_block = [b for b in detail["blocks"] if not b["answered"]][0]
-    # Backdate the parked round's start: stamps are second-resolution
-    # epochs, and the delta compares strictly-later — the park must
-    # span a real interval like an operator's would.
-    conn = db()
-    conn.execute("update sessions set started_at = strftime('%s','now') - 60"
-                 " where id = (select min(id) from sessions where task_id = ?)",
-                 (probe_id,))
-    conn.commit()
-    conn.close()
-    # While parked: a new rule attached to the project + a new note.
-    rules_state = slot_public(auth, "/rules", "rules")
-    act(auth, rules_state["create"], {
-        "name": "Nightly gate", "body": "Every PR must pass the nightly suite before merge."})
-    conn = db()
-    rule_id = conn.execute("select id from rules where name = 'Nightly gate'").fetchone()[0]
-    conn.close()
-    act(auth, slot_public(auth, "/projects/1", "project")["attach_rule"],
-        {"rule_id": str(rule_id)})
-    conn = db()
-    conn.execute("insert into project_notes (project_id, body, created_at)"
-                 " values (1, 'The demo repo moved its CI to nightly builds.',"
-                 " strftime('%s','now'))")
-    conn.commit()
-    check(conn.execute("select count(*) from rule_projects where rule_id = ?",
-                       (rule_id,)).fetchone()[0] == 1,
-          "the rule attaches to the project while the task is parked")
-    conn.close()
-    probe_assignments = len([p for p in fake.start_payloads
-                             if int(p.get("task", {}).get("id") or 0) == probe_id])
-    act(auth, open_block["answer_action"], {"answer": "postgres"})
-    check(wait_for(lambda: len([p for p in fake.start_payloads
-                                if int(p.get("task", {}).get("id") or 0) == probe_id])
-                   > probe_assignments or False, timeout=60,
-                   what="probe task resumes") is not None,
-          "answering the block resumes the probe task")
-    probe_resume = [p for p in fake.start_payloads
-                    if int(p.get("task", {}).get("id") or 0) == probe_id][-1]
-    delta = probe_resume.get("context_update") or ""
-    check("Rules changed" in delta and "Nightly gate" in delta
-          and "nightly suite" in delta,
-          "the resume's context_update summarises the newly attached rule")
-    check("New project notes" in delta and "nightly builds" in delta,
-          "the resume's context_update summarises the new project note")
-    check("Plan approved" not in delta,
-          "standalone resumes carry no plan section")
-    check(wait_task_done(auth, probe_id, timeout=60) is not None,
-          "the probe task completes after its resume")
-
-
-# =============================================================================
-# Bundle: replay — plan 13 B1/B2: the daemon-global entry dedup and the
-# idempotent terminal/narrative projections. Replays the live-failure
-# post-mortem shapes directly against the push channels: an outbox
-# redelivery arriving under the WRONG session id after churn (and after
-# a web restart), and repeated failure pushes that must still project
-# exactly once. Includes this shard's one deliberate app restart (the
-# dedup must survive it — it is database state, not memory).
-# =============================================================================
-
-def bundle_replay(ctx):
-    auth, fake, fake_id, fake_token = ctx.auth, ctx.fake, ctx.fake_id, ctx.fake_token
-    app = ctx.app
-
-    def rows_for(session):
-        conn = db()
-        try:
-            return conn.execute(
-                "select count(*) from session_commands where session_id = ?",
-                (session,)).fetchone()[0]
-        finally:
-            conn.close()
-
-    def dedup_rows():
-        conn = db()
-        try:
-            return conn.execute("select count(*) from saddle_entry_dedup").fetchone()[0]
-        finally:
-            conn.close()
-
-    def open_session_on_fake(task_id):
-        """A fixture open session row on the shard's saddle (the churn
-        shape: a fresh web-side run row the daemon never really drove)."""
-        conn = db()
-        try:
-            conn.execute(
-                "insert into sessions (task_id, saddle_id, started_at)"
-                " values (?, ?, strftime('%s','now'))", (task_id, fake_id))
-            conn.commit()
-            return conn.execute(
-                "select max(id) from sessions where task_id = ?",
-                (task_id,)).fetchone()[0]
-        finally:
-            conn.close()
-
-    print("== plan 13 B1: entry dedup is daemon-global, not per-session ==")
-    # A first task runs to completion; its session is the replay source.
-    first = create_queued(auth, {"project_id": "1", "title": "Replay source task",
-                                 "priority": "2"})
-    check(wait_task_done(auth, first, timeout=60) is not None,
-          "the replay-source task completes")
-    conn = db()
-    src_session = conn.execute(
-        "select max(id) from sessions where task_id = ?", (first,)).fetchone()[0]
-    conn.close()
-
-    # The outbox batch: two command entries the daemon already
-    # delivered once (their ids landed with the source session).
-    burst = [
-        {"id": 5001, "command": "make test", "output": "ok", "exit_code": 0,
-         "type": "command", "timestamp": "2026-09-11T00:00:00Z"},
-        {"id": 5002, "command": "grep -r flange src/", "output": "src/flange.vala",
-         "exit_code": 0, "type": "command", "timestamp": "2026-09-11T00:00:01Z"},
-    ]
-    status, _ = saddle_api("POST", "/api/saddle/results", fake_token,
-                           {"session_id": src_session, "state": "done",
-                            "entries": burst})
-    check(status == 200 and rows_for(src_session) >= 2,
-          "the entries batch stores under its session")
-    stored_once = rows_for(src_session)
-    dedup_after_first = dedup_rows()
-
-    # Redelivery under the SAME session: consumed, nothing new.
-    status, _ = saddle_api("POST", "/api/saddle/results", fake_token,
-                           {"session_id": src_session, "state": "done",
-                            "entries": burst})
-    check(status == 200 and rows_for(src_session) == stored_once
-          and dedup_rows() == dedup_after_first,
-          "a same-session redelivery stores nothing new (consumed silently)")
-
-    # Session churn: a brand-new session id on the same saddle replays
-    # the SAME entry ids — the post-mortem's mis-keyed outbox send.
-    # The entries' ids already populated another session, so the push
-    # may not create rows here either.
-    conn = db()
-    conn.execute(
-        "insert into tasks (project_id, title, status, priority, created_at,"
-        " completed_at) values (1, 'Churn target task', 'done', 5,"
-        " strftime('%s','now'), strftime('%s','now'))")
-    conn.commit()
-    churn_task = conn.execute(
-        "select max(id) from tasks where title = 'Churn target task'").fetchone()[0]
-    conn.close()
-    churn_session = open_session_on_fake(churn_task)
-    status, _ = saddle_api("POST", "/api/saddle/results", fake_token,
-                           {"session_id": churn_session, "state": "done",
-                            "entries": burst})
-    check(status == 200 and rows_for(churn_session) == 0,
-          "replay-under-wrong-session stores nothing new (daemon-global dedup)")
-    check(dedup_rows() == dedup_after_first,
-          "the consumed redelivery claims no fresh dedup rows")
-
-    # A fresh entry id under the churned session DOES store — the dedup
-    # keys on the entry id, never on the session.
-    fresh = [{"id": 5003, "command": "git status", "output": "clean",
-              "exit_code": 0, "type": "command", "timestamp": "2026-09-11T00:00:02Z"}]
-    status, _ = saddle_api("POST", "/api/saddle/results", fake_token,
-                           {"session_id": churn_session, "state": "done",
-                            "entries": fresh})
-    check(status == 200 and rows_for(churn_session) == 1
-          and dedup_rows() == dedup_after_first + 1,
-          "a fresh entry id stores under any session of its saddle")
-
-    # Web restart: the dedup survives (database state, not memory).
-    app.terminate()
-    app.wait(timeout=10)
-    app = start_app()
-    auth = login("admin", "adminpass123")
-    ctx.app = app  # teardown tracks the restarted process
-    ctx.auth = auth
-    # The restart wiped the in-memory ask bookkeeping; the daemon
-    # re-establishes sleeping with a fresh ask (the real daemon's
-    # idle-awake ask / 15-minute safety self-ask).
-    fake.ask_now()
-    status, _ = saddle_api("POST", "/api/saddle/results", fake_token,
-                           {"session_id": churn_session, "state": "done",
-                            "entries": burst + fresh})
-    check(status == 200 and rows_for(churn_session) == 1
-          and rows_for(src_session) == stored_once,
-          "a post-restart redelivery still stores nothing (dedup is persistent)")
-
-    print("== plan 13 B2: duplicate failed entries project once (task) ==")
-    # The post-mortem's honest burst: the same failure entry redelivered
-    # under a churned session AND a second, DISTINCT failure entry id
-    # in the same session — one transition, one comment, ever.
-    def agent_comments(task_id, body=None):
-        conn = db()
-        try:
-            if body is None:
-                return conn.execute(
-                    "select count(*) from task_comments"
-                    " where task_id = ? and author = 'agent'",
-                    (task_id,)).fetchone()[0]
-            return conn.execute(
-                "select count(*) from task_comments"
-                " where task_id = ? and author = 'agent' and body = ?",
-                (task_id, body)).fetchone()[0]
-        finally:
-            conn.close()
-
-    conn = db()
-    conn.execute(
-        "insert into tasks (project_id, title, status, priority, created_at)"
-        " values (1, 'Burst failure task', 'working', 5, strftime('%s','now'))")
-    conn.commit()
-    burst_task = conn.execute(
-        "select max(id) from tasks where title = 'Burst failure task'").fetchone()[0]
-    conn.close()
-    burst_session = open_session_on_fake(burst_task)
-    first_fail = [{"id": 6001, "command": "saddle failure",
-                   "output": "bash -n rejected the script", "exit_code": 1,
-                   "type": "failed", "timestamp": "2026-09-11T00:01:00Z"}]
-    status, _ = saddle_api("POST", "/api/saddle/results", fake_token,
-                           {"session_id": burst_session, "state": "failed",
-                            "entries": first_fail,
-                            "summary": "bash -n rejected the script"})
-    check(status == 200
-          and task_state(auth, burst_task)["status"] == "failed",
-          "the failure entry + state pair fails the task")
-    check(agent_comments(burst_task, "bash -n rejected the script") == 0
-          and "bash -n rejected the script"
-          in (task_state(auth, burst_task).get("summary") or ""),
-          "the failure explanation lives ONCE — in tasks.summary, the terminal cache (S4: no duplicate agent comment)")
-
-    # The burst: a DISTINCT failure entry id in the same session, plus
-    # both ids redelivered under a churned session — nothing re-runs.
-    second_fail = [{"id": 6002, "command": "saddle failure",
-                    "output": "bash -n rejected the script", "exit_code": 1,
-                    "type": "failed", "timestamp": "2026-09-11T00:01:01Z"}]
-    churned_burst = open_session_on_fake(burst_task)
-    for target in (burst_session, churned_burst):
-        status, _ = saddle_api("POST", "/api/saddle/results", fake_token,
-                               {"session_id": target, "state": "failed",
-                                "entries": first_fail + second_fail,
-                                "summary": "bash -n rejected the script"})
-        check(status == 200,
-              "the burst push under %s is consumed, not rejected" % (
-                  "its session" if target == burst_session else "a churned session"))
-    check(task_state(auth, burst_task)["status"] == "failed"
-          and agent_comments(burst_task) == 0
-          and "bash -n rejected the script"
-          in (task_state(auth, burst_task).get("summary") or ""),
-          "duplicate failed entries leave one transition, one summary, zero agent comments (S4)")
-
-    print("== plan 13 B2: goal failure projects once ==")
-    # Goal context: `saddle failure` fails the goal ONCE — the 115
-    # goal-failed events of the live failure are structurally gone.
-    def goal_state(goal_id):
-        return slot_public(auth, "/goals/%d" % goal_id, "goal")
-
-    def goal_failed_events(goal_id):
-        # Plan 15 C3: the narrative derives at read time — the
-        # failed-goal row IS the goal-failed record (one row, ever).
-        return len([e for e in goal_state(goal_id)["events"]
-                    if e["kind"] == "goal-failed"])
-
-    act(auth, slot_public(auth, "/goals", "goals")["create"], {
-        "project_id": "1", "title": "Burst goal", "brief": "Fails honestly.",
-        "branch_name": "goal/burst"})
-    conn = db()
-    burst_goal = conn.execute(
-        "select id from goals where title = 'Burst goal'").fetchone()[0]
-    conn.close()
-    fake.goal_script = [("suspend",)]
-    act(auth, goal_state(burst_goal)["start"], {})
-    conn = db()
-    run_task = conn.execute(
-        "select id from tasks where goal_id = ? and kind = 'goal_run'",
-        (burst_goal,)).fetchone()[0]
-    conn.close()
-    check(wait_for(lambda: task_state(auth, run_task)["status"] == "suspended"
-                   or False, timeout=60, what="burst goal agent parks") is not None,
-          "the burst goal's agent parks first")
-    conn = db()
-    run_session = conn.execute(
-        "select id from sessions where task_id = ? and ended_at is null",
-        (run_task,)).fetchone()[0]
-    conn.close()
-
-    goal_fail = [{"id": 7001, "command": "saddle failure",
-                  "output": "the harness collapsed", "exit_code": 1,
-                  "type": "failed", "timestamp": "2026-09-11T00:02:00Z"},
-                 {"id": 7002, "command": "saddle failure",
-                  "output": "the harness collapsed", "exit_code": 1,
-                  "type": "failed", "timestamp": "2026-09-11T00:02:01Z"}]
-    status, _ = saddle_api("POST", "/api/saddle/results", fake_token,
-                           {"session_id": run_session, "state": "failed",
-                            "entries": goal_fail, "summary": "the harness collapsed"})
-    check(status == 200 and goal_state(burst_goal)["status"] == "failed",
-          "the goal agent's failure fails the goal")
-    check(goal_failed_events(burst_goal) == 1,
-          "a two-entry failure burst records exactly one goal-failed event")
-
-    # Redeliveries — same ids under the run's session AND under a
-    # churned session — plus the bare failed state again: still one.
-    churned_run = open_session_on_fake(run_task)
-    for target in (run_session, churned_run):
-        status, _ = saddle_api("POST", "/api/saddle/results", fake_token,
-                               {"session_id": target, "state": "failed",
-                                "entries": goal_fail,
-                                "summary": "the harness collapsed"})
-        check(status == 200, "the goal-failure redelivery under %s is consumed"
-              % ("its session" if target == run_session else "a churned session"))
-    check(goal_state(burst_goal)["status"] == "failed"
-          and goal_failed_events(burst_goal) == 1,
-          "redelivered failures never re-run the goal failure (one event, ever)")
-    check(task_state(auth, run_task)["status"] == "failed",
-          "the goal-run task stays failed after the replays")
-    conn = db()
-    burst_blocks = conn.execute(
-        "select count(*) from task_blocks where task_id = ?", (run_task,)
-    ).fetchone()[0]
-    conn.close()
-    check(burst_blocks == 0,
-          "the goal-failed path raises ZERO blocks (nothing pins the pile)")
-
-    print("== plan 13 B4: the comment projection stores the body ==")
-    # The heredoc shape: the command is the pipe invocation, the OUTPUT
-    # is the body. The projections must carry the body — the command
-    # echo never becomes comment text, and the literal `saddle
-    # comment` string never renders outside the terminal.
-    act(auth, slot_public(auth, "/goals", "goals")["create"], {
-        "project_id": "1", "title": "Comment goal", "brief": "Reports cleanly.",
-        "branch_name": "goal/comment"})
-    conn = db()
-    comment_goal = conn.execute(
-        "select id from goals where title = 'Comment goal'").fetchone()[0]
-    conn.close()
-    fake.goal_script = [("suspend",)]
-    act(auth, goal_state(comment_goal)["start"], {})
-    conn = db()
-    comment_run = conn.execute(
-        "select id from tasks where goal_id = ? and kind = 'goal_run'",
-        (comment_goal,)).fetchone()[0]
-    conn.close()
-    check(wait_for(lambda: task_state(auth, comment_run)["status"] == "suspended"
-                   or False, timeout=60, what="comment goal agent parks") is not None,
-          "the comment goal's agent parks")
-    conn = db()
-    comment_session = conn.execute(
-        "select id from sessions where task_id = ? and ended_at is null",
-        (comment_run,)).fetchone()[0]
-    conn.close()
-
-    comment_body = "The flange weld holds. First sentence carries the information."
-    comment_entry = [{"id": 8001, "command": "cat << 'EOF' | saddle comment",
-                      "output": comment_body, "exit_code": 0, "type": "comment",
-                      "timestamp": "2026-09-11T00:03:00Z"}]
-    status, _ = saddle_api("POST", "/api/saddle/results", fake_token,
-                           {"session_id": comment_session, "state": "suspended",
-                            "entries": comment_entry})
-    check(status == 200, "the comment entry push is accepted")
-    conn = db()
-    task_comment_bodies = [r[0] for r in conn.execute(
-        "select body from task_comments where task_id = ?", (comment_run,))]
-    tables = {r[0] for r in conn.execute(
-        "select name from sqlite_master where type = 'table'").fetchall()}
-    conn.close()
-    check(task_comment_bodies == [comment_body],
-          "the run task's comment stores the body, not the command echo")
-    check("goal_comments" not in tables,
-          "the goal_comments table is gone (the run task's rows are the thread)")
-    narrative_comments = [e["text"] for e in goal_state(comment_goal)["events"]
-                          if e["kind"] == "comment"]
-    check(len(narrative_comments) == 1
-          and narrative_comments[0].startswith("The flange weld holds.")
-          and "saddle comment" not in narrative_comments[0]
-          and "EOF" not in narrative_comments[0],
-          "the derived narrative's comment rows carry the body text")
-
-    state = goal_state(comment_goal)
-    check(state["current_command"] == comment_body,
-          "the goal page's current-activity line shows the comment body")
-    check(state["comments"] and state["comments"][0]["body"] == comment_body
-          and any(e["kind"] == "comment"
-                  and e["text"].startswith("The flange weld holds.")
-                  for e in state["events"]),
-          "the goal slot carries the body in its comments and narrative")
-    page = http_get_page(auth, "/goals/%d" % comment_goal)
-    check("saddle comment" not in page,
-          "the rendered goal page never shows the command echo")
-    check("event.kind == 'comment' ? ' footnote'" in page,
-          "the narrative's comment events render with footnote styling")
-    check(page.index('stm-markdown="comment.body"')
-          < page.index('stm-text="comment.quote"'),
-          "the comment card shows the body before the quote")
-
-    # Drain: nothing queued remains for the shard's shutdown.
-    check(queued_count() == 0, "the replay shard drains its queue")
-
-def bundle_goalui(ctx):
-    """Plan 14 workstream B + plan 15 C1: the goal supervision surface.
-
-    B1 — goal-run control parity (Retry supervision / Requeue-to-resume
-    on the status head, the /tasks/<goal-run-id> redirect, no
-    notify-me toggle), B2 — the plan-review remarks queue, B4 —
-    sessions.resume_notice + the terminal dropdown/resume panel, B5 —
-    page order, effective rules and per-task capability badges, B6 —
-    narrative footnote weights. C1 — the single-row block world: the
-    goal's blocks ARE the run task's rows (answered from every
-    surface through one path; no dual rows, no stragglers, at most
-    one review-kind block per verdict path). C4 — the goal page
-    batch: one muted head activity line, plan between attention and
-    tasks, answered blocks behind an expander, footnote comments.
-    C5 — the dashboard deep-link closure: goal pile cards link the
-    goal page, every surface settles the single row, and no
-    goal-side store exists to hold stragglers.
-    """
-    auth, fake, fake_id, fake_token = ctx.auth, ctx.fake, ctx.fake_id, ctx.fake_token
-
-    def goal_state(goal_id):
-        return slot_public(auth, "/goals/%d" % goal_id, "goal")
-
-    def run_task_of(goal_id):
-        conn = db()
-        try:
-            return int(conn.execute(
-                "select id from tasks where goal_id = ? and kind = 'goal_run'",
-                (goal_id,)).fetchone()[0])
-        finally:
-            conn.close()
-
-    def wait_run(status, timeout=60, what="run status"):
-        return wait_for(lambda: task_state(auth, run_task_of(goal))["status"] == status
-                        or False, timeout=timeout, what=what)
-
-    def pile_questions():
-        return [b.get("question") for b in
-                slot_public(auth, "/", "dashboard")["pinned"]
-                if b.get("item_type") == "goal"]
-
-    def open_session(task_id):
-        conn = db()
-        try:
-            row = conn.execute(
-                "select id from sessions where task_id = ? and ended_at is null",
-                (task_id,)).fetchone()
-            return int(row[0]) if row else None
-        finally:
-            conn.close()
-
-    print("== B1: the goal-run task page redirects to the goal ==")
-    fake.goal_script = [("plan", "# Remarks plan\n\n## Steps\n\n1. First move")]
-    act(auth, slot_public(auth, "/goals", "goals")["create"], {
-        "project_id": "1", "title": "Goalui goal",
-        "brief": "Drive the plan-14 goal surface end to end.",
-        "branch_name": "goal/goalui"})
-    conn = db()
-    goal = conn.execute("select id from goals where title = 'Goalui goal'"
-                        ).fetchone()[0]
-    conn.close()
-    act(auth, goal_state(goal)["start"], {})
-    wait_run("blocked", what="goalui goal agent parks on its plan")  # plan review parks blocked
-    run_task = run_task_of(goal)
-
-    frames = directives("/tasks/%d" % run_task, auth)
-    navigations = [d for d in frames if d.get("type") == "navigate"]
-    check(any(d.get("uri") == "/goals/%d" % goal for d in navigations),
-          "the goal-run task page redirects to /goals/<id> (navigate directive)")
-    check(slot_public(auth, "/tasks/%d" % run_task, "task")["id"] == run_task,
-          "the redirect still hydrates the task slot (sealed refresh + API readers)")
-
-    status, page = http("GET", "/tasks/%d" % run_task, headers={
-        "X-Statum-Slot": "key=%s; as_at=%s" % (auth["key"], auth["as_at"])}, timeout=15)
-    check(status == 200, "the compiled goal-run page serves")
-
-    act(auth, slot_public(auth, "/tasks", "tasks")["create"], {
-        "project_id": "1", "title": "Goalui worker", "priority": "4",
-        "description": "A plain worker under no goal."})
-    conn = db()
-    worker = conn.execute("select id from tasks where title = 'Goalui worker'"
-                          ).fetchone()[0]
-    conn.close()
-    check(not [d for d in directives("/tasks/%d" % worker, auth)
-               if d.get("type") == "navigate"],
-          "worker task pages render normally (no redirect)")
-
-    state = goal_state(goal)
-    check("toggle_notify" not in state and state.get("notify") is None,
-          "no notify-me toggle on the goal (goals notify unconditionally)")
-    goal_page = http_get_page(auth, "/goals/%d" % goal)
-    check("Notify me" not in goal_page and "toggle-notify" not in goal_page,
-          "the goal page template ships no notify control")
-    check(state["branch_name"] == "goal/goalui" and state["base_branch"] == "main"
-          and isinstance(state["push_branches"], list)
-          and state["priority"] == 3
-          and len(state["started_display"]) > 0
-          and len(state["agent_saddle"]) > 0,
-          "the status head carries the full field set (branch pair, chips list,"
-          " priority, timestamps, agent saddle)")
-    check("Retry supervision" in goal_page and "Requeue to resume" in goal_page,
-          "the status head ships the run-control parity buttons")
-    check("status-corner" not in goal_page and "goal complete" not in goal_page
-          and goal_page.count("badge-yeehaw") == 1,
-          "yeehaw is rows-only (no goal-head corner badge; the row badge remains)")
-
-    check(goal_state(goal)["current_activity"] == "parked awaiting the plan review",
-          "the head line reads 'parked awaiting the plan review' while one is open")
-    goal_page = http_get_page(auth, "/goals/%d" % goal)
-    check(goal_page.index("Goal agent blocks") < goal_page.index("<h3>Plan</h3>")
-          < goal_page.index("<h3>Tasks</h3>"),
-          "the plan section sits between attention and tasks")
-    check("data-plan-review" in goal_page and "Approved plan &amp; revisions" in goal_page,
-          "an open review renders expanded beside the collapsed approved-plan expander")
-
-    print("== B2: the plan-review remarks queue ==")
-    check(goal_state(goal)["status"] == "plan_review"
-          and goal_state(goal)["plan_pending_block"] is not None,
-          "the goal sits in plan review with a pending block")
-    goal_page = http_get_page(auth, "/goals/%d" % goal)
-    review_at = goal_page.index("data-plan-review")
-    check(review_at > 0, "the plan review region is marked for the remarks queue")
-    check(goal_page.index('data-block-id="goal.plan_pending_block.id"') > 0,
-          "the queue keys on the pending goal block id")
-    body_at = goal_page.index('data-plan-body')
-    remarks_at = goal_page.index("data-plan-remarks")
-    check(body_at < remarks_at,
-          "the remarks queue renders at the bottom of the plan body")
-    for marker in ("data-plan-accept", "data-plan-toggle", "data-plan-submit",
-                   "data-plan-remove", "plan-popover", "remarksByBlock"):
-        check(marker in goal_page, "the remarks queue ships %s" % marker)
-    check("(index + 1) + '. '" in goal_page,
-          "the rejection payload numbers every queued remark")
-    check("rejectOpenByBlock" in goal_page and "statum.afterEvaluate(syncPlanRemarks)" in goal_page,
-          "the queue survives pulse refreshes (maps outside statum re-renders)")
-
-    # The rejection payload exactly as the client composes it: the
-    # stable verdict wording, then each remark NUMBERED in queue order
-    # with its quote prefixed like a comment.
-    payload = ("Plan feedback received:\n\n"
-               "> ## Steps\n\n1. First move\n\n"
-               "1. Add a rollback step\n\n"
-               "2. Name the owner of the migration")
-    act(auth, goal_state(goal)["plan_pending_block"]["answer_action"],
-        {"answer": payload})
-    state = goal_state(goal)
-    check(state["status"] == "planning",
-          "the remarks rejection returns the agent to planning")
-    rejected = [r for r in state["plan_revisions"] if r.get("answered")]
-    check(any(r["answer"] == payload for r in rejected),
-          "the rejection carries the remarks verbatim, in order")
-    check(payload.index("1. Add a rollback step") < payload.index("2. Name the owner"),
-          "the numbering is queue-ordered")
-
-    print("== B4: resume_notice lands on the resumed session row ==")
-    fake.goal_script = [("question", "Which datastore?", ["SQLite", "Redis"])]
-    check(wait_for(lambda: goal_state(goal)["status"] == "planning" or False,
-                   timeout=30, what="rejection observed") is not None,
-          "the agent revises")
-    # The parked plan agent resumes with the verdict; the next round
-    # raises the scripted question.
-    check(wait_for(lambda: any(b["question"] == "Which datastore?"
-                               and not b.get("answered")
-                               for b in goal_state(goal)["blocks"]) or False,
-                   timeout=60, what="question raised") is not None,
-          "the resumed agent raises its question")
-    conn = db()
-    notices = dict(conn.execute(
-        "select id, resume_notice from sessions where task_id = ?", (run_task,)
-    ).fetchall())
-    conn.close()
-    resumed_ids = [i for i, text in notices.items() if text]
-    fresh_ids = [i for i, text in notices.items() if not text]
-    check(len(resumed_ids) >= 1 and any("Plan feedback received" in notices[i]
-                                        for i in resumed_ids),
-          "the resumed session stores the notice it was allocated")
-    check(min(notices) in fresh_ids,
-          "session 1 (the fresh opening round) carries no resume notice")
-
-    print("== C1: the single run-task row IS the goal's block ==")
-    check("Which datastore?" in pile_questions(),
-          "the open goal question pins onto the dashboard pile")
-    goal_rows = [b for b in goal_state(goal)["blocks"]
-                 if b["question"] == "Which datastore?"]
-    run_rows = [b for b in task_state(auth, run_task)["blocks"]
-                if b["question"] == "Which datastore?"]
-    check(len(run_rows) == 1 and len(goal_rows) == 1
-          and int(run_rows[0]["id"]) == int(goal_rows[0]["id"]),
-          "the goal page and the run task read the SAME single row")
-    pile_card = [b for b in slot_public(auth, "/", "dashboard")["pinned"]
-                 if b.get("question") == "Which datastore?"][0]
-    check(pile_card.get("item_type") == "goal"
-          and int(pile_card.get("goal_id") or 0) == goal
-          and int(pile_card.get("id") or 0) == int(run_rows[0]["id"])
-          and pile_card.get("goal_title") == "Goalui goal",
-          "the pile card is the run-task row styled as a goal item")
-    act(auth, [b for b in goal_state(goal)["blocks"]
-               if b["question"] == "Which datastore?" and not b.get("answered")]
-        [0]["answer_action"], {"option": "SQLite"})
-    conn = db()
-    unanswered = conn.execute(
-        "select count(*) from task_blocks where question = 'Which datastore?'"
-        " and answer is null").fetchone()[0]
-    conn.close()
-    check(unanswered == 0, "answering from the goal page closes the single row")
-    check("Which datastore?" not in pile_questions(),
-          "the answered row no longer pins the dashboard pile")
-
-    # The task-page deep link (the AnswerBlockAction API surface)
-    # answers the SAME row through the one goal path — there is no
-    # second row to sweep and no stale copy can survive.
-    conn = db()
-    conn.execute("insert into task_blocks (task_id, type, question, created_at)"
-                 " values (?, 'question', 'Deep link probe?',"
-                 " strftime('%s','now'))", (run_task,))
-    conn.commit()
-    conn.close()
-    check("Deep link probe?" in pile_questions(),
-          "the fixture row pins like any goal question")
-    deep_block = [b for b in task_state(auth, run_task)["blocks"]
-                  if b["question"] == "Deep link probe?" and not b.get("answered")][0]
-    act(auth, deep_block["answer_action"], {"answer": "Answered via the deep link"})
-    conn = db()
-    answered_row = conn.execute(
-        "select answer from task_blocks where question = 'Deep link probe?'"
-    ).fetchone()[0]
-    tables = {r[0] for r in conn.execute(
-        "select name from sqlite_master where type = 'table'").fetchall()}
-    conn.close()
-    check(answered_row == "Answered via the deep link",
-          "the task-page deep link answers the same single row (the API path)")
-    check("Deep link probe?" not in pile_questions(),
-          "the deep-link answer closes the pile card too")
-    check("goal_blocks" not in tables,
-          "the goal_blocks table is gone (run-task blocks are canonical)")
-
-    print("== C5: deep-link closure on the single-row world ==")
-    # The pile card's goal item deep-links the goal page (the answer
-    # surface); answering from either surface settled THE row above.
-    home_markup = http_get_page(auth, "/")
-    check("'/goals/' + blockview.goal_id" in home_markup,
-          "the pile card deep-links the goal page for goal items")
-    conn = db()
-    dupes = conn.execute(
-        "select count(*) from (select question from task_blocks where task_id = ?"
-        " group by question having count(*) > 1)", (run_task,)).fetchone()[0]
-    stragglers = conn.execute(
-        "select count(*) from task_blocks where task_id = ? and answer is null",
-        (run_task,)).fetchone()[0]
-    goal_side_tables = [r[0] for r in conn.execute(
-        "select name from sqlite_master where type = 'table'"
-        " and name in ('goal_blocks','goal_comments','goal_events')").fetchall()]
-    conn.close()
-    check(dupes == 0 and stragglers == 0,
-          "one row per question on the run task, none left unanswered")
-    check(not goal_side_tables,
-          "no goal-side store exists — historical stragglers are impossible")
-
-    print("== B4: the terminal session dropdown + resume-info panel ==")
-    fake.goal_script = [("suspend",)]
-    check(wait_for(lambda: task_state(auth, run_task)["status"] == "suspended"
-                   or False, timeout=60, what="agent parks suspended") is not None,
-          "the agent parks suspended for the requeue scenario")
-    terminal = slot_public(auth, "/tasks/%d/terminal" % run_task, "terminal")
-    ids = [int(s["id"]) for s in terminal["sessions"]]
-    check(ids == sorted(ids, reverse=True),
-          "the session dropdown lists newest-first")
-    check(int(terminal["session_id"]) == ids[0],
-          "the terminal still defaults to the latest session")
-    labels = {int(s["id"]): s["label"] for s in terminal["sessions"]}
-    check(all(label.startswith("Session #") for label in labels.values()),
-          "dropdown labels read 'Session #N — started <time>'")
-    # Recompute at the check point: the C1 answers above each
-    # resumed the agent too, so the earlier snapshot would go stale.
-    conn = db()
-    resumed_ids = [int(i) for (i, text) in conn.execute(
-        "select id, resume_notice from sessions where task_id = ?",
-        (run_task,)).fetchall() if text]
-    conn.close()
-    resumed_markers = [i for i in ids if "[resumed]" in labels[i]]
-    check(set(resumed_markers) == set(resumed_ids),
-          "the [resumed] marker rides exactly the notice-carrying sessions")
-    notices_by_id = {int(s["id"]): s.get("notice") or "" for s in terminal["sessions"]}
-    check("Opening brief" in notices_by_id[min(ids)]
-          and "Drive the plan-14 goal surface" in notices_by_id[min(ids)],
-          "session 1's panel shows the opening-brief framing (from the goal brief)")
-    check(any("Plan feedback received" in (notices_by_id[i] or "") for i in resumed_ids),
-          "a resumed session's panel shows the stored resume notice")
-    terminal_page = http_get_page(auth, "/tasks/%d/terminal" % run_task)
-    check('id="session-select"' in terminal_page
-          and "window.terminalPickSession" in terminal_page,
-          "the session picker is an options dropdown")
-    check('stm-markdown="window.terminalSessionNotice(terminal)"' in terminal_page,
-          "the panel renders the selected session's notice as markdown")
-    check("No opening brief or resume notice recorded" in terminal_page,
-          "the panel ships its graceful empty state")
-    css = open(os.path.join(REPO, "src/pages/app.css")).read()
-    check("resume-notice-panel" in css and "max-height: 200px" in css,
-          "the panel is a 200px vertical-scroll strip (stylesheet)")
-
-    print("== B1: requeue-to-resume from the goal head ==")
-    conn = db()
-    conn.execute("update saddles set status = 'offline' where id = ?", (fake_id,))
-    conn.commit()
-    conn.close()
-
-    def requeue_offered():
-        # Act on the SAME state that satisfied the wait: a second read
-        # once raced the scripted daemon's ask reviving the saddle row,
-        # and the conditionally-authored action vanished between the
-        # two reads (KeyError on act).
-        offered = goal_state(goal)
-        return offered if offered.get("requeue_run") is not None else False
-    state = wait_for(requeue_offered, timeout=30, what="requeue offered")
-    check(state is not None,
-          "a parked run on a dead saddle offers Requeue-to-resume")
-    check(state.get("retry_run") is None,
-          "an active goal offers no Retry supervision")
-    open_before = open_session(run_task)
-
-    def parked_session_ended():
-        if open_before is None:
-            return True
-        conn = db()
-        try:
-            return conn.execute(
-                "select ended_at is not null from sessions where id = ?",
-                (open_before,)).fetchone()[0] == 1
-        finally:
-            conn.close()
-    act(auth, state["requeue_run"], {})
-    check(task_state(auth, run_task)["status"] == "queued",
-          "the requeue returns the run to the queue")
-    # The PARKED session itself must end (the restore-on-dispatch
-    # successor may open immediately — the check keys the old row,
-    # not the task's transient open-session window).
-    check(wait_for(parked_session_ended, timeout=60,
-                   what="parked session closed") is not None,
-          "the requeue closed the parked session (restore-on-dispatch)")
-    conn = db()
-    conn.execute("update saddles set status = 'idle' where id = ?", (fake_id,))
-    conn.commit()
-    conn.close()
-    fake.goal_script = [("suspend",)]
-    check(wait_for(lambda: task_state(auth, run_task)["status"] == "suspended"
-                   or False, timeout=60, what="requeued run re-dispatches") is not None,
-          "the requeued run re-dispatches and re-parks")
-    fresh_session = open_session(run_task)
-    conn = db()
-    fresh_notice = conn.execute(
-        "select resume_notice from sessions where id = ?", (fresh_session,)
-    ).fetchone()[0]
-    conn.close()
-    check(fresh_notice is None,
-          "a requeue's fresh session carries no resume notice (empty panel state)")
-
-    print("== B1: Retry supervision revives a failed goal ==")
-    fake.push_results("failed", summary="the supervision collapsed (scripted)")
-    check(wait_for(lambda: goal_state(goal)["status"] == "failed" or False,
-                   timeout=30, what="goal fails") is not None,
-          "the run's failure fails the goal")
-    check(wait_for(lambda: goal_state(goal).get("retry_run") is not None
-                   or False, timeout=30, what="retry offered") is not None,
-          "a failed goal offers Retry supervision")
-    fake.goal_script = [("suspend",)]
-    act(auth, goal_state(goal)["retry_run"], {})
-    state = goal_state(goal)
-    check(state["status"] == "active",
-          "the retry revives supervision (goal back to active)")
-    check(task_state(auth, run_task)["status"] in ("queued", "assigned", "working",
-                                                   "suspended", "blocked"),
-          "the retry re-offered the run task")
-    check(wait_for(lambda: task_state(auth, run_task)["status"] == "suspended"
-                   or False, timeout=60, what="retried supervision parks") is not None,
-          "the retried supervision dispatches and parks again")
-    state = goal_state(goal)
-    check(any(e["kind"] == "system" and "Supervision retried" in e["text"]
-              for e in state["events"]),
-          "the narrative records the supervision retry (a system row)")
-
-    print("== B5 + C4: order, effective rules, capability badges ==")
-    goal_page = http_get_page(auth, "/goals/%d" % goal)
-    markers = [
-        ('class="card goal-head"', "status head"),
-        ("Agent progress", "progress"),
-        ("Goal agent blocks", "attention blocks"),
-        ("<h3>Plan</h3>", "plan"),
-        ("<h3>Tasks</h3>", "tasks"),
-        ("Initial brief", "brief"),
-        ("Involved projects", "projects"),
-        ("<h3>Rules</h3>", "rules"),
-        ("Supervision narrative", "narrative"),
-        ("<h3>Comments</h3>", "comments"),
-        ("Goal agent runs", "runs"),
-    ]
-    positions = []
-    for marker, _ in markers:
-        check(marker in goal_page, "the goal page ships the %s section" % _)
-        positions.append(goal_page.index(marker))
-    check(positions == sorted(positions),
-          "the page reads status → progress → attention → plan → tasks → brief →"
-          " rules → narrative → comments → runs (in order)")
-    check("goal.current_activity" in goal_page and "Current activity" not in goal_page,
-          "the activity lives as ONE muted head line (the card is gone)")
-    check(".goal-page .card" in open(os.path.join(REPO, "src/pages/app.css")).read(),
-          "the stylesheet restores the goal page's card rhythm (padding regression)")
-
-    rules_state = slot_public(auth, "/rules", "rules")
-    act(auth, rules_state["create"], {"name": "goalui-primary", "body": "Primary rule"})
-    act(auth, rules_state["create"], {"name": "goalui-codev", "body": "Co-dev rule"})
-    act(auth, rules_state["create"], {"name": "goalui-ref", "body": "Reference rule"})
-    conn = db()
-    rule_ids = {name: int(conn.execute("select id from rules where name = ?",
-                                       (name,)).fetchone()[0])
-                for name in ("goalui-primary", "goalui-codev", "goalui-ref")}
-    conn.execute("insert into rule_projects (rule_id, project_id, created_at)"
-                 " values (?, 1, strftime('%s','now'))", (rule_ids["goalui-primary"],))
-    conn.execute("insert into projects (name, git_url, default_branch, created_at)"
-                 " values ('goalui-codev-project', 'https://example.com/g.git',"
-                 " 'main', strftime('%s','now'))")
-    codev_project = conn.execute(
-        "select id from projects where name = 'goalui-codev-project'").fetchone()[0]
-    conn.execute("insert into projects (name, git_url, default_branch, created_at)"
-                 " values ('goalui-ref-project', 'https://example.com/r.git',"
-                 " 'main', strftime('%s','now'))")
-    ref_project = conn.execute(
-        "select id from projects where name = 'goalui-ref-project'").fetchone()[0]
-    conn.execute("insert into rule_projects (rule_id, project_id, created_at)"
-                 " values (?, ?, strftime('%s','now'))",
-                 (rule_ids["goalui-codev"], codev_project))
-    conn.execute("insert into rule_projects (rule_id, project_id, created_at)"
-                 " values (?, ?, strftime('%s','now'))",
-                 (rule_ids["goalui-ref"], ref_project))
-    conn.commit()
-    conn.close()
-    act(auth, goal_state(goal)["add_link"], {"linked_project_id": str(codev_project),
-                                             "relationship": "co-developed"})
-    act(auth, goal_state(goal)["add_link"], {"linked_project_id": str(ref_project),
-                                             "relationship": "reference"})
-    rule_names = [r["name"] for r in goal_state(goal)["rules"]]
-    check(rule_names == ["goalui-primary", "goalui-codev"],
-          "the Rules section lists the goal's effective set (primary then"
-          " co-developed; reference contributes nothing)")
-
-    act(auth, slot_public(auth, "/saddles", "saddles")["create_capability"],
-        {"name": "goalui-capability"})
-    conn = db()
-    capability = conn.execute(
-        "select id from capabilities where name = 'goalui-capability'"
-    ).fetchone()[0]
-    # The early redirect-fixture worker joins the goal (a fanned
-    # worker's shape) so its row carries the badge too.
-    conn.execute("update tasks set goal_id = ? where id = ?", (goal, worker))
-    conn.execute("insert into task_capabilities (task_id, capability_id)"
-                 " values (?, ?)", (worker, capability))
-    conn.commit()
-    conn.close()
-    goal_worker = {"id": worker, "caps": None}
-    act(auth, slot_public(auth, "/tasks", "tasks")["create"], {
-        "project_id": "1", "title": "Goalui fanned worker", "priority": "4",
-        "description": "A worker the agent fanned out."})
-    conn = db()
-    fanned = conn.execute(
-        "select id from tasks where title = 'Goalui fanned worker'").fetchone()[0]
-    conn.execute("update tasks set goal_id = ? where id = ?", (goal, fanned))
-    conn.execute("insert into task_capabilities (task_id, capability_id)"
-                 " values (?, ?)", (fanned, capability))
-    conn.commit()
-    conn.close()
-    rows = {int(t["id"]): t for t in goal_state(goal)["goal_tasks"]}
-    check(rows[fanned].get("capabilities") == ["goalui-capability"]
-          and rows[worker].get("capabilities") == ["goalui-capability"],
-          "task rows carry their required capability tags")
-    goal_page = http_get_page(auth, "/goals/%d" % goal)
-    check('stm-for-capability-in="goal_task.capabilities"' in goal_page
-          and "badge-capability" in goal_page,
-          "the task rows render capability badges")
-
-    print("== B6: narrative weights — events full, comments footnote ==")
-    # An AGENT comment projects the narrative's comment event (human
-    # comments only thread) — pushed through the entries channel while
-    # parked, so the suspended state stays put.
-    fake.push_results("suspended", entries=[{
-        "id": 9001, "command": "saddle comment", "output": "An agent aside.",
-        "exit_code": 0, "type": "comment", "timestamp": "2026-09-12T00:00:00Z"}])
-    check(wait_for(lambda: any(e["kind"] == "comment"
-                               for e in goal_state(goal)["events"]) or False,
-                   timeout=15, what="comment event lands") is not None,
-          "an agent comment lands as a narrative event")
-    goal_page = http_get_page(auth, "/goals/%d" % goal)
-    check("stm-attribute.class=\"'goal-event' + (event.kind == 'comment'"
-          " ? ' footnote' : '')\"" in goal_page.replace("\n", " ").replace("  ", " ")
-          or "'goal-event' + (event.kind == 'comment' ? ' footnote' : '')" in goal_page,
-          "the WHOLE comment event row carries .footnote (badge included)")
-    check("'badge badge-goal-' + event.kind" in goal_page,
-          "non-comment events keep their full-weight kind badges")
-    css = open(os.path.join(REPO, "src/pages/app.css")).read()
-    check(".goal-event.footnote" in css and ".footnote {" in css,
-          "the stylesheet ships the footnote row weight beside the utility")
-
-    print("== C2: system rows render distinctly on the ONE thread ==")
-    run_comments = task_state(auth, run_task)["comments"]
-    system_rows = [c for c in run_comments if c.get("is_system")]
-    check(system_rows and all(c["author"] == "system" for c in system_rows)
-          and not any(c.get("from_agent") for c in system_rows),
-          "the harness bookkeeping rows are authored 'system' (never agent)")
-    goal_thread = goal_state(goal)["comments"]
-    check(any(c.get("is_system") for c in goal_thread),
-          "the goal page reads the same thread (the system rows included)")
-    css = open(os.path.join(REPO, "src/pages/app.css")).read()
-    check(".comment.system" in css and ".system-label" in css,
-          "the stylesheet ships the distinct system-event styling")
-    page = http_get_page(auth, "/goals/%d" % goal)
-    check("comment.is_system" in page and "system-label" in page,
-          "the goal page renders system rows with the labelled muted style")
-    task_page = http_get_page(auth, "/tasks/%d" % worker)
-    check("comment.is_system" in task_page and "system-label" in task_page,
-          "the task page renders system rows with the same style")
-
-    print("== S5 U2: mechanical rows filtered from user-facing timelines ==")
-    # The daemon's mechanical system entries (the park notice, the
-    # restore footnote) ride the wire typed 'system': the raw terminal
-    # row STORES (session_commands), but no comment row, narrative
-    # event or dashboard timeline row is authored for them.
-    open_run = open_session(run_task)
-    mechanical = [
-        {"id": 9501, "command": "saddle suspend",
-         "output": "goal agent parked until an owned task completes or"
-                   " fails; resume via /start resume_notice",
-         "exit_code": 0, "type": "system", "timestamp": "2026-09-12T00:00:00Z"},
-        {"id": 9502, "command": "harness resume",
-         "output": "[harness] session context restored — task resumed",
-         "exit_code": 0, "type": "system", "timestamp": "2026-09-12T00:00:01Z"},
-    ]
-    status, _ = saddle_api("POST", "/api/saddle/results", fake_token,
-                           {"session_id": open_run, "state": "suspended",
-                            "entries": mechanical})
-    check(status == 200, "the mechanical system entries push cleanly")
-    conn = db()
-    raw_rows = conn.execute(
-        "select count(*) from session_commands where session_id = ?"
-        " and type = 'system'", (open_run,)).fetchone()[0]
-    conn.close()
-    check(raw_rows >= 2,
-          "the raw terminal keeps the mechanical rows (typed entries store)")
-    check(all("parked until" not in c["body"]
-              and "session context restored" not in c["body"]
-              for c in task_state(auth, run_task)["comments"]),
-          "no mechanical comment row lands on the thread (U2)")
-    check(all("parked until" not in e["text"]
-              and "session context restored" not in e["text"]
-              for e in goal_state(goal)["events"]),
-          "no mechanical narrative event lands on the goal page (U2)")
-    dash_events = slot_public(auth, "/", "dashboard")["activity"]
-    check(all("parked until" not in e["text"]
-              and "session context restored" not in e["text"]
-              for e in dash_events),
-          "no mechanical row lands on the dashboard timeline (U2)")
-
-    print("== C4: head line, answered-blocks expander, footnote comments ==")
-    state = goal_state(goal)
-    check(state["current_activity"] == "parked awaiting its tasks' terminal transitions",
-          "a suspended run folds into the one muted head line")
-    check(len(state.get("answered_blocks") or []) >= 2
-          and len(state.get("open_blocks") or []) == 0,
-          "the historic answered blocks expose as their own vector (open ones empty)")
-    goal_page = http_get_page(auth, "/goals/%d" % goal)
-    check("Answered blocks (" in goal_page and "comment-meta" in goal_page,
-          "the answered blocks and the footnote comment meta ship in the markup")
-    check("timeless note for a future reader" in goal_page,
-          "the composer hint states the timeless-comment rule")
-    css = open(os.path.join(REPO, "src/pages/app.css")).read()
-    check(".goal-page .card { margin-bottom" in css and ".comment-meta" in css,
-          "the stylesheet ships the card rhythm and the comment footnote meta")
-
-    print("== C1: one review block per verdict path (F6) ==")
-    # The daemon's honest round pushes the ENTRY and the STATE
-    # together — the done pair must raise exactly ONE completion
-    # block, and a redelivered pair nothing more.
-    fake.goal_script = [("done", "# Completion\n\nOne block only.")]
-    conn = db()
-    conn.execute("insert into tasks (project_id, goal_id, kind, title, status,"
-                 " priority, completed_at, created_at) values (1, ?, 'task',"
-                 " 'Warmup', 'done', 5,"
-                 " strftime('%s','now'),"
-                 " strftime('%s','now','-30 seconds'))", (goal,))
-    conn.commit()
-    conn.close()
-    check(wait_for(lambda: goal_state(goal)["status"] == "completion_review" or False,
-                   timeout=60, what="goalui completion review opens") is not None,
-          "the scripted done round enters completion review")
-    def completion_block_count():
-        conn = db()
-        try:
-            return conn.execute(
-                "select count(*) from task_blocks where task_id = ?"
-                " and type = 'completion'", (run_task,)).fetchone()[0]
-        finally:
-            conn.close()
-    check(completion_block_count() == 1,
-          "the done state raises exactly ONE completion block")
-    # Plan 16 S5 (U1): the verdict-shaped block renders the rich review
-    # form — explicit accept/reject affordances with the free-text
-    # feedback path, never a free-text-only verdict.
-    goal_page = http_get_page(auth, "/goals/%d" % goal)
-    check("Accept goal" in goal_page and "Reject with feedback" in goal_page
-          and 'name="feedback"' in goal_page,
-          "the completion review presents explicit accept/reject + free-text feedback (U1)")
-    # The burst shape: the done ENTRY and the done STATE in one push
-    # (fresh entry ids), then the whole pair redelivered — the
-    # pending-report idempotency leaves the one row alone.
-    conn = db()
-    burst_session = conn.execute(
-        "select id from sessions where task_id = ? and ended_at is null",
-        (run_task,)).fetchone()[0]
-    conn.close()
-    done_pair = [{"id": 9401, "command": "saddle done",
-                  "output": "# Completion\n\nOne block only.", "exit_code": 0,
-                  "type": "done", "timestamp": "2026-09-12T00:00:00Z"}]
-    status, _ = saddle_api("POST", "/api/saddle/results", fake_token,
-                           {"session_id": burst_session, "state": "done",
-                            "entries": done_pair,
-                            "summary": "# Completion\n\nOne block only."})
-    check(status == 200 and completion_block_count() == 1,
-          "the done entry + state pair raises nothing more (one block, ever)")
-    state = goal_state(goal)
-    act(auth, state["completion_pending_block"]["answer_action"],
-        {"verdict": "accept"})
-    check(wait_for(lambda: goal_state(goal)["status"] == "complete" or False,
-                   timeout=30, what="goalui goal completes") is not None,
-          "accepting the completion completes the goal")
-    check(completion_block_count() == 1,
-          "the accept path leaves exactly one review-kind block behind")
-    conn = db()
-    stragglers = conn.execute(
-        "select count(*) from task_blocks where task_id = ? and answer is null",
-        (run_task,)).fetchone()[0]
-    conn.close()
-    check(stragglers == 0,
-          "no unanswered straggler rows survive the completion")
-
-    print("== S2: server-owned verdicts + the container-resolved reject ==")
-    # A fresh goal drives the verdict paths the goal page's forms now
-    # use: verdict markers for accept, raw `feedback` for reject, and
-    # the block resolution living in the review CONTAINER (not
-    # goal.plan_pending_block — the diagnosed completion-review bug).
-    fake.goal_script = [("plan", "# S2 plan\n\nOne step")]
-    act(auth, slot_public(auth, "/goals", "goals")["create"], {
-        "project_id": "1", "title": "S2 verdict goal",
-        "brief": "Covers the plan-16 S2 verdict paths.",
-        "branch_name": "goal/s2-verdicts"})
-    conn = db()
-    s2_goal = int(conn.execute(
-        "select id from goals where title = 'S2 verdict goal'").fetchone()[0])
-    conn.close()
-    act(auth, goal_state(s2_goal)["start"], {})
-    check(wait_for(lambda: goal_state(s2_goal)["status"] == "plan_review" or False,
-                   timeout=90, what="S2 goal enters plan review") is not None,
-          "the S2 goal enters plan review")
-    s2_state = goal_state(s2_goal)
-    s2_pending = s2_state["plan_pending_block"]
-
-    # (1) A remark-less, text-less rejection is refused: the action
-    # errors and the block keeps waiting.
-    refusal = act(auth, s2_pending["answer_action"], {"feedback": "   "})
-    check(any(d.get("type") == "notify" and d.get("kind") == "error"
-              and "answer is required" in (d.get("message") or "").lower()
-              for d in refusal),
-          "a remark-less, text-less rejection is refused with an error")
-    conn = db()
-    s2_still_open = conn.execute(
-        "select answer from task_blocks where id = ?",
-        (s2_pending["id"],)).fetchone()[0]
-    conn.close()
-    check(s2_still_open is None,
-          "the refused rejection leaves the block unanswered")
-
-    # (3) The goal page template ships no verdict constants and its
-    # script resolves the review block from ANY [data-plan-review]
-    # container via the open-blocks list (the completion-review fix).
-    # Fetched while the review is open so the accept form renders.
-    s2_page = http_get_page(auth, "/goals/%d" % s2_goal)
-    check("Plan approved. Proceed with implementation." not in s2_page
-          and "Review approved. Continue with the task." not in s2_page,
-          "the goal page ships no verdict constants (server-owned wording)")
-    check('name="verdict" value="accept"' in s2_page,
-          "the goal page's accept forms post the verdict marker")
-    check("resolveReviewBlock" in s2_page and "goal.open_blocks" in s2_page,
-          "the reject flow resolves its block from the open-blocks list (container-keyed)")
-    check("statum.act(block.answer_action, { feedback: feedback })" in s2_page,
-          "the reject flow posts raw feedback (the server wraps the prefix)")
-    check("extraText.length === 0" in s2_page,
-          "a remark-less rejection with textarea content is allowed (S2)")
-
-    # (2) The goal page's reject rides `feedback` (the client composes
-    # the numbered-remarks body) and the SERVER wraps it with the plan
-    # prefix — byte-identical to the historical client-built answer.
-    act(auth, s2_pending["answer_action"],
-        {"feedback": "> ## One step\n\n1. Tighten it\n\n2. Name the owner"})
-    conn = db()
-    s2_wrapped = conn.execute(
-        "select answer from task_blocks where id = ?",
-        (s2_pending["id"],)).fetchone()[0]
-    conn.close()
-    check(s2_wrapped
-          == "Plan feedback received:\n\n"
-             "> ## One step\n\n1. Tighten it\n\n2. Name the owner",
-          "the plan rejection wraps the client-shaped body with the stable prefix (%r)"
-          % s2_wrapped)
-    check(goal_state(s2_goal)["status"] == "planning",
-          "the feedback rejection returns the agent to planning")
-
-
-BUNDLES_ORDER = ("pages", "dispatch", "subtasks", "lineage",
-                 "allocation", "lifecycle", "answers", "push", "goals",
-                 "replay", "goalui")
-
-
-def run_bundle(name):
-    """Runs one shard to completion; returns a failure count."""
-    started = time.monotonic()
-    ctx = start_bundle(name)
-    runner = globals()["bundle_" + name]
-    try:
-        runner(ctx)
-    finally:
-        # Exit-code diagnostic: distinguishes a crashed app (negative
-        # returncode, e.g. -11 SIGSEGV) from a clean shutdown. When
-        # tearing down mid-exception, also capture the still-alive
-        # app's stacks before killing it (a wedged-but-alive server
-        # otherwise leaves no evidence).
-        print("(app returncode at teardown: %s)" % ctx.app.poll())
-        if ctx.app.poll() is None and sys.exc_info()[0] is not None:
-            dump_app_stacks(ctx.app.pid)
-        ctx.fake.kill()
-        try:
-            ctx.app.terminate()
-            try:
-                ctx.app.wait(timeout=5)
-            except subprocess.TimeoutExpired:
-                ctx.app.kill()
-            check(ctx.app.poll() in (0, -15),
-                  "bundle %s app shut down cleanly (exit %s)"
-                  % (name, ctx.app.poll()))
-        except OSError:
-            pass
-    print("%d passed, %d failed" % (passes, failures))
-    print("[bundle %s] %.1fs" % (name, time.monotonic() - started))
-    return failures
-
-
-def run_all_parallel():
-    """The default meson entry: one subprocess per bundle (each with its
-    own app, daemons and database), verdicts aggregated into one exit
-    code and one combined check-count summary."""
-    base = os.environ.get("WEBSTACK_WORK", "/tmp/kilo/webstack-e2e")
-    log_dir = os.path.join(os.path.dirname(base) or "/tmp/kilo",
-                           "webstack-shards")
-    os.makedirs(log_dir, exist_ok=True)
-    procs = {}
-    started = time.monotonic()
-    for name in BUNDLES_ORDER:
-        out_path = os.path.join(log_dir, "bundle-%s.log" % name)
-        handle = open(out_path, "w")
-        procs[name] = (subprocess.Popen(
-            [sys.executable, "-u", os.path.abspath(__file__), APP,
-             "--bundle", name],
-            stdout=handle, stderr=subprocess.STDOUT), handle, out_path)
-    total_pass = total_fail = 0
-    broken = []
-    for name, (proc, handle, out_path) in procs.items():
-        try:
-            proc.wait(timeout=SHARD_TIMEOUT_S)
-        except subprocess.TimeoutExpired:
-            proc.kill()
-            proc.wait()
-        handle.close()
-        text = open(out_path).read()
-        match = re.search(r"(\d+) passed, (\d+) failed", text)
-        took = re.search(r"\[bundle %s\] ([0-9.]+)s" % name, text)
-        bundle_pass = int(match.group(1)) if match else 0
-        bundle_fail = int(match.group(2)) if match else -1
-        total_pass += max(bundle_pass, 0)
-        total_fail += max(bundle_fail, 0)
-        status = "ok"
-        if proc.returncode != 0 or bundle_fail != 0 or match is None:
-            status = "BROKEN (exit %s)" % proc.returncode
-            broken.append(name)
-        print("[shard %-10s] %6ss  %3d passed %3d failed  %s"
-              % (name, took.group(1) if took else "?",
-                 bundle_pass, bundle_fail, status))
-        if status != "ok":
-            tail = "\n".join(text.rstrip().split("\n")[-60:])
-            print("--- web-stack/%s tail (full log: %s) ---" % (name, out_path))
-            print(tail)
-            print("--- end web-stack/%s tail ---" % name)
-    print("shards wall: %.1fs  (logs under %s)" % (time.monotonic() - started, log_dir))
-    print("ALL SHARDS: %d passed, %d failed%s"
-          % (total_pass, total_fail,
-             "" if not broken else "  BROKEN: " + ", ".join(broken)))
-    return 1 if broken or total_fail else 0
-
 
-def main():
-    if not os.path.exists(APP):
-        raise SystemExit("app binary not found at %s (build first)" % APP)
-    argv = sys.argv[2:]
-    if "--bundle" in argv:
-        sys.exit(1 if run_bundle(argv[argv.index("--bundle") + 1]) else 0)
-    if os.environ.get("WEBSTACK_SEQUENTIAL"):
-        # Debug path: every bundle in-process, one after another.
-        for name in BUNDLES_ORDER:
-            if run_bundle(name):
-                return 1
-        return 0
-    return run_all_parallel()
+sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
 
+import harness  # noqa: E402
 
 if __name__ == "__main__":
-    sys.exit(main())
+    sys.exit(harness.main())