Canon

03 — Triage Agents

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

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

Agent Registry

AgentServiceRoleAuthority
TriageAgent (runtime)iw-agent-runtimeIntake classifierOperational state only
TriageAgent (cognitive)intelligenceDeep evaluationCandidate staging only
Triage BotknowledgeAI extraction + SlackPending 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

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 IDPatternPriorityRoute
approval"approve"100governance
decision"decide"90proposal
signal"signal"50signal
(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

{
  "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

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

CategoryMeaning
insightBusiness insight or observation
factConcrete fact about customer, product, market
decisionDecision that was made
action_itemTask or follow-up committed to
preferenceUser or customer preference
relationshipRelationship 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