Back to Netdata

Spec - Topology Modes, Correlation, Aggregation, And Actor Identification

.agents/skills/project-create-topology/topology-modes-correlation-aggregation.md

2.11.033.8 KB
Original Source

Spec - Topology Modes, Correlation, Aggregation, And Actor Identification

Status

Implementation contract introduced by topology v1 producer work in PR #22496 / commit 8afe52d8b.

PR #22496 completed the cross-repo compatibility layer for modes, modal identification, correlation classes, and table merge policy. The stronger detailed network-connections loose-side graph model remains target behavior, but requires a separate Agent/UI/aggregator execution pass before it becomes current contract.

Purpose

Topology payloads must let operators inspect a topology at the right level:

  • exact evidence when they need detailed troubleshooting;
  • compact relationships when they need an infrastructure-level map;
  • consistent cross-node correlation when many independently produced payloads are merged;
  • useful actor modals without duplicating the same facts only for display.

The contract must remain topology-agnostic. The UI and aggregator must not learn domain words such as process, router, parent, child, endpoint, LLDP, socket, or retention as hardcoded behavior. Producers describe identities, modes, merge rules, table merge policies, and presentation recipes in the payload.

Terms

  • Producer: the Agent Function that emits one netdata.topology.v1 payload, for example network-connections, SNMP, streaming, or vSphere.
  • Aggregator: Cloud service that fans out to many producers, decodes their payloads, correlates them, optionally aggregates detail, and returns a normal netdata.topology.v1 payload.
  • UI: Cloud frontend topology renderer and actor/link modal renderer.
  • Detailed mode: payload or returned view that keeps the finest evidence grain the producer exposes for troubleshooting.
  • Aggregated mode: payload or returned view that groups detailed evidence into compact relationships for map readability.
  • Known actor: an entity the producer knows exists, such as a process, host, SNMP device, interface, streaming node, vSphere object, or Kubernetes object.
  • Loose side: one side of a relationship row that has endpoint facts but no actor reference yet.
  • Materialized actor: actor created from loose-side facts for presentation or partial correlation, such as an endpoint grouped by IP.
  • Replacement: aggregation action where a weaker actor is removed and all incident relationships are rewired to a stronger actor.
  • Enrichment: aggregation action where rows from multiple actors with the same identity are merged into one actor, preserving all non-conflicting facts.
  • Evidence table: lossless or near-lossless relationship facts, for example sockets, L2 observations, or streaming relationships.
  • Relationship summary table: compact relationship rows at a grain between graph links and detailed evidence.
  • Actor labels: actor-owned key/value rows for modal labels and display selection. They are not a replacement for typed identity, matching, grouping, sorting, filtering, or aggregation columns.

Global Rules

Mode Request

The user-facing request key for topology mode is __topology_mode.

Allowed values:

  • detailed
  • aggregated

If the key is absent, each Function uses its documented default. Producers that do not have a meaningful detailed/aggregated difference should not expose a mode selector only to return identical output.

Mode-capable producers declare data.view.supported_modes. Consumers treat an absent field or a single-value field as mode-invariant and must not show a detailed/aggregated toggle for that payload.

Aggregator Fanout

The aggregator must consume detailed payloads whenever a producer supports detail mode.

When the user asks the aggregator for __topology_mode=aggregated, the aggregator must rewrite fanout requests to producers as __topology_mode=detailed before correlation and aggregation. This prevents early information loss before cross-node matching. After correlation, the aggregator returns either detailed or aggregated output according to the original user request.

If a producer does not expose __topology_mode, the aggregator must not invent that parameter for it. SNMP and streaming are expected to be mode-invariant unless a future producer change defines a real mode difference.

Final Output

Aggregator internal states must not appear in final payloads. Terms such as absorbed, candidate, rewrite plan, partial class, or equivalence set may exist inside the service, but final topology output contains only normal actors, links, tables, labels, presentation, and diagnostics.

No Duplicate Display Facts

Do not copy high-cardinality evidence rows only to make modal tables easier. Modal sections must select and project existing actors, links, evidence, relationship tables, actor tables, and actor labels.

Small scalar facts may appear in more than one plane when the grains differ. For example, a graph link and a relationship-summary row may both carry socket_count; the graph link is the renderable relationship, while the summary row is the modal/drilldown grain.

Actor Modal Identification

The modal identification area is part of the schema contract.

types.actor_types.<id>.presentation.modal.labels must be extended with an ordered producer-selected identification list over the existing actor label table. The UI renders those selected label keys near the actor title. The full label table remains available in the Labels tab.

Target shape:

json
{
  "labels": {
    "enabled": true,
    "table": "actor_labels",
    "actor_column": "actor",
    "key_column": "key",
    "value_column": "value",
    "identification": {
      "enabled": true,
      "fields": [
        { "key": "process", "label": "Process", "max_values": 1 },
        { "key": "username", "label": "User", "max_values": 1 },
        { "key": "cmdline", "label": "Command", "max_values": 1 }
      ]
    }
  }
}

Rules:

  • identification.fields[] selects rows from actor_labels by key.
  • Selection is per selected modal actor through actor_column.
  • Repeated values are ordered by value_index when present.
  • Missing selected keys are skipped; they do not create empty labels.
  • max_values limits displayed values for one key. The full Labels tab still shows all values.
  • The UI must not guess important labels from key names.
  • Producers must not duplicate these values into a separate modal-only table.

Schema Additions Required

This spec requires these schema extensions beyond the currently deployed v1 contract:

  1. Modal label identification metadata: modal.labels.identification.enabled and modal.labels.identification.fields[].
  2. Link-side materialization policy for tables that can carry loose sides: producers must declare how a loose side can be grouped into presentation actors when a detailed row has only one real actor.
  3. Aggregation/correlation rules must support three semantic outcomes:
    • loose-side resolution;
    • actor replacement;
    • actor enrichment.
  4. Table merge policies must be explicit enough for the aggregator to merge streaming path, retention, inbound, outbound, SNMP observation, and relationship-summary rows without domain-specific code.

The implementation may encode these additions in the most compact shape that fits the existing JSON schema style. This spec defines semantics; exact field names are accepted when they are schema-valid, documented, and used uniformly by Agent, UI, and aggregator.

Correlation And Aggregation Model

Rule Classes

Correlation rules are declarative. The aggregator builds keys from columns and literals; it does not understand domain semantics.

Required rule classes:

  • resolve_loose_side: matches a loose relationship side to a known actor or to a materialized partial actor.
  • replace_actor: replaces weaker actors with stronger actors and rewires incident links/tables.
  • merge_enrich_actor: merges actors with the same identity and combines their labels, attributes, links, evidence, and detail tables according to declared table policies.

Priority

Rules run by ascending priority number. Exact rules must run before broader or partial rules.

Example:

json
{
  "rules": {
    "socket_exact": {
      "class": "resolve_loose_side",
      "priority": 10,
      "key_space": "socket",
      "key": [
        { "column": "protocol" },
        { "literal": "|" },
        { "column": "address_space" },
        { "literal": "|" },
        { "column": "ip" },
        { "literal": ":" },
        { "column": "port" }
      ],
      "output_link_type": "socket"
    },
    "ip_partial": {
      "class": "resolve_loose_side",
      "priority": 100,
      "key_space": "ip",
      "key": [
        { "column": "address_space" },
        { "literal": "|" },
        { "column": "ip" }
      ],
      "output_link_type": "partial_endpoint"
    }
  }
}

Ambiguity

If one point matches exactly one claim, apply the rule.

If one point matches multiple claims with the same priority, the aggregator must not pick randomly. It keeps the point unresolved or materializes a partial actor according to the rule, and records a diagnostic.

If no match exists, the point or loose side remains unresolved and may be materialized for UI display according to the declared materialization policy.

Alias And NAT Evidence

NAT, load balancer, or alias information is modeled as additional keys for the same point or claim. Alias rows add match possibilities; they do not mutate or delete the original observation.

Table Merge Policies

Every table type that can cross producer boundaries needs a merge policy.

Required dimensions:

  • key: columns that identify equivalent rows.
  • action: one of deduplicate, append, set_union, merge_metrics, latest, or preserve.
  • metrics: per numeric column merge operation, such as sum, min, max, avg_weighted, or latest.
  • conflicts: how non-key scalar conflicts are handled. Allowed policies are prefer_claim, prefer_newest_agent, preserve_all, or diagnostic.

General rules:

  • Relationship evidence normally uses append or deduplicate.
  • Relationship summaries normally use merge_metrics on the declared key.
  • Actor labels use set_union keyed by actor, key, value, source, kind, and value_index.
  • Streaming retention uses preserve or append when two parents retain data for the same node because each retaining parent is meaningful.
  • Raw JSON columns cannot participate in key construction unless a scalar JSON path is explicitly declared in the table policy. Prefer typed scalar columns.

Layer Responsibilities

Agent Direct View

The Agent returns the producer's local topology.

  • If detailed and aggregated modes are meaningful, the Agent may expose __topology_mode.
  • Detailed mode keeps the finest useful evidence.
  • Aggregated mode returns a readable local graph and modal relationship summaries.
  • If modes are identical, the Agent should not expose a mode option.

Aggregator View

The aggregator always collects the highest-detail useful input it can get.

  • Requested detailed output:
    • fan out detailed when supported;
    • correlate and enrich;
    • return detailed rows with resolved actors where exact matches exist;
    • keep unresolved loose sides/materialized actors when no match exists.
  • Requested aggregated output:
    • fan out detailed when supported;
    • correlate and enrich first;
    • aggregate into compact actors, links, relationship summaries, and modal tables according to schema policies.

UI View

The UI renders the payload it receives.

  • It does not run domain-specific correlation.
  • It may materialize loose sides for direct-Agent detailed views only if the payload declares the materialization policy.
  • It renders actor modal identification from modal.labels.identification.fields[].
  • It renders the full Labels tab from actor_labels.
  • It renders modal tables from schema recipes and existing data planes.

Network-Connections

Domain Model

A socket observation is associated with an observed process actor and two dependency endpoint tuples:

text
protocol, client_ip, client_port, server_ip, server_port, state

For inbound sockets, the observed process owns the server tuple. For outbound sockets, the observed process owns the client tuple. For local/same-node sockets, both process actors may be known, but the emitted topology direction remains client-to-server. For listening sockets, there is no remote side.

The exact remote tuple is required for cross-node correlation, but creating an actor per IP:PORT in a single-node graph can explode actor count and force layout noise. Therefore detailed mode must preserve the exact tuple without requiring every tuple to be an actor.

Agent Aggregated Mode

Agent aggregated mode is a readable local process dependency map.

Rules:

  • Every graph link has two actor references.
  • The producer creates materialized endpoint actors for unknown peers using the peer IP plus address space.
  • Socket dependency link types use direction_role: "dependency" and graph links point from client/dependant actor to server/dependency actor.
  • Relationship-summary rows are collapsed by actor pair, protocol, and state. They keep dependency endpoint IPs (client_ip, server_ip) and merged metrics, but not per-socket ephemeral ports.
  • Process actor size is driven by socket_count.
  • Port bullets are driven by compact actor-owned port summaries, using a numeric count column.
  • Node-to-process ownership links are graph-coherence links, not networking dependencies.

Synthetic example:

json
{
  "view": { "mode": "aggregated" },
  "actors": [
    { "id": 1, "type": "node", "display_name": "node-a" },
    { "id": 2, "type": "process", "display_name": "api", "socket_count": 14 },
    { "id": 3, "type": "endpoint", "display_name": "198.51.100.20", "ip": "198.51.100.20" }
  ],
  "links": [
    { "src_actor": 1, "dst_actor": 2, "type": "ownership" },
    { "src_actor": 2, "dst_actor": 3, "type": "endpoint_socket", "protocol": "tcp", "socket_count": 12 }
  ],
  "tables": {
    "relationship": {
      "connections": [
        { "src_actor": 2, "dst_actor": 3, "protocol": "tcp", "client_ip": "192.0.2.10", "server_ip": "198.51.100.20", "socket_count": 12 }
      ]
    }
  }
}

The example uses row objects for readability. Production uses compact tables.

Agent Detailed Mode

Agent detailed mode preserves exact socket evidence.

Rules:

  • Graph links still have two actor references.
  • Unknown peers are still visible endpoint actors, grouped by peer IP plus address space.
  • Socket evidence preserves the exact client/server tuple, including ports, so Cloud correlation has no tuple loss.
  • Listening rows have no remote side and no fake remote actor.
  • Local sockets with both processes known have two process actor refs.

Synthetic example:

json
{
  "view": { "mode": "detailed" },
  "actors": [
    { "id": 1, "type": "node", "display_name": "node-a" },
    { "id": 2, "type": "process", "display_name": "api" },
    { "id": 3, "type": "endpoint", "display_name": "198.51.100.20", "ip": "198.51.100.20" }
  ],
  "evidence": {
    "socket": [
      {
        "src_actor": 2,
        "dst_actor": 3,
        "protocol": "tcp",
        "client_ip": "192.0.2.10",
        "client_port": 50120,
        "server_ip": "198.51.100.20",
        "server_port": 443
      }
    ]
  }
}

Aggregator Network-Connections

The aggregator receives detailed rows.

Exact match:

text
node-a api claims client tcp 192.0.2.10:50120, points at server tcp 198.51.100.20:443
node-b nginx claims server tcp 198.51.100.20:443, points at client tcp 192.0.2.10:50120

Result:

text
node-a/api -> node-b/nginx

No endpoint actors remain for the exact match. The loose side was resolved to a known actor and the final graph is a normal process-to-process dependency.

Partial match:

text
node-a api outbound -> 198.51.100.20:443
node-b is known to own 198.51.100.20
node-b has no matching process/socket row at collection time

Result:

text
node-a/api -> node-b/[materialized endpoint for 198.51.100.20]

The graph remains truthful: the dependency points at node-b, but the exact process could not be proven.

No match:

text
node-a/api -> materialized endpoint 198.51.100.20

The unresolved endpoint remains visible with presentation that clearly differs from resolved process links.

UI Network-Connections

Direct Agent aggregated:

  • Show process and endpoint actors.
  • Show two-sided graph links.
  • Non-node actor modals show Dependencies from relationship-summary rows where the selected actor is src_actor, and Dependants where it is dst_actor.

Direct Agent detailed:

  • Show known actors.
  • Show visible endpoint actors for unknown peers, grouped by peer IP and address space.
  • Non-node actor modals show Dependencies and Dependants from exact socket evidence using the same src_actor / dst_actor split.

Aggregator aggregated:

  • Show the post-correlation compact dependency map.
  • Exact cross-node matches are process-to-process.
  • Unmatched loose sides are materialized according to policy.

Aggregator detailed:

  • Show exact socket evidence with resolved actors where possible.
  • Unresolved rows retain their loose-side facts.

SNMP

Domain Model

SNMP topology observations are device, interface, neighbor, forwarding, ARP, bridge, VLAN, protocol, and bounded L3 adjacency facts.

Most graph links represent observed or inferred L2 relationships between two actors. SNMP may also emit logical L3 relationships with their own link and evidence types. These links MUST NOT be presented as physical or L2 adjacency.

l3_subnet represents an observed shared-subnet relationship between two managed SNMP device actors. It is currently derived from interface IP/netmask state collected from IP-MIB ipAddrTable, limited to IPv4 point-to-point /30 and /31 subnets. It means both devices have managed interfaces in the same point-to-point subnet; it does not prove that the devices are physically connected.

l3_subnet_segment represents a broader IPv4 shared subnet observed from managed SNMP device interface state. SNMP currently emits these segment actors for /24 through /29 subnets. The segment actor is a logical grouping point, not a physical switch, bridge domain, VLAN, or endpoint. Each member device is connected to the segment by an l3_subnet_membership link. Membership evidence contains the member actor, subnet, member IP, interface index/name/description, network, netmask, prefix, and source. Only resolved managed SNMP network-device actors participate; unmanaged endpoints and unresolved rows are suppression state, not graph actors.

l3_subnet_segment actor ids must be scoped by a stable producer scope, such as the parent Agent registry id, plus the subnet identity. If the producer cannot obtain a stable scope id, it must omit L3 subnet segments rather than fall back to a process-local or random id. This prevents identical private subnets from different Agents from colliding after Cloud aggregation.

Current SNMP L3 subnet segments are single-routing-context. L3Interface does not currently carry a VRF or routing-context field, so identical subnet/prefix values inside one producer scope are treated as one logical segment. Producers MUST NOT present these segments as VRF-aware until collection adds routing context to L3 interface observations and segment identity includes it.

ospf_adjacency represents OSPF control-plane adjacency between two resolved managed SNMP device actors. It is a logical L3 routing-protocol relationship, not physical, L2, discovery, or port-neighbor evidence. The producer emits graph links only for full OSPF neighbors with resolved managed endpoints. Non-full or unresolved OSPF neighbor rows remain diagnostic actor-owned detail rows and must not create loose router/IP graph actors. Current SNMP OSPF topology scope is OSPFv2 non-virtual neighbors from ospfNbrTable; OSPFv3 and OSPF virtual-neighbor tables are future scope unless a later topology feature explicitly adds their distinct semantics.

bgp_adjacency represents BGP control-plane adjacency between two resolved managed SNMP device actors. It is a logical routing-protocol relationship, not physical, L2, discovery, or port-neighbor evidence. The producer emits graph links only for established BGP peers with resolved local and remote managed actors. Unresolved or non-established BGP peer rows remain diagnostic actor-owned detail rows and must not create loose router/IP graph actors. BGP adjacency graph identity should use the managed actor pair plus routing instance. BGP identifiers, ASNs, and endpoint IPs are useful evidence and display fields, but they must not be the primary graph deduplication key because SNMP BGP profiles expose those fields inconsistently across vendors. Parallel sessions between the same managed actor pair in the same routing instance should remain actor-owned peer detail rows under one compact graph relationship unless a future producer contract explicitly adds a more detailed BGP graph mode.

When ospf_adjacency and l3_subnet describe the same resolved actor pair and endpoint/subnet relationship, OSPF is the stronger protocol-specific signal for the graph. The producer may suppress the matching l3_subnet graph link while preserving typed OSPF evidence and actor-owned neighbor detail rows.

SNMP is not a loose-side topology. Every graph link should have two actors in both Agent and aggregator views. l3_subnet follows the same rule: unmatched or ambiguous L3 endpoints are diagnostic/suppression state, not materialized IP-only graph actors.

Mode Behavior

SNMP detailed and aggregated modes are currently a no-op. The producer should not expose __topology_mode until it has a real lower/higher-grain distinction.

If a global Cloud topology request asks for aggregated output, the aggregator still consumes the same SNMP payload and returns the same semantic grain after correlation/replacement.

Correlation Behavior

SNMP mainly uses actor replacement.

Examples:

  • A managed device actor is stronger than an LLDP remote placeholder that has the same chassis id.
  • A managed interface actor is stronger than an inferred endpoint that has the same MAC/interface identity.
  • A discovered management IP can help match a placeholder to a managed device, but ambiguous matches must not be chosen randomly.

Replacement example:

text
payload-a: switch-a port 10 -> lldp-remote(chassis=aa:bb:cc)
payload-b: managed-switch-b(chassis=aa:bb:cc)

Result:

text
switch-a port 10 -> managed-switch-b

The weaker LLDP remote actor is removed from the aggregated output and its incident links/tables are rewired to the managed device actor.

For l3_subnet, aggregation MUST preserve the explicit l3_subnet link and evidence type. Replacement may rewire endpoint actors to stronger managed device actors, but it MUST NOT reinterpret l3_subnet as discovery protocol evidence or port-neighbor evidence.

For l3_subnet_segment, aggregation MUST preserve the explicit l3_subnet_segment actor type and l3_subnet_membership link/evidence type. Replacement may rewire member actors to stronger managed device actors, but it MUST NOT reinterpret subnet membership as L2 segment membership, discovery protocol evidence, or port-neighbor evidence. Aggregation may merge identical scoped subnet segment actors from the same producer scope, but must not merge identical private subnet strings across different producer scopes. Within one producer scope, the current identity is subnet/prefix only because SNMP topology does not yet collect VRF/routing-context for L3 interfaces.

For ospf_adjacency, aggregation MUST preserve the explicit ospf_adjacency link and evidence type, including its semantic_role: control. Replacement may rewire endpoint actors to stronger managed device actors, but it MUST NOT reinterpret OSPF adjacency as discovery, physical, L2, or port-neighbor evidence. Actor-owned OSPF neighbor detail rows should remain attached to the local device actor and are not loose-side graph materialization input unless a future producer contract explicitly defines such a policy.

For bgp_adjacency, aggregation MUST preserve the explicit bgp_adjacency link and evidence type, including its semantic_role: control. Replacement may rewire endpoint actors to stronger managed device actors, but it MUST NOT reinterpret BGP adjacency as discovery, physical, L2, or port-neighbor evidence. Actor-owned BGP peer detail rows should remain attached to the local device actor and are not loose-side graph materialization input unless a future producer contract explicitly defines such a policy.

UI SNMP

The UI should not expose a detailed/aggregated toggle for SNMP unless the payload declares supported modes.

Device modals should remain port-centric:

  • actor identification: device name, management IP, vendor, model, role, and other selected labels;
  • full labels tab: all labels;
  • ports table: one row per known interface/port, with SNMP if_index as the visible real numeric port ID when known, and the port name;
  • expanded port rows: show a clickable neighbor actor and neighbor port name when graph-link facts can align the port to a remote actor;
  • links/neighbor information: derived from the same port rows or aligned relationship rows so local port identity never contradicts the port table.
  • L3 adjacency information: derived from typed l3_subnet relationship evidence, not from actor_port_links.
  • L3 subnet membership information: derived from typed l3_subnet_membership evidence. A focused device may show the shared subnet segment and the focused membership without automatically fanning out to every other managed device in that broader subnet.
  • routing protocol neighbor information: derived from typed actor-owned detail rows such as actor_ospf_neighbors and actor_bgp_peers, not from actor_port_links. The modal may show unresolved or non-established protocol neighbors as diagnostics without creating graph links.

Streaming

Domain Model

Streaming topology describes Netdata Agent streaming relationships:

text
child -> parent
parent <-> parent
virtual/stale/remote nodes represented as actors

All actors are real topology actors from the streaming view. Links always have two actor refs. Streaming is not a loose-side topology.

Mode Behavior

Streaming detailed and aggregated modes are currently a no-op. The producer should not expose __topology_mode until it has a real lower/higher-grain distinction.

The aggregator still consumes the same streaming payload for global aggregated requests and returns merged/enriched streaming topology.

Correlation Behavior

Streaming uses actor enrichment and table merging by machine_guid.

Example:

text
child-1 -> parent-1 <-> parent-2 <- child-2

Both parents may report facts about the same node. The aggregator must not show duplicate actors for the same machine_guid. It merges those actors and then merges their tables according to table policy.

Required merge behavior:

  • actor labels: set union;
  • actor scalar facts: prefer non-empty, newest Agent version when explicitly comparable, otherwise preserve conflicts in diagnostics or expanded labels;
  • stream path rows: deduplicate identical path membership rows;
  • retention rows: preserve each retaining parent/source row, because multiple parents retaining the same child are meaningful;
  • inbound stream rows: merge by parent actor, child actor, immediate source actor when known, and relationship type, with numeric metrics merged by table policy;
  • outbound stream rows: merge by sending parent actor, streamed node actor, destination actor when known, and stream state, with numeric metrics merged by table policy;
  • links: merge by source actor, destination actor, type, protocol, and state, then merge metrics/evidence according to link type policy.

Retention example:

text
payload-parent-a: parent-a retains child-x for tier 0
payload-parent-b: parent-b retains child-x for tier 0
payload-child-x: child-x self retention tier 0

Result:

text
actor child-x modal Retention table has 3 rows:
  retaining actor parent-a
  retaining actor parent-b
  retaining actor child-x

These rows must not be deduplicated away solely because the retained child is the same.

UI Streaming

The UI should not expose a detailed/aggregated toggle for streaming unless the payload declares supported modes.

Actor modal identification should show selected labels such as role, hostname, machine GUID when useful, and stream status. The full Labels tab remains complete.

Tables:

  • stream path: deduplicated path rows for the selected actor only. Timestamps must be populated for every path row when the producer or aggregator can derive them; synthetic rows used for highlighting are not allowed to drop known timing facts;
  • retained nodes: all nodes whose data is maintained by the selected actor, using the same retention table filtered by observer_actor. This is the default retention view in the current modal contract;
  • received nodes: children, virtual nodes, stale nodes, and descendants received or transiting through the selected parent. The immediate source must be populated when known; direct local receipt should use the child/vnode actor as the source instead of rendering an empty value;
  • outbound streams: every node payload the selected parent sends upstream, including self, virtual nodes, direct children, and transit descendants. Rows are owned by the sending parent and must show the streamed node and the destination.

The current default modal contract does not show a separate Retention for node section. The underlying retention table still preserves actor and observer_actor so aggregated/cloud views can add an explicitly named Retained by section later without changing the facts.

Highlight path must use the deduplicated stream-path table, not direct sibling selection only.

Cross-Topology Examples

Agent Detailed To Aggregator Aggregated

Input request to Cloud:

text
function=topology:network-connections __topology_mode=aggregated

Aggregator fanout:

text
node-a: topology:network-connections __topology_mode=detailed
node-b: topology:network-connections __topology_mode=detailed

Aggregator work:

  1. Decode detailed socket evidence from both nodes.
  2. Resolve exact loose-side socket keys.
  3. Materialize unresolved partial endpoints.
  4. Aggregate graph links and relationship summaries.

Returned payload:

json
{
  "view": { "mode": "aggregated" },
  "actors": "... compact post-correlation actor table ...",
  "links": "... compact post-correlation graph links ...",
  "tables": {
    "relationship": {
      "connections": "... aggregated drilldown rows ..."
    }
  }
}

Agent Detailed To UI Direct Detailed

Input request to Agent:

text
function=topology:network-connections __topology_mode=detailed

UI work:

  1. Decode known actors and exact socket evidence.
  2. Render known actors.
  3. Materialize loose endpoints only as declared by the payload, normally by IP.
  4. Show exact socket rows in process modals.

SNMP Global Aggregated

Input request to Cloud:

text
function=topology:snmp __topology_mode=aggregated

Aggregator fanout:

text
node-a: topology:snmp
node-b: topology:snmp

No mode parameter is sent unless the producer advertises one. Aggregator applies replacement rules and returns a normal graph.

Streaming Global Aggregated

Input request to Cloud:

text
function=topology:streaming __topology_mode=aggregated

Aggregator fanout:

text
node-a: topology:streaming
node-b: topology:streaming

No mode parameter is sent unless the producer advertises one. Aggregator merges actors by machine_guid, preserves retention rows by retaining source, and deduplicates stream path rows by declared path identity.

Open Edge Cases And Required Behavior

  • Ambiguous network socket match: keep unresolved or materialize partial; record diagnostic; do not randomly choose a process.
  • Socket closed between node collections: exact process match may fail; partial IP/node match may still be valid if a node/endpoint claim exists.
  • NAT or load balancer aliases: add alias keys; do not overwrite original tuples.
  • SNMP duplicate weak actors: replace all weak actors that match one strong actor; preserve evidence and diagnostics.
  • SNMP weak actor matches multiple strong actors: keep weak actor visible or diagnostic; do not choose randomly.
  • Streaming stale node: keep actor if it is meaningful to streaming status; merge by machine_guid only when identities match.
  • Streaming retention from multiple parents: preserve rows; do not collapse them into one retained child row.
  • Actor label conflicts: keep full label set; modal identification applies display limits only, not data loss.
  • High-cardinality detailed network-connections: detailed mode may be large; aggregated mode must avoid actor-per-port explosion.

Validation Requirements

Agent:

  • Schema validation for all changed topology payloads.
  • Network-connections fixtures for aggregated and detailed modes.
  • SNMP fixture proving no mode selector is exposed unless behavior differs.
  • Streaming fixture proving no mode selector is exposed unless behavior differs.
  • Modal label identification metadata present for actor types with useful labels.

UI:

  • Decode modal label identification metadata.
  • Render selected identification labels in actor modal header.
  • Keep full Labels tab.
  • Render loose-side materialized actors only from schema policy.
  • Do not show SNMP/streaming mode toggles unless payload capability declares them.

Aggregator:

  • Rewrite __topology_mode=aggregated to detailed on fanout only when the producer supports it.
  • Consume detailed network-connections and return both detailed and aggregated outputs.
  • Resolve exact socket loose sides and preserve unresolved/partial cases.
  • Replace SNMP weak actors with managed actors.
  • Merge/enrich streaming actors and tables by machine_guid and table policy.
  • Preserve schema-valid unknown future fields.