If you are an ecology or evolution graduate student deciding whether
drmTMB fits your problem, the first question is not “can I
fit this model?” It is “which numbers from the fitted model can I report
with a straight face?” A model can converge, print coefficients, and
still hand you a confidence/compatibility interval that does not cover
the truth at the rate it claims to. This page separates what
drmTMB fits from what drmTMB has checked, cell
by cell, so you know whether to trust a point estimate, an interval, or
neither before it goes in a manuscript.
Throughout, mu is the location term, sigma
is the scale term, family-specific parameters such as Student-t
nu are shape terms, and coscale means a
residual-correlation parameter such as bivariate rho12 –
the association left between two responses after their means and scales
are modelled. Those four words describe what a formula changes; they say
nothing about whether the resulting interval has been checked. That
check is what the rest of this page reports.
Four tiers, defined once
Every model/effect combination in drmTMB sits in one of
four tiers.
- Inference-ready. The confidence/compatibility interval has been coverage-checked by simulation and holds, at least at an honest small-sample floor (see the caveats below). You can report the point estimate and the interval.
- Recovery-only. The point estimate has been checked against a known simulated truth and recovers it. The interval has not been coverage-checked and should be treated as provisional: report the point estimate, and treat any interval on the same row as a plausible range rather than a calibrated one.
- Diagnostic-only. A deterministic or single-smoke fit verifies that the route is wired to the requested parameter and that its extractors work, but no retained-denominator seed ladder supports recovery. Treat the estimate as a debugging or feasibility result, not as a recovery-backed scientific estimate.
-
Not available / rejected by design.
drmTMBrefuses to fit the request outright. Some of these routes are planned for a later release; some are out of scope for the package’s current design. Either way, fitting it anyway is not an option – use the alternative named below each entry.
No cell in drmTMB is coverage-verified at the strictest
bar the project tracks internally as “supported” (nominal-exact coverage
with symmetric misses on both sides). The census does mark four cells
fit_status = supported – ordinary (unstructured) Gaussian
and bivariate-Gaussian random effects – but those are point-trustworthy
with interval coverage still planned, not coverage-verified. Read
“inference-ready” as an honest floor for a first fitted structured
route, not as parity with a long-mature fixed-effect interval in a
package such as glmmTMB or lme4.
At a glance
| Model / effect | Tier | What you can trust |
|---|---|---|
Census-supported ordinary Gaussian mu random effects
and matching bivariate-Gaussian mu1/mu2
intercepts |
Point-trustworthy (census “supported”, coverage planned) | Point estimate for the exact supported rows; their intervals are not yet coverage-verified |
Gaussian mu q1 intercept – phylo(),
spatial(), relmat()
|
Inference-ready | Point estimate and the default location-axis bias-corrected, small-sample-t Wald interval; coverage is mildly conservative in the tested campaigns |
Gaussian sigma q1 one-slope – phylo(),
animal(), relmat()
|
Inference-ready | Point estimate and raw uncorrected log-SD Wald-z interval; profile
is diagnostic-only at g = 8
|
Bivariate Gaussian slope-only mu1:x/mu2:x
q2 mean-mean – phylo(), relmat()
|
Inference-ready (default-corrected channel only) | Point estimate and interval from plain confint(fit);
intercept-only and explicitly uncorrected Wald intervals are not
promoted by this evidence |
binomial / Poisson / beta / nbinom2 unstructured
mu
|
Inference-ready | Point estimate and Wald interval in the tested designs
(n = 50, 150, or 500); this is
not a universal sample-size threshold |
nbinom2 unstructured location-scale (mu and
sigma ~ x) |
Inference-ready | Point estimate and Wald interval on both formulas |
| beta unstructured location-scale, interior proportions | Inference-ready | Point estimate and Wald interval; exact 0 or 1 needs
zero_one_beta() instead |
Ordinary independent mu random slope
(0 + x \| id) – binomial, cumulative-logit, skew-normal,
Tweedie, zero-one-beta |
Inference-ready with caveats | Profile interval for the natural-scale slope SD, ML only, not
supported, no Wald or point-bias claim. The tested floor
differs by family, so do not generalize one number: skew-normal /
Tweedie / zero-one-beta at M >= 16 (true SD 0.50,
ML-Laplace); binomial at M >= 32 (true SD 0.6,
ML-Laplace); cumulative-logit at M >= 80 (true SD 0.50,
adaptive Gauss-Hermite + Cox-Reid; its M = 40 rung is
exploratory, not the floor). Zero-one-beta is generator-qualified (see
the caveat below) |
Gamma sigma ordinary random intercept
(1 \| id)
|
Inference-ready with caveats | ML-Laplace profile interval only for the exact iid, uncentred
coverage fixture (true SD 0.40, 12 observations/group,
M = 32 or 64); M = 16 is
borderline and M = 8 is excluded |
Poisson / nbinom2 structured mu q1 –
phylo(), spatial(), animal(),
relmat()
|
Recovery-only | Point estimate only |
nbinom2 structured sigma – phylo(),
spatial(), animal(),
relmat()
|
Recovery-only | Point estimate only; scale-targeting bug fixed in 0.4.0 |
Row-specific recovery slices: beta animal() on
mu/sigma, Student-t
mu ~ spatial(1 + x | ...), and Gamma
mu ~ relmat()
|
Recovery-only | Point estimate only; no interval or coverage promotion |
Bivariate Gaussian spatial q2 location-intercept REML – matching
labelled spatial(1 | p | site, coords = coords) in
mu1 and mu2
|
Recovery-only | Point estimates for both structured SDs and their latent
correlation; requires intercept-only sigma1,
sigma2, and rho12, complete pairs, unit
weights, no known meta_V(), and no additional ordinary
random, direct-SD, or corpair() layer; no interval or
coverage promotion |
Bivariate Gaussian supplied-K relmat q2
location-intercept REML – matching labelled
relmat(1 | p | id, K = K) in mu1 and
mu2
|
Recovery-only (point_fit_recovery) |
Point estimates for both structured SDs and their latent relatedness
correlation; requires the same named K, group ordering, and
label in both formulas, intercept-only sigma1,
sigma2, and rho12, complete pairs, unit
weights, and no additional random-effect, scale-side,
meta_V(), direct-SD, or corpair() layer; no
interval or coverage promotion |
Row-specific single-smoke slices: ordinal mu ~ phylo(),
truncated-nbinom2 hu ~ relmat(), Student-t
nu ~ phylo(), Student-t intercept-only
mu ~ spatial(1 | ...), Poisson slope-only
mu ~ spatial(0 + x | ...), Poisson labelled-scalar
mu ~ spatial(), Poisson
mu ~ spatial(1 | ...) + (1 | id), Poisson
zi ~ spatial(), fixed-zi Poisson
mu ~ spatial(), and fixed-zi NB2
mu ~ spatial()
|
Diagnostic-only | Use only to confirm fit/extractor feasibility; no recovery, interval, or coverage claim |
| Structured effects for lognormal, skew-normal, Tweedie, zero-one-beta | Not available | Use a Gaussian or basic count/proportion structured route, or fixed effects |
Gaussian pure-mu univariate REML –
spatial(), animal(),
relmat()
|
Inference-ready with caveats | Unlabelled intercept or independent intercept plus one numeric
slope, with sigma ~ 1; report a direct structured-SD
profile interval only inside the tested discrete domains below |
REML for non-Gaussian families; non-phylogenetic mean-side REML
outside the pure-mu Arc 1a boundary and the exact bivariate
spatial and supplied-K relmat q2 intercepts above; all
other bivariate non-phylogenetic structured REML |
Not available (rejected by design) | Use REML = FALSE (maximum likelihood) |
q4/q6/q8/q12
covariance interval promotion; derived-correlation intervals |
Not available (planned) | Use the fitted point estimate; try profile_targets()
for a direct target |
The rest of this page expands each row with the caveat that changes how you should read it.
Tier 1: inference-ready
Gaussian structured random effects: eleven anchor cells
Eleven conceptual cells across drmTMB’s structured
Gaussian-family random-effect routes are inference-ready today. Eight
are the established ML model-surface anchors: six sit on a univariate
Gaussian mu or sigma formula, all at q1, and
two are bivariate-Gaussian slope-only
mu1:x/mu2:x q2 mean-mean blocks. The other
three are the Arc 1a REML estimator cells for pure-mu
univariate spatial(), animal(), and
relmat() routes:
- three q1 mean-intercept rows –
phylo(),spatial(),relmat()on univariate Gaussianmu; - three q1 sigma one-slope rows –
phylo(),animal(),relmat()on univariate Gaussiansigma; - two slope-only q2 mean-mean rows –
phylo(0 + x | ...)andrelmat(0 + x | ...)on bivariate Gaussianmu1/mu2, a joint cross-response covariance block. The intercept-only bivariate q2 rows are not inference-ready. The univariate Gaussian single-response q2 mean-slope route is recovery-only, not inference-ready; - three Arc 1a REML rows –
spatial(),animal(), andrelmat()on univariate Gaussianmu, restricted to an unlabelled intercept or an independent intercept plus one numeric slope withsigma ~ 1. Each provider is one ledger cell that covers both admitted shapes; the cell count is not a count of formula shapes.
The machine ledger contains thirteen rows for these eleven conceptual
cells because each of the two bivariate slope-only q2 provider blocks
has separate mu1 and mu2 endpoint rows. That
storage detail does not create four distinct scientific covariance
blocks.
None of these eleven is free of a caveat, and the caveat is different
for each group. The three q1 mu intercept rows are backed
by the default location-axis bias-corrected, small-sample-t Wald
channel, with coverage of 0.9705-0.9832 in the retained-denominator
campaigns. The three q1 sigma one-slope rows are backed by
raw, uncorrected log-SD Wald-z intervals: intercept-SD coverage is
0.9388-0.9633 and slope-SD coverage is 0.9895-0.9957 at
g = 8, with material miss asymmetry for some intercept
targets. Profile intervals for these q1 sigma rows are
diagnostic-only at g = 8 because their finite-interval
rates do not clear the promotion gate. These are the documented
small-sample limitations; do not replace either evidence channel with a
general profile recommendation.
The three Arc 1a REML cells are coverage-backed only over discrete
campaign domains. Here M is the number of structured levels
(sites, animals, or relatedness levels, and therefore the structured
matrix dimension), while n_each is the number of
observations per structured level. Spatial and relmat() use
n_each = 20 and exactly M = {8, 16, 32}, while
the animal(A = A) campaign uses n_each = 20
and one fixed M = 8 matrix. Coverage clears the
pre-specified small-sample floors but is not nominal-exact; upper-tail
miss asymmetry and zero-lower-bound slope profiles remain material. Do
not rewrite these as continuous M >= ... claims or treat
other pedigrees, matrices, or sample sizes as coverage-checked.
These are copy-paste forms of the three admitted independent one-slope REML cells (replace the object names with objects from your analysis):
fit_spatial_reml <- drmTMB(
bf(y ~ x + spatial(1 + x | site, coords = coords), sigma ~ 1),
family = gaussian(), data = dat, REML = TRUE
)
fit_animal_reml <- drmTMB(
bf(y ~ x + animal(1 + x | id, A = A), sigma ~ 1),
family = gaussian(), data = dat, REML = TRUE
)
fit_relmat_reml <- drmTMB(
bf(y ~ x + relmat(1 + x | id, K = K), sigma ~ 1),
family = gaussian(), data = dat, REML = TRUE
)The multi-seed campaigns used exactly the coordinate, A,
and K representations shown above. Pedigree and
Ainv animal inputs and relmat Q have
deterministic representation-parity evidence only; they do not inherit
the multi-seed campaign claim. Intercept-only versions replace
1 + x with 1; slope-only, labelled, and
multiple-slope shapes remain rejected.
For every admitted Arc 1a term, the fitted structured SD scale
s_j is the latent-field scale: the covariance is
s_j^2 K_h, and node i has marginal SD
s_j sqrt(K_h[ii]). The fitted s_j is therefore
equal to a node marginal SD only when the corresponding diagonal entry
of K_h is one.
The two bivariate-Gaussian slope-only q2 mean-mean rows are
inference-ready only because confint()’s defaults already
correct for known small-sample bias on location-axis structured-SD
targets: bias_correct = "location" shifts the log-scale
point estimate to counter ML shrinkage, and
small_sample_df = "location" widens the interval with a
t(df = g - 1) reference instead of a normal quantile.
Calling plain confint(fit) gives you this corrected
interval automatically. If you explicitly turn the correction off
(bias_correct = "none",
small_sample_df = "none"), the resulting raw Wald interval
under-covers on these two rows – do not do that for a bivariate
phylo()/relmat() q2 mean-mean report.
None of these eleven structured cells carries the “supported”
fit_status the census reserves for the package’s ordinary
(unstructured) Gaussian and bivariate-Gaussian random effects – and even
those supported cells are point-trustworthy with interval coverage still
planned, not coverage-verified. Report these structured intervals as
inference-ready, not as a fully mature fixed-effect-grade interval.
Ordinary (unstructured) random effects: point-trustworthy, coverage pending
One group of cells deserves explicit mention even though its interval
does not yet meet the coverage bar for this tier. The census-supported
rows are the Gaussian mu random intercept, its independent
(0 + x | id) slope, and the matching bivariate-Gaussian
mu1/mu2 intercept block. They are the
package’s highest fit-maturity random-effect rows, so their point
estimates are the most trustworthy ordinary random-effect estimates
drmTMB produces. This does not extend to other bivariate
blocks or to an arbitrary intercept-plus-slope formula. Their interval
coverage is still planned rather than simulation-verified: until that
campaign lands, read any interval on these rows the way you would a
recovery-only row below, and report the point estimate with
confidence.
Unstructured non-Gaussian fixed effects
A 2026-07-09 coverage campaign
(docs/dev-log/simulation-artifacts/2026-07-09-nongaussian-unstructured-coverage-pilot/)
checked the fixed-effect mean coefficients of binomial(),
poisson(), beta(), and nbinom2()
across n in {50, 150, 500}, 400 seeds per
cell. Every cell cleared the bar: finite rate at 1.00 and Wald coverage
between 0.922 and 0.973, with no worsening at the smallest sample size
and no systematic under-coverage. That holds even under stress – a
rare-event binomial design with an approximately 8% base rate, and a
low-count Poisson design with a mean near 1 – so a scarce or noisy field
dataset is not, by itself, a reason to distrust these intervals.
The same campaign extended to nbinom2() location-scale
models, where both the mean coefficients and the sigma ~ x
dispersion coefficients are calibrated (coverage 0.93-0.97 across
n), and to beta() location-scale models on
interior proportions, where mean and sigma ~ x coefficients
are also calibrated (coverage 0.93-0.95). The beta() result
carries one hard requirement: the family strictly needs responses in the
open interval (0, 1). An observation with an exact 0 or
exact 1 – a boundary proportion that arises naturally from rounding at
extreme covariate values – produces a non-finite result by design, not a
bug to route around. If your proportions can legitimately sit at the
boundary, fit zero_one_beta() instead of
beta().
Ordinary non-Gaussian random slopes: profile intervals with caveats
Five non-Gaussian families now carry an inference-ready-with-caveats
interval for the standard deviation of a single ordinary independent
mu random slope, (0 + x | id): binomial,
cumulative-logit, skew-normal, Tweedie, and zero-one-beta. The claim is
narrow and the same in shape across them – a profile interval for the
natural-scale slope SD, ML only, no Wald-interval or point-bias
claim – but the tested floor and design differ by family and should not
be generalized to a single number. Skew-normal, Tweedie, and
zero-one-beta are certified at M >= 16 groups (true
slope SD 0.50) with the standard ML-Laplace profile. Binomial is
certified at M >= 32 (true SD 0.6). Cumulative-logit is
certified at M >= 80 (true SD 0.50) and reaches this
tier through adaptive Gauss-Hermite quadrature with a Cox-Reid
restricted likelihood rather than the Laplace approximation; its
M = 40 grid rung clears mechanically but is boundary-heavy
and exploratory, so it is not the reporting floor.
Zero-one-beta carries an extra caveat and is
generator-qualified. Its coverage campaign was designed
with a fixed 15% structural boundary mass and interior draws from a beta
density, but the interior draws leaked rare machine-exact ones – 50, 87,
and 193 of them across the M = 16, 32, and
64 replicate banks – because the sampler’s precision
parameter pushes the beta shape toward a boundary in the upper tail. The
reported coverage (0.929, 0.940, 0.952 at M = 16 / 32 / 64)
therefore describes the generator as executed, not an
exactly-15%-boundary design. The leak is not independent of the
estimand: affected replicates carry systematically larger slope-SD
estimates, so the effect of the defect under the intended generator is
unquantified and cannot be recovered from the retained campaign. One of
the three independent promotion reviewers withheld this cell on exactly
that ground; it promotes under the frozen two-withhold rule, and the
caveat travels with it. This is a principled boundary, not a temporary
one. At the beta shapes where the leak occurs, the intended distribution
genuinely places a large share of its mass within one machine-precision
step of the boundary, so no strictly-interior sampler can faithfully
reproduce the intended design; a rerun would answer a different,
convention-dependent question rather than certify the intended one. The
generator-qualified reading is therefore the correct terminal statement
for this cell.
Gamma sigma random intercept: narrow coverage-backed
interval
The Gamma sigma ~ (1 | id) random-intercept standard
deviation has a separate, narrower result. Its ML-Laplace profile
interval was assessed only in an iid, uncentred fixture with true SD
0.40 and 12 observations per group. M = 32 and
64 groups met the retained coverage rule;
M = 16 is borderline and M = 8 is excluded
because boundary behaviour made that arm unsuitable for reporting. This
is not evidence for Gamma sigma slopes, labelled blocks,
joint mu and sigma random effects, REML, or
other sampling designs.
Tier 2: recovery-only
A larger set of non-Gaussian structured random-effect routes has verified point-estimate recovery but no coverage evidence at all. Trust the coefficient; do not report the interval as calibrated.
This covers Poisson and nbinom2 q1 structured mu
intercepts and one-slopes for phylo(),
spatial(), animal(), and
relmat(), and nbinom2 structured sigma for the
same four providers. The nbinom2 structured-sigma route
deserves a specific caution: through 0.3.x, a
sigma ~ phylo()/spatial()/animal()/relmat()
formula silently modified the mean predictor instead of the
scale predictor, so a fitted model reported a
sigma-labelled standard deviation that was actually
changing mu. That mis-targeting is fixed in 0.4.0, and the
route now correctly modifies scale with verified point-fit recovery –
but intervals and coverage remain out of scope, so this row stays
recovery-only even after the fix.
A further handful of row-specific slices sit at the same tier: beta
animal() structured effects on mu and on
sigma, Student-t mu ~ spatial(1 + x | ...),
and Gamma mu ~ relmat() (unlabelled intercept and
one-slope). Each of these fits and has point-recovery evidence; none has
a coverage study behind its interval. If your scientific question turns
on the width of a confidence/compatibility interval rather than the sign
and rough size of an effect, do not build the argument on one of these
rows yet.
Tier 3: diagnostic-only
Ten exact structured routes currently have deterministic or
single-smoke fit/extractor evidence without a retained-denominator
recovery ladder: ordinal mu ~ phylo(), truncated-nbinom2
hu ~ relmat(), Poisson zi ~ spatial(),
fixed-zi Poisson mu ~ spatial(), Student-t
nu ~ phylo(1 | ...), Student-t intercept-only
mu ~ spatial(1 | ...), Poisson slope-only
mu ~ spatial(0 + x | ...), Poisson labelled-scalar
mu ~ spatial(), Poisson
mu ~ spatial(1 | ...) + (1 | id), and fixed-zi
NB2 mu ~ spatial(1 | ...). These routes establish that the
parser, likelihood target, and extractors connect. They do
not establish point-estimate recovery. Use them for
feasibility or debugging only, and do not report an interval or coverage
claim.
Tier 4: not available or rejected by design
Structured random effects outside the narrow gates
above. drmTMB does not currently accept structured
phylo(), spatial(), animal(), or
relmat() random effects for lognormal, skew-normal,
Tweedie, or zero-one-beta families. Gamma is the one partial exception:
it accepts relmat() on mu (recovery-only,
listed under Tier 2 above) but rejects phylo(),
spatial(), and animal(). Try instead: model
the same structural dependence through a Gaussian route (for example a
log- or logit-transformed response under gaussian()), fall
back to the ordinary Poisson/nbinom2 structured routes described above
for count data, or drop to fixed effects for the family you need while
structured support catches up.
REML outside its Gaussian scope. REML is implemented
for Gaussian models only, and even inside Gaussian models it accepts a
specific boundary rather than every structured shape. It accepts
univariate phylogenetic mean-side, scale-side, and matched q2
mean-and-scale blocks, plus univariate spatial, animal, and
relmat() structured effects on the scale side, bivariate
phylogenetic structured effects in every covariance layout, and
heteroscedastic sigma ~ x formulas together with ordinary
(non-phylogenetic) sigma random effects. Arc 1a
additionally accepts a pure-mu, univariate
spatial(), animal(), or relmat()
term as an unlabelled intercept or an independent intercept plus one
numeric slope, but only with constant sigma ~ 1 and no
sigma random effect. Arc 1b-S1 accepts matching labelled
fixed-covariance spatial(1 | p | site, coords = coords)
intercepts in bivariate mu1 and mu2, with
intercept-only sigma1, sigma2, and
rho12, complete response pairs, unit weights, no known
meta_V() covariance, and no additional ordinary random,
direct-SD, or corpair() layer, at recovery-only grade. Arc
1b-S2R admits the analogous location-only supplied-relatedness cell only
when both formulas contain the same labelled
relmat(1 | p | id, K = K) intercept and the named
K, group ordering, and label match exactly. This relmat
route has point_fit_recovery evidence: report its two
structured SDs and latent relatedness correlation as point estimates,
not calibrated intervals.
The relmat REML exception does not admit Q = Q, slopes,
q4 or larger blocks, scale-side terms, extra random effects, incomplete
response pairs, non-unit weights, nonconstant residual formulas,
direct-SD models, meta_V(), or corpair().
Animal-model bivariate REML and every non-Gaussian family also remain
rejected. Try instead: fit the same model with REML = FALSE
(maximum likelihood); ML is the route to use for any model REML
rejects.
Higher-order covariance promotion. q4,
q6, q8, and q12
covariance-interval promotion, plus derived-correlation intervals more
broadly for non-Gaussian structured covariance, remain planned rather
than implemented. Try instead: use the fitted point estimate for the
covariance or correlation summary you need, and check
profile_targets(fit) for any direct target that already has
an interval route before assuming none exists.
Known limitations for 0.6.0
If you are deciding whether a specific drmTMB output
belongs in a manuscript, read this section next. It names four gaps
between what an extractor currently returns and what the underlying fit
actually supports, and what to do about each one.
Regression-parameterised coscale intervals are computable,
but not coverage-certified. If your rho12 formula
depends on a covariate (rho12 ~ x),
corpairs(fit, conf.int = TRUE) reports
conf.status = "newdata_required" and no bounds until you
supply the covariate values. Use
confint(fit, parm = "rho12", newdata = grid, method = "profile")
for row-specific profile intervals, or
predict_parameters(fit, newdata = grid, dpar = "rho12", conf.int = TRUE)
for the corresponding Wald intervals. The same evidence boundary applies
to the constant rho12 ~ 1 profile interval: it is
available, but the current ledger records no committed bivariate
fixed-effect CI-coverage simulation. Treat either result as an
interval-feasibility output, not a calibrated reporting guarantee.
Tracked as issue #802.
The three certified Arc 4c mu-slope cells make
no point-bias or Wald claim. The skew-normal (mc-0464), Tweedie
(mc-0539), and zero-one-beta (mc-0575) cells described under “Ordinary
non-Gaussian random slopes” above come from a coverage campaign whose
reporting extractor had a disclosed defect: it recorded NA
for the point estimate (sd_hat) and every Wald column,
across the whole campaign. The defect is repaired going forward, but the
immutable campaign artifact was not backfilled, so these three cells
carry only the certified ML-Laplace profile interval described above –
not a point-bias number and not a Wald interval. What to try next: read
and report the profile interval for these three cells, and treat any
point-bias or Wald claim about them as unavailable, not merely
uncertain.
Profile-interval endpoints no longer depend on your
iter.max budget (issue #710.5). A previously
reported numerical-stability issue – a tight
iter.max/eval.max on the profile-endpoint
refit could bias a profile CI inward – is fixed: the endpoint refit now
floors its own inner-iteration budget regardless of what you pass in, so
tightening your fit’s control settings no longer distorts a profile
interval. One related item stays open post-0.6.0, a
sigma-slope start-value correction (issue #710.2), but it
does not touch the certified profile-CI cells described above.
Julia cross-family extractors are not wired yet. If
you fit a bivariate model with engine = "julia" across two
different families (a drmTMB_julia_xfam object),
vcov(), fitted(), residuals(),
predict(dpar = ...), and the coefficient table inside
summary() currently return an empty or NULL
result instead of an error or a value. What to try next: use the native
TMB engine, drmTMB’s default, for these extractors, or fit
the same-family Julia route instead; confint() and
predict() on native fits are unaffected. This is a known
code gap awaiting a post-0.6.0 fix, not a supported behaviour.
Missing data
Missing-data support is a separate axis from the tiers above: it is
likelihood based (missing responses are marginalised, missing predictors
are modelled inside the same likelihood), not multiple imputation and
not a posterior. It is validated against two single-source-of-truth
inventories. A positive runtime test reconciles all 18 fitted response
routes with the response ledger; predictor-family tests still require
every family outside drm_missing_predictor_families() to
reject. Route-specific tests cover unsupported response neighbours, so
an unsupported request is a clear error, never a silent wrong
likelihood. The full worked walkthrough is in
vignette("missing-data").
The response-missingness board below is generated from the same 18-route ledger as the capability surface. It distinguishes code admission from completed validation: a route receives a verified ✓ only at G3 recovery or above.
| Route | Runtime state | Evidence gate | Work state | Next gate |
|---|---|---|---|---|
gaussian |
implemented | G3 ✓ | verified | G4/G5 interval and coverage evidence are outside this arc. |
biv_gaussian |
implemented | G3 ✓ | verified | G4/G5 interval and coverage evidence are outside this arc. |
student |
implemented | G3 ✓ | verified | G4/G5 interval and coverage evidence are outside this arc. |
lognormal |
implemented | G3 ✓ | verified | G4/G5 interval and coverage evidence are outside this arc. |
gamma |
implemented | G3 ✓ | verified | G4/G5 interval and coverage evidence are outside this arc. |
poisson |
implemented | G3 ✓ | verified | G4/G5 interval and coverage evidence are outside this arc. |
nbinom2 |
implemented | G3 ✓ | verified | G4/G5 interval and coverage evidence are outside this arc. |
zi_poisson |
implemented | G3 ✓ | verified | G4/G5 interval and coverage evidence are outside this arc. |
zi_nbinom2 |
implemented | G3 ✓ | verified | G4/G5 interval and coverage evidence are outside this arc. |
beta |
implemented | G3 ✓ | verified | G4/G5 interval and coverage evidence are outside this arc. |
truncated_nbinom2 |
implemented | G3 ✓ | verified | G4/G5 interval and coverage evidence are outside this arc. |
hurdle_nbinom2 |
implemented | G3 ✓ | verified | G4/G5 interval and coverage evidence are outside this arc. |
cumulative_logit |
implemented | G3 ✓ | verified | G4/G5 interval and coverage evidence are outside this arc. |
beta_binomial |
implemented | G3 ✓ | verified | G4/G5 interval and coverage evidence are outside this arc. |
zero_one_beta |
implemented | G3 ✓ | verified | G4/G5 interval and coverage evidence are outside this arc. |
tweedie |
implemented | G3 ✓ | verified | G4/G5 interval and coverage evidence are outside this arc. |
skew_normal |
implemented | G3 ✓ | verified | G4/G5 interval and coverage evidence are outside this arc. |
binomial |
implemented | G3 ✓ | verified | G4/G5 interval and coverage evidence are outside this arc. |
A ✓ appears only at G3 recovery or above. Missing-response evidence does not change the model’s separate inference tier.
Missing-predictor support is a different axis and is not managed by the new response-missingness ledger:
| Response family | Missing predictor mi()
(predictor = "model") |
|---|---|
gaussian() |
✓ (broad predictor-model catalogue) |
binomial(), poisson(),
nbinom2(), beta()
|
✓ (one binary predictor) |
| every other family | — (rejects) |
Two missing-predictor details:
- Imputation-model catalogue. When the response is a univariate Gaussian location model, the missing predictor can be modelled with a wide family set — Gaussian, Bernoulli/logit, ordered cumulative logit, unordered softmax, beta, zero-one beta, beta-binomial (known trials), Poisson, NB2, zero-truncated NB2, lognormal, Gamma, and fixed-power Tweedie. The non-Gaussian responses above currently model one binary (Bernoulli/logit) missing predictor each.
-
Structured / multivariate
mi(). One intercept-only structured predictor model (phylo(),spatial(),animal(),relmat()) is available for the Gaussian-responsemi()route only. Multivariate/bivariate missing-predictor modelling is not available (that isgllvmTMB’s lane).
Not available anywhere yet, and rejected with a family-specific
message: non-binary missing predictors on non-Gaussian responses;
multiple missing predictors; mi() with random-effect,
structured, or zero-inflated response terms; response masking combined
with mi() in the same fit; and EM, profile, or REML
missing-data engines. No fitted response route remains at G0 on the
generated board, but each G3 tick applies only to the route and effect
structure named in its evidence row.
Full per-family capability map
The table below preserves the original whole-package view alongside the missing-response board. It shows distributional parameters, fixed and random effects, structured providers, REML, inference maturity, and both missing-data axes. Its missing-response column is generated from the same 18-route ledger.
| Response | dpars | Fixed | Random (int/slope) | Structured (phylo/spatial/animal/relmat/phylo_interaction) | REML | Highest evidence (exact scope) | Miss-response | Miss-predictor mi() |
|---|---|---|---|---|---|---|---|---|
| gaussian |
mu, sigma
|
mu: scope-limited (implemented 1; not implemented 1);
sigma: implemented |
mu: int implemented / slope implemented;
sigma: int implemented / slope implemented |
mu: phylo=scope-limited (implemented 4; rejected 1; not
implemented 1), spatial=implemented, animal=implemented,
relmat=implemented, phylo_interaction=implemented; sigma:
phylo=implemented, spatial=implemented, animal=implemented,
relmat=implemented, phylo_interaction=rejected |
mu: scope-limited (implemented 8; rejected 4);
sigma: scope-limited (implemented 8; rejected 3) |
supported — mc-0264 (mu;
ordinary_re_intercept; provider=none; estimator=ML;
dimension=univariate; q=na; variant=base); mc-0268 (mu;
ordinary_re_slope; provider=none; estimator=ML; dimension=univariate;
q=na; variant=base) |
G3 ✓ recovery verified | implemented: broad predictor-family catalogue |
| biv_gaussian |
sigma1, sigma2, rho12,
mu2, mu1
|
sigma1: implemented; sigma2: implemented;
rho12: implemented; mu2: implemented;
mu1: implemented |
sigma1: int scope-limited (implemented 1; rejected 1) /
slope implemented; sigma2: int implemented / slope
implemented; rho12: int rejected / slope absent;
mu2: int implemented / slope implemented; mu1:
int scope-limited (implemented 2; rejected 1) / slope implemented |
sigma1: phylo=implemented, spatial=implemented,
animal=implemented, relmat=implemented, phylo_interaction=absent;
sigma2: phylo=implemented, spatial=implemented,
animal=implemented, relmat=implemented, phylo_interaction=absent;
rho12: phylo=absent, spatial=absent, animal=absent,
relmat=absent, phylo_interaction=absent; mu2:
phylo=implemented, spatial=implemented, animal=implemented,
relmat=implemented, phylo_interaction=absent; mu1:
phylo=scope-limited (implemented 9; rejected 1), spatial=scope-limited
(implemented 7; rejected 1), animal=scope-limited (implemented 7;
rejected 1), relmat=scope-limited (implemented 7; rejected 1),
phylo_interaction=not implemented |
sigma1: scope-limited (implemented 5; rejected 1);
sigma2: implemented; rho12: implemented;
mu2: scope-limited (implemented 7; rejected 1);
mu1: scope-limited (implemented 12; rejected 4) |
supported — mc-0069 (mu1;
ordinary_re_intercept; provider=none; estimator=ML; dimension=bivariate;
q=na; variant=legacy_01); mc-0070 (mu2;
ordinary_re_intercept; provider=none; estimator=ML; dimension=bivariate;
q=na; variant=legacy_01) |
G3 ✓ recovery verified | rejected by runtime gate (biv_gaussian response) |
| student |
mu, sigma, nu
|
mu: implemented; sigma: implemented;
nu: implemented |
mu: int implemented / slope implemented;
sigma: int rejected / slope rejected; nu: int
rejected / slope rejected |
mu: phylo=rejected, spatial=scope-limited (implemented
2; rejected 1), animal=absent, relmat=absent, phylo_interaction=absent;
sigma: phylo=rejected, spatial=absent, animal=absent,
relmat=absent, phylo_interaction=absent; nu:
phylo=scope-limited (implemented 1; rejected 1), spatial=rejected,
animal=absent, relmat=absent, phylo_interaction=absent |
mu: rejected; sigma: rejected;
nu: rejected |
interval_feasible — mc-0484 (mu;
fixed; provider=none; estimator=ML; dimension=univariate; q=na;
variant=base); mc-0485 (sigma; fixed; provider=none;
estimator=ML; dimension=univariate; q=na; variant=base);
mc-0486 (nu; fixed; provider=none; estimator=ML;
dimension=univariate; q=na; variant=base); mc-0487 (mu;
ordinary_re_intercept; provider=none; estimator=ML;
dimension=univariate; q=na; variant=base); mc-0488 (mu;
ordinary_re_slope; provider=none; estimator=ML; dimension=univariate;
q=na; variant=base) |
G3 ✓ recovery verified | rejected by runtime gate (student response) |
| lognormal |
mu, sigma
|
mu: scope-limited (implemented 1; rejected 1);
sigma: implemented |
mu: int implemented / slope implemented;
sigma: int implemented / slope rejected |
mu: phylo=scope-limited (implemented 1; rejected 1),
spatial=rejected, animal=rejected, relmat=scope-limited (implemented 1;
rejected 1), phylo_interaction=rejected; sigma:
phylo=rejected, spatial=rejected, animal=rejected, relmat=rejected,
phylo_interaction=rejected |
mu: rejected; sigma: rejected |
inference_ready_with_caveats — mc-0382
(sigma; ordinary_re_intercept; provider=none; estimator=ML;
dimension=univariate; q=na; variant=base) |
G3 ✓ recovery verified | rejected by runtime gate (lognormal response) |
| gamma |
mu, sigma
|
mu: implemented; sigma: implemented |
mu: int implemented / slope implemented;
sigma: int implemented / slope rejected |
mu: phylo=scope-limited (implemented 1; rejected 1),
spatial=rejected, animal=rejected, relmat=scope-limited (implemented 1;
rejected 1), phylo_interaction=rejected; sigma:
phylo=rejected, spatial=rejected, animal=rejected, relmat=rejected,
phylo_interaction=rejected |
mu: rejected; sigma: rejected |
inference_ready_with_caveats — mc-0242
(sigma; ordinary_re_intercept; provider=none; estimator=ML;
dimension=univariate; q=na; variant=base) |
G3 ✓ recovery verified | rejected by runtime gate (gamma response) |
| poisson | mu |
mu: scope-limited (implemented 1; not implemented
1) |
mu: int implemented / slope scope-limited (implemented
1; rejected 1) |
mu: phylo=scope-limited (implemented 2; not implemented
1), spatial=scope-limited (implemented 5; rejected 1; not implemented
1), animal=scope-limited (implemented 2; rejected 1; not implemented 1),
relmat=scope-limited (implemented 2; rejected 1; not implemented 1),
phylo_interaction=scope-limited (implemented 1; rejected 1) |
mu: rejected |
inference_ready_with_caveats — mc-0427
(mu; fixed; provider=none; estimator=ML; dimension=univariate; q=na;
variant=base) |
G3 ✓ recovery verified | implemented: one binary missing predictor |
| nbinom2 |
mu, sigma
|
mu: scope-limited (implemented 1; rejected 1);
sigma: implemented |
mu: int implemented / slope implemented;
sigma: int implemented / slope rejected |
mu: phylo=scope-limited (implemented 2; rejected 3; not
implemented 1), spatial=implemented, animal=implemented,
relmat=implemented, phylo_interaction=implemented; sigma:
phylo=scope-limited (implemented 1; rejected 1; not implemented 1),
spatial=implemented, animal=implemented, relmat=implemented,
phylo_interaction=not implemented |
mu: rejected; sigma: rejected |
inference_ready_with_caveats — mc-0397
(mu; fixed; provider=none; estimator=ML; dimension=univariate; q=na;
variant=base); mc-0398 (sigma; fixed; provider=none;
estimator=ML; dimension=univariate; q=na; variant=base) |
G3 ✓ recovery verified | implemented: one binary missing predictor |
| zi_poisson |
mu, zi
|
mu: implemented; zi: implemented |
mu: int rejected / slope rejected; zi: int
rejected / slope rejected |
mu: phylo=rejected, spatial=implemented, animal=absent,
relmat=absent, phylo_interaction=absent; zi:
phylo=rejected, spatial=implemented, animal=absent, relmat=absent,
phylo_interaction=absent |
mu: rejected; zi: rejected |
interval_feasible — mc-0657 (mu;
fixed; provider=none; estimator=ML; dimension=univariate; q=na;
variant=base); mc-0663 (zi; fixed; provider=none;
estimator=ML; dimension=univariate; q=na; variant=base) |
G3 ✓ recovery verified | implemented: one binary missing predictor via poisson
family-type gate |
| zi_nbinom2 |
mu, sigma, zi
|
mu: implemented; sigma: implemented;
zi: implemented |
mu: int rejected / slope rejected; sigma:
int rejected / slope rejected; zi: int rejected / slope
rejected |
mu: phylo=rejected, spatial=scope-limited (implemented
1; rejected 1), animal=rejected, relmat=rejected,
phylo_interaction=rejected; sigma: phylo=rejected,
spatial=rejected, animal=rejected, relmat=rejected,
phylo_interaction=not implemented; zi: phylo=absent,
spatial=rejected, animal=absent, relmat=absent,
phylo_interaction=absent |
mu: rejected; sigma: rejected;
zi: rejected |
interval_feasible — mc-0623 (mu;
fixed; provider=none; estimator=ML; dimension=univariate; q=na;
variant=base); mc-0625 (sigma; fixed; provider=none;
estimator=ML; dimension=univariate; q=na; variant=base);
mc-0627 (zi; fixed; provider=none; estimator=ML;
dimension=univariate; q=na; variant=base) |
G3 ✓ recovery verified | implemented: one binary missing predictor via nbinom2
family-type gate |
| beta |
mu, sigma
|
mu: implemented; sigma: implemented |
mu: int implemented / slope scope-limited (implemented
1; rejected 1); sigma: int rejected / slope rejected |
mu: phylo=scope-limited (implemented 1; rejected 1),
spatial=rejected, animal=scope-limited (implemented 2; rejected 1),
relmat=rejected, phylo_interaction=rejected; sigma:
phylo=rejected, spatial=rejected, animal=scope-limited (implemented 1;
rejected 1), relmat=rejected, phylo_interaction=rejected |
mu: rejected; sigma: rejected |
inference_ready_with_caveats — mc-0001
(mu; fixed; provider=none; estimator=ML; dimension=univariate; q=na;
variant=base); mc-0003 (sigma; fixed; provider=none;
estimator=ML; dimension=univariate; q=na; variant=base);
mc-0017 (mu; structured; provider=phylo; estimator=ML;
dimension=univariate; q=q1; variant=beta_phylo_q1_direct_sd) |
G3 ✓ recovery verified | implemented: one binary missing predictor |
| truncated_nbinom2 |
mu, sigma
|
mu: scope-limited (implemented 1; rejected 1);
sigma: implemented |
mu: int implemented / slope implemented;
sigma: int rejected / slope rejected |
mu: phylo=rejected, spatial=rejected, animal=rejected,
relmat=rejected, phylo_interaction=rejected; sigma:
phylo=rejected, spatial=rejected, animal=rejected, relmat=rejected,
phylo_interaction=rejected |
mu: rejected; sigma: rejected |
interval_feasible — mc-0508 (mu;
fixed; provider=none; estimator=ML; dimension=univariate; q=na;
variant=base); mc-0509 (sigma; fixed; provider=none;
estimator=ML; dimension=univariate; q=na; variant=base);
mc-0510 (mu; ordinary_re_intercept; provider=none;
estimator=ML; dimension=univariate; q=na; variant=base) |
G3 ✓ recovery verified | rejected by runtime gate (truncated_nbinom2
response) |
| hurdle_nbinom2 |
mu, sigma, hu
|
mu: implemented; sigma: implemented;
hu: implemented |
mu: int rejected / slope rejected; sigma:
int rejected / slope rejected; hu: int rejected / slope
rejected |
mu: phylo=rejected, spatial=rejected, animal=rejected,
relmat=rejected, phylo_interaction=rejected; sigma:
phylo=rejected, spatial=rejected, animal=rejected, relmat=rejected,
phylo_interaction=rejected; hu: phylo=rejected,
spatial=rejected, animal=rejected, relmat=implemented,
phylo_interaction=rejected |
mu: rejected; sigma: rejected;
hu: rejected |
interval_feasible — mc-0326 (mu;
fixed; provider=none; estimator=ML; dimension=univariate; q=na;
variant=base); mc-0342 (sigma; fixed; provider=none;
estimator=ML; dimension=univariate; q=na; variant=base);
mc-0358 (hu; fixed; provider=none; estimator=ML;
dimension=univariate; q=na; variant=base) |
G3 ✓ recovery verified | rejected by runtime gate (truncated_nbinom2
response) |
| cumulative_logit | mu |
mu: implemented |
mu: int implemented / slope implemented |
mu: phylo=scope-limited (implemented 1; rejected 1),
spatial=rejected, animal=rejected, relmat=rejected,
phylo_interaction=rejected |
mu: rejected |
inference_ready_with_caveats — mc-0227
(mu; ordinary_re_slope; provider=none; estimator=ML;
dimension=univariate; q=na; variant=base) |
G3 ✓ recovery verified | rejected by runtime gate (cumulative_logit
response) |
| beta_binomial |
mu, sigma
|
mu: implemented; sigma: implemented |
mu: int implemented / slope implemented;
sigma: int rejected / slope rejected |
mu: phylo=rejected, spatial=rejected, animal=rejected,
relmat=rejected, phylo_interaction=rejected; sigma:
phylo=rejected, spatial=rejected, animal=rejected, relmat=rejected,
phylo_interaction=rejected |
mu: rejected; sigma: rejected |
interval_feasible — mc-0025 (mu;
fixed; provider=none; estimator=ML; dimension=univariate; q=na;
variant=base); mc-0027 (sigma; fixed; provider=none;
estimator=ML; dimension=univariate; q=na; variant=base);
mc-0029 (mu; ordinary_re_intercept; provider=none;
estimator=ML; dimension=univariate; q=na; variant=base);
mc-0031 (mu; ordinary_re_slope; provider=none;
estimator=ML; dimension=univariate; q=na; variant=base) |
G3 ✓ recovery verified | rejected by runtime gate (beta_binomial response) |
| zero_one_beta |
mu, sigma, zoi,
coi
|
mu: implemented; sigma: implemented;
zoi: implemented; coi: implemented |
mu: int implemented / slope implemented;
sigma: int not implemented / slope not implemented;
zoi: int not implemented / slope not implemented;
coi: int not implemented / slope not implemented |
mu: phylo=not implemented, spatial=not implemented,
animal=not implemented, relmat=not implemented, phylo_interaction=not
implemented; sigma: phylo=not implemented, spatial=not
implemented, animal=not implemented, relmat=not implemented,
phylo_interaction=not implemented; zoi: phylo=not
implemented, spatial=not implemented, animal=not implemented, relmat=not
implemented, phylo_interaction=not implemented; coi:
phylo=not implemented, spatial=not implemented, animal=not implemented,
relmat=not implemented, phylo_interaction=not implemented |
mu: rejected; sigma: rejected;
zoi: rejected; coi: rejected |
inference_ready_with_caveats — mc-0575
(mu; ordinary_re_slope; provider=none; estimator=ML;
dimension=univariate; q=na; variant=base) |
G3 ✓ recovery verified | rejected by runtime gate (zero_one_beta response) |
| tweedie |
mu, sigma, nu
|
mu: scope-limited (implemented 1; not implemented 1);
sigma: implemented; nu: implemented |
mu: int implemented / slope implemented;
sigma: int rejected / slope rejected; nu: int
rejected / slope rejected |
mu: phylo=rejected, spatial=rejected, animal=rejected,
relmat=rejected, phylo_interaction=rejected; sigma:
phylo=rejected, spatial=rejected, animal=rejected, relmat=rejected,
phylo_interaction=rejected; nu: phylo=rejected,
spatial=rejected, animal=rejected, relmat=rejected,
phylo_interaction=rejected |
mu: rejected; sigma: rejected;
nu: rejected |
inference_ready_with_caveats — mc-0539
(mu; ordinary_re_slope; provider=none; estimator=ML;
dimension=univariate; q=na; variant=base) |
G3 ✓ recovery verified | rejected by runtime gate (tweedie response) |
| skew_normal |
mu, sigma, nu
|
mu: scope-limited (implemented 1; not implemented 1);
sigma: implemented; nu: implemented |
mu: int implemented / slope implemented;
sigma: int rejected / slope rejected; nu: int
rejected / slope rejected |
mu: phylo=rejected, spatial=rejected, animal=rejected,
relmat=rejected, phylo_interaction=rejected; sigma:
phylo=rejected, spatial=rejected, animal=rejected, relmat=rejected,
phylo_interaction=rejected; nu: phylo=rejected,
spatial=rejected, animal=rejected, relmat=rejected,
phylo_interaction=rejected |
mu: rejected; sigma: rejected;
nu: rejected |
inference_ready_with_caveats — mc-0464
(mu; ordinary_re_slope; provider=none; estimator=ML;
dimension=univariate; q=na; variant=base) |
G3 ✓ recovery verified | rejected by runtime gate (skew_normal response) |
| binomial | mu |
mu: implemented |
mu: int implemented / slope implemented |
mu: phylo=rejected, spatial=rejected, animal=rejected,
relmat=rejected, phylo_interaction=rejected |
mu: rejected |
inference_ready_with_caveats — mc-0057
(mu; fixed; provider=none; estimator=ML; dimension=univariate; q=na;
variant=base); mc-0061 (mu; ordinary_re_slope;
provider=none; estimator=ML; dimension=univariate; q=na;
variant=base) |
G3 ✓ recovery verified | implemented: one binary missing predictor |
Choosing an interval method
confint()’s default method is Wald
(method = "wald"), and for most unstructured fixed-effect
rows in Tier 1 that default is already calibrated. Do not collapse the
four structured-anchor evidence channels into one method: q1
mu and the exact phylo/relmat slope-only q2
mu1:x/mu2:x SD rows use the default
location-axis bias-corrected, small-sample-t Wald channel; q1
sigma uses raw uncorrected log-SD Wald-z evidence, with
profile diagnostic-only at g = 8; and the Arc 1a REML cells
use direct structured-SD profile evidence only inside their tested
discrete domains. Near a boundary, profile_targets(fit) can
identify a direct target worth diagnosing, but that does not promote
profile intervals for a row whose ledger calls them diagnostic-only.
When neither an admitted Wald channel nor an admitted profile channel is
available for a target, method = "bootstrap" is the
last-resort fallback.
For a structured sigma on count data where only the
point estimate is verified, prefer a better-tested alternative when the
interval matters to your conclusion: an ordinary
sigma ~ (1 | id) random intercept, or a fixed-effect
sigma ~ predictors model, both of which carry stronger
evidence than the structured-sigma recovery-only routes
above.
Where the exhaustive detail lives
This page is a summary. The full, machine-readable capability census
– one row per family, distributional parameter, effect type, structure
provider, estimator, and evidence tier, with a source citation for every
row – lives under docs/dev-log/dashboard/capability-census/
in the package repository. Read it when you need the exact test or
simulation artifact behind a specific cell rather than the tier-level
summary given here.