fix(javascript): retain selected application paths in Evidence

Record the admitted selected path separately from canonical artifact identity in successful and partial Evidence. Anchor relative inputs consistently across both CLI routes using the existing caller-path owner.

Adapt shared client verifier assertions and boundary coverage from PR #5261, and the dedicated-route anchoring correction proposed in PR #5265. Historical parsing remains independent of live paths, including legacy records without the parameter.

Validation: 118 focused tests in eight files, static and docs checks, discovery, and installed Gemini CLI 0.29.5 loopback verification of 207 schemas/241 examples passed. Synthetic static-analysis fixtures; no live Google API or native target execution.

Fixes #5258

Co-authored-by: kwakhyun <khyun2348@naver.com>
Co-authored-by: vishal-tambi <tambivishal3@gmail.com>
This commit is contained in:
committed 2026-10-20 00:37:45 +08:00
1 parent aacf740a04
commit c4aaf813e0
19 files changed
+286 -17

No files matched your search

@@ -1,5 +1,5 @@
import { setImmediate } from "node:timers";
import { mkdir, writeFile } from "node:fs/promises";
import { mkdir, realpath, symlink, writeFile } from "node:fs/promises";
import { join } from "node:path";
import { expect, it, onTestFinished } from "vitest";
import { z } from "zod";
@@ -16,7 +16,16 @@ import { analyzeJavaScriptApplication } from "../../support/javascriptApplicatio
it.each(["during cleanup", "on the next control turn"] as const)(
"retains the final source when cancellation arrives %s after analysis",
async (timing) => {
const root = await createTestTempDirectory("rea-js-cancel-handoff-");
const parent = await createTestTempDirectory("rea-js-cancel-handoff-");
const root = join(parent, "physical");
const selected = join(parent, "selected");
await mkdir(root);
await symlink(
root,
selected,
process.platform === "win32" ? "junction" : "dir",
);
const resolved = await realpath(root);
await writeFile(
join(root, "main.js"),
'import { readFile } from "node:fs/promises"; export { readFile };\n',
@@ -35,13 +44,22 @@ it.each(["during cleanup", "on the next control turn"] as const)(
const scope = new CancellingCleanupScope();
onTestFinished(() => scope.close());
const result = await analyzeOwnedApplication(
{ input_path: root, format: "directory" },
{ input_path: selected, format: "directory" },
scope,
{ signal: controller.signal },
);
if (result.ok) throw new Error("Cancelled handoff must not succeed");
const projected = projectAnalysisError(result.error);
expect(projected.code).toBe("cancelled");
expect(projected).toMatchObject({
details: {
partial_observation: {
parameters: { input_path: selected },
subject: { local_path: resolved },
normalized_result: { input_path: resolved },
},
},
});
const partial = z
.object({
details: z.object({