Agent Lineage¶
The Agent Registry tracks parent-child relationships between agents on-chain. When an autonomous agent spawns a child agent, the lineage is recorded permanently, creating a traceable family tree from any agent back to its root creator and Haftungsperson.
Why Lineage Matters¶
Autonomous agents can create other agents. An AI research assistant might spawn specialized sub-agents for data collection, analysis, and report writing. A trading bot might spawn child bots for different markets. Without lineage tracking:
- There is no way to trace who is responsible for a grandchild agent
- There is no way to understand the organizational structure of an agent network
- There is no way to limit recursive spawning (an agent creating agents that create agents indefinitely)
- There is no way to audit the creation chain when something goes wrong
The Responsibility Chain
Lineage is not just metadata -- it is a chain of accountability. If a Generation 3 grandchild agent causes harm, lineage tracking lets you trace the chain back through its parent, its grandparent, and ultimately to the root agent's Haftungsperson.
How Lineage Works¶
Registration with a Parent¶
When registering an agent, the parentAgentId parameter determines lineage:
parentAgentId = 0: The agent is a root agent (Generation 0), directly created by a humanparentAgentId != 0: The agent is a child agent, spawned by the specified parent
function registerAgent(
address _haftungsperson,
address _agentWallet,
bytes32 _constitutionHash,
bytes32 _capabilityHash,
string calldata _operationalScope,
uint256 _parentAgentId, // 0 for root, parent's ID for children
bool _selfModifying
) external returns (uint256 agentId);
Generation Tracking¶
Generation depth is computed automatically:
| Agent Type | parentAgentId |
generation |
|---|---|---|
| Root agent (human-deployed) | 0 |
0 |
| Child of a root agent | Root agent's ID | 1 |
| Grandchild | Child agent's ID | 2 |
| Great-grandchild | Grandchild's ID | 3 |
| ... | ... | ... |
The formula is: child.generation = parent.generation + 1
Maximum Generation Depth¶
To prevent unbounded recursive spawning, the registry enforces a maximum generation depth.
| Parameter | Default Value | Configurable? |
|---|---|---|
maxGenerationDepth |
10 | Yes, via setMaxGenerationDepth() (owner only) |
If an agent at Generation 10 attempts to register a child, the transaction reverts with "Max generation depth exceeded".
Why Cap Depth?
Uncapped generation depth creates a risk of unbounded agent proliferation. A rogue agent could spawn children that spawn children indefinitely, creating an exponentially growing swarm with no clear accountability. The depth cap ensures that every agent tree remains tractable.
Lineage Rules¶
The following rules govern parent-child registration:
| Rule | Enforced By | Error Message |
|---|---|---|
| Parent must exist | agents[_parentAgentId].registeredAt != 0 |
"Parent agent not found" |
| Parent must be Active | agents[_parentAgentId].status == AgentStatus.Active |
"Parent agent not active" |
| Generation must not exceed max | generation <= maxGenerationDepth |
"Max generation depth exceeded" |
| Wallet must not be already registered | walletToAgent[_agentWallet] == 0 |
"Wallet already registered to another agent" |
Suspended Parents Cannot Spawn
Only Active agents can register children. If a parent is Suspended, Revoked, or Terminated, it cannot create child agents. This prevents a compromised or non-compliant agent from spawning new agents to continue operating.
Haftungsperson Inheritance¶
Child agents inherit accountability from the lineage chain. The haftungsperson field is set explicitly at registration time, but the convention is:
- Root agents specify their own Haftungsperson (the human or organization responsible)
- Child agents inherit the Haftungsperson from their parent (or specify the same one)
The contract does not enforce inheritance -- it allows any valid address as haftungsperson. However, the SDKs default to using the parent's Haftungsperson when registering child agents.
Children Tracking¶
The contract maintains a mapping of parent IDs to their children:
When a child agent is registered, its ID is pushed to the parent's children array, and a ChildSpawned event is emitted.
Query Functions¶
| Function | Returns |
|---|---|
getChildren(uint256 agentId) |
Array of child agent IDs |
getChildCount(uint256 agentId) |
Number of child agents |
Lineage API¶
The REST API provides a recursive lineage endpoint:
This returns the full tree: the agent, its children, its children's children, and so on.
Example: Agent Hierarchy¶
The following diagram shows a typical agent hierarchy with three generations.
graph TD
HP["Haftungsperson<br/>(Dr. Schmidt, COAI Research)<br/>0x4b19...Ccf2"]
HP -->|"registers"| R["Agent #1 — Root<br/>Generation 0<br/>Research Coordinator"]
R -->|"spawns"| C1["Agent #2<br/>Generation 1<br/>Data Collector"]
R -->|"spawns"| C2["Agent #3<br/>Generation 1<br/>Report Writer"]
R -->|"spawns"| C3["Agent #4<br/>Generation 1<br/>Peer Reviewer"]
C1 -->|"spawns"| G1["Agent #5<br/>Generation 2<br/>Web Scraper"]
C1 -->|"spawns"| G2["Agent #6<br/>Generation 2<br/>API Fetcher"]
C2 -->|"spawns"| G3["Agent #7<br/>Generation 2<br/>LaTeX Formatter"]
style HP fill:#f9f,stroke:#333,color:#000
style R fill:#bbf,stroke:#333,color:#000
style C1 fill:#bfb,stroke:#333,color:#000
style C2 fill:#bfb,stroke:#333,color:#000
style C3 fill:#bfb,stroke:#333,color:#000
style G1 fill:#ffb,stroke:#333,color:#000
style G2 fill:#ffb,stroke:#333,color:#000
style G3 fill:#ffb,stroke:#333,color:#000
In this example:
- Dr. Schmidt is the Haftungsperson for the entire tree
- Agent #1 is the root agent (Generation 0), a research coordinator
- Agents #2-4 are Generation 1 children, each with a specialized role
- Agents #5-7 are Generation 2 grandchildren, handling fine-grained tasks
- All agents are traceable back to Dr. Schmidt through the lineage chain
Lineage and Compliance¶
Lineage interacts with compliance in two important ways:
1. Parent Must Be Active to Spawn¶
A suspended, revoked, or terminated agent cannot register children. This prevents non-compliant agents from spawning new agents to circumvent restrictions.
2. Children Are Independent After Creation¶
Once registered, a child agent's compliance is independent of its parent. If the parent is suspended, the child remains Active (unless separately suspended by a regulator). This is by design -- a child agent may be operating correctly even if its parent has issues.
Future Consideration: Cascading Suspension
The current contract does not implement cascading suspension (where suspending a parent automatically suspends all children). This may be added in a future version as a governance option, but it raises complex questions about proportionality and fairness.
Events¶
| Event | Emitted When | Fields |
|---|---|---|
AgentRegistered |
Any agent is registered | agentId, creator, haftungsperson, parentAgentId, generation |
ChildSpawned |
A child agent is registered (parentAgentId != 0) | parentId, childId, generation |
Further Reading¶
- Key Concepts -- Overview of all concepts
- Compliance & Attestation -- How compliance affects lineage
- Architecture -- How lineage fits into the full system