Skip to content
Merged
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
3 changes: 3 additions & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
^README\.Rmd$
^\.lintr\.R$
^_quarto\.yml$
^AGENTS\.md$
^CLAUDE\.md$
^\.claude$
^.*\.qmd$
^.*\.png$
^Vary.*\.r$
Expand Down
26 changes: 26 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"permissions": {
"allow": [
"Bash(Rscript -e:*)",
"Bash(R CMD build:*)",
"Bash(R CMD check:*)",
"Bash(git status:*)",
"Bash(git diff:*)",
"Bash(git log:*)",
"Bash(git show:*)",
"Bash(git fetch:*)",
"Bash(git ls-files:*)",
"Bash(git ls-remote:*)",
"Bash(git branch --list:*)",
"Bash(gh pr view:*)",
"Bash(gh pr list:*)",
"Bash(gh pr checks:*)",
"Bash(gh pr diff:*)",
"Bash(gh issue view:*)",
"Bash(gh issue list:*)",
"Bash(gh run view:*)",
"Bash(gh run list:*)",
"Bash(typos:*)"
]
}
}
83 changes: 72 additions & 11 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ recreate that pattern).
file. File name must match function name (dotted internal helpers
like `.helper_fn()` go in `R/helper_fn.R` — drop the leading dot in
the filename only).
- **`inst/stan/`**: Stan model files (`model_1.stan`, `model_2.stan`).

- **`inst/extdata/`**: Model files (JAGS today, plus the Stan models that the chapter branches carry).
- **`inst/examples/`**: One example script per exported function,
named `<function_name>-examples.R`.
- **`tests/testthat/`**: Unit tests, named `test-<function_name>.R`.
Expand All @@ -66,6 +67,10 @@ recreate that pattern).
- **`.Rbuildignore`**: Must exclude `^scripts$`, `^slurm$`, and
`^chapter2$` (last for historical safety).

- **`_typos.toml`**: Where accepted terms for crate-ci/typos go, at the repo root, created on demand.
- **`AGENTS.md`** and **`CLAUDE.md`**: Short orientation files for AI coding agents, both deferring to this file as the source of truth.
Record a repository convention here and let them point at it.

## Review Priorities — What Copilot Should Flag

### 1. R Package Structure
Expand All @@ -77,7 +82,8 @@ recreate that pattern).
`@example inst/examples/<fn>-examples.R`.
- One function per file. File name matches function name. Internal
helpers are dotted (`.helper_fn()`) and live in `R/helper_fn.R`.
- Stan model files belong in `inst/stan/`, never in a nested folder.

- Stan model files belong in `inst/extdata/`, never in a nested folder.

### 2. Examples That Actually Run

Expand Down Expand Up @@ -110,7 +116,7 @@ recreate that pattern).

### 5. Stan Model Files

- Stan files (`.stan`) belong in `inst/stan/`.
- Stan files (`.stan`) belong in `inst/extdata/`.
- Compiled Stan binaries (no extension, or `.exe`/`.hpp`) belong in
`.gitignore`.
- When a Stan model file is modified, verify:
Expand Down Expand Up @@ -253,18 +259,70 @@ spelling::spell_check_package()
```

Custom words live in `inst/WORDLIST`.
A second, separate accept-list lives in `_typos.toml` — see "Two Accept-Lists" below.

## Continuous Integration

The following workflows run on every PR. **All must pass** for merge:
Most workflows under `.github/workflows/` are thin callers of reusable
workflows in
[`Morrison-Lab/gha`](https://github.com/Morrison-Lab/gha), pinned to `@v2`.
Read the callee at its pinned tag before changing a caller's `with:` or
`secrets:` block: a caller passing a secret the pinned tag does not declare is
rejected before any job starts, and that failure produces no logs, no
annotations, and no check run.

Hand-maintained here, because `gha` models no equivalent:

1. **R-CMD-check.yaml** — Runs `R CMD check` on multiple platforms.
2. **lint-changed-files.yaml** — Lints PR-changed files with the custom
`.lintr.R` config. Fails on any lint.
3. **check-spelling.yaml** — Spell check.
4. **R-check-docs.yml** — Verifies `roxygen2::roxygenise()` output
matches committed `man/` and `NAMESPACE`.
5. **pkgdown.yaml** — Builds the pkgdown site.
2. **R-check-docs.yml** — Verifies `roxygen2::roxygenise()` output matches committed `man/` and `NAMESPACE`.
3. **check-readme.yaml** — Renders `README.Rmd`.
4. **pkgdown.yaml** — Builds the pkgdown site.
5. **test-coverage.yaml** — Coverage, uploaded to Codecov.
6. **pr-commands.yaml** — `/document` and `/style` PR commands.
7. **copilot-setup-steps.yml**, **phase0-debug.yaml** — Copilot agent environment setup, and a manual Phase 0 diagnostic run.

Called from `gha`:

- **spellcheck.yml** — [`{spelling}`](https://docs.ropensci.org/spelling/) over package prose, accepting `inst/WORDLIST`.
- **check-typos.yml** — crate-ci/typos over the lines a PR adds, accepting `_typos.toml`.
- **lint-changed-lines.yml** — lintr over the lines a PR adds or modifies, rather than whole changed files.
- **version-check.yml** and **bump-dev-version.yml** — the version pair described under "Versioning" below.
- **news.yaml** — requires a `NEWS.md` entry, bypassed with the `no changelog` label.
- **check-junk-files.yml**, **check-secrets.yml**, **check-phi.yml**, **check-links.yml**, **check-new-line-breaks.yml** — hygiene and safety checks.
- **lint-workflows.yml**, **lint-yaml.yml**, **lint-markdown.yml** — currently warn-only, while a pre-existing backlog is worked down.
- **claude.yml** and **claude-code-review.yml** — the `@claude` agent and its reviewer, which are a pair.
`claude.yml` dispatches the reviewer by filename, so keep both names and keep their pins in step.

`main` is a thin package skeleton: the chapter analysis code, the Stan models, and the dissertation sources live on long-running feature branches.
Check what is present with `git ls-files` before asserting a layout, rather than reading it from this file or from another branch's tree.

On the branches that carry `inst/scripts/`, `lint-changed-lines` reports a large pre-existing backlog.
It is not something a given PR introduced, and clearing it is not in scope for unrelated work.

## Versioning

**Do not change `DESCRIPTION`'s `Version:` in a pull request.**
It must match `main`'s exactly, and `version-check` fails a PR that changes it.
`bump-dev-version` bumps the dev counter after every merge to `main`, so a PR never needs to.

This inverted on 2026-08-27.
The older convention required every PR to increment the version, so older branches and older habits point the wrong way.
Apply the `no version increment` label when a deliberate version change is genuinely needed, such as a release.

**This departs from the lab manual deliberately.**
Its [quality-assurance checklist](https://ucd-serg.github.io/lab-manual/coding-practices.html) still lists "Version number has been incremented" as a pre-PR step, which predates `bump-dev-version`.
Here the automation owns the bump, so following that item fails `version-check`.
The manual remains authoritative on everything else.

## Two Accept-Lists

Adding a word to the wrong one silently fails.

- **`inst/WORDLIST`** — read by `spelling::spell_check_package()`, covering `DESCRIPTION`, `man/*.Rd`, vignette sources, and root Markdown.
Sorted by codepoint, so uppercase entries precede lowercase ones.

- **`_typos.toml`**, at the repo root — read by crate-ci/typos, covering everything the R spellchecker cannot see.
Put a domain abbreviation in `[default.extend-words]`, and prefer fixing a real typo in the source over listing it here.

## Things Not to Flag

Expand Down Expand Up @@ -298,8 +356,11 @@ When making changes:
`scripts/` or `vignettes/`.
7. **NEVER** commit real Shigella data or files matching
`dL_clean_*.rda` or patient data spreadsheets.
8. **NEVER** modify `inst/stan/*.stan` files for stylistic reasons —

8. **NEVER** modify `inst/extdata/*.stan` files for stylistic reasons —
only for clearly documented bug fixes.

9. **NEVER** change `DESCRIPTION`'s `Version:` in a pull request, because `bump-dev-version` owns it — see "Versioning" above.

Only search for additional information if these instructions are
incomplete or incorrect for your specific task.
130 changes: 130 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# Agent Instructions

Project guidance for AI coding agents working in `shigella` --- Codex, Cursor,
Gemini, opencode, and anything else that reads `AGENTS.md`.
Claude Code reads [`CLAUDE.md`](CLAUDE.md), which points back here for these
conventions and adds only what is specific to Claude Code.

[`.github/copilot-instructions.md`](.github/copilot-instructions.md) is the
**source of truth** for repository-specific structure, style, and workflow.
This file is a short orientation and a list of the conventions that most often
catch people out.
Defer to `copilot-instructions.md` for anything not stated here, and edit that
file rather than this one when the two would disagree.

Authoritative style guide: the
[UCD-SERG Lab Manual](https://ucd-serg.github.io/lab-manual/)
(source: <https://github.com/UCD-SERG/lab-manual>).

## Project context

`shigella` is an R package for multivariate Bayesian hierarchical modeling of
antibody response trajectories after confirmed *Shigella* infection.
It is maintained by UCD-SERG (Aiemjoy and Morrison labs).

## Repository layout

- `R/`, `man/`, `NAMESPACE`, `DESCRIPTION` --- package source and generated docs
- `inst/extdata/` --- model files (JAGS today; Stan models arrive with the chapter branches)
- `tests/` --- test suite
- `vignettes/articles/` --- Quarto manuscripts and the dissertation source
- `inst/WORDLIST` --- accepted spellings for [`{spelling}`](https://docs.ropensci.org/spelling/)
- `_typos.toml` --- where accepted terms for crate-ci/typos go, at the repo root
- `.github/workflows/` --- CI, mostly thin callers of `Morrison-Lab/gha`

## Conventions that trip people up

Each of these fails CI rather than merely being frowned upon.

### Never touch `Version:` in a PR

`DESCRIPTION`'s `Version:` must match `main`'s exactly.
The `version-check` workflow fails a PR that changes it.
`bump-dev-version` bumps the dev counter after every merge to `main`, so a PR
never needs to.

This inverted on 2026-08-27.
The older convention required every PR to increment the version, so older
branches, older instructions, and habit all point the wrong way.
If a deliberate version change is genuinely needed --- a release --- apply the
`no version increment` label.

**This deliberately departs from the lab manual**, whose
[quality-assurance checklist](https://ucd-serg.github.io/lab-manual/coding-practices.html)
still lists "Version number has been incremented" as a pre-PR step.
That checklist predates `bump-dev-version`, which did not exist when it was
written.
Here the automation owns the bump, so following the checklist item fails
`version-check`.
The manual remains authoritative on everything else.

### Two accept-lists, with different owners

Adding a word to the wrong one silently fails.

- `inst/WORDLIST` --- read by `spelling::spell_check_package()`.
Covers `DESCRIPTION`, `man/*.Rd`, vignette sources, and root Markdown.
Sorted by codepoint, so uppercase entries precede lowercase ones.

- `_typos.toml`, at the repo root --- read by crate-ci/typos.
Covers everything the R spellchecker cannot see, diff-scoped to what a PR
adds.
Put a domain abbreviation under `[default.extend-words]`, and prefer fixing
a real typo in the source over listing it here.
Create the file if it is not there yet; typos discovers it automatically.

### Documentation is generated

Run `devtools::document()` after editing any roxygen2 comment.
`R-check-docs.yml` re-runs `roxygen2::roxygenise()` and fails when the result
differs from what is committed.
Never hand-edit `man/` or `NAMESPACE`.

### CI is mostly `Morrison-Lab/gha`

Most workflows under `.github/workflows/` are thin callers of reusable
workflows, pinned to `@v2`.
Two things follow.

Read the callee at its pinned tag before changing a caller's `with:` or
`secrets:` block.
A caller that passes a secret the pinned tag does not declare is rejected
before any job starts, and that failure has no logs, no annotations, and no
check run --- so it is invisible in `gh pr checks` and on the PR.
`gh run list --workflow <file>` is what surfaces it.

Prefer fixing a shared problem in `Morrison-Lab/gha` over reintroducing a
hand-maintained workflow here.

## Before you open a PR

Run these locally; each has a CI counterpart that will fail otherwise.

```r
devtools::document()
lintr::lint_package()
spelling::spell_check_package()
devtools::check()
```

Add a `NEWS.md` entry under `# shigella (development version)`, or apply the
`no changelog` label when the change genuinely does not warrant one.

Write Markdown with semantic line breaks --- one sentence per line.
`check-new-line-breaks` scans the lines a PR adds and fails on lines packing
more than one sentence together.

## Branches carry more than `main` does

`main` is a thin package skeleton.
The chapter analysis code, the Stan models, and the dissertation sources live
on long-running feature branches and reach `main` only as those merge.

So check what is actually present before asserting a layout, rather than
reading it from this file or from another branch's working tree.
`git ls-files inst` settles it in one command.

One consequence worth knowing: `lint-changed-lines` passes on `main` and
reports a large pre-existing backlog on the branches that carry
`inst/scripts/`.
A failure there is not something that PR introduced.
62 changes: 62 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Claude Code Instructions

Project guidance for Claude Code --- the CLI, the IDE extension, and the
`@claude` GitHub Action.

[`AGENTS.md`](AGENTS.md) is the cross-agent contract and carries the same
conventions; read it rather than duplicating its content here.
[`.github/copilot-instructions.md`](.github/copilot-instructions.md) is the
**source of truth** for repository-specific structure, style, and workflow.
This file adds only what is specific to Claude Code.

Authoritative style guide: the
[UCD-SERG Lab Manual](https://ucd-serg.github.io/lab-manual/)
(source: <https://github.com/UCD-SERG/lab-manual>).

## Start here

Read [`AGENTS.md`](AGENTS.md) first.
Its "Conventions that trip people up" section covers the four things that fail
CI here: the inverted `Version:` rule, the two separate accept-lists,
generated documentation, and the `Morrison-Lab/gha` caller pins.

## Review scope

When reviewing a PR in this repository, judge it against
`.github/copilot-instructions.md` and the lab manual, in that order.
`copilot-instructions.md` carries a "Things Not to Flag" section; honour it.

Two review notes specific to this repository:

- `main` carries a thin package skeleton, and the chapter analysis code and
model files arrive with the long-running feature branches.
Derive the layout from `git ls-files` on the branch in front of you rather
than from prose.

- Where a branch carries `inst/scripts/`, that is analysis code rather than
package code, held to a looser standard than `R/`, and it carries a large
pre-existing lint backlog that no single PR introduced.

- Model files under `inst/extdata/` are not lintable as R, and their numerical
content --- priors, parameter names, simulation semantics --- is not to be
changed for style.

## Editing workflows

`.github/workflows/` is mostly thin callers of `Morrison-Lab/gha` reusable
workflows.
The integrated `GITHUB_TOKEN` cannot push changes under `.github/workflows/`,
so an `@claude` run that edits one needs a `WORKFLOW_TOKEN` secret; without it
the push is rejected and the commits are posted to the thread as a patch.

The two Claude workflows are a pair.
`claude.yml` dispatches `claude-code-review.yml`, so keep that filename, and
keep both pinned to the same major tag.

## Data handling

Never commit real *Shigella* participant data.
`check-phi` scans added lines on every PR, and `check-secrets` scans the whole
git history --- but neither is a substitute for not committing it.
Synthetic values that trip `check-phi` can be exempted with a `phi-allow`
comment on the line.
8 changes: 8 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@
Setting it in the caller records that intent
and keeps it from changing if the `@v2` default ever moves.

* Added `AGENTS.md` and `CLAUDE.md`, short orientation files for AI coding
agents that defer to `.github/copilot-instructions.md` as the source of
truth, plus a `.claude/settings.json` permissions allowlist (#35)

* Corrected `.github/copilot-instructions.md`, whose CI section was stale, and
recorded the inverted version convention and the two separate spelling
accept-lists there (#35)

# shigella 0.0.0

Started development.
1 change: 1 addition & 0 deletions inst/WORDLIST
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ PHI
Postprocess
SOSAR
Seroresponse
allowlist
changelog
df
ggplot
Expand Down
Loading