2025.07.17.

Pezeta Progress Log

Spent today designing the Rails controller layer for Pezeta.

I analyzed Capito, an envelope budgeting prototype I built seven years ago. Standard approach – categories as envelopes, track balances, show what’s left to spend, like YNAB. But Pezeta takes a different angle. Instead of manually managing category balances, I’m building a goal-oriented system where users define financial objectives and the system calculates the monthly allocations needed to achieve them.

For the controller architecture I designed five main tasks:

Authentication & Ledger Foundation – Auto-create ledgers with system categories when users sign in the first time. System categories like Income and Safe to Spend get created automatically, so no manual setup required.

Budget Controller – Returns a single JSON endpoint for now, focused on Safe to Spend calculation and future goal balances. This is what the UI will display prominently, not a list of category balances.

Categories Controller – Standard CRUD for user-defined categories. Goals are implemented as special categories with allocation rules that determine how they get funded each month.

Monthly Allocations – This is where goal-driven allocations get applied, but users can override them when needed.

Test Infrastructure – Rails conventions with fixtures that include the system categories.

I’m sticking with pure Rails MVC patterns, so no service objects, no complex abstractions. Business logic lives in models, controllers stay thin, everything renders JSON for now since we don’t have a Turbo-based UI yet.

This foundation should make the goal system feel automatic rather than manual.

2025.07.15.

Pezeta Progress Log: Day 9

I built the model layer for goal-oriented budgeting in Pezeta today. This is the implementation of the goal system I’ve been designing over the past week.

I’ve laid the foundation for four distinct goal types:

  • Someday Goals – For big purchases. Save until you hit your target amount, then stop allocating.
  • Monthly Goals – For recurring commitments. Allocate a fixed amount every month, like subscriptions or regular savings habits.
  • Deadline Goals – For time-bound expenses. Spread the target amount evenly across the remaining months until your due date.
  • Reserve Goals – For emergency funds. Maintain a buffer of N months of average expenses based on your actual spending patterns.

I still need to test all of this thoroughly, but the models are in place and the calculations are working. What I like about this approach is how it will turn vague financial intentions into concrete monthly actions. Want to save $5,000 for a vacation by next December? The system can calculate exactly how much to set aside each month. Need three months of expenses in your emergency fund? It’ll figure out what that means based on your actual spending patterns. The system tracks progress over time, adjusts recommendations based on current balances, and integrates smoothly with the existing budget structure.

Next up is building the UI layer. The foundation is solid, but there’s still work to do before I can actually use these goal features in my own budgeting workflow.

2025.07.13.

On Deleting Second Brains

Joan Westenberg:

Two nights ago, I deleted everything.

Every note in Obsidian. Every half-baked atomic thought, every Zettelkasten slip, every carefully linked concept map. I deleted every Apple Note I’d synced since 2015. Every quote I’d ever highlighted. Every to-do list from every productivity system I’d ever borrowed, broken, or bastardized. Gone. Erased in seconds.

What followed: Relief.

Sometimes it’s good to delete things, but a second brain isn’t an end goal. The sole purpose of a second brain is to help achieve some form of output. It serves as a tool to organize thinking for the future.

The problem with output is that we often don’t know what it will look like when we start. What a Zettelkasten (and GTD too) acknowledges is that you’ll have an outcome of some kind and you need a framework to manage it. That’s all.

People who capture their ideas then leave them there are still doing the same thing, but can probably think through their output in their head. I do that sometimes too, and it’s fast.

But as soon as I’m working on anything that requires more thinking capacity than I currently have, I reach for PKMs and task managers to handle it.

I usually split my long-term project-specific Zettelkastens off from my main one, though.

Previously:

2025.07.12.

2025.07.11.

Pezeta Progress Log: Day 5

Today I worked on planning Pezeta’s goal system. I experimented with using two AI agents to collaborate on breaking down the work: Claude Opus 4 as the coordinating agent with read/write access, and ChatGPT o3 through Repo Prompt for implementation planning.

The idea was to leverage each model’s strengths. Claude handles the file operations and manages the task structure, while ChatGPT analyzes the codebase and suggests implementation approaches. They literally chat with each other using the Repo Prompt MCP tool, with Claude asking questions and ChatGPT providing analysis. Sometimes I had to intervene to guide them back on track or stop them to wait for my approval on design decisions. It’s like having two developers pair programming, each bringing their own expertise to the planning session.

The approach surfaced some important design decisions. Instead of service objects, we’re going with Rails-idiomatic patterns: model methods, class methods on MonthlyAllocation, and callbacks for snapshots. Everything through ActiveRecord.

Planning Through Test Cases

The bulk of the work went into defining test specifications:

  • 7 test cases for SomedayGoal
  • 15 for MonthlyGoal (including top-up logic)
  • 17 for DeadlineGoal (with auto-advance scenarios)
  • 17 for ReserveGoal

Each test case addresses specific edge cases. What happens when a monthly goal already has surplus funds? How does a deadline goal behave when it’s past due? Getting these details right upfront matters.

All calculations will use “opening balance,” the balance at the start of the month, not the current balance. This prevents allocation amounts from changing as transactions flow through during the month, which matches how people think about budgets.

The session produced seven detailed task files ready for implementation. Each includes exact specifications, test cases, and implementation notes. The tasks cover Single Table Inheritance strategy, historical snapshots through callbacks, and model-driven allocation suggestions.

Tomorrow I’m letting Claude Code implement these tasks.

2025.07.10.

Pezeta Progress Log: Day 4

Had a focused session today expanding the goal system design for Pezeta. Yesterday I started with the basic concept, today I dove deeper into the details.

I expanded all four goal types with detailed logic and edge cases:

  • Someday goals are your classic piggy bank. You want $3,000 for a new laptop someday. The system suggests funding it until you hit that target, then stops.
    • Edge case: what happens if you change the target from $3,000 to $4,000? Only future months use the new target.
  • Monthly goals keep a set amount available each month. You want $200 available for groceries each month. If you spend $150, you need $50 to top back up. If you somehow end up with $300, that’s fine – surplus is allowed.
    • Edge case: what happens if you never spend anything? The surplus just sits there – no more funding needed.
  • Deadline goals add time pressure. $2,000 for a vacation by next summer. The system calculates: you need $200 per month to hit that target.
    • Edge case: what happens if you miss a month? The next month’s allocation jumps to catch up.
  • Reserve goals are your safety nets. Keep at least $2,000 in emergency savings. If it dips to $1,500, fund $500 immediately.
    • Edge case: what happens if you never touch it? No allocation needed – it’s already above the reserve.

So this session was used to think about these and take a deep dive in the goal rule engine inner workings. I still have questions but it will be iterated when I start using the MVP. I have goal examples in my current budget for all of these.

The technical challenge was handling goal changes over time. What happens if you change your vacation target from $2,000 to $3,000 in March? Should January’s allocation be recalculated as if you always wanted $3,000?

I went with a snapshot approach. Each month gets its own snapshot of goal parameters. Past months never change retroactively. January’s allocation was based on January’s goal settings, period. This preserves the audit trail of what you were thinking at the time.

2025.07.09.

Pezeta Progress Log: Day 3

Today wrapped up the core data foundation with the Budget view model and spent time planning the goal allocation rules that’ll make this budgeting app different.

The aggregation layer

The Budget model pulls everything together. Give it a ledger and a month, and it calculates the current state of all categories, their allocated amounts, actual spending, and remaining balances.

This is just pure Ruby class that takes the foundational models and presents them in a way that makes sense to users.

Goal allocation rules

The bigger breakthrough today was finalizing the goal allocation rules. This is what’ll set Pezeta apart from traditional envelope budgeting.

Instead of managing dozens of budget categories, users define their financial goals—things they actually care about saving for. The app figures out how much to allocate to each goal and shows one simple number: how much is safe to spend on everything else. Goals run in the background while you focus on that single “Safe to Spend” amount.

I want to implement four goal types:

  • Someday: Save for something with no deadline—like a new laptop or vacation fund. Allocates the difference between target and current balance until you hit the goal.
  • Monthly: Keep a certain amount available each month—like rent or groceries. Tops up to the monthly amount, and any surplus stays there.
  • Deadline: Gather a lump sum by a specific date—like saving $3000 for a trip by July. Calculates how much to save each month based on time remaining.
  • Reserve: Maintain a minimum balance at all times—like an emergency fund. Only allocates money when the balance dips below the reserve amount.

Each follows different allocation formulas, but the key insight is the engine just calculates expected allocations—it never moves money automatically. That stays under your control.

The vision coming together

I’ve got a React prototype artifact built with Claude that demonstrates how this will look. We have a simple “Safe to Spend” number on top, goals running quietly in the background. I just created this to validate the UX approach, but it shows the vision clearly.

2025.07.08.

Pezeta Progress Log: Day 2

Day two of building Pezeta. Yesterday was all planning and starting. Today was about getting my hands dirty with actual Rails models.

Completed the three core models today:

  • Category model (with proper enums and validations)
  • MonthlyAllocation model (with decimal precision for money)
  • Transaction model (income/expense tracking)

Not the most exicting part for people to see (and I’m spending about 1–2 hours a day to build this), but I want to get the models right, that’s the whole point of why I’m writing the first MVP in Rails, I know Rails the best.

I’m trying to stick to test-driven development. Write the test first, make it pass, move on. Feels slower at first, but every time I change something, I know immediately if I broke anything.

The workflow experiment

Here’s something weird I’m trying: I started a new zettelkasten in Obsidian yesterday to drive this whole project.

The idea: use notes as the driving force to guide Claude Code through writing the actual code. I think in the zettelkasten, then I let AI collect that context and draft the output: code, blog posts, status updates etc. At the end I still manually review and adjust.

I’m using a modified version of Ian Nuttal’s Task Magic system to drive the development. Break big plans into smaller tasks, then automate the output generation. Not just code generation though. Claude Code helps with everything like documentation, tests, even these blog posts, but I’m still reviewing everything.

My theory is that this might be the fastest way to do solo development today. Capitalize on what AI is actually good at – turning clear thinking into working artifacts.

We’ll see if this scales. but for now, it’s working.

2025.07.07.

Bookmarked “I Shipped a macOS App Built Entirely by Claude Code”

I recently shipped Context, a native macOS app for debugging MCP servers. The goal was to build a useful developer tool that feels at home on the platform, powered by Apple’s SwiftUI framework. I’ve been building software for the Mac since 2008, but this time was different: Context was almost 100% built by Claude Code. There is still skill and iteration involved in helping Claude build software, but of the 20,000 lines of code in this project, I estimate that I wrote less than 1,000 lines by hand.

Indragie shipped a native macOS app with Claude Code writing 95% of the code. Haven’t dug into the full post yet, but Simon Willison pulled out the key bits – Claude nails SwiftUI but gets tripped up by Swift’s newer concurrency stuff.

Starting Pezeta

Finally decided to start building Pezeta today. It’s been in my mind for years – since we started Agyvihar, our Hungarian podcast about personal finance and productivity.

What’s Pezeta?

Simple: a budgeting app that tells you one number – how much you can spend right now.

That’s it.

No charts. No categories. No endless reports. Just open the app and see: $47. Or $134. Or whatever you can actually spend without screwing up your budget.

The features (keeping it minimal)

The One Number – Your daily spending limit. Updated in real-time. Factors in your bills, savings, everything.

Goals – Want to save $2000 by December? Cool. The app adjusts your daily number automatically. No spreadsheets required.

That’s basically it. If budgeting were simpler, maybe more people would actually do it.

Starting with Rails

I’m not jumping straight into building native apps. Starting with a Rails MVP instead.

Few reasons:

  • Rails 8 has some new stuff I want to try
  • Need a reference implementation anyway for the iOS/macOS versions
  • I can actually use it myself while building

This Rails version won’t go public. It’s just for me to validate the idea and work out the kinks.

Building in public (might regret this)

I’m putting it all out there because watching someone figure things out might be more useful than another perfect tutorial.

Partly for feedback – maybe someone will tell me this is a terrible idea before I waste six months on it.

Partly for accountability – harder to quit when people are watching.

Partly because I’m curious what happens when you share the messy process instead of just the polished result.

The plan

Starting with Rails 8 setup, basic models, authentication. The boring foundation stuff that nobody talks about but takes forever.

After that, we’ll see. Building software is weird.

2025.03.09.

2025.02.26.

Mihai Parparita is asking on Mastodon:

What are good examples of early Mac OS X software (10.0-10.4 era, pre-Intel switch)?

Then providing the initial list.

  • OmniWeb, OmniGraffle, OmniOutliner and other Omni Group software
  • Transmit 2, Unison, Candy Bar, Pixadex, and other Panic software
  • Audio Hijack and other Rogue Amoeba software
  • NetNewsWire and MarsEdit
  • Watson
  • Acorn
  • TextMate
  • Quicksilver
  • VoodooPad
  • BBEdit
  • SubEthaEdit
  • GraphicConverter
  • iCab
  • Camino
  • Fetch
  • Default Folder X
  • MenuMeters
  • DEVONthink
  • CodeWarrior
  • Resorcerer
  • FruitMenu, WindowShadeX and other Unsanity haxies
  • LiteSwitch X
  • DragThing and PCalc
  • TinkerTool
  • LaunchBar
  • Path Finder
  • Konfabulator

Good memories, although most if these are still alive and well.

Read “It’s still worth blogging in the age of AI”

Blogging is essential because it provides knowledge and serves as a valuable reference for us and others.

On the other hand, getting recognized as a blogger these days is rarely going to work. People are increasingly consuming different types of content these days, and this is largely due to the way AI is changing the way we interact with the web.

That said, having a blog for thinking out loud is still the best way to learn and then “report” it, even if we’re the only ones reading it.

2025.02.18.

2025.02.17.

2025.02.10.

Bookmarked “(mac)OStalgia”

Mac(os)talgia is exploring my 2020 work-from-home routine with an added touch of nostalgia. How would have the same workflow looked like with the tools of today and the limitations of yesterday.

I would take this Mac OS 9 design of Slack, Zoom, and Figma immediately.

2025.02.08.

Using tags to create threads in WordPress

Continuing 3380:

Maybe I should use tags as a thread title in a way that group posts together. I’m using pretty general tags currently, which is fine, but a tag page is just another filtered wall of text. This way, each post could be part of an ongoing conversation. Here’s an example page for a thread.

It means that I could have more precise tags which can be displayed in the sidebar, or even better, I can link to a thread which kind of acts like an article on its own. It was just written in a chronological order.

As an icing on the cake, a post could belong to multiple threads.

Continuing 3378:

If you visit the front page of my blog, you’ll notice that I organize posts by day, inspired by the daily notes feature from Roam Research.

I typically enjoy this wall of text style more than having separate posts highlighted individually (perhaps that’s why I like threading on Mastodon).

The issue is that WordPress lacks a similar feature, but I would love to have threading on my blog too. My Zettelkasten can stack connected notes, which aligns with this concept.

Maybe I should create something that allows me to link posts together, with backlink support.

Previously:

I sometimes think we might need different ways to share ideas instead of long articles—it’s important to mention that I’m talking about ideas, not stories.

Looking at how I read, I see that I usually skim content instead of reading it all at once. Then, I go back to the interesting parts later. If you think this is like Incremental reading, then you’re correct.

I’m not sure what might happen if I started using formats closer to the raw idea then heavily edited posts.

Exploring Real-Time Voice-to-Text Transcription Options

I’ve been thinking about using voice input more in my workflow after watching Chris from DailyTekk talk about quitting typing. He made some interesting points about how speaking (120-150 words per minute) is naturally faster than typing (40-60 words per minute). What was interesting is his observation about typing disrupting the flow with constant self-editing—I’ve definitely experienced this.

So, I’m experimenting with various voice-based input options for my Mac (and possibly iOS/iPadOS as well).

I recently acquired VoicePen as a tool to take voice notes. It’s not a direct dictation app, though. Instead, it works by recording voice in a separate app and then allowing you to copy the cleaned transcription back to your note-taking app. It maintains a history of transformations (such as fixing grammar and cleaning the text) alongside the original transcription. I can revisit and reapply these transformations or copy different versions of the text. It’s a decent tool, but it’s not designed for real-time voice input.

I looked at Inbox AI too, but it’s more of an automation app and I don’t want to invest time learning it right now. I’m sure it can do this.

Bolt.AI offers something different – it has an inline dictation feature. I’m currently trying out its dictation with chat assistants—being able to talk naturally to AIs instead of typing.

I’m also experimenting with macOS’s built-in dictation. It integrates well with text editing and shows what I’m typing in real-time. Sure, it sometimes types the wrong stuff, but these can be fixed quickly with the built-in writing tools.

I’m noticing there’s a difference between thinking out loud and just dictation—I’ll need more time to figure out what works best for each case. For now, I think each input method—typing, voice, even Apple Pencil—probably has its place. I’ll likely end up using a mix of them depending on what I’m trying to do.

Read “The Field Notes Thing”

I try to operate on the “Nothing Doesn’t Go in Here” principle. Flipping through the notebook that is on my desk right now, I see shopping lists, notes from conference calls, sermon notes, a little chart I made when working on some invoices for Relay, a doodle of the Widgetsmith icon I made for some reason, and a lot more. A receipt for a recent meal with a friend fell out of it onto my lap; I’ll probably tape that into the notebook for safekeeping.

The good thing about Field Notes is that you don’t have to care about it. It doesn’t feel pristine like some other brands. So, I mainly capture similar things, but I group them by date. I have meeting notes, programming session notes, random ideas, outlines, journal entries, etc.

These notebooks are a trail of breadcrumbs dating back almost 15 years. If I flip through an old one, I get a glimpse of what was going on in my life at that time. I can go to the notebook I was using when we launched Relay, or when I quit my job. I like having them on hand; seeing them in my studio each day makes me happy.

I never scanned my old Field Notes but kept them safe in a wooden box. I don’t care if they are destroyed someday since I use my notebooks as a temporary capture tool. If something is interesting, I’ll transfer it to my GTD system or just scan that part of the notebook.

Otherwise, the notebook can be discarded.

Previously:

2025.02.05.

Read “Google removes pledge to not use AI for weapons from website | TechCrunch”

Google removed a pledge to not build AI for weapons or surveillance from its website this week. The change was first spotted by Bloomberg. The company appears to have updated its public AI principles page, erasing a section titled “applications we will not pursue,” which was still included as recently as last week.

Asked for comment, the company pointed TechCrunch to a new blog post on “responsible AI.” It notes, in part, “we believe that companies, governments, and organizations sharing these values should work together to create AI that protects people, promotes global growth, and supports national security.”

Shit, I just finished watching the Terminator movies yesterday.

2025.02.04.

2025.01.31.

How to clean a MacBook keyboard

After today’s post on disabling the wake on lid open, I got a comment from smarthieef on how we can switch off this behavior for the keyboard too, so we can only turn on the MacBook using the Touch ID button, making the keyboard cleaning process way easier.

  • Press and hold the left Control and Command buttons with right Shift button for a total of 7 seconds.
  • Without releasing them, press the Power button and hold together for an additional 7 seconds until your laptop shuts down. The login screen may flash for a second so don’t prematurely release the keys until the machine is off.
  • For your next startup, your Mac can only be powered on by using the Power button or closing and opening the lid.

I tested this on a 16-inch M1 MacBook Pro, and it works indeed. It is also a one-time thing, so on the next boot, it resets this behavior to the default one, so we can get the best of both worlds.

Update: I tested this on an M3 MacBook Air too, and it didn’t work.