Skip to content

skill update does not follow skills added to or removed from an --all source #4

Closed

Description

@showxu

Summary

For a local source added with --all, skill update considers the skills recorded at add time rather than reconciling the source's current membership. Skills added later are not installed. A removed or renamed skill remains managed: edit mode leaves a broken symlink; default link mode leaves a stale canonical copy. skill doctor reports source-missing but does not repair it.

Reproduced with the current release, v0.2.1, and a fresh build of current master, b742a997851943090748575f1ad06678047039d5. Both binaries report 0.2.1.

Reproduction

All fixtures, temporary HOME, agent directories, state, caches, and temporary files were isolated under the checkout's ignored .build/. No real user installation was used.

The commands below were run in Bash. <checkout>, <repro>, and <skill-binary> shorten temporary/executable paths. For the release run, the binary was the installed skill returned by command -v skill. For master, it was built in the clean canonical checkout:

cd "<checkout>"
git rev-parse HEAD origin/master
swift build --scratch-path .build/issue-filing/build \
  --cache-path .build/issue-filing/cache --product skill

Both refs resolved to b742a997851943090748575f1ad06678047039d5; the build succeeded. The master binary was <checkout>/.build/issue-filing/build/debug/skill.

Run the following with a fresh <repro> under <checkout>/.build/issue-filing/ for each binary/mode combination. This is the executed sequence, with paths shortened and shell tracing omitted:

repro_root="<repro>"
skill_bin="<skill-binary>"
install_mode=edit

mkdir -p "$repro_root/home/.codex/skills" \
  "$repro_root/source/a" "$repro_root/source/b" \
  "$repro_root/project" "$repro_root/tmp"
cd "$repro_root/project"

skill() {
  env -i PATH=/usr/bin:/bin:/usr/sbin:/sbin \
    HOME="$repro_root/home" CODEX_HOME="$repro_root/home/.codex" \
    XDG_CONFIG_HOME="$repro_root/home/.config" \
    XDG_STATE_HOME="$repro_root/home/.local/state" \
    XDG_CACHE_HOME="$repro_root/home/.cache" TMPDIR="$repro_root/tmp" \
    "$skill_bin" "$@"
}

for skill_name in a b; do
  printf -- '---\nname: %s\ndescription: Reproduction fixture\n---\n# %s\n' \
    "$skill_name" "$skill_name" > "$repro_root/source/$skill_name/SKILL.md"
done

skill --version
skill doctor --scope user --agent codex --json
skill add "$repro_root/source" --all --scope user --agent codex --mode "$install_mode"

mkdir "$repro_root/source/c"
printf -- '---\nname: c\ndescription: Reproduction fixture\n---\n# c\n' \
  > "$repro_root/source/c/SKILL.md"
mv "$repro_root/source/b" "$repro_root/source/b2"
printf -- '---\nname: b2\ndescription: Reproduction fixture\n---\n# b2\n' \
  > "$repro_root/source/b2/SKILL.md"

skill update --scope user
skill update --scope user --all --apply
skill doctor --scope user --agent codex --json
skill list --scope user --agent codex --json
ls -l "$repro_root/home/.agents/skills"

skill remove b --scope user --agent codex
skill doctor --scope user --agent codex --json

Repeated the same sequence with install_mode=link, the default mode, in a fresh isolated directory for each binary.

Relevant output was the same on release and master:

$ skill --version
0.2.1

$ skill add <repro>/source --all --scope user --agent codex --mode edit
installed a for codex at <repro>/home/.agents/skills/a
installed b for codex at <repro>/home/.agents/skills/b

$ skill update --scope user
current a
current b

$ skill update --scope user --all --apply
current a
current b

Doctor output after update in edit mode (temporary paths shortened; JSON slash escaping normalized):

{
  "checks": [
    {
      "id": "resolved-file",
      "message": "resolved state found for global scope",
      "path": "<repro>/home/.local/state/skills/skills.resolved",
      "status": "ok"
    },
    {
      "id": "skill.codex.a",
      "message": "a for codex: edit-linked",
      "path": "<repro>/home/.agents/skills/a",
      "status": "ok"
    },
    {
      "hint": "Restore the local source path or remove the resolved entry.",
      "id": "skill.codex.b",
      "message": "b for codex: source-missing",
      "path": "<repro>/home/.agents/skills/b",
      "status": "error"
    }
  ],
  "ok": false
}

The subsequent list still contained only a and b. In edit mode, b had "installed": false and "status": "source-missing"; its symlink still targeted ../../../source/b. In link mode, b had "installed": true, "materialization": "copy-installed", and "status": "source-missing". Neither c nor b2 was installed.

Manual cleanup worked in all four runs:

$ skill remove b --scope user --agent codex
Removing b
removed <repro>/home/.agents/skills/b

The next doctor result was "ok": true, with only a managed; this cleanup did not install c or b2.

Expected Behavior

An --all source stays in sync. Applying skill update installs skills new in that source and removes skills that no longer exist, or reports them with the exact fix command. Skills selected individually retain their existing selection semantics.

Completion check: after applying skill update, c and b2 are installed, b is gone, and skill doctor reports no errors. For this fixture, the verified manual removal command is skill remove b --scope user --agent codex.

Actual Behavior

Binary Mode Managed names after update Missing new names Retained b Doctor
Release 0.2.1 edit a, b c, b2 Broken symlink source-missing; ok=false
Master b742a99 edit a, b c, b2 Broken symlink source-missing; ok=false
Release 0.2.1 link a, b c, b2 Stale copy source-missing; ok=false
Master b742a99 link a, b c, b2 Stale copy source-missing; ok=false

Both update forms report current b. Doctor provides a generic removal hint, without the exact command, and leaves the state unchanged.

Related: #2 fixed manual removal of missing managed skills; the earlier #1 was closed. Neither addresses automatic membership reconciliation for an --all source. The remaining decision belongs to this repository's maintainer: remove missing members during update, or provide the exact remediation command while installing new members.

Environment

  • skill version: 0.2.1; latest release and master b742a99 tested separately.
  • Swift version used to build master: Apple Swift 6.4 (swiftlang-6.4.0.34.1 clang-2100.3.34.1).
  • OS: macOS 27.0.1 (26A434).
  • Architecture: arm64.
  • Scope/agent/source: isolated user scope, Codex, local directory; no watch mode.

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