The Broker Statement My Accountant Had Never Seen
How I adopted spec-driven vibe coding to build a tax engine in three and a half weeks
The statement my accountant had never seen
I still remember my accountant’s face the first time I handed him a brokerage statement — in English, every line item in dollars, from a US broker he’d never heard of. He flipped through it twice, looked up, and asked me for one more week to go through it.
That statement existed because of restricted stock units. I’d worked at Hewlett-Packard Enterprise, then moved to Google, and RSUs had been quietly vesting into a US brokerage account the whole time — grants nobody ever asked me to think about, because that’s the point of RSUs: you get equity, you wait, it shows up. I wasn’t interested in personal finance back then. I just let it sit.
That changed in 2023. I started reading — books, Italian finance writers (The Bull, Mr. RIP, Paolo Coletti, Pietro Michelangeli, if you want good sources), the whole rabbit hole — and one of the first things I did with that new knowledge was sell most of the RSUs and diversify into plain, boring, cap-weighted ETFs. Sensible. Except a US broker account isn’t an Italian Regime Amministrato account, where the bank withholds and reports gains for you automatically. Mine falls under Regime Dichiarativo: I calculate, I declare, I’m the one on the hook if I get it wrong. My accountant’s hesitation wasn’t a personal failing — foreign multi-currency brokers under Regime Dichiarativo are a genuine niche inside Italian tax prep, and niche means nobody’s built decent tooling for it. Which meant it was on me.
So I learned Quadro RT, RM, RW — the forms, and the specific arithmetic Italian law actually requires, most of which no general-purpose brokerage tool respects:
LIFO, not FIFO — the last lot bought is the first one sold, by law, regardless of what your broker’s own report defaults to.
The ECB reference rate on the exact trade date (±3 business days) — not a monthly average, not “today’s rate.”
Two tax buckets that can’t touch each other — ETF gains (Art. 44 TUIR) and stock gains/losses (Art. 67 TUIR) are calculated and reported separately; a stock loss can’t offset an ETF gain.
By 2025 I could fill in RT/RM/RW by hand, from a spreadsheet, in an afternoon. It wasn’t a good use of an afternoon — and it’s also roughly when I started paying real attention to vibe coding.
Personal finance was the excuse, not the point
I founded a startup in 2012. I’ve been a builder for a long time, with a stubbornly pragmatic streak — when something new shows up, I want my hands on it, not just an opinion about it. When the whole vibe-coding trend broke out, I wanted in, past the headlines, actually building something.
Here’s the part I didn’t expect going in: personal finance wasn’t the reason I started this project. It was the vehicle. Getting genuinely good at vibe coding was the actual goal, and I needed a subject I already loved enough to stay obsessed with for months, not weeks — because that’s roughly how long a real side project takes before it’s real. It could have been almost anything. I picked the thing I’d already spent two years reading books and following Italian finance writers about, because obsession is the only fuel that survives week six.
That project has a name: minus-tracker — a CLI that turns a DEGIRO export into LIFO-matched, ECB-converted, correctly-bucketed capital gains, ready for Quadro RT/RM. Source is on GitHub; the package itself is on npm.
This is what this series is about: reporting the evolution of my journey into spec-driven vibe coding and context engineering. The adopted workflow, the skills, the subagents, the environment setup, everything that can be useful if you want to go down a similar path, with one important call out before starting: studying is important, but in the end you need to start building from day 0.
It takes a (fool-proof) workflow to remain sane
I don’t have one clean story about the moment doubt kicked in — if I’m honest, there wasn’t a single night or a single bug I can point to. What there was, instead, was a slow accumulation: weeks of prompting without a plan, watching Claude Code produce code that ran fine in isolation and fought everything around it — a new file for every new idea instead of extending what already existed, logic quietly duplicated in two or three places because nothing forced it to reuse what it had already built. No single moment stung. It was death by a thousand small rewrites, and it took me longer than I’d like to admit to notice the pattern instead of just patching around it each time.
I went looking for a better process, and what actually clicked for me was Nathan Onn’s writing (nathanonn.com) on structured, spec-driven ways of working with coding agents — worth a read if you’re hitting the same wall. What I built from that, over the following weeks, was a six-stage pipeline that treats writing software the way I’d treat filling out a tax form: get the requirements exactly right before you touch a single number.
idea.md & PRD.md — Requirements pinned down to the letter, before a single line of code.
test_plan.md & impl_plan.md — The map, drawn before the code.
execute — One focused sub-agent per task, grouped into dependency waves (~18% context used per task).
verify — One sub-agent at a time, up to 3 automatic fix cycles per failing test.
The execution step changed things the most. Every task runs in its own sub-agent, with a clean context — it never has to “remember” the whole project, just its one task and the interfaces it has to respect. Per my own setup notes, that’s roughly a third of what a single agent burns trying to hold the entire project in its head (~56%). Narrower context, fewer contradictions between pieces, and when something breaks I know exactly which task touched it.
The bar wasn’t “it runs” — it was “it’s legally correct”
Getting the code to execute was never the hard requirement. Getting it right under Italian law was. Every calculation rule — LIFO matching, the four-year loss-carryforward window, the split between the two tax buckets — is validated against the Agenzia delle Entrate’s own FAQ scenarios, not against expectations I wrote myself based on how I assumed the law worked. Twelve of those scenarios map one-to-one to official FAQ examples, accounting for 61 of the suite’s 506 test cases. One of them, worked in full:
Units Price/unit Date Fees
BUY 10 €100.00 2024-01-02 €2.00
SELL 10 €150.00 2024-06-03 €2.00Result: a taxable gain of €496.00, fees allocated per lot, down to the cent — not an approximation.
That kind of precision didn’t show up in one sitting. It came together in stages, each version doing one thing. Grounding the software behavior to legal documentation and dedicating a significant amount of time to create a simulation environment to test it out alongside the software itself is, to me, mandatory to ensure vibe-coding is not producing crappy software.
Three and a half weeks, four versions
Version Shipped What it added
v0.5.0 Jun 16, 2026 Core: DEGIRO parser, LIFO/FIFO calculator, multi-currency via ECB rates, CLI
v0.6.0 Jun 29, 2026 Two-bucket tax classification, OpenFIGI lookup, 4-year carryforward
v0.7.0 Jul 3, 2026 Modello Redditi PF export (Quadro RT/RM)
v0.8.0 Jul 5, 2026 Stateless classification mode + minus-tracker-mcp server, for AI agentsThree and a half weeks, June 13 to July 5, from an empty repository to a package on npm with 506 passing tests. It’s public today, MIT-licensed, zero runtime dependencies in the core library.
It wasn’t flawless. A few hours after v0.8.0 shipped, I turned the same adversarial instinct I’d used to build the thing loose on the finished product — and it found seven real bugs, one of them with actual tax consequences if you’d hit it on the wrong trade. Full repro, root cause, and the same-day fix are Episode 8. For now: it happened, it got fixed before the day was over, and I’ll walk through exactly how later in the series.
What I’d actually like from you
I don’t think minus-tracker’s ceiling is “a CLI that fills in Quadro RT.” It’s the first capstone in what I’d like to grow into a broader personal finance toolkit — no promises on scope or timeline on that front. What exists right now is real, free, and on npm, and I’d genuinely like people to run it against their own portfolio and tell me what breaks:
npx @gabrielerandelli/minus-tracker
Your trades and results never leave your machine — the one optional network call sends ISIN codes, not amounts or account details, to classify instrument types, and even that’s skippable with --offline.
It’s a calculation aid, not tax advice — mine or the tool’s — so treat anything with real money behind it accordingly. But if you have a DEGIRO export, a multi-currency mess, or an RSU sale you never quite trusted your own math on, try it and reply with what you find.
Next tax season, I’ll walk into it with Quadro RT, RM, and RW already filled in — done myself, start to finish, with the tool I built for exactly that. That’s not a knock on what my accountant does; a niche, multi-currency Regime Dichiarativo filing like mine was never going to be where a general practice adds the most value, and that’s fine. It’s just that AI made it possible for me to close that gap myself, on my own numbers, instead of handing off a statement I couldn’t fully explain myself. That’s the part of “vibe coding” nobody puts in the tweet.
What’s Next
This is a 9-part series. Next up: the environment itself — the actual Claude Code setup, the skills, and the CLAUDE.md files behind everything above. Creating an efficient environment is where I spent most of my time and, in my opinion, the best favor I can do for you is to address this part before the workflow description. Subscribe if you want the rest of it.
Resources
In my constant interleaving between studying and executing, as you may imagine, not everything was built from scratch. It’s worth crediting those who have influenced me in this journey and to leave here some resources that, trust me, can accelerate your learning:
Workflow and Context Engineering: Nathan Onn
Agent Skills: Addy Osmani
Loop Engineering: Shubham Saboo
Knowledge Base: Andrej Karpathy
SDLC: Giovanni Galloro
Agents CLI: Elia Secchi & Pier Paolo Ippolito



