docs(6209): calibration stamp, after-write hook, usage seam, work log, duplicates, skill structure, tuning and rulebook routes, kind surface, prompt filter, moments, strict args, auth, lesson write path
Fourteen more test files: docstrings state the failure each guard defends as a present-tense shape instead of the incident that found it, and issue, milestone and rule numbers leave comments and assertion messages. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,13 +1,12 @@
|
||||
"""Unknown tool arguments are rejected, never silently dropped (#2709).
|
||||
"""Unknown tool arguments are rejected, never silently dropped.
|
||||
|
||||
The failure this pins: MCPServer validates tool arguments with a pydantic model
|
||||
whose extra-field policy is "ignore", so `create_note(content=...)` — a
|
||||
plausible near-miss for `body=`, primed by add_task_log's `content` — ran
|
||||
successfully, stored `body: ""`, and left a record embedding/search cannot
|
||||
see. The call REPORTED SUCCESS. Two real notes were persisted body-less
|
||||
before the pattern was noticed.
|
||||
plausible near-miss for `body=`, primed by add_task_log's `content` — would
|
||||
run, store `body: ""`, and leave a record embedding/search cannot see, while
|
||||
REPORTING SUCCESS.
|
||||
|
||||
The fix is at the dispatch seam, not per-tool: StrictArgsMCPServer rejects any
|
||||
The rejection is at the dispatch seam, not per-tool: StrictArgsMCPServer rejects any
|
||||
call carrying arguments the tool does not declare, with a did-you-mean when
|
||||
one is close. An error the caller sees once beats data half-written forever.
|
||||
"""
|
||||
@@ -59,11 +58,11 @@ async def test_unknown_tool_keeps_the_upstream_error():
|
||||
assert "no_such_tool" in str(exc.value)
|
||||
|
||||
|
||||
# --- a refusal's text reaches the agent (#4794) -------------------------------
|
||||
# --- a refusal's text reaches the agent ---------------------------------------
|
||||
#
|
||||
# SDK 2.x passes on only a ToolError's text; anything else is wrapped as
|
||||
# "Error executing tool X" and its message is kept on the server. ValueError is
|
||||
# how every Scribe tool refuses, so for weeks every refusal arrived bare.
|
||||
# how every Scribe tool refuses, so without this every refusal arrives bare.
|
||||
|
||||
|
||||
def _raising_server() -> StrictArgsMCPServer:
|
||||
@@ -112,7 +111,7 @@ async def test_a_real_tools_refusal_reaches_the_caller():
|
||||
|
||||
|
||||
async def test_the_original_regression_create_note_with_content():
|
||||
"""Pin #2709 itself against the REAL server: `content=` on create_note
|
||||
"""Against the REAL server: `content=` on create_note
|
||||
must raise before dispatch — naming the bad argument and listing `body`
|
||||
among the accepted ones — instead of creating a body-less note."""
|
||||
from scribe.mcp.server import build_mcp_server
|
||||
|
||||
Reference in New Issue
Block a user