Skip to content

[Bug]: skill_generator.py rewrites the packaged SKILL.md even with an explicit --output, dirtying the tree during tests #441

Description

@clydeRbuegel

Affected Software/Harness

plugin (skill_generator.py), observable in the mubu harness

Version / Commit

6f372d3 (main, 2026-08-13)

Operating System

Linux

Python Version

3.13.5

Steps to Reproduce

cd mubu/agent-harness
PYTHONPATH=. python3 -m pytest cli_anything/mubu/tests/test_agent_harness.py -q
cd ../.. && git status --short

Expected Behavior

A test run leaves the working tree clean. test_skill_generator_can_regenerate_skill_from_canonical_harness
generates into a throwaway path (HARNESS_ROOT / "tmp-generated-SKILL.md") and removes it afterwards,
so nothing tracked should change.

Actual Behavior

11 passed in 0.20s
 M mubu/agent-harness/cli_anything/mubu/skills/SKILL.md

The tracked packaged skill file is rewritten. The cause is in generate_skill_file(), which writes
the packaged mirror unconditionally — also when --output explicitly points somewhere else
(mubu/agent-harness/skill_generator.py:404-419):

    if output_path is None:
        output = harness_root.parent.parent / "skills" / skill_id / "SKILL.md"
    else:
        output = Path(output_path)
    mirror = harness_root / "cli_anything" / metadata.software_name / "skills" / "SKILL.md"
    output.parent.mkdir(parents=True, exist_ok=True)
    output.write_text(content, encoding="utf-8")
    if mirror != output:
        mirror.parent.mkdir(parents=True, exist_ok=True)
        mirror.write_text(content, encoding="utf-8")

cli-anything-plugin/skill_generator.py:537-552 has the same shape with compatibility_path, so this
is the generator's general behaviour rather than something specific to mubu. Three harnesses ship a
generator copy (mubu, zotero, plugin) and three test files invoke it.

Why it only shows up in mubu: the write happens everywhere, but it is a content no-op where the
committed mirror still matches generator output. I confirmed that for zotero — running
python skill_generator.py . --output /tmp/z.md there leaves git status clean. For mubu the
committed mirror has drifted from what the generator now produces, so the same write shows up as a
diff:

 description: >-
-  Command-line interface for Mubu - Canonical packaged entrypoint for the Mubu live bridge....
+  Command-line interface for Mubu - Canonical packaged entrypoint for the Mubu live bridge.

plus a number of blank-line differences in the command tables.

Relevant Logs / Tracebacks

$ PYTHONPATH=. python3 -m pytest cli_anything/mubu/tests/test_agent_harness.py -q
...........                                                              [100%]
11 passed in 0.20s

$ git status --short
 M mubu/agent-harness/cli_anything/mubu/skills/SKILL.md

$ git diff --stat -- mubu/agent-harness/cli_anything/mubu/skills/SKILL.md
 .../cli_anything/mubu/skills/SKILL.md | 42 ++--------------------
 1 file changed, 2 insertions(+), 40 deletions(-)

Additional Context

Impact is small but annoying in two ways: a contributor who runs the mubu suite before committing can
carry an unrelated SKILL.md rewrite into their commit without noticing, and git status stops being
a reliable signal during a test run.

Two directions, whichever you prefer:

  • have generate_skill_file() skip the mirror write when an explicit --output was passed (a
    --no-mirror flag would do the same job more explicitly), or
  • regenerate and commit mubu's packaged SKILL.md so the write becomes a no-op, as it already is for
    zotero. That fixes the symptom but not the surprise.

Not a CI problem today: python3 .github/scripts/validate_root_skills.py passes on a clean tree and
leaves it clean — its docstring already notes that the sync script "regenerates the mirror from the
harness source unconditionally", so the behaviour appears known on the root-skills side.

Found while adding a __main__ guard to the mubu CLI in #440; not related to that change (it
reproduces on unmodified main). Happy to open a PR for either direction.

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions