
Software Checklist - happyscrappy
http://www.solipsys.co.uk/new/SoftwareChecklist.html?ColinsBlog
======
matthewmacleod
What I object to here is the core principle that there's something to fix in
software development terms here.

There's not. We've got robust, reliable tools for creating nearly bug-free
software. We have the usual engineering principles; we have automated testing;
we have virtual machines and documented environments and specifications and
APIs and all the rest.

The problem is, there is a cost associated with preventing software bugs, and
it's a big one. There's a reason Facebook kept saying "move fast and break
things" \- their software was buggy as shit, but the cost of that was minimal;
in situations where bugs don't matter as much, _time invested in robust bug-
free software is an undesirable expense_.

In the Heartbleed case, this is reversed. There's a highly-sensitive, critical
bit of Internet infrastructure; there have been minimal resources invested
into it, but it is relied on by a lot of key systems.

So the problem is a "social" one, in a sense. OpenSSL as a project did not
invest enough in reducing the occurrence of bugs, and this resulted in the
vulnerability. It's not the maintainers' fault, really; it was irresponsible
for so many of us to rely on the software without considering it's quality.

I suspect we'll start seeing renewed focus on bits of important software like
OpenSSL, and greater attention to the engineering tradeoffs. So there's an
upside to the whole thing...

~~~
gcv
> We have the usual engineering principles

No. We don't. As Alan Kay said, programmers don't have a solid concept like an
arch to build on. In real engineering, when you build a bridge, a single rusty
rivet won't cause it to fall down. In software, a single pair of misplaced
braces give you critical "goto fail" bugs. (And don't fool yourself into
thinking that static analysis catches all these errors.)

It has become fashionable to say that automated tests somehow turn programming
into a rigorous discipline. This is bullshit. Tests are a decent band-aid
which kinda help sometimes if you spend half your programming time writing
them. And will still miss plenty of horrible bugs. In truth, programming
remains a poorly-understood endeavor. Checklists as auto-written automatic
tests might actually be a step in the right direction, especially if compilers
start to analyze the kinds of mistakes individual programmers tend to make.

~~~
matthewmacleod
_No. We don 't. As Alan Kay said, programmers don't have a solid concept like
an arch to build on. In real engineering, when you build a bridge, a single
rusty rivet won't cause it to fall down. In software, a single pair of
misplaced braces give you critical "goto fail" bugs. (And don't fool yourself
into thinking that static analysis catches all these errors.)_

Yes, we do. Misplaced braces can cause catastrophic failure, but that's
_precisely because engineering principles were not followed_ ; the system was
left with a critical vulnerability which meant that a typo could cause
catastrophic failure.

We can, however, build systems that don't suffer from these problems. Look at
the Shuttle, for instance; multiple redundant machines making the same
calculations, and additional machines running _totally independently
developed_ software. AFAIK the system has never failed.

So I dispute that there's a problem here in terms of our ability to develop
critical software with engineering-level quality. The problem is that software
in an order of magnitude more complex to reason about than e.g. a bridge, and
as a result developing software to the same level of quality would in most
cases be a waste of time.

~~~
gcv
> software [is] an order of magnitude more complex to reason about than e.g. a
> bridge

I think you're trying to flatter our profession. Software is not more complex;
it's just that we don't know what we're doing well enough to have useable,
reliable components. Like arches. Or even just rivets.

To stretch the bridge analogy further (probably almost to its breaking point),
it's as if I'm about to start work on the Hoover Dam Bridge, but I have to
start by getting some rivets. So I first go out and pick up some pieces of
iron ore, and start trying to figure out how to build a smelter that can
introduce just the right amount of carbon into them to make decent steel.
Knowing a bit about smelter designs, I decide to use a Japanese tatara
furnace. I still don't have rivets, but I figure that in a few weeks I'll have
enough steel to start making them. (After I make the buy-or-build-build
decision on the furnace, that is. I'm not allowed to reuse the one I made for
my last project of building music stands, and the commonly-used open-source
design has been known to mysteriously turn iron ore into lead instead.) The
rest of the bridge has yet to be tackled...

Point being: this is not a "we know enough, it's just complicated" problem. We
know _almost nothing_ and our tools are appallingly primitive. To quote some
classic hacker humor: "I was taught assembler / In my second year of school /
It's kinda like construction work / With a toothpick for a tool." Assembler
and Haskell have much more in common than a toothpick and a Caterpillar D9.

------
dano
Using wiki's in two different companies provided us with these checklist like
capabilities. We used MoinMoin at a prior company and now use MediaWiki, but
the technology isn't the point.

Everyone contributes to the wiki and it accrues knowledge from experience.
Some process documentation is carefully reviewed for accuracy, but it also
left a bit free-form so as to accommodate situation specific variations from
the norm.

The verification team (I dislike the term QA) encapsulates as much as possible
into the testing framework, but since the wiki based descriptions are so much
more rich, they remain a go to resource.

Recently I moved the IT/Networking staff to start making their project plans
in the wiki. Their defect rate has plummeted to nearly zero - mostly because
they are making plans! But what they've discovered is that they now have
frameworks of plans (checklists) from which they can derive their next plan.

Others have mentioned Dr. Gawande and I would recommend his book
[http://atulgawande.com/book/the-checklist-
manifesto/](http://atulgawande.com/book/the-checklist-manifesto/)

Good discussion. Don't have an internal wiki? Start one, you'll never go back.

~~~
greenyoda
You can also read Gawande's original article in the New Yorker magazine that
his book was based on:

[http://www.newyorker.com/reporting/2007/12/10/071210fa_fact_...](http://www.newyorker.com/reporting/2007/12/10/071210fa_fact_gawande?currentPage=all)

------
rybosome
My current team is the first one in my career as a software engineer in which
our testing infrastructure is robust enough to think like this. I just
resolved a bug this week by writing a test that failed due to its presence
(and leaving a comment with the ID of the bug), changing the code, then re-
running the test to ensure that it passed. This confidence in our code base is
wonderful; I have never felt so little fear when deploying.

Looking back, it amazes me that I ever didn't develop software this way.

~~~
jnbiche
May I ask what language this code base is in?

~~~
vinceguidry
Probably Ruby. No other language makes testing that easy or fun.

~~~
burntsushi
Go does. So does Rust. Both languages have some sort of unit testing
facilities packaged with the standard distribution. And both are dead simple
to use.

~~~
AYBABTME
You can't mock out your dependencies as easily in Go as you can monkey patch
them in Ruby.

However I've found the explicit error handling in Go to be more valuable in
making reliable software than a torrent of test in Ruby, or Java.

------
icefox
Whenever I introduce a bug that could have been caught automatically I either
add the missing unit test or I add a new git hook (there is of course a hook
to run unit tests). From missing license files, build failures, to just
spelling mistakes in the commit message there is no reason for these to exists
in the repository.

I created [https://github.com/icefox/git-hooks](https://github.com/icefox/git-
hooks) to manage hooks across repositories, users, and system wide. For
example if in a project I add a new hook making sure I never commit an invalid
xml file, all repos that have xml files will get the hook for free.

~~~
lifeisstillgood
I am loving the look of the git-books - got to try it tomorrow

------
mherrmann
I find the comparison of software development and surgery/flying an air plane
very lacking. It restricts the term "Software" in the post title to very
critical systems (OpenSSL admittedly being one of them).

The author proposes automated tests/Software "checklists" as the solution to
all problems. The problem with automated tests is that they can only catch
"expected" bugs. The author describes an idea for an automated test that
_might_ have caught the Heartbleed bug. Big deal, now that we know all about
the bug. A next unforeseen type of vulnerability will come, and no automated
test will catch it.

I think the article greatly exaggerates the applicability and capabilities of
automated tests (or "check lists"). I'm a big fan of all things TDD and
consider myself a very rigorous programmer (surely often to the detriment of
speed/pragmaticism). But I don't need a check list of the complexity of a
flight check to describe the rules I use in my work.

~~~
taejo
> A next unforeseen type of vulnerability will come, and no automated test
> will catch it.

But Heartbleed _wasn 't_ a new type of vulnerability. It's the same type of
vulnerability we've known about at least since the dawn of C. Almost all bugs
are of known types. How often do we see new types of vulnerabilities? Maybe a
couple a year. If we had only a couple vulnerabilities a year across all
software, we'd be many orders of magnitude better off.

~~~
mherrmann
Sure, I'm not saying the proposed automated test is bad. I think it might be
sensible to add it. As I said, I'm 100% for automated tests (I should be, as
the co-founder of a startup specializing in test automation tools). But
ascribing magical capabilities to catch all future bugs to automated tests /
"check lists" is IMHO detrimental to the cause because it leads to too high
expectations.

~~~
scott_w
They don't, and the article doesn't imply this.

A lot of stuff that gets on checklists is because not knowing about it killed
someone. Other documented procedures came from time in the simulator -
somewhat anagolous to manual user testing.

To be honest, the only people I know ascribing "magical capabilities" to unit
testing are those disparaging it. The rest of us think it's great, and makes
life a lot easier, but we've all been bitten by that unexpected bug when you
see it working in the real world.

~~~
jimktrains2
Exactly. I've always hated the "You can't test what you don't know so it's
worthless." Well sorry, I can test what I do know and make sure that I don't
break that. As new errors come upon, you add it to your tests (akin to
checklists, essentially), and make sure you don't break that use case again.

------
JoachimSchipper
Checklists have been proven to work, but the software I write (low-level high-
security/crypto software) is less repetitive than (most) surgeries. I haven't
managed to use anything checklist-like while writing code; however, quickly
pattern-matching against a mental library has been exceedingly useful when
_reviewing_ code.

Here are some sources I would recommend to people building their own mental
checklists:

\- The Art of Software Security Assessment (thanks to tptacek); I actually
learnt most of this from bits 'n pieces scattered over the web, but it's a
very convenient collection;

\- Common crypto flaws. Always look for authentication, _then_ encryption,
_and_ replay protection. (The latter is often forgotten even in otherwise good
protocols.) If a password is used anywhere, consider bruteforcing it (bcrypt
may stop such attacks - or not.) Check that IVs are used as demanded by the
mode (in particular, that CTR or GCM IVs are not reused.) Look for timing
attacks; the easy-to-spot and high-impact ones are use of memcmp() with HMACs
and use of CBC on unauthenticated data (padding oracle).

\- Buffer overflows may be bad, but integer under-/overflows are much more
common (in decent code.) Basically, you need a check before any operation
involving a user-supplied length, and this is very commonly forgotten. (Using
functions with internal overflow checking, like a decent calloc, helps.)

\- Consider the wider context. Spotting a buffer overflow is easy. Noting that
you forgot to <? include auth.php ?> is harder. You likely won't notice that
the latest "cleanup" leaves the firmware updater open to the internet unless
you actually spend five seconds thinking about the wider system.

(I'm quite interested in other's tips; the above is clearly _very_ slanted.
Also, I feel vaguely guilty about doing all of this in memory instead of from
a paper checklist - does anyone have positive or other experiences with
those?)

------
aegiso
Thing is, software doesn't happen in a vacuum.

Perhaps it's worth considering that maybe the reason that checklists aren't
the norm in the FOSS "meritocracy" is that they hinder progress, for a certain
value of progress. Maybe there was a stealth project that could have been
OpenSSL, developed with scrict adherance to checklists, but OpenSSL won
because it didn't have that burden? I suspect this applies more broadly to
startups, too.

Maybe checklists are a silent killer in the natural selection of the software
ecosystem, and that's why so much of our software is tripping over peacock
feathers?

Just a thought.

------
humancontact
I use this very frequently, helps a lot:
[http://www.boxuk.com/upload/2014/02/Relaunched-Ultimate-
Webs...](http://www.boxuk.com/upload/2014/02/Relaunched-Ultimate-Website-
Checklist-2.0.pdf)

------
leemcalilly
With software this should be your test suite. No test is too simple. No
feature or detail too small to test. Replace the line "relentless checklist"
with "relentless testing" and you're good to go. Don't deploy before all tests
are green and that's the same as not flying without running through your
checklist.

I grew up flying with my dad in his Cesna 172 and admiring how well the pre-
flight checklist worked. When I first heard about TDD, I immediately
recognized it as the same process, except automated.

~~~
ColinWright
That's what I first thought. Then I realized that test suites as most people
think of them would not have caught the Heartbleed bug, whereas a checklist
like this would have done so.

Testing is testing, but there are different ways of thinking about it, and
different ways to have it embodied. Test suites are one embodiment, and
higher-level checklists can complement them.

~~~
leemcalilly
I guess I've always thought of my integration tests as the higher-level
checklist. I've only done web development, so that works. I could see how if
you're writing software for something as important as OpenSSL then you might
need an extra set of checks, but there's still room for human error. Seems
like there should be someway to automate everything required to deploy
software.

But I realize this is an idealistic approach. The reality is that a good test
suite with higher-level checklists is probably more practical.

------
goblin89
> This can be automated! This could be mandated as a procedure to be gone
> through before the code is released. And doing this would prevent this kind
> of bug from ever happening again.

I might be missing something, but this sounds to me very much like a usual
test case. :) Having one in a suite of system or acceptance tests would indeed
prevent further occurrences of the bug.

------
brudgers
The optimist's response to "What could possibly go wrong?" is a swing for the
fences. The pessimist's response is a checklist. It's seeking to avoid the
worst outcomes and allowing success to come in due time. It's braking early
and accelerating from the apex as opposed going full speed and breaking things
fast.

~~~
jacques_chester
This seems like a fallacy of false dilemmas. The optimist can swing harder
because, thanks to professional pessimism, the bat won't crack halfway through
the swing, the stands don't collapse before the ball reaches them, the ball
doesn't explode on contact, and the rules for what constitutes a home run
don't have to be constantly reinvented by each player individually.

~~~
brudgers
Yes, we agree that the optimist's imagination limits the list of things that
could possibly go wrong to the absurd. And as you suggest perhaps an
optimist's optimism derives from a concept of professionalism born the love
child of dunning-kruger. Or perhaps the horns are grown on a strawman dividing
the world into naught but optimists and pessimists according to the law of the
excluded muddle.

------
qwerta
I tend to use checklists for everything. It saves a lot of thinking. I would
recommend Zim or other personal wiki.

------
nextos
I think he's missing an important point. C should not be used for safety
critical systems code if possible, period. A language that prevents those
leaks should be employed in its place.

Checklists are good, but you need to enforce them. If such a language is used
instead, these errors are impossible by design.

~~~
ColinWright
I think you're missing the point. Whether or not we're talking about C is a
detail, what is more important is that the lessons we learn need to be
encapsulated and encoded into procedures that everyone can apply and learn
from.

Equivalent mistakes can be made in any language powerful enough to do real
work. Off-by-one, behaving inappropriately on parameters outside those
expected, lots of things can go wrong in any language. Capturing your
knowledge in a form that can be used for testing is the idea, and that seems
to be missing entirely from computing.

~~~
PeterisP
Languages _can_ eliminate large classes of such mistakes.

Taking your own two examples: most off-by-one errors go away if you replace
"for (i = 0; i < datalength; i++)" with "for i in data" or something like
that; and by replacing < or <= comparisons with checks for range membership. A
checklist might say - "don't have assignments in your if statement conditions
like 'if (x=0)', it's risky"; but your language or tools around it may make it
impossible to do it.

"Behaving inappropriately on parameters outside those expected" is correlated
with the frequency of getting unexpected parameters. No static typing? You'll
have to check at runtime if the parameters are of the type that you expect.
Null/undefined values? Again, you may remember to check everywhere or the
language can force you to check _really every time_ , not almost every time.
Niche languages like Eiffel can help you ensure that you _know_ that the
parameters are within the expected range, etc.

Capturing such knowledge and encoding in a way suitable for everyone is done
in this way - it does break backward compatibility and requires rewriting code
and abandoning libraries or even languages; but the checklist equivalent of
"don't ever turn on the engine before checking X, even if you think it's okay"
is "don't use C strcpy ever, even if you think you know it's correct there".

------
Qworg
Using a system like this really helps for complicated and/or important code.
All of our safety critical and embedded code references a checklist before it
is made into a pull request. It really helps catch all of the "rubber ducky"
bugs.

------
nmrm
This is essentially describing a "process".

Except instead of emphasizing team-level details, it calls for an emphasis on
code-level details. I really like this idea.

~~~
jacques_chester
Watts Humphreys was probably the first to the idea of scaling development
processes _down_ , rather than up, arriving in the 90s at the Personal
Software Process.

The PSP is very data-intensive. You're meant to log pretty much everything you
do.

For example, you log your mistakes. Missed a semicolon? Log the mistake. Typo
in a variable name? Log the mistake. Critical misunderstanding of how a
library works? Log the mistake.

After a while you use your data to correct your common errors with ...
checklists! And other tools and practices, of course, but checklists are a big
part of the PSP.

It's worth reading _A Discipline for Software Engineering_ , even if you never
apply it.

------
hardwaresofton
Tried to make something similar to this once:

[http://konvention.vadosware.com](http://konvention.vadosware.com)

Suffered from the false premise that people would willingly contribute en
masse though...

~~~
icefox
On the main page the link for "Copy arrays with array#slice" is 404

~~~
hardwaresofton
Yeah, I haven't touched the site in what feels like forever...unfortunately,
don't have the time to fill it up with information... I might return to it one
day

------
menzoic
Isn't this what static analysis, penetration testing, and various other
automated smoke tests made for? Instead of adding to a checklist these tests
are updated to account for new vulnerabilities.

~~~
krschultz
The checklist is about making sure you have used those tools.

This is not how I would recommend running the average startup, but for mission
critical software having someone other than the author review all the code
using a checklist is probably the best way to ensure quality. The author of
the code would have the same checklist and would be expected to hit all the
points before handing the code over to the reviewer.

------
macobo
Can anyone point to the studies done about using checklists in surgeries?

~~~
ColinWright
A quick Google search[0] returns these:

[http://news.bbc.co.uk/1/hi/health/7825780.stm](http://news.bbc.co.uk/1/hi/health/7825780.stm)

[http://www.nrls.npsa.nhs.uk/resources/?entryid45=59860](http://www.nrls.npsa.nhs.uk/resources/?entryid45=59860)

[http://www.who.int/patientsafety/safesurgery/ss_checklist/en...](http://www.who.int/patientsafety/safesurgery/ss_checklist/en/)

[http://www.bmj.com/content/338/bmj.b220](http://www.bmj.com/content/338/bmj.b220)

[0]
[https://www.google.com/search?q=surgery+checklists](https://www.google.com/search?q=surgery+checklists)

~~~
mcguire
You should probably also mention this:

[http://theincidentaleconomist.com/wordpress/when-
checklists-...](http://theincidentaleconomist.com/wordpress/when-checklists-
work-and-when-they-dont/)

Atul Gawande is probably the foremost proponent of surgical checklists and in
that article is responding to an Ontario study reporting that checklists were
not significant---it sounds like a pretty bad study.

Surgeons don't particularly like checklists.

" _For starters, the most controversial idea for teams to accept is perhaps
the simplest item in the checklist. Require all team members say their names
prior to the launch of the procedure.

"'This has been one of the most important things that help people feel
comfortable speaking up' if they're unsure or unclear, for example, that this
is the right patient, right site, right procedure.

"'It acknowledges that you're part of a team and are allowed to speak.'

"Gawande says that there has been resistance to accepting checklists at
another level. 'The concept has forced us rethink what it means to be great at
what we do. And I hadn't grasped this until I saw it recur over and over
again. There's a set of values in the idea of a checklist, and they're in
distinct conflict with some of the values we have in medicine.'

"'We value physician autonomy, which works well when there are just two full
time equivalents providing care, but when we have 19.5 FTEs trying to make
things work, it becomes a problem.'_"[1]

Any of that sounding familiar?

[1]
[http://www.healthleadersmedia.com/page-3/QUA-262159/Gawande-...](http://www.healthleadersmedia.com/page-3/QUA-262159/Gawande-
on-Checklists-Why-Dont-Hospitals-Use-Them)

~~~
poof131
Great reference. That first point relates more to Crew Resource Management
(CRM)[1], an important concept making its way from aviation to surgery. After
a decade flying F-18s for the Navy, I value checklists but communication is
probably even more important and often overlooked. Finding the courage to
speak up is more challenging then it seems. It's so easy to assume that the
Captain, Surgeon, or whoever is in charge knows what they are doing. One of
the worst accidents in history[2] that helped kick off CRM, could have likely
been prevented if the co-pilot had assertively told the Captain that they
weren't cleared for take-off.

I still remember the Navy's version and believe it's applicable to many places
other than aviation.

D - decision making A - assertiveness M - mission analysis C - communication L
- leadership A - adaptability / flexibility S - situational awareness

[1]
[http://en.wikipedia.org/wiki/Crew_Resource_Management](http://en.wikipedia.org/wiki/Crew_Resource_Management)
[2]
[http://en.wikipedia.org/wiki/Tenerife_airport_disaster](http://en.wikipedia.org/wiki/Tenerife_airport_disaster)

------
halayli
Rather than asking more from the developers, donate more money to the project
and get more developers to test the software.

------
cammil
I think this is a great idea.

------
andyl
Software already has checklists - using names like 'regression tests',
'automation scripts', etc.

