# How Routa’s Kanban Lane Specialist System Works: Automating Workflows with AI Agents

> Discover how Routa’s Kanban lane specialist system works. Learn how AI agents automate complex workflows and enforce quality gates for efficient task management.

- Repository: [Fengda Huang/routa](https://github.com/phodal/routa)
- Tags: deep-dive
- Published: 2026-05-26

---

**Routa’s Kanban lane specialist system treats each board column as an automated workflow orchestrated by small, purpose-built AI agents (specialists) that execute specific stages of work and enforce quality gates before cards can advance.**

The open-source project `phodal/routa` implements a sophisticated automation layer on top of traditional Kanban boards. Unlike simple status columns, Routa’s lanes can host multi-step specialist workflows where each step represents a distinct agent—such as a code reviewer, test runner, or deployment specialist—that must complete before the task moves forward.

## Core Architecture of the Lane Specialist System

The system centers on the concept that a **Kanban column** defines an `automation` object containing one or more `KanbanAutomationStep` entries. These steps are defined in [`src/models/kanban.ts`](https://github.com/phodal/routa/blob/main/src/models/kanban.ts) and specify which specialist should handle the work through flexible selectors.

### Automation Definition and Step Configuration

Each automation step can target a specialist using multiple identification fields. According to the model definitions in the repository, a step may include:

```ts
{
  specialistId?: string;       // Exact specialist identifier
  specialistName?: string;     // Human-readable name
  role?: string;               // Role such as "developer" or "reviewer"
  providerId?: string;         // Backend provider (e.g., "anthropic")
}

```

Columns with single steps automatically select that specialist. Multi-step lanes require the system to resolve which step is currently active based on the task’s assignment metadata and any running lane sessions.

### State Resolution and Step Matching

The heart of the resolution logic lives in [`src/core/kanban/lane-automation-state.ts`](https://github.com/phodal/routa/blob/main/src/core/kanban/lane-automation-state.ts). The exported function `resolveCurrentLaneAutomationState` constructs a `CurrentLaneAutomationState` object that captures:

- The `currentColumnId` where the task resides
- The ordered list of automation `steps` for that column
- The active **lane session** (retrieved via `getTaskLaneSession` from [`src/core/kanban/task-lane-history.ts`](https://github.com/phodal/routa/blob/main/src/core/kanban/task-lane-history.ts))
- The `currentStepIndex` and references to `currentStep` and `nextStep`

When no lane session exists, the system invokes `findStepIndexFromTaskAssignment` to score every step against the task’s fields (`assignedProvider`, `assignedRole`, `assignedSpecialistId`, `assignedSpecialistName`) using the `getStepMatchScore` algorithm. The highest-scoring match becomes the active step. If the system cannot infer a step in a multi-step lane, it logs a warning to aid debugging.

## Blocking Mechanisms and Quality Gates

Routa enforces workflow integrity by preventing task movement while specialists are active. UI components call `buildRemainingLaneStepsMessage(taskTitle, state)` from [`lane-automation-state.ts`](https://github.com/phodal/routa/blob/main/lane-automation-state.ts) (lines 55–71) to generate user-facing blockers.

If `state.hasRemainingSteps` returns true, the function produces messages such as:

```

Cannot move "Add login page" out of Review yet: code-review is still active and testing must run next in the same lane.

```

This mechanism ensures that **quality gates** are respected—cards cannot bypass automated code review or testing stages simply by manual drag-and-drop operations.

## Specialist Execution and Session Tracking

When a step becomes active, the orchestration engine invokes the specialist runner located at [`tools/hook-runtime/src/specialist-review.ts`](https://github.com/phodal/routa/blob/main/tools/hook-runtime/src/specialist-review.ts). This module loads specialist definitions from YAML files in `resources/specialists/` (or falls back to built-in defaults) and executes them via the configured LLM provider.

Session persistence is handled through `TaskLaneSession` records managed by `getTaskLaneSession` in [`src/core/kanban/task-lane-history.ts`](https://github.com/phodal/routa/blob/main/src/core/kanban/task-lane-history.ts). Each session tracks:

- The `stepIndex` currently executing
- The `status` enum value (`running`, `transitioned`, or `completed`)
- Hand-off data between specialists

This allows the system to resume interrupted workflows—for example, if a code review specialist fails due to a missing API key (surfaced as "Automatic review specialist unavailable"), the task retains its context when the system retries.

## Practical Implementation Example

The following TypeScript example demonstrates how to resolve the current automation state for a task and handle blocking logic in a custom UI:

```ts
import { resolveCurrentLaneAutomationState } from "@/core/kanban/lane-automation-state";
import { buildRemainingLaneStepsMessage } from "@/core/kanban/lane-automation-state";
import { getBoardColumns } from "@/core/kanban/boards";

// Task entering the "Review" column
const task = {
  id: "T-123",
  title: "Add login page",
  columnId: "review",
  assignedSpecialistId: "code-reviewer",
  assignedProvider: "anthropic",
};

const boardColumns = await getBoardColumns();
const laneState = resolveCurrentLaneAutomationState(task, boardColumns);

if (laneState.hasRemainingSteps) {
  console.log(
    `Task "${task.title}" is waiting on specialist:`,
    laneState.currentStep?.specialistName ?? laneState.currentStep?.specialistId
  );
}

// Generate UI blocker message
const blockMsg = buildRemainingLaneStepsMessage(task.title, laneState);
if (blockMsg) {
  alert(blockMsg); // Prevent lane movement in the UI
}

```

## Summary

- **Lane specialization**: Each Kanban column defines automation steps in [`src/core/kanban/lane-automation-state.ts`](https://github.com/phodal/routa/blob/main/src/core/kanban/lane-automation-state.ts) that map to specific AI specialists via `KanbanAutomationStep` configurations.
- **Dynamic resolution**: The `resolveCurrentLaneAutomationState` function determines the active step by matching task assignments against step selectors or resuming existing lane sessions from [`task-lane-history.ts`](https://github.com/phodal/routa/blob/main/task-lane-history.ts).
- **Movement blocking**: The `buildRemainingLaneStepsMessage` utility enforces workflow integrity by generating descriptive error messages when tasks attempt to leave lanes with incomplete specialist steps.
- **Session persistence**: `TaskLaneSession` records in [`src/core/kanban/task-lane-history.ts`](https://github.com/phodal/routa/blob/main/src/core/kanban/task-lane-history.ts) track step indices and status, enabling recovery from interruptions and maintaining state across specialist hand-offs.
- **Execution runtime**: Specialists run through [`tools/hook-runtime/src/specialist-review.ts`](https://github.com/phodal/routa/blob/main/tools/hook-runtime/src/specialist-review.ts), which loads YAML definitions and manages provider-specific LLM interactions.

## Frequently Asked Questions

### How does Routa determine which specialist to run in a multi-step lane?

Routa uses the `findStepIndexFromTaskAssignment` helper in [`lane-automation-state.ts`](https://github.com/phodal/routa/blob/main/lane-automation-state.ts) to calculate a match score for each step against the task’s `assignedProvider`, `assignedRole`, `assignedSpecialistId`, and `assignedSpecialistName` fields. The step with the highest score becomes active. If a lane session already exists from a previous run, the system resumes from the recorded `stepIndex` instead.

### Can users manually move a card while a specialist is running?

No. The `buildRemainingLaneStepsMessage` function checks `state.hasRemainingSteps` and returns a blocking message if any automation steps remain incomplete. This prevents manual bypassing of automated quality gates such as code review or security scanning.

### Where are specialist definitions stored and how are they loaded?

Specialist definitions are stored as YAML files in `resources/specialists/` or as built-in defaults. The [`specialist-review.ts`](https://github.com/phodal/routa/blob/main/specialist-review.ts) runtime in the `tools/hook-runtime` package loads these definitions and executes them against the configured provider (e.g., Anthropic), handling errors such as missing API keys gracefully.

### What happens if a specialist execution is interrupted?

The system maintains `TaskLaneSession` records in [`src/core/kanban/task-lane-history.ts`](https://github.com/phodal/routa/blob/main/src/core/kanban/task-lane-history.ts) that persist the `stepIndex`, status (`running`, `transitioned`, or `completed`), and hand-off data. When `resolveCurrentLaneAutomationState` is called again, it retrieves the most recent session via `getTaskLaneSession` and resumes the workflow from the exact point of interruption.