Weeknote 42/2020

Going Marie Kondo on my desk – My desk sparks joy in me. That’s because I was able to give my IKEA BEKANT a new lease on life. More than a year ago, it lost its standing desk function because suddenly the motor wouldn’t lift the top more than a centimetre before giving up. I found out that this was a common issue caused by a faulty power supply. After filing a warranty case, it took many months and repeated phone calls to get a replacement unit delivered, but a few days ago, it finally arrived. When I installed it, seeing the messy underside of my desk sent me on a cable management quest. Using cable ties, velcro and double-sided pads, I was able to tidy up the rat’s nest of power and USB cables nicely. Fixing a power bar with USB charging ports to the underside of the desk substantially reduced the number of cables going down to the floor. Not only is the desk now a joy to look at, raising it also doesn’t pull a whole power bar off the ground anymore.

Checking off tasks with TickTick – Its growing popularity brought the Ticktick app to my attention. It aims at combining the two most important productivity tools, the to-do list and the calendar. Other than HourStack and TimeHero, two similar web applications I tried in the past, TickTick is a native app for Mac and iOS. I’m still a fan of time-boxing my work, and my home-grown solution that I built in Notion falls short in calendar integration. I’ve decided to give TickTick a try for my daily focus work. For my long-term strategic direction, I’ll keep tracking goals and outcomes in Notion.

I have a new type – Just like Steven Waterman, I fell Down the ergonomic keyboard rabbit hole. His description of how he gradually switched to a more ergonomic multi-layer keyboard layout is written and illustrated hilariously. But there’s also a serious health aspect behind the gadget mania. I’ve come to very similar conclusions recently that led me to split ortholinear keyboards. I’ve also adopted the Colemak keymap. I’m going to sell most of my keyboards that have the traditional row-staggered key layout because regardless of their build quality, they just can’t compete when it comes to long-term health benefits.

Weeknote 31/2020

My second week off work is coming to an end. I’m not sad; actually yesterday I started missing work. Thanks to my business partner manning the fort, I got to really switch off and recharge my batteries. Last week, my family and I spent a few days at a Slieve Aughty, an eco-friendly equestrian and activity leisure centre near Galway. Mere minutes before leaving, my daughter broke her arm; not by falling off a horse but by jumping off a swing. She wears her cast like a badge of honour, so it’s all good.

After coming back home, I decided to get back into live coding on Twitch. Feels good. Before, Imposter Syndrome had made me question if I really should sit in front of a camera when other streamers who are completely new to software development easily reach multiples of my viewer numbers. I’m incredibly grateful that my viewers were quick to reassure me that I’m providing them with real value. So instead of stupidly comparing myself with others, I’m looking forward to my upcoming streams.

My next few streams might suffer a little in terms of speed because a change of keyboard layout is going to keep messing with my brain. When I realised that my new split ortholinear Lily58 keyboard feels so much nicer than all the traditionally configured boards I had used before even though it’s nothing fancy in terms of materials, it brought up the question if switching from the QWERTY layout to something more modern would improve my typing experience even more. For about two weeks, I’ve been trying out the Colemak layout now (in particular, its mod-DHm variant), and I’m convinced it’s much more ergonomic. And I hope that over time, I’ll also regain a somewhat decent typing speed.

Now school has started again for our kids. My daughter has an enviably soft start into secondary school with only two hours of class so far just to see the new environment. The precautions against infection the school is taking are quite okay, so we’re happy to send her there. Not quite so with our second-grader. At his age, masks aren’t mandatory and there’s also only a 1m distance rule in place. At the moment, we’re not comfortable with this level of risk management and have decided to teach him at home, similar to before the holidays. Fortunately, the school is going to support our approach at least for a few weeks with materials and regular check-ins.

Adaptation is undoubtedly the skill of the year.

How not to drown in too many Discord servers

Discord has become a popular community platform far beyond gamers. Recently, the number of Discord servers I’ve joined has grown quite a bit. I have whole folders full of Discord servers grouped by Live Coders, Mechanical Keyboards, World of Warcraft, and application software support.

The downside of how easy it is to create or join a Discord server is keeping up with the amount of chatter that’s happening. That applies especially if you are a member of multiple servers that have overlapping interests and/or “general social” channels. I simply don’t want to wade through every “pet pictures” channel, sorry.

Unfortunately, the Discord UI is a bit convoluted, and I ended up using the “mute server” feature for almost everything. That stopped the flood of messages, but it also cut me off from updates that were relevant for me. This week, I finally found a good solution how to handle muting notifications, channels or whole servers, and it made all the difference! Here’s how I cut down the time it takes me to catch up to a few minutes every so often.


The way Discord handles notifications is quite straightforward. I’m strongly in the “the fewer notifications, the better” camp. That’s why I usually have notifications enabled only for @-mentions. Only in channels in which I don’t want to miss any post, I enable “notify for all messages”. For me, this applies mostly to announcement channels that are used rarely but contain time-critical information like keyboard group-buys.

Unread messages

Managing unread messages efficiently takes a little bit more effort. First, use “mute server” for servers that you don’t frequent actively at all. Servers you only joined to ask an occasional question but stay out of otherwise shouldn’t draw your attention at any time.

The majority will be servers that have some channels in which you’re actively interested. On these servers, mute each channel that doesn’t interest you. When new channels are added to the server, you’ll have to choose if you want to add them to the mute list. On some servers, I even enable “hide muted channels” to shorten the channel list.

With these two measures, Discord will only track unread messages for the servers and channels you didn’t mute. Only now the “unread messages” indicator on the server icon starts making sense. More importantly, it is the prerequisite for efficiently using the “Next channel with updates” key combination. Hitting Opt+Shift+Down-Arrow (Alt+Shift+Down-Arrow on Windows, Up-Arrow for the opposite direction) gets you to the next unmuted channel containing unread messages. Read the channel to the end, hit the key combination again. It jumps across server boundaries, too. That way, you can catch up on everything that interests you in no time. I’ve assigned the “next unread channel” and “previous unread channel” functions to two extra buttons on my trackball, so I can simply leave my hand on it if I don’t want to write a reply. Scroll, next, scroll, next. Usually, it takes me less than two minutes to get through all my new posts.

And when I press the key combo another time after having already caught up with everything, Discord rewards me with a satisfying wiggle.

Clean Chef code: Depend on public cookbook interfaces

For about a year, we’ve been cleaning up the Chef Infra code for freistilbox to make updating dependencies, Chef versions and even operating systems easier. It’s a lot of work because our early code is functional but not pretty. There have been many instances of “we didn’t know better”, and that’s what refactoring is for. But I also came to realise that we were missing a critical fact: Common software engineering principles and practices apply to infrastructure code like they do to any other type of code.

Or as early Chef developer Joshua Timberman puts it:

“Hey, ya’ll remember when devops really just meant you knew how to write all your bash in ruby instead?”

Ouch. Making this connection earlier would have saved us weeks of work. That’s why I’m going to share my findings in a series of posts.

In this post, I’m going to advocate for treating a Chef cookbook as a unit of software that provides explicit interfaces instead of tempting its users to depend on implementation details.

Chef Infra cookbooks use node attributes as variable parameters for system configuration. In software engineering terms, node attributes are global variables. They’re implementation details of a cookbook. In consequence, using a cookbook’s node attributes for any purpose other than defining setup parameters creates a dependency on implementation details which can change at any time.

For example, it’s common practice to use a search on node attributes for service discovery. As node attributes are global variables, any cookbook can do this:

service_nodes = search(:node, "webservice_id:myservice")

From this code, we can tell that web service nodes are identified by a node attribute named webservice_id; nodes sharing the same webservice_id value belong to the same web service.

The problem with using this information outside the cookbook which provides it is that this particular implementation can change at any time. This kind of tight coupling is a liability. For example, a second attribute webservice_status might get introduced, reducing the node set by adding AND webservice_status:active to the query. Since this change in semantics is not necessarily a breaking change, there’s no simple way like semantic versioning to inform everyone who depends on this unofficial interface.

How about we provide an public API instead? Our web service cookbook could for example provide a class we can use for service discovery:

webservice = Company::Cookbook::Webservice::Discovery.new("myservice")
service_nodes = webservice.nodes

This is easy to implement as a cookbook library. By using namespaces, we make sure that method names don’t conflict. In my practice, I tend to use the camel-cased cookbook name under the namespace Cookbook and the company namespace.

With service discovery encapsulated and hidden behind a public interface, we could even reimplement the cookbook’s service discovery using a different technology like Consul without breaking any code outside our cookbook.

But even if other cookbooks depending on our implementation isn’t a concern, implementing auxiliary logic in a central library instead of scattering it across recipe files makes it much easier to maintain. I’m going to talk about “Plain Old Ruby versus Chef DSL” in a separate post.

Typing with Jazz

I do my work using keyboards and I make music using keyboards. This clever web application brings it all together.

Making the step from being non-racist to being anti-racist

For decades, I’ve lived a sheltered life as a person whom MLK describes as

“the white moderate who is more devoted to “order” than to justice; who prefers a negative peace which is the absence of tension to a positive peace which is the presence of justice”

All this time, I stayed in my comfort zone and considered justice someone else’s problem, probably something the state needs to take care of via foreign aid or policy.

Just like it took meeting my wife for me to learn that protecting our environment starts with me as an individual changing my consumption behaviour, it took the BLM movement and the recent riots for me to understand that I as an individual can be an ally, can contribute to racial justice, can speak up against discrimination. That being non-racist isn’t enough, that I need to be anti-racist.

I have much to learn, and I am grateful for the many online communities that raise awareness, practice solidarity, and foster understanding in “non-racist” people like me.

DIRECT - The seven core topics of remote team communication

Pick any guide on remote work (oh, there are so many…) and it’ll tell you that communication is essential when you work in a distributed team. The problem is that it’s not obvious where exactly the centre of balance is between sharing too little and sharing too much. That’s why I’ve created a framework that uses a simple acronym to remind you of good opportunities to keep your distributed team in the loop.

You can watch it here or on YouTube. I’m already working on my next videos, so don’t forget to subscribe to my YouTube channel!

Weeknote 20/2020

Back in Azeroth I will certainly not remember the current World of Warcraft expansion “Battle for Azeroth” as my favourite one. After months of frustration with its storytelling, I stopped playing in February. I didn’t expect my exodus to last only three months, but I also didn’t anticipate that I’d be stuck at home for an eternity. So this week, I converted some of my in-game gold into play time and took my Tauren druid out of cold storage. With lowered expectations.

Wait, mouse buttons are cool? I’m a keyboard person. In the last few weeks, I’ve even put in extra effort to memorise as many useful keyboard shortcuts as possible. But plugging in my gaming mouse again gave me the idea to put its 12 side buttons to use in my work applications as well. So I went and mapped the keyboard combos I use most to the available extra buttons on my mice and trackballs (between which I rotate occasionally). Instead of running multiple ugly vendor applications like Razer Synapse and Logitech Options, I’m using Steermouse which I had already licensed for my Elecom trackball. I still try to keep my hands on the keyboard as much as possible, but when I do reach for the mouse, I can now make the most of it.

Goals for direction, time boxing for pace After discovering two weeks ago that a project had dropped off my radar, I made it my main priority to finally ship it. I put the project on my short-term goals list that I reference every morning. This kept it in my crosshairs. And every day, I reserved time for it in my calendar. That made sure I made continuous progress. This week, I deployed to production and published both the documentation update and the announcement blog post. It was a great feeling of achievement. Just like the great John “Hannibal” Smith, I love it when a plan comes together.

Finished my cyberdeck

GMK Night Runner, one of a few keycap sets I ordered last year, finally arrived, completing my cyberpunk-themed keyboard. The case is a Keyboardbelle Nouvelle limited edition. I used tactile T1 switches with 67g springs, lubed with Tribosys 3204. They’re mounted in a carbon-fibre plate over a hot-swap HS60 PCB.

Because the case is 3D-printed, it sounded a little bit hollow. I was able to mitigate that by putting a thin foam envelope (previously used for packaging a plate or PCB) into the bottom of the case.

I’m very happy with how nicely everything came together, especially how the CF plate lets a lot of the RGBs shine through.

I’ve created a gallery with a few more pictures.

How we schedule our days is how we spend our lives

“Scheduling is an invaluable tool for habit formation: it helps to eliminate decision making; it helps us make the most of our limited self-command; it helps us fight procrastination. Most important, perhaps, the Strategy of Scheduling helps us make time for the things that are most important to us. How we schedule our days is how we spend our lives.” (Gretchen Rubin, Better Than Before)

Cover letter > Resume

So we whittle the group of candidates down aggressively first. This means judging their cover letter and, to a far lesser extent, their resume.

Nice to get confirmation that great teams like Basecamp take the same approach as I.

-> m.signalvnoise.com/hiring-pr…


Despite working on a Mac, I’m using the mouse/trackball less and less. I’ve installed Vimium in my Brave browser; it allows me to follow links by selecting them with easy-to-type letter combinations.

I’ve also programmed my keyboards to send arrow keys when I hold the space bar and press the H, J, K and L keys. That way, I can move the cursor and scroll a page without even leaving the home row with my fingers.

My Daily Bootup checklist

With such a huge number of people suddenly thrust into working from home, I thought I’d share a bit of my experience (more than 10 years, actually) with doing Remote Work. I started a new morning livestream called “The Daily Bootup”. It’s named after the checklist I use to start every workday. This checklist helps me keep track of my goals and to-dos, especially my most important tasks (aka “MIT”). This is how it looks like:

  • Check my calendar for the day
  • Check my weekly goals
  • Check my to-do list
  • Check other sources of work
  • Schedule my MIT
  • Write a 5-Minute Journal entry
  • Send a team check-in

Let’s take a look at each checklist item in detail!

Check my calendar for the day

Before I can start planning my work for the day, I have to get a feel for how much of the day is already predetermined by appointments and repeating events. That’s why I first check my calendar.

Check my weekly goals

I use weekly goals to guide my focus. On Mondays, I define one or two important results I’d like to achieve by the end of the week. Every other weekday, I reference this definition (which I share with my team on Basecamp) to keep me on track.

Check my to-do list

Unfortunately, I’m still living in a world in which there are tasks that I have to do no matter what, and deadlines that I haven’t set myself. My to-do list helps preventing them from falling by the wayside.

Check other sources of work

On top of my primary to-do list, there are other systems that tell me things that need to be pushed forward. Sales deals in our CRM and incident follow-ups are only two examples.

Schedule my MIT

At this point, it’s finally time to define today’s work by entering tasks into my calendar. For me, a time boxing approach has been working best to make sure that I put in the work to get the important things done in time.

Write a 5-Minute Journal entry

Many people recommend picking up journaling as a daily practice for reflection and recording one’s thoughts and feelings. Instead of doing free form writing, I have a 5-Minute-Journal template in Day One that asks me three things every morning: “What are you grateful for?”, “What would make today great?” and “What’s your daily affirmation?”

5-Minute Journal

In my experience, a gratitude journal is a great way to keep myself on the positive side of things. Listing the things that are good in my life takes effect while I’m writing them down, and again when I read these entries two weeks or many years later.

Send a team check-in

As the final step in my morning routine, I submit a form that our team uses to tell everyone what to expect of ourselves today. It does so on multiple levels because it lets us not only enter our main goal for the day but also our mood and additional information that might be helpful for dealing with us. I haven’t yet tried to analyse the data. For now, it’s just nice to quickly see who’s feeling excited and who’s already tired at breakfast time.

Team Check-In

So that’s my Daily Bootup routine! Let me know on Twitter or micro.blog what you think of it. Or how about you drop by on Full Stack Live? I do “The Daily Bootup” weekdays from 9:30am to 10am (Ireland/UK time) and would love to have a chat!

Weeknote 13/2020

Learning JavaScript

While I’ve learned more than a dozen different programming languages in my three decades of using computers, I’ve been focusing on Ruby for the last one. At my company, we automate our hosting infrastructure with Chef, we build our websites with Rails or Jekyll, and even for more complex command line scripts, Ruby has replaced Bash for us. But lately, I’ve actually added another programming language to my roster that I wanted to learn for years: Javascript. With StimulusJS, it was really easy to add a bit of client-side logic to our hosting dashboard. There’s a lot to learn and I’m really looking forward to doing more frontend development!

Icons for everything

Talking about frontend: Iconography is an important part of every user interface nowadays. Of course, the internet offers endless supply of icons but many of these collections are of low quality, have unclear licensing policies or are of a quality that doesn’t justify their price. Discovering the Noun Project has solved this problem for me completely. I’ve started using their icons on web sites, in my talk slides and even to give my Stream Deck a more consistent look:

Stream Deck

Live stream for remote workers

With so many more people now working from home (and struggling with the change), I thought I’d share my 10 years of experience with remote work. I’ve started doing a 30-minute live stream over on my live coding channel every morning at 9:30am (10:30 on the continent) where I chat with viewers about how to make remote work… work. The stream is titled “The Daily Bootup”. How about you join me Monday morning and we start the day together? Simply click “Follow” to get a notification when we start!

Managing multiple Git identities

I’ve always been struggling to use the right name and email address, separate between work and personal projects, for each of my Git repositories. Micah Henning solved that problem nicely by removing the global settings but making a repo-specific configuration mandatory. And a handy alias is the icing on the Git identity selection cake.

The Live Coders Conference

There won’t be many conferences in the next few weeks, at least not the sort that you need to attend in person. However, with COVID-19 handing out lemons, people start to discover the lemonade of online conferences!

I’m happy to be part of an initiative by The Live Coders, a community of people broadcasting their software development on Twitch. On 9th April, we’re going to broadcast more than 12 hours of presentations on a wide range of topics. With my talk about burnout prevention, I’m probably going to have a slot in the (European) afternoon.

For details, check out The Live Coders Conference. Andy, one of the organisers, also did a write-up on Setting up an online conference.

It lives!

Reading with the sun in my back.

When terminals were real tty’s

For my first Retro Saturday live stream, I chose working with a PDP-11 minicomputer. I don’t own a PDP-11, nor can I afford to buy or run one, but I can simulate one realistically usingsimh, the simulator for historic computer systems.

After successfully installing Unix V7, the original Unix operating system from 1979, I ran into unexpected issues with entering source code. One of the problems was the lack of a full-screen editor combined with my lack of ed skills. Another problem was that the Backspace key didn’t work as expected; an issue I first encountered 27 years ago trying out an early version of Linux. And then there was the strange behaviour that I had to escape the number sign at the beginning of #include <stdio.h> with a backslash; otherwise it would disappear.

After the stream, I found out what the problem was: V7 was simply still geared towards being operated from a teletype, basically a typewriter with a serial port. (It would take many years until typewriters actually came with correction ribbons that enabled you to erase and overwrite. But by that time, teletypes had been replaced by serial terminals with CRT screens.)

On an input device that prints each character you type immediately on paper, it’s impossible to do what Backspace does. That’s why the Unix developers assigned special meaning to the # and @ signs.

The # sign tells the V7 shell to ignore the previously typed character. Correcting a typo would look like this: cat memp#o.txt.

For larger errors, there’s the @ sign. It tells the shell to ignore everything before it. For example: rm mem@mv memo.txt memo.bak.

Exploring historic operating systems has become a passion for me lately. Not only do I learn a lot about early computing technology. It also makes me appreciate so much more the achievements of pioneers like Thompson and Richie who didn’t have any of the conveniences software developers enjoy today.

2.11BSD seems to be a more user-friendly OS for the PDP-11, so that’s what I’m going to try next!

Supporting UDUMASS

I’d like us to start gathering funds to have the uncensored version played every day on every major TV station and streaming service.

VAX on, VAX off

In “geewiz explores computer history” news, I’m now an official member of DECUS, the Digital Equipment Corporation User Society! The reason is that HP (who bought Compaq who bought DEC) issue a Hobbyist License to DECUS members who’d like to install OpenVMS for funsies. And I have to admit, working with an old-school operating system that isn’t unixoid has been a great experience so far. I’ll do a live installation of OpenVMS on my Twitch stream tomorrow.

☑️ Go full coffee hipster

Weeknote 8/2020

As I’m pretty much Epoch years old, I celebrated a special birthday this week. It’s interesting in this context that my interest in historic computer systems has never been higher. I want that PiDP11 so hard. I’ve just applied for a hobbyist OpenVMS license. And on my live stream today, I installed the ancient Unix V7 from a virtual tape.

I mentioned in my last weeknote that I was trying out Brain.fm to put focus-improving background noise into my head. During one of my uses, its selection page for choosing a style of music made me remember another familiar page: the “Music” page that Calm added to their mindfulness app last year (I think?). While I’ve been using Calm for meditation for years, I’ve been using its music feature only for falling asleep easier. But since there’s also a “Focus” section, I won’t need to add another music app to my already long list of subscriptions.

That list still did get a new entry recently, though. Despite the fact that I’m fortunate in that I don’t have to schedule many meetings and calls, my calendar is one of my most important productivity tools. Most of the entries there are appointments with myself that I schedule every morning. By time-boxing my most important tasks for the day, I make sure that I actually have the time to get them done. That’s why I’m among the first subscribers of Fantastical 3 Premium, my calendar app of choice on all my devices.

My usual table at Starbucks where I sit to plan my day in the morning has a raised platform in the middle. Because of its more ergonomic height, it’s the ideal place for my iPad. The downside: It makes touching the screen inconvenient because I have to lean in and reach out with my arm. Even though there are people who started using a mouse as soon as iPadOS 13 came out, I dismissed the iPad’s mouse support because it was “only an accessibility feature”. Now that I finally decided to try connecting a Logitech Master Anywhere mouse, I am wondering how many times my “doing it the proper way” has been getting in the way of actual improvement already. Setting up the mouse (with all its 5 buttons, no driver installation necessary) took 2 minutes and it’s working perfectly. I can tap things easily, and with just a single click, I can go back to the home screen, switch to a different app or display the control center. With the iPad, the Happy Hacking Keyboard and the new mouse, I think I’ve found my mobile work endgame.

Josh Wood’s article resonates a lot with me. I’ve chosen a humble amount of “fuck-that money” over the chance of getting lots of “fuck-you money”. www.honeybadger.io/blog/f-ck…

An easy and secure way to launch helper scripts in a project

On one of my recent live coding streams, a viewer asked what my abe script does. I showed that it simply launched a Ruby command in my project’s application container. Since I’m using Docker Compose to spin up most of my development environments, I have to run all development tasks within the application container. Typing abe rake test is much faster than typing docker-compose exec app bundle exec rake test, so I added this script to my project’s bin directory:

docker-compose exec app bundle exec $@

It’s a nifty time-saver, but the smart part of this isn’t the script itself but how I make helper scripts in the bin directory of my projects easy to launch without having to prepend every command with ./bin/.

If you’re familiar with how a Unix shell finds the right program to execute, you ’ll probably suggest just adding ./bin to the environment variable PATH. But that’s a risky move because you don’t want to accidentally launch a malicious script after checking out a repository that happens to have an executable ls command in its bin directory.

Once again, it was the talented devs over at ThoughtBot who found a better solution. Instead of adding ./bin to PATH, they recommend adding .git/safe/../../bin. With this entry, the shell descends into .git, further down into safe, all the way back to the repository root and only then into bin. What makes this seemingly roundabout way to find your helper scripts secure is that it only works if you’ve first manually created the subdirectory safe within .git. The latter is, after all, git’s data directory which normally doesn’t contain a directory named safe.

There you have it — easy access to your project’s helper scripts is simple to achieve. And without any additional effort, it’s safe as well!

If you have any questions or would like to discuss a topic, tweet me @geewiz or join the chat on my Discord server!