Skip to content

Produce → judgement gate (LLM or reviewer) → revise cycle with loop guard

State: open/active · Genre: analysis

Use case: llm-judged-revise-cycle RFC mapping: UC5 Source: cross-repo survey of sksizer/* (2026-07-05), companion to the workflow-constellation RFC (PR #682).

Work products are gated by a judgement — an LLM verifier, an external PR reviewer, or a spec-completion check — and revised in a cycle that must be bounded by a loop guard, often persisted across runs (consecutive no-change counters, fire-at-most-once prose rules). The judge, the revise dispatch, and especially the guard are all hand-built.

Rework loop: resolve unresolved PR review threads → rebase → re-invoke agent with REWORK_FEEDBACK → verify → push → reply; bounded by a persisted ReworkGuard JSON counting consecutive no-change cycles (block after 2), automated by a 529-line hand-rolled polling daemon.

Where: python/darkfactory/workflow/definitions/prd/rework/workflow.py · python/darkfactory/rework/guard.py · python/darkfactory/cli/rework_watch.py

Pain: ~700 lines of infrastructure around one conceptual judgement-gated loop.

Two-phase PRD workflow (implement, then a second claude invocation as LLM verification judge against a checklist), rewritten four times (bash/python × simple/full); a 9-state lifecycle where a separate verification agent advances or blocks requirements by editing frontmatter.

Where: scripts/prd-workflow.sh · .claude/skills/prd-verification/SKILL.md (the python twins, prd_workflow.py/prd_simple.py, were dead duplicates of the shell versions and have been deleted)

Pain: The judge step and its state transitions are enforced only by model adherence to prose; four rewrites signal no reusable composition layer.

task-ensure-ready: deterministic verify → on gap dispatch the LLM fixer task-auto-define exactly once → re-verify → pass or downshift, with the bound enforced by prose warnings (‘do NOT dispatch a second time in this run’).

Where: plugin/skills/task-ensure-ready/SKILL.md · plugin/skills/task-auto-define/SKILL.md

Pain: A one-iteration judge cycle whose bound exists only as capitalized prose because no combinator can cap it.

Two-phase review → apply fleet flows: read-only LLM review pass aggregating per-repo reports into a tempdir REVIEW.md, then a disconnected mutating apply pass that re-clones and re-derives everything, with a human as the judgement gate between them.

Where: scripts/template_review_all.sh · scripts/cousin_apply.sh · scripts/cousins.json

Pain: Review findings are discarded /tmp state; the apply phase carries none of the judge’s output forward.

ralph_loop sketch: work → static validations (loop back) → spec verification (loop back, typestate Specification machine with attempt counts) → summarize, ending in the comment ‘Have to translate this into a generic engine’ — stalled at exactly that gap.

Where: examples/lib_ralph_loop/mod.rs · examples/lib_ralph_loop/model/specification.rs

Pain: The cycle was specified in comments and dead code because the composition layer didn’t exist.

@flow/workflow’s judge combinator. The evidence adds two requirements: loop guards that persist across process runs (DarkFactory’s no-change counter — needs @flow/durable), and external-judgement variants where the judge is a human reviewer arriving asynchronously via PR comments (needs a trigger/resume story, see triggered-recurring-runs).

Builds on: 05 Introduces: judge()

Same loop shape with an LLM-judgement gate; the producer can be 05’s entire cycle — combinators nest:

import { judge } from "flowline/workflow";
const reviewed = judge("self-review", {
produce: implementLoop, // 05's cycle nests as the producer
evaluate: llmReviewer, // agent -> { verdict: "approve" | "revise", notes }
reviseWith: addressNotes, // agent step: reads notes, loops to evaluate
accept: (v) => v.verdict === "approve",
maxRounds: 3,
});

Approve/revise enums, round caps, and revision-note threading stop being per-script prose contracts (agentpants’ review lifecycle, DarkFactory’s rework watch).


← Back to Notes