---
title: "How to deploy an AI bug triage workflow on Rock8Cloud"
description: "Deploy Bugtriage to Rock8Cloud in one click - Mastra agents that check every bug report for duplicates, analyse it against your repository, and hand small fixes to a coding agent that opens the pull request."
seoTitle: "Deploy an AI Bug Triage Agent with Mastra"
seoDescription: "One-click Mastra bug triage workflow: duplicate detection, repo analysis, a coding agent that opens the PR, and human review. PostgreSQL and pgvector wired in."
tech: "Mastra + TanStack"
icon: mastra
category: fullstack
pubDate: 2026-09-14
image: /how-to/og/howto.png
imageAlt: "How to deploy an AI bug triage workflow on Rock8Cloud"
headerImage: true
heroImage:
  src: /how-to/bugtriage-demo.webp
  alt: "The Bugtriage board with reports closed by the process, including a linked duplicate, waiting on a person, shipped as a pull request, and shelved"
  width: 1920
  height: 1393
exampleRepo: https://github.com/rock8-cloud/ai-bug-triage-workflow
ctaTitle: "Triage bugs with agents."
ctaTitleHighlight: "A person decides the rest."
ctaSubtitle: "A Mastra server, a web app, Mastra Studio and PostgreSQL - provisioned together, wired to each other, live on the first deploy."
ctaIcons: [mastra, tanstack, postgresql, typescript]
order: 6
steps:
  - name: "Start from the blueprint"
    text: "Open the Bugtriage blueprint. Rock8Cloud clones the monorepo into your GitHub account and creates three services from it - the Mastra server, the web app and Mastra Studio."
  - name: "Hit Deploy"
    text: "Rock8Cloud provisions PostgreSQL with pgvector, passes it to the server as DATABASE_URL, and wires the services to each other, including CORS for Studio."
  - name: "Add your keys"
    text: "Enter your own OpenAI-compatible API key and base URL at deploy. Then set ROCK8CLOUD_API_KEY and ROCK8CLOUD_SERVICE_ID on the server service and redeploy it."
  - name: "Index the docs"
    text: "Open the web app, go to Setup and run the docs index once. Then file your first bug report."
faq:
  - q: "What does the workflow do with a bug report?"
    a: "It files the report, checks it for duplicates, recalls any standing rule your team taught it, has a read-only agent analyse your repository, and applies a plain policy rule. A simple fix goes to a coding agent that opens a pull request. Anything else waits for a person."
  - q: "What do I need to set after deploying?"
    a: "Two values on the server service: ROCK8CLOUD_API_KEY to start coding agents, and ROCK8CLOUD_SERVICE_ID for the repo-backed service the agents work on. The model key and base URL are your own OpenAI-compatible ones, entered at deploy. Everything else, including the database, is wired on deploy."
  - q: "Which model does it use?"
    a: "Any model behind your OpenAI-compatible API key and base URL. CHAT_MODEL picks the model the app reasons with and EMBEDDING_MODEL the embeddings. ROCK8CLOUD_AGENT_MODEL_ID optionally picks the coding agent model, which is billed separately."
  - q: "Where is the state stored?"
    a: "In one PostgreSQL database with pgvector - suspended workflow runs, reports, decisions, standing rules, traces and the vector indexes. A run waiting on a person survives a restart."
  - q: "Can I change when it acts on its own?"
    a: "Yes. The policy is a pure function in apps/server/src/mastra/classify.ts, and its thresholds such as DUPLICATE_THRESHOLD and MAX_AUTOFIX_FILES are env vars on the server service."
---

A bug triage process that runs on agents and stops before it does something nobody approved. [Mastra](https://mastra.ai/) workflows on [Bun](https://bun.sh/), a [TanStack Start](https://tanstack.com/start) web app and Mastra Studio, managed as a single [Turborepo](https://turborepo.dev/) monorepo. Rock8Cloud provisions the database and wires the services, so the first report can be filed minutes after deploy.



[Bugtriage example](https://github.com/rock8-cloud/ai-bug-triage-workflow)

[1-click clone & deploy](https://app.rock8.cloud/new-deployment?blueprint=bugtriage&utm_source=howto&utm_medium=landing&utm_campaign=howto&utm_content=bugtriage)



Or ask an agent instead of clicking. With Rock8Cloud [connected over MCP](/how-to/connect-claude), `deploy_blueprint` with the `bugtriage` slug forks the same template into your GitHub account, creates the project with its services, and starts the first build.

## Deploy in one click

The blueprint clones the monorepo into your GitHub account, then builds three services from it - the Mastra server (port 4111), the web app (port 3000) and Mastra Studio (port 3001). A managed PostgreSQL database with pgvector is provisioned and passed to the server as `DATABASE_URL`.

The web app reaches the server over the internal network. Studio runs in the browser, so it gets the server public URL, and the server allows Studio's origin for CORS. Nothing about that is yours to wire.

## How a report moves

Every stage costs more than the one before it, and each stage exists to stop work reaching the next:

1. **Duplicates** - one embedding against past reports. A match is linked and closed.
2. **Standing rules** - a policy agent recalls rules your team taught it and closes reports they cover.
3. **Analysis** - a read-only Rock8Cloud agent reads your repository and the product docs.
4. **Policy** - a plain rule sends the report to one of three branches: not a bug, simple fix, or needs a person.

A simple fix goes to a coding agent that implements it and opens a pull request. Anything else suspends the workflow with a drafted brief, and a person approves, backlogs or declines it from the review page.

## What is in the box

| Layer | Technology |
|---|---|
| Agents | Mastra workflows, Memory and evals, port 4111 |
| Web | TanStack Start, port 3000 |
| Studio | Mastra Studio, port 3001 |
| Models | Any model behind your own OpenAI-compatible API key and base URL |
| Coding agents | Rock8Cloud agent sessions over the REST API |
| Database | PostgreSQL with pgvector |

## Before the first report

Enter your own OpenAI-compatible API key and base URL when you deploy, and both are set on the server service. Then set two values on the server service and redeploy it:

- `ROCK8CLOUD_API_KEY` - a `vhk_` Rock8Cloud API key, used to start the coding agents
- `ROCK8CLOUD_SERVICE_ID` - the repo-backed service the agents read and change

Then open the web app, go to **Setup** and run the docs index once. It loads the product documentation into pgvector so the analysis can tell intended behaviour from a bug. The same page shows whether each key actually works.



> **Pro tip:** The server, the web app and Studio have no authentication. Anyone with the server URL can start workflows that spend your AI provider budget and task coding agents with your key. Treat the URLs as private and add auth before putting anything real behind them.



## Tuning the policy

The decision is a pure function in `apps/server/src/mastra/classify.ts`. Its thresholds - `DUPLICATE_THRESHOLD`, `MAX_AUTOFIX_FILES`, `ANALYSIS_CONFIDENCE_FLOOR` and `DOCS_INTENT_THRESHOLD` - are env vars on the server service. Change one, file the same report again, and watch the branch flip.

## Deciding from Slack

Set `SLACK_BOT_TOKEN`, `SLACK_SIGNING_SECRET` and `SLACK_CHANNEL_ID` on the server service and every report opens a thread. Reports waiting on a person get Build, Backlog and Won't do buttons, and the button calls the same decision as the review page.
