CtrlK
BlogDocsLog inGet started
Tessl Logo

bug-to-patch-generator

Automatically synthesizes code patches to fix identified bugs, leveraging the bug location and surrounding context. Use when a bug has been localized and the user wants an automated fix, when generating candidate patches for review, or when the user asks to fix a specific bug.

Install with Tessl CLI

npx tessl i github:santosomar/general-secure-coding-agent-skills --skill bug-to-patch-generator
What are skills?

93

Quality

91%

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SKILL.md
Review
Evals

Bug-to-Patch Generator

Produce the minimal edit that makes the failing test pass without breaking anything else. The discipline is subtractive: most first-draft patches are too big, and every unnecessary line is a line a reviewer has to verify.

Preconditions — do not start patching until you have these

PreconditionWhy you need itIf missing
Fault location (file:line)You need to know where to editbug-localization
Failing testYou need a red→green signalbug-reproduction-test-generator
Green baselineYou need to know what "doesn't break anything" meansRun the full suite once, record result

If you don't have all three, you are not patching a bug — you are guessing.

Step 1 — Classify the fault

Match the fault to a fix family. Different families have different minimal-patch shapes.

Fault classTypical symptomMinimal patch shape
Off-by-oneLoop over/under-runs by oneChange <<=, nn-1, ++ii++
Missing null/empty guardNPE / KeyError / index-out-of-boundsOne early-return or if (x == null) branch
Wrong operatorInverted condition, swapped argsSingle-token edit: &&||, swap two args
Wrong constantMagic number is slightly wrongOne literal changes
Missing state updateStale cache, unrotated log, unset flagOne statement added: the missing mutation
Wrong API callDeprecated/misused library callReplace call; may cascade to import/signature
Missing caseUnhandled enum branch / edge inputOne branch added to a switch/match/if-chain
Resource leakFD/connection/lock not releasedMove into try/with; add finally/defer

Start with the smallest family that could explain the symptom.

Step 2 — Draft the patch

Write the minimal candidate for the classified family. Constraints:

  • Touch one location if at all possible. Two-location patches are suspicious; three-location patches are almost always wrong or hiding a deeper design flaw.
  • No refactoring. The temptation to "clean up while you're here" couples the fix to unrelated risk.
  • No new abstractions. A bug fix that introduces a class or interface is a design change wearing a bug-fix costume.
  • Match surrounding style. If the file uses == not is, use ==.

Step 3 — Validate

Run validation in order of cost. Stop at the first failure.

GateWhat it checksOn failure
Compile / typecheckPatch is syntactically & type-validRevert; your classification is wrong
Failing test now passesPatch actually fixes the bugWrong family — go back to Step 1
Green baseline still greenNo collateral damageShrink the patch; you changed too much
behavior-preservation-checkerSemantic equivalence on unchanged pathsIf time allows — catches subtle breakage

Worked example

Input:

  • Fault: src/pagination.py:47 in page_slice(items, page, per_page)
  • Failing test: test_last_page_partial — last page returns [] when it should return 2 items
  • Code at fault line:
def page_slice(items, page, per_page):
    start = page * per_page
    end = start + per_page
    if end > len(items):
        return []                    # line 47
    return items[start:end]

Classification: Missing case — but look closer. The guard end > len(items) isn't missing a case, it's wrong. The fault class is actually wrong operator: it should only bail when start is past the end, not end.

Minimal patch:

-    if end > len(items):
-        return []
+    if start >= len(items):
+        return []

One line. items[start:end] already handles end > len(items) correctly via Python's slice semantics.

Validation: test_last_page_partial passes; full suite green. Done.

Edge cases

  • The fix is "delete the guard": Sometimes the bug is the defensive code. If removing a condition makes the test pass and nothing else fails, removal is the fix. Don't invent a replacement guard.
  • Two fixes both work: Pick the one closer to the fault's introduction point. If commit A added a bad condition and commit B worked around it downstream, fix A and delete B's workaround.
  • The test was wrong: Rare but real. If the code matches spec and the test doesn't, patch the test — but flag it explicitly; never silently flip an assertion.
  • Intermittent failure: Stop. You cannot validate a patch against a flaky oracle. → bug-reproduction-test-generator to stabilize first.

Do not

  • Do not add try/except to swallow the symptom. That's a bug in a trench coat.
  • Do not broaden the fix beyond the failing scenario "just in case." You don't have a test for "just in case."
  • Do not change the test assertion to match current behavior unless you've established the test is wrong.
  • Do not ship a patch that touches more than ~5 lines without a second review. The minimal fix for a real bug is almost never that big.

Output format

## Patch
<unified diff — minimal>

## Classification
<fault family from table>

## Validation
- [ ] compiles
- [ ] failing test → pass
- [ ] baseline suite → green
- [ ] behavior-preservation check (optional)

## Assumptions
<anything the patch relies on that isn't proven by the test>
Repository
santosomar/general-secure-coding-agent-skills
Last updated
Created

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.