6 Critics Grade My Post, Then Fix the Skill That Wrote It Six adversarial critic subagents, dispatched in parallel by a Claude Code blog-post skill, returned two skill_adjustments that named the instruction file section responsible for a flaw, enabling a self-improving loop. The system, detailed by an unnamed author, pins each agent to a single failure mode via lane rules in agent files and requires exact quotes from indicted blocks, with the ai-detector lens filling a unique field so seven opinions merge by function. The approach solves the problem of generic reviewer notes that cannot edit instruction files because they never name the failed instruction. July 23, 2026 Six critics read my last draft in parallel. Two of their twenty findings were not about the draft at all: they came back as skill adjustments , naming a section of the instruction file that wrote it. That is the trick behind a self-improving Claude Code skill. The loop writes the patch. I apply it by hand, and the hand-apply is load-bearing. Running one general reviewer over the draft is where this usually dies. The notes come back generic, and a generic note cannot edit an instruction file, because it never names the instruction that failed. Stage 5 of my blog-post skill dispatches six adversarial critic subagents in a single message, so they run in parallel and never read each other's output. The six are rules-judge, claim-auditor, expert-skeptic, hostile-reader, ai-detector, and contract-lens. Each one owns a single failure mode and is told in writing to stay out of the other lanes. That lane rule lives in the agent files. The ai-detector's contract tells it the rules-judge already adjudicates regex-level hits, so it must not re-report an isolated one. Without that line, six reports collapse into the same report six times. --- name: blog-post-ai-detector description: Panel lens that reads a blog draft the way AI detectors and AI-literate readers do. Returns a detection-risk score. tools: Read, Grep, Glob model: opus color: red --- < -- ... -- Division of labor: the rules-judge already adjudicates the script's regex hits banned words, em dashes, "However," openers . Do NOT re-report an isolated regex-level tell. You own what regexes cannot see: statistical texture, structural templates, and pattern CLUSTERS. Model is pinned per agent. The orchestrator can run on something fast and cheap while every lens runs on opus, so a quick driver never degrades the judgment. | Criterion | rules-judge | claim-auditor | expert-skeptic | hostile-reader | ai-detector | contract-lens | |---|---|---|---|---|---|---| | Adjudicates mechanical script hits in context | ● | ○ | ○ | ○ | ○ | ○ | | Traces every claim back to the research brief | ○ | ● | ◐ | ○ | ◐ | ◐ | | Steelmans the strongest technical objection | ○ | ○ | ● | ◐ | ○ | ◐ | | Drafts the top hostile comment verbatim | ○ | ○ | ○ | ● | ○ | ○ | | Scores AI detection risk | ◐ | ○ | ○ | ◐ | ● | ○ | | Grades the draft against this post's reader contract | ○ | ○ | ◐ | ◐ | ○ | ● | | Reviews the artifact plan before anything is built | ◐ | ○ | ○ | ○ | ◐ | ● | | Can file a BLOCKER | ● | ● | ○ | ○ | ○ | ● | All six return the same JSON shape, with one field only the ai-detector fills. That is the only reason seven opinions can be merged by a function instead of by me reading seven reports at midnight. Both live in the same report. A finding indicts a block of the draft. An adjustment indicts the instruction that produced it. { "lens": "ai-detector", "aiRisk": { "score": 4, "drivers": "uniform paragraph shape across four sections" }, "findings": { "severity": "MAJOR", "block": 14, "evidence": "exact quote from the block being indicted", "issue": "which signal fired and why it fires here", "suggestion": "the rewritten human version of that sentence" } , "strengths": { "evidence": "exact quote", "why": "rhythm break, odd word, lived detail" } , "wow": { "score": 7, "moments": "the arbitration is a reducer, not a mood" }, "skill adjustments": { "file": "agents/writer.md", "section": "Inline Code Restraint", "problem": "Writer re-backticked the same token on every mention, so one paragraph rendered as five code chips.", "suggestion": "State the rule as first-mention-only and cap inline code at two spans per block." } } Every finding carries an exact quote from the block it indicts, and a lens that cannot produce the quote does not get to file the finding. Scoring is deliberately hard to game. Every lens returns a wow score from 0 to 10 and the merge takes the median instead of the mean. The claim-auditor reads a walkthrough as if it were an argument, comes back at 2, and a mean would drag a perfectly good draft into the revise pile on one lens's category error. A median absorbs that, and it absorbs the opposite case too, where a single lens falls in love with a paragraph the other six walked past. aiRisk is the exception to the whole averaging scheme, because only the ai-detector returns it, so the merge copies that object across verbatim. The last field is the one that changes anything. It names a file path and a section heading inside the instruction file that produced the draft. The Inline Code Restraint entry above is one my own panel filed against agents/writer.md . Here is the paragraph that triggered it, and the same paragraph after the rule landed. Set chrome to terminal , editor , diff , or plain , then make the label match it: terminal wants a shell context, editor wants a real file path, and diff wants before or after . Pick the chrome first, then make the label match it. A terminal frame wants a shell context, an editor frame wants a real file path, and a diff frame wants before or after. No framework is involved here. The Claude Code skills docs https://code.claude.com/docs/en/skills describe a skill as a directory with SKILL.md as the entrypoint, YAML frontmatter plus markdown instructions. Editing it is a Write call against a text file. How one lens report reaches SKILL.md Reflexion https://arxiv.org/abs/2303.11366 is the closest published loop, and the difference is where the lesson gets stored. Its reflections live in an episodic memory buffer scoped to the current task run. skill adjustments writes the durable instruction file that governs every future run. The next run does not remember this post and does not need to. It starts from a repaired instruction file instead. Collect only faults and every pass makes the instruction file more restrictive. Nothing in the loop ever argues for keeping a move that worked. I have not watched a self-editing SKILL.md sand off its own edges yet, and I would rather not learn how many runs that takes. Huang et al. https://arxiv.org/abs/2310.01798 ran the experiment that settles this. Loops carrying an external correctness signal improve. Loops running on self-critique alone drift down, and the model becomes more likely to break a correct answer than to fix a wrong one. So every lens returns a strengths array and a wow score next to its findings. Call that an oracle and I would be lying. Six prompts with disjoint mandates buy decorrelated error, and under Huang et al.'s own taxonomy a panel of same-family lenses is intrinsic self-correction wearing role prompts. The genuinely external signals here are three: the non-Claude peer, the mechanical regex pass that runs before the panel, and me applying adjustments by hand. strengths is a ratchet brake on the instruction file getting monotonically more restrictive, which is a different job from telling me whether the draft is correct. A reinforcement adjustment reads like this. { "file": "agents/writer.md", "section": "Voice", "problem": "none, this is a reinforcement entry", "suggestion": "Keep naming the wrong approach before the right one. hostile-reader and ai-detector both cited it as a wow moment. Do not promote it into a per-section template, which is how it stops working." } Reinforcement entries are the ones I edit hardest before applying. A note that says keep doing X sits one careless merge away from a rule that says always do X, and always-do-X is how you get a template. None of this matters if the skill never fires in the first place. Getting the description right so Claude actually invokes it is a different problem, and I covered it in how to write skills that actually trigger /blog/guides/create-claude-code-skills . The loop here presumes a skill that already runs. Six lenses plus an outside model from a different family run concurrently against the same draft. Seven reports come back and they disagree. A multi-model verdict has to be a function over the merged findings, because I am not arbitrating seven JSON files by hand. The seventh reviewer runs outside the subagent pool entirely. It is a separate CLI call fired concurrently with the six dispatches, handed the rendered draft and the reader contract, and told to review as an outside editor. bun ~/.claude/skills/rizz-partner/rizz.ts crew "Peer-review blog draft" \ --task "adversary: Read