diff --git a/ROADMAP.md b/ROADMAP.md index 557b3cc..9c4c69b 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -17073,3 +17073,15 @@ Gap. `claw status` is currently a local workspace cleanliness snapshot, not a pr Required fix shape: (a) extend `claw status --output-format json` `workspace` with `git_head_sha`, `git_head_short`, `git_head_message`, `git_head_timestamp`, `upstream_branch`, `upstream_remote_name`, `upstream_remote_url`, `ahead`, `behind`, `last_fetch_at` (nullable), and `source_of_truth_repo` derived from the existing `OFFICIAL_REPO_URL`; (b) add optional `roadmap_last_pinpoint` / `roadmap_path` when `ROADMAP.md` exists at project root; (c) add `staleness_seconds` or `freshness_status` when upstream data is available, and `freshness_status: unknown_no_fetch` when it is not; (d) mirror the key fields in text mode compactly; (e) regression-test clean, ahead, behind, detached, no-upstream, and wrong-remote fixtures. Acceptance: a dogfood reporter can consume only `claw status --output-format json` plus ROADMAP content and refuse stale/wrong-repo reports without ad hoc git shelling. **Status:** Open. No source code changed. Filed 2026-04-26 15:31 KST. Branch: feat/jobdori-168c-emission-routing. HEAD: `ba6c5bc` before filing. Cluster delta: product-status-provenance +1; sibling to #259 (report provenance) and #271 (repo identity guard), but distinct product status surface layer. Concrete delta this cycle: ROADMAP-only pinpoint appended after live `claw status` JSON/text verification. + +## Pinpoint #274 — MCP tool calls and results render with the generic untyped fallback formatter while native tools get rich field-aware renderers, so every `mcp__server__tool` invocation prints a 96-char JSON summary plus a raw pretty-printed result block instead of the structured icon/path/lines/preview affordances `bash`/`Read`/`Write`/`Edit`/`Glob`/`Grep`/`WebSearch` enjoy + +Dogfooded 2026-04-26 15:32 KST on `feat/jobdori-168c-emission-routing` at HEAD `f36f283` (post-#273). Static audit of `rust/crates/rusty-claude-cli/src/main.rs` `format_tool_call_start` (line 8504) and `format_tool_result` (line 8557) confirms the rendering arms match exclusively on native tool aliases: `"bash" | "Bash"`, `"read_file" | "Read"`, `"write_file" | "Write"`, `"edit_file" | "Edit"`, `"glob_search" | "Glob"`, `"grep_search" | "Grep"`, `"web_search" | "WebSearch"`. MCP qualified names follow the `mcp__{server}__{tool}` shape produced by `runtime::mcp::mcp_tool_name` (e.g., `mcp__claude_ai_Example_Server__weather_tool`); none of these match any specialized arm and both functions fall through to the wildcard `_ =>` branch — `summarize_tool_payload(input)` (96-char JSON-compaction truncate) for the call-start banner and `format_generic_tool_result(icon, name, &parsed)` (pretty-printed JSON dump capped at 60 lines / 4000 chars) for the result. + +Concrete failure mode: an MCP server like `mcp__filesystem__read_file` performs the same logical operation as the native `Read` tool, but the user sees `╰─ mcp__filesystem__read_file ─╮` with `{"path":"…"}` JSON-summarized to 96 chars and a raw JSON pretty-print of the file content as result, instead of the native `📄 Reading …` start banner with structured `✓ read_file: lines` rendering. Same goes for MCP search tools (no `🔎` icon, no match summary), MCP write tools (no `✏️ Writing ( lines)` banner, no diff preview), and MCP shell tools (no `format_bash_result` exit-code/stdout/stderr structuring). Worse, MCP tool input schemas are typically known to the client (`tools/list` returns `inputSchema`), so the renderer has the metadata to extract semantic fields like `path`, `query`, `command`, `content`, `pattern` — it just doesn't. + +Gap. The renderer treats MCP tools as opaque black boxes even though they cover the same semantic categories as native tools (file ops, search, shell, web). This is distinct from #254 (MCP Resources lifecycle absence — server-side concept), distinct from #258/#266/#272 (CLI parse / typed-error / spec gaps), distinct from #268 (`tools/list` re-fetch on resume — staleness, not rendering), and distinct from #261 (compact-summary internal consistency — doesn't touch tool rendering). It founds a NEW `mcp-vs-native-tool-rendering-parity` cluster on the rendering axis and pairs structurally with #268 along the MCP-axis (#268 = catalog freshness, #274 = rendering parity), forming an MCP cross-axis bundle. + +Required fix shape: (a) introduce a `ToolRenderingProfile` enum keyed off the runtime tool category (FileRead, FileWrite, FileEdit, Search, Shell, WebSearch, Generic) and have both native and MCP tools advertise their category at registration time; (b) when an MCP tool's `inputSchema` declares well-known field names (`path`, `paths`, `query`, `pattern`, `command`, `content`), extract them in `format_tool_call_start` via a schema-aware path-extractor that supersedes the current `extract_tool_path` hardcoded key list; (c) thread server identity through the renderer so MCP tool banners can show `⚡ {server} · {tool}` instead of the raw `mcp__server__tool` underscore-glob; (d) emit a `tool_call_render_kind` field in the JSON envelope (`native_typed`, `mcp_typed`, `mcp_generic`, `untyped_fallback`) so dogfood audits can count parity coverage over time; (e) regression-test that an MCP tool whose schema declares `path: string` renders the same `📄 Reading {path}…` start banner as native `Read`, that an MCP shell tool with `command: string` renders the same exit-code/stdout/stderr structure as native `bash`, and that unknown-schema MCP tools fall back to `format_generic_tool_result` cleanly without breaking layout. Acceptance: an MCP `read_file` and a native `Read` of the same path produce visually equivalent terminal output, and the JSON envelope's per-tool `render_kind` field is populated for every tool call. + +**Status:** Open. No source code changed. Filed 2026-04-26 15:32 KST. Branch: feat/jobdori-168c-emission-routing. HEAD: `f36f283` before filing. Cluster delta: founds NEW `mcp-vs-native-tool-rendering-parity` cluster (1 member); pairs with #268 (MCP catalog freshness) on the MCP-axis as a cross-axis bundle (rendering × staleness). Concrete delta this cycle: ROADMAP-only pinpoint appended after static audit of `format_tool_call_start` / `format_tool_result` rendering arms vs `runtime::mcp::mcp_tool_name` qualified-name shape — zero MCP-aware match arms, full fallback to generic untyped path.