--- title: "Distributing models in a downstream package" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Distributing models in a downstream package} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include=FALSE} # Format the rendered R output consistently. knitr::opts_chunk$set(collapse = TRUE, comment = "#>") library(form.model) ``` ## Package layout A downstream package owns concrete models. Store each definition as `-form.yaml` under `inst/forms/`. Use explicit subdirectories when shipping several versions of the same named model. ```text exampleforms/ DESCRIPTION NAMESPACE R/survey.R inst/forms/survey-form.yaml ``` Declare `Imports: form.model` in `DESCRIPTION`. Supply a documented wrapper with explicit resource selection. ```r # Expose the packaged survey definition through a domain-specific function. survey_model <- function() { # Select the packaged survey definition with its exact identity and version. form.model::select_form_model( "forms/survey-form.yaml", id = "survey", version = "2026.2", package = "exampleforms" ) } ``` `package` names the installed package containing the YAML resource. ## Runnable equivalent The bundled example uses exactly the same installed-resource mechanism. ```{r} # Locate the installed survey definition. model_resource_path <- form_resource("examples/survey/form.yaml", "form.model") # Confirm that the installed resource exists. stopifnot(file.exists(model_resource_path)) # Load the definition with the exact survey identity and version. model_definition <- select_form_model(model_resource_path, "survey", "2026.2") # Inspect its catalogue and table requirements. form_references(model_definition) ``` Selection reads only supplied paths, validates all of them, and requires exactly one matching identity tuple. Supply an explicit list of files to support multiple versions. There is no directory scan or latest-version fallback. Package-relative paths cannot escape the installed package, including through symbolic links. ## Inspect fields and locations ```{r} # Inspect observation fields in workbook column order. form_fields(model_definition, sheet = "Observations") # Inspect the observation table layout. form_layout(model_definition, id = "Observations") # Locate the submission identifier's row and column. form_field(model_definition, id = "Metadata.submission")[c("row", "column")] ``` Fields retain declaration order; coordinates are one-based. Field IDs use `.`. Accessors expose declarations without executing constraints or loading reference data. See `?form_fields`, `?form_field`, `?form_layout` and `?form_references` for details. ## Pass models and dependencies explicitly A future validator accepts a model, submitted data, and caller-supplied reference snapshots. A form package must not fetch snapshots, connect to a database, or write files during package loading. Keep concrete domain definitions in the downstream package. Keep loader destinations and mappings in loader packages. Run model checks in downstream tests for every shipped resource. Reserve validation equivalence tests for the full proof.