# How Paperclip Board Approval Workflows and Governance Gates Function for Agent Hires

> Learn how Paperclip board approval workflows and governance gates ensure policy checks, budget compliance, and explicit board approval for every agent hire before activation.

- Repository: [Paperclip/paperclip](https://github.com/paperclipai/paperclip)
- Tags: how-to-guide
- Published: 2026-08-18

---

**Paperclip enforces a multi-step governance process where every agent hire creates a draft agent in `pending_approval` status and a linked `hire_agent` approval record that must pass company policy checks, budget gates, and explicit board approval before activation.**

The Paperclip platform treats agent hiring as a privileged operation requiring organizational oversight. Whether triggered via CLI, API, or agent-to-agent calls, the system routes all hire requests through a structured **approval workflow** designed to enforce budget constraints, board governance, and auditability. This article examines the complete lifecycle—from draft creation through final activation—based on the Paperclip source code implementation.

## Overview of the Agent Hire Approval Process

When an agent or board member initiates a hire, Paperclip does not immediately create an active agent. Instead, it establishes two linked records: a **draft agent** with frozen configuration and an **approval object** that tracks the governance decision. This separation allows boards to review, modify, or reject proposals without affecting operational agents.

The approval system centralizes around three core concepts:
- **Approval types**: Categorized by operation (`hire_agent`, `budget_change`, etc.)
- **Governance gates**: Automated policy checks (budget limits, role conflicts)
- **Board decisions**: Human or delegated authority to approve, reject, or request revisions

## Step 1: Draft Agent Creation and Approval Record Generation

Upon receiving a hire request, [`server/src/services/approvals.ts`](https://github.com/paperclipai/paperclip/blob/main/server/src/services/approvals.ts) instantiates a draft agent with status `pending_approval`. Simultaneously, it writes a record to the `approvals` table with `type: "hire_agent"` containing a complete payload snapshot.

The payload schema—defined as `HireAgentPayload` in the type system—captures:

```typescript
// Representative payload structure for hire_agent approvals
{
  type: "hire_agent",
  payload: {
    name: "Research Analyst",
    role: "Research Analyst",
    budget: 3000,
    capabilities: ["search", "summarize"],
    reporting_to: "manager-agent-id",  // optional hierarchy
  }
}

```

This snapshot ensures board members review exactly what was proposed, even if subsequent configuration changes occur elsewhere in the system.

## Step 2: Company Policy Evaluation and Board Approval Requirements

Each Paperclip company configures governance through policies stored in the company settings. The `require_approval` policy (documented in [`docs/guides/board-operator/approvals.md`](https://github.com/paperclipai/paperclip/blob/main/docs/guides/board-operator/approvals.md)) determines which operation types demand board review.

When `require_approval` is enabled for `hire_agent` types:
- The approval status remains `pending` indefinitely
- No lifecycle hooks execute
- The draft agent cannot transition to `active`

If the policy is disabled, the system may auto-approve routine hires while still logging the decision for audit purposes.

## Step 3: Governance Gates and Budget Enforcement

Before any approval reaches the board, [`server/src/services/approvals.ts`](https://github.com/paperclipai/paperclip/blob/main/server/src/services/approvals.ts) executes automated **governance gates**. The primary gate is **budget validation**:

1. The system sums the proposed agent's budget against existing committed budgets
2. If the total exceeds the company budget cap, the approval status shifts to `revision_requested`
3. The board must either reduce the proposed budget or explicitly authorize a `budget_override`

Additional gates may check for:
- Role hierarchy violations (circular reporting chains)
- Capability conflicts with existing agents
- Rate limits on hire frequency

These gates prevent malformed or excessive requests from consuming board attention while maintaining guardrails.

## Step 4: Board Review and Decision Lifecycle

Board members interact with pending approvals through the Paperclip UI, specifically via the **Approvals** navigation tab. The [`ui/src/components/ApprovalPayload.tsx`](https://github.com/paperclipai/paperclip/blob/main/ui/src/components/ApprovalPayload.tsx) component renders `hire_agent` payloads in a structured format showing:

- Proposed agent name and role
- Budget allocation
- Capability grants
- Proposed reporting structure

Board members have three resolution options:

| Action | System Effect |
|--------|---------------|
| **Approve** | Triggers `onHireApproved` hook; agent status → `active` |
| **Reject** | Draft agent deleted or marked `rejected`; approval status → `rejected` |
| **Request Revision** | Approval status → `revision_requested`; original requester notified |

Upon approval, the approval service in [`server/src/services/approvals.ts`](https://github.com/paperclipai/paperclip/blob/main/server/src/services/approvals.ts) orchestrates:
1. Status transition to `approved`
2. Draft agent activation
3. `onHireApproved` lifecycle hook invocation
4. Activity log writes for audit trails

## Step 5: Lifecycle Hook Execution and Post-Approval Configuration

The `onHireApproved` hook—defined in [`packages/adapter-utils/src/types.ts`](https://github.com/paperclipai/paperclip/blob/main/packages/adapter-utils/src/types.ts) at line 311—allows adapter developers to execute custom logic when hires complete:

```typescript
// Hook implementation in adapter-managed-agents.ts
export const onHireApproved = async ({
  agentId,
  companyId,
}: { agentId: string; companyId: string }) => {
  // Perform post-hire configuration
  await grantPermissions(agentId, { role: "analyst" });
  await provisionResources(agentId, { computeTier: "standard" });
};

```

This hook runs after board approval but before the agent begins accepting tasks, enabling secure initialization of credentials, resources, or external integrations.

## Step 6: Rejection Handling and Approval Cleanup

When a board rejects a hire, the system performs cleanup based on configuration:

- **Hard deletion**: Draft agent removed; approval record retained with `rejected` status for audit
- **Soft retention**: Draft agent marked `rejected` with tombstone timestamp

The system also handles superseded requests. If a newer hire request overlaps with a pending approval for the same role or purpose, the migration logic (referenced in [`built-in-agent-unique-marker-migration.sql`](https://github.com/paperclipai/paperclip/blob/main/built-in-agent-unique-marker-migration.sql)) cancels orphan approvals with the comment: *"cancel each duplicate's orphan pending hire_agent approval"*.

## Idempotency and Concurrency Guarantees

The approval service is designed for safe concurrent access. As verified in [`approval-routes-idempotency.test.ts`](https://github.com/paperclipai/paperclip/blob/main/approval-routes-idempotency.test.ts), repeated approval attempts for the same `hire_agent` approval ID are deduplicated at the database level. This prevents race conditions where multiple board members simultaneously approve the same request, which could otherwise create duplicate active agents.

## CLI and API Integration

Operators can manage the full approval lifecycle programmatically:

**Create a hire approval via CLI:**

```bash
npx paperclipai approval create \
  --company-id <company-id> \
  --type hire_agent \
  --payload '{"name":"New Analyst","role":"Research Analyst","budget":5000}'

```

**Approve via CLI:**

```bash
npx paperclipai approval update \
  --approval-id <approval-id> \
  --status approved

```

**API equivalent:**

```typescript
// POST /api/approvals — Create hire approval
await fetch(`${API_URL}/approvals`, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    type: "hire_agent",
    payload: {
      name: "Research Analyst",
      role: "Research Analyst",
      budget: 3000,
      capabilities: ["search", "summarize"],
    },
  }),
});

```

The CLI implementation resides in [`cli/src/commands/client/approval.ts`](https://github.com/paperclipai/paperclip/blob/main/cli/src/commands/client/approval.ts), which wraps the REST endpoints defined in [`server/src/routes/approvals.ts`](https://github.com/paperclipai/paperclip/blob/main/server/src/routes/approvals.ts).

## Key Source Files and Their Roles

- **[`server/src/services/approvals.ts`](https://github.com/paperclipai/paperclip/blob/main/server/src/services/approvals.ts)**: Core state machine; implements budget gates, status transitions, and hook orchestration
- **[`server/src/routes/approvals.ts`](https://github.com/paperclipai/paperclip/blob/main/server/src/routes/approvals.ts)**: REST API surface for CRUD operations on approval records
- **[`packages/adapter-utils/src/types.ts`](https://github.com/paperclipai/paperclip/blob/main/packages/adapter-utils/src/types.ts)**: TypeScript definitions for `onHireApproved` and related payloads
- **[`ui/src/components/ApprovalPayload.tsx`](https://github.com/paperclipai/paperclip/blob/main/ui/src/components/ApprovalPayload.tsx)**: Board-facing UI for rendering hire proposals
- **[`cli/src/commands/client/approval.ts`](https://github.com/paperclipai/paperclip/blob/main/cli/src/commands/client/approval.ts)**: Operator tooling for approval management
- **[`docs/guides/board-operator/approvals.md`](https://github.com/paperclipai/paperclip/blob/main/docs/guides/board-operator/approvals.md)**: Human documentation for governance configuration

## Summary

- **Every agent hire creates a `pending_approval` draft and a linked `hire_agent` approval record**, ensuring no agent activates without oversight
- **Company policies in `require_approval` determine whether board review is mandatory** for specific operation types
- **Automated governance gates**—primarily budget validation with override capabilities—filter requests before board review
- **Board decisions trigger the `onHireApproved` lifecycle hook**, enabling adapters to configure credentials and resources
- **The system guarantees idempotency and proper cleanup** of rejected or superseded approvals through database constraints and migration logic
- **Full programmatic access** via CLI and API allows integration with external HR or procurement systems

## Frequently Asked Questions

### What happens if a hire request exceeds the company budget?

The approval status automatically transitions to `revision_requested`. The board must either reduce the proposed budget in the payload or explicitly provide a `budget_override` authorization. Until resolved, the draft agent remains inactive and no lifecycle hooks execute.

### Can agents hire other agents without board approval?

If the company policy `require_approval` for `hire_agent` operations is disabled, agents can hire subordinates autonomously. However, governance gates still apply—budget constraints may trigger revision requests even without mandatory board review. The policy granularity allows organizations to balance agility with control.

### How does the `onHireApproved` hook differ from general agent initialization?

The `onHireApproved` hook runs after board approval but before task acceptance, whereas general initialization occurs at agent process startup. This sequencing allows the hook to provision resources that require governance authorization—such as API keys with elevated permissions or budget-enforced service accounts—that should not be available during pre-approval phases.

### What prevents duplicate agents from concurrent approvals?

The approval service implements database-level idempotency constraints verified by [`approval-routes-idempotency.test.ts`](https://github.com/paperclipai/paperclip/blob/main/approval-routes-idempotency.test.ts). Multiple simultaneous approval attempts for the same approval ID collapse to a single successful transaction. The draft agent record includes unique markers that prevent re-activation of already-processed hires.