Butts in Seats: Part Duh

Several eons ago (i.e. December 2019), I wrote a post called Butts in Seats that made the astounding claim that the whole business of having people come in to a shared office five days a week for at least 9 consecutive hours (don’t give me this 8-hour day bullshit) was over. Done. Finito. Old news. In fact, I called myself a dinosaur for having a residual fondness for the butts in seats concept. Well ..

Technical co-founder looking ahead to the future of work in the Cretaceous Era.

From: Rex, T.
To: Civilization Steering Committee, Ranking Member/Theropods
Re: Our way of life

With respect to some of the recent environmental changes, some of the other theropods and I think that learning to live in holes in the ground might be a good idea. It’s clear from the KPIs that business is down slightly. With searing hot glass particles raining from the sky, tsunamis wiping out the coasts and wildfires sweeping the earth it’s become much more difficult to carry out our daily, keep-the-lights-on business out here in the open never mind starting any new lines of business.

Some ideas we already came up with – we could make shelters out of the deadly, searing hot glass particles. We could work by the light of the wildfires. Not ideal, obviously, but on the plus side, there’s lots of attractive new oceanfront property to build on.

We propose forming a committee to look into it. Might take a few millennia to get a good start on it, we’d have to do a pilot project, gather some metrics. We’ll need representation from all departments, yes even the sauropods. I know they’re slow but what are we going to eat if we don’t bring the sauropods, right? We acknowledge that selling this to the pterosaurs and icthyosaurs will also be problematic. It will take some time.

Let me know what you think. No rush. We’ve ruled the earth doing things this way for 150 million years and that’s not likely to change anytime soon.

T. Rex

PSA: Empty Test Suite

I’m writing this post, and tagging it with “Empty Test Suite” all over the place, because Googling “Empty Test Suite” won’t tell you what I discovered.  In fact, the StackOverflow method of debugging this led me on a couple of hours of bad adventure.

The setup:

  • Android Things developer preview 0.6
  • Raspberry Pi connected hardware
  • IntelliJ
  • JUnit tests using the AndroidJunitTestRunner

Almost all my tests (200+ at this point) are run on-device as they require hardware.  After hours of fiddling with Gradle, I get my tests, 45 minutes worth, running on the device.  Even hooked it up to the CI pipeline.

Then I went on a couple of hours worth of refactoring.  Run CI again, and bang! Empty Test Suite.

Testing started at 2:07 PM ...
 02/13 14:07:17: Launching Tests in 'com.farlo.android.bubbles.control.rule'
 $ adb push C:\Users\rodley\Documents\bubbles\Bubbles\build\outputs\apk\blue\debug\Bubbles-blue-debug.apk /data/local/tmp/com.farlo.android.bubbles
 $ adb shell pm install -g -t -r "/data/local/tmp/com.farlo.android.bubbles"

$ adb push C:\Users\rodley\Documents\bubbles\Bubbles\build\outputs\apk\androidTest\blue\debug\Bubbles-blue-debug-androidTest.apk /data/local/tmp/com.farlo.android.bubbles.test
 $ adb shell pm install -g -t -r "/data/local/tmp/com.farlo.android.bubbles.test"

No apk changes detected since last installation, skipping installation of C:\Users\rodley\.gradle\caches\modules-2\files-2.1\com.android.support.test\orchestrator\1.0.1\12d61be26b643c6413d207248660bce8f6d8b236\orchestrator-1.0.1.apk
 $ adb shell am force-stop android.support.test.orchestrator
 No apk changes detected since last installation, skipping installation of C:\Users\rodley\.gradle\caches\modules-2\files-2.1\com.android.support.test.services\test-services\1.0.1\c24c3f3ccf05dfdd86dbcd6c7a648d6c4a429178\test-services-1.0.1.apk
 $ adb shell am force-stop android.support.test.services
 Running tests

$ adb shell CLASSPATH=$(pm path android.support.test.services) app_process / android.support.test.services.shellexecutor.ShellMain am instrument -r -w -e targetInstrumentation com.farlo.android.bubbles.test/android.support.test.runner.AndroidJUnitRunner -e package com.farlo.android.bubbles.control.rule -e debug false android.support.test.orchestrator/android.support.test.orchestrator.AndroidTestOrchestrator
 Client not ready yet..
 Started running tests
 Tests ran to completion.

Empty test suite.

That error message seems pretty clear.  The test runner couldn’t find any tests to run.  To me, this said that I’d broken my build configuration – either grabbing a bad dependency, picking the wrong test runner or otherwise hosing the build.gradle somehow.  Setting up connected testing was just painful enough in those particular ways that this seemed almost inevitable.

Well, the error message wasn’t clear, or at least complete.  What happened was that my Android Application was blowing up on a simple null pointer in the onCreate and crashing the process, which the test runner, bless its heart, interprets as an empty suite.  If I had, first time out, looked at the logcat:

02-13 19:03:04.404 10994-10994/? E/InstrumentationResultPrinter: Failed to mark test No Tests as finished after process crash
02-13 19:03:04.407 10994-10994/? E/MonitoringInstr: Exception encountered by: com.farlo.android.bubbles.BubblesApp@d5f45a0. Dumping thread state to outputs and pining for the fjords.
 java.lang.NullPointerException: Attempt to invoke virtual method 'void com.farlo.android.bubbles.Cabinet.setupMonitoredDevices(android.content.Context)' on a null object reference

I would have seen that I’d written an easily fixed bit of crappe code, not a painful gradle misconfiguration.  If the tests had been running locally, not connected, the crash would have reported to the console just like the erroneous “Empty Test Suite” message, and again, the issue would have been obvious.

Empty Test Suite?  Check the logcat.

It’s the little things …

… that make the difference between good/fun and not-so-good/not-so-fun.

Terminology for example. (Oy, here he goes again on the name thing!) There are a fair number of things that have to be named when you’re trying to make something from nothing.  The company, the product, individual projects, components, workflow states and transitions, interfaces, even the term you use to describe customers (guest, client …).  They all have to be named.  And as close readers of this blog know (Hi Mom!) the first name you pick for something usually sucks.  Which means that not only does everything have to be named, it usually also has to be renamed.

When product (and seriously it’s always those guys leading the renaming charge) decides to rename something it takes a while for the terminology to work its way through the org, whether your company is 4 people or 400.  For some things, in some organizations, you never really flush out the old name.  The dual names then become a form of low-level, everyday friction.  C’est la guerre, right?  Well, no, it’s not.

I was forced to think about this by a stark counter-example.  I was sitting in a meeting one day, not paying much attention when I realized that we’d been talking for awhile and all three people from one particular group had nailed the just-changed-yesterday name for the product in question every single time.  The rest of us were all over the map.  It stuck in my head as a data point that probably meant something.

bossPersonally, I was always bad at this and tended to hang on to the old names.  I’m not very good at remembering people’s names so why should it be any different for things?  But when I thought about it, I realized that I didn’t hang on to old names for things because I couldn’t remember the new ones, at least not most of the time.  It was because I thought that renaming things was stupid and I was annoyed and often had “the juice” politically to get away with hanging on to the old name.  Passive aggression at its finest.

Very occasionally I see product people get annoyed by this phenomenon, but I’ve never seen anyone take it seriously.  From the product side of the house I suspect that this inability to make a name-change and have it stick quickly is a low-level irritant that decreases their effectiveness and quality of life, but never rises to the level of “I have to do something about this”.  It’s one of those things that leaves you pissed off but you’re not really sure why.  Well now you know why – you’ve been passively aggressed.

When you’re building a team and trying to get some momentum this is one of the little things you can watch, and use to prevent problems you’d otherwise have to ‘fix’ later, probably by firing someone’s sorry ass.  Somebody who consistently uses old terminology is actually arguing with your right to name things.  He’s saying “you’re not the boss of me”.  Fix him now, or fire him later.

For my part, hereby resolved – the next time I’m leading a crew, this is one of the things I’ll be paying attention to, for myself and for the crew.  Perhaps I’ll make a point of explaining it up-front. Or now that I recognize the root of the issue maybe I’ll just jump on anyone who’s not with the program.  Fair warning.  And to all the product people in my past – my bad.

The 83b Episode

… or me and my six-figure mistake.

3boysblocks1You start a company with a couple of guys and it’s really hard to picture it turning into anything more than an excuse to work together for awhile before you go out and get real jobs.  Sure you start a real company but ‘exits’ happen to other people.  You’ll be happy to build something cool, have some fun and not go broke.

So when we first issued the restricted stock for this particular venture it didn’t feel like a big deal. As always, it was an article of faith that this one, like most startups would amount to nothing. I had to assume that to retain my sanity. It’s easier to tell yourself and everyone else that you’re a psycho who works like a madman because you like it, than to admit that you’re betting a shitload of sweat equity on a super long-shot.

No surprise then, that when it was time to file the 83b election form I prioritized it appropriately. The 83b election is the IRS form you file to get any appreciation on the stock treated as capital gains rather than personal income.  And when I say appropriately, I mean I put it at the bottom of the task pile, below laundry and beard trimming.  The problem with that approach to the 83b is that you have 30 days from receipt of stock to file it or it doesn’t work.  So one day I was driving along and realized that the 83b was laying on the passenger seat next to me, unfiled, and it’d been a lonnnnngggggg time since I’d signed it. An icy chill shot through me. I stopped at the nearest post office and, without actually doing the calendar math, fired it off to the feds (and the state?!), return receipt requested.

Fast forward several years and lo and behold, we’ve done something right and someone wants to buy the company. Suddenly the 83b takes on incredible significance. If I did it right, I pay 15% capital gains on the money. If I screwed it up, I pay 35% personal income tax on it. A difference of 20% – or as we used to say back in Inman Square, six fucking figures.

Now I’m not the most organized guy in the world.  If it’s not in source control  or my pants pocket (what has it got in its pocketses?), I have no idea where it might be.  And the company was not the most organized operation so the paperwork I had was crappy and scattered all over the place. But what I HAD retained in a nice neat little box in my brain was that spear of icy fear that I’d screwed it up – I’d missed the deadline. I was convinced of it.

Worse, I would have to turn the house upside down to find the paperwork and all that effort would merely prove that I was an idiot. And having realized this in the middle of the week, there was nothing I could do about it until I had the time to go through every piece of paper in my office.  A sloppy mistake I made years ago cost the family six figures. We didn’t have six figures to give away.

Mrs Pointy-Hair found me sitting at the kitchen table that first day. I told her I was worried. Mrs. PH and I have been together for a long time, through our share of ups and downs, and that’s the first time I ever said that to her. I’m not a worrier.

That Saturday I sat for seven hours sorting through 10 years of tax returns and every loose piece of paper in my office. The 83b showed up right after lunch, dated September 21st. Then a few hours later, a return receipt signed by the nice man at the IRS office. October 19th. 28 days. Sloppiness had nearly cost me six figures.  I’d done a shit job getting the 83b in on time, and I’d paid no attention to the return receipt, just threw it in a file and forgot it.  How close I skated to the edge of that abyss is appalling.

But you don’t come here just to see me confess the occasional sin and shred startup CEOs and glibertarian developers.  Come for the entertainment, but stay for the education.  So without further ado, the several lessons to be drawn from this sordid episode:

  • Memory sucks, mine more than most. I can draw up the network map of a data center I haven’t seen in ten years but I remembered the formation of the company, the transfer of stock and much of the action at the company wrong – completely wrong.  In one case, I was looking in the wrong boxes because my recollection of an event was off by two years.  As I sifted through the paperwork it was clear that stuff I thought had happened one way really hadn’t.  It was like reading about someone else’s life.
  • Being generally correct is better than precisely incorrect, but being precisely correct is even better. Who knows, if I’d prioritized 83b ahead of something else that might have started a chain reaction and we might have missed a contract milestone and lost the business right off the bat.   Right.  Measured precisely, it was still higher priority.  And if I’d read up on 83b at the time I would have filed away the “nailed it” feeling when the return receipts showed up.
  • Here’s one for the ladies: Don’t marry a guy who makes up convoluted rationalizations for not sweating the details.
  • Sloppiness kills.  If I’d had one more layer of crappe on top of it on the passenger seat, I wouldn’t have seen the 83b in time.  If I hadn’t been driving by a post office (those things are EVERYWHERE!) I might have put it off again.
  • Whatever it is, do it now.  Really, how fucking hard is it to go to the post office?

Choose Wisely

choosewiselyThe most important lesson of all though is choose wisely – in this case choosing your partner.  That came with Mrs. Pointy Hair’s reaction to the (incorrect) news that I’d pissed away a house or two by not going to the post office on time.  She listened patiently to my confession and simply said:

Well, it’s still a lot of money.

And she was right. Capital gain or personal income, it WAS a lot of money. And I love her for realizing that when it mattered, not years later when it wouldn’t.

Mistakes … I’ve Made A Few

… but then again, too few to mention.  Ah yes, I’m dating myself with that reference but if I don’t, who will?

I spend a lot of time slagging the business guys and believe me, they’ve earned it.  That said, even when the business guys weren’t in the building, mistakes were made, and if you looked at them a certain way, you might even attribute a scintilla of responsibility for some of these missteps to me.

So without further ado, here are the autopsy results from a few of the ones I think I understand and am willing to admit to.  Believe me, there are a few that are worth their very own post, and there are a few I’m taking to the grave with me.

Waiting too long to fire underperformers

lucyshowTrue story: I inherited this guy from another manager, and he was useless – “hello world” useless.  Not only that, but he had no shame about dragging other people in to get him out of whatever hole he’d coded himself into.  I watched for a couple of days and saw, in action, one of the fixed axioms of software: there is no upper limit to the amount of damage a low-performer can do.  Watching three people try to debug “Hello wo$#%@%^!” for this knucklehead proved that.  But, one of the few professionals we employed at the time was our HR person who told me how firing was done:

  • written warnings
  • improvement plan
  • constant monitoring and feedback
  • deadline for improvement

This was before I knew what an “at will” employee was.  So … a month later, after wasting countless hours on this guy and on a day when he brought in food for the entire team, I fired him.

That was a lack-of-aggression mistake.  I had the juice to just deal with it, but I asked for guidance and got timidity instead.  It still grates.  We were in a “hot” space and had great IP.  Deals and very important people were swirling around us.  We were running out of runway.  And I wasted a month firing an at-will employee who would never be more than a bad coder.  This episode and the fact that we went Chapter 7 are probably unrelated.  Probably.

Quick and dirty coding

flappingEven if you’re God’s gift to technology, you’re gonna commit crimes against computer science on your way to the promised land.  If you’re a huge dumbass you’re gonna commit lots of those crimes and for terrible reasons.  Let me illustrate:

  • In the early days of one venture, I wrote some C++ Win32 code that I wasn’t particularly proud of – lots of global variables, timing hacks, failsafe graphic refreshes – stuff I knew would need a rewrite.
  • In the later days of another venture, I wrote a pile of equally dreadful C# Web Services. Not thread-safe, non-transactional SQL, duplicate code everywhere …

In the first case, I was alone, literally doing the best I could and had to hit deadlines or we’d lose a contract.  In the latter case, I was bored and wanted to write code, but I had plenty of help and was just too lazy to do it right.  Equivalent crimes, but motive matters. You could also consider the latter a case of taking too long to fire a low performer – myself.

Bad Leases

leaseMy last venture launched when my kids were 20 months and 1 month old respectively.  If you can work in a small house with two children under two years old, you’re a better man than I.  That’s focus.  Me, I have noise cancelling headphones and a nice home office with a door that locks and I still couldn’t do it.  For awhile I was a nomad, I worked everywhere, Starbucks (g*d****d fruit flies!), the bar at Chilis, the commuter boat .. even the lobby of the Boston Harbor Hotel. I still have their guest wireless access code that we paid 10$ for back in 2005.  But all that’s barely better than working with a one year old in your lap.

So we sublet space at a lawyers office and that early space was key, not a mistake at all because some of us needed it, and some of us needed to be together  But space takes on a life of its own.  There came a moment when we had more people than the lawyers office could hold, but we weren’t in a position to make a decent deal for space anywhere tolerable.  People started piling up.  We weren’t happy.  The lawyers weren’t happy.  There were people (yours truly) making demands about location.  The pressure mounted.

What should we have done at that moment?  Gone virtual, at least partly.  Would it have been a pain in the ass to manage?  Yup, but lots of worthwhile things are a pain in the ass.  What did we do instead?  We made a deal for more space than we actually needed or could use.  Dreadful space.  No build-out, horrible floor plan, nasty carpet, 8 thermostats none of which controlled the temperature, lighting better suited to a Turkish prison and as a bonus we got the landlord as a shareholder.  When our exit came, we were still in the same shitty space because part of the shitty deal was a lock-in.  Maybe I didn’t make the deal, but I made it all but inevitable that a deal like that had to be made.

What kind of mistake was this? Failure to look at the big picture maybe, but actually more just inexperience. I didn’t know the space bit until I’d lived in it for awhile.

Shooting from the hip

cf-yulBrynnerWestworldIf you have any success with your startup – last a few years, hire a few people, get some traction – you get pretty good at shooting from the hip.  The first technology that pops into your head does the job, the first algorithm you think of is “good enough”, your first take on an interviewee proves out.  You’re a bright guy and it never takes you more than 90 seconds to figure anything out.

Trouble is, with all that shooting from the hip, you forget how to do it right – the take-a-deep-breath-aim-and-fire method.

Guy comes into my office with a code problem.  He lays it out, I get impatient and my mind starts to wander, eyes start to glaze over and as he gets toward the end I lose patience and blurt out “Just do X” where X is something plausible, but probably quick and dirty.  Usually, my saying “Just do X” ends the conversation but this time the guy doesn’t move.  He just stands there because, first of all he likes to do things right, and second, X isn’t plausible, in fact it’s stupid, and proves that I wasn’t listening and just want him out of my office.  I realize in a flash that I’ve been doing this to this poor guy for months.  What I kidded myself was decisive and incisive, was actually glib and dismissive.  I tell him “okay, sit down and start over” and force myself to focus patiently on the problem.  And whenever he comes back to my office, I take a deep breath and do it all over again. Leading sucks sometimes.

You can file this one under “scaling with the organization” I guess. It took me awhile but eventually I learned to stop looking at my own navel long enough to actually manage my crew.

So there are some of my mistakes. Got any good ones you’d like to share?