Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/INVENTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ This file is the exact path inventory for the live GitHub Copilot catalog in thi
- `.github/instructions/awesome-copilot-kubernetes-manifests.instructions.md`
- `.github/instructions/awesome-copilot-shell.instructions.md`
- `.github/instructions/internal-bash.instructions.md`
- `.github/instructions/internal-copilot-agent-authoring.instructions.md`
- `.github/instructions/internal-copilot-skill-reference-authoring.instructions.md`
- `.github/instructions/internal-docker.instructions.md`
- `.github/instructions/internal-github-action-composite.instructions.md`
- `.github/instructions/internal-github-actions.instructions.md`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Treat this agent plus `.github/skills/internal-agent-sync-global-copilot-configs
- Treat this repository as the source of truth for the managed sync baseline.
- Start in `plan` by default. Move to `apply` only on explicit request and only when the plan is conflict-safe.
- Keep target assumptions narrow and let the paired skill own the mirrored-scope and plan-file details.
- Preserve target `local-*` assets plus any consumer-owned `.github/local-github-instructions-overrides.md` file, exclude repository-owned `internal-sync-*` resources from mirroring, and keep root-guidance files layered according to the paired skill contract.
- Preserve target `local-*` assets plus any consumer-owned `.github/copilot-instructions.override.md` file, exclude repository-owned `internal-sync-*` resources from mirroring, and keep root-guidance files layered according to the paired skill contract.
- When the source baseline contains approved imported-asset override registries or replay patches, mirror them as source-managed governance assets; do not recreate target-only hidden forks or ad hoc local edits to imported upstream resources.
- When repository-root `LESSONS_LEARNED.md` is in scope, ensure the target has it and keep it structurally aligned with the source contract while preserving or migrating target-authored lesson rows through the paired skill workflow.
- Sync only the managed cross-repository baseline declared by the paired skill contract; do not expand beyond that scope unless the user explicitly asks for more.
Expand All @@ -52,7 +52,7 @@ Treat this agent plus `.github/skills/internal-agent-sync-global-copilot-configs
## Routing

- Use this agent for consumer-repository baseline propagation, drift assessment, `plan`, and `apply` runs.
- Use this agent when the target must inherit the current bridge model around `AGENTS.md`, `.github/copilot-instructions.md`, `.github/local-github-instructions-overrides.md`, `.github/INVENTORY.md`, and repository-root `LESSONS_LEARNED.md`.
- Use this agent when the target must inherit the current bridge model around `AGENTS.md`, `.github/copilot-instructions.md`, `.github/copilot-instructions.override.md`, `.github/INVENTORY.md`, and repository-root `LESSONS_LEARNED.md`.
- Do not use this agent for source-side catalog redesign, agent or skill authoring, or governance restructuring in this repository; recommend `internal-planning-leader` instead.
- Do not use this agent for routine local execution once the sync contract is already settled and only a small target-local edit remains; recommend the appropriate executor for that repository instead.
- When current platform behavior is the deciding factor, validate it through `internal-copilot-docs-research` before changing the sync policy.
Expand All @@ -73,7 +73,7 @@ Treat this agent plus `.github/skills/internal-agent-sync-global-copilot-configs

- Target analysis and selected mode
- Root-guidance alignment strategy and `LESSONS_LEARNED.md` sync status
- Preserved `local-*` assets, `.github/local-github-instructions-overrides.md` status, and target-only cleanup decisions
- Preserved `local-*` assets, `.github/copilot-instructions.override.md` status, and target-only cleanup decisions
- Boundary or approval decisions that affected the selected mode
- Validation results, remaining blockers, and the completion-report sections
- When present, the completion report should name the used agents, instructions, skills, and other resources and explain why they were relevant
8 changes: 4 additions & 4 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ You are an expert software and platform engineer. Protect correctness, security,
4. Matching `.github/instructions/*.instructions.md` files provide scoped or domain-specific guidance and may override defaults inside their declared scope.
5. Skills and agents are on-demand operational assets; use them only when relevant.
6. `.github/INVENTORY.md` is the live catalog of managed assets and is never replaced by `AGENTS.md`.
7. If `.github/local-github-instructions-overrides.md` exists, read it before relying on synced repo-wide defaults; it is the consumer-local exception layer authorized by `AGENTS.md`.
7. If `.github/copilot-instructions.override.md` exists, read it before relying on synced repo-wide defaults; it is the consumer-local exception layer authorized by `AGENTS.md`.

- `internal-sync-*` assets stay sync-specific and must not become second canonical homes for repository-wide policy.
- When repository-wide defaults change, update `AGENTS.md` first, then refresh this file, then realign narrower governance assets that reference the change.
- When source-managed guidance from this repository is mirrored into consumer repositories, phrase source-side rules conditionally so they remain true in targets and do not imply that the target repository is the source of truth.
- `.github/local-github-instructions-overrides.md` may override synced defaults from `AGENTS.md` or this file only when the exception makes the conflict, scope, reason, and required disclosure explicit.
- If `.github/local-github-instructions-overrides.md` exists but declares no active overrides, keep following the synced baseline.
- When following a local override instead of the synced baseline, say that a consumer-local exception is in effect and cite `.github/local-github-instructions-overrides.md`.
- `.github/copilot-instructions.override.md` may override synced defaults from `AGENTS.md` or this file only when the exception makes the conflict, scope, reason, and required disclosure explicit.
- If `.github/copilot-instructions.override.md` exists but declares no active overrides, keep following the synced baseline.
- When following a local override instead of the synced baseline, say that a consumer-local exception is in effect and cite `.github/copilot-instructions.override.md`.
- Do not treat the local override file as inventory or as a replacement for the bridge, projection, and catalog split.

## Language Projection
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Local GitHub Instructions Overrides
# Copilot Instructions Override

This file is the consumer-local exception layer authorized by `AGENTS.md` and referenced by `.github/copilot-instructions.md`.

In the standards repository it lives as `.github/local-github-instructions-overrides.md.template`.
Sync materializes that template into consumer repositories as `.github/local-github-instructions-overrides.md`.
In the standards repository it lives as `.github/copilot-instructions.override.md.template`.
Sync materializes that template into consumer repositories as `.github/copilot-instructions.override.md`.
After materialization, the target repository owns the local exceptions declared there.

## Status
Expand Down Expand Up @@ -32,5 +32,5 @@ Copy this block for each active exception and replace the placeholders.
- `Baseline rule`: `<quote or summarize the synced rule being overridden>`
- `Local scope`: `<paths, file families, workflows, or request types>`
- `Reason`: `<why this repository needs the exception>`
- `Required disclosure`: `Consumer-local exception in effect from .github/local-github-instructions-overrides.md: <short disclosure>`
- `Required disclosure`: `Consumer-local exception in effect from .github/copilot-instructions.override.md: <short disclosure>`
- `Local instruction`: `<the replacement behavior that applies in the declared scope>`
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
description: Repository-owned Copilot agent authoring guardrails for boundary clarity, paired-asset coherence, and minimal duplication.
applyTo: ".github/agents/internal-*.agent.md,.github/agents/local-*.agent.md"
---

# Copilot Agent Authoring Instructions

## Workflow

- Load `internal-agent-development` before planning or editing a repository-owned agent, or before redefining the boundary between an agent, skill, prompt, and instruction.
- When the agent depends on a paired skill or local references, inspect those assets before finalizing and fix only the necessary drift in the same change.

## Cohesion

- Keep route, boundary, tool contract, and output expectations in the agent.
- Keep reusable procedure in paired skills and deep reusable detail in references.
- If a paired skill or reference owns the detailed contract, keep the agent summary-level and remove re-listed subtopics.
- Use `## Mandatory Engine Skills` only for required engines and `## Optional Support Skills` only for conditional helpers.
- Use `## Skill Usage Contract` only when declared support skills are genuinely conditional.
- Treat `## Preferred/Optional Skills` as legacy and do not introduce it in repository-owned agents.

## Validation

- Re-check frontmatter alignment, declared skills, and paired-bundle drift before finishing.
- Run the closest existing catalog validation that covers the touched agent.
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
description: Repository-owned skill reference guardrails for deep reusable detail without duplicating paired agent or SKILL.md contracts.
applyTo: ".github/skills/internal-*/references/**/*.md,.github/skills/local-*/references/**/*.md"
---

# Copilot Skill Reference Authoring Instructions

## Workflow

- Use references as the deep owner for reusable tables, templates, and detailed checklists.
- When a reference change rewrites the paired bundle boundary, load `internal-skill-creator` and `internal-agent-development` as needed instead of inventing a parallel split.
- When editing a deep reference, inspect the paired `SKILL.md` and any paired agent before finalizing and fix only the necessary drift in the same change.

## Cohesion

- Keep route and boundary language in the paired agent.
- Keep reusable workflow, anti-scope, and validation posture in `SKILL.md`.
- Use references as the deep owner for reusable tables, templates, and detailed checklists.
- Do not copy the same deep material back into `SKILL.md` or the paired agent.
- If a reference becomes the canonical detail owner, trim matching duplication from the paired bundle in the same change.

## Validation

- Re-check local links and paired-bundle drift before finishing.
- Run the closest existing skill or catalog validation that covers the touched bundle.
51 changes: 51 additions & 0 deletions .github/scripts/lib/catalog_checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ def run_consistency_checks(root: Path, include_token_risks: bool = False) -> lis
findings.extend(check_inventory_matches_filesystem(root))
findings.extend(check_bridge_references(root))
findings.extend(check_internal_agent_contracts(root))
findings.extend(check_repo_owned_agent_sections(root))
findings.extend(check_duplicate_frontmatter_names(root))
findings.extend(check_source_local_assets(root))
findings.extend(check_imported_asset_overrides(root))
Expand Down Expand Up @@ -191,6 +192,56 @@ def check_internal_agent_contracts(root: Path) -> list[Finding]:
return findings


def check_repo_owned_agent_sections(root: Path) -> list[Finding]:
findings: list[Finding] = []
agents_root = root / ".github/agents"
if not agents_root.exists():
return findings

for path in sorted(agents_root.glob("*.agent.md")):
if not path.is_file() or not path.name.startswith(("internal-", "local-")):
continue

relative_path = path.relative_to(root).as_posix()
text = read_text(path)

if "## Preferred/Optional Skills" in text:
findings.append(
Finding(
severity="blocking",
code="repo-owned-agent-legacy-skill-heading",
path=relative_path,
message=(
"Repository-owned agents must use `## Optional Support Skills` instead of the legacy "
"`## Preferred/Optional Skills` heading."
),
suggestion=(
"Replace the legacy heading and keep `## Skill Usage Contract` only when support "
"skills are genuinely conditional."
),
)
)

if "## Skill Usage Contract" in text and "## Optional Support Skills" not in text:
findings.append(
Finding(
severity="blocking",
code="repo-owned-agent-skill-usage-without-optional-support",
path=relative_path,
message=(
"Repository-owned agents should not keep `## Skill Usage Contract` without an "
"`## Optional Support Skills` section."
),
suggestion=(
"Remove `## Skill Usage Contract` or add `## Optional Support Skills` only when the "
"declared skills are genuinely conditional."
),
)
)

return findings


def check_duplicate_frontmatter_names(root: Path) -> list[Finding]:
findings: list[Finding] = []
groups = {
Expand Down
4 changes: 2 additions & 2 deletions .github/scripts/lib/shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@
".github/repo-profiles.yml",
)
MANAGED_WORKFLOW_FILES = (".github/workflows/_pre-commit.yml",)
LOCAL_GITHUB_INSTRUCTIONS_OVERRIDES_TEMPLATE_PATH = ".github/local-github-instructions-overrides.md.template"
LOCAL_GITHUB_INSTRUCTIONS_OVERRIDES_PATH = ".github/local-github-instructions-overrides.md"
COPILOT_INSTRUCTIONS_OVERRIDE_TEMPLATE_PATH = ".github/copilot-instructions.override.md.template"
COPILOT_INSTRUCTIONS_OVERRIDE_PATH = ".github/copilot-instructions.override.md"
INVENTORY_PATH = ".github/INVENTORY.md"
IMPORTED_ASSET_OVERRIDES_PATH = ".github/skills/internal-agent-sync-external-resources/references/imported-asset-overrides.yaml"

Expand Down
20 changes: 10 additions & 10 deletions .github/scripts/lib/syncing.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
from .inventory import render_inventory_markdown, sections_from_catalog_paths
from .fingerprinting import HASH_ALGO, NORMALIZATION_VERSION, build_fingerprint
from .shared import (
COPILOT_INSTRUCTIONS_OVERRIDE_PATH,
COPILOT_INSTRUCTIONS_OVERRIDE_TEMPLATE_PATH,
INVENTORY_PATH,
LESSONS_PATH,
LOCAL_GITHUB_INSTRUCTIONS_OVERRIDES_PATH,
LOCAL_GITHUB_INSTRUCTIONS_OVERRIDES_TEMPLATE_PATH,
MANAGED_ROOT_FILES,
MANAGED_WORKFLOW_FILES,
SyncOperation,
Expand Down Expand Up @@ -65,25 +65,25 @@ def build_sync_plan(source_root: Path, target_root: Path) -> SyncPlan:
local_assets: list[str] = []
generated_lessons: str | None = None

local_override_template_path = source_root / LOCAL_GITHUB_INSTRUCTIONS_OVERRIDES_TEMPLATE_PATH
local_override_target_path = target_root / LOCAL_GITHUB_INSTRUCTIONS_OVERRIDES_PATH
local_override_template_path = source_root / COPILOT_INSTRUCTIONS_OVERRIDE_TEMPLATE_PATH
local_override_target_path = target_root / COPILOT_INSTRUCTIONS_OVERRIDE_PATH
if local_override_template_path.exists():
if not local_override_target_path.exists():
operations.append(
SyncOperation(
action="create",
path=LOCAL_GITHUB_INSTRUCTIONS_OVERRIDES_PATH,
path=COPILOT_INSTRUCTIONS_OVERRIDE_PATH,
reason="Source-managed local override template missing from target; create the consumer-local override scaffold.",
source_hash=sha256_file(local_override_template_path),
target_hash=None,
)
)
else:
local_assets.append(LOCAL_GITHUB_INSTRUCTIONS_OVERRIDES_PATH)
local_assets.append(COPILOT_INSTRUCTIONS_OVERRIDE_PATH)
operations.append(
SyncOperation(
action="preserve",
path=LOCAL_GITHUB_INSTRUCTIONS_OVERRIDES_PATH,
path=COPILOT_INSTRUCTIONS_OVERRIDE_PATH,
reason="Preserved consumer-owned local override layer after template materialization.",
source_hash=sha256_file(local_override_template_path),
target_hash=sha256_file(local_override_target_path),
Expand Down Expand Up @@ -384,7 +384,7 @@ def discover_source_sync_files(root: Path) -> set[str]:
files.update(all_files_under(root, ".github/agents"))
files.update(all_files_under(root, ".github/instructions"))
files.update(all_files_under(root, MANAGED_SKILL_DIR))
files.discard(LOCAL_GITHUB_INSTRUCTIONS_OVERRIDES_TEMPLATE_PATH)
files.discard(COPILOT_INSTRUCTIONS_OVERRIDE_TEMPLATE_PATH)
return {
relative_path
for relative_path in files
Expand Down Expand Up @@ -574,8 +574,8 @@ def apply_sync_plan(plan: SyncPlan, allow_dirty_target: bool = False) -> Path:
if plan.generated_lessons is None:
raise RuntimeError("Generated LESSONS_LEARNED.md content missing from sync plan.")
write_text(target_path, plan.generated_lessons)
elif operation.path == LOCAL_GITHUB_INSTRUCTIONS_OVERRIDES_PATH:
source_path = plan.source_root / LOCAL_GITHUB_INSTRUCTIONS_OVERRIDES_TEMPLATE_PATH
elif operation.path == COPILOT_INSTRUCTIONS_OVERRIDE_PATH:
source_path = plan.source_root / COPILOT_INSTRUCTIONS_OVERRIDE_TEMPLATE_PATH
copy2(source_path, target_path)
else:
source_path = plan.source_root / operation.path
Expand Down
22 changes: 15 additions & 7 deletions .github/scripts/lib/token_risks.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@ def detect_token_risks(root: Path) -> list[Finding]:
return sorted(findings, key=finding_sort_key)


def iter_repo_owned_agent_paths(root: Path) -> list[Path]:
agents_root = root / ".github/agents"
if not agents_root.exists():
return []

return [
path
for path in sorted(agents_root.glob("*.agent.md"))
if path.is_file() and path.name.startswith(("internal-", "local-"))
]


def check_bridge_overlap(root: Path) -> list[Finding]:
agents_path = root / "AGENTS.md"
copilot_path = root / ".github/copilot-instructions.md"
Expand Down Expand Up @@ -106,17 +118,15 @@ def check_duplicate_markdown_bodies(root: Path) -> list[Finding]:

def check_internal_agent_skill_list_size(root: Path) -> list[Finding]:
findings: list[Finding] = []
for path in sorted((root / ".github/agents").glob("internal-*.agent.md")):
if not path.is_file():
continue
for path in iter_repo_owned_agent_paths(root):
bullets = extract_section_bullets(read_text(path), "## Optional Support Skills")
if len(bullets) > 8:
findings.append(
Finding(
severity="non-blocking",
code="large-skill-list",
path=path.relative_to(root).as_posix(),
message=f"The internal agent declares {len(bullets)} optional support skills, which broadens live context.",
message=f"The repo-owned agent declares {len(bullets)} optional support skills, which broadens live context.",
suggestion="Keep optional skill lists tight and move generic guidance into shared skills when possible.",
)
)
Expand Down Expand Up @@ -227,9 +237,7 @@ def check_paired_agent_skill_overlap(root: Path) -> list[Finding]:
return []

findings: list[Finding] = []
for agent_path in sorted(agents_root.glob("internal-*.agent.md")):
if not agent_path.is_file():
continue
for agent_path in iter_repo_owned_agent_paths(root):

agent_text = read_text(agent_path)
mandatory_skills = [bullet.strip("`") for bullet in extract_section_bullets(agent_text, "## Mandatory Engine Skills")]
Expand Down
Loading
Loading