home..

Everything Connected

Platform Sprint

Weekend

Monica took up most of the weekend. I renamed it from Opticon and immediately broke the live site. Spent a full day reading through error logs before realizing the actual problem was hidden behind a crash page. Ten minute fix once I could actually see what was wrong.

After that things picked up. Built a daily brief so when you open the app you just see the important stuff right away – top movers, headlines, no clicking around. Put wildfires on the map next to earthquakes using NASA satellite data. The biggest thing was building a knowledge graph into it. Stocks, earthquakes, people, places – everything is connected now and you can search across all of it. Added an AI chat panel that can actually pull data from the app while you talk to it.

On the money side, built out debt projections, income timelines, and a spending simulator. Found a bad bug where the app was making 30,000 server calls per user per day. Portfolio was showing $0 because it was forgetting to count account balances.

The phone app went from rough to actually usable – spending predictions, simpler layout, dark mode that follows your phone settings, charts that stopped breaking on early morning checks. Fixed the map so it pulls from all its data sources instead of just three. Canadian weather alerts finally work. A bunch of construction data was being quietly thrown away.

Spark got threaded comments, then I went all in on the Apple side. Rebuilt the iPhone app with profiles, badges, and sorting. Built a Mac app, a watch app, and widgets for all three. Fixed a voting bug where it was counting things twice and locked down the database. Mac, iPhone, watch, widgets – same logic, four passes. The fourth pass is where you find all the places you made bad assumptions on the first.

Tally got a proper benefits guide for BC and Canada. Went back and fixed some of the existing info that was wrong. Built contacts sync with disability tracking. Same Apple sweep as Spark – Mac app, watch app with a countdown to your next payment, widgets. Your paid status and read messages actually save to your account now. Tightened up security across the board.

Arthur got smaller. Compressed the model down so it actually fits on a normal computer – went from huge to 91MB. Had to retrain it from scratch because I realized it was learning wrong, reading text in both directions when it should only go forward. Upgraded how it breaks words apart. It can write grammatical sentences now. It cannot think. Fair result for a tiny model.

Then on Saturday I turned Arthur into a live service. The exported model is 656MB at full precision, 168MB compressed. Vercel’s size limit is 100MB per file, so the full model does not fit. What does fit: a smaller version running in the browser through WebAssembly. A leftover folder was hiding the real server code, which took longer to find than it should have. Two pages now: one shows the architecture, the other takes a prompt and writes text back. The full model needs a bigger host. Live at arthur.heyitsmejosh.com.

Later that evening I went through a list of things bugging me. Monica had a phantom green dot on the map floating 800 meters from the real location pin – a second marker at a hardcoded offset meant to show “local activity.” Pulled it. Fixed the mobile nav buttons too, they needed 5 to 20 taps to register because the touch targets were too small. Spark’s deploys were failing because the free plan caps at 12 server functions and Spark had grown past that with duplicate files. Cleaned those out. Arthur’s site was showing raw data instead of the actual page because the deploy was uploading the wrong folder. One-line fix. Had 29 projects on GitHub, 19 of which were archived and already folded into bigger projects months ago. Deleted all of them. Down to 10.

Cleaned up my portfolio site with new fonts and better mobile layout. Rebuilt the project showcase. Spent time making all my apps look consistent – same colors, same feel across web, phone, and desktop. Folded a bunch of standalone projects into bigger collections to stop the sprawl. Cleaned out dead projects.

Saturday was gym, studying, homework. Found out Ben Poile deactivated his Twitter. Was going to send him the new Kanye album. No way to reach him now.

Monday

Chatted with Alex for almost two hours – the usual stuff, the future, intelligence, how most people are not applying themselves and what it would take for people to actually be better. Then it got heavy. He started arguing parents should hit their kids more, that his dad throwing him on the couch at 12 was good discipline, good for his development. Biggest disagreement we have ever had. He is my oldest friend so it had to happen eventually. Kinda bummed me out though. I had to laugh a bit because what he described is nothing compared to what I went through at two years old, and what I went through is nothing compared to my grandpa, who is 80 with dementia and still cries about his dad beating him as a kid. Three generations of it. Hard to hear someone argue it builds character.

Gym. School work. Mom’s birthday, called her. On the computer side, spent the day making everything look the same. Dose and Lingo got refreshed to match the portfolio site. Same with the NYC game where the phone, desktop, and web versions were all slightly different colors, now synced up. Updated school grades in Tally. Fixed something in Spark where background files were being treated as separate pages. Took Arthur off the portfolio since it is not ready to show. Updated a balance in Monica. Cleaned up leftover projects on Vercel from consolidation. Quiet Monday.

Replaced all the charts in Monica with TradingView’s library. Nine chart types now – candlesticks, Heikin Ashi, bars, line, area, and more. Heikin Ashi is the default because it smooths out the noise. The data now includes open/high/low/close prices instead of just the closing number, so the time axis and candles actually render right.

Brought the same charts to the phone and Mac apps. Both got the full nine-type picker using the same data.

Added five games to Lingo – chess, 2048, memory match, minesweeper, and snake.

Found a leaked API key in the Xcode build files and scrubbed it out.

Spent the evening consolidating again. Moved bots into the systems monorepo, reorganized Dose, and cleaned up dead projects on Vercel. Down to 10 active repos. Also fixed the auto-commit watcher so it stops spamming empty lines into journal entries.

Tuesday

Spent the afternoon vibing the portfolio’s Zinc aesthetic into Lingo across all three platforms.

The web version got aligned to the portfolio’s monochrome palette, swapped bright icons for subdued colors, replaced the opacity-fade hover pattern with spring transitions, and added fade-up entrance animations. Fixed a dark-mode ripple bug and removed dead variables.

iOS replaced every frosted material background with explicit Zinc colors through a new theme system. Stripped all accent colors in favor of primary and secondary label. The review pass caught that minesweeper’s monochrome number colors were nearly indistinguishable and 2048’s tile grays shared values for different tiles. Fixed both.

macOS got a brand new app. Sidebar navigation with categories, shares all models from the iOS version. 44/44 tests pass.

Removed emoji characters from source files across all projects. Six files touched. Everything now uses plain text or Font Awesome icons.

Wednesday

Full day across four projects. Morning was fixing bugs from a punch list. Afternoon shifted to payments, real portfolio data, and more consolidation.

The map in Monica was showing nothing on any layer even though settings showed everything enabled. A filter was silently rejecting every marker that did not have both a source label and a valid link. Removed the filter and replaced it with a simple location check. Flights were completely missing – the data source existed but the app never asked for it. Wired it up. Profile photos were not sticking after upload because the app kept the URL in temporary memory. Fixed it so the app refreshes after upload. Also fixed a bug where a network hiccup during login would sign you out entirely.

Added a $1/week tier and updated the pricing page. Three tiers now with a clear feature breakdown. Pulled real portfolio data from Wealthsimple for the first time. Portfolio charts now show actual positions instead of placeholder data.

Changed the Spark feed from a vertical list to a two-column grid on desktop, single column on mobile. Added six starter posts so the feed has content on first load.

Moved the jot programming language into the systems monorepo. The old standalone repo is archived.

Thursday

Late night session clearing the brain dump backlog for Monica. Converted a scattered PDF of ideas into a prioritized plan, then worked through the top items in one sitting.

Fixed two bugs. The watchlist was showing duplicate stars on certain stocks because the same ticker appeared in both the Watchlist section and the main All Markets list. Filtered them so each stock only shows once. Login errors on the mobile apps were also too vague, so added better messages that explain what actually went wrong.

Two new features. Polymarket whale tracking now pulls large recent trades and surfaces the top traders and their moves in the Situation Monitor. Also brought the Tally payday countdown to the web version – it was previously only visible on the native apps.

Housekeeping turned up fourteen stray code coverage files left behind by the test runner across every repo. Cleaned them all out and added ignore rules so they stop accumulating.

Friday

Got the BC Garage Doors project properly set up. The landing page and the inventory dashboard were living in two separate places with no connection between them, so I merged them into one project and gave each its own subdomain.

The landing page is now at bcgd.heyitsmejosh.com. It is the customer-facing site with the phone number, booking form, reviews, and service info. The inventory dashboard is at bcgd-dashboard.heyitsmejosh.com. That one tracks parts, stock levels, low-stock alerts, and order history for the shop. Both are live.

After that, cleaned up the codebase again. Had 13 active repositories, which was too many. Merged the bots into the systems repo, moved bhaddie into the apps collection, and archived the old copies. Down to 10 repositories now. Also found a third duplicate copy of the dashboard hiding inside the apps folder under a different name and cleaned that up too.

Saturday

Housekeeping day. Ran the morning update and it failed on a repo called core that was deleted months ago when it got renamed to Arthur. The local directory was still sitting there pointing at a GitHub repo that no longer exists. Deleted it.

Went through the rest of the morning-update script and found more rot. The skip list still referenced three repos that do not exist anymore from before consolidation. Two repos we do not own, lil-agents and tradingview-mcp, were failing with permission denied errors every single morning because the script tries to push everything it finds. Added those to the skip list along with shannon. Fixed the step counter too, it was showing 13 when there are 14 steps.

Found that Tally’s backup copies were committing Puppeteer browser artifacts to git. Chrome leaves behind symlinks like SingletonCookie and SingletonLock in a chrome-data/ folder and the auto-commit was happily adding them. Added the folder to .gitignore and cleaned them out of tracking.


Monica

Spent the whole day on Monica. Started the morning with a blank map, 33 GitHub repos, and a version number that was lying to everyone.

The map had been empty for weeks. All 11 data layer endpoints were wired up, settings showed everything enabled, markers worked fine in isolation. But production loaded nothing. Traced it through the stack: the fallback logic treated empty API responses as valid data and skipped the estimated fallbacks. Traffic returned an empty array because both API keys were dead. OpenSky rate-limited flights into a silent 502. Every source came back empty, so the map rendered nothing. Fixed the fallback chain, wired up the mapLayers prop that was being passed around but never actually used, and got markers rendering.

Then kept going. Flattened the navigation from two nested levels down to five top-level tabs: Situation, Markets, Portfolio, People, Settings. The old layout had “Markets” appearing in two places meaning different things. Merged the People panel’s three-tab picker (Search, Index, Graph) into a single scrollable view across web, iOS, and macOS. Removed the $20/month Pro tier, keeping just Free and Premium at $1/week. Got real API keys configured for TomTom, HERE, and Ticketmaster. Added CoinGecko crypto and Reddit trending as new data sources. Wrote a whitepaper. Built a new Palantir-style hexagonal icon. Deleted 23 dead GitHub repos. Called it v5.0.0 and pushed.

Came back in the evening to test the live site and it was broken. Stock detail crashed with a TypeError from the charting library choking on duplicate timestamps. The app was defaulting to light mode. Map popups were in monospace. Scrollbars were light-colored on a dark UI. The Settings page still said v3.5.1. None of the morning’s changes had actually deployed properly.

Fixed the stock crash by deduplicating history data before passing it to lightweight-charts and wrapping chart creation in try/catch. Ripped out light mode entirely. Changed popup font to system font. Added dark scrollbar CSS. Then discovered Monica was burning through Vercel’s free tier: 1.4M edge requests against a 1M limit, 1.1M function invocations against a 1M limit. The culprit was aggressive polling. Flights, traffic, stocks, and Polymarket were all hitting the API every 120 seconds. One open tab generated about 120 function invocations per minute. Changed everything to 5-minute intervals, cutting usage by 75%.

Connected a Vercel Blob store for avatar uploads. Regenerated Xcode app icons from the new SVG. Reset the version to v1.0.0-beta because calling it v5 when half the features are broken is dishonest.

Quest Night

Built a gamified RPG task manager called Quest in one session. The concept: a fantasy quest journal for tracking real-life tasks, with XP, leveling (Squire through Mythic), difficulty ranks (F through S), dopamine rewards (80% chance on completion), and streak tracking.

Started with the web app. Vite + React, PWA-ready, full medieval aesthetic: parchment cards with torn edges, wax seal completion animations, gold XP bar, leather textures. MedievalSharp headings, Crimson Text body, Metamorphous stats. 23 tests passing. Then built the iOS app (SwiftUI + SwiftData, iOS 17+) and macOS app (NavigationSplitView with leather sidebar). All three platforms building clean.

Then the real move: merged everything into the NYC colony sim. Colonists now perform your real-life quests. Add “Go to the gym” as a fitness quest, and a colonist walks to the Gym building, shows a speech bubble saying “Lifting weights”, works for 60 ticks, earns XP. Every 5 quests in a category boosts colonist stats matching that class (Warrior gets STR/END from fitness). Quest board built directly into the HUD (Q key). Player profile shows level, title, XP bar, streak.

Added wallpaper mode (Shift+W). Hides all UI, auto-camera slowly drifts between colonists, real-time day/night cycle. Reduced need decay so colonists survive indefinitely. The game auto-starts on load, no menu. The idea is to run it as a desktop wallpaper: a living city where little people are doing your productive tasks.

Deleted the standalone quest app, quest-ios, and quest-macos after the merge. NYC is the life game now.

Late Night Sprint

Came back after dinner and burned through a stack of accumulated task PDFs from my phone.

Life iOS: Finished the interrupted work from last session. Six new therapy visualization views were staged but never wired in. Integrated all six into the paging scroll, built clean, pushed.

BCGD Dashboard: Big night for dad’s garage door business dashboard. Added low stock reorder email alerts, a settings page, browser notifications when stock drops below threshold. Then added PIN authentication so not just anyone with the URL can modify inventory. Built a backup/restore system. Built a full job pipeline tracker so he can track jobs from lead through quote, scheduled, complete, and paid. Dashboard now shows job stats alongside inventory. Added wholesale cost estimates for all 28 parts so the inventory value card actually shows a number. Deployed everything to Vercel.

Monica: Updated Telus phone bill data from actual PDF statements. Added a Bills section to the finance panel with Telus device payment breakdowns. Stripped dead API calls from four server routes for a 234 line reduction. Split App.jsx from 1634 lines into three new layout components, bringing it down to 1323. Bumped the macOS companion to v0.7.0.

NYC: Added an AI autoplay system. The colony can now run and build entirely on its own. It assesses needs, decides what to build, places buildings near the colony center, recruits new colonists when stable, and shifts directives between gather and patrol. Toggle with the AUTOPLAY button in the directive bar.

Monday

Off the keyboard today. School application, prerequisites, gym. No commits. The colony ran itself.

Later in the week

Eleven repos touched across the back half of the week, four platforms, well over fifty commits.

dose

Added a facemaxxing module. Tracks jaw, skin, and posture metrics across sessions. Shipped to web, iOS, macOS, and watchOS simultaneously. Library page got a redesign. Categories now group everything, sticky filters at the top with item counts. Desktop layout hit v2.1.0 with a wider sidebar nav.

Then labs. You can now add blood panels directly in the app using predefined templates for CBC, metabolic panel, lipids, thyroid, vitamins, and HbA1c. Every marker gets a reference range, a flag status (normal, low, high, critical), and a trend chart if you have multiple readings over time. On web there is also a LifeLabs PDF import tab. Drop a PDF from the patient portal and it parses the text client-side, extracts panels by heading, and pulls marker values using pattern matching. Nothing leaves the device.

The insight engine runs entirely on-device with no model needed. It looks at three things: dose log versus biometrics (does heart rate go up on days you log caffeine?), biometric anomalies flagged when a reading is more than two standard deviations from your personal mean, and lab marker trends when the same marker moves monotonically across three or more results toward its reference limit. The top findings show up on the Dashboard as small cards, and the full list lives in the Insights tab.

UI bump landed on all four platforms. Web dashboard now has a small SVG health score ring in the header. iOS got the same ring, colored green above 80, orange above 50, red below. macOS finally has a real dashboard with active stack, recent entries, and the top insight. watchOS dashboard got a ring arc overlaid on the dose count card.

nyc

Version 2.1. Particles on movement, four-frame character animation, and a basic lighting system. Quest pathfinding was broken. Units were routing to the building tile itself instead of an adjacent tile, which caused a hard freeze at level 5. Fixed. XP and leveling now behave consistently across platforms. 4x tick speed with normalized decay rates.

epiphany

Monica is now Epiphany. Name updated in the readme, project config, page title, and portfolio. Domain and the GitHub repo still need manual renames through the dashboards, but the visible layer is done.

Earlier in the week: sticky header in the markets panel, glass search and sort row. Map layers now retry on cold start instead of failing silently. History chart was broken because the API returns a time field, not date. Chart was rendering nothing. Fixed. Mobile scroll and map blur cleaned up. Indicator system is now fully customizable.

Later: the markets panel now shows a TradingView icon on every row that links directly to the chart for that ticker instead of the homepage. Stocks were showing dashes for P/E, EPS, beta, and market cap because the old code only hit one endpoint. Switched to two parallel requests per symbol so all four fundamentals populate correctly now.

The stock detail card was cut off on mobile. Fixed with a proper responsive width and a viewport-relative max height. The map had a pixelation issue on high-DPI screens, so the pixel ratio gets clamped now. The situation monitor on mobile was too dense. Trimmed the flight count and hid the source health strip on small screens.

AI enrichment in the people module was refusing to run because it required an API key environment variable. Removed the hard check and added a fallback that calls the Claude CLI directly when no key is present.

Six bugs fixed from a backlog PDF. Email verification links were going to 404 because the server was using Vercel’s deployment-specific URL instead of the custom domain. Added a SITE_URL env var check so links always point to the real domain. Markets chart data was blank for every symbol because Yahoo Finance now requires a crumb token exchange before accepting chart requests. Added cookie fetch, crumb cache in KV, and a query2 fallback. The horizontal ticker bar was eating touch taps as drags because the drag threshold was the same for mouse and touch. Raised it to 10px for touch. Flights and traffic were showing red “temporarily unavailable” banners even when data was present but estimated. Changed to a muted “Estimated” label so it is informative without looking broken.

Profile photo upload is gone. Clicking the avatar circle now generates a 64x64 bitmap directly in the browser. Symmetric pixel pattern, random palette, no file picker. Saves immediately to Vercel Blob via the existing avatar endpoint.

Cleaned up old standalone monica-ios and monica-macos directories. Both platforms now live under epiphany/ios/ and epiphany/macos/ with their own plan.md task files.

tally

Version 3.0.0. Stripped out a significant amount of complexity. BCeID credentials now load from ~/.config/tally/credentials.env so nothing is baked in.

Bottom tab bar is gone. Navigation moved to a horizontal row at the top. The Benefits tab was blank so it got cut. Footer is now semantically correct.

On iOS, the settings screen was missing entirely. Added it with account display and a destructive logout button. Notifications were not clearing when you opened the messages tab. Fixed with a content hash stored in local storage that marks things as read on tab switch. A Swift compiler warning about a non-exhaustive switch statement got resolved by adding the missing case.

nimble

Parallel API requests so the interface does not block waiting on a single source. Natural language math parsing added. Type “fifty divided by three” and get an answer inline. App icon done. iOS README now has a real screenshot, generated automatically by a UI test target.

The iOS app showed instant answers but no web search results, which is a real gap from the web version. Added a parallel web search fetch that hits the production API alongside the instant answer query. Results appear below the instant answer card as a list with domain, title, and snippet.

life

The geography map had labels for Vancouver Island positioned right at the left edge of the SVG, which caused them to clip on any narrow screen. Moved them to the right side of their dot so they have room to breathe.

The name anonymization from the previous session missed the inline charts, timeline entries, tooltip text, and the iOS data model. Everything got cleaned up across both platforms. Relationship labels are now First and Second. NYC no longer names anyone.

The deploy config was also missing an output directory declaration, which caused the live site to show a 404. One line fix, now resolves correctly.

school

Same deploy fix as life. The school subdomain was returning 404 because the static site config did not declare where to serve files from. School iOS quiz was returning 404 in production because @vercel/node was not bundling the data/ directory with the function. One line in vercel.json fixed it.

new apps

Three new apps shipped. wiretext is a Unicode wireframe design tool. Pick components from a palette, place them on a monospace canvas, export as plain text. Runs on web, iOS, and macOS. claude-usage tracks Claude API consumption: a dashboard with a monthly summary ring, a charts view, an entries log, and an iOS widget showing this month’s token count. Both got a zinc dark restyle pass at the end of the week, swapping green for indigo and moving to Inter. fuse is a timeline app built around bomb-timer style countdowns, pulling from iCal and custom event sources.

portfolio

Replaced the SVG app mockups with real iOS screenshots for all project cards. Added NYC to the projects list with a live link. Gallery columns fixed to equal width. Previews refreshed.