From aa0476f4d1643adda0d0bf51edd2a4834e0df3aa Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 16 Aug 2026 15:31:02 +0000 Subject: [PATCH 1/2] ci: add Cloud Agent dev environment config Add a versioned .cursor/environment.json plus .cursor/install.sh that provision the R toolchain and CRAN dependencies (mirt, testthat, rcmdcheck, roxygen2) as prebuilt binaries and install the checked-out aFIPC package into the R user library. - R comes from the CRAN 'release' channel to match the r.yml CI. - CRAN packages come from r2u as Ubuntu binaries to avoid compiling mirt. - install step is idempotent and self-contained. - .cursor is added to .Rbuildignore so R CMD check stays clean. Co-authored-by: Seongho Bae --- .Rbuildignore | 2 ++ .cursor/environment.json | 4 ++++ .cursor/install.sh | 41 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 .cursor/environment.json create mode 100755 .cursor/install.sh diff --git a/.Rbuildignore b/.Rbuildignore index 232504f0..8989c62f 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -5,6 +5,8 @@ ^\.Rprofile$ ^\.github$ ^\.github/.* +^\.cursor$ +^\.cursor/.* ^\.codegraph$ ^\.codegraph/.* ^.*\.Rcheck$ diff --git a/.cursor/environment.json b/.cursor/environment.json new file mode 100644 index 00000000..1951d4eb --- /dev/null +++ b/.cursor/environment.json @@ -0,0 +1,4 @@ +{ + "name": "aFIPC", + "install": "bash .cursor/install.sh" +} diff --git a/.cursor/install.sh b/.cursor/install.sh new file mode 100755 index 00000000..44f80ee1 --- /dev/null +++ b/.cursor/install.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +# Cloud Agent install step for the aFIPC R package. +# +# The R toolchain and CRAN dependencies (mirt, testthat, rcmdcheck, roxygen2) +# are normally already present in the prebuilt environment base image/snapshot. +# The guarded block below only runs on a bare image so this script stays +# idempotent and self-contained. R itself is pulled from the CRAN "release" +# channel (matching the r.yml CI), and CRAN packages come from r2u as prebuilt +# Ubuntu binaries so mirt does not have to be compiled from source. +set -euo pipefail + +if ! command -v R >/dev/null 2>&1; then + sudo apt-get update -qq + sudo apt-get install -y --no-install-recommends wget ca-certificates gnupg dirmngr + + # CRAN apt repo: release R for Ubuntu noble. + wget -q -O- https://cloud.r-project.org/bin/linux/ubuntu/marutter_pubkey.asc \ + | sudo tee /etc/apt/trusted.gpg.d/cran_ubuntu_key.asc >/dev/null + echo "deb [arch=amd64] https://cloud.r-project.org/bin/linux/ubuntu noble-cran40/" \ + | sudo tee /etc/apt/sources.list.d/cran_r.list + + # r2u: prebuilt binary CRAN packages for Ubuntu noble. + wget -q -O- https://eddelbuettel.github.io/r2u/assets/dirk_eddelbuettel_key.asc \ + | sudo tee /etc/apt/trusted.gpg.d/cranapt_key.asc >/dev/null + echo "deb [arch=amd64] https://r2u.stat.illinois.edu/ubuntu noble main" \ + | sudo tee /etc/apt/sources.list.d/cranapt.list + printf 'Package: *\nPin: release o=CRAN-Apt Project\nPin: release l=CRAN-Apt Packages\nPin-Priority: 700\n' \ + | sudo tee /etc/apt/preferences.d/99cranapt >/dev/null + + sudo apt-get update -qq + sudo apt-get install -y --no-install-recommends \ + r-base-core r-cran-mirt r-cran-testthat r-cran-roxygen2 r-cran-rcmdcheck pandoc +fi + +# Install the checked-out aFIPC source into the R user library so that +# library(aFIPC) and the test suite run against the current tree. +USERLIB=$(R_PROFILE_USER=/dev/null Rscript -e 'cat(Sys.getenv("R_LIBS_USER"))') +mkdir -p "$USERLIB" +R_PROFILE_USER=/dev/null R CMD INSTALL --no-multiarch --no-staged-install -l "$USERLIB" . + +echo "aFIPC install complete: R=$(R --version | head -1)" From 0718deb2402d6bb3504b9a31a21fdfd6e7da428c Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 16 Aug 2026 15:42:23 +0000 Subject: [PATCH 2/2] ci: keep Cloud Agent install revision-agnostic Stop R CMD INSTALL of the current tree in .cursor/install.sh so environment-build snapshots cannot freeze library(aFIPC) at the build revision. Detect Ubuntu codename/arch, require CRAN deps before skipping the toolchain, and document .cursor/ in ARCHITECTURE.md, AGENTS.md, and CLAUDE.md. Co-authored-by: Seongho Bae --- .cursor/install.sh | 45 +++++++++++++++++++++++++++------------------ AGENTS.md | 3 +++ ARCHITECTURE.md | 9 +++++++-- CLAUDE.md | 2 ++ 4 files changed, 39 insertions(+), 20 deletions(-) diff --git a/.cursor/install.sh b/.cursor/install.sh index 44f80ee1..4f41758b 100755 --- a/.cursor/install.sh +++ b/.cursor/install.sh @@ -1,28 +1,43 @@ #!/usr/bin/env bash # Cloud Agent install step for the aFIPC R package. # -# The R toolchain and CRAN dependencies (mirt, testthat, rcmdcheck, roxygen2) -# are normally already present in the prebuilt environment base image/snapshot. -# The guarded block below only runs on a bare image so this script stays -# idempotent and self-contained. R itself is pulled from the CRAN "release" -# channel (matching the r.yml CI), and CRAN packages come from r2u as prebuilt -# Ubuntu binaries so mirt does not have to be compiled from source. +# Provisions CRAN-release R and the CRAN dependencies used by documented +# verification (mirt, testthat, rcmdcheck, roxygen2). This step must stay +# revision-agnostic: with environment builds, `install` is snapshotted and is +# not rerun on later checkouts, so this script must not `R CMD INSTALL` the +# current tree (that would freeze library(aFIPC) at the build revision). +# Agents should use testthat::test_local() / rcmdcheck against the checkout. +# +# R comes from the CRAN "release" channel (matching r.yml). CRAN packages +# come from r2u as prebuilt Ubuntu binaries so mirt is not compiled from source. set -euo pipefail -if ! command -v R >/dev/null 2>&1; then +toolchain_ready() { + command -v R >/dev/null 2>&1 || return 1 + R_PROFILE_USER=/dev/null Rscript -e ' + pkgs <- c("mirt", "testthat", "roxygen2", "rcmdcheck") + q(status = if (all(pkgs %in% rownames(installed.packages()))) 0 else 1) + ' >/dev/null 2>&1 +} + +if ! toolchain_ready; then + # shellcheck source=/dev/null + . /etc/os-release + ARCH="$(dpkg --print-architecture)" + # CRAN's Ubuntu channel is "-cran40/" (e.g. noble-cran40). + CRAN_SUITE="${VERSION_CODENAME}-cran40" + sudo apt-get update -qq sudo apt-get install -y --no-install-recommends wget ca-certificates gnupg dirmngr - # CRAN apt repo: release R for Ubuntu noble. wget -q -O- https://cloud.r-project.org/bin/linux/ubuntu/marutter_pubkey.asc \ | sudo tee /etc/apt/trusted.gpg.d/cran_ubuntu_key.asc >/dev/null - echo "deb [arch=amd64] https://cloud.r-project.org/bin/linux/ubuntu noble-cran40/" \ + echo "deb [arch=${ARCH}] https://cloud.r-project.org/bin/linux/ubuntu ${CRAN_SUITE}/" \ | sudo tee /etc/apt/sources.list.d/cran_r.list - # r2u: prebuilt binary CRAN packages for Ubuntu noble. wget -q -O- https://eddelbuettel.github.io/r2u/assets/dirk_eddelbuettel_key.asc \ | sudo tee /etc/apt/trusted.gpg.d/cranapt_key.asc >/dev/null - echo "deb [arch=amd64] https://r2u.stat.illinois.edu/ubuntu noble main" \ + echo "deb [arch=${ARCH}] https://r2u.stat.illinois.edu/ubuntu ${VERSION_CODENAME} main" \ | sudo tee /etc/apt/sources.list.d/cranapt.list printf 'Package: *\nPin: release o=CRAN-Apt Project\nPin: release l=CRAN-Apt Packages\nPin-Priority: 700\n' \ | sudo tee /etc/apt/preferences.d/99cranapt >/dev/null @@ -32,10 +47,4 @@ if ! command -v R >/dev/null 2>&1; then r-base-core r-cran-mirt r-cran-testthat r-cran-roxygen2 r-cran-rcmdcheck pandoc fi -# Install the checked-out aFIPC source into the R user library so that -# library(aFIPC) and the test suite run against the current tree. -USERLIB=$(R_PROFILE_USER=/dev/null Rscript -e 'cat(Sys.getenv("R_LIBS_USER"))') -mkdir -p "$USERLIB" -R_PROFILE_USER=/dev/null R CMD INSTALL --no-multiarch --no-staged-install -l "$USERLIB" . - -echo "aFIPC install complete: R=$(R --version | head -1)" +echo "aFIPC toolchain ready: R=$(R --version | head -1)" diff --git a/AGENTS.md b/AGENTS.md index b60b03df..63f46ef4 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -19,6 +19,9 @@ parameter calibration and test linking. - Keep `.github/dependabot.yml` active for GitHub Actions updates. - Keep `ARCHITECTURE.md` up to date when structure changes. - Keep README accurate for local verification commands. +- Keep `.cursor/install.sh` revision-agnostic: provision R + CRAN deps only. + Do not `R CMD INSTALL` the current tree in `install` (environment builds + freeze that copy). Use `testthat::test_local()` / `rcmdcheck` on the checkout. ## Editing priorities diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 3880f15c..59672533 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -19,6 +19,7 @@ metadata and CI are wired, and which parts are safe to evolve. - `.github/ISSUE_TEMPLATE/` - structured issue intake templates - `.github/CODEOWNERS` - code ownership map for reviews - `.github/dependabot.yml` - Automated Actions dependency updates +- `.cursor/` - Cloud Agent environment (`environment.json` + `install.sh`) - `docs/coderabbit/review-commands.md` - CodeRabbit command quick reference - `docs/operations/maintenance-runbook.md` - recurring maintainer operations checklist - `README.md` - User/developer entrypoint @@ -91,6 +92,10 @@ package metadata, and CI workflow definitions in Git. - Primary check: `R CMD check` via GitHub Actions - Local check command: - `Rscript -e 'rcmdcheck::rcmdcheck(args = c("--no-manual", "--as-cran"))'` +- Cloud Agent: `.cursor/environment.json` runs `.cursor/install.sh` to provision + CRAN-release R and r2u binaries (`mirt`, `testthat`, `roxygen2`, `rcmdcheck`). + `install` is snapshot-scoped and must not `R CMD INSTALL` the current tree; + use `testthat::test_local()` / `rcmdcheck` against the checkout. ## 9. Future Considerations / Roadmap @@ -103,9 +108,9 @@ package metadata, and CI workflow definitions in Git. ## 10. Project Identification - Project Name: aFIPC -- Repository URL: `https://github.com/seonghobae/aFIPC` +- Repository URL: `https://github.com/ContextualWisdomLab/aFIPC` - Primary Contact: Seongho Bae -- Date of Last Update: 2026-02-15 +- Date of Last Update: 2026-08-16 ## 11. Glossary / Acronyms diff --git a/CLAUDE.md b/CLAUDE.md index 264efb15..6a11a23e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -78,6 +78,8 @@ See `ARCHITECTURE.md` for the full map. Essentials: - `.github/workflows/` — `r.yml` (R CMD check), `code-quality.yml` (yamllint + markdownlint + actionlint), `security-audit.yml` (gitleaks + actionlint). All action refs are pinned to full commit SHAs. +- `.cursor/` — Cloud Agent environment. `install.sh` provisions R + CRAN + deps only; do not `R CMD INSTALL` the current tree there. Runtime is single-process and fileless: in-memory old/new form data -> `autoFIPC()` -> `mirt` calibration -> optional item parameter drift (IPD)