Sunday, February 24, 2008

The problem with contractors

Like most technology managers, I often need the services of outside parties to back fill for
people on leave, provide overflow support on projects, or to provide short-term expertise in
areas my team has none. Contractors, which I differentiate from consultants, have played
integral roles in a number of key projects for me over the years. Typically, they are
bright, motivated, and professional, knowing that without a permanent gig, their reputation
determines if they get a next job.

Recently, I had the worst experience I've ever had with a contractor. So bad, in fact, I
alerted every agency I've worked with that sending this individual out as a representative
of their organization would only diminish their reputation. I've never felt compelled to do
that in any prior experience - even with people I've fired for non-performance.

For those interested in the full story, read the details below. The short story is the
contractor was in over his head from the beginning and didn't recognize it. I checked in
every day - and even asked to see the work - to see how it was progressing and always left
assured that everything was on track. When he delivered it to me for testing, it was an
embarrassment. We finally got the system working at 1:30 AM, two days before the delivery
date, and delivered it for testing. The system went live on time, and functioned as
required, so the business users never felt the impact - though my team certainly did.
Then it got worse.

After letting the contractor go, and informing the agency of the challenges, he started
spamming myself and my superiors with emails slandering the intelligence and professionalism
of me and my staff. He claimed the people who made his code actually function had sabotaged
his efforts. It got so bad his agency had to threaten him with legal and police action
before he would stop harassing me, my staff, and my management.
Suffice it to say, I hope he picks a new industry to work in and I pity an organization
unfortunate enough to hire him.

Lessons Learned:

1) Never push a high-profile, high-urgency project to a contractor. Bring them in to back
fill for the staff that will do the project.
2) Good partners can still provide bad service, and you need to be prepared for that.
3) Involving senior people at the beginning (which I did) is imperative if you need to call
on them to save you at the end. Their familiarity with the project will save valuable time.

THE FULL STORY:

The Background

One of our business units poorly planned the roll-out of a new process they needed
implemented by December 1st and contacted me on November 15th to request an automated
solution. I took their requirements, worked with my team to map out a solution, and provided
a realistic estimate and timeline - December 3rd for testing. They reiterated production
release by December 1, and threw the weight of our Chief Administrative Officer behind the
request, so we now had a new delivery date of November 26th to allow for testing.
I called a firm I have had repeated success (and continued success after this incident),
provided them the technical requirements, and asked them to have someone to me at the
contracted rate the next day for a quick phone screen and a start date two days later - the
Friday before Thanksgiving. In the phone screen, I explained the project, asked a few basic
questions regarding past projects, technical strengths, and dealing with pressure
situations, and agreed to hire him for the job.

Trouble Early

The day he began, I explained the project, went through the detailed design, introduced two
resources at his disposal for assistance and questions (one technical, one a PM), and then
left him to work. I had off site meetings the week of Thanksgiving so I was checking in by
phone at the end of each day. On Monday (day 2 of the project), my PM informed me that he
had to explain to the contractor how to work with data grids and, at one point, sat down and
wrote the initial code for him to get the grids working. I spoke with the contractor who
indicated he had initial issues, but thanks to the PM was now through them and was confident
in hitting the date. On Wednesday, before leaving for Thanksgiving, I checked in once again
and everything was "complete" except for one SQL routine for determining hierarchy. We
agreed I would get the code to test on Monday afternoon, when we returned from the holidays.
On Monday at noon, the SQL routine was not done. The contractor said it would be a few
hours. At the end of the day, I said he needed to stay until it was complete and that
another member of my staff would stay with him to assist. At 9 PM, I received a link to
begin testing.

The Test

Monday evening, I tested what he called "complete" and found an issue with the first user
account - I couldn't log in and received an ugly .NET error. I tried another user - same
issue. The third user finally could access the system, but there were more issues. In all, I
found 14 issues on a small project that had two screens - a login screen and a data entry
screen with nested data grids. Many issues were basic - password was clear text instead of
in asterisks, users couldn't log in, the footer was at the top of the screen instead of the
bottom.

With four days left and a non-functioning product, I asked to borrow an architect from
another team to help close out the project. I called a meeting with the architect, the
contractor, and a junior member on my staff who was doing production support and reviewed
the issues. We devised a plan to resolve them and they estimated a delivery of Tuesday
afternoon.

Situation Worsens

At 2PM, the architect informs me that the contractor seems clueless. He has named the two
data-grids DataGrid1 and DataGrid2 - with DataGrid2 as the primary grid, and DataGrid1 the
nested grid. He said he felt it would be mostly done by end of day with some minor fixes
early the next morning. On Wednesday, they tell me they are finishing the last issue and
I'll have code by noon. At noon, the architect informs me that testing is not going well.
After further investigation, we discover that the contractor used three different data types
(float, int, and text) to represent the same field. Half of the errors we were encountering
were a result of his code casting the data back and forth between the data types.
At 5PM, I told everyone to plan on a long night and asked them to pick what they wanted for
dinner. At 10 PM, I sent the contractor home. At 1AM, we finally finished and had an
incomplete product, but one we could hand over to the users for testing and finish the
following morning. Completing meant a trigger on one table to audit data changes, and a
report they wouldn't use for at least a week.

The Attack

The next morning, I informed the contractor that I could not trust him to work on the other
items I had originally hired him for. I told him that I felt he knew he needed help early
on, and didn't ask for it, and that's why I couldn't trust him. He said he disagreed but was
happy I was letting him go. I then informed his agency that he didn't cut it, and that I
felt it would be in their best interest to not sell him as a lead or put him on any solo C#
projects.

Shortly after that conversation, I received an email from the contractor extolling his own
virtues - even referring me to the strength of his resume - and explaining that the
architect and member of my staff that had saved the project were actually incompetent,
amateurs, and would only hurt my team in the long run. I thanked him for his input and
wished him luck.

He then responded that I had no concept of SDLC, project management, or of development best
practices. He followed that email with one to my boss's boss, explaining that my team was
incompetent, that I hired sycophants, and that he should subject us all to testing so he
could gain a true appreciation of our incompetence.

I, of course, forwarded each of his emails to the agency who had sent him. They were
apologetic, but never offered to refund his fee. They did eventually threaten him with a
lawsuit and a visit from the police, and that seemed to resolve the issue.

What would you have done differently?

No comments: