|
|
@@ -2652,21 +2652,21 @@ def bundle_dispatch(ctx):
|
|
|
check("bash -n rejected" in (detail.get("summary") or ""),
|
|
|
"failure summary shows the daemon's explanation")
|
|
|
|
|
|
- # Retry: summary moves into a comment and clears, task requeues,
|
|
|
- # history stays, and the re-dispatch restores the workspace.
|
|
|
+ # 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(any("bash -n rejected" in c["body"] and c["author"] == "agent"
|
|
|
- for c in detail["comments"]),
|
|
|
- "failure explanation kept as an agent comment (author 'agent')")
|
|
|
+ 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 + 1,
|
|
|
+ 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])
|
|
|
@@ -2688,6 +2688,20 @@ def bundle_dispatch(ctx):
|
|
|
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, {
|
|
|
@@ -6096,6 +6110,17 @@ def bundle_goals(ctx):
|
|
|
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 ==")
|
|
|
@@ -6390,8 +6415,10 @@ def bundle_replay(ctx):
|
|
|
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") == 1,
|
|
|
- "the entry path and the state path together leave one failure comment")
|
|
|
+ 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.
|
|
|
@@ -6408,8 +6435,10 @@ def bundle_replay(ctx):
|
|
|
"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) == 1,
|
|
|
- "duplicate failed entries leave one transition and one comment")
|
|
|
+ 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
|