@mutmutco/kilo-plugin 3.82.0 → 3.84.0

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/kilo-plugin",
3
- "version": "3.82.0",
3
+ "version": "3.84.0",
4
4
  "description": "MMI workflow skills and org gates delivery.",
5
5
  "author": {
6
6
  "name": "MMI Future",
@@ -128,6 +128,8 @@ for `rc`/`main` (#3433). `$FIRST` is the track's first branch: `development` for
128
128
  FIRST=development # full / direct
129
129
  FIRST=main # trunk (content)
130
130
 
131
+ # One-time namespace + first-ref creation uses the authenticated master-admin GitHub session. The current
132
+ # mmi-cli has no App-backed command for a repository that does not exist; this is the named exception.
131
133
  gh repo create "$OWNER/$REPO" --private
132
134
  gh api -X PUT "repos/$OWNER/$REPO/contents/.gitkeep" \
133
135
  -f message="chore: initial commit" -f content="Cg==" -f branch="$FIRST"
@@ -136,6 +138,11 @@ gh api -X PUT "repos/$OWNER/$REPO/contents/.gitkeep" \
136
138
  On an empty repo that PUT creates `$FIRST` **and leaves it the default branch**, so no `gh repo edit
137
139
  --default-branch` is needed here. Skip this step when the repo already exists with the track's default branch.
138
140
 
141
+ The two `gh` writes above are authorized by the authenticated master-admin login and are the one-time
142
+ bootstrap exception while no App-backed `mmi-cli` command owns a repository that does not yet exist. They
143
+ are not a general write lane: after the namespace and first ref exist, use the App-backed
144
+ `mmi-cli bootstrap apply --execute` path for managed seeds, labels, rulesets, and registry state.
145
+
139
146
  For a **content** repo the API form is not merely tidier, it is the only thing that works: `main` is that
140
147
  track's first and only branch, so the initial commit IS a push to `main` and the #1660 guard fences it — and
141
148
  the deny's own advice ("land through a CI-gated PR to development") is meaningless on a repo with no commits,
@@ -9,6 +9,14 @@ Turn one large item — a vision issue, an epic, an umbrella issue — into a se
9
9
  single pre-validated batch, each already linked to its parent. This is the slice-and-fan-out act done by
10
10
  hand today: draft the children, validate them all, create them, confirm the tree.
11
11
 
12
+ ## Opening branch — create a new umbrella when none exists
13
+
14
+ When the request is a product intent rather than an existing issue, gather the intent first, read the
15
+ repo's live issue templates, draft the umbrella from the matching feature/task template, and show that
16
+ draft for the user's go. Only then create one issue with the `epic` label and an explicit Priority field;
17
+ re-read it from the board to prove the body, label, and priority landed. Stop there unless the user also
18
+ asked for and approved child decomposition.
19
+
12
20
  ## Step 0 — load the umbrella whole
13
21
 
14
22
  Read the parent end-to-end before slicing — body **and every comment**, treating later comments as
@@ -28,7 +36,7 @@ Write a JSON array (one object per child) to a scratch path under `tmp/`. Each r
28
36
  ```json
29
37
  [
30
38
  { "type": "task", "title": "C1: extract the shared frame", "body": "…", "priority": "high",
31
- "parent": "owner/repo#42" },
39
+ "surface": "cli", "parent": "owner/repo#42" },
32
40
  { "type": "feature", "title": "C2: wire the new command", "body": "…", "priority": "medium",
33
41
  "parent": "owner/repo#42" }
34
42
  ]
@@ -40,6 +48,8 @@ Write a JSON array (one object per child) to a scratch path under `tmp/`. Each r
40
48
  create, so you do not need a separate `link-child` pass. Cross-repo is fine (a Hub umbrella can parent
41
49
  product-repo children).
42
50
  - `priority` — `urgent|high|medium|low` (defaults to `medium`); sets the board Priority **field**.
51
+ - `surface` — required when the target repo uses `surface:*` taxonomy; accepts the value with or without
52
+ the prefix. A top-level `--surface <value>` may supply the default for every applicable row.
43
53
 
44
54
  The batch **pre-validates every row before creating any** — one bad row fails the whole set with an
45
55
  aggregate error, so you fix all of them once. Get the user's go on the drafted set before writing.
@@ -47,13 +57,18 @@ aggregate error, so you fix all of them once. Get the user's go on the drafted s
47
57
  ## Step 2 — create the children
48
58
 
49
59
  ```bash
50
- mmi-cli issue create --type task --batch tmp/epic-children.json
60
+ mmi-cli issue create --type task --batch tmp/epic-children.json --surface cli
51
61
  ```
52
62
 
53
63
  `--type` is required by the create command but each row's own `type` governs; pass any valid type as the
54
64
  placeholder. It prints per-row `{number,url}` results and fails loud on any misfire. Add
55
65
  `--idempotency-key <key>` when a retried loop must not duplicate.
56
66
 
67
+ The idempotency lookup is find-before-create, not an atomic reservation. Run one batch writer at a time:
68
+ never submit concurrent creates with the same key. Size the calling command's wall-clock budget for the
69
+ whole sequential batch. If the command times out, its outcome is unknown — confirm the process has ended,
70
+ wait for writes to quiesce, inspect the children, then retry the missing rows with the same key.
71
+
57
72
  ## Step 3 — confirm the tree
58
73
 
59
74
  ```bash
@@ -38,7 +38,11 @@ mmi-cli doctor --no-repo-writes
38
38
  ```
39
39
 
40
40
  Stop on a red authority or CLI-version result. The worktree must be clean; move scratch into `tmp/` or
41
- gitignore it rather than widening the hotfix diff.
41
+ gitignore it rather than widening the hotfix diff. A TRACKED path named in a `working tree must be clean
42
+ before …` refusal is not scratch: read both `git status --porcelain` columns, treat every state except
43
+ exactly ` M` as real work to commit or stash, and for ` M` discard only when
44
+ `git diff HEAD --numstat -- <paths>` is empty, and only with `git checkout -- <paths>`. Plain
45
+ `git diff --numstat` prints nothing for a merely staged change, so it cannot make that call (#4004).
42
46
 
43
47
  ## 1. Start from the merged development fix
44
48
 
@@ -43,8 +43,12 @@ primary checkout.
43
43
  ## Step 1 — development ahead of rc?
44
44
 
45
45
  Preconditions: on `development`, clean tree. The clean-tree check rejects UNTRACKED scratch too, not just
46
- modified tracked files — if `--apply` stops with `working tree must be clean before …`, run `git status` and
47
- gitignore the `??` scratch (or move it to a gitignored path like `tmp/`) before retrying (#1472).
46
+ modified tracked files — if `--apply` stops with `working tree must be clean before …`, run `git status
47
+ --porcelain` on the paths it named and read both columns. Gitignore the `??` scratch (or move it to a
48
+ gitignored path like `tmp/`). Treat every tracked state except exactly ` M` as real work to commit or stash;
49
+ for ` M`, discard only when `git diff HEAD --numstat -- <paths>` is empty, and only with
50
+ `git checkout -- <paths>`. Plain `git diff --numstat` prints nothing for a merely staged change, so it
51
+ cannot tell real work from line-ending churn (#1472, #4004).
48
52
  ```bash
49
53
  git fetch origin
50
54
  git rev-list --count origin/rc..origin/development
@@ -72,9 +72,22 @@ breaks here: the new worktree's branch is never literally named `development`/`r
72
72
  development` inside it fails outright when `development` is already checked out in the primary checkout (git
73
73
  worktrees cannot have the same branch checked out twice). If you are in such a worktree, exit it first and
74
74
  run the release from the primary checkout.
75
- The clean-tree check rejects UNTRACKED scratch too, not just modified tracked files if `--apply` stops
76
- with `working tree must be clean before …`, run `git status` and gitignore the `??` scratch (or move it to a
77
- gitignored path like `tmp/`) before retrying (#1472).
75
+ The clean-tree check rejects UNTRACKED scratch too, not just modified tracked files. When `--apply` or
76
+ `--resume` stops with `working tree must be clean before …`, run `git status --porcelain` on the paths it
77
+ named and read BOTH status columns before touching anything (#1472, #4004):
78
+
79
+ - `??` — untracked scratch. Gitignore it, or move it to a gitignored path like `tmp/`, then retry.
80
+ - exactly ` M` (blank staged column) — the only state that can be churn rather than work. Test it with
81
+ `git diff HEAD --numstat -- <paths>`: non-empty is a real edit to commit or stash; empty means the
82
+ worktree normalizes straight back to HEAD (an LF↔CRLF rewrite, say), and `git checkout -- <paths>`
83
+ then clears the refusal without discarding anything.
84
+ - anything else — `M `, `MM`, `A`, `D`, `R`, `T`, or any `U` conflict — is real work or an exceptional
85
+ index state. Commit, stash or resolve it; do not try to classify it.
86
+
87
+ Do not substitute plain `git diff --numstat` for the `HEAD` form. It compares the worktree against the
88
+ INDEX, so a change that is merely staged prints nothing at all, and reading that emptiness as
89
+ "line-ending churn" throws the change away. The remedy is the index form of `git checkout` for the same
90
+ reason: `git checkout HEAD -- <paths>` would overwrite a staged edit that was misread as churn.
78
91
 
79
92
  Full-track repos:
80
93
  ```bash
@@ -139,7 +152,10 @@ Verify META + required SSM secret names before touching `main`:
139
152
  mmi-cli org project get {owner}/{repo}
140
153
  mmi-cli secrets preflight --stage main --repo {owner}/{repo}
141
154
  ```
142
- Missing META or secret names → stop and repair the registry/secrets first.
155
+ An enumerated missing META row or missing secret name → stop and repair the registry/secrets first. An
156
+ HTTP 5xx, timeout, DNS, socket, or other transport failure is **unverified**, not evidence that a name is
157
+ missing: retry the read/preflight and repair connectivity if it persists. Never provision or rename a
158
+ secret from a transport-error response.
143
159
 
144
160
  ## Step 0c — hotfix-coverage guard (fail closed, #839, #958)
145
161
 
@@ -468,6 +484,19 @@ mmi-cli org project sync-info --apply # omit --apply for the read-only plan
468
484
  channel — #3630 took SessionStart off the hook surface) runs the
469
485
  same fast-forward first thing, so a stale local `development`/`main`/`rc` self-heals to origin before you
470
486
  work — no manual `git pull`. Nothing here ever blocks or fails the release.
487
+ - **Read the `checkout:` clause — it does not always say "returned" (#4006).** The report always prints
488
+ one, and restoration is deliberately skipped rather than forced when the repo is not in a fit state.
489
+ A release leaves the repo on `main` until the train moves it back, so a non-`returned` outcome means
490
+ you are still there and must return by hand once the cause is cleared:
491
+ - `checkout restoration skipped: working tree changed after release` — the tree went dirty DURING the
492
+ train, so the train declined to move you. Diagnose those paths with the Step 0 clean-tree rules,
493
+ then `git checkout <start branch>` yourself. The release itself already shipped; this is a
494
+ deliberate, harmless decline, not a failed release.
495
+ - `checkout restoration failed while returning to …` / `origin/<branch> fast-forward failed` — the
496
+ checkout or the pull errored. Read the appended git message; the release is unaffected.
497
+
498
+ `--resume` prints no `checkout:` clause at all, so after a resumed release check `git branch
499
+ --show-current` rather than assuming you were moved back.
471
500
 
472
501
  ## Step 6 — collect deploy verdict + report
473
502
 
@@ -475,6 +504,10 @@ Collect the backgrounded prod-deploy watch from Step 4 (it has typically finishe
475
504
  healthy (the central deploy workflow smoke step / a health check); **red** → report the failure prominently and flag
476
505
  that the release shipped on a failed deploy (re-run just the deploy — `main` is already correct).
477
506
 
507
+ **This distribution verifier is Hub-only.** It assumes the Hub release fold has already committed its
508
+ generated artifacts. Non-Hub `registry-publish` repositories must not run `release-distribution.mjs
509
+ verify`: use their own release-workflow evidence and the publish-visibility contract below.
510
+
478
511
  Hub releases always carry a distribution bump (the Step 1b fold), so the **publish workflow**
479
512
  (`publish.yml`) ships every registry-declared public npm artifact on the GitHub Release from Step 4 —
480
513
  don't publish by hand.
@@ -35,14 +35,16 @@ mmi-cli status
35
35
 
36
36
  `status` is the unified current-state read for **this** checkout: branch, linked worktrees, your open PRs,
37
37
  your claimed board items, and whether a local stage is running. It is the "where am I" line — render it,
38
- don't re-derive it from raw `git`/`gh`.
38
+ don't re-derive it from raw `git`/`gh`. Keep the case-preserving `repo` value it reports; that is the
39
+ workspace identity the next step must use (for example `mutmutco/MMC-ZuberShade`).
39
40
 
40
41
  ## Step 2 — the next move
41
42
 
42
43
  ```bash
43
- mmi-cli next
44
+ mmi-cli next --repo <repo reported by status>
44
45
  ```
45
46
 
47
+ Pass the repository from `status` explicitly; never reconstruct it by changing case or punctuation.
46
48
  `next` recommends the single most actionable claimable board item (unblocked, priority-ranked) and prints
47
49
  the exact `mmi-cli board claim <n>` to take it. Offer it; do not claim on the user's behalf without a go.
48
50
  For the full board partition (yours / claimable / taken) run `/mmi`.