[Bug]: skill_generator.py rewrites the packaged SKILL.md even with an explicit --output, dirtying the tree during tests
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--outputwas passed (a--no-mirrorflag would do the same job more explicitly), or - regenerate and commit mubu's packaged
SKILL.mdso 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.
Source: HKUDS/CLI-Anything