Author: Christie Koehler

software engineer, geek, yoga practitioner, bike commuter, zen buddhist, queer, vegan, legion of tech board member, osbridge planner, engineer@ShopIgniter

Join me in Supporting the Recompiler for Year 3

My good friend and colleague Audrey Eschright runs indie publishing company Recompiler Media, which produces the feminist tech zine Recompiler and a companion podcast of the same name that I co-host.  It also publishes important books such as the Responsible Communication Style Guide, edited by Thursday Bram.

Right now, Audrey is running a Kickstarter campaign to fund Year 3 of the Recompiler. If you’re able, please contribute what you can to this awesome effort. There are some fantastic backer rewards. If you select the “Community Builder” package, you’ll get a copy of the Responsible Communication Style Guide, the 1st edition of Community Event Planning, along with updates as we complete chapters of the 2nd edition.

That’s right! We’re doing a 2nd edition of Community Event Planning, our guide on how to organize community-focused tech events and if you support the Kickstarter you’ll get a copy of the new and current editions. I’m thrilled for the opportunity to share even more of what we’ve learned about organizing community through events, including first-person accounts from organizers of all kinds of events. The new edition will include sections on selecting the best talks and activities for your event, budgeting (with examples!), logistics, inclusion, and building your team.

To celebrate the Recompiler and all its great content (and to inspire you to join the Kickstarter), we’re doing our first telethon! It’s this weekend, Saturday, 11 November from 10am-4pm PST. I don’t have the links to the livestream quite yet, but will update this post soon with all the relevant details. Stay tuned! One of the things we’ll be doing during the telethon is answering your questions so submit them here.

Please tune in on Saturday and join me in supporting the Recompiler for Year 3!

Using Zapier and OmniFocus to stay on top of meetings

(If you like this post, you might also like Using Zapier to import GitHub issues into OmniFocus.)

I use OmniFocus for personal task-tracking and Zapier to automate work when possible.

One way I use these two tools in combination is to automatically create tasks when a new event is created on my work calendars.

The two tasks look like this:

  • Meeting Prep: Call with Robert Smith, with a due date the day before the meeting is schedule.
  • Call with Robert Smith, with a due date the date the meeting is scheduled.

In OmniFocus this looks something like:

The reasons I create two tasks in OmniFocus is because I use a few applescripts to generate daily and weekly task reports and forecasts and I like to have a record of my meetings as well as the prep work I do for them in those reports.

What you need to setup this integration:

Optional tools include Hazel or Lingon to automate the running of the ParseInbox applescript.

Before I continue, thank you to Joe Buhling for sharing his collection of OmniFocus scripts!

Part 1: Create Zap

Step 1: Google Calendar app, New Event trigger

First, select the Google Calendar app and the New Event trigger:

Next you’ll need to configure the connection to your Google account (if you haven’t already):

Then you’ll select the specific calendar from which to retrieve new events:

That’s it for this step. Don’t forget to test the step before moving on to be sure you can retrieve an event.

Step 2: Formatter app, Date/Time trigger

In this step, we’ll take the start date of the meeting and subtract one day to get the due date for our Meeting Prep task.

Select the Formatter by Zapier app and the Date/Time trigger:

Next, you’ll set the following fields:

  • Transform: Add/Subtract Time
  • Input: Step 1 Event Begins (Pretty)
  • Expression: -1 day
  • To Format: Use a Custom Value (advanced)
  • Custom Value for To Format: MMM D, YYYY

(The script I’m using to parse OmniFocus Inbox items doesn’t handle date formats with times well which is why in this step we’re also formatting the date as MMM D, YYYY.)

 

Continue and be sure to test the step before moving on to the next one. The output should look something like:

Jun 8, 2017

Step 3: Formatter app, Date/Time trigger

This step is similar to Step 2 except that we aren’t going to modify the date, just format it so it works with the script we’ll use to parse our OmniFocus Inbox.

Select the Formatter by Zapier app and the Date/Time trigger as before. This time you’ll select Format as the Transform value:

  • Transform: Format
  • Input: Step 1 Event Begins (Pretty)
  • To Format: Use a Custom Value (advanced)
  • Custom Value for To Format: MMM D, YYYY

Continue and be sure to test the step before moving on to the next one. The output should look something like:

Jun 8, 2017

Step 4: OmniFocus app, Create Task action

In this step we’ll create the first of our two tasks, this one for Meeting Prep.

First, select the OmniFocus app:

Select OmniFocus app for Step 4.
Select OmniFocus app for Step 4.

Now select the Create Task action for the OmniFocus app:

Select create task action for OmniFocus app.
Select create task action for OmniFocus app.

Next you’ll need to connect your OmniFocus account if you haven’t already and select which connection you’d like to use.

Next, set up the create task action. You’ll configure only the Title field as such:

--Meeting Prep: Step 1 Summary @Meeting Prep ::Project name #Step 2 Start Datetime Pretty //Step 1 HTML Link

Let’s break this down:

  • The -- sets the name of the task.
  • The @ sets the context.
  • The:: sets the the name of the project.
  • The# sets the due date.
  • The// sets the text of the note.

Two notes:

  • The name of the project is fuzzy matched against flatted name of folders and projects, so you don’t need to use a colon between folder and project name.
  • With the applescript I’m using to parse OmniFocus’ Inbox, I had trouble with dates including time, so this is why I simplify the due date format in Step 2 and 3 of the Zap.

For details on the syntax used for parsing the inbox, see this post.

Here’s what the the task looks like in Zapier:

As always, test the action before proceeding to make sure everything looks right before continuing on. You test should look something like this:

Step 5: OmniFocus app, Create Task action

In this step we’ll create the second of our two tasks, this one for the meeting itself.

As in Step 4, select the OmniFocus app and Create Task action.

The Title field for this Create Task action is slight different as is the due date:

--Step 1 Summary @Meetings ::Project name #Step 3 Start Datetime Pretty //Step 1 HTML Link

Here’s what it looks like in Zapier:

Next, test the action before proceeding to make sure everything looks right before continuing on. Your output should look something like this:

Part 2: Parsing tasks in OmniFocus’ Inbox

Step 1: Manually run the ParseInbox script

For this part, if you haven’t already, you’ll want to grab a copy of the AutoParser scripts from either the original author or myself.

The repositories linked to above contain a collection of applescripts for use with OmniFocus. (Thank you Joe Buhling for putting these together!)

There are two main options for running the script manually.

Option 1: You can run any of the scripts from the command line with the osascript command:

/usr/bin/osascript "/Users/christie/Bin/OFScripts/Auto-Parser/ParseInbox.applescript"

Option 2: If you don’t want to use the command line to run scripts, you can copy the ParseInbox.applescript into OmniFocus’ scripts folder. To find out where this is, go to Help > Open Scripts Folder in OmniFocus and it will open a new finder window at that location. Once you do this, you’ll see Script: ParseInbox as an option in the View > Customize Toolbar… window. Drag this icon to your toolbar for ease of use.

When you run the ParseInbox script, it will transform the Inbox task Zapier created that looks like this:

--install certbot @GitHub ::sustainbility index project kick off #06/08/17 //https://github.com/numfocus/collab-infrastructure/issues/30

Into the task install certbot, belonging to the project Project Kick Off in the folder Sustainability Index. The task will now have a due date of 6/8/2017, and note text that includes a link back to the original GitHub issue:

Task in OmniFocus after it has been parsed from Inbox.
Task in OmniFocus after it has been parsed from Inbox.

If at this point you realize that your Zap isn’t quite configured correctly or exactly how you want it, you can go back and adjust it. And, if you get tired of waiting for OmniFocus to sync with the server to retrieve the new task, just remember you can copy and paste the test output from Step 4 of your Zap.

Step 2 (optional): Automatically running ParseInbox

This step is totally optional and you can skip it if you’re happy manually running the script when you want to parse Inbox items.

However, if you don’t want to have to remember to do this, or if you want OmniFocus to be able to process Inbox items while you’re out and about, then you’ll want to automate it.

There are a few options for doing this. They all require your computer be on, but OmniFocus doesn’t have to be open (the script will open it if closed).

Option 1 is to use Hazel to run the script when your OmniFocus has been updated. Joe explains how to configure this option on his blog here. I had mixed results with this method. The script seemed to run sometime and not others. YMMV.

Option 2 is to schedule the script using launchd (macOS’s version of cron). This involves editing plist files, which I hate doing, so I bought Lingon X to make this easy.

Here’s what my settings for Lingon look like:

Lingon settings for scheduling ParseInbox script.
Lingon settings for scheduling ParseInbox script.

And the plist generated by Lingon looks like this:

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>EnvironmentVariables</key>
	<dict>
		<key>PATH</key>
		<string>/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/MacGPG2/bin:/usr/local/sbin</string>
	</dict>
	<key>Label</key>
	<string>of.autoparser</string>
	<key>ProgramArguments</key>
	<array>
		<string>/usr/bin/osascript</string>
		<string>/Users/christie/Bin/OFScripts/Auto-Parser/ParseInbox.applescript</string>
	</array>
	<key>StartInterval</key>
	<integer>300</integer>
</dict>
</plist>

Using Zapier to import GitHub issues into OmniFocus

I use OmniFocus for personal task-tracking and Zapier to automate work when possible.  I also coordinate open source work on GitHub. Recently I was wondering if there was a way to make OmniFocus automatically import any GitHub issue assigned to me. It turns out there is!

What you need:

Optional tools include Hazel or Lingon to automate the running of the ParseInbox applescript.

Before I continue, thank you to Joe Buhling for sharing his collection of OmniFocus scripts!

Part One: Create zap on Zapier

If you haven’t already, enable OmniSync and create a Mail Drop email address. You’ll also need a GitHub account and there should be a newly created issue assigned to you.

To get started, while logged into Zapier, click MAKE A ZAP! button.

Step 1: GitHub app, new issue trigger

Select GitHub as the trigger app:

Screen capture of selecting "GitHub" as trigger app.
Select “GitHub” as trigger app.

Next, select New Issue as the GitHub trigger:

Screen capture of selecting "new issue" as GitHub trigger.
Select “new issue” as GitHub trigger.

Next, set up the GitHub new issue trigger according to your preferences:

Screen capture of setting up GitHub issue trigger according to your preferences.
Set up GitHub issue trigger according to your preferences.

In my Zap, I’ve selected Only issues assigned to you and for the time being, I’ve limited it to a single GitHub organization. What you select is up to you.

Next, test this step to ensure it is retrieving the data from GitHub that you expect it to. Before you run the test, Zapier will remind you to have a recently created issue that matches your trigger options:

Screen capture of testing your GitHub new issue trigger.
Test your GitHub new issue trigger.

Once everything looks good, save the step.

Next, you’ll create a formatter step to format any dates attached to GitHub issues via their assigned milestones.

Step 2: Formatter app, date/time action

The app you’ll select for this 2nd step is Formatter by Zapier:

Screen capture of selecting step 2 app as Formatter by Zapier
Step 2 app is Formatter by Zapier.

The action you’ll use for Formatter is Date / Time:

Screen capture of using the date action for app Formatter.
Use the date action for app Formatter.

Next, set up the Date / Time action. You’ll want to set the following fields accordingly:

  • Transform: Format
  • Input: Step 1 Milestone Due On
  • To Format: MM/DD/YY
Screen capture of configuring date transform.
Configure date transform action.

Now test the action to ensure the result is as you expect. You’ll see something like:

Test results for date formatter action.
Test results for date formatter action.

Once everything looks good, save the step.

Step 3: Code by Zapier app, run Python action

In this step, I’m using Python code to map GitHub repository names to OmniFocus folders and GitHub milestones to OmniFocus projects within those folders. If you have a different organizational scheme, you’ll want to modify the code in this step accordingly.

First, select the Code by Zapier app:

For Step 3, select the Code by Zapier app.
For Step 3, select the Code by Zapier app.

Next, select Run Python as the Code by Zapier action:

Select Run Python as Code by Zapier action.
Select Run Python as Code by Zapier action.

(You could also select Run Javascript and re-write the Python code below in Javascript.)

Next, configure the Input Data for use with our custom python code. You’ll want to set the following:

  • repo: Step 1: Repository Name
  • milestone: Step 1: Milestone Title

The names of the fields on the left doesn’t really matter, but it must match the key names we’ll use in our Python code.

Configure input data for custom python code.
Configure input data for custom python code.

Next, you’ll enter the following Python code into the Code field:

# want to set the project as
# repo milestone
# or just repo if no milestone

output = {'project' : input_data.get('repo').replace("-", " ")}

if input_data.get('milestone'):
    repo = input_data.get('repo')
    milestone = input_data.get('milestone')
    project = repo.replace("-", " ") + ' ' + milestone.replace("-", " ")
    output = {'project' : project}

If the issue being processed by Zapier has a milestone, this code sets project to Repository name milestone name, replacing any hyphens with spaces. Otherwise, it sets project to simply Repository name, also replacing any hyphens with spaces.

This works for me because I organize NumFOCUS projects in GitHub like this:

  • [repository] my-project
    • [milestone] milestone 1
    • [milestone] milestone 2

And in OmniFocus, I organize projects like this:

  • [folder] My Project
    • [project] Milestone 1
    • [project] Milestone 2

If you structure your projects differently, you’ll need to update the Python code above accordingly.

When you’re ready, test the Python code and check to see that it creates the expected output:

Results of testing custom Python code.
Results of testing custom Python code.

When everything looks good, save this step and continue on to creating the 4th and final step.

Step 4: OmniFocus app, create task action

In this last step you’ll configure the OmniFocus app to create an OmniFocus task with information from the retrieved GitHub issue.

First, select the OmniFocus app:

Select OmniFocus app for Step 4.
Select OmniFocus app for Step 4.

Now select the Create Task action for the OmniFocus app:

Select create task action for OmniFocus app.
Select create task action for OmniFocus app.

Next you’ll need to connect your OmniFocus account if you haven’t already and select which connection you’d like to use.

Next, set up the create task action. You’ll configure only the Title field as such:

--Step 1 Title @GitHub ::Step 3 Project #Step 2 Output //Step 1 Html Url

Let’s break this down:

  • The -- sets the name of the task.
  • The @ sets the context.
  • The:: sets the the name of the project.
  • The# sets the due date.
  • The// sets the text of the note.

Two notes:

  • The name of the project is fuzzy matched against flatted name of folders and projects, so you don’t need to use a colon between folder and project name.
  • With the applescript I’m using to parse OmniFocus’ Inbox, I had trouble with dates including time, so this is why I simplify the due date format in Step 2 of the Zap.
  • If you wanted to dynamically set the name of the context based on some attribute of the GitHub issue (e.g. label), you could do that by modifying the Run Python action in Step 3.

For details on the syntax used for parsing the inbox, see this post.

Here’s what the the task looks like in Zapier:

Configure create task omnifocus action.
Configure create task OmniFocus action.

As always, test the action before proceeding to make sure everything looks right:

Test create task OmniFocus action.
Test create task OmniFocus action.

If this looks good, click Create & Continue to create the task. Once you do this, flip over to OmniFocus and wait for the task to appear in your Inbox. It’ll look something like this:

New task in OmniFocus Inbox.
New task in OmniFocus Inbox.

Now you’re ready to setup the script to parse that monster-looking task out of your OmniFocus Inbox and into the right spot!

Part 2: Parsing tasks in OmniFocus’ Inbox

Step 1: Manually run the ParseInbox script

For this part, if you haven’t already, you’ll want to grab a copy of the AutoParser scripts from either the original author or myself.

The repositories linked to above contain a collection of applescripts for use with OmniFocus. (Thank you Joe Buhling for putting these together!)

There are two main options for running the script manually.

Option 1: You can run any of the scripts from the command line with the osascript command:

/usr/bin/osascript "/Users/christie/Bin/OFScripts/Auto-Parser/ParseInbox.applescript"

Option 2: If you don’t want to use the command line to run scripts, you can copy the ParseInbox.applescript into OmniFocus’ scripts folder. To find out where this is, go to Help > Open Scripts Folder in OmniFocus and it will open a new finder window at that location. Once you do this, you’ll see Script: ParseInbox as an option in the View > Customize Toolbar… window. Drag this icon to your toolbar for ease of use.

When you run the ParseInbox script, it will transform the Inbox task Zapier created that looks like this:

--install certbot @GitHub ::sustainbility index project kick off #06/08/17 //https://github.com/numfocus/collab-infrastructure/issues/30

Into the task install certbot, belonging to the project Project Kick Off in the folder Sustainability Index. The task will now have a due date of 6/8/2017, and note text that includes a link back to the original GitHub issue:

Task in OmniFocus after it has been parsed from Inbox.
Task in OmniFocus after it has been parsed from Inbox.

If at this point you realize that your Zap isn’t quite configured correctly or exactly how you want it, you can go back and adjust it. And, if you get tired of waiting for OmniFocus to sync with the server to retrieve the new task, just remember you can copy and paste the test output from Step 4 of your Zap.

Step 2 (optional): Automatically running ParseInbox

This step is totally optional and you can skip it if you’re happy manually running the script when you want to parse Inbox items.

However, if you don’t want to have to remember to do this, or if you want OmniFocus to be able to process Inbox items while you’re out and about, then you’ll want to automate it.

There are a few options for doing this. They all require your computer be on, but OmniFocus doesn’t have to be open (the script will open it if closed).

Option 1 is to use Hazel to run the script when your OmniFocus has been updated. Joe explains how to configure this option on his blog here. I had mixed results with this method. The script seemed to run sometime and not others. YMMV.

Option 2 is to schedule the script using launchd (macOS’s version of cron). This involves editing plist files, which I hate doing, so I bought Lingon X to make this easy.

Here’s what my settings for Lingon look like:

Lingon settings for scheduling ParseInbox script.
Lingon settings for scheduling ParseInbox script.

And the plist generated by Lingon looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>EnvironmentVariables</key>
	<dict>
		<key>PATH</key>
		<string>/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/MacGPG2/bin:/usr/local/sbin</string>
	</dict>
	<key>Label</key>
	<string>of.autoparser</string>
	<key>ProgramArguments</key>
	<array>
		<string>/usr/bin/osascript</string>
		<string>/Users/christie/Bin/OFScripts/Auto-Parser/ParseInbox.applescript</string>
	</array>
	<key>StartInterval</key>
	<integer>300</integer>
</dict>
</plist>

 

How could GitHub announce an all-male conference line up the same week it shares results from an OSS demographics survey with 3% women?

(Post adapted from this twitter thread.)

This week, GitHub released results from a survey it did regarding the “attitudes, experiences, and backgrounds of those who use, build, and maintain open source software.” Of 5,500 responses from 3,800 open source repositories, only 3% of responses were from women.

Also this week, GitHub announced an all-male speaker roster for its upcoming ElectronConf and then promptly postponed due to negative feedback about the line up. The original roster is no longer available, replaced for the time-being with the following message:

“We published a list of speakers that does not reflect the standards to which we hold ourselves. We will be postponing this event until we can deliver a more diverse slate of speakers.”

It also appears the twitter account for the conference (@electronconf) has been switched to private.

How could this happen? How could an organization that appears to be working so hard to improve with regard to diversity and inclusion let such an embarrassing and totally preventable thing happen? Easily. Leadership isn’t truly committed to enacting change.

How can I say this without having any insider knowledge? Because I’ve seen it happen at other organizations. And I’ve studied organizational change and have learned it’s very difficult. It requires leadership be entirely committed to change and act accordingly.

I think we’ve all noticed how many diversity-minded folks GitHub has hired over the last two years or so. While I’m always happy when colleagues and acquaintances receive an exciting career opportunity, it makes me a bit nervous when an organization known to be problematic makes a bunch of hires like GitHub did. One way to quiet your critics, after all, is to hire them! And there’s a ripple benefit to this, too. Other people watching think, “Oh, GitHub hired so-and-so, maybe they can finally get their act together now.” Plus you don’t want to make someone you care about feel like shit by criticizing their employer and possibly their work, so you temper what you say.

Unfortunately simply hiring prominent diversity folks doesn’t actually solve systemic organizational issues. Those skilled in diversity & inclusion can help plan and guide improvements, but leadership has to do the hard emotional labor. And so, unless leadership is committed to change, if you come aboard to work on D&I or any other kind of major change, you are very unlikely to succeed. You might be able to make small improvements here and there, and even release some great product features. But wholesale organization change? No.

(A really good resource for learning more about this, particularly how you can make the most of being an individual contributor, is Who Really Matters: Core Group Theory and I wrote about it here.)

I know this from experience because I’ve been that senior hire at a prominent OSS company who hasn’t been allowed to do anything of real impact.

After nearly four years of one frustrating thing after another, what finally got me to quit Mozilla was this: In a planning meeting for the developer conference (View Source) that I was tasked with producing, the team organizing logistics, in response to me saying I was assembling an accessibility guide for them to follow, said something like “we don’t need an accessibility guide because we’re reasonable people.” This from the same team that had not a single accessibility-related item on their venue selection checklist. No one else present at the meeting, including my manager, said anything. Except for me, of course. I was livid. Having finally realized I would never get passed the hubris Mozilla engenders across its entire organization, I quit a few hours later.

I mention this because I think it speaks to how an organization like GitHub could so publicly and embarrassingly fail on diversity & inclusion and not realize it until it’s pointed out by external folks. Many people think that addressing the systemic issues required for improving diversity & inclusion is about being a good or reasonable person. It is absolutely not. It is about committing to change. To listening and learning, far outside of your comfort zone and doing that over and over again. It’s about bringing in subject-matter experts when needed and supporting them appropriately. It’s about identifying and getting rid of the people in your organization who obstruct change, even if they are ‘nice’ or even (especially) someone you personally like.

Lastly, I want to say: Don’t give GitHub any accolades for “admitting” it’s mistake and postponing ElectronConf. Postponing an annual event that’s six weeks away from happening is a major kind of fail. It jerks everybody around. GitHub selecting and announcing an all-male speaker line-up is not a coincidence or an accident. Diversity and inclusion, like security and UX, is not something you think about at the end of the product development process. Rather, it has to be a priority and an integral part of the conference planning process from the beginning. Whatever led to GitHub publishing the line up they did relates to systemic issues present throughout the development and planning of their conference. Any response that fails to speak to those issues and how they will be addressed rings hollow.

Support indie tech feminist Recompiler magazine + podcast

On Saturday, Recompiler Media, which publishes a print and online magazine as well as a podcast (hosted by me) turned two years old. Yay!

Audrey reports about year two accomplishments:

I’m very proud to be producing a podcast component of the magazine. We’ve shared interviews with amazing, thoughtful technologists such as Meli Lewis, Amelia Abreu, Helga Hansen, Sumana Harihareswara, Thursday Bram, and Heidi Waterhouse. We’ve talked about what happens when your toaster has a DNS bug, we’ve shared all kinds of creepy fun tech news, and we’ve figured out how to hop the internet.

But it’s tough because the Recompiler currently doesn’t generate enough revenue to pay me, so I do it for free, on the side, as a “passion project.”

Audrey provides more details in her post about where we’re struggling:

This is not a sustainable level of subscriptions, sales, and reader support. The way things are right now, we won’t be able to continue publishing The Recompiler into year three.

We know we have a lot of enthusiastic readers, and many of you contribute what you can. Here’s what we need:

  • If you forgot to renew your subscription, please do that! I send out reminders but there is a limited amount of time I can spend on admin tasks and still keep the articles coming.
  • If you’ve been meaning to subscribe: this is the time. We have print and digital options, and we can do invoicing or bundles for schools, libraries, and offices. Email us to discuss.
  • If you have the means to make a recurring contribution or sponsor an issue, this makes a huge difference in our ability to keep things running smoothly.
  • Finally, if you haven’t ordered a copy of the book yet, it will be out soon and it’s a great resource.

We need to bring in about $3000 by the end of the month in order to publish Issue 7 (security) on schedule.

Audrey has pledged the following: for every $500 in new subscriptions, renewals, monthly pledges, and sponsorships, she’ll find something fun to post on our Twitter account.

For my part, I am pledging:

  • For every $500 raised, I’ll record a dramatic reading of a tongue-twister for the podcast. (We’re up to $1588 as I type this, so I’m on the hook for three already. Can you help me it four? Five?)
  • If we exceed the $3k goal by 50% or more, I’ll figure out how to do the readings LIVE.
  • If you pledge $100 or more, I will read any short message of your choosing on the podcast (within reason, subject to our code of conduct).

Thanks for reading this far, and all your enthusiasm and support. We wouldn’t be able to do this without you!

Thoughts on recent Drupal governance decisions

(Content warning: This post discusses BDSM and abuse.)

[Updated 12:20 PDT 28 March 2017: Corrected spelling errors and added a few clarifications, including the opening notes 1-3 below.]

[Update 9:30 PDT 31 March 2017: Dries and Drupal Association have posted a thoughtful follow-up regarding this situation. Link added in-line below as well.]

[Updated 18:50 PDT 3 April 2017: Fixed minor typos. Added clarification about targets of kink-shaming. Added notes 4-5.]

[Updated 10:30 PDT 18 April 2017: Added notes 6 and 7.]

Note 1: In many contexts, including when talking about community governance, I use a rather broad definition of “abuse” and “abusive.” Abuse includes not just physical and sexual assault, but also repeated interpersonal misconduct as well as harassment. Interpersonal misconduct includes many things such as: lying, deception, and manipulation; violating the boundaries of others; not respecting the agency, autonomy, and equality of others; and more. These types of transgressive behaviors are often hard to detect and discern by others in a way that is actionable and can go on for a long time without the person engaging in them being brought to account.

Note 2: Many have characterized what I have written below as evidence of my passing unfair, hasty judgements about the contributor who was asked to step down from Drupal leadership. Some assume I made these judgements based on the sole fact of that contributor’s participation in the Gor community. In reality, I reviewed a lot of the contributor’s publicly available writing, including Drupal-related ones and formed my opinions based on that. If you haven’t done that and are vehemently defending the expelled contributor, I encourage you to reassess. And if you have and found the writing perfectly okay, I question your experience, maturity, and judgement.

Furthermore, I intentionally and specifically did not make direct statements about the “guilt” or “innocence” of the contributor or whether or not he is an abuser and nothing below should be read as such. Rather, the below should be read for two things: a) an explanation and refutation of common misconceptions people have about these kinds of situations when they arise, and b) a hypothetical alternative point of view of what might have happen in a situation such as what unfolded recently in the Drupal community.

Note 3: Several people have commented that Drupal has a Code of Conduct and a conflict resolution process, that it was followed and that the Community Working Group (CWG) found that the contributor had not violated the code of conduct. This is true, but doesn’t mean that there wasn’t a serious issue to address. In fact, the CWG indicated this to be the case and escalated up the leadership chain. Those who have experience in these matters know that even the most well-thought out and well-written policy isn’t going to handle every edge case and that you will need to have a process for handling those edge cases. That is, community governance doesn’t end with your code of conduct. In the most recent situation with Drupal, I believe they found an edge case where a contributor’s conduct was counter to the kind of community they wanted to foster but that they hadn’t accounted for in their code of conduct. (And, this doesn’t really surprise me, Drupal is using one of the weaker codes of conduct, one that I do not recommend, for this very reason, among others.)

Note 4: See this twitter thread for a follow-up analysis regarding those wanting a clear “victim” and wanting to know what the “rules” of conduct are. Also see this thread about consent and BDSM and this blog post about autism and compliance. See this thread for details on what makes me qualified to speak about the intersection of BDSM/Code of Conduct issues.

Note 5: A few people have asked which of the Drupal contributor’s public writings I read that informed my thinking on this issue. These include:

Note 6:  Below is a list of follow-up responses from various groups involved.

Statements from Drupal Community Working Group (CWG):

Statements from the Drupal Association:

Statements from Dries Buytaert:

Note 7: Members of the Drupal community and outsiders (including alt-right brigaders) who oppose the decision to ask LG to leave have created Drupal Confessions (DC) to pressure a reversal along with other governance changes. A lot of the language in DC’s statement reminds me of statements from LambdaConf organizer and Fantasyland Code of Professionalism (FCOP) author John de Goes. I wrote about what’s wrong with the FCOP earlier this year and updated my analysis in this twitter thread.

[Updated 19:10 PDT 14 July 2017: Drupal project lead Dries and Drupal Association have posted a joint statement regarding conclusion of this matter.]


The Drupal community recently asked a long-time contributor to leave. (See follow-up post from DA/Dries on the matter here.)

A lot of the public response I’ve seen has been negative. And, most troubling, the separate decisions by the Drupal Association and project leader Dries are being cast by some as bigoted and exclusionary. I am seeing this sort of response from folks who are normally supportive — at least on a surface level — of projects having a code of conduct and of supporting diversity and inclusion. Interestingly, I am also noticing who is staying silent about the manner — a lot of women and folks who I generally know to have experience and good judgement in this area.

I am not part of the Drupal community, though I was part of the PHP community for many years. I do not have insider knowledge of the situation.

From my view as an outsider, I think the Drupal Association and Dries made the right decisions. If anything, they likely could have acted more decisively and skillfully sooner than they did, but that is often the case with these situations. Hindsight is 20/20, of course, and the FLOSS community is just started to exercise these type of governance skills. We have a lot to learn and we’re going to stumble along the way.

What I want to address in this post are the misunderstandings and misconceptions I see repeated every time one of our FLOSS communities reaches the point of imposing significant consequences upon a long-term, well-known contributor. And I want to share an alternative idea of what might have happened, one not based in bigotry or ignorance about consensual BDSM.

BDSM is not a protected class

While those who engage in BDSM might feel marginalized by mainstream society, they are not, as a class, subject to oppression anywhere near equivalent to what queer and trans folks, non-Christians, people with disabilities, and persons of color are. I believe folks have a right to privacy, including in regard to their sex life, and don’t believe in kink-shaming. However, to equate engaging in BDSM in and of itself with being a member of an oppressed class is incorrect and gross. (Furthermore, on a personal note, I loathe the equating of BDSM and queer in this way because it re-contextualizes being queer as being about sex, which it’s not.)

Furthermore, I do not think folks are commonly ostracized from communities simply because it becomes known that they engage in consensual BDSM play. In fact, I’ve never encountered this at all. (Update 3 April 2017: When I wrote this I was thinking in terms of white, straight, hetero cis men as those who are not kink-shamed. I absolutely recognize marginalized folks are subject to kink-shaming. See Shanley’s twitter thread for more on this.)

What I do now to be common are the following two scenarios.

One, a non-BDSM community or community member sets a boundary and asks someone not to discuss their BDSM practices within that community setting. This is entirely appropriate. No one is entitled to share and have an audience to share the intimate details of their sex life whenever they want. This isn’t oppressive or bigoted. It’s reasonable and appropriate boundary setting. (Tangentially, it’s not appropriate to “come out” as BDSM either, especially during times set aside for queer folks to do that.)

Two, a BDSM or BDSM-adjacent community ostracize a community member who has been engaging in transgressive behavior. Usually this is abusive behavior conducted under the guise of consensual, above board BDSM but instead crosses the line of established norms and practices into abuse.

BDSM and Gor are not equivalent

Okay, so the bit about Gor is kind of specific this Drupal incident…I hope? Regardless, it exemplifies the kind of discernment skills we need to be able to apply in these situations. One (acceptable) thing can look like another (not acceptable) thing and we need to practice telling the difference.

Even a cursory bit of research tells you that Gor and BDSM are not the same thing. Predominantly, those who engage in Gor are into the philosophy (not the fantasy) of the Gor novels. These novels posit that women are intrinsically inferior to men and should be rightfully dominated by them. For many who call themselves Gor, these ideas exceed the realm of fantasy enacted as part of recreational roleplay and extend into their everyday world view. This fact, to me, crosses the line from the privacy-deserving consensual power exchange of BDSM into something unacceptable and deserving of scrutiny. A “lifestyle” follower of Gor is overwhelmingly likely to negatively impact any community in which they participate in a non-trivial way.

Perhaps this seems harsh. Maybe it is. I strongly believe folks have a right to whatever weird private life they want to have. But there are limits. If on weekends you like to roleplay as a Nazi in charge of exterminations at Auschwitz, or a white plantation owner who whips Black slaves, I have a hard time believing you are a perfectly decent person during the week at work. Maybe it’s possible, I don’t know. My personal experience with kink is minimal and tangential (never really my thing). But I know folks with kink experience and they confirm the Gor sub-community is not well-regarded.

(For more details about Gor and how it isn’t BDSM, check out this article.)

Slippery slope!

Some folks have invoked a slippery slope argument: Well, if we exclude folks based on their misogynistic private life, are we also going to exclude fundamentalist evangelical Christians who publicly espouse misogyny and homophobia?? To which is say: Yes.

Yes, it is okay, and, I would argue, just, to exclude people from your community who publicly express cis, white, male, straight, Christian, heterosexual supremacy (in any combination of those attributes). Those who do this are the people keeping everyone else who is not them away. You do not need to coddle or protect these people. If you think your project cannot survive without the support of white male supremacists and their enablers, stop to consider if perhaps you are part of the problem.

Lack of public details does not automatically indicate bad governance

Those of us who have been a part of FLOSS communities for a long time are used to certain ways of working. We’re used to “working in the open” via written, recorded media. We expect to be able to get up to speed on an issue by reading though a mailing list’s archives, an IRC channel’s log, or a bug’s comment thread. We feel entitled to access and absorb this information and then chime in with our own view of things, be it lay opinion or reasoned expertise, or something in between. We expect to have this point of view meaningfully considered in the process of decision-making.

These norms work relatively well for collaboratively producing software. They do not, however, work for addressing certain community governance topics, including most conduct issues. These require private communication, limited numbers of people involved in making decisions, and a vagueness when publicly reporting outcomes.

All but the most trivial issues regarding community members’ conduct requires careful handling. The security principle of least access necessary applies. Only those who need to be a part of the decision-making process should be party to the often very private details of conduct-related incidents. This is especially true of situations regarding on-going or long-term abuse.

When a decision is reached it is unwise and likely unethical to share the details of the evidence that was considered in making that decision. Public statements you make about individuals involved in the decision are subject to libel and defamation law suits. The more specific your statements, the greater the risk. Not only to project leads have an obligation to limit the liability they expose their projects too, they also have an obligation to protect the privacy of all those involved, perpetrator and victim alike.

Unlike with technical decisions, decisions about governance, especially conduct, can never be as transparent as we’d like. As such, a certain amount of opaqueness is not necessarily a sign of bad governance. In fact, it can be a sign of good governance. At best project leads should, if they are able, share the nature or category and volume of evidence considered as well as the process that was followed.

Because in these cases good governance prohibits complete transparency, it’s incredibly important that you trust your project leaders. And, likewise, it’s important that project leaders work to establish and build trust continually, not just when code of conduct issues arise.

Lack of understanding of abuse dynamics

Each time one of these conduct issues arise, I’m reminded of how insidious abuser dynamics are and how little awareness there is with in our community about how they work.

This lack of understanding combined with lack of information about specific incidents causes a lot of otherwise decent community members to come to the defense of those who have engaged in transgressive behavior, including serial abusers.

Abusers are master manipulators. They are adept at shaping how people perceive them and they use a whole array of techniques to do this, deflection and distraction chief among them. Abusers always have the upper hand when it comes to (mis)information because they aren’t playing by the same rules as the rest of us. They will lie, violate others’ privacy by reveling intimate details, and overshare irrelevant details. Anything they communicate serves the purpose not of genuine communication and connection, but of creating a particular outcome in their favor.

In terms of public opinion, organizations who take action against serial abusers are almost always at a disadvantage. It’s the prisoner’s dilemma (to use an imperfect analogy). You always lose when you play with a cheater unless you’re also a cheater.

Abusers leverage social power and privilege to gain access to potential victims and to maintain their ability to abuse. It’s not unheard of to discover abusers have been masquerading as advocates for women in tech, for example. Doing so gives them credibility, cover, and access.

Abusers groom victim as well as accomplices. This is an incremental and long-term effort. Abusers do not exist in a vacuum. Their abuse is enabled by others who look the other way, come to their defense, and otherwise provide cover. Perfectly reasonable, “good” people participate in this all the time. It’s hard to spot and hard to break away from. Abuse endures through denial. It’s “normal” for those subject to abuse to minimize and lie about what they experience until they’ve been able to breakthrough this denial. Having previously said good things about your abuser, characterized their behavior as okay, or come to their defense is not an indication you weren’t abused.

Most abuse is never reported. As such, most abusers aren’t reported until they’ve abused multiple people and most communities don’t or aren’t able to take action until they’ve received multiple reports about a single person.

Fruit of the poison tree

Sometimes we hear things about others we’d rather not have been told. Sometimes we are given information obtained through questionable or even transgressive means.

In US law, evidence obtained through illegal or improper means is usually excluded from consideration, as being “fruit of the poison tree.” While I think this is an important standard in criminal legal proceedings, I do not think it applies in the same way to community stewardship. I’ve written before about how communities can and should act extra-legally and I believe the same concept applies here.

So, as opposed to in a court of law, in community we must still account for the fruit of the poison tree, even when we’d rather not.

Earlier I invoked the prisoner’s dilemma, in which the only way to win against a cheater is to either not play or to cheat as well. Dealing with abusers is not all that dissimilar. It’s hard to gather enough information about a potential abuser in order to confirm their abuse, and to do so, you often have to play their game, at least a little bit.

Am I condoning outright digging into anyone’s personal life and sharing those details with project leadership or the public? No, I’m not. There’s great potential there for abuse, especially of already marginalized folks. But if that’s the only way to reveal serial abuser? Yeah, then a certain amount of it might be justified.

Furthermore, the appearance of poison fruit could be an intentional distraction designed to deflect blame, or even a mere coincidence. It is not unheard of for abusers, when their abuse is revealed, to claim discrimination or persecution based on some unrelated aspect of themselves, including participation in BDSM activities.

What might have happened

Again, I don’t have insider information about the Drupal situation. But I have been on the leadership side of complicated community conduct situations. It is never easy or straightforward.

In the case of Drupal, it’s my best guess that something like this happened:

It was an open secret that the long-time contributor (LTC) they asked to leave held problematic views. He did not act on them so egregiously as to provide a clear, unequivocable reason to expel him. Instead, some in leadership positions grimaced at LTC’s conduct, while others looked the other way, or failed to see the problematic behavior at all or as problematic. People warned their friends to stay away from this LTC and tried to shield them as much as possible from his bad behavior. At the same time, this LTC had allies who supported him and helped him maintain his leadership position.

Over some period of time, people started coming forward with reports of abuse by this LTC. As is often the case, the folks making the reports request privacy and that the details of their reports not be made public or otherwise shared widely (and so most of us will never have direct knowledge of it). Perhaps also at this time people who felt this LTC’s behavior was problematic took it upon themselves to try to help and started mining private message boards for incriminating information about him. They found some and shared with project leadership.

At this point, project leadership has several reports of abuse by this LTC (which they can’t tell us about in any detail) along with information about LTC private life they’d rather not know, but that they feel they must act upon, particularly in light of the several other reports of misconduct they’ve received.

So, project leadership works their process, perhaps skillfully, perhaps less so, and this culminates in LTC being asked to step down from their leadership position and/or leave the project. Being less than experienced at dealing with such issues and wanting to respect people’s privacy as well as limit the liability exposure of the project, they refrain from making a public statement.

The LTC, seeing an opportunity to gain back some of the upper hand, posts his own story in which he includes a bunch of semi- or completely irrelevant details, crying BDSM discrimination, in hopes of obfuscating and confusing the real reason he was asked to leave. Project lead, in turn, responds with a post attempting to explain as much as he can, as clearly as he can, without violating anyone’s privacy or exposing the project to a defamation/libel action.

I have no idea if I’m right, but that’s my intuition about what’s going on in this case. I certainly find the above scenario far more plausible than a project expelling someone who is otherwise completely decent for consensual BDSM play in their private life.

[quote] The oppressor consciousness…

Note: Much longer than usual quote from Freire today. It’s more important than ever to understand the oppressor mindset that Freire illuminates for us in the discourse below. While I could have shared bits of the following discourse over a few posts, I felt it important to keep this part of the analysis whole.  

The oppressor consciousness tends to transform everything surrounding it into an object of its domination. The earth, property, production, the creations of people, people themselves, time—everything is reduced to the status of objects at its disposal.

In their unrestrained eagerness to possess, the oppressors develop a conviction that it is possible for them to transform everything into objects of their purchasing power; hence they’re strictly materialistic concept of existence. Money is a measure of all things, and profit the primary goal. For the oppressors, what is worthwhile is to have more—always more—even at the cost of the oppressed having less or having nothing. For them, to be is to have and to be the class of the “haves.”

As beneficiaries of a situation of oppression, the oppressors cannot perceive that if having as a condition of being, it is necessary condition for all women and men. This is why their generosity is false. Humanity is a “thing,” and they possess it as an exclusive right, as inherited property. To the oppressor consciousness, humanization of the “others,” of the people, appears not as the pursuit of full humanity, but as subversion.

The oppressors do not perceive the monopoly on having more as a privilege which dehumanizes others and themselves. They cannot see that, in the egoistic pursuit of having as a possessing class, they suffocate in their own possessions and no longer are; they merely have. For them, having more is an unalienable right, a right they acquired through their own “effort,” with their “courage to take risks.” If others do not have more, it is because they’re incompetent and lazy, and worst of all it is their unjustifiable in gratitude towards the “generous gestures” of the dominant class. Precisely because they are “ungrateful” and “envious,” the oppressed are regarded as potential enemies who must be watched.

— Paulo Freire, Pedagogy of the Oppressed (Amazon, Goodreads)