
POND: Query Your Life From One Local File
Overview
Spotify knows what you played at 2am, your bank knows what you ordered afterwards, Google Fit knows you didn't train that week — and none of them talk to each other. The two obvious options are a spreadsheet that dies around row 40,000 or a SaaS that wants you to upload your bank statements and trust its privacy policy. POND is the third option: a CLI that lands every export in one DuckDB file and answers plain-English questions like "how much did I spend on Swiggy in weeks I skipped gym this year?" — a question that needs three sources joined on a calendar, where the interesting half is about rows that don't exist.
Tech Stack
Challenges
- Answering questions about absence — "weeks I skipped gym" is about rows that were never recorded.
- Trusting an LLM to write SQL against personal data without letting it read that data or run anything dangerous.
- Ingesting messy, inconsistent exports (Android vs iOS WhatsApp dates, every bank's own CSV format) idempotently.
- Keeping re-imports safe so overlapping exports don't double-count.
Solution
The LLM only ever sees the schema; generated SQL is parsed with sqlglot and validated on the AST — one statement, SELECT only, no DDL/DML/PRAGMA/ATTACH/COPY, no filesystem-reaching functions, with an automatic LIMIT 500. days and weeks calendar-spine views manufacture the rows gaps don't have, so "skipped gym" is a simple WHERE instead of a clever anti-join. Imports are idempotent twice over: a sha256 file ledger skips files already processed, and a per-row dedupe_key catches overlap between exports. An unknown bank format asks four questions once, saves a profile keyed on the header signature, and never asks again.
Outcome
Point pond import at a Spotify zip, a WhatsApp .txt, a Google Takeout, or a bank CSV; check pond status; then pond ask in English, or pond sql for raw local SQL with no LLM in the loop at all. Everything runs on your machine except one clearly-labelled hop. 56 tests run on synthetic fixtures — no real data anywhere — with lint and format enforced in CI.
What I'd do differently
The privacy claim only means something if it can't drift from the code, so pond schema prints the exact payload pond ask would send, from the same code path. Deciding what NOT to build mattered too: bank PDFs and Google location history are explicitly out of scope, and the site is marketing, not a UI — the tool is CLI-only on purpose.