Designing an AI wealth manager that tries to make you check it less

A design study, not a shipped product. Aria is a personal AI wealth manager I specified, architected and partially built. The foundation exists and the product layer does not, and the interesting part is which half got built and why.

What it is A goal-based wealth manager for ordinary savers, with an AI advisor whose main job is talking people out of selling
Status Foundation built, product layer not implemented. Private repository
Built Data model, migrations, repositories, a contract-first market-data adapter, task infrastructure. 69 tests passing
Not built Every API route is a stub. There is no advisor. No user has ever used it
Why it's here The product thinking is the output worth showing — and auditing it a year later turned up a lesson I now apply everywhere

I am putting this up because the specification is the part I would want to be judged on, and because a portfolio that only shows finished things quietly misrepresents how work actually goes.


The thesis

Most consumer investing products are built to be opened. Engagement is the metric, so the product optimises for it: notifications, streaks, daily balances, a feed.

For a long-term wealth product that incentive is inverted. The evidence is unambiguous that the largest destroyer of retail returns is not fees or bad allocation but behaviour — selling in drawdowns, chasing last year's winner, trading too often. A product that successfully increases how often you look at your portfolio is a product that makes your outcomes worse.

So Aria's design premise was stated in one line and everything else derived from it:

The most sophisticated thing Aria can do is help someone do nothing when markets are crashing, because that is what builds wealth.

This is the whole product. The allocation logic is a solved problem, and deliberately boring — a low-cost, three-fund, risk-matched portfolio beats most of what is sold to retail investors. The hard part is the twenty minutes on a red morning when someone wants to sell, and that is where the AI belongs.

Designing against engagement

The consequence is a success-metrics table that reads backwards, and it is the artifact I would point an interviewer at first:

Measured Explicitly not measured
Users staying invested during downturns Daily active users — checking often is the failure mode
Goal achievement rate Trades executed — fewer is better
Time to goal completion Short-term returns — noise, not signal
Behavioural mistakes prevented Session length

Writing down what you refuse to optimise is harder than writing down goals, and more useful. It resolves arguments before they happen: any proposal that would raise daily actives at the cost of trading frequency is already decided.

The same discipline produced a "what this does not do" table alongside the feature list — no day trading, no options, no market timing, no performance chasing — each with the reason. A feature list without its negative is a wish; with it, it's a scope.

The course correction

Aria did not start clean. It began by inheriting architecture from an earlier trading system of mine, and the inheritance brought the wrong assumptions: short holding periods, signal generation, an active-management cadence, a decision loop shaped around "what should I trade today?"

That is a plausible way to build the wrong product quickly, and it is worth being precise about why. The trading architecture was not badly built. It was correctly built for a different user with a different time horizon, and almost every structural choice that was right there was wrong here. Reusing it would have produced a wealth manager with a day trader's nervous system.

So I wrote a course-correction document that did nothing except restate the identity: what Aria is, what it is not, and what changes as a result. Time horizon years to decades rather than hours. Monthly rebalancing rather than continuous signals. The user relationship as advisor and coach rather than terminal. The recurring decision as "should I adjust anything this month?" rather than "what do I trade today?"

The document changed no code. It changed every subsequent decision, which is cheaper.

What the architecture committed to, and what it actually did

Here the study turned into an audit, and the audit is the most useful thing in it.

Aria has a decision log: six architectural decisions, each with a rationale and a stated impact, written at the time. Reading it a year later, three of them describe a system I would be pleased to have built.

None of the three exists in the code. There is no row-level security in any migration and no current_user_id anywhere. There is no configuration validator and no validation logic in the settings module. There is no logging configuration module at all. The project-state document lists all three under "what is working now."

I did not know this until I went looking. The decision log recorded the decisions as made and applied, and nothing ever checked.

This is the same failure my other systems are explicitly built to prevent, arriving from the opposite direction. There, the recurring bug was a producer being retired while its consumer was left behind. Here it is a decision recorded as done that was never done — a document drifting away from the code it describes, silently, because a decision log is written once and read rarely, and nothing tests it.

The honest conclusion is not that the decisions were wrong. Row-level security is still the right call for multi-tenant financial data, for exactly the reason the log gives. The conclusion is that a decision log is not evidence, and I had been treating it as evidence. The fix is the same one I use elsewhere: every claim either carries a test that fails when it stops being true, or it is labelled as intent rather than state.

What the architecture actually did do

One commitment was built, and built properly: a contract-first boundary to the market-data provider. Nine modules — client, cache, rate limiter, schemas, typed errors, configuration, dependency wiring — written against the provider's published contract.

That one is verifiable, and the proof showed up while I was writing this: no API route in the application touches market data. Zero references across all eleven route modules. The dependency on a private upstream platform is real, but it is contained behind one adapter, which means the product layer could be built — and the provider swapped for something public — without the two ever meeting.

That is the difference between a decision that was implemented and a decision that was recorded.

What was built, and what was not

Honest, because the point of the study collapses otherwise.

Layer State
Data model, migrations Built
Repositories and schemas Built
Market-data adapter, caching, rate limiting Built
Background task infrastructure, scheduling Built
Configuration module Built (without the validation its own log claims)
Row-level security, config validation, structured logging Documented as done. Never implemented
Test suite over the above 69 passing
Goals, portfolios, recommendations, reports Stubs
The AI advisor Not started
Any user interface Not started

The internal state document tracked this accurately throughout — it says "Phase 1, data layer" and never claimed otherwise. The repository README was more optimistic than the project was, which is its own small lesson about where overclaiming creeps in: not in the tracking documents that nobody reads, but in the introduction that everybody does.

What I take from it

The foundation is the expensive half and I finished it. Models, migrations, isolation, adapters and task infrastructure are where projects like this usually die. That work is done and it is good.

The product layer is where the judgment lives, and I stopped before spending it. The advisor — what it may say, what it must refuse to say, how it behaves when someone wants to sell at the bottom, how it avoids becoming a chatbot that congratulates you for checking — is the entire differentiator and none of it exists. Given the choice again I would build one thin end-to-end slice through the advisor before completing the data layer, precisely because the advisor is the risky part and the data layer is not.

Writing the negative space was the highest-return hour spent. "What this does not do" and "what we refuse to measure" did more to shape the design than any architecture diagram, and they were the cheapest documents to produce.

And a decision log needs a test, or it becomes fiction. Three of six decisions here describe code that does not exist, and the document that tracks project state repeated the error. I found it only because I went looking a year later. Everything I have built since carries the rule that came out of this: a claim is either enforced by something that fails when it stops being true, or it is marked as intent. That rule has an origin, and this is it.

The behavioural thesis is the piece I would build a company on. The code is a foundation waiting for it.