Hello friends,

Jessica was in town this week. We made a spaceship (pictured below). We also did some livestreaming. We Paired with Bunny on some basic client-side JavaScript, and Jessica showed me what she's working on for Atomist.


I've been thinking about a tension in how we think about relationships.

When I was growing up I was heavily influenced by the point of view that compatibility is basically irrelevant, and relationships are all about the work you put into them. This came primarily from a parent who felt that arranged marriages were the ideal kind of marriage, as well as this jackass who taught that dating was a bad idea (he has since repented).

(Aside: never trust a relationship book by someone under 40).

While this perspective can obviously be taken to extremes, there's a kernel of usefulness in it. It's the idea that you're going to have to work at a relationship. That's a pretty good expectation to set.

On the opposite extreme is the societal trope about how when you meet “The One”, everything will just flow. It'll feel right, and easy! The kernel of truth here is that compatibility matters. The failure mode is an endless search for the perfect partner, based on some list of requirements.

I was thinking about this tension recently, and how I've seen it play out in various people's relationships. And what struck me was that while we usually prepare young adults for the idea that relationships will require some amount of work, we don't usually give them any calibration.

How much work is a reasonable amount of work? The easy answer is it depends, but I think that's a cop-out. There is such a thing as an unreasonable amount of work, a not-OK ratio of pain-to-pleasure in a relationship. But without a wide variety of experiences, you have no idea where your current experience falls on that continuum!

And you can try reaching out to friends and mentors for help, but chances are you'll get wildly mixed messages! Because everyone's labor-sensitivity is calibrated differently. One person's “dealbreaker” is another person's typical Tuesday.

It's also not useful to fall back on the idea that “different people have different tolerances”. Because tolerance isn't fixed. One thing I've learned about being human is that we have an almost infinite capacity for building up tolerances. Saying “it depends on your tolerance level” is tantamount to saying “there is no such thing as Too Much Work”.

This problem of calibration extends far beyond relationships. One of the sensibilities I've honed as a developer over the years is a sense of how hard is too hard. What is the pain point that indicates I am almost certainly fighting the system, and that there is a better way to do it?

These days I feel like I have pretty good idea of when to stop, step back, and ask around for alternative approaches. But when you're a novice, it can be scary to do that! You have a sense that this stuff is supposed to be hard, and so the pain you're feeling right now… well, it's probably perfectly normal, right? And you should just apply yourself more dilligently.

From relationships, to documentation, to system monitoring… it's not enough to say “there will be some friction”. Expectation of friction is useless without calibration. Some of the most useful guidance we can receive are concrete heuristics for what amount of difficulty/pain/failure is reasonable… and what amount is not.


Hanging out with Jessica always spawns a lot of philosophical, systems-thinky conversations. Today I tried to sum up some of the ideas we've been knocking around in a tweet, and I thought I'd make a first crack here at expanding on them.


Value over simplicity.

Valuable systems are complex ones. Let's put paid to the idea we can have one without the other.

Communication over correctness.

I'd rather work with a system that gives me a good idea of what it's trying to do and fails at it, than one that is “correct” but inscrutable.

Learning over longevity.

One of the most pernicious, difficult-to-root out biases I've found in my own psyche is the idea that something has to be long-lived
(at least theoretically) in order to be “good”, “right”, or “important”.

E.g.: A divorced marriage is a “failed” marriage. A political system is “broken” unless it can last forever. Tests are only valuable if they can be retained indefinitely for regression-checking. Successful code is modified rather than replaced.

I'm trying to replace this bias with the idea that a thing is right, good, useful, and important so long as you (or more importantly, the entire sociotechnical system around it) learns from it.

Importantly, this is not the idea of “learning from failure”. It's the philosophy that the learning is the aim. Sometimes other interesting benefits fall out along the way. Sometimes artifacts you create along the way remain stable for a while. Others don't. Sometimes your direction changes with the learning, and the change renders artifacts obsolete. This is fine.

Context over consistency.

This one feels pretty self-explanatory to me… there's no such thing as a universal best-practice. There is little to be gained and much to be lost from aggressive standardization. Things that work well only work well in a given context. There is no universal or objective correctness.

Movement over stability.

Nowadays I seek forward motion, rather than trying to converge on some ideal stable state. It's deeply uncomfortable for me, still. But I'm working at it.

Remediation over rigor.

I'm not 100% on the terminology for this one yet. But the basic idea is that I'm not interested in making systems rigorously robust. I don't want to trace out every possible failure mode and plan for it. I also don't believe it's possible to make systems that can erase all consequences of failure.

Instead I want to build systems that are optimized for making things right when something goes wrong. That can mean anything from well-maintained backups, to having a well-trained and empowered support team.

Connection over completeness.

This is something I talk about in my #NOCODE talk. It's less important to build a system that covers every last jot of needed functionality, and more important to build one that has well-established ways of reaching out for help when something goes beyond its capacity to handle.

This has obvious implications for life in general, e.g. knowing people with skills you lack. But it's also applicable to software systems which can ask a human for help with resolving an unhandled situation.


Right, let's see how I did.

  • ✔ Tie up loose ends from the Cohere meetings. Inasmuch as I did some due diligence, made some concrete decisions, and communicated them, yes.
  • ❌ Catch up on my snail mail. Ugh, nope. There's something tax-related in that pile and that always puts me off the whole enterprise.
  • ✔ Catch up on RubyTapas TODOs. Done.
  • ✔ Catch up on email. Done. And I finally rigged up a new shared inbox for certain non-business stuff, so e.g. I don't have to forward emails from the propane company to my assistant anymore. Win.
  • ✔ Finish unpacking and go over notes from AIT. Done.
  • ✔ BONUS TASK: Populate and organize my conference RADAR board. I now have a much better sense of which confs are coming up when, and a way to track which confs I'm hoping to get into.  

This week:

  • Burn Catch up on snail-mail. For real.
  • The usual RubyTapas stuff, including several guest chef meetings.
  • Actually show up for a >Code episode.
  • Write and record VO for two RubyTapas episodes.
  • Go running.
  • Investigate my options for some part-time consulting work. I'm looking to close a cash gap, make myself useful on a team, and satisfy my urge to have a real sociotechnical system to bang my ideas against again. (Feel free to get in touch if you have a lead…)

As always, thanks for reading. Cheers!

Published by Avdi Grimm