Skip to content

What the derived dependency graph would do to alerting, compared with the hand-authored one.

GET
/api/v1/topology/shadow
curl --request GET \
--url https://example.com/api/v1/topology/shadow \
--header 'Authorization: Bearer <token>'

This is the review surface for enabling derived suppression: would_suppress lists the active alerts that would stop being raised, and unresolved_pools lists the pollers that have no place in the graph yet. Both are computed on demand and neither affects alerting.

The comparison between the manual and derived dependency graphs

Media typeapplication/json

What the derived dependency graph would do, against what the manual one does.

object
anchors
required

Nodes the derived graph treats as roots, because a poller sits on their segment.

Array<string>
covered_nodes
required

How many nodes the derived graph gives at least one upstream.

Read with total_nodes: a low ratio means most of the fleet would keep alerting exactly as it does now, which is usually the point rather than a problem.

integer
derived_edges
required

Edges in the derived graph.

integer
manual_edges
required

Edges in the hand-authored graph.

integer
mode
required

manual, shadow or derived.

string
Allowed values: manual shadow derived
mode_since

When the mode was last changed (RFC 3339), or null if it never has been.

string | null
only_in_derived
required

Parent edges only the derived graph has.

Array<object>

One node whose parent set differs between the two graphs.

object
child
required

The downstream node.

string format: uuid
parent
required

The upstream node.

string format: uuid
only_in_manual
required

Parent edges only the hand-authored graph has.

Array<object>

One node whose parent set differs between the two graphs.

object
child
required

The downstream node.

string format: uuid
parent
required

The upstream node.

string format: uuid
opted_out
required

Nodes an operator has excluded from derived suppression entirely.

A list rather than a count: the screen that shows the comparison is also where the exclusion is toggled, and a count cannot tell a row whether it is the excluded one. Bounded by what an operator typed in, not by the fleet.

Array<string>
total_nodes
required

Nodes in the inventory.

integer
unresolved_pollers
required

Poller ids that could not be placed, so an operator knows which to give an anchor.

Array<string>
unresolved_pools
required

Pools with at least one poller whose location could not be resolved.

Non-empty blocks derived. A pool with no anchor contributes no roots, so none of its nodes would ever be suppressed while every screen showed the feature as on.

Array<string>
would_suppress
required

Active alerts the derived graph would suppress and the manual one does not.

The number to review before enabling derived: each of these is an alert that would stop being raised.

Array<object>

One node whose suppression would change if the deployment moved to the derived graph.

object
node_id
required

The node whose active alert is affected.

string format: uuid
root_cause

The node the derived graph blames, when it has one.

string | null format: uuid
would_unsuppress
required

Active alerts the manual graph suppresses and the derived one would not — the noise direction.

Array<object>

One node whose suppression would change if the deployment moved to the derived graph.

object
node_id
required

The node whose active alert is affected.

string format: uuid
root_cause

The node the derived graph blames, when it has one.

string | null format: uuid
Example
{
"mode": "manual"
}

No valid bearer token

Media typeapplication/json

The ADR-019 envelope every failure renders as. pub(crate) and schema-bearing so the OpenAPI document can name one error shape for every endpoint (ADR-035) instead of leaving 4xx/5xx bodies undescribed — a client that has to guess the failure shape ends up parsing the success shape and reading undefined.

object
error
required
object
code
required

Stable machine-readable code. Clients branch on this, never on the message.

string
message
required

Operator-facing sentence. Safe to display; never carries an internal error’s own text.

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example"
}
}

Role lacks the view permission

Media typeapplication/json

The ADR-019 envelope every failure renders as. pub(crate) and schema-bearing so the OpenAPI document can name one error shape for every endpoint (ADR-035) instead of leaving 4xx/5xx bodies undescribed — a client that has to guess the failure shape ends up parsing the success shape and reading undefined.

object
error
required
object
code
required

Stable machine-readable code. Clients branch on this, never on the message.

string
message
required

Operator-facing sentence. Safe to display; never carries an internal error’s own text.

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example"
}
}

Skeleton mode has no inventory to compare

Media typeapplication/json

The ADR-019 envelope every failure renders as. pub(crate) and schema-bearing so the OpenAPI document can name one error shape for every endpoint (ADR-035) instead of leaving 4xx/5xx bodies undescribed — a client that has to guess the failure shape ends up parsing the success shape and reading undefined.

object
error
required
object
code
required

Stable machine-readable code. Clients branch on this, never on the message.

string
message
required

Operator-facing sentence. Safe to display; never carries an internal error’s own text.

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example"
}
}