pub(crate) fn resolve_bundle_components(
mstore: &Store,
identity_store: &Store,
bundle_id: &str,
) -> Result<ResolvedComponents, String>Expand description
Resolve what a bundle actually contains, from db_bundle_skills_ref.
Phase 0b of SPEC_INSTRUCTION_AND_MEMORY_PORTABILITY_2026_09_09.md. Before
this, export read the inline bundle.skills column
while agent launch read the ref tables (write_agent_config_files in
app_api/agent_open.rs), and nothing kept the two in step — so a skill
bound in Memory → Skills ran at launch but exported as an empty skills/
directory, with no warning. One
resolver, used by every export path, is what stops that recurring.
Scope note: this is deliberately narrower than effective_skills,
which additionally unions an agent’s own binds, globals and the legacy
blob. Those answer “what does this agent run with”;
this answers “what is in this bundle”, which is what an ABF describes. The
two are not meant to be equal, only to agree about the bundle’s own
contribution.
managed_list returns the whole catalog with a bound_to_bundle flag
rather than just the bound rows, hence the filter; and because it joins
through the catalog table, a ref whose catalog row has been deleted
resolves to nothing rather than reporting itself. skill_delete purges
refs (managed_delete in
storage/managed.rs), so that state is not reachable through the app
within one channel — but no FK enforces it: the ref tables’ catalog FK was
dropped in schema v34, once the catalog moved to identity_store.