Removing a cooldown lock that was never true to the source
Greenhouse (my creative-project manager) shipped v1 with a rule I lifted straight from the design doc: after you touch an active project, it locks for 7 days. The idea was borrowed from Mike Monday’s creative-process material, where incubation matters. Ideas need to rest before you judge them. That part’s true and stays true.
The problem is I applied the same rest period to active projects too, and that part was never true to how the source material actually works, or how I actually work.
The gap
A spike went back to check the claim against two things: my own two years of practice, and Mike Monday’s actual writing. Neither matched what I’d built. In practice, 5 or 6 active projects get touched in a single day, and the same project gets touched again the next day. Monday’s own posts describe daily return to the same project as the whole point, a race against boredom, not a mandated week off.
So the 7-day active-project lock wasn’t incubation. It was idea-incubation logic pasted onto the wrong pipeline stage.
The fix
The follow-up issue pulled the lock out entirely. Rotation ordering (least-recently-touched rises to the top of the worklist) already existed and already did the useful part of the job, without ever needing a hard lock behind it - the same conclusion the cooldown-vs-rotation detour pointed at when the question first came up. Idea-maturity (7 days before you can judge a fresh idea) and vault-maturity (14 days before a shelved item comes up for Rescue-or-Keep) are untouched. Those are real incubation gates on real decisions, not busywork sitting on top of rotation.
On the Rust side this was mostly deletion: the is_cooling / cooldown_until / cooldown_remaining_secs fields on the derived item state, the worklist/cooling split in the daily-state assembler, the cooldown_days and cooldown_on_promote config knobs. last_touched stays exactly as it was, since it’s still what drives rotation order and touch history. Nothing about the DB schema changed. The whole thing turned out to be a read-time interpretation layered on data that was already correct.
The one design call I hadn’t pre-decided: cooldown_on_promote was live behavior (a toggle for whether promoting an idea also sinks it in rotation), not dead code, so removing it was an actual decision rather than cleanup. Went with full removal. Promoting an idea never records a touch, so a freshly promoted project lands at the top of the worklist as the most-neglected item, which matches how promotion is framed everywhere else in the app: a decision to work, not work itself.
Lesson
The bug wasn’t in the code, it was in translating a well-sourced idea (incubation matters) into the wrong scope (every pipeline stage) instead of the right one (idea judgment specifically). Cheap to write, expensive to notice, because the tests I’d written were internally consistent. They just encoded the wrong rule correctly. Checking a design assumption against a real workload turned up in a day what code review alone wouldn’t have.
Related reading
Two notes nobody ever saw
Greenhouse saved a capture note and a handoff note faithfully, and showed neither: one had no field in the wire type, the other had a working command nobody called.
The scan that offered to import itself
An import scanner that found the app's own scaffolding, then re-offered a folder it had just imported - two versions of the same missing conversation between layers.
Adding a native macOS menu to Greenhouse broke Cmd+Q, and my test harness couldn't press Cmd+N either
set_menu replaces the default menu, it doesn't extend it - taking Quit, Hide, and every Edit shortcut with it. Then the WebDriver actions endpoint turned out unable to press a key.