mirror of
https://github.com/morluto/rea
synced 2026-10-26 06:16:17 -04:00
fix(artifacts): publish addressable inspection sources through both adapters
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { readArtifactInspectionSources } from "../domain/artifactInspection.js";
|
||||
import { dispatchQueuedInterrupts } from "../process/queuedInterrupts.js";
|
||||
import { absoluteCallerPath } from "../filesystem/callerPath.js";
|
||||
import { requireAuthenticationHeadroom } from "./JsonAuthenticationHeadroom.js";
|
||||
@@ -84,7 +85,16 @@ export const deliverAnalysisEvidence = async (
|
||||
});
|
||||
if (!headroom.ok)
|
||||
return err(headroom.error.retainPartialObservation(evidence));
|
||||
const bundle = createImmutableEvidenceBundle([evidence]);
|
||||
const sourceEvidence =
|
||||
evidence.operation === "inspect_artifact"
|
||||
? readArtifactInspectionSources(evidence.normalized_result)
|
||||
: ok([]);
|
||||
if (!sourceEvidence.ok)
|
||||
return err(sourceEvidence.error.retainPartialObservation(evidence));
|
||||
const bundle = createImmutableEvidenceBundle([
|
||||
...sourceEvidence.value,
|
||||
evidence,
|
||||
]);
|
||||
const delivered =
|
||||
detail === "summary"
|
||||
? inspectAnalysisViewValidated(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { readArtifactInspectionSources } from "../domain/artifactInspection.js";
|
||||
import type { AnalysisViewRequest } from "../domain/analysisView/analysisView.js";
|
||||
import { z } from "incur";
|
||||
import { parseEvidence, type Evidence } from "../domain/evidence.js";
|
||||
@@ -97,6 +98,9 @@ export const deliverCliAnalysisEvidence = async (
|
||||
detail,
|
||||
evidenceOutput,
|
||||
...(input.view === undefined ? {} : { view: input.view }),
|
||||
...(input.sourceEvidence === undefined
|
||||
? {}
|
||||
: { sourceEvidence: input.sourceEvidence }),
|
||||
});
|
||||
};
|
||||
|
||||
@@ -127,13 +131,22 @@ export const publishCliAnalysisEvidence = async (
|
||||
return projectAnalysisError(
|
||||
delivered.error.retainPartialObservation(complete),
|
||||
);
|
||||
const inspectionSources =
|
||||
complete.operation === "inspect_artifact"
|
||||
? readArtifactInspectionSources(complete.normalized_result)
|
||||
: ok([]);
|
||||
if (!inspectionSources.ok)
|
||||
return projectAnalysisError(
|
||||
inspectionSources.error.retainPartialObservation(complete),
|
||||
);
|
||||
const published = await publishEvidenceDelivery({
|
||||
bundle: createEvidenceBundle([
|
||||
...new Map(
|
||||
[...(input.sourceEvidence ?? []), complete].map((record) => [
|
||||
record.evidence_id,
|
||||
record,
|
||||
]),
|
||||
[
|
||||
...(input.sourceEvidence ?? []),
|
||||
...inspectionSources.value,
|
||||
complete,
|
||||
].map((record) => [record.evidence_id, record]),
|
||||
).values(),
|
||||
]),
|
||||
complete,
|
||||
|
||||
@@ -123,10 +123,13 @@ export const artifactInventorySummarySchema = z.strictObject({
|
||||
limitation_count: z.number().int().nonnegative(),
|
||||
});
|
||||
|
||||
const inputError = (message: string): AnalysisInputError =>
|
||||
const inputError = (
|
||||
field: "source" | "view",
|
||||
message: string,
|
||||
): AnalysisInputError =>
|
||||
new AnalysisInputError("inspect_analysis_view", undefined, [
|
||||
{
|
||||
path: ["source"],
|
||||
path: [field],
|
||||
reason: "invalid_value",
|
||||
message,
|
||||
},
|
||||
@@ -221,7 +224,7 @@ const sourceFailure = (
|
||||
if (cause instanceof z.ZodError)
|
||||
return err(analysisViewResultInputError(input, cause));
|
||||
if (!(cause instanceof ArtifactInventoryValidationError)) throw cause;
|
||||
return err(inputError(cause.message));
|
||||
return err(inputError("source", cause.message));
|
||||
};
|
||||
|
||||
/** Project exact source records; exhausted pages cover available records, not runtime behavior. */
|
||||
@@ -233,12 +236,16 @@ export const projectArtifactInventoryView = (
|
||||
if (operation !== "inventory_artifact" && operation !== "inspect_artifact")
|
||||
return err(
|
||||
inputError(
|
||||
"source",
|
||||
"Inventory views require inventory_artifact or inspect_artifact Evidence.",
|
||||
),
|
||||
);
|
||||
if (view.kind !== "summary" && view.kind !== "inventory")
|
||||
return err(
|
||||
inputError("Artifact Evidence supports summary and inventory views."),
|
||||
inputError(
|
||||
"view",
|
||||
"Artifact Evidence supports summary and inventory views.",
|
||||
),
|
||||
);
|
||||
const parsed = parseSource(parent);
|
||||
if (!parsed.ok) return parsed;
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
import { readEvidencePayload } from "./evidenceValidation.js";
|
||||
import type { EvidenceIntegrityError } from "./evidenceErrors.js";
|
||||
import { ok, type Result } from "./result.js";
|
||||
import {
|
||||
canBorrowParsedJsonSnapshot,
|
||||
immutableJsonSnapshotMember,
|
||||
} from "./immutableJson.js";
|
||||
import {
|
||||
artifactIntegrityPairOf,
|
||||
artifactSha256PairSchema,
|
||||
@@ -437,3 +444,22 @@ const inspectionCoverage = (
|
||||
if (inventory.coverage.status !== "complete") return "partial";
|
||||
return "complete-within-substeps";
|
||||
};
|
||||
|
||||
/** Own the atomic source closure published or retained with an inspection. */
|
||||
export const readArtifactInspectionSources = (
|
||||
result: unknown,
|
||||
): Result<readonly Evidence[], EvidenceIntegrityError> => {
|
||||
const parsed = readEvidencePayload(artifactInspectionResultSchema, result);
|
||||
if (!parsed.ok) return parsed;
|
||||
const inspection = canBorrowParsedJsonSnapshot(result, parsed.value)
|
||||
? result
|
||||
: parsed.value;
|
||||
const substeps = immutableJsonSnapshotMember(inspection, "substeps");
|
||||
return ok(
|
||||
inspection.substeps.map((step, index) => {
|
||||
const ownedStep = immutableJsonSnapshotMember(substeps, String(index));
|
||||
immutableJsonSnapshotMember(ownedStep, "evidence");
|
||||
return step.evidence;
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
import {
|
||||
canBorrowParsedJsonSnapshot,
|
||||
immutableJsonSnapshotMember,
|
||||
} from "../domain/immutableJson.js";
|
||||
import type { EvidenceMcpServer } from "./EvidenceMcpServer.js";
|
||||
|
||||
import { ARTIFACT_TOOL_CONTRACTS } from "../contracts/artifactToolContracts.js";
|
||||
import { createArtifactExtractionDestination } from "../application/artifacts/ArtifactExtractionDestination.js";
|
||||
import { registerEvidenceTools } from "./registerEvidenceTools.js";
|
||||
import { artifactInspectionResultSchema } from "../domain/artifactInspection.js";
|
||||
import { readArtifactInspectionSources } from "../domain/artifactInspection.js";
|
||||
import {
|
||||
retainedSummaryDelivery,
|
||||
withoutDeliveryDetail,
|
||||
@@ -40,16 +36,9 @@ export const registerArtifactTools = (
|
||||
parametersForEvidence: decodeWithoutDelivery,
|
||||
sourceEvidence: (operation, result) => {
|
||||
if (operation !== "inspect_artifact") return [];
|
||||
const parsed = artifactInspectionResultSchema.parse(result);
|
||||
const inspection = canBorrowParsedJsonSnapshot(result, parsed)
|
||||
? result
|
||||
: parsed;
|
||||
const substeps = immutableJsonSnapshotMember(inspection, "substeps");
|
||||
return inspection.substeps.map((step, index) => {
|
||||
const ownedStep = immutableJsonSnapshotMember(substeps, String(index));
|
||||
immutableJsonSnapshotMember(ownedStep, "evidence");
|
||||
return step.evidence;
|
||||
});
|
||||
const parsed = readArtifactInspectionSources(result);
|
||||
if (!parsed.ok) throw parsed.error;
|
||||
return parsed.value;
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user