Mike Bland


Most recent posts

122 posts total. See Filtering and Navigation for tips on how to find the bits in which you're interested.

I've just released go-script-bash v1.1.0, which adds some major new features, two new builtin commands, and multiple bug fixes and internal improvements.

- London
Tags: Bash, dev tools, go script, Linux, Mac OS X, programming, technical, testing, Windows
Discuss: Discuss "go-script-bash v1.1.0" on Google+

You may not be surprised to learn that I’ve left the country—but I’ll be back in a few days. I’m visiting my colleague Ben Grinnell, whom I met at DevOps Enterprise 2015 and who invited me over to discuss a potential short-term opportunity at the beginning of the new year. Promises to be tons of fun if we can pull it off!

In the meanwhile, you may also not be surprised to learn that I’ve gone plunging through rabbit hole after rabbit hole in Bash again, and I’m proud to’ve just released go-script-bash v1.1.0. This release adds some major new features, two new builtin commands, and multiple bug fixes and internal improvements. The release notes contain all the highlights. Enjoy!

I was forcefully reminded of the wages of complacency last night, in a rather intense, personal fashion. I'm ready to act.

- Alexandria
Tags: personal, philosophy, politics
Discuss: Discuss "The Triumph of Evil" on Google+

The only thing necessary for the triumph of evil is that good men do nothing. — attribution uncertain

This is another personal/political post, the first of what I intend to be many more.

Like over half of American citizens, I’m horrified by the outcome of the 2016 election, and have been struggling to come to terms with what happened and how to move forward. As if having Donald Trump as President wasn’t bad enough, Republican control of both houses of Congress and the potential for multiple Supreme Court vacancies has me terrified that most of the social progress we’ve made in the last fifty years or so is in grave danger of being undone for generations. This to say nothing of the economic and foreign policy consequences, which appear by all indications to prove just as disastrous.

So much has been written about the disgust and terror and shame that has rippled through large parts of the country ever since. At this moment, I struggle to do it justice in my own voice. I see it, I feel absolutely terrible about it, yet I know that being a white man, these feelings are slower to take hold in me to the same degree that they’ve gripped minorities and women from the beginning. I don’t want people in my country living in fear of anyone, especially people who look like me, yet who couldn’t disagree more with the decision that so many of my ethnic peers made.

Well, last night, I got enough of a taste, up-close and in-person, that’s compelled me to break my personal silence and begin feeling out an actual path forward, rather than quietly deliberating until I feel I’ve got all the right words in the right order first. And it appears that for the second time in my life, OKCupid is playing a pivotal role.

First date
First thoughts
Last straw
Next steps

First date

Yeah, that’s right: OKCupid. I’ve only hinted once in my blog about how OKCupid was on the critical path of my entry to Google back in 2005 ("Request for Berklee Tips"). I’m not going to tell that story just yet. But after eleven years of no online dating at all, and two years of running through sand with ankle weights on wondering where are the available women my age are, I caved in and joined again three days ago.

There’s a bunch more I can say about all of that, but I want to focus on my first offline encounter with a woman I met through the site, an encounter that’s lit a fire under my ass in a way the election results themselves have not done up to this point. I don’t want to give away too much identifying information about her, but she’s 100% American, raised in Arlington, whose parents emigrated to the United States from the Middle East in the 1970s. We rather quickly got on the topic of the election, and commisserated for hours about how horrible it was, and why it happened, and what to do about it. The conversation’d drift to other topics, but we kept circling back. It was really going quite well for a while; we both seemed to feel so relaxed, agreeing on many points, and arguing alternate perspectives and openly listening to what each other was saying.

First thoughts

A lot of what I was bringing up was something I’d articulated in an email with another woman I’ve met on the site, who’s white but also pretty shaken up about the election results. She lamented that so many apparently fell for Trump’s con man rhetoric, and that all she seems able to focus on now is that we’ve got “a misogynistic crazy man in the White House”. I 100% agree with her diagnosis of the man, but I went on to explain my perception of the danger those of us who oppose Trump now face, and my current thinking on how to move forward, which I’ll paraphrase here.

I don’t think most people who voted for him actually fell for most of what he said. In fact, I’m wondering if the Democrats weren’t largely to blame for the outcome as well. They actually did kind of rig the primaries against Bernie—another populist who I now believe would have been certain to win against Trump—in favor of a political dynasty candidate—the one who played by every rule, the one who’s “turn” it was to win—and the party as a whole hasn’t really reached out and listened to the white, blue-collar, uneducated masses for years. The result: the mounting frustration over feeling ignored by “coastal liberal elites” combined with Republican-stoked jingoistic fear of “the other” led to people voting out of desperation. You could say they voted irrationally, but honestly, I think they had their reasons.

And I say this as a “coastal liberal elite” who’s just now, like so many others, recognizing the massive strategic error of our highly-intellectual, cosmopolitan, egalitarian ways. It’s easy to write off the Trump voters as entitled, uneducated, irrational, reckless, and plain stupid and/or bigoted; but while many of them undoubtedly are, I think there were plenty of clear-thinking folks who love the country just as we do who decided that a vote for Trump wasn’t a vote in support of his policies and behaviors, but a vote against a political establishment that chose to ignore their voices in pursuit of their own political agenda.

To make it more personal, have you ever had a partner that you felt didn’t understand you, or condescended to you, or failed to demonstrate even an interest in exercising empathy for your perspective and feelings? It really kinda sucks, and I think this was the feeling that enough of the electorate had to produce what would normally be an unthinkable outcome. They took action to address their issues using the best means available to them—and I’m relieved they used the ballot box rather than their rifles. In that respect, the American system of government continued to work as designed, thankfully.

So I think the most powerful thing we can do to prevent all the social, economic, and foreign policy progress in recent years from reverting back to early Cold War-era levels is not to focus on obstructing the Trump presidency at all costs—to commit the same injustice the Republicans inflicted upon President Obama—but to find out how to reconnect to that part of the country that clearly felt uninvited to the party. We will need to stand against bad policy positions, of course, but the focus needs to be on the outcome of the debate, not demonization of the other side. Whether older whites have “historically” been entitled—which, yes, they totally have been—is an orthogonal issue to the practicality of working towards forward progress for the entire American population. Belaboring that former point won’t win the next round of elections.

I see Donald Trump as a decoy in a sense, a distraction from the deeper issues that resulted in his rise to power. I’m worried that being focused only on him will only serve to strengthen those forces, when we should be eroding them to make sure history corrects itself sooner than later, with as little further damage as possible. (This tendency to look at social foundations is probably why I became such an advocate for automated testing, documentation, and organizational change. There are parallels.)

Last straw

Back to last night. At some point, as the hour grew later, I apparently made the mistake of being too cautious with my words. I had intended to express that there’s probably no way I could be as viscerally affected by Trump’s rhetoric and subsequent election as those who were directly targeted by it, because I want to be genuine in my expression and not come off as superficial by claiming that, as a white man, I feel the existential threat to the same degree. That triggered something in her, and before I knew what was happening, the conversation spiraled out of control. Suddenly, this very intelligent, mature, thoughtful woman was pouncing on my choice of words, practically shouting over everything else I was trying to follow up with. I quickly saw that there was nothing satisfactory I could say at that point, and pointed out that, you know, I felt like she suddenly switched from seeing me as a person to seeing me as a stereotype. She said yes, she did, and kept going. She called me lazy, complacent, and—worst of all—cowardly.

I decided to shut up and listen for a few minutes, to see if she’d get it out of her system, calm down, and salvage the situation. But what actually happened is that she went on autopilot at that point. After a couple more minutes of sitting there and listening to all the pain and the outrage and the fear pouring over me in the most personal (and unfair) of terms, I’d had enough. I threw up my hands, said “I’m done,” and walked out without another word and without looking back, while she continued to spew invectives at my back.

Yes, I was offended, and angry. I felt unfairly typecast and judged, tried and convicted in her mind with no hope of a retrial. I felt like she had napalmed the bridge we had been building for most of the evening, because she interpreted something I said in the worst possible way and regarded it as an unforgivable sin.

In short, I felt like she turned the hurt and betrayal she felt at the election back onto me, because I was a convenient target. I felt like it was a taste of the pain and fear and anguish that she and so many others have felt long before the election, and even moreso since. And unfairly as she may have acted towards me, her feelings and fears are 100% legitimate.

Next steps

I don’t expect she and I will ever speak again. I’m OK with that; I feel like it’d be difficult to trust her now, since she’s demonstrated that she can be quick to dispense with empathy for someone who’s genuinely trying to connect on a personal level, that she’s quick to reach an immediate conclusion about someone at the expense of further communication. Though I’m open to the possibility of being wrong in that assessment, I went through something similar with my last breakup almost two years ago, and I’m not going to put up with that kind of treatment ever again.

But I am man enough to admit that there was a kernel of truth in what she said, painful as it was to hear: I’ve been too silent up to this point. And as stated by the quote that opened this post, that may make me just as complicit in the fallout. How does the saying go? “When they came for the Jews, I said nothing; when they came for my neighbors, I said nothing; when they came for me, there was nobody left.”

So she challenged me in an important way. She did so very poorly, and here was what I was trying to point out all throughout the evening: The temptation is strong to turn the Republican’s own hatred and intimidation tactics back on them, or onto anyone who may unintentionally trigger the hurt. An eye for an eye. But we all know that eventually we run out of eyes.

This is a very natural human impulse, and sometimes when you fear for your existence, you have to use dangerous and deadly force. But what happens after the immediate threat passes? What retaliatory action will the other side take in response? How far will the escalation go? When will it end? Genocide?

As a direct consequence of that encounter, I’m writing this as the first step in an attempt to live my values publicly, rather than merely ruminate about them privately. Just as she is perfectly justified in feeling threatened by the outcome of the election, I’d’ve been just as justified to throw her hurtful words back at her, pointing out that she’s just as guilty of the same lizard-brained stereotyping and demonization as those who voted for Trump last week.

But I knew that doing that wouldn’t’ve helped a damned thing, and in fact would’ve only made it worse. The cycle can’t be broken by perpetuating it. Turning the other cheek isn’t about backing down, it’s about standing firm in the face of injustice with the focus on the larger game of putting a stop to it altogether. That requires the imagination, courage, patience, and tenacity to rise above evil and pull it out by the roots rather than allowing yourself to get absorbed into it—especially when you realize that all too often it’s caused by a good person, or good people, at least as fleshy and vulnerable and scared as you are, reacting to a very bad situation.

No problem can be solved from the same level of consciousness that created it. — Albert Einstein

Some background on the .about.yml project metadata format prompted by an unexpected inquiry from the TODO Group.

- Alexandria
Tags: 18F, programming, technical
Discuss: Discuss ".about.yml background" on Google+

This morning I received an email from Will Norris of the TODO Group, which I wasn’t aware of before. Turns out he’s been trying to launch a discussion about storing project metadata in a portable fashion, and is interested in the .about.yml format that I and some colleagues were developing at 18F.

What follows is a brain dump spurred by Will’s questions in an offline thread. While I’m no longer at 18F or in the government, I remain willing to help cultivate the .about.yml format however I might.

Note on code.gov


Here’s the collection of .about.yml-related repos (and a direct link to the existing schema):

This was part of my attempt to recreate the kind of internal visibility experience that I had at Google (Googlers: think PDB+Moma, specifically), fit to the 18F environment and largely depending upon repo-based metadata rather than a centralized database (which could, of course, be automatically constructed and queried by a front end). The idea was that this would then feed into static (primarily Jekyll) sites, keeping costs and security concerns at a bare minimum, given the presence of a suitably technical employee at an agency.

I also hacked a little Node.js server to automate feeding data from .about.yml files and other sources into the 18F Dashboard, though it was a little janky:

Still, as a fragile proof-of-concept, it did mostly work.

The idea of .about.yml was somewhat popular within 18F; neither I nor the other folks actively developing it had to poke people too hard to try it. It was basically an evolution of the monolithic projects.yml that used to exist as part of the 18F Dashboard repo, so the YAML-based format was familiar and noncontroversial. John Jediny and Phil Ashlock of the General Services Administration’s Data.gov team were also keen on helping develop it.

There were a lot of open questions and discussion around parts of the schema, even when I left 18F in March. It wasn’t so much contentious as inconclusive, given the greenfield nature of the project and the limited resources available.


We didn’t so much create a new format as extract one from existing practice within the team. As mentioned above, the 18F Dashboard was a Jekyll site that had a monolithic _data/projects.yml. I started playing around with that as a data source for my earliest 18F project (the Hub), and eventually the one file became many, one file per project. What started as a site-specific data source was becoming a more general repository of team metadata, and I wanted to use the Hub to surface more than what appeared on the Dashboard. (The idea being, the Dashboard would be a higher-level view for an external audience, and the Hub a detailed view for internal folks and those with a deeper interest.)

When I politely asked project managers over Slack to please update their data one day, I got one particularly obstinate person pushing back and saying it was basically too much work to ask them to keep this data up-to-date. Somehow my frustration over this reaction (how is it not in a PM’s wheelhouse to maintain an accurate repository of project metadata?) led to the insight that if the metadata was in a project’s repository, it shouldn’t be too much of a context switch for the PMs and devs on the project to keep it up-to-date. Then I could hack something to automatically harvest it and join it with other metadata sources—hence the Team API, which exposed the metadata as a fully-connected graph represented as JSON. (I was on Instant Indexing my last two years at Google, so I love joining things; I even created hash-joiner and lambda_map_reduce as separate, reusable components.)

I also wasn’t personally aware of anything resembling project metadata beyond what’s typically found in .gemspec files, package.json files, and the like. These seemed relatively limited, and things got awkward when a project contained more than one language.

Trying to model multi-repo projects was another topic we were trying to hash out, but we hadn’t yet arrived at a firm resolution by the time I left. Still, .about.yml seems better suited to an eventually successful model than any of the other formats of which I’m yet aware.

On top of that, I find YAML easier to edit and structure than practically any other text-based data format (even text-based protobufs). Don’t think I’m particularly unique in that regard. It’s also more accessible to the hardier non-technical folks on the team.

Note on code.gov

I know a couple of the folks that’ve contributed to code.gov, but even without talking to them in months, I’m practically certain they chose JSON for the code.json metadata format because it’s published as a website endpoint, where you generally want JSON instead of YAML. I can imagine the code.json schema somehow blending with .about.yml, and then compiling the code.json file very easily from an .about.yml file, just like the team_api gem compiles the .about.yml file and other inputs to JSON.


So out of familiarity, frustration, ignorance, laziness, preference, and necessity, .about.yml was born. It’s not that I wanted to reinvent the wheel, I just wasn’t sure if anyone else already had, and no one else on the team seemed aware of an existing wheel, either.

As for future development of the .about.yml format, whether it’s evolved or absorbed into something more general, I’m happy to participate. I’m certainly not possessive about it; now just as well as then, I’d like to see a workable standard solution emerge that helps people discover information about projects, government or otherwise, regardless whose fingerprints are on it.