Summary
The copyright header validation script (scripts/linting/Test-CopyrightHeaders.ps1) contains a critical bug that silently excludes all files under .github/ from scanning. This means every skill added to the repo (which live under .github/skills/) bypasses copyright and SPDX header enforcement entirely — both locally and in CI.
Root Cause
In the Get-FilesToCheck function (Test-CopyrightHeaders.ps1 line ~152), the exclusion logic uses:
if ($filePath -like "*$excludePath*") {
$excluded = $true
break
}
The default ExcludePaths includes .git, which produces the wildcard pattern *.git*. This matches both .git/ (intended) and .github/ (unintended), since .github contains the substring .git.
Proof: "C:\repo\.github\skills\test.py" -like "*.git*" → True
Impact
- 29 Python files in
.github/skills/experimental/powerpoint/ (14 in scripts/, 15 in tests/) are missing both copyright and SPDX headers.
- The validation report (
logs/copyright-header-results.json) shows 70 files passing with zero Python skill files appearing in results — they are completely invisible.
- CI runs this check on every PR via
pr-validation.yml → copyright-headers.yml with -FailOnMissing, but the gate is ineffective for skill files because they're silently excluded.
- Any future skill files added under
.github/skills/ would also be silently excluded.
Required Fixes
1. Fix the .git exclusion pattern (Critical)
Change the .git entry in ExcludePaths to use a boundary-aware pattern that excludes .git/ and .git\ but not .github/. Options:
- Use a separator-bounded pattern like checking for
$excludePath followed by a path separator or end of string
- Change the default entry from
.git to a more precise value (e.g., \.git\, .git/, or a regex-based approach)
- Switch from
-like wildcard matching to -match regex matching for path exclusion
2. Add missing exclusion paths
Add these to the default ExcludePaths:
| Path |
Reason |
.venv |
Python virtual environments contain third-party code that shouldn't be validated. Currently invisible due to the .git bug but will surface once that's fixed. |
__pycache__ |
Python bytecode cache directories. |
.copilot-tracking |
Gitignored working directory; currently causes 2 false positives in validation results. |
3. Add missing headers to all 29 Python skill files
All files under .github/skills/experimental/powerpoint/scripts/ and .github/skills/experimental/powerpoint/tests/ need:
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: MIT
4. Add test coverage for the exclusion logic
The Pester test file (scripts/tests/linting/Test-CopyrightHeaders.Tests.ps1) has no test cases verifying that:
.github/ paths are not excluded by the .git exclusion rule
.venv/ and __pycache__/ paths are excluded
- The exclusion logic correctly differentiates
.git (the directory) from .github (not excluded)
5. Verify CI enforcement end-to-end
After fixes, run the full validation to confirm:
- All 29 previously-invisible Python files now appear in results
- The
-FailOnMissing flag in copyright-headers.yml would catch missing headers
- No false positives from
.copilot-tracking/ or .venv/ directories
Acceptance Criteria
Files to Modify
| File |
Changes |
scripts/linting/Test-CopyrightHeaders.ps1 |
Fix .git exclusion pattern; add .venv, __pycache__, .copilot-tracking to defaults |
scripts/tests/linting/Test-CopyrightHeaders.Tests.ps1 |
Add exclusion logic boundary tests |
.github/skills/experimental/powerpoint/scripts/*.py (14 files) |
Add copyright + SPDX headers |
.github/skills/experimental/powerpoint/tests/*.py (15 files) |
Add copyright + SPDX headers |
Summary
The copyright header validation script (
scripts/linting/Test-CopyrightHeaders.ps1) contains a critical bug that silently excludes all files under.github/from scanning. This means every skill added to the repo (which live under.github/skills/) bypasses copyright and SPDX header enforcement entirely — both locally and in CI.Root Cause
In the
Get-FilesToCheckfunction (Test-CopyrightHeaders.ps1 line ~152), the exclusion logic uses:The default
ExcludePathsincludes.git, which produces the wildcard pattern*.git*. This matches both.git/(intended) and.github/(unintended), since.githubcontains the substring.git.Proof:
"C:\repo\.github\skills\test.py" -like "*.git*"→TrueImpact
.github/skills/experimental/powerpoint/(14 inscripts/, 15 intests/) are missing both copyright and SPDX headers.logs/copyright-header-results.json) shows 70 files passing with zero Python skill files appearing in results — they are completely invisible.pr-validation.yml→copyright-headers.ymlwith-FailOnMissing, but the gate is ineffective for skill files because they're silently excluded..github/skills/would also be silently excluded.Required Fixes
1. Fix the
.gitexclusion pattern (Critical)Change the
.gitentry inExcludePathsto use a boundary-aware pattern that excludes.git/and.git\but not.github/. Options:$excludePathfollowed by a path separator or end of string.gitto a more precise value (e.g.,\.git\,.git/, or a regex-based approach)-likewildcard matching to-matchregex matching for path exclusion2. Add missing exclusion paths
Add these to the default
ExcludePaths:.venv.gitbug but will surface once that's fixed.__pycache__.copilot-tracking3. Add missing headers to all 29 Python skill files
All files under
.github/skills/experimental/powerpoint/scripts/and.github/skills/experimental/powerpoint/tests/need:4. Add test coverage for the exclusion logic
The Pester test file (
scripts/tests/linting/Test-CopyrightHeaders.Tests.ps1) has no test cases verifying that:.github/paths are not excluded by the.gitexclusion rule.venv/and__pycache__/paths are excluded.git(the directory) from.github(not excluded)5. Verify CI enforcement end-to-end
After fixes, run the full validation to confirm:
-FailOnMissingflag incopyright-headers.ymlwould catch missing headers.copilot-tracking/or.venv/directoriesAcceptance Criteria
.gitexclusion pattern no longer matches.github/pathsExcludePathsdefaults include.venv,__pycache__, and.copilot-tracking.github/skills/experimental/powerpoint/have copyright and SPDX headers.gitvs.githubexclusion boundary casenpm run validate:copyrightreports all skill files and shows 100% compliancepr-validation.yml→copyright-headers.yml) catches missing headers in.github/skills/Files to Modify
scripts/linting/Test-CopyrightHeaders.ps1.gitexclusion pattern; add.venv,__pycache__,.copilot-trackingto defaultsscripts/tests/linting/Test-CopyrightHeaders.Tests.ps1.github/skills/experimental/powerpoint/scripts/*.py(14 files).github/skills/experimental/powerpoint/tests/*.py(15 files)