* fix(managed): keep caller-input details in managed workflow errors
The managed workflows wrapped every rejected input as
`new AnalysisInputError(op, { cause })` with no issues. The projected
result said "Correct the listed arguments and retry" and listed nothing:
- `rea import-managed-reconstruction`,
`rea project-managed-application-graph` and
`rea verify-managed-native-boundaries` lost every schema issue for
malformed JSON;
- domain checks such as a reconstruction text hash mismatch, or Evidence
from the wrong operation, lost their message on CLI and MCP;
- `rea compare-managed-members` with a missing file did not say which
path failed.
Add managedInputError, which projects Zod issues with their paths and
keeps a domain TypeError's message, as the JavaScript workflows already
do. Return the BinaryTargetError from an unopenable comparison path
unchanged, with details.path, as every other path-based command does.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(managed): keep nested Evidence schema issues off request paths
A ZodError raised after the request parsed comes from a nested
Evidence result, so its issue paths are relative to that result.
Projecting it against the whole request reported, for example,
artifact.sha256 as a missing request field. Keep request-relative
projection for the raw request's schema failures. Report nested schema
failures as root issues whose message names the nested location.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(managed): type the malformed nested Evidence fixture
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(workflows): keep input details in the remaining workflow services
Inventory projection (project_android_application_graph and
project_apple_application_graph), build_reconstruction_obligation_ledger
and evaluate_reconstruction_coverage had the same issue-less
`AnalysisInputError({ cause })` as the managed services. For example,
evaluating coverage for an unknown boundary returned "Correct the listed
arguments" with no issues, dropping "Unknown reconstruction boundary: X"
on CLI and MCP.
Move the helpers to src/application/workflowInputError.ts and use them
for these services: requestInputError for raw request schema failures,
workflowInputError for nested schema and domain constraint failures.
Classification is unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
94 lines
3.2 KiB
TypeScript
94 lines
3.2 KiB
TypeScript
import { z } from "zod";
|
|
|
|
import { AnalysisProtocolError } from "../../domain/analysisErrorCore.js";
|
|
import { type AnalysisError } from "../../domain/analysisErrorBase.js";
|
|
import { createEvidence, type Evidence } from "../../domain/evidence.js";
|
|
import { jsonValueSchema } from "../../domain/jsonValue.js";
|
|
import {
|
|
managedApplicationGraphResultSchema,
|
|
projectManagedApplicationGraph,
|
|
projectManagedApplicationGraphInputSchema,
|
|
type ManagedApplicationGraphResult,
|
|
type ProjectManagedApplicationGraphInput,
|
|
} from "../../domain/managed/managedApplicationGraph.js";
|
|
import { err, ok, type Result } from "../../domain/result.js";
|
|
import { MANAGED_WORKFLOW_PROVIDER } from "../InvestigationProviders.js";
|
|
import {
|
|
requestInputError,
|
|
workflowInputError,
|
|
} from "../workflowInputError.js";
|
|
|
|
const OPERATION = "project_managed_application_graph" as const;
|
|
|
|
/** Project authenticated managed Evidence into a provider-neutral graph. */
|
|
export const projectManagedApplicationGraphEvidence = (
|
|
rawInput: unknown,
|
|
): Result<Evidence, AnalysisError> => {
|
|
const parsed = projectManagedApplicationGraphInputSchema.safeParse(rawInput);
|
|
if (!parsed.success)
|
|
return err(requestInputError(OPERATION, parsed.error, rawInput));
|
|
try {
|
|
const result = projectManagedApplicationGraph(parsed.data);
|
|
return ok(createManagedApplicationGraphEvidence(parsed.data, result));
|
|
} catch (cause: unknown) {
|
|
return err(
|
|
cause instanceof TypeError || cause instanceof z.ZodError
|
|
? workflowInputError(OPERATION, cause)
|
|
: new AnalysisProtocolError(
|
|
"Managed application graph projection produced an invalid result",
|
|
{ cause },
|
|
),
|
|
);
|
|
}
|
|
};
|
|
|
|
const createManagedApplicationGraphEvidence = (
|
|
input: ProjectManagedApplicationGraphInput,
|
|
result: ManagedApplicationGraphResult,
|
|
): Evidence =>
|
|
createEvidence(subjectTarget(input), MANAGED_WORKFLOW_PROVIDER, {
|
|
predicateType: "rea.managed-application-graph",
|
|
operation: OPERATION,
|
|
parameters: {
|
|
managed_artifact_evidence_id: input.managed_artifact?.evidence_id ?? null,
|
|
managed_members_evidence_id: input.managed_members?.evidence_id ?? null,
|
|
managed_native_boundaries_evidence_id:
|
|
input.managed_native_boundaries?.evidence_id ?? null,
|
|
},
|
|
result: jsonValueSchema.parse(
|
|
managedApplicationGraphResultSchema.parse(result),
|
|
),
|
|
rawResult: null,
|
|
confidence: "inferred",
|
|
authority: "analyst-inference",
|
|
environment: null,
|
|
limitations: result.limitations,
|
|
evidenceLinks: result.evidence_links,
|
|
});
|
|
|
|
const subjectTarget = (
|
|
input: ProjectManagedApplicationGraphInput,
|
|
):
|
|
| {
|
|
readonly path: string;
|
|
readonly sha256: string;
|
|
readonly format: "pe";
|
|
readonly architecture?: "x86" | "x86_64" | "arm" | "arm64";
|
|
}
|
|
| undefined => {
|
|
const subject =
|
|
input.managed_artifact?.subject ??
|
|
input.managed_members?.subject ??
|
|
input.managed_native_boundaries?.subject;
|
|
if (subject === undefined || subject === null || subject.format !== "pe")
|
|
return undefined;
|
|
return {
|
|
path: subject.local_path,
|
|
sha256: subject.digest.sha256,
|
|
format: "pe",
|
|
...(subject.architecture === null
|
|
? {}
|
|
: { architecture: subject.architecture }),
|
|
};
|
|
};
|