fix(cli)!: one typed tool-result shape for every --json refusal - #2690
Merged
Merged
Conversation
`tracedecay tool --json` printed a refusal in three shapes. A compatibility
tool printed the MCP tool result. A typed application tool printed its
application envelope with a top-level `problem`. A refusal settled before any
owner answered (a missing daemon socket, a rejected argument, an unknown
tool) printed `{"problem": {reason_code, retryable, ...}}`, which is not a
problem record at all.
Every path now prints the one refusing tool result, `isError` beside the
typed record at `structuredContent.problem`, through one renderer
(`problem_tool_result`). Pre-owner refusals map through the owner's
error-to-problem mapping under the tool's CLI result contract, or under the
adapter problem contract for a name no binding owns. The untyped
`{"problem": ...}` printer is deleted.
A missing daemon socket is now the typed `daemon.unreachable` detail
(`daemon_unreachable`): the socket, the variable that named it, and the
managed service unit as observed (`not_installed`, `unobservable`, or
`installed` with the socket it serves). Its message and stderr keep the
same sentence.
BREAKING CHANGE: `tracedecay tool --json` refusals from typed application
tools and from pre-owner failures print the MCP tool result with the
record at `structuredContent.problem` instead of an application envelope
or an untyped `{"problem": ...}` object. The problem detail union gains
`daemon_unreachable`, and `@tracedecay/sdk` is 0.10.0.
|
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.
Fixes #2672
Cause
After #2651,
tracedecay tool --jsonrefusals still came out in three shapes, depending on which path produced them:search) printed the MCP tool result. This was already correct.callers) went throughprint_cli_application_surface, whose--jsonbranch printedjson_line(&result.result): the application envelope with a top-levelproblem, and noisError.run()printed{"problem": project_route_problem(..)}, the JSON-RPC error-data shape (reason_code/retryable/detail), which is not a problem record. The daemon-down error had no typed detail at all; its socket and service-unit facts existed only inside a sentence.Change
problem_tool_result(tracedecay-mcp):isError, with the typed record atstructuredContent.problem.render_application_resultuses it. A typed-path--jsonrefusal now prints that tool result, markedisErrorjust as on the compatibility path.render_settled_route_refusal. The error is mapped to a problem by the owner's own mapping (graph_tool_error_problem). The envelope uses the tool's CLI result contract (settled_tool_refusal, which replaces the MCP-onlymcp_project_open_reset_refusal); a tool name no binding owns uses the adapter problem contract (tracedecay_api::adapter_problem). The untyped{"problem": ...}printer is deleted, andproject_route_problemis now private to the JSON-RPC error-data path.ApplicationProblemDetailV1::DaemonUnreachable, codedaemon.unreachable, with fieldssocket,named_by, andservice_unit(not_installed|unobservable{error}|installed{path, serves}). It maps tounavailable,retry: after_delay,legal_actions: [retry].unreachable_daemon_detailreplacesunavailable_daemon_socket_message. The rendered message and stderr keep the same sentence.contracts:generate, no drift after the rebase), and@tracedecay/sdkgoes 0.9.0 → 0.10.0.Still open, and outside this issue's scope: a successful typed-path
--jsoncall still prints the application envelope, while a compatibility tool prints the MCP tool result.Fails on master
core_cli_suite tool_cursor_test::every_json_refusal_prints_one_typed_problem_placementrunssearchwith an invalid cursor,callerswith an unknown node id, andstatusagainst a missingTRACEDECAY_DAEMON_SOCKET. It asserts that all three have the same placement and carry the literal typed records. On master (with only this test added) it fails with:With the change it passes. The records are
(invalid_request, cursor.invalid, never),(not_found_or_not_authorized, not_found_or_not_authorized, never), and(unavailable, daemon.unreachable, after_delay), with detail{"kind":"daemon_unreachable","socket":"<path>","named_by":"TRACEDECAY_DAEMON_SOCKET","service_unit":{"state":"not_installed"}}andlegal_actions: ["retry"], and exit code 69.Runtime journey
Debug
tracedecayfrom this branch, an isolatedHOME, and one daemon in aMemoryMax=6Gscope:(
search --cursor not-a-cursor --jsonexit 1,callers --node-id no-such-node --jsonexit 1,TRACEDECAY_DAEMON_SOCKET=<missing> status --jsonexit 69.)Local verification (after the rebase)
core_cli_suite: 170/170 passed (tracedecay-cli bins 350). A re-run of tool_cursor/tool_surface_transport/tool_daemon after the final rebase passed 64/64.mcp_suite: 611/611 passed.code_index_park1, runtime_acceptance (reachability, advisory, tool_client_transport) 22, transport_acceptancetyped_terminal_restart_acceptance10: all passed.-D warningson every touched crate is clean.cargo fmt --checkis clean. The Windows cross-check (cargo check --workspace --all-targets --target x86_64-pc-windows-gnu ...) exits 0.typecheckis clean.pnpm test: 2016/2017, with one codegen fixture test timing out at a load average near 100; it passed 15/15 when run alone.contracts:generateshows no drift. SDKtypecheckandtest(33) pass.BREAKING CHANGE:
tracedecay tool --jsonrefusals from typed application tools and from pre-owner failures print the MCP tool result with the record atstructuredContent.probleminstead of an application envelope or an untyped{"problem": ...}object. The problem detail union gainsdaemon_unreachable, and@tracedecay/sdkis 0.10.0.