Skip to content
124 changes: 32 additions & 92 deletions cran-comments.md
Original file line number Diff line number Diff line change
@@ -1,100 +1,40 @@
# CRAN submission preparation: bifrost 0.2.2
# bifrost 0.2.2

Draft for an update from CRAN version 0.2.0 to 0.2.2. Version 0.2.1 was
published on GitHub. Version 0.2.2 has not yet been submitted or published.
This updates CRAN version 0.2.0; version 0.2.1 was released on GitHub only.

## Release changes
## Changes

Searches now default to data-dependent BM/BMM starting values adapted from
the mvMORPH 1.2.1 development initializer used in earlier analyses. The
compatibility helper passes these values through `start` to the installed
mvMORPH; it does not pin or modify that package. Native initialization remains
available through `start_strategy = "native"` and is required for EmpBayes.
The adapted code credits Julien Clavel in its source and in `Authors@R`.
`corpcor` and `RhpcBLASctl` are now explicit imports.
This release restores the data-dependent starting-value strategy used in
earlier analyses, while retaining an option for native mvMORPH initialization.
It also fixes progress-related random-state and numerical-thread handling.
The adapted starting-value code credits Julien Clavel. New imports are
`corpcor` for initialization and `RhpcBLASctl` for worker thread control.
Further changes and reproducibility limitations are described in NEWS.md.

This update also corrects progress-related random-stream and numerical-thread
handling and refines the console displays. It includes the citation and source
archive updates from the GitHub-only 0.2.1 release. NEWS.md describes the
changed defaults and reproducibility limitations.
## Checks

## Package contents and network access

Worked articles and empirical data remain on the package website and are
excluded from the source package. `bifrost_example_file()` downloads data
only on explicit request, verifies SHA-256 and byte size, and reports download
failures. Installation, attachment, and examples do not require these downloads.

## Verified CI results

The following results apply to main commit
`30e58e82af46f6f0ef35ebf69f3a563f8b459774` (2026-10-15 UTC):

- [R CMD check](https://github.com/jakeberv/bifrost/actions/runs/38688925126)
passed on macOS and Windows R release, and Ubuntu R release, devel, and
oldrel-1, using `--as-cran --run-donttest --no-manual`.
- [Coverage and parallel smoke tests](https://github.com/jakeberv/bifrost/actions/runs/38688925143)
passed. Whole-package R coverage was exactly 100%, with zero uncovered rows.
The coverage run recorded 4,947 passing assertions, zero failures or warnings,
and 43 expected skips for coverage-specific cases or development files absent
from the built package. Separate Linux and Windows parallel smoke jobs passed.
- [The pkgdown build and deployment](https://github.com/jakeberv/bifrost/actions/runs/38688925130)
passed.
- [The advisory audit](https://github.com/jakeberv/bifrost/actions/runs/38688925163)
completed. It still reports print/cat usage and documentation/style findings;
a successful advisory job does not mean every advisory finding is cleared.
URL-liveness and advisory spelling checks were skipped.

## Final source-package check

On 2026-10-15, `bifrost_0.2.2.tar.gz` built from the same commit passed
`R CMD check --as-cran --run-donttest --library=<isolated library>` with:
`R CMD check --as-cran --run-donttest`, including PDF and HTML manuals,
completed on macOS arm64 (R 4.4.2) on 2026-10-17 UTC with:

**0 errors | 0 warnings | 1 note**

The sole note was `unable to verify current time`, from the local environment's
timestamp check. Installation, loading, examples (including `\donttest`),
tests, and both PDF and HTML manual checks passed. The test suite recorded
2,969 passing assertions, zero failures or warnings, and 138 expected skips
(including CRAN-mode skips and development files absent from the tarball).
The 101-page PDF manual also passed a separate `qpdf --check`.

Environment: macOS Sequoia 15.7.9, arm64, R 4.4.2, mvMORPH 1.2.3, and OpenBLAS
0.3.34. Bifrost was installed in an isolated library; other dependencies were
accessed read-only. Numerical libraries used one thread per worker, with at
most eight workers. Archive contents were inspected to confirm that local
outputs, caches, and development tooling were excluded.

Archive SHA-256:

```text
153dbcf17195ad2c0e727fda3acad1e47c91a4ae67f32f5a609b525b0dbfe92b
```

The first attempt passed tests and the PDF manual but crashed inside the
existing V8 8.2.0 installation during the HTML manual check. A standalone V8
call reproduced the crash without loading bifrost. A private build of V8 8.2.0
with bundled engine 14.6.202.26 resolved it. The complete check then passed on
the identical archive, without disabling checks or changing bifrost source.
Existing installations were unchanged during this validation.

## Known limitations retained in this update

- High-dimensional searches remain sensitive to initialization and random
state, and some intermediate fits can fail to converge. The compatibility
policy restores a reproducible starting strategy, not guaranteed optimality.
Follow-up: https://github.com/jakeberv/bifrost/issues/242.
- The existing Gumbel KL-divergence bootstrap can discard valid large draws
because of overflow/underflow and understate uncertainty. Its correction is
deferred and is not part of 0.2.2 preparation.
Follow-up: https://github.com/jakeberv/bifrost/issues/231.

## Pending before submission

Merge the check-evidence PR through normal review and confirm CI on its merge
commit. Select the release commit and verify that its package contents still
match the checked source; rerun the final check if package contents change.
These maintainer notes and `tools/releases/0.2.2.md` are excluded from source
archives. Keep the checksum above tied to the actual checked archive, not an
unverified rebuild. Remove draft/pending wording only when submission is
authorized. No tag, GitHub release, or CRAN submission has been made for 0.2.2.
The sole note was `unable to verify current time`, an environment-related
timestamp check. Installation, examples and tests passed, with 2,980 passing
test assertions and no test warnings or failures. The RNG chunk-invariance
test now exercises two and three chunks using at most two worker processes.

[CI](https://github.com/jakeberv/bifrost/pull/252/checks)
also checks macOS and Windows R release, and Ubuntu R release, devel and
oldrel-1 (`--as-cran --run-donttest --no-manual`). A Windows temporary-file
note was traced to the worker-cancellation test; its worker files now use a
test-owned temporary directory with scoped cleanup.

## Additional notes

- Worked articles and empirical data are hosted separately. Data downloads
occur only on explicit request, not during installation, attachment or checks.
- High-dimensional fits remain sensitive to initialization and random state;
some intermediate fits can fail to converge (issue #242).
- The existing Gumbel KL-divergence bootstrap can understate uncertainty because
of overflow/underflow. Its correction remains deferred to a later release:
https://github.com/jakeberv/bifrost/issues/231.
20 changes: 12 additions & 8 deletions inst/WORDLIST
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ Caetano
Carvajal
Cheng
Claramunt
Clavel
Codecov
Colab
Collyer
Expand All @@ -29,9 +28,9 @@ Cov
Cracraft
Cui
DF
DOI
Dipnoi
EB
EmpBayes
Escarguel
Evaluable
Felsenstein
Expand All @@ -54,7 +53,6 @@ Interspecific
Iteratively
JS
Jolliffe
Julien
KDE
Kaliontzopoulou
Kozak
Expand Down Expand Up @@ -103,6 +101,7 @@ Pennell
Phylogenies
Phytologist
Precompute
Preprint
Probst
Purvis
Qiao
Expand Down Expand Up @@ -149,12 +148,12 @@ Welch
XQuartz
Xie
Zenodo
Zenodo's
Zhaoqi
Zhou
Zhu
Ziebell
abline
accuracies
acknowledgements
adjustcolor
adp
Expand Down Expand Up @@ -223,6 +222,7 @@ gic
gmShiny
grDevices
grey
gz
heterochronous
hindlimb
hjust
Expand All @@ -231,6 +231,8 @@ htmltools
ic
idx
ij
initializer
initializer's
interpretable
intersp
intra
Expand Down Expand Up @@ -260,7 +262,10 @@ morphometric
mtext
mult
multisession
multithreading
mustWork
mvMORPH
mvMORPH's
mvPGLS
mvgls
mvmorph
Expand All @@ -269,6 +274,7 @@ ncol
nodelabels
nodepath
nonmonophyletic
normalizePath
nph
nrow
oma
Expand All @@ -277,9 +283,7 @@ overrepresented
oversubscription
pGLS
parallelization
parallelize
parallelizes
parameterizing
passerine
pca
pch
Expand Down Expand Up @@ -312,7 +316,6 @@ reclusters
rect
renderer
renormalizes
replicate's
reproducibility
rescale
rescaled
Expand Down Expand Up @@ -345,18 +348,19 @@ tunable
ultrametric
ultrametricity
uncached
unevaluable
unflagged
unname
unrepresentable
unscaled
unshifted
vapply
vdots
vectorize
vectorized
vectorizes
vectorizing
viridis
winslash
xend
xlab
xlim
Expand Down
25 changes: 24 additions & 1 deletion tests/testthat/test-search-progress.R
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,11 @@ test_that("search progress stage preserves failure lifecycle and rethrows errors
})

test_that("animated Future failures cancel remaining work and restore settings", {
# Killing a Windows Rscript worker bypasses its normal temporary-file cleanup.
# Keep this fault-injection test's worker files in a directory it owns.
worker_tmp <- withr::local_tempdir(pattern = "bifrost-cancel-")
withr::local_envvar(c(TMPDIR = worker_tmp, TMP = worker_tmp, TEMP = worker_tmp))

thread_vars <- c(
"OMP_NUM_THREADS",
"OPENBLAS_NUM_THREADS",
Expand Down Expand Up @@ -557,6 +562,21 @@ test_that("animated Future failures cancel remaining work and restore settings",
})

test_that("animated Future RNG matches ordinary work and preserves parallel chunk invariance", {
# Compare two and three real Future chunks on at most two worker processes.
# Only cap the backend; retain production chunking and per-item RNG streams.
with_future_plan <- .bifrost_search_with_future_plan
testthat::local_mocked_bindings(
.bifrost_search_with_future_plan = function(workers, work, ...) {
with_future_plan(
workers = min(workers, 2L),
work = function() {
testthat::expect_lte(future::nbrOfWorkers(), 2L)
work()
},
...
)
}
)
run_random_work <- function(workers) {
set.seed(42)
.bifrost_search_future_lapply(
Expand Down Expand Up @@ -592,7 +612,10 @@ test_that("animated Future RNG matches ordinary work and preserves parallel chun
set.seed(42)
serial_reference <- as.list(stats::runif(6L))
testthat::expect_identical(run_random_work(1L), serial_reference)
testthat::expect_equal(run_random_work(2L), run_random_work(3L))
two_chunks <- run_random_work(2L)
seed_after <- .Random.seed
testthat::expect_identical(run_random_work(3L), two_chunks)
testthat::expect_identical(.Random.seed, seed_after)
testthat::expect_error(
run_random_work(NA_integer_),
"`workers` must be a single finite number",
Expand Down
68 changes: 64 additions & 4 deletions tools/releases/0.2.2.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,13 @@ for details. GitHub publication does not update CRAN automatically.
`\donttest` examples and PDF/HTML manuals: **0 errors, 0 warnings, 1 note**
(`unable to verify current time`). See `cran-comments.md` for the environment,
archive checksum, and resolution of the local V8 crash using a private build.
- [ ] Merge the check-evidence PR through normal review and confirm its CI.
Select the exact release commit: **pending**. Confirm package contents match
the checked source; rerun the final check if package contents change.
- [x] Check-evidence PR #251 merged as `e1d2fe3`; its post-merge CI passed.
- [x] Rebuild with the PR #252 dictionary update and test worker-limit fix;
complete the package and manual check with zero test warnings or failures.
- [x] Preserve the two-versus-three-chunk RNG comparison using at most two real
workers; also verify identical final caller RNG state.
- [ ] Merge PR #252 through normal review and confirm its CI. Select the exact
release commit and use the verified submission archive recorded below.
- [ ] Retain the documented deferral of #231; this preparation does not fix it.
Keep the initialization/convergence follow-up (#242) and RRphylo dependency
work (#247) separate from this release.
Expand All @@ -70,7 +74,63 @@ for details. GitHub publication does not update CRAN automatically.
- [ ] Apply the publication-time documentation edits below through a PR.
Update CRAN availability separately, only after CRAN actually publishes it.

## Checked archive and local evidence
## Latest check: PR #252 Windows cancellation-test cleanup

Source commit: `87b6d31444424a90f823aebcbcbd291bbf80b5d6`; checked on 2026-10-17 UTC.
Archive SHA-256: `4a817a3ab4e3f6c98efc01342ebaf8fb0b47b61287a05294d943c596a78a00dc`.

The Windows NOTE came from a test that deliberately cancels an active Future
worker. A Windows diagnostic reproduced leftover `Rscript…` files after forced
cancellation and none after cooperative shutdown. Windows R removes those
scripts during normal exit, which forced termination bypasses. The test now
launches its workers with temporary paths in a test-owned directory and cleans
that directory on exit. It still forcibly cancels a real worker and retains all
eight assertions. Production behavior and the RNG tests are unchanged.
Temporary CI diagnostic code was removed after gathering this evidence.

`R CMD check --as-cran --run-donttest`, including both manuals, returned
**0 errors, 0 warnings, 1 note** (`unable to verify current time`). All **2,980
assertions passed**, with zero test warnings/failures and 138 expected skips.
The PDF passed `qpdf --check`. The isolated library used existing dependencies
read-only, two advertised cores, and one numerical thread per worker;
dependency DESCRIPTION hashes remained unchanged.

Evidence: `output/release-0.2.2-pr252-check/run-yr9i7roc/` and
`output/windows-temp-investigation/`. The Windows diagnostic is retained in
[its CI log](https://github.com/jakeberv/bifrost/actions/runs/38998764680/job/117297030452).
Check the latest [PR #252 CI](https://github.com/jakeberv/bifrost/pull/252/checks)
before merging; the older archives below are superseded.

## Earlier check: PR #252 dictionary and test worker-limit updates

Source commit: `49e8b20faef72532fcee6a127d625e5da32e963b`; checked on 2026-10-17 UTC.
Archive SHA-256: `4ad44c0dde81d0ae924c4ef1b524c536ad12cdce7d9e44c142a0a29d0df0beea`.

`R CMD check --as-cran --run-donttest` with both manuals returned **0 errors,
0 warnings, 1 note** (`unable to verify current time`). Testthat recorded
**2,980 passing assertions, zero failures, zero warnings**, and 138 expected
skips. The 101-page PDF also passed `qpdf --check`.

The RNG chunk-invariance test retains two and three real Future chunks, but
caps its backend at two worker processes. It asserts the worker limit and
identical results and final caller RNG state. Production fitting code and RNG
handling are unchanged; no test skips, warning suppression, or coverage
exclusions were added. The original targeted test failed on the worker warning;
the fixed test passed. A diagnostic mutation bypassing per-item seeding made
the fixed test fail as expected, confirming it still detects that RNG regression.

Validation used a fresh isolated library with existing dependencies accessed
read-only, one numerical thread per worker, and two advertised cores. Existing
dependency DESCRIPTION hashes were unchanged. Relative to the previous PR #252
archive, only the corrected test and generated packaging timestamp differ.

Evidence: `output/release-0.2.2-pr252-check/run-hivedoav/`, including the archive,
`SHA256SUMS`, `final-summary.txt`, `bifrost.Rcheck/00check.log`, and the manual.
Targeted regression logs: `output/rng-worker-limit-regression/`.
The earlier warning and its diagnostic evidence remain preserved under
`output/release-0.2.2-pr252-check/run-jx3msm29/`; that archive is superseded.

## Earlier checked archive and local evidence

Checked archive: `bifrost_0.2.2.tar.gz`, built from `30e58e8` on 2026-10-15.
SHA-256: `153dbcf17195ad2c0e727fda3acad1e47c91a4ae67f32f5a609b525b0dbfe92b`.
Expand Down
Loading