--- title: "Quantitative Project Risk Analysis with PRA" author: "Paul Govan" date: "`r Sys.Date()`" output: rmarkdown::html_vignette: toc: true toc_depth: 2 bibliography: pra.bib link-citations: true vignette: > %\VignetteIndexEntry{Quantitative Project Risk Analysis with PRA} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include=FALSE} # Render large currency values in full, not scientific notation. options(width = 80, scipen = 999) knitr::opts_chunk$set( echo = TRUE, collapse = TRUE, comment = "#>", fig.align = "center", fig.width = 6, fig.height = 4, out.width = "100%" ) set.seed(42) library(PRA) ``` **PRA** unifies a core set of widely adopted quantitative project risk analysis methods in a single, open-source implementation: the Second Moment Method (SMM), Monte Carlo simulation (MCS), earned value management (EVM), contingency and sensitivity analysis, noisy-OR risk inference and updating, sigmoidal learning curves, and design structure matrices (DSM). Beyond this foundational core, **PRA** implements probabilistic network methods for project risk, supporting the forward simulation of cost uncertainty and Bayesian conditioning along causal chains. **PRA** also exposes its core analytical functions as tools over the Model Context Protocol (MCP), so that large-language-model agents can run project risk analyses directly. This vignette walks through every module in turn, with working code drawn from a single R session, and closes with an integrated case study. # Introduction Quantitative risk analysis is a foundational discipline in project management, enabling organizations to assess schedule and cost uncertainty, identify high-impact risk drivers, and set evidence-based contingency reserves. This vignette presents **PRA**, an open-source R package that unifies the core quantitative methods of project risk analysis, schedule and cost uncertainty, earned value management, sensitivity and contingency analysis, learning curves, and dependency structure analysis, under a single, reproducible API. Despite broad industry adoption of quantitative methods, open-source tooling for integrated project risk analysis in R remains fragmented. Proprietary platforms such as Oracle Primavera Risk Analysis and Palisade \@RISK provide integrated workflows but impose licensing costs and limit reproducibility. Within R, no single package unifies Monte Carlo risk analysis, earned value management, noisy-OR risk inference, sigmoidal learning curves, and dependency structure analysis under a common API. The **mc2d** package [@mc2d] provides general-purpose two-dimensional Monte Carlo simulation but has no project-specific constructs. The **sensitivity** package [@sensitivity] implements variance-based indices for general functions but does not integrate with schedule or cost models. EVM metrics are absent from CRAN entirely. Bayesian packages such as **rstan** [@rstan] and **brms** [@brms] operate at a high level of generality and require substantial expertise to apply in project risk contexts. For probabilistic networks specifically, **bnlearn** [@bnlearn] and **gRain** [@gRain] are the established R tools: **bnlearn** provides structure and parameter learning along with graph-surgery interventions through `mutilated()`, and **gRain** performs exact junction-tree inference. Both are more general and more capable inference engines than the sampling-based module of [Probabilistic Networks](#sec-network). However, neither carries a project-risk vocabulary of risks, resources, and tasks, and neither connects to schedule, cost, or earned value; **PRA**'s contribution is that project layer rather than the underlying inference. **PRA** is the first package available on CRAN to integrate these project risk analysis methods in a single API. The comparison table below covers the closest general-purpose Monte Carlo and sensitivity packages and the dominant commercial platform, while a broader survey of project-specific R packages is provided below. Where the existing ecosystem is fragmented across general-purpose packages, none of which are project-specific, **PRA** provides a single reproducible, auditable API for the full workflow, integrating outputs across modules in a way that the fragmented ecosystem does not. For example, MCS results are directly fed into contingency and sensitivity analyses, and noisy-OR risk updates can re-parameterize task distributions for subsequent simulations. The package targets project analysts who work in R and require outputs that are compatible with standard reporting pipelines. It is annotated against the rOpenSci Statistical Software Review (SRR) general standards [@rOpenSciStats2021] and uses minimal hard dependencies: **mc2d** [@mc2d] for triangular distribution families and **minpack.lm** [@Elzhov2016] for nonlinear least-squares fitting. **PRA** also provides an R implementation of probabilistic-network methods for project risk that grounds causal networks in the resource-based view, showing that organizational capabilities and shared resources, not schedule uncertainty alone, are the structural pathways through which risks propagate across project tasks [@Govan2014; @Govan2016]. This approach is extended with structural network measures that quantify the topology of project risk networks [@Govan2020]. The [probabilistic network module](#sec-network) operationalizes these ideas by propagating distributions through the causal chain from risks to the total project risk. **PRA** is the first project risk analysis package to expose its core analytical methods as tools callable by LLM agents over the Model Context Protocol (MCP). The optional MCP server is activated through `Suggests`-only dependencies; therefore, the analytical core incurs no additional runtime cost. The following table underscores the primary contribution: no existing R package or commercial platform covers the foundational project risk workflow that **PRA** unifies. It summarizes how **PRA** compares with the most closely related R packages and the dominant commercial platform. ```{r comparison-table, echo=FALSE, results="asis"} comp <- data.frame( Feature = c( "MCS schedule risk", "EVM (11 metrics)", "Noisy-OR updating", "Learning curves", "Design structure matrices", "Probabilistic networks", "MCP tool server", "Open-source (CRAN)", "SRR general standards" ), PRA = c("Yes","Yes","Yes","Yes","Yes","Yes","Yes","Yes","Yes"), mc2d = c("Partial","---","---","---","---","---","---","Yes","---"), sensitivity = c("---","---","---","---","---","---","---","Yes","---"), `rstan/brms`= c("---","---","Yes","---","---","Partial","---","Yes","---"), `bnlearn/gRain` = c("---","---","Partial","---","---","Yes","---", "Yes","---"), `\\@RISK` = c("Yes","Yes","---","---","---","---","---","---","---"), check.names = FALSE ) knitr::kable( comp, caption = paste0("Comparison of PRA with related R packages and commercial", " tools. 'Partial' = only general-purpose support, requiring custom", " modeling and not project-specific; '---' = not supported."), align = "lcccccc" ) ``` A small number of CRAN packages do target project management specifically, but each addresses a single slice of the workflow rather than the integrated whole. The **ProjectManagement** package [@ProjectManagement] is the closest in spirit: it implements deterministic and stochastic scheduling, PERT/CPM, critical-path identification, and Monte Carlo simulation over activity durations, and is complementary to the schedule-network extension planned for **PRA** (see the [Summary](#sec-summary)), but it does not provide earned value management, noisy-OR risk updating, learning curves, dependency structure matrices, or probabilistic networks. The **plan** package [@plan] produces Gantt and burn-down charts for project visualization but performs no risk quantification. More generally, decision-analysis packages such as **decisionSupport** [@decisionSupport] apply Monte Carlo simulation to cost--benefit models under uncertainty, but are not organized around project-schedule or earned-value constructs. None of these packages, nor any single package on CRAN, spans the foundational project risk workflow that **PRA** unifies. The gap is not limited to R: open-source tooling for integrated project risk analysis remains sparse across languages, and no package in another ecosystem matches **PRA**'s combined scope either. In Python, **PyCostTools** [@PyCostTools] implements learning-curve and cost-estimating-relationship models similar in spirit to PRA's [learning curves](#sec-learning), but remains a low-adoption project without peer-reviewed documentation. The general-purpose **PyMC** [@PyMC2016] supports arbitrary Bayesian models but, unlike PRA's [probabilistic-network module](#sec-network), has no project-risk-specific vocabulary of risks, resources, and tasks. In Julia, **MCHammer.jl** [@MCHammerJL] provides Monte Carlo business-risk modeling with correlated sampling and sensitivity tornado charts in the style of Crystal Ball and \@RISK, but has seen minimal maintenance activity in recent years. Design structure matrix tools outside R target software and systems architecture rather than project risk, and no citable academic survey of open-source project-risk software outside R could be located; this survey is therefore drawn directly from the individual tools' own repositories rather than a secondary source. The package is installed from CRAN in the standard way: ```{r install, eval=FALSE} install.packages("PRA") library("PRA") ``` Optional dependencies, **ellmer** [@ellmer], **mcptools** [@mcptools], and **jsonlite** [@jsonlite], are only required for the MCP server, `pra_mcp_server()`. The remainder of this vignette describes each analytical module in turn, with working code examples drawn from the same R session. - [Schedule and Cost Uncertainty](#sec-uncertainty) covers SMM, MCS, contingency, sensitivity, and correlation matrix construction. - [Earned Value Management](#sec-evm) covers the eleven EVM metrics. - [Learning Curves](#sec-learning) covers sigmoidal growth models. - [Noisy-OR Risk Inference](#sec-bayes) covers prior and posterior risk probabilities. - [Probabilistic Networks](#sec-network) introduces the network module. - [Dependency Structure Analysis](#sec-dsm) covers design structure matrices, built from that same network example. - [Model Context Protocol Integration](#sec-agent) describes the agent layer. - [Illustrative Case Study](#sec-casestudy) works an end-to-end analysis. # Schedule and Cost Uncertainty {#sec-uncertainty} Two complementary methods are provided for quantifying schedule and cost uncertainty: the Second Moment Method for rapid analytical estimates, and Monte Carlo simulation for full distributional analysis. Contingency extraction and sensitivity analysis complete the workflow. To illustrate the workflow, **PRA** includes `building_project`, a bundled example dataset describing a mid-rise commercial building with six work packages, adapted from the construction-project examples in @Damnjanovic2020. ```{r bp-load} data("building_project", package = "PRA") bp <- building_project bp$task_names ``` ## Second Moment Method The Second Moment Method (SMM) propagates task-level means and variances to project-level estimates using the Central Limit Theorem [@Benjamin2000]. For a project with $n$ tasks: $$E[X] = \sum_{i=1}^{n} E[X_i], \quad \text{Var}(X) = \sum_{i=1}^{n}\text{Var}(X_i) + 2\sum_{i Posterior P(delay):", round(post_r, 3), "\n") ``` The shift from prior to posterior quantifies how much the site inspection evidence should move the project team's confidence in a schedule delay, information that feeds directly into whether the contingency reserve computed in Step 1 needs to be revisited. ## Step 6: Propagate Cost Through the Network Use the [probabilistic network](#sec-network) `net` to propagate cost uncertainty to the project total, then condition on the observation that Risk-2 (Technical Complexity) did not occur: ```{r cs-net} cat("Prior mean project cost: $", format(round(mean(sim_net$I)), big.mark = ","), "\n") cat("Prior P80 project cost: $", format(round(quantile(sim_net$I, 0.80)), big.mark = ","), "\n") cat("Posterior mean (Risk-2 = 0): $", format(round(mean(learn_net$I)), big.mark = ","), "\n") ``` Conditioning on the resolved risk lowers the expected project cost, closing the loop from uncertainty characterization to evidence-based updating. ## Step 7: Identify Coupled Tasks via DSM ```{r cs-dsm, fig.cap="Grandparent DSM for the case-study project, showing which task pairs share the most risk exposure through common resources."} g_cs <- grandparent_dsm(bp$resource_task, bp$risk_resource) plot(g_cs) ``` The Grandparent DSM reveals which task pairs share risk exposure through common resources, informing targeted contingency allocation and resource decoupling decisions. # Summary {#sec-summary} **PRA** is an R package whose primary contribution is being the first package to unify the foundational methods of quantitative project risk analysis in a single, open-source framework of ten integrated analytical modules: SMM, MCS, contingency analysis, sensitivity analysis, EVM (11 metrics), noisy-OR risk inference and updating, cost risk distributions, sigmoidal learning curves, correlation matrix construction, and design structure matrices. The eleventh module applies probabilistic network methods to project risk, with forward simulation and Bayesian conditioning over a network of risks, resources, and tasks. **PRA** also exposes its core analytical functions as tools over the Model Context Protocol, so that LLM agents can drive the package without any embedded model, the first project risk analysis package to do so. All exported functions are annotated against the rOpenSci SRR general standards, with a test suite verifying correctness, edge-case handling, and numerical stability across three operating systems. The package is licensed under MIT and the source is available at ; documentation and a companion online book are at . ## Limitations and Future Work Several limitations apply. First, **PRA** currently propagates uncertainty at the task level and does not yet model schedule logic, critical path, activity precedence, and resource leveling. Full schedule-network risk analysis, in which schedule Monte Carlo runs over an activity-precedence network, such as Program Evaluation and Review Technique / Critical Path Method (PERT/CPM) to identify the critical path and criticality indices under uncertainty, is a planned future direction that would extend **PRA** from task-level to network-level schedule risk. Second, `mcs()` induces task correlation through the Cholesky decomposition of the correlation matrix, which preserves every marginal exactly, but which fixes the dependence structure to the Gaussian family: tail dependence stronger than a multivariate normal implies, such as tasks that fail together only in extreme scenarios, cannot be represented. Richer dependence structures are planned. Third, the probabilistic network module is newer than the analytical core: its API may still evolve. Fourth, the package currently accepts data as R vectors and lists. Direct import from project management file formats (Microsoft Project, Primavera P6, CSV exports from Jira or Asana) is not supported and is planned for a future release. # Computational details {-} The results in this vignette were produced using R [@RCore] with the **PRA** package (version `r packageVersion("PRA")`) and its hard dependencies **mc2d** [@mc2d] and **minpack.lm** [@Elzhov2016]. The optional Model Context Protocol server additionally uses **ellmer** [@ellmer], **mcptools**, and **jsonlite**. R itself and all packages used are available from the CRAN at . A random seed of 42 is set at the start of the session so that the simulation output is reproducible. # References {-}