mirror of
https://github.com/morluto/rea.git
synced 2026-11-11 01:13:39 +00:00
Declare logical Evidence sources once and resolve exact retained inputs through shared application workflows across 20 composition tools. Preserve domain-owned authentication, source closure, caller choices, coverage and resource admission. Validation includes public CLI/MCP regressions, local Codex terra/high trials and fresh-import real-artifact workflows. Measurements, failed attempts and coverage limits are recorded in docs/verification/evidence-input-composition-2026-10-31.md. Fixes #8293. Fixes #8281. Assisted-by: Suika (gensokyo-skills:suika-scatter-gather-planning)
71 lines
2.7 KiB
TypeScript
71 lines
2.7 KiB
TypeScript
import { z } from "incur";
|
|
import type { Logger } from "pino";
|
|
|
|
import {
|
|
compareArtifactEvidence,
|
|
resolveArtifactComparisonSources,
|
|
} from "../application/artifacts/ArtifactComparisonEvidence.js";
|
|
import { ArtifactResourceScope } from "../artifacts/ArtifactResourceScope.js";
|
|
import { CLI_COMMANDS } from "../cliCommandNames.js";
|
|
import { parseCliJsonInput, resolveCliJsonPaths } from "../cliJsonInput.js";
|
|
import { logCliCommand } from "../cliLogging.js";
|
|
import { ARTIFACT_COMPARISON_PROVIDER } from "../domain/comparisonEvidenceIdentity.js";
|
|
import { withCommandCancellation } from "./commandCancellation.js";
|
|
import { finishAnalysisCommand } from "./finishAnalysisCommand.js";
|
|
import type { CliInstance } from "./types.js";
|
|
|
|
const OPERATION = "compare_artifacts";
|
|
|
|
/** Compare artifact inventories through the same source owners and workflow as MCP. */
|
|
export const registerArtifactComparisonCommand = (
|
|
cli: CliInstance,
|
|
logger: Logger,
|
|
): void => {
|
|
const name = CLI_COMMANDS.compareArtifacts;
|
|
cli.command(name, {
|
|
description:
|
|
'Compare two artifact inventories named as {left, right}: complete Evidence or {kind:"evidence-file",path,evidence_id?}. A one-shot command retains no session Evidence for retained-evidence references.',
|
|
args: z.object({
|
|
inputJson: z.string().describe("Inline workflow JSON or JSON file path"),
|
|
}),
|
|
run: ({ args }) =>
|
|
withCommandCancellation((signal) =>
|
|
logCliCommand(logger, name, async () => {
|
|
const input = await parseCliJsonInput(
|
|
args.inputJson,
|
|
OPERATION,
|
|
signal,
|
|
);
|
|
if (!input.ok) return input.error;
|
|
// Evidence-file paths are resolved against the operator's working directory.
|
|
const value = resolveCliJsonPaths(input.value, [
|
|
["left", "path"],
|
|
["right", "path"],
|
|
]);
|
|
const resources = new ArtifactResourceScope();
|
|
const result = await finishAnalysisCommand(
|
|
async () => {
|
|
const sources = await resolveArtifactComparisonSources(
|
|
value,
|
|
undefined,
|
|
{ signal, resources },
|
|
);
|
|
if (!sources.ok) return sources;
|
|
const compared = compareArtifactEvidence(sources.value);
|
|
return compared.ok
|
|
? { ok: true as const, value: compared.value.evidence }
|
|
: compared;
|
|
},
|
|
resources,
|
|
ARTIFACT_COMPARISON_PROVIDER.id,
|
|
OPERATION,
|
|
signal,
|
|
);
|
|
return result.ok
|
|
? result.value
|
|
: { error: "Application workflow failed", ...result.error };
|
|
}),
|
|
),
|
|
});
|
|
};
|