@mutmutco/hermes-plugin 4.1.4 → 4.1.6

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mutmutco/hermes-plugin",
3
- "version": "4.1.4",
3
+ "version": "4.1.6",
4
4
  "description": "MMI canonical skills transported as a Hermes Agent native plugin.",
5
5
  "author": {
6
6
  "name": "MMI Future",
package/plugin.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "manifest_version": 1,
3
3
  "name": "mmi",
4
- "version": "4.1.4",
4
+ "version": "4.1.6",
5
5
  "description": "MMI canonical workflow skills and fail-closed pre-tool policy gates.",
6
6
  "provides_hooks": [
7
7
  "pre_tool_call"
@@ -23,6 +23,7 @@ name: gate
23
23
  # main on trunk). `main` is ALWAYS included in the job `if:` below so a required-
24
24
  # checks ruleset on main cannot be silently skipped by a future bootstrap (#4113).
25
25
  # GATE_BUDGET_SHA is rendered by the CLI from its blessed run-with-budget pin — not an operator knob.
26
+ # GATE_RUNNER_SHA pins the org runner-checkout / runner-node-toolchain actions (#5610).
26
27
  # Estate policy 2026-08-23: GitHub-hosted Windows (`windows-latest` / windows-*) is forbidden org-wide.
27
28
  # Do not add a windows-compat (or any other) job that runs-on GH-hosted Windows. Linux self-hosted
28
29
  # (mmi-live / mmi-heavy) is the only CI merge gate. Rare Windows proof stays on the owner's machine or
@@ -58,7 +59,9 @@ jobs:
58
59
  defaults:
59
60
  run: { working-directory: {{GATE_WORKDIR}} }
60
61
  steps:
61
- - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
62
+ - uses: mutmutco/MMI-Hub/.github/actions/runner-checkout@{{GATE_RUNNER_SHA}}
63
+ with:
64
+ lockfile-path: {{GATE_CACHE_DEP_PATH}}
62
65
  # #5427: per-job npm cache under $RUNNER_TEMP — never the shared ~/.npm. Twelve mmi-live lanes
63
66
  # share the gha-runner home; npm hardlinks from that cache into node_modules, so one job's
64
67
  # `npm ci` can make another job's vitest/dist/workers/forks.js vanish mid-suite (Cannot find
@@ -91,21 +94,17 @@ jobs:
91
94
  exit 1
92
95
  fi
93
96
  - if: ${{ '{{GATE_RUNTIME}}' == 'node' }}
94
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
95
- with: { node-version: 24, cache: npm, cache-dependency-path: {{GATE_CACHE_DEP_PATH}} }
97
+ uses: mutmutco/MMI-Hub/.github/actions/runner-node-toolchain@{{GATE_RUNNER_SHA}}
98
+ with:
99
+ node-version: 24
100
+ cache: npm
101
+ cache-dependency-path: {{GATE_CACHE_DEP_PATH}}
96
102
  - if: ${{ '{{GATE_RUNTIME}}' == 'python' }}
97
103
  uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
98
104
  with: { python-version: '{{GATE_PY_VERSION}}' }
99
- # MMI-Hub#3446: assert the runtime toolchain is on PATH BEFORE the install step. A runner whose
100
- # node/npm (or python) is missing, or whose setup step raced, fails `{{GATE_INSTALL_CMD}}` with a
101
- # bare `command not found` (exit 127) that reads like a broken diff and abandons a correct PR in an
102
- # autonomous merge loop. This names the RUNNER instead — a distinguishable infra failure that
103
- # `mmi-cli devops pr checks-wait` classifies as rerunnable (title `CI runner toolchain`), mirroring the
104
- # disk (#3366) and browser (#808) preflights. No test ran; the diff is not implicated.
105
- - name: Toolchain preflight
106
- if: ${{ '{{GATE_RUNTIME}}' == 'node' }}
107
- run: |
108
- node -v && npm -v || { echo "::error title=CI runner toolchain::RUNNER NOT PROVISIONED — node/npm not on PATH after setup-node. This is the runner, not your diff; no install or test ran. Re-run the job (a fresh lane usually clears it); if it persists the mmi-runner node toolchain needs attention (docs/Guides/gh-runner-runbook.md in MMI-Hub)."; exit 1; }
105
+ # MMI-Hub#3446: assert the runtime toolchain is on PATH BEFORE the install step. Node uses the
106
+ # runner-node-toolchain composite above (setup-node + preflight in one action, #5610). Python
107
+ # keeps the inline preflight below.
109
108
  - name: Toolchain preflight
110
109
  if: ${{ '{{GATE_RUNTIME}}' == 'python' }}
111
110
  run: |
@@ -53,12 +53,9 @@ mmi-cli oracle org access role <owner/repo> --json
53
53
  mmi-cli doctor --no-repo-writes
54
54
  ```
55
55
 
56
- Stop on a red authority or CLI-version result. **Hub hotfix release runs the same distribution fold as
57
- `/release`:** if `process.cwd()` contains whitespace, stop before `hotfix start` / `hotfix release`
58
- touches local `main` (#5603). Relocate the clone to a real no-space path. A subst / junction /
59
- drive-letter alias that hides spaces is not a valid workaround — canonical-root containment still
60
- sees the physical path, so materialization inputs resolve outside the alias root. See `/release`
61
- Step 0e.
56
+ Stop on a red authority or CLI-version result. Hub hotfix release runs the same distribution fold as
57
+ `/release`; its hook-contract verifier executes adapter commands as a native argv without a shell
58
+ (#5605), so a checkout path containing spaces is supported.
62
59
 
63
60
  The worktree must be clean; move scratch into `tmp/` or
64
61
  gitignore it rather than widening the hotfix diff. A TRACKED path named in a `working tree must be clean
@@ -109,8 +109,6 @@ development` inside it fails outright when `development` is already checked out
109
109
  worktrees cannot have the same branch checked out twice). If you are in such a worktree, exit it first and
110
110
  run the release from the primary checkout.
111
111
 
112
- **Hub `/release` also refuses a checkout path that contains spaces — prove that in Step 0e before touching local `main`.** A subst/junction/alias that hides the spaces is not a workaround.
113
-
114
112
  The clean-tree check rejects UNTRACKED scratch too, not just modified tracked files. When `--apply` or
115
113
  `--resume` stops with `working tree must be clean before …`, run `git status --porcelain` on the paths it
116
114
  named and read BOTH status columns before touching anything (#1472, #4004):
@@ -144,6 +142,23 @@ git rev-list --count origin/main..origin/development
144
142
  ```
145
143
  `0` → stop ("nothing to release").
146
144
 
145
+ **Checkout topology — verify the lane's refs exist locally before apply (#5624).** A fresh single-branch
146
+ `development` clone has no local `main`; the train then fails or rolls back at `git checkout main`. Before
147
+ any merge or `--apply`, confirm every ref the lane will touch is present as a local tracking branch:
148
+
149
+ ```bash
150
+ git branch --list development main # direct-track (and full-track --dev)
151
+ git branch --list rc main # full-track rc → main
152
+ ```
153
+
154
+ A missing ref is a topology gap, not a train failure — materialize it from origin, never force past it:
155
+
156
+ ```bash
157
+ git fetch origin main:main # (or development:development / rc:rc) — creates the local ref
158
+ ```
159
+
160
+ Re-run the `--list` until every ref the lane touches is present, then proceed.
161
+
147
162
  ## Step 0a — stale CLI preflight (#1410)
148
163
 
149
164
  Before local gates or `release --apply`, ensure the repo-local / PATH `mmi-cli` matches the released train
@@ -182,6 +197,19 @@ A different npm MAJOR (e.g. local 12 vs. CI's 11) resolves the same lockfile dif
182
197
  <pkg> from lock file` on a lockfile that is not actually broken. Align the local npm major
183
198
  (`npm install -g npm@<CI major>`) and re-run `npm ci` before rewriting or regenerating the lockfile.
184
199
 
200
+ **A pre-tag `npm publish --dry-run` failure whose stack trace is inside npm internals — e.g.
201
+ libnpmpublish cannot find its declared sigstore dependency (`MODULE_NOT_FOUND`) — is toolchain
202
+ corruption / an npm-major mismatch, not a malformed publish surface (#5616).** Compare toolchains
203
+ BEFORE inspecting package contents (deleted dir, malformed `package.json`, missing `files`):
204
+ ```bash
205
+ npm -v
206
+ # green gate npm from the gate log's `node -v && npm -v` toolchain-preflight line (#3446),
207
+ # or the exact node pin in `.github/workflows/gate.yml` (Hub infra gate: node 24.19.0 → npm 11.17.0)
208
+ ```
209
+ When local npm differs from the green gate (e.g. local npm 12 vs CI's 11.17.0), align local npm
210
+ (`npm install -g npm@<gate npm>`) and rerun the train — do not rewrite the publish surface for an
211
+ npm-internal missing module.
212
+
185
213
  **A `npm ci was killed (signal SIGTERM)` failure during the fold is a cold npm cache, not a lockfile or
186
214
  toolchain problem (#4841).** The signature is the kill, not error text: no `Missing:` line, no lockfile
187
215
  complaint at all — the fold's child-process budget expired while a cold cache installed the full tree.
@@ -287,33 +315,6 @@ Current state is compute-at-read + the estate repo-index (`mmi-cli oracle repo-i
287
315
  If shipping code made a hand-written surface wrong, fix it on `development` as an ordinary PR
288
316
  **outside** the train — never as a release Step.
289
317
 
290
- ## Step 0e — Hub checkout path must not contain spaces (#5603)
291
-
292
- **Hub `/release` only. Do this before Step 1 — before any `git checkout main`, merge, or `--apply`.**
293
- The Hub fold runs `scripts/check-hook-contract.mjs`. That verifier's Cursor probe still executes the
294
- adapter command through `shell: true`. An unquoted launcher path is then split at the first space
295
- (`E:\AI Projects\Mutatis Mutandis\MMI-Hub` → `E:\AI`), so the fold never gets a coherent argv. Stop
296
- when the checkout path contains whitespace; do not discover this after local `main` has already moved.
297
-
298
- Prove it from the release checkout:
299
-
300
- ```bash
301
- node -e "const p = process.cwd(); if (/\s/.test(p)) { console.error('Hub /release: checkout path contains spaces:\\n' + p + '\\nStop. Clone or move MMI-Hub to a path with no spaces. subst/junction/alias is not a workaround.'); process.exit(1); }"
302
- ```
303
-
304
- Non-zero → **stop**. Relocate the clone to a real path without spaces (for example `C:\src\MMI-Hub` or
305
- `/opt/mmi/MMI-Hub`) and re-run `/release` from that checkout. Do not reset, merge, or fold on the
306
- spaced tree.
307
-
308
- **A subst / junction / directory-junction / drive-letter alias that hides spaces is not a valid
309
- workaround.** Mapping `E:\AI Projects\Mutatis Mutandis\MMI-Hub` onto `M:\` only hides spaces in the
310
- *logical* cwd. Canonical-root containment still sees the physical path: the fold's materialization
311
- inputs resolve through that physical location, which then sits outside the alias root and fails
312
- containment. Clone or move the repository; do not alias around the spaces.
313
-
314
- This constraint is Hub-fold specific (the hook-contract verifier). Product-repo `/release` does not
315
- run that script; still prefer a no-space checkout.
316
-
317
318
  ## Step 1 — merge to main (never force)
318
319
 
319
320
  Full-track repos:
@@ -361,9 +362,10 @@ What the fold bumps, by repo:
361
362
  prepare` — spine dogfood (`scripts/spine-dogfood.mjs`: verify docs/surfaces + the managed `.gitignore` block),
362
363
  every registry-declared version holder, adapter payload synchronization, build output, and the public
363
364
  artifact bill of materials — then verifies the set (`verify --skip-npm-view`). That prepare path runs
364
- `scripts/check-hook-contract.mjs`; Step 0e must already have passed, or the Cursor probe splits on a
365
- spaced checkout. Publication and staging both derive from `surfaces.json`; there is no second package
366
- list. Claude, Codex, Kimi, Cursor, and Kilo are active.
365
+ `scripts/check-hook-contract.mjs`, which executes host adapter commands as a native argv without a
366
+ shell (#5605), so a checkout path that contains spaces is supported; the spaced-path argv regression
367
+ is pinned in `infra/plugin-set.test.mjs`. Publication and staging both derive from `surfaces.json`;
368
+ there is no second package list. Claude, Codex, Kimi, Cursor, and Kilo are active.
367
369
  - **App-style repos with a root `package.json`** (most products): the manifest + lockfile version via
368
370
  `npm version --no-git-tag-version`, kept in lockstep with the release tag.
369
371
  - **Repos with neither:** nothing to fold — the tag is the version.