| title | Contributing Instructions to HVE Core |
|---|---|
| description | Requirements and standards for contributing GitHub Copilot instruction files to hve-core |
| sidebar_position | 3 |
| author | Microsoft |
| ms.date | 2026-03-17 |
| ms.topic | how-to |
This guide defines the requirements, standards, and best practices for contributing GitHub Copilot instruction files (.instructions.md) to the hve-core library.
⚙️ Common Standards: See AI Artifacts Common Standards for shared requirements (XML blocks, markdown quality, RFC 2119, validation, testing).
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.
Create an instructions file when you need to:
- Define language-specific coding standards (e.g., Python, C#, Bash)
- Establish framework-specific conventions (e.g., Terraform, Bicep)
- Document file type requirements (e.g., Markdown, YAML)
- Specify workflow patterns (e.g., commit messages, PR creation)
- Codify project-specific style guidelines
- Auto-apply rules based on file patterns (
applyToglob matching)
Instruction files are typically organized in a collection subdirectory by convention:
.github/instructions/
├── {collection-id}/
│ └── your-instructions.instructions.md # Collection-scoped
├── coding-standards/
│ ├── language.instructions.md # Language-specific
│ └── {language}/
│ └── language.instructions.md # Language with subdirectory
├── shared/
│ └── cross-collection.instructions.md # Shared across collections
└── hve-core/
└── markdown.instructions.md # Collection-scoped (distributed)
Important
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.
Note
Collections can reference artifacts from any subfolder. The path: field in collection YAML files
accepts any valid repo-relative path regardless of the artifact's parent directory.
.github/instructions/coding-standards/python-script.instructions.md.github/instructions/hve-core/markdown.instructions.md.github/instructions/coding-standards/csharp/csharp.instructions.md.github/instructions/coding-standards/bash/bash.instructions.md
- Use lowercase kebab-case:
python-script.instructions.md - Be specific about target:
csharp-tests.instructions.md - Include domain prefix when needed:
ado-wit-planning.instructions.md - Avoid generic names:
code.instructions.md❌ →python-script.instructions.md✅
Instruction files MUST:
- Use the
.instructions.mdextension - Start with valid YAML frontmatter between
---delimiters - End with single newline character
description (string, MANDATORY)
| Property | Value |
|---|---|
| Purpose | Concise explanation of instruction scope and target |
| Format | Single sentence, 10-200 characters |
| Style | Sentence case with proper punctuation |
| Example | 'Required instructions for Python script implementation with type hints and docstrings' |
applyTo (string, MANDATORY for auto-applied instructions)
| Property | Value |
|---|---|
| Purpose | Glob pattern(s) defining when these instructions activate |
| Format | Valid glob pattern or comma-separated patterns |
| Scope | Matches from repository root |
Examples:
- Single pattern:
**/*.py - Multiple files:
**/*.py, **/*.ipynb - Directory scope:
**/src/**/*.sh - Specific paths:
**/.copilot-tracking/pr/new/**
version (string)
| Property | Value |
|---|---|
| Purpose | Tracks instruction file revisions |
| Format | Semantic versioning (e.g., 1.0.0) |
| Pattern | ^\d+\.\d+(\.\d+)?$ (major.minor or major.minor.patch) |
author (string)
Attribution for the instruction creator (e.g., microsoft/hve-core, your-team-name).
lastUpdated (string)
Timestamp of last modification in ISO 8601 format (YYYY-MM-DD).
---
description: 'Required instructions for Python script implementation with type hints, docstrings, and error handling'
applyTo: '**/*.py, **/*.ipynb'
version: '1.0.0'
author: 'microsoft/hve-core'
lastUpdated: '2025-11-19'
---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.
Note
Root-level instructions (directly under .github/instructions/ with no subdirectory) are repo-specific and MUST NOT be added to collection manifests. See Repo-Specific Artifact Exclusion for details.
After creating your instructions file, add an items[] entry in each target collection manifest:
items:
# path can reference artifacts from any subfolder
- path: .github/instructions/{collection-id}/my-language.instructions.md
kind: instruction
maturity: stableFor instructions in language subdirectories, use the full path:
items:
- path: .github/instructions/coding-standards/csharp/csharp.instructions.md
kind: instruction
maturity: stableChoose collections based on who uses the technology or pattern:
| Instruction Type | Recommended Collections |
|---|---|
| Language standards | hve-core-all, coding-standards |
| Infrastructure (IaC) | hve-core-all, coding-standards |
| Documentation standards | hve-core-all, hve-core |
| Workflow instructions | hve-core-all plus relevant workflow collections |
| Test standards | hve-core-all, coding-standards |
| ADO integration | hve-core-all, ado, project-planning |
For complete collection documentation, see AI Artifacts Common Standards - Collection Manifests.
- Clear heading describing target technology/pattern
- Should align with filename and scope
# Python Script Implementation Instructions- Explains what these instructions cover
- Defines when they apply
- Lists any prerequisites or assumptions
## Scope
These instructions apply to all Python scripts in the repository, covering:
* Code structure and organization
* Type hinting and documentation
* Error handling patterns
* Testing requirements- Defines mandatory coding patterns
- Uses RFC 2119 keywords (MUST, SHOULD, MAY)
- Organizes by category (structure, naming, patterns)
- Provides rationale for key decisions
## Code Structure
Scripts MUST follow this organization:
1. Shebang (if executable)
2. Module docstring
3. Imports (standard library → third-party → local)
4. Constants
5. Functions/classes
6. Main execution block- Specifies naming patterns for identifiers
- Covers files, functions, classes, variables, constants
- Provides examples of correct usage
## Naming Conventions
* Files: `snake_case.py` (e.g., `data_processor.py`)
* Functions: `snake_case()` (e.g., `process_data()`)
* Classes: `PascalCase` (e.g., `DataProcessor`)
* Constants: `SCREAMING_SNAKE_CASE` (e.g., `MAX_RETRIES`)
* Private: `_leading_underscore` (e.g., `_internal_helper()`)- Demonstrates correct patterns with working code
- Shows both positive (✅) and negative (❌) examples
- Wraps in XML-style blocks for reusability
- Includes inline comments explaining key points
<!-- <example-python-function> -->
```python
def calculate_average(numbers: list[float]) -> float:
"""
Calculate the arithmetic mean of a list of numbers.
Args:
numbers: List of numeric values to average
Returns:
Arithmetic mean of the input numbers
Raises:
ValueError: If the input list is empty
"""
if not numbers:
raise ValueError("Cannot calculate average of empty list")
return sum(numbers) / len(numbers)
```
<!-- </example-python-function> -->- Documents what to avoid
- Explains why patterns are problematic
- Shows correct alternatives
## Anti-Patterns
❌ Bare except clauses:
```python
try:
risky_operation()
except: # DON'T DO THIS
pass✅ Specific exception handling:
try:
risky_operation()
except FileNotFoundError as e:
logger.error(f"File not found: {e}")
raise- Specifies validation tools and commands
- Defines testing requirements
- Lists quality gates
## Validation
All Python code MUST pass:
* Linting: `ruff check .`
* Type checking: `mypy --strict .`
* Testing: `pytest tests/ --cov=src`
* Coverage: Minimum 80% line coverageAlways include an attribution footer at the end of the file.
---
Brought to you by microsoft/hve-coreSee AI Artifacts Common Standards - XML-Style Block Standards for complete rules. Common tags for instructions:
<!-- <example-{pattern-name}> -->- Code examples<!-- <convention-{category}> -->- Convention blocks<!-- <anti-pattern-{issue}> -->- Things to avoid<!-- <validation-checklist> -->- Validation steps<!-- <file-structure> -->- File organization
Use RFC 2119 compliant keywords (MUST/SHOULD/MAY). See AI Artifacts Common Standards - RFC 2119 Directive Language for complete guidance.
Instructions should clearly define:
Structure for target files:
<!-- <file-structure-python-script> -->
```python
#!/usr/bin/env python3
"""
Module-level docstring describing purpose and usage.
"""
# Standard library imports
import os
import sys
from pathlib import Path
# Third-party imports
import requests
import pandas as pd
# Local imports
from .utils import helper_function
# Constants
MAX_RETRIES = 3
DEFAULT_TIMEOUT = 30
# Functions and classes
def main() -> int:
"""Main entry point."""
return 0
# Main execution
if __name__ == "__main__":
sys.exit(main())
```
<!-- </file-structure-python-script> -->Approved implementation patterns:
## Error Handling Pattern
<!-- <pattern-error-handling> -->
```python
def process_file(file_path: Path) -> dict[str, Any]:
"""
Process a configuration file with proper error handling.
Args:
file_path: Path to configuration file
Returns:
Parsed configuration dictionary
Raises:
FileNotFoundError: If configuration file doesn't exist
ValueError: If configuration is invalid
"""
if not file_path.exists():
raise FileNotFoundError(f"Configuration not found: {file_path}")
try:
with file_path.open() as f:
config = json.load(f)
except json.JSONDecodeError as e:
raise ValueError(f"Invalid JSON in {file_path}: {e}")
# Validate required keys
required = {"version", "settings"}
if not required.issubset(config.keys()):
missing = required - config.keys()
raise ValueError(f"Missing required keys: {missing}")
return config
```
<!-- </pattern-error-handling> -->Formatting and style rules:
## Style Conventions
* Indentation: 4 spaces (no tabs)
* Line length: 88 characters (Black formatter default)
* Quotes: Double quotes for strings, single for dict keys
* Imports: Organized by isort with Black-compatible settings
* Trailing commas: Use in multi-line collections
* Type hints: Use modern syntax (`list[str]` not `List[str]`)Specify tools and configurations:
## Linting
All Python code MUST pass Ruff checks:
<!-- <config-ruff> -->
```toml
[tool.ruff]
line-length = 88
target-version = "py311"
[tool.ruff.lint]
select = ["E", "F", "I", "N", "W", "UP"]
ignore = ["E501"] # Line too long (handled by formatter)
```
<!-- </config-ruff> -->
Run: `ruff check . --fix`Define test expectations:
## Testing Requirements
* Coverage: Minimum 80% line coverage
* Test location: `tests/` directory mirroring `src/` structure
* Test naming: `test_*.py` files, `test_*` functions
* Fixtures: Use pytest fixtures for shared test data
* Mocking: Mock external dependencies (file I/O, network calls)
<!-- <example-pytest-test> -->
```python
import pytest
from pathlib import Path
from mymodule import process_file
def test_process_file_valid(tmp_path: Path) -> None:
"""Test processing valid configuration file."""
config_file = tmp_path / "config.json"
config_file.write_text('{"version": "1.0", "settings": {}}')
result = process_file(config_file)
assert result["version"] == "1.0"
assert "settings" in result
def test_process_file_missing(tmp_path: Path) -> None:
"""Test handling of missing configuration file."""
config_file = tmp_path / "missing.json"
with pytest.raises(FileNotFoundError):
process_file(config_file)The applyTo field uses glob patterns to match files:
*- Matches any characters except/**- Matches any characters including/(recursive)?- Matches single character[abc]- Matches any character in brackets{a,b}- Matches eitheraorb
# Single file extension
applyTo: '**/*.py'
# Multiple extensions
applyTo: '**/*.py, **/*.ipynb'
# Specific directory
applyTo: '**/src/**/*.ts'
# Specific path pattern
applyTo: '**/.copilot-tracking/plans/*.md'
# Exclude pattern (handled by negative patterns in schema-mapping.json)
# Not directly in applyTo, but can be configuredVerify your glob pattern matches intended files:
# PowerShell
Get-ChildItem -Path . -Recurse -Include *.py
# Bash
find . -name "*.py"Before submitting your instructions file, verify:
- File uses
.instructions.mdextension - File starts with YAML frontmatter between
---delimiters - File ends with single newline character (EOF)
- No trailing whitespace on any lines
- Uses UTF-8 encoding
- Valid YAML between
---delimiters -
descriptionfield present and descriptive (10-200 chars) -
applyTofield with valid glob pattern (if auto-applied) -
versionfollows semantic versioning format (if present) - No trailing whitespace in values
- Clear H1 title describing target
- Overview/scope section
- Core standards with RFC 2119 keywords
- Naming conventions documented
- Code examples wrapped in XML-style blocks
- Anti-patterns section with alternatives
- Validation/testing requirements
- Attribution footer present
- All examples are syntactically correct
- Examples include necessary imports/context
- Both positive and negative examples provided
- Examples wrapped in XML-style blocks with unique names
- Code blocks have language tags
- Inline comments explain key points
- Markdown quality (see Common Standards - Markdown Quality)
- XML-style blocks properly formatted (see Common Standards - XML-Style Blocks)
- RFC 2119 keywords used consistently (see Common Standards - RFC 2119)
- Glob pattern in
applyTois valid and tested - All file references point to existing files
- External links are valid and accessible
- Tool/command references are correct
- No conflicts with existing instructions files
- Aligns with
.github/copilot-instructions.md - Follows repository conventions
- Compatible with existing instructions
- Does not duplicate existing instruction functionality
- Glob pattern doesn't conflict with other instructions
See AI Artifacts Common Standards - Common Testing Practices for testing guidelines. For instructions specifically:
- Verify
applyToglob pattern matches intended files - Test all code examples execute correctly
- Have Copilot generate code following your instructions
- Validate specified linting/validation commands work
Glob patterns that only match root directory or contain syntax errors cause matching failures. Use the **/ prefix for recursive matching (e.g., **/*.py for all Python files recursively).
Multiple instruction files with overlapping glob patterns cause ambiguity. Make patterns more specific (e.g., **/tests/**/*.py vs **/*.py) or ensure they target distinct file sets.
For additional common issues (XML blocks, markdown, directives), see AI Artifacts Common Standards - Common Issues and Fixes.
Run these commands before submission (see Common Standards - Common Validation):
npm run lint:frontmatternpm run lint:mdnpm run spell-checknpm run lint:md-links
All checks MUST pass before merge.
- AI Artifacts Common Standards - Shared standards for all contributions
- Contributing Custom Agents - AI agent configuration files
- Contributing Prompts - Workflow-specific guidance
- Pull Request Template - Submission requirements
See AI Artifacts Common Standards - Getting Help for support resources. For instructions-specific assistance:
- Review existing examples in
.github/instructions/{collection-id}/(the conventional location for instruction files) - Test glob patterns using file search commands
- Use
prompt-builder.agent.mdagent for assistance
🤖 Crafted with precision by ✨Copilot following brilliant human instruction, then carefully refined by our team of discerning human reviewers.