NEWS


dmsa 1.20.1

Test-suite fixes only. No change to any result.

dmsa 1.20.0

Three review items, all verified on real data.

dmsa 1.19.0

Five review comments from the Set 1 rev-3 output, all implemented.

dmsa 1.18.0

Chip now enters as a random intercept, as the Project Alpha covariate contract specifies.

tutor/covariate_sets.csv states 1 parent T1, chip_T1, random, (1 | chip_T1). Through 1.17.0 dmsa entered chip as a FIXED factor - 61 levels, 60 df on the parent build, with 7 singleton chips fitted perfectly. That was an undocumented deviation from the pre-specified contract.

Why chip is needed at all (parent build, n = 396):

Implementation: for a one-way random intercept the GLS solution is exactly OLS on quasi-demeaned data (Balestra-Nerlove), with the variance ratio estimated by REML. No mixed-model package is required - the REML step is a 1-D optimisation in R/ranef.R. Validated against lme4::lmer(REML = TRUE) on the Alpha parent build: coefficients and t-statistics agree to 5e-13, variance components to 4e-06, including the sigma^2_u = 0 boundary.

Because the transform is a linear map applied once, before any permutation, Freedman-Lane block permutation is unaffected. Validity does not depend on the variance ratio being exactly right: the null is generated under the same transform, so the variance ratio affects power, not type-I error.

What it costs and what it buys: the random intercept spends a median of ~16 effective df instead of 60, and 0 on the ~20% of probes where the chip variance is estimated as nil. On the two deposit genes it is appropriately more conservative than the fixed factor, and both still survive:

| gene | random (contract) | fixed (1.17.0) | chip omitted | |---|---|---|---| | PLAGL1 | adj .0260 survives | adj .0100 survives | adj .1360 | | AVP | adj .0140 survives | adj .0080 survives | adj .0140 survives |

Omitting chip loses PLAGL1 altogether.

dmsa 1.17.0

Five defects found by auditing a 29-model battery run on all four Project Alpha builds. All five were silent: every one produced a report that compiled cleanly and said something false or incomplete.

dmsa 1.16.0 (2026-08-19)

Everything in this release came out of running the 25-model Set 1 battery on all four Project Alpha 2026d builds. Five of the twenty-five models failed and two more passed while testing something other than what they claimed to.

Three of the four builds could not be analysed at all (critical)

Typing the contract out by hand gave a different model (serious)

Moderated curvature was reported in prose and never drawn

chip is an argument

Shared probes: audited, and the hazard is structurally absent

Two failures that gave uninformative errors

Smaller

dmsa 1.15.0 (2026-08-18)

covariates = "contract" is build-aware (important)

Overview figure fixes

dmsa 1.14.0 (2026-08-18)

The summary is what people will read, so it now says what it means

dmsa 1.13.0 (2026-08-18)

Outcome types, labels, and the non-linear moderation figure

dmsa 1.12.0 (2026-08-18)

Moderated non-linear is now a real test, and the shape prose reaches the report

dmsa 1.11.0 (2026-08-18)

The scan now covers the whole declared hierarchy, and the exponential arm is real

dmsa 1.10.0 (2026-08-18)

The shape scan runs at every level, and is corrected like everything else

dmsa 1.9.0 (2026-08-18)

The shape scan now respects marginality, and will not call a curve a U

Reported shape numbers change in this release. Anything taken from a 1.8.9 shape table came from the wrong specification and should be re-run.

dmsa 1.8.9 (2026-08-18)

Bug fix: type = "non-linear" computed a result and threw it away

dmsa 1.8.8 (2026-08-18)

A surviving moderation now gets a figure, and the model gets stated

dmsa 1.8.7 (2026-08-18)

Moderation runs get the same reporting support as main-effect runs

dmsa 1.8.6 (2026-08-18)

Reporting the result, not just computing it

Fixes

dmsa 1.8.5 (2026-08-18)

dmsa 1.8.4 (2026-08-18)

dmsa 1.8.3 (2026-08-18)

Two conveniences for long runs

A report is minutes of permutation with nothing on screen - the parent cohort at B = 1999 across 19 systems takes 35 minutes - which leaves no way to tell "working" from "hung".

Both default to interactive(). A progress bar writes carriage returns, which turn a piped log into soup, and a package that makes noise during R CMD check or a testthat run is one people learn to mute - so both are live at the console and off under Rscript, check and tests. beepr is a Suggests: without it the sound is silently a no-op, never load-bearing.

dmsa 1.8.2 (2026-08-18)

Regression fix: maxT had lost its information advantage under a single engine

Caught by running the shipped package against the pre-registered proof of concept and comparing every number to the deposited results.

A change on 15 August 2026 standardised each lens statistic by its own permutation null before the family-wise step. That was introduced to fix a real problem in the combined engine - a rank-p fusion floors the family-wise p near (family size)/(B+1), which silently zeroes power for large families at modest B - but it was applied to the single-engine path too, where it does not belong.

Standardising divides out exactly what maxT's advantage is made of. A unit whose probes all point the same way generates the widest permutation null in its family and is therefore charged the least; rescale every unit to unit spread and that width buys nothing, leaving minP-like behaviour under a maxT label.

The cost was the pre-registered anchor. AVP's family-adjusted coherence moved from .0120 - the reported value, and the one the p-dancing figures quote at every perturbation - to .1135, which is the documented combined-engine value of .125. PLAGL1, CAT and the exploratory sweep all shifted with it, in both directions, and a gene that is not a finding (ADCY6) appeared to clear .05.

Standardisation now happens only where two engines are actually fused. With one engine, maxT sees the raw statistic again.

Every number in the pre-registered proof of concept now reproduces exactly from the shipped package at weighting = "flat", cpg_map = "full", B = 1999: AVP coherence .0120/.0120, composite .0070/.1285, diffuse .0080/.0505; PLAGL1 coherence .0055/.0425, composite .0025/.0080, diffuse .0025/.1720. All twelve raw and adjusted values match the deposit.

Three tests now pin the property: the concordant unit's toll stays small under one engine, maxT stays strictly kinder than minP to it, and the two-engine fusion keeps its standardisation.

dmsa 1.8.1 (2026-08-18)

The locus panel was mixing genome builds, silently

Found by running the whole pipeline on the real parent cohort rather than on test fixtures - which is the only way this class of defect surfaces, because neither layer is wrong on its own.

554 unit tests.

dmsa 1.8.0 (2026-08-18)

The locus panel draws the gene, not a bar shaped like one

Strip B used to draw a gene as a featureless grey rectangle, and - when a probe carried no coordinate - to space probes evenly along it. Both told the reader nothing while looking like they told them something. A CpG in the first exon and a CpG 40 kb into an intron are different claims about regulation, and which one it is decides the probe's direction call. The panel now shows it.

Gviz, GenomicRanges, IRanges, GenomicFeatures, ensembldb, AnnotationDbi and AnnotationFilter are Suggests. The Ensembl and GFF sources need none of them - nothing beyond base R - so the figure is not reachable only by users who can install a gigabyte of annotation.

The evenly-spaced fallback is no longer a silent default

It looks like a map and is not one: two probes drawn adjacent may be 40 kb apart. When the panel has no choice it now prints NOT TO SCALE in bold under the axis, where the caveat survives being cropped into a slide, and messages once on the console naming how to fix it. The bundled Alpha cascade carries an hg38 position for every probe, and dmsa_report() now reads coordinates straight from it, so the default path is always to scale.

Fix

dmsa 1.7.2 (2026-08-17)

dmsa_sets_check("alpha") failed the package's own data

The data sanity gate reported the bundled cascade as not usable on two counts, and both were defects in the check rather than in the data. A validator that cries wolf on the shipped set teaches users to ignore it, so:

Fixes found by R CMD check --run-donttest

494 unit tests.

dmsa 1.7.1 (2026-08-17)

dmsa 1.7.0 (2026-08-17)

Gene-to-system polarity becomes auditable data

w_g is the multiplier that decides which way a system score points, so a single wrong sign does not degrade a result - it inverts it. Until now those signs lived inside a curated CSV with no provenance. They are now a first-class table in which every row states where its sign came from and what would change it.

The rule the audit turned on

A gene is signed against the system's declared tone, not against its immediate molecular partner. FKBP5 restrains GR and GR mediates HPA negative feedback, so FKBP5 is +1 to the HPA system - a brake on a brake. The role vocabulary therefore carries brake-of-brake and feedback-enabler as first-class labels, and separates roles that commit to a direction (driver, brake, ...) from roles whose sign is inherited from what they serve (accessory, transducer, capacity, readout).

A database may raise the evidence grade of a sign it agrees with. It may never flip a sign on its own. All 38 database contradictions were adjudicated one at a time against the literature; four proved to be defects at source. w_g for the Project Alpha panel is unchanged from the curated values in every one of the 112 rows the PI set by hand. POLARITY_AUDIT.md records the method, the rejected resources and the escalations.

dmsa 1.6.0

The selection cascade becomes a first-class object

system > module > gene > probe now ships with the package as a curated selection set, and it is the object dmsa_frame() resolves systems = against. The point is not convenience: because families are declared in this file and never harvested from whatever the analyst happened to load, the family a unit is corrected within is a property of the map rather than of the session. That is the mechanism behind DMSA's invariance to set selection, and it is now visible.

Module evidence travels with the result

Every module label in the bundled set was checked against the literature. That check is now part of the output, on the principle that a module-level finding is only as good as the module's definition.

Bringing your own panel

Fixes

dmsa 1.5.0 (2026-08-15)

dmsa 1.4.0 (2026-08-15)

dmsa 1.3.0 (2026-08-15)

dmsa 1.2.0 (2026-08-14)

dmsa 1.1.2 (2026-08-14)

dmsa 1.1.1 (2026-08-14)

dmsa 1.1.0 (2026-08-14)

The two-call user interface.

Anchor (real Alpha data, systems 1 + 21, B = 1999, seed 1, cpg_map = "full"): AVP coherence adj .0120, PLAGL1 composite adj .0080 - identical to the locked triangulation run. New from the always-on bridge: two PLAGL1 probes carry a formal brain bridge (cg08263357, ensemble percentile 94; cg11532302).

dmsa 0.99.10

blocks = replaces random_effects =, and there is no default (spec 42)

Unresolved polarity is counted and said; user polarity merges (spec 40, E13)

The statistic columns, labelled (spec 26/28)

Report failures are recorded, never swallowed (spec 53)

The locus panel draws the tested estimator (spec 52)

Regression tests for the lenses, custom polarity and the display rules (spec 62/63/67)

dmsa 0.99.9

The all-one-direction note tells the user where to check

Binary moderator: one panel; leaner overview; stale frames

Moderation joins the report; Ensembl fetch repaired

Covariate/moderator overlap said out loud

Labels that cannot lie, levels that cannot flip

Predictor_levels

The family-corrected omnibus and its badge

Labels, precise omnibus wording, exons back by default

Exact second-level calibration, measured error, the badge

The rule carried through every output

The naming rule, re-ruled

Report figures and the gene table

Orientation spellings

Group selection

Engine review pass — PI-ruled fixes E1-E10

Ten findings from the whole-package adversarial review were ruled on individually by the PI and fixed. These are the first changes to engine files in this release cycle; each was approved explicitly.

Second pass, same day

The pair path is live (spec 1/3): direction_source

Coverage is itemised (spec 15/16/17)

The 0.99.9 foundation

The biological reference and CpG mapping (the 2026c re-architecture)

Adjusted p-values are NOT comparable to earlier versions

Safety (hard errors where silence used to be)

Report

dmsa 0.99.8

dmsa 0.99.7

dmsa 0.99.6

dmsa 0.99.5

dmsa 0.99.4

dmsa 0.99.3

dmsa 0.99.2

dmsa 0.99.1

dmsa 0.99.0

Bioconductor submission version. No change to any estimate, permutation, or correction; every number in the manuscript reproduces from v1.20.2, archived at 10.5281/zenodo.22042907.

Bioconductor requires new packages to enter review at 0.99.z and to release at 1.0.0, so the version number resets here. The GitHub and Zenodo lineage continues at 1.20.x; the concept DOI 10.5281/zenodo.22023957 resolves to whichever is current.