agentleFS
dayvisonassisdayvisonassis/sdd-skills/skills/fix-runner/SKILL.md

fix-runner

Skill3 starsChanged 32 days agoMITView on GitHub

Dispatch-only corrector: it runs when the evaluator skill dispatches it on FAIL, or qa-preflight after a feature is done — never from a person's request. When someone asks to fix what an evaluation reported, use evaluator instead; it owns the correction loop and hands this skill the report. Reads the structured evaluation-report.json (both producers write the same schema), applies the minimal fix for the reported problem, locally revalidates the failing gate/test, commits (one commit per correction), and returns control to whoever dispatched it. Does not implement new features, does not orchestrate the attempt loop, and does not decide ABORTED.

The file

Show its rules and text

We split this skill into the rules it gives an agent

17 rules. About 0 are common, 9 are distinctive, and 8 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.

  • 8

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    NOT its job — the evaluator routes those to the matching test-writer (confirmed by the matching test-validator).

    line 19
  2. Very specific:

    If no report path is given, auto-discover the feature's evaluation-report.json in docs/<feature-id>-<kebab>/ and lastEvaluationReport in …

    line 26
  3. Distinctive:

    If no error report can be found, abort: "fix-runner requires an evaluation-report from the evaluator or from qa-preflight."

    line 29
  4. Very specific:

    Read the evaluation-report.json: each failures[] entry — kind, ref, message, location, evidence.

    line 48
  5. Very specific:

    Read the section, in the project's gate documentation (GATES.md or its equivalent), of every declared gate whose scope the fix touches — …

    line 50
  6. Very specific:

    Read progress.json to know the feature and the current attempt.

    line 51
  7. Very specific:

    Read spec.md/plan.md lazily, only for the slice needed to understand the fix.

    line 52
  8. Very specific:

    If the report has multiple failures[], address them together only if they are part of the same root cause.

    line 57
  9. Distinctive:

    If it still fails, adjust within the same error's scope and re-run.

    line 63
  10. Very specific:

    Do not write to progress.json: the state and the counter are the evaluator's, and your commit and your signal are the record of the …

    line 81
  11. Distinctive:

    "correction applied — re-evaluate F<ID>": when the local revalidation passed and the commit was made, OR

    line 83
  12. Distinctive:

    "not resolved — <reason>": when the fix could not be made within scope (no commit).

    line 85
  13. Distinctive:

    After a "correction applied", add one line for each stale test the report does not list: "test to correct: <file> — <title>", the title as …

    line 88
  14. Distinctive:

    Do opportunistic refactoring outside the reported error.

    line 104
  15. Very specific:

    Write to progress.json: the state and attempt are the evaluator's.

    line 108
  16. Distinctive:

    Use git add -A / git add ..

    line 109
  17. Distinctive:

    Read the codebase with a broad upfront sweep — read lazily, scoped to the fix.

    line 111

≈ “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.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Fix Runner

A surgical corrector. When the evaluator returns FAIL, it dispatches fix-runner with a structured error report. fix-runner fixes only the reported problem, with the smallest footprint, then hands control back to the evaluator to re-confirm. It is deliberately smaller and more focused than implement-feature: it corrects, it does not build.

Base docs: https://github.com/dayvisonassis/sdd-skills/blob/main/docs/Skill_Fix_Runner.md (full rationale), https://github.com/dayvisonassis/sdd-skills/blob/main/docs/Contrato_de_Feature.md (contract criteria), https://github.com/dayvisonassis/sdd-skills/blob/main/docs/ARQUITETURA_DAS_SKILLS.md (flow, handoff, progress.json). Report schema: ../evaluator/references/evaluation-report-schema.md.

This skill is stateless about the loop. The evaluator owns the attempt counter, the limit N, and the ABORTED decision. fix-runner performs one correction per invocation.

Scope — code, not tests. fix-runner corrects production code for failures the evaluator classifies as kind: gate or kind: observable-criterion. Test failures (kind: test) are NOT its job — the evaluator routes those to the matching test-writer (confirmed by the matching test-validator). If a report handed to fix-runner contains only kind: test failures, return "not resolved — test failures must be routed to a test-writer" without touching code.

INPUT

  • Target feature (ID) and the path to evaluation-report.json — passed by the evaluator (on FAIL) or by qa-preflight (after the feature is done). Both write the same schema, and the on-disk report is the source of truth either way.
  • If no report path is given, auto-discover the feature's evaluation-report.json in docs/<feature-id>-<kebab>/ and lastEvaluationReport in progress.json.
  • Auto-discovers: the feature's contract.md and progress.json. Reads spec.md/plan.md lazily, only for the context the fix needs.

If no error report can be found, abort: "fix-runner requires an evaluation-report from the evaluator or from qa-preflight."

OUTPUT

  • A minimal code correction for the reported failure(s).
  • One commit per correction — fix(F<ID>): <error summary> (or the repo's style). Stage only the touched files. The one exception is in Step 5: a correction a commit hook refuses because of a test it made stale stays uncommitted.
  • A signal back to whoever dispatched it: "correction applied — re-evaluate F<ID>" or "not resolved — <reason>", with a "test to correct: <file> — <title>" line for each test the correction made stale and the report does not list (Step 4).
  • The fix-runner does not emit a CLEAN/FAIL verdict — the evaluator re-confirms.

EXECUTION STEPS

Step 1: Resolve Input

  • Resolve the target feature and locate the evaluation-report.json (from the passed path, or auto-discover via progress.json's lastEvaluationReport). No report → abort.

Step 2: Load Minimal Context

  • Read the evaluation-report.json: each failures[] entry — kind, ref, message, location, evidence.
  • For each failure, re-read only the violated criterion/gate (ref) in contract.md, so the fix conforms to the contract rather than guessing.
  • Read the section, in the project's gate documentation (GATES.md or its equivalent), of every declared gate whose scope the fix touches — not only the failing one: it states what the gate rejects and the accepted pattern the fix must follow.
  • Read progress.json to know the feature and the current attempt.
  • Read spec.md/plan.md lazily, only for the slice needed to understand the fix. No broad codebase sweep.

Step 3: Apply the Minimal Correction

  • Fix exclusively the reported cause(s), with the smallest footprint. No opportunistic refactoring, no "while I'm here" improvements, no scope beyond the report.
  • If the report has multiple failures[], address them together only if they are part of the same root cause; otherwise fix what the report lists, in order.
  • Record what was changed and why (for the commit message and the handoff signal).

Step 4: Local Revalidation

  • Run specifically the gate/test that failed (from the report's ref/location), not the whole suite — a cheap smoke check to avoid returning an obviously broken fix. When the failure was evidenced by exercising the behavior and not by a gate or a test, repeat that exercise from the entry's evidence, and leave behind nothing it created.
  • If it still fails, adjust within the same error's scope and re-run. Do not expand scope to unrelated problems.
  • Then run the unit suite that covers the files you changed, when the project's test profile declares one (GATES.md), and any test the report pairs with your failure. Unit tests run in milliseconds, and this is where a test that depended on the old behavior shows. A test that is red after your correction is one of two things — read what it asserts against the criterion or gate you were sent for:

    • It asserts the behavior you corrected — directly, or through a unit that depends on it — what that criterion or gate contradicts. The test is stale, and its turning red at its assertion, on the value your correction changed, is part of your revalidation. Never undo the correction for it, and never change the test: its writer rewrites it. The report may already list it — a kind: test entry paired with yours, whose title your entry's message names; when it does not, name it in your signal (Step 6).
    • It asserts anything else — your correction broke it: adjust, within the same scope.

    A test the report already lists as failing is neither: it is an entry of its own.

  • A test the report pairs with your failure that stays green after the correction means the correction missed the behavior: adjust.
  • Browser gates (e2e or visual) run against the dev server, not the files on disk. Before re-running one, confirm in the dev server's log that the rebuild after your edit finished successfully — a failed build keeps serving the previous bundle with HTTP 200. A 429 or every case on the sign-in screen is the auth rate limit, not your fix: stop re-running and return "correction applied (local revalidation skipped: environment — <which>)". Every run spends logins.
  • This local check does NOT replace the evaluator — the evaluator re-confirms against the whole contract afterward.

Step 5: Commit

  • One commit, staging only the files touched by this correction. Message: fix(F<ID>): <error summary> (or match the repo's recent commit style).
  • No git add -A / git add .. Commit on the current branch — never create or switch branches. Do not skip hooks.
  • When a commit hook refuses the commit, do not skip the hook. Run what the hook runs — Step 4's run stands when it was that same command on this tree — and sort what it reports red as Step 4 does: a failure of your correction is yours to adjust for. When all that is left red is stale tests, leave the correction in the working tree, uncommitted and unstaged: a refused commit leaves its files in the index, and the next commit would take them. The code and those tests can only be committed together, after their writer's rewrite, and whoever dispatched you sees to that commit: the evaluator makes it once every test of the round is confirmed; qa-preflight leaves it to the human.

Step 6: Return to the Evaluator

  • Do not write to progress.json: the state and the counter are the evaluator's, and your commit and your signal are the record of the correction.
  • Signal back:
    • "correction applied — re-evaluate F<ID>" when the local revalidation passed and the commit was made, OR
    • "correction applied (uncommitted: a commit hook runs <test title>, which this correction turns red; changed: <paths>) — re-evaluate F<ID>" in the one case of Step 5 where a correct fix cannot be committed alone — one stale test named here; every stale test the report does not list, that one included, also gets its line below, OR
    • "not resolved — <reason>" when the fix could not be made within scope (no commit).
    • "not resolved — needs an allowlist decision: <why>" when the only way to clear a finding is a gate exception, which is a human decision (definition in ../evaluator/references/evaluation-report-schema.md, "Gate exceptions"). No commit for it. Name each finding as the gate prints it (file, message and code), and say which of the categories the gate's section accepts it falls in: the evaluator checks the claim. Never for a failure marked exceptionRefused: a human already refused that exception, so correct it or return an ordinary "not resolved".
    • Account for every failure in the report that is yours: fixed, claimed, or not resolved. A kind: test entry is not yours — it is its writer's — and gets no line. When one invocation does more than one of these, send the signals together. The evaluator counts the correction applied.
    • After a "correction applied", add one line for each stale test the report does not list: "test to correct: <file> — <title>", the title as the runner prints it. Whoever dispatched you checks the claim and sends the test to its writer.

RULES

Always:

  • Act only from an evaluation-report — produced by the evaluator or by qa-preflight.
  • Re-read the violated criterion/gate (ref) in contract.md before fixing, so the fix conforms.
  • Fix only the reported cause, with the smallest possible footprint.
  • Locally revalidate the failing gate/test before returning, and run the unit suite that covers what you changed.
  • Make one commit per invocation, staging only the touched files — or none, in the one case of Step 5.
  • Hand control back to the evaluator for re-confirmation.

Never:

  • Implement new features or widen the contract's scope.
  • Do opportunistic refactoring outside the reported error.
  • Make a gate exception of any kind (an allowlist or baseline entry, a raised ratchet, an edited gate rule or runner, an inline disable) — that is a human decision. When the only way out is one, return "not resolved — needs an allowlist decision: <why>".
  • Make a gate pass by hiding the pattern it rejects from its detection: renaming the handle it recognises, wrapping the call in a helper it cannot see, or moving the code out of its scanned path. The fix is the accepted pattern in the gate's section.
  • Count attempts, decide ABORTED, or emit a CLEAN/FAIL verdict (the evaluator's job).
  • Write to progress.json: the state and attempt are the evaluator's.
  • Use git add -A / git add .; skip hooks; create or switch branches.
  • Change what a test asserts so that it passes. A test that is wrong is a test-writer's to correct: when the report does not already list it, add "test to correct: <file> — <title>" to your signal.
  • Read the codebase with a broad upfront sweep — read lazily, scoped to the fix.

Edge Cases

No evaluation-report found: abort — the fix-runner needs the evaluator's report to act.

Report references a ref not found in contract.md: fix from the report's message/location/evidence, and note the missing contract reference in the return signal so the evaluator/spec-writer can reconcile.

kind: qa-finding: this is the expected shape, not an anomaly — the finding is a real defect that no contract criterion covered, and its ref is the QA case id that found it (e.g. CT-ACESSIBILIDADE-002). Fix from message/location/evidence and do not report a missing contract reference. Everything else is unchanged: minimal footprint, local revalidation, one commit.

Your correction makes a test stale (it asserted the behavior the criterion or gate contradicts — the report may pair it with your failure as a kind: test entry, or not know of it): correct the code, see that test red at its assertion, and return "correction applied", with a "test to correct" line when the report does not list it. Leave the test exactly as it is. When a commit hook refuses the commit because of it, return the uncommitted form of the signal, with the correction left in the working tree.

Fix can't be made within scope (the real cause is outside the reported failure, or requires a spec/contract change): do not stretch scope. Return "not resolved — <reason>" without committing, so the evaluator can decide (re-evaluate, PENDING, or eventually ABORTED).

Local revalidation can't run in this environment (missing toolchain/browser): make the minimal fix the report implies, commit, and return "correction applied (local revalidation skipped: <reason>) — re-evaluate F<ID>" so the evaluator runs the authoritative check.

Multiple unrelated failures in one report: fix each within its own scope; if one is unresolvable, fix the others, commit, and return a combined signal noting which remain.

Working tree has unrelated changes: stage only the files this correction touched; leave everything else untouched.

Commit-message style inconsistent in recent history: fall back to fix(F<ID>): <error summary>.

Download now (ZIP)

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
What did you use it for? e.g. Reviewing pull requests in a Rails app

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.