@hardkas/query 0.7.1-alpha → 0.7.4-alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -170,6 +170,7 @@ interface LineageNode {
170
170
  readonly networkId: NetworkId;
171
171
  readonly mode: string;
172
172
  readonly createdAt: string | null;
173
+ readonly workflowId?: string | undefined;
173
174
  }
174
175
  interface LineageTransition {
175
176
  readonly from: LineageNode;
package/dist/index.js CHANGED
@@ -127,7 +127,9 @@ var FilesystemQueryBackend = class {
127
127
  return { applied: 0 };
128
128
  }
129
129
  async executeRawSql(_sql) {
130
- throw new Error("Raw SQL execution not supported by Filesystem backend. Use SQLite backend.");
130
+ throw new Error(
131
+ "Raw SQL execution not supported by Filesystem backend. Use SQLite backend."
132
+ );
131
133
  }
132
134
  async scanFiles(dir) {
133
135
  const results = [];
@@ -419,7 +421,9 @@ function formatWhyBlock(block) {
419
421
  }
420
422
  if (block.evidence.length > 0) {
421
423
  lines.push("");
422
- lines.push(` Evidence Refs: ${block.evidence.map((e) => `${e.type}:${e.value.slice(0, 12)}...`).join(", ")}`);
424
+ lines.push(
425
+ ` Evidence Refs: ${block.evidence.map((e) => `${e.type}:${e.value.slice(0, 12)}...`).join(", ")}`
426
+ );
423
427
  }
424
428
  return lines.join("\n");
425
429
  }
@@ -438,7 +442,18 @@ var ArtifactQueryAdapter = class {
438
442
  return ["list", "inspect", "diff", "verify"];
439
443
  }
440
444
  supportedFilters() {
441
- return ["schema", "version", "networkId", "mode", "from.address", "to.address", "amountSompi", "status", "contentHash", "createdAt"];
445
+ return [
446
+ "schema",
447
+ "version",
448
+ "networkId",
449
+ "mode",
450
+ "from.address",
451
+ "to.address",
452
+ "amountSompi",
453
+ "status",
454
+ "contentHash",
455
+ "createdAt"
456
+ ];
442
457
  }
443
458
  async execute(request) {
444
459
  switch (request.op) {
@@ -487,12 +502,16 @@ var ArtifactQueryAdapter = class {
487
502
  const paged = sorted.slice(request.offset, request.offset + request.limit);
488
503
  let why;
489
504
  if (request.explain) {
490
- why = paged.map((item) => explainIntegrity(item, {
491
- ok: true,
492
- hashMatch: true,
493
- schemaValid: KNOWN_SCHEMAS.has(item.schema),
494
- errors: []
495
- }));
505
+ why = paged.map(
506
+ (item) => explainIntegrity(item, {
507
+ ok: true,
508
+ hashMatch: true,
509
+ schemaValid: KNOWN_SCHEMAS.has(
510
+ item.schema
511
+ ),
512
+ errors: []
513
+ })
514
+ );
496
515
  }
497
516
  return {
498
517
  domain: "artifacts",
@@ -516,7 +535,8 @@ var ArtifactQueryAdapter = class {
516
535
  async executeInspect(request) {
517
536
  const start = Date.now();
518
537
  const target = request.params["target"];
519
- if (!target) throw new Error("inspect requires params.target (content hash or file path)");
538
+ if (!target)
539
+ throw new Error("inspect requires params.target (content hash or file path)");
520
540
  const filePath = await this.resolveTarget(target);
521
541
  const raw = await this.readJsonSafe(filePath);
522
542
  if (!raw) throw new Error(`Cannot read artifact at: ${filePath}`);
@@ -550,8 +570,13 @@ var ArtifactQueryAdapter = class {
550
570
  integrity: {
551
571
  ok: integrityResult.ok && hashMatch,
552
572
  hashMatch,
553
- schemaValid: KNOWN_SCHEMAS.has(item.schema),
554
- errors: [...integrityResult.issues.map((i) => i.message), ...semanticResult.issues.map((i) => i.message)]
573
+ schemaValid: KNOWN_SCHEMAS.has(
574
+ item.schema
575
+ ),
576
+ errors: [
577
+ ...integrityResult.issues.map((i) => i.message),
578
+ ...semanticResult.issues.map((i) => i.message)
579
+ ]
555
580
  },
556
581
  economics,
557
582
  staleness,
@@ -584,7 +609,8 @@ var ArtifactQueryAdapter = class {
584
609
  const start = Date.now();
585
610
  const leftPath = request.params["left"];
586
611
  const rightPath = request.params["right"];
587
- if (!leftPath || !rightPath) throw new Error("diff requires params.left and params.right");
612
+ if (!leftPath || !rightPath)
613
+ throw new Error("diff requires params.left and params.right");
588
614
  const leftRaw = await this.readJsonSafe(leftPath);
589
615
  const rightRaw = await this.readJsonSafe(rightPath);
590
616
  if (!leftRaw) throw new Error(`Cannot read left artifact: ${leftPath}`);
@@ -653,7 +679,8 @@ var ArtifactQueryAdapter = class {
653
679
  for (const entry of entries) {
654
680
  const full = path2.join(dir, entry.name);
655
681
  if (entry.isDirectory()) {
656
- if (entry.name === "node_modules" || entry.name === ".git" || entry.name === "keystores") continue;
682
+ if (entry.name === "node_modules" || entry.name === ".git" || entry.name === "keystores")
683
+ continue;
657
684
  await this.walkDir(full, out);
658
685
  } else if (entry.name.endsWith(".json") && !entry.name.endsWith(".enc.json")) {
659
686
  out.push(full);
@@ -738,7 +765,8 @@ import { deterministicCompare } from "@hardkas/core";
738
765
  var VALID_TRANSITIONS2 = {
739
766
  "hardkas.snapshot": ["hardkas.txPlan"],
740
767
  "hardkas.txPlan": ["hardkas.signedTx"],
741
- "hardkas.signedTx": ["hardkas.txReceipt"]
768
+ "hardkas.signedTx": ["hardkas.signedTx", "hardkas.txReceipt"],
769
+ "hardkas.workflow.v1": ["hardkas.txPlan", "hardkas.signedTx", "hardkas.txReceipt"]
742
770
  };
743
771
  var LineageQueryAdapter = class {
744
772
  domain = "lineage";
@@ -771,8 +799,24 @@ var LineageQueryAdapter = class {
771
799
  // -------------------------------------------------------------------------
772
800
  async executeChain(request) {
773
801
  const start = Date.now();
774
- const anchor = request.params["anchor"];
775
- if (!anchor) throw new Error("chain requires params.anchor (contentHash or artifactId)");
802
+ let anchor = request.params["anchor"];
803
+ if (!anchor)
804
+ throw new Error("chain requires params.anchor (contentHash or artifactId)");
805
+ if (typeof anchor === "string") {
806
+ try {
807
+ const path7 = await import("path");
808
+ const fs7 = await import("fs");
809
+ const resolvedPath = path7.resolve(this.rootDir, anchor);
810
+ if (fs7.existsSync(resolvedPath) && fs7.statSync(resolvedPath).isFile()) {
811
+ const content = fs7.readFileSync(resolvedPath, "utf-8");
812
+ const json = JSON.parse(content);
813
+ if (json) {
814
+ anchor = json.lineage?.artifactId || json.artifactId || json.planId || json.signedId || json.txId || json.contentHash || anchor;
815
+ }
816
+ }
817
+ } catch (e) {
818
+ }
819
+ }
776
820
  const direction = request.params["direction"] ?? "ancestors";
777
821
  const graph = await this.buildGraph();
778
822
  const anchorNode = graph.byArtifactId.get(anchor) ?? graph.byContentHash.get(anchor);
@@ -910,30 +954,46 @@ var LineageQueryAdapter = class {
910
954
  const byContentHash = /* @__PURE__ */ new Map();
911
955
  const children = /* @__PURE__ */ new Map();
912
956
  const docs = await this.backend.findArtifacts();
957
+ const VALID_SCHEMAS = [
958
+ "hardkas.txPlan",
959
+ "hardkas.signedTx",
960
+ "hardkas.txReceipt",
961
+ "hardkas.workflow.v1",
962
+ "hardkas.snapshot"
963
+ ];
913
964
  for (const doc of docs) {
914
965
  const raw = doc.payload;
915
- if (!raw?.schema || !raw.lineage) continue;
966
+ if (!raw?.schema || !VALID_SCHEMAS.includes(raw.schema)) continue;
916
967
  const node = {
917
968
  contentHash: doc.contentHash,
918
969
  schema: doc.schema,
919
- artifactId: raw.lineage.artifactId || "",
920
- parentArtifactId: raw.lineage.parentArtifactId,
921
- rootArtifactId: raw.lineage.rootArtifactId || "",
922
- lineageId: raw.lineage.lineageId || "",
923
- sequence: raw.lineage.sequence,
970
+ artifactId: raw.lineage?.artifactId || raw.artifactId || raw.planId || raw.signedId || raw.txId || doc.contentHash || "",
971
+ parentArtifactId: raw.lineage?.parentArtifactId || raw.sourcePlanId || raw.sourceSignedId,
972
+ rootArtifactId: raw.lineage?.rootArtifactId || raw.rootArtifactId || raw.artifactId || raw.planId || raw.signedId || raw.txId || doc.contentHash || "",
973
+ lineageId: raw.lineage?.lineageId || "",
974
+ sequence: raw.lineage?.sequence,
924
975
  filePath: doc.path,
925
976
  networkId: doc.networkId,
926
977
  mode: doc.mode,
927
- createdAt: doc.createdAt || ""
978
+ createdAt: doc.createdAt || "",
979
+ workflowId: raw.schema === "hardkas.workflow.v1" ? void 0 : raw.workflowId
928
980
  };
929
981
  nodes.push(node);
930
982
  if (node.artifactId) byArtifactId.set(node.artifactId, node);
983
+ if (raw.planId) byArtifactId.set(raw.planId, node);
984
+ if (raw.signedId) byArtifactId.set(raw.signedId, node);
985
+ if (raw.txId) byArtifactId.set(raw.txId, node);
931
986
  if (node.contentHash) byContentHash.set(node.contentHash, node);
932
987
  if (node.parentArtifactId) {
933
988
  const existing = children.get(node.parentArtifactId) ?? [];
934
989
  existing.push(node);
935
990
  children.set(node.parentArtifactId, existing);
936
991
  }
992
+ if (node.workflowId) {
993
+ const existing = children.get(node.workflowId) ?? [];
994
+ existing.push(node);
995
+ children.set(node.workflowId, existing);
996
+ }
937
997
  }
938
998
  return { nodes, byArtifactId, byContentHash, children, totalFiles: docs.length };
939
999
  }
@@ -941,44 +1001,59 @@ var LineageQueryAdapter = class {
941
1001
  // Graph Traversal
942
1002
  // -------------------------------------------------------------------------
943
1003
  walkAncestors(node, graph, nodes, transitions) {
944
- const chain = [node];
945
- let current = node;
1004
+ const queue = [node];
946
1005
  const visited = /* @__PURE__ */ new Set();
947
- while (current.parentArtifactId && !visited.has(current.parentArtifactId)) {
948
- visited.add(current.parentArtifactId);
949
- const parent = graph.byArtifactId.get(current.parentArtifactId);
950
- if (!parent) break;
951
- chain.unshift(parent);
952
- const allowed = VALID_TRANSITIONS2[parent.schema] ?? [];
953
- transitions.unshift({
954
- from: parent,
955
- to: current,
956
- valid: allowed.includes(current.schema),
957
- rule: allowed.includes(current.schema) ? `${parent.schema} \u2192 ${current.schema} (valid)` : `${parent.schema} \u2192 ${current.schema} (INVALID)`
958
- });
959
- current = parent;
1006
+ const queued = /* @__PURE__ */ new Set([node.artifactId]);
1007
+ nodes.push(node);
1008
+ while (queue.length > 0) {
1009
+ const current = queue.shift();
1010
+ visited.add(current.artifactId);
1011
+ const parentIds = [];
1012
+ if (current.parentArtifactId) parentIds.push(current.parentArtifactId);
1013
+ if (current.workflowId) parentIds.push(current.workflowId);
1014
+ for (const parentId of parentIds) {
1015
+ const parent = graph.byArtifactId.get(parentId) ?? graph.byContentHash.get(parentId);
1016
+ if (!parent) continue;
1017
+ if (!queued.has(parent.artifactId)) {
1018
+ queued.add(parent.artifactId);
1019
+ nodes.unshift(parent);
1020
+ queue.push(parent);
1021
+ const allowed = VALID_TRANSITIONS2[parent.schema] ?? [];
1022
+ transitions.unshift({
1023
+ from: parent,
1024
+ to: current,
1025
+ valid: allowed.includes(current.schema),
1026
+ rule: allowed.includes(current.schema) ? `${parent.schema} \u2192 ${current.schema} (valid)` : `${parent.schema} \u2192 ${current.schema} (INVALID)`
1027
+ });
1028
+ }
1029
+ }
960
1030
  }
961
- nodes.push(...chain);
962
1031
  }
963
1032
  walkDescendants(node, graph, nodes, transitions) {
964
1033
  const queue = [node];
965
1034
  const visited = /* @__PURE__ */ new Set();
1035
+ const queued = /* @__PURE__ */ new Set([node.artifactId]);
966
1036
  nodes.push(node);
967
1037
  while (queue.length > 0) {
968
1038
  const current = queue.shift();
969
- if (visited.has(current.artifactId)) continue;
970
1039
  visited.add(current.artifactId);
971
- const kids = graph.children.get(current.artifactId) ?? [];
1040
+ const kids = [
1041
+ ...graph.children.get(current.artifactId) ?? [],
1042
+ ...current.contentHash ? graph.children.get(current.contentHash) ?? [] : []
1043
+ ];
972
1044
  for (const child of kids) {
973
- nodes.push(child);
974
- queue.push(child);
975
- const allowed = VALID_TRANSITIONS2[current.schema] ?? [];
976
- transitions.push({
977
- from: current,
978
- to: child,
979
- valid: allowed.includes(child.schema),
980
- rule: allowed.includes(child.schema) ? `${current.schema} \u2192 ${child.schema} (valid)` : `${current.schema} \u2192 ${child.schema} (INVALID)`
981
- });
1045
+ if (!queued.has(child.artifactId)) {
1046
+ queued.add(child.artifactId);
1047
+ nodes.push(child);
1048
+ queue.push(child);
1049
+ const allowed = VALID_TRANSITIONS2[current.schema] ?? [];
1050
+ transitions.push({
1051
+ from: current,
1052
+ to: child,
1053
+ valid: allowed.includes(child.schema),
1054
+ rule: allowed.includes(child.schema) ? `${current.schema} \u2192 ${child.schema} (valid)` : `${current.schema} \u2192 ${child.schema} (INVALID)`
1055
+ });
1056
+ }
982
1057
  }
983
1058
  }
984
1059
  }
@@ -1000,7 +1075,8 @@ var LineageQueryAdapter = class {
1000
1075
  for (const entry of entries) {
1001
1076
  const full = path3.join(dir, entry.name);
1002
1077
  if (entry.isDirectory()) {
1003
- if (entry.name === "node_modules" || entry.name === ".git" || entry.name === "keystores") continue;
1078
+ if (entry.name === "node_modules" || entry.name === ".git" || entry.name === "keystores")
1079
+ continue;
1004
1080
  await this.walkDir(full, out);
1005
1081
  } else if (entry.name.endsWith(".json") && !entry.name.endsWith(".enc.json")) {
1006
1082
  out.push(full);
@@ -1033,7 +1109,15 @@ var ReplayQueryAdapter = class {
1033
1109
  return ["list", "summary", "divergences", "invariants"];
1034
1110
  }
1035
1111
  supportedFilters() {
1036
- return ["txId", "status", "networkId", "mode", "daaScore", "from.address", "to.address"];
1112
+ return [
1113
+ "txId",
1114
+ "status",
1115
+ "networkId",
1116
+ "mode",
1117
+ "daaScore",
1118
+ "from.address",
1119
+ "to.address"
1120
+ ];
1037
1121
  }
1038
1122
  async execute(request) {
1039
1123
  switch (request.op) {
@@ -1096,7 +1180,8 @@ var ReplayQueryAdapter = class {
1096
1180
  const txId = request.params["txId"];
1097
1181
  if (!txId) throw new Error("summary requires params.txId");
1098
1182
  const receipt = await this.backend.getArtifact(txId);
1099
- if (!receipt || receipt.schema !== "hardkas.txReceipt") throw new Error(`Receipt not found for txId: ${txId}`);
1183
+ if (!receipt || receipt.schema !== "hardkas.txReceipt")
1184
+ throw new Error(`Receipt not found for txId: ${txId}`);
1100
1185
  const traces = await this.backend.findTraces({ txId });
1101
1186
  const trace = traces[0];
1102
1187
  const item = toSummary(receipt.payload, trace?.payload);
@@ -1209,7 +1294,8 @@ var ReplayQueryAdapter = class {
1209
1294
  const txId = request.params["txId"];
1210
1295
  if (!txId) throw new Error("invariants requires params.txId");
1211
1296
  const doc = await this.backend.getArtifact(txId);
1212
- if (!doc || doc.schema !== "hardkas.txReceipt") throw new Error(`Receipt not found for txId: ${txId}`);
1297
+ if (!doc || doc.schema !== "hardkas.txReceipt")
1298
+ throw new Error(`Receipt not found for txId: ${txId}`);
1213
1299
  const receipt = doc.payload;
1214
1300
  const issues = [];
1215
1301
  const planIntegrity = receipt.contentHash ? computeContentHashSafe(receipt) === receipt.contentHash : true;
@@ -1342,10 +1428,30 @@ function explainDivergence(d) {
1342
1428
  function explainInvariants(result) {
1343
1429
  const causalChain = [];
1344
1430
  let order = 1;
1345
- causalChain.push({ order: order++, assertion: result.planIntegrity ? "Plan integrity is OK" : "Plan integrity FAILED", evidence: `planIntegrity=${result.planIntegrity}`, rule: "SHA-256 canonical consistency" });
1346
- causalChain.push({ order: order++, assertion: result.receiptReproducible ? "Receipt is reproducible" : "Receipt is NOT reproducible", evidence: `receiptReproducible=${result.receiptReproducible}`, rule: "Replay evidence requirements" });
1347
- causalChain.push({ order: order++, assertion: result.stateTransitionValid ? "State transition is valid" : "State transition INVALID", evidence: `stateTransitionValid=${result.stateTransitionValid}`, rule: "Status/State alignment" });
1348
- causalChain.push({ order: order++, assertion: result.utxoConservation ? "UTXO conservation holds" : "UTXO conservation VIOLATED", evidence: `utxoConservation=${result.utxoConservation}`, rule: "Value conservation policy" });
1431
+ causalChain.push({
1432
+ order: order++,
1433
+ assertion: result.planIntegrity ? "Plan integrity is OK" : "Plan integrity FAILED",
1434
+ evidence: `planIntegrity=${result.planIntegrity}`,
1435
+ rule: "SHA-256 canonical consistency"
1436
+ });
1437
+ causalChain.push({
1438
+ order: order++,
1439
+ assertion: result.receiptReproducible ? "Receipt is reproducible" : "Receipt is NOT reproducible",
1440
+ evidence: `receiptReproducible=${result.receiptReproducible}`,
1441
+ rule: "Replay evidence requirements"
1442
+ });
1443
+ causalChain.push({
1444
+ order: order++,
1445
+ assertion: result.stateTransitionValid ? "State transition is valid" : "State transition INVALID",
1446
+ evidence: `stateTransitionValid=${result.stateTransitionValid}`,
1447
+ rule: "Status/State alignment"
1448
+ });
1449
+ causalChain.push({
1450
+ order: order++,
1451
+ assertion: result.utxoConservation ? "UTXO conservation holds" : "UTXO conservation VIOLATED",
1452
+ evidence: `utxoConservation=${result.utxoConservation}`,
1453
+ rule: "Value conservation policy"
1454
+ });
1349
1455
  const allOk = result.planIntegrity && result.receiptReproducible && result.stateTransitionValid && result.utxoConservation;
1350
1456
  return {
1351
1457
  question: `Are replay invariants satisfied for tx ${result.txId.slice(0, 16)}...?`,
@@ -1420,7 +1526,10 @@ var DagQueryAdapter = class {
1420
1526
  deterministic: true,
1421
1527
  queryHash: computeQueryHash(paged),
1422
1528
  why,
1423
- annotations: { executedAt: (/* @__PURE__ */ new Date()).toISOString(), executionMs: Date.now() - start }
1529
+ annotations: {
1530
+ executedAt: (/* @__PURE__ */ new Date()).toISOString(),
1531
+ executionMs: Date.now() - start
1532
+ }
1424
1533
  };
1425
1534
  }
1426
1535
  // -------------------------------------------------------------------------
@@ -1456,7 +1565,10 @@ var DagQueryAdapter = class {
1456
1565
  deterministic: true,
1457
1566
  queryHash: computeQueryHash(paged),
1458
1567
  why,
1459
- annotations: { executedAt: (/* @__PURE__ */ new Date()).toISOString(), executionMs: Date.now() - start }
1568
+ annotations: {
1569
+ executedAt: (/* @__PURE__ */ new Date()).toISOString(),
1570
+ executionMs: Date.now() - start
1571
+ }
1460
1572
  };
1461
1573
  }
1462
1574
  // -------------------------------------------------------------------------
@@ -1508,7 +1620,10 @@ var DagQueryAdapter = class {
1508
1620
  deterministic: true,
1509
1621
  queryHash: computeQueryHash(entries),
1510
1622
  why,
1511
- annotations: { executedAt: (/* @__PURE__ */ new Date()).toISOString(), executionMs: Date.now() - start }
1623
+ annotations: {
1624
+ executedAt: (/* @__PURE__ */ new Date()).toISOString(),
1625
+ executionMs: Date.now() - start
1626
+ }
1512
1627
  };
1513
1628
  }
1514
1629
  // -------------------------------------------------------------------------
@@ -1542,7 +1657,10 @@ var DagQueryAdapter = class {
1542
1657
  truncated: false,
1543
1658
  deterministic: true,
1544
1659
  queryHash: computeQueryHash([result]),
1545
- annotations: { executedAt: (/* @__PURE__ */ new Date()).toISOString(), executionMs: Date.now() - start }
1660
+ annotations: {
1661
+ executedAt: (/* @__PURE__ */ new Date()).toISOString(),
1662
+ executionMs: Date.now() - start
1663
+ }
1546
1664
  };
1547
1665
  }
1548
1666
  // -------------------------------------------------------------------------
@@ -1608,7 +1726,10 @@ var DagQueryAdapter = class {
1608
1726
  deterministic: true,
1609
1727
  queryHash: computeQueryHash(paged),
1610
1728
  why,
1611
- annotations: { executedAt: (/* @__PURE__ */ new Date()).toISOString(), executionMs: Date.now() - start }
1729
+ annotations: {
1730
+ executedAt: (/* @__PURE__ */ new Date()).toISOString(),
1731
+ executionMs: Date.now() - start
1732
+ }
1612
1733
  };
1613
1734
  }
1614
1735
  // -------------------------------------------------------------------------
@@ -1683,7 +1804,12 @@ function explainDisplacement(d, _dag) {
1683
1804
  answer: d.reason,
1684
1805
  evidence: [{ type: "txId", value: d.txId }],
1685
1806
  causalChain: [
1686
- { order: 1, assertion: "Tx in displaced set", evidence: "dag.displacedTxIds includes txId", rule: "DAG reorganization" },
1807
+ {
1808
+ order: 1,
1809
+ assertion: "Tx in displaced set",
1810
+ evidence: "dag.displacedTxIds includes txId",
1811
+ rule: "DAG reorganization"
1812
+ },
1687
1813
  { order: 2, assertion: "Status: displaced", evidence: d.reason }
1688
1814
  ],
1689
1815
  model: "deterministic-light-model",
@@ -1700,8 +1826,16 @@ function explainTxHistory(entry, _dag) {
1700
1826
  { type: "blockId", value: entry.blockId }
1701
1827
  ],
1702
1828
  causalChain: [
1703
- { order: 1, assertion: `In block ${entry.blockId}`, evidence: `daaScore=${entry.daaScore}` },
1704
- { order: 2, assertion: entry.inSinkPath ? "In selected sink path" : "Not in sink path", evidence: `selectedPathToSink.includes("${entry.blockId}")` }
1829
+ {
1830
+ order: 1,
1831
+ assertion: `In block ${entry.blockId}`,
1832
+ evidence: `daaScore=${entry.daaScore}`
1833
+ },
1834
+ {
1835
+ order: 2,
1836
+ assertion: entry.inSinkPath ? "In selected sink path" : "Not in sink path",
1837
+ evidence: `selectedPathToSink.includes("${entry.blockId}")`
1838
+ }
1705
1839
  ],
1706
1840
  model: "deterministic-light-model",
1707
1841
  confidence: "definitive"
@@ -1716,7 +1850,12 @@ function explainAnomaly(a, _dag) {
1716
1850
  answer: a.description,
1717
1851
  evidence,
1718
1852
  causalChain: [
1719
- { order: 1, assertion: a.description, evidence: `Anomaly: ${a.kind}`, rule: "DAG invariant check" }
1853
+ {
1854
+ order: 1,
1855
+ assertion: a.description,
1856
+ evidence: `Anomaly: ${a.kind}`,
1857
+ rule: "DAG invariant check"
1858
+ }
1720
1859
  ],
1721
1860
  model: "deterministic-light-model",
1722
1861
  confidence: "definitive"
@@ -1784,18 +1923,32 @@ var EventsQueryAdapter = class {
1784
1923
  executionMs: Date.now() - start,
1785
1924
  filesScanned: backendUsed === "sqlite" ? 0 : 1
1786
1925
  },
1787
- why: request.explain ? [{
1788
- question: "How were events loaded and linked?",
1789
- answer: `Loaded ${total} events matching filters. Causal links (correlation/causation) available in payload.`,
1790
- evidence: [],
1791
- causalChain: [
1792
- { order: 1, assertion: `Source: ${backendUsed}`, evidence: "Event stream processed" },
1793
- { order: 2, assertion: `Filters: ${effectiveFilters.length} applied`, evidence: effectiveFilters.map((f) => `${f.field} ${f.op} ${f.value}`).join(", ") || "none" },
1794
- { order: 3, assertion: "Ordering: timestamp ASC", evidence: "Deterministic stream sorting" }
1795
- ],
1796
- model: "events-causality",
1797
- confidence: "definitive"
1798
- }] : void 0
1926
+ why: request.explain ? [
1927
+ {
1928
+ question: "How were events loaded and linked?",
1929
+ answer: `Loaded ${total} events matching filters. Causal links (correlation/causation) available in payload.`,
1930
+ evidence: [],
1931
+ causalChain: [
1932
+ {
1933
+ order: 1,
1934
+ assertion: `Source: ${backendUsed}`,
1935
+ evidence: "Event stream processed"
1936
+ },
1937
+ {
1938
+ order: 2,
1939
+ assertion: `Filters: ${effectiveFilters.length} applied`,
1940
+ evidence: effectiveFilters.map((f) => `${f.field} ${f.op} ${f.value}`).join(", ") || "none"
1941
+ },
1942
+ {
1943
+ order: 3,
1944
+ assertion: "Ordering: timestamp ASC",
1945
+ evidence: "Deterministic stream sorting"
1946
+ }
1947
+ ],
1948
+ model: "events-causality",
1949
+ confidence: "definitive"
1950
+ }
1951
+ ] : void 0
1799
1952
  };
1800
1953
  }
1801
1954
  async loadEvents() {
@@ -1856,29 +2009,46 @@ var TxQueryAdapter = class {
1856
2009
  const roles = new Set(artifacts.map((a) => a.role));
1857
2010
  if (!roles.has("plan")) warnings.push("Missing tx plan artifact");
1858
2011
  if (!roles.has("signed")) warnings.push("Missing signed tx artifact");
1859
- if (!roles.has("receipt")) warnings.push("Missing tx receipt artifact (may not exist yet)");
2012
+ if (!roles.has("receipt"))
2013
+ warnings.push("Missing tx receipt artifact (may not exist yet)");
1860
2014
  const complete = roles.has("plan") && roles.has("signed");
1861
2015
  const result = {
1862
2016
  txId,
1863
2017
  artifacts,
1864
- events: events.sort((a, b) => deterministicCompare5(a.timestamp, b.timestamp) || deterministicCompare5(a.eventId, b.eventId)),
2018
+ events: events.sort(
2019
+ (a, b) => deterministicCompare5(a.timestamp, b.timestamp) || deterministicCompare5(a.eventId, b.eventId)
2020
+ ),
1865
2021
  warnings,
1866
2022
  complete
1867
2023
  };
1868
2024
  let why;
1869
2025
  if (request.explain) {
1870
- why = [{
1871
- question: `Causal aggregation for transaction ${txId}?`,
1872
- answer: complete ? `Found ${artifacts.length} artifact(s) and ${events.length} event(s). Workflow is consistent.` : `Aggregation incomplete: ${warnings.join(". ")}.`,
1873
- evidence: [{ type: "txId", value: txId }],
1874
- causalChain: [
1875
- { order: 1, assertion: `Artifacts linked: ${artifacts.length}`, evidence: artifacts.map((a) => a.role).join(", ") },
1876
- { order: 2, assertion: `Events linked: ${events.length}`, evidence: "Events found in stream" },
1877
- { order: 3, assertion: `Completeness check: ${complete}`, evidence: warnings.join("; ") || "all required roles found" }
1878
- ],
1879
- model: "tx-causality",
1880
- confidence: "definitive"
1881
- }];
2026
+ why = [
2027
+ {
2028
+ question: `Causal aggregation for transaction ${txId}?`,
2029
+ answer: complete ? `Found ${artifacts.length} artifact(s) and ${events.length} event(s). Workflow is consistent.` : `Aggregation incomplete: ${warnings.join(". ")}.`,
2030
+ evidence: [{ type: "txId", value: txId }],
2031
+ causalChain: [
2032
+ {
2033
+ order: 1,
2034
+ assertion: `Artifacts linked: ${artifacts.length}`,
2035
+ evidence: artifacts.map((a) => a.role).join(", ")
2036
+ },
2037
+ {
2038
+ order: 2,
2039
+ assertion: `Events linked: ${events.length}`,
2040
+ evidence: "Events found in stream"
2041
+ },
2042
+ {
2043
+ order: 3,
2044
+ assertion: `Completeness check: ${complete}`,
2045
+ evidence: warnings.join("; ") || "all required roles found"
2046
+ }
2047
+ ],
2048
+ model: "tx-causality",
2049
+ confidence: "definitive"
2050
+ }
2051
+ ];
1882
2052
  }
1883
2053
  return {
1884
2054
  domain: "tx",
@@ -1949,18 +2119,21 @@ var QueryEngine = class _QueryEngine {
1949
2119
  const { HardkasStore, SqliteQueryBackend, HardkasIndexer } = await import("@hardkas/query-store");
1950
2120
  const store = new HardkasStore({ dbPath });
1951
2121
  if (options.autoSync) {
1952
- await withLock({
1953
- rootDir: options.artifactDir,
1954
- name: "query-store",
1955
- command: "query-engine-auto-sync",
1956
- wait: options.waitLock ?? false,
1957
- timeoutMs: 5e3
1958
- // Short timeout for auto-sync
1959
- }, async () => {
1960
- store.connect({ autoMigrate: true });
1961
- const indexer = new HardkasIndexer(store.getDatabase());
1962
- await indexer.sync();
1963
- });
2122
+ await withLock(
2123
+ {
2124
+ rootDir: options.artifactDir,
2125
+ name: "query-store",
2126
+ command: "query-engine-auto-sync",
2127
+ wait: options.waitLock ?? false,
2128
+ timeoutMs: 5e3
2129
+ // Short timeout for auto-sync
2130
+ },
2131
+ async () => {
2132
+ store.connect({ autoMigrate: true });
2133
+ const indexer = new HardkasIndexer(store.getDatabase());
2134
+ await indexer.sync();
2135
+ }
2136
+ );
1964
2137
  } else {
1965
2138
  store.connect();
1966
2139
  }
@@ -1980,11 +2153,23 @@ var QueryEngine = class _QueryEngine {
1980
2153
  constructor(options) {
1981
2154
  this.backend = options.backend || new FilesystemQueryBackend(options.artifactDir);
1982
2155
  this.adapters = /* @__PURE__ */ new Map();
1983
- this.adapters.set("artifacts", new ArtifactQueryAdapter(options.artifactDir, this.backend));
1984
- this.adapters.set("lineage", new LineageQueryAdapter(options.artifactDir, this.backend));
1985
- this.adapters.set("replay", new ReplayQueryAdapter(options.artifactDir, this.backend));
2156
+ this.adapters.set(
2157
+ "artifacts",
2158
+ new ArtifactQueryAdapter(options.artifactDir, this.backend)
2159
+ );
2160
+ this.adapters.set(
2161
+ "lineage",
2162
+ new LineageQueryAdapter(options.artifactDir, this.backend)
2163
+ );
2164
+ this.adapters.set(
2165
+ "replay",
2166
+ new ReplayQueryAdapter(options.artifactDir, this.backend)
2167
+ );
1986
2168
  this.adapters.set("dag", new DagQueryAdapter(options.artifactDir, this.backend));
1987
- this.adapters.set("events", new EventsQueryAdapter(options.artifactDir, this.backend));
2169
+ this.adapters.set(
2170
+ "events",
2171
+ new EventsQueryAdapter(options.artifactDir, this.backend)
2172
+ );
1988
2173
  this.adapters.set("tx", new TxQueryAdapter(options.artifactDir, this.backend));
1989
2174
  }
1990
2175
  /**
@@ -2013,7 +2198,9 @@ var QueryEngine = class _QueryEngine {
2013
2198
  rowsRead: result.items.length,
2014
2199
  scannedFiles: result.annotations.filesScanned || 0,
2015
2200
  freshness,
2016
- warnings: freshness === "stale" ? ["Index is STALE. mtime mismatch detected. Run 'hardkas query store rebuild'."] : []
2201
+ warnings: freshness === "stale" ? [
2202
+ "Index is STALE. mtime mismatch detected. Run 'hardkas query store rebuild'."
2203
+ ] : []
2017
2204
  };
2018
2205
  }
2019
2206
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hardkas/query",
3
- "version": "0.7.1-alpha",
3
+ "version": "0.7.4-alpha",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -14,9 +14,9 @@
14
14
  ],
15
15
  "dependencies": {
16
16
  "picocolors": "^1.1.1",
17
- "@hardkas/core": "0.7.1-alpha",
18
- "@hardkas/artifacts": "0.7.1-alpha",
19
- "@hardkas/query-store": "0.7.1-alpha"
17
+ "@hardkas/core": "0.7.4-alpha",
18
+ "@hardkas/query-store": "0.7.4-alpha",
19
+ "@hardkas/artifacts": "0.7.4-alpha"
20
20
  },
21
21
  "devDependencies": {
22
22
  "tsup": "^8.3.5",