Andrew Borowicz

Andrew Borowicz

Finance student at Trinity University who builds software

Outside class, I'm training for a half-IRONMAN and bouldering

Activity

Past year on GitHub

2,879 contributions129 active days134 on the busiest day17-day longest streak

Most of this is in private repositories for Lone Pine and Minsky

GitHub contributions · snapshot Nov 10, 2026

Selected work

Minsky

May 2026 – Present

A Mac app that fills out job applications and stops before Submit

Tasks: a flow chart of 96 applications split into needs you, in progress, not started and finished, above the task queue

Every application from queue to submitted, and the ones that need youReal app · sample data · scroll sideways

25releases
16,000+roles found per daily scan
11application platforms

Snapshot Oct 31, 2026

Read the Minsky case study

Overview

A Mac app that finds openings on company career sites, ranks them against the user’s profile and fills in the application. It does not submit. The user reviews and submits each form.

What I built Electron · React · TypeScript · SQLite · Playwright

  • Job ingestion from 2,971 job boards on the major hiring platforms, with automatic discovery of new boards.
  • Local SQLite storage for jobs, the user’s profile and saved answers.
  • A match score across skills, level, sector, location, sponsorship and freshness, adjusted by what the user applies to and skips.
  • Eleven platform adapters that fill forms in a real browser. Answers come from the profile. AI drafts only open-ended text.
  • A guard that blocks every Submit click and Enter press. Fields the app can’t answer are left blank and asked once.

Results

Roles per sweep
3,250 → 16,310 (Sep 17)
Boards reached
99% of 2,971
Workday forms reaching Review
1 → 13 of 20
Application platforms
11
Releases shipped
25
Tests
4,587
Commits
442

Problems solved

Job boards skipped without an error
Problem
About 1,300 boards per run were never requested, and no error was logged.
Cause
The circuit breaker counted failures per host. All Greenhouse boards share one host, as do Lever and Ashby, so a few slow employers disabled a whole platform.
Fix
Raised the threshold, added a retry probe and added a coverage meter.
Result
Roles per sweep rose from 3,250 to 16,310. 99% of 2,971 boards reached.
Workday forms stopping before Review
Problem
Each employer runs a different Workday form, and most runs stopped before the Review step.
Fix
Typeahead handling that types, presses Enter and keeps Workday’s selection. Sign-in handling. A test harness across 20 employers, run once a day because repeated sign-ins lock the test account.
Result
Employers reaching Review went from 1 of 20 to 13 of 20.
Wrong answers on live forms
Problem
Running the answer rules on live forms, without submitting, found a reversed sponsorship answer, school names in email fields, and “Not Hispanic” matching “Hispanic”.
Fix
Held the release until each was fixed. Fields the app is unsure of are now left blank and asked once.
A link change that broke embedded job boards
Problem
I changed the Greenhouse apply-link format, checked it with a command-line request and shipped it. On embedded job boards the new link redirected to a page with no form.
Fix
Reverted the change and wrote a database migration to repair the links saved by the affected releases.

What I’d change

  • Script the release process from the start. An early release raced two uploads and shipped broken.
  • Send every platform through one shared answer pipeline from the start. Workday had its own.

Co-founders: Jasper Buntinx (web and funnel) and Diego Prozzi (growth). I built the desktop app. About 2,100 of the 2,971 job boards came from Jasper’s board list.

Screens: the shipping app with sample data (fictional applicant, contacts and activity)

Lone Pine

Jun 2023 – Present

Operations software for my Amazon resale business, used daily by my team

Lone Pine Pipeline screen with sample data. Units from purchase order to live at Amazon, valued at cost.

Units from purchase order to live at Amazon, valued at costReal app · sample data · scroll sideways

$1M+sales, last 12 months
30,000+units sold, same period
3,500+purchase orders since Feb 2025

Platform reports, rounded

$50k$100kOctNovDecJanFebMarAprMayJunJulAugSep

Sep 2026 (through the 27th) · ~$113k sales

Sales by month · Sep still settlingHover or tap a monthTap a month
Read the Lone Pine case study

Overview

Lone Pine buys products from retailers and resells them on Amazon. I replaced its Airtable setup with a web app for purchasing, inventory, reimbursements and accounting, and migrated all 2,671 purchase orders on file. When data is missing, the app shows a blank rather than an estimate.

What I built Next.js · Postgres · Vercel

  • A per-unit ledger. Each unit gets a code and its purchase cost when bought, and is tracked until it sells.
  • Card-charge matching. Each charge is linked to a purchase order or given a stated reason why not.
  • One-click claim packets for Amazon reimbursement claims.
  • 44 scheduled jobs that sync Amazon’s seller API, Gmail, the Plaid card feed, carriers, the prep center and a repricer, each with a health check.
  • Row-level security by staff role. Approvals and digests go to Slack.

Results

Commits
1,637
Merged pull requests
183
Dashboard tabs
42
Database migrations
208
Per-unit ledger
Live since Aug 1
Scheduled jobs
44
First-load JavaScript
−60%

Problems solved

Cost per unit sold
Problem
Amazon reports which product sold, not which unit, so the cost behind each sale was unknown.
Fix
Each unit’s cost is fixed at purchase. Sales use up units with evidence of reaching Amazon first, so a lost unit is never counted as sold. Timestamps are compared as times. Comparing them as text would have rewritten every row nightly.
Result
The first run traced 36,923 units in one 34-second job. Sales it can’t attribute are counted and shown, not estimated.
Claim packets missing invoices
Problem
Reimbursement claims were generated without the supplier invoices that support them.
Cause
The app searched a synced copy of the inbox that held only a capped subset of emails.
Fix
Search Gmail live when the packet is built, render each email as it appears, and fill the claim letter automatically.
Result
Replaced about 110 minutes a week of manual work. A second review found two cases where the tracking-number parser could return a number that wasn’t in the email.
Failed data shown as healthy
Problem
Some sections showed “all clear” when their data had failed to load, and a hidden 1,000-row limit produced wrong overdue counts.
Fix
A tab-by-tab audit, with each finding re-measured before any change. Failed loads now display as errors.
Result
Re-measuring also corrected one proposed alert threshold from 16 days to 8.
Load time
Problem
Staff missed how fast Airtable was. One VA created 324 purchase orders and pasted 122 tracking numbers in a month on a single screen.
Fix
A September redesign in a native Apple style. Removed duplicate reads, cut first-load JavaScript from 495 KB to 193 KB, and moved the servers next to the database.
Result
Main-tab cold load went from 23.2 s to 4.8 s. A rewrite of 112 security rules took one query from 1,037 ms to 21 ms in testing. It has not shipped yet.

What I’d change

  • Add a health check to every data feed from the start. One feed was dead for weeks while showing green.
  • Test every staff workflow after a redesign. Six buttons were white-on-white for five days.

I own the business and built the platform. Our two VAs, one on sourcing and one on reimbursements, gave daily feedback.

Sales figures come from the platform’s own reports, rounded. Sales data in the platform starts February 2025, with 3,500+ purchase orders from 200+ suppliers since then. Screens use sample data.

Résumé

Trinity University · Class of 2027
Select a role for details

Awards Competitions

  1. 1st
    TAMU Datathon 2026, Heads Up poker bot challenge

    Hackathon winner with Final Boss Bot, built with a teammate in one weekend

    Nov 2026
  2. 2nd
    Indiana University stock pitch competition

    2nd place of 50 teams with a team pitch on Delta Air Lines (NYSE: DAL)

    2025

Education Expected May 2027

Trinity University

Neidorff School of Business · Bachelor of Business, Economics and Finance · San Antonio, TX

3.58cumulative GPA
Dean's List2024–26
2027expected graduation

National Hispanic Recognition Program · AP Scholar

Finance and investing

Derivatives · Equity Valuation · Principles of Investing · Real Estate and Alternative Investments · Corporate Finance · FINRA Securities Industry Essentials

Accounting

Financial Accounting · Intermediate Accounting I · Intermediate Accounting II

Quantitative and business

Advanced Spreadsheet Modeling · Statistics for Business and Economics · Business Law · Business Management · Operations Management

Skills Select one to see where it was used

Organizations

San Antonio FPA · Chess Club · ModernGuild · Youth on Course Golf · Trinity Men's Soccer Club · Armadillo Bouldering

Final Boss Bot

Nov 2026

1st place hackathon winner in the Heads Up poker bot challenge at TAMU Datathon 2026

Heads Up challenge · College Station, Nov 7–8
1stplace, hackathon winner
Practice matches won, 22 bots66 of 66
Time bank used, worst case4.2 of 8 s

Every pair of bots played the same 1,000 deals from both seats, so card luck cancels. A match only counted as a win when its 95% confidence interval cleared zero.

The bot
Game
Short Deck Omaha
Blueprint training
1.29 billion iterations
Solver
Written in C
Hand evaluator
~2,000× faster
Judge errors
0
Built in
One weekend, team of two

Practice results from our local tests and the official judge in its tournament container · Nov 2026

Read the Final Boss Bot case study

Overview

TAMU Datathon's Heads Up challenge asked teams to build a bot for two-player Short Deck Pot-Limit Omaha: a 36-card deck, five hole cards each, and no published solver. Bots met in a round robin on one CPU each, with 8 seconds of thinking per 1,000 hands. I built it with Diego Prozzi over the weekend, and it won 1st place.

What we built Python · NumPy · C

  • A CFR solver in C that trained a blueprint strategy for 1.29 billion iterations.
  • An opponent model learned during each match: 31 betting situations, 5 hand-strength bins and 4 actions, with the strength behind each action read from showdowns.
  • The opponent's range as about 500 weighted hands, updated after every action they take.
  • A search over the rest of each betting round that uses the opponent model for their replies.
  • A hand evaluator about 2,000× faster than the starter code in batches, identical on 146,000 checked hands.
  • A time governor that benchmarks the CPU at startup and keeps the bot near half of its time bank.

Results

Placement
1st place, hackathon winner
Practice pool
66 of 66 matches won
vs pure CFR bots
Even, 32 seeds each
Time bank used
2.7–4.2 of 8 s
Judge errors
0

Problems solved

One CPU
Problem
Under a 1-CPU limit, NumPy's extra math threads only spun, tripling the time the judge charged.
Fix
Pin NumPy to one thread and budget each decision from a startup benchmark.
Result
At most 4.2 of the 8 seconds used, with 0 errors.
Strong opponents
Problem
The bot's one measured leak: it lost 0.26 big blinds a deal to a pure solver strategy.
Fix
Average two blueprints trained with different card groupings into the opponent model.
Result
Even with both solver bots, and still unbeaten by the practice pool.

Results from our local tests · Nov 2026

Recall

May – Sep 2026

A long-term memory for Claude, scored on a public benchmark

LongMemEval · 150 questions
0.767115 of 150 correct
Baseline0.713
With my router0.767

LongMemEval tests long-term memory in chat assistants. The full run cost $4.30 of a $5 budget. The router raised scores on preferences and changed facts, and lowered them on dates.

By question type, 25 eachbaselinerouter
  • Assistant said, one chat1.00 → 0.96
  • User said, one chat0.80 → 0.88
  • Preferences0.24 → 0.44
  • Facts that changed0.72 → 0.84
  • Across many chats0.68 → 0.72
  • Dates and order0.84 → 0.76
Read the Recall case study

Overview

A markdown knowledge base of my work, summarized daily by scheduled jobs and searchable from Claude through an MCP server I wrote. I measured it on LongMemEval, a public benchmark, against success bands set before the run. The 0.767 score fell in the middle band.

What I built

  • A vault of notes, decisions and people as plain markdown files.
  • Scheduled jobs that write daily and weekly summaries.
  • A router that chooses how retrieved memories are laid out for each question. It still misroutes most questions that span many chats (5 of 25 correct).
  • An MCP server that lets Claude search the vault from any chat.

Results

Benchmark score
0.713 → 0.767
Running
Daily since May 9
Vault commits
194
Eval spend
$4.30 of $5

Remaining errors

Compared with a run given exactly the right memories, about 62% of the remaining gap comes from reading the answer, not retrieving it. Better search alone will not close it.

Poker bot

Oct 2026 – Present

A no-limit Hold’em research bot in Rust, benchmarked against Slumbot

Slumbot benchmark · 2,000 hands each
+31.9bb/100 with search, ± 43.8
Blueprint alone−4.6 ± 41.8
With search+31.9 ± 43.8

Dots are the measured win rate in bb/100, big blinds won per 100 hands; bars show the ± range. The search result is AIVAT variance-reduced. Both ranges still cross zero, so it is positive but not yet statistically significant. 15,000 more benchmark hands are queued.

Training and serving
Blueprint training
1 billion iterations
Hardware
16 GB M1 laptop
Cloud compute
None
Policy memory
272 → 18 MB
Median reply
86 ms
Tests
383

Benchmarks vs Slumbot, a public benchmark bot · Oct 2026

Read the poker bot case study

Overview

A research bot for two-player no-limit Texas Hold’em that follows the published Pluribus and Libratus recipe. It plays 200 big blinds deep, the standard format for the Slumbot and GTO Wizard benchmarks. It is for research and benchmarks only and has never been used on a real-money site.

What I built Rust

  • A Linear MCCFR blueprint, trained for 1 billion iterations on a 16 GB M1 laptop with no cloud compute.
  • Depth-limited re-solving, so the bot searches during a hand instead of only reading the blueprint.
  • A safe opponent-exploitation layer. This part is still in progress.
  • A live play table on a free-tier Google Cloud e2-micro.
  • Test-first phases. Each one closes only when its gate suite passes.

Results

Blueprint vs Slumbot
−4.6 ± 41.8 bb/100
With search
+31.9 ± 43.8 bb/100
Hands per run
2,000
Policy memory
272 → 18 MB
Median reply
86 ms
Tests
383

Problems solved

Fitting a free server
Problem
The policy took 272 MB, too much for a free e2-micro.
Fix
A compact quantized policy.
Result
About 18 MB, with a median reply of 86 ms.
Training speed
Problem
A billion iterations on one laptop takes a long time.
Fix
A rewrite of the training code for speed.
Result
About 1.6× fewer cycles per iteration, with byte-identical results.

What is not known yet

2,000 hands is a small sample in poker. Neither result is yet clear of zero, so the bot has not been shown to beat Slumbot.

Benchmarks vs Slumbot · Oct 2026

Taska

Aug – Sep 2026

Coursework, calendar and training in one list, sorted by due date

Taska week plan: each day's work blocks, capped at three hours a day, with due dates

Deadlines split into daily work blocks under a three-hour capReal app · demo courses · scroll sideways

Read the Taska case study

Overview

Pulls Canvas assignments, calendar events, GitHub and my training plan into one list, schedules work blocks under a daily cap, and shows the top items in a lock-screen widget on my phone. Originally named Canvas Planner, which still appears in the sidebar.

What I built Node · MCP · iOS widget

  • A single Node file with no dependencies.
  • An MCP server so Claude can read and update my to-dos.
  • A lock-screen widget fed by the top of the list.

Results

Load, cold / warm
2.0 s / 12 ms
MCP protocol tests
20 / 20
Dependencies
0
Sources
Canvas · calendar · GitHub

Problems solved

Slow loads
Problem
One slow source could stall a load for over a minute.
Fix
A timeout per source and a ten-minute cache.
Result
2 s cold, 12 ms warm.

Screens use the app’s demo mode with sample courses

IRONMAN 70.3 training plan

Jul – Sep 2026

A half-IRONMAN training plan, built from one data file

Training site day view for a Saturday: date strip, a 24-hour ribbon and every block from pre-ride breakfast to sleep

A Saturday: long ride, run off the bike, meals, rest and sleepReal site · personal details removed · scroll sideways

Read the IRONMAN case study

Overview

A training plan for a half-IRONMAN (1.2-mile swim, 56-mile bike, 13.1-mile run) alongside a full course load. I first aimed at Waco in October, did not register, and moved the plan to a spring race.

What I built Python → static site

  • One data file for the whole plan.
  • A Python build that fails unless every day totals exactly 1,440 minutes.
  • Output: a five-page site, a 141-event calendar feed and a 5:45 a.m. push notification to my phone.
  • Three dated swim checkpoints. Missing the 1,500-yard checkpoint moves the plan to a spring race, and the build recomputes every date.

Results

Next target
A spring 2027 70.3
Minutes per day, checked
1,440
Calendar events
141
Swim checkpoints
3, dated
Pages
Daily · Training · Diet · Gym · Progress

Screens are from the real site with nutrition targets and locations removed

Also built

Lone Pine design system

SF Pro type and spacing rules applied to every Lone Pine tab

359 commits
Daily business recap

Three read-only agents summarize Slack, business data and Amazon updates each morning

3 agents, daily
Course review pipeline

Turns lecture decks into quiz sites. Numeric answers are checked in Python.

7 lectures
Card-charge feed

Two years of card charges matched to suppliers, with the reason for each match

4,712 transactions
Multi-agent audit

Review of every Lone Pine tab. Each finding was re-measured before a fix.

82 findings

Contact

Open to internships and full-time roles in finance and product

hello@andrewborowicz.dev