An exploration of Apple business news and technology. We talk about how businesses can use new technology to empower their business and employees, from Leo Dion, founder of BrightDigit.
EAS-210
===
Leo Dion (host): [00:00:00] Welcome to another episode of Empower Apps. I'm your host, Leo Dion. Today, I'm joined once again with five-timer Donnie Walls. Donnie, thank you for coming back. It's been a while.
Donny Wals (guest): Yeah, thanks for inviting me back. It's a always a pleasure to be on
Leo Dion (host): Before we begin what have you been up to lately?
Donny Wals (guest): Oh, I've been up to a bunch of things since the last time we spoke. I don't remember exactly when I was on last time, but basically last year I didn't do too much of conferencing. I was just working on client work, my apps, my blog, and everything. And then this year came around and everything was different with AI suddenly eating a lot of traffic.
Donny Wals (guest): So I decided to double down on my workout tracking app which I've been working on a lot. It's called Magazine. I've been doing just more of client work. I've updated my Swift concurrency book in the [00:01:00] meantime. And yeah, mainly a lot of trying to figure out what to do in this age of AI and how it will change the way I work, how it will change the content that I make, the content that I want to make.
Donny Wals (guest): So been thinking about that a lot as well. Hasn't really turned into anything to create yet. But thinking is being done a lot. Yeah
Leo Dion (host): So how, what surprised you the most over the last year or so as far as like where AI, how AI has affected you?
Donny Wals (guest): Yeah. So it's been something that was, I think, on my mind probably somewhere around late 2024, where we had Cursor, and it became easier and easier to use AI, and it was still very much not great. But you could see that this was something that a lot of very [00:02:00] smart people were interested in, and you could see that, that there was going to be a use for it, right?
Donny Wals (guest): At that point, I was pretty sure that it would impact the way that I work, it would impact the work that I did. I just had no idea how. And then somewhere through 2025, I feel like things started to fade a little bit. People seemed to almost lose interest. We were just resuming work as normal, and we had these cool tools, but real developers wouldn't use it.
Donny Wals (guest): You know what I mean? So everyone's like: "Oh, it's not great. It doesn't do anything exactly the way I want it to." But then, So I, I was pretty comfortable during that time, and then suddenly late 2025 all these new models came out, and we didn't just have Cursor as a harness, we also had Claude Code, we also had Codex, and all of a sudden, almost overnight I felt like it happened over Christmas, over the New Year's break.
Donny Wals (guest): A lot of people were off talking to friends and family, and we all came back mid-January, and [00:03:00] suddenly nobody wanted to write code anymore, at least not in, in my environment. Everybody was like: "Okay, I'm not writing code. I'm going to prompt it. I'm gonna use agents because now an agent can work on my full project, and it might not be perfect code, but it's good enough to keep it."
Donny Wals (guest): And it's almost just like that. It was a long time coming. It almost felt like it might never happen, and then suddenly it just happened. Agentic coding was there. Nobody wanted to read blogs anymore. Nobody wanted to read books anymore. Nobody wanted to learn anything anymore other than how do I prompt this thing efficiently, and how do I just make it magically do what I want?
Donny Wals (guest): And so the way it impacted me was it changed the way that I work, and it's really made the blog take a hit. It's really made the books take a hit. It's really hard to sell workshops now to, to companies because they're... Like, nobody seems, especially for the first five, six months of the year, nobody seems very interested anymore in deeply learning something.
Donny Wals (guest): Everybody just wants to get the agent to do [00:04:00] stuff.
Leo Dion (host): Let's see, where do I go with this? So do you think we're gonna see a rebound at some point? Because I mean, at some point you do kinda have to know how this stuff works behind the scenes
Donny Wals (guest): Yeah, I'm not exactly sure about that. In a way, I think so. It actually feels like the magic has worn off over the past couple months, and a lot of people are tired of not writing code, tired of this crazy new multitasking that we're all having to do. We're all being encouraged by companies, by managers, by CTOs to spend tokens, right?
Donny Wals (guest): To make sure that we
Leo Dion (host): a lot of pullback from that, like
Donny Wals (guest): it's been starting to happen, yeah. I was about to say the beginning of the year was like do as much as you can with AI. We were all very much almost forced to try and almost like multitask into the point where it seemed like higher-ups and enthusiasts were almost trying to [00:05:00] spend like an hour in the morning to tell like as much agents as possible to perform as many tasks as they possibly could, and then you would go off and do other stuff, and you'd come back in the afternoon, and you would just click approve on a bunch of PRs. And the reality has been that's not the way it works, right? Like I, I think more and more people are just seeing okay, we're producing more PRs, but reviewing them is more tedious. It's harder. It takes longer if we want to do it correctly. We have feedback. We have suggestions, but whoever put up the PR doesn't really know how to properly implement the feedback because they didn't really write all of the code in the first place.
Donny Wals (guest): And so in the end, we're producing more, but we're not always shipping faster. We're just having more PRs sit in review for longer. I think that's the reality for a lot of what I'm seeing at least and what I'm hearing as well.
Leo Dion (host): That makes a lot of sense, especially in a big company.
Donny Wals (guest): Yeah
Leo Dion (host): to have human eyes on stuff.
Donny Wals (guest): Absolutely. And I actually read this study as [00:06:00] well where for that particular company that they examined an AI-assisted PR would sit in non-reviewed state, like waiting for review state, like two to three times longer than other PRs. People would be afraid to post feedback because that would essentially make them own that feedback. So it's "Oh, I don't agree with the architecture here." And they were afraid that whoever made the PR didn't fully support the architecture, so they'd be like, "Okay, well, tell me how to do it," or "Help me prompt the agent how to do it."
Donny Wals (guest): So they would suddenly become part owner of that PR. But then once they did run through the PRs that were made by humans and they had to start reviewing the AI PRs, they would spend less time reviewing the PR because of complexity, because of just the perceived, How did they put that?
Donny Wals (guest): They didn't perceive that the writer put so much effort in and so they weren't compelled to put in the [00:07:00] same effort that they would for a human-written PR.
Leo Dion (host): Interesting
Donny Wals (guest): yeah, it was quite interesting to read that, especially because I would've expected the review itself to take longer. But it seems like once, for that company, they would put themselves to actually reviewing it, they actually didn't really care about the PR so much, so they just approved it and "If there's a bug, we'll have the agent fix it 'cause it's all AI code anyway.
Donny Wals (guest): Who gives a crap?"
Leo Dion (host): Right.
Donny Wals (guest): quite interesting
Leo Dion (host): I mean, a few thoughts from me is shouldn't we be doing smaller PRs then so that way they're easier to manage and review?
Donny Wals (guest): Yeah. I mean, that probably helps 'cause the average PR made by an agent is larger than a human PR. I j- I just wonder, like, at what point... if you're, right, insistent on using agents for everything, and you've given it a task, and that task should, in theory, produce a manageable PR, I wonder how compelled people would be to look at the code the [00:08:00] agent made, see that it implemented the feature, it didn't refactor half the code base, so it's probably fine.
Donny Wals (guest): I'm not sure, like, how compelled people are to then be like, "Okay, this is kind of big. Let's split that up into per screen or per first the network call, then the UI," or however you might have done that as a person writing this. And that's also an interesting, I'm not even sure who said it or where I, where exa- I read this, but I didn't come up with this at least.
Donny Wals (guest): The beauty of a human writing code is that the human at some point goes, "Wait, should I be doing this?"
Leo Dion (host): Yeah.
Donny Wals (guest): An agent doesn't do that. An agent just goes. "I have a task, I'm gonna go do it." Whereas as a human, at-- when you're working on something, at some point you just kind of feel like the vibes are not there.
Donny Wals (guest): You're coding, it's this feels like too much work. This feels like it's getting out of hand. This feels like it wasn't scoped properly." And you stop working, and you go back to your manager or whatever, and you go "Okay, maybe this ticket needs to be two or three tickets. I can work on them in parallel, but we're gonna make [00:09:00] three PRs out of this because it's too much otherwise."
Leo Dion (host): The way okay, like I don't know how you've been doing Maxine, but like the way I've been doing stuff is kind of like I'll have a main branch, I'll have the version I'm releasing, and then I'll have features, and if those features need to be split up, I'll split those up. And then like basically everything I ever tell Claude to do is its own PR, and that way it's all manageable and easy for me to look at the PR, be like...
Leo Dion (host): and quite frankly, like I think one of the things we're afraid of but we shouldn't be s- we shouldn't be especially now, is ripping out code that is excessive. I forgot which library I had been working on, but I just wanted something simple and it gave me like fallback retries, networking caching, all this crap that was just like maybe it works, maybe it doesn't, but it's crap I have to maintain and I have to be responsible for.
Leo Dion (host): And it's like we should be [00:10:00] okay with saying no to too much code from a
Leo Dion (host): agent
Donny Wals (guest): Yeah I totally agree with that. I've been dealing with that myself in two ways. One is I do the same thing you do. Ev-every prompt basically becomes a PR. Maybe there's a follow-up prompt to clean something up, but generally speaking, one task is one PR. I have agents working in worktrees so I can have multiple in parallel.
Donny Wals (guest): And then before I tell it to make a PR, I always tell it to do a review where it will scrutinize every line of code that it added as is this absolutely necessary to achieve the goal? And basically encouraging it to do the same result with less code. I always ask it like, "Is there anything in there for backwards compatibility?
Donny Wals (guest): If so, rip it out because you're building a new feature. Don't be
Leo Dion (host): Yeah. Oh my gosh, I get that a lot. I've got libraries that are in beta and it's "Oh, you sure this is okay?" No, I don't care.
Donny Wals (guest): Exactly. So it's and sometimes I have to point it to compare this to main because we're like five commits deep and like maybe multiple [00:11:00] PRs stacked on top of each other. So it's "Oh, but you already had this feature and we're changing it now, so maybe it's not a user." But it's "No, compare it to main.
Donny Wals (guest): If it's not on main, it doesn't exist, and you're fine to break everything and anything you want. If there's anything I want preserved, I will let you know."
Leo Dion (host): Have you tried to put any of this guidance in a Claude MD or Agents MD file?
Donny Wals (guest): It's in the agents file. I find that most of the time it works okay. The problem is that it becomes like a blanket thing, where if I do want backwards compatibility, I have to be explicit about it. So I'm always trying to balance, like, how annoying is it to pull it back on this, and how annoying is it if it's too strict with this rule?
Donny Wals (guest): Or if... Right? So th- that's a trade-off that I always have to that I'm always trying to make.
Leo Dion (host): What kind of, So let's take one step back. What are you using now for your Nginx coding, and what are you using as far as p- managing PRs, reviewing PRs, et cetera?
Donny Wals (guest): So I'm using Cursor. It's [00:12:00] one that I started using early on. I've always liked it. I like that it allows me to switch models really easily and not just the two big players, but any model. And actually Composer, which is Cursor's own model is pretty good nowadays.
Donny Wals (guest): It's all I need. And it's super cheap compared to the API usage for ChatGPT or or
Leo Dion (host): How much is it?
Donny Wals (guest): I mean, the plan itself is really expensive. I'm on a $200 plan, but I never run out of tokens. On a $20 one I used to run out of tokens, but I haven't tried it with only Composer, 'cause Cursor subsidizes usage with their own model, obviously,
Leo Dion (host): Yeah.
Donny Wals (guest): Heavily.
Donny Wals (guest): If you use ChatGPT through Cursor, it's quite expensive because you're paying API pricing.
Leo Dion (host): Yep
Donny Wals (guest): So it's a bit of a trade-off but it's been working really well for me. I've been using it for, I think, exclusively for six months now. And for my PRs I'm still just reviewing them on GitHub. I am somewhat changing the way I look at the code.
Donny Wals (guest): I mainly kinda spot check it for [00:13:00] is this what I would expect versus is this what I would have written myself? Which has not always been great. I mainly do this on Magazine, by the way. On client work I'm still a lot more scrutinizing, but Magazine is my playground essentially, where I just wanna see how far I can push this.
Donny Wals (guest): So just it's different ways of working. Basically Magazine is almost like... I've almost blind merged PRs but I'm still not confident enough to do that, 'cause almost every time there's a subtle bug
Leo Dion (host): Let me ask you a question. What APIs im- so you're pretty good with I don't know, Swift data. You've written books about core data. You've written books about certain libraries that involve reacting to information which we won't c- name. W- you've, you're quite experienced in certain APIs and not experienced in some.
Leo Dion (host): When it comes to Maxine's work, are there particular areas where "Yeah, I don't really know how this works, and I'm just gonna let Cursor have its
Donny Wals (guest): Oh, yeah. [00:14:00] I would say half the
Leo Dion (host): an example?
Donny Wals (guest): so I had never done a watch app before and so I basically just told it "Make me a watch app. Here's what it needs to do." And like it did a decent job of setting up, like, all the essentials, mainly communicating with the phone. 'Cause like I was reading it.
Donny Wals (guest): I was looking at the sample. I was like, "Okay, this is a lot of work.
Leo Dion (host): Did you try my library for watch communication?
Donny Wals (guest): I did not, no.
Leo Dion (host): Okay, we'll talk about Sundial K afterwards.
Donny Wals (guest): We'll talk about that. I might wanna integrate that. But like I just told it like, "Hey, make me this. It needs to communicate that." And it just gave me a bunch of code. And I think the main part that I went back and forth with was, like, how do we communicate data, right?
Donny Wals (guest): Do we use structs? Do we just send Swift data objects? Do we send encoded messages that aren't that are strings or whatever? It came up with a bunch of ideas, and we [00:15:00] ended up deciding that structs was the way to go. So the only place that touches my actual database is the phone the watch, live activities, widgets, app intents, they all talk to snapshots.
Donny Wals (guest): So bas- every time the user does a workout, I generate a snapshot of it that exists on the file system only the parts that would be needed by other parts. And if, for example, an app intent wants to communicate back to the watch or to the phone it will make a snapshot, same for the watch.
Donny Wals (guest): It will send a specific message to the phone app. The phone app then processes it, updates the database, and sends information back to the watch. The watch updates its UI.
Leo Dion (host): Okay
Donny Wals (guest): And look, I had never done that before. I figured it would be a lot of work, and I wanted it fast so that I could start testing.
Donny Wals (guest): And it's I think it took four hours for me to have it on my watch, on my phone, and to go to the gym and actually have a first version to test.
Leo Dion (host): Yeah. Tell the story you had about the app crashing mid-workout, 'cause that was pretty good[00:16:00]
Donny Wals (guest): Oh, yeah. That's a nice thing about Cursor also is that they have a web interface, right? That sort of was a reason that I liked it so much as well. And as I was testing the... I don't remember which particular feature I was testing, but I was testing the app, and I did something, and it crashed.
Donny Wals (guest): And I tried it again, and I could get it to crash a second time. Okay, perfect. I have reproduction steps. So I just went to cursor.com, fired off an agent. I, in detail, described what I did in the app and that it crashed. And luckily, I was on a TestFlight build, so as I was typing that, I got an email from TestFlight saying a user submitted feedback.
Donny Wals (guest): So I had a crash report, and I just copied that over, attached it to my prompt and was like, "Here's everything that I did. Here's the crash report. Go figure it out." And the funny thing is that Cursor runs on Linux, so it wasn't able to build my iOS app. So it basically just completely went by vibes.
Donny Wals (guest): It was just like, "Okay, here's what the user told me. Here's probably what went [00:17:00] wrong." And I got back home, and a PR was sitting there waiting for me. Bitrise had run, had ran a build. It had ran my tests. It was all green. It was all good. And all I needed to do was install it on my device, check that the crash was resolved, and it actually worked.
Donny Wals (guest): There were a few minor nitpicks that I wanted to fix in the code, but yeah, it was pretty good. Especially because it was so in the moment no thinking of "Oh, what did I do exactly?" No first writing a crash report on my phone and then forgetting it when I got home. I have that all the time, right?
Donny Wals (guest): I write something down in a note. I go home after the gym. Kids are there. Kids need to be picked up, whatever, and I forget all about that note until I've found my next bug in the gym. I say, "Oh, crap, I forgot about that one thing." So sending it immediately to an agent and having a PR to review was... Yeah, that was really a very cool moment for me to, to, "Okay, so here's how we could be working on some of these things."
Leo Dion (host): Do they have Swift? So [00:18:00] Cursor has you can run stuff on the web. Can it run Swift?
Donny Wals (guest): I think it should be able to install and run Swift. You can build your own containers. So if I had made all of this into
Leo Dion (host): Cl- Claude Code doesn't have that, so you can't even run Swift. So I am one who has also on occasion coded on my phone by going into the Claude app and telling it to create a PR for something I just remembered. So I totally get it, but like every time I've tried to get Swift to work, it's "No, we can't install Swift on this server."
Leo Dion (host): It's or you can't do like a Docker container. It's pretty limited right now
Donny Wals (guest): Yeah. I think Cursor does allow you to configure containers, but they launched an iOS app two or three days ago, and I haven't tried it yet, but the app can actually connect to your computer, and then you can run agents on your computer which is really nice. I've been running a setup with a Mac Mini for basically just to try it, where I can just SSH into my Mac Mini at home, and then [00:19:00] instead of using the Cursor website, I can just fire up a Cursor agent on the Mac Mini I have at home.
Donny Wals (guest): Which is also quite nice 'cause then I have the simulator and, Actually, just last weekend, I was at a festival and they didn't have offline access for their timetable thing, and the internet was, like, non-existent there. So when I got back to my hotel, I told Cursor on the Mac Mini to make me an app based on the website.
Donny Wals (guest): I just gave the URL for the timetable. And since I wouldn't be able to install it 'cause I was not with my MacBook at that time I did have it close, but I wasn't... I was at the breakfast thing so I told it that. I was like, "Okay, take these screenshots of every state of the app and put them on the GitHub README.
Donny Wals (guest): Make me a repo and everything. Put the screenshots there. Build me the app." And then basically just on those screenshots, I iterated for a bit. I was like, "Okay, this needs to change. That needs to change."
Leo Dion (host): Wait, th- where were you when you were doing this?
Donny Wals (guest): I was having [00:20:00] breakfast with my wife at the hotel. We were talking about how annoying it was that we couldn't do the timetable the day before.
Leo Dion (host): W- what did Mrs. Walls think about this?
Donny Wals (guest): She thought it was amazing. She was so happy because she was very annoyed at, like I was, with the lack of timetable at the venue itself. So we were just trying to figure out, like, how should this thing work, and just talking to the agent, and then we go back to the hotel room, plug in our phones, install the app, and we used it for the next two days.
Donny Wals (guest): It was amazing. And I haven't even seen the code. I didn't even check anything. Just as long as it worked, installed on my phone, solved my problem, I was happy with it
Leo Dion (host): Yeah. Yeah I have a few Mac Minis. I need to do that and take advantage of that. I haven't gotten to that part yet, but that makes total sense. I wanted to hop back and talk about architecture. Is there anything you're changing as far as your architecture and your... let's talk Maxine, but also let's talk your other jobby-job stuff.
Leo Dion (host): Is there a way you're changing the way you're architecting your apps in any way?
Donny Wals (guest): Not [00:21:00] necessarily. I'm mostly less concerned about repetitive code and boring stuff. Like when I would write code by hand, I would be writing the same kind of thing like over and over, and it's 99% the same, but it's slightly different. I would start thinking about like, how do I abstract that?
Donny Wals (guest): Like, how do I make it so that I don't have to repeat this little dance every single time? And I think more often than not, that would actually lead to like clever code where it's like it it's 99% the same, so you still have to account for the differences, but most things are the same, so you can come up with something with generics and do smart stuff.
Donny Wals (guest): And,
Leo Dion (host): Ah, I get it
Donny Wals (guest): almost always that sort of bites you in the end. And I do like that when I tell an agent to do the boring thing, it will just do it. And yes, there is some repetitive pieces of code, but it's repetitive not because it's doing the same thing every single time. It's just repetitive because that's just the way [00:22:00] it is.
Leo Dion (host): I think that's one of those over optimization things that developers do. We hear don't repeat yourself, the DRY method. And we like I think it's been overdone because like I think until you g- have like several copies of something it's not worth refactoring into like you said, being clever with generics and protocols and
Donny Wals (guest): Yeah. And especially
Leo Dion (host): I was just gonna say, it also depends if you're coding for an app or coding for developers too
Donny Wals (guest): Yeah, absolutely. And it's also when, like, when something is the same because it's doing literally the exact same thing over and over again, or if it's the same just because it happens to do the same thing, if you know what I mean.
Leo Dion (host): Yep. I know exactly what
Donny Wals (guest): like d- decoding JSON, it feels so repetitive. It's the same thing over and over and every time you do it by hand, it's like it's screaming for an abstraction.
Donny Wals (guest): Whereas, like, when you're [00:23:00] done and six months go by, probably all of these objects will have diverged in subtle ways and they're not exactly the same. And so even though the initial writing was incredibly boring and repetitive, it wasn't like you did the same thing over and over again.
Donny Wals (guest): It's just it was kinda the same thing.
Leo Dion (host): Yep
Donny Wals (guest): so yeah. I like that an agent doesn't care about that. It'll just do whatever you told it to, and it doesn't care about abstractions. The downside, on the other hand, is that it doesn't realize when an abstraction would be a good idea. So for example, with Magazine, I have a lot of places where I show weights, and I convert from pounds to kilograms.
Donny Wals (guest): Actually, the other way around. I store everything in kilograms, and sometimes I present pounds for US folks. And,
Leo Dion (host): way. Anyways, go ahead
Donny Wals (guest): the wrong... Yeah. There's just a couple places where we have to show labels for things, and an AI will just happily reinvent the same helper or reinvent the same string interpolation every single time, [00:24:00] where I do have to tell it "Hey, look, you know what we really need?
Donny Wals (guest): We need a unified way to just ask the weight data object for a display weight and then use that everywhere instead of figuring out how to display it locally every single time."
Leo Dion (host): It seems I mean, you could have both issues with an agent where it over-abstracts as well, and I think the issue with repeating usually is just a simple context window issue of there's just so much code that it's like har- it's like difficult for it to even know that existing code already exists somewhere in your
Leo Dion (host): app. So yeah, that's usually the case with repeating code is like you need somewhere Claude MD or whatever that says, "Hey, if you ever need to do this is what you need to do," and save it in the memory somewhere.
Donny Wals (guest): Yes. I think you're touching on a really interesting point there as well, where it's possibly even more important than before to kind of know your way around the code base that you're working on. Because you... [00:25:00] The better you are at telling the agent examples of what you've done before, the better the output's going to be.
Donny Wals (guest): 'Cause if you just let it run freely, it might never discover that you've done the exact same thing mostly or solved the exact same problem before. And so it will come up with its own way to do it, and it might not be the right way. And then nudging it to do it the right way without telling it how it was done before is really frustrating.
Donny Wals (guest): So if you can just tell it "Hey, look at this file. We have helpers for all the weight stuff. If there's anything missing, add a new function using the exact same sort of API styling, and make sure that you never ever do inline conversion of weights." If you can add that to your agent file or to your prompt if it's not relevant enough for the entire file, then yeah, that's great, and it's going to do a much, much better job
Leo Dion (host): Isn't there like a measurements API that Apple provides?
Donny Wals (guest): There is,
Leo Dion (host): was it [00:26:00] using that or was it doing its own or what exactly was
Donny Wals (guest): So it's basically because I wasn't using measurements I started building this thing without knowing that it existed. So I just have a multiplier for kilograms to, to pounds and that's it. It's super
Leo Dion (host): that... Yeah, but we need that practical measurements book in the next year or two.
Donny Wals (guest): I guess so. I should probably
Leo Dion (host): It'd be like a pamphlet, but still, you know, it wouldn't be too bad
Donny Wals (guest): I mean, just knowing how to store stuff and how to normalize it in general is a really good idea. Like storing currency and stuff, I've seen so many people mess that up
Leo Dion (host): what are some tips you have for people who are just getting into Nginx coding? Like I say, like context window management is still, I think, important in some ways, I think. Yeah, just being able to document stuff properly so it knows how things work.
Leo Dion (host): What are some other tips you might have?
Donny Wals (guest): So just I just want to reiterate the documenting. Like having an agents [00:27:00] file or a claude.md or I think Gemini uses gemini.md or whatever your agent of choosing uses. Make sure you have one of those. It helps your agent navigate your code base, make sure that it contains the important parts.
Donny Wals (guest): Tell it, like, where to find certain things. And a nice trick that you can actually use is you can also nest them. So you can have an agents.md file at your root or a claude.md, and then if you have your folder structure, like for example, like your models, your networking, your UI, and then per, like in UI you have features.
Donny Wals (guest): Every folder can have its own agents.md or its own claude.md and
Leo Dion (host): also have a .Claude folder in the root, for instance, I don't know how the other ones do it, where you can provide even more general documentation to guide the agent
Donny Wals (guest): Exactly. A cursor has something similar as well. But just the fact that you can stack them and then do progressive disclosure is really useful, because that means that you can keep your root agents file relatively small, [00:28:00] and then the agent can just discover what it needs to find as it goes.
Donny Wals (guest): Great way to manage your context window. Also, I have a sort of file that my agent has to maintain on its own, which I call agent notes. So in my agent's file, I tell it that it must, for every correction that I make or every time I tell it to always or never do something, it must add a line to agent notes where it will teach itself what to do, and then it loads that as rules
Leo Dion (host): I like that a lot. Do
Donny Wals (guest): 'cause
Leo Dion (host): that file through the whole process? Do you ever, like, when you merge it, We'll, we can get into worktrees later, but then how do you deal with merge conflicts with that or
Donny Wals (guest): You keep everything. So everything it writes down is valid. So if there's a merge conflict, you just resolve it by keeping both changes, 'cause it never changes an existing line. It just, it's just, like appending.
Leo Dion (host): right,
Donny Wals (guest): so also like conflicts, I don't think I've ever had a, an actual conflict on it 'cause Git will figure out like nothing changed the same line, it's just everybody adding stuff.
Donny Wals (guest): But then every once in a while I look at [00:29:00] it and I go "Okay, so there's a bunch of stuff there," and I'll just tell the agent like, "Okay, find me like the general lessons in there. Find me the overarching rules and update your agent's file so
Leo Dion (host): Oh, I love
Donny Wals (guest): now matches that." And then ev- every month or so, like I end up with a clean agent notes and it's so much better than trying to remember because sometimes you have a session where you have to correct it like 10 times on the exact same thing and it feels so important to add to your agent's file, but it turns out it was just the agent having a bad day and it never again messes that one thing up.
Donny Wals (guest): And other times it feels like it's not such a big deal, but you've corrected the agent like 10 times over the course of a month and it was always like a small, tiny thing. But then you see like the same thing in the agent notes file or variations of it, and it's "Oh, hold on. I'm actually very often telling it to do something in a specific way.
Donny Wals (guest): So maybe we should, you know, make sure that we generalize a nice rule out of this so that it always does it the right way."
Leo Dion (host): So what, do you ever go through it [00:30:00] and clean it, not clean it up, but you know what I mean. Like 'cause it's just gonna grow continually. Do you ever like you just keep them all in there? Like it's gonna end up getting big pretty quick
Donny Wals (guest): Yeah so every once in a while I'll tell the agent to go through it and then update the agent's file. And in the beginning it got really big every single time. And as time goes on, it gets smarter about what I want and the way I
Leo Dion (host): Very good. Very clever
Donny Wals (guest): almost... Now it adds maybe two lines in a month. And almost always those are just one-time things where the agent was just having a bad day or sometimes even I look back at those and "Oh yeah, I was really not setting the agent up for success, I think, on that day."
Donny Wals (guest): I was just very vague and very changing my mind all the time trying to work with an 80% full context window. Of course you're gonna get bad results. And then I'll just delete those lines by myself. "Okay, fine. We don't want this." Another one that I use that's also like a self-learning thing is a skill called Grill with Docs.
Leo Dion (host): Okay
Donny Wals (guest): from a skill called Grill Me, and now it's Grill with [00:31:00] Docs. So what it does is every time you prompt it the Grill part of it is actually like really basic. It basically says, "Analyze what I say, scrutinize every part of it, keep asking questions until we mutually agree on what the feature actually is.
Donny Wals (guest): Do not make assumption. Ask a question for literally everything you want to do." And it's quite tedious in the beginning especially 'cause it'll ask you like the dumbest things. But in a way that it feels dumb to you, but at the same time it's okay, so you're going to assume that when I said move the button to the top, you assumed that you meant set Y to zero.
Donny Wals (guest): Which might not have been true if I flipped the coordinate system or I might have meant to move it to 20 points or whatever. So it'll ask "What do you mean by top? What do you mean by this?" And so when it was just a Grill Me doc, it would do that every single time. Now, the guy that wrote it introduced a new skill called Grill with Docs, and that looks for a file called context.md.
Donny Wals (guest): And as it asks these questions, it will find [00:32:00] out like what is the specific terminology that you use for your app? What is the specific way that you refer to things in your natural language? What is it-- what are certain-- What's the main color in your app? When you say, "Use the main color," it has to go and find a variable called main color every time.
Donny Wals (guest): So when it finds things like that, it goes "Okay, let's add that to context.md." And so context.md then becomes part of what Grill with Docs loads as it starts deciding what the feature is. And as time goes by, it becomes smarter and smarter, and it understands you and your app and your field of business much better.
Donny Wals (guest): And so I use that paired with Plan Mode. So basically it's like I go to Plan Mode in Cursor, I use Grill with Docs, I tell it what I want, I get a bunch of questions. And sometimes it's really smart about it. It's just the other day I told it when I finished the last set on my watch and I log the set and I have nothing else to log in my plan, it will suggest me to [00:33:00] end the workout.
Donny Wals (guest): I don't want that. I want it to allow me to add another set. And then it was like, "You know what? You actually have this flow throughout the watch where you planned three sets of an exercise, you press next, next, next, and then you go into the next exercise immediately. Don't you want a step there as well so that you can add another set?"
Donny Wals (guest): It's "Wow, I didn't actually think of that," 'cause it never annoyed me, but you're absolutely right. So that's... Yeah it's for those kinds of things it's really good 'cause it... it becomes that annoying developer in the sprint planning that asks a question for every single sentence in a ticket.
Donny Wals (guest): But in the end, they're the ones that ship without no bugs. They're the ones that just ship exactly what was meant be, to be shipped because they didn't assume anything. And 90% of the time the assumption is correct, right? So the grill scale basically tells you "I would recommend you do this," or, "I would assume this."
Donny Wals (guest): It's "Yep,
Leo Dion (host): yeah.
Donny Wals (guest): But every once in a while it's like, "Oh, hold up. That's a good idea," or, "I didn't think of that," or, "That's not what I meant," or, [00:34:00] "That's gonna break something." So highly recommend that
Leo Dion (host): You were just talking about sprints and stuff. What are you using for managing tasks or issues or sprints and stuff? Especially when it comes to Maxine
Donny Wals (guest): oh I went through a whole cycle with that. So I first set up GitHub projects, right? Where I made tickets every time. The problem was it was a lot of friction for me to make tickets because it's the kind of app where I can test it at my desk for hours and hours, but I have no idea how it works until I actually go to the gym and try to use it.
Donny Wals (guest): So I, I have to go out and use it to actually know does this truly work? Does this feel right? Does this look right in the context of, you know, me being sweaty, me being busy? So every time I found an issue, I would have to go to GitHub, which on my phone, I don't know. The app's fine, but I don't like trying to navigate GitHub issues on my phone.
Donny Wals (guest): It feels like too much effort, especially if you want to write down a quick line of something you didn't like.
Leo Dion (host): Yeah, 100%.
Donny Wals (guest): So I had that. I was like, "Okay, that might be [00:35:00] overkill, the project set up," 'cause like it... I was reluctant to write things down. I would just write down in my notes app.
Donny Wals (guest): Okay they'll just copy it over later, which I never did. Then I went to Notion, which I still use every once in a while. I was like, "Maybe Notion is a bit more lightweight." It was pretty much the same thing as GitHub, like just as annoying. Also, the Notion mobile app isn't that great in my experience.
Donny Wals (guest): It's fine, but it's not good for doing like ticket-based stuff.
Leo Dion (host): Great
Donny Wals (guest): Then I decided that note list that I had, like just Arraycast note, was fine. So it's just everything I wanna do is a line in that notes thing. And when I do it, I just remove it. And basically what I try to do is if I write down a problem now as I'm working out, I either just feed it to an agent directly and I don't even make a note, or if it's more of a feature I want to think through, I start writing a prompt that I would give to an agent.
Donny Wals (guest): And it becomes like this whole couple sentences [00:36:00] on what I have in mind. And then I go back to it when I'm at my desk. And that's kind of it. I don't really have a ticket system or an issue tracker.
Leo Dion (host): There's task tools out there, like Task Manager and SpecKit and stuff, and I always have just been going back to just doing GitHub issues rather... 'Cause I don't like the idea of keeping a bunch of markdown files for every single issue and doing that as far as like planning things out.
Leo Dion (host): And then, yeah, I just use milestones and GitHub issues as far as that's concerned, and then make sure that Claude knows how to use the GitHub CLI so it can just create the issue for me every time. And then whenever I have time to go back to it, I will
Donny Wals (guest): Yeah. Yeah, I mean, that works. I use it on other projects. It's just for this particular one because in most of my bug filing and reporting and coming up with features happens in the gym. It's for some reason Notes app just works best
Leo Dion (host): that makes a lot of sense. Yeah. One thing I wanted to mention before we [00:37:00] switch topics that you kind of went into is with a lot of this stuff, you can use these tools to help you with this stuff. So if you're like, "Hey I need a prompt," you know, it can write the prompt for you and you can help write the prompt.
Leo Dion (host): If you need help creating your agents file, your context file, in a lot of these cases, the, these tools can help you with those items, I guess is what I'm trying to say. And yeah, like it'll be freely like, "Yeah, we can edit your agents.md so we know about this context file," or whatever it is.
Leo Dion (host): It's usually pretty good about that
Donny Wals (guest): Absolutely, yeah. I use it a lot for those kinds of things
Leo Dion (host): Before we close out let's talk about APIs, dub. Where do you think Core Data, Swift Data, where are you at with that right now?
Donny Wals (guest): So Maxine is all Swift data and I'm not hating it. Mainly because... I wasn't expecting to [00:38:00] hate it at all because it's a pretty simple app database-wise. No multithreading, no multiple axes, no iCloud sync. Just, you know, it's just on a phone, local database, model changes every once in a while.
Donny Wals (guest): Migrations work fine. A couple things that are a little bit annoying around migrations, but once you know how they work it's not that big of a deal. Mainly, like, when you want to remove a property from a model and then move it to some other entity. Pretty vague, I know. So what I wanted to do at some point I had an integer, like three integers somewhere on an object, and I wanted to make those three integers parts of a new entity, and then the old entity didn't have the three numbers anymore, just one field that pointed to
Leo Dion (host): This is migration stuff? Okay.
Donny Wals (guest): And Swift data cannot do that in one pass, so you need two model versions, one to copy, and then the other one to remove the old property. In Core Data, I could do that in one pass. So [00:39:00] when I ran into that, it was really annoying 'cause I was like, ~"How do I do this? ~How do I do this? I cannot do this.
Donny Wals (guest): Okay, fine, two model versions it is." Turns out
Leo Dion (host): Or they should...
Donny Wals (guest): the way I had to do it
Leo Dion (host): Yeah, you think they'd have a tempor- like I, I don't know if you were a SQL person, but there's always the idea of a temporary table. Like you'd think there'd be a way to script something like that up
Donny Wals (guest): Yep. Yeah, and Cordata does that, right? Cordata gives you old context and new context, so you can query anything you had in your old database, and you can query anything you have in your new one, and you can link stuff together. SwiftData gives you old context and new context but not in the same function, so not in the same pass.
Donny Wals (guest): And because it spins up a new container for each you cannot go "Okay, so I want this object by object identifier," because in the new database it doesn't exist, 'cause it's changing that stuff. I don't know exactly how it works, but you cannot get old objects into the new database,
Leo Dion (host): Would you be like, "Yeah, SwiftData all the way, all the time"? Or where would you think SwiftData just, where are the rough edges right [00:40:00] now?
Donny Wals (guest): I think mainly when you want to have sharing support from NSPersistentCloudKitContainer. That doesn't exist in SwiftData. I would say if you need advanced compound predicates and everything, which I think iOS 27 will have. So that's quite nice, but at the same time, it's iOS 27 plus, so quite older iOS versions won't have it, so you're gonna have to probably figure out a way to use Core Data anyway.
Donny Wals (guest): I would say in a heavily multi-threaded environment as well, where you want to make use of scratch contexts make sure that things run in the background. I found that you can do it with SwiftData. It's... And I haven't been bitten by it yet, but I feel like SwiftData's model relies on trust a lot in the sense that you can pass your models to any thread, and the Core Data thread checker isn't going to fail on them.
Leo Dion (host): Okay
Donny Wals (guest): But I'm [00:41:00] not exactly sure that your models are fully threat safe and sendable, and it all gets a little bit like, it should work. I've been told that it should work. It's just Core Data has given me a lot of trust issues around these things. Like whenever they would say "With Core Data, just trust us, it'll work."
Donny Wals (guest): It's i'm gonna,
Leo Dion (host): You're saying core data you trust less or Swift
Leo Dion (host): data
Donny Wals (guest): I would say, so I don't trust either, but in Core Data I have a way to take control
Leo Dion (host): Okay.
Donny Wals (guest): that I know what I'm doing. Swift Data, on the other hand they're like, "Oh, no this should work fine. This should be managed in a model container."
Donny Wals (guest): Core Data has this annoying problem if you have a widget and an app, and they both operate on the same SQLite store, that you can easily get crashes when both want to write or both want to read, 'cause there's only supposed to be one connection active. Swift Data says you can do that now.
Leo Dion (host): Okay.
Donny Wals (guest): I don't trust that
Leo Dion (host): Yeah, I agree
Donny Wals (guest): because I have trust issues. There-- [00:42:00] I haven't had actual problems, but I have trust issues, right? Core Data bit me too many times with those kinds of things. And it's also in Swift Data, there's bits and pieces scattered out there on, like, how it should work, but there's no official guidance, especially on complex topics, where you're like I
Leo Dion (host): Would you go like a, with a SQLite type or SQLite adjacent library instead? Or what's your position now?
Leo Dion (host): So like in my case, I don't want to keep going with SwiftData in my apps. I actually would want to migrate away from it w- especially with Bushel. But maybe, like there's a couple of apps which are, they're fairly simple where SwiftData would make more sense, but I'm not like super happy with SwiftData and how it works.
Leo Dion (host): It's very SwiftUI tied and not like database tied, I guess. I don't know how to put it,
Donny Wals (guest): yeah I get that. It's definitely a UI abstraction over SwiftData in some way, o- over [00:43:00] SQLite in many ways. I... Especially for a magazine, I don't hate it to the point where I would want to switch off of it. Do you know what I mean? It's fine. It's not causing me any problems.
Donny Wals (guest): I don't have any performance issues with it.
Leo Dion (host): Benefits to using Core Data with an app like Magazine either,
Donny Wals (guest): There's also no benefits to switching to something like GRDB. I did try GRDB in the beginning. Interestingly, 'cause everybody told me like, "Oh, it's so much easier." Interestingly enough, I found it so much harder
Leo Dion (host): Okay.
Donny Wals (guest): than SwiftData and Core Data, maybe because I've been using both of those for such a long time that using something else to me felt like, "Oh why do I have to relearn database?"
Donny Wals (guest): I know how to do
Leo Dion (host): my chief experience is with Fluent, which is the server side Swift library, and I'm used to that. So there was some adjustment to be made when I switched over to SwiftData, and I haven't done Core Data in at least a decade, so yeah
Donny Wals (guest): Oh, yeah. [00:44:00] Yeah, I can imagine if you were to come from a more, let's say ORM style thing to SwiftData, which is like its own... it's not, I guess it's not technically an ORM. I think Core Data was pitched as like a graph management tool or something
Leo Dion (host): right. It's like a abstraction layer. Yeah, I get it.
Donny Wals (guest): Yeah.
Leo Dion (host): Yeah
Donny Wals (guest): I can totally see like how that would be
Leo Dion (host): Annoying?
Donny Wals (guest): To deal with when you're used to a certain level of control and certain level of doing things
Leo Dion (host): Before we close out, I guess this is the second time I've said that maybe, but I could, I, What's next for Donny? What kind of books should we expect, if any, in the next couple of years? And has there... And additionally I'm gonna ask, was there anything out of Dub that you were like, "I wanna write a book about that," or something that really caught your attention?
Donny Wals (guest): So I don't know. I started working on a Swift data book, which I think I'm, I might not [00:45:00] finish, I might finish. I have no idea right now where I'm at with that. So whether I'm gonna do more books I really don't know at this point. I think for me to do more books, the concurrency book has to pick up again 'cause that was in demand a lot.
Donny Wals (guest): And then somewhere in the last quarter of 2025, that sort of just took a nosedive,
Leo Dion (host): Wow. Okay
Donny Wals (guest): which very clearly says to me people are not interested in learning the details of how this works. They want their agents to know the details, and there are skills out there that people can use. And I th- I do feel like eventually people will come back from that because they have no idea what the agent is doing.
Donny Wals (guest): Concurrency is really hard. Even with skills, it might still make poor decisions because of, probably because the user doing a poor job explaining what they want. So yeah, maybe we'll come back to that. So I have no idea. In terms of what's next, I'm still very heavily thinking what do I do next?[00:46:00]
Donny Wals (guest): I am dabbling in indie apps shipping my own stuff, which I chose the hardest niche to get into, I think, which is health and fitness. But it's fun. I'm liking it a lot. So yeah, that's good. Maybe other apps, maybe other ideas will come at some point. I have no idea. YouTube, I do want to pick that up again.
Donny Wals (guest): I've been putting that on hold as well while I figure out what am I gonna do exactly content-wise.
Leo Dion (host): Mm-hmm
Donny Wals (guest): I'm leaning more towards maybe a live stream format where just co-working or more workflow, higher level stuff, like not tutorials, not here's how to do X or not here's how I like to do this this UI part or how I architect this.
Donny Wals (guest): But a lot more high level, like how do I work with agents? Like how do I manage context windows? How do I describe architecture? How do I review code? How do I recognize when my agent's going after rails? Those kinds of things. But I have [00:47:00] no
Leo Dion (host): like off the rails, like it's going crazy, not Ruby, right?
Donny Wals (guest): Yeah. Like how do I recognize that I should probably stop the agent mid-task? 'Cause like you can just leave it running and sometimes... I do still think there's a ton of value in deeply understanding what the agent is doing in terms of how should the code look and
Leo Dion (host): There was a way in Claude Code where you could have it tell you what it's thinking while it does something, and I don't know if they got rid of it or it's no longer there. I need to re-enable it because it's really helpful
Donny Wals (guest): I've, used that many times. I've had that when You have your plan. Plan mode is great. Everything looks fine. The files, it lists it. It looks good. Then it starts doing the work and it's "Oh, we need to remove the old model version because there's a new model version."
Donny Wals (guest): No, don't remove anything. Don't do that. Do not remove anything. You're making new model versions. Model versions are additive, not destructive. And if I had let that run, it could've spent like 30 minutes to an hour doing work, [00:48:00] and then I come back, it's why does nothing work anymore?"
Leo Dion (host): Right, right. Yeah, thinking mode is what it's called. So yeah. Well, Donnie let's do this again before the AI apocalypse or AI bubble. One or the other, we'll see. We'll flip a coin and we'll
Leo Dion (host): see which way it
Donny Wals (guest): something will happen
Leo Dion (host): where can people find you online?
Donny Wals (guest): On X, Donny Walls. On, I think Mastodon also Donny Walls. On all the social networks, just find Donny Walls. And if you cannot find me by Donny Walls, find me by Donny Walls Dev, which I think is what I had to use on Instagram because somebody stole Donny Walls, and they're not even a Donny Walls
Leo Dion (host): what does that Donny Walls do? Do you
Donny Wals (guest): steal my stuff.
Leo Dion (host): Oh, man.
Donny Wals (guest): Like literally it's I tried many times. No so what they did is they posted like some weird picture, then three pictures that they stole on my page, and then one other picture, and then they haven't posted for six or seven years. And every once in a while write to [00:49:00] Instagram yeah, I write them like, "Hey, that's my name.
Donny Wals (guest): That's my photos." And they ended up taking down my photos, but they're like, "Yeah, well nothing we can do about them using your name."
Leo Dion (host): What?
Donny Wals (guest): was like, "Okay." They're not even using the account. Like it, it sucks. Yeah.
Leo Dion (host): Thank you again for coming on the show. It was fantastic.
Donny Wals (guest): for having me
Leo Dion (host): people can find me online @leogdion, @leogdion.c.im on Mastodon YouTube, we're at BrightDigit is the name of the channel. If you're watching this on YouTube, and subscribe, and also and subscribe to Donnie's channel too.
Leo Dion (host): If you're on a podcast player, please go ahead and post a review. I'd really appreciate it. Oh, one more thing. I have a newsletter again. Yay. I'm gonna post a link to the newsletter. I finally m- moved from MailChimp to Buttondown, and it's a lot nicer definitely check that out. And check out the Patreon.
Leo Dion (host): Thank you to Patreon supporters like Steve Lipton for helping [00:50:00] support the show. Oh, right. So I'm gonna be installing Windows and learning about Windows. I haven't touched Windows in over 12 years. So if you have any questions for Selim, the I don't know, founder, principal motivator of Swift for Windows drop me a line and let me know what you want me to ask him, 'cause he'll be in the next episode.
Leo Dion (host): We'll be talking about that story. Thank you again, and I look forward to talking to you again. Bye, everybody.
Donny Wals (guest): See ya