Improve agent guidance: skill discovery, module skills, review workflow#15977
Improve agent guidance: skill discovery, module skills, review workflow#15977borinquenkid wants to merge 20 commits into
Conversation
The mandatory skill-reading list pointed agents at .agents/skills/codebase-memory/SKILL.md, which was never created and isn't listed in the skills table. Drop the reference.
Agents should run an adversarial review pass (e.g. /code-review or a fresh-context agent) against AGENTS.md's rules and the change's own logic before requesting human review, so scarce reviewer time goes to judgment calls rather than mechanical rule violations. Supplements, does not replace, the human review gate. Also fixes the pre-existing duplicate "6." numbering in this list.
PR chains (e.g. the Neo4j GormRegistry migration: apache#15779-apache#15817, consolidated into apache#15972) were used to keep diffs reviewable, but GitHub's Copilot reviewer silently skips PRs over ~300 files - apache#15972's consolidated diff got no automated review, and the integration between its sub-PRs was never itself reviewed. Since adversarial self-review is now mandatory on every PR regardless of size, splitting for reviewability no longer buys coverage, only coordination overhead. Default to one PR per feature/migration; split only for independently revertable/mergeable units.
The task->skill bullet list and the skills table both had to be kept in sync with .agents/skills/ by hand, and had already drifted twice: a reference to codebase-memory/SKILL.md that never existed, and mono-repo-integration/SKILL.md existing on disk but referenced nowhere in this file. Point agents at the directory instead: enumerate .agents/skills/*/ and match on each SKILL.md's own front-matter description. Adding, renaming, or removing a skill no longer requires touching AGENTS.md, and this works for any agent that reads front-matter, not just ones that follow a Claude-specific list.
.claude/worktrees/ accumulates agent-created worktrees with no documented cleanup process - found 3 stale ones from a 2026-06-25 workflow run still present today, plus a since-removed one for a branch whose PR had long since merged. Age/idle time is the wrong staleness signal here: this repo's PR chains go quiet between review rounds without being abandoned, so a worktree is valid as long as its branch has a live remote or open PR. The skill classifies each worktree under .claude/worktrees/ by GitHub PR state and merge-into-default-branch status instead, checks for uncommitted work before recommending anything, and never touches worktrees outside .claude/worktrees/ or removes anything without explicit confirmation. No AGENTS.md edit needed to make this discoverable - it surfaces through the directory-based skill discovery added in the previous commit.
grails-forge is a Micronaut application (project generator behind start.grails.org), not a Grails app, but nothing in .agents/skills/ covered its actual idioms - DI, HTTP controllers, MicronautTest+Spock, Picocli CLI, Rocker templating, or the Feature extension-point system (82 files use @singleton, 32 @introspected, 20 @Inject, 9 @controller, 8 @MicronautTest; zero skill coverage for any of it before this). Root AGENTS.md is also actively wrong for this subproject in at least one place: its "@GrailsCompileStatic, not @CompileStatic" rule is inverted here (0 @GrailsCompileStatic usages, 8 correct @CompileStatic ones), since grails-forge has no Grails artefacts. This skill documents where root rules do and don't transfer, verified against actual source rather than assumed. Grounds the earlier context-management finding: an agent working in grails-forge paid the full cost of root AGENTS.md's GORM/Hibernate/ artefact content with no corresponding Micronaut guidance to fill the actual gap. This is the prerequisite for a later scoped grails-forge/AGENTS.md.
Root AGENTS.md (2073 words) was loaded in full for every grails-forge task despite being ~0% applicable: grails-forge is a Micronaut application (the generator behind start.grails.org), not a Grails app, and has its own settings.gradle/build. At least one root rule is actively wrong there - "@GrailsCompileStatic, not @CompileStatic" is inverted, since grails-forge correctly uses plain @CompileStatic (8 files, 0 @GrailsCompileStatic). Adds grails-forge/AGENTS.md (+ CLAUDE.md symlink, matching root's agent-neutral pattern) scoped to what's actually true here: corrected critical rules, this subproject's own build/test/style commands (verified against its CI job, .github/workflows/codestyle.yml's check_forge_projects), its module table, and a pointer to the micronaut-developer skill for code patterns. PR/branch/review/security policy is explicitly not repeated, to avoid drift from the root copy. Root AGENTS.md's Project Structure table now points to the nested file so an agent starting at repo root knows it exists.
The root CLAUDE.md -> AGENTS.md symlink exists because some tools hard-require that exact filename; replicating it in every subproject with a nested AGENTS.md doesn't scale and shouldn't be necessary if AGENTS.md is discovered natively in nested directories. About to test that assumption directly rather than assume it.
An A/B test (agent working in grails-forge with vs without the scoped guidance, identical prompt) surfaced a real gap: this skill documented @MicronautTest+Spock for HTTP controllers but had nothing on ApplicationContextSpec, the different, lighter-weight pattern actually used to test Feature classes (no server startup, just a shared ApplicationContext). Both test runs had to reverse-engineer it from MongoSyncSpec.groovy; the "after" agent's own report even claimed this was "the pattern the skill describes" - it wasn't, grep confirmed zero hits for ApplicationContextSpec/CommandOutputFixture/BuildBuilder before this commit. Adds the pattern grounded in the real source (ApplicationContextSpec, CommandOutputFixture, BuildBuilder, MongoSyncSpec) and clarifies the two testing patterns aren't interchangeable - MicronautTest is for grails-forge-api controllers, ApplicationContextSpec is for grails-forge-core Feature classes.
Answers a real question: the repo has Codecov integrated (codecov.yml, coverage.yml), but nothing said whether that data is visible without a CI round-trip. Checked the actual task sources (GrailsJacocoPlugin, GrailsViolationAggregationPlugin in build-logic): - aggregateJacocoCoverage -> JACOCO_COVERAGE.md (already used by violation-fixer, just never connected to "Codecov" by name) - jacocoAggregateReport -> the exact XML CI uploads to Codecov Both are ordinary local Gradle tasks, no token or network needed. What's actually CI-only is Codecov's diff-against-base-branch comparison, PR comment, and dashboard - and per codecov.yml both status checks are informational: true, so they don't block merge today regardless. Also notes coverage.yml only wires up grails-core and grails-gradle - grails-forge and build-logic have no Codecov data at all, in CI or locally.
Diff coverage (coverage of only the lines you actually changed) is what Codecov computes in CI, but the underlying data - JaCoCo line hit/miss counters - is already produced locally by an ordinary :module:test run (GrailsJacocoPlugin, finalizedBy jacocoTestReport). The only missing piece was cross-referencing it against git diff. Considered wiring in form-com/diff-coverage-gradle (a real, maintained plugin for exactly this) but that's a build.gradle change with its own review burden and a new external dependency - a different risk category from the rest of this branch. This skill gets the same signal with zero build changes: run the affected module's tests, then cross-reference its existing JaCoCo XML against git diff hunks. The script and procedure are verified against real data in this repo, not assumed from JaCoCo's schema docs: - Confirmed module derivation must walk up to the nearest build.gradle, not assume module = first path segment (grails-gsp/grails-taglib and grails-gsp/core are separate modules nested two levels deep). - Confirmed some .java files live under src/main/groovy/, not src/main/java/ (grails-i18n/.../AvailableLocaleResolver.java). - Found and documented a real gotcha: a stale JaCoCo report doesn't error, it silently cross-references the wrong code against shifted line numbers - must regenerate after every edit. - Verified end-to-end against a real mixed-coverage diff in grails-i18n (one covered line, one genuinely uncovered dead branch), confirming the script correctly identifies exactly which changed line needs a test.
Two problems the previous commit left behind: 1. The Coverage section still claimed diff-coverage "genuinely requires CI/Codecov's cloud service (not reproducible locally)" - wrong as of the diff-coverage-check skill added in the prior commit. Corrected. 2. The skill was only discoverable (an agent might find it via the mandatory pre-code skill scan, or if explicitly asked about coverage), never required. PR checklist step 5 still just said "ensure coverage" with no mechanism to check it. Now points directly at the skill.
Same gap as the previous commit, mirrored: test-fixer already existed
for diagnosing test failures, but PR checklist step 2 ("Run tests")
never pointed to it, and neither skill referenced the other despite
being sequential steps in the same workflow (run tests -> fix
failures via test-fixer -> once passing, check coverage via
diff-coverage-check). A failing test run also produces an untrustworthy
JaCoCo report, so the ordering matters, not just the pointer.
hibernate-developer's own description already said "use this when changing code under grails-data-hibernate7" - but that's prose an agent has to interpret, not a structural signal, so a task could plausibly load it (or fail to) based on how well the description matched the agent's phrasing of its own task. Adds an optional paths: glob to front-matter (Agent Skills Specification allows arbitrary metadata) and teaches the directory- based discovery instruction in AGENTS.md to check it: if the file(s) being touched match a skill's paths, load it regardless of whether the task description alone would have matched. This is deliberately generic, not a hibernate-only fix - it's the same mechanism fix apache#4 already established (directory is the source of truth, not a hand-maintained list), just extended to path-scope in addition to semantic description matching. Applied to all three currently path-scoped skills to prove it generalizes: hibernate-developer (grails-data-hibernate7/**), micronaut-developer (grails-forge/**), worktree-hygiene (.claude/worktrees/**). Repo-wide skills (grails-developer, groovy-developer, etc.) intentionally have no paths: field.
Same treatment as hibernate-developer: grails-data-mongodb is part of the root aggregate build (no own settings.gradle), so root AGENTS.md's rules apply unmodified - it just needed deeper technical guidance layered on top. Grounded in real source across all 8 subprojects (core, bson, ext, boot-plugin, spring-data, grails-plugin, gson-templates, docs): mapping/codec pipeline (MongoMappingContext, BsonPersistentEntityCodec/ PersistentEntityCodec), confirmed-implemented concepts (embedded docs, GeoJSON, TTL indexes via collMod reconciliation, DBRef vs embedding, multi-tenancy), and one real trap verified by absence-of-evidence: the `shard "name"` mapping keyword is a documented no-op - zero shardCollection calls anywhere in core/src/main, it silently falls through to Entity's generic methodMissing catch-all. Testing pattern confirmed: GrailsDataTckSpec<GrailsDataMongoTckManager> (111+ specs, spot-checked), real MongoDB via Testcontainers (mongo:7.0.19, spot-checked), core module's tests deliberately serial (maxParallelForks=1) - don't casually "fix" that. Includes paths: grails-data-mongodb/** front-matter, consistent with the structural discovery mechanism added for hibernate-developer.
Two more independent sub-builds with zero agent guidance, found the same way grails-forge was: own settings.gradle, own test harness, but neither fits the grails-forge template cleanly - both are hybrids that share root's dependencies.gradle/gradle.properties (via a purpose-built SharedPropertyPlugin that walks up the directory tree, since "Gradle can't share properties across buildSrc or composite projects") while diverging on everything else: Groovy 4.0.32 (Gradle's embedded version) instead of root's 5.0.x, plain @CompileStatic never @GrailsCompileStatic (verified: 0 real annotation usages in either module, only javadoc mentions), and Gradle TestKit (GradleRunner) instead of Spock/GORM-mock testing. grails-gradle: the actual Plugin<Project> classes an app's build.gradle applies (org.apache.grails.gradle.grails-app etc.) - catalogued all 12 plugin-ID-to-class mappings, the GradleSpecification TestKit base class, and the model/common/plugins/tasks/bom module split (spock excluded transitively via grails-gradle-model, verified). build-logic: the convention-plugin layer every other build in this repo (root, grails-forge, grails-gradle) consumes transitively via includeBuild - implements GrailsJacocoPlugin, GrailsViolationAggregationPlugin, and 11 others that other skills already cited by name without documentation. Catalogued all 13 plugins with what each actually configures, both testing patterns (TestKit for task-graph behavior, ProjectBuilder for pure logic), and flagged that only 4 of 13 plugins have dedicated specs. No CI job of its own is expected here, not a dormancy signal like grails-data-neo4j - confirmed live via a substantive commit (GROOVY-12146 workaround) the day before this was written, not just "exercised transitively" hand-waving. Root AGENTS.md's Project Structure table now points to both nested files, same pattern as grails-forge.
~50 real functional test apps live under grails-test-examples/<name>/ (hibernate7, mongodb, micronaut, spring-security, geb, etc.) - each a real, standalone Grails app exercising a specific framework feature - and nothing pointed grails-developer (the app-development skill) at them. Real risk: several share a name with a framework-internals module (grails-test-examples/hibernate7/ vs grails-data-hibernate7/), so without an explicit signal an agent could reach for the wrong skill's mental model in the wrong place. Adds paths: grails-test-examples/** (additive, not restrictive - this is still a repo-wide skill per its own description) plus a short section grounding the skill's generic app-layout guidance in this repo's actual location, and the real -PonlyFunctionalTests/ -PskipFunctionalTests gating flags (verified wired into 9 gradle config files, not just README claims).
The July 6 OpenAI Codex-plugin insight this rule was originally based on is specifically about cross-model review - a different vendor's model catches what the authoring model is blind to. But mandating that excludes any contributor without a second AI subscription, which isn't a realistic bar for most people working on this repo. The actual mechanism that does the work is the adversarial framing itself (explicitly instructed to refute, not confirm) combined with a genuinely fresh context (no memory of writing the change) - neither requires a second vendor. Reframed the rule around what every contributor actually has access to, with cross-model review named as the stronger upgrade when available, not the baseline requirement.
Closes a gap from earlier in this branch's work: we found and cleaned up real branch sprawl from the Hibernate7/GORM registry migration (four branches independently attempting the same architectural work - 8.0.x-hibernate7, gorm-registry-refactor, gorm-scaling-clean, fix/gorm-api-registration-scaling), but never turned that into guidance for the next time it happens. This closes that loop. Two-step process: classify a task as mechanical (bounded, just do it) or architectural (a project, not a patch - check prior art first) - then, for architectural work, check local/remote branches for prior attempts using git merge-base --is-ancestor, not branch names or commit dates. The real case is the worked example, including its counterintuitive findings: the branch that actually won had an OLDER last-commit date than the dead ends, and the largest diff (456 files) was the most thoroughly abandoned one - both direct warnings against the naive heuristics (recency, size) an agent might otherwise use. Cross-references worktree-hygiene's PR-state check so "orphaned" isn't confused with "in review."
There was a problem hiding this comment.
Pull request overview
This PR updates the repository’s agent-facing documentation and skill packages to make “agent guidance” discoverable via .agents/skills/*/SKILL.md front-matter, and adds subproject-scoped AGENTS.md guides for hybrid/independent builds (grails-gradle, grails-forge, build-logic).
Changes:
- Replaces the root
AGENTS.mdhardcoded skill index with directory-based discovery, adding guidance for optionalpaths:-scoped skills and local coverage workflows. - Adds subproject-level
AGENTS.mdfiles documenting howgrails-forge,grails-gradle, andbuild-logicdiffer from root assumptions. - Adds several new module/scenario skills (
mongodb-developer,micronaut-developer,build-logic-developer,grails-gradle-developer,diff-coverage-check,worktree-hygiene,migration-scoping) and augments existing skills withpaths:.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
AGENTS.md |
Switches to directory-based skill discovery; adds coverage + PR sizing guidance. |
build-logic/AGENTS.md |
Adds build-logic-specific agent guide for composite-build conventions. |
grails-forge/AGENTS.md |
Adds Micronaut-specific agent guide for the forge subproject. |
grails-gradle/AGENTS.md |
Adds gradle-plugin subproject agent guide and build/test commands. |
.agents/skills/build-logic-developer/SKILL.md |
New skill documenting build-logic convention plugins + testing patterns. |
.agents/skills/diff-coverage-check/SKILL.md |
New skill to compute local diff coverage from JaCoCo XML + git diff. |
.agents/skills/grails-developer/SKILL.md |
Extends grails-developer to cover grails-test-examples/** via paths:. |
.agents/skills/grails-gradle-developer/SKILL.md |
New skill for grails-gradle/** plugin development + TestKit patterns. |
.agents/skills/hibernate-developer/SKILL.md |
Adds paths: grails-data-hibernate7/** to scope discovery. |
.agents/skills/migration-scoping/SKILL.md |
New pre-work triage skill for “architectural vs mechanical” migrations. |
.agents/skills/micronaut-developer/SKILL.md |
New skill for Micronaut patterns used in grails-forge/**. |
.agents/skills/mongodb-developer/SKILL.md |
New skill for grails-data-mongodb/** internals + Testcontainers test patterns. |
.agents/skills/test-fixer/SKILL.md |
Adds a note distinguishing “tests pass” from “diff is covered”. |
.agents/skills/worktree-hygiene/SKILL.md |
New skill to classify/remove stale .claude/worktrees/** entries using PR state. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| > 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. |
| 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. |
| <!-- | ||
| 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 | ||
| --- |
| <!-- | ||
| 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 | ||
| --- |
| <!-- | ||
| 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 | ||
| --- |
| <!-- | ||
| 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 | ||
| --- |
- Fix stale AGENTS.md example: grails-developer now has paths:, use groovy-developer/java-developer as the no-paths example instead; clarify compatibility: is optional/unverified-if-absent. - Stop hardcoding Gradle's embedded Groovy patch version in grails-gradle/AGENTS.md; point at gradle-wrapper.properties instead so it doesn't drift on wrapper bumps. - Move front-matter above the license comment block in four new SKILL.md files (worktree-hygiene, migration-scoping, micronaut-developer, diff-coverage-check) to match the repo's existing convention (front-matter first, e.g. violation-fixer). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## 8.0.x #15977 +/- ##
==================================================
+ Coverage 49.6709% 51.0269% +1.3560%
- Complexity 17017 17407 +390
==================================================
Files 2004 2012 +8
Lines 93896 94215 +319
Branches 16448 16460 +12
==================================================
+ Hits 46639 48075 +1436
+ Misses 40078 38934 -1144
- Partials 7179 7206 +27 🚀 New features to boost your workflow:
|
✅ All tests passed ✅🏷️ Commit: e234b83 Learn more about TestLens at testlens.app. |
Summary
Docs/skills-only changes (no build or runtime code touched) improving how AI coding agents work in this repo. Every change is grounded in actual source investigation, not assumed — several corrected findings that turned out to be wrong on first pass (see commit messages for the specifics).
codebase-memoryskill reference inAGENTS.mdpointing at a file that never existedAGENTS.mdwith directory-based discovery — skills are found via their own front-matterdescription, not a hand-maintained list that drifts out of sync every time a skill is added or removedpaths:front-matter field so module-scoped skills are discovered structurally (by the files being touched), not just by description-matchinghibernate-developer-style skills forgrails-data-mongodb,grails-forge(a Micronaut application, not Grails — corrects a root rule that's actually inverted there),grails-gradle, andbuild-logic— four real, previously-undocumented subsystems, each verified against actual source and, where relevant, actual test runsAGENTS.mdfiles forgrails-forge/,grails-gradle/, andbuild-logic/correcting root rules that don't transfer to those subprojects (e.g.@GrailsCompileStaticdoesn't apply to any of them;grails-gradle/build-logicshare root's dependency versions whilegrails-forgedoesn't)grails-developertograils-test-examples/, the ~50 real functional test apps that had zero skill coverage despite several sharing a name with a framework-internals module (e.g.grails-test-examples/hibernate7/vs.grails-data-hibernate7/)diff-coverage-checkskill computing real diff coverage (only the lines you changed, not whole-class coverage) entirely locally by cross-referencing JaCoCo XML againstgit diff— zero new build dependency, verified end-to-end against a real mixed-coverage diffworktree-hygieneskill for.claude/worktrees/sprawl, using PR/remote state as the staleness signal rather than commit age (a worktree can go idle between review rounds without being abandoned)migration-scopingskill for pre-work architectural triage, grounded in a real four-branch sprawl case (from the Hibernate7/GORM registry migration) found and cleaned up during this workAttribution
The skill packaging format (
SKILL.mdfront-matter, discovery-by-description convention, cross-agentcompatibilityfield) follows the Agent Skills Specification — Anthropic's public spec and reference implementation for portable, cross-agent skill packages. Nothing in this PR is Claude-specific; every skill's front-matter listsopencode, claude, grok, gemini, copilot, cursor, windsurfas compatible tooling.Test plan
grep/Read), not assumed:grails-i18n:testto confirm thediff-coverage-checkskill's script produces correct output against a real mixed-coverage diff, rangrails-forge/grails-gradle/build-logicbuilds to confirm real commands.agents/skills/*/SKILL.mdfront-matter scan) tested against the full current skill set after each additionbuild.gradle,settings.gradle, or source file was modified — this PR cannot change build or runtime behavior