# Shipped Skills Update Checklist

Mechanics for editing `src/main/skills/` safely. Load before any edit in that tree (workflow step 6).

## How shipping works

- `zipSkills` (root `build.gradle.kts`) zips `src/main/skills/` plus the generated overlay at `build/generated/skills/authoring-gradle-builds/references` (merged into `authoring-gradle-builds/references` inside the zip) into `build/generated/resources/skills/skills.zip`.
- That directory is a `main` resources source directory, so `skills.zip` ships inside the application; `install_gradle_skills` installs it into agents.
- Consequence: every edit under `src/main/skills/` ships with the next build/install. There is no separate publish step and no partial shipping.

## Edit rules

1. **Name matches directory.** Frontmatter `name:` must equal the skill directory name — enforced by `UpdateSkills.discoverSkills` (`src/main/kotlin/dev/rnett/gradle/mcp/UpdateSkills.kt`).
2. **Version bumps.** Bump frontmatter `metadata.version` (quoted semver string) for every material change: minor for substantive guidance/compatibility changes (the normal case during upgrade ingestion), patch for typo-level fixes, major only for a restructure that changes the skill's contract.
3. **Version-labelling.** Current-state facts get no version label — write them as plain guidance. Use `**Gradle N:**` / `as of N` anchors only for version-specific facts (deprecations, lifecycle status, version numbers, transitional behavior) and past notes; never `N+` future-labelled notes. Anchored notes age into past notes naturally, so no `N+` relabelling is ever needed.
4. **New references.** A new reference lives at `src/main/skills/<skill>/references/<name>.md`, is reachable through a real Markdown link from that skill's `SKILL.md` body, and the link text carries its load trigger (when to load it).
5. **`afterEvaluate` safety rule.** `SkillArtifactSafetyTest` scans every `*.md` under `src/main/skills/` (and only that tree): any mention of `afterEvaluate` must sit in a prohibition/avoidance context containing one of these exact markers — `prohibited`, ``Avoid `afterEvaluate``, `avoid-afterevaluate`, `Don't Do This`, ``removes `afterEvaluate`` — or carry an explicit `afterEvaluate-justification:` block. Otherwise the test fails.
6. **Never hand-edit the best-practices corpus.** It is generated by `generateBestPracticesDoc` under `build/generated/skills/authoring-gradle-builds/references/best-practices/`; link it, don't restate it.

## When the skill inventory itself changes (rare — not part of normal upgrade ingestion)

Adding or removing a shipped skill requires all of:
1. `<dir>/SKILL.md` with frontmatter `name:` matching `<dir>`.
2. A curated entry in `UpdateSkills.DESCRIPTIONS` (the `linkedMapOf` in canonical portfolio order in `src/main/kotlin/dev/rnett/gradle/mcp/UpdateSkills.kt`). Both `update` and `verify` require the discovered skill directories to equal the `DESCRIPTIONS` key set exactly.
3. `./gradlew :updateSkillsList` — re-splices the rendered list into `docs/skills.md` between the exact markers `[//]: # (<<SKILLS_LIST_START>>)` and `[//]: # (<<SKILLS_LIST_END>>)` (exactly one of each must exist).
Editing an existing skill does not touch `DESCRIPTIONS` unless its one-line portfolio description is no longer accurate.

## Best-practices corpus regeneration

- `./gradlew generateBestPracticesDoc` runs `dev.rnett.gradle.mcp.bestpractices.GenerateBestPracticesDoc` against the target version: `-PgradleDocsVersion=<v>` when passed, otherwise `gradle.gradleVersion` — the **running** Gradle version: NEW once the wrapper bump is in effect.
- Output: `build/generated/skills/authoring-gradle-builds/references/best-practices/` (`_index.md` plus one file per section), untracked (under the gitignored `build/` tree); `zipSkills` merges it into `skills.zip`.
- **Regenerates cleanly** means: (1) the task succeeds against NEW — if the new docs structure breaks extraction it fails loudly with `No Gradle best-practices pages were extracted for version <v>. Examined entries include: <examined entries>`; if it fails, fix `:best-practices-generator` and rerun before proceeding; (2) review the regenerated `best-practices/*.md` for material drift caused by the upgrade (sections appearing/disappearing, guidance contradicting the new release notes). Nothing is committed: the output is gitignored build output, regenerated on every build.
- After every wrapper upgrade, regenerate against NEW even if no ledger item touched best practices.

## Verification commands

- `./gradlew verifySkillsList` — `docs/skills.md` list sync + inventory match. NOT wired into `check`; run explicitly.
- `./gradlew :test --tests "dev.rnett.gradle.mcp.skills.SkillArtifactSafetyTest"` — the `afterEvaluate` gate (also runs under plain `test`).
- `./gradlew check` — full verification gate: `test`, `verifyToolsList`, and the `integrationTest` and `treeSitterTest` suites (all wired into `check`; it is not a unit-only gate).
- `./gradlew integrationTest` — when execution-layer code changed; known pre-existing failures to name, not hide: `JavaReplIntegrationTest.initializationError`, `KotlinReplIntegrationTest.basic execution works()`.
- `./gradlew :updateToolsList` — only if Kotlin tool metadata changed; never for skill-only edits.
