Overview

Run a persistent, multi-stage pipeline your agents actually execute

Kanban pipeline: a persistent, Workspace-level board#

The event stream is the single source of truth#

The single source of truth for board state is the append-only event stream .kxen/kanban/<board>/events.jsonl. The sibling snapshot.json is just a cache to speed up loading; startup validates it, and any mismatch triggers a full rebuild from the event stream.

Every state change goes through Command → Guard → Event: an illegal command is rejected with zero side effects, and neither the model nor a human can write state directly. UI actions and agent tool calls travel the same command path, so the event stream can replay every transition, execution, and verdict in full.

Columns and the default template#

A new board ships with a default software-development template — five columns, flowing in order:

  • Requirements: a human gate. A card entering it parks immediately until intent is confirmed.
  • In Progress: an agent-execution column. Success advances to Testing automatically; failure flows back to Requirements.
  • Testing: an agent-execution column. Success advances to Review; failure flows back to In Progress.
  • Review: a human gate. Approval moves the card to Done; rejection flows back to In Progress.
  • Done: a terminal column with no outgoing edge.

Columns are fully customizable — add or remove them, change their on_success/on_failure targets, set a work-in-progress limit (wip_limit), and a column execution timeout (timeout_ms). Beyond agent-execution columns, you can also add QuickJS-script columns, human-gate columns, and plain columns.

Product entry points#

  • The Workspaces board shows a "Kanban" area on every Workspace card, listing that Workspace's boards and pending-review counts, and links into /kanban/<board>.
  • The board page gives you a column-by-column view, card details, approve/reject, retry, comments, new-card creation, and authorization settings.
  • The main-thread agent can discover kanban_* tools through tool_search (create board, add column, create card, move, comment, define column agent), and build and maintain a pipeline directly inside a conversation.

Column execution#

Once a card enters an agent-execution column, the board runner dispatches it automatically — the same card only ever has one active execution at a time.

Results are never guessed. Completion is a two-phase protocol: a run_started event lands before any execution begins, and the outcome is only decided by an explicit VERDICT: success or VERDICT: failure in the final turn — finishing without declaring one counts as failure. A timeout, interruption, or process death is always treated as an unknowable outcome: the card parks in blocked with an audit comment, only an explicit retry gives it a second execution, and the system never automatically resends it.

A QuickJS-script column reuses the same column-agent definition file — its body is the script itself, executed by the Workflow engine.

Column agent definitions#

The agent definition a column references lives in .kxen/kanban/agents/<name>.md. Its frontmatter includes name, role, model, and permission_profile; its body is the system prompt. permission_profile decides which tools that column instance can call:

  • readonly: read-only retrieval.
  • readonly+test: read-only retrieval plus running verification commands.
  • full: every resident tool.

model set to auto picks through role-based model routing; you can also pin an explicit provider:model.

Human gates#

A human-gate column parks every card that enters it, waiting for a person to approve or reject it from the board page — the system never auto-releases it. Approving moves the card along on_success; rejecting follows on_failure. If the matching outgoing edge doesn't exist, the command is refused and the card stays in place.

Board-level autonomous authorization#

Each board can hold one autonomous authorization: a command-prefix allowlist, plus an optional time limit (minutes) and a maximum auto-release count. A column agent's high-risk command that matches the allowlist auto-releases and gets logged for audit; anything that doesn't match still goes through Approval individually, and a command Safety judges Deny is never released.

Only a human can set this authorization, from the board page's "Authorization" panel — it's never exposed as an agent tool, so a model can never expand its own authorization.

Per-card Worktree isolation#

Inside a Git Workspace, column execution happens inside a card-specific Worktree (.kxen/worktrees/card-<id>, branch kxen/card-<id>), so multiple cards executing at once never step on each other. A non-Git Workspace falls back to executing in the project root, and leaves an audit comment noting there's no isolation this time.

Once a card reaches a terminal column, the board first rescues uncommitted artifacts (including gitignored files), snapshots them into .kxen/kanban/<board>/artifacts/<card>/, and only then releases the Worktree directory — the branch itself stays. Merging that branch back into your main tree is your job, usually done at the Review column. The general-purpose Worktree capability is covered in Worktree.

Where it differs from Agent Teams#

Agent Teams is multi-member collaboration inside one Session: members, inbox, and tasks all attach to that conversation. Kanban is a Workspace-level persistent pipeline: columns, cards, and the event stream attach to the Workspace. The two concepts don't overlap. Prefer Workflow for one-off parallel analysis, Team for division of labor inside a conversation, and Kanban for a multi-stage process that has to persist across conversations.

Agent Teams: collaborate through tasks, inbox, and independent transcripts#

Agent Teams fit tasks where multiple agents need to collaborate continuously. A Team has a lead and members, and each member can use a different role and model. A Team shares its Session's working directory; if the whole Session was created inside a Worktree, lead and members all work inside that isolated directory.

Team members#

Every member has:

  • Its own identity and role.
  • Its own running context and transcript.
  • An inbox.
  • A current task and status.
  • An optional model binding.

Members can message the lead or other members. A message lands in the target's inbox — it never gets appended to every member's context.

Shared tasks#

A Team task records:

  • Status: pending, in_progress, completing, blocked, completed, failed, or canceled.
  • An assignee.
  • depends_on.
  • A task description and result.

A dependent task only becomes executable once its dependency completes. A failed or canceled task cascades to cancel any pending tasks that depend on it; an in_progress task settles on its own. Once a completion hook succeeds, a task first enters the completing intermediate state, and only task_resolve settles it to completed. If a teammate crashes, a task stuck in completing is marked blocked; an in_progress task keeps its state and waits for the lead to handle it explicitly. Task status is the source of truth for Team collaboration — never rely on natural-language "I'm done" alone.

Persistence#

Team configuration, tasks, inboxes, and member transcripts are saved to local application data. Closing the window doesn't turn a saved collaboration record into a plain chat transcript.

When to use it#

Agent Teams fits sustained collaboration with clear division of labor. For one-off parallel analysis, prefer Workflow or multiple Subagents instead.

Background tasks: manage long-running processes#

Background tasks fit local processes that shouldn't block the current agent turn — dev servers, watchers, and long builds.

Starting one#

The agent can start a process through the task tool. Each task gets its own task ID, and records its command, working directory, output, run time, and process state.

A dev server can declare a readiness condition. kxen waits for a matching output pattern or a reachable port before reporting it as ready, instead of guessing startup time with a fixed sleep.

Managing them#

Background tasks support:

  • Listing running tasks.
  • Reading accumulated output.
  • Stopping a task.
  • Restarting with the same command.
  • Viewing port, run time, and a tail of output.

A completed task fires a notification, so the agent doesn't need to poll repeatedly.

Where you see it#

The current Session's background tasks show in the right-hand Dock. The status bar shows how many tasks are still running in the current Session (0 when no Session is selected). The Workspaces board currently rolls up running Sessions, Queue, Goal, Schedule, Worktree, and Git status — it doesn't list background processes separately.

Lifecycle boundary#

A background task belongs to this run of the app, not a system-level daemon. Once the app stops, the system kills the process, or the task exits on its own, its old state should never be treated as still running.

Starting one still goes through Shell Safety and Approval — running in the background never bypasses high-risk command checks.

Tool system: what the agent can actually call#

Tools let the agent read your project, edit files, run commands, reach language services, and call external integrations. The tool catalog isn't a permission list — a tool appearing in the catalog doesn't guarantee it can execute under the current role or on this machine.

Resident tools#

High-frequency tools go straight to the model:

exec, read, edit, write, task, goal, glob, grep, todo, webfetch, websearch, tool_search, workflow, team.

team is only visible to the main Session's lead; teammates use a restricted send_message and team_task. File tools are bounded by Workspace and unified path checks. exec requires an explicit Shell dialect, and turns long commands into background tasks.

webfetch and websearch's extraction, fallback, network, and metering boundaries are covered in Web & Search.

On-demand tools#

Low-frequency tools are progressively disclosed through tool_search:

delete, lsp, agent, worktree, skill, knowledge, schedule, browser.

browser only enters the catalog once you've explicitly enabled the experimental toggle in your personal configuration. MCP tools have their own catalog and policy — they're not part of the built-in deferred-tools list. The model discovers a contract first, then calls the specific tool, instead of stuffing every tool description into context up front.

Where permission comes from#

Whether a tool is available depends jointly on:

  • The agent's role and permission profile.
  • Workspace trust.
  • Local runtime and external service status.
  • The Safety verdict.
  • Your Approval.

Research and planning roles have no write or command permission by default. An execution role can get a fuller tool surface, but still can't override Safety's hard denials. Shell runs on your host machine — it isn't a sandbox — so every command must show its full command and working directory, and get its own Approval.

Observability#

Every tool call in the timeline is a summary card: a status dot, tool name, a summary of key arguments, and metadata badges. Cards are collapsed by default; expand one to see exact arguments and full output in place — edit and write render a structured diff when expanded, not raw JSON. A run of read-only exploration calls collapses into one grouped card showing the call count and per-tool breakdown, expandable card by card. Cmd+O, or the toggle in the Session header, expands or collapses every tool's detail globally; any card you've toggled by hand keeps your choice.

Long output is truncated for display, but the actual task state is still decided by the backend's tool run record.

Updated

Was this page helpful?