Adventure Goals in Practice


In my last post, I sketched out a new goal setting system I dreamed up loosely based the many, many systems I’ve tried in the past. However, I found I wanted a system which was more mental-health friendly, and—to be honest—a bit more fun! I used it to set my first quarter goals, and now that the quarter is half-way over, I thought I’d share some observations about how it’s going so far. Needless to say, this post will make a lot more sense if you’ve already read the last one!

Is this a peak or a horizon?

I started the exercise by brainstorming on peaks and horizons with the mental image of what I can see from my current campsite. These generally came pretty easily, but there were a few situations where it wasn’t entirely clear whether something was a peak or horizon. These were usually things that were of the form: “Establish xyz as a new status quo”. Is this a thing to check off, or a new habit to cultivate? I wound up classifying those as peaks with the reasoning that establishing a habit is a thing that can be checked off, and then cultivating / improving the habit is a horizon.

Paths can have multiple destinations

With all the choices in front of me, I started picking out various peaks and horizons which felt most important to tackle in the coming quarter. For each, I picked out a path which seemed like a promising way to make progress toward it. Almost immediately, I noticed that nearly all of the paths I selected would bring me closer to multiple destinations. For example, I initially selected the path of “Develop a habit of taking a walk 4+ times per week” to bring me toward the “Improve physical health” horizon. However, it is also an excellent way to move toward the “Improve mental health” horizon as well. So, under my notes for that path, I included both.

As I was choosing paths, I also noticed that several of the Peaks were all specific things I wanted to accomplish to move my photography business forward. So, I included both the peak (i.e., the specific project) as well as the horizon (i.e., advance my business) in my notes for those paths.

By the time I was part-way through selecting paths, I found that I was starting to deliberately look out for Paths which could bring me closer to multiple destinations. In hindsight, I now feel like this is an important criteria to use when brainstorming paths in the first place.

Capture notes when selecting paths

As I selected each path, I immediately had a whole bunch of random ideas about it. Most were ideas for implementing the path, but some were details about deliverables, who should be involved, open questions in need of answers, and lots of other things. I gave myself permission to just capture all that stuff just to get it out of my head. That way, I could feel ready to move along to the next one without anything cluttering up my brain.

Milestones as being in the past tense

When I got to thinking about milestones, I found it helpful to take the perspective of looking backward along the path from the point of view of having already successfully completed it. That made it easy to see all of the milestones in the past tense: as things already done. It also made it easier to visualize moments which, in hindsight, were important inflection points or signs of progress. Compared to other systems I’ve used (e.g., OKRs), this felt much lower-pressure and wholesome. These weren’t things to strive for at the penalty of being a failure, but rather things you happen to notice were steps along the way to being successful.

Multiple Campsites

When I got to thinking about campsites, the first thing that came to mind for all of them was: “end of quarter”. That’s the cadence at which I want to do these “campsite” exercises, so that made total sense. I found this rather too simple, so I spent some more time, and found that I could also add “all milestones achieved”. Also not super insightful, but it makes sense that you’d stop to pause at that point.

The real insight came as I spent a bit more time and found that I didn’t really need to achieve all of the milestones to feel like it was a good time to stop and re-evaluate. In one case, the peak in question was to set up a new recurring habit. There were a bunch of milestones which might be reached, but really, I’d consider myself to have reached the next campsite after demonstrating that I could repeat the new habit: whether I reached the subsequent milestones or not.

Naming the adventurers

When I was pretty much finished with everything else, I was reviewing my selections and trying to decide whether I was spreading myself too thin. At that point, I decided to assign each path to a specific adventurer, and name the adventurers according to the broad areas of focus each path was addressing. So, I wound up with “Arnold: Fitness Adventurer”, “Warren: Financial Adventurer”, and several others. Some of them are people I’ve never met, and others are mentors I’ve actually known. I liked the idea of attaching a specific person each path as a reminder of someone who would be an inspiration as I travelled down it.


So far, I’m liking the new system a lot. It feels like much less pressure, and I don’t have the same sense of trepidation about the possibility of not meeting all my goals that I’ve felt with other systems. I’m also finding that I’m actually accomplishing a much higher percentage of my milestones than is typical at this point in the quarter. I’m looking forward to seeing how things progress through the rest of this first attempt at using it!

If you’ve been interested enough in the Adventure Goals system to try it out, I’d love to compare notes on how it’s been working for you!

Goal Setting as an Adventure

A lot of goal setting systems are very binary in their results, and rather unforgiving in their mindset. They don’t allow for things to change mid-stream, uncertainty during the initial goal selection process, or unexpected things causing set-backs. After trying lots of these systems, I started thinking about goal setting more like a party going on an adventure.


Big Concepts

The Adventure and Expeditions

The Adventure is the course of our entire lives. It takes a long while, is full of unexpected encounters, and requires a balance of effort and rest if we’re going to make it to the end. At times, it seems like we know exactly where we’re headed, and at others it feels like we’re lost in the wilderness. Everyone starts out in different terrain, and that can make it much harder for some people than others. In the end, though, we each make our own journey and have to do the best we can with what we find along the way.

An Expedition is the “effort” part of the Adventure which comes between the rests. It’s when we marshall our resources together, and head off down the road trying to make some progress toward those things we want.

Peaks & Horizons

Some goals are definite things you want to accomplish. You can see it way off in the distance, and even if the terrain between here and there is hard to make out, you definitely know when you arrive. These are Peaks.

A Peak might be something like obtaining a degree, getting married, or building a greenhouse. They are things where there’s an obvious point at which there’s nothing left to do, and you’re done.

At other times, a goal is much less definite. It’s more of a desire to head into the unknowable distance without a specific destination in mind (“Go west, young man!”). You can check your compass to see whether you’re heading the right way, but there’s no particular point at which you’ve arrived. These are Horizons.

A Horizon might be something like: improve my mental health, learn to cook, or improve my skill at the clarinet. These are things which can’t be “checked off” in any meaningful way. They’re just things we want to keep striving toward: sometimes with more or less vigor.

When setting goals, we usually have both.

Campsites, Paths, and Milestones

We start and end an Expedition at a Campsite. When we’re at a Campsite, we’re not making progress toward a Peak or Horizon, but rather reflecting on the past, recovering our strength, and planning the next stage of our journey.

In real life, a Campsite is the process of sitting down and thinking. Maybe you’re sitting in a coffeeshop with a pad of paper, or maybe you’re in your office tapping away at your computer. Either way, you’re looking back on how your plans for the last month, quarter, year, etc. turned out, and trying to figure out where to go next. Do you even want to keep pursuing the same set of Peaks and Horizons that got you to this Campsite?

There are many Paths leaving each Campsite. Some of these are well traveled by others who have come before us, and others are only a faint track through the weeds. Some are steep and dangerous—but direct—while others are easier but meandering. Ideally, you’re able to follow a Path to the next Campsite having gotten a little closer to your goal. On the other hand, there are also false paths that simply die out in the woods, forcing you to retrace your steps back your starting Campsite for another try.

In practice, a Path is a course of action which seems to lead toward a Peak or Horizon. If the Peak is to get married, one Path might be to sign up for a ballroom dance class on the hope you will find some suitable partners. Another path might be to join an online dating app. Yet another might be to make plans to go out to a nightclub once a week. It’s up to you to judge what strategy seems most achievable, most enjoyable, and most likely to succeed.

As we travel down a Path, once in a while we might find a Milestone. These are markers that tell us how far we’ve come. From that, we might experience a boost of confidence in being able to mark our progress, and maybe even infer how far it is to the next Campsite. Not all paths have many (or any) milestones. Even when they do, it’s not always easy to infer anything about how far it is to the next Campsite from that information, but they’re certainly nice to have when we can find them!

In practice, a Milestone is a measure of the progress you’ve already made with a given strategy. Taking our example above, perhaps you signed up with a dating app. Each date you go on is a milestone. Maybe you also decided to stick with it until you’d gone on ten dates and then reevaluate. That’s the next Campsite along that particular Path.

The Band of Adventurers

Of course, on a real hike, we could only follow a single Path at a time. However, unlike a hike, we’re often capable of pushing forward many different projects at once. So, imagine that we each have a little Band of Adventurers at our command, and each one of them can pursue a different path for us. Of course, we’re not talking about an army here, so we do have a limited number of paths we can explore at one time. Plus, our little adventurers constantly need our advice and attention. So if one of them is exploring an especially complex, dangerous, or ambiguous Path, we have less time and attention we have to look after the others. We might choose to severely limit the number of Adventurers on a particular Expedition so we better assist one particular Adventurer on a difficult Path.

The Band of Adventures is a proxy for the amount of productive time we have in a day. If we try to do too many things, then some of them will wind up getting ignored or get done badly. For example, if we have a lot going on at work, tending to that Adventurer takes up most of our time. Maybe so much so that we can only really help along one or two others. At other times, things are more-or-less on auto-pilot, and we can guide a lot of little Adventurers. As we stop at each Campsite, we get a chance to check in with ourselves and decide how many of them we can send out exploring on the next Expedition.

Planning an Expedition

How does one actually implement this system?

First, we need to start out in a Campsite. That is, we need a calm, quiet place which allows us to reflect on our journey and make plans. This probably means turning off the phone, closing the door, or grabbing a study room in the library so that no one can disturb us.

Second, we need to decide on our Peaks and Horizons for the upcoming Expedition. These are the really big things as far out as we can see right now, so this is the place to be bold and courageous. Brainstorm as many as possible; we’ll filter out less interesting ones later. If we’ve just finished an Expedition, then we have the Peaks and Horizons from before as a starting point. Just don’t take it for granted that those are the only Peaks and Horizons to choose from, or that it’s even worth heading for those particular ones anymore.

Third, we need to pick a set of Paths. For each Peak or Horizon we selected, we need to have at least one Path toward it. If we want to hedge our bets, we might pick multiple paths toward a certain objective, but that leaves us with fewer Adventurers on other Paths. There’s a lot of uncertainty involved in this step, and it may be necessary to decide not to progress toward a certain Peak or Horizon after all. In the end, we want to wind up with a number of Paths that matches the number of Adventurers we can support along the way, so when you think you’ve picked your Paths, take a moment to reflect on whether it’s too much to handle.

Finally, we want to give some thought to the Campsite where the Expedition is going to end, and what kind of Milestones we should expect to see along the way. To keep things simple, we might decide that all our Adventurers reach the next Campsite at the end of the current quarter: no matter what. For other Paths, a other metrics may make sense (e.g., the dating app example). Whichever it is, you’ll want to know when you’ve gotten to a point on each Path to stop and reflect. Then, we can let our Adventurers regroup, swap stories over the campfire, and get ready to do it all again.


I haven’t actually used this system yet myself, but I’m planning to try it out for my quarterly goal setting exercise this time around. I’m hopeful that it will provide enough structure to help me set priorities, select projects, and stay on target for the upcoming quarter without creating the kind of stress and sense of frustration and failure that other systems have produced. I’ll definitely follow up on how things turned out!

Vue.js Computed Property Gotcha

I spent a few hours today trying to track down why a change password form I created wasn’t working. Ultimately, it turned out to be a surprising behavior from the way Vue.js (v2.6.14) computed properties are refreshed.

First, let’s have a quick reminder about how computed properties work. Each computed property runs some code and returns a result as the current value of that property. Vue will cache the value, and automatically re-compute it only when some data it depends upon changes. Normally, this works perfectly, and is completely transparent to the end user. Somehow, Vue just knows which other properties it depends upon.

So, on to my problematic example where it doesn’t just know. Let’s start with a simplified version of the component’s code:

01: computed: {
02:     canSubmit: function() {
03:         result = this.password && this.passwordConfirm;
04:         console.log(`canSubmit() -> #{result}`);
05:         return result;
06:     }
07: }
08: 
09: data: function() {
10:     return {
11:         password: undefined,
12:         passwordConfirm: undefined
13:     }
14: }

Seems pretty straight-forward, no? Well, it doesn’t work.

I have an event handler (not shown) which changes this.password and this.passwordConfirm each time the user types in an input element. For each letter the user types in the “password” box, you see the console statement. However, no matter what the user types into the “confirm” box, the console statement never appears.

The problem, it turns out, was on line 3:

    result = this.password && this.passwordConfirm;

Since this appears inside a computed property, behind the scenes Vue.js is trying to work out what other properties are being used so that it can figure out when this property will need to be refreshed. You would expect it would have have something like this in its dependency graph:

    canSubmit -> password, passwordConfirm

Except, it doesn’t. For some reason, when both this.password and this.passwordConfirm appear on the same line, Vue.js fails to recognize the dependency on this.passwordConfirm, and produces only this dependency graph:

    canSubmit -> password

Therefore, you see the console statements only when this.password changes, and not when this.passwordConfirm changes.

The fix is pretty easy. Just change canSubmit to this:

canSubmit: function() {
    p = this.password
    c = this.passwordConfirm
    return p && c
}

Having the references to this.password and this.passwordConfirm on separate lines appears to do the trick, and causes Vue.js to produce the expected dependency graph.


Why is this happening? To be honest, I don’t know. Here are a few theories…

The method Vue.js uses to detect dependencies:

  1. doesn’t work with multiple properties on the same line
  2. gets confused by the similarity of the two names
  3. get confused by the logical operators

To be honest, I have a hard time accepting that any of these are true, but they’re the only plausible explanations I can come up with. If anyone has a better theory, please leave it in the comments below!

Gamifying Empathy

My son was diagnosed with “high-functioning autism” when he was a toddler. For the purposes of this post, I want to focus on one specific aspect of what that means: a lack of empathy. Mostly though, I want to share a system we have invented to help him with it.

First, let me explain a bit about what “lack of empathy” actually means in his case. In simple terms, it doesn’t naturally cross his mind to try to figure out how what he says and does will affect other people. If he is specifically thinking about it, then yes, he can figure it out, and plan how to behave accordingly. So, in a classroom, for example, where he knows there are specific social rules, he mostly does fine (unless he gets distracted). Same thing when we have company over for dinner. Since he is never required to join us, it’s always a conscious choice for him to engage with our guests, and he generally does well.

However, when he’s not thinking about it, how his words and actions affect others simply doesn’t cross his mind. So, blowing his nose without a tissue continues, despite many outraged protests from us. Same with washing hands after using the bathroom. Likewise, handling our dog roughly continues, despite countless reminders. On and on. And, when we remind him, we get nothing but dismissive sass. Even more frustrating, this has all amplified as he’s reached his teenage years. He has even been able to clearly articulate that he simply doesn’t care that these things (and many others) bother us.

What to do?

Clearly, one could take a punitive route. Heap punishments upon punishments until he’s fearful enough of incurring more that he obeys. My wife and I both find this approach repulsive and sad. We could just ignore it. But, the world at large simply won’t tolerate this kind of behavior, so we’d be doing him a massive disservice by allowing him to not learn this lesson while the consequences are so mild. Not to mention, neither of us could bear to live that way. We needed another way.

The problem is that our feelings don’t register in his value system, and—even more than that—he’s very bad at judging how something will affect us, even if he’s inclined to try. So, our system needs to take a long-term value which is currently outside his ability to project, and map it into a value hierarchy that he does understand right now.

The Goodwill Game

My son is crazy for games. Chess, board games, card games, you name it. He even invents his own. And, he’s a master at almost all of them almost immediately. So, we cooked up a game which helps him “win” at getting along with other people (my wife and I, in this case).

As parents, we need to ensure he learns how to treat people in his environment well. However, he often lacks the insight into how his behavior affects other people, which makes it hard for him to know how well he is doing. This game is intended to provide direct feedback—in a quantifiable way—of how his actions affect the emotional well-being of people around him: both positive and negative. As this is an abstract skill which doesn’t map well to his current values, the points accumulated will be periodically converted into things he does currently value, to help him better relate in terms which are more immediately understandable.

Points Awarded Scale

To set up the game, we started by creating a Points Awarded Scale. All of us sat down together and came up with positive & negative things to put on the scale, and agreed upon the number of points gained & lost for each.

While the points may seem arbitrary: they really aren’t. They quantify how a particular behavior makes us feel in a way that he can understand. So, mildly annoying things (e.g., stomping around the house) have a small negative value, while awesome things (e.g., volunteering to clear up dog vomit) have a large positive value. Apologizing immediately and sincerely (something which is very hard for him) neutralizes any negative points: because they neutralize the bad feelings for us. So the whole points system allows him to better understand how his actions affect us.

As an aside, it was immensely enlightening for him to just make the scale! He was often surprised that we actually cared so much about various items on there, and it frequently provoked extended conversations about why that was the case.

Here’s a small sample of our current scale:

positive negative
1 — humorous banter -1 — reminder to complete chore
2 — saying thank you -2 — isolated rude comment
2 — responding to text message -2 — ignoring a text message
3 — chore completed on time -3 — snarky response to reminders
5 — asking for on a task when needed -5 — dismissive/rude response to feedback
8 — independent follow-through on feedback -8 — performing a chore badly after a reminder
10 — volunteering to help -10 — performing a request in a snotty manner
-20 — attempting to cheat this system

Point Redemption Scale

While the first scale does a great job of helping him understand how he’s affecting us, it still doesn’t bring our feelings into his value hierarchy. So, we added the Point Redemption Scale so that he can “cash in”: thus bringing how he affects us back into a realm that relates to values he currently holds.

The scale has two parts: benefits and punishments. If he accumulates enough points, he can redeem them for things he likes on the benefits side of the scale (e.g., pizza for lunch). If he winds up in negative points, then we choose a punishment from the other side of the scale (e.g., no internet for 24 hours).

As with the first scale, we all sat down together and decided how many points all the various benefits and punishments were worth, and everyone started out in agreement about everything on both sides. However, this scale is the opposite of the first scale in that the first was a subjective measure of our preferences, while this one is a subjective measure of his preferences. All the benefits are things he likes, scaled to his level of preference. Likewise, all the punishments are things that he dislikes, again on his own subjective scale of preference.

This is how the mapping finally occurs. Our subjective preferences are mapped to points on a scale which is public and knowable to him. His preferences are mapped into a scale which is calibrated with ours. So, now he can see a direct correlation between his value hierarchy and our own.

Here’s a sample of our current redemption scale:

benefits punishments
25 — 1 pt gelato 20 — 24h without internet
50 — pizza for lunch 50 — 24h without computer & iPad
75 — $10 extra allowance 75 — 24h restricted to his room
100 — extra family TV episode 100 — 2h extra chores
200 — 1.5h of 3-player board games 200 — 24h restricted to guest room

Running the Game

In order to actually run the game, we adopted the following rules:

  • points gained & lost are awarded in real time (as much as possible) by referencing the Points Awarded Scale
  • points are recorded on a chart which is accessible to the entire family
  • once per day, we all get together and make sure to capture all the points for that day while our memory is still fresh (in case anything is missed)
  • once per week, we tally up all the points gained and lost
  • if there are positive points, then our son can redeem them for items listed in the benefits side of the Point Redemption Scale. He may also bank points for specific items which are “too expensive”
  • if there are negative points, then we select items from the punishments side of the scale
  • points reset to zero each week

How is it working?

We used something very similar to this when our son was much younger (around 10 or so), and we’ve just started in again at around 17. It worked very well when he was little, and it seems to be working even better now. By having a short list of things to be mindful about, it doesn’t seem to be so daunting and nebulous about how to get along with us well. As I mentioned before, he’s also super keen on games, so making this into a game he can win is compelling. I think that—even more than cashing in the points—is what makes this work for him.

I think the real benefit, though, has come from the conversations we had to set things up. We clearly understand one another a lot better now, and we’re able to refer back to the various scales when talking about things. Moreover, when some new behavior comes up which is good or bad, we have a quantifiable scale to relate it to (even if it’s not actually part of the game). That makes conversations about how his actions affect us go SO MUCH more smoothly.

The End Game

Obviously, this is a tool to get past a brief hump we’re having as a family. We used it for a while when he was little because we were having a similar kind of problem. Eventually, he picked up better habits, and we let the game fall by the wayside. When we started having the same problems again recently, I suggested we dust this off, and give it a try again. I fully expect that we’ll use it for a little while until he internalizes some better habits, and we’ll again set it aside.

Except… do you ever really set it aside? While we, as adults, don’t actually tally points and what-not, we certainly do have a sense of “fairness” or getting “value for value” with our spouses, co-workers, and friends. When a relationship feels “unfair”, or like one person is doing all the work, we feel discontented and allow those relationships to wither. In extreme cases, we actually cut them off. Perhaps a topic for another post!

The Quest for the Perfect Beatles Playlist

I needed a break from working the other day, so I decided to make a comprehensive Beatles playlist… all of their songs, in the order which best reflects the evolution of their work over time. It’s harder than it sounds.

The easy part is the full-length albums… but there’s still a little complexity there with “Let It Be” and “Abbey Road”. The former was recoded in Jan 1969, but not released until 1970. The latter was recorded in August 1969, and released later that same year. So… if you go by release date, then “Let It Be” is the last album, but if you go by recording date, then “Abbey Road” is. But, there’s a deeper story.

“Let It Be” was recorded under extremely trying circumstances. They were filming the process for a concept movie, which meant that instead of working in their cozy studio, they were on a film set. It was cold, drafty, and noisy. There were people all around all the time. They knew they were being filmed all the time. Plus, they were all starting to feel pretty worn out on The Beatles as a whole. So, they bickered their way through the entire production. Personally, I think you can feel it in the music.

“Abbey Road” was different. There’s a few stories about it, but the common thread is that it was understood that it was going to be “the one last album”. As such, you can tell that they guys pulled everything they had together to make one final statement. Everyone contributed a song or two (even Ringo, which is pretty unusual), and they are univerally held to be among their very best songs. Plus, the album captures the full breadth of their work from the pop songs of their start, to the orchestral overtones of their middle years, to the wild disonence and heavily distorted guitars of their later years. It feels like “the last album”, and the perfect summary of their work.

So. Recording order it is. But… what about everything else? Many of their best songs didn’t make it onto one of the canonical full-length albums!

Fortunately, long after The Beatles had broken up (and, indeed, long after John died), a collection called “The Past Masters” was released in 1988. This collection was specifically created to collect together all those songs which were released on singles and EPs. Now… where do they go?

One might be tempted to slot them in between the albums by their release dates, but this creates a lot of problems. To start, most of these songs were released multiple times in different formats and in different countries. Many of them, too, were released long after they were recorded. For example, “Across the Universe” was recorded roughly in the same time-frame as “The Beatles (The White Album)”, but wasn’t released until 1970… after “Let It Be”! So, sticking with the recording date comes to the rescue, and solves both problems.

Finally, there’s a few loose ends to tie up. First, “The Past Masters” does include a few songs which did actually make it onto a studio album (alhough almost always a slightly different recording). I decided to remove these in preference of those which appeared on an album. And, second, I just don’t need to listen to “Revolution 9” on a routine basis. So, that makes my final, complete, and “perfect” playlist:

songLove Me Do1962-10-05
albumPlease Please Me1963-02-20
songFrom Me to You1963-04-11
songThank You Girl1963-04-11
songShe Loves You1963-08-23
songI’ll Get You1963-08-23
albumWith the Beatles1963-10-23
songI Want to Hold Your Hand1963-11-29
songThis Boy1963-11-29
songKomm, Gib Mer Deine Hand1964-02-04
songSie Liebt Dich1964-02-04
songLong Tall Sally1964-03-01
songI Call Your Name1964-03-01
songSlow Down1964-06-01
songMatchbox1964-06-01
albumA Hard Day’s Night1964-06-02
songShe’s a Woman1964-10-08
songI Feel Fine1964-10-18
albumBeatles for Sale1964-10-26
songYes It Is1965-02-16
songRain1965-04-16
songBad Boy1965-05-10
songI’m Down1965-06-14
albumHelp!1965-06-17
songDay Tripper1965-10-16
songWe Can Work it Out1965-10-29
albumRubber Soul1965-11-11
songPaperback Writer1966-04-14
albumRevolver1966-06-21
albumSgt. Pepper’s Lonely Hearts Club Band1967-04-21
albumMagical Mystery Tour1967-11-07
songLady Madonna1968-02-06
songThe Inner Light1968-02-08
songAcross the Universe1968-02-08
songRevolution1968-07-13
songHey Jude1968-08-26
albumThe White Album1968-10-14
albumYellow Submarine1968-10-23
songDon’t Let Me Down1969-01-28
albumLet It Be1969-01-31
songThe Ballad of John and Yoko1969-04-14
songOld Brown Shoe1969-04-18
songYou Know My Name1969-04-30
albumAbbey Road1969-08-20

Milton Friedman—Is Capitalism Humane?

My personal politics may best be defined as “pro-freedom”. In some ways that makes me sympathetic to positions espoused (though seldom actually practiced) by both of the major political parties in the US. It makes me much more sympathetic to several of the “third” parties of US politics: most especially the Libertarian party (though not without reservations).

However, I’m much more interested in economics than politics (although the two are inextricably intertwined). And, in that realm, my leanings are entirely towards laissez-faire capitalism. To clarify, this is the form of capitalism in which the government only takes on the role of preventing force or fraud and adjudicating disagreements. No bail-outs, no subsidies, no charity, no public works. Regulations are only in service of preventing fraud and force. Also, there are no favors, no bribes, and very little corruption as there are no hand-outs to be obtained or clubs to he wielded against competitors. Needless to say, the form the US economy has taken since before WWI has only had a passing resemblance to this economic system, even though many people still refer to it as “capitalism.”

Milton Friedman (1912–2006) won the Nobel Prize for economics in 1976, and was perhaps the most famous defender of laissez-faire capitalism in the 20th century. In the talk I’ve linked to here, he defends capitalism on moral grounds by tackling the question: “Is capitalism humane?”.

If you feel as I do about capitalism, I encourage you to listen to this talk. In it, you will witness an excellent and entertaining speaker explaining points you may have heard before, but in an excellently clear and persuasive fashion.

If you do not feel as I do about capitalism, I encourage you to listen to this talk all the more. Not because I think you’ll be persuaded by 45 minutes of listening to Milton Friedman, but because I suspect what you and I think of when we hear the word “capitalism” are miles apart. And when you hear me promote and defend capitalism, and, perhaps, are inclined to persuade me otherwise, it would be great if we started out on the same page. Listening to this talk will bring us a lot closer to that point.

We’re our own journalists now

A friend just posted this article from NPR which describes a new racial outrage where a White woman called the police on a Black man for birdwatching. There’s even a video the man shot documenting the encounter. And, the woman does, indeed, seem pretty unhinged while the man seems very cool and rational. Except, that’s not actually what happened.

Someone else posted an article from the National Review which does some deeper digging. As this second article indicates, the video only shows part of the encounter. You can actually see the original post on Facebook. The description gives a little more information on what happened before the video starts. In particular, the man asks that the woman put her dog back on its leash, and she resists several suggestions of how she could exercise her dog off-leash elsewhere. At which point, the man says (quoted from his Facebook post): “Look, if you’re going to do what you want, I’m going to do what I want, but you’re not going to like it.” At this point, he attempts to offer the dog a treat, the woman becomes alarmed, and the man starts filming.

Judging from this information (as reported by the man, and therefore likely to be biased somewhat in his favor), I think they both handled the situation badly. It’s understandable that the man was annoyed. The woman was clearly violating the rules for that area of the park, and it inhibited his ability to enjoy it by scaring away the birds he came to watch. It’s also understandable that the woman was alarmed. She encountered a stranger in a secluded part of the park who said he was going to do something she wouldn’t like in retaliation for her annoying him.

On the other hand… he could have just walked away. I can’t count the times I’ve been in a big city, saw someone doing something they obviously weren’t supposed to, and did exactly that. He chose to confront the woman when it wasn’t necessary. When she resisted, he upped the ante in a way which was intended to frighten the woman into compliance, and then the situation blew up. And, for her part, the woman clearly knew she was violating the rules, and could have chosen to simply appologize and clip the leash back on her dog (even if only until the stranger had moved along). Moreover, the man was still calm, and keeping his distance, and so was clearly not an imminent threat. Both of them had opportunities to de-escalate the situation, and neither of them made that choice.

Is the woman racist? Maybe, but I don’t think this one incident provides enough data to actually be sure. I expect what the man said and did would have been enough to frighten me, no matter what he looked like. If she has some subconscious association between black men and crime, then she would have been all the more frightened. However, I don’t find it unreasonable that she would have been frighted enough to call the police even without any extra factor from subconscious racism. So, I don’t think we can make any real judgement from the little data this incident provides.

This, of course, calls into question the justice of everything else the woman experienced after this incident became public. However, it’s clear that her employer didn’t want to take the risk of becoming entangled in the situation—no matter what truth was behind it—and cut their losses as soon as it became publicly embarassing. Maybe the woman actually is racist, and this was a good call. Maybe not. As I said, I, personally, don’t think this one incident is enough to go on. To my mind, that makes her company’s actions at least somewhat cowardly, if not blatently unjust.

✧✧✧

I view the original incident as a misunderstanding between two people who wanted to “win” the encounter. When neither was willing to back down, the whole incident blew up.

The real tragedy is what happened later, and I think it demonstrates the value of “classical” journalism as an intermediary between ourselves the messy fragments of truth actually available. However, it’s been a long while since we learned about the world only through the eyes of mature, responsible journalists who knew how to spell “objective.” They’re still out there—to be sure—but they are now largely buried by the flood of social media and clickbait stories designed to stir us up.

This means we’re largely on our own to become such journalists as we used to have as our intellectual first line of defense. We have to take responsibility for turning the messy fragments of reality which find their way onto our screens into a cohesive, objective whole before reacting. I’m certainly guilty of falling short here (all too often, I’m afraid). So, I’m personally taking this as a reminder to check whether I’m falling into the trap of provocative so-called journalism, whether I think I actually am working with all the facts before coming to a judgement of my own.

Muhammed Ali asks: Why is everything white?

click to watch the video

He tells the story as though its a funny anecdote, and everyone’s laughing, but you can still see how earnestly he wants you to hear him and really consider: why is everything white?

Thinking on this and similar subjects has made me make small changes in my own writing. For example, as I was previously thinking a lot about sexism, I started to write about “humans” or “people” instead of “men” when I want to talk about everyone in general, and to use “they” as a singular pronoun when the subject’s gender isn’t known. It’s an easy change for me to make, and demands nothing of my readers. And, it breaks the needless ambiguity that “men” can be used both to mean a group of males as well as a group of people in general.

I suspect, having listened to this, I’ll find more things to subtly alter: not to be more PC (which I generally despise), but to be more clear with my actual desired meaning.

Access Denied! (or how S3 permissions can be super confusing)

I’m currently working on a feature for runbooks.app which allows users to upload images for their runbooks. I’m using the Python boto3 library to make a PutObject API requests. Simply provide the bytes, the target bucket, and object key, and you should be all set. However, to my considerable frustration, I spent most of the morning trying to figure out why I was getting this error:

botocore.exceptions.ClientError:
An error occurred (AccessDenied)
when calling the PutObject operation:
Access Denied

Not super helpful, as there are, of course, a whole host of things which could be wrong.

Access Keys

I wanted my bucket to only be available to a specific IAM user I set up for my application code. This user should only be given permissions for the specific API operations I want my code to perform: and nothing else. When you set up the user, you’re given an Access Key and a Secret Access Key. The former is a jumble of letter which identifies the account, and the latter is a shared secret so AWS can be sure the request comes from a trusted source.

I’m using Heroku, so I went to my application’s settings page to verify that my Config Vars contained the correct values. They did. So, that wasn’t the problem.

User Policy

Each new user you create in IAM has a section which specifically lists what things that user is permitted to do. There are many ways to assign permissions. You can create a separate policy and associate it with that user directly. You could make such a policy, associate it with a group, and then add the user to the group. You could assign the policy to a role, and then have that user don that role temporarily to do its work. You can even create an inline policy which is merely attached directly to that one user.

It turns out, you don’t need any of that if the user is specifically called out in the access policy for the object being accessed. So, in the end, I could simply remove all policies, groups, and roles from the application’s user so long as the S3 bucket call it out specifically.

Bucket Policy

Each S3 bucket can have its own security policy which specifically lists what each user (group, role, etc.) is permitted to do. As I before, I wanted to limit this user’s access to just those functions I knew my code was going to try to perform. So, I created a bucket policy which looked like this:

{
    "Version": "2012-10-17",
    "Id": "policy-123",
    "Statement": [
        {
            "Sid": "statement-id-123
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::<user-id>:<user-name>"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::<bucket-name>/*"
        }
    ]
}

I knew I was only ever calling the PutObject API, so I didn’t want to grant any more permissions than that. However, no matter what I did, I kept getting the error message at the top of this post stating that I didn’t have permissions to do exactly the action listed!

After much fiddling about and reading of StackOverflow, I found the solution. I needed to grant more permissions!

{
    "Version": "2012-10-17",
    "Id": "policy-123",
    "Statement": [
        {
            "Sid": "statement-id-123
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::<user-id>:<user-name>"
            },
            "Action": [
                "s3:PutObject",
                "s3:PutObjectAcl",
                "s3:PutObjectTagging"
            ]
            "Resource": "arn:aws:s3:::<bucket-name>/*"
        }
    ]
}

Even though I was only calling PutObject myself, the implementation of that API endpoint was both trying to set up the Access Control List (ACL) for the newly uploaded object, and, since I included some tags in my PutObject request, it was trying to set those as well. It was failing at both because I hadn’t set up those permissions.

The thing which threw me off the scent was the error message. It was merely saying that it couldn’t perform the PutObject API request because some permission was lacking. If it had clearly stated which permission was actually lacking, I would have been past this whole thing in a second. Instead, I erroneously assumed that the “PutObject” part of the message was referring to what I need to know in order to solve the problem (i.e., the name of the missing permission), not what I already knew (i.e., the name of API endpoint)! Since they have the same exact name, I thought telling me that it was lacking the one permission it actually did have!

So, a few lessons learned:

  • User policies aren’t actually needed if the user is specifically mentioned in the bucket policy.
  • If you get an access-denied message from AWS, the error will only mention the API which it couldn’t perform, not the actual permission it is lacking.
  • API calls may require several permissions beyond simply the one which shares the name of the API call. Some of these are conditional, depending upon which additional parameters you provide in your call.
  • AWS continues to have the most byzantine APIs and documentation in the business.

Giving an excellent technical interview

There are several things I do in my technical interviews which I think make the experience quite a bit better than your average interview.

The first step comes before the actual interview in selecting the technical question. I have a few which I’ve created myself based upon actual problems I faced as a professional developer. They are, of course, somewhat simplified to be able to fit into an interview time slot, but they have the ring of a “real” problem rather than some annoying “toy” problem. Each question is intended to have multiple “extra features” you can add to it, so every candidate is able to complete at least part of it, and exceptional candidates can complete several. Only once have I had a candidate who completed all of the sections I had prepared.

Second, as the interview starts, I deliberately adopt a fairly casual, friendly, outgoing attitude, and chit chat. If possible, I try to crack jokes, and put the candidate at ease. I try to get them to tell me stories about something which will give me a sense of whether they’d be a good culture fit with the company and our team.

Then, as I introduce the technical question, I make a few points right up front to try to take some of the anxiety out of it:

  1. This is a pair-programming exercise, and the primary point is to see how well we like working together.
  2. I’m not particularly interested in seeing how much of the language you’ve memorized; if you’re uncertain on something, just ask, and we’ll look it up, if necessary.
  3. I’m not as much interested in how quickly you solve the problem, but how you approach the problem, and how you think it through.

At this point, I turn my laptop around for them, and either project the screen or slide my chair around so I can see what they’re doing. On the laptop is a basic IDE already set up with a “hello world” program and a simple test case. There’s also a browser with Google brought up.

I think this is the most important part.

I want to make the impossibly contrived interview situation as close to actual working conditions as humanly possible. Starting with a simplified, but realistic problem, continuing with real tools (i.e., IDE and Google), and ending with us looking at the same screen, side-by-side, I’ve tried to emulate, as closely as possible, a situation developers find themselves all the time: pairing up to write a piece of code.

As we start to work on the problem, I try to strike a balance between being a helpful part of the pair programming team, and leaving enough of the problem for the candidate to solve that I can evaluate their performance. The more junior the candidate, the more helpful I am. The more senior, the less. If a candidate seems to be stuck at any point, I’ll suggest a possible solution.

During this process, I will deliberately probe a candidate to see how they react when:

  • I suggest something which isn’t the best solution.
  • I directly contradict a course they had chosen.
  • I point out a minor typo or error in their code.
  • I press them to justify a design choice.

I never interrupt the natural flow of the conversation to do these things, but I always have my eyes open for an opportunity to slip them in. In all of them, I’m looking for the candidate to have the best possible answer in mind, and to neither try to boost their own ego or mine.

As we get to the end, I keep my eye on the time (easy, since we’re looking at my laptop where I keep it up in the corner), and let them naturally stop when we get to the end of a part with somewhere between 5–10 minutes left. At this point, I let the candidate ask me questions for the remaining time.

✧✧✧

I think the important take-away here is to try to make the interview feel as much like a pair-programming session on a real problem as possible. Pick a problem which isn’t directly from an algorithms textbook. Set up a real development environment for the candidate (for coding questions). Sit next to the candidate and look at the same screen, just as you would for a pair-programming session (or stand at the whiteboard with them, for a more design-y, less code-y question). Finally, don’t interrogate the candidate, or just let them squirm if they’re stuck; be a good member of the “pair” and help them along.