diff --git a/.hlint.yaml b/.hlint.yaml
new file mode 100644
--- /dev/null
+++ b/.hlint.yaml
@@ -0,0 +1,67 @@
+# HLint configuration file
+# https://github.com/ndmitchell/hlint
+##########################
+
+# This file contains a template configuration file, which is typically
+# placed as .hlint.yaml in the root of your project
+
+
+# Specify additional command line arguments
+#
+# - arguments: [--color, --cpp-simple, -XQuasiQuotes]
+
+
+# Control which extensions/flags/modules/functions can be used
+#
+# - extensions:
+#   - default: false # all extension are banned by default
+#   - name: [PatternGuards, ViewPatterns] # only these listed extensions can be used
+#   - {name: CPP, within: CrossPlatform} # CPP can only be used in a given module
+#
+# - flags:
+#   - {name: -w, within: []} # -w is allowed nowhere
+#
+# - modules:
+#   - {name: [Data.Set, Data.HashSet], as: Set} # if you import Data.Set qualified, it must be as 'Set'
+#   - {name: Control.Arrow, within: []} # Certain modules are banned entirely
+#
+# - functions:
+#   - {name: unsafePerformIO, within: []} # unsafePerformIO can only appear in no modules
+
+
+# Add custom hints for this project
+#
+# Will suggest replacing "wibbleMany [myvar]" with "wibbleOne myvar"
+# - error: {lhs: "wibbleMany [x]", rhs: wibbleOne x}
+
+# The hints are named by the string they display in warning messages.
+# For example, if you see a warning starting like
+#
+# Main.hs:116:51: Warning: Redundant ==
+#
+# You can refer to that hint with `{name: Redundant ==}` (see below).
+
+# Turn on hints that are off by default
+#
+# Ban "module X(module X) where", to require a real export list
+# - warn: {name: Use explicit module export list}
+#
+# Replace a $ b $ c with a . b $ c
+# - group: {name: dollar, enabled: true}
+#
+# Generalise map to fmap, ++ to <>
+# - group: {name: generalise, enabled: true}
+
+
+# Ignore some builtin hints
+# - ignore: {name: Use let}
+# - ignore: {name: Use const, within: SpecialModule} # Only within certain modules
+- ignore: {name: "Use lambda-case"}
+
+
+# Define some custom infix operators
+# - fixity: infixr 3 ~^#^~
+
+
+# To generate a suitable file for HLint do:
+# $ hlint --default > .hlint.yaml
diff --git a/src/Data/Tax/ATO.hs b/src/Data/Tax/ATO.hs
--- a/src/Data/Tax/ATO.hs
+++ b/src/Data/Tax/ATO.hs
@@ -146,7 +146,7 @@
   taxWithheld = to (foldMap (view taxWithheld))
 
 -- TODO part year spouse
-data SpouseDetails a = SpouseDetails
+newtype SpouseDetails a = SpouseDetails
   { _spouseTaxableIncome :: Money a
   -- TODO other fields
   }
@@ -442,8 +442,8 @@
 
     incomeForSurchargePurposes =
       taxable
-      <> mempty -- TODO reportable fringe benefits
-      <> mempty -- TODO net investment losses
+      -- TODO reportable fringe benefits
+      -- TODO net investment losses
       <> foldOf (paymentSummaries . traverse . to reportableEmployerSuperannuationContributions) info
 
     spouseIncomeForSurchargePurposes =
diff --git a/src/Data/Tax/ATO/Days.hs b/src/Data/Tax/ATO/Days.hs
--- a/src/Data/Tax/ATO/Days.hs
+++ b/src/Data/Tax/ATO/Days.hs
@@ -46,9 +46,9 @@
 type DaysInYear = KnownNat
 
 daysInYear :: KnownNat n => Proxy n -> Integer
-daysInYear proxy = case isLeapYear (natVal proxy) of
-  False -> 365
-  True  -> 366
+daysInYear proxy
+  | isLeapYear (natVal proxy) = 366
+  | otherwise                 = 365
 
 -- | Some number of days in a year.  Use 'days' to construct.
 newtype Days (n :: Year) = Days
diff --git a/src/Data/Tax/ATO/FY/FY2023.hs b/src/Data/Tax/ATO/FY/FY2023.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Tax/ATO/FY/FY2023.hs
@@ -0,0 +1,61 @@
+-- This file is part of hs-tax-ato
+-- Copyright (C) 2023  Fraser Tweedale
+--
+-- hs-tax-ato is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU Affero General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU Affero General Public License for more details.
+--
+-- You should have received a copy of the GNU Affero General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+{-# LANGUAGE DataKinds #-}
+
+-- | Tax tables for 2022–23 financial year.
+module Data.Tax.ATO.FY.FY2023 (tables) where
+
+import Data.Tax
+import Data.Tax.ATO.Common
+import qualified Data.Tax.ATO.FY.FY2022 as FY2022
+
+help :: (Fractional a, Ord a) => Tax (Money a) (Money a)
+help = thresholds'
+  [ (48361, 0.01)
+  , (55837, 0.01)
+  , (59187, 0.005)
+  , (62739, 0.005)
+  , (66503, 0.005)
+  , (70493, 0.005)
+  , (74723, 0.005)
+  , (79207, 0.005)
+  , (83959, 0.005)
+  , (88997, 0.005)
+  , (94337, 0.005)
+  , (99997, 0.005)
+  , (105997, 0.005)
+  , (112356, 0.005)
+  , (119098, 0.005)
+  , (126244, 0.005)
+  , (133819, 0.005)
+  , (141848, 0.005)
+  ]
+
+tables :: (Ord a, Fractional a) => TaxTables 2023 a
+tables = TaxTables
+  (ttIndividualIncomeTax FY2022.tables)
+
+  (medicareLevy (Money 24276))
+
+  medicareLevySurcharge
+  help
+  help
+
+  lowIncomeTaxOffset2021 -- LMITO ceased
+
+  -- https://www.health.gov.au/news/phi-circulars/phi-1023-private-health-insurance-rebate-adjustment-factor-effective-1-april-2023
+  (ttPHIRebateRates FY2022.tables)
diff --git a/tax-ato.cabal b/tax-ato.cabal
--- a/tax-ato.cabal
+++ b/tax-ato.cabal
@@ -1,21 +1,22 @@
+cabal-version:       2.2
 name:                tax-ato
-version:             2022.1
+version:             2023.1
 synopsis:            Tax types and computations for Australia
 description:
   This library provides types and tax computations for tax
   in Australia (ATO = /Australian Taxation Office/).  It is
   based on the <https://hackage.haskell.org/package/tax tax>
   library.
-license:             AGPL-3
+license:             AGPL-3.0-or-later
 license-file:        LICENSE
 author:              Fraser Tweedale
 maintainer:          frase@frase.id.au
-copyright:           Copyright (C) 2018 Fraser Tweedale
+copyright:           Copyright (C) 2018-2023 Fraser Tweedale
 category:            Finance
 build-type:          Simple
-cabal-version:       >=1.10
-tested-with:
-  GHC==7.10.3, GHC==8.0.2, GHC==8.2.1, GHC==8.4.3, GHC==8.6.1
+tested-with:         GHC ==8.10.7 || ==9.0.2 || ==9.2.7 || ==9.4.4 || ==9.6.1
+extra-source-files:
+  .hlint.yaml
 
 homepage:            https://github.com/frasertweedale/hs-tax-ato
 bug-reports:         https://github.com/frasertweedale/hs-tax-ato/issues
@@ -23,7 +24,39 @@
   type: git
   location: https://github.com/frasertweedale/hs-tax-ato.git
 
+common common
+  default-language: Haskell2010
+  ghc-options:
+    -Wall
+    -Wcompat
+    -Werror=missing-methods
+    -Widentities
+    -Wincomplete-record-updates
+    -Wincomplete-uni-patterns
+    -Wmissing-export-lists
+    -Wnoncanonical-monad-instances
+    -Wpartial-fields
+    -Wredundant-constraints
+    -Wunused-packages
+    -fhide-source-paths
+  if impl(ghc >= 9.0)
+    ghc-options:
+      -Winvalid-haddock
+      -Werror=unicode-bidirectional-format-characters
+  if impl(ghc >= 9.2)
+    ghc-options:
+      -Wimplicit-lift
+      -Woperator-whitespace
+      -Wredundant-bang-patterns
+  if impl(ghc >= 9.4)
+    ghc-options:
+      -Wredundant-strictness-flags
+  build-depends:
+    base >= 4.14 && < 5
+
 library
+  import: common
+  hs-source-dirs:      src
   exposed-modules:
     Data.Tax.ATO
     Data.Tax.ATO.CGT
@@ -37,15 +70,8 @@
     Data.Tax.ATO.FY.FY2020
     Data.Tax.ATO.FY.FY2021
     Data.Tax.ATO.FY.FY2022
-  -- other-modules:
-  -- other-extensions:
+    Data.Tax.ATO.FY.FY2023
   build-depends:
-    base >= 4.8 && < 5
-    , lens >= 4.12
-    , time >= 1.5
-    , tax >= 0.2
-  hs-source-dirs:      src
-  default-language:    Haskell2010
-  ghc-options: -Wall
-  if impl(ghc >= 8)
-    ghc-options: -Wredundant-constraints
+    , lens >= 4.12 && < 6
+    , time >= 1.5 && < 1.13
+    , tax >= 0.2 && < 0.3
