Note: filed here because the affected component's repo (microsoft/amplifier-bundle-skills, tool-skills module) has issues disabled. The evidence cites that repo's source.
Problem
Documentation (the skills-instructions context injected into every session, and the authoring guide) states that local skill dirs (.amplifier/skills/ workspace, ~/.amplifier/skills/ user, AMPLIFIER_SKILLS_DIR) are discovered by default and take priority over bundle-shipped skills.
In practice, when any bundle mounts tool-skills with config.skills (as this repo's own behaviors/skills.yaml does), local dirs are silently never scanned, and there is no supported way for a user to override/customize a bundle-shipped skill (e.g. fork /council with a modified roster).
Evidence (from tool-skills source)
Paths relative to modules/tool-skills/amplifier_module_tool_skills/:
__init__.py:86-123 — _resolve_skill_sources() is a strict if/elif chain: when config["skills"] is present, get_default_skills_dirs() is never called. Default local-dir discovery is replaced, not merged. AMPLIFIER_SKILLS_DIR is dead for the same reason (discovery.py:437-460 only runs in the fallback branch).
discovery.py:392-434 (discover_skills_multi_source) — name collisions are strictly first-registered-wins (if name not in all_skills); no priority tiers.
__init__.py:596-603 — runtime load_skill(source=...) registration is session-memory only (no persistence anywhere), and on name collision the incumbent mount-time skill always wins, so it cannot be used to shadow either.
behaviors/skills.yaml:14-16 — this bundle's behavior sets config.skills to only the remote git source, despite its description mentioning workspace and user skills; combined with the above, user dirs are excluded from every session composed with this behavior.
Net effect: the documented priority table (workspace > user > bundle) only applies in sessions where no bundle configures skills — which excludes any session using this bundle's behavior. Users cannot shadow a bundle skill by name at all.
Workaround found (fragile)
Composition deep-merge concatenates list config parent-first (amplifier-foundation dicts/merge.py). A user can declare tool-skills with config.skills: ["/home/<user>/.amplifier/skills"] in their own behavior YAML and order it before the skills behavior in bundle.app in settings.yaml, making the local dir the first registered source. This works but relies on undocumented compose-order semantics and is per-user manual surgery.
Proposed fix
Have _resolve_skill_sources() always prepend get_default_skills_dirs() to configured sources instead of the current replace semantics — restoring the documented priority (workspace > user > env > bundle) and enabling intentional user-side skill shadowing. Alternatively: an explicit, documented settings surface for user skill sources with priority.
Drawbacks / considerations for the fix
- Prepend-by-default enables silent shadowing: a stale local fork or accidental name collision quietly replaces bundle behavior in every session. Mitigation: log shadowing at mount, and have
load_skill(info=...) report the shadowed path alongside the winner.
- Fork skills spawn sub-sessions that re-resolve sources — the fix must apply consistently to spawned/delegated sessions or skill resolution diverges between parent and child.
- At minimum, if replace semantics are kept, the docs (skills-instructions context, authoring guide, and this bundle's behavior description) should be corrected to say local dirs are NOT scanned when a bundle supplies
config.skills.
Note: filed here because the affected component's repo (microsoft/amplifier-bundle-skills, tool-skills module) has issues disabled. The evidence cites that repo's source.
Problem
Documentation (the skills-instructions context injected into every session, and the authoring guide) states that local skill dirs (
.amplifier/skills/workspace,~/.amplifier/skills/user,AMPLIFIER_SKILLS_DIR) are discovered by default and take priority over bundle-shipped skills.In practice, when any bundle mounts tool-skills with
config.skills(as this repo's ownbehaviors/skills.yamldoes), local dirs are silently never scanned, and there is no supported way for a user to override/customize a bundle-shipped skill (e.g. fork/councilwith a modified roster).Evidence (from tool-skills source)
Paths relative to
modules/tool-skills/amplifier_module_tool_skills/:__init__.py:86-123—_resolve_skill_sources()is a strict if/elif chain: whenconfig["skills"]is present,get_default_skills_dirs()is never called. Default local-dir discovery is replaced, not merged.AMPLIFIER_SKILLS_DIRis dead for the same reason (discovery.py:437-460only runs in the fallback branch).discovery.py:392-434(discover_skills_multi_source) — name collisions are strictly first-registered-wins (if name not in all_skills); no priority tiers.__init__.py:596-603— runtimeload_skill(source=...)registration is session-memory only (no persistence anywhere), and on name collision the incumbent mount-time skill always wins, so it cannot be used to shadow either.behaviors/skills.yaml:14-16— this bundle's behavior setsconfig.skillsto only the remote git source, despite its description mentioning workspace and user skills; combined with the above, user dirs are excluded from every session composed with this behavior.Net effect: the documented priority table (workspace > user > bundle) only applies in sessions where no bundle configures skills — which excludes any session using this bundle's behavior. Users cannot shadow a bundle skill by name at all.
Workaround found (fragile)
Composition deep-merge concatenates list config parent-first (
amplifier-foundationdicts/merge.py). A user can declaretool-skillswithconfig.skills: ["/home/<user>/.amplifier/skills"]in their own behavior YAML and order it before the skills behavior inbundle.appin settings.yaml, making the local dir the first registered source. This works but relies on undocumented compose-order semantics and is per-user manual surgery.Proposed fix
Have
_resolve_skill_sources()always prependget_default_skills_dirs()to configured sources instead of the current replace semantics — restoring the documented priority (workspace > user > env > bundle) and enabling intentional user-side skill shadowing. Alternatively: an explicit, documented settings surface for user skill sources with priority.Drawbacks / considerations for the fix
load_skill(info=...)report the shadowed path alongside the winner.config.skills.