* fix(enhanced): stop call graph traversals at unconfirmed provider cleanup A relationship read whose provider could not confirm cleanup of resources it owns was projected into a graph node or call-path failure, the traversal kept dispatching queued reads, and get_call_graph / trace_call_path returned success with the cleanup_incomplete status buried inside the result. Both traversals now read relationships through one shared owner, readCallRelationships, which classifies a cancelled read or a read with unconfirmed owned cleanup as terminal. On such a cleanup stop the workflow returns the provider's own error as the outcome, so its cleanup owner, retry binding and live resolution stay intact, and keeps the work admitted before the stop as the workflow's normal result shape with a caveat naming the stopped procedure and the unexpanded count. The composed-workflow layer turns that admitted result into partial workflow Evidence on the failure, and the MCP adapter retains it through the shared partial-error delivery. Ordinary read failures still produce successful partial results. Fixes #8369 Co-Authored-By: Claude Opus 5.5 <[email protected]> * fix(enhanced): retain every carried partial Evidence on enhanced failures Enhanced-tool failures used the shared partial-error delivery only when this PR's workflow partial was attached. A failing read that already carried its own partial Evidence, and analyze_function dossier failures, were projected inline and never recorded with the session writer, so readback and bundle export could not recover them. Every enhanced execution failure now goes through one delivery owner that uses toPartialErrorToolResult with the session writer; it still falls back to inline when no writer or no valid Evidence exists. Tests compare the traversal caveat against its owning formatter instead of copying the sentence. Co-Authored-By: Claude Opus 5.5 <[email protected]> --------- Co-authored-by: Claude Opus 5.5 <[email protected]>
52 lines
1.8 KiB
TypeScript
52 lines
1.8 KiB
TypeScript
import type { z } from "zod";
|
|
|
|
import { analysisInputErrorFromIssues } from "../domain/inputIssueProjection.js";
|
|
import type { AnalysisError } from "../domain/analysisErrorBase.js";
|
|
import type { JsonValue } from "../domain/jsonValue.js";
|
|
import type { TraceContainingProcedure } from "../domain/native/nativeObservation.js";
|
|
import { err, type Result } from "../domain/result.js";
|
|
import {
|
|
enhancedInputSchemas,
|
|
type EnhancedToolName,
|
|
} from "../contracts/enhancedInputs.js";
|
|
|
|
/** A failure that stopped a workflow after it admitted part of its result. */
|
|
export interface PartialEnhancedFailure {
|
|
readonly ok: false;
|
|
readonly error: AnalysisError;
|
|
/** The workflow's own result shape, holding only work admitted before the stop. */
|
|
readonly partialResult: JsonValue;
|
|
}
|
|
export type EnhancedOutcome =
|
|
| Result<JsonValue, AnalysisError>
|
|
| PartialEnhancedFailure;
|
|
export type EnhancedResult = Promise<EnhancedOutcome>;
|
|
|
|
/** Keep the stopping failure primary while retaining the admitted result. */
|
|
export const failedWithPartialResult = (
|
|
error: AnalysisError,
|
|
partialResult: JsonValue,
|
|
): PartialEnhancedFailure => ({ ok: false, error, partialResult });
|
|
export type TraceReference = {
|
|
readonly target_address: string;
|
|
readonly source_address: string;
|
|
readonly containing_procedure: TraceContainingProcedure;
|
|
};
|
|
|
|
/** One enhanced call whose input was parsed at its owning adapter boundary. */
|
|
export type ValidatedEnhancedCall = {
|
|
[Name in EnhancedToolName]: {
|
|
readonly name: Name;
|
|
readonly input: z.output<(typeof enhancedInputSchemas)[Name]>;
|
|
};
|
|
}[EnhancedToolName];
|
|
|
|
export const invalidEnhancedInput = (
|
|
name: EnhancedToolName,
|
|
cause: z.ZodError,
|
|
input: unknown,
|
|
): EnhancedResult =>
|
|
Promise.resolve(
|
|
err(analysisInputErrorFromIssues(name, cause.issues, input, { cause })),
|
|
);
|