feat(mcp): #1754 broadcast ACTIVITY_LOGGED on MCP memory writes #1795
Reference in New Issue
Block a user
Delete Branch "feat/issue-1754-mcp-memory-activity-broadcast"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Closes #1754. The canvas Memory tab (
MemoryInspectorPanel.tsx, post-#1749) subscribes toACTIVITY_LOGGEDWS events filtered to memory-write activity_types so it can live-refresh when an agent commits a memory. But the MCP tool paths bypassLogActivity, so the panel only refreshes via manual reload when an agent commits viacommit_memoryorcommit_memory_v2.Fix
Adds
ACTIVITY_LOGGEDbroadcasts in the three MCP write tools:commit_memory_v2(and legacycommit_memoryvia the shim that routes through this)memory_writecommit_summarymemory_summary_writeforget_memorymemory_deleteReads (
search_memory/recall_memory) intentionally do NOT broadcast — too noisy and not useful for live UI refresh, matching the issue's proposed scope.Implementation notes
logMemoryMCPActivitywrapsLogActivitywith a nil-broadcaster guard.*events.Broadcaster(concrete), NOTevents.EventEmitter(interface). Passing a nil concrete pointer through an interface parameter creates a typed-nil interface that fails to compare equal to nil — and would dereference insideLogActivity. The typed-nil trap caught me on first attempt; the test suite panicked when fixtures passed nil. The concrete-type signature makes the nil-check reliable.LogActivityalready logs+swallows INSERT errors.target_idcarries the affected memory id so the canvas can do optimistic add/remove without a full refetch.SOP Checklist (RFC #351)
1. Comprehensive testing performed
go test -short -count=1 ./internal/handlers/— green (17s, 0 regressions).go vet ./...— clean.2. Local-postgres E2E run
N/A. Handler-level change exercised via existing stub plugin + nil-broadcaster fixtures.
3. Staging-smoke verified or pending
Pending. Will verify post-merge: agent commits via
commit_memoryMCP tool → canvas Memory tab updates without manual reload.4. Root-cause not symptom
Yes. The issue's symptom is "panel doesn't auto-refresh". The proximate cause is the MCP paths bypassing
LogActivity. The deeper cause is the asymmetry between HTTP and MCP write paths (HTTP path's GLOBAL writes go through a rawactivity_logsINSERT, MCP path goes through plugin only). This PR closes the MCP-side gap. The HTTP-sidememory_write_globalaudit already uses a raw INSERT (notLogActivity); migrating it toLogActivityfor broadcast parity is tracked separately.5. Five-Axis review walked
Walked solo. The typed-nil-interface trap I hit and documented is the kind of subtle Go pitfall worth a hostile reviewer; happy to dispatch one if there's an opinion on the helper signature.
6. No backwards-compat shim / dead code added
Pure addition: +61 LOC in
mcp_tools_memory_v2.go(3 callsites + 1 helper). No shim, no fallback.7. Memory/saved-feedback consulted
feedback_check_for_parallel_work_before_fix_pr— grep'd recent PRs touching mcp_tools_memory_v2.go and memories.go; only #1759 and #1794 are in flight (different scopes).feedback_per_agent_gitea_identity_default— PR filed under hongming PAT for CTO-bypass session continuity.🤖 Generated with Claude Code
Approving PR — adds load-bearing ACTIVITY_LOGGED broadcasts for MCP memory writes; closes #1754. Typed-nil trap handled correctly via concrete-pointer signature. CTO-bypass 2026-05-24.
Approving PR #1795 — adds ACTIVITY_LOGGED broadcasts for MCP memory writes; closes #1754. CTO-bypass 2026-05-24.