- π Portfolio Website - (https://mysteriousvoid.github.io).
- π οΈ Building DisFile β a personal ops app (tasks, mail, habits, finance, job hunt, agents).
DisFile is my go-to app for day-to-day work and life ops β tasks, email, habits, money, networking, and job search β in one place.
Most of that used to live in five tabs and a pile of docs. DisFile pulls it together: a focus list for today, Gmail that can create follow-ups, habits and bank accounts next to outreach and resumes, plus browser agents when something on the web has to be checked or collected. Job hunt is a big piece of it (profiles, tailor, job boards), not the only piece. Live web app, small iOS client, real backend. I designed, built, and run it.
Everyday
- Tasks β inbox plus a Top 3 / Next 5 focus list. Other parts of the app (mail agents, Scout) can drop work into the same inbox.
- Mail β Gmail in the product. Argus runs a short tool pipeline (classify, link contacts, summarize, create tasks) from a preset β not one mega-prompt.
- Habits β check-ins, streaks, a simple weekly tracker.
- Finance β linked accounts and transactions (Plaid) so money sits next to everything else, not in another silo.
People & web
- Networking β companies, contacts, and a βtodayβ outreach queue.
- Scout β research companies, enrich them, pull open roles from careers pages.
- Watch Tower β scheduled checks on real sites that need a logged-in browser (the messy scraping / monitoring layer).
Job hunt
- Career profiles β separate tracks (e.g. Founding Engineer vs Data Science), each with its own Word resume, optional cover letter, and writing defaults.
- Tailor to a JD β paste a posting; selective paragraph edits; accept/reject; export a real
.docx. No invented bullets, employers, or metrics. - Quick copy β LinkedIn, GitHub, portfolio, email ready for application forms.
- Job Agents β browse LinkedIn / YC, collect listings, score each job against the best-matching profileβs resume.
Three deployable pieces:
| Piece | Platform | Job |
|---|---|---|
| Co-life | Next.js on Vercel | Web UI, auth (Clerk), BFF (/api/trpc). Owns tasks, habits, finance (Plaid). |
| Kratos | Fastify + tRPC on Railway | Mail, resumes, networking, LLMs, agents, background workers. |
| Browser runtimes | Headed Chrome (Browser Use / CDP) | Job boards, careers pages, scheduled site watches. Called only from Kratos. |
| Co-life-mobile | Expo (iOS) | Tasks / habits via the BFF only β never holds the Kratos secret. |
Web (Clerk cookie) ββ
iOS (Clerk JWT) βββββΌβββΆ Co-life BFF ββ service token + userId βββΆ Kratos
β β β
β Postgres: tasks, habits, finance Postgres: kratos_* / argus_*
β (+ signed DOCX storage via Kratos) β
βββββββββ internal hooks (tasks, API keys) ββββββββ
β
headed Chrome runtimes
Design
- Trust β service token authenticates Co-life as the caller; your Clerk user id in the payload scopes every backend row. The browser never picks the user or holds the token.
- Data β one Postgres, two owners. Co-life migrations cannot drop
kratos_*tables. Domain DOCX files are stored with server-minted paths, not client-chosen keys. - Contract β Zod schemas + hand-written tRPC types are mirrored from Kratos into Co-life (Vercel only clones the frontend repo). When the API shape changes, Kratos deploys first.
- Async work β mail sync, job scrapes, and watches run as queued workers with concurrency limits and leases, not as one long request from the UI.
- Stack in practice β TypeScript end to end on the app servers; Drizzle for SQL; structured LLM calls (Vercel AI SDKβstyle
generateObject+ Zod); Gmail API for mail; Plaid for accounts; Python FastAPI sidecars where Chrome has to stay headed and durable.
Models are not sprinkled through the UI. Everything goes through one runner on Kratos: a named purpose (resume tailor, mail intel, job score, β¦), an optional per-purpose model preference, structured JSON validated with Zod, a daily spend cap, and a row in a call ledger whether the call succeeded or failed. Keys stay on the server.
Resumes and cover letters are treated as documents you own, not chat transcripts. The source .docx is immutable. The model proposes paragraph-level edits (rewrite / delete / insert) against stable ids. You accept or reject in the UI. Export applies accepted text in place so Word formatting survives. System prompts enforce selective edits, per-paragraph factual boundaries, and no JD keyword stuffing; unknown ids are dropped, not guessed.
Job Agents drive a real browser per board (LinkedIn, YC) with an isolated cookie profile. Listings are upserted by fingerprint, then scored in two steps: pick which career profile fits the posting, then score that profileβs active resume. Output is apply / skip / unsure. Mock mode and human login warmup exist because live sites break often.
Argus (mail) is a tool pipeline, not βsummarize my inbox.β After Gmail sync, a preset (job search, networking, triage, β¦) orders deterministic tools and LLM tools. LLM tools are batched into one structured call per email; side effects (labels, CRM links, tasks in Co-life) only run when the tool output allows them.
Scout and Watch Tower use the same browser layer for research, careers scraping, and scheduled page checks β durable sessions, mock-before-live, and human login when Cloudflare or MFA shows up.
Longer write-up
Full product + architecture notes:
docs/disfile.md in the Co-life repo.
Last Edited on: 08/18/2026





