|
| 1 | +# Fiduciary Circuit Breaker (FCB) Extension |
| 2 | + |
| 3 | +!!! info |
| 4 | + |
| 5 | + This extension provides structured risk types for AP2 Section 7.4 (Risk Signals). |
| 6 | + |
| 7 | + `v0.1-alpha` (see [roadmap](../roadmap.md)) |
| 8 | + |
| 9 | +## Overview |
| 10 | + |
| 11 | +The **Fiduciary Circuit Breaker (FCB)** is a runtime governance pattern that complements AP2's mandate-based authorization. While mandates prove that an agent has authority to act, FCB monitors *how* the agent exercises that authority in real-time. |
| 12 | + |
| 13 | +### Why FCB? |
| 14 | + |
| 15 | +AP2 mandates validate authority at signing time: |
| 16 | + |
| 17 | +- ✅ "Agent has a valid IntentMandate with $50,000 budget" |
| 18 | +- ✅ "This transaction is within the mandate constraints" |
| 19 | + |
| 20 | +But mandates don't address runtime behaviors: |
| 21 | + |
| 22 | +- ❌ "Agent already spent $30,000 today across 10 transactions" |
| 23 | +- ❌ "Agent is making purchases 3x faster than normal" |
| 24 | +- ❌ "Agent is buying from an unfamiliar vendor in a high-risk region" |
| 25 | + |
| 26 | +FCB fills this gap by providing **cross-transaction behavioral monitoring** that can trip and require human intervention when something looks wrong. |
| 27 | + |
| 28 | +## Conceptual Model |
| 29 | + |
| 30 | +```text |
| 31 | +┌─────────────────────────────────────────────────────────────────────────────┐ |
| 32 | +│ AGENT GOVERNANCE STACK │ |
| 33 | +├─────────────────────────────────────────────────────────────────────────────┤ |
| 34 | +│ │ |
| 35 | +│ Layer 3: RUNTIME GOVERNANCE (FCB) │ |
| 36 | +│ ───────────────────────────────── │ |
| 37 | +│ Question: "Should this action proceed RIGHT NOW?" │ |
| 38 | +│ Evaluates: Cumulative risk, velocity, anomalies, thresholds │ |
| 39 | +│ Output: ALLOW / TRIP (escalate to human) │ |
| 40 | +│ │ |
| 41 | +│ Layer 2: PAYMENT AUTHORIZATION (AP2 Mandates) │ |
| 42 | +│ ───────────────────────────────────────────── │ |
| 43 | +│ Question: "Does agent have cryptographic proof of authority?" │ |
| 44 | +│ Evaluates: User-signed mandates, intent constraints │ |
| 45 | +│ Output: Valid credential / Reject │ |
| 46 | +│ │ |
| 47 | +│ Layer 1: AGENT IDENTITY & DISCOVERY │ |
| 48 | +│ ──────────────────────────────────── │ |
| 49 | +│ Question: "Is this agent authentic?" │ |
| 50 | +│ Evaluates: Agent cards, trust registries │ |
| 51 | +│ Output: Verified identity / Untrusted │ |
| 52 | +│ │ |
| 53 | +└─────────────────────────────────────────────────────────────────────────────┘ |
| 54 | +``` |
| 55 | + |
| 56 | +## FCB States |
| 57 | + |
| 58 | +The FCB operates as a state machine: |
| 59 | + |
| 60 | +| State | Behavior | Entry Condition | |
| 61 | +| ----- | -------- | --------------- | |
| 62 | +| **CLOSED** | Normal operation. Agent acts autonomously. | Initial state; human approves from OPEN; or conditions met from HALF_OPEN | |
| 63 | +| **OPEN** | All actions blocked. Requires human review. | Any trip condition fails from CLOSED; or conditions violated from HALF_OPEN | |
| 64 | +| **HALF_OPEN** | Limited operations with enhanced monitoring. | Human approves with conditions from OPEN | |
| 65 | +| **TERMINATED** | Permanently halted. No recovery. | Human rejects from OPEN; or timeout | |
| 66 | + |
| 67 | +### State Transitions |
| 68 | + |
| 69 | +```text |
| 70 | +CLOSED ──[trip condition fails]──► OPEN |
| 71 | + ▲ │ |
| 72 | + │ ┌─────────────┼─────────────┐ |
| 73 | + │ │ │ │ |
| 74 | + │ [approve] [approve w/conditions] [reject] |
| 75 | + │ │ │ │ |
| 76 | + │ │ ▼ ▼ |
| 77 | + └────────────────────┘ HALF_OPEN TERMINATED |
| 78 | + │ |
| 79 | + ┌─────────┴─────────┐ |
| 80 | + │ │ |
| 81 | + [conditions met] [conditions violated] |
| 82 | + │ │ |
| 83 | + ▼ ▼ |
| 84 | + CLOSED OPEN |
| 85 | +``` |
| 86 | + |
| 87 | +## Trip Conditions |
| 88 | + |
| 89 | +Trip conditions are predicate functions that evaluate agent behavior: |
| 90 | + |
| 91 | +| Type | Description | Example | |
| 92 | +| ---- | ----------- | ------- | |
| 93 | +| `VALUE_THRESHOLD` | Single transaction exceeds limit | Order > $100,000 | |
| 94 | +| `CUMULATIVE_THRESHOLD` | Running total exceeds threshold | Daily spend > $500,000 | |
| 95 | +| `VELOCITY` | Too many actions too quickly | > 10 transactions/minute | |
| 96 | +| `AUTHORITY_SCOPE` | Action outside delegated domain | Modifying payment account | |
| 97 | +| `ANOMALY` | ML model detects unusual pattern | Behavior inconsistent with baseline | |
| 98 | +| `TIME_BASED` | Action during restricted period | Trade outside market hours | |
| 99 | +| `DEVIATION` | Significant departure from baseline | Price 30% below historical average | |
| 100 | +| `VENDOR_TRUST` | Untrusted counterparty | New vendor in high-risk region | |
| 101 | + |
| 102 | +## Usage in AP2 Messages |
| 103 | + |
| 104 | +### Including RiskPayload in Messages |
| 105 | + |
| 106 | +The `RiskPayload` can be attached to any AP2 message via the `risk_data` DataPart: |
| 107 | + |
| 108 | +```json |
| 109 | +{ |
| 110 | + "messageId": "msg_123", |
| 111 | + "parts": [ |
| 112 | + { |
| 113 | + "kind": "data", |
| 114 | + "data": { |
| 115 | + "ap2.mandates.PaymentMandate": { ... }, |
| 116 | + "ap2.risk.RiskPayload": { |
| 117 | + "fcb_evaluation": { |
| 118 | + "fcb_state": "CLOSED", |
| 119 | + "trips_evaluated": 8, |
| 120 | + "trips_triggered": 0, |
| 121 | + "trip_results": [ |
| 122 | + { |
| 123 | + "condition_type": "VALUE_THRESHOLD", |
| 124 | + "status": "PASS", |
| 125 | + "threshold": 100000, |
| 126 | + "actual_value": 45000 |
| 127 | + }, |
| 128 | + { |
| 129 | + "condition_type": "CUMULATIVE_THRESHOLD", |
| 130 | + "status": "PASS", |
| 131 | + "threshold": 500000, |
| 132 | + "actual_value": 125000 |
| 133 | + } |
| 134 | + ], |
| 135 | + "risk_score": 0.15, |
| 136 | + "evaluated_at": "2026-02-03T14:30:00Z" |
| 137 | + }, |
| 138 | + "agent_modality": "HUMAN_NOT_PRESENT", |
| 139 | + "agent_id": "agent_xyz", |
| 140 | + "agent_type": "B2B_BUYER", |
| 141 | + "session_id": "session_abc123", |
| 142 | + "cumulative_session_value": 125000, |
| 143 | + "transaction_count_today": 3 |
| 144 | + } |
| 145 | + } |
| 146 | + } |
| 147 | + ] |
| 148 | +} |
| 149 | +``` |
| 150 | + |
| 151 | +### FCB Trip with Human Escalation |
| 152 | + |
| 153 | +When FCB trips, the `human_escalation` field captures the escalation flow: |
| 154 | + |
| 155 | +```json |
| 156 | +{ |
| 157 | + "ap2.risk.RiskPayload": { |
| 158 | + "fcb_evaluation": { |
| 159 | + "fcb_state": "HALF_OPEN", |
| 160 | + "previous_state": "OPEN", |
| 161 | + "trips_evaluated": 8, |
| 162 | + "trips_triggered": 2, |
| 163 | + "trip_results": [ |
| 164 | + { |
| 165 | + "condition_type": "CUMULATIVE_THRESHOLD", |
| 166 | + "status": "FAIL", |
| 167 | + "threshold": 500000, |
| 168 | + "actual_value": 525000, |
| 169 | + "message": "Daily cumulative spend exceeds $500,000 limit" |
| 170 | + }, |
| 171 | + { |
| 172 | + "condition_type": "VENDOR_TRUST", |
| 173 | + "status": "WARNING", |
| 174 | + "message": "New vendor not in approved registry" |
| 175 | + } |
| 176 | + ], |
| 177 | + "risk_score": 0.72, |
| 178 | + "human_escalation": { |
| 179 | + "escalation_id": "esc_789", |
| 180 | + "triggered_at": "2026-02-03T14:30:00Z", |
| 181 | + "approver_id": "user_john_smith", |
| 182 | + "decision": "APPROVE_WITH_CONDITIONS", |
| 183 | + "decided_at": "2026-02-03T14:45:00Z", |
| 184 | + "conditions": [ |
| 185 | + "Add vendor to approved registry", |
| 186 | + "Enhanced monitoring for 7 days" |
| 187 | + ], |
| 188 | + "notes": "Approved given strong counterparty history" |
| 189 | + }, |
| 190 | + "evaluated_at": "2026-02-03T14:30:00Z" |
| 191 | + }, |
| 192 | + "agent_modality": "HUMAN_NOT_PRESENT" |
| 193 | + } |
| 194 | +} |
| 195 | +``` |
| 196 | + |
| 197 | +## Python Types |
| 198 | + |
| 199 | +```python |
| 200 | +from ap2.types.risk import ( |
| 201 | + RiskPayload, |
| 202 | + FCBEvaluation, |
| 203 | + FCBState, |
| 204 | + TripConditionResult, |
| 205 | + TripConditionType, |
| 206 | + TripConditionStatus, |
| 207 | + AgentModality, |
| 208 | +) |
| 209 | + |
| 210 | +# Create an FCB evaluation |
| 211 | +evaluation = FCBEvaluation( |
| 212 | + fcb_state=FCBState.CLOSED, |
| 213 | + trips_evaluated=3, |
| 214 | + trips_triggered=0, |
| 215 | + trip_results=[ |
| 216 | + TripConditionResult( |
| 217 | + condition_type=TripConditionType.VALUE_THRESHOLD, |
| 218 | + status=TripConditionStatus.PASS, |
| 219 | + threshold=100000, |
| 220 | + actual_value=45000, |
| 221 | + ) |
| 222 | + ], |
| 223 | + risk_score=0.15, |
| 224 | +) |
| 225 | + |
| 226 | +# Create risk payload |
| 227 | +risk_payload = RiskPayload( |
| 228 | + fcb_evaluation=evaluation, |
| 229 | + agent_modality=AgentModality.HUMAN_NOT_PRESENT, |
| 230 | + agent_id="agent_xyz", |
| 231 | + session_id="session_abc123", |
| 232 | +) |
| 233 | +``` |
| 234 | + |
| 235 | +## Go Types |
| 236 | + |
| 237 | +```go |
| 238 | +import "github.com/google-agentic-commerce/ap2/samples/go/pkg/ap2/types" |
| 239 | + |
| 240 | +// Create an FCB evaluation |
| 241 | +evaluation := types.NewFCBEvaluation(types.FCBStateClosed) |
| 242 | +threshold := 100000.0 |
| 243 | +actualValue := 45000.0 |
| 244 | +riskScore := 0.15 |
| 245 | +evaluation.AddTripResult(types.TripConditionResult{ |
| 246 | + ConditionType: types.TripConditionValueThreshold, |
| 247 | + Status: types.TripConditionStatusPass, |
| 248 | + Threshold: &threshold, |
| 249 | + ActualValue: &actualValue, |
| 250 | +}) |
| 251 | +evaluation.RiskScore = &riskScore |
| 252 | + |
| 253 | +// Create risk payload |
| 254 | +riskPayload := types.NewRiskPayload(types.AgentModalityHumanNotPresent) |
| 255 | +riskPayload.FCBEvaluation = evaluation |
| 256 | +agentID := "agent_xyz" |
| 257 | +riskPayload.AgentID = &agentID |
| 258 | +``` |
| 259 | + |
| 260 | +## Benefits for Payment Ecosystem |
| 261 | + |
| 262 | +### For Merchants |
| 263 | + |
| 264 | +- Real-time visibility into agent behavior before accepting transaction |
| 265 | +- Ability to require higher security for risky transactions |
| 266 | + |
| 267 | +### For Payment Networks |
| 268 | + |
| 269 | +- Standardized risk signals for authorization decisions |
| 270 | +- Clear audit trail of FCB state and human approvals |
| 271 | + |
| 272 | +### For Issuers |
| 273 | + |
| 274 | +- Additional data points for fraud detection |
| 275 | +- Visibility into agent vs. human-initiated transactions |
| 276 | + |
| 277 | +### For Users |
| 278 | + |
| 279 | +- Confidence that agents operate within guardrails |
| 280 | +- Human oversight for exceptional cases |
| 281 | + |
| 282 | +## References |
| 283 | + |
| 284 | +- [AP2 Specification Section 7.4: Risk Signals](../specification.md#74-risk-signals) |
| 285 | +- [Circuit Breaker Pattern - Michael Nygard, Release It! (2007)](https://pragprog.com/titles/mnee2/release-it-second-edition/) |
0 commit comments