diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown
deleted file mode 100644
--- a/CHANGELOG.markdown
+++ /dev/null
@@ -1,934 +0,0 @@
-Release Notes
-=============
-
-All notable changes to this project will be documented in this file.
-
-This project is versioned according to the [Package Versioning Policy](https://pvp.haskell.org), the
-*de facto* standard Haskell versioning scheme.
-
-
-1.0.0.1
--------
-
-- **Date**    2017-01-19
-- **Git tag** [dejafu-1.0.0.1][]
-- **Hackage** https://hackage.haskell.org/package/dejafu-1.0.0.1
-
-### Miscellaneous
-
-- The upper bound on concurrency was bumped to <1.5.
-
-[dejafu-1.0.0.1]: https://github.com/barrucadu/dejafu/releases/tag/dejafu-1.0.0.1
-
-
----------------------------------------------------------------------------------------------------
-
-
-1.0.0.0
--------
-
-- **Date**    2017-12-23
-- **Git tag** [dejafu-1.0.0.0][]
-- **Hackage** https://hackage.haskell.org/package/dejafu-1.0.0.0
-
-### Test.DejaFu
-
-- All testing functions now require a `MonadConc`, `MonadRef`, and `MonadIO` constraint:
-
-    It is no longer possible to test things in `ST`.
-
-- All testing functions now take the action to test as the last parameter.
-
-- The `autocheckIO`, `dejafuIO`, `dejafusIO`, `autocheckWayIO`, `dejafuWayIO`, `dejafusWayIO`,
-  `dejafuDiscardIO`, `runTestM`, and `runTestWayM` functions are now gone.
-
-- The `Predicate` type has been replaced with a more general `ProPredicate` type which is a
-  profunctor and (b) can discard results not needed to determine if the predicate passes. (#124)
-
-    All testing functions have been generalised to take a `ProPredicate` instead.  The `Predicate a`
-    type remains as an alias for `ProPredicate a a`.  Passing tests have their resident memory usage
-    significantly decreased.
-
-- The `Result` type no longer includes a number of cases checked, as this is not meaningful with
-  predicates including discard functions.
-
-- New `alwaysNothing` and `somewhereNothing` functions, like `alwaysTrue` and `somewhereTrue`, to
-  lift functions to `ProPredicate`s.
-
-- The `alwaysTrue2` function is gone, as its behaviour was unintuitive and easy to get wrong, and
-  has been replaced with new `alwaysSameOn` and `alwaysSameBy` predicates, which generalise
-  `alwaysSame`.
-
-- The `alwaysSame`, `alwaysSameOn`, and `alwaysSameBy` predicates now gives the simplest execution
-  trace leading to each distinct result.
-
-### Test.DejaFu.Common
-
-- This module has been split up into new Test.DejaFu.Internal, Types, and Utils modules. (#155)
-
-- New `ForkOS` and `IsCurrentThreadBound` thread actions. (#126)
-
-- New `WillForkOS` and `WillIsCurrentThreadBound` lookaheads. (#126)
-
-- The `TTrace` type synonym for `[TAction]` has been removed.
-
-- The `preEmpCount` function has been removed.
-
-- New functions `strengthenDiscard` and `weakenDiscard` to combine discard functions.
-
-- The `Discard` type is now defined here and re-exported from Test.DejaFu.SCT.
-
-- The `ThreadId`, `CRefId`, `MVarId`, and `TVarId` types are now newtypes over a common `Id`
-  type. (#137)
-
-### Test.DejaFu.Conc
-
-- The `ConcST` type alias is gone.
-
-- The `MonadBase IO ConcIO` instance is gone.
-
-- The `MonadIO ConcIO` instance is replaces with a more general `MonadIO n => MonadIO (ConcT r n)`
-  instance.
-
-- The `runConcurrent` function now has a `MonadConc` constraint.
-
-- If bound threads are supported, the main thread when testing is bound. (#126)
-
-- Each entry in an execution trace is now in the form `(decision, alternatives, action)`.  The
-  chosen thread is no longer in the list of alternatives, which makes raw traces easier to
-  read. (#121)
-
-- Due to changes in Test.DejaFu.Schedule, no longer re-exports `Decision`, `NonEmpty`, `tidOf`, or
-  `decisionOf`.
-
-### Test.DejaFu.Refinement
-
-- A blocking interference function is no longer reported as a deadlocking execution.
-
-### Test.DejaFu.Schedule
-
-- No longer re-exports `Decision` or `NonEmpty`.
-
-- The `tidOf` and `decisionOf` functions have moved to Test.DejaFu.Utils.
-
-### Test.DejaFu.SCT
-
-- All testing functions now require a `MonadConc` constraint:
-
-    It is no longer possible to test things in `ST`.
-
-### Test.DejaFu.STM
-
-- This is now an internal module. (#155)
-
-### Performance
-
-- Significant resident memory reduction for most passing tests.
-- Improved dependency detection for `MVar` actions, leading to fewer executions.
-
-### Miscellaneous
-
-- The minimum supported version of concurrency is now 1.3.0.0.
-
-[dejafu-1.0.0.0]: https://github.com/barrucadu/dejafu/releases/tag/dejafu-1.0.0.0
-
-
----------------------------------------------------------------------------------------------------
-
-
-0.9.1.2
--------
-
-- **Date**    2017-12-12
-- **Git tag** [dejafu-0.9.1.2][]
-- **Hackage** https://hackage.haskell.org/package/dejafu-0.9.1.2
-
-### Miscellaneous
-
-- The upper bound on leancheck was bumped to <0.8.
-
-[dejafu-0.9.1.2]: https://github.com/barrucadu/dejafu/releases/tag/dejafu-0.9.1.2
-
-
----------------------------------------------------------------------------------------------------
-
-
-0.9.1.1
--------
-
-- **Date**    2017-12-08
-- **Git tag** [dejafu-0.9.1.1][]
-- **Hackage** https://hackage.haskell.org/package/dejafu-0.9.1.1
-
-### Miscellaneous
-
-- Fix an issue where nested masks nested inside unmasks would sometimes not be pre-empted in
-  systematic testing.
-
-[dejafu-0.9.1.1]: https://github.com/barrucadu/dejafu/releases/tag/dejafu-0.9.1.1
-
-
----------------------------------------------------------------------------------------------------
-
-
-0.9.1.0
--------
-
-- **Date**    2017-11-26
-- **Git tag** [dejafu-0.9.1.0][]
-- **Hackage** https://hackage.haskell.org/package/dejafu-0.9.1.0
-
-### Test.DejaFu.Common
-
-- Fix some incorrect "@since" haddock comments.
-- Pretty-printed traces now display a pre-emption following a yield with a little "p".
-
-### Test.DejaFu.Conc
-
-- Add a missing `MonadFail` instance.
-
-### Test.DejaFu.STM
-
-- Add a missing `MonadFail` instance.
-
-[dejafu-0.9.1.0]: https://github.com/barrucadu/dejafu/releases/tag/dejafu-0.9.1.0
-
-
----------------------------------------------------------------------------------------------------
-
-
-0.9.0.3
--------
-
-- **Date**    2017-11-06
-- **Git tag** [dejafu-0.9.0.3][]
-- **Hackage** https://hackage.haskell.org/package/dejafu-0.9.0.3
-
-### Miscellaneous
-
-- Impose a dependency between commits and memory barriers, to make barriers sound (#138).
-
-[dejafu-0.9.0.3]: https://github.com/barrucadu/dejafu/releases/tag/dejafu-0.9.0.3
-
-
----------------------------------------------------------------------------------------------------
-
-
-0.9.0.2
--------
-
-- **Date**    2017-11-02
-- **Git tag** [dejafu-0.9.0.2][]
-- **Hackage** https://hackage.haskell.org/package/dejafu-0.9.0.2
-
-### Miscellaneous
-
-- Small improvement to dependency detection of STM transactions.
-- A fair bound of 0 will now prevent all yields.
-
-[dejafu-0.9.0.2]: https://github.com/barrucadu/dejafu/releases/tag/dejafu-0.9.0.2
-
-
----------------------------------------------------------------------------------------------------
-
-
-0.9.0.1
--------
-
-- **Date**    2017-10-28
-- **Git tag** [dejafu-0.9.0.1][]
-- **Hackage** https://hackage.haskell.org/package/dejafu-0.9.0.1
-
-### Miscellaneous
-
-- Fixed an issue where tests with exception handlers would sometimes skip over nested handlers or
-  try to take the tail of an empty list (#139 and #141).
-
-[dejafu-0.9.0.1]: https://github.com/barrucadu/dejafu/releases/tag/dejafu-0.9.0.1
-
-
----------------------------------------------------------------------------------------------------
-
-
-0.9.0.0
--------
-
-- **Date**    2017-10-11
-- **Git tag** [dejafu-0.9.0.0][]
-- **Hackage** https://hackage.haskell.org/package/dejafu-0.9.0.0
-
-### Test.DejaFu.Common
-
-- New `isInternalError`, `isAbort`, `isDeadlock`, `isUncaughtException`, and
-  `isIllegalSubconcurrency` functions for matching failure types.  Also exported from Test.DejaFu.
-
-- The `UncaughtException` `Failure` constructor now includes the exception.
-
-    The `Read`, `Enum`, and `Bounded` instances are gone.  The `Eq`, `Ord`, and `NFData` instances
-    use the `show` of the exception.  Pretty-printed failures include the exception text.
-
-- New `ThreadDelay` and `WillThreadDelay` constructors in `ThreadAction` and `Lookahead`.  Uses of
-  `threadDelay` are no longer reported as a use of `yield`.
-
-[dejafu-0.9.0.0]: https://github.com/barrucadu/dejafu/releases/tag/dejafu-0.9.0.0
-
-
----------------------------------------------------------------------------------------------------
-
-
-0.8.0.0
--------
-
-- **Date**    2017-09-26
-- **Git tag** [dejafu-0.8.0.0][]
-- **Hackage** https://hackage.haskell.org/package/dejafu-0.8.0.0
-
-### Test.DejaFu.Common
-
-- Execution traces now only include a single item of lookahead (#120).
-- STM traces now include IDs of created `TVar`s (#80).
-
-### Test.DejaFu.Schedule
-
-- Schedulers no longer take the execution trace so far (#106).
-- The `Scheduler` type is now a newtype (#122).
-
-[dejafu-0.8.0.0]: https://github.com/barrucadu/dejafu/releases/tag/dejafu-0.8.0.0
-
-
----------------------------------------------------------------------------------------------------
-
-
-0.7.3.0
--------
-
-- **Date**    2017-09-26
-- **Git tag** [dejafu-0.7.3.0][]
-- **Hackage** https://hackage.haskell.org/package/dejafu-0.7.3.0
-
-### Test.DejaFu.Common
-
-- A new function `threadNames`, to get all named threads from a trace.
-
-### Miscellaneous
-
-- Escaping a mask by raising an exception now correctly restores the masking state (#118).
-- Named threads which are only started by a pre-emption now show up in the trace (#101).
-
-[dejafu-0.7.3.0]: https://github.com/barrucadu/dejafu/releases/tag/dejafu-0.7.3.0
-
-
----------------------------------------------------------------------------------------------------
-
-
-0.7.2.0
--------
-
-- **Date**    2017-09-16
-- **Git tag** [dejafu-0.7.2.0][]
-- **Hackage** https://hackage.haskell.org/package/dejafu-0.7.2.0
-
-### Test.DejaFu.STM
-
-- The `STM n r` monad now has `Alternative` and `MonadPlus` instances, using `orElse` for the binary
-  operation and `retry` for the unit.
-
-### Miscellaneous
-
-- The `Eq` instance for `ThreadId`, `CRefId`, `MVarId`, and `TVarId` now only compares the numbers,
-  not the names.
-
-    This makes it consistent with the `Ord` instances, and is also a small performance gain.
-
-- Now compatible with concurrency-1.2.0.0.
-
-[dejafu-0.7.2.0]: https://github.com/barrucadu/dejafu/releases/tag/dejafu-0.7.2.0
-
-
----------------------------------------------------------------------------------------------------
-
-
-0.7.1.3
--------
-
-- **Date**    2017-09-08
-- **Git tag** [dejafu-0.7.1.3][]
-- **Hackage** https://hackage.haskell.org/package/dejafu-0.7.1.3
-
-### Miscellaneous
-
-- Aborted STM transactions are now rolled back correctly (issue #111).
-- Slightly improved run-time of systematic testing.
-
-[dejafu-0.7.1.3]: https://github.com/barrucadu/dejafu/releases/tag/dejafu-0.7.1.3
-
-
----------------------------------------------------------------------------------------------------
-
-
-0.7.1.2
--------
-
-- **Date**    2017-08-21
-- **Git tag** [dejafu-0.7.1.2][]
-- **Hackage** https://hackage.haskell.org/package/dejafu-0.7.1.2
-
-### Miscellaneous
-
-- Errors thrown with `Control.Monad.fail` no longer terminate testing, and are now correctly treated
-  as asynchronous exceptions.
-
-[dejafu-0.7.1.2]: https://github.com/barrucadu/dejafu/releases/tag/dejafu-0.7.1.2
-
-
----------------------------------------------------------------------------------------------------
-
-
-0.7.1.1
--------
-
-- **Date**    2017-08-16
-- **Git tag** [dejafu-0.7.1.1][]
-- **Hackage** https://hackage.haskell.org/package/dejafu-0.7.1.1
-
-### Miscellaneous
-
-- Significantly reduced memory usage in systematic testing when discarding traces.
-
-    Previously this was `O(max trace length * number of executions)`
-
-    Now it's `O(max trace length + total size of traces kept)`
-
-[dejafu-0.7.1.1]: https://github.com/barrucadu/dejafu/releases/tag/dejafu-0.7.1.1
-
-
----------------------------------------------------------------------------------------------------
-
-
-0.7.1.0
--------
-
-- **Date**    2017-08-10
-- **Git tag** [dejafu-0.7.1.0][]
-- **Hackage** https://hackage.haskell.org/package/dejafu-0.7.1.0
-
-### Test.DejaFu
-
-- Exposed the new SCT discard functions through `dejafuDiscard` and `dejafuDiscardIO`.
-
-    There are no `dejafusDiscard` and `dejafusDiscardIO` functions because this would probably be
-    confusing, as the traces are shared.
-
-- The `Discard` type and `defaultDiscard` function are also exposed.
-
-### Test.DejaFu.Defaults
-
-- Added a new `defaultDiscarder` function, which discards nothing.
-
-### Test.DejaFu.SCT
-
-- Added new SCT functions to selectively discard results or traces, which can be a significant
-  memory saving if you know what sorts of results you are interested in:
-    - New type: `Discard`.
-    - New functions: `runSCTDiscard`, `resultsSetDiscard`, `sctBoundDiscard`,
-      `sctUniformRandomDiscard`, and `sctWeightedRandomDiscard`.
-    - `resultsSet` and `resultsSet'` now discard traces as they are produced, rather than all at the
-      end, greatly improving performance when traces are large.
-
-[dejafu-0.7.1.0]: https://github.com/barrucadu/dejafu/releases/tag/dejafu-0.7.1.0
-
-
----------------------------------------------------------------------------------------------------
-
-
-0.7.0.2
--------
-
-- **Date**    2017-06-12
-- **Git tag** [dejafu-0.7.0.2][]
-- **Hackage** https://hackage.haskell.org/package/dejafu-0.7.0.2
-
-### Test.DejaFu.Refinement
-
-- Removed unnecessary typeclass constraints from `check`, `check'`, `checkFor`, and
-  `counterExamples`.
-
-### Miscellaneous
-
-- Removed an unnecessary dependency on [monad-loops][].
-
-[monad-loops]: https://hackage.haskell.org/package/monad-loops
-[dejafu-0.7.0.2]: https://github.com/barrucadu/dejafu/releases/tag/dejafu-0.7.0.2
-
-
----------------------------------------------------------------------------------------------------
-
-
-0.7.0.1
--------
-
-- **Date**    2017-06-09
-- **Git tag** [dejafu-0.7.0.1][]
-- **Hackage** https://hackage.haskell.org/package/dejafu-0.7.0.1
-
-### Test.DejaFu.Refinement
-
-- `check`, `check'`, and `checkFor` are now faster if there are multiple counterexamples.
-- The above and `counterExamples` are now faster even if there is only a single counterexample in
-  some cases.
-
-[dejafu-0.7.0.1]: https://github.com/barrucadu/dejafu/releases/tag/dejafu-0.7.0.1
-
-
----------------------------------------------------------------------------------------------------
-
-
-0.7.0.0
--------
-
-- **Date**    2017-06-07
-- **Git tag** [dejafu-0.7.0.0][]
-- **Hackage** https://hackage.haskell.org/package/dejafu-0.7.0.0
-
-### Test.DejaFu
-
-- The new Test.DejaFu.Defaults and Test.DejaFu.Refinement modules are re-exported.
-- The new smart constructors from Test.DejaFu.SCT are exported.
-
-### Test.DejaFu.Defaults
-
-- The `default*` values are now defined in the new Test.DejaFu.Defaults module. There is no breaking
-  API change as they are re-exported from Test.DejaFu.
-
-### Test.DejaFu.Refinement
-
-- A new module for checking observational properties of the side-effects of stateful, concurrent
-  functions.
-
-    This is related to my work on [CoCo][], allowing dejafu to test what CoCo discovers.
-
-### Test.DejaFu.SCT
-
-- The `Way` type is now abstract and exposes smart constructor functions:
-    - `systematically`, corresponding to the old `Systematically`.
-    - `randomly`, corresponding to the old `Randomly`,
-    - `uniformly`, a new uniform random (as opposed to weighted random) scheduler.
-    - `swarmy`, corresponding to the old `Randomly` and specifying how many executions to use the
-      same weights for.
-- A new `sctUniformRandom` function to do uniform (non-weighted) scheduling.
-- The `sctRandom` function is now called `sctWeightedRandom` and can now re-use the same weights for
-  multiple executions.
-- The `sctPreBound`, `sctFairBound`, and `sctLengthBound` functions have been removed.
-
-### Fixed
-
-- An issue where `subconcurrency` would re-use `MVar` IDs, leading to false reports of deadlock on
-  occasion (issue #81).
-
-[CoCo]: https://github.com/barrucadu/coco
-[dejafu-0.7.0.0]: https://github.com/barrucadu/dejafu/releases/tag/dejafu-0.7.0.0
-
-
----------------------------------------------------------------------------------------------------
-
-
-0.6.0.0
--------
-
-- **Date**    2017-04-08
-- **Git tag** [dejafu-0.6.0.0][]
-- **Hackage** https://hackage.haskell.org/package/dejafu-0.6.0.0
-
-### Test.DejaFu.Conc
-
-- The `Conc n r a` type is now `ConcT r n a`, and has been given a `MonadTrans` instance. Uses of
-  `lift` appear in the execution trace in the same way as `liftBase` and `liftIO`.
-    - The `ConcIO` and `ConcST` aliases have been updated, so this should be an invisible change to
-      most users.
-
-### Test.DejaFu.SCT
-
-- `Way` is now a GADT, no longer taking a type parameter. This greatly improves type inference when
-  the `Systematically` constructor is used.
-    - The `NFData` instance for `Way` is now gone. The alternative was requiring that any
-      `RandomGen` used also implement `NFData`, which is *very* restrictive
-
-### Miscellaneous
-
-- There is now a changelog.
-- Test.DejaFu.Common is now considered to form part of the public API of the library.
-- Every definition and instance now has a Haddock "@since" annotation.
-
-[dejafu-0.6.0.0]: https://github.com/barrucadu/dejafu/releases/tag/dejafu-0.6.0.0
-
-
----------------------------------------------------------------------------------------------------
-
-
-0.5.1.3
--------
-
-- **Date**    2017-04-05
-- **Git tag** [dejafu-0.5.1.3][]
-- **Hackage** https://hackage.haskell.org/package/dejafu-0.5.1.3
-
-### Miscellaneous
-
-- The version range on the concurrency package has been changed to 1.1.*.
-
-[dejafu-0.5.1.3]: https://github.com/barrucadu/dejafu/releases/tag/dejafu-0.5.1.3
-
-
----------------------------------------------------------------------------------------------------
-
-
-0.5.1.2
--------
-
-- **Date**    2017-03-04
-- **Git tag** [dejafu-0.5.1.2][]
-- **Hackage** https://hackage.haskell.org/package/dejafu-0.5.1.2
-
-**This version was misnumbered! It should have caused a minor version bump!**
-
-### Test.DejaFu.Conc
-
-- New `MonadRef` and `MonadAtomicRef` instances for the `Conc` type using `CRef`.
-
-### Fixed
-
-- A long-standing bug where if the main thread is killed with a `throwTo`, the throwing neither
-  appears in the trace nor correctly terminates the execution.
-
-### Miscellaneous
-
-- The maximum supported version of the concurrency package has been changed to 1.1.1.*.
-
-[dejafu-0.5.1.2]: https://github.com/barrucadu/dejafu/releases/tag/dejafu-0.5.1.2
-
-
----------------------------------------------------------------------------------------------------
-
-
-0.5.1.1
--------
-
-- **Date**    2017-02-25
-- **Git tag** [dejafu-0.5.1.1][]
-- **Hackage** https://hackage.haskell.org/package/dejafu-0.5.1.1
-
-### Fixed
-
-- The correct scheduler state is now passed to the scheduler immediately after the termination of a
-  `subconcurrency` action.
-- SCT of subconcurrency no longer loops infinitely.
-
-[dejafu-0.5.1.1]: https://github.com/barrucadu/dejafu/releases/tag/dejafu-0.5.1.1
-
-
----------------------------------------------------------------------------------------------------
-
-
-0.5.1.0
--------
-
-- **Date**    2017-02-25
-- **Git tag** [dejafu-0.5.1.0][]
-- **Hackage** https://hackage.haskell.org/package/dejafu-0.5.1.0
-
-### Test.DejaFu
-
-- A new `NFData` instance for `Result`.
-
-### Test.DejaFu.Common
-
-- New instances:
-    - `NFData` for `ThreadId`, `CRefId`, `MVarId`, `TVarId`, `IdSource`, `ThreadAction`,
-      `Lookahead`, `ActionType`, `TAction`, `Decision`, `Failure`, and `MemType`.
-    - `Eq`, `Ord`, and `Show` instances for `IdSource`.
-
-### Test.DejaFu.SCT
-
-- New `NFData` instances for `Way`, `Bounds`, `PreemptionBound`, `FairBound`, and `LengthBound`.
-- New strict variants of `runSCT` and `resultsSet`: `runSCT'` and `resultsSet'`.
-
-### Test.DejaFu.STM
-
-- A new `NFData` instance for `Result`.
-
-[dejafu-0.5.1.0]: https://github.com/barrucadu/dejafu/releases/tag/dejafu-0.5.1.0
-
-
----------------------------------------------------------------------------------------------------
-
-
-0.5.0.2
--------
-
-- **Date**    2017-02-22
-- **Git tag** [dejafu-0.5.0.2][]
-- **Hackage** https://hackage.haskell.org/package/dejafu-0.5.0.2
-
-**This version was misnumbered! It should have caused a major version bump!**
-
-### Test.DejaFu.Common
-
-- A new `StopSubconcurrency` constructor of `ThreadAction`.
-
-### Changed
-
-- A `StopConcurrency` action appears in the execution trace immediately after the end of a
-  `subconcurrency` action (much like the `PopCatching` and `ResetMasking` actions which appear after
-  a catch and mask).
-- A `subconcurrency` action now inherits the number of capabilities from the outer computation,
-  rather than being reset to 2 as before.
-
-### Miscellaneous
-
-- Test.DejaFu.SCT now compiles with MonoLocalBinds enabled (implied by GADTs and TypeFamilies),
-  which may be relevant to hackers.
-
-[dejafu-0.5.0.2]: https://github.com/barrucadu/dejafu/releases/tag/dejafu-0.5.0.2
-
-
----------------------------------------------------------------------------------------------------
-
-
-0.5.0.1
--------
-
-- **Date**    2017-02-21
-- **Git tag** [dejafu-0.5.0.1][]
-- **This version was never pushed to hackage, whoops!**
-
-### Fixed
-
-- `readMVar` is once again considered a "release action" for the purposes of fair-bounding.
-
-[dejafu-0.5.0.1]: https://github.com/barrucadu/dejafu/releases/tag/dejafu-0.5.0.1
-
-
----------------------------------------------------------------------------------------------------
-
-
-0.5.0.0
--------
-
-- **Date**    2017-02-21
-- **Git tag** [dejafu-0.5.0.0][]
-- **Hackage** https://hackage.haskell.org/package/dejafu-0.5.0.0
-
-### Test.DejaFu
-
-- All the functions which did take a `Bounds` now take a `Way` instead and support random scheduling
-  as well.
-
-### Test.DejaFu.Common
-
-- New `Eq` instances for `ThreadAction` and `Lookahead`.
-- A `TryReadMVar` constructor for `ThreadAction` and a corresponding `WillTryReadMVar` constructor
-  for `Lookahead`.
-
-### Test.DejaFu.Conc
-
-- A new testing-only `subconcurrency` function, to run a concurrent action and do something with its
-  result in the same concurrent context, even if it fails.
-
-### Test.DejaFu.SCT
-
-- An `sctRandom` function to run a fixed number of randomly-scheduled executions of a program.
-- The `Way` type, to abstract over how to run a concurrent program, used by new functions `runSCT`
-  and `resultsSet`.
-
-### Fixed
-
-- Some previously-missed `CRef` action dependencies are no longer missed.
-
-### Miscellaneous
-
-- The supported version of the concurrency package was bumped to 1.1.0.0, introducing `tryReadMVar`.
-- A bunch of things were called "Var" or "Ref", these are now consistently "MVar" and "CRef".
-- Significant performance improvements in both time and space.
-- The dpor package has been merged back into this, as it turned out not to be very generally
-  useful. There is no direct replacement, but I have no intent to update it, so the dpor package is
-  now __deprecated__.
-
-[dejafu-0.5.0.0]: https://github.com/barrucadu/dejafu/releases/tag/dejafu-0.5.0.0
-
-
----------------------------------------------------------------------------------------------------
-
-
-0.4.0.0
--------
-
-- **Date**    2016-09-10
-- **Git tag** [dejafu-0.4.0.0][]
-- **Hackage** https://hackage.haskell.org/package/dejafu-0.4.0.0
-
-### Test.DejaFu
-
-- The `autocheck'` function now takes the schedule bounds as a parameter.
-- New `runTestM` and `runTestM'` functions, monad-polymorphic variants of the now-removed
-  `runTestIO` and `runTestIO'` functions.
-
-### Test.DejaFu.Conc
-
-- The `Conc` type no longer has the STM type as a parameter.
-- A new `runConcurrent` function, a monad-polymorphic version of the now-removed `runConcST` and
-  `runConcIO` functions.
-
-### Test.DejaFu.SCT
-
-- The `ST`-specific functions are now monad-polymorphic.
-- The `IO` function variants have been removed.
-
-### Test.DejaFu.STM
-
-- A new `runTransaction` function, a monad-polymorphic version of the now-removed `runTransactionST`
-  and `runTransactionIO` functions.
-
-### Changed
-
-- The termination of the main thread in execution traces now appears as a single `Stop`, rather than
-  the sequence `Lift, Stop`.
-- Execution traces printed by the helpful functions in Test.DejaFu now include a key of thread
-  names.
-
-### Miscellaneous
-
-- Remodularisation:
-    - The Control.* modules have all been split out into a separate "concurrency" package.
-    - Many definitions from other modules have been moved to the new Test.DejaFu.Common module.
-    - The Test.DejaFu.Deterministic module has been renamed to Test.DejaFu.Conc
-
-[dejafu-0.4.0.0]: https://github.com/barrucadu/dejafu/releases/tag/dejafu-0.4.0.0
-
-
----------------------------------------------------------------------------------------------------
-
-
-0.3.2.1
--------
-
-- **Date**    2016-07-21
-- **Git tag** [dejafu-0.3.2.1][]
-- **Hackage** https://hackage.haskell.org/package/dejafu-0.3.2.1
-
-### Fixed
-
-- The implementation of the STM `orElse` for `STMLike` incorrectly handled some state
-  non-associatively, leading to false deadlocks being reported in some cases.
-
-[dejafu-0.3.2.1]: https://github.com/barrucadu/dejafu/releases/tag/dejafu-0.3.2.1
-
-
----------------------------------------------------------------------------------------------------
-
-
-0.3.2.0
--------
-
-- **Date**    2016-06-06
-- **Git tag** [dejafu-0.3.2.0][]
-- **Hackage** https://hackage.haskell.org/package/dejafu-0.3.2.0
-
-**Builds with both dpor-0.1 and dpor-0.2, however some improvements require dpor-0.2.**
-
-### Fixed
-
-- (faster with dpor-0.2) Executions missed due to daemon threads with uninteresting first actions
-  are no longer missed.
-
-### Changed
-
-- (requires dpor-0.2) Significantly improved dependency inference of exceptions, greatly improving
-  performance of testcases using exceptions.
-- Significantly improved dependency inference of STM transactions, greatly improving performance of
-  testcases using STM.
-
-[dejafu-0.3.2.0]: https://github.com/barrucadu/dejafu/releases/tag/dejafu-0.3.2.0
-
-
----------------------------------------------------------------------------------------------------
-
-
-0.3.1.1
--------
-
-- **Date**    2016-05-26
-- **Git tag** [dejafu-0.3.1.1][]
-- **Hackage** https://hackage.haskell.org/package/dejafu-0.3.1.1
-
-### Miscellaneous
-
-- Now supports GHC 8.
-
-[dejafu-0.3.1.1]: https://github.com/barrucadu/dejafu/releases/tag/dejafu-0.3.1.1
-
-
----------------------------------------------------------------------------------------------------
-
-
-0.3.1.0
--------
-
-- **Date**    2016-05-02
-- **Git tag** [dejafu-0.3.1.0][]
-- **Hackage** https://hackage.haskell.org/package/dejafu-0.3.1.0
-
-### Fixed
-
-- Context switches around relaxed memory commit actions could cause the number of pre-emptions in an
-  execution to be miscounted, leading to the pre-emption bounding being too lenient.
-
-[dejafu-0.3.1.0]: https://github.com/barrucadu/dejafu/releases/tag/dejafu-0.3.1.0
-
-
----------------------------------------------------------------------------------------------------
-
-
-0.3.0.0
--------
-
-- **Date**    2016-04-03
-- **Git tag** [dejafu-0.3.0.0][]
-- **Hackage** https://hackage.haskell.org/package/dejafu-0.3.0.0
-
-**The minimum supported version of GHC is now 7.10.**
-
-I didn't write proper release notes, and this is so far back I don't really care to dig through the
-logs.
-
-[dejafu-0.3.0.0]: https://github.com/barrucadu/dejafu/releases/tag/dejafu-0.3.0.0
-
-
----------------------------------------------------------------------------------------------------
-
-
-0.2.0.0
--------
-
-- **Date**    2015-12-01
-- **Git tag** [0.2.0.0][]
-- **Hackage** https://hackage.haskell.org/package/dejafu-0.2.0.0
-
-I didn't write proper release notes, and this is so far back I don't really care to dig through the
-logs.
-
-[0.2.0.0]: https://github.com/barrucadu/dejafu/releases/tag/0.2.0.0
-
-
----------------------------------------------------------------------------------------------------
-
-
-0.1.0.0
--------
-
-- **Date**    2015-08-27
-- **Git tag** [0.1.0.0][]
-- **Hackage** https://hackage.haskell.org/package/dejafu-0.1.0.0
-
-Initial release. Go read the API docs.
-
-[0.1.0.0]: https://github.com/barrucadu/dejafu/releases/tag/0.1.0.0
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.rst
@@ -0,0 +1,925 @@
+Release Notes
+=============
+
+This project is versioned according to the PVP_, the *de facto*
+standard Haskell versioning scheme.
+
+.. _PVP: https://pvp.haskell.org/
+
+
+1.0.0.2 (2017-02-18)
+--------------------
+
+* Git: :tag:`dejafu-1.0.0.2`
+* Hackage: :hackage:`dejafu-1.0.0.2`
+
+**Contributors:** :u:`qrilka` (:pull:`214`).
+
+Changed
+~~~~~~~
+
+* (:issue:`193`) Deterministically assign commit thread IDs.
+
+Fixed
+~~~~~
+
+* (:issue:`189`) Remove an incorrect optimisation in systematic
+  testing for ``getNumCapabilities`` and ``setNumCapabilities``.
+
+* (:issue:`204`) Fix missed interleavings in systematic testing with
+  some uses of STM.
+
+* (:issue:`205`) Fix ``forkOS`` being recorded in an execution trace
+  as if it were a ``fork``.
+
+Miscellaneous
+~~~~~~~~~~~~~
+
+* (:pull:`180`) Doctest Haddock examples in ``Test.DejaFu`` and
+  ``Test.DejaFu.Refinement``.
+
+* (:pull:`185`, :pull:`215`) Check some more internal invariants and
+  throw on error.
+
+* (:pull:`214`) Remove unnecessary use of ``head``.
+
+
+1.0.0.1 (2018-01-19)
+--------------------
+
+* Git: :tag:`dejafu-1.0.0.1`
+* Hackage: :hackage:`dejafu-1.0.0.1`
+
+Miscellaneous
+~~~~~~~~~~~~~
+
+* The upper bound on :hackage:`concurrency` is <1.5.
+
+
+1.0.0.0 - The API Friendliness Release (2017-12-23)
+---------------------------------------------------
+
+* Git: :tag:`dejafu-1.0.0.0`
+* Hackage: :hackage:`dejafu-1.0.0.0`
+
+Added
+~~~~~
+
+* ``Test.DejaFu.alwaysSameOn`` and ``alwaysSameBy`` predicate helpers.
+
+* ``Test.DejaFu.SCT.strengthenDiscard`` and ``weakenDiscard``
+  functions to combine discard functions.
+
+* (:issue:`124`) The ``Test.DejaFu.ProPredicate`` type, which contains
+  both an old-style ``Predicate`` and a discard function.  It is also
+  a ``Profunctor``, parameterised by the input and output types.
+
+* (:issue:`124`) ``Test.DejaFu.alwaysNothing`` and
+  ``somewhereNothing`` predicate helpers, like ``alwaysTrue`` and
+  ``somewhereTrue``, to lift regular functions into a
+  ``ProPredicate``.
+
+* (:issue:`137`) The ``Test.DejaFu.Types.Id`` type.
+
+* (:pull:`145`) Thread action and lookahead values for bound threads:
+
+    * ``Test.DejaFu.Types.ForkOS``
+    * ``Test.DejaFu.Types.IsCurrentThreadBound``
+    * ``Test.DejaFu.Types.WillForkOS``
+    * ``Test.DejaFu.Types.WillIsCurrentThreadBound``
+
+* (:issue:`155`) ``Test.DejaFu.Types`` and ``Test.DejaFu.Utils``
+  modules, each containing some of what was in ``Test.DejaFu.Common``.
+
+Changed
+~~~~~~~
+
+* All testing functions require ``MonadConc``, ``MonadRef``, and
+  ``MonadIO`` constraints.  Testing with ``ST`` is no longer possible.
+
+* The ``Test.DejaFu.alwaysSame`` predicate helper gives the simplest
+  trace leading to each distinct result.
+
+* The ``MonadIO Test.DejaFu.Conc.ConcIO`` instance is now the more
+  general ``MonadIO n => MonadIO (ConcT r n)``.
+
+* (:issue:`121`) The chosen thread is no longer redundantly included
+  in trace lookahead.
+
+* (:issue:`123`) All testing functions in ``Test.DejaFu`` take the
+  action to run as the final parameter.
+
+* (:issue:`124`) All testing functions in ``Test.DejaFu`` have been
+  generalised to take a ``ProPredicate`` instead of a ``Predicate``.
+
+* (:issue:`124`) The ``Test.DejaFu.Predicate`` type is an alias for
+  ``ProPredicate a a``.
+
+* (:issue:`124`) The ``Test.DejaFu.Result`` type no longer includes a
+  number of cases checked.
+
+* (:issue:`137`) The ``Test.DejaFu.Types.ThreadId``, ``CRefId``,
+  ``MVarId``, and ``TVarId`` types are now wrappers for an ``Id``.
+
+* (:pull:`145`) If built with the threaded runtime, the main thread in
+  a test is executed as a bound thread.
+
+* (:issue:`155`) The ``Test.DejaFu.SCT.Discard`` type is defined in
+  ``Test.DejaFu.Types``, and re-exported from ``Test.DejaFu.SCT``.
+
+* (:issue:`155`) The ``Test.DejaFu.Schedule.tidOf`` and ``decisionOf``
+  functions are defined in ``Test.DejaFu.Utils``, but not re-exported
+  from ``Test.DejaFu.Schedule``.
+
+Removed
+~~~~~~~
+
+* The ``IO`` specific testing functions:
+
+    * ``Test.DejaFu.autocheckIO``
+    * ``Test.DejaFu.dejafuIO``
+    * ``Test.DejaFu.dejafusIO``
+    * ``Test.DejaFu.autocheckWayIO``
+    * ``Test.DejaFu.dejafuWayIO``
+    * ``Test.DejaFu.dejafusWayIO``
+    * ``Test.DejaFu.dejafuDiscardIO``
+    * ``Test.DejaFu.runTestM``
+    * ``Test.DejaFu.runTestWayM``
+
+* The ``Test.DejaFu.Conc.ConcST`` type alias.
+
+* The ``MonadBaseControl IO Test.DejaFu.Conc.ConcIO`` typeclass instance.
+
+* The ``Test.DejaFu.alwaysTrue2`` function, which had confusing
+  behaviour.
+
+* The ``Test.DejaFu.Common.TTrace`` type synonym for ``[TAction]``.
+
+* The ``Test.DejaFu.Common.preEmpCount`` function.
+
+* Re-exports of ``Decision`` and ``NonEmpty`` from
+  ``Test.DejaFu.Schedule``.
+
+* (:issue:`155`) The ``Test.DejaFu.Common`` and ``Test.DejaFu.STM``
+  modules.
+
+Fixed
+~~~~~
+
+* In refinement property testing, a blocking interference function is
+  not reported as a deadlocking execution.
+
+Performance
+~~~~~~~~~~~
+
+* (:issue:`124`) Passing tests should use substantially less memory.
+
+* (:issue:`168`) Prune some unnecessary interleavings of ``MVar``
+  actions in systematic testing.
+
+Miscellaneous
+~~~~~~~~~~~~~
+
+* The lower bound on :hackage:`concurrency` is >=1.3.
+
+
+0.9.1.2 (2017-12-12)
+--------------------
+
+* Git: :tag:`dejafu-0.9.1.2`
+* Hackage: :hackage:`dejafu-0.9.1.2`
+
+Miscellaneous
+~~~~~~~~~~~~~
+
+* The upper bound on :hackage:`leancheck` is <0.8.
+
+
+0.9.1.1 (2017-12-08)
+--------------------
+
+* Git: :tag:`dejafu-0.9.1.1`
+* Hackage: :hackage:`dejafu-0.9.1.1`
+
+Fixed
+~~~~~
+
+* (:issue:`160`) Fix an off-by-one issue with nested masks during
+  systematic testing.
+
+
+0.9.1.0 (2017-11-26)
+--------------------
+
+* Git: :tag:`dejafu-0.9.1.0`
+* Hackage: :hackage:`dejafu-0.9.1.0`
+
+Added
+~~~~~
+
+* ``MonadFail`` instance for ``Test.DejaFu.Conc.ConcT``.
+* ``MonadFail`` instance for ``Test.DejaFu.STM.STMLike``.
+
+Changed
+~~~~~~~
+
+* Pretty-printed traces display a pre-emption following a yield with a
+  little "p".
+
+Fixed
+~~~~~
+
+* Some incorrect Haddock ``@since`` comments.
+
+
+0.9.0.3 (2017-11-06)
+--------------------
+
+* Git: :tag:`dejafu-0.9.0.3`
+* Hackage: :hackage:`dejafu-0.9.0.3`
+
+Fixed
+~~~~~
+
+* (:issue:`138`) Fix missed interleavings in systematic testing with
+  some relaxed memory programs.
+
+
+0.9.0.2 (2017-11-02)
+--------------------
+
+* Git: :tag:`dejafu-0.9.0.2`
+* Hackage: :hackage:`dejafu-0.9.0.2`
+
+Changed
+~~~~~~~
+
+* A fair bound of 0 prevents yielding or delaying.
+
+Performance
+~~~~~~~~~~~
+
+* Prune some unnecessary interleavings of STM transactions in
+  systematic testing.
+
+
+0.9.0.1 (2017-10-28)
+--------------------
+
+* Git: :tag:`dejafu-0.9.0.1`
+* Hackage: :hackage:`dejafu-0.9.0.1`
+
+Fixed
+~~~~~
+
+* (:issue:`139`) Fix double pop of exception handler stack.
+
+
+0.9.0.0 (2017-10-11)
+--------------------
+
+* Git: :tag:`dejafu-0.9.0.0`
+* Hackage: :hackage:`dejafu-0.9.0.0`
+
+Added
+~~~~~
+
+* Failure predicates (also exported from ``Test.DejaFu``):
+
+    * ``Test.DejaFu.Common.isAbort``
+    * ``Test.DejaFu.Common.isDeadlock``
+    * ``Test.DejaFu.Common.isIllegalSubconcurrency``
+    * ``Test.DejaFu.Common.isInternalError``
+    * ``Test.DejaFu.Common.isUncaughtException``
+
+* Thread action and lookahead values for ``threadDelay``:
+
+    * ``Test.DejaFu.Common.ThreadDelay``
+    * ``Test.DejaFu.Common.WillThreadDelay``
+
+Changed
+~~~~~~~
+
+* The ``UncaughtException`` constructor for
+  ``Test.DejaFu.Common.Failure`` now includes the exception value.
+
+* Uses of ``threadDelay`` are no longer reported in the trace as a use
+  of ``yield``.
+
+Removed
+~~~~~~~
+
+* The ``Bounded``, ``Enum``, and ``Read`` instances for
+  ``Test.DejaFu.Common.Failure``.
+
+
+0.8.0.0 (2017-09-26)
+--------------------
+
+* Git: :tag:`dejafu-0.8.0.0`
+* Hackage: :hackage:`dejafu-0.8.0.0`
+
+Changed
+~~~~~~~
+
+* (:issue:`80`) STM traces now include the ID of a newly-created
+  ``TVar``.
+
+* (:issue:`106`) Schedulers are not given the execution trace so far.
+
+* (:issue:`120`) Traces only include a single action of lookahead.
+
+* (:issue:`122`) The ``Test.DejaFu.Scheduler.Scheduler`` type is now a
+  newtype, rather than a type synonym.
+
+
+0.7.3.0 (2017-09-26)
+--------------------
+
+* Git: :tag:`dejafu-0.7.3.0`
+* Hackage: :hackage:`dejafu-0.7.3.0`
+
+Added
+~~~~~
+
+* The ``Test.DejaFu.Common.threadNames`` function.
+
+Fixed
+~~~~~
+
+* (:issue:`101`) Named threads which are only started by a pre-emption
+  are shown in the pretty-printed trace key.
+
+* (:issue:`118`) Escaping a mask by raising an exception correctly
+  restores the masking state (#118).
+
+
+0.7.2.0 (2017-09-16)
+--------------------
+
+* Git: :tag:`dejafu-0.7.2.0`
+* Hackage: :hackage:`dejafu-0.7.2.0`
+
+Added
+~~~~~
+
+* ``Alternative`` and ``MonadPlus`` instances for
+  ``Test.DejaFu.STM.STM``.
+
+Fixed
+~~~~~
+
+* The ``Eq`` and ``Ord`` instances for
+  ``Test.DejaFu.Common.ThreadId``, ``CRefId``, ``MVarId``, and
+  ``TVarId`` are consistent.
+
+Miscellaneous
+~~~~~~~~~~~~~
+
+* The upper bound on :hackage:`concurrency` is <1.2.
+
+
+0.7.1.3 (2017-09-08)
+--------------------
+
+* Git: :tag:`dejafu-0.7.1.3`
+* Hackage: :hackage:`dejafu-0.7.1.3`
+
+Fixed
+~~~~~
+
+* (:issue:`111`) Aborted STM transactions are correctly rolled back.
+
+Performance
+~~~~~~~~~~~
+
+* (:issue:`105`) Use a more efficient approach for an internal
+  component of the systematic testing.
+
+
+0.7.1.2 (2017-08-21)
+--------------------
+
+* Git: :tag:`dejafu-0.7.1.2`
+* Hackage: :hackage:`dejafu-0.7.1.2`
+
+Fixed
+~~~~~
+
+* (:issue:`110`) Errors thrown with ``Control.Monad.fail`` are
+  correctly treated as asynchronous exceptions.
+
+
+0.7.1.1 (2017-08-16)
+--------------------
+
+* Git: :tag:`dejafu-0.7.1.1`
+* Hackage: :hackage:`dejafu-0.7.1.1`
+
+Performance
+~~~~~~~~~~~
+
+* (:issue:`64`) Greatly reduce memory usage in systematic testing when
+  discarding traces by using an alternative data structure.
+
+    * Old: ``O(max trace length * number of executions)``
+    * New: ``O(max trace length * number of traces kept)``
+
+
+0.7.1.0 - The Discard Release (2017-08-10)
+------------------------------------------
+
+* Git: :tag:`dejafu-0.7.1.0`
+* Hackage: :hackage:`dejafu-0.7.1.0`
+
+Added
+~~~~~
+
+* (:issue:`90`) A way to selectively discard results or traces:
+
+    * Type: ``Test.DejaFu.SCT.Discard``
+    * Functions: ``Test.DejaFu.SCT.runSCTDiscard``,
+      ``resultsSetDiscard``, ``sctBoundDiscard``,
+      ``sctUniformRandomDiscard``, and ``sctWeightedRandomDiscard``.
+
+* (:issue:`90`) Discarding variants of the testing functions:
+
+    * ``Test.DejaFu.dejafuDiscard``
+    * ``Test.DejaFu.dejafuDiscardIO``
+
+* (:issue:`90`) ``Test.DejaFu.Defaults.defaultDiscarder``.
+
+Performance
+~~~~~~~~~~~
+
+* (:issue:`90`) The ``Test.DejaFu.SCT.resultsSet`` and ``resultsSet'``
+  functions discard traces as they are produced, rather than all at
+  the end.
+
+
+0.7.0.2 (2017-06-12)
+--------------------
+
+* Git: :tag:`dejafu-0.7.0.2`
+* Hackage: :hackage:`dejafu-0.7.0.2`
+
+Changed
+~~~~~~~
+
+* Remove unnecessary typeclass constraints from
+  ``Test.DejaFu.Refinement.check``, ``check'``, ``checkFor``, and
+  ``counterExamples``.
+
+Miscellaneous
+~~~~~~~~~~~~~
+
+* Remove an unnecessary dependency on :hackage:`monad-loops`.
+
+
+0.7.0.1 (2017-06-09)
+--------------------
+
+* Git: :tag:`dejafu-0.7.0.1`
+* Hackage: :hackage:`dejafu-0.7.0.1`
+
+Performance
+~~~~~~~~~~~
+
+* The ``Test.DejaFu.Refinement.check``, ``check'``, and ``checkFor``
+  functions no longer need to compute all counterexamples before
+  showing only one.
+
+* The above and ``counterExamples`` are now faster even if there is
+  only a single counterexample in some cases.
+
+
+0.7.0.0 - The Refinement Release (2017-06-07)
+---------------------------------------------
+
+* Git: :tag:`dejafu-0.7.0.0`
+* Hackage: :hackage:`dejafu-0.7.0.0`
+
+Added
+~~~~~
+
+* The ``Test.DejaFu.Refinement`` module, re-exported from
+  ``Test.DejaFu``.
+
+* The ``Test.DejaFu.SCT.sctUniformRandom`` function for SCT via random
+  scheduling.
+
+* Smart constructors for ``Test.DejaFu.SCT.Way`` (also re-exported
+  from ``Test.DejaFu``):
+
+    * ``Test.DejaFu.SCT.systematically``, like the old
+      ``Systematically``.
+    * ``Test.DejaFu.SCT.randomly``, like the old ``Randomly``.
+    * ``Test.DejaFu.SCT.uniformly``, a new uniform (as opposed to
+      weighted) random scheduler.
+    * ``Test.DejaFu.SCT.swarmy``, like the old ``Randomly`` but which
+      can use the same weights for multiple executions.
+
+Changed
+~~~~~~~
+
+* The ``default*`` values are defined in ``Test.DejaFu.Defaults`` and
+  re-exported from ``Test.DejaFu``.
+
+* The ``Test.DejaFu.SCT.sctRandom`` function is now called
+  ``sctWeightedRandom`` and can re-use the same weights for multiple
+  executions.
+
+Removed
+~~~~~~~
+
+* The ``Test.DejaFu.SCT.Way`` type is now abstract, so its
+  constructors are no longer exported:
+
+    * ``Test.DejaFu.SCT.Systematically``
+    * ``Test.DejaFu.SCT.Randomly``
+
+* The ``Test.DejaFu.SCT.sctPreBound``, ``sctFairBound``, and
+  ``sctLengthBound`` functions.
+
+Fixed
+~~~~~
+
+* (:issue:`81`) ``Test.DejaFu.Conc.subconcurrency`` no longer re-uses
+  IDs.
+
+
+0.6.0.0 (2017-04-08)
+--------------------
+
+* Git: :tag:`dejafu-0.6.0.0`
+* Hackage: :hackage:`dejafu-0.6.0.0`
+
+Changed
+~~~~~~~
+
+* The ``Test.DejaFu.Conc.Conc n r a`` type is ``ConcT r n a``, and has
+  a ``MonadTrans`` instance.
+
+* The ``Test.DejaFu.SCT.Way`` type is a GADT, and does not expose the
+  type parameter of the random generator.
+
+Removed
+~~~~~~~
+
+* The ``NFData`` instance for ``Test.DejaFu.SCT.Way``.
+
+Miscellaneous
+~~~~~~~~~~~~~
+
+* ``Test.DejaFu.Common`` forms part of the public API.
+
+* Every definition, class, and instance now has a Haddock ``@since``
+  annotation.
+
+
+0.5.1.3 (2017-04-05)
+--------------------
+
+* Git: :tag:`dejafu-0.5.1.3`
+* Hackage: :hackage:`dejafu-0.5.1.3`
+
+Miscellaneous
+~~~~~~~~~~~~~
+
+* The version bounds on :hackage:`concurrency` are 1.1.*.
+
+
+0.5.1.2 (2017-03-04)
+--------------------
+
+* Git: :tag:`dejafu-0.5.1.2`
+* Hackage: :hackage:`dejafu-0.5.1.2`
+
+**Note:** this version was misnumbered! It should have caused a minor
+ version bump!
+
+Added
+~~~~~
+
+* ``MonadRef`` and ``MonadAtomicRef`` instances for
+  ``Test.DejaFu.Conc.Conc`` using ``CRef``.
+
+Fixed
+~~~~~
+
+* A long-standing bug where if the main thread is killed with a
+  ``throwTo``, the throwing neither appears in the trace nor correctly
+  terminates the execution.
+
+Miscellaneous
+~~~~~~~~~~~~~
+
+* The upper bound on :hackage:`concurrency` is <1.1.1.
+
+
+0.5.1.1 (2017-02-25)
+--------------------
+
+* Git: :tag:`dejafu-0.5.1.1`
+* Hackage: :hackage:`dejafu-0.5.1.1`
+
+Fixed
+~~~~~
+
+* Fix using incorrect correct scheduler state after a `subconcurrency`
+  action.
+
+* Fix infinite loop in SCT of subconcurrency.
+
+
+0.5.1.0 (2017-02-25)
+--------------------
+
+* Git: :tag:`dejafu-0.5.1.0`
+* Hackage: :hackage:`dejafu-0.5.1.0`
+
+Added
+~~~~~
+
+* ``NFData`` instances for:
+
+    * ``Test.DejaFu.Result``
+    * ``Test.DejaFu.Common.ThreadId``
+    * ``Test.DejaFu.Common.CRefId``
+    * ``Test.DejaFu.Common.MVarId``
+    * ``Test.DejaFu.Common.TVarId``
+    * ``Test.DejaFu.Common.IdSource``
+    * ``Test.DejaFu.Common.ThreadAction``
+    * ``Test.DejaFu.Common.Lookahead``
+    * ``Test.DejaFu.Common.ActionType``
+    * ``Test.DejaFu.Common.TAction``
+    * ``Test.DejaFu.Common.Decision``
+    * ``Test.DejaFu.Common.Failure``
+    * ``Test.DejaFu.Common.MemType``
+    * ``Test.DejaFu.SCT.Bounds``
+    * ``Test.DejaFu.SCT.PreemptionBound``
+    * ``Test.DejaFu.SCT.FairBound``
+    * ``Test.DejaFu.SCT.LengthBound``
+    * ``Test.DejaFu.SCT.Way``
+    * ``Test.DejaFu.STM.Result``
+
+* ``Eq``, ``Ord``, and ``Show`` instances for
+  ``Test.DejaFu.Common.IdSource``.
+
+* Strict variants of ``Test.DejaFu.SCT.runSCT`` and ``resultsSet``:
+  ``runSCT'`` and ``resultsSet'``.
+
+
+0.5.0.2 (2017-02-22)
+--------------------
+
+* Git: :tag:`dejafu-0.5.0.2`
+* Hackage: :hackage:`dejafu-0.5.0.2`
+
+**Note:** this version was misnumbered! It should have caused a major
+ version bump!
+
+Added
+~~~~~
+
+* ``StopSubconcurrency`` constructor for
+  ``Test.DejaFu.Common.ThreadAction``.
+
+Changed
+~~~~~~~
+
+* A ``Test.DejaFu.Common.StopConcurrency`` action appears in the
+  execution trace immediately after the end of a
+  ``Test.DejaFu.Conc.subconcurrency`` action.
+
+Fixed
+~~~~~
+
+* A ``Test.DejaFu.Conc.subconcurrency`` action inherits the number of
+  capabilities from the outer computation.
+
+Miscellaneous
+~~~~~~~~~~~~~
+
+- ``Test.DejaFu.SCT`` compiles with ``MonoLocalBinds`` enabled
+  (implied by ``GADTs`` and ``TypeFamilies``), which may be relevant
+  to hackers.
+
+
+0.5.0.1 (2017-02-21)
+--------------------
+
+* Git: :tag:`dejafu-0.5.0.1`
+* Hackage: :hackage:`ps!**`
+
+Fixed
+~~~~~
+
+* ``readMVar`` is considered a "release action" for the purposes of
+  fair-bounding.
+
+
+0.5.0.0 - The Way Release (2017-02-21)
+--------------------------------------
+
+* Git: :tag:`dejafu-0.5.0.0`
+* Hackage: :hackage:`dejafu-0.5.0.0`
+
+Added
+~~~~~
+
+* ``Eq`` instances for ``Test.DejaFu.Common.ThreadAction`` and
+  ``Lookahead``.
+
+* Thread action and lookahead values for ``tryReadMVar``:
+
+    * ``Test.DejaFu.Common.TryReadMVar``
+    * ``Test.DejaFu.Common.WillTryReadMVar``
+
+* The testing-only ``Test.DejaFu.Conc.subconcurrency`` function.
+
+* SCT through weighted random scheduling:
+  ``Test.DejaFu.SCT.sctRandom``.
+
+* The ``Test.DejaFu.SCT.Way`` type, used by the new functions
+  ``runSCT`` and ``resultsSet``.
+
+Changed
+~~~~~~~
+
+* All the functions which took a ``Test.DejaFu.SCT.Bounds`` now take a
+  ``Way`` instead.
+
+Fixed
+~~~~~
+
+* Some previously-missed ``CRef`` action dependencies are no longer
+  missed.
+
+Miscellaneous
+~~~~~~~~~~~~~
+
+* The version bounds on :hackage:`concurrency` are 1.1.0.*.
+
+* A bunch of things were called "Var" or "Ref", these are now
+  consistently "MVar" and "CRef".
+
+* Significant performance improvements in both time and space.
+
+* The :hackage:`dpor` package has been merged back into this, as it
+  turned out not to be very generally useful.
+
+
+0.4.0.0 - The Packaging Release (2016-09-10)
+--------------------------------------------
+
+* Git: :tag:`dejafu-0.4.0.0`
+* Hackage: :hackage:`dejafu-0.4.0.0`
+
+Added
+~~~~~
+
+* The ``Test.DejaFu.runTestM`` and ``runTestM'`` functions.
+
+* The ``Test.DejaFu.Conc.runConcurrent`` function.
+
+* The ``Test.DejaFu.STM.runTransaction`` function.
+
+* The ``Test.DejaFu.Common`` module.
+
+Changed
+~~~~~~~
+
+* The ``Control.*`` modules have all been split out into a separate
+  :hackage:`concurrency` package.
+
+* The ``Test.DejaFu.Deterministic`` module has been renamed to
+  ``Test.DejaFu.Conc``.
+
+* Many definitions from other modules have been moved to the
+  ``Test.DejaFu.Common`` module.
+
+* The ``Test.DejaFu.autocheck'`` function takes the schedule bounds as
+  a parameter.
+
+* The ``Test.DejaFu.Conc.Conc`` type no longer has the STM type as a
+  parameter.
+
+* The ``ST`` specific functions in ``Test.DejaFu.SCT`` are polymorphic
+  in the monad.
+
+* The termination of the main thread in execution traces appears as a
+  single ``Stop``, rather than the previous ``Lift, Stop``.
+
+* Execution traces printed by the helpful functions in ``Test.DejaFu``
+  include a key of thread names.
+
+Removed
+~~~~~~~
+
+* The ``Test.DejaFu.runTestIO`` and ``runTestIO'`` functions: use
+  ``runTestM`` and ``runTestM'`` instead.
+
+* The ``Test.DejaFu.Conc.runConcST`` and ``runConcIO`` functions: use
+  ``runConcurrent`` instead.
+
+* The ``Test.DejaFu.STM.runTransactionST`` and ``runTransactionIO``
+  functions: use ``runTransaction`` instead.
+
+* The ``IO`` specific functions in ``Test.DejaFu.SCT``.
+
+
+
+0.3.2.1 (2016-07-21)
+--------------------
+
+* Git: :tag:`dejafu-0.3.2.1`
+* Hackage: :hackage:`dejafu-0.3.2.1`
+
+Fixed
+~~~~~
+
+* (:issue:`55`) Fix incorrect detection of deadlocks with some nested
+  STM transactions.
+
+
+0.3.2.0 (2016-06-06)
+--------------------
+
+* Git: :tag:`dejafu-0.3.2.0`
+* Hackage: :hackage:`dejafu-0.3.2.0`
+
+Fixed
+~~~~~
+
+* (:issue:`40`) Fix missing executions with daemon threads with
+  uninteresting first actions.  This is significantly faster with
+  :hackage:`dpor-0.2.0.0`.
+
+Performance
+~~~~~~~~~~~
+
+* When using :hackage:`dpor-0.2.0.0`, greatly improve dependency
+  inference of exceptions during systematic testing.
+
+* Improve dependency inference of STM transactions during systematic
+  testing.
+
+
+0.3.1.1 (2016-05-26)
+--------------------
+
+* Git: :tag:`dejafu-0.3.1.1`
+* Hackage: :hackage:`dejafu-0.3.1.1`
+
+Miscellaneous
+~~~~~~~~~~~~~
+
+* Now supports GHC 8.
+
+
+0.3.1.0 (2016-05-02)
+--------------------
+
+* Git: :tag:`dejafu-0.3.1.0`
+* Hackage: :hackage:`dejafu-0.3.1.0`
+
+Fixed
+~~~~~
+
+* Fix inaccurate counting of pre-emptions in an execution trace when
+  relaxed memory commit actions are present.
+
+
+0.3.0.0 (2016-04-03)
+--------------------
+
+* Git: :tag:`dejafu-0.3.0.0`
+* Hackage: :hackage:`dejafu-0.3.0.0`
+
+**The minimum supported version of GHC is now 7.10.**
+
+I didn't write proper release notes, and this is so far back I don't
+really care to dig through the logs.
+
+
+0.2.0.0 (2015-12-01)
+--------------------
+
+* Git: :tag:`0.2.0.0`
+* Hackage: :hackage:`dejafu-0.2.0.0`
+
+I didn't write proper release notes, and this is so far back I don't
+really care to dig through the logs.
+
+
+0.1.0.0 - The Initial Release (2015-08-27)
+------------------------------------------
+
+* Git: :tag:`0.1.0.0`
+* Hackage: :hackage:`dejafu-0.1.0.0`
+
+Added
+~~~~~
+
+* Everything.
diff --git a/Test/DejaFu.hs b/Test/DejaFu.hs
--- a/Test/DejaFu.hs
+++ b/Test/DejaFu.hs
@@ -17,21 +17,24 @@
 __A first test:__ This is a simple concurrent program which forks two
 threads and each races to write to the same @MVar@:
 
-> example = do
->   var <- newEmptyMVar
->   fork (putMVar var "hello")
->   fork (putMVar var "world")
->   readMVar var
+>>> :{
+let example = do
+      var <- newEmptyMVar
+      fork (putMVar var "hello")
+      fork (putMVar var "world")
+      readMVar var
+:}
 
 We can test it with dejafu like so:
 
-> > autocheck example
-> [pass] Never Deadlocks
-> [pass] No Exceptions
-> [fail] Consistent Result
->         "hello" S0----S1--S0--
->
->         "world" S0----S2--S0--
+>>> autocheck example
+[pass] Never Deadlocks
+[pass] No Exceptions
+[fail] Consistent Result
+    "hello" S0----S1--S0--
+<BLANKLINE>
+    "world" S0----S2--S0--
+False
 
 The 'autocheck' function takes a concurrent program to test and looks
 for some common unwanted behaviours: deadlocks, uncaught exceptions in
@@ -180,26 +183,29 @@
 to one of the @CRef@s and reads the other.  The value that each thread
 reads is communicated back through an @MVar@:
 
-> relaxed = do
->   r1 <- newCRef False
->   r2 <- newCRef False
->   x <- spawn $ writeCRef r1 True >> readCRef r2
->   y <- spawn $ writeCRef r2 True >> readCRef r1
->   (,) <$> readMVar x <*> readMVar y
+>>> :{
+let relaxed = do
+      r1 <- newCRef False
+      r2 <- newCRef False
+      x <- spawn $ writeCRef r1 True >> readCRef r2
+      y <- spawn $ writeCRef r2 True >> readCRef r1
+      (,) <$> readMVar x <*> readMVar y
+:}
 
 We see something surprising if we ask for the results:
 
-> > autocheck relaxed
-> [pass] Never Deadlocks
-> [pass] No Exceptions
-> [fail] Consistent Result
->         (False,True) S0---------S1----S0--S2----S0--
->
->         (False,False) S0---------S1--P2----S1--S0---
->
->         (True,False) S0---------S2----S1----S0---
->
->         (True,True) S0---------S1-C-S2----S1---S0---
+>>> autocheck relaxed
+[pass] Never Deadlocks
+[pass] No Exceptions
+[fail] Consistent Result
+    (False,True) S0---------S1----S0--S2----S0--
+<BLANKLINE>
+    (False,False) S0---------S1--P2----S1--S0---
+<BLANKLINE>
+    (True,False) S0---------S2----S1----S0---
+<BLANKLINE>
+    (True,True) S0---------S1-C-S2----S1---S0---
+False
 
 It's possible for both threads to read the value @False@, even though
 each writes @True@ to the other @CRef@ before reading.  This is
@@ -346,12 +352,15 @@
 
  * The expression to evaluate, as a function over the state.
 
-> sig e = Sig
->  { initialise = maybe newEmptyMVar newMVar
->  , observe    = \v _ -> tryReadMVar v
->  , interfere  = \v _ -> putMVar v 42
->  , expression = void . e
->  }
+>>> import Control.Monad (void)
+>>> :{
+let sig e = Sig
+      { initialise = maybe newEmptyMVar newMVar
+      , observe    = \v _ -> tryReadMVar v
+      , interfere  = \v _ -> putMVar v 42
+      , expression = void . e
+      }
+:}
 
 This is a signature for operations over @Num n => MVar n@ values where
 there are multiple producers.  The initialisation function takes a
@@ -362,10 +371,11 @@
 Given this signature, we can check if @readMVar@ is the same as a
 @takeMVar@ followed by a @putMVar@:
 
-> > check $ sig readMVar === sig (\v -> takeMVar v >>= putMVar v)
-> *** Failure: (seed Just 0)
->     left:  [(Nothing,Just 0)]
->     right: [(Nothing,Just 0),(Just Deadlock,Just 42)]
+>>> check $ sig readMVar === sig (\v -> takeMVar v >>= putMVar v)
+*** Failure: (seed Just 0)
+    left:  [(Nothing,Just 0)]
+    right: [(Nothing,Just 0),(Just Deadlock,Just 42)]
+False
 
 The two expressions are not equivalent, and we get a counterexample:
 if the @MVar@ is nonempty, then the left expression (@readMVar@) will
@@ -387,8 +397,10 @@
 import           Control.Monad.Ref        (MonadRef)
 import           Data.Function            (on)
 import           Data.List                (intercalate, intersperse)
-import           Data.Maybe               (catMaybes, isNothing, mapMaybe)
+import           Data.Maybe               (catMaybes, isJust, isNothing,
+                                           mapMaybe)
 import           Data.Profunctor          (Profunctor(..))
+import           System.Environment       (lookupEnv)
 
 import           Test.DejaFu.Conc
 import           Test.DejaFu.Defaults
@@ -397,7 +409,29 @@
 import           Test.DejaFu.Types
 import           Test.DejaFu.Utils
 
+{- $setup
 
+>>> import Control.Concurrent.Classy hiding (check)
+
+>>> :{
+let example = do
+      var <- newEmptyMVar
+      fork (putMVar var "hello")
+      fork (putMVar var "world")
+      readMVar var
+:}
+
+>>> :{
+let relaxed = do
+      r1 <- newCRef False
+      r2 <- newCRef False
+      x <- spawn $ writeCRef r1 True >> readCRef r2
+      y <- spawn $ writeCRef r2 True >> readCRef r1
+      (,) <$> readMVar x <*> readMVar y
+:}
+
+-}
+
 -------------------------------------------------------------------------------
 -- DejaFu
 
@@ -406,13 +440,14 @@
 -- In particular, look for deadlocks, uncaught exceptions, and
 -- multiple return values.  Returns @True@ if all tests pass
 --
--- > > autocheck example
--- > [pass] Never Deadlocks
--- > [pass] No Exceptions
--- > [fail] Consistent Result
--- >         "hello" S0----S1--S0--
--- >
--- >         "world" S0----S2--S0--
+-- >>> autocheck example
+-- [pass] Never Deadlocks
+-- [pass] No Exceptions
+-- [fail] Consistent Result
+--     "hello" S0----S1--S0--
+-- <BLANKLINE>
+--     "world" S0----S2--S0--
+-- False
 --
 -- @since 1.0.0.0
 autocheck :: (MonadConc n, MonadIO n, MonadRef r n, Eq a, Show a)
@@ -424,28 +459,30 @@
 -- | Variant of 'autocheck' which takes a way to run the program and a
 -- memory model.
 --
--- > > autocheckWay defaultWay defaultMemType relaxed
--- > [pass] Never Deadlocks
--- > [pass] No Exceptions
--- > [fail] Consistent Result
--- >         (False,True) S0---------S1----S0--S2----S0--
--- >
--- >         (False,False) S0---------S1--P2----S1--S0---
--- >
--- >         (True,False) S0---------S2----S1----S0---
--- >
--- >         (True,True) S0---------S1-C-S2----S1---S0---
--- >
--- > > autocheckWay defaultWay SequentialConsistency relaxed
--- > [pass] Never Deadlocks
--- > [pass] No Exceptions
--- > [fail] Consistent Result
--- >         (False,True) S0---------S1----S0--S2----S0--
--- >
--- >         (True,True) S0---------S1-P2----S1---S0---
--- >
--- >         (True,False) S0---------S2----S1----S0---
+-- >>> autocheckWay defaultWay defaultMemType relaxed
+-- [pass] Never Deadlocks
+-- [pass] No Exceptions
+-- [fail] Consistent Result
+--     (False,True) S0---------S1----S0--S2----S0--
+-- <BLANKLINE>
+--     (False,False) S0---------S1--P2----S1--S0---
+-- <BLANKLINE>
+--     (True,False) S0---------S2----S1----S0---
+-- <BLANKLINE>
+--     (True,True) S0---------S1-C-S2----S1---S0---
+-- False
 --
+-- >>> autocheckWay defaultWay SequentialConsistency relaxed
+-- [pass] Never Deadlocks
+-- [pass] No Exceptions
+-- [fail] Consistent Result
+--     (False,True) S0---------S1----S0--S2----S0--
+-- <BLANKLINE>
+--     (True,True) S0---------S1-P2----S1---S0---
+-- <BLANKLINE>
+--     (True,False) S0---------S2----S1----S0---
+-- False
+--
 -- @since 1.0.0.0
 autocheckWay :: (MonadConc n, MonadIO n, MonadRef r n, Eq a, Show a)
   => Way
@@ -472,11 +509,12 @@
 -- predicate to determine if the test passes.  Predicates can look for
 -- anything, including checking for some expected nondeterminism.
 --
--- > > dejafu "Test Name" alwaysSame example
--- > [fail] Test Name
--- >         "hello" S0----S1--S0--
--- >
--- >         "world" S0----S2--S0--
+-- >>> dejafu "Test Name" alwaysSame example
+-- [fail] Test Name
+--     "hello" S0----S1--S0--
+-- <BLANKLINE>
+--     "world" S0----S2--S0--
+-- False
 --
 -- @since 1.0.0.0
 dejafu :: (MonadConc n, MonadIO n, MonadRef r n, Show b)
@@ -492,20 +530,22 @@
 -- | Variant of 'dejafu' which takes a way to run the program and a
 -- memory model.
 --
--- > > import System.Random
--- >
--- > > dejafuWay (randomly (mkStdGen 0) 100) defaultMemType "Randomly!" alwaysSame example
--- > [fail] Randomly!
--- >         "hello" S0----S1--S0--
--- >
--- >         "world" S0----S2--S0--
--- >
--- > > dejafuWay (randomly (mkStdGen 1) 100) defaultMemType "Randomly!" alwaysSame example
--- > [fail] Randomly!
--- >         "hello" S0----S1--S0--
--- >
--- >         "world" S0----S2--S1-S0--
+-- >>> import System.Random
 --
+-- >>> dejafuWay (randomly (mkStdGen 0) 100) defaultMemType "Randomly!" alwaysSame example
+-- [fail] Randomly!
+--     "hello" S0----S1--S0--
+-- <BLANKLINE>
+--     "world" S0----S2--S0--
+-- False
+--
+-- >>> dejafuWay (randomly (mkStdGen 1) 100) defaultMemType "Randomly!" alwaysSame example
+-- [fail] Randomly!
+--     "hello" S0----S1--S0--
+-- <BLANKLINE>
+--     "world" S0----S2--S1-S0--
+-- False
+--
 -- @since 1.0.0.0
 dejafuWay :: (MonadConc n, MonadIO n, MonadRef r n, Show b)
   => Way
@@ -523,11 +563,12 @@
 
 -- | Variant of 'dejafuWay' which can selectively discard results.
 --
--- > > dejafuDiscard (\_ -> Just DiscardTrace) defaultWay defaultMemType "Discarding" alwaysSame example
--- > [fail] Discarding
--- >         "hello" <trace discarded>
--- >
--- >         "world" <trace discarded>
+-- >>> dejafuDiscard (\_ -> Just DiscardTrace) defaultWay defaultMemType "Discarding" alwaysSame example
+-- [fail] Discarding
+--     "hello" <trace discarded>
+-- <BLANKLINE>
+--     "world" <trace discarded>
+-- False
 --
 -- @since 1.0.0.0
 dejafuDiscard :: (MonadConc n, MonadIO n, MonadRef r n, Show b)
@@ -552,12 +593,13 @@
 -- | Variant of 'dejafu' which takes a collection of predicates to
 -- test, returning 'True' if all pass.
 --
--- > > dejafus [("A", alwaysSame), ("B", deadlocksNever)] example
--- > [fail] A
--- >         "hello" S0----S1--S0--
--- >
--- >         "world" S0----S2--S0--
--- > [pass] B
+-- >>> dejafus [("A", alwaysSame), ("B", deadlocksNever)] example
+-- [fail] A
+--     "hello" S0----S1--S0--
+-- <BLANKLINE>
+--     "world" S0----S2--S0--
+-- [pass] B
+-- False
 --
 -- @since 1.0.0.0
 dejafus :: (MonadConc n, MonadIO n, MonadRef r n, Show b)
@@ -571,14 +613,15 @@
 -- | Variant of 'dejafus' which takes a way to run the program and a
 -- memory model.
 --
--- > > dejafusWay defaultWay SequentialConsistency [("A", alwaysSame), ("B", exceptionsNever)] relaxed
--- > [fail] A
--- >         (False,True) S0---------S1----S0--S2----S0--
--- >
--- >         (True,True) S0---------S1-P2----S1---S0---
--- >
--- >         (True,False) S0---------S2----S1----S0---
--- > [pass] B
+-- >>> dejafusWay defaultWay SequentialConsistency [("A", alwaysSame), ("B", exceptionsNever)] relaxed
+-- [fail] A
+--     (False,True) S0---------S1----S0--S2----S0--
+-- <BLANKLINE>
+--     (True,True) S0---------S1-P2----S1---S0---
+-- <BLANKLINE>
+--     (True,False) S0---------S2----S1----S0---
+-- [pass] B
+-- False
 --
 -- @since 1.0.0.0
 dejafusWay :: (MonadConc n, MonadIO n, MonadRef r n, Show b)
@@ -912,25 +955,30 @@
 -- | Run a test and print to stdout
 doTest :: Show a => String -> Result a -> IO Bool
 doTest name result = do
-  if _pass result
-  then
-    -- Display a pass message.
-    putStrLn ("\27[32m[pass]\27[0m " ++ name)
-  else do
-    -- Display a failure message, and the first 5 (simplified) failed traces
-    putStrLn ("\27[31m[fail]\27[0m " ++ name)
+    doctest <- isJust <$> lookupEnv "DEJAFU_DOCTEST"
+    if _pass result
+    then putStrLn (passmsg doctest)
+    else do
+      -- Display a failure message, and the first 5 (simplified) failed traces
+      putStrLn (failmsg doctest)
 
-    unless (null $ _failureMsg result) $
-      putStrLn $ _failureMsg result
+      unless (null $ _failureMsg result) $
+        putStrLn $ _failureMsg result
 
-    let failures = _failures result
-    let output = map (\(r, t) -> putStrLn . indent $ either showFail show r ++ " " ++ showTrace t) $ take 5 failures
-    sequence_ $ intersperse (putStrLn "") output
-    when (moreThan 5 failures) $
-      putStrLn (indent "...")
+      let failures = _failures result
+      let output = map (\(r, t) -> putStrLn . indent $ either showFail show r ++ " " ++ showTrace t) $ take 5 failures
+      sequence_ $ intersperse (putStrLn "") output
+      when (moreThan 5 failures) $
+        putStrLn (indent "...")
 
-  pure (_pass result)
+    pure (_pass result)
+  where
+    passmsg True = "[pass] " ++ name
+    passmsg False = "\27[32m[pass]\27[0m " ++ name
 
+    failmsg True = "[fail] " ++ name
+    failmsg False = "\27[31m[fail]\27[0m " ++ name
+
 -- | Check if a list is longer than some value, without needing to
 -- compute the entire length.
 moreThan :: Int -> [a] -> Bool
@@ -940,4 +988,4 @@
 
 -- | Indent every line of a string.
 indent :: String -> String
-indent = intercalate "\n" . map ('\t':) . lines
+indent = intercalate "\n" . map ("    "++) . lines
diff --git a/Test/DejaFu/Conc/Internal.hs b/Test/DejaFu/Conc/Internal.hs
--- a/Test/DejaFu/Conc/Internal.hs
+++ b/Test/DejaFu/Conc/Internal.hs
@@ -191,11 +191,11 @@
       let (idSource', newtid) = nextTId n (cIdSource ctx)
       let threads' = launch tid newtid a (cThreads ctx)
       threads'' <- makeBound newtid threads'
-      pure (Right ctx { cThreads = goto (b newtid) tid threads'', cIdSource = idSource' }, Single (Fork newtid))
+      pure (Right ctx { cThreads = goto (b newtid) tid threads'', cIdSource = idSource' }, Single (ForkOS newtid))
 
     -- check if the current thread is bound
     AIsBound c ->
-      let isBound = isJust (_bound =<< M.lookup tid (cThreads ctx))
+      let isBound = isJust . _bound $ elookup "stepThread.AIsBound" tid (cThreads ctx)
       in simple (goto (c isBound) tid (cThreads ctx)) (IsCurrentThreadBound isBound)
 
     -- get the 'ThreadId' of the current thread
@@ -370,7 +370,7 @@
     -- a function to run a computation with the current masking state.
     AMasking m ma c ->
       let a = runCont (ma umask) (AResetMask False False m' . c)
-          m' = _masking . efromJust "stepThread.AMasking" $ M.lookup tid (cThreads ctx)
+          m' = _masking $ elookup "stepThread.AMasking" tid (cThreads ctx)
           umask mb = resetMask True m' >> mb >>= \b -> resetMask False m >> pure b
           resetMask typ ms = cont $ \k -> AResetMask typ True ms $ k ()
           threads' = goto a tid (mask m tid (cThreads ctx))
diff --git a/Test/DejaFu/Conc/Internal/Memory.hs b/Test/DejaFu/Conc/Internal/Memory.hs
--- a/Test/DejaFu/Conc/Internal/Memory.hs
+++ b/Test/DejaFu/Conc/Internal/Memory.hs
@@ -129,12 +129,15 @@
 -- | Add phantom threads to the thread list to commit pending writes.
 addCommitThreads :: WriteBuffer r -> Threads n r -> Threads n r
 addCommitThreads (WriteBuffer wb) ts = ts <> M.fromList phantoms where
-  phantoms = [ (ThreadId (Id Nothing $ negate tid), mkthread c)
-             | ((_, b), tid) <- zip (M.toList wb) [1..]
+  phantoms = [ (ThreadId (Id Nothing . negate $ commitTidOf k), mkthread c)
+             | (k, b) <- M.toList wb
              , c <- maybeToList (go $ viewl b)
              ]
   go (BufferedWrite tid (CRef crid _) _ :< _) = Just $ ACommit tid crid
   go EmptyL = Nothing
+
+  commitTidOf (ThreadId (Id _ t), Nothing) = t + 1
+  commitTidOf (ThreadId (Id _ t), Just (CRefId (Id _ c))) = t + 1 + c * 10000
 
 -- | Remove phantom threads.
 delCommitThreads :: Threads n r -> Threads n r
diff --git a/Test/DejaFu/Conc/Internal/Threading.hs b/Test/DejaFu/Conc/Internal/Threading.hs
--- a/Test/DejaFu/Conc/Internal/Threading.hs
+++ b/Test/DejaFu/Conc/Internal/Threading.hs
@@ -16,16 +16,16 @@
 import qualified Control.Concurrent.Classy        as C
 import           Control.Exception                (Exception, MaskingState(..),
                                                    SomeException, fromException)
+import           Control.Monad                    (forever)
 import           Data.List                        (intersect)
 import           Data.Map.Strict                  (Map)
+import qualified Data.Map.Strict                  as M
 import           Data.Maybe                       (isJust)
 
 import           Test.DejaFu.Conc.Internal.Common
 import           Test.DejaFu.Internal
 import           Test.DejaFu.Types
 
-import qualified Data.Map.Strict                  as M
-
 --------------------------------------------------------------------------------
 -- * Threads
 
@@ -85,32 +85,33 @@
 -- | Propagate an exception upwards, finding the closest handler
 -- which can deal with it.
 propagate :: SomeException -> ThreadId -> Threads n r -> Maybe (Threads n r)
-propagate e tid threads = case M.lookup tid threads >>= go . _handlers of
-  Just (act, hs) -> Just $ except act hs tid threads
-  Nothing -> Nothing
+propagate e tid threads = raise <$> propagate' handlers where
+  handlers = _handlers (elookup "propagate" tid threads)
 
-  where
-    go [] = Nothing
-    go (Handler h:hs) = maybe (go hs) (\act -> Just (act, hs)) $ h <$> fromException e
+  raise (act, hs) = except act hs tid threads
 
+  propagate' [] = Nothing
+  propagate' (Handler h:hs) = maybe (propagate' hs) (\act -> Just (act, hs)) $ h <$> fromException e
+
 -- | Check if a thread can be interrupted by an exception.
 interruptible :: Thread n r -> Bool
 interruptible thread = _masking thread == Unmasked || (_masking thread == MaskedInterruptible && isJust (_blocking thread))
 
 -- | Register a new exception handler.
 catching :: Exception e => (e -> Action n r) -> ThreadId -> Threads n r -> Threads n r
-catching h = M.adjust $ \thread ->
+catching h = eadjust "catching" $ \thread ->
   let ms0 = _masking thread
       h'  = Handler $ \e ms -> (if ms /= ms0 then AResetMask False False ms0 else id) (h e)
   in thread { _handlers = h' : _handlers thread }
 
 -- | Remove the most recent exception handler.
 uncatching :: ThreadId -> Threads n r -> Threads n r
-uncatching = M.adjust $ \thread -> thread { _handlers = etail "uncatching" (_handlers thread) }
+uncatching = eadjust "uncatching" $ \thread ->
+  thread { _handlers = etail "uncatching" (_handlers thread) }
 
 -- | Raise an exception in a thread.
 except :: (MaskingState -> Action n r) -> [Handler n r] -> ThreadId -> Threads n r -> Threads n r
-except actf hs = M.adjust $ \thread -> thread
+except actf hs = eadjust "except" $ \thread -> thread
   { _continuation = actf (_masking thread)
   , _handlers = hs
   , _blocking = Nothing
@@ -118,24 +119,24 @@
 
 -- | Set the masking state of a thread.
 mask :: MaskingState -> ThreadId -> Threads n r -> Threads n r
-mask ms = M.adjust $ \thread -> thread { _masking = ms }
+mask ms = eadjust "mask" $ \thread -> thread { _masking = ms }
 
 --------------------------------------------------------------------------------
 -- * Manipulating threads
 
 -- | Replace the @Action@ of a thread.
 goto :: Action n r -> ThreadId -> Threads n r -> Threads n r
-goto a = M.adjust $ \thread -> thread { _continuation = a }
+goto a = eadjust "goto" $ \thread -> thread { _continuation = a }
 
 -- | Start a thread with the given ID, inheriting the masking state
 -- from the parent thread. This ID must not already be in use!
 launch :: ThreadId -> ThreadId -> ((forall b. M n r b -> M n r b) -> Action n r) -> Threads n r -> Threads n r
 launch parent tid a threads = launch' ms tid a threads where
-  ms = maybe Unmasked _masking (M.lookup parent threads)
+  ms = _masking (elookup "launch" parent threads)
 
 -- | Start a thread with the given ID and masking state. This must not already be in use!
 launch' :: MaskingState -> ThreadId -> ((forall b. M n r b -> M n r b) -> Action n r) -> Threads n r -> Threads n r
-launch' ms tid a = M.insert tid thread where
+launch' ms tid a = einsert "launch'" tid thread where
   thread = Thread (a umask) Nothing [] ms Nothing
 
   umask mb = resetMask True Unmasked >> mb >>= \b -> resetMask False ms >> pure b
@@ -143,7 +144,7 @@
 
 -- | Block a thread.
 block :: BlockedOn -> ThreadId -> Threads n r -> Threads n r
-block blockedOn = M.adjust $ \thread -> thread { _blocking = Just blockedOn }
+block blockedOn = eadjust "block" $ \thread -> thread { _blocking = Just blockedOn }
 
 -- | Unblock all threads waiting on the appropriate block. For 'TVar'
 -- blocks, this will wake all threads waiting on at least one of the
@@ -168,26 +169,20 @@
     getboundIO <- C.newEmptyMVar
     btid <- C.forkOSN ("bound worker for '" ++ show tid ++ "'") (go runboundIO getboundIO)
     let bt = BoundThread runboundIO getboundIO btid
-    pure (M.adjust (\t -> t { _bound = Just bt }) tid threads)
+    pure (eadjust "makeBound" (\t -> t { _bound = Just bt }) tid threads)
   where
-    go runboundIO getboundIO =
-      let loop = do
-            na <- C.takeMVar runboundIO
-            C.putMVar getboundIO =<< na
-            loop
-      in loop
+    go runboundIO getboundIO = forever $ do
+      na <- C.takeMVar runboundIO
+      C.putMVar getboundIO =<< na
 
 -- | Kill a thread and remove it from the thread map.
 --
 -- If the thread is bound, the worker thread is cleaned up.
 kill :: C.MonadConc n => ThreadId -> Threads n r -> n (Threads n r)
-kill tid threads = case M.lookup tid threads of
-  Just thread -> case _bound thread of
-    Just bt -> do
-      C.killThread (_boundTId bt)
-      pure (M.delete tid threads)
-    Nothing -> pure (M.delete tid threads)
-  Nothing -> pure threads
+kill tid threads = do
+  let thread = elookup "kill" tid threads
+  maybe (pure ()) (C.killThread . _boundTId) (_bound thread)
+  pure (M.delete tid threads)
 
 -- | Run an action.
 --
diff --git a/Test/DejaFu/Internal.hs b/Test/DejaFu/Internal.hs
--- a/Test/DejaFu/Internal.hs
+++ b/Test/DejaFu/Internal.hs
@@ -14,6 +14,7 @@
 import           Control.DeepSeq    (NFData(..))
 import           Control.Monad.Ref  (MonadRef(..))
 import           Data.List.NonEmpty (NonEmpty(..))
+import qualified Data.Map.Strict    as M
 import           Data.Maybe         (fromMaybe)
 import           Data.Set           (Set)
 import qualified Data.Set           as S
@@ -290,12 +291,6 @@
 -------------------------------------------------------------------------------
 -- * Error reporting
 
--- | 'head' but with a better error message if it fails.  Use this
--- only where it shouldn't fail!
-ehead :: String -> [a] -> a
-ehead _ (x:_) = x
-ehead src _ = fatal src "head: empty list"
-
 -- | 'tail' but with a better error message if it fails.  Use this
 -- only where it shouldn't fail!
 etail :: String -> [a] -> [a]
@@ -320,6 +315,27 @@
 efromList :: String -> [a] -> NonEmpty a
 efromList _ (x:xs) = x:|xs
 efromList src _ = fatal src "fromList: empty list"
+
+-- | 'M.adjust' but which errors if the key is not present.  Use this
+-- only where it shouldn't fail!
+eadjust :: (Ord k, Show k) => String -> (v -> v) -> k -> M.Map k v -> M.Map k v
+eadjust src f k m = case M.lookup k m of
+  Just v -> M.insert k (f v) m
+  Nothing -> fatal src ("adjust: key '" ++ show k ++ "' not found")
+
+-- | 'M.insert' but which errors if the key is already present.  Use
+-- this only where it shouldn't fail!
+einsert :: (Ord k, Show k) => String -> k -> v -> M.Map k v -> M.Map k v
+einsert src k v m
+  | M.member k m = fatal src ("insert: key '" ++ show k ++ "' already present")
+  | otherwise = M.insert k v m
+
+-- | 'M.lookup' but which errors if the key is not present.  Use this
+-- only where it shouldn't fail!
+elookup :: (Ord k, Show k) => String -> k -> M.Map k v -> v
+elookup src k =
+  fromMaybe (fatal src ("lookup: key '" ++ show k ++ "' not found")) .
+  M.lookup k
 
 -- | 'error' but saying where it came from
 fatal :: String -> String -> a
diff --git a/Test/DejaFu/Refinement.hs b/Test/DejaFu/Refinement.hs
--- a/Test/DejaFu/Refinement.hs
+++ b/Test/DejaFu/Refinement.hs
@@ -22,19 +22,21 @@
 --
 -- This module can test properties like that:
 --
--- @
--- sig e = Sig
---   { initialise = maybe newEmptyMVar newMVar
---   , observe    = \\v _ -> tryReadMVar v
---   , interfere  = \\v s -> tryTakeMVar v >> maybe (pure ()) (void . tryPutMVar v) s
---   , expression = e
---   }
+-- >>> import Control.Monad (void)
+-- >>> :{
+-- let sig e = Sig
+--       { initialise = maybe newEmptyMVar newMVar
+--       , observe    = \v _ -> tryReadMVar v
+--       , interfere  = \v _ -> putMVar v 42
+--       , expression = void . e
+--       }
+-- :}
 --
--- > check $ sig (void . readMVar) \`equivalentTo\` sig (\\v -> takeMVar v >>= putMVar v)
--- *** Failure: (seed Just ())
---     left:  [(Nothing,Just ())]
---     right: [(Nothing,Just ()),(Just Deadlock,Just ())]
--- @
+-- >>> check $ sig readMVar === sig (\v -> takeMVar v >>= putMVar v)
+-- *** Failure: (seed Just 0)
+--     left:  [(Nothing,Just 0)]
+--     right: [(Nothing,Just 0),(Just Deadlock,Just 42)]
+-- False
 --
 -- The two expressions are not equivalent, and we get given the
 -- counterexample!
@@ -115,6 +117,9 @@
 import           Test.DejaFu.Conc         (ConcIO, Failure, subconcurrency)
 import           Test.DejaFu.Defaults     (defaultMemType, defaultWay)
 import           Test.DejaFu.SCT          (runSCT)
+
+-- $setup
+-- >>> import Control.Concurrent.Classy hiding (check)
 
 -------------------------------------------------------------------------------
 -- Specifying properties
diff --git a/Test/DejaFu/SCT/Internal/DPOR.hs b/Test/DejaFu/SCT/Internal/DPOR.hs
--- a/Test/DejaFu/SCT/Internal/DPOR.hs
+++ b/Test/DejaFu/SCT/Internal/DPOR.hs
@@ -1,10 +1,12 @@
+{-# LANGUAGE ViewPatterns #-}
+
 -- |
 -- Module      : Test.DejaFu.SCT.Internal.DPOR
 -- Copyright   : (c) 2015--2017 Michael Walker
 -- License     : MIT
 -- Maintainer  : Michael Walker <mike@barrucadu.co.uk>
 -- Stability   : experimental
--- Portability : portable
+-- Portability : ViewPatterns
 --
 -- Internal types and functions for SCT via dynamic partial-order
 -- reduction.  This module is NOT considered to form part of the
@@ -20,7 +22,8 @@
 import           Data.List.NonEmpty   (toList)
 import           Data.Map.Strict      (Map)
 import qualified Data.Map.Strict      as M
-import           Data.Maybe           (isJust, isNothing, listToMaybe)
+import           Data.Maybe           (isJust, isNothing, listToMaybe,
+                                       maybeToList)
 import           Data.Sequence        (Seq, (|>))
 import qualified Data.Sequence        as Sq
 import           Data.Set             (Set)
@@ -67,6 +70,28 @@
                  , dporTaken    dpor
                  )
 
+-- | Check the DPOR data invariants and raise an error if any are
+-- broken.
+--
+-- This is a reasonable thing to do, because if the state is corrupted
+-- then nothing sensible can happen anyway.
+validateDPOR :: String -> DPOR -> DPOR
+validateDPOR src dpor
+    | not (todo `S.isSubsetOf` runnable) = fatal src "thread exists in todo set but not runnable set"
+    | not (done `S.isSubsetOf` runnable) = fatal src "thread exists in done set but not runnable set"
+    | not (taken `S.isSubsetOf` done) = fatal src "thread exists in taken set but not done set"
+    | not (todo `disjoint` done) = fatal src "thread exists in both taken set and done set"
+    | not (maybe True (`S.member` done) next) = fatal src "taken thread does not exist in done set"
+    | otherwise = dpor
+  where
+    done = dporDone dpor
+    next = fst <$> dporNext dpor
+    runnable = dporRunnable dpor
+    taken = S.fromList (M.keys (dporTaken dpor))
+    todo = S.fromList (M.keys (dporTodo dpor))
+
+    disjoint s1 s2 = S.null (S.intersection s1 s2)
+
 -- | One step of the execution, including information for backtracking
 -- purposes. This backtracking information is used to generate new
 -- schedules.
@@ -152,9 +177,10 @@
         state' = updateDepState state tid' a
     in case dporNext dpor of
          Just (t, child)
-           | t == tid'      -> dpor { dporNext = Just (tid', grow state' tid' rest child) }
+           | t == tid' ->
+             validateDPOR "incorporateTrace (grow / Just)" $ dpor { dporNext = Just (tid', grow state' tid' rest child) }
            | hasTodos child -> fatal "incorporateTrace" "replacing child with todos!"
-         _ ->
+         _ -> validateDPOR "incorporateTrace (grow / Nothing)" $
            let taken = M.insert tid' a (dporTaken dpor)
                sleep = dporSleep dpor `M.union` dporTaken dpor
            in dpor { dporTaken = if conservative then dporTaken dpor else taken
@@ -168,12 +194,12 @@
   hasTodos dpor = not (M.null (dporTodo dpor)) || (case dporNext dpor of Just (_, dpor') -> hasTodos dpor'; _ -> False)
 
   -- Construct a new subtree corresponding to a trace suffix.
-  subtree state tid sleep ((_, _, a):rest) =
+  subtree state tid sleep ((_, _, a):rest) = validateDPOR "incorporateTrace (subtree)" $
     let state' = updateDepState state tid a
         sleep' = M.filterWithKey (\t a' -> not $ dependent state' tid a t a') sleep
     in DPOR
         { dporRunnable = S.fromList $ case rest of
-            ((_, runnable, _):_) -> map fst runnable
+            ((d', runnable, _):_) -> tidOf tid d' : map fst runnable
             [] -> []
         , dporTodo = M.empty
         , dporNext = case rest of
@@ -245,24 +271,23 @@
   -- backtracking points.
   doBacktrack killsEarly allThreads enabledThreads bs =
     let tagged = reverse $ zip [0..] bs
-        idxs   = [ (ehead "doBacktrack.idxs" is, False, u)
+        idxs   = [ (i, False, u)
                  | (u, n) <- enabledThreads
                  , v <- S.toList allThreads
                  , u /= v
-                 , let is = idxs' u n v tagged
-                 , not $ null is]
+                 , i <- maybeToList (findIndex u n v tagged)]
 
-        idxs' u n v = go' True where
+        findIndex u n v = go' True where
           {-# INLINE go' #-}
           go' final ((i,b):rest)
             -- Don't cross subconcurrency boundaries
-            | isSubC final b = []
+            | isSubC final b = Nothing
             -- If this is the final action in the trace and the
             -- execution was killed due to nothing being within bounds
             -- (@killsEarly == True@) assume worst-case dependency.
-            | bcktThreadid b == v && (killsEarly || isDependent b) = i : go' False rest
+            | bcktThreadid b == v && (killsEarly || isDependent b) = Just i
             | otherwise = go' False rest
-          go' _ [] = []
+          go' _ [] = Nothing
 
           {-# INLINE isSubC #-}
           isSubC final b = case bcktAction b of
@@ -284,7 +309,7 @@
 -- | Add new backtracking points, if they have not already been
 -- visited and aren't in the sleep set.
 incorporateBacktrackSteps :: [BacktrackStep] -> DPOR -> DPOR
-incorporateBacktrackSteps (b:bs) dpor = dpor' where
+incorporateBacktrackSteps (b:bs) dpor = validateDPOR "incorporateBacktrackSteps" dpor' where
   tid = bcktThreadid b
 
   dpor' = dpor
@@ -529,6 +554,35 @@
 -------------------------------------------------------------------------------
 -- * Dependency function
 
+-- | Check if two actions commute.
+--
+-- This implements a stronger check that @not (dependent ...)@, as it
+-- handles some cases which 'dependent' doesn't need to care about.
+--
+-- This should not be used to re-order traces which contain
+-- subconcurrency.
+independent :: DepState -> ThreadId -> ThreadAction -> ThreadId -> ThreadAction -> Bool
+independent ds t1 a1 t2 a2
+    | t1 == t2 = False
+    | check t1 a1 t2 a2 = False
+    | check t2 a2 t1 a1 = False
+    | otherwise = not (dependent ds t1 a1 t2 a2)
+  where
+    -- can't re-order any action of a thread with the fork which
+    -- created it.
+    check _ (Fork t) tid _ | t == tid = True
+    check _ (ForkOS t) tid _ | t == tid = True
+    -- because we can't easily tell if this will terminate the other
+    -- thread, we just can't re-order asynchronous exceptions at all
+    -- :(
+    --
+    -- See #191 / #190
+    check _ (ThrowTo t) tid _ | t == tid = True
+    check _ (BlockedThrowTo t) tid _ | t == tid = True
+    -- can't re-order an unsynchronised write with something which synchronises that CRef.
+    check _ (simplifyAction -> UnsynchronisedWrite r) _ (simplifyAction -> a) | synchronises a r = True
+    check _ _ _ _ = False
+
 -- | Check if an action is dependent on another.
 --
 -- This is basically the same as 'dependent'', but can make use of the
@@ -536,13 +590,6 @@
 -- in a few cases.
 dependent :: DepState -> ThreadId -> ThreadAction -> ThreadId -> ThreadAction -> Bool
 dependent ds t1 a1 t2 a2 = case (a1, a2) of
-  -- @SetNumCapabilities@ and @GetNumCapabilities@ are NOT dependent
-  -- IF the value read is the same as the value written. 'dependent''
-  -- can not see the value read (as it hasn't happened yet!), and so
-  -- is more pessimistic here.
-  (SetNumCapabilities a, GetNumCapabilities b) | a == b -> False
-  (GetNumCapabilities a, SetNumCapabilities b) | a == b -> False
-
   -- When masked interruptible, a thread can only be interrupted when
   -- actually blocked. 'dependent'' has to assume that all
   -- potentially-blocking operations can block, and so is more
@@ -588,13 +635,13 @@
 
   -- Another worst-case: assume all STM is dependent.
   (STM _ _, WillSTM) -> True
+  (BlockedSTM _, WillSTM) -> True
 
   -- This is a bit pessimistic: Set/Get are only dependent if the
   -- value set is not the same as the value that will be got, but we
   -- can't know that here. 'dependent' optimises this case.
-  (GetNumCapabilities a, WillSetNumCapabilities b) -> a /= b
+  (GetNumCapabilities _, WillSetNumCapabilities _) -> True
   (SetNumCapabilities _, WillGetNumCapabilities)   -> True
-  (SetNumCapabilities a, WillSetNumCapabilities b) -> a /= b
 
   _ -> dependentActions ds (simplifyAction a1) (simplifyLookahead l2)
 
@@ -715,6 +762,7 @@
   Nothing -> masks
 updateMaskState tid (SetMasking   _ ms) = M.insert tid ms
 updateMaskState tid (ResetMasking _ ms) = M.insert tid ms
+updateMaskState tid Stop = M.delete tid
 updateMaskState _ _ = id
 
 -- | Check if a @CRef@ has a buffered write pending.
diff --git a/dejafu.cabal b/dejafu.cabal
--- a/dejafu.cabal
+++ b/dejafu.cabal
@@ -2,7 +2,7 @@
 -- documentation, see http://haskell.org/cabal/users-guide/
 
 name:                dejafu
-version:             1.0.0.1
+version:             1.0.0.2
 synopsis:            A library for unit-testing concurrent programs.
 
 description:
@@ -23,7 +23,7 @@
 copyright:           (c) 2015--2017 Michael Walker
 category:            Concurrency
 build-type:          Simple
-extra-source-files:  README.markdown CHANGELOG.markdown
+extra-source-files:  README.markdown CHANGELOG.rst
 cabal-version:       >=1.10
 
 source-repository head
@@ -33,7 +33,7 @@
 source-repository this
   type:     git
   location: https://github.com/barrucadu/dejafu.git
-  tag:      dejafu-1.0.0.1
+  tag:      dejafu-1.0.0.2
 
 library
   exposed-modules:     Test.DejaFu
