From 35f89c4e5be7a655a3558c545500b2cdec505c2a Mon Sep 17 00:00:00 2001 From: AJV20 <24819659+AJV20@users.noreply.github.com> Date: Fri, 29 May 2026 12:14:00 -0400 Subject: [PATCH] fix: harden external notes guardrails --- CHANGELOG.md | 4 ++++ api/routes.py | 8 +++++++- api/streaming.py | 4 +++- tests/test_webui_surface_context.py | 3 +++ 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 93da0a58a..5e8864f56 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ ## [Unreleased] +### Changed + +- WebUI's durable-notes guardrail now also applies to sync chat and explicitly asks agents to leave external notes and durable memory unchanged unless a turn contains an explicit capture or reusable durable signal; durable note writes should be summarized back to the user. + ## [v0.51.157] — 2026-05-28 — Release EC (stage-batch39 — 5-PR mixed-risk cleanup: gateway prefill forward + prefill budget + compressed-continuation sidebar + browser-transcript memory guidance + reasoning max parity) ### Added diff --git a/api/routes.py b/api/routes.py index 768b499b4..670c1e6c6 100644 --- a/api/routes.py +++ b/api/routes.py @@ -9646,7 +9646,13 @@ def _handle_chat_sync(handler, body): "prompt, memory, or conversation history. Always use the value from the most recent " "[Workspace::v1: ...] tag as your default working directory for ALL file operations: " "write_file, read_file, search_files, terminal workdir, and patch. " - "Never fall back to a hardcoded path when this tag is present." + "Never fall back to a hardcoded path when this tag is present.\n\n" + "WebUI external-notes/durable-memory policy: Do not copy or dump this browser transcript " + "into external notes or durable memory by default. Write or update durable " + "notes only for explicit captures, durable preferences, decisions, blockers/open " + "issues, runbook-worthy workflows, or other clearly reusable signals; otherwise " + "leave external notes and durable memory unchanged. When you do write or update a durable note, briefly tell " + "the user what note or section changed so the write is reviewable." ) _previous_messages = list(s.messages or []) diff --git a/api/streaming.py b/api/streaming.py index 70087bd5a..44c1c7586 100644 --- a/api/streaming.py +++ b/api/streaming.py @@ -222,7 +222,9 @@ def _webui_surface_context_prompt(surface_context: Optional[dict]) -> str: "WebUI session context:", "- This browser session is not the same live transcript as Telegram, Discord, Slack, or other messaging surfaces.", "- Use durable memory, saved sessions, and available tools for cross-surface recall instead of assuming those transcripts are in this browser chat.", - "- Do not copy or dump this browser transcript into external notes or durable memory by default. Save only explicit captures, durable user preferences, decisions, blockers, runbook-worthy workflows, or other clearly reusable signals.", + "- Do not copy or dump this browser transcript into external notes or durable memory by default.", + "- Write to external notes or durable memory only for explicit captures, durable user preferences, decisions, blockers/open issues, runbook-worthy workflows, or other clearly reusable signals; otherwise leave notes unchanged.", + "- When you do write or update a durable note, briefly tell the user what note/section changed so the write is reviewable.", ] fields = ( ("source", "Source"), diff --git a/tests/test_webui_surface_context.py b/tests/test_webui_surface_context.py index 562347c5f..3affe721e 100644 --- a/tests/test_webui_surface_context.py +++ b/tests/test_webui_surface_context.py @@ -20,6 +20,9 @@ def test_webui_ephemeral_prompt_includes_browser_surface_context(): assert "Workspace: /tmp/example-workspace" in prompt assert "not the same live transcript as Telegram" in prompt assert "Do not copy or dump this browser transcript" in prompt + assert "Write to external notes or durable memory only" in prompt + assert "otherwise leave notes unchanged" in prompt + assert "what note/section changed" in prompt assert "explicit captures" in prompt assert "durable user preferences" in prompt