Run the jax-gcm CI gates locally on Derecho when GitHub Actions minutes are exhausted or a pre-push check is wanted — lint, fast tests (90% coverage), slow tests (80% PR coverage) and a local Claude…

Apache-2.0Auto-check passedDevelopment

Install Jcm Local CI

skills CLI
$ npx skills add climate-analytics-lab/jax-gcm --skill jcm-local-ci -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install climate-analytics-lab/jax-gcm jcm-local-ci --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/climate-analytics-lab/jax-gcm.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/jcm-local-ci .claude/skills/jcm-local-ci && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
jcm-local-ci
GitHub stars
108
Token cost
~3k tokens
SKILL.md length
1,611 words
Files
2 (incl. scripts)
Skills in repo
7
Repo updated
First seen
Licence
Apache-2.0

At a glance

Run the jax-gcm CI gates locally on Derecho when GitHub Actions minutes are exhausted or a pre-push check is wanted — lint, fast tests (90% coverage), slow tests (80% PR coverage) and a local Claude…

  • Tasks that involve Deep learning
  • SKILL.md covers One command, Which dinosaur the gate tests…, The gates, individually and Local Claude review — run it…, plus 2 more sections
  • Runs Shell scripts from its folder; calls pip, pytest and gh
  • Tasks that involve Linting and formatting

What it does

Jcm Local CI is an agent skill from climate-analytics-lab/jax-gcm. Run the jax-gcm CI gates locally on Derecho when GitHub Actions minutes are exhausted or a pre-push check is wanted — lint, fast tests (90% coverage), slow tests (80% PR coverage) and a local Claude code review. Use before pushing or merging any jcm branch without Actions.

Its SKILL.md is about 3k tokens, which your agent loads only when the skill is triggered. The skill folder holds 2 other files, including scripts (for example `scripts/local_ci.sh`).

It sits in Development, covering Deep learning, Linting and formatting and CI/CD. It works with GitHub Actions. The repository describes itself as: GCM Physics written in JAX. The licence is Apache-2.0.

When your agent uses it

  • Tasks that involve Deep learning
  • Tasks that involve Linting and formatting
  • Tasks that involve CI/CD

Example prompts

  • “/jcm-local-ci”

Requirements

  • Python 3
  • A Bash shell

What it can do on your machine

Read from SKILL.md and the folder at commit 0940e89. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Ships 1 file in scripts/ (Shell), which the agent can run.

    Shell commands in SKILL.md call:

    • pip
    • pytest
    • gh
    • ruff
    • python
    • git

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use pip, gh and git, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Jcm Local CI loads about 3k tokens when it runs. Until then it costs about 72 tokens; SKILL.md has 1,611 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~72
When it runs · the whole SKILL.md, loaded when a task matches
~3k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); the scripts in this folder are not scanned.

SKILL.md

The full file from climate-analytics-lab/jax-gcm at commit 0940e89, republished under its Apache-2.0 licence (© climate-analytics-lab). 1,611 words, ~3,029 tokens.

Download SKILL.mdSave it as .claude/skills/jcm-local-ci/SKILL.md (or your agent's skills folder). This skill also uses 1 other file; get the full folder from GitHub.
name
jcm-local-ci
description
Run the jax-gcm CI gates locally on Derecho when GitHub Actions minutes are exhausted or a pre-push check is wanted — lint, fast tests (90% coverage), slow tests (80% PR coverage) and a local Claude code review. Use before pushing or merging any jcm branch without Actions.

Local CI for jax-gcm

Reproduces the CI gates from .github/workflows/run_test.yaml + run_linter.yaml (lint, fast, slow and extras), plus the Claude review, without GitHub Actions.

One command

bash
scripts/local_ci.sh /path/to/worktree                  # lint here, both gates via qsub
scripts/local_ci.sh --local-fast /path/to/worktree     # ...and a fast gate on this node

Lint runs on the current node; both test gates run in a single develop-queue PBS job (select=1:ncpus=16:mem=200GB), fast then slow, sequentially. Watch the job log for FAST_EXIT=0, SLOW_EXIT=0 and the closing GATES PASSED: the job exits non-zero if either gate failed, so a job that ends green means both passed.

Every submission gets its own log, named for the tree it tests: <worktree>/jcm_ci.<tag>.<UTC timestamp>.log, where <tag> is HEAD's short sha, with +dirty.<hash> appended when the worktree differs from HEAD — tracked edits or untracked, non-ignored files, which pytest would collect too; the hash is of that difference (the tracked diff and every untracked file's contents), so two different dirty trees on one commit get different tags. The PBS job is named jcm_ci_<tag>_<timestamp> to match (punctuation replaced by _, to keep the name to characters every PBS accepts). The script prints the exact log path and the watch command when it submits:

bash
tree: 1a2b3c4d.20260930T051200Z
log:  /path/to/worktree/jcm_ci.1a2b3c4d.20260930T051200Z.log
watch: grep -E 'FAST_EXIT|SLOW_EXIT|GATES' /path/to/worktree/jcm_ci.1a2b3c4d.20260930T051200Z.log

The job tests the worktree as it is when the job starts, which an edit or a commit made while it queued can change, so it recomputes the tag then: the log opens with submitted=<tag> tested=<tag> (and a WARNING line when they differ), and every result line carries both, GATES PASSED tree=<tag>.<timestamp> tested=<tag>.

Use the printed path, not a glob over jcm_ci.*.log: an earlier run's log in the same worktree is a verdict on an earlier tree, and a green line in it says nothing about the one just submitted. Check that the tested= tag on the line you read is the sha you pushed.

The gates go to a compute node because a login node caps you at 10 GiB (see docs/source/design/test_suite_memory.md) — well under what an -n 12 fast suite needs, so a local run there reports OOM-killed workers as unrelated test failures. --local-fast opts into an -n 2 fast run on the current node anyway, for a quick read before the job lands; it runs before the submission, never alongside it, because both would fight over the same worktree's .coverage.*.

Which dinosaur the gate tests against

The gate exists to reproduce CI, so it must run the dinosaur that pip install -e . resolves — requirements.txt pins dinosaur>=1.5.0, which carries the semi-Lagrangian transport jcm's backend requires (neuralgcm/dinosaur#135). The script therefore auto-detects nothing: a stale fork checkout sitting in $HOME would silently displace the pinned package and the gate would measure a dependency CI never sees, which is the one thing it is for.

A fork is used only when you pass JCM_DINOSAUR explicitly, and the run then says so and warns that it is not at CI parity. With no override and an installed dinosaur that lacks the SL class, the script fails before lint and names both remedies — pip install -e ., or JCM_DINOSAUR=<checkout>. (Failing is the point: without SL every model-construction test raises, and ~100 unrelated failures bury the ones that matter.)

~/.venvs/jaxgcm satisfies the pin (dinosaur 1.5.0), so gate jobs from it need no override — just run the script. JCM_DINOSAUR remains the escape hatch for a pre-release checkout, and a run using it says so and states that it is not at CI dependency parity.

The gates, individually

bash
# 1. Lint (run_linter.yaml)
ruff check .

# 2. Push gate — fast tests, 90% coverage
JAX_PLATFORMS=cpu pytest -n 12 -m "not slow" --cov=jcm --cov-fail-under=90
coverage report --fail-under=90

# 3. PR gate — slow tests only, 80% coverage vs .coveragerc-pr
JAX_PLATFORMS=cpu pytest -n 4 -m "slow" --cov=jcm \
    --cov-config=.coveragerc-pr --cov-fail-under=80
coverage report --rcfile=.coveragerc-pr --fail-under=80
bash
# 4. extras-tests — every test an optional extra gates, fast and slow, in a
#    SEPARATE venv (installing the extras into the coverage venv breaks
#    dependency parity for gates 2 and 3):
pip install -e ".[$(python tools/ci/optional_extras.py pip-extras)]"
python tools/ci/optional_extras.py check
JCM_REQUIRE_EXTRAS=1 JAX_PLATFORMS=cpu pytest -v -rs -m requires_extra

Gate 4 mirrors the extras-tests job. Under JCM_REQUIRE_EXTRAS=1 the session refuses to start without every extra and a selected test that skips is a failure, so a green run means every gated test ran. It is serial on purpose, as in CI: the pySES delegating-config chunk peaks at ~12.7 GB. About 13 min on the dev workstation. A test gates on an extra only through @pytest.mark.requires_extra(...); any other gate fails gates 2/3 (see tools/ci/optional_extras.py). local_ci.sh does not run it: it needs its own venv, so run the three commands yourself.

Gate 3 runs the whole slow suite in one command. CI runs the same tests as two parallel path shards (slow-tests-radiation / slow-tests-rest, defined with their partition check in tools/ci/slow_shards.py) and enforces the 80% floor on their combined coverage in slow-coverage; the local gate is equivalent.

The trailing coverage report is not redundant — it mirrors the two enforcement steps CI gained in #786, and it is the one that exits non-zero on plugin behaviour nobody controls. See the "Coverage differs by suite" note below.

Gates 2 and 3 are real compute — run them on a develop-queue node, not a login node; local_ci.sh does. The -n 4 on gate 3 is mandatory on Derecho, not an optimization: a single serial process accumulates thousands of mmap'd XLA JIT code sections and dies mid-suite with LLVM ERROR: Unable to allocate section memory! (SIGSEGV/SIGABRT — three attempts at 120–220 GB all failed identically; RAM is not the issue, per-process map count is). Splitting across workers resets the budget. GitHub's runners tolerate the serial run; Derecho's do not. (docs/source/design/test_suite_memory.md covers the related growth in retained XLA executables that the root conftest.py bounds.)

Local Claude review — run it BEFORE pushing, on the right model

The adversarial self-review jcm-dev-workflow step 3 requires before every push that changes code: Codex credits are finite, and a finding Codex makes that this review would have made is a credit burnt and a round lost. Fix or explicitly refute every finding before git push.

Which reviewer depends on the session's model. /code-review high forks the invoking session — same model, full conversation context inherited — and its finders and verifiers fan out the same way, so it is billed to that session at full context. It exhausted a Fable session limit twice on 2026-09-10 (the failure notices name the model: model sent to the API: claude-fable-5-1).

  • Opus or Sonnet session: /code-review high on the branch, as before.
  • Fable session: do not invoke the skill. Spawn a general-purpose agent with model: opus, give it the same scope (reference formulation, JAX hygiene, tests, docs, comment style, diff vs upstream), and have it post one review via gh pr review <PR> --comment --body-file <file>. Forward its findings to the authoring agent for fix-and-reply. This is how #776's blocker and #783's second-round findings were caught.
  • If the maintainer explicitly asks for /code-review from a Fable session, say first that it will fork on Fable at full context, and confirm.

For the deep cloud variant use /code-review ultra (user-triggered, separately billed).

Show full SKILL.md (566 more words)Show less

Codex review comments: always reply inline

Every Codex (or other bot) inline comment on a PR gets an explicit threaded reply stating the resolution — "Confirmed and fixed in <commit>: <what changed>" or "Refuted: <the evidence>" — via

bash
gh api -X POST repos/<owner>/<repo>/pulls/<PR>/comments/<comment_id>/replies \
    -f body="..."

(comment ids from gh api repos/<owner>/<repo>/pulls/<PR>/comments). Fixing the code silently is not enough: the reviewer tracks resolution through the comment threads, and an unanswered thread reads as an unaddressed finding. Verify a claim against the actual code/data before replying — Codex has been right (forcing unit conventions) and wrong (FZJ ozone units) on the same PR.

Facts that bite

  • Login-node load produces phantom failures. A -n 12 fast-suite run on a busy login node has produced 50+ failures across unrelated subsystems that all pass serially (twice now: 55 in July, 53 in August). That is why the fast gate is a PBS job too. Before believing a red --local-fast run, rerun a sample of the failures serially.

  • Never run two coverage suites concurrently in one worktree. pytest-cov erases .coverage.* at startup and combines at exit, so a fast-gate run (or a stray rm .coverage*) deletes an overlapping slow job's in-flight worker data — all its tests pass but whole modules lose credit (76%, then 0.00%, on a tree whose true number was 85%). Sequence the gates, or give the slow PBS job its own worktree.

  • Capture pytest's exit via PIPESTATUS[0], never $? after a | tail — and never pipe the slow suite through tail at all (a segfault's context ends up truncated).

  • Lint the whole repo (ruff check .), never a subdirectory — CI lints everything, including tools/ and stray root files. And never commit with git add -A: it sweeps untracked scratch files into the commit, which is exactly how a lint-clean jcm/ still turned CI red once. Stage files by name.

  • Coverage differs by suite. The fast gate uses .coveragerc (builders omitted); the slow gate uses .coveragerc-pr (also omits fast-tested utility modules). New fast-tested modules that slow tests never touch belong in .coveragerc-pr's omit list — that is the repo's documented mechanism, see the header comment there.

  • A floor is only enforced at the reported precision. fail_under is checked as round(total, precision) < fail_under, so at coverage's default precision of 0 the 80 floor was a 79.5 floor and the slow gate printed FAIL ... 79.68% while exiting 0 (#786). Both rcfiles now carry [report] precision = 2; run the gates with the repo's rcfiles (never a bare --cov-fail-under against a config that lacks it), and keep the standalone coverage report line so a plugin change cannot disarm the gate unnoticed.

  • JAX_PLATFORMS=cpu is mandatory on GPU nodes (xdist workers otherwise fight over the GPU).

  • The gate job asks for 16 cpus so -n 12 (fast) and -n 4 (slow) both fit, and 200 GB because the suite is memory-bound, not CPU-bound.

  • local_ci.sh exports JAX_COMPILATION_CACHE_DIR (default $SCRATCH/jcm-jax-cache) so xdist workers and successive gate runs share XLA compiles of identical jitted modules instead of each recompiling. Only the XLA-compile share is saved — tracing reruns — and only for bit-identical whole model steps. Safe: a miss just recompiles.

  • The repo pins ruff in CI, in two places that must agree — run_linter.yaml (lints everything, every push) and the lint gate job in run_test.yaml (the fast/slow suites hang off it). Run the pinned version (pip show ruff vs either file) before trusting a clean pass.

  • GPU-gated slow tests skip on CPU exactly as they do in CI — a local CPU pass is equivalent evidence.

© climate-analytics-lab, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 1 other file (scripts) in .claude/skills/jcm-local-ci of climate-analytics-lab/jax-gcm.

  • SKILL.md
  • scripts/local_ci.sh

Open the folder on GitHubat commit 0940e89

Compare with similar skills

Jcm Local CI next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Jcm Local CI compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Jcm Local CI this skillclimate-analytics-lab/jax-gcm108—~3kAutomated safety check: PassApache-2.0
Babysit PR To Pass CIsgl-project/sglang37k2 repos~3kAutomated safety check: PassApache-2.0
Update Dependenciesalorence/django-modern-rpc111—~1.3kAutomated safety check: PassMIT
Golang Continuous Integrationsamber/cc-skills-golang3.4k—~3.7kAutomated safety check: PassMIT
Golang Continuous Integrationcontext-labs/whip1.1k—~3.5kAutomated safety check: PassMIT
Python Pypi Package Buildergithub/awesome-copilot40k1 repos~4.6kAutomated safety check: PassMIT

Similar skills

  • Babysit PR To Pass CI

    sgl-project/sglang

    Start and persistently pursue a goal to babysit an SGLang pull request until selected GitHub Actions workflows pass on the latest PR head.

    37k GitHub starsUsed in 2 repos~3k tokens
    DevelopmentAuto-check passed
  • Update Dependencies

    alorence/django-modern-rpc

    Routine update of all project dependencies — uv itself, uv.lock (all groups), tool versions pinned in GitHub workflows and .pre-commit-config.yaml (uv, ruff, mypy...), and SHA-pinned GitHub Actions.

    111 GitHub stars~1.3k tokensUpdated 2 days ago
    DevelopmentAuto-check passed
  • Golang Continuous Integration

    samber/cc-skills-golang

    GitHub Actions CI/CD pipeline configuration for Golang projects — workflow files for test, lint, SAST, coverage and vulnerability-scan jobs, Dependabot and Renovate config files, GoReleaser release…

    3.4k GitHub stars~3.7k tokensUpdated 8 days ago
    DevelopmentAuto-check passed
  • CI/CD with GitHub Actions for Golang — testing, linting, SAST, security scanning, coverage, Dependabot, Renovate, GoReleaser, release pipelines.

    1.1k GitHub stars~3.5k tokensUpdated 4 days ago
    DevelopmentAuto-check passed
  • Python Pypi Package Builder

    github/awesome-copilot

    Official

    End-to-end skill for building, testing, linting, versioning, and publishing a production-grade Python library to PyPI.

    40k GitHub starsUsed in 1 repo~4.6k tokens
    DevelopmentAuto-check passed
  • Obsidian Plugin Release

    crafter-station/skills

    Release a new version of an Obsidian community plugin without forgetting steps.

    112 GitHub stars~1.8k tokensUpdated 1 mo ago
    DevelopmentAuto-check passed

More from climate-analytics-lab/jax-gcm

  • Derecho Jcm Runs

    climate-analytics-lab/jax-gcm

    Submit, monitor and benchmark jax-gcm (jcm) simulations on NCAR Derecho's PBS queues.

    108 GitHub stars~2.5k tokensUpdated today
    Auto-check passed
  • Kubernetes Jcm Runs

    climate-analytics-lab/jax-gcm

    Run jcm on a Kubernetes GPU cluster — generate benchmark and production Job manifests, pick a comparable GPU, survive eviction, collect results.

    108 GitHub stars~3.4k tokensUpdated today
    Auto-check passed
  • Devbox Jcm Runs

    climate-analytics-lab/jax-gcm

    Run jcm on the shared UCSD dev workstation (8x A100-80GB, no scheduler) — find a genuinely free GPU, avoid stomping on colleagues' jobs, environment and scratch paths, and the etiquette/traps…

    108 GitHub stars~1.7k tokensUpdated today
    Auto-check passed
  • Jcm Benchmark

    climate-analytics-lab/jax-gcm

    Measure jcm throughput reproducibly — short (1 month) or long (12 month) runs on a validated stable config, with GPU memory/utilisation logging and an explicit convergence criterion.

    108 GitHub stars~3.7k tokensUpdated today
    Auto-check passed
  • Jcm Dev Workflow

    climate-analytics-lab/jax-gcm

    End-to-end development workflow for jcm — atomic commits, the local test/lint gate, opening a PR linked to its issue, monitoring CI and the automatic Codex review, addressing feedback, and handing…

    108 GitHub stars~3k tokensUpdated today
    Auto-check passed
  • Jcm Run

    climate-analytics-lab/jax-gcm

    Launch a jcm model run through the built-in Hydra configs — config groups, the validated stable T63L47 overrides, Hydra override traps, and watching for startup failures.

    108 GitHub stars~2.1k tokensUpdated today
    Auto-check passed

Works with

Questions about Jcm Local CI

What does Jcm Local CI do?

Run the jax-gcm CI gates locally on Derecho when GitHub Actions minutes are exhausted or a pre-push check is wanted — lint, fast tests (90% coverage), slow tests (80% PR coverage) and a local Claude…. Jcm Local CI is an agent skill from climate-analytics-lab/jax-gcm. Run the jax-gcm CI gates locally on Derecho when GitHub Actions minutes are exhausted or a pre-push check is wanted — lint, fast tests (90% coverage), slow tests (80% PR coverage) and a local Claude code review.

When should I use Jcm Local CI?

Jcm Local CI fits situations like: tasks that involve Deep learning; tasks that involve Linting and formatting; tasks that involve CI/CD.

How do I install Jcm Local CI in Claude Code?

Run `npx skills add climate-analytics-lab/jax-gcm --skill jcm-local-ci -a claude-code`. Or copy the skill folder (.claude/skills/jcm-local-ci in climate-analytics-lab/jax-gcm) into .claude/skills/jcm-local-ci in your project. Claude Code loads it when a task matches its description.

How do I install Jcm Local CI in Codex?

Run `npx skills add climate-analytics-lab/jax-gcm --skill jcm-local-ci -a codex`. Or copy the skill folder (.claude/skills/jcm-local-ci in climate-analytics-lab/jax-gcm) into .agents/skills/jcm-local-ci in your project. Codex loads it when a task matches its description.

Can I use Jcm Local CI in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add climate-analytics-lab/jax-gcm --skill jcm-local-ci -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/jcm-local-ci, .gemini/skills/jcm-local-ci, .github/skills/jcm-local-ci and .opencode/skills/jcm-local-ci in your project.

What does Jcm Local CI need to run?

Going by SKILL.md and its folder, Jcm Local CI needs a shell for the scripts in its folder and the command-line tools its instructions call (pip, pytest, gh, ruff, python and git). Our summary lists: Python 3; A Bash shell.

Does Jcm Local CI access the network?

SKILL.md contains no URLs. Its commands use pip, gh and git, which can reach the network depending on how they are called. This is read from the text; nothing was executed.

Is Jcm Local CI safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.

What licence does Jcm Local CI use?

Jcm Local CI is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Jcm Local CI use?

About 3k tokens (SKILL.md is roughly 12k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Jcm Local CI?

Skills that share tags, products or a category with Jcm Local CI: Babysit PR To Pass CI (sgl-project/sglang, 37k stars), Update Dependencies (alorence/django-modern-rpc, 111 stars), Golang Continuous Integration (samber/cc-skills-golang, 3.4k stars) and Golang Continuous Integration (context-labs/whip, 1.1k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Jcm Local CI?

climate-analytics-lab (a GitHub organization) maintains it in climate-analytics-lab/jax-gcm, which has 108 GitHub stars. The repository holds 7 skills in this directory. The repository was last updated on October 9, 2026.

Source: climate-analytics-lab/jax-gcm on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.