When Humans and Agents Work Together: Who Approves? Who Is Responsible?
When Humans and Agents Work Together: Who Approves? Who Is Responsible?
For five days, we’ve given agents structure, policy, and coordination rules. But one question remains: Do agents work alone?
No. In a fintech firm, there’s an agent called “transfer_processor” that handles customer money transfers. One night at midnight, a 1-billion-lira transaction fails. Who’s responsible—the agent, the human, or the system?
Scenario: Mixed Team in Payment Processing
On an e-commerce platform, the transfer flow looks like this:
- Customer request: “Withdraw 50,000 TL from my account”
- transfer_processor (AGENT): Validates the request, checks compliance, sends to bank
- approval_manager (HUMAN, Finance Manager): Manually reviews flagged transactions (>100K or new customers)
- banking_gateway (AGENT): Confirms the bank’s response
Now consider this sequence:
Workflow: Customer Transfer
Input: Customer X, Amount: 50,000 TL
Step 1: transfer_processor (AGENT)
- Account balance check: OK (150K available)
- Daily limit check: OK (limit is 100K, spent 0 today)
- Fraud score: OK (normal pattern)
→ Decision: "Approve and forward to banking_gateway"
Step 2: banking_gateway (AGENT)
- Bank API call executed
- Status: "Pending" (bank processing)
→ Log: 2026-09-10 14:32:15 - Transaction ID TX-2026-0001
Step 3: Bank response arrives
- Status: "REJECTED - Account frozen due to compliance flag"
→ Error: Customer's account is under compliance review; Legal team blocked it
The problem: transfer_processor and banking_gateway have no “compliance freeze” check in their policies. Why? Because compliance data isn’t in their current datasets.
The Finance Manager arrives next morning and says: “Why did you approve this transfer? Yesterday, this customer was flagged in an AML report!”
transfer_processor replies: “My policy doesn’t include compliance checks. I was supposed to approve.”
Solution 1: Work Division and Approval Roles
To solve this, the workflow changes:
policy.md (transfer_processor):
- Skill: Basic transfer validation
- Limits:
- Max 100,000 TL per transaction
- Balance and daily limit checks only
- CANNOT do compliance checks
- Requires approval: If amount > 50K
policy.md (approval_manager HUMAN):
- Role: Finance Manager
- Responsibility: Reject compliance-flagged transactions
- Access: Compliance information system
- Veto power: Can reject any transfer
- File path: /policies/approval_manager.md → versioned in Git
policy.md (banking_gateway):
- Skill: Bank API integration
- Limits: API status checks, logging
- NOTE: Cannot make compliance decisions (human job)
- Error fallback: Escalate to Finance Manager
Two things changed:
- transfer_processor now escalates amounts >50K to the Finance Manager
- approval_manager (HUMAN) makes decisions with compliance data
New Workflow:
Step 1: transfer_processor (AGENT)
→ Check: Amount > 50K? YES
→ Action: "Requires human approval"
→ Forward to: approval_manager
→ Log: "Forwarded for manual review"
Step 2: approval_manager (HUMAN, Finance Manager)
→ Login to dashboard
→ Check: Compliance flag? YES, flag exists
→ Decision: REJECT with reason "Compliance investigation ongoing"
→ Log: "Rejected by approval_manager at 2026-09-10 07:15"
Step 3: transfer_processor (AGENT)
→ Error received: REJECTED
→ Notify customer: "Your account is under review. Please contact support."
→ Log: "Customer notified of rejection"
Solution 2: Config-as-Code and Git Versioning
Here’s the critical part: These policies must be written and versioned.
Repository Structure:
/root/projects/org-config/
├── policies/
│ ├── transfer_processor.md (version: 2.3)
│ ├── approval_manager.md (version: 1.2)
│ └── banking_gateway.md (version: 1.1)
├── workflows/
│ ├── customer_transfer_flow.yaml (version: 3.1)
│ └── compliance_escalation.yaml (version: 2.0)
├── roles/
│ ├── approval_manager.json (Finance Manager definition)
│ └── compliance_officer.json (Legal Advisor definition)
└── git log
└── "Updated transfer_processor policy to add compliance check"
(2026-09-01 by financial_director)
This structure ensures:
- Each policy is a file: It’s tracked and updatable
- Git history: “Who added this rule and when?” can be queried
- PR + Review: Policy changes require another manager’s approval
- Rollback: If a rule was wrong, revert to the old version
Example: Policy Update via PR
The Finance Manager notices: “We should lower the approval threshold from 50K to 30K—fraud is rising.”
GitHub PR #2847:
Title: "Lower transfer approval threshold to 30K due to fraud spike"
Changes:
- File: policies/transfer_processor.md
- Line 15: - Approval required: Amount > 50,000 TL
- To: - Approval required: Amount > 30,000 TL
Reviewer: CEO
Status: APPROVED and merged
Result:
- Merged to main: 2026-09-10 10:00
- All agents auto-load this policy
- Old: >50K requires approval → New: >30K requires approval
Days later: “Why did the threshold suddenly drop to 30K?”
→ Answer: git log policies/transfer_processor.md → PR #2847 → explained.
Solution 3: Responsibility and Human Veto
But here’s another question: When can a human override?
Responsibility Matrix:
Activity | Agent | Human | Veto Rights
----------------------------------|----------------|----------------|------------------
Basic validation (balance, limit) | transfer_proc | | N/A
Compliance check | (no) | approval_mgr | approval_mgr
Fraud scoring | transfer_proc | | approval_mgr can override
Bank API call | banking_gw | (observe log) | approval_mgr can cancel
Customer notification | transfer_proc | (optional) | N/A
Audit logging | banking_gw | compliance_off | (review only, no veto)
“approval_mgr can override” means: for example:
- transfer_processor: “Amount is 50K, needs approval? YES, forwarding.”
- approval_manager: Checks dashboard, no compliance flag. Can:
- “Approve” (standard decision)
- “Approve with note: Customer has pending KYC” (approval with context)
- “Reject and flag account for review” (veto + escalation)
The key part of a veto: It’s logged with a reason.
Audit Log:
2026-09-10 07:20 | transfer_processor | Initiated TX-2026-0042, Amount: 75,000 TL
2026-09-10 07:21 | transfer_processor | Escalated to approval_manager (threshold exceeded)
2026-09-10 07:25 | approval_manager | Reviewed TX-2026-0042
2026-09-10 07:26 | approval_manager | APPROVED with note: "KYC updated, proceeding"
2026-09-10 07:27 | banking_gateway | API call initiated to bank
2026-09-10 07:28 | banking_gateway | Status from bank: PENDING
2026-09-10 08:15 | banking_gateway | Status from bank: CONFIRMED
2026-09-10 08:15 | transfer_processor | Final confirmation sent to customer
Three days later: “Who approved this transfer?”
→ From log: approval_manager, 2026-09-10 07:26, with note “KYC updated”.
Summary: Principles for Mixed Teams
- Work division is explicit: Which does the agent do? Which does the human?
- Policies are file-based: Versioned in Git, approved via PR
- Approval roles are defined: Who has veto rights?
- Logs are complete: Every step shows who did what
- Rollback is possible: Wrong rule applied? Revert to the old version
Without these: something breaks, the Finance Manager and transfer_processor blame each other, neither has clear responsibility.
With these: git log + policy files + audit trail = complete responsibility chain.
Tomorrow: Role + Policy + Delegation + Git versioning synthesis.