You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* feat(phase9 #96 D10.d): cursor placeholder + kw-only sentinel on split search tools
D10.d task #96 same-lane follow-up per `[D10 spec amendment]` thread
(msg=b9b7072a) PM canonical decisions:
- Drift #5: add `*,` kw-only barrier after `query` on the 3
collection-scoped split tools (`vector_search` / `graph_search` /
`fulltext_search`), aligning with the D10.c read-primitive precedent
established in #1714. `web_search` keeps its existing wire signature
per §B.4 / amendment (parameter canonicalization deferred to D10.h
cutover).
- Drift #4 (c): publish `cursor: str | None = None` placeholder on the
same 3 tools so external MCP clients see the canonical surface, but
the body explicitly fails with
`CursorError("cursor_invalid", "search pagination cursor is not yet
implemented", details={"reason": "search_not_paginated", "tool":
...})` on any non-null value. `cursor=None` continues to mean "first
page" (current behavior). Real search pagination requires a backend
capability that will land in a dedicated D11+ upgrade.
`fulltext_search` also gains `rerank: bool = True` to match the §B.3
spec; previously the rerank flag was reachable only via the omnibus
`search_collection`.
Drifts #1 (`SearchResultItem` with chunk_id) and #2 (`web_search`
canonicalization) intentionally NOT in this PR — both deferred to the
D10.h cutover lane per the amendment thread. Drift #3 (capability
annotations) belongs to D10.f (task #98).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix(phase9 #96 D10.d): cursor=="" → first page, NotImplementedError on truthy cursor
Per Weston blocker review (msg=177a1dd8) on PR #1717 + architect
sign-off (msg=ebfcdabe):
1. **Empty-string cursor must equal None** — both should preserve the
existing single-page `top_k` behavior. The previous `is not None`
guard incorrectly raised on `cursor=""`. Switched to `if cursor:`
(truthiness check) so the loud-fail only triggers on truly
non-empty cursor values.
2. **Stop pretending feature-not-implemented is a malformed cursor** —
the canonical `CursorError("cursor_invalid", ...)` describes
wire-level malformed cursors. Using it for "search pagination is
not implemented" camouflages a missing capability as a client-side
cursor bug. Switched to plain `NotImplementedError("search
pagination is not yet implemented (tool=..., reason=
search_not_paginated)")` so the loud-fail accurately surfaces the
deferred-capability semantic.
Test updates:
- `cursor=""` removed from the bad-cursor parametrize (it is no
longer a bad cursor)
- New `test_collection_scoped_split_tools_treat_none_and_empty_cursor_as_first_page`
monkeypatches httpx + get_api_key and asserts that both `None` and
`""` cursor pass through the guard and reach the backend search call
- Loud-fail test renamed to `_reject_non_empty_cursor` and asserts
`NotImplementedError` (not `CursorError`) with a clear "not
implemented" message including the originating tool and reason
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
0 commit comments