How to Build a Production Agent Harness A developer demonstrates how to build a production-grade AI agent harness using Bit's component-based architecture. The tutorial packages harness logic as versioned components—state tracker, context loader, and verifier—in a shared Bit scope, enabling automatic propagation of fixes via Ripple CI. This approach replaces one-off scripts with reusable, installable components, addressing common failure modes in agent loops. AI agents don't usually become unreliable all at once. They degrade quietly. One session the agent repeats a step it already completed. The next, it loses track of where it was mid-run and starts over from scratch. Eventually it produces output with nothing in place to verify whether it actually succeeded. The problem is structural. Harness components get built as one-off scripts instead of versioned, reusable units. Your state file lives in one project, a slightly different version lives in another, and when you fix a bug in one place the fix stays local. Teams end up maintaining the same harness logic across multiple projects and debugging whichever version happens to be in front of them. This tutorial shows how to fix that at the source. Instead of writing harness logic as inline scripts, you'll package it as versioned components in a shared Bit scope. Fix a bug once, tag and export, and Ripple CI Bit's built-in component CI/CD pipeline propagates the update to every project that depends on it automatically. By the end, your harness stops being something you rebuild per project and becomes something you install with a single command. Before you start, make sure you have the following in place so the setup steps run cleanly: Node.js 18 or higher installed on your machine. Run node --version to check. A bit.cloud account. You'll create a scope during setup. If you don't have one yet, head to bit.cloud/signup https://bit.cloud/signup . Basic familiarity with TypeScript. The components in this tutorial use TypeScript. You don't need to be an expert, but you should be comfortable reading typed function signatures. A terminal and a code editor. The tutorial runs entirely from the command line with a few file edits along the way. The three components are a state tracker, a context loader and a verifier. Each one targets a specific failure mode in the agent loop. harness/state tracks what the agent has done, what it's currently working on and what comes next. It reads at session start and writes at session end. harness/context pre-loads a structured map of your components and their relationships before the agent takes its first action. harness/verifier evaluates agent output against a done condition before the loop continues, returning one of four verdicts: NO , YES , MAYBE or IFF . Once all three are released to a shared scope, your entire harness installs into any agent project with a single command: bit install @your-username/agent-harness.harness.state @your-username/agent-harness.harness.context @your-username/agent-harness.harness.verifier Here's how the three components fit into the agent loop: Create a new scope https://bit.dev/reference/reference/scope/scope-bit-cloud and give it any name you like. For this tutorial, the scope will be named agent-harness . You can also use an existing scope." With your scope ready, install Bit's version manager by running this in your terminal. It handles Bit installations and keeps your version up to date across projects: npx @teambit/bvm install Next, initialize your workspace. This creates a workspace.jsonc configuration file at your project root and sets agent-harness as the default scope for every component you create in this workspace: bit init --default-scope your-username.agent-harness Replace your-username with your bit.cloud http://bit.cloud username. A successful run looks like this: successfully initialized a bit workspace. Open workspace.jsonc and uncomment the Node environment line. This tells Bit which runtime to use when building and compiling your components: "bitdev.node/node-env": {} Then run this to pull the Node environment and resolve its full dependency tree. This is a one-time step per workspace: bit install This will take a few minutes on first run. You'll see pnpm working through several hundred packages before it completes. Before creating any components, run this to see the available templates for your environment: bit templates The template you want is module , listed under bitdev.node/node-env . Now run this to scaffold all three harness components at once: bit create module harness/state harness/context harness/verifier Each command generates a component folder with a TypeScript entry file, a test file and the necessary Bit configuration. You'll see output confirming all three components were created under your scope, each assigned the Node environment automatically: One thing worth noting before you move on: harness/state , harness/context and harness/verifier are the component paths inside your workspace. When Bit publishes them to your scope, it generates a fully qualified package name by combining your scope and component path, for example @your-username/agent-harness.harness.state . Your workspace is ready. Three component folders now exist under agent-harness/harness/ , the Node environment is configured and you have a scope waiting to receive them once the implementations are complete. An agent without externalized state forgets everything between sessions. Every run starts blind: no record of what was completed, no awareness of what's in progress and no queue of what comes next. This is the failure mode that production systems https://dev.to/hackmamba/the-three-layer-architecture-that-makes-software-production-ready-2pdh are designed to prevent at the infrastructure level. The state component fixes that by reading a structured JSON file at session start and writing back to it before the session ends. Open the agent-harness/harness/state/state.ts file generated by bit create module in the previous step and replace the generated content with this: js import { readFileSync, writeFileSync, existsSync } from 'fs'; import { resolve } from 'path'; export type HarnessState = { done: string ; inProgress: string ; next: string ; }; const DEFAULT STATE: HarnessState = { done: , inProgress: , next: , }; export function loadState statePath = 'harness-state.json' : HarnessState { const abs = resolve statePath ; if existsSync abs return { ...DEFAULT STATE }; const raw = readFileSync abs, 'utf-8' ; return JSON.parse raw as HarnessState; } export function saveState state: HarnessState, statePath = 'harness-state.json' : void { const abs = resolve statePath ; writeFileSync abs, JSON.stringify state, null, 2 , 'utf-8' ; } HarnessState has three fields. done holds everything the agent has completed. inProgress holds whatever the agent is currently working on. next holds the queue of work still to come. loadState reads the state file at the path you specify, defaulting to harness-state.json at the project root. If no file exists yet, it returns an empty default state rather than throwing an error. saveState writes the updated state back to the same path before the session ends. Between those two calls, your agent has a persistent, structured record of exactly where it is in the work, regardless of how many sessions it takes to get there. Without pre-loaded context, your agent rediscovers the same dependency relationships from scratch on every run. It wastes the first part of every session figuring out what it already knew. The context component solves that by querying your Bit workspace for component dependencies and dependents before the agent takes its first action, handing it a structured map it can reason over immediately. Open the agent-harness/harness/context/context.ts file generated by bit create module in the previous step, and replace the generated content with this: js import { exec } from 'child process'; import { promisify } from 'util'; const execAsync = promisify exec ; export type ComponentMeta = { id: string; description?: string; dependencies: string ; dependents: string ; }; export type DependencyMap = Record