Copilot commented on code in PR #15977: URL: https://github.com/apache/grails-core/pull/15977#discussion_r3565595838
########## grails-gradle/AGENTS.md: ########## @@ -0,0 +1,75 @@ +<!-- +SPDX-License-Identifier: Apache-2.0 + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +--> + +# Agent Guide for grails-gradle + +> **IMPORTANT**: `grails-gradle` is a **hybrid** subproject — unlike [`grails-forge`](../grails-forge/AGENTS.md), +> it is NOT independent of the root build's dependency management. It has its own `settings.gradle` +> and its own test harness (Gradle TestKit, not Spock/GORM mocking), but it deliberately shares +> `dependencies.gradle`/`gradle.properties` with the repo root via `SharedPropertyPlugin`. Read this +> file for what's actually different; root [`AGENTS.md`](../AGENTS.md) still governs PR/branch/review +> conventions, dependency *versions*, and repository-wide policy. + +## Quick Reference + +Run from inside `grails-gradle/`, not the repo root: + +```bash +./gradlew build --continue --stacktrace +./gradlew build -PskipTests -PskipCodeStyle +./gradlew validateDependencyVersions --continue --stacktrace +./gradlew aggregateStyleViolations --continue +./gradlew jacocoAggregateReport --continue --stacktrace -PskipCodeStyle +``` + +## Critical Rules (corrected for this subproject) + +Checked against actual source, not assumed: + +1. **Use plain `@CompileStatic`, NOT `@GrailsCompileStatic`.** This inverts the root rule. Grails-gradle is build tooling — Gradle plugins, not Grails artefacts. Every `@GrailsCompileStatic` string in this module's own source is javadoc describing the feature the plugin implements *for a consumer app*, never a real annotation here. Confirmed: 47 files use plain `@CompileStatic`, zero use `@GrailsCompileStatic` as an actual annotation. +2. **`javax.*` is legitimate here, not stale migration debt.** `javax.inject.Inject` (JSR-330, unrelated to Jakarta EE) and `javax.xml.*` (permanent JDK APIs) both appear correctly. Don't "fix" these to `jakarta.*` — they were never part of that migration. The `jakarta.*` references that do exist here are about configuring a *downstream Grails application's* dependencies, not this module's own runtime. +3. **Dependency versions are NOT independent — this is the opposite of `grails-forge`.** `grails-gradle/gradle.properties` defines no version properties at all, only Gradle daemon/cache flags. Versions come from root's `dependencies.gradle` (via `allprojects { apply from: '../dependencies.gradle' }`) and root's `gradle.properties` (via `SharedPropertyPlugin`, which walks up the directory tree loading every `gradle.properties` it finds). Don't hardcode a version here; don't assume `validateDependencyVersions` doesn't apply — it does, just run separately (see Quick Reference). +4. **Module source compiles against Gradle's embedded Groovy 4.0.32, not root's Groovy 5.0.x.** This is a real, structural split (`groovy-gradle-plugin`), not a version-drift bug. Don't "upgrade" it to match root — it can't, by design, since it compiles inside Gradle's own plugin classpath. Review Comment: This hard-codes Gradle's embedded Groovy patch version (4.0.32), but the codebase itself documents this only as “Gradle's embedded Groovy” / `gradle-groovy.version` (e.g. `gradle/docs-config.gradle`). Hardcoding the patch version here will drift the next time the wrapper is updated, and there isn't a source-of-truth reference in this doc. ########## AGENTS.md: ########## @@ -58,27 +58,15 @@ export GRADLE_OPTS="-Xms2G -Xmx5G" ## Available Skills -> **AI AGENTS - MANDATORY**: Before writing or modifying any code, you **MUST** read the relevant skill file(s) below. Do not write Groovy/Grails code without first loading these instructions: -> - Writing Grails code → Read `.agents/skills/grails-developer/SKILL.md` -> - Writing Groovy code → Read `.agents/skills/groovy-developer/SKILL.md` -> - Writing Java code → Read `.agents/skills/java-developer/SKILL.md` -> - Upgrading applications to Grails 8 → Read `.agents/skills/grails-8-upgrade/SKILL.md` -> - Writing Hibernate code → Read `.agents/skills/hibernate-developer/SKILL.md` -> - Fixing style/analysis violations → Read `.agents/skills/violation-fixer/SKILL.md` -> - Fixing broken test → Read `.agents/skills/test-fixer/SKILL.md` -> - Indexing code -> Read `.agents/skills/codebase-memory/SKILL.md` +> **AI AGENTS - MANDATORY**: Before writing or modifying any code, list `.agents/skills/*/SKILL.md`, read each one's front-matter `description`, and load the full file for any skill whose description matches the task at hand. Do not write Groovy/Grails/Java code without first loading the skill(s) that apply. > -> Use your file reading capability to load the skill content before proceeding with any code changes. - -| Skill | Path | Use For | -|-------|------|---------| -| **grails-developer** | `.agents/skills/grails-developer/SKILL.md` | Current Grails apps, GORM, controllers, views | -| **groovy-developer** | `.agents/skills/groovy-developer/SKILL.md` | Groovy 5 syntax, closures, DSLs, Spock | -| **grails-8-upgrade** | `.agents/skills/grails-8-upgrade/SKILL.md` | Upgrading Grails applications from 7.x to 8 | -| **java-developer** | `.agents/skills/java-developer/SKILL.md` | Java 21 features, Groovy interop | -| **hibernate-developer** | `.agents/skills/hibernate-developer/SKILL.md` | Hibernate 7 mapping, binders, generators | -| **violation-fixer** | `.agents/skills/violation-fixer/SKILL.md` | Fix style/analysis violations (CodeNarc, Checkstyle, PMD, SpotBugs) | -| **test-fixer** | `.agents/skills/test-fixer/SKILL.md` | Aggregate and fix test failures | +> ```bash +> for f in .agents/skills/*/SKILL.md; do awk -F': *' '/^description:/{d=$2} /^paths:/{p=$2} END{print FILENAME": "d (p?" [paths: "p"]":"")}' "$f"; done +> ``` +> +> Some skills also declare an optional front-matter `paths:` glob (e.g. `paths: grails-data-hibernate7/**`) scoping them to a specific module — if the file(s) you're touching match a skill's `paths`, load it regardless of whether you'd have matched it on description alone. `paths` is a stronger, structural signal than prose; not every skill needs one (repo-wide skills like `grails-developer`/`groovy-developer` intentionally have none). +> +> The directory is the source of truth, not a list in this file — a hardcoded skill index here would drift the moment a skill is added, renamed, or removed. Each `SKILL.md`'s front-matter (`name`, `description`, `paths`, `compatibility`) is what makes it discoverable to any agent, per the Agent Skills Specification. Review Comment: The text here treats `compatibility` and `paths` as if they are always present, and also gives `grails-developer` as an example of a repo-wide skill with no `paths`. In the current skill set, only a subset of skills declare `compatibility`, and `grails-developer` now has `paths: grails-test-examples/**`, so this paragraph is internally inconsistent and can mislead readers running discovery based on these fields. ########## .agents/skills/diff-coverage-check/SKILL.md: ########## @@ -0,0 +1,140 @@ +<!-- +SPDX-License-Identifier: Apache-2.0 + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +--> +--- +name: diff-coverage-check +description: Computes real diff coverage (coverage of only the lines you actually changed, not whole-file coverage) entirely locally, without CI or Codecov — by running each affected module's own tests and cross-referencing its JaCoCo XML against git diff. Use before committing, or when asked "is my change covered" / "check coverage on the files I touched" / "diff coverage". A change often spans several modules; run this per module. +license: Apache-2.0 +compatibility: opencode, claude, grok, gemini, copilot, cursor, windsurf +metadata: + audience: maintainers + frameworks: grails +--- Review Comment: This SKILL file puts the YAML front-matter after a license comment block. Since the intent is cross-agent portability, it’s safer to follow the repo’s existing convention where `---` front-matter is at the very top of the file (so strict front-matter parsers can find it). ########## .agents/skills/micronaut-developer/SKILL.md: ########## @@ -0,0 +1,242 @@ +<!-- +SPDX-License-Identifier: Apache-2.0 + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +--> +--- +name: micronaut-developer +description: Guide for working in grails-forge (grails-forge-core, grails-forge-api, grails-forge-cli, grails-forge-web-netty) — a Micronaut application, not a Grails one. Covers Micronaut DI/bean patterns, HTTP controllers, two distinct Spock testing patterns (MicronautTest for HTTP controllers, ApplicationContextSpec for Feature classes), Picocli CLI commands, Rocker templating, and the Feature extension-point system. Use this instead of grails-developer/hibernate-developer when changing code under grails-forge/. +license: Apache-2.0 +compatibility: opencode, claude, grok, gemini, copilot, cursor, windsurf +paths: grails-forge/** +metadata: + audience: maintainers + frameworks: micronaut +--- Review Comment: This SKILL file places YAML front-matter after a license comment block. Many front-matter parsers expect `---` to be the first line of the file; other skills here (e.g. `violation-fixer`) already follow that convention. Moving the license block below the YAML front-matter would improve portability across agents/tools. ########## .agents/skills/migration-scoping/SKILL.md: ########## @@ -0,0 +1,87 @@ +<!-- +SPDX-License-Identifier: Apache-2.0 + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +--> +--- +name: migration-scoping +description: Before starting any refactor/rewrite/optimization-shaped task on a core subsystem (GORM registry, datastore internals, binder/mapping layer, etc.), classify it as mechanical (bounded, safe to just do) or architectural (a project, not a patch) and check whether another local or remote branch already attempted it. Use this before writing code for anything that sounds like "improve/refactor/optimize/rewrite X", not for ordinary bug fixes or additive features. +license: Apache-2.0 +compatibility: opencode, claude, grok, gemini, copilot, cursor, windsurf +metadata: + audience: maintainers + frameworks: grails +--- Review Comment: This SKILL file places the YAML front-matter after a license comment block. Most skills in this repo start with `---` front-matter at the top of the file, which is the most interoperable convention for tools that parse YAML front-matter. Consider moving the license block below the front-matter for consistency and portability. ########## .agents/skills/worktree-hygiene/SKILL.md: ########## @@ -0,0 +1,99 @@ +<!-- +SPDX-License-Identifier: Apache-2.0 + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +--> +--- +name: worktree-hygiene +description: Reports stale or orphaned git worktrees under .claude/worktrees/ (the agent-managed worktree directory) by checking each worktree's branch against its GitHub PR state and merge-into-default-branch status, not commit age. Use at the start of a session in this repo when .claude/worktrees/ has accumulated entries, or when asked to clean up worktrees or check branch hygiene. Report-only — never deletes without explicit confirmation, and never touches worktrees outside .claude/worktrees/. +license: Apache-2.0 +compatibility: opencode, claude, grok, gemini, copilot, cursor, windsurf +paths: .claude/worktrees/** +metadata: + audience: maintainers + frameworks: grails +--- Review Comment: This SKILL file puts the YAML front-matter after a license comment block. Most other skills in this repo put the `---` front-matter at the start of the file (e.g. `violation-fixer`, `test-fixer`), which is the more interoperable convention for tools that parse “front-matter at file start”. To maximize cross-agent portability, consider moving the license comment block below the YAML front-matter. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
