@mutmutco/claude-plugin 4.0.15 → 4.0.17
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
package/skills/release/SKILL.md
CHANGED
|
@@ -38,6 +38,9 @@ nothing deploys before the protected `main` push accepts that checked SHA.
|
|
|
38
38
|
branch's lineage and every tag-anchored check (coverage trailers, misalignment guard, version probes)
|
|
39
39
|
re-flags or mis-reads forever after. Any merge that carries an already-tagged commit — the Step 5
|
|
40
40
|
`main → development` roll-forward, any alignment PR — lands as a **true merge** (`--merge`), never squash.
|
|
41
|
+
`--wait` does not relax this: use `mmi-cli devops pr merge <n> --wait --merge` (or the policy-gated
|
|
42
|
+
`--auto --merge`). `--wait` alone still defaults the CLI merge method to squash and must not land an
|
|
43
|
+
alignment / tagged-commit-carrying PR.
|
|
41
44
|
- **A refused train is a stop, never a license to finish by hand.** Every fail-closed halt below — authority
|
|
42
45
|
probe, coverage guard, untolerated conflict, required checks, stray tag — ends the run. The recovery is
|
|
43
46
|
always to fix the cause and re-run the train; it is never hand-resolving on `main`, bare-pushing a train
|
|
@@ -45,6 +48,12 @@ nothing deploys before the protected `main` push accepts that checked SHA.
|
|
|
45
48
|
- **Version probes anchor on the latest Release tag, not a branch.** `next-version.mjs` and the fold derive
|
|
46
49
|
the next version from tags; a branch manifest or a stale local tag is not a version source. (This is why a
|
|
47
50
|
stray tag must be deleted locally too — a surviving local tag silently mints the *next* version, Step 3.)
|
|
51
|
+
- **One `/release` at a time on a repo (#5380).** Two overlapping `--apply` runs race the shared tag namespace:
|
|
52
|
+
the slower train can tag a SHA that never got a fold commit, while the other sees that tag mid-flight and
|
|
53
|
+
mints the *next* version (a skip). Publish then fails verify (`root package and lockfile versions must
|
|
54
|
+
equal …`) and the broken GitHub Release can briefly hold **Latest**. `mmi-cli devops release --apply`
|
|
55
|
+
fail-closes post-fold / pre-tag when the computed tag (or a newer release tag) appears on origin since
|
|
56
|
+
the plan-phase probe — stop, do not hand-finish, do not start a second train. Recovery is below (Step 3).
|
|
48
57
|
|
|
49
58
|
## Step 0 — confirm + probe
|
|
50
59
|
|
|
@@ -181,6 +190,17 @@ not a lockfile failure (#4982).** Rename `node_modules` aside once into a gitign
|
|
|
181
190
|
the identical train command. `npm ci` extracts into the now-empty tree and performs no unlinks; do not retry
|
|
182
191
|
this workaround repeatedly.
|
|
183
192
|
|
|
193
|
+
**A fold failure outside `npm ci` is often the repo's own npm lifecycle script, not a toolchain or lockfile
|
|
194
|
+
problem (#5365).** App-style folds run `npm version`, which fires `preversion` / `version` / `postversion`
|
|
195
|
+
(e.g. sync-workspace-version + refresh-distribution-bom); Hub folds run `release-distribution.mjs prepare`,
|
|
196
|
+
which likewise executes repo scripts. When those fail, the train surfaces only
|
|
197
|
+
`fold failed; local main was reset` — the real error is one layer down. Open the newest npm debug log
|
|
198
|
+
(path printed by npm, typically under the npm cache `_logs/`) and read the verbose title / argv: if it
|
|
199
|
+
names `npm version …` (or another non-`ci` command) and a `runScript` / lifecycle command failed, run that
|
|
200
|
+
script standalone (e.g. `node scripts/refresh-distribution-bom.mjs`) to get the real error in seconds.
|
|
201
|
+
Do this **before** suspecting npm major (#4578), cold cache (#4841), EPERM/EBUSY (#4982), or regenerating
|
|
202
|
+
the lockfile — those classes apply to install failures, not to a script that already had `node_modules`.
|
|
203
|
+
|
|
184
204
|
**Then check the version yourself — do not rely on doctor having printed a row (#3674).** "Read the rows"
|
|
185
205
|
resolves to "proceed" when the row is *absent*, and doctor's version row is conditional. On 2026-07-27 this
|
|
186
206
|
step reported healthy with no version line while the installed CLI was 3.70.0 against a released 3.71.0;
|
|
@@ -277,7 +297,8 @@ why (a hotfix freezes a snapshot that `development` can keep rewriting).
|
|
|
277
297
|
Alignment PRs are the exception to the org's squash default: land them with a true merge —
|
|
278
298
|
`mmi-cli devops pr merge <n> --auto --merge` (not squash; a squash discards the merge parentage, so the
|
|
279
299
|
misalignment guard re-flags the same divergence on the next run). `--auto` clears the checks the PR
|
|
280
|
-
triggers, which block an immediate merge right after a release.
|
|
300
|
+
triggers, which block an immediate merge right after a release. When awaiting checks inline, keep
|
|
301
|
+
`--merge`: `mmi-cli devops pr merge <n> --wait --merge` — `--wait` alone is not enough (merge floor above).
|
|
281
302
|
|
|
282
303
|
**Exception — version-manifest and `.gitignore` paths.** `mmi-cli devops release --apply` tolerates
|
|
283
304
|
conflicts confined to the version-fold paths (Step 1b) and `.gitignore` (#1037 — a
|
|
@@ -309,6 +330,10 @@ What the fold bumps, by repo:
|
|
|
309
330
|
|
|
310
331
|
Nothing to do by hand; the `--apply` result reports the fold outcome (`versionFold`).
|
|
311
332
|
|
|
333
|
+
When the fold fails here, classify with Step 0a's fold-failure notes before retrying or touching the
|
|
334
|
+
lockfile. If the failure is outside `npm ci`, read the npm debug log's verbose title/argv and run the
|
|
335
|
+
named lifecycle script standalone (#5365) — do not stop at `fold failed; local main was reset`.
|
|
336
|
+
|
|
312
337
|
## Step 2 — tag the release
|
|
313
338
|
|
|
314
339
|
Full-track repos drop the `-rc.N` suffix from the open cycle. Direct-track repos use the next cycle directly
|
|
@@ -381,6 +406,16 @@ delete — mint the next version with `MMI_RELEASE_VERSION` instead. The CLI alr
|
|
|
381
406
|
(`isStrayUnreleasedTag`, `cli/src/train-apply.ts`); this note surfaces the doctrine so a halted operator does
|
|
382
407
|
not re-derive it from source.
|
|
383
408
|
|
|
409
|
+
**Halted by a concurrent-train refusal, or a publish verify that says package/lockfile versions ≠ the tag
|
|
410
|
+
(#5380)?** Same deletion class as a stray tag, plus the GitHub Release if one was created (it may still show
|
|
411
|
+
as **Latest** while broken). Evidence shape: two tags one patch apart from overlapping `/release` runs (e.g.
|
|
412
|
+
`v3.1.11` on a no-fold SHA + `v3.1.12` minted because that tag landed mid-flight), and verify text like
|
|
413
|
+
`root package and lockfile versions must equal 3.1.11`. Do **not** leave the skip-version tag and continue —
|
|
414
|
+
with the authorized human's go: delete the broken Release (`gh release delete vX.Y.Z --yes`), delete the
|
|
415
|
+
stray tag locally and on origin, confirm `next-version` would re-derive the *same* version (not the skip),
|
|
416
|
+
then re-run a **single** `mmi-cli devops release --apply`. If the newer skip-version already published
|
|
417
|
+
cleanly, keep it and only remove the broken older Release/tag.
|
|
418
|
+
|
|
384
419
|
## Step 4 — GitHub Release + start prod deploy (non-blocking)
|
|
385
420
|
|
|
386
421
|
For `tenant-container` repos, publish the GitHub Release and dispatch the central tenant deploy.
|
|
@@ -498,7 +533,8 @@ mmi-cli oracle org project sync-info --apply # omit --apply for the read-only
|
|
|
498
533
|
PR with a true merge** — `mmi-cli devops pr merge <number> --auto --merge` (never squash — a squash drops the merge
|
|
499
534
|
parentage and the misalignment guard re-flags the divergence). `--auto` is what makes it land right after a
|
|
500
535
|
release: the alignment PR's own `cli`/`infra`/`docs` checks are still running, so a plain immediate merge is
|
|
501
|
-
policy-blocked — `--auto` merges once they pass.
|
|
536
|
+
policy-blocked — `--auto` merges once they pass. If you await with `--wait` instead, still pass `--merge`
|
|
537
|
+
(`mmi-cli devops pr merge <number> --wait --merge`); `--wait` alone must not land the alignment PR. Never force.
|
|
502
538
|
- Full-track repos: `mmi-cli devops release --apply` already aligned `rc` to the released `main` (#1036 — the
|
|
503
539
|
push runs inside the authority-gated train; the result reports it as `rcAlignment`). No manual `rc`
|
|
504
540
|
push — if the result reports a failed alignment, investigate and rerun via the train, never bare-push.
|
|
@@ -551,15 +587,36 @@ don't publish by hand.
|
|
|
551
587
|
Watch it, then confirm npm caught up:
|
|
552
588
|
```bash
|
|
553
589
|
gh run watch "$(gh run list --workflow publish.yml --event release --limit 1 --json databaseId -q '.[0].databaseId')" --exit-status
|
|
554
|
-
node scripts/release-distribution.mjs verify "
|
|
590
|
+
node scripts/release-distribution.mjs verify "X.Y.0" # bare semver — asserts registry versions, BOM identities, and published npm artifacts
|
|
555
591
|
```
|
|
592
|
+
**verify takes bare semver (#5379).** Pass `X.Y.Z`, not the git-tag form `vX.Y.Z`. Checkout still
|
|
593
|
+
uses the tag (`git checkout "vX.Y.0"`); the distribution script's version argument is strict semver
|
|
594
|
+
without a leading `v`.
|
|
556
595
|
Run that verify from a checkout **at the tag** (`main` right after the release merge, `git checkout
|
|
557
596
|
"vX.Y.0"`, or a worktree at the tag) — verify checks the working tree and refuses any other commit once
|
|
558
597
|
the tag exists, so a stale `development`/`rc` checkout can't masquerade as a broken release.
|
|
559
598
|
Release-blocking for Hub tooling changes: every public artifact must match the registry version and BOM
|
|
560
|
-
identity. Manual fallback if CI can't publish: `node scripts/release-distribution.mjs publish "
|
|
599
|
+
identity. Manual fallback if CI can't publish: `node scripts/release-distribution.mjs publish "X.Y.0"`
|
|
561
600
|
from a machine with npm auth.
|
|
562
601
|
|
|
602
|
+
**npm tarball identity is packer-sensitive (#5366 / #5251).** `verify` without `--skip-npm-view`
|
|
603
|
+
compares the registry's served `dist.integrity` (SSRI) against a live `npm pack` on THIS machine
|
|
604
|
+
(`packedIntegrityBySurface`). A tarball SSRI covers file modes and packer (npm version) behavior, so
|
|
605
|
+
that identity step is authoritative **only** when run in the publish environment (`publish.yml` on the
|
|
606
|
+
self-hosted Linux runner) — or on an operator machine with the **same OS and npm major** as that
|
|
607
|
+
runner. Elsewhere (Windows, a clean Linux container with a different packer, a mismatched npm major) a
|
|
608
|
+
`tarball identity mismatch` can false-fail even when the published bytes match the tag: three different
|
|
609
|
+
SSRIs (registry / Windows pack / container pack) with content-identical unpacked trees is the expected
|
|
610
|
+
cross-environment shape, not a substituted artifact. Off the publish environment, either:
|
|
611
|
+
- fall back to an **unpacked-content** proof — download the registry tarball (`npm pack <pkg>@X.Y.Z`
|
|
612
|
+
from the registry, or `npm view … dist.tarball`), `npm pack` from the tag checkout, unpack both, and
|
|
613
|
+
`diff -r` the trees (empty diff ⇒ identity OK; do not alarm on SSRI alone), or
|
|
614
|
+
- skip the registry identity read with
|
|
615
|
+
`node scripts/release-distribution.mjs verify "X.Y.0" --skip-npm-view` and verify published content
|
|
616
|
+
by hand the same way.
|
|
617
|
+
Do not treat an off-runner SSRI mismatch as a broken release, and do not change how the runner publishes
|
|
618
|
+
to paper over a local packer difference.
|
|
619
|
+
|
|
563
620
|
**Private packages (#2405) — never trust a bare `npm view` to mean "not published".** An unauthenticated
|
|
564
621
|
`npm view <pkg>` returns a hard 404 on any package published with `publishConfig.access=restricted`
|
|
565
622
|
(private) — indistinguishable from "not published" — because npm masks private packages from anonymous
|
package/skills/stage/SKILL.md
CHANGED
|
@@ -33,6 +33,15 @@ into the compose **process environment** — the compose file reads them via `en
|
|
|
33
33
|
secret ever touches disk. A repo that still ships `.env.example` keeps the legacy `.env` bootstrap for
|
|
34
34
|
back-compat until its compose migrates to passthrough; new repos should ship **no** `.env.example`.
|
|
35
35
|
|
|
36
|
+
**Build-time secrets (#5381).** When META declares `requiredBuildSecrets` (e.g. Katip's
|
|
37
|
+
`NODE_AUTH_TOKEN=@github-packages-token` for `@mutmutco/fofu-ds` on GitHub Packages), `/stage` injects those
|
|
38
|
+
BuildKit ids into the **`docker compose build`** process env only — not into the running container. Central
|
|
39
|
+
deploy mints the packages sentinel from Actions `GITHUB_TOKEN`; a laptop cannot. Resolution order: existing
|
|
40
|
+
process env → stageless project vault secret under the BuildKit id (a `read:packages` PAT at
|
|
41
|
+
`NODE_AUTH_TOKEN`). If both are missing, `/stage` fails with a teaching error before npm's opaque 401.
|
|
42
|
+
Setup: [`docs/Guides/tenant-runtime.md`](../../docs/Guides/tenant-runtime.md) § Local `/stage`. Never commit
|
|
43
|
+
or print the PAT.
|
|
44
|
+
|
|
36
45
|
## Step 0 — inspect the plan
|
|
37
46
|
|
|
38
47
|
```bash
|