November 9th, 2015
(written by lawrence krubner, however indented passages are often quotes). You can contact lawrence at: firstname.lastname@example.org
(Note: I must offer a huge “Thank you” to Natalie Sidner for the tremendous editing she did on the rough draft of this post. To the extent that this article is readable, it is thanks to her. Any mistakes are entirely my fault. If you need to hire a good editor, contact Natalie Sidner at “nataliesidner at gmail dot com”.)
I have been working with startups for most of the last 15 years, and one common pattern that I’ve seen is the startup that has a brilliant idea but terrible management. Those news outlets that focus on startups tend to focus on the success stories, but the whole startup ecosystem would be stronger if we heard more stories about the promising startups that go astray. I feel I can offer a real service by documenting my own experience and offering it up as a case study. I’ve spent the last 6 months working at Celolot, which falls into the “great idea/bad management” category. The idea is brilliant: Natural Language Processing as an interface to interact with big Customer Relationship Management tools such as SAP. The execution has been flawed.
I wanted to communicate the sense of how easy it is to make mistakes in a fast evolving startup. I hope I have managed to convey at least some of the details that make this story so fascinating to me.
I’ve skipped over most of the computer programming details, as my intended audience is everyone who cares about building a business. I believe this is an exciting struggle, and one that a lot of people attempt at one time or another. I could write another post that goes into detail on the technical side, but here I’ve tried to keep technical details to the minimum needed to communicate what difficulties we faced.
All names have been changed except for mine.
When I joined Celolot in May, the mission was to build an Android app that could interact with SAP. Celolot had hired a design firm in Brooklyn to develop the look and feel of the app.
Hinton (our 22 year-old CEO) had done an internship with Milburn, a man in his 50s with a successful career in sales. They had come up with the idea together. Milburn then pulled in some of his friends and they put together $1.5 million to get the company started. Milburn put himself on the Board Of Directors.
The tech team consisted of three people: Pranab would build the Natural Language Processing app, Shinzo would build the Android app, and I would build the API app, which the Android would talk to. I would also build our SAP app, which would talk to SAP. I was nominally the tech “lead” but I started with the assumption that we were each excellent at our own tasks, and so each of us could be trusted to build out the part of the system which we had been hired to build. Three of us worked at a startup incubator in New York City, but Shinzo was working remotely from Washington D.C.
The full Android app was expected to take 6 to 8 months, but we thought it would be enough to just get the part relating to Targets working, and then we could start showing it to potential customers.
We worked hard in May, June, July, and we were on track to push out the first version in August.
Then came what can be described as the Big Pivot. Hinton, Milburn and Zach (our lead sales guy), decided we should get rid of the Android app and switch to a pure chat app. We would now use Natural Language Processing for everything. Instead of the user clicking a button to edit old Contacts, they would type, “I want to edit the info about my contact Jenny Hei,” and we would then find the info about Jenny Hei and offer it to the user so they could edit it. That was the new plan.
This was a brilliant idea. Salespeople hate software. They are good dealing with people, but they hate buttons and forms and all the other junk that is part of dealing with software. A pure chat interface eliminated all of that debris that salespeople dislike. It also meant that it would be easy to eventually introduce a voice-based interface.
If Celolot could become the default way that people interacted with the big CRMs, such as SAP, then Celolot could eventually tax much of the value in the CRM ecosystem. Therefore, Celolot had the potential to one day become a multi-billion dollar company.
But even though the basic idea was good, there were mistakes in the way the Big Pivot was handled, starting with the fact that the tech team was never consulted. I have the impression that Milburn decided the Big Pivot would not cost much time, and he reassured the rest of the Board. Yet in reality, giving up on a traditional UI — full of buttons and forms — and switching to 100% pure Natural Language Processing increased the complexity of the programming by an order of magnitude. We were decreasing the complexity that our users had to face, but we were greatly increasing the complexity that we programmers would face.
The tech team was not consulted about the idea, and we were barely consulted about the implementation details. For instance, management decided that we no longer needed an Android app because we could use the standard Android chat app to send text messages, and we could rely on the text-to-server service offered by Twilio to send the text messages to our servers.
Hinton told me we no longer needed Shinzo, but he didn’t want to talk to Shinzo about this and I was told that I needed to remain silent as well. I was not comfortable keeping this secret. I was going to D.C. the next day, so I met with Shinzo and I told him what was going on.
An early stage startup is either a transparent learning organization, or it is dead. When given a chance, Shinzo pointed out the many custom features that we could build that we couldn’t get with Twilio. And later, in October and November, testing would have been a nightmare if we didn’t have our own app. Moreover, if we had used Twilio it would not have saved us much work, since we can’t send a user’s SAP username and password in plain text via text message. So we would have been forced to build a website where users created accounts and gave us their phone number, SAP username, and password. The use of Twilio was a terrible idea, yet Shinzo and I had to fight against it for days before management conceded. In the end, it was agreed that Shinzo would create a specialized chat application for us.
We spent so much time and energy fighting against an implementation detail (Twilio) that we never had a conversation about the Big Pivot itself.
The Big Pivot cost us an extra three months of work, something that eventually had the Board Of Directors in terror. Milburn had suggested the Big Pivot would be easy, so they were taken by surprise by reality.
Over the summer we built a simple one-page website that allowed us to demo the Natural Language Processing engine. The Android app was not yet working, so Hinton used the website to show potential customers how they could type in a sentence and get back a parsed version of what was typed.
Hinton would write: “I just met with Susan Malle of Hilton Hotels and they committed to buy $10000 of cleaning supplies. We close on November 1.”
The Natural Language Processing engine would respond: “Please confirm, the Person is Susan Malle, the Delivery Date is November 1 2015, the Owner is Hilton Hotels, the Money is 10000 and the Items are cleaning supplies.”
Hinton got a very positive response from the people he showed this to. Several companies suggested they would be interested in using Celolot.
Around this time Hinton stopped going to class at NYU. I was pleased because this meant he could work as much as the rest of us. Although his parents had put a lot of pressure on him to stay in school, even part-time, we needed him to focus on Celolot.
There was the issue of Pranab’s excessive hours spent playing video games. I complained of this to Hinton, but Hinton hated any form of confrontation, so he excused Pranab’s behavior by saying that everyone occasionally goofs off at work. That is true, and I have checked personal email and watched funny YouTube videos while at work. I agree that everyone does this to some extent. But Pranab was spending easily four hours a day playing video games. More to the point, there was a great deal that he did not know about computer programming, and he could have spent the time learning all of the many things that we needed him to know.
Hinton had a major demo coming up on July 3rd, but as of the evening of July 1st, we could not send a message to the Natural Language Processing app and get back a response. Pranab and I began work at 11 AM on July 2nd and we gave up 21 hours later, at 8 AM on July 3rd. We took a one-hour lunch break and a two-hour dinner break, but we put in a solid 18 hours of work during that 24-hour period. To his credit, in these urgent situations, Pranab was willing to put in long hours. He simply had no idea what he was doing. The number of errors were endless: cast errors, regex errors, dependency issues and more. This was a case where we were sabotaged by the strict typing of Java. (My apps were written in Clojure, but his app was written in Java. They communicated by sending JSON objects to each other, via Redis.) Since we were changing the data structure every 4 or 5 minutes, we were getting endless cast errors. If we had been using Clojure, and simply manipulating hashmaps nested inside of hashmaps, then 50% of the errors would have vanished. Sad to say, we were not able to get the app working by 8 AM on the 3rd. We did get it working a few days later.
During July and August, I spent half my time working with Pranab on his code. I became his teacher. If Celolot had been officially committed to running a mentorship program for junior programmers, then of course I would have understood that this was a responsibility of mine. However, we were not running a mentorship program. Instead, I was repeatedly told that speed was our #1 priority.
Shinzo and I were worried about the project running late. After countless delays caused by bugs in Pranab’s code, Shinzo and I asked Hinton to fire Pranab and replace him with someone more competent. Shinzo and I both felt that Celolot would progress much faster if we had a team consisting of three excellent programmers. Hinton did not want to fire Pranab. Hinton was not comfortable with confrontation. Also, he suggested that Pranab was working for a low rate, and if we hired an excellent Natural Language Processing expert, they would be very expensive. I thought this was very odd. We were trying to do a boldly cutting edge Natural Language Processing startup, but without a top-notch Natural Language Processing expert. The room for failure seemed large.
During July and August, one thing that allowed us to move faster was that I went to Washington D.C. once a week to work directly with Shinzo. Half the time Celolot paid for my travel, and half the time I paid for the ticket myself.
When the Board decided on the Big Pivot, we realized we would have to track the state of the user’s conversation on the server. Pranab was given this task and he worked on it for three weeks, but he was not able to get it to work. At the end of August, I took responsibility for writing this code. After a few days of work and research I realized we would need a Finite State Machine that could track our user’s conversation. I estimated this would take four weeks of full-time work (which implied eight weeks of part-time work). On September 3rd, I tried to emphasize the importance of this by sending an email to Hinton which said, “This will be the most important software at the company. Everything else is just a sideshow.” If the Board had been willing to give me six months, then I could have written all the code myself — but no one wanted to wait six months, so I suggested we bring someone else in to do this work. A week went by before we started doing interviews, another week before we hired someone part-time, and then another week before they started.
To be clear, I would have preferred if we simply had 3 excellent programmers working full-time, but we ended up with 2 excellent programmers working full time, a very junior programmer working full-time, and another excellent programmer working part-time. This was not ideal, but it was the best that I could get Hinton to agree to.
This is how the autumn played out.
September 17, 2015
By this day, I had chipped away at the Natural Language Processing code that Pranab had written until we finally had a working demo. I fixed the issues with concurrency. I also wrote a very simple 8-line if() statement that could handle the barebones of a conversation. This was not good enough for real-world use, but it was good for a carefully controlled demo. Once the conversation Finite State Machine was done, it would take the place of this if() statement.
September 18, 2015
Hinton showed the working demo to the Board Of Directors. I was not invited to this meeting. (I never met the Board). Hinton failed to communicate to the Board that this was a toy demo that was not meant for real world use. Unknown to me, the Board decided to schedule their next meeting for October 16th, at which time they wished to hear feedback from customers. I was only told of this a month later, on October 12th — four days before the supposed meeting.
Hinton and I had worked late on the 17th so we could test the demo, therefore Hinton had a good understanding of how fragile the app was. It was extremely irresponsible for him to leave the Board with the impression that we would be able to give the app to real customers, and get feedback, all within a month. Hinton did not like confrontation, and he was eager to please, so I can imagine that when the Board pressed him to move forward quickly, he assured them that he would.
The idea that this was ready for customers was ludicrous, and Hinton knew this.
September 21, 2015
On this day, Gregory started working for us. We contracted him for 20 hours a week. He was to work on our “user-convo-finite-state-machine”, that is, the Finite State Machine that would handle the current state of the user’s conversation.
At the same time, I started working on “nlp-wrapper”, which became a wrapper around Pranab’s code. Pranab’s app would now become a narrowly focused Natural Language Processing library that would be included inside of nlp-wrapper.
Of course, this didn’t leave much work for Pranab. I had taken over a lot of the responsibilities that had originally been his. But he simply didn’t know how to write the app we needed. (Later, in mid-October, I asked Gregory to take over the responsibility of developing the nlp-wrapper app, so I could get more time to focus on SAP integration.)
I set up a wiki on Github and established 2 pages for each app, one that showed what data the app expected to receive, and one that showed what data it returned. I emphasized to everyone the importance of keeping this up to date, however, Hinton felt that documentation was a long-term issue that got in the way of our short-term goals.
Milburn put a lot of pressure on Hinton to go out and show our software to customers. Hinton, in turn, put a lot of pressure on us to get the software working so he could do what Milburn requested.
September 22, 2015
Hinton had been working with an outside agency to develop the video that we would be posting on our promotional web site. The video was extremely impressive. It promised many features that I thought we would need another six months to develop, but if the goal of the video was to simply to sound impressive — after all, maybe it was more aimed at investors than customers — then this video was very well done.
Late September and early October, 2015
Hinton had scheduled a meeting with potential customers, but the software was not working yet, so he had to cancel it. He scheduled another meeting for the 24th and the 25th and the 30th. All of these eventually had to be cancelled. The whole team was working long hours to transform our demo into real working code, but it was an arduous effort. I did, several times, try to hard-code enough stuff that it might have worked as a demo, but there were frequently edge cases, such as credential timeout issues, that triggered Exceptions in the code. Hinton grew very frustrated that he could not do a demo. Reviving a pattern from the summer, I wanted to go to D.C. one day a week so I could work directly with Shinzo, but I was told we could not afford it. For the demo that Hinton wanted to perform, we had the option of spinning up a dedicated server that would run the demo we gave on September 18th; the same amount of money, however, would have covered the cost of several tickets to D.C. — and my preference would have been to go to D.C. Also, of course, the demo of the 18th was extremely fragile and only worked under very controlled circumstances, so there was no way to put it into customers’ hands.
October 8, 2015
Hinton did not like direct confrontation, so he never expressed anger in person. When he needed to vent, he would post an angry message on Slack. And so he wrote:
“I was tld this was workng and ive also been told itll be ready today everyday for the last 2-3 weeks. the ‘issue is that it doesnt work.x. just need to send messages through i dont car about stabilty nd long run anymore, i cannot express it enoguh no one cares. very simple. Just need a miniml viabl product. the long run stuff all means nothing if this gets continus to get “delaayed one more day” for more and more days. very simple just send simple json mesages thats all so i can use the product already. just upload som sort of simple buildlike such tomorrow. Everyone havea good night talk to you all tomorrow when we have a minimal viable product upa dn runing and deeliverable tomorrow.”
There was a lot here that seemed completely beside the point. We were not having any trouble serializing and deserializing JSON. We had fixed those issues in August by writing a lot of serializing and deserializing code, and besides, the issue had vanished completely once I created the nlp-wrapper app (which was in Clojure, like the other apps, and therefore all of our apps could now use Carmine to talk to Redis, and Carmine used Nippy under the hood. In other words, all of our apps were now using the same serialization/deserialization library, so we no longer had to think about serialization/deserialization at all. It was invisible to us). We were not doing any work on long-term issues, though he might have thought that our documentation on Github was a long-run effort with no short-term benefit. That was false. We needed to understand what to expect from each other’s apps, so the documentation on Github had immediate short-term benefits. We were focused on getting a minimal viable product out the door, but the issues we faced were still complex. We could not fix everything in a night, no matter how much we wanted to.
I responded on Slack:
“My suggestion would be: if you have never tested the software yourself, then don’t promise it to customers and don’t schedule demos. Most of the places that I have worked have at least a month of testing before a product goes to the public. You are setting yourself up for failure if you promise software that isn’t yet working — we can never be certain exactly what day it will be ready. And even it is working, you should test it yourself to see if there are any serious bugs.”
October 9, 2015
Hinton told me that the Board was running out of patience. We needed to get the software into the hands of customers soon, otherwise the Board might cut off all funding and shut Celolot down. I wasn’t clear if this was true, or if this was an empty threat. If the goal was to motivate us to work harder, it was an incredibly stupid move. I was running into my physical limits from lack of sleep. If the Board wanted to close us down, despite our efforts, that was the prerogative of the Board. I do not believe that Shinzo or I could have possibly worked any harder. I reminded Hinton that if he wanted to see us move faster, he could fire Pranab and hire a competent replacement. For some reason, this option was off the table.
October 12, 2015
Hinton and Milburn were angry that the project was running later than they wanted. They suggested that I was incompetent. Milburn told Hinton they were sending in a high-level consultant. The consultant was an old friend of some of the Board members, someone they trusted. The consultant was described as a superstar of computer programming, a guy who has turned around many crippled teams. This superstar consultant was going to analyze the mistakes we had made. He was going to save the situation.
To me, this seemed like they were getting ready to fire me. What could the consultant do but come in, blame some stuff on me, and take over the situation? It would be a chance for the consultant to pick up a lucrative contract. Even if I was innocent, he would lose nothing by blaming all current problems on me.
We were ordered to have a phone call with this consultant. Hinton and Shinzo and I were on the call. Hinton started with ten minutes of summarizing what we were doing. Then the consultant described himself. I was impressed. It sounded like he had done a lot of incredible technical projects. I had to respect him, even if he was being called in to replace me.
The consultant asked what he was needed for. What was the problem?
Hinton asked me to summarize the situation. I summarized: the initial plan to do a complex app on the Android; the Big Pivot to doing a simple chat app; moving the real complexity to the server; our problems working with Pranab; the fact that Pranab played video games all day; that in mid-August Shinzo and I had asked Hinton to fire Pranab; the complexity of building a “finite state machine” that can manage conversations with humans. I went over each of the issues we had wrestled with.
Hinton jumped in. He was embarrassed that I had mentioned Pranab. He described what he felt was the real issue: small problems kept coming up on a day-to-day basis. The software needed to work, but it was not working.
The conversation went on for another ten minutes, entirely between Hinton and the consultant.
Finally, the consultant offered his conclusions. We were doing something that no one has ever tried before. We were going beyond what Siri does on the iPhone. Most Natural Language Processing apps only handle “one response to one question,” but we were going further; we were trying to track entire conversations over long periods of time. The project was extremely ambitious. Also, we were clearly wrestling with personnel issues that needed to be addressed.
He said he wouldn’t be able to help. He would only slow us down. The team (us) seemed to know what it was doing and simply needed time to get the work done. A project this ambitious was inevitably going to hit some tough moments. The Board would have to accept that.
Hinton thanked him and promised to tell the Board what had been said.
We hung up.
I was very pleased. That went waaaaaaayyyy better than I expected.
Immediately Hinton called me back, and he got Shinzo to join the call. Hinton was furious that I had mentioned Pranab. Hinton said that I was never, ever to mention Pranab again. I got angry and told him that I was going to mention Pranab every time anyone asked me a question like “Why are you running late?” If anyone implies that I am the reason the project is running late, then I will bring up the personnel issue that has been ignored all summer. I said we could have finished this project a month sooner if we had three excellent programmers. I told Hinton that I refused to take the blame for his bad decisions. He would have to take 100% of the responsibility for building a flawed team.
Then his tone changed and he said that there was no question of blame, that no one had ever blamed me for anything, that the Board was not blaming anyone for anything, that this had merely been a fact-finding phone call to gather data, not to access blame. He and I went back and forth a few times. Finally, Shinzo stepped in and played the diplomat. We spoke for another hour. Everyone calmed down.
Finally, Hinton asked, “So, when the Board asks me what is going on, should I just keep that information from you? Would that alleviate the pressure you feel?”
I said, “Hinton, I want you to share as much information as possible, but it would be nice if you sounded like you were on our side. You always sound like you are taking the side of the Board. If they ask why things are running late, it would be nice to think that you stand up for us and explain to the Board that we are all working hard.”
Shinzo agreed. Shinzo said he wanted to feel that Hinton was on our side.
Hinton said that there were no sides, that we were all on the same team, and that we should never feel there was an us-versus-them conflict between us and the Board.
All of which was a lie. Clearly there was a conflict between us and the Board. And clearly Hinton was on their side.
But at least for this one phone call, Hinton promised he would do more to be on our side.
One suggestion that the consultant had was that we should all document our work. I was pleased to get his support on this issue. After the call, I sent an email to the entire team telling them that we had had a conversation with a very important consultant who was sent to us by the Board, and the consultant said we should update our documentation, therefore it was very important that everyone update the pages on the Github wiki for which they were responsible. Neither Shinzo nor Pranab updated their wiki pages, unless I specifically prompted them to do so. Only Gregory was religious about always keeping his documentation up to date.
October 16, 2015
Hinton went to another meeting of the Board Of Directors. I have no idea what they discussed.
October 27, 2015
Hinton and I were at the incubator working late. Just then Milburn called and wanted to talk with us via video conference. Shinzo was also asked to join us via video conference. This was the first time I got to have a real conversation with Milburn. He appeared to be angry that the project was late. He asked a bunch of questions, such as, Where is the documentation? I pointed him to the wiki on Github but for some reason he dismissed this as invalid.
It was 9 PM and Shinzo had other obligations. Milburn was aware that I had been working long hours, and Milburn used this to shame Shinzo. Everyone should be working hard like Lawrence! Shinzo apologized profusely for having to leave. I felt grubby about being used this way, but I wasn’t clear what I could say. The situation was unfair, because Shinzo is a very talented programmer, and he had been working very long hours.
We ended on an ominous note. Milburn said the project had been badly managed, but he did not offer details. It was clear that he wasn’t saying the project had been badly managed because he had made a series of miscalculations regarding the Big Pivot. He was saying the project had been badly managed because of something the programmers had done. Then he said we would talk more the following day.
October 28, 2015
We spent six hours in a video conference with Milburn. This was an utter waste of time.
Milburn started by asking us what we thought of the baseball game the night before, the epic battle between the Royals and the Mets in Game 1 of the World Series. Pranab and Hinton both watch sports, so they both had opinions about the game. In that moment Milburn wanted to convince us that he was our friend, our buddy, our chum, someone we could hang out with and have a beer and laugh about the referees making bad calls. Pranab made a remark about how suddenly the game had turned around at some point, and Hinton laughed, and Milburn laughed, and they were all good fellows sharing a laugh.
I later learned that Milburn was fairly talented at playing both sides of a Good Cop/Bad Cop routine. Arguably, this is part of what has allowed him to become so successful. First he creates a friendly feeling, then he gets angry and he makes his new friends feel guilty for letting him down.
It did not take long before the laughing ended and the anger started.
“Where is the spec?” asked Milburn.
He insisted that we could not make any progress until we had a written spec. I again pointed him to the documentation on Github, which he again dismissed without giving a reason. I would have been pleased if he had said “This spec on Github is good, but everyone should do their part by keeping it updated.” This would have been useful. The data on the Github wiki was our spec, but we were constantly making changes to our code, and to the spec, as our understanding of the project came into focus. Sometimes Pranab and Shinzo allowed the pages relating to their code to become obsolete — that is, they made changes to their code, but they failed to update the Github pages. I would have welcomed additional support in keeping it up to date. All the same, I felt it was a solid spec.
We then spent two hours writing down what Milburn referred to as “the spec”. This was mostly an exercise so that Milburn could gain an understanding of the software. We walked him through the various scenarios: what happens when a user first logs in, what happens when oauth credentials expire, what happens when a user forgets to send us a mandatory field. He apparently felt this was important work, but I mourned the loss of a whole day spent in a meeting. In particular, I mourned the loss of momentum. I felt the team had made exceptional progress over the previous two weeks, and this day was like hitting a self-inflicted road block. What we ended up with was a high level document that was too much of a summary to offer any benefit to us programmers. It was absolutely the kind of summary I would have written if someone had asked me to write a summary for the Board Of Directors. But no engineer would have regarded it as a real spec.
Towards evening, Gregory joined us via video. We ended up talking for 20 minutes about whether a user should type “yes” or “Yes” to confirm an edit, and how much regex we should use to catch possible mistakes. Six people spent 20 minutes discussing this, while more important issues were ignored. The level of micro-management was ridiculous.
This was the most extreme case of bikeshedding that I’ve seen in years: this issue got a lot of conversation because Milburn was able to understand it. But the crucial issues, such as missing fields in the user’s conversation, were skipped over, because Milburn did not understand those issues. Classic bikeshedding.
Worse, I had been trying to get the team to stick to a two-week sprint cycle, and this Friday, the 30th, was suppose to be our next release day. One item that I had scheduled for the November 13th release was some code that would allow users to stay logged in for extended periods of time (using the SAP oauth refresh token). Milburn then said this was crucial and had to be included in Friday’s release. I said that we could not add new features late on a Wednesday for a release that goes out on Friday. Milburn insisted it had to happen. I said it was not going to happen. Milburn said it absolutely had to happen. I said it wasn’t possible. Milburn and Hinton said it had to happen. I repeated that it was not possible. Shinzo, via video, said we should do it, and Pranab agreed, and Milburn and Hinton repeated how crucial it was.
But in the end, it did not happen. As I later told Shinzo, I might want $1 billion dollars, but that doesn’t mean I will get $1 billion dollars; they can want this feature released on Friday, but that doesn’t mean it will be done on Friday. Merely wanting something to happen does not automatically mean it will happen.
October 29, 2015
This morning I was “late” going to the office, in that I was leaving my apartment at 11 AM. Milburn called me on my cell phone and asked me where I was. I explained that I mostly had to work with Gregory, and Gregory only worked evenings. Gregory typically worked from 6 PM to 10 PM and sometimes he had worked as late as 1 AM. He had a full-time day job and we were a secondary job for him. He was a very good programmer and I liked him. I had adopted a late schedule so I could overlap with him (and because I was not willing to work the 16 hours from 8 AM to midnight, which is what would happen if I started as early as Hinton and Shinzo and then stayed as late as Gregory sometimes did).
But now I had a member of the Board Of Directors calling me on my personal cell phone and asking me where I was. This situation was not sustainable. This level of pressure was not healthy. Either Milburn was going to soon go away and leave us alone, or I would have to find other work.
I worked late to find the source of our current errors. Everything seemed to indicate another bug in Pranab’s code. Around midnight, I decided to quit for the night. I sent an email to the team saying:
“The bug seems to be in the Transform class that Pranab wrote, but I am not sure which function.”
Milburn responded via email the next day:
“I would like to again ask that we not call out individuals – but the apps.”
It was odd the way they jumped in to protect Pranab.
October 30, 2015
We had a video conference with Milburn at noon. He said he wanted a 15-minute scrum session, but it stretched to 40 minutes.
Milburn started off by telling us that we needed project management software. Why hadn’t we thought of this? Hinton said we had project management software (PivotalTracker) but some developers (he meant me) didn’t keep it up to date. Milburn asked if some other software would be better? Pranab wanted to use Jira. Shinzo wanted something lightweight. I said that we did not need project management software, so much as we needed a project manager — someone who could keep track of what needed to happen, guide the right tasks to the right developer, then test all work as it was being done, and mark a project complete after the work had been witnessed working. I could not do this because I was too busy writing code. Hinton could do it but he got bored. Testing can be tedious. A good project manager has to have patience to test the same thing ten times.
I said, The best project management software won’t help us if we don’t have a good manager in charge, and conversely, if we had a great project manager then it wouldn’t matter if they preferred to write their notes on crumbled-up napkins, we would still benefit from having someone oversee the project.
Milburn said that from now on we were all responsible for the project management. I thought this was a frustrating dodge. The crucial issue was, who was in charge of saying when something was really done? We needed to answer that, but Milburn was not going to allow us to answer that. He wanted to reserve for himself the power to say that something was not done, but he did not want to get dragged into the tedious task of testing something ten times. That meant we would have no project manager. Without a project manager, the discussion over project management software struck me as utterly futile.
Then we started talking about what needed to happen next — Milburn wanted to know the exact problem we were facing at that moment. I gave a high level overview and then he demanded more detail. Back in the 1990s Milburn was an early user of Microsoft Excel and eventually became very good at it. He even learned how to program in Visual Basic, so he considered himself something of a computer programmer.
If he engaged in the conversation as someone who was moderately technical, I would be comfortable with the fact that he understood programming more than most non-technical people. But he instead seemed to be joining the conversation as someone highly technical, with no regard to the fact that his experience was out of date, and with no regard to the fact that we had many years of current experience.
I then described the problem in more detail, focusing on the race conditions. We had to manage the trick of sending the right error message to the Android when credentials were expired. He said it sounded like it should be easy to fix. I said, We have a lot of apps talking to each other, and getting them to all say the right thing at the right time is complicated. Milburn dismissed this as a meaningless excuse.
Shinzo suggested that we should test the whole system together as much as possible; we should not test the pieces in isolation.
Milburn then became obsessed with this idea. It’s so obvious! Why are we testing our code in isolation? Are we idiots? Why not test the whole system together?
I pointed out that testing the whole system together means using the Android app, and that means the software needs to be somewhere the Android app can reach it, that is, on a central server. Milburn looked at me like I was an idiot. Obviously we should do what I just said, why would I not want to do that?
Milburn said, “Once you have your code on the same server, you can all test the same code. Instead of testing stuff on your local machines, where you never know if your stuff matches up with anyone else’s stuff, if you push it all to a central server, then you are all testing the same code and you know whether or not your stuff works together!”
I pointed out that when I test code on my machine, I can see a bug, fix it, recompile, and re-test, all in a minute or less. But if I have to test on a central server, I need to push all my code to the central server, and recompile there, and then my see-bug-fix-recompile-retest cycle is about ten minutes long instead of one minute long, and so I end up fixing 6 lines of code per hour instead of 60.
Milburn became sarcastic and said, “The difference between my system and your system is that my system takes ten minutes and your system takes two months! If you just tested the whole system together then you would have been done in August!”
For most of August and September and October I had run all of the apps on my local machine, and thus had the whole system running together. But in mid-October I started testing the Android app. So we were currently doing a mix, sometimes working locally, and sometimes testing on a central server. I had set up Jenkins on our server to make it as easy as possible for me, or anyone else on the team, to push code to the server and test it in a unified way.
I could have downloaded Eclipse and asked Shinzo to help me set up the full Android development app on my machine, and then I could have used that as an Android emulator to test the whole entire system locally. But I never felt like we had a day free from the pressure of our short term deadlines, so it was difficult to justify the time needed to set up for local testing of the Android. When facing extremely short, ambitious deadlines, one knows there are a dozen good things one can do, but very little feels justifiable in the face of a crisis, except writing code as fast as possible.
Shinzo felt Milburn had misunderstood the situation, and so Shinzo spoke at some length about the advantage of using an Android emulator to test the whole system locally. These were good ideas.
Milburn loved this idea and said that all of us should have been doing this since the projected started.
“You’ve got to be testing the whole system!” he said. “All your problems so far are because you haven’t done testing! You’ve got to run it on your machines and see how this actually works.”
Then I said, “You just said the exact opposite thing two minutes ago. You said you wanted us to push everything to a central server and test it there.”
Milburn responded, “Oh, okay, Lawrence, I see. I am the bad guy, and you are the good guy. Everything I say is stupid, and everything you say is smart. I’m a complete bozo, and you are a genius. That’s why we are two months late, right?”
Dead silence. Nobody said anything. I thought about saying that we were not two months late, but I realized that anything I said right then would be interpreted as an effort on my part to make excuses for the project. Milburn was expecting me to apologize. He waited a long while. I believed he wanted me to back down. I refused to do it. So I remained silent.
Hinton hated conflict. He had a tendency to end any awkward silence, because it made him uncomfortable. So at that moment he piped up and suggested that we should all try to do more testing. And of course, that is a generic statement, like saying parents should love their children, so who is going to argue? Testing is good. The only disagreement was over what kind of testing.
Gregory suggested it might be more productive if we all got to work, and Milburn agreed, but he insisted that we work while logged into a video chat with him. So we went to our desks and we started working, and all of us (except Hinton) were logged into video chat with Milburn. And Milburn just sort of stared at us through the screen. He wanted to overhear us, and he wanted to watch us as we worked. His attitude was like that of a foreman who was overseeing a crew that had to dig a ditch. It was as if he feared that we would only work while he was looking at us, and the moment he looked away we would goof off.
Gregory had already offered to team up with me to investigate the most important bug we were facing, which was somewhere inside the nlp-wrapper app, and possibly inside of Pranab’s code (which was embedded inside of nlp-wrapper). To be clear, I thought Gregory was a good guy, very smart and hard working, and very friendly. In many ways he was a better Clojure programmer than me. I was frustrated that Hinton would only offer Gregory a part-time contract.
Normally I enjoyed all of my interactions with Gregory, but what followed was very strange, because Milburn was listening.
I had recently given Gregory full responsibility for the nlp-wrapper app, but in situations like this, I would still work on it, since I still knew it better than Gregory.
Gregory said, “On line 239 I don’t think we have the user_id set yet.”
I said, “It is definitely in the hashmap.”
Milburn jumped in. “What is this? Hashmaps? Shouldn’t you be sending JSON documents?”
He had no idea what he was talking about.
I replied, “Milburn, JSON is the serialization format we use when our apps send messages to each other, but now we are inside of an app, and we use hashmaps.”
Milburn went quiet for a moment, but he was still watching.
Then Gregory said, “Hey, I don’t see where we initialize our Natural Language Processing engine. Are you sure you set this up so it is initialized?”
Milburn said, “Gregory, are you saying Lawrence forgot to turn the software on? That’s incredible.”
Gregory tried to correct him. “No, no, I’m just asking where is this initialized …?”
I said, “Gregory, look in core.clj and you’ll see the start function.”
Gregory looked and recognized a pattern of code that was first developed by a well known Clojure programmer named Stuart Sierra.
Gregory asked, “Oh, I see, is this Stuart Sierra’s stuff?”
I said, “Right, it’s a little verbose, but I used it in all the apps.”
Milburn was suspicious because he did not recognize the name we were using. “Who is Stuart Sierra?”
I said, “He is a programmer who came up with a pattern for starting apps, and he wrote some blog posts about it.”
Milburn was still in love with the idea that I had made a serious mistake, so he tried to get Gregory to pursue it further: “But do you see where Lawrence initialized the Natural Language Processing engine? Is it on?”
Gregory said, “No, I don’t see that.”
Milburn was delighted. “So Lawrence forgot to set up the code correctly?”
I said, “Gregory, you have to look in the start.clj file.”
Gregory looked, but he still asked, “Are you sure this is being called?”
Yes, I was sure, but I had never faced a situation like this. I had never had my credibility attacked the way Milburn was attacking mine, so I figured I should document everything I did. I said, “I can check on the server.”
And Milburn, instead of waiting till I had checked, said, “I can’t believe this. I can’t believe this.”
So I logged into the staging server and a ran a search on the logs, looking for the special startup message that I had coded. I saw that it appeared six times that day, which made sense because I had made six changes to the app and I’d restarted it six times.
I said, “Sure, if I run grep on the logs I see the startup message six times.”
That should have killed that line of conversation. But Milburn was still in love with the idea that I had made some terrible mistake, and he was hoping that Gregory would find it, so he kept encouraging, “But, Gregory, do you actually see the line of code that initiates the Natural Language Processing engine?”
Gregory found the line and then Milburn asked him to pursue it further — was it possible that Lawrence had screwed up something inside of the initiation process? Those two went off on a tangent that lasted over an hour. It was a good experience for Gregory, I think, because it forced him to walk through all of my code and really learn it, and since he was taking over this app, it was good that he should know it in detail. But in terms of fixing the bug we were supposed to be fixing, it was an incredible waste of time.
And in fact, as we learned many hours later, there was no one particular bug that was stopping the system. There were dozens of small bugs, all over the place, and the only way to fix them was by patiently stepping through the code and finding them and fixing them one at a time. There were bugs in the code that Gregory wrote, there were bugs in the code that Pranab wrote, and there were bugs in the code that I wrote. And all of that is to be expected, given the phase of development we were at.
After about two more hours of this, Milburn began to rant about how we had taken a very simple problem and turned it into a big complicated thing. I did not challenge him this time, but I was fascinated that Milburn and Hinton had both been unwilling to recognize how ambitious this project was. Even Apple, with all of its money and engineers, has never attempted anything as ambitious as what we were now trying to do. The closest that Apple has come has been Siri, but Siri is fairly simple. If you ask Siri a question, it gives an answer, or if you tell it do something, it does it. These are all one-to-one interactions. If you ask, “Siri, what is the temperature?” then Siri says something like, “It is 78 degrees outside.” If you say, “Siri, wake me up at 6 AM,” then Siri says, “I have scheduled an alarm for 6 AM.”
This was a point that was made by the consultant who was sent to us by the Board, so I would have thought that by this time, the Board would have been made aware of the consultant’s point of view. But both Hinton and Milburn seemed to still believe that this project was fundamentally simple. It’s possible that Milburn knew the project was complicated and was only pretending to believe that it was simple. He was guilty of convincing the Board that the Big Pivot would not cost Celolot any extra development time, and of course, he had been wrong.
Siri is simple. With Celolot, a salesperson would be engaging in a conversation which would have an unlimited number of interactions and which might last hours, and the result needed to be cumulative over time.
A salesperson might say: “Create a new record of sale: I just sold $1 million of cleaning supplies to Hilton Hotel.”
And then we say: “Please confirm, the client is Hilton Hotels, the amount is $1,000,000 and the product is cleaning supplies?”
And then the salesperson might say: “That is confirmed.”
And then we say: “What is the start date for this contract?”
And then the salesperson might say: “I don’t know that yet.”
Then we check to see if we can create this record of sale, and we have to deal with what circumstances come up — for instance, we might find that we can not create the record of sale, because the salesperson works for a company that insists that the start_date is mandatory.
So then we say: “Your company has decided that the start_date is mandatory, so we can not create this record of sale at this time.”
And the salesperson says: “Okay, just keep this in memory and I’ll get back to you with the start date.”
And then the next day the salesperson calls Hilton Hotels and they work out the start date for this contract, and the salesperson says to us: “For Hilton Hotels, the start date is November 1st.”
And then we find the conversation from yesterday, and we give it the start date, and then we can create the record of sale in SAP.
That is a lot more complicated than Siri. We track the whole accumulated meaning of a conversation over the course of days.
Eventually, Milburn stopped lecturing us about how simple the project was, and eventually he got bored of watching us. Unless you are a computer programmer, it is not exciting to watch a computer programmer work, and even if you are a computer programmer, watching a computer programmer fix bugs, one line at a time, is rarely exciting.
But Milburn did one more thing to try and trick us. He turned off his video, but he left his computer logged into the chat room. Now we could not see if he was there or not. Maybe he had left, but maybe he was still there, listening to every word we were saying.
Some hours later I found a bug that I thought would be interesting to the group and I asked if Milburn was there. “Milburn? Milburn, Are you there? Milburn?”
No answer. So at some point he had snuck away. But he wanted us to think that he was still there, watching us.
Typically, I enjoy pair programming. I enjoy talking through problems with other programmers. But writing code while Milburn listened was like pair programming with Genghis Khan.
As much as I wanted to see Celolot succeed, it occurred to me that this was becoming a hostile environment that would keep me from doing my best work.
November 2nd, 2015
Given the surreal nature of my work day on Friday, the 30th, over the weekend I sent two emails to the entire team — Hinton, Milburn, Pranab, Gregory, and Shinzo. In the first email, I reminded everyone of the importance of documenting (in the wiki on Github) any changes they made to the data structure that their app expected to receive, and any change to the data structure that their app sent to the other apps. In the second email I copied and pasted portions of my two earlier emails, from August 31st and September 3rd, in which I had offered a realistic estimate suggesting that the initial system would be stable in early November. Now it was early November and we were almost done, so that estimate was on track to come true. I also offered an estimate of when the app would be feature complete: roughly six more months of work to implement all the features on our wish list, so we would be done in the Spring of 2016.
Monday morning I woke up and got ready for work. Still at my apartment, I checked my work email. I saw that Milburn had sent me a short email that simply said, “Why did you send these emails over the weekend? Can you please call me as soon as you get to the office?”
I was surprised. Was he actually going to provoke a showdown over those emails?
In an attempt to give him one last chance to think about what he was doing, I replied, “I send email all the time. Do we now have a policy that says I can not communicate with my co-workers? That is unusual. Do I understand that you want to talk to me about this?”
But I underestimated the extremism with which he was willing to pursue this issue, and at that moment, I was also too innocent in my view of his motivations.
I went to the office. Just when I got there, Shinzo showed up. I was expecting this. He was scheduled to visit from Washington D.C. He and I started to talk about what we should get done while he was in New York.
Then Hinton came over. He was on the phone with Milburn. I heard Hinton say, “Yes, he is here. I’ll tell him to call you.”
I found a private corner of the incubator and I gave Milburn a call.
Me: Good morning, Milburn. What can I do for you?
Milburn: I asked you to call me. Why didn’t you call me?
He sounded sad.
Me: I just got to work and Shinzo got here.
Milburn: I asked you to call me. It’s a simple request. Just a phone call. And yet you didn’t call me. That is not nice. It’s rude, it’s disrespectful, and I’m hurt. As a human being, as someone with feelings, I am hurt, and I would like an apology.
He almost sounded like he was going to cry. This note of self-pity was surprising to me.
My friends and I have sometimes discussed the right-wing television personality Glenn Beck and his tendency to cry on television. Is Beck truly overwhelmed with emotion that often, or is it all just an act? The best explanation I ever heard, from a friend of mine who is herself a professional actress, was that a great actor truly experiences the emotions they were portraying, and so it was possible that Beck was playing a character in some sense, yet still sincerely feeling the frequent raptures that he performed. And I think something similar must be true of Milburn. On the one hand, it seems naive to think that he really felt such strong emotions over my failure to call him, but on the other hand, his emoting seemed sincere.
Milburn had had a career as a great salesman, which meant he was a master of manipulating other people’s emotions. He knew all the tricks: praise, shame, laughter, anger, promises, guilt. Whether his use of these tools was conscious or unconscious is, of course, unknowable. But it doesn’t matter much. A lifetime as a sales professional left him with an arsenal of psychological tricks that had become second nature to him. He knew that once a person apologizes, the apology sets the pattern for the conversation, and the person who apologizes tends to continue to apologize. For this very reason, I avoided apologizing.
Me: I received an email from you stating that you would like to talk, but we have a meeting scheduled at 1 PM and…
Milburn: I told you to call me!
Me: …and I knew we were going to talk.
Milburn: I told you to call me! Don’t send a bullshit email! Pick up the phone, if I tell you to pick up the phone!
Me: I was confused by the email that you sent. It sounded like you wanted to talk about the fact that I sent emails to my…
Milburn: You are wasting the time of your co-workers, when they are trying to stay focused on getting the next release out. Does that interest you at all? Do you want us to get the next release out?
Me: I have been working very long hours to try to get the next release out.
Milburn: The time you spent writing those emails is time you could have spent debugging the software. But I guess that doesn’t interest you, does it?
Effectively, he was saying that I was no longer allowed to communicate with my co-workers regarding any issue except for a small set of issues that he felt free to arbitrarily define. It was clear that, from this point on, I would get in trouble for writing any of the emails that I usually wrote, especially regarding changes I wanted to make to the software over the next two months — a subject I thought about all the time.
I don’t know why I often feel such intense loyalty to the project that I am working on, and I don’t know why I so often work to build software in the exact way that I think will be both powerful and elegant. On some level, I am driven by devotion to the craft of software. Milburn was now trying to demonstrate that all of my previous contributions could be ignored, if he felt like ignoring them. A line such as, “But I guess that doesn’t interest you, does it?” is never meant in any literal sense; it is always thrown out there to show that the person speaking has the power to throw it out there. The previous Tuesday he had praised me for working long hours, and shamed Shinzo for not working as late as me, and yet now he wanted to suggest that I was lazy and didn’t want to work.
Milburn: Who am I to you, right now?
Me: You are Milburn Vrock, a member of the Board Of Directors of Celolot.
Milburn: Yes, that’s right, but who else am I?
For the life of me, I could not imagine what he wanted me to say. Did he want to hear something stupid like “We are teammates!” or “You are my friend!”? At a stretch, I could imagine he wanted to hear something like “You are an investor in Celolot,” but I did not actually know if he was an investor or just a Board member, so I couldn’t say that.
Me: Who else are you?
Milburn: Yes, who am I to you?
Me: Uh, I am not sure what you are looking for.
Milburn: I AM THE LEADER OF THE TECH TEAM!
Me (unable to hide my surprise): Oh?
Milburn: And do you know why I am the leader of the tech team?
I said nothing.
Milburn: Do you know why I am the leader of the tech team?
I said nothing.
Milburn: BECAUSE YOU FAILED!
Me: This project is on time.
Milburn: You could have done something great. You could have come in here and been a real leader. You could have shown the world what you were made of. But you decided to do nothing. You decided you’d rather sit around and complain. You didn’t lead this team. You don’t know how to lead. Admit it. I want to hear you say it. Admit that you failed.
Me: We have been working very hard and we have built…
Milburn: ARE YOU MAN ENOUGH TO ADMIT YOU FAILED?
Me: …some impressive technology. This is a service that has to deal…
Milburn: ARE YOU MAN ENOUGH TO ADMIT YOU FAILED?
Me: …with massively concurrent real-world communications going between…
Milburn: ARE YOU MAN ENOUGH TO ADMIT YOU FAILED?
Me: …multiple points, from the Android to our servers, though our Natural Language Processing…
Milburn: ARE YOU MAN ENOUGH TO ADMIT YOU FAILED?
Me: …engine, sometimes back to the Android and other times to…
Milburn: ARE YOU MAN ENOUGH TO ADMIT YOU FAILED?
Me: …SAP. And we have built a working demo in a remarkably short amount of time.
He was silent for a moment. I looked around the incubator and watched all the other people, at all the other startups, working hard on their projects. I wasn’t sure what Milburn was waiting for. I wasn’t sure what he expected me to say. I felt that if I said anything at this point it would sound like an apology, so I decided to remain silent and simply wait him out.
A very long moment passed in silence. He was waiting for me to speak and I was waiting for him to speak. Actually, I was waiting for him to hang up so I could go and get some actual work done.
Milburn: You can’t do it, can you?
I stayed silent.
Milburn: You can’t do it, can you?
I stayed silent.
Milburn: You can’t admit that you failed. Because that hurts, and you don’t like to feel hurt, is that it?
This was a guy who was almost crying a few minutes ago because I didn’t give him a call. Or at least, he was almost pretend crying. Or pretend almost crying. Either way, this was quite an accusation for him now to throw at me.
Another very long silence followed. He was hoping that I would talk into the silence. That’s the kind of mistake that Hinton always made. I also made that mistake when I was younger; I suppose we all do it when we are young. It’s an easy trick whereby those who are good at verbal combat can get their opponent to sabotage themselves: create an awkward silence and then see if the other person feels compelled to say something in that awkward silence. My best option was silence. If Milburn and I were peers then I would also have the option of going on the offensive, but since he was on the Board and I was only an employee, I figured silence was my best choice.
He let out a long sigh.
Milburn: So where are we right now? Where is the software? What more needs to happen?
Me: We are stuck at the point where we call the Natural Language Processing library that Pranab has built, so I assume there is some problem in Pranab’s code.
Milburn: There you go again. You keep doing that!
I had no idea what he was talking about.
Milburn: You can’t give a straight answer to save your life, can you?
I stayed silent, but I certainly felt it was a straight answer. Those were the facts as I knew them.
Milburn: Why do you have to use words like “library”? There are no libraries! Why do you always try to obfuscate every conversation? Model, View, Controller! That is how software is built! Model, View, Controller! It’s not a library! It’s a model!
This was unbelievable. When Milburn was doing VisualBasic programming 15 years ago, the Model, View, Controller architecture was gaining in popularity. That was when Struts was the best framework that the tech industry had. The Model, View, Controller architecture remains popular today in monolithic frameworks such as Ruby On Rails and Symfony. However, from the start I had been building the architecture at Celolot following a microservices design. If Milburn wanted to learn about our software, I was happy to teach him, but he would need to learn about our actual software, and not try to make it fit a paradigm we were not using.
More importantly, every computer programmer I know would understand what I meant if I used the word “library.” Milburn himself did programming on the Microsoft stack, so presumably he knew what a DLL was, and the last “L” in DLL stands for “Library.” He should have known that.
All the same, I am flexible, so I adjusted my speech.
Me: We are stuck at the point where we call the Natural Language Processing “model” that Pranab has built, so I assume there is some problem in Pranab’s code.
A long silence passed.
Milburn: You like to blame others, don’t you? Does that make you feel good, when you blame other people? I’ve heard you blame Pranab, I’ve heard you blame Shinzo, I’ve heard you blame Gregory, but you know who you never blame? You never blame yourself. I’ve never heard you say one bad thing about yourself. And yet every single time you blame Pranab or Shinzo, in the end, when we find out the real problem, it always turns out to be you. All the problems go back to you, but you never take responsibility for what you’ve done.
Several things occurred to me at once:
1.) I could repeat these words, verbatim, about Milburn himself, and the statement would be true. Certainly, if the Board felt we were running late, the root problem was Milburn’s decision to proceed with the Big Pivot in August.
2.) It would be a mistake to treat any of what he said as rational.
3.) It would be a mistake to respond as if we were having a good faith conversation, eagerly trying to discover the real facts of the situation.
4.) If we were interested in facts, then of course, he was wrong. I’ve written two dozen commit notes in Github that contain the words “I am an idiot.” I always call myself out when I make a mistake, at least in part because I think it sets a good example for all of the other programmers. By calling out my own mistakes, I encourage them to call out their mistakes, and when we all call out our mistakes, we can fix them faster and move forward faster.
5.) I have learned a great deal over the last five months, and if we were having a good faith conversation, it would be fun to talk about what we could do differently. For instance, we currently have small bits of routing logic scattered among the server apps, and I’ve thought about writing a central routing app, and moving all the routing logic to that. Or, perhaps we should look at using a company like LSQ.io, which has built some great Service Discovery technology to automate microservices projects. That would be a fantastic conversation for us to have, and an important one. But this current conversation was becoming a pure power struggle, and so there was no place to talk about any of the interesting things that could make Celolot better.
Me: We have added debugging statements to every function in the system, and the code runs until we call Pranab’s model. That strongly indicates that there is a problem in that model.
Milburn: Why didn’t you foresee this problem and put in some guards against it?
Me: We have made huge progress making this code more and more stable. We are on track to meet our deadline this week.
Milburn: Can you guarantee that the project will be complete on Friday? Every bug is fixed? We can put this in the hands of a customer on Friday, and you guarantee it?
Me: I don’t want to speak to…
Milburn: IT’S A YES OR NO QUESTION!
Me: …how much Shinzo or Pranab…
Milburn: IT’S A YES OR NO QUESTION!
Me: …still need to do or…
Milburn: IT’S A YES OR NO QUESTION!
Me: …how many hours Gregory feels…
Milburn: IT’S A YES OR NO QUESTION!
Me: …he can work this week.
Milburn: IT’S A YES OR NO QUESTION!
Me: It is not a yes or no question!
Milburn: IT’S A YES OR NO QUESTION!
Me: It is not a yes or no question!
Milburn: IT’S A YES OR NO QUESTION!
Me: It is not a yes or no question!
Milburn: WILL YOU MAN UP AND GIVE ME A YES OR NO ANSWER FOR ONCE!
Me: It is not a yes or no question! I can not take full responsibility for Shinzo or Pranab or Gregory!
Milburn: THAT’S RIGHT! YOU CAN’T TAKE RESPONSIBILITY FOR ANYTHING!
Me: Why have more than one programmer if I can write all the code by myself? Why did you even hire Shinzo or Gregory or Pranab if you think I can get this project done by myself?
Milburn: IF YOU ARE LEAD OF THE TECH TEAM THEN YOU TAKE RESPONSIBILITY FOR THE TECH TEAM!
Me: If I am the lead developer at Celolot, then why are we ignoring the estimate I gave in August?
Milburn: Oh, I see. I get it. You don’t want to be lead developer any more, is that it? Too much responsibility? Is that it? When the going gets tough, Lawrence goes home. Is that it? Well, I just looked at your LinkedIn profile. Do you know what it says there? IT SAYS YOU ARE LEAD DEVELOPER AT CELOLOT!
Me: If I am the lead developer, then…
Milburn: IT SAYS YOU ARE LEAD DEVELOPER AT CELOLOT!
Me: …why can’t I get rid of Pranab and why can’t…
Milburn: IT SAYS YOU ARE LEAD DEVELOPER AT CELOLOT!
Me: …I get someone better as a replacement? And why…
Milburn: IT SAYS YOU ARE LEAD DEVELOPER AT CELOLOT!
Me: …can’t I get Gregory hired full-time?
Milburn: ONCE YOU RING THAT BELL YOU CAN’T UNRING IT! IT SAYS YOU ARE LEAD DEVELOPER AT CELOLOT!
I wasn’t even sure what that meant, and it’s possible that Milburn didn’t know what he meant either. Milburn was very, very good at this kind of verbal combat, and he clearly learned long ago that he could win a fight like this by getting the advantage and keeping it. And a person doesn’t need to make sense to keep the advantage in this kind of fight, sometimes it’s enough to simply shout and express anger till the other person backs down.
I won’t even comment on his gendered language, which made it sound like he had been watching too many episodes of Mad Men.
He was trying to put me in a position where I had to accept all the responsibilities of being a tech lead, even though I had none of the powers. I could not hire, I could not fire, I could not set schedules or even offer estimates, I was not consulted on any of the important pivots, I almost had Twilio forced on me, I was given the task of adjusting my code to cushion the faults of the code written by our weakest programmer, and until six days ago, I had never had a chance to talk to any of the people who actually made all the big decisions about the direction our technology should take. Rather, those decisions were made by the Board, who then told Hinton, who then would tell me. I was treated as an independent contractor, someone with little relationship to the company. But I was now supposed to take responsibility for the team. I suspect that Milburn knew how irrational this was, and he was simply testing me to see if I would back down.
And of course, we never talked about the idea that the CEO should take responsibility for anything. There was an unspoken awareness that Milburn was the real CEO, and Hinton was Milburn’s assistant, and Hinton had been given the title of CEO just for fun, because Milburn did not need another credential on his resume. But in a startup with just three programmers and one CEO, four people in total, I would normally assume that the CEO can take some responsibility for the progress of the tech team. After all, Hinton hired all of us. In fact, in most startups that I’ve worked at, the CEO would take responsibility for protecting the tech team from outside pressures, such as meddling from the Board. The idea that software development estimates should come from the Board is very unusual.
If I was the type of person who screamed at other people during business meetings, I could have taken his tactics and turned them around on him: Are you man enough to take responsibility for the Big Pivot? Because that is the big question that haunts this conversation, isn’t it? Milburn had put his reputation on the line, with the other Board members, when he suggested to them that the Big Pivot would not take much time. Milburn needed to find someone to take the fall, or he would end up taking the fall himself.
There were moments in this conversation when he sounded like he wanted to fire me, but I don’t think that was ever his intention. Rather, from his point of view, the purpose of this conversation was to silence a critic. He was worried about those two emails that I had sent over the weekend, and he wanted to rattle me enough that I would never again think about sending any such emails. The reason he felt no need to go after Pranab was because Pranab was not the type of person who would write any such emails.
Milburn: No one ever told you September.
Milburn: No one ever told you September.
For the life of me, I could not imagine what he meant.
Me: I am not sure I know what you mean.
Milburn: In your bullshit email. Stable and feature complete. No one ever told you September. No one ever said that to you.
Milburn: Don’t you parse my words! Don’t you dare do that! Don’t try to derail this conversation again!
To his credit, Milburn had a genius for the strategic use of anger. If he sensed the risk of losing control of the conversation, he would indulge in another angry outburst, and thus get the momentum back on his side. If I were ever to switch over to the Dark Side, I would want to study with him. But his tactics are fundamentally dishonest and manipulative. Arguably, this is what made him so good at sales. And I might be willing to believe that this was an effective way to drive a sales team. But I sincerely believe that it is the wrong way to run a software development team. Especially when doing something cutting-edge original, like we were doing, I think open and honest communications are extremely important.
And my question was a valid one. He might have meant the previous September. Was he now saying that no one expected the team to be done this last September? Was he suddenly agreeing with me? Or did he mean to say “Spring” and he accidentally said “September”? Both words start with “S” and I could imagine him mixing them up because he was angry. In my email I had said “Spring.” This seemed like an important point to be clear on. If he was saying that he had never pressured us to be done during September, and I had imagined the pressure, then that would be a revelation. But I let the whole subject go because he seemed very angry.
Milburn: No one ever said that to you, whatever the month you said, no one ever said that to you!
If he meant “Spring,” then that was certainly true, but that is why I spoke up. Shouldn’t estimates come from the tech team? In what rational development process does the Board Of Directors generate the software development estimates? Or, one could argue that Milburn was the real CEO, and since he had some experience programming, it was reasonable for him to create development estimates, but then the question would become, in what startup of five people does the tech team work for five months without ever talking to the CEO? No matter how one looked at the situation, there was something fundamentally irrational happening.
I could see why Milburn was in trouble with the other Board members. Did he really think that because he wrote some Visual Basic code 15 years earlier he was competent to estimate a cutting-edge Natural Language Processing project in 2015? If so, this was perhaps an excellent example of the “Dunning/Kruger Effect,” where someone with little knowledge of a subject doesn’t realize how much they don’t know, and therefore they assume they are highly competent regarding a subject about which, in fact, they know almost nothing.
Me: I think the Spring is a reasonable estimate for being feature complete and reliable.
Milburn: You will never say that again. Do you hear me? You will never say that again. You have done everything in your power to demoralize this team. You have done everything in your power to distract them from the mission. You have done everything in your power to sabotage this project. I’m sick of it. I am sick of your bullshit. I am sick of your sabotage. You will never say that again, do you understand?
I might have said that his unrealistic deadlines were demoralizing the team. Everyone on the team was running scared. Everyone felt panic. The Board was in a panic, and that was being communicated to the rest of us. It is not comfortable to work at a company when the Board Of Directors is in a panic. And it seemed unnecessary, given that we were on schedule with the estimate that I had given on August 31st.
By this point we had been talking for so long that it was time for the meeting with the entire team. So we had to end the call and go into the full team meeting.
And that team meeting was completely insane, in its own way.
At the end of the day, I reached out to Mera, the woman at the talent agency that had first connected me to Celolot. I let her know that things were going badly, and that I would need to find another job, and I asked her to talk to Hinton.
November 9, 2015
Over the next few days, we pushed through the final bugs. Then we were able to send a message from the Android through the Natural Language Processing model, back to the Android for confirmation, then to the server again, and then to SAP. This was similar to the demo we had on September 18th, but now we had much more error protection, and the system was stable for a much wider set of possibilities. This was something we could actually put in a customer’s hands. It was an exciting moment.
Despite all the obstacles, the tech team had moved fast. We had a working demo just 3 months after the Big Pivot. This is a success story, of which I am proud.
So this was a good moment for me to quit. I wrote up documentation regarding the devops stuff I had been doing (Jenkins, build scripts, kill scripts, start scripts) and how my Clojure apps worked, and then I decided it was time to leave.
I would like to emphasize how strongly I believe in this business model. At some point a startup like Celolot is going to take over the CRM industry, and as it becomes the default interface for CRMs, it will be able to tax most of the value in the ecosystem. Therefore, some startup is going to become a multi-billion dollar company, building software like what Celolot has been building.
Celolot currently has bad leadership, but with the right leadership, I believe it could eventually take over the CRM industry.
lawrence at krubner dot com
There were several good discussions that arose in response to this article. You can read them here:Source