kwikkEmail 1.0.3 live in the App Store

I occupy my time with writing and releasing software. The latest — kwikkEmail 1.0.3 — just went live in the App Store.

Thank you for your support.

PracticeDeck 1.1.2 released

One of my iPhone apps, DR Performance Practice Deck for iOS version 1.1.2, is now available in the App Store.

Just a minor bug fix update, but an update nonetheless.

Thank you for your support.


I’m trying to emerge from one of the worst burnouts that I can remember.

It happens. It’s the nature of the business I’m in… and I think it’s also the nature of me.

I try to live a balanced life, but by the time I figure out how to balance things, there’s something new in the mix that imbalances everything. And I have enough drive and dedication to things that sometimes I push too much, and it’s… well… too much.

I think to some extent I just have to accept that this is me and how I run. It does better sometimes to go with the flow instead of fighting the current.

It finally came to a head a couple weeks ago. I just cracked. Was really short-fused and couldn’t focus on anything. No motivation for work or other stuff. I made a long Labor Day weekend, taking 5 days to do nothing. And while I did some stuff, the main focus was on sleeping and eating. I slept a lot. Heck, I woke up on Sunday after about 9 hours of sleep, ate breakfast, then went back to bed for another 2 hours. I then took another nap later in the day. Yes, everything was shot. In fact, I think if I could take another week off of “life” I’d come out in really good shape.

As it is, I feel a lot better. And one thing that is most significant that I didn’t realize was an issue? I don’t feel stiff and creeky. I figured it was just being beat up from the weights. I do think it was that, but it was… silly. Trying to just kneel down then get back up? It was a chore. OK so squatting 295×2 isn’t huge numbers, but if I can squat more than my bodyweight, why is it difficult to kneel down and get back up? I guess because I was so shot. After all this time resting, I don’t feel stiff and creeky any more. I can just squat down, kneel down, get up, and it’s no problem.


But it taught me a lot, and gave me a lot of signs to look for in the future. Catch it before it gets bad, because a lot of these signs are new signs.

Sleep is key. I need more of it.

But food is another.

Trying to diet down, seeing how it hurt me, running counter to my true goals. I also believe the restriction on food contributed to things because I didn’t have what I needed to build myself back up. I’ve learned over the years to listen to my body. Sometimes I’ll get a massive craving for something, like fruit. Listen to it. Eat until body says that’s enough. and it’s never really a want to pig out and gorge. There’s a limit and eventually the body says it’s good.

As much as I hate to keep the belly flab, I think I need to just keep eating more. It makes sense. But I do think along with listening to my body more, I can do things to be cleaner and, if I stick to things more long-term, it should work out alright for me. I’ll get there, but it will take time.. perhaps a lot of time.

I’m going to eat well, 250g of protein a day I think is minimal, don’t sweat the fat (tho don’t be stupid about it), and moderate the carbs. For example, if I have a piece of whole fruit with breakfast, fine. But that’s probably all I need. If I can have a carbless lunch, great. Then if Wife makes something for dinner that has some carbs in it (e.g. rice), just roll with it. If I have a scoop of ice cream before bed, fine, just don’t do it every night. I think all the “artificial” program following I’ve done has been good because it’s taught me a lot and shown me a lot; learned a lot about my body. I’m finding my groove, and right now, it’s a shit-ton of protein and moderate everything else… where my body is nourished to the level it needs, and it will tell me.

So, to anyone I’ve ignored or snapped at in the past some weeks (or months), I apologize. I let a lot fall by the wayside because I was burned out but had to keep chugging on key things (e.g. day job). I was tapped out and didn’t see the signs, because a lot of them are new ones. There are no excuses, just asking your forgiveness and thanking you for your patience.


If you could give me one piece of advice…

…about running a small business, what would it be?

I know other small-business-owners and entrepreneurs read my blog. So if there is one thing you can share with me from your experience, please do.

A lesson learned.

A mistake made (and how to not repeat it).

A wise principle.

A guiding concept.

Whatever it might be, towards helping one achieve success.

For example, Michael Lazerow says the #1 mistake entrepreneurs make?


Successful entrepreneurs focus exclusively on efforts that matter and are able to tune out the rest. People who focus succeed. It’s that simple.

So, what can you teach me? I’m ready to listen. Please add a comment.

Commitments and Priorities

I saw the above image posted to the DangerouslyHardcore Facebook page. In case the image goes away it says:

Commitment means staying loyal to what you said you were going to do long after the mood you said it in has left you.

Very true.

I’ve had a bunch of things rolling in my head for a while, and seeing the above image/text along with something that happened in Wife’s life a few days ago… it changed my priorities regarding my commitments.

I had committed to being more involved in shooting competitions, like IDPA. That’s going down the priority ladder.

I had committed to working on a new iPhone app. This commitment was made some time ago, work started, but has been treading water for too many months. This is going up the priority ladder.

I only have so much time and energy. The app went down the ladder because after staring at the computer all day and busting my ass all week for the day job, I just didn’t have the desire to look at the computer any more. I was (am) drained. Other things went up the priority ladder because they were not-computer things. They gave me something else to do, something else to occupy my mind and energy. Plus they were things that needed attention.

Well… the lack of app commitment also strikes a little closer because this particular app project is very personal. It’s something I’m doing with Wife, and it means a lot to her. That I haven’t been able to give it the attention it’s due is not right, and I feel horrible. It’d be one thing to not honor the commitment to myself, or to anyone else. But to not honor this commitment to my wife? That’s not right, and that hurts me deeply. It wasn’t not honored out of malice or anything bad, just exhaustion. I need to do something about it.

And in some regard, the mood for the app has left me. It’s mostly because I’ve been away, had too many false restarts, and it’s just hard to get motivated yet yet yet again. But I know once I truly get back into it, I’ll roll along alright. I need to rediscover my commitment, and see it through.

So, since much of my “free time” is on the weekends, that means I need to spend it working on this app.

That means shooting matches is out, for now. I don’t expect the app will take me all year to do, so I reckon later this year I should be able to make it out to matches. As well, so long as I keep dry firing at home and regularly shooting, like when I go out to KRT to teach, that’s alright. I mean, if I can run through a few magazines, run a few drills, assess state of things, then go home and dry fire to bring up the skill, then go back and shoot to measure progress, really, that’s OK. That will hold me for now. That I’m just shooting live at least once a month is well, about what shooting competition would be. Granted, there isn’t any of the pressure or environment, but this is the trade-off for now while I live up to my more important commitment. I just have to keep up with dry fire and ensuring I put at least a mag or two through the gun (for myself, with purpose) when I go out to teach.

I’m not abandoning my commitment to shooting competition, just changing course a bit. I have to, because Wife is more important. 🙂  And hopefully it brings other commitments back, like more regular dry fire and practice.

I can only look at this as a good thing, as long as I remain committed. 🙂

What we (programmers) want

I’ve poked at computers for decades… yes, I’m dating and aging myself.

And programming always appealed to me. I guess it’s been my craft, my calling. I’ve had opportunities to move into management, but I refuse because I know what I’m good at and what I love (and that I don’t like being a paper-pusher). For example, right now I’m working on one of the more challenging programming tasks I’ve dealt with in a very long time. It’s very complex, very complicated, very frustrating. But because it’s such a huge challenge (and will be a HUGE win when I pull it off), I’m happy to let it engulf me. Part of my poor sleep this past week has been due to Daylight Saving Time throwing me off, but also because the moment I wake up my brain churns on this problem because well… it’s just what I find exciting. Geek that I am.

Over my years, over my jobs, my bosses, my companies, the projects and groups… I’ve learned what I want and don’t want. Geeks do tick differently, and we aren’t satisfied by the same things a lot of other officer workers are. It’s welcome when the company and bosses get it, and frustrating when those that “run you” don’t get it. I don’t expect people to bend to my way of being, but I can say if you can understand folks better, you tend to get further.

This article by Michael O’Church about “What Programmers Want” is insightful and pretty spot-on about us.

If you have to manage geeks or interact with them, take the time to read it and gain some insight into us.

Or if you just want to understand us geeks a little better, it’s worth your time too.

Senior Engineer

John Allspaw writes “On Being a Senior Engineer“.

In my long career, I’ve met lots of people with the title “senior engineer”. We’d joke and call them “señior engineer” because it was all too often thrown around as some title of arrogance or tenure, but was about as meaningful as a “perfect attendance” award  — sure it’s great that you showed up and have been here a while, but that didn’t mean you knew anything.

Or were mature enough.

So with that, I’ve often cast off the title because it’s tended to be meaningless, maybe useful for business cards or at most on your résumé. But John’s article gives a perspective that the title is meaningful, if applied to someone who actually fits the role.

Of course for it to truly be meaningful, the title needs to be properly applied over the course of a career, not just because you’re the lone coder at some startup you and your other 20-something-year-old friends put together over beers one evening fresh out of college.

In the end, it’s just a title. It doesn’t really matter. But the merits and qualities of a senior engineer, as John lays out, are what really matters and what are worth striving to be.

More things I’ve learned about Jenkins

At the day job, I’m still working with Jenkins and our build system. I’ve written about some things I learned at the onset, and now I’d like to add some things I’ve learned since then.


Be mindful of them. There’s a great many out there that can help you solve things, but they seem to also bring much risk. For example, Jenkins was going belly-up at least a couple of times a day. I’d look in the system console and see some plugin that I wasn’t even using (just had installed) was somehow causing memory failures, throwing an exception, and Jenkins went stupid and had to be restarted. Once you figure out what plugins you need, uninstall every other plugin. Keep your system as minimal and tight as possible to avoid introducing risk or uncertainty.


I had to write a lot of custom scripts (some bash, a lot of ruby). These files I can keep in our version control system. But Jenkins files themselves are harder to do. Make sure you have a backup strategy. Make sure you run it often while you work. Working on a Mac and using Time Machine is useful… make a change, screw up, easy to revert.


Don’t apply an update unless the changelog shows it directly affects you. For example, the git plugin was just updated to fix a regression that prevented using env parameters in the branch name — I need that, so I upgraded that plugin. This goes back to the plugin issues I mentioned above… and if you screw up, it goes back to my backup issue I mention above. 🙂


Do your best to plan your jobs and pipeline. Figure out the abstract ideal that you want. Then figure what Jenkins can offer to get you there. You might find plugins, but you might also have to write your own scripts and other management.

Then, don’t be afraid to revise and revise again, even starting over if you have to.


I wanted to use a lot of plugins, because they’re supposed to make it easy, right? Well, it depends. The Xcode plugin is supposed to make it easier to do xcodebuild-based, builds. And in theory it does, but our needs are different and so I just have to get dirty with our own scripts.

The email-ext plugin is really cool, but I couldn’t get it to understand and bring in a bunch of env vars and do other bits of logic processing that we needed. So again, scripting to the rescue. Net::SMTP to the rescue.

CodeSign problems

I noticed from time to time that I’d start a build and eventually xcodebuild or ‘xcrun PackageApplication’ would fail:

“There are no valid public/private key pairs in the default keychain”

It seems this would happen after rebooting the machine (and Jenkins started up via the launchd stuff). I could manually use launchctl to unload then (re)load and things might be back to normal, but that’s annoying.

I found this post at, and adding the “SessionCreate = true” key/value to the launchd plist seems to do the trick.

But then further down things failed out. Despite the codesign command line tool being granted special Keychain access, it still hated life:

<path to build output app>: User interaction is not allowed.


So I found this and added a:

security unlock-keychain -p "" login.keychain

in the custom ruby script before invoking xcodebuild and PackageApplication.

BTW, I don’t have the passwords encoded into the script. Remember the use of the .netrc file? Use that.

Speaking of .netrc… it seems curl doesn’t like a .netrc where newlines separate entries… it wants everything on one line.

Passing Data to Downstream Jobs

Using Jenkins’ parameterized build mechanism, I was able to pass parameters around. I’d have the main build job, which would then use the promoted builds plugin to allow me to move the build through a pipeline, like to promote to QA, then promote to the App Store, or whatever. But there’s a lot of information from the main build job that I want the downstream jobs to have so the jobs can be properly named, emails can be properly formatted, version control tags set up, whatever. I found the easist way to do this was at the end of the main build job to use a little ruby scripting, create a Hash with all the things I cared to preserve, use YAML to preserve it to file, make sure the build job archived and fingerprinted that .yml file, and moved that “config.yml” file along with the rest of my archives and promotions. Then it’s simple enough to load and look up key/values out of the config.yml file in the later job scripts.

Tagging Git

One of the downstream jobs is a “deploy to the Apple app store” job. Certainly when we do that we want to tag our github-hosted repository with info about the build so we can know what was deployed. Trouble is, at that phase of the build pipeline we don’t have source code. So we can’t just “git tag” then “git push”. What to do? Use the github v3 API. In that config.yml file I was able to preserve the SHA hash of the code we used, so that’s all we need.

At first I thought to use the Tags API, but as I played with that it didn’t work. Even if I could create a tag, it wouldn’t show up in the Tags area of my git GUI app SourceTree. In fact, it started to give errors about refs. So I started to play with the References API and tried things like:

$ curl -XPOST --netrc \
-d '{"ref":"refs/tags/MyTestTag","sha":"be43262431c7a4b9db67a23d37f51e7901b9845c"}'

and lo… that seemed to work.

Is that enough? Is that correct? I don’t know. I’m not an expert on the low-level plumbing of git. I have contacted github support, but as of this writing have yet to hear back.

The Journey Continues

That’s all that I have for now.

It’s a lot of work to set up a build system, but it’s rather satisfying to do it. I still have a long ways to go. Right now we just have the basics for building and deploying to help our general workflow. It still needs lots of work for validations, testing, continuous integration, and other good stuff like that. One step at a time.

Setting up Jenkins… things I’ve learned so far

At the day job I’ve been tasked with setting up an automated build system. This is a Good Thing™ and I actually volunteered to do this task. I’m interested in doing what can help us make our code better, deliver our products faster, and make our lives easier in terms of automating things we don’t necessarily need to be involved in. So a Mac Mini was obtained to be a build machine, and I’ve been working to set things up.

I should note that I’m not a dedicated buildmeister. I know at larger companies they can have a person (or persons) whose full-time job is dealing with builds, but I’ve never been one of those people. I’ve done some build hacking in the past, but it was always homebrewed scripts and systems. This time around, let’s use an established system instead of homebrew.

It seems the modern hotness is Jenkins. Yes there are other options, but all signs via Google searching point to it. As well, it seemed (note the verb tense) like the more Mac-friendly solution. If nothing else, it had a nice Mac OS X installer. 🙂

I’m still far from having our complete build system, and I reckon as I learn more things on this list will change. But I’ve already learned a few useful things and I felt like sharing and adding to the greater knowledge-base out there that, through Google-Fu, helped me get this far. Maybe with my additions, someone else can be helped and maybe with a little less frustration and time sink.

The Project

A little context about the project being built.

Working on Mac OS X, developing iOS apps. Thus we’re using Mac OS X 10.7 Lion as our dev runtime environment. We’re using Xcode 4.3.3. Jenkins is version 1.474. We use git and a mix of private and public repositories on

First Time Problems

Started with a brand new, fresh from the box Mac Mini. Of course, before attempting any of this CI-specific work, the box was brought up to date with OS updates, Mac App Store updates, and so on. Note! Jenkins is a Java app and Java is NOT installed by default. So after you run the Jenkins installer and it tries to start Jenkins, things will probably fail. The OS will prompt you to install Java, so you’ll have to do that, but then Jenkins should end up running. Not a big hurdle, but it’s there.

Make sure to launch (the GUI app) and get it properly happy. This is mostly ensuring the various downloadable components get downloaded and installed, like command line tools and such.

You will be using command line tools, thus you will have to run xcode-select. But being as this is Xcode 4, things are different.

$ sudo /usr/bin/xcode-select -switch /Applications/

This will ensure xcodebuild can be found. And note, the first time you run xcodebuild, it won’t run! While you agreed to the license agreement when you first launched the GUI, that’s not good enough for xcodebuild; you have to agree to it all over again via the command line. Just be aware. It’s not a big deal, it’s a first-time-only occurrence, but it’s there to deal with.

The User (login) Matters

This was the source of much fun and frustration for me.

The first time I installed Jenkins I had no idea what to expect. That it had a proper Mac OS X Installer .pkg was cool, but it was also hiding a secret. Any time there’s a “Customize” button I like to click it and see what options there are. I noticed it provided two options:

  • Start at boot as “daemon”
  • Start at boot as “jenkins”

I had no idea what the relevance of these two options were. The default was “daemon” and “jenkins” was unchecked. I just figured to trust the default installer settings. Ha ha ha…  This actually caused me the most trouble and pain. I won’t recount the many hours spent dealing with this, but I will explain the issues.

I opted to go with the installer’s default of “daemon” but that creates a problem because “daemon” is a special user. When Jenkins needs to do things, it’s going to look in non-typical places, like /var/root for ssh keys or the like. Basically, it’s going to cause you a lot of headache.

When you search around for information about this, everyone starts to talk about using the “dscl” command line tool to create a hidden secret “jenkins” user and run Jenkins that way. This makes sense because it creates a user of restricted ability so it helps to keep the system secure and minimize chance of damage should someone gain access to the system via the Jenkins system or login. But in practice, this turned out to be a big pain in the ass because of what we’re doing. I’m sure there are some projects where this won’t be that problematic. But writing iOS apps brings issues. Apple makes great products, but you find they are great as long as you color within the lines; the lines might be really wide and vast, but still you must color within them. Trying to deal with this secret “jenkins” user created various issues.

For Xcode (or xcodebuild) to do code signing, it needs access to private keys and certificates and other such things. Thus the Keychain is involved, but this hidden “jenkins” user doesn’t have one. Again, more searching will turn up possible solutions, but they are not ideal solutions. In fact, one solution of putting these into the “system” keychain really defeats the purpose doesn’t it? Then there are the .mobileprovision files needed during the signing process, and those must exist somewhere in the “jenkins” user structure. In my case, the provisioning files may be updated fairly often due to the addition of device UDID’s, and setting up the initial .mobileprovision files by downloading to the logged in user then copying it all into the hidden jenkins user locations… it was just turning into a massive pain in the ass. And you’ll have to do this at least once a year, when you renew your iOS account with Apple.

So I fumbled with various permutations of these user setups and it was all just frustrating to me.

In the end, I backed everything out and started over (for the umpteenth time). I created a “jenkins” user via the System Preferences. That is a full-on login-able user named “jenkins”, admin user. I then logged in as the “jenkins” user. I ran the Jenkins installer, customize, and selected the “start at boot as ‘jenkins'” option (and deselected the “start at boot as ‘daemon'” option). I ran the installer. That did not immediately succeed, but the resolution was simple. Stop the daemon (using launchctl). Edit the .plist for the Jenkins launchd job and changed the location of JENKINS_HOME to /Users/Jenkins. Then restarted the machine. Life was good.

I think today I’m going to try doing it “yet again” tho… deleting the Jenkins user and creating it again, then installing again, and this time making a subfolder, like /Users/Jenkins/Jenkins_CI or something like that. That’ll contain all the stuff in one folder and not litter the actual home directory.

Is this the right thing to do? Well, from a pure security standpoint, no. It’s now an admin user that can log in and have all sorts of fun. But my feeling is this machine will be behind our firewall. If this box gets compromised, we have bigger problems anyways.  Could it mean bigger problems for me down the line with Jenkins-CI itself? Maybe. We’ll see. I’m not necessarily advocating taking this approach, but it’s just the one I’ve presently taken. It appears that it will create less long-term hell for me, especially in dealing with Xcode and the OS.


Another source of pain was dealing with authentication issues.

Since we use private repositories on github, we need to authenticate. This proved to be more difficult than it should have been.

When I first tried a basic build of our project, I installed the various git plugins within Jenkins, created the new job, set it to obtain the source via the http protocol, and off we go. Well, that failed. The job just hung forever, I reckon waiting for authentication. So how can we authenticate? I saw no configuration options for it. So I started playing with ssh.

ssh would actually be a good thing in many ways, but with all the aforementioned user/login issues, it was becoming a massive pain. The way Mac OS X seems to handle ssh is by launching the ssh-agent on demand. Well… it can’t do that for the secret jenkins user. I tried all sorts of things, but I just could NOT get it working. *sigh*   Another vote for making a fully-realized jenkins users instead of this secret hacked one.

The one thing I had to then do was edit my ssh keys to not have a passphrase, and that would work (no need for ssh-agent, no need for interactive issues). But lacking a passphrase ain’t so hot. But it seemed to work… well, at first.

The next problem? Our git project has submodules. In the .gitmodules list, the “url” for each submodule used http as the protocol. And so, when the Jenkins-CI git plugin tried to obtain the submodules, we were back to the original problem. FML.

I tried fiddling with the repository URL as specified in the “git” section of the Jenkins-CI job to be something like:

and while that worked for the top-level repository, the submodules still tripped me up. Plus, I did not like the idea of storing a password in plain text and sight like that.

I was able to solve it tho… through the magic of the .netrc file.

I created the following file in /Users/jenkins/.netrc

login <github username>
password <github password>

Saved it. Did a “chmod 600” on it. And lo…. everything worked. Huzzah!

I think the git plugin should have a way of doing authentication, but I’m still too much of a Jenkins n00b to know really where the fault lies.

More Ahead

At this point, I’m able to clone our git repository and build the app. It’s very basic at this point, with much configuration and fiddling yet to come. But I spent a good deal of time on these matters this past week and tried to sift through a bunch of search engine results to wind up here. So much of the information out there is Linux or Windows based, which is fine for the general but some of the little details aren’t there. And I can’t imagine we’re the first people to need to build in such a way, but I just couldn’t find anything specific to the particulars of our setup. So here’s hoping this helps contribute back.

As well, if you the reader have any information, insight, comment, etc. please share. I’m still learning, and constructive contribution is appreciated.

Trying Trello

The new hotness in software development is “agile“. At my prior day job, it was waterfall. Sure they tried to adopt agile processes, but it really wasn’t going to happen. Due to the nature of the products and process, it just can’t be agile, tho they could try to adopt a few things and make some improvements. But at my new day job? Agile can make a LOT of sense. Take home: you can’t impart the process merely because it’s the new hotness or you think if you just adopt X process it’ll solve problems. Like any problem to be solved, you have to understand your problem fully and then apply the right tools to solve it, and that includes what processes you use.

However, it’s tough getting folks on board, so I’ve desire to try to sneak in agile stuff as we can. It’s nothing more than a commentary on human condition — we tend to resist change. If all this change is dropped on folks all at once, we’ll balk. I would too. Massive sudden change, especially when you’ve still got daily chaos and stress to manage, well… the change will be rejected. But if we can make little changes here, little changes there, over time we get there.

One thing I can tell is we all need a way to see the whole picture. We’ve got so many things going on at once, and it changes on a daily and sometimes sub-daily basis. I find myself often making lists and (re)telling my todo lists to my teammates merely to help ensure 1. I know what I’m doing and am on track, 2. that we’re all on the same page. By sharing with them I hope that if there’s a mismatch, they’ll speak up and correct. I’d rather be perceived as over-communicating than under-communicating.

But all this talk doesn’t solve the problem for everyone. The dev team is one thing, testing another, production another, sales another, marketing another… there’s so many things. Sure, we could use our issue tracking system, and there’s a lot of sense in that approach. But the issue tracker doesn’t work as well for non-dev folk PLUS it’s harder to get a 1000′ view. Yes, pictures/diagrams can make a big difference.

One thing from the agile/scrum world is having the daily stand-up meetings at “the wall”. Let’s set aside the meeting for now (again, baby steps), and just focus on the wall. I’ve suggested the wall, because I think that would be useful. Pick a wall in the office, divide it up in whatever way makes sense for us, then start populating it with sticky notes to represent all the tasks to be done. I think that’ll be useful at keeping a somewhat permanent record of the state of things (unlike a whiteboard, which will be erased eventually). Plus it allows anyone to just look at the wall at any time of the day to see where things are. CEO wants to know what’s up with Customer X? Just look at the wall. Did we ship Product Y yet? Just look at the wall.

Alas, one shortcoming is 1. we don’t have a lot of free wall space left in the office, 2. the wall is restricted to the physical. I’ve been searching for a digital wall solution and haven’t found much that thrills me. Something that we could access from any computer via a web browser (or even a platform-based app), and it would look good. But then we could also access from iOS or Android devices. In the office. Out of the office. At 3 AM, during office hours. From my desk, in a meeting on the shared screen. Whatever. Something with power to do what we need, but flexibility to work for anyone, not just the geeks.

So… I recently read this article from Joel Spolsky about “Software Inventory”. While I read it, it sounded like it was talking directly to me and our situation. I went looking at their solution:


I’ve only just started to play with it, but it seems like it could be the answer to my problems. I could see using this in my personal life, for Hsoi Enterprises, and for the day job stuff. Even if the rest of the office doesn’t buy into it, it could be useful for my own management of my tasks and issues to deal with. Being able to SEE everything instead of sorting through a bunch of text notes and to-do lists is sometimes much more useful, even if it ends up being redundant and a little more maintenance to keep 2 data stores in sync.

It’s still preliminary, but it’s promising.