Release Playbook

Purpose

Define the deliberate, evidence-led release process for DSAMbayes. It supports the normal quarterly release cycle and material ad-hoc releases. It is not a CI/CD process and does not imply continuous deployment or a high release cadence.

The point is to make the infrequent release decision reproducible and reviewable, not to automate it for its own sake.

Roles and release boundary

  • Release owner: fixes the candidate commit, runs or coordinates the gates, and prepares the evidence bundle.
  • Reviewer: independently checks the evidence and records the GO, NO-GO, or HOLD decision. The reviewer should be different from the release owner when practical.
  • Maintainers: resolve failures or explicitly approve a documented exception.

One release has one candidate commit. Do not make product, dependency, or documentation changes after gates begin. If a change is required, create a new candidate and rerun the affected gates.

Preconditions

Before starting:

  1. The intended version is consistent in DESCRIPTION and CHANGELOG.md.
  2. The candidate commit is identified and the working tree is clean apart from deliberately excluded local evidence and run artefacts.
  3. The local R runtime and package library are recorded. The current tested baseline is R 4.5.1; DESCRIPTION declares the supported runtime floor. The floor is a compatibility policy, not a claim that every R version has been exercised for every release.
  4. Required non-CRAN dependencies, including DSAMdecomp, are reachable at the recorded revision. Record the source and commit SHA in the evidence bundle. Do not record credentials.
  5. No Stan template, prior, boundary-default, or fit-semantics change is released without the required human model review.

Manual release flow

1. Freeze and identify the candidate

git status --short
git rev-parse HEAD
git rev-parse --abbrev-ref HEAD

Record the full SHA, branch, intended tag, package version, R version, and platform in 00_release_identity/release_identity.txt of the evidence bundle. Use the current package version rather than editing this playbook for each release.

2. Prepare the local environment

source scripts/r-library-path.sh
dsambayes_set_r_library container
mkdir -p "$R_LIBS_USER" .cache
export XDG_CACHE_HOME="$PWD/.cache"
export _R_CHECK_FORCE_SUGGESTS_=false
export DSAMDECOMP_DISABLE_TELEMETRY=1
export DSAMBAYES_DISABLE_TELEMETRY=1
export USE_BUNDLED_LIBUV=1

R -q -e 'install.packages(".", repos = NULL, type = "source")'
R --version

Use a local container only when it makes the environment easier to reproduce; it is evidence capture, not a CI service. Its R version must match renv.lock (currently 4.5.1); record the image and digest if one is used. The helper selects .Rlib-container-r<active-R-version>/; never mount a host library as the container package library.

3. Create the evidence root

Use the layout defined in Release Evidence Pack. The evidence root is local working material until the release owner decides how it will be retained. It must not contain .env, credentials, private data, or unredacted tokens.

4. Run the mandatory gates once, against the frozen candidate

Run QG-1 to QG-8 from Quality Gates, capturing both complete logs and exit codes. The canonical commands are:

Rscript scripts/check.R --lint
Rscript scripts/check.R --style
Rscript scripts/check.R --test
Rscript scripts/check.R --stan-release-evidence
_R_CHECK_FORCE_SUGGESTS_=false \
  R -q -e 'rcmdcheck::rcmdcheck(args = c("--no-manual"), error_on = "warning")'
Rscript scripts/dsambayes.R validate \
  --config config/blm_timeseries.yaml --run-dir results/quality_gate_validate
Rscript scripts/dsambayes.R run \
  --config config/blm_timeseries.yaml --run-dir results/quality_gate_run
python3 docs-site/build_content.py
(cd docs-site && hugo --cleanDestinationDir)

scripts/check.R --release is a useful local consolidation check, but it does not replace rcmdcheck, the two runner checks, the docs-site build, or the high-budget --stan-release-evidence gate.

5. Interpret warnings correctly

The release decision is based on the mandatory gates, not on a search for a silent terminal.

  • A non-zero exit code, missing required tool, test failure, unresolved package WARNING, failed diagnostic threshold, or missing required runner artefact is a blocker.
  • rcmdcheck NOTEs require written review and acceptance; they are not silently waived.
  • Low-budget Stan smoke tests can emit deliberately exercised sampler warnings. They are not release evidence and must be recorded as expected test-fixture behaviour if observed. The high-budget QG-4 diagnostics are the release evidence and may not be waived without an explicit human decision.
  • Any new, unexplained warning is a HOLD until it is understood or removed.

6. Review and sign off

Complete the Release Readiness Checklist and copy Release Sign-off Template into the evidence bundle. A GO requires all mandatory checks to pass, the candidate SHA to match throughout, and the reviewer to sign the decision.

7. Tag and publish manually

Only after GO:

git tag -a vX.Y.Z -m "DSAMbayes vX.Y.Z"
git push origin vX.Y.Z

Create any GitHub release and publish any docs mirror as separate manual acts. Record what was published, by whom, and when. No automatic deployment follows from tagging.

8. Retain the decision record

Retain the signed evidence bundle for approved and rejected candidates. Record post-release defects as a new hotfix candidate; do not retag or rewrite the published release history.

Go/no-go rules

  1. GO only when QG-1 to QG-8 pass and the sign-off record is complete.
  2. HOLD when evidence is incomplete, a warning is unexplained, or approval is pending.
  3. NO-GO for any release blocker. Fix the issue, select a new candidate SHA, and rerun the affected gates.

Hotfixes

For a post-release defect, branch from the affected tag, make the smallest safe change, update the version and changelog, and run the same manual process. The smaller scope does not remove the evidence or human-review requirement.