@neat.is/core 0.9.12 → 0.9.13
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/{chunk-WE3AFQYL.js → chunk-BKSM2YLV.js} +35 -4
- package/dist/{chunk-WE3AFQYL.js.map → chunk-BKSM2YLV.js.map} +1 -1
- package/dist/{chunk-RBZNXA5L.js → chunk-RL6H3VVD.js} +56 -2
- package/dist/chunk-RL6H3VVD.js.map +1 -0
- package/dist/cli.cjs +538 -29
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +18 -2
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +87 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +2 -2
- package/dist/neatd.cjs +87 -3
- package/dist/neatd.cjs.map +1 -1
- package/dist/neatd.js +2 -2
- package/dist/server.cjs +55 -1
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-RBZNXA5L.js.map +0 -1
package/dist/neatd.js
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
import {
|
|
3
3
|
reconcileDaemonRecordSync,
|
|
4
4
|
startDaemon
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-BKSM2YLV.js";
|
|
6
6
|
import {
|
|
7
7
|
listProjects,
|
|
8
8
|
registryPath
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-RL6H3VVD.js";
|
|
10
10
|
import {
|
|
11
11
|
BindAuthorityError,
|
|
12
12
|
__require
|
package/dist/server.cjs
CHANGED
|
@@ -5428,6 +5428,14 @@ function mergeColumnsAt(graph, tableNodeId, columns, provenance, confidence) {
|
|
|
5428
5428
|
function mergeObservedColumns(graph, tableNodeId, columns) {
|
|
5429
5429
|
mergeColumnsAt(graph, tableNodeId, columns, import_types7.Provenance.OBSERVED, OBSERVED_COLUMN_CONFIDENCE);
|
|
5430
5430
|
}
|
|
5431
|
+
function mergeObservedDeployState(graph, serviceNodeId, state) {
|
|
5432
|
+
if (!graph.hasNode(serviceNodeId)) return;
|
|
5433
|
+
const attrs = {};
|
|
5434
|
+
if (typeof state.image === "string" && state.image.length > 0) attrs["observedImage"] = state.image;
|
|
5435
|
+
if (typeof state.readyReplicas === "number") attrs["observedReadyReplicas"] = state.readyReplicas;
|
|
5436
|
+
if (Object.keys(attrs).length === 0) return;
|
|
5437
|
+
graph.mergeNodeAttributes(serviceNodeId, attrs);
|
|
5438
|
+
}
|
|
5431
5439
|
function ensureDatabaseNode(graph, host, engine) {
|
|
5432
5440
|
const id = (0, import_types7.databaseId)(host);
|
|
5433
5441
|
if (graph.hasNode(id)) return id;
|
|
@@ -7044,6 +7052,11 @@ function isSaturated(ctx) {
|
|
|
7044
7052
|
function isBoundaryTimeoutSymptom(ctx) {
|
|
7045
7053
|
return ctx.errorsEmittedHere > 0 && ctx.boundaryTimeout === true && ctx.errorsFromCallers === 0 && ctx.hasOutboundDeps === true && ctx.observedErroringDownstream !== true;
|
|
7046
7054
|
}
|
|
7055
|
+
var UNREACHABLE_INBOUND_ERROR_RATE = 0.5;
|
|
7056
|
+
var UNREACHABLE_MIN_INBOUND = 3;
|
|
7057
|
+
function isUnreachableSeed(ctx) {
|
|
7058
|
+
return ctx.callCount >= UNREACHABLE_MIN_INBOUND && ctx.errorsFromCallers > 0 && ctx.errorsFromCallers >= UNREACHABLE_INBOUND_ERROR_RATE * ctx.callCount && ctx.errorsEmittedHere === 0 && ctx.outboundVolume === 0;
|
|
7059
|
+
}
|
|
7047
7060
|
function classifyNode(ctx) {
|
|
7048
7061
|
if (ctx.errorsEmittedHere > 0) {
|
|
7049
7062
|
if ((ctx.stale || isSaturated(ctx)) && ctx.errorsFromCallers >= ctx.errorsEmittedHere) {
|
|
@@ -7052,6 +7065,7 @@ function classifyNode(ctx) {
|
|
|
7052
7065
|
if (isBoundaryTimeoutSymptom(ctx)) return "symptom-only";
|
|
7053
7066
|
return "primary-failure";
|
|
7054
7067
|
}
|
|
7068
|
+
if (isUnreachableSeed(ctx)) return "unreachable";
|
|
7055
7069
|
if (ctx.errorsFromCallers > 0) return "symptom-only";
|
|
7056
7070
|
return "unrelated";
|
|
7057
7071
|
}
|
|
@@ -7338,6 +7352,16 @@ function enrichWithNavigation(graph, errorNodeId, tagged, incidents, now) {
|
|
|
7338
7352
|
confidence: Math.min(legacy.confidence, 0.4),
|
|
7339
7353
|
...lastProv ? { provenance: lastProv } : {}
|
|
7340
7354
|
});
|
|
7355
|
+
} else if (seedCtx && isUnreachableSeed(seedCtx)) {
|
|
7356
|
+
const name = displayNameOf(seedNode);
|
|
7357
|
+
candidates.push({
|
|
7358
|
+
node: seedNode,
|
|
7359
|
+
classification: "unreachable",
|
|
7360
|
+
reason: `${name} is unreachable: its callers' requests fail (${seedCtx.errorsFromCallers} erroring inbound calls) and it produced no telemetry of its own \u2014 no server spans, no outbound calls \u2014 so it never served. The failure is observed, but its cause is not in the trace: a startup failure, a crash before the first span, or an unschedulable / unhealthy pod. Inspect ${name}'s deploy state and logs \u2014 there is no code fault to find in the graph here.`,
|
|
7361
|
+
context: seedCtx,
|
|
7362
|
+
confidence: legacy.confidence,
|
|
7363
|
+
provenance: import_types8.Provenance.OBSERVED
|
|
7364
|
+
});
|
|
7341
7365
|
} else if (seedCtx && isBoundaryTimeoutSymptom(seedCtx)) {
|
|
7342
7366
|
const pointer = structuralUpstreamPointer(graph, seedNode, incidents);
|
|
7343
7367
|
const seedName = displayNameOf(seedNode);
|
|
@@ -7687,6 +7711,25 @@ function detectColumnDrift(node) {
|
|
|
7687
7711
|
}
|
|
7688
7712
|
return out;
|
|
7689
7713
|
}
|
|
7714
|
+
var RECOMMENDATION_DEPLOY_IMAGE_MISMATCH = "The running image differs from the manifest-declared image \u2014 the rollout has not taken (the old ReplicaSet is still serving). Re-apply the deployment or investigate why the new image failed to roll out.";
|
|
7715
|
+
var DEPLOY_DIVERGENCE_CONFIDENCE = 0.9;
|
|
7716
|
+
function detectDeployDivergence(svc) {
|
|
7717
|
+
const out = [];
|
|
7718
|
+
if (typeof svc.declaredImage === "string" && typeof svc.observedImage === "string" && svc.declaredImage !== svc.observedImage) {
|
|
7719
|
+
out.push({
|
|
7720
|
+
type: "deploy-mismatch",
|
|
7721
|
+
kind: "image",
|
|
7722
|
+
source: svc.id,
|
|
7723
|
+
target: svc.id,
|
|
7724
|
+
declaredImage: svc.declaredImage,
|
|
7725
|
+
observedImage: svc.observedImage,
|
|
7726
|
+
confidence: DEPLOY_DIVERGENCE_CONFIDENCE,
|
|
7727
|
+
reason: `Service ${svc.name} declares image ${svc.declaredImage} but its running pods report ${svc.observedImage} \u2014 the deploy has not taken (the old version is still serving), so no incident fires.`,
|
|
7728
|
+
recommendation: RECOMMENDATION_DEPLOY_IMAGE_MISMATCH
|
|
7729
|
+
});
|
|
7730
|
+
}
|
|
7731
|
+
return out;
|
|
7732
|
+
}
|
|
7690
7733
|
var SYMBOL_MISMATCH_PATTERNS = [
|
|
7691
7734
|
{
|
|
7692
7735
|
// "'ListProductsResponse' object has no attribute 'products_list'" and kin.
|
|
@@ -8014,6 +8057,7 @@ function computeDivergences(graph, opts = {}) {
|
|
|
8014
8057
|
const svc = n;
|
|
8015
8058
|
for (const d of detectHostMismatch(graph, nodeId, svc)) all.push(d);
|
|
8016
8059
|
for (const d of detectCompatDivergences(graph, nodeId, svc)) all.push(d);
|
|
8060
|
+
for (const d of detectDeployDivergence(svc)) all.push(d);
|
|
8017
8061
|
return;
|
|
8018
8062
|
}
|
|
8019
8063
|
if (n.type === import_types9.NodeType.InfraNode && n.kind === "sql-table") {
|
|
@@ -8054,7 +8098,12 @@ function computeDivergences(graph, opts = {}) {
|
|
|
8054
8098
|
// orders last so at equal confidence the structural and symbol divergences
|
|
8055
8099
|
// lead, per the contract ("rank below the definitive structural and symbol
|
|
8056
8100
|
// divergences").
|
|
8057
|
-
"observed-failing": 6
|
|
8101
|
+
"observed-failing": 6,
|
|
8102
|
+
// Deploy mismatch (ADR-225) is a definitive structural declared-vs-observed
|
|
8103
|
+
// divergence carrying high confidence (0.9), so the confidence sort already
|
|
8104
|
+
// places it among the structural leaders; this slot only breaks an exact
|
|
8105
|
+
// confidence tie and sits last as a stable tiebreaker.
|
|
8106
|
+
"deploy-mismatch": 7
|
|
8058
8107
|
};
|
|
8059
8108
|
filtered.sort((a, b) => {
|
|
8060
8109
|
if (b.confidence !== a.confidence) return b.confidence - a.confidence;
|
|
@@ -18602,6 +18651,11 @@ async function runConnectorPoll(connector, ctx, graph, resolveTarget) {
|
|
|
18602
18651
|
unresolved++;
|
|
18603
18652
|
continue;
|
|
18604
18653
|
}
|
|
18654
|
+
if (signal.deployState) {
|
|
18655
|
+
ensureServiceNode(graph, resolved.serviceName, NO_ENV);
|
|
18656
|
+
mergeObservedDeployState(graph, resolved.targetNodeId, signal.deployState);
|
|
18657
|
+
continue;
|
|
18658
|
+
}
|
|
18605
18659
|
if (signal.incident) {
|
|
18606
18660
|
ensureServiceNode(graph, resolved.serviceName, NO_ENV);
|
|
18607
18661
|
if (!ctx.errorsPath || !graph.hasNode(resolved.targetNodeId)) {
|