solsticestudioai commited on
Commit
39f387e
·
verified ·
1 Parent(s): 78a429e

Update DeltaStore Trace Explorer Phase 2: replay-core.js

Browse files
Files changed (1) hide show
  1. replay-core.js +32 -0
replay-core.js CHANGED
@@ -1,4 +1,5 @@
1
  export const SCHEMA_VERSION = "deltastore-replay-trace-v1";
 
2
 
3
  export function parseTrace(value) {
4
  const trace = typeof value === "string" ? JSON.parse(value) : value;
@@ -15,3 +16,34 @@ export function compareBranch(trace, branchId) {
15
  const index = trace.original_trajectory.findIndex(event => event.event_id === checkpoint.event_id);
16
  return { sharedPrefix: trace.original_trajectory.slice(0, index + 1), originalTail: trace.original_trajectory.slice(index + 1), alternate: branch.events, originalOutcome: trace.final_outcome || {}, alternateOutcome: branch.final_outcome || {}, classification: branch.comparison_classification || "outcome_changed" };
17
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  export const SCHEMA_VERSION = "deltastore-replay-trace-v1";
2
+ export const EXCHANGE_SCHEMA_VERSION = "solstice-agent-trace-exchange/v1";
3
 
4
  export function parseTrace(value) {
5
  const trace = typeof value === "string" ? JSON.parse(value) : value;
 
16
  const index = trace.original_trajectory.findIndex(event => event.event_id === checkpoint.event_id);
17
  return { sharedPrefix: trace.original_trajectory.slice(0, index + 1), originalTail: trace.original_trajectory.slice(index + 1), alternate: branch.events, originalOutcome: trace.final_outcome || {}, alternateOutcome: branch.final_outcome || {}, classification: branch.comparison_classification || "outcome_changed" };
18
  }
19
+
20
+ export function parseExchange(value) {
21
+ const packageValue = typeof value === "string" ? JSON.parse(value) : value;
22
+ if (!packageValue || packageValue.schema_version !== EXCHANGE_SCHEMA_VERSION || !Array.isArray(packageValue.events)) throw new Error("Unsupported or malformed exchange package");
23
+ const ids = new Set();
24
+ let previous = -1;
25
+ for (const event of packageValue.events) {
26
+ if (!event.event_id || ids.has(event.event_id)) throw new Error("Duplicate or missing exchange event ID");
27
+ if (!Number.isInteger(event.sequence) || event.sequence <= previous) throw new Error("Invalid exchange event ordering");
28
+ ids.add(event.event_id); previous = event.sequence;
29
+ }
30
+ return packageValue;
31
+ }
32
+
33
+ export function attachFindings(packageValue, findingsValue) {
34
+ const packageTrace = parseExchange(packageValue);
35
+ const findings = Array.isArray(findingsValue) ? findingsValue : findingsValue?.findings;
36
+ if (!Array.isArray(findings)) throw new Error("Findings must be an array");
37
+ const eventIds = new Set(packageTrace.events.map(event => event.event_id));
38
+ for (const finding of findings) {
39
+ if (finding.trace_id && finding.trace_id !== packageTrace.trace_id) throw new Error("Finding trace ID does not match");
40
+ for (const ref of finding.evidence_refs || finding.evidence_events || []) if (!eventIds.has(ref)) throw new Error("Finding references an unknown event");
41
+ }
42
+ return {...packageTrace, findings};
43
+ }
44
+
45
+ export function downloadJson(value, filename) {
46
+ const blob = new Blob([JSON.stringify(value, null, 2)], {type: "application/json"});
47
+ const link = document.createElement("a"); link.href = URL.createObjectURL(blob); link.download = filename; link.click();
48
+ URL.revokeObjectURL(link.href);
49
+ }