Gorewood Logs

The Spec Problem, Part 2: Dialectical Refinement

Part 1 ended with a hypothesis: a single reviewer tends toward over-engineering or over-simplification. You need opposing forces to converge on correct scope. I've been calling this process "dialectical refinement."

The core idea is adversarial tension. Instead of one agent writing a spec and calling it done, you run the spec through multiple phases with explicitly opposing goals. The Proposer argues for cuts. The Advocate argues against them. A Judge synthesizes. Each phase uses a fresh agent context โ€” no memory of previous reasoning โ€” so they can't self-reinforce their own mistakes.

Here's the process I've landed on, now codified as a skill:

Phase 1: Formalize. The Analyst surfaces ambiguity. What terms are undefined? What's the input/output contract? What exists versus genuinely new? This phase also tags "protected categories" โ€” things that must not be cut: core workflow, agent primitives like --json flags, explicitly user-requested features. You're establishing the boundaries before anyone argues about them.

Phase 2: Propose Cuts. The Proposer looks at the formalized spec and suggests simplifications. Strong candidates, moderate candidates, weak candidates. Crucially, the Proposer proposes but doesn't execute. It's building a case for the prosecution.

Phase 3: Challenge. The Advocate receives the Proposer's list and argues against each cut. Some cuts it accepts. Others it contests โ€” this feature has hidden value, that deferral will cost more later. The Advocate can also identify cheap additions the Proposer missed. Defense builds its case.

Phase 4: Scope Lock. A checkpoint before final synthesis. Are core workflow commands preserved? Agent primitives intact? User requests addressed? If the spec got cut too thin โ€” fewer than five commands for a system, structured output removed, all medium tasks reduced to trivial โ€” you loop back to Phase 3 with guidance to restore scope.

Phase 5: Synthesize. The Judge resolves remaining debates and produces the final spec. Concrete implementation details. Testable acceptance criteria. Explicit out-of-scope boundaries. The output must be standalone-reviewable โ€” an external agent with no conversation history should understand what's being built and why.

Not every spec needs all five phases. Trivial tasks skip refinement entirely. Medium complexity gets a compressed two-phase pass (Formalize โ†’ Synthesize). The full adversarial process is for large or extra-large work where hidden complexity is likely.

Why separate agents per phase? Each phase agent receives only previous output plus goals โ€” not internal reasoning. The Proposer doesn't remember why the Analyst included something, so it proposes cuts from scratch. The Advocate doesn't remember the Proposer's reasoning, so it challenges independently. This prevents the self-reinforcing agreement that tanks single-pass spec processes.

The connection to Yegge's five-iteration insight: he found that repeated passes through fresh context yielded stable specs. Dialectical refinement structures those passes with explicit roles. You're not just running the same prompt multiple times and hoping โ€” you're creating genuine tension between simplification and preservation, then resolving it.

I use this for fresh specs, epic refinement, even large individual tasks that feel "clear but big" (a warning sign for hidden complexity). The output hands off cleanly to Beads โ€” no markdown task conversion, no lifecycle ownership fights. Articulation stays in the refinement process. Execution stays in Beads.

This connects back to what I've been saying about industrialization: everyone is still inventing their own workflows. The e2e agent environments are getting better, but they don't easily accept parts of my workflow that I'm keen on. I'd rather see the industry move toward a Unix-pipeline approach โ€” pick your spec process, connect to your execution engine, swap components as better ones emerge.

I work in Claude Code partly because it's less opinionated. It lets me wire in superpowers brainstorming and writing-plans, my dialectical-refinement, uses plugins and skills to customize workflows, and whatever else I need. The tradeoff is I'm building more infrastructure myself (and probably missing out on a lot of value that I haven't discovered on my own yet). But I control the seams. When something better emerges or hits my radar, I can swap it in without rebuilding everything.

Dialectical refinement isn't final. I'm still finding where it works and where it's overkill. But the principle holds: opposing passes surface what single passes miss. Don't trust a spec until it's survived an argument.

#ai-development #tools #vibe-coding #workflow