agentsclimarketplace

E2e driven iteration

Skill veegee82/loss-driven-development/skills/e2e-driven-iteration

Use at the start of every inner-loop iteration where the goal is to fix a bug / close a failing test / reach a green E2E. Forbids editing code without first running the E2E to capture a fresh loss signal, and forbids declaring "done" without the E2E passing. Makes the cycle "E2E → loss → 5-why-by-layer → fix → E2E" the only admissible rhythm.From its SKILL.md

Install
npx -y skills add veegee82/loss-driven-development --skill e2e-driven-iteration

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

9.0 KB, as published. Nobody here has run it

E2E-Driven-Iteration — inner loop (∂L/∂code), the forward-pass cadence

The Metaphor

The lab scientist with a hypothesis. Before any intervention: measure the baseline. After any intervention: measure again. Between the two measurements: exactly one change. "I know what this reagent does" without running the control experiment is not science — it is storytelling. The E2E run is the measurement device. Skipping it turns every edit into a story and leaves the loss unexamined.

Overview

In Gradient Descent for Agents, the E2E run is the forward pass. Every iteration of the inner loop has one: it produces the loss number this iteration descends against. This skill enforces the rhythm measure → diagnose → fix → measure inside loop-driven-engineering. The existing dach-skill says "run E2E when warranted." That's too soft. Under time pressure, "warranted" silently becomes "never" and the iteration degrades into blind-patching based on stale assumptions.

Core principle: when you are in a fix-loop (trying to close a failing signal), every iteration begins and ends with an E2E run of the failing case. The E2E is the forward pass; its output is the loss; the delta between iterations is the gradient signal that tells you whether the last edit helped or regressed.

No E2E at the start → no loss measurement → your edit is speculative. No E2E at the end → you don't know if you converged or just stopped.

See ../../docs/ldd/convergence.md §5 for how this skill implements the loss trace across the test pyramid.

When to Use

Invoke at the start of every inner-loop iteration whose purpose is:

  • Fixing a failing test
  • Closing a rejected gate
  • Resolving a production incident
  • Debugging an unexpected behavior
  • Converging on any goal where "is it fixed yet?" is the question

Do not use for: new-feature work where there's no failing E2E yet (write the E2E first, then enter this loop), pure refactors (no behavioral E2E to run), documentation-only changes.

The Six-Step Iteration

k-th iteration:
  1. Run E2E        → loss_k = measured rubric score / failing items
  2. Compare        → Δloss_k = loss_{k-1} − loss_k  (was the last edit a step or a random walk?)
  3. Diagnose       → invoke root-cause-by-layer, name layer 4/5
  4. Fix            → one focused edit, smallest coherent unit, at the named layer
  5. Run E2E again  → loss_{k+1} becomes loss_k of iteration k+1
  6. Emit trace     → python -m ldd_trace append ...  (see using-ldd §"Persisted trace")

Do not skip step 1 — "I know what broke, I'll just fix it" is the anti-pattern. Until you measured the current state, you don't know if the last change helped, hurt, or was a no-op.

Do not skip step 2 — if Δloss_k ≤ 0, the previous edit did not help. You are in oscillation or a local minimum. Invoke loss-backprop-lens before proposing another edit.

Do not skip step 5 — without the post-edit run, "fixed" is a claim, not a measurement.

Do not skip step 6 — the user needs to see the loss descend live, per-iteration. v0.5.1 makes this a hard step, not an optional summary at task end. Running python -m ldd_trace append ... appends to .ldd/trace.log AND prints the full trace block (sparkline + chart + per-iteration line) — one command satisfies both mandates. If the tool is unavailable, render the trace block manually per using-ldd/SKILL.md §"Loss visualization".

Red Flags — STOP, the loop is degrading

  • "I'll fix it then run the E2E at the end" → no loss measurement per step; you won't notice regressions
  • "The E2E is slow, I'll skip it this iteration" → you lost the gradient
  • "The last edit probably worked, don't need to re-run" → you don't know
  • "E2E keeps failing the same way, let me try something else" → Δloss is not going down; step size wrong (invoke loss-backprop-lens)
  • "I'll run the unit test instead, same signal" → only if the unit test covers the same failure surface; otherwise you're measuring a different loss
  • "Let me batch 3 fixes and run once" → conflates 3 gradient steps; if one regressed, you can't attribute
  • "I'll emit the trace block at the end of the whole task, the user doesn't need it per iteration" → NO. The user CANNOT see convergence without per-iteration emission; a final-block-only cadence gives them a single data point instead of a trajectory. Per-iteration trace is step 6, not optional.

E2E selection — cheap before expensive

If the failure reproduces at a cheaper pyramid tier (unit, integration), iterate there first. Only escalate to full E2E when the cheap tier can't reproduce.

TierUse as iteration gate when
UnitThe failure is localized to one function / class / module with no external deps
IntegrationThe failure crosses module boundaries but is deterministic with test doubles
E2E (fake externals)The failure involves orchestration but external APIs can be mocked
E2E (real externals)The failure involves real LLM / DB / network non-determinism

Running full E2E for a typo catchable at unit tier is a pyramid violation; it wastes budget and slows the gradient signal. Running only unit tests for a cross-boundary contract bug misses the real loss surface.

Budget interaction

This skill runs inside loop-driven-engineering's K_MAX = 5. The E2E-per-iteration cost sets a floor on how fast iterations can happen; if one E2E takes 30 minutes, your total budget is 2.5 hours. Plan accordingly:

  • Before entering the loop, estimate E2E cost and multiply by 5 — that's your budget ceiling
  • If estimate > available time, either cheapen the E2E (subset of scenarios, fake externals) OR accept you'll hit K_MAX and escalate
  • At K_MAX: escalation per loop-driven-engineering's §Escalation — with the added requirement of attaching the loss_k trace across all iterations

How to Apply — checklist

  1. Define the failing E2E. Exact command, expected state, measured state. Save the output of iteration 0 as loss_0. If .ldd/trace.log exists in the project, first run python -m ldd_trace status --project . to see prior iterations.
  2. Enter the loop. At the start of each iteration: run E2E, capture loss_k, compare to loss_{k-1}.
  3. Interpret the delta. Negative → progress, continue. Zero → no-op, rethink. Positive → regression, revert immediately and re-diagnose.
  4. Diagnose via root-cause-by-layer. Calibrate via loss-backprop-lens.
  5. Edit smallest coherent unit.
  6. Rerun E2E. That's loss_{k+1}.
  7. Emit trace block. Run python -m ldd_trace append --project . --loop inner --auto-k --skill <skill> --action "<what changed>" --loss-norm <v> --raw <n>/<max>. The tool appends to .ldd/trace.log AND prints the full trace block — show the output to the user.
  8. Close only when E2E is fully green AND the regularizers (contracts, docs) are honored — hand off to docs-as-definition-of-done. Run python -m ldd_trace close ... to record terminal status.

Common Rationalizations

ExcuseReality
"The E2E is slow, every iteration is expensive"Yes. That's why K_MAX = 5 and you must think, not guess. Slow E2E is itself a gradient — it tells you to invest in a faster test surface.
"I'll skip the start-of-iteration run to save time"You saved 5 minutes and lost the ability to tell if your last edit helped. Net loss.
"The loss barely moved, close enough""Close enough" is a claim, not a measurement. Either the rubric is too lax (outer-loop issue → method-evolution) or you're stopping before convergence.
"E2E passed once on try 2, ship"You owe a reproducibility-first check. One pass is one sample.
"I'll fix all three issues in one iteration, E2E at end"You cannot attribute which edit helped and which regressed. Run per edit.

Relation to other skills

  • reproducibility-first runs before this skill enters the loop — you must have a reproducible signal to begin.
  • root-cause-by-layer runs at step 3 of each iteration — diagnosis.
  • loss-backprop-lens runs when Δloss ≤ 0 to recalibrate step size.
  • loop-driven-engineering is the parent — this skill is what it dispatches during a fix-loop.
  • docs-as-definition-of-done runs at close — when the E2E is green, the loop isn't closed until docs are synced.

Real-World Cue

If your iteration log for a bug fix doesn't show a loss_k trace — one number per iteration, visibly decreasing toward zero — you were not doing E2E-driven iteration. You were hoping.

Keep looking

Skills are one crate of 628,853. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.