@mutmutco/kilo-plugin 3.79.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.
Files changed (40) hide show
  1. package/agent/reviewer.md +108 -0
  2. package/package.json +23 -0
  3. package/scripts/command-ladder-core.mjs +334 -0
  4. package/scripts/command-ladder-gate.mjs +126 -0
  5. package/scripts/deny-gate-crash.mjs +179 -0
  6. package/scripts/edit-tool-paths.mjs +113 -0
  7. package/scripts/env-write-lint.mjs +137 -0
  8. package/scripts/hook-io.mjs +17 -0
  9. package/scripts/hook-policy.mjs +73 -0
  10. package/scripts/hook-run.mjs +170 -0
  11. package/scripts/hook-trace.mjs +108 -0
  12. package/scripts/pretooluse-shell-gates.mjs +420 -0
  13. package/scripts/secret-echo-lint.mjs +170 -0
  14. package/scripts/secret-redact.mjs +537 -0
  15. package/scripts/throttle-core.mjs +324 -0
  16. package/scripts/validate-hook.mjs +156 -0
  17. package/scripts/vault-edit-gate.mjs +94 -0
  18. package/server.mjs +237 -0
  19. package/skills/bootstrap/SKILL.md +493 -0
  20. package/skills/bootstrap/seeds/Dockerfile.template +30 -0
  21. package/skills/bootstrap/seeds/README.template.md +36 -0
  22. package/skills/bootstrap/seeds/architecture.template.md +34 -0
  23. package/skills/bootstrap/seeds/decisions-readme.template.md +46 -0
  24. package/skills/bootstrap/seeds/docker-compose.template.yml +26 -0
  25. package/skills/bootstrap/seeds/gate.template.yml +90 -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/browser-automation/SKILL.md +93 -0
  30. package/skills/doctor/SKILL.md +76 -0
  31. package/skills/epic/SKILL.md +87 -0
  32. package/skills/hotfix/SKILL.md +113 -0
  33. package/skills/mmi/SKILL.md +400 -0
  34. package/skills/onboard/SKILL.md +70 -0
  35. package/skills/rcand/SKILL.md +194 -0
  36. package/skills/release/SKILL.md +546 -0
  37. package/skills/resume/SKILL.md +68 -0
  38. package/skills/secrets/SKILL.md +157 -0
  39. package/skills/stage/SKILL.md +151 -0
  40. package/skills/worktree/SKILL.md +86 -0
@@ -0,0 +1,194 @@
1
+ ---
2
+ name: rcand
3
+ description: Promote development to a release-candidate branch.
4
+ ---
5
+
6
+ # /rcand — promote development to release-candidate
7
+
8
+ Merge `development → rc`, tag `vX.Y.0-rc.N`, push (the GitHub authority gate), then dispatch the rc deploy
9
+ path. **Train-authority gated (D14):** the repo's project-admin or the master. Direct-track repos
10
+ (product repos with `releaseTrack: direct`, plus MMI-Hub via the `isHubControlRepo` special-case) are the exception: they skip rc and `/rcand` refuses there;
11
+ run `/release` from `development` instead. The board needs no touch
12
+ here — items reach `Done` when their PR merges to `development` (native close → Done); `rc` is a deploy
13
+ stage, not a lane.
14
+
15
+ Authority is **structural + server-checked**: step 0 asks the Hub (`mmi-cli org access role`), and step 4
16
+ pushes to the protected `rc` branch, whose per-repo allowlist carries the same people (master + that repo's
17
+ project-admins). No `.env` role marker. Gate ordering: the tag lands the rc SHA
18
+ for checks, and every deploy side-effect waits until the protected `rc` push accepts that checked SHA.
19
+
20
+ ## Step 0 — train-authority probe (server-side, D14)
21
+
22
+ ```bash
23
+ mmi-cli org access role {owner}/{repo} --json # Hub-verified: { role, train }
24
+ ```
25
+ `train: false` — or ANY error (fail closed) → stop: a product repo's train belongs to that repo's
26
+ **project-admin** (repo write + registry `projectAdmins`) or the master. When `project-admin` + `train`,
27
+ proceed — do not redirect to the master (`AGENTS.md` § Authority). Errors → fix `gh auth` first,
28
+ never proceed unverified.
29
+
30
+ **CLI freshness (#2562):** check the running CLI is current BEFORE step 1 — `mmi-cli rcand --apply` refuses
31
+ a stale CLI at its own step 0 (pre-mutation), but the manual steps below mutate local state earlier, so a
32
+ stale CLI discovered late reads as a mid-train abort. When another train just published a new CLI (e.g. a
33
+ Hub release), run `mmi-cli doctor --apply --no-repo-writes` first. A stale-CLI refusal itself changes
34
+ nothing; after updating, the rerun resumes any partial train state safely.
35
+
36
+ **Run from the checkout that already has `development` — never a fresh isolated worktree (#2770).** This is
37
+ a shared-branch train operation (merge/tag/push against origin's protected `rc`), not an isolated
38
+ feature-branch edit. A background-job harness that isolates every task into a fresh worktree by default
39
+ breaks here: `git worktree`s cannot have the same branch checked out twice, so a fresh worktree can't check
40
+ out `development` while the primary checkout already has it. Exit any such worktree first and run from the
41
+ primary checkout.
42
+
43
+ ## Step 1 — development ahead of rc?
44
+
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).
48
+ ```bash
49
+ git fetch origin
50
+ git rev-list --count origin/rc..origin/development
51
+ ```
52
+ Dirty → stop. Count `0` → stop ("nothing to promote"). `>0` → capture the commit list for the report.
53
+
54
+ > Verifying CLI/plugin-health before a train? Use `mmi-cli doctor --apply --no-repo-writes`: it runs the
55
+ > env/plugin repairs but never mutates the working tree, so a pending org-managed `.gitignore` repair is
56
+ > reported with its follow-up command instead of dirtying the product checkout right before promotion.
57
+ > Apply that follow-up after the train.
58
+
59
+ ## Step 1b — registry + rc secret-name preflight
60
+
61
+ Resolve the project META first; its `deployModel` decides the deploy path. `tenant-container` repos use the
62
+ central tenant deployer and therefore need DEPLOY# coords. Serverless, `registry-publish`, and
63
+ `solo-container` repos deploy from their own workflow, so do **not** dispatch `tenant-deploy.yml` for them.
64
+ Direct-track repos (`releaseTrack: direct`, e.g. MMI-Hub) have no rc candidate path; `mmi-cli rcand --apply`
65
+ refuses after this preflight.
66
+ Verify META + required SSM secret names before touching `rc`:
67
+ ```bash
68
+ mmi-cli org project get {owner}/{repo}
69
+ mmi-cli secrets preflight --stage rc --repo {owner}/{repo}
70
+ ```
71
+ Missing META or secret names → stop and repair the registry/secrets first.
72
+
73
+ ## Step 2 — merge development → rc (never force)
74
+
75
+ ```bash
76
+ git checkout rc
77
+ git pull --ff-only origin rc
78
+ git merge development --no-edit
79
+ ```
80
+ Conflict → `git merge --abort`, report paths, resolve on `development`, re-run.
81
+
82
+ **Exception — version manifests only.** When every conflicted path is a version manifest
83
+ (`package.json` · `package-lock.json`), the incoming `development` side carries the org truth — the
84
+ `/release` version fold (#976) bumps manifests on `main` and the release back-merge brings them to
85
+ `development`, so `development` is always the newer side. Take it deterministically and continue (no
86
+ hand-resolution, no abort):
87
+ ```bash
88
+ git checkout --theirs package.json package-lock.json && git add package.json package-lock.json
89
+ git commit --no-edit
90
+ ```
91
+ Any other conflicted path in the same merge → abort as above. Tag (step 3) only AFTER the merge commit
92
+ exists — a tag minted before the conflict resolution points at the wrong SHA.
93
+
94
+ ## Step 3 — tag the rc
95
+
96
+ The shared helper derives the next rc tag from existing tags (re-run-safe — `-rc.N` increments):
97
+ ```bash
98
+ TAG=$(node scripts/next-version.mjs rc) # -> vX.Y.0-rc.N
99
+ git tag "$TAG"
100
+ ```
101
+
102
+ ## Step 4 — push tag, wait for the REQUIRED checks, then push rc (the gate)
103
+
104
+ Required status checks are **per-repo branch protection, not a fixed list** — MMI-Hub requires `cli` ·
105
+ `infra` · `docs`, but a product repo may require different contexts or none at all (#1045). A fresh merge
106
+ SHA has no check-runs yet, so when checks ARE required, pushing the branch *first* is structurally rejected
107
+ until CI catches up (it then succeeds on a retry — avoidable noise). Push the **tag first**: it lands the
108
+ SHA and triggers the repo's CI without touching the protected branch ref. Then probe what `rc` actually
109
+ requires and wait only for those contexts:
110
+
111
+ ```bash
112
+ git push origin "vX.Y.0-rc.N" # lands the SHA + triggers the repo's CI
113
+ SHA=$(git rev-parse rc)
114
+ # discover the REQUIRED contexts on rc (classic protection + rulesets; 404 = none from that source):
115
+ gh api repos/{owner}/{repo}/branches/rc/protection/required_status_checks --jq '[.contexts[]]'
116
+ gh api repos/{owner}/{repo}/rules/branches/rc \
117
+ --jq '[.[]|select(.type=="required_status_checks")|.parameters.required_status_checks[].context]'
118
+ # ZERO required contexts -> push rc immediately (the GitHub push gate is the backstop).
119
+ # Otherwise poll until every required context is "success" on $SHA — never a hard-coded list, and bound
120
+ # the wait (~10 min): on timeout, stop with a clear failure naming the pending/failed contexts.
121
+ gh api repos/{owner}/{repo}/commits/$SHA/check-runs \
122
+ --jq '[.check_runs[]|{name:.name,conclusion:.conclusion}]'
123
+ git push origin rc
124
+ ```
125
+ (`mmi-cli rcand --apply` performs this discovery + bounded wait itself.)
126
+ Rejected (protected / not a bypass actor) → stop, nothing deployed, no board writes; leave the local tag
127
+ for an authorized re-push, never force. Non-fast-forward → re-pull, re-run from step 1.
128
+
129
+ ## Step 5 — rc deploy (model-specific, non-blocking)
130
+
131
+ For `tenant-container` repos, dispatch the Hub **tenant-deploy.yml** workflow for rc (OIDC, keyless). Don't
132
+ deploy by hand, and **don't block on it** — start the watch as a background task and move straight to
133
+ Step 6:
134
+ ```bash
135
+ gh workflow run tenant-deploy.yml --repo mutmutco/MMI-Hub \
136
+ -f slug={slug} -f repo={owner}/{repo} -f ref=rc -f stage=rc
137
+ gh run watch "$(gh run list --workflow tenant-deploy.yml --limit 1 --json databaseId -q '.[0].databaseId')" \
138
+ --exit-status # run this in the BACKGROUND (Bash run_in_background) — capture its URL for the report
139
+ ```
140
+
141
+ For serverless repos, do **not** dispatch `tenant-deploy.yml`: their own push-triggered workflow owns the
142
+ rc deploy.
143
+
144
+ `mmi-cli rcand --apply --json` returns the relevant run `runId` + `runUrl` (alongside `deployStatus`), so
145
+ you never hand-correlate Actions. For tenant-container repos, that is the dispatched `tenant-deploy.yml`
146
+ run. For Hub serverless, that is the auto-fired `deploy.yml` run from the protected `rc` push. Add
147
+ `--watch` to block on the run and have `deployStatus` resolve to `success`/`failure`; `promoted: true`
148
+ stays set either way — a failed **deploy** never undoes the **promotion**.
149
+
150
+ The deploy runs while you report. When the background watch returns, surface the outcome:
151
+ **green** → note the run + rc env URL; **red** → report plainly. The rc tag is already pushed, so the
152
+ correct next action is a **deploy retry of the existing rc ref** after the Hub runtime is repaired — never
153
+ a re-tag/re-merge:
154
+ ```bash
155
+ mmi-cli runtime tenant redeploy {owner}/{repo} rc --watch # re-dispatch tenant-deploy.yml for the promoted rc
156
+ ```
157
+ **Branch the recovery by failure class — a bare redeploy is NOT always the whole recovery.** For **exit 78**
158
+ (`compose is fileless but DEPLOY#<stage>.noEnvFile is not true`) a plain redeploy fails identically: the
159
+ box's baked `/opt/mmi-control/<slug>.sh` still carries the stale `noEnvFile`, so it writes no `.env` while
160
+ the fileless compose expects passthrough. Fix the registry AND re-render the box control script first, then
161
+ redeploy (`set-deploy` alone is not enough — the reconcile is the discoverable-but-non-obvious middle step):
162
+ ```bash
163
+ mmi-cli org project set-deploy {owner}/{repo} --stage rc --no-env-file true # register the DEPLOY#rc fileless flag
164
+ mmi-cli runtime tenant reconcile {owner}/{repo} rc --watch # Hub-authorized; project-admin needs no MMI-Hub Actions access
165
+ mmi-cli runtime tenant redeploy {owner}/{repo} rc --watch # NOW the redeploy reads the corrected control script
166
+ mmi-cli runtime tenant control {owner}/{repo} rc verify-broker --watch # value-free broker proof for runtime consumers
167
+ ```
168
+ The reconcile must finish green before redeploy starts; `--watch` enforces that ordering. A failed rc
169
+ dispatch stays fail-loud — rc is ephemeral and re-runnable, so the redeploy (after the reconcile step above
170
+ for an exit-78 fileless mismatch) re-runs it.
171
+
172
+ ## Step 6 — report
173
+
174
+ Version `vX.Y.0-rc.N` · merged commits · rc deploy run + env URL.
175
+
176
+ ## Notes
177
+
178
+ - `rc` is NOT prod. Shipping `rc → main → prod` is `/release` (ships exactly what's on `rc`; never pulls
179
+ `development`). Never force-push `rc`; never commit to `rc` outside the step-2 merge.
180
+ - `rc` is **ephemeral**: `/rcand` creates the rc runtime, `/release` retires it after a confirmed prod
181
+ deploy. A full-track repo can skip rc entirely with `/release --dev` (`development → main`); `/hotfix`
182
+ always skips rc (it cherry-picks `development → main` directly).
183
+ - **MAJOR / exact-target cycle:** for a release the tag math can't derive (a MAJOR like `2.0.0`, or skipping
184
+ a version already on npm), export `MMI_RELEASE_VERSION=X.Y.Z` before `/rcand` — `next-version.mjs rc` then
185
+ opens that exact cycle (validated to move strictly forward). Keep it exported through `/release`.
186
+
187
+ ## Retro — one check before you finish
188
+ Before your final report, answer one question honestly: did **this skill's own instructions** misfire
189
+ this run — ambiguous wording, a misleading message, or an environment failure it should have warned
190
+ about? (Process only — never the user's code or task; e.g. a misleading authority or gate message, or an
191
+ ambiguous tag or push-order step.) If yes, file **one** lesson and move on; a clean run is silent (hard
192
+ cap: one per run). It lands on the Hub board (deduped) and is fixed only via a reviewed PR — never edit
193
+ the skill live; the retro is advisory, so if the call fails, note it and continue:
194
+ `mmi-cli skill-lesson --skill rcand --title "<what misfired>" --body "<what; evidence; proposed amendment>"`