[eric] browser: tell a user their DELETION was unconfirmed, not their send

This commit is contained in:
ciregenz
2026-08-03 15:48:33 -07:00
parent 116e44255e
commit aa07ff0728
3 changed files with 29 additions and 1 deletions
+1 -1
View File
@@ -3105,7 +3105,7 @@ async def run_browser_agent(
else:
honest, dishonest_reason = completion_is_honest(
action_log, publish_task=is_publish_task(skill_key_task),
send_confirmed=send_confirmed)
send_confirmed=send_confirmed, removal_task=p_task_is_removal)
final_status = "completed" if honest else "error"
if not honest:
summary = f"I was not able to complete this task ({dishonest_reason})."
@@ -364,6 +364,7 @@ def deliverable_is_informational(summary: str, task: str = "") -> bool:
def completion_is_honest(
action_log: list[dict], publish_task: bool = False, send_confirmed: bool = False,
removal_task: bool = False,
) -> tuple[bool, str]:
"""Reality-check a run the model declared done. Returns (honest, reason).
@@ -383,6 +384,13 @@ def completion_is_honest(
# click runs (a resend guard, not proof), so this can still let a bad send through, but it can
# never newly flag a run that had any send signal at all.
if publish_task and not send_confirmed:
# "delete my post" carries the noun `post`, so is_publish_task calls a DELETE a publish and
# this gate then judged it against a send it was never meant to make. Flagging is right (the
# run proved nothing either way), but the sentence has to describe the task the user gave.
# Telling someone their deletion "may not have gone out" sends them to check the wrong thing.
if removal_task:
return False, ("the deletion was never confirmed, so the item may still be there; "
"check the page before trusting this")
return False, ("the send was never confirmed, so it may not have gone out; "
"check the page before trusting this")
if not action_log:
@@ -72,3 +72,23 @@ def test_the_post_send_backstop_refuses_to_claim_a_send_on_a_removal():
removal_code = [ln for ln in branch.split("elif")[0].splitlines()
if "done_message" in ln and not ln.strip().startswith("#")]
assert removal_code and all("sent" not in ln for ln in removal_code), removal_code
def test_the_completion_gate_describes_the_task_the_user_actually_gave():
"""The fourth site of the same root cause, found while cleaning up after the third.
`is_publish_task` matches the NOUN in "delete my post", so a delete run reaches the publish
branch of the completion gate. Flagging it is right (the run proved nothing either way), but
the sentence was "the send was never confirmed, so it may not have gone out", which points the
user at the wrong page to check: they deleted something, and nothing was ever meant to go out.
"""
from backend.apps.agents.browser.browser_loop import completion_is_honest
honest, why = completion_is_honest([], publish_task=True, send_confirmed=False,
removal_task=True)
assert not honest
assert "deletion" in why and "may still be there" in why
assert "gone out" not in why, "a delete must not be described as a send"
honest, why = completion_is_honest([], publish_task=True, send_confirmed=False)
assert not honest and "gone out" in why, "a real send keeps its own wording"