Register your own node kinds and executors. bayesgrove handles the graph, cache, decision log, and workflow protocol.
| Term | Meaning in bayesgrove |
|---|---|
| Node set | A group of node kinds plus executors you register on a handle |
| Ruleset | A chosen set of workflow_packs plus the summary
vocabulary they consume |
| Domain module | An R helper or package that bundles node registration, pack selection, and project conventions |
| Plugin | A built-in executor set (e.g. bg_use_cmdstanr()) |
| Extension | Any combination of the four items above |
The stable public hooks are node-kind registration, built-in executor
activation (bg_use_cmdstanr() /
bg_use_brms()), and summary emission from executors.
Workflow-pack selection is also public. Custom workflow-pack providers
use internal APIs. External packages should emit the built-in summary
kinds rather than call unexported provider functions.
Select workflow packs
Projects start empty by default. If your workflow needs the built-in review vocabulary, activate and persist the packs you want after creating the project:
library(bayesgrove)
project_root <- file.path(tempdir(), "bg-extensions")
unlink(project_root, recursive = TRUE, force = TRUE)
handle <- bg_init(
path = project_root,
project_name = "Extensions"
)
bg_use_workflow_packs(
handle,
c(
"bayesgrove.default_bayesian",
"bayesgrove.process_guidance",
"bayesgrove.model_taxonomy",
"bayesgrove.prior_workflow",
"bayesgrove.model_checks",
"bayesgrove.model_selection",
"bayesgrove.stan_workflow",
"bayesgrove.causal_dagitty"
)
)
#> [[1]]
#> [[1]]$pack_id
#> [1] "bayesgrove.default_bayesian"
#>
#> [[1]]$version
#> [1] "0.2.0"
#>
#> [[1]]$config
#> list()
#>
#>
#> [[2]]
#> [[2]]$pack_id
#> [1] "bayesgrove.process_guidance"
#>
#> [[2]]$version
#> [1] "0.1.0"
#>
#> [[2]]$config
#> list()
#>
#>
#> [[3]]
#> [[3]]$pack_id
#> [1] "bayesgrove.model_taxonomy"
#>
#> [[3]]$version
#> [1] "0.1.0"
#>
#> [[3]]$config
#> list()
#>
#>
#> [[4]]
#> [[4]]$pack_id
#> [1] "bayesgrove.prior_workflow"
#>
#> [[4]]$version
#> [1] "0.1.0"
#>
#> [[4]]$config
#> list()
#>
#>
#> [[5]]
#> [[5]]$pack_id
#> [1] "bayesgrove.model_checks"
#>
#> [[5]]$version
#> [1] "0.1.0"
#>
#> [[5]]$config
#> list()
#>
#>
#> [[6]]
#> [[6]]$pack_id
#> [1] "bayesgrove.model_selection"
#>
#> [[6]]$version
#> [1] "0.1.0"
#>
#> [[6]]$config
#> list()
#>
#>
#> [[7]]
#> [[7]]$pack_id
#> [1] "bayesgrove.stan_workflow"
#>
#> [[7]]$version
#> [1] "0.1.0"
#>
#> [[7]]$config
#> list()
#>
#>
#> [[8]]
#> [[8]]$pack_id
#> [1] "bayesgrove.causal_dagitty"
#>
#> [[8]]$version
#> [1] "0.1.0"
#>
#> [[8]]$config
#> list()
vapply(bg_workflow_packs(handle), function(pack) pack$pack_id, character(1))
#> [1] "bayesgrove.default_bayesian" "bayesgrove.process_guidance"
#> [3] "bayesgrove.model_taxonomy" "bayesgrove.prior_workflow"
#> [5] "bayesgrove.model_checks" "bayesgrove.model_selection"
#> [7] "bayesgrove.stan_workflow" "bayesgrove.causal_dagitty"Those packs add review vocabulary without changing the graph engine:
-
bayesgrove.default_bayesian: computation review, fit criticism, candidate comparison, and branch disposition. -
bayesgrove.process_guidance: workflow preflight, iterative repair notes, and out-of-sample stability review. -
bayesgrove.model_taxonomy: PAD classification and utility-tradeoff review. -
bayesgrove.prior_workflow: prior rationale and prior predictive review. -
bayesgrove.model_checks: posterior predictive checks and, forlatent_inferencebranches, SBC and LOO-PIT calibration review. -
bayesgrove.model_selection: model-comparison evidence from fresh comparison summaries, with optional stacking weights. -
bayesgrove.stan_workflow: a bundled Stan-oriented ruleset covering the default loop, process guidance, taxonomy, predictive checks, model selection, Stan diagnostics, and projection review. -
bayesgrove.causal_dagitty: DAG-backed adjustment review, implication review, and causal selection contracts forlatent_inferencebranches.
bayesgrove.model_selection only acts at project scope
when there are at least two clean fit candidates. The taxonomy and
causal packs apply to branches with the relevant goal. After review of a
causal_selection_contract,
bayesgrove.causal_dagitty can constrain formulas and
projection-based selection to retain required identification terms and
exclude forbidden controls.
Build a node set
A node set is usually a helper that registers several node kinds for
one modeling domain. Each executor receives (node, inputs)
and returns plain R data.
register_normal_model_nodes <- function(handle) {
bg_register_node_kind(handle, "study_data", executor = function(node, inputs) {
data.frame(y = rnorm(50), x = rnorm(50))
})
bg_register_node_kind(handle, "prior_note", executor = function(node, inputs) {
list(
result = node$params,
summaries = list(list(
summary_kind = "prior_spec",
passed = TRUE,
severity = "ok",
metrics = list(scale = node$params$scale)
))
)
})
bg_register_node_kind(handle, "fit_normal", executor = function(node, inputs) {
data <- inputs[[1]]
list(
result = list(mean_y = mean(data$y)),
summaries = list(
list(
summary_kind = "prior_predictive_check",
passed = TRUE,
severity = "ok",
metrics = list(simulated_mean = 0.0)
),
list(
summary_kind = "posterior_predictive_check",
passed = TRUE,
severity = "ok",
metrics = list(ppc_p_value = 0.46)
),
list(
summary_kind = "pad_annotation",
passed = TRUE,
severity = "ok",
metrics = list(
model_class = "PAD",
primary_utility = "predictive_performance"
)
)
)
)
})
}For node sets that can be used together:
- Keep executors domain-specific and return plain data.
- Emit summaries as plain-data records so workflow packs can react to them.
Opening a project never runs project-supplied code
Executors are R functions, and a project’s runtime manifest stores
their source text so the project can be reopened later. For safety,
bg_open() restores the kind name, input contracts, and
executor source as metadata. It does not evaluate the saved source,
including when opening a project directory from an untrusted source.
To restore executable executors after opening, call
bg_restore_executors() explicitly:
handle <- bg_open("path/to/project")
# Default: print the stored source for each kind and abort, so you can
# review what would run before consenting.
bg_restore_executors(handle)
# Once you have reviewed the source, opt in:
bg_restore_executors(handle, trust = TRUE)With trust = FALSE (the default) the stored source for
each kind is printed and the call aborts. With trust = TRUE
each source is evaluated in a child of the global environment (not
inside the bayesgrove namespace), and a warning reminds you that
closures capturing the original environment are not restored.
Alternatively, re-register executors with
bg_register_node_kind().
Built-in executors (shipped with the package) are persisted as stable references and restore safely without this opt-in step.
Attach data to nodes
Node params contain data, not executable R source.
bayesgrove does not evaluate R code from params, including
data_fn_source or check_fn_source. To preserve
R types that JSON serialization can change, such as Stan’s typed
integers, attach the object with bg_set_node_data(). It
saves the object in the content-addressed store and sets a
data_ref param:
n_data <- bg_add_node(handle, kind = "stan_data", label = "Data")
bg_set_node_data(handle, n_data, list(N = 10L, y = as.integer(y)))Register executable R functions with
bg_register_node_kind(), or restore saved executors with
bg_restore_executors(trust = TRUE) after reviewing
them.
Emit diagnostic summaries
The optional packs are summary-driven. They do not require special node kinds; they use summary records attached to fresh results.
| Summary kind | Consumed by | Typical use |
|---|---|---|
prior_spec |
bayesgrove.prior_workflow |
Record the current prior specification |
prior_predictive_check |
bayesgrove.prior_workflow |
Review whether priors generate plausible observables |
posterior_predictive_check |
bayesgrove.model_checks |
Review fit-to-data mismatch after conditioning |
loo_pit_calibration |
bayesgrove.model_checks |
Review leave-one-out predictive calibration |
sbc_result |
bayesgrove.model_checks |
Review parameter recoverability and calibration for
latent_inference branches |
comparison_results / model_comparison /
stacking_weights
|
bayesgrove.model_selection |
Compare clean candidates and review weighting evidence |
projpred_selection /
projection_predictive_selection
|
bayesgrove.stan_workflow |
Review submodel compression and refit plans |
dagitty_adjustment |
bayesgrove.causal_dagitty |
Review DAG-derived adjustment sets |
dagitty_implications |
bayesgrove.causal_dagitty |
Review implied independencies and falsification targets |
causal_selection_contract |
bayesgrove.causal_dagitty |
Lock required terms, exclude forbidden controls, and rank admissible precision candidates |
pad_annotation |
bayesgrove.model_taxonomy |
Label a branch with PAD class and utility dimensions |
Causal selection contracts and constrained projpred workflows
A causal branch can emit a causal_selection_contract
summary to constrain model construction. Its fields include:
-
required_termsfor identification-critical covariates, -
forbidden_termsfor colliders, post-treatment variables, or other blocked controls, -
ranked_candidate_termsfor the admissible precision path from simpler to larger models, and - optionally
allowed_formulasto enumerate exact permitted RHS patterns.
Once that summary is reviewed, bayesgrove.causal_dagitty
can enforce formula consistency and keep downstream work on hold until
the branch’s formulas obey the contract.
bayesgrove.stan_workflow also forwards the same causal
payload into projection-predictive review so a
projpred-style node can search only inside the admissible
ranked candidate set.
bg_register_node_kind(handle, "causal_selection_contract", executor = function(node, inputs) {
list(
summaries = list(list(
summary_kind = "causal_selection_contract",
passed = TRUE,
severity = "ok",
metrics = list(
required_terms = c("treatment", "z"),
forbidden_terms = "post_treatment",
ranked_candidate_terms = c("w", "x")
)
))
)
})Start with the smallest causally valid formula. Add permitted terms in the specified order when evaluating precision. Restrict projection-based selection to the permitted candidates.
Use serializable data in each summary:
-
summary_kindfor dispatch, -
passedandseverityfor review urgency, -
metricsfor compact numeric or categorical evidence, - extra fields only when they remain stable plain data.
Package a domain module
A domain module combines bg_init() with
node-registration helpers in a reusable setup function. You can
distribute it as an extension package.
init_normal_workflow <- function(path) {
handle <- bg_init(
path = path,
project_name = "normal_workflow"
)
bg_use_workflow_packs(
handle,
c(
"bayesgrove.default_bayesian",
"bayesgrove.process_guidance",
"bayesgrove.model_taxonomy",
"bayesgrove.prior_workflow",
"bayesgrove.model_checks",
"bayesgrove.model_selection",
"bayesgrove.stan_workflow"
)
)
register_normal_model_nodes(handle)
handle
}Put the helper in an analysis package, a lab utility package, or a project script. Update the node set and its selected workflow packs together.
Built-in cmdstanr and brms executors
bayesgrove includes executors that call cmdstanr and brms and compute diagnostics themselves (divergences, R-hat, ESS, Pareto-k, posterior-predictive p-values). Activate them with:
bg_use_cmdstanr(handle)
bg_use_brms(handle)These register node kinds (stan_data,
cmdstanr_fit, brms_fit, loo,
compare, ppc, …) whose executors emit the
validated summary kinds the workflow packs consume. A
cmdstanr_fit node emits an hmc_diagnostics
summary. With the default review pack active, warning or error
diagnostics raise a blocking review_computation_validity
obligation.
Use the built-in executors for cmdstanr and brms, or register a
custom executor with bg_register_node_kind().
Rulesets
A ruleset combines:
- the
workflow_packsyou activate inbg_init(), and - the summary kinds your executors emit for those packs to interpret.
Registering new workflow-pack providers from an external package is not a public API. For custom review logic, use one of these approaches:
- emit the existing summary vocabulary and reuse the built-in packs,
- wrap a project-specific decision policy around
bg_next_actions(), or - pin to internal helpers only if you are comfortable tracking internal API changes.