@neat.is/core 0.10.6-dev.20261007 → 0.10.6-dev.20261009

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 (46) hide show
  1. package/dist/{chunk-VL7ANDPI.js → chunk-ECBRGTB2.js} +10 -8
  2. package/dist/{chunk-VL7ANDPI.js.map → chunk-ECBRGTB2.js.map} +1 -1
  3. package/dist/{chunk-KTJK2PAH.js → chunk-H2BAPN33.js} +311 -611
  4. package/dist/chunk-H2BAPN33.js.map +1 -0
  5. package/dist/chunk-MR64ICXX.js +19 -0
  6. package/dist/chunk-MR64ICXX.js.map +1 -0
  7. package/dist/{chunk-EFBWQIKG.js → chunk-QPG2QXCW.js} +11 -27
  8. package/dist/chunk-QPG2QXCW.js.map +1 -0
  9. package/dist/chunk-RGYC5U2Q.js +511 -0
  10. package/dist/chunk-RGYC5U2Q.js.map +1 -0
  11. package/dist/{chunk-LXQCL4MP.js → chunk-TZXSWSHX.js} +2 -2
  12. package/dist/{chunk-BC53SCT7.js → chunk-VFZ6CXLI.js} +20 -6
  13. package/dist/chunk-VFZ6CXLI.js.map +1 -0
  14. package/dist/cli.cjs +409 -77
  15. package/dist/cli.cjs.map +1 -1
  16. package/dist/cli.d.cts +2 -0
  17. package/dist/cli.d.ts +2 -0
  18. package/dist/cli.js +251 -77
  19. package/dist/cli.js.map +1 -1
  20. package/dist/index.cjs +165 -17
  21. package/dist/index.cjs.map +1 -1
  22. package/dist/index.d.cts +3 -99
  23. package/dist/index.d.ts +3 -99
  24. package/dist/index.js +18 -15
  25. package/dist/neatd.cjs +165 -17
  26. package/dist/neatd.cjs.map +1 -1
  27. package/dist/neatd.js +7 -4
  28. package/dist/neatd.js.map +1 -1
  29. package/dist/otel-grpc-CCCI772O.js +11 -0
  30. package/dist/registry.cjs +570 -0
  31. package/dist/registry.cjs.map +1 -0
  32. package/dist/registry.d.cts +220 -0
  33. package/dist/registry.d.ts +220 -0
  34. package/dist/registry.js +62 -0
  35. package/dist/registry.js.map +1 -0
  36. package/dist/server.cjs +185 -23
  37. package/dist/server.cjs.map +1 -1
  38. package/dist/server.js +10 -6
  39. package/dist/server.js.map +1 -1
  40. package/package.json +8 -3
  41. package/dist/chunk-BC53SCT7.js.map +0 -1
  42. package/dist/chunk-EFBWQIKG.js.map +0 -1
  43. package/dist/chunk-KTJK2PAH.js.map +0 -1
  44. package/dist/otel-grpc-B7ABHLV7.js +0 -10
  45. /package/dist/{chunk-LXQCL4MP.js.map → chunk-TZXSWSHX.js.map} +0 -0
  46. /package/dist/{otel-grpc-B7ABHLV7.js.map → otel-grpc-CCCI772O.js.map} +0 -0
package/dist/index.cjs CHANGED
@@ -6587,7 +6587,29 @@ function ensureFrontierNode(graph, host, ts) {
6587
6587
  graph.addNode(id, node);
6588
6588
  return id;
6589
6589
  }
6590
- function upsertObservedEdge(graph, type, source, target, ts, isError = false, evidence, durationMs) {
6590
+ var EDGE_ERROR_MESSAGE_MAX = 512;
6591
+ function buildEdgeErrorExemplar(detail, ts) {
6592
+ return {
6593
+ ...detail.exceptionType !== void 0 ? { exceptionType: detail.exceptionType } : {},
6594
+ ...detail.message !== void 0 ? { message: detail.message.slice(0, EDGE_ERROR_MESSAGE_MAX) } : {},
6595
+ ...detail.httpStatusCode !== void 0 ? { httpStatusCode: detail.httpStatusCode } : {},
6596
+ at: ts
6597
+ };
6598
+ }
6599
+ function edgeErrorDetailFromSpan(span) {
6600
+ const exceptionType = span.exception?.type;
6601
+ const message = span.exception?.message;
6602
+ const httpStatusCode = httpResponseStatus(span);
6603
+ if (exceptionType === void 0 && message === void 0 && httpStatusCode === void 0) {
6604
+ return void 0;
6605
+ }
6606
+ return {
6607
+ ...exceptionType !== void 0 ? { exceptionType } : {},
6608
+ ...message !== void 0 ? { message } : {},
6609
+ ...httpStatusCode !== void 0 ? { httpStatusCode } : {}
6610
+ };
6611
+ }
6612
+ function upsertObservedEdge(graph, type, source, target, ts, isError = false, evidence, durationMs, errorDetail) {
6591
6613
  if (!graph.hasNode(source) || !graph.hasNode(target)) return null;
6592
6614
  const grain = source.startsWith("file:") || source.startsWith("symbol:") ? "file" : "service";
6593
6615
  const id = makeObservedEdgeId(type, source, target);
@@ -6597,13 +6619,15 @@ function upsertObservedEdge(graph, type, source, target, ts, isError = false, ev
6597
6619
  const newErrorCount = (existing.signal?.errorCount ?? 0) + (isError ? 1 : 0);
6598
6620
  const latencyHist2 = durationMs !== void 0 ? recordLatency({ ...existing.signal?.latencyHist ?? {} }, durationMs) : existing.signal?.latencyHist;
6599
6621
  const latencyMs2 = latencyPercentiles(latencyHist2) ?? existing.signal?.latencyMs;
6622
+ const lastError2 = isError && errorDetail ? buildEdgeErrorExemplar(errorDetail, ts) : existing.signal?.lastError;
6600
6623
  const newSignal = {
6601
6624
  spanCount: newSpanCount,
6602
6625
  errorCount: newErrorCount,
6603
6626
  lastObservedAgeMs: 0,
6604
6627
  ...latencyHist2 ? { latencyHist: latencyHist2 } : {},
6605
6628
  ...latencyMs2 ? { latencyMs: latencyMs2 } : {},
6606
- ...existing.signal?.anomalous !== void 0 ? { anomalous: existing.signal.anomalous } : {}
6629
+ ...existing.signal?.anomalous !== void 0 ? { anomalous: existing.signal.anomalous } : {},
6630
+ ...lastError2 ? { lastError: lastError2 } : {}
6607
6631
  };
6608
6632
  const updated = {
6609
6633
  ...existing,
@@ -6620,12 +6644,14 @@ function upsertObservedEdge(graph, type, source, target, ts, isError = false, ev
6620
6644
  }
6621
6645
  const latencyHist = durationMs !== void 0 ? recordLatency({}, durationMs) : void 0;
6622
6646
  const latencyMs = latencyHist ? latencyPercentiles(latencyHist) : void 0;
6647
+ const lastError = isError && errorDetail ? buildEdgeErrorExemplar(errorDetail, ts) : void 0;
6623
6648
  const signal = {
6624
6649
  spanCount: 1,
6625
6650
  errorCount: isError ? 1 : 0,
6626
6651
  lastObservedAgeMs: 0,
6627
6652
  ...latencyHist ? { latencyHist } : {},
6628
- ...latencyMs ? { latencyMs } : {}
6653
+ ...latencyMs ? { latencyMs } : {},
6654
+ ...lastError ? { lastError } : {}
6629
6655
  };
6630
6656
  const edge = {
6631
6657
  id,
@@ -6966,6 +6992,7 @@ async function handleSpan(ctx, span) {
6966
6992
  const sourceId = ensureServiceNode(ctx.graph, span.service, env);
6967
6993
  const isError = spanRecordsError(span);
6968
6994
  const durationMs = span.durationNanos > 0n && !spanIsStreaming(span) ? Number(span.durationNanos) / 1e6 : void 0;
6995
+ const errorDetail = isError ? edgeErrorDetailFromSpan(span) : void 0;
6969
6996
  const sourceServiceNode = ctx.graph.getNodeAttributes(sourceId);
6970
6997
  const callSite = callSiteFromSpan(span, sourceServiceNode, ctx.scanPath);
6971
6998
  cacheSpanService(span, nowMs, callSite);
@@ -7005,7 +7032,8 @@ async function handleSpan(ctx, span) {
7005
7032
  ts,
7006
7033
  isError,
7007
7034
  callSiteEvidence,
7008
- durationMs
7035
+ durationMs,
7036
+ errorDetail
7009
7037
  );
7010
7038
  if (result) affectedNode = targetId;
7011
7039
  if (span.dbSystem === "mongodb" && span.dbCollection) {
@@ -7018,7 +7046,8 @@ async function handleSpan(ctx, span) {
7018
7046
  ts,
7019
7047
  isError,
7020
7048
  callSiteEvidence,
7021
- durationMs
7049
+ durationMs,
7050
+ errorDetail
7022
7051
  );
7023
7052
  }
7024
7053
  if (span.dbTable) {
@@ -7031,7 +7060,8 @@ async function handleSpan(ctx, span) {
7031
7060
  ts,
7032
7061
  isError,
7033
7062
  callSiteEvidence,
7034
- durationMs
7063
+ durationMs,
7064
+ errorDetail
7035
7065
  );
7036
7066
  mergeObservedColumns(ctx.graph, tableId, span.dbColumns);
7037
7067
  }
@@ -7051,7 +7081,8 @@ async function handleSpan(ctx, span) {
7051
7081
  ts,
7052
7082
  isError,
7053
7083
  callSiteEvidence,
7054
- durationMs
7084
+ durationMs,
7085
+ errorDetail
7055
7086
  );
7056
7087
  if (result) affectedNode = targetId;
7057
7088
  } else if (span.graphqlOperationName && span.graphqlOperationType && spanServesGraphqlOperation(span.kind)) {
@@ -7069,7 +7100,8 @@ async function handleSpan(ctx, span) {
7069
7100
  ts,
7070
7101
  isError,
7071
7102
  callSiteEvidence,
7072
- durationMs
7103
+ durationMs,
7104
+ errorDetail
7073
7105
  );
7074
7106
  if (result) affectedNode = targetId;
7075
7107
  } else if (span.rpcSystem === "grpc" && span.rpcService && span.rpcMethod && spanServesGrpcMethod(span.kind)) {
@@ -7082,7 +7114,8 @@ async function handleSpan(ctx, span) {
7082
7114
  ts,
7083
7115
  isError,
7084
7116
  callSiteEvidence,
7085
- durationMs
7117
+ durationMs,
7118
+ errorDetail
7086
7119
  );
7087
7120
  if (result) affectedNode = targetId;
7088
7121
  } else if (span.websocketChannel && spanServesWebsocketChannel(span.kind)) {
@@ -7099,7 +7132,8 @@ async function handleSpan(ctx, span) {
7099
7132
  ts,
7100
7133
  isError,
7101
7134
  callSiteEvidence,
7102
- durationMs
7135
+ durationMs,
7136
+ errorDetail
7103
7137
  );
7104
7138
  if (result) affectedNode = targetId;
7105
7139
  } else {
@@ -7116,7 +7150,8 @@ async function handleSpan(ctx, span) {
7116
7150
  ts,
7117
7151
  isError,
7118
7152
  callSiteEvidence,
7119
- durationMs
7153
+ durationMs,
7154
+ errorDetail
7120
7155
  );
7121
7156
  affectedNode = targetId;
7122
7157
  resolvedViaAddress = true;
@@ -7130,7 +7165,8 @@ async function handleSpan(ctx, span) {
7130
7165
  ts,
7131
7166
  isError,
7132
7167
  callSiteEvidence,
7133
- durationMs
7168
+ durationMs,
7169
+ errorDetail
7134
7170
  );
7135
7171
  affectedNode = frontierNodeId;
7136
7172
  resolvedViaAddress = true;
@@ -7157,7 +7193,8 @@ async function handleSpan(ctx, span) {
7157
7193
  ts,
7158
7194
  isError,
7159
7195
  fallbackEvidence,
7160
- durationMs
7196
+ durationMs,
7197
+ errorDetail
7161
7198
  );
7162
7199
  }
7163
7200
  }
@@ -7172,7 +7209,7 @@ async function handleSpan(ctx, span) {
7172
7209
  );
7173
7210
  if (routeNodeId) {
7174
7211
  const routeSvc = ctx.graph.getNodeAttributes(routeNodeId).service;
7175
- upsertObservedEdge(ctx.graph, import_types8.EdgeType.CONTAINS, (0, import_types8.serviceId)(routeSvc), routeNodeId, ts, isError, void 0, durationMs);
7212
+ upsertObservedEdge(ctx.graph, import_types8.EdgeType.CONTAINS, (0, import_types8.serviceId)(routeSvc), routeNodeId, ts, isError, void 0, durationMs, errorDetail);
7176
7213
  }
7177
7214
  }
7178
7215
  if (span.statusCode === 2) {
@@ -17625,6 +17662,11 @@ function detectObservedFailingEdge(graph, bucket) {
17625
17662
  spanCount,
17626
17663
  errorCount,
17627
17664
  errorRate: clampConfidence(errorRate),
17665
+ // The bounded last-error exemplar rides the finding as evidence (ADR-236):
17666
+ // the error rate says HOW MUCH is failing, the exemplar says WHAT failed —
17667
+ // a timeout vs a deadlock vs a connection-refused, which `errorCount`
17668
+ // alone cannot name. Present only when the observed edge carries one.
17669
+ ...signal.lastError ? { lastError: signal.lastError } : {},
17628
17670
  confidence: OBSERVED_FAILING_CONFIDENCE,
17629
17671
  reason: `Code declares ${bucket.source} \u2192 ${bucket.target} (${bucket.type}) and production observes it, but ${errorCount}/${spanCount} observed calls fail (${pct}% error rate) \u2014 the declared dependency is predominantly failing. The declared intent (EXTRACTED) and the observed behaviour (OBSERVED) diverge.`,
17630
17672
  recommendation: "Treat this as a broken declared dependency, not a coverage gap: production runs the call the code declares and most calls error. Check the dependency\u2019s health, recent deploys, and the observed error responses on this edge."
@@ -17954,10 +17996,11 @@ function locusOf(graph, ev) {
17954
17996
  const rawLine = ev.attributes?.[CODE_LINENO_ATTR2];
17955
17997
  const line = typeof rawLine === "number" ? rawLine : Number(rawLine);
17956
17998
  const node = graph.hasNode(ev.affectedNode) ? graph.getNodeAttributes(ev.affectedNode) : void 0;
17999
+ const symbol = node?.type === "SymbolNode" ? node.qualname : void 0;
17957
18000
  return {
17958
18001
  file,
17959
18002
  ...Number.isFinite(line) ? { lineStart: line, lineEnd: line } : {},
17960
- ...node?.name ? { symbol: node.name } : {},
18003
+ ...symbol ? { symbol } : {},
17961
18004
  service: node?.service ?? ev.service,
17962
18005
  provenance: import_types61.Provenance.OBSERVED
17963
18006
  };
@@ -18053,7 +18096,8 @@ function buildIncidentCard(graph, errorEvent, incidents, policies) {
18053
18096
  const policyCards = applicable.map((p) => ({
18054
18097
  policyName: p.policyName,
18055
18098
  severity: p.severity,
18056
- message: p.reason
18099
+ message: p.reason,
18100
+ onViolation: p.onViolation
18057
18101
  }));
18058
18102
  const divergences = inGraph ? computeDivergences(graph, { node: affected, incidents }).divergences.map((d) => ({
18059
18103
  type: d.type,
@@ -18080,8 +18124,111 @@ function buildIncidentCard(graph, errorEvent, incidents, policies) {
18080
18124
  ...divergences.length > 0 ? { divergence: divergences } : {},
18081
18125
  headline: renderHeadline(graph, errorEvent, locus, rootCause?.node ?? null)
18082
18126
  };
18127
+ card.grade = gradeIncidentCard(card);
18083
18128
  return import_types61.IncidentCardSchema.parse(card);
18084
18129
  }
18130
+ var GRADE_PRIORS_VERSION = "sniper-architecture-priors-2026-10-08";
18131
+ var GRADE_WEIGHTS = {
18132
+ evidence: 3,
18133
+ locus: 2,
18134
+ tests: 2,
18135
+ reach: 1.5,
18136
+ kind: 1.5,
18137
+ chain: 1,
18138
+ recur: 1,
18139
+ div: 1
18140
+ };
18141
+ var PROVENANCE_WEIGHT = {
18142
+ OBSERVED: 1,
18143
+ EXTRACTED: 0.8,
18144
+ INFERRED: 0.4,
18145
+ FRONTIER: 0.3,
18146
+ STALE: 0.2
18147
+ };
18148
+ var REACH_NODES_MAX = 50;
18149
+ var TIMEOUT = /timeout|timed out|deadline/i;
18150
+ var round2 = (n) => Math.round(n * 1e4) / 1e4;
18151
+ function factor(name, value, evidence, reason) {
18152
+ return {
18153
+ value: value === null ? null : round2(value),
18154
+ weight: GRADE_WEIGHTS[name],
18155
+ evidence,
18156
+ ...reason ? { reason } : {}
18157
+ };
18158
+ }
18159
+ function gradeIncidentCard(card) {
18160
+ const rc = card.rootCause;
18161
+ const chain = rc?.chain ?? [];
18162
+ const gates = {
18163
+ policyNotBlock: {
18164
+ passed: !(card.policies ?? []).some((p) => p.onViolation === "block"),
18165
+ evidence: ["policies[].onViolation"]
18166
+ },
18167
+ notSymptomOnly: {
18168
+ passed: rc?.classification !== "symptom-only",
18169
+ evidence: ["rootCause.classification"]
18170
+ },
18171
+ locusResolves: { passed: card.locus !== null, evidence: ["locus"] }
18172
+ };
18173
+ const gamma = Object.values(gates).every((g) => g.passed) ? 1 : 0;
18174
+ const carrying = chain.some((h) => h.carriesSignal === true) ? chain.filter((h) => h.carriesSignal === true) : chain;
18175
+ const hopWeights = carrying.map((h) => PROVENANCE_WEIGHT[h.provenance]);
18176
+ const evidence = hopWeights.length === 0 ? factor("evidence", null, ["rootCause.chain[].provenance"], "no root-cause chain on the card") : hopWeights.some((w) => w === void 0) ? factor("evidence", null, ["rootCause.chain[].provenance"], "a chain hop has a provenance with no weight") : factor("evidence", Math.min(...hopWeights), ["rootCause.chain[].provenance"]);
18177
+ const locus = card.locus ? factor("locus", card.locus.symbol ? 1 : 0.6, ["locus.symbol", "locus.file"]) : factor("locus", null, ["locus"], "no locus on the card (the locus gate fails)");
18178
+ const tests = factor(
18179
+ "tests",
18180
+ null,
18181
+ [],
18182
+ "the card carries no test-file classification or test-to-symbol edges"
18183
+ );
18184
+ const reach = card.blastRadius ? factor(
18185
+ "reach",
18186
+ Math.max(0, 1 - card.blastRadius.totalAffected / REACH_NODES_MAX),
18187
+ ["blastRadius.totalAffected"],
18188
+ `nodes in the blast radius against a prior bound of ${REACH_NODES_MAX}`
18189
+ ) : factor("reach", null, ["blastRadius"], "no blast radius on the card");
18190
+ const timeout = TIMEOUT.test(`${card.exceptionType ?? ""} ${card.message}`);
18191
+ const kindValue = timeout ? 0.3 : card.incidentKind === "exception" ? 1 : card.incidentKind === "5xx" || card.incidentKind === "status-error" ? 0.7 : card.incidentKind === "connector" ? 0.6 : 0.4;
18192
+ const kind = factor("kind", kindValue, ["incidentKind", "exceptionType", "message"]);
18193
+ const chainFactor = rc ? factor(
18194
+ "chain",
18195
+ 1 / (1 + 0.25 * (Math.max(1, chain.length - 1) - 1)),
18196
+ ["rootCause.chain"]
18197
+ ) : factor("chain", null, ["rootCause"], "no root cause on the card");
18198
+ const occurrences = card.count ?? 1;
18199
+ const recurValue = Math.min(1, Math.log(1 + occurrences) / Math.log(11));
18200
+ const recur = factor(
18201
+ "recur",
18202
+ recurValue,
18203
+ ["count"],
18204
+ card.count === void 0 ? "no coalesced count; one recorded occurrence" : void 0
18205
+ );
18206
+ const div = factor("div", (card.divergence ?? []).length > 0 ? 1 : 0.7, ["divergence"]);
18207
+ const factors = { evidence, locus, tests, reach, kind, chain: chainFactor, recur, div };
18208
+ let weighted = 0;
18209
+ let total = 0;
18210
+ for (const f of Object.values(factors)) {
18211
+ if (f.value === null) continue;
18212
+ weighted += f.weight * f.value;
18213
+ total += f.weight;
18214
+ }
18215
+ const C = round2(weighted / total);
18216
+ const G = round2(gamma * C);
18217
+ const band = gamma === 0 || G < 0.5 ? "out" : G >= 0.75 ? "full" : "diagnose-only";
18218
+ return {
18219
+ G,
18220
+ gamma,
18221
+ gates,
18222
+ C,
18223
+ factors,
18224
+ band,
18225
+ urgency: {
18226
+ value: null,
18227
+ reason: "f_fresh needs the time of the last OBSERVED signal at the node, which the card does not carry"
18228
+ },
18229
+ priorsVersion: GRADE_PRIORS_VERSION
18230
+ };
18231
+ }
18085
18232
 
18086
18233
  // src/ask.ts
18087
18234
  init_cjs_shims();
@@ -20096,7 +20243,7 @@ async function computePrVerdict(req, ctx, deps, deadline) {
20096
20243
  const found = observedBreakFrom(node, getObservedDependencies(ctx.liveGraph, node.id));
20097
20244
  if (found) observedBreaks.push(found);
20098
20245
  }
20099
- const { marker, body } = renderVerdict({
20246
+ const { marker, body: rendered } = renderVerdict({
20100
20247
  graph: head,
20101
20248
  delta,
20102
20249
  changedFiles,
@@ -20104,6 +20251,7 @@ async function computePrVerdict(req, ctx, deps, deadline) {
20104
20251
  observedBreaks,
20105
20252
  tone: req.tone ?? "loud"
20106
20253
  });
20254
+ const body = rendered.startsWith(marker) ? rendered.slice(marker.length).replace(/^(?:\r?\n)+/, "") : rendered;
20107
20255
  return {
20108
20256
  marker,
20109
20257
  body,