mirror of
https://github.com/morluto/rea.git
synced 2026-10-29 19:05:45 +00:00
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:
1 parent
aacf740a04
commit
c4aaf813e0
19 files changed
+286
-17
No files matched your search
@@ -0,0 +1,142 @@
|
||||
import {
|
||||
mkdir,
|
||||
readFile,
|
||||
realpath,
|
||||
rm,
|
||||
symlink,
|
||||
writeFile,
|
||||
} from "node:fs/promises";
|
||||
import { join } from "node:path";
|
||||
import { expect } from "vitest";
|
||||
|
||||
import { parseEvidence } from "../../../src/domain/evidence.js";
|
||||
import { parseEvidenceBundle } from "../../../src/domain/evidenceBundle.js";
|
||||
import { parseApplicationGraphEvidence } from "../../../src/application/javascript/JavaScriptApplicationEvidenceGraph.js";
|
||||
import { JAVASCRIPT_APPLICATION_EVIDENCE_EXAMPLE } from "../../../src/contracts/javascript/javascriptRuntimeReconciliationExample.js";
|
||||
import { connectLocalToolsMcp } from "../../fixtures/localToolsMcp.js";
|
||||
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
||||
import { cliTest } from "../../support/cli/cliFixture.js";
|
||||
|
||||
cliTest(
|
||||
"retains selected JavaScript path separately from resolved identity",
|
||||
async ({ cli }) => {
|
||||
const root = await createTestTempDirectory("rea-js-selected-path-");
|
||||
const physicalPath = join(root, "physical-app");
|
||||
const selectedPath = join(root, "selected-app");
|
||||
await mkdir(physicalPath);
|
||||
await writeFile(join(physicalPath, "main.js"), "export const value = 7;\n");
|
||||
await symlink(
|
||||
physicalPath,
|
||||
selectedPath,
|
||||
process.platform === "win32" ? "junction" : "dir",
|
||||
);
|
||||
const resolvedPath = await realpath(physicalPath);
|
||||
expect(await realpath(selectedPath)).toBe(resolvedPath);
|
||||
|
||||
const cliResponse = await cli.run({
|
||||
arguments: [
|
||||
"analyze-javascript-application",
|
||||
selectedPath,
|
||||
"--artifact-format",
|
||||
"directory",
|
||||
"--json",
|
||||
],
|
||||
environment: { REA_LOG_LEVEL: "silent" },
|
||||
});
|
||||
expect(cliResponse.exitCode, cliResponse.stderr).toBe(0);
|
||||
const cliEvidence = parseEvidence(cliResponse.json);
|
||||
|
||||
for (const command of ["analyze", "analyze-javascript-application"]) {
|
||||
const relativeResponse = await cli.run({
|
||||
arguments: [command, "./selected-app", "--json"],
|
||||
cwd: root,
|
||||
environment: { REA_LOG_LEVEL: "silent" },
|
||||
});
|
||||
expect(relativeResponse.exitCode, relativeResponse.stderr).toBe(0);
|
||||
const relativeEvidence = parseEvidence(relativeResponse.json);
|
||||
expect(relativeEvidence.parameters.input_path, command).toBe(
|
||||
selectedPath,
|
||||
);
|
||||
expect(relativeEvidence.subject).toEqual(cliEvidence.subject);
|
||||
expect(relativeEvidence.normalized_result).toEqual(
|
||||
cliEvidence.normalized_result,
|
||||
);
|
||||
}
|
||||
|
||||
const { call } = await connectLocalToolsMcp({ REA_LOG_LEVEL: "silent" });
|
||||
const aliasResponse = await call("analyze_javascript_application", {
|
||||
input_path: selectedPath,
|
||||
format: "directory",
|
||||
integrity_policy: "fail",
|
||||
});
|
||||
expect(
|
||||
aliasResponse.isError,
|
||||
JSON.stringify(aliasResponse.content),
|
||||
).not.toBe(true);
|
||||
const aliasEvidence = parseEvidence(aliasResponse.structuredContent);
|
||||
const physicalResponse = await call("analyze_javascript_application", {
|
||||
input_path: physicalPath,
|
||||
format: "directory",
|
||||
integrity_policy: "fail",
|
||||
});
|
||||
expect(
|
||||
physicalResponse.isError,
|
||||
JSON.stringify(physicalResponse.content),
|
||||
).not.toBe(true);
|
||||
const physicalEvidence = parseEvidence(physicalResponse.structuredContent);
|
||||
|
||||
for (const evidence of [cliEvidence, aliasEvidence]) {
|
||||
expect(evidence.parameters.input_path).toBe(selectedPath);
|
||||
expect(evidence.subject?.local_path).toBe(resolvedPath);
|
||||
expect(evidence.normalized_result).toMatchObject({
|
||||
input_path: resolvedPath,
|
||||
});
|
||||
expect(parseApplicationGraphEvidence(evidence).ok).toBe(true);
|
||||
}
|
||||
expect(cliEvidence.normalized_result).toEqual(
|
||||
aliasEvidence.normalized_result,
|
||||
);
|
||||
expect(physicalEvidence.parameters.input_path).toBe(physicalPath);
|
||||
expect(physicalEvidence.subject?.local_path).toBe(resolvedPath);
|
||||
expect(physicalEvidence.normalized_result).toEqual(
|
||||
aliasEvidence.normalized_result,
|
||||
);
|
||||
expect(physicalEvidence.subject?.digest.sha256).toBe(
|
||||
aliasEvidence.subject?.digest.sha256,
|
||||
);
|
||||
expect(physicalEvidence.evidence_id).not.toBe(aliasEvidence.evidence_id);
|
||||
const bundlePath = join(root, "retained-evidence.json");
|
||||
expect(
|
||||
(await call("export_evidence_bundle", { path: bundlePath })).isError,
|
||||
).not.toBe(true);
|
||||
await rm(selectedPath);
|
||||
await rm(physicalPath, { recursive: true });
|
||||
const bundle = parseEvidenceBundle(
|
||||
JSON.parse(await readFile(bundlePath, "utf8")),
|
||||
);
|
||||
const retained = bundle.records.find(
|
||||
(record) => record.evidence_id === aliasEvidence.evidence_id,
|
||||
);
|
||||
expect(retained?.parameters.input_path).toBe(selectedPath);
|
||||
for (const evidence of [
|
||||
cliEvidence,
|
||||
aliasEvidence,
|
||||
physicalEvidence,
|
||||
retained,
|
||||
])
|
||||
expect(
|
||||
parseApplicationGraphEvidence(JSON.parse(JSON.stringify(evidence))).ok,
|
||||
).toBe(true);
|
||||
expect((await call("close_binary", {})).isError).not.toBe(true);
|
||||
expect(
|
||||
(await call("import_evidence_bundle", { path: bundlePath })).isError,
|
||||
).not.toBe(true);
|
||||
|
||||
expect(
|
||||
JAVASCRIPT_APPLICATION_EVIDENCE_EXAMPLE.parameters,
|
||||
).not.toHaveProperty("input_path");
|
||||
expect(
|
||||
parseApplicationGraphEvidence(JAVASCRIPT_APPLICATION_EVIDENCE_EXAMPLE).ok,
|
||||
).toBe(true);
|
||||
},
|
||||
);
|
||||
Reference in new issue
Block a user