{"id":"17b4c131-2114-4e8a-820b-9c4c198ac832","shortId":"tZXChp","kind":"skill","title":"fix-bug","tagline":">-","description":"!../principles/SKILL_BODY.md\n\n!../tool-gitnexus/SKILL_BODY.md\n\n---\n\n# Bug Fix Workflow\n\n## Disambiguating fix-bug vs modify-feature\n\n> **Use this skill when:** the code *should* do X but does Y — you want to restore correct behavior.\n> **Use modify-feature when:** the code does X correctly — you want it to do Z instead (desired behavior changed).\n>\n> Quick test: *\"Did this ever work correctly, or was it always intended to work differently?\"*\n> → **Yes, it used to work / should work** → fix-bug (continue here).\n> → **No, the requirement itself is changing** → **stop**. Tell the user: \"This looks like a behavior change rather than a bug fix — the modify-feature workflow is a better fit. You can say something like 'refactor/change how X works' to trigger the right workflow, or tell me to proceed anyway and I'll apply baseline rules only.\" Do not proceed unless the user explicitly says to proceed.\n>\n> Edge case: A feature never implemented but expected is a bug only if it was promised in an interface contract; otherwise **stop** and direct the user to `sextant:add-feature`.\n\n## Core Principle\n\nWhen fixing bugs, **make surgical modifications to the existing solution** — do not start over with a rewrite.\n\n---\n\n## Complete Execution Workflow\n\n> **Progress tracking:** At the start of each step, output an updated progress block so the user always knows where you are. Use this format:\n>\n> ```\n> Bug Fix Progress\n> ✓ Step 1: Reproduce & Locate   — <one-line finding>\n> ✓ Step 2: Impact Assessment    — Risk: <Low/Medium/High>\n> → Step 3: Minimal-Change Fix   — in progress\n> ○ Step 4: Boundary Validation\n> ```\n>\n> Replace `○` with `→` for the current step, and `✓` once complete.\n\n---\n\n### Step 1: Reproduce and Locate the Root Cause\n\nBefore making any changes, confirm:\n\n- What is the **specific manifestation** of the bug? (Error message, abnormal behavior, data anomaly)\n- What are the **trigger conditions**? (Specific input, timing, environment)\n- Where is the **root cause**? (Don't fix the symptom — find the source)\n\n**Localization techniques:**\n- Starting from the error manifestation, trace the call chain **upward** to the earliest point of failure\n- Distinguish between \"where the bug is exposed\" and \"where the bug originates\" — they are often not the same place\n- Check whether **implicit state assumptions** have been violated (e.g., a variable expected to be non-null is actually null)\n- Pay attention to **boundary conditions**: null values, zero values, overflow, concurrency races, type mismatches\n\n🔗 When GitNexus is available, use `context` / `trace` MCP tools for enhanced root-cause tracing.\n\n### Step 2: Impact Assessment\n\nAfter locating the root cause, assess the potential impact of the fix:\n\n- Which **callers** does this function/method have? Will their behavior change after the fix?\n- Does the bug location involve a **public interface**? Will the fix change the interface contract?\n- Is there other code that **depends on the bug's behavior**? (Sometimes bugs have existed so long that other code has adapted to the erroneous behavior)\n\n🔗 When GitNexus is available, use `impact` MCP tool to enumerate callers automatically.\n\n```\n─── Bug Impact Assessment ───────────────────────────\nBug location: <file/function name>\nRoot cause: <brief description>\nNumber of callers: <N>\nInvolves public interface: Yes / No\nPossible code depending on buggy behavior: Yes (explanation) / No\nFix impact scope: Internal only / Affects callers / Cross-module\nRisk level: Low / Medium / High\n─────────────────────────────────────────────────────\n```\n\n**When risk level is \"High\" (involves public interface or cross-module), you MUST inform the user of the impact scope and confirm before fixing.**\n\n---\n\n### Confirmation Gate (between Step 2 and Step 3)\n\nAfter completing the Impact Assessment, **before writing any code**, use the confirmation gate with:\n\n- **question**: A concise Proposed Fix Plan (see format below)\n- **options**:\n  - `\"Yes, apply the fix\"`\n  - `\"No — let's discuss a different approach\"`\n\n**Proposed Fix Plan format:**\n```\nRoot cause   : <one sentence>\nWhat changes : <file:line-range — what will be added/removed>\nCallers affected : <N callers — names>\nRisk         : <Low / Medium / High> — <one-sentence justification>\n```\n\n**Decision rules by risk level:**\n\n| Risk | Behavior |\n|------|----------|\n| **High** | Always use the confirmation gate. Do not touch any file until user selects \"Yes\". |\n| **Medium** | Always use the confirmation gate. Do not touch any file until user selects \"Yes\". |\n| **Low** | Use the confirmation gate with an additional option `\"Yes, and skip confirmations for low-risk fixes in this session\"`. If the user selected that option earlier in the **current conversation**, proceed directly without using the confirmation gate for subsequent low-risk fixes — this preference is session-scoped only. |\n\n**If user selects \"No\":** ask *\"What direction would you prefer?\"*, incorporate their feedback, update the Proposed Fix Plan, and use the confirmation gate again before proceeding.\n\n---\n\n### Step 3: Minimal-Change Fix\n\n**Execution discipline:**\n- **Only change the part of code that causes the bug** — do not expand the scope of changes\n- **Maintain style consistency**: The fix code is fully consistent with surrounding code style (naming, indentation, comment language)\n- **Annotate changes**: Comments explaining the fix reason, format: `# fix: <reason description>`\n- **No hitchhiking**: Don't \"optimize\" unrelated code while fixing a bug — this introduces new regression risk\n\n**✅ Correct fix approach:**\n```python\ndef calculate_discount(price, rate):\n    # fix: rate = 0 causes division by zero; added boundary check\n    if rate <= 0:\n        return price\n    return price / rate\n```\n\n**❌ Incorrect fix approach:**\n```python\n# Rewrote the entire function — introduces unnecessary change risk\ndef calculate_discount(price, rate):\n    if not isinstance(price, (int, float)):  # Added type checking (not part of this bug)\n        raise TypeError(\"...\")\n    validated_rate = max(rate, 0.01)          # Changed boundary strategy (not the original behavior)\n    return round(price / validated_rate, 2)   # Added rounding (not part of this bug)\n```\n\n### Step 4: Boundary Validation\n\nAfter completing the fix, check:\n\n```\n─── Fix Verification Checklist ──────────────────────\n[ ] Is the original bug fixed? (Verify with original trigger conditions)\n[ ] Is the normal path still correct? (Regression validation)\n[ ] Are related boundary conditions handled correctly? (Null, zero, extreme values)\n[ ] Does the fix introduce new boundary issues?\n[ ] Does caller behavior still match expectations?\n[ ] Do related unit tests pass? If new tests are needed, use the sextant:write-tests skill\n    with bug-fix context: root cause (Step 1) + impact scope (Step 2) already resolved.\n[ ] Is the style consistent with surrounding code?\n─────────────────────────────────────────────────────\n```\n\nReport to the user: **Fix complete ✅** or **Additional issues found ⚠️ (with description)**.\n\n---\n\n## Forbidden Actions\n\n- Delete the old function and write a new \"better\" replacement (unless the user explicitly requests refactoring)\n- \"Optimize\" unrelated code while fixing a bug (introduces new variables, increases regression risk)\n- Use a temporary patch to work around the problem without fixing the root cause (e.g., adding `try/except` to swallow the exception)\n- \"Mask\" the bug with defensive code without understanding the root cause\n\n---\n\n## Exceptions (Require Explicit User Authorization)\n\nThe following situations can break the \"minimal change\" principle, but **must be initiated by the user**:\n- User says \"this approach has fundamental flaws, try a different approach\"\n- User says \"redesign this module/component\"\n- User says \"refactor this part of the code while you're at it\"\n\nEven when the user authorizes expanding the scope, **fix the bug first, then refactor** — do it in separate steps, don't mix them together.\n\n---\n\n## Common Bug Pattern Quick Reference\n\n| Bug Pattern | Typical Manifestation | Investigation Direction |\n|-------------|----------------------|------------------------|\n| Null/None reference | `NoneType has no attribute` | Check if data source can be null/None |\n| Out-of-bounds access | `IndexError` / `KeyError` | Check collection length / key existence |\n| Concurrency race | Intermittent errors, data inconsistency | Check if shared state reads/writes are locked |\n| Type mismatch | `TypeError` / implicit conversion error | Check type consistency across layers |\n| State leak | Previous call's state affects the next | Check for unreset global/class-level variables |\n| Missing boundary | Abnormal behavior for specific inputs | Check null, zero, negative, very large values |\n| Async timing | Callback/Promise order doesn't match expectation | Check missing await, event order |\n| Configuration error | Only occurs in specific environments | Check env vars, config file differences |\n\n---\n\n## Sprint State Integration\n\nIf `.sextant/state.json` exists in the project root and the current task matches a sprint task:\n\n- **On start:** offer to update the task's `status` from `pending` → `in_progress`. Ask: *\"Update sprint state to mark Task N as in_progress?\"*\n- **On completion** (acceptance condition met): offer to update `status` to `done`. Ask: *\"Update sprint state to mark Task N as done?\"*\n- **On blocker** (test failure, missing dependency, unresolvable ambiguity that halts progress): surface the issue, then ask: *\"Mark Task N as blocked and record the reason in flags?\"* If confirmed, set `status: \"blocked\"` and append `{\"task\": N, \"reason\": \"<one-sentence blocker description>\"}` to the top-level `flags` array. Do not proceed to the next task while a task is blocked.\n\nDo not write the file without explicit user confirmation. If the user declines, continue without state updates.\n\n---\n\n## Reply Format\n\n**Lightweight task** (single function, < 50 lines changed): one sentence only.\n```\n✅ Fixed `<function>`: <root cause> — <what changed> (<file>:<line>).\n```\nor if something needs attention:\n```\n⚠️ Fixed `<function>`: <root cause> — <what changed>. Note: <one risk or open question>.\n```\n\n**Medium/large task** (cross-file, public interface, or high-risk): full block.\n\nFix Summary:\n\n| # | Item | Detail |\n|---|------|--------|\n| [1] | Conclusion | <one sentence: root cause + fix approach + outcome> |\n| [2] | Changes | <files / functions modified, with line ranges> |\n| [3] | Risks / Assumptions | <caller assumptions made; edge cases not yet covered> |\n| [4] | Verification | <Step 4 checklist status; unit test pass / fail / not yet run> |\n| [5] | Needs your input | <high-risk callers to review; tests the user should run> |","tags":["fix","bug","sextant","hellotern","agent-skills","claude-code","skill-md"],"capabilities":["skill","source-hellotern","skill-fix-bug","topic-agent-skills","topic-claude-code","topic-skill-md"],"categories":["Sextant"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/hellotern/Sextant/fix-bug","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add hellotern/Sextant","source_repo":"https://github.com/hellotern/Sextant","install_from":"skills.sh"}},"qualityScore":"0.457","qualityRationale":"deterministic score 0.46 from registry signals: · indexed on github topic:agent-skills · 14 github stars · SKILL.md body (10,753 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-04-22T13:03:25.852Z","embedding":null,"createdAt":"2026-04-19T00:40:20.722Z","updatedAt":"2026-04-22T13:03:25.852Z","lastSeenAt":"2026-04-22T13:03:25.852Z","tsv":"'/principles/skill_body.md':4 '/tool-gitnexus/skill_body.md':5 '0':801,811 '0.01':854 '1':230,261,953,1403 '2':234,396,547,867,957,1412 '3':240,550,724,1420 '4':248,876,1431,1434 '5':1444 '50':1372 'abnorm':283,1192 'accept':1274 'access':1144 'across':1174 'action':980 'actual':364 'ad':806,840,868,1025 'adapt':460 'add':178 'add-featur':177 'added/removed':601 'addit':652,974 'affect':508,603,1182 'alreadi':958 'alway':65,218,616,631 'ambigu':1300 'annot':765 'anomali':286 'anyway':131 'append':1326 'appli':135,576 'approach':585,792,819,1066,1073,1410 'around':1016 'array':1336 'ask':701,1261,1283,1308 'assess':236,398,404,479,555 'assumpt':350,1422,1424 'async':1204 'attent':367,1383 'attribut':1132 'author':1046,1096 'automat':476 'avail':383,468 'await':1214 'baselin':136 'behavior':34,53,96,284,419,449,464,499,614,861,924,1193 'better':110,989 'block':214,1313,1324,1348,1398 'blocker':1294 'bound':1143 'boundari':249,369,807,856,877,907,920,1191 'break':1051 'bug':3,6,12,79,101,159,184,226,280,331,337,426,447,451,477,480,740,784,847,874,890,947,1003,1033,1102,1117,1121 'bug-fix':946 'buggi':498 'calcul':795,830 'call':318,1179 'callback/promise':1206 'caller':412,475,488,509,602,605,923,1423,1451 'case':150,1427 'caus':267,300,393,403,485,591,738,802,951,1023,1041,1408 'chain':319 'chang':54,87,97,243,271,420,435,593,727,732,747,766,827,855,1054,1374,1413 'check':346,808,842,883,1133,1147,1158,1171,1185,1197,1212,1224 'checklist':886,1435 'code':22,41,442,458,495,559,736,753,759,780,966,999,1036,1086 'collect':1148 'comment':763,767 'common':1116 'complet':199,259,552,880,972,1273 'concis':567 'conclus':1404 'concurr':376,1152 'condit':291,370,896,908,1275 'config':1227 'configur':1217 'confirm':272,540,543,562,619,634,648,657,682,718,1321,1357 'consist':750,756,963,1173 'context':385,949 'continu':80,1362 'contract':168,438 'convers':676,1169 'core':180 'correct':33,44,61,790,902,910 'cover':1430 'cross':511,528,1389 'cross-fil':1388 'cross-modul':510,527 'current':255,675,1242 'data':285,1135,1156 'decis':608 'declin':1361 'def':794,829 'defens':1035 'delet':981 'depend':444,496,1298 'descript':978 'desir':52 'detail':1402 'differ':69,584,1072,1229 'direct':172,678,703,1126 'disambigu':9 'disciplin':730 'discount':796,831 'discuss':582 'distinguish':327 'divis':803 'doesn':1208 'done':1282,1292 'e.g':354,1024 'earlier':672 'earliest':323 'edg':149,1426 'enhanc':390 'entir':823 'enumer':474 'env':1225 'environ':295,1223 'erron':463 'error':281,314,1155,1170,1218 'even':1092 'event':1215 'ever':59 'except':1030,1042 'execut':200,729 'exist':190,453,1151,1235 'expand':743,1097 'expect':156,357,927,1211 'explain':768 'explan':501 'explicit':145,994,1044,1355 'expos':333 'extrem':913 'fail':1440 'failur':326,1296 'featur':16,38,106,152,179 'feedback':709 'file':594,625,640,1228,1353,1390,1414 'file/function':482 'find':306 'first':1103 'fit':111 'fix':2,7,11,78,102,183,227,244,303,410,423,434,503,542,569,578,587,662,689,713,728,752,770,773,782,791,799,818,882,884,891,917,948,971,1001,1020,1100,1378,1384,1399,1409 'fix-bug':1,10,77 'flag':1319,1335 'flaw':1069 'float':839 'follow':1048 'forbidden':979 'format':225,572,589,772,1367 'found':976 'full':1397 'fulli':755 'function':824,984,1371,1415 'function/method':415 'fundament':1068 'gate':544,563,620,635,649,683,719 'gitnexus':381,466 'global/class-level':1188 'halt':1302 'handl':909 'high':517,522,615,1395,1449 'high-risk':1394,1448 'hitchhik':775 'impact':235,397,407,470,478,504,537,554,954 'implement':154 'implicit':348,1168 'inconsist':1157 'incorpor':707 'incorrect':817 'increas':1007 'indent':762 'indexerror':1145 'inform':532 'initi':1059 'input':293,1196,1447 'instead':51 'int':838 'integr':1232 'intend':66 'interfac':167,431,437,491,525,1392 'intermitt':1154 'intern':506 'introduc':786,825,918,1004 'investig':1125 'involv':428,489,523 'isinst':836 'issu':921,975,1306 'item':1401 'key':1150 'keyerror':1146 'know':219 'languag':764 'larg':1202 'layer':1175 'leak':1177 'length':1149 'let':580 'level':514,520,612,1334 'lightweight':1368 'like':94,116 'line':596,1373,1418 'line-rang':595 'll':134 'local':309 'locat':232,264,400,427,481 'lock':1164 'long':455 'look':93 'low':515,645,660,687 'low-risk':659,686 'low/medium/high':238 'made':1425 'maintain':748 'make':185,269 'manifest':277,315,1124 'mark':1266,1288,1309 'mask':1031 'match':926,1210,1244 'max':852 'mcp':387,471 'medium':516,630 'medium/large':1386 'messag':282 'met':1276 'minim':242,726,1053 'minimal-chang':241,725 'mismatch':379,1166 'miss':1190,1213,1297 'mix':1113 'modif':187 'modifi':15,37,105,1416 'modify-featur':14,36,104 'modul':512,529 'module/component':1078 'must':531,1057 'n':604,1268,1290,1311,1328 'name':483,606,761 'need':937,1382,1445 'negat':1200 'never':153 'new':787,919,934,988,1005 'next':1184,1342 'non':361 'non-nul':360 'nonetyp':1129 'normal':899 'note':1385 'null':362,365,371,911,1198 'null/none':1127,1139 'number':486 'occur':1220 'offer':1250,1277 'often':341 'old':983 'one':1375,1405 'optim':778,997 'option':574,653,671 'order':1207,1216 'origin':338,860,889,894 'otherwis':169 'out-of-bound':1140 'outcom':1411 'output':210 'overflow':375 'part':734,844,871,1083 'pass':932,1439 'patch':1013 'path':900 'pattern':1118,1122 'pay':366 'pend':1258 'place':345 'plan':570,588,714 'point':324 'possibl':494 'potenti':406 'prefer':691,706 'previous':1178 'price':797,813,815,832,837,864 'principl':181,1055 'problem':1018 'proceed':130,141,148,677,722,1339 'progress':202,213,228,246,1260,1271,1303 'project':1238 'promis':164 'propos':568,586,712 'public':430,490,524,1391 'python':793,820 'question':565 'quick':55,1119 'race':377,1153 'rais':848 'rang':597,1419 'rate':798,800,810,816,833,851,853,866 'rather':98 're':1089 'reads/writes':1162 'reason':771,1317,1329 'record':1315 'redesign':1076 'refactor':996,1081,1105 'refactor/change':117 'refer':1120,1128 'regress':788,903,1008 'relat':906,929 'replac':251,990 'repli':1366 'report':967 'reproduc':231,262 'request':995 'requir':84,1043 'resolv':959 'restor':32 'return':812,814,862 'review':1453 'rewrit':198 'rewrot':821 'right':124 'risk':237,513,519,607,611,613,661,688,789,828,1009,1396,1421,1450 'root':266,299,392,402,484,590,950,1022,1040,1239,1407 'root-caus':391 'round':863,869 'rule':137,609 'run':1443,1458 'say':114,146,1064,1075,1080 'scope':505,538,695,745,955,1099 'see':571 'select':628,643,669,699 'sentenc':1376,1406 'separ':1109 'session':665,694 'session-scop':693 'set':1322 'sextant':176,940 'sextant/state.json':1234 'share':1160 'singl':1370 'situat':1049 'skill':19,944 'skill-fix-bug' 'skip':656 'solut':191 'someth':115,1381 'sometim':450 'sourc':308,1136 'source-hellotern' 'specif':276,292,1195,1222 'sprint':1230,1246,1263,1285 'start':194,206,311,1249 'state':349,1161,1176,1181,1231,1264,1286,1364 'status':1256,1280,1323,1436 'step':209,229,233,239,247,256,260,395,546,549,723,875,952,956,1110,1433 'still':901,925 'stop':88,170 'strategi':857 'style':749,760,962 'subsequ':685 'summari':1400 'surfac':1304 'surgic':186 'surround':758,965 'swallow':1028 'symptom':305 'task':1243,1247,1254,1267,1289,1310,1327,1343,1346,1369,1387 'techniqu':310 'tell':89,127 'temporari':1012 'test':56,931,935,943,1295,1438,1454 'time':294,1205 'togeth':1115 'tool':388,472 'top':1333 'top-level':1332 'topic-agent-skills' 'topic-claude-code' 'topic-skill-md' 'touch':623,638 'trace':316,386,394 'track':203 'tri':1070 'trigger':122,290,895 'try/except':1026 'type':378,841,1165,1172 'typeerror':849,1167 'typic':1123 'understand':1038 'unit':930,1437 'unless':142,991 'unnecessari':826 'unrel':779,998 'unreset':1187 'unresolv':1299 'updat':212,710,1252,1262,1279,1284,1365 'upward':320 'use':17,35,72,223,384,469,560,617,632,646,680,716,938,1010 'user':91,144,174,217,534,627,642,668,698,970,993,1045,1062,1063,1074,1079,1095,1356,1360,1456 'valid':250,850,865,878,904 'valu':372,374,914,1203 'var':1226 'variabl':356,1006,1189 'verif':885,1432 'verifi':892 'violat':353 'vs':13 'want':30,46 'whether':347 'without':679,1019,1037,1354,1363 'work':60,68,74,76,120,1015 'workflow':8,107,125,201 'would':704 'write':557,942,986,1351 'write-test':941 'x':25,43,119 'y':28 'yes':70,492,500,575,629,644,654 'yet':1429,1442 'z':50 'zero':373,805,912,1199","prices":[{"id":"5ef5a557-23dd-49d0-8a28-07fcd5db753d","listingId":"17b4c131-2114-4e8a-820b-9c4c198ac832","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"hellotern","category":"Sextant","install_from":"skills.sh"},"createdAt":"2026-04-19T00:40:20.722Z"}],"sources":[{"listingId":"17b4c131-2114-4e8a-820b-9c4c198ac832","source":"github","sourceId":"hellotern/Sextant/fix-bug","sourceUrl":"https://github.com/hellotern/Sextant/tree/main/skills/fix-bug","isPrimary":false,"firstSeenAt":"2026-04-19T00:40:20.722Z","lastSeenAt":"2026-04-22T13:03:25.852Z"}],"details":{"listingId":"17b4c131-2114-4e8a-820b-9c4c198ac832","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"hellotern","slug":"fix-bug","github":{"repo":"hellotern/Sextant","stars":14,"topics":["agent-skills","claude-code","skill-md"],"license":"mit","html_url":"https://github.com/hellotern/Sextant","pushed_at":"2026-04-07T00:57:27Z","description":"init","skill_md_sha":"092c89699b3caf8c268f6c7a5eb941ac835ec9d1","skill_md_path":"skills/fix-bug/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/hellotern/Sextant/tree/main/skills/fix-bug"},"layout":"multi","source":"github","category":"Sextant","frontmatter":{"description":">-"},"skills_sh_url":"https://skills.sh/hellotern/Sextant/fix-bug"},"updatedAt":"2026-04-22T13:03:25.852Z"}}