jason_
Jason Poindexter / PortfolioDesign leadership + production AIStart a conversation
JASONPOINDEXTER
Menu
Case study / Keelhouse / Solo, product and architecture

I kept turning "evaluate this" into "adopt this".

Keelhouse is a native macOS workbench for running coding agents without a full IDE. I tried three existing tools in one day and rejected all three. During those trials, I caught myself repeatedly treating an evaluation as a commitment to adopt.

Role
Solo: product, design, architecture
Platform
Native macOS
Decisions logged
38
Trials run
3, all rejected
01 / Stage setting

I kept turning "evaluate this" into "adopt this".

Keelhouse is a native macOS workbench for running coding agents without a full IDE. I tried three existing tools in one day and rejected all three. During those trials, I caught myself repeatedly treating an evaluation as a commitment to adopt.

02 / Problem

VS Code as a very expensive project shell.

Developers using Codex, Claude, Gemini, or OpenCode often keep a full IDE open mainly to have a file tree and a terminal. Keelhouse puts the structured agent conversation at the centre of the screen and brings projects, files, editing, Git, browser preview, and real terminal sessions into resizable trays around it.

03 / My role

Solo: product, design, architecture

Solo: product, design, architecture

04 / Direction

Build our own, and lock the stack

Every candidate had failed for a reason I could name. With three trials rejected on stated grounds, building became the cheapest remaining option rather than the ambitious one. The full stack was locked in the same session, and a render-and-input-loop spike passed before any product work started, so the foundation was proven rather than assumed.

05 / Impact

A flow report against the thing that got built.

The workbench was then audited on its own terms, tracing the paths a developer actually takes: open a project, run an agent, inspect and edit, verify, and resume later without switching to an IDE.

The problem

VS Code as a very expensive project shell.

Developers using Codex, Claude, Gemini, or OpenCode often keep a full IDE open mainly to have a file tree and a terminal. Keelhouse puts the structured agent conversation at the centre of the screen and brings projects, files, editing, Git, browser preview, and real terminal sessions into resizable trays around it.

  • 01The agent conversation is the primary surface, not a sidebar.
  • 02Everything else is a tray that appears when needed and gets out of the way.
  • 03A workbench that reimplements an IDE has missed the point of not being one.
The method

Trials run one at a time, not in parallel.

Rather than designing from scratch, the plan was to trial existing tools in sequence and only build once every candidate had failed for a nameable reason. Running them sequentially rather than in parallel was itself a logged decision: parallel trials produce impressions, sequential trials produce verdicts.

01

Trial one, and the rejection that named the criterion

A static configuration model cannot carry a dynamic workbench. The first candidate was a terminal multiplexer paired with a fast terminal emulator. It was rejected on its configuration model: the layout is defined statically, and a workbench whose trays appear and resize around a conversation needs to be rearranged at runtime. Rejecting it produced the actual requirement.

Trial run and rejected, 2026-07-07
LiveTrial one: the multiplexer cockpit demo, before it was rejected.
02

Trial two, a fork question that turned out to be moot

The correction was logged as fast as the mistake. The second candidate looked like it would need forking to be themeable, which triggered a blind-spot audit on whether forking was justified. The audit found the premise was wrong: the chrome was already configurable, so the fork question did not exist. The decision entry is a correction of the previous entry rather than a new choice.

Blind-spot audit, fork question retired
LiveThe fork-decision audit. Sixteen frameworks against one premise.
The correction

I was converting "evaluate X" into "adopt X" every time.

Three trials in, the pattern was visible in the plan itself: each evaluation had been quietly rewritten as an adoption before it finished. That is a process bug, not a product one, and it is logged in DECISIONS.md as its own entry so the plan could be corrected rather than the tools re-blamed. After that, building rather than adopting became the explicit decision.

03

Build our own, and lock the stack

Every candidate had failed for a reason I could name. With three trials rejected on stated grounds, building became the cheapest remaining option rather than the ambitious one. The full stack was locked in the same session, and a render-and-input-loop spike passed before any product work started, so the foundation was proven rather than assumed.

Spike passed: render and input loop provenScaffold merged into the passing spike
LiveThe Keelhouse chrome, built after the trials failed.
Checking the result

A flow report against the thing that got built.

The workbench was then audited on its own terms, tracing the paths a developer actually takes: open a project, run an agent, inspect and edit, verify, and resume later without switching to an IDE.

LiveKeelhouse user-flow report.
Limits

Where the evidence stops.

No users. The trials were run by me, judged by me, and the criteria emerged during the process rather than being set in advance, which is a weaker test than a fair comparison. The value here is the discipline of rejecting three options on record before building, not a claim that the fourth is correct.

Keelhouse

Three rejections, then one build.

The trials cost a day and saved a rewrite. Every rejection is written down with the reason, including the one where the thing being corrected was my own plan.

In development. No users yet.