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:

  1. Customer request: “Withdraw 50,000 TL from my account”
  2. transfer_processor (AGENT): Validates the request, checks compliance, sends to bank
  3. approval_manager (HUMAN, Finance Manager): Manually reviews flagged transactions (>100K or new customers)
  4. 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:

  1. transfer_processor now escalates amounts >50K to the Finance Manager
  2. 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:

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:

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

  1. Work division is explicit: Which does the agent do? Which does the human?
  2. Policies are file-based: Versioned in Git, approved via PR
  3. Approval roles are defined: Who has veto rights?
  4. Logs are complete: Every step shows who did what
  5. 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.