Skip to contents

This document tracks the direction of the package: what is done, what is in progress, and what is planned. It is updated alongside meaningful code changes. Dates are omitted in favour of milestone ordering.

Guiding principles

  • Statistical correctness first. Every test must reproduce an established reference (or a defensible derivation) and be covered by a test that checks behaviour (size and power), not just object structure.
  • One consistent interface. All diagnostics return base-R htest objects and follow the perform*Test(model, data, ...) convention.
  • Scale and robustness as first-class concerns, not afterthoughts: streaming implementations for large data, resampling/robust variants for small or non-normal samples.

Completed

Statistical correctness

Packaging / correctness hygiene

Documentation

Current priorities (next)

CRAN submission is deferred. The package is not considered mature enough to submit, so nothing here is sequenced towards a submission date. R CMD check --as-cran is still worth passing as a quality signal – it is what surfaced the \doi{} note cleared in 0.8.1 – but it no longer runs on every merge, because it costs about an hour and three consecutive runs were cancelled or left queued before finishing. It runs weekly and on demand (gh workflow run R-CMD-check.yml).

With submission deferred, the useful work is the statistical surface rather than packaging: the validation matrix below is complete for the exported tests, and its follow-ons are listed under short-term improvements.

Validation matrix

The validation effort ran in four passes and is complete for the exported surface. Evidence lives in inst/validation/, with scripts that regenerate it.

Six exported procedures were found to be broken, and all six shared a single property: no size or power check.

procedure fault outcome
performRiceTest() insensitive by construction; rejection rate 0% under every variance pattern tried withdrawn in 0.8.0
performCurryWalshTest() 0% rejection withdrawn in 0.8.0
fitWLS() weights were the inverse squared residuals of the same fit; nominal 95% intervals covered 10.4% corrected to feasible GLS in 0.9.0
rbootstrap_test_statistic() resampled rows rather than under the null, so the p-value sat near 0.5; 0% power null-imposed resampling in 0.10.0
performBPRandomEffectsTest() statistic omitted the - 1 and the square from Breusch-Pagan’s equation 5; size 32.5% corrected in 0.11.0
performPesaranTest() T divided where Pesaran’s CD multiplies, making the statistic 1/T too small; size 0.0% corrected in 0.11.0

Twenty-five of the twenty-six heteroscedasticity tests hold their nominal level, at 400 replications and n = 150. The exception is performBoxMTest(), conservative at 0.012; inst/validation/README.md carries the table and the reasoning, and generates those counts from the CSV rather than restating them, because an earlier draft of this paragraph quoted figures from a different run and a z computed against the wrong standard error.

Two conclusions worth keeping. A reference comparison is not a substitute for a size check: four of the six faults above are in procedures with no reference implementation to compare against, and the two that had one agreed with it. And a stored-value regression test would have frozen each fault rather than caught it, so the guards added are simulated size, not recorded numbers.

Short-term improvements

Sequencing

Statistical correctness comes before API reduction. Shrinking the public surface is still wanted, but mixing API-breaking cleanup into the same release as method-definition corrections makes both harder to review and harder to explain in NEWS.md. The order is: finish the validation passes, green CI, release, and only then reduce the exported surface.

Medium-term

Long-term

Technical debt

  • renv.lock is incomplete relative to Imports/Suggests; the Docker build leans on install_local() rather than the lockfile.
  • The recommendation/benchmark/dashboard layers are large relative to the package’s “simple implementations” remit; some carry optional dependencies that are only exercised conditionally.
  • Several htest printers and metadata fields are hand-maintained and can drift from the roxygen sources; periodic reconciliation is needed.

Open questions

  • How much of the recommendation/automation layer belongs in the core package versus a companion package?
  • What is the right default multiplier (rademacher vs mammen) and B for the null-imposed wild bootstrap across typical sample sizes?
  • Should the caching layer depend on digest unconditionally (move to Imports) or remain an optional accelerator?