diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,10 @@
-## [_Unreleased_](https://github.com/freckle/stackctl/compare/v1.1.0.1...main)
+## [_Unreleased_](https://github.com/freckle/stackctl/compare/v1.1.0.2...main)
+
+## [v1.1.0.2](https://github.com/freckle/stackctl/compare/v1.1.0.1...v1.1.0.2)
+
+- Log responses from `awsLambdaInvoke` when running actions
+- Clarify discovery logging
+- Add install script
 
 ## [v1.1.0.1](https://github.com/freckle/stackctl/compare/v1.1.0.0...v1.1.0.1)
 
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -16,31 +16,48 @@
 
 ## Install
 
-### Binary install
+### Pre-requisites
 
-Go to the [latest release][latest] and download the `.tar.gz` asset appropriate
-for your OS. Navigate to the directory containing the downloaded file and run:
+- Have `~/.local/bin` on your `$PATH`
+- Have `~/.local/share/man` on your `$MANPATH` (for documentation)
+- If on OSX, `brew install coreutils` (i.e. have `ginstall` available)
 
+### Scripted
+
 ```console
-tar xvf stackctl-*.tar.gz && cd stackctl
+curl -L https://raw.githubusercontent.com/freckle/stackctl/main/install | bash
 ```
 
-[latest]: https://github.com/freckle/stackctl/releases/latest
+**NOTE**: some in the community have expressed [concerns][curlsh-bad] about the
+security of so-called "curl-sh" installations. We think the argument has been
+[pretty well debunked][curlsh-ok], but feel free to use the manual steps
+instead.
 
-#### Global installation
+[curlsh-bad]: https://0x46.net/thoughts/2019/04/27/piping-curl-to-shell/
+[curlsh-ok]: https://www.arp242.net/curl-to-sh.html
 
-Install into `/usr/local/`, with appropriate permissions:
+### Manual
 
+Go to the [latest release][latest] and download the `.tar.gz` asset appropriate
+for your OS. Navigate to the directory containing the downloaded file and run:
+
+[latest]: https://github.com/freckle/stackctl/releases/latest
+
 ```console
-sudo make install
+tar xvf stackctl-*.tar.gz
+cd stackctl
 ```
 
-#### User installation
+User installation:
 
-Set `PREFIX` to base the installation in a directory of your choosing:
+```console
+make install PREFIX="$HOME/.local"
+```
 
+Global installation
+
 ```console
-make install PREFIX=$HOME/.local
+sudo make install
 ```
 
 ## Usage
diff --git a/src/Stackctl/AWS/Lambda.hs b/src/Stackctl/AWS/Lambda.hs
--- a/src/Stackctl/AWS/Lambda.hs
+++ b/src/Stackctl/AWS/Lambda.hs
@@ -16,14 +16,19 @@
 import Stackctl.AWS.Core
 
 data LambdaInvokeResult
-  = LambdaInvokeSuccess
+  = LambdaInvokeSuccess ByteString
   | LambdaInvokeError LambdaError (Maybe Text)
   | LambdaInvokeFailure Int (Maybe Text)
   deriving stock Show
 
 logLambdaInvocationResult :: MonadLogger m => LambdaInvokeResult -> m ()
 logLambdaInvocationResult = \case
-  LambdaInvokeSuccess -> logInfo "LambdaInvokeSuccess"
+  LambdaInvokeSuccess bs -> do
+    let
+      meta = case decode @Value $ BSL.fromStrict bs of
+        Nothing -> ["response" .= decodeUtf8 bs]
+        Just response -> ["response" .= response]
+    logInfo $ "LambdaInvokeSuccess" :# meta
   LambdaInvokeError LambdaError {..} mFunctionError ->
     logError $ (:# []) $ mconcat
       [ "LambdaInvokeError"
@@ -41,7 +46,7 @@
 
 isLambdaInvocationSuccess :: LambdaInvokeResult -> Bool
 isLambdaInvocationSuccess = \case
-  LambdaInvokeSuccess -> True
+  LambdaInvokeSuccess{} -> True
   LambdaInvokeError{} -> False
   LambdaInvokeFailure{} -> False
 
@@ -72,6 +77,7 @@
     status = resp ^. invokeResponse_statusCode
     mError = decode . BSL.fromStrict =<< resp ^. invokeResponse_payload
     mFunctionError = resp ^. invokeResponse_functionError
+    response = fromMaybe "" $ resp ^. invokeResponse_payload
 
   logDebug
     $ "Function result"
@@ -84,7 +90,7 @@
   pure $ if
     | statusIsUnsuccessful status -> LambdaInvokeFailure status mFunctionError
     | Just e <- mError            -> LambdaInvokeError e mFunctionError
-    | otherwise                   -> LambdaInvokeSuccess
+    | otherwise                   -> LambdaInvokeSuccess response
 
 statusIsUnsuccessful :: Int -> Bool
 statusIsUnsuccessful s = s < 200 || s >= 300
diff --git a/src/Stackctl/Action.hs b/src/Stackctl/Action.hs
--- a/src/Stackctl/Action.hs
+++ b/src/Stackctl/Action.hs
@@ -71,8 +71,8 @@
     InvokeLambdaByName name -> "InvokeLambdaByName" .= name
 
 data ActionFailure
-  = NoSuchOutput StackName Text [Output]
-  | InvokeLambdaFailure LambdaInvokeResult
+  = NoSuchOutput
+  | InvokeLambdaFailure
   deriving stock Show
   deriving anyclass Exception
 
@@ -100,15 +100,21 @@
     InvokeLambdaByStackOutput outputName -> do
       outputs <- awsCloudFormationDescribeStackOutputs stackName
       case findOutputValue outputName outputs of
-        Nothing -> throwIO $ NoSuchOutput stackName outputName outputs
+        Nothing -> do
+          logError
+            $ "Output not found"
+            :# [ "stackName" .= stackName
+               , "desiredOutput" .= outputName
+               , "availableOutputs" .= map (^. output_outputKey) outputs
+               ]
+          throwIO NoSuchOutput
         Just name -> invoke name
     InvokeLambdaByName name -> invoke name
  where
   invoke name = do
     result <- awsLambdaInvoke name payload
     logLambdaInvocationResult result
-    unless (isLambdaInvocationSuccess result) $ throwIO $ InvokeLambdaFailure
-      result
+    unless (isLambdaInvocationSuccess result) $ throwIO InvokeLambdaFailure
 
   payload = object ["stack" .= stackName, "event" .= on]
 
diff --git a/src/Stackctl/Spec/Discover.hs b/src/Stackctl/Spec/Discover.hs
--- a/src/Stackctl/Spec/Discover.hs
+++ b/src/Stackctl/Spec/Discover.hs
@@ -52,21 +52,21 @@
   filterOption <- view filterOptionL
 
   let
-    filtered = filterFilePaths filterOption discovered
+    matched = filterFilePaths filterOption discovered
     toSpecPath = stackSpecPathFromFilePath scope
-    (errs, specPaths) = partitionEithers $ map toSpecPath filtered
+    (errs, specPaths) = partitionEithers $ map toSpecPath matched
 
     context =
       [ "path" .= dir
       , "filters" .= filterOption
       , "discovered" .= length discovered
-      , "filtered" .= length filtered
+      , "matched" .= length matched
       , "errors" .= length errs
       ]
 
   withThreadContext context $ do
     logDebug "Discovered specs"
-    when (null filtered) $ logWarn "No specs found"
+    when (null matched) $ logWarn "No specs found"
     checkForDuplicateStackNames specPaths
 
   sortStackSpecs <$> traverse (readStackSpec dir) specPaths
diff --git a/stackctl.cabal b/stackctl.cabal
--- a/stackctl.cabal
+++ b/stackctl.cabal
@@ -1,209 +1,166 @@
-cabal-version: 1.18
-
--- This file has been generated from package.yaml by hpack version 0.35.0.
---
--- see: https://github.com/sol/hpack
-
-name:           stackctl
-version:        1.1.0.1
-description:    Please see <https://github.com/freckle/stackctl#readme>
-homepage:       https://github.com/freckle/stackctl#readme
-bug-reports:    https://github.com/freckle/stackctl/issues
-author:         Freckle Engineering
-maintainer:     freckle-engineering@renaissance.com
-copyright:      2022 Renaissance Learning Inc
-license:        MIT
-license-file:   LICENSE
-build-type:     Simple
+cabal-version:   1.18
+name:            stackctl
+version:         1.1.0.2
+license:         MIT
+license-file:    LICENSE
+copyright:       2022 Renaissance Learning Inc
+maintainer:      freckle-engineering@renaissance.com
+author:          Freckle Engineering
+homepage:        https://github.com/freckle/stackctl#readme
+bug-reports:     https://github.com/freckle/stackctl/issues
+description:     Please see <https://github.com/freckle/stackctl#readme>
+build-type:      Simple
 extra-doc-files:
     README.md
     CHANGELOG.md
 
 source-repository head
-  type: git
-  location: https://github.com/freckle/stackctl
+    type:     git
+    location: https://github.com/freckle/stackctl
 
 library
-  exposed-modules:
-      Stackctl.Action
-      Stackctl.AWS
-      Stackctl.AWS.CloudFormation
-      Stackctl.AWS.Core
-      Stackctl.AWS.EC2
-      Stackctl.AWS.Lambda
-      Stackctl.AWS.Orphans
-      Stackctl.AWS.Scope
-      Stackctl.AWS.STS
-      Stackctl.CLI
-      Stackctl.ColorOption
-      Stackctl.Colors
-      Stackctl.Commands
-      Stackctl.DirectoryOption
-      Stackctl.FilterOption
-      Stackctl.Options
-      Stackctl.Prelude
-      Stackctl.Prompt
-      Stackctl.Spec.Capture
-      Stackctl.Spec.Cat
-      Stackctl.Spec.Changes
-      Stackctl.Spec.Changes.Format
-      Stackctl.Spec.Deploy
-      Stackctl.Spec.Discover
-      Stackctl.Spec.Generate
-      Stackctl.StackSpec
-      Stackctl.StackSpecPath
-      Stackctl.StackSpecYaml
-      Stackctl.Subcommand
-      Stackctl.VerboseOption
-      Stackctl.Version
-      UnliftIO.Exception.Lens
-  other-modules:
-      Paths_stackctl
-  hs-source-dirs:
-      src
-  default-extensions:
-      BangPatterns
-      DataKinds
-      DeriveAnyClass
-      DeriveFoldable
-      DeriveFunctor
-      DeriveGeneric
-      DeriveLift
-      DeriveTraversable
-      DerivingStrategies
-      DerivingVia
-      FlexibleContexts
-      FlexibleInstances
-      GADTs
-      GeneralizedNewtypeDeriving
-      LambdaCase
-      MultiParamTypeClasses
-      NoImplicitPrelude
-      NoMonomorphismRestriction
-      OverloadedStrings
-      RankNTypes
-      RecordWildCards
-      ScopedTypeVariables
-      StandaloneDeriving
-      TypeApplications
-      TypeFamilies
-  ghc-options: -fwrite-ide-info -Weverything -Wno-all-missed-specialisations -Wno-missing-import-lists -Wno-missing-local-signatures -Wno-missing-safe-haskell-mode -Wno-prepositive-qualified-module -Wno-unsafe -optP-Wno-nonportable-include-path
-  build-depends:
-      Blammo >=1.1.0.0
-    , Glob
-    , aeson
-    , aeson-casing
-    , aeson-pretty
-    , amazonka
-    , amazonka-cloudformation
-    , amazonka-core
-    , amazonka-ec2
-    , amazonka-lambda
-    , amazonka-sts
-    , base ==4.*
-    , bytestring
-    , cfn-flip >=0.1.0.3
-    , conduit
-    , containers
-    , errors
-    , exceptions
-    , extra
-    , fast-logger
-    , filepath
-    , lens
-    , lens-aeson
-    , monad-logger
-    , optparse-applicative
-    , resourcet
-    , rio
-    , text
-    , time
-    , unliftio
-    , unliftio-core
-    , unordered-containers
-    , uuid
-    , yaml
-  default-language: Haskell2010
+    exposed-modules:
+        Stackctl.Action
+        Stackctl.AWS
+        Stackctl.AWS.CloudFormation
+        Stackctl.AWS.Core
+        Stackctl.AWS.EC2
+        Stackctl.AWS.Lambda
+        Stackctl.AWS.Orphans
+        Stackctl.AWS.Scope
+        Stackctl.AWS.STS
+        Stackctl.CLI
+        Stackctl.ColorOption
+        Stackctl.Colors
+        Stackctl.Commands
+        Stackctl.DirectoryOption
+        Stackctl.FilterOption
+        Stackctl.Options
+        Stackctl.Prelude
+        Stackctl.Prompt
+        Stackctl.Spec.Capture
+        Stackctl.Spec.Cat
+        Stackctl.Spec.Changes
+        Stackctl.Spec.Changes.Format
+        Stackctl.Spec.Deploy
+        Stackctl.Spec.Discover
+        Stackctl.Spec.Generate
+        Stackctl.StackSpec
+        Stackctl.StackSpecPath
+        Stackctl.StackSpecYaml
+        Stackctl.Subcommand
+        Stackctl.VerboseOption
+        Stackctl.Version
+        UnliftIO.Exception.Lens
 
+    hs-source-dirs:     src
+    other-modules:      Paths_stackctl
+    default-language:   Haskell2010
+    default-extensions:
+        BangPatterns DataKinds DeriveAnyClass DeriveFoldable DeriveFunctor
+        DeriveGeneric DeriveLift DeriveTraversable DerivingStrategies
+        DerivingVia FlexibleContexts FlexibleInstances GADTs
+        GeneralizedNewtypeDeriving LambdaCase MultiParamTypeClasses
+        NoImplicitPrelude NoMonomorphismRestriction OverloadedStrings
+        RankNTypes RecordWildCards ScopedTypeVariables StandaloneDeriving
+        TypeApplications TypeFamilies
+
+    ghc-options:
+        -fwrite-ide-info -Weverything -Wno-all-missed-specialisations
+        -Wno-missing-import-lists -Wno-missing-local-signatures
+        -Wno-missing-safe-haskell-mode -Wno-prepositive-qualified-module
+        -Wno-unsafe -optP-Wno-nonportable-include-path
+
+    build-depends:
+        Blammo >=1.1.0.0,
+        Glob,
+        aeson,
+        aeson-casing,
+        aeson-pretty,
+        amazonka,
+        amazonka-cloudformation,
+        amazonka-core,
+        amazonka-ec2,
+        amazonka-lambda,
+        amazonka-sts,
+        base >=4 && <5,
+        bytestring,
+        cfn-flip >=0.1.0.3,
+        conduit,
+        containers,
+        errors,
+        exceptions,
+        extra,
+        fast-logger,
+        filepath,
+        lens,
+        lens-aeson,
+        monad-logger,
+        optparse-applicative,
+        resourcet,
+        rio,
+        text,
+        time,
+        unliftio,
+        unliftio-core,
+        unordered-containers,
+        uuid,
+        yaml
+
 executable stackctl
-  main-is: Main.hs
-  other-modules:
-      Paths_stackctl
-  hs-source-dirs:
-      app
-  default-extensions:
-      BangPatterns
-      DataKinds
-      DeriveAnyClass
-      DeriveFoldable
-      DeriveFunctor
-      DeriveGeneric
-      DeriveLift
-      DeriveTraversable
-      DerivingStrategies
-      DerivingVia
-      FlexibleContexts
-      FlexibleInstances
-      GADTs
-      GeneralizedNewtypeDeriving
-      LambdaCase
-      MultiParamTypeClasses
-      NoImplicitPrelude
-      NoMonomorphismRestriction
-      OverloadedStrings
-      RankNTypes
-      RecordWildCards
-      ScopedTypeVariables
-      StandaloneDeriving
-      TypeApplications
-      TypeFamilies
-  ghc-options: -fwrite-ide-info -Weverything -Wno-all-missed-specialisations -Wno-missing-import-lists -Wno-missing-local-signatures -Wno-missing-safe-haskell-mode -Wno-prepositive-qualified-module -Wno-unsafe -optP-Wno-nonportable-include-path -threaded -rtsopts -with-rtsopts=-N
-  build-depends:
-      base ==4.*
-    , stackctl
-  default-language: Haskell2010
+    main-is:            Main.hs
+    hs-source-dirs:     app
+    other-modules:      Paths_stackctl
+    default-language:   Haskell2010
+    default-extensions:
+        BangPatterns DataKinds DeriveAnyClass DeriveFoldable DeriveFunctor
+        DeriveGeneric DeriveLift DeriveTraversable DerivingStrategies
+        DerivingVia FlexibleContexts FlexibleInstances GADTs
+        GeneralizedNewtypeDeriving LambdaCase MultiParamTypeClasses
+        NoImplicitPrelude NoMonomorphismRestriction OverloadedStrings
+        RankNTypes RecordWildCards ScopedTypeVariables StandaloneDeriving
+        TypeApplications TypeFamilies
 
+    ghc-options:
+        -fwrite-ide-info -Weverything -Wno-all-missed-specialisations
+        -Wno-missing-import-lists -Wno-missing-local-signatures
+        -Wno-missing-safe-haskell-mode -Wno-prepositive-qualified-module
+        -Wno-unsafe -optP-Wno-nonportable-include-path -threaded -rtsopts
+        -with-rtsopts=-N
+
+    build-depends:
+        base >=4 && <5,
+        stackctl
+
 test-suite spec
-  type: exitcode-stdio-1.0
-  main-is: Spec.hs
-  other-modules:
-      Stackctl.AWS.CloudFormationSpec
-      Stackctl.FilterOptionSpec
-      Stackctl.StackSpecSpec
-      Stackctl.StackSpecYamlSpec
-      Paths_stackctl
-  hs-source-dirs:
-      test
-  default-extensions:
-      BangPatterns
-      DataKinds
-      DeriveAnyClass
-      DeriveFoldable
-      DeriveFunctor
-      DeriveGeneric
-      DeriveLift
-      DeriveTraversable
-      DerivingStrategies
-      DerivingVia
-      FlexibleContexts
-      FlexibleInstances
-      GADTs
-      GeneralizedNewtypeDeriving
-      LambdaCase
-      MultiParamTypeClasses
-      NoImplicitPrelude
-      NoMonomorphismRestriction
-      OverloadedStrings
-      RankNTypes
-      RecordWildCards
-      ScopedTypeVariables
-      StandaloneDeriving
-      TypeApplications
-      TypeFamilies
-  ghc-options: -fwrite-ide-info -Weverything -Wno-all-missed-specialisations -Wno-missing-import-lists -Wno-missing-local-signatures -Wno-missing-safe-haskell-mode -Wno-prepositive-qualified-module -Wno-unsafe -optP-Wno-nonportable-include-path
-  build-depends:
-      base ==4.*
-    , hspec
-    , stackctl
-    , yaml
-  default-language: Haskell2010
+    type:               exitcode-stdio-1.0
+    main-is:            Spec.hs
+    hs-source-dirs:     test
+    other-modules:
+        Stackctl.AWS.CloudFormationSpec
+        Stackctl.FilterOptionSpec
+        Stackctl.StackSpecSpec
+        Stackctl.StackSpecYamlSpec
+        Paths_stackctl
+
+    default-language:   Haskell2010
+    default-extensions:
+        BangPatterns DataKinds DeriveAnyClass DeriveFoldable DeriveFunctor
+        DeriveGeneric DeriveLift DeriveTraversable DerivingStrategies
+        DerivingVia FlexibleContexts FlexibleInstances GADTs
+        GeneralizedNewtypeDeriving LambdaCase MultiParamTypeClasses
+        NoImplicitPrelude NoMonomorphismRestriction OverloadedStrings
+        RankNTypes RecordWildCards ScopedTypeVariables StandaloneDeriving
+        TypeApplications TypeFamilies
+
+    ghc-options:
+        -fwrite-ide-info -Weverything -Wno-all-missed-specialisations
+        -Wno-missing-import-lists -Wno-missing-local-signatures
+        -Wno-missing-safe-haskell-mode -Wno-prepositive-qualified-module
+        -Wno-unsafe -optP-Wno-nonportable-include-path
+
+    build-depends:
+        base >=4 && <5,
+        hspec,
+        stackctl,
+        yaml
