Random Thought

The utility of language is inexorably linked to a time and place.


The Definition of Done (An Outline)

This post is just a brain-dump of an idea for an outline or framework for creating a Definition of Done.  Many will recognize the term Definition of Done from the Scrum process, which we use in my work.  However, this idea actually stems from my home life, where things just aren’t getting done!  As an example, when we ask for the dishes to be washed — that is exactly what happens, and nothing more.  But “doing the dishes” can include so much more:

  • Move dirty dishes out of the sink
  • Clean out the sink
  • Move things out of the drying area
  • Put down a towel for drying
  • Get a clean rag
  • Fill the sink, add dish soap
  • Soak dishes as necessary
  • Wash
  • Rinse
  • Dry
  • Put away
  • Wipe counters
  • Clean out the sink
  • Take dirty rag/towel to the laundry

The Outline:

  1. Preparation Tasks
  2. The Primary Task
    1. Subtasks
  3. Mini-tasks and follow-up tasks
  4. Maintenance Tasks


Preparation Tasks (and Rabbit Trails):

Preparation Tasks are things that have to happen before you can even think about completing the primary task.  As an example, the other day my wife asked me to wash the laundry.  Two important pieces of background information:

  • We had major pipe bursts over this winter and I am nearing the end of a project to completely re-plumb my house with PEX.
  • I got a new compound miter saw for Christmas which had yet to be properly setup.

I had purchased a new washer hookup box and wanted to get it installed before I ran the washer again, since I had reused the old crusty valves and push connectors — not a long-term solution.  So considering my constraints, the day went like this:

  • In order to do the laundry, I have to install the new washer hookup box.
  • In order to install the box, I need to cut a 2×4.
  • In order to cut the 2×4, I need to adjust my new saw.
  • In order to adjust the saw, I had to read the manual.

So i grabbed the manual, sat down in my chair and started reading — and promptly forgot why I had even started this whole rabbit trail.

The point is this:  when estimating a project, don’t forget all things that have to be done before the thing can be done.  A few examples in software include:

  • Installing/upgrading your IDE, Frameworks, Server software, Testing infrastructure, etc…
  • Learning a new API or library.
  • Connecting to the source control repository and downloading code.
  • For legacy project maintenance, fixing (or creating) builds that haven’t run for several coons’ age.

The Primary Tasks and Subtasks

I’m not going to spend much time here — this is the bit that we naturally focus on so volumes have been written.  Exactly how you break-down what is a primary task and its subtasks will be very subjective and it is not my intention to opine here.  Suffice it to say the Primary Task is the thing the user (or your wife) asked you to do.

Mini-tasks and Follow-up Tasks

When I say mini-tasks I’m thinking of all the side things that just need to be done to get to “fit and finish”.  The example in the case of dishes is cleaning the counters.  It’s not technically “washing dishes”, but the job just wouldn’t be done without it — this is the bit my kids like to skip (or argue with lawyerly vigor was not a part of the contractual negotiations that apparently happened while I was sleeping).

Follow-up tasks might include putting away tools, cleaning up the workspace.

Maintenance Tasks

Maintenance tasks (as contrasted with Follow-up Tasks) make me think of things like sharpening the chain on the chain saw so that it’s ready for the next time it’s used.  A few other examples I can think of:

  • Start the clothes washer after gathering the dirty rags and dish towels.
  • Refilling the jet-dry dispenser
  • Organizing tools

For the case of software development, I’ll state 2 major counter-examples that I DO NOT consider “Maintenance Tasks” or Follow-up Tasks:

  1. Unit Testing
  2. Refactoring

To me these are an integral part of the Primary Task (or at worst Subtasks).

Series: You’re doing it wrong! (YDIW) – PILOT

For those who are familiar with Jeff Foxworthy, you’ll know his signature joke format:  If you <insert stupidity here>, you might be a redneck!  In that vein, I am starting a series of posts in the format:  If you <insert anti-pattern here>, you’re <emphasis statement> doing it wrong!  The emphasis statement may be emphatic (“You’re doing it wrong!”) or something like “You’re probably doing it wrong!” or “There’s a high probability that you’re doing it wrong!”  When it’s not ridiculously obvious, I’ll try to follow each with suggestions on how to do it right — or at least how to suck less.

So for my first entry:

YDIW#1:  “If you’re actively coding and haven’t checked-in in the last 24 hours, you’re doing it wrong.”

There’s a couple foundational corollaries behind this one:

YDIW#2:  “If you’re not using source control, you’re doing it wrong!”

Use source control — for EVERYTHING.  JUST DO IT!  Check-ins should be task based and contain explanatory information like comments and work item links.  These linked artifacts provide real value — code is only half the picture.  Treat changeset/commit comments and work items as deliverables.  If your system supports rules requiring comments and work item links, turn them on now.

YDIW#3:  “If your task takes more than a business day, you’re probably doing it wrong.”

To be predictable in software development, you must estimate small tasks.  I’m terrible at estimation — ALL software developers are terrible at estimation, because we are generally idealists.  If you’re a Product Owner or Scrum Master and your dev tells you it will take 3 days (or anything greater than 1 day) make them break it down further.

“Aim small, miss small.”  – The Patriot

That is to say, if you aim at a small detail of your target, you might miss that detail, but you’ll still hit your target.

As you can probably tell, this series is going to opinionated.  Deal with it.  😉

regenerating a TFS server’s guid

in order to clone TFS server and still be able to connect to both the existing and cloned server afterwards from the same client, you must regenerate the Project Collection’s identity guid.  This can be done with TFSConfig ChangeServerID.  after this you must update the guid on the AT’s web.config.

if you have already connected to the cloned server before regenerating the guid and wish to switch back to the original server, you must delete the client cache or you will receive a HTTP 404 error.

In a VSPackage, getting services on startup

a few years back, I wrote a VSPackage that needs to get a reference to TFS VersionControlServer on startup.  However, this was problematic as Package.Initalize happens while the IDE is still in “Zombie” state.  To know when Zombie state is done, you hook OnShellPropertyChanged and listen for propid = __VSSPROPID_Zombie, val = False.  This worked fine in previous version of VS, but not VS2012, as it appeard TFS initializes later in the process.  To Solve this, I am now listening for propid = __VSSPROPID_ShellInitialized.

Private _shellPropertyChangeCookie As UInteger
Public Function OnShellPropertyChange(ByVal propid As Integer, ByVal var As Object) As Integer Implements IVsShellPropertyEvents.OnShellPropertyChange
    ' if the zombie state changes from true to false we can go ahead and
    ' ask for the DTE service and then stop listening for property change
    If propid = CInt(__VSSPROPID4.VSSPROPID_ShellInitialized) Then ' AndAlso CBool(var) = False Then
        Dim shellService As IVsShell = GetService(Of SVsShell, IVsShell)()
        If shellService IsNot Nothing Then
            _shellPropertyChangeCookie = 0
        End If


    End If

    Return Microsoft.VisualStudio.VSConstants.S_OK

End Function

Saving pages with Readability and InstaPaper from IE on your Windows Phone

After much searching I have found a way to save pages to services like Readability and InstaPaper from my Windows Phone.  On desktop browsers, a bookmarklet that contains a bit of javascript code (instead of a standard URL) is used to post the page to your account.  Although not advertised, this works just as well in the phone’s browser.  To create the bookmarklet:

  1. browse to the service’s bookmarklet instruction page (you may have to log-in).
  2. tap and hold the “Read Later” button and choose “copy link”.
  3. tap the ellipsis on the address bar and choose “add to favorites”.
  4. tap the “Web address” field and paste the copied link.
  5. if desired change the Name of the new favorite
  6. tap the check mark to save the new favorite

Now to save a page for later, simply go to favorites and choose the favorite.

For Readability the bookmarklet instruction page can be found here:  http://www.readability.com/bookmarklets

InstaPaper has a copy of the Read Later button on all of their pages:  http://instapaper.com


This works on both Windows Phone 7.5 (Mango/Tango) and Windows Phone 8 (Apollo) phones.  I suspect that this method might work just as well on Android and iOS devices, but have not tested it.

Validating the MD5 hash from an Authorize.net relay response.

so i’m working on implementing credit card processing with Authorize.net in a website project.  when it comes to authenticating the relay response you need to validate the hash generated by Authorize.net.  The docs are quite forth-coming on how to generate the transaction fingerprint with the HMAC_MD5 algorithm for the request, but very few details given on how the validate the response.  Here is the function necessary to generate the appropriate hash value that can be compared with the value provided in the response:

        using System.Security.Cryptography;

        public static string MD5(string value)
            byte[] data = (new System.Text.ASCIIEncoding()).GetBytes(value);
            using (var md5 = new MD5CryptoServiceProvider())
                byte[] result = md5.ComputeHash(data);

                string hash = "";
                for (int i = 0; i < result.Length; i++)
                    hash += result[i].ToString("x").PadLeft(2, '0');

                return hash.ToUpper();