Don’t be a Jerk: Write Documentation

Fred Hébert understands that software engineering is not just about writing code, but about writing documentation, and that the two aren’t the same. His book, Learn You Some Erlang for Great Good!, is also bloody fantastic.

Ardmore: a Reflection on Burnout

Ardmore comes from the Irish Ard Mór, meaning “great height”.

Sometime in 2005, DHH released “Creating a weblog in 15 minutes”. It was the seminal screencast that introduced Ruby on Rails. Seeing his use of TextMate and Rails to quickly create working software for the web: that changed me.

It wasn’t bullshit ASP Classic, which I was using for an internship at the time. It was beautiful. I had already drooled over the acrylic iMacs at my internship (my first real job in software), and now a bit flipped in my head, demanding action. I took my paltry savings, took the train to the Apple Store in Ardmore, Pennsylvania, and came home with Aquariel: a 24 inch iMac and my first Apple computer. I didn’t know it at the time but it was the best career move of my young life.

I learned enough Rails to become dangerous, put some time into learning modern (at the time) web design, and my world took off. All kinds of doors opened to me, and I made my way through a series of web development jobs that, in 2010, landed me at Google through an acquisition. If it hadn’t been for that screencast, and that wicked urge to dive into the unknown, I’d probably still be churning out ASP Classic in the wasteland of terrible software.

But now I’m at an impasse. I’m jaded by the web. I’m uncertain in my ability to write applications for the desktop. My code is usually terrible, and starts to lose coherence after the fifth or sixth refactor to get myself out of the corner I painted myself in with my code. I am a master at using git in my workflow, but I struggle to keep my commits atomic, and my commit messages clear and comprehensive. And so forth. My work process feels slow, trudging.

I’m twenty-six, and I feel very old. I sift through my knowledge now, trying to find firm foundations from which to continue pushing myself, and my ability to learn, but it is difficult, and my foundations are flimsy, even after many forays into functional programming and other core principles of software.

My assumptions about the world of software development, the naive ones that solidified in my formative years, are getting knocked over by the reign of multi-datacenter, schema-less, state-less web backends that serve millions of people, and their lightweight, colorful, mobile application counterparts.

Nothing grabs me the way that Rails grabbed me in 2006.

I no longer code outside of work. The merits of same have been argued back and forth, but the more important point is this: I find myself wanting to learn, wanting to evolve and improve. But the problems I want to solve can’t be solved by a little cowboy wherewithal and a couple sleepless nights in front of Emacs. I visualize products: polished, clever solutions that people happily pay for because their lives are improved. Or otherwise they’re games: typically grandiose in scope, unattainable, but profound and insightful. Either way, I often find myself without the knowhow to really make a dent in any of my dreams.

The work I want to do requires teams now: teams of artists, designers, experts in their field. I am just a programmer, and when I was on edge Rails and writing blog engines, it at least felt like I was a modern programmer. Now I do not even feel that.

I have made my way along my career in such a way that I have been exposed to the marvelous potential of computers and software, but unable to exploit that potential for myself. It’s always been in the service of another person’s goal. I have attempted to carve out small paths for myself: caring desperately about user experience and UI design when no one around me even considers it a priority, taking over unglamorous jobs of writing APIs that document themselves, or tests that don’t break depending on what time they were run.

My desire to throw all my knowledge away and start fresh has diminished. My desire to create one great thing has increased.

I do not quite know where to go from here. I don’t know if I have it in me to create great things for the web anymore, or to create things at all. The endless nature of programming means that no projects are ever truly finished, but I would have to hesitate to even say that any projects I’ve attempted have been successful. I’ve learned a lot from my failures. I don’t mind making mistakes.

I missed the mobile boat. Every day I faff about writing these onerous articles, I’m not learning Objective-C or trying to create mobile experiences or apps. Is this burnout? Does it matter? The work needs to be done, the opportunities will continue to flow by. I can only hope to prepare myself, and be at the right place at the right time, to catch on to something, and propel myself to another great height.

1Password and Login Rot

I should be clear at the outset that 1Password is a fantastic product, and it’s not their fault I’m an idiot with weird edge-cases, OCD, myopia, et cetera. Nonetheless, there’s room for some amount of improvement in documentation and setting expectations through UI, here.

This article is about 1Password, and trying to stay freakishly organized in a complex world.

Declaring ‘login bankruptcy’ is tricky. It’s not like declaring e-mail bankruptcy, where the minimum necessary work is to label everything in your inbox, and then archive it. I’ve been using the 1Password for like five years now, and it’s full of all kinds of logins and crap that I’ll never need again. But this is misleading, right? Because every time you register an account online, one of a million things could happen.

If you have an insecure password, and then declare bankruptcy and forget all about it, the site could get hacked and then it really fucking needs to be on your radar again. If you registered an account during the free-love 2007 Rails era when every web programmer and their dog was creating site after site, then maybe the site itself has changed. Maybe they have a database with that old login somewhere, but now they want you to use OAuth. Maybe they’ve taken away the login-component of their site, and you have no idea if they still have your old credentials lying around on a hard drive somewhere. Maybe the site won’t allow you to delete your account. Maybe it’s too much of a fucking hassle to try.

So I was going to content myself with a ‘client-side’ bankruptcy. My plan had several facets:

  • Let me find all the logins that use e-mails I’ll never be able to access again, and at least update those e-mail addresses so if something happens I’ll be notified.
  • Let me take the 25% most insecure passwords in my 1Password vault, go to those sites and update them with something nice and stable, if they’ll let me.
  • Then let me just archive my whole 1Password vault. Now this is important: it needs to be archived in such a way that as I go about the internet with my brand new empty vault, I can quickly and easily import all the passwords I need, with like, one click maximum.

So of course I did this with no research at all. I wrote this dumb little AppleScript to export 1Password logins to plain text. Each one, individually. Because I thought that was the only way to be able to import them selectively: by separating them into separate files. The AppleScript works great. Problem is, it doesn’t save all the information about the password in the file. Notably missing: the day the password was created, and the last date the password was modified. So that really sucks. What sucks worse is, after I tried to import a password back in, I realized that the CSV import requires the user to individually select the ‘meanings’ of the rows in the CSV file. And there’s less ‘meanings’ than fields that are exported from 1Password! For instance, here’s a fake CSV file (oh I guess it’s TSV, whatever):

title   notes   faveIndex   securityLevel   contentsHash    htmlAction  htmlName    passwordHistory htmlMethod  URLs    username    password    URL/Location     1000    SL5 08800990  appleConnectForm        post  secret-pw

So there’s some interesting things that are saved, like the securityLevel. The default is that all passwords require the master password. This can be changed: you can make passwords ‘low level’ security, requiring only a PIN code, or less, for mobile devices. I think. The security settings in 1Password 4 on iOS are confusing and interact in weird ways.

In any event, here are the sum total list of ‘meanings’ that must be manually assigned to the columns of a TSV file upon import:

The default TSV import 'meanings' in 1Password.

Notice what’s not there? How about most of the columns that 1Password exported? securityLevel? htmlAction? htmlName?

More importantly. When I use 1Password to preserve credentials with their browser extension, it doesn’t just save passwords. It saves all the HTML form fields it found the username and password inputs in. Here you can see how it’s captured the HTML input name and value for the submit button on a web form.

HTML form key-values stored in 1Password.

But those form fields don’t get saved into TSV format upon text file export. And even if they were, they couldn’t be imported back in. More importantly than that, 1Password allows you to add key-value pairs to the login after it gets created. I have stuff like my secret questions added to logins after the fact. but those additional key-value pairs don’t get saved into TSV format upon text file export, and even if they were, they couldn’t be imported back in.

And, finally, to add insult to injury: you can choose which rows in a TSV file you actually want imported into 1Password (making my AppleScript totally worthless). It even allows you to specify a folder name, and suggests one based on the file’s name. As fucking cool as that is, it’s less cool for a format that’s half broken on the way out and then completely mangled on the way in.

As for the 1Password Interchange Format, the metadata laden, thumbnail-preserving format designed specifically for import and export? You get no choice as to what logins you want imported upon selection, and you get no choice as to where the imported logins go: they simply appear in your global Logins vault, no folders or tags.

Oh well. At least restore from backup is fast.

I don’t want to give the impression that this is some kind of rant about 1Password. What I’m doing is feeling around the edges of a larger problem, the problem that’s plagued technology with insecure passwords, identity theft, and the search for some kind of Holy Grail in the form of OpenID/OAuth/Mozilla Persona/App-based logins. Yes, I would love it if 1Password could tell me when the last time was that I used a login. It would be even better if it counted every time I used one successfully. Maybe one day we could have some set of reliable internet error codes, and a common set of verbs to use on URLs, so that 1Password could even tell if a login was successful or not. But that’s crazy talk.

Technology has tendrils. Every time we register an account somewhere, we’re reaching out, and making some kind of connection. It’s not simple to recall those tendrils on a whim, and I question if it should be. I have no solutions of my own to offer. Decaying logins are an interesting thought (remember me for a week! I mean it!) but product owners are always going to want that big impressive database full of credentials. It’s a lifeline to e-mail accounts, marketing attempts, user preferences. Wanting a clean password database is not sufficient enough reason to upend the world trying to find a better solution. But it’s another reason, added to a growing list, of reasons why the status quo is unsatisfactory.

A GTD Retrospective, Part I

I took a two week hiatus from the world at the beginning of 2013. I holed myself up in my apartment and cut all outside contact. I did this to map out my current situations, and start planning to make awesome things happen. One of the steps I took was to put together a new OmniFocus database. I had tried out GTD in 2007. I loved it, but I gradually stopped using it. While many basics followed me to 2013, much of the value of GTD was lost.

I was determined to make sense of my complicated life. Even better, I had an international move to prepare for. What better case study for GTD than that? I didn’t use the GTD book as gospel, but I sure as hell listen to Back to Work religiously, so I’ll be prepared, right?

Well, it sucked. I’ve made it to the other side, but my database is in tatters, and my priorities are mangled. I’m writing to find out why. In this article I’m going to mostly tackle the Inbox.

Forgive my generalizations about the actual rules; once I have a copy of GTD in my possession again I can resume the usual level of orthodoxy.

The roots of OmniFocus lie in trying to create the perfect GTD client. They were made for each other, but it’s a simplifying assumption to conflate the two. I plan to do it a whole bunch.

GTD (and by proxy, OmniFocus) tries to be self-contained, with two important exceptions. It does not try to be a calendar, and it only allows input through a trusted inbox. But the real world is sticky. It wants you to have lots of inboxes. Your Facebook messenger, your Jabber client, your e-mail. Your paper inbox, your work responsibilities, your back-of-the-napkin ideas. Your tumblr posts, your feed reader, your Netflix queue. OmniFocus’s inbox is only useful insomuch as you keep, in the back of your head, the thought that it’s not the only Inbox you have to process. This is the equivalent of buying a shiny new car, and hoping it will retain its value when you drive it off the lot. As soon as you accept that OmniFocus’s inbox is not special, it loses an insane amount of value.

That is one nebulous problem, too large to finagle here. But there are more immediate issues. Inbox processing is sticky. I am a master at putting things into it, but once they’re in there, one of several things ends up happening:

  1. I didn’t care as much about the thing as I thought I did, and I get rid of it after doing nothing about it.
  2. Whatever it was is actually super important and needs to be at the forefront of my mind for logistical planning. So it can’t just hide in some project/folder. This is also a symptom of not solidifying the idea enough in its current state.
  3. I don’t have a good idea of where my time is going, or what time I have available when planning out tasks. OmniFocus 2 looks like it might address a bit of this with the Forecast calendar right in the application.
  4. I never enter all the metadata I need to make smart decisions about my schedule. Time available, due date, start date… perhaps these things come with practice. More often than not I can’t answer the questions at all, or I’m over-prepared: I’ll say “rent’s due”, and give it a start date and due date a week apart, but all it takes is a couple clicks on a webpage. Padding all my tasks with space like that seems to come with some mental cost.

Processing has a two-minute limit placed on the amount of time you can spend doing some item. If it can’t be done in two minutes, it needs to be delayed, delegated, or filed where it belongs, either as a task, or some meaningful data that could be needed later.

But processing is also about the practice of planning. It is looking at a single line in your inbox and saying, “Do I care about this? Does this matter at the right levels? Is it better to do well, or quickly? How many individual actions is this, really?”

No one is perfect, decisions may not be strictly correct or incorrect, so there may be no way to know if the decision you made was beneficial, detrimental, or had any effect at all. Nonetheless, the practice is in assessing a situation and making good judgement calls, quickly. And let me tell you, I am bad at it.

I get lost half an hour after trying to Google something coming from an inbox item. Other times I process them too quickly; finding something a month later in the wrong place with a misleading due date. The lack of a Forecast in the desktop OmniFocus app is a clear disadvantage. I look at my calendar some mornings, only to find it full of crap I honestly did not need to get done that day, or subject to the Default-itus problem: when all the meaning of what I wanted to accomplish on a given day is mangled, because every task defaulted to 5pm on the day:

A useless calendar.

This hurts in two ways: each day you feel lost, and planning for the future seems hopeless.

The other items on the calendar, shit that feels like it would ‘die’ if not placed on the calendar, seem stupefyingly obvious: an hour after I get through security and am waiting for a flight, my phone buzzes: It’s a reminder to go to the airport.

There’s a lot I struggle with, here. I’m convinced GTD is a reasonable approach, but its effectiveness isn’t panning out for me. Now that I’m starting my life over, a lot of my OmniFocus projects and contexts need to be reviewed, and I hope to do that soon. At this point it’s too early to blame myself, or the system. Blame is not needed; re-evaluation is.

In a future article I hope to detail some of the pain points of trying to plan an international move with GTD.

prev Page 8 / 8