feat(dev-safety): Phase 3 of #185 — guard rail blocks mutating muse-dev calls on canonical repos
Adds muse/cli/dev_guard.py, wired into app.py's dispatch right before args.func(args): any editable build (muse-dev, or any future editable install — detected structurally via muse.__file__ not being under site-packages, not by binary name) refuses local-object-store-mutating commands (commit, merge, push, reset, rm, gc, prune, etc. — code add/reset/patch/rename/migrate/semantic-cherry-pick within the `code` namespace; grep/impact/hotspots/etc. remain unaffected) against a protected canonical repo (default: ~/ecosystem/muse, ~/ecosystem/musehub, overridable via MUSE_DEV_PROTECTED_ROOTS). Override via MUSE_DEV_ALLOW_CANONICAL=1, explicit and loud. A stable, non-editable muse build is never blocked, regardless of target — it has no live-source hazard.
Deliberately out of scope: `hub` subcommands (network calls to a remote server — different risk category, not local object-store corruption).
32 tests, written first (red before wiring into app.py, green after). Unit tests for the classifier functions never touch a real repo. The one true end-to-end integration test runs the real muse-dev binary but only ever against a disposable temp repo pointed to via MUSE_DEV_PROTECTED_ROOTS — never the real canonical repos this guard exists to protect.
Manually verified against the real ~/ecosystem/muse: `muse-dev -C ~/ecosystem/muse commit -m "..."` now exits 77 with a clear message and makes zero mutation (rev-parse dev unchanged before/after); read-only commands (status) still pass through unaffected; the stable `muse` build is untouched by any of this.
Semantic Changes
50 symbols
Files Changed
+2
~1
1163 in snapshot
0 comments
muse hub commit comment sha256:2a8dfcf895b528326eedf00a21babac1a18d90176b856ea1e0fb3027b39be0da --body "your comment"
No comments yet. Be the first to start the discussion.