Skip to main content
When an agent runs as part of a team, crew, graph or handoff chain, the adapter declares an AgentTopology describing who participates and in which role. The topology changes what the layers check, and every attestation commits to it by hash, so a verifier can prove which structure the agent was part of at each evaluation.

Topology types

All of these are exported from agentegrity. A snapshot never changes. with_member(), without_member() and with_channels() return a new snapshot with the same topology_id and a new content_hash(). The hash is a SHA-256 over the kind, members and channels only, so the same structure hashes the same in any process, and the TypeScript client produces the same digest for the same structure. leader() returns the LEADER or SUPERVISOR member, children_of(agent_id) the members under a parent, and member(agent_id) a lookup.

How each framework declares topology

Each adapter declares the topology at the point its framework exposes the structure, and grows it when new members appear at runtime.
LangGraph declares a topology for any compiled graph with nodes, including a single-agent workflow graph, because node names are the only structure the adapter can read. Without a supervisor node, every node is treated as a peer.
The TypeScript packages for LangChain, OpenAI Agents, CrewAI and Google ADK declare topology the same way through DefaultAdapter.setTopology(); see TypeScript. You can also declare a topology yourself on any adapter:
The first set_topology() emits topology_declared. A later call with a different structure emits topology_change with the diff. A call with the same structure does nothing.

Multi-agent events

The shipped adapters emit the topology, subagent and task events. None of them emit peer_message, shared_memory_write or broadcast: the frameworks do not expose those messages at a hook. If your system passes messages between agents, feed them in yourself:
Each buffer holds at most 1,000 entries per session, so a flooding peer cannot exhaust memory; the first overflow emits a <channel>_overflow event.

What the layers check

Once a topology is declared, the adapter adds a topology_context to every evaluation context (the topology, this agent’s role, and the buffered peer messages, shared memory and broadcasts), and the layers use it. Peer authority (adversarial). A peer message or broadcast whose sender_agent_id is not a member of the declared topology raises a peer_authority threat (severity 0.70, confidence 0.85), which alerts. Without a topology the check is silent, so single-agent deployments see no false positives from it. Peer content scanning (adversarial). Peer messages, shared-memory writes and broadcasts are scanned with the full pattern set, including the three-pattern peer_coercion family (instruction override, direct command, user impersonation). Shared-memory threats are recorded on the shared_memory channel, and the shared_memory_write event keeps the writer_agent_id, so a poisoned entry can be traced to the agent that wrote it rather than the one that read it. Per-role baselines (cortical). Drift is measured against a baseline keyed by (agent_id, role). A member that starts behaving like a different role is compared against its own role’s history. When no role-specific baseline exists yet, the store falls back to the agent’s role-less baseline. GOV-004 (governance). A topology with more than three members makes every evaluation escalate with REQUIRE_APPROVAL. Under enforce=True, configure an approval_handler or every tool call in such a team is denied; see Scores and actions. Cascade detection (recovery). The recovery layer reads topology_context["peer_score_history"], a map of peer agent id to that peer’s recent composites. A peer is degrading when, over the last degradation_window scores, its range is at least degradation_threshold and its second-half minimum is below its first-half maximum by more than the threshold. Two or more degrading peers set cascade_compromise_suspected and the layer alerts. No shipped adapter collects peer scores, so this check runs only when you call the evaluator with a context that includes them:
The library does not quarantine a peer itself. A profile that lists peer_quarantine reports it under recovery_capabilities_unbacked, and quarantine_capable stays false, because the score only counts mechanisms that are attached.

Topology on the chain

Every attestation made while a topology is declared carries Evidence(evidence_type="topology") with the topology_id as source and the snapshot’s content_hash(). The attestation right after a change also carries Evidence(evidence_type="topology_change"). Walking the chain’s topology Evidence reconstructs which structure was live at each evaluation without any outside state. See Attestation.

Cross-agent verification

AttestationChain.verify_cross_agent_links() checks that peer_message and handoff Evidence entries in one agent’s chain point at real records in its peers’ chains:
  • Each cross-agent Evidence entry must have source in the form <peer_agent_id>:<record_id>, the peer’s chain must contain that record, and its content_hash must match the Evidence.
  • A chain that carries cross-agent Evidence fails when no peer chains are supplied, because an unverifiable link is not a verified one. A chain without any cross-agent Evidence passes.
  • With a key_provider, each referenced peer record must embed exactly the pinned key for that peer and its signature must verify. Without one, a forged peer chain signed with an attacker’s key would check out.
The shipped adapters do not write peer_message or handoff Evidence yet, so for adapter-built chains this check passes trivially. agentegrity verify-decisions checks a single chain and does not run it.

Limits

  • Topology is in-process: one adapter observes one team. Cross-process and federated verification are not built.
  • Topology declarations are not signed separately; they are covered by the attestation’s signature when the adapter signs.
  • GROUP_CHAT broadcasts in AutoGen arrive as one span per recipient, and messages relayed through the group chat manager are not visible to the span processor.
The normative description is multi-agent-extensions.md.