Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions .cursor/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Cloud Agent environment

This directory configures the Cursor Cloud Agent development environment for
`aFIPC`.

- `environment.json` runs `install.sh` after the repository is checked out.
- `install.sh` provisions CRAN-release R plus the CRAN dependencies used by
documented verification (`mirt`, `testthat`, `roxygen2`, `rcmdcheck`) from
[r2u](https://eddelbuettel.github.io/r2u/) prebuilt binaries. It is
revision-agnostic: it never `R CMD INSTALL`s the current tree, because
environment builds snapshot `install` and do not rerun it on later checkouts.

Reproducibility across agents is pinned by the environment-build snapshot; the
apt block in `install.sh` only reprovisions a bare image.

Run the documented checks against the checkout:

```bash
R_PROFILE_USER=/dev/null Rscript -e 'testthat::test_local()'
R_PROFILE_USER=/dev/null Rscript -e 'rcmdcheck::rcmdcheck(args = c("--no-manual", "--as-cran"))'
```

Run a single test file with the `filter` argument (matches
`tests/testthat/test-<filter>.R`):

```bash
R_PROFILE_USER=/dev/null Rscript -e 'testthat::test_local(filter = "surveyFA")'
```

See `ARCHITECTURE.md` (sections 1 and 8) for how this fits the repository.

## Security

`install.sh` stores each repository key in its own keyring under
`/etc/apt/keyrings` and binds it to that repository with `signed-by`, so a key
can only vouch for its own source (no global `trusted.gpg.d` trust).
26 changes: 19 additions & 7 deletions .cursor/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,19 @@ if ! toolchain_ready; then
sudo apt-get update -qq
sudo apt-get install -y --no-install-recommends wget ca-certificates gnupg dirmngr

# Store each repository key in its own keyring and bind it to that repo with
# signed-by, so a key can only vouch for its own source (no global trust).
sudo install -d -m 0755 /etc/apt/keyrings

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
| sudo gpg --dearmor -o /etc/apt/keyrings/cran_r.gpg
echo "deb [arch=${ARCH} signed-by=/etc/apt/keyrings/cran_r.gpg] https://cloud.r-project.org/bin/linux/ubuntu ${CRAN_SUITE}/" \
| sudo tee /etc/apt/sources.list.d/cran_r.list >/dev/null

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
| sudo gpg --dearmor -o /etc/apt/keyrings/cranapt.gpg
echo "deb [arch=${ARCH} signed-by=/etc/apt/keyrings/cranapt.gpg] https://r2u.stat.illinois.edu/ubuntu ${VERSION_CODENAME} main" \
| sudo tee /etc/apt/sources.list.d/cranapt.list >/dev/null
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

Expand All @@ -47,4 +51,12 @@ if ! toolchain_ready; then
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)"
# Report resolved versions. Reproducibility across agents comes from the
# environment-build snapshot, which pins this toolchain at build time; this
# block only reprovisions on a bare image.
R_PROFILE_USER=/dev/null Rscript -e '
cat(sprintf("aFIPC toolchain ready: R %s\n", getRversion()))
for (p in c("mirt", "testthat", "roxygen2", "rcmdcheck")) {
cat(sprintf(" %-10s %s\n", p, as.character(packageVersion(p))))
}
'
Loading