fix: drop duplicate skill inventory and handle YAML block scalars in copilot executor (#578) - #583
Open
Shayne Boyer (spboyer) wants to merge 1 commit into
Open
fix: drop duplicate skill inventory and handle YAML block scalars in copilot executor (#578)#583Shayne Boyer (spboyer) wants to merge 1 commit into
Shayne Boyer (spboyer) wants to merge 1 commit into
Conversation
…copilot executor (#578) The Copilot SDK already advertises available skills to the model via SkillDirectories, so waza's synthetic <available_skills> block was a duplicate inventory. Worse, its per-skill descriptions were parsed by a line-based scanner that read only the tokens after "description:" on the same line, so a skill authored with a YAML block-scalar description (>-, >, |, |-) — as `waza new skill` scaffolds — had its indicator string surfaced as the description. Fix: * Drop the <available_skills> inventory from buildSkillSystemMessage. The message now emits only the <skill_context> block containing the target skill's full SKILL.md, and only when injectSkillBody is true. This preserves the primary-skill injection behavior while eliminating duplication with the SDK's own advertisement. * Rewrite parseSkillFrontmatter to use yaml.Unmarshal (matching how internal/skill parses frontmatter) so block-scalar name/description fields round-trip correctly. This keeps target-skill name matching robust for future callers even though the message body no longer serializes descriptions itself. Adds regression tests covering >-, >, |, and |- block scalars in both the parser and the system-message builder, and updates existing skill_injection tests to match the new behavior. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Shayne Boyer (spboyer)
requested review from
Charles Lowell (chlowell) and
Richard Park (richardpark-msft)
as code owners
September 5, 2026 13:08
Contributor
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
The changes are narrowly scoped to the Copilot SDK executor path and are backed by updated and newly added regression tests covering the reported failure modes.
Review tier: Lite
Findings: None
What changed in this PR
This pull request fixes an issue in the Copilot SDK executor where waza redundantly injected its own <available_skills> inventory (duplicating what the Copilot SDK already provides) and also mis-parsed YAML block-scalar frontmatter values in SKILL.md.
Changes:
- Removed waza-authored
<available_skills>emission so only the target skill’s<skill_context>is injected (when enabled), eliminating duplicated/malformed skill listings. - Reimplemented
parseSkillFrontmatterusingyaml.Unmarshalso YAML block scalars (>-,>,|,|-) are parsed correctly. - Updated/expanded tests to assert the inventory is absent and to cover block-scalar parsing and target-skill matchability.
| File | Description |
|---|---|
| internal/execution/copilot.go | Stops emitting a synthetic <available_skills> block and switches frontmatter parsing to yaml.Unmarshal to correctly handle YAML block scalars. |
| internal/execution/skill_injection_test.go | Updates assertions to ensure <available_skills> is absent and adds regression coverage for block-scalar frontmatter. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #578.
Problem
When
waza runuses thecopilot-sdkexecutor, the request to the model contained a duplicate<available_skills>block authored by waza itself, in addition to the skill catalog the Copilot SDK already advertises viaSkillDirectories. Worse, waza's per-skill descriptions were parsed by a line-based scanner that read only the tokens afterdescription:on the same line, so a skill authored with a YAML block-scalar description (>-,>,|,|-) — aswaza new skillscaffolds by default — surfaced the literal indicator string (e.g.>-) as the description.Fix
Two surgical changes in
internal/execution/copilot.go:<available_skills>inventory.buildSkillSystemMessagenow emits only the<skill_context>block containing the target skill's fullSKILL.md, and only wheninjectSkillBodyistrue. This preserves the primary-skill injection behavior while eliminating duplication with the SDK's own advertisement.parseSkillFrontmatterto useyaml.Unmarshal(matching howinternal/skillparses frontmatter) so block-scalarname/descriptionfields round-trip correctly. This keeps target-skill name matching robust for future callers even though the message body no longer serializes descriptions itself.Tradeoff vs. removing only the synthetic block
Dropping the block alone would have solved the user-visible issue (no duplicate inventory, no corrupted descriptions in the prompt). We additionally hardened
parseSkillFrontmatterbecause it's still on the call path for matching the target skill's name — so an author who writesname: >-\n my-skillstill resolves correctly. The parser is now correct for any future consumer that reintroduces frontmatter-driven logic.Non-Copilot executors (mock and command-line copilot-cli) are unaffected — the entire code path lives in
CopilotEngine.Regression coverage
internal/execution/skill_injection_test.go:TestBuildSkillSystemMessage_*cases flipped to assert<available_skills>is absent.TestBuildSkillSystemMessage_BlockScalarSkillIsMatchable— a skill authored withdescription: >-is still selectable as the target and its body still injects into<skill_context>.TestParseSkillFrontmatterextended with block-scalar cases:>-,>,|,|-, plus a block-scalarname:field.Verification
Co-authored-by: Copilot App 223556219+Copilot@users.noreply.github.com