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

Author: clydeRbuegelCreated Aug 15, 2026Updated Aug 15, 2026

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.