test(semantic): route the semantic tool tests through the gate - #119
Merged
Merged
Conversation
Refs #112 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Refs #112 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Refs #112 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…he gate Refs #112 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Refs #112 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Refs #112 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Third of four PRs for #112. Converts
runSearch(~120 call sites behind it) andthe six files in
test/semantic/tools/to reach tools through the registration,so the repo-wide rule PR 4 records has no exception.
grep -rn '\.handler(' test/semantic/now returns nothing; the only survivinghandler-direct calls in the repo are the two commented
edit_noteWRITE_FAILEDtests whose subject is the
CallToolResultenvelope.Triage — every previously-green test the migration broke
Seven tests failed once their calls crossed the gate. None was relaxed; each was
either a false pin on an unreachable handler check, or a fixture passing a
parameter the advertised schema does not declare.
Unreachable handler checks (5). The schema already states the constraint, so
registerTool's.strict()wrapper rejects withINVALID_PARAMSanddetails.issuesbefore the handler's own check can run. The pins onINVALID_ARGUMENTwere pinning a branch no client can reach. Rewritten to assertINVALID_PARAMSplus the offending field — the same triageread_notesgot inPR 1 (task 1.4), and exactly the divergence ADR-0015 is being written to record.
rejects thresholds below 0 and above 1threshold: z.number().min(0).max(1)INVALID_ARGUMENTINVALID_PARAMS,path: 'threshold'rejects an empty query arrayquery: …array(z.string()).min(1).max(8)INVALID_ARGUMENTINVALID_PARAMS,path: 'query'rejects a query array longer than 8INVALID_ARGUMENTINVALID_PARAMS,path: 'query'handler treats empty path_prefix array as empty filterfilter.path_prefix.min(1)INVALID_ARGUMENTINVALID_PARAMS,path: 'filter.path_prefix'; renamed torejects an empty path_prefix array at the gatehandler treats empty exclude_path_prefix array as empty filterfilter.exclude_path_prefix.min(1)INVALID_ARGUMENTINVALID_PARAMS,path: 'filter.exclude_path_prefix'; renamed likewiseThe dead code these expose is left in place deliberately —
readThreshold'svalue < 0 || value > 1branch insrc/modules/semantic/tool-helpers.tsand theempty-
path_prefixarm of the filter fallback are now provably unreachablethrough the gate. Removing them is a source change, not a test migration; it
belongs with the same sweep as the
set_propertyfinding below.Fixtures naming the only vault (3). In single-vault mode
vaultParamShapecontributes no
vaultparameter at all, so{ vault: 'v', … }is an unknown key.The subject of each test was the lexical-only fallback /
semantic_status/missing backend — never vault routing — so the redundant argument was dropped and
the assertion kept intact. Same shape as PR 2's
VAULT_NOT_FOUNDtriage.search-notes.test.ts—returns lexical-only matches (no throw) when vault has no semantic backendsearch-notes.test.ts—reports unavailable when the semantic module is globally off (no backend)get-similar-notes.test.ts—throws SEMANTIC_INDEX_NOT_FOUND when vault has no semantic backendNew coverage
Per task 3.4, a
rejects a vault argument in single-vault modecase was added toget-similar-notes.test.tsandfind-duplicates.test.ts, assertingINVALID_PARAMSwithpath: '<root>'and a message namingvault. Net testcount: 1331 → 1333.
Notes
find_duplicatesandget_similar_notesresolve with an array, andtoToolResponseonly populatesstructuredContentfor a plain record — socallToolreads them off the text channel, as the helper's doc commentdescribes. Expected, not a gate bug. Their result types are module-internal, so
the tests derive them from the tool's own handler rather than exporting from
src/.reg.spec.inputSchema(hybrid) andregisterTool(tool).spec.description(search-notes) were left untouched — they already cross the gate. The raw
tool.inputSchema.safeParseassertions likewise stay on the unwrapped schema,which is their actual subject.
npm test && npm run lint && npm run typecheck.Carried forward, not fixed here
set_propertyis the only caller ofinferTypeAndValidate, and all three of itsUNSUPPORTED_VALUE_TYPEthrows are unreachable under the declaredvalueunion(null/undefined, a non-string/number list element, a non-scalar value — the gate
cuts all three first). The code is still declared in
OperationsErrorCode. Foundin PR 2; deserves its own change rather than a drive-by.
Refs #112
🤖 Generated with Claude Code