@mutmutco/codex-plugin 4.0.15 → 4.0.16

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mmi",
3
- "version": "4.0.15",
3
+ "version": "4.0.16",
4
4
  "mmiCompat": "4.x",
5
5
  "description": "MMI workflow skills and org gates delivery.",
6
6
  "author": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mutmutco/codex-plugin",
3
- "version": "4.0.15",
3
+ "version": "4.0.16",
4
4
  "description": "MMI workflow skills and org gates delivery.",
5
5
  "author": {
6
6
  "name": "MMI Future",
@@ -45,6 +45,12 @@ nothing deploys before the protected `main` push accepts that checked SHA.
45
45
  - **Version probes anchor on the latest Release tag, not a branch.** `next-version.mjs` and the fold derive
46
46
  the next version from tags; a branch manifest or a stale local tag is not a version source. (This is why a
47
47
  stray tag must be deleted locally too — a surviving local tag silently mints the *next* version, Step 3.)
48
+ - **One `/release` at a time on a repo (#5380).** Two overlapping `--apply` runs race the shared tag namespace:
49
+ the slower train can tag a SHA that never got a fold commit, while the other sees that tag mid-flight and
50
+ mints the *next* version (a skip). Publish then fails verify (`root package and lockfile versions must
51
+ equal …`) and the broken GitHub Release can briefly hold **Latest**. `mmi-cli devops release --apply`
52
+ fail-closes post-fold / pre-tag when the computed tag (or a newer release tag) appears on origin since
53
+ the plan-phase probe — stop, do not hand-finish, do not start a second train. Recovery is below (Step 3).
48
54
 
49
55
  ## Step 0 — confirm + probe
50
56
 
@@ -181,6 +187,17 @@ not a lockfile failure (#4982).** Rename `node_modules` aside once into a gitign
181
187
  the identical train command. `npm ci` extracts into the now-empty tree and performs no unlinks; do not retry
182
188
  this workaround repeatedly.
183
189
 
190
+ **A fold failure outside `npm ci` is often the repo's own npm lifecycle script, not a toolchain or lockfile
191
+ problem (#5365).** App-style folds run `npm version`, which fires `preversion` / `version` / `postversion`
192
+ (e.g. sync-workspace-version + refresh-distribution-bom); Hub folds run `release-distribution.mjs prepare`,
193
+ which likewise executes repo scripts. When those fail, the train surfaces only
194
+ `fold failed; local main was reset` — the real error is one layer down. Open the newest npm debug log
195
+ (path printed by npm, typically under the npm cache `_logs/`) and read the verbose title / argv: if it
196
+ names `npm version …` (or another non-`ci` command) and a `runScript` / lifecycle command failed, run that
197
+ script standalone (e.g. `node scripts/refresh-distribution-bom.mjs`) to get the real error in seconds.
198
+ Do this **before** suspecting npm major (#4578), cold cache (#4841), EPERM/EBUSY (#4982), or regenerating
199
+ the lockfile — those classes apply to install failures, not to a script that already had `node_modules`.
200
+
184
201
  **Then check the version yourself — do not rely on doctor having printed a row (#3674).** "Read the rows"
185
202
  resolves to "proceed" when the row is *absent*, and doctor's version row is conditional. On 2026-07-27 this
186
203
  step reported healthy with no version line while the installed CLI was 3.70.0 against a released 3.71.0;
@@ -309,6 +326,10 @@ What the fold bumps, by repo:
309
326
 
310
327
  Nothing to do by hand; the `--apply` result reports the fold outcome (`versionFold`).
311
328
 
329
+ When the fold fails here, classify with Step 0a's fold-failure notes before retrying or touching the
330
+ lockfile. If the failure is outside `npm ci`, read the npm debug log's verbose title/argv and run the
331
+ named lifecycle script standalone (#5365) — do not stop at `fold failed; local main was reset`.
332
+
312
333
  ## Step 2 — tag the release
313
334
 
314
335
  Full-track repos drop the `-rc.N` suffix from the open cycle. Direct-track repos use the next cycle directly
@@ -381,6 +402,16 @@ delete — mint the next version with `MMI_RELEASE_VERSION` instead. The CLI alr
381
402
  (`isStrayUnreleasedTag`, `cli/src/train-apply.ts`); this note surfaces the doctrine so a halted operator does
382
403
  not re-derive it from source.
383
404
 
405
+ **Halted by a concurrent-train refusal, or a publish verify that says package/lockfile versions ≠ the tag
406
+ (#5380)?** Same deletion class as a stray tag, plus the GitHub Release if one was created (it may still show
407
+ as **Latest** while broken). Evidence shape: two tags one patch apart from overlapping `/release` runs (e.g.
408
+ `v3.1.11` on a no-fold SHA + `v3.1.12` minted because that tag landed mid-flight), and verify text like
409
+ `root package and lockfile versions must equal 3.1.11`. Do **not** leave the skip-version tag and continue —
410
+ with the authorized human's go: delete the broken Release (`gh release delete vX.Y.Z --yes`), delete the
411
+ stray tag locally and on origin, confirm `next-version` would re-derive the *same* version (not the skip),
412
+ then re-run a **single** `mmi-cli devops release --apply`. If the newer skip-version already published
413
+ cleanly, keep it and only remove the broken older Release/tag.
414
+
384
415
  ## Step 4 — GitHub Release + start prod deploy (non-blocking)
385
416
 
386
417
  For `tenant-container` repos, publish the GitHub Release and dispatch the central tenant deploy.
@@ -551,15 +582,36 @@ don't publish by hand.
551
582
  Watch it, then confirm npm caught up:
552
583
  ```bash
553
584
  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 "vX.Y.0" # asserts registry versions, BOM identities, and published npm artifacts
585
+ node scripts/release-distribution.mjs verify "X.Y.0" # bare semver — asserts registry versions, BOM identities, and published npm artifacts
555
586
  ```
587
+ **verify takes bare semver (#5379).** Pass `X.Y.Z`, not the git-tag form `vX.Y.Z`. Checkout still
588
+ uses the tag (`git checkout "vX.Y.0"`); the distribution script's version argument is strict semver
589
+ without a leading `v`.
556
590
  Run that verify from a checkout **at the tag** (`main` right after the release merge, `git checkout
557
591
  "vX.Y.0"`, or a worktree at the tag) — verify checks the working tree and refuses any other commit once
558
592
  the tag exists, so a stale `development`/`rc` checkout can't masquerade as a broken release.
559
593
  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 "vX.Y.0"`
594
+ identity. Manual fallback if CI can't publish: `node scripts/release-distribution.mjs publish "X.Y.0"`
561
595
  from a machine with npm auth.
562
596
 
597
+ **npm tarball identity is packer-sensitive (#5366 / #5251).** `verify` without `--skip-npm-view`
598
+ compares the registry's served `dist.integrity` (SSRI) against a live `npm pack` on THIS machine
599
+ (`packedIntegrityBySurface`). A tarball SSRI covers file modes and packer (npm version) behavior, so
600
+ that identity step is authoritative **only** when run in the publish environment (`publish.yml` on the
601
+ self-hosted Linux runner) — or on an operator machine with the **same OS and npm major** as that
602
+ runner. Elsewhere (Windows, a clean Linux container with a different packer, a mismatched npm major) a
603
+ `tarball identity mismatch` can false-fail even when the published bytes match the tag: three different
604
+ SSRIs (registry / Windows pack / container pack) with content-identical unpacked trees is the expected
605
+ cross-environment shape, not a substituted artifact. Off the publish environment, either:
606
+ - fall back to an **unpacked-content** proof — download the registry tarball (`npm pack <pkg>@X.Y.Z`
607
+ from the registry, or `npm view … dist.tarball`), `npm pack` from the tag checkout, unpack both, and
608
+ `diff -r` the trees (empty diff ⇒ identity OK; do not alarm on SSRI alone), or
609
+ - skip the registry identity read with
610
+ `node scripts/release-distribution.mjs verify "X.Y.0" --skip-npm-view` and verify published content
611
+ by hand the same way.
612
+ Do not treat an off-runner SSRI mismatch as a broken release, and do not change how the runner publishes
613
+ to paper over a local packer difference.
614
+
563
615
  **Private packages (#2405) — never trust a bare `npm view` to mean "not published".** An unauthenticated
564
616
  `npm view <pkg>` returns a hard 404 on any package published with `publishConfig.access=restricted`
565
617
  (private) — indistinguishable from "not published" — because npm masks private packages from anonymous
@@ -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