fix(snapshot): replay validated workflow evidence (#984)

* fix(snapshot): bind replay to validated cache entry

* fix(snapshot): persist composed workflow results

* fix(snapshot): enforce workflow replay identity

* fix(snapshot): honor cancellation after route resolution

* test(snapshot): make cancellation race deterministic

* fix(snapshot): replay all composed workflow evidence

* fix(snapshot): index workflow evidence once per snapshot

Validate workflow entries against a query and content index instead of scanning the evidence bundle for every entry.

* fix(snapshot): reuse previewed routes and bound workflow cache

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
This commit is contained in:
morlutoandCursor Agent authored and GitHub committed 2026-10-08 01:33:39 +08:00
1 parent 96a46ada0a
commit 1d62e54e1f
11 files changed
+1462 -80

No files matched your search

+36 -3
View File
@@ -46,11 +46,22 @@ interface ResolveSessionOpenInput {
) => boolean;
}
interface ResolveSessionTargetInput {
readonly router: SessionProviderRouter;
readonly current: CurrentOpenBinding | undefined;
readonly target: BinaryTarget;
readonly options: BinarySessionOpenOptions;
readonly stagedSnapshotMatches: (
target: BinaryTarget,
profile: AnalysisProfileCommitment | null,
) => boolean;
}
/** Parse a target, resolve its provider route, and validate snapshot binding. */
export const resolveSessionOpen = async (
input: ResolveSessionOpenInput,
): Promise<Result<ResolvedSessionOpen, AnalysisError>> => {
const { router, current, path, options, stagedSnapshotMatches } = input;
const { path, options } = input;
const parsed = await parseBinaryTarget(
path,
process.cwd(),
@@ -59,7 +70,14 @@ export const resolveSessionOpen = async (
options.formatHint,
);
if (!parsed.ok) return parsed;
const target = parsed.value;
return resolveSessionTarget({ ...input, target: parsed.value });
};
/** Resolve a known target's provider route and validate snapshot binding. */
export const resolveSessionTarget = async (
input: ResolveSessionTargetInput,
): Promise<Result<ResolvedSessionOpen, AnalysisError>> => {
const { router, current, target, options } = input;
const sameTarget =
current?.target.path === target.path &&
snapshotMatchesTarget(snapshotTarget(current.target), target);
@@ -68,7 +86,22 @@ export const resolveSessionOpen = async (
? ({ ok: true, value: current.route } as const)
: await router.resolve(target, options.providerId, options.signal);
if (!resolvedRoute.ok) return resolvedRoute;
const route = resolvedRoute.value;
return validateResolvedSessionTarget({
...input,
route: resolvedRoute.value,
});
};
/** Revalidate a previewed route against the current session and snapshot binding. */
export const validateResolvedSessionTarget = (
input: Omit<ResolveSessionTargetInput, "router"> & {
readonly route: SessionProviderRoute;
},
): Result<ResolvedSessionOpen, AnalysisError> => {
const { current, target, route, options, stagedSnapshotMatches } = input;
const sameTarget =
current?.target.path === target.path &&
snapshotMatchesTarget(snapshotTarget(current.target), target);
const snapshotError = validateSnapshot({
snapshot: options.snapshot,
target,