microsoft / microsoft/amplifier
A behavior's context include and skills source both fail silently when the namespace roots at the behavior's directory
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 3.1k
- Forks
- 261
- Avg merge
- 3h 28m
- Merged PRs (30d)
- 13
Description
Summary
A bundle can compose cleanly, pass schema validation and its whole test suite, and contribute nothing. Both of the surfaces that carry guidance — a context.include and a tool-skills source — drop out without a word when their path does not resolve.
The rooting rule behind it is defensible. The silence is not.
Measured, not inferred
Installed the documented way — amplifier bundle add <url>#subdirectory=behaviors/<name>.yaml --app — then ran a real single-turn session that asked the model to quote text which could only exist if the mechanism worked:
LINE1: ABSENT # the context file was not in the system instructions
LINE2: SKILL-ABSENT # load_skill -> "Skill '<name>' not found"
Before that run, every local check was green and every one of them was structurally incapable of observing the failing stage: bundle schema validation PASS, 265 unit tests OK, and a probe confirming the tool-skills config merge is append-not-replace. All true. None able to see it.
Root cause
A behavior installed as a subdirectory file gets its namespace rooted at that file's directory, not the repo root:
source_base_paths: {
'<bundle-name>-standalone': <repo>,
'<bundle-name>': <repo>/behaviors <-- here
}
So @<ns>:skills resolved to <repo>/behaviors/skills, and <ns>:context/<file>.md to <repo>/behaviors/context/<file>.md. Neither exists.
Foundation's own behaviors use the foundation:context/... form and work — because foundation installs as a whole bundle, so its namespace is the repo root. Copying that shape without the precondition is the trap, and the YAML looks identical either way.
Five candidate forms tested; exactly one resolves:
<ns>:context/x.md -> None
<ns>-standalone:context/x.md -> None
../context/x.md -> RESOLVES
context/x.md -> None
<ns>:../context/x.md -> None
The actual defect
resolve_context_path()returnsNonefor an unresolvable include, and the include is then discarded. No warning, no error, no mention inbundle show. A typo in a context path ships a bundle that looks entirely healthy.- An unresolvable skills source produces no diagnostic either. The skill simply never enters the catalog, and the only way to discover it is to ask a model to load it by name and watch it fail.
This is the same failure class the bundle docs are careful about elsewhere — a missing opt-in is inert by design and says so. This is inert by accident and says nothing.
What would fix it
Any one of these, in preference order:
- Fail loud at compose time when a declared
context.includeresolves to nothing — an error, or at minimum a warning naming the path that was tried. - Surface it in
bundle show— list declared-but-unresolved includes and skills sources rather than omitting them. - Same for skills sources that resolve to a directory containing no
SKILL.md.
A one-line "path X did not resolve; tried Y" would have saved this entirely.
Workaround, for anyone hitting it now
For a behavior installed via #subdirectory=behaviors/<name>.yaml:
- context: use a path relative to the behavior file —
../context/<file>.md - skills: use the
git+<url>#subdirectory=skillsform that foundation itself uses inbehaviors/agents.yaml
Both verified working in the same container, by the same quote-it-back check that caught the failure.
Why it is filed here
microsoft/amplifier-foundation has issues disabled and states it is not currently accepting external contributions, so this is filed against the ecosystem entry point. Happy to move it, and happy to attempt the fix if contributions open.
Environment: amplifier-core 1.6.1, app-cli 0.1.1. Discovered while adding a guidance layer to a third-party bundle; tracked on our side as teamwork-x8a.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at resolve_context_path() and the tool-skills source resolution path, then review the existing 265-unit-test coverage and reproduce with a behavior installed through #subdirectory=behaviors/. Done means unresolved context includes and skills sources produce a diagnostic naming the declared path and attempted resolution, with coverage for both cases.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100