Architecture

Agent Orchestration

Complete guide to Triqual's 5 specialized agents

Agent Orchestration

Category: Architecture | Updated: 2026-02-02

Complete guide to Triqual's 5 specialized agents and the MCP context loading tool that powers autonomous test generation.


Overview

Triqual orchestrates 5 specialized agents plus a deterministic MCP tool to implement the documented learning loop:

AgentColorRoleStage
triqual_load_context-Context Loading (MCP)Pre-ANALYZE
test-planner🟣 PurplePlanningANALYZE/RESEARCH/PLAN
test-generator🟒 GreenCode GenerationWRITE
test-healerπŸ”΅ BlueAutonomous HealingRUN/FIX
failure-classifier🟠 OrangeFailure Analysis(on failure)
pattern-learner🟣 PurplePattern ExtractionLEARN

The Agentic Loop

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    TRIQUAL AGENT LOOP                           β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                  β”‚
β”‚  User Request (ticket, description, feature name)               β”‚
β”‚        ↓                                                         β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                                            β”‚
β”‚  β”‚LOAD CONTEXT (MCP)β”‚ ← triqual_load_context({ feature })        β”‚
β”‚  β”‚  (subprocess)    β”‚   Writes .triqual/context/{feature}/       β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                            β”‚
β”‚         ↓                                                        β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                                                β”‚
β”‚  β”‚ TEST-PLANNER β”‚ ← Reads context files, creates ANALYZE/PLAN    β”‚
β”‚  β”‚   (purple)   β”‚   Creates run log with test plan               β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜                                                β”‚
β”‚         ↓                                                        β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                                                β”‚
β”‚  β”‚TEST-GENERATORβ”‚ ← WRITE stage                                  β”‚
β”‚  β”‚   (green)    β”‚   Generates test code from plan                β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜                                                β”‚
β”‚         ↓                                                        β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                                                β”‚
β”‚  β”‚   RUN TEST   β”‚ ← RUN stage                                    β”‚
β”‚  β”‚   (bash)     β”‚   npx playwright test                          β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜                                                β”‚
β”‚         β”‚                                                        β”‚
β”‚    β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”€β”                                                   β”‚
β”‚   PASS      FAIL                                                 β”‚
β”‚    ↓         ↓                                                   β”‚
β”‚  LEARN   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                                    β”‚
β”‚    ↓     β”‚FAILURE-CLASSIFIERβ”‚ ← Categorizes the failure          β”‚
β”‚ pattern- β”‚    (orange)      β”‚                                    β”‚
β”‚ learner  β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                    β”‚
β”‚                   ↓                                              β”‚
β”‚            β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                                      β”‚
β”‚            β”‚ TEST-HEALER  β”‚ ← FIX stage (up to 3 attempts)       β”‚
β”‚            β”‚    (blue)    β”‚   Then back to RUN                   β”‚
β”‚            β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜                                      β”‚
β”‚                   ↓                                              β”‚
β”‚              RUN TEST (loop)                                     β”‚
β”‚                                                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

MCP Tool: triqual_load_context

Purpose

Deterministic MCP tool that spawns a headless Claude subprocess (Sonnet) to build comprehensive context BEFORE test generation begins.

Usage

triqual_load_context({
  feature: "login",              // Required: feature name
  ticket?: "ENG-123",           // Optional: Linear ticket ID
  description?: "...",          // Optional: text description
  force?: false                 // Optional: force reload even if context exists
})

What It Does

  1. Spawns headless subprocess (Claude Sonnet)
  2. Searches Quoth for patterns and anti-patterns
  3. Queries Exolar for failure history
  4. Scans codebase for relevant code (Page Objects, helpers, fixtures)
  5. Writes context files to .triqual/context/{feature}/

Context Files Created

FileContent
patterns.mdQuoth proven patterns
anti-patterns.mdKnown failures to avoid
codebase.mdRelevant source files, selectors, routes
existing-tests.mdReusable tests and Page Objects
failures.mdExolar failure history
requirements.mdTicket/description (if provided)
summary.mdIndex of all context

Why Mandatory

ENFORCED by hooks β€” test writing BLOCKED until context files exist.

Benefits:

  • Context files contain proven patterns from Quoth
  • Failure history from Exolar prevents repeating mistakes
  • Codebase analysis ensures code reuse
  • Subprocess runs in isolation (doesn't consume main context tokens)

Example

/test login
    β”‚
    └─► Calls triqual_load_context({ feature: "login" })
        β”‚
        β”œβ”€β–Ί Subprocess searches Quoth
        β”œβ”€β–Ί Subprocess queries Exolar
        β”œβ”€β–Ί Subprocess scans codebase
        └─► Writes 7 files to .triqual/context/login/

Agent 1: test-planner (Purple)

Purpose

Creates comprehensive test plan with ANALYZE/RESEARCH/PLAN stages.

Trigger Conditions

  • User command: /test login
  • User request: "plan tests for X"
  • Linear ticket provided: /test --ticket ENG-123
  • Description provided: /test --describe "..."

Tools Available

  • Read - Read context files
  • Grep - Search codebase
  • Glob - Find files
  • Playwright MCP - Explore app
  • Linear MCP - Fetch ticket details (if available)
  • Write - Create run log

What It Creates

File: .triqual/runs/{feature}.md

Sections:

  • ### Stage: ANALYZE - Test cases identified from requirements
  • ### Stage: RESEARCH - Quoth patterns, Exolar history, existing code
  • ### Stage: PLAN - Test strategy, tools to use, new artifacts

Decision Points

  1. What to test? - Extracted from ticket/description/feature name
  2. What patterns apply? - From context files (Quoth)
  3. What code to reuse? - From context files (existing tests)
  4. What to create new? - Only if no existing code covers the need

Example Output

# Test Run Log: login

## Session: 2026-02-02T10:30:00Z

### Stage: ANALYZE

**Acceptance Criteria:**
1. User can login with valid credentials
2. Invalid credentials show error

**Test Cases:**
- Happy path: successful login β†’ dashboard
- Error case: invalid credentials β†’ error message

### Stage: RESEARCH

**Context Files Read:**
- .triqual/context/login/patterns.md (5 patterns found)
- .triqual/context/login/existing-tests.md (LoginPage exists)

**Quoth Patterns:**
- Auth tests use `StorageState` pattern
- Login selectors use `data-testid` convention

**Existing Code to Reuse:**
- `pages/LoginPage.ts` βœ…
- `helpers/auth.ts` βœ…

### Stage: PLAN

**Test Strategy:**
1. Reuse existing LoginPage
2. Create new DashboardPage
3. 2 test cases (happy path + error)

**New Artifacts:**
- `.draft/pages/DashboardPage.ts` (needed)

Agent 2: test-generator (Green)

Purpose

Generates Playwright test code from plan.

Trigger Conditions

  • After test-planner completes
  • User request: "generate tests from plan"
  • Run log has PLAN stage

Tools Available

  • Read - Read run log PLAN stage, knowledge.md, context files
  • Write - Create test files in .draft/
  • Edit - Modify existing files

What It Creates

Files: .draft/tests/{feature}.spec.ts, possibly Page Objects

Pattern:

  • Reads PLAN stage carefully
  • Applies patterns from knowledge.md
  • Reuses existing code (Page Objects, helpers)
  • Creates new Page Objects ONLY if needed
  • Documents WRITE stage with hypothesis

Decision Points

  1. Reuse or create? - Always prefer reuse from context/existing-tests.md
  2. Which patterns? - Apply patterns from knowledge.md and Quoth
  3. Where to write? - Always .draft/ folder (hook enforces this)

Example Output

File Created: .draft/tests/login.spec.ts

import { test, expect } from '@playwright/test';
import { LoginPage } from '../pages/LoginPage';
import { DashboardPage } from '../pages/DashboardPage';

test.describe('Login Flow', () => {
  test('successful login redirects to dashboard', async ({ page }) => {
    const loginPage = new LoginPage(page);
    const dashboard = new DashboardPage(page);

    await loginPage.goto();
    await loginPage.login('user@example.com', 'password');

    await expect(page).toHaveURL('/dashboard');
    await expect(dashboard.welcomeMessage).toBeVisible();
  });
});

Run Log Updated:

### Stage: WRITE

**Hypothesis:** Using StorageState pattern from Quoth, reuse existing LoginPage and new DashboardPage to test login flow.

**Files Created:**
- `.draft/tests/login.spec.ts`
- `.draft/pages/DashboardPage.ts`

**Patterns Applied:**
- Quoth: StorageState auth pattern
- Existing: LoginPage reused βœ…

Agent 3: test-healer (Blue) - AUTONOMOUS LOOP

Purpose

Runs tests, analyzes failures, applies fixes autonomously. Loops until PASS or 25 attempts.

Trigger Conditions

  • After test-generator completes
  • User request: "fix failing tests"
  • Test failure detected

Tools Available

  • Read - Read test files, run log, error output
  • Edit - Fix test code
  • Bash - Run npx playwright test
  • Grep - Search for similar patterns
  • Quoth MCP - Search patterns on 2+ same failures
  • Exolar MCP - Query failure history on 2+ same failures

Autonomous Loop Logic

1. Run test (npx playwright test)
2. Test result?
   β”œβ”€ PASS β†’ STOP (await user approval to promote)
   β”‚         └─ Dispatch pattern-learner
   β”‚
   └─ FAIL β†’ Classify failure (via failure-classifier)
             β”œβ”€ Attempt < 3? β†’ Quick fix
             β”œβ”€ Attempt 3-11? β†’ Research patterns (Quoth/Exolar)
             β”œβ”€ Attempt 12? β†’ Deep analysis phase
             β”œβ”€ Attempt 13-24? β†’ Continue fixing
             └─ Attempt 25? β†’ Mark .fixme() or justify

3. Apply fix, document FIX stage, loop back to step 1

Escalation Phases

PhaseAttemptsAction
Quick Fixes1-2Direct fixes based on error
Research3-11Search Quoth patterns, query Exolar
Deep Analysis12Expanded research, broader scope
Final Attempts13-24Apply advanced fixes
Justification25+Mark .fixme() or justify continued attempts

Work Location

Always works in .draft/ folder

  • Reads: .draft/tests/{feature}.spec.ts
  • Edits: .draft/tests/{feature}.spec.ts
  • On SUCCESS: STOPS (does NOT auto-promote)

Promotion

BLOCKED by design - user must explicitly approve:

# Review test
cat .draft/tests/login.spec.ts

# Approve promotion
git mv .draft/tests/login.spec.ts tests/login.spec.ts

Example Run Log Updates

### Stage: RUN (Attempt 1)
**Result:** FAILED
**Category:** WAIT
**Analysis:** Dashboard loads async, URL changes before content ready

### Stage: FIX (Attempt 1)
**Hypothesis:** Add networkidle wait after login

### Stage: RUN (Attempt 2)
**Result:** PASSED

### Stage: LEARN
**Pattern:** This project requires networkidle wait after auth redirects

Agent 4: failure-classifier (Orange)

Purpose

Classifies test failures into categories for targeted fixes.

Trigger Conditions

  • Test failure unclear
  • User request: "classify this failure"
  • test-healer needs categorization

Tools Available

  • Read - Read error output, test file
  • Grep - Search for similar patterns
  • Exolar MCP - Query historical failures

Failure Categories

CategoryDescriptionTypical Fix
FLAKEIntermittent, timing-relatedAdd waits, stabilize selectors
BUGApplication bug, not test issueReport to dev team
ENVEnvironment-specific (CI/local)Adjust config, dependencies
WAITAsync loading, race conditionAdd explicit waits
TEST_ISSUETest code bugFix test logic

Decision Points

  1. Error message analysis - What does stack trace indicate?
  2. Historical data - Has this failed before? (Exolar)
  3. Reproducibility - Consistent or intermittent?

Example Output

**Classification:** WAIT

**Reasoning:**
- Error: "Element not found"
- Occurs after URL change (redirect)
- Dashboard content loads async

**Recommended Fix:**
- Add `page.waitForLoadState('networkidle')` after login
- Verify dashboard element visible before interaction

Agent 5: pattern-learner (Purple)

Purpose

Extracts patterns from successful fixes and updates knowledge.md.

Trigger Conditions

  • Test healed successfully
  • Session ending
  • User request: "extract patterns from this session"
  • Multiple fixes applied

Tools Available

  • Read - Read all run logs, test files
  • Edit - Update knowledge.md
  • Quoth MCP - Propose patterns for capture

What It Extracts

  1. Recurring patterns - Fixes applied multiple times
  2. Project-specific learnings - Unique to this codebase
  3. Anti-patterns - What NOT to do (from failures)

Knowledge File Updates

File: .triqual/knowledge.md

# Project Knowledge: {project}

## Patterns

### Auth Redirects Require networkidle Wait

**Context:** Dashboard loads async content after login redirect

**Pattern:**
```typescript
await loginPage.login(email, password);
await page.waitForLoadState('networkidle'); // Critical!
await expect(page).toHaveURL('/dashboard');

Why: URL change happens before content loads


Quoth Proposal

Pattern-learner can propose patterns to Quoth for project-wide capture:

quoth_create_pattern({
  title: "Auth Redirect Timing",
  category: "authentication",
  pattern: "...",
  project: "your-project"
})

Agent Coordination

Context Injection (SubagentStart Hook)

Before agent runs, hook tells it what to read:

πŸ”΅ test-healer starting

CRITICAL CONTEXT - Read these files FIRST:
1. .triqual/runs/login.md (run log - current state)
2. .triqual/knowledge.md (project patterns)
3. .triqual/context/login/patterns.md (Quoth patterns)

DO NOT proceed without reading these files.

Next Step Guidance (SubagentStop Hook)

After agent completes, hook suggests next step:

βœ… test-planner completed

NEXT STEPS:
1. Update run log with PLAN stage findings
2. Dispatch test-generator to write code
3. Read plan carefully before generating

Agent Models

All agents run on Opus 4.5 for maximum reasoning capability:

# agents/test-planner.md frontmatter
model: opus
color: purple
tools:
  - Read
  - Write
  - Grep
  - Glob
  - browser_navigate
  - browser_snapshot

Related Documentation


Next Steps: Read Learning Loop to understand workflow, or Hooks System to see context injection.