@merittdev/horus 0.15.1 → 0.15.2

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.
Files changed (2) hide show
  1. package/dist/index.cjs +28 -4
  2. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -65880,7 +65880,7 @@ init_cjs_shims();
65880
65880
 
65881
65881
  // ../../packages/core/src/version.ts
65882
65882
  init_cjs_shims();
65883
- var HORUS_VERSION = true ? "0.15.1" : "dev";
65883
+ var HORUS_VERSION = true ? "0.15.2" : "dev";
65884
65884
  var PINNED_SOURCE_VERSION = "2.0.2";
65885
65885
 
65886
65886
  // ../../packages/core/src/evidence.ts
@@ -93610,6 +93610,19 @@ function detectFixedCadence(body2, name2) {
93610
93610
  }
93611
93611
  return null;
93612
93612
  }
93613
+ function detectExactMatchQuery(body2, name2) {
93614
+ const sql2 = /\bWHERE\b[^;]*?["'`]?\b\w+\b["'`]?\s*=\s*[$?:]\w*/i.exec(body2);
93615
+ if (sql2 && !/\b(?:LIKE|ILIKE|LOWER|UPPER|TRIM|SIMILAR|REGEXP)\b/i.test(grp(sql2, 0))) {
93616
+ const frag = grp(sql2, 0).trim().slice(0, 48);
93617
+ return { pattern: "exact-match-query", matched: frag, baseScore: 0.2, title: hedged(name2, `matches on an exact-equality query (\`${frag}\`) with no normalization, so a value differing only in formatting (case, whitespace, leading zeros) returns no rows`) };
93618
+ }
93619
+ const orm = /\.(?:find|findOne|findFirst|findUnique)\s*\(\s*\{\s*\w+\s*:/.exec(body2);
93620
+ if (orm) {
93621
+ const frag = grp(orm, 0).trim().slice(0, 40);
93622
+ return { pattern: "exact-match-query", matched: frag, baseScore: 0.2, title: hedged(name2, `looks up by an exact field match (\`${frag}\`) with no normalization, so a value differing only in formatting returns no match`) };
93623
+ }
93624
+ return null;
93625
+ }
93613
93626
  function detectInPlaceMutation(body2, ctx) {
93614
93627
  const hay = `${ctx.symbol.name} ${ctx.symbol.filePath ?? ""} ${ctx.symbol.signature ?? ""}`;
93615
93628
  const contextual = /reduc|\bslice\b|store|mutat|\bstate\b/i.test(hay) || ctx.imports.some((i3) => /redux|zustand|immer|valtio|mobx/i.test(i3));
@@ -93665,7 +93678,14 @@ function detectDataFlowCause(ctx) {
93665
93678
  if (raw.length < 40) return null;
93666
93679
  const body2 = stripComments(raw);
93667
93680
  const nm = ctx.symbol.name;
93668
- return detectFixedCadence(body2, nm) ?? detectInPlaceMutation(body2, ctx) ?? detectUnawaitedWrite(body2, ctx) ?? detectHardcodedBound(body2, nm);
93681
+ return detectFixedCadence(body2, nm) ?? detectExactMatchQuery(body2, nm) ?? detectInPlaceMutation(body2, ctx) ?? detectUnawaitedWrite(body2, ctx) ?? detectHardcodedBound(body2, nm);
93682
+ }
93683
+ function detectDataFlowCauseAcross(contexts) {
93684
+ for (const c4 of contexts) {
93685
+ const f5 = detectDataFlowCause(c4);
93686
+ if (f5) return f5;
93687
+ }
93688
+ return null;
93669
93689
  }
93670
93690
 
93671
93691
  // ../../packages/engine/src/hypotheses.ts
@@ -97794,8 +97814,12 @@ async function investigate(input, deps) {
97794
97814
  });
97795
97815
  }
97796
97816
  }
97797
- if (top && seedEv && ctx && !sourceImpactHint) {
97798
- const dataFlow = detectDataFlowCause(ctx);
97817
+ if (top && seedEv && ctx && code && !sourceImpactHint) {
97818
+ const scanIds = [
97819
+ .../* @__PURE__ */ new Set([...seeds.slice(1, 4).map((s5) => s5.id), ...(ctx.callees ?? []).slice(0, 4).map((c4) => c4.id)])
97820
+ ].filter((id) => id !== top.id);
97821
+ const extraCtxs = (await Promise.all(scanIds.map((id) => code.context(id).catch(() => null)))).filter((c4) => c4 !== null);
97822
+ const dataFlow = detectDataFlowCauseAcross([ctx, ...extraCtxs]);
97799
97823
  if (dataFlow) {
97800
97824
  causeInputs.push({
97801
97825
  id: "cause:seed-data-flow",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@merittdev/horus",
3
- "version": "0.15.1",
3
+ "version": "0.15.2",
4
4
  "description": "Local-first, source-aware production-incident investigation engine",
5
5
  "type": "module",
6
6
  "bin": {