diff --git a/docs/user-visible-errors.csv b/docs/user-visible-errors.csv index a1c3536f39..f4934b80b5 100644 --- a/docs/user-visible-errors.csv +++ b/docs/user-visible-errors.csv @@ -1,10 +1,10 @@ harm_rank,location,trigger,current_copy,user_risk,proposed_replacement,implementation_status,verification_result 1,src/domain/errors.ts:AnalysisCapabilityUnavailableError,Requested analysis unavailable,"Provider {providerId} cannot execute {operation}: {reason}",Exposes provider and internal operation/reason,"This analysis is unavailable for the current target. Choose another analysis or target.",implemented,focused assertions passed; full `npm run check` passed -2,src/domain/errors.ts:ProviderAdapterError,Provider adapter fails,"Provider {providerId} adapter failed during {operation}",Exposes provider and implementation boundary,"Analysis could not complete. Retry once; if it continues, run `rea doctor`.",implemented,focused assertions passed; full `npm run check` passed -3,src/domain/errors.ts:HopperRemoteError,Remote analysis request fails,"Hopper request failed ({code}): {safeMessage}",Exposes provider name code and upstream text,"Analysis could not complete. Retry once; if it continues, run `rea doctor`.",implemented,focused assertions passed; full `npm run check` passed -4,src/domain/errors.ts:HopperProtocolError,Malformed provider protocol result,Raw constructor message,Can expose provider protocol and implementation details,"Analysis returned an unreadable result. Retry once; if it continues, run `rea doctor`.",implemented,focused assertions passed; full `npm run check` passed -5,src/domain/errors.ts:AnalysisOutputError,Analysis output fails parsing,"Invalid analysis output for {operation}: {reason}",Exposes internal operation and parser reason,"Analysis returned an unreadable result. Retry once; if it continues, run `rea doctor`.",implemented,focused assertions passed; full `npm run check` passed -6,src/domain/errors.ts:AnalysisProtocolError,Application protocol fails,Raw constructor message,Can expose protocol internals,"Analysis returned an unreadable result. Retry once; if it continues, run `rea doctor`.",implemented,focused assertions passed; full `npm run check` passed +2,src/domain/errors.ts:ProviderAdapterError,Provider adapter fails,"Provider {providerId} adapter failed during {operation}",Exposes provider and implementation boundary,"Analysis could not complete. Run `rea doctor` and review the reported details; repeating the unchanged request is not expected to succeed.",implemented,focused assertions passed; full `npm run check` passed +3,src/domain/errors.ts:HopperRemoteError,Remote analysis request fails,"Hopper request failed ({code}): {safeMessage}",Exposes provider name code and upstream text,"Analysis could not complete. Run `rea doctor` and review the reported details; repeating the unchanged request is not expected to succeed.",implemented,focused assertions passed; full `npm run check` passed +4,src/domain/errors.ts:HopperProtocolError,Malformed provider protocol result,Raw constructor message,Can expose provider protocol and implementation details,"Analysis returned an unreadable result. Run `rea doctor` and review the reported details; repeating the unchanged request is not expected to succeed.",implemented,focused assertions passed; full `npm run check` passed +5,src/domain/errors.ts:AnalysisOutputError,Analysis output fails parsing,"Invalid analysis output for {operation}: {reason}",Exposes internal operation and parser reason,"Analysis returned an unreadable result. Run `rea doctor` and review the reported details; repeating the unchanged request is not expected to succeed.",implemented,focused assertions passed; full `npm run check` passed +6,src/domain/errors.ts:AnalysisProtocolError,Application protocol fails,Raw constructor message,Can expose protocol internals,"Analysis returned an unreadable result. Run `rea doctor` and review the reported details; repeating the unchanged request is not expected to succeed.",implemented,focused assertions passed; full `npm run check` passed 7,src/domain/errors.ts:HopperProcessError,Analysis subprocess stops,"Hopper bridge stopped unexpectedly with code {exitCode}",Exposes provider bridge and process code,"Analysis could not start or stopped unexpectedly. Run `rea doctor`, then try again.",implemented,focused assertions passed; full `npm run check` passed 8,src/domain/errors.ts:HopperStartError,Analysis subprocess cannot start,Hopper application bridge could not be started,Exposes provider and bridge implementation,"Analysis could not start or stopped unexpectedly. Run `rea doctor`, then try again.",implemented,focused assertions passed; full `npm run check` passed 9,src/domain/errors.ts:BinaryTargetError,Target cannot open,"Cannot open artifact: {reason}",May expose raw reason and lacks checks,"Preserve the target admission reason; directories name analyze_javascript_application and rea analyze as available alternatives.",implemented,focused assertions passed; full `npm run check` passed @@ -21,7 +21,7 @@ harm_rank,location,trigger,current_copy,user_risk,proposed_replacement,implement 21,src/domain/errors.ts:AnalysisCancelledError,Caller cancels analysis,"Analysis operation was cancelled: {operation}",Exposes operation identifier,"Analysis was cancelled. Start it again when ready.",implemented,focused assertions passed; full `npm run check` passed 22,src/domain/errors.ts:HopperCancelledError,Caller cancels provider request,Hopper operation was cancelled,Exposes provider name,"Analysis was cancelled. Start it again when ready.",implemented,focused assertions passed; full `npm run check` passed 23,src/domain/errors.ts:NoBinaryOpenError,Analysis requested without target,"No app is open. Ask the user which app to investigate, then call open_binary with its local path.",Low risk; already supplies agent recovery,Keep current copy,implemented,focused assertions passed; full `npm run check` passed -24,src/server/toolResult.ts:successResult,Successful value violates public output schema,AnalysisOutputError: Analysis output does not match the tool contract,Exposes internal error tag and contract implementation,"Analysis returned an unreadable result. Retry once; if it continues, run `rea doctor`.",implemented,focused assertions passed; full `npm run check` passed +24,src/server/toolResult.ts:successResult,Successful value violates public output schema,AnalysisOutputError: Analysis output does not match the tool contract,Exposes internal error tag and contract implementation,"Analysis returned an unreadable result. Run `rea doctor` and review the reported details; repeating the unchanged request is not expected to succeed.",implemented,focused assertions passed; full `npm run check` passed 24.5,src/server/registerOfficialTools.ts:capability unknown,Approved unknown tracking records an unavailable analysis,"TOOL_NAME is unavailable: PROVIDER_REASON",Exposes an internal tool identifier and provider diagnostic in persistent user-visible evidence,"The requested analysis is unavailable for the current target.",implemented,verified by focused MCP integration test 24.6,src/application/ReferenceSourceImportEntries.ts:failed entry,A partial reference import contains an unreadable entry,Low-level reader diagnostic stored in entry limitations,Can persist filesystem or reader implementation details,"Code- and entry-specific safe guidance with a retry, limit, exclusion, or platform recovery step.",implemented,verified by exhaustive focused projection test 24.7,src/server/registerSessionTools.ts:process residual,Capture records a residual unknown linked to capture Evidence,SCOPE: RAW_REASON,Persists adapter diagnostic and implementation wording,"Was SCOPE behavior fully observed during capture?",implemented,verified by focused session MCP test diff --git a/src/domain/analysisErrorPresentation.ts b/src/domain/analysisErrorPresentation.ts index 07b2269476..b0e81e54ee 100644 --- a/src/domain/analysisErrorPresentation.ts +++ b/src/domain/analysisErrorPresentation.ts @@ -66,7 +66,7 @@ export const analysisErrorRemediationAction = ( if (error instanceof HopperRemoteError) return error.diagnosticType === "invalid_request" ? "Correct the reported address, document, or arguments and retry." - : "Review the Hopper diagnostic details; correct the request or retry if the failure was transient."; + : "Review the Hopper diagnostic details and correct the request or target; run `rea doctor` if the provider itself is failing. Repeating the unchanged request is not expected to succeed."; if (error instanceof EvidenceReferenceError) return "Use an exact Evidence reference retained by this session, supply the complete inline Evidence, re-run its producer, or import its Evidence bundle. close_binary clears retained records."; if ( @@ -282,7 +282,7 @@ const hopperProcessMessage = (error: HopperProcessError): string => { const standardErrorMessage = (tag: AnalysisErrorTag): string | undefined => { if (UNREADABLE_OUTPUT_TAGS.has(tag)) - return "Analysis returned an unreadable result. Retry once; if it continues, run `rea doctor`."; + return "Analysis returned an unreadable result. Run `rea doctor` and review the reported details; repeating the unchanged request is not expected to succeed."; if (UNSUPPORTED_PROVIDER_TAGS.has(tag)) return "This analysis is unavailable for the current target. Choose another analysis or target."; if (CANCELLED_TAGS.has(tag)) @@ -290,7 +290,7 @@ const standardErrorMessage = (tag: AnalysisErrorTag): string | undefined => { if (TIMEOUT_TAGS.has(tag)) return "Analysis took too long. Try a smaller request, then run `rea doctor` if it continues."; if (ADAPTER_FAILURE_TAGS.has(tag)) - return "Analysis could not complete. Retry once; if it continues, run `rea doctor`."; + return "Analysis could not complete. Run `rea doctor` and review the reported details; repeating the unchanged request is not expected to succeed."; if (START_FAILURE_TAGS.has(tag)) return "Analysis could not start or stopped unexpectedly. Run `rea doctor`, then try again."; return undefined; diff --git a/src/domain/analysisErrorProjection.test.ts b/src/domain/analysisErrorProjection.test.ts index 66fa069140..635d5c0219 100644 --- a/src/domain/analysisErrorProjection.test.ts +++ b/src/domain/analysisErrorProjection.test.ts @@ -384,6 +384,38 @@ describe("analysis error projection: provider failures", () => { }); }); +describe("analysis error projection: retry guidance", () => { + it.each([ + [ + "unreadable output", + new AnalysisOutputError("inspect_firmware_regions", "report missing"), + "unreadable_output", + ], + [ + "adapter failure", + new ProviderAdapterError("firmware", "inspect_firmware_regions"), + "execution_failure", + ], + [ + "Hopper remote failure", + new HopperRemoteError(7, "Hopper analysis failed", { + diagnosticType: "bridge_exception", + operation: "trace_feature", + }), + "execution_failure", + ], + ])( + "does not recommend an unchanged retry for non-retryable %s", + (_name, error, code) => { + const projected = projectAnalysisError(error); + + expect(projected).toMatchObject({ code, retryable: false }); + for (const text of [projected.message, projected.remediation.action]) + expect(text).not.toMatch(/\bretry\b/iu); + }, + ); +}); + describe("analysis error projection: caller contract", () => { it("preserves the reported output constraint without exposing its internal cause", () => { const projected = projectAnalysisError( diff --git a/tests/boundary/mcp/enhancedTools.03-returns-typed-graph-failures-and.test.ts b/tests/boundary/mcp/enhancedTools.03-returns-typed-graph-failures-and.test.ts index 035689b58c..511dec47c1 100644 --- a/tests/boundary/mcp/enhancedTools.03-returns-typed-graph-failures-and.test.ts +++ b/tests/boundary/mcp/enhancedTools.03-returns-typed-graph-failures-and.test.ts @@ -44,7 +44,7 @@ describe("enhanced MCP tools", () => { error: { category: "execution_failure", message: - "Analysis returned an unreadable result. Retry once; if it continues, run `rea doctor`.", + "Analysis returned an unreadable result. Run `rea doctor` and review the reported details; repeating the unchanged request is not expected to succeed.", }, }, ], diff --git a/tests/boundary/mcp/enhancedTools.callPathsAndBatches.test.ts b/tests/boundary/mcp/enhancedTools.callPathsAndBatches.test.ts index 1792221acc..5ed8e9c529 100644 --- a/tests/boundary/mcp/enhancedTools.callPathsAndBatches.test.ts +++ b/tests/boundary/mcp/enhancedTools.callPathsAndBatches.test.ts @@ -96,11 +96,11 @@ describe("enhanced MCP tools", () => { category: "execution_failure", details: { operation: "decompile", reason: "failed" }, message: - "Analysis returned an unreadable result. Retry once; if it continues, run `rea doctor`.", + "Analysis returned an unreadable result. Run `rea doctor` and review the reported details; repeating the unchanged request is not expected to succeed.", retryable: false, remediation: { action: - "Analysis returned an unreadable result. Retry once; if it continues, run `rea doctor`.", + "Analysis returned an unreadable result. Run `rea doctor` and review the reported details; repeating the unchanged request is not expected to succeed.", }, }, },