Engineering / How I Build

Two Real Bug Fixes, In Full

Not a methodology diagram — the actual work, from a live repo.

The short version is on the homepage: observe the problem, write it down, build with AI assistance, test it against the real rules, ship, explain. What that loop actually looks like day to day is less "one prompt, done" and more "open the tool, decide exactly what's wrong with the logic or the output, describe that one thing precisely, check the result against the real rule, repeat until it's right." Below are two real examples of that loop from portbill, the wharfrent calculator C&F agents use daily at Mongla Port. The source repository is private, so each fix is written up here in full.

Example 1 — A One-Poysha VAT Mismatch
What Was Wrong

PortBill's printed VAT line was occasionally one poysha (Tk 0.01) off from the official bill the Port Authority's own billing system produced for the same charges — a small gap, but on a document C&F agents check against a real government bill, "small" and "wrong" are the same thing.

How I Found It

Every monetary value in the app, including VAT at the time, used the same round-half-down rule — the port's documented convention for everything else. Comparing enough real bills against the MPA-printed totals, the mismatch only ever showed up at an exact half-poysha midpoint with an odd result. That pattern — not a random scatter — meant two rounding rules disagreeing, not a math error.

The Fix

MPA's own billing engine is a C# system, and .NET's Math.Round defaults to banker's rounding (round-half-to-even) — not round-half-down. I wrote calcVATmpa() as its own dedicated function, separate from every other monetary calculation in the app, using integer poysha-scale math and half-to-even rounding — so VAT alone matches the government system's convention, while every other charge keeps the port's existing round-half-down rule untouched.

How I Verified It

A dedicated test suite checks calcVATmpa() against the documented half-poysha midpoint cases, and a second test scans every other monetary-rounding site in the codebase and fails the build if any copy drifts from the shared formula — so this exact class of bug can't quietly come back later without a test catching it first.

Example 2 — A Fail-Open Authorization Bug
What Was Wrong

The Cloudflare Worker behind PortBill gates admin-only writes — config changes, deleting a saved bill, the rotation registry — behind a Bearer token checked against a hashed secret. Until that secret was actually set on the Worker, the authorization check returned true — "authorized" — instead of false. That meant every admin-only write, including the one that stores the admin password hash itself, was open to anyone with the Worker's URL for as long as the secret hadn't been configured.

How I Found It

Found while adding a genuinely new open-by-design route (bill-saving isn't admin-gated on purpose — any user can save a bill) and reading what the shared authorization function actually returned in every branch, not just the branch I was adding to.

The Fix

Flipped it to fail closed: no secret configured now means every admin write is refused, not allowed. Since one route (saved-bills) is meant to stay open by design, I added an explicit allowlist naming only that one filename — kept short and deliberate so adding to it later can't be done by accident — plus an Origin allowlist and a body-size cap as additional hardening on the now more clearly-defined open route.

How I Verified It

Re-read every call site of the authorization check after the change to confirm nothing outside the allowlist could reach a write path with the secret unset, then deployed and re-tested both the admin panel and the saved-bills flow against the live Worker before calling it done.

Neither fix started with a big prompt. Both started with noticing something specific was wrong, narrowing it to a cause, and describing that one thing precisely enough that the fix could be checked against a real rule — a government billing convention, an authorization path — not just against "does it look right." That narrowing and checking is the actual skill; the tool writes the resulting code faster than I'd type it by hand.

Next: where AI actually fits in this loop →