ggplot2 figures in place of base graphics,
tables through knitr::kable(), and a stated limit that the
random-effects lenses' fixed N(0, 5) coefficient prior dominates on
raw-scale (tens- or hundreds-scale) responses unless the caller
standardises the response and covariates before building the pass.synthesise() no longer silently drops a lens that abstains at
fit time. Previously the fit-time koine_abstention a lens returns had no
$status field, so the "contributed" filter dropped it without recording
why, and the synthesis-level abstention then blamed the PSIS gate
(psis_unreliable) even when no lens ever reached it. The lens's real
reason (e.g. convergence_failed, feature_unsupported) now propagates to
the synthesis-level reason when it is the sole distinct reason among the
declining lenses, and every declining lens is carried into
lenses_dropped with that reason.inst/INTEGRATION.md refreshed to describe the MET random-effects
structure (two crossed/nested intercepts) as in-corner, add the groups
argument to the IR-mapping table, and correct the stale version/licence
status block.README.md and CITATION.cff
previously stated no licence was declared and the package was
undistributed, while DESCRIPTION has declared MIT + file LICENSE since
2026-06-08 and the package is pushed to max578/koine. Both now state MIT
and the correct installation/contributing instructions.detail text, which
described the supported corner as "a single random intercept on one
grouping factor" -- stale since the MET (two crossed/nested intercepts)
structure landed at 0.3.0. It now names both supported shapes.n_eff annotated, and
the over-dispersed linear-pool envelope against the fitted data.---) with the house en dash (--) throughout
README.md and the vignette prose.@references (Vehtari, Simpson, Gelman, Yao & Gabry 2024 for the
PSIS gate; Yao, Vehtari, Simpson & Gelman 2018 for the stacking
objective) and an @examples block for is_abstention().CITATION.cff licence
wording) failing with an error, rather than skipping, under R CMD check,
where the source-tree files it reads are not installed alongside the
package.CONTRIBUTING.md's stale instruction to branch off a dev
branch that does not exist in this repository; it now says main.inst/CITATION, so citation("koine") returns a reference.(1 | variety) + (1 | trial). koine now
corroborates a production MET model directly --- on the variety-plus-trial
structure the production model actually fits --- rather than on a
single-random-effect reduction that discards the trial structure. Whether the
two groupings are crossed or nested is resolved from the data, never from the
formula.y ~ N(X beta, sigma^2 I + tau_variety^2 Z_variety Z_variety' + tau_trial^2 Z_trial Z_trial'). fit_glmm_marginal() samples
(beta, sigma, tau_variety, tau_trial) on that exact marginal (a dense
Cholesky of V) with a coordinate-wise slice kernel, integrating the random
effects out where the sealed engines sample or Laplace-approximate them. The
exact marginal log-likelihood was validated to machine precision against an
independent lme4 ML fit (the Independent Oracle Principle), and the MET fit
concords with the NIMBLE MET reference (which samples the two crossed random
effects). The draws now carry one tau_<grouping> per random factor.(1 | g) is
unchanged (byte-identical code path and accessors); the MET structure is the
new capability, dispatched only when two groupings are present. No exported
function gained or changed a required argument, so the public API and the
C1/C3 triangulation contract hold. koine_pass_from_design() gained a groups
argument (a named list of two grouping vectors) alongside the existing group.feature_unsupported) rather
than an ungrounded approximation; the single-random-intercept GLMM path
(Gaussian, binomial, Poisson) is untouched. The heavy-tailed single-RE lens
(fit_glmm_robust_re()) is excluded from a MET pass with a recorded reason
rather than dropping the second grouping.data_ungrounded and provenance_unverified (Independent Oracle Principle).
A converged, high-ESS lens fit on an ungrounded input still carries that
input's ungroundedness; these let a lens decline on a fact failure
(an input marked ungrounded in the orchestra provenance vocabulary), not
only on the existing numerical failures (convergence, calibration, ESS).K = 1). NIMBLE's inprod() over a length-1 vector generates non-compiling
Eigen C++, so the NIMBLE GLMM lenses now write the K = 1 fixed-effects mean
as the scalar beta[1] and keep inprod() for K >= 2. The bug never fired
before because every test used a K = 2 fixed part; the MET model (a commonly
intercept-only fixed part) surfaced it.fit_glmm_marginal) and the NIMBLE reference lens
(fit_nimble_glmm), validated by simulation-based calibration (SBC clean over
the contributing simulations: every parameter's rank uniform, p > 0.16) and
cross-engine concordance against NIMBLE (median standardised discrepancy 0.23,
SD ratios 0.94--1.17) on the identifiable-variance-component regime.log tau is slice-sampled, and the coefficients are slice-sampled along their
tau-resolved principal axes (the scaled eigenvectors of the Laplace
covariance of the coefficient conditional). This clears the variance-component
funnel neck where a
static-metric Hamiltonian kernel funnels (~50% divergences, ess_tau ~ 3) and a
Laplace independence proposal freezes; the Gaussian and binomial marginals keep
the joint NUTS kernel. A value-only marginal log-posterior
(.glmm_marginal_logpost_value) backs the slice kernel (it skips the score-
identity gradient quadrature the slice never uses).tau beyond ~2, the ~8% upper tail of the
prior) the marginalised funnel is too weakly identified for any marginal sampler
to mix --- with the random effects integrated out, the non-centred remedy is
unavailable. A post-fit convergence gate makes the lens ABSTAIN
(convergence_failed, a new first-class abstention reason --- too few effective
draws or chains that disagree) rather than contribute a badly-mixed opinion.
koine contributes a calibrated Poisson opinion where the variance component is
identifiable, and abstains where it is not (a first-class outcome, SS3).koine_opinion_draws() now mixes each parameter only over the lenses for which
it is comparable: the linear-predictor coefficients over every contributing
lens, but a scale parameter (sigma, tau) only over the family-likelihood
lenses. A likelihood-variant lens (the robust-t lens, which carries its own
Student-t likelihood) reports its scale on a different metric (a Student-t scale
rather than a Gaussian SD), so it is excluded from the scale mixture --- and
flagged in the new koine_scale_restricted attribute --- while still
contributing to the coefficients. This fixes a synthesised-sigma bias when a
likelihood-variant lens carried stacking weight (it dragged sigma toward the
t-scale); the fixed effects are unchanged. The draws are a per-parameter
marginal representation, which is what a parameter-marginal triangulation needs.First tagged release --- the version carrying the IR-targetable, re-entrant model
builder (koine_pass_from_design()) and the integration surface a parent
triangulation panel drives, so koine clears the backend contract's construction,
output, and determinism clauses. Licence declared MIT.
koine_pass() now parses an lme4-style random intercept (1 | g) on one
grouping factor into a fixed-effects design plus a random-effects design;
richer structure (random slopes, multiple or crossed/nested groupings) is
parsed and flagged unsupported so the battery abstains
(feature_unsupported) rather than silently fitting the wrong model. This
also closes a latent gap whereby a random-effects formula previously slipped
through as a wrongly parsed population model.resolve_battery() gained the feature-support gate (a lens enrols only when
its random-effects support matches the pass), with directional recorded
reasons.fit_glmm_marginal()
--- a koine-authored No-U-Turn (Hamiltonian) sampler that integrates the random
effects out (exact for the Gaussian LMM, adaptive Gauss-Hermite quadrature for a
GLMM) and rides the marginal's analytic gradient (the score identity for a GLMM,
closed form for the Gaussian) --- and fit_nimble_glmm() --- NIMBLE Gibbs that
samples the random effects. The two carry identical priors, so their agreement
is method-independent consensus. Enrolled (validated) for the Gaussian LMM and
the binomial GLMM (the Poisson GLMM is implemented but held experimental ---
see below).fit_glmm_robust_re(): a Gaussian LMM
whose random intercepts are Student-t (b_g ~ t_nu), integrated out via the
Normal scale-mixture (Gauss-Laguerre over the mixing scale). It is enrolled as
a spectrum over the degrees of freedom (a grid nu in {3, 8}, analogous
to the shrinkage spectrum), so stacking can favour the random-effect
tail-weight the data support. It is the within-battery analogue of the
population robust-t lens --- where the Gaussian-RE lenses corroborate (weights
collapse), the t-RE lenses earn real stacking weight when group effects are
heavy-tailed (n_eff ~ 1.75 on t_3 effects), so koine's RE opinion becomes
sensitive to random-effect structure rather than a weighted echo of one
assumption.family_spec). Fixed Gauss-Hermite is
non-convergent for the sharply-peaked Poisson count integrand; adaptive
Gauss-Hermite is accurate to ~1e-3 across the prior range and makes the
binomial GLMM validate more accurately..re_prior()): the log-link
Poisson uses a tighter coefficient / random-intercept-SD prior than the
Gaussian and binomial families, whose N(0, 5) prior is fine.assemble_loglik() and evidence_axis() gained random-effects branches built
on a single shared marginalisation core..dram_one_chain() and the marginal log-posteriors
guard both Metropolis acceptance ratios against non-finite log-posteriors, so
an extreme proposal is rejected (and a chain started from an impossible point
escapes) rather than halting on a NaN acceptance test. Finite cases are
unchanged.inst/validation/). The Poisson GLMM remains held
experimental and is not enrolled. The Hamiltonian kernel fixes the
count-intercept mixing that the random walk could not (the original failure),
but a minority of prior-plausible datasets with a large random-intercept SD
give the marginal a variance-component funnel that a static-metric sampler
cannot traverse cheaply (occasional divergences and order-minutes fits).
Because the random effects are marginalised, the usual non-centred remedy does
not apply; the recorded next step is a funnel-robust metric (Riemannian /
Fisher information, reused from the quadrature) or a bounded enrolled-tau range.koine_pass_from_design() --- an IR-targetable, re-entrant, deparse-free model
builder that constructs a pass directly from a named design matrix, a response,
a family, and an optional grouping vector (no model formula, no match.call()
capture, no session-global state). This is the programmatic entry a parent
triangulation panel drives (the backend contract's construction clause); it
preserves non-syntactic canonical column names such as (Intercept) verbatim.inst/INTEGRATION.md): koine_opinion_draws() materialises the single
synthesised opinion as a posterior draws_array over the parameters its
contributing lenses share, sampling each lens in proportion to its stacking
weight (a mixture over koine's own battery, with the stacking weights and
stacked predictive elpd surfaced as attributes --- never a pool across the
parent's independent engines). synthesise() gains keep_fits to retain the
per-lens fits for it, and koine_can_contribute() is a cheap pre-flight
capability predicate for the parent's backend-availability gate.First development scaffold --- the Stage-1 increment-1 spine.
The engine-neutral request (koine_pass()) with content-hashed provenance,
the evaluable family adapter (as_family_spec(), Gaussian / Binomial /
Poisson), and the uniform lens-output contract (fb_fit()) with a complete,
validated provenance record.
The enrolment registry and family-conditional resolve_battery() for the
leanest Stage-1 cut (DRAM, NIMBLE-Gibbs, Polya-Gamma Gibbs, DREAM); only the
DRAM lens carries a working adapter in this increment, the other three are
registered but excluded with a recorded reason.
The first opinion lens: a self-contained, koine-authored delayed-rejection
adaptive Metropolis sampler (fit_dram()).
The synthesis spine: pointwise log-likelihood assembly (assemble_loglik()),
the tier-1 PSIS reliability gate (gate_psis()), predictive-space
LOO-stacking (stack_opinion()), and the top-level synthesise() --- which
returns a first-class abstention when fewer than two independent opinion
lenses survive.
The dual-reader NetCDF interchange (read_idata_nc(), RNetCDF canonical with
an ncdf4 fallback), enforcing the four hard read assertions.
Abstention (abstention()) and the typed error taxonomy as first-class outcomes.
The full Stage-1 battery across three diversity axes: four inference-family
witnesses (DRAM, NIMBLE-Gibbs, Polya-Gamma Gibbs, DREAM_ZS), a heavy-tail
structure variant (fit_robust_t()), and a shrinkage spectrum
(fit_ridge() / fit_lasso() / fit_horseshoe()), with the
weight-concentration diagnostic and the weight_degenerate abstention.
The diagnostic layer is complete: alongside weight concentration,
linear_pool_envelope() reports an over-dispersed reference bracket
and flags disagreeing lenses leave-one-out, and evidence_axis() reports
per-lens marginal likelihoods (bridge sampling, prior-conditional). Both carry
role = "diagnostic" and are surfaced by synthesise(), never pooled into
the opinion.
A validation / maturity gate for koine-authored lenses (the open-arms
correctness obligation): simulation-based calibration (sbc_check()), an
exact grid-based reference-posterior check (reference_posterior_check()), and
the corroboration gate (gate_corroboration()). resolve_battery() now
excludes a koine-first lens until its validation evidence is on record --- an
unvalidated first-mover abstains. The DRAM, Polya-Gamma Gibbs, and robust-t
lenses are validated (the recorded study is in inst/validation/).
Release-grade documentation and tooling: a runnable @examples block on every
exported function, an en-GB spell-check gate (inst/WORDLIST), a pkgdown
site, a README, a CITATION.cff, an air.toml / .lintr style
configuration, and an R-CMD-check GitHub Actions workflow. R CMD check --as-cran is clean (no ERRORs or WARNINGs).
No licence is declared yet (pending the required consultation); the package is local-only and not distributed.