@mutmutco/hermes-plugin 3.139.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +4 -0
  2. package/__init__.py +72 -0
  3. package/package.json +20 -0
  4. package/plugin.yaml +9 -0
  5. package/prompts/soul.md +71 -0
  6. package/scripts/command-ladder-core.mjs +334 -0
  7. package/scripts/command-ladder-gate.mjs +126 -0
  8. package/scripts/deny-gate-crash.mjs +179 -0
  9. package/scripts/edit-tool-paths.mjs +113 -0
  10. package/scripts/env-write-lint.mjs +137 -0
  11. package/scripts/hook-io.mjs +22 -0
  12. package/scripts/hook-policy.mjs +78 -0
  13. package/scripts/hook-run.mjs +416 -0
  14. package/scripts/hook-trace.mjs +151 -0
  15. package/scripts/pretooluse-shell-gates.mjs +564 -0
  16. package/scripts/secret-echo-lint.mjs +177 -0
  17. package/scripts/throttle-core.mjs +324 -0
  18. package/scripts/vault-edit-gate.mjs +94 -0
  19. package/skills/bootstrap/SKILL.md +561 -0
  20. package/skills/bootstrap/seeds/Dockerfile.template +30 -0
  21. package/skills/bootstrap/seeds/README.template.md +37 -0
  22. package/skills/bootstrap/seeds/architecture.template.md +34 -0
  23. package/skills/bootstrap/seeds/decisions-readme.template.md +45 -0
  24. package/skills/bootstrap/seeds/docker-compose.template.yml +26 -0
  25. package/skills/bootstrap/seeds/gate.template.yml +85 -0
  26. package/skills/bootstrap/seeds/google-login.template.md +33 -0
  27. package/skills/bootstrap/seeds/manifest.json +26 -0
  28. package/skills/bootstrap/seeds/mmi-product-required-checks.template.json +23 -0
  29. package/skills/bootstrap/seeds/readme-mmi-developer-environment.block.md +5 -0
  30. package/skills/browser-automation/SKILL.md +95 -0
  31. package/skills/epic/SKILL.md +112 -0
  32. package/skills/hotfix/SKILL.md +165 -0
  33. package/skills/mmi/SKILL.md +398 -0
  34. package/skills/mmi-doctor/SKILL.md +66 -0
  35. package/skills/mmi-resume/SKILL.md +90 -0
  36. package/skills/onboard/SKILL.md +86 -0
  37. package/skills/rcand/SKILL.md +208 -0
  38. package/skills/release/SKILL.md +604 -0
  39. package/skills/secrets/SKILL.md +159 -0
  40. package/skills/stage/SKILL.md +153 -0
@@ -0,0 +1,165 @@
1
+ ---
2
+ name: hotfix
3
+ description: Promote an already-merged development fix to main and production through the gated Hub train.
4
+ ---
5
+
6
+ **Host-native invocation:** Claude `/mmi:hotfix` · Codex `$mmi:hotfix` · jervcode/Kimi `/skill:hotfix` · Kilo `skill` tool. A backticked `/name` in this doc names the matching workflow (this skill or a sibling), not a literal command.
7
+
8
+ # /hotfix — promote a development fix to main + prod
9
+
10
+ A hotfix is promotion, not authoring. The fix must land on `development` through a normal issue,
11
+ worktree, PR, review, and CI gate first. Hub then ports that merged PR or SHA to a main-base hotfix PR,
12
+ preserves the cherry-pick audit trail, and performs the PATCH release. Never author directly from `main`.
13
+ Never author the fix on a branch off `main`. The main-base branch is only the orchestrated port of a fix
14
+ that is already merged to `development`.
15
+
16
+ The FIX is never back-merged: `development` already contains it, and `rc` absorbs it at the next
17
+ `/rcand`. The release hotfix-coverage guard blocks a later candidate that omits the production fix.
18
+
19
+ The VERSION FOLD is different, and `hotfix release` ports it for you (#4410). `hotfix start` commits the
20
+ fold onto the main-base branch, so after the tag `main` declares the new version while `development`
21
+ still declares the old one. The Hub's catalogs now pin exact npm packages (#4948), so there is no
22
+ branch/content lockstep red; the fold still must land so the next release starts from production's real
23
+ version, BOM, and package pins. Step 3 opens that development-base fold PR automatically; land it.
24
+
25
+ ## Merge floor (#3167 — non-negotiable)
26
+
27
+ - **Never squash-merge a tagged commit.** The hotfix PR itself may squash (step 2 — the tag lands *after*,
28
+ on the merged `main` HEAD, and the `-x` trailer must survive the squash message). But any merge that
29
+ carries an already-tagged commit — an alignment PR, a later `main → development` roll-forward — lands as a
30
+ true merge, never squash: a squash re-mints the SHA and orphans the tag from the branch lineage.
31
+ - **A refused release train is a stop, never a license to finish by hand.** A conflict on the port, a red
32
+ authority probe, a failed required check, a refused `hotfix release` — each ends the run. Fix the cause on
33
+ `development` through a normal PR and re-run the orchestrator; never hand-cherry-pick, bare-push, or
34
+ bypass the gate to finish.
35
+ - **Version probes anchor on the latest Release tag, not a branch.** `hotfix status` derives the PATCH from
36
+ the latest Release tag; branch manifests and stale local tags are not version sources.
37
+
38
+ ## Authority and preflight
39
+
40
+ Production changes require the authorized human's explicit approval in the current turn. Verify authority
41
+ and CLI health before starting:
42
+
43
+ ```bash
44
+ mmi-cli oracle org access role <owner/repo> --json
45
+ mmi-cli doctor --no-repo-writes
46
+ ```
47
+
48
+ Stop on a red authority or CLI-version result. The worktree must be clean; move scratch into `tmp/` or
49
+ gitignore it rather than widening the hotfix diff. A TRACKED path named in a `working tree must be clean
50
+ before …` refusal is not scratch: read both `git status --porcelain` columns, treat every state except
51
+ exactly ` M` as real work to commit or stash, and for ` M` discard only when
52
+ `git diff HEAD --numstat -- <paths>` is empty, and only with `git checkout -- <paths>`. Plain
53
+ `git diff --numstat` prints nothing for a merely staged change, so it cannot make that call (#4004).
54
+
55
+ ## 1. Start from the merged development fix
56
+
57
+ Use the orchestrator with an explicit source every time:
58
+
59
+ ```bash
60
+ mmi-cli devops hotfix start --from <development-pr-or-sha>[,<development-pr-or-sha>...] --json
61
+ ```
62
+
63
+ **One hotfix cycle carries as many merged fixes as you name.** `--from` takes a comma-separated list in
64
+ pick order, and every sha it picks goes into the PR's carries marker, so the release proves each one
65
+ present before tagging. Do not open one hotfix per fix: batch everything ready for production into the
66
+ single PATCH. A fix that only becomes ready mid-cycle rides the same tag — cherry-pick it with `-x` onto
67
+ a `hotfix/<tag>-<n>` continuation branch, merge that PR, and rerun `hotfix release` with the full
68
+ `--carries` list; the release pins the newest merged SHA (#1025).
69
+
70
+ `hotfix start` resolves the PATCH version, branches from `origin/main`, performs the cherry-pick with `-x`,
71
+ prepares Hub distribution artifacts when applicable (stamping BOM `sourceCommit` at the durable
72
+ `origin/main` merge-base so a squash merge cannot orphan it — #4361; and for `registry-publish`
73
+ consumers, folds the package version so upgrade probes observe the PATCH), pushes the branch, and opens
74
+ the main-base PR. Do not duplicate those steps with raw branch commands, manual cherry-picks, or raw
75
+ GitHub PR creation.
76
+
77
+ Conflicts confined to regenerable distribution / version-fold paths (e.g. Hub `distribution-bom.json`,
78
+ locked plugin manifests, consumer `package.json`) — and, for hub-serverless + registry-publish, shipped
79
+ skill roots `skills/` and `.kilo-plugin/skills/` (#4363 / #4471) — are auto-resolved (take the picked
80
+ side) and regenerated by the bump/fold step. Source TS under `src/` / `cli/src/` is never auto-resolved.
81
+
82
+ Before cutting the hotfix branch, `hotfix start` preflights every `--from` pick on an accumulating
83
+ `origin/main` tree (#4472). If any pick would hard-stop, it refuses with every failing pick and path and
84
+ prescribes **one** development-based cite-only synthesis PR for the whole batch (#4643; the old
85
+ "cut from origin/main" pattern #4467 wording is retired — a main-parented branch must never merge
86
+ into development, #4365/#4371): cut from `origin/development`, regenerate the conflicting content so
87
+ it cherry-picks cleanly onto `origin/main`, land it with the cite-only marker (the #5096 flow) — not N
88
+ serial ports. Behavior changes still land on `development` first through a normal PR, then rerun hotfix
89
+ start from the port merge SHA(s) — never hand-resolve onto main.
90
+
91
+ ## 2. Verify the hotfix PR
92
+
93
+ Run the repo's local gate against the hotfix branch, then obtain the independent reviewer required by the
94
+ active agent doctrine. Review the actual main-base diff and the original issue acceptance criteria.
95
+
96
+ Wait for required CI through Hub:
97
+
98
+ ```bash
99
+ mmi-cli devops pr checks-wait <hotfix-pr-number>
100
+ mmi-cli devops pr merge <number> --squash
101
+ ```
102
+
103
+ The main-base PR is the production gate. Do not bypass checks or protected-branch authority. After the
104
+ authorized merge, verify the merged main commit still carries the cherry-pick provenance; if the PR was
105
+ squashed, the source trailer must survive in the squash message so future coverage checks remain exact.
106
+ Because Hub's default branch is `development`, the main-base hotfix PR does not close a separate tracking
107
+ issue. The development PR should already have closed the work item; do not add raw GitHub issue operations.
108
+
109
+ ## 3. Run the gated release
110
+
111
+ Derive the tag from `mmi-cli devops hotfix status`, then release with the same declared source:
112
+
113
+ ```bash
114
+ mmi-cli devops hotfix status
115
+ mmi-cli devops hotfix release <vX.Y.Z> --carries <development-pr-or-sha>[,<development-pr-or-sha>...]
116
+ ```
117
+
118
+ Name **every** fix the cycle carries. Each is proven an ancestor of the tagged SHA before tagging; a
119
+ missing one refuses the release and names the continuation path.
120
+
121
+ For MMI-Hub, pass a fresh 2-4 line neutral summary file with `--announce-summary-file`; never reuse a
122
+ stale file and never put a product or brand name in the summary. Hub release scope never includes another
123
+ repo's board or `ds-propagate.yml`. The orchestrator creates the tag and GitHub Release, selects the
124
+ registry-declared deploy path, watches the release-triggered or central deployment, verifies distribution,
125
+ and announces best-effort. Do not hand-dispatch a second publish/deploy path: duplicate release events can
126
+ race or double-publish.
127
+
128
+ For a private package, trust the authenticated publish job and its logged package/version result; a bare
129
+ unauthenticated `npm view` cannot distinguish private from missing.
130
+
131
+ ## 4. Verify and report
132
+
133
+ Report the tag and Release URL, production run and URL, source development PR/SHA, hotfix PR, and these
134
+ branch facts:
135
+
136
+ - `main`: the tag commit is on `origin/main`.
137
+ - `development`: the source fix was already merged before the hotfix began.
138
+ - `rc`: intentionally untouched; the next release coverage gate prevents regression.
139
+ - the development fold PR the release opened (`hotfix-fold/<tag>`), and whether it landed.
140
+
141
+ Do not hand-open a manifest-alignment PR: the version fold is already ported by `hotfix release` — land
142
+ its PR instead of authoring one. That port is explicitly NOT a back-merge — nothing from `main` is
143
+ merged into `development`; the fold is regenerated on a branch cut from `development` itself. If the run
144
+ reported `development fold port FAILED`, follow the manual remedy it named; never improvise a merge from
145
+ `main`.
146
+
147
+ ### Development fold after a hotfix (#4517 / #4948)
148
+
149
+ The Hub's thin catalogs now pin exact npm packages, so the old main-anchored catalog-lockstep gate is
150
+ retired: an unreleased branch cannot deliver a package version the release train has not published.
151
+ Hotfix versioning still belongs on the main-base train, never in an improvised development prepare PR:
152
+
153
+ 1. `mmi-cli devops hotfix start --from <merged-dev-pr-or-sha>` (prepare + distribution bump on `hotfix/vX.Y.Z` from `main`)
154
+ 2. merge the hotfix PR → `mmi-cli devops hotfix release vX.Y.Z` (publish)
155
+ 3. land the automatic `hotfix-fold/<tag>` development fold PR (or follow its printed remedy)
156
+
157
+ The fold is now required for version/BOM/package-pin continuity, not to clear a branch-content gate.
158
+
159
+ ## Retro
160
+
161
+ If this skill's instructions themselves misfired, file one deduplicated lesson and continue:
162
+
163
+ ```bash
164
+ mmi-cli learning skill-lesson --skill hotfix --title "<what misfired>" --body "<what; evidence; proposed amendment>"
165
+ ```
@@ -0,0 +1,398 @@
1
+ ---
2
+ name: mmi
3
+ description: Show, claim, move, or file work on the repo board.
4
+ ---
5
+
6
+ # mmi — start of work
7
+
8
+ Shows a dev their workboard for this repo: what they're working on, what's free to pick up, and what others
9
+ have claimed. Read-only by default — render the board, then get out of the way.
10
+
11
+ Explicit invocation is host-native: `/mmi:mmi` in Claude Code, `$mmi:mmi` in Codex, `/mmi`
12
+ (canonical `/skill:mmi`) in Kimi Code CLI, and the `mmi` skill (listed in Kilo's `/` picker, invoked via
13
+ the `skill` tool) in Kilo Code. The `/mmi` label used below names this workflow; it is not a
14
+ universal literal command.
15
+
16
+ Status values: `Todo · In Progress · In Review · Done` (GitHub enforces who can move what — don't re-explain
17
+ it on every move). Closed/finished items auto-archive after they go quiet; archived ones aren't on the board.
18
+
19
+ ## Step 0 — identity, greet, eager preflight when stale
20
+
21
+ `/mmi` is the dev's hello-to-work — the most common command they run. Three pacing rules before anything else:
22
+
23
+ 1. **Resolve login, then greet immediately** (before `board read` or doctor — still the first lines in
24
+ the response so the dev never stares at silent tool output). One emoji max in the whole response.
25
+ The greeting addresses the dev, never claims to *be* them (not "I'm @<login>"):
26
+ - **SessionStart banner** — if context carries `current human: <login>`, use that login.
27
+ - **Else** one fast call: `mmi-cli whoami --json` (cached Hub session in `hub-session.json` when
28
+ valid — no network; `gh` fallback only when the cache lacks `login`; exit 0 on `unknown`). Do
29
+ **not** call `gh api user` separately — `whoami` already covers it. Do **not** wait on `board read`
30
+ for identity — `viewer` is for work items only (Step 1).
31
+ - Known login → `👋 Welcome back, @<login> — pulling up your board…`
32
+ - `source: unknown` → generic `👋 Welcome back — pulling up your board…`
33
+ 2. **Keep the board fast: read first, run doctor only when evidence says it can change this render (#2112).**
34
+ The normal happy path is identity → board read. Do **not** block the board on a doctor run just to
35
+ check freshness. Run doctor synchronously only after a hard signal that the current setup may be broken:
36
+ `mmi-cli` is missing, `board read` reports missing auth/project scope, the command surface is absent, or a
37
+ cached/session-start health line explicitly says a heal is needed.
38
+
39
+ ```bash
40
+ mmi-cli oracle board read --json # Step 1 — first useful render on the happy path
41
+ mmi-cli doctor --no-repo-writes # only after a hard setup signal — foreground, one at a time
42
+ ```
43
+
44
+ Since #4199 `--preflight` is **READ-ONLY** (docs/doctor-contract.md § Flag Grammar — the canon
45
+ reversal; jerv semantics win estate-wide): it measures and reports with the shared exit code and performs
46
+ zero writes. The heal lane for "fix my env before work" is `doctor --no-repo-writes` — the default heal
47
+ run minus repo working-tree mutation. Its heals are `npm install -g` and a marketplace remove → add →
48
+ install, both machine-global, serialised behind a machine-wide lock (#3489), so two concurrent runs no
49
+ longer interleave inside the npm prefix or the marketplace clone — the second waits, and if the first is
50
+ still installing after two minutes the second reports the heal as skipped rather than forcing it.
51
+
52
+ Still run it in the foreground and wait. The lock stops corruption, not confusion: a backgrounded run
53
+ that reports "skipped — lock busy" has healed nothing, and an agent that does not read that line will
54
+ carry on believing its tooling was fixed.
55
+
56
+ `doctor --no-repo-writes` heals a stale/unresolved plugin install (the **env** half of the interactive
57
+ doctor, #3485/#3975) — it never touches the repo working tree. When it prints
58
+ `↻ Updating mmi tooling, one moment…`, relay that before waiting; when it prints `↻ MMI tooling
59
+ updated — …`, relay the reload/restart guidance.
60
+
61
+ What the env half heals:
62
+
63
+ - a stale or unresolved Claude plugin → `claude plugin marketplace remove mmi` → `… remove mutmutco` →
64
+ `claude plugin marketplace add mutmutco/MMI-Hub` → `claude plugin install mmi@mutmutco`. A fresh
65
+ reinstall, never `claude plugin update`, which nests into itself past MAX_PATH on Windows and wipes the
66
+ marketplace clone (#1126). Effective after a reload: **restart Claude Code / run `/reload-plugins`**
67
+ (native), or **reopen the workspace** (VS Code extension).
68
+ - superseded plugin cache versions → the guarded auto-prune (#4199, canon per
69
+ docs/doctor-contract.md § Guarded cache prune): never the running/newest/installed version, a cache a
70
+ live session holds is named "still held" and never forced.
71
+
72
+ What it does **not** do since #4954: converge CLI or host versions. A behind npm global is REPORTED
73
+ and the `fleet` row reads MMI Hub's last-run journal evidence. `mmi-hub update` is the single safe
74
+ version-convergence writer; plain doctor and `/mmi` never run repository cleanup.
75
+
76
+ - **Fast path** → `whoami` then `board read`; no foreground doctor.
77
+ - **Hard setup signal** → run `doctor --no-repo-writes`, relay `↻` lines, then retry `board read` when appropriate.
78
+ - **`mmi-cli: command not found`** → plugin PATH provisioning has not applied, or the standalone CLI is not installed.
79
+ In Claude Code, reopen the session; if it persists, install the MMI plugin:
80
+ `/plugin marketplace add mutmutco/MMI-Hub` → `/plugin install mmi@mutmutco` → `/reload-plugins`.
81
+ On Codex, install the Hub-shipped plugin: `codex plugin marketplace add mutmutco/MMI-Hub` →
82
+ `codex plugin add mmi@mutmutco`, then trust the bundled hooks via `/hooks`. On Kimi Code CLI:
83
+ `/plugins install https://github.com/mutmutco/MMI-Hub` → `/reload`. On Cursor, run
84
+ `mmi-cli plugin heal`, then reload the Cursor window. On OpenCode and plain shell install the
85
+ maintenance package; it provisions the standalone CLI:
86
+ ```powershell
87
+ npm install -g @mutmutco/hub
88
+ mmi-hub install
89
+ ```
90
+ In PowerShell from an `MMI-Hub` checkout, or when diagnosing a stale plugin cache, use the repo-local fallback:
91
+ ```powershell
92
+ node cli/dist/index.cjs doctor --json
93
+ ```
94
+ - **The host-native skill entry is missing** — `/mmi:mmi` is absent in Claude, `$mmi:mmi` is absent in
95
+ Codex, or `/skill:mmi` is absent in Kimi (the auto-heal below is Claude-only; Codex and Kimi ship the
96
+ same skills but repair is a manual reinstall — see their recipes above) → the plugin is stale,
97
+ duplicated, or disabled, so the skill surface is gone and you can't reach this workflow through the
98
+ host UI. Recover from the shell with the repo-local doctor, which detects and self-heals it:
99
+ ```powershell
100
+ node cli/dist/index.cjs doctor # from an MMI-Hub checkout — auto-heals + prints the reload action
101
+ ```
102
+ If `claude` isn't on PATH for the auto-heal, run the reinstall by hand (never `/plugin` in VS Code — it
103
+ isn't an updateable path there):
104
+ ```bash
105
+ # Claude Code (native or VS Code extension)
106
+ claude plugin marketplace remove mmi && claude plugin marketplace remove mutmutco && claude plugin marketplace add mutmutco/MMI-Hub && claude plugin install mmi@mutmutco
107
+ # then: restart Claude Code / run /reload-plugins (VS Code: reopen the workspace)
108
+ ```
109
+ - **A gate is ✗** → walk them through the printed fix; don't just echo it:
110
+ - **GitHub auth** (the usual one) — the board uses its `gh` token. Give them the
111
+ command to run **in their own terminal** (the browser step is theirs — an agent can't log in as them):
112
+ ```bash
113
+ gh auth login --hostname github.com --git-protocol https --web --scopes "project"
114
+ ```
115
+ The `project` scope is what lets `/mmi` read + move the board, granted here once. When they're back,
116
+ re-run `mmi-cli doctor --preflight` to confirm green without writes.
117
+ - **Hub registry / board META** — `mmi-cli oracle org project get <owner/repo>` or `mmi-cli oracle board read` reports
118
+ missing project/board coords → a master-admin registers or backfills the repo's `PROJECT#<slug>` META.
119
+ There's no reliable project to read until that is fixed, so stop here.
120
+
121
+ A broken setup surfaces from `doctor --preflight` (read-only), a failed `board read`, or a gate that still fails after
122
+ heal — handle it then. A `command not found` from **either** command routes into the recovery paths above.
123
+ Don't block the all-green path on doctor noise.
124
+
125
+ ## Authority (org-wide)
126
+
127
+ `/mmi` is the usual session start — agents should know the dev's role before any later train, vault, or
128
+ tenant request surfaces. After the board read (Step 1), you already have `viewer` in the JSON; for train
129
+ authority on this or another repo, run:
130
+
131
+ ```bash
132
+ mmi-cli oracle org access role <owner/repo> --json # { role, train } — Hub-verified from registry projectAdmins
133
+ ```
134
+
135
+ When `role` is `project-admin` and `train` is true on **that** repo, the dev holds D14 authority there —
136
+ guide or execute via the matching skill (`/secrets`, `/rcand`, `/release`, `/hotfix`, `runtime tenant control`).
137
+ **Do not** redirect them to the master. Hub train is master-only; org-tier vault and access grants stay
138
+ master-only. Full matrix: `AGENTS.md` § Authority.
139
+
140
+ ## Config
141
+
142
+ The project this repo is on lives in the Hub registry (`PROJECT#<slug>`: `projectOwner`, `projectNumber`,
143
+ `projectId`, `statusFieldId`, `statusOptions{}`, and optional Priority field ids), set by `/bootstrap`
144
+ (repos and projects are not 1:1 — a repo attaches to a chosen project). Refresh the registry META if a
145
+ lookup misses; do not read or repair committed repo-local board config.
146
+
147
+ ## Step 1 — read the board (one call, caller-scoped)
148
+
149
+ SessionStart injects a **bounded board slice** (assigned + top claimable items, max five lines,
150
+ 3s timeout, fail-soft) and, when task relevance is high-confidence, up to **two North Star context
151
+ cards** (title + compact intent, PRIOR-not-instruction framing — silent when ambiguous). For the
152
+ complete partition — secondary repos, taken items, bundle details — run the full command below.
153
+
154
+ ```bash
155
+ mmi-cli oracle board read --json
156
+ ```
157
+
158
+ This is the **only foreground call** on the happy path for **work items** (not identity — Step 0 already
159
+ resolved login). Its JSON carries `viewer`, `repo`, and the project title — do **not** run separate
160
+ `gh api user` / `gh repo view` calls; they just delay the board. If `repo` is missing from the JSON,
161
+ keep the board header generic. The CLI resolves the project from the Hub registry; to inspect it
162
+ directly, `mmi-cli oracle org project get --json`.
163
+
164
+ Use the returned `primary` group for current-repo items and `secondary` for other repos on the same Project.
165
+ Within each group, render `userOwned`, `claimable`, and `taken`.
166
+
167
+ CLI partition:
168
+ - **Yours** — assignee includes the viewer AND `Status ∈ {Todo, In Progress, In Review}`.
169
+ - **Free to claim** — `Status == Todo` AND unassigned AND the viewer has repo write permission
170
+ (`repos/<owner>/<repo>.permissions.push == true`). Issue filing stays available to any authenticated
171
+ org member; claiming work is gated by write access.
172
+ - **Taken** — assigned to someone else (any active status). Render id + status + owner ONLY — no title.
173
+
174
+ Do not cache claimable state. Every `/mmi` board is a fresh Project v2 read. Partial reads exit nonzero by
175
+ default; use `--allow-partial` only when the dev explicitly accepts an incomplete board. If the read fails
176
+ for a missing `read:project` scope, surface that verbatim — the dev grants it once at `gh auth login`.
177
+
178
+ ## Step 2 — show the board
179
+
180
+ This render is the product: welcoming, guiding, clear — and gone in one glance. Plain **markdown**,
181
+ never a fenced code block (monospace hard-wraps long titles and the structure is lost). The shape:
182
+
183
+ - **Short refs.** `[RepoName#N](issue-url) · short title` — repo name + number only, no `owner/`
184
+ prefix, no `[type]` brackets. The ref is the clickable link; the title follows after `·`, trimmed
185
+ to its essence (drop boilerplate prefixes, keep it under ~8 words).
186
+ - **Flat `-` lists** under bold head lines — never `##` headings (too heavy for a three-section
187
+ board), never nested bullet trees, never tables, never a literal `•` glyph (it breaks GFM list
188
+ parsing).
189
+ - **Three heads, each with one factual clause** appended after an em dash — a fact the dev can act
190
+ on ("two train fixes in flight"), not cheerleading. Encouragement lives once, in the close.
191
+ - **On your plate** — the dev's items, status noted inline after the title (`· in review`) when
192
+ not In Progress. In Review means *awaiting admin review & merge* — caption it that way, never
193
+ "ready to move".
194
+ - **Up for grabs** — claimable items.
195
+ - **Taken** — id · status · owner ONLY, never the title. No commentary clause; it's reference.
196
+ - **Skip empty sections silently** — no "nothing here" filler. Empty board entirely → one warm line:
197
+ nothing assigned, point at Up for grabs or filing a new item.
198
+ - **Close with one grounding line** — no question, no hype, no pressure: `Pick one and claim it
199
+ when you're ready.` plus the standing quiet affordance `Or file a new item — say the word.`
200
+ - **One screen total.** Greeting + sections + optional Leverage (Step 6) + close.
201
+
202
+ Full example (greeting printed earlier, before the read):
203
+
204
+ > 👋 Welcome back, @dev — here's your board on **MMI-Hub**.
205
+ >
206
+ > **On your plate** — two train fixes in flight:
207
+ > - [MMI-Hub#834](https://github.com/mutmutco/MMI-Hub/issues/834) · automated hotfix apply path
208
+ > - [MMI-Hub#841](https://github.com/mutmutco/MMI-Hub/issues/841) · rcand stuck on required checks
209
+ >
210
+ > **Up for grabs** — ready when you are:
211
+ > - [MMI-Hub#821](https://github.com/mutmutco/MMI-Hub/issues/821) · redesign tenant env-writer
212
+ > - [MMI-Hub#839](https://github.com/mutmutco/MMI-Hub/issues/839) · revisit hotfix back-merge policy
213
+ >
214
+ > **Taken**
215
+ > - MMI-Hub#827 · In Progress · @otherdev
216
+ >
217
+ > **Leverage**
218
+ > - #834 and #841 are both train-lane — I can run them side by side, one PR each.
219
+ >
220
+ > Pick one and claim it when you're ready. Or file a new item — say the word.
221
+
222
+ Only an admin merges (a project-admin on their own project, the master-admin everywhere); the dev who
223
+ opened the PR waits on that review, they don't move it themselves.
224
+
225
+ ## Step 3 — stop (act only on request)
226
+
227
+ Render the board and stop. Don't prompt for a choice, don't recommend a next move, don't ask "what now?".
228
+ The dev drives: when they say claim / continue / file — or accept a Leverage offer (Step 6) — do it.
229
+ Otherwise the board alone is the answer.
230
+
231
+ **Status moves happen automatically** as the work flows (claim, PR open, merge, release). The dev never
232
+ moves an item by hand, so **never suggest a status move** — not "advance to Test", not "mark this PR",
233
+ not "ready to move?". The board reflects state; it doesn't ask the dev to change it.
234
+
235
+ The one standing affordance is **filing a new item** — always available, no item needed. The Step 2
236
+ close line already carries it (`Or file a new item — say the word.`); never turn it into a status
237
+ nudge. If the dev takes it, run the guided flow in Step 5.
238
+
239
+ ## Step 4 — load the full item before working it
240
+
241
+ The moment the dev commits to an item (continue or claim), read the **whole** work item before planning or
242
+ acting — never from the board title alone. Body **and every comment**, end-to-end; treat later comments as
243
+ potentially **superseding** the body. Only then greet into the work or propose a plan.
244
+
245
+ ```bash
246
+ # One shot — status, assignees, type, body, and every comment for one board item:
247
+ mmi-cli oracle board show <owner/repo#N> # add --json for machine-readable output
248
+ ```
249
+ For an item **not on the board**, `mmi-cli oracle issue view <N> --comments` is the board-independent one-shot:
250
+ it returns the body **and** every comment as JSON in a single call (add `--context` for `linkedPrs` and, on
251
+ an epic, a `children` summary). Prefer it over raw `gh issue view --comments`, which in a non-TTY shell (every
252
+ agent/CI context) prints only the comments, hides the body, and prints nothing at all on a zero-comment issue.
253
+ ```bash
254
+ mmi-cli oracle issue view <N> --repo <owner/repo> --comments # body + every comment, one call
255
+ ```
256
+
257
+ > **Never reach for standalone `jq`** — it isn't installed on Windows dev machines, so each attempt burns a
258
+ > failed call (#230). `mmi-cli oracle board read|show` is already human-readable (drop `--json`); to parse JSON use
259
+ > `mmi-cli … --json` piped to `node`, or `gh`'s **built-in** `--jq`.
260
+
261
+ (Triggers only when a dev commits to an existing item — no-op for the *report a bug / request a feature /
262
+ something else* paths.)
263
+
264
+ ## Step 5 — act
265
+
266
+ - **Claim:** when the dev takes an item, assign them + set `In Progress` in one go. This is the only status
267
+ write `/mmi` makes, and only as the mechanical side of claiming — never as a standalone "move" the dev
268
+ is offered. Every later transition (In Review on PR open, Done on merge) flows automatically from the
269
+ work, not from here.
270
+ ```bash
271
+ mmi-cli oracle board claim <owner/repo#N> --json
272
+ ```
273
+ The command validates `Todo` + unassigned, assigns the viewer, and moves the Project v2 `Status` to
274
+ `In Progress`. A partial claim exits nonzero unless the dev explicitly accepted `--allow-partial`.
275
+ Claiming several items (batch/parallel act-paths) takes them in **one call** — `board claim <ref> <ref> …`
276
+ — which shares the setup cost and reports per-item results (any per-item failure → nonzero exit).
277
+ - **File a new item (guided by type → template):** don't free-type an issue. Walk the dev through it:
278
+ 1. **Pick the type** — `bug` · `feature` · `task` (the repo's three `.github/ISSUE_TEMPLATE/` forms;
279
+ each carries its own label). Offer the choice with the structured-question UI, one line each:
280
+ bug = something's broken · feature = new capability · task = chore/improvement.
281
+ 2. **Fill that type's template.** Read its fields from `.github/ISSUE_TEMPLATE/<type>.yml` and gather
282
+ answers from the dev for each — draft where you can, ask where you can't (the template form is
283
+ interactive and won't drive in a non-TTY agent shell, so collect the fields, then create directly).
284
+ 3. **Submit via `mmi-cli oracle issue create`** — the canonical create path. Before filing, read the live
285
+ command contract from `mmi-cli explain oracle issue create --json`; flags change, and a missing documented flag means
286
+ the installed CLI is stale until a fresh local build proves otherwise. It maps `--type` to the label,
287
+ `--priority` sets the board Priority **field** (never a `priority:*` label — #416), and `--surface`
288
+ supplies the repository's required single surface label. It always prints `{number,url}` JSON. Never
289
+ use `gh issue create`; it bypasses these board contracts:
290
+ ```bash
291
+ mmi-cli oracle issue create --type <bug|feature|task> --title "<title>" --body "<filled template>" \
292
+ --priority <high|medium|low> --surface <surface>
293
+ ```
294
+ For long markdown, materialize a temporary UTF-8 body file, pass its real path with
295
+ `--body-file <path>`, then remove it after the write succeeds. Do not pipe multiline markdown to
296
+ `--body-file -` on a guarded host.
297
+ A title with backticks needs `--title-file` (#3381). On Windows Git Bash, a title that starts
298
+ with `/` (or contains an MSYS-path-shaped token) is rewritten before `mmi-cli` sees it — e.g.
299
+ `--title "/update …"` becomes `C:/Program Files/Git/update …`. Prefer `--title-file <path>`, or
300
+ prefix the create with `MSYS_NO_PATHCONV=1` (#4373).
301
+ The command starts bounded related-issue discovery off-path. It auto-comments only high-confidence,
302
+ idempotent links. To inspect candidates manually before writing anything else:
303
+ ```bash
304
+ mmi-cli oracle issue discover-related --repo <owner/repo> --number <number> --title "<title>" --body "<body>" --json
305
+ ```
306
+ It lands on the board as Todo automatically — confirm the link from the JSON. (Templates differ per
307
+ repo; read the actual `.yml` set rather than assuming bug/feature/task.)
308
+ - **File a friction report (org-tooling pain):** `mmi-cli learning report --title "<one-line>" --body "<what hurt>"`
309
+ files it on the Hub board via your Hub session and dedups against the open reports (a confident
310
+ duplicate becomes a +1 comment, not a new issue). The actual GitHub write runs server-side with the
311
+ Hub App's own token (#263), so no MMI-Hub repo access is required to file. Never read Hub coordinates or
312
+ keys from a repo-local `.env`, call a repo-local report script, or POST the Hub API directly — the CLI
313
+ carries the endpoint and your Hub session intrinsically.
314
+ - Surface any `gh`/`mmi-cli` error verbatim.
315
+
316
+ ## Step 6 — Leverage (offer where it fits)
317
+
318
+ `/mmi` is an agentic coding board — every item is written by an LLM agent, so the board can do more than
319
+ hand over one item at a time. Between the Taken section and the close, render an optional **Leverage**
320
+ block: **up to two** offers, one line each, under a bold `**Leverage**` head (see the Step 2 example).
321
+ **Default to silence:** if nothing below crisply fits, omit the whole block — never pad it. Never use a
322
+ question-UI, never pressure — the dev acts or ignores.
323
+
324
+ Pick up to two, in priority order:
325
+
326
+ 1. **Split + fan out** — a single item plainly too large for one PR (body is multi-part, an umbrella or
327
+ epic). Offer to slice it into child issues. (First because it *creates* the items the rest act on.)
328
+ 2. **Batch** — 2+ claimable items that are one coherent unit (shared title-prefix family, same subsystem)
329
+ **and** touch overlapping/adjacent paths. Coupled → **one PR**.
330
+ 3. **Parallel** — 2+ items that are mutually independent and touch **disjoint paths**. Independent → **one PR each**, run concurrently.
331
+ 4. **Background** — a single long-running item (broad refactor, large build/sweep). Kick it off in the
332
+ background so the dev isn't blocked.
333
+
334
+ Disjoint paths is the deciding signal between batch (overlap → one PR) and parallel (disjoint → N PRs).
335
+ When unsure which fits, prefer the more conservative offer — a marginal call is worse than a quiet board.
336
+ Two offers must not overlap (never the same item in both); a second marginal offer is worse than one
337
+ crisp one.
338
+
339
+ Bundling detail boundary: start from the metadata board. Only if there are multiple viable
340
+ `userOwned`/`claimable` candidates, fetch bodies/comments with:
341
+
342
+ ```bash
343
+ mmi-cli oracle board read --json --bundle-details
344
+ ```
345
+
346
+ That detail path may fetch bodies/comments only for `userOwned` and `claimable` issues. `taken` stays
347
+ metadata-only, always. Do not fetch Done items, do not cache claimables, and do not pass `--allow-partial`
348
+ unless the dev explicitly accepts an incomplete Leverage read. If detail lookup exits nonzero, render
349
+ the board without a Leverage block.
350
+
351
+ Offer lines — one line each, no UI, no "(Recommended)", phrased as available leverage:
352
+
353
+ - **Batch** — `These read like one change — I can take #66–#70 together in a single PR if you'd like.`
354
+ - **Parallel** — `#17 and #18 are independent — I can run them side by side, one PR each, if that helps.`
355
+ - **Background** — `#22 looks long-running — I can take it in the background so you're not blocked.`
356
+ - **Split** — `#60 looks large — I can slice it into child issues and fan them out, if you want.`
357
+
358
+ Act-paths run only on the dev's explicit go. MMI coordinates board and PR outcomes, while the host owns
359
+ workspace mechanics:
360
+
361
+ - **PR metadata:** read `mmi-cli explain devops pr create --json` or `mmi-cli explain devops pr edit --json` before the
362
+ write. For multiline Markdown, materialize a temporary UTF-8 body file, pass its real path with
363
+ `--body-file <path>`, and remove it after the write succeeds. Do not pipe the body to `--body-file -`;
364
+ host prose guards require the materialized-file path.
365
+ - **Batch:** claim each item (the Step 5 claim loop), make the coupled edits, and open **one** PR
366
+ (`Closes #…, #…`). When an issue must stay open (HOLD/prep), never write `Does not close #N` — GitHub
367
+ still closes it; use `Part of #N` / `Refs #N` / `leaves #N open` only (JC#495).
368
+ - **Parallel:** run independent work concurrently, **one PR per item**. If two would touch the same file,
369
+ serialize them or fold them into a batch instead.
370
+ - **Background:** run off the hot path (a background task or CI job); poll with `/loop` if useful. Bound it
371
+ — never block silently.
372
+ - **Split:** keep the original as the umbrella; file each child as a **native sub-issue** of it with
373
+ `mmi-cli oracle issue create --parent <umbrella-ref> …` (or `mmi-cli oracle issue link-child <umbrella> <child>` for a
374
+ child that already exists). The parent then renders a sub-issue checklist with each child's state and the
375
+ child renders its parent — no title prefix or body task-list to maintain. Refs are `#NN`, `owner/repo#NN`,
376
+ or a URL, and it works cross-repo (a Hub umbrella can track product-repo children). Get the dev's go before
377
+ filing the children; each child then becomes a parallel item. **When the last child merges, close the
378
+ umbrella** — its `Done` follows automatically.
379
+
380
+ ## Notes
381
+
382
+ - Reads/moves use **your** `gh` token (needs `read:project`/`project`, granted once at `gh auth login`).
383
+ - Promotion (`/rcand`, `/release`, `/hotfix`) and the local test env (`/stage`) are their own skills — `/mmi`
384
+ is the board + start-of-work, not the train.
385
+ - **Board verbs:** `board read` · `board show <id>` · `board claim <id>` · `board move <status> <id>`.
386
+ `move` exists for an agent's own mechanical bookkeeping when **no PR rides the automation** — e.g.
387
+ setting `Done` on a no-PR `task` or closed-out item that will not auto-advance. It is a tool, not a
388
+ dev-facing offer: the "never suggest a status move" rule (Step 3) still governs the human flow. The verb
389
+ hides the `gh project item-edit` + option-id wiring, so reach for it, not raw `gh`.
390
+
391
+ ## Retro — one check before you finish
392
+ Before your final report, answer one question honestly: did **this skill's own instructions** misfire
393
+ this run — ambiguous wording, a misleading message, or an environment failure it should have warned
394
+ about? (Process only — never the user's code or task; e.g. a board read that misreported what's
395
+ claimable, or a claim that moved the wrong item.) If yes, file **one** lesson and move on; a clean run is
396
+ silent (hard cap: one per run). It lands on the Hub board (deduped) and is fixed only via a reviewed PR —
397
+ never edit the skill live; the retro is advisory, so if the call fails, note it and continue:
398
+ `mmi-cli learning skill-lesson --skill mmi --title "<what misfired>" --body "<what; evidence; proposed amendment>"`
@@ -0,0 +1,66 @@
1
+ ---
2
+ name: mmi-doctor
3
+ description: Diagnose hygiene and safely heal tooling; repository cleanup is explicit.
4
+ ---
5
+
6
+ **Host-native invocation:** Claude `/mmi:mmi-doctor` · Codex `$mmi:mmi-doctor` · jervcode/Kimi `/skill:mmi-doctor` · Kilo `skill` tool. A backticked `/name` in this doc names the matching workflow (this skill or a sibling), not a literal command.
7
+
8
+ # /mmi-doctor — one hygiene pass
9
+
10
+ Run the safe default when a session opens messy or before a handoff:
11
+
12
+ ```bash
13
+ mmi-cli doctor
14
+ ```
15
+
16
+ A plain run may repair machine-global plugin wiring and guarded caches, but **never mutates the
17
+ repository** (#5023). It reports managed `.gitignore`, docs-index, board mechanics, and aged scratch.
18
+ Local workspace lifecycle is host-owned; doctor does not relocate or delete worktrees. Run
19
+ `mmi-cli doctor --apply` only when the operator explicitly wants guarded repository maintenance. Secrets
20
+ stay out of doctor; use `mmi-cli vault secrets diff` for a catalog gap check.
21
+
22
+ Doctor does **not** converge CLI or host versions (MMI-Hub#4954). `mmi-hub update` is the single
23
+ writer of those versions; doctor only reports lag and last-run journal evidence. `mmi-hub status`
24
+ reads actual installed locations and versions. Doctor's active-plugin repair pass
25
+ covers every surface from any invocation surface — including Cursor's local-checkout row, not only
26
+ the active surface.
27
+
28
+ ## Flags
29
+
30
+ | Flag | Role |
31
+ |------|------|
32
+ | *(none)* | Safely heal tooling; report repository hygiene without repo writes. |
33
+ | `--verbose` | Full checklist + per-row evidence. |
34
+ | `--no-repo-writes` | Compatibility spelling for the safe default. |
35
+ | `--self` / `--fast` / `--banner` / `--preflight` | Cheap / read-oriented lanes (see `docs/doctor-contract.md`). |
36
+ | `--apply` | Explicit advanced lane: also apply guarded repository cleanup. |
37
+
38
+ ## Do not run the old multi-step ritual
39
+
40
+ Do **not** chain these as a `/mmi-doctor` substitute:
41
+
42
+ ```bash
43
+ mmi-cli doctor --self
44
+ mmi-cli oracle board doctor
45
+ mmi-cli vault secrets diff
46
+ ```
47
+
48
+ Plain `mmi-cli doctor` covers safe tooling repair and diagnosis. Explicit `doctor --apply` covers
49
+ repository maintenance; the host owns workspace cleanup. Reach for individual verbs only when you want
50
+ one surface alone.
51
+
52
+ ## Notes
53
+
54
+ - `/mmi-doctor` is the hygiene pass; `/mmi-resume` is the lighter read-only session open.
55
+ - Prefer one doctor run over hand-editing board items, gitignore blocks, or marketplace pins.
56
+ - The host owns workspace roots, cleanup, and any lease policy. Doctor diagnoses MMI tooling and does
57
+ not relocate or delete local worktrees.
58
+
59
+ ## Retro — one check before you finish
60
+ Before your final report, answer one question honestly: did **this skill's own instructions** misfire
61
+ this run — ambiguous wording, a misleading message, or an environment failure it should have warned
62
+ about? (Process only — never the user's code or task; e.g. a doctor run that proposed deleting a live
63
+ branch.) If yes, file **one** lesson and move on; a clean run is silent (hard cap: one per run). It
64
+ lands on the Hub board (deduped) and is fixed only via a reviewed PR — never edit the skill live; the
65
+ retro is advisory, so if the call fails, note it and continue:
66
+ `mmi-cli learning skill-lesson --skill doctor --title "<what misfired>" --body "<what; evidence; proposed amendment>"`