Skip to content

Meta-skill namespace collision: a catalog skill named 'onboarding' fights the embedded praxis-onboarding #52

Description

@anujhydrabadi

Bug

The embedded praxis-onboarding meta-skill (multi-file tree, internal/skillinstall/embedded/praxis-onboarding/) and a hypothetical server catalog skill named onboarding collide: Skill.PrefixedName() = "praxis-" + name (internal/skillcatalog/skillcatalog.go:67) maps onboardingpraxis-onboarding — the same install dir.

Precedence is then inconsistent:

  • praxis login installs the embedded meta-skill first, then installFetchedCatalog (cmd/login_setup.go:314) overwrites the dir and replaces the receipt entry (upsert keyed on SkillName+Harness) → server version wins on disk.
  • praxis updateskillinstall.Refresh() (internal/skillinstall/installer.go:386) sees the receipt entry, isTreeSkill is unconditionally true for the name (embedded.go:35), and rewrites from the embed → embedded version silently clobbers the server content.
  • IsMetaSkill (dummy.go:392) is always true for the name → logout/profile-switch never removes the server version.

Which content is on disk depends on the last command run. Nothing prevents a catalog skill claiming a meta-skill's name — this also applies to catalog skills named praxis or memory (→ praxis-memory).

Suggested fix

Reserve the meta-skill namespace:

  1. In installFetchedCatalog, skip (with a warning) any catalog skill whose PrefixedName() collides with MetaSkillNames() — embedded meta-skills always win locally.
  2. Optionally: server-side, forbid creating org/personal skills named praxis, memory, onboarding (agent-factory validation), so authors find out at creation time rather than at install time.
  3. Add a test: catalog bundle containing onboarding → install skips it, receipt untouched, embedded content intact after login AND after update.

Found during the praxis skills/gateway audit (2026-07-06).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions