Dev.to · 11 min read

Dynamic Workflows: Critical Analysis (pt. II) (feat. Fable)

Dynamic Workflows: Critical Analysis (pt. II) (feat. Fable)

[NOTE: This is a follow-up to this post where I began to develop a hermeneutic critique of the Claude Code Workflow tool from the perspective of a user who just wants the feature to work.] "Loop-until-dry": A Recipe for Disaster The Claude Workflow tool definition has substantially migrated out of the definition, and into a built-in Claude Code Skill, which is not publicly available for users to review. This makes it very difficult to implement tooling that attempts to leverage dynamic workflows: it's rather hard to know whether the design you have in mind will cohere with the bundled Skill or conflict with it. One concept that comes up in the workflow-authoring Skill is: adversarial review/verification. This is a useful pattern (in theory), because it forces Claude to submit its plans to a critic before committing to them, and if the critic can identify any issues, then Claude must revise the plan, and repeat the cycle. As a result (so the reasoning goes), at the end of the process, the plan will be strengthened in virtue of having had its defects exposed. This is a genuinely useful strategy that is often employed when making decisions in the "real world" - that's why scholarly journals use peer review, for example. But a strategy that is effective in the context of human interaction becomes a guaranteed failure mode when blindly applied to coding agents. I asked Claude Fable 5.1 to perform an adversarial review on the workflow-authoring Skill. This is how it turned out: REALLY HIM I did loop until dry the other day. It went on for, like, an hour because, you know, you're not naive: what happens when you ask an agent, "review something"? Do you find any errors? How likely is it that they will say no errors? They will invent things more likely than to say, "yeah, it's fine." FABLE Here is my own pass over the built-in reference, treating each pattern as a claim and asking how it fails in practice. Your loop-until-dry experience is not an outlier. Several of these patterns share the same defect. The finder prior is never addressed Every discovery pattern in the reference assumes an agent asked "find bugs" will eventually say "none." That assumption is wrong, and it is the root of most of the waste. Loop-until-dry. A finder prompted to find things is rewarded by its training for finding things. Given the same corpus and the same prompt, successive rounds are near-independent samples from the same distribution, not a search that exhausts a space. The dedup step compares keys, and a reworded duplicate is a fresh key. So "two consecutive rounds return nothing new" is a condition the process almost never reaches. Termination comes from the budget or the agent cap, which is what your hour-long run was. The reference adds no honesty valve ("an empty list is valid and preferred"), no narrowing of scope per round, and no exclusion of already-seen regions. Without those it is a random-sampling loop with a stopping rule that cannot fire. Completeness critic. Same defect, one level up. A critic asked "what's missing?" always finds something, so "what it finds becomes the next round of work" is an infinite tail generator with no bound and no ranking by consequence. Loop-until-count. The opposite failure. Repeated identical prompts return overlapping bugs, so the counter fills with duplicates and stops early with false confidence. There is no dedup in the example. Loop-until-budget. The only well-bounded loop, and it is bounded by being broke, not by being done. It spends to the ceiling by construction. Adversarial verify is weaker than it looks The example spawns three refuters with the identical prompt, the identical claim text, and no evidence or tools. Correlated votes. Three samples from the same model with the same input are not independent skeptics. A majority of correlated votes is roughly one vote with false confidence attached. Blind refutation. The refuter receives the claim as a string. It cannot check the code, so it refutes on plausibility or rubber-stamps. "Default to refuted if uncertain" makes the outcome a coin toss over prompt wording rather than a judgment over evidence. Attrition kills valid claims. The survival rule is two non-refuted votes among the survivors. If two of three verifiers die, which the reference says happens and tells you to filter away, the claim cannot survive regardless of merit. Dead agents and refuting agents have the same effect. That is a concrete bug in the reference's own example. The rubric shapes what reaches verification. In this morning's run, nothing reached the confirm phase because the assessor prompts capped everything at "concern." A verify pass only verifies what upstream labels chose to send. The reference presents verification as a filter on findings, but its real input is the labeling rules, which it never discusses. The reference does mention perspective-diverse verify, which is the right idea. It should be the default, and each verifier should be handed the evidence and the tools to reproduce, with survival requiring a citation, not a vote. Scale and cost are treated as one thing "Thoroughly audit" means more finders and 3 to 5 votes. Multiplicity on the same corpus produces duplicates and multiplies verify spend. Thoroughness comes from partitioning by file, subsystem, or lens, which is a different axis the reference does not name. "Token cost is not a constraint" under ultracode. Combined with loop-until-dry, a five-vote verify, and Fable inheritance, that sentence is the complete recipe for a run that costs an hour and a million tokens and reports the same six findings three times. Single-currency cost model. Pipeline is the default because it minimizes wall-clock. The reference never mentions that a pipeline has no stop-safe point, so an interrupted run forfeits everything behind its slowest item. Your TOPOLOGY-COSTS doc covers this. The harness reference does not. Model inheritance "almost always correct." Covered earlier. It is correct for cheap main models and wrong for the case that costs the most. The largest omission: empty versus failed The reference says agent() returns null on death and tells you to filter it out. It never distinguishes "found nothing" from "did not run." That single conflation corrupts every pattern above: a dead finder counts as a dry round, a dead verifier counts as a refutation, a dead assessor in a gate looks like a pass. The Rebuttal It wouldn't be very honest of me to ask for a one-sided critique and then present it as "Fable's Opinion", so I then asked Claude to present the other side of the argument: REALLY HIM ok so i asked you to take on an adversarial stance against the Skill guidance, so to be fair, I will now ask you to defend the Skill just as vigorously. FABLE Taken as a brief for the defense, the reference holds up better than my prosecution allowed. The strongest argument is about what kind of document it is. It is an API reference, and it is a good one The reference's job is to teach the primitives and their traps: agent returns text unless you pass a schema, parallel is a barrier and pipeline is not, stages take thunks not promises, meta must be a pure literal, Date.now breaks resume, a dead agent resolves to null and you must filter it, budget is a hard ceiling. Every one of those is a mistake a first-time author makes, and every one is stated once, correctly, with a runnable line. Judged as the document it is, it is dense, accurate, and unusually candid about failure modes. Most tool docs never tell you what returns null. The patterns section says, in its own words, "these patterns aren't exhaustive, compose novel harnesses when the task calls for it." They are sketches of control flow, three lines each. Criticizing Try to refute: ${claim} for not passing evidence is criticizing a three-line illustration for not being the thirty-line prompt the author is expected to write. The reference shows where the prompt goes. Filling it is the author's job, and the reference says so. The patterns I attacked are defensible on their own terms Loop-until-dry replaces while count < N, which is strictly worse for unknown-size discovery, and the reference says why: counters miss the tail. Non-termination is real, and the reference fences it three ways in the same section: a concurrency cap, a 1000-agent backstop, and the budget primitive presented right beside it with the explicit warning that an unguarded loop runs to the cap. An hour-long run is a run launched without a budget directive. The reference told the reader how to set one. And the composed example's note, dedup against seen rather than confirmed so judge-rejected findings don't reappear, shows the authors thought about convergence harder than a sketch requires. The finder prior is a prompt problem, and the prompt string is the one thing the author fully controls. Adversarial verify with default-to-refute is a deliberate asymmetry, not carelessness. A plausible-but-wrong finding forwarded to a human costs trust; a lost true finding costs one bug. The reference names that trade. Correlated votes still cut single-sample variance, and two-of-three catches exactly the temperature outlier that a lone verifier would ship. The very next bullet says to use distinct lenses when a finding can fail more than one way, which is the fix I demanded as if it were missing. The attrition arithmetic is one line the author owns, and the null convention that makes it fixable is documented. Empty versus failed is not absent from the harness. It is in the type: a dead agent is null, an honest-empty result is {findings: []}. The reference states the null case and tells you to handle it. What it lacks is a paragraph of methodology, and that paragraph belongs in a methodology document. Your AUTHORING.md is that document. A tool reference that duplicated it would be longer, would drift, and would still not be loaded on the by-name path. Model inheritance is the right default for the case the reference is written for: an inline script authored mid-task by a model that cannot reliably tier its own stages. Guessing wrong per stage is a worse failure than uniform. The text says "only set it when highly confident," which is a default with an override, not a prohibition. The Fable problem is a pricing artifact of one main-session model, and a pricing rule belongs in a launch hook, which is where you put it. Pipeline by default is the single most valuable instruction in the document. Barrier-by-default is the natural mistake, because everyone's mental model is Promise.all. The reference gives a smell test and a short list of the only justifications for a barrier. Resume loss is real and second-order; idle-time waste happens on every run, interruption on some. Ultracode is gated on an explicit opt-in confirmed by a system reminder. "Token cost is not a constraint" is the user's stated preference in that mode, and the same section still says to stay in the loop between phases and to go solo on trivial work. It is not a runaway directive. The evidence from this session favors it This morning's run was a script built entirely on these primitives. Seven agents, none dead, the null convention correctly handled by the dead-assessor logic, a security finding reproduced against the venv, and eight conditions a release manager can act on. Everything we diagnosed afterward was fit-to-repo and launch-path, and the editorial guidance that would have caught the fit problem was in this reference. It was not loaded, which is a trigger-design question, and a defensible one: the document is a few thousand tokens, and loading it on every turn of every session to serve the reuse case would tax the common case. The tool description keeps the invariants; the reference carries the rest. So the honest verdict from both sides: the content is sound for authoring from scratch, its sketches need the prompts and valves your plugin already supplies, and the two documents are complementary rather than in conflict. The failure was delivery, not doctrine. The Verdict Well, dear reader: what do you think? Having seen Fable's critique of the current Workflow architecture, as well as its defense, which side do you find more convincing?

This is a summary aggregated from Dev.to. Read the complete article on the original site:

Read full article at Dev.to

More AI & Machine Learning News