From df4b37673f370d66af5ae50b1fe7b384892989bb Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Sat, 3 Oct 2026 21:25:37 -0400 Subject: [PATCH] fix(plugin): a subagent hand-back is not an operator prompt (#4785) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `` turns were scored by auto-inject and the prompt rule arm as if the operator had typed them, spending a retrieval and writing a retrieval_logs row that reads as a real message (log 54355, found by the #4772 review). Same class as #4142. Matched up to the tag name, since the tag carries attributes; `` and the tag named mid-sentence are still retrieved against. Plugin 2026.10.04.0125. Co-Authored-By: Claude Opus 5.5 --- plugin/.claude-plugin/plugin.json | 2 +- plugin/hooks/scribe_defs.sh | 1 + tests/test_prompt_boundary_filter.py | 5 +++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/plugin/.claude-plugin/plugin.json b/plugin/.claude-plugin/plugin.json index 013d69dc..bd5458f8 100644 --- a/plugin/.claude-plugin/plugin.json +++ b/plugin/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "scribe", "description": "Scribe for Claude Code: connects the scribe MCP server, adds the hooks that deliver live project state and relevant records at the right moment, ships the shared client-neutral Scribe skills (using-scribe, writing-plans, reporting-back, systematic-debugging, verification, brainstorming, reusing-code, shape-accounting), and syncs your saved Scribe Processes as skills (/scribe:sync).", - "version": "2026.10.03.1934", + "version": "2026.10.04.0125", "author": { "name": "Bryan Van Deusen" }, diff --git a/plugin/hooks/scribe_defs.sh b/plugin/hooks/scribe_defs.sh index 8a4c2deb..2dd48514 100644 --- a/plugin/hooks/scribe_defs.sh +++ b/plugin/hooks/scribe_defs.sh @@ -79,6 +79,7 @@ scribe_skip_prompt() { _scribe_prompt=${1#"${1%%[![:space:]]*}"} case "$_scribe_prompt" in ""*|\ + ""*|""*|""*|""*|\ ""*|""*|""*) return 0 ;; diff --git a/tests/test_prompt_boundary_filter.py b/tests/test_prompt_boundary_filter.py index bd44a403..97862d96 100644 --- a/tests/test_prompt_boundary_filter.py +++ b/tests/test_prompt_boundary_filter.py @@ -52,6 +52,10 @@ SYNTHETIC = [ "Failed to reconnect", "Caveat: The messages below were generated…", " \n\nabc", # whitespace must not walk the filter + # A subagent's hand-back (#4785) — it carries attributes, so the tag is + # matched up to its name, not to a closing `>`. + '\n[Subagent hand-back] The text below is the final report', + "\nreport", ] # Typed by a person. Every one of these must still be retrieved against. @@ -62,6 +66,7 @@ REAL = [ "fix the hookinjected", # tag, but trailing "This session is being continued from a previous conversation.", # see module docstring " is rendering wrong", # a tag, but not one of the client's + " list is empty", # shares the prefix, is not the tag "here is the transcript you asked for:\nhi", ]