Skip to content

[bug] pull removes root skills without a word when roles or projects take effect #911

Description

@SaulMoro

Description

In role or project mode the root skills/ is the tag catalog and is not delivered by default (design doc, "Skills keep one difference"; pinned by still does not deliver root skills by default in role mode). That part is intended. What is wrong is how a member finds out: they don't. When a member picks a role or project, pull deletes the root skills it installed earlier. It does the same when an admin just adds manifest/projects.yaml, and then it hits members who never ran --project too. The only record is a debug line that calls the skills "excluded", and the summary says No resources to sync.

pullForScope                                          src/pull.ts
  resolveResourceNamespaces                           src/resource-namespaces.ts:57
    team has projects.yaml  →  project mode, even with no active project
  resolveDesiredSkills                                src/resources/desired.ts:242
    scanRoleAwareSkills: active namespaces only       src/resources/desired.ts:198   (root = tag catalog, by design)
  Step 3b: installed skill not in the desired set     src/pull.ts:1296
    remove(skillDir)
    log.debug(`Removed excluded skill …`)             only visible with --verbose, and wrong: nothing was excluded
  "No resources to sync"

Two doc passages say the opposite, which makes the removal look like a bug:

  • docs/designs/multi-project-management.md:229: <type>/ root, shared with everyone. The skills exception is 40 lines later.
  • docs/usage-guide.md:239 (docs/usage-guide.zh-CN.md:223): a member with no project "still get[s] common". They don't, unless a role lists common. With projects.yaml present and no role, pull delivers no skills at all.

Other types are fine: root rules, agents, CLAUDE.md fragments and docs are delivered with a project active.

Expected: pull names the skills it removes and says how to get a root skill back.

Proposed fix, in Step 3b:

   if (!options.dryRun && desiredSkillNames && knownRepoSkillNames) {
     const baseDir = resolveBaseDir(localConfig);
+    const removedSkills = new Set<string>();
     …
         await remove(skillDir);
-        log.debug(`Removed excluded skill ${dir} from ${tool}`);
+        removedSkills.add(dir);
+        log.debug(`Removed skill ${dir} from ${tool}: no longer delivered here`);
     …
+    if (removedSkills.size > 0) {
+      const hint = roleContext ? ' While the team uses roles or projects, root skills arrive only through a tag: `teamai tags subscribe <tag>`.' : '';
+      log.info(`[${scopeLabel}] Removed ${removedSkills.size} skill(s) no longer delivered here: ${[...removedSkills].join(', ')}.${hint}`);
+    }
   }

Plus a pull-namespace-override test: install lonely with no role, pull as frontend, and assert that the skill is gone and an info line names it and teamai tags subscribe. Fix the two doc lines above, and add a bullet to the usage guide's multi-project section, in both languages. cleanupInactiveNamespaceSkills (src/pull.ts:270) removes namespace skills just as quietly; the same one-line summary would cover it.

Not proposed here: delivering root skills by default in role/project mode, or at least to members with no project. That would change the design, so it is for the maintainers to decide.

Reproduction

  1. Team repo with teamai.yaml and skills/shared-skill/SKILL.md. A member runs teamai init <url>, then teamai pull: new: shared-skill.
  2. Add manifest/projects.yaml with one project (id: svc-a, resources: { skills: [svc-a] }) and push it.
  3. The member runs teamai pull again, with no --project:
✔ [project] Team repo: 1 file(s) changed
ℹ [project] No resources to sync

.claude/skills/shared-skill is gone. teamai pull --verbose shows [debug] Removed excluded skill shared-skill from claude. init --project svc-a on a fresh machine gives Synced 1 skills … new: svc-a-skill and no shared-skill.

Environment

  • OS: macOS 27.0
  • Node.js: v24.21.0
  • teamai: 0.22.0 (repro); fix and test on main at 417e704
  • Provider: git
  • AI tool(s): Claude Code

Logs

Where it was found

Seen in three separate sandbox setups while testing multi-project layouts for #908. Reproduced with the real CLI in a sandbox with a bare git team repo. The proposed fix went red then green in pull-namespace-override.test.ts. The pull suites pass (23 files, 304 tests), and a real-CLI run of step 3 prints Removed 1 skill(s) no longer delivered here: shared-skill. ….

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions