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..4f41758b --- /dev/null +++ b/.cursor/install.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env bash +# Cloud Agent install step for the aFIPC R package. +# +# 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 + +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 + + 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=${ARCH}] https://cloud.r-project.org/bin/linux/ubuntu ${CRAN_SUITE}/" \ + | sudo tee /etc/apt/sources.list.d/cran_r.list + + 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=${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 + + 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 + +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)