From de01337cca129affbd7fed95aa2a177cf132eff5 Mon Sep 17 00:00:00 2001 From: amannocci Date: Tue, 14 Jul 2026 19:57:36 +0200 Subject: [PATCH] chore: convert skill files to proper skill dirs and fix CLAUDE.md drift Restructure pr-template-validation.md and issue-template-validation.md into /SKILL.md directories so they're auto-discovered, reference them from CLAUDE.md, and correct CLAUDE.md claims that had drifted from the codebase (broken test path, nonexistent Log API methods, missing exception classes). --- .claude/CLAUDE.md | 30 ++- .../skills/issue-template-validation/SKILL.md | 192 ++++++++++++++++++ .../skills/pr-template-validation/SKILL.md | 125 ++++++++++++ 3 files changed, 337 insertions(+), 10 deletions(-) create mode 100644 .claude/skills/issue-template-validation/SKILL.md create mode 100644 .claude/skills/pr-template-validation/SKILL.md diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index c4d0efd..567d682 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -93,10 +93,10 @@ uv run poe test uv run poe test:e2e # Run single test file -pytest tests/it/test_resources.py +pytest tests/it/test_process.py # Run single test -pytest tests/it/test_resources.py::test_load_manifest +pytest tests/it/test_process.py::TestCommand::test_empty # Run tests matching a pattern pytest -k "test_load" -v @@ -197,23 +197,25 @@ Use the `Log` class from utils: ```python from terranova.utils import Log -Log.info("message") # Blue info -Log.success("message") # Green success -Log.warning("message") # Yellow warning -Log.error("message") # Red error -Log.fatal("action", err) # Red fatal, prints error context +Log.action("message") # Yellow action marker +Log.success("message") # Green success ("Succeeded to {message}") +Log.failure("message", err) # Red failure, prints ExplainedError cause/resolution if present +Log.fatal("message", err) # Red failure + raises Exit(1) ``` ### Error Handling Custom exceptions in `src/terranova/exceptions.py`: -- `InvalidManifestError`: Manifest validation failed +- `ExplainedError`: Base for all errors that carry a `cause` and optional `resolution` shown to the user +- `ManifestError` / `InvalidManifestError`: Manifest validation failed - `InvalidResourcesError`: Resource configuration invalid - `MissingManifestError`: Manifest file not found - `UnreadableManifestError`: Cannot read manifest -- `MissingRunbookEnvError`: Required env var for runbook missing - `VersionManifestError`: Unsupported manifest version +- `RunbookError` / `AmbiguousRunbookError`: Multiple runbooks match a name +- `MissingRunbookError`: Named runbook not found +- `MissingRunbookEnvError`: Required env var for runbook missing Wrap jsonschema `ValidationError` in `InvalidManifestError` when catching. @@ -276,4 +278,12 @@ This sets `SharedContext.debug = True` which can be checked in code. - Apache-2.0 licensed - Original source: [elastic/terranova](https://github.com/elastic/terranova) - Keep copyright notices for both Elasticsearch and current maintainer -- Follow existing commit message format: `type: description` (e.g., `fix:`, `refactor:`, `chore:`, `docs:`) \ No newline at end of file +- Follow existing commit message format: `type: description` (e.g., `fix:`, `refactor:`, `chore:`, `docs:`) + +## GitHub PR/Issue Creation + +Before running `gh pr create`, use the `pr-template-validation` skill to check the PR body against `.github/PULL_REQUEST_TEMPLATE.md`. + +Before running `gh issue create`, use the `issue-template-validation` skill to check the issue body against the matching `.github/ISSUE_TEMPLATE/*` template. + +Both skills reject placeholder text (TBD/TODO/FIXME/WIP), empty sections, and duplicated content across sections โ€” do not bypass them by creating the PR/issue directly without invoking the skill first. \ No newline at end of file diff --git a/.claude/skills/issue-template-validation/SKILL.md b/.claude/skills/issue-template-validation/SKILL.md new file mode 100644 index 0000000..741b2b6 --- /dev/null +++ b/.claude/skills/issue-template-validation/SKILL.md @@ -0,0 +1,192 @@ +--- +name: issue-template-validation +description: Validate GitHub issue template sections before creating an issue. Invoke this skill immediately before any `gh issue create` command. Do not proceed with issue creation if any PRESENT required section is empty, contains placeholders (TBD/TDB/TODO/FIXME/WIP), or duplicates another section. Detect the template type from the issue title prefix or user context and apply the matching template rules. +--- + +# Issue Template Validation + +## When to Use This Skill + +Invoke this skill **before creating any GitHub issue** to validate that all required sections contain meaningful, unique content. + +## Template Types + +Detect the template from the issue title prefix or user context: + +| Prefix | Template | +|---|---| +| `[Bug]:` | Bug Report | +| `[Feature]:` | Feature Request | +| `[Task]:` | Task | +| `[Docs]:` | Documentation | +| `[Question]:` | Question | + +If no prefix is present, infer from the content or ask the user which template they intend to use. + +## Required Sections per Template + +### ๐Ÿ› Bug Report + +**Required (must have meaningful content):** +1. `:bug: Bug Description` +2. `โœ… Expected Behavior` +3. `โŒ Actual Behavior` +4. `๐Ÿ” Steps to Reproduce` + +**Optional (skip validation if header absent):** +- `๐Ÿ–ฅ๏ธ Environment` +- `๐Ÿ“ธ Screenshots / Logs` +- `๐Ÿง  Additional Context` + +--- + +### โœจ Feature Request + +**Required:** +1. `๐Ÿš€ Feature Summary` +2. `๐Ÿค” Problem Statement` +3. `๐Ÿ’ก Proposed Solution` + +**Optional:** +- `๐Ÿ”„ Alternatives Considered` +- `๐Ÿ“ˆ Impact` +- `๐Ÿ“ Additional Context` + +--- + +### ๐Ÿ“‹ Task + +**Required:** +1. `๐Ÿ“Œ Summary` +2. `๐ŸŽฏ Objectives` +3. `๐Ÿงฉ Scope` + +**Optional:** +- `๐Ÿง  Design / Decisions` +- `๐Ÿ“… Timeline` +- `โœ… Definition of Done` +- `๐Ÿ“ฃ Notes / Updates` + +--- + +### ๐Ÿ“š Documentation + +**Required:** +1. `๐Ÿ“ Location` +2. `โ“ What's Wrong` +3. `โœ… Suggested Improvement` + +**Optional:** +- `๐Ÿง  Additional Context` + +--- + +### โ“ Question + +**Required:** +1. `โ“ Question` + +**Optional:** +- `๐Ÿ” What I've Tried` +- `๐Ÿงพ Context` +- `๐Ÿ“Ž Additional Info` + +--- + +## Validation Rules + +**Important distinction:** +- **Missing optional section** (header not in body) = ALLOWED +- **Missing required section** (header not in body) = FAIL โ€” ask user to add it +- **Empty section** (header present but no content) = FAIL โ€” user must fill it or remove it + +For each **required** section that IS present, and for each **optional** section that IS present, validation **FAILS** if: + +### 1. Empty Content +Section header exists but contains only whitespace or placeholder list items. + +**Action:** Reject and ask user to either add substantive content or remove the section header entirely. + +### 2. Placeholder Text +Case-insensitive detection of: `TBD`, `TDB`, `TODO`, `FIXME`, `WIP` + +This includes placeholders inside list items (e.g. `- TBD`, `- [ ] TDB`). + +**Action:** Reject and ask user to replace with actual content. + +### 3. Content Duplication +Section content is an exact or near-exact duplicate of another section. + +**Action:** Reject and explain each section must articulate a distinct aspect. + +### 4. Missing Required Section +A required section for the detected template type is entirely absent from the body. + +**Action:** Reject and ask user to add the missing section with real content. + +--- + +## What Counts as Meaningful Content + +**Valid examples:** + +- **Bug Description:** "When running `ensemble run --parallel`, jobs are silently dropped after the 10th concurrent execution. No error is logged." +- **Expected Behavior:** "All submitted jobs should be executed. The system should queue excess jobs if concurrency limit is hit." +- **Objectives:** "- [ ] Identify the root cause of the queue overflow\n- [ ] Add backpressure mechanism\n- [ ] Add test coverage for high-concurrency scenarios" +- **Proposed Solution:** "Add a configurable `max_queue_size` parameter to the worker executor with exponential backoff when the queue is full." + +**Invalid examples:** + +- `TBD`, `TDB`, `TODO`, `FIXME`, `WIP` +- `- TBD` or `- [ ] TDB` +- Empty section with just the header +- Copy of another section's content + +--- + +## Validation Workflow + +1. **Detect template type** from title prefix or context (ask if unclear) +2. **Check required sections** are all present in the body โ†’ fail if any are missing +3. **For each present section** (required or optional), validate: + - Trim whitespace + - Check if empty โ†’ FAIL + - Check for placeholder patterns (case-insensitive) โ†’ FAIL + - Check for duplicate content โ†’ FAIL +4. **If ANY validation fails:** + - Do **not** proceed with issue creation + - Report all failures with specific reasons + - Ask user to revise and retry +5. **If ALL validations pass:** + - Proceed with issue creation using `gh issue create` + +--- + +## Error Reporting Format + +``` +โŒ Issue validation failed. Will not create issue until these sections are fixed: + +1. "๐ŸŽฏ Objectives" [required] + โŒ Contains placeholder text: TDB + โ†’ Replace with actual objectives as a checklist + +2. "๐Ÿงฉ Scope" [required] + โŒ Section header exists but is empty + โ†’ Describe what is in and out of scope, or remove the header + +3. "๐Ÿš€ Feature Summary" [required] + โŒ Section is missing from the issue body + โ†’ Add this section with a short description of the feature + +Please revise these sections and try creating the issue again. +``` + +--- + +## Implementation Notes + +- Placeholder detection is case-insensitive and covers bare words as well as list items (`- TBD`, `- [ ] TDB`) +- Trim whitespace before checking for empty content +- Identify sections by emoji/heading markers from the templates +- This validation does NOT apply to issue updates after initial creation or issues created manually outside Claude \ No newline at end of file diff --git a/.claude/skills/pr-template-validation/SKILL.md b/.claude/skills/pr-template-validation/SKILL.md new file mode 100644 index 0000000..c340b89 --- /dev/null +++ b/.claude/skills/pr-template-validation/SKILL.md @@ -0,0 +1,125 @@ +--- +name: pr-template-validation +description: Validate PR body sections before creating a GitHub PR. Invoke this skill immediately before any `gh pr create` command. Do not proceed with PR creation if any PRESENT section is empty, contains placeholders (TBD/TODO/FIXME/WIP), or duplicates another section. Missing sections are allowed if not relevant. +--- + +# PR Template Validation + +## When to Use This Skill + +Invoke this skill **before creating any GitHub PR** to validate that all PR template sections contain meaningful, unique content. + +## Template Sections to Validate + +Validate these sections from `.github/PULL_REQUEST_TEMPLATE.md`: + +1. **๐Ÿง‘โ€๐Ÿ’ป What is the change being made?** +2. **:question: Why is the change being made?** +3. **:white_check_mark: How has this been tested?** +4. **:books: How has this been documented?** +5. **:link: Related Issues** + +## Validation Rules + +**Important distinction:** +- **Missing section** (header not included in PR body) = ALLOWED if not relevant to the change +- **Empty section** (header exists but no content) = FAIL (user must either fill it or remove it) + +For each section that IS present in the PR body, validation **FAILS** if: + +### 1. Empty Content +- Section header exists but contains only whitespace or is completely empty +- **Action:** Reject and ask user to either: + - Add substantive content, OR + - Remove the section header entirely if not relevant + +### 2. Placeholder Text Detection +Case-insensitive detection of: +- `TBD` (To Be Determined) +- `TODO` (To Do) +- `FIXME` (Fix Me) +- `WIP` (Work In Progress) + +**Example failure:** "How has this been tested?" contains "TBD - will test later" + +**Action:** Reject and ask user to replace placeholder with actual content + +### 3. Content Duplication +If a section's content is an exact or near-exact duplicate of another section. + +**Example failure:** +- "What is the change?" = "Add user authentication" +- "Why is the change?" = "Add user authentication" + +**Action:** Reject and explain that each section must articulate a unique aspect (What vs Why vs How) + +## What Counts as Meaningful Content + +**Valid examples:** + +- **What:** "Add JWT token refresh mechanism to extend session lifetime without requiring re-login. Implements automatic token rotation with 5-minute intervals." + +- **Why:** "Users were experiencing session timeouts during long workflows. This allows sessions to stay active without interrupting user work." + +- **Testing:** "Added unit tests for token rotation logic. Verified refresh tokens are generated and validated correctly. Manual testing in staging confirms token expiry and refresh behavior." + +- **Documentation:** "Updated API docs with new `/auth/refresh` endpoint. Added troubleshooting section for token expiration in runbook." + +- **Related Issues:** "Closes #1234. Related to #1235 for session management improvements." + +**Invalid examples:** + +- **Placeholder:** "TBD" or "Will add tests later" +- **Dismissive:** "N/A" or "Not applicable" +- **Duplicate:** Copy of another section's content +- **Too vague:** "Added stuff" or "Fixed bugs" + +## Validation Workflow + +When invoked during PR creation: + +1. **Extract** the PR body content +2. **Parse** to identify which template sections are present (by emoji/heading markers) +3. **For each PRESENT section**, validate: + - Trim whitespace + - Check if empty (header exists but no content) โ†’ FAIL + - Check for placeholder patterns (case-insensitive) โ†’ FAIL + - Check for duplicate content across other sections โ†’ FAIL + - **Note:** If section header is missing entirely, skip validation (allowed if not relevant) +4. **If ANY validation fails:** + - **Do not proceed** with PR creation + - Report failures with specific reasons + - Provide examples of valid content + - Ask user to revise and retry +5. **If ALL validations pass:** + - Proceed with PR creation + +## Error Reporting Format + +When validation fails, report like this: + +``` +โŒ PR validation failed. Will not create PR until these sections are fixed: + +1. "Why is the change being made?" + โŒ Contains placeholder text: TBD + โ†’ Replace with actual reasoning for this change + +2. "How has this been tested?" + โŒ Section header exists but is empty + โ†’ Either add testing details, or remove the section header if no testing was needed + +3. "How has this been documented?" + โŒ Content duplicates "What is the change being made?" + โ†’ Explain what docs were updated, not just repeat the change + +Please revise these sections and try creating the PR again. +``` + +## Implementation Notes + +- Validation is case-insensitive for placeholder detection +- Trim all whitespace before checking for empty content +- Identify sections by emoji headers from the template +- Consider section separators (blank lines) as structural markers +- This validation does NOT apply to PR updates after initial creation or manual PRs created outside Claude