The vault-review card that never rotated
Greenhouse has a daily “Rescue or Keep” card for the oldest thing sitting in the vault. Rescue makes sense - it pulls the item back out. Keep is supposed to be the other valid answer: leave it alone, I’ve looked at it, ask me again later. Except “later” never came. I found the bug while working an adjacent issue, and it’s a good example of a comment lying to me for weeks before anyone caught it.
The pick logic is deterministic on purpose: order all vaulted items by how long they’ve been dormant, and the daily review surfaces the longest-dormant one. That’s a reasonable design. The problem was what “Keep” actually did with that pick. There was a comment right next to it explaining that clicking Keep dismisses the card and the pick “naturally changes (tomorrow).” I read that comment, believed it, and moved on to the next issue. It’s wrong. Keep didn’t write anything to the database. It set a piece of state in the Svelte component and called it done. The card would vanish for the rest of that session because a client-side id got flagged as dismissed, but the underlying query never changed. Reload the app, or come back the next day, and the exact same item wins the “longest dormant” contest again. Forever. Every other vaulted item just… never got reviewed.
The fix ended up being a single nullable column. I added last_reviewed_at to the items table, separate from vaulted_at. That separation mattered more than I expected while writing it: vaulted_at is what the dormancy ordering is built on, so if Keep had touched that column instead, it would’ve reset the item’s dormancy clock and started corrupting the exact ordering the review depends on - the same trap the original Keep design dodged by not calling the vault command again. Two different questions, two different columns: “how long has this been in the vault” and “when did I last look at it and decide to leave it.”
With the new column in place, the daily pick got one more filter: skip anything reviewed inside the configured cadence, then take the oldest of what’s left. Keep now makes a real backend call, and the client-side dismiss flag I’d been trusting just goes away entirely, comment and all.
The part I keep coming back to is that this bug was invisible in every obvious sense. No crash, no error, no failing test. The card behaved exactly like the comment said it would, within a single session. You’d only notice something was off if you kept using the app across multiple days and started wondering why the vault review kept showing you the same dormant song idea from three weeks ago. Which is exactly how it got reported in the first place.
Lesson I’m taking from this one: a comment that explains why the current behavior is fine is a claim, not a fact, and it needs the same skepticism as the code itself. “Naturally changes tomorrow” sounds like a statement about the system. It was actually a statement about someone’s intent for the system that never got built.
Related reading
Navigation redesign: topbar tabs and a Settings dialog
Eight footer controls at identical visual weight, an i18n key doing double duty, and the ARIA pattern the project's own a11y test refused to let me half-build.
Six small UX fixes in one sitting
Ultra-wide layout caps, locale-aware timestamps, emoji to SVG, dismissible errors, a first-run hero, and the word that showed up three times on one card.
Toast + undo for Greenhouse's vault action
The app's first transient-feedback surface, the aria-live rule that makes a conditionally-rendered toast silently unannounced, and a prop that goes stale the moment you rename.