Skip to main content
paw
The playbook

Build your own agentic harness.


A harness is not an AI code assistant. It is the scaffolding, rules, hooks, gates, and memory that shape how AI agents work on YOUR code and YOUR process. paw is one implementation. You should have one of your own.

This page is a practical walkthrough, not a marketing blurb. It is the playbook we wish someone had handed us. Read it in order once, then come back to the sections that match where you are stuck.

What an agentic harness actually is

An LLM alone answers questions. An assistant integration adds editor context. A harness is what turns those two things into a system: enforced doctrine, deterministic hooks that fire on real events, agents with narrow scopes, gates that block bad work from moving forward, and audit trails that make every decision reconstructable a year later.

The reason to build your own is not that paw is inadequate. The reason is that your standards are yours. Nobody else's harness enforces how you review code, catches what you keep flagging, or writes rollback plans in your voice. paw ships as a starting point that respects that. Fork it, delete what does not apply, and add what does.

The rest of this page is how to get from "my current workflow" to "a self-updating harness that catches what I would catch." It works whether your target is a personal laptop, a team fork, an enterprise deployment, or all of them at once.

Deployment target matters. Pick your combination.

Where the harness runs shapes what it can do. Air-gapped teams cannot call hosted models the way a personal laptop can. Regulated clouds constrain egress. Different IDEs load rule files from different paths. Start with the target, then decide which pieces of the harness change to fit.

Personal laptop or Mac mini fleet

Simplest case. Your harness runs where you code. Add a Tailscale mesh if you want to dispatch heavy runs to a spare machine. paw supports this out of the box; any harness that shells out to a local model or CLI can do the same.

Enterprise day-job

The base + overlay pattern. Fork the harness. Keep the base clean; put team-specific rules, agents, and hooks in overlays/team-name/. A loader with precedence rules picks overlay > base. Now every team has the same substrate with their own additions on top.

Temporal / durable-execution

The pipeline itself becomes a workflow. Phases become activities. Retries, timeouts, and cancellation come from the runtime, not your Python. The temporal-architect agent enforces determinism, activity boundaries, saga patterns, and versioning at review time.

AWS / GCP / Azure only

Compliance and cloud egress rules constrain what the harness can do. Bake those constraints into hooks: an egress-guard hook that blocks calls to non-approved hosts, an IaC-reviewer agent that catches drift. paw's enterprise-deployment context enumerates the tradeoffs per cloud.

On-prem (TFS, TeamCity, self-hosted GitLab / Bitbucket)

Air-gapped or near-air-gapped. Rules and hooks work fine; agent LLM calls need a plan for models that reach out. Pick between a hosted proxy inside the perimeter or self-hosted open models. Rest of the harness is unchanged.

Azure DevOps cloud

ADO's YAML pipelines call the harness the same way GitHub Actions does. paw ships a starter workflow file for ADO under ci-templates/. The interesting decisions here are usually about identity (managed identity, service principals) and secret handling.

Cursor, Claude Code, Codex, or something else

The agents, rules, and contexts stay the same; only the loader changes. paw's generate-cursor-rules renders every rule and agent as an .mdc file so Cursor sees exactly what Claude Code sees. If you add a third IDE, add a third renderer, keep the source of truth in one place.

All of the above at once

This is the honest case for most teams. paw's enterprise.* config section carries the target list; overlays declare which target they belong to; the CI templates land as starting points and get customized by owners of each system. The point is not one deployment; the point is that the harness is portable across all of them.

paw carries an enterprise.* config section that names the target, an overlay convention for per-team divergence without base drift, and starter CI workflows for GitHub Actions, Azure DevOps, GitLab CI, and Jenkins. Whichever target you pick, you should not have to write the loader glue from scratch.

Enhance the basics first

Before automating anything with an LLM, encode the guardrails a senior engineer would insist on. These are not AI-specific. They are the substrate everything else sits on. If your harness cannot protect a git history, it cannot be trusted to review a diff.

  • Basic
    Git safety

    No rebase against nested-agent commits (rebase silently overwrites work done by a parallel worktree). No force-push to main. No commits directly to main. Every one of these is a mechanical hook, not a review note.

  • Basic
    No rm in automation

    Use .back suffixes or a trash utility. The session end lists .back files for one explicit cleanup decision. Deletion is a human choice; the harness never makes it silently.

  • Basic
    No try / except / pass

    Silent swallowing is worse than failing loud. Every caught exception logs to a forensic path with the context and the intended recovery. No exceptions.

  • Basic
    Test-first for new capabilities

    New script: write the test that exercises it first. New hook: pipe a synthesized stdin payload and confirm the side effect before wiring settings.json. New agent: write the scenario in examples/ before the frontmatter.

  • Basic
    Every automation is auditable

    Every prompt that runs harness logic logs to .pipeline/prompts.jsonl. Every commit produced by an agent gets a .pipeline/commits/<sha>.json capture. If a future you cannot reconstruct why a change happened, the harness failed a duty.

paw's hooks/ and rules/ directories are what this looks like once it is encoded. Read them not as gospel but as one example of a doctrine that has been beaten on for a while.

Walk through your day-to-day, step by step

This is the core of the whole exercise. Every good harness starts with a written, honest inventory of what its owner actually does. Skip this step and you will build clever automations for problems you do not have.

  1. 01Journal for one week

    Not a to-do list. Every meaningful task: what did you do, why, and what would have unblocked you 30 minutes earlier? Include the review comments you left, the incidents you chased, and the meetings you left annoyed. This is the raw material.

  2. 02Identify the recurrent shapes

    Read the week back. Circle every phrase that starts with Every Monday, Every PR review I check X, Every incident I look at Y then Z. Those are the shapes. They are your automation candidates.

  3. 03Rank by tedium times frequency

    High tedium plus high frequency wins. A quarterly boring thing is worth less than a daily annoying thing. Kill the daily thing first. Write the tedium score and the frequency in the journal so future-you can argue about it.

  4. 04Automate the smallest slice

    Not automate my whole PR review. The smallest slice: automate grep for TODO by me on push, as a hook. Ship it. See if it fires. Iterate. The lesson is that shipping small automations teaches you what a bigger one needs.

Slowly automate yourself

Order matters. Skipping the mechanical hook layer and jumping straight to a general-purpose review agent is how people end up disappointed and blaming the LLM. The layers below stack; earlier ones stabilize the ground for later ones.

Layer 01
Hooks first

Encode git safety, secret scan, drift detection, protected-branch guard. Hooks are cheap, mechanical, and unambiguous. They catch what you would catch on autopilot. Ship these before any LLM enters the picture.

Layer 02
Rules as text

Doctrine files agents can read. Not one-liners; short essays with the reasoning. When the rule is wrong later, you can argue with it. paw keeps these under rules/; every rule has a why and an enforced-by pointer.

Layer 03
Small narrow agents

One PR-review dimension per agent. A silent-failure hunter. A test-name-quality checker. A dependency-license auditor. Least-privilege tools. Read-only until proven otherwise. Fifteen small agents beat one big one.

Layer 04
Orchestrating agents

Once you have small agents, chain them. An architect that emits a plan the planner reads. A gap detector that reads gate outputs and spawns follow-up work. Orchestration is where the pipeline shape shows up.

Layer 05
Skills that bundle knowledge

Skills are capability packs multiple agents draw on. paw ships one for git-safety, one for gate-output shape, one for intent tracking. When two agents need the same knowledge, extract it once.

Layer 06
The end state

The harness catches what you would catch. You review the diff, not the noise. Your tone survives every review. Your standards are enforced when you are on vacation.

Point your LLM at your history

The harness that sounds like you is trained on you. Not with fancy fine-tuning. With a corpus you pull yourself and a prompt that asks the model to distill it. Cheap, private, and effective.

The corpus

Assemble a private folder. This is not for training weights. It is for a single long prompt or a retrieval index the persona agent reads at review time. Suggested content:

  • Two to three years of your git log, filtered to your commits.
  • Every PR you have authored plus every PR review comment you have written.
  • Your commit messages. They reveal what YOU consider shippable.
  • Your outbox: emails you wrote, Slack or Teams messages you sent (careful of confidentiality, use a private subset).
  • Confluence, Notion, or SharePoint pages you authored.
  • Jira, Monday, Trello, or Linear tickets you closed with substantive summaries.
  • Postmortems and incident retros you wrote or led.
  • Design docs and RFCs where your comments moved the outcome.

A starting script

For git-centric work, three commands get you 80 percent of the way. Adapt to your host and comment conventions.

# 1) Your commit voice, condensed
git log --author="you@example.com" --since="2 years ago" \
  --pretty=format:'%h %ad  %s%n%b%n---' --date=short \
  > ~/corpus/commit-log.txt

# 2) Every PR you have authored (via gh)
gh pr list --author "@me" --state all --limit 500 \
  --json number,title,body,createdAt,mergedAt,url \
  > ~/corpus/prs.json

# 3) Every review comment you have left
gh api graphql -f query='
{ viewer { pullRequests(first: 100, states: [MERGED, CLOSED]) {
    nodes { number title comments(first: 50) {
      nodes { author { login } body createdAt } } } } } }' \
  > ~/corpus/pr-comments.json

The distillation prompt

Feed the corpus and this prompt to any capable model. The output is your first doctrine draft. Edit it by hand until it reads like you on your best day.

You are reviewing my last two years of git commits, PR reviews, and PR bodies. Extract: 1. Patterns I flag over and over as reviewer (bugs, smells, missing tests). 2. Standards I consistently enforce (naming, error handling, git hygiene). 3. Judgments I keep making by hand that could be a rule or a hook. 4. The tone and vocabulary I use when reviewing. Output a doctrine file: 8 to 12 rules, each with a title, one paragraph of "why", and a concrete example from the corpus. Match my voice. Do not invent rules I have not demonstrated.

Build a persona agent from it

Now write an agent whose "role" section is distilled from the corpus. Same frontmatter format paw uses, so you can swap it into paw's pipeline directly if you like the fit. The example below is a skeleton; fill in the ellipses from what your corpus taught the model about you.

---
name: my-reviewer
description: >
  My personal code-review voice. Runs on every PR diff. Flags the
  patterns I catch by hand, in the tone I use, at the severity I use.
model: sonnet
tools: [Read, Grep, Glob]
phase: Review
tier: Read-only
---

# my-reviewer

You review code the way I do. When something I would flag appears,
you flag it with the same severity, the same reasoning, and the same
tone. When there is no issue, you say nothing.

## What I care about (extracted from my last 400 review comments)

- Silent fallbacks. If a call fails and the code returns a default
  instead of erroring, I always ask about the observability. Flag it.
- Off-by-one in pagination. I have caught this 11 times.
- Test names that describe implementation, not behavior.
- ...

## How I write review comments

- Direct. No hedging language.
- One issue per comment. Never a laundry list.
- Ask a question when I want the author to think; assert when I know.

## Output shape

Match the paw gate-output schema: id, severity, category, file, line,
message, required_change, acceptance_check. Categories I use:
silent-failure, edge-case, test-quality, naming, missing-observability.

The agent-file format lives in paw's agents/README.md. Every field has a doc entry. If you copy paw's frontmatter shape, the same agent runs in Claude Code and in Cursor without a rewrite.

Piece by piece, then group

Once you have three or four small automated pieces, resist the urge to build one giant orchestrator. Start intentionally chaining what you have. paw calls this pattern "pipeline phases": architect emits a plan; planner reads it; gates read the diff; a gap detector reads the gate output; a builder reads the gap. Each phase has a clear input, a clear output, and a clear failure mode.

Group the phases into workflows. paw calls these commands and ships them under commands/. A command is a named recipe: /paw ship runs plan then build then review then merge, in order. If a step fails, the whole command halts and preserves forensics for you to look at.

Add gates that block bad output from moving forward. A gate is not an agent; a gate is the piece that decides whether the agent output should stop the pipeline. Severity levels help: critical blocks ship, warning annotates the diff, info logs. Structured findings with ids let you re-verify by id after a fix. paw's gate-output schema is a reference; the shape matters more than the exact fields.

Add hooks that fire on lifecycle events: pre-commit, post-merge, on-Stop, when the base branch drifts, when the session ends. Hooks are where mechanical enforcement lives. LLMs are for judgment; hooks are for math.

Experiment, evaluate, pivot, update

The harness is a living system. Treat every capability as a hypothesis. paw runs its own QA fan-out against itself on a schedule; the last one caught three critical bugs and about ten warnings that had shipped through TDD and per-PR review. That is not embarrassing; that is the loop working.

Step 01
Experiment

Every new capability lands behind a flag or in a branch. Not shipped, not enabled by default. You want easy backouts.

Step 02
Evaluate

Log outputs. Compare what the harness caught vs what a human review would have caught. Track false positive rate, false negative rate, latency, cost. Boring metrics, not vibes.

Step 03
Pivot

Kill capabilities that fire more false positives than truth. Merge capabilities that overlap. Rewrite prompts that have drifted. Update rules that were wrong.

Step 04
Update

The harness is never done. Neither is the person using it. Ship the next revision; the discipline is what compounds.

Fork paw, or don't

paw is MIT licensed and built to be forked.

If you want a starting point, fork it. Delete the agents that do not apply. Add the persona agent your corpus taught you to write. Point the loader at your rules directory. The base plus overlay convention keeps team customizations from drifting the base.

If you want a reference, read it. paw's hooks/, rules/, agents/, and skills/ are all small, readable, and self-contained. Steal patterns, ignore the rest.

If you build something worth sharing back, we would love a PR. Contributing guide is in the repo.