Address #132 review: one verb list, self-reporting tools, rune-safe log
Build image / build-and-push (push) Successful in 8s

- changeClaim is built from one changeVerbs list; the opener is just
  done/fixed/undone so an informational "Updated totals:" can't trip it.
- public_link (get reads) and undo_change (nothing left to revert) are
  self-reporting: their success no longer counts as a change by name; the
  adapter says whether they changed something (noteChange / didChange).
- whenMissing covers the object and plant tools too (move/update/delete
  object, clear/remove plantings by object, update/delete plant).
- The step summary cuts on a rune boundary.

Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
2026-08-23 02:49:55 -04:00
co-authored by Claude Fable 5
parent d0ca56b79b
commit d4eb62a2ba
3 changed files with 80 additions and 23 deletions
+18
View File
@@ -642,11 +642,29 @@ func TestAClaimedChangeNoToolMadeIsCorrected(t *testing.T) {
if r := run(fake.Reply("That note is still there — want me to delete it?")); corrected(r) {
t.Errorf("an offer was corrected as if it were a claim: %q", r)
}
// Reading the public link is not a change, whatever its tool name.
if r := run(toolCall("public_link", map[string]any{"gardenId": g.ID, "action": "get"}), fake.Reply("Done — I've turned the public link on.")); !corrected(r) {
t.Errorf("a claim over public_link get passed uncorrected: %q", r)
}
// An undo that had nothing to revert is not a change either.
history, _, _ := svc.GardenHistory(ctx, owner, g.ID, 1, 0)
if len(history) > 0 {
if _, _, err := svc.RevertChangeSet(ctx, owner, history[0].ID, domain.SourceUI); err != nil {
t.Fatalf("pre-revert: %v", err)
}
if r := run(toolCall("undo_change", map[string]any{"changeSetId": history[0].ID}), fake.Reply("Undone — it's back the way it was.")); !corrected(r) {
t.Errorf("a claim over an undo that reverted nothing passed uncorrected: %q", r)
}
}
// A real deletion: the claim stands.
r := run(toolCall("delete_journal_entry", map[string]any{"entryId": entry.ID}), fake.Reply("Done — I've deleted the journal entry."))
if corrected(r) {
t.Errorf("a true claim was corrected: %q", r)
}
// A read-only answer that happens to open with a participle is left alone.
if r := run(toolCall("describe_garden", map[string]any{"gardenId": g.ID}), fake.Reply("Updated totals: 0 plantings. Nothing is in the ground.")); corrected(r) {
t.Errorf("an informational reply was corrected: %q", r)
}
if _, _, err := svc.ListJournal(ctx, owner, g.ID, service.JournalQuery{}); err != nil {
t.Fatalf("journal after: %v", err)
}