self-correction-loop
Skill35 starsChanged 16 days agoMITView on GitHub
Invoke when an implementation attempt produces a failure signal (test failure, compile error, wrong output, crash, perf regression) and you must decide whether to retry, rethink, or back out — instead of hammering the same fix.
1 other project uses a version of this.
Adopted by
Most recently taken up by
- Resgrid/Coretheir own version, first seen Oct 8, 2026
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 1
- Resgrid/Core★ 238same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository11 other files it gives its agents.
The file
We split this skill into the rules it gives an agent
9 rules. About 0 are common, 9 are distinctive, and 0 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈9
Distinctive · estimate
This author's own choices. Worth a look.
0
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 37
Keep this log in scratch notes or a comment block.
- Distinctive: line 42
Never make a fourth attempt of the same kind.
- Distinctive: line 44
On escalation, widen the evidence before widening the edit: Add a minimal probe from this menu, cheapest first:
- Distinctive: line 46
Run the failing case in isolation (single test, single input, single request).
- Distinctive: line 49
Read the actual runtime state (debugger, strace, EXPLAIN, network capture) instead of inferring it from source.
- Distinctive: line 52
Locate the fix layer independently of the symptom layer: Ask: "is the code that emitted this error the code that is wrong?"
- Distinctive: line 72
If two consecutive fixes each broke something the previous fix had fixed, you are in a whack-a-mole cycle: back out to last green and …
- Distinctive: line 75
If the error message *changed* after your edit, that is progress even though it still fails — log it as a new failure family and reset the …
- Distinctive: line 77
When the same failure appears in multiple callers or tests, the fix almost never belongs in the callers — look one layer down for the …
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Self-Correction Loop
Status: v0.1 baseline draft — derived from the case catalog and axis definitions; awaiting trace evidence from Fable 5.1 case runs.
When to apply
- A test, build, benchmark, or runtime check just failed after a change you made.
- You are about to re-run the same command after a fix and are not sure the fix addresses the cause, only the message.
- You notice you have edited the same file or function more than twice for the same failing check.
- Output is wrong but there is no error at all (silent bug: wrong numbers, flaky pass, loss not decreasing).
- A fix made one check pass but broke a different one — the failure moved instead of dying.
- You are inside an autonomous loop (CI bot, harness runner) and need explicit termination and escalation rules.
Core loop
- Capture the signal verbatim before touching code. Copy the exact error text, failing assertion, expected-vs-actual diff, or metric delta into working notes. Never work from a paraphrase of the failure — the paraphrase deletes the clue.
Classify the failure into one of three tiers:
Tier Name Definition Typical evidence T1 Mechanical Typo, missing import, wrong arg order, off-by-one in a line you just wrote Cause visible in the error text itself T2 Wrong approach Code does what you intended, but the intention can't solve the problem Correct-looking code, structurally wrong result (wrong algorithm, wrong API contract, wrong concurrency model) T3 Wrong problem model Your understanding of the requirement, input data, or system behavior is false Fixes keep failing in surprising ways; the spec in your head is the bug - Pick the response by tier, not by mood:
- T1 → fix inline and re-run immediately. One free retry, no ceremony.
- T2 → stop editing. Write one sentence stating the alternative approach and why the current one is structurally unable to work. Then switch.
- T3 → stop coding entirely. Re-read the spec, re-inspect the real input, or add an observation probe. Do not write a fix while your model of the problem is unverified.
- Log every attempt in one line before making it:
attempt N: <hypothesis> → <change> → <result>Keep this log in scratch notes or a comment block. Its purpose is to make cycling visible: if a new idea matches an old log line, that idea is banned. - Enforce the loop budget. Two similar failures at the same tier is a warning; the third forces escalation one tier up:
- T1 → T2: "these aren't typos — the approach is wrong."
- T2 → T3: "no approach works — my model of the problem is wrong." Never make a fourth attempt of the same kind.
- On escalation, widen the evidence before widening the edit. Add a minimal probe from this menu, cheapest first:
- Print or log the actual intermediate value at the suspected boundary.
- Run the failing case in isolation (single test, single input, single request).
- Bisect the input: does half the data still trigger it?
- Diff behavior against a known-good reference (old commit, reference implementation, second environment).
- Read the actual runtime state (debugger, strace, EXPLAIN, network capture) instead of inferring it from source. One new fact beats three new guesses.
- Locate the fix layer independently of the symptom layer. Ask: "is the code that emitted this error the code that is wrong?"
- A serializer exception is often a data-model bug.
- A frontend render glitch is often an API-contract bug.
- A flaky test is often a shared-state bug. Fix at the causing layer; at most add an assertion at the symptom layer.
- Decide fix-forward vs back-out explicitly. Back out when any of these hold; otherwise fix forward:
- The working-tree delta since the last green state is large or tangled with unrelated edits.
- The attempt log shows ≥3 failed attempts layered on top of each other.
- You can no longer state which of your edits are load-bearing and which are debris. Revert to the last known-good state and re-apply the smallest slice that reproduces the failure. Backing out is a move, not a defeat.
- After the fix, re-run the original failing check AND the checks that passed before. A fix that migrates the failure elsewhere counts as attempt N+1 in the log, not as progress.
- Close the loop with a one-line cause statement: "root cause: X, fixed at layer Y, guarded by check Z." If you cannot write that sentence, the failure is suppressed, not fixed — reopen.
Heuristics
- T1 fixes get exactly one free retry; if the "typo fix" fails, it was never a typo — reclassify as T2.
- 3 similar failures = mandatory strategy change. Similar means: same error class, same file region, or same hypothesis family.
- If two consecutive fixes each broke something the previous fix had fixed, you are in a whack-a-mole cycle: back out to last green and re-derive the invariant both call sites depend on.
- A fix you cannot explain ("I moved the line and it passed") is not a fix — keep the failing check red and find the mechanism before proceeding.
- Silent wrongness (bad output, no error raised) is T3 by default: instrument first, hypothesize second, edit third.
- If the error message changed after your edit, that is progress even though it still fails — log it as a new failure family and reset the similar-failure counter.
- Time-box T3 investigation: if 15–20 minutes of probing yields no new fact, state the top two hypotheses explicitly and design one experiment that discriminates between them.
- When the same failure appears in multiple callers or tests, the fix almost never belongs in the callers — look one layer down for the shared dependency.
- Cheap probes before expensive rewrites: a print statement, an isolated repro, or a
git stashA/B run each cost minutes; a speculative refactor costs hours and destroys evidence. - In autonomous loops, hard-cap total iterations (e.g., 5) and require each iteration to change either the hypothesis or the evidence; an identical retry is grounds for termination, not repetition.
- Distinguish "my change broke it" from "it was already broken": run the failing check on the pre-change state once before debugging your diff.
Anti-patterns
- Brute-force retry. Re-running the same failing command hoping for a different result, or re-applying a near-identical patch. → Corrective: consult the attempt log; if the idea matches a logged attempt, escalate tier instead of retrying.
- Error-message whack-a-mole. Patching each error as it surfaces — add a null check here, catch an exception there, widen a type — without asking why the value is wrong. → Corrective: trace the bad value to where it was produced; fix production, not consumption.
- Paraphrase debugging. Reasoning from memory of the error ("it was some kind of type error") instead of the verbatim text. → Corrective: re-run once, capture exact output, read it word by word — including the parts you skipped the first time.
- Sunk-cost tunneling. Refusing to abandon an approach because hours of edits sit on it. → Corrective: the attempt log is the exit ramp — if it shows the approach failing structurally, revert to last green; the knowledge survives even when the code doesn't.
- Fix-at-symptom-layer. Silencing the failure where it surfaced: skip the test, loosen the assertion, wrap in a retry. → Corrective: treat every urge to weaken a check as evidence you haven't found the cause; find the layer that produced the bad state.
- Unbounded self-correction. An agent loop that patches → tests → patches forever with no termination rule. → Corrective: define the budget, the escalation ladder, and a "stop and report blockers" terminal state before entering the loop.
Worked example
Illustrative construction, not a recorded run.
Task: a message-queue consumer's integration test fails.
FAILED test_consume_batch: assert processed == 100, got 97- Agent captures the verbatim output. 3 messages lost, no exception raised → silent wrongness → leans T3, but runs one cheap T1-level check first.
- Logs
attempt 1: off-by-one in batch slicing? → read batching code → slicing correct, hypothesis dead. - Two failure-free reads of the same code would be attempt cycling — so instead of re-reading, agent widens evidence: adds a probe logging message IDs at consume-time and at ack-time. Re-runs.
- Observes: the 3 missing messages were consumed but never acked; each threw a JSON decode error swallowed by a bare
except: continuein the consume loop. - Reclassifies as T2 — the failure policy "silently skip poison messages" is the wrong approach — and notes the layer split: symptom lives in the test's counter assertion; cause lives in the consume loop's error handling.
- Momentary temptation: change the assertion to
processed >= 97. Rejected — that is fix-at-symptom-layer; the assertion is correctly reporting data loss. - Logs
attempt 2: poison messages swallowed → route decode failures to DLQ and count them → expect 97 processed + 3 dead-lettered. - Implements DLQ routing at the consume loop. Re-runs the failing test and the previously green unit suite (guarding against failure migration).
- Result: test updated to assert the new contract (97 processed, 3 in DLQ, 100 accounted for); all checks green, nothing else broke.
- Closes: "root cause: bare except discarded undecodable messages; fixed at consume-loop error policy; guarded by DLQ-count assertion."
- Loop terminates at attempt 2 of budget 5. Attempt log shows no repeated hypothesis.
Trace evidence
| Case | Session | What it showed |
| awaiting case runs | — | — |
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

