mirror of
https://github.com/morluto/rea.git
synced 2026-10-12 02:19:24 +00:00
perf(evidence): remove disposable ledger work from standalone import
Count already-validated records and unknown revisions without reimporting, sealing, and exporting a temporary empty ledger. Keep canonical integrity checks at the file boundary and verify counts and malformed bundles through the compiled CLI. Validation: Evidence file and CLI consumer suites; check:fast; Flameox CPU profiles and alternating 3.8 MB import benchmark (315.8 ms to 102.5 ms warm median, identical result digests). No real-provider workflow changed or verified.
This commit is contained in:
@@ -5,27 +5,22 @@ import type { JsonValue } from "../domain/jsonValue.js";
|
||||
import { jsonValueSchema } from "../domain/jsonValue.js";
|
||||
import { err, ok, type Result } from "../domain/result.js";
|
||||
import { compareBundles } from "../domain/bundleComparison.js";
|
||||
import { EvidenceLedger } from "./investigation/EvidenceLedger.js";
|
||||
import {
|
||||
readEvidenceBundle,
|
||||
writeEvidenceBundle,
|
||||
} from "./EvidenceBundleFiles.js";
|
||||
|
||||
/** Validate and merge one bundle using the session Evidence ledger. */
|
||||
/** Validate a standalone bundle and report its complete record/revision counts. */
|
||||
export const importEvidenceBundleCommand = async (
|
||||
path: string,
|
||||
): Promise<Result<JsonValue, AnalysisError>> => {
|
||||
const loaded = await readEvidenceBundle(path);
|
||||
if (!loaded.ok) return loaded;
|
||||
const ledger = createLedger();
|
||||
const imported = ledger.import(loaded.value);
|
||||
return imported.ok
|
||||
? ok({
|
||||
imported: imported.value.recordsAdded,
|
||||
unknowns_added: imported.value.unknownsAdded,
|
||||
total: ledger.export().records.length,
|
||||
})
|
||||
: imported;
|
||||
return ok({
|
||||
imported: loaded.value.records.length,
|
||||
unknowns_added: loaded.value.unknowns.length,
|
||||
total: loaded.value.records.length,
|
||||
});
|
||||
};
|
||||
|
||||
/** Validate a source bundle and atomically export canonical bytes. */
|
||||
@@ -64,8 +59,6 @@ export const compareEvidenceBundlesCommand = async (input: {
|
||||
}
|
||||
};
|
||||
|
||||
const createLedger = (): EvidenceLedger => new EvidenceLedger();
|
||||
|
||||
const projectWrite = (
|
||||
bundle: EvidenceBundle,
|
||||
written: Awaited<ReturnType<typeof writeEvidenceBundle>>,
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
import { writeFile } from "node:fs/promises";
|
||||
import { join } from "node:path";
|
||||
|
||||
import { expect } from "vitest";
|
||||
|
||||
import { createEvidence } from "../../../src/domain/evidence.js";
|
||||
import { createEvidenceBundle } from "../../../src/domain/evidenceBundle.js";
|
||||
import {
|
||||
createResidualUnknown,
|
||||
updateResidualUnknown,
|
||||
} from "../../../src/domain/residualUnknown.js";
|
||||
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
||||
import { cliTest } from "../../support/cli/cliFixture.js";
|
||||
|
||||
const revisionBundle = () => {
|
||||
const records = ["open", "investigate"].map((operation) =>
|
||||
createEvidence(
|
||||
undefined,
|
||||
{ id: "fixture", name: "Fixture", version: "1" },
|
||||
{ operation, parameters: {}, result: { observed: operation } },
|
||||
),
|
||||
);
|
||||
const [opened, investigated] = records;
|
||||
if (opened === undefined || investigated === undefined)
|
||||
throw new Error("Missing mutation Evidence");
|
||||
const details = {
|
||||
severity: "high" as const,
|
||||
supporting_evidence_ids: [],
|
||||
contradicting_evidence_ids: [],
|
||||
required_authority: null,
|
||||
required_confidence: "observed" as const,
|
||||
required_environment: null,
|
||||
recommended_probes: [],
|
||||
relationships: [],
|
||||
};
|
||||
const initial = createResidualUnknown(
|
||||
{ question: "How is this input handled?", domain: "protocol", ...details },
|
||||
opened.evidence_id,
|
||||
null,
|
||||
);
|
||||
const revised = updateResidualUnknown(
|
||||
initial,
|
||||
{
|
||||
unknown_id: initial.unknown_id,
|
||||
expected_revision: initial.revision,
|
||||
status: "investigating",
|
||||
...details,
|
||||
resolution: null,
|
||||
},
|
||||
investigated.evidence_id,
|
||||
);
|
||||
return createEvidenceBundle(records, [initial, revised]);
|
||||
};
|
||||
|
||||
cliTest(
|
||||
"reports standalone import counts for every unknown revision",
|
||||
async ({ cli }) => {
|
||||
const root = await createTestTempDirectory("rea-evidence-import-");
|
||||
const path = join(root, "bundle.json");
|
||||
await writeFile(path, JSON.stringify(revisionBundle()));
|
||||
const result = await cli.run({
|
||||
arguments: ["evidence-import", path, "--json"],
|
||||
});
|
||||
expect(result.exitCode).toBe(0);
|
||||
expect(result.json).toEqual({ imported: 2, unknowns_added: 2, total: 2 });
|
||||
},
|
||||
);
|
||||
|
||||
cliTest(
|
||||
"rejects altered Evidence and incomplete unknown history before reporting counts",
|
||||
async ({ cli }) => {
|
||||
const root = await createTestTempDirectory("rea-evidence-import-invalid-");
|
||||
const path = join(root, "bundle.json");
|
||||
const bundle = revisionBundle();
|
||||
for (const invalid of [
|
||||
{
|
||||
...bundle,
|
||||
records: bundle.records.map((record) => ({
|
||||
...record,
|
||||
normalized_result: "altered",
|
||||
})),
|
||||
},
|
||||
{ ...bundle, unknowns: bundle.unknowns.slice(1) },
|
||||
]) {
|
||||
await writeFile(path, JSON.stringify(invalid));
|
||||
const result = await cli.run({
|
||||
arguments: ["evidence-import", path, "--json"],
|
||||
});
|
||||
expect(result.exitCode).toBe(1);
|
||||
expect(result.json).toMatchObject({
|
||||
code: "evidence_integrity_mismatch",
|
||||
});
|
||||
expect(result.json).not.toHaveProperty("imported");
|
||||
}
|
||||
},
|
||||
);
|
||||
Reference in New Issue
Block a user