Why Agent Management Fails Without policy.md

Why Agent Management Fails Without policy.md

We talked in recent days: every agent should have a place in your org chart, with a clear owner. But that only tells you who is accountable. It does not tell you what the agent will do, what rules it must follow.

Imagine a manager hires a new sales rep. On day one, what does the manager say? “I want you to bring in new customers.” Is that enough? No. The new hire also needs to know:

These questions need written answers. For an autonomous agent, this file is called policy.md.

policy.md: The Written Operating Rules

Especially for an autonomous (non-human) agent, policy.md is critical. The agent cannot chat, cannot observe a situation and adapt. When it receives a task, it looks to the code — and the code looks to policy.md.

An example policy.md:

# Agent: Support Ticket Triage Agent (support_triager_001)

## Responsibility
- Classify incoming support tickets by priority level
- Distinguish product bugs from user errors
- Escalate critical failures to engineering immediately

## Access (Skills)
- Tool: Support ticket API (read/write)
- Tool: Slack (team notification)
- Limit: Do not process more than 1,000 tickets per week
- Blocked: Write access to customer records, invoice processing

## Error Handling
- Unclear ticket: Ask the team via Slack
- Same issue appears in 3+ tickets: Mark as "recurring issue"
- Missing data: Send auto-reply to customer, ask to complete

## Reporting
- Daily: Post summary to Slack #support-ops (ticket count, classification, avg response time)
- Weekly: Upload trend data to spreadsheet (patterns, new issue types)

With this policy, the agent knows:

An Agent’s Lifecycle: Draft, Active, Retired

An agent does not go live in production on day one.

Draft Newly built, developer tested, but not yet approved by the organization. The policy.md may be incomplete, skills not fully validated. Lives in a Git branch, not main. Production systems do not run this agent yet.

Active policy.md is complete, tests pass, owner says “I accept this responsibility.” Marked status: active in config. In Git main. Doing real work. If it fails, the owner answers for it.

Inactive No longer needed. Maybe another agent does the job better, or the job is no longer needed. We do not delete it — it stays in Git history. But marked status: inactive. Perhaps we will need it again.

agents:
  support_triager_001:
    name: "Support Ticket Triage Agent"
    owner: "person_Ali_Support"
    status: active
    created: 2026-08-20
    policy: "policy/support_triager_001.md"
    
  old_report_bot:
    name: "Old Report Generator"
    owner: "person_Zeynep_Analytics"
    status: inactive
    created: 2025-06-10
    retired: 2026-08-15
    policy: "policy/old_report_bot.md"

What does this design give you? Accountability. Every agent has an owner. Every agent’s rules are in Git. If rules change, a human reviews it in a PR. Who did what, why, and who is responsible is traceable.

Agent Skill Types: Each Carries Different Risks

Regardless of which tools an agent uses, each type must be controlled differently.

builtin — Written directly in the agent’s code

mcp (Model Context Protocol) — External system via standard interface

http — Free-form HTTP call

function — External code (Python/Node.js)

skills:
  - type: builtin
    name: "ticket_categorize"
    
  - type: mcp
    name: "slack_notify"
    config:
      channel: "#support-ops"
      
  - type: http
    name: "fetch_customer_data"
    config:
      base_url: "https://api.internal.our-company/customers"
      timeout: 10
      rate_limit: 100_per_hour
      
  - type: function
    name: "calculate_priority_score"
    config:
      runtime: python
      path: "functions/priority_scorer.py"
      timeout: 5

Each skill must be clearly described in policy.md. “How many times per day can this skill be called?”, “What happens on error?”, “Where do results go?” All must be specified.

Why policy.md and Git Work Together

The policy.md file lives in your config repo, in Git. When it needs to change, someone opens a PR. A human reviews, change is approved or rejected.

This is the only reliable way to say “I tested this agent, no issues.” Because Git history shows exactly who changed what, when, and why — with human approval stamps.

Compare that to: someone writes a custom system prompt for ChatGPT. Nobody knows what it does. If it makes a bad decision? No policy, no accountability, no trail.

But with policy.md in Git, the agent’s rulebook is public. If someone wants to know why this rule exists, they open Git history, see when it was added, see the PR discussion, find the owner.

Tomorrow: How does one agent hand off work to another? A2A delegation, approval flow, result tracking.