Releases
Thursday (August 6)
Voxprint macOS 1.3.6 shipped live today — Apple approved the rename build I pushed five days ago. iOS 1.3.6 is still waiting in review (submitted Aug 3), so the Mac version sneaked through first. Updated the App Store landing page to point at voxprint.heyitsmejosh.com and fixed a stray marketingUrl reference that was still pointing at the old echo domain.
Finished Inkpress’s overdue redesign tonight. The icon had become a invisible hairline sketch on dark—swapped it for a bold amber nib glyph. Added a real loading spinner to the feed view so it doesn’t feel frozen during background syncs. Built out a landing page at inkpress.heyitsmejosh.com on Cloudflare Pages (DNS verified, live), so it actually has a storefront now instead of just an App Store link.
Migrated Healstack from Vercel to Cloudflare Pages. The wrangler config had gotten tangled trying to be both at once, so stripped out the Vercel-only settings and redeployed. Restyled the landing page to match the Lexly design system (header, hero, features, status grid).
Completed the Lexly masterclass integration—built the converter script and shipped all 15 book summaries live. Found and fixed a converter bug on the first run (h3 subheadings weren’t handled, fell into an infinite loop instead of erroring). Widened the check to catch any heading level and reran clean.
Litigate got light-mode support with manual override toggle (detects system preference via prefers-color-scheme). Designed a minimalist gavel SVG for the favicon and PWA manifest that reads clean in both themes. Fixed a stray sign-in screen that still said “Brief” instead of “Litigate” on both iOS and macOS—the app renamed July 18 but the Text() view got missed.
Swept through roadmap consolidations across seven repos (epiphany, sparkjar, lexly, litigate, uprighty, nyc, talli), merging duplicate entries and pruning stale items. Verified Sparkjar’s Vercel production already has the right env vars wired, and confirmed the consolidation passes didn’t miss anything actionable.
Added seven new skills to dotfiles: mail-sweep, wrapup, architecture-svg, duolingo, git-sweep, localization-sweep, and trakt. The trakt skill was built earlier with a stdlib-only Python OAuth device-code client; the others scaffold the next batch of automations.
Friday (August 7)
Renamed the Uprighty app to Bookrank tonight after App Store Connect rejected “Uprighty” as a duplicate. Tried and landed on “Bookrank” after cycling through Shelved, Stacked, Booknook, Bookline, and Litshelf (all taken). Propagated the rename everywhere: ASC app record (appInfoLocalizations), GitHub repo from nulljosh/uprighty to nulljosh/bookrank with local git remote updated, domain moved from spine.heyitsmejosh.com to bookrank.heyitsmejosh.com (Cloudflare CNAME added and old one deleted), repo CNAME file, README, metadata JSON (supportUrl/privacyPolicyUrl), iOS/macOS CFBundleDisplayName/CFBundleName, and regenerated the Xcode project via xcodegen. Updated the portfolio site index.html link. All changes committed and pushed across uprighty/bookrank repo, nulljosh.github.io, and the Code meta-repo. Deliberately left the local folder at ~/Documents/Code/uprighty (not renamed).
Spent the evening fixing Epiphany’s bank-statement upload feature. The Blob store had been set as public by default, but the code needs private access for sensitive statements — and Vercel won’t let you change a store’s permissions after it’s created. Created a new private Blob store and repointed the code to use its token explicitly via EPIPHANY2_READ_WRITE_TOKEN. Also verified the deploy pipeline was actually working end-to-end (push-to-Vercel confirmed via the API), since earlier reports that it was “still broken” made me wonder if deploys were even firing at all.
Filed two stray Apple Notes into the system tonight: a personal note about money owed with Mom got moved into the wiki’s personal-accounts page, and a vague “Lexly Mac OS Issues” note was expanded and logged into Lexly’s roadmap. Cleared out the Notes inbox completely after that.
Later in the night, fixed Epiphany’s avatar lookup returning 500 errors — the Blob store SDK’s keys() method wasn’t being called correctly. Also tightened up the search suggestion dropdown appearance over busy map terrain (changed from ultra-thin to regular material for readability). Went through and pruned nine completed items from the roadmap to keep the backlog manageable.
Fixed the portfolio memoji avatar tonight—been bothering me for months that it looked fuzzy. Turned out the source was just a 128px screenshot; swapped it for a proper 512px cutout with the background removed and now it reads sharp. First pass cropped a bit too tight and clipped the chin—recropped with padding around the face and it’s right now.
Saturday (August 8)
Cleared the Apple Notes inbox—11 items archived. Fixed two critical bugs that had blocked shipping: Voxprint iOS 1.3.6 and Bookrank iOS 1.0 were stuck in review with phantom rejections, so I cancelled and resubmitted each via the API (now WAITING_FOR_REVIEW). Verified two other things that looked like bugs but weren’t: Portfolio’s animoji is actually live, and Sparkjar’s old TestFlight icon is just a stale build. Shipped Lexly’s branded splash and login logo (native SwiftUI), and wired up Epiphany’s Yelp location hours as open/closed badges across the app and web (live now). Also checked personal finances and filed an idea to the wiki.
Sunday (August 9)
Added error handling and diagnostic logging to Epiphany’s avatar upload flow—the KV and Blob store calls were missing try/catch blocks. This is a diagnostics pass on yesterday’s 500-error fix, so the real root cause should surface more clearly if it happens again. Fixed the ship-mac workflow after the ASC CLI renamed a parameter (--pkg-path became --ipa-path), and added --overwrite to avoid stuck uploads. Verified that Litigate’s RLS policy for case documents already has the WITH CHECK guard we were looking for, so no code fix was needed there—just marked it done in the roadmap.
Spent the evening processing book summaries for the Bookrank site. Finished three new chapters of “The Optimist” (Sam Altman/OpenAI biography)—prologue, chapter 1, and chapter 2—and published them live with a badge. Discovered that “Data Science For Dummies” had silently sat incomplete for weeks; the memory note claimed it was done, but chapter 20 was never summarized and 175 raw photos were still sitting in the backlog untouched. Cleaned and summarized chapter 20, so that book is now genuinely complete. Started “AI in Business For Dummies” and summarized the introduction chapter. Had to trace through the folder history (spine→uprighty→bookrank repo renames) and re-clone the project locally since the original wasn’t on disk anymore.
Finished clearing the entire book-photo backlog tonight. Wrapped up three new books for the site: AI in Business (chapters 1–2 with badge live), Accounting for Canadians (intro through chapter 3 with badge live), and macOS Tahoe (intro plus chapters 1–2 with badge live). The queue is genuinely clear now except for one book that’s still waiting to have its chapters photographed.
Spent the late evening debugging App Store Connect review statuses. Found a real bug in the asc-login script—it was asking for a 2FA code before ever contacting Apple, which is backwards. Rewrote it to call asc web auth login directly and let Apple’s prompt drive the flow. Upgraded the asc CLI to the latest version, but login kept failing with an SRP signin error even after the fix; suspect it’s a cached terminal session and needs a fresh tab to resolve. Investigated four apps with genuine App Review rejection reasons (Transcriptly, Wiretext, NYC Survive, Curvely) that aren’t exposed via the public API—they all need dashboard access to see the actual rejection text. Tried fixing Curvely’s empty release notes but discovered Apple doesn’t allow first-version apps to set What’s New (no prior version to diff against), so that’s not a bug to fix.
Earlier tonight: Epiphany’s map search suggestion dropdown now has an opaque backing so the map terrain doesn’t bleed through and make the suggestions unreadable. Also closed out the stale Echo-to-Voxprint web copy item in the roadmap. Late evening: Inkpress v1.0.3 shipped. The 2026-08-06 icon redesign and loading indicator had never shipped—bumped to v1.0.3 (build 202608092030) and rebuilt the stale App Store screenshot (seeded 4 demo feeds into the sim: journal, Daring Fireball, The Verge, Hacker News; captured on iPhone 14 Plus at full 1284×2778 pixels in light mode). Fixed two blockers: the icon 1024px file had an alpha channel, which failed Apple’s ITMS-90717 validation (flattened it onto opaque #161412), and added encryption compliance flags to the build + Info.plist. Fixed a stale CLAUDE.md note about the scheme name (was -scheme Inkpress, real scheme is Journal-iOS). Submitted v1.0.3 for review. Simulator shut down and quit.
Rewrote Newsline tonight — turned it from a website into a dependency that other people’s code can call. Added query params to the API (/api/stories now filters by view, outlet, bias, blindspot, plus full-text search and limit), and built an MCP server at /mcp with two methods (get_news and get_blindspots) to integrate with Claude and other agents. Wrote the API docs (OpenAPI spec) and security policy. Surfaced three production bugs while testing against live feeds: the CDN was caching query-string variants as the same response (responses now go no-store to avoid collision), filtering was happening after the 120-item cap so low-volume outlets had nothing left to return (reordered to filter first), and the feed parser was only matching RSS <item> elements, never Atom <entry>—Daring Fireball had been silently contributing zero items since it was added. Also added HTML entity decoding for titles. Pruned five feeds that weren’t returning anything (Reuters, AP, MSNBC, CTV, Washington Post); 17 outlets now remain, each verified live against real feed pulls.
Also recovered Cadence’s source code tonight from a Vercel deployment snapshot and migrated it to Cloudflare Pages Functions—the stats view and heatmap are now working on the new platform. Lexly got a forgot-password reset flow wired in. Nimble’s web app moved to Cloudflare Pages too, and I fixed a payload-key bug in the answer proxy.
Finished the Newsline distribution push later tonight. Published the MCP server to the official registry as io.github.nulljosh/newsline (status active, remote streamable-http). Added GitHub topics to the repo and rewrote its description to say “MCP server + JSON API” so people discovering it know it’s a dependency, not just a website. Advertised both the API and the MCP server on the site itself (footer with curl + claude mcp add lines, links to llms.txt and openapi.yaml for docs). Also drafted Show HN and r/mcp posts and opened a PR to the official awesome-mcp-servers list on GitHub (opted into their fast-track PR review, should see feedback within a day or two).
Audited all projects under ~/Documents/Code for password-recovery and email-verification gaps. Added forgot-password flows to Lexly and Litigate—both now send email reset links and verify the token before allowing a password change. Sparkjar added optional signup verification emails (soft gate, existing accounts grandfathered, login never blocked). BCGD’s dashboard auth screen got rewritten to support password recovery for admin sign-in. All code pushed. Lexly deployed live to Cloudflare Pages (project lexly-heyitsmejosh, verified at lexly.heyitsmejosh.com/app/; forgot-password flow working). Litigate deployed live to Cloudflare Pages (project litigate, verified at litigate.heyitsmejosh.com). Sparkjar deployed to Vercel production (verify-email endpoint returns 302 as expected). Critical finding: sparkjar has no SMTP env vars on Vercel and never has—both the password-reset and new email-verification flows ship successful responses but silently no-op on sending. Fix is Resend (epiphany already uses it), not SMTP: needs RESEND_API_KEY env var, sparkjar domain added to Resend + DKIM/SPF records in Cloudflare. Logged to sparkjar/roadmap.md. Not fixed this session.
Late evening audit of every app’s authentication state. Found that Sparkjar was assumed to be the last one needing password recovery and email verification, but it’s actually the most complete—it has both implemented, though mail.js silently no-ops on Vercel without SMTP environment variables. Epiphany, Healstack, Litigate, and Roost already have both features working. The real remaining work is Talli (has neither forgot-password nor email verification built yet) and Lexly (signup and login UI only, no recovery or verification paths). Added three roadmap items: sparkjar needs SMTP_HOST/USER/PASS/FROM verification in prod, Talli needs both features built, and Lexly the same.
Apps
Bookrank: Data Science For Dummies completed (chapter 20 added), The Optimist summary added (prologue + ch. 1–2 with badge), AI in Business intro started. Voxprint macOS 1.3.6 shipped live, iOS 1.3.6 resubmitted after fixing stuck review, roadmap Echo→Voxprint web copy item closed. Inkpress v1.0.3 WAITING_FOR_REVIEW (shipped icon redesign + loading indicator + refreshed App Store screenshot + icon alpha flatten + encryption compliance). Healstack migrated to Cloudflare Pages with refreshed landing. Lexly integrated 15 masterclass summaries (converter infinite-loop bug fixed) + branded splash/login logo shipped + forgot-password reset flow added (Vercel deploy pending). Litigate added light mode + gavel icon + fixed Brief→Litigate sign-in text + verified RLS policy already had WITH CHECK guard + forgot-password reset flow added (deploy pending). Sparkjar added optional email verification on signup (soft gate, existing accounts grandfathered, login never blocked; requires SMTP env vars to send). BCGD dashboard rewrote auth to support password recovery (build clean). Bookrank renamed from Uprighty (ASC duplicate rejection), domain/repo/app-display-names/metadata all updated, iOS 1.0 resubmitted after fixing stuck review. Epiphany’s bank-statement upload fixed (private Blob store provisioned), avatar 500 error fixed with diagnostic logging added, search suggestions now opaque with improved readability over map, Yelp location hours now showing as open/closed badges across iOS/macOS/web, ship-mac workflow fixed for ASC CLI API change. Newsline v0.3.0: turned into API + MCP server dependency (query params for filtering, openapi.yaml + security docs), three production bugs fixed (CDN cache collisions, filter-before-cap reordering, Atom entry parsing + entity decoding), 5 dead feeds pruned (Reuters/AP/MSNBC/CTV/WaPo), 17 outlets verified live. Cadence recovered from Vercel backup and migrated to Cloudflare Pages Functions (stats + heatmap working). Nimble web migrated to Cloudflare Pages, answer-proxy payload key fixed. Roadmaps consolidated across seven repos, nine completed items pruned. Seven new skills added. Apple Notes inbox cleared (11 items).