diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -8,7 +8,7 @@
 The more detailed your report, the faster it can be resolved and will ensure it
 is resolved in the right way. Once your bug has been resolved, the responsible
 person will tag the issue as _Needs confirmation_ and assign the issue back to
-you. Once you have tested and confirmed that the issue is resolved, close the 
+you. Once you have tested and confirmed that the issue is resolved, close the
 issue. If you are not a member of the project, you will be asked for
 confirmation and we will close it.
 
@@ -19,14 +19,12 @@
 the Wiki has been deprecated in favor of markdown files placed in a new `/doc`
 subdirectory of the repository itself. Please submit a
 [pull request](https://help.github.com/articles/using-pull-requests/) with your
-changes/additions.
+changes/additions based off the [the stable branch](https://github.com/commercialhaskell/stack/tree/stable).
 
 The documentation is rendered on [haskellstack.org](http://haskellstack.org) by
 readthedocs.org using Sphinx and CommonMark. Since links and formatting vary
 from GFM, please check the documentation there before submitting a PR to fix
-those.  In particular, links to other documentation files intentionally have
-`.html` extensions instead of `.md`, unfortunately (see
-[#1506](https://github.com/commercialhaskell/stack/issues/1506) for details).
+those.
 
 If your changes move or rename files, or subsume Wiki content, please continue
 to leave a file/page in the old location temporarily, in addition to the new
@@ -85,7 +83,79 @@
 Once installed, you can check your changes with:
 
 ```
-hlint src/ test/ --cpp-simple
+$ ./etc/scripts/hlint.sh
 ```
 
-Where `--cpp-simple` strips `#` lines.
+## Testing
+
+The Stack code has both unit tests and integration tests. Integration tests can
+be found in the [test/integration](https://github.com/commercialhaskell/stack/tree/master/test/integration)
+folder and unit tests, in the [src/test](https://github.com/commercialhaskell/stack/tree/master/src/test)
+folder. Tests are written using the [Hspec](https://hspec.github.io/) framework. In
+order to run the full test suite, you can simply do:
+
+```bash
+$ stack test
+```
+
+The `--file-watch` is a very useful option to get quick feedback. However,
+running the entire test suite after each file change will slow you down. You'll
+need to specify which test suite (unit test or integration) and pass arguments
+to specify which module you'd specifically like to run to get quick feedback. A
+description of this follows below.
+
+### Working with Unit Tests
+
+If you would like to run the unit tests on their own, you can:
+
+```bash
+$ stack test stack:stack-test
+```
+
+Running an individual module works like this:
+
+```bash
+$ stack test stack:stack-test --ta "-m <PATTERN>"
+```
+
+Where `<PATTERN>` is the name of the module without `Spec.hs`.
+
+You may also load tests into GHCi and run them with:
+
+```bash
+$ stack ghci stack:stack-test --only-main
+# GHCi starting up output ...
+> :main -m "<PATTERN>"
+```
+
+Where again, `<PATTERN>` is the name of the module without `Spec.hs`.
+
+### Working with Integration Tests
+
+Running the integration tests is a little involved, you'll need to:
+
+```bash
+$ stack test stack:integration-test --flag stack:stack-integration-tests
+```
+
+Running an individual module works like this:
+
+```bash
+$ stack test stack:stack-integration-test --flag stack:integration-tests --ta "-m <PATTERN>"
+```
+
+Where `<PATTERN>` is the name of the folder listed in the
+[test/integration/tests/](https://github.com/commercialhaskell/stack/tree/master/test/integration/tests)
+folder.
+
+You may also achieve this through GHCi with:
+
+```bash
+$ stack ghci stack:stack-integration-test
+# GHCi starting up output ...
+> :main -m "<PATTERN>"
+```
+
+Where again, `<PATTERN>` is the name of the folder listed in the
+[test/integration/tests/](https://github.com/commercialhaskell/stack/tree/master/test/integration/tests)
+folder.
diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,6 +1,40 @@
 # Changelog
 
 
+## v1.6.5
+
+Bug fixes:
+* 1.6.1 introduced a change that made some precompiled cache files use
+  longer paths, sometimes causing builds to fail on windows. This has been
+  fixed. See [#3649](https://github.com/commercialhaskell/stack/issues/3649)
+* Some unnecessary rebuilds when no files were changed are now avoided, by
+  having a separate build cache for each component of a package. See
+  [#3732](https://github.com/commercialhaskell/stack/issues/3732).
+* Correct the behavior of promoting a package from snapshot to local
+  package. This would get triggered when version bounds conflicted in
+  a snapshot, which could be triggered via Hackage revisions for old
+  packages. This also should allow custom snapshots to define
+  conflicting versions of packages without issue. See
+  [Stackage issue #3185](https://github.com/fpco/stackage/issues/3185).
+* When promoting packages from snapshot to local, we were
+  occassionally discarding the actual package location content and
+  instead defaulting to pulling the package from the index. We now
+  correctly retain this information. Note that if you were affected by
+  this bug, you will likely need to delete the binary build cache
+  associated with the relevant custom snapshot. See
+  [#3714](https://github.com/commercialhaskell/stack/issues/3714).
+* `--no-rerun-tests` has been fixed. Previously, after running a test
+  we were forgetting to record the result, which meant that all tests
+  always ran even if they had already passed before. See
+  [#3770](https://github.com/commercialhaskell/stack/pull/3770).
+* Includes a patched version of `hackage-security` which fixes both
+  some issues around asynchronous exception handling, and moves from
+  directory locking to file locking, making the update mechanism
+  resilient against SIGKILL and machine failure. See
+  [hackage-security #187](https://github.com/haskell/hackage-security/issues/187)
+  and [#3073](https://github.com/commercialhaskell/stack/issues/3073).
+
+
 ## v1.6.3.1
 
 Hackage-only release with no user facing changes (updated to build with
@@ -66,7 +100,7 @@
 * The `package-indices` setting with Hackage no longer works with the
   `00-index.tar.gz` tarball, but must use the `01-index.tar.gz` file
   to allow revised packages to be found.
-* Options passsed via `--ghci-options` are now passed to the end of the
+* Options passed via `--ghci-options` are now passed to the end of the
   invocation of ghci, instead of the middle.  This allows using `+RTS`
   without an accompanying `-RTS`.
 * When auto-detecting `--ghc-build`, `tinfo6` is now preferred over
@@ -157,7 +191,7 @@
 * Stack will now try to detect the width of the running terminal
   (only on POSIX for the moment) and use that to better display
   output messages. Work is ongoing, so some messages will not
-  be optimal yet. The terminal width can be overriden with the
+  be optimal yet. The terminal width can be overridden with the
   new `--terminal-width` command-line option (this works even on
   non-POSIX).
 * Passing non local packages as targets to `stack ghci` will now
@@ -431,7 +465,7 @@
 * The script interpreter will now output error logging.  In particular,
   this means it will output info about plan construction errors.
   ([#2879](https://github.com/commercialhaskell/stack/issues/2879))
-* `stack ghci` now takes `--flag` and `--ghc-options` again (inadverently
+* `stack ghci` now takes `--flag` and `--ghc-options` again (inadvertently
   removed in 1.3.0).
   ([#2986](https://github.com/commercialhaskell/stack/issues/2986))
 * `stack exec` now takes `--rts-options` which passes the given arguments inside of
@@ -703,7 +737,7 @@
 * Parse CLI arguments and configuration files into less permissive types,
   improving error messages for bad inputs.
   [#2267](https://github.com/commercialhaskell/stack/issues/2267)
-* Add the ability to explictly specify a gcc executable.
+* Add the ability to explicitly specify a gcc executable.
   [#593](https://github.com/commercialhaskell/stack/issues/593)
 * Nix: No longer uses LTS mirroring in nixpkgs. Gives to nix-shell a derivation
   like `haskell.compiler.ghc801`
@@ -1110,7 +1144,7 @@
   [docs](http://docs.haskellstack.org/en/stable/yaml_configuration/#image)
 - Specify which executables to include in images for `stack image container`
   [docs](http://docs.haskellstack.org/en/stable/yaml_configuration/#image)
-- Docker: pass supplemantary groups and umask into container
+- Docker: pass supplementary groups and umask into container
 - If git fetch fails wipe the directory and try again from scratch
   [#1418](https://github.com/commercialhaskell/stack/issues/1418)
 - Warn if newly installed executables won't be available on the PATH
@@ -1169,7 +1203,7 @@
   profiling, but instead of generating a report for `--bench` and
   `--test`, prints out a stack trace on exception. Great for using
   like `stack build --test --trace`
-* Nix: all options can be overriden on command line
+* Nix: all options can be overridden on command line
   [#1483](https://github.com/commercialhaskell/stack/issues/1483)
 * Nix: build environments (shells) are now pure by default.
 * Make verbosity silent by default in script interpreter mode
@@ -1282,7 +1316,7 @@
   [#1401](https://github.com/commercialhaskell/stack/issues/1401)
 * GHCi: cpp-options in cabal files weren't used
   [#1419](https://github.com/commercialhaskell/stack/issues/1419)
-* Benchmarks couldn't be run independently of eachother
+* Benchmarks couldn't be run independently of each other
   [#1412](https://github.com/commercialhaskell/stack/issues/1412)
 * Send output of building setup to stderr
   [#1410](https://github.com/commercialhaskell/stack/issues/1410)
@@ -1469,7 +1503,7 @@
 
 * Added the `--docker-env` argument, to set environment variables in Docker container.
 * Set locale environment variables to UTF-8 encoding for builds to avoid "commitBuffer: invalid argument" errors from GHC [#793](https://github.com/commercialhaskell/stack/issues/793)
-* Enable translitation for encoding on stdout and stderr [#824](https://github.com/commercialhaskell/stack/issues/824)
+* Enable transliteration for encoding on stdout and stderr [#824](https://github.com/commercialhaskell/stack/issues/824)
 * By default, `stack upgrade` automatically installs GHC as necessary [#797](https://github.com/commercialhaskell/stack/issues/797)
 * Added the `ghc-options` field to stack.yaml [#796](https://github.com/commercialhaskell/stack/issues/796)
 * Added the `extra-path` field to stack.yaml
diff --git a/doc/CONTRIBUTING.md b/doc/CONTRIBUTING.md
--- a/doc/CONTRIBUTING.md
+++ b/doc/CONTRIBUTING.md
@@ -8,7 +8,7 @@
 The more detailed your report, the faster it can be resolved and will ensure it
 is resolved in the right way. Once your bug has been resolved, the responsible
 person will tag the issue as _Needs confirmation_ and assign the issue back to
-you. Once you have tested and confirmed that the issue is resolved, close the 
+you. Once you have tested and confirmed that the issue is resolved, close the
 issue. If you are not a member of the project, you will be asked for
 confirmation and we will close it.
 
@@ -19,14 +19,12 @@
 the Wiki has been deprecated in favor of markdown files placed in a new `/doc`
 subdirectory of the repository itself. Please submit a
 [pull request](https://help.github.com/articles/using-pull-requests/) with your
-changes/additions.
+changes/additions based off the [the stable branch](https://github.com/commercialhaskell/stack/tree/stable).
 
 The documentation is rendered on [haskellstack.org](http://haskellstack.org) by
 readthedocs.org using Sphinx and CommonMark. Since links and formatting vary
 from GFM, please check the documentation there before submitting a PR to fix
-those.  In particular, links to other documentation files intentionally have
-`.html` extensions instead of `.md`, unfortunately (see
-[#1506](https://github.com/commercialhaskell/stack/issues/1506) for details).
+those.
 
 If your changes move or rename files, or subsume Wiki content, please continue
 to leave a file/page in the old location temporarily, in addition to the new
@@ -85,7 +83,79 @@
 Once installed, you can check your changes with:
 
 ```
-hlint src/ test/ --cpp-simple
+$ ./etc/scripts/hlint.sh
 ```
 
-Where `--cpp-simple` strips `#` lines.
+## Testing
+
+The Stack code has both unit tests and integration tests. Integration tests can
+be found in the [test/integration](https://github.com/commercialhaskell/stack/tree/master/test/integration)
+folder and unit tests, in the [src/test](https://github.com/commercialhaskell/stack/tree/master/src/test)
+folder. Tests are written using the [Hspec](https://hspec.github.io/) framework. In
+order to run the full test suite, you can simply do:
+
+```bash
+$ stack test
+```
+
+The `--file-watch` is a very useful option to get quick feedback. However,
+running the entire test suite after each file change will slow you down. You'll
+need to specify which test suite (unit test or integration) and pass arguments
+to specify which module you'd specifically like to run to get quick feedback. A
+description of this follows below.
+
+### Working with Unit Tests
+
+If you would like to run the unit tests on their own, you can:
+
+```bash
+$ stack test stack:stack-test
+```
+
+Running an individual module works like this:
+
+```bash
+$ stack test stack:stack-test --ta "-m <PATTERN>"
+```
+
+Where `<PATTERN>` is the name of the module without `Spec.hs`.
+
+You may also load tests into GHCi and run them with:
+
+```bash
+$ stack ghci stack:stack-test --only-main
+# GHCi starting up output ...
+> :main -m "<PATTERN>"
+```
+
+Where again, `<PATTERN>` is the name of the module without `Spec.hs`.
+
+### Working with Integration Tests
+
+Running the integration tests is a little involved, you'll need to:
+
+```bash
+$ stack test stack:integration-test --flag stack:stack-integration-tests
+```
+
+Running an individual module works like this:
+
+```bash
+$ stack test stack:stack-integration-test --flag stack:integration-tests --ta "-m <PATTERN>"
+```
+
+Where `<PATTERN>` is the name of the folder listed in the
+[test/integration/tests/](https://github.com/commercialhaskell/stack/tree/master/test/integration/tests)
+folder.
+
+You may also achieve this through GHCi with:
+
+```bash
+$ stack ghci stack:stack-integration-test
+# GHCi starting up output ...
+> :main -m "<PATTERN>"
+```
+
+Where again, `<PATTERN>` is the name of the folder listed in the
+[test/integration/tests/](https://github.com/commercialhaskell/stack/tree/master/test/integration/tests)
+folder.
diff --git a/doc/ChangeLog.md b/doc/ChangeLog.md
--- a/doc/ChangeLog.md
+++ b/doc/ChangeLog.md
@@ -1,6 +1,40 @@
 # Changelog
 
 
+## v1.6.5
+
+Bug fixes:
+* 1.6.1 introduced a change that made some precompiled cache files use
+  longer paths, sometimes causing builds to fail on windows. This has been
+  fixed. See [#3649](https://github.com/commercialhaskell/stack/issues/3649)
+* Some unnecessary rebuilds when no files were changed are now avoided, by
+  having a separate build cache for each component of a package. See
+  [#3732](https://github.com/commercialhaskell/stack/issues/3732).
+* Correct the behavior of promoting a package from snapshot to local
+  package. This would get triggered when version bounds conflicted in
+  a snapshot, which could be triggered via Hackage revisions for old
+  packages. This also should allow custom snapshots to define
+  conflicting versions of packages without issue. See
+  [Stackage issue #3185](https://github.com/fpco/stackage/issues/3185).
+* When promoting packages from snapshot to local, we were
+  occassionally discarding the actual package location content and
+  instead defaulting to pulling the package from the index. We now
+  correctly retain this information. Note that if you were affected by
+  this bug, you will likely need to delete the binary build cache
+  associated with the relevant custom snapshot. See
+  [#3714](https://github.com/commercialhaskell/stack/issues/3714).
+* `--no-rerun-tests` has been fixed. Previously, after running a test
+  we were forgetting to record the result, which meant that all tests
+  always ran even if they had already passed before. See
+  [#3770](https://github.com/commercialhaskell/stack/pull/3770).
+* Includes a patched version of `hackage-security` which fixes both
+  some issues around asynchronous exception handling, and moves from
+  directory locking to file locking, making the update mechanism
+  resilient against SIGKILL and machine failure. See
+  [hackage-security #187](https://github.com/haskell/hackage-security/issues/187)
+  and [#3073](https://github.com/commercialhaskell/stack/issues/3073).
+
+
 ## v1.6.3.1
 
 Hackage-only release with no user facing changes (updated to build with
@@ -66,7 +100,7 @@
 * The `package-indices` setting with Hackage no longer works with the
   `00-index.tar.gz` tarball, but must use the `01-index.tar.gz` file
   to allow revised packages to be found.
-* Options passsed via `--ghci-options` are now passed to the end of the
+* Options passed via `--ghci-options` are now passed to the end of the
   invocation of ghci, instead of the middle.  This allows using `+RTS`
   without an accompanying `-RTS`.
 * When auto-detecting `--ghc-build`, `tinfo6` is now preferred over
@@ -157,7 +191,7 @@
 * Stack will now try to detect the width of the running terminal
   (only on POSIX for the moment) and use that to better display
   output messages. Work is ongoing, so some messages will not
-  be optimal yet. The terminal width can be overriden with the
+  be optimal yet. The terminal width can be overridden with the
   new `--terminal-width` command-line option (this works even on
   non-POSIX).
 * Passing non local packages as targets to `stack ghci` will now
@@ -431,7 +465,7 @@
 * The script interpreter will now output error logging.  In particular,
   this means it will output info about plan construction errors.
   ([#2879](https://github.com/commercialhaskell/stack/issues/2879))
-* `stack ghci` now takes `--flag` and `--ghc-options` again (inadverently
+* `stack ghci` now takes `--flag` and `--ghc-options` again (inadvertently
   removed in 1.3.0).
   ([#2986](https://github.com/commercialhaskell/stack/issues/2986))
 * `stack exec` now takes `--rts-options` which passes the given arguments inside of
@@ -703,7 +737,7 @@
 * Parse CLI arguments and configuration files into less permissive types,
   improving error messages for bad inputs.
   [#2267](https://github.com/commercialhaskell/stack/issues/2267)
-* Add the ability to explictly specify a gcc executable.
+* Add the ability to explicitly specify a gcc executable.
   [#593](https://github.com/commercialhaskell/stack/issues/593)
 * Nix: No longer uses LTS mirroring in nixpkgs. Gives to nix-shell a derivation
   like `haskell.compiler.ghc801`
@@ -1110,7 +1144,7 @@
   [docs](http://docs.haskellstack.org/en/stable/yaml_configuration/#image)
 - Specify which executables to include in images for `stack image container`
   [docs](http://docs.haskellstack.org/en/stable/yaml_configuration/#image)
-- Docker: pass supplemantary groups and umask into container
+- Docker: pass supplementary groups and umask into container
 - If git fetch fails wipe the directory and try again from scratch
   [#1418](https://github.com/commercialhaskell/stack/issues/1418)
 - Warn if newly installed executables won't be available on the PATH
@@ -1169,7 +1203,7 @@
   profiling, but instead of generating a report for `--bench` and
   `--test`, prints out a stack trace on exception. Great for using
   like `stack build --test --trace`
-* Nix: all options can be overriden on command line
+* Nix: all options can be overridden on command line
   [#1483](https://github.com/commercialhaskell/stack/issues/1483)
 * Nix: build environments (shells) are now pure by default.
 * Make verbosity silent by default in script interpreter mode
@@ -1282,7 +1316,7 @@
   [#1401](https://github.com/commercialhaskell/stack/issues/1401)
 * GHCi: cpp-options in cabal files weren't used
   [#1419](https://github.com/commercialhaskell/stack/issues/1419)
-* Benchmarks couldn't be run independently of eachother
+* Benchmarks couldn't be run independently of each other
   [#1412](https://github.com/commercialhaskell/stack/issues/1412)
 * Send output of building setup to stderr
   [#1410](https://github.com/commercialhaskell/stack/issues/1410)
@@ -1469,7 +1503,7 @@
 
 * Added the `--docker-env` argument, to set environment variables in Docker container.
 * Set locale environment variables to UTF-8 encoding for builds to avoid "commitBuffer: invalid argument" errors from GHC [#793](https://github.com/commercialhaskell/stack/issues/793)
-* Enable translitation for encoding on stdout and stderr [#824](https://github.com/commercialhaskell/stack/issues/824)
+* Enable transliteration for encoding on stdout and stderr [#824](https://github.com/commercialhaskell/stack/issues/824)
 * By default, `stack upgrade` automatically installs GHC as necessary [#797](https://github.com/commercialhaskell/stack/issues/797)
 * Added the `ghc-options` field to stack.yaml [#796](https://github.com/commercialhaskell/stack/issues/796)
 * Added the `extra-path` field to stack.yaml
diff --git a/doc/GUIDE.md b/doc/GUIDE.md
--- a/doc/GUIDE.md
+++ b/doc/GUIDE.md
@@ -58,16 +58,12 @@
 vanilla Ubuntu 14.04 machine.
 
 ```
-# Starting with a *really* bare machine
 michael@d30748af6d3d:~$ sudo apt-get install wget
-# Demonstrate that stack really isn't available
-michael@d30748af6d3d:~$ stack
--bash: stack: command not found
-# Install stack
-wget -qO- https://get.haskellstack.org/ | sh
-# downloading...
-michael@d30748af6d3d:~$ stack --version
-Version 0.1.3.1, Git revision 908b04205e6f436d4a5f420b1c6c646ed2b804d7
+# installing ...
+michael@d30748af6d3d:~$ wget -qO- https://get.haskellstack.org/ | sh
+# downloading ...
+michael@d30748af6d3d:~$ stack --help
+# help output ...
 ```
 
 With stack now up and running, you're good to go. Though not required, we
@@ -89,8 +85,8 @@
 package name first:
 
 > A package is identified by a globally-unique package name, which consists
-of one or more alphanumeric words separated by hyphens. To avoid ambiguity,
-each of these words should contain at least one letter.
+> of one or more alphanumeric words separated by hyphens. To avoid ambiguity,
+> each of these words should contain at least one letter.
 
 (From the [Cabal users guide](https://www.haskell.org/cabal/users-guide/developing-packages.html#developing-packages))
 
@@ -103,95 +99,34 @@
 
 For this first stack command, there's quite a bit of initial setup it needs to
 do (such as downloading the list of packages available upstream), so you'll see
-a lot of output. Though your exact results may vary, below is an example of the
-sort of output you will see. Over the course of this guide a lot of the content
-will begin to make more sense:
-
-```
-Downloading template "new-template" to create project "helloworld" in helloworld/ ...
-Using the following authorship configuration:
-author-email: example@example.com
-author-name: Example Author Name
-Copy these to /home/michael/.stack/config.yaml and edit to use different values.
-Writing default config file to: /home/michael/helloworld/stack.yaml
-Basing on cabal files:
-- /home/michael/helloworld/helloworld.cabal
+a lot of output. Over the course of this guide a lot of the content will begin
+to make more sense.
 
-Downloaded lts-3.2 build plan.
-Caching build plan
-Fetched package index.
-Populated index cache.
-Checking against build plan lts-3.2
-Selected resolver: lts-3.2
-Wrote project config to: /home/michael/helloworld/stack.yaml
-```
 We now have a project in the `helloworld` directory!
 
-### stack setup
-
-Instead of assuming you want stack to download and install
-GHC for you, it asks you to do this as a separate command:
-`setup`. If we don't run `stack setup` now, we'll later see a
-message that we are missing the right GHC version.
-
-Let's run stack setup:
-
-```
-michael@d30748af6d3d:~/helloworld$ stack setup
-Downloaded ghc-7.10.2.
-Installed GHC.
-stack will use a sandboxed GHC it installed
-For more information on paths, see 'stack path' and 'stack exec env'
-To use this GHC and packages outside of a project, consider using:
-stack ghc, stack ghci, stack runghc, or stack exec
-```
-
-It doesn't come through in the output here, but you'll get intermediate
-download percentage statistics while the download is occurring. This command
-may take some time, depending on download speeds.
-
-__NOTE__: GHC will be installed to your global stack root directory, so
-calling `ghc` on the command line won't work. See the `stack exec`,
-`stack ghc`, and `stack runghc` commands below for more information.
-
 ### stack build
 
 Next, we'll run the most important stack command: `stack build`.
 
-__NOTE__: If you forgot to run `stack setup` in the previous step you'll get an
-error:
-
 ```
-michael@d30748af6d3d:~$ cd helloworld/
+michael@d30748af6d3d:~$ cd helloworld
 michael@d30748af6d3d:~/helloworld$ stack build
-No GHC found, expected version 7.10.2 (x86_64) (based on resolver setting in /home/michael/helloworld/stack.yaml).
-Try running stack setup
+# installing ... building ...
 ```
 
-stack needs GHC in order to build your project, and `stack setup` must be run to
-check whether GHC is available (and install it if not).
+stack needs a GHC in order to build your project. stack will discover that you
+are missing it and will install it for you. You can do this manually by using
+the `stack setup` command.
 
-Having run `stack setup` successfully, `stack build` should build our project:
+You'll get intermediate download percentage statistics while the download is
+occurring. This command may take some time, depending on download speeds.
 
-```
-michael@d30748af6d3d:~/helloworld$ stack build
-helloworld-0.1.0.0: configure
-Configuring helloworld-0.1.0.0...
-helloworld-0.1.0.0: build
-Preprocessing library helloworld-0.1.0.0...
-[1 of 1] Compiling Lib              ( src/Lib.hs, .stack-work/dist/x86_64-linux/Cabal-1.22.4.0/build/Lib.o )
-In-place registering helloworld-0.1.0.0...
-Preprocessing executable 'helloworld-exe' for helloworld-0.1.0.0...
-[1 of 1] Compiling Main             ( app/Main.hs, .stack-work/dist/x86_64-linux/Cabal-1.22.4.0/build/helloworld-exe/helloworld-exe-tmp/Main.o )
-Linking .stack-work/dist/x86_64-linux/Cabal-1.22.4.0/build/helloworld-exe/helloworld-exe ...
-helloworld-0.1.0.0: install
-Installing library in
-/home/michael/helloworld/.stack-work/install/x86_64-linux/lts-3.2/7.10.2/lib/x86_64-linux-ghc-7.10.2/helloworld-0.1.0.0-6urpPe0MO7OHasGCFSyIAT
-Installing executable(s) in
-/home/michael/helloworld/.stack-work/install/x86_64-linux/lts-3.2/7.10.2/bin
-Registering helloworld-0.1.0.0...
-```
+__NOTE__: GHC will be installed to your global stack root directory, so
+calling `ghc` on the command line won't work. See the `stack exec`,
+`stack ghc`, and `stack runghc` commands below for more information.
 
+Once a GHC is installed, stack will then build your project.
+
 ### stack exec
 
 Looking closely at the output of the previous command, you can see that it built
@@ -215,21 +150,12 @@
 ### stack test
 
 Finally, like all good software, helloworld actually has a test suite.
+
 Let's run it with `stack test`:
 
 ```
 michael@d30748af6d3d:~/helloworld$ stack test
-NOTE: the test command is functionally equivalent to 'build --test'
-helloworld-0.1.0.0: configure (test)
-Configuring helloworld-0.1.0.0...
-helloworld-0.1.0.0: build (test)
-Preprocessing library helloworld-0.1.0.0...
-In-place registering helloworld-0.1.0.0...
-Preprocessing test suite 'helloworld-test' for helloworld-0.1.0.0...
-[1 of 1] Compiling Main             ( test/Spec.hs, .stack-work/dist/x86_64-linux/Cabal-1.22.4.0/build/helloworld-test/helloworld-test-tmp/Main.o )
-Linking .stack-work/dist/x86_64-linux/Cabal-1.22.4.0/build/helloworld-test/helloworld-test ...
-helloworld-0.1.0.0: test (suite: helloworld-test)
-Test suite not yet implemented
+# build output ...
 ```
 
 Reading the output, you'll see that stack first builds the test suite and then
@@ -240,9 +166,7 @@
 ```
 michael@d30748af6d3d:~/helloworld$ stack build
 michael@d30748af6d3d:~/helloworld$ stack test
-NOTE: the test command is functionally equivalent to 'build --test'
-helloworld-0.1.0.0: test (suite: helloworld-test)
-Test suite not yet implemented
+# build output ...
 ```
 
 ## Inner Workings of stack
@@ -256,20 +180,28 @@
 ```
 michael@d30748af6d3d:~/helloworld$ find * -type f
 LICENSE
+README.md
 Setup.hs
 app/Main.hs
 helloworld.cabal
+package.yaml
 src/Lib.hs
 stack.yaml
 test/Spec.hs
 ```
 
-The `app/Main.hs`, `src/Lib.hs`, and `test/Spec.hs` files are all Haskell source
-files that compose the actual functionality of our project (we won't dwell on
-them here). The `LICENSE` file has no impact on the build, but is there for
-informational/legal purposes only. The files of interest here are `Setup.hs`,
-`helloworld.cabal`, and `stack.yaml`.
+The `app/Main.hs`, `src/Lib.hs`, and `test/Spec.hs` files are all Haskell
+source files that compose the actual functionality of our project (we won't
+dwell on them here).
 
+The `LICENSE` file and `README.md` have no impact on the
+build.
+
+The `helloworld.cabal` file is updated automatically as part of the
+`stack build` process and should not be modified.
+
+The files of interest here are `Setup.hs`, `stack.yaml`, and `package.yaml`.
+
 The `Setup.hs` file is a component of the Cabal build system which stack uses.
 It's technically not needed by stack, but it is still considered good practice
 in the Haskell world to include it. The file we're using is straight
@@ -280,15 +212,7 @@
 main = defaultMain
 ```
 
-Next, let's look at our `stack.yaml` file, which gives our project-level settings:
-
-```yaml
-flags: {}
-packages:
-- '.'
-extra-deps: []
-resolver: lts-3.2
-```
+Next, let's look at our `stack.yaml` file, which gives our project-level settings.
 
 If you're familiar with YAML, you may recognize that the `flags` and
 `extra-deps` keys have empty values. We'll see more interesting usages for these
@@ -305,21 +229,29 @@
 `stack setup` installs that version of GHC). There are a number of values you
 can use for `resolver`, which we'll cover later.
 
-The final file of import is `helloworld.cabal`. stack is built on top of the
-Cabal build system. In Cabal, we have individual *packages*, each of which
-contains a single `.cabal` file. The `.cabal` file can define 1 or more
-*components*: a library, executables, test suites, and benchmarks. It also
-specifies additional information such as library dependencies, default language
+Another file important to the build is `package.yaml`.
+
+Since Stack 1.6.1, the `package.yaml` is the preferred package format that is
+provided built-in by stack through [the hpack tool](https://github.com/sol/hpack).
+The default behaviour is to generate the `.cabal` file from this `package.yaml`,
+and accordingly you should **not** modify the `.cabal` file.
+
+It is also important to remember that stack is built on top of the Cabal build system. Therefore, an
+understanding of the moving parts in Cabal are necessary. In Cabal, we have individual
+*packages*, each of which contains a single `.cabal` file. The `.cabal` file
+can define 1 or more *components*: a library, executables, test suites, and benchmarks.
+It also specifies additional information such as library dependencies, default language
 pragmas, and so on.
 
 In this guide, we'll discuss the bare minimum necessary to understand how to
-modify a `.cabal` file. Haskell.org has the definitive [reference for the `.cabal`
-file format](https://www.haskell.org/cabal/users-guide/developing-packages.html).
+modify a `package.yaml` file. You can see a full list of the available options
+at the [hpack documentation](https://github.com/sol/hpack#quick-reference). Haskell.org
+has the definitive [reference for the `.cabal` file format](https://www.haskell.org/cabal/users-guide/developing-packages.html).
 
 ### The setup command
 
-As we saw above, the `setup` command installed GHC for us. Just for kicks,
-let's run `setup` a second time:
+As we saw above, the `build` command installed GHC for us. Just for kicks,
+let's manually run the `setup` command:
 
 ```
 michael@d30748af6d3d:~/helloworld$ stack setup
@@ -332,6 +264,7 @@
 Thankfully, the command is smart enough to know not to perform an installation
 twice. As the command output above indicates, you can use `stack path`
 for quite a bit of path information (which we'll play with more later).
+
 For now, we'll just look at where GHC is installed:
 
 ```
@@ -358,8 +291,8 @@
 
 ## Adding dependencies
 
-Let's say we decide to modify our helloworld source a bit to use a new library,
-perhaps the ubiquitous text package. For example:
+Let's say we decide to modify our `helloworld` source a bit to use a new library,
+perhaps the ubiquitous text package. In `src/Lib.hs`, we can, for example add:
 
 ```haskell
 {-# LANGUAGE OverloadedStrings #-}
@@ -377,60 +310,30 @@
 
 ```haskell
 michael@d30748af6d3d:~/helloworld$ stack build
-helloworld-0.1.0.0-c91e853ce4bfbf6d394f54b135573db8: unregistering (local file changes)
-helloworld-0.1.0.0: configure
-Configuring helloworld-0.1.0.0...
-helloworld-0.1.0.0: build
-Preprocessing library helloworld-0.1.0.0...
-
-/home/michael/helloworld/src/Lib.hs:6:18:
+# build failure output (abridged for clarity) ...
+/helloworld/src/Lib.hs:5:1: error:
     Could not find module `Data.Text.IO'
     Use -v to see a list of the files searched for.
-
---  While building package helloworld-0.1.0.0 using:
-      /home/michael/.stack/programs/x86_64-linux/ghc-7.10.2/bin/runhaskell -package=Cabal-1.22.4.0 -clear-package-db -global-package-db -package-db=/home/michael/.stack/snapshots/x86_64-linux/lts-3.2/7.10.2/pkgdb/ /tmp/stack5846/Setup.hs --builddir=.stack-work/dist/x86_64-linux/Cabal-1.22.4.0/ build exe:helloworld-exe --ghc-options -hpcdir .stack-work/dist/x86_64-linux/Cabal-1.22.4.0/hpc/.hpc/ -ddump-hi -ddump-to-file
-    Process exited with code: ExitFailure 1
+  |
+5 | import qualified Data.Text.IO as T
+  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 ```
 
-Notice that it says "Could not find module." This means that the package
-containing the module in question is not available. To tell stack to use text,
-you need to add it to your `.cabal` file — specifically in your build-depends
-section, like this:
+This means that the package containing the module in question is not available. To tell
+stack to use [text](https://hackage.haskell.org/package/text), you need to add it to your
+`package.yaml` file — specifically in your `dependencies` section, like this:
 
 ```
-library
-  hs-source-dirs:      src
-  exposed-modules:     Lib
-  build-depends:       base >= 4.7 && < 5
-                       -- This next line is the new one
-                     , text
-  default-language:    Haskell2010
+dependencies:
+- base >= 4.7 && < 5
+- text # added here
 ```
 
 Now if we rerun `stack build`, we should get a successful result:
 
 ```
 michael@d30748af6d3d:~/helloworld$ stack build
-text-1.2.1.3: download
-text-1.2.1.3: configure
-text-1.2.1.3: build
-text-1.2.1.3: install
-helloworld-0.1.0.0: configure
-Configuring helloworld-0.1.0.0...
-helloworld-0.1.0.0: build
-Preprocessing library helloworld-0.1.0.0...
-[1 of 1] Compiling Lib              ( src/Lib.hs, .stack-work/dist/x86_64-linux/Cabal-1.22.4.0/build/Lib.o )
-In-place registering helloworld-0.1.0.0...
-Preprocessing executable 'helloworld-exe' for helloworld-0.1.0.0...
-[1 of 1] Compiling Main             ( app/Main.hs, .stack-work/dist/x86_64-linux/Cabal-1.22.4.0/build/helloworld-exe/helloworld-exe-tmp/Main.o ) [Lib changed]
-Linking .stack-work/dist/x86_64-linux/Cabal-1.22.4.0/build/helloworld-exe/helloworld-exe ...
-helloworld-0.1.0.0: install
-Installing library in
-/home/michael/helloworld/.stack-work/install/x86_64-linux/lts-3.2/7.10.2/lib/x86_64-linux-ghc-7.10.2/helloworld-0.1.0.0-HI1deOtDlWiAIDtsSJiOtw
-Installing executable(s) in
-/home/michael/helloworld/.stack-work/install/x86_64-linux/lts-3.2/7.10.2/bin
-Registering helloworld-0.1.0.0...
-Completed all 2 actions.
+# build output ...
 ```
 
 This output means that the text package was downloaded, configured, built, and
@@ -441,44 +344,26 @@
 ### Listing Dependencies
 
 Let's have stack add a few more dependencies to our project. First, we'll include two new packages in the
-`build-depends` section for our library in our `helloworld.cabal`:
+`dependencies` section for our library in our `package.yaml`:
 
 ```
-library
-  hs-source-dirs:      src
-  exposed-modules:     Lib
-  build-depends:       base >= 4.7 && < 5
-                     , text
-                     -- a couple more dependencies...
-                     , filepath
-                     , containers
+dependencies:
+- filepath
+- containers
 ```
 
 After adding these two dependencies, we can again run `stack build` to have them installed:
 
 ```
 michael@d30748af6d3d:~/helloworld$ stack build
-helloworld-0.1.0.0: unregistering (dependencies changed)
-helloworld-0.1.0.0: configure
-Configuring helloworld-0.1.0.0...
-...
+# build output ...
 ```
 
 Finally, to find out which versions of these libraries stack installed, we can ask stack to `list-dependencies`:
 
 ```
 michael@d30748af6d3d:~/helloworld$ stack list-dependencies
-array 0.5.1.0
-base 4.8.2.0
-binary 0.7.5.0
-bytestring 0.10.6.0
-containers 0.5.6.2
-deepseq 1.4.1.1
-filepath 1.4.0.0
-ghc-prim 0.4.0.0
-helloworld 0.1.0.0
-integer-gmp 1.0.0.0
-text 1.2.2.1
+# dependency output ...
 ```
 
 ### extra-deps
@@ -498,75 +383,57 @@
 someFunc = launchMissiles
 ```
 
-Again, we add this new dependency to the `.cabal` file like this:
+Again, we add this new dependency to the `package.yaml` file like this:
 
 ```
-library
-  hs-source-dirs:      src
-  exposed-modules:     Lib
-  build-depends:       base >= 4.7 && < 5
-                     , text
-                       -- This next line is the new one
-                     , acme-missiles
-  default-language:    Haskell2010
+dependencies:
+- base >= 4.7 && 5
+- text
+- filepath
+- containers
+- acme-missiles # added
 ```
 
 However, rerunning `stack build` shows us the following error message:
 
 ```
 michael@d30748af6d3d:~/helloworld$ stack build
-While constructing the BuildPlan the following exceptions were encountered:
-
---  While attempting to add dependency,
-    Could not find package acme-missiles in known packages
-
---  Failure when adding dependencies:
-      acme-missiles: needed (-any), stack configuration has no specified version (latest applicable is 0.3)
-    needed for package: helloworld-0.1.0.0
-
-Recommended action: try adding the following to your extra-deps in /home/michael/helloworld/stack.yaml
-- acme-missiles-0.3
-
-You may also want to try the 'stack solver' command
+# build failure output ...
 ```
 
-It says acme-missiles is "not present in build plan." This brings us to the next
-major topic in using stack.
+It says that it was unable to construct the build plan.
 
+This brings us to the next major topic in using stack.
+
 ## Curated package sets
 
-Remember above when `stack new` selected the lts-3.2 resolver for us? That
-defined our build plan and available packages. When we tried using the
-text package, it just worked, because it was part of the lts-3.2 *package set*.
-But acme-missiles is not part of that package set, so building failed.
+Remember above when `stack new` selected some [LTS resolver](https://github.com/fpco/lts-haskell#readme)
+for us? That defined our build plan and available packages. When we tried using the
+`text` package, it just worked, because it was part of the LTS *package set*.
 
+But `acme-missiles` is not part of that package set, so building failed.
+
 To add this new dependency, we'll use the `extra-deps` field in `stack.yaml` to
-define extra dependencies not present in the resolver. With that change, our
-`stack.yaml` looks like:
+define extra dependencies not present in the resolver. You can add this like so:
 
 ```yaml
-flags: {}
-packages:
-- '.'
 extra-deps:
-- acme-missiles-0.3 # not in lts-3.2
-resolver: lts-3.2
+- acme-missiles-0.3 # not in the LTS
 ```
 
 Now `stack build` will succeed.
 
 With that out of the way, let's dig a little bit more into these package sets,
-also known as *snapshots*. We mentioned lts-3.2, and you can get quite a bit of
-information about it at
-[https://www.stackage.org/lts-3.2](https://www.stackage.org/lts-3.2), including:
+also known as *snapshots*. We mentioned the LTS resolvers, and you can get quite a bit of
+information about it at [https://www.stackage.org/lts](https://www.stackage.org/lts), including:
 
-* The appropriate resolver value (`resolver: lts-3.2`, as we used above)
+* The appropriate resolver value (`resolver: lts-10.0`, as is currently the latest LTS)
 * The GHC version used
 * A full list of all packages available in this snapshot
 * The ability to perform a Hoogle search on the packages in this snapshot
-* A [list of all modules](https://www.stackage.org/lts-3.2/docs) in a snapshot,
+* A [list of all modules](https://www.stackage.org/lts/docs) in a snapshot,
   which can be useful when trying to determine which package to add to your
-  `.cabal` file
+  `package.yaml` file.
 
 You can also see a [list of all available
 snapshots](https://www.stackage.org/snapshots). You'll notice two flavors: LTS
@@ -577,46 +444,25 @@
 
 ## Resolvers and changing your compiler version
 
-Let's explore package sets a bit further. Instead of lts-3.2, let's change our
-`stack.yaml` file to use
-[nightly-2015-08-26](https://www.stackage.org/nightly-2015-08-26). Rerunning
-`stack build` will produce:
+Let's explore package sets a bit further. Instead of lts-10.0, let's change our
+`stack.yaml` file to use [the latest nightly](https://www.stackage.org/nightly). Right now,
+this is currently 2017-12-19 - please see the resolve from the link above to get the latest.
 
+Then, Rerunning `stack build` will produce:
+
 ```
 michael@d30748af6d3d:~/helloworld$ stack build
-Downloaded nightly-2015-08-26 build plan.
-Caching build plan
-stm-2.4.4: configure
-stm-2.4.4: build
-stm-2.4.4: install
-acme-missiles-0.3: configure
-acme-missiles-0.3: build
-acme-missiles-0.3: install
-helloworld-0.1.0.0: configure
-Configuring helloworld-0.1.0.0...
-helloworld-0.1.0.0: build
-Preprocessing library helloworld-0.1.0.0...
-In-place registering helloworld-0.1.0.0...
-Preprocessing executable 'helloworld-exe' for helloworld-0.1.0.0...
-Linking .stack-work/dist/x86_64-linux/Cabal-1.22.4.0/build/helloworld-exe/helloworld-exe ...
-helloworld-0.1.0.0: install
-Installing library in
-/home/michael/helloworld/.stack-work/install/x86_64-linux/nightly-2015-08-26/7.10.2/lib/x86_64-linux-ghc-7.10.2/helloworld-0.1.0.0-6cKaFKQBPsi7wB4XdqRv8w
-Installing executable(s) in
-/home/michael/helloworld/.stack-work/install/x86_64-linux/nightly-2015-08-26/7.10.2/bin
-Registering helloworld-0.1.0.0...
-Completed all 3 actions.
+Downloaded nightly-2017-12-19 build plan.
+# build output ...
 ```
 
 We can also change resolvers on the command line, which can be useful in a
 Continuous Integration (CI) setting, like on Travis. For example:
 
 ```
-michael@d30748af6d3d:~/helloworld$ stack --resolver lts-3.1 build
-Downloaded lts-3.1 build plan.
-Caching build plan
-stm-2.4.4: configure
-# Rest is the same, no point copying it
+michael@d30748af6d3d:~/helloworld$ stack --resolver lts-9.18 build
+Downloaded lts-9.18 build plan.
+# build output ...
 ```
 
 When passed on the command line, you also get some additional "short-cut"
@@ -636,38 +482,13 @@
 snapshot:
 
 ```
-michael@d30748af6d3d:~/helloworld$ stack --resolver lts-2 build
-Selected resolver: lts-2.22
-Downloaded lts-2.22 build plan.
-Caching build plan
-No GHC found, expected version 7.8.4 (x86_64) (based on resolver setting in /home/michael/helloworld/stack.yaml). Try running stack setup
-```
-
-This fails, because GHC 7.8.4 (which lts-2.22 uses) is not available on our
-system. So, we see that different LTS versions (2 vs 3 in this case) use
-different GHC versions. Now, how do we get the right GHC version after changing
-the LTS version?  One answer is to use `stack setup` like we did above, this
-time with the `--resolver lts-2` option. However, there's another method worth
-mentioning: the `--install-ghc` flag.
-
-```
-michael@d30748af6d3d:~/helloworld$ stack --resolver lts-2 --install-ghc build
-Selected resolver: lts-2.22
-Downloaded ghc-7.8.4.
-Installed GHC.
-stm-2.4.4: configure
-# Mostly same as before, nothing interesting to see
+michael@d30748af6d3d:~/helloworld$ stack --resolver lts-9 build
+# build output ...
 ```
 
-What's nice about `--install-ghc` is:
-
-1. You don't need to have an extra step in your build script
-2. It only requires downloading the information on latest snapshots once
-
-As mentioned above, the default behavior of stack is to *not* install new
-versions of GHC automatically. We want to avoid surprising users with large
-downloads/installs. The `--install-ghc` flag simply changes that default
-behavior.
+This succeeds, automatically installing the necessary GHC along the way. So,
+we see that different LTS versions use different GHC versions and stack can
+handle that.
 
 ### Other resolver values
 
@@ -703,18 +524,7 @@
 
 ```
 cueball:~/yackage-0.8.0$ stack init
-Using cabal packages:
-- yackage.cabal
-
-Selecting the best among 6 snapshots...
-
-* Matches lts-4.1
-
-Selected resolver: lts-4.1
-Initialising configuration using resolver: lts-4.1
-Total number of user packages considered: 1
-Writing configuration to file: stack.yaml
-All done.
+# init output ...
 ```
 
 stack init does quite a few things for you behind the scenes:
@@ -737,42 +547,13 @@
 at times, you may find that not all dependencies required may be available in
 the Stackage snapshots.
 
-Let's simulate an unsatisfied dependency by adding acme-missiles to our
-build-depends and re-initing:
+Let's simulate an unsatisfied dependency by adding acme-missiles to the `.cabal` file
+(yackage does not currently support hpack, but you can also [hpack-convert](https://github.com/yamadapc/hpack-convert)
+should you need to generate a `package.yaml`) build-depends and then re-initing:
 
 ```
 cueball:~/yackage-0.8.0$ stack init --force
-Using cabal packages:
-- yackage.cabal
-
-Selecting the best among 6 snapshots...
-
-* Partially matches lts-4.1
-    acme-missiles not found
-        - yackage requires -any
-        - yackage flags: upload = True
-
-* Partially matches nightly-2016-01-16
-    acme-missiles not found
-        - yackage requires -any
-        - yackage flags: upload = True
-
-* Partially matches lts-3.22
-    acme-missiles not found
-        - yackage requires -any
-        - yackage flags: upload = True
-
-.
-.
-.
-
-Selected resolver: lts-4.1
-Resolver 'lts-4.1' does not have all the packages to match your requirements.
-    acme-missiles not found
-        - yackage requires -any
-        - yackage flags: upload = True
-
-However, you can try '--solver' to use external packages.
+# init failure output
 ```
 
 stack has tested six different snapshots, and in every case discovered that
@@ -780,55 +561,24 @@
 `--solver` command line switch if you want to use packages outside Stackage. So
 let's give it a try:
 
-
 ```
 cueball:~/yackage-0.8.0$ stack init --force --solver
-Using cabal packages:
-- yackage.cabal
-
-Selecting the best among 6 snapshots...
-
-* Partially matches lts-4.1
-    acme-missiles not found
-        - yackage requires -any
-        - yackage flags: upload = True
-
-.
-.
-.
-
-Selected resolver: lts-4.1
-*** Resolver lts-4.1 will need external packages:
-    acme-missiles not found
-        - yackage requires -any
-        - yackage flags: upload = True
-
-Using resolver: lts-4.1
-Using compiler: ghc-7.10.3
-Asking cabal to calculate a build plan...
-Trying with packages from lts-4.1 as hard constraints...
-Successfully determined a build plan with 3 external dependencies.
-Initialising configuration using resolver: lts-4.1
-Total number of user packages considered: 1
-Warning! 3 external dependencies were added.
-Overwriting existing configuration file: stack.yaml
-All done.
+# solver output ...
 ```
 
-As you can verify by viewing `stack.yaml`, three external dependencies were added
-by stack init:
+stack will complain that it needs a `cabal-install` installation. Let's get that:
 
 ```
-# Packages to be pulled from upstream that are not in the resolver (e.g., acme-missiles-0.3)
-extra-deps:
-- acme-missiles-0.3
-- text-1.2.2.0
-- yaml-0.8.15.2
+cueball:~/yackage-0.8.0$ stack install cabal-install
 ```
 
-Of course, you could have added the external dependencies by manually editing
-`stack.yaml` but stack init does the hard work for you.
+Then run the above `stack init` command above again and it will succeed.
 
+As you can verify by viewing `stack.yaml`, three external dependencies were added
+by stack init under the `extra-deps` field. Of course, you could have added the
+external dependencies by manually editing `stack.yaml` but stack init does the
+hard work for you.
+
 #### Excluded Packages
 
 Sometimes multiple packages in your project may have conflicting requirements.
@@ -846,57 +596,12 @@
 
 ```
 cueball:~/yackage-0.8.0$ stack init --force --solver --omit-packages
-Using cabal packages:
-- yackage.cabal
-- example/yackage-test.cabal
-
-Selecting the best among 6 snapshots...
-
-* Partially matches lts-4.2
-    acme-missiles not found
-        - yackage requires ==0.3
-        - yackage-test requires ==0.2
-        - yackage flags: upload = True
-        - yackage-test flags: upload = True
-.
-.
-.
-
-*** Failed to arrive at a workable build plan.
-*** Ignoring package: yackage-test
-*** Resolver lts-4.2 will need external packages:
-    acme-missiles not found
-        - yackage requires ==0.3
-        - yackage flags: upload = True
-
-Using resolver: lts-4.2
-Using compiler: ghc-7.10.3
-Asking cabal to calculate a build plan...
-Trying with packages from lts-4.2 as hard constraints...
-Successfully determined a build plan with 3 external dependencies.
-Initialising configuration using resolver: lts-4.2
-Total number of user packages considered: 2
-Warning! Ignoring 1 packages due to dependency conflicts:
-        - "example/yackage-test.cabal"
-
-Warning! 3 external dependencies were added.
-Overwriting existing configuration file: stack.yaml
-All done.
+# init failure output ...
 ```
 
 Looking at `stack.yaml`, you will see that the excluded packages have been
-commented out:
-
-```
-# Local packages, usually specified by relative directory name
-packages:
-- '.'
-# The following packages have been ignored due to incompatibility with the resolver compiler or dependency conflicts with other packages
-#- example/
-```
-
-In case wrong packages are excluded you can uncomment the right one and comment
-the other one.
+commented out under the `packages` field. In case wrong packages are excluded
+you can uncomment the right one and comment the other one.
 
 Packages may get excluded due to conflicting requirements among user packages
 or due to conflicting requirements between a user package and the resolver
@@ -904,8 +609,8 @@
 them may get commented out.
 
 When packages are commented out you will see a warning every time you run a
-command which needs the config file. The warning can be disabled by editing the
-config file and removing it.
+command which needs the configuration file. The warning can be disabled by
+editing the configuration file and removing it.
 
 #### Using a specific resolver
 
@@ -919,8 +624,8 @@
 
 #### Installing the compiler
 
-You can install the required compiler if not already installed by using the
-`--install-ghc` flag with the `stack init` command.
+stack will automatically install the compiler when you run `stack build` but you can
+manually specify the compiler by running `stack setup <GHC-VERSION>`.
 
 #### Miscellaneous and diagnostics
 
@@ -957,7 +662,6 @@
 Warning: Some packages were found to be incompatible with the resolver and have been left commented out in the packages section.
 Warning: Specified resolver could not satisfy all dependencies. Some external packages have been added as dependencies.
 You can suppress this message by removing it from stack.yaml
-
 ```
 ### stack solver
 
@@ -974,22 +678,10 @@
 
 ```
 cueball:~/yackage-0.8.0$ stack solver
-Using configuration file: stack.yaml
-The following packages are missing from the config:
-- example/yackage-test.cabal
-
-Using cabal packages:
-- yackage.cabal
-
-Using resolver: lts-4.2
-Using compiler: ghc-7.10.3
-Asking cabal to calculate a build plan...
-Trying with packages from lts-4.2 and 3 external packages as hard constraints...
-Successfully determined a build plan with 3 external dependencies.
-No changes needed to stack.yaml
+# solver output ...
 ```
 
-It says there are no changes needed to your config. Notice that it also reports
+It says there are no changes needed to your configuration. Notice that it also reports
 `example/yackage-test.cabal` as missing from the config. It was purposely
 omitted by `stack init` to resolve a conflict.
 
@@ -1007,34 +699,7 @@
 
 ```
 cueball:~/yackage-0.8.0$ stack solver
-
-Using configuration file: stack.yaml
-The following packages are missing from the config:
-- yackage.cabal
-
-Using cabal packages:
-- example/yackage-test.cabal
-
-.
-.
-.
-
-Retrying with packages from lts-4.2 and 3 external packages as preferences...
-Successfully determined a build plan with 5 external dependencies.
-
-The following changes will be made to stack.yaml:
-* Resolver is lts-4.2
-* Dependencies to be added
-    extra-deps:
-    - acme-missiles-0.2
-    - email-validate-2.2.0
-    - tar-0.5.0.1
-
-* Dependencies to be deleted
-    extra-deps:
-    - acme-missiles-0.3
-
-To automatically update stack.yaml, rerun with '--update-config'
+# solver failure output ...
 ```
 
 Due to the change that we made, solver suggested some new dependencies.
@@ -1052,58 +717,11 @@
 If you want to change the resolver for your project, you can run
 `stack solver --resolver <resolver name>` and it will figure out the changes needed for you.
 
-Let's see what happens if we change the resolver to lts-2.22:
+Let's see what happens if we change the resolver to an older resolver - lts-2.22:
 
 ```
 cueball:~/yackage-0.8.0$ stack solver --resolver lts-2.22
-Using configuration file: stack.yaml
-The following packages are missing from the config:
-- yackage.cabal
-
-Using cabal packages:
-- example/yackage-test.cabal
-
-Using resolver: lts-2.22
-Using compiler: ghc-7.8.4
-
-.
-.
-.
-
-Retrying with packages from lts-2.22 and 3 external packages as preferences...
-Successfully determined a build plan with 19 external dependencies.
-
-The following changes will be made to stack.yaml:
-* Resolver is lts-2.22
-* Flags to be added
-    flags:
-    - old-locale: true
-
-* Dependencies to be added
-    extra-deps:
-    - acme-missiles-0.2
-    - aeson-0.10.0.0
-    - aeson-compat-0.3.0.0
-    - attoparsec-0.13.0.1
-    - conduit-extra-1.2.0
-    - email-validate-2.2.0
-    - hex-0.1.2
-    - http-api-data-0.2.2
-    - http2-1.1.0
-    - persistent-2.2.4
-    - persistent-template-2.1.5
-    - primitive-0.6.1.0
-    - tar-0.5.0.1
-    - unix-time-0.3.6
-    - vector-0.11.0.0
-    - wai-extra-3.0.14
-    - warp-3.1.3.1
-
-* Dependencies to be deleted
-    extra-deps:
-    - acme-missiles-0.3
-
-To automatically update stack.yaml, rerun with '--update-config'
+# solver failure output ...
 ```
 
 As you can see, it automatically suggested changes in `extra-deps` due to the
diff --git a/doc/MAINTAINER_GUIDE.md b/doc/MAINTAINER_GUIDE.md
--- a/doc/MAINTAINER_GUIDE.md
+++ b/doc/MAINTAINER_GUIDE.md
@@ -90,7 +90,7 @@
 
 * Create a
   [new draft Github release](https://github.com/commercialhaskell/stack/releases/new)
-  with tag and name `vX.Y.Z` (where X.Y.Z is the stack package's version), targetting the
+  with tag and name `vX.Y.Z` (where X.Y.Z is the stack package's version), targeting the
   RC branch
 
 * On each machine you'll be releasing from, set environment variables:
@@ -295,7 +295,7 @@
 
 ### Install clang+llvm
 
-NOTE: the Debian jessie `llvm` packge does not work (executables built with it
+NOTE: the Debian jessie `llvm` package does not work (executables built with it
 just exit with "schedule: re-entered unsafely.").
 
 The version of LLVM needed depends on the version of GHC you need.
diff --git a/doc/README.md b/doc/README.md
--- a/doc/README.md
+++ b/doc/README.md
@@ -47,7 +47,7 @@
 ```
 
 - The `stack new` command will create a new directory containing all
-the needed files to start a project correctly.
+  the needed files to start a project correctly.
 - The `stack setup` will download the compiler if necessary in an isolated
   location (default `~/.stack`) that won't interfere with any system-level
   installations. (For information on installation paths, please use the
@@ -55,7 +55,7 @@
 - The `stack build` command will build the minimal project.
 - `stack exec my-project-exe` will execute the command.
 - If you just want to install an executable using stack, then all you have to do
-is `stack install <package-name>`.
+  is `stack install <package-name>`.
 
 If you want to launch a REPL:
 
@@ -63,7 +63,6 @@
 stack ghci
 ```
 
-
 Run `stack` for a complete list of commands.
 
 ##### Workflow
@@ -90,19 +89,20 @@
 
 1. Edit files in the `src/` directory.
 
-The `app` directory should preferably contain only files related to
-executables.
+   The `app` directory should preferably contain only files related to
+   executables.
 
-2. If you need to include another library (for example the package [`text`](https://hackage.haskell.org/package/text):
+2. If you need to include another library (for example the package
+   [`text`](https://hackage.haskell.org/package/text)):
 
    - Add the package `text` to the file `my-project.cabal`
      in the section `build-depends: ...`.
-   - run `stack build` another time
+   - Run `stack build` another time.
 
 3. If you get an error that tells you your package isn't in the LTS.
    Just try to add a new version in the `stack.yaml` file in the `extra-deps` section.
 
-It was a really fast introduction on how to start to code in Haskell using `stack`.
+That was a really fast introduction on how to start to code in Haskell using `stack`.
 If you want to go further, we highly recommend you to read the [`stack` guide](GUIDE.md).
 
 #### How to contribute
@@ -132,19 +132,30 @@
 stack build
 ```
 
+If you need to check your changes quickly run:
+
+```bash
+stack ghci
+λ: :main --stack-root /path/to/root/ --stack-yaml /path/to/stack.yaml COMMAND
+```
+
+This allows you to set a special stack root (instead of `~/.stack/`) and to
+target your commands at a particular `stack.yaml` instead of the one found in
+the current directory.
+
 #### Complete guide to stack
 
-This repository also contains a complete [user guide to using stack
-](GUIDE.md), covering all of the most common use cases.
+This repository also contains a complete [user guide to using
+stack](GUIDE.md), covering all of the most common use cases.
 
 
 #### Questions, Feedback, Discussion
 
 * For frequently asked questions about detailed or specific use-cases, please
   see [the FAQ](faq.md).
-* For general questions, comments, feedback and support please write
+* For general questions, comments, feedback and support, please write
   to [the stack mailing list](https://groups.google.com/d/forum/haskell-stack).
-* For bugs, issues, or requests please
+* For bugs, issues, or requests, please
   [open an issue](https://github.com/commercialhaskell/stack/issues/new).
 * When using Stack Overflow, please use [the haskell-stack
   tag](http://stackoverflow.com/questions/tagged/haskell-stack).
@@ -158,7 +169,7 @@
 power experienced developers need.  As a build tool, Stack does not
 stand alone. It is built on the great work provided by:
 
-* The __Glasgow Haskell Compiler__ (GHC), the premiere Haskell
+* The __Glasgow Haskell Compiler__ (GHC), the premier Haskell
   compiler. Stack will manage your GHC installations and automatically
   select the appropriate compiler version for your project.
 * The __Cabal build system__, a specification for defining Haskell
@@ -178,4 +189,5 @@
 project meeting the needs of Haskell users of all stripes.
 
 If you'd like to get involved with Stack, check out the
-[newcomer friendly](https://github.com/commercialhaskell/stack/issues?q=is%3Aopen+is%3Aissue+label%3a%22newcomer+friendly%22) label on the Github issue tracker.
+[newcomer friendly](https://github.com/commercialhaskell/stack/issues?q=is%3Aopen+is%3Aissue+label%3a%22newcomer+friendly%22)
+label on the Github issue tracker.
diff --git a/doc/faq.md b/doc/faq.md
--- a/doc/faq.md
+++ b/doc/faq.md
@@ -393,7 +393,7 @@
 
     $env:Path = ( stack setup | %{ $_ -replace '[^ ]+ ', ''} ), $env:Path -join ";"
 
-## How do I reset / remove Stack (such as to to do a completely fresh build)?
+## How do I reset / remove Stack (such as to do a completely fresh build)?
 
 The first thing to remove is project-specific `.stack-work` directory within
 the project's directory. Next, remove `~/.stack` directory overall. You may
@@ -407,38 +407,39 @@
 
 ## I get strange `ld` errors about recompiling with "-fPIC"
 
-Some users (myself included!) have come across a linker errors (example below)
-that seem to be dependent on the local environment, i.e. the package may
-compile on a different machine. The issue has been reported to be
-[non-deterministic](https://github.com/commercialhaskell/stack/issues/614) in
-some cases. I've had success using the docker functionality to build the
-project on a machine that would not compile it otherwise.
+(Updated in December 2017)
 
-```
-tmp-0.1.0.0: build
-Building tmp-0.1.0.0...
-Preprocessing executable 'tmp' for tmp-0.1.0.0...
-Linking dist-stack/x86_64-linux/Cabal-1.22.2.0/build/tmp/tmp ...
-/usr/bin/ld: dist-stack/x86_64-linux/Cabal-1.22.2.0/build/tmp/tmp-tmp/Main.o: relocation R_X86_64_32S against `stg_bh_upd_frame_info' can not be used when making a shared object; recompile with -fPIC
-dist-stack/x86_64-linux/Cabal-1.22.2.0/build/tmp/tmp-tmp/Main.o: error adding symbols: Bad value
-collect2: error: ld returned 1 exit status
+This is related to more recent versions of Linux distributions that have GCC
+with PIE enabled by default.  The continuously-updated distros like Arch, in
+particular, had been in flux with this change and the upgrading
+libtinfo6/ncurses6, and there were some workarounds attempted in Stack that
+ended up causing trouble as these distros evolved.
 
---  While building package tmp-0.1.0.0 using:
-      /home/philip/.stack/programs/x86_64-linux/ghc-7.10.1/bin/runghc-7.10.1 -package=Cabal-1.22.2.0 -clear-package-db -global-package-db /home/philip/tmp/Setup.hs --builddir=dist-stack/x86_64-linux/Cabal-1.22.2.0/ build
-    Process exited with code: ExitFailure 1
-```
+GHC added official support for this setup in 8.0.2, so if you are using an
+older version your best bet is to upgrade.  You may be able to work around it
+for older versions by editing `~/.stack/programs/x86_64-osx/ghc-VER/lib/ghc-
+VER/settings` (replace `VER` with the GHC version) and adding `-no-pie` (or
+`--no-pie` in the case of Gentoo, at least as of December 2017) to the __C
+compiler link flags__.
 
-The issue may be related to the use of hardening flags in some cases,
-specifically those related to producing position independent executables (PIE).
-This is tracked upstream in the [following
-ticket](https://ghc.haskell.org/trac/ghc/ticket/12759). Some distributions add
-such hardening flags by default which may be the cause of some instances of the
-problem. Therefore, a possible workaround might be to turn off PIE related
-flags.
+If `stack setup` complains that there is no `linuxNN-*-nopie` bindist available,
+try adding `ghc-build: *` (replacing the `*` with the actual value that
+precedes `-nopie`, which may be empty) to your `~/.stack/config.yaml` (this
+will no longer be necessary for stack >= 1.7).
 
-On Arch Linux, installing the `ncurses5-compat-libs` package from AUR resolves [this issue](https://github.com/commercialhaskell/stack/issues/2712).
+If you are experiencing this with GHC >= 8.0.2, try running `stack setup
+--reinstall` if you've upgraded your Linux distribution or you set up GHC
+before late December 2017.
 
-If you manage to work around this in other distributions, please include instructions here.
+If you are still having trouble after trying the above, check the following
+for more possible workarounds:
+
+  * [Previous version of this FAQ entry](https://docs.haskellstack.org/en/v1.6.3/faq/#i-get-strange-ld-errors-about-recompiling-with-fpic)
+  * Related issues:
+    [#3518](https://github.com/commercialhaskell/stack/issues/3518),
+    [#2712](https://github.com/commercialhaskell/stack/issues/2712),
+    [#3630](https://github.com/commercialhaskell/stack/issues/3630),
+    [#3648](https://github.com/commercialhaskell/stack/issues/3648)
 
 ## Where does the output from `--ghc-options=-ddump-splices` (and other `-ddump*` options) go?
 
diff --git a/doc/ghcjs.md b/doc/ghcjs.md
--- a/doc/ghcjs.md
+++ b/doc/ghcjs.md
@@ -12,7 +12,7 @@
 them with GHCJS.  For example: `stack build --compiler ghcjs-0.2.0.9006020_ghc-7.10.3`
 
 There are advanced options for `stack setup`: `--ghcjs-boot-options` (one word at a time) and `--[no-]ghcjs-boot-clean`
-which will passyour settings down to the `ghcjs-boot`. You will need to know exacty what you are doing with them.  
+which will pass your settings down to the `ghcjs-boot`. You will need to know exactly what you are doing with them.  
 
 Sidenote: If you receive a message like
 `The program 'ghcjs' version >=0.1 is required but the version of .../ghcjs could not be determined.`,
@@ -56,9 +56,9 @@
            sha1: d2cfc25f9cda32a25a87d9af68891b2186ee52f9
 ```
 The later can be generated via: https://github.com/tolysz/prepare-ghcjs
-the fromer is a bit more manual. Those bundles are only tested against the latest `node-7.4.0`.
+the former is a bit more manual. Those bundles are only tested against the latest `node-7.4.0`.
 
-In order to corrrectly boot and use ghcjs, one might need to install `alex` `happy` `hscolour` `hsc2hs` with the normal ghc.
+In order to correctly boot and use ghcjs, one might need to install `alex` `happy` `hscolour` `hsc2hs` with the normal ghc.
 
 Older resolvers:
 
diff --git a/doc/install_and_upgrade.md b/doc/install_and_upgrade.md
--- a/doc/install_and_upgrade.md
+++ b/doc/install_and_upgrade.md
@@ -94,29 +94,32 @@
 
   * [GHC 7.8.4 fails with `/usr/bin/ar: permission denied`](faq.md#usr-bin-ar-permission-denied)
   * [DYLD_LIBRARY_PATH is ignored](faq.md#dyld-library-path-ignored)
-  
 
+
 If you are on OS X 10.12 ("Sierra") and encounter [GHC panic while building, see this issue](https://github.com/commercialhaskell/stack/issues/2577)
 
 ## Ubuntu
 
 Use the [generic Linux option](#linux).
 
-There is also
-a
-[Ubuntu package](http://packages.ubuntu.com/search?keywords=haskell-stack&searchon=names&suite=all&section=all) for
-Ubuntu 16.04 and up. Note that the distribution's Stack version lags behind, so
-we recommend running `stack upgrade` after installing it.
+There is also a [Ubuntu
+package](http://packages.ubuntu.com/search?keywords=haskell-stack&searchon=names&suite=all&section=all)
+for Ubuntu 16.10 and up, but the distribution's Stack version lags behind, so we
+recommend running `stack upgrade --binary` after installing it. For older stack
+versions which do not support `--binary`, just `stack upgrade` is fine too. The
+version in Ubuntu 16.04 is too old to upgrade successfully, and so in that case
+stack should be installed from a [release
+tarball](https://github.com/commercialhaskell/stack/releases).
 
 ## Debian
 
 Use the [generic Linux option](#linux).
 
-There is also
-a
-[Debian package](https://packages.debian.org/search?keywords=haskell-stack&searchon=names&suite=all&section=all) for
-Stretch and up. Note that the distribution's Stack version lags behind, so
-we recommend running `stack upgrade` after installing it.
+There is also a [Debian
+package](https://packages.debian.org/search?keywords=haskell-stack&searchon=names&suite=all&section=all)
+for Stretch and up, but the distribution's Stack version lags behind, so running
+`stack upgrade --binary` is recommended after installing it. For older stack
+versions which do not support `--binary`, just `stack upgrade` is fine too.
 
 ## <a name="centos"></a>CentOS / Red Hat / Amazon Linux
 
@@ -192,7 +195,7 @@
 
 Users who follow the `nixos-unstable` channel or the Nixpkgs `master` branch can install the latest `stack` release into their profile by running:
 
-    nix-env -f "<nixpkgs>" -iA haskellPackages.stack
+    nix-env -f "<nixpkgs>" -iA stack
 
 Alternatively, the package can be built from source as follows.
 
diff --git a/doc/nix_integration.md b/doc/nix_integration.md
--- a/doc/nix_integration.md
+++ b/doc/nix_integration.md
@@ -35,7 +35,7 @@
 located at `$HOME/.nix-profile/etc/profile.d/nix.sh` is not sourced by your shell.
 
 You should either run `source ~/.nix-profile/etc/profile.d/nix.sh` manually
-everytime you open a terminal and need Nix or add this command to your
+every time you open a terminal and need Nix or add this command to your
 `~/.bashrc` or `~/.bash_profile`.
 
 ### Additions to your `stack.yaml`
diff --git a/doc/stack_yaml_vs_cabal_package_file.md b/doc/stack_yaml_vs_cabal_package_file.md
new file mode 100644
--- /dev/null
+++ b/doc/stack_yaml_vs_cabal_package_file.md
@@ -0,0 +1,136 @@
+<div class="hidden-warning"><a href="https://docs.haskellstack.org/"><img src="https://rawgit.com/commercialhaskell/stack/master/doc/img/hidden-warning.svg"></a></div>
+
+# stack.yaml vs cabal package file
+
+Due to their apparent overlap, the purpose of the following three files can be
+unclear:
+
+* `stack.yaml`
+* A cabal package file, e.g. `my-package.cabal`
+* `package.yaml`
+
+The last two are easy to explain: `package.yaml` is a file format supported by
+[hpack](https://github.com/sol/hpack#readme). It adds some niceties on top of
+cabal. For example, hpack has YAML syntax support and will automatically
+generate of `exposed-modules` lists. However, it's just a frontend to cabal
+package files. So for this document, we're instead going to focus on the first
+two and try to answer:
+
+_What's the difference between a `stack.yaml` file and a cabal package file?_
+
+## Package versus project
+
+Cabal is a build system, which is used by Stack. Cabal defines the concept of a
+_package_. A package has:
+
+* A name and version
+* 0 or 1 libraries
+* 0 or more executables
+* A cabal file (or, as mentioned above, an hpack `package.yaml` that
+  generates a cabal file)
+* And a bunch more
+
+The second to last bullet bears repeating: there's a 1-to-1 correspondence between
+packages and cabal files. 
+
+Stack is a build tool that works on top of the Cabal build system, and defines
+a new concept called a _project_. A project has:
+
+* A _resolver_, which tells it about a snapshot (more on this later)
+* Extra dependencies on top of the snapshot
+* 0 or more local Cabal packages
+* Flag and GHC options configurations
+* And a bunch more Stack configuration
+
+A source of confusion is that, often, you'll have a project that defines
+exactly one package you're working on, and in that situation it's unclear why,
+for example, you need to specify an extra depedency in both your `stack.yaml`
+_and_ cabal file. To explain, let's take a quick detour to talk about snapshots
+and how Stack resolves dependencies.
+
+## Resolvers and snapshots
+
+Stack follows a rule that says, for any projects, there is precisely 1 version
+of each package available. Obviously there are _many_ versions of many
+different packages available in the world. But when resolving a `stack.yaml`
+file, Stack requires that you have chosen a specific version for each package
+available.
+
+The most common means by which this set of packages is defined is via a
+Stackage Snapshot. For example, if you go to the page
+<https://www.stackage.org/lts-10.2>, you will see a list of 2,666 packages at
+specific version numbers. When you then specify `resolver: lts-10.2`, you're
+telling Stack to use those package versions in resolving dependencies down to
+concrete version numbers.
+
+Sometimes a snapshot doesn't have all of the packages you want. Or you want a
+different version. Or you want to work on a local modification of a package. In
+all of those cases, you can add more configuration data to your `stack.yaml` to
+override the values it received from your `resolver` setting. At the end of the
+day, each of your projects will end up with some way of resolving a package
+name into a concrete version number.
+
+## Why specify deps twice?
+
+When you add something like this to your `stack.yaml` file:
+
+```yaml
+extra-deps:
+- acme-missiles-0.3
+```
+
+What you're saying to Stack is: if at any point you find that you need to build
+the `acme-missiles` package, please use version `0.3`. You are _not_ saying
+"please build `acme-missiles` now." You are also not saying "my package depends
+on `acme-missiles`." You are simply making it available should the need arise.
+
+When you add `build-depends: acme-missiles` to your cabal file or
+`dependencies: [acme-missiles]` to your `package.yaml` file, you're saying
+"this package requires that `acme-missiles` be available." Since
+`acme-missiles` doesn't appear in your snapshot, without also modifying your
+`stack.yaml` to mention it via `extra-deps`, Stack will complain about the
+dependency being unavailable.
+
+You may challenge: but why go through all of that annoyance? Stack knows what
+package I want, why not just go grab it? The answer is that, if Stack just
+grabbed `acme-missiles` for you without it being specified in the `stack.yaml`
+somehow, you'd lose reproducibility. How would Stack know which version to use?
+It may elect to use the newest version, but if a new version is available in
+the future, will it automatically switch to that?
+
+Stack's baseline philosophy is that build plans are always reproducible\*. The
+purpose of the `stack.yaml` file is to define an immutable set of packages. No
+matter when in time you use it, and no matter how many new release happen in
+the interim, the build plan generated should be the same.
+
+\* There's at least one hole in this theory today, which is Hackage revisions.
+When you specify `extra-deps: [acme-missiles-0.3]`, it doesnt' specify which
+revision of the cabal file to use, and Stack will just choose the latest. Stack
+version 1.6 added the ability to specify exact revisions of cabal files, but
+this isn't enforced as a requirement as it's so different from the way most
+people work with packages.
+
+And now, how about the other side: why doesn't Stack automatically add
+`acme-missiles` to `build-depends` in your cabal file if you add it as an
+extra-dep? There are a surprising number reasons actually:
+
+* The cabal spec doesn't support anything like that
+* There can be multiple packages in a project, and how do we know which package
+  actually needs the dependency?
+* There can be multiple components (libraries, executable, etc) in a package,
+  and how do we know which of those actually needs the dependency?
+* The dependency may only be conditionally needed, based on flags, OS, or
+  architecture. As an extreme example, we wouldn't want a Linux-only package to
+  be force-built on Windows.
+
+While for simple use cases it seems like automatically adding dependencies from
+the cabal file to the `stack.yaml` file or vice-versa would be a good thing, it
+breaks down immediately for any semi-difficult case. Therefore, Stack requires
+you to add it to both places.
+
+And a final note, in case it wasn't clear. The example I gave above used
+`acme-missiles`, which is not in Stackage snapshots. If, however, you want to
+depend on a package already present in the snapshot you've selected, there's no
+need to add it explicitly to your `stack.yaml` file: it's already there
+implicitly via the `resolver` setting. This is what you do the majority of the
+time, such as when you add `vector` or `mtl` as a `build-depends` value.
diff --git a/doc/yaml_configuration.md b/doc/yaml_configuration.md
--- a/doc/yaml_configuration.md
+++ b/doc/yaml_configuration.md
@@ -22,6 +22,10 @@
 invoked inside a stack project, only options from `<project dir>/stack.yaml` are
 used, and `~/.stack/global-project/stack.yaml` is ignored.
 
+*Note 2:* A common source of confusion is the distinction between configuration
+in a `stack.yaml` file versus a cabal file. If you're trying to understand this
+breakdown, see [stack vs cabal config](stack_yaml_vs_cabal_package_file.md).
+
 ## Project-specific config
 
 Project-specific options are only valid in the `stack.yaml` file local to a
@@ -537,7 +541,7 @@
 custom package flag). However, setting options via `$everything` on all flags
 will not do so (see
 [Github discussion](https://github.com/commercialhaskell/stack/issues/849#issuecomment-320892095)
-for reasoning). This can lead to unpredicable behavior by affecting
+for reasoning). This can lead to unpredictable behavior by affecting
 your snapshot packages.
 
 The behavior of the `$locals`, `$targets`, and `$everything` special
diff --git a/package.yaml b/package.yaml
--- a/package.yaml
+++ b/package.yaml
@@ -1,5 +1,5 @@
 name: stack
-version: '1.6.3.1'
+version: '1.6.5'
 synopsis: The Haskell Tool Stack
 description: ! 'Please see the README.md for usage information, and
   the wiki on Github for more details.  Also, note that
@@ -10,7 +10,7 @@
 author: Commercial Haskell SIG
 maintainer: manny@fpcomplete.com
 license: BSD3
-github: commercialhaskell/stack.git
+github: commercialhaskell/stack
 homepage: http://haskellstack.org
 custom-setup:
   dependencies:
diff --git a/src/Stack/Build/Cache.hs b/src/Stack/Build/Cache.hs
--- a/src/Stack/Build/Cache.hs
+++ b/src/Stack/Build/Cache.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE NoImplicitPrelude #-}
 {-# LANGUAGE DeriveGeneric         #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
@@ -39,6 +40,9 @@
 import qualified Data.ByteString.Base64.URL as B64URL
 import qualified Data.ByteString as B
 import qualified Data.ByteString.Char8 as S8
+#ifdef mingw32_HOST_OS
+import           Data.Char (ord)
+#endif
 import qualified Data.Map as M
 import qualified Data.Set as Set
 import qualified Data.Store as Store
@@ -106,10 +110,24 @@
     ident' <- parseRelFile $ packageIdentifierString ident
     liftIO $ ignoringAbsence (removeFile $ dir </> ident')
 
+buildCacheFile :: (HasEnvConfig env, MonadReader env m, MonadThrow m)
+               => Path Abs Dir
+               -> NamedComponent
+               -> m (Path Abs File)
+buildCacheFile dir component = do
+    cachesDir <- buildCachesDir dir
+    let nonLibComponent prefix name = prefix <> "-" <> T.unpack name
+    cacheFileName <- parseRelFile $ case component of
+        CLib -> "lib"
+        CExe name -> nonLibComponent "exe" name
+        CTest name -> nonLibComponent "test" name
+        CBench name -> nonLibComponent "bench" name
+    return $ cachesDir </> cacheFileName
+
 -- | Try to read the dirtiness cache for the given package directory.
 tryGetBuildCache :: (MonadUnliftIO m, MonadReader env m, MonadThrow m, MonadLogger m, HasEnvConfig env)
-                 => Path Abs Dir -> m (Maybe (Map FilePath FileCacheInfo))
-tryGetBuildCache dir = liftM (fmap buildCacheTimes) . $(versionedDecodeFile buildCacheVC) =<< buildCacheFile dir
+                 => Path Abs Dir -> NamedComponent -> m (Maybe (Map FilePath FileCacheInfo))
+tryGetBuildCache dir component = liftM (fmap buildCacheTimes) . $(versionedDecodeFile buildCacheVC) =<< buildCacheFile dir component
 
 -- | Try to read the dirtiness cache for the given package directory.
 tryGetConfigCache :: (MonadUnliftIO m, MonadReader env m, MonadThrow m, HasEnvConfig env, MonadLogger m)
@@ -123,9 +141,9 @@
 
 -- | Write the dirtiness cache for this package's files.
 writeBuildCache :: (MonadIO m, MonadReader env m, MonadThrow m, HasEnvConfig env, MonadLogger m)
-                => Path Abs Dir -> Map FilePath FileCacheInfo -> m ()
-writeBuildCache dir times = do
-    fp <- buildCacheFile dir
+                => Path Abs Dir -> NamedComponent -> Map FilePath FileCacheInfo -> m ()
+writeBuildCache dir component times = do
+    fp <- buildCacheFile dir component
     $(versionedEncodeFile buildCacheVC) fp BuildCache
         { buildCacheTimes = times
         }
@@ -254,6 +272,14 @@
             PLRepo r -> Just $ T.unpack (repoCommit r) ++ repoSubdirs r
 
   forM mpkgRaw $ \pkgRaw -> do
+    platformRelDir <- platformGhcRelDir
+    let precompiledDir =
+              view stackRootL ec
+          </> $(mkRelDir "precompiled")
+          </> platformRelDir
+          </> compiler
+          </> cabal
+
     pkg <-
       case parseRelDir pkgRaw of
         Just x -> return x
@@ -263,7 +289,6 @@
                  $ B64URL.encode
                  $ TE.encodeUtf8
                  $ T.pack pkgRaw
-    platformRelDir <- platformGhcRelDir
 
     -- In Cabal versions 1.22 and later, the configure options contain the
     -- installed package IDs, which is what we need for a unique hash.
@@ -274,14 +299,18 @@
     hashPath <- parseRelFile $ S8.unpack $ B64URL.encode
               $ Mem.convert $ hashWith SHA256 $ Store.encode input
 
-    return $ view stackRootL ec
-         </> $(mkRelDir "precompiled")
-         </> platformRelDir
-         </> compiler
-         </> cabal
-         </> pkg
-         </> hashPath
+    let longPath = precompiledDir </> pkg </> hashPath
 
+    -- See #3649 - shorten the paths on windows if MAX_PATH will be
+    -- violated. Doing this only when necessary allows use of existing
+    -- precompiled packages.
+    if pathTooLong (toFilePath longPath) then do
+        shortPkg <- shaPath pkg
+        shortHash <- shaPath hashPath
+        return $ precompiledDir </> shortPkg </> shortHash
+    else
+        return longPath
+
 -- | Write out information about a newly built package
 writePrecompiledCache :: (MonadThrow m, MonadReader env m, HasEnvConfig env, MonadIO m, MonadLogger m)
                       => BaseConfigOpts
@@ -339,3 +368,20 @@
         { pcLibrary = mkAbs' <$> pcLibrary pc0
         , pcExes = mkAbs' <$> pcExes pc0
         }
+
+-- | Check if a filesystem path is too long.
+pathTooLong :: FilePath -> Bool
+#ifdef mingw32_HOST_OS
+pathTooLong path = utf16StringLength path >= win32MaxPath
+  where
+    win32MaxPath = 260
+    -- Calculate the length of a string in 16-bit units
+    -- if it were converted to utf-16.
+    utf16StringLength :: String -> Integer
+    utf16StringLength = sum . map utf16CharLength
+      where
+        utf16CharLength c | ord c < 0x10000 = 1
+                          | otherwise       = 2
+#else
+pathTooLong _ = False
+#endif
diff --git a/src/Stack/Build/Execute.hs b/src/Stack/Build/Execute.hs
--- a/src/Stack/Build/Execute.hs
+++ b/src/Stack/Build/Execute.hs
@@ -1372,7 +1372,8 @@
         case taskType of
             TTFiles lp _ -> do -- FIXME should this only be for local packages?
                 when enableTests $ unsetTestSuccess pkgDir
-                writeBuildCache pkgDir $ lpNewBuildCache lp
+                mapM_ (uncurry (writeBuildCache pkgDir))
+                      (Map.toList $ lpNewBuildCaches lp)
             TTIndex{} -> return ()
 
         -- FIXME: only output these if they're in the build plan.
@@ -1566,10 +1567,11 @@
             (lpPackage lp)
             (lpCabalFile lp)
             (lpComponents lp)
-            (lpNewBuildCache lp)
-    unless (null addBuildCache) $
-        writeBuildCache pkgDir $
-        Map.unions (lpNewBuildCache lp : addBuildCache)
+            (lpNewBuildCaches lp)
+    forM_ (M.toList addBuildCache) $ \(component, newToCache) -> do
+        let cache = Map.findWithDefault Map.empty component (lpNewBuildCaches lp)
+        writeBuildCache pkgDir component $
+            Map.unions (cache : newToCache)
     return warnings
 checkForUnlistedFiles TTIndex{} _ _ = return []
 
@@ -1732,6 +1734,8 @@
                 errs
                 (fmap fst mlogFile)
                 bs
+
+            setTestSuccess pkgDir
 
 -- | Implements running a package's benchmarks.
 singleBench :: HasEnvConfig env
diff --git a/src/Stack/Build/Source.hs b/src/Stack/Build/Source.hs
--- a/src/Stack/Build/Source.hs
+++ b/src/Stack/Build/Source.hs
@@ -265,28 +265,36 @@
         testpkg = resolvePackage testconfig gpkg
         benchpkg = resolvePackage benchconfig gpkg
 
-    mbuildCache <- tryGetBuildCache $ lpvRoot lpv
+    (componentFiles,_) <- getPackageFilesForTargets pkg (lpvCabalFP lpv) nonLibComponents
 
-    (files,_) <- getPackageFilesForTargets pkg (lpvCabalFP lpv) nonLibComponents
+    checkCacheResults <- forM (Map.toList componentFiles) $ \(component, files) -> do
+        mbuildCache <- tryGetBuildCache (lpvRoot lpv) component
+        checkCacheResult <- checkBuildCache
+            (fromMaybe Map.empty mbuildCache)
+            (Set.toList files)
+        return (component, checkCacheResult)
 
-    (dirtyFiles, newBuildCache) <- checkBuildCache
-        (fromMaybe Map.empty mbuildCache)
-        (Set.toList files)
+    let allDirtyFiles =
+            Set.unions $
+                map (\(_, (dirtyFiles, _)) -> dirtyFiles) checkCacheResults
+        newBuildCaches =
+            M.fromList $
+                map (\(c, (_, cache)) -> (c, cache)) checkCacheResults
 
     return LocalPackage
         { lpPackage = pkg
         , lpTestDeps = packageDeps testpkg
         , lpBenchDeps = packageDeps benchpkg
         , lpTestBench = btpkg
-        , lpFiles = files
+        , lpComponentFiles = componentFiles
         , lpForceDirty = boptsForceDirty bopts
         , lpDirtyFiles =
-            if not (Set.null dirtyFiles)
+            if not (Set.null allDirtyFiles)
                 then let tryStripPrefix y =
                           fromMaybe y (stripPrefix (toFilePath $ lpvRoot lpv) y)
-                      in Just $ Set.map tryStripPrefix dirtyFiles
+                      in Just $ Set.map tryStripPrefix allDirtyFiles
                 else Nothing
-        , lpNewBuildCache = newBuildCache
+        , lpNewBuildCaches = newBuildCaches
         , lpCabalFile = lpvCabalFP lpv
         , lpDir = lpvRoot lpv
         , lpWanted = isWanted
@@ -394,15 +402,18 @@
     -> Package
     -> Path Abs File
     -> Set NamedComponent
-    -> Map FilePath a
-    -> RIO env ([Map FilePath FileCacheInfo], [PackageWarning])
-addUnlistedToBuildCache preBuildTime pkg cabalFP nonLibComponents buildCache = do
-    (files,warnings) <- getPackageFilesForTargets pkg cabalFP nonLibComponents
-    let newFiles =
-            Set.toList $
-            Set.map toFilePath files `Set.difference` Map.keysSet buildCache
-    addBuildCache <- mapM addFileToCache newFiles
-    return (addBuildCache, warnings)
+    -> Map NamedComponent (Map FilePath a)
+    -> RIO env (Map NamedComponent [Map FilePath FileCacheInfo], [PackageWarning])
+addUnlistedToBuildCache preBuildTime pkg cabalFP nonLibComponents buildCaches = do
+    (componentFiles, warnings) <- getPackageFilesForTargets pkg cabalFP nonLibComponents
+    results <- forM (M.toList componentFiles) $ \(component, files) -> do
+        let buildCache = M.findWithDefault M.empty component buildCaches
+            newFiles =
+                Set.toList $
+                Set.map toFilePath files `Set.difference` Map.keysSet buildCache
+        addBuildCache <- mapM addFileToCache newFiles
+        return ((component, addBuildCache), warnings)
+    return (M.fromList (map fst results), concatMap snd results)
   where
     addFileToCache fp = do
         mmodTime <- getModTimeMaybe fp
@@ -420,16 +431,18 @@
 --   set of components.
 getPackageFilesForTargets
     :: HasEnvConfig env
-    => Package -> Path Abs File -> Set NamedComponent -> RIO env (Set (Path Abs File), [PackageWarning])
-getPackageFilesForTargets pkg cabalFP components = do
+    => Package
+    -> Path Abs File
+    -> Set NamedComponent
+    -> RIO env (Map NamedComponent (Set (Path Abs File)), [PackageWarning])
+getPackageFilesForTargets pkg cabalFP nonLibComponents = do
     (_,compFiles,otherFiles,warnings) <-
         getPackageFiles (packageFiles pkg) cabalFP
-    let filesForComponent cn = Set.map dotCabalGetPath
-                             $ M.findWithDefault mempty cn compFiles
-        files = Set.unions
-                $ otherFiles
-                : map filesForComponent (Set.toList $ Set.insert CLib components)
-    return (files, warnings)
+    let components = Set.insert CLib nonLibComponents
+        componentsFiles =
+            M.map (\files -> Set.union otherFiles (Set.map dotCabalGetPath files)) $
+                M.filterWithKey (\component _ -> component `Set.member` components) compFiles
+    return (componentsFiles, warnings)
 
 -- | Get file modification time, if it exists.
 getModTimeMaybe :: MonadIO m => FilePath -> m (Maybe ModTime)
diff --git a/src/Stack/Constants.hs b/src/Stack/Constants.hs
--- a/src/Stack/Constants.hs
+++ b/src/Stack/Constants.hs
@@ -1,6 +1,6 @@
 {-# LANGUAGE NoImplicitPrelude #-}
-{-# LANGUAGE TemplateHaskell #-}
 {-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE TemplateHaskell #-}
 
 -- | Constants used throughout the project.
 
diff --git a/src/Stack/Constants/Config.hs b/src/Stack/Constants/Config.hs
--- a/src/Stack/Constants/Config.hs
+++ b/src/Stack/Constants/Config.hs
@@ -9,7 +9,7 @@
   , projectDockerSandboxDir
   , configCacheFile
   , configCabalMod
-  , buildCacheFile
+  , buildCachesDir
   , testSuccessFile
   , testBuiltFile
   , hpcRelativeDir
@@ -32,13 +32,13 @@
       root = view projectRootL env
    in root </> workDir </> $(mkRelDir "odir/")
 
--- | The filename used for dirtiness check of source files.
-buildCacheFile :: (MonadThrow m, MonadReader env m, HasEnvConfig env)
+-- | The directory containing the files used for dirtiness check of source files.
+buildCachesDir :: (MonadThrow m, MonadReader env m, HasEnvConfig env)
                => Path Abs Dir      -- ^ Package directory.
-               -> m (Path Abs File)
-buildCacheFile dir =
+               -> m (Path Abs Dir)
+buildCachesDir dir = 
     liftM
-        (</> $(mkRelFile "stack-build-cache"))
+        (</> $(mkRelDir "stack-build-caches"))
         (distDirFromDir dir)
 
 -- | The filename used to mark tests as having succeeded
diff --git a/src/Stack/SDist.hs b/src/Stack/SDist.hs
--- a/src/Stack/SDist.hs
+++ b/src/Stack/SDist.hs
@@ -308,8 +308,8 @@
         , lpTestBench = Nothing
         , lpForceDirty = False
         , lpDirtyFiles = Nothing
-        , lpNewBuildCache = Map.empty
-        , lpFiles = Set.empty
+        , lpNewBuildCaches = Map.empty
+        , lpComponentFiles = Map.empty
         , lpComponents = Set.empty
         , lpUnbuildable = Set.empty
         , lpLocation = PLFilePath $ toFilePath pkgDir
diff --git a/src/Stack/Snapshot.hs b/src/Stack/Snapshot.hs
--- a/src/Stack/Snapshot.hs
+++ b/src/Stack/Snapshot.hs
@@ -482,7 +482,7 @@
 
           -- Put together the two split out groups of packages
           noLongerGlobals3 :: Map PackageName (LoadedPackageInfo SinglePackageLocation)
-          noLongerGlobals3 = Map.union (Map.mapWithKey globalToSnapshot noLongerGlobals1) noLongerGlobals2
+          noLongerGlobals3 = Map.mapWithKey globalToSnapshot (Map.union noLongerGlobals1 noLongerGlobals2)
 
           -- Now do the same thing with parent packages: take out the
           -- packages to be upgraded and then split out unmet
@@ -715,14 +715,14 @@
 splitUnmetDeps :: Map PackageName Version -- ^ extra dependencies available
                -> Map PackageName (LoadedPackageInfo loc)
                -> ( Map PackageName (LoadedPackageInfo loc)
-                  , Map PackageName (LoadedPackageInfo (PackageLocationIndex FilePath))
+                  , Map PackageName (LoadedPackageInfo loc)
                   )
 splitUnmetDeps extra =
     start Map.empty . Map.toList
   where
     start newGlobals0 toProcess0
       | anyAdded = start newGlobals1 toProcess1
-      | otherwise = (newGlobals1, Map.mapWithKey globalToSnapshot $ Map.fromList toProcess1)
+      | otherwise = (newGlobals1, Map.fromList toProcess1)
       where
         (newGlobals1, toProcess1, anyAdded) = loop False newGlobals0 id toProcess0
 
@@ -733,10 +733,35 @@
 
     depsMet globals = all (depsMet' globals) . Map.toList . lpiPackageDeps
 
-    depsMet' globals (name, intervals) =
+    -- MSS 2018-01-10. Previously, we would actually perform a version
+    -- bounds check at this point. I believe this is a mistake: we
+    -- don't want to promote a package from a snapshot to a local just
+    -- because the version ranges aren't satisfied. In fact, we
+    -- intentionally allow snapshots to specify mismatched versions of
+    -- packages, and try building anyway.
+    --
+    -- With the old behavior: a number of packages would be converted
+    -- and treated as local packages. I specifically stumbled on this
+    -- while investigating Stackage issues #3185, where a revision to
+    -- semigroupoids's tagged dependency caused the builds to
+    -- break. Stack should have just ignored this and printed a
+    -- warning. Instead, Stack believed that semigroupoids was a local
+    -- package, not a snapshot package, and failed.
+    --
+    -- All that said: I'm pretty certain this is the right behavior,
+    -- but all of this is strongly indicating that we need some code
+    -- cleanup around this promotion business. I don't think I did a
+    -- particularly good job on this code during the extensible
+    -- snapshot rewrite.
+    depsMet' globals (name, _intervals) =
       case (lpiVersion <$> Map.lookup name globals) <|> Map.lookup name extra of
+        -- The dependency doesn't exist at all in the snapshot or
+        -- extra, therefore this package must be promoted to local as
+        -- well.
         Nothing -> False
-        Just version -> version `withinIntervals` intervals
+        -- It exists. As explained above, don't bother checking the
+        -- version bounds, we trust the snapshot.
+        Just _version -> True
 
 -- | Calculate a 'LoadedPackageInfo' from the given 'GenericPackageDescription'
 calculate :: GenericPackageDescription
diff --git a/src/Stack/Types/Config.hs b/src/Stack/Types/Config.hs
--- a/src/Stack/Types/Config.hs
+++ b/src/Stack/Types/Config.hs
@@ -1,6 +1,6 @@
-{-# LANGUAGE NoImplicitPrelude #-}
-{-# LANGUAGE ConstraintKinds #-}
 {-# LANGUAGE CPP #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE DataKinds #-}
 {-# LANGUAGE DefaultSignatures #-}
 {-# LANGUAGE DeriveDataTypeable #-}
 {-# LANGUAGE DeriveFoldable #-}
@@ -9,17 +9,18 @@
 {-# LANGUAGE DeriveTraversable #-}
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE GADTs #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE MultiWayIf #-}
+{-# LANGUAGE NoImplicitPrelude #-}
 {-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE TemplateHaskell #-}
-{-# LANGUAGE TupleSections #-}
-{-# LANGUAGE TypeFamilies #-}
 {-# LANGUAGE RecordWildCards #-}
 {-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE DataKinds #-}
-{-# LANGUAGE GADTs #-}
 {-# LANGUAGE StandaloneDeriving #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TupleSections #-}
+{-# LANGUAGE TypeFamilies #-}
 
 -- | The Config type.
 
@@ -131,6 +132,7 @@
   ,platformGhcRelDir
   ,platformGhcVerOnlyRelDir
   ,useShaPathOnWindows
+  ,shaPath
   ,workDirL
   -- * Command-specific types
   -- ** Eval
@@ -176,6 +178,7 @@
   ) where
 
 import           Control.Monad.Writer (tell)
+import           Crypto.Hash (hashWith, SHA1(..))
 import           Stack.Prelude
 import           Data.Aeson.Extended
                  (ToJSON, toJSON, FromJSON, FromJSONKey (..), parseJSON, withText, object,
@@ -184,6 +187,7 @@
                   jsonSubWarningsT, jsonSubWarningsTT, WithJSONWarnings(..), noJSONWarnings,
                   FromJSONKeyFunction (FromJSONKeyTextParser))
 import           Data.Attoparsec.Args (parseArgs, EscapingMode (Escaping))
+import qualified Data.ByteArray.Encoding as Mem (convertToBase, Base(Base16))
 import qualified Data.ByteString.Char8 as S8
 import           Data.List (stripPrefix)
 import           Data.List.NonEmpty (NonEmpty)
@@ -231,11 +235,6 @@
 -- Re-exports
 import           Stack.Types.Config.Build as X
 
-#ifdef mingw32_HOST_OS
-import           Crypto.Hash (hashWith, SHA1(..))
-import qualified Data.ByteArray.Encoding as Mem (convertToBase, Base(Base16))
-#endif
-
 -- | The top-level Stackage configuration.
 data Config =
   Config {configStackRoot           :: !(Path Abs Dir)
@@ -1372,10 +1371,26 @@
 useShaPathOnWindows :: MonadThrow m => Path Rel Dir -> m (Path Rel Dir)
 useShaPathOnWindows =
 #ifdef mingw32_HOST_OS
-    parseRelDir . S8.unpack . S8.take 8 . Mem.convertToBase Mem.Base16 . hashWith SHA1 . encodeUtf8 . T.pack . toFilePath
+    shaPath
 #else
     return
 #endif
+
+shaPath :: (IsPath Rel t, MonadThrow m) => Path Rel t -> m (Path Rel t)
+shaPath
+    = parsePath . S8.unpack . S8.take 8
+    . Mem.convertToBase Mem.Base16 . hashWith SHA1
+    . encodeUtf8 . T.pack . toFilePath
+
+-- TODO: Move something like this into the path package. Consider
+-- subsuming path-io's 'AnyPath'?
+class IsPath b t where
+  parsePath :: MonadThrow m => FilePath -> m (Path b t)
+
+instance IsPath Abs Dir where parsePath = parseAbsDir
+instance IsPath Rel Dir where parsePath = parseRelDir
+instance IsPath Abs File where parsePath = parseAbsFile
+instance IsPath Rel File where parsePath = parseRelFile
 
 compilerVersionDir :: (MonadThrow m, MonadReader env m, HasEnvConfig env) => m (Path Rel Dir)
 compilerVersionDir = do
diff --git a/src/Stack/Types/Package.hs b/src/Stack/Types/Package.hs
--- a/src/Stack/Types/Package.hs
+++ b/src/Stack/Types/Package.hs
@@ -248,9 +248,9 @@
     -- ^ Nothing == not dirty, Just == dirty. Note that the Set may be empty if
     -- we forced the build to treat packages as dirty. Also, the Set may not
     -- include all modified files.
-    , lpNewBuildCache :: !(Map FilePath FileCacheInfo)
+    , lpNewBuildCaches :: !(Map NamedComponent (Map FilePath FileCacheInfo))
     -- ^ current state of the files
-    , lpFiles         :: !(Set (Path Abs File))
+    , lpComponentFiles :: !(Map NamedComponent (Set (Path Abs File)))
     -- ^ all files used by this package
     , lpLocation      :: !(PackageLocation FilePath)
     -- ^ Where this source code came from
@@ -302,6 +302,9 @@
 isCBench :: NamedComponent -> Bool
 isCBench CBench{} = True
 isCBench _ = False
+
+lpFiles :: LocalPackage -> Set.Set (Path Abs File)
+lpFiles = Set.unions . M.elems . lpComponentFiles
 
 -- | A location to install a package into, either snapshot or local
 data InstallLocation = Snap | Local
diff --git a/stack.cabal b/stack.cabal
--- a/stack.cabal
+++ b/stack.cabal
@@ -2,15 +2,15 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: ceb71155dcab7af0e6f88173046b55025b99819f514854c41d0a522b1d9edcd4
+-- hash: fb527fd6f73c61ffd0b8055991e9f777b12c9a6790e5939a1e46edc260201513
 
 name:           stack
-version:        1.6.3.1
+version:        1.6.5
 synopsis:       The Haskell Tool Stack
 description:    Please see the README.md for usage information, and the wiki on Github for more details.  Also, note that the API for the library is not currently stable, and may change significantly, even between minor releases. It is currently only intended for use by the executable.
 category:       Development
 homepage:       http://haskellstack.org
-bug-reports:    https://github.com/commercialhaskell/stack.git/issues
+bug-reports:    https://github.com/commercialhaskell/stack/issues
 author:         Commercial Haskell SIG
 maintainer:     manny@fpcomplete.com
 license:        BSD3
@@ -40,6 +40,7 @@
     doc/README.md
     doc/shell_autocompletion.md
     doc/SIGNING_KEY.md
+    doc/stack_yaml_vs_cabal_package_file.md
     doc/travis_ci.md
     doc/yaml_configuration.md
     package.yaml
@@ -52,7 +53,7 @@
 
 source-repository head
   type: git
-  location: https://github.com/commercialhaskell/stack.git
+  location: https://github.com/commercialhaskell/stack
 
 custom-setup
   setup-depends:
diff --git a/stack.yaml b/stack.yaml
--- a/stack.yaml
+++ b/stack.yaml
@@ -30,3 +30,6 @@
 - ansi-terminal-0.7.1.1
 - ansi-wl-pprint-0.6.8.1
 - smallcheck-1.1.3
+- archive: https://github.com/haskell/hackage-security/archive/3297b0f3f4285cb30321baaa7b54e3d22e1f6bd7.tar.gz
+  subdirs:
+  - hackage-security
