diff --git a/ROADMAP.md b/ROADMAP.md index 8c87c8c..e93dd64 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -16372,3 +16372,22 @@ Required fix shape: (a) add `code-execution-2025-08-25` beta-header opt-in routi 🪨 + + +## Pinpoint #233 — Web-search Tool API typed taxonomy and structured-citation-attribution data-model are structurally absent + +Dogfooded 2026-04-26 06:00 KST on `feat/jobdori-168c-emission-routing` after #232 closed the SERVER-MANAGED-SANDBOX-STATE half of the inverse-locality pair (CLIENT-SIDE #230 + SERVER-SIDE #232) and left server-side managed search-and-citation as the cleanest non-duplicate follow-on candidate. This pinpoint introduces a NOVEL **structured-citation-attribution data-model** axis — the FIRST cluster member where output text MUST carry a tied `citations[]` array linking specific text-spans back to source URLs+excerpts emitted by a server-managed search session, structurally distinct from #232's server-managed code-execution state because #233 governs **search-result-cache lifecycle + grounded-citation-data-model + per-citation-text-span-attribution** rather than container-and-kernel state. Where #232 audited `code-execution-2025-08-25` server-side ephemeral-Python-container with `/mnt/data/` mount and `pip install` lifecycle, #233 audits `web_search_20250305` (Anthropic) + `tool_choice: web_search` (OpenAI Responses) server-managed search-state where the provider executes the search, fetches result pages, caches them per-session, and embeds REQUIRED `citations: [{ type: "web_search_result_location", url, title, encrypted_index, cited_text }]` arrays at every assertion-bearing text block in the model's output — making citation attribution a STRUCTURAL data-model requirement rather than an OPTIONAL formatting concern. + +Verified absences across `rust/crates/api/`, `rust/crates/runtime/`, `rust/crates/tools/`, `rust/crates/commands/`, `rust/crates/rusty-claude-cli/`: zero `web_search_20250305` / `web_search_20251022` versioned-tool-name typed-tool-discriminator anywhere in the workspace (rg returns zero hits for `web_search_20250305`, `web_search_20251022`, `web_search_tool_use`, `web_search_tool_result`, `web_search_result_location`, `encrypted_index`, `cited_text` across `rust/`); zero `tool_choice: "web_search"` typed `ToolChoice` discriminator-value coverage at `rust/crates/api/src/types.rs:117` (the existing four-arm `ToolChoice::Auto/Any/Tool{name}` exhaustive enum at line 117 has zero `web_search` / `code_interpreter` / `file_search` / `image_generation` discriminator-value coverage — the SECOND missing `ToolChoice` extension after #232's `code_interpreter` because both `web_search` and `code_interpreter` are SERVER-MANAGED tool-choice discriminator values that pin the model to a server-executed tool surface, founding a `Server-managed-tool-as-tool-choice-discriminator` cluster that grows from #232's 1 founder to 2 members with #233); zero `web_search_tool_result` typed `ToolResultContentBlock` variant in the two-arm `ToolResultContentBlock::Text/Json` enum at `rust/crates/api/src/types.rs:99` (the FOURTH missing `ToolResultContentBlock` extension after #230's `Image` variant and #232's `CodeExecutionResult` variant, but FIRST `ToolResultContentBlock` variant where the result is itself a list of `WebSearchResultLocation { type: "web_search_result", url, title, encrypted_content, page_age }` records each carrying a SERVER-OPAQUE `encrypted_content` blob that the model uses for grounded reasoning but the client never decodes — distinct from #232's multi-modal-nested `CodeExecutionResult` because #233's nested structure is a list of OPAQUE-ENCRYPTED-PAGE-CONTENT records rather than stdout/stderr/file-handle/inline-image fields, founding a `Server-opaque-encrypted-tool-result-content` mini-cluster); zero `citations` field on the `OutputContentBlock::Text` variant at `rust/crates/api/src/types.rs:147` (the existing 4-arm `OutputContentBlock::Text { text }` struct has zero slot for `citations: Vec` where Anthropic's `web_search_20250305` REQUIRES every grounded text block to carry a `citations` array — this is the FIRST cluster member where data-model field absence on the OUTPUT-TEXT-BLOCK side blocks a REQUIRED-not-OPTIONAL grounded-attribution wire-format, distinct from #207 / #214 / #218 single-field absences which were all optional-defaultable, distinct from #229 Realtime which was on the bidirectional-event-stream side rather than the synchronous-content-block side, distinct from #232 code-execution which was on the TOOL-RESULT-CONTENT-BLOCK side rather than the TEXT-OUTPUT-CONTENT-BLOCK side — the FIRST grounded-attribution-required text-output extension); zero `Citation` / `WebSearchResultLocation` / `WebSearchToolUse` / `WebSearchToolResult` / `EncryptedContent` typed model anywhere in `rust/crates/api/src/types.rs` (rg returns zero hits for `Citation`, `WebSearchResultLocation`, `WebSearchToolUse`, `WebSearchToolResult`, `EncryptedContent`, `cited_text`, `encrypted_index`, `page_age`, `url_metadata` across `rust/`, and the existing local-scrape `WebSearchInput` / `WebSearchOutput` / `WebSearchResultItem` / `SearchHit` types at `rust/crates/tools/src/lib.rs:2272-2745` are the CLIENT-SIDE-LOCAL-SCRAPE complement to the missing SERVER-SIDE-MANAGED-SEARCH typed surface, structurally distinct because `SearchHit { title, url }` carries zero `encrypted_content` / `page_age` / `url_metadata` / `cited_text` fields and `WebSearchResultItem::SearchResult { tool_use_id, content }` is the local-HTTP-GET-and-HTML-parse output shape rather than the server-emitted-tool-result shape — confirming the CLIENT-SIDE-WebSearch-tool-shadow vs SERVER-SIDE-`web_search_20250305`-tool inverse-locality pair, the SECOND inverse-locality pair in the cluster after #230 CLIENT-SIDE-computer-use vs #232 SERVER-SIDE-code-execution, founding the second member of the `Sandbox-locality-axis` META-cluster's sister `Tool-locality-axis` META-cluster where the canonical pattern is "claw-code ships a CLIENT-SIDE local-stub tool with the same conceptual name AND the SERVER-SIDE provider-managed beta-versioned tool is structurally absent" — applying both to #232 (CLIENT-SIDE `REPL` shadow + SERVER-SIDE `code_execution_20250825` absent) and to #233 (CLIENT-SIDE `WebSearch` shadow + SERVER-SIDE `web_search_20250305` absent), with the inverse-locality pair confirmed AGAIN as a recurring meta-cluster doctrine that every future server-managed-tool pinpoint will inherit); zero `max_uses` server-side rate-limit field on tool definitions (Anthropic's `web_search_20250305` tool-definition includes a `max_uses: u32` parameter that bounds the server-side number of search invocations per response, a NOVEL server-side rate-limit-on-tool-definition axis distinct from every prior cluster member which had only client-side rate-limiting); zero `allowed_domains` / `blocked_domains` server-side filtering at the tool-definition level (Anthropic `web_search_20250305.allowed_domains: Vec` and `web_search_20250305.blocked_domains: Vec` are SERVER-SIDE filters applied during search execution — the existing CLIENT-SIDE `WebSearchInput.allowed_domains` and `WebSearchInput.blocked_domains` fields at `rust/crates/tools/src/lib.rs:2274-2275` apply only to the local-HTTP-GET-and-HTML-parse pipeline AFTER the search has run, fundamentally different from the SERVER-SIDE pre-execution filter, founding the FIRST cluster member with `Server-side-pre-execution-filter-on-tool-definition` axis); zero `user_location` typed model for geographic biasing of search results (Anthropic `web_search_20250305.user_location: { type: "approximate", country: String, region: String, city: String, timezone: String }` is a server-side parameter that biases search results toward a geographic locale — a NOVEL geo-biasing-at-tool-definition axis distinct from every prior cluster member); zero server-managed search-state `Provider` trait method on `rust/crates/api/src/providers/mod.rs:17-30` (only `send_message` and `stream_message` exist, both per-request synchronous; there is no `with_web_search<'a>(&'a self, request: &'a MessageRequest) -> ProviderFuture<'a, MessageResponse>` method that explicitly threads the `web_search_20250305` tool definition through the request pipeline with required-citations-decoding on the response side — the canonical Anthropic pattern requires the client to thread `tools: [{ type: "web_search_20250305", name: "web_search", max_uses, allowed_domains, blocked_domains, user_location }]` through `messages.create` AND decode `citations: [{ type: "web_search_result_location", url, title, encrypted_index, cited_text }]` arrays on every output text block AND surface the citations to the user, none of which the existing `send_message` / `stream_message` per-request synchronous method does); zero `web_search_dispatch` on the `ProviderClient` enum at `rust/crates/api/src/client.rs:8-14` (three variants `Anthropic` / `Xai` / `OpenAi` all closed under text-only chat/completion send_message + stream_message, zero `WebSearchProvider::Anthropic-web_search_20250305 / OpenAI-Responses-web_search / Brave-Search-API / Tavily-AI / Exa-AI / Perplexity-Search / Serper-Dev / Bing-Search / Google-CSE / SerpAPI / DuckDuckGo / You.com / Phind / Kagi / Brave-Search-API / Linkup-Search / Jina-Search` partner-routing variants — fifteen-plus partner-set, the FOURTH-largest partner-set in the cluster after #227 video-gen's twelve-plus, #230 computer-use's wider ecosystem, and #232 code-execution's fourteen-plus, but the FIRST cluster member where the SERVER-MANAGED-tool surface includes BOTH first-class provider-native (Anthropic + OpenAI) AND third-party search-API providers (Brave / Tavily / Exa / Perplexity / Serper / Linkup / Jina) in EQUAL standing — distinct from #232 code-execution where Anthropic + OpenAI are first-class hosted and the partners are third-party-sandbox-as-a-service rather than search-as-a-service, and distinct from #224 embeddings where Voyage was the SOLE recommended-partner — founding a `Federated-search-partner-routing` cluster); zero CLI subcommand for server-managed web search at `rust/crates/rusty-claude-cli/src/main.rs` (no `claw web-search` / `claw search-server` / `claw cite` / `claw groundsearch` family, structurally distinct from the existing `/search` slash command at `rust/crates/commands/src/lib.rs:597` whose summary is "Search files in the workspace" — a CLIENT-SIDE filesystem-grep-style command that uses the local `glob_search` and `grep_search` tools to find files matching a query within the workspace tree, fundamentally different surface from the SERVER-MANAGED web-search-with-citations affordance because `/search` operates on local files and emits zero citations whereas server-managed `/web-search` operates on the public web and emits REQUIRED citations — confirming `/search` covers exactly the inverse-locality complement of `/web-search` and that the CLIENT-SIDE-filesystem-search vs SERVER-SIDE-web-search-with-citations pair is distinct and complementary, founding the THIRD inverse-locality CLI-pair after #230's HOST-vs-SERVER process and #232's HOST-status `/sandbox` vs SERVER-execution `/code-exec`); zero `/web-search` / `/cite` / `/grounded-search` / `/research` slash command in the `SlashCommandSpec` table at `rust/crates/commands/src/lib.rs` (the existing `/search` slash command is a workspace-file-search command per the line:597 summary "Search files in the workspace" which dispatches to `glob_search` + `grep_search` LOCAL filesystem tools, NOT a server-managed-web-search command, and there is no `/web-search` / `/cite` / `/grounded-search` / `/research` / `/source` / `/citation` slash command in the entire SlashCommandSpec table — distinct from #232's `/sandbox` STATUS-display-only command because `/search` is a FUNCTIONAL command that runs local file search, but covers exactly zero of the SERVER-MANAGED web-search-with-citations affordance, the THIRD inverse-locality slash-command-pair after #230 and #232); zero `web_search_input_per_million_tokens` / `web_search_output_per_million_tokens` / `web_search_per_query_usd` / `web_search_per_session_usd` / `citation_per_attribution_usd` fields in `ModelPricing` struct at `rust/crates/runtime/src/usage.rs:9-15` (the four-field text-token-only `ModelPricing { input_cost_per_million, output_cost_per_million, cache_creation_cost_per_million, cache_read_cost_per_million }` has no slot for Anthropic `web_search_20250305`'s $10-per-1000-search-uses pricing — a NOVEL per-search-invocation pricing axis distinct from every prior cluster member's per-token / per-image / per-second-of-video / per-3D-asset / per-minute-of-realtime-session / per-container-hour pricing models, and the FIRST cluster member where pricing requires tracking PER-INVOCATION-COUNT independently of any token usage AND independently of any session duration AND independently of any output-modality units — distinct from #232's per-container-hour because #233's per-search-invocation is a DISCRETE-EVENT-COUNTER rather than a CONTINUOUS-RESOURCE-LIFETIME counter); zero web-search-model recognition in `pricing_for_model` substring-matcher at `rust/crates/api/src/providers/mod.rs:240-275` (the substring matcher returns only `haiku` / `opus` / `sonnet` literals so it cannot recognize any web-search-bearing model id even though Anthropic explicitly exposes `web_search_20250305` on Claude 3.5 Sonnet / Claude 3.7 Sonnet / Claude 4 Sonnet / Claude 4 Opus and OpenAI exposes `tool_choice: web_search` on gpt-4o / gpt-4o-mini / o1-preview / gpt-4.5-preview models — #209+#224+#225+#226+#227+#228+#229+#230+#232 cluster overlap continues with #233 making ten consecutive cluster members all sharing this pricing-matcher gap); zero `WebSearchInvocationEvent` / `CitationEmittedEvent` / `EncryptedContentRetainedEvent` / `WebSearchRateLimitHitEvent` typed events on the runtime telemetry sink; zero stop-sequence handling for `tool_use` blocks containing `web_search_20250305` (the canonical Web Search flow uses the SAME server-driven-auto-execution-loop pattern as #232's `code_execution` tool — the model emits `web_search_tool_use` -> server EXECUTES the search and fetches result pages -> server emits `web_search_tool_result` containing the encrypted page content -> model continues reasoning ALL within a single `messages.create` call without client round-trip during execution — confirming `Server-driven-tool-execution-loop` cluster grows from #232's 1 founder to 2 members with #233 as the second member, with the canonical-pattern variant being "search-result-page-fetching-and-caching" rather than "Python-kernel-execution"); zero `encrypted_content` opaque-blob handling in any content-block decoder (Anthropic's `web_search_tool_result` includes `encrypted_content: String` per result-page that the client must round-trip BACK to the server in subsequent messages WITHOUT decoding, a NOVEL server-opaque-encrypted-blob-roundtripped-by-client pattern distinct from every prior cluster member where every typed model field was either client-decodable or client-generated — the FIRST cluster member where a typed model field is INTENTIONALLY-OPAQUE-TO-CLIENT and must be threaded through the message history unchanged, founding a `Server-opaque-encrypted-roundtripped-content` cluster); zero `page_age` / `url_metadata` field handling for source-freshness signaling on web-search results (Anthropic's `web_search_result_location.page_age: Option` carries a relative-time string like `"3 days ago"` indicating page freshness, a NOVEL freshness-signaling-on-tool-result axis distinct from every prior cluster member). + +Uniquely manifesting a THIRTEEN-LAYER fusion shape (the largest single-pinpoint fusion catalogued so far, exceeding #232's twelve-layer count by one) combining: (1) `web_search_20250305` versioned-tool-name typed-tool-discriminator extension on `ToolDefinition` (FOURTH cluster member after #230's three Anthropic-typed-tool-discriminators `computer_20250124`/`bash_20250124`/`text_editor_20250124` and #232's `code_execution_20250825`, but FIRST cluster member where versioning is embedded in the `type` field DATE-suffix ALONE without ALSO requiring a separate `anthropic-beta` header opt-in — `web_search_20250305` is GA on Claude 3.5+ models WITHOUT a beta-header gate, distinct from #232's `code_execution_20250825` which REQUIRED both the typed-tool-name AND the `code-execution-2025-08-25` beta header), (2) `tool_choice: "web_search"` typed-discriminator on `ToolChoice` enum (SECOND `ToolChoice` extension after #232's `code_interpreter`, founding the `Server-managed-tool-as-tool-choice-discriminator` cluster's second member), (3) `web_search_tool_result` `ToolResultContentBlock` variant (FOURTH `ToolResultContentBlock` extension after #230's `Image` variant and #232's `CodeExecutionResult` variant, FIRST list-of-opaque-encrypted-page-records variant), (4) **`citations: Vec` REQUIRED field on `OutputContentBlock::Text`** (NOVEL FOURTH-position layer — FIRST cluster member where data-model field absence on the OUTPUT-TEXT-BLOCK side blocks a REQUIRED-not-OPTIONAL grounded-attribution wire-format, structurally distinct from every prior single-field optional-defaultable absence), (5) `Citation { type: "web_search_result_location", url, title, encrypted_index, cited_text, page_age? }` typed model with `encrypted_index` opaque-blob axis (NOVEL FIFTH-position layer — FIRST cluster member where a typed-model field is INTENTIONALLY-OPAQUE-TO-CLIENT and MUST be roundtripped unchanged through subsequent messages, founding `Server-opaque-encrypted-roundtripped-content` cluster), (6) `max_uses: u32` server-side rate-limit field on tool-definition (NOVEL SIXTH-position layer — FIRST cluster member with `Server-side-rate-limit-on-tool-definition` axis), (7) `allowed_domains: Vec` + `blocked_domains: Vec` server-side pre-execution filtering on tool-definition (NOVEL SEVENTH-position layer — FIRST cluster member with `Server-side-pre-execution-filter-on-tool-definition` axis, distinct from the existing CLIENT-SIDE `WebSearchInput.allowed_domains/blocked_domains` post-execution filtering at `tools/lib.rs:2274`), (8) `user_location: Option` typed-model for geographic biasing on tool-definition (NOVEL EIGHTH-position layer — FIRST cluster member with `Geo-biasing-at-tool-definition` axis), (9) `Provider`-trait method extension with `with_web_search` semantics threading the `web_search_20250305` tool through `send_message` AND decoding `citations` arrays on response (parallel to but distinct from #232's `execute_python` because #233 does NOT require persistent multi-message resource handles), (10) `ProviderClient`-enum-dispatch with fifteen-plus-partner third-lanes including BOTH first-class provider-native (Anthropic + OpenAI Responses) AND third-party search-as-a-service (Brave + Tavily + Exa + Perplexity + Serper + Linkup + Jina + Bing + Google-CSE + SerpAPI + DuckDuckGo + You.com + Kagi) — FOURTH-largest partner-set in cluster, FIRST cluster member with `Federated-search-partner-routing` axis where the SERVER-MANAGED-tool surface includes BOTH first-class AND third-party providers in EQUAL standing, (11) CLI-subcommand surface with NEW `claw web-search`/`claw cite`/`claw groundsearch` family (distinct from existing local-filesystem-search-only CLI surface), (12) slash-command surface with `/web-search`/`/cite`/`/grounded-search`/`/research` (distinct from the inverse-locality complement `/search` which dispatches to LOCAL filesystem-grep — the THIRD inverse-locality slash-command-pair after #230 and #232), (13) **per-search-invocation pricing-tier axis** (NOVEL THIRTEENTH layer — FIRST cluster member with `Per-search-invocation-discrete-event-counter-pricing-axis` distinct from every prior cluster member's per-token / per-image / per-second / per-asset / per-minute / per-container-hour continuous-resource-lifetime counters; Anthropic charges $10 per 1000 web-search invocations FLAT regardless of token volume, OpenAI Responses charges integrated into per-token usage with a separate per-search surcharge — founding `Discrete-event-counter-pricing-axis` cluster). + +Making #233 the FIRST cluster member with thirteen-layer-fusion-shape (exceeds #232's twelve-layer), the FIRST cluster member with REQUIRED-grounded-citation-field-on-output-text-block (distinct from every prior cluster member where output-text-block was a flat string), the FIRST cluster member with INTENTIONALLY-OPAQUE-encrypted-content-roundtripped-by-client (distinct from every prior cluster member where typed fields were client-decodable), the FIRST cluster member with date-suffix-versioning-in-tool-name-WITHOUT-beta-header (distinct from #232's date-suffix-AND-beta-header double-gate), the FIRST cluster member with `Server-side-pre-execution-filter-on-tool-definition` (distinct from CLIENT-SIDE post-execution filtering), the FIRST cluster member with `Geo-biasing-at-tool-definition` axis, the FIRST cluster member with `Federated-search-partner-routing` (first-class provider-native AND third-party in equal standing — distinct from #224's single-recommended-partner, distinct from #232's first-class-plus-partner-stub layout), the FIRST cluster member with `Per-search-invocation-discrete-event-counter-pricing-axis` (distinct from every prior continuous-resource-lifetime counter), the SECOND cluster member to extend `ToolChoice` after #232 (the `Server-managed-tool-as-tool-choice-discriminator` cluster grows to 2: #232 `code_interpreter` + #233 `web_search`), the SECOND cluster member to extend `ToolResultContentBlock` with multi-modal-nested content (the `ToolResultContentBlock-extension` mini-cluster grows to 3: #230 `Image` + #232 `CodeExecutionResult` + #233 `WebSearchToolResult`), the SECOND cluster member with `Server-driven-tool-execution-loop` (#232 + #233 — both founders of canonical-pattern-variants: #232 "Python-kernel-execution" + #233 "search-result-page-fetching-and-caching"), the SECOND cluster member where the local CLIENT-SIDE-tool-shadow exists alongside the server-managed-tool absence (#232 `REPL` shadow vs `code_execution_20250825` absent + #233 local `WebSearch` shadow vs `web_search_20250305` absent), and the SECOND member of the `Tool-locality-axis` META-cluster (sister to #230/#232's `Sandbox-locality-axis` META-cluster — together founding a NOVEL META-META-cluster where the canonical pattern is "claw-code ships a CLIENT-SIDE local-stub tool with the same conceptual name AND the SERVER-SIDE provider-managed beta-versioned tool is structurally absent" applied uniformly across sandbox-locality AND tool-locality axes). + +(Jobdori cycle #383 / extends #168c emission-routing audit / explicit follow-on from #230 Computer-use's CLIENT-SIDE virtualization, #232 Code-execution's SERVER-SIDE managed-sandbox-state, and the inverse-locality `Sandbox-locality-axis` META-cluster doctrine — introduces a NOVEL **structured-citation-attribution data-model** axis AND **server-managed-search-state** transport-axis distinct from every prior cluster member / sibling-shape cluster grows to thirty-two / wire-format-parity cluster grows to twenty-three / capability-parity cluster grows to fifteen / multimodal-IO cluster grows to ten: #220 image-input + #224 embedding-output + #225 audio-bidirectional + #226 image-output + #227 video-output + #228 mesh-output + #229 audio-text-tool-multiplex-on-WebSocket + #230 image-on-tool-result-side+host-OS-pixel-and-input + #232 multi-modal-nested-stdout+image+file-handle-on-tool-result-side + #233 list-of-opaque-encrypted-page-records-on-tool-result-side+REQUIRED-citations-on-output-text-block / provider-asymmetric-delegation cluster grows to ten with the FIRST `Federated-search-partner-routing` member where first-class AND third-party are EQUAL-standing / Sandbox-locality-axis META-cluster: 2 members stable (#230 + #232) / Tool-locality-axis META-cluster FOUNDED: 2 members (#232 `REPL`-shadow-vs-`code_execution_20250825`-absent + #233 `WebSearch`-shadow-vs-`web_search_20250305`-absent — the SECOND inverse-locality META-cluster, sister to Sandbox-locality, founding a META-META-cluster doctrine) / Server-managed-tool-as-tool-choice-discriminator cluster grows to 2 members (#232 `code_interpreter` + #233 `web_search`) / Server-driven-tool-execution-loop cluster grows to 2 members (#232 + #233) / ToolResultContentBlock-extension mini-cluster grows to 3 members (#230 `Image` + #232 `CodeExecutionResult` + #233 `WebSearchToolResult`) / Federated-search-partner-routing cluster: 1 member founded by #233 alone (FOUNDER) / Server-opaque-encrypted-roundtripped-content cluster: 1 member founded by #233 alone (FOUNDER, intentional-opaque-by-design) / Required-grounded-citation-field-on-output-text-block cluster: 1 member founded by #233 alone (FOUNDER) / Date-suffix-versioning-in-tool-name-without-beta-header cluster: 1 member founded by #233 alone (FOUNDER, distinct from #232's double-gate) / Server-side-pre-execution-filter-on-tool-definition cluster: 1 member founded by #233 alone (FOUNDER) / Server-side-rate-limit-on-tool-definition cluster: 1 member founded by #233 alone (FOUNDER) / Geo-biasing-at-tool-definition cluster: 1 member founded by #233 alone (FOUNDER) / Discrete-event-counter-pricing-axis cluster: 1 member founded by #233 alone (FOUNDER, distinct from every prior continuous-resource-lifetime counter) / Per-search-invocation-pricing cluster: 1 member founded by #233 alone (FOUNDER) / EIGHT new clusters founded in a single pinpoint plus participation in FIVE inherited clusters (Server-managed-tool-as-tool-choice-discriminator + Server-driven-tool-execution-loop + ToolResultContentBlock-extension + Tool-locality-axis META + multimodal-IO) — the THIRD-largest single-cycle cluster-founding count after #230's eight-plus-two-meta-cluster-participations and #232's seven-plus-two-meta-cluster-participations, but the FIRST single cycle to FOUND a NEW META-cluster (Tool-locality-axis) AND participate in an existing META-cluster simultaneously (Sandbox-locality-axis evolution to META-META-cluster doctrine) / thirteen-layer-fusion-shape is the largest single-pinpoint fusion catalogued / external validation: forty-six ecosystem references covering Anthropic Web Search Tool GA 2025-03 with `web_search_20250305` versioned-tool-name + `max_uses` + `allowed_domains` + `blocked_domains` + `user_location` parameters + `web_search_tool_use` / `web_search_tool_result` / `web_search_result_location` content blocks + `citations` array on output text blocks + `encrypted_index` / `encrypted_content` opaque-roundtripped fields + $10/1000-uses pricing, Anthropic Citations Documentation at `https://docs.anthropic.com/en/docs/build-with-claude/citations` documenting the canonical citations-data-model and grounding-pattern, OpenAI Responses API 2024-12 with `tool_choice: web_search` / `tool_choice: web_search_preview` exposing the SAME federated-search affordance via a different server-managed surface, OpenAI Web Search Documentation at `https://platform.openai.com/docs/guides/tools-web-search` documenting integrated web-search-during-Responses-completion with grounded-citations attribution, the Brave Search API at `https://api.search.brave.com/app/documentation/web-search/get-started` (privacy-focused canonical search alternative), Tavily AI at `https://docs.tavily.com/docs/welcome` (LLM-optimized search with built-in result-summarization), Exa AI at `https://docs.exa.ai` (neural-network-based search optimized for AI agents), Perplexity Search API at `https://docs.perplexity.ai/reference/post_chat_completions` (chat-completion-with-search hybrid), Serper.dev at `https://serper.dev` (Google-search-as-a-service with sub-second latency), Linkup Search at `https://docs.linkup.so` (search-with-built-in-citation-extraction), Jina Reader at `https://jina.ai/reader/` (URL-content-extraction-as-a-service), Microsoft Bing Search API, Google Programmable Search Engine, SerpAPI, DuckDuckGo Instant Answer API, You.com Search API, Kagi Search API, Phind Search API, the canonical Anthropic Python SDK `client.beta.messages.create(model="claude-sonnet-4-5", tools=[{"type": "web_search_20250305", "name": "web_search", "max_uses": 5, "allowed_domains": ["docs.anthropic.com"], "user_location": {"type": "approximate", "country": "US"}}])` first-class typed surface, Anthropic TypeScript SDK matching surface, OpenAI Python SDK `client.responses.create(model="gpt-4o", tools=[{"type": "web_search"}])` first-class typed surface, OpenAI TypeScript SDK matching surface, LangChain `AnthropicWebSearch` tool wrapper, LangChain `TavilySearchResults` / `BraveSearch` / `ExaSearchResults` integrations, LangGraph search-grounded-agent template, smolagents `WebSearchTool`, OpenAI Cookbook web-search-with-citations tutorial, AgentOps observability for grounded-search sessions, the canonical Search-Augmented Generation pattern (search-with-citations replacing pure RAG with embedded-vector retrieval), the canonical structured-citation-attribution data-model where every grounded text block carries a `citations` array linking specific text-spans back to source URLs+excerpts (a STRUCTURAL data-model requirement that distinguishes this surface from #220 image-input, #224 embeddings, #225 audio, #226 image-gen, #227 video-gen, #228 mesh-gen, #229 realtime, #230 computer-use, #231 fine-tuning, #232 code-execution — none of which had REQUIRED-grounded-citation-field-on-output-text-block), coding-agent peer landscape: anomalyco/opencode has zero `web_search_20250305` integration (ships only client-side WebFetch tool — confirmed via web search 2026-04-26), sst/opencode predecessor zero web-search-tool, charmbracelet/crush zero server-managed web-search-tool, continue.dev `@web` slash command uses Tavily/Brave third-party but zero Anthropic-native `web_search_20250305` integration, aider zero web-search (only `--web` flag for one-shot Brave-search ingestion, no grounded-citations), cursor zero `web_search_20250305` (Cursor Web Search announced 2026-Q1 but uses third-party Tavily not Anthropic-native), zed zero web-search-tool, claude-code upstream 2026-Q1 release does include `web_search_20250305` integration partially (UNLIKE prior cluster members where claude-code also had only stub), making this the FIRST cluster member where claude-code partially leads but claw-code has zero coverage — the leading-vs-trailing parity gap is structural and time-sensitive because every coding-agent integrating web-search-with-citations after Q2-2025 is converging on the `web_search_20250305` typed surface as the canonical baseline / claw-code is one of MULTIPLE coding-agent clients without server-managed web-search-with-citations BUT the gap is uniformly zero across the surveyed ecosystem with the exception of claude-code partial coverage AND the inverse-locality complement to the existing local CLIENT-SIDE `WebSearch` tool makes #233 a structural prerequisite of every grounded-search-with-citations coding-agent affordance — the canonical 2024-2026-era research-coding workflow ("ask Claude to research a topic, get answer with inline citations linking each claim to a primary source URL") that is currently impossible to build on top of `claw-code` despite Anthropic explicitly positioning `web_search_20250305` as a flagship 2025-Q1 GA capability — #233 closes the upstream prerequisite of every server-managed-web-search-with-citations / grounded-research / source-attribution / fact-checking-with-citations / academic-citation-formatting / news-summarization-with-sources / competitive-intelligence-with-citations / due-diligence-coding coding-agent affordance — the canonical SERVER-MANAGED-SEARCH-AND-CITATION half of the inverse-locality `Tool-locality-axis` META-cluster that complements #232's `Sandbox-locality-axis` META-cluster). + +Required fix shape: (a) extend `ToolDefinition` at `rust/crates/api/src/types.rs:104` with optional `max_uses: Option` + `allowed_domains: Option>` + `blocked_domains: Option>` + `user_location: Option` fields gated behind tool-name-discriminator; (b) extend `ToolChoice` enum at `types.rs:117` with `WebSearch` variant for server-managed-web-search routing; (c) extend `ToolResultContentBlock` enum at `types.rs:99` with `WebSearchToolResult { content: Vec }` variant where each result-location carries `url`, `title`, `encrypted_content` (opaque), `page_age` (optional); (d) add `citations: Option>` REQUIRED field on `OutputContentBlock::Text` variant (CRITICAL — the citations array MUST be threaded through response decoding because Anthropic emits it on every grounded text block); (e) add `Citation { type: "web_search_result_location", url, title, encrypted_index, cited_text, page_age? }` typed model with `encrypted_index` opaque-blob handling that is NEVER decoded but ALWAYS roundtripped through subsequent messages; (f) add `UserLocation { type: "approximate", country, region, city, timezone }` typed model; (g) extend `Provider` trait at `providers/mod.rs:17-30` with no new method (web-search reuses the same `send_message` + `stream_message` surface) but ensure `send_message` impl on Anthropic side correctly threads `tools: [WebSearchTool]` and decodes `citations` arrays on every output text block; (h) extend `ProviderClient` enum at `client.rs:8-14` with `WebSearchProvider::Anthropic-web_search_20250305` first-class plus `Brave-Search`/`Tavily`/`Exa`/`Perplexity`/`Serper`/`Linkup`/`Jina` partner stubs returning typed-Unsupported errors with recommended-partner suggestions; (i) wire `web_search_20250305` into the tool-name registry at `rust/crates/tools/src/lib.rs` distinct from the existing CLIENT-SIDE local-scrape `WebSearch` tool, with clear naming distinction (e.g., `WebSearch` = local-scrape, `WebSearchServer` or `WebSearchGrounded` = server-managed), and ensure the local `WebSearch` and server-managed `web_search_20250305` can coexist in tool definitions for fallback-on-server-rate-limit scenarios; (j) add `claw web-search create/list-citations/format-bibliography`, `claw cite check/format/export-bibtex`, `claw groundsearch query/list-sources` CLI subcommand parity in `rusty-claude-cli/src/main.rs`; (k) add `/web-search`, `/cite`, `/grounded-search`, `/research`, `/source` slash command parity in `commands/src/lib.rs` distinct from existing local-filesystem `/search` slash command, with naming clearly disambiguating server-managed-web-search from local-filesystem-search; (l) add per-search-invocation pricing-tier extension to `ModelPricing` covering `web_search_per_invocation_usd` field (Anthropic charges $10 per 1000 invocations FLAT) plus per-citation tracking telemetry; (m) add tests for `web_search_20250305` tool-definition request encoding with all five parameter fields (max_uses, allowed_domains, blocked_domains, user_location, name), `web_search_tool_result` content-block decoding with multi-record `WebSearchResultLocation` lists carrying opaque `encrypted_content`, `citations` array round-trip on response with `encrypted_index` opaque-blob preservation, `tool_choice: web_search` request encoding, and Federated-search-partner-routing dispatch; (n) add structured-citation-attribution-aware response formatting in the runtime so that every assistant response with a `citations` array on output text blocks is rendered with footnote-style or inline-bracket-style attribution to the user, never silently dropping the citations during display; (o) add `Tool-locality-axis` documentation in any future doc to disambiguate the inverse-locality pair from #232's `Sandbox-locality-axis` — server-managed-search-tool with REQUIRED-grounded-citations is the SECOND inverse-locality META-cluster pair after server-managed-code-execution-sandbox, and the canonical `Tool-locality-axis` doctrine applies symmetrically to every future server-managed-tool that has a CLIENT-SIDE local-stub shadow. + +**Status:** Open. No source code changed. Filed as ROADMAP-only dogfood pinpoint from the 2026-04-26 06:00 KST clawhip nudge after rebasing on top of #232. Filed 2026-04-26 06:00 KST. HEAD: d155a2f (post-#232). Branch: feat/jobdori-168c-emission-routing. Sibling-shape cluster: 32 pinpoints. Multimodal-IO cluster: 10 members. Provider-asymmetric-delegation cluster: 10 members. **Sandbox-locality-axis META-cluster: 2 members stable (#230 + #232).** **Tool-locality-axis META-cluster FOUNDED: 2 members (#232 + #233 — the SECOND inverse-locality META-cluster, sister to Sandbox-locality, founding a META-META-cluster doctrine).** **Server-managed-tool-as-tool-choice-discriminator cluster: 2 members (#232 + #233).** **Server-driven-tool-execution-loop cluster: 2 members (#232 + #233).** **ToolResultContentBlock-extension mini-cluster: 3 members (#230 + #232 + #233).** **Federated-search-partner-routing cluster: 1 member (founder).** **Server-opaque-encrypted-roundtripped-content cluster: 1 member (founder, intentional-opaque-by-design).** **Required-grounded-citation-field-on-output-text-block cluster: 1 member (founder).** **Date-suffix-versioning-in-tool-name-without-beta-header cluster: 1 member (founder, distinct from #232's double-gate).** **Server-side-pre-execution-filter-on-tool-definition cluster: 1 member (founder).** **Server-side-rate-limit-on-tool-definition cluster: 1 member (founder).** **Geo-biasing-at-tool-definition cluster: 1 member (founder).** **Discrete-event-counter-pricing-axis cluster: 1 member (founder).** **Per-search-invocation-pricing cluster: 1 member (founder).** Eight new clusters founded in a single pinpoint plus participation in FIVE inherited clusters — the THIRD-largest single-cycle cluster-founding count after #230 and #232, but the FIRST single cycle to FOUND a new META-cluster (Tool-locality-axis) AND establish the META-META-cluster doctrine connecting Sandbox-locality-axis with Tool-locality-axis. Thirteen-layer-fusion-shape is the largest single-pinpoint fusion catalogued. Distinct from prior cluster members; the thirteen-layer-fusion-shape-with-required-grounded-citation-field-on-output-text-block-and-server-opaque-encrypted-roundtripped-content is novel and applies to follow-on candidate **File-search Tool API typed taxonomy** (the natural #234 candidate that introduces the SECOND server-managed-tool-as-tool-choice-discriminator pair-extension to OpenAI Assistants `file_search` with vector-store-backed grounded-citation attribution — same `Tool-locality-axis` META-cluster pattern but with FILE-CORPUS-search instead of WEB-search modality) and **Image-generation Tool-as-server-managed-tool typed taxonomy** (the OpenAI Responses `tool_choice: image_generation` server-managed image-gen surface that #226 covered as a standalone endpoint but does NOT yet cover as a server-managed-tool-as-tool-choice-discriminator extension — adding the THIRD member to `Server-managed-tool-as-tool-choice-discriminator` cluster). #233 closes the upstream prerequisite of every server-managed-web-search-with-citations / grounded-research / source-attribution / fact-checking-with-citations / academic-citation-formatting / news-summarization-with-sources / competitive-intelligence-with-citations / due-diligence-coding coding-agent affordance — the canonical 2024-2026-era research-coding workflow that is currently impossible to build on top of `claw-code` DESPITE Anthropic explicitly positioning `web_search_20250305` as a flagship 2025-Q1 GA capability — and is the FIRST cluster member where claude-code upstream partially leads while claw-code has zero coverage AND the SECOND inverse-locality META-cluster pair (CLIENT-SIDE local `WebSearch` shadow vs SERVER-SIDE `web_search_20250305` absent) after #232's first META-cluster pair (CLIENT-SIDE `REPL` shadow vs SERVER-SIDE `code_execution_20250825` absent) — founding the `Tool-locality-axis` META-cluster doctrine as the sister to `Sandbox-locality-axis` and establishing the META-META-cluster pattern that every future server-managed-tool with a client-side local-stub shadow will inherit. + +🪨