@neat.is/core 0.10.6-dev.20261008 → 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.
package/dist/cli.cjs CHANGED
@@ -18365,10 +18365,11 @@ function locusOf(graph, ev) {
18365
18365
  const rawLine = ev.attributes?.[CODE_LINENO_ATTR2];
18366
18366
  const line = typeof rawLine === "number" ? rawLine : Number(rawLine);
18367
18367
  const node = graph.hasNode(ev.affectedNode) ? graph.getNodeAttributes(ev.affectedNode) : void 0;
18368
+ const symbol = node?.type === "SymbolNode" ? node.qualname : void 0;
18368
18369
  return {
18369
18370
  file,
18370
18371
  ...Number.isFinite(line) ? { lineStart: line, lineEnd: line } : {},
18371
- ...node?.name ? { symbol: node.name } : {},
18372
+ ...symbol ? { symbol } : {},
18372
18373
  service: node?.service ?? ev.service,
18373
18374
  provenance: import_types63.Provenance.OBSERVED
18374
18375
  };
@@ -18464,7 +18465,8 @@ function buildIncidentCard(graph, errorEvent, incidents, policies) {
18464
18465
  const policyCards = applicable.map((p) => ({
18465
18466
  policyName: p.policyName,
18466
18467
  severity: p.severity,
18467
- message: p.reason
18468
+ message: p.reason,
18469
+ onViolation: p.onViolation
18468
18470
  }));
18469
18471
  const divergences = inGraph ? computeDivergences(graph, { node: affected, incidents }).divergences.map((d) => ({
18470
18472
  type: d.type,
@@ -18491,8 +18493,111 @@ function buildIncidentCard(graph, errorEvent, incidents, policies) {
18491
18493
  ...divergences.length > 0 ? { divergence: divergences } : {},
18492
18494
  headline: renderHeadline(graph, errorEvent, locus, rootCause?.node ?? null)
18493
18495
  };
18496
+ card.grade = gradeIncidentCard(card);
18494
18497
  return import_types63.IncidentCardSchema.parse(card);
18495
18498
  }
18499
+ var GRADE_PRIORS_VERSION = "sniper-architecture-priors-2026-10-08";
18500
+ var GRADE_WEIGHTS = {
18501
+ evidence: 3,
18502
+ locus: 2,
18503
+ tests: 2,
18504
+ reach: 1.5,
18505
+ kind: 1.5,
18506
+ chain: 1,
18507
+ recur: 1,
18508
+ div: 1
18509
+ };
18510
+ var PROVENANCE_WEIGHT = {
18511
+ OBSERVED: 1,
18512
+ EXTRACTED: 0.8,
18513
+ INFERRED: 0.4,
18514
+ FRONTIER: 0.3,
18515
+ STALE: 0.2
18516
+ };
18517
+ var REACH_NODES_MAX = 50;
18518
+ var TIMEOUT = /timeout|timed out|deadline/i;
18519
+ var round2 = (n) => Math.round(n * 1e4) / 1e4;
18520
+ function factor(name, value, evidence, reason) {
18521
+ return {
18522
+ value: value === null ? null : round2(value),
18523
+ weight: GRADE_WEIGHTS[name],
18524
+ evidence,
18525
+ ...reason ? { reason } : {}
18526
+ };
18527
+ }
18528
+ function gradeIncidentCard(card) {
18529
+ const rc = card.rootCause;
18530
+ const chain = rc?.chain ?? [];
18531
+ const gates = {
18532
+ policyNotBlock: {
18533
+ passed: !(card.policies ?? []).some((p) => p.onViolation === "block"),
18534
+ evidence: ["policies[].onViolation"]
18535
+ },
18536
+ notSymptomOnly: {
18537
+ passed: rc?.classification !== "symptom-only",
18538
+ evidence: ["rootCause.classification"]
18539
+ },
18540
+ locusResolves: { passed: card.locus !== null, evidence: ["locus"] }
18541
+ };
18542
+ const gamma = Object.values(gates).every((g) => g.passed) ? 1 : 0;
18543
+ const carrying = chain.some((h) => h.carriesSignal === true) ? chain.filter((h) => h.carriesSignal === true) : chain;
18544
+ const hopWeights = carrying.map((h) => PROVENANCE_WEIGHT[h.provenance]);
18545
+ 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"]);
18546
+ 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)");
18547
+ const tests = factor(
18548
+ "tests",
18549
+ null,
18550
+ [],
18551
+ "the card carries no test-file classification or test-to-symbol edges"
18552
+ );
18553
+ const reach = card.blastRadius ? factor(
18554
+ "reach",
18555
+ Math.max(0, 1 - card.blastRadius.totalAffected / REACH_NODES_MAX),
18556
+ ["blastRadius.totalAffected"],
18557
+ `nodes in the blast radius against a prior bound of ${REACH_NODES_MAX}`
18558
+ ) : factor("reach", null, ["blastRadius"], "no blast radius on the card");
18559
+ const timeout = TIMEOUT.test(`${card.exceptionType ?? ""} ${card.message}`);
18560
+ 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;
18561
+ const kind = factor("kind", kindValue, ["incidentKind", "exceptionType", "message"]);
18562
+ const chainFactor = rc ? factor(
18563
+ "chain",
18564
+ 1 / (1 + 0.25 * (Math.max(1, chain.length - 1) - 1)),
18565
+ ["rootCause.chain"]
18566
+ ) : factor("chain", null, ["rootCause"], "no root cause on the card");
18567
+ const occurrences = card.count ?? 1;
18568
+ const recurValue = Math.min(1, Math.log(1 + occurrences) / Math.log(11));
18569
+ const recur = factor(
18570
+ "recur",
18571
+ recurValue,
18572
+ ["count"],
18573
+ card.count === void 0 ? "no coalesced count; one recorded occurrence" : void 0
18574
+ );
18575
+ const div = factor("div", (card.divergence ?? []).length > 0 ? 1 : 0.7, ["divergence"]);
18576
+ const factors = { evidence, locus, tests, reach, kind, chain: chainFactor, recur, div };
18577
+ let weighted = 0;
18578
+ let total = 0;
18579
+ for (const f of Object.values(factors)) {
18580
+ if (f.value === null) continue;
18581
+ weighted += f.weight * f.value;
18582
+ total += f.weight;
18583
+ }
18584
+ const C = round2(weighted / total);
18585
+ const G = round2(gamma * C);
18586
+ const band = gamma === 0 || G < 0.5 ? "out" : G >= 0.75 ? "full" : "diagnose-only";
18587
+ return {
18588
+ G,
18589
+ gamma,
18590
+ gates,
18591
+ C,
18592
+ factors,
18593
+ band,
18594
+ urgency: {
18595
+ value: null,
18596
+ reason: "f_fresh needs the time of the last OBSERVED signal at the node, which the card does not carry"
18597
+ },
18598
+ priorsVersion: GRADE_PRIORS_VERSION
18599
+ };
18600
+ }
18496
18601
 
18497
18602
  // src/ask.ts
18498
18603
  init_cjs_shims();
@@ -34587,7 +34692,8 @@ function formatIncidentLine(card) {
34587
34692
  const cls = rc.classification ? `${rc.classification} ` : "";
34588
34693
  tag = ` \xB7 ${cls}${rc.confidence.toFixed(2)}${provs ? ` [${provs}]` : ""}`;
34589
34694
  }
34590
- return `\u2716 incident [${card.incidentKind}] ${card.headline}${tag}`;
34695
+ const grade = card.grade ? ` \xB7 grade ${card.grade.G.toFixed(2)} ${card.grade.band}` : "";
34696
+ return `\u2716 incident [${card.incidentKind}] ${card.headline}${tag}${grade}`;
34591
34697
  }
34592
34698
  function incidentJson(card) {
34593
34699
  return JSON.stringify(card);