microsoft/hve-core
Publicmirrored fromhttps://github.com/microsoft/hve-coreAvailable
docs/contributing/instructions.md
666lines · modecode
| 1 | --- |
| 2 | title: 'Contributing Instructions to HVE Core' |
| 3 | description: 'Requirements and standards for contributing GitHub Copilot instruction files to hve-core' |
| 4 | author: Microsoft |
| 5 | ms.date: 2025-11-26 |
| 6 | ms.topic: how-to |
| 7 | --- |
| 8 | |
| 9 | This guide defines the requirements, standards, and best practices for contributing GitHub Copilot instruction files (`.instructions.md`) to the hve-core library. |
| 10 | |
| 11 | **⚙️ Common Standards**: See [AI Artifacts Common Standards](ai-artifacts-common.md) for shared requirements (XML blocks, markdown quality, RFC 2119, validation, testing). |
| 12 | |
| 13 | ## What is an Instructions File? |
| 14 | |
| 15 | An **instructions file** is a technology-specific or pattern-specific guidance document that defines coding standards, conventions, and best practices for GitHub Copilot to follow when working with particular file types, languages, or frameworks. |
| 16 | |
| 17 | ## Use Cases for Instructions Files |
| 18 | |
| 19 | Create an instructions file when you need to: |
| 20 | |
| 21 | * Define language-specific coding standards (e.g., Python, C#, Bash) |
| 22 | * Establish framework-specific conventions (e.g., Terraform, Bicep) |
| 23 | * Document file type requirements (e.g., Markdown, YAML) |
| 24 | * Specify workflow patterns (e.g., commit messages, PR creation) |
| 25 | * Codify project-specific style guidelines |
| 26 | * Auto-apply rules based on file patterns (`applyTo` glob matching) |
| 27 | |
| 28 | ## File Structure Requirements |
| 29 | |
| 30 | ### Location |
| 31 | |
| 32 | Instruction files are typically organized in a collection subdirectory by convention: |
| 33 | |
| 34 | ```text |
| 35 | .github/instructions/ |
| 36 | ├── {collection-id}/ |
| 37 | │ └── your-instructions.instructions.md # Collection-scoped |
| 38 | ├── coding-standards/ |
| 39 | │ ├── language.instructions.md # Language-specific |
| 40 | │ └── {language}/ |
| 41 | │ └── language.instructions.md # Language with subdirectory |
| 42 | ├── shared/ |
| 43 | │ └── cross-collection.instructions.md # Shared across collections |
| 44 | └── hve-core/ |
| 45 | └── markdown.instructions.md # Collection-scoped (distributed) |
| 46 | ``` |
| 47 | |
| 48 | > [!IMPORTANT] |
| 49 | > Files placed directly at the root of `.github/instructions/` (without a subdirectory) are repo-specific and never distributed through extension packages or collections. Only use root-level placement for internal repository concerns such as CI/CD workflows or conventions that do not generalize to consumers. Files in subdirectories like `hve-core/`, `ado/`, and `shared/` are collection-scoped and distributable. |
| 50 | |
| 51 | <!-- markdownlint-disable-next-line MD028 --> |
| 52 | |
| 53 | > [!NOTE] |
| 54 | > Collections can reference artifacts from any subfolder. The `path:` field in collection YAML files |
| 55 | > accepts any valid repo-relative path regardless of the artifact's parent directory. |
| 56 | |
| 57 | **Examples**: |
| 58 | |
| 59 | * `.github/instructions/coding-standards/python-script.instructions.md` |
| 60 | * `.github/instructions/hve-core/markdown.instructions.md` |
| 61 | * `.github/instructions/coding-standards/csharp/csharp.instructions.md` |
| 62 | * `.github/instructions/coding-standards/bash/bash.instructions.md` |
| 63 | |
| 64 | ### Naming Convention |
| 65 | |
| 66 | * Use lowercase kebab-case: `python-script.instructions.md` |
| 67 | * Be specific about target: `csharp-tests.instructions.md` |
| 68 | * Include domain prefix when needed: `ado-wit-planning.instructions.md` |
| 69 | * Avoid generic names: `code.instructions.md` ❌ → `python-script.instructions.md` ✅ |
| 70 | |
| 71 | ### File Format |
| 72 | |
| 73 | Instruction files **MUST**: |
| 74 | |
| 75 | 1. Use the `.instructions.md` extension |
| 76 | 2. Start with valid YAML frontmatter between `---` delimiters |
| 77 | 3. End with single newline character |
| 78 | |
| 79 | ## Frontmatter Requirements |
| 80 | |
| 81 | ### Required Fields |
| 82 | |
| 83 | **`description`** (string, MANDATORY) |
| 84 | |
| 85 | * **Purpose**: Concise explanation of instruction scope and target |
| 86 | * **Format**: Single sentence, 10-200 characters |
| 87 | * **Style**: Sentence case with proper punctuation |
| 88 | * **Example**: `'Required instructions for Python script implementation with type hints and docstrings'` |
| 89 | |
| 90 | **`applyTo`** (string, MANDATORY for auto-applied instructions) |
| 91 | |
| 92 | * **Purpose**: Glob pattern(s) defining when these instructions activate |
| 93 | * **Format**: Valid glob pattern or comma-separated patterns |
| 94 | * **Scope**: Matches from repository root |
| 95 | * **Examples**: |
| 96 | * Single pattern: `**/*.py` |
| 97 | * Multiple files: `**/*.py, **/*.ipynb` |
| 98 | * Directory scope: `**/src/**/*.sh` |
| 99 | * Specific paths: `**/.copilot-tracking/pr/new/**` |
| 100 | |
| 101 | ### Optional Fields |
| 102 | |
| 103 | **`version`** (string) |
| 104 | |
| 105 | * **Purpose**: Tracks instruction file revisions |
| 106 | * **Format**: Semantic versioning (e.g., `1.0.0`) |
| 107 | * **Pattern**: `^\d+\.\d+(\.\d+)?$` (major.minor or major.minor.patch) |
| 108 | |
| 109 | **`author`** (string) |
| 110 | |
| 111 | * **Purpose**: Attribution for instruction creator |
| 112 | * **Example**: `microsoft/hve-core`, `your-team-name` |
| 113 | |
| 114 | **`lastUpdated`** (string) |
| 115 | |
| 116 | * **Purpose**: Timestamp of last modification |
| 117 | * **Format**: ISO 8601 date (YYYY-MM-DD) |
| 118 | |
| 119 | ### Frontmatter Example |
| 120 | |
| 121 | ```yaml |
| 122 | --- |
| 123 | description: 'Required instructions for Python script implementation with type hints, docstrings, and error handling' |
| 124 | applyTo: '**/*.py, **/*.ipynb' |
| 125 | version: '1.0.0' |
| 126 | author: 'microsoft/hve-core' |
| 127 | lastUpdated: '2025-11-19' |
| 128 | --- |
| 129 | ``` |
| 130 | |
| 131 | ## Collection Entry Requirements |
| 132 | |
| 133 | All instructions must have matching entries in one or more `collections/*.collection.yml` manifests, except for repo-specific instructions placed at the root of `.github/instructions/` (without a subdirectory). Collection entries control distribution and maturity. |
| 134 | |
| 135 | > [!NOTE] |
| 136 | > Root-level instructions (directly under `.github/instructions/` with no subdirectory) are repo-specific and MUST NOT be added to collection manifests. See [Repo-Specific Instructions Exclusion](ai-artifacts-common.md#repo-specific-instructions-exclusion) for details. |
| 137 | |
| 138 | ### Adding Your Instructions to a Collection |
| 139 | |
| 140 | After creating your instructions file, add an `items[]` entry in each target collection manifest: |
| 141 | |
| 142 | ```yaml |
| 143 | items: |
| 144 | # path can reference artifacts from any subfolder |
| 145 | - path: .github/instructions/{collection-id}/my-language.instructions.md |
| 146 | kind: instruction |
| 147 | maturity: stable |
| 148 | ``` |
| 149 | |
| 150 | For instructions in language subdirectories, use the full path: |
| 151 | |
| 152 | ```yaml |
| 153 | items: |
| 154 | - path: .github/instructions/coding-standards/csharp/csharp.instructions.md |
| 155 | kind: instruction |
| 156 | maturity: stable |
| 157 | ``` |
| 158 | |
| 159 | ### Selecting Collections for Instructions |
| 160 | |
| 161 | Choose collections based on who uses the technology or pattern: |
| 162 | |
| 163 | | Instruction Type | Recommended Collections | |
| 164 | |-------------------------|---------------------------------------------------| |
| 165 | | Language standards | `hve-core-all`, `coding-standards` | |
| 166 | | Infrastructure (IaC) | `hve-core-all`, `coding-standards` | |
| 167 | | Documentation standards | `hve-core-all`, `hve-core` | |
| 168 | | Workflow instructions | `hve-core-all` plus relevant workflow collections | |
| 169 | | Test standards | `hve-core-all`, `coding-standards` | |
| 170 | | ADO integration | `hve-core-all`, `ado`, `project-planning` | |
| 171 | |
| 172 | For complete collection documentation, see [AI Artifacts Common Standards - Collection Manifests](ai-artifacts-common.md#collection-manifests). |
| 173 | |
| 174 | ## Content Structure Standards |
| 175 | |
| 176 | ### Required Sections |
| 177 | |
| 178 | #### 1. Title (H1) |
| 179 | |
| 180 | * Clear heading describing target technology/pattern |
| 181 | * Should align with filename and scope |
| 182 | |
| 183 | ```markdown |
| 184 | # Python Script Implementation Instructions |
| 185 | ``` |
| 186 | |
| 187 | #### 2. Overview/Scope |
| 188 | |
| 189 | * Explains what these instructions cover |
| 190 | * Defines when they apply |
| 191 | * Lists any prerequisites or assumptions |
| 192 | |
| 193 | ```markdown |
| 194 | ## Scope |
| 195 | |
| 196 | These instructions apply to all Python scripts in the repository, covering: |
| 197 | |
| 198 | * Code structure and organization |
| 199 | * Type hinting and documentation |
| 200 | * Error handling patterns |
| 201 | * Testing requirements |
| 202 | ``` |
| 203 | |
| 204 | #### 3. Core Standards/Conventions |
| 205 | |
| 206 | * Defines mandatory coding patterns |
| 207 | * Uses RFC 2119 keywords (MUST, SHOULD, MAY) |
| 208 | * Organizes by category (structure, naming, patterns) |
| 209 | * Provides rationale for key decisions |
| 210 | |
| 211 | ```markdown |
| 212 | ## Code Structure |
| 213 | |
| 214 | Scripts MUST follow this organization: |
| 215 | |
| 216 | 1. Shebang (if executable) |
| 217 | 2. Module docstring |
| 218 | 3. Imports (standard library → third-party → local) |
| 219 | 4. Constants |
| 220 | 5. Functions/classes |
| 221 | 6. Main execution block |
| 222 | ``` |
| 223 | |
| 224 | #### 4. Naming Conventions |
| 225 | |
| 226 | * Specifies naming patterns for identifiers |
| 227 | * Covers files, functions, classes, variables, constants |
| 228 | * Provides examples of correct usage |
| 229 | |
| 230 | ```markdown |
| 231 | ## Naming Conventions |
| 232 | |
| 233 | * **Files**: `snake_case.py` (e.g., `data_processor.py`) |
| 234 | * **Functions**: `snake_case()` (e.g., `process_data()`) |
| 235 | * **Classes**: `PascalCase` (e.g., `DataProcessor`) |
| 236 | * **Constants**: `SCREAMING_SNAKE_CASE` (e.g., `MAX_RETRIES`) |
| 237 | * **Private**: `_leading_underscore` (e.g., `_internal_helper()`) |
| 238 | ``` |
| 239 | |
| 240 | #### 5. Code Examples |
| 241 | |
| 242 | * Demonstrates correct patterns with working code |
| 243 | * Shows both positive (✅) and negative (❌) examples |
| 244 | * Wraps in XML-style blocks for reusability |
| 245 | * Includes inline comments explaining key points |
| 246 | |
| 247 | ````markdown |
| 248 | <!-- <example-python-function> --> |
| 249 | ```python |
| 250 | def calculate_average(numbers: list[float]) -> float: |
| 251 | """ |
| 252 | Calculate the arithmetic mean of a list of numbers. |
| 253 | |
| 254 | Args: |
| 255 | numbers: List of numeric values to average |
| 256 | |
| 257 | Returns: |
| 258 | Arithmetic mean of the input numbers |
| 259 | |
| 260 | Raises: |
| 261 | ValueError: If the input list is empty |
| 262 | """ |
| 263 | if not numbers: |
| 264 | raise ValueError("Cannot calculate average of empty list") |
| 265 | |
| 266 | return sum(numbers) / len(numbers) |
| 267 | ``` |
| 268 | <!-- </example-python-function> --> |
| 269 | ```` |
| 270 | |
| 271 | #### 6. Anti-Patterns |
| 272 | |
| 273 | * Documents what to avoid |
| 274 | * Explains why patterns are problematic |
| 275 | * Shows correct alternatives |
| 276 | |
| 277 | ```markdown |
| 278 | ## Anti-Patterns |
| 279 | |
| 280 | ❌ **Bare except clauses**: |
| 281 | ```python |
| 282 | try: |
| 283 | risky_operation() |
| 284 | except: # DON'T DO THIS |
| 285 | pass |
| 286 | ``` |
| 287 | |
| 288 | ✅ **Specific exception handling**: |
| 289 | |
| 290 | ```python |
| 291 | try: |
| 292 | risky_operation() |
| 293 | except FileNotFoundError as e: |
| 294 | logger.error(f"File not found: {e}") |
| 295 | raise |
| 296 | ``` |
| 297 | |
| 298 | #### 7. Validation/Testing |
| 299 | |
| 300 | * Specifies validation tools and commands |
| 301 | * Defines testing requirements |
| 302 | * Lists quality gates |
| 303 | |
| 304 | ```markdown |
| 305 | ## Validation |
| 306 | |
| 307 | All Python code MUST pass: |
| 308 | |
| 309 | * **Linting**: `ruff check .` |
| 310 | * **Type checking**: `mypy --strict .` |
| 311 | * **Testing**: `pytest tests/ --cov=src` |
| 312 | * **Coverage**: Minimum 80% line coverage |
| 313 | ``` |
| 314 | |
| 315 | #### 8. Attribution Footer |
| 316 | |
| 317 | * **MANDATORY**: Include at end of file |
| 318 | |
| 319 | ```markdown |
| 320 | --- |
| 321 | |
| 322 | Brought to you by microsoft/hve-core |
| 323 | ``` |
| 324 | |
| 325 | ### XML-Style Block Requirements |
| 326 | |
| 327 | See [AI Artifacts Common Standards - XML-Style Block Standards](ai-artifacts-common.md#xml-style-block-standards) for complete rules. Common tags for instructions: |
| 328 | |
| 329 | * `<!-- <example-{pattern-name}> -->` - Code examples |
| 330 | * `<!-- <convention-{category}> -->` - Convention blocks |
| 331 | * `<!-- <anti-pattern-{issue}> -->` - Things to avoid |
| 332 | * `<!-- <validation-checklist> -->` - Validation steps |
| 333 | * `<!-- <file-structure> -->` - File organization |
| 334 | |
| 335 | ### Directive Language Standards |
| 336 | |
| 337 | Use RFC 2119 compliant keywords (MUST/SHOULD/MAY). See [AI Artifacts Common Standards - RFC 2119 Directive Language](ai-artifacts-common.md#rfc-2119-directive-language) for complete guidance. |
| 338 | |
| 339 | ## Pattern Definition Standards |
| 340 | |
| 341 | Instructions should clearly define: |
| 342 | |
| 343 | ### File Organization |
| 344 | |
| 345 | Structure for target files: |
| 346 | |
| 347 | ````markdown |
| 348 | <!-- <file-structure-python-script> --> |
| 349 | ```python |
| 350 | #!/usr/bin/env python3 |
| 351 | """ |
| 352 | Module-level docstring describing purpose and usage. |
| 353 | """ |
| 354 | |
| 355 | # Standard library imports |
| 356 | import os |
| 357 | import sys |
| 358 | from pathlib import Path |
| 359 | |
| 360 | # Third-party imports |
| 361 | import requests |
| 362 | import pandas as pd |
| 363 | |
| 364 | # Local imports |
| 365 | from .utils import helper_function |
| 366 | |
| 367 | # Constants |
| 368 | MAX_RETRIES = 3 |
| 369 | DEFAULT_TIMEOUT = 30 |
| 370 | |
| 371 | # Functions and classes |
| 372 | def main() -> int: |
| 373 | """Main entry point.""" |
| 374 | return 0 |
| 375 | |
| 376 | # Main execution |
| 377 | if __name__ == "__main__": |
| 378 | sys.exit(main()) |
| 379 | ``` |
| 380 | <!-- </file-structure-python-script> --> |
| 381 | ```` |
| 382 | |
| 383 | ### Code Patterns |
| 384 | |
| 385 | Approved implementation patterns: |
| 386 | |
| 387 | ````markdown |
| 388 | ## Error Handling Pattern |
| 389 | |
| 390 | <!-- <pattern-error-handling> --> |
| 391 | ```python |
| 392 | def process_file(file_path: Path) -> dict[str, Any]: |
| 393 | """ |
| 394 | Process a configuration file with proper error handling. |
| 395 | |
| 396 | Args: |
| 397 | file_path: Path to configuration file |
| 398 | |
| 399 | Returns: |
| 400 | Parsed configuration dictionary |
| 401 | |
| 402 | Raises: |
| 403 | FileNotFoundError: If configuration file doesn't exist |
| 404 | ValueError: If configuration is invalid |
| 405 | """ |
| 406 | if not file_path.exists(): |
| 407 | raise FileNotFoundError(f"Configuration not found: {file_path}") |
| 408 | |
| 409 | try: |
| 410 | with file_path.open() as f: |
| 411 | config = json.load(f) |
| 412 | except json.JSONDecodeError as e: |
| 413 | raise ValueError(f"Invalid JSON in {file_path}: {e}") |
| 414 | |
| 415 | # Validate required keys |
| 416 | required = {"version", "settings"} |
| 417 | if not required.issubset(config.keys()): |
| 418 | missing = required - config.keys() |
| 419 | raise ValueError(f"Missing required keys: {missing}") |
| 420 | |
| 421 | return config |
| 422 | ``` |
| 423 | <!-- </pattern-error-handling> --> |
| 424 | ```` |
| 425 | |
| 426 | ### Style Conventions |
| 427 | |
| 428 | Formatting and style rules: |
| 429 | |
| 430 | ```markdown |
| 431 | ## Style Conventions |
| 432 | |
| 433 | * **Indentation**: 4 spaces (no tabs) |
| 434 | * **Line length**: 88 characters (Black formatter default) |
| 435 | * **Quotes**: Double quotes for strings, single for dict keys |
| 436 | * **Imports**: Organized by isort with Black-compatible settings |
| 437 | * **Trailing commas**: Use in multi-line collections |
| 438 | * **Type hints**: Use modern syntax (`list[str]` not `List[str]`) |
| 439 | ``` |
| 440 | |
| 441 | ## Validation and Tooling |
| 442 | |
| 443 | ### Linting Configuration |
| 444 | |
| 445 | Specify tools and configurations: |
| 446 | |
| 447 | ````markdown |
| 448 | ## Linting |
| 449 | |
| 450 | All Python code MUST pass Ruff checks: |
| 451 | |
| 452 | <!-- <config-ruff> --> |
| 453 | ```toml |
| 454 | [tool.ruff] |
| 455 | line-length = 88 |
| 456 | target-version = "py311" |
| 457 | |
| 458 | [tool.ruff.lint] |
| 459 | select = ["E", "F", "I", "N", "W", "UP"] |
| 460 | ignore = ["E501"] # Line too long (handled by formatter) |
| 461 | ``` |
| 462 | <!-- </config-ruff> --> |
| 463 | |
| 464 | Run: `ruff check . --fix` |
| 465 | ```` |
| 466 | |
| 467 | ### Testing Requirements |
| 468 | |
| 469 | Define test expectations: |
| 470 | |
| 471 | ```markdown |
| 472 | ## Testing Requirements |
| 473 | |
| 474 | * **Coverage**: Minimum 80% line coverage |
| 475 | * **Test location**: `tests/` directory mirroring `src/` structure |
| 476 | * **Test naming**: `test_*.py` files, `test_*` functions |
| 477 | * **Fixtures**: Use pytest fixtures for shared test data |
| 478 | * **Mocking**: Mock external dependencies (file I/O, network calls) |
| 479 | |
| 480 | <!-- <example-pytest-test> --> |
| 481 | ```python |
| 482 | import pytest |
| 483 | from pathlib import Path |
| 484 | from mymodule import process_file |
| 485 | |
| 486 | def test_process_file_valid(tmp_path: Path) -> None: |
| 487 | """Test processing valid configuration file.""" |
| 488 | config_file = tmp_path / "config.json" |
| 489 | config_file.write_text('{"version": "1.0", "settings": {}}') |
| 490 | |
| 491 | result = process_file(config_file) |
| 492 | |
| 493 | assert result["version"] == "1.0" |
| 494 | assert "settings" in result |
| 495 | |
| 496 | def test_process_file_missing(tmp_path: Path) -> None: |
| 497 | """Test handling of missing configuration file.""" |
| 498 | config_file = tmp_path / "missing.json" |
| 499 | |
| 500 | with pytest.raises(FileNotFoundError): |
| 501 | process_file(config_file) |
| 502 | ``` |
| 503 | <!-- </example-pytest-test> --> |
| 504 | |
| 505 | ## Glob Pattern Guidelines |
| 506 | |
| 507 | The `applyTo` field uses glob patterns to match files: |
| 508 | |
| 509 | ### Pattern Syntax |
| 510 | |
| 511 | * `*` - Matches any characters except `/` |
| 512 | * `**` - Matches any characters including `/` (recursive) |
| 513 | * `?` - Matches single character |
| 514 | * `[abc]` - Matches any character in brackets |
| 515 | * `{a,b}` - Matches either `a` or `b` |
| 516 | |
| 517 | ### Common Patterns |
| 518 | |
| 519 | ```yaml |
| 520 | # Single file extension |
| 521 | applyTo: '**/*.py' |
| 522 | |
| 523 | # Multiple extensions |
| 524 | applyTo: '**/*.py, **/*.ipynb' |
| 525 | |
| 526 | # Specific directory |
| 527 | applyTo: '**/src/**/*.ts' |
| 528 | |
| 529 | # Specific path pattern |
| 530 | applyTo: '**/.copilot-tracking/plans/*.md' |
| 531 | |
| 532 | # Exclude pattern (handled by negative patterns in schema-mapping.json) |
| 533 | # Not directly in applyTo, but can be configured |
| 534 | ``` |
| 535 | |
| 536 | ### Testing Patterns |
| 537 | |
| 538 | Verify your glob pattern matches intended files: |
| 539 | |
| 540 | ```bash |
| 541 | # PowerShell |
| 542 | Get-ChildItem -Path . -Recurse -Include *.py |
| 543 | |
| 544 | # Bash |
| 545 | find . -name "*.py" |
| 546 | ``` |
| 547 | |
| 548 | ## Validation Checklist |
| 549 | |
| 550 | Before submitting your instructions file, verify: |
| 551 | |
| 552 | ### File Format Structure |
| 553 | |
| 554 | * [ ] File uses `.instructions.md` extension |
| 555 | * [ ] File starts with YAML frontmatter between `---` delimiters |
| 556 | * [ ] File ends with single newline character (EOF) |
| 557 | * [ ] No trailing whitespace on any lines |
| 558 | * [ ] Uses UTF-8 encoding |
| 559 | |
| 560 | ### Frontmatter |
| 561 | |
| 562 | * [ ] Valid YAML between `---` delimiters |
| 563 | * [ ] `description` field present and descriptive (10-200 chars) |
| 564 | * [ ] `applyTo` field with valid glob pattern (if auto-applied) |
| 565 | * [ ] `version` follows semantic versioning format (if present) |
| 566 | * [ ] No trailing whitespace in values |
| 567 | |
| 568 | ### Content Structure |
| 569 | |
| 570 | * [ ] Clear H1 title describing target |
| 571 | * [ ] Overview/scope section |
| 572 | * [ ] Core standards with RFC 2119 keywords |
| 573 | * [ ] Naming conventions documented |
| 574 | * [ ] Code examples wrapped in XML-style blocks |
| 575 | * [ ] Anti-patterns section with alternatives |
| 576 | * [ ] Validation/testing requirements |
| 577 | * [ ] Attribution footer present |
| 578 | |
| 579 | ### Code Examples |
| 580 | |
| 581 | * [ ] All examples are syntactically correct |
| 582 | * [ ] Examples include necessary imports/context |
| 583 | * [ ] Both positive and negative examples provided |
| 584 | * [ ] Examples wrapped in XML-style blocks with unique names |
| 585 | * [ ] Code blocks have language tags |
| 586 | * [ ] Inline comments explain key points |
| 587 | |
| 588 | ### Common Standards |
| 589 | |
| 590 | * [ ] Markdown quality (see [Common Standards - Markdown Quality](ai-artifacts-common.md#markdown-quality-standards)) |
| 591 | * [ ] XML-style blocks properly formatted (see [Common Standards - XML-Style Blocks](ai-artifacts-common.md#xml-style-block-standards)) |
| 592 | * [ ] RFC 2119 keywords used consistently (see [Common Standards - RFC 2119](ai-artifacts-common.md#rfc-2119-directive-language)) |
| 593 | |
| 594 | ### Technical Validation |
| 595 | |
| 596 | * [ ] Glob pattern in `applyTo` is valid and tested |
| 597 | * [ ] All file references point to existing files |
| 598 | * [ ] External links are valid and accessible |
| 599 | * [ ] Tool/command references are correct |
| 600 | * [ ] No conflicts with existing instructions files |
| 601 | |
| 602 | ### Integration |
| 603 | |
| 604 | * [ ] Aligns with `.github/copilot-instructions.md` |
| 605 | * [ ] Follows repository conventions |
| 606 | * [ ] Compatible with existing instructions |
| 607 | * [ ] Does not duplicate existing instruction functionality |
| 608 | * [ ] Glob pattern doesn't conflict with other instructions |
| 609 | |
| 610 | ## Testing Your Instructions |
| 611 | |
| 612 | See [AI Artifacts Common Standards - Common Testing Practices](ai-artifacts-common.md#common-testing-practices) for testing guidelines. For instructions specifically: |
| 613 | |
| 614 | 1. Verify `applyTo` glob pattern matches intended files |
| 615 | 2. Test all code examples execute correctly |
| 616 | 3. Have Copilot generate code following your instructions |
| 617 | 4. Validate specified linting/validation commands work |
| 618 | |
| 619 | ## Common Issues and Fixes |
| 620 | |
| 621 | ### Instructions-Specific Issues |
| 622 | |
| 623 | ### Invalid Glob Pattern |
| 624 | |
| 625 | * **Problem**: Glob patterns that only match root directory or contain syntax errors |
| 626 | * **Solution**: Use `**/` prefix for recursive matching (e.g., `**/*.py` for all Python files recursively) |
| 627 | |
| 628 | ### Conflicting Patterns |
| 629 | |
| 630 | * **Problem**: Multiple instruction files with overlapping glob patterns causing ambiguity |
| 631 | * **Solution**: Make patterns more specific (e.g., `**/tests/**/*.py` vs `**/*.py`) or ensure they target distinct file sets |
| 632 | |
| 633 | For additional common issues (XML blocks, markdown, directives), see [AI Artifacts Common Standards - Common Issues and Fixes](ai-artifacts-common.md#common-issues-and-fixes). |
| 634 | |
| 635 | ## Automated Validation |
| 636 | |
| 637 | Run these commands before submission (see [Common Standards - Common Validation](ai-artifacts-common.md#common-validation-standards)): |
| 638 | |
| 639 | * `npm run lint:frontmatter` |
| 640 | * `npm run lint:md` |
| 641 | * `npm run spell-check` |
| 642 | * `npm run lint:md-links` |
| 643 | |
| 644 | All checks **MUST** pass before merge. |
| 645 | |
| 646 | ## Related Documentation |
| 647 | |
| 648 | * [AI Artifacts Common Standards](ai-artifacts-common.md) - Shared standards for all contributions |
| 649 | * [Contributing Custom Agents](custom-agents.md) - AI agent configuration files |
| 650 | * [Contributing Prompts](prompts.md) - Workflow-specific guidance |
| 651 | * [Pull Request Template](../../.github/PULL_REQUEST_TEMPLATE.md) - Submission requirements |
| 652 | |
| 653 | ## Getting Help |
| 654 | |
| 655 | See [AI Artifacts Common Standards - Getting Help](ai-artifacts-common.md#getting-help) for support resources. For instructions-specific assistance: |
| 656 | |
| 657 | * Review existing examples in `.github/instructions/{collection-id}/` (the conventional location for instruction files) |
| 658 | * Test glob patterns using file search commands |
| 659 | * Use `prompt-builder.agent.md` agent for assistance |
| 660 | |
| 661 | --- |
| 662 | |
| 663 | <!-- markdownlint-disable MD036 --> |
| 664 | *🤖 Crafted with precision by ✨Copilot following brilliant human instruction, |
| 665 | then carefully refined by our team of discerning human reviewers.* |
| 666 | <!-- markdownlint-enable MD036 --> |
| 667 | |