@neat.is/core 0.8.1-dev.20260816 → 0.8.1

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/neatd.js CHANGED
@@ -2,11 +2,11 @@
2
2
  import {
3
3
  reconcileDaemonRecordSync,
4
4
  startDaemon
5
- } from "./chunk-OJ6BW63H.js";
5
+ } from "./chunk-RQTW7IV3.js";
6
6
  import {
7
7
  listProjects,
8
8
  registryPath
9
- } from "./chunk-3PXRQH53.js";
9
+ } from "./chunk-ZGZYZ33B.js";
10
10
  import {
11
11
  BindAuthorityError,
12
12
  __require
package/dist/server.cjs CHANGED
@@ -4777,7 +4777,7 @@ function ensureObservedSymbolNode(graph, fileNodeId, service, relPath, fn, line)
4777
4777
  }
4778
4778
  return sid;
4779
4779
  }
4780
- function landObservedSymbol(graph, fileNodeId, service, relPath, callSite) {
4780
+ function landObservedSymbol(graph, fileNodeId, service, relPath, callSite, mint = true) {
4781
4781
  const line = callSite.line;
4782
4782
  if (line === void 0) return fileNodeId;
4783
4783
  let sawSymbol = false;
@@ -4792,7 +4792,7 @@ function landObservedSymbol(graph, fileNodeId, service, relPath, callSite) {
4792
4792
  }
4793
4793
  });
4794
4794
  if (candidates.length > 0) return pickContainingSymbol(candidates, callSite.fn);
4795
- if (sawSymbol && callSite.fn) {
4795
+ if (mint && sawSymbol && callSite.fn) {
4796
4796
  return ensureObservedSymbolNode(graph, fileNodeId, service, relPath, callSite.fn, line);
4797
4797
  }
4798
4798
  return fileNodeId;
@@ -5198,6 +5198,20 @@ function incidentAffectedNode(span, graph, scanPath) {
5198
5198
  const callSite = callSiteFromSpan(span, serviceNode, scanPath);
5199
5199
  if (callSite) {
5200
5200
  const relPath = graph ? reconcileObservedRelPath(graph, span.service, callSite.relPath) : callSite.relPath;
5201
+ const canonicalService = serviceNode && typeof serviceNode.name === "string" ? serviceNode.name : span.service;
5202
+ if (graph) {
5203
+ const fusedFileId = (0, import_types7.fileId)(canonicalService, relPath);
5204
+ if (graph.hasNode(fusedFileId)) {
5205
+ return landObservedSymbol(
5206
+ graph,
5207
+ fusedFileId,
5208
+ canonicalService,
5209
+ relPath,
5210
+ { ...callSite, relPath },
5211
+ false
5212
+ );
5213
+ }
5214
+ }
5201
5215
  return (0, import_types7.fileId)(span.service, relPath);
5202
5216
  }
5203
5217
  return sid;
@@ -5536,7 +5550,11 @@ async function handleSpan(ctx, span) {
5536
5550
  ...span.exception?.type ? { exceptionType: span.exception.type } : {},
5537
5551
  ...span.exception?.stacktrace ? { exceptionStacktrace: span.exception.stacktrace } : {},
5538
5552
  ...Object.keys(attrs).length > 0 ? { attributes: attrs } : {},
5539
- affectedNode
5553
+ // Attribute to where the failure originated — the symbol / file / service
5554
+ // the throwing span named (incidentAffectedNode, ADR-191) — the same
5555
+ // source-based attribution the durable receiver write uses, not the
5556
+ // outbound edge target this span happened to mint.
5557
+ affectedNode: incidentAffectedNode(span, ctx.graph, ctx.scanPath)
5540
5558
  };
5541
5559
  await appendErrorEvent(ctx, ev);
5542
5560
  }
@@ -6046,7 +6064,11 @@ function legacyRootCause(graph, errorNodeId, errorEvent, incidents) {
6046
6064
  }
6047
6065
  var INCIDENT_ROOT_CAUSE_CONFIDENCE = 0.6;
6048
6066
  function incidentMatchesNode(ev, nodeId) {
6049
- return ev.affectedNode === nodeId || ev.service === nodeId.replace(/^service:/, "");
6067
+ if (ev.affectedNode === nodeId) return true;
6068
+ if (ev.service === nodeId.replace(/^service:/, "")) return true;
6069
+ const sym = (0, import_types8.parseSymbolId)(ev.affectedNode);
6070
+ if (sym && (0, import_types8.fileId)(sym.service, sym.relPath) === nodeId) return true;
6071
+ return false;
6050
6072
  }
6051
6073
  function localizeFromIncidents(nodeId, incidents, errorEvent) {
6052
6074
  const pool = incidents && incidents.length > 0 ? incidents : errorEvent ? [errorEvent] : [];
@@ -6064,8 +6086,8 @@ function localizeFromIncidents(nodeId, incidents, errorEvent) {
6064
6086
  const reasonParts = [`${latest.service}: ${latest.errorMessage}`];
6065
6087
  if (location) reasonParts.push(`surfaced at ${location}`);
6066
6088
  const rootCauseReason = `${reasonParts.join(" \u2014 ")}${tail}`;
6067
- const localizesToFile = latest.affectedNode !== nodeId && latest.affectedNode.startsWith("file:");
6068
- const fileNode = localizesToFile ? latest.affectedNode : void 0;
6089
+ const localizesFiner = latest.affectedNode !== nodeId && (latest.affectedNode.startsWith("file:") || latest.affectedNode.startsWith("symbol:"));
6090
+ const fileNode = localizesFiner ? latest.affectedNode : void 0;
6069
6091
  const fixRecommendation = location ? `Inspect ${location}${route ? ` handling ${route}` : ""}` : route ? `Inspect ${latest.service}'s handler for ${route}` : void 0;
6070
6092
  return {
6071
6093
  rootCauseNode: fileNode ?? nodeId,
@@ -6550,6 +6572,22 @@ function findLoadOrigin(graph, alertNodeId, incidents, now) {
6550
6572
  }
6551
6573
  return best ? { node: best.node, ctx: best.ctx } : null;
6552
6574
  }
6575
+ var LOAD_ORIGIN_CONFIDENCE_CEILING = 0.9;
6576
+ function loadOriginConfidence(originCtx, seedCtx) {
6577
+ const cleanSplit = seedCtx.errorsFromCallers > 0 && seedCtx.errorsEmittedHere === 0;
6578
+ const partialSplit = seedCtx.errorsFromCallers > seedCtx.errorsEmittedHere;
6579
+ let evidence = 0;
6580
+ evidence += cleanSplit ? 0.45 : partialSplit ? 0.2 : 0;
6581
+ evidence += seedCtx.stale ? 0.2 : 0;
6582
+ evidence += isSaturated(seedCtx) ? 0.15 : 0;
6583
+ evidence += (volumeWeight(originCtx.outboundVolume) - 0.5) * 0.4;
6584
+ const anchor = 0.45;
6585
+ const confidence = anchor + Math.min(1, evidence) * (LOAD_ORIGIN_CONFIDENCE_CEILING - anchor);
6586
+ return Math.max(0, Math.min(LOAD_ORIGIN_CONFIDENCE_CEILING, confidence));
6587
+ }
6588
+ function displayNameOf(nodeId) {
6589
+ return nodeId.replace(/^[a-z]+:/, "");
6590
+ }
6553
6591
  function getRootCause(graph, errorNodeId, errorEvent, incidents, opts) {
6554
6592
  const legacy = legacyRootCause(graph, errorNodeId, errorEvent, incidents);
6555
6593
  if (!legacy) return null;
@@ -6564,20 +6602,20 @@ function enrichWithNavigation(graph, errorNodeId, legacy, incidents, now) {
6564
6602
  const candidates = [];
6565
6603
  if (seedCtx && isVictimSeed(seedCtx)) {
6566
6604
  const origin = findLoadOrigin(graph, errorNodeId, incidents, now);
6605
+ const staleNote = seedCtx.stale ? "; it has gone STALE under load" : "";
6606
+ const satNote = isSaturated(seedCtx) ? `; its inbound p95 ${Math.round(seedCtx.latencyP95Ms)}ms is saturated` : "";
6567
6607
  if (origin) {
6568
- const path68 = findPath(graph, errorNodeId, origin.node, "up", ROOT_CAUSE_MAX_DEPTH);
6569
- const originConfidence = confidenceFromMix(path68?.edges ?? [], now);
6608
+ const originName = displayNameOf(origin.node);
6609
+ const seedName = displayNameOf(seedNode);
6570
6610
  candidates.push({
6571
6611
  node: origin.node,
6572
6612
  classification: "primary-failure",
6573
- reason: `Highest-volume upstream source (${origin.ctx.outboundVolume} observed outbound calls) driving a saturated/stale subgraph; the alerting path decays downstream into a starved victim rather than a fault at the callee.`,
6613
+ reason: `${originName} is the root cause: it overloads the failing subgraph, and the alerting node ${seedName} is a downstream symptom, not the fault \u2014 errors reach ${seedName} from its callers (${seedCtx.errorsFromCallers}), none originate there${staleNote}${satNote}. ${originName} is the upstream source driving that load (${origin.ctx.outboundVolume} observed outbound calls).`,
6574
6614
  context: origin.ctx,
6575
- confidence: Math.max(0.3, Math.min(0.8, originConfidence || 0.5)),
6615
+ confidence: loadOriginConfidence(origin.ctx, seedCtx),
6576
6616
  provenance: import_types8.Provenance.OBSERVED
6577
6617
  });
6578
6618
  }
6579
- const staleNote = seedCtx.stale ? "; the node has gone STALE" : "";
6580
- const satNote = isSaturated(seedCtx) ? `; inbound p95 ${Math.round(seedCtx.latencyP95Ms)}ms is saturated` : "";
6581
6619
  candidates.push({
6582
6620
  node: seedNode,
6583
6621
  classification: "symptom-only",
@@ -6609,16 +6647,27 @@ function enrichWithNavigation(graph, errorNodeId, legacy, incidents, now) {
6609
6647
  edgeProvenances = [top.provenance ?? import_types8.Provenance.OBSERVED];
6610
6648
  }
6611
6649
  }
6650
+ const fixRecommendation = fixRecommendationForTop(top, seedNode, legacy);
6612
6651
  return import_types8.RootCauseResultSchema.parse({
6613
6652
  rootCauseNode: top.node,
6614
6653
  rootCauseReason: top.reason,
6615
6654
  traversalPath,
6616
6655
  edgeProvenances,
6617
6656
  confidence: top.confidence,
6618
- ...legacy.fixRecommendation ? { fixRecommendation: legacy.fixRecommendation } : {},
6657
+ ...fixRecommendation ? { fixRecommendation } : {},
6619
6658
  candidates
6620
6659
  });
6621
6660
  }
6661
+ function fixRecommendationForTop(top, seedNode, legacy) {
6662
+ if (top.classification === "primary-failure" && top.node === seedNode) {
6663
+ return legacy.fixRecommendation;
6664
+ }
6665
+ const name = top.node.replace(/^service:/, "");
6666
+ if (top.classification === "primary-failure") {
6667
+ return `Reduce or throttle the load from ${name} (or scale the saturated downstream capacity it drives) \u2014 the failure originates at this overloading source, not the starved callee.`;
6668
+ }
6669
+ return `${name} is a saturated/starved downstream victim; investigate its inbound load and upstream callers, not its own handler.`;
6670
+ }
6622
6671
 
6623
6672
  // src/divergences.ts
6624
6673
  function bucketKey(source, target, type) {