Je me souviens
Everything here is my opinion. I do not speak for your employer.
April 2006
May 2006

2006-04-22 »

Design Gems

Normally I'm a programmer with a high output rate, which means that I can turn ideas into code pretty quickly. But what with my self-imposed marketing responsibilities lately, I've had almost no time for coding.

The problem is that I still think about coding. So my designs are ever-improving, while the amount of code I write has been ever-decreasing. A few times lately at work I've gotten caught explaining how I remember certain code working, only to find out that I only imagined it that way in excruciating detail; nobody implemented that feature or even talked to me about it yet. Oops.

But another weird effect from this is that my code design quality is improving. I spend so much time pre-considering things lately that when I finally actually write it, I've got it all figured out. But it results in what I will name the "pphaneuf syndrome": the problem is solved so thoroughly by so little code that nobody can believe your code actually solves the problem... or that you did any work.

Here is my example:

The Gracefultavi "Attach" Plugin

GracefulTavi is the wiki we use for our internal documentation. Over time, it's been used for more and more things, and we're finding the need to write more and more "formal" documentation (eg. specs that need to look nice for presenting to clients, who will sign a contract to pay us hundreds of k$ for implementing them).

So our first problem is simple: the wiki has all our development information, cross-referenced in different ways, because we've used a wiki since day one and we've done all our development documentation (with a few, ironically unremembered, exceptions) in the wiki. But it's not customer-grade documentation; sending customers wiki page dumps is pretty lame.

Secondly, even when no customer contract is involved, writing specs in wiki format is really annoying, because (like most traditional wikis) GracefulTavi doesn't support attachments and screenshots. As with any html, you can link to outside attachments and images, of course, but these are hard to administer properly and definitely break with the "anybody can fix your mistakes" wiki tradition.

Thirdly, we're trying to implement internal processes whereby (for example) even an internal spec can get signed off by several people and that version becomes completely tamper-proof: despite the "anybody can edit" wiki tradition, anybody can edit, but nobody can edit that version. And that version might contain images, tables, attachments, and so on. And there will be more versions after that. And you might want to refer to those same versions of those images and attachments from other pages even when new versions appear (for example, the "1.0 test results" want to reference the "1.0 test plan" even after 2.0 is released).

Thanks to mich and kjrose, it's easy to add new macro plugins to GracefulTavi. So I did... in about 1.5 hours. But that very short time was possibly only because I thought about it so much first. (*)

Other wikis, like MediaWiki also support attachments, but in a much more extensive way that took a lot more coding effort. Here's how my solution works. For most purposes (probably not WikiPedia), mine is better. You don't have to believe me, but it's true.

My attachment plugin has only three concepts: upload, delete, and lock. (There's also "undelete" and "view", but those are too obvious.) Upload is simple: a non-uploaded attachment is empty, and has a file submit button. Delete is simple: an uploaded but non-locked attachment has a delete button, which will permanently delete the file and let you upload a new one. And lock is simple: an uploaded but non-locked attachment has a lock button, which will permanently protect the file from deletion. Preventing deletion, in turn, prevents re-uploading.

The filename space is global. That is, across the entire wiki, if you upload a file called "foo.txt" and lock it, that's it; there will never be another foo.txt.

Despite its ridiculous simplicity, this model is not nearly as obvious as it sounds. Permanent deletion - in a wiki? Permanently locked documents - in a wiki? Names that nobody can ever change ever again? An attachment scheme with no revision history or version control - in this day and age?

Yes, yes, yes, and yes. And only those four things together make it work. In other words, breaking any of those "common sense" rules would have resulted in an unusable system; breaking all four of them at once is why it works.

Here's why. First, the wiki already has revision control; adding another versioning layer for attachments would be inelegant. Instead, what you do is encode the version into the filename. Sounds lame to you, Subversion users? Just remember, the kind of people who prefer binary documents to wiki documents are exactly the kind of people who don't like Subversion either. Furthermore, fully revision controlling binary documents isn't useful, because the diff/blame/branch/merge features don't work anyway. And auto-assigned revision numbers are meaningless, while human-assigned ones are memorable. And because you can't re-upload a locked document, nobody can change your document once you're sure you've uploaded it correctly - in other words, we implement the one remaining feature of Subversion that's actually useful for binary files.

So you can easily do 100% protected revision control with my plugin, which doesn't even support revision control. Don't upload "myproject-spec.doc" - upload "myproject-spec-1.0.doc", ie. the 1.0 version of the spec - and lock it. From then on, anybody who wants to talk about the 1.0 spec (on any page in the wiki, past, present, and future) will be confident that they're talking about that exact file. And the MyProjectSpec wiki page can link to that file for now... and in a future version, it can link to "myproject-spec-1.1.doc" instead or in addition. What did the spec look like last September? Go back in wiki history and view the hosting page, and it definitely points at the same attachment it did at the time. No magic auto-assigned rev numbers to remember, no branches, no tags, no syntax, and no uncertainty.

The pent-up demand for this was obviously huge, because within days it was being used all over the place in the wiki, and the usage is ever-increasing. Meanwhile, some people are still ironically claiming that it can't possibly solve the problems it intends to solve.

I say... the results speak for themselves. Which is good, because the above explanation is really long and confusing.

Off-topic Disclaimer

(*) People will say that we could have saved a lot of time arguing about it internally by just doing the 1.5 hours of work in the first place, but that't not how design works; I wouldn't have spent so much time (much more than 1.5 hours) thinking about the problem if there weren't so many arguments about it before. And just leaping into coding with a bad design would have taken more time than thinking/talking about it first.

I'm CEO at Tailscale, where we make network problems disappear.

Why would you follow me on twitter? Use RSS.

apenwarr on