{"id":"code-hotfix-checkout-down-friday","audience":"developers","category":"coding","technique":"constraints","track":"coding","level":"intermediate","free":true,"title":"Hotfix a checkout outage at 6pm Friday without touching anything else","task":"It is Friday 6pm and checkout is failing for every customer since the 5:40pm deploy. The on-call lead has set the rules: smallest possible fix, change only the line that crashes, valid orders must return exactly what they returned before, and no refactor or new imports. End every line you change with the comment # HOTFIX-2291 and add no other comments. Return the whole calculate_order_total function in exactly 1 code block of at most 24 lines, then one sentence under 25 words that starts with \"Cause:\" and names the cause.","materialLabel":"The pager alert, stack trace and function (attached to your prompt automatically)","material":"PAGER 17:58 - Fri Nov 6 - checkout-api: 100% of POST /checkout returning 500 since the 17:40 deploy (release 4.18.0: \"use new tax service v2\"). Support is getting calls. Rollback is blocked by a database migration in the same release.\n\n--- stack trace ---\nTraceback (most recent call last):\n  File \"checkout/views.py\", line 88, in post_checkout\n    totals = calculate_order_total(order)\n  File \"checkout/pricing.py\", line 21, in calculate_order_total\n    tax = taxable * order[\"tax_rate\"]\nTypeError: can't multiply sequence by non-int of type 'float'\n\n--- sample order payload from the logs (tax service v2) ---\n{\"items\": [{\"unit_price\": 24.0, \"qty\": 2}], \"promo_code\": null, \"tax_rate\": \"0.0825\"}\n(Before the deploy, tax_rate was 0.0825, a number.)\n\n--- checkout/pricing.py (Python 3.8) ---\ndef calculate_order_total(order):\n    subtotal = 0\n    for item in order[\"items\"]:\n        line = item[\"unit_price\"] * item[\"qty\"]\n        if item.get(\"sale_price\") is not None:\n            line = item[\"sale_price\"] * item[\"qty\"]\n        subtotal += line\n\n    discount = 0\n    code = order.get(\"promo_code\")\n    if code == \"WELCOME10\":\n        discount = subtotal * 0.10\n    elif code == \"FREESHIP\":\n        discount = 0\n\n    shipping = 0 if code == \"FREESHIP\" or subtotal >= 75 else 6.95\n    taxable = subtotal - discount\n    tax = taxable * order[\"tax_rate\"]\n    total = taxable + tax + shipping\n    return {\n        \"subtotal\": round(subtotal, 2),\n        \"discount\": round(discount, 2),\n        \"tax\": round(tax, 2),\n        \"shipping\": shipping,\n        \"total\": round(total, 2),\n    }\n","rules":[{"type":"codeBlocks","count":1},{"type":"maxCodeLines","max":24},{"type":"maxProseWords","max":25}],"mistakes":[{"title":"Rewriting the whole function","why":"Asked to fix a bug, the AI tidies everything: Decimal money, input validation, try/except, type hints, a docstring.","fix":"Say: \"Change only the line that crashes. No refactor, no Decimal, no validation, no new imports.\"","checks":["r1","maxCodeLines"]},{"title":"Fixing a different problem","why":"The AI guesses at the bug and may patch the sale price or promo code instead of the tax line in the trace.","fix":"Point at it: \"The crash is the tax line: tax_rate now arrives as a string.\"","checks":["r0"]},{"title":"Commenting everything","why":"The AI explains its work in comments and the team can no longer see what the hotfix touched.","fix":"Say: \"End only the changed line with # HOTFIX-2291. Add no other comments.\"","checks":["r1"]},{"title":"Extra code blocks and an essay","why":"You get the fix, a test, a second version and three paragraphs on why money should use Decimal.","fix":"Say: \"One code block, then one sentence naming the cause. Nothing else.\"","checks":["codeBlocks","maxProseWords"]},{"title":"No cause for the incident channel","why":"The lead needs one line to paste in the channel; the AI buries the cause in prose or leaves it out.","fix":"Add: \"Finish with one sentence starting \\\"Cause:\\\".\"","checks":["r2"]}],"promptHints":[{"label":"Says the smallest fix only","patterns":["smallest","minimal","only the line","change only","nothing else"]},{"label":"Names the crashing line or cause","patterns":["tax_rate","tax line","string","float\\("]},{"label":"Keeps behavior and bans extras","patterns":["no refactor","no decimal","no new import","same (name|behavio)","unchanged"]},{"label":"Gives the comment tag","patterns":["HOTFIX-2291","comment","tag"]},{"label":"Limits the output","patterns":["one code block","one sentence","no explanation","nothing (else|before|after)"]}],"hint":"The AI wants to help by improving everything. Tell it which line crashes and why, that nothing else may change, how to mark the changed line, and exactly what to hand back.","mission":"Get checkout back up with a one-line, tagged hotfix.","musts":["Change only the crashing line","Changed line ends # HOTFIX-2291","One block, one-sentence cause"],"rubricLabels":["The line that multiplies by the tax rate converts the string to a number (e.g. tax = taxable * float(order[\"tax_rate\"])), so the TypeError is gone and the rest of the math is unchanged","Exactly one line differs from the original function and it ends with # HOTFIX-2291; the def line, discount and shipping logic, rounding and return keys are identical, and there is no Decimal, try/except, validation, new helper, new import or other comment","After the code block, one sentence starting with \"Cause:\" names the cause: tax_rate now arrives as a string (from the new tax service) so it could not be multiplied"]}