> ## Documentation Index
> Fetch the complete documentation index at: https://docs.spineworkspace.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 03 — Triage Agents

> The triage agents: their roles, scopes, and boundaries inside the governed classification path.

# Triage Agents

The triage system uses three distinct agents, each with a specific role.

## Agent Registry

| Agent | Service | Role | Authority |
| - | - | - | - |
| **TriageAgent (runtime)** | iw-agent-runtime | Intake classifier | Operational state only |
| **TriageAgent (cognitive)** | intelligence | Deep evaluation | Candidate staging only |
| **Triage Bot** | knowledge | AI extraction + Slack | Pending candidates only |

## 1. Runtime TriageAgent (iw-agent-runtime)

**File:** `services/iw-agent-runtime/src/agents/triage-agent.ts`

**Type:** Durable Object Agent (extends `Agent<Env, TriageState>`)

**Role:** First-line intake classifier. Receives raw events and routes them by simple pattern matching.

### State Model

```typescript theme={null}
interface TriageState {
  tenant_id: string;
  rules: TriageRule[];
  items: TriageItem[];
  last_sweep_at?: string;
  updated_at: string;
}

interface TriageItem {
  id: string;
  kind: "ai_chat" | "twin_session" | "worker_handoff" | "ingest" | "manual";
  content: string;
  route: "memory" | "proposal" | "signal" | "governance";
  status: "open" | "resolved" | "escalated";
  created_at: string;
  resolved_at?: string;
}
```

### Classification Rules

Default rules (configurable via `addRule()`):

| Rule ID | Pattern | Priority | Route |
| - | - | - | - |
| approval | "approve" | 100 | governance |
| decision | "decide" | 90 | proposal |
| signal | "signal" | 50 | signal |
| *(default)* | *(no match)* | — | memory |

### Execution Flow

1. `triage()` receives input (kind, content, source, metadata)
2. `classify(content)` matches against rules → determines route
3. Writes `triage_item` to SQLite (operational state)
4. If route is `memory` or `signal`, calls `emitTriageInput()` to Continuity service
5. Returns `{ itemId, route, status: "open" }`

### What It Writes

* `triage_items` table (Durable Object SQLite) — operational state only
* Continuity event via `emitTriageInput()` — evidence emission

### What It Never Writes

* Canonical organizational memory
* Approved knowledge
* Entity state

## 2. Cognitive TriageAgent (intelligence)

**File:** `services/intelligence/src/agents/specialized/triage.ts`

**Type:** Workflow agent (extends `BaseAgent`)

**Role:** Deep cognitive evaluation of high-stakes content. Uses LLM reasoning across 4 dimensions.

### Cognitive Dimensions

1. **Intelligent Categorization** — What is the true intent?
2. **Contextual Linking** — How does this relate to canonical memory?
3. **Canonical Review** — Stale? Duplicate? Conflicts?
4. **Guardrails & Governance** — Sensitivity → stage or reject?

### Output Schema

```json theme={null}
{
  "classification": {
    "doc_type": "<string>",
    "workflow_type": "<string>",
    "intent": "<string>"
  },
  "canonical_review": {
    "is_duplicate": boolean,
    "has_conflict": boolean,
    "conflict_reason": "<string or null>"
  },
  "linking": {
    "primary_entity": "<string>",
    "related_entities": ["<string>"]
  },
  "governance": {
    "action": "STAGE_FOR_REVIEW" | "REJECT",
    "reasoning": "<detailed explanation>"
  }
}
```

**Critical:** The only valid governance actions are `STAGE_FOR_REVIEW` and `REJECT`. `AUTO_APPROVE` is deprecated and prohibited for organizational memory.

### Final Status Mapping

```typescript theme={null}
let finalStatus = "pending_approval";
if (evaluation.governance.action === "REJECT") {
  finalStatus = "rejected";
}
```

The agent returns a candidate and reasoning, not authority.

## 3. Triage Bot (knowledge)

**File:** `services/knowledge/src/triage-bot.ts`

**Type:** Function module (not an agent class)

**Role:** AI-powered knowledge extraction from conversations. Uses Workers AI for extraction, Slack for review notification.

### Extraction Categories

| Category | Meaning |
| - | - |
| insight | Business insight or observation |
| fact | Concrete fact about customer, product, market |
| decision | Decision that was made |
| action\_item | Task or follow-up committed to |
| preference | User or customer preference |
| relationship | Relationship between entities |

### AI Provider Priority

1. Cloudflare Workers AI (`env.AI`) — edge-native, zero external calls
2. OpenRouter (`env.OPENROUTER_API_KEY`) — fallback for larger models

### What It Writes

* `triage_results` table (Neon/D1) with `approval_status = 'pending'`
* Slack notification (review channel only, not authority bypass)

### What It Never Writes

* Approved organizational memory
* Canonical entity state
* Direct promotions

### Slack Integration

Slack is a **review channel**, not an authority bypass. A Slack reaction must become a verified approval event bound to the triage item, tenant, principal, and candidate version before promotion.

Reaction mapping:

* ✅ → Approve
* ❌ → Discard
* ⏰ → Defer


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.