test(handlers/mcp): correct RecallMemory_GlobalScope to expect descriptive error
Some checks failed
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 15s
CI / Detect changes (pull_request) Successful in 20s
E2E API Smoke Test / detect-changes (pull_request) Successful in 26s
Harness Replays / detect-changes (pull_request) Successful in 17s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 14s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 29s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 32s
qa-review / approved (pull_request) Failing after 18s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 30s
sop-checklist / all-items-acked (pull_request) [soft-fail tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: 7
security-review / approved (pull_request) Failing after 20s
sop-checklist-gate / gate (pull_request) Successful in 19s
gate-check-v3 / gate-check (pull_request) Successful in 29s
sop-tier-check / tier-check (pull_request) Successful in 20s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m25s
CI / Canvas (Next.js) (pull_request) Successful in 9s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 6s
CI / Python Lint & Test (pull_request) Successful in 9s
Harness Replays / Harness Replays (pull_request) Successful in 17s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 14s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 8s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Failing after 6m0s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 7m48s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
CI / Platform (Go) (pull_request) Failing after 14m8s
CI / all-required (pull_request) Failing after 4s

Aligns with PR #669's fix to mcp.go: the descriptive GLOBAL scope error
("GLOBAL scope is not permitted via the MCP bridge — use LOCAL, TEAM, or empty")
now propagates to the caller. The OFFSEC-001 scrub applies only to "unknown
tool:" errors (to avoid leaking tool names); permission/usage errors are
returned verbatim. Test name updated to reflect actual behavior.

Branch: fix/681-recall-memory-offsec-scrub (PR #693)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Molecule AI · core-be 2026-05-12 07:34:23 +00:00
parent a9351ae47d
commit fe3c9ee4fd

View File

@ -548,7 +548,13 @@ func TestMCPHandler_CommitMemory_CleanContent_PassesThrough(t *testing.T) {
// tools/call — recall_memory
// ─────────────────────────────────────────────────────────────────────────────
func TestMCPHandler_RecallMemory_GlobalScope_Blocked(t *testing.T) {
// TestMCPHandler_RecallMemory_GlobalScope_ReturnsDescriptiveError verifies C3
// (GLOBAL scope blocked on MCP bridge) is enforced and the error message
// propagates to the caller. Unlike "unknown tool:" errors (OFFSEC-001), which
// are scrubbed to a constant "tool call failed" to avoid leaking tool names,
// permission/usage errors like "GLOBAL scope is not permitted" are returned
// verbatim so callers (including tests) can assert on permission messages.
func TestMCPHandler_RecallMemory_GlobalScope_ReturnsDescriptiveError(t *testing.T) {
h, mock := newMCPHandler(t)
// No DB expectations — handler must abort before touching the DB.
@ -568,7 +574,17 @@ func TestMCPHandler_RecallMemory_GlobalScope_Blocked(t *testing.T) {
var resp mcpResponse
json.Unmarshal(w.Body.Bytes(), &resp)
if resp.Error == nil {
t.Error("expected JSON-RPC error for GLOBAL scope recall, got nil")
t.Fatal("expected JSON-RPC error for GLOBAL scope recall, got nil")
}
// Error code is -32000 (server error).
if resp.Error.Code != -32000 {
t.Errorf("expected error code -32000, got %d", resp.Error.Code)
}
// Descriptive error message propagates to the caller. The OFFSEC-001 scrub
// applies only to "unknown tool:" errors (to avoid leaking tool names).
want := "GLOBAL scope is not permitted via the MCP bridge — use LOCAL, TEAM, or empty"
if resp.Error.Message != want {
t.Errorf("error message: got %q, want %q", resp.Error.Message, want)
}
if err := mock.ExpectationsWereMet(); err != nil {
t.Errorf("unexpected DB calls on GLOBAL scope block: %v", err)