Layers and Generators

Concept: Vocabulary that names a phenomenon.

A failure sequence contains layers when each fix permanently removes one blocker, and a generator when one root cause keeps producing fresh failures across attempts.

Where the name comes from: Wolf McNally coined layers and generators after a four-attempt acceptance-gate incident in 2026. The first three failures were masked blockers; fixing each exposed the next. A fourth root cause produced a different-looking failure every time the gate ran. A search across software reliability, loop termination, systems thinking, and agent-loop practice found no established term for the pair.

Understand This First

• Failure Mode — the discipline of naming distinct ways a system breaks.

• Feedback Loop — the repeating act, observe, and correct structure in which these sequences appear.

• Monotonic Progress — the rule that each iteration must shrink remaining work or blocking uncertainty.

What It Is

Fix-and-retry work produces a sequence of failures. You change something, run the gate again, and inspect whatever fails next. That familiar rhythm can hide two different mechanisms.

A layer is one member of a finite stack of blockers. The first failure masks the second because the gate stops at the earliest violated condition. Fix the first and it stays fixed. The next run reaches farther and exposes the second. Each correction removes something from the remaining work, so the sequence can terminate.

A generator is a root cause that manufactures another failure on each attempt. The surface may change: a new error message, a different test, or a fresh review finding. Fixing the latest symptom doesn’t remove the mechanism that produced it. The next run gives that mechanism another chance to express itself.

QuestionLayersGenerator
What changed after the fix?One blocker is goneOne symptom is gone
Does remaining work shrink?YesNo, or not measurably
Will another run reveal useful information?UsuallyOnly if it tests a root-cause hypothesis
What should you do?Keep fixing and rerunningStop the symptom loop and repair the mechanism

Consecutive failures don’t have to look alike. Layers can resemble each other, while a generator can vary its output on every run. Test root-cause identity instead: did the last fix retire part of a finite set, or did the same unresolved cause produce another member of an open-ended set?

Why It Matters

Every run has a cost. A local unit test may cost seconds. A full integration suite, security review, deployment rehearsal, or model-based evaluation can cost hours and money. “Fix what failed and try again” is rational only when the loop has evidence that another attempt can advance.

Layers justify patience. A compiler reports the first type error, then the next. An installer checks prerequisites in order. An acceptance gate stops at its first hard failure. The visible sequence grows because earlier failures masked later ones, but the actual work shrinks after each sound fix.

Generators justify interruption. A stale schema produces a new mismatch wherever execution reaches next. A confused agent repairs each review comment while preserving the mistaken requirement that causes them. A nondeterministic evaluator invents a fresh objection each round because its rubric doesn’t constrain judgment. More attempts can produce more evidence without producing more progress.

Exact or near-exact repetition is the easiest generator-driven failure to catch. A detector can fingerprint the same tool call with the same arguments. It can’t catch a generator that emits a different symptom, filename, or explanation on every turn. Surface variation makes the loop look productive. Root-cause identity reveals that it isn’t.

How to Recognize It

Start with one question after each fix: What became impossible because of this change?

If the answer is concrete, you may be clearing a layer. The invalid configuration can no longer pass validation. The missing dependency is now installed and pinned. The failing invariant has a regression test. The next run can still fail, but it can’t fail for that same reason without disproving the fix.

If the answer is only “that message won’t appear again,” suspect a generator. Renaming the complaint, suppressing one exception, or satisfying one free-form reviewer doesn’t constrain what the underlying mechanism may produce next.

Useful evidence includes:

• A decreasing measure. Error count, unresolved criteria, or unverified assumptions falls and doesn’t rebound. The measure must track remaining work, not activity such as commits or tokens spent.

• A durable exclusion. A test, type rule, schema, or invariant prevents the repaired failure from returning through another path.

• Cross-attempt cause mapping. Different-looking failures trace back to the same assumption, state mutation, rubric gap, or contract mismatch.

• A stable finish line. The gate checks fixed criteria. If the evaluator can mint new criteria after every attempt, the evaluation process itself may be the generator.

Warning: Don’t classify a sequence from one attempt. A single failure can’t tell you whether it masks a finite stack or came from a mechanism that will regenerate. Compare at least two attempts and record what each fix made impossible.

How It Plays Out

A coding agent runs a compiler that stops after a bounded number of diagnostics. The first pass shows a missing import. The next reaches an incompatible return type, and the third exposes an unreachable match arm. Each correction is covered by the compiler and remains fixed. The failures are layers. The team keeps running the cheap gate because every pass reduces the known error set.

Another agent is told to make a service “production ready,” but the request has no acceptance criteria. One reviewer asks for retries. After retries arrive, the next review asks for caching; then rate limiting; then a migration plan. Every addition is defensible, yet no fixed measure moves toward done because the evaluator can generate another plausible requirement forever. The missing specification is the generator. The right move isn’t a fifth implementation pass. It is to stop, define the finish line, and rerun against that fixed contract.

A deployment rehearsal fails first on an expired credential, then on a missing database migration, then on a malformed health check. Each fix removes a distinct blocker and the rehearsal reaches a later stage. On the fourth run, three different services report unrelated validation errors. Investigation shows they all consume code generated from an obsolete schema snapshot. Repairing each service would chase symptoms; regenerating from the current schema removes the common source.

Consequences

Benefits. The distinction makes retry decisions evidence-based. Teams can keep working through masked blockers without mistaking new failures for regression. They can also stop expensive loops before surface variation consumes the whole budget. Monitoring improves when tools group failures by causal mechanism instead of exact message identity.

Liabilities. Root causes are hypotheses, not facts delivered by the error message. A team can misclassify a deep stack as a generator and stop too early. It can also call a generator “one more layer” until the budget is gone. The decreasing measure can lie: error count may fall while semantic damage grows. A model-based judge can score each attempt higher while drifting away from the user’s need.

The practical answer is to pair the classification with a retry budget. Spend a bounded number of attempts collecting evidence. Continue while fixes create durable exclusions and the remaining-work measure falls. When failures vary but map to one unchanged cause, stop paying for symptoms and work on the generator.

Complements: Monotonic Progress — Monotonic Progress tests whether a loop is advancing; layers and generators explain why progress is shrinking or flat.

Complements: Retry Budget — A retry budget limits blind repetition, while this distinction decides whether another fix-and-retry attempt can converge.

Contrasts with: Cascade Failure — A cascade spreads failure across components; a generator recreates failure across attempts.

Informs: Loop Engineering — Outer loops need this classification to distinguish finite repair work from structurally non-convergent churn.

Informs: Trusted Monitoring — A monitor uses root-cause identity, rather than surface similarity, to recognize a generator.

Refines: Failure Mode — Layers and generators classify failure modes by what happens across repeated fix-and-retry attempts.

Refines: Feedback Loop — The distinction asks whether each turn of a corrective feedback loop reduces the work that remains.

Sources

• Wolf McNally introduced the layers and generators distinction from a documented 2026 acceptance-gate incident in Bartley’s own engineering work. A prior-art search found established foundations for each half but no earlier source naming this exact pair.

• Robert W. Floyd’s “Assigning Meanings to Programs” (1967) established the use of assertions and well-founded reasoning about program behavior. Dijkstra’s later loop-variant formulation makes the termination test explicit: a loop needs a measure that strictly decreases.

• Algirdas Avizienis, Jean-Claude Laprie, Brian Randell, and Carl Landwehr’s “Basic Concepts and Taxonomy of Dependable and Secure Computing” (2004) distinguishes transient, intermittent, and permanent faults, the reliability lineage behind deciding whether another attempt can help.

• Eliyahu M. Goldratt’s It’s Not Luck (1994) develops Current Reality Trees for tracing many undesirable effects to shared root causes. Peter Senge’s The Fifth Discipline (1990) describes the related “Fixes That Fail” systems archetype, in which symptom relief leaves the generating structure intact.

• “Practical Limits of Autonomous Test Repair” (2026) examines why an agent without a formal correctness signal can’t reliably distinguish progress from lateral variation across repair attempts.