diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,16 @@
 # Release history for stack-all
 
+## 0.7 (2025-05-25)
+- complete rework of stack*.yaml config file logic
+- add --stack option to specify stack program (eg stack-2)
+- support "snapshot:" as well as "resolver:"
+- add -S,--make-all-lts flag (pbrisbin,#4)
+- bump default oldest major version from LTS 18 to 20
+- error for lts11 with stack > 3
+- fix --update-resolver for nightly snapshot
+- change --default-resolver short option from -d to -r
+- add ghc9.8 alias for lts23
+
 ## 0.6.4 (2024-10-13)
 - Fix the missing stack.yaml logic to first check for a .cabal file before
   trying parent directory
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -8,8 +8,7 @@
 ## Usage
 
 `stack-all` by default runs `stack build` over Stackage Nightly and
-LTS major versions
-(the current default range is nightly & major LTS versions back to lts-18)
+LTS major versions (the current default range is LTS versions back to lts-20)
 corresponding to latest major ghc minor versions,
 using appropriate stack `--resolver` options.
 
@@ -19,24 +18,26 @@
 Of course it may still fail to build, but this allows for quick attempts
 to build a package that does not include a stack.yaml file.
 
-Since 0.6, stack-all also works outside projects, like stack itself does.
+Since 0.6, stack-all also works outside projects, like stack itself does
+(for commands that do not need a project).
 
 ### Help output
 `$ stack-all --version`
 
 ```
-0.6.4
+0.7
 ```
 `$ stack-all --help`
 
 ```
 Build project over Stackage major versions
 
-Usage: stack-all [--version] [-k|--keep-going] [-D|--debug] [--refresh-cache] 
-                 [-n|--newest MAJOR] [(-o|--oldest MAJOR) | (-a|--all-lts)] 
-                 [(-c|--create-config) | (-d|--default-resolver MAJOR) | 
-                   (-u|--update-resolver) | (-s|--make-lts MAJOR) | 
-                   [MAJORVER... COMMAND...]]
+Usage: stack-all [--version] [-k|--keep-going] [-D|--debug] [--refresh-cache]
+                 [--stack STACKPROG] [-n|--newest MAJOR]
+                 [(-o|--oldest MAJOR) | (-a|--all-lts)]
+                 [(-c|--create-config) | (-r|--default-resolver MAJOR) |
+                   (-u|--update-resolver) | (-s|--make-lts MAJOR) |
+                   (-S|--make-all-lts) | [MAJORVER... COMMAND...]]
 
   https://github.com/juhp/stack-all#readme
 
@@ -46,14 +47,16 @@
   -k,--keep-going          Keep going even if an LTS fails
   -D,--debug               Verbose stack build output on error
   --refresh-cache          Force refresh of stackage snapshots.json cache
+  --stack STACKPROG        stack program [default: "stack"]
   -n,--newest MAJOR        Newest LTS release to build from
   -o,--oldest MAJOR        Oldest compatible LTS release
   -a,--all-lts             Try to build back to LTS 1 even
   -c,--create-config       Create a project .stack-all file
-  -d,--default-resolver MAJOR
+  -r,--default-resolver MAJOR
                            Set stack.yaml resolver
   -u,--update-resolver     Update stack.yaml resolver
   -s,--make-lts MAJOR      Create a stack-ltsXX.yaml file
+  -S,--make-all-lts        Create all stack-ltsXX.yaml files
 ```
 
 ### Overriding stack.yaml
@@ -63,11 +66,11 @@
 older LTS major versions until another `stack-ltsYY.yaml` file is found.
 `stack-nightly.yaml` is also supported, but used only for nightly.
 
-For example if you have `stack-lts20.yaml` and `stack-lts18.yaml` files
+For example if you have `stack-lts22.yaml` and `stack-lts20.yaml` files
 in your project,
-then `stack.yaml` will be used as normal to build nightly, lts-22 and lts-21,
-but `stack-lts20.yaml` will be used for building lts-20 and lts-19,
-and `stack-lts18.yaml` will be used for lts-18, lts-16 (and older).
+then `stack.yaml` will be used as normal to build nightly and lts-23,
+but `stack-lts22.yaml` will be used for building lts-22 and lts-21,
+and `stack-lts20.yaml` will be used for lts-20 (and older).
 Since `stack-all` overrides the exact resolver with the latest minor snapshot,
 the exact minor Stackage version specified in the `stack*.yaml` files
 doesn't actually matter: `stack-all` always uses the latest published
@@ -79,39 +82,47 @@
 (Other versioned stack.yaml filenames like stack-ghc-8.8.yaml
 are not currently supported.)
 
+If you wish you can create `stack-ltsXX.yaml` for all lts versions using
+`--make-all-lts` (`-S`), but it is recommended to create only needed files.
+
+Since 0.7, a `stack-ltsXX.yaml` conflicting (overlapping in major version)
+with `stack.yaml` gives an error, and stack-all will also refuse to generate
+such a file.
+
 ### Specifying LTS versions
 You can abbreviate `lts-XX` args to `ltsXX` on the commandline.
 `lts` is also accepted and resolves to the latest major LTS version.
 
-You can also use ghc major version aliases:
-eg `ghc9.6` corresponds to `lts22` or `ghc-9.2` to `lts-20`.
+You can also use (hardcoded) ghc major version aliases:
+eg `ghc9.8` corresponds to `lts23` or `ghc-9.2` to `lts-20`,
+though not for `nightly` currently.
 
 There are `--oldest`  and `--newest` options to specify the range of
 lts versions to build over:
 
-You can specify the oldest major LTS to build for with eg `stack-all -o lts16`.
-Otherwise if not configured the default oldest LTS is currently `lts-18`.
+You can specify the oldest major LTS to build for with eg `stack-all -o lts18`.
+Otherwise if not configured the default oldest LTS is currently `lts-20`.
 
 Similarly you can specify the newest LTS version to build from with
-eg `stack-all -n lts20`. (The default is to build from nightly.)
+eg `stack-all -n lts21`. (The default is to build from nightly.)
 
 Alternatively, one can give one or more explicit LTS major versions to build
-for as arguments: eg `stack-all lts19` if you only wish to build that version.
+for as arguments: eg `stack-all lts22` if you only wish to build that version.
 
 ### Configuring the oldest and/or newest LTS to build
 You can configure the oldest working LTS major version for your project
-by running for example `stack-all -c -o lts-19` which generates a `.stack-all`
+by running for example `stack-all -c -o lts-21` which generates a `.stack-all`
 project config file like this:
 ```
 [versions]
-# lts-18 too old
-oldest = lts-19
+# lts-20 too old
+oldest = lts-21
 ```
 (the comment line can be used to document why the older LTS doesn't work).
-This specifies that the oldest LTS version to build for is lts-19.
+This specifies that the oldest LTS version to build for is lts-21.
 
 The newest LTS to build with stack-all can similarly be configured:
-`stack-all -c -n lts21` or setting `newest = lts-21`.
+`stack-all -c -n lts22` or inserting `newest = lts-22`.
 
 ### Running other stack commands
 By default `stack-all` just runs the stack `build` command over
diff --git a/src/Main.hs b/src/Main.hs
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -1,16 +1,27 @@
-{-# LANGUAGE OverloadedStrings, CPP #-}
+{-# LANGUAGE BangPatterns, OverloadedStrings, CPP #-}
 
-import Control.Monad.Extra
+import Control.Monad.Extra (unless, unlessM, when, whenJustM, (||^))
 import Data.Either
 import Data.Ini.Config
-import Data.List.Extra
-import Data.Maybe
+import Data.List.Extra -- not explicit to avoid awkward CPP
+import Data.Maybe (fromMaybe, listToMaybe)
 import Data.Tuple (swap)
-import SimpleCmd
+import Data.Version.Extra
+import SimpleCmd ((+-+), cmdBool, cmd, cmd_, error',
+#if MIN_VERSION_simple_cmd(0,2,4)
+                  fileWithExtension
+#endif
+                 )
 import SimpleCmdArgs
-import System.Directory
+import System.Directory (copyFile, doesFileExist, getCurrentDirectory,
+#if !MIN_VERSION_simple_cmd(0,2,4)
+                         listDirectory,
+#endif
+                         setCurrentDirectory, withCurrentDirectory)
 import System.Exit
-import System.FilePath
+#if !MIN_VERSION_simple_cmd(0,2,4)
+import System.FilePath -- not explicit to avoid awkward CPP
+#endif
 import System.IO
 import System.Process
 import qualified Data.Text.IO as T
@@ -18,10 +29,10 @@
 import MajorVer
 import Paths_stack_all (version)
 import Snapshots
-import StackYaml (readStackYaml)
+import StackYaml
 
 defaultOldestLTS :: MajorVer
-defaultOldestLTS = LTS 18
+defaultOldestLTS = LTS 20
 
 data VersionLimit = DefaultLimit | Oldest MajorVer | AllVersions
 
@@ -29,6 +40,7 @@
              | SetDefaultResolver MajorVer
              | UpdateDefaultResolver
              | MakeStackLTS MajorVer
+             | MakeAllLTS
              | RunCmd [String]
   deriving Eq
 
@@ -41,22 +53,21 @@
     <$> switchWith 'k' "keep-going" "Keep going even if an LTS fails"
     <*> switchWith 'D' "debug" "Verbose stack build output on error"
     <*> switchLongWith "refresh-cache" "Force refresh of stackage snapshots.json cache"
+    <*> strOptionalLongWith "stack" "STACKPROG" "stack program to use" "stack"
     <*> optional (readMajor <$> strOptionWith 'n' "newest" "MAJOR" "Newest LTS release to build from")
     <*> (Oldest . readMajor <$> strOptionWith 'o' "oldest" "MAJOR" "Oldest compatible LTS release" <|>
          flagWith DefaultLimit AllVersions 'a' "all-lts" "Try to build back to LTS 1 even")
     <*>
     (flagWith' CreateConfig 'c' "create-config" "Create a project .stack-all file" <|>
-     (SetDefaultResolver . readMajor <$> strOptionWith 'd' "default-resolver" "MAJOR" ("Set" +-+ stackYaml +-+ "resolver")) <|>
+     (SetDefaultResolver . readMajor <$> strOptionWith 'r' "default-resolver" "MAJOR" ("Set" +-+ stackYaml +-+ "resolver")) <|>
      flagWith' UpdateDefaultResolver 'u' "update-resolver" ("Update" +-+ stackYaml +-+ "resolver") <|>
      (MakeStackLTS . readMajor <$> strOptionWith 's' "make-lts" "MAJOR" "Create a stack-ltsXX.yaml file") <|>
+     flagWith' MakeAllLTS 'S' "make-all-lts" "Create all stack-ltsXX.yaml files" <|>
      RunCmd <$> many (strArg "MAJORVER... COMMAND..."))
 
-stackYaml :: FilePath
-stackYaml = "stack.yaml"
-
-run :: Bool ->Bool -> Bool -> Maybe MajorVer -> VersionLimit -> Command
-    -> IO ()
-run keepgoing debug refresh mnewest verlimit com = do
+run :: Bool ->Bool -> Bool -> FilePath -> Maybe MajorVer -> VersionLimit
+    -> Command -> IO ()
+run keepgoing debug refresh stack mnewest verlimit com = do
   whenJustM findStackProjectDir setCurrentDirectory
   case com of
     CreateConfig ->
@@ -65,12 +76,15 @@
         _ -> createStackAll Nothing mnewest
     SetDefaultResolver ver -> stackDefaultResolver $ Just ver
     UpdateDefaultResolver -> stackDefaultResolver Nothing
-    MakeStackLTS ver -> makeStackLTS refresh ver
+    MakeStackLTS ver -> makeStackLTS False refresh ver
+    MakeAllLTS -> do
+      vers <- determineVersions mnewest verlimit []
+      mapM_ (makeStackLTS (length vers > 1) refresh) vers
     RunCmd verscmd -> do
-      (versions, cargs) <- getVersionsCmd verscmd
+      (versions, cargs) <- getVersionsAndCmd verscmd
       configs <- readStackConfigs
-      let newestFilter = maybe id (filter . (>=)) mnewest
-      mapM_ (runStack configs keepgoing debug refresh $ if null cargs then ["build"] else cargs) (newestFilter versions)
+      let finalvers = maybe id (filter . (>=)) mnewest versions
+      mapM_ (runStack configs keepgoing debug refresh stack $ if null cargs then ["build"] else cargs) finalvers
   where
     findStackProjectDir :: IO (Maybe FilePath)
     findStackProjectDir = do
@@ -88,7 +102,7 @@
           putStrLn $ "creating" +-+ stackYaml +-+ "in" +-+ cwdir
           -- FIXME take suggested extra-deps into stack.yaml
           -- FIXME stack init content too verbose
-          unlessM (cmdBool "stack" ["init"]) $ do
+          unlessM (cmdBool stack ["init"]) $ do
             snap <- latestLtsSnapshot refresh
             writeFile stackYaml $ "resolver: " ++ snap ++ "\n"
           return $ Just cwdir
@@ -99,50 +113,50 @@
           putStrLn "no package/project found"
           return Nothing
 
-    getVersionsCmd :: [String] -> IO ([MajorVer],[String])
-    getVersionsCmd verscmd = do
+    getVersionsAndCmd :: [String] -> IO ([MajorVer],[String])
+    getVersionsAndCmd verscmd = do
       let partitionMajors = swap . partitionEithers . map eitherReadMajorAlias
           (verlist,cmds) = partitionMajors verscmd
-      allMajors <- getMajorVers
-      versions <-
-        if null verlist then
+      versions <- determineVersions mnewest verlimit verlist
+      return (versions,cmds)
+
+inRange :: MajorVer -> MajorVer -> MajorVer -> Bool
+inRange newest oldest v = v >= oldest && v <= newest
+
+determineVersions :: Maybe MajorVer -> VersionLimit -> [MajorVerAlias]
+                  -> IO [MajorVer]
+determineVersions mnewest verlimit verlist = do
+        if null verlist then do
+          allMajors <- getMajorVers
           case verlimit of
             DefaultLimit -> do
-              (newestLTS, oldestLTS) <- readNewestOldestLTS
-              return $ case mnewest of
-                         Just newest ->
-                           if newest < oldestLTS
-                           then filter (inRange newest (LTS 1)) allMajors
-                           else filter (inRange newest oldestLTS) allMajors
-                         Nothing -> filter (inRange newestLTS oldestLTS) allMajors
+              (newestLTS, oldestLTS) <- readNewestOldestLTS mnewest
+              return $
+                case mnewest of
+                  Just newest ->
+                    if newest < oldestLTS
+                    then filter (inRange newest (LTS 1)) allMajors
+                    else filter (inRange newest oldestLTS) allMajors
+                  Nothing -> filter (inRange newestLTS oldestLTS) allMajors
             AllVersions -> return allMajors
-            Oldest ver -> return $ filter (inRange Nightly ver) allMajors
+            Oldest ver ->
+              return $
+              filter (inRange (fromMaybe Nightly mnewest) ver) allMajors
         else nub <$> mapM resolveMajor verlist
-      return (versions,cmds)
-      where
-        inRange :: MajorVer -> MajorVer -> MajorVer -> Bool
-        inRange newest oldest v = v >= oldest && v <= newest
 
-readStackConfigs :: IO [MajorVer]
-readStackConfigs = do
-  sort . mapMaybe readStackConf <$> listDirectory "."
-  where
-    readStackConf :: FilePath -> Maybe MajorVer
-    readStackConf "stack-lts.yaml" =
-      error' "unversioned stack-lts.yaml is unsupported"
-    readStackConf f =
-      stripPrefix "stack-" f >>= stripSuffix ".yaml" >>= readCompactMajor
-
-readNewestOldestLTS :: IO (MajorVer,MajorVer)
-readNewestOldestLTS = do
+readNewestOldestLTS :: Maybe MajorVer -> IO (MajorVer,MajorVer)
+readNewestOldestLTS mnewest = do
   haveConfig <- doesFileExist stackAllFile
   if haveConfig then
     readIniConfig stackAllFile $
     section "versions" $ do
-    mnewest <- fmap readMajor <$> fieldMbOf "newest" string
-    moldest <- fmap readMajor <$> fieldMbOf "oldest" string
-    return (fromMaybe Nightly mnewest, fromMaybe defaultOldestLTS moldest)
-    else return (Nightly, defaultOldestLTS)
+    mnewest' <-
+      case mnewest of
+        Nothing -> fmap readMajor <$> fieldMbOf "newest" string
+        _ -> return mnewest
+    moldest' <- fmap readMajor <$> fieldMbOf "oldest" string
+    return (fromMaybe Nightly mnewest', fromMaybe defaultOldestLTS moldest')
+    else return (fromMaybe Nightly mnewest, defaultOldestLTS)
   where
     readIniConfig :: FilePath -> IniParser a -> IO a
     readIniConfig inifile iniparser = do
@@ -175,71 +189,90 @@
                 in maybe "" (\s -> showMajor s ++ " too old") molder
           in "# " ++ older ++ "\noldest = " ++ showMajor oldest ++ "\n"
 
+updateResolver :: String -> FilePath -> IO ()
+updateResolver snapshot stackfile =
+  cmd_ "sed" ["-i", "-e", "s/\\(resolver:\\|snapshot:\\) .*/\\1 " ++ snapshot ++ "/", stackfile]
+
 stackDefaultResolver :: Maybe MajorVer -> IO ()
 stackDefaultResolver mver = do
   unlessM (doesFileExist stackYaml) $
     error' $ "no" +-+ stackYaml +-+ "present"
   case mver of
     Nothing -> do
-      mdef <- readStackYaml stackYaml
+      mdef <- readDefaultStackYaml
       case mdef of
         Nothing -> error' $ "could not determine major version of" +-+ stackYaml
         Just ver -> stackDefaultResolver $ Just ver
     Just ver ->
       whenJustM (latestMajorSnapshot False ver) $ \latest ->
-      cmd_ "sed" ["-i", "-e", "s/\\(resolver:\\) .*/\\1 " ++ latest ++ "/", stackYaml]
+      updateResolver latest stackYaml
 
-makeStackLTS :: Bool -> MajorVer -> IO ()
-makeStackLTS refresh ver = do
+makeStackLTS :: Bool -> Bool -> MajorVer -> IO ()
+makeStackLTS multiple refresh ver = do
   configs <- readStackConfigs
-  let newfile = configFile ver
-  if ver `elem` configs
-    then do
-    error' $ newfile ++ " already exists!"
-    else do
-    let mcurrentconfig = find (ver <=) (delete Nightly configs)
-    case mcurrentconfig of
-      Nothing -> copyFile stackYaml newfile
-      Just conf -> do
-        let origfile = configFile conf
-        copyFile origfile newfile
-    whenJustM (latestMajorSnapshot refresh ver) $ \latest ->
-      cmd_ "sed" ["-i", "-e", "s/\\(resolver:\\) .*/\\1 " ++ latest ++ "/", newfile]
-
-configFile :: MajorVer -> FilePath
-configFile ver = "stack-" ++ showCompact ver <.> "yaml"
+  case filter (isVersion ver) configs of
+    [] -> do
+      let newfile = configFile $ Config ver
+          mcurrentconfig = find ((ver <) . configVersion) configs
+      when multiple $ putStrLn $ "creating" +-+ newfile
+      case mcurrentconfig of
+        Nothing -> copyFile stackYaml newfile
+        Just conf -> do
+          let origfile = configFile conf
+          copyFile origfile newfile
+      whenJustM (latestMajorSnapshot refresh ver) $ \latest ->
+        updateResolver latest newfile
+    [c] ->
+      let msg =
+            configFile c +-+ "already" +-+
+            case c of
+              Config _ -> "exists"
+              ConfigDefault v -> "has" +-+ showMajor v
+      in if multiple
+         then putStrLn msg
+         else error' $ msg ++ "!"
+    cs ->
+      (if multiple then putStrLn else error') $ "overlapping major versions:" +-+
+      unwords (map configFile cs)
 
-runStack :: [MajorVer] -> Bool -> Bool -> Bool -> [String]
-           -> MajorVer -> IO ()
-runStack configs keepgoing debug refresh command ver = do
-  let mcfgver =
-        case ver of
-          Nightly | Nightly `elem` configs -> Just Nightly
-          _ ->
-            case sort (filter (ver <=) (delete Nightly configs)) of
+runStack :: [ConfigVersion] -> Bool -> Bool -> Bool -> FilePath -> [String]
+         -> MajorVer -> IO ()
+runStack configs keepgoing debug refresh stack command ver = do
+  -- FIXME add --stack or STACK envvar or look for stack-<VERSION>
+  when (ver <= LTS 11) $ do
+    stackver <- readVersion <$> cmd stack ["--numeric-version"]
+    when (stackver >= makeVersion [3]) $
+      error' $ "stack-" ++ showVersion stackver +-+ "no longer supports lts < 12"
+  let !mconfig =
+        case filter (isVersion ver) configs of
+          [] ->
+            case sort (filter (Config ver <) $ delete (Config Nightly) configs) of
               [] -> Nothing
-              (cfg:_) -> Just cfg
+              (c:_) -> nonDefaultConfig c
+          [c] -> nonDefaultConfig c
+          cs -> error' $ "overlapping major versions:" +-+
+                unwords (map configFile cs)
   latest <- latestMajorSnapshot refresh ver
   case latest of
     Nothing -> error' $ "no snapshot not found for " ++ showMajor ver
     Just minor -> do
       let opts = ["-v" | debug] ++ ["--resolver", minor] ++
-                 maybe [] (\f -> ["--stack-yaml", configFile f]) mcfgver
+                 maybe [] (\f -> ["--stack-yaml", configFile f]) mconfig
       putStrLn $ "# " ++ minor
       if debug
         then debugBuild $ opts ++ command
         else do
-        ok <- cmdBool "stack" $ opts ++ command
+        ok <- cmdBool stack $ opts ++ command
         unless (ok || keepgoing) $ do
           putStr "\nsnapshot-pkg-db: "
-          cmd_ "stack" $ "--silent" : opts ++ ["path", "--snapshot-pkg-db"]
+          cmd_ stack $ "--silent" : opts ++ ["path", "--snapshot-pkg-db"]
           error' $ "failed for " ++ showMajor ver
       putStrLn ""
   where
     debugBuild :: [String] -> IO ()
     debugBuild args = do
-      putStr $ "stack " ++ unwords args
-      (ret,out,err) <- readProcessWithExitCode "stack" args ""
+      putStr $ stack +-+ unwords args
+      (ret,out,err) <- readProcessWithExitCode stack args ""
       putStrLn "\n"
       unless (null out) $ putStrLn out
       unless (ret == ExitSuccess) $ do
@@ -249,6 +282,12 @@
 
 
 #if !MIN_VERSION_simple_cmd(0,2,4)
+#if !MIN_VERSION_filepath(1,4,2)
+isExtensionOf :: String -> FilePath -> Bool
+isExtensionOf ext@('.':_) = isSuffixOf ext . takeExtensions
+isExtensionOf ext         = isSuffixOf ('.':ext) . takeExtensions
+#endif
+
 filesWithExtension :: FilePath -- directory
                    -> String   -- file extension
                    -> IO [FilePath]
@@ -274,9 +313,3 @@
   case mf of
     Nothing -> return False
     Just f -> doesFileExist f
-
-#if !MIN_VERSION_filepath(1,4,2)
-isExtensionOf :: String -> FilePath -> Bool
-isExtensionOf ext@('.':_) = isSuffixOf ext . takeExtensions
-isExtensionOf ext         = isSuffixOf ('.':ext) . takeExtensions
-#endif
diff --git a/src/MajorVer.hs b/src/MajorVer.hs
--- a/src/MajorVer.hs
+++ b/src/MajorVer.hs
@@ -10,23 +10,33 @@
   )
 where
 
+import Data.Char (isDigit)
 import Data.List.Extra
+import Numeric.Natural (Natural)
 import SimpleCmd (error')
 import Text.Read (readMaybe)
 
 -- FIXME allow specific snapshots?
-data MajorVer = LTS Int | LTSLatest | Nightly
+data MajorVer = LTS Natural | Nightly
   deriving (Eq, Ord)
 
 maybeReadMajor :: String -> Maybe MajorVer
-maybeReadMajor "nightly" = Just Nightly
 maybeReadMajor ver
+  | "nightly" `isPrefixOf` ver =
+      case dropPrefix "-" $ dropPrefix "nightly" ver of
+        "" -> Just Nightly
+        ds ->
+          if all (\d -> isDigit d || d == '-') ds
+          then Just Nightly
+          else Nothing
+maybeReadMajor ver
   | "lts" `isPrefixOf` ver =
       case readMaybe (dropPrefix "-" (dropPrefix "lts" ver)) of
         Just major -> Just (LTS major)
         Nothing -> Nothing
   | "ghc" `isPrefixOf` ver =
       case dropPrefix "-" (dropPrefix "ghc" ver) of
+        "9.8" -> Just (LTS 23)
         "9.6" -> Just (LTS 22)
         "9.4" -> Just (LTS 21)
         "9.2" -> Just (LTS 20)
@@ -45,15 +55,14 @@
 -- readMajor "lts-16"
 readMajor :: String -> MajorVer
 readMajor "nightly" = Nightly
-readMajor "lts" = LTSLatest
 readMajor ver =
   case maybeReadMajor ver of
     Just s -> s
     Nothing ->
-      error' $! "couldn't parse " ++ ver ++ " (expected lts-XX, ltsXX, ghc-X.Y or ghcX.Y)"
+      error' $! "couldn't parse " ++ ver ++ " (expected lts*, nightly*, ghc-X.Y or ghcX.Y)"
 
 -- readCompactMajor "lts16"
--- Should we support "stack-lts.yaml"?
+-- Should we support stack-lts.yaml or even stack-<minor>.yaml?
 readCompactMajor :: String -> Maybe MajorVer
 readCompactMajor "nightly" = Just Nightly
 readCompactMajor ver =
@@ -65,7 +74,6 @@
 
 showMajor :: MajorVer -> String
 showMajor Nightly = "nightly"
-showMajor LTSLatest = "lts"
 showMajor (LTS ver) = "lts-" ++ show ver
 
 showCompact :: MajorVer -> String
diff --git a/src/StackYaml.hs b/src/StackYaml.hs
--- a/src/StackYaml.hs
+++ b/src/StackYaml.hs
@@ -1,14 +1,88 @@
 {-# LANGUAGE OverloadedStrings #-}
 
-module StackYaml (readStackYaml)
+module StackYaml (
+  readDefaultStackYaml,
+  stackYaml,
+  readStackConfigs,
+  ConfigVersion(..),
+  configVersion,
+  configFile,
+  isVersion,
+  nonDefaultConfig
+  )
 where
 
+import Control.Applicative ((<|>))
+import Control.Monad.Extra (mapMaybeM, unless)
+import Data.List.Extra
+import Data.Maybe (mapMaybe)
 import Data.Yaml (decodeFileThrow)
 import Network.HTTP.Query (lookupKey)
+import SimpleCmd ((+-+))
+import System.Directory (listDirectory)
+import System.FilePath ((<.>))
 
-import MajorVer (MajorVer, snapMajorVer)
+import MajorVer (MajorVer, readCompactMajor, showCompact, showMajor,
+                 snapMajorVer)
 
-readStackYaml :: FilePath -> IO (Maybe MajorVer)
-readStackYaml file = do
+stackYaml :: FilePath
+stackYaml = "stack.yaml"
+
+data ConfigVersion = Config MajorVer | ConfigDefault MajorVer
+  deriving Eq
+
+instance Ord ConfigVersion where
+  compare (Config v1) (Config v2) = compare v1 v2
+  compare (ConfigDefault v1) (Config v2) = compare v1 v2
+  compare (Config v1) (ConfigDefault v2) = compare v1 v2
+  compare (ConfigDefault v1) (ConfigDefault v2) = compare v1 v2
+
+isVersion :: MajorVer -> ConfigVersion -> Bool
+isVersion v cfg = configVersion cfg == v
+
+nonDefaultConfig :: ConfigVersion -> Maybe ConfigVersion
+nonDefaultConfig (ConfigDefault _) = Nothing
+nonDefaultConfig c = Just c
+
+configVersion :: ConfigVersion -> MajorVer
+configVersion (Config v) = v
+configVersion (ConfigDefault v) = v
+
+configFile :: ConfigVersion -> FilePath
+configFile (ConfigDefault _) = stackYaml
+configFile (Config ver) = "stack-" ++ showCompact ver <.> "yaml"
+
+data ConfigFile = ConfigFileDefault | ConfigFile MajorVer
+
+-- FIXME error "unversioned stack-lts.yaml is unsupported"
+readConfigFile :: FilePath -> Maybe ConfigFile
+readConfigFile file =
+  if file == stackYaml
+  then Just ConfigFileDefault
+  else
+    ConfigFile <$>
+    (stripPrefix "stack-" file >>= stripSuffix ".yaml" >>= readCompactMajor)
+
+readStackYamlFile :: FilePath -> IO (Maybe MajorVer)
+readStackYamlFile file = do
   yaml <- decodeFileThrow file
-  return $ snapMajorVer <$> lookupKey "resolver" yaml
+  return $ snapMajorVer <$>
+    (lookupKey "resolver" yaml <|> lookupKey "snapshot" yaml)
+
+readDefaultStackYaml :: IO (Maybe MajorVer)
+readDefaultStackYaml = readStackYamlFile stackYaml
+
+readStackYaml :: ConfigFile -> IO (Maybe ConfigVersion)
+readStackYaml ConfigFileDefault =
+  fmap ConfigDefault <$> readDefaultStackYaml
+readStackYaml (ConfigFile ver) = do
+  let file = configFile $ Config ver
+  mactual <- readStackYamlFile file
+  unless (mactual == Just ver) $
+    putStrLn $ configFile (Config ver) +-+ "has" +-+ maybe "undefined" showMajor mactual +-+ "resolver"
+  return $ Just $ Config ver
+
+readStackConfigs :: IO [ConfigVersion]
+readStackConfigs =
+  listDirectory "." >>=
+  fmap sort . mapMaybeM readStackYaml . mapMaybe readConfigFile
diff --git a/stack-all.cabal b/stack-all.cabal
--- a/stack-all.cabal
+++ b/stack-all.cabal
@@ -1,5 +1,5 @@
 name:                stack-all
-version:             0.6.4
+version:             0.7
 synopsis:            CLI tool for building over Stackage major versions
 description:
         Stack-all is a tool for stack building of a Haskell project
@@ -8,7 +8,7 @@
 license-file:        LICENSE
 author:              Jens Petersen <juhpetersen@gmail.com>
 maintainer:          Jens Petersen <juhpetersen@gmail.com>
-copyright:           2020-2024  Jens Petersen <juhpetersen@gmail.com>
+copyright:           2020-2025  Jens Petersen <juhpetersen@gmail.com>
 category:            Distribution
 homepage:            https://github.com/juhp/stack-all
 bug-reports:         https://github.com/juhp/stack-all/issues
@@ -18,7 +18,7 @@
 cabal-version:       1.18
 tested-with:         GHC == 8.0.2, GHC == 8.2.2, GHC == 8.4.4, GHC == 8.6.5,
                      GHC == 8.8.4, GHC == 8.10.7, GHC == 9.0.2, GHC == 9.2.8,
-                     GHC == 9.4.8, GHC == 9.6.6, GHC == 9.8.2
+                     GHC == 9.4.8, GHC == 9.6.7, GHC == 9.8.4, GHC == 9.10.2
 
 source-repository head
   type:                git
