Changes in version 0.3.2.9000 - The package has a logo. - README carries status badges and lists related packages. - CI runs lintr (report-only) and test coverage. Changes in version 0.3.2 - Documentation names kernR's mechanism-consistency test directly. Changes in version 0.3.1 - Dropped apsimx from Suggests. No apsimR function, test or vignette uses it; apsimR runs APSIM through the Models command line. - Removed the licence note that the package becomes a GPL combined work when installed with apsimx or PESTO: apsimx is no longer suggested and PESTO is MIT-licensed since 0.11.0. Changes in version 0.3.0 - The package vignette was brought to the orchestra's vignette quality bar: a fixed Why/What/Do/Read/Limits/What-to-read-next/Reproduce shape, a colourblind-safe ggplot2 leave-one-out figure alongside the existing observed-versus-predicted plot, knitr::kable() tables for every fitted or designed table, every printed number interpreted inline in prose, and guarded, one-sentence-explained skips for every simulator-dependent section on a build without APSIM installed. - apsimR now emits the orchestra's general result contract natively: as_orchestra_manifest() lifts any apsim_manifest into an orchestra_manifest at schema 2.0.0-draft, with verify_manifest() for payload integrity and manifest_summary() for a typed verdict. The class carries the federation's bare class identity and the reference integrity-hash recipe, so a consumer (decideR, conductoR, optimix) reads an apsimR result with no special casing; a sensitivity table maps onto the contract's parameters target and an emulator or validation onto predictions, with the original apsimR target preserved in metadata$apsim_target and a validation verdict lifted into the typed summary. - as_pesto_manifest() now produces a pesto_ensemble_manifest that PESTO itself verifies. The bridge previously abstained on every payload apsimR emits: it passed apsimR's method vocabulary and apsimR's own payload hash straight into PESTO's ensemble contract, which accepts neither. It now translates the method onto PESTO's enum, assembles the row-aligned parameter and simulated-observation ensemble the contract requires, and re-hashes with PESTO's own payload recipe. Results that are not ensemble inversions -- a prediction, a screening table, an emulator, a validation -- now abstain with a reason that names the requirement and points at as_orchestra_manifest(), instead of returning an opaque validator error. - apsim_calibrate(backend = "ies") keeps the simulated-observation ensemble and the assimilation context (observation targets and weights) in the result's metadata instead of summarising them away; both backends now record the assimilation context under the same names. - The as_pesto_manifest() test suite gained a positive path. The only bridge test skipped whenever PESTO was installed, so the success path had no coverage at all; the new tests run with PESTO present and assert against PESTO's own validator and hash verifier, and the contract tests assert against an independently authored sibling implementation of the same contract. - Added a GitHub Actions R-CMD-check workflow. Tests that need the APSIM simulator or the optional optimix package skip on the runner. - Added a README.md with a purpose statement, install instructions and a minimal runnable example. - Documented apsim_fact_status()'s previously-undocumented @examples. - Vignette: the emulation section now exercises the real exact-GP training and prediction pair on a genuine leave-one-out pass, with a plotted diagnostic, instead of demonstrating stats::smooth.spline under a Gaussian-process label; the estimation section calls the same internal fitter apsim_estimate() uses instead of a hand-rolled nls() call; both sections now state the governing equation (the Mitscherlich dose-response, the ARD squared-exponential kernel) rather than leaving the mathematics implicit in R code; the validation section now renders the observed-versus-predicted plot instead of only describing it; and mu.star is corrected to the emitted mu_star. - apsim_validate()'s documentation now states the Moriasi et al. (2007) performance bands were derived for watershed/streamflow simulation and directs readers to the joint NSE/RSR/PBIAS reading the source recommends rather than grading on NSE alone. The citation now carries its DOI. - Corrected apsim_sensitivity()'s documentation to name the emitted column mu_star, not mu.star. - apsim_external_facts() marks an unchecked fact "ungrounded" in the grounding column instead of "[unverified]"; apsim_fact_status() counts both values. Exact Gaussian-process emulator The "exact" emulator backend is now a genuine exact Gaussian process. It previously fixed a single isotropic length-scale by the median-distance heuristic with unit signal variance and never fitted its hyperparameters -- exact-inference, but never fitted, so on an anisotropic target it neither interpolated the design nor competed with a reference exact GP (an independent benchmark on the Branin function found it ~334x less accurate out-of-sample and not interpolating). The "exact" label is now true to its name. Behaviour change - apsim_emulate(backend = "exact") (and the internal .apsim_gp_train()) now fit per-dimension ARD length-scales, the signal variance and the noise variance by maximising the exact log marginal likelihood (the median heuristic only seeds the optimiser, with restarts against a local optimum). Predictions from the default backend therefore change -- and improve: on the Branin benchmark the surrogate's held-out RMSE now matches a marginal-likelihood-fitted DiceKriging exact GP (ratio ~0.85x, i.e. on par) and it interpolates the training design to ~1e-3 of the output range. The public API is unchanged. Bug fixes - The squared-exponential predictive variance now uses the fitted signal variance (it was implicitly fixed at one in standardised space), so the reported uncertainty scales correctly with the data. Changes in version 0.2.0 A stabilisation pass on the 0.1.0 core: the simulator-backed edit round-trip is fixed, the reference documentation is organised for a published site, and the expensive live oracles are run end-to-end against the installed APSIM. Bug fixes - apsim_edit() now completes the edit round-trip on a real install instead of abstaining. APSIM 2026.5's --apply SaveCommand resolves an absolute save target through the process temporary path (Path.GetTempPath()); under a sandboxed R session that path is the per-process confined temporary root, which R cannot write to, so the save failed with an UnauthorizedAccessException (the identical command from a bare shell succeeds -- the failure is specific to the R process's temporary-directory confinement, not a config-format change). The edit is now run with a relative save filename resolved against a writable scratch directory, then moved to the requested path; the source file is still never touched. Grounded against APSIM Next Generation 2026.5.8046.0. The live edit test asserts success (no tolerated abstention) and that the working directory is restored. Documentation - Adds a pkgdown configuration (_pkgdown.yml, Bootstrap 5) with the reference index grouped by verb family -- simulation files, run/predict, calibrate/ estimate, sensitivity/emulate, validate, causal ground truth (OSSE), the contract manifest, runtime/abstention, and external-fact grounding. pkgdown::check_pkgdown() reports no problems and pkgdown::build_site() runs clean. Verification - The expensive live oracles (forward-model evaluation, Morris sensitivity, Gaussian-process emulation with leave-one-out diagnostics, the OSSE ground-truth dataset, and the yield-versus-nitrogen monotonicity sign check) were run end-to-end against the installed APSIM Next Generation 2026.5.8046.0 via APSIMR_LIVE_TESTS=true and pass. These tests remain skip-gated so the suite stays green without the simulator present. Changes in version 0.1.0 First formal release. apsimR enrols APSIM Next Generation into the orchestra as a typed, contract-emitting analysis member: every entry point returns a versioned, provenance-complete apsim_manifest compatible with the PESTO ensemble-manifest contract, and abstains with a typed reason when the simulator or its runtime is absent. The release consolidates the Phase-1 through Phase-4 walking skeleton, the inference verbs, the OSSE causal test-bench, and the Independent-Oracle grounding of the APSIM facts the package asserts. New features - Independent Oracle Principle (Phase-1 grounding). apsim_external_facts() / apsim_fact_status(): a registry of the class-8 APSIM facts apsimR asserts (DataStore SQLite schema, the "Current" checkpoint, report columns, manager node paths) with the oracle that grounds each. The DataStore schema and report columns are grounded by a replayed real run (test-datastore-grounding.R) that asserts the fact by name, not just non-emptiness -- closing the "skip != pass" hole, and grounding the schema against a live run rather than the shipped empty Wheat.db stub. The audit's inference that Wheat.AboveGround.Wt is absent from the stock report was corrected by the live oracle: the report emits both Yield and Wheat.AboveGround.Wt. Adds a yield-vs-nitrogen monotonicity sign check (opt-in via APSIMR_LIVE_TESTS). - Validation and causal ground truth (Phase 4). apsim_validate() scores simulated output against observations with the standard goodness-of-fit metrics (RMSE, MAE, mean error, Nash-Sutcliffe efficiency, Willmott's d, RSR, percent bias) and a typed verdict against the Moriasi et al. (2007) performance bands; it accepts an apsim_predict() manifest, data frames joined on a key, or vectors, and emits a "validation" manifest. apsim_validation_plot() draws observed-versus-predicted when ggplot2 is present. apsim_ground_truth() turns the simulator into a known-causal-structure data factory: it runs each unit under control and treatment so both potential outcomes are known, assigns treatment at random or with covariate confounding, and returns an observing-system simulation experiment (OSSE) -- the observed (covariates, W, Y) a causal method consumes, plus the recorded individual and average treatment effects it is graded against. - Inference verbs (Phase 3), all over one shared forward model. apsim_calibrate() solves the inverse problem -- a bounded stats::optim point estimate by default, or a posterior parameter ensemble through PESTO's iterative ensemble smoother (with RTPS inflation) when that package is present; several targets calibrate jointly. apsim_sensitivity() runs global sensitivity analysis -- Morris elementary-effect screening and Sobol-Jansen variance decomposition (the sensitivity package). apsim_emulate() fits a Gaussian-process surrogate of an expensive output, returned with mandatory leave-one-out diagnostics (RMSE, R^2, 95% coverage) and a predict() method; the default exact-GP backend needs no extra package, and PESTO's GP / random-feature surrogates compose when present. - apsim_forward_model() exposes the shared core: a closure mapping an nreal x npar parameter matrix to an nreal x nobs observation matrix (the PESTO forward-model contract), one APSIM --apply edit-and-run invocation per realisation, failed runs recorded as NA rows. apsim_design() builds the parameter points a sweep evaluates (Latin hypercube, grid or random). - The apsim_manifest contract enum gains "sensitivity" and "emulator" inferential targets alongside "predictions" and "parameters". - First walking skeleton (Phase 1). apsim_predict() runs APSIM Next Generation over a simulation file and returns the simulated reports as a contract-emitting ensemble object; apsim_estimate() runs the simulator across an input grid and fits a mechanism (a saturating dose-response by default), returning the fitted parameters. Both emit an apsim_manifest compatible with the PESTO ensemble-manifest contract via as_pesto_manifest(). - Execution layer. apsim_available(), apsim_version() and apsim_configure() discover and pin the installed Models executable and its .NET runtime; the command-line factorial path runs a simulation file once and reads its outputs from the SQLite DataStore via apsim_read(). Entry points that need the simulator return a typed apsim_abstention when it is absent, so the package is standalone-functional. - apsim_sim() reads an .apsimx (JSON) file into a typed, round-trippable object; apsim_write() writes it back; apsim_edit() applies [Node].Property = value edits through APSIM's own --apply config mechanism. - Experimental server client (Phase 2). apsim_server() starts APSIM's persistent apsim-server and speaks its native socket protocol from R; apsim_run() (optionally with parameter overrides) and apsim_output() re-run a file held in memory without re-paying the per-run load. This is the throughput path for adaptive inner loops. It is marked experimental: APSIM's bundled V1 server has known issues on current builds (it can fail to run stock files, and its re-runs degrade), so apsim_run() / apsim_output() abstain cleanly when the server cannot run; the command-line path remains the reliable default engine.