Repository navigation
fix(tools): shorten tool descriptions, and point Errors entries at messages that carry their remedy - #713
Conversation
|
umm-actually re-reviewed at No new findings (15 tracked finding(s) across all runs). Context notes
umm-actually · z-ai/glm-5.3-flash |
… and polish descriptions - Shorten Errors entries whose message already gives the fix, keeping each entry's reading and every state fact. - Merge vault_move_note's abort and partial-move entries, name the Canvas cards a move updates, and send its daily-notes config remedy to the owner. - Fix the six tools graded below 4.8: list_files, get_outgoing_links, search_by_folder, get_backlinks, move_note, list_memory_files. - Apply the second polish batch: lag lines, no-offset notes, null rules, tie-breaks, routing lines, and repeated facts cut. - Name the image-fit remedy MAX_IMAGE_OUTPUT_BYTES, and pin the 994-folder orphan exclusion limit with a test. - Share the memory-name Errors entry across the three memory tools. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- vault_read_note: drop a remedy the schema repeats, say there is no size cap, and give "start line past the end" an action - vault_write_note: route partial edits from When to use instead of the "note already exists" entry - vault_get_backlinks, vault_get_outgoing_links: state the path rule and the index delay once each - vault_search_by_property, vault_find_orphans: drop "There is no offset" and an unneeded tie order - vault_read_file: merge the library-error entry into the damaged-file entry - vault_create_task: give the duplicate-block_id entry its own remedy - vault_move_note: note that new parent folders may remain after a failed write - Errors entries that point at a message say "the message", not "the error" Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…lete_memory Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ED_PATHS Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…efuses protected paths Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Restore vault_write_note's single vault_update_properties disable case, cover a vault_list_files folder that names a file, and assert a canvas backlink's title. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The image-fit entry no longer promises a 64-pixel attempt, the daily-note format entry lists LT and LTS among the refused localized formats, and vault_update_task's changes line covers the on_completion delete entry. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…get_daily_note's token list Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… fallback chain Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…stated vault_list_tasks says what folder and is_kanban_task hold, vault_search says what folder holds for notes and for files, vault_list_files names what vault_read_file cannot read, and vault_memory_recall's any-term fallback is tied to reranking. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t_tasks' repeated sort fact The any-term fallback also runs when no vector hit exists, and without a reranker the distance cut always keeps a hit, so "When reranking runs" implied an empty result that cannot happen. sort_direction already says each fallback in a date sort uses its own direction, so sort_by stops repeating it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…list_tasks' lane and cascade wording
A 🏁 delete with nested lines reports a count ("task and N children
removed"), not their names. sort_direction now calls the date-sort
fallback a cascade, as sort_by does, and done_lanes describes the lanes
as holding a **Complete** line, as vault_update_task does.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…top-level folder Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tion's cascade as plain verbs Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… rule the server applies A done lane is one whose first line is **Complete**, so the three sentences that said a lane "holding" the line now say so. vault_list_tasks' opening no longer lists the Returns fields, and vault_update_task's Recurring bullet leaves the indented-line rule to its Errors entry. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
eb5250d to
92aff1d
Compare
…and test asset-tools' gated references Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
vault_list_files leaves image shrinking to vault_read_file, vault_insert_at_anchor says a failed save leaves the note unchanged, vault_replace_span and vault_replace_in_note break their line-break rules into bullets, vault_get_memory states each return shape once, and vault_list_memory_files' example no longer repeats the Returns fields. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e_task's spawn follow-up Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Pin the full empty-recall payload the description now promises
Pre-existing: the no-match recall test picks entries, total, and truncated off the parsed payload instead of asserting the whole object, while the PR's updated Errors entry now explicitly promises the empty shape carries search_mode and reranked. The exact payload is deterministic in this harness (no embedder, so fts and reranked false), so the missing keys or a wrong value would pass silently. Failure scenario: A handler change drops search_mode or reranked from the empty-recall response (or emits reranked: true on a no-match query); the description promises both fields in the empty contract, but the test passes because it never reads them, and an agent relying on the documented shape hits an undefined field. Suggested fixReplace the three property picks with one whole-value assertion: expect(payload).toEqual({ entries: [], total: 0, truncated: false, search_mode: "fts", reranked: false }).umm-actually · z-ai/glm-5.3-flash |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Responding to umm-actually's PR-level finding "Pin the full empty-recall payload the description now promises" (comment 6508421940): Fixed in df9dd98: the no-match recall test now asserts the whole payload, 🔍 ship-check · pr-monitor · claude-opus-5-5 |
|
Stale error-boundary passage now contradicts the new tool description
Pre-existing: ARCHITECTURE.md states that a damaged PDF or undecodable image “each return the server’s own message, with the library’s error kept as the cause”, while the vault_read_file description this PR rewrites asserts client-facing errors surface “in the reading library’s own words”. The two authoritative surfaces now state opposite behavior; since the PR changes no handler, the tool description is the side that is wrong, and this passage is the evidence the claim was never verified against the code path. Failure scenario: A reviewer or maintainer cross-checking the vault_read_file definition against ARCHITECTURE.md finds the two contradicting each other on whether raw library error text reaches clients; whichever they trust, one surface misleads — and if the description is trusted, a client-visible path leak of install-path-quoting pdf.js errors would go unnoticed as “documented”. Suggested fixAlign the two: correct the vault_read_file entry (see the companion finding) and, if desired, leave this passage as the statement of record — it already matches the safeHandler design.umm-actually · z-ai/glm-5.3-flash |
|
Responding to umm-actually's PR-level finding "Stale error-boundary passage now contradicts the new tool description" (comment 6508527766): Not changing this: the two passages describe different errors. ARCHITECTURE.md lists the library errors that come back as the server's own message (a password-protected or damaged PDF, an image sharp cannot decode, a PDF reader that fails to start). vault_read_file names those messages and says any other PDF or image error comes back in the library's own words, which matches asset-operations.ts:198 and :216: only pdf.js's PasswordException and InvalidPDFException are reworded, and everything else is rethrown unchanged. 🔍 ship-check · pr-monitor · claude-opus-5-5 |
…ry tool's vault_list_files fallback Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-write Errors entries Twelve, ten and seven tool descriptions typed these bullets out word for word; they now reference constants beside FILESYSTEM_ERROR_ENTRY, so a wording change is made once. vault_get_daily_note's vault_write_note pointer uses whenToolEnabledText like its siblings. The served text is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… it served Every sentence or clause in a tool description or input schema that names another tool now renders only while that tool is served. Error bullets whose remedy was that tool fall back to a check that needs none, and routing lines drop out without leaving an empty lead-in. A new test disables each tool in turn and fails if any served tool's text still names it. With every tool enabled, the text is byte-identical, so the tool-surface snapshots are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ile reply only while it is served Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ut word for word The plain-retry concurrent-write entry joins the shared constants in tool-helpers.ts; entries repeated inside one module (heading lookups, task ids, recurrence rules, dates, control characters, span anchors, memory sections, link-graph extensions) become module constants. No Errors bullet is now typed out twice, and the served text is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…en vault_delete_memory is off Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Update the durable-cross-reference claim the availability sweep just retired
This paragraph still documents a surviving class of durable API-level references, citing error-section alternatives that name sibling tools. This PR gates every one of those mentions behind whenToolEnabledText and adds a sweep test asserting that no served tool description or schema names a disabled tool, so the documented exception no longer exists on the tool surface. Failure scenario: A maintainer adding a new error entry reads this paragraph, treats 'durable API-level references remain' as an accepted class, hard-codes a sibling tool name in the entry, and the new 'no served tool's text names a tool DISABLED_TOOLS turned off' test fails CI — or, without running it, a served description directs agents to a tool DISABLED_TOOLS removed. Suggested fixReword the sentence to state the current invariant: cross-references in tool descriptions and prompt text are availability-keyed with no durable exceptions, enforced by the served-and-disabled sweep in tool-definitions.test.ts.umm-actually · z-ai/glm-5.3-flash |
|
Update the Read-only mode note that still cites durable sibling-tool references
The Read-only mode section states that a small number of durable API-level references remain, citing error-section alternatives that name sibling tools. After this PR, every such mention in the tool descriptions is availability-keyed and a sweep test asserts none survive a DISABLED_TOOLS removal, so the documented exception is stale. Failure scenario: A contributor using this section as the spec for read-only/DISABLED_TOOLS behavior hard-codes an error-section sibling-tool mention; the new sweep test fails, or the shipped description directs agents at a tool the configuration removed. Suggested fixReword the bullet to state that all cross-references in surviving descriptions and prompts are availability-keyed, with no durable exceptions.umm-actually · z-ai/glm-5.3-flash |
…th the test that checks it Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each tool's description and parameter text drops claims that restate another sentence, the Returns line or a parameter's own description, describe how the server carries out the call, or give advice a calling agent follows anyway. Remedies, state facts and the gating keep their place. The implementation facts that left the descriptions move to ARCHITECTURE.md. The default tool list goes from 136,621 to about 129,100 characters. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… and pin the trimmed descriptions The re-read concurrent-write entry moves into vault-crud-tools.ts as CONCURRENT_WRITE_REREAD_ERROR_ENTRY, Errors bullets two tools typed out from the same template become closure constants, the vault_read_note remedies sit with the other not-found remedies, and helper names, doc comments and blank lines follow the repo conventions. vault_update_task's line parameter says "note" instead of "file" when vault_list_tasks is disabled. The tool-definition tests now pin the trimmed descriptions. The default served text is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e allowance to 3,997 vault_list_property_keys again says it saves reading notes and shows its folder parameter in an example. vault_get_outgoing_links again says a broken markdown link's path has its %-escapes decoded, and that daily_note_forward_ref is false when the daily notes folder is the vault root or blank. vault_find_orphans states its sort order once. The per-tool allowance drops to the default list's average plus 2%, so the cut cannot grow back unnoticed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Both findings are fixed in 16e50fa:
A repo-wide search for "durable API-level" finds no other copy of the old claim. 🔍 ship-check · pr-monitor · claude-opus-5-5 |
|
Name the length check in the cannot-read-memory-file entry
The shortened memoryFileReadErrorEntry replaces the old parenthetical '(a name longer than the filesystem allows fails here)' with 'check file's spelling and length', but the length half of the remedy is only rendered when vault_list_memory_files is disabled; with it served the entry reads 'check file against vault_list_memory_files', which drops the only hint that an over-long name is the cause — the fact ARCHITECTURE.md documents as the reason this message exists (no ENAMETOOLONG leaks). Failure scenario: A client calls vault_update_memory with a 300-character file name; the store rejects with 'cannot read memory file …'; the entry directs the agent to vault_list_memory_files, which lists valid short names but never tells the agent its name was too long, so the agent re-guesses spellings instead of shortening the name. Suggested fixWhen vault_list_memory_files is served, append the length hint to that remedy, e.g. 'check file against vault_list_memory_files (a name longer than the filesystem allows fails here)'.umm-actually · z-ai/glm-5.3-flash |
… an update by line, and name an over-long memory file name in the read error Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Fixed in f275ee7 (issue comment 6510557073, the cannot-read-memory-file entry): while 🔍 ship-check · pr-monitor · claude-opus-5-5 |
Summary
The tool definitions get 7,177 characters shorter in total, which every conversation loads; 28 of the 33 tools shrink. Errors entries point at the error messages that already carry their remedy, descriptions gain the facts a caller was missing, and a tool turned off with
DISABLED_TOOLSis no longer named in any other tool's text. The change is description text, tests and docs: no handler, error message or schema shape changes, apart from one reply that drops a tool name when that tool is disabled.DISABLED_TOOLSset, no served tool's description or input schema names a tool the server no longer serves. Where the named tool was the remedy, the entry falls back to one that needs no tool, such as checking the path's spelling and letter case.vault_update_memory's reply for a new memory file namesvault_replace_in_noteonly while it is served. A new test disables each tool in turn and checks every other tool's text.vault_move_note. The four "move aborted" messages share one entry, and the three "move incomplete" messages another, since each message names its own state and next step. The opening sentence names the Canvas cards a move updates.vault_search,vault_recent_notes,vault_search_by_property,vault_find_orphans,vault_memory_recallandvault_list_tasks.vault_search_by_foldersays there is no offset,vault_find_orphansnames its 994-folder limit, and Returns lines state when a field is null.vault_list_taskssays whatstatus_char,folder,is_kanban_taskanddone_laneshold.vault_searchsaysfolderis a note's top-level folder and a file's full parent folder, which a new test pins.vault_write_notepoints partial edits atvault_patch_noteandvault_replace_in_notefrom When to use.vault_list_tagspoints atvault_list_property_valuesfor a folder or limit.MAX_IMAGE_OUTPUT_BYTES, the setting that causes it, instead of asking for a smaller export.CHARS_PER_TOOL_ALLOWANCEdrops from 4,198 to 3,997, the default list's average plus 2%, so the snapshot test fails if the list grows back.Tool text
All 33 tools change in the default configuration. Definition size counts the description and the input schema. Glama grades are the ones it published under its "0.55.3" label, which grades this branch's base, read 2026-10-29.
Errors:chars (before → after)vault_create_taskvault_delete_memoryvault_delete_notevault_delete_spanvault_find_orphansvault_get_backlinksvault_get_daily_notevault_get_memoryvault_get_outgoing_linksvault_insert_at_anchorvault_list_filesvault_list_memory_filesvault_list_notesvault_list_property_keysvault_list_property_valuesvault_list_tagsvault_list_tasksvault_memory_recallvault_move_notevault_patch_notevault_read_filevault_read_notevault_recent_notesvault_replace_in_notevault_replace_spanvault_searchvault_search_by_foldervault_search_by_propertyvault_search_by_tagvault_update_memoryvault_update_propertiesvault_update_taskvault_write_noteThe default tool list goes from 136,639 to 129,462 characters (-7,177, 5.3%), and its
Errors:text from 34,207 to 31,190. No tool'sErrors:text is more than half its description.Tool-definition review:
vault_delete_memorythat aPROTECTED_PATHSsetting could make false and a reranking condition invault_memory_recallthat the code does not hold.vault_list_memory_files' example output dropped the heading fields' names, now named in Returns; andvault_update_memorylists no entry for its "would shrink content" refusal, which gets none because only a file made almost entirely of blank Windows-style lines can trigger it.vault_list_property_keyssaves reading notes one by one and showsfolderin an example; a broken markdown link's path invault_get_outgoing_linkshas its%-escapes decoded; anddaily_note_forward_refis false when the daily notes folder is the vault root or blank. Every other cut was confirmed to leave the fact elsewhere in the definition, in the error message, or to change no call.vault_delete_note's protected-path entry had no remedy and now says to ask the vault owner to delete the note in Obsidian.Tests
DISABLED_TOOLSturned off;vault_update_memory's new-file reply names no editing tool whenvault_replace_in_noteis disabled;vault_find_orphansaccepts 994 excluded folders and refuses 995;vault_list_filesreturns an empty listing for a folder that names a file; a canvas backlink's title is the file name without.canvas; a search result'sfolderis a file's full parent folder and a note's top-level folder.tool-definitions.test.tspins whole description lines, and checks that each cross-reference appears while its target tool is served and disappears when that tool is disabled.npm run lint,npm run build:serverandnpm run knippass.npx vitest run src/vault-mcp src/__tests__/integration src/utils scripts/__tests__ src/__tests__/install-deps.test.tspasses 5,360 tests, with 2 skipped. Two file-watcher timing tests timed out locally under machine load, a different pair on each run; this branch changes no watcher code, and CI runs them on a clean runner.Live Test Results
Test deploy of
f275ee75(run 40970832799): the container was re-created from image revisionf275ee75b0daab6f0fe0d73b37ff520c4e1cc7dband reported healthy. A fresh MCP client read the servedtools/listand compared it with the committedobsidian-sync.jsonsnapshot, the configuration the test instance runs.This PR is releasable on its own.
🤖 Generated with Claude Code