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() returns None for an unresolvable include, and the include is then discarded. No warning, no error, no mention in bundle 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.include resolves 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=skills form that foundation itself uses in behaviors/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.
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.includeand atool-skillssource — 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: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-skillsconfig 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:
So
@<ns>:skillsresolved to<repo>/behaviors/skills, and<ns>:context/<file>.mdto<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:
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.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:
context.includeresolves to nothing — an error, or at minimum a warning naming the path that was tried.bundle show— list declared-but-unresolved includes and skills sources rather than omitting them.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/<file>.mdgit+<url>#subdirectory=skillsform that foundation itself uses inbehaviors/agents.yamlBoth verified working in the same container, by the same quote-it-back check that caught the failure.
Why it is filed here
microsoft/amplifier-foundationhas 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.