@merittdev/horus 0.8.4 → 0.8.6
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.cjs +85 -3
- 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.8.
|
|
65883
|
+
var HORUS_VERSION = true ? "0.8.6" : "dev";
|
|
65884
65884
|
var PINNED_SOURCE_VERSION = "1.5.0";
|
|
65885
65885
|
|
|
65886
65886
|
// ../../packages/core/src/evidence.ts
|
|
@@ -92471,10 +92471,21 @@ function looksDiffable(since) {
|
|
|
92471
92471
|
function looksExplanatory(hint) {
|
|
92472
92472
|
const h3 = hint.trim();
|
|
92473
92473
|
if (h3.length === 0) return false;
|
|
92474
|
+
if (/^\s*(explain|describe|walk\s+me\s+through|tell\s+me\s+(?:about|how))\b/i.test(h3)) {
|
|
92475
|
+
return true;
|
|
92476
|
+
}
|
|
92477
|
+
if (/\b(recently\s+changed|what\s+changed|changed\s+recently|regress|regression)\b/i.test(h3)) {
|
|
92478
|
+
return false;
|
|
92479
|
+
}
|
|
92474
92480
|
if (/\b(how|what|why|when|where)\b.*\b(work|works|working|do|does|done|happen|happens|flow|flows|behave|called|invoked|triggered|used)\b/i.test(h3)) {
|
|
92475
92481
|
return true;
|
|
92476
92482
|
}
|
|
92477
|
-
if (
|
|
92483
|
+
if (/\b(fail|fails|failed|failing|failure|break|breaks|breaking|broke|broken|crash|crashes|crashing|down|slow|stuck|hang|hangs|hung|timeout|timing\s*out|wrong|exception|error|errors|leak|leaking|stopped|throwing|throws|reject|rejected|denied|not\s+work|doesn'?t\s+work|isn'?t\s+work|can'?t|cannot|caus(?:e|es|ing)|misbehav)/i.test(
|
|
92484
|
+
h3
|
|
92485
|
+
)) {
|
|
92486
|
+
return false;
|
|
92487
|
+
}
|
|
92488
|
+
if (/^\s*(how|what|why|when|where)\b/i.test(h3)) {
|
|
92478
92489
|
return true;
|
|
92479
92490
|
}
|
|
92480
92491
|
return false;
|
|
@@ -92976,6 +92987,77 @@ async function investigate(input, deps) {
|
|
|
92976
92987
|
} catch {
|
|
92977
92988
|
}
|
|
92978
92989
|
}
|
|
92990
|
+
if (top !== void 0 && typeof deps.code?.searchSymbols === "function") {
|
|
92991
|
+
const GAP_D_MAX_RESOLVE = 12;
|
|
92992
|
+
const seedScope = /* @__PURE__ */ new Set([top.id, ...(ctx?.callees ?? []).map((c4) => c4.id)]);
|
|
92993
|
+
const alreadyEmitted = new Set(seedEmittedJoins.map((j3) => j3.code));
|
|
92994
|
+
const eligible = analysis.signatures.filter(
|
|
92995
|
+
(s5) => s5.key !== "" && s5.key !== "(none)" && s5.count > 0 && !alreadyEmitted.has(s5.key)
|
|
92996
|
+
);
|
|
92997
|
+
const meaningful = meaningfulHintTokens.filter((t2) => t2.length >= 4);
|
|
92998
|
+
const hintRelevant = (s5) => meaningful.some(
|
|
92999
|
+
(t2) => s5.key.toLowerCase().includes(t2) || (s5.sampleMessage ?? "").toLowerCase().includes(t2)
|
|
93000
|
+
);
|
|
93001
|
+
const candidates = [
|
|
93002
|
+
.../* @__PURE__ */ new Set([
|
|
93003
|
+
...[...eligible].sort((a2, b5) => b5.count - a2.count).slice(0, GAP_D_MAX_RESOLVE),
|
|
93004
|
+
...eligible.filter(hintRelevant).slice(0, GAP_D_MAX_RESOLVE)
|
|
93005
|
+
])
|
|
93006
|
+
].slice(0, GAP_D_MAX_RESOLVE * 2);
|
|
93007
|
+
for (const sig of candidates) {
|
|
93008
|
+
let raiser;
|
|
93009
|
+
try {
|
|
93010
|
+
raiser = (await deps.code.searchSymbols(sig.key, 1))[0];
|
|
93011
|
+
} catch {
|
|
93012
|
+
continue;
|
|
93013
|
+
}
|
|
93014
|
+
if (raiser === void 0 || !seedScope.has(raiser.id)) continue;
|
|
93015
|
+
let evId = directEvIdByKey.get(sig.key);
|
|
93016
|
+
if (evId === void 0) {
|
|
93017
|
+
const where = raiser.id === top.id ? "the seed" : "a callee of the seed";
|
|
93018
|
+
const links = raiser.startLine !== void 0 && raiser.startLine > 0 ? { symbolId: raiser.id, file: raiser.filePath, line: raiser.startLine } : { symbolId: raiser.id, file: raiser.filePath };
|
|
93019
|
+
const ev = mkEv(
|
|
93020
|
+
"log",
|
|
93021
|
+
`event_code ${sig.key}: ${sig.count}x in Elasticsearch \u2014 raised by ${raiser.name} (${where})`.slice(
|
|
93022
|
+
0,
|
|
93023
|
+
220
|
|
93024
|
+
),
|
|
93025
|
+
{
|
|
93026
|
+
signature: sig.key,
|
|
93027
|
+
count: sig.count,
|
|
93028
|
+
firstSeen: sig.firstSeen,
|
|
93029
|
+
lastSeen: sig.lastSeen,
|
|
93030
|
+
services: sig.services,
|
|
93031
|
+
isNew: sig.isNew ?? false,
|
|
93032
|
+
ratio: sig.ratio ?? null,
|
|
93033
|
+
sampleMessage: sig.sampleMessage ?? null,
|
|
93034
|
+
relevanceClass: "direct",
|
|
93035
|
+
relevanceReason: `event_code ${sig.key} is raised by ${raiser.name} (${where})`,
|
|
93036
|
+
crossSignalJoin: true,
|
|
93037
|
+
seedEmitted: true
|
|
93038
|
+
},
|
|
93039
|
+
links,
|
|
93040
|
+
sig.lastSeen || void 0,
|
|
93041
|
+
0.9
|
|
93042
|
+
);
|
|
93043
|
+
if (sig.isNew) ev.isNew = sig.isNew;
|
|
93044
|
+
if (typeof sig.ratio === "number" && Number.isFinite(sig.ratio)) ev.ratio = sig.ratio;
|
|
93045
|
+
logEvIds.push(ev.id);
|
|
93046
|
+
directLogEvIds.push(ev.id);
|
|
93047
|
+
directSignatures.push({ key: sig.key, count: sig.count, message: sig.sampleMessage ?? "" });
|
|
93048
|
+
directEvIdByKey.set(sig.key, ev.id);
|
|
93049
|
+
evId = ev.id;
|
|
93050
|
+
}
|
|
93051
|
+
seedEmittedJoins.push({
|
|
93052
|
+
code: sig.key,
|
|
93053
|
+
count: sig.count,
|
|
93054
|
+
message: sig.sampleMessage ?? "",
|
|
93055
|
+
evId,
|
|
93056
|
+
isNew: sig.isNew ?? false,
|
|
93057
|
+
level: sig.level ?? null
|
|
93058
|
+
});
|
|
93059
|
+
}
|
|
93060
|
+
}
|
|
92979
93061
|
if (typeof deps.logs.aggregateErrors === "function") {
|
|
92980
93062
|
const sigForEntities = analysis.signatures.find(
|
|
92981
93063
|
(s5) => detectEntityFields(s5.sampleContext).length > 0
|
|
@@ -93724,7 +93806,7 @@ async function investigate(input, deps) {
|
|
|
93724
93806
|
const seedDisclaimer = seedIsLowConfidence && top ? `\u26A0 No symbol closely matched "${hint}" \u2014 "${top.name}" is a low-confidence closest match (semantic). Refine with an exact symbol or error code to target precisely. ` : "";
|
|
93725
93807
|
let summary = headlineCause ? headlineLinked ? `${seedDisclaimer}${banner2}Investigation of "${hint}" ${scope}. Top suspected cause: ${headlineCause.title}.` : `${seedDisclaimer}${banner2}Investigation of "${hint}" ${scope}. No cause is structurally linked to the seed; the strongest co-occurring signal (a lead to verify, not a diagnosis) is: ${headlineCause.title}.` : `${seedDisclaimer}${banner2}Investigation of "${hint}" ${scope}. No dominant suspected cause emerged from the available ${degradedNoSource ? "runtime" : "structural"} evidence.`;
|
|
93726
93808
|
const hasIncidentSignal = directLogEvIds.length > 0 || latencyMetricEvIds.length > 0 || queueMetricEvIds.length > 0 || dataAnomalyEvIds.length > 0 || queueFailureSignals.length > 0 || findings2.some((f5) => f5.kind === "anomaly") || headlineCause !== void 0;
|
|
93727
|
-
const explanatoryHint = looksExplanatory(hint);
|
|
93809
|
+
const explanatoryHint = looksExplanatory(hint) && input.since === void 0;
|
|
93728
93810
|
let behavioral;
|
|
93729
93811
|
if (explanatoryHint) {
|
|
93730
93812
|
let flowPool = flows;
|