GeistHaus
log in · sign up

https://sonnet.io/feed.xml

atom
39 posts
Polling state
Status active
Last polled May 19, 2026 04:38 UTC
Next poll May 20, 2026 01:23 UTC
Poll interval 86400s
ETag W/"0762092dd327967686e579ed6c2e060b"
Last-Modified Fri, 24 Apr 2026 20:27:34 GMT

Posts

***
Show full content

I remember the first time I drew a face. It looked like this:

a face

I was sitting on the slope of a hill overlooking my house, together with my older cousin. It was a late summer afternoon: still warm, with the grass still golden, but slowly turning red, the air smelling like honey and beeswax. He drew first. I followed.

That's how I draw faces now:

a face

I also remember the first letter I ever wrote! It looked like this:

an r

I drew it on a wooden plank with a flat red carpenter's pencil. The shape of the lead and the texture of the wood made it hard to draw curves. You had to go in straight lines and press just a little bit so the lead didn't sink into the pulp.

I drew it in the room where all of us slept and watched TV. The light was crisp (with the shadows freshly chiseled) and the air smelled of spring and tobacco. My dad wrote first. Then I followed. This is how I write now:

a hi

Hello! says the impostor syndrome (nihilism kicks in): I'm none of the things I wanted to be between then and now. I still draw the same face and I still write the same «ر».


Still, none of the faces I draw look like this:

(Click to continue)

There was an error, that's ok. Try again or find a mirror. Don't worry, I can't see you.

And, none of the notes I write look like this:

Calligraphy
Calligraphy (written with a reed pen)

Or this:

Calligraphy
Calligraphy (written with a reed)

But then, I draw a little face on a rock and you smile.

I write you a card and you read my name, rolling your Rs.

[hidden] > * { display: none; } .cannot-see-you-message { position: absolute; bottom: 0; z-index: 1; left: 50%; translate: -50% 0; font-size: 1.25rem; } .preview-container { --aspect-ratio: 3/4; background-size: contain; position: relative; aspect-ratio: var(--aspect-ratio); margin-left: calc(var(--page-margin) * -1); width: calc(100% + calc(var(--page-margin) * 2)); animation: preview-container--enter 1s ease-in-out; } @keyframes preview-container--enter { from {opacity: 0;} to {opacity: 1;} } .preview-container::before { content: '.'; position: absolute; top: 50%; left: 50%; translate: -50% -50%; animation: preview-container--loading 1s linear infinite; font-size: 3rem; } @keyframes preview-container--loading { 0% {content: '.';} 20% {content: '..';} 40% {content: '...';} 60% {content: '....';} 80% {content: '.....';} } .preview-container::after { content: ''; display: block; position: absolute; inset: 0; background: url('/images/face/mirror-vertical.webp'); background-size: contain; pointer-events: none; } @media (min-aspect-ratio: 1) { .preview-container { --aspect-ratio: 4/3; } .preview-container::after { background-image: url('/images/face/mirror.webp'); } } .preview-container .error-message { position: absolute; left: 50%; top: 50%; translate: -50% -50%; background: white; color: black; padding: 2rem; font-size: 2rem; text-align: center; border: 2px solid black; visibility: hidden; } .preview-container .error-message button { background: black; color: white; border: none; font-size: 2rem; padding: 0 0.5rem; cursor: pointer; border-radius: 0.5rem; box-shadow: 0 0 0 0.2rem black; line-height: 1.3; cursor: pointer; } .preview-container button:hover { opacity: 0.8; } .preview-container .embed { width: 100%; height: 100%; position: relative; opacity: 0; transition: opacity 1s; } .preview-container .embed.is-active { opacity: 1; } .preview-container video { position: absolute; inset: 10%; width: 80%; height: 80%; visibility: hidden; object-fit: cover; filter: brightness(1.4) contrast(4.3) saturate(0); transform: rotateY(180deg); } .preview-container-video-overlay { position: absolute; inset: 0; background: var(--color-bg); mix-blend-mode: multiply; opacity: .3; } .preview-container__spacer { width: 100%; height: 100vh; } const umami = window.umami || { trackEvent: () => {}, } const previewContainerEl = document.querySelector(".preview-container"); const ctaEl = document.querySelector(".preview-container-cta"); const retryButtonEl = document.querySelector(".retry-button"); const videoEl = document.querySelector(".preview-container-video"); const errorMessageEl = document.querySelector(".error-message"); let hasPlayedOnce = false; document.querySelectorAll(".next-step-button").forEach((el) => el.addEventListener("click", (e) => { e.preventDefault(); e.target.hidden = true; }) ); const getVideoStream = () => { if (!videoEl.paused) return; return navigator.mediaDevices .getUserMedia({ video: true, }) .then((stream) => { videoEl.srcObject = stream; return videoEl.play(); }); }; const requestVideoInput = async () => { try { errorMessageEl.style.visibility = "hidden"; await getVideoStream(); const embedEl = document.querySelector(".preview-container .embed"); embedEl.classList.add("is-active"); if(hasPlayedOnce) return hasPlayedOnce = true; umami.trackEvent('mirror-play'); } catch (error) { umami.trackEvent('mirror-error', {error: error.message}); errorMessageEl.style.visibility = "visible"; } // pause the video when videoEl is not in view const observer = new IntersectionObserver( (entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { getVideoStream(); } else { if(!videoEl.paused) { videoEl.pause(); //unload the video stream from the element videoEl.srcObject.getTracks().forEach((track) => track.stop()); } } }); }, { threshold: 0.5 } ); observer.observe(videoEl); }; const handleCTAClick = (e) => { e.preventDefault(); previewContainerEl.hidden = false; document.querySelector(".faces__step-1").hidden = false; videoEl.style.visibility = "visible"; ctaEl.style.display = "none"; previewContainerEl.scrollIntoView({ behavior: "smooth", block: "center", }); setTimeout( () => { requestVideoInput(e); document.querySelector(".preview-container__spacer").remove(); } ) }; retryButtonEl.addEventListener("click", (e) => { umami.trackEvent('mirror-retry-click') handleCTAClick(e); }); ctaEl.addEventListener("click", (e) => { umami.trackEvent('mirror-click') handleCTAClick(e) });
https://sonnet.io/posts/face/
Hummingbirds are Evil! Procrastination, Laziness and Play
Show full content

Today I want to talk about three of my favourite spicy words: procrastination, laziness, and play. Hopefully by the time you’ve finished reading, you’ll see them in a more useful light. And, if I do my job right, you’ll leave this post a little bit lazier, and slightly more playful.

Along the way, I will also try to smuggle in some tips on how to work with yourself when tackling a design problem.

This is by no means a prescriptive guide and, in keeping with the article’s theme, I hope to leave you with more questions rather than strict answers. I’ll try to keep it low on jargon, and relatively high on personal introspection. Here’s why: we learn more efficiently through stories, and from people who communicate by setting an example. With that out of the way, let’s get started!

TODO

When it comes to personal projects or any work where I have more control over my time, my process looks sometimes like this:

  1. Work on something important
  2. Procrastinate
  3. Work on something less important, but something I care about
  4. Once I get the kick from doing 3., go back to 1., rinse and repeat…

I had mixed feelings writing down this list. It’s hard to avoid judgement when talking about procrastination, especially because we tend to equate it with “laziness” or apathy. But procrastination is an avoidance mechanism and a form of self sabotage, and laziness does not exist.

Procrastination

A simple round face with a neutral expression. It looks a bit like a cheap 1960s Soviet cartoon

Research on procrastination contradicts the common belief that it's a symptom of “poor conscientiousness” and laziness. Instead, as it turns out, procrastination has everything to do with emotional regulation .

So, why and how do we procrastinate? We might be afraid of failure or (more likely) of how daunting and complicated a particular task might look, so we keep postponing our work, and trade temporary relief for increased difficulty in the future. Or, we might be unable to manage (or even accept) the way a certain task makes us feel, leading us to search for endless distractions instead. This is where the emotional regulation issue comes in—we’d do anything to avoid feeling our painful, complicated emotions. Even if that means doom-scrolling to the bottom of Twitter or the Orange Website as our work inbox fills up.

But this is, of course, counterproductive and every time we avoid facing this little monster, we feed it a bit, and make it stronger.

This gets worse if you have a tendency for perfectionism, a term which, thankfully we’ve mostly grown out of in a professional context. Perfectionism, by definition, is all or nothing. And, since all or nothing is a pretty high bar, this is also where self-sabotage comes into play.

Self-sabotage happens when instead of facing the problem, we put ourselves in a situation where we’re unlikely to succeed. Let me illustrate this with an example:

A long time ago, when Sun was god and people still spoke in ActionScript, I was taking exams to determine which uni would have me. My grades were OK and with a bit of work I could get where I wanted, so naturally I took 2.5x as many exams as I needed, which in fact reduced my chances of getting anywhere. I did it purely because I couldn’t stand the idea of failing at the “normal” level. This is obvious in hindsight, and obviously nonsense.

Self-sabotage allows us to say: we’ve failed not because of us, but because of the world around us. It’s not us who are inherently broken.

“New Yorker humour”
Laziness, or, why hummingbirds are evil

Laziness is a huge subject, involving evolutionary biology, neuroscience, psychology, religion, politics, and make-believe. Naturally, I can’t do it justice in a few paragraphs. So, instead of getting bogged down in the details, let’s play a round of Laziness Bingo™.

OK, here are the results: it seems like 90s kids with ADHD, people with mental illness, the homeless, people in their 30s, and immigrants are all lazy. Laziness is an umbrella term we apply to things and behaviours we don’t—or don’t want to—understand.

Can you think of a single example of a real and truly lazy person you know? By that I mean, someone who’s inherently lazy, without any extenuating circumstances like mental illness. A good heuristic for answering this question usually looks like this:

  1. Rephrase your sentence as a news headline: Is <placeholder> lazy?
  2. Apply Betteridge's law of headlines

Another useful tool for this is Emotive Conjugation, which predicts that we’re more charitable when explaining our own behaviour vs. the behaviours of others.

And then there’s also a darker, more manipulative aspect to the concept of laziness, the ability to other anything it touches. That’s how immigrants can somehow be both lazy and out to steal all the jobs, depending on which side of the imaginary line in the sand you stand.

Anyway, so why are hummingbirds evil? Because despite their ridiculously high energy demands, they still do fuck all once they’re satiated. And, as you know Idle hands are the devil's workshop (Proverbs 16:27).

Hail Satan
Just sit down and get to work (or YMMV)

You might’ve heard about Sitzfleisch—the ability to just sit down on your butt and keep going. There’s no doubt that it’s an important skill, especially now, when we're bombarded with distractions and our attention spans are getting shorter and shorter.

However, in my case, it’s more of a red herring, a Sitzfisch if you will. Once I finally start working on something, I find it relatively easy to stay focused or to push myself, sometimes for hours, but it doesn’t always mean I get more done this way. On the contrary, the mistake I often make is overcorrecting for Sitzfleisch by spending too much time on a single task, and getting burned out.

It seems a bit like the opposite of the self-sabotage example from above, but in fact it’s a very similar mechanism: I do it so I can tell myself I did my best. If you’re reading my blog chances are you can relate.

Work and play

I cringe a bit when I hear someone using the verb play in a work context. The reason for that is twofold:

First, it’s a bit sinister. In corpo-newspeak words like this are used to manipulate people into working harder than they should, or working on something they wouldn’t otherwise want to work on. This form of fake playfulness, even infantilization, is usually directly proportional to how much VC money is poured into the business and inversely proportional to the actual value it creates.

Here’s an example:

We might be selling ads, but you, pal, you’re #deliveringwow. Now pass me the nerf gun and let’s head to the Clubhouse! unnamed, but real, employee of a London ad tech company

This also makes for a much more interesting story when your friends or family (or you) ask yourself what you do for a living. You’re not working, you’re just having good old fun™. You must be special. Have a cookie.

The last paragraph is particularly important here. Just like with laziness, our definition of play doesn’t hold up to scrutiny once we stop and apply critical thinking.

First, playing to many of us means doing something inherently useless, and perhaps this is why play can seem counterproductive from an evolutionary standpoint. But is it inherently useless? For most of what we call “the West” (and most of this planet, believe me or not, is not West-centric) the answer might not be that obvious.

In fact, playing is a universal behaviour shared by humans and animals, serving a plethora of different purposes ranging from improving motor coordination, practice, bonding, managing stress, developing and improving cognitive skills, reinforcing or organising social structures. (This does not apply to seals. Seals, unlike hummingbirds, are actually evil.)

Predictably irrational

A broken clock once said: we’re irrational creatures, but the beautiful part is that we’re predictably irrational. Know your flaws and set up systems to help account for them. In other words: it’s not your fault that you feel a certain way, but it’s your responsibility to act when you can.

For instance, the answer for me, sometimes, is this: If you can, work on something you care about. If that’s hard, try to find something smaller to care about and don’t worry if it seems a bit trivial. Still nothing? Look for something even smaller you can fit in your schedule.

Intrinsic motivation always trumps external motivation when it comes to creative work. When you care about something, it’s easier to push yourself out of your comfort zone, e.g. message someone with a crappy demo of your project asking them for feedback, pick up a new piece of tech or learn about my personal nemesis: marketing. Intrinsic motivation makes it easier to think in terms of what’s possible vs. what could go wrong.

I am terrible at working on things I don’t give a shit about. Luckily, the list gets longer every year. But I realised very late how much stress I was causing myself by brute-forcing the problem instead of trying to understand it better.

If you grew up without financial security or under pressure to perform better than your peers, you can probably relate.

The key here is balance: if I recognise that I’m getting bored and it’s hard to focus when working on Number 1. (the important thing on our list), I try to work on Number 3. (the thing I care about), instead, reducing my chances of falling into the familiar procrastination-self-doubt-apathy cycle.

This is hard and doesn’t always work, but that’s still perfectly fine since every failure is a stepping stone if we take time to reflect on it. Accepting that is a part of work. When my amygdala is screaming danger, you’ll fail! I still have to remind myself that my choices are not motivated by defeatism, but patience.

The balancing act is a skill like any other – just like learning a new language, playing an instrument or juggling.

Closing words

We gonna turn frustration into inspiration
Whatever demons are there, we gonna set them free Gogol Bordello, Tribal Connection

Once we stop for a second and approach these behaviours without being distracted by judgement statements, we can work around them. Or, even better, we can work with them .

In my case, this took the form of attending therapy, swapping social media time for daily writing, building mental health friendly tools like Sit., or Ensō, and spending more time with my family and friends. You’ve read lists like this 100s of times, and the reason they don’t work is the same reason they exist: the way you build yours will be different from the way I built mine.

So, here’s my only piece of advice:

Learn to recognise your patterns.

Consider self-judgement a warning signal that your perspective might be flawed.

With the above in mind, let’s fix our list!

  1. Work (on something important)
  2. Rest (get bored)
  3. Play (with something you care about… or not!)
  4. Rinse and repeat…

I hope you’ll be able to set those demons free. Trust me, I was a middle-school satanist.



PS. Alexandra Ciufudean edited and translated this article into human.

https://sonnet.io/posts/hummingbirds/
Short: WiP
Show full content

“Are you pondering what I’m pondering?”
“I think so Brain, but I still don’t understand why commit messages would matter?” Unaired episode of Pinky and the Brain

For reasons beyond the scope of this post, I spent a possibly unhealthy amount of time watching Pinky and the Brain as a kid. It wasn’t too bad. ORF, the main Austrian broadcaster also aired the German version of Teletubbies shortly before, which I consider my first psychedelic, although unpleasantly so, experience. Wait, where was I… Ah, yes, here are some quick, practical tips on how we can apply two different modes of thinking when iterating and committing our code, sponsored by ACME.

Poorly drawn characters from the Ponky and Bron-a cheap knock off of a famous cartoon from the mid 90s. Both assumed very dramatic poses, with a 1000 mile stare. Ponky says 'I have glimpsed into the abyss' to which Bron, who looks a weirdly similar to Werner Herzog, replies with 'And thus, Ponk, you saw a deep ocean of chaos and darkness'.

Commit often when you’re exploring the problem (divergent thinking) but use structure when you know where you’re heading (convergent thinking). When you diverge you want to prioritise quantity over quality, make mistakes cheap, and fun.

Pinky is our divergent process, Brain is the convergence. Let's see how we can apply this to our work.

Brain

Consider using Conventional Commits and a commit message linter. In tandem, these tools force you to adhere to a relatively strict format of commit messages, including:

  • the type of the change (“feat”, “fix”, “chore”, “wip”) and,
  • a terse description of the change itself.

So, no more cryptic messages like “cosmetics”, “typo”, “cleaned” in your history1, but “feat(sign-up): add the CTA”, “fix: remove typos in the header”, “chore: update leftpad”. Your colleagues and the future You will thank you. Small improvements like this go a long way.

These tools reduce the number of things you’ll need to care about when saving your work, play nicely with semantic release, and provide some uniform structure in shared codebases.

But, what I like about them the most is that if you can’t come up with a good commit message, it’s probably a signal that the changes are either too broad or not focused enough.

This is why I follow the Conventional Commits style for all of my projects, even the ones small enough where installing the tooling would be an overkill.

Key takeaway:

Impose limitations and repetition to keep focus. Make your code rhyme.

Pinky

At the same time, when the chunk of work is really tiny and doesn’t merit a description or I’m just exploring different solutions, I commit and push my changes every few minutes.

The process often looks like this:

  1. draft some changes, add a bunch of smaller wip commits
  2. deploy to a test env or re-run a local build, rinse and repeat…
  3. once the code looks good, and the tests pass, squash all wip commits and push to production

Disclaimer: For more complex, serious work, I replace step #3 with removing all code and writing it from scratch using TDD. Check GeePaw Hill’s Intro to Spikes for details.

Key takeaways:
  • prioritise short feedback loops
  • quantity > quality

With that in mind, I don’t want to spend half of that time crafting my perfect commit message, so I made myself this little snippet:

    wip () {
git commit --no-verify -m "wip: $*"
}

Here’s how I use it:

    $ ga . # stage working changes
$ wip yak shaving # commit as wip: yak shaving

How to install it:

Either paste it in your .zshrc or add it to your PATH environment variable. Feel free to copy it from my custom dotfile .

Summary

Understand the two different modes of thinking when exploring and narrowing down the solution. Either automate or use repetition to the point where you can just run things on autopilot. Keep the feedback loops short and make mistakes fun. Brain works, but Pinky plays.

PS. Alexandra Ciufudean edited and translated this article into human. She also came up with the idea of using my childhood trauma one of my favourite cartoons as a metaphor.

Footnotes
  1. These are real examples found after spending less than a minute sampling the commit history of a randomly selected project.
https://sonnet.io/posts/wip/
Sit.
Show full content

In this article I’ll be using Sit. as an excuse to talk about some wider ideas (motivation, mental health, iterative design processes). We’ll explain why it came about, but not how. In part 2 I’ll show you how to take an idea from a hunch into a working app. Stay tuned!

Before you read on, open the app and check it out for yourself. It shouldn’t take more than 1–2 minutes and if it does I’m certain it’ll be time well spent.

This page isn’t going anywhere, I’ll wait for you here.

A long (2-3 screen heights) red thread. When you follow it, you notice that in the middle it turns into text 'keep scrolling'. At the end of the thread there is a head on which the thread rests, forming a tiny messy pile.

Glad to have you back. Did you cheat?

Sit. is a brutally simple alarm clock, not much more complex than an egg timer. You choose a length of time to just sit in silence, set it and forget it. When that time is up, a gong gently brings you back and then repeats every minute until you switch it off – so you don’t lose track of time.

Some people (myself included) use it to meditate, but there really is no right way of enjoying it.

To be fair, “just sit” is also a famous zen koan. But regardless of the reason, as long as I can get you to sit down on your ass for a moment and stop trying to be productive, I’m a happy man.

Sidenote: why do we say “brutally” simple and not, say, “elegantly” simple? The selection process of building things like this app could be considered “brutal”, but we don’t call poetry or mathematics “brutal” where both areas are essentially an art form based on seeking simplicity.
We don’t really say, “Did you read that haiku? Was it brutal?”, do we?

I’ve always loved the idea of simple, atomic (as “indivisible”) tools, objects with a brütally™ simple purpose. They’re easy to explain, you can stack them like legos and compose. Sit. is an exercise in that.

Some of my other projects, like Ensō, Façade, and the goat telling me to slow down when I talk too fast, also follow the same principle. So let’s focus on the specifics: why are we talking about Sit., and not, say, Squanch?

Reason #1: Time

"Live Slow, Die Old"
an ancient Doom Metal koan

In the past decade the Web has become a sort of a shitty metaverse. Every step you take is watched and assessed in terms of its monetisation potential, every interaction is meant to extract value from you. Fine, IndieWeb and Mastodon are making things marginally better, but there’s so much more to be done outside of their little bubbles (which I love dearly).

A messy hand-drawn illustration with a variety of characters screaming at each other using cheesy social media hashtags or conspiracy theory quotes (e.g. "peppa the pig did a nazi salute!", "#blessed", "I have no mouth but I must scream").
An artist's interpretation of my Twitter feed, the colours depicted are not accurate.

Just like advertising, which assumes consent by default, most of the Web in its current shape robs you of your time. You can withdraw consent, but only after we’ve shown you the brain parasite.

So, most of the Web is a time/money/attention grabbing machine. It’s Sting walking behind you humming Every Breath You Take. We’ve established that.

What I wanted to build was the opposite. I wanted to give you a little of your time back. That’s why when you open Sit., there are only two things you can do:

  • close the tab, or
  • sit down on your butt and watch the grass grow

I hope you chose the latter. If not, I do hope that since you've read this far I’m giving you something worth your time. Just like anyone else I want to feel useful.

An unfinished drawing of a foot. It's done using a single line which takes the shape of a foot, but eventually turns into a scribbled text saying 'ah whatever fuck it' followed by a poorly drawn logo of a bird, flying away. The bird looks a little bit like the logo of Twitter.
Have you ever wasted 10 minutes of your life scrolling through Twitter, only to forget why you’re there in the first place? Spoiler: you were looking for something else, but got lost on the way.

A funny thing can happen when you use Sit. When you just sit and do nothing, every minute drags on into what feels like infinity. But when you mindlessly watch TikTok or doomscroll through Twitter on the other hand, hyperspace seems to bend in the opposite direction: I blink and the pasta is overcooked, I blink again and the light in the kitchen is different, cooler, the shadows have moved. Are we really alive if we’re not here?

When you open Sit., I don’t try to fill your brain with anything. It’s just you and your thoughts. That can get uncomfortable. But when you finish, for some strange reason you feel better.

Alternative title for reason #1: the time I want back.

The two other reasons I built Sit. are more trivial and less likely to generate a rant.

Reason #2: Motivation

I’ve decided to drop full time work and move back to personal projects, which means I’m still figuring out a structure for my day, which means it’s easy to get stuck in a rut.

You see, I suffer from a condition known as irony deficiency: even though I preach simplicity when mentoring or running workshops, I struggle with the very same thing in my own practice. Speak with your GP if these symptoms seem familiar.

After a few days of running around in circles, I decided to take a detour and build something else to boost my morale a bit, ideally something so small I couldn’t afford not to finish and share it (hold that thought, we’ll get back to it in the second post).

The most prolific and creative people I know get their boost of motivation from projects with a short feedback loop. This way they can have contact with the user, and watch as their work is enjoyed by others or at the very least interacted with. Building things for others is a form of communication, and it fulfils a very basic human need.

Iterative methodologies like Agile are not only useful because they allow us to split problems into smaller, more testable chunks, bringing us closer to the essence of a problem. There’s also a mental health and motivation aspect to it which honestly deserves its own article.

Alternative title for reason #2:
I’m stuck, pass the shovel, not this one, the small one.

A simple border made of a bunch of tiny shovels in a row, forming a horizontal line. One of the shovels is gold.

Reason #3: Black dog

The final reason will sound trivial, but it’s one of those trivial things worth repeating till they’ve finally carved into our brains: mental health is important.

I’m interested in mental health both from a professional and personal point of view. I’m not a therapist or a qualified medical professional, so I try to help using the skills I have. The areas where I can contribute somewhat usefully took the form of my work on privacy, using music and psychedelics for therapeutic purposes at Wavepaths, and writing tools supporting mental health in my spare time. The beauty of building those (digital) tools for myself is that it costs 0$ to share them with others.

Rant: It just feels perplexing how preoccupied we are with sending people to a dead rock 138600000 km away by treating some random tech bro like your favourite football team, where at the same time we have 1000s of Curies, Teslas, Newtons worth of human potential, brain power which could be unlocked with sometimes relatively little work. Those people are not 1 au away. Yet, we fetishise those who make us miserable instead.

There’s so much low hanging fruit here.

Reason #3.1: I have very specific clock needs.

I don’t want to be wise. I want to be clockwise.

But seriously now. Another big reason why Sit. is built this way is habit reinforcement. Preventing issues is easier than crisis management once the black dog pays a visit.

I try to meditate every day in the morning. For me it’s a form of mental hygiene and a “spiritual” practice only in terms of connecting with something bigger than us (nature, not religion). One of the types of meditation I practise, called shi-nè, is quite challenging because it involves learning how to detach yourself from the voice in your head without focusing on anything else in particular like breath or music.

A red ballon with a face peeking out of a hole in the ground, looking up longingly towards a bunch of tiny people, dressed as if they were going to work, holding suitcases. One of those characters looks like an angel. They have little pieces of thread attached to their feet, which makes them resemble balloons.
Be comfortable with being, sitting down, uninvolved.
There’s no anchor, but there isn’t anywhere to go, either.

The simple instruction for shi-ne is to maintain presence of awareness without focusing on anything, that is, remain uninvolved with whatever arises in mind source

The point here is that this can quickly get both frustrating and boring. Our brain constantly looks for things to focus on, it abhors a vacuum. So the positive effects of this exercise take time to manifest. And maintaining a habit that initially feels unpleasant is hard.

Remember earlier when I said that although sitting down and doing nothing can be unpleasant at first, when you finish for some strange reason you feel better? It turns out, you benefit from habits more if you take some time to reflect on them after you’re done. It also makes them easier to stick, by teaching us to associate reward with an initially annoying activity.

A red ballon with a face peeking out of a hole in the ground, looking up longingly towards a little black hole in the ceiling. It looks as if another balloon just escaped through that hole, since we can still see a little thread in it. Perhaps it's the same baloon, looking at himself from the past.

That’s why the timer in Sit. is gentler than a regular snooze button. It lets me wind down and reflect without aggressively throwing me back into my regular routine like an alarm clock would. And it gives me more control over my meditation schedule: I still know how much time has passed but I can afford to spend another minute or two on it .

Alternative title for reason #3: The fact that I keep snoozing is not a bug, it’s a feature!

Closing words (for now)

How did it go?

Screenshots of feedback and testimonials given by the users of Sit. The feedback is overall very positive and people seem happy that they had an excuse to rest for a few minutes. Most of the men commented asking if Sit could also provide additional features such as standing. I feel like they're missing the point.

So far the users of Sit. “wasted” a combined few days’ worth of work by sitting down and doing nothing. Someone wrote a short article about it, and I received warm comments from people who apparently needed to be distracted from their distractions.

I put all of those wasted minutes together into one imaginary person. Imagine you sent someone you like on a spa vacation for a few days. Now imagine that that hypothetical person is a perfect sphere.

A large pink circle, with a tiny face in the middle. It has rosy cheecks.
A human

Listen, I know it’s not rocket science, I know it’s a small thing. But knowing that somewhere, someone sat down, watched the grass grow and had time for themselves instead of doomscrolling or crafting a world-altering post on LinkedIn… It made me feel better and let me get out of my own head. We’re simple folk here, with simple, yet mysterious needs.

Next steps

You’ve probably noticed that Sit. was an excuse to talk about wider ideas.

In the next article I’ll use Sit. to introduce to you my rapid prototyping workflow. It's a multidisciplinary process involving user research, Human Centred Design, and code.

If you want to see how to turn a hunch into an idea, and then an idea into a working piece of software used by actual people, stay tuned!

I also offer free office hours, where I talk to random people about ideas big and small, pair program or rant. If that sounds like your cup of tea, come and say hi or book a chat!

And remember: every minute spent in Sit. is $0.01 Mark Zuckerberg can't spend on metaverse.

PS. This article wouldn’t be possible without Alexandra Ciufudean who translated it into human.

https://sonnet.io/posts/sit/
Emotive Conjugation
Show full content
.post { --pickle: #959e00; } .emotive-gpt-3 { padding: 0; margin: 0; } @media all and (min-width: 430px) { .emotive-gpt-3 { padding-left: 3rem; } } .emotive-gpt-3 p{ font-style: italic; font-size: 1.75rem; } .emotive-gpt-3-legend { font-style: italic; } .emotive-gpt-3 em, .emotive-gpt-3-legend em { font-weight: 600; color: var(--pickle); } :is(.emotive-gpt-3 em, .emotive-gpt-3-legend em):before { /* content: '🥒 '; */ } .emotive-rant{ transition: 1s all; opacity: 1; } .emotive-rant--hidden{ display: none; opacity: 0; visibility: hidden; } .emotive-rant__cta{ appearance: none; background: none; border: none; color: var(--color-text); font-weight: 600; cursor: pointer; font-style: italic; text-decoration: underline; } .emotive-rant__cta:hover, .emotive-rant__cta:active { color: var(--color-link); } @media all and (min-width: 700px) { .post__content .post__quote--pickled { position: relative; margin-left: 0; padding-left: 11rem; } .post__content .post__quote--pickled:after{ content: ''; background-position: 0 bottom; background-repeat: no-repeat; background-size: contain; background-image: url('/images/emotive-conjugation/quote-bg.png'); bottom: 0; height: 100%; left: 0; position: absolute; width: 10rem; z-index: -1; } } document.addEventListener('DOMContentLoaded', () => { const el = document.querySelector('.emotive-rant__cta') el.onclick=()=>{ el.remove() document.querySelector('.emotive-rant').classList.remove('emotive-rant--hidden') } })

I am firm, you are obstinate, he is a pig-headed fool.

Also, good morning/afternoon (wherever, whenever you are)!

Here’s something you’ve never heard before: we’re more charitable when explaining our own behaviour vs. behaviour of the others. Emotive conjugation illustrates that by mimicking the grammatical conjugation of irregular verbs. Here’s an example:

A comic strip describing the reasons why the main character forgot to buy pickles for dinner. "I was busy" says the main character. "You were distracted". "He is just an idiot"

The term was mentioned for the first time in the 1940s by Bertrand Russel, during a BBC radio show called The Brains Trust.

As you can already see, emotive conjugation is a tool that allows us to express attribution bias using quasi-grammatical rules. Nifty! Put that in your mental model catalogue, Farnam Street.

GPT-3

A true 0.1x engineer is a lazy one. So, let’s shove some instructions into GPT-3 to see what happens. We’ll start with some prompts and tweak the settings a little bit:

First attempt

Note: Prompts are in cursive, and the completed text is in bold.

I am firm, you are obstinate, he is a pig-headed fool.
I am righteously indignant, you are annoyed, he is making a fuss over nothing.
I have reconsidered the matter, you have changed your mind, he has gone back on his word.

I was tired, you were lazy, he was a slacker
I was busy, you were unoccupied, he was idle.
I was motivated, you were uninspired, he was apathetic.

I forgot, you neglected, he ignored

Examples improved

We’ve increased the temperature a bit and added a small frequency penalty to get slightly diverse input.

My idea was groundbreaking, his was unoriginal, and yours was just stupid.
I’m an excellent driver, you’re a terrible driver, he’s the worst driver in the world.
I was excited, you raised your voice, he was shouting.
I am curious, you are interested, he is nosy.
I am trying to be reasonable, you are being stubborn, he is being obstinate.

I'm a 10x developer, you're a 5x developer, he's a 2x developer. (fair enough)

I'm always right, you're always wrong, he's always wrong.
I'm the best developer in the world, you're the second best developer in the world, he's the worst developer in the world.

My implementation is perfect, yours is inadequate, his is completely wrong.
I was thinking about the problem, you were daydreaming, he was asleep on the job.
I am not going to stoop to his level, you will stoop to mine, he will wallow in the gutter. (sic!)

My idea was groundbreaking, his was unoriginal, and yours was just stupid.

Side note: it’s amusing that mentioning a 10x dev resulted in the following prompts being quite toxic. Who would’ve thought?

Greek philosopher, with a pickle for his head, holding a pickle-themed artefact in his hand
A true 10x developer

Brilliant! We’ve successfully automated that one guy in your office emotive conjugation. I must admit, I’m much less pessimistic about using GPT-3 as a copy generation tool. Here’s the preset, in case you wanna give it a go.

Please remember, this is a powerful tool, and we should use it irresponsibly. And, to use it irresponsibly, we need to learn how it works.

Attribution bias

Two identically looking men. The first one is pointing at himself saying "This is me all right (two words)". He uses his other hand to point at the other man and say "This is him, alright" (one word).

Chances are you’ve heard about attribution bias before. The general idea is that we constantly make attributions: judgments and assumptions about why people act in a certain way. We tend to be much more compassionate when judging our own decisions than the choices or actions of others.

Some familiar examples of attribution bias might involve a driver cutting you off abruptly (He’s reckless! Why doesn’t he drive the way I do?!), or… a fellow engineer, hidden behind the lines of git diffs in your code editor, with their pythonic incantations invoking the wrong[...] click to expand rant., forbidden abstractions, throwing at you nothing else but the cursed spaghetti, which now you, the 10x engineer in a shiny full plate armour, need to fix. Why didn’t they think of using Typescript? How come they didn’t read that carefully crafted tweet you wrote about co-locating code? And, what’s the point of passive-aggressive messages on Slack if no one pays attention? Didn’t they hear that the old Object-oriented gods are dead, their temples and towers toppled by the blinding light of lambda calculus? Our Church was built and named after its founder. Hey, are you still listening?

Humans are social creatures, and I like to think that we’re not inherently as selfish as the media soup would like us to think. Most of us don’t think less of others, but we have a tendency to take cognitive shortcuts.

For example, instead of malevolence, attribution bias could be partially explained by a lack of data: we don’t know that the driver who cut you off was tired or stressed, or that the engineer whose commits you were about to criticise was in fact you.

A comic strip describing two worms or snake complaining about each other’s work, while being in fact a single, two-headed snake

Ghost in the /bin/sh

Now, if you’re a software engineer or anyone collaborating with people on solving a problem where the solution changes as often as your understanding of the problem, where people come and go, and the problem is wicked, you’ll quickly learn that:

  1. writing code is easy, but
  2. reading code is hard, because
  3. 9 out of 10 times your work is communication, and
  4. most of the time you’re communicating with ghosts.

You’re communicating with ghosts, because they’re not here and they’re not now. The artefact in front of you lacks the context of the thought process of the person coming up with the solution, with all of its undocumented details and constraints: they were working with a legacy system, they had to rush, they were afraid of looking stupid (so they over-abstracted everything), they were tired. In a sense, this problem is as old as writing itself (assuming that the god Teuth gave us writing):

And when they [thoughts, ideas] have been once written down they are tumbled about anywhere among those who may or may not understand them, and know not to whom they should reply, to whom not: and, if they are maltreated or abused, they have no parent to protect them; and they cannot protect or defend themselves.

— Jowett, Benjamin. The Dialogues of Plato in Five Volumes. 3rd ed. Oxford University, 1892. Vol. 1, pp. 483–489.

In other words, hips don’t lie, and the code you wrote communicates the complexity and the meaning of your work in a very shallow way. And that’s just the nature of the medium. Still, your code will have to defend explain itself regardless.

Why should we care? Two reasons:
  1. Blaming others is a waste of energy.
    You could’ve avoided that (surprisingly) complex rewrite if you had spent more time thinking about the reasons the code looks this way, instead of assuming they didn’t know better.

  2. You can get better at this.

People are prone to cognitive bias because without them it would be impossible for our brains to make efficient predictions and to reason about the plethora of sensory stimuli surrounding us. The engine cannot be completely changed but it can be improved with a bit of practice. For instance, research conducted on students shows that attributional retraining is tied to better performance. These improvements were especially noticeable when looking at students who used to explain their failures with external factors, and particularly those who used to work in more competitive environments.

Attributional retraining mainly involved encouraging controllable attributions (I can pass the exam if I study) and discouraging uncontrollable attributions (I will fail, since I always do). Nothing controversial here, since if you want to improve an aspect of your life, starting with yourself is generally a good heuristic. But, I also think that there’s something to say about trust. Human apes have a tendency to fill the gaps in their knowledge with the worst possible outcomes.

After all, the farther apart we are on the Emotive Conjugation Table™, the less we know about each other, and the less likely we are to make kind judgements.

A comic strip describing two worms or snake complaining about each other’s work, while being in fact a single, two-headed snake

In my experience, many of the problems regarding trust or blame got solved when I filled the room with people who generally don’t work together. A prime example would be members of distant teams, usually working through a proxy (e.g. an ops person and an engineer) or a bunch of highly specialised, siloed teams. That’s in part because we’re more likely to give the benefit of the doubt to people we know.

So let’s take a look at a few practical tools that might improve this situation. You will notice many of these solutions also aim at improving knowledge sharing and I believe that’s not by accident. It’s easier for us to empathise with what we know.

Tools

Two consenting pickles sharing a bag of dill

Smell Your Colleague Day™

Are you running a distributed team? Meet at least once a month/quarter. Put a human face on the JPEG-encoded blob of rectangles you talk to in the morning.

Pair development

Try pair programming, or pair development. In a nutshell, pair programming involves two engineers working on a problem together. Pair development means two or more people from different functions working on a problem together. Here’s a quick introduction with more resources about pair development.

If you can’t commit to doing it regularly, consider running an occasional mob-programming session on a Friday afternoon. Pick a weird chunk of spaghetti and untangle it a little bit with your colleagues. Or, be opportunistic and have an engineer and a marketing person pairing on the next release email.

The biggest benefits of pair development take time to materialise (or to be communicated well), but there’s low-hanging fruit. Earlier we said that reading code is a bit like speaking with ghosts. You don’t have to worry about these issues if the ghost is with you here and now (and ideally, alive).

Design Thinking

Learn about any cross-functional methodologies, such as Design Thinking or Human Centred Design and try to introduce them in your work. Again, these are iterative processes and I’d love for you to go through a series of sprints relying on it, but even borrowing one or two tools can help, albeit to a lesser extent.

Recommended tools to start with: User Story Mapping or ideation.

Yes, having people from different functions and backgrounds will save you time due to less LARPing on Slack and that’s fantastic. But, it will also let people see beyond their respective parts of the spaghetti bowl you’re sharing (and there’s only one bowl).

This is a huge topic, so I’m leaving out much, but if you’re curious to learn more, come and say hi!

Cross-team rotations

Try to rotate for a week and work with a different team. Rotating between engineering teams (pods) is the easiest first step. What I found even more useful was to jump between different functions. Spend a week working with the Ops team if your business has one.

Advice for managers: if your organisation had to quickly scale up and you’re struggling with knowledge silos or bottlenecks between teams—this is a really cheap way of ameliorating the problem.

Shadowing

Shadowing means learning from your colleagues by observing their work from up close but without actively participating in it or mimicking what they do. A great chance to try this is your company’s hiring process: a new joiner shadows a more experienced colleague interviewing a candidate. I often shadow product managers or designers conducting user interviews. I am yet to see a case when I’d consider this time wasted.

Closing words

My archeologist friend once told me that working at a dig site is like visiting an empty theatre after the play has ended. Your job is to figure out the title of the play and the only tools at your disposal are the prompts left on the stage and your own curiosity.

And I think this is a very apt metaphor for our work. Everything’s fragmented: the code you’re working on communicates only a small part of the original problem, the people behind it are gone or on a different continent. The requirements are just a game of telephone.

So, if you can take away one thing from this post, let it be this: next time you’re tasked with fixing someone’s antediluvian code mess, try to observe your first natural reaction. Is ranting going to make you feel better? Then, na zdrowie! Rant away! Then cut the author some slack. Chances are it was you.

And if that doesn’t work, fall back to Hanlon’s razor:

Never attribute to malice that which is adequately explained by stupidity.

See you soon!


Credits

Alexandra Ciufudean edited this article and translated it into Human.

The inspiration for this article came from a chat with Morgan Friedman.

A pickle and a tomato in a warm embrace

https://sonnet.io/posts/emotive-conjugation/
useRainbow()
Show full content

Hi there! It's been a long time, I know. I took a break from work and started working on some small, personal projects (toys).

One of those small projects is potato.horse where I keep all of my doodles, visual short stories and jokes. Check it out!

However, this post is not about my break from work, other experiments, or the site itself. People seem to like one particular technique I used in the design, notably, the backround effect applied when the user browses the content:

Some asked me how this effect was implemented (including going as far as reading the minified code, which is very flattering).

So, here's a quick gist, followed up with some context:

export const useRainbowBg = () =>
useEffect(() => {
const cb = () => {
const viewportHeight = window.innerHeight
const contentHeight = document.body.getBoundingClientRect().height
const viewportsPerRotation = Math.min(
3,
contentHeight / viewportHeight
)
const from = 51
const progress =
window.scrollY / (viewportHeight * viewportsPerRotation)
const h = (from + 360 * progress) % 360

document.body.style.backgroundColor = `hsl(${h}deg, 100%, 50%)`
}
window.addEventListener('scroll', cb, { passive: true })
return () => window.removeEventListener('scroll', cb)
})

In short, I map the scroll position into the hue in the HSL colour notation. Let's break this down.

Colour models

There are many ways of describing colours in CSS, with the two most common ones being RGB (left) and HSL (right):

RGB is an additive colour palette. This means that mixing 100% of red, green and blue will produce white, mixing 100% red and 100% green but 0% blue, will produce yellow and so on. This is different from, say, using oil paint or the CMYK colour model, where the resulting tone would be black(-ish)1.

We're used to this approach because it's easy to describe in code but specifying colours in terms of hue, saturation and luminosity seems more natural, especially if you come from a design background, or... you know, are a human being using a human language.

We've gotten used to RGB as developers, but in spoken language using it would feel unnatural and confusing. Façade would be very hard to use in RGB.

On the other hand, HSL can often be much more intuitive to work with. For instance if I want to make a colour slightly colder, I can just move the hue slider a bit towards blue and I should get closer to what I have in mind. With RGB if we make the colour appear colder by including more blue, the resulting tone will be a bit brighter as the blue component contributes to the overall lightness. This means that you'd have to lower the red and green values to compensate.

To see how this works in practice, try maxing out the blue colour in the example below.

The first thing that stands out is that all tones are shifted towards blue and the overall brightness of the picture is increased. In the case of the effect we're discussing, that would be undesirable.

Now, let's try to do the same with the HSL colour circle. Drag the slider to the left, by ca. 90 degrees:

In this scenario using HSL not only turns Susan into a vampire, but also maintains a similar2 level of brightness. And that's exactly what I'm looking for.

So, what did I mean by saying:

How does this work? In short, I map the scroll position into the hue in the HSL colour notation. Rafal, 2 days earlier

I meant that every time we detect a scroll event, I try to map it to an angle on the hue circle:

I didn't want to start with red as it would make me hungry and the base yellow fits the design a bit better, so I applied a small initial shift, hence const from = 51 set as the initial offset.

And, as far as the basic implementation goes, that's it!

Now, there are three other areas of improvement:

Performance

We're triggering a repaint on every scroll, so I was a bit worried that older mobile devices, or even some hi-end laptops plugged in to 4k screens might not be able to maintain solid 60fps. But, I'm happy with the results so far. Using passive event listeners provided a bit of a boost, especially on mobile.

When/if I realise that performance is a problem, especially with more content down the line, I'll probably focus on these areas first:

  • removing the unnecessary call to getBoundingClientRect on every scroll handler call
  • deferring or throttling background colour changes using requestAnimationFrame

I expect the first improvement to have some impact, but the benefits of the second one should be negligible.

Measure before optimising. Obsessing about the performance only makes sense when issues become noticeable, be it through a drop in framerate or battery impact. Your iPhone Pro has more computing power than many low-end laptops, so it's a good idea to test on those devices too. It's good to have a crappy old Android phone exacly for that purpose if you can spare a few quid.

Perceptually uniform colour spaces

You might've noticed that in the previous illustrations some fully saturated colours seemed darker than the others. That's because the colour spaces we use normally when coding don't reflect the way the human eye works. I'll leave the in-depth explanation to someone much more experienced than me, but suffice to say (gross oversimplification alert!) that generally the same amount of red/green/yellow will appear brighter than blue. This means that in some cases the text on the page will be harder to read.

HSL
⬇ ⬆
HSLUV (perceptually uniform)

For now, this isn't an issue as I've just put this thing online and titles serve a secondary purpose. But there's a solution to the problem and it's not overly complicated: use a perceptually uniform colour space. There's a bunch of libraries that do it out of the box, both in JS/TS and CSS/SASS/<pick your CSS flavour here>. hsluv seems like a good starting point.

Accessibility

Note that I'll be focusing on the visual effect itself and not discussing the rest of the site (e.g. alt tags, document structure, etc...). I'd like to focus on contrast, colour blindness and people who rely on prefers-reduced-motion. The site is a living document, there's always so much to improve. For instance, contrast can be an issue in a few, non-critical places. I'm happy to accept feedback and implement it: hit me up!.

Colour blindness

I wanted to make sure that the effect doesn't break the site completely for people with colour blindness. So I focused on the most common types: Deuteranomaly and Protanomaly (red-green colour blindness), but also ran wider tests. I used Photoshop and Colorblindly (Chrome extension) for some rudimentary checks.

prefers-reduced-motion

The prefers-reduced-motion CSS media feature is used to detect if the user has requested that the system minimize the amount of non-essential motion it uses. MDN

This site doesn't contain many animations (besides the Little Sausage Angels you'll see if you hit 'Share'), but I was wondering if people who rely on prefers-reduced-motion would like the background colour to stay constant.

The short answer is: I don't know. My intuition is that rotating colours doesn't really qualify as motion, but my experience and understanding of the problem is, to say the least, limited. In situations like this I'd rather depend on user research instead of guesses.

Luckily, the site had its five minutes of fame on Reddit which proved to be a decent opportunity to collect feedback. None of the users brought up an issue with the background effect so far. I'm also lucky enough to know a bunch of accessibility specialists, such as Sandrina Pereira. Her suggestion was that a) background animations definitely qualify as motion, b) perhaps the effect feels natural because it's a direct result of a user interaction.

Summary

The late 90s/Geocities web felt playful and weird. It was fun in an uninhibited, somewhat less performative, way. I wanted to incorporate some of this look and feel in the site. But still, I didn't want to make it feel esoteric to the point where you'd need to up your hipsterdom-level to 9000 and browse it exclusively throught Netscape 7. All of that, while listening to the new Nirvana: Unplugged.

I still wanted decent UX on mobile and desktop, and some space for easter eggs (something you can't do when living in the strange and abusive relationship with social media we've grown so accustomed to).

As a kid I had build 6 websites before I even got access to the Internet for the first time. Now, after being burned out for 3 years, even considering changing my job, it was the first time I genuinely enjoyed coding. Fuck, I forgot how much fun it was.

Now, go out, pet your cat and make some shit!


PS. Check https://www.cameronsworld.net/

PPS. The code for interactive diagrams can be found here

Footnotes
  1. hence the K component in CMYK meaning black. Using B would be confusing as it means blue in other colour models.
  2. it's not perfect, since the perceptual colour space differs from what's described using RGB/HSL.
@import '/js/use-rainbow/style.css'; .use-rainbow__rainbow{ display: flex; flex-direction: column; } .use-rainbow__column-title { text-align: center; font-size: 2rem; font-weight: 500; line-height: calc(var(--ru) * 2rem); margin: calc(var(--ru) * 1rem) 0; } .use-rainbow__swatches { display: flex; justify-content: space-between; } .use-rainbow__swatches div { height: 3rem; flex: 1; } .example-hue-shift-rgb, .example-hue-shift-hsl { max-width: 35rem; margin-left: auto; margin-right: auto; } Examples.mountExample(Examples.ExampleRGBHSL, '.example-rgb-hsl') Examples.mountExample(Examples.ExampleScroll, '.example-scroll') Examples.mountExample(Examples.ExampleHueShiftRGB, '.example-hue-shift-rgb') Examples.mountExample(Examples.ExampleHueShiftHSL, '.example-hue-shift-hsl')
https://sonnet.io/posts/use-rainbow/
No Such Thing as a Fish
Show full content

This one will be short. A few days ago I was facilitating a retrospective for a team being a mix of old and new people, all of that in an organisation that has scaled up quite a bit in the past few years. It's not a surprise that many of their questions dealt with their process, practices, figuring out how to live work with each other, how to make stuff.

I remembered that I had an old template of the Starfish team activity, which fits the use-case perfectly. Also, is quite fun to run. So I dug it out and pasted into Procreate. Check it out if you're running a practice-focused retrospective:

As always, it should work fine as a background for Mural, Miro, Figma Jam board or whatever is your jam (mine's fig).

Retro template

Now, although I'm a fan of Funretros, I still believe that my Starfish is superior to their examples, as it's wearing a slingsuit.


PS. The making-of video can be found here. It's cursed, remember I warned you.

https://sonnet.io/posts/starfish/
Short: Retrofuturetrospectives
Show full content
.post__title{ overflow: hidden; text-overflow: ellipsis; }

I'm a big fan of Fun retros, and I like smuggling my doodles into my work*.

If your retrospectives feel a bit repetitive or you're working with a team you don't know well and want to learn a bit more about them before you hit the ground, check out Hot-air Balloon, Bad Weather. It's quite versatile and works well with remote setups.

And, feel free to use the template I made!

It should work fine as a background for Mural, Miro, Figma Jam board or whatever is your jam (fig's mine).

Retro template


* There's still a bunch of businesses in the Square Mile with ponies hidden in their documentation. The more JIRA you use, the more ponies you get.

PS. Speaking of facilitation materials, if you're looking for something less developer-oriented check out the Hyper Island Toolbox.

https://sonnet.io/posts/hot-air-balloon/
Code sober, debug drunk
Show full content
The main reasons I write tests are:
  • reduced cognitive load,
  • improved communication with my peers,
  • ability to sleep at night.

Testing allows me to split hard problems into chunks small enough to fit in my head. I'm young, but with every passing year as a software engineer more and more often I wonder whether these chunks are becoming smaller because I'm getting better at my craft or because I'm losing the ability to hold and process large, complex ideas. Yes, I know I'm a bit paranoid.

  1. Writing code is easier than reading it.
  2. If your code is hard to write now it will be almost impossible to read later.

This is a paraphrase as I can't find the original quote, but I think it sums up the issue pretty well. Structure your code in a way that a more tired, less focused, "drunk" version of you would understand.

Tests help with this because they make the intent behind the code more obvious. First, test cases document the use cases. What's more important is that the code written following TDD tends to be simpler and less abstract.

The simpler and more boring the code is, the more satisfied I am with my work.

If we're working together, the last thing I want to do is to make your life harder. It's in the interest of both of us to be able to focus on something more rewarding than untangling spaghetti – such as, you know, building stuff.

https://sonnet.io/posts/code-sober-debug-drunk/
Pair Programming with Snakes
Show full content

OK, this was supposed to be a longer post, but I'm trying to learn to get things like this out quickly, instead of yak shaving and eventually letting them fester in drafts. So, here we go. This one’s about pair development.

Pair Development is one of those habits that many of us practice in one form or another before realising that:

  • people have already come up with a label for it (it's a thing)
  • a significant amount of brain power has been spent turning it into a form of deliberate practice (it's a Thing)

This post lies somewhere between these two points. It's not an introduction to Pair Development, but a short description of a few dynamics that are often skipped during training, the things that we discover once we start practicing it ourselves. For tried and tested theoretical resources, check the footer.

So, if you came here for practical and opinionated pairing advice, and for snakes wearing fancy hats, you came to the right place, my friend.

First of all, why pair development?

Because while flow and being in the zone are all great things (I'm saying this without any sarcasm, believe me, I keep trying to make apps for that) interesting things happen when we're forced to verbalise our thinking process. This not only reduces an entire category of errors and improves knowledge sharing, but also—and I think this is crucial—it makes our code more a record of a conversation between two engineers rather than an internal monologue.

An Ideal Pairing day

Two parallel snakes

Let’s start with the ideal pairing day—two snakes work on a thing together. They might be using the same workstation, a remote editor or zoom and a bit of branch magic. The technology is secondary here and often the most rudimentary tools work best.

You might've also heard the term Ideal Pairing Day from a development manager, a “seasoned” engineer or a project manager. It was used as a measure of time: how much could two snakes achieve when pairing uninterrupted for a single day?

Keep in mind that “ideal” in this context means the same as “doesn't exist”. We’ll see why in a moment. On the rare occasions a day like this does happen, it might be a sign that you should be taking breaks more frequently.

Less ideal would be ideal

one snake in a straight line, another diverging and returning after a while

The yellow snake stays working on the story, cracking the red-green-refactor cycle like it's no one's business, but the green one moves temporarily to another task.

Why?

  1. You've been pairing for a couple of hours. You have a fairly clear idea of where you're heading, but then stumble upon a problem that needs more research. OR
  2. You realise you need to finish a smaller task that could easily be done in parallel. OR
  3. You're just tired of each other, tired of talking, or both.

All of these are valid reasons for one of you to move on to another task for a while.

Two snakes starting out together, diverging and converging

So, you start out working on the same task, but eventually realise that splitting up would be the best use of your time. You have a fairly clear idea of the interface between the components you're writing and both pieces of work are not too complex.

After an hour or so you pair up again, connect the two pieces and continue working on the main problem with little difficulty. Happy snake times.

Rotations

one snake leaves, another one raplaces her

Generally, the same snakes shouldn't be pairing with each other for longer than a day. Hence, just after the standup one team member is replaced by another. This cycle repeats the following day, creating a pattern like this:

Why do we do this? Frequent rotations help with knowledge sharing within the team and allow everyone to have a stronger sense of ownership over the project. No one wants to be "the postgres snake" for reasons that are purely circumstantial, such as just happening to be the original developer on a particular story. Same applies to the "exotic (database technology) snake" whom you have to call in the middle of the night because no one has enough context to revert a broken release.

Whether you're a reptile or a mammal, rotating can be a chance for you to either stay engaged or rest. You should avoid working on the same task for a week straight.

What about the downsides? These are pretty obvious, but often avoidable: frequent rotations can make it hard to keep enough context to feel that you're productive once you pick up the task again. It can be demoralising not to be able to immerse yourself in a problem fully. How to mitigate?

Some problems might just require more focused time, but this could also be a sign that the task should be split into smaller chunks. If you're sure that's not possible, consider having longer rotations or parallelising parts of the task. Avoid being dogmatic. Test and pick what works best for you.

An impromptu mob

one snake temporarily joining the pair

Yellow and Green had some difficulties with setting up the environment, so they got some help from a Cyan snake, one well versed in the pythonic scriptures. While Yellow and Green might not understand everything to the same extent as Cyan, at least now they know the required incantations. Her role here done, Cyan can now go back to her previous task.

Key points here: Cyan had the time to help, and gave them just enough context to continue working on the story. Maybe tomorrow Cyan will jump in and pair with one of them and learn more about their domain?

Multiple pairs joining

multiple pairs of snakes converging for a moment

Here's where this comes in handy:

  • Yellow and Green discover that their changes might impact a larger piece of work, or maybe they want to consult their approach with the rest of the team. OR
  • Yellow and Green want to share with the rest of the team how to iterate on the large feature they're just wrapping up. There's no better way of learning than by practice, so all snakes briefly work together.

There's a third pair of snakes which we can't see here. Those snakes decided to avoid interruptions and work in a more focused way. If you feel like distractions are a big problem when pairing in your team, consider having designated “interruptible” and “uninterruptible” pairs.

A regular day

snake spaghetti

Yellow mobbed with an entire rainbow of snakes and moved on to working solo for a while. In fact, most of the snakes spent half the day on independent work, then joined back again in the afternoon.

Key points here: take frequent breaks, listen to your partner, and be present (no staring at your phone). Reflection on what works and what needs to be improved, deliberate practice—all of these things require our full attention.

Bless this mess.

.rotate { text-align: center; padding: 0 1rem; } .rotate img { max-width: 40rem; animation: spin-those-snakes 6s 1s linear infinite both; } @keyframes spin-those-snakes { from{ transform: rotate(0); } to { transform: rotate(-360deg); } } a spinning circle of snakes, one earthworm

I believe that the most valuable thing about pairing is the short feedback loop.

Here's why:

The two snakes split their thinking into two modes: the What? and the How? One of them deals with the short-term, tactical decisions while the other focuses on the long-term, strategic choices. They both have the same goal in mind but they see it through two different lenses.

Through pair development, their code becomes a record of the conversation between those two different perspectives, rather than the inner monologue of a single snake.

Think of the last messy piece of code you had to work with. Chances are that “internal monologue” would be a fitting description.


Credits and resources:

Alexandra Ciufudean edited this article and translated it into Human.

The inspiration for this post came from the diagrams created by my old colleague from Unruly, Gel Goldsby. I had so much fun writing this, thank you, Gel.❤️

https://sonnet.io/posts/snakes/
Reactive Hole
Show full content

In the past few weeks I've been messing with turning some of my doodles into little apps.

Here's a (fairly) private and (mostly) secure P2P transfer thingy:

You can check it out here, and here (source).

What are the other tools/digital products that are so simple, so low-tech that we'd choose them over the alternatives purely because of their aesthetics or how they make us feel?

I'm not talking about anything more complex than the digital version of a coffee mug or a keychain. Neither serves an important purpose and both are anything but irreplaceable. I don't care whether the thing in front of me is pretty or ugly, playful or boring. What I care about is whether it feels mine.

This might sound like I'm procrastinating (likely) or talking about the experience economy (also, likely). But, what I really have in mind are toys.

Now, if you were to build a toy (not a game and not a tool), what would that be?

https://sonnet.io/posts/reactive-hole/
Come and say hi
Show full content

Are you working on something new, exciting or weird?

Are you learning about a new piece of tech or just looking for someone to bounce off an idea that has been haunting you for some time?

Brilliant!

I'm available throughout the week for a coffee and a chat about ideas big and small. There's no specific format to this—ask me any question and I'll see if I can help, free of charge.

I also have a bi-weekly 2h slot which I use for pair programming and mentoring sessions with friends, old and new.

Should none if this suit you, feel free to call me for a delicious 3 minute rant. It's simple: you rant, I listen.

We spend the remaining 7 minutes staring into the void, contemplating the pointlessness of our endeavors and the strange pleasure of hyperventilation.

A few days later I might text you back with a solution to your problem.

Honestly though, I'm just curious to see who you are and what you've been up to.

Come and say hi

Example topics

(In no specific order)

  • Product Development, from MVP to enterprise (prototyping workflows and scale)
  • Privacy, the impact of AdTech on our society
  • Design Thinking, Human-Centred Design
  • Photography (film, digital, medium and small format)
  • Mental health
  • The Web Platform (browsers, standards, Google being an utter 🐴, the history of the Web)
  • Emerging Technologies (AR, VR, ML/NLP)
  • Pair programming (I'd love to pair with you on your own problem)
  • Agile/XP, TDD, pair programming
  • AdTech, Pharma, Publishing, SaaS
  • Software Engineering (web, mobile, AR, backend, game-dev, infra)
  • Linguistics incl. NLP
  • Game Development (Unity, C#, web) and Game Design (methodologies and tools)
  • How to make an amazing Cacio e Pepe (and why 🇮🇹 + 🇰🇷 = ❤️)
  • How to draw poorly but regularly
  • Being an engineer, lead, CTO or consultant confused human working for Startups, scale-ups and enterprise
  • Remote work, living abroad
https://sonnet.io/posts/hi/
Ensō
Show full content

Ensō is a writing tool that helps you enter a state of flow.

It does this by separating writing from editing and thus making it harder for you to edit yourself.

The rules of the game:
  1. you can't select text
  2. you can edit only a character at a time
  3. only a few last lines are visible as you type, fading away and losing their importance
  4. you can download and review your text when you’re done writing

Ensō

I created Ensō to help me improve my writing habit and find a moment in my day to spend some time with my own thoughts. Editing in Ensō is hard, so writing can be easier. Generally, as I use it, the annoying bits of the UX quickly fade and since the only thing I could do is to write, I’m focused enough to think about something in depth. For me, it is a freeing experience.

You might use Ensō to:
  • develop your writing habit
  • improve fluency in your native language, or when learning a new one
  • think aloud (but quietly, so just think I guess?)

You may keep it on the side of your screen during the day and jot down your thoughts as impromptu notes—you know, the ones you'll never bother reading again, but write down anyway, so you can retain and organise information, or just clear your head.

At least this is how I use it. You might find it limiting to the point of annoyance or freeing and somewhat addictive, as I have. Give it a try and let me know what you think!

https://sonnet.io/posts/ulysses/