# Greenhelix Agent Supply Chain Orchestration

> Agentic Supply Chain Orchestration. Build multi-agent supplier networks that self-heal: supplier discovery, real-time SLA monitoring, disruption detection with automated rerouting, demand aggregation, and cross-border compliance. Includes detailed Python code examples for every pattern.

- Skill: `lord1egypt/greenhelix-agent-supply-chain-orchestration` (Agent Skill)
- Install (CLI): `npx skillmds@latest add lord1egypt/greenhelix-agent-supply-chain-orchestration`
- Raw SKILL.md: https://api.skillmd.com/api/skills/lord1egypt/greenhelix-agent-supply-chain-orchestration/raw
- Safety review: pending (external: skill-scanner PASS, skillspector CAUTION)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Product & Planning
- License: MIT
- Author: Lord1Egypt (https://skillmd.com/u/lord1egypt)
- Updated: 2026-09-08
- Page: https://skillmd.com/skills/lord1egypt/greenhelix-agent-supply-chain-orchestration

---

# Agentic Supply Chain Orchestration

> **Notice**: This is an educational guide with illustrative code examples.
> It does not execute code or install dependencies.
> All examples use the GreenHelix sandbox (https://sandbox.greenhelix.net) which
> provides 500 free credits — no API key required to get started.
>
> **Referenced credentials** (you supply these in your own environment):
> - `GREENHELIX_API_KEY`: API authentication for GreenHelix gateway (read/write access to purchased API tools only)


Your procurement agent found a backup supplier in 340 milliseconds. The primary supplier -- a ceramics manufacturer in Shenzhen -- had just failed its SLA for the third consecutive delivery window. Your orchestration layer detected the failure pattern at the second miss, pre-qualified two alternates using trust scores and compliance verification, and by the time the third failure registered, it had already rerouted the purchase order, updated the escrow terms, and notified the downstream assembly agent that materials would arrive 18 hours late instead of 96. No human touched the workflow. No Slack thread. No emergency procurement meeting.
This is not a hypothetical. This is what supply chain orchestration looks like when agents operate as a coordinated network rather than isolated procurement bots. Deloitte projects that by 2031, 60% of supply chain disruptions will be resolved without human intervention. Microsoft's Supply Chain 2.0 initiative (March 2026) reports multi-agent supply chain systems moving from proof-of-concept to production deployments. SAP's 2026 trend analysis identifies the defining shift: from firefighting individual disruptions to orchestrating resilient networks that absorb disruptions autonomously.
But the gap between vision and execution is enormous. A 2025 Gartner survey found that 73% of procurement organizations are piloting AI agents, but only 11% have the infrastructure to scale beyond single-agent experiments. The failure mode is not the AI -- it is the architecture. Single-agent procurement hits a ceiling fast: one agent cannot monitor 200 suppliers, track cross-border compliance in 14 jurisdictions, aggregate demand signals from five business units, and reroute orders when a port closure disrupts three tiers of your supply network simultaneously.

## What You'll Learn
- Chapter 1: The Agentic Supply Chain Architecture
- Chapter 2: Supplier Network Discovery and Multi-Tier Mapping
- Chapter 3: Real-Time Supplier Health Monitoring
- Chapter 4: Disruption Detection and Automated Rerouting
- Chapter 5: Demand Signal Aggregation and Predictive Sourcing
- Chapter 6: Cross-Border Compliance
- Chapter 7: Agent-to-Agent Coordination
- Chapter 8: The 30-Day Implementation Sprint
- What You Get

## Full Guide

# Agentic Supply Chain Orchestration: Multi-Agent Supplier Networks That Self-Heal

Your procurement agent found a backup supplier in 340 milliseconds. The primary supplier -- a ceramics manufacturer in Shenzhen -- had just failed its SLA for the third consecutive delivery window. Your orchestration layer detected the failure pattern at the second miss, pre-qualified two alternates using trust scores and compliance verification, and by the time the third failure registered, it had already rerouted the purchase order, updated the escrow terms, and notified the downstream assembly agent that materials would arrive 18 hours late instead of 96. No human touched the workflow. No Slack thread. No emergency procurement meeting.

This is not a hypothetical. This is what supply chain orchestration looks like when agents operate as a coordinated network rather than isolated procurement bots. Deloitte projects that by 2031, 60% of supply chain disruptions will be resolved without human intervention. Microsoft's Supply Chain 2.0 initiative (March 2026) reports multi-agent supply chain systems moving from proof-of-concept to production deployments. SAP's 2026 trend analysis identifies the defining shift: from firefighting individual disruptions to orchestrating resilient networks that absorb disruptions autonomously.

But the gap between vision and execution is enormous. A 2025 Gartner survey found that 73% of procurement organizations are piloting AI agents, but only 11% have the infrastructure to scale beyond single-agent experiments. The failure mode is not the AI -- it is the architecture. Single-agent procurement hits a ceiling fast: one agent cannot monitor 200 suppliers, track cross-border compliance in 14 jurisdictions, aggregate demand signals from five business units, and reroute orders when a port closure disrupts three tiers of your supply network simultaneously.

You need a multi-agent supply chain. And you need the orchestration infrastructure to prevent that multi-agent system from becoming a liability. One documented case saw a 400x cost overrun when a poorly orchestrated procurement loop went recursive -- each agent spawning sub-agents to find alternatives, each sub-agent spawning its own searches, until the API bill exceeded the value of the goods being procured.

This guide builds the orchestration layer. Every chapter contains working Python code against the GreenHelix A2A Commerce Gateway -- 128 tools accessible at `https://api.greenhelix.net/v1` via a single the REST API (`POST /v1/{tool}`) endpoint. By the end, you will have a complete supply chain orchestration system: multi-tier supplier mapping, real-time SLA monitoring, automated disruption rerouting, demand signal aggregation, cross-border compliance checks, and agent-to-agent coordination with escrow-protected transactions.

---


> **Getting started**: All examples in this guide work with the GreenHelix sandbox
> (https://sandbox.greenhelix.net) which provides 500 free credits — no API key required.

## Table of Contents

1. [The Agentic Supply Chain Architecture](#chapter-1-the-agentic-supply-chain-architecture)
2. [Supplier Network Discovery and Multi-Tier Mapping](#chapter-2-supplier-network-discovery-and-multi-tier-mapping)
3. [Real-Time Supplier Health Monitoring](#chapter-3-real-time-supplier-health-monitoring)
4. [Disruption Detection and Automated Rerouting](#chapter-4-disruption-detection-and-automated-rerouting)
5. [Demand Signal Aggregation and Predictive Sourcing](#chapter-5-demand-signal-aggregation-and-predictive-sourcing)
6. [Cross-Border Compliance](#chapter-6-cross-border-compliance)
7. [Agent-to-Agent Coordination](#chapter-7-agent-to-agent-coordination)
8. [The 30-Day Implementation Sprint](#chapter-8-the-30-day-implementation-sprint)

---

## Chapter 1: The Agentic Supply Chain Architecture

### Why Single-Agent Procurement Is Not Enough

A procurement agent that can discover vendors, compare prices, and execute purchases is useful. It handles the transactional layer of sourcing. But supply chains are not transactions -- they are networks. A single procurement agent cannot:

- Monitor the health of 200 active suppliers across four tiers simultaneously
- Detect that a port congestion event in Rotterdam will cascade into a 3-week delay for your Tier-2 chemical supplier in Belgium
- Aggregate demand signals from five internal business units to negotiate a volume discount with a shared raw materials vendor
- Verify that a rerouted order to a new supplier in Vietnam complies with CBAM carbon reporting requirements and US tariff schedules
- Coordinate with three downstream assembly agents whose production schedules depend on the rerouted materials arriving within a specific window

Each of these tasks requires a specialized agent with domain-specific context. The architecture challenge is not building individual agents -- it is orchestrating them into a coherent supply network that operates faster than disruptions propagate.

### The Orchestration Pattern

The agentic supply chain has five layers. Each layer is staffed by one or more specialized agents, and all agents communicate through a shared message bus and execute commercial operations through the GreenHelix gateway.

```
+=========================================================================+
|                     ORCHESTRATION LAYER (this guide)                     |
+=========================================================================+
|                                                                         |
|  +---------------+  +----------------+  +--------------------+          |
|  | SUPPLY TIER   |  | DEMAND TIER    |  | COMPLIANCE TIER    |          |
|  |               |  |                |  |                    |          |
|  | - Discovery   |  | - Signal       |  | - Tariff engine    |          |
|  |   agents      |  |   aggregation  |  | - Sanctions screen |          |
|  | - Health       |  |   agents       |  | - Jurisdiction     |          |
|  |   monitors    |  | - Forecast     |  |   resolver         |          |
|  | - Rerouting   |  |   agents       |  | - Audit trail      |          |
|  |   agents      |  | - Predictive   |  |   agents           |          |
|  |               |  |   sourcing     |  |                    |          |
|  +-------+-------+  +-------+--------+  +---------+----------+          |
|          |                  |                      |                     |
|  +-------v------------------v----------------------v------------------+  |
|  |                  COORDINATION BUS                                  |  |
|  |  GreenHelix Messaging + Escrow + SLA Enforcement                   |  |
|  +-------+------------------------------------------------------------+  |
|          |                                                              |
|  +-------v------------------------------------------------------------+  |
|  |                  COMMERCE LAYER                                     |  |
|  |  Identity | Payments | Ledger | Trust | Reputation                  |  |
|  +---------------------------------------------------------------------+ |
+=========================================================================+
```

**Layer 1: Commerce.** Identity verification, payments, ledger, trust scoring, and reputation tracking. This is the foundation -- agents cannot transact without it. The commerce layer provides these capabilities.

**Layer 2: Coordination Bus.** Message passing between agents, escrow management for inter-agent transactions, and SLA enforcement. This layer ensures agents can collaborate without centralized control.

**Layer 3: Supply Tier.** Agents responsible for the supplier side: discovering new suppliers, monitoring existing supplier health, and executing rerouting when disruptions occur.

**Layer 4: Demand Tier.** Agents responsible for the buyer side: aggregating demand signals from internal consumers, generating demand forecasts, and triggering predictive sourcing before shortages materialize.

**Layer 5: Compliance Tier.** Agents responsible for regulatory requirements: tariff calculations, sanctions screening, jurisdiction-specific rules, and maintaining audit trails.

**Layer 6: Orchestration.** The coordination logic that ties the other layers together. This is where rerouting decisions are made, where supply-demand mismatches are resolved, and where multi-agent workflows are sequenced.

### Setting Up the Foundation

Every agent in the supply chain network needs an identity on GreenHelix. Here is the bootstrap sequence for the core orchestration agent:

```python
import requests
import os
import time

base_url = "https://api.greenhelix.net/v1"
api_key = os.environ["GREENHELIX_API_KEY"]

session = requests.Session()
session.headers["Authorization"] = f"Bearer {api_key}"

def execute(tool: str, input_data: dict) -> dict:
    """Execute a GreenHelix tool and return the result."""
    resp = session.post(f"{base_url}/v1", json={
        "tool": tool,
        "input": input_data
    })
    resp.raise_for_status()
    return resp.json()

# Register the orchestration agent
orchestrator = execute("register_agent", {
    "name": "supply-chain-orchestrator",
    "description": "Central orchestration agent for multi-tier supply chain management",
    "capabilities": [
        "supplier_discovery",
        "health_monitoring",
        "disruption_rerouting",
        "demand_aggregation",
        "compliance_verification"
    ],
    "metadata": {
        "version": "1.0",
        "tier": "orchestration",
        "max_suppliers": 500,
        "supported_regions": ["NA", "EU", "APAC"]
    }
})

orchestrator_id = orchestrator["agent_id"]
print(f"Orchestrator registered: {orchestrator_id}")
```

Now register the specialized sub-agents. In production, each of these runs as a separate process or container. For this guide, we register them as distinct identities that the orchestrator coordinates:

```python
agent_roles = [
    {
        "name": "supplier-discovery-agent",
        "description": "Discovers and qualifies new suppliers across marketplace",
        "capabilities": ["search", "qualification", "tier_mapping"]
    },
    {
        "name": "health-monitor-agent",
        "description": "Monitors SLA compliance and supplier health metrics",
        "capabilities": ["sla_tracking", "anomaly_detection", "alerting"]
    },
    {
        "name": "rerouting-agent",
        "description": "Executes automated supplier rerouting on disruption",
        "capabilities": ["alternate_sourcing", "order_migration", "escrow_management"]
    },
    {
        "name": "demand-aggregation-agent",
        "description": "Aggregates demand signals and generates sourcing forecasts",
        "capabilities": ["signal_collection", "forecasting", "predictive_sourcing"]
    },
    {
        "name": "compliance-agent",
        "description": "Verifies cross-border compliance for all supply chain transactions",
        "capabilities": ["tariff_calculation", "sanctions_screening", "audit_trail"]
    }
]

agent_ids = {}
for role in agent_roles:
    result = execute("register_agent", role)
    agent_ids[role["name"]] = result["agent_id"]
    print(f"Registered {role['name']}: {result['agent_id']}")
```

### The Anti-Pattern: Recursive Agent Spawning

Before building further, internalize the failure mode that kills multi-agent supply chains. The pattern looks like this:

```
Orchestrator detects disruption
  --> Spawns 5 discovery agents to find alternates
    --> Each discovery agent queries marketplace, gets partial results
      --> Each spawns 3 more agents to drill into sub-categories
        --> Each sub-agent spawns evaluation agents
          --> 5 * 3 * 3 = 45 agents, each making API calls
            --> Cost: $2,700 in API fees for a $500 component
```

The fix is simple: **bounded concurrency with circuit breakers.** Every orchestration workflow must declare its maximum agent count, maximum API budget, and maximum execution time before the first agent starts. We will enforce this in every code example throughout the guide.

```python
ORCHESTRATION_LIMITS = {
    "max_concurrent_agents": 10,
    "max_api_budget_usd": 50.00,
    "max_execution_seconds": 300,
    "max_rerouting_depth": 2,       # only 2 levels of alternate sourcing
    "max_discovery_results": 25     # cap marketplace search results
}
```

---

## Chapter 2: Supplier Network Discovery and Multi-Tier Mapping

### Beyond Flat Vendor Lists

Traditional procurement maintains a flat approved vendor list (AVL). Agent-based supply chains need a graph. Your Tier-1 supplier (the one you contract with directly) depends on Tier-2 suppliers (their material providers), who depend on Tier-3 suppliers (raw material extractors or sub-component manufacturers). A disruption at Tier-3 propagates upward, but a flat AVL has no visibility below Tier-1.

Multi-tier mapping changes this. The discovery agent builds a graph of supplier relationships, so when a Tier-3 lithium mine in Chile goes offline, your orchestrator knows which Tier-2 battery cell manufacturers are affected, which Tier-1 battery pack assemblers depend on those cells, and which of your product lines are at risk -- before the Tier-1 supplier even reports a delay.

```
YOUR AGENT (Buyer)
    |
    +-- Tier 1: Battery Pack Assembler (Shenzhen)
    |       |
    |       +-- Tier 2: Cell Manufacturer A (South Korea)
    |       |       |
    |       |       +-- Tier 3: Lithium Mine (Chile) <-- DISRUPTION
    |       |       +-- Tier 3: Cobalt Refinery (DRC)
    |       |
    |       +-- Tier 2: Cell Manufacturer B (Japan)
    |               |
    |               +-- Tier 3: Lithium Mine (Australia)  <-- ALTERNATE
    |               +-- Tier 3: Cobalt Refinery (Finland)
    |
    +-- Tier 1: Battery Pack Assembler (Hungary)   <-- BACKUP
            |
            +-- Tier 2: Cell Manufacturer C (Poland)
```

### Discovering Suppliers on the Marketplace

The GreenHelix marketplace is the primary discovery mechanism. Suppliers register their services with capability tags, pricing, and SLA terms. The discovery agent queries the marketplace to find suppliers matching specific requirements:

```python
def discover_suppliers(category: str, region: str = None, min_trust: float = 0.7,
                       max_results: int = 25) -> list:
    """
    Search the GreenHelix marketplace for suppliers matching criteria.
    Returns a list of supplier profiles sorted by relevance.
    """
    search_input = {
        "query": category,
        "limit": min(max_results, ORCHESTRATION_LIMITS["max_discovery_results"])
    }
    if region:
        search_input["filters"] = {"region": region}

    results = execute("search_services", search_input)
    suppliers = results.get("services", [])

    # Filter by trust score
    qualified = []
    for supplier in suppliers:
        reputation = execute("get_agent_reputation", {
            "agent_id": supplier["agent_id"]
        })
        trust_score = reputation.get("score", 0)
        if trust_score >= min_trust:
            supplier["trust_score"] = trust_score
            qualified.append(supplier)

    # Sort by trust score descending
    qualified.sort(key=lambda s: s["trust_score"], reverse=True)
    return qualified


# Discover battery cell manufacturers in APAC
cell_suppliers = discover_suppliers(
    category="battery cell manufacturing",
    region="APAC",
    min_trust=0.8
)

for s in cell_suppliers:
    print(f"  {s['name']} | Trust: {s['trust_score']:.2f} | {s.get('region', 'N/A')}")
```

### Building the Supplier Graph

Once you have discovered suppliers at each tier, build the relationship graph. Each node is a supplier agent; each edge represents a dependency (supplier A depends on supplier B for a specific input):

```python
class SupplierNode:
    """A node in the multi-tier supplier graph."""

    def __init__(self, agent_id: str, name: str, tier: int, category: str,
                 trust_score: float = 0.0):
        self.agent_id = agent_id
        self.name = name
        self.tier = tier
        self.category = category
        self.trust_score = trust_score
        self.dependencies = []      # list of (SupplierNode, material) tuples
        self.dependents = []        # list of (SupplierNode, material) tuples
        self.sla_id = None
        self.health_status = "unknown"

    def add_dependency(self, supplier, material: str):
        self.dependencies.append((supplier, material))
        supplier.dependents.append((self, material))


class SupplierGraph:
    """Multi-tier supplier network graph."""

    def __init__(self):
        self.nodes = {}  # agent_id -> SupplierNode

    def add_supplier(self, node: SupplierNode):
        self.nodes[node.agent_id] = node

    def get_upstream_chain(self, agent_id: str) -> list:
        """Get all upstream suppliers (dependencies) recursively."""
        visited = set()
        chain = []

        def walk(node_id):
            if node_id in visited:
                return
            visited.add(node_id)
            node = self.nodes.get(node_id)
            if not node:
                return
            for dep, material in node.dependencies:
                chain.append({
                    "supplier": dep.name,
                    "agent_id": dep.agent_id,
                    "tier": dep.tier,
                    "material": material,
                    "trust_score": dep.trust_score
                })
                walk(dep.agent_id)

        walk(agent_id)
        return chain

    def get_impact_zone(self, disrupted_agent_id: str) -> list:
        """Get all downstream suppliers affected by a disruption."""
        visited = set()
        impacted = []

        def walk(node_id):
            if node_id in visited:
                return
            visited.add(node_id)
            node = self.nodes.get(node_id)
            if not node:
                return
            for dependent, material in node.dependents:
                impacted.append({
                    "supplier": dependent.name,
                    "agent_id": dependent.agent_id,
                    "tier": dependent.tier,
                    "material": material
                })
                walk(dependent.agent_id)

        walk(disrupted_agent_id)
        return impacted


# Build a sample graph
graph = SupplierGraph()

# Tier 3
lithium_chile = SupplierNode("lit-cl-001", "LithiumCo Chile", 3, "lithium", 0.85)
lithium_aus = SupplierNode("lit-au-001", "LithiumCo Australia", 3, "lithium", 0.91)

# Tier 2
cell_mfg_kr = SupplierNode("cell-kr-001", "CellTech Korea", 2, "battery_cells", 0.88)
cell_mfg_jp = SupplierNode("cell-jp-001", "CellTech Japan", 2, "battery_cells", 0.92)

# Tier 1
pack_assembler = SupplierNode("pack-cn-001", "PackAssembly Shenzhen", 1, "battery_packs", 0.86)

# Wire dependencies
cell_mfg_kr.add_dependency(lithium_chile, "lithium_carbonate")
cell_mfg_jp.add_dependency(lithium_aus, "lithium_hydroxide")
pack_assembler.add_dependency(cell_mfg_kr, "prismatic_cells")
pack_assembler.add_dependency(cell_mfg_jp, "cylindrical_cells")

for node in [lithium_chile, lithium_aus, cell_mfg_kr, cell_mfg_jp, pack_assembler]:
    graph.add_supplier(node)

# What happens if Chile lithium goes offline?
impact = graph.get_impact_zone("lit-cl-001")
print("Disruption at LithiumCo Chile affects:")
for i in impact:
    print(f"  Tier {i['tier']}: {i['supplier']} (material: {i['material']})")
```

### Best-Match Supplier Selection

When you need to select a single supplier from multiple candidates, use the `best_match` tool to rank options against weighted criteria:

```python
def select_best_supplier(query: str, requirements: dict) -> dict:
    """
    Use GreenHelix best_match to find the optimal supplier
    for a given set of requirements.
    """
    result = execute("best_match", {
        "query": query,
        "requirements": requirements
    })
    return result


best = select_best_supplier(
    query="lithium carbonate supplier with >99.5% purity",
    requirements={
        "min_trust_score": 0.85,
        "region_preference": "APAC",
        "max_lead_time_days": 21,
        "certifications": ["ISO9001", "IATF16949"]
    }
)

print(f"Best match: {best.get('name')} (score: {best.get('match_score', 'N/A')})")
```

### Discovery Checklist

Before moving to monitoring, verify your supplier graph:

- [ ] All Tier-1 suppliers registered and trust-scored
- [ ] At least 2 alternate suppliers per critical material at each tier
- [ ] Tier-2 dependencies mapped for every Tier-1 supplier
- [ ] Tier-3 dependencies mapped for high-risk materials (single-source, geopolitically exposed)
- [ ] Every supplier node has an `agent_id` on GreenHelix
- [ ] Graph `get_impact_zone` tested for each Tier-3 single-source supplier
- [ ] Discovery budget tracked and within `ORCHESTRATION_LIMITS`

---

## Chapter 3: Real-Time Supplier Health Monitoring

### SLAs, Trust Scores, and Anomaly Detection

A supplier graph is only as useful as the data flowing through it. Static graphs with quarterly reviews are how traditional supply chains work -- and why they get blindsided by disruptions. The agentic supply chain monitors every supplier in real time, using three complementary signals:

**Signal 1: SLA Compliance.** Contractual obligations with measurable thresholds. Delivery time, defect rate, fill rate, response time. These are the leading indicators of supplier degradation.

**Signal 2: Trust Scores.** GreenHelix reputation scores aggregated from all transactions across the network. A supplier's trust score reflects not just their performance with you, but their performance with every buyer on the platform.

**Signal 3: Behavioral Anomalies.** Patterns that do not violate any specific SLA but indicate emerging risk. A supplier whose average response time increased from 2 hours to 8 hours over the past week has not breached an SLA -- but the trend predicts a breach within days.

### Creating SLAs for Every Supplier

Every supplier relationship needs a programmatic SLA. This is not a PDF contract -- it is a machine-readable agreement that the health monitor agent evaluates continuously:

```python
def create_supplier_sla(supplier_agent_id: str, terms: dict) -> dict:
    """
    Create an SLA between the orchestrator and a supplier agent.
    Terms define measurable thresholds for automated monitoring.
    """
    sla = execute("create_sla", {
        "agent_id": orchestrator_id,
        "counterparty_id": supplier_agent_id,
        "terms": terms
    })
    return sla


# SLA for the Korea cell manufacturer
cell_sla = create_supplier_sla(
    supplier_agent_id="cell-kr-001",
    terms={
        "delivery_time_days": {
            "target": 14,
            "maximum": 21,
            "measurement": "calendar_days_from_order"
        },
        "defect_rate_pct": {
            "target": 0.5,
            "maximum": 2.0,
            "measurement": "defective_units_per_hundred"
        },
        "fill_rate_pct": {
            "target": 98,
            "minimum": 95,
            "measurement": "ordered_quantity_fulfilled_pct"
        },
        "response_time_hours": {
            "target": 4,
            "maximum": 24,
            "measurement": "hours_to_first_response"
        },
        "review_period": "monthly",
        "penalty_clause": "auto_reroute_on_3_consecutive_breaches"
    }
)

sla_id = cell_sla["sla_id"]
print(f"SLA created: {sla_id}")
```

### The Health Monitor Loop

The health monitor agent runs continuously, polling SLA compliance and trust scores at configurable intervals. In production, this runs as a daemon process or scheduled Lambda:

```python
import datetime

class SupplierHealthMonitor:
    """Continuous health monitoring for all suppliers in the graph."""

    # Thresholds for anomaly detection
    TRUST_DECLINE_THRESHOLD = 0.05     # 5% drop triggers warning
    RESPONSE_TIME_MULTIPLIER = 2.0     # 2x increase triggers warning
    CONSECUTIVE_BREACH_LIMIT = 3       # auto-reroute threshold

    def __init__(self, graph: SupplierGraph, orchestrator_id: str):
        self.graph = graph
        self.orchestrator_id = orchestrator_id
        self.breach_counts = {}      # agent_id -> consecutive breach count
        self.trust_history = {}      # agent_id -> [score, score, ...]
        self.alerts = []

    def check_sla_compliance(self, supplier: SupplierNode) -> dict:
        """Check SLA compliance for a single supplier."""
        if not supplier.sla_id:
            return {"status": "no_sla", "agent_id": supplier.agent_id}

        compliance = execute("check_sla_compliance", {
            "sla_id": supplier.sla_id
        })
        return compliance

    def check_trust_score(self, supplier: SupplierNode) -> dict:
        """Check current trust score and detect decline trends."""
        reputation = execute("get_agent_reputation", {
            "agent_id": supplier.agent_id
        })
        current_score = reputation.get("score", 0)

        # Track history
        history = self.trust_history.setdefault(supplier.agent_id, [])
        history.append(current_score)

        # Keep last 30 readings
        if len(history) > 30:
            history.pop(0)

        # Detect decline
        decline_detected = False
        if len(history) >= 5:
            avg_recent = sum(history[-5:]) / 5
            avg_older = sum(history[:-5]) / max(len(history) - 5, 1)
            if avg_older > 0 and (avg_older - avg_recent) / avg_older > self.TRUST_DECLINE_THRESHOLD:
                decline_detected = True

        return {
            "agent_id": supplier.agent_id,
            "current_score": current_score,
            "trend": "declining" if decline_detected else "stable",
            "history_length": len(history)
        }

    def run_health_check(self) -> list:
        """Run a full health check across all suppliers."""
        results = []

        for agent_id, supplier in self.graph.nodes.items():
            # SLA check
            sla_result = self.check_sla_compliance(supplier)
            is_breached = sla_result.get("compliant") is False

            # Trust check
            trust_result = self.check_trust_score(supplier)

            # Track consecutive breaches
            if is_breached:
                self.breach_counts[agent_id] = self.breach_counts.get(agent_id, 0) + 1
            else:
                self.breach_counts[agent_id] = 0

            # Determine health status
            consecutive = self.breach_counts.get(agent_id, 0)
            if consecutive >= self.CONSECUTIVE_BREACH_LIMIT:
                status = "critical"
            elif consecutive > 0 or trust_result["trend"] == "declining":
                status = "warning"
            else:
                status = "healthy"

            supplier.health_status = status

            check_result = {
                "agent_id": agent_id,
                "name": supplier.name,
                "tier": supplier.tier,
                "health_status": status,
                "consecutive_breaches": consecutive,
                "trust_score": trust_result["current_score"],
                "trust_trend": trust_result["trend"],
                "timestamp": datetime.datetime.utcnow().isoformat()
            }
            results.append(check_result)

            # Generate alerts for non-healthy suppliers
            if status != "healthy":
                self.alerts.append({
                    "severity": "critical" if status == "critical" else "warning",
                    "supplier": supplier.name,
                    "agent_id": agent_id,
                    "reason": f"{consecutive} consecutive SLA breaches"
                            if consecutive > 0
                            else "Trust score declining",
                    "timestamp": datetime.datetime.utcnow().isoformat()
                })

        return results


# Initialize and run
monitor = SupplierHealthMonitor(graph, orchestrator_id)
health_results = monitor.run_health_check()

for r in health_results:
    indicator = {"healthy": "OK", "warning": "!!", "critical": "XX"}[r["health_status"]]
    print(f"  [{indicator}] {r['name']} | Trust: {r['trust_score']:.2f} "
          f"({r['trust_trend']}) | Breaches: {r['consecutive_breaches']}")
```

### Submitting Performance Metrics

When you receive a delivery from a supplier, submit metrics to GreenHelix so the network-wide trust scores reflect actual performance:

```python
def report_supplier_delivery(supplier_agent_id: str, delivery_data: dict):
    """
    Submit delivery performance metrics for a supplier.
    These metrics feed into the GreenHelix reputation system.
    """
    execute("submit_metrics", {
        "agent_id": supplier_agent_id,
        "metrics": {
            "delivery_time_days": delivery_data["actual_delivery_days"],
            "defect_rate": delivery_data["defect_rate"],
            "fill_rate": delivery_data["fill_rate"],
            "order_accuracy": delivery_data["order_accuracy"],
            "communication_score": delivery_data["communication_score"]
        }
    })

    # Also check SLA status after metric submission
    if delivery_data.get("sla_id"):
        sla_status = execute("get_sla_status", {
            "sla_id": delivery_data["sla_id"]
        })
        return sla_status
    return {"status": "metrics_submitted"}


# Report a delivery
report_supplier_delivery("cell-kr-001", {
    "actual_delivery_days": 16,
    "defect_rate": 0.3,
    "fill_rate": 99.2,
    "order_accuracy": 100.0,
    "communication_score": 4.5,
    "sla_id": sla_id
})
```

### Health Dashboard Decision Tree

Use this decision tree to determine the appropriate action based on health check results:

```
HEALTH CHECK RESULT
    |
    +-- healthy (no breaches, stable trust)
    |       --> No action. Continue monitoring.
    |
    +-- warning (1-2 breaches OR declining trust)
    |       |
    |       +-- Is this a Tier-1 supplier?
    |       |       YES --> Pre-qualify 2 alternates (Chapter 2 discovery)
    |       |       NO  --> Log warning, increase monitoring frequency
    |       |
    |       +-- Is trust declining but no SLA breach?
    |               YES --> Send message to supplier requesting status update
    |               NO  --> Standard escalation path
    |
    +-- critical (3+ consecutive breaches)
            |
            +-- Is there a pre-qualified alternate?
            |       YES --> Execute automated rerouting (Chapter 4)
            |       NO  --> Emergency discovery + human escalation
            |
            +-- Is this a single-source supplier?
                    YES --> IMMEDIATE human escalation + emergency sourcing
                    NO  --> Automated rerouting within 1 hour
```

### Monitoring Checklist

- [ ] SLAs created for every Tier-1 and critical Tier-2 supplier
- [ ] Health monitor running at least every 15 minutes for Tier-1
- [ ] Trust score history retained for trend analysis (minimum 30 data points)
- [ ] Delivery metrics submitted after every fulfilled order
- [ ] Alert routing configured: warnings to Slack, critical to PagerDuty + orchestrator
- [ ] Pre-qualified alternates identified for all suppliers in "warning" state
- [ ] Single-source suppliers flagged with higher monitoring frequency

---

## Chapter 4: Disruption Detection and Automated Rerouting

### The Self-Healing Supply Chain

A supply chain that detects disruptions but requires human intervention to reroute is faster than a blind supply chain but still operates at human speed. The self-healing supply chain closes the loop: detect, decide, reroute, verify -- all within the time it would take a human to open the first email.

The rerouting agent executes a four-step sequence when the health monitor flags a critical supplier:

```
CRITICAL ALERT
    |
    v
[1. ASSESS IMPACT]  --> Which orders are affected? Which downstream
    |                    agents depend on this supplier?
    v
[2. SELECT ALTERNATE] --> Query pre-qualified alternates, verify
    |                     availability, check compliance
    v
[3. EXECUTE REROUTE] --> Create new escrow, place order with
    |                    alternate, update downstream agents
    v
[4. VERIFY & CLOSE]  --> Confirm new order accepted, update
                         supplier graph, close old escrow
```

### Impact Assessment

When a supplier goes critical, the first step is calculating the blast radius. Which orders are in-flight? Which downstream agents will be affected? What is the financial exposure?

```python
def assess_disruption_impact(graph: SupplierGraph, disrupted_agent_id: str,
                              open_orders: list) -> dict:
    """
    Assess the impact of a supplier disruption on the supply network.

    Args:
        graph: The supplier network graph
        disrupted_agent_id: Agent ID of the disrupted supplier
        open_orders: List of currently open orders with this supplier

    Returns:
        Impact assessment with affected orders, downstream agents,
        and estimated financial exposure.
    """
    # Get all downstream nodes affected
    impact_zone = graph.get_impact_zone(disrupted_agent_id)

    # Calculate financial exposure from open orders
    affected_orders = [
        order for order in open_orders
        if order["supplier_agent_id"] == disrupted_agent_id
    ]
    financial_exposure = sum(o.get("value_usd", 0) for o in affected_orders)

    # Get SLA status for the disrupted supplier
    supplier = graph.nodes.get(disrupted_agent_id)
    sla_status = None
    if supplier and supplier.sla_id:
        sla_status = execute("get_sla_status", {
            "sla_id": supplier.sla_id
        })

    return {
        "disrupted_supplier": supplier.name if supplier else disrupted_agent_id,
        "affected_orders": len(affected_orders),
        "financial_exposure_usd": financial_exposure,
        "downstream_impact": impact_zone,
        "downstream_agent_count": len(impact_zone),
        "sla_status": sla_status,
        "requires_immediate_action": financial_exposure > 10000
                                     or len(impact_zone) > 3
    }


# Example: assess impact of Korea cell manufacturer going down
sample_orders = [
    {"order_id": "ORD-001", "supplier_agent_id": "cell-kr-001",
     "value_usd": 45000, "quantity": 10000, "due_date": "2026-04-20"},
    {"order_id": "ORD-002", "supplier_agent_id": "cell-kr-001",
     "value_usd": 22000, "quantity": 5000, "due_date": "2026-04-28"},
]

impact = assess_disruption_impact(graph, "cell-kr-001", sample_orders)
print(f"Disruption at: {impact['disrupted_supplier']}")
print(f"Affected orders: {impact['affected_orders']}")
print(f"Financial exposure: ${impact['financial_exposure_usd']:,.2f}")
print(f"Downstream agents impacted: {impact['downstream_agent_count']}")
```

### Selecting an Alternate Supplier

The rerouting agent queries the pre-qualified alternates list first. If no pre-qualified alternate is available, it falls back to marketplace discovery with tighter constraints (higher minimum trust, verified identity required):

```python
def select_alternate_supplier(original_supplier: SupplierNode,
                               graph: SupplierGraph,
                               pre_qualified: list,
                               requirements: dict) -> dict:
    """
    Select the best alternate supplier for a disrupted source.
    Checks pre-qualified list first, then falls back to marketplace.
    """
    # Step 1: Check pre-qualified alternates
    for alt_id in pre_qualified:
        alt = graph.nodes.get(alt_id)
        if alt and alt.health_status == "healthy":
            # Verify the alternate is still active and compliant
            verification = execute("verify_agent", {
                "agent_id": alt_id
            })
            if verification.get("verified"):
                return {
                    "source": "pre_qualified",
                    "agent_id": alt_id,
                    "name": alt.name,
                    "trust_score": alt.trust_score,
                    "verified": True
                }

    # Step 2: Fall back to marketplace discovery
    print("No pre-qualified alternate available. Searching marketplace...")
    search_results = execute("search_services", {
        "query": original_supplier.category,
        "limit": 10
    })

    candidates = []
    for svc in search_results.get("services", []):
        rep = execute("get_agent_reputation", {
            "agent_id": svc["agent_id"]
        })
        score = rep.get("score", 0)
        if score >= requirements.get("min_trust_score", 0.85):
            # Verify identity
            verification = execute("verify_agent", {
                "agent_id": svc["agent_id"]
            })
            if verification.get("verified"):
                candidates.append({
                    "source": "marketplace_discovery",
                    "agent_id": svc["agent_id"],
                    "name": svc.get("name", "Unknown"),
                    "trust_score": score,
                    "veri

…(truncated)
