Why I Built a Decision Log Before I Built the Dashboard
The first feature of AlphaNode is not a chart. It's a forcing function that makes me write down what would prove me wrong.
When I started AlphaNode, the obvious first build was a beautiful dashboard — moving lines, sector heatmaps, watchlist sparklines. Dashboards photograph well. They get clicks on X.
I shipped a Decision Log instead.
The pain that actually loses me money
Looking back at three years of trades, the ones that hurt the most were never bad ideas. They were ideas I never bothered to write down.
I would say to myself, "I'm buying NVDA because the silicon photonics cycle is inflecting." Six months later, NVDA is down 18%, the silicon photonics narrative is still alive, and I'm holding because I'm anchored. But what was the invalidation condition I would have written down? I never wrote one.
If you can't write down what would prove your thesis wrong, you don't have a thesis. You have a feeling.
What the form forces
Every entry in AlphaNode's Decision Log requires five fields:
- Ticker
- Action (Buy / Sell / Short / Cover / Hold)
- Sector
- Core thesis — the one-paragraph why
- Invalidation condition — the specific evidence that would kill this trade
The fifth field is the only one that matters. The Data Table even highlights it in a warning color so I can't pretend I didn't see it.
The technical implementation is boring
// Server Action — runs on Vercel, writes to Supabase
"use server";
export async function createDecision(input: DecisionInput) {
const validated = decisionSchema.parse(input);
await supabase.from("decision_logs").insert(validated);
revalidatePath("/decision-log");
}
react-hook-form + zod on the client. A Server Action submits it to Supabase. revalidatePath re-renders the table. Total code: under 200 lines.
The behavior change in me, though — that's the whole point.
What's next
- Phase 2: a
closed_atcolumn with a free-text post-mortem field. Did the invalidation condition trigger? If yes, did I sell, or did I rationalize? - Phase 3: weekly emails with "decisions older than 90 days you haven't reviewed."
If you have your own version of this, I'd love to hear how you structured it.