Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions internal/mcp/mcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,9 @@ Examples:
mcp.WithString("topic_key",
mcp.Description("New topic key (normalized internally)"),
),
mcp.WithString("project",
mcp.Description("New project — reassign this observation to a different project"),
),
),
queuedWriteHandler(writeQueue, handleUpdate(s)),
)
Expand Down Expand Up @@ -1410,6 +1413,9 @@ func handleUpdate(s *store.Store) server.ToolHandlerFunc {
if v, ok := req.GetArguments()["topic_key"].(string); ok {
update.TopicKey = &v
}
if v, ok := req.GetArguments()["project"].(string); ok {
update.Project = &v
}
Comment on lines +1424 to +1426
Comment on lines +1424 to +1426

if update.Title == nil && update.Content == nil && update.Type == nil && update.Project == nil && update.Scope == nil && update.TopicKey == nil {
return mcp.NewToolResultError("provide at least one field to update"), nil
Expand Down
40 changes: 40 additions & 0 deletions internal/store/store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8830,3 +8830,43 @@ func TestSanitizeFTS(t *testing.T) {
})
}
}

func TestUpdateObservationReassignsProject(t *testing.T) {
s := newTestStore(t)

if err := s.CreateSession("s1", "alpha", "/tmp/alpha"); err != nil {
t.Fatalf("create session: %v", err)
}

id, err := s.AddObservation(AddObservationParams{
SessionID: "s1",
Type: "config",
Title: "movable",
Content: "belongs elsewhere",
Project: "alpha",
Scope: "project",
})
if err != nil {
t.Fatalf("add observation: %v", err)
}

newProject := "beta"
updated, err := s.UpdateObservation(id, UpdateObservationParams{
Project: &newProject,
})
Comment on lines +8853 to +8856
if err != nil {
t.Fatalf("update observation: %v", err)
}
if derefString(updated.Project) != "beta" {
t.Fatalf("project reassignment did not apply; got project=%q, want %q", derefString(updated.Project), "beta")
}

// Confirm it persisted on re-read.
got, err := s.GetObservation(id)
if err != nil {
t.Fatalf("get observation: %v", err)
}
if derefString(got.Project) != "beta" {
t.Fatalf("reassignment not persisted; got project=%q, want %q", derefString(got.Project), "beta")
}
}
Comment on lines +8834 to +8872

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Extend coverage beyond the happy path.

This test verifies successful reassignment and persistence, but omits UpdateObservation error paths and project-input edge cases. Add deterministic assertions for an invalid/missing observation ID and the intended empty/normalization behavior before merge.

As per path instructions, **/*_test.go must verify happy path, error paths, and edge cases, and behavior changes without tests should be blocked.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/store/store_test.go` around lines 8834 - 8872, Extend
TestUpdateObservationReassignsProject to cover UpdateObservation error handling
for an invalid or missing observation ID, plus deterministic assertions for
empty project input and the intended project-name normalization behavior before
merge. Keep the existing successful reassignment and persistence checks, and use
the store’s established error and normalization expectations rather than
inventing new behavior.

Source: Path instructions