Skip to contents

This document is for people making changes to the SPoRC codebase, where things live and why is covered in Architecture; this page covers the mechanics of actually getting a change in: environment setup, branching, testing, and what CI checks before a change lands.

Getting set up

SPoRC is a standard R package built around RTMB. There’s no compiled code to build (RTMB traces plain R at runtime rather than compiling C++), so getting started is just:

Branching

Work happens on dev-* branches off main (e.g. dev-movement, dev-popn-seasons), merged in when ready. dev-* is not just convention, the GitHub Actions workflows (R-CMD-check, test-coverage, pkgdown) are configured to trigger on pushes to branches matching that pattern, so a differently-named branch won’t get CI feedback until you open a PR against main.

Making a change

The Architecture doc’s “Extending the model: a checklist” section walks through where a new process, fleet type, or data source touches the pipeline (Setup function → objective section → sim counterpart → post-fit exposure → tests → vignette). Two conventions worth internalizing before you start:

  • Naming tells you the role. Setup_Mod_* builds data/parameters/mapping, Get_* / get_* derives a quantity from already-built state, do_* re-runs or perturbs a fitted model, do_*_mapping builds an RTMB parameter map. Match an existing prefix rather than inventing a new one, see the naming conventions table in Architecture.
  • Extract non-trivial logic out of model_objective.R into a helper. The objective function is already large; sections that do complex computations (population projection, observation models, priors/penalties) call out to a get_*() helper that takes the relevant state as named arguments and returns it, rather than computing inline.

Testing

Tests live in tests/testthat/ (Config/testthat/edition: 3). Run the full suite with:

devtools::test()

or a single file while iterating:

testthat::test_file("tests/testthat/test-model_selectivity.R")

or a whole group, since test files hold the same prefixes as R/:

testthat::test_dir("tests/testthat", filter = "model_")

filter is a regex matched against the file path, so use the bare prefix rather than anchoring it with ^.

Most test files are narrowly scoped (test-model_movement.R, test-setup_fishery_fdev.R, test-model_selectivity.R, …), but the test-regression_*.R files fit a full model end-to-end against a bundled example dataset and check the resulting obj$rep values (e.g. SSB, Rec) against fixed reference vectors. These are the tests most likely to catch an accidental change in model_objective.R’s numerics, and they’re also the slowest (each one runs a real optimization) so expect a full local run of just that subset to take several minutes to tens of minutes depending on your machine. If you touch anything in model_objective.R or a helper it calls, run at least one of these before opening a PR, even if your change looks purely mechanical (e.g. a refactor that moves code into a helper function without intending to change any values), a subtle argument-order or indexing mistake in that kind of change won’t show up any other way.

For a new feature, add a targeted test near it, and check whether the reference values in the test-regression_*.R tests need updating (they should only change if your feature is expected to change model output for the bundled example data, if a “pure refactor” changes them, that’s a bug in the refactor, not a test that needs updating).

Documentation

Roxygen comments (RoxygenNote: 7.3.3) generate both man/*.Rd and the pkgdown reference site. After adding or changing a roxygen block:

devtools::document()

Internal helpers (not meant for users to call directly) should have @keywords internal rather than @export. If you add a new exported function, add it to the appropriate section of reference: in _pkgdown.yml too. pkgdown won’t list a function on the reference index just because it’s exported, it needs to be in that config.

User-facing vignettes are the lettered .Rmd files in vignettes/ (a_model_dimensions.Rmd, b_model_parameters.Rmd, …), grouped under articles: in _pkgdown.yml. This document and Architecture are unlettered and live under the same articles: listing, grouped separately since they’re about the package’s internals rather than how to use it.