diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml
index 30f2fd58..6c71eb9b 100644
--- a/.github/workflows/R-CMD-check.yaml
+++ b/.github/workflows/R-CMD-check.yaml
@@ -22,6 +22,7 @@ on:
       - 'LICENSE'
       - '.Rbuildignore'
       - '.github/workflows/R-CMD-check.yaml'
+  merge_group:
   pull_request:
     paths:
       - 'data/**'
@@ -85,6 +86,7 @@ jobs:
         id: rcmdcheck
         with:
           upload-snapshots: true
+          error-on: '"note"'
 
       # fail-fast but only if rcmdcheck step fails
       - name: Manual fail-fast
diff --git a/.github/workflows/dependency-change.yaml b/.github/workflows/dependency-change.yaml
new file mode 100644
index 00000000..1250c8a5
--- /dev/null
+++ b/.github/workflows/dependency-change.yaml
@@ -0,0 +1,75 @@
+# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples
+# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help
+on:
+  pull_request:
+    paths:
+      - 'DESCRIPTION'
+
+name: Analyze dependency changes
+
+concurrency:
+  group: ${{ github.workflow }}-${{ github.ref }}
+  cancel-in-progress: true
+
+permissions:
+  pull-requests: write
+
+jobs:
+  dependency-changes:
+    runs-on: ubuntu-latest
+    env:
+      GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
+    steps:
+      - name: Setup R
+        uses: r-lib/actions/setup-r@v2
+        with:
+          use-public-rspm: true
+
+      - name: Install dependencies
+        uses: r-lib/actions/setup-r-dependencies@v2
+        with:
+          packages: any::pak, glue, gh
+
+      - name: Analyze dependency changes
+        shell: Rscript {0}
+        run: |
+          deps_base <- pak::pkg_deps("${{ github.repository }}@${{ github.base_ref }}", dependencies = TRUE) |>
+            subset(!directpkg) |>
+            subset(is.na(priority))
+          # We install from PR number rather than branch to deal with the case
+          # of PR coming from forks
+          deps_head <- pak::pkg_deps("${{ github.repository }}#${{ github.event.number }}", dependencies = TRUE) |>
+            subset(!directpkg) |>
+            subset(is.na(priority))
+
+          deps_added <- deps_head |>
+            subset(!ref %in% deps_base$ref)
+
+          deps_removed <- deps_base |>
+            subset(!ref %in% deps_head$ref)
+
+          if (nrow(deps_added) + nrow(deps_removed) > 0) {
+
+            message("Dependencies have changed! Analyzing...")
+
+            msg <- glue::glue(
+              .sep = "\n",
+              "This pull request:",
+              "- Adds {nrow(deps_added)} new dependencies (direct and indirect)",
+              "- Adds {length(unique(deps_added$sysreqs))} new system dependencies",
+              "- Removes {nrow(deps_removed)} existing dependencies (direct and indirect)",
+              "- Removes {length(unique(deps_removed$sysreqs))} existing system dependencies",
+              "",
+              "(Note that results may be inacurrate if you branched from an outdated version of the target branch.)"
+            )
+
+            message("Posting results as a pull request comment.")
+
+            gh::gh(
+              "POST /repos/{repo}/issues/{issue_number}/comments",
+              repo = "${{ github.repository }}",
+              issue_number = "${{ github.event.number }}",
+              body = msg
+            )
+
+          }
diff --git a/.github/workflows/pkgdown.yaml b/.github/workflows/pkgdown.yaml
index 9c32a3dd..c09f1b0c 100644
--- a/.github/workflows/pkgdown.yaml
+++ b/.github/workflows/pkgdown.yaml
@@ -21,6 +21,7 @@ on:
       - 'DESCRIPTION'
       - '.Rbuildignore'
       - '.github/**'
+  merge_group:
   pull_request:
     paths:
       - 'README.Rmd'
@@ -44,13 +45,14 @@ concurrency:
   group: ${{ github.workflow }}-${{ github.ref }}
   cancel-in-progress: true
 
+permissions:
+  contents: write
+
 jobs:
   pkgdown:
     runs-on: ubuntu-latest
     env:
       GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
-    permissions:
-      contents: write
     steps:
       - uses: actions/checkout@v3
 
@@ -70,7 +72,7 @@ jobs:
         shell: Rscript {0}
 
       - name: Deploy to GitHub pages 🚀
-        if: github.event_name != 'pull_request'
+        if: github.event_name != 'merge_group' && github.event_name != 'pull_request'
         uses: JamesIves/github-pages-deploy-action@4.1.4
         with:
           # We clean on releases because we want to remove old vignettes,
diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml
index 40c8bb4f..8e0c450c 100644
--- a/.github/workflows/test-coverage.yaml
+++ b/.github/workflows/test-coverage.yaml
@@ -16,6 +16,7 @@ on:
       - 'inst/**'
       - 'DESCRIPTION'
       - '.github/workflows/test-coverage.yaml'
+  merge_group:
   pull_request:
     paths:
       - 'R/**'
diff --git a/.github/workflows/update-citation-cff.yaml b/.github/workflows/update-citation-cff.yaml
index 3b006e99..9926f8d7 100644
--- a/.github/workflows/update-citation-cff.yaml
+++ b/.github/workflows/update-citation-cff.yaml
@@ -1,13 +1,14 @@
 # Workflow derived from https://github.com/r-lib/actions/tree/master/examples
 # The action runs when:
-# - A new release is published
 # - The DESCRIPTION or inst/CITATION are modified
 # - Can be run manually
 # For customizing the triggers, visit https://docs.github.com/en/actions/learn-github-actions/events-that-trigger-workflows
 on:
-  release:
-    types: [published]
   push:
+    branches:
+      # This may seem like a no-op but it prevents triggering on tags.
+      # We use '**' rather '*' to accomodate names like 'dev/branch-1'
+      - '**'
     paths:
       - DESCRIPTION
       - inst/CITATION
@@ -16,6 +17,13 @@ on:
 
 name: Update CITATION.cff
 
+concurrency:
+  group: ${{ github.workflow }}-${{ github.ref }}
+  cancel-in-progress: true
+
+permissions:
+  contents: write
+
 jobs:
   update-citation-cff:
     runs-on: ubuntu-latest
@@ -52,4 +60,5 @@ jobs:
           git config --local user.name "GitHub Action"
           git add CITATION.cff
           git commit -m 'Update CITATION.cff' || echo "No changes to commit"
+          git pull --rebase origin ${{ github.ref.name }}
           git push origin || echo "No changes to commit"
diff --git a/.lintr b/.lintr
index ad4afeee..6e125294 100644
--- a/.lintr
+++ b/.lintr
@@ -1,24 +1,39 @@
 linters: all_linters(
     packages = c("lintr", "etdev"),
     object_name_linter = NULL,
-    undesirable_function_linter = NULL,
     implicit_integer_linter = NULL,
     extraction_operator_linter = NULL,
     todo_comment_linter = NULL,
+    library_call_linter = NULL,
+    undesirable_function_linter(
+      modify_defaults(
+        default_undesirable_functions,
+        citEntry = "use the more modern bibentry() function",
+        library = NULL # too many false positive in too many files
+      )
+    ),
     function_argument_linter = NULL,
     indentation_linter = NULL, # unstable as of lintr 3.1.0
-    object_length_linter = NULL, # do not trigger due to long internal functions
+  object_length_linter = NULL, # do not trigger due to long internal functions
     # Use minimum R declared in DESCRIPTION or fall back to current R version.
     # Install etdev package from https://github.com/epiverse-trace/etdev
     backport_linter(if (length(x <- etdev::extract_min_r_version())) x else getRversion())
   )
 exclusions: list(
-    "tests/testthat.R" = list(unused_import_linter = Inf),
+    "tests/testthat.R" = list(
+      unused_import_linter = Inf
+    ),
+    "tests" = list(
+      undesirable_function_linter = Inf
+    ),
     "data-raw" = list(
       missing_package_linter = Inf,
       namespace_linter = Inf
     ),
     # RcppExports.R is auto-generated and will not pass many linters. In
     # particular, it can create very long lines.
-    "R/RcppExports.R"
+    "R/RcppExports.R",
+    # R/stanmodels.R is auto-generated and will not pass many linters. In
+    # particular, it uses `sapply()`.
+    "R/stanmodels.R"
   )
diff --git a/CITATION.cff b/CITATION.cff
index d366ac95..6713c0a0 100644
--- a/CITATION.cff
+++ b/CITATION.cff
@@ -9,7 +9,12 @@ type: software
 license: MIT
 title: 'epidemics: A Library of Compartmental Epidemic Scenario Models'
 version: 0.0.0.9000
-abstract: Model epidemics using compartmental models.
+abstract: A library of compartmental epidemic models taken from the published literature,
+  and classes to represent populations with heterogeneous characteristics, public
+  health response measures including non-pharmaceutical interventions on social contacts,
+  non-pharmaceutical and pharmaceutical interventions that affect disease transmissibility,
+  vaccination regimes, and disease seasonality, which can be combined to compose epidemic
+  scenarios.
 authors:
 - family-names: Gupte
   given-names: Pratik
@@ -58,6 +63,70 @@ references:
     email: michellang@gmail.com
     orcid: https://orcid.org/0000-0001-9754-0393
   year: '2023'
+- type: software
+  title: cli
+  abstract: 'cli: Helpers for Developing Command Line Interfaces'
+  notes: Imports
+  url: https://cli.r-lib.org
+  repository: https://CRAN.R-project.org/package=cli
+  authors:
+  - family-names: Csárdi
+    given-names: Gábor
+    email: csardi.gabor@gmail.com
+  year: '2023'
+- type: software
+  title: data.table
+  abstract: 'data.table: Extension of `data.frame`'
+  notes: Imports
+  url: https://r-datatable.com
+  repository: https://CRAN.R-project.org/package=data.table
+  authors:
+  - family-names: Barrett
+    given-names: Tyson
+    email: t.barrett88@gmail.com
+  - family-names: Dowle
+    given-names: Matt
+    email: mattjdowle@gmail.com
+  - family-names: Srinivasan
+    given-names: Arun
+    email: asrini@pm.me
+  year: '2023'
+- type: software
+  title: deSolve
+  abstract: 'deSolve: Solvers for Initial Value Problems of Differential Equations
+    (''ODE'', ''DAE'', ''DDE'')'
+  notes: Imports
+  url: http://desolve.r-forge.r-project.org/
+  repository: https://CRAN.R-project.org/package=deSolve
+  authors:
+  - family-names: Soetaert
+    given-names: Karline
+    email: karline.soetaert@nioz.nl
+    orcid: https://orcid.org/0000-0003-4603-7100
+  - family-names: Petzoldt
+    given-names: Thomas
+    email: thomas.petzoldt@tu-dresden.de
+    orcid: https://orcid.org/0000-0002-4951-6468
+  - family-names: Setzer
+    given-names: R. Woodrow
+    email: setzer.woodrow@epa.gov
+    orcid: https://orcid.org/0000-0002-6709-9186
+  year: '2023'
+- type: software
+  title: glue
+  abstract: 'glue: Interpreted String Literals'
+  notes: Imports
+  url: https://glue.tidyverse.org/
+  repository: https://CRAN.R-project.org/package=glue
+  authors:
+  - family-names: Hester
+    given-names: Jim
+    orcid: https://orcid.org/0000-0002-2739-7082
+  - family-names: Bryan
+    given-names: Jennifer
+    email: jenny@rstudio.com
+    orcid: https://orcid.org/0000-0002-6983-2759
+  year: '2023'
 - type: software
   title: Rcpp
   abstract: 'Rcpp: Seamless R and C++ Integration'
@@ -102,36 +171,7 @@ references:
     given-names: Yixuan Qiu; the authors of Eigen for the included version of
   year: '2023'
 - type: software
-  title: data.table
-  abstract: 'data.table: Extension of `data.frame`'
-  notes: Imports
-  url: https://r-datatable.com
-  repository: https://CRAN.R-project.org/package=data.table
-  authors:
-  - family-names: Dowle
-    given-names: Matt
-    email: mattjdowle@gmail.com
-  - family-names: Srinivasan
-    given-names: Arun
-    email: asrini@pm.me
-  year: '2023'
-- type: software
-  title: glue
-  abstract: 'glue: Interpreted String Literals'
-  notes: Imports
-  url: https://glue.tidyverse.org/
-  repository: https://CRAN.R-project.org/package=glue
-  authors:
-  - family-names: Hester
-    given-names: Jim
-    orcid: https://orcid.org/0000-0002-2739-7082
-  - family-names: Bryan
-    given-names: Jennifer
-    email: jenny@rstudio.com
-    orcid: https://orcid.org/0000-0002-6983-2759
-  year: '2023'
-- type: software
-  title: utils
+  title: stats
   abstract: 'R: A Language and Environment for Statistical Computing'
   notes: Imports
   authors:
@@ -142,7 +182,7 @@ references:
   institution:
     name: R Foundation for Statistical Computing
 - type: software
-  title: stats
+  title: utils
   abstract: 'R: A Language and Environment for Statistical Computing'
   notes: Imports
   authors:
@@ -153,36 +193,17 @@ references:
   institution:
     name: R Foundation for Statistical Computing
 - type: software
-  title: deSolve
-  abstract: 'deSolve: Solvers for Initial Value Problems of Differential Equations
-    (''ODE'', ''DAE'', ''DDE'')'
-  notes: Imports
-  url: http://desolve.r-forge.r-project.org/
-  repository: https://CRAN.R-project.org/package=deSolve
-  authors:
-  - family-names: Soetaert
-    given-names: Karline
-    email: karline.soetaert@nioz.nl
-    orcid: https://orcid.org/0000-0003-4603-7100
-  - family-names: Petzoldt
-    given-names: Thomas
-    email: thomas.petzoldt@tu-dresden.de
-    orcid: https://orcid.org/0000-0002-4951-6468
-  - family-names: Setzer
-    given-names: R. Woodrow
-    email: setzer.woodrow@epa.gov
-    orcid: https://orcid.org/0000-0002-6709-9186
-  year: '2023'
-- type: software
-  title: cli
-  abstract: 'cli: Helpers for Developing Command Line Interfaces'
-  notes: Imports
-  url: https://cli.r-lib.org
-  repository: https://CRAN.R-project.org/package=cli
+  title: bench
+  abstract: 'bench: High Precision Timing of R Expressions'
+  notes: Suggests
+  url: https://bench.r-lib.org/
+  repository: https://CRAN.R-project.org/package=bench
   authors:
-  - family-names: Csárdi
-    given-names: Gábor
-    email: csardi.gabor@gmail.com
+  - family-names: Hester
+    given-names: Jim
+  - family-names: Vaughan
+    given-names: Davis
+    email: davis@posit.co
   year: '2023'
 - type: software
   title: bookdown
@@ -235,53 +256,6 @@ references:
     email: Achim.Zeileis@R-project.org
     orcid: https://orcid.org/0000-0003-0918-3766
   year: '2023'
-- type: software
-  title: ggplot2
-  abstract: 'ggplot2: Create Elegant Data Visualisations Using the Grammar of Graphics'
-  notes: Suggests
-  url: https://ggplot2.tidyverse.org
-  repository: https://CRAN.R-project.org/package=ggplot2
-  authors:
-  - family-names: Wickham
-    given-names: Hadley
-    email: hadley@posit.co
-    orcid: https://orcid.org/0000-0003-4757-117X
-  - family-names: Chang
-    given-names: Winston
-    orcid: https://orcid.org/0000-0002-1576-2126
-  - family-names: Henry
-    given-names: Lionel
-  - family-names: Pedersen
-    given-names: Thomas Lin
-    email: thomas.pedersen@posit.co
-    orcid: https://orcid.org/0000-0002-5147-4711
-  - family-names: Takahashi
-    given-names: Kohske
-  - family-names: Wilke
-    given-names: Claus
-    orcid: https://orcid.org/0000-0002-7470-9261
-  - family-names: Woo
-    given-names: Kara
-    orcid: https://orcid.org/0000-0002-5125-4188
-  - family-names: Yutani
-    given-names: Hiroaki
-    orcid: https://orcid.org/0000-0002-3385-7233
-  - family-names: Dunnington
-    given-names: Dewey
-    orcid: https://orcid.org/0000-0002-9415-4582
-  year: '2023'
-- type: software
-  title: knitr
-  abstract: 'knitr: A General-Purpose Package for Dynamic Report Generation in R'
-  notes: Suggests
-  url: https://yihui.org/knitr/
-  repository: https://CRAN.R-project.org/package=knitr
-  authors:
-  - family-names: Xie
-    given-names: Yihui
-    email: xie@yihui.name
-    orcid: https://orcid.org/0000-0003-0645-5666
-  year: '2023'
 - type: software
   title: dplyr
   abstract: 'dplyr: A Grammar of Data Manipulation'
@@ -307,35 +281,16 @@ references:
     orcid: https://orcid.org/0000-0003-4777-038X
   year: '2023'
 - type: software
-  title: tidyr
-  abstract: 'tidyr: Tidy Messy Data'
-  notes: Suggests
-  url: https://tidyr.tidyverse.org
-  repository: https://CRAN.R-project.org/package=tidyr
-  authors:
-  - family-names: Wickham
-    given-names: Hadley
-    email: hadley@posit.co
-  - family-names: Vaughan
-    given-names: Davis
-    email: davis@posit.co
-  - family-names: Girlich
-    given-names: Maximilian
-  year: '2023'
-- type: software
-  title: tibble
-  abstract: 'tibble: Simple Data Frames'
+  title: EpiEstim
+  abstract: 'EpiEstim: Estimate Time Varying Reproduction Numbers from Epidemic Curves'
   notes: Suggests
-  url: https://tibble.tidyverse.org/
-  repository: https://CRAN.R-project.org/package=tibble
+  url: https://github.com/mrc-ide/EpiEstim
+  repository: https://CRAN.R-project.org/package=EpiEstim
   authors:
-  - family-names: MĂĽller
-    given-names: Kirill
-    email: kirill@cynkra.com
-    orcid: https://orcid.org/0000-0002-1416-3412
-  - family-names: Wickham
-    given-names: Hadley
-    email: hadley@rstudio.com
+  - family-names: Cori
+    given-names: Anne
+    email: a.cori@imperial.ac.uk
+    orcid: https://orcid.org/0000-0002-8443-9162
   year: '2023'
 - type: software
   title: finalsize
@@ -358,17 +313,51 @@ references:
     orcid: https://orcid.org/0000-0001-8814-9421
   year: '2023'
 - type: software
-  title: bench
-  abstract: 'bench: High Precision Timing of R Expressions'
+  title: ggplot2
+  abstract: 'ggplot2: Create Elegant Data Visualisations Using the Grammar of Graphics'
   notes: Suggests
-  url: https://bench.r-lib.org/
-  repository: https://CRAN.R-project.org/package=bench
+  url: https://ggplot2.tidyverse.org
+  repository: https://CRAN.R-project.org/package=ggplot2
   authors:
-  - family-names: Hester
-    given-names: Jim
-  - family-names: Vaughan
-    given-names: Davis
-    email: davis@posit.co
+  - family-names: Wickham
+    given-names: Hadley
+    email: hadley@posit.co
+    orcid: https://orcid.org/0000-0003-4757-117X
+  - family-names: Chang
+    given-names: Winston
+    orcid: https://orcid.org/0000-0002-1576-2126
+  - family-names: Henry
+    given-names: Lionel
+  - family-names: Pedersen
+    given-names: Thomas Lin
+    email: thomas.pedersen@posit.co
+    orcid: https://orcid.org/0000-0002-5147-4711
+  - family-names: Takahashi
+    given-names: Kohske
+  - family-names: Wilke
+    given-names: Claus
+    orcid: https://orcid.org/0000-0002-7470-9261
+  - family-names: Woo
+    given-names: Kara
+    orcid: https://orcid.org/0000-0002-5125-4188
+  - family-names: Yutani
+    given-names: Hiroaki
+    orcid: https://orcid.org/0000-0002-3385-7233
+  - family-names: Dunnington
+    given-names: Dewey
+    orcid: https://orcid.org/0000-0002-9415-4582
+  year: '2023'
+- type: software
+  title: knitr
+  abstract: 'knitr: A General-Purpose Package for Dynamic Report Generation in R'
+  notes: Suggests
+  url: https://yihui.org/knitr/
+  repository: https://CRAN.R-project.org/package=knitr
+  authors:
+  - family-names: Xie
+    given-names: Yihui
+    email: xie@yihui.name
+    orcid: https://orcid.org/0000-0003-0645-5666
   year: '2023'
 - type: software
   title: rmarkdown
@@ -422,7 +411,11 @@ references:
   authors:
   - family-names: Wickham
     given-names: Hadley
-    email: hadley@rstudio.com
+    email: hadley@posit.co
+  - family-names: Pedersen
+    given-names: Thomas Lin
+    email: thomas.pedersen@posit.co
+    orcid: https://orcid.org/0000-0002-5147-4711
   - family-names: Seidel
     given-names: Dana
   year: '2023'
@@ -469,16 +462,35 @@ references:
   year: '2023'
   version: '>= 3.0.0'
 - type: software
-  title: EpiEstim
-  abstract: 'EpiEstim: Estimate Time Varying Reproduction Numbers from Epidemic Curves'
+  title: tibble
+  abstract: 'tibble: Simple Data Frames'
   notes: Suggests
-  url: https://github.com/mrc-ide/EpiEstim
-  repository: https://CRAN.R-project.org/package=EpiEstim
+  url: https://tibble.tidyverse.org/
+  repository: https://CRAN.R-project.org/package=tibble
   authors:
-  - family-names: Cori
-    given-names: Anne
-    email: a.cori@imperial.ac.uk
-    orcid: https://orcid.org/0000-0002-8443-9162
+  - family-names: MĂĽller
+    given-names: Kirill
+    email: kirill@cynkra.com
+    orcid: https://orcid.org/0000-0002-1416-3412
+  - family-names: Wickham
+    given-names: Hadley
+    email: hadley@rstudio.com
+  year: '2023'
+- type: software
+  title: tidyr
+  abstract: 'tidyr: Tidy Messy Data'
+  notes: Suggests
+  url: https://tidyr.tidyverse.org
+  repository: https://CRAN.R-project.org/package=tidyr
+  authors:
+  - family-names: Wickham
+    given-names: Hadley
+    email: hadley@posit.co
+  - family-names: Vaughan
+    given-names: Davis
+    email: davis@posit.co
+  - family-names: Girlich
+    given-names: Maximilian
   year: '2023'
 - type: software
   title: BH
diff --git a/DESCRIPTION b/DESCRIPTION
index d554172a..a5400670 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -1,97 +1,68 @@
 Package: epidemics
 Title: A Library of Compartmental Epidemic Scenario Models
 Version: 0.0.0.9000
-Authors@R: 
-    c(
-        person(
-            given = "Pratik",
-            family = "Gupte",
-            role = c("aut", "cre", "cph"),
-            email = "pratik.gupte@lshtm.ac.uk",
-            comment = c(ORCID = "https://orcid.org/0000-0001-5294-7819")
-        ),
-        person(
-            given = "Rosalind",
-            family = "Eggo",
-            role = c("aut", "cph"),
-            email = "rosalind.eggo@lshtm.ac.uk",
-            comment = c(ORCID = "https://orcid.org/0000-0002-0362-6717")
-        ),
-        person(
-            given = "Edwin",
-            family = "Van Leeuwen",
-            role = c("aut", "cph"),
-            email = "edwin.vanleeuwen@ukhsa.gov.uk",
-            comment = c(ORCID = "https://orcid.org/0000-0002-2383-5305")
-        ),
-        person(
-            given = "Adam",
-            family = "Kucharski",
-            role = c("ctb", "rev"),
-            email = "adam.kucharski@lshtm.ac.uk",
-            comment = c(ORCID = "https://orcid.org/0000-0001-8814-9421")
-        ),
-        person(
-            given = "Tim",
-            family = "Taylor",
-            role = c("ctb", "rev"),
-            email = "tim.taylor@hiddenelephants.co.uk",
-            comment = c(ORCID = "https://orcid.org/0000-0002-8587-7113")
-        ),
-        person(
-            given = "Hugo",
-            family = "Gruson",
-            role = c("rev"),
-            email = "hugo.gruson@data.org",
-            comment = c(ORCID = "https://orcid.org/0000-0002-4094-1476")
-        ),
-        person(
-            given = "Joshua W.",
-            family = "Lambert",
-            role = c("rev"),
-            email = "joshua.lambert@lshtm.ac.uk",
-            comment = c(ORCID = "https://orcid.org/0000-0001-5218-3046")
-        )
-    )
-Description: Model epidemics using compartmental models.
+Authors@R: c(
+    person("Pratik", "Gupte", , "pratik.gupte@lshtm.ac.uk", role = c("aut", "cre", "cph"),
+           comment = c(ORCID = "https://orcid.org/0000-0001-5294-7819")),
+    person("Rosalind", "Eggo", , "rosalind.eggo@lshtm.ac.uk", role = c("aut", "cph"),
+           comment = c(ORCID = "https://orcid.org/0000-0002-0362-6717")),
+    person("Edwin", "Van Leeuwen", , "edwin.vanleeuwen@ukhsa.gov.uk", role = c("aut", "cph"),
+           comment = c(ORCID = "https://orcid.org/0000-0002-2383-5305")),
+    person("Adam", "Kucharski", , "adam.kucharski@lshtm.ac.uk", role = c("ctb", "rev"),
+           comment = c(ORCID = "https://orcid.org/0000-0001-8814-9421")),
+    person("Tim", "Taylor", , "tim.taylor@hiddenelephants.co.uk", role = c("ctb", "rev"),
+           comment = c(ORCID = "https://orcid.org/0000-0002-8587-7113")),
+    person("Hugo", "Gruson", , "hugo.gruson@data.org", role = "rev",
+           comment = c(ORCID = "https://orcid.org/0000-0002-4094-1476")),
+    person("Joshua W.", "Lambert", , "joshua.lambert@lshtm.ac.uk", role = "rev",
+           comment = c(ORCID = "https://orcid.org/0000-0001-5218-3046"))
+  )
+Description: A library of compartmental epidemic models taken from the
+    published literature, and classes to represent populations with
+    heterogeneous characteristics, public health response measures
+    including non-pharmaceutical interventions on social contacts,
+    non-pharmaceutical and pharmaceutical interventions that affect
+    disease transmissibility, vaccination regimes, and disease
+    seasonality, which can be combined to compose epidemic scenarios.
 License: MIT + file LICENSE
-URL: https://github.com/epiverse-trace/epidemics, https://epiverse-trace.github.io/epidemics/
+URL: https://github.com/epiverse-trace/epidemics,
+    https://epiverse-trace.github.io/epidemics/
 BugReports: https://github.com/epiverse-trace/epidemics/issues
-Encoding: UTF-8
-Roxygen: list(markdown = TRUE)
-RoxygenNote: 7.2.3
 Imports:
     checkmate,
-    Rcpp,
-    RcppEigen,
+    cli,
     data.table,
+    deSolve,
     glue,
-    utils,
+    Rcpp,
+    RcppEigen,
     stats,
-    deSolve,
-    cli
+    utils
 Suggests: 
+    bench,
     bookdown,
     colorspace,
-    ggplot2,
-    knitr,
     dplyr,
-    tidyr,
-    tibble,
+    EpiEstim,
     finalsize,
-    bench,
+    ggplot2,
+    knitr,
     rmarkdown,
     scales,
     socialmixr,
     spelling,
     testthat (>= 3.0.0),
-    EpiEstim
-Config/testthat/edition: 3
-VignetteBuilder: knitr
+    tibble,
+    tidyr
 LinkingTo: 
-    Rcpp,
     BH,
+    Rcpp,
     RcppEigen
+VignetteBuilder: 
+    knitr
+Config/Needs/website: epiverse-trace/epiversetheme
+Config/testthat/edition: 3
+Encoding: UTF-8
 Language: en-GB
-Config/Needs/website:
-    epiverse-trace/epiversetheme
+Roxygen: list(markdown = TRUE)
+RoxygenNote: 7.2.3
diff --git a/R/intervention.R b/R/intervention.R
index ff499c0a..836f5a46 100644
--- a/R/intervention.R
+++ b/R/intervention.R
@@ -33,16 +33,16 @@ new_intervention <- function(name = NA_character_,
   # argument class is empty to force interventions to have a sub-class
 
   # create and return intervention class
-  structure(
-    list(
-      name = name,
-      time_begin = time_begin,
-      time_end = time_end,
-      reduction = reduction,
-      ...
-    ),
-    class = c(class, "intervention")
+  x <- list(
+    name = name,
+    time_begin = time_begin,
+    time_end = time_end,
+    reduction = reduction,
+    ...
   )
+  class(x) <- c(class, "intervention")
+
+  x
 }
 
 #' Constructor for a new <contacts_intervention>
diff --git a/R/population.R b/R/population.R
index 52460ef6..2d9e0fe5 100644
--- a/R/population.R
+++ b/R/population.R
@@ -20,15 +20,15 @@ new_population <- function(name = NA_character_,
                            demography_vector = numeric(),
                            initial_conditions = matrix()) {
   # create and return population class
-  structure(
-    list(
-      name = name,
-      contact_matrix = contact_matrix,
-      demography_vector = demography_vector,
-      initial_conditions = initial_conditions
-    ),
-    class = "population"
+  x <- list(
+    name = name,
+    contact_matrix = contact_matrix,
+    demography_vector = demography_vector,
+    initial_conditions = initial_conditions
   )
+  class(x) <- "population"
+
+  x
 }
 
 #' Construct a new population for an epidemic model
diff --git a/R/vaccination.R b/R/vaccination.R
index f94adc39..ffc0ee61 100644
--- a/R/vaccination.R
+++ b/R/vaccination.R
@@ -18,15 +18,15 @@ new_vaccination <- function(name = NA_character_,
                             time_end,
                             nu) {
   # create and return vaccination class
-  structure(
-    list(
-      name = name,
-      time_begin = time_begin,
-      time_end = time_end,
-      nu = nu
-    ),
-    class = "vaccination"
+  x <- list(
+    name = name,
+    time_begin = time_begin,
+    time_end = time_end,
+    nu = nu
   )
+  class(x) <- "vaccination"
+
+  x
 }
 
 #' Construct a new vaccination regime for an epidemic model
diff --git a/README.Rmd b/README.Rmd
index 31c85039..bb44dac1 100644
--- a/README.Rmd
+++ b/README.Rmd
@@ -19,7 +19,7 @@ knitr::opts_chunk[["set"]](
 # {{ packagename }}: A library of compartmental epidemic scenario models <img src="man/figures/logo.svg" align="right" width="130"/>
 
 <!-- badges: start -->
-[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
+[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/license/mit/)
 [![R-CMD-check](https://github.com/{{ gh_repo }}/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/{{ gh_repo }}/actions/workflows/R-CMD-check.yaml)
 [![Codecov test coverage](https://codecov.io/gh/{{ gh_repo }}/branch/main/graph/badge.svg)](https://app.codecov.io/gh/{{ gh_repo }}?branch=main)
 [![Project Status: WIP – Initial development is in progress, but there has not yet been a stable, usable release suitable for the public.](https://www.repostatus.org/badges/latest/wip.svg)](https://www.repostatus.org/#wip)
@@ -43,7 +43,7 @@ _{{ packagename }}_ currently provides three models:
 More models are planned to be added in the near future.
 Please get in touch if you would like to see your model added to the _{{ packagename }}_ model library --- we are happy to help with translating it into our framework, with a special focus on making the model applicable to LMIC settings.
 
-_{{ packagename }}_ relies on [Eigen](https://gitlab.com/libeigen/eigen) via [{RcppEigen}](https://cran.r-project.org/web/packages/RcppEigen/index.html), and on [Boost Odeint](https://www.boost.org/doc/libs/1_82_0/libs/numeric/odeint/doc/html/index.html) via [{BH}](https://cran.r-project.org/web/packages/BH/index.html), and is developed at the [Centre for the Mathematical Modelling of Infectious Diseases](https://www.lshtm.ac.uk/research/centres/centre-mathematical-modelling-infectious-diseases) at the London School of Hygiene and Tropical Medicine as part of the [Epiverse-TRACE initiative](https://data.org/initiatives/epiverse/).
+_{{ packagename }}_ relies on [Eigen](https://gitlab.com/libeigen/eigen) via [{RcppEigen}](https://cran.r-project.org/package=RcppEigen), and on [Boost Odeint](https://www.boost.org/doc/libs/1_82_0/libs/numeric/odeint/doc/html/index.html) via [{BH}](https://cran.r-project.org/package=BH), and is developed at the [Centre for the Mathematical Modelling of Infectious Diseases](https://www.lshtm.ac.uk/research/centres/centre-mathematical-modelling-infectious-diseases) at the London School of Hygiene and Tropical Medicine as part of the [Epiverse-TRACE initiative](https://data.org/initiatives/epiverse/).
 
 ## Installation
 
@@ -154,7 +154,7 @@ output <- model_default_cpp(
 
 Visualise the development of individuals in the "infectious" compartment over model time. Note that these curves represent the number of individuals that are infectious, and not the number of newly infectious individuals.
 
-```{r echo=FALSE}
+```{r fig-modelout, echo=FALSE}
 filter(output, compartment == "infectious") %>%
   ggplot() +
   geom_vline(
@@ -196,6 +196,15 @@ filter(output, compartment == "infectious") %>%
 
 More details on how to use _{{ packagename }}_ can be found in the [online documentation as package vignettes](https://epiverse-trace.github.io/{{ packagename }}/), under "Articles".
 
+## Related projects
+
+_epidemics_ aims to be a library of published epidemiological models, and the following projects may be useful for building your own models:
+
+- The [R package _finalsize_](https://cran.r-project.org/package=finalsize) is also developed by Epiverse-TRACE and helps to calculate the final size of an epidemic in a heterogeneous population, and is a quicker option for estimates of total infections when the temporal dynamics are less important;
+- The [Epirecipes project](http://epirecip.es/epicookbook/) is a cookbook-style guide that focuses on different ways to implement epidemic models in R and other languages;
+- The [R package _odin_](https://cran.r-project.org/package=odin) generates systems of ordinary differential equations (ODE) and integrate them, using a domain specific language (DSL), and is widely used to translate compartmental models from R to C code for performance gains;
+- Many R packages provide modelling options, and these can be found on the [CRAN Epidemiology Task View](https://cran.r-project.org/view=Epidemiology) under the section "Infectious disease modelling".
+
 ## Help
 
 To report a bug please open an [issue](https://github.com/{{ gh_repo }}/issues/new/choose).
diff --git a/README.md b/README.md
index d18e2ff7..39a71cf6 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
 <!-- badges: start -->
 
 [![License:
-MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
+MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/license/mit/)
 [![R-CMD-check](https://github.com/epiverse-trace/epidemics/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/epiverse-trace/epidemics/actions/workflows/R-CMD-check.yaml)
 [![Codecov test
 coverage](https://codecov.io/gh/epiverse-trace/epidemics/branch/main/graph/badge.svg)](https://app.codecov.io/gh/epiverse-trace/epidemics?branch=main)
@@ -57,11 +57,11 @@ library — we are happy to help with translating it into our framework,
 with a special focus on making the model applicable to LMIC settings.
 
 *epidemics* relies on [Eigen](https://gitlab.com/libeigen/eigen) via
-[{RcppEigen}](https://cran.r-project.org/web/packages/RcppEigen/index.html),
-and on [Boost
+[{RcppEigen}](https://cran.r-project.org/package=RcppEigen), and on
+[Boost
 Odeint](https://www.boost.org/doc/libs/1_82_0/libs/numeric/odeint/doc/html/index.html)
-via [{BH}](https://cran.r-project.org/web/packages/BH/index.html), and
-is developed at the [Centre for the Mathematical Modelling of Infectious
+via [{BH}](https://cran.r-project.org/package=BH), and is developed at
+the [Centre for the Mathematical Modelling of Infectious
 Diseases](https://www.lshtm.ac.uk/research/centres/centre-mathematical-modelling-infectious-diseases)
 at the London School of Hygiene and Tropical Medicine as part of the
 [Epiverse-TRACE initiative](https://data.org/initiatives/epiverse/).
@@ -217,7 +217,7 @@ over model time. Note that these curves represent the number of
 individuals that are infectious, and not the number of newly infectious
 individuals.
 
-<img src="man/figures/README-unnamed-chunk-8-1.png" width="100%" />
+<img src="man/figures/README-fig-modelout-1.png" width="100%" />
 
 ## Package vignettes
 
@@ -226,6 +226,30 @@ documentation as package
 vignettes](https://epiverse-trace.github.io/epidemics/), under
 “Articles”.
 
+## Related projects
+
+*epidemics* aims to be a library of published epidemiological models,
+and the following projects may be useful for building your own models:
+
+- The [R package
+  *finalsize*](https://cran.r-project.org/package=finalsize) is also
+  developed by Epiverse-TRACE and helps to calculate the final size of
+  an epidemic in a heterogeneous population, and is a quicker option for
+  estimates of total infections when the temporal dynamics are less
+  important;
+- The [Epirecipes project](http://epirecip.es/epicookbook/) is a
+  cookbook-style guide that focuses on different ways to implement
+  epidemic models in R and other languages;
+- The [R package *odin*](https://cran.r-project.org/package=odin)
+  generates systems of ordinary differential equations (ODE) and
+  integrate them, using a domain specific language (DSL), and is widely
+  used to translate compartmental models from R to C code for
+  performance gains;
+- Many R packages provide modelling options, and these can be found on
+  the [CRAN Epidemiology Task
+  View](https://cran.r-project.org/view=Epidemiology) under the section
+  “Infectious disease modelling”.
+
 ## Help
 
 To report a bug please open an
diff --git a/inst/WORDLIST b/inst/WORDLIST
index a9814416..ec21b8db 100644
--- a/inst/WORDLIST
+++ b/inst/WORDLIST
@@ -87,6 +87,7 @@ io
 kylieainslie
 md
 odeint
+odin
 org
 packagename
 pkg
diff --git a/man/epidemics-package.Rd b/man/epidemics-package.Rd
index 8a1370d5..9517b74a 100644
--- a/man/epidemics-package.Rd
+++ b/man/epidemics-package.Rd
@@ -6,7 +6,7 @@
 \alias{epidemics-package}
 \title{epidemics: A Library of Compartmental Epidemic Scenario Models}
 \description{
-Model epidemics using compartmental models.
+A library of compartmental epidemic models taken from the published literature, and classes to represent populations with heterogeneous characteristics, public health response measures including non-pharmaceutical interventions on social contacts, non-pharmaceutical and pharmaceutical interventions that affect disease transmissibility, vaccination regimes, and disease seasonality, which can be combined to compose epidemic scenarios.
 }
 \seealso{
 Useful links:
diff --git a/man/figures/README-unnamed-chunk-8-1.png b/man/figures/README-fig-modelout-1.png
similarity index 100%
rename from man/figures/README-unnamed-chunk-8-1.png
rename to man/figures/README-fig-modelout-1.png
diff --git a/man/figures/README-unnamed-chunk-9-1.png b/man/figures/README-unnamed-chunk-9-1.png
deleted file mode 100644
index fb4c49db..00000000
Binary files a/man/figures/README-unnamed-chunk-9-1.png and /dev/null differ
diff --git a/tests/spelling.R b/tests/spelling.R
index 226d21ac..647406c2 100644
--- a/tests/spelling.R
+++ b/tests/spelling.R
@@ -1,6 +1,7 @@
 if (requireNamespace("spelling", quietly = TRUE)) {
   spelling::spell_check_test(
-    vignettes = TRUE, error = TRUE,
+    vignettes = TRUE,
+    error = TRUE,
     skip_on_cran = TRUE
   )
 }
diff --git a/tests/testthat/helper-state.R b/tests/testthat/helper-state.R
new file mode 100644
index 00000000..4910faa6
--- /dev/null
+++ b/tests/testthat/helper-state.R
@@ -0,0 +1,26 @@
+# This helper ensures the package does not modify the session global state. As
+# per CRAN policy, packages should not interfere with the user's session state.
+# If global settings need to be modified, they should be restored to their
+# original values on exit. This can be achieved with the `on.exit()` base
+# function, or more conveniently with the `withr` package.
+# We add a test on R >= 4.0.0 because some functions such as
+# `globalCallingHandlers()` did not exist before.
+if (getRversion() >= "4.0.0") {
+  testthat::set_state_inspector(function() {
+    list(
+      attached    = search(),
+      connections = getAllConnections(),
+      cwd         = getwd(),
+      envvars     = Sys.getenv(),
+      handlers    = globalCallingHandlers(),
+      libpaths    = .libPaths(),
+      locale      = Sys.getlocale(),
+      options     = options(),
+      par         = par(),
+      packages    = .packages(all.available = TRUE),
+      sink        = sink.number(),
+      timezone    = Sys.timezone(),
+      NULL
+    )
+  })
+}
diff --git a/tools/check.env b/tools/check.env
new file mode 100644
index 00000000..181ad6bb
--- /dev/null
+++ b/tools/check.env
@@ -0,0 +1,11 @@
+# Do not report if package size is larger than 5 megabytes
+_R_CHECK_PKG_SIZES_=false
+
+# Do not check Rd cross references
+_R_CHECK_RD_XREFS_=false
+
+# Do not report if package requires GNU make
+_R_CHECK_CRAN_INCOMING_NOTE_GNU_MAKE_=false
+
+# Do not check non-ASCII strings in datasets
+_R_CHECK_PACKAGE_DATASETS_SUPPRESS_NOTES_=true