Changes in version 1.0.1 A patch release for the bootstrap intervals of the reliability family, prompted by a report from an analysis of the Big Five Inventory constructs (2026-10-14), in which every BCa interval for categorical omega failed with "estimated adjustment 'a' is NA" and no interval said how many replications it rested on. The Reliability Bootstrap Counts Its Replications - Every bootstrap interval in the reliability family now says how many replications it conditions on. reliability_alpha(), reliability_kr20(), reliability_omega(), reliability_omega_categorical(), and reliability() through them record, in a bootstrap attribute, how many replications were attempted, how many returned a finite value, how many were set aside and why (an error from the refit, or no finite value, as from a fit that did not converge), and the distinct error messages with their counts. The standard error is the standard deviation of the returned replicates and the percentile and BCa limits are their quantiles, which the help pages now state; the printed table shows the counts in one line, and a single warning states them whenever a replication was set aside. Through 1.0.0 a failed replication was dropped silently. No existing row or attribute changes. - The BCa interval no longer fails when a jackknife refit fails. With B below the number of cases, boot estimates the BCa acceleration from jackknife influence values, and one leave-one-out refit that returned no value made the whole vector NA and stopped the call. The influence values are now computed in the package under boot's own rule (regression on the resampling frequencies when at least as many replications as cases returned a value, the jackknife otherwise), the leave-one-out refits that fail are counted and set aside, and the acceleration is estimated from the rest; the jackknife counts and the acceleration join the bootstrap attribute. When the acceleration or the bias correction cannot be estimated at all, the percentile interval is returned in its place with a warning, and the ci_method attribute reads "percentile (BCa acceleration could not be estimated: k jackknife replicates failed)", so the substitution is on the record. On a run where nothing fails the interval and the acceleration equal boot's to machine precision, in both regimes, so no interval that 1.0.0 computed changes. - reliability_omega() states which intervals apply to which denominator. The closed forms, the Wald intervals, and the profile likelihood are derived under the model implied ratio and apply to denominator = "model_implied" only; the bootstrap methods and "none" apply to both. The help page now says so in one place, and a request for a combination that does not apply, such as ci_method = "mlr" with the default observed denominator, stops with a message naming the denominator that does. Changes in version 1.0.0 (2026-09-21) First public release of DMAR (pronounced "Dee-Mar," for "Design, Measurement, and Analysis in R"), a greatly expanded reimagining of the MBESS package, published on CRAN on 2026-09-21. Every Example Runs, and Nothing Writes or Seeds Behind the User's Back - Every line of code in every help page example now runs. Earlier drafts carried a slow call (a bootstrap interval, a Monte Carlo planner, a refit) as a comment so that a reader could see the syntax without the check paying for it; the CRAN review of 2026-09-04 asked that no example line be commented out, and none is. Where a call was slow, it runs with a small replication count and a comment naming the count a reported analysis deserves (the defaults are unchanged); where a page demonstrated the same thing twice, it now demonstrates it once. The package still ships no \donttest{} and no \dontrun{}, and a parse-based detector in the test suite fails on any comment line that would parse as code. - The sensitivity family no longer writes a file unless asked to, and never to a default location. The save argument is gone from <>; the single switch is filename, which defaults to NULL. Supplying a path writes the per-replication results there exactly as save = TRUE used to; a throwaway run points it at tempfile(fileext = ".csv"). - A supplied seed is now set through withr::local_seed() (withr, which has no dependencies of its own, joins Imports), by way of one internal helper that every seeded function calls. The behavior is what it was, the user's generator state is restored when the function returns, but the package no longer touches .Random.seed or the global environment to do it, and no function uses <<-: the handlers that count clamped or non-converged replications keep their counts in a local environment. - The six Monte Carlo functions that silenced every warning for their duration with options(warn = -1) now muffle only the warnings their loops are known to raise (lavaan convergence and variance warnings on borderline replicates, the noncentral clamp); any other warning reaches the user. - The Bryant-Paulson distribution function integrates over the covariate shrinkage factor after the change of variables delta = 1 - u^2, under which the Beta weight of Bryant and Paulson (1976, Equation 12) is smooth on the unit interval for every number of covariates instead of carrying an integrable singularity at the endpoint where the distribution puts most of its mass. The two forms agree to about 1e-10 (checked on a grid of 288 quantile, covariate, group, and degrees of freedom combinations), the Table 1 reproduction in the tests is unchanged, and a critical value now costs about a twentieth of what it did, which is what lets every qbryant_paulson(), cv_bryant_paulson(), and ci_c_ancova_bp() example run live. - Two smaller changes from the same pass. mlmr(), mlmr_mv(), and average_variance_extracted() resample through lavaan::lavBootstrap(), the entry point that replaced bootstrapLavaan() in lavaan 0.7-2 (the package already requires that version); the results are identical. The five sensitivity functions whose ... was never forwarded anywhere (ss_aipe_sc_sensitivity(), ss_aipe_smd_sensitivity(), ss_aipe_sm_sensitivity(), ss_aipe_R2_sensitivity(), and ss_power_R2_sensitivity()) no longer accept it, so a misspelled or retired argument such as save = TRUE now stops with an error instead of being swallowed. ss_aipe_cv() with assurance supplied reports its noncentral accuracy note once, with the combined count, where it used to report it twice; and ss_aipe_cv_sensitivity() and ss_aipe_sc_ancova_sensitivity() report that note once per run, with the number of replications it arose in, rather than once per replication. An Adversarial Quality Control Pass - A package-wide audit (numerical verification against complex-step derivatives and Monte Carlo, documentation contracts run rather than read, and mechanical convention gates) closed out with these fixes. analysis_of_change() now fits an intercept-only polynomial (order = 0) under both methods; it previously stopped inside stats::poly(), and its no-fit message for the polynomial now counts occasions instead of suggesting start, which the polynomial rejects. - The equivalence sensitivity siblings speak their parents' language: ss_aipe_equivalence_smd_sensitivity() takes delta_lower / delta_upper and ss_aipe_equivalence_r_sensitivity() takes rho_lower / rho_upper, positive magnitudes with the upper bound required and the lower defaulting to symmetric, exactly as in equivalence_smd() and equivalence_r(). The signed equivalence_lower / equivalence_upper spellings, and their silent default of plus or minus 0.20, are gone. - Every AIPE planner that reports an expected interval width names the row ci_width_expected and reports the expected full width: ss_aipe_equivalence_smd() and ss_aipe_mixed_effects() previously reported the half-width as ci_half_width_expected while ss_aipe_equivalence_r() reported the full width, a trap for anyone extracting the row programmatically. - The equivalence trio attaches the conf_level attribute the ci_* family always carried, and the equivalence_c() verdict label is spelled "Noninferior only", matching the solid noninferior the rest of its page uses. equivalence_r() now validates raw data (matching lengths, at least 4 complete pairs) the way its summary-statistics path always did. convert_r_Z() and convert_Z_r() insist on a single value, as documented; vector input previously recycled the term column into duplicated rows. A follow-up ruling extended the same single-value guard to the whole scalar conversion family (convert_R2_f() and its three siblings, convert_delta_lambda() and its inverse, and convert_z_normal()), with domain checks where a map's algebra ends (an R2 at or past 1, a nonpositive group size), so no conversion can recycle vector input into duplicated rows. - Documentation corrections from the same audit: the four nonlinear simulators state that the first-order delta method behind reliability and reliability_by_occasion can drift from the realized variance ratio when random variances are large, and document the schedule attribute; the Richards example comment places the delta = 3 inflection at about 63% of total change, per its own formula; the mixed-effects examples on ?analysis_of_change now run live. One Prefix for Every Confidence Interval - The four multiple-comparison interval functions moved into the ci_* family: ci_dunnett, ci_scheffe, ci_games_howell, and ci_tukey_kramer replace dunnett_ci, scheffe_ci, games_howell_ci, and tukey_kramer_ci. The suffix forms were the only four exports naming a confidence interval outside the family prefix, and each function now pairs with its critical-value sibling (cv_dunnett, cv_scheffe, cv_tukey_hsd). The package is unreleased, so the old names are gone rather than aliased. - The noncentral-distribution toolkit is named by one rule (2026-08-21): nc_ and then the distribution, so ci_nc_t(), ci_nc_F(), and ci_nc_chisq() replace conf_limits_nct(), conf_limits_ncf(), and conf_limits_nc_chisq() (the snake-cased descendants of MBESS's conf.limits.nct() and kin), and moments_nc_t() and moments_nc_F() replace moments_nct() and moments_ncf() to match moments_nc_chisq(). The intervals join the ci_* family because a confidence interval, on the noncentrality parameter that the effect size intervals are built from, is what they compute, and "confidence limits" was vocabulary that existed only in MBESS. Splitting nc from the distribution token retires the one inherited exception (nct, ncf against nc_chisq) and restores the capital \emph{F} the package writes everywhere else (F_value, convert_F_chisq). The noncentral marker stays because the noncentrality parameter is the estimand. plot_ci() keeps its name: it is a plot first. The old names are gone rather than aliased; each page names its earlier self in the description. - The correlation intervals now carry the names of their estimands, matching the rest of the correlation family (ss_aipe_r, ss_power_r, var_r, expected_r, equivalence_r): ci_r() is the confidence interval for the simple Pearson correlation (renamed from the MBESS-heritage ci_cc(), with the estimate row renamed from est_cor to r), and ci_R() is the interval for the population multiple correlation coefficient (its former lowercase alias spelling is gone). Cross-references across the package were audited against this distinction and every one now points at the interval it meant. Because the two natural file names differ only by case, which case-insensitive filesystems refuse, both functions live in R/ci_correlation.R and share the ci_correlation help page. - Kish's design effect function is design_effect(); the abbreviation deft() is gone as a function name, while the returned table keeps its design_effect and deft rows, deft being the standard term for the standard error inflation factor, the square root of the design effect. - The remaining exported alias pairs were resolved to single names. Fisher's Z is written with a capital Z throughout the package, because it is the variance-stabilizing transform of a correlation and not a z-score, so the converts are convert_r_Z() and convert_Z_r() only (the lowercase spellings are gone) and the prose and math were swept to match. The limits of agreement function is limits_of_agreement(), with loa() kept as its short alias and bland_altman_loa() gone (the method is named for what it computes; Bland and Altman are credited in the references). reliability_omega_categorical() and covmat_from_cfa() are the only names for those functions; the reliability_omega_c() and covmat_from_cfm() aliases are gone. The dataset alias bindings HS_Data and Prime_Time are gone as well: every dataset carries exactly one name, the documented snake_case one, and unlike the alias bindings the canonical names work with data(). Fitting Change Models, Linear and Nonlinear - The vocabulary of the longitudinal simulators names what the rows are: the identifier column identifies units (persons, animals, trees, classrooms), n counts units, and the former group column is population, one level per data generating parameter vector. - Measurement schedules can now be unit-specific, in every simulator: in place of a shared target_times grid, time_range = c(lower, upper) draws each unit's own measurement times uniformly between the bounds, with occasions fixing the number of times per unit or c(min, max) letting it vary, so designs such as age at testing rather than grade at testing are simulated directly. The polynomial simulator additionally requires every unit's count of occasions to reach P + 1, so each simulated trajectory identifies the polynomial it came from. - analysis_of_change() closes the loop the simulators open: it fits any of the four nonlinear change models, or a polynomial of any order, to longitudinal data. The default two-stage method fits one curve per unit, from that unit's data alone, with data-driven starting values, and summarizes the unit-level parameters by their mean, their standard deviation and variance across units (the individual differences), and the standard error of the mean; method = "mixed" instead estimates the proper random-coefficients model simultaneously, lme4::lmer() for the polynomial and nlme::nlme() for the nonlinear curves started at the two-stage estimates, so sd_units becomes a variance component purged of estimation noise. The help page positions the function candidly against nlme::lmList(), nlme::nlsList(), and the self-starting SS* curves: what it adds is the landmark parameterizations, the simulator match, and one tidy interface across linear and nonlinear change. With a single trajectory (or id = NULL) it reduces to one nonlinear least squares fit reported with asymptotic standard errors, so N = 1 is one unit's change. Non-converging units are dropped with a single counted warning and the effective count travels as the n_used attribute; the full matrix of unit-level estimates rides along for plotting or as starting values for a simultaneous nlme::nlme() fit, and the help page states plainly that the between-unit spread of estimates includes estimation noise, which a variance-component model separates. Nonlinear Growth Curve Simulators - Four random-coefficients nonlinear change simulators join simulate_longitudinal_polynomial(), sharing its interface (several populations of units, between-unit parameter variances and correlations, level-one error by variance or by target reliability, error correlation structures, assessment-time jitter) and its long-format return that feeds plot_trajectories() and nonlinear mixed-model fitters: simulate_longitudinal_negative_exponential() (asymptotic regression), simulate_longitudinal_logistic(), simulate_longitudinal_gompertz(), and simulate_longitudinal_richards(), whose shape parameter delta subsumes the logistic (delta = 1) and the Gompertz (delta -> 0) as special cases, relations the tests pin exactly. The parameterizations are those of Kelley (2005, dissertation; 2008, Methodology), in which every parameter is a landmark of the change process (floor, ceiling, moment of fastest change, curvature, inflection height) and the intercept-shifting zeta frees the lower asymptote from zero; the Richards application follows Guo, Cheng, and Kelley (2016). A new vignette, "Nonlinear Growth Curves and the Meaning of Their Parameters", illustrates all four curves, the Richards unification, and the polynomial comparison: a ninth-order polynomial needs ten uninterpretable coefficients to track a four parameter Gompertz inside the data and still collapses the moment it extrapolates. One Word for the Equivalence Family - The equivalence tests are named for the question they answer: equivalence_smd(), equivalence_r(), and equivalence_c() replace tost_smd(), tost_r(), and tost_c(), and the AIPE planners follow (ss_aipe_equivalence_smd(), ss_aipe_equivalence_r(), with their sensitivity siblings). The whole family now speaks the same word as the planning and plotting surfaces that always did (power_equivalence_md(), ss_power_equivalence_c(), plot_equivalence()). The procedure is unchanged, Schuirmann's two one-sided tests, and each help page says so by that name; the reported TOST \emph{p}-value keeps its standard p_tost term. The old names are gone rather than aliased. Sample Size Planning for Correlation Equivalence - ss_aipe_equivalence_r() plans the sample size for an equivalence question about a Pearson correlation: the smallest \emph{N} whose 100(1 - 2 alpha)% Fisher's \emph{Z} interval (the interval equivalence_r() and ci_r() invert) has expected width at or below the target, with an optional Monte Carlo assurance correction. At the conservative default planning value of 0 the answer has a closed form, and the tests anchor the search to it. Its Monte Carlo sibling ss_aipe_equivalence_r_sensitivity() follows the family API and reports, alongside the family's width and coverage summaries, the realized proportion of equivalence verdicts inside the chosen bounds. This fills the gap noted when the equivalence family was reviewed: the SMD had an AIPE planner for its equivalence interval and the correlation did not. The Examples Teach From the Package's Own Data - The help-page examples now use DMAR's own datasets rather than the base-R teaching sets: Dunnett-style comparisons run on depression_bdi with its wait list control, the studentized range procedures on test_market's six panels, the unequal-variance and rank methods on drinks_trial's skewed outcome, the factorial and generalized eta squared examples on pygmalion's manipulated treatment crossed with measured grade, and the correlation, regression, reliability, and multivariate examples on the holzinger_swineford battery, whose second-form tests carry real missingness that now powers the FIML demonstrations in mlmr() and mlmr_mv() in place of artificially punched holes. Examples that fit lme4 models keep lme4::sleepstudy, since those pages require lme4 regardless. The ecvi() example and tests likewise moved from lavaan's copy of the 1939 data to the package's own holzinger_swineford. Numeric claims in example comments were recomputed against the new output throughout. - Spell checking is now wired in: DESCRIPTION declares Language: en-US and inst/WORDLIST carries the package's technical vocabulary, so devtools::spell_check() runs clean. A Quieter, Faster Test Suite and ggplot2 4.0 Compatibility - plot_equivalence() no longer passes the fatten argument of ggplot2::geom_pointrange(), which ggplot2 4.0.0 deprecates. The point size is set through the size aesthetic at the value that draws the same figure on every supported ggplot2 (>= 3.4.0), so building the plot under ggplot2 4.0 no longer raises a deprecation warning. - reliability_omega() and reliability_omega_categorical() now validate their inputs before the courtesy message that a default call reports no confidence interval, so a call that is about to fail with an informative error no longer receives advice first. - The test suite runs its files in parallel (Config/testthat/parallel: true, with the slowest files scheduled first through Config/testthat/start-first; the testthat floor moves to 3.2.0). The heaviest Monte Carlo checks were recalibrated to smaller replication counts whose assertions still hold with room to spare, duplicated planner calls across neighboring tests were consolidated into single calls, and tests no longer leak messages, notes, or printed tables into the run's output. A full devtools::test() on the maintainer's machine dropped from about 20 minutes to about 5, with no warnings and nothing skipped. One Return Schema Across the Sensitivity Family - Every ss_aipe_*_sensitivity() member now returns the family's documented schema: mean_ci_width / median_ci_width / sd_ci_width for the realized interval widths, pct_ci_less_w for the proportion of intervals at or below the planning width, pct_ci_miss_low / pct_ci_miss_high / total_type_I_error for the empirical non-coverage (proportions on the 0 to 1 scale, so the total is the sum of its tails), mean_X / median_X / sd_X for the member's own estimand, and input echoes named for their unit (total_N or n_per_group for the evaluated size, true_X, estimated_X, width, conf_level, and, when one was supplied, assurance). The core term vector lives once, as the internal registry constant .SS_AIPE_SENS_CORE_TERMS in R/dmar_tidiers.R, and a family-wide contract test asserts every member against it. Every member's @return now lists exactly the rows the function returns. - The term names that departed from the schema moved to it, loudly (the package is unreleased; no old name survives). ss_aipe_R2_sensitivity() drops the lowercase _r2 suffixes and pct_less_w (mean_r2 is mean_R2, mean_ci_width_r2 is mean_ci_width, the realized-limit rows are mean_lower_limit and siblings, the one-sided widths are mean_ci_width_lower / mean_ci_width_upper); the four term-matching reads inside ss_aipe_R2()'s assurance search were updated with it. ss_aipe_sc_sensitivity(), ss_aipe_sc_ancova_sensitivity(), and ss_aipe_sm_sensitivity() retire mean_full_width and pct_Width_obs_narrower / pct_width_obs_narrower; ss_aipe_smd_sensitivity() retires pct_less_desired; ss_aipe_c_ancova_sensitivity() retires width_narrower and mean_width_obs (its standard error comparison is now mean_se_ratio); ss_aipe_rmsea_sensitivity() retires rmsea_pop, desired_width, mean_width, and, most importantly, an output row named assurance that actually reported the realized width-attainment proportion, now pct_ci_less_w so the name no longer collides with the planning input; ss_aipe_sem_path_sensitivity() retires width_less_than_desired and the type_I_err* trio. - Four members scaled their non-coverage rows by 100 while the rest of the family reported proportions: ss_aipe_sm_sensitivity(), ss_aipe_smd_sensitivity(), ss_aipe_sc_ancova_sensitivity() (both divisor branches), and ss_aipe_c_ancova_sensitivity() (which also scaled its width-attainment row). All are now proportions on the 0 to 1 scale, completing the sweep that earlier fixed ss_aipe_sc_sensitivity(), ss_aipe_cv_sensitivity(), and ss_aipe_reg_coef_sensitivity(). - The family contract test caught a real defect while it was being written: the divisor = "s_anova" branch of ss_aipe_sc_ancova_sensitivity() read the confidence limits out of ci_sc_ancova() by row position ([2, 2] and [4, 2]) when that function returns three rows, so the branch treated the point estimate as the lower limit and NA as the upper: its realized widths were NA and its "Type I error" rows were nonsense. The limits are now read by term name, as the s_ancova branch always did, and the branch's summaries are meaningful for the first time. - Members that reported only width summaries now also report their estimand: mean_psi and siblings in the three contrast members, mean_sm, mean_smd, mean_rmsea, and mean_path, computed from the same replications the widths come from. The echo rows the schema calls for were added where missing (ss_aipe_R2_sensitivity(), ss_aipe_cv_sensitivity(), ss_aipe_reg_coef_sensitivity() and its rc / src wrappers, the contrast members, and ss_seq_c_sensitivity(), which now echoes half_width, true_psi, true_sigma, alpha_level, and m0). - The power siblings joined the sweep: ss_power_R2_sensitivity() and ss_power_reg_coef_sensitivity() echo their planning inputs (p, true_R2 / true_b_j, estimated_R2 / estimated_b_j, desired_power, NA when a size was specified directly, and alpha_level), and their realized-R^2 rows follow the meaningful-capital rule (mean_R2, and in the omnibus member mean_F / F_crit). tidy() and glance() for the dmar_ss_power_sensitivity class are unchanged; the echoes ride along in glance(). The ICC Sample Size Planner Now Plans the Average-of-k Forms - ss_aipe_icc() accepted and documented the six Shrout-Fleiss type labels but planned every one of them on the single-rater scale, so average-of-k plans were materially undersized. The planning value and target width are now interpreted on the scale of the requested form: an average-of-k value is mapped to the single-rater scale through the inverse Spearman-Brown relation and each candidate confidence limit is mapped back (the convention var_icc() uses), and type is now validated, so an unrecognized label fails instead of silently planning ICC(1,1). Average-of-k recommendations move: at rho = .70, k = 3, and width = .20, planning for ICC(1,k) now recommends n = 110 (realized mean width .20 across 2,000 Monte Carlo replications of the F-based interval) where the undersized plan recommended n = 69 (realized width .26); at width = .10 the recommendation is n = 421, and at rho = .90, width = .10 it is n = 52. Single-rater plans are unchanged. The planned form travels as the icc_type attribute on the returned table. - ss_aipe_icc_sensitivity() had the matching defect on the generator side: it treated true_rho as the single-rater ICC no matter the type. For the average-of-k forms it now simulates data whose population ICC at the average-of-k level equals true_rho, so the realized estimates, widths, and coverage refer to the form being planned; type is validated the same way. - The claim in ?ss_aipe_icc that the assurance correction over-recommends sample size by 25 to 40 subjects was backwards. At the page's own condition (rho = .70, k = 3, width = .20, assurance = .80) the recommended n = 79 delivers an empirical assurance of about .77, and n = 81 is the smallest sample size that reaches .80 (10,000 Monte Carlo replications). The Details section now says so and points to ss_aipe_icc_sensitivity() for checking a strict assurance target. The Noncentral F Clamp Warning Speaks the Caller's Language - When an observed F falls below the alpha_lower critical value of the central F-distribution, the lower noncentrality limit is 0 by construction; that is a normal consequence of a small observed effect, not a failure. ci_nc_F() still warns once in that case, but the message now states the consequence for the interval (the lower confidence limit is 0) instead of describing achieved tail probabilities, and every function that builds its interval by inverting the noncentral F through it (ci_snr(), ci_srsnr(), ci_pvaf(), ci_R2() with fixed predictors, ci_eta_squared(), ci_eta_squared_partial(), ci_omega_squared(), ci_eta_squared_generalized() with the parametric method, and ci_mahalanobis()) restates it for its own effect size, for example "the lower confidence limit on the signal-to-noise ratio is 0", at most once per call. Previously ci_snr() and ci_srsnr() surfaced the inner wording, which pointed users to a prob_greater column those functions do not return. The warning carries the condition class dmar_nc_F_clamp, which the iterative callers (ss_aipe_R2(), ss_aipe_omega_squared(), factorial_anova(), simple_effects_AB()) now match by class when deduplicating. - A genuine failure of the inner root finding is no longer a bare uniroot() message: the error now names the function that was called, reports the F-statistic, degrees of freedom, and tail probabilities involved, and says what to try. design_consequences() Now Uses the Exact Noncentral t When df Is Finite - With finite df, the significance lens of design_consequences() (power, type_s_error, exaggeration_ratio) is now computed from the noncentral t distribution of the test statistic, the exact distribution when the standard error is estimated from the data and the same sampling model the precision lens already used; the exaggeration ratio integrates the truncated normal moments over the chi distribution of the estimated standard error. The previous code evaluated a location-shifted central t, the known-se approximation behind Gelman and Carlin's retrodesign(), so the help page promised the noncentral t while the code delivered the approximation. Small-df results move: at n = 5 per group with a true effect of d = 1, power is now 0.2863 (was 0.2469; a two-million replication Monte Carlo of the design gives 0.2860 with simulation standard error 0.0003, and base R's power.t.test(strict = TRUE) agrees exactly), the Type S error is 0.00129 (was 0.00937), and the exaggeration ratio is 1.658 (was 1.915). The differences fade as df grows (negligible by about 60 per group), and the df = Inf normal case is unchanged. The Robust Standardized Mean Difference Scales Correctly at Every Trim - smd_trimmed() applied the reciprocal of the Algina-Keselman-Penfield scaling constant at every trimming proportion other than the 0.20 default: the internal constant computed the Winsorized variance of a standard normal correctly and then returned 1 / sqrt(win_var) where the definition calls for sqrt(win_var), and a hard-coded 0.642 at trim = 0.20 masked the error at the default while making the estimate discontinuous there (trim = 0.1999 returned 2.43 times the value trim = 0.20 returned). The constant is now sqrt(win_var) at every trim and the hard-coded branch is gone. At the default the constant moves from the rounded 0.642 to its exact value 0.6419398, so estimates at trim = 0.20 change by less than one part in ten thousand; at any other trim the correction is substantial (previous estimates were 1.47 times too large at trim = 0.10, 4.99 times too large at trim = 0.30, and 17.99 times too large at trim = 0.40). The help page identity is corrected to match: 0.642 is SD(X_W) / SD(X), that is sqrt(Var(X_W) / Var(X)), for a standard normal Winsorized at 0.20, not Var(X) / Var(X_W). The Robust Standardized Mean Difference Interval Now Uses the Yuen-Welch Degrees of Freedom - smd_trimmed()'s help page promised a confidence interval on the Yuen-Welch degrees of freedom, but the code inverted the noncentral t at h_1 + h_2 - 2 degrees of freedom with noncentrality d_R * sqrt(h_1 * h_2 / (h_1 + h_2)); the Yuen-Welch value was computed, returned in the df_yuen row, and never used. The interval now follows the construction in Keselman, Algina, Lix, Wilcox, and Deering (2008): Yuen's t-statistic on the trimmed-mean difference (their Equation 8) is referred to a noncentral t distribution with the Yuen-Welch approximate degrees of freedom (their Equation 9), and the noncentrality limits are rescaled to the d_R metric. Feeding the summary statistics of the paper's worked example (their Tables 1 and 3) through this construction reproduces the printed robust effect size intervals [0.31, 3.37] and [0.10, 1.11] (p. 119) to the precision the rounded published inputs support, while h_1 + h_2 - 2 degrees of freedom give [0.40, 3.31] for the first: the paper's intervals use the Yuen-Welch value. The former noncentrality also understated the observed statistic (by about 16% at the default trim under equal Winsorized variances), so intervals move even where the two degrees of freedom nearly agree: on the help page example the interval is now [-0.88, 0.08] where the old construction gave [-0.97, 0.17]. A Consistent Confidence Interval for Lin's CCC - lin_ccc() now builds its confidence interval on Lin's (1989) z-transformed standard error, with the correction noted in Lin (2000), and the former default method = "king_chinchilli" is removed. The removed variance was not a consistent estimator of the sampling variance of the z-transformed CCC: when the two means and variances are equal it inflates the correct asymptotic variance by exactly the square of (1 + rho^2) / (1 - rho^2), already about 2.8-fold at a CCC of .5 and several hundred-fold at .95 (and by a comparable factor otherwise), so its intervals were nearly vacuous. The help page's own first example returned CCC = .928 with CI [-0.977, 1.000]; the same example now returns [0.871, 0.960], matching the independent DescTools::CCC() z-transform interval to ten decimals, and the Lin interval's simulated coverage is .952 at nominal .95 (bivariate normal, rho = .5, n = 50, where the removed default covered .982 with intervals 61% wider). The removed formula was also not King and Chinchilli's (2001) estimator, so keeping it under that name would have credited a wrong formula to real authors; a correct King-Chinchilli variance may return in a later release. Calls that request method = "king_chinchilli" now fail loudly. The Fleiss Kappa Test Uses the Corrected Null Variance - fleiss_kappa() computed its z statistic and p-value from a null variance that treats the category marginals as known constants, not from the estimated-marginals null variance of Fleiss, Nee, and Landis (1979), the correction of the standard errors in Fleiss (1971), even though the help page credited that paper. The two expressions coincide at uniform marginals, which is how the error hid, and diverge as the marginals skew: at N = 1000, m = 5, and marginals (.85, .10, .05), the old null standard deviation was 3.8 times the empirical one (.0303 versus .0080). Because the known-marginals expression is never smaller than the corrected one (they are equal only at uniform marginals), every affected z was understated and every affected p-value overstated; the test was conservative, never anticonservative. On the help page's own Fleiss (1971) Table 1 example the z statistic moves from 15.64 to 17.65, now matching irr::kappam.fleiss to ten decimals. The point estimate and the confidence interval do not move: kappa is unchanged, and the se, lower_limit, and upper_limit columns come from the Gwet (2008) linearization, which was correct all along. One-Sided Dunnett Intervals Now Contain Their Point Estimates - ci_dunnett(alternative = "less") formed its simultaneous upper bounds with the signed critical value that cv_dunnett() reports for that alternative, a negative lower-tail quantile, which placed every bound at diff - |d| * se: below the point estimate it was supposed to bound, and in contradiction with the adjusted p-values printed beside it (on the PlantGrowth example both "less" rows reported an upper limit below zero, a rejection, beside adjusted p-values of 0.162 and 0.989, no rejection). Simultaneous coverage of the true differences measured 0.00115 against the nominal .95 in a balanced null design with four groups and n = 10 per group. The critical value's magnitude is now applied on the side the alternative dictates, so the "less" bound is diff + |d| * se; coverage in the same design measures 0.94685, and the PlantGrowth "less" upper limits move from -0.928 and -0.063 to 0.186 and 1.051, agreeing with multcomp::glht()'s one-sided limits to about four decimal places (the remaining daylight is multcomp's simulated-quantile error) and with the adjusted p-values on every row. The alternative = "greater" interval already used the positive critical value and is unchanged, as are the two-sided intervals and all adjusted p-values. anova_within_two_way() Declines to Estimate an Inestimable Epsilon - When an effect's numerator degrees of freedom exceed n - 1, the covariance matrix of the effect's orthonormal contrasts is singular and the Greenhouse-Geisser formula returns an artifact bounded above by (n - 1)/df regardless of the population epsilon (even under exact sphericity, where the population value is 1); the Huynh-Feldt value derived from it is equally meaningless. anova_within_two_way() previously reported these artifacts as estimates. The Greenhouse-Geisser and Huynh-Feldt rows for such an effect now carry NA in epsilon, the adjusted degrees of freedom, and the p-value, with one warning naming the condition; car::Anova likewise declines to report the corrections when the effect's error matrix is singular. The unadjusted and lower-bound rows are unchanged: the lower bound 1/df is Geisser and Greenhouse's a priori bound, not an estimate, and remains valid however few the subjects (Maxwell, Delaney, & Kelley, 2027, Chapters 11 and 13). ci_r() Now Requires at Least Four Observations - ci_r() accepted any sample size and went quietly wrong below n = 4: at n = 3 it returned the vacuous interval [-1, 1] (the Fisher's Z variance 1/(n - 3) is infinite there), and at n = 2 it returned NaN limits. The function now stops with an informative error for n < 4, and the n = 3 message explains why no usable interval exists at that boundary. - The same unguarded 1/(N - 3) sat behind ci_method = "fisher" in reliability_alpha(), reliability_omega(), and reliability_kr20(); the Fisher interval there now stops for N < 4 with the same explanation. The package's other Fisher's Z consumers (var_r(), equivalence_r(), meta_r(), ss_power_r(), correlations_test(), correction_for_attenuation(), expected_r()) already validated their sample sizes. The AIPE Sensitivity Family Reports Coverage as Proportions - Three members of the ss_aipe_*_sensitivity family scaled some or all of their coverage and width-attainment rows by 100 while the rest of the family reported proportions. ss_aipe_sc_sensitivity() reported type_I_error_upper and type_I_error_lower as percentages; ss_aipe_cv_sensitivity() reported pct_ci_less_w, pct_ci_miss_low, and pct_ci_miss_high as percentages beside a total_type_I_error that was already a proportion, so its own rows did not add up; and ss_aipe_reg_coef_sensitivity() (inherited by ss_aipe_rc_sensitivity() and ss_aipe_src_sensitivity()) scaled all four. These rows are now proportions on the 0 to 1 scale everywhere, so total_type_I_error equals the sum of pct_ci_miss_low and pct_ci_miss_high, and a realized Type I error compares directly to 1 - conf_level with no per-function rescaling. Term names are unchanged; only the scale moved. The MBCO Likelihood Ratio Is Now Branch-Deterministic - mediation_mbco()'s null hypothesis for an indirect effect is a union of branches (the product is zero when any factor is), and the constrained search could converge to a worse-fitting branch on some platforms and OpenMx builds, inflating the likelihood ratio statistic. When every constrained algebra is a pure product of free parameters, the branches are now also fit directly as ordinary unconstrained models with one factor fixed to zero, and the reported statistic is defined by the best-fitting branch on every platform. Non-product constraints keep the multi-start constrained search. tidy() and glance() Speak DMAR's Names, on Every Table - The broom verbs now return DMAR's native column names: p_value, se, ci_lower, ci_upper, p_adjusted, conf_level, std_estimate, R2, adj_R2, df_residual, and so on, replacing broom's dotted p.value / std.error / conf.low across every tidier in the package. One naming system now covers every DMAR surface; a pipeline that feeds a tool expecting broom's dotted schema renames the columns at that boundary. - The wide tables answer the verbs too. content_validity_index(), dmacs(), measurement_invariance(), and measurement_alignment() gained bespoke tidy()/glance() pairs (items, ladder rungs, and groups as terms; the scale and model level summaries as the one-row glance), and a generic wide branch in the default methods serves htmt(), average_variance_extracted(), and any future wide table (term from the label columns, estimate from the first numeric column, remaining columns passed through). The output vignette's promise that the verbs answer everywhere is now literally true. One Bootstrap Vocabulary, Three New Bootstrap Intervals - B is the number of bootstrap replications everywhere. mlmr() and mlmr_mv() rename boot_R, R2_mixed_effects() and ci_eta_squared_generalized() rename R, and krippendorff_alpha() renames n_boot; the effective-count row is now B_used. Old argument names fail loudly. - cohen_kappa() and fleiss_kappa() gain bootstrap intervals (ci_method = "percentile" or "bca", B = 10000, seed), redeeming the kappa page's own advice that the Wald interval can have poor small-sample coverage (Blackman & Koval, 2000; Zapf, Castell, Morawietz, & Karch, 2016). Subjects are resampled, table input is expanded to the equivalent pairs, and the se, z_value, and p_value columns keep their asymptotic definitions; only the interval changes. - average_variance_extracted() gains a percentile bootstrap (ci_method = "percentile", B = 1000, refitting the model per replication) and now always returns ci_lower / ci_upper columns (NA under ci_method = "none"). No interval is possible from loadings alone, and the function says so. - krippendorff_alpha() no longer bootstraps by default (boot = FALSE), matching the package-wide rule that no analysis runs a bootstrap unless asked; its verbal reliability benchmarks were removed in favor of reporting the coefficient with its interval. - Failed bootstrap replications are dropped, never fatal: mediate() no longer errors when a degenerate resample returns no indirect effect, and htmt() no longer aborts when a resample leaves a block's average within-construct correlation nonpositive. Both drop the replication, warn once with the count, and stop only when fewer than 100 replications survive. - No help page wraps its examples in \donttest{} or \dontrun{} any more. Under R CMD check --as-cran, one \donttest{} block anywhere makes R run the whole example corpus twice, so the wrapper cost time rather than saving it. The examples that were slow are now fast. Replication counts in the cheap demonstrations were lowered, with a comment naming what a reported analysis deserves. No example runs a bootstrap confidence interval: those calls are carried as commented code, so the syntax is still on the page for a reader who wants it, and the surrounding prose explains the interval and when to ask for it. The randomization tests keep their resampling, since permuting the data is what those functions do and their examples cost a tenth of a second. Anything else expensive is commented out the same way, each passage introduced by a sentence saying what it does and why it is not run. The data behind every example are unchanged. The slowest help page now takes 0.38 seconds, and all 302 together take 8 seconds. The CFA Family: One General Function, Two Convenience Wrappers - cfa_1() is now the one factor special case of cfa_k(), a convenience wrapper rather than an independent implementation, and the new cfa_2() is the two factor sibling. cfa_1() only requires the data (and, when the data hold more than the items, a vector of item names); cfa_2() takes the items of each factor as factor_1 and factor_2. Both forward everything to cfa_k(), so there is now a single fitting implementation, one output schema (with confidence interval columns), and one set of fit index choices; under a robust estimator every CFA surface now reports the robust index versions. The former cfa_1() extras moved or dissolved: composite reliability with the observed denominator is reliability_omega(denominator = "observed"), the omega output mode is the omega_f1 row of the standard table, and the term names follow the cfa_k() convention (lambda_f1_, psi_f1_, omega_f1). - data and S are now separate arguments across the CFA family. Raw data are passed as data and a covariance matrix as S (with N); an argument never means both. cfa_k() refuses a square symmetric matrix passed as data, naming the fix. cfa_1() keeps its conveniences: unnamed input is auto-named y1, y2, ..., and items defaults to every column. Measurement Invariance Beyond the Exact-Invariance Ladder - measurement_invariance() now fits any measurement model, not only the one-factor case. It accepts model as lavaan syntax or as a named list mapping factors to their items (the items argument remains as the one-factor convenience), along with ordered, missing for full information maximum likelihood, group_partial for the partial invariance case, and parameterization. With ordered indicators the ladder itself changes: thresholds carry the location information, so a thresholds rung is fitted between configural and metric, following Wu and Estabrook (2016) and Millsap and Yun-Tein (2004). Constraining loadings before thresholds, as the continuous ladder does, tests the wrong hypothesis for ordered items. The chi square difference test is the scaled one whenever the estimator is robust or the data are ordered, and the fitted lavaan objects are returned on a "fits" attribute so a caller can run score tests and partial invariance refits without paying for the ladder twice. - dmacs() reports the dMACS effect size of measurement noninvariance (Nye & Drasgow, 2011): the expected difference between two groups' measurement equations for an item, integrated over the focal group's latent distribution and standardized by the pooled item standard deviation. A score test says a loading or intercept differs detectably; dMACS says whether the difference is large enough to matter. The defining integral has a closed form under a normal latent variable, so no numerical integration is used, and the two agree to machine precision in the tests. Accepts a fitted multiple group lavaan model or the parameters a paper reports. The help page states plainly that the index is meaningless from a configural fit, where the groups share no metric. - measurement_alignment() implements the alignment method of Asparouhov and Muthen (2014). Exact invariance essentially never holds across many groups, which leaves the ladder stalled at configural and group comparison blocked. Alignment estimates the group factor means and variances that make the measurement parameters as nearly invariant as possible, minimizing a simplicity function whose fourth-root component loss tolerates a few large differences and punishes many small ones. Both the fixed and free identifications are available, the optimizer runs from several starts because the surface has local minima, and the number of distinct optima found is reported so a solution is never presented as unique when it is not. Item Response Theory, as the Categorical Factor Model - irt_grm() fits Samejima's (1969) graded response model. It does so the way the rest of the package works, by fitting the categorical factor analysis model with lavaan and converting the solution: discrimination a_i = lambda_i / sqrt(1 - lambda_i^2) and location b_ik = tau_ik / lambda_i. The two models are the same model in different parameterizations (Takane & de Leeuw, 1987), so this adds item response theory without a second estimation engine and without leaving the factor analytic tradition. Both the normal ogive and the logistic metric are available. - irt_information() and plot_irt_information() give the item and test information functions and the standard error of the latent trait, SE(theta) = 1 / sqrt(I(theta)). This is precision as a function of where the respondent sits on the trait, which is what a single reliability coefficient cannot express: a scale can have excellent omega and still measure poorly over the range a study cares about. Verified against the closed form for the dichotomous case, which the graded model must reproduce exactly. Content Validity - content_validity_index() computes the item level content validity index from a panel of expert relevance ratings, with the modified kappa that corrects it for chance agreement (Polit, Beck, & Owen, 2007), Lawshe's (1975) content validity ratio, and the scale level S-CVI/Ave and S-CVI/UA. Each I-CVI carries an exact binomial confidence interval, because an index computed from five or six experts is a proportion with real uncertainty and reporting it as a bare point estimate overstates what a small panel establishes. This is evidence about the items, gathered before any data are collected. Mediation inference via model-based constrained optimization - mediation_mbco() implements the model-based constrained optimization (MBCO) procedure of Tofighi and Kelley (2020, Psychological Methods): a likelihood ratio test of any smooth function of path coefficients (an indirect effect, a total effect, a contrast of two indirect effects) formed by refitting the mediation model subject to the nonlinear constraint that the function equals zero. The model is specified in lavaan syntax (observed or latent variables; parallel or sequential mediators) and fit in OpenMx, whose optimizers support the nonlinear equality constraints the null model requires. The function enumerates the total, direct, total indirect, and every specific indirect pathway from x to y, reports each with a delta method standard error and a profile likelihood, Monte Carlo, or Wald confidence interval, tests each with the MBCO likelihood ratio statistic and its p-value, and reports AIC and BIC differences and the change in each endogenous R-squared under every null model. Because the null set of a product constraint is a union of surfaces, each null model is refit from several starting configurations and the best feasible solution is kept, so the reported statistic reflects the globally best-fitting null model rather than a local branch. Accepts raw data or the summary statistics a paper reports (covariance matrix, means, and sample size), which reproduce the raw-data analysis exactly; the tests replicate the published empirical example from its Table 1 moments. A group argument turns the model into a multiple-group SEM in which every effect is estimated per group and its between-group difference is tested, which is moderated mediation with a categorical moderator. A moderator argument probes continuous moderation stated in the syntax with : interaction terms (or precomputed product columns): each moderated pathway effect becomes a symbolically derived polynomial in the moderator, reported as conditional effects at probe values (the mean and one standard deviation either side by default), the index of moderated mediation (Hayes, 2015) tested by likelihood ratio rather than bootstrap, and, when a pathway is moderated in several places, a joint constancy test whose null model imposes several nonlinear constraints at once. hypotheses accepts a named list whose multi-expression elements are likewise tested jointly. Constrained null models are started on every branch of the constraint's null set (including exact conditional-coefficient branch starts for probed effects) and each solution is polished by a warm restart, so the reported statistic reflects the best-fitting feasible null model. Structural guardrails refuse pathway enumeration for nonrecursive (feedback) structures and warn on binary endogenous variables, on interaction terms no declared moderator accounts for, and on interactions missing their main effect (the principle of marginality). - plot_mediation_mbco() draws the conditional effects of a moderated mediation_mbco() analysis as curves over the moderator's observed range, one per moderated pathway effect, with a pointwise Monte Carlo confidence band, the probed values marked, a dashed zero line whose band crossings estimate the Johnson-Neyman boundaries, and a rug of the observed moderator values so extrapolation is visible. The band's polynomial is the same stored quantity the table probes, evaluated over the whole range; the help page is explicit that the band is pointwise and that boundary locations read from it are estimates, with the table's constancy test as the formal companion. Returns a plain ggplot object in the Okabe-Ito palette. API and Documentation Consistency - var_ete() computes the variance of the estimated treatment effect at selected covariate values in a two-group ANCOVA with heterogeneity of regression and a random covariate (Li, McLouth, & Delaney, 2020), the reimplementation of MBESS::var.ete(); tested against the MBESS reference on every branch and dogfooded in the Pygmalion vignette. - tidy() and glance() answer on every DMAR result. Two default methods on the dmar_tbl class are the floor under the package: any result table answers tidy() with the broom-shaped long view (term, estimate) and glance() with the one-row wide view, repeated terms disambiguated rather than dropped. The family methods sit ahead of the defaults and keep their richer views, and two families join them: the ss_aipe_* planners carry a new dmar_ss_aipe class whose tidy() reports the planned size beside the desired width it was planned against (term, estimate, width), through the same size registry the power planners use and a width registry beside it, and whose glance() widens the echoed inputs. ss_power_pcm(), the one power planner missing its family class, joins dmar_ss_power, so its tidy()/glance() no longer error, and ci_eta_squared_generalized() joins its siblings in dmar_ci_anova. - One sample size vocabulary across every planner. A planner's answer row is now named for what it counts: necessary_N (total), necessary_n_per_group, necessary_n_per_cell, or necessary_n_clusters; a user-fixed size echoes as specified_*; and total_N appears only as the implied-total companion beside a per-unit answer, never as an answer's name. Before this sweep the same word meant different things in different planners: sample_size was the total in ss_aipe_R2() and its seven siblings but the per-group size in ss_aipe_c() and its three, ss_aipe_smd() said sample_size_per_group, ss_power_pcm() carried the MBESS-era ss_c and ss_t pair (two rows for one number in a balanced design, now one branch-named row), ss_power_factorial_ancova() used one bare n_per_cell for both its planned and its user-supplied branch, and the cluster planners' answers had no prefix at all. Sensitivity outputs echo the evaluated size under its bare unit name (total_N, n_per_group), and the six sensitivity functions whose specified_N argument actually meant a per-group size now call it n_per_group (ss_aipe_c/sc/sc_ancova/smd/equivalence_smd/pcm_sensitivity). Two term names in the cluster family that contained literal spaces are underscored. The tidy()/glance() size recognizer no longer accepts the legacy names, so a stray old producer fails a test instead of slipping through, and a 216-table characterization grid recorded before the sweep reproduces identically after it, so only names moved, never values. The package is unreleased; old names fail loudly. - The number of predictors is p everywhere. ci_rc(), ci_src(), ss_aipe_rc(), ss_aipe_src(), ss_power_rc(), and plot_R2() renamed J to p, and ci_R() renamed K to p, matching ci_R2(), ci_reg_coef(), and the rest of the regression family. J remains only in the partial and semipartial correlation family, where it counts the variables partialed out (a different quantity; J = 0 is the simple correlation). The package is unreleased, so the old names fail loudly rather than being aliased. - ci_rc() and ci_src() are documented as the thin wrappers they are around ci_reg_coef(), the general engine, with titles that distinguish the unstandardized, standardized, and general cases. - Every function help-page title is now AP title case with no trailing period, matching base R convention (previously the package mixed sentence case and title case). Ten Help Pages Now State Exactly What the Code Computes A numerical audit compared every displayed formula and quoted magnitude on these pages against the quantity the function computes. In each case the computation was correct and the page was not, so no returned value changes; the documentation now matches the code, and new tests recompute each corrected expression independently and assert agreement with the function output. - expected_partial_r() displayed the expectation with every index one lower than the Olkin-Pratt formula under the n to n - J substitution the code makes; as printed, the formula can exceed 1, an impossible value for the expectation of a correlation. The page now prints E[r] = rho 2F1(1/2, 1/2; (n - J + 1)/2; rho^2) Gamma((n - J)/2)^2 / (Gamma((n - J - 1)/2) Gamma((n - J + 1)/2)), which matches the function to machine precision. The bias prose also described E[r] - rho while the returned bias column is rho - E[r]; the sign convention now matches the column, and the quoted magnitudes are the true +0.00624 (rho = 0.4, n = 30, J = 2) and +0.00888 (J = 10). - expected_r() quoted bias magnitudes with the wrong sign and size (-0.024 and -0.006); the true values are +0.021 (rho = 0.5, n = 10) and +0.0065 (n = 30), as the page's own example already reported. - icc_lmer() printed the variance of the Bonett (2002) L-transform as 1 / (2 (n - 2)), omitting the k / (k - 1) factor the code applies; the page now prints k / (2 (k - 1) (n - 2)). A reader hand-building the interval from the old page at k = 2 would have an SE too small by a factor of sqrt(2) and roughly .84 coverage instead of .95. - anova_within_two_way() printed the lower-bound epsilon as 1 / (df - 1); the code computes 1 / df, the attainable infimum, with df the effect's numerator degrees of freedom. - loa() printed a symmetric central t interval for the CIs on the limits of agreement; the code computes the Carkeet (2015) exact noncentral t interval, which is asymmetric about the sample LoA. The page now shows the noncentral form: quantiles of the noncentral t with noncentrality parameter k sqrt(n) for the upper LoA and its negative for the lower. - variance_components_mls() printed a symmetric interval with unsquared constants and a -MS_b MS_w / n cross term that appears nowhere in the method; the code computes the genuine Burdick-Graybill (1992, equations 2.4.1--2.4.5) form, and the page now prints V_L and V_U with the squared constants and the G_12 / H_12 cross terms. - ss_aipe_mixed_effects() printed Var(beta-hat) with a trailing design-effect factor the code does not apply; for the cluster-mean-centered level-1 slope the variance is sigma2_y (1 - rho_I) / (N sigma2_x), and the page now explains why the design effect does not enter. - ci_smd() pointed paired designs to ci_smd_c(), which is the interval for Glass's estimator (two independent groups, control group SD) and takes no correlation between paired measurements, so following the pointer reproduced essentially the independent groups interval. The page now states plainly that a paired-design SMD interval is not currently provided. - power_fisher_exact() attributed the alternative distribution to Wallenius; the code computes Fisher's noncentral hypergeometric, the conditional distribution of one binomial count given the total of two independent binomials, which is what conditioning on the margins of the 2 x 2 table produces. The prose and references now cite Fisher (1935) and Fog's (2008) sampling-methods paper. - ci_scheffe() said the default returns a - 1 pairwise contrasts; it returns all a (a - 1) / 2 of them, as the sibling pages already stated. A Second Documentation Pass: Quoted Values Now Match What Runs A continuation of the audit above, covering another two dozen help pages. As before, the computations were correct and the pages were not; no returned value changes, and where a corrected number is load-bearing a test now recomputes it independently. - Quoted numbers now match what the examples print. ci_rmsea()'s 90 percent example described its upper limit as landing below 0.05; the limit is 0.052, just above the Browne and Cudeck close fit threshold, and the page now draws the conclusion that follows (close fit is not established, even though the point estimate sits below the threshold). obrien_test()'s Hunter example quoted p = .2595, which matches neither the quoted F = 1.29 nor the exact statistic; the page now quotes p = .260, as computed. combine_p()'s Edgington sum for the Raudenbush example prints 7, not "near 6.9". ci_c()'s hypertension example described 24 subjects across group sizes of 4, 6, 5, and 5; it says 20. - mediation_mbco() separates the published memory-example likelihood ratios from what its example computes. Run from the rounded Table 1 summary statistics, the two null branches give LRT = 71.31 (the best-fitting branch, the statistic reported) and 179.02; the 72.54 and 175.77 the page previously quoted are the full-precision-moments values, and 175.77 is now attributed to Tofighi and Kelley (2020) as the published value, from the worse-fitting branch on which their optimizer stopped. The page notes that the difference comes from running from the published (rounded) summary statistics. - ss_power_indirect_effect()'s example no longer equates the approximation with the simulation benchmark. The joint significance approximation returns necessary_N = 65 for a = b = .39 at power .80; raw-data simulation puts the power at 65 nearer .77 and reaches .80 near N = 70, in line with the somewhat larger requirement in Fritz and MacKinnon's (2007) simulation-based table, and the example comment now says exactly that. The raw-data validation test's relative tolerance is widened from 0.03 to 0.06 with the reason recorded in place: the approximation sits about 3 percent above the simulation at those settings on any seed, so the old tolerance failed on some seeds for the approximation gap alone. - prime_time_achievement's corporation summaries are recomputed from the derived corp_id key. The bare corp column merges the two corporations that share code 2400, so the page overstated the largest corporation: corporations have 15 to 756 students (median 117), not 15 to 808 (median 124), and the three-level null model decomposition is 16.29 / 22.72 / 240.43 with a corporation ICC of 0.058 (previously 16.50 / 22.70 / 240.43 and 0.059). The data set's tests now anchor the corrected values. - bessel_errors' expected counts imply a normal sigma near 0.22, not 0.2. A least squares fit of the half-normal bin probabilities to Bessel's expected frequencies gives 0.216; at 0.2 the first bin alone is off by about eight observations. - The which_width contract of ss_aipe_omega_squared(), ss_aipe_icc(), and ss_aipe_partial_r() now says what the code does. The pages described "Lower" / "Upper" as a one-sided half-width; both settings interpret width as half the full width and return the same sample size. The pages now say so, note that an asymmetric interval's realized half-widths differ from each other and from half the full width, and state that a genuinely one-sided width target is not currently offered. - ci_mahalanobis() documents the tail arguments its backend accepts. The page promised that supplying alpha_lower and alpha_upper recomputes conf_level; that call errors, because the tails pass straight through to ci_nc_F(), which refuses a non-NULL conf_level beside them. The page now directs users to set conf_level = NULL and supply both alphas, and a test pins the contract. - ci_nc_F() and ci_nc_chisq() state the monotonicity each search actually exploits. The pages claimed each tail probability is strictly decreasing in the noncentrality parameter; the lower-limit condition works on the upper tail, which is strictly increasing. Each page now gives the direction per tail and notes that both roots are located on the decreasing lower-tail scale. - Smaller contract corrections. ss_aipe_equivalence_smd() described an expected half-width target of omega where the code targets omega / 2 (full width omega), and a 1-row return where the table has 5 rows; both now match, and the return's stale term names are corrected. The stale sample_size return term on the ss_aipe_c(), ss_aipe_c_ancova(), and ss_aipe_sm() pages now reads necessary_n_per_group, necessary_n_per_group, and necessary_N. ci_eta_squared()'s N is documented as the total number of observations (for aovlist fits, one more than the sum of all effect and residual degrees of freedom), matching its Details. mlmr()'s adj_R2 is documented as using the complete cases (N_complete), which the code deliberately uses, rather than the lavaan reported N. ci_c_ancova_bp()'s contrast_type entry dropped inline width expressions that omitted the 1/sqrt(2) and sqrt(1/n) factors and now points to the correct display in Details. ci_sc()'s note no longer contains a sentence directing users to pass the error variance where the argument (and the rest of the page) wants the error standard deviation. The multiplicative diff_size illustration on the ss_aipe_crd_* pages was a verbatim copy of the additive one; it now works the multiplicative form's arithmetic (cluster size 25 with diff_size = c(0.8, 1, 1.2) gives sizes 20, 25, 30, recycled across clusters). Equivalence and noninferiority for linear contrasts - equivalence_c() performs the two one-sided tests procedure and the companion noninferiority test for a linear contrast of group means against bounds stated in raw units of the response, with one pooled error term, a summary-statistic and a direct (estimate, SE, df) interface, a benchmark argument for comparisons against a known constant, and a five-way verdict (equivalent, superior, inferior, non-inferior only, inconclusive). Reproduces emmeans::test(..., side = "equivalence" | "noninferiority") to machine precision. - power_equivalence_c() computes the exact TOST power for a contrast by integration over the chi distribution of the estimated error standard deviation, generalizing power_equivalence_md() to arbitrary weights and unequal group sizes, and the noninferiority power in closed noncentral t form. - ss_power_equivalence_c() finds the smallest per-group sample size whose exact TOST (or noninferiority) power reaches a target, the declaration-probability counterpart of the width-targeting ss_aipe_c(). - ss_seq_c() and ss_seq_c_sensitivity() implement the purely sequential fixed-width confidence interval procedure for a contrast of Chattopadhyay, Bandyopadhyay, Kelley, and Padalunkal (2025), with cost-optimal allocation across groups; the sensitivity sibling verifies first-order efficiency and near-nominal coverage by Monte Carlo. - plot_equivalence() draws contrast estimates and their intervals against the equivalence region, colored by the equivalence_c() verdict. Mixed-effects R-squared - R2_mixed_effects() reports the Nakagawa and Schielzeth (2013) marginal and conditional R-squared for a fitted lme4 or nlme mixed model. It agrees to machine precision with r2mlm and with the direct Johnson quadratic form across the model classes the tests pin: random-intercept, correlated random-slope, split (||) random-slope, multi-slope, and nested two-level models. On split random-slope models performance/insight omits the random-slope variance from its marginal and conditional R-squared, so DMAR matches r2mlm and the Johnson form there and, by design, not performance::r2_nakagawa; the two agree on random-intercept and correlated-slope models. - R2_mixed_effects_decomposition() implements the Rights and Sterba (2019) integrative framework of mixed-effects model R-squared measures: the full family of total, within-cluster, and between-cluster measures from a complete five-source decomposition of the outcome variance, matching the authors' r2mlm reference implementation to machine precision across the same tested model classes. Output, tidiers, and contrasts - Publication-ready output helpers: knit_print.dmar_tbl() renders DMAR results as formatted tables in knitted documents, as_kable() produces a knitr::kable view, and results_sentence() writes an APA-style "estimate, CI" sentence from any interval-carrying result. - broom support (tidy() / glance()) added for the elementary tests (welch_t(), summary_t_test(), contrast_test()) and the simultaneous-comparison intervals (ci_dunnett(), ci_tukey_kramer(), ci_scheffe()). - The broom summary now spans the power-based sample size planners. tidy() and glance() summarize every closed-form ss_power_* planner that reports one size and one power, from the effect size planners to the ANOVA, ANCOVA, contrast, cluster, and mediation designs, reporting the design's planning unit (per group, per cell, per subject, or per cluster, or the total for the one-way ANOVA) beside its power. The lookup that resolves the size row learned the design-specific names (n_per_cell, n_subjects, J_per_arm, ss_per_group), so the meaningful names are kept rather than homogenized. The Monte Carlo sensitivity siblings ss_power_R2_sensitivity() and ss_power_reg_coef_sensitivity() carry a dmar_ss_power_sensitivity class whose tidy() places the empirical and analytic power side by side. - ss_power_composite_ancova_2group() plans the per-group sample size for composite power in a two-group ANCOVA: the probability that the group effect, the covariate effect, and the group by covariate interaction are all significant in the same study, the quantity a design must be planned against when its conclusion needs more than one result to hold at once. Composite power is not the product of the marginal powers, because every test divides by the same error estimate and the tests are positively dependent even when the effects are orthogonal. A one dimensional integral over the chi square distribution of that estimate evaluates the composite deterministically, with no simulation, and the plot() method draws the population effects the plan rests on. This opens the new composite power family. - ss_power_composite_factorial_ancova() and ss_power_composite_factorial_anova() carry composite power to any balanced factorial design: name any set of main effects and interactions in effects, each with its Cohen's f or partial eta squared, and the planner returns the per-cell sample size at which all of them are jointly significant. The effects are noncentral F tests sharing one error estimate, so the same shared-error integral applies; a single effect reproduces ss_power_factorial_anova() (or ss_power_factorial_ancova() with a covariate) exactly, and the two-effect composite matches a direct simulation. The ANOVA function is the no-covariate case named directly and admits no covariate. With no covariate the composite is exact to quadrature precision. The effects can be stated as sizes (Cohen's f or partial eta squared) or as a full array of population cell means with a common within-cell standard deviation, from which each effect's f is read off the analysis of variance decomposition of the means. The plot() method draws the purported population values: the cell-mean pattern (with error bars of one within-cell SD) when means were given, or the effect sizes annotated with their marginal power otherwise, with the composite power in the subtitle either way. - ss_power_composite_factorial_ancova_het() carries composite power to a factorial ANCOVA whose covariate slope differs across the cells. The average slope (the covariate main effect) and the factor by covariate slope heterogeneity are then testable effects that can join the composite alongside the factorial mean effects. The full model fits the means, the covariate, and every factor by covariate slope, so the residual has N minus twice the cells degrees of freedom; a "mean", "covariate", or "slope" effect is named in effects and sized by a Cohen's f or read from population values (cell means and a covariate outcome correlation per cell, with a common within-cell SD). The one-factor two-level case reproduces ss_power_composite_ancova_2group() to machine precision, and a three-effect composite matches a direct simulation of the heterogeneous-slope model. Kept separate from the common-slope ss_power_composite_factorial_ancova() for ease of use. The plot() method draws the population regression line in each cell, so heterogeneous slopes read as lines of different angle. - ss_power_composite_ancova() and ss_power_composite_anova() are the general entry points to the composite power family, covering a one-way design with any number of groups as well as any factorial arrangement. The ANCOVA planner takes a slopes argument, "homogeneous" for one common covariate slope or "heterogeneous" to let the slope differ across cells and make the covariate and slope-heterogeneity effects testable; its heterogeneous one-way case is the a-group generalization of the two-group ss_power_composite_ancova_2group(), and its two-level case reproduces it exactly. The ANOVA planner is the no-covariate design named directly, with a covariate-free interface that points to the ANCOVA version when a covariate is present. Both accept effect sizes or population values (cell means with a common within-cell SD) and forward to the factorial planners, so the same broom tidy()/glance() summaries and plot() figures apply. - ss_power_composite_sem() and ss_aipe_composite_sem() carry composite sample size planning to structural equation models, for both design goals. The researcher states the population as a fully fixed lavaan model (or its cov_sem() covariance matrix), labels the parameters of interest in the free analysis model (structural paths, loadings, covariances, or :=-defined quantities such as an indirect effect), and the planner finds the smallest N at which every labeled parameter is statistically significant in the same study with the desired probability (ss_power_composite_sem()), or at which every confidence interval is sufficiently narrow, in expectation or with a stated assurance for the joint event (ss_aipe_composite_sem()). No closed form covers a set of dependent SEM estimates, so both planners run an a priori Monte Carlo simulation (Muthén & Muthén, 2002; Maxwell, Kelley, & Rausch, 2008): data are drawn from the population covariance matrix, the analysis model is fit G times per candidate N, and a search seeded by the analytic Wald approximation brackets and bisects to the smallest integer meeting the goals; each reported power or proportion travels with its simulation standard error, and a seed argument makes a plan reproducible. The power planner joins the dmar_ss_power broom family; marginal power_