Groovy 5 Developer Guide
apache/grails-core
Guidance for Groovy 5 work in Grails projects: syntax, closures, traits, DSLs, metaprogramming, Spock tests, static compilation and Java 21 integration.
A skill your agent uses when writing, reviewing or refactoring modern Java (21+, 25 LTS) — records and sealed interfaces as algebraic data types, exhaustive pattern-matching switch over instanceof…
$ npx skills add ericrisco/rsc-harness --skill java -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install ericrisco/rsc-harness java --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/ericrisco/rsc-harness.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/java .claude/skills/java && rm -rf skills-srcUse ~/.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/
Install the "java" agent skill from https://github.com/ericrisco/rsc-harness/tree/main/skills/java into .claude/skills/java/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "java", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/ericrisco/rsc-harness/tree/main/skills/javaType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add ericrisco/rsc-harness --skill java -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install ericrisco/rsc-harness java --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/ericrisco/rsc-harness.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/java .agents/skills/java && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "java" agent skill from https://github.com/ericrisco/rsc-harness/tree/main/skills/java into .agents/skills/java/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "java", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add ericrisco/rsc-harness --skill java -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install ericrisco/rsc-harness java --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/ericrisco/rsc-harness.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/java .cursor/skills/java && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "java" agent skill from https://github.com/ericrisco/rsc-harness/tree/main/skills/java into .cursor/skills/java/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "java", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/ericrisco/rsc-harness.git --path skills/java--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add ericrisco/rsc-harness --skill java -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install ericrisco/rsc-harness java --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/ericrisco/rsc-harness.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/java .gemini/skills/java && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "java" agent skill from https://github.com/ericrisco/rsc-harness/tree/main/skills/java into .gemini/skills/java/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "java", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install ericrisco/rsc-harness javaInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add ericrisco/rsc-harness --skill java -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/ericrisco/rsc-harness.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/java .github/skills/java && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "java" agent skill from https://github.com/ericrisco/rsc-harness/tree/main/skills/java into .github/skills/java/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "java", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add ericrisco/rsc-harness --skill java -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install ericrisco/rsc-harness java --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/ericrisco/rsc-harness.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/java .opencode/skills/java && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "java" agent skill from https://github.com/ericrisco/rsc-harness/tree/main/skills/java into .opencode/skills/java/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "java", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
javaA skill your agent uses when writing, reviewing or refactoring modern Java (21+, 25 LTS) — records and sealed interfaces as algebraic data types, exhaustive pattern-matching switch over instanceof…
Java is an agent skill from ericrisco/rsc-harness. Use when writing, reviewing or refactoring modern Java (21+, 25 LTS) — records and sealed interfaces as algebraic data types, exhaustive pattern-matching switch over instanceof ladders, virtual-thread concurrency, structured concurrency and ScopedValue replacing ThreadLocal, Stream and Optional pipelines, compact-constructor validation, parametrized JDBC, and the Maven/Gradle build surface. NOT Spring framework wiring (that is spring-boot).
Its SKILL.md is about 4.6k tokens, which your agent loads only when the skill is triggered. The skill folder holds 9 other files, including scripts and reference files (for example `evals/README.md`, `evals/cases.yaml` and `references/builds.md`).
It sits in Development, covering Backend development and Refactoring. It works with Java, Spring Boot, Gradle and Kotlin. The repository describes itself as: Your agent invents things because it has no memory, and can't touch your database because it has no arms. rsc is the meta-harness that gives it both, plus the trade to know the… The licence is MIT.
10 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit 92fde8f. It shows what the files ask for, not the result of running them.
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.
Ships 1 file in scripts/ (Shell), which the agent can run.
Shell commands in SKILL.md call:
mvnjavaFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Java loads about 4.6k tokens when it runs, and up to ~8.2k if it reads all its reference files. Until then it costs about 113 tokens; SKILL.md has 1,708 words of instructions outside code blocks.
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.
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.
The full file from ericrisco/rsc-harness at commit 92fde8f, republished under its MIT licence (© ericrisco). 1,708 words, ~4,571 tokens.
.claude/skills/java/SKILL.md (or your agent's skills folder). This skill also uses 6 other files; get the full folder from GitHub.Write, review, and refactor Java the way the language is shaped today, not the way it was in 2014.
Targets Java 21+ with Java 25 as the current LTS (released 2025-09-16, supported to
2033; Java 26 is the current non-LTS, 2026-03-17). "Modern" here means: records and sealed
interfaces instead of JavaBeans and type hierarchies, exhaustive pattern-matching switch
instead of instanceof+cast ladders, virtual threads instead of hand-tuned pools, and
ScopedValue instead of ThreadLocal. If you are reaching for a telescoping constructor,
a getter/setter bean, or a manual ExecutorService sized to a core count, stop.
Use when:
.java file.instanceof+cast chains or visitor boilerplate with a pattern-matching switch.ThreadLocal -> ScopedValue.pom.xml / build.gradle(.kts) for a current JDK (toolchain,
--release, preview flags, JUnit 5).When NOT to use (delegate):
@Transactional -> spring-boot.
This skill is the plain-JDK layer underneath; framework wiring is out of scope by topic.kotlin-android. Java and Kotlin interop but
are different languages; coroutines and Kotlin null-safety belong there.secure-coding. This skill keeps
only Java-specific controls (parametrized JDBC, compact-constructor validation, sane deser).deployment. This skill keeps only a
jlink/jpackage note and the JDK base-image choice.postgresdb. This skill covers JDBC
parametrization from the Java side only.harness (see "Project grounding").Records/sealed/pattern-matching design, virtual-thread concurrency, and the build surface live here — there is no separate "java-concurrency" or "java-build" skill.
Apply these on every Java edit:
record; it
gets equals/hashCode/toString and is immutable for free. Class only when you need
mutable identity or inheritance.switch over instanceof ladders. A closed set of cases is a
sealed interface; the compiler then proves your switch is total. An instanceof+cast
ladder is an unchecked manual version of this.final by default. Fields final, collections wrapped/copied; mutate
only where you have measured a reason. Shared mutable state is the bug you debug at 3am.Optional is a return type, never a field or parameter. It signals "maybe absent" to a
caller; an Optional field just adds a null-of-null. For absent collections, return empty.record's invariants belong in its compact
constructor so an invalid instance cannot exist — not in a separate validate() you can forget.PreparedStatement with ?, bind values; never
concatenate user input into SQL.map/filter/collect pipeline is
clear; a forEach that mutates external state is a loop wearing a costume — write the loop.-Xlint:all -Werror; an ignored
unchecked or deprecation warning is a deferred bug.A record is the default data carrier — immutable, no setters, validated in its compact
constructor.
// Good: invalid Money cannot exist; value semantics for free.
public record Money(long cents, Currency currency) {
public Money { // compact constructor
if (cents < 0) throw new IllegalArgumentException("cents < 0: " + cents);
Objects.requireNonNull(currency, "currency");
}
public Money plus(Money other) {
if (!currency.equals(other.currency)) throw new IllegalArgumentException("currency mismatch");
return new Money(cents + other.cents, currency);
}
}// Bad: telescoping constructors, mutable identity, hand-written equals you will get wrong.
public final class Money {
private long cents; private Currency currency;
public Money() {}
public Money(long cents) { this.cents = cents; }
public Money(long cents, Currency currency) { this.cents = cents; this.currency = currency; }
public void setCents(long c) { this.cents = c; } // now any caller can break invariants
public long getCents() { return cents; }
// ... 40 lines of getters/setters/equals/hashCode ...
}A sealed interface + record cases is an algebraic data type — a closed set the compiler knows about:
public sealed interface PaymentResult permits Captured, Declined, Pending {}
public record Captured(String id, Money amount) implements PaymentResult {}
public record Declined(String reason, int code) implements PaymentResult {}
public record Pending(String id, Instant retryAfter) implements PaymentResult {}Enum vs sealed: use an enum when cases are a fixed set of constants with no per-case
data (Status.ACTIVE); use a sealed interface when each case carries different fields
(above). Reaching for an enum plus a parallel "payload" map means you wanted a sealed type.
instanceof binds the pattern variable directly — no cast:
if (event instanceof Captured c) { // Good: c is in scope, already typed
ledger.record(c.id(), c.amount());
}An exhaustive switch over a sealed type with record deconstruction and when guards
replaces the whole ladder — and omit default when the sealed set is covered so adding a
new case becomes a compile error you must handle:
// Good: total over the sealed type; deconstruction patterns; guard; null branch.
String describe(PaymentResult r) {
return switch (r) {
case Captured(var id, var amt) when amt.cents() == 0 -> "free capture " + id;
case Captured(var id, var amt) -> "captured " + amt.cents() + "c " + id;
case Declined(var reason, var code) -> "declined(" + code + "): " + reason;
case Pending(var id, var __) -> "pending " + id;
case null -> "no result";
// no default: compiler proves exhaustiveness; a new permits-case won't compile until handled
};
}// Bad: instanceof + cast ladder. No exhaustiveness check; a new case silently falls through.
String describe(PaymentResult r) {
if (r instanceof Captured) { Captured c = (Captured) r; return "captured " + c.amount(); }
else if (r instanceof Declined) { Declined d = (Declined) r; return "declined " + d.reason(); }
else return "?"; // silently wrong when Pending is added
}Java 25 adds primitive type patterns in instanceof and switch (e.g. case int i),
extending exhaustiveness to primitives.
For blocking I/O, run one virtual thread per task inside a per-task executor closed with try-with-resources (the close call blocks until every submitted task finishes):
// Good: 500 blocking fetches, one virtual thread each. No pool sizing, no reactive ceremony.
List<String> fetchAll(List<URI> urls, HttpClient http) throws InterruptedException {
try (var exec = Executors.newVirtualThreadPerTaskExecutor()) {
var futures = urls.stream()
.map(u -> exec.submit(() -> http.send(
HttpRequest.newBuilder(u).build(), BodyHandlers.ofString()).body()))
.toList();
return futures.stream().map(f -> {
try { return f.get(); } catch (Exception e) { throw new CompletionException(e); }
}).toList();
} // close() joins all tasks
}// Bad: a fixed platform-thread pool caps you at N concurrent blocking calls and starves.
var exec = Executors.newFixedThreadPool(16); // 484 of 500 fetches wait on a threadJEP 491 (JDK 24) removed synchronized pinning — a virtual thread inside a synchronized
block no longer pins its carrier, so legacy synchronized code is safe on Loom now. For long
holds prefer ReentrantLock anyway (fairness, tryLock, interruptibility).
Structured concurrency (StructuredTaskScope) ties subtasks to a scope so one failure
cancels the siblings — but it is still preview in Java 25 (JEP 505, 5th preview), so it
needs --enable-preview. ScopedValue is FINAL in Java 25 (JEP 506) and is the immutable
replacement for ThreadLocal when sharing context across virtual threads:
// Good: immutable, explicitly scoped, propagates into child tasks; nothing to clean up.
private static final ScopedValue<String> REQUEST_ID = ScopedValue.newInstance();
ScopedValue.where(REQUEST_ID, id).run(() -> handle(req)); // REQUEST_ID.get() insideA ThreadLocal set on the caller does not appear in the tasks you submit to an executor,
and on millions of virtual threads its mutable per-thread copies leak memory — that symptom is
exactly what ScopedValue fixes. Deep dive (scopes, joiners, pinning diagnosis, when platform
threads still win) -> references/concurrency.md.
Use stream().toList() (Java 16+, immutable) for the common case; Collectors.groupingBy
and teeing cover most aggregation:
Map<Currency, Long> totalByCcy = payments.stream()
.collect(Collectors.groupingBy(Payment::currency,
Collectors.summingLong(p -> p.amount().cents())));Optional discipline: chain map/filter/orElseGet/orElseThrow; never .get() without a
prior isPresent, never an Optional field. Do not stream when a loop is clearer — a
forEach with side-effects, an early break/return, or index-coupled logic is a loop.
Full Collector catalog, custom collectors, mapMulti, Gatherers (Java 24+), and parallel-stream
caveats -> references/streams.md.
Pin the language level with the compiler plugin's <release>, run JUnit 5 via Surefire.
Maven 4 is not yet GA (4.0.0-rc-5, Nov 2025) — use Maven 3.9.x for production:
<properties><maven.compiler.release>25</maven.compiler.release></properties>
<build><plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration><release>25</release>
<compilerArgs><arg>-Xlint:all</arg><arg>-Werror</arg></compilerArgs></configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId>
<version>3.5.2</version>
</plugin>
</plugins></build>Gradle 9.x (current 9.5.1, requires Java 17+ to run, prefers the configuration cache) uses a toolchain block so the build picks the right JDK regardless of the runner's default:
plugins { java }
java { toolchain { languageVersion = JavaLanguageVersion.of(25) } }
tasks.test { useJUnitPlatform() }Full pom.xml / build.gradle.kts skeletons, multi-module, preview-flag wiring, JUnit 5 +
AssertJ + Mockito, jlink/jpackage -> references/builds.md.
null. Return Optional<T> for a maybe-value, an empty collection for "none".AutoCloseable; do not write a finally { close() } by hand.throw new ServiceException("loading user " + id, cause) — so the
stack trace keeps the root. Swallowing (catch (Exception e) {}) destroys the evidence.extends Exception) for recoverable, expected conditions
the caller must handle; unchecked (extends RuntimeException) for programming bugs / invariant
violations. Do not wrap everything in a checked exception "to be safe" — it just gets rethrown.| Rationalization | Reality / Do instead |
|---|---|
| "I'll add setters to the record for convenience" | Then it isn't immutable. Build a new instance; validate in the compact constructor. |
| "instanceof+cast is fine, it's only three cases" | No exhaustiveness; case four silently falls through. Sealed + switch. |
| "pool the virtual threads to be safe" | Pooling re-adds the limit Loom removes. One virtual thread per task. |
| "ThreadLocal carries my request context" | It doesn't cross submit() and leaks on millions of vthreads. ScopedValue. |
| "Optional field so callers handle absence" | Optional is a return type. A field is null-of-null; use the value or a default. |
"raw List is shorter than List<Payment>" | Raw types disable generics checks. Always parametrize. |
| "catch and ignore, it can't happen here" | Then assert it; a swallowed exception erases the bug. Log + rethrow or handle. |
| "fmt the id into the SQL string, it's trusted" | Trust nothing at the boundary. PreparedStatement with ?. |
| "wrap it in a checked exception to force handling" | Most callers just rethrow. Unchecked for bugs; checked only when recovery is real. |
"new Thread(r).start() per request" | On platform threads that's a few thousand max. Virtual-thread-per-task executor. |
| "default branch keeps the switch safe" | A default hides the new case. Omit it on a sealed type so it won't compile. |
| "warnings are just noise" | unchecked/deprecation are deferred bugs. -Xlint:all -Werror. |
| Task | Idiom / command |
|---|---|
| Build + test (Maven) | ./mvnw -q verify (or mvn -q verify) |
| Build + test (Gradle) | ./gradlew check |
| Data carrier | record Money(long cents, Currency ccy) { Money { ... } } |
| Closed case set | sealed interface R permits A, B {} + record A(...) implements R {} |
| Exhaustive match | switch (r) { case A(var x) -> ...; case B b -> ...; } (no default) |
| Concurrent blocking I/O | try (var e = Executors.newVirtualThreadPerTaskExecutor()) { ... } |
| Context across threads | ScopedValue.where(KEY, val).run(() -> ...) |
| Run a single source file | java App.java (compact source + instance main, JEP 512, final in 25) |
| Local gate | ./scripts/verify.sh (run in your project root) |
When this skill runs in a project with a 02-DOCS/ layer (the
harness Karpathy wiki), record this project's Java decisions there
and index them from the root CLAUDE.md, so the next agent inherits them instead of re-deriving.
02-DOCS/wiki/stack/java.md, indexed in 02-DOCS/wiki/index.md (the
Knowledge map index; root CLAUDE.md points to it).02-DOCS/wiki/index.md (the Knowledge map; root CLAUDE.md keeps only a
short pointer to it).Updated date) in the same change.No 02-DOCS/ layer? Skip silently (optionally suggest harness). Technical conventions are
recorded, not gated — never block the task on this.
Sibling skills (link only those present under skills/):
spring-boot - the Spring framework surface (controllers, beans, autoconfiguration); this
skill is the plain-JDK/language layer underneath it.secure-coding - threat modeling and language-agnostic
authz/abuse/OWASP review (this skill keeps the Java-specific controls).deployment - Docker, CI, and shipping (this skill keeps only the
jlink/jpackage note and base-image choice).postgresdb - SQL schema/index/query tuning (this skill covers JDBC
parametrization from the Java side only).harness - the 02-DOCS/ workspace wiki where per-project Java
conventions are recorded (see "Project grounding").Local references (read when):
references/concurrency.md - virtual-thread internals, structured concurrency, ScopedValue,
pinning diagnosis, when platform threads still win.references/streams.md - full Collectors catalog, custom collectors, Gatherers, parallel-stream
caveats, Stream-vs-loop decision table.references/builds.md - full pom.xml + build.gradle.kts skeletons, multi-module, preview flags,
JUnit 5 + AssertJ + Mockito, jlink/jpackage, dependency hygiene.© ericrisco, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 6 other files (scripts, references) in skills/java of ericrisco/rsc-harness.
Open the folder on GitHubat commit 92fde8f
Java 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.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Java this skillericrisco/rsc-harness | 156 | — | ~4.6k | Automated safety check: Pass | MIT | |
| Groovy 5 Developer Guideapache/grails-core | 2.9k | — | ~3k | Automated safety check: Pass | Apache-2.0 | |
| Java Idiomsirahardianto/awesome-agv | 157 | — | ~1.5k | Automated safety check: Pass | MIT | |
| Java Rulessoftspark/ai-toolkit | 179 | — | ~3.1k | Automated safety check: Pass | Apache-2.0 | |
| Progensivaprasadreddy/sivalabs-agent-skills | 187 | — | ~2.7k | Automated safety check: Notes | MIT | |
| Starter Domain Revieweraxelixlabs/axelix | 147 | — | ~3.3k | Automated safety check: Pass | LGPL-3.0 |
apache/grails-core
Guidance for Groovy 5 work in Grails projects: syntax, closures, traits, DSLs, metaprogramming, Spock tests, static compilation and Java 21 integration.
irahardianto/awesome-agv
Modern Java (17/21+ LTS) idioms: records, sealed classes, pattern matching switch, Optional hygiene, streams, and JUnit 5 testing.
softspark/ai-toolkit
Java coding rules: style, patterns, security, testing. An agent skill from softspark/ai-toolkit.
sivaprasadreddy/sivalabs-agent-skills
A skill your agent uses when the user wants to create/generate/scaffold a new Spring Boot project (Maven or Gradle, REST API / Web App / Spring Boot + Angular full stack).
axelixlabs/axelix
Reviews changes in sbs/starter-domain for technology-agnostic domain logic, forbidden production dependencies, and Java 11+ compatibility.
ArabelaTso/Skills-4-SE
Automatically migrate Spring MVC applications to Spring Boot.
ericrisco/rsc-harness
A skill your agent uses when designing or analyzing a controlled experiment — falsifiable hypothesis, sample size from an MDE, reading significance/CI/power, CUPED, or rescuing tests that won't go…
ericrisco/rsc-harness
A skill your agent uses when making a web UI conform to WCAG 2.2 Level AA — axe-core or Lighthouse a11y violations, keyboard operability, focus management, ARIA roles/names/live regions, contrast…
ericrisco/rsc-harness
A skill your agent uses when running or fixing paid acquisition on Google or Meta — campaign structure (Performance Max, Demand Gen, Search, Advantage+), platform-fit creative, budget/scaling rules…
ericrisco/rsc-harness
A skill your agent uses when measuring whether an LLM or agent system actually got better and gating merges on it: golden sets, fixing an inflated LLM-as-judge, scoring RAG (faithfulness, contextual…
ericrisco/rsc-harness
A skill your agent uses when a creative goal must become a finished media file: pick and order generative-media models per modality — AI voiceover, image-to-video clips, score — then glue them with…
ericrisco/rsc-harness
A skill your agent uses when instrumenting product or web analytics — GA4/PostHog SDK wiring, event taxonomy, funnels, double-counted events, consent gating, PII scrubbing.
Works with
Categories
A skill your agent uses when writing, reviewing or refactoring modern Java (21+, 25 LTS) — records and sealed interfaces as algebraic data types, exhaustive pattern-matching switch over instanceof…. Java is an agent skill from ericrisco/rsc-harness. Use when writing, reviewing or refactoring modern Java (21+, 25 LTS) — records and sealed interfaces as algebraic data types, exhaustive pattern-matching switch over instanceof ladders, virtual-thread concurrency, structured concurrency and ScopedValue replacing ThreadLocal, Stream and Optional pipelines, compact-constructor validation, parametrized JDBC, and the Maven/Gradle build surface.
Java fits situations like: refactoring modern Java (21+; 25 LTS) — records and sealed interfaces as algebraic data types; exhaustive pattern-matching switch over instanceof ladders; virtual-thread concurrency.
Run `npx skills add ericrisco/rsc-harness --skill java -a claude-code`. Or copy the skill folder (skills/java in ericrisco/rsc-harness) into .claude/skills/java in your project. Claude Code loads it when a task matches its description.
Run `npx skills add ericrisco/rsc-harness --skill java -a codex`. Or copy the skill folder (skills/java in ericrisco/rsc-harness) into .agents/skills/java in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add ericrisco/rsc-harness --skill java -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/java, .gemini/skills/java, .github/skills/java and .opencode/skills/java in your project.
Going by SKILL.md and its folder, Java needs a shell for the scripts in its folder and the command-line tools its instructions call (mvn and java). Our summary lists: A Bash shell.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
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.
Java is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 4.6k tokens (SKILL.md is roughly 18k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 3.6k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Java: Groovy 5 Developer Guide (apache/grails-core, 2.9k stars), Java Idioms (irahardianto/awesome-agv, 157 stars), Java Rules (softspark/ai-toolkit, 179 stars) and Progen (sivaprasadreddy/sivalabs-agent-skills, 187 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
ericrisco (a GitHub user) maintains it in ericrisco/rsc-harness, which has 156 GitHub stars. The repository holds 229 skills in this directory. The repository was last updated on October 6, 2026.
Source: ericrisco/rsc-harness on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.