For the complete documentation index, see llms.txt. This page is also available as Markdown.

Linear Backlog Agent

Automate Linear backlog execution with a DinoAI agent that picks up Agent Ready issues, builds dbt™ models with tests and docs, opens PRs, and posts progress to Slack.

Automate your analytics engineering backlog with a DinoAI agent that reads every open Linear ticket labelled Agent Ready, spins up a Paradime development session, implements the required dbt™ models with tests and YAML docs, and opens a PR — all in parallel, one session per ticket.

compass

Before You Start

Paradime

  • Your Paradime API endpoint, API key, and API secret — generate these under Workspace Settings → API. Make sure to enable DinoAI agent API capabilities. Requires Admin access.

Linear

  • A Linear personal API key — generate one under Settings → API → Personal API keys

  • The team key for the team whose backlog you want to process (e.g. "DNA")

  • Issues you want to automate must carry the label Agent Ready and have a state type that is not completed

Integrations

The following must already be connected in Paradime:

  • Linear — the agent calls get_linear_issue to fetch linked tickets

  • Slack — the agent posts status updates to #analytics-eng via post_slack_message

What You'll Build

By the end of this guide you'll have:

  • A Poetry project wired to the Paradime SDK and the Linear GraphQL API

  • A LinearClient that paginates through all non-completed, label-filtered issues

  • An AgentInvoker that fires one DinoAI session per issue in parallel and polls until completion

  • A run_notifier.py entry point that ties everything together

  • A linear-backlog-agent DinoAI agent YAML that reads the ticket, implements the dbt™ models, and opens a PR

What the Agent Does Per Ticket

Once triggered, the agent follows this sequence for each Linear issue:

The agent never invents a column that isn't in the source. When a ticket is ambiguous it surfaces explicit Open questions in the PR description rather than guessing.

Architecture Overview

How It Works

When run_notifier.py is executed it loads environment variables, fetches all non-completed Linear issues labelled Agent Ready, then fires one DinoAI agent session per issue using a ThreadPoolExecutor. All sessions run concurrently — total wall-clock time is bounded by the slowest single ticket, not the sum of all tickets. Each session is polled every 20 seconds for up to 30 minutes.

1

Set Up the Poetry Project

Create the following pyproject.toml at the same directory level as your dbt_project.yml. This is required so the agent can locate and write dbt™ model files correctly.

Install dependencies by running:

The only two third-party dependencies are requests (for the Linear GraphQL API) and paradime-io (the Paradime SDK). All other imports — concurrent.futures, os, sys, time, typing — are part of the Python standard library.

2

Create the Agent YAML

Create the following file in your repository at .dinoai/agents/linear-backlog-agent.yml. This defines the agent's role, goal, tools, and Slack output channel.

tools.mode: allowlist means the agent can only call the tools explicitly listed. This keeps each session focused and prevents unintended side effects across your repository.

The Slack channel is set to #analytics-eng by default. Update slack.channel before committing if your team uses a different channel.

3

Create the Linear Client

Create python/linear_slack_notifier/linear_client.py. This module communicates with the Linear GraphQL API and handles automatic pagination so no issues are missed regardless of backlog size.

The client accepts both a Linear team UUID and a short team key (e.g. "DNA"). Pagination is handled automatically via pageInfo.hasNextPage and endCursor — all matching issues are returned regardless of backlog size.

4

Create the Agent Invoker

Create python/linear_slack_notifier/slack_notifier.py. Despite the filename, this module no longer posts to Slack directly — it triggers and polls DinoAI agent sessions, one per issue, in parallel threads.

Sessions are polled every 20 seconds with a 30-minute timeout per issue. The ThreadPoolExecutor fires all sessions immediately — if you have 10 tickets, all 10 agent sessions start at the same time.

5

Create the Main Orchestrator

Create python/linear_slack_notifier/run_notifier.py. This is the entry point that loads configuration, fetches issues from Linear, and hands them to the AgentInvoker.

6

Set Your Environment Variables

The orchestrator requires five environment variables. Set them in your shell before running:

Variable
Description

LINEAR_API_KEY

Linear personal API key

LINEAR_TEAM_ID

Linear team key (e.g. "DNA")

PARADIME_API_ENDPOINT

Paradime GraphQL endpoint

PARADIME_API_KEY

Paradime API key

PARADIME_API_SECRET

Paradime API secret

LINEAR_LABEL_NAME

(optional) Label to filter by — defaults to "Agent Ready"

Your Paradime API endpoint, key, and secret are available under Workspace Settings → API. Make sure the key has DinoAI agent API capabilities enabled.

7

Run the Orchestrator

From the repository root, run:

You should see output like:

Each issue gets its own parallel agent session. The orchestrator polls every 20 seconds and prints a summary once all sessions have reached a terminal state.

File Structure

Your repository should look like this after completing the setup:

pyproject.toml must sit at the same directory level as dbt_project.yml. The agent uses run_terminal_command and read_file to navigate the dbt™ project, so the working directory at session start must be the repo root.

Schedule with Bolt

Instead of running the orchestrator manually, you can have Bolt execute it on a schedule — every morning, once a week, or at any cadence that suits your team's workflow. Bolt runs the two commands in sequence: first poetry install to ensure dependencies are up to date, then poetry run to trigger the agent sessions.

Add Environment Variables to Paradime

Before creating the schedule, store your secrets as environment variables in Paradime so Bolt can access them at runtime. Go to Account Settings → Environment Variables and add the following:

Variable
Value

LINEAR_API_KEY

Your Linear personal API key

LINEAR_TEAM_ID

Your Linear team key (e.g. "DNA")

PARADIME_API_ENDPOINT

Your Paradime GraphQL endpoint

PARADIME_API_KEY

Your Paradime API key

PARADIME_API_SECRET

Your Paradime API secret

LINEAR_LABEL_NAME

(optional) Defaults to "Agent Ready"

Environment variables set in Workspace Settings → Environment Variables are available to all Bolt schedules in your workspace. You only need to set them once.

Create the Bolt Schedule

Go to Bolt → Schedules and click New Schedule. Give it a name like Linear Backlog Agent and configure the two commands under the Commands section.

The schedule should run two commands in order:

poetry install is included as the first command so that any dependency updates committed to pyproject.toml are automatically picked up on every run — no manual intervention needed.

Choose a Schedule Frequency

Pick the cadence that matches how often your team labels new tickets as Agent Ready. The table below covers the most common options:

Cadence
Cron expression
When it runs

Every day at 9 AM

0 9 * * *

Monday–Sunday, 9:00 AM

Weekdays at 9 AM

0 9 * * 1-5

Monday–Friday, 9:00 AM

Once a week (Monday 9 AM)

0 9 * * 1

Every Monday, 9:00 AM

Twice a week (Mon & Thu)

0 9 * * 1,4

Monday and Thursday, 9:00 AM

Every 6 hours

0 */6 * * *

12 AM, 6 AM, 12 PM, 6 PM

For most teams, weekdays at 9 AM (0 9 * * 1-5) is a good default. The orchestrator exits cleanly with ✅ Nothing to process when there are no Agent Ready tickets, so there is no cost to running it on days with an empty queue.

Once saved, Bolt will run both commands on your chosen schedule, picking up any new Agent Ready Linear issues and spinning up the corresponding DinoAI sessions automatically.

Last updated

Was this helpful?