mirror of
https://github.com/morluto/rea.git
synced 2026-11-15 11:13:21 +00:00
fix(javascript)!: bind runtime identities to capture evidence (#10063)
fix(javascript)!: bind runtime graph identities to capture Evidence
This commit is contained in:
1 parent
b4d501e714
commit
3eb502ae5d
7 files changed
+258
-4
No files matched your search
@@ -446,6 +446,7 @@ export const applicationNodeIdentitySchema = z.discriminatedUnion("strategy", [
|
||||
z.strictObject({
|
||||
strategy: z.literal("runtime-instance"),
|
||||
stability: z.literal("capture-only"),
|
||||
capture_evidence_id: prefixedDigestSchema("ev"),
|
||||
capture_sha256: digestSchema,
|
||||
runtime_key: boundedTextSchema,
|
||||
}),
|
||||
|
||||
@@ -111,7 +111,7 @@ export const runtimeEvidence = (
|
||||
extractor: extractor("observe-passive-cdp"),
|
||||
coverage: completeCoverage,
|
||||
limitations: ["Only passive CDP metadata was observed."],
|
||||
evidence_ids: [],
|
||||
evidence_ids: [`ev_${"c".repeat(64)}`],
|
||||
});
|
||||
|
||||
type FixtureNode = ReturnType<typeof createJavaScriptApplicationNode>;
|
||||
@@ -271,6 +271,7 @@ const buildNativeRuntimeNodes = (): FixtureNode[] => [
|
||||
{
|
||||
strategy: "runtime-instance",
|
||||
stability: "capture-only",
|
||||
capture_evidence_id: `ev_${"c".repeat(64)}`,
|
||||
capture_sha256: APPLICATION_GRAPH_DIGESTS.capture,
|
||||
runtime_key: "script-preload",
|
||||
},
|
||||
|
||||
@@ -411,6 +411,7 @@ describe("JavaScript Application Graph: identity and evidence", () => {
|
||||
identity: {
|
||||
strategy: "runtime-instance",
|
||||
stability: "capture-only",
|
||||
capture_evidence_id: `ev_${"c".repeat(64)}`,
|
||||
capture_sha256: "6".repeat(64),
|
||||
runtime_key: "script-preload",
|
||||
},
|
||||
@@ -811,6 +812,50 @@ describe("JavaScript Application Graph: duplicate and orphan rejection", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("rejects runtime identities without an explicit capture Evidence identifier", () => {
|
||||
expect(() =>
|
||||
createJavaScriptApplicationNode({
|
||||
kind: "runtime-script-instance",
|
||||
identity: {
|
||||
strategy: "runtime-instance",
|
||||
stability: "capture-only",
|
||||
capture_sha256: APPLICATION_GRAPH_DIGESTS.capture,
|
||||
runtime_key: "script-preload",
|
||||
},
|
||||
observations: [
|
||||
{
|
||||
label: null,
|
||||
properties: {},
|
||||
evidence: runtimeEvidence("script-preload"),
|
||||
},
|
||||
],
|
||||
}),
|
||||
).toThrow(/capture_evidence_id/u);
|
||||
});
|
||||
|
||||
it("requires runtime identities to retain their capture Evidence provenance", () => {
|
||||
const runtimeWithUnrelatedEvidence = createJavaScriptApplicationNode({
|
||||
kind: "runtime-script-instance",
|
||||
identity: {
|
||||
strategy: "runtime-instance",
|
||||
stability: "capture-only",
|
||||
capture_evidence_id: `ev_${"d".repeat(64)}`,
|
||||
capture_sha256: APPLICATION_GRAPH_DIGESTS.capture,
|
||||
runtime_key: "script-preload",
|
||||
},
|
||||
observations: [
|
||||
{
|
||||
label: null,
|
||||
properties: {},
|
||||
evidence: runtimeEvidence("script-preload"),
|
||||
},
|
||||
],
|
||||
});
|
||||
expect(() => graphForNode(runtimeWithUnrelatedEvidence)).toThrow(
|
||||
/identity is not supported/u,
|
||||
);
|
||||
});
|
||||
|
||||
describe("JavaScript Application Graph: identity strategy requirements", () => {
|
||||
it("requires every identity strategy to have compatible supporting evidence", () => {
|
||||
const mismatchedPath = createJavaScriptApplicationNode({
|
||||
@@ -841,6 +886,7 @@ describe("JavaScript Application Graph: identity strategy requirements", () => {
|
||||
identity: {
|
||||
strategy: "runtime-instance",
|
||||
stability: "capture-only",
|
||||
capture_evidence_id: `ev_${"c".repeat(64)}`,
|
||||
capture_sha256: APPLICATION_GRAPH_DIGESTS.capture,
|
||||
runtime_key: "script-preload",
|
||||
},
|
||||
|
||||
@@ -245,6 +245,7 @@ const observationMatchesIdentity = (
|
||||
return false;
|
||||
const location = evidence.location.value;
|
||||
return (
|
||||
evidence.evidence_ids.includes(identity.capture_evidence_id) &&
|
||||
location.capture_sha256 === identity.capture_sha256 &&
|
||||
[location.target_key, location.frame_key, location.script_key].includes(
|
||||
identity.runtime_key,
|
||||
|
||||
@@ -137,7 +137,9 @@ const graphCoverageFacts = (
|
||||
inspection.completeness.conditions.includes("truncated"),
|
||||
);
|
||||
const captureHasUnknownOmissions = input.captures.some(
|
||||
({ inspection }) => inspection.completeness.unavailable_sections.length > 0,
|
||||
({ inspection }) =>
|
||||
inspection.completeness.attach_limited_sections.length > 0 ||
|
||||
inspection.completeness.unavailable_sections.length > 0,
|
||||
);
|
||||
const inputTruncated =
|
||||
input.layers.some(({ graph }) => graph.coverage.truncated) ||
|
||||
|
||||
@@ -102,11 +102,11 @@ const targetEntity = (
|
||||
label: target.title,
|
||||
properties: {
|
||||
runtime_type: target.type,
|
||||
...(location.kind === "unresolved"
|
||||
...("unresolved_location" in target
|
||||
? {
|
||||
reported_url: location.value,
|
||||
location_kind: "unresolved",
|
||||
location_reason: "unverifiable-file-location",
|
||||
location_reason: target.unresolved_location.reason,
|
||||
}
|
||||
: { location: location.value }),
|
||||
attached: target.attached,
|
||||
@@ -276,6 +276,7 @@ const runtimeEntity = (
|
||||
identity: {
|
||||
strategy: "runtime-instance",
|
||||
stability: "capture-only",
|
||||
capture_evidence_id: capture.evidence.evidence_id,
|
||||
capture_sha256: capture.captureSha256,
|
||||
runtime_key: input.runtimeKey,
|
||||
},
|
||||
@@ -420,6 +421,9 @@ const runtimeSectionComplete = (
|
||||
if (section === "target") return true;
|
||||
if (section === "scripts") return capture.scriptsCompleteWithinScope;
|
||||
return (
|
||||
!capture.inspection.completeness.attach_limited_sections.includes(
|
||||
section,
|
||||
) &&
|
||||
!capture.inspection.completeness.truncated_sections.includes(section) &&
|
||||
!capture.inspection.completeness.unavailable_sections.includes(section)
|
||||
);
|
||||
|
||||
Reference in new issue
Block a user