Cat Factory
Home
Get Started
GitHub
Home
Get Started
GitHub
  • Start

    • Introduction
    • Core Concepts
    • Quick Start
    • Tutorial: Your First Task to a Merged Pull Request
  • Guides

    • Recipes

      • Cookbook
    • Plan the work

      • Design Your Board
      • Clarify Requirements
      • Author a Document
      • Plan an Initiative
    • Run pipelines

      • Choose and Edit a Pipeline
      • Run a Pipeline
      • Schedule Recurring Work
      • Review and Merge Pull Requests
      • Control Spend with Budgets
    • Connect

      • Connect a Repository
      • Connect Issue & Document Sources
      • Feed Design Context to Agents
      • Preview and Test a Frontend
    • Models & prompts

      • Connect a Model Provider
      • Apply Standards with Prompt Fragments
      • Run a Claude Skill as a Step
      • Compare Prompts and Models in the Sandbox
    • Collaborate

      • Invite and Manage Your Team
      • Share Services Across Workspaces
      • Register Foundational Services
  • Deploy

    • Run Locally
    • Deploy to Node.js
    • Deploy to Cloudflare
    • Deploy on Kubernetes
    • Lay Out a Kubernetes Cluster
    • Set Up a Local Kubernetes Cluster on Windows
    • Register the GitHub App
    • Set Up Enterprise SSO
    • Set Up Your Deployment Repository
    • Configuration
  • Operate

    • Observability
    • Set Up Notifications
    • Run Jobs on Your Own Runners
    • Provision Ephemeral Environments
    • Debug a Run from Outside the Browser
    • Troubleshooting
    • Upgrades & Data Retention
  • Extend

    • Add a Custom Agent Kind
    • Add a Custom Gate or Judge
    • Add a Custom Provider
    • Extend the App with Frontend Modules
    • Integration Manifests
    • Give Agents External Tools (MCP)
    • Package a Reusable Operation
    • Register an Initiative Preset
    • Public API
    • Official SDKs
    • MCP Server
    • Cloudflare OS Gatekeeper
  • Reference

    • Architecture
    • Agent Isolation Model
    • Security Model & Hardening
    • Packages & Repository Layout
    • GitHub and GitLab Support Matrix
    • Environment Variables
    • API Endpoint Reference
    • Glossary

Run Jobs on Your Own Runners

For the operator who needs agent jobs to run on compute they control, and for anyone on the Node.js runtime, where a pool is not optional. On Cloudflare, per-run coding work executes in Cloudflare Containers by default; if you want control over where agents run, Cat Factory supports self-hosted runner pools. On the Node.js runtime there is no built-in per-run container, so repo-operating agent kinds (coder, mocker, blueprints, ci-fixer, conflict-resolver, merger, spec-writer, analysis) run on a runner pool. Wiring one up is what turns those kinds on there.

When to use a runner pool

Reach for a runner pool when you need to:

  • Run agent jobs on your own infrastructure (Kubernetes, Nomad, or another scheduler).
  • Meet data-residency or network requirements that rule out managed containers.
  • Reuse existing compute capacity for execution.

How it works

A runner pool is described by a declarative manifest you register on the deployment. It holds request templates for dispatching a job, polling its status, and (optionally) releasing it, plus the auth scheme and a mapping from your scheduler's responses onto the canonical job view. A single generic adapter interprets any manifest, so there's no per-org code. See Integration Manifests for the shape.

Routing and sizing jobs

Each dispatch and poll exposes the job's metadata as first-class template variables, so your manifest can route or size a job without decoding the embedded job spec:

VariableWhat it carries
{{input.kind}}The agent kind being dispatched (run, blueprint, spec, explore, ci-fix, resolve-conflicts, merge, on-call, test, fix-tests, bootstrap). Route different kinds to different handlers or queues.
{{input.instanceType}}The instance type a service pins (e.g. c7g.xlarge), or empty when unpinned. Use it for node selection.
{{input.cloudProvider}}The cloud provider a service pins (e.g. aws), or empty when unpinned.
{{input.jobId}}The execution id the pool is keyed on (sticky routing target).
{{input.job}}The full harness job spec as JSON; embed it verbatim to forward the whole payload.

These let one pool serve every agent kind and size each job from the service's pinned provider and instance type, all from the manifest. See Integration Manifests for the full list.

Custom adapters

The generic manifest adapter covers any HTTP scheduler and is the supported path for almost every deployment. If your scheduler can't be driven over HTTP at all, the Node.js runtime exposes the runner-pool and environment-provisioning ports as code seams: you can build the container with your own adapter implementation instead of the manifest-driven one. This is an advanced, code-level extension; reach for the manifest first. For a full walkthrough (the RunnerPoolProvider port, a worked example, wiring, and gotchas), see Add a Custom Provider.

Cat Factory dispatches per-run jobs to the pool, which executes the executor-harness container image. That's the same payload that runs the coding agent, performs Git operations, and produces the branch the platform opens a pull request from.

Backend  ──dispatch──▶  Runner pool (K8s / Nomad / scheduler)
                          └─ executor-harness container
                               → coding agent
                               → Git operations & PR creation

Configuration

SettingPurpose
Runner pool manifestDescribes your scheduler's dispatch/poll/release API declaratively.
Pool API credentialsSupplied at registration by logical key, stored encrypted at rest.
Container image registry + pull credentialsWhere the executor-harness image is pulled from.

The manifest's structure is documented in Integration Manifests; registration is part of the Infrastructure configuration. See Configuration → Infrastructure.

You register the pool in-app. Open the top-level Infrastructure window, Agent containers tab, select the HTTP manifest backend, and use the in-app JSON manifest editor to paste or edit the manifest, fill the write-only secrets sub-form, and run a test dispatch. The editor validates against the same wire contract the backend enforces. The Test environments tab in the same window registers an environment provider; a single pool can back both jobs.

Native Kubernetes backend

If your compute is a Kubernetes cluster, you don't need a manifest at all. Select the Kubernetes backend on the Agent containers tab and fill in a form (apiserver URL, namespace, a ServiceAccount token, and the executor-harness image): Cat Factory creates one pod per run directly, no HTTP scheduler in between. See Deploy on Kubernetes → Agent containers. On a developer machine, cat-factory k3s wires a local cluster into this backend in one command. How the cluster should be laid out around it (namespaces, the RBAC the token needs, egress, reaping leaked pods, sizing) is Lay Out a Kubernetes Cluster.

Reaching an internal pool

The pool URL must be https and a public host by default; private, internal, and cloud-metadata addresses are blocked (SSRF protection). To dispatch to a scheduler on an internal host, widen the allow-list:

VariablePurpose
RUNNERS_ALLOW_URL_HOSTSComma-separated hostnames exempt from the private/internal-host block. Each matches the URL host exactly (pool.corp, 10.1.2.3) or as a dot suffix when it starts with . (.internal).
RUNNERS_ALLOW_HTTP_URLSSet to true to also permit plain http (not just https).

This is scoped independently from the environment integration's ENVIRONMENTS_* allow-list: a host you allow here is not thereby reachable by the environment provider.

Bring-your-own infrastructure

Combined with the Node.js backend and your own PostgreSQL, runner pools let you run the entire platform on infrastructure you control, while keeping the same board UI, API, and agent pipelines.


Next: give agents somewhere to test their work with Provision Ephemeral Environments, or describe your scheduler declaratively with Integration Manifests.

Edit this page on GitHub
Last Updated: 8/9/26, 12:55 PM
Prev
Set Up Notifications
Next
Provision Ephemeral Environments