Dew

Log a purchase by voice — "spent 250 on headphones at Best Buy" — and the plant reacts. A big splurge brings a hailstorm. A new subscription brings aphids that crawl the branches and stay until you cancel. An essential like rent or groceries brings nothing at all. The point is to make the long-term cost of a decision something you feel today instead of a number you ignore.


The problem

People make everyday financial decisions without clearly understanding how those decisions may affect them later.

This isn't an information gap. Everyone knows overspending hurts. It's a perception gap: the consequences live months or years away and feel like they belong to someone else. Nowhere is that more true than for a first-year university student who just became financially independent — small budget, no felt intuition for money yet, every spending habit of their adult life forming right now.

Dew doesn't show you a chart. It gives your future a heartbeat, and lets you watch what your decisions do to it.

How it works

You speak or type a purchase you've already made. The app parses it into structured fields — amount, category, merchant, whether it's essential, whether it's recurring — and asks you to confirm. Then the plant reacts.

Two things move with every purchase:

Vigor is the plant's short-term health. It measures the cash-flow shock: how much of your monthly discretionary room and your liquid buffer this purchase just consumed. A $250 hit against $200 of monthly slack is a hailstorm — lightning cracks, hail bounces off the soil, leaves tear away. A $15 impulse buy is a passing frost. Vigor damage is proportional and continuous: a $15 and a $60 purchase are both cold spells, but the $60 stings more. Damage lingers, then heals over time as the baseline recovers.

Maturity is the plant's long-term growth trajectory over the four years of the degree. It measures the market opportunity cost of the money: what the purchase amount plus the growth it would have earned is worth by graduation, priced against a real Monte Carlo simulation running on real Nasdaq data inside Snowflake. On actual QQQ history, a $250 purchase costs roughly 10 maturity points; a subscription costs roughly 11, because it's a multi-month commitment. Maturity moves slowly and ratchets — growth is permanent.

The plant never dies. Essentials — rent, groceries, transit, phone — produce no weather, ever. You are never punished for necessities. Subscriptions are aphids: they crawl the branches and quietly lower your recovery baseline until you cancel, at which point they leave and the baseline restores. The state accumulates across purchases — each new decision applies its deltas to the current plant, not a fresh one.

A roguelike narrator voices every consequence: "Your plant weathers an arduous storm of hail. Its leaves are torn, and time will be needed to recover." The severity is always decided by the simulation, never the language model. A pizza never gets lightning.

Architecture

Client — React 19, Vite, TypeScript. The plant is an L-system grown on an HTML canvas with zero art assets: growth stages are rewrite iterations driven by maturity; health is rendering parameters (leaf color, droop, density, blooms) driven by vigor. All weather is code: particle systems for hail with ground bounce, rain, frost, and falling leaves; tweened sky color and wind; branch sway via sine modulation on the turtle angle; segment-attached aphids that crawl the recorded branch geometry. Voice input uses the browser Web Speech API to transcribe speech into the input field live, then /parse structures it; the logic is isolated so UI changes can't break it and it degrades to typing where speech isn't supported. The client runs offline against bundled fixtures or online against the API.

Backend — FastAPI. Owns the plant math (engine.py), the state store (store.py, mirroring the Snowflake table schema), the voice parser (parse.py), the narrative layer (narrative.py), and a translation layer (client_view.py) that maps numeric model output into the renderer's effect flags. Endpoints: /parse (voice or text to structured fields), /purchase (apply a purchase, return render block and projection), /cancel (remove a subscription, aphids leave), /state (hydrate the full plant), /narrative/{id} (stream the roguelike line via SSE), /reset (demo reset), /health (keep-alive).

Snowflake — the engine that grounds the long-term half of the app in real data.

How Snowflake is used

Snowflake is the engine, not the database. The plant's maturity — how much a purchase sets back your growth — is priced by a Monte Carlo simulation that runs in Snowflake, on real historical market data, via Snowpark, with Claude available in-perimeter through Cortex for the narrative layer.

Marketplace — real market data, zero-copy

We mount the free Snowflake Public Data listing — the Cybersyn Financial & Economic Essentials data, sourced from Databento's Nasdaq feed — via zero-copy Secure Data Sharing. This gives a live, provider-maintained, read-only share of daily US stock prices and volumes with no data engineering on our side. We read the daily post-market close for QQQ as the broad market proxy from SNOWFLAKE_PUBLIC_DATA_FREE.PUBLIC_DATA_FREE.STOCK_PRICE_TIMESERIES.

This is not decoration. The app's numbers come from real Nasdaq prices shared into our account, not a hardcoded mean and variance.

Snowpark — block-bootstrap Monte Carlo, in-database

We wrote a Snowpark Python stored procedure (DEW.CORE.run_montecarlo) that runs the simulation where the data lives, so no market data ever leaves Snowflake.

The procedure reads month-end closing prices from the Marketplace view and computes monthly returns, then runs a block bootstrap: it samples contiguous 6-month blocks from the real return sequence to build 5,000 simulated paths of 48 months — the length of a degree. Contiguous blocks preserve real fat tails and sequential clustering — the crashes, recoveries, and volatility regimes that actually happened — which a parametric normal distribution would erase. This is the honest reason to sample real history instead of assuming a bell curve: without it, the simulation understates the downside and overstates precision.

Cortex — Claude in-perimeter for the narrative

The roguelike line the plant speaks after each decision is designed to be generated by Claude running inside Snowflake Cortex via AI_COMPLETE, so the LLM runs in the same governed perimeter as the data. The narrative module serves a hand-written fallback bank today with a 4-second timeout pattern, and Cortex drops in behind the same interface. Severity is always decided by the runway model, never by the LLM — the language is expressive, but the drama is earned by the math.

Snowflake-backed datastore

snowflake_store.py is a drop-in adapter that backs the entire API with Snowflake tables — persona, goals, transactions, decisions, plant state, commitments, and mc_percentiles — via snowflake-connector-python. It mirrors the JSON store's interface, so the app can run entirely on Snowflake by flipping the store with no other code changes.

Design principles

Post-purchase, by voice. The student logs what they already spent — fitting a busy schedule and a persona that needs the habit of noticing, not a pre-purchase gate. Voice-first because typing numbers is friction; speaking is natural.

Every reaction is proportional and earned. Severity is continuous, computed by the runway model from the actual purchase against the actual buffer. The LLM voices what the math decided. A coffee is a frost. A hailstorm is earned.

Essentials are invisible. Rent, groceries, transit, and phone never produce weather. First-time independence must not be punished for existing.

Subscriptions are pests, not storms. A one-time purchase passes. A recurring charge sits on the plant and quietly drains the recovery baseline until you cancel — the most accurate picture of the financial cost most people don't see.

The plant never dies. Damage lingers, then heals. Growth only ratchets up. This prevents the fear spiral that makes people delete finance apps.

No numbers in the narrative. No dollar amounts, no percentages, no probability-of-success figures. The plant's appearance is the health bar. Consequences are weather and growth stages.

The fiction is grounded. The future you're seeing is a living plant. The engine underneath is a real Monte Carlo on real Nasdaq data. The feelings are invented; the math isn't.

Built with

React · Vite · TypeScript · HTML5 Canvas · FastAPI · Python · Snowflake (Marketplace, Snowpark, Cortex, SQL) · numpy · Web Speech API

Built With

Share this project:

Updates

Submission history