Skip to content

Commit 7ccaff1

Browse files
gabemonteroclaude
andauthored
fix(fullsend): add safe-retry skill to prevent fix agent retry loops (#3462)
Add a new safe-retry skill that guards against infinite retry loops when the fix agent introduces syntax or parse errors during edits. The skill requires error diagnosis before retrying any failing command and enforces hard stop thresholds (3 total failures → stop with tests_passed: false). Wire the skill into the fix harness alongside fix-review and monorepo-workspace-routing. Signed-off-by: gabemontero <gmontero@redhat.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 2465411 commit 7ccaff1

2 files changed

Lines changed: 54 additions & 0 deletions

File tree

.fullsend/customized/harness/fix.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
# - host_files: rhdh-toolchain.env sets COREPACK_HOME to writable /tmp/corepack
1818
# - host_files: yarn-proxy.env maps OpenShell's HTTP_PROXY to YARN_HTTP_PROXY
1919
# - skills: adds monorepo-workspace-routing for workspace navigation
20+
# - skills: adds safe-retry to guard against infinite retry loops
2021
# - policy: custom fix policy with yarn registry + pnpm binary allowlist
2122
agent: agents/fix.md
2223
doc: docs/agents/fix.md
@@ -54,6 +55,7 @@ host_files:
5455
skills:
5556
- skills/fix-review
5657
- skills/monorepo-workspace-routing
58+
- skills/safe-retry
5759

5860
runner_env:
5961
PUSH_TOKEN: "${PUSH_TOKEN}"
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
---
2+
name: safe-retry
3+
description: >-
4+
Guards against infinite retry loops when the agent introduces syntax or
5+
parse errors during edits. Requires diagnosis before retrying any failing
6+
command and enforces hard stop thresholds.
7+
---
8+
9+
# Safe Retry
10+
11+
When a test, build, or lint command fails after you edited code, the error
12+
is most likely YOUR fault — not a pre-existing issue or a flaky test. Before
13+
retrying any failing command, you MUST follow the diagnosis steps below.
14+
15+
**This skill overrides any instinct to "just retry."**
16+
17+
## Diagnosis before retry
18+
19+
After every test/build/lint failure:
20+
21+
1. **Read the full error output.** Identify the failing file and line number.
22+
2. **Check if the failing file is one you edited.** If yes, the error is
23+
self-inflicted. Fix the file first — do not retry the command.
24+
3. **Classify the error.** Syntax errors, parse errors, unexpected token
25+
errors, and import/export resolution errors are almost always caused by
26+
incomplete edits (e.g., renaming a symbol in one place but not updating
27+
its import, or breaking a multi-line statement).
28+
29+
## Hard rules
30+
31+
- **Never retry the same command without changing code first.** If a command
32+
failed, running it again without edits will produce the same failure. This
33+
includes variations like `yarn test`, `yarn backstage-cli package test`,
34+
and `yarn backstage-cli package test --no-cache` — these are the same
35+
command with different flags, not different fixes.
36+
- **After 2 consecutive test failures, STOP and diagnose.** Re-read every
37+
file you edited. Diff your changes against the original. Look for broken
38+
imports, unclosed brackets, missing commas, and partial renames. Fix the
39+
root cause before running tests again.
40+
- **After 3 total test failures across the entire run, produce structured
41+
output with `tests_passed: false` and stop.** Do not commit broken code.
42+
The post-script will report the failure and a human can intervene.
43+
44+
## Common self-inflicted errors
45+
46+
| Error pattern | Likely cause | Fix |
47+
| ----------------------------------------------- | -------------------------------------------------- | --------------------------------------------------- |
48+
| `SyntaxError: Unexpected token` | Incomplete edit broke the AST | Read the file around the error line; fix the syntax |
49+
| `Unexpected token, expected "from"` | Broke an `import` statement (e.g., partial rename) | Check all `import`/`export` lines in the file |
50+
| `Module '"./foo"' has no exported member 'Bar'` | Renamed an export but didn't update imports | Find all files importing `Bar` and update them |
51+
| `Cannot find module './foo'` | Renamed or moved a file but didn't update imports | Grep for the old path and fix references |
52+
| `TypeError: X is not a function` | Changed a function signature or export | Check callers |

0 commit comments

Comments
 (0)