Yareev's schmonz.comYareev's schmonz.comhttps://schmonz.com/Amitai Schleierikiwiki2024-02-13T04:28:32ZIntermissionhttps://schmonz.com/2023/11/09/intermission/Amitai Schleier2023-11-09T19:37:33Z2023-11-09T16:18:24Z
<p>It’s been a few weeks since
<a href="https://www.youtube.com/watch?v=aTc5eIkWzgo&list=PLkuryjnRFclTzNyap3TRgLtWxgQmbu5Am&index=50">my last Weekly Piano Miniature</a>
and I don’t feel bad about it.
That’s a strong signal.</p>
<p>Why don’t I feel bad?
Because
<a href="https://www.youtube.com/playlist?list=PLkuryjnRFclTzNyap3TRgLtWxgQmbu5Am">Weekly Piano Miniatures</a>
lasted an entire year (and
<a href="https://schmonz.com/2022/08/15/daily-piano-miniatures/">Daily Piano Miniatures</a>
for five months before that — all told, nearly 500 minutes of music).
Because my 100-year-old piano finally sounds rough enough that it’s been hard to want to play.
Because my energy is needed for family, health, and finding work.
Because I’m not worried I’ll stop making music.
Because if the last few pieces will have to keep reverberating for a while, I’m pleased that they’re three consecutive Medtners.</p>
<p>I hadn’t intended to pause the music project, but it’s intentional now.
Recording will resume
<a href="https://schmonz.com/2023/08/05/who-needs-an-amitai/">once I’m employed</a>
and have a more enjoyable instrument.
Let’s all look forward to that.</p>
Who needs an Amitai?https://schmonz.com/2023/08/05/who-needs-an-amitai/Amitai Schleier2023-11-03T02:27:20Z2023-08-05T11:46:12Z
<p>I’m looking for my next full-time role in <strong>engineering leadership</strong> (such as Director, VP, CTO) and/or <strong>senior engineering</strong> (such as Principal or Staff).</p>
<p>I love people, want them to succeed, and have fairly reliably made myself helpful.</p>
<p>You may already know me from
<a href="https://agilein3minut.es/">Agile in 3 Minutes</a>,
<a href="https://schmonz.com/tag/coding-tour/">my Coding Tour</a>,
<a href="https://schmonz.com/tag/pubmob/">my PubMob</a>,
<a href="https://schmonz.com/tag/jcjug/">meetups</a>
<a href="https://schmonz.com/tag/soctagile/">I’ve run</a>,
<a href="https://schmonz.com/tag/talk/">talks I’ve given</a>,
<a href="https://schmonz.com/tag/not-talk/">approximately a zillion podcasts I’ve guested on</a>,
or most recently my
<a href="https://www.youtube.com/playlist?list=PLkuryjnRFclQJqoIVpk9W9-eIRswejo-R">Daily</a>
and <a href="https://www.youtube.com/playlist?list=PLkuryjnRFclTzNyap3TRgLtWxgQmbu5Am">Weekly Piano Miniatures</a>.
I’m happy to say my track record of being an effective influencer extends beyond social media.</p>
<h2>Some core competencies</h2>
<ul>
<li>Coaching (technical and otherwise, all levels of the org)</li>
<li>Managing (risks, products, and people)</li>
<li>Contributing (tests, code, relentless improvements to developer UX, you name it)</li>
<li>Inviting and supporting meaningful conversations</li>
<li>Making and supporting effective decisions</li>
<li>Orienting myself — and helping others orient themselves — in new problem spaces</li>
<li>Seeking out and attending to unmet needs</li>
<li>Rooting practical daily choices in values and principles, and vice versa</li>
<li>Making workplaces more humane</li>
<li>Supporting people as the whole human beings they are</li>
<li>Giving, always and constructively, a shit</li>
</ul>
<h2>People saying nice things about my…</h2>
<ul>
<li><a href="https://latentagility.com/bio">Engineering leadership</a></li>
<li><a href="https://latentagility.com/testimonials">Consulting and coaching</a></li>
<li><a href="https://agilein3minut.es/comments">Agile in 3 Minutes micropodcast</a></li>
</ul>
<h2>A sampling of people saying nice things on <a href="https://www.linkedin.com/posts/schmonz_opentowork-activity-7090433839369519104-d_iZ">the LinkedIn copy of this very post</a></h2>
<p>A wonderful leader and leading practitioner. Here is a great opportunity for a software engineering organization that wants happy teams and happy customers.<br />
— Lisa Crispin</p>
<p>A thoughtful and competent person. I highly recommend bringing him in to help your organization achieve better success.<br />
— George Dinwiddie</p>
<p>One of the most talented people I’ve met in my Agile journey. He’d be great for your company.<br />
— Colleen Esposito</p>
<p>A great technical leader. Get him and save yourselves years!<br />
— Ewan O’Leary</p>
<p>I cannot say enough great things about Amitai. You should definitely hire him.<br />
— Kristen Belcher</p>
<p>Excellent addition to any team. And an all around great human too.<br />
— Doc Norton</p>
<p>Opportunity!! Amitai is an <em>awesome</em> engineering leader!<br />
— Ruth Malan</p>
<p>A pleasure to work with: walks the talk and doesn’t mind getting his hands dirty. I wish we could hire him.<br />
— Jeeva Nadarajah</p>
<p>An absolute wizard at helping software delivery folks get the most out of themselves and their organizations. I’ve seen first-hand his engineering expertise, and I’ve seen first-hand how great he is at helping others learn and improve. He’s one of the few engineering leaders who’s expert at true collaboration across the business-engineering chasm.<br />
— Jim Holmes</p>
<p>I’m gonna be so jealous of whoever gets to hire Amitai, that’s all I’ll say.<br />
— Dragan Stepanovi�</p>
<p>If you’re a hiring manager involved in software development, there are two questions to focus on:</p>
<ol>
<li>Why haven’t we hired Amitai yet?</li>
<li>When is the soonest moment on my calendar I can talk with Amitai?</li>
</ol>
<p>— Zach Bonaker</p>
<h2>Practicalities</h2>
<ul>
<li>For employers in the USA, I am a permanent resident and do not require a work permit</li>
<li>For locations across the USA and Europe, my US/Eastern timezone ensures some synchronous working hours every day</li>
<li><a href="https://schmonz.com/resume/">My résumé</a></li>
</ul>
<h2>Get in touch</h2>
<ul>
<li><a href="https://www.linkedin.com/in/schmonz">LinkedIn</a></li>
<li><a href="https://latentagility.com/link/free-call">Schedule a call</a></li>
</ul>
Daily piano miniatureshttps://schmonz.com/2022/08/15/daily-piano-miniatures/Amitai Schleier2022-08-15T18:42:02Z2022-08-15T18:12:30Z
<p>Since May, I’ve been posting a new video just about every day.
What’s in the videos?
A short piano piece, played as well as I can quickly learn it.
“Short” means, based on a sample size of 72 videos, two and a half minutes on average.
(You’ll probably agree, coming from the
<a href="https://agilein3minut.es">Agile in 3 Minutes</a>
guy, that tracks.)
Don’t like what you’re hearing?
No problem, the next piece is short too.
Here’s the
<a href="https://youtube.com/playlist?list=PLkuryjnRFclQJqoIVpk9W9-eIRswejo-R">full YouTube playlist</a>,
totaling over 3 hours of music so far.</p>
<p>Half a lifetime ago, I was already a musician and a technologist.
I’d have believed the future existence of a video-hosting platform such as YouTube.
Everything else, nope, no way that’s future-me.</p>
<p><img src="https://schmonz.com/2022/08/15/daily-piano-miniatures/recital.png" width="400" height="400" alt="1997 CWRU recital program" title="1998 CWRU recital program" class="img" /></p>
<p>I’d given this recital hoping for a tuition grant.
Having heard me play, the university accepted me as a music major.
Problem is, I hadn’t wanted that.
I wanted CS classes more than anything and my advisor from the music department couldn’t get me into those.</p>
<p>I frazzled out at that university, and almost certainly would have regardless of which courses I took.</p>
<p>8 years later I
<a href="https://schmonz.com/2005/09/07/first-week-of-classes/">tried again at another university</a>.
At that point music <em>was</em> what I wanted to study.
I graduated at 30 with a bachelor’s in it.</p>
<p>I also graduated with a changed belief.</p>
<p>My belief at the time of the pictured 1997 recital, and at the
<a href="https://schmonz.com/2007/11/14/medtner-music-and-me/">beginning of the fall 2005 semester</a>:
reading music is an aptitude, I lack it, and I compensate well enough by memorizing quickly.</p>
<p>My belief a few years later:
sight-reading is a skill.
By practicing it, I’ve gotten much better.</p>
<p>Obvious to me now, and surely obvious to you well before now.
But young-musician-me had been resigned to playing only pieces that others could show me and help me with.
I would never have believed a different experience were possible.</p>
<p>Lots of lessons in this:
for me personally, for how I raise (and praise) my kids, for
<a href="https://latentagility.com">how I work in and with teams</a>.
Most of all:
by changing a key belief, I changed how I relate to music.
You can
<a href="https://youtube.com/playlist?list=PLkuryjnRFclQJqoIVpk9W9-eIRswejo-R">see and hear the fruits of that</a>.</p>
<p>How did I get that belief to change? Well, that’s the magic, isn’t it.
Lots of things had to change a little bit.</p>
<p>What else changed when I gave myself a more direct relationship to music-making? Another thing I never would have guessed:
making more direct relationships with you.
In conclusion, behavior, conditions, beliefs, mindset, behavior, and so on, forever.
But mainly, thanks for listening.
And I don’t mean about the music.</p>
Galila Yara Schleierhttps://schmonz.com/2022/04/27/galila-yara-schleier/Amitai Schleier2022-04-27T21:55:04Z2022-04-27T20:16:19Z
<p>Our third child arrived yesterday, on April 26, at 7 pounds.
She was determined to make her debut in the car but instead came out moments after her mom got on the hospital bed.
Meet Galila Yara Schleier:</p>
<p><img src="https://schmonz.com/2022/04/27/galila-yara-schleier/IMG_1041-preview.jpg" width="400" height="300" alt="Galila Yara Schleier with big eyes" title="Galila Yara Schleier with big eyes" class="img" /></p>
<p>She comes home tomorrow to meet her brothers.
Grandparents, aunts, uncles, cousins, et al. will get to hold and smell her soon.</p>
<p>About the name:</p>
<p>Galila Yara honors Rebekka’s beloved aunt Judy and Amitai’s sweet uncle Rami.</p>
<h2>Galila</h2>
<p>From Hebrew Galil, the most mountainous region of Israel, the country where Uriel and Rami grew up.</p>
<ul>
<li>It signifies Judy’s endless love of the mountains and embodies the meaning of Rami’s name: “high”</li>
<li>Taken on its own, the Gal portion of the name means “wave”, representing the love of the ocean that Judy and Rachel shared and experienced together</li>
<li>The initial G honors Dianne’s mother, Grace</li>
</ul>
<h2>Yara</h2>
<p>From Hebrew and Arabic words for “small butterfly”, “forest”, or “honeycomb”, depending on how you read it.</p>
<ul>
<li>It reflects the beauty and sweetness of nature, which Judy always celebrated and appreciated</li>
<li>The Y honors Yehudit (Judith) and the Ra honors Rami</li>
<li>Like Amitai’s own middle name, it represents Yaakov and Rivka, Uriel’s and Rami’s parents</li>
</ul>
<h2>Galila Yara</h2>
<p>We chose the name “Galila Yara” to encompass our families’ rich memories and backgrounds and to celebrate Judy and Rami and their loving families.
We invite you to join us in welcoming Galila into ours.</p>
<h2>About the date</h2>
<ul>
<li>4/26 is the day before Finias’s birthday (he’s 2 today!)</li>
</ul>
<h3>More nice properties observed after the fact</h3>
<p>If you think of another reason this is a nice name, please pass it along.</p>
<h2>More photos</h2>
<p><a href="http://photos.theschleiers.com/galila/">photos.theschleiers.com/galila</a></p>
JC-JUG December 2021: Bob Allen on Coaching Teams to Do the Impossiblehttps://schmonz.com/2021/12/08/jcjug-december-2021-bob-allen/Amitai Schleier2021-12-08T21:10:19Z2021-12-08T20:50:51Z
<p>For
<a href="https://www.meetup.com/Jersey-City-Java-User-Group-JC-JUG/events/282467826/">the December meetup</a>
of
<a href="https://www.meetup.com/Jersey-City-Java-User-Group-JC-JUG">Jersey City Java</a>,
<a href="https://twitter.com/CuriousAgilist">Bob Allen</a>
presented
<a href="https://youtu.be/CfubTbNqfQM">Coaching Teams to Do the Impossible… as they see it, and, without straining their backs</a>.</p>
<p>About the presentation:</p>
<blockquote><p>As some of you likely have some appreciation for, what I and my fellow technical and product coaches do, when we are lucky, is a hard sell from the get-go.
Here are just a few of the reasons:</p>
<ul>
<li>We ask a whole team to do things they have never even contemplated doing,</li>
<li>For an extended period of time (4 to 6 weeks),</li>
<li>And to do it repeatedly,</li>
<li>All together,</li>
<li>With a WIP limit of ONE.</li>
</ul>
<p>Keep in mind, the clients are typically very large companies, whose employees often experience ‘transformation fatigue’ (been there, done that, didn’t even get the dang t-shirt).
Let me tell you some stories about how it is done, why and how it works, and why you might even want to do it yourself.</p></blockquote>
<p><a href="https://youtu.be/CfubTbNqfQM">Watch</a>.</p>
November crowdfunding updatehttps://schmonz.com/2021/12/04/november-crowdfunding-update/Amitai Schleier2023-04-22T11:55:21Z2021-12-04T10:43:48Z
<p><em>[ <a href="https://schmonz.com/crowdfunding/">About my public-facing work</a> ]</em></p>
<p>Starting now, I’m moving my monthly posts from
<a href="https://schmonz.com/link/patreon/">Patreon</a>
to my own website here.
Why?</p>
<ol>
<li>I prefer to own my data</li>
<li>There are many ways (Patreon merely one among them) in which people can fund my public-facing work</li>
</ol>
<p>My
<a href="https://latentagility.com">corporate work</a>
focuses on
<a href="https://latentagility.com/tech/">learning together, experientially</a>.
My public-facing work is similar: I’m creating learning experiences, Open Source code, and combinations thereof — at present, like so:</p>
<ul>
<li>Packaging third-party software for a cross-platform Unix package manager</li>
<li>Developing an email server</li>
<li>Fixing bugs and adding features to a (mostly) static site generator</li>
<li>Facilitating ensemble/mob programming sessions</li>
<li>Streaming solo programming sessions</li>
<li>Organizing meetups about programming and Agile</li>
</ul>
<p>For more, see
<a href="https://schmonz.com/crowdfunding/">crowdfunding</a>.
I’m grateful for your support.</p>
<h1>Experiences</h1>
<p>Held our final
<a href="https://pubmob.com/offerings/amitaischleier-legacy-open-source-fridays/">Legacy Open Source Fridays</a>
ensemble session of 2021.
Started back up with
<a href="https://www.twitch.tv/schmonzie">streaming my solo programming sessions on Twitch</a>,
mostly pkgsrc-related so far.
Improving my stream a bit each time.</p>
<p>For
<a href="https://www.meetup.com/Jersey-City-Java-User-Group-JC-JUG/">Jersey City Java</a>,
experimented with having a vendor present their product: a brief introduction to the tool, followed by
<a href="https://schmonz.com/2021/11/11/jcjug-november-2021-pejman-ghorbanzade/">programming together with Pejman Ghorbanzade</a>.
Glad we tried it.
If we do another vendor session sometime, this’ll be how.</p>
<p>Building momentum with
<a href="https://www.meetup.com/Southern-Connecticut-Agile-Meetup/">Southern Connecticut Agile</a>,
our second meetup was an extremely well liked
<a href="https://schmonz.com/2021/11/23/soctagile-november-2021-esther-derby-matthew-carlson/">conversation with Esther Derby and Matthew Carlson</a>.
We’ll skip December (too much holiday stuff), though
<a href="https://www.meetup.com/Jersey-City-Java-User-Group-JC-JUG/events/282467826/">JC-JUG’s session</a>
will be of interest.
I’m excited for our January SoCTAgile speaker.</p>
<h1>Build farm</h1>
<p><a href="https://www.virtualbox.org/wiki/Changelog-6.1#v30">VirtualBox 6.1.30</a> fixed the macOS Monterey
<a href="https://www.patreon.com/posts/57678431">troubles I encountered last month</a>.</p>
<p>Upgrading Devuan 3.1 to 4.0 was straightforward, as was updating Ubuntu aarch64 to 21.10.</p>
<p>After much reading and trying stuff,
<a href="https://schmonz.com/2021/11/22/now/">bringing up a 2007 MacBook</a>
(64-bit system, 32-bit EFI) with Lubuntu 21.10 was ultimately uneventful.
It’s no speed demon.
I doubt I’ll keep it running.
But the tricks I’ve just learned should apply to my original 2006 Mac Pro, boosted many years ago with SSD and lots of RAM and needing only an OS that can be kept current.
In the meantime, a cursory build of my usual packages turned up a build failure in libspf2.</p>
<h1>pkgsrc fixes</h1>
<ul>
<li>Doing cross-platform testing of an Ubuntu 21.10 fix for libspf2 (works nearly everywhere else, but needs more fixing on OpenBSD and Void)</li>
<li><a href="http://mail-index.netbsd.org/pkgsrc-users/2021/11/29/msg034809.html">Reviewed a fix needed in my cross-platform build environment</a>, now awaiting commit by the author</li>
<li>lighttpd: upstream patch for use-after-free</li>
<li>libhighlight: bump required API version to fix runtime errors seen on wiki.netbsd.org</li>
<li>ikiwiki: provide pkgsrc-compatible default values for configurable paths to fix runtime errors seen on wiki.netbsd.org</li>
<li>Linux with non-executable glibc (such as Ubuntu/aarch64 21.10): fall back to detecting GLIBC_VERSION another way</li>
<li>qmail and djbdns: catch up to pkgsrc’s switch from RMD160 to BLAKE2s hashes</li>
<li>gdk-pixbuf2: fix macOS build</li>
<li>ucspi-tools: fix Linux build</li>
<li>bootstrap: note that Solaris 11 works</li>
</ul>
<h1>pkgsrc updates</h1>
<ul>
<li>mob to 2.1.0</li>
<li>texttest to 4.0.8</li>
<li>p5-App-Sqitch to 1.2.0</li>
<li>py-approvaltests to 3.1.0</li>
<li>getmail to 5.16</li>
</ul>
<h1>pkgsrc additions</h1>
<ul>
<li>ucspi-udp</li>
<li>tcpexec</li>
<li>fd-proxy</li>
<li>pikchr</li>
<li>AusweisApp2 (to pkgsrc-wip for further attention)</li>
<li>dstp (also to pkgsrc-wip)</li>
</ul>
<h1>notqmail</h1>
<p>Legacy Open Source Fridays has produced a few pull requests which we’re still working through.
I made some progress on getting
<a href="https://github.com/notqmail/notqmail/pull/224">Add tests for qmail-send:job_*() functions</a>
past the Solaris autobuilds.</p>
<p>Legacy Open Source Fridays has also produced a few people with motivation to continue programming notqmail.
I had not imagined this possibility, and am gratified that it’s happened.</p>
<h1>ikiwiki</h1>
<p>My motivation for packaging pikchr was to be able to integrate it into ikiwiki.
Ikiwiki already has a
<a href="http://ikiwiki.info/plugins/graphviz/">graphviz plugin</a>
which I’ve been using to generate
<a href="https://schmonz.com/software/acceptutils/">somewhat explanatory diagrams of acceptutils</a> — but I’m not thrilled with my diagrams, pikchr appears designed to run in precisely this kind of context, and maybe I’ll like it better.
When I write the pikchr plugin for ikiwiki, it’ll be streamed
(<a href="https://www.twitch.tv/schmonzie">subscribe to my Twitch</a>).
In the meantime, you can
<a href="https://youtu.be/MxbqNHbjTBc">watch me create the pikchr package</a>.</p>
SoCTAgile November 2021: Esther Derby and Matthew Carlson on There Are No More Early Adopters of Agilehttps://schmonz.com/2021/11/23/soctagile-november-2021-esther-derby-matthew-carlson/Amitai Schleier2023-04-29T19:51:15Z2021-11-23T10:27:23Z
<p>Welcome back to
<a href="https://www.meetup.com/Southern-Connecticut-Agile-Meetup/">Southern Connecticut Agile</a>!
For our November meetup,
<a href="https://twitter.com/estherderby">Esther Derby</a>
and
<a href="https://twitter.com/mcarlson_sb">Matthew Carlson</a>
presented
<a href="https://youtu.be/XuZ39j7UE20">There Are No More Early Adopters of Agile</a>.</p>
<p>About the presentation:</p>
<blockquote><p>After 20 years, Agile has in a sense become pervasive.
While it’s neither mandated nor regulated, everyone’s heard of it, and lots of organizations understand the legitimacy it confers.
Still, some folks continue to approach changing to Agile as though it were a brand new set of ideas.
How’s that working out?
Join Esther and Matthew in a conversation about what motivated early Agile adopters, what’s different now, and how we can more effectively bring about the changes we seek.</p></blockquote>
<p>Comments from participants include “One of the best online sessions I have participated in at least this whole year” and “Best talk of any sort I’ve been to (online or otherwise) in a very long time.”</p>
<p><a href="https://youtu.be/XuZ39j7UE20">Watch</a>.</p>
<p>Papers, talks, books, videos, and blog posts mentioned along the way:</p>
<ul>
<li><a href="https://amzn.to/3l1KMuT">Crossing the Chasm</a>, Moore 2014 (popularization of work by <a href="https://en.wikipedia.org/wiki/Everett_Rogers">Rogers</a>)</li>
<li><a href="https://drive.google.com/file/d/0B0cALkZGPQMIYi15eXZhR3hHeEU/view?usp=sharing&resourcekey=0-v6BfnGJBA852xzPc_r6qhg">Institutionalized Organizations: Formal Structure as Myth and Ceremony</a>, Meyer and Rowan 1977</li>
<li><a href="https://scrumguides.org">Scrum Guide</a>, Schwaber and Sutherland 2020</li>
<li><a href="https://ronjeffries.com/articles/019-01ff/story-points/Index.html">Story Points Revisited</a>, Jeffries 2019</li>
<li><a href="https://amzn.to/3cE7KDN">Software Estimation Without Guessing</a>, Dinwiddie 2019</li>
<li><a href="https://www.agilealliance.org/resources/videos/whats-the-story-about-agile-data/">What’s the Story About Agile Data</a>, Magennis 2018</li>
<li><a href="https://leadinganswers.typepad.com/leading_answers/files/original_waterfall_paper_winston_royce.pdf">Managing the Development of Large Software Systems</a>, Royce 1970</li>
<li><a href="https://en.wikipedia.org/wiki/Total_quality_management">Total Quality Management</a>, Wikipedia</li>
<li><a href="https://drive.google.com/file/d/0B0cALkZGPQMIa1ozM05fLU4yekU/view?usp=sharing&resourcekey=0-JTCGlkyznd1bgZaorNwyoQ">Customization or Conformity? An Institutional and Network Perspective on the Content and Consequences of TQM Adoption</a>, Westphal, Gulati, Shortell 1997</li>
<li><a href="https://drive.google.com/drive/u/0/folders/0B0cALkZGPQMISS1DNUZ1dU4zM0E?resourcekey=0-APlJY09WZ53nClmqJKqBBw">Matthew’s stash of Institutional Theory papers</a></li>
</ul>
JC-JUG November 2021: Pejman Ghorbanzade on Continuous Regression Testing Using Toucahttps://schmonz.com/2021/11/11/jcjug-november-2021-pejman-ghorbanzade/Amitai Schleier2021-11-11T10:23:10Z2021-11-11T10:14:48Z
<p>For
<a href="https://www.meetup.com/Jersey-City-Java-User-Group-JC-JUG/events/281715735/">the November meetup</a>
of the
<a href="https://www.meetup.com/Jersey-City-Java-User-Group-JC-JUG">Jersey City JUG</a>,
<a href="https://twitter.com/heypejman">Pejman Ghorbanzade</a>
presented
<a href="https://youtu.be/Nn5We6yQ8Kg">Continuous Regression Testing Using Touca SDK for Java</a>.</p>
<p>About the presentation:</p>
<blockquote><p>Making code changes to real-world software systems without introducing unintended side-effects is non-trivial.
There are methods and tools to help us mitigate the inherent risks.
One of these methods is regression testing that helps us verify the behavior of our software using a large number of test cases.
But regression testing frameworks are clunky, have high maintenance costs, and produce results that are difficult to manage at scale.
These limitations have largely made their use an after-thought for most software teams.</p>
<p>Touca is an early-stage startup trying to rethink regression testing.
They offer open-source SDKs that enable describing the behavior and performance of software workflows by capturing values of variables and runtime of functions.
They remotely compare this description against a previous trusted version and report differences in near real-time.</p>
<p>Join us for an interactive session to explore this new approach to regression testing and to evaluate Touca’s implementation of that approach.
We will try their new Java SDK (https://github.com/trytouca/touca-java) to see if we can safely refactor two well-known code Katas in a friendly ensemble programming session.
We will take turns to share our thoughts about this new approach, and share general tips about changing real-world codebases safely and efficiently.</p></blockquote>
<p>If you missed it, you missed an ensemble programming session writing Touca tests for an existing codebase.
Pejman’s explanation and demo is short and sweet.
<a href="https://youtu.be/Nn5We6yQ8Kg">Watch</a>.</p>
SoCTAgile October 2021: Steve Doubleday on Three Frames of Software Developmenthttps://schmonz.com/2021/10/29/soctagile-october-2021-steve-doubleday/Amitai Schleier2021-10-28T22:43:38Z2021-10-28T22:23:22Z
<p>I noticed last week that the
<a href="https://www.meetup.com/Southern-Connecticut-Agile-Meetup/">Southern Connecticut Agile Meetup</a>
had gone maintainerless and decided to take it on.
Welcome back!
For our October meetup,
<a href="https://twitter.com/sjdayday">Steve Doubleday</a>
presented
<a href="https://youtu.be/0_Jre_46fBg">Three Frames of Software Development</a>.</p>
<p>About the presentation:</p>
<blockquote><p>The uneven adoption of agile methods over the past couple of decades can be usefully understood as coming from a difficulty executives have in letting go of three frames — the Building, Project, and More frames, and accompanying metaphors.
These are ubiquitous in the culture of many large IT organizations, and they conflict with what agile enthusiasts think are better ways of building software.
In these terms, SAFe has been successful because it blends agile concepts with the Building, Project, and More frames, allowing older and newer ways of thinking to co-exist.
This uneasy coexistence can be thought of as an importance source of problems in SAFe efforts.
In turn, this suggests that useful paths forward may need new frames and metaphors.</p></blockquote>
<p><a href="https://youtu.be/0_Jre_46fBg">Watch</a>.</p>
JC-JUG September 2021: Mike Coon on You Get What You Ask Forhttps://schmonz.com/2021/09/15/jcjug-september-2021-mike-coon/Amitai Schleier2021-10-28T22:43:38Z2021-09-15T08:17:24Z
<p>For
<a href="https://www.meetup.com/Jersey-City-Java-User-Group-JC-JUG/events/280486226/">the September meetup</a>
of the
<a href="https://www.meetup.com/Jersey-City-Java-User-Group-JC-JUG">Jersey City JUG</a>,
<a href="https://twitter.com/mikeonitstuff">Mike Coon</a>
presented
<a href="https://youtu.be/78o_lWES1BA">You get what you ask for — so you better ask for what you want</a>.</p>
<p>About the presentation:</p>
<blockquote><p>As we progress in an organization what we ask for and what we ask about become key to engaging our teams and to maximizing value.
We’ll talk about how subtle changes in our approach can ignite creativity and provide a sense of ownership in our teams.
We’ll also talk about how to build and maintain credibility through careful consideration of what we ask about.</p>
<p>This presentation is for:</p>
<ul>
<li>Scrum Masters</li>
<li>Product Owners</li>
<li>Managers and Dev Lead types</li>
<li>Anybody else hoping to get things of value from others</li>
</ul>
</blockquote>
<p><a href="https://youtu.be/78o_lWES1BA">Watch</a>.</p>
Code PaLOUsa 2021: Two Midwesterners Politely Invite You To Explore Codinghttps://schmonz.com/2021/08/20/codepalousa-2021-two-midwesterners/Amitai Schleier2021-08-20T16:25:13Z2021-08-20T16:06:13Z
<p>On Friday, August 20,
<a href="https://twitter.com/AgileFaye">Faye Thompson</a>
and I once again co-facilitated
<a href="http://codepalousa.com/Sessions/1968">Two Midwesterners Politely Invite You To Explore Coding</a>,
this time as a 3-hour workshop at
<a href="http://codepalousa.com">Code PaLOUsa 2021</a>.
The abstract:</p>
<blockquote><p>Wonder what it’s like to do what programmers do?
Maybe people have tried to explain it, but didn’t put it in terms that computed for you.
Or maybe you would like to become more technical, but the mere thought of trying to code has felt intimidating.
Today is a new day!</p>
<p>Faye’s a non-programmer from Ohio, Amitai’s a sometimes-programmer from Illinois, and with your help, we’ll solve a problem by thinking and coding together.
If you want to, you can take a brief turn at the keyboard; if not, no biggie.
When we’re done, we think you’ll have a new kind of feeling about code and coding.
You might even want to pursue it further.</p></blockquote>
<p>We didn’t have much audience participation, possibly because our session had to be rescheduled from Wednesday (against other half-day workshops, but I was traveling to Germany that day) to Friday (against regular-length talks).
On the plus side, Faye and I got to spend a few hours together pair programming, culminating in a last-minute pivot to “FizzBuzzBlerg”.
And though we don’t usually record this material, the conference has been capturing every session.
I’ll share the video if and when they publish.</p>
<ul>
<li><a href="https://schmonz.com/2021/08/20/codepalousa-2021-two-midwesterners/slides/">Slides</a></li>
</ul>
JC-JUG August 2021: Nayan Hajratwala on Power Up Your Gradlehttps://schmonz.com/2021/08/10/jcjug-august-2021-nayan-hajratwala/Amitai Schleier2021-10-28T22:43:38Z2021-08-10T21:18:37Z
<p>For
<a href="https://www.meetup.com/Jersey-City-Java-User-Group-JC-JUG/events/279894561/">the August meetup</a>
of the
<a href="https://www.meetup.com/Jersey-City-Java-User-Group-JC-JUG">Jersey City JUG</a>,
<a href="https://twitter.com/nhajratw">Nayan Hajratwala</a>
presented
<a href="https://youtu.be/CTRpz1D-r_I">Power Up Your Gradle</a>.</p>
<p>About the presentation:</p>
<blockquote><p>Does Gradle make you sad?
Are slow & flaky builds stealing your time?
Are you a Maven maven, longing for the days you could write incomprehensible build files in XML rather than Groovy?
If so, this session is for you!
Together, we will delve into some techniques to keep your Gradle builds simple and maintainable.</p></blockquote>
<p><a href="https://youtu.be/CTRpz1D-r_I">Watch</a>.</p>
JC-JUG June 2021: Julie Lerman, Helen Scotthttps://schmonz.com/2021/06/30/jcjug-june-2021-julie-lerman-helen-scott/Amitai Schleier2021-08-11T01:16:41Z2021-06-30T14:55:17Z
<p>In June, the Jersey City JUG had <em>two</em> meetups:</p>
<ul>
<li><a href="https://twitter.com/julielerman">Julie Lerman</a>
on
<a href="https://www.meetup.com/Jersey-City-Java-User-Group-JC-JUG/events/278360575/">Tackling System Complexity with Domain-Driven Design</a>
(sorry, no video)</li>
<li><a href="https://twitter.com/HelenJoScott">Helen Scott</a>
on
<a href="https://www.meetup.com/Jersey-City-Java-User-Group-JC-JUG/events/278300314/">Writing Code is Easy, Being a Great Developer Is Hard</a>
(<a href="https://youtu.be/olydqoInjxU">video</a>)</li>
</ul>
Legacy of SoCraTes: Inside-Out TDDDDhttps://schmonz.com/2021/06/17/legacy-of-socrates/Amitai Schleier2021-11-25T09:54:33Z2021-06-17T15:00:00Z
<p>On Thursday, June 17,
for the
<a href="https://www.crowdcast.io/e/the-legacy-of-socrates-5">6th edition of “Legacy of SoCraTes”</a>,
I gave a public talk with this abstract:</p>
<blockquote><p>In inside-out TDD, we incrementally redesign objects, their interactions, and the system as a whole, starting in the small and moving toward the large.
In something we might by extension want to call “Inside-Out TDD-Driven Development”, we incrementally redesign ourselves, our interactions, and our systems of work, starting in the small and expanding outward.
I’ll tell some personal stories about the impact of software craft on emotional states and working relationships, and I’ll lay out my reasoning for Inside-Out TDDDD being perhaps the most effective path toward greater joy and humanity in software development.</p></blockquote>
<p>The talk is about technical practices, sort of — in the sense that we can use them to improve our emotional states, working relationships, and business results.</p>
<p>Listener feedback has included:</p>
<blockquote><p>”I loved it.
It was fantastic.
My heart contains more praise than I know how to put into words.”</p></blockquote>
<!-- This was M. Scott Ford, who also led with "Your presentation fucking rocked!", in a DM on the Legacy Code Rocks Slack -->
<blockquote><p>”Only a quarter of the way in and I’m loving this talk.
Lots of notes taken and quotes stolen already….
Your perspective adds a whole ‘nother layer of richness that I never realized until now was there.”</p></blockquote>
<!-- [Junilu Lacar on LinkedIn](https://www.linkedin.com/feed/update/urn:li:activity:6811799026388766720?commentUrn=urn%3Ali%3Acomment%3A%28activity%3A6811799026388766720%2C6811817428620722176%29&replyUrn=urn%3Ali%3Acomment%3A%28activity%3A6811799026388766720%2C6811822936576557056%29) -->
<blockquote><p>”Stories that teach in so many dimensions!”</p></blockquote>
<!-- http://twitter.com/ruthmalan/status/1407151185442885637 -->
<ul>
<li><a href="https://schmonz.com/2021/06/17/legacy-of-socrates/slides/">Slides</a></li>
</ul>
<p>Video:</p>
<div class="video-container">
<iframe src="https://www.youtube-nocookie.com/embed/EZUf6hDipQk" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
JC-JUG May 2021: Ryan Latta on Learning Under Pressure: Scala in a Hurryhttps://schmonz.com/2021/05/11/jcjug-may-2021-ryan-latta/Amitai Schleier2021-08-11T01:16:41Z2021-05-11T21:25:15Z
<p>For
<a href="https://www.meetup.com/Jersey-City-Java-User-Group-JC-JUG/events/277546882/">the May meetup</a>
of the
<a href="https://www.meetup.com/Jersey-City-Java-User-Group-JC-JUG">Jersey City JUG</a>,
<a href="https://twitter.com/recursivefaults">Ryan Latta</a>
presented
<a href="https://youtu.be/wW98q0Eq5_I">Learning Under Pressure: Scala in a Hurry</a>.</p>
<p>About the presentation:</p>
<blockquote><p>How many times have you learned a new piece of tech while at work?
I know for me it seems like every new project comes with some new framework or language.
At the same time, most of the companies I’ve worked for expected me and the team to figure it out — no books, no experts.</p>
<p>I want to share a story of how I learned Scala and Finagle while under the pressure to deliver with hard SLAs.
I’ll show you how you can use the same techniques to learn languages, frameworks, and tools without your codebase turning into copy-pasta from Stack Overflow and countless tutorials.</p></blockquote>
<p>Ryan’s talk reminded me of a similar approach I took to
<a href="https://schmonz.com/2014/01/26/how-to-efficiently-learn-a-programming-language/">learn a programming language</a>
while under the pressure to make good use of an afternoon at a conference.
His context and his presentation make a stronger case.
<a href="https://youtu.be/wW98q0Eq5_I">Watch</a>.</p>
JC-JUG April 2021: Cat Swetel & Heidi Mitre on Continuous Verification Beyond Chaos Engineeringhttps://schmonz.com/2021/04/07/jcjug-april-2021-cat-swetel-heidi-mitre/Amitai Schleier2021-08-11T01:16:41Z2021-04-07T08:54:22Z
<p>For
<a href="https://www.meetup.com/Jersey-City-Java-User-Group-JC-JUG/events/276869374/">the April meetup</a>
of the
<a href="https://www.meetup.com/Jersey-City-Java-User-Group-JC-JUG">Jersey City JUG</a>,
<a href="https://twitter.com/catswetel">Cat Swetel</a>
and
<a href="https://github.com/heidimitre">Heidi Mitre</a>
presented
<a href="https://youtu.be/nR-iPf-ZXAQ">Continuous Verification: Beyond Chaos Engineering</a>.</p>
<p>About the presentation:</p>
<blockquote><p>As technologists, our work is increasingly situated in highly complex socio-technical ecosystems.
As much as we are encouraged to retrospectively seek a distinct and absolute root cause for an incident or outage, these complex systems are much more likely to drift into failure rather than suddenly taking one catastrophic wrong turn.
What if you and your colleagues could be sensitized to the drifting safety boundaries of your systems?
How would that inform the work you do?
Join this session to explore these ideas through an introduction — with Java-oriented examples — to the important new discipline of continuous verification.</p></blockquote>
<p><a href="https://youtu.be/nR-iPf-ZXAQ">Watch</a>.</p>
AO.com Webinar March 2021: Inside-Out TDDDDhttps://schmonz.com/2021/03/19/ao-webinar/Amitai Schleier2021-11-25T09:54:33Z2021-03-19T08:14:16Z
<p>On Friday, March 19,
at the invitation of
<a href="https://tech.ao.com/event/amitai-schleier/">AO.com</a>,
I gave a public talk about joy and humanity in software development.
The talk was primarily concerned with the effects of software craft on our emotional states and working relationships.
Along the way, I touched on
<a href="https://en.wikipedia.org/wiki/Theory%20of%20Constraints">Theory of Constraints</a>,
<a href="https://youtu.be/4rG9u478X1Q">stable and unstable equilibria</a>
in work environments,
a significant and deliberate omission from Scrum,
<a href="https://www.legacycode.rocks/podcast-1/episode/27c69746/defining-legacy-code-with-amitai-schleier">my take on “legacy code”</a>,
applied empathy (never mentioned explicitly, merely woven in),
and what agility looks and feels like when you’ve got it.</p>
<p>The talk’s title is admittedly a bit opaque.
<a href="https://8thlight.com/blog/georgina-mcfadyen/2016/06/27/inside-out-tdd-vs-outside-in.html">Inside-Out TDD</a>
is the style of Test-Driven Development I usually prefer:
we incrementally design objects and their interactions starting with the small and moving toward the large.
By extension, I’m calling the style of incrementally redesigning ourselves and our work interactions by starting in the small and expanding outward “Inside-Out TDD-Driven Development” — where “development” this time refers not only to code, but also to people and systems.
I usually prefer this style of development, too.
The talk (35 minutes, followed by Q&A) attempts to set out my reasoning.</p>
<p>For AO, this kicked off a new series in which they’re hosting well-known tech speakers, free and open to the public.
I hope I’ve gotten them off on the right foot.</p>
<ul>
<li><a href="https://schmonz.com/2021/03/19/ao-webinar/slides/">Slides</a></li>
<li><a href="https://schmonz.com/2021/03/19/ao-webinar/20210319-inside-out-tdddd.mp4">Video</a></li>
</ul>
<div class="video-container">
<iframe src="https://www.youtube-nocookie.com/embed/HqjrvJbuf3g" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
JC-JUG March 2021: Angie Jones on Modern Java Beyond Version 8https://schmonz.com/2021/03/10/jcjug-march-2021-angie-jones/Amitai Schleier2021-03-10T11:46:26Z2021-03-10T10:36:51Z
<p>For
<a href="https://www.meetup.com/Jersey-City-Java-User-Group-JC-JUG/events/276108725/">the March meetup</a>
of the
<a href="https://www.meetup.com/Jersey-City-Java-User-Group-JC-JUG">Jersey City JUG</a>,
<a href="https://twitter.com/techgirl1908">Angie Jones</a>
presented
<a href="https://youtu.be/sNiWs2b_MBM">Modern Java: Beyond Version 8</a>.</p>
<p>As a software development coach, I work with clients no matter what their code is written in.
When they’re using Java, it’s rarely a recent JDK.
And with the advent of OpenJDK, the JDK situation itself has gotten a bit harder to follow.</p>
<p><a href="https://youtu.be/sNiWs2b_MBM">Angie’s talk</a>
filled us in on some of the major new goodies since Java 8.
You might come away motivated to keep up with the latest and take full advantage in your code.</p>
<p><a href="https://youtu.be/sNiWs2b_MBM">Watch</a>.</p>
JC-JUG February 2021: Dave Nicolette with Java on the Mainframehttps://schmonz.com/2021/02/17/jcjug-february-2021-dave-nicolette/Amitai Schleier2021-02-17T11:48:04Z2021-02-17T11:30:32Z
<p>For the February meetup of the
<a href="https://www.meetup.com/Jersey-City-Java-User-Group-JC-JUG">Jersey City JUG</a>,
<a href="https://twitter.com/davenicolette">Dave Nicolette</a>
presented
<a href="https://www.meetup.com/Jersey-City-Java-User-Group-JC-JUG/events/276004683/">Java on the Mainframe</a>.</p>
<p>Most of us have written Java code.
Some of us have written code that integrates with mainframes.
Few of us have programmed mainframes.
Dave, an experienced programmer and agile coach, has.
He gave us a basic understanding of the platform, what’s similar and what’s different from environments we’re familiar with, and some examples of what mainframe code looks like — plus a view into
<a href="https://github.com/neopragma/cobol-check">Cobol Check</a>,
an open-source testing framework he’s developing for Cobol applications.
<a href="https://youtu.be/5MPKvjc4gX4">Watch the session</a>.</p>
OOP Konferenz 2021: Strangle Your Legacy Codehttps://schmonz.com/2021/02/08/oop-konferenz-2021-strangle-your-legacy-code/Amitai Schleier2021-02-08T20:23:09Z2021-02-08T17:30:00Z
<p>On February 8,
I facilitated
<a href="https://www.oop-konferenz.de/oop2021/programm/konferenzprogramm.html#item-2165">Strangle Your Legacy Code</a>
at
<a href="https://www.oop-konferenz.de/oop2021/english.html">OOP Konferenz</a>.
The abstract:</p>
<blockquote><p>Given an ancient codebase that makes refactoring risky and expensive, how do you clear a path to continued delivery?
The old wisdom says the best time to plant a tree was 20 years ago.
The next best time to preserve your software investment is today:
plant a Strangler Fig, a pattern for reaping continuous value from your existing system while growing new functionality alongside it.</p>
<p>We’ll test-drive new features into a real legacy system.
You’ll leave with a powerful strategy for extending the useful life of working, valuable software.</p></blockquote>
<p>The conference Zoom session didn’t let me give keyboard control, so I was the permanent Driver (and, as is common with this exercise, also frequently the Navigator).
Even so, the participants quickly saw the costs and risks of our particular Strangler Fig implementation, leading to a lively discussion about how this pattern might fit into other codebases and what to watch out for when implementing it.</p>
<ul>
<li><a href="https://schmonz.com/2021/02/08/oop-konferenz-2021-strangle-your-legacy-code/slides/">Slides</a></li>
</ul>
<p>A wise three-year-old recently told me, “Sometimes it bes like that; sometimes it’s similar.”
When we were making plans to move to Germany, OOP was one of the conferences I’d been most excited about being able to attend.
Attending online was probably similar.
OOP remains high on my list for when we can once again confer in person.</p>
JC-JUG January 2021: Emily Bache on Handling Legacy Code with Approvals and Coveragehttps://schmonz.com/2021/01/11/jcjug-january-2021-emily-bache/Amitai Schleier2021-01-12T20:41:00Z2021-01-11T16:48:00Z
<p>Our first
<a href="https://www.meetup.com/Jersey-City-Java-User-Group-JC-JUG">Jersey City JUG</a>
session for 2021 followed the
<a href="https://schmonz.com/2020/12/16/jcjug-december-2020-jbrains/">evolutionary design conversation from last month</a>,
as
<a href="https://twitter.com/emilybache">Emily Bache</a>
introduced a safety-enhancing technique for evolving the design of legacy code.
She demonstrated Approval Tests and code coverage, then split us into groups of three to get tests around the provided codebase.
(This entailed belatedly enabling Breakout Rooms for my Zoom account on the fly, with everyone’s help.
Totally worth it.)</p>
<p>My
<a href="https://www.meetup.com/Jersey-City-Java-User-Group-JC-JUG/events/274990208/">top insight from today’s session</a>:
every Approval Test is inherently also a test for the <em>absence</em> of the <em>unexpected</em>.
Not something we usually test for, because it requires some expensive thinking — but with Approval Tests it just happens.
An argument for including at least a few of these tests in your suite.</p>
<p>For more insights, both from Emily and from my fellow participants,
<a href="https://youtu.be/NOxThHYEX9I">watch the session</a>.</p>
<hr />
<h2>Emily’s new book</h2>
<p>Check out
<a href="https://leanpub.com/techagilecoach">Technical Agile Coaching with the Samman method</a>,
in which Emily carefully documents a particular way software development coaches can more effectively engage with clients.
<a href="https://schmonz.com/talk/20200122-mob-mentality/">In my experience, engaging in this way</a>
is much more effective and cost-effective for clients than any other way I’ve tried.
If you coach programmers, this book will help you.
Don’t believe me?
Take Kent Beck’s foreword for it.</p>
<p>(See also <a href="https://leanpub.com/u/emilybache">Emily’s other books</a>.)</p>
deliver:Agile: 2020 Geeky Wrap-Uphttps://schmonz.com/2020/12/17/deliveragile-2020-geeky-wrapup/Amitai Schleier2021-02-12T09:56:28Z2020-12-17T18:30:00Z
<p>A year ago, or whenever the heck it was, I was helping organize the 2020 edition of deliver:Agile, the Agile Alliance conference focused on practitioners and techniques.
(I had been part of the
<a href="https://schmonz.com/2016/04/10/aatc-2016-devops-dojo-discussion-panel/">2016</a>,
<a href="https://schmonz.com/2017/04/20/aatc-2017-cross-platform-deployment/">2017</a>,
and
<a href="https://schmonz.com/2019/05/01/deliveragile-2019-strangle-your-legacy-code/">2019</a>
conferences.
It’s one of my favorites.)
Turns out this wasn’t the best year for conferences.
Ours didn’t happen.
But the Agile Alliance has been holding — and
<a href="https://www.agilealliance.org/deliveragile-2020-reflections/">will continue to hold in 2021</a>
— a series of events on the deliver:Agile theme.
The final one for 2020, sprung from the imagination of
<a href="https://twitter.com/CatSwetel">Cat Swetel</a>, was rather silly.
I was part of the show.</p>
<p>Have you</p>
<p>(a) Always wanted to watch a dramatic reading of anthropomorphized processor architectures arguing their merits with each other?</p>
<p>(b) Only just now realized this?</p>
<p>(c) Not yet admitted it to yourself?</p>
<p>On
<a href="https://www.agilealliance.org/deliveragile-live/program/2020-geeky-wrap-up/">December 17</a>,
<a href="https://twitter.com/itsUnderstood">Sue Johnston</a>
and I performed the roles of the two processor architectures, with the moderator played by
<a href="https://twitter.com/msilpala">Markus Silpala</a>
(with whom I
<a href="https://schmonz.com/2019/05/01/deliveragile-2019-strangle-your-legacy-code/">presented at last year’s deliver:Agile</a>).
We were then joined by
Cat,
<a href="https://twitter.com/SoulCraftswoman">April Jefferson</a>,
<a href="https://twitter.com/geekygirlsarah">Sarah Withee</a>,
<a href="https://twitter.com/jamesshore">James Shore</a>,
and
<a href="https://twitter.com/RonJeffries">Ron Jeffries</a>
for a game of
<a href="https://www.jackboxgames.com/quiplash/">Quiplash</a>
customized for the occasion by
<a href="https://twitter.com/MargaretMckever">Margaret McKever</a>.</p>
<p>I’m hoping the Alliance will post a video of the dramatic reading.
As geeky topics go, it was pretty dang dramatic.</p>
JC-JUG December 2020: J. B. Rainsberger on Unlocking the Awesome Power of Refactoringhttps://schmonz.com/2020/12/16/jcjug-december-2020-jbrains/Amitai Schleier2021-08-11T01:16:41Z2020-12-16T06:32:00Z
<p>This month’s meetup of the
<a href="https://www.meetup.com/Jersey-City-Java-User-Group-JC-JUG">Jersey City Java User Group</a>
continued the refactoring conversation from
<a href="https://schmonz.com/2020/11/18/jcjug-november-2020-stop-obsessing-about-primitives-with-ted-m-young/">last month</a>,
as
<a href="https://twitter.com/jbrains">J. B. Rainsberger</a>
presented
<a href="https://youtu.be/hGSde7whUyY">Unlocking the Awesome Power of Refactoring</a>
and discussion ensued.
On at least three occasions, J. B. anticipated and answered a question
we might have before being able to see that it had indeed been asked.
One more remarkable trick from a consultant, coach, and trainer loaded with neat tricks.</p>
<p>For my part, after a Zoom hiccup I even managed to record nearly the whole thing.
<a href="https://youtu.be/hGSde7whUyY">Give it a watch</a>,
and join the
<a href="https://www.meetup.com/Jersey-City-Java-User-Group-JC-JUG">JC-JUG Meetup group</a>
to keep up with what’s coming next.</p>
JC-JUG November 2020: Stop Obsessing About Primitives with Ted M. Younghttps://schmonz.com/2020/11/18/jcjug-november-2020-stop-obsessing-about-primitives-with-ted-m-young/Amitai Schleier2021-08-11T01:16:41Z2020-11-18T07:54:18Z
<p><a href="https://schmonz.com/2020/10/06/jcjug-october-2020-more-smaller-steps-with-geepawhill/">Last month’s meetup</a>
of the Jersey City Java User Group got us off to a rollicking restart.
At yesterday’s,
<a href="https://twitter.com/jitterted">Ted M. Young</a>
(also known as
<a href="https://www.twitch.tv/jitterted">JitterTed</a>)
presented
<a href="https://youtu.be/4cyBW39asBQ">Stop Obsessing about Primitives</a>.
Ted’s focus on how people learn means you’re just about guaranteed to come away with ideas you can use.
I sure did.
Give it a watch.
And join the
<a href="https://www.meetup.com/Jersey-City-Java-User-Group-JC-JUG">JC-JUG Meetup group</a>
(if you haven’t already)
to stay tuned for our next speaker.</p>
Agile Arizona 2020: Two Midwesterners Politely Invite You To Explore Codinghttps://schmonz.com/2020/11/13/agile-arizona-2020-two-midwesterners/Amitai Schleier2020-11-14T10:11:10Z2020-11-13T18:00:00Z
<p>On Friday, November 13,
<a href="https://twitter.com/AgileFaye">Faye Thompson</a>
and I once again co-facilitated
<a href="https://agilearizona.org/speakers.html#sn-amitai-schleier">Two Midwesterners Politely Invite You To Explore Coding</a>
at
<a href="https://agilearizona.org/">Agile Arizona</a>
(rebranded “Agile Arisofa” for our remote-only era). The abstract:</p>
<blockquote><p>Wonder what it’s like to do what programmers do?
Maybe people have tried to explain it, but didn’t put it in terms that computed for you.
Or maybe you would like to become more technical, but the mere thought of trying to code has felt intimidating.
Today is a new day!</p>
<p>Faye’s a non-programmer from Ohio, Amitai’s a sometimes-programmer from Illinois, and with your help, we’ll solve a problem by thinking and coding together.
If you want to, you can take a brief turn at the keyboard; if not, no biggie.
When we’re done, we think you’ll have a new kind of feeling about code and coding.
You might even want to pursue it further.</p></blockquote>
<p>Fitting this into 60 minutes was a bit squeezy, so we made two tradeoffs:</p>
<ol>
<li>Instead of finishing the test-driven story, get just enough examples to show the process</li>
<li>Instead of giving navigators the full navigating experience, do lots of navigating myself to get us somewhere interesting enough by the end</li>
</ol>
<p>This seems to have worked out, by our own lights and by those of our participants, several of whom stuck around after the bell to ask Faye more questions about TDD and mobbing.
I’d have liked to be available afterward too, but a kid needed my help navigating bedtime.</p>
<ul>
<li><a href="https://schmonz.com/2020/11/13/agile-arizona-2020-two-midwesterners/slides/">Slides</a></li>
</ul>
JC-JUG October 2020: More Smaller Steps with GeePaw Hillhttps://schmonz.com/2020/10/06/jcjug-october-2020-more-smaller-steps-with-geepawhill/Amitai Schleier2021-08-11T01:16:41Z2020-10-06T21:32:02Z
<p>Remember when meetups still happened in locations?
Of the 50 attendees at our first meetup of the revived
<a href="https://www.meetup.com/Jersey-City-Java-User-Group-JC-JUG">Jersey City Java User Group</a>,
one admitted to living in the New York metropolitan area.
And it wasn’t even me, the organizer.
And the talk wasn’t even about Java.</p>
<p>Did I fall down on the job?
No, I think this was the perfect way to start JC-JUG back up.
<a href="https://www.geepawhill.org/">GeePaw Hill</a>
(<a href="https://twitter.com/GeePawHill">Twitter</a>)
knows from Java, and I hope he’ll come back and present about Kotlin.
Give his <a href="https://youtu.be/WYK4kbrmm84">More Smaller Steps</a> a watch.
In it, he distills issues we all face in software development, where the game is to incrementally change complex systems made of inseparably commingled social and technical facets.</p>
<p>Our November speaker is already lined up.
Details soon.</p>
Back to work, remote-stylehttps://schmonz.com/2020/09/15/back-to-work-remote-style/Amitai Schleier2020-09-15T13:55:03Z2020-09-15T13:01:31Z
<p>After 4.5 months of parental leave, I once again have time, space, and attention for
<a href="https://latentagility.com">my consulting work</a>.
I’m pleased to be returning not only to my corporate and individual clients but also to
<a href="http://pubmob.com">PubMob</a>,
a new venture spearheaded by
<a href="https://langrsoft.com">Jeff Langr</a>.
Jeff bills it as “the first-ever marketplace for remote collaborative software development and training.”
(What’s “mob programming” about?
Here, I’ll tell you
<a href="https://agilein3minut.es/32">in 3 minutes</a>.)
From the press release:</p>
<blockquote><p>PubMob provides consumers and businesses with face-to-face access to software development experts in cozy and compact online forums known as mob programming sessions.
<a href="http://pubmob.com">PubMob.com</a> is open today worldwide and accepting bookings for sessions.</p></blockquote>
<p>In
<a href="http://pubmob.com/pubs/amitaischleier/">my pub</a>,
for starters, I’m offering
<a href="http://pubmob.com/offerings/amitaischleier-strangle-your-legacy-code/">Strangle Your Legacy Code</a>
this Friday.
If it looks like your sort of thing, I’d be happy to see you there.
If not, I’d be happy to hear about topics that interest you more.
Either way, also check out what’s on offer from
Emily Bache, Llewellyn Falco, J.B. Rainsberger, and the other
<a href="http://pubmob.com/pubs/">PubMob session leads</a>.</p>
notqmail 1.08 releasedhttps://schmonz.com/2020/05/20/notqmail-108-released/Amitai Schleier2023-11-09T01:12:08Z2020-05-20T21:14:45Z
<p><a href="https://notqmail.org"><img src="https://schmonz.com/software/notqmail.png" width="188" height="188" alt="notqmail logo" title="notqmail logo" class="img" align="right" /></a></p>
<p>I’m pleased to announce notqmail 1.08, the latest update to
<a href="https://schmonz.com/2019/08/20/announcing-notqmail/">notqmail</a>.
It addresses
<a href="https://www.qualys.com/2020/05/19/cve-2005-1513/remote-code-execution-qmail.txt">security vulnerabilities in qmail 1.03 reported yesterday by Qualys</a>.
As a fork, we’ve inherited qmail’s relatively few bugs;
as an <em>active</em> qmail fork, we’ve addressed the vulnerabilities with a timely release;
and as the collaborative Open Source successor to qmail, we
<a href="https://notqmail.org/trust">show our work</a>.</p>
<p>The 1.08 release also includes many other small improvements we’ve made since 1.07, including fewer compiler warnings, less dead code, published intent to remove more presumed-dead code,
<a href="https://schmonz.com/software/remote/">my QMAILREMOTE patch</a>,
and our first few unit tests.
For more detail, see the
<a href="https://notqmail.org/releases/1.08">notqmail 1.08 release notes</a>.</p>
Finias Tira Schleierhttps://schmonz.com/2020/05/06/finias-tira-schleier/Amitai Schleier2021-07-15T01:40:02Z2020-05-06T14:05:43Z
<p>Our second child arrived a week ago, on April 27, at 3540 grams (7 pounds, 13 ounces).
Wanting to minimize our stay in any sort of public place, we chose to return home with our same-day delivery.
Perfectly packaged, here’s Finias Tira Schleier:</p>
<p><img src="https://schmonz.com/2020/05/06/finias-tira-schleier/IMG_2938.JPG" width="300" height="400" alt="Finias Tira Schleier with big eyes" title="Finias Tira Schleier with big eyes" class="img" /></p>
<p>It’s disconcerting not to know when everyone will get to hold and smell Finias.
His brother’s eagerness to do the job — always with a gentle kiss — has been a source of comfort to us all.</p>
<p><img src="https://schmonz.com/2020/05/06/finias-tira-schleier/IMG_6853.JPG" width="400" height="578" alt="Taavi holding Finias" title="Taavi holding Finias" class="img" /></p>
<p>About the name:</p>
<h2>Finias</h2>
<p>From Hebrew Pinchas, “bronze-skinned one”.</p>
<ul>
<li>We chose an “F” name to honor Amitai’s great-aunt Fannie, a loving and beloved influence on his mother Dianne, and to carry on a bit of Rebekka’s family tradition of naming a son “Ferdinand” (as well as her father Ferdinand’s wish not to take the tradition too literally)</li>
<li>It also honors Rebekka’s maternal grandfather Pinchas (Paul) Arnovitz</li>
<li>It also honors Paul, our sweet orange cat who taught Finias’s older brother — with care, dignity, and one well-earned swipe — to be loving and gentle with those smaller than him</li>
<li>We like the derivation from Hebrew, in which P and F are neighboring sounds, so that the name can also suggest Pesach, the season of his birth and an allegory for this plague we hope will pass us all over</li>
<li>We like how Germans and Israelis and Americans will be able to pronounce it</li>
<li>Incidentally, his complexion does look more like Mama’s than Dada’s</li>
<li>Finally, it calls to mind a famous case in the medical literature (<a href="https://en.wikipedia.org/wiki/Phineas%5FGage">Phineas Gage</a>) that advanced our understanding of brains as integrated parts of whole bodies and behaviors, and this understanding has been particularly important to us and Finias throughout his gestation and early life</li>
</ul>
<h2>Tira</h2>
<p>Hebrew, “castle” or “fortress”.</p>
<ul>
<li>Many villages in the Middle East have a name derived from this, and for a safe birth during this pandemic we sought refuge in the castle-like safety of Rebekka’s home village</li>
<li>We like its phonetic resemblance to “terra”, the Earth under our feet (more on this in a moment)</li>
</ul>
<h2>Finias Tira Schleier</h2>
<p>We chose the name “Finias Tira” as it evokes <a href="https://en.wikipedia.org/wiki/Finisterre">Finisterre</a> (”Land’s End”), the name of several outlying locations beyond which once stood the unknown.
In this pandemic we’ve all been conscripted for a long and arduous journey toward new advances that we hope will reshape how we live.
With a month to go before Finias’s arrival, seeking relative safety and calm, we dropped everything to travel to a place in the middle of nowhere — a place that feels a bit like Land’s End — precisely because of what we <em>did</em> know about it.
His name tells the story.
We wish for him safety, calm, and the courage and curiosity to discover the unknown.</p>
<h2>About the date</h2>
<ul>
<li>4/27 = 2<sup>2</sup>/3<sup>3</sup></li>
<li>4*27 is a multiple of his brother’s 6*6 (and the multiple is 3, and in a month Taavi will be three)</li>
</ul>
<h3>More nice properties observed after the fact</h3>
<p>Taavi and I discovered, while reading
<a href="https://en.wikipedia.org/wiki/Castle%20%28book%29">David Macaulay’s Castle</a>,
that castles have
<a href="https://en.wikipedia.org/wiki/Finial">finials</a>.
Their purpose is no more and no less than “to emphasize the apex of a dome”.</p>
<p>If you think of another reason this is a nice name, please pass it along.</p>
<h2>More photos</h2>
<p><a href="http://photos.theschleiers.com/finias/">photos.theschleiers.com/finias</a></p>
Mini-SPA 2020: Strangle Your Legacy Codehttps://schmonz.com/2020/02/21/minispa-2020-strangle-your-legacy-code/Amitai Schleier2021-11-25T09:54:33Z2020-02-21T15:59:11Z
<p>On Friday, February 21,
I presented
“Strangle Your Legacy Code”
at
<a href="https://www.bcs.org/events/2020/february/mini-spa-conference-2020-leeds/">Mini-SPA</a>,
a one-day event in Leeds, UK.
I wasn’t in Leeds, but my talk was.
The abstract:</p>
<blockquote><p>Given an ancient codebase that makes refactoring risky and expensive, how do you clear a path to continued delivery?
The old wisdom says the best time to plant a tree was 20 years ago, and the next best time is today.
But if you already have a gnarled old source tree, preserve your software investment by planting a Strangler:
a pattern for reaping continuous value from your existing system while growing new functionality alongside it.
We’ll define our terms, meet some legacy code and its Strangler (both open source), then test-drive new features into the system.
You’ll leave with a powerful strategy for extending the useful life of working, valuable software — especially when it’s hard to change.</p></blockquote>
<ul>
<li><a href="https://schmonz.com/2020/02/21/minispa-2020-strangle-your-legacy-code/slides/">Slides</a></li>
<li><a href="https://schmonz.com/2020/02/21/minispa-2020-strangle-your-legacy-code/20200221-strangle-your-legacy-code.mp4">Video</a></li>
</ul>
<div class="video-container">
<iframe src="https://www.youtube-nocookie.com/embed/FmH8kIJosIU" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
<p>Two questions came in at the end:</p>
<ol>
<li>What architecture do I suppose is most often Strangled?
My best guess is web applications, both because there are so many of them and because web proxying is well understood.</li>
<li>How did I intercept network calls to the SMTP service?
qmail’s SMTP daemon has no network code in it, relying on <code>inetd</code> or <code>tcpserver</code> to map client-connected sockets to stdio.
That’s why I could type into it interactively simply by running it from the command line.</li>
</ol>
<p>”Strangle Your Legacy Code” is usually
<a href="https://deejaygraham.github.io/2018/08/15/strangling-legacy-code/">an interactive workshop</a>,
one of many I’m happy to offer your team.</p>
NYCBUG: What is notqmail?https://schmonz.com/2020/01/08/nycbug-what-is-notqmail/Amitai Schleier2020-02-13T00:48:55Z2020-01-08T20:40:14Z
<p>On Wednesday, January 8,
I attended the
<a href="https://www.nycbug.org">New York City BSD User Group</a>
to present
<a href="https://www.nycbug.org/index?action=view&id=10675">What is notqmail?</a>,
a perhaps not entirely surprising followup to my
<a href="https://schmonz.com/2019/03/06/nycbug-maintaining-qmail-in-2019/">March talk</a>.
At the time, I’d been trying to avoid creating yet another qmail fork.
This talk is about my failure — notqmail is alive and well — and about our success thus far.</p>
<p>Abstract:</p>
<blockquote><p>We all use email, so we all use email servers.
notqmail is software for running an
<a href="https://en.wikipedia.org/wiki/Message_transfer_agent">email server</a>.
Someday, if we do a good job, some of the many
<a href="https://arstechnica.com/information-technology/2014/02/how-to-run-your-own-e-mail-server-with-your-own-domain-part-1/">articles about how and why to run your own</a>
will recommend notqmail.</p>
<p><a href="http://notqmail.org">notqmail</a>
is a community-driven fork of
<a href="https://cr.yp.to/qmail.html">qmail</a>,
beginning where
<a href="http://netqmail.org">netqmail</a>
left off: providing stable, compatible, small releases to which existing qmail users can safely update.
notqmail also aims higher: developing an extensible, easily packaged, and increasingly useful modern mail server.</p></blockquote>
<ul>
<li><a href="https://schmonz.com/2020/01/08/nycbug-what-is-notqmail/slides/">Slides</a></li>
</ul>
<hr />
<h2>Work with me</h2>
<p>Would you personally benefit from an individualized session with an experienced, inquisitive, and empathetic conversation partner?
Maybe you’re facing a challenging situation at work, a learning opportunity in some code — or both.
Last week a new client went from “frustrated” to “energized” in the span of an hour.
Get in touch: <a href="https://latentagility.com">latentagility.com</a></p>
<p>Would your org benefit from a rare combination of technical coaching and impactful conversations?
(Take
<a href="https://latentagility.com/testimonials">other people’s word for it</a>,
not mine.)
It’s not too late to book some time with me in 2020.
Let’s talk about
<a href="https://latentagility.com">what fits for you</a>.</p>
How to start pair programminghttps://schmonz.com/2019/12/01/how-to-start-pair-programming/Amitai Schleier2019-12-02T21:16:34Z2019-12-02T11:12:14Z
<p>A reader
<a href="https://twitter.com/kritulrathod/status/1199175107312340994">asks for advice</a>
as his team gets started with pair programming.</p>
<p>Pairing can be fun, cost-effective, and risk-reductive.
These benefits come with skilled practice.
The needed skills can, of course, be learned.
Here are my suggestions for a team new to pair programming.</p>
<h2>1. Conserve energy</h2>
<p>Programming solo is tiring in familiar ways.
Programming in pairs is tiring in unfamiliar ways.
When starting out, limit your pairing to 2 hours a day, perhaps as two separate 1-hour sessions.
Later, when everyone’s gotten the hang of it and is excited about doing more, that’s the time to try doing a little more.</p>
<h2>2. Keep participation voluntary</h2>
<p>Collaborative work without eager, willing participation is not collaborative work at all.
Anyone who doesn’t want to try pairing should not try pairing.
Maybe, if everyone else seems to be having fun, they’ll change their mind; maybe not.
No idea is so good that it must be forced on people.</p>
<h2>3. Learn out loud</h2>
<p>There are many different techniques for pairing.
In “strong-style” pairing, the <strong>navigator</strong> expresses intentions and the <strong>driver</strong> listens and transcribes.
Switch roles every 5 minutes.
When your timer goes off, don’t worry about finishing the sentence or the thought.
Just switch roles, see how well you adjust, and consider how to make the next switch easier.
Worst case, you can finish the hanging thought 5 minutes from now.</p>
<h2>4. Build pairing skill</h2>
<p>If you’re about to try pairing, it’s probably not the only thing you’re hoping your team will try.
Defer as many of those other ideas as you possibly can.
Concentrate first on adjusting and getting good at working together in this new way while continuing to create code that isn’t too much different (maybe slightly better, since code review is happening all the time).
When pairing is going well, it will provide a platform to disseminate new ideas.
Before it’s going well, hold off on other new ideas as best you can.</p>
<h2>5. Learn incrementally</h2>
<p>Once you’re pairing, you’ll encounter lots of other ideas, such as writing tests first, refactoring opportunistically, and synthesizing these into Test-Driven Development.</p>
<p>WIP (Work-In-Progress) limits are every bit as useful for learning as they are for delivery, and for the same reasons.</p>
<p>Since delivery requires learning, a Learning-In-Progress limit of 1 might be too low.
Try a limit of 2.
For the rest, keep a shared list of everything your team would like to try.
When you encounter a new something you’d like to try, add it to the list.
When you’re ready to try a new something, look at the list and see what jumps out at you.
Wait until you’re comfortable with what you’ve learned (enough to call it “done”) before pulling your next learning item.</p>
<h2>6. Maybe don’t bother with pairing</h2>
<p>Extreme Programming took a bunch of practices that had worked well and turned the dials all the way up.
If we were adjusting those dials today, we’d turn the collaboration dial past pairing and work, as a whole team, on one problem at a time.</p>
<h2>7. Invite an experienced facilitator</h2>
<p>These guidelines may help your team navigate the shift to working together more closely.
I hope they do.
I hope you also consider bringing a seasoned software development coach to join you as you begin this journey.
It doesn’t <em>have</em> to be
<a href="https://latentagility.com">me</a>. <img src="https://schmonz.com/smileys/smile.png" alt=":-)" /></p>
<h2>Suggestions from others</h2>
<ul>
<li><a href="https://mihai.software/content/presentations/pairing-techniques/summary.html">Mihai Popescu’s lightning talk from deliver:Agile 2019</a></li>
<li><a href="https://twitter.com/jaybazuzi/status/1201184555580809216">Jay Bazuzi adds</a>
“4a. 5-minute retro at the end of each session.”</li>
<li>More about
<a href="http://llewellynfalco.blogspot.com/2014/06/llewellyns-strong-style-pairing.html">Llewellyn Falco’s strong-style pairing</a></li>
<li><a href="https://twitter.com/schmonz/status/1199349711573938176">the whole Twitter thread</a></li>
</ul>
<h2>Additional references</h2>
<ul>
<li>Audio: <a href="https://agilein3minut.es/9">Agile in 3 Minutes 9: Pair</a></li>
<li>Audio: <a href="https://agilein3minut.es/32">Agile in 3 Minutes 32: Mob</a></li>
<li>Video: <a href="https://schmonz.com/talk/20191121-adibolb-codecast/">Remote Pair Programming with Adi Bolboacă</a></li>
<li>Video: <a href="https://schmonz.com/talk/20190329-twitch-jitterted/">Remote Pair Programming with Ted M. Young</a></li>
<li>Video: <a href="https://schmonz.com/talk/20170519-agileuprising-tdd-mob/">TDD and Mob Programming for Non-Programmers</a></li>
<li>Upcoming conference: <a href="https://mobprogrammingnewengland.com">Mob Programming 2020</a></li>
</ul>
Manhattan November 2019: Global Day of Coderetreathttps://schmonz.com/2019/11/19/manhattan-november-2019-global-day-of-coderetreat/Amitai Schleier2019-11-19T20:49:32Z2019-11-19T20:47:05Z
<p><img src="https://schmonz.com/2019/11/19/IMG_8841.jpg" width="480" height="360" alt="Manny leading a discussion" class="img" /></p>
<p>On Saturday, November 16,
I was going to have
<a href="https://schmonz.com/2018/11/18/brooklyn-november-2018-global-day-of-coderetreat/">once again co-facilitated the New York City instance</a>
of
<a href="https://www.coderetreat.org">Global Day of Coderetreat</a>.
I wound up not doing much of that, because
<a href="http://emmanuelgenard.com">Emmanuel Genard</a>
from
<a href="https://www.stridenyc.com">Stride Consulting</a>
had it well in hand
and because the situation at home required all available parents.
(Taavi, having progressed from crib to anarchy while I’d been off at a client, has since progressed to getting the hang of a new bedtime routine.
Phew.)
My chief contributions in a mere 90 minutes at the
<a href="https://www.appacademy.io/">App Academy</a>
office in Midtown:</p>
<ol>
<li>Talked to GDCR participants in Nuremberg, where I’d
<a href="https://schmonz.com/2018/07/13/coding-tour-stop-1-mathema-redheads/">made</a>
some
<a href="https://schmonz.com/2018/08/31/coding-tour-stop-4-codecentric/">friends</a>
on my
<a href="https://schmonz.com/2018/04/23/coding-tour/">Coding Tour last summer</a></li>
<li>Talked to Edinburgh
(<a href="https://schmonz.com/2018/08/17/coding-tour-stop-3-canon-medical-research/">same</a>)</li>
<li>Failed to talk to Montreal due to technical difficulties</li>
<li>Distracted Manny and at least some of the participants</li>
<li>Took a picture of them</li>
</ol>
<p>I know, I’m impressed too.</p>
<p>But seriously, thank you to my friends at Stride for organizing, sponsoring, and facilitating, and to App Academy for sharing their space with us.</p>
<p>If you’re energized by coming home from Global Day of Coderetreat with several new points of view on a seemingly small problem, you might be the kind of person who’d enjoy a Coding Tour.
I’d be more than happy to chat about what it’s like to go on tour and how you can make it happen for yourself.</p>
<h2>More</h2>
<p>Could this format for learning help your team?
Code Retreat (or
<a href="https://legacycoderetreat.typepad.com/blog/">Legacy Code Retreat</a>)
is one of the ways your organization can benefit from my rare combination of technical coaching and impactful conversations.
(Take
<a href="https://latentagility.com/testimonials">other people’s word for it</a>,
not mine.)
It’s not too late to book me for 2020.
Let’s talk about
<a href="https://latentagility.com">what fits for you</a>.</p>
<p>If that’s not your decision to make, could you personally benefit from an individualized session with an experienced, inquisitive, and empathetic conversation partner?
Maybe you’re facing a challenging situation at work, a learning opportunity in some code — or both.
Get in touch: <a href="https://latentagility.com">latentagility.com</a></p>
Medtner: Hymn, Op. 54 No. 7https://schmonz.com/2019/09/27/medtner-hymn-op-54-no-7/Amitai Schleier2020-09-18T14:41:37Z2019-09-28T00:00:00Z
<p><em>Schmonzcast #21</em>: To celebrate my parents’ 50th anniversary, and to honor their having shipped me the baby grand I grew up playing, I chose
<a href="https://schmonz.com/2019/09/27/20190927-medtner-hymn-54-7.mp4">this Medtner piece</a>.
The last time I’d prepared a piece under deadline was in high school.
This Hymn is one of the “Romantic Sketches For The Young”, but its longer lines, greater directness, and C major tonality (and, sure, the Opus number) reveal it to be one of his later works.
Though the recording is impromptu and hastily reassembled, and my performance shows some rough spots, I think you’ll be able to piece together why
<a href="https://schmonz.com/2019/09/27/20190927-medtner-hymn-54-7.mp4">this is the song I wanted to sing them</a>.</p>
Announcing notqmailhttps://schmonz.com/2019/08/20/announcing-notqmail/Amitai Schleier2023-11-09T01:12:08Z2019-08-20T15:13:00Z
<p><a href="https://schmonz.com/2017/03/27/automation-for-mail-hosting/">Running my own email server</a> has its challenges.
Chief among them:
<a href="https://cr.yp.to/qmail.html">my favorite mail-server software</a>
hasn’t been updated since I started using it in 1998.</p>
<table class="img align-left"><caption>The qmail logo</caption><tr><td><a href="https://cr.yp.to/qmail.html"><img src="https://schmonz.com/2019/08/20/Q.6.01.Logo.lg.jpg" width="203" height="186" alt="qmail logo" title="qmail logo" class="invertible" /></a></td></tr></table>
<p>Okay, that’s not entirely true.
While qmail hasn’t been updated by
<a href="https://cr.yp.to/djb.html">its original author</a>,
a group of respected users created
<a href="http://netqmail.org">netqmail</a>,
a series of tiny updates that were informed, conservative, and careful.
By their design, it was safe for everyone running qmail to follow netqmail, so everyone did.
But larger changes in the world of email — authentication, encryption, and ever-shifting anti-spam techniques — remained as puzzles for each qmail administrator to solve in their own way.
And netqmail hasn’t been updated since 2007.</p>
<h2>One fork per person</h2>
<p>In the interim, devotees have continued maintaining their own individual qmail forks.
Some have shared theirs publicly.
I’ve preferred the design constraints of making minimal, purpose-specific, and conflict-avoidant
<a href="https://schmonz.com/software/">add-ons and patches</a>.
Then again, these choices are motivated by the needs of
<a href="https://schmonz.com/software/pkgsrc-qmail-run/">my qmail packaging</a>,
which I suppose is itself a <em>de facto</em> fork.</p>
<p>I’ve found this solo work quite satisfying.
I’ve
<a href="https://schmonz.com/2016/07/08/how-to-learn-c-part-1/">learned more C</a>,
reduced build-time complexity, added run-time configurability, and published
<a href="https://schmonz.com/2019/01/07/2018q4-qmail-updates-in-pkgsrc/">unusually polished and featureful qmail packages for over 20 platforms</a>.
Based on these experiences, I’ve given
<a href="https://schmonz.com/2019/01/25/devopsdays-nyc-run-your-own-email-server/">dozens</a>
of
<a href="https://schmonz.com/2019/05/01/deliveragile-2019-strangle-your-legacy-code/">workshops</a>
and
<a href="https://schmonz.com/2019/03/06/nycbug-maintaining-qmail-in-2019/">talks</a>.
In seeking to simplify system administration for myself and others,
I’ve become a better programmer and
<a href="https://latentagility.com">consultant</a>.</p>
<p>Still, wouldn’t it be more satisfying if we could somehow pool our efforts?
If, long after the end of DJB’s brilliant one-man show, a handful of us could shift how we relate to this codebase — and to each other — in order to bring a collaborative Open Source effort to life?
If, with netqmail as inspiration, we could produce safe updates while also evolving qmail to meet more present-day needs?</p>
<h2>One fork per community</h2>
<table class="img align-right"><caption>My subtle artwork</caption><tr><td><a href="https://notqmail.org"><img src="https://schmonz.com/software/notqmail.png" width="188" height="188" alt="notqmail logo == qmail logo overlaid by a red circle with a slash through it" title="notqmail logo == qmail logo overlaid by a red circle with a slash through it" class="img" /></a></td></tr></table>
<p>Say hello to
<a href="https://notqmail.org">notqmail</a>.</p>
<p>Our
<a href="https://notqmail.org/releases/1.07">first release</a>
is informed, conservative, and careful — but bold.
It reflects our brand-new team’s rapid convergence on where we’re going and how we’ll get there.
In the span of a few weeks, we’ve:</p>
<ul>
<li>Started this project</li>
<li>Grown to four active developers with diverse concerns, opinions, and skills</li>
<li>Defined our big-picture <a href="https://notqmail.org/goals-and-non-goals">goals (and non-goals)</a></li>
<li>Identified milestones for
<a href="https://notqmail.org/roadmap">future releases</a></li>
<li>Agreed on standards for
<a href="https://notqmail.org/pull-requests">pull requests</a></li>
<li>Merged only the changes that absolutely had to be in the first release</li>
<li>Shipped
<a href="https://github.com/notqmail/notqmail/releases/tag/notqmail-1.07">our first release</a></li>
</ul>
<p>I say “bold” because, for all the ways we intend to hew to qmail tradition, one of our explicit goals is a significant departure.
Back in the day, qmail’s
<a href="https://cr.yp.to/softwarelaw.html">lack of license</a>,
<a href="https://web.archive.org/web/20060127000918/http://cr.yp.to/qmail/dist.html">redistribution restrictions</a>,
<a href="https://cr.yp.to/qmail/var-qmail.html">technical barriers</a>,
and
<a href="http://pyropus.ca/personal/writings/12-steps-to-qmail-list-bliss.html#step9">social norms</a>
made it hard for OS integrators to create packages, and hard for package users to get help.
netqmail 1.06
<a href="https://marc.info/?l=qmail&m=119689105301544&w=2">expressed a desire to change this</a>.
In notqmail 1.07, we’ve
<a href="https://notqmail.org/install">made packaging much easier</a>.
(I’ve already
<a href="https://github.com/NetBSD/pkgsrc/commit/e1bbfdbd03f2607dd43bf91154647b56db9e063f">updated pkgsrc from netqmail to notqmail</a>,
and some of my colleagues have prepared
<a href="https://software.opensuse.org/download.html?project=home%3Anotqmail&package=notqmail">notqmail RPM and .deb packages</a>.)
Further improvements for packagers are part of what’s slated for 1.08.</p>
<h2>What’s next</h2>
<p>Looking much further ahead, another of our <a href="https://notqmail.org/goals-and-non-goals">explicit goals</a> is “Meeting all common needs with OS-provided packages”.
We have a <a href="https://notqmail.org/roadmap">long way to go</a>.
But we couldn’t be off to a better start.</p>
<p>By our design, we believe we’ve made it safe for everyone running qmail to follow notqmail.
We hope you’ll vet our changes carefully, then update your installations to notqmail 1.07.
We hope you’ll start observing us as we continue the work.
We hope you’ll discuss freely on the
<a href="https://cr.yp.to/lists.html#qmail">qmail mailing list</a>.
We hope you’ll be a part of the qmail revival in ways that are comfortable for you.
And we hope that, in the course of time, notqmail will prove to be the community-driven Open Source successor to qmail.</p>
NYC Large Scale Scrum May 2019https://schmonz.com/2019/05/16/nyc-large-scale-scrum-may-2019/Amitai Schleier2019-07-24T18:13:27Z2019-05-17T14:55:31Z
<p>On Thursday, May 16,
<a href="https://www.meetup.com/Large-Scale-Scrum-LeSS-in-NYC/">NYC Large Scale Scrum</a>
hosted a
<a href="https://www.meetup.com/Large-Scale-Scrum-LeSS-in-NYC/events/259549884/">meetup with LeSS co-creator Craig Larman</a>.
The event was held at Morgan Stanley
— where I learned
<a href="http://www.extremeprogramming.org">Extreme Programming</a>
and got my first taste of
<a href="https://latentagility.com">software development coaching</a> —
so it was a pleasure to be back in a speaking capacity.
I served as Craig’s opening act, keeping folks warmed up and tuned in with a mix of presentation and discussion until he arrived.</p>
<p>The discussion portion was stoked by
<a href="https://agilein3minut.es/">Agile in 3 Minutes</a>,
specifically
<a href="https://agilein3minut.es/1">Effect</a>
and
<a href="https://agilein3minut.es/5">Wrong</a>.
One of my favorite things to hear about the podcast is when it helps conversations get going, so one of my favorite things about sharing the material in person is watching that happen.
I can still hear the roar of
<a href="https://schmonz.com/2016/04/12/agileindy-2016-agilein3minutes-shoestring-agility/">450 people talking first thing in the morning as I opened AgileIndy 2016</a>.</p>
<table class="img"><caption>Photo by Gene Gendel</caption><tr><td><img src="https://schmonz.com/2019/05/16/20190516_182705.jpg" width="400" height="259" alt="Storytelling" title="Storytelling" class="img" /></td></tr></table>
<p>The presentation portion was me telling stories of growing my Morgan Stanley team’s circles of trust, collaboration, feedback, and impact by improving our technical capabilities in our code.
By a show of hands in the room, about half the audience had worked for Morgan Stanley or still does, and least half of those were familiar with the system I had been responsible for.
I didn’t know how much time I’d have, so I ordered the stories chronologically and worked my way through two of them — just enough to establish
<a href="https://schmonz.com/2015/08/12/tdd-saved-my-brain/">Test-Driven Development</a>
as a keystone of our team’s development, and tee up technical excellence as a keystone of the LeSS framework.
(To find out how our development continued,
<a href="https://schmonz.com/tag/tdd-in-context/">read the stories</a>.)</p>
<p>When I handed off the show to Craig, he took a seat up front between the two flipcharts, fielded questions, and held the room for an hour and a half with his expertise and manner.
It was my first time hearing him speak, and memorable from the outset.
He said things that are often hard to hear in a way that I’m guessing may have been relatively easy for this audience to hear.
It was occasion to reflect on how my consulting skills have grown since my time at Morgan Stanley and how I might grow them further.
And then it was occasion to go out for tacos with John, with whom I’d spent
<a href="https://agilein3minut.es/25">many a Friday night</a>
delivering new code to production.
Looking forward to seeing more of my former colleagues soon.</p>
Big Apple Scrum Day 2019: Two Midwesterners Politely Invite You To Explore Codinghttps://schmonz.com/2019/05/10/big-apple-scrum-day-2019-two-midwesterners/Amitai Schleier2019-05-17T15:01:15Z2019-05-10T22:16:59Z
<p>On Friday, May 10,
I attended
<a href="http://www.bigapplescrumday.org">Big Apple Scrum Day</a>,
was part of its
<a href="https://www.bigapplescrumday.org/coaches-clinic">Coaches Clinic</a>,
and co-facilitated a session called
<a href="https://www.bigapplescrumday.org/speakers">Two Midwesterners Politely Invite You To Explore Coding</a>
with
<a href="https://twitter.com/AgileFaye">Faye Thompson</a>.</p>
<p><img src="https://schmonz.com/2019/05/10/IMG_7201.jpg" width="400" height="300" alt="Faye debriefing after some code" title="Faye debriefing after some code" class="img" /></p>
<p>Here’s the abstract:</p>
<blockquote><p>Wonder what it’s like to do what programmers do?
Maybe people have tried to explain it, but didn’t put it in terms that computed for you.
Perhaps you’ve considered participating in your team’s mobbing sessions but weren’t confident that you could contribute.
Or maybe you would like to become more technical, but the mere thought of trying to code has felt intimidating.
Today is a new day!</p>
<p>Faye’s a non-programmer from Ohio, Amitai’s a sometimes-programmer from Illinois, and with your help, we’ll solve a problem by thinking and coding together.
If you want to, you can take a brief turn at the keyboard; if not, no biggie.
When we’re done, we think you’ll have a new kind of feeling about code and coding.
You might even want to pursue it further.</p></blockquote>
<ul>
<li><a href="https://schmonz.com/2019/05/10/big-apple-scrum-day-2019-two-midwesterners/slides/">Slides</a></li>
</ul>
<p>We got the audience we were hoping for: mostly folks who haven’t touched code much before, if at all.
Feedback suggests it might make a difference for at least a few of them.
For my part, co-presenting with Faye was easy and enjoyable, and her involvement made the session much more effective.</p>
<p><a href="https://twitter.com/NativeWired">Gitte Klitgaard</a>’s
keynote set a powerful tone for my third consecutive Big Apple Scrum Day.
It’s always a privilege to present
— and to provide free 1-on-1 sessions as part of
<a href="http://www.keystepstosuccess.com/2019/04/2019-big-apple-scrum-day-coaching-clinic-coaches-worksheet/">Gene Gendel’s Coaching Clinic</a>.
As an independent consultant, I especially appreciate the chance to offer something of value to an audience that’s local to me.</p>
deliver:Agile 2019: Strangle Your Legacy Codehttps://schmonz.com/2019/05/01/deliveragile-2019-strangle-your-legacy-code/Amitai Schleier2021-03-10T11:46:26Z2019-05-01T13:41:02Z
<p>I attended
<a href="https://www.agilealliance.org/deliveragile-2019">deliver:Agile</a>
in Nashville and co-facilitated a session called
<a href="https://deliveragile2019.sched.com/event/N36Z/strangle-your-legacy-code-amitai-schleier-markus-silpala">Strangle Your Legacy Code</a>
with
<a href="https://twitter.com/msilpala">Markus Silpala</a>.
As a group, we practiced adding features to an old SMTP server without modifying its code.
Then we reflected on the potential applications, benefits, and risks of the Strangler application pattern.</p>
<table class="img"><caption>Photo by Avdi Grimm</caption><tr><td><a href="https://twitter.com/avdi/status/1123621220371574789"><img src="https://schmonz.com/2019/05/01/avdi-photo.jpg" width="400" height="300" alt="Me, some code, and some clasped hands" title="Me, some code, and some clasped hands" class="img" /></a></td></tr></table>
<p>Abstract:</p>
<blockquote><p>Given an ancient codebase that makes refactoring risky and expensive,
how do you clear a path to continued delivery?
The old wisdom says the best time to plant a tree was 20 years ago,
and the next best time is today.
But if you already have a gnarled old source tree, preserve your
software investment by planting a Strangler: a pattern for reaping
continuous value from your existing system while growing new
functionality alongside it.</p>
<p>We’ll take a quick look at a Strangler, demonstrate the basics of
<a href="https://agilein3minut.es/32">Mob Programming</a>,
then split into small groups to test-drive new features into
the system.
You’ll leave with a powerful strategy for extending the useful life of
working, valuable software — <em>especially</em> when it’s hard to change —
and with a free bonus development practice to accelerate your team’s
learning.
For a limited time only!</p></blockquote>
<p>You can find our code, our learnings, and links to more resources in the…</p>
<ul>
<li><a href="https://schmonz.com/2019/05/01/deliveragile-2019-strangle-your-legacy-code/slides/">Slides</a></li>
</ul>
<p>Wondering what this interactive, participatory session was like?
Take a look at
<a href="https://twitter.com/deejaygraham">Derek Graham</a>’s
writeup
<a href="https://deejaygraham.github.io/2018/08/15/strangling-legacy-code/">from last summer</a>.</p>
<p>Wondering what might make it better?
Markus got some excellent feedback (I had to head straight for the airport) and
<a href="https://markus.silpala.com/2019/05/02/retrospective-our-session-at-deliveragile2019/">synthesized some ideas</a>.</p>
<h2>Reflections</h2>
<p>After missing last year’s event, I was happy to be back at the Agile Alliance’s tech-focused conference.
(I’d been part of the
<a href="https://schmonz.com/2016/04/10/aatc-2016-devops-dojo-discussion-panel/">first</a>
<a href="https://schmonz.com/2017/04/20/aatc-2017-cross-platform-deployment/">two</a>
“AATC”s, and enjoyed them greatly.)
Markus and I have been remote-<a href="https://agilein3minut.es/9">pairing</a>
daily since November, so it was a treat (and doubtless beneficial for our client) to get to room with him and co-facilitate something
<a href="https://schmonz.com/2017/04/29/agile-coach-camp-2017/">again</a>.</p>
<p>Lots of other highlights, too.
This conference is always a who’s who of folks I’ve been lucky to learn from and get to know, and a chance to deepen both.
For instance, until Tuesday at deliver:Agile, I don’t think I’d managed to catch a quiet Ron-and-Chet chat since I stopped consulting in southeast Michigan.
The best of many moments, though, might have been while catching up with James Grenning.
He’d just been encouraging me to continue along my current path when someone came up to us — bound for James, I assumed — to shake my hand and thank me for my
<a href="https://schmonz.com/tag/">blog posts</a>,
<a href="https://agilein3minut.es/">podcasts</a>,
and generally
<a href="https://schmonz.com/tag/not-talk/">being me</a>.
That would have made my night under most any circumstances, and I told him it did.
All the more so, given how and when.</p>
<p>Chief lowlights: several people I didn’t get near enough time with.</p>
<p>Guess I’ll have to come back next year. <img src="https://schmonz.com/smileys/smile.png" alt=":-)" /></p>
<hr />
<h2>Missed it?</h2>
<p>Invite me to present internally for your organization in the NY metro area.
Or take a look at my
<a href="https://schmonz.com/speaker/">upcoming speaking engagements</a>
and
<a href="https://gist.github.com/schmonz/3d941ccc8e18a458537144cca707d191">some conferences and meetups I’m considering</a>.</p>
<h2>Loved it?</h2>
<p>Let’s take a half hour (or less) and explore how my rare and highly effective combination of
<a href="https://latentagility.com/services">technical coaching</a>
and
<a href="https://latentagility.com">impactful conversations</a>
could be useful to your organization.</p>
<p><a href="mailto:inquire@latentagility.com">Get in touch</a>.</p>
SmartBear April 2019: Mob Programming Explainedhttps://schmonz.com/2019/04/11/smartbear-mob-programming-explained/Amitai Schleier2021-11-25T09:54:33Z2019-04-11T18:00:00Z
<p>On Thursday, April 11,
I presented a webinar with
<a href="https://smartbear.com/company/about-us/">SmartBear</a>
called
<a href="https://smartbear.com/resources/webinars/mob-programming/">Mob Programming Explained</a>.
The abstract:</p>
<blockquote><p>Software development is complex.
It’s knowledge work.
How often does one developer know everything needed to solve a customer problem with code?
And on that rare occasion, how beneficial is it to the business for nobody else to have been involved?</p>
<p>Enter Mob Programming: the whole team, together, solving one problem at a time.
Come learn how it works, how it relates deeply to Agile and Lean values, and how it can address a surprising array of organizational and technical challenges.
Not a programmer? Mobbing on complex problems is for you, too — and so is this presentation.</p></blockquote>
<ul>
<li><a href="https://schmonz.com/2019/04/11/smartbear-mob-programming-explained/slides/2019-mobprogramming-smartbear.pdf">Slides</a></li>
<li><a href="https://smartbear.com/blog/collaborate/is-mob-programming-right-for-you-amitai-schleier-e/">Alex McPeak’s recap</a></li>
</ul>
<p>The video:</p>
<div class="video-container">
<iframe src="https://www.youtube-nocookie.com/embed/eLLOOmS-7pY" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
Training: Personal Kanbanhttps://schmonz.com/2019/03/11/training-personal-kanban/Amitai Schleier2019-03-12T00:17:15Z2019-03-11T16:47:24Z
<h2>Habits can change</h2>
<p>I have a habit I like very much: incorporating some professional training every year.
Last year my needs led me to go on a
<a href="https://schmonz.com/2018/09/15/coding-tour-summer-2018-conclusion/">coding tour</a>.</p>
<p>I also have habits I don’t like very much, particularly about how I allocate my time.
So when I heard
<a href="http://personalkanban.com/pk/">Personal Kanban</a>
training was coming to New York, I needed to allocate only a small amount of time to deliberate.
<a href="https://twitter.com/ItsUnderstood/status/1096513337506975744">Sue Johnston helped</a>,
too.</p>
<p>20 minutes in, I could tell my learning would be in good hands with
<a href="https://twitter.com/Sprezzatura">Tonianne DeMaria</a>
and
<a href="https://twitter.com/ourfounder">Jim Benson</a>.
The ideas I was hearing were ones I knew and cared for, and they were being used in the service of people being whole people.</p>
<h2>Emotions contain information</h2>
<p>One such idea: a leading indicator for software quality problems is the emotional state of the developers.
(For me, this connects directly to
<a href="https://twitter.com/GeePawHill">Michael D. “GeePaw” Hill</a>’s
formulation of
<a href="http://geepawhill.org/my-agility-1/">made-making-maker</a>.)
If we’re uncomfortable with what we just delivered, that’s a signal.
If we ignore our emotions and the information they contain, we’re likely to experience them again, more painfully.
Or — check this out, fellow humans! — we could help each other observe and value our emotional signals.</p>
<p>Another such idea: in Lean manufacturing, where work is standard, variation is desirable to reduce.
In Lean software development, where work is knowledge, variation is desirable to <em>understand</em>.
Can we learn to expect where it comes from?
If so, our planning will improve.
(Can we differentiate “accidental” and “essential” variation?
If so, we can drive down the former and our planning will further improve.)</p>
<h2>Lean in code and class</h2>
<p>What does the application of Lean principles to software development look like?
Perhaps the best known example thus far is
<a href="https://agilein3minut.es/32">Mob Programming</a>:
when the whole team works on the same problem on the same computer, we get single-piece flow, a WIP limit of 1, just enough decisions made just in time, shared context, and easy predictability.
I had enough to say about mobbing, it seems, to be called “the Mob Programming guy” in our class.
In response to
<a href="https://en.wikipedia.org/wiki/Pomodoro%20Technique">Pomodoro Technique</a>,
I also offered what I might call “Inverse Pomodoro”: when you <em>are</em> being pulled away, write down your next thought before you lose it. Then it’s waiting for you when you come back.
When my work is programming, I do it
<a href="https://schmonz.com/2015/08/19/life-hacks-for-the-test-infected/">like this</a>.</p>
<p>What does the application of Lean principles to teaching look like?
A couple
<a href="http://www.bigapplescrumday.org/">Big Apple Scrum Day</a>s
ago,
<a href="https://twitter.com/ryanripley">Ryan Ripley</a>
and I did an entirely audience-driven talk where folks told us what they were wondering about and
<a href="https://schmonz.com/2017/05/01/basd-2017-t-shaped-people/">that’s what we talked about</a>.
Jim and Tonianne did this for two whole days, relating each idea back to previous ones, often via previous visuals.
As a result, I found myself relating familiar ideas in new ways.
If I hadn’t encountered most of them previously, I might well have been overwhelmed.
It was plenty to take in as it was.</p>
<h2>Insights</h2>
<p>Hearing about Jim and Toni’s working relationship, I realized: I’d pay someone to irregularly but periodically wipe my kanban board (and absorb my reaction).
I tend to habituate quickly to my board and forget I have agency to rethink everything about how it works.
When it’s been cleared, I’ve been reminded.
After several emptyings, I might even find myself less attached to my backlog.
Might be nice.</p>
<p>Hearing about Personal Kanban in the service of whole people, with health explicitly non-negotiable, I was reminded of a hypothesis:
<a href="https://schmonz.com/2017/01/05/new-years-slack/">a balanced life is a small-batch-size life</a>.
Mine hasn’t been so balanced lately.
Returning to visualizing my work — everything I need to do to have the life I want — will help.
I’m eager to get to my office, lay out a dozen stickies with fresh design considerations, and build myself a fresh board.</p>
<hr />
<h2>Previous trainings</h2>
<ul>
<li>2018: Schleier, <em><a href="https://schmonz.com/2018/09/15/coding-tour-summer-2018-conclusion/">Coding Tour</a></em></li>
<li>2017: Larsen, <em><a href="https://schmonz.com/2017/12/29/training-agile-fluency-game/">Leading Agile Adoptions with the Agile Fluency Game</a></em></li>
<li>2016: Grenning, <em><a href="https://schmonz.com/2016/06/18/training-tdd-for-embedded-c/">Test-Driven Development for Embedded C</a></em></li>
<li>2015: Weinberg and Derby, <em><a href="https://schmonz.com/2015/06/17/problem-solving-leadership/">Problem Solving Leadership</a></em></li>
<li>2014: Cockburn, <em><a href="https://schmonz.com/2014/11/05/assumption-carpaccio/">Coaching in an Agile Context</a></em></li>
</ul>
NYCBUG: Maintaining qmail in 2019https://schmonz.com/2019/03/06/nycbug-maintaining-qmail-in-2019/Amitai Schleier2021-11-25T09:54:33Z2019-03-07T02:59:47Z
<p>On Wednesday, March 6,
I attended
<a href="https://www.nycbug.org">New York City BSD User Group</a>
and presented
<a href="https://www.nycbug.org/index?action=view&id=10665">Maintaining qmail in 2019</a>.
This one pairs nicely with my recent DevOpsDays
<a href="https://en.wikipedia.org/wiki/Ignite%5F%28event%29">Ignite</a>
talk about why and how to
<a href="https://schmonz.com/2019/01/25/devopsdays-nyc-run-your-own-email-server/">Run Your @wn Email Server!</a>
That this particular “how” could be explained in 5 minutes is remarkable, if I may say so myself.
In this NYCBUG talk — my first since
<a href="https://schmonz.com/2014/03/05/nycbug-2014-one-weird-trick-to-simplify-package-management/">2014</a>
— I show my work.
It’s a real-world, open-source tale of methodically, incrementally reducing complexity in order to afford added functionality.</p>
<p>My abstract:</p>
<blockquote><p>qmail 1.03 was notoriously bothersome to deploy.
Twenty years later, for common use cases, I’ve finally made it pretty easy.
If you want to try it out, I’ll help!
(Don’t worry, it’s even easier to uninstall.)
Or just listen as I share the sequence of stepwise improvements from then to now — including pkgsrc packaging, new code, and testing on lots of platforms — as well as the reasons I keep finding this project worthwhile.</p></blockquote>
<ul>
<li><a href="https://schmonz.com/2019/03/06/nycbug-maintaining-qmail-in-2019/slides/">Slides</a></li>
</ul>
<p>Here’s the video:</p>
<div class="video-container">
<iframe src="https://www.youtube-nocookie.com/embed/xR776OFqqeA" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
NY XP & Agile February 2019: Strangle Your Legacy Codehttps://schmonz.com/2019/02/21/ny-xpagile-strangle-your-legacy-code/Amitai Schleier2019-03-06T16:24:38Z2019-02-22T02:39:40Z
<p>On Thursday, February 21, I attended
<a href="https://www.meetup.com/xp-26/">New York XP & Agile</a>
and presented
<a href="https://www.meetup.com/xp-26/events/258389200/">Strangle Your Legacy Code</a>.
As a mob, we practiced adding features to an old SMTP server without
modifying its code.</p>
<p>Abstract:</p>
<blockquote><p>Given an ancient codebase that makes refactoring risky and expensive,
how do you clear a path to continued delivery?
The old wisdom says the best time to plant a tree was 20 years ago,
and the next best time is today.
But if you already have a gnarled old source tree, preserve your
software investment by planting a Strangler: a pattern for reaping
continuous value from your existing system while growing new
functionality alongside it.</p>
<p>We’ll take a quick look at a Strangler, demonstrate the basics of
<a href="https://agilein3minut.es/32">Mob Programming</a>,
then split into small groups to test-drive new features into
the system.
You’ll leave with a powerful strategy for extending the useful life of
working, valuable software — <em>especially</em> when it’s hard to change —
and with a free bonus development practice to accelerate your team’s
learning.
For a limited time only!</p></blockquote>
<ul>
<li><a href="https://schmonz.com/2019/02/21/ny-xpagile-strangle-your-legacy-code/slides/">Slides</a></li>
</ul>
<p>Wondering what this interactive, participatory session was like?
Take a look at
<a href="https://twitter.com/deejaygraham">Derek Graham</a>’s
writeup
<a href="https://deejaygraham.github.io/2018/08/15/strangling-legacy-code/">from last summer</a>.</p>
DevOpsDays NYC: Run Your @wn Email Server!https://schmonz.com/2019/01/25/devopsdays-nyc-run-your-own-email-server/Amitai Schleier2019-02-21T16:40:24Z2019-01-25T22:53:41Z
<p>In late January,
I was at
<a href="https://www.devopsdays.org/events/2019-new-york-city">DevOpsDays NYC</a>
in midtown Manhattan
to present
<a href="https://www.devopsdays.org/events/2019-new-york-city/program/amitai-schleier">Run Your @wn Email Server!</a></p>
<p>My abstract:</p>
<blockquote><p>When we’re responsible for production, it can be hard to find room to
learn. That’s why I run my own email server. It’s still “production”
— if it stays down, that’s pretty bad — but I own all the decisions,
take more risks, and have learned lots. And so can you! Come see why
and how to get started.</p>
<p>With one command, install famously secure email software. A couple
more and it’s running. A few more and it’s encrypted. Twiddle your
DNS, watch the mail start coming in, and start feeling responsible for
a production service in a way that web hosting can’t match.</p></blockquote>
<ul>
<li><a href="https://schmonz.com/2019/01/25/devopsdays-nyc-run-your-own-email-server/slides/">Slides</a></li>
</ul>
2018Q4 qmail updates in pkgsrchttps://schmonz.com/2019/01/07/2018q4-qmail-updates-in-pkgsrc/Amitai Schleier2023-06-28T04:40:46Z2019-01-07T18:19:43Z
<p>Happy 2019!
Another three months, another stable branch for
<a href="https://www.pkgsrc.org">pkgsrc, the practical cross-platform Unix package manager</a>.
I’ve shipped quite a few improvements for qmail users in our
<a href="http://mail-index.netbsd.org/pkgsrc-users/2018/12/30/msg027871.html">2018Q4 release</a>.
In three sentences:</p>
<ol>
<li><a href="https://schmonz.com/software/pkgsrc-qmail-run/">qmail-run</a>
gains TLS, SPF, IPv6, SMTP recipient checks, and many other
sensible defaults.</li>
<li>Most qmail-related packages — including the new ones used by
qmail-run — are available on most pkgsrc platforms.</li>
<li><a href="http://pkgsrc.se/pkgtools/rc.d-boot">rc.d-boot</a>
starts <code>rc.conf</code>-enabled pkgsrc services at boot time on many
platforms.</li>
</ol>
<p>In one:</p>
<blockquote><p>It’s probably easy for you to run qmail now.</p></blockquote>
<p>On this basis, at
<a href="https://schmonz.com/talk/2019-devopsdays/">my DevOpsDays NYC talk in a few weeks</a>,
I’ll be recommending that everyone try it.</p>
<h2>Try it</h2>
<script>
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => {
const newColorScheme = event.matches ? 'dark' : 'light';
const oldColorScheme = event.matches ? 'light' : 'dark';
const players = document.getElementsByClassName('asciinema-player asciinema-theme-solarized-' + oldColorScheme);
while (players.length > 0) {
players[0].className = 'asciinema-player asciinema-theme-solarized-' + newColorScheme;
}
});
const initialColorScheme = (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) ? 'dark' : 'light';
</script>
<p>Here’s a demo on CentOS 7, using binary packages:</p>
<div id="centos7"></div>
<script>
AsciinemaPlayer.create('../centos7-pkgsrc-qmail.cast', document.getElementById('centos7'), {
cols: 88,
rows: 42,
autoPlay: false,
preload: false,
loop: false,
startAt: 0,
speed: 1,
theme: 'solarized-' + initialColorScheme,
poster: 'data:text/plain,pkgsrc 2019Q2: qmail on CentOS 7',
fit: false,
});
</script>
<p>The main command I ran:</p>
<pre><code>$ sudo env PKG_RCD_SCRIPTS=yes pkgin -y install qmail-run rc.d-boot
</code></pre>
<p>Here’s another demo on Debian 9, building from source packages:</p>
<div id="debian9"></div>
<script>
AsciinemaPlayer.create('../debian9-pkgsrc-qmail.cast', document.getElementById('debian9'), {
cols: 88,
rows: 42,
autoPlay: false,
preload: false,
loop: false,
startAt: 0,
speed: 1,
theme: 'solarized-' + initialColorScheme,
poster: 'data:text/plain,pkgsrc 2018Q4: qmail on Debian 9',
fit: false,
});
</script>
<p>The commands I ran:</p>
<pre><code>$ cd ...pkgsrc/mail/qmail-run && make PKG_RCD_SCRIPTS=yes install
$ cd ../../pkgtools/rc.d-boot && make PKG_RCD_SCRIPTS=yes install
</code></pre>
<p>These improvements were made possible by
<a href="https://schmonz.com/software/acceptutils/">acceptutils</a>,
my redesigned TLS and SMTP AUTH implementation that obviates the
need for several large and conflicting patches.
Further improvements are expected.</p>
<p>Here’s the full changelog for qmail as packaged in pkgsrc-2018Q4.</p>
<h2>Removed</h2>
<ul>
<li>From <code>mail/mess822</code>:
<ul>
<li>The SMTP AUTH patch.</li>
</ul>
</li>
<li>From <code>mail/qmail</code>:
<ul>
<li>The SMTP AUTH patch.</li>
<li>The <code>qmail-smtpd</code> half of the TLS patch.</li>
<li>The RCPTCHECK patch.</li>
</ul>
</li>
<li>From <code>mail/qmail-run</code>:
<ul>
<li>Dependency on spamdyke.</li>
<li>Dependency on stunnel.</li>
</ul>
</li>
<li>From <code>sysutils/checkpassword</code> and <code>sysutils/checkpassword-pam</code>:
<ul>
<li>The setuid bit.</li>
</ul>
</li>
</ul>
<h2>Updated</h2>
<ul>
<li><code>mail/qmail</code>:
<ul>
<li>To the latest
<a href="https://schmonz.com/software/tlsonlyremote/"><code>qmail-remote</code> half of the TLS patch</a>.</li>
<li>To warn if the queue filesystem is case-insensitive.</li>
</ul>
</li>
<li><code>mail/qmail-rejectutils</code>:
<ul>
<li>To let <code>qmail-rcptcheck</code> run under
<a href="http://qmail-spp.sourceforge.net/">qmail-spp</a>,
so that other RCPTCHECK programs can continue to run unmodified.</li>
<li>To deprecate <code>qmail-qfilter-ofmipd-queue</code> and
<code>qmail-qfilter-smtpd-queue</code> in favor of <code>qmail-qfilter-queue</code>.</li>
</ul>
</li>
<li><code>mail/qmail-run</code>’s defaults:
<ul>
<li>To <code>sslserver</code> (from <code>tcpserver</code>).</li>
<li>To listen on IPv6 when available.</li>
<li>To auto-enable TLS for message submission, incoming SMTP, and
POP3 (as well as remote delivery) when certs are in place.</li>
<li>To tag log entries with <code>nbqmail/send</code>, <code>nbqmail/smtpd</code>, etc.
(inspired by Postfix).</li>
<li>To find tcprules in <code>control/tcprules/*</code> (and auto-migrate from
<code>/etc/qmail/tcp.*</code>).</li>
<li>To rebuild outdated tcprules CDBs on startup.</li>
<li>To delay the SMTP greeting by 2 seconds (a simple anti-spam measure).</li>
<li>To check the <code>zen.spamhaus.org</code> RBL.</li>
<li>To check recipients using qmail’s delivery logic before accepting mail.</li>
<li>To record a <code>Received-SPF:</code> header.</li>
<li>To skip
<a href="https://en.wikipedia.org/wiki/greylisting">greylisting</a>
(if any) when SPF returns “pass”.</li>
<li>To record a <code>Received:</code> header with TLS protocol and ciphers.</li>
<li>To let users
<a href="https://schmonz.com/software/acceptutils/features/">configure their own <code>ofmipd</code> address-rewriting
rules</a>.</li>
</ul>
</li>
</ul>
<h2>Added</h2>
<ul>
<li><a href="http://pkgsrc.se/mail/greylisting-spp"><code>mail/greylisting-spp</code></a>:
<ul>
<li>For greylisting.</li>
</ul>
</li>
<li><a href="http://pkgsrc.se/mail/qmail-spp-spf"><code>mail/qmail-spp-spf</code></a>:
<ul>
<li>For SPF checks.</li>
</ul>
</li>
<li><code>pkgtools/rc.d-boot</code>:
<ul>
<li>For starting pkgsrc-provided services at boot on a variety of systems.</li>
</ul>
</li>
<li>To <code>devel/syncdir</code>:
<ul>
<li>A
<a href="https://schmonz.com/software/syncdirdlsym/"><code>dlsym()</code>-based implementation</a>,
for systems without <code>syscall()</code>.</li>
</ul>
</li>
<li>To <code>mail/qmail</code>:
<ul>
<li>The qmail-spp patch, for flexibly modifying SMTP behavior at runtime.</li>
</ul>
</li>
<li>To <code>mail/qmail-rejectutils</code>:
<ul>
<li>Manual pages.</li>
</ul>
</li>
<li>To <code>mail/qmail-run</code>:
<ul>
<li><code>greylisting-spp-wrapper</code>, for whitelisting recipient addresses or
whole domains, and optionally omitting IP address from
greylisting’s tuples.</li>
</ul>
</li>
<li>To <code>mail/qmail</code> and <code>mail/qmail-run</code>:
<ul>
<li>Cleaner uninstall, so people can feel comfortable trying qmail.</li>
</ul>
</li>
</ul>
Brooklyn November 2018: Global Day of Coderetreathttps://schmonz.com/2018/11/18/brooklyn-november-2018-global-day-of-coderetreat/Amitai Schleier2018-11-19T18:14:29Z2018-11-18T16:57:54Z
<p>Yesterday I co-facilitated the
<a href="https://www.meetup.com/Community-Position-Dev/events/253609066/">Brooklyn instance</a>
of
<a href="https://www.coderetreat.org">Global Day of Coderetreat</a>.
Last year, having just
<a href="https://schmonz.com/2017/01/27/now/">moved back to New York</a>,
I was disappointed we didn’t have a GDCR instance going on around here.
(<a href="https://twitter.com/adibolb">Adi Bolboacă</a>,
who was facilitating in Paris, did me the kindness of connecting me with a participant there for a remote pairing session.) So this year, when I saw
<a href="https://twitter.com/horrorcheck">Libby Horacek</a>
would be organizing and hosting at
<a href="https://positiondev.com">her company</a>,
I offered to try to make myself useful. I think it worked out.</p>
<blockquote><p>We had an incredible #GDCR18 today! Thanks so much to @8thLightInc for
sponsoring, to @schmonz for co-facilitating, and to the participants
for being so enthusiastic, thoughtful, and engaged!<br />
—<a href="https://twitter.com/positiondev/status/1063927602149318664">@PositionDev</a></p></blockquote>
<p>I opened the day by playing
<a href="https://en.wikipedia.org/wiki/PowerPoint%20Karaoke">Presentation Karaoke</a>
with the GDCR-issued slide deck, adding a few details about the
<a href="https://www.coderetreat.org/pages/facilitating/structure-of-a-coderetreat/">Code Retreat format</a>,
and suggesting three themes for the day: Play, Gratitude, and Community.</p>
<h2>Play</h2>
<p>At work, we’re responsible for outcomes. We learn when learning is required to solve the problem efficiently (which turns out to be pretty often). Code Retreat is play. We know we’ll delete our code every 45 minutes, so we’re free to try a bunch of new ways of making it.</p>
<p>Kids play to build richer mental models of their world, to grow their explanatory and predictive powers, to acquire problem-solving tools to be synthesized as needed, to gain confidence in more situations, and to
<a href="https://schmonz.com/2015/04/08/how-to-develop-humans/">ride the positive feedback loop of following their enthusiasm</a>.</p>
<p>As adults, even though we need these things just as much as kids do, we don’t play nearly as much. We need all the chances we can get. Code Retreat is a chance for us to play. If it goes well, we’ll find our thinking refreshed and our enthusiasm for programming renewed.</p>
<h2>Gratitude</h2>
<p>The name “Code Retreat” has the effect of encouraging people who wouldn’t want to spend a day at something called “Code Retreat” to self-select out. This is probably good. It means we can be pretty sure everyone here really wants to be here. But there are also plenty of folks who’d love to be here and can’t. Sometime today, take a moment to appreciate your good fortune in having the time, energy, freedom, and space to spend a day this way, your own choices in life that have opened you to this opportunity, and the actions of others that helped bring you to it.</p>
<p><a href="https://schmonz.com/2013/12/13/global-day-of-code-retreat/">My first GDCR</a>
arguably set me on my
<a href="https://latentagility.com/services">current career path</a>,
and inarguably instigated a great deal of learning.</p>
<h2>Community</h2>
<p>I owe the state of my career in large part to many people who have been incredibly generous with their time, expertise, and reputation. It is the absolute least I can do to ask you to think about ways you can be generous with yours. I’ll do a little of this myself, too.</p>
<p>Today it’s not only a community we’re part of, but a community of communities. A Code Retreat can happen any time, any place; Global Day of Coderetreat is everywhere, right now. We’ll get to say hello to people all over the world (Vienna, London, Atlanta, Montreal, and Seattle, as it happened) who are doing what we’re doing because they care about what we care about.</p>
<h2>Constraints</h2>
<p>The first session is for getting our brains familiar with the problem (Conway’s Game of Life) and thinking about
<a href="https://agilein3minut.es/9">pairing</a>.
Each of the sessions that follows imposes some constraint likely to change how we think about solving the problem. Of the many, many known options, we chose:</p>
<ol>
<li><a href="https://cumulative-hypotheses.org/2011/08/30/tdd-as-if-you-meant-it/">TDD As If You Meant It</a></li>
<li><a href="http://c2.com/cgi/wiki?PairProgrammingPingPongPattern">Ping Pong Pairing</a></li>
<li><a href="https://www.coderetreat.org/blog/2013/03/11/taking-baby-steps/">Baby Steps</a></li>
<li><a href="https://williamdurand.fr/2013/06/03/object-calisthenics/">Object Calisthenics</a></li>
<li><a href="https://docs.google.com/document/d/1WcAUdyrfTtmU2KYZacmaTNZgk_sB6eZIv13DSyUUSOU/edit">Evil Pair</a></li>
</ol>
<p>With Baby Steps, I was newly interested to hear whether people noticed that they succeeded more frequently on their first attempt to make a new red test green. My guess is they would. But it didn’t seem so, at least not that they noticed or reported. I still need to try
<a href="https://medium.com/@kentbeck_7670/test-commit-revert-870bbd756864"><code>test && commit || revert</code></a> for myself.</p>
<p><img src="https://schmonz.com/2018/11/18/meetup.jpg" width="480" height="360" alt="At day's end" class="img" /></p>
<h2>Learnings</h2>
<p>Going around the room, every single person had a new trick or tool or shortcut to share. (One had written a full page of new IntelliJ shortcuts to take home. Awesome.)</p>
<p>Kritul Rathod posted
<a href="https://twitter.com/kritulrathod/status/1063991817916596224">his key takeaways</a>.</p>
<p>Someone who’s been pairing all day every day for years with dozens of people came away with a nuanced insight about pair dynamics.</p>
<p>At lunch, I had a conversation with someone who was interested in giving interns the sort of learning experiences I had on my recent
<a href="https://schmonz.com/2018/04/23/coding-tour/">coding tour</a>.
I certainly don’t know an answer, but I agree it’s important for more people to have experiences like these, and was able to give her some ideas.</p>
<p>After preaching that folks get involved in community-focused activities, I of course found out that more than a few already are, and well beyond my own involvement. Heartening. Maybe I didn’t need to have said anything about that. Or maybe someone else will turn out to have been newly inspired by the idea and the day.</p>
<h2>More</h2>
<p>Could this format for learning help your team? I’ll gladly facilitate a Code Retreat (or
<a href="https://legacycoderetreat.typepad.com/blog/">Legacy Code Retreat</a>)
for your company. I offer
<a href="https://latentagility.com/services">consulting, coaching, and training</a>
in the New York metropolitan area. Here’s
<a href="https://latentagility.com/">what people say</a>
about their time with me.</p>
NYC Lean/Kanban + CTO School: Mob Programming Workshophttps://schmonz.com/2018/10/25/nyc-mob-programming-workshop/Amitai Schleier2023-12-19T15:13:11Z2018-10-26T02:02:09Z
<p>On Thursday, October 25 in Manhattan, I presented a
Mob Programming Workshop
at the first ever joint meetup of
<a href="https://www.meetup.com/ctoschool/events/255218065/">CTO School</a>
and
<a href="https://www.meetup.com/nyc-kanban/events/252036869/">NYC Lean/Kanban</a>.</p>
<p>Abstract:</p>
<blockquote><p>Mob Programming brings the whole team together to one terminal,
programmer and non-programmer alike, to improve quality and speed of
building and deploying software.
This group-process may feel counterintuitive, but provides many
benefits such as increased empathy for other roles, fewer blocked
programmers, and fewer bugs.</p>
<p>The CTO School and Lean/Kanban meetups will be partnering to bring
programmers, product managers, and agile coaches to try our hands at
solving a problem in small groups by thinking and coding together.</p>
<p>Wondering what this interactive, participatory session will be like?
Amitai ran it this summer in Edinburgh on
<a href="https://schmonz.com/2018/04/23/coding-tour/">coding tour</a>, and
<a href="https://schmonz.com/2018/08/14/lean-agile-edinburgh-august-2018-programming-for-nonprogrammers/">there’s video</a>.</p>
<p>Join
<a href="https://www.linkedin.com/in/schmonz">Amitai Schleier</a>,
a sometimes-programmer originally from the friendly midwest, as we
solve a problem in small groups by thinking and coding together.
If you want to, you can take a brief turn at the keyboard; if not, no biggie.
When we’re done, we think you’ll have a new kind of feeling about code and coding.
You might even want to pursue it further.</p></blockquote>
<p><img src="https://schmonz.com/2018/10/25/IMG_5877.jpg" width="480" height="360" alt="Three of the four mobs" class="img" /></p>
<p>We did
<a href="https://web.archive.org/web/20230321132408/https://agileoutloud.wordpress.com/2018/05/11/tdd-by-storywriting/">TDD For Non-Programmers</a>
(<em>not</em> a coding exercise!) together, then split into four
<a href="https://agilein3minut.es/32">mobs</a>
to program
<a href="https://en.wikipedia.org/wiki/Fizz%20buzz">FizzBuzz</a>
in Python at
<a href="http://cyber-dojo.org">Cyber-Dojo</a>.
All four groups solved it!</p>
<ul>
<li><a href="https://schmonz.com/2018/10/25/nyc-mob-programming-workshop/slides/">Slides</a></li>
</ul>
Coding Tour Summer 2018: Conclusionhttps://schmonz.com/2018/09/15/coding-tour-summer-2018-conclusion/Amitai Schleier2023-06-07T17:34:43Z2018-09-15T13:05:42Z
<p>After my fourth and final tour stop, we decamped to Mallorca for a week.
With no upcoming workshops to polish and no upcoming plans to finalize, the laptop stayed home.
Just each other, a variety of beaches, and the annual
<a href="https://www.seemallorca.com/reviews/les-festes-del-rei-en-jaume-santa-ponsa-698864">Les Festes del Rei En Jaume</a>
that Bekki and I last saw two years ago on our honeymoon.
The parade was perhaps a bit much for Taavi.</p>
<p><img src="https://schmonz.com/2018/09/15/coding-tour-summer-2018-conclusion/480x360-IMG_5489.jpg" width="408" height="360" alt="Looking away" title="Looking away" class="img" /></p>
<p>The just-released
<a href="https://schmonz.com/talk/20180913-agile-for-humans/">episode 99 of Agile for Humans</a>
includes some reflections (starting around 50 minutes in) from partway through my coding tour.
As our summer in Germany draws to a close, I’d like to reflect on the tour as a whole.</p>
<h2>Annual training</h2>
<p>I’ve made a habit of setting aside time, attention, and money each year for focused learning.
My most recent trainings, all formative and memorable:</p>
<ul>
<li>2014: Cockburn, <em><a href="https://schmonz.com/2014/11/05/assumption-carpaccio/">Coaching in an Agile Context</a></em></li>
<li>2015: Weinberg and Derby, <em><a href="https://schmonz.com/2015/06/17/problem-solving-leadership/">Problem Solving Leadership</a></em></li>
<li>2016: Grenning, <em><a href="https://schmonz.com/2016/06/18/training-tdd-for-embedded-c/">Test-Driven Development for Embedded C</a></em></li>
<li>2017: Larsen, <em><a href="https://schmonz.com/2017/12/29/training-agile-fluency-game/">Leading Agile Adoptions with the Agile Fluency Game</a></em></li>
</ul>
<p>I hoped Schleier, <em>Coding Tour</em> would fit the bill for 2018.
<a href="https://schmonz.com/resume/">It has</a>.</p>
<h2>Geek joy</h2>
<p>At the outset, I was asked how I’d know whether the tour had gone well.
My response: “It’s a success if I get to meet a bunch of people in a bunch of places and we have fun programming together.”</p>
<p>I got to program with a bunch of people in a bunch of places.
We had fun doing it.
Success!</p>
<h2>New technologies</h2>
<p>My first tour stop offered such an ecumenical mix of languages, tools, and techniques that I began writing down each new technology I encountered.
I’m glad I started at the beginning.
Even so, this list of things that were new or mostly new to me is probably incomplete:</p>
<ul>
<li><a href="https://docs.pact.io">Pact</a>,
<a href="https://www.barco.com/en/clickshare">ClickShare</a>,
<a href="https://docs.microsoft.com/en-us/ef/">Entity Framework</a>,
<a href="https://jmeter.apache.org">JMeter</a>,
<a href="https://docs.microsoft.com/en-us/dotnet/core/testing/unit-testing-with-mstest">MSTest</a>,
<a href="https://docs.microsoft.com/en-us/visualstudio/test/unit-test-your-code">Visual Studio Unit Testing Framework</a>,
<a href="https://developer.microsoft.com/en-us/windows/iot">Windows on Raspberry Pi</a>,
<a href="https://www.eclipse.org/photon/">Eclipse Photon</a>,
<a href="http://dunkels.com/adam/pt/">protothreads</a>,
<a href="https://ascom-standards.org">ASCOM</a>,
<a href="http://hibernate.org">Hibernate</a>,
<a href="http://www.eclipse.org/jubula/">Jubula</a>,
<a href="https://wiki.openjdk.java.net/display/OpenJFX/Main">JavaFX</a>,
<a href="http://rest-assured.io">REST-assured</a>,
<a href="http://barneydellar.blogspot.com/2018/05/mobodoro.html">mobodoro</a>,
mob rotation every 2 minutes 30 seconds,
<a href="http://www.boost.org/doc/libs/release/libs/test/doc/html/index.html">Boost Test</a>,
<a href="https://jfrog.com/artifactory/">Artifactory</a>,
<a href="https://www.mercurial-scm.org">Mercurial</a>,
<code>_</code> for ignoring a parameter,
<a href="https://www.scala-lang.org">Scala</a>,
<a href="http://www.scalatest.org">ScalaTest</a>,
<a href="http://www.scalatest.org/at_a_glance/WordSpec">WordSpec</a>,
<a href="http://blog.jessitron.com/2013/04/property-based-testing-what-is-it.html">property-based testing</a>,
<a href="https://www.scalacheck.org">ScalaCheck</a>,
<a href="https://cloud.google.com/sql/docs/">Google Cloud SQL</a>,
<a href="https://akka.io">Akka</a></li>
</ul>
<p>In the moment, learning new technologies was a source of geek joy.
In the aggregate, it’s professionally useful.
I think the weight clients tend to place on consultants needing to be expert in their tech stack is dangerously misplaced, but it doesn’t matter what I think if they won’t bring me in.
Any chance for me to broaden my tech background is a chance for a future client to take advantage of all the other reasons I can be valuable to them.</p>
<h2>Insights</h2>
<p>As
<a href="https://schmonz.com/2007/05/14/schmonzs-theorem/">Schmonz’s Theorem</a>
predicts, code-touring is both similar to and different from consulting.</p>
<p>When consulting, I expect most of my learning to be meta: the second loop (at least) of
<a href="https://en.wikipedia.org/wiki/double%2Dloop%20learning">double-loop learning</a>.
When touring, I became reacquainted with the simple joys of the first loop, spending all day learning new things to be able to do.
It often felt like play.</p>
<p>When consulting, I initially find myself being listened to in a peculiar way, my words being heard and measured carefully for evidence of my real intentions.
My first tasks are to demonstrate that I can be trusted and that I can be useful, not necessarily in that (or any) order.
Accomplishing this as a programmer on tour felt easier than usual.</p>
<p>When I’m consulting, not everyone I encounter wants me there.
Some offer time and attention because they feel obligated.
On this tour, even though some folks were surprised to find out their employer wasn’t paying me anything, I sensed people were sharing their time and attention with me out of curiosity and generosity.
I believe I succeeded in making myself trusted and useful to each of them, and the
<a href="https://www.youtube.com/playlist?list=PLkuryjnRFclTZkaCn8KgjyyQ7DqBPZUWV">conversation videos</a>
and
<a href="https://latentagility.com/testimonial/alex/">written</a>
<a href="https://latentagility.com/testimonial/patrick/">testimonials</a>
help me hold the belief.</p>
<h2>Professional development</h2>
<p>With so much practice designing and facilitating group activities, so much information-rich feedback from participants, and so many chances to try again soon, I’ve leveled up as a facilitator.
I was comfortable with my skills, abilities, and material before; I’m even more comfortable now.
In my tour’s final public meetup, I facilitated one of my legacy code exercises for three simultaneous mobs.
It went pretty well — in large part because of the participants, but also because of my continually developing skill at designing and facilitating learning experiences.</p>
<p>As a consultant, it’s a basic survival skill to quickly orient myself in new problem spaces.
As a coach, my superpower might be that I help others quickly orient themselves in <em>their</em> problem spaces.
Visiting many teams at many companies, I got lots of practice at both.
These areas of strength for me are now stronger, the better with which to serve my next clients.</p>
<p>On several occasions I asked mobs not to bother explaining the current context to me before starting the timer.
My hypothesis was, all the context I’d need would reveal itself through doing the work and asking a question or two along the way.
(One basis among many for this hypothesis: what happened when I
<a href="https://schmonz.com/2018/04/20/mob-programming-and-scna-2018/">showed up late to one of Lennart Fridén’s sessions</a>
at this spring’s Mob Programming Conference and everyone else had already read the manual for our CPU.)
I think there was one scenario where this didn’t work extremely well, but my memory’s fuzzy — have I mentioned meeting a whole bunch of people at a whole bunch of workplaces, meetups, and conferences? — so I’ll have to report the details when I rediscover it.</p>
<h2>You can do this too, and I can help</h2>
<p>When
<a href="https://schmonz.com/2018/04/23/coding-tour/">designing my tour</a>,
I sought advice from several people who’d gone on one.
(Along the way I met several more, including
<a href="https://twitter.com/s4nchez">Ivan Sanchez</a>
at
<a href="https://schmonz.com/2018/07/04/spa-software-in-practice-2018/">SPA in London</a>
and
<a href="https://twitter.com/dtemme">Daniel Temme</a>
at
<a href="https://schmonz.com/2018/08/28/socrates-2018/">SoCraTes in Soltau</a>.)</p>
<p>If you’re wondering whether a coding tour is something you want to do, or how to make it happen, get in touch.
I’m happy to listen and offer my suggestions.</p>
<h2>What’s next for me, and you can help</h2>
<p>Like what I’m doing?
Want more of it in your workplace?</p>
<p>I offer short, targeted engagements in the New York metro area — coaching, consulting, and training — co-designed with you to meet your organization’s needs.</p>
<p>More at <a href="https://latentagility.com">latentagility.com</a>.</p>
<h2>Gratitude</h2>
<p>Yes, lots.</p>
<p>It’s been a splendid set of privileges to have the free time to go on tour, to have organizations in several countries interested to have me code with them, and to meet so many people who care about what I care about when humans develop software together.</p>
<p>Five years ago I was discovering the existence of a set of communities of shared values in software development and my need to feel connected to them.
Today I’m surer than ever that I’ve needed this connection and that I’ve found it.</p>
<p>Thanks to the people who hosted me for a week at their employer:
<a href="https://twitter.com/drechsler">Patrick Drechsler</a>
at
<a href="https://www.mathema.de">MATHEMA</a>/<a href="https://www.redheads.de">Redheads</a>
in Erlangen,
<a href="https://twitter.com/alex_schl">Alex Schladebeck</a>
at
<a href="https://www.bredex.de">BREDEX</a>
in Braunschweig,
<a href="https://twitter.com/branaby">Barney Dellar</a>
at
<a href="https://research.eu.medical.canon">Canon Medical Research</a>
in Edinburgh, and
<a href="https://twitter.com/thbrunzendorf">Thorsten Brunzendorf</a>
at
<a href="https://www.codecentric.de">codecentric</a>
in Nürnberg and München.
And thanks to these companies for being willing to take a chance on bringing in an itinerant programmer for a visit.</p>
<p>Thanks and apologies in equal measure to
<a href="https://twitter.com/ArghRich">Richard Groß</a>,
who did all the legwork to have me visit
<a href="https://www.maibornwolff.de">MaibornWolff</a>
in Frankfurt, only to have me cancel at just about the last minute.
At least we got to enjoy each other’s company at
<a href="https://schmonz.com/2018/06/24/agile-coach-camp-germany-2018/">Agile Coach Camp Germany</a>
and SoCraTes (the only two people to attend both!).</p>
<p>Thanks to
<a href="https://twitter.com/dgheath21">David Heath</a>
at the UK’s
<a href="https://www.gov.uk/government/organisations/government-digital-service">Government Digital Service</a>
for inviting me to join them on extremely short notice when I had a free day in London, and to
<a href="https://twitter.com/OlafLewitz">Olaf Lewitz</a>
for making the connection.</p>
<p>Thanks to the meetups and conferences where I was invited to present:
<a href="https://schmonz.com/2018/06/14/mallorca-software-craft-june-2018-vending-machine-kata/">Mallorca Software Craft</a>,
<a href="https://schmonz.com/2018/07/04/spa-software-in-practice-2018/">SPA Software in Practice</a>,
<a href="https://schmonz.com/2018/07/07/pkgsrccon-2018-maintaining-qmail-in-2018/">pkgsrcCon</a>,
<a href="https://schmonz.com/2018/07/12/hackerkegeln-nuernberg-july-2018-strangle-your-legacy-code/">Hackerkegeln</a>,
<a href="https://schmonz.com/2018/07/19/jug-ostfalen-braunschweig-july-2018-when-to-stop-kata/">JUG Ostfalen</a>,
<a href="https://schmonz.com/2018/08/14/lean-agile-edinburgh-august-2018-programming-for-nonprogrammers/">Lean Agile Edinburgh</a>,
<a href="https://schmonz.com/2018/08/15/nebytes-newcastle-august-2018-strangle-your-legacy-code/">NEBytes</a>,
and
<a href="https://schmonz.com/2018/08/30/munich-software-craft-august-2018-strangle-your-legacy-code/">Munich Software Craft</a>.
And thanks to Agile Coach Camp Germany and SoCraTes for the open spaces I did my part to fill.</p>
<p>Thanks to
<a href="https://twitter.com/somesheep">Marc Burgauer</a>,
<a href="https://twitter.com/jensschauder">Jens Schauder</a>,
and
<a href="https://twitter.com/JuttaEckstein">Jutta Eckstein</a>
for making time to join me for a meal.
Thanks to Zeb Ford-Reitz, Barney Dellar, and their respective spice for inviting me into their respective homes for dinner.</p>
<p>Thanks to
<a href="https://twitter.com/jbrains">J.B. Rainsberger</a>
for simple, actionable advice on making it easy for European companies to reimburse my expenses, and more broadly on the logistics of going on European consulting-and-speaking tours when one is from elsewhere.
(BTW, his next tour begins soon.)</p>
<p>Thanks all over again to everyone who helped me design and plan the tour, most notably
<a href="https://twitter.com/SalFreudenberg">Dr. Sal Freudenberg</a>,
<a href="https://twitter.com/LlewellynFalco">Llewellyn Falco</a>,
and
<a href="https://twitter.com/NicoleRauch">Nicole Rauch</a>.</p>
<p>Thanks to
<a href="https://twitter.com/WoodyZuill">Woody Zuill</a>,
<a href="https://twitter.com/BillyGarnet">Bryan Beecham</a>,
and
<a href="https://twitter.com/timothep">Tim Bourguignon</a>
for that serendipitous conversation in the park in London.
Thanks to Tim for having been there in the park with me.
(No thanks to Woody for waiting till we’d left London before arriving.
At least David Heath and GDS got to see him.
Hmph.)</p>
<p>Thanks to
<a href="https://twitter.com/lisihocke">Lisi Hocke</a> for making my wish a reality: that
<a href="https://www.lisihocke.com/2018/09/testing-tour-stop-18-mob-exploring-with-amitai-and-codecentric.html">her testing tour and my coding tour would intersect</a>.
As a developer, I have so much to learn about testing and so few chances to learn from the best.
She made it happen.
A perfect ending for my tour.</p>
<p>Thanks to
<a href="https://twitter.com/ryanripley">Ryan Ripley</a>
for having me on
<a href="https://agileforhumans.com">Agile for Humans</a> a couple more times as the tour progressed.
I can’t say enough about what Ryan and his show have done for me, so this’ll have to be enough.</p>
<p>Thanks to everyone else who helped draw special attention to my tour when I was seeking companies to visit, most notably
<a href="https://twitter.com/KentBeck">Kent Beck</a>.
It really did help.</p>
<p>Another reason companies cited for inviting me: my micropodcast, Agile in 3 Minutes.
Thanks to
<a href="https://agilein3minut.es/34">Johanna Rothman</a>,
<a href="https://agilein3minut.es/35">Andrea Goulet</a>,
<a href="https://agilein3minut.es/36">Lanette Creamer</a>,
<a href="https://agilein3minut.es/37">Alex Harms</a>,
and
<a href="https://agilein3minut.es/38">Jessica Kerr</a>
for your wonderful guest episodes.
You’ve done me and our listeners a kindness.
I trust it will come back to you.</p>
<p>Thank you to my family for supporting my attempts at growth, especially when I so clearly need it.</p>
<p>Finally, thanks to all of you for following along and for helping me find the kind of consulting work I’m best at, close to home in New York.
You can count on me continuing to learn things and continuing to share them with you.</p>
<h2>FIN</h2>
<hr />
<ul>
<li><a href="https://schmonz.com/tag/coding-tour/">All coding tour posts</a></li>
<li><a href="https://twitter.com/search?q=%23CodingTour&src=typed_query&f=live">All coding tour tweets</a> (twitter.com)</li>
<li><a href="https://www.youtube.com/playlist?list=PLkuryjnRFclTZkaCn8KgjyyQ7DqBPZUWV">All end-of-week conversations</a> (youtube.com)</li>
<li><a href="https://latentagility.com">My consultancy</a> (latentagility.com)</li>
</ul>
Coding Tour Stop #4: codecentrichttps://schmonz.com/2018/08/31/coding-tour-stop-4-codecentric/Amitai Schleier2023-06-07T17:34:43Z2018-09-01T10:13:22Z
<p><em>[Update:
Thorsten wrote a few words about our week together.
<a href="https://latentagility.com/testimonial/thorsten/">They’re quite nice</a>.]</em></p>
<p>The final week of my coding tour came right on the heels of
<a href="https://schmonz.com/2018/08/28/socrates-2018/">SoCraTes</a>.
On Sunday evening I went straight from Soltau to Nuremberg.
On Monday morning, when
<a href="https://twitter.com/thbrunzendorf">Thorsten Brunzendorf</a>
met me in the lobby of my hotel, it was the first time I’d seen him since… Sunday afternoon.
Like several other already-familiar-by-now faces, he’d been at SoCraTes too.</p>
<p>This tour stop was different from the start: we’d spend our first three days in one city and the last two in another.</p>
<h2>Monday</h2>
<ul>
<li><a href="https://www.scala-lang.org">Scala</a></li>
<li><a href="http://kata-log.rocks/mars-rover-kata">Mars Rover</a></li>
<li>TDD in-memory aggregates, headed toward
<a href="http://postgresql.org">PostgreSQL</a></li>
<li>New to me:
<a href="http://www.scalatest.org">ScalaTest</a>,
<a href="http://www.scalatest.org/at_a_glance/WordSpec">WordSpec</a>,
<a href="https://akka.io">Akka</a>,
<a href="http://scalikejdbc.org">scalikejdbc</a>,
<a href="https://github.com/jeremylong/DependencyCheck">OWASP dependency-check</a>,
<a href="https://www.terraform.io">Terraform</a>,
<a href="https://docs.ansible.com/ansible/latest/user_guide/vault.html">Ansible Vault</a>,
<a href="https://lightbend.github.io/config/">Typesafe Config</a>,
<a href="http://junit.sourceforge.net/javadoc/org/junit/Assume.html">org.junit.Assume</a></li>
</ul>
<h2>Tuesday</h2>
<ul>
<li>New to me:
<a href="https://www.dropwizard.io">Dropwizard</a></li>
<li>Discussion (with running examples) about test value, cost</li>
<li>Updated
<a href="https://www.fractint.org">xfractint</a>
(what a throwback!)
<a href="https://github.com/NetBSD/pkgsrc/commit/dfe0dd9610f1936961a5d6b7f477d7baddbc6528">in pkgsrc</a></li>
<li>Helped install
<a href="https://www.openbsd.org">OpenBSD</a>
on spare ThinkPad</li>
<li>Biergarten @thbrunzendorf @drechsler talking architecture, coaching</li>
</ul>
<h2>Wednesday</h2>
<p><img src="https://schmonz.com/2018/08/31/IMG_5244.JPG" width="480" height="163" alt="Mobbing in Scala with Thorsten and Martin" title="Mobbing in Scala with Thorsten and Martin" class="img" /></p>
<ul>
<li>Updated my local Scala setup</li>
<li>More Mars Rover; found a small-step path to refactor <code>Direction</code> to know its left and right</li>
<li>Mob Programming, TDD: mapping an old structure to new, then aggregating</li>
</ul>
<h2>Thursday</h2>
<p><img src="https://schmonz.com/2018/08/31/strangler.jpg" width="480" height="360" alt="Introducing ‘Strangle Your Legacy Code'" title="Introducing ‘Strangle Your Legacy Code'" class="img" /></p>
<ul>
<li>Train to Munich</li>
<li>Krustenschweinebraten</li>
<li>Mars Rover with @thbrunzendorf in Scala using
<a href="http://blog.jessitron.com/2013/04/property-based-testing-what-is-it.html">property-based testing</a>,
live-streamed on
<a href="https://www.twitch.tv/schmonzie">Twitch</a>
to 5 observers</li>
<li>Strangle Your Legacy Code with 3 parallel mobs
<a href="https://schmonz.com/2018/08/30/munich-software-craft-august-2018-strangle-your-legacy-code/">at Munich Software Craft</a></li>
</ul>
<h2>Friday</h2>
<p><img src="https://schmonz.com/2018/08/31/exploratory.jpg" width="480" height="360" alt="Navigating during Lisi's session" title="Navigating during Lisi's session" class="img" /></p>
<ul>
<li>Talk through @thbrunzendorf’s recent story-slicing workshop</li>
<li>Observe a Git workshop</li>
<li>Exploratory testing in a mob with
<a href="https://twitter.com/lisihocke">Lisi Hocke</a>
on her #TestingTour</li>
<li>Review the week</li>
<li>Board the train</li>
</ul>
<p>Here are
<a href="https://twitter.com/search?q=%23CodingTour%20since%3A2018-08-27%20until%3A2018-09-01&src=typd&f=live&vertical=default">all #CodingTour tweets from the week</a>.</p>
<h2>Reflections</h2>
<p>Even though the odds keep stacking higher and higher, the pattern of each tour stop varying meaningfully from the previous ones continued at codecentric.
For instance, we chose not to do Learning Hours.
I think one reason I didn’t particularly miss it is that <em>I</em> was so busy learning.
I’d seen Scala once before, for an hour; here we worked in it all week, both in katas and on production code.
And property-based testing had been on my long list of techniques I know I need to learn about.
Now I’ve had it explained to me simply and well by Thorsten and I’ve used it enough to know some ways it can help me go where I want to go.</p>
<p><img src="https://schmonz.com/2018/08/31/IMG_5262.JPG" width="480" height="360" alt="Lisi and me" title="Lisi and me" class="img" /></p>
<p>I’m a fan of Lisi’s testing tour and of
<a href="https://www.lisihocke.com/search/label/testingtour">how she writes about it</a>.
The chance to learn with her felt like the perfect ending for my tour.
Here’s
<a href="https://www.lisihocke.com/2018/09/testing-tour-stop-18-mob-exploring-with-amitai-and-codecentric.html">her post about it</a>.
Next week I’ll offer my reflections on the tour as a whole.</p>
<p>Thorsten, Martin, and I got together Friday afternoon to share some of our highlights from the week.
Have a look.</p>
<div class="video-container">
<iframe src="https://www.youtube-nocookie.com/embed/lnsrD6_KQRM" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
Munich Software Craft August 2018: Strangle Your Legacy Codehttps://schmonz.com/2018/08/30/munich-software-craft-august-2018-strangle-your-legacy-code/Amitai Schleier2018-08-30T20:25:06Z2018-08-30T20:15:48Z
<p>On Thursday, August 30 in Munich, I attended
<a href="https://www.meetup.com/munich-software-craft-community/">Munich Software Craft</a>
and presented
<a href="https://www.meetup.com/munich-software-craft-community/events/253675616/">Strangle Your Legacy Code</a>.
We split into several
<a href="https://agilein3minut.es/32">mobs</a>
to practice adding features to an old SMTP server without modifying its code.</p>
<ul>
<li><a href="https://schmonz.com/2018/08/30/munich-software-craft-august-2018-strangle-your-legacy-code/slides/">Slides</a></li>
</ul>
<p>Abstract:</p>
<blockquote><p>Given an ancient codebase that makes refactoring risky and expensive, how do you clear a path to continued delivery?
The old wisdom says the best time to plant a tree was 20 years ago, and the next best time is today.
But if you already have a gnarled old source tree, preserve your software investment by planting a Strangler: a pattern for reaping continuous value from your existing system while growing new functionality alongside it.</p>
<p>We’ll take a quick look at a Strangler, demonstrate the basics of Mob Programming, then split into small groups to test-drive new features into the system.
You’ll leave with a powerful strategy for extending the useful life of working, valuable software — <em>especially</em> when it’s hard to change — and with a free bonus development practice to accelerate your team’s learning.
For a limited time only!</p></blockquote>
SoCraTes 2018https://schmonz.com/2018/08/28/socrates-2018/Amitai Schleier2023-04-22T11:55:21Z2018-08-29T07:17:03Z
<p>I’d been hearing great things about the
<a href="https://www.socrates-conference.de">International Conference for Software Craft and Testing</a>
for years.
Last year, I
<a href="https://twitter.com/schmonz/status/900661671982714881">narrowly missed it</a>.
This past weekend, I finally made it to the 8th SoCraTes.
“Craft” isn’t exactly my thing, but the people who congregate around it are often exactly my people.</p>
<p>Before arriving, I’d only experienced
<a href="https://en.wikipedia.org/wiki/Open%20Space%20Technology">Open Space</a>
at
<a href="https://agilecoachcamp.org">Agile Coach Camps</a>,
or as a portion of a regular conference.
I was excited to see what might happen when programmers get a hold of the idea.</p>
<p><img src="https://schmonz.com/2018/08/28/IMG_5218.jpg" width="480" height="360" alt="Dragan driving, Daniel navigating" title="Dragan driving, Daniel navigating" class="img" /></p>
<p>What happened was, two dials on this conference were turned way up:</p>
<ol>
<li>Inclusion</li>
<li><a href="http://geepawhill.org/the-team-and-three-flows/">Geek joy</a></li>
</ol>
<p>They had been turned up with intention by the organizers and facilitator.
And they stayed up because of a positive feedback loop: mostly geek joy amplified by people feeling included, but also inclusion amplified by people feeling joyful.</p>
<p>I convened three sessions:</p>
<ul>
<li><a href="https://schmonz.com/2018/04/23/coding-tour/">Coding Tour</a>: what, why, how</li>
<li><a href="https://agilein3minut.es/32">Mob Programming</a> (a.k.a. “help me finish
<a href="https://schmonz.com/software/acceptutils/">my open source project</a>”)</li>
<li>Workshop My Workshop (a.k.a. “help me adapt ‘Strangle Your Legacy
Code’ to multiple simultaneous mobs”)</li>
</ul>
<p>And enjoyed many others.
Someone expressed appreciation for my being an international bumblebee, cross-pollinating ideas from far away.
Next month, back in the States, I’ll complete the international-Open-Space-bumblebee round trip at the
<a href="https://agilecoachcampus.com">10th anniversary Agile Coach Camp in Ann Arbor</a>.</p>
Coding Tour Stop #3: Canon Medical Researchhttps://schmonz.com/2018/08/17/coding-tour-stop-3-canon-medical-research/Amitai Schleier2023-06-07T17:34:43Z2018-08-17T16:46:40Z
<p><em>[Update:
Barney wrote a few words about our week together.
<a href="https://latentagility.com/testimonial/barney/">They’re quite nice</a>.]</em></p>
<p><img src="https://schmonz.com/2018/08/17/IMG_5088.JPG" width="480" height="640" alt="Water of Leith" title="Water of Leith" class="img" /></p>
<p>This week, the Octoberth of August, was my first ever visit to Edinburgh.
It was also the first of my tour stops to be scheduled.
I’d met
<a href="https://twitter.com/branaby">Barney Dellar</a>
a few months ago at the
<a href="https://schmonz.com/2018/04/20/mob-programming-and-scna-2018/">Mob Programming Conference</a>.
When I
<a href="https://schmonz.com/2018/04/23/coding-tour/">announced my coding tour</a>,
and he realized the best week for his team would be during the height of the
<a href="https://www.edfringe.com">Edinburgh Festival Fringe</a>,
he moved quickly and decisively to book my lodging and travel.
I was grateful to know well in advance that I’d get to visit at least one company —
<a href="https://research.eu.medical.canon">Canon Medical Research Europe</a>
— and that as such my tour would, in fact, exist.</p>
<h2>Monday</h2>
<ul>
<li>Joined a
<a href="https://agilein3minut.es/32">mob</a>
(2.5-minute rotations!)!</li>
<li>My worst-facilitated
<a href="https://schmonz.com/2015/02/25/the-when-to-stop-kata/">Gilded Rose</a>
ever: OS+keyboard mismatch, AND language (C++ version wouldn’t build in IDE beforehand, so… Java)</li>
<li>Took in
<a href="https://www.meetup.com/cppedinburgh/events/krmpqmyxlbrb/">Barney’s talk at C++ Edinburgh</a></li>
<li>Ate irresponsibly</li>
<li>Walked lots</li>
</ul>
<p><img src="https://schmonz.com/2018/08/17/IMG_5094.JPG" width="480" height="640" alt="On the way back from Barney's talk" title="On the way back from Barney's talk" class="img" /></p>
<h2>Tuesday</h2>
<ul>
<li>More
<a href="http://barneydellar.blogspot.com/2018/05/mobodoro.html">mobodoros</a></li>
<li>Monthly
<a href="http://barneydellar.blogspot.com/2018/06/mob-walking.html">mob walk</a>,
where more reflections came to fore</li>
<li>Learning Hour: proper Gilded Rose in C++ (with the needed
<a href="https://github.com/emilybache/GildedRose-Refactoring-Kata/pull/91">build fix</a>)</li>
<li>Helped find agreement to try
<a href="https://leankit.com/learn/kanban/benefits-of-wip-limits/">WIP limits</a></li>
<li>Evening meetup: presented
<a href="https://schmonz.com/2018/08/14/lean-agile-edinburgh-august-2018-programming-for-nonprogrammers/">Programming For Non-Programmers at Lean Agile Edinburgh</a></li>
</ul>
<p><img src="https://schmonz.com/2018/08/17/IMG_5098.JPG" width="480" height="360" alt="Learning Hour: Gilded Rose kata" title="Learning Hour: Gilded Rose kata" class="img" /></p>
<h2>Wednesday</h2>
<ul>
<li>A static analysis tool inspired by
<a href="https://codescene.io">Adam Tornhill’s</a></li>
<li>”Running Effective Meetings”</li>
<li>Walked through park to lunch with Barney</li>
<li>New mob!
<a href="https://agilein3minut.es/29">Refactoring</a>
a mess, narrowed scope, made progress</li>
<li>Down to Newcastle for the evening to present
<a href="https://schmonz.com/2018/08/15/nebytes-newcastle-august-2018-strangle-your-legacy-code/">Strangle Your Legacy Code at NEBytes</a></li>
</ul>
<h2>Thursday</h2>
<p><img src="https://schmonz.com/2018/08/17/IMG_5104.JPG" width="480" height="360" alt="Learning Hour: Intro to TDD" title="Learning Hour: Intro to TDD" class="img" /></p>
<ul>
<li>Paired with junior developer (with extremely Scottish name)</li>
<li>Test-Driven Development intro: 3 slicing options, then Roman numerals</li>
<li>River walk with tech lead concerned with how new hires learn</li>
<li>Dependency setup hell</li>
<li>Nap and dinner chez Barney, beach walk and 🍻</li>
</ul>
<h2>Friday</h2>
<ul>
<li>Mob 2 refactoring in smaller steps — 3 commits in an hour!</li>
<li>Use whiteboard to write observations down and stay focused</li>
<li>Learning Hour: “Strangle Your Legacy Code”</li>
<li>Tech lead’s exercise: practice code design skills</li>
<li>Review the week</li>
</ul>
<p>Here are
<a href="https://twitter.com/search?q=%23CodingTour%20since%3A2018-08-12%20until%3A2018-08-17&src=typd&f=live&vertical=default">all #CodingTour tweets from the week</a>.</p>
<h2>Reflections</h2>
<p>After my visit here, which needed to be planned well in advance, I’m also appreciating the corresponding just-in-time planning that made sense during the week.
Rather than choosing all five Learning Hours up front, each morning we selected what sounded best to us that day.</p>
<p>Another useful contrast with my previous tour stops: this week I programmed with a total of two teams.
Mostly with Barney’s team, and also twice with another that’s newer to mobbing.
I found it easy and comfortable to get to spend more time with fewer people, to get to know each other better, and to accumulate more solved problems together.
If I were staying longer, I’d really start to feel part of the team.</p>
<p>Neither team followed a strict
<a href="http://mobprogramming.org/mob-programming-basics/">Driver-Navigator rule</a>,
and in neither case did it seem important to ask about it or otherwise draw attention to it, because there was never much crosstalk or persistent disagreement about where to navigate.
Barney’s team rotated especially smoothly and frequently (every 150 seconds!), pausing after each Mobodoro to retrospect and take a short break.
I’m a fan of extremely short, on-the-spot retros whenever we notice something.
Now that I’ve seen Mobodoros up close, I’ll likely adopt this practice as well.</p>
<p>A bunch of us got together Friday afternoon to share some of our highlights from the week.
Have a look.</p>
<div class="video-container">
<iframe src="https://www.youtube-nocookie.com/embed/hgm4myAiNUE" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
NEBytes Newcastle August 2018: Strangle Your Legacy Codehttps://schmonz.com/2018/08/15/nebytes-newcastle-august-2018-strangle-your-legacy-code/Amitai Schleier2018-08-17T16:55:25Z2018-08-15T21:10:00Z
<p>On Wednesday, August 15 in Newcastle, England, I attended
<a href="http://www.nebytes.net">NEBytes</a>
and presented
<a href="https://www.eventbrite.co.uk/e/nebytes-15th-august-strangle-your-legacy-code-tickets-48896445585">Strangle Your Legacy Code</a>.
As a
<a href="https://agilein3minut.es/32">mob</a>,
we added features to an old SMTP server without modifying its code.</p>
<ul>
<li><a href="https://schmonz.com/2018/08/15/nebytes-newcastle-august-2018-strangle-your-legacy-code/slides/">Slides</a></li>
</ul>
<p><a href="https://twitter.com/deejaygraham">Derek Graham</a>
(who kindly invited me and orchestrated my appearance)
also has some
<a href="https://deejaygraham.github.io/2018/08/15/strangling-legacy-code/">notes and photos of the event</a>.</p>
Lean Agile Edinburgh August 2018: Programming For Non-Programmershttps://schmonz.com/2018/08/14/lean-agile-edinburgh-august-2018-programming-for-nonprogrammers/Amitai Schleier2023-12-19T15:13:11Z2018-08-14T22:32:13Z
<p>On Tuesday, August 14 in Edinburgh, I attended
<a href="https://www.meetup.com/Lean-Agile-Edinburgh/">Lean Agile Edinburgh</a>
and presented
<a href="https://www.meetup.com/Lean-Agile-Edinburgh/events/mwvrppyxlbcc/">Programming for Non-Programmers</a>.
As a
<a href="https://agilein3minut.es/32">mob</a>,
we did
<a href="https://web.archive.org/web/20230321132408/https://agileoutloud.wordpress.com/2018/05/11/tdd-by-storywriting/">TDD For Non-Programmers</a> (not a coding exercise!)
followed by programming
<a href="https://en.wikipedia.org/wiki/Fizz%20buzz">FizzBuzz</a>
in Python at
<a href="http://cyber-dojo.org">Cyber-Dojo</a>.</p>
<p>The event was livestreamed. Here’s the recording, skipping ahead to where the audio got good:</p>
<div class="video-container">
<iframe src="https://www.youtube-nocookie.com/embed/Zci84UIbARo" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
<!--
<iframe width="560" height="315" src="https://www.youtube.com/embed/nP7MbEy2Oqo?rel=0&start=1644" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
-->
<ul>
<li><a href="https://schmonz.com/2018/08/14/lean-agile-edinburgh-august-2018-programming-for-nonprogrammers/slides/">Slides</a></li>
</ul>
Legacy Code Lessons: pymsgauthhttps://schmonz.com/2018/08/07/legacy-code-lessons-pymsgauth/Amitai Schleier2023-04-22T11:55:21Z2018-08-07T15:22:02Z
<h1>What’s pymsgauth?</h1>
<p>Posting to a mailing list is usually, but not always, as simple as sending an email.
I’m on a few lists where
<a href="https://jdebp.uk/FGA/djb-qsecretary.html">an automated “secretary” responds to each post, requiring me to reply</a>
before the post is allowed through.
This cuts down on both spam and ease of participation.</p>
<p>A fellow participant on these lists wrote
<a href="http://pyropus.ca/software/pymsgauth/">pymsgauth</a>
to automatically handle these mailing list confirmation notices.
With pymsgauth configured on my mail server, I can post to the list and be done.
(Opportunities for automation are one big reason
<a href="https://schmonz.com/2017/01/18/qmail-smtp-auth-tls-redux/">why I run my own mail server</a>.)</p>
<h1>Why change the code?</h1>
<p>pymsgauth was written for
<a href="https://en.wikipedia.org/wiki/History%20of%20Python">Python 1.x</a>,
was last updated by its author in 2003, and is unlikely to receive further updates.
Thanks to
<a href="http://python3porting.com/strategies.html">Python’s compatibility strategy</a>,
pymsgauth continues to run well under 2.7.
But it doesn’t run under Python 3 at all.
And
<a href="https://pythonclock.org/">2.7’s days are numbered</a>.</p>
<p>Given the option, I’d rather deal with this well before the clock runs out.
And since I recently wrote some
<a href="https://github.com/schmonz/smtp-strangler">code targeting both Python 2.7 and 3</a>,
now seemed like a good time for my brain to do the same for pymsgauth.</p>
<p>In order for it to modify the right outbound messages and respond to the right inbound ones, all my email flows through pymsgauth.
Since my email is important to me — did I mention
<a href="https://schmonz.com/2017/03/27/automation-for-mail-hosting/">going to some effort to run my own server</a>? — pymsgauth’s reliability is important to me.</p>
<p>As usual with legacy code, my goal here was to obtain the desired change in observable behavior with just enough safety, just enough changed code, and just enough learning along the way.
No more than necessary.</p>
<h1>What needed to change?</h1>
<p>Zeroth, I created a git repository and
<a href="https://github.com/schmonz/pymsgauth/tree/pymsgauth-2.1.0">tagged the last release of pymsgauth</a>.</p>
<p>First, I ran
<a href="http://python3porting.com/2to3.html">2to3</a>.
It made
<a href="https://github.com/schmonz/pymsgauth/commit/7706821c30999c448d0a494b0184ede455f933ef">many of the obvious changes</a>,
such as exception syntax, explicit calls to <code>list()</code>, and replacing <div class="highlight-python"><pre class="hl"><span class="hl kwa">if</span> mydict<span class="hl opt">.</span><span class="hl kwd">has_key</span><span class="hl opt">(</span>mykey<span class="hl opt">)</span>
</pre></div> with <div class="highlight-python"><pre class="hl"><span class="hl kwa">if</span> mykey <span class="hl kwa">in</span> mydict
</pre></div>
(It missed a few things I assumed it’d catch, as I discovered later!)</p>
<p>Then I entered the try-see-fix cycle: try the code under Python 3, see the next error, fix it.</p>
<p>The first errors came from the config file parser.
It was subclassing <code>UserDict</code>
(<a href="https://docs.python.org/2/library/userdict.html">part of Python 2’s standard library</a>)
and the <code>import UserDict</code> was failing.
I guessed this meant <code>UserDict</code> was gone in Python 3 and I’d have to learn enough about its behavior to subclass Python’s <code>dict</code> instead.
Luckily, I guessed wrong.
<code>UserDict</code> merely
<a href="https://docs.python.org/3/library/collections.html#collections.UserDict">moved</a>.
I tweaked the imports, the type instance-check syntax, and (almost all) the string method calls, and
<a href="https://github.com/schmonz/pymsgauth/commit/0ef4491296bbe78628ed3ca75447e8307fab0688">stopped getting errors from <code>ConfParser.py</code></a>.</p>
<p>The next batch of errors came from <code>pymsgauth.py</code> itself.
It was failing to <code>import rfc822</code>.
This time, unluckily, I was right:
<a href="https://docs.python.org/2/library/rfc822.html">that module</a> was gone, replaced in Python 3 by something called
<a href="https://docs.python.org/3/library/email.html#module-email"><code>email</code></a>.</p>
<h1>How to switch from <code>rfc822</code> to <code>email</code>?</h1>
<p>The interfaces were different.
Among other things, <code>rfc822</code> had a file pointer we were using to read a line at a time.
<code>email</code> doesn’t.</p>
<p>I found a
<a href="https://github.com/MarkNenadov/rfc822py3">Python 3 port of <code>rfc822</code></a>.
Maybe I could bundle it with pymsgauth, or add an external dependency.
It looked experimental, though.
Clearly better to avoid if possible.</p>
<p>So I searched for all instances of <code>rfc822.Message</code>, and all methods that were being called on them, and (under Python 2.7) wrote
<a href="https://en.wikipedia.org/wiki/Characterization%20test">tests to characterize pymsgauth’s expectations</a>.</p>
<p>Then I
<a href="https://en.wikipedia.org/wiki/Adapter%20pattern">extracted an adapter class</a>
<code>RFC822Message</code> (right there in the test file) with all the same methods, trivially delegating to <code>rfc822</code>.</p>
<p>Since <code>email</code> is already available under Python 2.7, I replaced <code>import rfc822</code> with <code>import email</code> and figured out how to
<a href="https://github.com/schmonz/pymsgauth/commit/53326de945f0a51197b1212e60d54914c0a74dd0">make the tests pass with the new delegate</a>.</p>
<p>Tests passed equally well with Python 3, modulo a few warnings (fixed).
So I
<a href="https://github.com/schmonz/pymsgauth/commit/2560a0f665fa813647f6bd3ebe1d1559558a4b40">moved my <code>RFC822Message</code> class</a>
out of the test file and into <code>pymsgauth.py</code>, where I replaced all three instances of <code>rfc822.Message</code> with <code>RFC822Message</code>.</p>
<p>Not bad.</p>
<h1>Done yet?</h1>
<p>Nope, on to the next error.
Can’t <code>import popen2</code>.
I bounced confusedly around the docs and eventually understood the one-line change to replace <code>popen2.Popen3()</code> with <code>subprocess.Popen()</code>.</p>
<p>While there, I had a false start.
Based on my recent experience developing an 8-bit-clean SMTP proxy, I thought I’d want to open streams as binary and use Python’s <code>b'this is a sequence of bytes'</code>.
But that started looking like too much learning and changing the code.
pymsgauth had always worked well enough with Unicode as it was.
I reverted to the previous behavior, in a way that worked across Python 2.7 and 3, by adding this at the top:</p>
<div class="highlight-python"><pre class="hl"><span class="hl kwa">if</span> sys<span class="hl opt">.</span>version_info<span class="hl opt">[</span><span class="hl num">0</span><span class="hl opt">] <</span> <span class="hl num">3</span><span class="hl opt">:</span>
<span class="hl kwa">import</span> codecs
sys<span class="hl opt">.</span>stdin <span class="hl opt">=</span> codecs<span class="hl opt">.</span><span class="hl kwd">getreader</span><span class="hl opt">(</span><span class="hl sng">'utf-8'</span><span class="hl opt">)(</span>sys<span class="hl opt">.</span>stdin<span class="hl opt">)</span>
</pre></div>
<p>Next: can’t <code>import sha</code>.
That one was easy.
2.7 and 3 both have <code>hashlib</code> and it has a <code>sha1()</code>.</p>
<p>Before running on my server, I manually tested 3 of the 4 programs: <code>pymsgauth-mail</code>, <code>pymsgauth-filter</code>, and <code>pymsgauth-clean</code>.
They ran under both Python 2.7 and 3, with no apparent errors, and with the observable behavior I expected.
And I sort of tested <code>pymsgauth-confirm</code>, but to be really sure, it would need to run on my real mail server and do its real work.</p>
<h1>How about now?</h1>
<p>Almost.</p>
<p>I tried announcing my new patch to one of the mailing lists that issues these confirmation notices.
The notice showed up in my inbox, for the first time in a while.
This was disconcerting, but ideal: I had failed to announce a patch that was evidently not quite working.</p>
<p>With verbose logging, I saw I’d missed converting a few static string methods to object methods.
Fixed.</p>
<p>I tried sending my announcement again and watched the logs.
<code>pymsgauth-filter</code> added the magic token to the headers, <code>pymsgauth-confirm</code> found it and auto-replied, and the only message that appeared in my inbox was the one I had sent to the mailing list.</p>
<h1>Today’s Legacy Code Lessons</h1>
<p>I could have interpreted
<a href="https://en.wikipedia.org/wiki/YAGNI">YAGNI</a>
to mean “wait until you’re having a problem”.
Maybe Python 2.7 will get a stay of execution, such that other people will have more time to consider fixing it themselves.
Or maybe, compared to the other things I need to get done, I can’t prioritize this one right now.</p>
<p>As it happens, I often have free time in the mornings, and
<a href="https://twitter.com/schmonz/status/1025075087911936000">mitigating a risk is my favorite use of slack time</a>.</p>
<p>If my goal had been zero change in observable behavior, then the way I accomplished it was terribly wasteful.
I could have changed zero code.
My goal was zero change to observable behavior <em>later</em>, despite a known source of impending change.
(Or to start making other plans well in advance, if my goal had proved prohibitively expensive.)</p>
<p>The Adapter pattern isolates dependencies.
I use it pretty eagerly whenever I
<a href="https://schmonz.com/2017/03/08/how-to-manage-dependencies/">take on a new dependency</a>.
It’s also extremely useful for minimizing the impact of replacing an existing one.</p>
<p>Developing a class directly in the test file comes from
<a href="https://cumulative-hypotheses.org/2011/08/30/tdd-as-if-you-meant-it/">TDD As If You Meant It</a>,
where we wait for application code to really need our new class before making it available in its own file.
This wasn’t TDD — I wasn’t seeking design feedback, one test at a time — but I knew what I wanted our application to need from our new class.
Flipping from file to file would have slowed me down.
So I avoided it.</p>
<p>In the end:</p>
<ul>
<li>I didn’t have to understand much of pymsgauth’s code</li>
<li>I didn’t have to change much of it, either</li>
<li>I got fairly safely and cheaply where I needed to go</li>
</ul>
<p>Here’s
<a href="https://schmonz.com/software/pymsgauthfilter/">my patch to pymsgauth</a>.</p>
<p>Until next time, I hereby declare Legacy Code Success!</p>
Coding Tour Stop #2: BREDEXhttps://schmonz.com/2018/07/20/coding-tour-stop-2-bredex/Amitai Schleier2023-06-07T17:34:43Z2018-07-20T14:13:10Z
<p><em>[Update:
Alex wrote a few words about our week together.
<a href="https://latentagility.com/testimonial/alex/">They’re quite nice</a>.]</em></p>
<p>After a week visiting
<a href="https://www.bredex.de">BREDEX</a>
in Braunschweig, I’m struck by just how many teams I got to meet — nearly all of whom I was lucky enough to introduce to
<a href="https://agilein3minut.es/32">mob programming</a>.
<a href="https://twitter.com/alex_schl">Alex Schladebeck</a>
had prepared everyone to try it, scheduled 3 teams per day into 2-hour timeslots, and pre-selected several of the week’s Learning Hours.
Pretty much all I had to do was hang out in the big meeting space, keep an eye on the schedule, and facilitate.
When
<a href="https://twitter.com/schmonz/status/1021626721739710464">Learning Hour</a>
ended, some folks would take me to lunch.</p>
<p><img src="https://schmonz.com/2018/07/20/IMG_4807.jpg" width="480" height="360" alt="First mob on Monday morning" title="First mob on Monday morning" class="img" /></p>
<h2>Monday</h2>
<ul>
<li>3 teams new to Mob Programming (4-minute rotations)</li>
<li>Non-programmers in each mob</li>
<li>3 GUIs: 2 ~directly from SQL, one with more Java thinking</li>
<li>”Care and Feeding of T-Shaped People”</li>
<li>True fact: “Thought it’d take 2 days”, nearly done in 2 hours</li>
</ul>
<h2>Tuesday</h2>
<ul>
<li>Python, Strangler, etc. w/Alex</li>
<li>”Gilded Rose” (big group)</li>
<li>Team’s first mob session is also their first Test-Driven Development</li>
<li>Team builds a feature iteratively: first client UI, then message bus, then server, then database</li>
<li>More non-coders trying Driver role</li>
</ul>
<p><img src="https://schmonz.com/2018/07/20/IMG_4817.jpg" width="480" height="360" alt="Learning Hour: Gilded Rose kata" title="Learning Hour: Gilded Rose kata" class="img" /></p>
<h2>Wednesday</h2>
<ul>
<li>Team (new mob) brought egg timer! Idea: don’t splain me the feature, just start. I got it. My egg timer skills, tho</li>
<li>”Intro to TDD” (Roman Numerals)</li>
<li>Team (new mob) ran into sticky design choice. Externalized our concerns as words on whiteboard</li>
</ul>
<h2>Thursday</h2>
<ul>
<li>Arrived late, team already mobbing (💪)</li>
<li>Got navigated in German, did OK despite tricky Denglisch identifiers</li>
<li>”Mob Programming for Non-Programmers”</li>
<li>Flaky test failed alone, passed from suite. Binary-searched for the dependency. Got fast test working.</li>
</ul>
<h2>Friday</h2>
<ul>
<li>7am gym w/Alex</li>
<li>Finished UI ding from Day 1</li>
<li>Got navigated auf Deutsch, ganz gut gemacht</li>
<li>”Bring Your Whole Self To Work”</li>
<li>Useful feedback on “Mob Programming for Non-Programmers”</li>
<li>Fixed <a href="http://www.eclipse.org/jubula/">Jubula</a> bug</li>
<li>Heimwärts!</li>
</ul>
<p>Here are
<a href="https://twitter.com/search?q=%23CodingTour%20since%3A2018-07-15%20until%3A2018-07-20&src=typd&f=live&vertical=default">all #CodingTour tweets from the week</a>.</p>
<h2>Reflections</h2>
<p>After last week’s remarkable mix of technologies, it was relaxing in a way to have a week where some teams used Eclipse, others used IntelliJ, and the public meetup I attended was the
<a href="https://www.jug-ostfalen.de">local Java User Group</a>.
After
<a href="https://schmonz.com/2018/07/19/jug-ostfalen-braunschweig-july-2018-when-to-stop-kata/">my presentation there</a>,
several of us entered into a lively and worthwhile discussion about diversity in our field, including arguments for and against Codes of Conduct.
This is the first time my habit of
<a href="https://schmonz.com/2017/05/24/codes-of-conduct-in-3-minutes/">always asking about a CoC when I speak</a>
led to some conversation (at least one with me included).
I’m happy for this result and hopeful I can get it to happen again.</p>
<p>Doing so much mobbing with so many teams reminded me of the
<a href="https://twitter.com/schmonz/status/1020327573438517249">importance of having a flipchart or whiteboard</a>:</p>
<blockquote><p>”We notice things as we go. Simply writing them down, where everyone
can see, frees us to finish one idea at a time.”</p></blockquote>
<p>Alex (Head of Testconsulting) and Zeb (developer) joined me to share some of our highlights from the week.
Have a look.</p>
<div class="video-container">
<iframe src="https://www.youtube-nocookie.com/embed/cA26ggHVQq8" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
JUG Ostfalen Braunschweig July 2018: The When-To-Stop Katahttps://schmonz.com/2018/07/19/jug-ostfalen-braunschweig-july-2018-when-to-stop-kata/Amitai Schleier2018-07-19T19:36:56Z2018-07-19T19:35:44Z
<p>On Thursday, July 19 in Braunschweig, I attended
<a href="https://www.jug-ostfalen.de">Java User Group Ostfalen</a>
and
<a href="https://www.jug-ostfalen.de/event/2018/07/19/bessere-praesentationen.html">presented “The When-To-Stop Kata”</a>.
As a
<a href="https://agilein3minut.es/32">mob</a>,
we played the
<a href="https://github.com/wouterla/GildedRose">Gilded Rose kata</a>,
where the goal is to practice working safely and quickly in legacy code.</p>
<ul>
<li><a href="https://schmonz.com/2018/07/19/jug-ostfalen-braunschweig-july-2018-when-to-stop-kata/slides/">Slides</a></li>
</ul>
Coding Tour Stop #1: MATHEMA/Redheadshttps://schmonz.com/2018/07/13/coding-tour-stop-1-mathema-redheads/Amitai Schleier2023-06-07T17:34:43Z2018-07-13T19:20:13Z
<p><em>[Update:
Patrick wrote a few words about our week together.
<a href="https://latentagility.com/testimonial/patrick/">They’re quite nice</a>.]</em></p>
<p>I’m on the train back from Erlangen, where I spent the week joining forces with
<a href="https://www.mathema.de">MATHEMA</a>
and
<a href="https://www.redheads.de">Redheads</a>.
<a href="https://twitter.com/drechsler">Patrick Drechsler</a>
organized the visit to maximize my opportunities to get and give something of value.
Each day, inspired by the
<a href="https://www.praqma.com/stories/agile-coaching/">format I learned from pair-coaching with Llewellyn Falco</a>,
I:</p>
<ul>
<li>Visited two or three teams, joining them in their work and occasionally making myself useful</li>
<li>Ran a “learning hour”</li>
<li>Had lunch with whoever could join us</li>
</ul>
<p>Patrick also arranged for an activity each evening (except tonight, where the activity is getting home to my family).</p>
<h2>Monday</h2>
<ul>
<li>Embedded-sys boot loader (C)</li>
<li>Web app performance tuning (C# w/<a href="https://en.wikipedia.org/wiki/Entity%20Framework">Entity Framework</a>)</li>
<li>Joined an <a href="https://www.isaqb.org">ISAQB</a> (architecture cert exam) study group</li>
<li>Drank unglaublich quantities of coffee</li>
</ul>
<h2>Tuesday</h2>
<ul>
<li>Bootloader writes memory!</li>
<li>Met <a href="http://dunkels.com/adam/pt/">protothreads</a></li>
<li>Started a “new to me” list</li>
<li>Introduced <a href="http://leancoffee.org">Lean Coffee</a></li>
<li>Talked C#-and-C++ driver design (next: write examples in NUnit!)</li>
<li>Walked around Erlangen, ate <a href="https://en.wikipedia.org/wiki/Sch%C3%A4uferla">Schäuferla</a>, drank <a href="https://en.wikipedia.org/wiki/Weizen">Weizen</a></li>
</ul>
<h2>Wednesday</h2>
<p><a href="https://twitter.com/drechsler/status/1017008035716304896"><img src="https://schmonz.com/2018/07/13/gildedrose.jpg" width="480" height="360" alt="Mobbing on Gilded Rose" title="Mobbing on Gilded Rose" class="img" /></a></p>
<ul>
<li>Fascinating results giving mob a head start on <a href="https://github.com/emilybache/GildedRose-Refactoring-Kata">Gilded Rose</a> with <a href="http://approvaltests.com">Approval Tests</a></li>
<li>Intro to TDD with MSUnit, designing an API and debugging serial comms to pass</li>
<li>Walked around Nürnberg, ate <a href="https://en.wikipedia.org/wiki/Schweinebraten">Schweinebraten</a>, watched <a href="http://www.espn.com/soccer/match?gameId=498141">Hrvatska</a></li>
<li>”Bassd scho” (~= “passt schon”, the highest compliment <a href="https://en.wikipedia.org/wiki/Franconia">Franconians</a> can bring themselves to give)</li>
</ul>
<p><a href="https://twitter.com/timothep">Tim Bourguignon</a>,
MATHEMA’s Chief Learning Officer, was able to join us on Wednesday.
Was great to get more time with him after a very enjoyable few days in
London last week.
We wound up challenging each other to take one of our experiences and make a thing.
Maybe my experience on this tour will turn into a thing of some sort.</p>
<h2>Thursday</h2>
<ul>
<li>C#: test fixture needs tons of params, feel the pain</li>
<li>Python: non-programmers solved <a href="https://en.wikipedia.org/wiki/fizz%20buzz">FizzBuzz</a>!</li>
<li>C#: test-first the next serial-port write and read</li>
<li>Evening meetup (where I presented):
<a href="https://schmonz.com/2018/07/12/hackerkegeln-nuernberg-july-2018-strangle-your-legacy-code/">Hackerkegeln</a></li>
</ul>
<h2>Friday</h2>
<ul>
<li>Fixed 2 paths in 4.5G SQL with iconv&sed</li>
<li>Played Strangle Your Legacy Code (won all 4 features)!</li>
<li>Tracked serial protocol bug to differing <code>sizeof(double)</code> on host and target</li>
<li>Recorded a brief video about the week</li>
<li>Boarded train</li>
</ul>
<p>Here are
<a href="https://twitter.com/search?q=%23CodingTour%20since%3A2018-07-08%20until%3A2018-07-13&src=typed_query&f=live">all #CodingTour tweets from the week</a>.</p>
<h2>Reflections</h2>
<p>I got to work with a wide variety of new-to-me technologies.
Any one of them would have made for a sufficiently interesting week.
I feel lucky to have encountered this variety so early: it prompted me to start keeping a list.
I expect it’ll be quite long when I share it at the end of the tour.</p>
<p><a href="https://twitter.com/thbrunzendorf/status/1017498177992384513"><img src="https://schmonz.com/2018/07/13/hackerkegeln.jpg" width="480" height="360" alt="At Hackerkegeln" title="At Hackerkegeln" class="img" /></a></p>
<p>I got to meet a lively, active
<a href="https://www.softwerkskammer.org">Softwerkskammer</a>
community in Nürnberg, including the host for my final tour stop the last week of August.</p>
<p>In MATHEMA and Redheads I perceived a
<a href="https://www.infoq.com/news/2010/07/oath-of-nonallegiance">non-doctrinaire practicality</a>
which I appreciated very much.
At least one person made a point to offer appreciation for my doing the same while facilitating our Gilded Rose mob.
Done poorly, Gilded Rose is no more than any other kata about refactoring.
Done well, it’s a
<a href="https://schmonz.com/2015/02/25/the-when-to-stop-kata/">kata about prioritizing</a>:
we buy safety as cheaply as possible, gain understanding as quickly as possible, and deliver the feature as soon as possible.
MATHEMA and Redheads did it well and creatively, with an expedient solution I’d never seen before.</p>
<p>Thomas (Chief Technical Officer) and Khaled (developer) joined me to share some of our highlights from the week.
Have a look.</p>
<div class="video-container">
<iframe src="https://www.youtube-nocookie.com/embed/-xvzOJKgo04" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
Hackerkegeln Nürnberg July 2018: Strangle Your Legacy Codehttps://schmonz.com/2018/07/12/hackerkegeln-nuernberg-july-2018-strangle-your-legacy-code/Amitai Schleier2018-08-15T17:35:49Z2018-07-12T17:09:20Z
<p>On Thursday, July 12 in Nürnberg I attended
<a href="http://www.hackerkegeln.de/">Hackerkegeln</a>
and presented “Strangle Your Legacy Code”.
As a
<a href="https://agilein3minut.es/32">mob</a>,
we added features to an old SMTP server without modifying its code.
Great to meet this active, lively
<a href="https://www.softwerkskammer.org">Softwerkskammer</a>
community.</p>
<ul>
<li><a href="https://schmonz.com/2018/07/12/hackerkegeln-nuernberg-july-2018-strangle-your-legacy-code/slides/">Slides</a></li>
</ul>
pkgsrcCon 2018: Maintaining qmail in 2018https://schmonz.com/2018/07/07/pkgsrccon-2018-maintaining-qmail-in-2018/Amitai Schleier2023-04-21T21:04:25Z2018-07-07T12:17:00Z
<p><a href="http://pkgsrc.org/pkgsrcCon/2018/">pkgsrcCon</a>
is an annual conference about the challenges of cross-platform open-source package management, focusing on the development and usability of
<a href="http://pkgsrc.org">pkgsrc</a>.
I’ve gone to something like half the pkgsrcCons since its inception in 2004, even though they’re always in Europe and I’m usually not.
Conveniently, this summer I’m mostly in Germany and pkgsrcCon was entirely in Berlin.
Just a train ride away.</p>
<p>I had to cut my attendance very short, so I’m glad I got to see some familiar and new-to-me faces, eager to see the remaining talks when the videos are published, and pleased to have been able to share the continuing story of my long-running and perhaps misplaced
<a href="https://schmonz.com/2017/03/27/automation-for-mail-hosting/">efforts to improve our packaging</a>
of
<a href="https://schmonz.com/software/">qmail</a>.</p>
<ul>
<li><a href="https://schmonz.com/2018/07/07/pkgsrccon-2018-maintaining-qmail-in-2018/slides/">Slides</a></li>
<li><a href="https://video.wiedi.hk/pkgsrcCon-2018/pkgsrcCon-2018-05-schmonz-qmail.mp4">Video</a></li>
</ul>
Coding Tour Stop #0: UK Government Digital Servicehttps://schmonz.com/2018/07/05/coding-tour-stop-0-uk-government-digital-service/Amitai Schleier2018-07-06T10:48:34Z2018-07-05T15:11:51Z
<p>My
<a href="https://schmonz.com/2018/04/23/coding-tour/">coding tour</a> has officially begun!
Not at the first stop — that’s next week — but at the zeroth.
By happy happenstance,
<a href="https://twitter.com/OlafLewitz">Olaf Lewitz</a>
heard I had a spare
<a href="https://schmonz.com/2018/07/04/spa-software-in-practice-2018/">post-SPA</a>
day in London and connected me to
<a href="https://twitter.com/dgheath21">David Heath</a>
at the United Kingdom’s
<a href="https://www.gov.uk/government/organisations/government-digital-service">Government Digital Service</a>.</p>
<p><img src="https://schmonz.com/2018/07/05/leancoffee.jpg" width="500" height="375" alt="Lean Coffee" title="Lean Coffee" class="img" /></p>
<p>After meeting David for a morning coffee to get to know each other and plan the day, and meeting the team at standup, all of us decamped to a
<a href="https://agilein3minut.es/32">mob-programming</a>-friendly
meeting room for a
<a href="http://leancoffee.org">Lean Coffee</a>.
Some topics we covered (with me in particular noisily moving my mouth around a lot):</p>
<ul>
<li>TDD: theory vs. practice</li>
<li><a href="https://agilein3minut.es/9">Pair programming</a>: how to do it best</li>
<li>How much up-front design to do in a new project</li>
<li>How to test an async module in a synchronous one</li>
</ul>
<p><img src="https://schmonz.com/2018/07/05/IMG_4690.jpg" width="500" height="375" alt="Refactoring as a mob" title="Refactoring as a mob" class="img" /></p>
<p>With the 45 minutes before lunch, we decided to tackle a desired refactoring (string primitive to value object) as a mob — their first time mob programming.
The team really took to it: drivers doing well listening to navigators, navigators doing well making their intentions understood by drivers, and new team members doing well in new code with new people.
I helped by running the timer, asking a clarifying question here or there, gently admonishing the driver when it looked like they were expressing an original thought, and writing down things we noticed along the way but didn’t want to act on just yet.</p>
<p>After lunch, David facilitated an introduction to
<a href="http://www.liberatingstructures.com">Liberating Structures</a>
for a regular meeting of an internal GDS community group.
I’d heard of these from my SPA co-presenter
<a href="https://twitter.com/timothep">Tim Bourguignon</a>
but hadn’t made their direct experiential acquaintance.
David had us play out exercises with
<a href="http://www.liberatingstructures.com/6-making-space-with-triz/">Triz</a>
and
<a href="http://www.liberatingstructures.com/8-troika-consulting/">Troika Consulting</a>
and reflect briefly on when we might like to use them.
Between the exercises and David’s take-home gift of a deck of facilitation cards,
this may be how I finally learn and apply Liberating Structures!
(Coaches <em>love</em> facilitation cards.
This was a great gift.)</p>
<p><img src="https://schmonz.com/2018/07/05/mobbing2.jpg" width="500" height="375" alt="Mobbing again" title="Mobbing again" class="img" /></p>
<p>The team then reconvened as a mob to continue the
<a href="https://github.com/alphagov/pay-direct-debit-connector/compare/PP-3942_introduce_external_id_object">refactoring in progress</a>.
I had to leave for the airport 45 minutes in, so we said our goodbyes.
I suspect (and hope) they carried on mobbing.
I’ll be curious to hear how and when they decide to use the technique from now on.</p>
<p>It was only a day with David and team at Government Digital Service, a short one at that, and sweet.
We didn’t even have time to reflect together on how it went.
Speaking for myself, then, it was a perfectly serendipitous start to my tour.
I’m eager to see what changes when I stay with a company all week — and am about to find out.</p>
<p><img src="https://schmonz.com/2018/07/05/goodbye.jpg" width="500" height="375" alt="Just before leaving" title="Just before leaving" class="img" /></p>
SPA Software in Practice 2018https://schmonz.com/2018/07/04/spa-software-in-practice-2018/Amitai Schleier2018-07-11T22:39:05Z2018-07-04T11:01:56Z
<p>At
<a href="https://spaconference.org">SPA Software in Practice</a>
in London,
I joined
<a href="http://www.timbourguignon.fr">Tim Bourguignon</a>
yesterday for
“How Would YOU Call This Workshop?”
(<a href="https://spaconference.org/spa2018/sessions/session782.html">abstract</a>,
<a href="https://speakerdeck.com/timothep/what-would-you-call-this-talk-and-other-powerful-questions">slides</a>).</p>
<table class="img"><caption>
<ul>
<li>Open -> Time consuming</li>
<ul>
<li>waffle on</li>
</ul>
<li>Close to enable</li>
<ul>
<li>to confirm</li>
<li>limits spectrum</li>
<li>leading</li>
</ul>
<li>Open to explore</li>
<li>Closed-open to lead</li>
<li>Open as inclusion mechanism</li>
<li>Open -> new ideas</li>
</ul></caption><tr><td><a href="https://schmonz.com/2018/07/04/IMG_4669.jpg"><img src="https://schmonz.com/2018/07/04/spa-software-in-practice-2018/225x300-IMG_4669.jpg" width="225" height="300" alt="Question Formulation Technique" title="Question Formulation Technique" class="img" /></a></td></tr></table>
<table class="img"><caption><ul>
<li>Other contexts as well</li>
<li>inquirer controls at the beginning</li>
<li>Open-closed || Closed-open</li>
<li>check with closed, why then…</li>
<li>Beware of closed questions (Bias)</li>
<li>Beware to check a common vocabulary</li>
</ul></caption><tr><td><a href="https://schmonz.com/2018/07/04/IMG_4670.jpg"><img src="https://schmonz.com/2018/07/04/spa-software-in-practice-2018/225x300-IMG_4670.jpg" width="225" height="300" alt="Architecture Investigation Exercise" title="Architecture Investigation Exercise" class="img" /></a></td></tr></table>
<p>Today, he joined me for
“Strangle Your Legacy Code”
(<a href="https://spaconference.org/spa2018/sessions/session819.html">abstract</a>,
<a href="https://schmonz.com/2018/07/04/spa-software-in-practice-2018/slides/">slides</a>),
where we added features to an old SMTP server without modifying its code.</p>
<p><a href="https://schmonz.com/2018/07/04/DhQ8iZTX4AQhxgB.jpg"><img src="https://schmonz.com/2018/07/04/DhQ8iZTX4AQhxgB.jpg" width="500" height="255" alt="Strangle Your Legacy Code" title="Strangle Your Legacy Code" class="img" /></a></p>
<p>SPA was small, participatory, conversational, practical.
And the
<a href="https://spaconference.org/spa2018/social.html">Unbelievable Knuth</a>
game show
(<a href="https://twitter.com/KaraMarck/status/1014248524614197250">photo</a>)
with
<a href="https://twitter.com/johnsnolan">John Nolan</a>,
<a href="https://twitter.com/rachelcdavies">Rachel Davies</a>,
<a href="https://twitter.com/duncanmcg">Duncan McGregor</a>,
and
<a href="https://twitter.com/natpryce">Nat Pryce</a>
was made from equal parts expertise and whimsy.
I’ve had a lovely time. And my
<a href="https://schmonz.com/2018/04/23/coding-tour/">coding tour</a> is finally at hand!
Tomorrow’s the first (miniature) stop: a one-day visit to the UK’s
<a href="https://www.gov.uk/government/organisations/government-digital-service">Government Digital Service</a>.</p>
Agile Coach Camp Germany 2018https://schmonz.com/2018/06/24/agile-coach-camp-germany-2018/Amitai Schleier2023-12-19T15:13:11Z2018-06-24T19:22:16Z
<p>On arriving at
<a href="http://agilecoachcamp.de">Agile Coach Camp Germany</a>
in Rückersbach (about an hour outside Frankfurt)
I could already feel a difference from
<a href="https://schmonz.com/2016/10/16/agile-coach-camp/">my experiences</a>
of
<a href="https://schmonz.com/2017/04/29/agile-coach-camp-2017/">US Coach Camps</a>.
Instead of a city center, we were atop a hill overlooking a village.
Instead of streaming in each morning from various hotels, we were staying on-site.
Instead of a company’s office or a meeting space, we were at a
<a href="https://www.natuerlich-tagen.de">dedicated venue</a>.</p>
<p>We were simply together — including meals, late-night gaming and other activities, and for many of us, double rooms.
This gave the weekend a consistently higher level of intensity, which was easy to tune to my liking by going for a walk in the woods, throwing a disc with a fellow Ultimate enthusiast, or sitting down with some code.
And it consistently afforded opportunities for serendipitous conversations until at least 3am. In short, the “Camp” part of the name suddenly makes way more sense to me.</p>
<p><img src="https://schmonz.com/2018/06/24/IMG_4577.jpg" width="480" height="360" alt="In the flow of mob programming" title="In the flow of mob programming" class="img" /></p>
<p>I offered my now customary two sessions:</p>
<ol>
<li><a href="https://web.archive.org/web/20230321132408/https://agileoutloud.wordpress.com/2018/05/11/tdd-by-storywriting">Test-Driven Development for Non-Programmers</a></li>
<li><a href="https://schmonz.com/talk/20170519-agileuprising-tdd-mob/">Mob Programming for Non-Programmers</a></li>
</ol>
<p>And also my customary anti-session:</p>
<ul>
<li>Interrupt me anytime (except in the bathroom) for 15 minutes’ chat about any Agile technical practice: try it with me, watch me do it, ask about a situation…</li>
</ul>
<p><img src="https://schmonz.com/2018/06/24/IMG_4645.jpg" width="240" height="320" alt="Positive feedback (in both senses)" title="Positive feedback (in both senses)" class="img" align="right" /></p>
<p>I continue to offer these because I believe that the most significant influence a coach can have comes through modeling behaviors, and the most important team behavior a coach can model is utter openness to joining others in their work. Coaches who
<a href="https://agilein3minut.es/35">disqualify themselves from joining in technical work</a>
are modeling behavior we’d all advise Agile teams against, while simultaneously constraining the potential depth of their connection to the people who do that work.</p>
<p>Coaching is hard enough without these extra challenges!
I offer these sessions in the hope that more of us feel more comfortable opening more of ourselves to more of the folks we serve.
I’m grateful to receive feedback suggesting it’s effective.
So I’ll keep doing it every chance I get.
The next Coach Camp for me will be
<a href="https://agilecoachcampus.com">Ann Arbor in September</a>.</p>
<p>Speaking of creating joyful shared programming experiences, the first stop on my
<a href="https://schmonz.com/2018/04/23/coding-tour/">summer coding tour</a>
is in just two weeks.
Can’t wait to start sharing what I learn.
Stay tuned!</p>
Mallorca Software Craft June 2018: Vending Machine Katahttps://schmonz.com/2018/06/14/mallorca-software-craft-june-2018-vending-machine-kata/Amitai Schleier2023-06-07T17:34:43Z2018-06-15T05:13:24Z
<p>At the
<a href="https://www.meetup.com/Mallorca-Software-Craftsmanship/events/251514368/">Mallorca Software Craft meetup</a>
last night, 20 people played at
<a href="https://twitter.com/guyroyse">Guy Royse</a>’s
<a href="https://github.com/guyroyse/vending-machine-kata">Vending Machine Kata</a>.</p>
<h2>What we did</h2>
<p><img src="https://schmonz.com/2018/06/14/IMG_4269.jpg" width="480" height="360" alt="In the flow of mob programming" title="In the flow of mob programming" class="img" /></p>
<p>We organized as one big mob, used Python and PyCharm, and rotated every
4 minutes.</p>
<p>As a guest, I was asked to write something in this book:</p>
<p><a href="https://twitter.com/schmonz/status/1007317825436962818"><img src="https://schmonz.com/2018/06/14/000.jpg" width="480" height="680" alt="Amazing hand-made logbook by Rachel M. Carmena" title="Amazing hand-made logbook by Rachel M. Carmena" class="img" /></a></p>
<p>What I wrote:</p>
<blockquote><p>Thank you for convening a summer session, inviting me, and tolerating
my almost complete absence of Catalan or Castilian. We’re about to
start the meetup. It’s wonderful to find a community of shared values
here. I’m looking forward to the Vending Machine Kata with this group.
If it doesn’t get much bigger, maybe as one big mob!</p>
<p>Yes, that’s what we did! It was the first experience with Mob
Programming for everyone in the room. Mostly in Spanish. Still
<a href="https://twitter.com/schmonz/status/1007324035561254915">possible to facilitate decently</a>.</p></blockquote>
<p>And also this:</p>
<table class="img"><caption>Don’t think too hard. Talk your ideas out loud. Do something simple. Write another test. Work together.</caption><tr><td><img src="https://schmonz.com/2018/06/14/IMG_4272.jpg" width="480" height="640" alt="Amitai's " title="Amitai's " class="img" /></td></tr></table>
<p>Here are
<a href="https://twitter.com/search?q=%23MallorcaSC%20since%3A2018-06-14%20until%3A2018-06-15&src=typed_query&f=live">all the tweets to #MallorcaSC from the time of the event</a>.</p>
<h2>Learn more</h2>
<p>The <a href="https://schmonz.com/2018/06/14/mallorca-software-craft-june-2018-vending-machine-kata/slides/">slides</a> have our retro findings, references, and more!</p>
Big Apple Scrum Day 2018: Coaches Clinichttps://schmonz.com/2018/05/12/big-apple-scrum-day-2018-coaches-clinic/Amitai Schleier2018-05-12T14:12:29Z2018-05-12T13:01:08Z
<p>I had a great time at last year’s Big Apple Scrum Day
<a href="https://schmonz.com/2017/05/01/basd-2017-t-shaped-people/">presenting with Ryan Ripley</a>
in my
<a href="https://schmonz.com/2018/02/09/back-to-work-maybe-with-you/">home market</a>,
so it was an honor to be invited back to contribute to the 2018 BASD
proceedings in a new way: as part of the
<a href="https://www.bigapplescrumday.org/coaches-clinic">Coaches Clinic</a>,
where attendees could talk through a situation they’re facing and, in so
doing, perhaps gain some new understanding or insight.</p>
<p><a href="https://twitter.com/schmonz/status/995063465223041025"><img src="https://schmonz.com/2018/05/12/IMG_3577.jpg" width="160" height="167" alt="Like his podcast, but live!" title="Like his podcast, but live!" class="img" align="right" /></a></p>
<p>These conversations, while brief, can have profound impact. Five years ago,
<a href="https://schmonz.com/2014/02/10/my-thirty-fifth-solar-orbit/">my first visit to a Coaches Clinic</a>
transmuted my curiosity about a career option into the resolve to try it.
And
<a href="http://latentagility.com/">here we are</a>.</p>
<p>Yesterday, I don’t think I came close to doing for anyone what Roger did
for me. But I did
<a href="https://twitter.com/schmonz/status/995063465223041025">make myself useful</a>,
reasoning about the needs of the people in Matt’s situation until we
found an actionable idea.
<a href="https://twitter.com/">Gene Gendel</a>,
who organized the Clinic, is collecting
<a href="http://www.keystepstosuccess.com/2018/05/2018-big-apple-scrum-day-coaching-clinic/">experience reports from the coaches</a>.</p>
<p>Despite the prevalence of Lego in Agile coaching games and simulations,
I still hadn’t played with it much since childhood. I guess I decided to
start practicing because Taavi will be Lego-ready before we know it. I
tried to stay off the grid.</p>
<p><img src="https://schmonz.com/2018/05/12/IMG_3574.JPG" width="480" height="360" alt="Not rectangular" title="Not rectangular" class="img" /></p>
<p>It was energizing to punctuate the pace of the one-day conference by
visiting with friends — especially
<a href="https://twitter.com/joPerold">Joanne Perold</a>
and
<a href="https://twitter.com/BarryTandy">Barry Tandy</a>,
who I’d met online via
<a href="https://schmonz.com/tag/agile-for-humans/">Agile for Humans</a>,
and now in person, all the way from South Africa.
I also got a kick out of
<a href="https://twitter.com/AgileSquirrel/status/994966888856858626">rubberducking my code problem</a>
with
<a href="https://twitter.com/DocOnDev">Doc Norton</a>,
though we ran out of time to pair on it.
(Jo and Doc both keynoted.)</p>
<p><img src="https://schmonz.com/2018/05/12/Dc7VGfVU8AA0xE1.jpg" width="480" height="338" alt="Geeks at laptops" title="Geeks at laptops" class="img" /></p>
<p>I missed the Lean Coffee facilitated by
<a href="https://twitter.com/jonathansen">Jonathan Hansen</a>,
though I attend the weekly one he hosts in Chelsea as often as I can.
Jonathan also organizes the monthly
<a href="https://www.meetup.com/nyc-kanban/">NYC Lean/Kanban meetup</a>,
where I’ll be presenting in October.</p>
<p>Big Apple Scrum Day is once a year, but the
<a href="https://www.meetup.com/NYC-Scrum-User-Group/">NYC Scrum meetups</a>
are every month. I look forward to participating more when we return
from Germany.</p>
<p>Speaking of which: there are only a few slots left in my
<a href="https://schmonz.com/2018/04/23/coding-tour/">summer coding tour</a>
schedule. If you’ve been meaning to get in touch, now’s the time!</p>
Coding Tour Summer 2018https://schmonz.com/2018/04/23/coding-tour/Amitai Schleier2022-05-09T16:55:07Z2018-04-23T04:48:38Z
<div id="mapdiv-map"></div>
<h2>Planned stops</h2>
<ul>
<li><strong>London</strong> (mini-stop), July 5: <a href="https://schmonz.com/2018/07/05/coding-tour-stop-0-uk-government-digital-service/">UK Government Digital Service</a></li>
<li><strong>Erlangen</strong>, July 9-13: <a href="https://schmonz.com/2018/07/13/coding-tour-stop-1-mathema-redheads/">MATHEMA/Redheads</a></li>
<li><strong>Braunschweig</strong>, July 16-20: <a href="https://schmonz.com/2018/07/20/coding-tour-stop-2-bredex/">BREDEX</a></li>
<li><strong>Edinburgh</strong>, August 13-17: <a href="https://schmonz.com/2018/08/17/coding-tour-stop-3-canon-medical-research/">Canon Medical Research</a></li>
<li><strong>Nürnberg</strong> and <strong>München</strong>, August 27-31: <a href="https://schmonz.com/2018/08/31/coding-tour-stop-4-codecentric/">codecentric</a></li>
</ul>
<p>While in town, I’ll do my best to attend a public meetup or two.
See what’s been planned at my <a href="https://schmonz.com/speaker/">speaker</a> page.</p>
<h2>Who’s Amitai?</h2>
<p>I’m an independent software development consultant, coach, and trainer.
In nearly 20 years comprising global finance, startups, agriculture,
universities, and nonprofits, I’ve managed products, projects, and
people; engineered code, tests, and releases; deployed and operated
production systems; provided phone and desk support; and listened to,
empathized with, and improved the lot of folks in all of these roles.
(<a href="https://schmonz.com/coach/">More about me…</a>)</p>
<h2>What’s this “coding tour”?</h2>
<p>It’s when a programmer briefly visits several companies to join them in their coding work and to learn from each other.
(<a href="http://nicolerauch.de/posts/2016-08-29-craftsman-swap-and-journeyman-tour.html#journeyman-tour">More…</a>)</p>
<p>I’m on tour June through mid-September, anywhere in Germany — and anywhere else in Europe, schedule and travel costs permitting.</p>
<p>You provide room and board.
I mob and/or pair with you for a week.
We do it because we both expect to gain.
That’s the whole deal!</p>
<p><em>Unique opportunity to be in the presence of someone who will make you a better, smarter version of you. And he doesn’t charge near enough.</em>
—<a href="https://twitter.com/KentBeck/status/1004497592242208768">Kent Beck</a></p>
<h2>What’s it like to code with Amitai?</h2>
<p><em>From personal experience: you won’t find a more supportive, encouraging human with whom to explore and problem-solve.
This is an opportunity you won’t want to miss!</em>
—<a href="https://twitter.com/AgileFaye/status/989551111198605313">Faye Thompson</a></p>
<p><em>Enormous value to me.
Helps my thinking, helps my energy, helps my code.</em>
—<a href="https://twitter.com/GeePawHill/status/986679877876273152">Michael “GeePaw” Hill</a></p>
<p><em>Great. Very insightful comments.</em>
—<a href="https://twitter.com/TotherAlistair/status/517724189457805312">Alistair Cockburn</a></p>
<p><em>Love his open, interesting approach to problem-solving during coding.
I can’t even describe it.
It’s just inspiring.</em>
—<a href="https://twitter.com/aJimHolmes/status/986687684755144704">Jim Holmes</a></p>
<p><em>His focus on the “real” goals and value, and his ego-less way of working through a problem, made all of it possible.</em>
—<a href="https://www.linkedin.com/in/schmonz/">Nathan Arthur</a></p>
<h2>How can I form my own impression?</h2>
<p>Got
<a class="toggle" href="https://schmonz.com/#id2018-04-23-coding-tour.15-minutes">15 minutes</a>
or
<a class="toggle" href="https://schmonz.com/#id2018-04-23-coding-tour.an-hour">an hour</a>
to listen?
Prefer
<a class="toggle" href="https://schmonz.com/#id2018-04-23-coding-tour.prefer-reading">reading</a>?
Need to
<a class="toggle" href="https://schmonz.com/#id2018-04-23-coding-tour.see-for-yourself">see for yourself</a>?</p>
<div class="toggleable" id="id2018-04-23-coding-tour.15-minutes"></div>
<p>Listen to these episodes of <a href="https://agilein3minut.es/">Agile in 3 Minutes</a> in this order:
<a href="https://agilein3minut.es/1">Effect</a>,
<a href="https://agilein3minut.es/2">Retrospect</a>,
<a href="https://agilein3minut.es/5">Wrong</a>,
<a href="https://agilein3minut.es/8">Care</a>,
<a href="https://agilein3minut.es/26">Surprise</a>.</p>
<div class="toggleableend"></div>
<div class="toggleable" id="id2018-04-23-coding-tour.an-hour"></div>
<p>Listen to one of my
<a href="https://schmonz.com/tag/agile-for-humans/">Agile for Humans guest-host appearances</a>
(such as with
<a href="https://schmonz.com/talk/20151006-agile-for-humans/">Esther Derby and Don Gray</a>,
<a href="https://schmonz.com/talk/20160623-agile-for-humans/">Diane Zajac and Zach Bonaker</a>,
<a href="https://schmonz.com/talk/20170717-agile-for-humans/">John Cutler</a>,
<a href="https://schmonz.com/talk/20160224-agile-for-humans/">Woody Zuill</a>,
or
<a href="https://schmonz.com/talk/20160214-agile-for-humans/">Jerry Weinberg</a>.)
Or you can hear me being interviewed on
<a href="https://schmonz.com/talk/20160616-developer-on-fire/">Developer on Fire</a>
or
<a href="https://schmonz.com/talk/20160212-developers-journey/">Developer’s Journey</a>.</p>
<div class="toggleableend"></div>
<div class="toggleable" id="id2018-04-23-coding-tour.prefer-reading"></div>
<p>My
<a href="https://schmonz.com/talk/20160823-we-do-tdd/">interview responses for WeDoTDD</a>
were given on behalf of my then-employer, but remain very much <em>my</em> answers.
I still stand by them.</p>
<div class="toggleableend"></div>
<div class="toggleable" id="id2018-04-23-coding-tour.see-for-yourself"></div>
<p>My coding tour <a href="https://schmonz.com/2018/09/15/coding-tour-summer-2018-conclusion/">has concluded</a>.
I’m still happy to talk about it.</p>
<div class="toggleableend"></div>
<h2>How good is Amitai’s German?</h2>
<p><img src="https://schmonz.com/2018/04/23/coding-tour/160x165-meine_ersten_farben.jpg" width="160" height="165" alt="Meine Ersten Farben" title="Meine Ersten Farben" class="img" align="right" /></p>
<p>I
<a href="https://schmonz.com/2017/12/29/training-agile-fluency-game/">understand some</a>.
I pronounce better than I understand, understand better than I speak, and speak better than my son — for now! — to whom I’ve been reading books like this.</p>
<p>Let’s prefer English, while also not worrying too much about avoiding German.</p>
<h2>How do we invite Amitai?</h2>
<p>My coding tour
<a href="https://schmonz.com/2018/09/15/coding-tour-summer-2018-conclusion/">has concluded</a>.
I’m still happy to talk about it.</p>
<hr />
<h2><a class="toggle" href="https://schmonz.com/#id2018-04-23-coding-tour.who-else">Who else has gone on tour</a>?</h2>
<div class="toggleable" id="id2018-04-23-coding-tour.who-else"></div>
<p>Lots of programmers.
Here are just the ones I’ve gotten advice from:</p>
<ul>
<li><a href="https://twitter.com/coreyhaines">Corey Haines</a>,
2008-2009
<a href="http://blog.coreyhaines.com/2008/12/welcome.html">Pair Programming Tour</a></li>
<li><a href="https://twitter.com/nhajratw">Nayan Hajratwala</a>,
2010
<a href="http://agileshrugged.com/?p=101">Michigan Pairing Tour</a>
(<a href="http://agileshrugged.com/?cat=97">all posts</a>)</li>
<li><a href="https://twitter.com/NicoleRauch">Nicole Rauch</a>,
2014
<a href="https://devjourney.info/Guests/11-NicoleRauch.html">Journeyman Tour</a></li>
<li><a href="https://twitter.com/DevLCSC">Lennart Fridén</a>,
2015
<a href="http://codecoupled.org/2015/05/06/announcing-my-journeymanship/">Journeyman Tour</a>
(<a href="https://codecoupled.org/tag/journeyman/">all posts</a>)</li>
<li><a href="https://twitter.com/SalFreudenberg">Sal Freudenberg</a>,
2017
<a href="https://salfreudenberg.wordpress.com/2017/10/20/what-the-heck-is-a-coding-tour-anyway/">Coding Tour</a>
(<a href="https://salfreudenberg.wordpress.com/category/coding-tour/">all posts</a>)</li>
</ul>
<p>Related: as of this writing,
<a href="https://twitter.com/lisihocke">Lisi Hocke</a>
is on a
<a href="https://www.lisihocke.com/2017/12/the-pact-not-a-remake-but-a-sequel.html">testing tour</a>
(<a href="https://www.lisihocke.com/search/label/testingtour">all posts</a>).</p>
<div class="toggleableend"></div>
<h2><a class="toggle" href="https://schmonz.com/#id2018-04-23-coding-tour.thanks">Thanks</a></h2>
<div class="toggleable" id="id2018-04-23-coding-tour.thanks"></div>
<p>I owe gratitude to lots of folks for helping me design and implement this coding tour.
In particular:</p>
<ul>
<li>Sal Freudenberg for her recent UK tour, my source of inspiration to do this</li>
<li>Llewellyn Falco for ideas about the format, based on
<a href="https://schmonz.com/2018/02/09/back-to-work-maybe-with-you/">our recent pair coaching</a></li>
<li>Nicole Rauch for the majority of the encouragement, advice, and local industry contacts I’ve received</li>
</ul>
<div class="toggleableend"></div>
Mob Programming and SCNA 2018https://schmonz.com/2018/04/20/mob-programming-and-scna-2018/Amitai Schleier2018-04-20T19:36:54Z2018-04-20T18:57:23Z
<p>After two years of ruing my inability to attend the
<a href="https://www.agilegamesnewengland.com/index.php/mob-programming-conference">Mob Programming Conference</a>,
last week I finally made it.
It was simultaneously everything I hoped for and exactly what I expected: the hybrid vigor of a conference crossed with an unconference, and the generalizable learning that only comes from concrete experiences.</p>
<p>Mob programming is one of my favorite techniques.
(For more about it, listen to
<a href="https://agilein3minut.es/32">Agile in 3 Minutes #32</a>.)
I learned it with
<a href="https://twitter.com/patmaddox">Pat Maddox</a>
and
<a href="https://twitter.com/WoodyZuill">Woody Zuill</a>
in 2014, have used it frequently in my
<a href="https://latentagility.com">consulting</a>
ever since, and treasure my occasional opportunities to simply <em>be</em> in a mob.
The Mob Programming Conference’s
<a href="https://www.agilegamesnewengland.com/index.php/mob-programming-conference/mob-programming-schedule">1.5-hour sessions</a>
were designed to maximize those opportunities.
Woody likes to say mob programming is “All the brilliant minds working on the same thing at the same time on the same computer”;
at every session of Mob Programming 2018, I saw brilliant people every time I looked around the room.</p>
<div class="notebox">
<p>Turns out Lennart — my “brother from another mother”, as he put it — was able to give me some older-brother advice on my upcoming coding tour, because he
<a href="https://codecoupled.org/2015/05/06/announcing-my-journeymanship/">went on tour in 2015</a>.
Now I have a better plan.
Look for an announcement next week.</p>
</div>
<p>A week on, both of
<a href="https://twitter.com/DevLCSC">Lennart Fridén</a>’s
sessions have stayed with me.
One was about
<a href="https://www.agilegamesnewengland.com/index.php/mob-programming-conference/41-session/206-mob-exploration-and-learning">solving problems in a fictional assembly language</a>,
where nobody’s an expert and we all have to learn together.
I came in late, so I had even less information than everyone else, but within a few rotations and a few questions was able to make myself useful, and by the end had roughly the same working understanding as everyone else.
If you’ve mobbed before, you’ve likely seen and felt this convergence of shared understanding.
Lennart’s session was designed to highlight it.</p>
<p>His other session invited a few volunteers to
<a href="https://www.agilegamesnewengland.com/index.php/mob-programming-conference/41-session/204-facilitation-techniques">role-play unconstructive mobster behaviors</a>,
then opened to group discussion about how we might overcome them.
As one of the improv actors, I found it disturbingly easy to behave badly in a succession of audience-specified ways.
I may have had slightly too much fun doing it, but I think my acting supported the session’s intended learnings, and if not, Lennart’s facilitation skills made it so.
I guess if the tech coaching well ever runs dry, I can always
<a href="https://twitter.com/schmonz/status/984822558217392128">take my talents to Silicon Valley</a>:</p>
<p><img src="https://schmonz.com/2018/04/20/mob-programming-and-scna-2018/480x320-IMG_3046.jpg" width="427" height="320" alt="My new calling: disruptive bullshit" title="My new calling: disruptive bullshit" class="img" /></p>
<p>In addition to seeing lots of old friends, I got to meet face-to-face with some folks I’d thus far only gotten to appreciate via Twitter.
One of them,
<a href="https://twitter.com/lisihocke">Lisi Hocke</a>,
wrote about
<a href="https://www.lisihocke.com/2018/04/mob-programming-conference-2018-all-about-the-people.html">her experience moberating two sessions</a>,
along with vivid details of her participation; read it and you’ll almost have the feeling of being there.
With a little luck I’ll return to the Mob Programming Conference next year, perhaps as a moberator.</p>
<p>A conference that took me five years to return to was
<a href="https://scna.softwarecraftsmanship.com">Software Craft[smanship] North America</a>.
The 2013 SCNA in Chicago brought me into a community of shared values I didn’t even know I was missing, and nudged me to make a
<a href="https://schmonz.com/2015/01/09/two-engagements/">significant career change</a>.
I can’t imagine how any subsequent SCNA could be as personally momentous, but at yesterday’s event in midtown Manhattan I enjoyed getting to know some
<a href="https://8thlight.com">8th Lighters</a>
over lunch, to run into one of my
<a href="https://schmonz.com/2015/06/17/problem-solving-leadership/">Problem Solving Leadership</a>
cohort (and meet
<a href="http://positiondev.com">his whole company</a>!),
to ask
<a href="https://twitter.com/spolsky">Joel Spolsky</a>
a
<a href="https://medium.com/@Aprilw/suffering-on-stack-overflow-c46414a34a52">pointed question about Stack Overflow culture</a>,
and to feel for a multitude of reasons that my professional and personal homes — coaching and New York — are finally neighbors.</p>
<p>Sure is good to be here.</p>
How to meet me (spring 2018 edition)https://schmonz.com/2018/04/02/how-to-meet-me-spring-2018-edition/Amitai Schleier2018-04-14T22:00:33Z2018-04-02T17:34:53Z
<p>Thanks to the power of the internet you can
<a href="https://schmonz.com/link/coffee/">buy me a fancy coffee</a>,
but I’d much rather treat you, dear reader, to the beverage of your choice — in person.
Here are some upcoming chances for us to do that:</p>
<ul>
<li><strong>Boston</strong>, April 12-13: <a href="https://www.agilegamesnewengland.com/index.php/mob-programming-conference">Mob Programming 2018</a></li>
<li><strong>New York City</strong>, April 19: <a href="https://scna.softwarecraftsmanship.org">Software Craftsmanship North America</a></li>
<li><strong>New York City</strong>, May 11: <a href="https://schmonz.com/talk/2018-basd/">Big Apple Scrum Day</a></li>
<li><strong>New York City</strong>, May 12-13: <a href="http://bangbangcon.com">!!Con</a></li>
</ul>
<p>(I’m considering
<a href="http://codelandconf.com">Codeland</a>,
also in NYC.
Let me know if you’re going.)</p>
<p>Another way is for us to work together.
I’m available for
<a href="https://latentagility.com">consulting, coaching, or training</a>,
mostly in the New York metro area.</p>
<p>In Europe?
You’re in luck!
This summer I’ll be doing a coding tour, speaking at a few conferences, and consulting (mostly in Germany).
More details forthcoming.</p>
<form method="get" action="https://schmonz.com/cgi-bin/ikiwiki" id="tinyemailform">
<div id="tinyemailform">
<div id="tinyemailexhortation">Might we meet and/or work together?</div>
<input type="text" id="tinyemailbox" name="tinyemailfrom" value="" size="30" placeholder="my@email.address" />
<input type="hidden" id="tinyemaildestination" name="tinyemaildestination" value="consulting inquiries" />
<input type="hidden" id="tinyemailsubject" name="tinyemailsubject" value="contact from 2018/04/02 blog post" />
<input type="hidden" id="tinyemailbody" name="tinyemailbody" value="" />
<input type="hidden" id="tinyemailconfirmationheading" name="tinyemailconfirmationheading" value="tinyemail request" />
<input type="hidden" id="tinyemailconfirmationbody" name="tinyemailconfirmationbody" value="Request submitted. Amitai will be in touch." />
<input type="hidden" name="do" value="tinyemail" />
<br /><input type="submit" value="Please email me back" size="30" />
</div>
</form>
Back to work — maybe with you?https://schmonz.com/2018/02/09/back-to-work-maybe-with-you/Amitai Schleier2018-05-02T17:30:05Z2018-02-09T11:47:48Z
<p>A few weeks ago, I returned to work.
A friend and fellow technical coach graciously invited me to his client to
<a href="https://www.praqma.com/stories/agile-coaching/">pair-coach for a week and solo for another</a>.
Since Bekki and Taavi were able to travel with me on this occasion, it was easy to accept.</p>
<p><a href="https://schmonz.com/2018/02/09/IMG_1873.jpg"><img src="https://schmonz.com/2018/02/09/back-to-work-maybe-with-you/480x320-IMG_1873.jpg" width="427" height="320" alt="Taavi's first Residence Inn (since being born)" title="Taavi's first Residence Inn (since being born)" class="img" /></a></p>
<p>I would strongly recommend that anyone, given the option, return to work in this particular way.
I feel very lucky to have been given the option.
My friend designed the guest-coaching environment at his client for my time to be meaningful to them — and, therefore, to me.
It was an honor to be there.
And it’s more wonderful than ever to be home again.</p>
<h2>Meaningful for others</h2>
<p>Clients typically invite me in because they want technical coaching.</p>
<p>I’m happy to accept.
I enjoy programming with programmers, testing with testers, and managing with managers.
I join in the work, observe where we’re going, and offer techniques and habits intended to help us get there.
Along the way, we talk.</p>
<p>My recent two-week engagement has clarified for me once again that my impact typically stems from (most to least):</p>
<ol>
<li>One-on-one conversations</li>
<li>Group conversations</li>
<li>Anything involving computers</li>
</ol>
<p>There’s a big gap between (3) and (2).
Whereas techniques and habits are hard to change and slow to pay off, conversations can quickly strengthen human connections, bring instant insight, and improve conditions for further improvements.</p>
<blockquote><p><strong>Given</strong> I’m just visiting<br />
<strong>When</strong> I’ve done my job<br />
<strong>Then</strong> the folks involved feel more effective doing theirs</p></blockquote>
<p>Clients are typically happy to have had me as a technical coach.
It gets me close enough to have meaningful conversations.</p>
<h2>Meaningful for me</h2>
<p><a href="https://schmonz.com/2018/02/09/IMG_2052.jpg"><img src="https://schmonz.com/2018/02/09/back-to-work-maybe-with-you/320x480-IMG_2052.jpg" width="320" height="427" alt="Taavi falling asleep in the car" title="Taavi falling asleep in the car" class="img" /></a></p>
<p>My son is eight months old.
It’s been very special having so much time with him.
I’m motivated to keep it this way.</p>
<p>I’m 39 today, and feeling reflective.</p>
<ul>
<li>Four years ago: <a href="https://schmonz.com/2014/04/01/my-superpower/">needed my career to change</a></li>
<li>Three years ago: <a href="https://schmonz.com/2015/01/09/two-engagements/">found a foothold</a></li>
<li>Two years ago: <a href="https://schmonz.com/2016/02/15/birthday-week/">gathered momentum</a></li>
<li>One year ago: <a href="https://schmonz.com/2017/01/05/new-years-slack/">moved cross country, baby on the way</a></li>
</ul>
<p>Today, I’m pleased to announce that I’ve <a href="https://latentagility.com">gone independent</a>.</p>
<h2>Meaningful for you</h2>
<p>You can engage me directly for consulting, coaching, or training in the New York metro area (and very occasionally elsewhere).
We’ll design an environment for our time together to be impactful and valuable.</p>
<p>To learn more about what I can do for you, take a quick look at my <a href="https://schmonz.com/resume/">one-page résumé</a> and my <a href="https://schmonz.com/coach/">coaching bio</a>.
Or a quick listen to my <a href="https://agilein3minut.es/">three-minute podcast</a>.</p>
<form method="get" action="https://schmonz.com/cgi-bin/ikiwiki" id="tinyemailform">
<div id="tinyemailform">
<div id="tinyemailexhortation">Or just get in touch and let’s talk:</div>
<input type="text" id="tinyemailbox" name="tinyemailfrom" value="" size="30" placeholder="my@email.address" />
<input type="hidden" id="tinyemaildestination" name="tinyemaildestination" value="consulting inquiries" />
<input type="hidden" id="tinyemailsubject" name="tinyemailsubject" value="contact from 2018/02/09 blog post" />
<input type="hidden" id="tinyemailbody" name="tinyemailbody" value="" />
<input type="hidden" id="tinyemailconfirmationheading" name="tinyemailconfirmationheading" value="tinyemail request" />
<input type="hidden" id="tinyemailconfirmationbody" name="tinyemailconfirmationbody" value="Request submitted. Amitai will be in touch." />
<input type="hidden" name="do" value="tinyemail" />
<br /><input type="submit" value="I'd like to schedule a call" size="30" />
</div>
</form>
Agile Coaching DC January 2018: Behavior-Driven Development for Everyonehttps://schmonz.com/2018/01/18/agilecoachingdc-january-2018-bdd-for-everyone/Amitai Schleier2021-11-25T09:54:33Z2018-01-18T23:30:00Z
<table class="img"><caption>Photo by Steve Moubray</caption><tr><td><a href="http://www.agilecoachingdc.org/2018/better-stories-through-behavior-driven-design/"><img src="https://schmonz.com/2018/01/18/agilecoachingdc-january-2018-bdd-for-everyone/480x320-A6_06120.jpg" width="480" height="320" alt="I peek at one group's BDD scenarios" title="I peek at one group's BDD scenarios" class="img" /></a></td></tr></table>
<p>At
<a href="https://www.meetup.com/Agile_Coaching_DC/events/246126647/">the Agile Coaching DC
meetup</a>
tonight, about 50 people participated in my “Behavior-Driven
Development for Everyone” exercise.
The abstract:</p>
<blockquote><p>Problems are better solved when you’re better involved. That’s how you
make your living, and that’s what BDD is all about. We’ll work together
to solve a problem in a way we can all understand and trust, expressing
what we want in plain English and automating our tests with a tool
called Cucumber. Don’t worry, you won’t be put on the spot at the
keyboard — I’ll handle all the coding!</p></blockquote>
<h2>What we did</h2>
<p>My goal was to illustrate two things:</p>
<ol>
<li>Cucumber the tool: side-by-side-by-side, how the three ingredients —
the human-readable Gherkin spec, the programmer-readable step
definitions that animate the spec, and the code being developed to
meet the spec — are connected, or might fail to be, and how they
must evolve together.</li>
<li>BDD the practice: side-by-side-by-side, how the Three Amigos —
Product Owners, Testers, and Developers — are connected, or might
fail to be, and how they can collaborate via shared language (and
<em>optionally</em> a tool like Cucumber).</li>
</ol>
<p>To that end, after reviewing a few <a href="https://schmonz.com/2018/01/18/agilecoachingdc-january-2018-bdd-for-everyone/slides/">slides</a>, I live-coded the first
few bits of Gherkin, step definitions, and application code, using
<a href="https://github.com/cucumber/cucumber/wiki/Cucumber-for-Perl">Cucumber in Perl</a>.
Then we split into a few groups to slice and sequence the remaining
scenarios that add up to a properly scored game of bowling, and got back
together at the end to compare results. Our findings are in the <a href="https://schmonz.com/2018/01/18/agilecoachingdc-january-2018-bdd-for-everyone/slides/">slides</a>.</p>
<p>Here’s video of the first half:</p>
<div class="video-container">
<iframe src="https://www.youtube-nocookie.com/embed/TqAeRtYImZA" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
<p>And here are organizer <a href="http://www.agilecoachingdc.org/2018/better-stories-through-behavior-driven-design/">Steve Moubray’s photos of the second half</a>.</p>
<h2>Read more</h2>
<p>In addition to the references in the <a href="https://schmonz.com/2018/01/18/agilecoachingdc-january-2018-bdd-for-everyone/slides/">slides</a>, here’s a story of my
own about
<a href="https://schmonz.com/2015/07/01/tdd-in-context-9-thwarted/">seeking greater effectiveness through BDD</a>,
from my <a href="https://schmonz.com/tag/tdd-in-context/">series about the human value of TDD</a>.</p>
<h2>Learn more</h2>
<p>What would BDD look like in your context? Need help getting started? Get
in touch! I’d love to work with you (especially in the New York metro
area or remotely) or refer you to an expert hands-on instructor near you.</p>
Training: The Agile Fluency Gamehttps://schmonz.com/2017/12/29/training-agile-fluency-game/Amitai Schleier2018-01-02T16:30:32Z2017-12-29T11:59:19Z
<p>Etymologically, “fluency” is about flow. Practically, it’s about language: from one angle, it’s how well you understand and speak under stress or pressure. My teammates playing the <a href="http://www.jamesshore.com/Blog/Agile-Fluency-Game-Now-Available.html">Agile Fluency Game</a> in Hamburg a couple weeks ago had no discernible difficulty speaking English, but it must have been effortful for them, because when we felt the clock ticking, they returned to German. Communicating more efficiently within the team — including me, since I could mostly understand them — bought us time and brainpower to improve our outcome considerably.</p>
<p>The Agile Fluency Game is intended to help understand and speak about the <a href="http://www.agilefluency.org">Agile Fluency Model</a>. As <a href="https://www.futureworksconsulting.com/about/diana-larsen">Diana Larsen</a> explained it, the model suggests thinking of Agile as something like <a href="https://www.mvv-muenchen.de/en/tickets-and-fares/tariff-structure/zones/">zones in a municipal transit system</a>. From the city center, it costs more to get to the outer zones, but not because they’re objectively superior places. They’re just further away from where we are. If it’s worth it to pay the fare and take the time, we can get there.</p>
<p>Since the model offers <a href="http://www.agilefluency.org/model.php">four zones</a> with benefits and relative costs, I might also liken it to the number of courses in a meal: Agile-striving organizations can order just enough to sate their investment appetite.</p>
<h2>So what?</h2>
<p>For me, the usefulness of the Agile Fluency Model centers on offering an alternative to some false dichotomies:</p>
<ul>
<li>doing Agile vs. being Agile</li>
<li>being Agile vs. not</li>
</ul>
<p>Perhaps these dichotomies are rhetorically useful. I certainly find them useful as motivation to reframe. As a student of behavior, I don’t see a clear separation between doing and being; as a student of Agile, I <a href="https://agilein3minut.es/1">don’t see a clear reason (or basis) to judge ourselves in or out</a>. If the Agile Fluency Model helps us refocus on making adaptive choices in and about our own environments, then it’s a useful frame.</p>
<p>In this sense, it’s also an Agile <a href="http://sourcesofinsight.com/satir-categories/">Congruency</a> Model. If we can more precisely identify our organizational and individual needs, we can more explicitly meet them, and expend much less effort bridging or apologizing for a significant <a href="http://www.drdavidfraser.com/2015/03/20/whats-the-difference-between-espoused-theories-and-theories-in-use/">gap between our espoused values and our values-in-action</a>. Maybe the two sets of values can be congruent.</p>
<h2>Playing the game</h2>
<p>We played twice.</p>
<p>The first time through, we spent a big percentage of our time and brainpower getting oriented in the game — some up front and some as we went along — kind of like when we were brand new to Agile. There were cards about features (of which we must deliver at least one per quarter, to make money) and about practices (which might be, I dunno, really helpful for delivering features). <a href="https://agilein3minut.es/4">My intuition said</a> that if the design of this game was based on real-world experience anything like mine, we should be willing to defer most other goals in exchange for practicing Test-Driven Development and <a href="https://agilein3minut.es/29">Refactoring</a> as early as possible. My teammates had other ideas, so my intuition was tested. Indeed, it got harder and harder to deliver a feature in time, until finally we couldn’t, and lost.</p>
<p>TDD and refactoring conspire to remove costs and <a href="https://agilein3minut.es/6">risks</a> that otherwise remain hidden. It’s precisely when the current state is hard to see that the proposed benefit is hard to imagine. Words often fail. Distilled from the experience and wisdom of <a href="http://www.jamesshore.com/Consulting/Credentials.html">James Shore</a> and <a href="http://arlobelshee.com/about/">Arlo Belshee</a>, the Agile Fluency Game offers a way for people who haven’t yet <a href="https://agilein3minut.es/10">tried</a> these <a href="https://agilein3minut.es/22">disciplined development practices</a> to get a meaningful, cause-and-effect feeling for their costs and benefits.</p>
<p>The second time through, we graphed the practices and their dependencies, avoided delivering more than one feature per quarter, and spent the rest of our resources acquiring practices prioritized by in-game benefits (such as reduced carrying cost of existing code). This turned out to be a very good strategy. We got into flow, played more than our individual roles, helped each other hold attention to our strategy, racked up increments of success and momentum, rolled up our sleeves because we were getting warm, and won an outcome beyond what we assumed possible. Afterward, Anja said “Can we do a real project together?”</p>
<h2>Takeaways</h2>
<p>After sharing that feeling, I was disappointed at not being able to take away a copy of the Agile Fluency Game. It’s understandable: since the game’s design is intentionally complicated, learning from the game in a reasonable timeframe benefits from — indeed, might require — intentional facilitation. Even so, it was disappointing. Even so <em>so</em>, I may consider enrolling in the <a href="http://www.agilefluency.org/workshops.php">training required to get it</a>, because I’d love to have the option to share the game with my clients.</p>
<p>Why is having this option important to me? Because what I did take away is a reinforced belief that we humans are far more apt to learn new behaviors from experiences than from words. (Don’t get me wrong. I love words. And they’re a great way to become aware of behaviors we might like to try.) As a coach, I can tell when I’m at my best: it’s when I’m doing less explaining and more <a href="https://twitter.com/GeePawHill/status/644955414002536448">creating shared experiences</a>. So I’m glad to have played the Agile Fluency Game, and I hope many more people get to play it.</p>
Toronto Agile Community August 2017: Behavior-Driven Development for Everyonehttps://schmonz.com/2017/08/17/torontoagile-august-2017-bdd-for-everyone/Amitai Schleier2021-11-25T09:54:33Z2017-08-17T17:00:00Z
<p>In mid-August, the week after the big Agile conference, I led a
“Behavior-Driven Development for Everyone” webinar for the
<a href="http://www.torontoagilecommunity.org">Toronto Agile Community</a>.</p>
<blockquote><p>Problems are better solved when you’re better involved. That’s how you
make your living, and that’s what BDD is all about. We’ll work together
to solve a problem in a way we can all understand and trust, expressing
what we want in plain English and automating our tests with a tool
called Cucumber. Don’t worry, you won’t be put on the spot at the
keyboard — I’ll handle all the coding!</p></blockquote>
<h2>What we did</h2>
<p>There were several dozen people watching online as I programmed
out loud with
<a href="https://github.com/cucumber/cucumber/wiki/Cucumber-for-Perl">Cucumber in Perl</a>,
taking questions along the way. Of course, it wasn’t nearly as
collaborative as a group of <a href="https://agilein3minut.es/9">two</a> or
<a href="https://agilein3minut.es/32">five</a> could be. We tried to mitigate the
unidirectionality by stopping regularly for question breaks, and to
elucidate the differences between my unilateral onscreen actions and BDD
as it is meaningfully and collaboratively practiced.</p>
<p>The video:</p>
<div class="video-container">
<iframe src="https://www.youtube-nocookie.com/embed/5lM8xcV4Jk4" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
<h2>What I learned</h2>
<p>In the webinar, side-by-side-by-side, I live-coded the human-readable
Gherkin spec, the programmer-readable step definitions that bring the
spec to life, and the code being developed to meet the spec.</p>
<p>In doing this, my intention was to illustrate how these three pieces are
connected (or might fail to be) and how they must evolve together — in
other words, to give concrete impressions of the cost of maintaining
Cucumber tests and of the value they might provide in return.</p>
<p>We didn’t get to retrospect together, but I suspect a couple things
worked somewhat well for the group:</p>
<ul>
<li>Choosing a notoriously difficult-to-read language of implementation,
to drive home the point that it’s not necessary to understand the code
to understand the state of the product</li>
<li>Demonstrating what a developer’s work looks like when Cucumber is involved</li>
</ul>
<p>I think I could have delivered more on my intention to illustrate
Cucumber’s cost and value as a BDD-supporting tool if I’d spent less
time typing. Next time I present this material, if we can’t do it
collaboratively (as I did
<a href="https://schmonz.com/2016/03/09/agileindy-march-2016-bdd-for-everyone/">for AgileIndy last year</a>),
I’ll use a technique I’ve used before and simply forgot about:</p>
<ol>
<li>Develop the demo code in advance, committing at each interesting change</li>
<li>With the audience, move through the changes at leisure using
<a href="https://twitter.com/magnusstahre">Magnus Stahre</a>’s
<a href="https://github.com/magnusstahre/git-stuff">git-crawl</a>.</li>
</ol>
<h2>Read more</h2>
<p>In addition to the references in the <a href="https://schmonz.com/2017/08/17/torontoagile-august-2017-bdd-for-everyone/slides/">slides</a>, here’s a story of my
own about
<a href="https://schmonz.com/2015/07/01/tdd-in-context-9-thwarted/">seeking greater effectiveness through BDD</a>,
from my <a href="https://schmonz.com/tag/tdd-in-context/">series about the human value of TDD</a>.</p>
<h2>Learn more</h2>
<p>What would BDD look like in your context? Need help getting started? Get
in touch! If you’re in the New York metro area or willing to try a remote
consultant, I’d love to work with you. Otherwise, I’m happy to refer you
to an expert hands-on instructor in your area.</p>
How to share photoshttps://schmonz.com/2017/06/29/how-to-share-photos/Amitai Schleier2017-06-29T22:27:44Z2017-06-29T21:01:39Z
<p>We aren’t usually <a href="https://schmonz.com/2017/06/16/now/">operating at peak mental capacity</a> over here. When I do have some brain, I try to spend it on mitigating the low-brain situation. For instance, we want to make sure we keep sharing photos of <a href="https://schmonz.com/2017/06/14/taavi-lua-schleier/">Taavi</a>. Like this one:</p>
<p><a href="http://photos.theschleiers.com/taavi/week3/IMG_2649.jpg"><img src="https://schmonz.com/2017/06/29/IMG_2649.jpg" width="300" height="400" alt="Taavi, chillaxing" title="Taavi, chillaxing" class="img" /></a></p>
<h2>Goals</h2>
<ol>
<li>Continue to publish baby photos at the URL <a href="http://photos.theschleiers.com">http://photos.theschleiers.com</a></li>
<li>Make it safe for us to keep taking photos
<ol>
<li>Save them to our computers first (where they get backed up), then publish</li>
<li>Limit potential damage from making it easy (below)</li>
</ol>
</li>
<li>Make it easy for us to publish new photos
<ol>
<li>Manipulate albums as network folders</li>
<li>Sort gallery view by date (not filename — everyone’s are numbered differently)</li>
<li>Use the same URL for uploads, because we’re not trying to have
<em>more</em> things to keep track of</li>
</ol>
</li>
</ol>
<h2>Things that didn’t work</h2>
<p>Bekki and I both use Macs. The Finder is a <a href="https://en.wikipedia.org/wiki/WebDAV">WebDAV</a> client. Having <a href="https://schmonz.com/2016/09/11/refactorings-for-web-hosting/">refactored all my sites to Lighttpd</a>, I was hoping to use <a href="https://redmine.lighttpd.net/projects/lighttpd/wiki/Docs_ModWebDAV">its WebDAV module</a>. But it turns out the Finder is a pretty demanding WebDAV client. <a href="http://nginx.org/en/docs/http/ngx_http_dav_module.html">nginx’s WebDAV module</a> interoperated poorly too.</p>
<p>I was reminded that the Finder is also an FTP client. I got as far as trying it, only to find out it’s read-only.</p>
<p>I reviewed which network protocols the Finder can read <em>and</em> write, and which servers interoperate. All signs pointed to <a href="https://httpd.apache.org/docs/2.4/mod/mod_dav.html">Apache’s WebDAV implementation</a>. I was reluctant, but accepted the need to allow Apache back into my life.</p>
<h2>Under controlled circumstances</h2>
<p>My internet-facing reverse proxy is still <a href="http://www.apsis.ch/pound/">Pound</a>. Nearly all my sites are still <a href="https://www.lighttpd.net">Lighttpd</a>. Now there’s one site that’s Apache. I’m okay with this because:</p>
<ul>
<li>Our originals are elsewhere, and backed up. What you see are copies.
If an attacker gains access, they <strong>can’t make us lose photos</strong>.</li>
<li>This Apache instance runs as its own Unix user. If an attacker gains
access, they <strong>can’t make me lose other stuff</strong>.</li>
<li>I learned <a href="https://schmonz.com/2016/09/11/refactorings-for-web-hosting/">last time around</a>
how to make a small, self-contained Apache config. I <strong>feel confident in
my understanding</strong> of what it will and won’t do.</li>
</ul>
<h2>How it works</h2>
<p>Last week, when Pound received a request for <code>photos.theschleiers.com</code>, it delegated to my instance of <a href="https://www.rainskit.com">Nathan Arthur</a>’s <a href="https://github.com/truist/gallery">Gallery</a> app.</p>
<p>This week, Pound delegates to Apache, and Apache delegates typical browser requests to Gallery. For you, no visible change.</p>
<p>When Apache receives a request from a client that looks roughly like the Finder, it requires a login, then speaks full Finder-friendly WebDAV. When Bekki or I have new photos to share, we just copy them over.</p>
<p>Here’s <a href="https://schmonz.com/2017/06/29/apache_webdav.conf.txt">the Apache config</a> that made it safe and easy for us to post <a href="http://photos.theschleiers.com/taavi/week3/">photos from Taavi’s third week</a>.</p>
Taavi Lua Schleierhttps://schmonz.com/2017/06/14/taavi-lua-schleier/Amitai Schleier2017-06-14T14:54:41Z2017-06-14T14:51:37Z
<p>Our child arrived a week ago, at 6 pounds 6 ounces on 6/6. On Friday, we introduced him to his grandparents via Skype, showing them his name on an iPad. It looked like this:</p>
<p><img src="https://schmonz.com/2017/06/14/IMG_7316.JPG" width="300" height="400" alt="Taavi Lua Schleier with big letters" title="Taavi Lua Schleier with big letters" class="img" /></p>
<p>We’ve been home for a few days. Yesterday Taavi looked — and looked! — like this:</p>
<p><img src="https://schmonz.com/2017/06/14/IMG_7489.JPG" width="400" height="300" alt="Taavi Lua Schleier with big eyes" title="Taavi Lua Schleier with big eyes" class="img" /></p>
<p>I don’t know what Taavi looked like while listening to me play the piano last night. If indeed he was listening, he heard bits and pieces of <a href="https://www.youtube.com/watch?v=WMFbDP34m5w">Medtner’s “Dance Tale”, Op. 48 No. 1</a>, and then the <a href="https://www.youtube.com/watch?v=CvhWk6j2tFw">Brahms Intermezzo, Op. 117 No. 1</a> I had hummed to him in the cocoon.</p>
<p>My sister and both grandmae have held him. Grandpae and Bekki’s brothers will soon. Everyone is happy and healthy. About the name:</p>
<h2>Taavi</h2>
<p>Finnish/Estonian variant of Hebrew David, “beloved”.</p>
<ul>
<li>We like the sound</li>
<li>We like the meaning</li>
<li>We like the Hebrew connection</li>
<li>We like how Germans and Israelis and Americans will be able to pronounce it</li>
<li>After a couple days with him, we both independently decided he’s Taavi (and not the other names we were thinking about)</li>
<li>Amitai likes being able to vaguely associate the name with <a href="https://schmonz.com/2007/11/14/medtner-music-and-me/">Medtner</a> (of Livonian descent, Germans who settled in the Baltics, of which Estonia is one)</li>
<li>Sounds phonetically related to “Ami<strong><em>ta</em></strong>i” and “Bekk<strong><em>i</em></strong>”</li>
<li>The first “a” is <a href="https://schmonz.com/2014/06/29/one-russian-soul/">in memory of our friend Andrew</a></li>
</ul>
<h2>Lua</h2>
<p>Portuguese, “moon”.</p>
<ul>
<li>Born under a big moon (waxing gibbous), and he went home on the full moon</li>
<li>We like the sound</li>
<li>We like mixing languages for our citizen of the world</li>
<li>We like the reminder to look beyond our world</li>
<li>We like the association with our love and memory of another very special animal, Lunar</li>
<li>We like the association with our <a href="https://schmonz.com/2014/03/01/haskell-the-dog/">Haskell</a>, by virtue of both being programming languages</li>
<li>The Lua programming language is included in <a href="http://netbsd.gw.com/cgi-bin/man-cgi?lua+4+NetBSD-current">NetBSD</a>, an open-source project which led Amitai to friends, <a href="https://schmonz.com/2005/09/07/first-week-of-classes/">Columbia</a>, <a href="https://schmonz.com/2016/10/16/agile-coach-camp/">employment</a>, and ultimately Bekki</li>
<li>Amitai has even <a href="https://schmonz.com/2016/09/11/lowercase-textpattern-categories.lua.txt">written a little Lua</a></li>
</ul>
<h2><a href="http://theschleiers.com/taavi/">Taavi Lua Schleier</a></h2>
<ul>
<li>We like the sounds together</li>
<li>The names and initials aren’t obviously embarrassing</li>
<li>It’s unique enough</li>
<li>It means enough</li>
<li>It reflects our heritages enough</li>
<li>It will sound like a grownup when he’s a grownup</li>
</ul>
<h3>More nice properties observed after the fact</h3>
<ul>
<li><strong>Taavi:</strong>
<ul>
<li>Abba: תביא (ta-VEE, emphasis on second syllable) means “bring” (imperative), which is what the doctors needed to do</li>
<li>Abba: תו (tav, “musical note”)</li>
<li>Abba: “Tavi” is a Hebrew name these days apparently</li>
</ul>
</li>
<li><strong>Lua:</strong>
<ul>
<li>Bekki: “Mondschleier” (”Mond” is German for “moon”) is the halo around the moon</li>
</ul>
</li>
<li><strong>Whole name:</strong>
<ul>
<li>Nathan: TLS means “secure” (<a href="https://en.wikipedia.org/wiki/Transport%20Layer%20Security">Transport Layer Security</a>, encryption for data in motion)</li>
</ul>
</li>
</ul>
<p>If you think of another reason this is a nice name, please pass it along.</p>
<h2>For my Lean/Agile/XP/systems/org-thinker readers</h2>
<p>Taavi embodies the famous <a href="https://en.wikipedia.org/wiki/Peter%20Senge">Peter Senge</a> adage “People don’t resist change. They resist being changed.” But he’s getting used to it.</p>
<h2>For Taavi to understand someday</h2>
<p><img src="https://schmonz.com/2017/06/14/IMG_8314.JPG" width="400" height="300" alt="Bekki & Amitai lock" title="Bekki & Amitai lock" class="img" /></p>
<h2>More photos</h2>
<p><a href="http://photos.theschleiers.com/taavi/">photos.theschleiers.com/taavi</a></p>
qmail + submission + rewrite headershttps://schmonz.com/2017/05/27/qmail-submission-rewrite-headers/Amitai Schleier2023-11-15T15:53:47Z2017-05-27T16:37:16Z
<h2>Previously</h2>
<p>This is the eighth in a series of
“Nifty and Minimally Invasive qmail Tricks”,
following</p>
<ol>
<li><a href="https://schmonz.com/2007/01/14/qmail-smtp-auth-ssl-tls-patches/">qmail + SMTP AUTH + SSL + TLS - patches</a></li>
<li><a href="https://schmonz.com/2007/01/15/qmail-badrcptto-patches/">qmail + badrcptto - patches</a></li>
<li><a href="https://schmonz.com/2007/02/07/qmail-netbsd-nightly-maintenance/">qmail + NetBSD nightly maintenance</a></li>
<li><a href="https://schmonz.com/2007/02/28/qmail-imap-before-smtp/">qmail + IMAP-before-SMTP</a></li>
<li><a href="https://schmonz.com/2007/03/07/qmail-spam-filtering/">qmail + spam filtering</a></li>
<li><a href="https://schmonz.com/2017/01/18/qmail-smtp-auth-tls-redux/">qmail + SMTP AUTH + TLS redux</a></li>
<li><a href="https://schmonz.com/2017/05/22/qmail-outbound-dkim/">qmail + outbound DKIM</a></li>
</ol>
<h2>The mess822-QMAILQUEUE patch</h2>
<p>This is not <em>the</em> <a href="https://qmail.notqmail.org/qmailqueue-patch">QMAILQUEUE patch</a> by <a href="https://untroubled.org">Bruce Guenter</a> that’s included in <a href="https://qmail.notqmail.org/netqmail/">netqmail</a>.
When you want <a href="https://qmail.notqmail.org/man/man8/qmail-smtpd.html"><code>qmail-smtpd(8)</code></a>, for instance, to be able to modify or reject incoming messages by inserting a wrapper around <a href="https://qmail.notqmail.org/man/man8/qmail-queue.html"><code>qmail-queue(8)</code></a>, <em>the</em> QMAILQUEUE patch makes that easier.</p>
<p>The <a href="https://schmonz.com/software/mess822qmailqueue/">mess822-QMAILQUEUE patch</a> is the exact same idea (and code), but for <a href="https://cr.yp.to/mess822.html">mess822</a>.</p>
Codes of Conduct in 3 Minuteshttps://schmonz.com/2017/05/24/codes-of-conduct-in-3-minutes/Amitai Schleier2017-05-24T20:54:50Z2017-05-24T20:32:06Z
<h2>Then and now</h2>
<p>A few years ago, after a long stretch of not feeling heard in my job, I <a href="https://schmonz.com/2014/04/01/my-superpower/">resolved to change that</a>, starting with <a href="https://schmonz.com/2015/01/09/two-engagements/">getting a different kind of job</a>.
Then I started <a href="https://schmonz.com/2015/06/03/self-conf-2015-almost-self-less/">attending conferences</a>, <a href="https://schmonz.com/2015/07/15/introducing-agile-in-3-minutes/">making Agile in 3 Minutes</a>, and appearing on <a href="https://schmonz.com/tag/agile-for-humans/">Agile for Humans</a> and <a href="https://schmonz.com/tag/not-talk/">other podcasts</a>.
Finally, I found myself at many of the same conferences <a href="https://schmonz.com/speaker/">as a speaker</a>, sometimes even by invitation.</p>
<p>This took a nonzero amount of luck and a lot of effort.
I put in the effort because, as a human being, I needed to feel heard at work.
If you’re reading this, odds are you’re a human being with the same need.</p>
<p>Today I expect that I can mostly get myself listened to, and am surprised (and indirectly, gratified) on the rare occasions when I can’t.
Compared to myself a few years ago, I feel relieved, empowered, and a little scared.
Scared? Yeah, sometimes.
When folks are apparently much more inclined to try as I suggest, it becomes much more important that I suggest wisely.</p>
<h2>Them and me</h2>
<p>My path here was, and is, smoother than others’.
One way I’ve come to understand this: when I go to conferences, the worst I ever feel (or expect to feel) is introvert-overwhelmed.
It happens.
I have to strategize what to do when I notice my tank is running low, or when I’ve failed to notice for too long.
Either way, it can usually be as simple as going back to my hotel room.</p>
<p>Another way I’ve come to understand this: when I go back to my room, I’ve never been followed there, or been creeped on or harassed in any number of other ways.
So I’ve neither had to deal with those things as they’re happening, nor had to decide whether I’m going to sign myself up to strategize how I’ll deal with those things happening again.</p>
<p>Finally, and most clearly, I’ve come to understand this by hearing from people who are no longer willing to attend a conference unless it has a <a href="https://en.wikipedia.org/wiki/Code%20of%20Conduct">Code of Conduct</a>.
I haven’t experienced what they have, so I’m still willing to go, I think (it’s been a while since I had to choose).
The thought that I’m able to feel comfortable in a place where others might not be makes me wonder: when I’m there, what I can do about it?</p>
<p>I’ve started <a href="https://twitter.com/schmonz/status/809150922035200000">doing a small thing</a>.</p>
<h2>Me and you</h2>
<p>If you’re in a position like mine — where you’re listened to and heard — you have currency.
I’d like to suggest a small investment you can make with it.</p>
<p>When you’re presenting at a conference, spend <a href="https://agilein3minut.es/8">three of your minutes</a> giving a quick overview of the Code of Conduct that’s in effect:</p>
<ul>
<li>Where to find it</li>
<li>What it can and can’t do</li>
<li>Key examples of language to look for</li>
<li>Some ramifications for the audience and the conference as a whole</li>
</ul>
<p>If the conference <em>doesn’t</em> have a Code of Conduct, say that out loud, along with this one weird ramification: <strong>some of the people we could have learned the most from aren’t here</strong>.</p>
<p>If the conferences where you’re speaking are technical and/or Agile, you can relate all of this to <a href="https://schmonz.com/tag/tdd-in-context/">TDD</a> and/or <a href="https://schmonz.com/2016/03/09/agileindy-march-2016-bdd-for-everyone/">BDD</a>, and encourage folks to pair afterward on example scenarios for shared understanding.</p>
<h2>Invest wisely</h2>
<p>Why do I suggest this? Because in my limited experience of not being listened to, followed by being frighteningly well listened to, I can begin to guess what it’s like to be frightened of worse things <em>and then</em> of not being listened to about them.
And I can begin to guess, when humans want to add to our communities and we don’t take small chances to try to include them, how much the rest of us lose.</p>
<p>If you have currency, consider making a small investment.
The returns may surprise us all.</p>
<h2>Steal freely</h2>
<p>Here’s the <a href="https://schmonz.com/2017/05/24/codes-of-conduct-in-3-minutes/slides/">text of the slides</a> I’ve been using for my last several presentations (<a href="https://schmonz.com/2017/05/05/aab-2017-best-team-anywhere/slides/#5">example</a>).
The content is licensed <a href="https://creativecommons.org/licenses/by/4.0/">CC-BY-4.0</a> or in the public domain, whichever you prefer.</p>
<p>Copy, modify, and present as you wish.
Please share what you learn!</p>
qmail + outbound DKIMhttps://schmonz.com/2017/05/22/qmail-outbound-dkim/Amitai Schleier2023-11-15T15:53:47Z2017-05-22T16:48:58Z
<h2>Previously</h2>
<p>This is the seventh in a series of
“Nifty and Minimally Invasive qmail Tricks”,
following</p>
<ol>
<li><a href="https://schmonz.com/2007/01/14/qmail-smtp-auth-ssl-tls-patches/">qmail + SMTP AUTH + SSL + TLS - patches</a></li>
<li><a href="https://schmonz.com/2007/01/15/qmail-badrcptto-patches/">qmail + badrcptto - patches</a></li>
<li><a href="https://schmonz.com/2007/02/07/qmail-netbsd-nightly-maintenance/">qmail + NetBSD nightly maintenance</a></li>
<li><a href="https://schmonz.com/2007/02/28/qmail-imap-before-smtp/">qmail + IMAP-before-SMTP</a></li>
<li><a href="https://schmonz.com/2007/03/07/qmail-spam-filtering/">qmail + spam filtering</a></li>
<li><a href="https://schmonz.com/2017/01/18/qmail-smtp-auth-tls-redux/">qmail + SMTP AUTH + TLS redux</a></li>
</ol>
<h2>The QMAILREMOTE patch</h2>
<p>When you want to wrap
<a href="https://qmail.notqmail.org/man/man8/qmail-remote.html"><code>qmail-remote(8)</code></a>
with another program — for instance, to
<a href="https://en.wikipedia.org/wiki/DomainKeys%20Identified%20Mail">DKIM</a>-sign outgoing mail
— the <a href="https://schmonz.com/software/remote/">QMAILREMOTE patch</a>
lets you do so by setting an environment variable.</p>
Agile and Beyond 2017: The Best Team Anywhere: Distributed Agile Tradeoffs and Techniqueshttps://schmonz.com/2017/05/05/aab-2017-best-team-anywhere/Amitai Schleier2017-05-06T21:19:17Z2017-05-05T04:00:00Z
<table class="img"><caption>Photo by Jason Dinkelmann</caption><tr><td><a href="https://www.facebook.com/photo.php?fbid=10212904262381711&set=pcb.10212904265301784&type=3&theater"><img src="https://schmonz.com/2017/05/05/aab-2017-best-team-anywhere/480x270-workshop.jpg" width="480" height="270" alt="Jeff and I describe the A&B Code of Conduct" title="Jeff and I describe the A&B Code of Conduct" class="img" /></a></td></tr></table>
<p>At
<a href="http://agileandbeyond.com/2017/">Agile and Beyond</a>
in Ann Arbor,
<a href="http://blog.jhoover.com">Jeff Hoover</a>
and I facilitated a workshop on <a href="https://aab17.sched.com/event/9EhN/the-best-team-anywhere-distributed-agile-tradeoffs-and-techniques">effective collaborative software development for distributed teams</a>
(including
<a href="http://shapemywork.com">remote</a>
<a href="https://agilein3minut.es/9">pairing</a>
and
<a href="https://agilein3minut.es/32">mobbing</a>).</p>
<p>I also appeared on a <a href="https://aab17.sched.com/event/Afh0/blame-shame-and-punishment">Blame, Shame, and Punishment panel</a> with <a href="https://twitter.com/_AprilJefferson">April Jefferson</a> and <a href="https://twitter.com/tottinge">Tim Ottinger</a>, moderated by <a href="https://twitter.com/antz29">John Le Drew</a>.</p>
<p>The night before the conference, some of us got together for drinks, and nearly everyone who walked in the door was someone for me to hug.
It was wonderful to make a return visit to be among so many friends in southeast Michigan, to design and run another workshop with Jeff, and to feel satisfied about <a href="https://schmonz.com/2017/04/17/now/">not going to any more conferences for a while</a>.
My heart is full.
And my mind is full of heartily solicited advice for how to manage when my heart will soon be overflowing.</p>
<p>Oh yeah, the workshop:</p>
<ul>
<li><a href="https://schmonz.com/2017/05/05/aab-2017-best-team-anywhere/slides/">Slides</a></li>
</ul>
<p>Here’s the abstract:</p>
<h2>The Best Team Anywhere: Distributed Agile Tradeoffs and Techniques</h2>
<p>Colocated Agile is the easiest way to do a hard thing. Distributed Agile
is harder. But it’s 2017! It’s strategically valuable to be able to work
effectively with people no matter where they are. Bring your laptops and
prepare to experience the basic mechanics, pitfalls, and techniques of
distributed teamwork, including “remote” pairing.</p>
<table class="img"><caption>Photo by Kristen Belcher</caption><tr><td><a href="https://twitter.com/healthyagile/status/860592299201507331"><img src="https://schmonz.com/2017/05/05/aab-2017-best-team-anywhere/600x600-panel.jpg" width="600" height="600" alt="L to R: John, April, me, Tim" title="L to R: John, April, me, Tim" class="img" /></a></td></tr></table>
Big Apple Scrum Day 2017: The Care and Feeding of T-Shaped Peoplehttps://schmonz.com/2017/05/01/basd-2017-t-shaped-people/Amitai Schleier2017-05-02T17:41:07Z2017-05-01T04:00:00Z
<table class="img align-right"><caption>Photo by Faye Thompson</caption><tr><td><a href="https://twitter.com/AgileFaye/status/859142439390646273"><img src="https://schmonz.com/2017/05/01/basd-2017-t-shaped-people/600x338-agilefaye-last-responsible-vim-moment.jpg" width="600" height="338" alt="Redefining the 'last responsible moment'" title="Redefining the 'last responsible moment'" class="img" /></a></td></tr></table>
<p><a href="http://ryanripley.com">Ryan Ripley</a>
and I gave a talk at
<a href="http://www.bigapplescrumday.org">Big Apple Scrum Day</a>
in New York City.
We already do plenty of <a href="https://schmonz.com/tag/agile-for-humans/">talking at people</a>, and wanted to try a new format: collect questions from the audience, turn each into a slide, work our way through the slides.
Sort of a mash-up of <a href="http://leancoffee.org">Lean Coffee</a> and <a href="http://www.powerpointkaraoke.com">PowerPoint Karaoke</a>.
(We got the idea from <a href="https://twitter.com/chrismurman">Chris Murman</a> at <a href="https://schmonz.com/2017/04/29/agile-coach-camp-2017/">Agile Coach Camp</a>.
He was passing it along from having seen <a href="https://twitter.com/whurley">William ‘Whurley’ Hurley</a>’s <a href="https://drive.google.com/file/d/0B-dqbJ5HCsObUHVwekJBal9JSG8/view">Keep Austin Agile 2016 keynote</a>.)</p>
<ul>
<li><a href="https://schmonz.com/2017/05/01/basd-2017-t-shaped-people/slides/">Slides</a></li>
</ul>
<p>Here’s the abstract:</p>
<h2>The Care and Feeding of T-Shaped People</h2>
<p>Do we value “T-shaped” people who combine breadth with one area of
depth? Then we value “paint-drip” people who grow and change. Come hear
stories of professional growth through the lens of Kent Beck’s powerful
metaphor, learn ways to encourage others to broaden and deepen, and
practice on yourself.</p>
<p>Maybe you’re a project manager who knows your tracking tool inside and
out, but doesn’t totally understand what developers’ work is like. Maybe
you’re a developer who glides gracefully through your IDE, but doesn’t
grok how the PM stays busy all day. Probably neither of these reductive
examples captures your unique self. Good! So how did you come to be in
your current role, knowing what you know so far? What might you like to
learn next?</p>
<p>Ryan and Amitai’s experience as developers, managers, and now coaches
seems to agree with
<a href="https://www.facebook.com/notes/kent-beck/paint-drip-people/1226700000696195/">Kent Beck’s “Paint Drip Person” metaphor</a>,
which suggests that continued professional satisfaction and growth comes
not only from seeking deeper understanding within our original
specializations, but also by deliberately broadening our skills and
following our curiosity (or heeding its absence).</p>
<p>We’ll draw on our experiences to kick-start your thinking about which
brush you’re using, which color, and where your paint is picking up
speed. You’ll leave with energy and clarity for the next step in your
personal Agile journey.</p>
<table class="img"><caption>Photo by Jason Tice</caption><tr><td><a href="https://twitter.com/TheAgileFactor/status/859222896115294213"><img src="https://schmonz.com/2017/05/01/basd-2017-t-shaped-people/600x450-theagilefactor-live-notes.jpg" width="600" height="450" alt="Jason Tice's live notes" title="Jason Tice's live notes" class="img" /></a></td></tr></table>
Agile Coach Camp 2017https://schmonz.com/2017/04/29/agile-coach-camp-2017/Amitai Schleier2017-05-02T17:54:25Z2017-04-30T01:34:51Z
<p><a href="https://agilecoachcampus.com">Agile Coach Camp US</a> is in New York, at <a href="https://www.spotify.com">Spotify</a> (!).
It’s my second Coach Camp.
Between seeing lots of familiar faces from <a href="https://schmonz.com/2016/10/16/agile-coach-camp/">my first</a> and elsewhere (plus lots of new ones), getting and giving lots of hugs, and not needing a hotel room in order to attend or even to take an afternoon nap, I feel completely at home.
These are my people, and to get to spend time with them as a <a href="https://schmonz.com/2017/04/17/now/">newly independent consultant</a> is imbued with possibility.
If we find our interactions leading us to wish we could collaborate professionally — well, now we can.</p>
<p><a href="https://twitter.com/msilpala"><img src="https://schmonz.com/2017/04/29/msilpala-mob.jpg" width="300" height="400" alt="Mobbing with Markus" title="Mobbing with Markus" class="img" align="right" /></a></p>
<p>Today <a href="https://twitter.com/onealexharms">Alex Harms</a> and I convened a session on programming for non-programmers.
We did</p>
<ul>
<li><a href="http://c2.com/cgi/wiki?FizzBuzzTest">FizzBuzz</a></li>
<li>in <a href="https://try-python.appspot.com">Python</a></li>
<li>in <a href="http://cyber-dojo.org">Cyber-Dojo</a></li>
<li>in <a href="https://twitter.com/keithb_b">Keith Braithwaite</a>’s <a href="https://cumulative-hypotheses.org/2011/08/30/tdd-as-if-you-meant-it/">TDD As If You Meant It</a> style</li>
<li>as a <a href="https://agilein3minut.es/32">Mob</a></li>
</ul>
<p>And then <a href="https://twitter.com/ryanripley">Ryan Ripley</a> and I asked for help with our new talk, “The Care and Feeding of T-Shaped People”, which’ll <a href="https://schmonz.com/talk/2017-basd/">debut on Monday at Big Apple Scrum Day</a>.
We got lots of thoughtful and thought-provoking suggestions, some of which will make it into our 45-minute session.
Next time I’m lucky enough to have several people willing to help design a conference presentation, I’ll try to involve them earlier.</p>
<p>Tomorrow I plan to join <a href="https://twitter.com/msilpala">Markus Silpala</a>’s session, which is also aimed at giving folks who don’t usually write code (or haven’t in a while, or ever) a taste of what it’s like. All of us are grateful Markus is <a href="https://markus.silpala.com">recovering well</a> and is back with us.</p>
<p><em>Update:</em> I did join Markus’s session (pictured), as did several other skilled programmers and technical coaches, so the learnings came from several directions. It was great.</p>
Agile Alliance Technical Conference 2017: Cross-Platform Deploymenthttps://schmonz.com/2017/04/20/aatc-2017-cross-platform-deployment/Amitai Schleier2017-04-20T15:44:49Z2017-04-20T04:00:00Z
<p>At the <a href="https://www.agilealliance.org/agile-alliance-technical-conference-2017/">second Agile Alliance Technical Conference</a>,
I facilitated a DevOps-themed workshop called
“Cross-Platform Full-Stack Deployment with pkgsrc”.</p>
<ul>
<li><a href="https://aatc2017.sched.com/event/5c81d05097613f4815e3c7c2b86569e5">Abstract</a></li>
<li><a href="https://schmonz.com/2017/04/20/aatc-2017-cross-platform-deployment/slides/">Slides</a></li>
</ul>
<p>I loved <a href="https://schmonz.com/2016/04/10/aatc-2016-devops-dojo-discussion-panel/">being at the first one last year</a>, and it’s great to be back with a comfortably large number of people who feel — as I do — that Agile software development centers on <a href="https://schmonz.com/2016/10/16/agile-coach-camp/">doing it and helping others do it</a>.</p>
<hr />
<p>Does your company deliver valuable software? Maybe I can help.
Consulting, coaching, training.</p>
Automation for mail hostinghttps://schmonz.com/2017/03/27/automation-for-mail-hosting/Amitai Schleier2023-11-15T15:53:47Z2017-03-28T18:26:58Z
<h2>Previously</h2>
<ul>
<li><a href="https://schmonz.com/2016/09/11/refactorings-for-web-hosting/">Refactorings for web hosting</a></li>
<li><a href="https://schmonz.com/2016/11/23/automation-for-web-hosting/">Automation for web hosting</a></li>
<li><a href="https://schmonz.com/2017/01/18/qmail-smtp-auth-tls-redux/">qmail + SMTP AUTH + TLS redux</a></li>
</ul>
<h2>Intro</h2>
<p>As a sysadmin (”Ops”), I’ve had root responsibilities on NetBSD, FreeBSD, OpenBSD, Mac OS X, Solaris, and weirder systems like IRIX, AIX, and Linux.
As a developer (”Dev”), I’ve used a bunch of those, sometimes without root privileges.
Across all these contexts, to do my job reliably and productively, I found it often helped to use a cross-platform Unix package manager.</p>
<p>In the course of a couple decades of running mail servers, for pay and for myself, I’ve made a “DevOps” habit of observing and automating.
This post is about how I recently synthesized old skills with new ones to make a big improvement in my mail-hosting automation.</p>
<p>Are any of your contexts like mine?
Read on.
You may conclude that my approach and/or tools could help you in your work.
If so, maybe you can <a href="https://schmonz.com/talk/2017-aatc/">come to my hands-on workshop in a few weeks</a>.
If not, maybe we can work together another way.</p>
<h2>Background</h2>
<p>I’ve been running <a href="https://www.netbsd.org">NetBSD</a> for 20 years: from <a href="https://www.netbsd.org/releases/formal-1.1/NetBSD-1.1.html">1.1</a> in high school to <a href="https://www.netbsd.org/releases/formal-7/NetBSD-7.1.html">7.1, released two weeks ago</a>.
NetBSD’s continued growth and relevance is one of the reasons I keep choosing to run it.</p>
<p>I’ve been running <a href="http://cr.yp.to/qmail.html">qmail</a> for almost as long: from 1.03 in my first job to 1.03 (plus a few third-party patches) today.
qmail’s lack of continued growth and relevance makes it harder for me to keep choosing to run it. Yet I still do.</p>
<p>A friend wondered, in response to a recent post about <a href="https://schmonz.com/2017/01/18/qmail-smtp-auth-tls-redux/">refactoring my mail-server configuration</a>, why I continue to make this choice when <a href="https://en.wikipedia.org/wiki/Postfix%5F%28software%29">Postfix</a> is ubiquitous and easy to work with.
My friend made a good point.
Postfix is the default MTA shipped with many operating systems — including NetBSD — and on the few occasions I’ve needed to tweak Postfix from its default behavior, it’s been easy enough.
If it’d existed when my first employer and I needed an alternative to <a href="https://en.wikipedia.org/wiki/Sendmail">Sendmail</a>, I’m sure I’d be happily running Postfix today.</p>
<p>But qmail 1.03 <em>did</em> exist by 1998.
And by force of its <a href="https://cr.yp.to/qmail/pictures.html">compellingly different and better architecture</a>, I found it both necessary and possible to understand <a href="https://en.wikipedia.org/wiki/SMTP">SMTP</a>, the nuances of running a production mail server on the open Internet, and the details that go into safely and reliably delivering a single message.
qmail’s author, <a href="https://cr.yp.to/djb.html">Dan Bernstein</a>, also invented a new <a href="https://cr.yp.to/proto/maildir.html">Maildir storage format</a> whose desirable runtime behaviors delivered me a message about the significance of finding the right data structure — one of the few lessons I managed to learn in <a href="https://schmonz.com/1997/01/13/biography/">college-the-first-time</a>.
(A few years later, Bernstein’s <a href="http://cr.yp.to/djbdns.html">djbdns</a> would teach me very similar lessons about <a href="https://en.wikipedia.org/wiki/DNS">DNS</a>.)</p>
<p>Anywho, I responded to my friend with the offhand rationale that my choice to continue with qmail stems from</p>
<blockquote><p>A mélange of</p>
<ul>
<li>Laziness (possibly the <a href="http://c2.com/cgi/wiki?FalseLaziness">false kind</a>)</li>
<li>Anti-<a href="https://en.wikipedia.org/wiki/monoculture">monoculture</a> activism (possibly of the <a href="http://moduscooperandi.com/blog/is-retrospective-coherence-a-cognitive-bias/">bullshit retroactive justification kind</a>), and</li>
<li>Enjoying the very occasional small effort it takes to keep things going to my liking (pretty sure this is genuine).</li>
</ul>
</blockquote>
<p>As my <a href="https://schmonz.com/2016/11/23/automation-for-web-hosting/">weekly server update</a> has grown more streamlined, the sharp edges of the qmail package have grown more salient.
And a couple weeks ago, they scratched a friend trying to install it on a fresh NetBSD instance.
So I wanted to take another stab at making things easier for my friend (and future-me, who I hope to be friends with).</p>
<p>It went well.
Now that I’ve composed NetBSD and qmail into their finest two-part harmony yet, I’d like to tell you a tale of software archaeology, a tale replete with flexibility, persuasion, persistence, and very occasional free time.
And possibly just a smidge of <a href="https://en.wikipedia.org/wiki/Sunk%20Cost%20Fallacy">Sunk Cost Fallacy</a>.</p>
<p>It’s not my shortest story.
(Did I mention Sunk Cost Fallacy?)
But if the problems I’ve tried to solve sound like problems you’re trying to solve, there’s likely something in it for you.</p>
<h2>1997: Build from source</h2>
<p>What’s wrong with installing software from source code by manually following its instructions?
When you’re trying to learn how it works, not much at all.
If you do this with qmail, you’ll learn how it</p>
<ul>
<li>Makes use of several Unix users and groups for security partitioning,</li>
<li>Requires that those users and groups be created before it’ll compile,</li>
<li>Installs its programs and documentation to locations that need additional configuration to be useful to users, and</li>
<li>Expects its daemons to be managed in a way that almost certainly departs significantly from your OS’s usual (such as <a href="https://wiki.netbsd.org/guide/rc/">NetBSD’s <code>rc.d</code> subsystem</a>).</li>
</ul>
<p>When you’re trying to learn how qmail works, these are all important things to know.
When you’re trying to integrate it into your systems, your habits, and your automations, these are important things to be able to forget.</p>
<p>There’s an abstraction layer for hiding such details: a package manager.
NetBSD’s is <a href="https://youtu.be/tyQvjKqXA0Y">spelled “pkgsrc” and pronounced “package source”</a>.</p>
<h2>2002: Maybe build from pkgsrc</h2>
<p>After submitting a series of patch requests to pkgsrc, it was just about exactly 15 years ago that I was invited to commit directly to the repository.
As a project, pkgsrc was mainly focused on automating dependencies, builds, installs, and uninstalls of third-party code from source code.
As a developer and user, so was I.</p>
<p>We had a package of qmail.
It was pretty rough.
It jumped through hoops to create those users and groups early enough in the build, it didn’t place qmail’s programs or documentation in users’ existing paths, it didn’t offer NetBSD-style <code>rc.d</code> scripts, and if memory serves, uninstalling it didn’t really uninstall anything.
And while pkgsrc could be used to generate binary packages, the qmail package very sensibly refused to.</p>
<p>My <a href="https://github.com/NetBSD/pkgsrc/commit/e0d07f05de92a892ef30eb4d3d27683ad2a7a6fb">first commit to qmail</a> (<a href="http://mail-index.netbsd.org/pkgsrc-changes/2002/07/28/0008.html">original</a>) was from <a href="https://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=15326">a future developer’s patch request</a>.
He provided an <code>rc.d</code> script that started and stopped <code>qmail-send</code>. Pretty cool.</p>
<h2>2004: Definitely build from pkgsrc</h2>
<p>Someday I hoped to produce a binary package that worked well.
If I could start making our source package work well, I might get there someday.</p>
<p>One of DJB’s conditions for redistributions of qmail was that all files must be addressable in their documented default locations under the <code>/var/qmail</code> hierarchy.
One of pkgsrc’s conditions for uninstalling files was that they must be stored under the <code>/usr/pkg</code> hierarchy.
And, of course, if the programs and manual pages were installed into <code>/usr/pkg</code>, they’d be instantly available to users.
Inspired by an <a href="https://lists.gt.net/qmail/users/187#187">idea from Matthew R. Green on the qmail discussion list</a>, I taught the package to create symlinks under <code>/var/qmail</code> before running qmail’s installer, which then followed the symlinks.
For example, a symlink in <code>/var/qmail/bin</code> pointing to <code>/usr/pkg/bin</code> induced qmail programs to install into <code>/usr/pkg/bin</code> as pkgsrc users would expect, while also being accessible via <code>/var/qmail/bin</code> as qmail users would expect.</p>
<p>Score!
The symlink-before-install trick provided the basis for <a href="https://github.com/NetBSD/pkgsrc/commit/b5be95a30c098df6eed356ec48c61e6b3ce274d5">many contemporaneous improvements</a> (<a href="http://mail-index.netbsd.org/pkgsrc-changes/2004/07/21/0034.html">original</a>) and also <a href="https://github.com/NetBSD/pkgsrc/commit/4e5cc1592cc2fc1926a46d9a42a75c2b5eb8f099">obviated the need for path-related hacks</a> (<a href="http://mail-index.netbsd.org/pkgsrc-changes/2004/07/21/0045.html">original</a>) in a handful of packages depending on qmail. After a lot of careful work, our package suddenly provided a rather high-functioning qmail installation.</p>
<p>It even followed a whole bunch of the recommendations codified by the qmail community elders in the <a href="http://www.lifewithqmail.org/lwq.html">Life with qmail</a> configuration guide.
There was one big recommendation, by virtue of its mere existence, that it could not follow: the qmail elders strongly recommended avoiding packages entirely, for reasons like those in the “1997: Build from source” section above.
Nonetheless, I <a href="http://copilotco.com/mail-archives/qmail.2004/msg05640.html">asked for their review and feedback</a>, received it, and <a href="http://copilotco.com/mail-archives/qmail.2004/msg05805.html">applied it</a>.
The gist: I <a href="https://github.com/NetBSD/pkgsrc/commit/144fc3039e8466e40cef289a1fc42f620c16505e">removed my NetBSD-specific customizations from the qmail package</a> (<a href="http://mail-index.netbsd.org/pkgsrc-changes/2004/08/02/0010.html">original</a>) and <a href="https://github.com/NetBSD/pkgsrc/commit/116990d25b8458f556a7c8abf55639b8c2cc26d1">re-added them as a new qmail-run package</a> (<a href="http://mail-index.netbsd.org/pkgsrc-changes/2004/08/02/0011.html">original</a>), along with other tweaks intended to help users distinguish standard stuff that the community could support from custom stuff they should ask me about directly.
(I wrote about the experience as a <a href="https://schmonz.com/2005/01/01/mit-application-optional-essay/">college-the-second-time application essay</a>.
Wound up going <a href="https://schmonz.com/2005/07/05/what-the-curtains/">somewhere else</a>.)</p>
<p>At this point, as I <a href="https://schmonz.com/2005/05/08/pkgsrccon-2005-packaging-complex-software/">explained</a> at a <a href="https://schmonz.com/2007/04/29/pkgsrccon-2007-packaging-djbware/">couple pkgsrcCons</a>, for most “djbware” in pkgsrc, we could generate useful binary packages, but weren’t confident that we could meet <a href="https://web.archive.org/web/20060207000727/http://cr.yp.to:80/distributors.html">DJB’s conditions for distributors</a>.</p>
<p>For qmail in particular, binary packages were less useful. A qmail binary package built on one machine could run on another if and only if the numeric IDs of qmail’s users and groups were the same on both systems, which is not only mathematically exceedingly unlikely to happen at random, but often difficult to arrange for in the wild.
FreeBSD Ports, among others, worked around this by <a href="https://svnweb.freebsd.org/ports/head/mail/qmail/files/patch-auto_uids-c-dist?view=markup&pathrev=277915">permanently allocating a non-configurable set of IDs</a>.
Their decision could never have made sense for pkgsrc, where besides NetBSD we run on <a href="http://pkgsrc.org/#platforms">all manner of operating systems</a> we don’t control.
To fix it, we’d really have to fix it.
But applying patches that changed visible behavior of the installed software was clearly against the redistribution conditions.</p>
<p>In late 2007, <a href="http://cr.yp.to/qmail/dist.html">DJB placed qmail in the public domain</a>.
It became possible to apply the usual consideration for the costs and benefits of patching our package.</p>
<p>I was busy with <a href="https://schmonz.com/2005/09/07/first-week-of-classes/">college-the-second-time</a>, particularly so with <a href="https://schmonz.com/2007/12/17/schlair-student-piece-1/">validating my goal to be a composer</a>.
For my own needs, I continued using source packages.</p>
<h2>2011: Maybe install from a custom binary package</h2>
<p>Motivated by the desire to improve the quality of our binary packages, pkgsrc grew an idea of <code>DESTDIR</code>.
Source packages that knew about <code>DESTDIR</code> no longer installed directly onto the running system, but rather into a temporary staging directory from which a binary package was generated and <em>then</em> installed.
(This was not a new idea; OpenBSD Ports, among others, <a href="https://www.openbsd.org/faq/ports/differences.html#Fake">beat us to it</a>.)
Once all our packages had been adapted, we could remove the old way.
Then even source-centric developers like myself would notice when our binary packages weren’t working right.</p>
<p>I liked the sound of that and didn’t want to hold up progress, so I made what I thought were the <a href="https://github.com/NetBSD/pkgsrc/commit/21221db5ee910b24dc73021230738bdcf18a16b2">smallest possible changes to minimally support <code>DESTDIR</code></a> (<a href="http://mail-index.netbsd.org/pkgsrc-changes/2011/06/07/msg056339.html">original</a>).</p>
<p>Turns out, when the <a href="https://github.com/NetBSD/pkgsrc/commit/627877e41529ffa62ee186ecb6bd26676f0652c3"><code>DESTDIR</code> rapture finally came</a> (<a href="http://mail-index.netbsd.org/pkgsrc-changes/2015/12/27/msg134036.html">original</a>) in late 2015, I had not arranged for the qmail binary package to initialize its message queue.</p>
<p>The regression in our binary package occurred because my brain continued to assume it was not worth anyone’s time to try to use it, even though the meaning of the coming rapture was <em>specifically</em> that one day all package installs would be binary package installs.</p>
<p>The missing queue went unnoticed because on the mail server where I would’ve quickly noticed it, it hadn’t been missing!
It was still there from before the <code>DESTDIR</code> rapture, when I’d first installed from the old-style source package.</p>
<p>(It also went unnoticed because very few people run qmail from pkgsrc.
Even when lots of people ran qmail, pkgsrc’s package wasn’t great, pkgsrc itself was relatively unpopular, and running qmail from any sort of package was, as mentioned previously, strongly discouraged.)</p>
<h2>2017: Definitely install from the pre-built 2017Q1 binary package</h2>
<p>In late 2014, before everything went <code>DESTDIR</code>, I stopped managing packages from source directly on my server — it ate CPU, I/O, and disk space I preferred to allocate to <em>serving</em> — and <a href="https://github.com/schmonz/dotfiles/commit/2ed1cc572dfe530c2bd59f71bade83c32730822a">started building binaries in a VM on my local development machine</a>.
Since I had chosen to generate binary packages, I had to configure qmail to <a href="https://github.com/schmonz/dotfiles/commit/2ed1cc572dfe530c2bd59f71bade83c32730822a#diff-cd9c66ef1da394262295f5261e6376a7R70">build with numeric user and group IDs matching those already present on my server</a>.</p>
<p>A couple weeks ago, trying to help my friend, I turned up a <a href="ftp://ftp.foxharp.boston.ma.us/pub/pgf/qmail/getpwnam.patch">patch by Paul Fox</a> that taught an early version of qmail to look up its numeric IDs at runtime.
Using <a href="https://schmonz.com/2017/02/16/how-to-learn-c-part-2/">my growing C skills</a>, I ported it forward and <a href="https://github.com/NetBSD/pkgsrc/commit/7197840de1a401793fdf954de0cde284942731c8">added it to pkgsrc</a> (<a href="http://mail-index.netbsd.org/pkgsrc-changes/2017/03/10/msg153868.html">original</a>).</p>
<p>With the patch, qmail’s compile process no longer needed any users or groups to exist.
To also avoid needing them in the install process, I recorded the permissions qmail’s installer wanted to set, linked the installer with a fake <code>chown()</code> that does nothing, then applied pkgsrc’s mechanism for setting all the desired special permissions when installing a binary package.
(I used the trick in <a href="https://schmonz.com/2013/03/10/permanent-cvs-temporary-git/">Permanent CVS, temporary Git</a> to work on a git branch, experiment freely, and keep only my best commits.)</p>
<p>I thought I was just about done solving my friend’s problem.
On a test system, I cleaned out all vestiges of qmail having ever been there, then built and installed it.
That’s when I noticed there was no queue.</p>
<p>Huh?</p>
<p><a href="https://schmonz.com/talk/20160214-agile-for-humans/">Oh</a>.</p>
<p>I don’t remember slapping my forehead, which might not mean I didn’t.</p>
<p>After over a year of breakage, I finally noticed my nearly six-year-old mistake.
Eager to fix it and ship it, and not seeing an elegant solution, I settled for a less elegant one.
<code>queue-fix</code> is a third-party tool that reuses qmail’s code to repair or create a queue.
I added it as a dependency and scripted it to create the queue if missing.</p>
<p>As far as I can tell, the result of naively installing our qmail binary package now matches file-for-file, permission-for-permission, what you’d get installing it from source by hand.
Also, it works exactly as well as it always has for me in production.
The <a href="https://github.com/NetBSD/pkgsrc/commit/92470adb11642ca1daf440a6419809c53b912a55">triumphant pkgsrc commit message</a> (<a href="http://mail-index.netbsd.org/pkgsrc-changes/2017/03/20/msg154489.html">original</a>) concludes:</p>
<blockquote><p>A typical binary package should now:</p>
<ol>
<li>Install on any other system of matching OS and architecture,</li>
<li>Not need matching numeric UIDs and GIDs to do so, and</li>
<li>Be usable in production.</li>
</ol>
<p>You know, like any other binary package.</p></blockquote>
<p>The latest soon-to-be-released pkgsrc stable branch will include production-ready qmail binary packages for many popular platforms.
Especially if you’re on NetBSD, but also on other platforms, <code>pkg_add qmail-run</code> will make you wonder what all this fuss was ever about.</p>
<p>Exactly the point!</p>
<p>Once 2017Q1 is out, the main reasons I can think of <em>not</em> to get your qmail from our published binary packages are:</p>
<ol>
<li>You don’t use pkgsrc or NetBSD (or qmail)</li>
<li>You don’t see a binary qmail package for your OS and architecture</li>
<li>You need a qmail with non-default <code>PKG_OPTIONS</code></li>
</ol>
<p>With the default <code>PKG_OPTIONS</code>, you’ll get <a href="https://qmail.notqmail.org/netqmail/">netqmail</a> with <a href="http://www.memoryhole.net/qmail/#oversize-dns">Christopher K. Davis’s oversize DNS</a> and <a href="http://code.dogmap.org/qmail/#realrcptto">Paul Jarc’s realrcptto</a> patches.</p>
<p><em>2017/04/04 Update:</em> Here’s the <a href="http://mail-index.netbsd.org/netbsd-announce/2017/04/04/msg000265.html">2017Q1 release announcement</a>.</p>
<p><em>2017/04/10 Update:</em> Binary qmail packages aren’t showing up in the <a href="http://ftp.netbsd.org/pub/pkgsrc/packages/NetBSD/">usual places</a>.
A dependency on <a href="https://cr.yp.to/checkpwd.html">checkpassword</a> — which, not being under any license, is not under one of the licenses pkgsrc deems acceptable by default — is preventing bulk builds from publishing qmail binaries.
On the off chance DJB intends to include checkpassword in the <a href="https://cr.yp.to/distributors.html">list of software he has placed in the public domain</a>, I’ve emailed to request that he do so now.
In the meanwhile, I’ve <a href="https://github.com/NetBSD/pkgsrc/commit/380be754cd5a603f720d12980bdad3ef50457956">removed the checkpassword dependency</a> (<a href="http://mail-index.netbsd.org/pkgsrc-changes/2017/04/08/msg155076.html">original</a>) and requested the change be applied to the 2017Q1 branch.
When it’s been applied, we should start seeing qmail binary packages.
Likewise qmail-run and its dependency on <code>ofmipd</code> from <a href="https://cr.yp.to/mess822.html">mess822</a>, which I <a href="https://github.com/NetBSD/pkgsrc/commit/1ae1eeb453800ceb3ccaca736cecae463c15c847">made optional, off by default</a> (<a href="http://mail-index.netbsd.org/pkgsrc-changes/2017/04/09/msg155139.html">original</a>).</p>
<p><em>2017/04/18 Update:</em> Binary packages are here!
Running qmail on NetBSD <a href="https://youtu.be/4FDdKsVAwvk">takes two minutes</a>.</p>
<h2>Why did I make this effort?</h2>
<p>My mail server had been running fine before.
As far as I can tell, it’s running exactly as fine now.</p>
<p>My friend who likes qmail is having trouble convincing himself it’s still practical to run his own mail server at all.</p>
<p>My friend who wonders why I stick with qmail, were he to read this, would surely be feeling a renewed sense of wonder right about now.</p>
<p>I’m not.
I’ve long been investing myself in NetBSD, pkgsrc, and qmail, and they continue to feel like good investments.
Someday there may be a new effect I want to accomplish with qmail whose marginal cost I won’t enjoy paying.
When that happens, I’ll reevaluate alternatives and the cost of switching to them.</p>
<p>In the meanwhile, next time I install qmail, I’m happy to say there’s an excellent chance none of the experience and expertise that went into the writing of this post will be called for.
Having shipped working code, I get to evict some longstanding want-to-dos and oh-yeah-that-weird-things from residence in my brain (and <a href="https://github.com/schmonz/dotfiles/commit/2dc6f619dadf952fd1c67d11239ac17209205a96">cruft from my weekly build config</a>), and I get positive reinforcement that further improvements are also worth trying for.
Both of these have the effect of increasing my overall <a href="https://schmonz.com/2013/06/10/area-under-the-curve/">area under the curve</a>.</p>
<p>The more I can simplify and automate, the fewer attention-slices I can require of myself, the more likely <a href="https://schmonz.com/2015/07/29/enthusiasm-engineering/">my desired outcomes persist</a> when my circumstances change.
That’s pretty important to me right about now.</p>
<h2>What I might do next</h2>
<p>qmail lets the <em>names</em> of its users and groups be configured at build time.
pkgsrc could pretty easily support this, retaining the current names as defaults.</p>
<p>Some of qmail’s attendant packages can optionally build with patches to add <a href="https://en.wikipedia.org/wiki/IPv6">IPv6</a> support.
Enabling IPv6 mail service would require at least an optional patch to qmail itself.</p>
<p>Patches and/or wrapper programs exist to implement <a href="https://en.wikipedia.org/wiki/Sender%20Policy%20Framework">Sender Policy Framework</a>, <a href="https://en.wikipedia.org/wiki/Sender%20Rewriting%20Scheme">Sender Rewriting Scheme</a>, and <a href="https://en.wikipedia.org/wiki/DomainKeys%20Identified%20Mail">DomainKeys Identified Mail</a>.
It may be useful to optionally include them.</p>
<p><em>Update:</em> <a href="https://github.com/NetBSD/pkgsrc/commit/35020412b03426677082d8e3b1c43eed7d639f44">account names are configurable</a> (<a href="http://mail-index.netbsd.org/pkgsrc-changes/2017/04/04/msg154825.html">original</a>), <a href="https://github.com/NetBSD/pkgsrc/commit/1d0a169b45a3ad7dfdca43ff36176875098d630a">SRS is optional</a> (<a href="http://mail-index.netbsd.org/pkgsrc-changes/2017/03/31/msg154759.html">original</a>), and <a href="https://github.com/NetBSD/pkgsrc/commit/bd709f8fce68618ac00e55e388d517b2fa4e66dc">qmail-remote can be wrapped easily</a> (<a href="http://mail-index.netbsd.org/pkgsrc-changes/2017/05/22/msg157166.html">original</a>).</p>
<h2>What you might do next</h2>
<p>What do you think?
Could you benefit from applying some of these <a href="https://en.wikipedia.org/wiki/DevOps">DevOps</a> tools and practices?
I’m teaching a <a href="https://schmonz.com/talk/2017-aatc/">hands-on workshop at the upcoming Agile Alliance Technical Conference</a> where you can learn them.
And/or teach me how I can benefit from letting go of qmail. <img src="https://schmonz.com/smileys/smile4.png" alt=";-)" /></p>
How to meet me (spring 2017 edition)https://schmonz.com/2017/03/16/how-to-meet-me-spring-2017-edition/Amitai Schleier2018-04-14T22:00:32Z2017-03-16T13:58:48Z
<p>There’s a link in the sidebar where you can
<a href="https://schmonz.com/link/coffee/">buy me a fancy coffee</a>,
but I’d much rather treat you, dear reader, to the beverage of your choice.
Here are some upcoming chances for us to do that:</p>
<p><strong>Boston</strong>, April 19-21: <a href="https://schmonz.com/talk/2017-aatc/">Agile Alliance Technical Conference</a></p>
<p><strong>New York City</strong>, April 28-30: <a href="https://schmonz.com/talk/2017-agilecoachcamp/">Agile Coach Camp</a></p>
<p><strong>New York City</strong>, May 1: <a href="https://schmonz.com/talk/2017-basd/">Big Apple Scrum Day</a></p>
<p><strong>Ann Arbor</strong>, May 4-5: <a href="https://schmonz.com/talk/2017-aab/">Agile and Beyond</a></p>
<p>Hope to see you. If not one of these, then another time.</p>
How to manage dependencieshttps://schmonz.com/2017/03/08/how-to-manage-dependencies/Amitai Schleier2017-03-12T19:43:57Z2017-03-08T18:11:42Z
<p>When solving a problem, we often take advantage of known solutions.
For sufficiently small and repeatable problems, we can buy solutions at
the store.
Usually they don’t solve the entire problem all by themselves.
Bleach doesn’t clean the toilet; <em>I</em> do, with the help of bleach and
other tools.</p>
<p>In software problem-solving parlance, bleach is a “dependency”.
It doesn’t have to be.
I’m free to try to solve my problem using some other product.
But for as long as I believe bleach is what I need — maybe because it
gets me there sooner and more reliably than anything else I can think of
— then I’m depending on it.</p>
<p>I’m also free to try to solve my problem using no products whatsoever.
It might sound like an unqualified bad decision to get in there with my
fingernails.
But what if bleach and scrub brushes haven’t been invented yet?
What if they have, but the store can’t reliably stock them?
What if they can, but I can’t reliably get to the store or pay for it?
Or what if cleaning toilets is my core business, and my main
differentiator is artisanal hand-maintained porcelain?</p>
<p>Whether to add a new dependency, and if so which, are two of the
<a href="https://agilein3minut.es/4">many, many decisions</a>
we make every day in software development.
We can have reasons for generally preferring to keep the total number small.
But however small that is, it will never reach zero.
For me to clean the toilet depends, at minimum, on whatever it takes to
keep me alive, able, and present.
And on the privilege of having a toilet.</p>
<h2>Minimize the number</h2>
<p>One Agile strategy for reducing dependency risk is to
<a href="http://c2.com/cgi/wiki?DoTheSimplestThingThatCouldPossiblyWork">do the simplest thing that could possibly work</a>.
Sometimes that can mean copy-pasting a function from
<a href="http://stackoverflow.com">Stack Overflow</a>
instead of depending on a third-party library for it.</p>
<p>Another Agile strategy for reducing dependency risk is to
<a href="http://c2.com/cgi/wiki?KeepItSimpleMinimalization">maximize the amount of work not done</a>.
Sometimes we can deliberately decide that a sub-problem isn’t worth solving.</p>
<p>The only way to entirely avoid dependencies is to entirely avoid solving problems.</p>
<p>Then we’d need new jobs, which would be a problem. Sort of a circular dependency.</p>
<p>We need techniques for living with dependencies more effectively.</p>
<blockquote><p>A dependency isn’t just one more line in a file. It’s</p>
<ul>
<li>An expected interface (adapter pattern)</li>
<li>Noticing when it changes (contract tests)<br />
—<a href="https://twitter.com/schmonz/status/837699431545913344">Moi</a></li>
</ul>
</blockquote>
<div class="notebox">
<p>Amber is the force behind
<a href="http://selfconference.org/">Self.conference</a>,
which I’ve
<a href="https://schmonz.com/2015/06/03/self-conf-2015-almost-self-less/">spoken at</a>
and
<a href="https://schmonz.com/2016/04/06/work-not-done/">attended</a>
and which just posted its
<a href="http://selfconference.org/sessions">list of sessions and speakers</a>.
If you’re a human involved in the making of software, I highly recommend
it, and can give you a code good for 10% off your ticket.</p>
</div>
<p>And also all of its transitive dependencies — dependencies can have
dependencies too — as
<a href="https://twitter.com/crebma">Amber Conville</a>
reminded me.</p>
<p>In the moment where we decide to add one more dependency, it <em>could</em> look
like just one more line in a file specifying names and minimum versions.
In the moment where we finish the feature and get it out the door, that
<em>could</em> feel like enough.</p>
<h2><a href="https://en.wikipedia.org/wiki/The%20Serenity%20Now">Dependency now, dependency later</a></h2>
<p>We may think we’ve chosen to depend on something as it is today.
That’s true.</p>
<p>We may think we can cheaply remove or replace it tomorrow if we have a
better idea.
That might be true too.</p>
<p>We may even think we can cheaply remove or replace it in a few months if
need be.
That’s a lot less likely to be true.</p>
<p>Why?
If we’re not
<a href="https://agilein3minut.es/8">careful</a>,
our expectations of it will be dispersed throughout our code.
If it then changes in a way that fails to meet our expectations, we’ll
have to be expensively careful to adjust to it.
If our own expectations need to change, we’ll have to be expensively
careful about how we change them.
And if we hadn’t been careful, the way we’ll find out we suddenly need
to be expensively careful might well come at an expensive time: in
production.</p>
<h2>Maximize control</h2>
<p>In software, when we <em>are</em> careful, we can arrange to reduce our
dependency risk:</p>
<div class="notebox">
<p>I follow similar reasoning when I
<a href="https://schmonz.com/2016/11/23/automation-for-web-hosting/">update all the dependencies on my server every week</a>.
The tool I use for this
<a href="http://julio.meroh.net/2017/02/introducing-pkg_comp-2.0.html">recently underwent a major upgrade</a>.
So last week I did my build on Friday, a little early.
Over the weekend, I made the fewest possible changes to bring forward my
existing configuration, did a build with the new tool, found a
regression, did another build, went to production, and reported the fix.
If it hadn’t worked, I’d still have another week to figure it out or
revert without interrupting my cadence.
But since it did work, my dependency on the build tool has been safely
managed through some breaking changes.
Next week, if I feel like it, I can see about taking advantage of
some of the new features.</p>
</div>
<p><strong>Adapter pattern:</strong>
Define the calls we want to be able to make, then implement them by
backing our interface with the dependency.
Lets us adjust faster when something changes.
(<a href="https://en.wikipedia.org/wiki/Adapter%20pattern">more on Wikipedia</a>)</p>
<p><strong>Contract tests:</strong>
For each call our adapter makes to the dependency, write automated tests
for the behavior we’re relying on.
Tells us sooner when adjustments must be made.
(more at <a href="https://martinfowler.com/bliki/IntegrationContractTest.html">Martin Fowler’s Bliki</a>)</p>
<p>Given these techniques, another Agile risk-mitigation strategy clicks
into place:
<a href="https://martinfowler.com/bliki/FrequencyReducesDifficulty.html">If it hurts, do it more often</a>.
Figure out how to get notified when any of your dependencies have
been updated.
When you get a notification, before you do anything else, update your
code to use the new version.
If tests break, before you do anything else, fix them.
If it’s not clear how to do that, before you do anything else, raise the
risk with your team.
By uncovering the dependency problem as early as possible, you’ve
maximized your options for handling it well.</p>
<p>Once your tests are green, ship it as soon as you can.
If a dependency problem somehow slips past your tests into production,
it’ll be relatively easy to find, because you’ve narrowed the search
space considerably.
Roll back first, if you have to.
Then test-drive a bugfix and ship it again.</p>
<p>The goal here, given that
<a href="https://agilein3minut.es/26">surprises</a>
are inevitable, is to
<a href="https://agilein3minut.es/22">control</a>
the influx of entropy into your system.
Track updates and put out releases less frequently, and the surprises
get larger, take longer to track down, and offer fewer, more expensive
options for resolution.
Or
<a href="https://schmonz.com/2017/01/05/new-years-slack/">reduce batch size</a>
to get the opposite effects.</p>
<h2>Sorry, I only understand toilets</h2>
<p>No problem.
To keep your delivery schedule from getting clogged, flush regularly.</p>
<p>Here’s how I documented my reasoning for a product I both managed and
<a href="https://schmonz.com/2015/03/13/when-is-being-technical-lead-a-good-decision/">tech lead</a>-ed:</p>
<blockquote><h3>Why release every month?</h3>
<ol>
<li>Each release contains less total change. Why this matters:
<ul>
<li>Code change is risky. Smaller increments of change help manage
the risk.</li>
<li>If a bug survives into production, finding it is easier, so fixing
it is faster.</li>
<li>If a feature doesn’t meet expected requirements, customers will
complain earlier, so fixing it can happen earlier.</li>
</ul>
</li>
<li>The next release is always soon. Why this matters:
<ul>
<li>Small features (or bugfixes) don’t have to wait long to get
into customers’ hands.</li>
<li>Big features can only be delivered via composable solutions,
implemented one tractable piece at a time.</li>
<li>Each change <em>can</em> be tested well because it’s small. Each
change <em>must</em> be tested well because it’s about to ship.</li>
<li>The master branch is always production-ready. We can always
ship what we have right now.</li>
</ul>
</li>
<li>The previous release is always recent. Why this matters:
<ul>
<li>Release deployment is risky. More frequent practice — and
being able to remember what went wrong last time — helps
manage the risk.</li>
</ul>
</li>
</ol>
<h3>Why skip a month?</h3>
<ol>
<li>If Operations is fully booked on other product releases and
doesn’t have someone available.</li>
<li>If up- or downstream systems are changing and it’s too risky to
change ours at the same time.</li>
<li>If a particular big feature simply can’t be decomposed into
month-sized chunks of work. (This is very rare.)</li>
</ol>
<h3>When do you notify Operations of new dependencies to package?</h3>
<p>By Thursday afternoon, the day before <a href="https://agilein3minut.es/25">release day</a>,
we have a complete or
near-complete list. In general, we try to declare each codebase’s dependencies
in one place so that we can simply diff it against the previous release
to see everything that’s new (updated counts as new). Then we list
those dependencies on the release’s wiki page and notify our local Operations
representative.</p>
<p>Occasionally a last-minute code change will add another dependency or
two. Asking Operations to build one or two more last-minute packages
isn’t terrible if we don’t do it often. More packages than that means
the change probably isn’t a smart last-minute choice.</p>
<h3>Why are you always upgrading to the latest available dependencies?</h3>
<p>Because we depend on them.</p>
<p>Less elliptical answer: because they’re code we rely on but don’t
control. Therefore we’re especially susceptible to changes in
them. Therefore we minimize our exposure by staying up to date whenever
possible, giving us the easiest possible rollback option when (inevitably)
an unexpected problem occurs.</p>
<p>See also “Why release every month?”</p></blockquote>
<h2>Another <a href="http://c2.com/cgi/wiki?DependencyInversionPrinciple">dependency inversion principle</a></h2>
<p><a href="http://geepawhill.org">GeePaw Hill</a>
likes to say
<a href="https://twitter.com/GeePawHill/status/645304579735744512">The code works for me, I don’t work for the code.</a>
If you’d like to put dependencies fully at your service — and not the
other way around — I invite you to join me next month for my
<a href="https://schmonz.com/talk/2017-aatc/">hands-on workshop at the Agile Alliance Technical Conference</a>.</p>
PillarCon 2017: Fundamentals of C and Embeddedhttps://schmonz.com/2017/02/18/pillarcon-2017-fundamentals-of-c-and-embedded/Amitai Schleier2017-03-07T16:14:00Z2017-02-19T00:07:16Z
<p>At the second annual
<a href="http://pillarcon.com">PillarCon</a>,
I facilitated a workshop called
“Fundamentals of C and Embedded using Mob Programming”.
On a Mac, we test-drove toggling a Raspberry Pi’s onboard LED.</p>
<ul>
<li><a href="https://pillarcon2017.sched.com/event/98X6">Abstract</a></li>
<li><a href="https://github.com/schmonz/c-embedded-fundamentals">Materials</a></li>
</ul>
<h2>Before and after</h2>
<table class="img"><caption>Before: ACT LED off</caption><tr><td><img src="https://schmonz.com/2017/02/18/IMG_8084.JPG" width="200" height="200" alt="Before: ACT LED off" class="img" /></td></tr></table>
<table class="img"><caption>After: ACT LED on</caption><tr><td><img src="https://schmonz.com/2017/02/18/IMG_8085.JPG" width="200" height="200" alt="After: ACT LED on" class="img" /></td></tr></table>
<h2>Retrospective</h2>
<table class="img align-right"><caption>Noteboard: takeaways from Fundamentals of C and Embedded</caption><tr><td><img src="https://schmonz.com/2017/02/18/IMG_8083.JPG" width="400" height="300" alt="Noteboard: takeaways from Fundamentals of C and Embedded" class="img" /></td></tr></table>
<p>Here are the takeaways we wrote down:</p>
<ul>
<li>Could test return type of <code>main()</code></li>
<li>Why wasn’t <code>num_calls</code> 0 to begin with?</li>
<li>Maybe provide the mocks in advance (maybe use
<a href="http://www.throwtheswitch.org/cmock/">CMock</a>)</li>
<li>Fun idea: fake
<a href="https://en.wikipedia.org/wiki/General%2Dpurpose%20input%2Foutput">GPIO</a>
device</li>
<li>Vim tricks! Cool</li>
<li>But maybe use an easier editor for target audience</li>
<li>Appropriate amount of effort; need bigger payoff</li>
<li><a href="https://en.wikipedia.org/wiki/Mob%20programming">Mob programming</a> supported the learning process/objective</li>
</ul>
<p>My own thoughts for next time I do this material:</p>
<ul>
<li><strong>Keep:</strong> providing multi-target <code>Makefile</code> and prebuilt cross compiler</li>
<li><strong>Try:</strong> providing the mocks in the starting state</li>
<li><strong>Keep:</strong> being prepared with a
<a href="https://schmonz.com/2015/08/19/life-hacks-for-the-test-infected/">test list</a></li>
<li><strong>Try:</strong> using a more discoverable (e.g., non-modal) text editor</li>
<li><strong>Keep:</strong> being prepared with corners to cut if time gets short</li>
<li><strong>Try:</strong> providing already-written test cases to uncomment one at a
time (one of the aspects of
<a href="https://schmonz.com/2016/06/18/training-tdd-for-embedded-c/">James Grenning’s training course</a>
I especially loved)</li>
<li><strong>Keep:</strong> mobbing</li>
<li><strong>Try:</strong> knowing more of the mistakes we might make when cutting corners</li>
<li><strong>Keep:</strong> delivering a visible result</li>
<li><strong>Try:</strong> turning off the PWR light (if possible) so we can more easily
see when the ACT light turns on and off</li>
</ul>
<p>Participants who already knew some of this stuff liked the mob programming
(new to some of them) and appreciated how I structured the material
to unfold.
Participants who were new to C and/or embedded (my target audience) came
away feeling that they needn’t be intimidated by it, and that
programming in this context can be as fun and feedbacky as they’re
accustomed to.</p>
<h2>Play along at home</h2>
<ol>
<li><a href="https://wiki.netbsd.org/ports/evbarm/raspberry_pi/">Install NetBSD 7 on Raspberry Pi</a></li>
<li><a href="https://www.netbsd.org/docs/guide/en/chap-fetch.html">Fetch the NetBSD source tree</a>
(or <a href="https://github.com/schmonz/c-embedded-fundamentals/blob/9bdd1d2d8839a6a65523c4cdbef68e9f3705707e/Makefile#L37">let the <code>Makefile</code> do it for you</a>)</li>
<li><a href="https://www.netbsd.org/docs/guide/en/chap-build.html">Build the cross compiler and a complete NetBSD for the target system</a>
(or <a href="https://github.com/schmonz/c-embedded-fundamentals/blob/9bdd1d2d8839a6a65523c4cdbef68e9f3705707e/Makefile#L40">let the <code>Makefile</code> do it for you</a>)</li>
</ol>
<p>Then follow the steps outlined in the
<a href="https://github.com/schmonz/c-embedded-fundamentals/blob/master/README.md">README</a>.</p>
<h2>Further learning</h2>
<p>You’re welcome to use the workshop materials for any purpose, including
your own workshop.
If you do, I’d love to hear about it.
Or if you’d like me to come facilitate it for your company, meetup
group, etc., let’s talk.</p>
<ul>
<li><a href="https://schmonz.com/2016/07/08/how-to-learn-c-part-1/">How to learn C (Part 1)</a></li>
<li><a href="https://schmonz.com/2017/02/16/how-to-learn-c-part-2/">How to learn C (Part 2)</a></li>
<li><a href="https://agilein3minut.es/32">Agile in 3 Minutes 32: Mob</a></li>
</ul>
How to learn C (Part 2)https://schmonz.com/2017/02/16/how-to-learn-c-part-2/Amitai Schleier2017-02-17T00:08:32Z2017-02-16T23:56:35Z
<h2>Previously</h2>
<ul>
<li><a href="https://schmonz.com/2016/07/08/how-to-learn-c-part-1/">How to learn C (Part 1)</a></li>
</ul>
<h2>Give assignments</h2>
<p>Since July, when I wrote Part 1, I
<a href="https://schmonz.com/2016/08/18/new-name/">got married</a>,
<a href="https://schmonz.com/2016/09/11/refactorings-for-web-hosting/">joined a C-based project</a>,
rolled off,
<a href="https://schmonz.com/2017/02/02/settling-in/">joined a new project, and moved house</a>.</p>
<p>One of the recommendations in Part 1 was “take assignments.”
The reason I’m finally back for Part 2 is that I’m
<a href="https://schmonz.com/talk/2017-pillarcon/">running a workshop on Saturday</a>.
If you’re having trouble making time to learn something, try committing
yourself to teach it.</p>
<h2>Trust your doubts</h2>
<p>I’m supposed to deliver two hours of hands-on “Fundamentals of C and Embedded.”
Having worked in C professionally for some weeks — and embedded systems for zero — I certainly don’t know any <em>more</em> than the fundamentals.
It could be the case that I know less.</p>
<p>I don’t have to be an expert at C or embedded to deliver what I’ve promised.
I <em>do</em> have to be an expert at noticing, of all the things I don’t know, what’s bothering me the most right now.
Over and over again.</p>
<h2>One question at a time</h2>
<p>Even though a Raspberry Pi is a general-purpose computer, in the workshop we’re going to treat it as an embedded system.
By that, I mean that even though we could easily develop software directly on the Pi, we’re going to pretend we can’t.
Or another way: even though it’s actually reasonably quick and cheap, we’re going to pretend it’s slow and expensive to deploy and test on the “target” system.</p>
<p>As I was preparing the workshop, here’s what I didn’t know that bothered me the most, in order:</p>
<ol>
<li>Can I write C to drive some visible feature of the Pi?
See whether I can get the onboard LED to toggle.
Result:
<a href="https://gist.github.com/schmonz/c8a8d38019823462781e6d68126bac93">it works</a>.</li>
<li>Can I cross-compile some C code? Try adapting
<a href="https://github.com/schmonz/c-roman-numeral-kata">Roman Numeral Calculator</a>
to optionally target the Pi.
Result:
<a href="https://github.com/schmonz/c-roman-numeral-kata/commit/5193bfe7d0e2409f7f88110c531af0025efd04c4">it works</a>.</li>
<li>Can I link with one implementation of an interface for the host and
another for the target?
Yes: the native Mac build prints “gonna toggle the LED” and the Pi
build really toggles it.</li>
<li>Can I instruct the Pi build (and not the native Mac build) to depend
on that cross compiler, and to rebuild it if it’s missing?
Yes (and I’m glad I kept my notes and got it right on the first try).</li>
<li>Can I link with real system calls for the target and custom fakes for
the host?
Yes, and this supersedes what I learned in (3): with fakes for
<code>open(2)/ioctl(2)/close(2)</code>, I can get rid of the fake implementation
of <code>led_toggle()</code>.</li>
<li>Can I now write microtests for <code>led_toggle()</code>?
Yes, and in so doing I found and fixed some behavior that didn’t meet
my expectations.</li>
<li>Am I now qualified to run a workshop that claims we’ll “test-drive a
Raspberry Pi from a Mac”?
I believe so.</li>
</ol>
<h2>Conclusion</h2>
<p>Am I <em>ready</em> to run the workshop?
Not quite.
I want to make sure that in our two hours as a
<a href="https://agilein3minut.es/32">mob</a>,
test-driving C in Vim, we get the satisfaction of toggling that LED.</p>
<p>How fast we get there depends on how well we test-drive (our company
prides itself on this), how well we know C (depends on who shows up),
and how well we can deal with Vim (same).
It’s possible that our pace won’t be fast enough; I’ll want to have
thought about how to speed us up.
It’s also possible that we’ll blow right through it; I’ll want to have
thought about what more we could do with our time.</p>
<p>I’m still no expert in C or embedded systems, but the state of my
knowledge is no longer the bottleneck to delivering a valuable version
of this workshop.
Wish me luck!</p>
Settling inhttps://schmonz.com/2017/02/02/settling-in/Amitai Schleier2017-02-02T14:36:46Z2017-02-02T14:28:02Z
<p>My birthday’s next week, which usually grants me license to submit my
<a href="https://schmonz.com/2014/02/10/my-thirty-fifth-solar-orbit/">year-in-review</a>
<a href="https://schmonz.com/2015/02/09/a-square-triangular-number/">posts</a>
a solid month after the deadline (though
<a href="https://schmonz.com/2015/12/16/a-mini-sabbatical/">last year’s</a>
came in under the wire).</p>
<p>But I’ve done enough reflecting and resolving in a recent post about
<a href="https://schmonz.com/2017/01/05/new-years-slack/">slack and batch size</a>
for the moment.
And my batch sizes this week are necessarily small (though this post
maybe takes the idea a bit too far).
For the moment, I’m happy to say that several
<a href="https://schmonz.com/2017/01/27/now/">anticipated changes</a>
have fallen into place:</p>
<ol>
<li><a href="https://agilein3minut.es/">Agile in 3 Minutes</a> is back.</li>
<li>I’ve joined a new team.</li>
<li>I’m in Des Moines visiting them in person.</li>
<li>I’ll mostly be working from home.</li>
<li>I get home tomorrow.</li>
<li>Home is New York.</li>
</ol>
<p>With all this important stuff established, my main goal for my birthday
is to restore my daily habit of long, fast walks. I’ve got just enough
days between now and then to give myself that gift.</p>
qmail + SMTP AUTH + TLS reduxhttps://schmonz.com/2017/01/18/qmail-smtp-auth-tls-redux/Amitai Schleier2018-04-02T04:34:26Z2017-01-18T19:42:55Z
<h2>Previously</h2>
<p>This is the sixth in a series of
“Nifty and Minimally Invasive qmail Tricks”,
following</p>
<ol>
<li><a href="https://schmonz.com/2007/01/14/qmail-smtp-auth-ssl-tls-patches/">qmail + SMTP AUTH + SSL + TLS - patches</a></li>
<li><a href="https://schmonz.com/2007/01/15/qmail-badrcptto-patches/">qmail + badrcptto - patches</a></li>
<li><a href="https://schmonz.com/2007/02/07/qmail-netbsd-nightly-maintenance/">qmail + NetBSD nightly maintenance</a></li>
<li><a href="https://schmonz.com/2007/02/28/qmail-imap-before-smtp/">qmail + IMAP-before-SMTP</a></li>
<li><a href="https://schmonz.com/2007/03/07/qmail-spam-filtering/">qmail + spam filtering</a></li>
</ol>
<h2>Losing services (and eventually restoring them)</h2>
<p>When my
<a href="https://schmonz.com/2006/06/29/installing-netbsd-on-powerpc-mac-mini/">Mac mini</a>’s
hard drive died in the
<a href="https://schmonz.com/2014/04/23/shoulda-bought-yak-insurance/">Great Crash of Fall 2008</a>,
taking this website and my email offline with it, I was already going
through a rough time, and my mental bandwidth was extremely limited.
I expended some of it explaining to friends what they could do about
their hosted domains until such time as my brain became available again
(as I assumed and/or hoped it eventually would).
I expended a bit more asking a friend to do a small thing to keep my
email flowing somewhere I could get it.
And then I was spent.</p>
<p>The years where I used Gmail and had no website felt like years in the
wilderness.
That feeling <em>could</em> mostly have been about how I missed the habit of
reflecting about my life now and again, writing about it, and sharing.
But when the website returned four years ago (in order to
<a href="https://schmonz.com/2013/01/20/my-unexpected-neighbor/">remember Aaron Swartz</a>),
the feeling didn’t go away. All I got was
<a href="https://schmonz.com/2013/05/27/remembering-textpattern/">a small sense of relief</a>
that my writings and recordings were available and that I could safely
revive my old habit.
After a year and half of reflecting, writing, and sharing, the
feels-needle hadn’t rebounded much further.</p>
<p>It was only after painstakingly restoring all my old email (from
Mail.app’s cache, using
<a href="http://mike.laiosa.org/software/emlx2maildir/">emlx2maildir</a>),
moving it up to my IMAP server, carefully merging six years’ worth of
Gmail into that,
<a href="https://twitter.com/schmonz/status/523459700352761858">accepting SMTP deliveries for <code>@schmonz.com</code></a>,
and
<a href="https://twitter.com/schmonz/status/525911496207765504">not needing Gmail at all</a>
for several weeks that I noticed my long, strange sojourn had ended.</p>
<h2>Hypothetically speaking</h2>
<p>If it so happened that I’d instead fixed email first, I’d also have felt
a tiny bit weird till my website was back. But only a tiny bit. When my
web server’s down, you might not hear from me; when my mail server’s
down, I can’t hear from you — or, as happened in 2008, from my
professors during finals week. So while
<a href="https://schmonz.com/2016/09/11/refactorings-for-web-hosting/">web hosting can be interesting</a>,
mail hosting keeps me attached to what it feels like to be responsible
for a production service.</p>
<h2>Keeping it real</h2>
<p>I value this firsthand understanding very, very highly. I started as a
sysadmin, I’m often still a developer, and that’s part of why I’m
sometimes helpful to others. But since I’m always in danger of
forgetting lessons I learned by doing it, I’m always in danger of being
harmful when I try to
<a href="https://schmonz.com/coach/">help others do it</a>.</p>
<p>As a coach, one of my meta-jobs is to remind myself what it takes to
know the risks, decide to ship it, live with the consequences, tighten
the shipping-it loop until it’s tight enough, and notice when that stops
being true.</p>
<p>And <em>that’s</em> why I run my own mail server.</p>
<h2>What’s new this week</h2>
<p>My 2014 mail server was configured just about identically with my 2008
one, for which it was handy to consult the
<a href="https://schmonz.com/tag/qmail/">earlier articles in this series</a>.</p>
<p>Then, recently, my weekly build broke on the software I’ve been
using to send mail.
It was a trivial breakage, easy to fix, but it reminded me about a
non-trivial future risk that I didn’t want hanging over my head anymore.
(For more details, see <a href="https://schmonz.com/2017/01/05/new-years-slack/">my previous post</a>.)</p>
<p>Now I’m sending mail another way.
Clients are unchanged, the server no longer needs
<a href="http://tmda.net">TMDA</a>
or its dependencies,
and I no longer have a specific expectation for how this aspect of my
mail service will certainly break in the future.
(Just some vague guesses, like a newly discovered compromise in the TLS
protocol or OpenSSL’s implementation thereof, or
<a href="https://en.wikipedia.org/wiki/Opportunistic%20TLS">STARTTLS</a>
or
<a href="https://www.stunnel.org">Stunnel</a>’s
implementation thereof.)</p>
<h2>A couple iterations</h2>
<p>First, I tried the smallest change that might work:</p>
<ol>
<li>Replacing
<a href="http://tmda.sourceforge.net/cgi-bin/moin.cgi/TmdaOfmipdHowto"><code>tmda-ofmipd</code></a>
with the original <code>ofmipd</code> from
<a href="https://cr.yp.to/mess822.html"><code>mess822</code></a>
(by the author of
<a href="https://cr.yp.to/qmail.html"><code>qmail</code></a>,
the software around which my mail service is built),</li>
<li>Wrapped in
<a href="https://en.wikipedia.org/wiki/SMTP%20Authentication">SMTP AUTH</a>
by
<a href="http://www.spamdyke.org"><code>spamdyke</code></a>
(new use of an existing tool),</li>
<li>Wrapped in STARTTLS by <code>stunnel</code> (as before).</li>
</ol>
<p>It worked!
TMDA no longer needed.
I
<a href="http://mail-index.netbsd.org/pkgsrc-changes/2017/01/09/msg151304.html">committed an update</a>
to my
<a href="http://pkgsrc.se/mail/qmail-run"><code>qmail-run</code> package</a>
with a new
<a href="http://cvsweb.netbsd.org/bsdweb.cgi/pkgsrc/mail/qmail-run/files/qmailofmipd.sh?rev=1.1&content-type=text/x-cvsweb-markup">shell script to manage this <code>ofmipd</code> service</a>,
uninstalled TMDA, and removed its configuration files.</p>
<p>Next, I tried a change that might shorten the
<a href="http://www.catb.org/~esr/writings/taoup/html/ch06s06.html">chain of executables</a>:</p>
<ol>
<li><a href="http://mail-index.netbsd.org/pkgsrc-changes/2017/01/14/msg151493.html">Committing an update</a>
to pkgsrc’s
<a href="http://pkgsrc.se/mail/mess822"><code>mess822</code> package</a>
adding a build-time option to apply
<a href="http://qmail.gurus.org/mess822-smtp-auth-patch.txt">John R. Levine’s SMTP AUTH patch</a>,</li>
<li>Doing a build with the new option enabled,</li>
<li>Letting <code>ofmipd</code> handle SMTP AUTH on its own.</li>
</ol>
<p>It worked!
Second instance of <code>spamdyke</code> no longer needed.
To start a mail submission service on <code>localhost</code> port 26, these are the lines I added to <code>/etc/rc.conf</code>:</p>
<div class="highlight-sh"><pre class="hl">qmailofmipd<span class="hl opt">=</span>YES
qmailofmipd_datalimit<span class="hl opt">=</span><span class="hl sng">"160000000"</span>
qmailofmipd_postofmipd<span class="hl opt">=</span><span class="hl sng">"'' `cat /etc/qmail/control/me` /usr/pkg/bin/checkpassword true"</span>
</pre></div>
<p>To make the service available on the network, this is the config from <code>/etc/stunnel/stunnel.conf</code>:</p>
<div class="highlight-ini"><pre class="hl"><span class="hl kwa">[submission]</span>
<span class="hl kwb">accept </span><span class="hl opt">=</span> submission
<span class="hl kwb">connect </span><span class="hl opt">=</span> localhost<span class="hl opt">:</span><span class="hl num">26</span>
<span class="hl kwb">protocol </span><span class="hl opt">=</span> smtp
</pre></div>
<p>(It already had this stanza, but with <code>8025</code> where <code>tmda-ofmipd</code> was listening.
I simply changed the port number and restarted <code>stunnel</code>.)</p>
<p>I’m still relying on <code>spamdyke</code> for other purposes, but I’m comfortable
with those.
I’m still relying on <code>stunnel</code> for STARTTLS, but I’m relatively
comfortable keeping OpenSSL contained in its own address space and
user account.</p>
<h2>Refactoring for mail hosting</h2>
<p>The present configuration is a
<a href="https://schmonz.com/2016/09/11/refactorings-for-web-hosting/">refactoring</a>:
no externally visible change to email clients, yes internally visible
change to email administrator (moi).
I believe this refactoring was one of the best kind, able to be
performed safely and reducing the risk I was worried about.
The current configuration is much more likely to meet my future need to
not have a production outage that interrupts my work for arbitrary
duration while I scramble to understand and fix it.
I don’t have any more cheap ideas for lowering my risk, and it feels low
enough anyway.
So I’m comfortable that this is
<a href="https://schmonz.com/2015/02/25/the-when-to-stop-kata/">the right place to stop</a>.</p>
<h2>Conclusion</h2>
<p>Want to learn to see the consequences of your choices and/or help other
people do the same?
Consider productionizing something important to you.</p>
New Year's Slackhttps://schmonz.com/2017/01/05/new-years-slack/Amitai Schleier2017-01-07T15:51:47Z2017-01-05T17:42:06Z
<p>Last night, mere moments from letting me
<a href="http://mail-index.netbsd.org/pkgsrc-changes/2017/01/05/msg151138.html">commit a new package</a>
of <a href="http://search.cpan.org/dist/Test-Continuous/">Test::Continuous</a>
(<a href="http://c2.com/cgi/wiki?ContinousTesting">continuous testing</a>
for Perl), my computer acted as though it knew its replacement was on
the way and didn’t care to meet it.
This tiny
<a href="https://support.apple.com/kb/SP677">mid-2013 11” MacBook Air</a>
made it relatively ergonomic to work from planes, buses, and
<a href="https://schmonz.com/2013/10/17/working-from-everywhere/">anywhere else</a>
when I lived in New York and flew regularly to see someone important in
Indiana, and continued to serve me well
<a href="https://schmonz.com/2014/02/10/my-thirty-fifth-solar-orbit/">when that changed</a>
and
<a href="https://schmonz.com/2015/01/09/two-engagements/">changed again</a>.</p>
<p>The next thing I was planning to do with it was write this post.
Instead I rebooted into
<a href="https://www.amazon.com/Disk-Warrior-Mac-select-Version/dp/B00RYGM48E/ref=as_li_ss_tl?ie=UTF8&qid=1483639092&sr=8-1&keywords=diskwarrior&linkCode=ll1&tag=schmonz-20&linkId=9c3d1c544398a645823f8d104de2341e">DiskWarrior</a>
and crossed my fingers.</p>
<p>Things get in your way, or threaten to. That’s life. But when you have
<a href="https://www.amazon.com/Slack-Getting-Burnout-Busywork-Efficiency-ebook/dp/B004SOVC2Y/ref=as_li_ss_tl?_encoding=UTF8&qid=1483639181&sr=8-1&linkCode=ll1&tag=schmonz-20&linkId=d8b7d849eee0620cd34dcaa6ae3abc5d">slack time</a>,
you can</p>
<ol>
<li>Cope better when stuff happens,</li>
<li>Invest in reducing obstacles, and</li>
<li>Feel more prepared for the next time stuff happens.</li>
</ol>
<p>Having enough slack is as virtuous a cycle as insufficient slack is a vicious one.</p>
<h2>Paying down non-tech debts…</h2>
<p>Last year I decided to spend more
<a href="https://schmonz.com/2016/03/03/why-i-went-to-fat-camp/">time and energy improving my health</a>.
Having recently spent a few weeks deliberately not paying attention to
any of that, I’m quite sure that I prefer paying attention to it, and am
once again doing so.</p>
<p>Learning to make my health a priority required that I make other things
non-priorities, notably
<a href="https://agilein3minut.es/">Agile in 3 Minutes</a>.
It no longer requires that.
I’ve recently invested in making the site easier for me to publish, and
you may notice that it’s easier for you to browse.
I didn’t have enough slack to do these things when I was
<a href="https://schmonz.com/2015/09/23/my-podcasting-workflow/">writing and recording a new episode every week</a>.
Now that enough of them have been taken care of, I feel prepared to take
new steps with the podcast.</p>
<h2>…And <a href="http://c2.com/cgi/wiki?TechnicalDebt">tech debts</a></h2>
<p>Earlier this week I noticed a broken link in a comment on
<a href="https://schmonz.com/2016/09/11/refactorings-for-web-hosting/">Refactorings for web hosting</a>,
so I took a moment to check for other broken links on this site (ikiwiki
<a href="http://ikiwiki.info/ikiwiki/directive/brokenlinks/">makes it easy</a>).</p>
<p>Before that, I inspected and minimized the differences between “dev” (my
laptop) and “prod” (my server, where you’re reading this), updated prod
with the latest ikiwiki settings, and (because it’s all in Git)
<a href="https://git-scm.com/book/en/v2/Git-Branching-Rebasing">rebased</a>
dev from prod.
In so doing, I observed that more config differences could be easily
harmonized by adjusting some server paths to match those on my laptop.
(When Apple introduced
<a href="https://en.wikipedia.org/wiki/System%20Integrity%20Protection">System Integrity Protection</a>,
<a href="http://pkgsrc.org">pkgsrc</a>
on Mac OS X could no longer install under <code>/usr</code>, and moved to <code>/opt</code>.
With my
<a href="https://schmonz.com/2016/11/23/automation-for-web-hosting/">automated NetBSD package build</a>,
I can easily build the next batch for <code>/opt/pkg</code> as well, retaining
<code>/usr/pkg</code> as a symlink for a while.
So I have.)</p>
<p>I’ve been running lots of these builds in the past week anyway, because
a family of packages I maintain in pkgsrc had been outdated for quite a
while and I finally got around to catching them up to upstream.
Once they built on OS X, I committed the updates to the
<a href="https://schmonz.com/2013/01/22/codemash-2013-your-dev-toolbox-everywhere/">cross-platform package system</a>,
only to notice that at least one of them didn’t build on NetBSD.
So I fixed it, ran another build, saw what else I broke, and repeated
until green.</p>
<h3>…And taking on patience debt telling you about more of this crud</h3>
<p>Due to another update that temporarily broke the build of
<a href="https://en.wikipedia.org/wiki/TMDA">TMDA</a>,
I was freshly reminded that that’s a relatively biggish liability in my
server setup.
I <a href="https://schmonz.com/2007/01/14/qmail-smtp-auth-ssl-tls-patches/">use TMDA to send mail</a>,
which is not mainly what it’s for, and I never got around to using it
for what it’s for (protecting against spam with automated
challenge-response), and it hasn’t been maintained for years, and is
stuck needing an old version of Python.</p>
<p>On the plus side, running a weekly build means that when TMDA breaks
more permanently, I’ll notice pretty quickly. On the minus side, when
that happens, I’ll feel pressure to fix or replace it so I can (1)
continue to send email like a normal person and (2) restart the weekly
build like a me-person. If I can reduce the liability now, maybe I can
avoid feeling that pressure later.</p>
<p>Investigating alternatives, I remembered that
<a href="http://www.spamdyke.org">Spamdyke</a>,
which I already use for
<a href="https://en.wikipedia.org/wiki/Anti%2Dspam%20techniques">delaying the SMTP greeting</a>,
blacklisting from a
<a href="https://en.wikipedia.org/wiki/DNSBL">DNSBL</a>
as well as <code>To:</code> addresses that only get spam anymore, and
<a href="https://en.wikipedia.org/wiki/greylisting">greylisting</a> from unknown senders,
can provide
<a href="https://en.wikipedia.org/wiki/SMTP%20AUTH">SMTP AUTH</a>.
So I’ll try keeping
<a href="https://en.wikipedia.org/wiki/stunnel">stunnel</a>
and replacing <code>tmda-ofmipd</code> with a second instance of <code>spamdyke</code>.
If that’s good, I’ll remove <code>mail/tmda</code> from
<a href="https://github.com/schmonz/dotfiles/blob/master/pkgcomp-autopackages">the list of packages I build every week</a>,
then build <code>spamdyke</code> with OpenSSL support and try letting it handle the
TLS encryption directly.
If that’s good, I’ll remove <code>security/stunnel</code> from the list of packages
too, leaving me at the mercy of fewer pieces of software breaking.</p>
<p>Leaning more heavily on Spamdyke isn’t a clear net reduction of risk.
When a bad bug is found, it’ll impact several aspects of my mail service.
And if and when NetBSD moves from GCC to Clang, I’ll have to add
<code>lang/gcc</code> to my list of packages and instruct pkgsrc to use it when
building Spamdyke, or else come up with a patch to remove Spamdyke’s use
of anonymous inner functions in C.
(That could be fun. I recently
<a href="https://schmonz.com/2016/07/08/how-to-learn-c-part-1/">started learning C</a>.)</p>
<p>I could go on, but I’m a nice person who cares about you.</p>
<h3>That’s enough of that. So what?</h3>
<p>All these builds pushing my soon-to-be-replaced laptop through its
final paces as a development machine might have had something to do
with triggering its misbehavior last night.
And all this work seems like, well, a lot of work.
Is there some way I could
<a href="http://agilemanifesto.org/principles.html">do less of it</a>?</p>
<p>Yes, of course.
But given my interests and goals, it might not be a clear net improvement.
For instance, when
<a href="http://agileotter.blogspot.com">Tim Ottinger</a>
drew my attention to that <code>Test::Continuous</code> Perl module, being a pkgsrc
developer gave me an easy way to uninstall it if I wound up not liking
it, which meant it was easy to try, which meant I tried it.
I want
<a href="https://schmonz.com/2015/07/29/enthusiasm-engineering/">conditions in my life to favor trying things</a>.
So I’m invested in preserving and extending those conditions.
In
<a href="https://www.destroyallsoftware.com">Gary Bernhardt</a>’s
formulation, I’m aiming to maximize the
<a href="https://schmonz.com/2013/06/10/area-under-the-curve/">area under the curve</a>.</p>
<h2>No new resolutions, yes new resolvings</h2>
<p>I’m not looking to add new goals for myself for 2017.
I’m not even trying to make existing things “good enough” — there are
too many things, and as a
<a href="https://schmonz.com/2015/08/12/tdd-saved-my-brain/">recovering perfectionist</a>
I have trouble setting a reasonable bar — I’m just trying to make them
“good enough enough” that I can expect
<a href="https://schmonz.com/2015/11/04/incremental-effort-incremental-payoff/">small slices of time and attention to permit small improvements</a>.</p>
<p><a href="http://jessitron.com">Jessica Kerr</a>
has a thoughtful side blog named
<a href="http://tistil.tumblr.com">True in software, true in life</a>.
Here’s something that’d qualify:</p>
<ol>
<li>When conditions are expected to change, smaller batch size helps us adjust.</li>
<li>Reducing batch size takes time and effort.</li>
</ol>
<p>Paying down my self-debts (technical and otherwise) feels like
<em>resolving</em>.
I have, at times, felt quite out of position at managing myself.
Lately I’m feeling much more in position, and much more like I can
expect to continue to make small improvements to my positioning.</p>
<blockquote><p>When you want the option to change your body’s direction, you take
smaller steps, lower your center, concentrate on balance. That’s
#Agile.<br />
—<a href="https://twitter.com/schmonz/status/805228859507544064">Moi</a></p></blockquote>
<p>My current best understanding is that a balanced life is a
small-batch-size life.
If that’s the case, I’m getting there.</p>
<h2>Further repositioning</h2>
<p>This coming Monday, I’ll be switching to one of these
<a href="https://support.apple.com/kb/SP748">weird new MacBook Pros</a>
with the row of non-clicky touchscreen “keys”.
If my current computer survives till then, that’ll be one smooth step in
a series of transitions.
(In other news, Bekki defends her dissertation that day.)</p>
<p>The following Monday, I’ll be starting my next project, a mostly-remote
gig pairing in Python to deliver software for a client while encouraging
and supporting growth in my Pillar teammates.
I’ll be in Des Moines every so often; if you’re there and/or have
recommendations for me, I’d love to hear from you.</p>
<p>The Monday after that, we’ll pack up a few things the movers haven’t
already taken away, and our time in Indiana will come to an end.
We’re headed back to the New York area to live near family and friends.</p>
<h2>No resolutions, yes intentions</h2>
<p>For 2017, I declare my intentions to:</p>
<ol>
<li>Continue to improve my health and otherwise attend to my own needs</li>
<li>Help more people
<a href="https://schmonz.com/2016/10/16/agile-coach-camp/">understand what software development work is like</a></li>
<li>Help more people feel heard</li>
</ol>
<p>I hope to see and hear you along the way.</p>
1000 words on metricshttps://schmonz.com/2016/12/21/1000-words-on-metrics/Amitai Schleier2016-12-24T16:14:22Z2016-12-22T03:57:54Z
<p>Last week someone asked some Agile coaches for their thoughts on
metrics. It occurred to me that I’ve got some feelings too.</p>
<h2>Nope!</h2>
<p>I distrust metrics. More accurately, I distrust what people — myself
included — tend to do with metrics not only by default, but also in
spite of any better intentions we might set out with. It doesn’t
matter what we say a number is supposed to be for: people will decide
(and re-decide) for themselves. Regardless of what we wish, expect, or
can even observe, a metric is “for” whatever behaviors it produces. In
other words:</p>
<blockquote><p>The purpose of a system is what it does.<br />
—<a href="https://en.wikipedia.org/wiki/The%5Fpurpose%5Fof%5Fa%5Fsystem%5Fis%5Fwhat%5Fit%5Fdoes">Stafford Beer</a></p></blockquote>
<p>Metrics are tools. Tools have affordances. Affordances influence
behavior. Most metrics have untidy affordances.</p>
<h2>Not on my watch!</h2>
<p>When I’m asked for metrics, I find myself feeling oppositional. I may
ask questions like “Which decisions will this help you make?”, but I’m
not asking to clarify intent and explore the problem. I’m asking to be
passively aggressive, to be obstructive, to make myself a hurdle to be
cleared before one more development team gets measured in one more
useless, counterproductive, or spirit-crushing way. As I like to say:</p>
<blockquote><p>Careful what you measure, because you’ll get it.<br />
—Amitai Schleier</p></blockquote>
<p>(I’m smart enough not to track how many times I quote myself.)</p>
<p>There are a few problems with my strategy.</p>
<h2>Who needs my approval?</h2>
<p>Nobody. I don’t have to agree that a given metric is a good idea for it
to get measured and observed.</p>
<h2>Who’s measuring whom?</h2>
<p>My reaction is maybe a bit
<a href="https://schmonz.com/2015/04/08/how-to-develop-humans/">parental</a>,
triggered by the prospect that people with more
<a href="https://agilein3minut.es/15">power</a>
might use it to do harm to people with less. But sometimes teams have
their own reasons to measure themselves, as an input to their own
satisfaction with their own work. When that’s what’s happening, and we
can make sure nobody else will ever get to see our numbers, I’m happy to
join in clarifying intent and exploring the problem.</p>
<h2>Who’s got a better idea?</h2>
<p>Just because <em>I</em> think my idea is better doesn’t mean anyone else does.</p>
<p>For instance, maybe I get on my soapbox and claim that we’ve already got
some metrics. What?!? Sure, we’ve already got some idea of how much it’s
costing us to do stuff, how much risk we’re taking, how much value we’re
delivering, and how much people feel like what we’re doing is worth
continuing to do. Aren’t these the questions we’re motivated to answer
better? And if so, how about before we pose new questions, let’s look
for ways to get better answers?</p>
<p>Maybe that’s convincing, maybe it isn’t. If we’re gonna take on new
metrics, I try to improve the likelihood that we’ll
<a href="https://agilein3minut.es/2">pay attention to them and act on what we notice</a>.</p>
<h2>Idea: metrics come with expiration dates</h2>
<p>Just because <em>I</em> think adding a metric constitutes an experiment to see
whether it produces net-desirable behaviors doesn’t mean anyone else
does. Because I believe they’ll come around to my way of thinking once
they see for themselves, I suggest a
<a href="https://schmonz.com/2015/07/29/enthusiasm-engineering/">behavioral hack</a>.
It’s a rule:</p>
<blockquote><p>Every new metric we add must be accompanied by an expiration date.</p></blockquote>
<p>Could be two retrospectives from now, if we’re doing iterations. Could
be three months from now, if we’re not comfortable with running
experiments.</p>
<p>The expiration date is a means to an end. The ends are affordances to:</p>
<ol>
<li>Remember to observe, and</li>
<li>Stop if we want.</li>
</ol>
<p>By the time the expiration date rolls around, we might not remember why
we started tracking the metric. That would be an observation worthy of
reflection, but also an affordance to retain the metric out of inertial
uncertainty. The expiration date provides a counter-affordance that it’s
<a href="https://agilein3minut.es/11">safe</a>
to drop it, because we’ve made that aspect of our original intent clear.</p>
<p>If we remember what else we originally intended, and/or it seems to be
serving us well, we can choose a new date and renew our subscription. Or
<a href="https://agilein3minut.es/10">try</a>
a new variation.</p>
<h2>Conclusion</h2>
<p>In short, I find most grasping for metrics to be a reliable metric for
lack of understanding of human behavior, not only that of those who
would be measured but that of those who would do the measuring.</p>
<p>If a higher-up wants a metric about a team, say, as an input to their
judgment about whether the team’s work is satisfactory, oughtn’t there
be some other way to tell?</p>
<p>And if I choose nearly any metric on someone else’s behalf, doesn’t that
reveal my assumption that I know something about how they do their good
work better than they do?</p>
<p>Or worse, that I prefer they nail the metric than do something as loose
and floppy as “good work”?</p>
<h2>Let’s try that again</h2>
<p>New metric (expiration = next subhead, privacy = public): I’m 0 for 1 on
satisfying conclusions to this post.</p>
<p>I’m hardly an expert on human behavior. If I were one, rather than
being passive-aggressive and obstructive, I’d have a ready step to
suggest to metrics-wanters, one that they’d likely find more desirable
than metrics.</p>
<p>Instead I have to talk myself down from passo-aggro-obstructo, by which
time they’ve chosen what they’ll observe and the ready step I can offer
is limited to encouraging them to observe the effects of their
observation.</p>
<p>Can you give me some better ideas?</p>
<h2>Further reading</h2>
<p>I’m much more comfortable with the latest conclusion, especially if
you’ll give me some ideas. I’ll call it 1 for 2 and let the metric
expire here.</p>
<p>My suggestion that metrics auto-expire was mentioned in
<a href="http://agileotter.blogspot.com">Tim Ottinger</a>’s recent post,
<a href="https://www.industriallogic.com/blog/what-should-we-measure/">Modern Agile Metrics: What Should We Measure?</a>.</p>
<p>I’ve heard that
<a href="http://neopragma.com">Dave Nicolette</a>’s
book,
<a href="https://www.manning.com/books/software-development-metrics">Software Development Metrics</a>,
would be useful for me to read. Also
<a href="https://www.amazon.com/How-Measure-Anything-Intangibles-Business-ebook/dp/B00INUYS2U/ref=as_li_ss_tl?_encoding=UTF8&me=&linkCode=ll1&tag=schmonz-20&linkId=aabc7841298077f2b98ee7c50e8529fb">How to Measure Anything</a>.
What else?</p>
<hr />
<p><em>Updates:</em></p>
<p><a href="https://twitter.com/cwfreeman">Chris Freeman</a>
writes in:</p>
<blockquote><p>You might add
<a href="https://www.amazon.com/Out-Crisis-Press-Edwards-Deming-ebook/dp/B00653KTES/ref=as_li_ss_tl?_encoding=UTF8&me=&linkCode=ll1&tag=schmonz-20&linkId=eb701bb670c6a999f75c77ba3a032b4f">Out Of The Crisis</a>
as a resource to your post since he writes about how the folks on the
floor are in control of their own improvements and how metrics are
hard and how surprising “normal” can be.</p></blockquote>
<p><a href="https://twitter.com/DocOnDev">Doc Norton</a>
has a presentation called
<a href="http://docondev.com/presentations">Agile Metrics - Velocity Is NOT The Goal</a>.</p>
<p><a href="https://twitter.com/DayleyAgile">Alan Dayley</a>
suggests over on the
<a href="https://plus.google.com/+AmitaiSchleier/posts/jBNnh8x9pnk">Google+ Agile group</a>
that “Every metric should be tied to a business or improvement goal”,
and uses a modified
<a href="https://en.wikipedia.org/wiki/GQM">Goal-Question-Metric</a>
model.</p>
<p><a href="https://twitter.com/mikerogers_">Mike Rogers</a>
points at
<a href="https://twitter.com/LMaccherone">Larry Maccherone</a>’s
<a href="https://blog.agilecraft.com/blog/eight-dragons-of-agile-metrics">Eight Dragons of Agile Metrics</a>.</p>
<p><a href="https://twitter.com/t_magennis">Troy Magennis</a>
offers a
<a href="https://github.com/FocusedObjective/FocusedObjective.Resources">GitHub repo full of treasures</a>.</p>
Agile Testing Days 2016: DevOps Dojohttps://schmonz.com/2016/12/07/agiletd-2016-devops-dojo/Amitai Schleier2023-04-22T11:55:21Z2016-12-07T09:01:44Z
<p>At
<a href="http://www.agiletestingdays.com">Agile Testing Days</a>,
I facilitated a workshop called
“DevOps Dojo”.
We role-played Dev and Ops developing and operating a production system,
then figured out how to do it better together.</p>
<ul>
<li><a href="http://www.agiletestingdays.com/session/devops-dojo/">Abstract</a></li>
<li><a href="https://schmonz.com/2016/12/07/agiletd-2016-devops-dojo/slides/">Slides</a></li>
</ul>
<p>We wrote down our takeaways on the
<a href="https://schmonz.com/2016/12/07/agiletd-2016-devops-dojo/slides/#23">final “Retrospective” slide</a>.</p>
<p>You’re welcome to use the
<a href="https://github.com/schmonz/devops-dojo">workshop materials</a>
for any purpose, including your own workshop.
If you do, I’d love to hear about it.</p>
<h2>Some firsts</h2>
<p><img src="https://schmonz.com/smileys/prio1.png" alt="{1}" /> I’ve spoken at several instances of
<a href="http://pkgsrc.org/pkgsrcCon/">pkgsrcCon</a>
(including
<a href="https://schmonz.com/2008/06/15/pkgsrccon-2008-the-wrapper-framework-then-now-and-soon/">twice</a>
in nearby
<a href="https://schmonz.com/2013/04/05/pkgsrccon-2013-rehabilitating-pkglint/">Berlin</a>),
but that’s more like a hackathon with some talks.
Agile Testing Days was a proper <em>conference</em>, with hundreds of
people and plenty of conferring.
If someone asks whether I’m an “international speaker”,
or claims I am one,
I now won’t feel terribly uncomfortable going along with it.</p>
<p><a href="https://twitter.com/carlosble/status/806250754336030721"><img src="https://schmonz.com/2016/12/07/agiletd-2016-devops-dojo/400x300-CzBguACXAAMn0-q.jpg" width="400" height="300" alt="Two WeDoTDDers" class="img" /></a></p>
<p><img src="https://schmonz.com/smileys/prio1.png" alt="{1}" /> I met a fellow
<a href="https://twitter.com/WeDoTDD">WeDoTDD</a>
practitioner,
<a href="https://twitter.com/carlosble">Carlos Blé</a>
of
<a href="https://twitter.com/codesaidev">Codesai</a>.
(Here’s
<a href="http://www.wedotdd.com/interviews/companies/7">their WeDoTDD interview</a>
and
<a href="http://www.wedotdd.com/interviews/companies/3">Pillar’s</a>.)
Carlos and I have both
<a href="https://schmonz.com/2015/08/05/confessions-of-a-twitter-completionist/">relied on Twitter</a>
to build our careers.
Who knows, maybe we’ll give a talk together about it.</p>
<p><img src="https://schmonz.com/smileys/prio1.png" alt="{1}" /> At the Tuesday morning
<a href="http://leancoffee.org">Lean Coffee</a>,
I found a bug in myself (<em>not</em> a first).</p>
<p><strong>What I expected</strong> from many previous Lean Coffees:
I’d have to control myself to not say all the ideas and suggestions that
come to mind.</p>
<p><strong>What happened</strong> at this Lean Coffee:
It was very easy to listen, because I didn’t have many ideas or
suggestions, because the topics came from people who were mostly
testers.</p>
<p>Conclusions I immediately drew:</p>
<ul>
<li>Come to think of it, I have not played every role on a team. I don’t
know what it’s like to be a tester. Maybe my guesses about what it’s
like are less wrong than some others, but they’re still gonna be
wrong.</li>
<li>This is evidently my first conference that’s more <em>testing</em> than
<em>Agile</em>. Cool! I bet I can learn a lot here.</li>
</ul>
<p><a href="https://twitter.com/lisacrispin/status/806632387920752640"><img src="https://schmonz.com/2016/12/07/agiletd-2016-devops-dojo/400x300-CzG74ZOXgAEcPtF.jpg" width="400" height="300" alt="Four Yorkshiremen" class="img" /></a></p>
<p><img src="https://schmonz.com/smileys/prio1.png" alt="{1}" /> <a href="https://twitter.com/mheusser">Matt Heusser</a>
invited me to perform in the Late Night Cabaret with Bob
(<a href="https://twitter.com/lisacrispin">Lisa Crispin</a>’s spouse)
and Jack
(<a href="https://twitter.com/janetgregoryca">Janet Gregory</a>’s).
We did the
<a href="https://en.wikipedia.org/wiki/Four%20Yorkshiremen%20sketch">Four Yorkshiremen sketch</a>
as
<a href="https://www.youtube.com/watch?v=26ZDB9h7BLY">popularized by Monty Python</a>.</p>
<p><img src="https://schmonz.com/smileys/prio1.png" alt="{1}" /> Thanks to
<a href="https://twitter.com/t_magennis">Troy Magennis</a>,
<a href="https://twitter.com/mgaertne/status/758673541642477568">Markus Gärtner</a>,
and
<a href="https://twitter.com/CatSwetel/status/758676635000406016">Cat Swetel</a>,
I decided to
<a href="https://twitter.com/schmonz/status/759484222864183296">try a new idea</a>
and spend
<a href="https://schmonz.com/2016/12/07/agiletd-2016-devops-dojo/slides/#3">a few slides</a>
drawing attention to the existence and purpose of Agile Testing Days’
<a href="https://en.wikipedia.org/wiki/Code%5Fof%5Fconduct">Code of Conduct</a>.
I can’t tell yet how much good this did, but it took so little time that
I’ll keep trying it in future conference presentations and workshops.</p>
<h2>Some nexts</h2>
<p><img src="https://schmonz.com/smileys/star_on.png" alt="{*}" /> My next gig will be remote coaching, centered around what we notice as
we’re pair programming and delivering working software.
I’ve done plenty of
<a href="https://schmonz.com/coach/">coaching</a>
and plenty of
<a href="https://schmonz.com/2013/10/17/working-from-everywhere/">remote work</a>,
but not usually at the same time.
Thanks to Lean Coffee with folks like Janet and
<a href="https://twitter.com/alex_schl">Alex Schladebeck</a>,
I got some good advice on being a more effective
<a href="https://agilein3minut.es/15">influencer</a>
when it takes more intention and effort to have face-to-face interactions.</p>
<ul>
<li>Alex: For a personal connection, start meetings by unloading your
“baggage” — whatever’s on your mind today that might be dividing your
attention — and inviting others to unload theirs. (Ideally, establish
this practice in person first.)</li>
<li>Janet: Ask questions that help people recognize their own situation.
(Helping people orient themselves in their problem spaces is one of my
go-to strengths. I’m ready to be leaning harder on it.)</li>
</ul>
<p><img src="https://schmonz.com/smileys/star_on.png" alt="{*}" /> As I learn about remote coaching, I expect to write things down at
<a href="http://shapemywork.com/">Shape My Work</a>,
a wiki about distributed Agile that
<a href="https://twitter.com/onealexharms">Alex Harms</a>
and I created.
You’ll notice it has a Code of Conduct.
If it makes good sense to you, we’d love to learn what you’ve learned as
a remote Agilist.</p>
<p><img src="https://schmonz.com/smileys/star_on.png" alt="{*}" /> I found Agile Testing Days to be a lovingly organized and carefully
tuned mix of coffee breaks, efficiency, flexibility, and whimsy.
The love and whimsy shone through.
I’m honored to have been part of it, and I sure as heck hope to be back
next year.</p>
<p>We’d be back next year anyway; we visit family in Germany every December.
Someday we might choose to live near them for a while.
It occurs to me that having participated in Agile Testing Days
might well have been an early investment in that option, and the thought
pleases me.
(As does the thought of hopping on a train to participate again.)</p>
<p><img src="https://schmonz.com/smileys/star_on.png" alt="{*}" /> I’m in Europe through Christmas.
I consult,
<a href="https://schmonz.com/coach/">coach</a>,
and train.
Do you know of anyone who could use a day or three of my services?</p>
<p><img src="https://schmonz.com/smileys/star_on.png" alt="{*}" /> One aspect of being a tester I <em>do</em> identify with is being frequently
challenged to explain their discipline or justify their decisions to
people who don’t know what the work is like (and might not recognize the
impact of their not knowing).
In that regard, I wonder how helpful
<a href="https://schmonz.com/2015/10/07/agile-in-3-minutes-the-book/">Agile in 3 Minutes</a>
is for testers.</p>
<p>Let’s say I could be so lucky as to have a few guest episodes about testing.
Who would be the first few people you’d want to hear from?
Who has a way with words and ideas, knows the work, and can speak to it
— in their unique voice —
to help the rest of us understand a bit better?</p>
Automation for web hostinghttps://schmonz.com/2016/11/23/automation-for-web-hosting/Amitai Schleier2016-11-26T06:17:23Z2016-11-24T00:35:52Z
<p>My first job was in
<a href="https://en.wikipedia.org/wiki/Information%5Ftechnology%5Foperations">Operations</a>.
When I got to be a Developer, I promised myself I’d remember how to be good to Ops.
I’ve <a href="https://schmonz.com/coach/">sometimes succeeded</a>.
And when I’ve been effective, it’s been in part due to my firsthand knowledge of both roles.</p>
<h2>DevOps is two things (hint: they’re not “Dev” and “Ops”)</h2>
<p>Part of what people mean when they say
<a href="https://en.wikipedia.org/wiki/DevOps">DevOps</a>
is automation.
Once a system or service is in operation, it becomes more important to engineer its tendencies toward staying in operation.
Applying disciplines from software development can help.</p>
<p>These words are brought to you by a Unix server I operate.
I rely on it to serve this website, those of a few friends, and a
<a href="https://agilein3minut.es/">tiny podcast of some repute</a>.
Oh yeah, and my email.
It has become rather important to me that these services tend to stay operational.
One way I improve my chances is to
<a href="https://schmonz.com/2016/09/11/refactorings-for-web-hosting/">simplify what’s already there</a>.</p>
<h2>If it hurts, do it more often…</h2>
<p>Another way is to update my
<a href="https://github.com/schmonz/dotfiles/blob/master/pkgcomp-autopackages">installed third-party software</a>
once a week.
This introduces two pleasant tendencies: it’s much…</p>
<ol>
<li>Less likely, at any given time, that I’m running something dangerously outdated</li>
<li>More likely, when an urgent fix is needed, that I’ll have my wits about me to do it right</li>
</ol>
<p>Updating software every week also makes two strong assumptions about safety (see
<a href="http://modernagile.org">Modern Agile’s</a>
“Make Safety a Prerequisite”): that I can quickly and easily…</p>
<ol>
<li>Roll back to the previous versions</li>
<li>Build and install new versions</li>
</ol>
<p>Since I’ve been leaning hard on these assumptions, I’ve invested in making them more true.</p>
<p>The initial investment was to figure out how to configure
<a href="http://pkgsrc.org">pkgsrc</a>
to build a complete set of binary packages that could be installed at the same time as another complete set.
My hypothesis was that then, with predictable and few side effects, I could select the “active” software set by moving a
<a href="https://en.wikipedia.org/wiki/symbolic%5Flink">symbolic link</a>.</p>
<p>It worked.
On my
<a href="https://schmonz.com/2006/06/29/installing-netbsd-on-powerpc-mac-mini/">PowerPC Mac mini</a>,
the best-case upgrade scenario went from half an hour’s downtime (bring down services, uninstall old packages, install new packages, bring up services) to less than a minute (install new packages, bring down services, move symlink, bring up services, delete old packages after a while).
The worst case went from <img src="https://schmonz.com/smileys/alert.png" alt="/!\" /> over an hour to <img src="https://schmonz.com/smileys/thumbs-up.png" alt="{OK}" /> maybe a couple of minutes.</p>
<h2>…Until it hurts enough less</h2>
<p>I liked the payoff on that investment a <em>lot</em>.
I’ve been
<a href="https://schmonz.com/2015/11/04/incremental-effort-incremental-payoff/">adding incremental enhancements</a>
ever since.
I used to do builds directly on the server: in place for low-risk leaf packages, as a separate full batch otherwise.
It was straightforward to do, and I was happy to accept an occasional reduction in responsiveness in exchange for the results.</p>
<p>After
<a href="https://schmonz.com/2013/05/27/remembering-textpattern/">the Mac mini died</a>,
I moved to
<a href="https://schmonz.com/2015/11/25/equipped-to-podcast/">a hosted Virtual Private Server</a>
that was much easier to mimic.
So I took the job offline to a local
<a href="https://www.virtualbox.org">VirtualBox</a> running the same release and architecture of
<a href="http://www.netbsd.org">NetBSD</a>
(<a href="http://wiki.netbsd.org/ports/i386/">32-bit <code>i386</code></a>
to begin with,
<a href="http://wiki.netbsd.org/ports/amd64/">64-bit <code>amd64</code></a>
now, both under
<a href="http://wiki.netbsd.org/ports/xen/">Xen</a>).
The local job ran faster by some hours (I forget how many), during which the server continued devoting all its I/O and CPU bandwidth to its full-time responsibilities.</p>
<p>Last time I went and improved something was to fully automate the building and uploading, leaving myself a documented sequence of manual installation steps.
Yesterday I
<a href="https://schmonz.com/2016/11/23/schmonz-software-rebuild.txt">extended that shell script</a>
to generate another shell script that’s uploaded along with the packages.
When the upload’s done, there’s one manual step: run the install script.</p>
<p>If you can read these words, it works.</p>
<h2>DevOps is still two things</h2>
<p>Applying Dev concepts to the Ops domain is one aspect.
When I’m acting alone as both Dev and Ops, as in the above example, I’ve demonstrated only that one aspect.</p>
<p>The other, bigger half is collaboration across disciplines and roles.
I find it takes some not-tremendously-useful effort to distinguish this aspect of DevOps from
<a href="https://schmonz.com/2016/03/09/agileindy-march-2016-bdd-for-everyone/">BDD</a>
— or from anything else that looks like healthy cross-functional teamwork.
It’s the healthy cross-functional teamwork I’m after.
There are lots of places to start having more of that.</p>
<p>If your team’s context suggests to you that DevOps would be a fine place to start, go after it!
Find ways for Dev and Ops to be learning together and delivering together.
That’s the whole deal.</p>
<h2>Here’s another deal</h2>
<p>Two weeks from today, at
<a href="http://www.agiletestingdays.com">Agile Testing Days</a>
in Potsdam, Germany, I’m running a
<a href="http://www.agiletestingdays.com/session/devops-dojo/">hands-on DevOps collaboration workshop</a>.
Can you join us?
It’s not too late, and you can save 10% off the price of the conference ticket.
Just provide
<a href="https://schmonz.com/talk/2016-agiletd/">my discount code</a>
when you
<a href="http://www.agiletestingdays.com/registration/">register</a>.
I’d love to see you there.</p>
What we can dohttps://schmonz.com/2016/11/08/what-we-can-do/Amitai Schleier2016-11-12T01:39:43Z2016-11-08T13:02:26Z
<p>Every four years, I revisit my thinking about voting. I do it because I’ll revisit any old thinking given a chance and a reason, and because one of the consequences of this particular old thinking is that many people, on hearing it, feel more distant from me.</p>
<p>A theme of my life has been to find steps I can take to feel less apart from other people. Every election has generally been a big backward step. Every four years, I hope I can adapt myself to holding less alienating thoughts, or at least find less alienating ways to express them.</p>
<p>Right now, I’m feeling hopeful.</p>
<h2>I believe, and you may agree, that…</h2>
<p>It was meaningful and
<a href="https://schmonz.com/2008/11/01/whats-at-stake/">emotionally resonant</a>
when we managed to elect a black man as President. It will be meaningful and emotionally resonant when we manage to elect a woman. Maybe today.</p>
<h2>I’m open to the possibility that, in some contexts…</h2>
<ul>
<li>Voting is morally or ethically superior to not voting</li>
<li>Voting can more effectively bring about desirable outcomes than not voting</li>
<li>Voting is significant compared to other actions we can take</li>
</ul>
<p>I have not yet found myself in contexts where these claims seemed likely to be true.</p>
<h2>I agree that…</h2>
<blockquote><p>Voting is buying into democracy.<br />
—<a href="https://twitter.com/cyetain/status/793429681148141568">Jabe Bloom</a></p></blockquote>
<p>In previous elections, I’ve often been told “If you don’t vote, you can’t complain” (about what the elected officials wind up doing). I’ve sometimes replied “If you <em>do</em> vote, you can’t complain” (about what the system of power inevitably winds up doing). But I never found it satisfying to say that. Everyone can always complain whenever they like, of course, and my goal had been to increase mutual understanding, not score a cheap rhetorical point.</p>
<p>In this election, I don’t recall anyone telling me this one. I’d be happier about it if I didn’t think it was because I’ve been talking openly with many fewer people than in previous elections. (I’m writing these words in a small attempt to do better about that.)</p>
<p>In previous elections, I’ve often been told that the debates are an important way to become informed about the issues and the candidates, and it’s irresponsible not to watch. In this election, I haven’t heard anyone say this. I’m somewhat happy about it because it means, for once, that my not watching the debates hasn’t added distance between me and other people. I’d be happier about it if we weren’t so polarized that those who watched the debates saw only confirming evidence of their choice.</p>
<h2>I don’t agree that…</h2>
<blockquote><p>not voting is self-disenfranchisement<br />
—<a href="https://twitter.com/cyetain/status/793468453977985024">Jabe Bloom</a></p></blockquote>
<p>I’m not disenfranchised simply because I don’t want to be part of this specific franchise. I continue to exercise my agency and influence in ways I find congruent.</p>
<h2>It matters who we elect</h2>
<p>It also costs us. Some of the costs we never know, and many we can only guess. By the time we know more, it’s too late.</p>
<p>We all suspect we know which choice of presidential candidate would reduce more harm. One of them sounds, to my ears, far more evidently dangerous. That doesn’t fill me with certainty. It fills me with doubt about the other candidate, who is far more practiced at appearing sensible and humane and also at working the system of power.</p>
<p>I know which one <em>sounds</em> worse. But I don’t know which one <em>is</em> worse. We can’t know. There is no means through which that knowledge can be available to us.</p>
<p>Do I want to participate in a giant system of power — one with with long, slow, obfuscatory feedback cycles — that requires us to put one of these people in office? I don’t. As an Agilist, I don’t see this as a system that can ever work well, or that can ever trend toward better.</p>
<p>There’s no way this election doesn’t have consequences. That doesn’t mean I see any option for influencing them to my liking.</p>
<h2>It also matters, far more, what else we do</h2>
<p>John Lewis risked his life for something he held dear:</p>
<blockquote><p>I’ve marched, protested, been beaten and arrested — all for the
right to vote. Friends of mine gave their lives. Honor their
sacrifice. Vote.<br />
—<a href="https://twitter.com/repjohnlewis/status/794161827546599424">John Lewis</a></p></blockquote>
<p><em><a href="https://en.wikipedia.org/wiki/Selma%5F%28film%29">Selma</a></em> flattened me. I don’t know that I could have done what he did. I do know that the value he places on voting does not obligate me to do the same. When I see how he and others had to fight for some small additional fraction of equal treatment backed by the power of law, it does not occur to me that to solve this problem we must arrange for this power to be shared by more people. It occurs to me that this power is the proximate cause of the problem. We can’t prevent cruelty, but we are not obligated to put leaders in a system of power that magnifies the effects of any cruel behavior. And if the only option we can offer those to whom this system of power has been especially cruel is for them to participate in it more fully, then there is much more kindness waiting to be released from our hearts.</p>
<p>We invented this system. We can invent another one.</p>
<h2>Neither voting nor not voting is sufficient</h2>
<p>That’s how I see it. If voting is part of what you need to do, I’ll try to understand. I hope you’ll try to understand why not voting is part of what I need to do. And I’m quite sure that together, with our combined privilege and savvy and smarts and love, we can have a far more meaningful influence than the one we’ll have today.</p>
<p>Let’s keep using all our advantages to move the world, inch by inch, toward the world we want.</p>
Agile Coach Camp 2016https://schmonz.com/2016/10/16/agile-coach-camp/Amitai Schleier2023-12-19T15:13:11Z2016-10-17T00:12:37Z
<p>There was an
<a href="http://agilecoachcamp.org/">Agile Coach Camp</a>
two years ago in Indianapolis — I could have been making crucial
career-changing connections, then sleeping in my own bed! — but we were
out of the country that weekend.
It was, unquestionably, a missed opportunity; perhaps
<a href="https://en.wikipedia.org/wiki/Open%5FSpace%5FTechnology%23Guiding%5Fprinciples%5Fand%5Fone%5Flaw">what happened was the only thing that could have</a>.
Things worked out anyhow.
Pillar
<a href="https://schmonz.com/2015/01/09/two-engagements/">gave me the work</a>,
and I’ve been
<a href="https://schmonz.com/2015/09/02/how-to-get-hired-as-a-coach/">trying to</a>
<a href="https://schmonz.com/2015/09/09/how-to-get-decent-at-coaching/">make the</a>
<a href="https://schmonz.com/2015/10/07/agile-in-3-minutes-the-book/">most of it</a>
<a href="https://schmonz.com/speaker/">ever since</a>.</p>
<p>I’m mildly amused at the timing of my first Agile Coach Camp.
Before I started down the coaching path, I imagined that sustaining it
— and myself — would mean I’d need to alternate between “doing it” and
“helping others do it”, like it
<a href="http://agilemanifesto.org">says right there in the Manifesto</a>.
So far, I’m not wrong.
At my request, I’ve just swung my professional pendulum most of the way
back to “doing it”, recharging my coaching energy and developer cred on
a team of fellow consulting-minded XP developers.
We’re embedded at a client, working to
<a href="https://twitter.com/schmonz/status/785564180514471936">influence the outcome of a change-the-world project that’s in the news</a>.
(Interested? Hit me up.)</p>
<p>Maybe this mental context switch is why, when only a handful of Campy
Coaches self-identified as “technical”, I was primed to figure out how
I might be able to share with the rest of them a tiny experience of
software development work.
En route to St. Louis, I’d already been revisiting this old thought:</p>
<blockquote><p><a href="https://twitter.com/schmonz/status/787256956285255680">People who haven’t done it have no way of knowing the extent to which
programming consists of making decisions. (It’s a very large extent.)</a></p></blockquote>
<p>The first time I wrote these words down was
<a href="https://schmonz.com/2014/04/01/my-superpower/">when I resigned from Morgan Stanley</a>.
Three years ago, despairing at how few around me shared my values, I
<a href="https://schmonz.com/2013/12/13/global-day-of-code-retreat/">discovered the Software Craftsmanship community</a>.
(If they sound like your people too,
<a href="http://globalday.coderetreat.org">Global Day of Code Retreat</a>
is this Saturday, and I highly recommend participating.)
I’ve had cause lately to reflect on how much
<a href="https://schmonz.com/2016/08/18/new-name/">my life</a>
<a href="https://schmonz.com/2016/03/03/why-i-went-to-fat-camp/">has improved</a>,
including how
<a href="http://www.wedotdd.com/interviews/companies/3">my role in the community</a>
has changed; if I hadn’t, spending a long weekend with Agile friends in
the venue’s main meeting room surely would have started the gears turning.</p>
<p><img src="https://schmonz.com/2016/10/16/IMG_3855.JPG" width="400" height="300" alt="the Morgan Stanley room" class="img" /></p>
<p>I came up with a few ways to offer folks an introduction to important
stuff that might normally make them uncomfortable:</p>
<ol>
<li><a href="https://twitter.com/ahmedavais/status/787312303976755200">Mob Programming ESPECIALLY for Non-Programmers</a>, during which we
used Vim to write C and almost got one FizzBuzz test to pass</li>
<li><a href="https://twitter.com/schmonz/status/787370782645063680">Test-Driven Development and Pairing for Non-Techies</a>
with
<a href="https://twitter.com/MarkBalbes">Mark Balbes</a>,
during which we “test-drove” and “refactored” a bit of prose
(<a href="https://web.archive.org/web/20230321132408/https://agileoutloud.wordpress.com/2018/05/11/tdd-by-storywriting/">Zach Bonaker’s writeup</a>)</li>
<li>”Show Me The Tech”, in which anyone interested to try/see/discuss any
technical practice could
<a href="https://twitter.com/schmonz/status/787682390374096896">pull me aside</a>
anytime
<a href="https://twitter.com/schmonz/status/787695479941312514">for 15 minutes</a></li>
</ol>
<p>The feedback I received suggested that this is a direction I might want
to keep going:</p>
<blockquote><p><a href="https://twitter.com/schmonz/status/787720856461979648">Closing circle at #ACCUS. My key learning: I can do a lot to help
non-developers better understand the work, and it’s needed and
wanted.</a></p></blockquote>
<p>Thank you to
<a href="https://twitter.com/TheAgileFactor">Jason Tice</a>
for giving us this
<a href="http://openspaceworld.org/wp2/what-is/">Open Space</a>,
and to everyone who joined me in finding meaningful ways to fill it.</p>
Refactorings for web hostinghttps://schmonz.com/2016/09/11/refactorings-for-web-hosting/Amitai Schleier2017-01-07T18:22:22Z2016-09-11T22:03:50Z
<p>I’ve been running a public web server since 1999, when my employer
registered <code>schmonz.com</code> for me as a gag gift. Last week, I
<a href="https://schmonz.com/2015/08/05/confessions-of-a-twitter-completionist/">learned from Twitterbrausen</a>
that in German, “Schmonz” means something akin to “bullshit”. That’s not
what my employer had meant by it; I consider nonetheless that my
incessant blogging has acquired a fine new patina of significance.</p>
<p>As I recall, when I was first looking for web server software, there was
not a wide variety to choose from.
<a href="http://httpd.apache.org/">Apache</a>
was popular and featureful, a safe default choice. As a novice
programmer, I was very much taken with the idea of building dynamic
sites, and Apache offered many ways to go about that. Done deal.</p>
<p>In the intervening years, my server machine has changed several
times, from
<a href="https://en.wikipedia.org/wiki/Macintosh%5FIIci">Macintosh IIci</a>
to
<a href="https://en.wikipedia.org/wiki/Mini%2DITX">Mini-ITX</a>
box to
<a href="https://en.wikipedia.org/wiki/Mac%5FMini">Mac Mini</a>
to
<a href="https://en.wikipedia.org/wiki/Xen">Xen</a> <a href="https://en.wikipedia.org/wiki/Virtual%5Fprivate%5Fserver">Virtual private server</a>.
(I’m particularly fond of the present arrangement wherein hardware is
someone else’s problem <em>and</em> I continue to have root access.) No
matter the system architecture, the OS has always been
<a href="http://www.NetBSD.org">NetBSD</a>,
which remains
<a href="https://twitter.com/schmonz/status/640968395027054592">unobtrusively thrilling</a>,
and the web server has always been Apache, which has gradually become
more noisome.</p>
<p>Between my own sites and those of friends I’ve hosted, I’ve needed many
times to adapt my Apache configuration to accommodate changes in
external modules (such as
<a href="http://www.tldp.org/HOWTO/Apache-Compile-HOWTO/php.html">mod_php</a>),
to interfaces (such as
<a href="http://wiki.apache.org/httpd/PHP-FPM">PHP via FastCGI instead</a>),
and within Apache itself (such as
<a href="https://httpd.apache.org/docs/2.4/mod/mod_access_compat.html">basic access control</a>).
Each time I forcibly revisited my config, I found myself revisiting my
discomfort with its complexity. I never felt sure that I understood
exactly, in its entirety, what my Apache installation would and wouldn’t
do. And as a result of years of entanglement and unclarity, I never saw
a way to give my users full administrative control over their own sites.</p>
<p>I’ve
<a href="https://schmonz.com/2015/11/04/incremental-effort-incremental-payoff/">been imagining moving off Apache</a>
for a while. But it always seemed like a project, so I never did
anything about it. I can’t usually afford to start on something unless I
know I’m going to be able to stop soon, and I won’t usually want to stop
unless I know how I can easily start next time. That leaves me needing a
sequence of small-enough steps in my desired direction. Or, more
precisely, two expectations: that at least one such sequence exists, and
that I’ll be able to discover one as I go.</p>
<p>Conveniently, I’ve had plenty of professional practice at
<a href="https://agilein3minut.es/20">incremental problem-solving</a>,
enough to identify my first few steps and start making progress.
Here’s the rest of the sequence, naming the
<a href="https://agilein3minut.es/29">refactorings</a>
I’ve found along the way.</p>
<h2>Step 1: Extract Virtual Host</h2>
<p>I wanted to see what I’d learn by persuading one site to become its own
self-contained thing running its own Apache instance. I picked a
relatively basic site, told the
<a href="https://schmonz.com/2016/09/11/system_apache.conf.txt">system Apache to reverse-proxy that virtual host</a>,
added just enough configuration to
<a href="https://schmonz.com/2016/09/11/site_apache.conf.txt">start a site-specific Apache on <code>localhost</code></a>,
verified that as far as I could discern the site
worked equally well, and cut over to the new configuration.</p>
<p>Inserting a proxy usually means, at the very least, server logs start
reporting requests coming from the proxy’s IP rather than the browser’s.
For this to be a refactoring, the system Apache needed to send an
<code>X-Forwarded-For</code> header (it automatically does), and the site-specific Apache needed
to know to look for it (by enabling the bundled
<a href="https://httpd.apache.org/docs/current/mod/mod_remoteip.html">mod_remoteip</a>).</p>
<p>Manually starting an instance of a service usually means the system
won’t automatically know how to do the same next time it boots up. For
this to be a refactoring, I needed to
<a href="https://schmonz.com/2016/09/11/site_apache_crontab.txt">add an entry to the site owner’s <code>crontab</code></a>.
To validate that the site would continue to be served by its
own Apache as well as it’d been served the old way, I rebooted the
system. The site stayed up.</p>
<h2>Step 2: Extract More Virtual Hosts</h2>
<p>Good, because there were 17 more sites to go. Each of them would also be
listening on its own non-standard port on <code>localhost</code>. To identify them
at a glance in <code>netstat</code>, I added the port to <code>/etc/services</code>. Now I had
a pattern worth repeating.</p>
<p>Some sites were more complex than others (PHP, language negotiation,
other wrinkles), but I didn’t need to invent their configurations from
scratch, merely uncover the tiny portions of the existing giant config
that were relevant and copy them over.</p>
<p>Near the end, I couldn’t start new Apache instances without increasing
some kernel IPC parameters (<code>kern.ipc.msgmni</code> from 40 to 80,
<code>kern.ipc.semmni</code> from 10 to 20). This felt like a small backward step.
I hoped to be able to undo it later.</p>
<p>It also might have felt like a small step backward to suddenly have lots
more instances of Apache. But it was a large step forward in my
understanding.</p>
<h2>Step 3: Remove Dependency (on Apache Modules)</h2>
<p>En route to that understanding, I was fairly sure I’d reduced the system
Apache to a single responsibility: being a reverse HTTP proxy. To
validate that it was no longer serving any other purpose, I turned off
most <code>LoadModule</code> directives — even the typical and enabled-by-default
ones — leaving only those that prevented Apache from running when I
tried turning them off.</p>
<h2>Step 4: Substitute Apache with <a href="http://www.eterna.com.au/bozohttpd/">Bozohttpd</a></h2>
<p>I’d been hoping to replace Apache with <code>bozohttpd</code>. Now that I had
small, explicit per-site configurations, I could try converting one. The
site worked, but the logs were missing lots of basic information. I
still think this is where I want to go, but since it’s not a
refactoring, I can’t go there yet.</p>
<h2>Step 5: Substitute Apache with <a href="https://www.lighttpd.net/">Lighttpd</a></h2>
<p>I tried
<a href="https://schmonz.com/2016/09/11/site_lighttpd.conf.txt">converting the same site from Apache to <code>lighttpd</code></a>,
which is a
little more featureful than <code>bozohttpd</code>. The site worked, and with
<a href="http://redmine.lighttpd.net/projects/1/wiki/Docs_ModExtForward">mod_extforward</a>
enabled, its server logs were indistinguishable from
Apache’s. I gzipped the now-retired Apache config to prevent it from
being used by mistake while keeping it for reference, updated the
site’s <code>crontab</code> entry to start Lighttpd instead of Apache, and
rebooted. Bingo!</p>
<h2>Step 6: Substitute More Apaches with Lighttpd</h2>
<p>I converted a bunch more sites. After doing a few, I figured out how to
extract shared configuration. Simpler sites have extremely short config
files (just a few lines). More complex sites only define what’s unusual
about them.</p>
<h2>Step 7: Remove Dependency (on Apache PHP FastCGI)</h2>
<p>With a few Apache-powered sites left to convert, I was pretty sure none
of them was using PHP. To test this hypothesis, I stopped the <code>php-fpm</code>
service. After a week, with nothing broken, I uninstalled it.</p>
<p>With only a few Apache-powered sites remaining, could I return kernel
IPC parameters to their default values? Yes, all the Lighttpd and Apache
sites ran just fine that way.</p>
<h2>Step 8: Get Married</h2>
<p>Getting married is the opposite of a refactoring. There’s no internal
change, but many callers have new expectations.</p>
<h2>Step 9: Substitute Remaining Apaches with Lighttpd</h2>
<p>I expected three sites to be relatively tricky to convert:</p>
<ol>
<li><a href="http://theschleiers.com/">theschleiers.com</a>
needed language negotiation to provide English or German content. I
didn’t want to futz with it until there was clearly no longer any
urgent need for information about the wedding.</li>
<li><a href="https://agilein3minut.es/">agilein3minut.es</a>
needed SSL, which I wasn’t sure whether to proxy at all. Turned out
to be easy to proxy because it’s the only HTTPS site I host at
present, and it looks like it might continue to not be a big deal if
and when I host more.</li>
<li><a href="https://schmonz.com/">schmonz.com</a>
needed
<a href="https://schmonz.com/2016/09/11/schmonz_apache.conf.txt">fancy URL rewriting for compatibility</a>
with
<a href="https://schmonz.com/2013/05/27/remembering-textpattern/">the site’s previous incarnation</a>.
I assumed it was going to, anyway. I wound up being able to translate
most of its Apache
<a href="http://httpd.apache.org/docs/2.4/mod/mod_rewrite.html">mod_rewrite</a>
config to
<a href="https://schmonz.com/2016/09/11/schmonz_lighttpd.conf.txt">Lighttpd’s expressive conditional redirects</a>,
and needed hardly any
<a href="https://schmonz.com/2016/09/11/lowercase-textpattern-categories.lua.txt">special-snowflake cleverness</a>.</li>
</ol>
<p>Once they were converted, there were zero remaining Apache-powered sites.</p>
<h2>Step 10: Substitute Apache with <a href="http://www.apsis.ch/pound/">Pound</a></h2>
<p>A single Apache instance remained: the system one that was nothing but a
reverse proxy to a bunch of Lighttpd instances.</p>
<p>Had I known that’d be its only job, I’d have chosen software designed
for the purpose. I knew that now, and chose Pound. On a non-standard
port, I figured out how to express a few sites’ worth of reverse
proxying in Pound’s configuration language, continued
<a href="https://schmonz.com/2016/09/11/pound.cfg.txt">until I’d translated everything</a>
in the Apache config, stopped Apache, and started Pound.</p>
<h2>Step 11: Remove Dependency (on Apache)</h2>
<p>Not a single Apache instance remained. To my knowledge, all sites were
operating as normal. After a week, I uninstalled Apache, deleted its
corresponding Unix user and group, and gzipped all its config files for
reference.</p>
<h2>Summary</h2>
<p>Apache had been serving multiple roles. I brought the number down to zero,
then got rid of it. To do that, I…</p>
<ul>
<li>Decoupled Apache (the virtual-host multiplexer) from Apache (the web server)</li>
<li>Gave each site its own Apache web server instance</li>
<li>Found a suitable replacement web server and converted all instances</li>
<li>Found a suitable replacement virtual-host multiplexer and switched to it</li>
<li>Turned software off, and left it off for a while, before uninstalling</li>
</ul>
<p>For human site visitors, all of these steps were genuine refactorings.
(Atypical and automated visitors might notice the HTTP header reporting
different server software.) For site owners, most of these steps were
also genuine refactorings. (In a couple cases, using the shared
Lighttpd config required changing the names of log files by a small
nonzero amount.)</p>
<p>I replaced one big application with two small ones. Better. Still, could
be more better.</p>
<h2>Room for improvement</h2>
<p>The replacement virtual-host multiplexer (Pound) feels simple, good, and
necessary, in the sense that nothing like it is included with the OS.
The replacement web server (Lighttpd) feels simpler and better, by far
— I understand what it’s doing, my users finally have full
administrative control over their own sites, and unlike Apache, this
configuration doesn’t require extra system resources — but NetBSD
<em>does</em> include a web server, the one I experimented with in Step 4. If
<code>bozohttpd</code> did a few more things, then “Replace Lighttpd with
Bozohttpd” would be a refactoring, one that could be followed
immediately by “Remove Dependency (on Lighttpd)”.</p>
<h2>Next steps</h2>
<p>I’ve been
<a href="https://schmonz.com/2016/07/08/how-to-learn-c-part-1/">practicing C</a>.
In some kind of cosmic coincidence, next week I’ll be joining a project
that’s being developed primarily in C. Hacking on <code>bozohttpd</code> will be
good practice. Here’s the incremental sequence of features awaiting my
next increment of time and attention, perhaps on tomorrow’s
transatlantic flight:</p>
<ol>
<li>Optionally log to a file (instead of <code>syslog</code> or <code>stderr</code>)</li>
<li>Optionally log more information (say, in Apache’s “combined” format)</li>
<li>Optionally specify a proxy or proxies that can pass an
<code>X-Forwarded-For</code> header whose contents we’ll use as the true client
source address (for logs, access control decisions, etc.)</li>
</ol>
<p>Since I believe I’ll be able to stop, I’ll be able to start. It might
not be terribly long before I have more progress to share.</p>
New namehttps://schmonz.com/2016/08/18/new-name/Amitai Schleier2016-11-12T01:39:43Z2016-08-18T15:14:35Z
<p>After
<a href="http://theschleiers.com/wedding">a week and a half in Chicago</a>,
we’re home. I’m still not entirely sure what happened. All I know is, we
weren’t married when we left, and photos like these offer some clues:</p>
<p><img src="https://schmonz.com/2016/08/18/rings.jpg" width="225" height="300" alt="Rings on our hands" class="img" /></p>
<p>As part of the deal, we both got ourselves a new name. Our friend
Henry explained:</p>
<blockquote><p>They wanted it to represent both of them…. Rebekka suggested the
idea to Germify the “Schlair” name, which is already a German word
meaning “veil”, by giving it its standard German spelling. This was
obviously the best idea. It was a short and satisfying conversation.</p></blockquote>
<p>He also saw fit to share a bit of
<a href="https://schmonz.com/2013/11/15/a-premeditated-improvisation/">my bad poetry</a>
in the ceremony. So I’ll share a few of my better words here:</p>
<blockquote><p>It’s because of you that I keep getting better at knowing what I need,
at choosing what to do about it, and at being able to do it. And it’s
because of who you are that what I need most is you, and what I choose
to do about it is this.</p>
<p>These are supposed to be my vows, but I have only one: I promise that
for us to continue having a fulfilling life together, there aren’t any
new promises we need to make.</p></blockquote>
<p>She said some nice things to me too. We’re very happy.</p>
<p><img src="https://schmonz.com/2016/08/18/faces.jpg" width="300" height="400" alt="Smiling selfie in the bridal suite after the ceremony" class="img" /></p>
How to learn C (Part 1)https://schmonz.com/2016/07/08/how-to-learn-c-part-1/Amitai Schlair2016-12-18T16:05:59Z2016-07-08T20:52:51Z
<p>Lately I’ve been trying to learn C,
<a href="https://schmonz.com/2016/06/18/training-tdd-for-embedded-c/">starting with online training</a>
a month ago, and continuing with daily practice.
Yesterday, inspired by
<a href="https://schmonz.com/2007/06/29/when-programming-chose-me/">a personal story</a>
I told on
<a href="https://schmonz.com/talk/20160616-developer-on-fire/">Developer on Fire 139</a>,
I wrote a C program to draw the
<a href="https://en.wikipedia.org/wiki/Mandelbrot%20set">Mandelbrot set</a>.
The first image it generated,
<a href="http://alistair.cockburn.us/Walking+skeleton">intentionally</a>,
didn’t look like much:</p>
<table class="img"><caption>Diagonal lines.</caption><tr><td><img src="https://schmonz.com/2016/07/08/mandel1.png" width="100" height="100" alt="First generated image: diagonal lines" class="img" /></td></tr></table>
<p>You’ll see that the image gets progressively better as I learn more.
Not even a metaphor.
Or is it?</p>
<p>I’m still getting the hang of C.
But I’m doing pretty well with the hang-acquiring.
You can too.
Here’s my advice.</p>
<h2>Bring your knowledge</h2>
<p>You’ll have a head start if you already feel:</p>
<ul>
<li>Productive in your preferred text editor</li>
<li>Confident with your preferred revision control system</li>
<li>Proficient in some other programming language (including writing,
running, and listening to automated tests)</li>
</ul>
<h2>Be mildly relentless</h2>
<p>Do a tiny bit of C each day.
Do more than a tiny bit, if you can.
Don’t do less.
If you miss a day, since you’re aiming for <em>mild</em> relentlessness, no big deal.
Just make sure to do a tiny bit the next day.
The tactic here is to bring C to your conscious attention often enough
to support the strategy.
The strategy: keep C rolling around in the back of your brain <em>all the time</em>.</p>
<table class="img"><caption>A circle.</caption><tr><td><img src="https://schmonz.com/2016/07/08/mandel2.png" width="100" height="100" alt="Second generated image: a circle" class="img" /></td></tr></table>
<h2>Get a running start</h2>
<p><a href="https://schmonz.com/2014/01/26/how-to-efficiently-learn-a-programming-language/">Learning a new language</a>
means learning to navigate in a new environment.
How to enter new code? build? run? change? test? organize?
The C language is merely one aspect of the world you’re entering.
If you’re not careful, your focus will be divided by more than one of
the things you don’t know well: a language, a build tool, a test
library, an IDE, etc.</p>
<p>If your goal is to learn C, pay as little attention to the other stuff
as you can get away with.
When you’re getting started, don’t try to choose the best compiler,
build tool, test library, or IDE, and <em>definitely</em> don’t try to choose
the best way to be installing them.
You’re not having those problems yet, so you don’t have enough context
to choose and the differences don’t matter much.</p>
<p>Start with an environment prepared by someone else.
<a href="http://cyber-dojo.org/">Cyber-Dojo</a> provides compilers, test frameworks, and a text editor, and runs in your browser.
You can be learning C <em>right now</em>.</p>
<h2>Take assignments</h2>
<p>Cyber-Dojo also includes <a href="https://en.wikipedia.org/wiki/Kata%5F%28programming%29">code katas</a>.
Pick one at random.
Write a trivial failing test and make sure it really fails.
Then read the instructions, think a little, and code a little.</p>
<p>You might have an idea of what to do and not know how to express it in C.
With a failing test, you can guess and check.
If it doesn’t compile, it’s not valid C; try again until it compiles.
If the test still fails, it’s C that doesn’t match your intention; try
again until it does.
Voilà: you’re learning C.</p>
<p>If you think taking a little time to work through a C tutorial would
help you move faster, do it.
If you think having a C reference at hand would get you unstuck more
quickly, find one.</p>
<p>When you’re satisfied with your solution, Cyber-Dojo has plenty more katas.
If you’d rather solve a real-world problem, maybe you’ve got one in mind.
Or maybe someone you know can ask you for help with something.</p>
<table class="img"><caption>The Mandelbrot set!</caption><tr><td><img src="https://schmonz.com/2016/07/08/mandel3.png" width="100" height="100" alt="Third generated image: the Mandelbrot set" class="img" /></td></tr></table>
<h2>Invest in your environment</h2>
<p>As you practice, you’re also learning what would help you be more productive.
For instance, your preferred text editor would probably help!
When you’re making good progress in Cyber-Dojo, you wish it could go a
little faster, and your tests are green, it’s time to continue the
kata offline.</p>
<p>On your machine, install the same test framework and a compiler (ideally
also the same).
You might have to twiddle the code to get it to build on your system.
Once the tests are green again, return to the kata: think a little, test
a little, code a little.
You’re learning C again — and now that you’re in an environment you
control, it’s worth (1) noticing what gets in your way and (2) taking
action to improve it.</p>
<p>If you want to run the tests frequently, teach your text editor to run
them with a keystroke.
If you want it to be easier to undo back to the last green state, <code>git
init</code> and start committing whenever you’re green.</p>
<p>If you’re frustrated by how long it’s taking to figure out a particular
improvement, it’s worth noticing that too.
Leave it for later — if it keeps being annoying, you’ll get more
chances to solve it — and get back to the cycle of learning: think a
little, test a little, code a little, commit on green.</p>
<p>Even if it’s
<a href="https://schmonz.com/2013/06/10/area-under-the-curve/">sometimes frustrating</a>,
incrementally removing bottlenecks to your productivity is incredibly worthwhile.</p>
<h2>…Especially in tools that can support you</h2>
<p>Your C compiler is willing to warn you about lots of potential mistakes,
and to treat warnings as errors.
You only have to ask.</p>
<p>Your editor might be able to show the same warnings and errors, in the
context where you made them, before you try to invoke the tests.
Seeing mistakes earlier helps you go faster.
Try it.</p>
<p>Your memory-management logic is easy to get wrong.
<a href="http://valgrind.org/">Valgrind</a> can tell you when and where you’ve made
basic mistakes.
You’ll want to run it less often than your unit tests, because it’s
slower, but when you’re dealing with <code>malloc()</code> and <code>free()</code> you’ll want
to run it pretty often.
(The longer you go between Valgrind runs, the harder it’ll be to figure
out where you screwed up.
<code>git bisect</code> might help.)</p>
<table class="img"><caption>Same thing, bigger.</caption><tr><td><img src="https://schmonz.com/2016/07/08/mandel4.png" width="400" height="400" alt="Fourth generated image: same thing, bigger" class="img" /></td></tr></table>
<h2><em>…Especially</em> in your fastest feedback loop</h2>
<p>You need to be able to rely on your tests to tell you when and where
something is wrong.</p>
<p>If it’s hard to spot when a test is failing, fix that.
I noticed myself having this problem with
<a href="http://www.throwtheswitch.org/unity/">Unity</a>,
so I wrote a
<a href="https://schmonz.com/2016/07/08/tap.pl.txt">tiny wrapper to run Unity tests from Perl’s <code>prove</code> tool</a>,
which paints failing tests red in a way I’m used to.</p>
<p>If it’s hard to know what a red test is trying to tell you, fix that.
Using
<a href="https://libcheck.github.io/check/">Check</a>,
for instance, when <code>ck_assert()</code> needs to tell you something, it
can’t say much.
Maybe there’s a
<a href="https://libcheck.github.io/check/doc/doxygen/html/check_8h.html">more precise assertion available</a>.
Otherwise, <code>ck_assert_msg()</code> at least lets you tell it what to tell you,
so you’ll understand what to do faster the next time it’s red.</p>
<h2>Invite your friends</h2>
<p>Pairing accelerates learning.
During my 3-day online training a month ago, I worked with a remote pair
the entire time.
Whenever you can find someone to pair with you, do it.</p>
<p>Experts accelerate learning.
That’s one of the reasons I took
<a href="https://www.wingman-sw.com/training/remote-delivered-tdd">that training course</a>
from
<a href="https://www.wingman-sw.com/about">James Grenning</a>.
More recently, I asked some
<a href="http://www.netbsd.org">NetBSD</a>
developers — who understand from experience how to see the costs and
risks of development in C — to review my code and suggest what I
might pay more attention to.
I’ve gotten some very thoughtful, articulate comments.</p>
<p><a href="http://exercism.io">Exercism.io</a>
has a
<a href="http://exercism.io/languages/c">nascent C track</a>,
and its exercises come with ready-made tests you can enable, one at a
time, to simulate part of the thinking that goes into TDD.
Since you’re not trying to learn a thinking technique, this helps you
focus on learning the language.</p>
<p>Exercism is also a way to invite code review.
When you post a solution, other Exercism users might notice, read, and comment.
Even if they don’t, your code’s posted at a stable URL and you can send
the link to anyone you like.
Or anyone you don’t like, if you like.</p>
<table class="img"><caption>Same thing, with points outside the set in light blue.</caption><tr><td><img src="https://schmonz.com/2016/07/08/mandel5.png" width="400" height="400" alt="Fifth generated image: same thing, with points outside the set in light blue" class="img" /></td></tr></table>
<h2>Choose small steps</h2>
<p>While trying to draw the Mandelbrot set in C, given that there were lots
of things I wasn’t sure how to do, I made extra sure to organize my work
into small steps:</p>
<ol>
<li>Since I’ve never used
<a href="http://libgd.github.io">GD</a>
before, start by generating an image — any image.</li>
<li>Since I’m not sure GD offers what I need, make sure it can color
individual pixels.</li>
<li>Since I keep opening the image to see whether it’s different, write an
<a href="http://approvaltests.com">approval test</a> to turn red whenever the
image has changed.</li>
<li>Since I want to try plotting an equation, test-drive mapping pixels
to <em>(x,y)</em> coordinates.</li>
<li>Since I think I got that right, try plotting the equation for a
<a href="https://en.wikipedia.org/wiki/Unit%5Fcircle">Unit circle</a>.</li>
<li>Since I instead got a weird blocky thing, figure out which
coordinate-mapping test I forgot to write, make it pass, and
try again.</li>
<li>Since I got a circle, refactor my <em>(x,y)</em> coordinates to <em>a+bi</em>
(<a href="https://en.wikipedia.org/wiki/Complex%5Fnumber">complex numbers</a>).</li>
<li>Since I don’t know C’s complex math functions, compute the Mandelbrot
set using C’s ordinary math operations on <em>a</em> and <em>b</em> separately.</li>
<li>Since that worked, refactor to C’s complex math functions.</li>
<li>Add some color.</li>
</ol>
<table class="img"><caption>Same thing, with points near the boundary by red or green according to escape velocity.</caption><tr><td><img src="https://schmonz.com/2016/07/08/mandel6.png" width="400" height="400" alt="Sixth generated image: same thing, with points near the boundary red or green according to escape velocity" class="img" /></td></tr></table>
<h2>Conclusion</h2>
<p>This post isn’t much about C after all, is it.
It’s about how to apply what you know, and what you know about what you
don’t know, to acquire what you want to know.
When you’re trying to learn something, do the fastest thing that gets
you a
<a href="http://alistair.cockburn.us/Walking+skeleton">walking skeleton</a>.
From there, iterate in tiny steps.
As soon as you’re satisfied,
<a href="https://schmonz.com/2015/02/25/the-when-to-stop-kata/">stop</a>.</p>
<p>It so happens that the Mandelbrot algorithm itself relies on iteration.
The more times you iterate over each point, the more accurate the picture.
But there’s no number of iterations that guarantees perfect accuracy,
and each iteration costs runtime.
So you have to choose how many iterations is good enough, and stop.
And that number depends on how fast your computer is, how far you’re
zoomed in, and what you want — in other words, on context.</p>
<p>Not a bad metaphor after all.</p>
<p>Not a bad exercise, either, and I’m not satisfied with it yet.
I’ve still got plenty of ideas for what I can learn.</p>
<p><a href="https://github.com/schmonz/c-mandelbrot/commits/master">To be continued…</a></p>
Training: TDD for Embedded Chttps://schmonz.com/2016/06/18/training-tdd-for-embedded-c/Amitai Schlair2017-05-22T21:12:09Z2016-06-18T15:29:02Z
<p>This week I ran a workshop. Last week I was in one.</p>
<p>For as long as I can remember, and probably longer, I’ve had a self-directed drive to learn, strong enough to be salient to observers. Lately I’ve become aware that I also have a periodic need for tiny doses of structured learning. Last week made this the third consecutive year I’ve taken some kind of training course. I observed the new pattern when I added <a href="https://wingman-sw.com/training/remote-delivered-tdd">James Grenning’s TDD for Embedded C</a> to <a href="https://schmonz.com/resume/">my résumé</a> and realized that if a recruiter or hiring manager saw nothing but the top three “Education” items, they’d get a remarkably accurate impression of me. I <a href="https://schmonz.com/coach/">coach</a>, I lead, I <a href="https://agilein3minut.es/about">Agile</a>, I solve problems, and I test-drive my code.</p>
<p>But not totally accurate. I don’t C.</p>
<p>Not much, anyway. I can think of a total of five bits of code I’ve ever written in C:</p>
<ol>
<li>A program to generate the Fibonacci sequence (iteratively and then recursively)</li>
<li>A <a href="https://en.wikipedia.org/wiki/Java%5FNative%5FInterface">JNI</a> library allowing Java programs to create a “link” (symlink on UNIX, shortcut on Windows)</li>
<li><a href="https://github.com/NetBSD/src/commit/d6fee2e18390c6d36b24859ae7ee948f2e08be5e">A <code>case</code> statement</a> in the <a href="http://wiki.netbsd.org/ports/macppc/">NetBSD/macppc</a> bootloader to allow system administrators to configure kernel behaviors (just like they already could on NetBSD/i386)</li>
<li>A bugfix for a <a href="https://en.wikipedia.org/wiki/Load%20balancing%20%28computing%29">load-balancing</a> appliance’s web admin GUI that wouldn’t display a particular table in (and only in) Internet Explorer if (and only if) the appliance lacked hardware <a href="https://en.wikipedia.org/wiki/SSL%20acceleration">SSL acceleration</a>, traced to some uninitialized <a href="https://en.wikipedia.org/wiki/automatic%20variable">automatically allocated</a> strings in the C <a href="https://en.wikipedia.org/wiki/Common%20Gateway%20Interface">CGI program</a> that emitted JSON for the <a href="https://en.wikipedia.org/wiki/Dojo%20Toolkit">Dojo Toolkit</a> GUI</li>
<li><a href="http://source.ikiwiki.branchable.com/?p=source.git;a=commitdiff;h=5da229aa51adcec27b109ebe2e696f7426cbd781">A <code>for</code> loop</a> that instructs ikiwiki, when run as a post-commit hook in a website repository, to do nothing whatsoever when the triggering event was a <code>cvs add <directory></code> (because that acts immediately on the repo, does not constitute a commit, and justifiably confuses ikiwiki if not filtered out)</li>
</ol>
<p>I’m pretty sure that’s everything.</p>
<h2>What I hoped for</h2>
<p>Last week’s course was designed for people who’ve been developing for embedded systems in C to become acquainted with Test-Driven Development in general and/or in that context. I, on the other hand, am <a href="https://schmonz.com/2015/08/12/tdd-saved-my-brain/">very comfortable test-driving</a> and I wanted to become better acquainted with C. I knew I wasn’t in the course’s target (ha!) audience — but I also knew that someone skilled with TDD can exploit its fast feedback to <a href="https://schmonz.com/2014/01/26/how-to-efficiently-learn-a-programming-language/">learn a programming language quite quickly</a>.</p>
<p>With this in mind, I signed up for the course as <a href="https://schmonz.com/2015/07/29/enthusiasm-engineering/">an act of self-engineering</a> designed to focus 3 days x 5 hours of my attention on the material I wanted to be learning. And I enlisted a pair partner to <a href="https://agilein3minut.es/9">help me stay focused and un-stuck</a>.</p>
<h2>What I did</h2>
<p>During exercises, my remote pair and I used <a href="https://screenhero.com/">Screenhero</a> to share screen, mouse, keyboard, and voice. We didn’t use any particular pairing style, other than a little <a href="http://c2.com/cgi/wiki?PairProgrammingPingPongPattern">ping-pong</a> to get rolling. My pair had written some C++ somewhat recently, and often had better guesses than mine about how to say our next idea in C. We both understood when and how to test our guesses as quickly as possible.</p>
<p>During the TDD lectures, we each muted our Screenhero to avoid echoing the incoming audio at each other. I generally continued working on the day’s exercise. Sometimes my pair would join me. Without sound, I’d wiggle my mouse cursor (Screenhero gives each user their own cursor) to indicate I wanted the keyboard.</p>
<p>Because my pair and I had similar levels of skill with TDD (good), C (meh), and pairing itself (good), I didn’t notice silence slowing our pace much. I did, however, notice it constraining the flow of humor.</p>
<p>Each evening, since we hadn’t gotten all the way down the exercise’s <a href="https://schmonz.com/2015/08/19/life-hacks-for-the-test-infected/">test list</a>, I’d continue working (solo) until we had. The following morning, I’d review with my pair.</p>
<p>We’d been doing the training exercises online in <a href="http://cyber-dojo.org/">Cyber-Dojo</a>, which is very convenient for getting started, especially when the instructor provides ready-made exercises with test-driven supporting code and well-thought-out test lists, along with all the needed tools. Once the course was over, I knew that to sustain my momentum, I’d need to be able to edit, build, and run tests in my usual development machine — and pronto. The day after the course, I created a local git repository, added all three exercises as we’d done them, installed <a href="http://cpputest.github.io/">CppUTest</a>, debugged the exercise builds on my particular host OS and compiler, and committed the fixes to <code>makefile</code>s and code to make the tests green. Then I dumped the next few things I know I want to try, in a sensible order, to a to-do list.</p>
<p>Now that I can run the tests from my usual editor with my usual keystroke, and won’t forget my next goal, I’m confident that my learning will continue.</p>
<h2>What I got</h2>
<p>I wanted to learn some C. I got what I wanted.</p>
<p>I also got geek joy. When we figured out just enough about bitwise logical operators to test the right thing, make it pass, then refactor to more expressive symbols, that was a programmer’s high. I’ve always wanted to understand this stuff. Given a goal, a fast feedback loop, and a pair, I was able to start understanding it.</p>
<p>The joy was greater because it was shared. Usually I’d consider it risky to pair remotely for three days with someone I’d never met. But if that pair is someone who works for <a href="http://www.pillartechnology.com/">Pillar</a> and thinks learning about TDD in C sounds awesome? I had no doubt in my mind we were gonna have a good time together, and we did.</p>
<p>Some of the joy was meta-joy. Since TDD is a great way to learn design and domain concepts, and I’ve used it to learn one programming language, I hypothesized that it might be a great way to learn another, and that sure feels true. I love it when a mental model holds up!</p>
<p>I’m also feeling joy in my self-mastery: knowing what I wanted to learn, knowing what I needed to <em>start</em> and <em>continue</em> learning it, and arranging to get what I needed. (I talked about when and how I learn, among other things, on <a href="https://schmonz.com/talk/20160616-developer-on-fire/">this week’s Developer on Fire</a>. I’d love to hear what you think.) And getting better in general at knowing what I want — like spending more of my time programming — and arranging to get it.</p>
<h2>What’s next</h2>
<p>There’s a particular refactoring direction I want to take one of the exercises. If it works out the way I hope, I’ll learn some C. If it doesn’t, I’ll learn some C.</p>
<p>We didn’t get to deploy to hardware. I’ve got a <a href="https://en.wikipedia.org/wiki/Raspberry%5FPi">Raspberry Pi</a> and an <a href="https://en.wikipedia.org/wiki/Arduino">Arduino</a>, never used. I’d like to test-drive a “Hello World” and see it run, then test-drive the basic use of a device-specific hardware feature and see it work. That’ll teach me some embedded basics. Once I’ve done that, I’ll have a better idea what I need to learn next.</p>
<p>Many NetBSD kernel drivers can be recompiled, with no source changes, into standalone userland programs. (<em>See also</em> <a href="http://rumpkernel.org/">rump kernels</a>.) This means test failures can crash the process, but never the kernel — so automated test suites can be run freely and frequently, and it might be possible and sensible to test-drive new functionality into the NetBSD kernel. I’d like to try. Maybe I’m closer than I think.</p>
Path to Agility 2016: Shoestring Agility in a Velcro Organizationhttps://schmonz.com/2016/05/26/path-to-agility-2016-shoestring-agility/Amitai Schlair2016-11-12T01:39:43Z2016-05-26T19:09:28Z
<table class="img align-right"><caption>Gesticulating</caption><tr><td><a href="https://www.flickr.com/photos/cohaa/26832083743/in/photostream/"><img src="https://schmonz.com/2016/05/26/26832083743_43eeb410c4_o.jpg" width="200" height="301" alt="Gesticulating" class="img" /></a></td></tr></table>
<p>At <a href="http://www.thepathtoagility.com/">Path to Agility</a>, I told
stories of “Shoestring Agility in a Velcro Organization”.</p>
<ul>
<li><a href="http://www.thepathtoagility.com/breakout-16/">Abstract</a></li>
<li><a href="https://schmonz.com/2016/05/26/path-to-agility-2016-shoestring-agility/slides/">Slides</a></li>
</ul>
<p>The stories are also available in written form as the
<a href="https://schmonz.com/tag/tdd-in-context/">TDD in Context series</a>.</p>
My speaking workflowhttps://schmonz.com/2016/05/25/my-speaking-workflow/Amitai Schlair2017-02-07T23:05:49Z2016-05-25T14:46:43Z
<h2>Previously</h2>
<ul>
<li><a href="https://schmonz.com/2015/09/16/my-coding-workflow/">My coding workflow</a></li>
<li><a href="https://schmonz.com/2015/09/23/my-podcasting-workflow/">My podcasting workflow</a></li>
<li><a href="https://schmonz.com/2015/10/14/my-writing-workflow/">My writing workflow</a></li>
</ul>
<h2>What I’ve been up to</h2>
<p>I’ve done very little writing lately. If it weren’t for my
<a href="https://schmonz.com/tag/not-talk/">guest appearances on other shows</a>,
I’d be doing zero podcasting. I’ve been traveling frequently for work and a
<a href="https://schmonz.com/2016/04/06/work-not-done/">whole bunch of conferences while effortfully maintaining new food and exercise habits</a>.
That’s all I’ve had time for.</p>
<p>After this week’s <a href="https://schmonz.com/talk/2016-path-to-agility/">Path to Agility conference</a>,
I’ll be traveling less and working from home more.
I expect to be writing regularly again, starting now.
Since I’ve been <a href="https://schmonz.com/speaker/">speaking regularly</a>,
I’ve been incrementally improving how I present and publish.
And since I’m about to take a break from conferences, here’s what I’ve
figured out so far.</p>
<h2>Notice CFPs of interest</h2>
<p>”CFP” == Call For Proposals. Or sometimes Papers, but I haven’t written
any of those, and am intimidated by the title.</p>
<p>I mainly become aware of conferences when
<a href="https://schmonz.com/2015/08/05/confessions-of-a-twitter-completionist/">someone I follow on Twitter mentions them</a>,
or sometimes when
<a href="https://schmonz.com/2015/06/24/agile-roots-2015-shoestring-agility-in-a-velcro-organization/">someone I meet in person recommends them</a>.
Last year I assembled a list of “2015 conferences I may want to attend”.
I found it so useful that I
<a href="https://gist.github.com/schmonz/8fe378c219e56f2250e1">did it again this year</a>.
Suggestions and corrections welcome!</p>
<p>Recently I became aware of the
<a href="http://www.techspeak.email/">Technically Speaking</a>
and
<a href="http://theweeklycfp.com">The Weekly CFP</a>
newsletters (probably via Twitter) and subscribed.</p>
<p>It’s also possible to bypass the usual talk submission process by
receiving a personal invitation to speak. I’ve been invited a few times.
When this happens, it’s very flattering, and it drives home the
continued need for me to participate in the usual process. I’ve had lots
of talks rejected. If I hadn’t kept at it, gotten some acceptances, and
made the most of them, the folks who’ve invited me to speak to their
audiences wouldn’t have known I had anything to offer.</p>
<p>Moral of the story: keep submitting, keep presenting, keep practicing.</p>
<h2>Write an abstract</h2>
<p>I have not, by any stretch, mastered the art of writing a winning
abstract. I do know what I like as an attendee. What draws me in? Among
other things, I look for a story from personal experience. That helps me
understand how being there might change my own story.</p>
<p>We discussed this on <a href="https://schmonz.com/talk/20160420-agile-for-humans/">Agile for Humans 032</a>.</p>
<h2>Save a copy</h2>
<p>If an abstract is accepted, I might want to submit it to more
conferences. If an abstract is rejected, I might want to tweak it and
submit it to more conferences. Either way, I don’t want to rely on
being able to pull a copy out of a submission system. I do my writing
in my personal wiki (an <a href="https://schmonz.com/tag/ikiwiki/">ikiwiki</a> instance, naturally), then
submit a copy.</p>
<h2>Rejected? Try again from the top</h2>
<p>Program committees and organizers don’t usually have time and energy to
give personalized feedback. If my talk was rejected, it’s up to me to
figure out what that might mean and what I might want to do about it. I
might try to find someone who gives talks and get their personalized
feedback. Or maybe it was one of the many perfectly good talks that get
rejected all the time, and submitting verbatim to another conference is
worth a shot.</p>
<h2>Accepted? Publicize</h2>
<p>I write a very short page linking to the conference, my session, and
where to buy tickets (if they’re still available), and I tag the page
<a href="https://schmonz.com/tag/talk-pending/">talk-pending</a>. That automatically adds it to the list of upcoming
appearances on my <a href="https://schmonz.com/speaker/">speaker page</a>, and also (via
<a href="https://schmonz.com/2013/06/10/area-under-the-curve/">rss2email</a>)
turns it into an email message, which gets sent to
<a href="https://schmonz.com/2016/02/22/my-new-mailing-list/">my low-volume mailing list</a>.</p>
<p>Sooner or later I’ll mention the talk on Twitter, etc., as well.</p>
<h2>[Talk planning goes here]</h2>
<p>I have no profound thoughts about how to put together a winning talk.
Have experiences, figure out what’s interesting about them, extract the
story arc.</p>
<h2>Write slides</h2>
<p>I’m not, as yet, attempting to design
<a href="https://vimeo.com/145917204">fast-paced, visually arresting slides</a>.
I’ve been trying to keep it simple for myself instead.
After several iterations, I’ve landed on a comfortable setup for writing
and publishing decent web-based slides.</p>
<p>I used to use <a href="http://meyerweb.com/eric/tools/s5/">S5</a>.
No special tools: write HTML, get slides. I was happy with it. Here’s a deck from
<a href="https://schmonz.com/2013/01/22/codemash-2013-your-dev-toolbox-everywhere/slides/">a lightning talk a few years ago</a>.</p>
<p>Last year, after <a href="https://schmonz.com/2015/01/01/happy-new-year/">migrating this site to ikiwiki</a>,
I was finally able to write new posts in Markdown.
I wanted to be able to write slides in Markdown too.
<a href="http://remarkjs.com">Remark.js</a> does that.
The easiest way to get started was to use it exactly as directed, then let
<a href="http://ikiwiki.info/plugins/rawhtml/">ikiwiki’s rawhtml plugin</a>
preserve it for publishing.</p>
<p>The third time I published Remark.js slides, I noticed it was my third
local copy of an old version of Remark.js. So I put it in a central
place, adjusted the three references, and upgraded to the latest version
— with git commits at each step, just in case I broke something. (I
<a href="https://schmonz.com/2015/04/29/signal-and-static/">love having my site in git</a>.)</p>
<p>This reduced duplication would certainly simplify my next slide-writing
experience. To simplify it further, I wanted to extract the shared HTML
and CSS. So I wrote a
<a href="http://ikiwiki.info/plugins/contrib/remark/">plugin for ikiwiki</a>
that provides the standard Remark.js template and styles, along with
ikiwiki-idiomatic ways of overriding the template and styles.</p>
<p>Now I write <code>my_slides.remark</code> just like I’d write <code>my_blog_post.md</code>.
I locally preview the same way, too: commit, triggering an incremental
render. Quick and easy.</p>
<h2>Finished? Publish</h2>
<p>When the talk’s over, I:</p>
<ol>
<li>Squash unneeded intermediate commits</li>
<li>Write a very short post linking to the abstract, slides, and any
other related information</li>
<li>Replace the very short publicity page with a redirect to the new post</li>
<li><code>git push</code></li>
</ol>
<p>This used to be a less streamlined process. Now I do it immediately
after the talk.</p>
<h2>Further improvements</h2>
<p>It’s a very common ikiwiki configuration to allow anyone to web-edit any
page. That’s not a smart thing to allow for pages that are
JavaScript-powered web slides. My site happens to be safe because I
disallow web-editing, but if I want to stop carrying around a local
copy of my code — and I do — then I need to make the plugin safe for
inclusion in ikiwiki. That will require more thinking and doing.</p>
<p>At some point, it may become important to me to make fancier slides than
Remark.js can produce. To do that, I’ll have to develop a new skill.</p>
Agile and Beyond 2016: Shoestring Agility in a Velcro Organizationhttps://schmonz.com/2016/05/05/agile-and-beyond-2016-shoestring-agility/Amitai Schlair2016-11-12T01:39:43Z2016-05-05T04:00:00Z
<table class="img align-right"><caption>Blur-o-Vision: Next-to-last story</caption><tr><td><img src="https://schmonz.com/2016/05/05/Cht6E_dXEAA1nly.jpg" width="400" height="305" alt="Blur-o-Vision: Next-to-last story" class="img" /></td></tr></table>
<p>At <a href="http://agileandbeyond.com/2016/">Agile and Beyond</a>,
I told stories of “Shoestring Agility in a Velcro Organization”.</p>
<ul>
<li><a href="http://agileandbeyond2016a.sched.org/event/65sf/shoestring-agility-in-a-velcro-organization">Abstract</a></li>
<li><a href="https://schmonz.com/2016/05/05/agile-and-beyond-2016-shoestring-agility/slides/">Slides</a></li>
</ul>
<p>The stories are also available in written form as the
<a href="https://schmonz.com/tag/tdd-in-context/">TDD in Context series</a>.</p>
PillarCon 2016: Web Architecture for Unix Lovers + Cross-Platform Full-Stack Deploymenthttps://schmonz.com/2016/04/16/pillarcon-2016-web-architecture-cross-platform-deployment/Amitai Schlair2016-11-12T01:39:43Z2016-04-16T17:19:16Z
<table class="img"><caption>Saturday morning at PillarCon</caption><tr><td><img src="https://schmonz.com/2016/04/16/IMG_6578.JPG" width="400" height="300" alt="Saturday morning at PillarCon" class="img" /></td></tr></table>
<p>My employer — with offices in Columbus, Ann Arbor, and Des Moines and
some consultants who don’t get to visit the offices very often — held
its first ever internal conference,
<a href="http://pillarcon.com">PillarCon</a>.
I chaired the “Delivery & Feedback” track, as part of which I held a
<a href="http://pillarcon2016.sched.org/event/6lyL/cross-platform-full-stack-deployment">breakout session on Cross-Platform Full-Stack Deployment</a>
(<a href="https://schmonz.com/2016/04/16/pillarcon-2016-web-architecture-cross-platform-deployment/slides/cross-platform-full-stack-deployment/">slides</a>).
I also gave a
<a href="http://pillarcon2016.sched.org/event/6lxj/web-architecture-for-unix-lovers">lightning talk on Web Architecture for Unix Lovers</a>
(<a href="https://schmonz.com/2016/04/16/pillarcon-2016-web-architecture-cross-platform-deployment/slides/web-architecture-for-unix-lovers/">slides</a>).</p>
AgileIndy 2016: Agile in 3 Minutes + Shoestring Agilityhttps://schmonz.com/2016/04/12/agileindy-2016-agilein3minutes-shoestring-agility/Amitai Schlair2016-11-12T01:39:43Z2016-04-12T04:00:00Z
<table class="img align-right"><caption>Blur-o-Vision: Whole audience up and talking</caption><tr><td><img src="https://schmonz.com/2016/04/12/IMG_5554.jpg" width="400" height="300" alt="Blur-o-Vision: Whole audience up and talking" class="img" /></td></tr></table>
<p>At <a href="http://agileindy.org/conference/">the fourth AgileIndy conference</a>,
I led off the proceedings with <a href="https://agilein3minut.es/about">Agile in 3 Minutes</a>.
To prepare ourselves to participate in the day’s learning, we (quickly)
introduced ourselves to two people, then (briefly) discussed what the
first two episodes made us think about and (briskly) shared a few
highlights with the whole audience.
My hope in making Agile in 3 Minutes is to help you
<a href="https://schmonz.com/2015/10/07/agile-in-3-minutes-the-book/">have more valuable conversations</a>.
In case today’s rapid-fire format helps you do that, here are the
<a href="https://schmonz.com/2016/04/12/agileindy-2016-agilein3minutes-shoestring-agility/slides/agile-in-3-minutes.pdf">slides</a>.</p>
<p>In a breakout session, I also told some stories
(<a href="https://schmonz.com/2016/04/12/agileindy-2016-agilein3minutes-shoestring-agility/slides/shoestring-agility/">slides</a>)
of “Shoestring Agility in a Velcro Organization”. You can find them in
written form on this site as the
<a href="https://schmonz.com/tag/tdd-in-context/">TDD in Context series</a>.</p>
<h2>Highlights from AgileIndy</h2>
<ol>
<li>Meeting someone who shared that “Before Agile in 3 Minutes, I
couldn’t get my team to have a conversation. Now I have to
timebox it.”</li>
<li>Seeing this effect firsthand, as 450 people had conversations
prompted by Agile in 3 Minutes.</li>
<li>Being told that in the hallway outside my breakout session, someone
told someone else, “Hey, that’s the Agile in 3 Minutes guy!” The
doors were closed. They must have recognized my voice.</li>
</ol>
<table class="img"><caption>Kicking things off with Agile in 3 Minutes</caption><tr><td><img src="https://schmonz.com/2016/04/12/AgileIndy-2016-035.jpg" width="300" height="200" alt="Kicking things off with Agile in 3 Minutes" class="img" /></td></tr></table>
AATC 2016: DevOps Dojo + Discussion Panelhttps://schmonz.com/2016/04/10/aatc-2016-devops-dojo-discussion-panel/Amitai Schlair2016-11-12T01:39:43Z2016-04-10T04:00:00Z
<p>At the
<a href="https://www.agilealliance.org/agile-alliance-technical-conference-2016/">inaugural Agile Alliance Technical Conference</a>,
I got to meet and hang out with lots of people I’ve looked up to for a
long time. It’s a thrill to have these face-to-face conversations, and I
don’t think becoming less new to consulting and conference-going will
ever make that less true.</p>
<h2>Sessions</h2>
<p>Of the conference sessions, my favorite was
<a href="http://www.jamesshore.com">James Shore</a> test-driving CSS in front of an
audience. For one thing, someday I’d like to have a larger fraction of
his immense skill at doing and explaining. (He’s made several hundred
<a href="http://www.letscodejavascript.com">screencasts about test-driving JavaScript</a>.)
For another, I was reminded that we as technologists already have
immense agency. Things are the way they are because people made them
that way; if we want things to be different, we can make them be
different.</p>
<p>Everyone who’s worked with Cascading Style Sheets knows it can be a pain
in the ass. James decided to do something about that, and started
building <a href="http://www.quixote-css.com">Quixote</a>. And for the entirety of
his presentation, my face was stuck in a big dumb grin. So good, for so
many reasons.</p>
<table class="img align-right"><caption>Flipboard: takeaways from DevOps Dojo</caption><tr><td><img src="https://schmonz.com/2016/04/10/IMG_6538.JPG" width="300" height="400" alt="Flipboard: takeaways from DevOps Dojo" class="img" /></td></tr></table>
<p>My session was a 90-minute interactive workshop called “DevOps Dojo”. We
simulated Dev and Ops being forced not to work together, felt
non-simulated frustration, talked about how artificial the constraint
really was, and finally worked together the way we wanted to. Here are
the takeaways we wrote down:</p>
<ul>
<li>Make repo readable to everyone</li>
<li>Exec sponsorship (training, “safe space to fail”, support for “doing
it right”, funding)</li>
<li>Focus on quality (metric: mean time to resolution)</li>
<li>Dev asks Ops about <em>their</em> needs</li>
<li>Exercise empathy</li>
<li>Be ready for change; practice change</li>
<li>Look for mutual interest</li>
</ul>
<p>You’re welcome to use
<a href="https://github.com/schmonz/devops-dojo">the workshop materials</a>
for any purpose, including your own workshop. If you do, I’d love to
hear about it.</p>
<h2>Video interview</h2>
<p>After my workshop, SolutionsIQ’s Leslie Morse asked me what it was
<em>really</em> about. Hint: not DevOps.
<a href="https://schmonz.com/talk/20160407-agile-amped/">Take a look</a>.</p>
<h2>Panel discussion</h2>
<p>Here’s a photo proving that I once sat at a table with
<a href="https://twitter.com/lauriewilliams">Laurie Williams</a>,
<a href="https://twitter.com/martinfowler">Martin Fowler</a>,
and <a href="https://twitter.com/rebeccaparsons">Rebecca Parsons</a>.</p>
<table class="img"><caption>Left to right: Rachel, Amitai, Laurie, Martin, Rebecca</caption><tr><td><a href="https://schmonz.com/2016/04/10/IMG_6552.JPG"><img src="https://schmonz.com/2016/04/10/aatc-2016-devops-dojo-discussion-panel/400x300-IMG_6552.JPG" width="400" height="300" alt="Left to right: Rachel, Amitai, Laurie, Martin, Rebecca" class="img" /></a></td></tr></table>
<p>See the name card? I was <em>supposed</em> to be there. Based on what folks
told me about what it was like to watch, listen, and ask questions,
<a href="https://twitter.com/rachellaycock">Rachel Laycock</a>’s
advance preparations enabled us panelists to have a conversation that
the audience appreciated being part of. Very effective moderating on her
part. For my part, in my first appearance on a panel, I appear not to
have disqualified myself from being invited on another one somewhere
someday. Here are a couple things I said that people liked:</p>
<blockquote><p>“<a href="https://twitter.com/rhoegg/status/718815855811780609">We’re making more software faster than we’re getting better at it.
We’re cruisin’ for a bruisin’.</a>”</p>
<p>”Software is a human activity. <a href="https://twitter.com/chrisshinkle/status/718821668852867073">To get better at writing software
together, we have to get better at being human together.</a>”</p></blockquote>
<h2>Further listening and reading</h2>
<p>Thank you to the Agile Alliance for creating this small, focused
conference and for inviting me to be part of it. And thanks to everyone
there who made the conference so enjoyable and valuable.</p>
<p>If you liked what I said and how I said it, try listening to a few
episodes of my micropodcast, <a href="https://agilein3minut.es/about">Agile in 3 Minutes</a>.
And if you particularly appreciated the idea of getting better at
being human together, try reading and sharing the
<a href="https://leanpub.com/littleguide">Little Guide to Empathetic Technical Leadership</a>
by <a href="http://maitria.com">Alex Harms</a>
with your nearest humans.</p>
Work not donehttps://schmonz.com/2016/04/06/work-not-done/Amitai Schlair2016-11-12T01:39:43Z2016-04-13T16:22:14Z
<h2>Saying yes</h2>
<p>After effectively
<a href="https://schmonz.com/2016/02/01/a-meta-sabbatical/">taking the winter off</a>,
I came back to work about a month ago. It was a nice soft landing, in
part because my new responsibilities are largely self-determined, and in
part because, between working from home and traveling together, I got to
be with my favorite person for four consecutive weeks.</p>
<p>The next four-plus weeks will be much different, because I’m mixing in a
densely packed bunch of conferences. I’m writing this in the air en
route to the first hop in the sequence: the new Agile Alliance Technical
Conference. I’m pretty excited about
<a href="https://schmonz.com/talk/2016-aatc/">my role in it and the people I’m about to meet</a>.
Same for <a href="https://schmonz.com/talk/2016-agileindy/">AgileIndy</a>,
the inaugural <a href="https://schmonz.com/talk/2016-pillarcon/">PillarCon</a>, and
<a href="https://schmonz.com/talk/2016-aab/">Agile and Beyond</a>.
I’ll also be attending
<a href="http://www.kalamazoox.org">KalamazooX</a>
and
<a href="http://selfconference.org">Self.conference</a>
(as planned, after
<a href="https://schmonz.com/2015/06/03/self-conf-2015-almost-self-less/">missing most of last year’s</a>).</p>
<p>That probably sounds like a lot. It sure feels like a lot. But in the
context of my top-priority project, the talks and travel are mere
temporary complications. My focus, above all else, is on strengthening
new habits about food and exercise.</p>
<h2>Saying no</h2>
<blockquote><p>Everything you can possibly not do, don’t do. Everything that’s left,
do well. Everything that’s done, see what good it does, quick.<br />
—<a href="https://twitter.com/schmonz/status/709921930493632512">Moi</a> on Twitter</p></blockquote>
<p>As you may have noticed, I haven’t written here in weeks, and there
hasn’t been a new
<a href="https://agilein3minut.es/">Agile in 3 Minutes</a>
since
<a href="https://agilein3minut.es/33">mid-December</a>.
These are deliberate decisions by me, in my role as Product Owner for my
one human self.</p>
<p>My health project is
<a href="https://schmonz.com/2016/03/03/why-i-went-to-fat-camp/">doing me an enormous amount of good</a>.
Because of that, until (and unless) it self-stabilizes enough to be put
on autopilot, I don’t have room for other projects. I do know I have
more to say, and perhaps more to accomplish, with Agile in 3 Minutes.
The thought of coming back to it, under the right conditions, excites
me. In the meantime, it’s work I can’t afford to do, so I’m maximizing
the amount of it I’m not doing.</p>
<h2>Upside</h2>
<p>If you haven’t listened to (or
<a href="https://schmonz.com/2015/10/07/agile-in-3-minutes-the-book/">read through</a>)
every last Agile in 3 Minutes, now you can take your time. As it stands,
the <em>œuvre</em> amounts to over an hour and a half of tiny thickets of
thought-thorns crooking to catch on brambles in your brain, and the
brains of your teammates, managers, and customers. For most people, one
or two episodes at a time is plenty to chew on. Masticate slowly, notice
when you’re full, and stop. You can have more later.</p>
<h2>Do me a favor</h2>
<p>If you’ll be at any of the above conferences, please come find me and
introduce yourself. I’d love to meet you and hear what you’re up to.</p>
AgileIndy March 2016: Behavior-Driven Development for Everyonehttps://schmonz.com/2016/03/09/agileindy-march-2016-bdd-for-everyone/Amitai Schlair2016-11-12T01:39:43Z2016-03-10T04:57:13Z
<p>At the March meetup of AgileIndy, I facilitated “Behavior-Driven
Development for Everyone”. I’d guess there were about 50 people sitting
and watching me program. I knew I wouldn’t be at my smartest on my feet
in front of a crowd, but I also knew I wouldn’t have to be, because we’d
work together to solve the problem. And we did. Lots of fun.</p>
<ul>
<li><a href="http://www.meetup.com/agileindy/events/226675257/">Abstract</a></li>
<li><a href="https://schmonz.com/2016/03/09/agileindy-march-2016-bdd-for-everyone/slides/">Slides</a></li>
</ul>
<p>Next month is this year’s
<a href="http://agileindy.org/conference/">AgileIndy conference</a>.
I’ll be there
<a href="https://schmonz.com/talk/2016-agileindy/">presenting different material</a>
and recording
<a href="http://ryanripley.com/agile-for-humans/">Agile for Humans</a>
with
<a href="https://twitter.com/ryanripley">Ryan Ripley</a>.
As of this writing, a few tickets are still available.</p>
<h2>Further Reading</h2>
<p>Besides the references in the slides, here’s a story of my own about
<a href="https://schmonz.com/2015/07/01/tdd-in-context-9-thwarted/">seeking greater effectiveness through BDD</a>,
from my <a href="https://schmonz.com/tag/tdd-in-context/">series about the human value of TDD</a>.</p>
Why I went to fat camphttps://schmonz.com/2016/03/03/why-i-went-to-fat-camp/Amitai Schlair2019-05-27T04:16:25Z2016-03-04T17:37:28Z
<p>A month ago, when I shared some of <a href="https://schmonz.com/2016/02/01/a-meta-sabbatical/">what I’d accomplished during my
time off</a>, I promised to share the rest
when I got back to work. I’m back now and there’s lots to tell, but most
of it will have to wait, because first I need to tell you about the
single most important thing I accomplished.</p>
<h2>I’ve been fat once before</h2>
<p>I grew up playing sports. I was decent at some of them, played a lot,
and enjoyed myself. I loved to run fast and jump high.</p>
<p>In 2002, having dropped out of college-the-first-time, gotten my first
programming job, and gained 40 pounds too many, I lost all the weight
(and <a href="https://schmonz.com/2003/12/07/atkins-vs-south-beach/">improved my blood chemistry</a>)
with the Atkins diet. At 23, changing how I ate was enough. When my
condition had sufficiently improved, I started playing competitive
Ultimate frisbee again. I was running fast and jumping high.</p>
<h2>I got better</h2>
<p>I promised myself I’d keep it that way. For the better part of the next
6 years, whether or not I was playing Ultimate, lifting weights,
learning Krav Maga, or eating French fries and ice cream (not usually at
the same time), my weight stayed in the right spot. When it went up a
bit, I’d eat carefully for a few days and it’d come right back down.</p>
<p>I was no longer on a strict Atkins diet, but I’d still occasionally be
reminded of my sensitivity to carbohydrate. After one weekend Ultimate
tourney, I came home more tired than usual — and despite running around
for two days straight, 10 pounds heavier. Why? The tourney had provided
the typical sideline fare of bagels, bananas, and soft pretzels, and I’d
eaten some. I have no other guesses. It took a full zero-carb week to
overcome my lethargy and point the scale back where it belonged.</p>
<h2>I broke my promise</h2>
<p>When I was considering college-the-second-time, one of the scariest
ramifications of the decision was the prospect of going deeply into
debt. I couldn’t begin to pay for <a href="https://schmonz.com/2005/06/28/arrivalderci/">where I wanted to
be</a> unless I got sizable private loans. I
accepted that, but in my final year, the loans didn’t accept <em>me</em>. (It
was the market downturn of 2008, a bad time to ask for credit. Still,
you’d think they’d factor in that a diploma would probably help me pay
them off for the previous three loans.) Even though I’d hoped not to use
it, I took the money my parents had set aside for my higher education.
Boy, was I lucky to have the option. It was enough to register for
classes and figure out the rest later.</p>
<p>Suddenly it was later. Exactly seven years ago, midway through my
final semester, with my credit cards maxed out, my bank balance said:
$80. I snapped to attention. No matter what, bills would soon be going
delinquent. All things being equal, I figured I’d rather have food on
the shelves than not, and spent all $80 at the grocery store before
one more bill could be auto-paid. To make my meager holdings last
longer, I sought out free food at events on campus. Occasionally
friends would treat me to something. It wasn’t often the sort of food
I’d prefer to eat. But I preferred even more, between March and May,
to be able to eat.</p>
<p>I had no plan for after that. I knew I’d have to move out of my student
housing after graduating, but to where? With what money? With what job
prospect might I stand a tiny chance of persuading anyone to lend me
money or put me up someplace? New York was expensive. I couldn’t even
afford to leave.</p>
<p>Also I was gaining weight. But so what? The risk of taking on all that
debt had turned into consequences. At 30, for the first time since I was
19, I couldn’t handle meeting my own basic needs.</p>
<h2>Friends saved me</h2>
<table class="img align-right"><caption>This cat once woke me from a nap, not because he was draped over my throat and mouth, but because his fur was poking into my nostrils.</caption><tr><td><img src="https://schmonz.com/2016/03/03/IMG_0449.JPG" width="400" height="300" alt="This cat once woke me from a nap, not because he was draped over my throat and mouth, but because his fur was poking into my nostrils." class="img" /></td></tr></table>
<p>Some extraordinarily generous friends invited me into their home with
their bright and bouncy two-and-a-half-year-old child and sweet and
cuddly older-gentleman cat. They lent me their car to move most of my
stuff into a storage facility they’d paid for. They fed me. They found
me some contract work that helped me back to my feet, which I followed
as soon as I possibly could to a cheap room in deepest Brooklyn, like
you do, in an apartment shared with weird flatmates and bold rodents. I
was relieved and happy to be able to pay my own way again, relieved
some more to be out of my friends’ hair, and happier still to be
undertaking the lifelong project of attempting to find ways to repay
them. Did I mention their home had been undergoing a construction
project at the time? One of them had forgone the use of her office so I
could live in it.</p>
<p>Another friend got me a full-time job, from which I ultimately learned a
great deal about effective software development and found my way toward
<a href="https://schmonz.com/coach/">what I do now</a>. But to begin with, I was mainly concerned with
<a href="https://schmonz.com/2014/06/01/tdd-in-context-1-keeping-my-job/">keeping my job</a>. As I grew
competent and confident within some context, I’d be given responsibility
for a larger, more stressful context. Doubtless my body was being bathed
in cortisol at all times.</p>
<p>Certainly I was urgently working at most times. I gained more weight.</p>
<h2>I started rebooting myself</h2>
<table class="img align-left"><caption>Schmonz Haven on day 1.</caption><tr><td><img src="https://schmonz.com/2016/03/03/IMG_4200.JPG" width="300" height="400" alt="Schmonz Haven on day 1." class="img" /></td></tr></table>
<p>I couldn’t manage to concern myself with that. I was occupied with my
comfort. As soon as I could just barely afford to move out of Rat Haven
into a quiet, spacious, calming apartment near my generous friends, I
piled up all my nickels to make the security deposit. The place remained
mostly shiny floors and white walls for months, but I didn’t mind. I was
there, alone, in my own space, calm and safe. I could afford to order
in, and did. I could work from home several days a week, and did, even
as my “desk” was a bookshelf plank laid across a couple upside-down
U-Haul boxes. I slowly built up my savings, credit, and furnishings.</p>
<p>Self-displays of agency were themselves comforting. I could visit
out-of-town friends on weekends, and did.</p>
<h2>I learned some things</h2>
<p>When I once again had some credit and some savings, I was able to take a
deep breath and reflect.</p>
<p>I didn’t have a family to somehow take care of. I never had to live on
the street or go hungry for days. I even got to keep all my stuff.
Still, I learned a lot about what it’s like to be poor. I’d already
understood that having money means no more and no less than having
options. Now I understood that being poor means you have many fewer
choices, and each of the good ones costs you far more, so you can’t
afford to make many good ones, so you keep having fewer choices. It’s
self-perpetuating.</p>
<p>I found that even when I started having money again, my mental state was
self-perpetuating too. When I’d wanted to do any small thing for myself,
since I couldn’t afford to do it, I’d write it down for later. This
habit, learned under deprivation, was very difficult to unlearn. In a
hundred tiny ways, my internal logic continued to be founded on the
assumption that “I can’t, not right now, I just can’t.” One case at a
time, when I observed myself limiting myself, I’d <a href="https://schmonz.com/2015/07/29/enthusiasm-engineering/">retrain
myself</a> that I could, right now, I
just could.</p>
<h2>I continued to boot up</h2>
<p>I got better, mostly. I even made a <a href="https://schmonz.com/2013/02/26/how-to-maybe-lose-45-pounds-in-a-year/">project of improving my
weight</a>. Changing the
way I ate lost me about 20 pounds, then stalled out. (I wasn’t 23
anymore.) I <a href="https://schmonz.com/2013/03/10/strength-gains-after-15-workouts/">returned to strength
training</a>, and it felt
great, but didn’t help me lose more weight. It was a minimum viable
health regimen: my energy felt relatively consistent throughout the day,
and for the first time in a while, I wasn’t getting fatter. But I wasn’t
running fast and jumping high, because that would’ve hurt; and I wasn’t
striving for it, because I couldn’t, not right then, I just couldn’t.</p>
<table class="img align-right"><caption>One of the many hills of southern Indiana.</caption><tr><td><img src="https://schmonz.com/2016/03/03/IMG_6495.JPG" width="300" height="400" alt="One of the many hills of southern Indiana." class="img" /></td></tr></table>
<p>On a 2012 road trip with my friend Henry, as we were driving through
northern Vermont toward Quebec, we were talking about what had happened
to me and what I’d been doing about it, and the conversation led me to
an insight: maybe the weight I was carrying around was the last chapter
of the story of a tough time in my life. As soon as I stopped carrying
it around, the story could be over.</p>
<p>It was a clarifying thought. I was thinking of it when I set out on
that 2013 weight-loss project. I was thinking of it last year when I
tried lifting twice a week on my own, and again when I hired a personal
trainer and worked out every day at lunch. And I was thinking of it
again when I couldn’t see any feedback that my incremental efforts were
doing any good.</p>
<p>During that time when I couldn’t do things for myself and had to write
them down for later, one of the less quotidian items I wrote down was
“go to fat camp”. Apparently I somehow knew that when the time came,
I’d need help and focus to get the needle to move in a way I could see.
That item sat, unaddressed, until I finally had money and time at the
same time.</p>
<h2>The last chapter</h2>
<p>On Saturday, I hiked 11 miles. I’d been doing a lot of hiking every day
for a few weeks, so that was no big deal. (Which is a big deal.)</p>
<p>Also on Saturday, I was deemed ready for a high-intensity strength
workout. It pushed me, and I responded by pushing myself at a new
level. Afterward, sitting outside in the spring February air to cool
down a bit, I was surprised to find myself weeping. That’s when I
realized it wasn’t a new level at all. It was a familiar old one, long
lost and now found.</p>
<p>I’m almost done rebooting. I can tell because I’m no longer concerned
only with my comfort, but also with <a href="https://schmonz.com/2015/10/14/my-writing-workflow/">productive discomfort</a>. I still have
an uphill climb to return to, say, Ultimate-playing shape. But I’ve
relearned how to push myself about how I push myself.</p>
<p>Can I finally see how this story will end?</p>
<p>I can, right now.</p>
<p>I just can.</p>
<table class="img"><caption>One of the many new dog friends who accompanied me on my hikes.</caption><tr><td><img src="https://schmonz.com/2016/03/03/IMG_6502.JPG" width="300" height="400" alt="One of the many new dog friends who accompanied me on my hikes." class="img" /></td></tr></table>
My new mailing listhttps://schmonz.com/2016/02/22/my-new-mailing-list/Amitai Schlair2020-11-30T11:23:32Z2016-02-22T21:52:54Z
<p>On the heels of <a href="https://schmonz.com/2016/02/15/birthday-week/">last week’s post</a>, I’ve
created a very simple notification list for my upcoming and recent
talks, podcasts, writings, and the occasional video. Interested?</p>
<p><a href="mailto:announce-subscribe@schmonz.com?subject=subscribe&body=1.%20Send%20this%20message%0A%0A2.%20Wait%20for%20the%20confirmation%20email%0A%0A3.%20Reply%20to%20confirm">📬 Join my announce list</a></p>
Birthday weekhttps://schmonz.com/2016/02/15/birthday-week/Amitai Schlair2016-11-12T01:39:43Z2016-02-15T13:52:48Z
<p>After the first of my three weeks at this fitness retreat, I’m pleased
with the outcomes:</p>
<ol>
<li>Since I’m working on strength, flexibility, and overall fitness, it’s
no surprise my muscles (and possibly metabolism) are waking up.</li>
<li>Despite not writing or recording anything (or otherwise working),
there’s been a surprising amount of new stuff with me in it. That’s
because other folks have been doing the hard parts.</li>
</ol>
<h2>Enjoy new stuff…</h2>
<ul>
<li>My first <a href="https://schmonz.com/talk/20160210-crash-course-crayon-x-factor-refactor/">Crash Course Crayon video</a></li>
<li>An <a href="https://schmonz.com/talk/20160212-developers-journey/">episode of Developer’s Journey</a></li>
<li>An <a href="https://schmonz.com/talk/20160214-agile-for-humans/">episode of Agile for Humans</a></li>
<li>An <a href="https://schmonz.com/talk/20160214-geek-joy/">episode of Geek Joy</a></li>
</ul>
<p>In the sidebar, under “Recent Showings”, you’ll notice links to each of
these (until something newer comes along). That’s because — thanks to
the evident need and the downtime between workouts — I’ve reorganized.
If you’d like to be notified of new stuff happening, each of these pages
has an RSS feed:</p>
<ul>
<li><a href="https://schmonz.com/tag/talk-pending/">Upcoming speaking engagements</a></li>
<li><a href="https://schmonz.com/tag/talk/">Past talks</a></li>
<li><a href="https://schmonz.com/tag/not-talk/">Other appearances</a></li>
</ul>
<p>In any case, if you’re here to see, hear, or read my opinions, I hope
I’ve made them easier to find.</p>
<p><a href="https://schmonz.com/2016/02/15/IMG_6429.JPG"><img src="https://schmonz.com/2016/02/15/IMG_6429.JPG" width="400" height="300" alt="An uprooted tree" title="An uprooted tree" class="img" /></a></p>
<h2>…While I’m replacing old stuff</h2>
<p>I’m here to uproot some of my habits, and perhaps some of the opinions
that have been reinforcing them.</p>
<p>Yesterday was a rest day. Today is not. Back to it.</p>
A meta-sabbaticalhttps://schmonz.com/2016/02/01/a-meta-sabbatical/Amitai Schlair2016-11-12T01:39:43Z2016-02-01T21:57:09Z
<p>I was to <a href="https://schmonz.com/2015/12/16/a-mini-sabbatical/">take six weeks off</a> until a
minor but very painful condition afflicted the plan’s back end: instead
of returning from a fitness retreat, I’m recovering from (very minor and
extremely helpful) surgery. It was convenient, as events were unfolding,
that those last three weeks had already been fully allocated to
improving my health. And this was an ideal wake-up call — impactful,
constraining, ultimately easily fixed and nothing serious — for a
fellow approaching yet another birthday since the last time he was in
playing shape. Next week at this time, thanks to the flexibility and
support of my employer, I’ll be at that fitness retreat after all.</p>
<p><a href="https://schmonz.com/2016/02/01/IMG_6383.JPG"><img src="https://schmonz.com/2016/02/01/IMG_6383.JPG" width="300" height="400" alt="One perk of working from home" title="One perk of working from home" class="img" align="right" /></a></p>
<p>This week I’m taking a brief meta-sabbatical from taking time off, doing
some fun company-internal stuff I don’t usually get to spend my
workdays doing. And I’m doing half of it from home, which affords such
activities as sitting outside with <a href="https://schmonz.com/2014/03/01/haskell-the-dog/">the dog</a>
and writing, and which constitutes both a change of pace from last year
and a setting of the pace for when I rejoin my current client (in a new
role) at the end of February.</p>
<p>Modulo CodeMash and this week of doesn’t-really-feel-like-work, I’ll
have been away for two and a half months. I seem to have backed into
hibernating for the winter, which is a neat trick, though I’m not at all
eager to repeat the experience. What I’m plenty eager about is expecting
to be returning in my best health in years.</p>
<p>Here’s a bit of what I got done during my time off:</p>
<ul>
<li>Created an RSS feed for <a href="https://schmonz.com/tag/talk-pending/">my upcoming speaking
engagements</a>, including the <a href="https://schmonz.com/talk/2016-aatc/">inaugural Agile
Alliance Technical Conference</a></li>
<li>Posted missing materials from <a href="https://schmonz.com/tag/talk/">many past talks</a></li>
<li>Spoke at CodeMash: one <a href="https://schmonz.com/2016/01/09/codemash-2016-shoestring-agility-in-a-velcro-organization/">regular
talk</a>
and one <a href="https://schmonz.com/2016/01/22/codemash-2016-agile-in-3-minutes/">lightning talk</a></li>
<li>Recorded an episode-to-be of <a href="http://maitria.com/podcast.html">Geek
Joy</a></li>
<li>Recorded an episode-to-be of <a href="http://ryanripley.com/agile-for-humans/">Agile for
Humans</a></li>
<li>Still expecting to see a couple short, stylish YouTube videos at
<a href="https://www.youtube.com/channel/UC3T-G4lJB-cKbL8PT7ya1Mg/videos">Crash Course
Crayon</a>
soon</li>
</ul>
<p>I’ll tell you the rest when I get back.</p>
CodeMash 2016: Agile in 3 Minuteshttps://schmonz.com/2016/01/22/codemash-2016-agile-in-3-minutes/Amitai Schlair2016-11-12T01:39:43Z2016-01-22T19:07:06Z
<p><em>Schmonzcast #20</em>: It was during <a href="http://agileandbeyond.com/2015/">last year’s Agile and
Beyond</a> lightning talks that I
<a href="https://schmonz.com/2015/07/15/introducing-agile-in-3-minutes/">introduced my new micropodcast</a>.
The night before, to have something to announce, I’d written, recorded,
and published two episodes: one to <a href="https://agilein3minut.es/1">frame my aims</a>, one
to <a href="https://agilein3minut.es/2">start fulfilling them</a>. I hoped folks would go find
them, listen, and be interested to hear <a href="https://agilein3minut.es/archive">what might
come next</a>. During the <a href="http://lightningvote.com/events/10">CodeMash lightning
talks</a> a couple weeks ago, I tried a
more direct approach: given the 5-minute timebox, if I moved fast, I
could get through both of those introductory episodes. Here they are, in
the first ever live performance of <a href="https://agilein3minut.es/about">Agile in 3
Minutes</a>.</p>
<ul>
<li><a href="https://schmonz.com/2016/01/22/codemash-2016-agile-in-3-minutes/slides/agile-in-3-minutes.pdf">Slides</a></li>
<li><a href="https://schmonz.com/2016/01/22/20160106-agile-in-3-minutes.mp4">Video</a> (excerpted from the
<a href="https://youtu.be/uUoNbIFFXN4?t=33m8s">original, by ZAGGStudios, of all the lightning
talks</a>)</li>
</ul>
CodeMash 2016: Shoestring Agility in a Velcro Organizationhttps://schmonz.com/2016/01/09/codemash-2016-shoestring-agility-in-a-velcro-organization/Amitai Schlair2016-11-12T01:39:43Z2016-02-25T01:36:26Z
<p><em>Schmonzcast #19</em>: Three years ago, I attended my first big tech
conference. At <a href="http://www.codemash.org">CodeMash</a> 2013, the contrast
with my workplace made apparent just how isolated I’d been from
modern software practice and its practitioners. I was reminded that
other kinds of workplaces exist. And I found myself, revealingly,
a bit embarrassed to tell people where I worked. CodeMash was a
catalyst for changing my job and reshaping my career. Now I’m a
<a href="https://schmonz.com/coach/">software development coach</a> with
<a href="http://www.pillartechnology.com">Pillar</a> because I want to help
folks who are trying to do good work and finding it painful, a
struggle I know well. In this talk from my fourth CodeMash — and
first as a speaker! — I share some stories of that struggle.</p>
<ul>
<li><a href="http://www.codemash.org/session/shoestring-agility-in-a-velcro-organization/">Abstract</a></li>
<li><a href="https://schmonz.com/2016/01/09/codemash-2016-shoestring-agility-in-a-velcro-organization/slides/">Slides</a></li>
<li><a href="https://schmonz.com/2016/01/09/20160107-shoestring-agility-in-a-velcro-organization.mp3">Audio</a></li>
</ul>
<p>(I gave a <a href="https://schmonz.com/2015/06/24/agile-roots-2015-shoestring-agility-in-a-velcro-organization/">shorter version of this talk at Agile
Roots</a>.)</p>
<h2>Further Reading</h2>
<p>The talk was based on this series of articles:</p>
<div class="feedlink">
</div>
<p>
<a href="https://schmonz.com/2014/06/01/tdd-in-context-1-keeping-my-job/">TDD in context #1: Keeping my job</a>
</p>
<p>
<a href="https://schmonz.com/2015/04/15/tdd-in-context-2-a-last-minute-feature/">TDD in context #2: A last-minute feature</a>
</p>
<p>
<a href="https://schmonz.com/2015/04/22/tdd-in-context-3-deadline-pressure/">TDD in context #3: Deadline pressure</a>
</p>
<p>
<a href="https://schmonz.com/2015/05/06/tdd-in-context-4-continual-delivery/">TDD in context #4: Continual delivery</a>
</p>
<p>
<a href="https://schmonz.com/2015/05/13/tdd-in-context-5-fail-safe/">TDD in context #5: Fail-safe</a>
</p>
<p>
<a href="https://schmonz.com/2015/05/20/tdd-in-context-6-a-big-project/">TDD in context #6: A big project</a>
</p>
<p>
<a href="https://schmonz.com/2015/05/27/tdd-in-context-7-win-win/">TDD in context #7: Win-win</a>
</p>
<p>
<a href="https://schmonz.com/2015/06/10/tdd-in-context-8-no-secret/">TDD in context #8: No secret</a>
</p>
<p>
<a href="https://schmonz.com/2015/07/01/tdd-in-context-9-thwarted/">TDD in context #9: Thwarted</a>
</p>
<p>
<a href="https://schmonz.com/2015/07/08/tdd-in-context-10-testing-acceptance/">TDD in context #10: Testing acceptance</a>
</p>
A mini-sabbaticalhttps://schmonz.com/2015/12/16/a-mini-sabbatical/Amitai Schlair2016-11-12T01:39:43Z2015-12-19T09:42:10Z
<p>Last year at this time, I was nearing the long-awaited end of a
longer-than-needed sabbatical during which I was angling to <a href="https://schmonz.com/2015/09/02/how-to-get-hired-as-a-coach/">get
hired as a coach</a>. It worked
out. I’ve just finished up with my first client team. I’m already
feeling joyous pangs of anticipation about what might come next. I
should <a href="https://schmonz.com/2015/09/09/how-to-get-decent-at-coaching/">keep doing this</a>.</p>
<p>But not yet. Traveling every week for a year has worn me down. When
I’ve been less effective at caring for myself, I’m less <a href="https://agilein3minut.es/8">effective at caring for others</a>. I’m not ready to offer
myself in the way that coaching requires.</p>
<h2>Stop and recharge</h2>
<p>Feeling that I ought to keep doing this, but also feeling that I
can’t keep doing this, I did some self-<a href="https://agilein3minut.es/2">retrospecting</a>.
My first “try this” is to address my immediate need to look after
my own needs. So I’m taking six weeks off, starting now:</p>
<ul>
<li>Two in Germany to be with my in-laws-to-be for the holidays (as usual)</li>
<li>One in Ohio to be at CodeMash (as usual)</li>
<li>Three in Indiana at a fitness retreat (very much not as usual)</li>
</ul>
<p>As may be evident, the themes here are to renew and reinvest in my
connections to loved ones, to programming, and to my physical
health.</p>
<p>I’d hoped to <a href="https://schmonz.com/2015/11/11/less-effort-same-payoff/">build up a buffer of podcast
episodes</a> so the show would
continue uninterrupted in my absence. That didn’t happen. When I
recently <a href="https://schmonz.com/2015/12/02/one-streak-ends/">missed a week</a>, that was a
gift: it helped me let go of the idea that I must keep going no
matter what. When I was <a href="https://schmonz.com/2015/07/15/introducing-agile-in-3-minutes/">about to take some vacation in
July</a>, I highly doubted
my self-discipline, and the show was just taking flight; in my mind
it still is, but as of today it’s averaging over 300 downloads per
episode, for a total of more than 10,000. These days, I’m much more
willing to believe that I’ll start a new streak when I get back,
and that you might still be willing to pay attention when I do. So
my time off will also be a break from podcasting, from writing on
this blog, and <a href="https://agilein3minut.es/33">if I’m smart</a>, from <a href="https://schmonz.com/2015/08/05/confessions-of-a-twitter-completionist/">consuming
Twitter maniacally</a>.</p>
<h2>Then go slower</h2>
<p>My second self-retrospective “try this” is to address my need for
a pace I can better sustain. So my next assignment will need to
accommodate at least one travel-free week per month. That will give
me much more time with my favorite person and furballs, much more
rest, and the chance to participate in the thriving tech and Agile
meetups in my own neck of the woods.</p>
<p>I’m not sure yet what I’ll be doing when I get back to work in
February — perhaps at the same client, perhaps elsewhere. Whatever
that challenge is, I’ll be physically and mentally ready. It had
better be ready for <em>me</em>.</p>
<h2>Keep in touch</h2>
<p>I’ll be significantly less on the grid, but I won’t be off it. I’ll
be happy to hear from you about anything that’s on your mind.
Meanwhile, if you’d like to read more from me over the next month
and a half:</p>
<ul>
<li>Browse this blog’s <a href="https://schmonz.com/tag/">articles by tag</a></li>
<li>Read the “TDD in Context” series in the sidebar</li>
<li>Read other of my best-liked posts, also in the sidebar</li>
<li>Buy the <a href="https://leanpub.com/agilein3minutes">Agile in 3 Minutes book</a></li>
</ul>
<p>To hear and see more:</p>
<ul>
<li>Come to <a href="http://www.codemash.org/session/shoestring-agility-in-a-velcro-organization/">my CodeMash talk</a></li>
<li>Look for my first “Crash Course Crayon” video to drop in a couple
weeks on Pillar’s <a href="https://www.youtube.com/channel/UC3T-G4lJB-cKbL8PT7ya1Mg/videos">YouTube
channel</a>
(<a href="https://www.youtube.com/feeds/videos.xml?channel_id=UC3T-G4lJB-cKbL8PT7ya1Mg">RSS</a>)</li>
<li>Catch up on my seven guest appearances on <a href="http://ryanripley.com/">Ryan
Ripley’s</a> <a href="http://ryanripley.com/agile-for-humans/">Agile for
Humans</a> podcast
(<a href="http://feeds.feedburner.com/agileforhumans">RSS</a>)</li>
</ul>
<p>To hear me every day this week on <a href="http://softwaredevelopmenttoday.com/">Vasco
Duarte’s</a> <a href="http://www.scrum-master-toolbox.com/">Scrum Master Toolbox
Podcast</a>
(<a href="http://scrummastertoolbox.libsyn.com/rss">RSS</a>):</p>
<ul>
<li><a href="http://www.scrum-master-toolbox.com/2015/12/podcast/amitai-schlair-on-the-3-levels-of-depth-of-learning/">Fail Monday</a></li>
<li><a href="http://www.scrum-master-toolbox.com/2015/12/podcast/amitai-schlair-on-how-to-enter-a-team/">Team Tuesday</a></li>
<li><a href="http://www.scrum-master-toolbox.com/2015/12/podcast/amitai-schlair-on-leading-change-as-a-scrum-master/">Change Wednesday</a></li>
<li><a href="http://www.scrum-master-toolbox.com/2015/12/podcast/amitai-schlairs-view-on-succes-as-a-scrum-master/">Success Thursday</a></li>
<li><a href="http://www.scrum-master-toolbox.com/2015/12/podcast/amitai-schlair-on-the-importance-of-understanding-our-environment/">System Friday</a></li>
</ul>
<p>Behind on <a href="https://agilein3minut.es/">Agile in 3 Minutes</a>, or been meaning to
start? There’s never been a better time to catch up
(<a href="https://agilein3minut.es/archive/index.rss">RSS</a>).</p>
<p>If you’re minded to give me a holiday gift, I’d be grateful for
your <a href="https://www.patreon.com/schmonz">support on Patreon</a> and your
<a href="https://agilein3minut.es/33">feedback on Agile in 3 Minutes</a>.</p>
<p>It’s been a fantastic and formative year. For your attention and
encouragement, I thank you, and I hope to live up to it in 2016.</p>
When learning is harder to findhttps://schmonz.com/2015/12/09/when-learning-is-harder-to-find/Amitai Schlair2016-11-12T01:39:43Z2015-12-11T04:23:00Z
<h2>Expertise is learning</h2>
<p>This recent tweet resonated with people:</p>
<blockquote><p>An expert is someone who keeps learning even when learning is harder to find.<br />
—<a href="http://twitter.com/schmonz/status/672056461376155648">Moi</a></p></blockquote>
<p>I’m hesitant to claim expertise about much of anything — not least
because <em>being</em> an expert doesn’t imply <em>continuing</em> to be an expert
— but I’ll readily admit to being pretty good, when faced with a
problem, at learning whatever I need to learn to solve it. If I’m
expert at anything, it’s that.</p>
<h2>Debugging is learning</h2>
<p>This less recent tweet of similar form resonated with considerably
fewer people:</p>
<blockquote><p>A bug is a mental-model mismatch. Your mental model of the code
is a cache. To debug well, clear your cache.<br />
—<a href="https://twitter.com/schmonz/status/533320412755525632">Moi aussi</a></p></blockquote>
<p>A bug is when we thought we knew something and it turns out we
don’t. So debugging, by definition, is learning: figuring out what
we don’t know, then problem-solving our way to knowing it.</p>
<h2>I can’t stand debugging</h2>
<p>I like things I’m good at. I’m good at learning. I hate debugging.
Let’s debug <em>that</em>.</p>
<p>If we need an extended debugging session, we’ve screwed up. We’ve
arranged to have <a href="https://schmonz.com/2015/11/18/how-to-miss-deadlines/">no idea how close we
are</a> until we’re suddenly done
— if we’re ever done. We’ve arranged to spend an indeterminate,
unbounded amount of time and patience to learn something very
crucial and small, late in the game, when it’s expensive.</p>
<p>Had we arranged to spend a tiny bit more time and patience earlier,
we could have been directing our efforts much more productively
(and predictably) now. But here we are, debugging. If I can’t get
over my revulsion at having put ourselves in this situation, I
compound the cost. So I’ve learned to get over it and on with it.</p>
<h2>I’m okay at debugging</h2>
<p>I have no particular skill with debugging tools. I do have particular
skill at developing software in a way that minimizes the need for
debugging. Sometimes my ego-wires get crossed and I’ll take pride
directly in my lack of skill with debuggers. Whoops!</p>
<p>Even though I can’t stand debugging, it <em>is</em> learning and for that
reason I <em>am</em> (if I can get out of my own emotional way) somewhat
skilled at it.</p>
<h2>Debugging even when debugging is harder to do</h2>
<p>When my niece is ideating, she says “How about this?” Sometimes
more than once, to buy time, and perhaps also to generously prepare
me to board her flight of fancy.</p>
<p>How about this? There’s a bug. If we don’t fix it, a whole bunch
of related functionality that is very valuable (and urgently needed)
is fairly useless. So we need to fix it.</p>
<p>We didn’t write any of this code. We have only a surface familiarity
with the problem domain and the system architecture. We are,
nonetheless, going to be the ones working on this bug.</p>
<p>The bug is somewhere in a big pile of long-method, interspersed-concern,
tightly-coupled,
<a href="http://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/">ServiceLocator</a>-using,
completely-untouched-by-test code. (<a href="http://www.brainyquote.com/quotes/quotes/m/marktwain161288.html">But I repeat
myself</a>.)
Naturally, we didn’t uncover it until pre-production. We can
reproduce it fairly reliably there, given sufficient load and
concurrency. We haven’t been able to reproduce it in any other
environments. We aren’t allowed to attach a remote debugger in
pre-production (not that that’d help me, because I’m awesome at
not knowing debugger (whoops again!)).</p>
<h2>What can’t we do?</h2>
<p>This less unrecent tweet resonated with less fewer folks:</p>
<blockquote><p>Chasing a bug, how often do you ask “Did that fix it?” Be kind
to yourself. Get answers fast. Write a failing test first.<br />
—<a href="https://twitter.com/schmonz/status/634097662766280705">Moi-même encore une fois</a></p></blockquote>
<p>Do we know exactly where the bug is? No.</p>
<p>Can we reproduce the bug faster? Not that we know of. It would be
ideal if we could first reproduce it locally in any way whatsoever,
and then automate that with a failing test. We’d give ourselves
<a href="https://vimeo.com/145917204#t=1911s">many more chances per day</a>
to take actions that close in on the problem. But let’s say we know
enough about the components in interaction to know it’s prohibitively
expensive to try.</p>
<h2>What can we do?</h2>
<p>We can obtain server logs, and we see exceptions thrown from our code.</p>
<h2>The feedback loop</h2>
<p>Armed with the logs and the following technique, we can narrow down
where the bug must be hiding.</p>
<ol>
<li>In the logs, skip past the app server crud to the stack trace
from our code.</li>
<li>In the code, inspect the method that threw the exception.</li>
<li>In tests, identify all the ways that method can possibly throw
that exception. Use any means necessary to get under test.</li>
<li>For each place the exception could be thrown, add a guard clause
that returns a sensible value right after it writes uniquely
and identifiably to the server log.</li>
<li>Deploy; reproduce the bug; collect the logs; verify that the
new exception is coming from one level down the call stack; goto 2.</li>
</ol>
<p>This is legacy code. We’ll increase visibility to make clunky
private methods testable. We’ll mock anything and everything that
should have been a fakeable dependency. The tests will be inelegant,
but <em>we’ll have some</em>. The code is already inelegant, untested,
and buggy. We’re making it slightly more inelegant, but so what?
We’re going to make it less buggy where it really counts, and we’re
going to leave behind tests covering code that was evidently both
valuable and hard to get right.</p>
<p>When we detected the system’s fingers tingling, that was just a
symptom. The technique here is to squeeze the capillaries and push
toward the heart of the bug. N times through the feedback loop, as
we’re putting tests around the Nth method down the stack, we’ll
realize we’ve arrived. This must be the place. Then we can write
a test that’s red because the bug exists, and turns green when
we’ve squashed it. When we redeploy and can no longer reproduce
the problem, it’s gone.</p>
<h2>Retrospective</h2>
<p>Despite all the obstacles, we figured out how to learn what we
needed to learn to solve the problem.</p>
<p>This method might seem like brute force. In a way, it is. If we’d
been test-driving all along, the effort would have been amortized,
and it wouldn’t have occurred to anyone that concerted effort was
required to avoid this bug. It probably wouldn’t have occurred to
anyone that this bug could even exist; after all, it didn’t occur
to us this time.</p>
<p>If we needed brute force, it’s because we made ourselves need it.
We are not obligated to continue doing this to ourselves.</p>
One streak endshttps://schmonz.com/2015/12/02/one-streak-ends/Amitai Schlair2016-11-12T01:39:43Z2015-12-05T19:24:41Z
<p>For the first time since mid-May (and only the second time since
the show started in April), there’s no <a href="https://agilein3minut.es/">Agile in 3
Minutes</a> this week.</p>
<p>It’s not that I didn’t write one. I did! But I wasn’t able to put
it together until I was sitting at the gate waiting to fly home.
And the microphone that makes the show sound any good is, intentionally,
enjoying a quiet weekend back at the hotel.</p>
<p>Doing final edits in the air, I found myself a bit disappointed.
Couldn’t I have managed to finish this slightly earlier? Especially
because it’s a script I feel particularly good about. It builds on
<a href="https://agilein3minut.es/31">last week’s episode</a>, leads us in a direction
I’m eager to explore next, and calls back into one of the very few
early episodes about practices. (Agile in 3 Minutes is, intentionally,
<a href="https://schmonz.com/2015/09/23/my-podcasting-workflow/">mostly not about what to go do</a>.)</p>
<p>Yet I also felt some relief. Traveling every week for a full-time
consulting gig while <a href="https://schmonz.com/2015/09/30/habit-forming/">writing two new pieces every week since
April</a> has been a sustained challenge
to my willpower and self-discipline. When I chose to leave the mic
behind at the hotel, I was choosing to end my current weekly podcast
streak. I think I’d rather not take this work home with me? Then
don’t. And that was that.</p>
<p>All day, I felt myself refilling with ideas, energy, and desire to
write. By evening, when I got to the airport, the thing I was
jonesing for wasn’t to get my unformed thoughts out of my head. It
was to put in the work to form them into a show.</p>
<p>Interesting.</p>
<p>With that in mind, I’ve decided that a few weeks from now, I’ll
break my weekly blog streak too. I’ll explain more about my intentions
and plans before I go. Rest assured, it’s all stuff I’m excited
about. And I’m excited about next week’s Agile in 3 Minutes, to be
recorded and published as soon as I meet back up with my trusty
microphone.</p>
<p>Meanwhile, if you’re a bit behind on your listening, right now’s
a great time to catch up — <a href="https://agilein3minut.es/">3 minutes</a> at a time.</p>
Equipped to podcasthttps://schmonz.com/2015/11/25/equipped-to-podcast/Amitai Schlair2016-11-12T01:39:43Z2015-11-26T17:20:18Z
<h2>Processes and tools</h2>
<p>The folks who gave us the <a href="http://agilemanifesto.org">Agile Manifesto</a>
wrote “We have come to value individuals and interactions over
processes and tools.” <a href="https://agilein3minut.es/">Agile in 3 Minutes</a>, my
micropodcast about doing business effectively, reflects the same
valuation. What I’m offering each week is the best of myself I can
give. What I’m hoping for each week are more and <a href="https://schmonz.com/2015/10/07/agile-in-3-minutes-the-book/">better interactions
between you and the folks you work
with</a>.</p>
<p>There are, unavoidably, some processes involved. You may already
know <a href="https://schmonz.com/2015/07/15/introducing-agile-in-3-minutes/">how Agile in 3 Minutes
began</a>, <a href="https://schmonz.com/2015/08/26/audio-in-a-tweetshell/">how it became
playable directly within Tweets</a>,
and <a href="https://schmonz.com/2015/09/23/my-podcasting-workflow/">how it gets written and published each
week</a>. Now that I can mostly
focus on <a href="https://schmonz.com/2015/11/04/incremental-effort-incremental-payoff/">one new episode at a
time</a>, I’m trying
to <a href="https://schmonz.com/2015/11/11/less-effort-same-payoff/">maximize the amount of work not
done</a>.</p>
<p>And in those processes, I rely on tools. If I didn’t have them,
there probably wouldn’t be a show. It’s Thanksgiving in the USA and
I’m very thankful to have these tools to hand. I’d like to tell you
a bit about them.</p>
<h2>Tools I’ve paid for</h2>
<p>Writing is hard for me, so I <a href="https://schmonz.com/2015/10/14/my-writing-workflow/">arrange my writing environment
carefully</a>. It’s easier for me to
stay focused when there’s no way to have lots of open windows and
the screen isn’t too big. Current preference: iPad Air with the
<a href="http://www.ianker.com/product/98AP9804A-BTA">Anker Bluetooth keyboard</a>.</p>
<p>Episode scripts are plain-text essays with a title, an emphasized
word here and there, and the occasional bulleted list. As far as
my brain’s concerned, that’s just <a href="http://markdowntutorial.com">Markdown</a>.
<a href="http://www.textasticapp.com">Textastic</a> is a general-purpose text
editor for iOS that highlights syntax, counts words,
displays rendered Markdown, and syncs with Dropbox. (That’s how I
<a href="https://schmonz.com/2015/10/07/agile-in-3-minutes-the-book/">update the book</a> every
week with the latest essay.) Lately I’ve been experimenting with
<a href="http://agiletortoise.com/drafts/">Drafts</a> for the unconstrained
“writing” phase, reserving Textastic for the highly constrained
“editing, editing, <em>editing</em>” phase. I’m liking it.</p>
<p>When it’s time to record, I read into a <a href="http://www.bluemic.com/yeti/">Blue
Yeti</a> USB microphone connected to a
MacBook Air. I have a cheap pop filter, but it doesn’t fasten very
well to the Yeti and is mildly annoying to travel with, so I haven’t
been using it. Instead I’m speaking into the Yeti at a slight angle
and trying not to pop my P’s too hard. Know something else I could
try? Please comment on this post and let me know.</p>
<p>The Yeti isn’t great to travel with either — it’s large, somewhat
heavy, and periodically attracts the attention of TSA inspectors
— but the couple episodes I recorded into a <a href="http://www.samsontech.com/samson/products/microphones/usb-microphones/gomic/">Samson
GoMic</a>
were of noticeably lesser audio quality. The GoMic is very small
and will doubtless come in handy, but for Agile in 3 Minutes I
quickly returned to the Yeti.</p>
<p>To monitor what’s going into the microphone as I record, I use <a href="https://www.bose.com/products/headphones/over_ear_headphones/quietcomfort-25-acoustic-noise-cancelling-headphones-apple-devices.html">Bose
QuietComfort
25</a>
headphones. The noise-canceling feature is a nice touch in other
contexts (such as travel), but while recording, I want to hear any
and all hotel noise that might sneak in. I count on the Yeti’s
cardioid pattern to filter most of it out.</p>
<p>(My Yeti has a finicky hardware mute button, so I invested $5 in
<a href="http://mizage.com/shush/">Shush</a>. This doesn’t help with Agile in
3 Minutes, but it makes me a more polite guest on <a href="http://ryanripley.com/agile-for-humans/">Agile for
Humans</a>.)</p>
<p>The <a href="https://agilein3minut.es">agilein3minut.es</a> domain and a few
related domains are registered at <a href="https://www.hover.com">Hover</a>.
The SSL certificate is from <a href="https://www.namecheap.com">NameCheap</a>.
The site is hosted on a Virtual Private Server at
<a href="http://www.panix.com/v-colo/">Panix</a>.</p>
<h2>Open-source tools I use</h2>
<p>On the VPS, I run <a href="http://www.netbsd.org/donations/#how-to-donate">NetBSD</a>,
along with hundreds of third-party tools I keep updated with
<a href="http://pkgsrc.org">pkgsrc</a>. Audio and text content is stored in
<a href="https://git-scm.com">Git</a>, from which the website and RSS feed are
generated by <a href="http://ikiwiki.info/tipjar/">Ikiwiki</a>.
<a href="https://httpd.apache.org">Apache</a> is way overkill for serving up
static content, but several other sites on the same VPS were already
using it.</p>
<p>I also use <a href="https://schmonz.com/2013/01/22/codemash-2013-your-dev-toolbox-everywhere/">pkgsrc on my OS X
laptop</a> to
install and maintain Git, Ikiwiki, <a href="http://lame.sourceforge.net">LAME</a>,
and many other Unix tools. I do my (very basic) audio editing with
<a href="http://audacityteam.org/donate/">Audacity</a>.</p>
<p>I’ve contributed to NetBSD, pkgsrc, and Ikiwiki.</p>
<h2>Ways you can contribute to my work</h2>
<p>Thanks to the generosity of others, producing Agile in 3 Minutes
doesn’t cost me as much as it might. But it does require (aside
from the time I willingly put into it) some one-time and running
costs I wouldn’t otherwise be carrying. The microphone, I definitely
wouldn’t be carrying. <img src="https://schmonz.com/smileys/smile4.png" alt=";-)" /></p>
<p>Is Agile in 3 Minutes helping you have more and better interactions
at work? I’d love to hear about it. That’s all the gratification I
need.</p>
<p>Would you like to share the show with others, give me topic ideas,
read the essays at your own pace, or drip-fund the production of
new episodes? Then I’ll have even more to be grateful for. <a href="https://agilein3minut.es/support">Here’s how you can help.</a></p>
How to miss deadlineshttps://schmonz.com/2015/11/18/how-to-miss-deadlines/Amitai Schlair2016-11-12T01:39:43Z2016-02-12T06:24:48Z
<h2>Scope of this article</h2>
<blockquote><p>The 3 things almost every team does to meet deadlines that make things worse:<br />
1. Hire more developers<br />
2. Cut corners<br />
3. Work long hours<br />
—<a href="https://twitter.com/jasongorman/status/667607294386044928">Jason Gorman</a></p></blockquote>
<p>I must admit, my deadline-missing expertise is fairly wide-ranging.
But this piece is specifically about deadlines that arise when we
undertake to develop software, and how you can do your level best
to miss them.</p>
<h2>Set deadlines</h2>
<p>Don’t think too hard about whether they’re needed. When in doubt, set one.</p>
<h2>Set deadlines unilaterally</h2>
<p>Avoid taking input from the customer who depends on the outcome or
the team trying to deliver it. Take your best guess and call it
good.</p>
<h2>Disagree on “deadline”</h2>
<p>Some possible meanings of the word “deadline”:</p>
<ul>
<li>If we miss, we go out of business</li>
<li>If we miss, our customer goes out of business</li>
<li>If we miss, my manager will blame me and/or I’ll be fired</li>
<li>If we miss, I’ll blame you and/or you’ll be fired</li>
<li>I don’t think you’ve been working hard enough lately</li>
</ul>
<p>These meanings aren’t mutually exclusive. Several may be in play.
To maximize the impact on nervousness and perceived pressure of
these implied threats, your best move here is to keep things vague.</p>
<h2>Disagree on “done”</h2>
<blockquote><p>”Done” is about completion. “Off my plate” is about avoidance.<br />
—<a href="https://twitter.com/tottinge/status/566262938601013249">Tim Ottinger</a></p></blockquote>
<p>Some possible meanings of the word “done”:</p>
<ul>
<li>Our customers have had it for weeks and haven’t noticed anything
needing changing</li>
<li>Our customers just got it this second</li>
<li>Our customers could get it if they wanted</li>
<li>Our QA team is testing it</li>
<li>The code is feature-complete on a branch</li>
<li>It’s out of our hands</li>
<li>Nobody can blame us</li>
</ul>
<p>Time wasted shuttling between various kinds of “done” is key. Avoid
disambiguating. Use “done” to mean whatever’s convenient for it to
mean right now.</p>
<h2>Disagree on scope</h2>
<p>Preconceive your own notions of what needs doing. Again, avoid
taking input from your customer and your development team. Also,
avoid letting them take input from each other. If they talk to each
other regularly, you’ve got two problems:</p>
<ol>
<li>They might more directly understand each other’s needs</li>
<li>They might find creative ways to meet their needs in less time</li>
</ol>
<p>It’s mainly (2) you’re worried about here, for which (1) will put
you at risk if you let it. Don’t let it. Get shallow agreement on
a list of work items and don’t let anyone make you deviate from it.</p>
<h2>Don’t have a customer (sort of)</h2>
<p>If there’s definitively no customer, you’ve got <em>big</em> problems.
Since nobody’ll be affected, there’s no harm in shipping whatever
you’ve got right now.</p>
<p>Let me restate: <strong>With no customer, there’s nothing standing between
you and deployment.</strong></p>
<p>This constitutes an <em>enormous</em> impediment to your goal. What you
need instead is a feeling of certainty that your customers exist,
plus a lack of connection to any of them. Now you know there’s
someone out there who’s supposed to be able to judge whether today’s
product is better or worse for them than last week’s, and who can
remind you every now and then why what you’re doing matters.
Furthermore, your team knows that they can’t get direct answers to
the most fundamental questions about their work, and that they can’t
determine whether they’re doing anyone any good.</p>
<p>Well done! You’ve severed the most important feedback loop in their
work.</p>
<h2>Rate-limit deployments</h2>
<p>If you’ve got customers and you talk to them — or, worse, the
<em>team</em> is talking to them — all is not lost. You’ve got lots of
options for making it difficult to get new code deployed:</p>
<ul>
<li>Name an environment “production” without discussing uptime,
reliability, or other aspects of service</li>
<li>Limit who has access to “production” systems (this also helps
later, to complexicate debugging!)</li>
<li>Require several signoffs for each deployment</li>
<li>Provide as little information as possible to those responsible
for signing off, so they waver, sometimes ask for more information,
and occasionally exercise their veto powers</li>
<li>Make it just as difficult to roll back, which helps justify the
elaborate signoff procedure</li>
</ul>
<p>Now you’re considerably more likely to miss your deadline. If the
team somehow manages to produce exactly what customers need, it’s
going to take a while before they can get it. And otherwise, look
how long it’ll take before customers can identify new needs, before
the team can possibly hear about them, and before any work to address
these needs can even begin!</p>
<h2>Separate QA from Development</h2>
<p>As part of your overall strategy, you need “QA” to be its own team
and problem-identifying to be its own phase.</p>
<p>You want “Dev” working on their own, assuming QA will catch whatever
they missed. You want QA working on their own, assuming Dev is
following the most expedient path to claiming they’re done.</p>
<p>You want even the best-intentioned developer to say “done” as soon
as possible and feel free of responsibility when it turns out not
to be deployable. You want even the best-intentioned QA member to
say “good enough” as soon as possible while finding a few unimportant
bugs. You want Dev to be annoyed with QA when they find important
problems, and you want QA to be annoyed with Dev when they repeatedly
let important problems through.</p>
<p>This part of your strategy is very important. You slow down the
work today by splitting it up, you slow down the work indefinitely
by incentivizing placing blame over delivering value, and you make
it very difficult to make predictable progress against the plan.
At any given moment, it might look like you’re on target for a
deadline when you’re really not. Perfect!</p>
<h2>Separate Development from decision-making</h2>
<p>If you’ve managed to keep your team from talking to the customer,
good: they don’t know what you know about the business situation,
so nobody but you is in a position to decide how the team should
do its work.</p>
<p>You’ve heard Test-Driven Development takes longer because developers
are also writing tests, and you’ve heard <a href="https://agilein3minut.es/9">Pair
Programming basically takes twice as long</a> because two people are
doing one person’s work, but you have the sneaking suspicion that
pairing and TDD would <em>save</em> time by producing work output that’s
frequently deployment-ready to begin with.</p>
<p>Can’t have that. What would happen to your standalone QA phase?
What would happen if people’s attention were suddenly focused on
your lengthy deployment signoff process?</p>
<p>Don’t let them pair or test-drive; above all, don’t let them make
these choices themselves. Not on your watch. You’ve got deadlines
to miss.</p>
<h2>Keep code brittle</h2>
<blockquote><p>the only time we don’t change code is when there’s no existing
code, a starting state that lasts about 10 minutes.<br />
—<a href="https://twitter.com/GeePawHill/status/603750237748998144">Michael D. “GeePaw” Hill</a></p></blockquote>
<p>As a codebase grows, it tends to get harder to change. Because this
stems from the number of components in interaction, the difficulty
grows much faster than, say, lines of code. Great news! The odds
are already stacked in your favor.</p>
<p>You still need to be careful. Besides Pair Programming and Test-Driven
Development, you need to keep an eye out for the other Extreme
Programming technical disciplines. Beware <a href="https://agilein3minut.es/29">Refactoring</a>,
Continuous Integration, Collective Code Ownership, and the like.
They tend to have the effect of greatly reducing the risk of changing
code. That’s why the decisions to use these practices belong with
you, so you can veto them. You need code-change risk as uncontrolled
as possible.</p>
<h2>Scope creep of this article</h2>
<p>I said this article would only be about missing software deadlines.
It seems like it could pretty easily be about a lot more. Also, if
you’re a developer, I could give you lots more specific ideas for
making deadlines whoosh by. But I’ve already missed my self-imposed
Wednesday deadline for this week’s blog post. Like I said, I’m an
expert on this topic.</p>
<p>This list is far from exhaustive, but I hope — from the bottom of
my backlog — that I’ve helped you get started on more reliably
missing your deadlines.</p>
Less effort, same payoffhttps://schmonz.com/2015/11/11/less-effort-same-payoff/Amitai Schlair2016-11-12T01:39:43Z2015-11-13T15:44:32Z
<h2>Similar, but different</h2>
<p><a href="https://schmonz.com/2015/09/23/my-podcasting-workflow/">Creating my podcast</a> feels
like debugging. After quite a bit of trial and error, not knowing
how far I am from identifying and solving the problem, eventually
and suddenly it’ll be working for me. It takes however long it
takes, and then it’s a source-control commit message away from being
done.</p>
<p>In the case of the podcast, there’s more to it than that. Besides
recording — the fun part — there are a bunch of manual steps to
post-process, encode, publish, and publicize. I’m annoyed by
repetitive steps in general, and by these in particular, because
they stand between me and a hard-earned adrenaline hit. That makes
me slightly less happy to have finished another episode. Being able
to push a figurative button (or run a literal program) would make
me slightly <em>more</em> happy instead. I want that, and I’m getting
closer.</p>
<p>I do recognize I’m optimizing away from the bottleneck, considering
the script takes me hours to write. I’m not proud of that. If there
were a faster, easier way to reach into my brain and pull out
something of equal value, I’d do it in a second, or however many
seconds it’d take. Meanwhile, I observe that, thus far, <a href="https://schmonz.com/2015/11/04/incremental-effort-incremental-payoff/">incremental
value correlates roughly with incremental
effort</a>. <a href="https://schmonz.com/2015/08/19/life-hacks-for-the-test-infected/">As a
lazy person</a> I very
much want to reduce effort, but <a href="https://schmonz.com/2015/08/12/tdd-saved-my-brain/">as a
perfectionist</a> I very much don’t
want to compromise value.</p>
<p>Impasse.</p>
<h2>Unimpasse</h2>
<p>Or so it seemed, until I got to experiment with another way.
<a href="http://www.pillartechnology.com">Pillar</a>
has been making a series of short (3 minutes or less, usually)
videos on various topics pertaining to our business, and our
artist/producer Darrin Hoover came up to our Michigan office this
week with his multimedia rig and a bagful of black crayons. I talked
into the microphone on a couple technical topics I feel strongly
about, Darrin drew some images directly or imaginatively related
to what I said, we took some footage of me manipulating the drawings
on or around my face, and that was that. What a change of pace! —
the interactive collaboration with a creative partner who reflected
and amplified my ideas, the video aspect, the being blessedly
uninvolved in the production process.</p>
<p>Compared to my usual, this was <a href="https://schmonz.com/2007/05/14/schmonzs-theorem/">similar, yet
different</a>. I came away reinvigorated
about my usual. (I’ll share the two videos as soon as they’re up.)</p>
<h2>Rate of flow</h2>
<p>My podcast production has had no buffer (<a href="https://schmonz.com/2015/07/15/introducing-agile-in-3-minutes/">with one
exception</a>). Every week,
if I’m to publish a new episode, that requires that I bring a new
episode into existence. This needs to change, effective immediately,
because the travel routine that has afforded <a href="https://schmonz.com/2015/09/30/habit-forming/">my writing
routine</a> will come to an end in mid-December,
to be followed by six weeks of deliberately routine-busting time
off. So if I’m to continue shipping new episodes on schedule through
the end of January, then for the next five weeks I need to be writing
more than <em>two</em> new episodes per week.</p>
<p>That’s never felt possible before, but it feels possible now. For
one thing, I’ve seized on a new sequence of topics that excites me
(including this week’s <a href="https://agilein3minut.es/29">Refactor</a>). For another,
if I’m smart, I’ll learn from Darrin’s fast, unfiltered creative
process and tune my design for bringing you 3 valuable minutes.</p>
Incremental effort, incremental payoffhttps://schmonz.com/2015/11/04/incremental-effort-incremental-payoff/Amitai Schlair2016-11-12T01:39:43Z2015-11-05T03:30:32Z
<p>What you’re looking at here is a razor-thin allegory about incremental
improvement — why it can be hard to start, and why once started
it can be easy to continue — in the guise of a story about
improvements to this website.</p>
<p>I rang in 2015 by <a href="https://schmonz.com/2015/01/01/happy-new-year/">upgrading to a static site
generator</a>, hoping the switch would
<a href="https://schmonz.com/2015/07/29/enthusiasm-engineering/">induce me to write more often</a>.
It has, but that’s its own <a href="https://schmonz.com/2015/09/30/habit-forming/">story of incremental
improvement</a>.</p>
<p>Now that I’m making more and better use of my new, simplified setup,
I’m motivated to seek further simplification. Unlike many other
<a href="https://en.wikipedia.org/wiki/Content%5Fmanagement%5Fsystem">CMS</a>-managed sites,
this web page was neither brought into existence
when you asked for it nor recalled from an application-level cache
because someone else recently did so. This page already existed as
a plain old file on disk before you asked, and it’ll continue to
exist long after. It’s served slightly faster when it’s in the OS
kernel’s filesystem cache, but it’s served plenty fast to begin
with, because bringing it to you requires no application code to
run — just webserver code. That’s why my next major improvement
target is to stop needing Apache, a big featureful configurable
complicated webserver. It’d be neat if the small, just-featureful-enough,
and fairly simple <a href="http://www.eterna.com.au/bozohttpd/"><code>bozohttpd</code></a>
bundled with <a href="http://www.netbsd.org">NetBSD</a> (my server OS of choice)
sufficed to serve this site.</p>
<p>That’s a goal I couldn’t have seen from my previous <a href="https://schmonz.com/2013/05/27/remembering-textpattern/">traditional-CMS
vantage point</a>, and it’s still
not a thing I can just go do. I feel pretty strongly about preserving
URLs that have ever been published; if not for the featurefulness
and configurability of Apache’s <code>mod_rewrite</code>, many of the URLs
served under the old regime would have become broken under the new
one. In order to convince myself I no longer need this handful of
powerful URL-rewriting rules, I’ll need to convince myself the
permanent HTTP redirects have had an impact by observing that
old-regime links are hardly ever getting hit. And if that’s not the
case, I’ll need to convince enough of the referrers with those old
links to update them. Then, and only then, will switching webservers
finally be within my incremental reach.</p>
<p>Another new-regime payoff I hoped for was that because making small
improvements would be easier, I’d make more of them. That’s going
well, too. Textpattern had generated imperfect URL slugs for some
old posts, and that had always bothered me, but I’d never done
anything about it. Last week I finally fixed them, committed the
changes to source control, and added simple HTTP redirects (nothing
<code>bozohttpd</code> can’t do) for the old URLs. While I was at it, since I
discovered that “completionist” is more common usage than “completist”,
I did the same for my recent post on <a href="https://schmonz.com/2015/08/05/confessions-of-a-twitter-completionist/">reading Twitter like a
madman</a>. Ikiwiki
lets me make changes across my entire site with familiar Unix tools
— including <code>git diff</code> and <code>git revert</code> — rather than nerve-wracking,
potentially-destructive-and-hard-to-restore-from database operations.</p>
<p>Since I feel safer about making changes, I act on a higher percentage
of the little ideas that come to mind. On Monday, for instance, it
occurred to me that since my posts have tags, and there are already
autogenerated pages listing every post for each tag, I’d like to
add a page with a cloud-like list of all the tags. With ikiwiki,
it was really, really easy, so <a href="https://schmonz.com/tag/">I did it</a>. And once I’d done
it and was inspecting the result, I noticed that some old posts
needed more tags added. (Textpattern had no native tags, only
categories, no more than two per post.) And since this is Unix, I
could <code>grep</code> for files containing the keywords I wanted to tag, or
<code>find</code> all the posts from 2014, pass them to my text editor for
quick fixing, and <code>git diff</code> to double-check before publishing. So
I followed the chain of affordances and did all these things.
Exactly as I would not have bothered to in Textpattern.</p>
<p>Getting to where desirable improvements are available to be made
in small increments can be difficult. It took me a couple weeks of
disciplined effort to import my Textpattern site into ikiwiki <a href="https://github.com/schmonz/txp2ikiwiki">in
a way that I fully trusted</a>.
But once I got there, and improvements became easy to make and safe
to try, it’s so rewarding to try them that I keep doing it.</p>
<p>One of these moons, before I know it and without making a concerted
effort, flipping the switch to <code>bozohttpd</code> will be the next increment
in front of me. And then, because I can just do it, I’ll just do
it.</p>
A few conferenceshttps://schmonz.com/2015/10/28/a-few-conferences/Amitai Schlair2016-11-12T01:39:43Z2015-11-05T03:39:32Z
<h2>This week</h2>
<p>Monday morning, in my regularly scheduled stupid-early cab to the
airport, I
<a href="http://twitter.com/schmonz/status/658571412534374401">reflected</a>
on where I’ve come from (besides being home, in bed, asleep, like
a normal person) and where I’m going:</p>
<blockquote><p>6 years ago today, I came back to software development. To relearn
old tricks, uncover new ones, and enjoy. Headed to
<a href="https://twitter.com/search?q=%23agiledc">#agiledc</a> to celebrate.</p></blockquote>
<p>My celebration got off to a proper start when I didn’t miss <a href="http://www.renaissancesoftware.net/blog/">James
Grenning</a>’s good-naturedly
trenchant keynote, during which my still sleepy brain perked up at
the mention of my colleague <a href="http://www.daedtech.com/">Erik Dietrich</a>,
in particular his <a href="http://www.daedtech.com/how-developers-stop-learning-rise-of-the-expert-beginner">How Developers Stop Learning: Rise of the Expert
Beginner</a>.
For one thing, it induced a beperkifying spike of writerly ambition.
Maybe, if I <a href="https://schmonz.com/2015/09/30/habit-forming/">keep publishing something every
week</a>, I’ll eventually learn how to have
written something worth being referred to by a respected keynoter.
(Erik landed one of the guys who wrote the <a href="http://agilemanifesto.org">Agile
Manifesto</a>. Achievement unlocked.)</p>
<p>For another thing, hearing a familiar name put me in the right frame
of mind to enjoy <a href="http://agiledc.org">AgileDC</a> in what is, for me,
a whole new way of enjoying conferences. When I was an introverted
outsider <a href="https://schmonz.com/2015/08/05/confessions-of-a-twitter-completionist/">knocking on the
door</a> to this
small, tight-knit community of human-loving, business-advancing
Agilists, the primary way I felt I could extract value at conferences
was to attend talks and workshops of interest. Now that I’m working
in the field and getting to know <a href="http://adaptivecollaboration.com">some</a>
of the <a href="http://blog.gdinwiddie.com">wonderfully</a>
<a href="http://agilesquirrel.blogspot.com">generous</a> and
<a href="http://agileshrugged.com">skilled</a> folks in it, I spent most of
my day in the “hallway track” I’d heard so much about. It was great.
We <em>conferred</em>. I heard some terrific stories of personal growth
interspersed with perfectly obnoxious jokes. And I saw some people
I’d seen just last week.</p>
<h2>Last week</h2>
<p>Several of us <a href="https://schmonz.com/2015/06/17/problem-solving-leadership/">June 2015 PSL
participants</a> schemed to
<a href="http://twitter.com/schmonz/status/656660161554026497">hold a mini-reunion</a>
at the <a href="http://www.torontoagilecommunity.org/display/PUBLIC/Conference+2015">Toronto Agile
Conference</a>.
Some were based in Toronto, and others got their talks accepted,
so I accepted the need to get myself there from Detroit. I drove
up Monday afternevening and joined a bunch of the already-fed
speakers at a bar on a high floor overlooking downtown. (Toronto
is for real. I want to visit again for real.) Almost everyone who
was there I’d heard of, maybe Twinteracted with, but never met in
person. I wasn’t a speaker; there was no need for them to have
invited me along; and once again I found myself feeling, as I’ve
been feeling so often lately, the generosity and inclusiveness of
this community I’m getting to know.</p>
<h2>Next year</h2>
<p>Some of the folks I met in Toronto and D.C. have been invited to
present at a new <a href="http://agilealliance.org/programs/agile-technical-conference-2016-april-7-9-2016-raleigh-nc/">Agile Alliance Technical
Conference</a>
being held in April 2016. What’s a little mind-boggling, considering
what little I was doing a year ago, is that I’ve been invited too.
And I’ll also be reviewing submissions for the <a href="http://agile2016.agilealliance.org">Agile
2016</a> Leadership track.</p>
<h2>Right now</h2>
<p>There’s no way I can take in the pace of what’s happening for me
and not see the pattern of generosity and inclusiveness. There’s
no way I can not feel immense gratitude for all the people who’ve
helped me find my new path and make my way along it.</p>
<p>I see it. I feel it. Thank you.</p>
Corporate therapisthttps://schmonz.com/2015/10/21/corporate-therapist/Amitai Schlair2017-01-01T22:55:07Z2015-10-22T23:37:20Z
<h2>The power of associative memory</h2>
<p>On Sundays, we’ve been taking <a href="https://schmonz.com/2014/03/01/haskell-the-dog/">the dog</a>
to one of the many <a href="http://www.stateparks.com/southern_indiana_parks.html">forests of southern
Indiana</a> and
going for a nice long walk. Conveniently, by the time we’re done,
the sorry-ass Bears games I <a href="https://schmonz.com/2015/07/29/enthusiasm-engineering/">want to avoid
watching</a> have usually ended.</p>
<p><a href="https://schmonz.com/2015/10/21/haskell-brown-county.jpg"><img src="https://schmonz.com/2015/10/21/corporate-therapist/400x300-haskell-brown-county.jpg" width="400" height="300" alt="Haskell being done at Brown County State Park" title="Haskell being done at Brown County State Park" class="img" /></a></p>
<p>Last weekend, as we drove home through a town named Trevlac, I
remarked that that didn’t look like a word, but that backwards it’s
Calvert, which does. My <a href="https://agilein3minut.es/4">intuition</a> about language
and its constituent parts, developed over <a href="https://schmonz.com/2006/03/12/about-being-around-and-about/">a lifetime of playful
friendship</a>, was validated
by Wikipedia’s entry for <a href="https://en.wikipedia.org/wiki/Trevlac%2C%5FIndiana">Trevlac, Indiana</a>. Bekki
observed that when I perceive words and piles thereof, I’m also
perceiving a “gestalt”, because the ways I comprehend, manipulate,
and generate language are largely visual. For instance, when I hear
words, I see them. When I’m fishing for a particular word, I often
remember nothing about it besides how many letters I think it
contains; while I’m almost always right, that rarely helps me find
the word in any way I’m aware of. Maybe it narrows the search space
in some way I’m not aware of.</p>
<p>I looked up <a href="https://en.wikipedia.org/wiki/Gestalt">Gestalt</a> on Wikipedia to see whether the
term made any more sense since I last tried to understand it.</p>
<p>If <a href="https://twitter.com/HaskellDog">Haskell</a> had anything to say
about any of this, we couldn’t hear him with his head out the window.
The last street he and I gazed upon before leaving Trevlac was named
“Rogers.” I don’t know what he thought about that, but my associative
memory was primed to bring me straight to Carl.</p>
<h2>Who?</h2>
<p>Carl Rogers was a psychologist, a student and teacher of human
behavior. Bekki had somehow not encountered him in her studies of
social learning behavior in animals (people not excluded). And my
recollection of his approach was fuzzy. I pulled up Wikipedia’s
<a href="https://en.wikipedia.org/wiki/Carl%5FRogers">Carl Rogers</a> page and reviewed his 19 propositions,
among other things. For the most part, what we heard lined up nicely
with our own views.</p>
<h2>Why had I heard of him?</h2>
<p>I don’t know exactly, only approximately.</p>
<p>After spending much of my software development career indulging my
introvert tendencies as a programmer, I became aware that the
limiting factor in my effectiveness was not my ability to write
code — and not because I’m such a gifted programmer. (This came
up in conversation with <a href="https://twitter.com/BillyGarnet">Bryan Beecham</a>
and <a href="https://twitter.com/ryanripley">Ryan Ripley</a> on <a href="http://ryanripley.com/human-refactoring-with-bryan-beecham/">Agile for
Humans 019</a>.)
To grow as a person and become more effective in the workplace, I
found that I needed to acquire skill at <a href="https://agilein3minut.es/8">caring for
people</a>. In my consulting, <a href="https://schmonz.com/coach/">coaching</a>, <a href="https://agilein3minut.es/">podcasting</a>, <a href="https://schmonz.com/speaker/">speaking</a>, and writing, I’m always
looking to acquire more skill at caring effectively.</p>
<p>It had been suggested to me, earlier in life, that I consider a
career as a therapist. The suggestion had usually been intended as
a compliment, and sometimes also as an idea to be considered
seriously, but my immediate reaction to the prospect of making that
kind of emotional effort all day every day was to cringe. How could
I possibly have any love left to give when I got home? I tried to
accept the compliment, but couldn’t see how to accept the suggestion.
Yet here I am, years later, having found a context in which I could
accept it. When I became a consultant and coach, I decided that
someday, when I’m prepared to live up to the title, my business
cards (if we’re still using those) will read “Corporate Therapist.”</p>
<p>In my <a href="https://schmonz.com/2015/08/05/confessions-of-a-twitter-completionist/">exhaustive consumption of material from
Twitter</a> and
<a href="https://schmonz.com/2005/11/09/how-i-read-rss/">elsewhere</a>, I was pleased to discover
that my self-imagining wasn’t original. <a href="https://twitter.com/flowchainsensei">Bob
Marshall</a> has billed himself
as an <a href="https://flowchainsensei.wordpress.com/category/organisational-therapy/">Organizational
Psychotherapist</a>.
So he’s long been one of the folks I try to read most exhaustively.
When he expresses a sentiment, I try to make my own sense of it;
when he points at a source, I look at it more closely. Another of
the people I’ve learned most from following is <a href="https://twitter.com/onealexharms">Alex
Harms</a>.
Maybe they, or others, are how I rediscovered Rogers.</p>
<p>But I’d heard of him before, too. Not sure how.</p>
<h2>What more do I need to know?</h2>
<p>Thanks to Bekki, I made my entrance into
software development coaching with a highly useful frame of mind
that averted my immediately doing terribly. (This came up in
conversation with <a href="https://twitter.com/gdinwiddie">George Dinwiddie</a>
on <a href="http://ryanripley.com/002-agile-for-humans/">Agile for Humans 002</a>.)
What <a href="https://schmonz.com/2015/01/09/two-engagements/">luck for me</a>! Career-wise, too,
I mean.</p>
<p>Where I am now: having a somewhat better-developed intuition about
how people operate themselves, based in part on extrapolation from
how I operate myself, and in part on some basic mental models I’ve
long since internalized. (I don’t really know which and from where.
Rogers might say I’ve <a href="https://en.wikipedia.org/wiki/Introjection">introjected</a>
them.)</p>
<p>Where I want to be: training to become a corporate therapist. Further
developing my intuition about how people operate themselves, and
about how organizations of people can adapt themselves to become
more adaptive. Greatly <a href="https://agilein3minut.es/16">expanding my map</a> of the
vast territory before me.</p>
<p>What I need to learn, then, is this: much, much more about human
behavior.</p>
My writing workflowhttps://schmonz.com/2015/10/14/my-writing-workflow/Amitai Schlair2016-11-12T01:39:43Z2015-10-14T14:16:23Z
<h2>Previously</h2>
<ul>
<li><a href="https://schmonz.com/2015/09/16/my-coding-workflow/">My coding workflow</a></li>
<li><a href="https://schmonz.com/2015/09/23/my-podcasting-workflow/">My podcasting workflow</a></li>
</ul>
<p>Now that <a href="https://schmonz.com/2015/09/30/habit-forming/">it’s a weekly habit</a>, when I
set about writing one of these here blog posts, it’s not usually
happening <a href="https://twitter.com/neil_killick/status/652897091975409664">in the heat of a ranty
moment</a>. I
have to decide what to write about. That decision is based partly
on what I’ve written recently, in case there’s a logical sequence
waiting to be followed (like this one); partly on what’s happening
with me in work or in life, in case I need a new direction; and
partly on which of the available options leads me first to an idea
about how to write about it. I wasn’t setting out today to write
up another workflow. A fortuitous input led me there.</p>
<h2>Fortuitous</h2>
<p>A fellow participant in June’s <a href="https://schmonz.com/2015/06/17/problem-solving-leadership/">Problem Solving
Leadership</a> wrote me recently.
I had told him during PSL that one of my goals there was to be less
comfortable, because <a href="https://schmonz.com/2015/07/29/enthusiasm-engineering/">I default to
comfort</a>. He hadn’t shared that
goal at the time, but recently attended a training session that
perhaps changed his mind. “One thing I got out of it,” he wrote,
“is that uncomfortable leads to growth.” So he had a question for me.</p>
<h2>Have I been less comfortable?</h2>
<p>Yes, in at least one way: since April, when I started my current
streak of <a href="https://schmonz.com/2015/04/01/to-scale-agile-delegate-risk/">one new blog post</a>
and <a href="https://agilein3minut.es/1">one new podcast episode</a> every week, I’ve
been uncomfortable every week.</p>
<h2>One weird trick for writing faster and better</h2>
<p>I have a hard time writing when I’m not clear on who I’m writing
<em>for</em>. One trick I discovered in the early days of my online journal
was to pick someone to write <em>to</em>, and immediately the words would
come. Simply by emailing me a question and being his specific self,
my PSL classmate solved my problem this week.</p>
<p>Would you be willing to ask me a question, either here as a comment
or privately (by <a href="mailto:schmonz@schmonz.com">email</a>, <a href="https://twitter.com/schmonz">Twitter
DM</a>, etc.)? You’ll be doing me a favor!</p>
<h2>Another weird trick for writing at all</h2>
<p>Bring only my iPad (no phone, no laptop, yes <a href="http://www.ianker.com/product/98AP9804A-BTA">Bluetooth
keyboard</a>) to a public
place where people are having conversations and caffeinated beverages
are available (coffeeshop, bar, etc.). Turn off WiFi and cellular
networking. Insert earbuds. Open the <a href="https://coffitivity.com">Coffitivity</a>
app, just in case individual conversations are distinct and salient,
just loud enough to make it fruitless to attend to any of them.</p>
<p>In short, be <a href="https://schmonz.com/2015/08/05/confessions-of-a-twitter-completionist/">disconnected from
Twitter</a>, from the
folks in my immediate vicinity, and in general from the option to
do other things (or no things). Open
<a href="http://www.textasticapp.com">Textastic</a> or
<a href="http://agiletortoise.com/drafts/">Drafts</a> or even <a href="https://en.wikipedia.org/wiki/Notes%5F%28application%29">Notes</a>. Sip awake juice. Listen for the
faint signals in my brain, and write them down. Listen some more.
Write some more.</p>
<p>I need this hack because it’s easy for me not to focus on one thing
at a time, because I want my writing to be extremely clear, and
because writing while unfocused goes even more slowly than usual
and the outcome is crap. As a <a href="https://schmonz.com/2015/08/12/tdd-saved-my-brain/">perfectionist and
procrastinator</a>, I need to engineer
an environment in which it’s easier to focus than to not focus. You
might think a quiet hotel room would do the trick, and sometimes
it does, but it also affords me lots of options that aren’t writing.
I don’t want to have those options until I’m done with the hard
parts.</p>
<h2>A WIP-limiting, flow-enhancing trick from programming</h2>
<p>As I code, when I notice I’m about to gloss over something important,
I drop an <code>XXX</code> (and maybe a few more words of breadcrumb) as a
reminder to come back and think about it. I have the corresponding
habit of finding and fixing all new instances of <code>XXX</code> before
committing the change to source control. This trick lets me safely
<a href="https://schmonz.com/2015/08/19/life-hacks-for-the-test-infected/">complete my current
thinking-in-process</a>
before picking up a new line of thought.</p>
<p>As I write, I often think of references (previous posts, podcast
episodes, tweets) I’d like to link to. I drop an <code>XXX</code> and keep
writing. This interdisciplinary hack works especially well now that
<a href="https://schmonz.com/2015/01/01/happy-new-year/">my writing also gets committed to source
control</a>.</p>
<h2>A focusing trick from <a href="https://agilein3minut.es/">Agile in 3 Minutes</a></h2>
<p>When I can write an outline first, and maybe even choose a title,
the writing seems to go more smoothly. Sometimes that works. And
sometimes the only way to find out what I’m trying to write about
is to have written it.</p>
<h2>What’s my next source of discomfort?</h2>
<p>The process of writing still induces discomfort for me; no matter
how many consecutive weeks I keep doing it, I’m guessing that’ll
never completely go away. But it does seem to be getting better.</p>
<p>I try to finish my two weekly writings in my two or three evenings
a week when I’m away for work, so that I don’t have to spend any
of my precious minutes at home on that stuff. I often (not always)
succeed. The during-travel-evenings-only timebox has pushed me to
be more disciplined, but also to feel more pressure, but also also
to notice that the feeling of pressure neither helps me get my
writing done nor brings out my best thoughts. These last few weeks
I’ve been practicing feeling less pressure and more pleasure. So I
think that creating, following, and addressing my discomfort here
has begun to pay off.</p>
<p>That means I’m ready to add something new. I’ve got something in
mind that I’m uncomfortable just thinking about. I’m looking forward
to seeing how I’ll learn to address it, and to sharing my learning
with you.</p>
Agile in 3 Minutes: The Bookhttps://schmonz.com/2015/10/07/agile-in-3-minutes-the-book/Amitai Schlair2016-11-12T01:39:43Z2015-10-07T01:35:27Z
<h2>Why a micropodcast?</h2>
<p>I’ve <a href="https://schmonz.com/2015/07/15/introducing-agile-in-3-minutes/">told the origin story</a>
of <a href="https://agilein3minut.es/">Agile in 3 Minutes</a>, my <a href="https://agilein3minut.es/about">micropodcast
about doing business effectively</a>, and <a href="https://schmonz.com/2015/09/23/my-podcasting-workflow/">narrated how I create
the show</a> each week. Last week,
I <a href="https://schmonz.com/2015/09/30/habit-forming/">wrote about writing consistently</a>,
because I seem to have <a href="https://schmonz.com/2015/07/29/enthusiasm-engineering/">arranged for that
habit</a>.</p>
<p>In my last job, when I found myself frequently <a href="https://schmonz.com/2015/07/01/tdd-in-context-9-thwarted/">fighting for my
team’s continued right to its disciplined
practices</a>, I often hoped
that those sitting in judgment would be willing to take a few
minutes, read something potentially clarifying from some non-me
internet person, and have a conversation with me about it. Looking
back, I strongly suspect those managers and colleagues would have
been more willing to take a few minutes to <em>listen</em> to something.
With <em>Agile in 3 Minutes</em>, I’m hoping to engender the kinds of the
conversations I’d hoped for.</p>
<p>It’s gratifying to hear, then, that the show is being put to that
use. For instance, a manager in an Agile-seeking workplace is holding
biweekly group discussions of particular <em>Agile in 3 Minutes</em>
episodes to build shared understanding of where they’re headed and
why. I love it! And I love that I’m not the only one who hopes for
more of that:</p>
<blockquote><p>”I cannot recommend this podcast enough. Listen to every episode.
Talk about them in your team. Share them with your managers.
Managers, share them with your teams.”</p>
<p>— <a href="https://twitter.com/DayleyAgile">Alan Dayley</a></p></blockquote>
<h2>Why not only a podcast?</h2>
<p>While some folks prefer listening over reading, episodes are often
densely packed, and 180,000 milliseconds goes by quickly. Some
listeners have requested transcripts, and I’d probably want that
too (I <a href="https://schmonz.com/2015/08/05/confessions-of-a-twitter-completionist/">read a lot</a>).
Everyone absorbs and digests ideas in their own way; 3 minutes of
listening isn’t everyone’s best way.</p>
<p>And some folks want to financially back the show, but would rather
not <a href="https://www.patreon.com/schmonz">drip-fund it</a>.</p>
<h2>Solution: a podcast <em>and</em> a book</h2>
<p>Now available on Leanpub: <a href="https://leanpub.com/agilein3minutes">Agile in 3 Minutes, the
book</a>. Subtitle: “The simplest
essays that could possibly work.”</p>
<p>Want to peruse the material and ruminate at your own pace? <a href="https://leanpub.com/agilein3minutes">Buy the
book</a>!</p>
<p>Want to make a one-time donation? Choose your amount, then please
accept the book as your free gift. (If you didn’t want it, tough
luck. It’s yours.)</p>
<p>Either way, as new episodes come out, new essays will be added to
the book. As with any Leanpub publication, once you own it, <a href="https://leanpub.com/help/reader_faq">all
updates are free</a>.</p>
<h2>Thank you</h2>
<p>I appreciate your devotion of time and attention to my work on
<em>Agile in 3 Minutes</em>. Since it’s a labor of love, your love is
another way to <a href="https://agilein3minut.es/support">support it</a>. Now that the
show’s included in the popular podcast directories, you can help
others discover <em>Agile in 3 Minutes</em> by reviewing it in
<a href="https://geo.itunes.apple.com/us/podcast/agile-in-3-minutes/id1043107219?mt=2">iTunes</a>
or <a href="http://www.stitcher.com/s?fid=74689&refid=stpr">Stitcher</a>.
Please do!</p>
Habit forminghttps://schmonz.com/2015/09/30/habit-forming/Amitai Schlair2016-11-12T01:39:43Z2015-10-03T19:11:33Z
<h2>I’ve always written a lot</h2>
<p>I’ve been writing on my website, on and off, for nearly half my
life. When <a href="https://schmonz.com/1999/06/26/journal-1999-06-26/">I started</a>, as a teenager
freshly dropped out of college into my first job, I tried to write
so far-flung friends and family could read it and get the references,
and so that if the occasional internet stranger ran across it,
they’d get a rough idea. A key learning, early on, was that my best
posts included both (1) what happened and (2) how I felt about it.
But the benefit I sought was primarily my own: to clarify my thinking,
to remember my feelings, to document the significant-seeming rapids
of my turbulently flowing life for my friends and my future self.
While my writing was publicly available, if other readers were
finding it, I was unaware of them; and in any case, I was convinced
that people who didn’t already know me could not possibly find
anything of value in my words.</p>
<p>I kept writing, sometimes <a href="https://schmonz.com/2000/05/19/journal-2000-05-19/">every day for half an
hour</a>, sometimes not at all for long
stretches. There was a period from <a href="https://schmonz.com/2008/12/09/literature-humanities-paper-2/">late
2008</a> to <a href="https://schmonz.com/2013/01/20/my-unexpected-neighbor/">early
2013</a> when this site was offline
and I didn’t write. It was a relief to <a href="https://schmonz.com/2013/05/27/remembering-textpattern/">bring it back
up</a> (including all the drafts
I never published), and a further relief to <a href="https://schmonz.com/2015/04/29/signal-and-static/">get them out of a
database and into revision control</a>.
Feeling safer about my words not being lost has been (as I suspected
it might) a contributing factor to my writing more often this year.
Another contributing factor has been <a href="http://www.daedtech.com">Erik
Dietrich</a>. He’s been writing on his website
for a long time too, and a ever-growing audience values his voice.
So thrumpteen weeks ago, when Erik offered some simple guidance on
how to make my blog more valuable to me by making it more valuable
to readers, I listened.</p>
<h2>I’ve always read a lot</h2>
<p>Of his suggestions, one that sounded most actionable was to publish
new posts on a regular schedule. But I didn’t see why that was
important. When I run across a post I like well enough that I’m
interested to see what its author says next, I subscribe to the
site’s RSS feed. My feed reader is
<a href="https://github.com/wking/rss2email">rss2email</a>, so whenever I feel
like catching up on blogs, I simply switch to my email’s “Feeds”
folder and read whatever catches my eye. Given this reading workflow
(see also my <a href="https://schmonz.com/2015/08/19/life-hacks-for-the-test-infected/">coding</a>
and <a href="https://schmonz.com/2015/09/23/my-podcasting-workflow/">podcasting</a> workflows) and
my being a fast reader, it’s easy to be an opportunistic subscriber.
My <a href="https://schmonz.com/2013/06/10/area-under-the-curve/">investment in flow is
self-reinforcing</a>, because
the <a href="https://schmonz.com/2015/08/05/confessions-of-a-twitter-completionist/">wide-ranging ideas and information I
gather</a> from my
readings further increase the area under the remainder of the curve.</p>
<p>As I heard myself explaining all this to Erik, I realized just how
atypical a reader I am. Most people don’t chase the dragon of
consuming their entire Twitter feed or subscribing to every blog
they’ve ever liked. My reading habits are weird even to most of my
RSS-reading fellows, let alone reasonable people who have a more
casual relationship to everything they could possibly be reading
on the internet. The way I consume, I don’t care about anyone’s
publishing cadence, other than to miss them when they haven’t posted
for a while.</p>
<h2>My experience may not be universally representative</h2>
<p>But it doesn’t matter that <em>I</em> don’t care. Lots of readers do. Lots
of folks open their browsers and go to a handful of sites to see
what’s new. Readers who are not like me — which is to say, <em>nearly
all readers!</em> — add a site to their reading rotation if and only
if it pays off: if they can expect to keep getting something valuable,
and if their expectation keeps being met.</p>
<p>Now I understood Erik’s suggestion as not only actionable, but also
sensible. And I loved the idea of returning to a disciplined practice
(as I’d had when I started my online journal at 19) about writing.
I wasn’t confident that my well of topics wouldn’t quickly run dry,
because I’d never been conscientious about filling it. But I’m a
pretty opinionated dude, and <a href="https://schmonz.com/coach/">my line of work</a> regularly
stimulates thought, so I figured I could probably figure out how
to keep the topics coming. (Lesson learned from software development:
if I want to start solving the problem in front of me, I’d better
stop trying to solve problems I’m not having yet.)</p>
<h2>Try and see</h2>
<p>So I <a href="https://schmonz.com/2015/07/29/enthusiasm-engineering/">acquired myself the habit</a>
of writing and publishing one new post every week. This week was a
little tricky, so this post was started in a car, mostly finished
at a coffeeshop, and published from the guest room at a friend’s
house. That’s what it took to put together my 27th weekly post
in a row? So be it. In 2014 I <a href="https://schmonz.com/2015/02/09/a-square-triangular-number/">wrote a total of 15 and wished for
better</a>; in 2015 I’ve already
written 33 posts. I still carry around a low-grade, back-of-mind
fear that some future week I’ll have nothing to say, but it no
longer feels like an imminent threat.</p>
<p>I’ve always found writing to be rewarding, but painful. The process
is becoming less painful for me; I’m hopeful that the results are
becoming more rewarding for you. In any case, expect me to keep at
it.</p>
<h2>P.S.</h2>
<p>Plot twist: I’ve actually been writing <em>two</em> new things every week!
Give a listen to <a href="https://agilein3minut.es/">Agile in 3 Minutes</a>, my micropodcast
about thinking and doing business effectively.</p>
My podcasting workflowhttps://schmonz.com/2015/09/23/my-podcasting-workflow/Amitai Schlair2016-11-12T01:39:43Z2015-09-23T04:00:00Z
<p>When I’m programming, I can usually sense when I’m off track, and
have <a href="https://schmonz.com/2015/08/19/life-hacks-for-the-test-infected/">accumulated a bunch of
tricks</a> to <a href="https://schmonz.com/2015/09/16/my-coding-workflow/">direct
my flow</a>. When I’m podcasting, I
envision automating some of the manual steps to make the production
process smoother, but it doesn’t feel like flow yet. Every time I
make it all the way to the end of my checklist, I feel a sense of
relief. Here’s <a href="https://schmonz.com/2007/11/16/explosion-at-the-poem-factory/">how the sausage gets
made</a> each week.</p>
<h2>Choose the topic</h2>
<p>Before there was a show, to convince myself I had enough to talk
about, I made a backlog. Once <a href="https://schmonz.com/2015/07/15/introducing-agile-in-3-minutes/">there was a
show</a>, listeners started
contributing suggestions for topics and other improvements. (<a href="https://agilein3minut.es/support">You can too</a>.)</p>
<p>Sometimes I <a href="https://agilein3minut.es/backlog">look at the backlog</a>. For
instance, a couple nights ago (having shipped <a href="https://agilein3minut.es/22">22:
Control</a>), I knocked off the top item from the list of possible
site enhancements: “Add enough iTunes-specific metadata to get
listed in the iTunes podcast directory”. By the time “23: Whatever
It’ll Be About” comes out next week, the show will have begun to
expand its audience beyond a small set of motivated Agilists who
are also podcast-app devotees and RSS fanatics. Being in iTunes
will help more people discover Agile in 3 Minutes.</p>
<p>So far, I haven’t looked at the backlog for the purpose of choosing
my next topic. I’ve just been choosing whatever topic is already
appearing on my mind’s horizon after the previous week’s writing
session. I have been peeking to remind myself of the ideas folks
have expressed interest in, in case any of them ought to influence
the week’s writing.</p>
<p>I don’t believe learning is linear or orderly, but I do believe
there exist more and less digestible orderings in which <a href="https://flowchainsensei.wordpress.com/2015/09/25/my-definition-of-agile">the Agile
memeplex can be
unfolded</a>.
When I choose a topic, I’m intending to improve the chances of a
rewarding learning experience for folks who are following along in
sequence.</p>
<p>That’s why, thus far, I haven’t talked much about what to go do.
I’ve talked mainly about what needs to be true in our heads for
Agile to make sense to us, so that it can be of use to us, so that
it can help us be effective in our work.</p>
<h2>Write it</h2>
<p>While an episode may follow logically from the previous, and contain
brief echoes, it must also stand on its own. One reason: I hope
listeners find particular episodes worth sharing, and I hope
recipients who aren’t familiar with the show will find those episodes
worth their time. Another reason: I hope Agile in 3 Minutes will
grow to become a reference, such that for any given topic, listeners
can <a href="https://agilein3minut.es/about">expect to find a 3-minute treatment</a>. So
I consider each episode fully responsible for carrying its own
meaning because it might be heard in any order (including none) and
it might form someone’s first impression.</p>
<p>I begin writing, once the topic is decided, by quickly jotting down
all the ideas that come to mind. Word associations, other associations,
sentence fragments, previous writings of mine to revisit and try
to steal from. Then I follow some of those ideas a sentence or
three, maybe a paragraph, not worrying about whether I’ve said the
same thing badly or twice. Just keep saying until I run out of
steam, then riff-fill on the next thing and the next thing. This
loosey-goosey phase stops when I’ve written enough words to constitute
an episode. If only they were the right words!</p>
<p>Every episode starts with a question, but I don’t always know the
question before I start writing. Every episode has a title; I always
start with a working title, and usually don’t need to change it.
For the question, I tend to wait to see what I’ve written, because
it tells me the hidden question I’ve been asking myself. That’s
almost always the one I want to ask you.</p>
<p>How do I get to that point? Write and revise, write and revise, all
the while asking myself more questions. Which concepts are holding
together nicely? Which ones don’t quite follow in my mind? Which
need more help if they’re to follow in yours? How does the whole
thing follow from last week? What have I overexplained? Can I explain
something better by way of my own experience, possibly my experience
making the show? Is there an analogy to be made? Are there enough
examples? Might a bit of self-reference kick the whole thing up a
notch? Am I having fun writing this? Is there a grin on my face
because I’m already looking ahead to reading it?</p>
<p>With rare exceptions, I don’t try to prepare more than one episode
per week. It takes my best energy and self-awareness to dig deep
for my best ideas in my best words in my best order. If I want the
output to keep being any good, I need time to recover between
attempts. Exceptions: I wrote the first two so there’d be enough
show to announce, and I wrote 11-13 so I could go on vacation (which
I then needed!) without impact to the weekly cadence. In the other
direction, since the show began, I’ve missed only one week: Episode
5 was delayed by a bout of bronchitis, and you can hear the urgency
to get back on schedule in my still-recovering voice.</p>
<p>You can hear me talking a bit about this writing process at 42:24
of <a href="http://ryanripley.com/013-agile-for-humans/">Agile for Humans 013</a>.
In short, I mash my thoughts and feelings, stir, pour through a
fine sieve, and chill for several hours. I’ve just thought of a fun
way to make my work visible. Next time I’m ahead of schedule, I’ll
try it.</p>
<h2>Record it</h2>
<p><a href="https://schmonz.com/2015/09/23/yeti-and-quietcomfort.jpg"><img src="https://schmonz.com/2015/09/23/my-podcasting-workflow/300x400-yeti-and-quietcomfort.jpg" width="300" height="400" alt="Audio equipment in its natural traveling habitat" title="Audio equipment in its natural traveling habitat" class="img" /></a></p>
<p>I travel for work every week, so I bring my USB microphone, pop
filter, headphones, laptop, and iPad. I set them up in my hotel
room, turn off the climate control, unplug the fridge, and wait for
outside noise from the street and neighboring rooms to die down. I
read the script off the iPad, through the pop filter, into the
microphone, into QuickTime Player. If it’s a good read, I plug the
fridge back in.</p>
<h2>Postprocess it</h2>
<p>I open <a href="http://audacityteam.org">Audacity</a>, import the audio, chop
leading and trailing space, run the Compressor and Noise Removal
filters, and export to AIFF. Using a shell script wrapper around
<a href="http://lame.sourceforge.net">LAME</a>, I compress and tag the MP3,
then delete the intermediate audio files.</p>
<h2>Describe it</h2>
<p>Using a <a href="http://ikiwiki.info/ikiwiki/directive/template/">custom ikiwiki
template</a>, I write show notes in a mostly declarative format,
usually with at least one link to the <a href="http://c2.com/cgi/wiki?">C2 wiki</a> and
another to <a href="https://en.wikipedia.org/wiki/">Wikipedia</a>. I also define lots of
tags, even though the Agile in 3 Minutes website doesn’t make use
of them yet, because otherwise at some point when there are lots
of episodes and I want to provide a tag cloud for navigation I’ll
have to assign lots of tags on lots of episodes. I hate grunt work,
so I do a little of it every week. Also grunt work: manually create
an HTML container so Twitter can <a href="https://schmonz.com/2015/08/26/audio-in-a-tweetshell/">show an inline audio
control</a> when anyone posts a link.</p>
<h2>Publish it</h2>
<p><code>git add</code> the MP3, the show notes, and the HTML container. <code>git
commit</code>. <code>git push</code>. Ikiwiki puts the episode on the front page and
adds it to the archive and the RSS feed. Easy!</p>
<h2>Share it</h2>
<p>I post the episode to Twitter and other social media. I post it to
Twitter several more times over the course of the day, 2-3 hours
apart, with a variety of quotes pulled from the episode script.</p>
<h2>Improve it</h2>
<p>More automation would help me sustain my pace. If all I had to do
each week besides write the script, record the read, and jot some
show notes were to push a button to do everything else, that would
be really fun — I’m a programmer, I think grunt work being done
by code I wrote is fun! — and would let me focus even more on the
writing that makes the show what it is. So anytime there’s a little
slack in the production schedule, I’ll be looking to automate one
more step.</p>
<p>Do you know a cool writing or audio-production trick? Got ideas for
the show? Let me know in the comments.</p>
My coding workflowhttps://schmonz.com/2015/09/16/my-coding-workflow/Amitai Schlair2016-11-12T01:39:43Z2015-09-16T04:00:00Z
<p>Julio Merino recently <a href="https://medium.com/@jmmv/my-coding-workflow-f26f81235752">described his coding
workflow</a>
and <a href="https://twitter.com/jmmv/status/641138163163922432">invited others to describe
theirs</a>. My
previous workplace development environment <a href="https://schmonz.com/2013/10/17/working-from-everywhere/">looked a whole
lot</a> like Julio’s, but my
current one necessarily looks pretty different. Having needed to
revisit some of the reasons for my preferences, I can more readily
distinguish my current nice-to-haves from my can’t-do-withouts.</p>
<h2>Development environments</h2>
<table>
<tr>
<th>When?</th>
<td>Then</td>
<td>Now</td>
</tr>
<tr>
<th>Team</th>
<td>Remote</td>
<td>Local</td>
</tr>
<tr>
<th>Role</th>
<td>Developer, etc.</td>
<td><a href="https://schmonz.com/2015/09/09/how-to-get-decent-at-coaching/">Coach</a></td>
</tr>
<tr>
<th>OS</th>
<td>Unix</td>
<td>Windows</td>
</tr>
<tr>
<th>Build Radiator</th>
<td>Standalone VM with a custom <code>cron</code> job</td>
<td>IBM uBuild</td>
</tr>
<tr>
<th>Backlog</th>
<td>Markdown files in Git</td>
<td>Rally</td>
</tr>
<tr>
<th>Source Control</th>
<td>Git</td>
<td>AccuRev</td>
</tr>
<tr>
<th>Architecture</th>
<td>CLI/GUI client/server</td>
<td>web services</td>
</tr>
<tr>
<th>Language</th>
<td>Perl</td>
<td>Java</td>
</tr>
<tr>
<th>Editor</th>
<td><code>vim</code></td>
<td>IBM Rational Software Architect (Eclipse-derived)</td>
</tr>
<tr>
<th>Pairing</th>
<td><code>tmux</code></td>
<td>same desk</td>
</tr>
</table>
<p>I had been an <code>nvi</code> fuddy-duddy until my teammates finally prevailed on
me with their fancy colors and configs. Thanks, guys.</p>
<h2>Mere strong preferences</h2>
<p>I grew up as a computer user on classic Mac OS and
<a href="http://www.netbsd.org">NetBSD</a>. When <a href="https://en.wikipedia.org/wiki/Mac%5FOS%5FX%5FServer%5F1%2E0">Mac OS X Server 1.0</a>
came out, all clunky and expensive, I bought it just to have it;
when the <a href="https://en.wikipedia.org/wiki/Mac%5FOS%5FX%5FPublic%5FBeta">Mac OS X Public Beta</a> came out, I knew my
worlds would usefully merge, and I could look forward to not having
two computers on my desk. As a developer, when I don’t have these
at hand, I sometimes fumble to compensate:</p>
<ul>
<li>Unix</li>
<li><code>vi</code></li>
<li>Git</li>
<li><a href="http://www.pkgsrc.org">pkgsrc</a></li>
</ul>
<p>pkgsrc (”package source”) gives me an easy way to install most any
other tools I might need on any Unix variant with any level of
system access. I <a href="https://schmonz.com/2013/01/22/codemash-2013-your-dev-toolbox-everywhere/">gave a lightning talk about
it</a> at CodeMash
2013.</p>
<p>On my own time, I choose a Unix-centered environment whenever
possible, to which the two open-source projects I spend the most
time with (pkgsrc and <a href="http://ikiwiki.info">ikiwiki</a>) happen to
lend themselves very well. I’m sure there’s cause and effect in
both directions.</p>
<p>When I’m stuck on Windows, where I don’t feel as comfortable or
productive, I usually wind up <a href="https://schmonz.com/2006/06/13/pkgsrc-on-windows/">arranging for a Unix
environment</a>, and using it from time
to time to keep myself from getting sidetracked too often figuring
out how to do some small thing.</p>
<p>When I’m stuck with a weird revision control system, I often <a href="https://schmonz.com/2013/03/10/permanent-cvs-temporary-git/">use
Git in parallel</a>. The
administrative overhead of syncing with the source control system
of record is more than paid for by the speed and clarity of diffs,
which I check quite often as I go along.</p>
<h2>Must-haves</h2>
<p>When I’m programming, I’m more attuned than usual to bottlenecks
in the flow of my work, because I’m more accustomed than usual to
having the agency and the means to ease them. I’ve learned that
while not having Unix tools is often a bottleneck, it’s not always
so, and I can wait until I’m having that problem to do something
about it.</p>
<p>In software development, there’s a problem I <em>always</em> have: I <a href="https://schmonz.com/2014/04/01/my-superpower/">make
lots of decisions</a>, some of them are bad,
and I need to know about those ASAP. So I don’t wait until
of-course-I’m-having-that-problem-again to do something about it.
Unless the code’s getting thrown away in a few minutes, I <em>always</em>
start by arranging for a fast red/green feedback loop.</p>
<p>It doesn’t have to display actual red and green, or <a href="https://schmonz.com/2014/01/26/how-to-efficiently-learn-a-programming-language/">use an
established testing
framework</a>,
or <a href="https://www.destroyallsoftware.com/blog/2014/tdd-straw-men-and-rhetoric">finish before I can
blink</a>.
It does have to start with a keystroke, finish with a clear indicator,
and <a href="https://schmonz.com/2015/08/19/life-hacks-for-the-test-infected/">return me to my
context</a>. These
affordances ensure that I’ll reliably make at least one decision
well: whether to run the tests. Because I’m sure I will, it’s worth
the marginal effort to add more tests as I go. And because I’m sure
those tests are the fastest way to catch my mistakes, it’s worth
the marginal effort to start with tests and use them to drive my
design decisions.</p>
<h2>It’s not about tools</h2>
<p>I don’t worry about optimizing test speed until I’m adding tests
often and running them often and the run is starting to feel slower.
I don’t want to solve it before it’s a problem (it might never be),
or after it’s a hard problem (I don’t care for those).</p>
<p>It’s about <em>flow</em>, both kinds — my state of mind and my delivery
of outcomes — because they’re tightly linked. If I let problems
grow large, they’ll impede my flow later, so I avoid knowingly
creating future hard-to-ease bottlenecks. If I let myself be bothered
by problems that aren’t yet impeding me, they’ll impede my flow
now, so I avoid any further worrying about future bottlenecks.</p>
<p>My coding workflow is continually being optimized for speed and
predictability. I look for the present bottleneck, work to ease
it, and repeat. Every time I <a href="https://twitter.com/schmonz/status/605826934564462593">pay for
smooth</a>, my
investments yield strong returns.</p>
How to get decent at coachinghttps://schmonz.com/2015/09/09/how-to-get-decent-at-coaching/Amitai Schlair2016-11-12T01:39:43Z2016-02-12T06:24:48Z
<p>I’m finally coaching! Considering I was <a href="https://schmonz.com/2015/09/02/how-to-get-hired-as-a-coach/">hired as a consulting
coach</a> in January, started
with a client in February, and landed with a team in March, that’s
an odd thing to say, isn’t it?</p>
<h2>What do I mean by “coaching”?</h2>
<p>”Coach” (the role) includes teaching, training, mentoring, and any
other kind of situationally called-for behavior, but aims to center
on coaching. “Coaching” (the activity) means helping people and
teams become more themselves. I recently discussed this topic with
<a href="https://www.linkedin.com/in/zachbonaker">Zach Bonaker</a> and <a href="http://www.ryanripley.com">Ryan
Ripley</a> on <a href="http://ryanripley.com/013-agile-for-humans/">Agile for Humans
013</a>, and I’ve got a
blurb about <a href="https://schmonz.com/coach/">how I and others see what I do</a>.</p>
<p>Others use the word differently. For instance, some say “coach” to
mean “consultant who will tell us what to do.” I don’t want to do
that, and I don’t think it has much to do with coaching. To take
another example, I often hear a distinction made between “process
coach” and “technical coach,” with which I have at least three
beeves:</p>
<ol>
<li>I’m not coaching processes or techniques. I’m coaching people.</li>
<li>As a coach, I’m more effective when I consider the whole system.</li>
<li>In Agile software development, process and technique are
intertwined.</li>
</ol>
<h2>Why did it take so long?</h2>
<p>I was brought in as a hands-on technical coach, as a deliberately
influential member of the team. I liked the sound of that, especially
after so much time off. Let’s get paid! Let’s go to offices and
work with people! Let’s see if I can earn <a href="https://agilein3minut.es/3">trust</a>,
influence and <a href="https://agilein3minut.es/15">be influenced</a>, help a few people
who wish for better to get it.</p>
<p>It was a slow start, for a variety of reasons: two weeks to get
new-hire oriented at my consultancy, more than that to arrive at
clarity about which client team to place me with, much more than
that to get me a development-capable machine with a development-ready
environment. During those months, when the only way to learn the
domain and the codebase was to bother someone who was trying to
get their work done, I tried pairing a couple times and <a href="https://agilein3minut.es/2">decided to stop</a>. (I <a href="https://agilein3minut.es/about">hate wasting
anyone’s time</a>.) Until I could acquire the local knowledge on my
own, I looked for other ways to start helping the team, such as:</p>
<ul>
<li>Hands-on classroom sessions for an hour every afternoon, alternating
between exercises to build new code skills (TDD, refactoring)
and legacy code skills (characterization tests, refactoring).
After a while, not seeing how to apply what they’d learned to
their production codebase, the team lost interest and we stopped
the sessions.</li>
<li>Whole-team programming for a full two-week iteration. It wasn’t
textbook <a href="https://en.wikipedia.org/wiki/mob%5Fprogramming">mob programming</a>, or even close, but it
was a start at learning to work together more effectively. They
were nearly as productive as they’d been the previous iteration,
plus key knowledge spread to many more brains, plus everyone on
the team was animated and engaged in the problem-solving. But
under perceived pressure to maximize velocity, the team decided
they couldn’t afford to continue working in this way.</li>
</ul>
<p>One obstacle was the sheer size of the team (at its largest, about
a dozen). With a team that size, it’s hard enough to <em>have</em> a
direction, let alone try to change it. Another obstacle was the
frequency with which members joined or departed, <a href="https://twitter.com/richardadalton/status/569275411508682752">constituting a
new team</a>.</p>
<h2>How can I tell I’m coaching?</h2>
<p>I’ve lost trust by trying to help in ways that haven’t helped,
earned some back by finding ways that have been desired. I’ve found
ways to offer potential <a href="https://agilein3minut.es/17">value</a> to the team
without asking more than they’re willing to offer. I’ve listened,
<a href="https://agilein3minut.es/18">asked questions</a>, and offered suggestions in
conversations with and without keyboards, in groups and one-on-one.
I’ve identified feedback loops in need of repair — several of
which involve me — and have been repairing them.</p>
<p>In short, I’ve tried a bunch of things that didn’t work, and found
a few that are (for the moment) working. I’ve danced insensitively,
and learned some signals to be more attentive to. I’ve improvised
ineffectively, and learned some new moves to try.</p>
<p>I know I’m coaching because, as the team’s needs have not yet been
primarily technical, I haven’t been doing much “technical coaching.”</p>
<p>I know I’m coaching because I’m sometimes aware when I’m failing,
when I’m succeeding, and when I’ve learned something.</p>
<p>I know I’m coaching because I’m sometimes aware when people want
what I’m offering, and when they want me to be offering more.</p>
<p>I know I’m coaching because I’m not even sure “coach” is a thing
anymore. Maybe nothing exists but people, the actions we take, the
behavior patterns we choose, the capabilities we grow, and the
environments we design. Some of what I do each day could be called
coaching, some programming, some teaching, some delivering. My job
is to catalyze mutually desired improvement, and I’m finally,
perhaps, beginning to.</p>
<h2>How do I feel?</h2>
<p>This work is exactly what I wanted. I’m finally wrestling with all
the challenges I hoped and wished this job would consist of. What’s
more, I’m being supported in ways I’d <a href="https://schmonz.com/2015/07/01/tdd-in-context-9-thwarted/">learned not to hope or wish
for</a>. As a new coach, I’ve
leaned heavily on Pillar folks and other coaches at the client,
all of whom have lent their expertise and experience to help me
when I’ve asked. I’ve been very lucky to have such easy
<a href="http://ironmoose.blogspot.com">access</a> <a href="http://xp123.com">to</a>
<a href="http://www.daedtech.com">terrific</a>
<a href="http://agileshrugged.com">consultants</a>, to know I’ve got the
backing of program management, and to <a href="https://schmonz.com/2015/03/05/riches-of-embarrassment/">bring my whole
self</a> — because the work needs
<em>me</em>.</p>
<p>I would have <a href="https://twitter.com/schmonz/status/631641409087479809">regretted not doing
this</a>. I
also would have regretted doing it badly. But I seem to be getting
the hang of it.</p>
<p>It’s everything I wanted, and then some.</p>
How to get hired as a coachhttps://schmonz.com/2015/09/02/how-to-get-hired-as-a-coach/Amitai Schlair2016-11-12T01:39:43Z2015-09-05T00:14:01Z
<p>I’m pretty sure my claims in <a href="https://schmonz.com/2014/03/27/how-to-develop-software/">How to develop
software</a>, <a href="https://schmonz.com/2015/04/08/how-to-develop-humans/">How to develop
humans</a>, and <a href="https://schmonz.com/2014/01/26/how-to-efficiently-learn-a-programming-language/">How to efficiently
learn a programming
language</a>
hold true for people who aren’t me. This how-to is <a href="https://schmonz.com/2007/05/14/schmonzs-theorem/">similar, yet
different</a>, in that I don’t know enough
to suggest anything you should believe or could try. All I know is
what I believed, what I tried, and whether it worked. If something
about my story helps you, I’d love to hear about it.</p>
<h2>Why did I want to try coaching?</h2>
<p>I’m not the most gifted programmer or project manager, and I <a href="https://schmonz.com/2007/11/11/advanced-composition/">have
an academic background in neither</a>.
Of necessity, I’ve <a href="https://schmonz.com/2015/08/19/life-hacks-for-the-test-infected/">picked up some
tricks</a> that help me
<a href="https://schmonz.com/2015/05/20/tdd-in-context-6-a-big-project/">deliver results</a>. I’ve
built up skill at <a href="https://agilein3minut.es/17">choosing the work that’s most
needed</a>, how to <a href="https://agilein3minut.es/19">make it most predictable</a>,
and how to <a href="https://agilein3minut.es/8">care for people</a>.</p>
<p>As a <a href="https://schmonz.com/2015/08/12/tdd-saved-my-brain/">perfectionist</a>,
<a href="https://schmonz.com/2006/04/08/mluvit-vymluvit-omluvit/">procrastinator</a>, and
<a href="https://schmonz.com/2013/09/16/words-with-friends-and-everyone-else/">introvert</a>, my
at-work effectiveness does not come naturally to me. It has been,
and continues to be, acquired through intellection; it is performed,
when I manage to perform it, through intellection. The downside is
that whenever I don’t have quite enough attention and energy, my
effectiveness <a href="https://agilein3minut.es/14">drops off pretty steeply</a>. The
upsides are that my best work is consistently trustworthy and
valuable, I habitually observe and adopt techniques to make it more
so, and I can almost always understand, verbalize, and demonstrate
why I choose how I choose and why I do how I do.</p>
<p>I’m not singularly talented, but I compensate by being wily and by
raising my team’s level of play. I’m no Michael Jordan, but maybe
I could hope to become a <a href="https://en.wikipedia.org/wiki/Phil%5FJackson">Phil Jackson</a>.</p>
<p>This isn’t the first time I’ve thought these thoughts in this order.
I began to piece them together a couple years ago while leading a
software team in a difficult environment, during which I <a href="https://schmonz.com/2015/07/08/tdd-in-context-10-testing-acceptance/">felt
both pride and pain</a>
while delivering exemplary work.</p>
<h2>How did I give myself a chance?</h2>
<p>A senior manager observed my frustration, suggested I’d do well at
coaching software teams that needed to improve (of which there were
many), arranged a test of our hypothesis (which went quite well),
and set a move in motion. The new role represented for me not only
an escape from chronic work-pain, but also a route to being
appreciated, for my value could only become more significant and
more evident. I had a lot riding on the move. So when a meddling
middle manager blocked my transfer out of the department, he soon
discovered that his authority <a href="https://schmonz.com/2014/04/01/my-superpower/">stopped short of keeping me
there</a>.</p>
<p>Our plan, had it come to fruition, would have served my needs
wonderfully. The team I would have joined was already 100% dispersed,
and the teams I would have coached were all far from New York.
Anticipating no further need for me to live far from Bekki and pay
dearly for the privilege, I <a href="https://schmonz.com/2014/02/10/my-thirty-fifth-solar-orbit/">moved to
Indiana</a>. I would have had
the chance to learn, under favorable and safe conditions — salary
and benefits, an environment I knew well, plentiful obvious
improvements to be made — the basics of how to be a coach.</p>
<p>But now it was time for Plan B. Having lowered my burn rate
considerably, and having done enough coaching to validate pursuing
more coaching, I could afford to wait up to 10 months for the
established Agile consultancies to decide I’d help them serve their
clients. (If I couldn’t make that happen in time, Plan C was to
get another remote programming job, for which I began collecting
links to promising remote-friendly employers.) To raise my profile,
I sought to involve myself in conferences, conversations, blog
posts, <a href="https://schmonz.com/2015/08/05/confessions-of-a-twitter-completionist/">Twitter</a>,
LinkedIn, you name it.</p>
<p>A few months into my experiment, with several consultancies
interviewing me, I warned each of them to see hiring me as a risk
— because while I’d done a little coaching, and a lot of being a
coach-ish teammate, I’d never been hired to be a coach — but that
it’s a smart bet that’ll pay off for them. All of them thanked me
for being honest; some of them continued to interview me in depth;
and all of them ultimately decided they’d like to talk to me again
after someone else had taken that risk.</p>
<h2>When did I get that chance?</h2>
<p>All of them, that is, except one. A couple months from bottoming
out my savings, having just taken a practice interview for Plan C,
I heard from Pillar. Like the others, they thanked me for being
honest. Unlike the others, they didn’t need someone else to go
first. Was I still available? How soon could I start?</p>
<h2>How did I feel?</h2>
<p>Jackpot! I get a chance to find out whether I can do this.</p>
<p>Crackpot! I have no idea whether I can do this. I haven’t done
paying work of any kind in over nine months. I haven’t worked with
the client’s primary programming language since <em>2003</em>.</p>
<p>If I let the self-doubt stop me from accepting the job, worst-case
scenario is I’m filled with regret and Plan C takes too long to
work. Very not great.</p>
<p>If I accept but the self-doubt proves correct, worst-case scenario
is I flame out in a few months and buy Plan C a little time. Somewhat
not great.</p>
<p>If I accept and I figure out how to do a good job, jackpot.</p>
<h2>How’s it working out for me?</h2>
<p>I accepted, of course! Come back next week for the rest of the
story.</p>
Audio in a tweetshellhttps://schmonz.com/2015/08/26/audio-in-a-tweetshell/Amitai Schlair2018-04-02T04:34:26Z2015-08-27T05:30:14Z
<h2>Get some stats</h2>
<p>I’m doing <a href="https://schmonz.com/2015/07/15/introducing-agile-in-3-minutes/">a weekly
micropodcast</a>. It’s
<a href="https://medium.com/@pete/downloads-listens-listeners-and-about-those-podcast-numbers-73a5ee3e2fca">difficult to count
listeners</a>,
but by a conservative accounting, as of this writing, there have
been 2593 total downloads of 18 total episodes, for an average of
144 per episode. How do I know? My web server logs and this shell
script:</p>
<div class="highlight-sh"><pre class="hl"><span class="hl slc">#!/bin/sh</span>
count_downloads_for_episodes<span class="hl opt">() {</span>
<span class="hl kwb">local</span> _start_episode _end_episode _num_episodes _total_downloads _episode _downloads
_start_episode<span class="hl opt">=</span><span class="hl sng">"</span><span class="hl ipl">$1</span><span class="hl sng">"</span>
_end_episode<span class="hl opt">=</span><span class="hl sng">"</span><span class="hl ipl">$2</span><span class="hl sng">"</span>
_num_episodes<span class="hl opt">=</span><span class="hl kwd">$(expr ${_end_episode} - ${_start_episode} + 1)</span>
_total_downloads<span class="hl opt">=</span><span class="hl num">0</span>
<span class="hl kwa">for</span> _episode <span class="hl kwa">in</span> <span class="hl kwd">$(jot ${_num_episodes} ${_start_episode})</span><span class="hl opt">;</span> <span class="hl kwa">do</span>
_downloads<span class="hl opt">=</span><span class="hl kwd">$(count_downloads_for_episode ${_episode})</span>
_total_downloads<span class="hl opt">=</span><span class="hl kwd">$(expr ${_total_downloads} + ${_downloads})</span>
<span class="hl kwb">echo</span> <span class="hl sng">"</span><span class="hl ipl">${_episode}</span><span class="hl sng">:</span> <span class="hl ipl">${_downloads}</span><span class="hl sng">"</span>
<span class="hl kwa">done</span>
<span class="hl kwb">echo</span> <span class="hl sng">"total:</span> <span class="hl ipl">${_total_downloads}</span><span class="hl sng">"</span>
<span class="hl kwb">echo</span> <span class="hl sng">"average:"</span> <span class="hl kwd">$(expr ${_total_downloads} / ${_num_episodes})</span>
<span class="hl opt">}</span>
count_downloads_for_episode<span class="hl opt">() {</span>
<span class="hl kwb">local</span> _http_status_of_interest _logfiles _episode _downloads
_episode<span class="hl opt">=</span><span class="hl sng">"</span><span class="hl ipl">$1</span><span class="hl sng">"</span>
_http_status_of_interest<span class="hl opt">=</span><span class="hl num">200</span>
_logfiles<span class="hl opt">=</span><span class="hl sng">'logs/access logs/access-ssl'</span>
_downloads<span class="hl opt">=</span><span class="hl kwd">$(grep "GET /.*ai3m${_episode}\.mp3" ${_logfiles} | grep " ${_http_status_of_interest} " | wc -l)</span>
<span class="hl kwb">echo</span> <span class="hl kwd">${_downloads}</span>
<span class="hl opt">}</span>
main<span class="hl opt">() {</span>
<span class="hl kwb">local</span> _start_episode _end_episode
<span class="hl kwa">if</span> <span class="hl opt">[</span> <span class="hl kwd">$#</span> <span class="hl opt">=</span> <span class="hl num">2</span> <span class="hl opt">];</span> <span class="hl kwa">then</span>
_start_episode<span class="hl opt">=</span><span class="hl sng">"</span><span class="hl ipl">$1</span><span class="hl sng">"</span>
_end_episode<span class="hl opt">=</span><span class="hl sng">"</span><span class="hl ipl">$2</span><span class="hl sng">"</span>
<span class="hl kwa">elif</span> <span class="hl opt">[</span> <span class="hl kwd">$#</span> <span class="hl opt">=</span> <span class="hl num">1</span> <span class="hl opt">];</span> <span class="hl kwa">then</span>
_start_episode<span class="hl opt">=</span><span class="hl sng">"</span><span class="hl ipl">$1</span><span class="hl sng">"</span>
_end_episode<span class="hl opt">=</span><span class="hl sng">"</span><span class="hl ipl">$1</span><span class="hl sng">"</span>
<span class="hl kwa">else</span>
_start_episode<span class="hl opt">=</span><span class="hl num">1</span>
_end_episode<span class="hl opt">=</span><span class="hl kwd">$(ls src/*.mp3 | sed -e 's|src/ai3m||' -e 's|\.mp3||' | sort -n | tail -1)</span>
<span class="hl kwa">fi</span>
count_downloads_for_episodes <span class="hl kwd">${_start_episode} ${_end_episode}</span>
<span class="hl opt">}</span>
main <span class="hl sng">"$@"</span>
</pre></div>
<p>There are thousands more HTTP status 206es in the logs, which are
excluded on the assumption that they represent partial downloads
and shouldn’t count toward the total. If you can suggest how I might
more accurately and/or standardly count podcast downloads without
relying on external services, I’m interested.</p>
<h2>Attract more listeners</h2>
<p>One way I’ve been trying to expand my audience is by announcing
each week’s episode via social media. As a <a href="https://schmonz.com/2015/08/05/confessions-of-a-twitter-completionist/">heavy Twitter
user</a>, I’ve noticed
that certain kinds of media — such as YouTube videos and animated
GIFs — can be played directly within tweets, without needing to
leave an app or click a link. I wanted Twitter to be presenting my
podcast in this way, on the hypothesis that the easier it is to
listen, the more folks will try listening.</p>
<p>Twitter calls this multimedia feature the <a href="https://dev.twitter.com/cards/types/player">Player
Card</a>, one of several
types of “Cards”, and gives developers a way to implement it for
their sites. As I was changing my episode template, I noticed a bug
in <a href="https://schmonz.com/2015/01/01/happy-new-year/">the CMS</a>’s expansion of some of the
directives. For instance, when I gave ikiwiki this input:</p>
<pre><code>[[!meta name="twitter:card" content="player"]]
</code></pre>
<p>I expected it to generate this output, which is what Twitter would
want:</p>
<div class="highlight-html"><pre class="hl"><span class="hl kwa"><meta</span> <span class="hl kwb">name</span>=<span class="hl sng">"twitter:card"</span> <span class="hl kwb">content</span>=<span class="hl sng">"player"</span> <span class="hl kwa">/></span>
</pre></div>
<p>But it did this instead:</p>
<div class="highlight-html"><pre class="hl"><span class="hl kwa"><meta</span> <span class="hl kwb">name</span>=<span class="hl sng">"twitter:cardcontent="</span>player<span class="hl sng">" /></span>
</pre></div>
<h2>Fix a bug</h2>
<p>Ikiwiki has lots of tests, but I didn’t see any for the plugin that
processes these directives. So I reviewed the docs and the code and
<a href="https://github.com/schmonz/ikiwiki/commit/d42ed9bdc3e4c4875e6fcf2f5e5ffe71652a51ee">wrote some
tests</a>
(warning: Perl (warning: hey, I <em>like</em> Perl!)) for a bunch of the
other variants of the <a href="http://ikiwiki.info/ikiwiki/directive/meta/">meta</a>
directive — partly in case there were more bugs lurking, partly
to make the neighborhood safer for future contributors, and mainly
to avoid creating new bugs when I <a href="https://github.com/schmonz/ikiwiki/commit/09916a90ed9f22212ac62078132fd2375ed0017f">fixed
mine</a>.
Between the time I’d invested in reading and exercising other code
in the same plugin, the bug being pretty obvious to begin with, and
tests that told me whether I was done yet, it was a quick fix.</p>
<h2>Great success <img src="https://schmonz.com/smileys/question.png" alt="(?)" /></h2>
<p>Now that my Player Card validates, when I (or anyone) tweets a new
episode of <a href="https://agilein3minut.es/">Agile in 3 Minutes</a>, some browsers and
Twitter clients display a nice little widget for playing the audio.
In Safari on OS X:</p>
<p><img src="https://schmonz.com/2015/08/26/twitter-player-card.png" alt="twitter-player-card.png" /></p>
<p><a href="https://twitter.com/schmonz/status/636377496523411456">Give it a try</a>.
How’s it work? How’s it look? Bug reports gratefully accepted.</p>
Life hacks for the test-infectedhttps://schmonz.com/2015/08/19/life-hacks-for-the-test-infected/Amitai Schlair2016-11-12T01:39:43Z2015-11-03T00:55:55Z
<p>When I started <a href="https://schmonz.com/2015/08/12/tdd-saved-my-brain/">recovering from
perfectionism</a>, I noticed I’d been
trying to carry around an “effectively infinite” set of thoughts
to make sure to think. Trying and failing, that is, and wasting
cognitive energy in the attempt. When TDD began to poke through my
thick skull, I observed the existence of at least one context in
which I didn’t have to carry that inventory. Run the tests, know
where I am; write a red test, know where I am; make it green, know
where I am.</p>
<p>Being able to instantly know where I was obviated my need to think
all the thoughts, at least during the act of writing code. I had
become <a href="http://c2.com/cgi/wiki?TestInfected">test-infected</a>. It was a first
step toward a better life.</p>
<p><a href="http://c2.com/cgi/wiki?TestDrivenDevelopment">Test-Driven Development</a>, as
opposed to test-first, means we <a href="https://twitter.com/GeePawHill/status/634817420981501952">drop the premise that we can be
pretty sure where we’re going to end
up</a>, and
replace it with the premise that we can be pretty sure we’ll figure
out how to get there. We keep the part where we write tests before
doing things. We drop the part where we write a whole bunch of tests
before doing a whole bunch of things. Instead, we write one test,
do one thing, and listen for hints about what needs to happen next.</p>
<p>Doing one thing at a time requires, as you might imagine, the ability
to delay some gratification. I happen to think a frequent green bar
more than makes up for it. Even so, patience can be hard to come
by when my brain, without my invitation, has begun loading up the
problem and throwing off sparks about what all might be important
later. And when it occurs to me that some of those ideas might well
be right, <em>and</em> I might not think of them again, it’s hard to let
them go. Hence our first hack.</p>
<h2>The Test List Trick</h2>
<p>The goal of this hack is to:</p>
<ol>
<li>Quickly record those ideas somewhere I know they won’t get lost,
and thereby</li>
<li>Restore my brain to a patience-capable state.</li>
</ol>
<p>Here’s the spec:</p>
<pre><code>Feature: Test-drive efficiently while being a talented worrier
Scenario: Initialize focused brain
Given I'm working on code with tests
And I'm trying to test-drive
When my head is full of all the things to make sure to worry about
Then empty it into a block comment in the tests
Scenario: Maintain focused brain
Given I'm test-driving
When my head invents a new thing to worry about later
Then append it to the block comment in the tests
Scenario: Convert good ideas to tests
Given I'm test-driving
When the right thing to do next is one of my commented ideas
Then convert the idea to a test
Scenario: Discard leftovers
Given I'm test-driving
When we're green and there's nothing left to do
And the block comment still has ideas in it
Then delete the block comment before committing
</code></pre>
<h2>The Red-Test Breadcrumb Trick</h2>
<p>In case the rationale for the previous hack didn’t make it clear,
I’m forgetful. (I had to go back and check that I wrote something
that implies forgetfulness.) I’m also a recovering procrastinator,
in addition to the perfectionist bit. Really just a lovely person
with fine character traits. I confess these things because while
context switches are known to be expensive for everyone, I’d be
willing to bet they’re extra expensive for me. So I evolved another
hack, which is only barely anything to do with TDD, but only works
if — and might not even make sense until — test-driving is part
of you.</p>
<p>The goal of this hack is to:</p>
<ol>
<li>Quickly, before I forget, record my next action somewhere I know
I’ll find it, and thereby</li>
<li>Restore my brain to its previous context when I return.</li>
</ol>
<p>The spec:</p>
<pre><code>Feature: Come back efficiently from a context switch
Scenario: Save mental state
Given I'm trying to test-drive
And I can write simple tests very quickly
When I need to step away for any reason
Then first write a test that says fail("yo, do X next")
Scenario: Restore mental state
Given I'm trying to test-drive
And I test-drive as a matter of course
When I'm trying to remember what the hell was going on here
Then run the tests and be reminded
Scenario: Get rolling again
Given I'm trying to test-drive
When I have a failing test
Then I'm on solid ground
And I know exactly what to do next
</code></pre>
<h2>Got hacks?</h2>
<p>I rely on a whole bunch of tricks to be effective. I’m quite sure
I’ve got more than two, and I’m quite sure I’m not the first to
introduce these two to the world, but as I said, I’m forgetful.
(Hey, this time I didn’t have to check!) When I remember some more
of my survival tactics, I’ll write another post.</p>
<p>What do you do to <a href="https://schmonz.com/2015/07/29/enthusiasm-engineering/">arrange yourself</a>
to get the right things done right?</p>
TDD saved my brainhttps://schmonz.com/2015/08/12/tdd-saved-my-brain/Amitai Schlair2016-11-12T01:39:43Z2015-08-15T02:24:47Z
<h2>I have a problem</h2>
<p>I’m a perfectionist. For any given task, in the absence of evidence
to the contrary — and sometimes despite the presence of said
evidence — I’ll often feel the need to perform it no less than
very well, and preferably superlatively.</p>
<p>I say “often” and not “always” because I’m a <em>recovering</em> perfectionist.
Before my recovery began, when I could stand to feel how I felt,
I’d be disappointed with my behavior, the way my life seemed to be
going, and my seeming lack of agency about any of it. I’d wonder
how much of my disappointment stemmed from the selfsame perfectionist
judgment I was disappointed with. I’d wonder whether I’d ever have
the option to think without always going in circles. I’d wonder
whether I’d ever stop criticizing myself for how I criticized myself.
I’d wonder about circles again, and try to stop.</p>
<h2>I had an insight</h2>
<p>With my brain throwing off so much waste heat, concentrating was
difficult. I dropped out of college and got my first job, where I
discovered the brilliantly clarifying experience of being very
slightly useful to others. It became my organizing principle, my
yardstick. Am I being at all useful? How can I be making myself
more useful?</p>
<p>I’m also a <a href="https://schmonz.com/2006/04/08/mluvit-vymluvit-omluvit/">procrastinator</a>,
probably because I’m a perfectionist, and vice versa, and so on.
To make myself maximally more useful, the most useful change I
could’ve made would’ve been to procrastinate less. But I had not,
as yet, hit upon a <a href="https://schmonz.com/2015/07/29/enthusiasm-engineering/">self-engineering</a>
trick to that end.</p>
<h2>I’ve got some tricks now</h2>
<p>The To-Do List Trick, for example, has four steps:</p>
<ol>
<li>Write down a bunch of possible tasks.</li>
<li>Pick the most important task, the easiest one, and one more.</li>
<li>Put the easiest task first.</li>
<li>Don’t worry about the order of the other two.</li>
</ol>
<p>Step 1 eases my fear of spending precious productive minutes on the
wrong thing. Step 2 limits today’s scope to tasks that I can expect
to complete and are worth completing. Step 3 helps me spend less
time not starting, and leaves me with much-needed momentum.</p>
<p>You might think Step 4 looks like a microoptimization. It’s not.
It’s weirdly important.</p>
<p>When I get to the second task, I sometimes exercise the option to
defer it until after the third one. Leaving myself that choice lets
me indulge my procrastinatory tendencies when I really want to, so
I can spend less cognitive energy on controlling myself. Knowing
that I’ll be procrastinating <em>productively</em>, I also don’t spend
energy second-guessing my choice to procrastinate. Since I start
sooner and throw off less waste heat, I find myself getting more
done, so I feel better about myself, so I keep getting more done.</p>
<p>That’s why I mustn’t worry about the order of the second and third
to-dos. If I’d put any thought whatsoever into the ordering, then
I either feel less free to reorder, or I reorder anyway despite
knowing I’m going to second-guess. Either way, I find myself getting
less done, so I feel worse about myself, so I keep getting less
done. I feel a tinge of annoyance and fatigue just putting this
vicious spiral into words. To favor the virtuous spiral, Step 4 is
crucial.</p>
<h2>I’m in recovery</h2>
<p>I still think in circles sometimes, but much less often, and mostly
in ways that serve me, so it bothers me less. I still seek perfection
more often than I and others need, and I still get off to slow
starts more often than I and others want, but much less more often
than I used to. I’ve got a small bag of tricks for exerting greater
agency over my behavior. I try not to let any fall out. Occasionally
I pick up a new one.</p>
<p>The very first trick I found, the one that started my recovery, was
Test-Driven Development.</p>
<h2>TDD saved my brain</h2>
<p>For any given problem, I never quite totally believe I’ll be able
to solve it. If I start at a whiteboard, I have to think, so I have
to be smart, and I’m not sure when I’ll be done thinking, so it’s
really hard to start. Instead, I make a to-do list: an even simpler
one, with a single dumb-as-rocks failing test that points vaguely
in a direction of some sort, possibly the wrong one, who knows. I
don’t have to be smart to make it pass, so I can just do it, so I
<em>do</em> do it. This helps me spend less time not starting, and leaves
me with much-needed momentum.</p>
<p>Because I know I won’t have to be smart later to remember to test
that thing again, I don’t spend cognitive energy second-guessing
each code change. And because I generally don’t <em>have</em> to be smart
all the time, I can afford to spend cognitive energy to load a
subproblem into my head, and make careful decisions and meta-decisions
about it, when I really need to.</p>
<p>Since I start sooner and throw off less waste heat, I find myself
getting more done, so I feel better about myself, so I keep getting
more done. Recognize the pattern? This is where I discovered it.</p>
<p>TDD not only helps me sidestep procrastination, it helps me directly
address perfectionism. By overriding my default vague, implicit
self-expectations with specific, explicit system expectations, TDD
reduces my brain’s WIP from “effectively infinite” to “approximately
1”. Test-driving provides a bounded context in which my code
frequently <em>is</em> perfect: when green, it’s perfect at doing everything
it’s ever been asked to do. And the tests that accumulate inhibit
the growth of new imperfections. With TDD, I trust myself later,
so I can confidently <a href="https://schmonz.com/2015/02/25/the-when-to-stop-kata/">stop sooner</a>.</p>
<h2>Conclusion</h2>
<p>I will always be a procrastinator and perfectionist. The thinking
behind TDD started me on the path to getting better, <a href="http://tistil.tumblr.com">in software
development and in life</a>. I’ve acquired
enough support, tools, and habits to do timely and effective work.</p>
<p>Still, I can always improve. And sometimes there’s no more perfect
way to procrastinate than to <a href="https://schmonz.com/2015/08/05/confessions-of-a-twitter-completionist/">seek
self-improvement</a>.</p>
Confessions of a Twitter completionisthttps://schmonz.com/2015/08/05/confessions-of-a-twitter-completionist/Amitai Schlair2016-11-12T01:39:43Z2015-08-09T17:04:02Z
<h2>Feel sorry for me</h2>
<p>It’s been a tough week to keep up with Twitter.</p>
<h2>Okay, don’t</h2>
<p>I realize this claim, as stated, may not arouse your sympathies.
Most folks don’t care about Twitter; of those who do, most probably
don’t feel any obligation to keep up with their timeline; of those
who do, most probably see themselves somewhere along a continuum
describing how frequently they take sips from the firehose. I admire
those people. When I say “keep up”, I mean sealing my mouth around
the firehose so that the whole of the flow (at the time of writing,
<a href="https://twitter.com/schmonz/following">992 people</a>) goes through
me.</p>
<p>Being a fairly fast reader is a prerequisite. Still, the firehose
is always faster. When I’ve caught up recently and am not very far
behind, I tend to evaluate each new tweet with more attention; if
I’m hours behind, I have to do a lot more skimming. Either way,
when I see links to papers, articles, blog posts, and the like, I
mostly <a href="https://www.instapaper.com/">save them for later</a>.</p>
<h2>Psychological self-trickery</h2>
<p>Save-for-later is among the most effective self-manipulation hacks
I’ve yet found. I want to feel like I’ve read everything I need to
have read. If I can barely keep up with tweets, then I definitely
can’t keep up with all the follow-up reading material they link to.
When I save an article for later, that almost always means I’ll
never see it again. But occasionally (mostly on planes) I do leaf
through my read-it-later pile. And when I encounter a situation in
which I vaguely recall having saved material that might be helpful,
lo and behold, Past Me has made it easy for Present Me. All told,
“save-for-later” lets me feel like I’ve read everything I need to
have read right now, because I’ve taken action to minimize my
unawareness of things I might need to read in the future. Evidently
I suffer from a kind of time-shifted <a href="https://en.wikipedia.org/wiki/Fear%5Fof%5Fmissing%5Fout">FOMO</a> for knowledge.</p>
<p>Keeping up with Twitter this week might have been a bit easier had
I attended either
<a href="http://www.associationforsoftwaretesting.org/conference/cast-2015/">CAST</a>
or <a href="http://agile2015.agilealliance.org/">Agile 2015</a>, rather than
<a href="https://agilein3minut.es/14">being at work trying to do work</a>. But
I couldn’t just mute
<a href="https://twitter.com/search?q=%23agile2015"><code>#agile2015</code></a> and
<a href="https://twitter.com/search?q=%23cast2015"><code>#cast2015</code></a> from my
timeline. I missed all those conference talks about my livelihood,
all those hallway conversations with my tribemates. Twitter is one
of the few ways I can still perhaps learn from them. See, there’s
that knowledge-FOMO again. I know my personality contains a strong
element of compulsiveness. So when I observe my impressive dedication
to rationalizing being a Twitter
<a href="http://www.urbandictionary.com/define.php?term=completionist">completionist</a>,
I’m obliged to wonder whether I ought to continue to indulge my
default preference, or maybe devote some energy and <a href="https://schmonz.com/2015/07/29/enthusiasm-engineering/">arrange myself
to behave differently</a>.</p>
<h2>Still no?</h2>
<p>If this question doesn’t arouse your sympathies either, consider
how long it takes to read the entire newspaper in one sitting. Now
imagine that you</p>
<ul>
<li>Spend the same total amount of time reading, but as the sum of
many smaller intervals,</li>
<li>Follow up elsewhere on half the smaller articles to avoid leaving
your mind dangling,</li>
<li>Don’t know how long the newspaper you’re trying to finish is going
to be today, and</li>
<li>Read this unrelaxing, variable-length paper every day.</li>
</ul>
<p>Switching to Twitter for your news might require more total coffee.
Even if it doesn’t, the frequent attention switches will leave you
jittery. When I force the entire flow to go through me, some of it
inevitably comes out my ears. And when I <a href="https://schmonz.com/2015/07/22/no-overtime/">go on
vacation</a>, I feel relieved to be excused
from firehose duty.</p>
<h2>Nobody was making me do it</h2>
<p>If that’s so, then besides my compulsions, what compels me to return
to duty? Unlike the convoluted “reasoning” I’ve subjected you to
in this post, this one’s simple. A year ago, I was struggling to
<a href="https://schmonz.com/2014/04/01/my-superpower/">make a career change</a>. My strategy
eventually worked, just before my budget ran out. Without Twitter,
I could not have <a href="https://schmonz.com/coach/">succeeded</a>.</p>
<p>Twitter? Really? Yes. I used it to find people who were doing what
I wanted to be doing and listen directly to them. How did they talk
about their work? Build my vocabulary. What questions did they find
worth consideration? Consider them. How did they seek growth? Seek
mine. What interested them in conversation? Try, if and when I felt
I could, to offer it. Thanks to Twitter, I formed needed connections
outside my brain that led me to form needed connections inside it,
so that by the time the right opportunity came knocking, I was the
right opportunist to open the door.</p>
<h2>Conclusion</h2>
<p>I still use Twitter this way, and intend to continue. But I know
enough now (and maybe knew enough all along) that the constraint
on my being helpful to teams and organizations isn’t how much I
know. It’s how effectively I pay attention. That’s one thing Twitter
can’t help me with — unless one of you posts a link to an article
about paying attention at a time when I’m sufficiently caught up
to read it on the spot.</p>
Enthusiasm engineeringhttps://schmonz.com/2015/07/29/enthusiasm-engineering/Amitai Schlair2016-11-12T01:39:43Z2015-08-11T14:55:26Z
<h2>I’m not smart enough to have ideas before I need them</h2>
<p>Last week an attentive colleague heard something potentially
self-contradictory in my reasoning and reflected it back to me. His
question was too precisely unexpected for me to remember it precisely
well, but it elicited an immediate response that was memorably
clarifying for both of us: “As a developer, I expect to be surprised
often by what the business needs from the software we’re building,
so I want to be surprised as little as possible by our software.”
He asked if I’d ever said those words in that order before. I had
not, and perhaps never would have, but for his careful observation
and question.</p>
<h2>I’m just smart enough to cope</h2>
<p>An observation by <a href="https://twitter.com/patmaddox">Pat Maddox</a> a few
months back <a href="https://twitter.com/schmonz/status/587641752112209920">induced me to
formulate</a>:</p>
<blockquote><p>”If you want to want to X, then arrange for whatever helps you
want it. Enthusiasm engineering.”</p></blockquote>
<p>I have lots of values of X I want (for varying degrees of “want”)
to be handling differently. Most of them aren’t, at any given time,
my most pressing concern. So they tumble around at the back of my
brain, taking up a bit of space, and seeming more and more difficult
the longer I’ve evidently failed to address them.</p>
<p>The downside is that no matter what doesn’t work about my current
behavior, it’s relatively easy for me to make a habit of it. The
<a href="https://twitter.com/GeePawHill/status/622833903267504128">upside</a> is
that as soon as I notice the problem — usually when it’s more
biggish — it’s relatively easy for me to change my habit. I wasn’t
doing it that way for any particular reason, so if I’ve got a reason
to do it another way, I can arrange myself to do that until it
sticks.</p>
<h2>I can sometimes evaluate more eagerishly</h2>
<p>If a future habit-induced difficulty would be sufficiently biggish
that I’d rather not wait for it to get that far, I can try to arrange
myself to address it sooner. This is considerably less of a sure
thing. My main strategy is to change my scenery.</p>
<p>Changing which desk/office/coffeeshop/city I’m working from today,
what I’m working on today, and/or <em>whether</em> I’m working today induces
temporary changes in what I notice and attend to. As such, I can
rely on changing my scenery to be temporarily useful. Among the
<a href="https://twitter.com/hashtag/AwesomeBandNames?src=hash">Temporary Usefuls</a>
are invitations to consider making more lasting changes to one or
two of my default settings. If I’m a <a href="https://en.wikipedia.org/wiki/complex%20adaptive%20system">complex adaptive system</a>, and I want to be making different choices, then I need
to arrange conditions that are likely to encourage me to make those
choices. I’m willing to make the effort for one or two things at
a time, if they seem likely to be worth it.</p>
<h2>I default to comfort</h2>
<p>When I’m not paying attention, I seek comfort above all else, which
places me in familiar vantage points, where I stop noticing things
I’d otherwise want to notice. That’s why, as a general rule, when
someone invites me to do something I wouldn’t choose to do on my
own, I try to accept: art museums, concerts of music that isn’t my
absolute favorite, vacations through tropical locales, etc. It’s a
good rule, if I ever want to expand beyond my self-imposed horizons.</p>
<h2>Eine kleine Enthusiasmusingenieurwesen</h2>
<p>I want to want that, so I arrange for others’ invitations to help
me want it.</p>
No overtimehttps://schmonz.com/2015/07/22/no-overtime/Amitai Schlair2016-11-12T01:39:43Z2016-02-14T17:52:28Z
<p>When I was in college, I discovered that after two semesters of
the kind of thinking that helped me complete my course assignments,
I’d itch for the kind of thinking that helped me consult for clients.
And after a summer of practical-minded problem-solving, I’d be
minded to float my head back up in the clouds.</p>
<p>When I graduated and <a href="https://schmonz.com/2014/06/01/tdd-in-context-1-keeping-my-job/">got another programming
job</a>, I discovered that
the kind of thinking I do to make worthwhile software energizes
the kind of thinking I do to make worthwhile music. Once again,
the converse also turned out to be true. On work-from-home days,
I alternated between computer keyboard and piano keyboard as often
as necessary to keep my code, and my brain, valuable and sustainable.</p>
<p><a href="http://www.hendricksonxp.com">Chet Hendrickson</a> recently reminded
me that what we now call <a href="http://c2.com/cgi/wiki?SustainablePace">sustainable pace</a>
and had once called <a href="http://c2.com/cgi/wiki?FortyHourWeek">40-hour week</a> had
originally been defined in XP as “no overtime”. These are not
identical concepts. <a href="http://c2.com/cgi/wiki?OverTime">Overtime</a>, as the XP
folks meant it, meant “time spent in the office when you don’t want
to be there”, or perhaps identically “time spent working that makes
you <em>less</em> effective in the long run”. Maybe some people average
40 hours of wanting to be in their (real or virtual) office. Maybe
some of them even cluster closely around 40 hours every single
week. But there are plenty of us for whom 40 isn’t the average.
And whatever your number is, no matter how closely you cluster
around it, every now and then you need to take a zero.</p>
<p>I love <a href="https://schmonz.com/coach/">my work</a>, and I’ve enjoyed a
<a href="http://agileanswerman.com/a4hpod">cluster</a> of
<a href="https://schmonz.com/2015/06/03/self-conf-2015-almost-self-less/">completely</a>
<a href="https://schmonz.com/2015/06/17/problem-solving-leadership/">terrific</a>
<a href="https://schmonz.com/2015/06/24/agile-roots-2015-shoestring-agility-in-a-velcro-organization/">opportunities</a>
over the last couple months. But taken all together, they’ve taken
altogether too much of my time away from the life my work is supposed
to be a <em>part</em> of. By any definition, it’s been overtime. So last
week and this week, I’m taking intentional zeroes. (Don’t worry,
the writing of this post happened outside zero hours.) And when I
get back into the swing of things, knowing myself, I’ll be energized
to think and act to sustain my sustainable pace.</p>
Introducing Agile in 3 Minuteshttps://schmonz.com/2015/07/15/introducing-agile-in-3-minutes/Amitai Schlair2016-11-12T01:39:43Z2015-11-03T00:55:55Z
<p>At <a href="http://agileandbeyond.com/2015/">Agile and Beyond</a> a few months
ago, I launched a new micropodcast: <a href="https://agilein3minut.es/">Agile in 3
Minutes</a>, “the simplest podcast that could
possibly work”.</p>
<p>For as long as I can remember, I’ve always wanted to produce a real
podcast. In college, to share my music (mostly) with far-flung
friends and family, I published an <a href="https://schmonz.com/2007/01/15/the-schmonzcast-begins/">irregularly-scheduled
“Schmonzcast”</a> here on <code>schmonz.com</code>.
That sort-of podcast mattered a great deal to me, but would never
matter to more than a few others.</p>
<p>I’ve long wanted to be real-podcasting because it seemed like it’d
play to my strengths. I’ve learned that some people find my voice
pleasant to listen to, and that sometimes I express ideas in ways
people are receptive to. And I’ve already got a handle on the
podcast-publishing basics.</p>
<p>As soon as the idea to describe aspects of Agile in tiny timeboxes
landed in my head, I <em>knew</em> it was worth trying. How many minutes,
though? Four felt like a giant blank canvas; three felt liberatingly
constraining. Three, then. I bought a domain and a decent microphone,
wrote and recorded the first couple episodes, and announced them,
fittingly, in a <a href="https://en.wikipedia.org/wiki/Lightning%5Ftalk">Lightning talk</a>. Every week since
Agile and Beyond, I’ve been writing, editing, editing, <em>editing</em>,
recording, processing, and publishing one new episode. (<a href="https://agilein3minut.es/12">Episode 12</a> went up yesterday.)</p>
<p>You might be wondering, how Agile a production is Agile in 3 Minutes?
The one-week iterations keep me delivering, the 450-word increments
feel sustainable, and the one-at-a-time batches give me chances
for feedback.</p>
<p>Until now. Whatever I might have learned from delivering #12 won’t
be reflected in #13, because they were written and produced in
rapid succession. (I’ll be mostly off-grid until it’s time to cook
14.) The larger batch size makes me a little uncomfortable. But
I’ve learned in other contexts — including software development
— that choosing not to indulge my perfectionist tendencies often
produces results that vary in some useful way. And since one of
my <a href="https://agilein3minut.es/about">goals for the show</a> is that
every episode be someone’s favorite, maybe there’ll be useful
variance in these two. We’ll see, won’t we? I have no idea what
Agile in 3 Minutes will add up to, but I’m pleased that it’s starting
to add up to <em>something</em>.</p>
<p>You might also be wondering, did I use the whole 5-minute timeslot
for my lightning talk? I did not. 3 minutes was enough.</p>
TDD in context #10: Testing acceptancehttps://schmonz.com/2015/07/08/tdd-in-context-10-testing-acceptance/Amitai Schlair2016-11-12T01:39:43Z2015-07-08T04:00:00Z
<h2>Previously</h2>
<p>This is the last in a series about TDD’s value to humans, following</p>
<ol>
<li><a href="https://schmonz.com/2014/06/01/tdd-in-context-1-keeping-my-job/">Keeping my job</a>,
in which I lost my manager’s trust,</li>
<li><a href="https://schmonz.com/2015/04/15/tdd-in-context-2-a-last-minute-feature/">A last-minute
feature</a>, in
which I regained some,</li>
<li><a href="https://schmonz.com/2015/04/22/tdd-in-context-3-deadline-pressure/">Deadline pressure</a>,
in which I earned quite a bit more than I’d started with,</li>
<li><a href="https://schmonz.com/2015/05/06/tdd-in-context-4-continual-delivery/">Continual delivery</a>,
in which the circle of trust grew to include our Operations team,</li>
<li><a href="https://schmonz.com/2015/05/13/tdd-in-context-5-fail-safe/">Fail-safe</a>, in which we
were always deploying soon,</li>
<li><a href="https://schmonz.com/2015/05/20/tdd-in-context-6-a-big-project/">A big project</a>, in
which we delivered an 8-month project with minutes to spare,</li>
<li><a href="https://schmonz.com/2015/05/27/tdd-in-context-7-win-win/">Win-win</a>, in which we
helped another project hit the same deadline,</li>
<li><a href="https://schmonz.com/2015/06/10/tdd-in-context-8-no-secret/">No secret</a>, in which
people oddly found the reasons for our success disappointing, and</li>
<li><a href="https://schmonz.com/2015/07/01/tdd-in-context-9-thwarted/">Thwarted</a>, in which
we almost reached a new level of collaborative development</li>
</ol>
<h2>Is there a doctor in the house?</h2>
<p>People who rely on the outcomes of software development work, but
who have not experienced firsthand what it’s like to do that work,
sometimes present with a disheartening cluster of chronic symptoms:</p>
<ul>
<li>They want to do something to help bring about an outcome</li>
<li>They see some simplistic knobs they could turn</li>
<li>They don’t see the costs of turning those knobs, or notice the
less visible knobs, or consider abstaining from knob-turning
altogether</li>
</ul>
<p>People exhibiting these symptoms might, for instance, ask a developer
to spend less time testing. (Note that they wouldn’t be caught dead
on the record instructing anyone to write fewer tests, but that’s
exactly what they’re wishing for.) This particular simplistic knob
appears to provide a way to trade quality for speed. If we rarely
have shortfalls in quality, and we’re perpetually understaffed,
then let’s turn this knob just this one time. Oh, and while we’re
presuming that developers don’t spend their time wisely, let’s also
presume that in any given unit of time they can always find a way
to accept more work.</p>
<p>By contrast, managers and customers in good software health know
that developer productivity is nonlinear. Even when solving relatively
well understood problems, time can’t usually be reclaimed from
test-driving and redeemed for more stuff done over any horizon
longer than a few lungfuls of overly conditioned air. The outcome
of attempting to trade quality for speed is often not only to have
traded quality for nothing, but also to have undermined the hard-won
basis of the attainable speed that had once been attained. (And
“productivity” is itself a questionable construct when the goal is
ostensibly not to maintain busyness, but to <a href="https://schmonz.com/2014/03/27/how-to-develop-software/">solve problems for
humans</a>.)</p>
<h2>Is there an <em>epidemiologist</em> in the house?</h2>
<p>Quite a few folks with other goals do nonetheless exist, as do those
who come to poor knob-wiggling conclusions <a href="https://agilein3minut.es/4">via faulty
premises</a>: people who don’t begin to
understand the nature of software development work, don’t begin to
imagine that their lack of understanding could possibly hinder the
outcomes they wish for, don’t prevent themselves from intervening
roughly and habitually in sensitive systems, and cause pain for
themselves that perhaps only hints at the pain they cause others.
I worked with (and for) many such people at the organization featured
in this series of stories. Their broad and deep misunderstandings
of the costs and benefits of TDD and of software development in
general — and my overall lack of success in reversing or otherwise
overcoming them — ultimately limited my effectiveness in my various
team roles. But everything I learned along the way is mine forever,
to keep and <a href="https://agilein3minut.es/">to share</a>.</p>
<h2>Retrospective</h2>
<p>We had a great run. Along the way, while reviewing my performance,
I summarized it thus:</p>
<blockquote><p>Test-Driven Development has become thoroughly entrenched as a
standard practice for <code>$OURPRODUCT</code> Engineering. The dividends, many
and profound, are difficult to completely quantify. Nonetheless,
three overall patterns are striking:</p>
<ol>
<li>We’ve reversed the usual signs of software aging. As typical
projects expand, the risk of change increases and the pace of
development therefore slows; as <code>$OURPRODUCT</code>’s test coverage
expands, the <a href="https://schmonz.com/2015/04/22/tdd-in-context-3-deadline-pressure/">risk has decreased and the pace has
accelerated</a>.
With TDD, we can safely develop <a href="https://schmonz.com/2015/05/20/tdd-in-context-6-a-big-project/">complex, invasive new
features</a>
(like support for an archaic database system’s not-exactly-identities)
and trust them to work as designed without breaking existing
code.</li>
<li>We’ve fundamentally changed our relationship with Operations.
They now <a href="https://schmonz.com/2015/05/06/tdd-in-context-4-continual-delivery/">trust us to ship working
software</a>
because they understand how TDD works. We’ve taken advantage
by releasing monthly (up from quarterly), which controls the
rate of change, ensures that new code is always production-ready,
and <a href="https://schmonz.com/2015/05/13/tdd-in-context-5-fail-safe/">maintains our sharp and careful release
habits</a>.</li>
<li>We’ve identified a new paradigm for collaborative development
at <code>$COMPANY</code>. The situation: <code>$OTHERPROJECT1</code> needed <code>$OTHERPROJECT2</code>,
<code>$OTHERPROJECT2</code> needed new code in <code>$OURPRODUCT</code>, and <code>$OURPRODUCT</code>
was laser-focused on that <code>$ARCHAIC_DATABASE_SYSTEM</code>, leaving
me zero time for requirements and design discussions with
<code>$OTHERPROJECT1</code>. They generously offered a developer on short-term
loan (a week or two) who happened to understand our product and
had the needed technical skills. The paradigm: I accepted the
loan on condition that it result in a set of test cases for our
test suite. This forced all the discussions to happen upstream
where they cost me nothing, made efficient use of the loaned
developer’s cross-silo expertise, and delivered a simple,
unambiguous spec which took me an hour or two to implement.
<code>$OTHERPROJECT2</code> and <code>$ARCHAIC_DATABASE_SYSTEM</code> <a href="https://schmonz.com/2015/05/27/tdd-in-context-7-win-win/">both shipped
on schedule</a>, thanks to TDD.</li>
</ol>
<p>In summary, the cultural shift to Test-Driven Development has
resulted in less risk, more intelligent use of existing resources,
and more agile reactions to the changing needs of the business.</p></blockquote>
<h2>Conclusion</h2>
<p>On our own, in a little corner of a big company, we created half a
humane workplace. If our efforts had been recognized and reciprocated,
it could have become a whole one. The pride I always felt in our
work, combined with the pain I frequently felt while doing it, led
me to become a <a href="https://schmonz.com/coach/">software development coach</a>. I want to help
people understand how this kind of work works, and how it can be
done better, because I want our lives to be filled with less pain
and more pride.</p>
<p>And that, as fully as I can tell — and have now fully told you —
is the human value of TDD.</p>
TDD in context #9: Thwartedhttps://schmonz.com/2015/07/01/tdd-in-context-9-thwarted/Amitai Schlair2016-11-12T01:39:43Z2015-07-01T04:00:00Z
<h2>Previously</h2>
<p>This is the ninth in a series about TDD’s value to humans, following</p>
<ol>
<li><a href="https://schmonz.com/2014/06/01/tdd-in-context-1-keeping-my-job/">Keeping my job</a>,
in which I lost my manager’s trust,</li>
<li><a href="https://schmonz.com/2015/04/15/tdd-in-context-2-a-last-minute-feature/">A last-minute
feature</a>, in
which I regained some,</li>
<li><a href="https://schmonz.com/2015/04/22/tdd-in-context-3-deadline-pressure/">Deadline pressure</a>,
in which I earned quite a bit more than I’d started with,</li>
<li><a href="https://schmonz.com/2015/05/06/tdd-in-context-4-continual-delivery/">Continual delivery</a>,
in which the circle of trust grew to include our Operations team,</li>
<li><a href="https://schmonz.com/2015/05/13/tdd-in-context-5-fail-safe/">Fail-safe</a>, in which we
were always deploying soon,</li>
<li><a href="https://schmonz.com/2015/05/20/tdd-in-context-6-a-big-project/">A big project</a>, in
which we delivered an 8-month project with minutes to spare,</li>
<li><a href="https://schmonz.com/2015/05/27/tdd-in-context-7-win-win/">Win-win</a>, in which we
helped another project hit the same deadline, and</li>
<li><a href="https://schmonz.com/2015/06/10/tdd-in-context-8-no-secret/">No secret</a>, in which
people oddly found the reasons for our success disappointing</li>
</ol>
<h2>A growth opportunity</h2>
<p>Our team had solidly established the habit of writing good tests
first and listening to what they told us. People who could read
Perl could read our tests, and we’d taken full advantage of that
to build shared understanding with stakeholders of sufficiently
technical backgrounds, whose trust served to <a href="https://schmonz.com/2015/05/06/tdd-in-context-4-continual-delivery/">reinforce the
effectiveness of our
collaboration</a> and
our product. We knew how valuable it’d be if we could find a way
to extend that understanding and trust to a broader audience. We
were on the lookout.</p>
<p>When our product and team moved to a better-fitting department, our
team’s reputation garnered some attention from our new neighbors.
For the first time, we found ourselves living next to a group of
QA folks, whose perceptive manager saw us as an opportunity. His
more skilled people could help us and learn from us. Would I like
to borrow one of them for a full two-week iteration?</p>
<p>Unlike previous occasions when I’d been <a href="https://schmonz.com/2015/05/27/tdd-in-context-7-win-win/">offered a person on
short-term loan</a>, I <em>instantly</em>
had a pretty good idea how we could put a skilled tester to effective
use. But not yet. First, we needed to prepare.</p>
<h2>Our preparations</h2>
<p>Our TDD practice was already oriented toward system behavior, aimed
at uncovering not only design choices but also acceptance criteria.
We would usually find surprising ramifications of a chosen approach
early in development, while it was still relatively cheap to review
with stakeholders and either get more precise agreement or adjust
the goal. We wanted our borrowed tester to comfortably participate
in those conversations and potentially contribute test scenarios.
We now needed a language more shared and more commodious than Perl.
And we didn’t need — indeed, couldn’t afford — to start shlepping
around any manual tests or non-executable specifications on our
journey. Dear reader, you doubtless see what we saw: Gherkin could
be our shared language, and Cucumber could incorporate it into our
build.</p>
<p>There was one small problem: none of us had ever used Cucumber
before. We didn’t want to waste any of our tester’s limited time
figuring out how to wield a new tool. We wanted to be ready the
moment he arrived. So we immediately picked a feature perfect for
learning: a low-urgency feature intended for the benefit of our
compatriots in Operations, and whose desired behavior we understood
very well. Instead of confidently writing our usual tests, we
wrestled with how best to express our assertions in Gherkin-inflected
English, and how best to arrange for them to fail meaningfully
against the production code we were wanting to change.</p>
<p>When we got it figured out well enough, with Cucumber hooked into
the build, we asked Ops to review the spec with us. Because they
could! And maybe they’d spot something we’d misunderstood! When
they didn’t, we proceeded to test-drive as usual, albeit with
slightly different red-test messages; when we got to green, the
feature was every bit as done (and well done) as usual.</p>
<h2>The payoff</h2>
<p>We were ready for our tester. When that iteration kicked off, we
would set right to pair-writing scenarios, likely conjuring more
meaningful tests than we’d have done on our own, and our visitor
would be acquiring a new and marketable skill.</p>
<p>Or at least he would have, if the window of opportunity hadn’t been
rudely slammed shut.</p>
<h2>A change of plans</h2>
<p>The original offer, and our preparatory actions to take advantage
of it, occurred while product decisions had still been mine — which
is to say, when the team had opinions distinct from mine, I generally
listened and took them into account. But I was in transition to a
much-needed role as an internal Agile coach, so my team and product
were necessarily in transition too. By the time the promised iteration
rolled around, product decisions were no longer mine — which turned
out to mean they were made with very limited consideration for the
team (me included).</p>
<p>The new product manager promptly nixed any further efforts with
Gherkin as a language, Cucumber as a tool, and QA as a partner in
our development process. No reason was ever shared with us for this
decision, which we felt wasted our investment in time and effort,
ignored our needs and wishes, and limited our options for improving
our effectiveness.</p>
<h2>Conclusion</h2>
<p>Cucumber continued to be the test runner for that lone Ops feature.
But who knows how much it might have helped us collaborate more
productively with testers, non-technical managers and customers,
and the business as a whole? We never got the chance to find out.</p>
Agile Roots 2015: Shoestring Agility in a Velcro Organizationhttps://schmonz.com/2015/06/24/agile-roots-2015-shoestring-agility-in-a-velcro-organization/Amitai Schlair2024-02-13T04:28:32Z2016-01-12T20:41:32Z
<h2>Back to our roots</h2>
<p>Last week I had the privilege of speaking at
<a href="https://web.archive.org/web/20150906134405/http://www.agileroots.com/">Agile Roots</a>
in South Jordan, Utah, a place
hemmed in by mountain ranges to the east and west. An image that
depicts how it felt to be there was hard to capture, but as the
plane came into Salt Lake City, I was able to capture this:</p>
<p><a href="https://schmonz.com/2015/06/24/IMG_5480.JPG"><img src="https://schmonz.com/2015/06/24/IMG_5480.JPG" width="400" height="300" alt="SLC landing" title="SLC landing" class="img" /></a></p>
<p>The mountains to the east hold Snowbird, the place where “Agile”
was given its particular meaning. I’m not religious about the
Manifesto, or much else, but I couldn’t shake the feeling I was
someplace important — possibly because with so many
<a href="https://web.archive.org/web/20150912022534/http://www.agileroots.com/sessions">outstanding speakers</a>,
I felt particularly honored to be included.</p>
<h2>That’s just it</h2>
<p>And if there’s a single word that conveys why my experience at Agile
Roots was so special, it’s “included”. I haven’t always felt that
way at other conferences I’ve attended, even as a speaker. But from
the moment <a href="http://www.dayleyagile.com">Alan Dayley</a> suggested that
Agile Roots was the sort of conference I’d enjoy, and as <a href="http://lisacrispin.com">Lisa
Crispin</a> and I were preparing <a href="http://lisacrispin.com/2015/07/05/devops-dojo-at-agile-roots-2015/">our
workshop</a>,
I suspected this experience would be different. And by the time I’d
been administered a <a href="http://patmaddox.com">Pat Maddox</a> power hug
and had lunch and dinner with some other speakers, I knew.</p>
<p>Agile Roots was amazing: small and familial, filled with great
people, and run with evident love and care. A beautiful conference,
and an honor to be — and <em>feel</em> — part of it.</p>
<p><a href="https://schmonz.com/2015/06/24/IMG_5495.JPG"><img src="https://schmonz.com/2015/06/24/IMG_5495.JPG" width="400" height="300" alt="SLC sunset" title="SLC sunset" class="img" /></a></p>
<h2>Listen to one of my talks</h2>
<p><em>Schmonzcast #18</em>: In addition to the workshop, I gave an experience
report. At an Agile-unfriendly Fortune 100 bank, with little budget
or domain expertise — and no testers! — our tiny team’s discipline
and creativity enabled us to safely and reliably manage risk, deliver
value, and earn precious trust. If you like, you can hear me tell
a few stories of our most effective maneuvers.</p>
Problem Solving Leadershiphttps://schmonz.com/2015/06/17/problem-solving-leadership/Amitai Schlair2019-07-23T19:35:17Z2015-08-11T15:00:31Z
<h2>PSL</h2>
<p>Last week I and 23 others made a pilgrimage to Albuquerque to
participate in the <a href="https://www.congruentchange.com/problem-solving-leadership/">Problem Solving
Leadership</a>
workshop.</p>
<h2>What did we do all week?</h2>
<p>Mainly exercises, discussion, and reflection on designing problems
to be solved, environments in which to solve them, and ourselves.</p>
<p>Can I say more about any of that? No, I don’t want to ruin anyone
else’s fun.</p>
<h2>What did I learn about designing problems and problem-solving environments?</h2>
<p>Maybe nothing, maybe lots. Not sure yet. Maybe I’ll notice over
time, as I’m facing various challenges, that I seem to keep having
better ideas about how to approach them. One idea I’ve had before
that occurred to me again:</p>
<blockquote><p><a href="https://twitter.com/schmonz/status/607933657072861185">Observation from exercise retro: we always work in iterations,
whether we choose them or
not.</a></p></blockquote>
<p>Another: for the entirety of the workshop,
<a href="http://www.estherderby.com/">Esther</a> and
<a href="http://www.geraldmweinberg.com/">Jerry</a> modeled changing focus
rapidly between the problem, how we’re solving the problem, and how
we’re arranging ourselves to solve the problem. I value this kind
of self-correcting thought process very highly, and it was an unusual
chance for me to observe it in others (and not only our facilitators)
for an extended period.</p>
<h2>What did I learn about myself?</h2>
<blockquote><p><a href="https://twitter.com/schmonz/status/608699240332730368">Self-observation: few things are more exhausting to me than
seeing someone treated
unkindly.</a></p></blockquote>
<p>Conversely, others can tell that I <a href="https://agilein3minut.es/8">make efforts</a>
to be kind.</p>
<blockquote><p><a href="https://twitter.com/schmonz/status/609122342187347968">Observer feedback: I’m like a lone hiker. I go off on my own,
be creative, and am accepted back because I bring something
valuable.</a></p></blockquote>
<p>I found the metaphor striking and the explanation somewhat surprising,
considering:</p>
<blockquote><p><a href="https://twitter.com/schmonz/status/608699003316752384">Self-observation: I’m more energized by being part of a conspiracy
than by being a lone
conspirator.</a></p></blockquote>
<p>But there’s never been any question where I get my energy. Further
proof:</p>
<blockquote><p><a href="https://twitter.com/schmonz/status/607757398996942848">Coffee + cool, dark, quiet time + reflection = second wind.
Classic introvert.</a></p></blockquote>
<h2>What will I remember?</h2>
<p>Getting to know some <a href="https://twitter.com/schmonz/status/607396509827481600">nice people with fast
brains</a>.</p>
<p>Acting as emergency backup consultant during lunch so Jerry could
eat too.</p>
<p>Feeling validated when my approach to consulting was apparently (1)
not entirely unlike his and (2) helpful.</p>
<p>Sitting quietly with Jerry for a few minutes, sharing something
very dear to me, and appreciating his appreciation.</p>
<h2>Should you attend PSL?</h2>
<p>That depends. Are you as capable as you’d like to be at creating
an environment that enables everyone to contribute productively to
solving problems?</p>
TDD in context #8: No secrethttps://schmonz.com/2015/06/10/tdd-in-context-8-no-secret/Amitai Schlair2016-11-12T01:39:43Z2015-06-10T04:00:00Z
<h2>Previously</h2>
<p>This is the eighth in a series about TDD’s value to humans, following</p>
<ol>
<li><a href="https://schmonz.com/2014/06/01/tdd-in-context-1-keeping-my-job/">Keeping my job</a>,
in which I lost my manager’s trust,</li>
<li><a href="https://schmonz.com/2015/04/15/tdd-in-context-2-a-last-minute-feature/">A last-minute
feature</a>, in
which I regained some,</li>
<li><a href="https://schmonz.com/2015/04/22/tdd-in-context-3-deadline-pressure/">Deadline pressure</a>,
in which I earned quite a bit more than I’d started with,</li>
<li><a href="https://schmonz.com/2015/05/06/tdd-in-context-4-continual-delivery/">Continual delivery</a>,
in which the circle of trust grew to include our Operations team,</li>
<li><a href="https://schmonz.com/2015/05/13/tdd-in-context-5-fail-safe/">Fail-safe</a>, in which we
were always deploying soon,</li>
<li><a href="https://schmonz.com/2015/05/20/tdd-in-context-6-a-big-project/">A big project</a>, in
which we delivered an 8-month project with minutes to spare, and</li>
<li><a href="https://schmonz.com/2015/05/27/tdd-in-context-7-win-win/">Win-win</a>, in which we
helped another project hit the same deadline</li>
</ol>
<h2>Our somewhat interesting behavior</h2>
<p>Our track record of <a href="https://schmonz.com/2015/05/13/tdd-in-context-5-fail-safe/">delivering working, valuable code every
month</a> began to attract some
mild curiosity. For most teams, the organization’s barriers to
releasing production code had the effect of encouraging them to go
to production less often with only the planned changes. We didn’t
see that as an effective way to manage risk for — or add value to
— code with test-driven properties. To suit our context, we chose
the opposite approach: go to production <em>more</em> often with whatever
was ready. Onlookers were curious to note that this game we were
all playing could evidently be played so differently without
immediately and visibly losing.</p>
<h2>Our <em>very</em> interesting behavior</h2>
<p>When we <a href="https://schmonz.com/2015/05/20/tdd-in-context-6-a-big-project/">delivered a project on
deadline</a> while <a href="https://schmonz.com/2015/05/27/tdd-in-context-7-win-win/">supporting
another project being delivered on
deadline</a>, our strange approach
(whatever it really was) looked much more like a winning strategy.
Onlookers who might have dismissed our monthly release-what’s-ready
cadence as “undisciplined” might have felt motivated to reevaluate.
Our previous track record <em>plus</em> a successful project attracted
much more curiosity.</p>
<h2>What about QA?</h2>
<p>One question I’d get asked was, how did our QA people validate the
changes we were making so frequently without strictly adhering to
a plan? Surely this was taxing for them. How did we arrange their
work to be able to sustain our pace?</p>
<p>We didn’t have any QA people. Our tiny team on a tiny budget had
learned, of austere necessity, to survive without. Our software had
wide-ranging security implications. We had to work in a quality-assuring
way at all times. There was no QA bottleneck because there was no
QA phase.</p>
<p>This was a surprising answer. Nearly all development teams had “QA
people” (whatever that even means). I would occasionally get an
offer of someone for a few days, but I never knew what to have them
do. What could they manually test that we hadn’t already automated?
What could they exploratorily find that we hadn’t already found?
To be polite, and just in case, I would accept these offers, summarize
what was new lately, and point them at the GUI. We got very little
value from this arrangement. If we could have added a permanent
team member with complementary testing expertise, it might have
been much more valuable. Still, not having someone didn’t seem to
be impeding us.</p>
<h2>So what was our secret?</h2>
<p>It was also an intriguing answer, because it appeared to take the
form of “doing more with less.” Everyone always needed to be doing
more with less. Their next question was, what were we doing to
obtain this level of quality, speed, and predictability?</p>
<p>Most of our quality and speed came from TDD. Most of our predictability
came from test coverage and Scrum-style velocity. But TDD would
have been difficult, and velocity-based predictions would have been
disappointing, if we hadn’t first <a href="https://schmonz.com/2015/04/15/tdd-in-context-2-a-last-minute-feature/">rescued our code just
enough</a> to where
we could incrementally improve its health over time. What was it
that we were doing? Being skilled, disciplined, and patient.</p>
<h2>Unable rightly to apprehend</h2>
<p>I hadn’t expected this to be a surprising answer, so I was surprised
by the responses it provoked. Faces that had been pumped full of
anticipation deflated. “We can’t scale that,” said one. It hadn’t
occurred to me that anyone could be hoping for easy actions and
fast results to what I knew to be hard problems. Charles Babbage
famously <a href="https://en.wikipedia.org/wiki/Garbage%20in%2C%20garbage%20out">rebuked someone for asking an incoherent
question about his computing machine</a>; I
was seeing what looked like an incoherent reaction to my answer
about our software development machine.</p>
<h2>Conclusion</h2>
<p>How could I account for so rapidly having transmuted respect for
our outcomes into disappointment in our methods? Not knowing, I had
to wonder. Practicing TDD had expanded our sphere of influence
greatly and made us more effective in many ways. Would the trend
continue?</p>
Self.conf 2015: Almost Self-lesshttps://schmonz.com/2015/06/03/self-conf-2015-almost-self-less/Amitai Schlair2016-11-12T01:39:43Z2015-06-03T19:34:59Z
<h2>What I did</h2>
<p>On Friday I attended <a href="http://selfconference.org">Self.conference</a>
just long enough to take in <a href="https://twitter.com/searls">Justin Searls</a>’
<a href="http://blog.testdouble.com/posts/2015-05-11-sometimes-a-controller-is-just-a-controller.html">opening
keynote</a>,
give <a href="https://schmonz.com/2015/03/05/riches-of-embarrassment/">my talk</a> (sorry,
intentionally no slides or recording), have an assumption-questioning
lunchtime conversation with my friend <a href="http://www.davidj.org">David</a>,
and get to the airport. It’s not that I didn’t want to stay longer,
but it had suddenly become more pressing that I go meet this fellow:</p>
<p><a href="https://schmonz.com/2015/06/03/IMG_5387.JPG"><img src="https://schmonz.com/2015/06/03/IMG_5387.JPG" width="300" height="400" alt="the nephew" title="the nephew" class="img" /></a></p>
<p>No regrets about my prioritization decision, but also no question
I missed out. Had I stayed longer, I would’ve had more conversations
(dunno which) and attended more talks such as these:</p>
<ul>
<li><a href="http://kwugirl.blogspot.com/2015/05/ask-vs-guess-culture-communications.html">Ask vs. Guess Culture
Communications</a></li>
<li><a href="https://speakerdeck.com/ctrevarthen/climbing-the-testing-pyramid-in-ios">Climbing the Testing Pyramid in
iOS</a></li>
<li><a href="https://goo.gl/TYpUxw">Coming Clean About Mental Health at Work</a></li>
<li>Empathy & Gender Diversity: AMA</li>
<li>Finding Joy at Work (possibly a cousin of my talk, I have no idea)</li>
<li><a href="http://jerlance.com/files/teams_as_communities_selfconf_2015.pdf">Strong Teams as Healthy
Communities</a></li>
</ul>
<p>(<a href="https://github.com/Selfconference/selfconf-2015">More slides</a>)</p>
<p>Nonetheless, I’m proud to have played a very small part in a
conference dedicated equally to <a href="https://schmonz.com/2014/03/27/how-to-develop-software/">developing
software</a> and <a href="https://schmonz.com/2015/04/08/how-to-develop-humans/">developing
humans</a>.</p>
<h2>What you might do</h2>
<p>The organizers are seeking donations to help cover for this year’s
sponsorship shortfall. If you’d prefer to wait and review the
conference financials first, <a href="https://twitter.com/selfconference/status/603305483097776128">they’ll be made public
shortly</a>.
But if you’re already sure you’d like to pitch in, <a href="http://selfconference.org/support">you
can</a>.</p>
<p>I’m sure. I want the chance to experience what I missed.</p>
TDD in context #7: Win-winhttps://schmonz.com/2015/05/27/tdd-in-context-7-win-win/Amitai Schlair2023-05-21T01:21:56Z2015-05-27T04:00:00Z
<h2>Previously</h2>
<p>This is the seventh in a series about TDD’s value to humans, following</p>
<ol>
<li><a href="https://schmonz.com/2014/06/01/tdd-in-context-1-keeping-my-job/">Keeping my job</a>,
in which I lost my manager’s trust,</li>
<li><a href="https://schmonz.com/2015/04/15/tdd-in-context-2-a-last-minute-feature/">A last-minute
feature</a>, in
which I regained some,</li>
<li><a href="https://schmonz.com/2015/04/22/tdd-in-context-3-deadline-pressure/">Deadline pressure</a>,
in which I earned quite a bit more than I’d started with,</li>
<li><a href="https://schmonz.com/2015/05/06/tdd-in-context-4-continual-delivery/">Continual delivery</a>,
in which the circle of trust grew to include our Operations team,</li>
<li><a href="https://schmonz.com/2015/05/13/tdd-in-context-5-fail-safe/">Fail-safe</a>, in which we
were always deploying soon, and</li>
<li><a href="https://schmonz.com/2015/05/20/tdd-in-context-6-a-big-project/">A big project</a>, in
which we delivered an 8-month project with minutes to spare</li>
</ol>
<h2>Cosmic justice (again)</h2>
<p>Right when our velocity had tanked (see “Change the plan” in
<a href="https://schmonz.com/2015/05/20/tdd-in-context-6-a-big-project/">A big project</a>) and
we were scrambling to get back on track, it came to light that our
system would need to provide some as-yet-unspecified new behaviors
in order for our coworker Murray to deliver his project. With a
deadline looming, was there any way we could defer the new work?
Nope. Murray had a deadline too — and it was the same as ours.</p>
<p>I invite you in this particular moment to enjoy
<a href="https://www.youtube.com/watch?v=W8Kw71ezXGU&t=37s">Jim Gaffigan on what it’s like to have four kids</a>.</p>
<h2>Why me?</h2>
<p>I was invited in that particular moment to join the discussions
between Murray and Dan, an expert stakeholder. But if I was already
unsure I had the time, energy, and cognitive capacity to hit my own
deadline, then I had approximately zilch to spend on someone else’s.
No matter how much I liked them and wanted to help, I couldn’t
afford to get involved in what would necessarily be spiraling
discussions about requirements, scope, and feasibility. Even if I
managed to sit those out, the mere thought of having to interpret
the intent of a design document made me clutch more tightly at my
mental wallet.</p>
<p>Dan’s manager, looking to break the logjam, generously offered me
a couple weeks of Dan’s time. But borrowing developers on short-term
loan with the expectation that they’ll improve overall team throughput
rarely meets expectations. Setting aside whether it’s reasonable
to assume that human productivity is additive, there’s too much for
a visitor to learn in a short time — programming language, tools,
habits, problem domain, context — before a potential payoff. Having
recently hired several developers, we’d seen ourselves get a bit
slower until they mostly knew when and how to trust themselves to
work safely and productively. That had been taking 3-6 months.</p>
<h2>Maximize the amount of work not done (by me)</h2>
<p>I continued to think through the offer, though, because if there
were an exception, it’d be Dan. He was deeply familiar with our
system’s purpose and behavior from having previously worked in our
department. He was well versed in our primary implementation language
and very comfortable writing unit tests. And, as with Murray, I
knew I could trust him.</p>
<p>The decision came down to whether I could figure out what to have
Dan do that would help me help Murray. As soon as I figured it out,
I accepted the offer and gave him this assignment:</p>
<ol>
<li>Determine exactly how my product needs to change to do what
Murray’s product needs, leaving for later everything that can
possibly be left for later.</li>
<li>Involve me not until you’re done.</li>
<li>”Done” means a specification in the form of failing test cases.</li>
</ol>
<p>Not only did Dan know everything he needed to know and do everything
I needed him to do, he did it superlatively. I expected to need to
ask about the intent of a test or two, but his spec was crystal
clear and evidently well thought out — including a few assertions
that he’d decided to comment out because the wished-for behavior
was tricky to implement and safe to defer.</p>
<h2>Mission accomplished</h2>
<p>Smart fellows that they were, Dan and Murray knew it was in our
shared interest to assign me the least thinking and typing possible.
They nailed it. I was able to stay completely focused on my project
until Dan’s tests appeared; I spent a couple afternoon hours getting
them to pass, knowing Murray would be getting precisely what he
needed (and soon, because we were always delivering soon); and by
morning I was once again completely focused on my project.</p>
<p>Given how close we came to missing our deadline, a few contiguous
hours must have been all I could spare. We made it. So did Murray.</p>
<p>When offered Dan’s capable development help, we were able to accept it
because we had a creative way to parallelize his efforts. And because
we had a test-driven way to take advantage of his expertise, all
of us met our commitments.</p>
<h2>Conclusion</h2>
<p>If there was some other situational approach we could’ve taken that
would have cost the business less or delivered more, I sure as hell
can’t think of it.</p>
TDD in context #6: A big projecthttps://schmonz.com/2015/05/20/tdd-in-context-6-a-big-project/Amitai Schlair2016-11-12T01:39:43Z2015-05-20T04:00:00Z
<h2>Previously</h2>
<p>This is the sixth in a series about TDD’s value to humans, following</p>
<ol>
<li><a href="https://schmonz.com/2014/06/01/tdd-in-context-1-keeping-my-job/">Keeping my job</a>,
in which I lost my manager’s trust,</li>
<li><a href="https://schmonz.com/2015/04/15/tdd-in-context-2-a-last-minute-feature/">A last-minute
feature</a>, in
which I regained some,</li>
<li><a href="https://schmonz.com/2015/04/22/tdd-in-context-3-deadline-pressure/">Deadline pressure</a>,
in which I earned quite a bit more than I’d started with,</li>
<li><a href="https://schmonz.com/2015/05/06/tdd-in-context-4-continual-delivery/">Continual delivery</a>,
in which the circle of trust grew to include our Operations team, and</li>
<li><a href="https://schmonz.com/2015/05/13/tdd-in-context-5-fail-safe/">Fail-safe</a>, in which we
were always deploying soon</li>
</ol>
<h2>Cosmic justice</h2>
<p>TDD had been helping us build things right. By enabling our new
monthly delivery cadence, it had just begun helping us make more
impactful choices about what to build. So by some conservation law
or other, that’s precisely when a large, non-optional project landed
atop our backlog with a hard deadline that was possibly impossible.</p>
<h2>Why us?</h2>
<p>Our first reaction was to inquire why this project, which was not
a straightforward and harmonious logical extension of our product’s
capabilities, had been assigned to our team. The response, reasonably,
was that the other options under consideration were less straightforward
and harmonious. (Unstated, but probably also a factor, was that we
had proven ourselves an effective and reliable team.)</p>
<h2>Why not us?</h2>
<p>Our second reaction was to quickly determine whether the deadline
was obviously impossible. To deliver the project outcome required
that our storage backend scale to several orders of magnitude more
data, along with a probable two- or threefold increase in concurrent
network access. That these were achievable was hardly given: our
storage backend was SQLite, not designed for this usage pattern.
If we couldn’t deliver the outcome without switching backends, then
we’d know up front we couldn’t hit the deadline, and we’d be able
to give the business almost all the time on the clock to pursue
other options. So we spiked it. The result: it’d be mostly fine,
and for several smaller bottlenecks there were effective actions
we’d be able to take.</p>
<h2>Test-driven planning</h2>
<p>Our third reaction was to slowly and painstakingly make arrangements
to find out ASAP along the way if we ever slipped into danger of
missing the deadline. Our product planning and prioritizing had
been haphazard and unstructured, but that hadn’t quite become our
biggest problem. Now it clearly was. My teammate
<a href="http://rainskit.com">Nathan</a> walked us through the reasoning:</p>
<ul>
<li>We have a hard deadline in eight months.</li>
<li>We’ll be working on this project, and only this project, until
it’s done.</li>
<li>We need early agreement from stakeholders that this is what they
want, because we can’t afford to waste effort.</li>
<li>We need early agreement from the upstream DBA team to work to our
schedule, because we can’t afford to be late.</li>
</ul>
<p>”And that’s why we’re going to make a project backlog,” said Nathan
— an ordered list of the fewest possible stories that’d get us to
the project outcome, with the simplest possible estimates attached
to each story, so that we could do the simplest possible math to get
from the deadline to the velocity we’d <em>need</em>. “Then we’ll start
completing stories, observe the velocity we <em>have</em>, and decide
whether that’s okay. It might be okay. We’ll find out soon enough.”</p>
<p>The first time we checked, a few weeks in, our velocity was fine.
A couple months later, still fine.</p>
<h2>Stick to the plan</h2>
<p>Meanwhile, we’d been continuing with our usual monthly production
deployments, even though the expected business value most months
was low, because the expected risk mitigation was high. We were
regularly making larger-than-usual internal changes, and it helped
everyone involved in the project to see pretty often that we still
hadn’t broken anything.</p>
<p>Extending our identity-management system to manage this archaic
database system’s not-exactly-identities, with their very different
behaviors and business rules, necessitated a significant set of
refactorings (afforded by our previous commitment to TDD, of course)
and a new network service, for which we designed the API we needed
from the DBA team and provided them a matching set of red tests.
Then we mocked the API and test-drove around them. When they came
back rather later asking whether they could provide a different
API, we said no, with two whole legs to stand on:</p>
<ol>
<li>See our test results here? With the API as previously defined,
our system is ready.</li>
<li>See our project burndown here? With the deadline as previously
defined, our system had <em>better</em> be ready.</li>
</ol>
<p>Our discussion turned promptly to the red API tests we’d provided
and how we could help them get to green. Which they eventually, not
a moment too soon, did.</p>
<h2>Change the plan</h2>
<p>The third time we checked our velocity, thanks in part to the API
kerfuffle, it had dropped a bunch. Not fine. So in the month leading
up to the deadline, we made two adjustments:</p>
<ol>
<li>We de-scoped the last few weeks of stories (which everyone had
agreed early on would be okay to leave out).</li>
<li>We gritted our teeth and temporarily tolerated the API having
been implemented in production <em>only</em>.</li>
</ol>
<p>If we ever wanted to change it or the code that consumed it, we’d
want a parallel version in non-prod. But DBA was having enough
trouble meeting their commitment to us. We came up with a plan to
safely end-to-end-test in production during weekend work windows,
with the new capabilities turned off for all users except us. It
took two Friday-into-Saturday all-nighters, but we got it tested
well enough.</p>
<h2>Mission accomplished</h2>
<p>On the Friday of the deadline, we completed the release into
production for all users, fulfilling the purpose of the project,
with several whole minutes to spare before midnight.</p>
<p>After midnight and a bit of Nathan’s favorite single malt, we wrote
down a backlog of all the corners that had been cut along the way
and needed repairing, starting with getting our hands on a
non-production instance of DBA’s new API, pronto. We sent the list
to our management asking for their backing. Despite repeated pleas,
nothing ever came of it — possibly because they wound up leaving
the company within the year. And that’s how it came to pass that
we wound up <a href="https://schmonz.com/2015/05/13/tdd-in-context-5-fail-safe/">running some production code we couldn’t confidently
change</a>.</p>
<p>While it was disappointing that our management was unwilling to
support or match our level of discipline, we’re still awfully glad
we did it our way — and had they cared to notice, they might have
been glad too.</p>
<h2>Because of our commitment to TDD…</h2>
<p>Our domain knowledge was easily shared among new team members.
Because of our shared knowledge, we thought of all the right stories
to include and defined them well.</p>
<p>Our development flow had become fairly smooth by the time this
project landed on us. Because our flow was generally smooth, point
estimates led us to useful predictions.</p>
<p>Every completed story was a shippable increment. Because we had the
freedom to ship every month, we exercised that freedom to buy
production-quality certainty in our progress.</p>
<p>Our just-enough-process plan actually worked. We made meaningful
hypotheses and drew informed conclusions that enabled us to adjust
the wheel, stay on schedule, and deliver an 8-month project with
confidence.</p>
<h2>Conclusion</h2>
<p>We continued to expand the scope and impact of our disciplined way
of working. Nathan had planted in our team the seed of Scrum. No
standups, no iterations, no retros; nothing more than an ordered
backlog with points. Just enough to solve the problem at hand.</p>
<p>Given how the project went, you can have exactly one guess whether
that seed grew.</p>
TDD in context #5: Fail-safehttps://schmonz.com/2015/05/13/tdd-in-context-5-fail-safe/Amitai Schlair2016-11-12T01:39:43Z2015-05-13T04:00:00Z
<h2>Previously</h2>
<p>This is the fifth in a series about TDD’s value to humans, following</p>
<ol>
<li><a href="https://schmonz.com/2014/06/01/tdd-in-context-1-keeping-my-job/">Keeping my job</a>,
in which I lost my manager’s trust,</li>
<li><a href="https://schmonz.com/2015/04/15/tdd-in-context-2-a-last-minute-feature/">A last-minute
feature</a>, in
which I regained some,</li>
<li><a href="https://schmonz.com/2015/04/22/tdd-in-context-3-deadline-pressure/">Deadline pressure</a>,
in which I earned quite a bit more than I’d started with, and</li>
<li><a href="https://schmonz.com/2015/05/06/tdd-in-context-4-continual-delivery/">Continual delivery</a>,
in which the circle of trust grew to include our Operations team</li>
</ol>
<h2>More value, less risk</h2>
<p>The discipline of Test-Driven Development let us share the reasons
for our confidence in our code with Operations. Their confidence
afforded us the option of the discipline of frequent, regular
releases, which we immediately exercised to deliver working, valuable
code into production every month. In so doing, we were taking aim
at two main goals:</p>
<ol>
<li>Minimize delay in delivering features to customers</li>
<li>Control operational risk by shipping in smaller increments</li>
</ol>
<p>Smaller increments meant we were always deploying soon, so we’d try
a little harder to make deploying safe. It meant that by release
time we could still mostly remember the implications of our
recent-enough changes. It meant that the aspects of release procedure
that were too expensive to automate (or exhaustively document) were
somewhat fresh in Operations’ and our minds. It meant that in case
of trouble, we wouldn’t have to worry about un-delivering a pile
of new features customers had long been waiting for: we could just
roll back, figure out what we missed, and deliver again soon.</p>
<h2>Just once</h2>
<p>The rollback option was mostly hypothetical, because we could almost
always get confident about how our code would behave in production.
But for one release, we had no way to test well enough to get that
confidence. So instead we thoroughly tested the rollback procedure,
highlighted the more-likely-than-usual risk that we’d need to
exercise it, and deployed. When the service became heavily degraded,
and it was clear we needed to roll back, it wasn’t difficult and
nobody was surprised.</p>
<h2>Inconclusion</h2>
<p>Our track record, all told: one safely failed monthly deployment,
dozens of safe successes. What about that one failure, though? How
could we, with all our discipline, ever have wound up running
production code we couldn’t confidently change?</p>
TDD in context #4: Continual deliveryhttps://schmonz.com/2015/05/06/tdd-in-context-4-continual-delivery/Amitai Schlair2016-11-12T01:39:43Z2015-05-06T04:00:00Z
<h2>Previously</h2>
<p>This is the fourth in a series about TDD’s value to humans, following</p>
<ol>
<li><a href="https://schmonz.com/2014/06/01/tdd-in-context-1-keeping-my-job/">Keeping my job</a>,
in which I lost my manager’s trust,</li>
<li><a href="https://schmonz.com/2015/04/15/tdd-in-context-2-a-last-minute-feature/">A last-minute
feature</a>, in
which I regained some, and</li>
<li><a href="https://schmonz.com/2015/04/22/tdd-in-context-3-deadline-pressure/">Deadline pressure</a>,
in which I earned quite a bit more than I’d started with</li>
</ol>
<h2>Same idea, next level up</h2>
<p>As a developer, I’d significantly reduced the waste and risk in my
work by incrementally bringing our legacy code under test while
test-driving new features (and bug fixes). As a newly minted product
manager with a small budget and high customer expectations, if I
wanted to maximize my tiny team’s business impact, I needed to find
our next big waste-and-risk targets and bring them down.</p>
<p>Conveniently, they were the same target. We’d been releasing into
production roughly every 3-6 months. That meant waste: customers
had to wait a long time to get any value from our work. And it
meant risk: we had to worry about a whole lot of
haven’t-thought-about-those-in-a-while changes going into production
all at once.</p>
<h2>Doctor, it hurts when I do this</h2>
<p>How had we settled on this release (in)frequency? Because originally,
deciding when to release hadn’t been easy. On our end, having had
no immediate feedback about the state of our code, we lacked ongoing
confidence in it, so we had to steel ourselves and others for any
change, so we released only when someone wanted the desired value
badly enough. (Thereby perpetuating the cycle? Naturally.) On
Operations’ end, supporting many products, their job was to review
all proposed changes to production and reject unsafe ones, and
they’d learned to treat even safe-looking changes as unsafe until
proven otherwise. They’d set the bar high, with good reason.</p>
<h2>If it hurts, do it more often</h2>
<p>But by giving ourselves an immediate feedback mechanism, our part
of the decision had become easy. As far as we were concerned, the
meaningful and thorough automated tests we’d built put us well over
that bar. At each desired release, our thousands of green tests
(and zero red ones) covered not only the new functionality but also
everything that had ever been tested before. Which, by now, was
rather a lot. Of course we were confident to ship. Therefore, in
the interest of minimizing branch-management effort, lead time,
and release-process forgetfulness, we asked Operations for special
permission not to have to freeze our code a week in advance, but
to ship everything that had been done up to and including release
day. Releases were on Friday evenings, and Ops needed a few hours
to prep what we gave them, so that meant we had till early afternoon
to get in whatever we could get in. (Given the time constraint,
not a good day to do something complex or risky, but perfectly fine
to try to squeeze in something simple and valuable.)</p>
<p>Operations saw that we were confident, and they saw our test results,
and they were tentatively approving our non-standard releases —
until one release day, after a teammate had pulled an all-nighter
to get one last piece in, when Ops decided at the last minute that
the release was no longer acceptable. Not because of anything my
teammate had or hadn’t done, but because I hadn’t added a couple
lines of documentation about something minor to the Ops wiki in
advance of the release procedure. I’d been planning to make those
tiny edits during the several Friday-evening hours I’d be on the
phone with Ops alternately guiding them through the release and
idle-waiting for the next step in our procedure.</p>
<h2>If it hurts a lot, maybe take a step back</h2>
<p>There would’ve been plenty of time. But they chose to cancel the
release. As was their right. Mine, in turn, was to react by huffing
and puffing about the spurious reasoning for the last-minute change
of plan and the evident disrespect for my teammate’s effort.
Predictable lot of good that did!</p>
<p>When I’d gotten that out of my system at everyone else’s expense,
I had the whole weekend to think quietly about my actions before,
during, and after, and about why Operations might have felt the
need to choose as they did. They did not, by default, trust
engineering teams to deliver with safety. They could not. It was
their job to be skeptical, and on the rare occasions they hadn’t
been sufficiently so, they’d been hurt. And here I was asking them
to <a href="https://agilein3minut.es/3">trust</a> us not only to deliver
with safety, but to let us skip a very visible part of the review
process. I was asking them to let us deliver whatever we — not
they — decided was ready, right up to the last minute, but I hadn’t
shown them why they ought to, certainly not in terms that made
sense to them. So they were likely inclined to feel that I was
asking them to be negligent in their roles, and they were likely
inclined to perceive any small failing of documentation as a red
flag indicating sloppiness elsewhere. Now that I saw where they
might be coming from, I couldn’t blame them. I wouldn’t have wanted
to be negligent either.</p>
<h2>Working together for shared understanding</h2>
<p>Because I had <a href="https://agilein3minut.es/2">retrospected</a>, by the
time we got together to discuss what had happened, I knew what I
wanted to try. I apologized for my outburst and asked Luke, the
Operations manager, if he’d be willing to pair with me to develop
a new feature sometime. To my relief, and his great credit, he
agreed.</p>
<p>It wasn’t long before we had our chance. Not unlike in <a href="https://schmonz.com/2015/04/15/tdd-in-context-2-a-last-minute-feature/">A last-minute
feature</a>, a
small feature request came in on a Wednesday, hoping to be delivered
as part of the release scheduled for that Friday. For any other
Engineering team, the rule about freezing a week in advance would
have made this a non-starter. But this was exactly the kind of
(apparently somewhat common) situation we wanted to handle with
agility. And it was a small, simple set of new behaviors, perfect
for pairing with someone who didn’t know our code but knew our
system very well.</p>
<p>Luke and I got together Thursday in a conference room. I had set
him up with access to our source code repositories and we started
by running the tests. We broke something obvious and saw that some
tests went red. Then we reverted to green and talked through what
the new feature would look like when it was working right. When
we had a shared understanding, I talked him through writing the
equivalent test assertions. He ran them; red as expected. I talked
him through how to change the code. He ran the new tests again;
green as expected.</p>
<p>”That’s the whole feature. Cool, right?” I asked.</p>
<p>”Yeah, sure, kinda,” Luke allowed.</p>
<h2>An unexpected twist</h2>
<p>”Okay, before you check it in, let’s run the whole test suite.”</p>
<p>Whoa. Some other tests, seemingly unrelated, were now red. Hadn’t
seen that coming. A smile came over Luke’s face. ”<em>Now</em> I get it,”
he said. “This problem can never happen in production. We found
the problem before we ever checked it in.” Exactly! Same for
everything else we’ve got tests for. (And, boy howdy, have we got
a lot of tests.)</p>
<p>After quickly fixing the fallout, Luke committed his new feature.
It went into production on the following evening.</p>
<h2>Conclusion</h2>
<p>For as long as Luke was in that role, we had no further difficulty
delivering just-in-time releases. And because we knew the sailing
would be smooth, we began releasing once a month, wasting less and
risking less — just as I’d hoped. More often was too often (busy
work, lost Friday nights); less often wasn’t often enough (Eng and
Ops both out of practice at release procedure); once a month was
just right.</p>
<p>While <em>continuous</em> delivery was prohibitively difficult in our
tightly controlled environment, we managed to achieve <em>continual</em>
delivery on a cadence that met everyone’s needs. For Operations,
we controlled the inherent risk of change by doing it in smaller
batches, giving us less to roll back and binary-search through in
case of trouble. For customers, we could honestly offer the
possibility of helping them as soon as next month, limited only by
our own constraints (priorities, WIP, nature of the request). And
for ourselves, since we’d always be delivering to production soon,
we could see more clearly the value and relevance of our work, and
hope for more meaningful customer feedback about it.</p>
<p>TDD gave me an opening. Luke’s willingness and ability to collaborate
(and to forgive my outburst) allowed us to walk through it together,
making a sizable impact on the business we both served — and on
me.</p>
Signal and statichttps://schmonz.com/2015/04/29/signal-and-static/Amitai Schlair2019-05-27T04:16:25Z2015-11-03T00:55:55Z
<h2>Do you write on your own site?</h2>
<p>Are you involved in software development in any way? Are you already
publishing your writing on a website you control? Me too. This post
is based on my personal experience writing on this site (and
administering it) since 1999. The word “blog” was apparently coined
around the same time, but I hadn’t heard of it yet. I was calling
this thing here an “online journal.” Quaint.</p>
<h2>How’s that working for you?</h2>
<p>When you’ve written a new piece, how do you publish it? Maybe by
clicking a “Publish” button in the admin interface of the production
instance of your CMS?</p>
<p>When you’ve written a final draft, how do you preview it? Do you
have a non-production instance of your CMS? Probably not. Maybe you
click “Publish” in a different mode that tries to avoid making the
post visible, or maybe you edit in a WYSIWYG control that tries to
render almost (but not exactly) the same as publishing would?</p>
<p>When you’ve written a first draft, how do you edit it? How do you
see what you changed from one draft to the next? If you try some
new wording, click “Save”, and decide it isn’t better, how do you
go back? <em>Can</em> you go back?</p>
<p>When your network connection drops or your browser crashes, do you
lose your writing in progress? Has either of these happened to you
yet? How do you imagine you’ll feel when they do?</p>
<p>When your CMS frequently has security holes (such as <a href="https://wordpress.org/news/2015/04/wordpress-4-2-1/">WordPress has
just had, again</a>),
how large is the attack surface? How easy is it apply the latest
patch? How often is it necessary to patch the latest bug? Until
you patch, how much of your work might you lose?</p>
<p>Even if your CMS doesn’t have security holes <em>frequently</em>, how
recently have you made an offline backup? How recently have you
test-restored from it? Are both steps easy to perform, or are they
extracurricular activities you might skip?</p>
<blockquote><p>”If you don’t test restores from your backups, you do not have
backups.”
—<a href="https://twitter.com/garybernhardt/status/493483356294635520">@garybernhardt</a></p></blockquote>
<p>Do you feel safe about the continued existence of the words you’ve
worked so hard to write? I ask because of how I felt when I was
still <a href="https://schmonz.com/2013/05/27/remembering-textpattern/">running a traditional dynamic
CMS</a>.</p>
<h2>Another approach</h2>
<p>To have more satisfying answers to some of these questions, one
idea is <a href="http://idlewords.com">Maciej Cegłowski</a>’s: run your CMS
on a non-public address, <a href="http://idlewords.com/2009/09/using_wordpress_to_generate_flat_files.htm">crawl it to create a static
cache</a>,
and <a href="http://idlewords.com/2009/09/how_to_not_get_your_blog_hacked.htm">publish the
cache</a>.
But this is hacky. It complicates publishing, generates some broken
internal links (at least on Maciej’s own site), and doesn’t solve
versioning or backups — which is to say, restores.</p>
<p>Since static content is such a good idea, surely there must be CMSes
designed to generate it? Two popular choices, Jekyll and its cousin
Octopress, are topics of this weekend’s
<a href="http://jekyllconf.com/">JekyllConf</a>. Static site generators typically
take away the heavyweight database and the entire dynamic-web-app
attack surface, in exchange for which they give you the safety of
writing offline, the power of revision control, and the ease of
<code>git push</code> to publish. If you value those things, an SSG is a
bargain. But in that bargain you’re also necessarily giving up a
web admin interface, a searchable local index, and reader comments
being stored somewhere you control.</p>
<p>That’s why I prefer a CMS that’s <em>mostly</em> a static site generator.
Most of my sites don’t enable the web admin interface, but many of
them are searchable, and this one allows comments. If you like any
of the following neat shell tricks I can do now that I’ve <a href="https://schmonz.com/2015/01/01/happy-new-year/">switched
<code>schmonz.com</code> to ikiwiki</a>, feel free to
comment. It’ll turn into a <code>git commit</code>, of course; next time I
<code>git pull</code> I’ll have a local backup; and I’m sure I’ll make that
backup, because I won’t be able to <code>git push</code> another post until I
do. ;-)</p>
<h2>Neat ikiwiki tricks</h2>
<p>Naturally, these can be encapsulated in shell functions or small
standalone scripts.</p>
<h3>List drafts committed after the ‘textpattern’ tag</h3>
<div class="highlight-sh"><pre class="hl">$ git <span class="hl kwc">diff</span> <span class="hl kwb">--stat</span> textpattern unpublished <span class="hl opt">|</span> <span class="hl kwc">awk</span> <span class="hl sng">'{print</span> <span class="hl ipl">$1</span><span class="hl sng">}'</span> <span class="hl opt">|</span> <span class="hl kwc">grep</span> <span class="hl sng">'\.md'</span>
</pre></div>
<h3>Write a new post with my permalink style</h3>
<div class="highlight-sh"><pre class="hl">$ _TODAY<span class="hl opt">=</span><span class="hl kwd">$(date '+%Y/%m/%d')</span> <span class="hl opt">&&</span> <span class="hl kwc">mkdir</span> <span class="hl kwb">-p</span> <span class="hl kwd">${_TODAY}</span> <span class="hl opt">&&</span> vi <span class="hl kwd">${_TODAY}</span><span class="hl opt">/</span>post<span class="hl kwb">-name</span>.md
</pre></div>
<h3>Write a new comment offline, using <code>$EDITOR</code></h3>
<div class="highlight-sh"><pre class="hl">$ ikiwiki<span class="hl kwb">-comment</span> <span class="hl kwd">${_TODAY}</span><span class="hl opt">/</span>post<span class="hl kwb">-name</span>.md
</pre></div>
<h3>List the most recent 12 posts</h3>
<div class="highlight-sh"><pre class="hl">$ <span class="hl kwc">find</span> . <span class="hl kwb">-type</span> f <span class="hl kwb">-name</span> <span class="hl sng">'*.md'</span> <span class="hl opt">|</span> <span class="hl kwc">egrep</span> <span class="hl sng">'^\./[0-9]+\/'</span> <span class="hl opt">|</span> <span class="hl kwc">sort</span> <span class="hl kwb">-rn</span> <span class="hl opt">|</span> <span class="hl kwc">head</span> <span class="hl kwb">-12</span>
</pre></div>
<h3>List the most recent 12 comments on any posts</h3>
<div class="highlight-sh"><pre class="hl">$ <span class="hl kwc">find</span> . <span class="hl kwb">-type</span> f <span class="hl kwb">-name</span> <span class="hl sng">'*._comment'</span> <span class="hl opt">|</span> <span class="hl kwc">xargs</span> stat <span class="hl kwb">-f</span> <span class="hl sng">'%Y%m%d %N'</span> <span class="hl opt">|</span> <span class="hl kwc">sort</span> <span class="hl kwb">-rn</span> <span class="hl opt">|</span> <span class="hl kwc">head</span> <span class="hl kwb">-12</span> <span class="hl opt">|</span> <span class="hl kwc">awk</span> <span class="hl sng">'{print</span> <span class="hl ipl">$2</span><span class="hl sng">}'</span>
</pre></div>
<h3>List all the comments on a given post</h3>
<div class="highlight-sh"><pre class="hl">$ <span class="hl kwc">find</span> <span class="hl kwd">${_TODAY}</span> <span class="hl kwb">-name</span> <span class="hl sng">'*._comment'</span> <span class="hl opt">|</span> <span class="hl kwc">sort</span> <span class="hl kwb">-rn</span>
</pre></div>
<h3>List all posts containing podcast-style enclosures</h3>
<div class="highlight-sh"><pre class="hl">$ <span class="hl kwc">find</span> . <span class="hl kwb">-type</span> f <span class="hl opt">|</span> <span class="hl kwc">xargs grep</span> <span class="hl kwb">-l</span> <span class="hl sng">'meta enclosure='</span> <span class="hl opt">|</span> <span class="hl kwc">sort</span> <span class="hl kwb">-rn</span>
</pre></div>
<h2>More possibilities</h2>
<ul>
<li>List posts which have been edited since being posted, and show the changes</li>
<li>Replace all occurrences in all files of <code>XXX</code> with <code>YYY</code>, review
the changes, commit, be able to revert if needed (I’ve done a few of these)</li>
<li>Your ideas?</li>
</ul>
TDD in context #3: Deadline pressurehttps://schmonz.com/2015/04/22/tdd-in-context-3-deadline-pressure/Amitai Schlair2016-11-12T01:39:43Z2015-04-22T04:00:00Z
<h2>Previously</h2>
<p>This is the third in a series about TDD’s value to humans, following</p>
<ol>
<li><a href="https://schmonz.com/2014/06/01/tdd-in-context-1-keeping-my-job/">Keeping my job</a>,
in which I lost my manager’s trust, and</li>
<li><a href="https://schmonz.com/2015/04/15/tdd-in-context-2-a-last-minute-feature/">A last-minute
feature</a>, in
which I regained some</li>
</ol>
<h2>Learning the domain</h2>
<p>The software I was hired to develop acted as user-facing glue to
several non-user-facing infrastructural systems in a highly complex
environment. On arrival, I didn’t see the whole picture, and knew
I couldn’t understand the implications of changing any given bit
of code. Whether or not I tried to consider the systems outside
ours, I didn’t understand what our software was aiming to do. The
Unix command-line tool’s “create” subcommand would have made sense,
except that there was also an “insert” which was slightly different.
I thought I grokked “update” until I noticed other subcommands for
specific kinds of updates. And I was about to believe I had a handle
on “assert” when I discovered that “accuse” was a way to speed it
up. Yikes!</p>
<h2>To (be able to) go fast, (be able to) go well</h2>
<p>Making things worse, the code I and my lone teammate had inherited
was freshly minted legacy code. If we’d been instructed to go fast,
we’d have made dangerous mistakes, and we still wouldn’t be going
anywhere near fast enough to make those mistakes tolerable. If we’d
been instructed to go safely, we wouldn’t have been able to deliver
much, plus some dangerous mistakes would still have slipped through.
If we wanted to move quickly and safely, we needed to make a concerted
effort to change the properties of our code. In <a href="https://schmonz.com/2015/04/15/tdd-in-context-2-a-last-minute-feature/">A last-minute
feature</a>, we
did, and it began to pay off.</p>
<h2>Now please go fast</h2>
<p>The big refactoring-etc. in that post had been driven in part by
the anticipated business need for a graphical UI for non-Unix users,
which in turn derived from the demonstrated business need to manage
identities for non-Unix platforms in the same way our successful
proof of concept was managing them for Unix. For reasons I may never
have been privy to, and certainly don’t remember, the need to manage
mainframe identities congealed into a hard deadline.</p>
<p>We had 1.5 weeks.</p>
<p>The code was built on Unix- and Kerberos-specific assumptions
scattered throughout — some of them hard-coded, some of them
invisible, and as yet relatively few of them documented by any kind
of automated tests. Discovering and reacting to all those assumptions
by building support for our first additional platform, while having
it be an unfamiliar platform with its own weird yet-to-be-discovered
rules, appeared rather unlikely to be doable at all, and exceedingly
unlikely to be doable safely.</p>
<h2>And don’t screw up</h2>
<p>But maybe. And we had to try. So I notified my teammate and our
manager that in order to avoid office distractions and enable
strategic napping, I’d be working from home, around the clock, until
stated otherwise. At midnight, I emailed them a summary of the day’s
progress and my tasks for the following day that, if completed,
would prevent the deadline from becoming obviously un-meetable. Any
given day, things might not have gone according to plan, and that
would’ve been the end of that; but every night, I kept being able
to report that they had, and here’s what has to happen tomorrow to
keep the string going. A week later, with a couple days to go, we
were still — against all reasonable expectation for a schedule
with zero slack — on track.</p>
<p>The next day, I went into the office to knowledge-share with my
teammate, who had researched the important platform-specific behavior
we’d need to implement. I took my understanding, turned it into
unit tests, and asked Robert (as I’d asked Bill about that last-minute
feature) to validate that they were testing for the desired behavior
and only the desired behavior. He caught and fixed a few mistakes
in the assertions. Then I went off and made the tests pass.</p>
<h2>What size shoe, and when?</h2>
<p>That night, our release scheduled for the following evening, I slept
deeply. We’d done everything in our power. We would go into production
with a credible effort that might prove good enough. Even so, I was
worried that it might not. I knew many of my refactorings had
outstripped our still limited test coverage, for which I attempted
to compensate by carefully making one small mechanical change at a
time, reasoning about what to manually check, and doing lots of
manual checking. I was pretty sure the system as a whole wasn’t
fundamentally broken, but I was also pretty sure it wouldn’t be
thoroughly fine. When we got to production, there was no question
whether the other shoe would drop. We hadn’t worked with sufficient
discipline to avoid it.</p>
<h2>A small shoe, immediately</h2>
<p>During the course of the Operations team’s usual post-release system
checks, they found a big regression: one of my less rigorous
refactorings had broken a common usage in an important third-party
client I’d forgotten to check. I immediately recalled a smell I’d
ignored while doing that refactoring and knew an expedient way to
fix the problem. A half hour later, our updated release indeed fixed
the regression, and I’d made myself a note to add a few integration
tests with that client.</p>
<h2>A big shoe, later</h2>
<p>I felt certain we hadn’t seen the last of the fallout. Some months
later it hit us. I don’t remember how we found it, but there was
one remaining invisible assumption in the code that hadn’t been
flushed out and fixed, and it was a potentially very bad one: a SQL
<code>DELETE</code> statement with an insufficiently constraining <code>WHERE</code>
clause. Not only had we forced Ops to scour several months of
application logs and database backups for signs of wrongly deleted
data, but also we’d forced the business to operate for several
months unknowingly without the data integrity they were relying on.
Against all reasonable expectation, again, the damage was very low.</p>
<h2>Conclusion</h2>
<p>It proved to have been crucial that, by the time this deadline
popped up, we’d already greatly improved the health of our code and
the extent of our tests and knowledge. If either had been any worse,
we’d have missed the deadline, made more costly mistakes, or both.
Instead I was able to test-drive sometimes, manually test fairly
effectively, and tolerate — as a time-boxed exception — working
mostly alone at an unsustainable pace with an unsustainable lack
of discipline. And because we had made ourselves able to do those
things, we delivered what we understood the business to need, when
they needed it.</p>
<p>But only because we lucked out. The unseen, unmanaged risk we
incurred by working in this way, even for a short time, could have
come back to bite us much harder than it did; since it happened not
to, I earned more trust. When I was given responsibility for managing
the product half a year later, I was told that this particular
outcome had been the one that sealed the deal. In other words, the
career opportunity to learn about software product development from
an entirely different perspective came as a direct result of having
chosen to pursue TDD. And when I landed in that role, I looked for
ways to manage risk without having to be so lucky.</p>
<p>Test-driven ways.</p>
TDD in context #2: A last-minute featurehttps://schmonz.com/2015/04/15/tdd-in-context-2-a-last-minute-feature/Amitai Schlair2016-11-12T01:39:43Z2015-04-15T04:00:00Z
<p>In <a href="https://schmonz.com/2014/06/01/tdd-in-context-1-keeping-my-job/">TDD in context #1: Keeping my
job</a>, I…</p>
<ul>
<li>Started a job as a software developer after 5+ years away from
programming</li>
<li>Implemented my first simple new feature in an unfamiliar domain
and a legacy codebase</li>
<li>Passed code review by one of the software’s original authors</li>
<li>Delivered to production, only to discover (in the form of user
complaints) that I’d caused several regressions</li>
<li>Scrambled to fix my dumb mistakes, while suddenly and vividly
recalling the value of Test-Driven Development</li>
<li>Obtained management permission to test-drive from then on</li>
</ul>
<h2>Getting to testability</h2>
<p>There were a couple very basic end-to-end tests to show that the
server could handle concurrent write requests without obviously
always corrupting the database. But to avoid the screwup I’d just
upscrewed, I’d have needed unit tests around the code I changed.
Since they didn’t already exist, I’d have needed to write them;
since that was too hard, I needed to make it easier somehow.</p>
<p>Working against me were my ignorance of the problem domain, my
inexperience with rescuing legacy code, my lack of recent practice
at programming in general and Perl in particular, my limited grasp
of the full complexity of the environment, and the fact that this
application had come to life as a hack-weekend proof-of-concept —
one that had so convincingly succeeded that they hired a dedicated
full-time developer (<em>moi</em>) to maintain and extend it.</p>
<p>Working in my favor were the existence of a couple of in-house (now
<a href="http://oskt.secure-endpoints.com/knc.html">open</a>
<a href="http://oskt.secure-endpoints.com/kharon.html">source</a>) tools that
provided network transport and authentication entirely outside our
server daemon’s process space, the imminent in-house release of a
major upgrade to the protocol library that promised to obviate the
need for marshal-and-unmarshal concern-mixing boilerplate in
applications, and the ready availability of the two in-house
developers who’d built those tools and my application.</p>
<p>Tipping the balance further in my favor was that, arguably, doing
that protocol library upgrade would help us meet a business need.
A Unix command-line client had been part of the proof-of-concept
code, but a web-based GUI for users from other platforms was
inevitable. Before we’d build and maintain a second client, though,
we wanted a dead simple client API. The protocol library upgrade
would solve that problem too.</p>
<p>Sealing the deal, one of the in-house developers was my manager.
Bill well understood the reasoning, agreed with it, and arranged
for us to have plenty of slack in the schedule for “the SSP 2 port.”</p>
<p>After a month or two of careful, incremental changes with help and
supervision from the local experts, we had less code, better
structure, a vastly simpler client API, decent confidence that we
hadn’t otherwise changed any behavior, and a handful of fast new
functional tests that helped me understand common workflows through
the system. We ran the new service alongside the old until we’d
found and ported all the other clients in the wild to our new API,
then retired the old service. The SSP 2 port was complete. But so
what?</p>
<h2>Getting under test</h2>
<p>Now that we had the beginnings of a test suite, for each new feature,
I knew what to do: TDD with one extra step. Before writing a new
red test, I checked whether any tests covered the current behavior
in the area of code I was likely to change. Almost always the answer
was “no”, so I’d dig around until I understood enough to add some
tests. Only then would I add a red test. (Or, sometimes, take one
of the tests I’d just added and change its assertion.)</p>
<p>After about half a year, I noticed that the answer was almost always
“yes”. We’d arrived at TDD as usual. I felt good about that. But
so what?</p>
<h2>Dubious business value</h2>
<p>Just before a release, a strange feature request came down out of
nowhere. It wasn’t a request at all, as we found out when we tried
and failed to refuse it on the basis that it wouldn’t actually solve
the stated problem (along with having lots of unspecified corner
cases). So on release-day morning, Bill apologetically asked if
there were any way we could implement the feature before cutting
the release.</p>
<p>We had good test coverage around that area of the code, so I said
“Yeah, I think so. I’ll write a spec covering all the corner cases
I can think of. Come back in an hour and half ready to review it.”
He read thoughtfully through the new tests and agreed: “I think
this feature is dumb, but if we have to do it, then this is how it
has to work.”</p>
<p>45 minutes later I had the new tests passing, the rest of the suite
still green, the dumb feature committed to source control, and the
release ready to deploy.</p>
<h2>Genuine business value</h2>
<p>We were right to feel skeptical about the feature: it never did
solve the stated problem. A few years later, we removed it.</p>
<p>I was right to feel confident about having arrived at TDD as usual:
it improved our internal collaboration, helped us arrive at early
and precise agreement, and allowed us to move quickly and safely
— not just for this silly feature, but for dozens of far more
valuable ones.</p>
<p>And Bill was right to have told me to do my work however I saw fit.
I vividly recall what he said when we shipped that feature:</p>
<blockquote><p>”I may not have the discipline to write tests first, but I sure
am glad you do.”</p></blockquote>
<p>Me too.</p>
How to develop humanshttps://schmonz.com/2015/04/08/how-to-develop-humans/Amitai Schlair2016-11-12T01:39:43Z2016-02-12T06:24:48Z
<p>I envision my day job (<a href="https://schmonz.com/coach/">software development coaching</a>)
being rather akin to parenting. If that sounds paternalistic and
creepy, consider firstly my complete lack of personal experience
with parenting, and secondly my mental model of what raising children
is like. My model says, <strong>given</strong> that humans…</p>
<ul>
<li>Are independent and individual</li>
<li>Are always in development</li>
<li>Are always influenced by our environments and experiences</li>
<li>Exert some influence over our immediate environments and experiences,
and those of perhaps a few others</li>
</ul>
<p>…<strong>then</strong> we’ll know we’ve succeeded as parents <strong>when</strong> one more
human responsibly owns and directs their own continued development.
If that’s what success looks like, then we’d want to act every day
as the temporary, partial, and grudging guardians we seem to be,
and seek every day to direct our love so as to <a href="https://schmonz.com/2015/03/13/when-is-being-technical-lead-a-good-decision/">hasten our
abdication</a>.</p>
<p>My mental model of parenting, untested though it may be, says
“raising children” is an inapposite way to describe the goal of
aiding in the development of adult humans. (In my darker moments,
the common wording — along with “having a baby” — does nothing
to dispel my suspicion that many parents aren’t interested in raising
adult humans.) But this post is less about parenting and more about
informal aunting and uncling: about what we can be doing, as <a href="http://ddaugher.github.io">a
colleague who’s already doing it</a> asked,
to “involve the next generation of young minds.”</p>
<h2>They’re already involved</h2>
<p>According to my parenting model, combined with a pretty simple
interpretation of observed behavior throughout human history, we
could stick with parenting our own kids if any, letting others
parent their own kids if any, and <a href="http://www.merlinmann.com/roderick/ep-36-uncle-licky.html">getting what we
get</a>.
Given the importance of parenting to human development, any additional
effort might be lost in the noise.</p>
<h2>Help children play at their enthusiasms</h2>
<p>It seems more likely to me that any additional effort could produce
exponential benefit. For instance, standardized schooling as commonly
implemented can be notoriously stultifying. Imagine attending your
neighborhood public school’s PTA meeting and volunteering to supervise
an age-appropriate “maker space” every other week. How likely is
it that they’d accept? What kind of impact might you have on the
lives of a few children? What kind of second-order impact could
that have on all of us?</p>
<p>If you’re finding opportunities to interact with young minds, take
your opportunities to provide options that might interest them.
Help them <a href="http://www.kalamazoox.org">see all that is possible</a>.
Help them <a href="http://bangbangcon.com">experience the enthusiasm of others</a>.
If you have an opinion about the apparent talent of a youngster,
be a grownup and <a href="http://nymag.com/news/features/27840/">do whatever it takes to keep it to
yourself</a>. For humans of any
age, do not…</p>
<ul>
<li>Steer them toward what you think they should want</li>
<li>Manufacture enthusiasm on their behalf</li>
</ul>
<p>…but especially for kids, who have less practice detecting and
deflecting sociopathic behavior.</p>
<p>Humans have their own enthusiasms. Help them find theirs. If you
must tell a kid what you think about their activity, tell them how
interested they appear to be, or how much fun they appear to be
having. If they agree, you’re being helpful so far; find more options
along that path to show them. If they don’t agree, you can be helpful
by showing them options along some other path. We don’t need humans
forcibly arranged into the fields we wish they were in (e.g., more
<a href="https://modelviewculture.com/pieces/i-didn-t-want-to-lean-out">women in STEM
fields</a>). We
need humans who <a href="https://schmonz.com/2005/06/21/history-of-my-world-part-i/">maintain their capacity for enthusiasm into
adulthood</a>, and who have
seen and followed ways to turn their enthusiasm into expertise.</p>
<h2>Help yourself play at your enthusiasms</h2>
<p>If you don’t get to interact with young minds, maybe it’d be good
for <em>you</em>. What’s the last wacky new thing you tried?</p>
<h2>Help grownups put their enthusiasm to work</h2>
<p>Until recently, I’d only ever worked at jobs where I wasn’t sure
their values matched mine — or where I was sure they didn’t. I’ve
finally found a place where I’m sure they do, where the enthusiasm
I’ve managed to retain <a href="https://schmonz.com/2014/03/27/how-to-develop-software/">about software
development</a> is reflected and
magnified by the kind and capable folks around me. I’m no more
deserving of this sort of work-joy than anyone else. I simply had
enough advantages in life to be able to keep holding on and hoping.
How many people are forced to learn quickly what I managed to refuse
to believe? How many are forced to grin and bear it because “Hey,
that’s why they call it ‘work’”? How can we grasp the enormity of
what is lost when we take intelligent, self-directed, <a href="http://decisionmakerbook.com">decision-making
adults</a> and consign them to an
infantilized workaday fate?</p>
<p>If you’re part of systems that influence the development of humans
— and as a human, you are unavoidably so — you have some degree
of influence over those systems. You can find ways to make them
more beneficial, or at least less harmful. Where your influence
stops — and as a human, it is unavoidably finite — you can find
alternatives to offer. And if you have, against all odds, preserved
and nurtured any form of enthusiasm in yourself, then you are
uniquely positioned to preserve and nurture it in others.</p>
<p>Imagine taking advantage of your position to create a workplace
where your favorite enthusiasms are cherished. What kind of impact
might you have on the lives of a few grownups? What kind of
second-order impact could that have on all of us?</p>
<p>I couldn’t begin to tell you. But I’ve been given such a gift. I
hope I’ve begun to convey how it feels to have received it. May I
pass it on.</p>
To scale Agile, delegate riskhttps://schmonz.com/2015/04/01/to-scale-agile-delegate-risk/Amitai Schlair2016-11-12T01:39:43Z2015-11-03T00:55:55Z
<p>The following idea popped into my head after discussions
<a href="http://www.daedtech.com/blog">with</a> <a href="http://ironmoose.blogspot.com">some</a>
<a href="http://agileshrugged.com">colleagues</a>. They bear no responsibility
for it. If it’s a bad idea, neither do I. <img src="https://schmonz.com/smileys/smile4.png" alt=";-)" /></p>
<h2>The problem</h2>
<p>It’s hard enough to reach full-throttle agility in a small software
company with a single development team. Large organizations make
it much harder, because they tend to:</p>
<ul>
<li>Require coordinating across teams</li>
<li>Require convincing more people</li>
<li>Incentivize counterproductive behavior (albeit unintentionally)</li>
<li>Organize around components and projects (not products)</li>
<li>Treat IT as a cost center (not a value provider)</li>
<li>Specialize in something other than software development</li>
<li>Control decision-making</li>
</ul>
<p>Agility can only happen if the team is empowered to make decisions
for themselves and their product. Big companies are afraid to unleash
that power because they have much longer risk tails and are much
fatter lawsuit targets; not only could one wrong move be extremely
costly, but also wrong moves are extremely easy to make. Out of
justifiable fear, then, big companies tend to prioritize risk
reduction over nearly everything else, up to and including the
appearance of common sense.</p>
<p>The priorities of a company — particularly the mistakes it wants
to avoid — tend to become policies. The priorities of a self-organizing
team may not always coincide with company policy. The more policies
exist, the more likely a self-organizing team finds itself forced
to decide whether to ignore or fight. If they’re lucky, maybe they’ll
be granted blanket exceptions for particular policies.</p>
<p>Best-case scenario: given a relatively enlightened large organization,
a team can perhaps hope that someday, relatively few of their
decisions won’t be theirs to make.</p>
<p>Wait, that’s the <em>best</em>-case scenario?</p>
<h2>The idea</h2>
<p>If big organizations truly want the benefits of Agile, they need
to provide the preconditions for Agile. But they don’t believe they
can vest full decision-making power in product teams, because they’re
afraid that one sufficiently bad decision could sink the whole
company.</p>
<p>What if it couldn’t?</p>
<p>What if we could limit decision-making <em>liability</em> to the teams,
so that we could safely delegate decision-making <em>authority</em> to the
teams?</p>
<p>Why not spin off every team as its own very small subsidiary company?</p>
<h2>The (presumed) benefits</h2>
<p>Worst-case scenario: a subsidiary team makes a terrible decision,
they lose all their money and/or assets (perhaps as a result of
losing a lawsuit), they lay everyone off and close up shop, and
whatever’s left maybe rolls up to the parent company, which was
never itself at risk.</p>
<p>Best-case scenario: subsidiary teams make their own decisions — who
are our customers? who can be on our team? how does our work work?
which software licenses can we accept? which security tradeoffs are
we comfortable with? etc. — and they’re sensible, effective, and
profitable.</p>
<p>In any case, we might expect to see:</p>
<ul>
<li>Value-delivering teams turning a profit</li>
<li>Underperforming teams netting a loss</li>
<li>Team performance being easier to appraise (and improve)</li>
<li>Annual budgets being simpler to prepare (and adjust)</li>
</ul>
<h2>The drawbacks</h2>
<p>IANAL (I Am Not A Lawyer), and I haven’t tried to search for and
study existing corporate structures that may be similar, but I feel
certain this can’t be an original idea. AYMIAL (Are You Maybe Is A
Lawyer)?</p>
<p>Even if you’re also not a lawyer, do you think this scheme could
possibly work? What might prevent it from working? If it could work,
what might be suboptimal about it?</p>
<p>One possibility: it’s expensive and risky to restructure a large
organization. But for sufficiently large organizations sufficiently
averse to risk, restructuring in this way might well be less expensive
and risky than doing nothing.</p>
<p>Other possibilities?</p>
<h2>The upshot</h2>
<p>If this approach to delegating risk through legal means can work,
then it promises to remove BigCo-induced accidental complexity,
leaving only the essential complexity faced by any self-organizing
team.</p>
<p>Perhaps the most effective way to scale Agile up is to scale risk down.</p>
When is being "technical lead" a good decision?https://schmonz.com/2015/03/13/when-is-being-technical-lead-a-good-decision/Amitai Schlair2016-11-12T01:39:43Z2016-02-12T06:24:48Z
<p>As software developers, “technical lead” sounds like a role we’re
supposed to want. How can we decide whether we should want it? What
exactly is a tech lead, and what does it take to be good at it?</p>
<h3>What isn’t a tech lead?</h3>
<p>We know by <a href="https://schmonz.com/2007/05/14/schmonzs-theorem/">Schmonz’s Theorem</a> that
there necessarily exist other roles similar to, yet different from,
“tech lead”. By inspection, some such similar roles appear to be:</p>
<ul>
<li>Architect</li>
<li>Developer</li>
<li>Senior developer</li>
<li>System administrator</li>
<li>Line manager</li>
</ul>
<p><strong>Line manager?!?</strong> Sort of. Both line managers and tech leads are
better positioned to make certain types of
<a href="https://schmonz.com/2014/04/01/my-superpower/">decisions</a>.</p>
<p><strong>Sysadmin?</strong> Sort of. Sysadmins and tech leads are better positioned
to understand the costs of technology decisions.</p>
<p><strong>Developer?</strong> For sure. A tech lead who hasn’t been a developer
faces an uphill climb to credibility, even if they somehow manage
to make good decisions.</p>
<p><strong>Senior developer?</strong> Depending on the context-specific meaning of
the title, it could be nearly identical with my conception of a
tech lead, or quite some distance away. In my experience, usually
the latter.</p>
<p><strong>Architect?</strong> Again, depends on the architect and the situation,
but in my experience, it’s difficult for architects to do what tech
leads can do.</p>
<h3>What do tech leads do?</h3>
<p>They help technical decisions get made.</p>
<h3>What do <em>good</em> tech leads do?</h3>
<p>They help good technical decisions get made by the team, consistently,
at every level of the decision tree.</p>
<h3>How do good tech leads do it?</h3>
<p>Their knowledge is wide, such that given any technical problem,
they know enough to guess well about potential solutions. Their
knowledge is a bit deeper in the codebases they live near, so they
don’t have to guess as often. And their desire to see teammates
make informed decisions is wide and deep, such that they can await
the delayed gratification of someone else making the “right” decision,
or even tolerate the discomfort of someone making the “wrong”
decision when it’s not too irreversibly wrong, if that’s what it
takes for them to make a better decision next time.</p>
<h3>What makes a great tech lead?</h3>
<p>A great tech lead has impeccable judgment with which to make every
last technical decision — and instead seeks, above all else, to
share that power with teammates. A great tech lead is one who doesn’t
think of themselves as “leading”, won’t be seen doing any such
thing, and might appear harmless to remove from their team. Don’t
go removing them! But if you do, and it turns out to be harmless,
that might be because they’ve just finished doing a terrific job.</p>
<h3>When is being “technical lead” a good decision?</h3>
<p>When you could be an architect, but are afraid to drift from your
team and your code; when you could be a senior developer, but are
afraid you won’t get to share everything you’ve learned; when you
could be a manager, but are afraid folks won’t get to manage
themselves; when you’ve got the chops to be “technical lead”, but
don’t want anyone thinking of you that way.</p>
<h3>Conclusion</h3>
<p>It’s a tough job. If you do it well, then (just like a sysadmin)
you might not hear appreciation for your work until years later.
Until that day comes, for what it’s worth, you’ve got mine.</p>
Riches of embarrassmenthttps://schmonz.com/2015/03/05/riches-of-embarrassment/Amitai Schlair2016-11-12T01:39:43Z2015-11-03T00:55:55Z
<p>I’ll be presenting <a href="http://selfconference.org/sessions#speaker_29">Bring Your Whole Self To Work (In 15 Years Or
Less)!</a> at
<a href="http://selfconference.org/">Self.conference</a>. Here’s the abstract:</p>
<blockquote><p>A few weeks into my latest gig, it became clear that what folks
needed most from me was to come in every day and be myself. Cool,
I was gonna do that anyway — except at every other job I’ve had,
that’s never totally worked out. What makes me so sure it’s different
this time? What’s changed in this new role? What’s changed about
me, and why, and how?</p>
<p>Come hear a tale full of embarrassments, disappointments, and
learnings, of mild reductions of obliviousness, of gradual improvements
in efficiency, of partially mitigated personal weaknesses, and of
matching who I am to where I belong.</p></blockquote>
<h2>How can I help?</h2>
<p>If our lives have ever crossed paths (in any way, at any time),
tell me the one thing you remember most vividly about our time
together. Maybe something along these lines:</p>
<ul>
<li>What were we trying to do?</li>
<li>What was I struggling with?</li>
<li>What was it like to interact with me?</li>
<li>What was important to me?</li>
<li>What did it seem like maybe I was starting to figure out?</li>
<li>What could you see about me and/or my situation that I wasn’t seeing?</li>
<li>What hilariously dumb thing(s) did I do that everyone who was
there will remember forever?</li>
</ul>
<p>…or anything else that’s coming to mind. Then please yes right
now <strong>email it to me</strong>.</p>
<p>P.S. Even if it’s been a while — <em>especially</em> if it’s been a while
— I’ll be very happy to hear from you.</p>
<p>P.P.S. Even if you’re not entirely sure I’d be happy to hear from
you, I promise you, I will be!</p>
The When-to-Stop Katahttps://schmonz.com/2015/02/25/the-when-to-stop-kata/Amitai Schlair2016-11-12T01:39:43Z2015-02-26T03:51:09Z
<p>I needed some practice with Java and Eclipse, and I love <a href="http://c2.com/cgi/wiki?WorkingEffectivelyWithLegacyCode">untangling legacy code</a>,
so a coworker recommended me the <a href="http://iamnotmyself.com/2011/02/13/refactor-this-the-gilded-rose-kata/">Gilded Rose
Kata</a>.
I used <a href="http://www.lagerweij.com">Wouter Lagerweij</a>’s <a href="https://github.com/wouterla/GildedRose">Java
port</a> as my starting point.</p>
<p>The <a href="https://github.com/wouterla/GildedRose/blob/master/readme.md">kata’s
README</a>
specifies the system’s current behavior, constraints on changing
it, and a desired new behavior. Since the spec wasn’t executable,
I couldn’t trust its accuracy; since no executable spec existed, I
couldn’t verify its accuracy; and since the code was carefully
written to be opaque, I didn’t think it was worth making an effort
to convince myself I understood it. At this point, I knew only two
things:</p>
<ol>
<li>Not going anywhere without some <a href="http://www.daedtech.com/characterization-tests">characterization
tests</a></li>
<li>Disallowing something makes me really, really motivated to carry
out its nearest permissible approximation</li>
</ol>
<p>After writing enough characterization tests to load the domain lingo
into my head and support (mostly) my reading of the spec, I looked
again at the system and at the desired new behavior. Not seeing an
obvious place to put it, I instead took the opportunity — afforded
by my new tests — to perform some obvious refactorings until I
spotted an opening just big enough to test-drive through. And then
I chopped up the concerns scattered throughout the characterization
tests and reconstituted them, filtered through my newfound understanding
of the system, as the one-new-thing-at-a-time unit tests I probably
would’ve written to begin with.</p>
<p>None of this is original or special. Anyone who’s danced with legacy
code knows the ungainly rhythm of this dance. And while Gilded Rose
is a very nicely designed exercise, it doesn’t compare in scope or
risk to a real production system. What might be interesting, since
it was just an exercise, is how I decided when to stop.</p>
<p>Given the <a href="https://github.com/schmonz/JavaKatas/tree/master/GildedRose/schmonz/src">state of my
code</a>,
I don’t love:</p>
<ul>
<li>The stupid not-allowed-to-get-rid-of-or-change-in-any-way <code>Item</code>
class and <code>items</code> property</li>
<li>The <a href="http://c2.com/cgi/wiki?PrimitiveObsession">Primitive Obsession</a> that remains</li>
<li>The <code>qualityIncrement</code> action-at-a-distance</li>
<li>The hardcoded names of items with special behaviors</li>
<li>The domain concepts (like “legendary” or “conjured”) not yet
explicitly represented in tests or code</li>
</ul>
<p>And I’m happy with:</p>
<ul>
<li>The small size of each step I took</li>
<li>The utility of my tests as they existed at each step</li>
<li>The increase in my work speed (partly from tests, partly from
plain old practice with the IDE)</li>
<li>The new feature as safely delivered</li>
<li>The unit tests as they now stand</li>
<li>The likelihood that, given some new desired behavior, I or someone
else could quickly and safely implement it</li>
</ul>
<p>Remember, the assignment was to implement a new behavior. All that
other stuff I did was enzymatic, enabling the assignment to be
digested by my limited arrangement of brain cells. See how mixed
that metaphor got? That’s why.</p>
<p>Anyway, I not only implemented the new behavior, but I did it in a
way that felt safe throughout and that, were there a next developer,
would afford them safety too. If this were a real production system,
nothing in the “I don’t love” list would make me want to keep the
new behavior out of people’s hands.</p>
<p>So that’s where I stopped. Because software development is always
an exercise. We pick a point when we’ve learned enough to produce
enough value, a point where more learning isn’t worth more cost,
and we stop there. Every product and project leaves value on the
table. I won’t pretend my “I don’t love” list doesn’t concern me
(it does) or that it doesn’t matter (it does), but I’ll admit it doesn’t
concern me or matter <em>enough</em> to be worth more cost. Every chance
I get to make that decision wisely is worth practicing.</p>
A square triangular numberhttps://schmonz.com/2015/02/09/a-square-triangular-number/Amitai Schlair2016-11-12T01:39:43Z2015-11-03T00:55:55Z
<p>A year ago, with several aspects of my life in heavy ferment, <a href="https://schmonz.com/2014/02/10/my-thirty-fifth-solar-orbit/">many
goals bubbled up and filtered
through</a>. How’d I do?</p>
<h3>Health</h3>
<p>Said I’d make significant lifestyle changes. Did. Moved away from
New York and quit my high-stress job. <a href="https://schmonz.com/2014/03/01/haskell-the-dog/">Got a
dog</a> and walked him lots. Biked to
<a href="http://www.coworkbtown.com">Cowork</a> a few times per week. In
November, underwent corrective nose and sinus surgery, producing a
huge functional improvement (though post-op maintenance is still
more of a hobby than I’d like). Weight feels more like myself, <a href="https://schmonz.com/2014/10/31/how-to-lose-45-pounds-in-two-years/">but
not completely</a>. New
work routine affords a regular exercise routine. Will start next
week.</p>
<h3>Writing</h3>
<p>Vowed to write at least 26 articles. Wrote only 15. Compensated,
somewhat, by moving this site to a more comfortable environment
(see “Ikiwiki” below), making writing more likely to occur.</p>
<h3>NetBSD</h3>
<p>Claimed that <a href="http://www.netbsd.org">NetBSD</a> was my top priority
for the year. Did some long overdue maintenance on my pkgsrc packages,
attended <a href="http://www.bsdcan.org/2014/">BSDCan</a> for the first time,
and spoke at <a href="http://www.pkgsrc.org/pkgsrcCon/2014/">pkgsrcCon</a> for
the umpteenth. Didn’t accomplish much for Board. Term ends soon.
If lucky, I may get another chance to apply what I’ve learned for
the good of the project.</p>
<h3>Philolexian</h3>
<p>Sad to have missed <a href="http://www.columbia.edu/cu/philo/kilmer/">Kilmer</a>.
Made many bad-poetry-like sounds while home recovering from nose
surgery, but none where the judges could hear. Reelected to Board.
Have been attempting to enlist the active members of the Society
in helping refresh their <a href="http://www.columbia.edu/cu/philo/">ikiwiki-backed
website</a>’s design and innards.</p>
<h3>Ikiwiki</h3>
<p>Became an <a href="http://ikiwiki.info//">ikiwiki</a> committer. Presented (and live-coded)
at <a href="https://schmonz.com/2014/11/15/pittsburgh-perl-workshop-2014-web-architecture-for-unix-lovers-with-ikiwiki/">Pittsburgh Perl
Workshop</a>.
And after years of running many other sites, finally <a href="https://schmonz.com/2015/01/01/happy-new-year/">migrated
this site to ikiwiki</a>.</p>
<h3>Code</h3>
<p>Committed to spend more of my time with people who care about what
I care about. Got involved with <a href="http://www.rubysteps.com">RubySteps</a>
and did lots of <a href="https://en.wikipedia.org/wiki/Mob%5Fprogramming">mob programming</a>,
including with <a href="http://alistair.cockburn.us">Alistair Cockburn</a> and
<a href="http://www.jbrains.ca">J. B. Rainsberger</a>. Now I work alongside
<a href="http://www.daedtech.com/blog">people</a> who <a href="http://geepawhill.org">share</a>
my values.</p>
<h3>Teams</h3>
<p>Wrote briefly about <a href="https://schmonz.com/2014/03/27/how-to-develop-software/">some
ingredients</a>. Participated in
Alistair’s <a href="https://schmonz.com/2014/11/05/assumption-carpaccio/">Coaching in an Agile
Context</a>.</p>
<h3>Work</h3>
<p>Needed to feel greater appreciation for my work. Was willing to
identify and deliver more valuable work in order to get it. Determined
that helping teams make better decisions about software development
would be highly valuable. Did some Agile coaching for my employer,
and was going to change roles to do more. When that plan was impeded,
<a href="https://schmonz.com/2014/04/01/my-superpower/">I left</a>. Now I’m a “Software Craftsmanship
Coach” with a <a href="https://schmonz.com/2015/01/09/two-engagements/">software consultancy that shares my
values</a>.</p>
<h3>Home</h3>
<p>Got a place in Bloomington together. Got a very nice dog. Got good
at living together. Got engaged. Not bad!</p>
<h3>Self</h3>
<p>Always knew when that job ended I’d take some months off. Did.
Needed the time to relearn to hear and attend to my own needs, to
get right with myself before the next thing — all the more so
because the next thing really did turn out to be coaching.</p>
<p>35-year-old me nailed it when he wrote “More than ever I know who
I am, who’s for me, and who I’m for.” 36-year-old me could not
possibly agree more.</p>
Two engagementshttps://schmonz.com/2015/01/09/two-engagements/Amitai Schlair2017-01-01T22:55:07Z2015-11-03T00:55:55Z
<p>A few weeks ago, while wandering through <a href="http://www.fws.gov/refuge/muscatatuck/">Muscatatuck National
Wildlife Refuge</a> with
<a href="https://schmonz.com/2014/03/01/haskell-the-dog/">Haskell</a>, I proposed to
Bekki. She went for it:</p>
<p><a href="https://schmonz.com/2015/01/09/IMG_4926.JPG"><img src="https://schmonz.com/2015/01/09/IMG_4926.JPG" width="300" height="400" alt="the newlygageds" title="the newlygageds" class="img" /></a></p>
<p>Which is really unfortunate, because under most any other circumstances
my joining <a href="http://pillartechnology.com/company">Pillar</a> as a
<a href="https://schmonz.com/coach/">software development coach</a> would be the most exciting
thing going. I start Monday.</p>
Happy new yearhttps://schmonz.com/2015/01/01/happy-new-year/Amitai Schlair2016-11-12T01:39:43Z2015-11-03T00:55:55Z
<p>After <a href="https://schmonz.com/2007/01/15/the-schmonzcast-begins/">eight years with <code>tru podcast</code></a>
— and <a href="https://schmonz.com/2005/05/02/preparing-for-departure/">nearly ten years</a>, all
told — I’ve moved my site (and its podcast) <a href="https://schmonz.com/2013/05/27/remembering-textpattern/">away from
Textpattern</a>. I <a href="https://schmonz.com/2014/02/10/my-thirty-fifth-solar-orbit/">promised
myself</a> I’d do this in 2014.
Missed by an hour; still pretty happy.</p>
<p><a href="http://ikiwiki.info//">Ikiwiki</a>, the CMS I moved to, reflects my
preferences for writing in <code>vim</code>, checking my thoughts into <code>git</code>,
and storing and serving static content as simply as possible. That’s
probably not what most folks secretly wish for. But if you do, and
you’d use a <a href="https://staticsitegenerators.net">static site generator</a>
if only there were a sufficiently flexible one, investigate ikiwiki.
And if you know you’re going to want to hack on whatever system you
choose, take a look at <a href="https://schmonz.com/2013/08/22/tdd-by-example-an-ikiwiki-feature/">how I improved ikiwiki’s
podcasts</a>.</p>
<p>My goal in doing that work was to be just barely as good as
<a href="http://www.rainskit.com/blog/542/tru_podcast-a-podcasting-plugin-for-textpattern"><code>tru_podcast</code></a>
— which is to say very good. Thanks to Textpattern and <code>tru_podcast</code>,
I was able to share a decade of significant moments as honestly and
directly as I knew how. Now that my memories and creations are
preserved more reliably, and I can publish my writing and <a href="https://schmonz.com/tag/music/">music</a>
more easily, I feel a whole new level of safety and comfort about
sharing the significant moments to come. I look forward to continuing
to share them with you.</p>
<p>To a wonderful 2015!</p>
Pittsburgh Perl Workshop 2014: Web Architecture for Unix Lovers with Ikiwikitag:www.schmonz.com,2014-11-15:ed4417a7059b5d1ff91904645c482f4b/78e44b21259c1b7d12b54bc7b8556b9dAmitai Schlair2014-11-15T14:45:25Z2014-11-15T14:41:19Z
<p><em>Schmonzcast #17</em>: I'm proud to have been <a href="http://pghpw.org/ppw2014/talk/5768">a speaker</a> at this year's <a href="http://pghpw.org/ppw2014/">Pittsburgh Perl Workshop</a>, a two-day conference for fellow practical-minded Perl programmers. As one who has striven to code in a modern way — <span class="caps">TDD, </span>expressive objects, type-checking, and the like — in a non-modern environment, I'm sensitive to Perl being pigeonholed. So it was gratifying to see talks about familiar and timeless ideas (<a href="http://pghpw.org/ppw2014/talk/5846">systems programming</a>, <a href="http://pghpw.org/ppw2014/talk/5784">asynchrony</a>, <a href="http://pghpw.org/ppw2014/talk/5800">inversion of control</a>, <a href="http://pghpw.org/ppw2014/talk/5786">simplicity</a>, <a href="http://pghpw.org/ppw2014/talk/5807">automated testing</a>) as well as envelope-pushing new ones (<a href="http://pghpw.org/ppw2014/talk/5774">everything Ingy said</a>, <a href="http://pghpw.org/ppw2014/talk/5792">native-extension performance</a>, <a href="http://pghpw.org/ppw2014/talk/5845">high-performance serialization</a>). I also appreciated getting to meet the author of <a href="http://hop.perl.plover.com">Higher-Order Perl</a> and help him set up an ikiwiki to play with.</p>
<p><a href="http://pghpw.org/ppw2014/talk/5768">My talk</a> was half explication, half topical demonstration: on Saturday morning we learned about Ingy's new <a href="http://search.cpan.org/dist/Swim/lib/Swim.pod">Swim</a> format, and here I was on Sunday morning attempting to live-code ikiwiki support for Swim input. Would I get it working? Would I be able to give a demo? Would I eventually come to understand <code>mjd</code>'s suggestion that I sing as I code? Here's the full <a href="https://schmonz.com/2014/11/15/pittsburgh-perl-workshop-2014-web-architecture-for-unix-lovers-with-ikiwiki/20141109-web-architecture-for-unix-lovers-with-ikiwiki.mp4">screencast of my presentation</a> (or <a href="http://youtu.be/upt1sTsL5fg">watch on YouTube</a>).</p>
<ul>
<li><a href="http://pghpw.org/ppw2014/talk/5768">Abstract</a></li>
<li><a href="https://schmonz.com/2014/11/15/pittsburgh-perl-workshop-2014-web-architecture-for-unix-lovers-with-ikiwiki/slides/">Slides</a></li>
<li><a href="https://schmonz.com/2014/11/15/pittsburgh-perl-workshop-2014-web-architecture-for-unix-lovers-with-ikiwiki/20141109-web-architecture-for-unix-lovers-with-ikiwiki.mp4">Screencast</a></li>
</ul>
Live-tweeted haiku on the nature of reserving a room for a week in January, during the CodeMash conference, at the famed Kalahari Resort of Sandusky, Ohiohttps://schmonz.com/2014/11/13/live-tweeted-haiku/Amitai Schlair2016-11-12T01:39:43Z2014-11-13T16:11:11Z
<p><em>[Performed on my behalf by Chris Travis]</em></p>
<p><em>Author’s note:</em> This really happened. These are real tweets. At 10am
on October 10, 2014, 2000 people with conference tickets started
vying for 1000 on-site rooms via one hotel telephone system. After
a half hour of not getting through, I began to tweet.</p>
<p><a href="https://twitter.com/schmonz/status/520583485309087744">10:35am</a><br />
Fleeting dialtone<br />
For a moment, heart racing<br />
Nope, busy again</p>
<p><a href="https://twitter.com/schmonz/status/520587845669761024">10:53am</a><br />
Questioning memory<br />
A tone I thought I once heard<br />
Maybe I didn’t</p>
<p><a href="https://twitter.com/schmonz/status/520588290463105024">10:54am</a><br />
Life has no meaning<br />
We must choose our own values<br />
Have I chosen well?</p>
<p><a href="https://twitter.com/schmonz/status/520589398921195520">10:59am</a><br />
Leaves turn, the wind blows<br />
Telephones stand still, unmoved<br />
Gray sky, the leaves fall</p>
<p><a href="https://twitter.com/schmonz/status/520590969558036480">11:05am</a><br />
Ancients spoke of flow<br />
Bottleneck, constraint, lead time<br />
Watch cost of delay</p>
<p><a href="https://twitter.com/schmonz/status/520592298510651392">11:10am</a><br />
Developers’ time<br />
Beautiful and limited<br />
Don’t use for haiku.</p>
<p><a href="https://twitter.com/schmonz/status/520593968590225408">11:17am</a><br />
The present moment<br />
A signal of busy-ness<br />
Mine is signaled here.</p>
<p><a href="https://twitter.com/schmonz/status/520595196653080576">11:22am</a><br />
A drop of water<br />
Another and another<br />
One hundred attempts</p>
<p><a href="https://twitter.com/schmonz/status/520596664592396288">11:28am</a><br />
A long time ago<br />
I was not calling hotels<br />
There was such a time</p>
<p><a href="https://twitter.com/schmonz/status/520597919242944512">11:33am</a><br />
There is hope, you say?<br />
I must choose to believe it;<br />
Choice is not easy.</p>
<p><a href="https://twitter.com/schmonz/status/520600025555279872">11:41am</a><br />
Programmer and coach<br />
Acquiring new specialty:<br />
Fruitless phone calling</p>
<p><a href="https://twitter.com/schmonz/status/520601603276292096">11:47am</a><br />
Great holy shitballs<br />
Ethereal female voice<br />
Holding gratefully</p>
<p><a href="https://twitter.com/schmonz/status/520608009673003008">12:13pm</a><br />
A kind voice intones<br />
All rooms sold out. La Quinta?<br />
Yes, I’ll drink a fifth.</p>
Assumption Carpacciotag:www.schmonz.com,2014-11-05:ed4417a7059b5d1ff91904645c482f4b/942f6de2157f964c4699c385cc333626Amitai Schlair2014-11-06T00:19:35Z2014-11-05T21:11:44Z
<p>In <a href="https://schmonz.com/2014/05/09/when-i-might-not-tdd/">When I might not <span class="caps">TDD</span></a>, I posed myself the following question:</p>
<blockquote><p>If I'm trying to be effective and efficient, when <em>wouldn't</em> I practice <span class="caps">TDD</span>?</p></blockquote>
<p>In response, I enumerated degenerate cases, false negatives, and conjectures, but was unable to come up with anything simultaneously true and nontrivial. Carrying out <a href="http://alistair.cockburn.us">Alistair Cockburn's</a> <a href="http://alistair.cockburn.us/Elephant+Carpaccio+Exercise">Elephant Carpaccio exercise</a> yesterday uncovered an answer I had forgotten.</p>
<p>In <a href="https://schmonz.com/2014/01/26/how-to-efficiently-learn-a-programming-language/">How to efficiently learn a programming language</a>, I noticed early on that <em>not</em> doing <span class="caps">TDD </span>was probably slowing me down. So I tried adding it, started making progress and having fun, reversed my performance problem, finished early, and got to help my neighbor.</p>
<p>Early in Elephant Carpaccio, my “Coaching in an Agile Context” class partner and I noticed that doing <span class="caps">TDD </span>was probably slowing us down. So we tried removing it, started making progress and having fun, reversed our performance problem, finished early, and got to chat for a bit.</p>
<p>I'm relieved to know that when the environment produces a signal to consider not practicing <span class="caps">TDD,</span> I'm able to receive and act on it. This indicates my strong feelings about the practice are truly a matter of context, as I hope they remain. For your reference and mine, the forgotten context where I probably wouldn't <span class="caps">TDD </span>is: tiny projects.</p>
<p>Apparently I've even forgotten that I remembered that context just fine in <a href="https://schmonz.com/2014/08/07/when-is-refactoring-a-good-decision/">When is refactoring a good decision?</a>. At least I still remember that my forgetfulness is one of the <a href="https://schmonz.com/2013/08/08/why-i-practice-tdd/">reasons I prefer to test first</a>.</p>
How to lose 45 pounds in two yearstag:www.schmonz.com,2014-10-31:ed4417a7059b5d1ff91904645c482f4b/dad6e1c8a63c604fc0fc1938bcbad79eAmitai Schlair2014-10-31T18:11:02Z2014-10-31T17:40:39Z
<p>I've lost over 30 pounds since <a href="https://schmonz.com/2013/02/26/how-to-maybe-lose-45-pounds-in-a-year/">this project began in early 2013</a>. This morning, when I weighed in, I saw a number that used to mean</p>
<ul>
<li>I'd been eating a little too poorly for a little too long,</li>
<li>I needed to strictly avoid carbohydrate for a week or so, and</li>
<li>I could expect to snap right back to my healthy weight.</li>
</ul>
<p>Seeing this number now means</p>
<ul>
<li>I've been eating very carefully for a long time,</li>
<li>I'm at my lowest weight in over five years, and</li>
<li>I'm finally within striking distance of my goal.</li>
</ul>
<h3>Agency and patience</h3>
<p><img src="https://schmonz.com/2014/10/31/31.jpg" width="400" height="400" alt="Cross-section of my deviated septum, from below" title="Cross-section of my deviated septum, from below" class="img" /></p>
<p>My weight has decreased so slowly, and retrogressed so frequently, that I've sometimes doubted my ability to bring about the desired result. But I felt confident enough in my mental model of my metabolism — and certain enough that other diets would serve me less well — to stick it out.</p>
<p>For a variety of reasons, I haven't been <a href="https://schmonz.com/2013/04/28/strength-gains-and-weight-loss-after-30-workouts/">strength training</a> for several months. One reason is that my easily enraged sinuses have been angrier more often, disrupting breathing (mainly when I'm trying to sleep) and general functioning (when I'm trying not to). Turns out I have a significantly deviated septum, which, along with a couple other longstanding nasal demons, will be surgically corrected in a week and a half. I expect to be useless for about a week, in exchange for which I hope to be much better at breathing, sleeping, and functioning <a href="https://schmonz.com/2013/06/10/area-under-the-curve/">for the rest of my life</a>.</p>
<p>One new form of exercise lately has been cycling to <a href="http://www.coworkbtown.com/">my local coworking space</a> a few times a week. It's not much, but it pretty immediately feels good to do it.</p>
<h3>How I feel</h3>
<p>(See also: <a href="https://schmonz.com/2013/05/15/health-gains-after-four-months/">four months in</a>, <a href="https://schmonz.com/2013/08/01/losing-learning-and-winning/">six months in</a>.)</p>
<h4>Clothing</h4>
<ul>
<li>Pants and t-shirts fit much, much better</li>
<li>I'm wearing nicer clothes, including some new ones, because they're comfortable now</li>
</ul>
<h4>Appearance</h4>
<ul>
<li>My face has progressed another stage, now looking almost exactly like my face</li>
<li>My belly no longer feels like a foreign object that keeps getting in the way, but merely a slightly oversized version of my own belly</li>
</ul>
<h4>Energy</h4>
<ul>
<li>Bekki and I hiked for a couple hours with dogs through <a href="https://en.wikipedia.org/wiki/Brown%5FCounty%5FState%5FPark">hilly terrain</a>, and I had plenty of energy the entire time</li>
<li>I hadn't been put off by the mere idea of going hiking for a couple hours</li>
<li>I'm excited to once again be physically comfortable with exercise, and to be able to concentrate more on activity and fitness than on weight <em>per se</em></li>
</ul>
<h3>Summary</h3>
<p>If you want to lose weight like I have, you need to do all the things I've done, in case any of them (alone or in combination) are responsible for the outcome. Go live with your partner, get a dog, quit your job, ride your bike now and again, and <a href="https://schmonz.com/2014/02/10/my-thirty-fifth-solar-orbit/">everything else in this post</a>. And if none of those changes winds up helping you lose weight, hey, I'm sorry, that's really unfortunate!</p>
When is refactoring a good decision?tag:www.schmonz.com,2014-08-07:ed4417a7059b5d1ff91904645c482f4b/fb2470baca7aa3de7acf81b4dd5fcc79Amitai Schlair2014-09-12T01:34:38Z2014-08-08T02:30:48Z
<p>To develop working, valuable software, we expend time and <a href="https://schmonz.com/2014/04/01/my-superpower/">decisions</a>. In this context, a good decision is one which helps us deliver more value with our time. When might <a href="https://en.wikipedia.org/wiki/Code%5Frefactoring">refactoring</a> be a good decision?</p>
<h3>What's refactoring for?</h3>
<p>I see refactoring, above all else, as a tool for managing risk.</p>
<p>Software development is naturally rich in risk. If we accept that it's worth doing, then we're accepting some amount of risk. For all but tiny projects, the greatest risks are likely:</p>
<ol>
<li>Making undesirable changes that go unnoticed until fixing them is surprisingly expensive</li>
<li>Making desirable changes that seem worthwhile until implementing them proves surprisingly expensive</li>
</ol>
<p><span class="caps">TDD </span>can help us control (1) and — at no additional cost — affords us the option of refactoring, should we want to. And if we seek to control (2), I contend that we should want to.</p>
<h4>Straw man: never stop refactoring!</h4>
<p>Let's say we not only put stories whose only purpose is refactoring on the backlog, but we've got lots and lots of “refactoring stories”, and we prioritize them over everything else. We'll have maximized the number of possible future changes that are easy for us to make, but we'll never get around to making any of them.</p>
<h4>Straw man: never start refactoring!</h4>
<p>Let's say we not only don't ask permission to refactor, we simply never refactor. We'll have maximized how much time we're working on changes motivated solely by business value, but we'll have driven up two averages: the cost per change, and the risk of greatly underestimating the cost per change. Even if we accept that we've taunted Hofstadter's Law.</p>
<h3>Who decides to refactor?</h3>
<table class="img"><caption><em>Illustration by Rebekka Dohme.</em></caption><tr><td><img src="https://schmonz.com/2014/08/07/29.jpg" width="620" height="349" alt="Make it work (bee sinuously finding way to target flower), make it right, make it fast (bees making beelines for target flower)" title="Make it work, make it right, make it fast" class="invertible" /></td></tr></table>
<p>I see developers bee-ing best positioned to decide whether, when, and how to refactor.</p>
<p>I don't see that the “value” of refactoring and the “value” of software's user-visible behavior can be measured along commensurate axes. The latter is what we're here to do. The former is a way to improve our chances of doing it. The latter is best judged by the folks who rely on the <em>outcome</em> of what we make. The former is best judged by the folks who rely on the <em>process</em> of what we make.</p>
<h3>When is refactoring a good decision?</h3>
<p>If we agree that managing the risks of software development means mitigating its inherent variability while collecting just enough options along the way, then refactoring is likely a good decision when:</p>
<ul>
<li>Developers choose it</li>
<li>Its intended scope is to clear a path in front of the desired change</li>
<li>Its intended effect is to deliver the desired change faster (or at least not much slower, and then to deliver future changes faster)</li>
</ul>
<p>After some months of judicious and opportunistic refactoring (more or less depending on context), here are some trailing indicators that you're reaping the benefits:</p>
<ul>
<li>You rarely wish an estimate didn't have to be so large</li>
<li>You almost never feel the need to fudge an estimate</li>
<li>You almost always get what you expected when you expected it</li>
</ul>
<h3>Conclusion</h3>
<p>In software development, where risk management is a fact of life, refactoring is one of the most powerful tools at our disposal. Wielded wisely, it helps us more predictably deliver more value with our time.</p>
<h3>References</h3>
<p>My opinions generally derive from my experience (and, stubborn as I am, little else). The expression of this particular opinion is better for my having encountered the following expressions:</p>
<blockquote><p>”If you want to estimate little things, you have to refactor.” — <a href="http://www.jbrains.ca/">J. B. Rainsberger</a>. <a href="http://vimeo.com/79106557">7 minutes, 26 seconds, and the Fundamental Theorem of Agile Software Development</a> (Øredev 2013).</p></blockquote>
<blockquote><p>”Why refactor? Economics.” — <a href="http://martinfowler.com/">Martin Fowler</a>. <a href="https://www.youtube.com/watch?v=vqEg37e4Mkw">Workflows of Refactoring</a> (OOP 2014).</p></blockquote>
<blockquote><p>”Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.” — <a href="http://www.soic.indiana.edu/people/profiles/hofstadter-douglas.shtml">Douglas Hofstadter</a>. <a href="https://en.wikipedia.org/wiki/G%C3%B6del%2C%5FEscher%2C%5FBach">Gödel, Escher, Bach</a> (1979).</p></blockquote>
<blockquote><p>”Do not taunt Happy Fun Ball.” Saturday Night Live (1991).</p></blockquote>
One Russian soultag:www.schmonz.com,2014-06-29:ed4417a7059b5d1ff91904645c482f4b/b1633c9a939ff4de33916ee39df05a3aAmitai Schlair2014-12-26T02:27:16Z2014-06-29T21:09:34Z
<blockquote><p>Our hearts do in dark forests dwell.<br />
Each feeling, choosing, kernel core<br />
lives in a roughly-tangled dell,<br />
a wilderness of soul and spore.</p>
<p>Each forest lives, each forest grows,<br />
unfurls through time our destinies.<br />
Alive with buzzing thoughts, each glows,<br />
cohesive-seeming unities.</p>
<p>— Andrew Hamilton, “Akrasia Forest”</p></blockquote>
<p>I've always wondered — sometimes more, sometimes less — what my life might become. Nine years ago those wonderings led me to <a href="https://schmonz.com/2005/06/25/a-musical-pilgrimage/">the house and grave of my favorite composer</a>. The past few months of leisurely introspection have encouraged me again to wonder more. When the past week found me within walking distance, I went for a return visit.</p>
<p><img src="https://schmonz.com/2014/06/29/27.jpg" width="300" height="358" alt="The tree where I sat, and Medtner's grave" title="The tree where I sat, and Medtner's grave" class="img" /></p>
<p>I brought <a href="https://schmonz.com/2014/01/28/on-some-cusps/">my changed self</a>. Since Medtner's resting place last observed me, I had not merely learned to <a href="https://schmonz.com/2007/02/02/medtner-skazka-in-f-minor-op-26-no-3/">play some</a> and <a href="https://schmonz.com/2007/04/23/musical-analysis-medtner-skazka-op-26-3-1912/">analyze some</a> of his music, I'd finally <a href="https://schmonz.com/2007/12/17/schlair-student-piece-1/">composed some</a> I was proud to call mine. On the off chance that wouldn't suffice, I also brought flowers. Then I cued up <a href="https://schmonz.com/2007/12/06/medtner-sonata-reminiscenza-op-38-no-1/">my recorded performance of his Sonata-Reminiscenza</a>, sat at the foot of an immense tree, and marveled at the life Medtner lived while making the music he made. Was the former a necessary precondition for the latter, or merely incidental? Are my preconditions likely similar to his? If I'm to write my music, what kind of life must I live? How can I be sure? How can I find out? The clouds parted. The birds resumed their song. I rose to my feet in appreciation.</p>
<p>No amount of wondering suffices to show me what my life will be. There's only one way to find out. I hope, on my next visit, to play Medtner something wonderful and new. In the meanwhile, I know that my life is <a href="https://schmonz.com/2007/11/14/medtner-music-and-me/">far better for his music</a>, that it's precious, and that it's mine.</p>
<p><img src="https://schmonz.com/2014/06/29/28.jpg" width="472" height="337" alt="Никола́й Ме́тнер ('Nicolas Medtner'), 1880-1951" title="Никола́й Ме́тнер ('Nicolas Medtner'), 1880-1951" class="img" /></p>
pkgsrcCon 2014: pkgsrc Design Goalshttps://schmonz.com/2014/06/21/pkgsrccon-2014-pkgsrc-design-goals/Amitai Schlair2017-05-27T21:39:13Z2014-06-22T02:17:22Z
<p>At <a href="http://pkgsrc.org/pkgsrcCon/2014/">pkgsrcCon 2014</a> in London,
I presented a talk called “pkgsrc Design Goals”.</p>
<ul>
<li><a href="https://schmonz.com/2014/06/21/pkgsrccon-2014-pkgsrc-design-goals/slides/">Slides</a></li>
</ul>
TDD in context #1: Keeping my jobtag:www.schmonz.com,2014-05-31:ed4417a7059b5d1ff91904645c482f4b/ee772b507d7bb67ed1f6740beac960a0Amitai Schlair2014-09-12T01:35:51Z2014-06-01T04:08:38Z
<p>For <a href="https://schmonz.com/2014/04/01/my-superpower/">a couple months now</a>, I've been spoiling myself by spending the bulk of my time reducing my world's entropy in three main ways:</p>
<p>1. Automate more of what I do<br />
2. Organize more of what I know<br />
3. Learn more of what I don't know</p>
<p>I've begun exploring the boundaries of <a href="https://schmonz.com/2014/05/09/when-i-might-not-tdd/">my attachment to Test-Driven Development</a>. How did I get so attached in the first place? In large part, because the thinking process I've learned and applied by <a href="http://www.jbrains.ca/permalink/test-driven-development-as-pragmatic-deliberate-practice">deliberately practicing <span class="caps">TDD</span></a> has, in the contexts I've experienced, almost always been an <a href="https://en.wikipedia.org/wiki/Adaptive%5Fbehavior">adaptive behavior</a>. This is the first anecdote in a series about <span class="caps">TDD</span>'s value to humans.</p>
<h3>My confidence</h3>
<p>Claiming I do my job better with <span class="caps">TDD </span>is equivalent to claiming I do my job worse without it — which, last I checked, was true.</p>
<p>Shortly after graduating with <a href="https://schmonz.com/2007/12/17/schlair-student-piece-1/">my music degree</a>, I was hired as a software developer in a highly regulated, tightly controlled corporate environment. The tools I was hired to develop had begun life as a proof-of-concept system to manage certain kinds of identities in a heterogeneous distributed network. They put it in production. It was a roaring success. Suddenly lots of customers appeared, wanting lots more use cases, business rules, and platforms added. Suddenly the security engineers realized their proof of concept had a long life ahead of it. It would need to be managed and developed as a software product.</p>
<p>They may have been confident in my fitness for the job, but I sure wasn't. While I'd been a longtime contributor to some significant open-source projects, I hadn't been a professional software developer since 2002. And that had been my first programming job. I'd learned a whole lot very quickly, including the rudiments of <span class="caps">TDD </span>and other XP practices, and I was probably worth what I'd gotten paid, but I had not, by any means, mastered much of anything.</p>
<h3>My first assignment</h3>
<p>To their credit, my superiors had devised for me a relatively gentle introductory exercise: when an identity is no longer needed, provide a way to “disable” it. I did not need to devise a mutually authenticated client and server that spoke a network protocol in order to manipulate the server's database of identities by issuing commands to be processed or rejected according to business rules. I didn't even need to tweak the database schema; it already contained the needed fields. I just needed to add a “disable” command. Reading through the “create” and “update” commands, I copy-paste-edited a new “disable” command. Then I figured out how to run my copy of the server, how to point my client at it, and how to prove to myself that my copy of the database correctly marked a given identity as disabled. (When I demonstrated my progress, I found out there was considerably more to it than that. A great deal of much-needed handholding occurred.)</p>
<p>Then it dawned on me: I bet a bunch of the other commands need to behave differently when asked to operate on an identity that's been disabled, now that such things exist. Taking my best guesses at those behaviors, I edited the <span class="caps">SQL </span>backing those other commands until they probably handled both the old and new cases. Since I didn't understand how most of the commands were intended to be used, let alone how to verify whether they worked, we code-reviewed my very simple changes. We agreed they looked fine.</p>
<h3>My first deployment</h3>
<p>Guess what happened when we put my code into production? That's right: my new “disable” command worked, but users complained that several other commands no longer did. It was easy to spot the mistakes, now that we knew where they were, and to make the obvious fixes. We scrambled to redeploy.</p>
<p>Before I tell you how the postmortem went, remember the context:</p>
<p>1. The environment was highly regulated and tightly controlled<br />
2. The code was security-sensitive<br />
3. I'd been uncertain of my ability to do the job <em>before</em> screwing up in production</p>
<p>”Bill,” I said, because that was Bill's name, “if you need me to avoid screwing up like that again…”</p>
<p>”Uh huh,” replied Bill.</p>
<p>”…then I need to be doing Test-Driven Development.”</p>
<p>”Listen,” said Bill. “Do whatever you think you need.”</p>
<p>I did. And over the several years that followed, I never screwed up like that again.</p>
<p><img src="https://schmonz.com/2014/06/01/26.jpg" width="620" height="316" alt="Before (code pouring all over the place) and after (code pouring cleanly through the TDD funnel)" title="Before and after TDD" class="invertible" /></p>
<p><em>Illustration by Rebekka Dohme.</em></p>
<h3>My conclusion</h3>
<p>You might suggest that that's because I quickly learned the problem domain and our system's model thereof, remembered how to write basic <span class="caps">SQL, </span>and made a habit of checking my assumptions and my results more carefully. You'd be right. You might suggest that I could have done all that without <span class="caps">TDD.</span> You'd be right again. But I'm fairly sure I did them sooner, better, and more reliably — all of which felt crucially important at the time — because of <span class="caps">TDD.</span></p>
<p>As near as I can tell, <span class="caps">TDD </span>saved my job.</p>
When I might not TDDtag:www.schmonz.com,2014-05-09:ed4417a7059b5d1ff91904645c482f4b/1cc162d817a51c658fb728e0ef4b4059Amitai Schlair2014-05-09T04:18:02Z2014-05-09T04:16:29Z
<p>Given a software project whose outcome and schedule truly matter, <a href="https://en.wikipedia.org/wiki/Ceteris%5Fparibus">all other things being equal</a>, I'd choose…</p>
<ul>
<li>A capable team of <span class="caps">TDD </span>practitioners over another capable team</li>
<li>To have the team practice <span class="caps">TDD</span></li>
</ul>
<p>Of course, there are always a great many other things, and they be rarely equal. Let's <a href="https://www.youtube.com/watch?v=xGGeLHnDQk8">scale it down a bit</a>.</p>
<p>Given the responsibility to deliver working, valuable <a href="https://schmonz.com/2014/03/27/how-to-develop-software/">software to humans</a>, I'd choose to drive my development with tests. I believe I fulfill my responsibility faster and better when I do. This turns out to be one of my strongest and most deeply held beliefs of any kind, right up there with the intrinsic value of human beings and an overarching respect for individual autonomy.</p>
<p>Yeah, that sounds a little odd to me too. Yet my professional experiences have repeatedly borne out the validity and importance of all three.</p>
<p>Sticking with <span class="caps">TDD </span>here, I've read and/or conjectured lots of plausible mechanisms by which it could be speeding me up, I've observed a bunch of them directly, and anecdotally I'm usually pleasantly surprised how smoothly things go, compared to how I imagine they might have gone instead.</p>
<p>Software development isn't a controlled experiment. It's possible I've been continually and subtly lying to myself under the sway of a whole bunch of cognitive biases and thus I've been egregiously misinterpreting my personal anecdata.</p>
<p>Since “I do my job better when I practice <span class="caps">TDD</span>” is merely a strong belief, not a result that I've proven, I owe it to myself and the people I work with to question it from time to time. Inspired by some recent professional experiences, now is one of those times. Where are the boundaries of my belief? If I'm trying to be effective and efficient, when <em>wouldn't</em> I practice <span class="caps">TDD</span>?</p>
<h3>What I mean by <span class="caps">TDD</span></h3>
<p><span class="caps">TDD, </span>to me, means holding a collaborative conversation with my code. I suggest what I think I want it to do next, ask it to try, listen to what it tells me, adjust my thinking and wanting, and repeat. To listen better and adjust faster, write smaller tests (in units of code, if inside-out; in slices of functionality, if outside-in).</p>
<p>If that metaphor doesn't quite work for you, try this one: <span class="caps">TDD </span>means pair programming with myself. Before typing anything, I communicate my intent aloud. Maybe my pair has a better idea, or a question to consider, or a drawing board we should be going back to. By working in a way that externalizes my thinking, I can be my own pair.</p>
<h3>Degenerate cases</h3>
<p>I wouldn't want <span class="caps">TDD </span>if…</p>
<ul>
<li>It doesn't need to work</li>
<li>It needs to work, but it doesn't matter when</li>
<li>It's so manifestly simple that it necessarily works</li>
<li>It won't ever need to change</li>
<li>It's so manifestly simple that it'll be obvious how to change and necessarily still manifestly simple afterward</li>
<li>It's a <a href="http://www.extremeprogramming.org/rules/spike.html">throwaway experiment</a> to learn something</li>
<li>I'm being held at gunpoint by a crazed stakeholder who'll shoot me if I write so much as a single test first (or try to have a conversation about it)</li>
</ul>
<p>None of these cases is particularly interesting.</p>
<h3>False negatives</h3>
<p>You might think I wouldn't want <span class="caps">TDD </span>if…</p>
<ul>
<li>It's legacy code</li>
<li>It's otherwise hard to write tests for</li>
<li>Nobody else on the team bothers</li>
<li>I'm <a href="https://schmonz.com/2014/01/26/how-to-efficiently-learn-a-programming-language/">learning a new programming language</a></li>
<li>Unarmed stakeholders express opposition to it</li>
</ul>
<p>You'd nearly always be wrong.</p>
<h3>Learnings go here</h3>
<p>I practice <span class="caps">TDD </span>for its many benefits. What if I could achieve those benefits another way?</p>
<p>As a useful oversimplification, the biggest external benefit of <span class="caps">TDD </span>might be that I get my work done faster and better, and the biggest internal benefit might be that I feel safer doing my work. (It seems plausible that there's a <a href="http://www.industriallogic.com/blog/anzeneering/">causal relationship</a>.) I've been working in a dynamic language famous for its runtime surprises, deriving a feeling of safety from my tests. Might there be a language where the compiler alone could give me that same feeling?</p>
<p>I can practice <span class="caps">TDD </span>because I've been targeting suitably unconstrained environments. Might there be a target whose constraints preclude <span class="caps">TDD</span>?</p>
<p>I don't know for sure when I wouldn't want <span class="caps">TDD.</span> But I've got some ideas, and watch out: I'm going to test them.</p>
Shoulda bought yak insurancetag:www.schmonz.com,2014-04-23:ed4417a7059b5d1ff91904645c482f4b/569fddf69d68df9fd160a1b92918d2dbAmitai Schlair2014-04-23T22:48:07Z2014-04-23T21:43:33Z
<table class="img"><caption><em>Illustration by <a href="https://www.flickr.com/photos/snapperwolf/6952219933/">Jason Crane</a>.</em></caption><tr><td><img src="https://schmonz.com/2014/04/23/25.png" width="410" height="352" alt="Hand-drawn yak with a safety razor going down its midsection" title="Hand-drawn yak with a safety razor going down its midsection" class="img" /></td></tr></table>
<p>My new <a href="http://teespring.com/maksesoftwarebetter2">Yak Shaving Expert t-shirt</a> is fitting, and not only because it's the right size. For instance, today I wanted to start backing up my email, so I found <a href="http://offlineimap.org/">offlineimap</a> to my taste, so I went to <a href="http://pkgsrc.se/mail/offlineimap">pkgsrc</a> to install it and saw that we're a couple releases behind, so I <a href="http://mail-index.netbsd.org/pkgsrc-changes/2014/04/23/msg104896.html">updated the package</a>. Sometimes it turns out that in order to do what you want, it's necessary that you first go <a href="http://programmers.stackexchange.com/questions/34775/correct-definition-of-the-term-yak-shaving">shave a yak</a>. Maybe I'll get to try backing up my email tomorrow.</p>
<p>In software development, it's pleasing when any desired change proves easy to make. When a change proves prohibitively difficult, we have to decide what to do: either to stop wanting it, or to <a href="https://twitter.com/KentBeck/status/250733358307500032">want it anyway</a>. In neither case will we be able to <a href="https://schmonz.com/2014/04/01/my-superpower/">know the full cost of our decision</a>. But our choice can and should be informed by our need for predictable cost of delivery in the future and our willingness to delay gratification in the present. It's sort of like insurance. If over our product's lifetime we need to minimize the frequency with which we have to stop everything and shave an entire yak, then we know the discipline required.</p>
<p>I've felt mildly and persistently overwhelmed since the <a href="https://schmonz.com/2013/06/10/area-under-the-curve/">great server crash of late 2008</a>. First I had time to deal with the fallout, but no money; then money, but no time. Not having all my personal data organized and available has meant that for any given task, I've learned to assume I can't just go and do it; instead, I'll have to first figure out what I need, then go digging to find it all. Then, and only then, can I hope to complete the task. So the act of getting started has been harder than usual, the list of tasks has grown large, the cycle has been self-sustaining, and the effect of five years of this drip-drip-drip on my cognitive capacity has been noticeable, at least to me.</p>
<p>My personal yaks have finally come home to roost. (Yes, they've evolved the ability to roost.) I have money, time, grand ideas, and some clippers. Where to start? A few weeks ago I guessed I'd want to answer that only after refining my enormous backlog a bit. Now I think whichever item I feel like doing next is what I'll do next. Why try to impose an ordering, when I know full well it's yaks all the way down?</p>
My superpowertag:www.schmonz.com,2014-03-14:ed4417a7059b5d1ff91904645c482f4b/a09009e2d3e6695c4740d940b5fb7582Amitai Schlair2014-04-02T04:33:11Z2014-04-01T22:00:00Z
<p>People who haven't been programmers have no way of knowing the extent to which programming consists of making decisions. It is, let me tell you, a very large extent. Many managers expect a few large, visible decisions when we're discussing “requirements” or “architecture” or “design”, but can't imagine the sheer number of decisions made when we're doing “implementation”. (These managers either haven't encountered Agile practices or have chosen not to learn from their encounters.) Everything strange and wonderful about the art of software development, the sometimes counterintuitive stuff we do in order to do it well, stems from three premises:</p>
<ol>
<li>Software is made <a href="https://schmonz.com/2014/03/27/how-to-develop-software/">by humans for humans</a>.</li>
<li>A person developing software makes hundreds, maybe thousands of choices each day.</li>
<li>For any given choice, we won't always know its future price, but we'll always have to pay it.</li>
</ol>
<p>In 2009, a Fortune 100 company hired me as a security engineer to develop a custom infrastructure product. I hadn't programmed professionally for longer than the four years I'd just spent earning a degree — not in computer science, but in music. Did I have what it took to do the job? I remember how unsure I felt. But a friend who vouched for me arranged an interview, it went well, and they made me an offer I was pleased to not refuse. A year later, I was managing the product and its team.</p>
<p>With a nod to <a href="http://en.wikiquote.org/wiki/Kent_Beck">Kent Beck</a>, I'm not a great programmer, I'm just a good programmer with great judgment. My superpower is decision-making.</p>
<p>A developer's choices are most often reified in code. A manager's choices are most often reified in the product and in the team that produces it. For several years, as product manager and team lead, I did work that took full advantage of the quality of my decisions. It was an extraordinarily difficult environment in which to do the job well, and I made damn sure to do it well. But when I learned last year that my work was not widely or consistently appreciated, the struggle suddenly felt much less rewarding. It turns out that people who haven't been software development managers have no way of knowing the extent to which managing software development teams consists of making decisions. It's the entire first paragraph all over again, a level higher on the org chart.</p>
<p>I willingly accepted a reduced role with the promise that the arrangement was temporary. I knew I wouldn't be making the big decisions anymore; this was a welcome relief from apparently thankless work. I didn't know my informed professional opinions would not be considered when making the decisions, or that the decisions would be made poorly, or that I'd still be around long enough for that to hurt me. I certainly didn't know, when I'd found a role elsewhere in which I'd get to deliver far more value far more visibly — a role in which I'd spend some percentage of my time coaching development teams — that my temporary arrangement, which had become untenable, wasn't so temporary after all.</p>
<p>We don't always know the price, but we always have to pay it. I was paying.</p>
<p>If making decisions is my superpower, then I had a decision to make. It stemmed from three premises:</p>
<ol>
<li>I was no longer being used to make decisions.</li>
<li>I was no longer being used to support the people who were making decisions.</li>
<li>I was no longer able to switch to a role where I'd make decisions or help others make them.</li>
</ol>
<p>After checking my premises, I handed in a brief letter with my conclusion. A few weeks later, it was my last day. Yesterday.</p>
<p>Today's my fourth anniversary with Bekki. As of a few months ago, we finally live in the same place. It's a nice place. I walk to the grocery, the butcher, the pharmacy, even the dentist, and a handful of good coffeeshops. Our house is full of comforts, two of which are covered in fur of their own devising. I'm writing these words sitting in the yard because spring arrived yesterday and we have a yard.</p>
<p>So I've left my job. What next? If I could, I'd want to slow down for a while and just enjoy what I have. And I can. It's the easiest decision in the world.</p>
How to develop softwaretag:www.schmonz.com,2014-03-27:ed4417a7059b5d1ff91904645c482f4b/f71158cca1cf9dc424a86e0a36e71197Amitai Schlair2014-09-12T01:35:55Z2014-03-27T21:17:19Z
<p>There are many ways to develop software. The method I'm most familiar with is to have people do it. You know, humans.</p>
<table class="img"><caption><em>Dogs would likely find it gratifying to deliver working, valuable software to their humans.</em></caption><tr><td><img src="https://schmonz.com/2014/03/27/24.jpg" width="460" height="333" alt="Dog wearing tie mashing keys, caption: 'I have no idea what I'm doing'" title="I have no idea what I'm doing" class="img" /></td></tr></table>
<h3>Knowledge</h3>
<p>Since software is made by humans for humans, one bottleneck is the state of our knowledge. You want something. I want to help you get it. But what is it, exactly? Why do we think so? How can we be sure? Let's say we feel pretty sure. How much can you afford to spend to get it? How much might it cost you to have me do it? Do we still think it's what you want? Let's say yes. Am I en route to what you want? Why do we think so? How can we be sure? Am I going to complete it under your budget and time constraints? Why do we think so? How can we be sure? Let's say I do. Is it still what you want? Let's say yes. Have I done what you needed? Why do we think so? How can we be sure? And so on.</p>
<p>Every time we find ourselves surprised, disappointed, confused, or stuck, we're being bottlenecked by our knowledge. We thought we knew, but it turns out we didn't. To exacerbate this, we can make a habit of pretending we always know and we're always sure. To ameliorate it, we can <a href="http://martinfowler.com/bliki/FrequencyReducesDifficulty.html">make a habit of checking</a> what we currently believe and why. If we haven't checked whether it's true recently, it might not be true now.</p>
<h3>Trust</h3>
<p>Since software is made by humans for humans, another bottleneck is the state of our trust. If you don't feel comfortable sharing your needs with me, I won't be able to understand them very well. If I don't understand your needs, you won't be interested in hearing my ideas for meeting them. If you're not interested in my ideas, I won't be able to help you very well. If I don't do you much good, you won't feel comfortable sharing your needs with me. And so on.</p>
<p>Of course, there's also a positive feedback cycle. If last time we both got what we wanted, this time we're more likely to give each other what we need. When we work together, my first meta-task is to convey to you that it'll be worth your while to trust me. Once you begin to believe it, my next meta-task is to quickly give you ways to validate your belief. If we haven't checked whether it's true recently, it might not be true now.</p>
<h3>Empathy</h3>
<p>Since software is made by humans for humans, another bottleneck is the state of our empathy. If I don't care about you, you'll feel it, you won't grant me your trust, and the knowledge we'll need to acquire together simply won't be available to us. If you don't care about me, likewise. When we work together, my zeroth meta-task is to convey to you that I care.</p>
<p>This one's easy for me. As a solitary kid, I got into programming for the thrill of solving my own problems (which I still get a kick out of, believe you me). As a full-sized social animal, I've built a career in software development for the thrill of helping you solve yours. What matters to you matters to me. When we work together, you'll be able to tell right away.</p>
<h3>Technical skill</h3>
<p>Oh, right: since software is made of bits on computers, another bottleneck might be the state of our technical skill. Technical skill can help us acquire knowledge and earn trust. It cannot help us empathize with each other. If and only if we're doing wonderfully at that, technical skill might become our bottleneck. In which case we'd be perfectly able to overcome it, together.</p>
NYCBUG 2014: One Weird Trick To Simplify Package Managementhttps://schmonz.com/2014/03/05/nycbug-2014-one-weird-trick-to-simplify-package-management/Amitai Schlair2016-11-12T01:39:43Z2014-03-06T03:17:22Z
<ul>
<li><a href="http://www.nycbug.org/index.cgi?action=view&id=10345">Abstract</a></li>
<li><a href="https://schmonz.com/2014/03/05/nycbug-2014-one-weird-trick-to-simplify-package-management/slides/">Slides</a></li>
</ul>
Haskell the dogtag:www.schmonz.com,2014-03-01:ed4417a7059b5d1ff91904645c482f4b/c8e57f479c01733c641918d4153ac881Amitai Schlair2014-03-01T19:24:50Z2014-03-01T19:08:47Z
<p>That was quick. I had <a href="https://schmonz.com/2014/02/10/my-thirty-fifth-solar-orbit/">lately mused here</a> that a dog to take me for walks would be just the thing. Not a week later we <a href="https://bloomington.in.gov/animalshelter">went to the shelter</a>, found our guy, and brought him home.</p>
<p><img src="https://schmonz.com/2014/03/01/23.png" width="629" height="416" alt="Haskell lying on the rug" title="Haskell lying on the rug, February 2013" class="img" /></p>
<p>It was quick because Bekki, having met him more than once, already knew he was for us. She'd been eyeing candidates for adoption online and occasionally visiting them, and she had gone to meet Rascal the day before Thanksgiving. By then nearly all my belongings had migrated to our house in Bloomington, but I was still living out my last few weeks in Washington Heights. Until the <a href="https://schmonz.com/2014/01/28/on-some-cusps/">end of January</a> we knew we'd be at home together for one week, in Germany together for three, and apart for another three while I was away for a conference and for work. Sweet as my trusted source assured me Rascal was, we knew we couldn't take him. Not quite yet.</p>
<p>When someone else did, we figured that was that. But here he was again. So it came to pass that we were able to go together to see Baloo (as he was now called) and to learn as much of his story as the shelter could tell us. He had been brought in by a family who purchased him on Craigslist but didn't have time; adopted by a young couple who returned him after three weeks due to a family member's allergies; adopted by another young couple who returned him after three days due to his nonstop vomiting; and here we were, another young couple. We liked him and we thought we'd like to adopt him, but we didn't want to continue the pattern, so we went home and slept on it. The following day we knew not only that his troubles endeared him to us more, but also that we were ready for whatever they might be, whatever he might need us to do.</p>
<p>His first days with us were quiet and loving, when they weren't vomitorious. Some combination of politeness and hunger impelled him to try to clean up his own messes, which we quickly put a stop to. Dozens of carpet-bombings and a couple medical inspections later, we're slowly getting the hang of managing his stomach, he's getting more comfortable with us and otherwise, and we're starting to discover hints of a boisterous personality. Bekki got home from driving me to the airport to find that the dog had amused himself in our several hours' absence by reorganizing the house a bit. And that's how we realized that was the longest we've left him home alone. Is this 10-year-old fellow's apparent gentility with his feline and human housemates a façade? I'm away from the home office till mid-March, so we're about to find out.</p>
<p>His new name was Bekki's idea: he responded well to “Rascal”, he's husky-derived, and one of his new owners is a programmer. Haskell. It's even more fitting because we <a href="https://en.wikipedia.org/wiki/Lazy%5Fevaluation">lazily evaluated</a> his name just in time to tell the vet. Now I have two Haskells to get to know. For the moment, I'm focusing on the 65-pound wannabe lapdog who wishes I'd walk faster, then cuddle more.</p>
My thirty-fifth solar orbittag:www.schmonz.com,2013-04-27:ed4417a7059b5d1ff91904645c482f4b/8631b010186bb7c37fbbbf601d7a87e7Amitai Schlair2014-02-11T01:22:33Z2014-02-11T01:22:33Z
<p>For the last two and a half years, ever since Bekki started her Ph.D. program, I've been splitting my time between New York and Indiana. At first, as part of a larger group expected to work together from the New York office on Tuesdays and Thursdays, I could at best fly out on a Thursday evening, <a href="https://schmonz.com/2013/10/17/working-from-everywhere/">work remotely</a> Friday and Monday, and fly back Monday night. After a year of that, I transferred (along with my product and team) to another group in order for us to be better managed, which had the pleasant side effect of enabling me to stay and work from Bloomington for stints of a week or longer.</p>
<p>Another side effect of a steady diet of lighter travel and enlightened management was that by the time 2013 rolled around, I realized I was mentally ready to <a href="https://schmonz.com/2013/02/26/how-to-maybe-lose-45-pounds-in-a-year/">prioritize my health</a>. If you were to guess that getting healthier might be accompanied by other improvements, you'd be right. I celebrated my 35th birthday yesterday, so I'm of a mind to reflect on some ways in which 2013 went well for me and how I intend to build on each in 2014.</p>
<h3>Health</h3>
<p>I hoped — but initially didn't quite believe — that I was prioritizing my health. I treated my weight loss as <a href="https://schmonz.com/2013/02/26/how-to-maybe-lose-45-pounds-in-a-year/">a project to be managed</a>. Other than assigning arbitrarily fixed scope (”lose 45 pounds”) and fixed deadline (”in a year”), I managed it with an Agile-influenced self-designed process that helped me make the daily choices I wanted to make, radiated current status visually at home and at work, prompted me to periodically review progress, and incremented itself one simplest-change-that-could-possibly-help(-and-stick) at a time.</p>
<p>As is typical when the stated goal and the stated deadline are both “fixed”, one must be prepared in the end to adjust the goal. I didn't lose 45 pounds. But because the parameters were of my own invention, I don't feel disappointed in the least about the project. Rather the contrary: I'm <a href="https://schmonz.com/2013/09/22/weights-rates-and-dates/">nearly 30 pounds lighter</a> than a year ago, I feel and look more like myself, and I've managed to convince myself that I really have been prioritizing my health.</p>
<p>For 2014, now that I trust what I've been doing, I'm willing to make more significant lifestyle changes.</p>
<h3>Writing</h3>
<p>I restored this site to operation and wrote 22 articles. You won't be surprised that my two most frequent topics were (1) health and (2) Test-Driven Development.</p>
<p>I was surprised to have written so much. In 2014 I'll make a point of delivering no fewer than 26 articles, no less often than every two weeks.</p>
<h3>NetBSD</h3>
<p>One of the <span class="caps">TDD</span>-related articles was from <a href="https://schmonz.com/2013/04/05/pkgsrccon-2013-rehabilitating-pkglint/">my talk at pkgsrcCon</a> in Berlin. As a longtime member of <code>pkgsrc-pmc</code>, the steering committee for the pkgsrc package management system, I have long felt the need to demonstrate technical leadership by improving the architecture of the system. I plan to attend this summer's pkgsrcCon in London; I hope by then I've done more than merely maintain my packages, and can show some consequential improvements to pkgsrc internals.</p>
<p>I was elected to the Board of the NetBSD Foundation. In 2013, I learned what the board does and how it does it, and represented NetBSD and pkgsrc in <a href="https://schmonz.com/2013/12/17/two-interviews/">two interviews</a>. If health was last year's top priority for me, NetBSD is this year's.</p>
<h3>Philolexian</h3>
<p>I've been serving for several years on the Board of the Philolexian Foundation, which supports the operation and strivings of the Philolexian Society of Columbia University. This year I ascended to President. I also took inspiration from my frequent proximity to Indiana University to write and perform <a href="https://schmonz.com/2013/11/15/a-premeditated-improvisation/">a reasonably bad poem</a> at Philo's annual <a href="https://en.wikipedia.org/wiki/Joyce%5FKilmer%5FMemorial%5FBad%5FPoetry%5FContest">Alfred Joyce Kilmer Memorial Bad Poetry Contest</a>.</p>
<h3>Ikiwiki</h3>
<p>Two of the articles featuring Test-Driven Development were <a href="https://schmonz.com/2013/08/20/tdd-by-example-an-ikiwiki-bugfix/">about</a> <a href="https://schmonz.com/2013/08/22/tdd-by-example-an-ikiwiki-feature/">ikiwiki</a>, web content management software I've used to solve publishing problems for <a href="http://wiki.netbsd.org">NetBSD</a> and <a href="http://www.philo.org">Philolexian</a>. Before 2014 is out, I'll finally be <a href="https://schmonz.com/2013/05/27/remembering-textpattern/">publishing this site with ikiwiki</a> too.</p>
<h3>Code</h3>
<p>Another of the Test-Driven Development articles reflected my deepened understanding that <span class="caps">TDD </span>is a technique for learning rapidly what's going on in code, even (maybe especially) <a href="https://schmonz.com/2014/01/26/how-to-efficiently-learn-a-programming-language/">when one doesn't know the language well</a>. I figured that out because a workshop at CodeMash 2013 pleasantly forced me to. CodeMash was the first software development conference I ever attended and the first of three in 2013. The third was Software Craftsmanship North America, where I experienced my first <a href="https://schmonz.com/2013/12/13/global-day-of-code-retreat/">Code Retreat</a> and the long-absent, much-needed feeling of being among peers whose software values matched mine.</p>
<p>In 2014 I intend to spend much less time with people who don't care about what I care about, and much more time with people who do.</p>
<h3>Teams</h3>
<p>The other conference I attended last year (as a newly minted <a href="http://www.scrumalliance.org/pages/certified_scrum_professional">Certified Scrum Professional</a>) was <a href="https://www.scrumalliance.org/courses-events/events/global-gatherings/2013/las-vegas-2013">Scrum Gathering Las Vegas</a>. Thirty of my most valuable 2013 minutes were spent at the <span class="caps">SGLAS</span> Coaches' Clinic talking with <a href="https://www.scrumalliance.org/community/profile/rbrown2">Roger Brown</a>. Considering coaching as a career, I wanted a coach to help me understand more precisely what that looks like and whether I might be able to do it well. Roger's answers to my questions about the coaching life fit my mental model — and when I answered his questions, his reactions indicated that I'd be smart to try it.</p>
<h3>Work</h3>
<p>Another thirty of my most valuable 2013 minutes were spent at the New York office talking with a senior manager. I shared with him my desire to coach, the potential benefits to the company, and my need to validate the idea. He knew of a team looking for some coaching and sent me to Montreal to coach them.</p>
<p>For a total of five days surrounding Thanksgiving with the family in New York, I worked on-site with the team as a whole and individually, developers and managers, hands-on and nonstop, and it was exhausting and exhilarating. My brief time with that team validated for me that I was already pretty decent at coaching, that I could be great at it, that it might let me make a small dent in the universe, and that I loved it.</p>
<p>In 2013 I determined that I needed to feel greater appreciation for my work, that I was willing to identify and deliver more valuable work in order to get it, and that helping teams make better decisions about software development would be highly valuable.</p>
<p>In 2014 I expect my responsibilities to change from managing a single product to coaching multiple teams, and I expect my efforts to produce observably meaningful results for all involved.</p>
<h3>Home</h3>
<p>A year ago the fact of living in New York wasn't the bottleneck to improving my health. A few minimal effective changes later, I feel otherwise. I'm doing well; to do better, I need to be able to safely ride my bike on pleasant paths without shlepping it up and down three flights of stairs, to randomly drop by a tennis or basketball court and probably get to play, to comfortably house some sort of dog (preferably large) who requires lots of walks, to relax in a quiet home, and to travel less.</p>
<p>My team isn't — indeed, most of the company's development teams aren't — in New York. So continuing to live there wouldn't win me much effectiveness or save me much travel. If I were to split my time such that my periodic trips were <em>to</em> the New York office, the proportions would be quantitatively different, but the arrangement wouldn't be qualitatively different.</p>
<p>My life isn't in New York. To a midwesterner by temperament, it never could have been. I'm grateful for eight and a half formative years there, and I'll be happy to see it every time I visit, but New York was only ever a place I tolerated in order to get what I needed.</p>
<p>Everything I need now is in Bloomington.</p>
<h3>Self</h3>
<p>When I think about how I spent my 35th solar orbit, I feel anything is possible in the next one. I feel powerful. More than ever I know who I am, who's for me, and who I'm for.</p>
On some cuspstag:www.schmonz.com,2014-01-28:ed4417a7059b5d1ff91904645c482f4b/12d0f25d5baec34c417a3b257b789ce0Amitai Schlair2014-09-11T23:32:25Z2014-01-29T00:51:19Z
<p>I first learned of the existence of a composer named Nikolai Medtner fourteen years ago, when overworked Amazon robots advised me, having peered deeply into my purchase history, that the missing <em>je ne sais quoi</em> in my Shopping Cart was a $60 box set of his complete piano sonatas. An ambitious suggestion, to be sure. I was nonplussed. But I became willing to plus it when I spotted that the pianist was Marc-André Hamelin, whose existence I had already discovered and come to appreciate. Anything Hamelin wanted to record, I wanted to hear.</p>
<p>Medtner's music did not endear itself to me immediately. But when it did, it began slowly and persistently <a href="https://schmonz.com/2007/11/14/medtner-music-and-me/">altering my life choices</a>. I am now a person who eight and a half years ago <a href="https://schmonz.com/2005/09/07/first-week-of-classes/">moved to New York</a> to find my way back to music. I am now a person who agreed to <a href="https://schmonz.com/2007/12/06/medtner-sonata-reminiscenza-op-38-no-1/">perform in recital</a> for the first time since high school because it meant an opportunity to share my love of Medtner. I am now a person who <a href="https://schmonz.com/2007/12/17/schlair-student-piece-1/">composed a small piano piece</a> (under the stylistic influence of Medtner) in order to prove to myself that I had what it takes to write worthwhile music. I am now a person who graduated college with a degree in music, who expects my musical training to continue, my musical life to flourish.</p>
<p>After all these years, I found myself last night in a room (Zankel Hall at Carnegie Hall) in which I saw for the first time my favorite pianist playing my favorite composer. The time and place of this culminating event were themselves, to me, poetic. And it's fitting that <a href="http://www.nytimes.com/2014/01/29/arts/music/a-lively-jaunt-with-medtner-schubert-and-chopin.html?pagewanted=all">Hamelin's recital</a> led to a new and timely insight about why Medtner's music so resonates with me: his extraordinary musical intelligence never — unlike plenty of self-consciously clever composers — draws attention to itself. It is only, always, ever subservient to the physical and emotional experiences he designed coterminously for the pianist and the audience. I asked my sister afterward whether she'd noticed that an entire movement had been in an unusual time signature (15/8). She had not, because the movement had not been written in order to be noticed for its cleverness. Medtner himself would probably say it was written that way because that's how it needed to sound, that he subjectively and with great care divined the natural shape it needed to have, then worked hard to preserve and develop it to its fullest expression.</p>
<p>With renewed vigor over the past year, I've been doing the same for myself, reevaluating the various ways in which I choose to spend my skill, ability, and effort, seeking to minimize waste and maximize returns. Several slow-building changes are close to fruition, one particularly so as I write these words. I'm excited to tell you more soon.</p>
<p>In classical sonata form, two themes of contrasting character battle for primacy, then reconcile. Medtner's chief contribution to sonata form is his novel route to reconciliation: he brings his themes together in <em>time</em>. By arranging for us to hear them simultaneously, he shows his seemingly incongruous motifs to be thematically related and contrapuntally complementary. Each theme demonstrates its value in isolation and opposition, they take turns developing, and in the end it turns out that not only can they coexist, but also in so doing they deepen each other. These profound syntheses in Medtner's sonatas, with their hard-earned simplicity, are for me some of the most intellectually and emotionally thrilling moments to be had in music and, as such, in all of existence.</p>
<p>Medtner's been leading me by example all along. Fourteen years and it took me until last night to see it. To harmonize two themes, identify their common ancestry, then play them together. The denouement has to be earned; it's hard. Until, at long last, it finally becomes simple.</p>
How to efficiently learn a programming languagetag:www.schmonz.com,2014-01-26:ed4417a7059b5d1ff91904645c482f4b/8b07d33954c0b5c5ca98293b43fecbb8Amitai Schlair2014-09-12T01:35:59Z2014-01-26T06:01:40Z
<p>Some commonly held ideas about <a href="http://blog.pieterg.com/how-to-learn-a-programming-language/">what a programmer needs</a> in order to learn another programming language:</p>
<ol>
<li>Your <strong>motivation</strong>: have a real problem you need to solve</li>
<li>Your <strong>patience</strong>: tolerate solving it slowly</li>
<li>The language's <strong>design</strong> and <strong>basic use</strong>: read a book</li>
<li>The language's <strong>standard libraries</strong>: consult online docs as needed</li>
<li>The language's <strong>actual behavior</strong>: play with the <span class="caps">REPL</span></li>
<li>Your <strong>basic understanding</strong> of the language: repeat all of the above until you've solved the problem</li>
<li>Your progressively <strong>improved understanding</strong> of the language: repeat for several more problems</li>
</ol>
<p>I find step 6 fuzzy. When you don't know a language very well, you can't express yourself in it very well, and your code frequently won't do what you intend. Of course, you can't debug it very well either, so you're forced to context-switch — either to the <span class="caps">REPL </span>(assuming there is one and its behavior is sufficiently representative) to validate your uninformed guesses about what might be wrong, or by littering <code>printf</code> statements everywhere. Neither makes for a fast feedback loop.</p>
<p>We all contend that context-switching and slow feedback loops are inefficient when we're learning how to solve problems in languages we already “know”. So why do we seem to tolerate these inefficiencies when we're learning how to solve problems in languages we “don't know”?</p>
<h3>A personal anecdatum</h3>
<p>At <a href="http://www.codemash.org">CodeMash</a> a year ago, I attended an afternoon workshop on elements of advanced Ruby style that explicitly targeted experienced Rubyists. My experience consisted of having attended an intro-to-Ruby workshop that very morning. Unsurprisingly, I had trouble keeping up with the first couple exercises, and started to wonder whether I'd get to have fun or learn much.</p>
<p>I took a moment to retrospect. Where was the bottleneck? Was I slower than others at noticing when my program produced the wrong results? Probably not. Was I producing many more wrong results before arriving at the right ones? Almost certainly. So if I was going to have a productive afternoon — first by keeping up, and then maybe enjoying myself and digging deeper — I needed to manufacture an advantage.</p>
<h3>I will turn this car around</h3>
<p>As I worked on each new exercise, I whittled away a bit more at my bottleneck. First, I figured out how to load my class from a driver program. Then I mapped a <code>vim</code> key to save both files and invoke the driver. Then I replaced the class's verbose status reporting with some assertions in the driver, comparing some expecteds to actuals. Then I only displayed assertions when they failed.</p>
<p>I had turned the tide. I had made myself able, just barely, to complete each exercise in the time allotted. This would be a productive afternoon after all.</p>
<h3>Deep breath, and continue</h3>
<p>I extracted each assertion into its own method, to remind me of its meaning at a glance, and so I could easily comment it out when I was visually confused by too many assertions failing. Then I factored out the common bits of state shared by multiple assertions, so that I could more quickly write new assertions without screwing up. Then I started writing assertions first, at the beginning of the exercise, and making sure they failed correctly before proceeding.</p>
<p>The workshop's exercises were cleverly designed to scale to each participant's needs. At this point I was completing not only the simplest form of each exercise, but also each of the successively harder forms, and then turning to help my neighbor.</p>
<h3>You see what I did there</h3>
<p>Dear reader, from this narrative you have doubtless identified the catalyst for my rapid learning of a new programming language: Test-Driven Development. You may not be surprised. I was! Even as a <a href="https://schmonz.com/2013/08/08/why-i-practice-tdd/">longtime</a> <a href="https://schmonz.com/2013/08/20/tdd-by-example-an-ikiwiki-bugfix/"><span class="caps">TDD</span></a> <a href="https://schmonz.com/2013/08/22/tdd-by-example-an-ikiwiki-feature/">adherent</a>, I had assumed the steps to professional competence in a language were:</p>
<ol>
<li>Do whatever you do to learn enough of the language</li>
<li>Find and master a popular <span class="caps">TDD </span>tool</li>
<li>Test-drive production-quality code</li>
</ol>
<p>On the basis of my experience, I now believe it is more efficient to replace the first step with these two:</p>
<ol>
<li>Figure out just enough of the language to express runtime assertions from outside your application code</li>
<li>Test-drive <em>in order to learn the language faster</em></li>
</ol>
<h3>Conclusion</h3>
<p>You don't need a fancy tool to apply <span class="caps">TDD </span>concepts. You might want <span class="caps">TDD </span>concepts to accelerate your learning — <a href="https://twitter.com/schmonz/status/335484769527812099">even when what you're learning is a new programming language</a>.</p>
CodeMash 2014: Developing Classical Musictag:www.schmonz.com,2014-01-10:ed4417a7059b5d1ff91904645c482f4b/2f7ddf98a26d5b72081ee62cc80487b7Amitai Schlair2014-01-14T06:13:15Z2014-01-14T06:13:15Z
<p><em>Schmonzcast #16</em>: Like <a href="https://schmonz.com/2013/01/22/codemash-2013-your-dev-toolbox-everywhere/">last year</a>, I gave a <a href="http://lightningtalks.codemash.org/">lightning talk</a> at this year's CodeMash. Unlike last year, I didn't prepare any speaking notes, just basic bullet-point slides — and to hear how I sound without rehearsing the talk at all, I didn't rehearse the talk at all. I was hoping for “more relaxed” without too much “less polished”; I wound up with some of both. Somehow it added up to the <a href="https://schmonz.com/2014/01/14/codemash-2014-developing-classical-music/20140109-developing-classical-music.mp4">allotted six minutes</a> (or <a href="http://youtu.be/iOQxqW8u5qE">watch on YouTube</a>), down to the second. This rapidly-congealed, never-practiced short talk is not profoundly great, but I bet the roomful of programmers found the content reasonably interesting, and I know it was good for me to practice a looser approach to public speaking.</p>
<ul>
<li><a href="https://schmonz.com/2014/01/14/codemash-2014-developing-classical-music/slides/developing-classical-music.pdf">Slides</a></li>
</ul>
Two interviewstag:www.schmonz.com,2013-12-17:ed4417a7059b5d1ff91904645c482f4b/2024ebd28333a6f068180a3b56a3b06bAmitai Schlair2014-02-12T15:56:12Z2013-12-17T17:27:49Z
<h3><span class="caps">BSD</span> Now (2013/11/20)</h3>
<p><a href="https://www.bsdnow.tv"><span class="caps">BSD</span> Now</a> has been podcasting weekly since its inception in September. Each show (recorded before a live <span class="caps">IRC </span>audience) includes <span class="caps">BSD</span>-related news, listener feedback, a tutorial, and an interview. You can see me being interviewed via Skype about <a href="http://www.netbsd.org">NetBSD</a> and <a href="http://www.pkgsrc.org">pkgsrc</a> as part of the <a href="https://youtu.be/bkP0LvsbqSg?t=1072">November 20 episode</a>, starting around 17:52.</p>
<h3>UGtastic (2013/11/09)</h3>
<p><a href="https://www.ugtastic.com">UGtastic</a> produces “an ongoing series of conversational interviews with people who make technical communities interesting.” Since <a href="http://scna.softwarecraftsmanship.org">Software Craftsmanship North America</a> was full of such people, <a href="https://twitter.com/just3ws">Mike Hall</a> brought his portable studio to the Mid-America Club, on the 80th floor of the <a href="https://en.wikipedia.org/wiki/Aon%5FCenter%5F%28Chicago%29"><span class="caps">AON</span> Center</a>, and set up shop in a quiet room facing Lake Michigan. I'm hardly the reason NetBSD and pkgsrc are interesting, but I felt strongly that they intersect with <a href="https://en.wikipedia.org/wiki/Software%5Fcraftsmanship">software craftsmanship</a> as espoused at the conference and as valued by its attendees. So I had lots more to say, and felt more comfortable saying it, when Mike interviewed me in person at <span class="caps">SCNA </span>for a standalone <a href="https://www.ugtastic.com/interviews/software-craftsmanship-north-america-2013-amitai-schlair">episode of UGtastic</a>.</p>
Global Day of Code Retreattag:www.schmonz.com,2013-12-13:ed4417a7059b5d1ff91904645c482f4b/60b6f6678de6f32da05a67fee9e9640dAmitai Schlair2013-12-17T17:28:04Z2013-12-13T14:12:19Z
<p>Last month in Chicago, the day before <a href="http://scna.softwarecraftsmanship.org">Software Craftsmanship North America</a>, <a href="http://www.8thlight.com/">8th Light</a> held a “Code Retreat”. My vague impression of <a href="http://coderetreat.org/about">Code Retreat</a> (which I'd heard of before, probably at <a href="http://codemash.org/about">CodeMash</a>) was that it would prescribe a relatively straightforward programming problem, so that we could focus instead on what's going on in our heads when we solve problems, so that we could consider alternative approaches, and to these ends there'd probably be lots of <a href="https://en.wikipedia.org/wiki/Pair%5Fprogramming">pair programming</a>. The name “Code Retreat” would prevent anyone from showing up who wouldn't want to attend something called “Code Retreat”. It would be a day for a roomful of programmers, working together, to get better at programming. I signed up.</p>
<p>My vague impression wasn't far off: the assignment was the old chestnut <a href="https://en.wikipedia.org/wiki/Conway%27s%5FGame%5Fof%5FLife">Conway's Game of Life</a>, there were five 45-minute pair programming sessions, and the goal was not to solve the whole problem in 45 minutes (fat chance!), but rather to practice solving various parts of the problem under varying constraints. At day's end, I would not be delivering code. I would be delivering my brain in an improved state.</p>
<h3>How to make 45 minutes disappear</h3>
<p>The first session was simple: remember what it's like to pair with a stranger, possibly use or explain an unfamiliar programming language, load the problem into our heads, solve some of it, and throw away our halting attempt. In this and two other sessions, I “drove” in Perl, a language with which my navigators were unfamiliar. I found it satisfying to offer an existence proof that a test-infected programmer with well-configured tools can develop in Perl as quick-deliberate-ly as we expect from newer, trendier languages, and that the result — were it to live long enough to be judged in production — might well exhibit all the hallmarks of happily maintainable code.</p>
<h3>If it's good, do more of it</h3>
<p>I found the two sessions in which I was more of a “navigator” more satisfying still. By some combination of the role itself, languages unfamiliar to me, the particular constraints assigned, and my pairing partner, these were the sessions in which I most memorably felt my own learning. In one, iterations could last no longer than 2 minutes: the guy who actually knew Ruby wrote a test, and if I made it pass before time ran out, we could commit it, else revert (!). For the first few iterations, we didn't slice thin enough, and weren't close; for the next few, my understanding of Ruby syntax was the bottleneck that made things exciting; and by the last few, we had mastered the art of the tiny increment. Besides spending a little time with Ruby, the value for me in this session was to consider what happens when we take a familiar <span class="caps">TDD </span>practice <a href="http://c2.com/cgi/wiki?ExtremeProgrammingCorePractices">to the extreme</a>, and thereby to reconsider the meaning and utility of increments.</p>
<p>In the other of the two sessions, we weren't allowed to speak, because we were adversaries. Our communication channels were the compiler and the tests, no more, no less. The guy who actually knew C# wrote a test, and I could write whatever stupid/clever code I wanted, as long as it made the test pass. He'd write a test in reaction to my best stupidity/cleverness to make it harder for me to do that. A few tests in, it was considerably easier to write sensible code than dumb/clever code. Halfway through, we switched roles. I wrote a test to spot-check cell states in a sample grid; he noticed a pattern in the input data that he could exploit to pass the test, not via row-column access, but with modular division. We were off to the evil races. Time ran out, not a moment too soon, as he set about overriding the definition of <code>Object.Equals()</code>. Being unable to speak forced us to express intent through our tests. Being adversaries forced us to maximize the clarity of our intent. This is a familiar function of a test suite, with (as before) the knobs turned all the way up.</p>
<h3>More learning, please</h3>
<p>After a full day of pair programming, I realized I'd been missing something important in my life. Nobody at Code Retreat needed to be told why <span class="caps">TDD </span>or pairing are valuable practices. We were all practitioners, we all knew why and how, we all wanted to get better. The contrast with my day-to-day was striking: so many shared values, so much overlapping knowledge, so little friction. It felt terrifically energizing to swap expertise with people whose expertise meaningfully relates to mine. I'm reshaping my day-to-day to include more of this. (More in an upcoming post.)</p>
<p>In summary, Code Retreat was like I expected, but better, and I liked it so much I'm doing it again tomorrow. <a href="http://globalday.coderetreat.org/">Global Day of Code Retreat</a> is tomorrow, December 14. I'll be participating in <a href="http://coderetreat.org/events/global-day-of-coderetreat-2013-frankfurt-am-main-germany">Frankfurt</a>. If you're a programmer who wants to sharpen your skills, no matter where in the world you are, I hope you'll consider attending a Code Retreat.</p>
<p><span class="caps">P.S.</span> There's also a <a href="http://legacycoderetreat.typepad.com/">Legacy Code Retreat</a> format which I hope to experience someday. In the meantime, I <a href="https://github.com/jbrains/trivia/pull/21">ported its terrible code to Perl</a>, which was <a href="https://twitter.com/schmonz/status/397100246062223360">strangely hard for me</a>.</p>
A Premeditated Improvisationtag:www.schmonz.com,2013-11-15:ed4417a7059b5d1ff91904645c482f4b/78e5256097fff7792ddc5c10fec5246cAmitai Schlair2013-11-21T14:53:35Z2013-11-15T14:33:49Z
<p><em>Schmonzcast #15</em>: Last night was the 28th Annual <a href="http://www.wikicu.com/Joyce_Kilmer_Memorial_Bad_Poetry_Contest">Alfred Joyce Kilmer Memorial Bad Poetry Contest</a>. Since discovering it (and the Philolexian Society) <a href="https://schmonz.com/2005/11/18/school-for-the-poetically-declined/">as a Columbia freshman in 2005</a>, I've attended every year save one. In my statesmanlike role <a href="https://schmonz.com/2007/11/16/explosion-at-the-poem-factory/">as a past laureate</a>, it is <em>de rigueur</em> that I reliably make a good showing. Here's the text of my entry and the <a href="https://schmonz.com/2013/11/15/a-premeditated-improvisation/20131114-kilmer-premeditated-improvisation.mp3">audio of my performance</a>.</p>
<p><em>On The Late Elinor Ostrom, Distinguished Professor At Indiana University, Which Is A University in Indiana, Which Is A Place That Exists, At Least Last I Checked, Which Illustrates The Epistemological Limits Placed On Human Knowledge Without Even Having Gotten Past The Title, So Check This, Because I'm About To Blow The Goddamn Doors Off Your Mind: A Premeditated Improvisation</em></p>
<p>by Amitai Schlair, GS '09, 2007 Poet Laureate</p>
<p><em>(inspired by “An Untitled Poem” by Everett Patterson, CC '06, 2003-04 Poet Laureate)</em></p>
<p>Elinor<br />
Elinor Ostrom<br />
Elinor Ostrom Ostrom<br />
Ostrom</p>
<p>Elinor Ostrom, you were an economist<br />
Milliner nostrum, willing colostrum<br />
Toast in her oven, osh kosh b'gostrom,<br />
Jellybean estrus, billionaire ostrich</p>
<p>Melon or onion? Colostomy instrument<br />
Excrement increment, Pandora's boxtrom<br />
Bloomington Bloomington Indianomically<br />
Estimate, aestivate, inner astronomy</p>
<p>Elinor Ostrom, economostrum<br />
Public choice theory phenomenostrom<br />
Nobel Prize winner, <em>per aspera ad astra</em><br />
Elinor, add sarsaparilla to blossom</p>
<p>Elinor Ostrom, Elinor Ostrom,<br />
Estrellanor Indianapolostrom<br />
Anchorbutt rancorous wankernut rostrum<br />
The budget shows us running Attention Deficit Disostrom</p>
<p>Elinor Ostrom, when you existed, you had been a person<br />
So far as we know.</p>
Working from everywheretag:www.schmonz.com,2013-10-13:ed4417a7059b5d1ff91904645c482f4b/db7516ebb01db3afa71a55013a76f5b7Amitai Schlair2014-03-29T14:26:17Z2013-10-17T05:21:43Z
<h3>Some offices I know</h3>
<p><img src="https://schmonz.com/2013/10/17/21.jpg" width="432" height="324" class="img" /></p>
<p>When I'm at the corporate office in midtown Manhattan, I have what I need to do my job effectively. Well, mostly. For one thing, I don't have <a href="http://www.joelonsoftware.com/articles/BionicOffice.html">a room with a door I can close</a>. But telephone-based interruptions come with such frequency that my noisy surroundings aren't the bottleneck to peacefully and quietly getting my work done. Okay, that first sentence was a lie. But it was a well-meaning lie. And in the end, isn't that the real truth? <a href="http://www.youtube.com/watch?v=in9Qdzxc1HM">The answer is: no</a>.</p>
<p>When I'm at the home office in <a href="http://www.urbandictionary.com/define.php?term=Upstate%20Manhattan">upstate Manhattan</a>, I have my pick of rooms with doors I can close. One of them has a 30” monitor and a whiteboard. Another has a recliner. Another has a burr grinder, a temperature-controlled electric kettle, and an AeroPress. The sun streams in from the south and west, <a href="https://scontent-ord1-1.xx.fbcdn.net/hphotos-xap1/v/t1.0-9/267573_931812233652_1258291_n.jpg?oh=5bbb1f0e08f481d0d41bf72042b9f74d&oe=57416C6D">setting over the George Washington Bridge</a>, New Jersey Palisades, Hudson River, Fort Washington Park, and what is by far the <a href="https://scontent.xx.fbcdn.net/hphotos-xap1/v/t1.0-9/23522_695557839352_1757527_n.jpg?oh=e8320b90f664683eaf51896954f95888&oe=576F63EF">largest of three better-than-bean-bag chairs</a>.</p>
<p>It's not as idyllic as it sounds. Construction — with a particular emphasis on jackhammers — has been <a href="http://www.columbiaspectator.com/2012/04/06/cb12-hears-plans-new-medical-center-education-building">proceeding right outside</a> for at least a year. At what feels like the exact same time, the unit above mine became inhabited by a small but heavy-footed child who has appropriated the railroad apartment's hallway as a training ground for the 2028 Summer Olympics.</p>
<p>But every jackhammer and sprint trial must occasionally come to a fleetingly temporary halt, and on the best days my home office is a truly great working environment, with near-ideal conditions for accomplishing tasks that require solitude and concentration. And on more typical days, when my schedule's dotted with meetings and the pavement's dotted with machines, the home office still wins for utility: while on a call, I can simultaneously be looking out the window at what passes for nature in these parts, or folding laundry, or pacing freely — and, I hope, lightly — to induce my mental gears to turn. The corporate office is superior for exactly two purposes: spending quality time with coworkers, and pressing the power switch on the computer at my desk. Otherwise it's noisier, distractier, further away from my softest pieces of furniture, and nowhere near persnickety enough about coffee.</p>
<h3>Places of work</h3>
<p>For the last several years I've been working from many locations, not just these two. I started working from anywhere because I could; I've continued working from anywhere because I've needed to.</p>
<p>Working from anywhere is not new. There exist successful companies designed around the idea. The organizational design typically includes such features as <a href="http://gettingreal.37signals.com/ch07_Meetings_Are_Toxic.php">asynchronous</a> <a href="http://37signals.com/svn/posts/2888-real-time-vs-slow-time-and-a-defense-of-sane-work-hours">communication</a> and <a href="http://zachholman.com/posts/how-github-works-hours/">distributed</a> <a href="http://zachholman.com/posts/how-github-works-asynchronous/">version</a> <a href="http://zachholman.com/posts/how-github-works-creativity/">control</a>. These working conditions reliably provide for the basic needs of the self-motivated programmer, enabling productivity in a wide range of environments and timezones.</p>
<p>I work for a company designed around employees who work from anywhere — but it's not a software company, my job is only occasionally to be a programmer, and the working conditions available to me necessarily reflect very different organizational constraints. So the lessons of GitHub, 37signals, and their ilk have been of limited applicability to my situation. By trial and error, I've come to understand that there isn't a single environment that best enables my productivity across a wide range of tasks, but rather environmental choices for me to make that depend primarily on what I'm trying to get done. Armed with a set of highly portable mix-and-match tools, I'm productive from nearly anywhere.</p>
<p>Besides the corporate office in midtown and my home office uptown, I work fairly frequently from such locations as:</p>
<ul>
<li>Homes of friends and family</li>
<li>Coffeeshops and libraries</li>
<li>In-between places (planes, trains, buses, cars I'm not actively driving)</li>
</ul>
<p>Having the option to work from places that aren't “the office” is freeing. When I choose to exercise the option, I'm choosing to manage my work needs using my personal resources. As this post will illustrate, I'm comfortable making that commitment. When it's up to me how to get my work done, I get more done.</p>
<h3>Types of work</h3>
<p>My professional time is divided between two modes of operation:</p>
<ol>
<li>Communicating (in-person meetings, phone meetings, instant messaging, emailing)</li>
<li>Thinking (planning, designing, testing, implementing)</li>
</ol>
<p>My company has a meeting-heavy culture. My team is expected to deliver software anyway. I've been throwing my body in front of oncoming meetings with the hope that in so doing, I'm saving the rest of the team from my fate. It mostly works.</p>
<p>A few of my meetings have a critical mass of people in the same building, or are one-on-ones. Naturally, I strongly prefer to attend these in person whenever possible. Most of my meetings are conference calls involving people from multiple locations. They frequently involve observing someone's shared screen over the network, or sharing mine with others.</p>
<p>A great meeting can lead to insights I wouldn't have arrived at on my own. When this happens, it's gratifying to be part of a conversation that led to a better outcome. In the aggregate, however, meetings take me out of the mental state in which I may arrive at insights. This wouldn't matter much if it weren't part of my job to be insightful, but it is, so it does.</p>
<p>When the task to be done requires extended concentration, I need a block of time during which I feel confident I won't be interrupted. During business hours, I approximate this by blocking out the time on my calendar (with a self-scheduled meeting!) and not opening instant messages or email. Our culture of meetings ensures that this is only an approximation, because new meetings can — and often do — appear on my calendar at any time, such as at the last minute. The phone can always ring. And if I'm in the corporate office, my shoulder can always receive a tap. So on the occasions when I must concentrate in order to be efficient and careful, I schedule the task for non-business hours. In this regard, the high cost of meetings is mitigated somewhat by the flexibility to work from home.</p>
<h3>Examples of workdays</h3>
<h4><span class="caps">NYC</span>: in-person meetings</h4>
<p>Go to the office (usually midtown, occasionally downtown).</p>
<h4><span class="caps">NYC</span>: early meetings and/or several contiguous meetings</h4>
<p>Stay at the home office. As needed, make <a href="https://tonx.org/082d613a">really good coffee</a>, look out the window, pace up and down the hall, etc.</p>
<h4><span class="caps">NYC</span>: no meetings</h4>
<p>Rejoice, for this day is special. Block out the calendar. Stay at the home office (or, on occasion, join a coworker at his preferred coffeeshop). Think through designs and plans and/or write code.</p>
<h4>Bloomington: many meetings</h4>
<p>Work from Bekki's place, in a room where I can close the door. Make my own coffee.</p>
<h4>Bloomington: few meetings</h4>
<p>Work on campus at the open workspace in the business school. For coffee and snacks, go down the hall. For meetings, duck into one of the small private conference rooms with doors that lock.</p>
<h4>Bloomington: no meetings</h4>
<p>Rejoice, for this day is special. Block out the calendar. If it's nice out, maybe stay at Bekki's place and spend some of it outside. Otherwise, go to a coffeeshop. Think through designs and plans and/or write code.</p>
<h4>Visiting my parents</h4>
<p>If no meetings, work from parents' house or public library (both of which have coffee). If meetings, go to the Northbrook branch office, convince them I'm really from corporate, and set up in an unused room.</p>
<h4>Visiting Bekki's family</h4>
<p>Bring IP phone from home office to Germany. Set up a desk upstairs. For fancy coffee, go downstairs. If meetings, beware timezones: I may not be off the phone and able to sleep till after midnight.</p>
<h3>Requirements of work</h3>
<p>For all professional purposes: <a href="https://scontent-ord1-1.xx.fbcdn.net/hphotos-xaf1/v/t1.0-9/35860_717095303102_3803394_n.jpg?oh=68f93d543122d323d82debc39c341fff&oe=576B2AB8">good coffee</a> (or at least coffee).</p>
<p>For quick phone calls: company-issued cell phone, reliable cell coverage.</p>
<p>For basic phone meetings: all of the above, minimal background noise, privacy.</p>
<p>For presentations or deeper discussions: all of the above, hands-free headset, laptop, reliable low-latency network access.</p>
<p>For designing, planning, and programming: laptop, reliable low-latency network access, external display.</p>
<p>For working in noisy places: all my music, over-the-ear headphones.</p>
<h3>Tools of work</h3>
<ul>
<li><a href="https://tonx.org/082d613a">Tonx coffee</a></li>
<li>Avaya 4620 desk phone and Plantronics <span class="caps">CS55 </span>wireless headset for calls at the home office</li>
<li>Verizon Blackberry Bold 9930 (company-issued) and <span class="caps">MEE</span>lectronics Air-Fi <span class="caps">AF32</span> Bluetooth Headset for calls and email away from home</li>
<li>iPod classic and the <span class="caps">AF32 </span>headset for music</li>
<li><span class="caps">AT&T </span>iPhone 5 for backup internet (via tethering) and phone (with MaxBoost Atomic Air battery pack)</li>
<li>Jawbone Jambox for speakerphone and music away from home</li>
<li>Jawbone Era for calls while driving (hardly ever happens)</li>
<li>11-inch MacBook Air for general-purpose remote computing with Unix (via <span class="caps">SSH</span>) and Windows (via Citrix) systems<ul>
<li>Quirky PowerCurl for compact power-cord transport</li>
<li>RadTech ScreenSavrz for screen protection and cleaning</li>
</ul>
</li>
<li>iPad 4 as <a href="https://scontent-ord1-1.xx.fbcdn.net/hphotos-xpf1/v/t1.0-9/263634_10100548973489522_1068458150_n.jpg?oh=97e41c79429b8798719143b418001813&oe=5742380B">my second monitor</a> (via <a href="http://avatron.com/apps/air-display">Air Display</a>)<ul>
<li>Smarter Stand for flexible positioning</li>
</ul>
</li>
<li>Tabletote Plus portable desk</li>
</ul>
<p>The 11” MacBook Air is a perfect fit for buses, trains, and planes: the screen is short enough to tilt far back enough to see comfortably, and the keyboard is far enough away to type comfortably. At a desk, the iPad with Air Display adds screen real estate. All of the above gadgets (minus the desk phone and desk) fit into my <a href="http://www.tombihn.com/PROD/TB0221.html">Tom Bihn Ristretto</a>. If I need the desk, I use the <a href="http://www.swissarmy.com/us/en/Products/Travel-Gear/Backpacks-%26-Messengers/Big-Ben-with-Security-Fast-Pass/p/31322301">Victorinox Architecture 2.0 Big Ben</a> backpack (link is to 3.0) instead. If I just need the laptop and some tunes, I carry the <a href="http://goincase.com/shop/incase-sling-sleeve-for-macbook-air-11">InCase Sling Sleeve</a>.</p>
<p>Since I can bring my own desk and internet access, the technical limit to how long I could work while sitting in the middle of a field had been the battery life of my laptop. No longer: I just upgraded from the late-2010 MacBook Air to the mid-2013 (which is what prompted me to write this post). I don't usually work from fields, though, so the practical upshot is that when I go to a coffeeshop for the day, I no longer need to worry about bringing a power cord or finding an outlet.</p>
<h3>An exhortation</h3>
<p>Working from everywhere requires discipline, internal motivation, self-observation, and control over your environment. If you know what you need and you know you've got it, you can do anything. Go forth and be productive!</p>
Weights, rates, and datestag:www.schmonz.com,2013-09-22:ed4417a7059b5d1ff91904645c482f4b/7016bf6aafc29399947212cc40a11f4cAmitai Schlair2014-01-18T19:06:15Z2013-09-22T16:37:43Z
<p>Of the <a href="https://schmonz.com/2013/02/26/how-to-maybe-lose-45-pounds-in-a-year/">45 pounds to be shed</a>, 26 have left me. Of the 352 days allotted to the project, 250 have gone by. A bit less than 2/3 the goal, in a bit more than 2/3 the time, means I'm slightly behind schedule — assuming the schedule isn't totally arbitrary, which it is. When I invented the schedule, I knowingly made at least two simplifying assumptions that were false-ish (i.e., not definitely true):</p>
<ol>
<li>Weight loss is linear</li>
<li>A year is enough</li>
</ol>
<p>Let's look at the chart.</p>
<p><img src="https://raw.github.com/schmonz/health/59aa943c516dd2f95c1e9ae55a9fdcae7b068570/burndown.png" alt="" /></p>
<p>Legend:</p>
<ul>
<li><strong>Black diagonal line from upper left to lower right:</strong> the schedule</li>
<li><strong>Red line with absurd spikes when no scale is available:</strong> daily weigh-ins</li>
<li><strong>Artisanal scientistic hand-laid blue arrows:</strong> rough trends</li>
</ul>
<p>I suppose I could force my weight loss to look “linear” by drawing a blue arrow straight from day 1 to today, but I wouldn't learn much, because I'm already an arrow-drawing expert. Also I wouldn't learn much about the data.</p>
<p>The schedule was concocted on the assumption that I could lose 45 pounds in a year: in other words, that I could sustain an average loss of almost 4 pounds per month for 12 months. Other than previously having comfortably weighed 200 pounds, and feeling intuitively that the timeline was neither reckless nor impossible, my assumption had no basis in reality. It was, and is, arbitrary.</p>
<p>So I neither feel bad about being slightly behind “schedule” nor feel good about being fairly close to it. What feels good is that I'm making progress toward a worthwhile goal and, more important, that I feel good. Not great — there's much more athleticism to be regained yet — but <em>good</em>. Since <a href="https://schmonz.com/2013/08/01/losing-learning-and-winning/">I last wrote</a>, there's been another qualitative change. In addition to my face looking like my face, my body looks and feels way more like my body. I was able to wear one of my suits to work last week. It was nice.</p>
<p>As you can see from the chart, I've been doing pretty well lately. As usual, there are many possible reasons, and I probably won't get to know exactly which are responsible:</p>
<ol>
<li>Had a cold, was briefly healthy, then had something flu-ish</li>
<li>As a result, haven't worked out regularly for a month and a half (only three sessions since August 7)</li>
<li>After the one post-cold workout, ate carbohydrate for the first time in a couple months (maybe helped kick my metabolism? maybe helped me get sick? both?)</li>
<li>Was on vacation for two weeks (during which several people noted how relaxed I sounded!), followed by greater-than-usual work stress, followed by returning to <span class="caps">NYC</span></li>
<li>Been eating lots of seafood recently (salmon, flounder, cod, scallops, always with plenty of butter), and more coconut (oil and meat)</li>
</ol>
<p>The weight I'm losing may be muscle, since I haven't been working out much. If that's what's happening, fine by me. On net, I'm still stronger than 250 days ago. Plus, gaining muscle is not this year's goal, merely a <a href="https://schmonz.com/2013/04/28/strength-gains-and-weight-loss-after-30-workouts/">means to the end of weight loss</a> — and it appears to be functioning for the intended purpose. Once I reach my goal weight, I can set new goals; body composition will almost certainly be among them. Meanwhile, from here to 200 pounds, I'll probably work out less intermittently than I have been, but still less regularly than I had been before.</p>
<p>Everyone knows the last few pounds are the hardest to lose. I'm not there yet, but my chart suggests I should expect another upward-sideways zig soon. I'm not worried, because a giant blue arrow would show that I'm moving in the right direction. And even though I weigh less, I've become harder to stop.</p>
Words with friends (and everyone else)tag:www.schmonz.com,2013-09-16:ed4417a7059b5d1ff91904645c482f4b/b36810dd735b24744a4bb39b20126a54Amitai Schlair2014-09-12T01:36:02Z2013-09-17T03:23:30Z
<p>I like people. I don't worry very much about this.</p>
<p>I like talking to people, but <a href="https://en.wikipedia.org/wiki/Extraversion%5Fand%5Fintroversion">it tires me out</a>. (Extraverts are often surprised to learn I'm not one of them.) I don't worry very much about this either. My energy gets budgeted well.</p>
<p>I like having deeply considered opinions about things that matter to me. (Maybe being introverted forced me to like this, or maybe the other way around, or a little of both.) I don't usually worry very much about this. It's valuable to know my reasons for thinking what I think, and for those reasons to stand up to as much scrutiny as I and others can muster.</p>
<p>Some of my opinions have only been arrived at after extended expenditures of time and effort: for instance, my current opinions on nutrition, exercise, politics, and software development. So have everyone else's, of course. My particular opinions generally seem to be outliers, as it happens, but that's not <em>per se</em> what worries me.</p>
<p>What worries me is that if I strike up a conversation with a random reasonably intelligent person and talk about our opinions, on average I'm going to find it a very frustrating conversation. That's true for many reasonably intelligent people, of course. But I have reason to speculate — not only because my opinions are outliers but because of how I arrived at them — that my average frustrating conversation is more frustrating than average. And even if that's not the case, I've learned (at least in part) to not want to have these conversations.</p>
<p>What worries me is that my introversion, combined with my specialized opinions that are usually fruitless to discuss with others, may be a vicious spiral. I'm worried that I'm making it more and more energy-costly for me to talk to people, more and more empathy-costly for people to talk to me, and less and less likely for me to have enough conversations with enough people to keep improving as a human being.</p>
<p>What can I do about it?</p>
<ul>
<li>When I need my opinions to matter, I seek relatively like-minded people with whom conversations feel mutually rewarding. (Primary danger: <a href="https://en.wikipedia.org/wiki/Filter%5Fbubble">filter bubble</a>.)</li>
<li>When I don't need my opinions to matter, I talk less and listen more. (Primary danger: <a href="https://en.wikipedia.org/wiki/Learned%5Fhelplessness">learned apathy</a>.)</li>
<li>When I'm feeling somewhere in between, I choose interlocutors more wisely, and choose how much conversational energy to expend on them more carefully. (Primary danger: underestimating myself or others.)</li>
<li>I try to do work that takes away some of my freedom of choice about who I talk to and how much talking is needed. (Primary danger: takes too much.)</li>
</ul>
<p>What else can I do to stay connected to people and have them stay connected to me? I can ask you for ideas. Hey, I just did!</p>
TDD by example: an ikiwiki featuretag:www.schmonz.com,2013-08-22:ed4417a7059b5d1ff91904645c482f4b/22d2035b111d98cea382d689d733de39Amitai Schlair2013-08-23T22:37:36Z2013-08-22T23:40:52Z
<p>In <a href="https://schmonz.com/2013/08/20/tdd-by-example-an-ikiwiki-bugfix/">my previous post</a> I gave an example of the benefits of fixing a bug by first writing a test. Even if my example had actually shown such a test, bugfixing isn't the archetypal <span class="caps">TDD </span>scenario. Most people — including me — primarily think of Test-Driven Development as a way to develop new features.</p>
<h3>Some context</h3>
<p><a href="http://ikiwiki.info//">Ikiwiki</a> isn't only for wikis. It's a fairly general-purpose <a href="https://en.wikipedia.org/wiki/Web%5Fcontent%5Fmanagement%5Fsystem">web content management system</a>.</p>
<p>In ikiwiki, any collection of pages can be turned into a <a href="https://en.wikipedia.org/wiki/Blog">blog</a>. What makes a typical blog? Posts sorted by date, newest first, with a <a href="https://en.wikipedia.org/wiki/Web%5Ffeed">feed</a>. People using <a href="https://en.wikipedia.org/wiki/Feed%5Faggregator">feed-reading software</a> can subscribe to the feed and receive new posts automatically.</p>
<p>A podcast is a blog that contains <a href="https://en.wikipedia.org/wiki/RSS%5Fenclosure">media enclosures</a>. Since it's a blog, any feedreader can display it; since it's a special kind of blog, a specialized kind of feedreader can download and manage enclosures. The best-known <a href="https://en.wikipedia.org/wiki/Podcatcher">podcatcher</a> is probably iTunes.</p>
<p>In ikiwiki, any blog post that can't be transformed into <span class="caps">HTML </span>— say, an <span class="caps">MP3 </span>— is published as is. Browsers see it as a link, feedreaders see it as an enclosure, and podcatchers can automatically download it.</p>
<p>Ikiwiki's support for publishing podcasts was pretty cool. I needed it to be cooler.</p>
<h3>The feature</h3>
<p>This website is mostly just a blog, but <a href="https://schmonz.com/2007/01/15/the-schmonzcast-begins/">also a podcast</a>. I'd really <a href="https://schmonz.com/2013/05/27/remembering-textpattern/">like to be publishing it with ikiwiki</a>.</p>
<p>Most podcasts (mine included) accompany every episode with descriptive “show notes”. Ikiwiki could only produce blog posts that were either text or media. I wanted it to be able to produce posts with both. In order to migrate smoothly, I also wanted to reach <a href="http://www.rainskit.com/reference/540/tru_podcast-feature-list">feature parity with tru_podcast</a>.</p>
<h3>The design</h3>
<p>To post a new podcast episode in Textpattern with <a href="http://www.rainskit.com/blog/542/tru_podcast-a-podcasting-plugin-for-textpattern">tru_podcast</a>, after some one-time setup, I write an article, upload an <span class="caps">MP3, </span>and give the article a particular kind of reference to the <span class="caps">MP3.</span> I find the workflow sensible and comfortable, modulo being forced to write in the browser, upload a large file out of band, and obtain Textpattern's unique identifier for the file.</p>
<p>Ikiwiki has a <code>[[!meta ]]</code> directive for defining metadata about a page. If I were to invent an <code>enclosure</code> parameter that let me write <code>[[!meta enclosure="WikiLink/to/media.mp3"]]</code> in a podcast post, ikiwiki would have enough information to produce my desired output from much simpler input.</p>
<h3>The implementation</h3>
<h4>Compatibility</h4>
<p>Before I went and changed anything, I needed to decide what should happen with ikiwiki's existing podcast behavior.</p>
<ul>
<li>Did my new idea replace the old? No, it wasn't a strict superset.</li>
<li>Could I break the old way a little if I needed to? Preferably not, because people (including me) were using it.</li>
<li>Would I need to break the old way? Glancing at the code, I didn't think so.</li>
<li>Would I able to tell for sure whether I'd broken it? Not easily enough.</li>
</ul>
<h4>A safety net behind me</h4>
<p>My first step, therefore, was to <a href="http://source.ikiwiki.branchable.com/?p=source.git;a=commitdiff;h=116f206">write automated tests</a> to <a href="http://source.ikiwiki.branchable.com/?p=source.git;a=commitdiff;h=d0862bc">cover the existing behavior</a>.</p>
<p>It's common and useful to think of these as regression tests, but when I'm adding tests for code that didn't have any — especially someone else's code — I prefer to think of them as <a href="https://en.wikipedia.org/wiki/Characterization%5Ftest">characterization tests</a>. I didn't know enough to decide whether the existing behavior was right or wrong, I just wanted to be sure to find out if I unintentionally changed it. With my <code>simple_podcast()</code> characterization tests in place, I felt safe about working in this area of the ikiwiki code.</p>
<h4>Throw a bit more net in front, take another step</h4>
<p>What behaviors would my new implementation demonstrate when complete? Ikiwiki would need to render pages containing the new <code>[[!meta enclosure]]</code> parameter…</p>
<ul>
<li>In browsers: as normal, plus an appended link to the media file</li>
<li>In feeds: with the text as the entry's content and the media file as its enclosure</li>
</ul>
<p>To figure out whether I was even on the right track, I <a href="http://source.ikiwiki.branchable.com/?p=source.git;a=commitdiff;h=cc0d875">wrote tests for a single <span class="caps">HTML </span>page</a> invoking my directive-to-be, then made the smallest possible changes to the <code>meta</code> plugin and to <code>page.tmpl</code> that caused the new tests to pass. When <code>single_page_html()</code> turned green — and <code>simple_podcast()</code> didn't turn red — I gained confidence in my understanding of ikiwiki and in my ability to take it where I wanted to go. A small first step, but it felt big.</p>
<h4>Iterate: generate internal links correctly</h4>
<p>My expansion of the new <code>enclosure</code> parameter was simplistic. I <a href="http://source.ikiwiki.branchable.com/?p=source.git;a=commitdiff;h=ac8aa3a">extended the tests to inspect the generated link</a>, then expanded the parameter's value as a <a href="http://ikiwiki.info/ikiwiki/wikilink/">WikiLink</a> adhering to the <a href="http://ikiwiki.info/ikiwiki/subpage/linkingrules/">LinkingRules</a>.</p>
<h4>Iterate: add documentative tests</h4>
<p>I wasn't quite ready to work on feeds yet, but I suddenly remembered that a feed entry can have no more than one enclosure, and I wanted to <a href="http://source.ikiwiki.branchable.com/?p=source.git;a=commitdiff;h=e2bf369">document what would happen</a> if a page tried to define more than one. No new code, just tests.</p>
<h4>Iterate: render links in inlined <span class="caps">HTML</span></h4>
<p>Ikiwiki generates blogs (and podcasts) with the <code>[[!inline ]]</code> directive, which combines multiple input pages into one output page. I <a href="http://source.ikiwiki.branchable.com/?p=source.git;a=commitdiff;h=aebd6c7">wrote tests to inline a few pages containing my new parameter</a> and look for the generated links. The tests failed. I figured out that it was because ikiwiki uses a separate template for inlined pages. Tweaking <code>inlinepage.tmpl</code> made the new <code>inlined_pages_html()</code> tests pass. The other tests continued to pass.</p>
<h4>Iterate: always generate absolute links</h4>
<p>In all the popular podcast feeds I'd inspected, enclosure <span class="caps">URL</span>s were always fully absolute, even when they could be expressed concisely as relative. <a href="http://www.apple.com/itunes/podcasts/specs.html#example">Apple's example</a> did likewise. So I <a href="http://source.ikiwiki.branchable.com/?p=source.git;a=commitdiff;h=3d2be49">wrote failing tests expressing this requirement</a>, and adjusted the code to make them pass.</p>
<h4>Iterate: extract method</h4>
<p>At this point, my code was generating the right links and displaying them in the browser. It was time to think about feeds. I could see that I was about to need to call ikiwiki's enclosure-generating code two different ways, so I <a href="http://source.ikiwiki.branchable.com/?p=source.git;a=commitdiff;h=a629b27">extracted it to a subroutine</a>, relying on my characterization tests to prove that I hadn't changed simple podcasts in any way.</p>
<h4>Iterate: render enclosures in feeds</h4>
<p>The quickest way to find out whether I could now generate <a href="http://ikiwiki.info/todo/fancypodcast/">fancy podcast</a> feeds was to <a href="http://source.ikiwiki.branchable.com/?p=source.git;a=commitdiff;h=d77ee60">munge a copy</a> of the <code>simple_podcast()</code> tests into <code>fancy_podcast()</code>. To make the new tests pass, I taught <code>[[!inline ]]</code> to look for the <code>[[!meta enclosure]]</code> parameter and pass it to the enclosure-generation subroutine I'd just extracted.</p>
<p>But the characterization tests had started failing! By populating <code><content></code> with the entry's text for fancy podcasts, I had unintentionally added an empty but non-null <code><content></code> to simple podcasts. Remember, the existing behavior was that a feed entry could be either text content or an enclosure, not both. Now there were both. I had changed behavior I hadn't meant to change. My characterization tests had done their job and notified me. I made the conservative choice and adjusted the code and <code>{atom,rss}item.tmpl</code> to preserve the existing behavior precisely.</p>
<h4>Iterate: style enclosures like content</h4>
<p>Ikiwiki includes a default style sheet and some themes. They needed to know how to <a href="http://source.ikiwiki.branchable.com/?p=source.git;a=commitdiff;h=984f2ab">style the new enclosure section</a>. The changes were simple enough to test manually. (As I was writing this article, <a href="https://twitter.com/jamesshore/status/370605785669042176">James Shore tweeted promisingly about <span class="caps">CSS </span>testing</a>.)</p>
<h4>Iterate: match <span class="caps">RSS </span>and Atom item metadata</h4>
<p>Previewing fancy podcasts on my phone, I noticed that ikiwiki's <span class="caps">RSS </span>and Atom feeds were slightly inconsistent. The <span class="caps">RSS </span>version of a podcast episode wasted valuable title space displaying the author first, when there's a perfectly good author field for that; the Atom version didn't. I <a href="http://source.ikiwiki.branchable.com/?p=source.git;a=commitdiff;h=e9f9a63">corrected <code>rssitem.tmpl</code></a>.</p>
<h4>Iterate: extract test method</h4>
<p>En route to fancy podcasts, I had made copypasta of my tests. The simple and fancy tests were <a href="http://anchorbutt.blogspot.com/2007/05/schmonzs-theorem.html">different, yet similar</a>. I <a href="http://source.ikiwiki.branchable.com/?p=source.git;a=commitdiff;h=2df57e9">extracted the common assertions and parameterized the differences</a>. No new code, no new tests, just refactored tests.</p>
<h4>Iterate: match <span class="caps">RSS </span>and Atom feed metadata</h4>
<p>I noticed that <span class="caps">RSS </span>feeds were missing some fields found in Atom feeds. I <a href="http://source.ikiwiki.branchable.com/?p=source.git;a=commitdiff;h=4b6ea05">filled in the blanks in <code>rsspage.tmpl</code></a> and checked the result in a feed validator.</p>
<h4>Iterate: manually test migration to fancy podcasts</h4>
<p>Fairly confident that the pieces were in place, I wanted to see <a href="http://source.ikiwiki.branchable.com/?p=source.git;a=commitdiff;h=313a094">what it would be like</a> to fancy up a simple podcast, and to move a podcast from another system (such as Textpattern) into ikiwiki. So I did. Both worked as I expected.</p>
<h3>The review</h3>
<p>I felt pretty good about my code: I knew it did good new things, I didn't think it did any bad new things, and at any rate it wasn't going to be a waste of anyone's time to look over my work. So I asked for review, and <a href="http://joeyh.name/blog/">Joey</a> <a href="http://ikiwiki.info/todo/fancypodcast/discussion/">provided it</a>.</p>
<h4>Feedback</h4>
<p>There were a handful of small tweaks I needed to make:</p>
<ul>
<li><a href="http://source.ikiwiki.branchable.com/?p=source.git;a=commitdiff;h=6a1cbe6">Don't add enclosure divs unless we have enclosures</a></li>
<li><a href="http://source.ikiwiki.branchable.com/?p=source.git;a=commitdiff;h=0c320f4">Genericize download link for more use cases</a></li>
<li><a href="http://source.ikiwiki.branchable.com/?p=source.git;a=commitdiff;h=e0ff81b">Don't confuse old readers with Atom names in <span class="caps">RSS</span></a></li>
<li><a href="http://source.ikiwiki.branchable.com/?p=source.git;a=commitdiff;h=b25f770">Instead of hacking back to $link, just provide it</a></li>
</ul>
<p>And there was one big one: I broke <a href="https://en.wikipedia.org/wiki/Planet%5F%28software%29">planets</a>. A “planet” is a site whose job it is to subscribe to a bunch of individual blogs and republish all of them as one big community blog. My changes to how ikiwiki makes podcasts (which are blogs) wound up having bad side effects on how ikiwiki makes planets (which are blogs). I fixed it by consistently applying the following rule to both <span class="caps">RSS </span>and Atom: <a href="http://source.ikiwiki.branchable.com/?p=source.git;a=commitdiff;h=97d0c09">if the blog's name and author are different, show both</a>.</p>
<p>There weren't tests to catch this, so it's a good thing Joey spotted it. I wasn't expecting to touch the planet code, but I'm happy I got a chance to improve it a bit.</p>
<h3>Pictured</h3>
<ul>
<li>A simple design</li>
<li>Tiny iterations</li>
<li>A careful implementation, driven by tests</li>
<li>One mistake the tests prevented me from making</li>
<li>Another mistake no tests prevented me from making</li>
<li>Some reasons why the discipline of <span class="caps">TDD </span>is valuable</li>
</ul>
<h3>Not pictured</h3>
<ul>
<li>Many other mistakes — in both design and implementation — the tests prevented me from making</li>
<li>The speed of the test-driven development cycle</li>
<li>The knowledge that, like simple podcasts, fancy podcasts won't get broken later by mistake</li>
</ul>
<h3>Significance</h3>
<p>My code has been merged upstream and will be in the next ikiwiki release. My tests were good enough to shape and prove out my idea, but some months later, I no longer fully understand them. Test code is just code, after all, subject to the same challenges of clearly expressing intent — and if tests' intent isn't clear now, they're not good tests now.</p>
<p>When I'm ready for my next round of ikiwiki podcast enhancements, I'll start by refactoring my test code until it's meaningful to me again. Then I'll know what I know, and iterate, and iterate.</p>
TDD by example: an ikiwiki bugfixtag:www.schmonz.com,2013-08-20:ed4417a7059b5d1ff91904645c482f4b/821d60eb2447efbf60930985a9aca55aAmitai Schlair2013-08-20T18:16:27Z2013-08-20T18:15:47Z
<p>I've written of my love <a href="https://schmonz.com/2013/08/08/why-i-practice-tdd/">for Test-Driven Development</a> and <a href="https://schmonz.com/2013/05/27/remembering-textpattern/">for ikiwiki</a>. Love is awfully abstract, though. Here's a concrete example.</p>
<h3>Some context</h3>
<p>Ikiwiki is a <a href="http://ikiwiki.info//">wiki compiler</a>. It transforms easy-to-write input files into easy-to-browse output files.</p>
<p>Since a wiki is <a href="https://en.wikipedia.org/wiki/Wiki%23Editing%5Fwiki%5Fpages">open for editing</a>, it's important to be able to <a href="https://en.wikipedia.org/wiki/Wiki%23Controlling%5Fchanges">see what changed recently</a>. Typical wikis provide their own limited way to view and compare a limited number of revisions. Ikiwiki <a href="http://ikiwiki.info/rcs/">integrates with many popular revision control systems</a>.</p>
<p>The integration is deep. Write in the browser, and saving an edit means making a commit. Write in the terminal, and committing to the repository means regenerating output files.</p>
<p>I developed and contributed <a href="http://ikiwiki.info/rcs/cvs/">ikiwiki's <span class="caps">CVS </span>integration</a> a few years ago. It's been in production use ever since.</p>
<h3>The bug</h3>
<p>On <code>cvs commit</code>, the commit succeeded and affected output was regenerated, but with a warning:</p>
<pre><code>Use of chdir('') or chdir(undef) as chdir() is deprecated at /usr/pkg/lib/perl5/vendor_perl/5.16.0/File/chdir.pm line 45.</code></pre>
<h3>How it got through</h3>
<p>The warning was introduced in Perl 5.12. I had written the code under Perl 5.10. (The warning appeared harmless, and I was busy, so Perl got all the way to 5.16 before I could deal with it.)</p>
<h3>How I came to understand it</h3>
<ol>
<li>Reproduced the problem by hand.</li>
<li>Extended my tests to automatically reproduce the problem.</li>
<li>Tried to reach understanding through thinking.</li>
<li>Succeeded at reaching understanding through debug <code>printf()</code>s.</li>
</ol>
<h3>How I fixed it</h3>
<ol>
<li>Tried some things that made the tests look good.</li>
<li>Kept the simplest one.</li>
</ol>
<h3>How it'll stay fixed</h3>
<p>If this were a canonical example of bugfixing with <span class="caps">TDD,</span> I would have written a test that fails if the warning appears and succeeds otherwise. Once the bug was fixed, that test would have magically become a regression test.</p>
<p>This isn't a canonical example of bugfixing with <span class="caps">TDD.</span> The bug manifested with ikiwiki as a post-commit hook, which my tests hadn't been covering. It took me a while to figure out how to wire up the needed integration in test. So when I started seeing the warning as a side effect of other tests, that was good enough for me at the time.</p>
<p>Writing these words spurred me to revalidate my previous judgment. I just tried reverting my fix and running the tests. As long as I don't run them verbosely — and I usually don't — the warning that reappears is very hard to miss. Still, I didn't write, and now don't have handy, a purpose-specific test that unambiguously fails if stderr matches the warning. That would be an obvious boon to future developers who don't know what I currently know (a set that includes me) or who don't always run the tests the way I mostly do (also a set that includes me), as well as a boon to the didactic value of this real-world example.</p>
<h3>Pictured</h3>
<p><a href="http://source.ikiwiki.branchable.com/?p=source.git;a=commitdiff;h=b30cacd">You can see</a> that I spent some time:</p>
<ul>
<li>Improving automated tests</li>
<li>Fixing a bug</li>
</ul>
<h3>Not pictured</h3>
<p>No code artifact can show you how much time I saved by:</p>
<ul>
<li>Making the computer tell me instantly whether I've solved the problem yet</li>
<li>Not needing to settle for a less elegant fix</li>
<li>Almost certainly never seeing this bug again</li>
</ul>
<h3>Significance</h3>
<p>As I've learned to expect, the up-front cost of making tests help me was nowhere near the benefit, especially over the long lifetime of production code. I'm pretty sure I got done faster (and better). If you write code for a living and you don't believe me, you owe it to yourself to question the basis of your belief.</p>
Why I practice TDDtag:www.schmonz.com,2013-08-07:ed4417a7059b5d1ff91904645c482f4b/36180c537a1f7caef69e77dce6616bfaAmitai Schlair2014-09-12T01:36:06Z2013-08-08T05:19:35Z
<p>When George Dinwiddie wrote recently about <a href="http://blog.gdinwiddie.com/2013/07/23/why-i-practice-tdd/">why he practices <span class="caps">TDD</span></a>, it made me think anew about why I do it. His explanation was <a href="http://anchorbutt.blogspot.com/2007/05/schmonzs-theorem.html">similar to, yet different from</a>, mine. The practical benefits he lists are old friends, and I probably feel a similar “freedom” to his, but something fundamental to my experience of Test-Driven Development is out of frame, not pictured. What, though? I couldn't pin it down. It wormed around in my brain, trying to find the exit.</p>
<p>Then Kent Beck offered <a href="http://twitter.com/KentBeck/status/364745180026384384">another way of valuing <span class="caps">TDD</span></a>, and immediately I was able to triangulate mine. I agree strongly with Kent, too: if I had to remember more than one or two things at any given time, I'd be a terrible programmer. But that's also not the strongest reason I write tests first.</p>
<p>I drive my development with tests, above all else, because it makes me do better thinking.</p>
<p>Like anyone involved in the development of software, my brain is full of assumptions and expectations based on working understandings. In my role as a developer, my expectations are derived from the customer's wants, and my assumptions are derived from the code's wants. These derivations are lossy. My understandings are imperfect. For as long as they're worming around in my brain, I don't know what's imperfect about them. I might even try to think I know exactly what to build and how to build it. Yikes.</p>
<p>Not an insight: when I write tests first, my tests are the first code to explicitly exercise the programming interface I'm designing. The tests help me negotiate what the interface needs by trying to use it, early and often.</p>
<p>Maybe an insight: when I write tests first, my brain is the first brain to explicitly exercise the expectation-to-assumption interface I'm designing. The act of writing tests first helps me negotiate what the interface needs by trying to use it, early and often.</p>
<p>I practice <span class="caps">TDD </span>because by forcing me to define a clear interface between my assumptions and my expectations, it flushes out inaccuracies in both.</p>
<p>I practice <span class="caps">TDD </span>because if my hypotheses haven't yet exited my brain, they can't possibly be meaningful hypotheses. Preparing to show them to other people forces me to formulate them precisely. Showing them to other people tells me how they might be wrong.</p>
<p>I practice <span class="caps">TDD </span>because it's the best way I know to deliver increments of shared understanding. As Agile as Agile gets.</p>
Losing, learning, and winningtag:www.schmonz.com,2013-06-25:ed4417a7059b5d1ff91904645c482f4b/82c42000ec3f9442cbadcc6f6047943aAmitai Schlair2013-08-07T21:38:02Z2013-08-02T02:03:26Z
<p>I claimed <a href="https://schmonz.com/2013/02/26/how-to-maybe-lose-45-pounds-in-a-year/">I would (maybe) lose 45 pounds this year</a>. I've been at it for over six months. What schemes and adjustments did I discuss with the team in the locker room at halftime?</p>
<p>Well, hang on. My thinking about nutrition, exercise, and weight loss seems to surprise some people. For me to have a chance of explaining my adjustments more convincingly than I explained my original plan, I'd better elucidate my thought process in this context. I have no pretense that what I'm doing is replicable science (especially since my girlfriend of several years is a scientist who just presented a talk at the <a href="http://animalbehaviorsociety.org/central-office/absco-news/abs-2013-university-of-colorado-boulder-28-july-2013-1-august-program-at-a-glance-available">Animal Behavior Society Conference</a>), but I do start by being as honest as I can about what I don't know, what I think I know, and why I think I know it.</p>
<h3>How I think about my hypotheses</h3>
<p>When someone devises a plan of action intended to reach a goal, they've formed a hypothesis about the causes needed to bring about the desired effects. If Bob doesn't realize he's formed a hypothesis, that doesn't mean he hasn't formed one: it means it's implicit, may not be well specified, and certainly hasn't been carefully considered. Bob's hypothesis could prove wrong for reasons that are forehead-slappingly obvious, or it could be so fuzzy that it <a href="https://en.wikipedia.org/wiki/Not%5Feven%5Fwrong">can't even be wrong</a>. In the former case some small amount of learning is possible; in the latter, zilch. In either case, has Bob arranged to make efficient use of his experience so that he can more reliably improve his results? No.</p>
<p>Conversely, if Alice is aware of the nature of her experiment, her hypothesis stands a much better chance of being wrong for interesting reasons. By recognizing what she doesn't know and would like to find out, she is forced to more directly confront and tolerate some amount of uncertainty, but her hypothesis is more likely to lead to meaningful learning.</p>
<h3>How I think about my conclusions</h3>
<p>When the context of a hypothesis is limited to a single person, drawing strong conclusions is difficult. The experiment necessarily has far too many uncontrolled variables and far too little data. Our bodies are incredibly complex machines about whose workings we are incredibly ignorant, further confounded by our unwillingness to admit as much. Many humans persist in believing that there is nothing more complicated about losing weight than eating less and moving more, despite mounds of evidence to the contrary. Imagine how ignorant we are in areas where there aren't mounds of evidence.</p>
<p>Any plan of action to lose weight makes a hypothesis that necessarily subsumes conjectures about how human metabolism works in general, how the particular person's metabolism works in general, what the current conditions of the person's metabolism are at the time of conjecture, and finally how the person's metabolism works under those particular conditions. I've hardly ever heard anyone frame their weight-loss goals in such terms. Many people's weight-loss hypotheses seem to be formed implicitly, so it's no surprise that they not only fail to lose weight, but also fail to learn anything interesting about why not.</p>
<h3>How I think about learning</h3>
<p>I don't want to fail. I don't want to fail at failing, either. But the learning that each iteration makes available to me is quite limited. The most extreme possible conclusions I can hope to safely draw after making a well-defined hypothesis about my personal health and observing for a while are:</p>
<ul>
<li>”It's mostly doing what I thought, possibly because my reasoning was right”</li>
<li>”It's mostly not doing what I thought, probably because my reasoning was wrong”</li>
</ul>
<p>Strong stuff. And of course, the most likely possible conclusion:</p>
<ul>
<li>”I can't tell what it's doing, for reasons I don't know and can barely guess”</li>
</ul>
<p>For a guy like me, this last outcome is a small but very palpable version of hell. When it happens, I'm able to tolerate it only after I've produced a new hypothesis that I believe is more likely to produce a conclusive result.</p>
<h3>How I feel</h3>
<p>Enough reading my writing about meta-thinking! Over halfway to 2014, how's it going for me?</p>
<h4>Clothing</h4>
<ul>
<li>T-shirts fit better</li>
<li>Beginning to have serious problems with my jeans and shorts</li>
<li>My nice work clothes are much easier to tolerate for a full day, and almost comfortable again</li>
</ul>
<h4>Appearance</h4>
<ul>
<li>My face looks like my face, whereas it used to look like something my face had been stuffed into</li>
<li>My butt must be less large, because in stadiums and subways I find it much easier to get out of someone's way</li>
<li>My belly continues to gently subside</li>
</ul>
<h4>Energy</h4>
<ul>
<li>Definitely less lethargic, especially considering what I'm usually like during the summer</li>
<li>I'm beginning to imagine what it'll be like when I can play a casual game of Ultimate, have fun doing it, and not be broken the next day</li>
</ul>
<h3>How I weigh</h3>
<p>On a bad day, 20 pounds lighter than when I started. On a good day, halfway to my goal, and my lowest weight in four years.</p>
<h3>How I plan to continue</h3>
<p>A month ago I was just about ready to change my goal. I hadn't lost weight in months, but I could tell my health was improving, I really liked my regimen, and I didn't want to change it to suit a goal that had been arbitrary in the first place. Then some pounds dropped off, and suddenly I was back within range of <a href="https://raw.github.com/schmonz/health/master/burndown.png">the chart's path</a>. And that reminded me of a change I was ready to try: go back to not eating carbohydrate after workouts. No carbohydrate whatsoever.</p>
<p>This is no different from how I was eating last year. If I didn't lose weight then, why should I expect to lose weight now? Because strength training for six months has built some muscle and almost certainly raised my resting metabolic rate.</p>
<p>It's possible that not eating carbohydrate after workouts will stall or even reverse some of my strength gains. I wasn't willing to accept that in January — or in May, when <a href="http://zooko.com/">Zooko</a> and <a href="http://www.empiri.ca/">Amber</a> suggested the idea — because I knew I needed to get stronger in order to be able to lose weight; I am willing to accept it now, because I've accomplished that step. Someday later, if I want, I can choose to make strength training an end in itself. For now, it's a means to lose weight (and feel good). As long as I keep most of the muscle I've built, the furnace will keep burning hot, and my belly fat will keep being recruited as fuel.</p>
<p>That's my current hypothesis, anyway.</p>
Area under the curvetag:www.schmonz.com,2013-06-08:ed4417a7059b5d1ff91904645c482f4b/1dc2f59e2f6943d2ed794b066ea61ae6Amitai Schlair2013-06-10T06:01:40Z2013-06-10T06:01:40Z
<p>As a computer programmer and user, my productivity depends primarily on my fluency with a handful of complex, powerful tools that flexibly suit many contexts alone or in combination: a <a href="https://en.wikipedia.org/wiki/Unix">family of operating systems</a>, a <a href="https://schmonz.com/2013/01/22/codemash-2013-your-dev-toolbox-everywhere/">package manager</a>, a <a href="https://en.wikipedia.org/wiki/Git%5F%28software%29">revision control system</a>, a <a href="https://en.wikipedia.org/wiki/Perl">programming language</a>, and a <a href="https://schmonz.com/2013/05/27/remembering-textpattern/">web content management system</a>. Each of these tools has a very long learning curve, but the price is worth paying, because I expect to continue using Unix systems at work and at home indefinitely. I'm heavily invested in maximizing my efficiency on these systems over the long term.</p>
<p>Most of the time, though, the gains are opportunistic and incremental. And some of the time the river runs backward and it takes effort just to stand still. This weekend, for example.</p>
<h3>Reading feeds</h3>
<p>In the great crash of 2008, I lost my <code>rss2email</code> configuration and the mail server it lived on. I've been “temporarily” using Google Reader ever since. Never liked it; never did anything about it. By retiring the service in a few weeks, Google is doing me a favor: I'll finally go back to reading feeds the way I like best. In the meantime, <code>rss2email</code> has found a <a href="https://github.com/wking/rss2email">new upstream maintainer</a> who's actively developing it. The <code>pkgsrc</code> <a href="http://pkgsrc.se/mail/rss2email">package</a>, which I maintain, trails reality by one major and several minor versions. I prepared an updated package by whacking on it with a <a href="http://www.montypython.net/scripts/gumbytheater.php">piece of wood</a> (I don't know Python or its conventions) until it worked, realized I couldn't commit it because the new configuration and cache are incompatible with the old, and <a href="http://article.gmane.org/gmane.mail.rss2email/166">set a plan in motion</a> to smoothly ferry users through the upgrade. If everything goes to plan, the latest version of <code>rss2email</code> will arrive in <code>pkgsrc</code> within days of the demise of Google Reader.</p>
<h3>Upgrading software on my desktop</h3>
<p>I hadn't updated <code>pkgsrc</code> on my Mac Pro in a while. Many of the outdated packages proceeded to update without incident, but I had to exclude a few because they would produce locking errors in an infinite loop. I couldn't reproduce the problem on my MacBook Air with the same Mac OS X and Xcode. It turned out to be a <code>libtool</code> bug that manifests only on OS X under certain multiple-filesystem configurations. After <a href="http://debbugs.gnu.org/cgi/bugreport.cgi?bug=14579">filing the bug</a> and applying my workaround, <code>libtool</code> did its job and my software upgrades completed.</p>
<h3>Upgrading software on my server</h3>
<p><code>pkgsrc-current</code> recently got <a href="http://www.nntp.perl.org/group/perl.perl5.porters/2013/05/msg201940.html">Perl 5.18.0</a>, so I figured I'd try a full package rebuild. Everything went fine until the last package, <code>ikiwiki</code>, hung indefinitely while building its documentation. It almost certainly had to be the new <code>lang/perl5</code>'s fault. I ran out of weekend to keep digging, so I <a href="http://mail-index.netbsd.org/tech-pkg/2013/06/09/msg011531.html">posted my findings</a> for discussion.</p>
<h3>Nothing's been fixed</h3>
<p>Unless I patch it, <code>libtool</code> still works wrong on my desktop. Unless I roll back to an older Perl, <code>ikiwiki</code> still doesn't build on my server. And I haven't stopped using Google Reader quite yet. But I could. (Maybe I should.)</p>
<p>When this sort of effort is required, why bother? The question is worth considering. I could read feeds with some other web service or native application. I could stop upgrading software from source, or stop having multiple filesystems, or maybe switch to some other package manager or operating system. I could wait for others to fix the fallout from a Perl upgrade.</p>
<p>But each of those options, in its own way, constitutes greater total long-term effort. If I can treat feeds like mailing lists in the tools I've already got, why should I bother with a dedicated feed reader? If I can keep my system as is and get software to build the way it used to, why should I merge my partitions? If I'm invested in <code>pkgsrc</code> and Perl, why should I wait for someone else to deal with them?</p>
<h3>Even so</h3>
<p>Sometimes computing means building cool new things, or extending existing things in fun ways, and sometimes it means this crap. But every small battle against local entropy is an obstacle removed, every obstacle removed is efficiency gained, and <a href="https://twitter.com/garybernhardt/status/300057725239451648">every bit of efficiency gained adds up over time</a>.</p>
Remembering Textpatterntag:www.schmonz.com,2013-05-27:ed4417a7059b5d1ff91904645c482f4b/f19c17b432cbf8df4d46b2acf96abc03Amitai Schlair2013-05-28T04:03:13Z2013-05-27T15:59:48Z
<p>As a person who makes and uses software, on this Memorial Day I want to commemorate the software that brings you these words, for I shall soon retire it from service. (I'll keep writing, naturally, using different software.)</p>
<p>This site has run on <a href="http://textpattern.com/">Textpattern</a> for <a href="https://schmonz.com/2005/05/02/preparing-for-departure/">eight years</a>. It was, at the time, the web publishing software most to <a href="http://www.rainskit.com/">Nathan's</a> taste, and by extension mine. Textpattern made it easy for me to publish, so I wrote about my <a href="https://schmonz.com/tag/travel/">travels home and abroad</a> and <a href="https://schmonz.com/tag/college/">travails in college</a>. Combined with <a href="https://github.com/wking/rss2email/">rss2email</a> and <a href="http://cr.yp.to/ezmlm.html">ezmlm</a>, it made it easy for my family and friends to read along, so they did. Every time I wrote, someone I cared for would write back. Quite simply, Textpattern kept me in contact with my favorite far-flung people. And <a href="https://schmonz.com/2007/01/15/the-schmonzcast-begins/">with Nathan's help</a>, it lifted my voice off the page and into your ears. When I finally <a href="https://schmonz.com/2007/12/17/schlair-student-piece-1/">settled the score on becoming a composer</a>, Textpattern is why you were able to hear my music and know how I felt.</p>
<p>For all this I'm thankful, but also uneasy. I've been uneasy for eight years because Textpattern takes my precious words and memories and stores them in a database. Databases are essential tools for solving certain kinds of problems, but also complex tools that demand effort and skill to maintain, and therefore a problem-solving tradeoff that merits careful consideration. “Database administrator” is a job, smart people who specialize in it make a good living, and I am not one of them. Remember how the server hosting this site crashed during 2008 fall finals and the site stayed offline for three years? I was lazy, and I was busy, and then I was lazy again, but mainly I was loath to deal with restoring a database. That experience was caused by, and reaffirmed, my unease. I'm extremely uncomfortable putting my most valuable data in a place even slightly beyond my ken.</p>
<p>Nothing forces web content management systems to rely on databases. When I started my online journal in 1999, I wrote a wee bit of <span class="caps">PHP </span>to assemble web pages from text files in a <code>YYYY/MM/DD</code> hierarchy. (HTML was generated on the fly, but there's no reason it couldn't have been precomputed.) Since my content consisted of ordinary documents in an ordinary filesystem, all the usual Unix tools were available to write, process, back up, etc. Granted, my needs were extraordinarily simple. But when I switched to Textpattern in 2005, despite getting a bunch of features I wanted, I felt I was giving up something extraordinarily important. I did it anyway because the <span class="caps">CMS</span> I wanted didn't exist yet and I wasn't in a position to build it.</p>
<p>It's existed for a while now. I've used <a href="http://ikiwiki.info//">ikiwiki</a> to build sites for <a href="http://www.columbia.edu/cu/philo/">The Philolexian Society of Columbia University</a> and <a href="http://wiki.netbsd.org/">The NetBSD Project</a> under constraints I don't believe any other web publishing system came close to meeting. In both cases ikiwiki already very nearly did; in both cases I was able to <a href="http://ikiwiki.info/users/schmonz/">easily extend it to finish the job</a>. I came away with a deep appreciation for its architecture and flexibility. It's the Unix of web <span class="caps">CMS</span>es (orthogonal and composable, with the concomitant learning curve) and a web <span class="caps">CMS </span>for Unix (files in the filesystem, real revision control). The server doesn't need a relational database installed. It doesn't even need ikiwiki installed! Any <span class="caps">HTTP </span>daemon can serve up static <span class="caps">HTML </span>files.</p>
<p>I'm very comfortable with ikiwiki. It has become my default solution to any web publishing problem that doesn't require a traditional dynamic <span class="caps">CMS.</span> The more sites I move to ikiwiki, the better I feel. So it's inevitable that I want this site, above all others, to move. As usual, I first need to <a href="http://ikiwiki.info/todo/fancypodcast/">extend ikiwiki a bit</a>. Once my podcast enhancements are merged, migrating <code>schmonz.com</code> from Textpattern to ikiwiki can be straightforward and seamless. You probably won't notice when it happens — except that since I'll be a <em>lot</em> happier about how my site works, you might notice me writing more.</p>
Health gains after four monthstag:www.schmonz.com,2013-05-15:ed4417a7059b5d1ff91904645c482f4b/6b335b3fdc484e783dd437a30dffa983Amitai Schlair2013-05-15T16:21:09Z2013-05-15T16:21:09Z
<p>My first recorded weigh-in was four months ago yesterday. Quantitative data is actionable data, and I've been doing plenty of quantitating. I'm solidly 1/3 of the way to my target weight, still right on schedule. But how I feel is important data, too. Recent readings:</p>
<h3>Clothing</h3>
<ul>
<li>T-shirts fit better</li>
<li>Jeans and shorts hang low after a couple wearings</li>
<li>Work slacks are fairly comfortable again</li>
<li>Work shirts are much better (still a bit tight at the neck)</li>
</ul>
<h3>Appearance</h3>
<ul>
<li>Some weight has departed my face</li>
<li>Some weight has migrated upwards to chest/shoulders/arms</li>
</ul>
<h3>Energy</h3>
<ul>
<li>Maybe less lethargic; too early to be sure, and summer-induced lethargy will temporarily confound any results</li>
<li>Exercise used to feel awful, now it feels pretty good</li>
</ul>
<h3>Summary</h3>
<p>I no longer feel like a complete mess, just a person who's out of shape. Since I'm over the exercise hump, perhaps my conditioning will now improve faster.</p>
Strength gains (and weight loss) after 30 workoutstag:www.schmonz.com,2013-04-27:ed4417a7059b5d1ff91904645c482f4b/97f170f4b483b2c84ddfa55338ae45b4Amitai Schlair2013-04-28T12:46:44Z2013-04-28T12:46:44Z
<p>I noticed that my progress, as measured by the weights I'm controlling for between 4 and 7 super-slow repetitions, had slowed. This was expected: as the weights increase, effort and intensity also increase, and so should recovery time. Strength gain isn't my primary goal this year; jettisoning 30 more pounds is. But since raising my resting metabolic rate via efficiently induced muscular hypertrophy is — thus far — my primary change of strategy for reaching my primary goal, and since my weight loss has been slow lately, I needed to change my strength-training routine.</p>
<h3>Change of exercise routine</h3>
<p>Rather than go to the gym less frequently, I've been continuing to go twice a week, alternating between my original workout routine (largest muscle groups) and a second one (smaller and/or complementary muscle groups).</p>
<h3>Strength gains</h3>
<h4>Progress on routine #1</h4>
<p>After 10 more workouts:</p>
<ul>
<li>Leg Extension: 90 -> 110</li>
<li>Leg Press: 405 -> 405</li>
<li>Shoulder Press: 65 -> 70</li>
<li>Row: 75 -> 80</li>
<li>Chest Flys: 100 -> 115</li>
<li>Chest Press: 70 -> 85</li>
<li>Crunches: body weight -> body weight</li>
</ul>
<p>One more slow, controlled crunch and I'll start holding a 5-pound plate during that exercise. Two more slow, controlled reps on the leg press and I'll have to go even slower and controllier.</p>
<h4>Progress on routine #2</h4>
<p>After the first 5 workouts:</p>
<ul>
<li>Back Extension: 110 -> 210</li>
<li>Leg Curl: 50 -> 90</li>
<li>Pulldown: 70 -> 95</li>
<li>Shrugs: 25 -> 50</li>
<li>Biceps: 30 -> 50</li>
<li>Triceps: 50 -> 90</li>
</ul>
<h4>I lied (sorry!)</h4>
<p>I've actually been going slightly more often than twice per week: every three days, like clockwork, to mesh the gears of my workout and travel schedules. I'm operating on the theory that the recovery interval to be concerned with is the one between identical workouts, in which case 6 days' rest is plenty more than the 3.5 I'd been getting before, and so it's worth it (for now) to squeeze in trips to the gym reasonably tightly.</p>
<p>Having just completed routine #2, I'm off to Boulder for a week in a rented house with parents, sister, and niece. (It's a regular work week for me. Too much going on right now to take vacation.) Then the parents and I will road-trip to Las Vegas, where I'll be attending the <a href="http://scrumalliance.org/events/610-las-vegas-">Scrum Gathering</a>.</p>
<h3>Weight loss</h3>
<p>Aside from the numbers on my workout sheets, there's also the number on my scale. After holding steady for a couple months in the low 230s, I finally reached my first sub-230 weigh-in on Friday morning. According to <a href="https://raw.github.com/schmonz/health/master/burndown.png">the burndown chart</a>, I'm still on pace to reach 200 pounds by January 1, but only because I got off to such a quick start. To stay on pace, I'll need to consistently drop a few pounds each month. If May goes by and that hasn't started happening, it will again be time to change my routine.</p>
<h3>Fun and/or effective</h3>
<p>Ignoring the numbers entirely, I'm enjoying what I'm doing, I feel good while doing it and for days afterward, and I'm continuing to notice improvements to my weight distribution and overall shape. The only reason I would consider stopping is if it were somehow at odds with my 2013 weight loss goal. Based on my reasoning and observations, high-intensity strength training alone may perhaps be insufficient exercise to deliver the goal on schedule, but the only way it could be an impediment is if the hypothetical other exercise that does suffice is also of fairly high intensity and has to happen daily. In which case I'd still lift, just less often.</p>
pkgsrcCon 2013: Rehabilitating pkglinttag:www.schmonz.com,2013-03-23:ed4417a7059b5d1ff91904645c482f4b/66508d6bfebf6e7dd35eceb0a848c6d6Amitai Schlair2013-04-05T13:15:33Z2013-04-05T13:15:33Z
<p><em>Schmonzcast #14</em>: Last week I returned from Berlin, where I gave a talk at <a href="http://www.pkgsrc.org/pkgsrcCon/2013/">pkgsrcCon 2013</a>. As a <code>pkgsrc</code> developer since 2002, and a member of its steering committee since 2005, I've attended every <a href="http://www.pkgsrc.org/pkgsrcCon/">pkgsrcCon</a> but one (<a href="http://www.pkgsrc.org/pkgsrcCon/2006/">Paris 2006</a>, as the spring semester of my freshman year at Columbia was ending). pkgsrcCon is a self-organized, purpose-specific conference for people interested in <code>pkgsrc</code>; it's short, sweet, and low-key; and thus far it's always been held in a European city well worth visiting. At this year's conference I <a href="https://schmonz.com/2013/04/05/pkgsrccon-2013-rehabilitating-pkglint/20130323-rehabilitating-pkglint.mp3">spoke about</a> <a href="http://www.pkgsrc.org/pkgsrcCon/2013/talks/pkgsrcCon-2013_schmonz-rehabilitating_pkglint/">applying 'Test-Eventually Development' to pkglint</a> (a tool for package maintainers), and how all of us volunteer developers ought to team up to slowly but surely apply the same techniques to <code>pkgsrc</code>'s unique and valuable internals. Even if you don't know much about <code>pkgsrc</code>, a passing familiarity with <span class="caps">TDD </span>suffices to follow my line of reasoning. And if you know and love <code>pkgsrc</code>, we'd love to have your help.</p>
<ul>
<li><a href="http://pkgsrc.org/pkgsrcCon/2013/presentations.html">Abstract</a></li>
<li><a href="https://schmonz.com/2013/04/05/pkgsrccon-2013-rehabilitating-pkglint/slides/">Slides</a></li>
</ul>
Strength gains after 15 workoutstag:www.schmonz.com,2013-03-10:ed4417a7059b5d1ff91904645c482f4b/a3a5e760544c01eb0f80927bd14ab9e0Amitai Schlair2013-03-11T02:21:06Z2013-03-11T02:21:06Z
<p>As mentioned in my <a href="https://schmonz.com/2013/02/26/how-to-maybe-lose-45-pounds-in-a-year/">2013 health manifesto</a>, my exercise regimen thus far consists solely of going to the gym for half an hour twice a week. I spend the 30 minutes (if that) doing high-intensity strength training.</p>
<p>No surprise: How much weight I should lift for each exercise is a data-driven decision. For my first workout in years, there were no data. I had to guess. After the first few workouts, the data were clear and I could start applying some rules. 8 or more full repetitions before muscle failure? More weight next time. 4 or fewer? I probably increased the weight too much. Less weight next time.</p>
<p>Pick an effort I can commit to, deliver it, observe the data, figure out how to reliably deliver a bit more, repeat. Sounds like Scrum sprints, right? I learned everything I know about strength training half a lifetime ago doing high school sports, thanks to an <a href="http://www.bodlesuperslow.com">unusually disciplined trainer</a>. I've always been lazy in a very particular way, wanting the best results with the least effort, no matter the endeavor. I'm lucky to have been taught some great techniques along the way.</p>
<p>Possible surprise: I record my workout data with pen on paper. It's hard to manipulate a spacephone with quivering hands in wrist-support gloves, it's a minor distraction to even have a phone around, and I haven't found a compelling app anyway (and don't feel like writing one). Paper has its own flaws, but it seems to work so far, and in the meantime I'm not generating enormous mounds of data that I'll regret not having digitized to begin with.</p>
<p>A nice side effect of paper is that it fills up, a free reminder to review and introspect. I've just started my second page. What have I noticed? By feel, my body has been adapting to the workload by building muscle. What do the data say? By the numbers, the weight I can control has roughly doubled:</p>
<p>Leg Extension: 50 -> 90<br />
Leg Press: 110 -> 405<br />
Shoulder Press: 30 -> 65<br />
Row: 40 -> 75<br />
Chest Flys: 50 -> 100<br />
Chest Press: 30 -> 70<br />
Crunches: body weight -> body weight</p>
<p>It'll take a while before I can do 8 crunches and start needing a 5-pound plate on my chest. Conversely, on leg press, I've maxed out the machine. Nothing to be done about it but concentrate on form, and go even slower.</p>
Permanent CVS, temporary Gittag:www.schmonz.com,2013-03-10:ed4417a7059b5d1ff91904645c482f4b/95a4c80c930ce680ea34b5cf0c57feeeAmitai Schlair2013-03-10T06:45:25Z2013-03-10T06:45:25Z
<p>I'm giving a talk called “Rehabilitating pkglint” later this month at <a href="http://pkgsrc.org/pkgsrcCon/2013/presentations.html">pkgsrcCon</a>, which means I need to do some work worth talking about. <a href="http://pkgsrc.se/pkgtools/pkglint">pkglint</a> is a tool for pkgsrc developers to <a href="http://www.netbsd.org/docs/pkgsrc/examples.html#checking-package-with-pkglint">find common errors in packages</a>. It's not part of pkgsrc infrastructure proper, but it's a key step in the package development cycle. And <a href="http://gnats.netbsd.org/46570">it has problems</a>. One proposed solution is to rewrite it.</p>
<p>A rewrite may or may not be a good idea (I bet <a href="http://www.joelonsoftware.com/articles/fog0000000069.html">not</a>), but in either case, the beginning of the solution to <code>pkglint</code>'s problems is to first understand and document its current behavior. I've <a href="http://mail-index.netbsd.org/pkgsrc-changes/2013/01/19/msg083583.html">retrofitted</a> (very <a href="http://mail-index.netbsd.org/pkgsrc-changes/2013/01/20/msg083590.html">cautiously</a>) a place to put tests, along with a handful of test cases. A long road of adding coverage and safely refactoring lies ahead. To get as far as I possibly can by the 23rd, I need to be able to:</p>
<ul>
<li>Work offline,</li>
<li>Make experimental and possibly outlandish choices,</li>
<li>Commit promptly each time one of those choices pays off, and</li>
<li>Not worry (yet) about having my changes reviewed and approved.</li>
</ul>
<p>If pkgsrc were managed in a <a href="https://en.wikipedia.org/wiki/Distributed%5Frevision%5Fcontrol"><span class="caps">DVCS</span></a>, I'd be good to go. Since it's in <span class="caps">CVS,</span> I did this:</p>
<pre><code>$ echo .git >> ~/.cvsignore
$ echo CVS >> ~/.gitignore_global
$ cd .../pkgsrc/pkgtools/pkglint
$ git init
$ git add .
$ git commit -am 'Add pkglint to git for offline hacking.'
$ git checkout -b rehab</code></pre>
<p>Now I'm tracking <code>pkglint</code> in its own little <code>git</code> repository. The <code>master</code> branch tracks upstream, and the <code>rehab</code> branch is where I hack:</p>
<pre><code>$ cd .../pkgsrc/pkgtools/pkglint
$ git checkout master
$ cvs update
$ git commit -am 'Track upstream changes from pkgsrc CVS.'
$ git checkout rehab
$ git rebase master
$ vi files/pkglint.t files/pkglint.pl && make test && make clean
$ git commit -am 'More cool stuff on my branch.'</code></pre>
<p>This is a slightly clever trick, but not too much so. I'm happy and productive with it so far.</p>
How to (maybe) lose 45 pounds in a yeartag:www.schmonz.com,2013-02-25:ed4417a7059b5d1ff91904645c482f4b/1c655d0b659dbf069dbbc01181f87190Amitai Schlair2014-09-12T01:36:09Z2013-02-26T06:20:18Z
<h2>Summary</h2>
<ol>
<li>Look at the evidence and decide that I'm tired of being fat.</li>
<li>Look at the evidence and decide that I can make becoming not fat my top priority for 2013.</li>
<li>Look at the evidence and prepare the simplest plan (read on for details) that could possibly work for me.</li>
<li>As soon as there's evidence that my plan is working, write this post.</li>
<li>As soon as there's evidence that my plan has stopped working, review and adjust until it's working again, then write another post.</li>
</ol>
<h2>Assumptions</h2>
<h3>A weight goal suffices</h3>
<p>I can worry about optimizing my body composition, blood chemistry, and other measurements in 2014. For 2013, I'm treating mass as a proxy for health, and worrying only about reducing total mass (as measured by proxy, in pounds, on Earth).</p>
<h3>200 pounds is worthwhile and achievable</h3>
<p>As recently as a few years ago, I was a healthy and fully functional adult human at that weight, and I had maintained it for six or seven years with ease. (Under normal life conditions, I'm really good at maintaining whatever weight I already have, whether or not it's a good one. Better make it a good one.)</p>
<h3>I won't do dumb things to lose weight</h3>
<p>I've just defined success by a single number, which means I have to be careful with myself about how I try to hit that number. For instance, amputating a leg would get me there immediately, and the ensuing blood loss would get me well under. I'm more concerned about choices that are less obviously stupid, such as taking supplements whose mechanisms of action I don't understand or whose side effects are risky.</p>
<p>For the record, I plan to keep both legs and ingest objects commonly understood to be food. But when people have their performance measured by specific known criteria, they tend to optimize for those at the expense of other criteria. (”Be careful what you measure, because you'll get it.”) I'm the one measuring my own performance, so my bias can hurt me if I'm not careful. More generally, as a person with many person-like characteristics, behavioral incentives can hurt me if I'm not careful.</p>
<p>I'll have to be careful, that's all.</p>
<h3>I understand my metabolism well enough</h3>
<p>I don't believe “calories in, calories out”. Some reasons I don't believe it:</p>
<ul>
<li>Calories measure how much energy is released by setting fire to something. Incineration is not one of the metabolic pathways found in humans.</li>
<li>Every now and then I'll eat some bread or a slice of pizza, and the next day I'll weigh 2-3 pounds more. The experiment's results are unnervingly repeatable.</li>
<li>My calorie intake over the last several years would <a href="http://www.nytimes.com/2012/01/01/magazine/tara-parker-pope-fat-trap.html?pagewanted=all">surprise you with how low it is</a>. For a person of my size, the calorie math says I should have been at least slowly losing weight. Instead I've gained some.</li>
</ul>
<p>As an extreme example, after an Ultimate tournament in Philadelphia wherein I partook of the sideline fare of bagels, bananas, and soft pretzels, I came home to find that I'd gained 10 pounds. Gained! 10 pounds! After running around all day for two days! It sounds crazy, but it happened, and it took a full week of careful eating to get back down to 200.</p>
<p>”Careful eating”, for me, means avoiding carbohydrate entirely. I feel better and I don't gain weight. It's hard to look at all my experiential data without concluding I'm exhibiting <a href="https://en.wikipedia.org/wiki/Insulin%5Fresistance">insulin resistance</a>.</p>
<p>Since “calories in, calories out” is a falsehood commonly accepted as truth, <a href="http://www.nytimes.com/2012/07/01/opinion/sunday/what-really-makes-us-fat.html?pagewanted=all">it's dangerous</a>. If you think calories are a reasonable metric, you'll try to optimize your calorie input and output. Are those the choices that optimize your health?</p>
<h3>I understand exercise well enough</h3>
<p>I'm an ex-athlete. This means I'll tend to overestimate my abilities, which I'm aware of, and careful not to. It also means I have useful knowledge and latent skill. For instance, I know that typical aerobic exercise is a very inefficient way to up-regulate one's metabolism and that <a href="https://en.wikipedia.org/wiki/Super%5Fslow">high-intensity strength training</a> is a very efficient way to do so. I also know how to safely practice high-intensity training, including which data to track and observe. I know it's a form of exercise I enjoy doing, which makes it far more likely that I'll stick to doing it. And I know that increasing strength and muscle mass is a three-step process, of which deliberate trauma to muscle fibers is step 1.</p>
<p>Step 2, starting immediately afterward, is nutrition. In the 30-45 minute window after an intense workout, insulin sensitivity is very high (yes, even for me) as my body decides how to react to the trauma. If in that window I eat nothing, my metabolism will take the hint and downshift, plus I won't get stronger; if I instead eat high-quality carbohydrate — ideally accompanied by minimal fat and protein, which slow absorption of the macronutrient I'm temporarily after — my metabolism will immediately press it into service to replenish glycogen and rebuild muscle.</p>
<p>Assuming sufficient nutrition, the bottleneck to rebuilding muscle is rest. Step 3, if I want to be stronger than last time I went to the gym, is to wait long enough. In high school I could lift three times a week; now I can manage two; much later, when I'm very strong and have to work my muscles very hard in order to push their limits, I'll only be able to lift once a week, and I won't even be able to work the same muscles in consecutive workouts. (That's a very long way off, though.)</p>
<p>Another reason I'm likely to stick with high-intensity strength training: because it's hard work the whole time, a workout takes no more than 30 minutes. I think I can spare a half hour twice a week to efficiently win a metabolic advantage by doing exercise I enjoy.</p>
<h3>I'll be able to formulate a workable plan</h3>
<p>I have strong knowledge of metabolism and exercise. I've lost nearly this much weight before (a decade ago). I recognize the importance of data and of fast feedback to achieve goals.</p>
<h3>I'll be able to enact the plan</h3>
<p>In 2012, work made unhealthy demands on my time and cortisol levels (another known contributor to weight gain). I made some changes midyear and they've paid off: I get to define and implement the lifestyle I want. I can consistently devote attention to recording data, observing feedback, and adjusting.</p>
<h2>The plan</h2>
<h3>Goal</h3>
<p>On January 1, 2014, weigh no more than 200 pounds.</p>
<h3>Actions</h3>
<ul>
<li>Every morning, I record my weight and push to GitHub. (Why GitHub? Because my repositories there are visible to the public, which makes me feel more accountable, and because I like using Git.) A <code>cron</code> job emails me at 7:30am if I haven't already committed and pushed that day's weigh-in.</li>
<li>Every time I weigh in, <a href="https://raw.github.com/schmonz/health/master/burndown.png">my screensaver picture</a> is automatically updated.</li>
<li>Within a half hour of waking up, I eat some fat and protein. Examples: bacon, eggs, high-fat cottage cheese, high-fat yogurt.</li>
<li>On non-workout days, I eat no carbohydrate, just fat and protein.</li>
<li>On workout days, I eat clean carbohydrate immediately after training. (I bring an old-school purple-paste PowerBar with me to the gym so I can eat it on the way home. After showering, I eat another.) Anecdotally, I <em>don't</em> gain weight when ingesting carbohydrate in this specific context.</li>
<li>Once a week, I work out in the late afternoon, then eat carbohydrate for the rest of the day. This prods my metabolism in a way that prevents down-regulation, seems to be going to good muscle-building use, and is fun.</li>
</ul>
<h2>Progress</h2>
<p>5 weeks in, I've lost more than 10 pounds. That rate won't continue forever, but it's a promising start. I feel some muscle where I didn't before. With each workout my form is a bit better, the weights are a bit heavier, and I can push myself a bit harder. Yesterday's was the first where I sustained an intensity that made it an aerobic workout too.</p>
<p>Thus far, the plan is working. Stay tuned.</p>
Synthesizing podcaststag:www.schmonz.com,2013-01-25:ed4417a7059b5d1ff91904645c482f4b/f035589e923f4c34257b6ac09c2136e7Amitai Schlair2013-01-26T01:07:23Z2013-01-25T23:53:31Z
<p>I'm a latecomer to the <a href="https://www.destroyallsoftware.com/screencasts">Destroy All Software</a> party. Lots and lots of catching up to do. Sure would be nice if I could watch at home on my iPad and on the subway with my iPhone and let <a href="http://www.downcastapp.com/">Downcast</a> keep them in sync about what I've seen so far. But <span class="caps">DAS </span>doesn't have a podcast feed and, since it's coming to an end in the next month or two, probably never will. So I made my own podcast for it. Glossing over most of the details:</p>
<h3>Acquire tools</h3>
<ol>
<li>Have <a href="http://ikiwiki.info//">ikiwiki</a> (I install it from <a href="http://www.pkgsrc.org/">pkgsrc</a>) and a web server (I use <a href="http://www.eterna.com.au/bozohttpd/">bozohttpd</a>, also from <code>pkgsrc</code>).</li>
</ol>
<p>I was already running <code>ikiwiki</code> and <code>bozohttpd</code> on my laptop for my personal wiki, so I had already jumped through many of these hoops.</p>
<h3>Configure the basics</h3>
<ol>
<li>Figure out how to get the web server to run at boot and serve the intended directory (on OS X, I often get help from <a href="http://www.peterborgapps.com/lingon/">Lingon</a>).</li>
<li>Create a very basic <code>ikiwiki</code> configuration, taking care to <code>add_plugin</code> the <code>inline</code> plugin.</li>
<li>Create an <code>index.md</code> at the root of the wiki containing pretty much just this: <code>[[!inline atom=yes pages="media/*" sort=title reverse=yes archive=yes]]</code> (tweak to taste).</li>
<li>Create a <code>media</code> subdirectory and put the videos there.</li>
<li>Run <code>/path/to/ikiwiki --setup /path/to/ikiwiki.setup</code>, then browse the wiki. All the videos should be linked there.</li>
<li>Subscribe to the Atom feed in a podcatcher.</li>
</ol>
<h3>And now, a bit of weird OS X magic</h3>
<ol>
<li>Create a <a href="http://www.macworld.com/article/1167157/automate_tasks_with_folder_actions.html">Folder Action</a> AppleScript on the <code>media</code> folder that does this:</li>
</ol>
<pre><code>on adding folder items to this_folder after receiving added_items
do shell script "/path/to/ikiwiki --setup /path/to/ikiwiki.setup"
end adding folder items to</code></pre>
<h3>Voilà!</h3>
<p>When Gary announces a new screencast:</p>
<ol>
<li>I download it to <code>media</code>.</li>
<li>The current application loses focus for some dumb reason.</li>
<li>There is no third thing.</li>
</ol>
<p>When the iPad and iPhone next refresh their subscriptions, they'll get the new screencast.</p>
Screencasting on the cheaptag:www.schmonz.com,2013-01-23:ed4417a7059b5d1ff91904645c482f4b/dc121f940214a1d7cd7d26a4615f3238Amitai Schlair2014-01-14T04:21:29Z2013-01-23T21:46:48Z
<p>When I gave my <a href="https://schmonz.com/2013/01/22/codemash-2013-your-dev-toolbox-everywhere/">lightning talk at CodeMash</a>, I made sure to record it (with my iPhone's Voice Memos app). Then I trimmed the ends and converted to <span class="caps">MP3 </span>(with iTunes), thinking it was ready to Schmonzcast. But what about the slides? Turns out I had all the needed tools on Mac OS X to make a halfway decent video. Steps:</p>
<h3>Acquire tools</h3>
<ol>
<li>Have QuickTime Player (for A/V capture) and <a href="http://code.google.com/p/soundflower/">Soundflower</a> (for audio redirection).</li>
</ol>
<h3>Configure the basics</h3>
<ol>
<li>Plug into wall power to avoid “low battery” popups.</li>
<li>In the Growl preference pane, set “hide all notifications”.</li>
<li>In Notification Center, set “Do Not Disturb”.</li>
<li>In f.lux, set “Disable for an hour”.</li>
<li>Enable Caffeine.</li>
<li>In the Sound preference pane, on the Sound Effects tab, drag the alert volume to 0.</li>
<li>Also in the Sound preference pane, on the Output tab, set the output device to “Soundflower (2ch)” and maximize the output volume. All audio output will be sent to Soundflower, not speakers or headphones.</li>
<li>In Soundflowerbed, send a copy of the “Soundflower (2ch)” stream to speakers or headphones.</li>
</ol>
<h3>Rehearse a few times</h3>
<ol>
<li>Open the slides fullscreen. (Mine were formatted as <a href="http://meyerweb.com/eric/tools/s5/">S5 <span class="caps">HTML</span></a>, so I used Google Chrome in Presentation Mode.)</li>
<li>In iTunes, make a playlist containing the audio track the slides will sync with.</li>
<li>With the iPhone's Remote app, navigate to the playlist and start the audio track playing.</li>
<li>Using the keyboard, advance the slides to match.</li>
</ol>
<h3>Perform for posterity</h3>
<ol>
<li>In QuickTime Player, from the File menu, make a “New Screen Recording”. In the in-window settings popup, for Microphone, choose “Soundflower (2ch)”. Click the Record button and Start Recording.</li>
<li>Go to the beginning of the slides, then do whatever it takes to hide the mouse cursor (I pressed an unimportant key).</li>
<li>On the iPhone, start the audio track playing.</li>
<li>It's showtime! Advance the slides to match.</li>
<li>When the audio stops, wait a few seconds, then show the menu bar and click Stop Recording.</li>
<li>In QuickTime Player, from the Edit menu, choose “Trim…” to slice off the prep work and dead air at the start and end. “Save As…” a “Movie”.</li>
<li>Upload to YouTube or Vimeo, or apply <span class="caps">ID3 </span>tags (e.g., with iTunes) and podcast it.</li>
</ol>
<p>This worked well enough for my one screencast, which had no live typing or narration. (Contrast with, for example, <a href="https://www.destroyallsoftware.com/screencasts">Destroy All Software</a>.) Would it work as well for something more demanding? Maybe I'll find out.</p>
CodeMash 2013: Your Dev Toolbox, Everywheretag:www.schmonz.com,2013-01-22:ed4417a7059b5d1ff91904645c482f4b/5890674b890867778e208cde43a78770Amitai Schlair2013-02-10T18:51:56Z2013-01-23T04:04:45Z
<p><em>Schmonzcast #13</em>: I've attended (and spoken at) more than a few instances of <a href="http://www.pkgsrc.org/pkgsrcCon/">pkgsrcCon</a>, but I'd never attended a full-on costs-money big-crowd software development conference until <a href="http://codemash.org/about">two weeks ago</a>. Perhaps counterintuitively, the first thing I did there was an all-day <a href="http://codemash.org/sessions?type=PreCompiler&day=2013-01-08">Speaker Workshop</a>. While the air at the hotel was thick with code, what was fresh on my mind was the pain of meticulously planning and presenting half-hour talks at work every week for the past couple months. I wanted to know how it might get easier. The instructor, <a href="http://leongersing.com/">Leon Gersing</a>, combined a background in theater with perceptive, intuitive teaching. I came away much more aware of what to work on. (For example: my personality is slightly goofy in a way that, once I'm comfortable enough in front of a crowd for it to show through, probably works in my favor.) And when <a href="http://www.coreyhaines.com/">Corey Haines</a> organized a session of <a href="http://lightningtalks.codemash.org/">lightning talks</a> two days later, I decided to <a href="https://schmonz.com/2013/01/22/codemash-2013-your-dev-toolbox-everywhere/20130110-your-dev-toolbox-everywhere.mov">get right to work, then and there</a> (or <a href="http://youtu.be/B2GV0GlXBX4">watch on YouTube</a>). Given the format, I like how it went; for next year's CodeMash, I plan to submit a full-length talk proposal.</p>
<ul>
<li><a href="https://schmonz.com/2013/01/22/codemash-2013-your-dev-toolbox-everywhere/slides/">Slides</a></li>
<li><a href="https://schmonz.com/2013/01/22/codemash-2013-your-dev-toolbox-everywhere/20130110-your-dev-toolbox-everywhere.mov">Screencast</a></li>
</ul>
My unexpected neighbortag:www.schmonz.com,2013-01-25:ed4417a7059b5d1ff91904645c482f4b/b01e9a4f81df52820215932e91132ce6Amitai Schlair2013-01-21T03:22:54Z2013-01-21T03:22:54Z
<p><em>[Originally posted to <a href="http://www.rememberaaronsw.com/memories/my-unexpected-neighbor.html">Remember Aaron Swartz</a>]</em></p>
<p>I maintain <a href="http://www.pkgsrc.org/">pkgsrc</a> packages of <a href="http://pkgsrc.se/mail/rss2email">some of</a> <a href="http://pkgsrc.se/textproc/py-html2text">Aaron's software</a>, and over the last decade or so would occasionally send him bits and pieces of code. Along the way we somehow discovered that we'd grown up a couple hundred meters apart, separated by a driveway and some trees. (If only we'd known, and been around at the same time, our common interests would doubtless have made us fast friends.)</p>
<p>When sending patches I'd always ask what he'd been up to lately, because it was always something new and ambitious, even audacious. We were just nerds on the Internet whose paths occasionally crossed, but I felt like I knew him better than that. Above all, he had managed to hold fast to a way of thinking about our world — as evidenced by his writing and his actions — that I had forced myself to hold rather more loosely. I always admired him for that.</p>
<p>Had we had the chance to know each other better, I'm quite sure I'd have admired Aaron for much more.</p>
pkgsrcCon 2010: What pkgsrc Needs Mosthttps://schmonz.com/2010/05/30/pkgsrccon-2010-what-pkgsrc-needs-most/Amitai Schlair2017-05-27T21:39:12Z2010-05-31T02:17:22Z
<ul>
<li><a href="http://pkgsrc.org/pkgsrcCon/2010/presentations.html">Abstract</a></li>
<li><a href="https://schmonz.com/2010/05/30/pkgsrccon-2010-what-pkgsrc-needs-most/slides/">Slides</a></li>
</ul>
Literature Humanities: Paper #2tag:www.schmonz.com,2012-01-05:ed4417a7059b5d1ff91904645c482f4b/2c629e673c89f305c713f57dda0c8899Amitai Schlair2012-01-05T07:04:27Z2008-12-09T19:23:00Z
<p><em>Compare Aristophanes' and Diotima's speeches in Plato's “Symposium”. You should analyze each one carefully, thinking about the context, themes, structure, images, language, and references to other texts already studied in our class, as well as the role of each passage within the Symposium. From your analysis consider if those ideas have permeated our contemporary conception of love and how. Feel free to use contemporary references such as novels, quotes from movies, news articles such as <a href="http://topics.nytimes.com/top/features/style/fashionandstyle/columns/modernlove/">Modern Love</a> in the NY Times. Notice that both speeches are very rich and you have limited space to write about them: choose the features in them that you find more interesting, and talk about them in detail.</em></p>
<h2>A little love, now and then</h2>
<h3>Ancient and contemporary Greeks in conversation</h3>
<p>The speech of Aristophanes in Plato's <em>Symposium</em> is notable in that its central metaphor survives to the present day. Though people are not generally aware of its attribution, in its genericized form it is part of contemporary discourse. Audiences require no explanation when hearing the title character in the film <em>Jerry Maguire</em> utter “You complete me” to the one he loves. Nor does she, but rather is overcome by the sentiment. It is a poetic formulation, the idea that human loneliness and the need for companionship are borne of estrangement from our original selves and that this eternal dissatisfaction was meted out by a higher power when we overreached our bounds. We had it, we blew it, we lost it. A later formulation of the same idea, the Old Testament tale of Adam and Eve, has achieved even wider cultural currency. In the conceptions of both Genesis and Plato's Aristophanes, companions share a connection rooted in the physical. Where Adam suffers the loss of a rib as raw material for the construction of his Eve, in Aristophanes the bonds between pairs of humans exist from the outset, as they share eight-limbed bodies, and the pain of their later separation is suggested by the bodily aspects of their forcible disjunction (26, 190E-191A). It is as though Aristophanes is responding to Eryximachus in kind, medical explanation for medical explanation.</p>
<p>Why has this metaphor retained its appeal? Plato's Socrates knows, because Diotima has taught him that ”…we divide out a special kind of love, and we refer to it by the word that means the whole — 'love'; and for the other kinds of love we use other words” (51, 205B). Today's discourse works the same way: unless they specify otherwise, two people talking about “love” are almost always talking about romantic love between two people. And Aristophanes' conception of love, focused as it is on the emotional experiences of individuals and their ideal states, meshes well with Romanticism (a precursor to our lowercased term), even as his story undermines the very etymology of the word “individual.” Upon finding each other, two matched dividuals “are struck from their senses by love, by a sense of belonging to one another, and by desire, and they don't want to be separated from one another, not even for a moment” (28, 192C). We identify with this description because it is the very same experience we ourselves seek. Love is, by Aristophanes' lights, “the name for our pursuit of wholeness, for our desire to be complete” (29, 193A). It would seem there is something timeless about the notion.</p>
<p>Socrates, speaking last and only after much characteristic self-deprecation, aims for a different sort of timelessness. Rhetorically, if not factually, he gestures away from himself as the source of any wisdom he may possess. Instead, he positions himself as having thought as his fellow revelers do until he received the wisdom of Diotima, prefiguring both the impact he wishes his speech to have and the distinction that speech (in the voice of Diotima) will soon make between the roles of lover and beloved (49, 204C). (Of course, the rhetorical layer of abstraction pointing to itself also points up Plato's role as the true author of all of <em>Symposium</em>'s speeches.) Diotima's speech begins, like Aristophanes' and thoroughly redolent of Aesop, with reference to god and myth. The properties of Love are initially explained as a hybrid of the properties of Love's parents. The speech's approach begins to depart from that of Aristophanes, however, when Socrates first interjects to ask a question of Diotima (49, 204B). From that point onward, the speech becomes recognizably Socratic, with the clever inversion of Socrates in the role of the student. Diotima asks so that Socrates might struggle toward the answers himself; as the character doing the speaking at this point in <em>Symposium</em>, Socrates affords the same luxury to his listeners, with the added benefit of providing his own answers moments later (an understandably proferred shortcut — after all, he knows they've been doing some drinking).</p>
<p>Aristophanes and Socrates both trade in abstractions, but the nature of the abstractions differs. Aristophanes relies on striking images and metaphors that are pleasurable to essay. That the whole of love can be explained in terms of paired permutations of sun (male), earth (female), and moon (both), that Zeus “cut those human beings in two… the way they cut eggs with hairs”; that Apollo created the navel as a result, is all persuasive in the same way any other origin myth is persuasive — which is to say, better at a glance than under close inspection. Socrates, on the other hand, is ready for his close-up. Once the Socratic portion of Diotima's speech is underway, the debate begins from definitions and first principles and follows a chain of dialogic discourse and stepwise discovery, along the way subsuming the speeches that have gone before in a symphonic synthesis. Aristophanes, for instance, is quickly deconstructed and dismissed in terms of Diotima's established chain of logic (52, 205E). This moment in Diotima's speech is a rich site for comparison between the intellectual capacities of Aristophanes and Socrates; the latter can dispatch the former's ideas as rapidly as that, and it is because the abstractions of Diotima (which is to say, Socrates) are less for artistic purposes and more for conceptual ones. That is to say, Diotima reaches for abstractions not to avoid confronting faulty logic, but rather when the complexity of an idea demands a level of abstraction, as for example drawing a distinction between the “object” and the “purpose” of love (52, 206B). This prepares the listener as well as possible for her explication of the ultimate progression of love, for the conception of Beauty “itself by itself with itself” with which her speech concludes (59, 211B). Having seen how Socrates makes a detailed logical argument, it is hard upon returning to Aristophanes to interpret it as anything more than a potent metaphor.</p>
<p>When Socrates speaks in the guise of Diotima, he is disguising more than his voice. His view of love places heavy demands of anyone who would try to understand and enact it, as Diotima says: “But as for the purpose of these rites when they are done correctly — that is the final and highest mystery, and I don't know if you are capable of it” (57, 210A). Socrates attempts, as per usual, to lower his apparent status (and thereby hearten his friends) by having Diotima preface her remarks with “Even you, Socrates, could probably come to be initiated into these rites.” But it remains apparent that achieving such a level of enlightenment is open only to the very few. Otherwise, if everyone could reasonably aspire to direct cognition of abstract beauty, which concrete individuals would be left to engage in concrete acts, to give literal “reproduction and birth in beauty” (53, 206E)? A society consisting solely of the enlightened would have to either compromise or die out. Aristophanes, by contrast, has a more egalitarian view in which any two people (for the most part, of any genders) can potentially be a match and achieve love. End of story.</p>
<p>The novel <em>Middlesex</em> presents several views of love over the course of the last century. In one, a brother and sister move from Greece to America, getting married on the ship over and swearing their only knowing American relative to secrecy. In another, a neighbor's daughter almost marries a priest before realizing he is the wrong man. Her realization hinges on the romanticized medium of Saturday matinee movies. In one of the movies she sees, a man played by a Claude Barron goes off to war in the desert because the woman he loved married another man who proves a poor choice. She goes to the desert and finds Barron, wounded, to confess her love. His reply, before dying:</p>
<blockquote><p><br />
'I went into the desert to forget about you. But the sand was the color of your hair. The desert sky was the color of your eyes. There was nowhere I could go that wouldn't be you.' (189)</p></blockquote>
<p>A few pages later, another film viscerally reminds the neighbor's daughter of her non-priestly suitor, and suddenly she knows who her other half truly is:</p>
<blockquote><p><br />
She doesn't want to be a priest's wife or move to Greece. As she gazes at Milton in the newsreel, her eyes fill with tears and she says out loud, 'There was nowhere I could go that wouldn't be you.'” (193)</p></blockquote>
<p>This archly romantic phrase figures at one more juncture in the novel, pertaining to the main character, who is born (unknown to anyone until puberty takes a strange turn) with a hermaphroditic condition, thanks to his/her brother-and-sister grandparents. After being informed that she is in fact a he, he runs away to San Francisco to try out his new identity. In this context, seeking and failing to find the self-love of his own other half, his suffering takes on a richer, more harrowing meaning:</p>
<blockquote><p><br />
Mostly I hung around the mimosa grove, in growing despair. A few times I walked out to the beach to sit by the sea, but after a while I stopped doing that, too. Nature brought no relief. Outside had ended. There was nowhere to go that wouldn't be me. (473)</p></blockquote>
<p><em>Middlesex</em> navigates family, gender, identity, and love — frequently blurring the boundaries of the familial, the friendly, and the romantic — through several generations. In so doing, it illustrates aspects of Aristophanes' quest for one's other half, as well as aspects of Socrates' quest for something more significant than a particular beautiful body. If <em>Middlesex</em> is relevant to contemporary life and love — and the decision of the Pulitzer committee would strongly indicate that it is — then the ideas it explores, old though they be, must themselves also be relevant today.</p>
<h2>Works Cited</h2>
<ul>
<li>Eugenides, Jeffrey. <em>Middlesex</em>. Macmillan, 2003.</li>
<li><em>Jerry Maguire</em>. Dir. Cameron Crowe. Perf. Tom Cruise, Cuba Gooding Jr., and Renée Zellweger. 1996.</li>
<li>Plato. <em>Symposium</em>. Trans. Nehamas, Alexander and Paul Woodruff. Indianapolis: Hackett Publishing, 1989.</li>
</ul>
Thankstag:www.schmonz.com,2012-01-05:ed4417a7059b5d1ff91904645c482f4b/ee05c1932d4f60b1c01509b2f1d50ea6Amitai Schlair2008-12-01T17:25:00Z2008-12-01T17:25:00Z
<p>This may be prolix. I've wanted to write since approximately forever, and my mind and heart are awhirl, plus when not reading for class I've been reading novels (lately <a href="https://en.wikipedia.org/wiki/Middlesex%5F%28novel%29">Middlesex</a> and <a href="https://en.wikipedia.org/wiki/Gilead%5F%28novel%29">Gilead</a> and a quick review of <a href="https://en.wikipedia.org/wiki/Goodbye%2C%5FColumbus">Goodbye, Columbus</a>. Apologies if I wind up writing one here.</p>
<p>Of all I can be thankful for, the most timely was Thanksgiving break. Mired as I have been in my muck, any time off would have sufficed, but the calendar afforded an especial reprieve with its prod toward gratitude and perspective.</p>
<p>I learned a few things over a relaxing, refreshing, and <a href="https://schmonz.com/2008/06/06/summer-of-road/">eventful summer</a>. At KlezKanada I sought to soak up Jewishness for use in my compositions only to realize that it's been there, always and unavoidably. At the <span class="caps">LSA</span> Summer Meeting and Mini-Institute I tried to fall under the sway of the linguistic lifestyle but was insufficiently moved. I won't be going to graduate school for music either, at least not now. The <a href="https://en.wikipedia.org/wiki/Senioritis">senioritis</a> that is inconveniently peaking at crunch time got its start months ago, maybe even almost a year ago. I'm ready to be done with academia, ready to be back in the world, ready to <a href="https://schmonz.com/2007/11/11/advanced-composition/">enact my plan</a>.</p>
<p>For all the travel and discovery, my Google Summer of Code project suffered. This disappointed me and, I'm sure, others (though I'm hoping to have time for it soon, belatedly). Had I done particularly well, it could have helped my chances applying for a job at Google; it may be that having done poorly hurts my chances, or it may not. If I apply there, we'll find out. The job hunt is due to begin in earnest over winter break, which arrives in a few short and intense weeks and lasts for a beautiful month. I'm not wedded to New York by any stretch, though I'd stay if the right offer came along (I appreciate having my sister near; also, after four years of a student budget, it'd be nice to try being a grownup here). I have a more than vague interest in moving to the west coast, however, and will be attempting to make that a possibility as well.</p>
<p>Winter break will be lonely but productive and, as such, restorative. I'll be reorganizing physically and emotionally. I've been doing Krav Maga three days a week this semester; over break my schedule becomes amenable to five. I'll have time for various projects and overdue tasks, time to see friends, time to write music, time to think about how I want my last semester of college to go. Because after this semester, my only remaining requirement is a single social science course. At the moment I'm inclined to register for no more than that, to extend the feeling and freedom of winter vacation right up until graduation, after which my father and I will take a summer vacation in Israel.</p>
<p>Before any of these dreams can come true, I have to grind through the next few weeks. The courses I'm taking (with the exception of piano lessons) are all core requirements, my major having been completed in the middle of last year:</p>
<ul>
<li>Earth, Moon, and Planets</li>
<li>Galaxies and Cosmology</li>
<li>Literature Humanities</li>
<li>Asian Music Humanities</li>
<li>Principles of Economics</li>
</ul>
<p>None particularly excites me (the astronomy courses are at a sixth- to eighth-grade level), so I'm glad I'm taking them now, when the end is in sight, rather than earlier, when my alacrity to study music and language would have met with such discouraging dullness. Columbia has been amazing — I'm a composer now! — but like I said, I'm ready to be done.</p>
<p>I'm thankful for this journey and for nearing its terminus; for my health, as good as it's been in quite some time; and for love. After losing some, I'm rediscovering how much I still have.</p>
A lesser poet of Athenstag:www.schmonz.com,2012-01-05:ed4417a7059b5d1ff91904645c482f4b/3caec4c85512e38da7525a736aa2cf51Amitai Schlair2012-06-30T23:56:56Z2008-11-14T02:00:00Z
<p>Last year, as you may recall, I experienced the uniquely ignominious pride of <a href="https://schmonz.com/2007/11/16/explosion-at-the-poem-factory/">winning a bad poetry contest</a>. In this, my last contest as an undergraduate, I settled happily for dishonorable mention. Good enough for me; I've been to the mountaintop. Inspired (such as it is) by material from my <a href="http://www.college.columbia.edu/core/classes/lh.php">Literature Humanities</a> course, here's my entry:</p>
<p><em>Recently Uncovered Draft Manuscript of Ascrapius, a lesser poet of Athens</em></p>
<p>Sing, O Muse, of the varied and sundry accumulated experiences of Herodoklodophopilus, though they be difficult to translate in an elegant fashion, what with the language features of Greek grammar unavailable in English, not to mention the other limitations inherent to the work of translation, plus I don't actually know Greek at all. So sing, O Muse, loudly and clearly and in a way we over here can understand, if you get my drift. And don't worry about this little audio-recording doodad. Just pretend it's not there. Okay I'll turn it off.</p>
<p><em>[pretend to turn it off]</em></p>
<p><em>[clear throat]</em></p>
<p>Sing, O Muse, of the mild, persistent disappointment<br />
That plagued our somewhat interesting protagonist<br />
In manner nonetheless not unmanageable<br />
Or even memorable. The strong-greaved, rarely-greaved<br />
Herodoklodophopilus himself forgot<br />
Though it be him what at this tale is all up on.</p>
<p>So when you have put away your desire for eating and drinking,<br />
Put away in your minds this other thing I tell you.<br />
Many poets could have been chosen for the recounting.<br />
The muse chose me. What can I say, I gave her some good shit.<br />
Behold! Of all most honorable poets, this is Ascrapius you'll get.</p>
<p>And now, the moment you've all been waiting for already.<br />
Stay your poisonous, venomous, poisonous darts.<br />
No Aias-crapius to block them am I, with<br />
That big ol' shield. That you would harm, it hurts me right here <em>[gesture to heart]</em><br />
It's okay. I'm good. Story time, motherfuckers.</p>
<p>There once was a man called Herodoklodophopilus<br />
Who liked to stand on top of the Acropolis.<br />
But the Greeks all wore onesies,<br />
Which made it less funsies,<br />
Because noone ever walked around topilus.</p>
What's at staketag:www.schmonz.com,2012-01-05:ed4417a7059b5d1ff91904645c482f4b/020ddc23f9b1f5ddbab1aa2cae4f0cccAmitai Schlair2014-09-12T01:36:15Z2008-11-01T16:43:00Z
<p>This morning, as I watched an elderly black couple board a full subway car, a seemingly unremarkable series of events occurred: a young white woman rose and offered her seat, then a middle-aged Hispanic man did likewise. America at its best, in a nutshell, right? But it wasn't so long ago that America didn't work that way — as these two old folks doubtless knew better than I. With the election mere days away, I wondered: what would an Obama presidency mean to them? My emotional response was immediate and shocking. I had to turn my mind away from the thought to keep from bursting out in tears somewhere between 96th and 103rd Streets.</p>
<p>I don't know anything about these two people, I don't know how they've struggled, I don't know where their political sympathies lie. Maybe they aren't Obama supporters; it doesn't matter: I can easily imagine two more just like them who are, and I can make the leap to imagining that an Obama victory could be the sort of victory that justifies all they went through, that makes it all worthwhile in the end. Because they would have seen this happen, in their own lifetimes, with their own eyes.</p>
<p>Like I said, I don't know anything about these two people, other than their age and skin color (<a href="http://www.twainquotes.com/Congress.html">but I repeat myself</a>). Yet the narrative I facilely superimposed on them acted on me with tremendous force, and if I think about it only out of the corner of my brain, I can understand why. Freedom and justice are two of my most vulnerable emotional pressure points.</p>
<p>My ability to empathize with fictional people notwithstanding, for me Obama represents neither freedom nor justice. I fear his presidency almost as much as I suspect I'd like him personally. (In the interest of fair and balanced commentary: I fear McCain's presidency far more than I'd probably like him personally.)</p>
<p>I don't want to be 80 before my country shows signs of offering me the freedom and justice I deserved all along. I don't want a symbolic shift that's enough to let me finally die in peace. I want my government to recognize and protect my rights. I want it soon, so that my life can be the better for it. I want my own liberation in my lifetime.</p>
<p><em><span class="caps">P.S.</span> If you think I'm a jerk for even making this comparison, then you've just been a jerk. Don't presume to tell other people what their oppression feels like, let alone whose is more valid.</em></p>