diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright Mark Wotton (c) 2016
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Mark Wotton nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/hspec-stack-rerun.cabal b/hspec-stack-rerun.cabal
new file mode 100644
--- /dev/null
+++ b/hspec-stack-rerun.cabal
@@ -0,0 +1,19 @@
+name:                hspec-stack-rerun
+version:             0.1.0.0
+synopsis:            Simple project template from stack
+description:         Please see README.md
+homepage:            https://github.com/mwotton/hspec-stack-rerun#readme
+license:             BSD3
+license-file:        LICENSE
+author:              Mark Wotton
+maintainer:          mwotton@gmail.com
+copyright:           AllRightsReserved
+category:            Web
+build-type:          Simple
+cabal-version:       >=1.10
+
+library
+  hs-source-dirs:      src
+  default-language:    Haskell2010
+  build-depends:       base >= 4.7 && < 5, hspec, strict, directory, safe
+  exposed-modules:     Rerun
diff --git a/src/Rerun.hs b/src/Rerun.hs
new file mode 100644
--- /dev/null
+++ b/src/Rerun.hs
@@ -0,0 +1,67 @@
+{-# LANGUAGE ScopedTypeVariables #-}
+module Rerun where
+
+import Test.Hspec.Runner
+import Control.Exception
+import Prelude
+import System.Environment
+import System.IO.Strict
+import System.IO(withFile,IOMode(ReadMode))
+import System.Directory(removeFile)
+import Safe (lastMay)
+import Control.Monad(when)
+
+-- | We wrap this so that we can stash HSPEC_FAILURES in a file (which
+--   comes from HSPEC_FAILURES_FILE).
+
+main clientSpec = do
+  stashFile <- lookupEnv "HSPEC_FAILURES_FILE"
+  alreadySet <- lookupEnv "HSPEC_FAILURES"
+  print ("startup", stashFile, alreadySet)
+  case (stashFile,alreadySet) of
+    (Just stash,Just failures) -> do
+      -- if there's no stash set, we might as well write it so
+      -- we have a starting point. it might get overwritten later,
+      -- that's fine
+      print ("writing stash optimistically", failures)
+      writeFile stash failures
+    (Just stash,Nothing) -> do
+      print ("reading", stash)
+      f <- safeReadFile stash
+      print ("read", stash)
+      case f of
+        Nothing -> print ("couldn't read stash", stash)
+        -- this should read all of contents, thereby closing the
+        -- filehandle. Lazy IO is the devil.
+        Just contents ->  do
+          when (contents /= "") $ do
+            print ("read stash, setting env", contents)
+            setEnv "HSPEC_FAILURES" contents
+    _ -> return ()
+  clientSpec `finally` do
+    print "done with tests!"
+    -- we don't remove the file until now, so that if ghcid gets
+    -- interrupted, we still have the failures to run first.
+    -- small race condition, obviously, but the worst case is that
+    -- we run more tests than we should.
+    case stashFile of
+      Just stash -> logAndIgnore () $ removeFile stash
+      Nothing -> return ()
+
+    newSet <- lookupEnv "HSPEC_FAILURES"
+    print ("spec failures", newSet,stashFile,alreadySet)
+    case (stashFile,alreadySet,newSet) of
+      -- only care if there is a stash file, the var wasn't set before,
+      -- and there is a new value: here, we write the file
+      (Just stash,Nothing,Just newset) ->
+        writeFile stash newset
+      _ -> return ()
+
+-- LAZY IO IS THE DEVIL
+safeReadFile :: FilePath -> IO (Maybe String)
+safeReadFile fs = logAndIgnore Nothing $ do
+  f <- withFile fs ReadMode (\h -> hGetContents h >>= \x -> seq (lastMay x) (return x))
+  print ("saferead got", f)
+  return (Just f)
+
+logAndIgnore def f  =   handle (\(e::IOException) -> print ("saferead failed", e) >> return def) f
