fix(snapshot): count newly retained workflow bindings on import (#4428)
AnalysisSnapshotCache.stage counted new direct entries but never incremented for new workflow entries, so a snapshot carrying only a trace_feature binding reported 0 new entries while retaining it. Count a workflow binding when its query ID is new, matching direct entries; replacements and capacity-refused bindings stay uncounted. Fixes #4377
This commit is contained in:
1 parent
cc4ed5b904
commit
3220e17b8b
2 files changed
+75
-9
No files matched your search
@@ -118,6 +118,68 @@ it("exports independent nested query, workflow and Evidence payloads", () => {
|
||||
expect(serializeAnalysisSnapshot(fresh.value)).toBe(expected);
|
||||
});
|
||||
|
||||
it("counts newly retained direct and workflow bindings when staging", () => {
|
||||
const source = new AnalysisSnapshotCache();
|
||||
const target = ANALYSIS_SNAPSHOT_TARGET;
|
||||
const profile = ANALYSIS_SNAPSHOT_PROFILE;
|
||||
const parameters = { address: "0x1000" };
|
||||
const workflowProfile = workflowAnalysisProfile(profile, "trace_feature");
|
||||
source.record({
|
||||
target,
|
||||
profile,
|
||||
operation: "procedure_info",
|
||||
parameters,
|
||||
execution: createAnalysisExecution("direct", ANALYSIS_SNAPSHOT_PROVIDER, {
|
||||
subject: target,
|
||||
analysisProfile: profile,
|
||||
}),
|
||||
});
|
||||
source.recordWorkflow({
|
||||
target,
|
||||
profile,
|
||||
operation: "trace_feature",
|
||||
parameters: { query: "feature" },
|
||||
execution: {
|
||||
...createAnalysisExecution("workflow", REA_WORKFLOW_PROVIDER, {
|
||||
subject: target,
|
||||
}),
|
||||
analysisProfile: workflowProfile,
|
||||
},
|
||||
});
|
||||
const bundle = createEvidenceBundle([
|
||||
createEvidence(target, ANALYSIS_SNAPSHOT_PROVIDER, {
|
||||
operation: "procedure_info",
|
||||
parameters,
|
||||
result: "direct",
|
||||
analysisProfile: profile,
|
||||
}),
|
||||
createEvidence(target, REA_WORKFLOW_PROVIDER, {
|
||||
operation: "trace_feature",
|
||||
confidence: "derived",
|
||||
parameters: { query: "feature" },
|
||||
result: "workflow",
|
||||
analysisProfile: workflowProfile,
|
||||
}),
|
||||
]);
|
||||
const exported = source.export(target, profile, bundle);
|
||||
if (!exported.ok) throw exported.error;
|
||||
const snapshot = parseAnalysisSnapshot(
|
||||
JSON.parse(serializeAnalysisSnapshot(exported.value)),
|
||||
);
|
||||
expect(snapshot.entries).toHaveLength(1);
|
||||
expect(snapshot.workflow_entries).toHaveLength(1);
|
||||
|
||||
const workflowOnly = new AnalysisSnapshotCache();
|
||||
expect(workflowOnly.stage({ ...snapshot, entries: [] })).toBe(1);
|
||||
expect(workflowOnly.workflowEntries()).toHaveLength(1);
|
||||
|
||||
const staged = new AnalysisSnapshotCache();
|
||||
expect(staged.stage(snapshot)).toBe(2);
|
||||
expect(staged.entries()).toHaveLength(1);
|
||||
expect(staged.workflowEntries()).toHaveLength(1);
|
||||
expect(staged.stage(snapshot), "replacements are not new entries").toBe(0);
|
||||
});
|
||||
|
||||
it("rebinds replayed target subjects while preserving child artifact subjects", () => {
|
||||
const cache = new AnalysisSnapshotCache();
|
||||
const target = ANALYSIS_SNAPSHOT_TARGET;
|
||||
@@ -333,15 +395,18 @@ describe("analysis snapshot cache capacity", () => {
|
||||
limitations: execution.limitations,
|
||||
locations: execution.locations,
|
||||
});
|
||||
cache.stage(
|
||||
parseAnalysisSnapshot({
|
||||
target: snapshotTarget(target),
|
||||
binding: snapshotBinding(profile),
|
||||
entries: [],
|
||||
workflow_entries: [incoming],
|
||||
evidence_bundle: createEvidenceBundle([evidence]),
|
||||
}),
|
||||
);
|
||||
expect(
|
||||
cache.stage(
|
||||
parseAnalysisSnapshot({
|
||||
target: snapshotTarget(target),
|
||||
binding: snapshotBinding(profile),
|
||||
entries: [],
|
||||
workflow_entries: [incoming],
|
||||
evidence_bundle: createEvidenceBundle([evidence]),
|
||||
}),
|
||||
),
|
||||
"a capacity-refused workflow binding is not counted",
|
||||
).toBe(0);
|
||||
expect(cache.workflowEntries()).toHaveLength(
|
||||
SNAPSHOT_CACHE_ENTRY_CEILING - 1,
|
||||
);
|
||||
|
||||
@@ -142,6 +142,7 @@ export class AnalysisSnapshotCache {
|
||||
for (const entry of snapshot.workflow_entries) {
|
||||
if (!this.#workflowEntries.has(entry.query_id) && !this.#hasCapacity())
|
||||
continue;
|
||||
if (!this.#workflowEntries.has(entry.query_id)) imported += 1;
|
||||
this.#workflowEntries.set(entry.query_id, entry);
|
||||
}
|
||||
return imported;
|
||||
|
||||
Reference in new issue
Block a user