Inline comments rot. They drift away from the code they describe, get half-updated in rebases, and end up actively lying to the next person who reads the file. The rationale you wanted to preserve — why this branch exists, what you tried before, which ticket this maps to — was never really about the code. It was about the decision.
Comments answer the wrong question
A good comment explains why. The problem: the “why” is usually a story, and stories don’t belong wedged between two lines of TypeScript. They belong somewhere a human will actually go looking when they’re confused.
That somewhere is almost never the file.
Quacks are persistent rationale
A quack is a short, timestamped narration of a decision, attached to the commit and the file range it touched. When a future engineer hovers the line, they see your reasoning — not as a stale comment, but as a thread they can reply to.
$ quack add src/billing/proration.ts:88-104
> We round half-up here because Stripe rounds half-even and
> we were getting 1-cent reconciliation diffs every Tuesday.
> See QS-441.What to delete tomorrow
// TODO:fix this later — replace with a real ticket and a quack.// HACK,// XXX,// NOTE:— all rationale, none of it durable.- Block comments that restate the function signature — your IDE already does that.
What to keep
Keep comments that explain what the code does when the code itself can’t — regex breakdowns, bitfield layouts, the load-bearing semicolon in an ASI footgun. Those earn their keep. Everything else is a quack waiting to happen.