fix: restore skill routing disambiguation for azure-hosted-copilot-sdk - #1644
Conversation
There was a problem hiding this comment.
Pull request overview
Restores routing disambiguation for azure-hosted-copilot-sdk to prevent azure-prepare from incorrectly capturing generic Azure deploy prompts when the repo contains Copilot SDK markers (Fixes #1599).
Changes:
- Reintroduced
DO NOT USE FORand addedPREFER OVER azure-preparedisambiguation inazure-hosted-copilot-sdkskill metadata. - Updated
azure-prepareStep 0 to route based on prompt or codebase markers (e.g.,@github/copilot-sdk). - Added regression-guard unit tests and updated trigger snapshots for the new description content.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| plugin/skills/azure-hosted-copilot-sdk/SKILL.md | Restores negative/priority routing clauses and documents mandatory codebase detection markers. |
| plugin/skills/azure-prepare/SKILL.md | Expands specialized-tech routing to include codebase-marker checks, not just prompt keywords. |
| tests/azure-hosted-copilot-sdk/unit.test.ts | Adds regression guard tests requiring routing-disambiguation phrases in the description. |
| tests/azure-hosted-copilot-sdk/snapshots/triggers.test.ts.snap | Updates expected extracted keywords/triggers to match the new description text. |
48176e8 to
de97ed7
Compare
Wallace Breza (wbreza)
left a comment
There was a problem hiding this comment.
Code Review Summary
I've performed a thorough review of PR #1644. The PR addresses a critical routing regression and makes important improvements to prevent future issues. However, I found 2 medium-severity issues that should be addressed:
Issue 1: Description exceeds recommended word count guideline
File: plugin/skills/azure-hosted-copilot-sdk/SKILL.md:3
Severity: Medium
Problem: The new description contains 107 words, exceeding the recommended 60-word limit for cross-model reliability stated in .github/skills/sensei/references/SCORING.md. The guideline explicitly states: "Trim description to ≤60 words for cross-model reliability"
Evidence:
- Character count: 815 (under 1024 limit ✓)
- Word count: 107 (exceeds 60 recommendation ✗)
Suggested fix: Consider consolidating the description by:
- Removing redundant phrasing in trigger phrases
- Moving some technical details to the skill body rather than frontmatter
- Keeping only the most distinctive trigger phrases
Note: I recognize this is a deliberate trade-off for disambiguation clarity, and the updated sensei guidelines now allow exceptions for disambiguation-critical skills. However, it's worth considering if the same disambiguation can be achieved more concisely.
Issue 2: Inconsistent marker detection tables between skills
Files:
plugin/skills/azure-hosted-copilot-sdk/SKILL.md:205-210plugin/skills/azure-prepare/SKILL.md:247-250
Severity: Medium
Problem: The codebase marker detection tables are inconsistent between the two skills that need to coordinate routing:
azure-hosted-copilot-sdk lists 4 markers:
@github/copilot-sdkin package.json dependenciescopilot-sdkin package.json name or dependenciesCopilotClientin source filescreateSession+sendAndWaitin source files
azure-prepare lists only 2 markers:
@github/copilot-sdkin dependencies in package.jsonCopilotClientimport in .ts/.js source files
Impact: If azure-prepare doesn't check for all the same markers that azure-hosted-copilot-sdk expects, routing could still fail in edge cases (e.g., a project with copilot-sdk in package.json name but not as @github/copilot-sdk).
Suggested fix: Synchronize these tables so both skills use identical detection logic. Either:
- Add the missing markers to azure-prepare's table (recommended for completeness), OR
- Document why the markers differ if there's a deliberate reason
Positive Observations
✅ Core regression fix is sound: Restoring DO NOT USE FOR with proper context
✅ Test coverage improved: New regression guard tests will prevent this from happening again
✅ Process improvements: PR template, guideline updates, and CI changes address root causes
✅ Comprehensive documentation: Excellent root cause analysis in PR description
✅ All CI checks passing: 10 successful checks including ESLint, CodeQL, and all skill tests
Recommendation
The core logic changes are solid and address a real production issue. The two issues I've identified are related to consistency and guidelines compliance rather than critical bugs. I recommend:
- Fix Issue #2 (marker inconsistency) before merging - this could affect routing correctness
- Consider Issue #1 (word count) for a follow-up - not blocking if the team accepts the trade-off
Great work on the thorough root cause analysis and process improvements! 👍
|
Thanks for the thorough review Wallace Breza (@wbreza) - both issues are fixed in the latest push (4e2c024): Issue 1 (word count): Trimmed the description from 107 to 55 words (under the 60-word guideline). Removed redundant phrases and implementation details while keeping all routing-critical triggers (copilot SDK, BYOM, CopilotClient, DO NOT USE FOR clause). The removed phrases like Issue 2 (marker inconsistency): Added the 2 missing markers to azure-prepare's Check 2 table so both skills use identical detection logic:
Version bumps: azure-hosted-copilot-sdk 1.0.2->1.0.3, azure-prepare 1.1.2->1.1.3. All tests pass (19 unit + 18 trigger). |
microsoft#1599) Restore DO NOT USE FOR clause and add codebase detection to fix routing regression where azure-prepare incorrectly won on generic deploy prompts (e.g. 'Deploy this app to Azure') when the codebase contains @github/copilot-sdk. Root cause: PR microsoft#1210 (commit a1ba84c) removed the DO NOT USE FOR clause from azure-hosted-copilot-sdk description, eliminating the critical negative discriminator that prevented azure-prepare from capturing Copilot SDK deployment prompts. Changes: - azure-hosted-copilot-sdk/SKILL.md: Restore DO NOT USE FOR clause, add PREFER OVER azure-prepare directive, add Codebase Detection section with marker table (v1.0.1 -> v1.0.2) - azure-prepare/SKILL.md: Expand Step 0 to check codebase markers (not just prompt keywords) for Copilot SDK detection (v1.1.1 -> v1.1.2) - unit.test.ts: Add 2 regression guard tests requiring DO NOT USE FOR and PREFER OVER clauses to prevent silent removal - triggers.test.ts.snap: Updated snapshots for new description Fixes microsoft#1599 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…R for disambiguation Add exception to the blanket 'do not use DO NOT USE FOR' guidance: skills whose triggers overlap with broader skills (e.g., azure-prepare) MUST retain DO NOT USE FOR clauses for routing disambiguation. The previous guidance actively caused the microsoft#1599 regression — PR microsoft#1210 removed the clause while following sensei's recommendation, breaking routing for azure-hosted-copilot-sdk. Updated files: - sensei/SKILL.md: Add exception note to warning blocks - sensei/references/SCORING.md: Add disambiguation row to risk table, update pseudocode to skip warning for overlapping skills - skill-authoring frontmatter.md: Add exception for disambiguation Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- #4: Audit conditional unit tests — added warning comments to azure-quotas and azure-hosted-copilot-sdk about the fragile if(description.includes('DO NOT USE FOR')) pattern - #5: Add PR template with skill routing verification checkbox - microsoft#6: Set continue-on-error: false in test-all-integration.yml so integration test failures actually fail the workflow Part of microsoft#1599 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…comments, genericize refs - Bump sensei version 1.0.1 -> 1.0.2 - Bump skill-authoring version 1.0.0 -> 1.0.1 - Update snapshot header to jestjs.io (CI Jest version compatibility) - Fix PR template: correct integration test command, remove issue link - Update stale workflow comments to match continue-on-error: false - Remove explicit issue number references from skill and test files Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ion exception - skill-authoring Constraints: changed blanket prohibition to conditional guidance - sensei help banner: added '(unless disambiguation-critical)' qualifier - test-all-integration.yml: clarified continue-on-error comment wording Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Main branch already has sensei at version 1.0.2 from another merged PR. Our PR also modified sensei, so we need a higher version to pass the Skill Structure CI check. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Address @wbreza review feedback: - Issue 1: Trim azure-hosted-copilot-sdk description from 107 to 55 words (under 60-word guideline). Removed redundant/implementation-detail phrases while preserving all routing-critical triggers. - Issue 2: Sync codebase marker tables - added 2 missing markers to azure-prepare Check 2 (copilot-sdk in name/deps, createSession+sendAndWait) so both skills use identical detection logic. - Version bumps: azure-hosted-copilot-sdk 1.0.2->1.0.3, azure-prepare 1.1.2->1.1.3 - Updated unit test to match trimmed description. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Fix snapshot header to jestjs.io URL (CI requirement) - Bump azure-prepare 1.1.3->1.1.4 (main already at 1.1.3) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
5da5ed9 to
aaee68c
Compare
microsoft#1644) * fix: restore skill routing disambiguation for azure-hosted-copilot-sdk (microsoft#1599) Restore DO NOT USE FOR clause and add codebase detection to fix routing regression where azure-prepare incorrectly won on generic deploy prompts (e.g. 'Deploy this app to Azure') when the codebase contains @github/copilot-sdk. Root cause: PR microsoft#1210 (commit f41a5fa) removed the DO NOT USE FOR clause from azure-hosted-copilot-sdk description, eliminating the critical negative discriminator that prevented azure-prepare from capturing Copilot SDK deployment prompts. Changes: - azure-hosted-copilot-sdk/SKILL.md: Restore DO NOT USE FOR clause, add PREFER OVER azure-prepare directive, add Codebase Detection section with marker table (v1.0.1 -> v1.0.2) - azure-prepare/SKILL.md: Expand Step 0 to check codebase markers (not just prompt keywords) for Copilot SDK detection (v1.1.1 -> v1.1.2) - unit.test.ts: Add 2 regression guard tests requiring DO NOT USE FOR and PREFER OVER clauses to prevent silent removal - triggers.test.ts.snap: Updated snapshots for new description Fixes microsoft#1599 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * docs: update sensei/skill-authoring guidelines to allow DO NOT USE FOR for disambiguation Add exception to the blanket 'do not use DO NOT USE FOR' guidance: skills whose triggers overlap with broader skills (e.g., azure-prepare) MUST retain DO NOT USE FOR clauses for routing disambiguation. The previous guidance actively caused the microsoft#1599 regression — PR microsoft#1210 removed the clause while following sensei's recommendation, breaking routing for azure-hosted-copilot-sdk. Updated files: - sensei/SKILL.md: Add exception note to warning blocks - sensei/references/SCORING.md: Add disambiguation row to risk table, update pseudocode to skip warning for overlapping skills - skill-authoring frontmatter.md: Add exception for disambiguation Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chore: implement recommendations #4 #5 microsoft#6 from RCA - #4: Audit conditional unit tests — added warning comments to azure-quotas and azure-hosted-copilot-sdk about the fragile if(description.includes('DO NOT USE FOR')) pattern - #5: Add PR template with skill routing verification checkbox - microsoft#6: Set continue-on-error: false in test-all-integration.yml so integration test failures actually fail the workflow Part of microsoft#1599 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: address review feedback - version bumps, snapshot header, stale comments, genericize refs - Bump sensei version 1.0.1 -> 1.0.2 - Bump skill-authoring version 1.0.0 -> 1.0.1 - Update snapshot header to jestjs.io (CI Jest version compatibility) - Fix PR template: correct integration test command, remove issue link - Update stale workflow comments to match continue-on-error: false - Remove explicit issue number references from skill and test files Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: update blanket DO NOT USE FOR prohibition to reflect disambiguation exception - skill-authoring Constraints: changed blanket prohibition to conditional guidance - sensei help banner: added '(unless disambiguation-critical)' qualifier - test-all-integration.yml: clarified continue-on-error comment wording Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chore: bump sensei version to 1.0.3 (main already at 1.0.2) Main branch already has sensei at version 1.0.2 from another merged PR. Our PR also modified sensei, so we need a higher version to pass the Skill Structure CI check. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: trim description to 55 words, sync marker tables between skills Address @wbreza review feedback: - Issue 1: Trim azure-hosted-copilot-sdk description from 107 to 55 words (under 60-word guideline). Removed redundant/implementation-detail phrases while preserving all routing-critical triggers. - Issue 2: Sync codebase marker tables - added 2 missing markers to azure-prepare Check 2 (copilot-sdk in name/deps, createSession+sendAndWait) so both skills use identical detection logic. - Version bumps: azure-hosted-copilot-sdk 1.0.2->1.0.3, azure-prepare 1.1.2->1.1.3 - Updated unit test to match trimmed description. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: snapshot header and azure-prepare version bump - Fix snapshot header to jestjs.io URL (CI requirement) - Bump azure-prepare 1.1.3->1.1.4 (main already at 1.1.3) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Fixes #1599
Summary
Restores the
DO NOT USE FORdisambiguation clause and adds codebase detection toazure-hosted-copilot-sdk, fixing the routing regression whereazure-prepareincorrectly captured generic deploy prompts (e.g., "Deploy this app to Azure") when the codebase contains@github/copilot-sdk. Also updates the sensei and skill-authoring guidelines that caused this regression.Root Cause Analysis
The Regression (3 Layers)
Layer 1 -- Primary Cause: Commit
a1ba84c(PR #1210)PR #1210 ("Reduce char count of existing skills", merged 2026-03-10) removed the
DO NOT USE FOR: general web apps without copilot SDKclause fromazure-hosted-copilot-sdk's frontmatter description. This clause was the critical negative discriminator that told the LLM routing engine: "do not select this skill for generic deploy prompts -- preferazure-prepareinstead." Without it,azure-preparewins on prompts like "Deploy this app to Azure" because it has"deploy to Azure"as a direct trigger phrase.Layer 2 -- Contributing:
azure-prepareonly checked prompt keywordsazure-prepare's Step 0 routing logic only examined prompt keywords (e.g., "copilot SDK" in the user's message), not codebase markers (e.g.,@github/copilot-sdkinpackage.json). The failing test prompt "Deploy this app to Azure" contains no copilot keywords -- they exist only in the codebase fixture (copilot-sdk-app-package.json).Layer 3 -- Contributing: Detection timing
The regression was introduced at commit
a1ba84c(2026-03-10) but only detected when the nightly integration test run happened to tag commitf47b744(2026-03-30) as failing. The actual causal change is 20 days older than the tagged failing commit.Commit Trace
a1ba84cDO NOT USE FORfrom descriptionf47b744Engineering Process Gap Analysis
Why This Regression Shipped
6 specific gaps allowed this regression to merge undetected:
Gap 1: Integration tests do not run on PRs
test-all-integration.ymlonly runs on nightly schedule (Mon-Fri cron) or manual triggertest-all-skills.yml(non-integration: trigger tests + unit tests)integration.test.ts:89-102) would have caught this immediately if it ran on the PRGap 2: Unit test was a no-op for removed clauses
unit.test.ts:118-126used a conditional check:if (description.includes("DO NOT USE FOR"))-- this passes silently when the clause is removed entirelyDO NOT USE FORandPREFER OVER azure-prepareclausesGap 3: Copilot PR reviewer gave incorrect assessment
DO NOT USE FORclauses were "adding length without routing benefit"azure-prepareGap 4: Sensei/skill-authoring guidelines actively DISCOURAGE
DO NOT USE FOR.github/skills/sensei/SKILL.mdwarned againstDO NOT USE FORas "risky in multi-skill environments".github/skills/skill-authoring/references/guidelines/frontmatter.mdsaid "Do NOT add DO NOT USE FOR clauses"azure-prepareGap 5: No automated rule validates disambiguation for overlapping skills
azure-preparemaintain disambiguation clausesGap 6: Waza evals run separately from PR CI
eval.ymlworkflow runs waza evaluations on a separate scheduleWhat the Team Could Have Done Differently
workflow_dispatchoftest-all-integration.ymlwould have caught the failureDO NOT USE FORaffected routing for the known integration test scenariosDO NOT USE FORis routing-critical -- The clause wasn't decorative; it was a routing instruction to the LLM. Removing it without running routing tests was the equivalent of removing an API permission check without running auth tests.Changes Made
Skill Fixes
1.
plugin/skills/azure-hosted-copilot-sdk/SKILL.md(v1.0.1 -> v1.0.2)DO NOT USE FOR: general web apps without copilot SDK, standard App Service deployments, Azure Functions without SDKPREFER OVER azure-prepare when codebase contains @github/copilot-sdk2.
plugin/skills/azure-prepare/SKILL.md(v1.1.1 -> v1.1.2)@github/copilot-sdkin package.json -> hand off toazure-hosted-copilot-sdk)Test Fixes
3.
tests/azure-hosted-copilot-sdk/unit.test.tsdescription contains DO NOT USE FOR clause to disambiguate from azure-preparedescription contains PREFER OVER clause for codebase-based routing4.
tests/azure-hosted-copilot-sdk/__snapshots__/triggers.test.ts.snapGuideline Fixes (Addresses Gap 4)
5.
.github/skills/sensei/SKILL.mdDO NOT USE FORwarning: skills whose triggers overlap with broader skills MUST retain the clause6.
.github/skills/sensei/references/SCORING.mdscoreSkill()now checks for overlapping triggers before warningcollectSuggestions()to not suggest removal for disambiguation-critical skills7.
.github/skills/skill-authoring/references/guidelines/frontmatter.mdProcess Improvements (Recommendations #4-6)
8.
.github/PULL_REQUEST_TEMPLATE.md(NEW)9.
.github/workflows/test-all-integration.ymlcontinue-on-error: truetofalseon integration test step10.
tests/azure-quotas/unit.test.tsTest Results
Recommendations to Prevent Future Regressions
Update sensei/skill-authoring guidanceCriticalAudit conditional unit testsHighAdd PR template checkboxMediumSetcontinue-on-error: falseMedium