Charlotte, NC
BlogNovember 3, 2026

Claude writes, Sol reviews: the skills I chain together for AI coding

Blake McCarn
Claude writes, Sol reviews: the skills I chain together for AI coding
I don't want to explain my development process every time I open a coding agent. Writing the code is only part of the job. Someone still has to settle what we're building, reproduce the bug, check the result, and decide whether the change belongs in the project at all. I use Claude Code, Codex, and Oh My Pi (OMP) side by side. A set of skills gives all three the same process, even though the tools don't have the same features. What I care about is the order of the work and where each agent has to stop. My global instructions come from one private repo, and every tool reads the same file. A repo's own instructions win inside that repo. I wrote up how that repo keeps six machines in step on the fleet project page. What matters here is that switching tools doesn't change what I mean by done. Claude Code gives me Claude's own workflow. Codex gives me OpenAI's coding and review environment. OMP lets me give each model a role, including an advisor that watches the agent doing the work. I keep those differences. I'm not trying to make the three tools act the same. I covered the terminal and worktree side in my Herdr post. Organized sessions help, but they don't tell an agent whether it's supposed to be planning, editing, or reviewing. That's what the skills are for. Most of this process already existed as other people's skills. I keep local copies of them and write my own skills around them. The copies let me keep my local changes when the upstream versions move. The building blocks are council, sol-loop, and babysit-pr from tstack, unslop, technical-writing, and blast-radius from pstack, and grilling, to-spec, and to-tickets from Matt Pocock's skills. The review skill I lean on most, ponytail-review, comes from the ponytail plugin. My own skills, scope, tee-up, and vet, are what I call a skill of skills. Each one chains several of those building blocks in a fixed order and decides what the agent is allowed to do at each step. That second part matters most to me. A skill that writes a plan shouldn't quietly turn into a skill that deploys it. scope starts by finding the project's tracker. If the repo names one, it uses that. Otherwise it looks for a project vault, then falls back to GitHub Issues. If none of those fit, it asks me instead of inventing a new place to keep tasks. Then it runs grilling, which questions me until we agree on the plan. The agent reads the code first, so it asks me about decisions, not facts it could look up. Once we agree, to-spec turns those decisions into a draft spec with acceptance criteria I can check and a list of open questions. A model from a different family reviews that draft against our decisions and the code, in one read-only round. It flags decisions the spec dropped, criteria nobody can test, gaps, and scope I didn't ask for. The agent fixes wording and testability problems itself and brings real decisions back to me. Only then does to-tickets cut the work into tickets that can each be built and proven on their own. I approve the spec and the breakdown together. The agent publishes them, reads every item back to check its text and links, and stops. Planning is done, and nothing is built yet. When I want a ticket built, I say "tee up" with a GitHub issue, a vault ticket, or a task in my own words. The ticket is the intent. The agent works from it, not from its own summary of what it thinks was asked. For a bug, the agent has to watch it fail before it edits anything. For a feature, it writes the test for an acceptance criterion and watches that test fail because the behavior doesn't exist yet. If it can't reproduce the problem, it stops and shows me the evidence instead of guessing at a fix. The work happens in its own Git worktree. A focused test has to fail without the change and pass with it, and the agent runs the checks CI runs: tests, lint, type check, and build. Then come two reviews, one after the other. First is sol-loop, where GPT 6.1 Sol reviews the change in rounds. Once that loop ends, its fixes are committed, and the checks pass again, ponytail-review runs once on the final diff. I run ponytail last on purpose. It's the review that pushes back on extra code, and every sol-loop round can add some. If both ran at once, ponytail could approve a diff that the Sol loop was about to change. tee-up can create a branch, commit, push, open the PR, answer review comments, and fix CI failures the change caused. It can't merge, turn on auto-merge, deploy, or close the ticket. It runs unslop on the PR title and body before publishing, then uses babysit-pr to wait for CI and review bots. What I get back is an open, green, reviewed PR that only needs me to press merge. Those are instructions in a Markdown file, not permissions. The tools' own permission rules and the repo's branch protection still do the enforcing. This part comes from my own experience with these models, so take it as that. GPT tends to overengineer, and I trust Opus as the coding agent that does the implementing. Sol does a great job reviewing code and catching gaps. The combination of the two is the powerful part. A reviewer from a different model family and provider gives me a much stronger review than a second model from the same one. My OMP config makes the split explicit. Every role that can edit files resolves to Claude. Sol takes the review role and the always-on advisor. If an editing role has to fall back, it falls back to another Claude model, so a provider outage can't turn the reviewer into the author. Day to day, Opus 5.5 does the main work, with a higher thinking setting for planning. A deep preset moves the main and planning roles to Mythos 5.1 when I want it for a hard problem. Sol keeps the advisor and review roles in both. Sol's review turns run in fast mode. The rule works the other way too. When Sol writes a change in Codex, Opus reviews it. A different model family can still miss the same bug, so tests and reading the code still matter. If I ask GPT to review something, I get one pass and a pile of suggestions. sol-loop turns review into a short back-and-forth with rules:
  • A fixed budget. The default is three rounds. It goes to five only for security, permissions, auth, data loss, or concurrency, while a blocker or should-fix finding is still open with evidence, or when I ask.
  • Smaller later rounds. Round one reviews the whole change. Later rounds look only at the code that changed since and the findings that are still open.
  • A ledger. Every finding gets a stable id, a severity (blocker, should, or nit), and an outcome. In each new round, Sol marks every old id as resolved or says why it's still open.
  • One reviewer. Sol can't start subagents or more reviewers. In OMP, the sol agent doesn't even get the tool for it.
  • The smallest fix. The author makes the minimal change that answers a finding and prefers deleting or narrowing code over adding a lock, cache, helper, or option.
  • Room to push back. The author can disagree, with a file and line, a test, or command output as evidence, and the skill tells it not to agree just to end the loop. If a finding is still disputed after two replies, both sides come to me.
  • An early stop. A round that returns only nits ends the loop.
Sol also gets the intent quoted from the issue or spec, and code the intent doesn't ask for counts as a should, not a nit. Running out of budget isn't approval. ponytail-review tells the model to review a change "like the senior developer who will be paged when it breaks." It checks, in order, whether the change is correct, safe, holds up under the expected load, is tested, is fast enough, and is lean. Lean is the part I love. Ponytail flags dead code, options nobody uses, helpers the repo already has, standard-library features someone rebuilt, abstractions with one implementation, and near-copies that should be one thing. Every finding needs a concrete case, meaning an input or situation that gives a wrong result. The fix it proposes is the smallest one that works, ideally one that deletes code. The report sorts findings into must fix, should fix, and nice to have, and it ends with a verdict and a count of lines that could go. In tee-up, ponytail gets the ticket as the intent and has to answer one more question: what does this diff add that the ticket didn't ask for? That question is why it runs last. Anything other people will read goes through unslop first, including PR titles and bodies, review comments, tickets, and READMEs. It's a numbered list of patterns that make text read like a model wrote it, each with a fix. It cuts filler like "in order to," stacked hedges, inflated words like "crucial" and "leverage," em dashes, colons used as connectors, title-case headings, and decorative emoji. It also asks for active voice with a named actor, the plain word over the fancy one, and whole sentences instead of compressed fragments. I only run it on public text, not on every reply to me. vet is for work someone else wrote, whether that's a person, a bot, or another agent run. It stays read-only and starts by pinning the change to a specific head and base commit. Its most useful rule is about intent. A linked issue, a spec, or my own request beats the PR description. The PR description is the author's account of their own work. If I review only against that account, I can miss a perfectly built solution to the wrong problem. Vet runs one ponytail-review and one Sol review in parallel, since nothing gets fixed during a vet. Then the coordinating agent filters. It keeps a finding only when it names a concrete case and the agent has confirmed that case in the code itself. Vet counts nits and nice-to-haves instead of forwarding them. Every kept finding goes to the author as a question, and nothing gets posted until I say so. Here's one from this week. After a cleanup of my homelab cluster, a PR in my homelab repo set out to stop the leftovers from piling up again. The nightly Longhorn restore canary, which proves backups actually restore, had been leaving an empty BackupVolume behind on every run, and 135 of them had piled up. The PR gave the canary's cleanup step permission to delete its own BackupVolume. It also capped old ReplicaSet history at 3 on my plain Deployments and pinned four floating images to the digests already running. I covered the cluster itself in my Kubernetes homelab post. I ran vet on it. The intent came partly from a backlog item in my homelab vault and partly from the PR description, and vet labeled which was which. Sol came back with VERDICT: CHANGES and three findings:
  • S1 (should). The PR said every cleanup command ignores failures, but the existing pod delete line didn't. Under set -eu, one API error there would skip the snapshot, PVC, and BackupVolume deletes and mark a passing canary as failed.
  • S2 (should). One plain Deployment never got the ReplicaSet limit, so it stayed at Kubernetes' default of 10.
  • S3 (nit). The new Role granted deletecollection, which nothing used.
Ponytail found the same pod delete problem and checked it in the canary's own container image, where a failing command in the cleanup trap stopped the rest and the script exited 1. It found the missed Deployment too. It rated deletecollection higher than Sol did, because that one verb would let a single API call wipe every BackupVolume in the namespace, and those are my real backups. Ponytail's best catch was one Sol didn't make. Two of the images it pinned are ones I build myself. My Renovate config skips those images, and their pipelines only push a latest tag. With a digest pin, the next fix I shipped to either app would build fine and never reach the cluster, without any error. Ponytail suggested a different pin format. The fix that landed was simpler. It dropped those two pins and kept the deploy path that already worked. The fix commit was four small edits: || true on the pod delete, no deletecollection, the missed limit, and the two first-party pins removed. I merged it that afternoon. Neither reviewer could prove the new cleanup step works, and neither claimed to. It hadn't run yet at merge time. Its first real test was the canary run at 3:45 the next morning. council asks one strong model from each of three providers to review the same work, in parallel and read-only. The upstream skill suggests Claude Opus, GPT Sol, and Gemini Pro. My OMP setup names the three members directly: Claude Opus, GPT 6.1 Sol, and Muse Wonder Full 1.0, Meta's model, which runs as a read-only muse agent. Muse only runs in OMP, so that's where I run council. For a code review, each member scores the work out of 10, and the scores go into the PR description as a table. A score is a reviewer's opinion, not proof that the software works. If a member can't run, council reports that instead of swapping in another model. The Sol and Muse reviewer models have empty fallback chains in my config for the same reason. The project-vault skill reads the relevant private project notes at startup and writes back durable state after meaningful work. Vault RAG searches use the project's vault profile, while exact startup files and fresh edits use the local clone. I described the note structure in my Obsidian work-brain post, and the retrieval side has its own Vault RAG project page. The skill chain needs those handoffs, but it doesn't need to repeat the whole project history in every prompt. This process spends more tokens and takes more turns than asking one agent to write a patch and push it. Running reviews one after the other also delays the PR. I'm fine with that for changes where the requirements, the scope, or the failure behavior deserve another look. The real risk is review turning into its own source of extra work. Every reviewer can suggest one more abstraction or one more nearby cleanup. My instructions ask for the smallest change that fully solves the request, and a finding outside that request needs a reason before it becomes code. Ponytail running last is the other half of that. I still settle ambiguous requirements and disputed findings, and I decide when the evidence is good enough to merge. What I want at the end is a PR with a traceable request, a demonstrated result, and a clear account of what was checked.
  • Claude Code, Codex, and OMP for coding sessions and model-specific review routes
  • Opus 5.5 and Mythos 5.1 as implementers, GPT 6.1 Sol and Muse Wonder Full 1.0 as reviewers
  • Shared global instructions and repository-specific rules
  • My own scope, tee-up, and vet skills around vendored planning and review skills, plus the ponytail plugin
  • Git worktrees for isolated implementation
  • Repository tests, type checks, builds, and CI for executable evidence
  • Obsidian project vaults and Vault RAG for cross-session context
I want to spend my review time on the change itself, not on reconstructing what the agent thought it was asked to do. This workflow makes that reconstruction the agent's job before the PR ever reaches me.
Share this post: