@mutmutco/kilo-plugin 3.105.12 → 3.107.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 +1 -1
- package/scripts/secret-echo-lint.mjs +13 -6
- package/scripts/secret-redact.mjs +2 -2
- package/skills/bootstrap/SKILL.md +23 -23
- package/skills/bootstrap/seeds/README.template.md +3 -3
- package/skills/bootstrap/seeds/architecture.template.md +1 -1
- package/skills/bootstrap/seeds/gate.template.yml +1 -1
- package/skills/bootstrap/seeds/google-login.template.md +5 -5
- package/skills/bootstrap/seeds/manifest.json +1 -1
- package/skills/browser-automation/SKILL.md +1 -1
- package/skills/epic/SKILL.md +5 -5
- package/skills/hotfix/SKILL.md +22 -8
- package/skills/mmi/SKILL.md +18 -17
- package/skills/mmi-doctor/SKILL.md +4 -4
- package/skills/onboard/SKILL.md +7 -7
- package/skills/rcand/SKILL.md +14 -14
- package/skills/release/SKILL.md +38 -27
- package/skills/resume/SKILL.md +9 -9
- package/skills/secrets/SKILL.md +18 -18
- package/skills/stage/SKILL.md +1 -1
- package/skills/worktree/SKILL.md +31 -15
package/package.json
CHANGED
|
@@ -91,21 +91,28 @@ function checkBashPrint(segment) {
|
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
function checkPsPrint(segment) {
|
|
94
|
+
// PowerShell accepts both $env:SECRET_VAR and ${env:SECRET_VAR}; keep one matcher so the braced form
|
|
95
|
+
// cannot bypass the same output checks as the ordinary form.
|
|
96
|
+
const envReference = /\$(?:\{env:(\w+)\}|env:(\w+))/gi;
|
|
97
|
+
const envName = (match) => match[1] ?? match[2];
|
|
98
|
+
|
|
94
99
|
// Write-Output / Write-Host / echo with $env:SECRET_VAR
|
|
95
100
|
if (/\b(?:Write-Output|Write-Host|echo)\b/i.test(segment)) {
|
|
96
|
-
for (const m of segment.matchAll(
|
|
97
|
-
|
|
98
|
-
|
|
101
|
+
for (const m of segment.matchAll(envReference)) {
|
|
102
|
+
const name = envName(m);
|
|
103
|
+
if (isSecretName(name)) {
|
|
104
|
+
return { block: true, reason: `Write/echo of $env:${name} prints a secret-named env var` };
|
|
99
105
|
}
|
|
100
106
|
}
|
|
101
107
|
}
|
|
102
108
|
|
|
103
109
|
// $env:SECRET_VAR in output position (start of command or after pipe, not assignment LHS)
|
|
104
|
-
for (const m of segment.matchAll(
|
|
110
|
+
for (const m of segment.matchAll(new RegExp(`(?:^|[;&|]\\s*)${envReference.source}`, 'gi'))) {
|
|
111
|
+
const name = envName(m);
|
|
105
112
|
const after = segment.slice(m.index + m[0].length);
|
|
106
113
|
if (/^\s*=(?!=)/.test(after)) continue; // assignment LHS, not output
|
|
107
|
-
if (isSecretName(
|
|
108
|
-
return { block: true, reason: `$env:${
|
|
114
|
+
if (isSecretName(name)) {
|
|
115
|
+
return { block: true, reason: `$env:${name} in output position prints a secret-named env var` };
|
|
109
116
|
}
|
|
110
117
|
}
|
|
111
118
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//
|
|
1
|
+
// Claude PostToolUse secret redaction (#1589). No throttling, no compaction; fail-soft always.
|
|
2
2
|
// Patterns are self-contained here (conservative, prefix-anchored secret shapes).
|
|
3
3
|
|
|
4
4
|
import { appendHookActivity } from './hook-trace.mjs';
|
|
@@ -498,7 +498,7 @@ export async function runHookGate({ input: buffered } = {}) {
|
|
|
498
498
|
// be tested against UPDATABLE_TOOLS, and it collapsed Codex `shell` and `local_shell` into "PowerShell".
|
|
499
499
|
// #4012 fixed this call's `tool` FIELD and #4015 the stderr arms; the `action` TEXT below was converted
|
|
500
500
|
// by neither, so one row read `{"tool":"shell","action":"secret detected in PowerShell output …"}` and
|
|
501
|
-
// disagreed with itself — in the log doctor, the Stop summary and scrooge.md's detection counts read.
|
|
501
|
+
// disagreed with itself — in the log doctor, the Stop summary and Archive/scrooge.md's detection counts read.
|
|
502
502
|
const alarmTool = tracedTool(input) || decision?.toolName || 'tool';
|
|
503
503
|
const action = !decision
|
|
504
504
|
? 'clean'
|
|
@@ -16,7 +16,7 @@ already be named on the taxonomy `<CATEGORY>-<PascalName>`.
|
|
|
16
16
|
## Seed sources + create-vs-upgrade
|
|
17
17
|
|
|
18
18
|
The org-standard scaffolding is a **machine-readable manifest** — `skills/bootstrap/seeds/manifest.json`
|
|
19
|
-
(loaded by the CLI; `mmi-cli bootstrap apply <repo> [--execute]` consumes it). Every seed carries an **ownership**:
|
|
19
|
+
(loaded by the CLI; `mmi-cli devops bootstrap apply <repo> [--execute]` consumes it). Every seed carries an **ownership**:
|
|
20
20
|
|
|
21
21
|
- **`org`** — org-delivered, **overwritten on upgrade** (the org owns it): the issue templates, the gate
|
|
22
22
|
workflow, and the org-managed `.gitignore` block. `source: self` = copied verbatim from MMI-Hub's own
|
|
@@ -44,7 +44,7 @@ branch (#4241). Running `apply --execute` against every registry repo by hand to
|
|
|
44
44
|
exactly the copy-per-repo pattern this rule exists to end — see Hub#4234.
|
|
45
45
|
|
|
46
46
|
**Rollback is per-repo, never a second fleet overwrite (#4240).** When a propagated `org`-owned seed
|
|
47
|
-
breaks a repo, the recovery is `mmi-cli bootstrap rollback <repo> --target <t> [--execute]` — it resolves
|
|
47
|
+
breaks a repo, the recovery is `mmi-cli devops bootstrap rollback <repo> --target <t> [--execute]` — it resolves
|
|
48
48
|
the ONE merge commit that repo's `bootstrap propagate` (#4238) run actually landed (live from the repo's
|
|
49
49
|
`seed-propagate-<slug>` merged-PR history, or replayed from a persisted propagate `--json` report via
|
|
50
50
|
`--record`) and opens an ordinary revert PR of it, through that repo's own gate, on a `seed-rollback-<slug>`
|
|
@@ -117,9 +117,9 @@ the confirmed values — no silent defaulting.
|
|
|
117
117
|
|
|
118
118
|
Before mutating anything, run the verifier so the current gaps are concrete:
|
|
119
119
|
```bash
|
|
120
|
-
mmi-cli bootstrap verify "$OWNER/$REPO" --class deployable --json
|
|
120
|
+
mmi-cli devops bootstrap verify "$OWNER/$REPO" --class deployable --json
|
|
121
121
|
# or for content repos:
|
|
122
|
-
mmi-cli bootstrap verify "$OWNER/$REPO" --class content --json
|
|
122
|
+
mmi-cli devops bootstrap verify "$OWNER/$REPO" --class content --json
|
|
123
123
|
```
|
|
124
124
|
|
|
125
125
|
Run it again after Step 7. A repo is not ready for real developers until every check is green, or the report
|
|
@@ -166,7 +166,7 @@ On an empty repo that PUT creates `$FIRST` **and leaves it the default branch**,
|
|
|
166
166
|
The two `gh` writes above are authorized by the authenticated master-admin login and are the one-time
|
|
167
167
|
bootstrap exception while no App-backed `mmi-cli` command owns a repository that does not yet exist. They
|
|
168
168
|
are not a general write lane: after the namespace and first ref exist, use the App-backed
|
|
169
|
-
`mmi-cli bootstrap apply --execute` path for managed seeds, labels, rulesets, and registry state.
|
|
169
|
+
`mmi-cli devops bootstrap apply --execute` path for managed seeds, labels, rulesets, and registry state.
|
|
170
170
|
|
|
171
171
|
For a **content** repo the API form is not merely tidier, it is the only thing that works: `main` is that
|
|
172
172
|
track's first and only branch, so the initial commit IS a push to `main` and the #1660 guard fences it — and
|
|
@@ -292,13 +292,13 @@ gh project list --owner "$PROJECT_OWNER" --format json # existing boards to ch
|
|
|
292
292
|
Then **interview the master** for the seed short description + README (what it tracks, member repos, links
|
|
293
293
|
to the repos' `README.md`/`architecture.md`); set them via the `updateProjectV2` mutation
|
|
294
294
|
(`shortDescription`, `readme`). If cloning, verify the built-in workflows survived (next note).
|
|
295
|
-
- **Built-in workflows:** `mmi-cli bootstrap verify` checks these Project workflows are enabled:
|
|
295
|
+
- **Built-in workflows:** `mmi-cli devops bootstrap verify` checks these Project workflows are enabled:
|
|
296
296
|
`Auto-add sub-issues to project`, `Auto-archive items`, `Item added to project`, and `Item closed`. The
|
|
297
297
|
Todo/In Progress/In Review moves are **central** (the Hub webhook); the built-in `Item closed` sets `Done`
|
|
298
298
|
on merge. GitHub's public GraphQL schema exposes delete/read surfaces for Project workflows but no
|
|
299
299
|
create/update/enable mutation; if any required workflow is missing or disabled, repair it in the project's
|
|
300
300
|
**Workflows** settings before calling the repo ready for developers.
|
|
301
|
-
- **Board shape (#4093):** `mmi-cli bootstrap verify` also checks the view triple (`List`/`Board`/`Roadmap`
|
|
301
|
+
- **Board shape (#4093):** `mmi-cli devops bootstrap verify` also checks the view triple (`List`/`Board`/`Roadmap`
|
|
302
302
|
by name **and** layout), the Board view's grouping, and its card fields against the standard the template
|
|
303
303
|
board (project 4) carries. Grouping (columns=`Status`, swimlanes=`Repository`) has **no** GraphQL create/
|
|
304
304
|
update mutation (`ProjectV2ViewConfigurationInput` carries only `visibleFieldIds`) — a drifted swimlane or
|
|
@@ -308,10 +308,10 @@ gh project list --owner "$PROJECT_OWNER" --format json # existing boards to ch
|
|
|
308
308
|
drifted one can be fixed live instead of only reported.
|
|
309
309
|
|
|
310
310
|
Record the chosen `projectNumber`/`projectId` plus Status/Priority field ids in the Hub registry META
|
|
311
|
-
(`PROJECT#<slug>`) by re-running `mmi-cli bootstrap apply --execute` **after** `gh project link`. Apply reads
|
|
311
|
+
(`PROJECT#<slug>`) by re-running `mmi-cli devops bootstrap apply --execute` **after** `gh project link`. Apply reads
|
|
312
312
|
the repo's linked board and derives all of them itself (#3543) — pass `--var PROJECT_ID=<node id>` only to
|
|
313
313
|
override, which is also what you need when the repo is linked to more than one board and apply therefore
|
|
314
|
-
refuses to guess. **Verify the row afterwards** (`mmi-cli org project get <owner/repo>`): a registered repo
|
|
314
|
+
refuses to guess. **Verify the row afterwards** (`mmi-cli oracle org project get <owner/repo>`): a registered repo
|
|
315
315
|
whose META carries no `projectId`/`statusFieldId` looks finished everywhere else while the Hub webhook has
|
|
316
316
|
nothing to move issues with, and `registry project board META exists` is the single check that says so. Going forward the thin Lambda adds each new issue to that project on `issues.opened` and sets
|
|
317
317
|
`Status: Todo`.
|
|
@@ -331,7 +331,7 @@ The default `tenant-container` substrate is a **Hetzner box** (`hetzner-ssh`): t
|
|
|
331
331
|
`.env` from the registry + vault and runs the container via docker-compose, deployed over the Hub's bounded
|
|
332
332
|
SSH lane. Do **not** create an AWS OIDC deploy role or a repo deploy Action for it. **Ask the master for the
|
|
333
333
|
box assignment** — the `sshHost` (and the loopback port) per stage — then write the `DEPLOY#<stage>` rows with
|
|
334
|
-
`mmi-cli org project set-deploy <owner/repo> --stage <dev|rc|main> --ssh-host <host> [--port <p>]` (defaults:
|
|
334
|
+
`mmi-cli oracle org project set-deploy <owner/repo> --stage <dev|rc|main> --ssh-host <host> [--port <p>]` (defaults:
|
|
335
335
|
`substrate: hetzner-ssh`, deploy path `/opt/mmi/<slug>/<stage>`, service = slug, ssh-user `root`). Without those
|
|
336
336
|
rows the tenant cannot deploy (`tenant-deploy.yml` errors on missing `DEPLOY#` coords), so do not skip this.
|
|
337
337
|
Keep every runtime config value in the vault; never paste secret values into logs.
|
|
@@ -381,7 +381,7 @@ collaborator list + the per-branch allowlist are the record — no separate rost
|
|
|
381
381
|
both enforce the step, so do not remove it. After apply,
|
|
382
382
|
master-admin must **activate** that JSON as a repository ruleset (GitHub → Settings → Rules → Rulesets →
|
|
383
383
|
Import/create from the committed reference) so the `gate` context is required on train branches. Once the
|
|
384
|
-
gate is green on `development`, `mmi-cli ci reconcile --apply --repo $OWNER/$REPO` should flip enforcement
|
|
384
|
+
gate is green on `development`, `mmi-cli devops ci reconcile --apply --repo $OWNER/$REPO` should flip enforcement
|
|
385
385
|
to **Active**; if it does not, use the Step 5 PUT fallback and confirm with `bootstrap verify` before
|
|
386
386
|
reporting bootstrap complete. MMI-Hub keeps its own three-job gate (`cli`/`infra`/`docs`) — never apply the
|
|
387
387
|
product ruleset there.
|
|
@@ -411,7 +411,7 @@ collaborator list + the per-branch allowlist are the record — no separate rost
|
|
|
411
411
|
Cloning from the template board (project 4, Step 3) already produces this; `bootstrap verify` asserts it
|
|
412
412
|
(`Board view card fields match the org standard`) on every subsequent run, so drift shows up there rather
|
|
413
413
|
than only at bootstrap time. Fix via Board view → **Fields**, or `updateProjectV2View(configuration:
|
|
414
|
-
{visibleFieldIds:[...]})`. Strip any legacy `priority:*` / taxonomy labels with `mmi-cli board doctor --fix`.
|
|
414
|
+
{visibleFieldIds:[...]})`. Strip any legacy `priority:*` / taxonomy labels with `mmi-cli oracle board doctor --fix`.
|
|
415
415
|
- **Org App credentials** — nothing to register per repo (#494). Board moves are central (the Hub webhook
|
|
416
416
|
moves Todo/In Progress/In Review for every repo) and the org App token is minted inside the Hub's own
|
|
417
417
|
central workflows, so `MMI_APP_ID` / `MMI_APP_PRIVATE_KEY` live only on the Hub — a product repo seeds no
|
|
@@ -436,12 +436,12 @@ collaborator list + the per-branch allowlist are the record — no separate rost
|
|
|
436
436
|
what this bootstrap already knows: **Stack / Run locally / Verify** from the Step-4c gate + install commands
|
|
437
437
|
and the repo's actual code; **Gotchas** and the architecture **Overview / Build & deploy** from the confirmed
|
|
438
438
|
Step-0 axes (class, project-type, deploy-model). Do **not** write the release track, board number, or deploy
|
|
439
|
-
coords as a value — the templates point at `mmi-cli org project get` (registry SSOT, never copied, so it cannot drift).
|
|
439
|
+
coords as a value — the templates point at `mmi-cli oracle org project get` (registry SSOT, never copied, so it cannot drift).
|
|
440
440
|
Do not write `AGENTS.md` / `CLAUDE.md` — these are developer-owned, gitignored agent guides, never a bootstrapped repo file (the `mmi-no-agent-files-org` ruleset blocks committing them).
|
|
441
441
|
- **`docs/index.md` is an optional generated routing index (#3545 / Hub#4133).** Agent entrypoints prefer
|
|
442
|
-
`mmi-cli repo-index search` + compute-at-read CLI over living prose under `docs/`. Apply may still create
|
|
442
|
+
`mmi-cli oracle repo-index search` + compute-at-read CLI over living prose under `docs/`. Apply may still create
|
|
443
443
|
`docs/index.md` once for link routing; it never rewrites it. Once the repo has docs of its own,
|
|
444
|
-
`mmi-cli docs index --write` owns the routing artifact and `--check` gates drift — it is not product
|
|
444
|
+
`mmi-cli oracle docs index --write` owns the routing artifact and `--check` gates drift — it is not product
|
|
445
445
|
current-state SSOT. Decision records under `docs/decisions/` remain append-only *why*.
|
|
446
446
|
- **Push the mandated fill past the active ruleset (#1807).** Deployable repos activate
|
|
447
447
|
`mmi-product-required-checks` during apply (its `bypass_actors` is empty by design), so the `gate` check is
|
|
@@ -451,8 +451,8 @@ collaborator list + the per-branch allowlist are the record — no separate rost
|
|
|
451
451
|
`mmi-product-required-checks`, set **Enforcement** to **Disabled**, push/merge the filled `README.md` +
|
|
452
452
|
`architecture.md`, then set **Enforcement** back to **Active**. Programmatic equivalent: PUT the ruleset
|
|
453
453
|
with `enforcement: disabled` (a PATCH is rejected, #917/#922), push the fill, then PUT it back to
|
|
454
|
-
`active` (or re-run `mmi-cli ci reconcile --apply --repo $OWNER/$REPO` once the gate is green, which
|
|
455
|
-
should activate idempotently). Before reporting bootstrap complete, run `mmi-cli bootstrap verify` and
|
|
454
|
+
`active` (or re-run `mmi-cli devops ci reconcile --apply --repo $OWNER/$REPO` once the gate is green, which
|
|
455
|
+
should activate idempotently). Before reporting bootstrap complete, run `mmi-cli devops bootstrap verify` and
|
|
456
456
|
confirm `product required-check ruleset enforcement active` is OK — a parked ruleset is not done. Never
|
|
457
457
|
leave enforcement disabled.
|
|
458
458
|
- `.claude/settings.local.json` is local-only and gitignored; bootstrap seeds no committed `.claude/settings.json`.
|
|
@@ -477,10 +477,10 @@ web tenants, `--project-type desktop-game --deploy-model none --clear-web-profil
|
|
|
477
477
|
app stores, and
|
|
478
478
|
`--class content --project-type content --deploy-model content --clear-web-profile` for a content/KB repo.
|
|
479
479
|
Run the apply path with the board variables discovered above, or register the same values with
|
|
480
|
-
`mmi-cli org project set` from the Hub or from the target project checkout:
|
|
480
|
+
`mmi-cli oracle org project set` from the Hub or from the target project checkout:
|
|
481
481
|
|
|
482
482
|
```bash
|
|
483
|
-
mmi-cli bootstrap apply "$OWNER/$REPO" --class deployable \
|
|
483
|
+
mmi-cli devops bootstrap apply "$OWNER/$REPO" --class deployable \
|
|
484
484
|
--project-type web-app --deploy-model tenant-container --execute \
|
|
485
485
|
--var PROJECT_OWNER="$PROJECT_OWNER" \
|
|
486
486
|
--var PROJECT_NUMBER="$PROJECT_NUMBER" \
|
|
@@ -502,14 +502,14 @@ and the app reads plain env vars — it must **not** self-load SSM and must **no
|
|
|
502
502
|
For a `web-app` that declares `oauth` META, print the canonical OAuth surface and provision the client once:
|
|
503
503
|
|
|
504
504
|
```bash
|
|
505
|
-
mmi-cli org oauth plan --repo "$OWNER/$REPO" # the exact JS origins + redirect URIs + canonical SSM keys
|
|
505
|
+
mmi-cli vault org oauth plan --repo "$OWNER/$REPO" # the exact JS origins + redirect URIs + canonical SSM keys
|
|
506
506
|
```
|
|
507
507
|
|
|
508
508
|
Register those JS origins + `/api/auth/callback` redirect URIs on the Console client (master, per
|
|
509
509
|
`docs/Guides/oauth-provision.md`), then store the creds in the canonical keys in one step:
|
|
510
510
|
|
|
511
511
|
```bash
|
|
512
|
-
mmi-cli org oauth set-creds --repo "$OWNER/$REPO" < client.json # the Console "Download JSON" file
|
|
512
|
+
mmi-cli vault org oauth set-creds --repo "$OWNER/$REPO" < client.json # the Console "Download JSON" file
|
|
513
513
|
```
|
|
514
514
|
|
|
515
515
|
The keys are the one stageless pair `GOOGLE_CLIENT_ID` + `GOOGLE_CLIENT_SECRET` at the slug root — every
|
|
@@ -536,7 +536,7 @@ never agent guides or a spine. The fanout pipeline that used to push this block
|
|
|
536
536
|
Repo, default branch, ruleset applied, train branches locked (push allowlist), project attached/created
|
|
537
537
|
(+ info seeded, Status lanes and Labels field verified), secrets set (names only), developer access, plugin
|
|
538
538
|
installed, docs seeded, registry META written, issue templates committed, org App credentials registered,
|
|
539
|
-
org-managed `.gitignore` block seeded, and the final `mmi-cli bootstrap verify "$OWNER/$REPO" --class ... --json` result.
|
|
539
|
+
org-managed `.gitignore` block seeded, and the final `mmi-cli devops bootstrap verify "$OWNER/$REPO" --class ... --json` result.
|
|
540
540
|
|
|
541
541
|
## Retro — one check before you finish
|
|
542
542
|
Before your final report, answer one question honestly: did **this skill's own instructions** misfire
|
|
@@ -545,4 +545,4 @@ about? (Process only — never the user's code or task; e.g. an ambiguous seed,
|
|
|
545
545
|
a guard that fired on a healthy repo.) If yes, file **one** lesson and move on; a clean run is silent
|
|
546
546
|
(hard cap: one per run). It lands on the Hub board (deduped) and is fixed only via a reviewed PR — never
|
|
547
547
|
edit the skill live; the retro is advisory, so if the call fails, note it and continue:
|
|
548
|
-
`mmi-cli skill-lesson --skill bootstrap --title "<what misfired>" --body "<what; evidence; proposed amendment>"`
|
|
548
|
+
`mmi-cli learning skill-lesson --skill bootstrap --title "<what misfired>" --body "<what; evidence; proposed amendment>"`
|
|
@@ -18,13 +18,13 @@ access runbook → [repo-access](https://github.com/mutmutco/MMI-Hub/blob/develo
|
|
|
18
18
|
|
|
19
19
|
Read this section at the start of agent work in this repo.
|
|
20
20
|
|
|
21
|
-
- **Structure search:** `mmi-cli repo-index search <path|symbol|meaning>` — Hub cloud pointer hits
|
|
21
|
+
- **Structure search:** `mmi-cli oracle repo-index search <path|symbol|meaning>` — Hub cloud pointer hits
|
|
22
22
|
(Hub#4133). Prefer this over inventing wiki pages or trusting stale inventories under `docs/`.
|
|
23
23
|
- **Durable WHY:** `docs/decisions/` — one file per decision, prose only for what was chosen and
|
|
24
24
|
rejected; never a description of current state. Do not maintain living current-state under `docs/`.
|
|
25
|
-
- **Current state:** code + compute-at-read CLI (`mmi-cli org project get`, `board`, `status`,
|
|
25
|
+
- **Current state:** code + compute-at-read CLI (`mmi-cli oracle org project get`, `board`, `status`,
|
|
26
26
|
`org schedules`, …) — registry facts, resolved live. Optional generated `docs/index.md` is a
|
|
27
|
-
**routing** index only (`mmi-cli docs index --check`), not product truth.
|
|
27
|
+
**routing** index only (`mmi-cli oracle docs index --check`), not product truth.
|
|
28
28
|
- **GitHub wikis are retired org-wide** — this repo does not publish to a `.wiki.git`; do not create one.
|
|
29
29
|
- **Stack:** (languages, frameworks, major services)
|
|
30
30
|
- **Run locally:** (install, dev server, `/stage` if non-obvious)
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
|
|
22
22
|
## Build & deploy
|
|
23
23
|
|
|
24
|
-
- **Class + release track + stages:** `mmi-cli org project get` (registry SSOT — full = development/rc/main,
|
|
24
|
+
- **Class + release track + stages:** `mmi-cli oracle org project get` (registry SSOT — full = development/rc/main,
|
|
25
25
|
direct = development/main, trunk = main; never copied here, so it cannot go stale).
|
|
26
26
|
- **Deploys run centrally** via the Hub (`tenant-deploy.yml`); this repo carries no deploy files, unless
|
|
27
27
|
noted otherwise below.
|
|
@@ -65,7 +65,7 @@ jobs:
|
|
|
65
65
|
# node/npm (or python) is missing, or whose setup step raced, fails `{{GATE_INSTALL_CMD}}` with a
|
|
66
66
|
# bare `command not found` (exit 127) that reads like a broken diff and abandons a correct PR in an
|
|
67
67
|
# autonomous merge loop. This names the RUNNER instead — a distinguishable infra failure that
|
|
68
|
-
# `mmi-cli pr checks-wait` classifies as rerunnable (title `CI runner toolchain`), mirroring the
|
|
68
|
+
# `mmi-cli devops pr checks-wait` classifies as rerunnable (title `CI runner toolchain`), mirroring the
|
|
69
69
|
# disk (#3366) and browser (#808) preflights. No test ran; the diff is not implicated.
|
|
70
70
|
- name: Toolchain preflight
|
|
71
71
|
if: ${{ '{{GATE_RUNTIME}}' == 'node' }}
|
|
@@ -6,10 +6,10 @@ prod. Adding Google login here is **self-serve**: you do not need master-admin h
|
|
|
6
6
|
## Reach the creds (from SSM — never in git, never printed)
|
|
7
7
|
```bash
|
|
8
8
|
# Confirm they resolve for your repo (names only, no value):
|
|
9
|
-
mmi-cli secrets list
|
|
9
|
+
mmi-cli vault secrets list
|
|
10
10
|
# Consume them keyless in a command — injected into its env, never printed (raw `secrets get` was removed, #2844):
|
|
11
|
-
mmi-cli secrets use GOOGLE_CLIENT_ID -- <cmd>
|
|
12
|
-
mmi-cli secrets use GOOGLE_CLIENT_SECRET -- <cmd>
|
|
11
|
+
mmi-cli vault secrets use GOOGLE_CLIENT_ID -- <cmd>
|
|
12
|
+
mmi-cli vault secrets use GOOGLE_CLIENT_SECRET -- <cmd>
|
|
13
13
|
```
|
|
14
14
|
The canonical keys are the stageless `GOOGLE_CLIENT_ID` + `GOOGLE_CLIENT_SECRET` pair at the project vault
|
|
15
15
|
root. The project-admin can manage them for their own repo; runtime and CI read them keylessly. Never bake a secret into an
|
|
@@ -28,6 +28,6 @@ URIs are registered for both `mutatismutandis.co` and `mutmut.co`, so the deploy
|
|
|
28
28
|
## Reference implementation + full guide
|
|
29
29
|
Inspect this repo's expected URIs and confirm the client is port-agnostic:
|
|
30
30
|
```bash
|
|
31
|
-
mmi-cli org oauth plan # the canonical JS origins + redirect URIs + SSM cred params
|
|
32
|
-
mmi-cli org oauth verify # probes an arbitrary :9123 loopback — no redirect_uri_mismatch = good
|
|
31
|
+
mmi-cli vault org oauth plan # the canonical JS origins + redirect URIs + SSM cred params
|
|
32
|
+
mmi-cli vault org oauth verify # probes an arbitrary :9123 loopback — no redirect_uri_mismatch = good
|
|
33
33
|
```
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"_comment": "Bootstrap seed manifest (#201) — the machine-readable contract of what /bootstrap and `mmi-cli bootstrap --apply` (#202) stamp into a target repo. Consumed by the CLI (loadBootstrapSeeds). ownership: 'org' = org-delivered, OVERWRITTEN on upgrade (the org owns it); 'repo' = created ONCE on a fresh bootstrap, never clobbered on upgrade (the repo owns its content). source: 'self' = copy MMI-Hub's own current file verbatim; 'seed:<file>' = render the named template in this dir with {{PLACEHOLDERS}}; 'managed-block' = merge the org-managed .gitignore block in place (preserves the repo's own ignore lines) — this is how the org-managed .gitignore block reaches every repo now that the fanout pipeline is retired (Hub#3010); the doctor SessionStart heal keeps it current thereafter. NOTE: this manifest seeds org-managed PRODUCT assets only — it never seeds AGENTS.md / CLAUDE.md / .claude/settings.json (personal agent guides) or a legacy repo-local control-plane marker. classes: which repo classes receive this seed.",
|
|
2
|
+
"_comment": "Bootstrap seed manifest (#201) — the machine-readable contract of what /bootstrap and `mmi-cli devops bootstrap --apply` (#202) stamp into a target repo. Consumed by the CLI (loadBootstrapSeeds). ownership: 'org' = org-delivered, OVERWRITTEN on upgrade (the org owns it); 'repo' = created ONCE on a fresh bootstrap, never clobbered on upgrade (the repo owns its content). source: 'self' = copy MMI-Hub's own current file verbatim; 'seed:<file>' = render the named template in this dir with {{PLACEHOLDERS}}; 'managed-block' = merge the org-managed .gitignore block in place (preserves the repo's own ignore lines) — this is how the org-managed .gitignore block reaches every repo now that the fanout pipeline is retired (Hub#3010); the doctor SessionStart heal keeps it current thereafter. NOTE: this manifest seeds org-managed PRODUCT assets only — it never seeds AGENTS.md / CLAUDE.md / .claude/settings.json (personal agent guides) or a legacy repo-local control-plane marker. classes: which repo classes receive this seed.",
|
|
3
3
|
"placeholders": ["OWNER", "REPO", "REPO_SLUG", "REPO_NAME", "CLASS", "GATE_CMD", "GATE_PUSH_BRANCHES_YAML", "GATE_FULL_RUN_BRANCH", "GATE_RULESET_BRANCH_REFS_JSON", "PROJECT_OWNER", "PROJECT_NUMBER", "PROJECT_ID", "STATUS_FIELD_ID", "STATUS_TODO", "STATUS_IN_PROGRESS", "STATUS_IN_REVIEW", "STATUS_DONE", "STACK", "REGION"],
|
|
4
4
|
"seeds": [
|
|
5
5
|
{ "target": ".github/ISSUE_TEMPLATE/bug.yml", "source": "self", "ownership": "org", "classes": ["deployable", "content"] },
|
|
@@ -90,4 +90,4 @@ about? (Process only — never the user's code or task.) If yes, file **one** le
|
|
|
90
90
|
silent (hard cap: one per run). It lands on the Hub board (deduped) and is fixed only via a reviewed PR —
|
|
91
91
|
never edit the skill live; the retro is advisory, so if the call fails, note it and continue:
|
|
92
92
|
|
|
93
|
-
`mmi-cli skill-lesson --skill browser-automation --title "<what misfired>" --body "<what; evidence; proposed amendment>"`
|
|
93
|
+
`mmi-cli learning skill-lesson --skill browser-automation --title "<what misfired>" --body "<what; evidence; proposed amendment>"`
|
package/skills/epic/SKILL.md
CHANGED
|
@@ -23,7 +23,7 @@ Read the parent end-to-end before slicing — body **and every comment**, treati
|
|
|
23
23
|
superseding:
|
|
24
24
|
|
|
25
25
|
```bash
|
|
26
|
-
mmi-cli board show <owner/repo#N> # status, body, and every comment for the umbrella
|
|
26
|
+
mmi-cli oracle board show <owner/repo#N> # status, body, and every comment for the umbrella
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
Slice by deliverable, not by phase: each child must be independently claimable and land in its own PR.
|
|
@@ -59,7 +59,7 @@ aggregate error, so you fix all of them once. Get the user's go on the drafted s
|
|
|
59
59
|
## Step 2 — create the children
|
|
60
60
|
|
|
61
61
|
```bash
|
|
62
|
-
mmi-cli issue create --type task --batch tmp/epic-children.json --surface cli
|
|
62
|
+
mmi-cli oracle issue create --type task --batch tmp/epic-children.json --surface cli
|
|
63
63
|
```
|
|
64
64
|
|
|
65
65
|
`--type` is required by the create command but each row's own `type` governs; pass any valid type as the
|
|
@@ -74,14 +74,14 @@ wait for writes to quiesce, inspect the children, then retry the missing rows wi
|
|
|
74
74
|
## Step 3 — confirm the tree
|
|
75
75
|
|
|
76
76
|
```bash
|
|
77
|
-
mmi-cli issue children <owner/repo#N> # each child: number/title/state/repo/boardStatus/linkedPrs
|
|
77
|
+
mmi-cli oracle issue children <owner/repo#N> # each child: number/title/state/repo/boardStatus/linkedPrs
|
|
78
78
|
```
|
|
79
79
|
|
|
80
80
|
Verify every intended child is linked and on the board as Todo. To link a child that already existed (not
|
|
81
81
|
part of the batch), use the inverse-friendly single link:
|
|
82
82
|
|
|
83
83
|
```bash
|
|
84
|
-
mmi-cli issue link-child <parent> <child>
|
|
84
|
+
mmi-cli oracle issue link-child <parent> <child>
|
|
85
85
|
```
|
|
86
86
|
|
|
87
87
|
Each child is now a parallel item — fan them out one worktree + PR each. **When the last child merges,
|
|
@@ -101,4 +101,4 @@ about? (Process only — never the user's code or task; e.g. a batch schema that
|
|
|
101
101
|
link that attached to the wrong parent.) If yes, file **one** lesson and move on; a clean run is silent
|
|
102
102
|
(hard cap: one per run). It lands on the Hub board (deduped) and is fixed only via a reviewed PR — never
|
|
103
103
|
edit the skill live; the retro is advisory, so if the call fails, note it and continue:
|
|
104
|
-
`mmi-cli skill-lesson --skill epic --title "<what misfired>" --body "<what; evidence; proposed amendment>"`
|
|
104
|
+
`mmi-cli learning skill-lesson --skill epic --title "<what misfired>" --body "<what; evidence; proposed amendment>"`
|
package/skills/hotfix/SKILL.md
CHANGED
|
@@ -39,7 +39,7 @@ Production changes require the authorized human's explicit approval in the curre
|
|
|
39
39
|
and CLI health before starting:
|
|
40
40
|
|
|
41
41
|
```bash
|
|
42
|
-
mmi-cli org access role <owner/repo> --json
|
|
42
|
+
mmi-cli oracle org access role <owner/repo> --json
|
|
43
43
|
mmi-cli doctor --no-repo-writes
|
|
44
44
|
```
|
|
45
45
|
|
|
@@ -55,7 +55,7 @@ exactly ` M` as real work to commit or stash, and for ` M` discard only when
|
|
|
55
55
|
Use the orchestrator with an explicit source every time:
|
|
56
56
|
|
|
57
57
|
```bash
|
|
58
|
-
mmi-cli hotfix start --from <development-pr-or-sha>[,<development-pr-or-sha>...] --json
|
|
58
|
+
mmi-cli devops hotfix start --from <development-pr-or-sha>[,<development-pr-or-sha>...] --json
|
|
59
59
|
```
|
|
60
60
|
|
|
61
61
|
**One hotfix cycle carries as many merged fixes as you name.** `--from` takes a comma-separated list in
|
|
@@ -91,8 +91,8 @@ active agent doctrine. Review the actual main-base diff and the original issue a
|
|
|
91
91
|
Wait for required CI through Hub:
|
|
92
92
|
|
|
93
93
|
```bash
|
|
94
|
-
mmi-cli pr checks-wait <hotfix-pr-number>
|
|
95
|
-
mmi-cli pr merge <number> --squash
|
|
94
|
+
mmi-cli devops pr checks-wait <hotfix-pr-number>
|
|
95
|
+
mmi-cli devops pr merge <number> --squash
|
|
96
96
|
```
|
|
97
97
|
|
|
98
98
|
The main-base PR is the production gate. Do not bypass checks or protected-branch authority. After the
|
|
@@ -103,11 +103,11 @@ issue. The development PR should already have closed the work item; do not add r
|
|
|
103
103
|
|
|
104
104
|
## 3. Run the gated release
|
|
105
105
|
|
|
106
|
-
Derive the tag from `mmi-cli hotfix status`, then release with the same declared source:
|
|
106
|
+
Derive the tag from `mmi-cli devops hotfix status`, then release with the same declared source:
|
|
107
107
|
|
|
108
108
|
```bash
|
|
109
|
-
mmi-cli hotfix status
|
|
110
|
-
mmi-cli hotfix release <vX.Y.Z> --carries <development-pr-or-sha>[,<development-pr-or-sha>...]
|
|
109
|
+
mmi-cli devops hotfix status
|
|
110
|
+
mmi-cli devops hotfix release <vX.Y.Z> --carries <development-pr-or-sha>[,<development-pr-or-sha>...]
|
|
111
111
|
```
|
|
112
112
|
|
|
113
113
|
Name **every** fix the cycle carries. Each is proven an ancestor of the tagged SHA before tagging; a
|
|
@@ -139,10 +139,24 @@ merged into `development`; the fold is regenerated on a branch cut from `develop
|
|
|
139
139
|
reported `development fold port FAILED`, follow the manual remedy it named; never improvise a merge from
|
|
140
140
|
`main`.
|
|
141
141
|
|
|
142
|
+
### Catalog-lockstep vs development prepare (#4517)
|
|
143
|
+
|
|
144
|
+
Hub docs catalog-lockstep refuses PRs into `development` that advance
|
|
145
|
+
`.claude-plugin/marketplace.json` ahead of `origin/main`. That gate is correct for main-anchored catalog
|
|
146
|
+
truth. When Publish-Truth / a version bump must advance the marketplace, do **not** land
|
|
147
|
+
`release-distribution prepare` as a development PR — use this hotfix door:
|
|
148
|
+
|
|
149
|
+
1. `mmi-cli devops hotfix start --from <merged-dev-pr-or-sha>` (prepare + distribution bump on `hotfix/vX.Y.Z` from `main`)
|
|
150
|
+
2. merge the hotfix PR → `mmi-cli devops hotfix release vX.Y.Z` (publish)
|
|
151
|
+
3. land the automatic `hotfix-fold/<tag>` development fold PR (or follow its printed remedy)
|
|
152
|
+
|
|
153
|
+
A development prepare PR that only exists to move marketplace ahead of main will keep failing
|
|
154
|
+
catalog-lockstep; that is not a false red — switch to the hotfix path above.
|
|
155
|
+
|
|
142
156
|
## Retro
|
|
143
157
|
|
|
144
158
|
If this skill's instructions themselves misfired, file one deduplicated lesson and continue:
|
|
145
159
|
|
|
146
160
|
```bash
|
|
147
|
-
mmi-cli skill-lesson --skill hotfix --title "<what misfired>" --body "<what; evidence; proposed amendment>"
|
|
161
|
+
mmi-cli learning skill-lesson --skill hotfix --title "<what misfired>" --body "<what; evidence; proposed amendment>"
|
|
148
162
|
```
|
package/skills/mmi/SKILL.md
CHANGED
|
@@ -37,7 +37,7 @@ it on every move). Closed/finished items auto-archive after they go quiet; archi
|
|
|
37
37
|
cached/session-start health line explicitly says a heal is needed.
|
|
38
38
|
|
|
39
39
|
```bash
|
|
40
|
-
mmi-cli board read --json # Step 1 — first useful render on the happy path
|
|
40
|
+
mmi-cli oracle board read --json # Step 1 — first useful render on the happy path
|
|
41
41
|
mmi-cli doctor --no-repo-writes # only after a hard setup signal — foreground, one at a time
|
|
42
42
|
```
|
|
43
43
|
|
|
@@ -112,7 +112,7 @@ What the env half heals:
|
|
|
112
112
|
```
|
|
113
113
|
The `project` scope is what lets `/mmi` read + move the board, granted here once. When they're back,
|
|
114
114
|
re-run `mmi-cli doctor` to confirm green.
|
|
115
|
-
- **Hub registry / board META** — `mmi-cli org project get <owner/repo>` or `mmi-cli board read` reports
|
|
115
|
+
- **Hub registry / board META** — `mmi-cli oracle org project get <owner/repo>` or `mmi-cli oracle board read` reports
|
|
116
116
|
missing project/board coords → a master-admin registers or backfills the repo's `PROJECT#<slug>` META.
|
|
117
117
|
There's no reliable project to read until that is fixed, so stop here.
|
|
118
118
|
|
|
@@ -127,7 +127,7 @@ tenant request surfaces. After the board read (Step 1), you already have `viewer
|
|
|
127
127
|
authority on this or another repo, run:
|
|
128
128
|
|
|
129
129
|
```bash
|
|
130
|
-
mmi-cli org access role <owner/repo> --json # { role, train } — Hub-verified from registry projectAdmins
|
|
130
|
+
mmi-cli oracle org access role <owner/repo> --json # { role, train } — Hub-verified from registry projectAdmins
|
|
131
131
|
```
|
|
132
132
|
|
|
133
133
|
When `role` is `project-admin` and `train` is true on **that** repo, the dev holds D14 authority there —
|
|
@@ -150,14 +150,14 @@ cards** (title + compact intent, PRIOR-not-instruction framing — silent when a
|
|
|
150
150
|
complete partition — secondary repos, taken items, bundle details — run the full command below.
|
|
151
151
|
|
|
152
152
|
```bash
|
|
153
|
-
mmi-cli board read --json
|
|
153
|
+
mmi-cli oracle board read --json
|
|
154
154
|
```
|
|
155
155
|
|
|
156
156
|
This is the **only foreground call** on the happy path for **work items** (not identity — Step 0 already
|
|
157
157
|
resolved login). Its JSON carries `viewer`, `repo`, and the project title — do **not** run separate
|
|
158
158
|
`gh api user` / `gh repo view` calls; they just delay the board. If `repo` is missing from the JSON,
|
|
159
159
|
keep the board header generic. The CLI resolves the project from the Hub registry; to inspect it
|
|
160
|
-
directly, `mmi-cli org project get --json`.
|
|
160
|
+
directly, `mmi-cli oracle org project get --json`.
|
|
161
161
|
|
|
162
162
|
Use the returned `primary` group for current-repo items and `secondary` for other repos on the same Project.
|
|
163
163
|
Within each group, render `userOwned`, `claimable`, and `taken`.
|
|
@@ -242,18 +242,18 @@ potentially **superseding** the body. Only then greet into the work or propose a
|
|
|
242
242
|
|
|
243
243
|
```bash
|
|
244
244
|
# One shot — status, assignees, type, body, and every comment for one board item:
|
|
245
|
-
mmi-cli board show <owner/repo#N> # add --json for machine-readable output
|
|
245
|
+
mmi-cli oracle board show <owner/repo#N> # add --json for machine-readable output
|
|
246
246
|
```
|
|
247
|
-
For an item **not on the board**, `mmi-cli issue view <N> --comments` is the board-independent one-shot:
|
|
247
|
+
For an item **not on the board**, `mmi-cli oracle issue view <N> --comments` is the board-independent one-shot:
|
|
248
248
|
it returns the body **and** every comment as JSON in a single call (add `--context` for `linkedPrs` and, on
|
|
249
249
|
an epic, a `children` summary). Prefer it over raw `gh issue view --comments`, which in a non-TTY shell (every
|
|
250
250
|
agent/CI context) prints only the comments, hides the body, and prints nothing at all on a zero-comment issue.
|
|
251
251
|
```bash
|
|
252
|
-
mmi-cli issue view <N> --repo <owner/repo> --comments # body + every comment, one call
|
|
252
|
+
mmi-cli oracle issue view <N> --repo <owner/repo> --comments # body + every comment, one call
|
|
253
253
|
```
|
|
254
254
|
|
|
255
255
|
> **Never reach for standalone `jq`** — it isn't installed on Windows dev machines, so each attempt burns a
|
|
256
|
-
> failed call (#230). `mmi-cli board read|show` is already human-readable (drop `--json`); to parse JSON use
|
|
256
|
+
> failed call (#230). `mmi-cli oracle board read|show` is already human-readable (drop `--json`); to parse JSON use
|
|
257
257
|
> `mmi-cli … --json` piped to `node`, or `gh`'s **built-in** `--jq`.
|
|
258
258
|
|
|
259
259
|
(Triggers only when a dev commits to an existing item — no-op for the *report a bug / request a feature /
|
|
@@ -266,7 +266,7 @@ something else* paths.)
|
|
|
266
266
|
is offered. Every later transition (In Review on PR open, Done on merge) flows automatically from the
|
|
267
267
|
work, not from here.
|
|
268
268
|
```bash
|
|
269
|
-
mmi-cli board claim <owner/repo#N> --json
|
|
269
|
+
mmi-cli oracle board claim <owner/repo#N> --json
|
|
270
270
|
```
|
|
271
271
|
The command validates `Todo` + unassigned, assigns the viewer, and moves the Project v2 `Status` to
|
|
272
272
|
`In Progress`. A partial claim exits nonzero unless the dev explicitly accepted `--allow-partial`.
|
|
@@ -279,14 +279,14 @@ something else* paths.)
|
|
|
279
279
|
2. **Fill that type's template.** Read its fields from `.github/ISSUE_TEMPLATE/<type>.yml` and gather
|
|
280
280
|
answers from the dev for each — draft where you can, ask where you can't (the template form is
|
|
281
281
|
interactive and won't drive in a non-TTY agent shell, so collect the fields, then create directly).
|
|
282
|
-
3. **Submit via `mmi-cli issue create`** — the canonical create path. Before filing, read the live
|
|
282
|
+
3. **Submit via `mmi-cli oracle issue create`** — the canonical create path. Before filing, read the live
|
|
283
283
|
`issue create` entry from `mmi-cli commands --json`; flags change, and a missing documented flag means
|
|
284
284
|
the installed CLI is stale until a fresh local build proves otherwise. It maps `--type` to the label,
|
|
285
285
|
`--priority` sets the board Priority **field** (never a `priority:*` label — #416), and `--surface`
|
|
286
286
|
supplies the repository's required single surface label. It always prints `{number,url}` JSON. Never
|
|
287
287
|
use `gh issue create`; it bypasses these board contracts:
|
|
288
288
|
```bash
|
|
289
|
-
mmi-cli issue create --type <bug|feature|task> --title "<title>" --body "<filled template>" \
|
|
289
|
+
mmi-cli oracle issue create --type <bug|feature|task> --title "<title>" --body "<filled template>" \
|
|
290
290
|
--priority <high|medium|low> --surface <surface>
|
|
291
291
|
```
|
|
292
292
|
For long markdown, materialize a temporary UTF-8 body file, pass its real path with
|
|
@@ -299,7 +299,7 @@ something else* paths.)
|
|
|
299
299
|
The command starts bounded related-issue discovery off-path. It auto-comments only high-confidence,
|
|
300
300
|
idempotent links. To inspect candidates manually before writing anything else:
|
|
301
301
|
```bash
|
|
302
|
-
mmi-cli issue discover-related --repo <owner/repo> --number <number> --title "<title>" --body "<body>" --json
|
|
302
|
+
mmi-cli oracle issue discover-related --repo <owner/repo> --number <number> --title "<title>" --body "<body>" --json
|
|
303
303
|
```
|
|
304
304
|
It lands on the board as Todo automatically — confirm the link from the JSON. (Templates differ per
|
|
305
305
|
repo; read the actual `.yml` set rather than assuming bug/feature/task.)
|
|
@@ -339,7 +339,7 @@ Bundling detail boundary: start from the metadata board. Only if there are multi
|
|
|
339
339
|
`userOwned`/`claimable` candidates, fetch bodies/comments with:
|
|
340
340
|
|
|
341
341
|
```bash
|
|
342
|
-
mmi-cli board read --json --bundle-details
|
|
342
|
+
mmi-cli oracle board read --json --bundle-details
|
|
343
343
|
```
|
|
344
344
|
|
|
345
345
|
That detail path may fetch bodies/comments only for `userOwned` and `claimable` issues. `taken` stays
|
|
@@ -364,7 +364,8 @@ destroying the worktree after each issue:
|
|
|
364
364
|
`--body-file <path>`, and remove it after the write succeeds. Do not pipe the body to `--body-file -`;
|
|
365
365
|
host prose guards require the materialized-file path.
|
|
366
366
|
- **Batch:** one worktree, claim each item (the Step 5 claim loop), make the coupled edits, open **one** PR
|
|
367
|
-
(`Closes #…, #…`).
|
|
367
|
+
(`Closes #…, #…`). When an issue must stay open (HOLD/prep), never write `Does not close #N` — GitHub
|
|
368
|
+
still closes it; use `Part of #N` / `Refs #N` / `leaves #N open` only (JC#495).
|
|
368
369
|
- **Session/sequential:** multiple related same-repo items handled one after another in the same session
|
|
369
370
|
reuse the active worktree until the session or execution group ends; do not churn one worktree per
|
|
370
371
|
issue unless a branch/PR boundary, true parallelism, or explicit user ask requires it.
|
|
@@ -375,7 +376,7 @@ destroying the worktree after each issue:
|
|
|
375
376
|
- **Stage/worktree:** a local `/stage` is tied to the worktree that started it. Stop/destroy and recreate
|
|
376
377
|
it before moving to another worktree, or warn first when intent is unclear.
|
|
377
378
|
- **Split:** keep the original as the umbrella; file each child as a **native sub-issue** of it with
|
|
378
|
-
`mmi-cli issue create --parent <umbrella-ref> …` (or `mmi-cli issue link-child <umbrella> <child>` for a
|
|
379
|
+
`mmi-cli oracle issue create --parent <umbrella-ref> …` (or `mmi-cli oracle issue link-child <umbrella> <child>` for a
|
|
379
380
|
child that already exists). The parent then renders a sub-issue checklist with each child's state and the
|
|
380
381
|
child renders its parent — no title prefix or body task-list to maintain. Refs are `#NN`, `owner/repo#NN`,
|
|
381
382
|
or a URL, and it works cross-repo (a Hub umbrella can track product-repo children). Get the dev's go before
|
|
@@ -400,4 +401,4 @@ about? (Process only — never the user's code or task; e.g. a board read that m
|
|
|
400
401
|
claimable, or a claim that moved the wrong item.) If yes, file **one** lesson and move on; a clean run is
|
|
401
402
|
silent (hard cap: one per run). It lands on the Hub board (deduped) and is fixed only via a reviewed PR —
|
|
402
403
|
never edit the skill live; the retro is advisory, so if the call fails, note it and continue:
|
|
403
|
-
`mmi-cli skill-lesson --skill mmi --title "<what misfired>" --body "<what; evidence; proposed amendment>"`
|
|
404
|
+
`mmi-cli learning skill-lesson --skill mmi --title "<what misfired>" --body "<what; evidence; proposed amendment>"`
|
|
@@ -14,7 +14,7 @@ mmi-cli doctor
|
|
|
14
14
|
By default this **heals and cleans** (MMI-Hub#3975): CLI/plugin/marketplace env repairs, managed
|
|
15
15
|
`.gitignore`, merged-branch / dead-worktree reap (including deferred IDE-locked removals), light board
|
|
16
16
|
mechanical fixes, docs-index working-tree heal, and related full-lane checks. Secrets stay **out** of
|
|
17
|
-
default doctor — use `mmi-cli secrets diff` when you need a catalog gap check.
|
|
17
|
+
default doctor — use `mmi-cli vault secrets diff` when you need a catalog gap check.
|
|
18
18
|
|
|
19
19
|
## Flags
|
|
20
20
|
|
|
@@ -32,8 +32,8 @@ Do **not** chain these as a `/mmi-doctor` substitute:
|
|
|
32
32
|
|
|
33
33
|
```bash
|
|
34
34
|
mmi-cli doctor --self
|
|
35
|
-
mmi-cli board doctor
|
|
36
|
-
mmi-cli secrets diff
|
|
35
|
+
mmi-cli oracle board doctor
|
|
36
|
+
mmi-cli vault secrets diff
|
|
37
37
|
mmi-cli worktree gc
|
|
38
38
|
```
|
|
39
39
|
|
|
@@ -52,4 +52,4 @@ about? (Process only — never the user's code or task; e.g. a doctor run that p
|
|
|
52
52
|
branch.) If yes, file **one** lesson and move on; a clean run is silent (hard cap: one per run). It
|
|
53
53
|
lands on the Hub board (deduped) and is fixed only via a reviewed PR — never edit the skill live; the
|
|
54
54
|
retro is advisory, so if the call fails, note it and continue:
|
|
55
|
-
`mmi-cli skill-lesson --skill doctor --title "<what misfired>" --body "<what; evidence; proposed amendment>"`
|
|
55
|
+
`mmi-cli learning skill-lesson --skill doctor --title "<what misfired>" --body "<what; evidence; proposed amendment>"`
|
package/skills/onboard/SKILL.md
CHANGED
|
@@ -35,7 +35,7 @@ front of you.
|
|
|
35
35
|
A `✗` on any line comes with a `Next command:` — run **that** first. Common ones:
|
|
36
36
|
|
|
37
37
|
- Hub API URL not configured → `mmi-cli doctor` (fix wiring).
|
|
38
|
-
- Repo not registered → a master-admin runs `/bootstrap` (or `mmi-cli org project set <owner/repo>`).
|
|
38
|
+
- Repo not registered → a master-admin runs `/bootstrap` (or `mmi-cli oracle org project set <owner/repo>`).
|
|
39
39
|
- GitHub auth missing → the dev runs `gh auth login --hostname github.com --git-protocol https --web --scopes "project"`.
|
|
40
40
|
|
|
41
41
|
## Step 1 — the picture
|
|
@@ -44,13 +44,13 @@ Once the gates are green:
|
|
|
44
44
|
|
|
45
45
|
```bash
|
|
46
46
|
mmi-cli status # branch, worktrees, your PRs, your claimed items, stage
|
|
47
|
-
mmi-cli next # the first claimable item + its claim command
|
|
47
|
+
mmi-cli oracle next # the first claimable item + its claim command
|
|
48
48
|
```
|
|
49
49
|
|
|
50
50
|
## Step 2 — hand over the first move
|
|
51
51
|
|
|
52
52
|
Close with one grounding line: gates green (or the one gate to fix), and the single first command —
|
|
53
|
-
usually `mmi-cli board claim <n>` for the recommended item, or the readiness fix if a gate is red. Don't
|
|
53
|
+
usually `mmi-cli oracle board claim <n>` for the recommended item, or the readiness fix if a gate is red. Don't
|
|
54
54
|
claim on the user's behalf; let them take the first item when ready.
|
|
55
55
|
|
|
56
56
|
## Step 2b — structure door (compute-at-read)
|
|
@@ -58,9 +58,9 @@ claim on the user's behalf; let them take the first item when ready.
|
|
|
58
58
|
Before treating `docs/**` as current-state, teach the Hub door (Hub#4133 / #4148):
|
|
59
59
|
|
|
60
60
|
```bash
|
|
61
|
-
mmi-cli repo-index search <path-or-symbol-or-meaning> # Hub cloud pointers (default)
|
|
62
|
-
mmi-cli repo-index search "where …" --semantic # Titan meaning over embeddings
|
|
63
|
-
mmi-cli repo-index status --cloud # is the estate index live?
|
|
61
|
+
mmi-cli oracle repo-index search <path-or-symbol-or-meaning> # Hub cloud pointers (default)
|
|
62
|
+
mmi-cli oracle repo-index search "where …" --semantic # Titan meaning over embeddings
|
|
63
|
+
mmi-cli oracle repo-index status --cloud # is the estate index live?
|
|
64
64
|
```
|
|
65
65
|
|
|
66
66
|
Host indexes (Cursor / Kilo) stay local helpers; **Hub `repo-index` is the org SSOT structure door**.
|
|
@@ -81,4 +81,4 @@ board read actually failed, or a next command that pointed at the wrong fix.) If
|
|
|
81
81
|
and move on; a clean run is silent (hard cap: one per run). It lands on the Hub board (deduped) and is
|
|
82
82
|
fixed only via a reviewed PR — never edit the skill live; the retro is advisory, so if the call fails,
|
|
83
83
|
note it and continue:
|
|
84
|
-
`mmi-cli skill-lesson --skill onboard --title "<what misfired>" --body "<what; evidence; proposed amendment>"`
|
|
84
|
+
`mmi-cli learning skill-lesson --skill onboard --title "<what misfired>" --body "<what; evidence; proposed amendment>"`
|
package/skills/rcand/SKILL.md
CHANGED
|
@@ -12,7 +12,7 @@ run `/release` from `development` instead. The board needs no touch
|
|
|
12
12
|
here — items reach `Done` when their PR merges to `development` (native close → Done); `rc` is a deploy
|
|
13
13
|
stage, not a lane.
|
|
14
14
|
|
|
15
|
-
Authority is **structural + server-checked**: step 0 asks the Hub (`mmi-cli org access role`), and step 4
|
|
15
|
+
Authority is **structural + server-checked**: step 0 asks the Hub (`mmi-cli oracle org access role`), and step 4
|
|
16
16
|
pushes to the protected `rc` branch, whose per-repo allowlist carries the same people (master + that repo's
|
|
17
17
|
project-admins). No `.env` role marker. Gate ordering: the tag lands the rc SHA
|
|
18
18
|
for checks, and every deploy side-effect waits until the protected `rc` push accepts that checked SHA.
|
|
@@ -20,14 +20,14 @@ for checks, and every deploy side-effect waits until the protected `rc` push acc
|
|
|
20
20
|
## Step 0 — train-authority probe (server-side, D14)
|
|
21
21
|
|
|
22
22
|
```bash
|
|
23
|
-
mmi-cli org access role {owner}/{repo} --json # Hub-verified: { role, train }
|
|
23
|
+
mmi-cli oracle org access role {owner}/{repo} --json # Hub-verified: { role, train }
|
|
24
24
|
```
|
|
25
25
|
`train: false` — or ANY error (fail closed) → stop: a product repo's train belongs to that repo's
|
|
26
26
|
**project-admin** (repo write + registry `projectAdmins`) or the master. When `project-admin` + `train`,
|
|
27
27
|
proceed — do not redirect to the master (`AGENTS.md` § Authority). Errors → fix `gh auth` first,
|
|
28
28
|
never proceed unverified.
|
|
29
29
|
|
|
30
|
-
**CLI freshness (#2562):** check the running CLI is current BEFORE step 1 — `mmi-cli rcand --apply` refuses
|
|
30
|
+
**CLI freshness (#2562):** check the running CLI is current BEFORE step 1 — `mmi-cli devops rcand --apply` refuses
|
|
31
31
|
a stale CLI at its own step 0 (pre-mutation), but the manual steps below mutate local state earlier, so a
|
|
32
32
|
stale CLI discovered late reads as a mid-train abort. When another train just published a new CLI (e.g. a
|
|
33
33
|
Hub release), run `mmi-cli doctor --no-repo-writes` first. A stale-CLI refusal itself changes
|
|
@@ -65,12 +65,12 @@ Dirty → stop. Count `0` → stop ("nothing to promote"). `>0` → capture the
|
|
|
65
65
|
Resolve the project META first; its `deployModel` decides the deploy path. `tenant-container` repos use the
|
|
66
66
|
central tenant deployer and therefore need DEPLOY# coords. Serverless, `registry-publish`, and
|
|
67
67
|
`solo-container` repos deploy from their own workflow, so do **not** dispatch `tenant-deploy.yml` for them.
|
|
68
|
-
Direct-track repos (`releaseTrack: direct`, e.g. MMI-Hub) have no rc candidate path; `mmi-cli rcand --apply`
|
|
68
|
+
Direct-track repos (`releaseTrack: direct`, e.g. MMI-Hub) have no rc candidate path; `mmi-cli devops rcand --apply`
|
|
69
69
|
refuses after this preflight.
|
|
70
70
|
Verify META + required SSM secret names before touching `rc`:
|
|
71
71
|
```bash
|
|
72
|
-
mmi-cli org project get {owner}/{repo}
|
|
73
|
-
mmi-cli secrets preflight --stage rc --repo {owner}/{repo}
|
|
72
|
+
mmi-cli oracle org project get {owner}/{repo}
|
|
73
|
+
mmi-cli vault secrets preflight --stage rc --repo {owner}/{repo}
|
|
74
74
|
```
|
|
75
75
|
Missing META or secret names → stop and repair the registry/secrets first.
|
|
76
76
|
|
|
@@ -126,7 +126,7 @@ gh api repos/{owner}/{repo}/commits/$SHA/check-runs \
|
|
|
126
126
|
--jq '[.check_runs[]|{name:.name,conclusion:.conclusion}]'
|
|
127
127
|
git push origin rc
|
|
128
128
|
```
|
|
129
|
-
(`mmi-cli rcand --apply` performs this discovery + bounded wait itself.)
|
|
129
|
+
(`mmi-cli devops rcand --apply` performs this discovery + bounded wait itself.)
|
|
130
130
|
Rejected (protected / not a bypass actor) → stop, nothing deployed, no board writes; leave the local tag
|
|
131
131
|
for an authorized re-push, never force. Non-fast-forward → re-pull, re-run from step 1.
|
|
132
132
|
|
|
@@ -145,7 +145,7 @@ gh run watch "$(gh run list --workflow tenant-deploy.yml --limit 1 --json databa
|
|
|
145
145
|
For serverless repos, do **not** dispatch `tenant-deploy.yml`: their own push-triggered workflow owns the
|
|
146
146
|
rc deploy.
|
|
147
147
|
|
|
148
|
-
`mmi-cli rcand --apply --json` returns the relevant run `runId` + `runUrl` (alongside `deployStatus`), so
|
|
148
|
+
`mmi-cli devops rcand --apply --json` returns the relevant run `runId` + `runUrl` (alongside `deployStatus`), so
|
|
149
149
|
you never hand-correlate Actions. For tenant-container repos, that is the dispatched `tenant-deploy.yml`
|
|
150
150
|
run. For Hub serverless, that is the auto-fired `deploy.yml` run from the protected `rc` push. Add
|
|
151
151
|
`--watch` to block on the run and have `deployStatus` resolve to `success`/`failure`; `promoted: true`
|
|
@@ -156,7 +156,7 @@ The deploy runs while you report. When the background watch returns, surface the
|
|
|
156
156
|
correct next action is a **deploy retry of the existing rc ref** after the Hub runtime is repaired — never
|
|
157
157
|
a re-tag/re-merge:
|
|
158
158
|
```bash
|
|
159
|
-
mmi-cli runtime tenant redeploy {owner}/{repo} rc --watch # re-dispatch tenant-deploy.yml for the promoted rc
|
|
159
|
+
mmi-cli devops runtime tenant redeploy {owner}/{repo} rc --watch # re-dispatch tenant-deploy.yml for the promoted rc
|
|
160
160
|
```
|
|
161
161
|
**Branch the recovery by failure class — a bare redeploy is NOT always the whole recovery.** For **exit 78**
|
|
162
162
|
(`compose is fileless but DEPLOY#<stage>.noEnvFile is not true`) a plain redeploy fails identically: the
|
|
@@ -164,10 +164,10 @@ box's baked `/opt/mmi-control/<slug>.sh` still carries the stale `noEnvFile`, so
|
|
|
164
164
|
the fileless compose expects passthrough. Fix the registry AND re-render the box control script first, then
|
|
165
165
|
redeploy (`set-deploy` alone is not enough — the reconcile is the discoverable-but-non-obvious middle step):
|
|
166
166
|
```bash
|
|
167
|
-
mmi-cli org project set-deploy {owner}/{repo} --stage rc --no-env-file true # register the DEPLOY#rc fileless flag
|
|
168
|
-
mmi-cli runtime tenant reconcile {owner}/{repo} rc --watch # Hub-authorized; project-admin needs no MMI-Hub Actions access
|
|
169
|
-
mmi-cli runtime tenant redeploy {owner}/{repo} rc --watch # NOW the redeploy reads the corrected control script
|
|
170
|
-
mmi-cli runtime tenant control {owner}/{repo} rc verify-broker --watch # value-free broker proof for runtime consumers
|
|
167
|
+
mmi-cli oracle org project set-deploy {owner}/{repo} --stage rc --no-env-file true # register the DEPLOY#rc fileless flag
|
|
168
|
+
mmi-cli devops runtime tenant reconcile {owner}/{repo} rc --watch # Hub-authorized; project-admin needs no MMI-Hub Actions access
|
|
169
|
+
mmi-cli devops runtime tenant redeploy {owner}/{repo} rc --watch # NOW the redeploy reads the corrected control script
|
|
170
|
+
mmi-cli devops runtime tenant control {owner}/{repo} rc verify-broker --watch # value-free broker proof for runtime consumers
|
|
171
171
|
```
|
|
172
172
|
The reconcile must finish green before redeploy starts; `--watch` enforces that ordering. A failed rc
|
|
173
173
|
dispatch stays fail-loud — rc is ephemeral and re-runnable, so the redeploy (after the reconcile step above
|
|
@@ -195,4 +195,4 @@ about? (Process only — never the user's code or task; e.g. a misleading author
|
|
|
195
195
|
ambiguous tag or push-order step.) If yes, file **one** lesson and move on; a clean run is silent (hard
|
|
196
196
|
cap: one per run). It lands on the Hub board (deduped) and is fixed only via a reviewed PR — never edit
|
|
197
197
|
the skill live; the retro is advisory, so if the call fails, note it and continue:
|
|
198
|
-
`mmi-cli skill-lesson --skill rcand --title "<what misfired>" --body "<what; evidence; proposed amendment>"`
|
|
198
|
+
`mmi-cli learning skill-lesson --skill rcand --title "<what misfired>" --body "<what; evidence; proposed amendment>"`
|
package/skills/release/SKILL.md
CHANGED
|
@@ -20,7 +20,7 @@ master-only. This is the **only** sanctioned prod path; a prod release still nee
|
|
|
20
20
|
explicit per-turn go — an agent never self-initiates it. The board needs no
|
|
21
21
|
touch — items reached `Done` when their PRs merged to `development`; `rc`/`main` are deploy stages, not lanes.
|
|
22
22
|
|
|
23
|
-
Authority is structural + server-checked: step 0 asks the Hub (`mmi-cli org access role`), and step 3 pushes
|
|
23
|
+
Authority is structural + server-checked: step 0 asks the Hub (`mmi-cli oracle org access role`), and step 3 pushes
|
|
24
24
|
to the protected `main` branch, whose per-repo allowlist carries the same people (master + that repo's
|
|
25
25
|
project-admins; Hub: master + App only). Gate ordering: the tag lands the release SHA for checks, and
|
|
26
26
|
nothing deploys before the protected `main` push accepts that checked SHA.
|
|
@@ -43,7 +43,7 @@ nothing deploys before the protected `main` push accepts that checked SHA.
|
|
|
43
43
|
|
|
44
44
|
Confirm the human holding train authority for THIS repo authorized a prod release this turn. Probe:
|
|
45
45
|
```bash
|
|
46
|
-
mmi-cli org access role {owner}/{repo} --json # Hub-verified: { role, train }
|
|
46
|
+
mmi-cli oracle org access role {owner}/{repo} --json # Hub-verified: { role, train }
|
|
47
47
|
```
|
|
48
48
|
`train: false` — or any error (fail closed) → stop: a product repo's train belongs to that repo's
|
|
49
49
|
project-admin or the master; the Hub train is master-only. **Two exceptions to fail-closed here, and both
|
|
@@ -129,6 +129,17 @@ direction is a gate. Read the rows.
|
|
|
129
129
|
Treating doctor's exit code as the gate halts a healthy train on cosmetic drift — or, worse, teaches an
|
|
130
130
|
operator to ignore doctor's exit code entirely.
|
|
131
131
|
|
|
132
|
+
**A local `npm ci` failure during the fold on a lockfile CI already accepted is an npm-major mismatch, not a
|
|
133
|
+
bad lockfile (#4578).** Before touching the lockfile, compare toolchains:
|
|
134
|
+
```bash
|
|
135
|
+
npm -v
|
|
136
|
+
gh api repos/{owner}/{repo}/actions/runs --jq '.workflow_runs[0].id' # or read the gate log's
|
|
137
|
+
# `node -v && npm -v` toolchain-preflight line (#3446) for the npm major CI ran with
|
|
138
|
+
```
|
|
139
|
+
A different npm MAJOR (e.g. local 12 vs. CI's 11) resolves the same lockfile differently and throws `Missing:
|
|
140
|
+
<pkg> from lock file` on a lockfile that is not actually broken. Align the local npm major
|
|
141
|
+
(`npm install -g npm@<CI major>`) and re-run `npm ci` before rewriting or regenerating the lockfile.
|
|
142
|
+
|
|
132
143
|
**Then check the version yourself — do not rely on doctor having printed a row (#3674).** "Read the rows"
|
|
133
144
|
resolves to "proceed" when the row is *absent*, and doctor's version row is conditional. On 2026-07-27 this
|
|
134
145
|
step reported healthy with no version line while the installed CLI was 3.70.0 against a released 3.71.0;
|
|
@@ -149,8 +160,8 @@ central tenant deployer and therefore need DEPLOY# coords. `hub-serverless` (MMI
|
|
|
149
160
|
workflow, so do **not** dispatch `tenant-deploy.yml` for them.
|
|
150
161
|
Verify META + required SSM secret names before touching `main`:
|
|
151
162
|
```bash
|
|
152
|
-
mmi-cli org project get {owner}/{repo}
|
|
153
|
-
mmi-cli secrets preflight --stage main --repo {owner}/{repo}
|
|
163
|
+
mmi-cli oracle org project get {owner}/{repo}
|
|
164
|
+
mmi-cli vault secrets preflight --stage main --repo {owner}/{repo}
|
|
154
165
|
```
|
|
155
166
|
An enumerated missing META row or missing secret name → stop and repair the registry/secrets first. An
|
|
156
167
|
HTTP 5xx, timeout, DNS, socket, or other transport failure is **unverified**, not evidence that a name is
|
|
@@ -182,7 +193,7 @@ files further via #2767/#2771; `/release` correctly stopped on 4 conflicted file
|
|
|
182
193
|
which side carries the correct current content, then land a true-merge alignment PR (never hand-resolve on
|
|
183
194
|
`main`) before rerunning release.
|
|
184
195
|
|
|
185
|
-
It runs **automatically inside `mmi-cli release --apply`** (Step 1+ below) — built into the CLI so it
|
|
196
|
+
It runs **automatically inside `mmi-cli devops release --apply`** (Step 1+ below) — built into the CLI so it
|
|
186
197
|
works in every product repo with no repo-local script. You do not invoke it separately.
|
|
187
198
|
|
|
188
199
|
Per main-only commit it accepts: the `(cherry picked from commit <sha>)` trailer with that dev SHA an
|
|
@@ -190,7 +201,7 @@ ancestor of `origin/rc` (immune to conflict-resolved ports); a matching `git pat
|
|
|
190
201
|
(trailer-less picks); or a distribution-manifest-only bump (exempt — rc carries its own). Anything else
|
|
191
202
|
**fails the release closed** → **stop**: the right fix is a re-cut `/rcand` from `development`. Only when
|
|
192
203
|
the authorized human has manually verified the content is in the candidate, rerun with
|
|
193
|
-
`mmi-cli release --apply --ack <sha>[,<sha>…]` — the ack is recorded in the verdict. Never ack to save time.
|
|
204
|
+
`mmi-cli devops release --apply --ack <sha>[,<sha>…]` — the ack is recorded in the verdict. Never ack to save time.
|
|
194
205
|
|
|
195
206
|
## Step 0d — no docs-keeping on the release train (Hub#4164)
|
|
196
207
|
|
|
@@ -198,8 +209,8 @@ Scheduled docs-janitor / wiki-keeper / living-docs freshness passes are **retire
|
|
|
198
209
|
The release train does **not** open docs-only PRs, wait on README/architecture auto-merges, or
|
|
199
210
|
treat prose refresh as a gate.
|
|
200
211
|
|
|
201
|
-
Current state is compute-at-read + the estate repo-index (`mmi-cli repo-index search`,
|
|
202
|
-
`mmi-cli org project`, board/schedules verbs). Durable WHY stays in `docs/decisions/`.
|
|
212
|
+
Current state is compute-at-read + the estate repo-index (`mmi-cli oracle repo-index search`,
|
|
213
|
+
`mmi-cli oracle org project`, board/schedules verbs). Durable WHY stays in `docs/decisions/`.
|
|
203
214
|
If shipping code made a hand-written surface wrong, fix it on `development` as an ordinary PR
|
|
204
215
|
**outside** the train — never as a release Step.
|
|
205
216
|
|
|
@@ -223,11 +234,11 @@ Conflict → abort + stop (the train is misaligned — investigate; don't hand-r
|
|
|
223
234
|
direct-track repo, a conflict here right after a hotfix is expected friction, not a fluke — see Step 0c for
|
|
224
235
|
why (a hotfix freezes a snapshot that `development` can keep rewriting).
|
|
225
236
|
Alignment PRs are the exception to the org's squash default: land them with a true merge —
|
|
226
|
-
`mmi-cli pr merge <n> --auto --merge` (not squash; a squash discards the merge parentage, so the
|
|
237
|
+
`mmi-cli devops pr merge <n> --auto --merge` (not squash; a squash discards the merge parentage, so the
|
|
227
238
|
misalignment guard re-flags the same divergence on the next run). `--auto` clears the checks the PR
|
|
228
239
|
triggers, which block an immediate merge right after a release.
|
|
229
240
|
|
|
230
|
-
**Exception — version-manifest and `.gitignore` paths.** `mmi-cli release --apply` tolerates
|
|
241
|
+
**Exception — version-manifest and `.gitignore` paths.** `mmi-cli devops release --apply` tolerates
|
|
231
242
|
conflicts confined to the version-fold paths (Step 1b) and `.gitignore` (#1037 — a
|
|
232
243
|
repo bootstrapped before the managed-gitignore era still carries the legacy file on `main`; the candidate
|
|
233
244
|
carries the Hub-managed copy with project-local entries preserved). The org spine is no longer delivered per
|
|
@@ -236,7 +247,7 @@ committed CLI bundle on `main` only, so the next merge re-conflicts there even w
|
|
|
236
247
|
and the fold rewrites those exact paths right after the merge. For all tolerated paths the CLI takes the
|
|
237
248
|
incoming side deterministically and continues. Any other conflicted path → abort + stop as above.
|
|
238
249
|
|
|
239
|
-
## Step 1b — version fold (automatic, inside `mmi-cli release --apply`)
|
|
250
|
+
## Step 1b — version fold (automatic, inside `mmi-cli devops release --apply`)
|
|
240
251
|
|
|
241
252
|
Every release folds the version bump into the release itself (#976): after the merge onto local `main` and
|
|
242
253
|
before the tag, the CLI bumps the version manifests to the release version and commits — **unconditionally,
|
|
@@ -269,7 +280,7 @@ git tag "$TAG"
|
|
|
269
280
|
|
|
270
281
|
## Step 3 — push tag, wait for the REQUIRED checks, then push main (the gate)
|
|
271
282
|
|
|
272
|
-
`mmi-cli release --apply`'s exit code is **not** the release verdict: exit `2` can mean the release
|
|
283
|
+
`mmi-cli devops release --apply`'s exit code is **not** the release verdict: exit `2` can mean the release
|
|
273
284
|
shipped successfully while protected-branch alignment remains pending, and exit `1` can mean a
|
|
274
285
|
post-release follow-up failed after promotion. Read the live release verdict and verify these four
|
|
275
286
|
facts instead: the `main..development` count, the tag on `origin`, `gh release view`, and the runs on
|
|
@@ -296,7 +307,7 @@ gh api repos/{owner}/{repo}/commits/$SHA/check-runs \
|
|
|
296
307
|
--jq '[.check_runs[]|{name:.name,conclusion:.conclusion}]'
|
|
297
308
|
git push origin main
|
|
298
309
|
```
|
|
299
|
-
(`mmi-cli release --apply` performs this discovery + bounded wait itself.) A required context can only ever
|
|
310
|
+
(`mmi-cli devops release --apply` performs this discovery + bounded wait itself.) A required context can only ever
|
|
300
311
|
resolve on a tag SHA if its workflow runs on `push: tags` (or is otherwise SHA-addressable) — a PR/issue-event
|
|
301
312
|
job (e.g. a stale hand-added `add-to-project` / `mark-merged-pr-done` board-automation check) structurally
|
|
302
313
|
never produces a check-run there. The train recognizes that fixed pair by name and, after a short grace
|
|
@@ -313,7 +324,7 @@ never go forward (a failed check will not pass on that SHA). This is the **oppos
|
|
|
313
324
|
state (checks passing/pending, only the branch push / Release / deploy left, where the recovery is to finish
|
|
314
325
|
forward and you must NOT delete the tag). Here: fix the cause on `development` via a CI-gated PR, then **delete
|
|
315
326
|
the stray tag** — `git push origin --delete vX.Y.0` **and** `git tag -d vX.Y.0` (delete the local tag too; a
|
|
316
|
-
surviving local tag makes `next-version cycle` silently mint the *next* version) — and re-run `mmi-cli release
|
|
327
|
+
surviving local tag makes `next-version cycle` silently mint the *next* version) — and re-run `mmi-cli devops release
|
|
317
328
|
--apply` (the fold re-tags the same version on the fixed HEAD). **Tag deletion is deletion-class → it needs the
|
|
318
329
|
authorized human's explicit per-turn go.** Exception: if a publish/deploy DID run off the stray tag, do **not**
|
|
319
330
|
delete — mint the next version with `MMI_RELEASE_VERSION` instead. The CLI already classifies this
|
|
@@ -340,7 +351,7 @@ For other direct-track repos, the train dispatches nothing centrally: a `registr
|
|
|
340
351
|
event fires its own `publish.yml` (npm / plugin marketplace); a `solo-container` repo deploys via its own
|
|
341
352
|
workflow. Publish the GitHub Release, then watch/report that repo's own release-triggered run.
|
|
342
353
|
|
|
343
|
-
`mmi-cli release --apply --json` returns the relevant run id/url data with `deployStatus`; `--watch` blocks
|
|
354
|
+
`mmi-cli devops release --apply --json` returns the relevant run id/url data with `deployStatus`; `--watch` blocks
|
|
344
355
|
on the run(s) and resolves `deployStatus` to `success`/`failure`. For tenant-container repos, that is the
|
|
345
356
|
dispatched `tenant-deploy.yml` run. For Hub serverless, that is the auto-fired release `deploy.yml` and
|
|
346
357
|
`publish.yml` workflow pair — watched on `mutmutco/MMI-Hub`. For `registry-publish`, that is the target
|
|
@@ -369,7 +380,7 @@ deploy even when the train reported success — flag it loudly and fix it before
|
|
|
369
380
|
|
|
370
381
|
**Hub releases announce to Slack (#883).** Hub scope is **only** `mutmutco/MMI-Hub`: the commits/PRs on
|
|
371
382
|
`origin/main..origin/development`, this repo's `deploy.yml` + `publish.yml`, and Hub tooling (`mmi-cli`,
|
|
372
|
-
skills, plugin, registry, central workflows). Do **not** read another repo's board (`mmi-cli board` / `/mmi`
|
|
383
|
+
skills, plugin, registry, central workflows). Do **not** read another repo's board (`mmi-cli oracle board` / `/mmi`
|
|
373
384
|
on a product), watch or dispatch `ds-propagate.yml`, run `design-system` / `doctor` design-system heals for
|
|
374
385
|
consumers, or treat a product's deploy state as part of this release — those belong to that product's own
|
|
375
386
|
`/release` or `/rcand`, never a Hub train.
|
|
@@ -384,7 +395,7 @@ Source from **Hub PR titles only** (`origin/main..origin/development` on `mutmut
|
|
|
384
395
|
each line in neutral Hub-subsystem terms (CLI, skills, plugin, workflows, registry, deploy hub) — **never**
|
|
385
396
|
a product or brand name (FoFu, Katip, etc.) anywhere in the summary file, Slack post, chat, or release
|
|
386
397
|
report. Product names are allowed only when releasing **that product's repo**. Then pass the file through:
|
|
387
|
-
`mmi-cli release --apply --announce-summary-file "$f"`. After the GitHub Release publishes, the CLI posts
|
|
398
|
+
`mmi-cli devops release --apply --announce-summary-file "$f"`. After the GitHub Release publishes, the CLI posts
|
|
388
399
|
the summary to the org alerts channel as the MMI-Future Slack app (token + channel from SSM at run time).
|
|
389
400
|
For a new MMI-Hub `--apply`, the CLI refuses before promotion when the file is missing, unreadable, or does
|
|
390
401
|
not contain 3–6 non-empty lines; generated-note fallback is not an agent release path. `--resume` never
|
|
@@ -396,8 +407,8 @@ never rolls back an otherwise completed release.
|
|
|
396
407
|
info, branch alignment) while prod deploys. The verdict is collected in Step 6 — verification is not
|
|
397
408
|
skipped, only un-blocked. Deploy failure → report plainly, then **retry the existing promoted ref by deploy
|
|
398
409
|
model** once the runtime is repaired — never a re-tag or republish (`main` is already at the release, which is
|
|
399
|
-
correct). Read the model from the registry (`mmi-cli org project get {owner}/{repo}` → `deployModel`):
|
|
400
|
-
- **tenant-container** — the central tenant deployer owns the redeploy: `mmi-cli runtime tenant redeploy
|
|
410
|
+
correct). Read the model from the registry (`mmi-cli oracle org project get {owner}/{repo}` → `deployModel`):
|
|
411
|
+
- **tenant-container** — the central tenant deployer owns the redeploy: `mmi-cli devops runtime tenant redeploy
|
|
401
412
|
{owner}/{repo} main --watch`.
|
|
402
413
|
- **repository-owned serverless / registry-publish** (e.g. Jerv-PowerTools' `Deploy Jerv Memory`) — there is
|
|
403
414
|
no `runtime tenant redeploy` for these; re-run the repo's OWN declared `workflow_dispatch` deploy workflow at
|
|
@@ -408,29 +419,29 @@ Name the sanctioned dispatch mechanism you used in the train report.
|
|
|
408
419
|
## Step 4b — re-sync project info (no in-repo docs pass)
|
|
409
420
|
|
|
410
421
|
In-repo README/architecture freshness is **not** a train step (Step 0d retired, Hub#4164).
|
|
411
|
-
`mmi-cli release --apply` re-syncs the GitHub **Project** short description + thin README from the
|
|
422
|
+
`mmi-cli devops release --apply` re-syncs the GitHub **Project** short description + thin README from the
|
|
412
423
|
released commit and the registry member list through the command ladder. For a manual repair or preview use:
|
|
413
424
|
```bash
|
|
414
|
-
mmi-cli org project sync-info --apply # omit --apply for the read-only plan
|
|
425
|
+
mmi-cli oracle org project sync-info --apply # omit --apply for the read-only plan
|
|
415
426
|
```
|
|
416
427
|
|
|
417
428
|
## Step 5 — roll development forward
|
|
418
429
|
|
|
419
|
-
- Keep branches aligned: `mmi-cli release --apply` back-merges the released `main` (incl. the version
|
|
430
|
+
- Keep branches aligned: `mmi-cli devops release --apply` back-merges the released `main` (incl. the version
|
|
420
431
|
fold) into `development` and reports it as `devRollForward`. When `development` has no required checks it
|
|
421
432
|
pushes directly (`status: pushed`). When `development` *requires* checks (e.g. MMI-Hub needs
|
|
422
433
|
`cli`/`infra`/`docs`), the fresh merge commit carries no passing checks, so a direct push is structurally
|
|
423
434
|
rejected — the train instead **opens an alignment PR** `main → development` (`status: pr-pending`) and the
|
|
424
435
|
release report prints the exact land command. The release itself has already shipped; **land the alignment
|
|
425
|
-
PR with a true merge** — `mmi-cli pr merge <number> --auto --merge` (never squash — a squash drops the merge
|
|
436
|
+
PR with a true merge** — `mmi-cli devops pr merge <number> --auto --merge` (never squash — a squash drops the merge
|
|
426
437
|
parentage and the misalignment guard re-flags the divergence). `--auto` is what makes it land right after a
|
|
427
438
|
release: the alignment PR's own `cli`/`infra`/`docs` checks are still running, so a plain immediate merge is
|
|
428
439
|
policy-blocked — `--auto` merges once they pass. Never force.
|
|
429
|
-
- Full-track repos: `mmi-cli release --apply` already aligned `rc` to the released `main` (#1036 — the
|
|
440
|
+
- Full-track repos: `mmi-cli devops release --apply` already aligned `rc` to the released `main` (#1036 — the
|
|
430
441
|
push runs inside the authority-gated train; the result reports it as `rcAlignment`). No manual `rc`
|
|
431
442
|
push — if the result reports a failed alignment, investigate and rerun via the train, never bare-push.
|
|
432
443
|
- **Local branches never left stale (#2582).** A release advances `main`/`development`/`rc` on **origin**;
|
|
433
|
-
`mmi-cli release --apply` also fast-forwards the LOCAL train branches to match, so the checkout you
|
|
444
|
+
`mmi-cli devops release --apply` also fast-forwards the LOCAL train branches to match, so the checkout you
|
|
434
445
|
released from does not lag what you just pushed. The train restores + fast-forwards the start branch
|
|
435
446
|
(`checkout`, #2340) and fast-forwards the others (`localSync`) — non-destructively: only a true
|
|
436
447
|
fast-forward moves a branch; a diverged local branch is reported and left untouched (never a force).
|
|
@@ -506,7 +517,7 @@ Hub's registry-declared npm surfaces are public today, so `release-distribution.
|
|
|
506
517
|
**tenant-publish.yml E409 belt-and-braces (#2428).** The central `tenant-publish.yml` lane (the
|
|
507
518
|
`publishRequired` companion publish only — never dispatched for `registry-publish`, see above) already
|
|
508
519
|
treats a lost `npm publish` race as idempotent inside the run (a re-check `npm view` after a failed publish;
|
|
509
|
-
see the workflow file). `mmi-cli release --apply --watch` mirrors that at the CLI layer: a watched
|
|
520
|
+
see the workflow file). `mmi-cli devops release --apply --watch` mirrors that at the CLI layer: a watched
|
|
510
521
|
`tenant-publish.yml` run that concludes `failure` is re-checked against that SAME run's own log (bounded
|
|
511
522
|
retries, visibility-agnostic — never a bare `npm view`) for the idempotent-success marker before the CLI
|
|
512
523
|
reports the publish as failed. A run whose log never shows the version landed stays a loud failure.
|
|
@@ -534,4 +545,4 @@ about? (Process only — never the user's code or task; e.g. a misleading author
|
|
|
534
545
|
ambiguous version-fold or back-merge step.) If yes, file **one** lesson and move on; a clean run is silent
|
|
535
546
|
(hard cap: one per run). It lands on the Hub board (deduped) and is fixed only via a reviewed PR — never
|
|
536
547
|
edit the skill live; the retro is advisory, so if the call fails, note it and continue:
|
|
537
|
-
`mmi-cli skill-lesson --skill release --title "<what misfired>" --body "<what; evidence; proposed amendment>"`
|
|
548
|
+
`mmi-cli learning skill-lesson --skill release --title "<what misfired>" --body "<what; evidence; proposed amendment>"`
|
package/skills/resume/SKILL.md
CHANGED
|
@@ -41,12 +41,12 @@ workspace identity the next step must use (for example `mutmutco/MMC-ZuberShade`
|
|
|
41
41
|
## Step 2 — the next move
|
|
42
42
|
|
|
43
43
|
```bash
|
|
44
|
-
mmi-cli next --repo <repo reported by status>
|
|
44
|
+
mmi-cli oracle next --repo <repo reported by status>
|
|
45
45
|
```
|
|
46
46
|
|
|
47
47
|
Pass the repository from `status` explicitly; never reconstruct it by changing case or punctuation.
|
|
48
48
|
`next` recommends the single most actionable claimable board item (unblocked, priority-ranked) and prints
|
|
49
|
-
the exact `mmi-cli board claim <n>` to take it. Offer it; do not claim on the user's behalf without a go.
|
|
49
|
+
the exact `mmi-cli oracle board claim <n>` to take it. Offer it; do not claim on the user's behalf without a go.
|
|
50
50
|
For the full board partition (yours / claimable / taken) run `/mmi`.
|
|
51
51
|
|
|
52
52
|
## Step 3 — render, then stop
|
|
@@ -61,12 +61,12 @@ janitor prose. Catalog: `docs/Architecture/compute-at-read.md` (in MMI-Hub).
|
|
|
61
61
|
|
|
62
62
|
| Ask | Verb |
|
|
63
63
|
| --- | --- |
|
|
64
|
-
| Schedules / harbour lanes | `mmi-cli org schedules` / `--json` |
|
|
65
|
-
| Boxes / IPs | `mmi-cli runtime box list` |
|
|
66
|
-
| Registry / projects | `mmi-cli org project list\|get` |
|
|
67
|
-
| Board | `mmi-cli board read` / `mmi-cli next` |
|
|
68
|
-
| Docs index freshness | `mmi-cli docs index --check` |
|
|
69
|
-
| Path / symbol / meaning pointers | `mmi-cli repo-index search <q>` (Hub cloud; `--semantic` optional) |
|
|
64
|
+
| Schedules / harbour lanes | `mmi-cli harbour org schedules` / `--json` |
|
|
65
|
+
| Boxes / IPs | `mmi-cli devops runtime box list` |
|
|
66
|
+
| Registry / projects | `mmi-cli oracle org project list\|get` |
|
|
67
|
+
| Board | `mmi-cli oracle board read` / `mmi-cli oracle next` |
|
|
68
|
+
| Docs index freshness | `mmi-cli oracle docs index --check` |
|
|
69
|
+
| Path / symbol / meaning pointers | `mmi-cli oracle repo-index search <q>` (Hub cloud; `--semantic` optional) |
|
|
70
70
|
|
|
71
71
|
## Notes
|
|
72
72
|
|
|
@@ -81,4 +81,4 @@ about? (Process only — never the user's code or task; e.g. a self-check that r
|
|
|
81
81
|
snapshot that named the wrong branch.) If yes, file **one** lesson and move on; a clean run is silent
|
|
82
82
|
(hard cap: one per run). It lands on the Hub board (deduped) and is fixed only via a reviewed PR — never
|
|
83
83
|
edit the skill live; the retro is advisory, so if the call fails, note it and continue:
|
|
84
|
-
`mmi-cli skill-lesson --skill resume --title "<what misfired>" --body "<what; evidence; proposed amendment>"`
|
|
84
|
+
`mmi-cli learning skill-lesson --skill resume --title "<what misfired>" --body "<what; evidence; proposed amendment>"`
|
package/skills/secrets/SKILL.md
CHANGED
|
@@ -5,7 +5,7 @@ description: Manage the full own-project vault and granted org-infra secret name
|
|
|
5
5
|
|
|
6
6
|
# /secrets — two-tier project secrets
|
|
7
7
|
|
|
8
|
-
**Authority:** a project-admin self-serves their own product repo's full vault tree (`mmi-cli org access
|
|
8
|
+
**Authority:** a project-admin self-serves their own product repo's full vault tree (`mmi-cli oracle org access
|
|
9
9
|
role` → `project-admin` + `train`): stageless, `dev`, `rc`, and `main`. Do not redirect them to master for
|
|
10
10
|
an own-project coordinate. Only org-infra grants and cross-project administration stay master-only.
|
|
11
11
|
|
|
@@ -22,11 +22,11 @@ SecureString + KMS, and **a value is never echoed to chat or logs**):
|
|
|
22
22
|
project-admin).
|
|
23
23
|
|
|
24
24
|
**Grant scope (#3652).** A grant is `rw` by default — it opens both keyless `use` and `set`/`rm` on that
|
|
25
|
-
key. `mmi-cli secrets grant <repo> <login> <key> --read` grants **consume-only** reach: keyless `use`
|
|
25
|
+
key. `mmi-cli vault secrets grant <repo> <login> <key> --read` grants **consume-only** reach: keyless `use`
|
|
26
26
|
works, rotate and remove still refuse. Only a `--read` grant may name a **wildcard** key — `*` for the
|
|
27
27
|
whole namespace, `<provider>/*` for one provider group — so "may read every crown jewel" is one grant
|
|
28
28
|
instead of forty. A wildcard never confers write; asking for one as `rw` is refused, not narrowed.
|
|
29
|
-
`mmi-cli org access capabilities` prints `grant (read)` or `grant (rw)` next to each name.
|
|
29
|
+
`mmi-cli oracle org access capabilities` prints `grant (read)` or `grant (rw)` next to each name.
|
|
30
30
|
|
|
31
31
|
A bare `<KEY>` is the **stageless canonical** at the slug root — one value every stage shares (#2244)
|
|
32
32
|
and the path deploys resolve (#2523). A staged `dev/<KEY>` is a **per-stage override** and WINS for that
|
|
@@ -36,15 +36,15 @@ own-project `main/SECRET_KEY_BASE` or `rc/DB_URL` remains project-admin self-ser
|
|
|
36
36
|
|
|
37
37
|
**Declare-first (#2528):** the registry catalog is the SSOT; SSM is a projection of it. A `set` to a
|
|
38
38
|
coordinate not declared in the catalog is **rejected** — the error names the attempted path and the fix.
|
|
39
|
-
Declare the key first via `mmi-cli org project set <owner/repo> --secrets-file <catalog.json>` (`stages: []`
|
|
39
|
+
Declare the key first via `mmi-cli oracle org project set <owner/repo> --secrets-file <catalog.json>` (`stages: []`
|
|
40
40
|
= the shared stageless canonical, `stages: ["dev"]` = a per-stage override), then retry. See what is
|
|
41
|
-
declared with `mmi-cli secrets catalog` or `secrets list`; ask for a key you lack via `mmi-cli secrets
|
|
41
|
+
declared with `mmi-cli vault secrets catalog` or `secrets list`; ask for a key you lack via `mmi-cli vault secrets
|
|
42
42
|
request <KEY>`. There is no master bypass. `rm` of an undeclared path stays allowed, so cleanup keeps
|
|
43
43
|
working. Google OAuth is one stageless pair per repo: bare `GOOGLE_CLIENT_ID` + `GOOGLE_CLIENT_SECRET`
|
|
44
44
|
at the slug root (the staged `{dev,rc,main}/GOOGLE_*` shape is retired; `org oauth set-creds` writes the
|
|
45
45
|
bare keys).
|
|
46
46
|
|
|
47
|
-
All ops run through `mmi-cli secrets …`, which calls the org backend with the caller's `gh` token; the
|
|
47
|
+
All ops run through `mmi-cli vault secrets …`, which calls the org backend with the caller's `gh` token; the
|
|
48
48
|
backend re-verifies **project-admin-of-this-repo** and the **vault namespace** server-side and does the scoped
|
|
49
49
|
SSM op. This skill never touches AWS.
|
|
50
50
|
|
|
@@ -54,11 +54,11 @@ Read the current repo + slug; the tier of a key follows from its name (above). `
|
|
|
54
54
|
exists and which ones **you** can manage (a `*`), never values.
|
|
55
55
|
|
|
56
56
|
```bash
|
|
57
|
-
mmi-cli secrets list # names + tier + a * on the ones you can write. NEVER values.
|
|
57
|
+
mmi-cli vault secrets list # names + tier + a * on the ones you can write. NEVER values.
|
|
58
58
|
```
|
|
59
59
|
|
|
60
60
|
`secrets: no registry META` or `Hub API unreachable` → the repo is not registered with the Hub, GitHub auth
|
|
61
|
-
is missing, or the Hub API is unavailable. Run `mmi-cli org project get <owner/repo>` to distinguish those cases;
|
|
61
|
+
is missing, or the Hub API is unavailable. Run `mmi-cli oracle org project get <owner/repo>` to distinguish those cases;
|
|
62
62
|
a master-admin backfills the registry before secrets can be resolved.
|
|
63
63
|
|
|
64
64
|
## Step 1 — the verb
|
|
@@ -68,17 +68,17 @@ Default to the **current repo**; pass `--repo owner/Name` to target another (you
|
|
|
68
68
|
```bash
|
|
69
69
|
# CONSUME a secret keyless — injected into the command's env, NEVER printed (raw `secrets get` was
|
|
70
70
|
# removed, the floor wins, #2844):
|
|
71
|
-
mmi-cli secrets use SCRAPER_API_KEY -- <cmd>
|
|
71
|
+
mmi-cli vault secrets use SCRAPER_API_KEY -- <cmd>
|
|
72
72
|
|
|
73
73
|
# Write / rotate — the VALUE is read from stdin, NEVER an argument (so it can't leak into shell history
|
|
74
74
|
# or process args). Pipe it in:
|
|
75
|
-
printf %s "$THE_VALUE" | mmi-cli secrets set SCRAPER_API_KEY
|
|
75
|
+
printf %s "$THE_VALUE" | mmi-cli vault secrets set SCRAPER_API_KEY
|
|
76
76
|
|
|
77
77
|
# Validate a known provider key without printing its value:
|
|
78
|
-
mmi-cli secrets verify RECALL_API_KEY
|
|
78
|
+
mmi-cli vault secrets verify RECALL_API_KEY
|
|
79
79
|
|
|
80
80
|
# Remove:
|
|
81
|
-
mmi-cli secrets rm SCRAPER_API_KEY
|
|
81
|
+
mmi-cli vault secrets rm SCRAPER_API_KEY
|
|
82
82
|
```
|
|
83
83
|
|
|
84
84
|
**Never** pass a value as an argument (`secrets set KEY thevalue` is wrong — there is no value arg). The
|
|
@@ -89,7 +89,7 @@ confirmation prints the **name and tier only**, never the value.
|
|
|
89
89
|
Before rotating, enumerate every copy of the key so no tier stays stale:
|
|
90
90
|
|
|
91
91
|
```bash
|
|
92
|
-
mmi-cli secrets list --repo owner/Repo
|
|
92
|
+
mmi-cli vault secrets list --repo owner/Repo
|
|
93
93
|
```
|
|
94
94
|
|
|
95
95
|
Check the bare canonical plus any `dev/`, `rc/`, `main/` overrides the list shows. Rotate the provider-side
|
|
@@ -107,9 +107,9 @@ it). These verbs are **master-only** — the backend 403s anyone else.
|
|
|
107
107
|
|
|
108
108
|
```bash
|
|
109
109
|
# MASTER: let @oguz-mut consume one _org provider key from their MM-Chat project
|
|
110
|
-
mmi-cli secrets grant mutmutco/MM-Chat oguz-mut google/SOME_SHARED_KEY
|
|
110
|
+
mmi-cli vault secrets grant mutmutco/MM-Chat oguz-mut google/SOME_SHARED_KEY
|
|
111
111
|
# MASTER: withdraw it
|
|
112
|
-
mmi-cli secrets revoke mutmutco/MM-Chat oguz-mut google/SOME_SHARED_KEY
|
|
112
|
+
mmi-cli vault secrets revoke mutmutco/MM-Chat oguz-mut google/SOME_SHARED_KEY
|
|
113
113
|
```
|
|
114
114
|
|
|
115
115
|
The master can also operate the org-infra key directly while guiding (master ⊇ project-admin). Org-infra
|
|
@@ -130,8 +130,8 @@ when they point at the same sandbox project; prod should stay distinct when the
|
|
|
130
130
|
|
|
131
131
|
Sanctioned copy within the own-project vault (org-infra/cross-project sources remain master-gated):
|
|
132
132
|
```bash
|
|
133
|
-
mmi-cli secrets copy --from rc --to dev --keys RECALL_API_KEY,GEMINI_API_KEY
|
|
134
|
-
mmi-cli secrets copy --from rc --to dev --keys RECALL_API_KEY --dry-run # plan only
|
|
133
|
+
mmi-cli vault secrets copy --from rc --to dev --keys RECALL_API_KEY,GEMINI_API_KEY
|
|
134
|
+
mmi-cli vault secrets copy --from rc --to dev --keys RECALL_API_KEY --dry-run # plan only
|
|
135
135
|
```
|
|
136
136
|
Prefer this over manual copy piping — audit-logged, blocklist enforced.
|
|
137
137
|
|
|
@@ -154,4 +154,4 @@ about? (Process only — never the user's code or task; e.g. a canonical-name or
|
|
|
154
154
|
that risked echoing a value.) If yes, file **one** lesson and move on; a clean run is silent (hard cap:
|
|
155
155
|
one per run). It lands on the Hub board (deduped) and is fixed only via a reviewed PR — never edit the
|
|
156
156
|
skill live; the retro is advisory, so if the call fails, note it and continue:
|
|
157
|
-
`mmi-cli skill-lesson --skill secrets --title "<what misfired>" --body "<what; evidence; proposed amendment>"`
|
|
157
|
+
`mmi-cli learning skill-lesson --skill secrets --title "<what misfired>" --body "<what; evidence; proposed amendment>"`
|
package/skills/stage/SKILL.md
CHANGED
|
@@ -148,4 +148,4 @@ about? (Process only — never the user's code or task; e.g. a teardown that lef
|
|
|
148
148
|
Playwright output path aimed at the repo root.) If yes, file **one** lesson and move on; a clean run is
|
|
149
149
|
silent (hard cap: one per run). It lands on the Hub board (deduped) and is fixed only via a reviewed PR —
|
|
150
150
|
never edit the skill live; the retro is advisory, so if the call fails, note it and continue:
|
|
151
|
-
`mmi-cli skill-lesson --skill stage --title "<what misfired>" --body "<what; evidence; proposed amendment>"`
|
|
151
|
+
`mmi-cli learning skill-lesson --skill stage --title "<what misfired>" --body "<what; evidence; proposed amendment>"`
|
package/skills/worktree/SKILL.md
CHANGED
|
@@ -25,8 +25,9 @@ The issue-ref form derives `<issue-number>-<short-slug>`, assigns the item, and
|
|
|
25
25
|
|
|
26
26
|
`worktree create` also leases the tree to the **creating session** (#4328). A later `jerv-cli lane submit
|
|
27
27
|
--dir` (or any governed seat) refuses an already-held host lease and will not commandeer it. Before handing
|
|
28
|
-
the tree to a governed seat, release that lease first
|
|
29
|
-
`jerv-cli lease close <
|
|
28
|
+
the tree to a governed seat, release that lease first — safe once the session's own edits in that tree are
|
|
29
|
+
committed and pushed: `jerv-cli lease close --ref <worktree path>` (closes every lease on that ref; no id
|
|
30
|
+
lookup needed). To inspect what's held before closing, `jerv-cli lease list` shows id, ref, and owner.
|
|
30
31
|
|
|
31
32
|
## Step 2 — claim + work
|
|
32
33
|
|
|
@@ -41,8 +42,8 @@ open — never move it by hand.
|
|
|
41
42
|
|
|
42
43
|
```bash
|
|
43
44
|
git push origin <branch>:<branch> # explicit feature refspec — see below
|
|
44
|
-
mmi-cli pr create --title "<title>" --body-file .jerv/PR_BODY.md --base development
|
|
45
|
-
mmi-cli pr checks-wait <PR-number> # wait for required CI to go green
|
|
45
|
+
mmi-cli devops pr create --title "<title>" --body-file .jerv/PR_BODY.md --base development
|
|
46
|
+
mmi-cli devops pr checks-wait <PR-number> # wait for required CI to go green
|
|
46
47
|
```
|
|
47
48
|
|
|
48
49
|
Write the PR body under `.jerv/` (#4405), never at the worktree root. `.jerv/` is the agent-artifact
|
|
@@ -56,12 +57,21 @@ share the push with staging or commit verbs in one compound command: the deny ap
|
|
|
56
57
|
command, so a refused `git add … && git commit … && git push …` chain discards the add and commit
|
|
57
58
|
with it. Stage, commit, and push as separate commands.
|
|
58
59
|
|
|
60
|
+
If the branch adds, removes, or renames any `docs/` file, `pr create` refuses with a stale
|
|
61
|
+
`docs/index.md` (#4092) — run `mmi-cli oracle docs index --write`, commit `docs/index.md`, and push again
|
|
62
|
+
before retrying.
|
|
63
|
+
|
|
59
64
|
## Step 4 — land + clean up
|
|
60
65
|
|
|
61
|
-
Under standing go (green CI, CI-gated PR) land to `development
|
|
66
|
+
Under standing go (green CI, CI-gated PR) land to `development`. **Invoke `mmi-cli devops pr land` from the
|
|
67
|
+
primary checkout** (or any cwd that is not the PR worktree) (#4549). Landing while cwd is still inside
|
|
68
|
+
the worktree that cleanup removes can merge successfully and still exit 1 with
|
|
69
|
+
`cleanupError: … Unable to read current working directory` — post-merge `gh`/`git` follow-ups then have
|
|
70
|
+
no readable cwd even when removal itself chdir'd away (#4140).
|
|
62
71
|
|
|
63
72
|
```bash
|
|
64
|
-
|
|
73
|
+
cd <primary-checkout> # e.g. the main MMI-Hub clone — not the slice worktree
|
|
74
|
+
mmi-cli devops pr land <PR-number>
|
|
65
75
|
```
|
|
66
76
|
|
|
67
77
|
`pr land` waits for checks, squash-merges, and does the full cleanup at the branch boundary: removes the
|
|
@@ -79,12 +89,11 @@ are standing in):
|
|
|
79
89
|
mmi-cli worktree land --apply
|
|
80
90
|
```
|
|
81
91
|
|
|
82
|
-
**Cwd-safe
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
sweep retries from a safe cwd.
|
|
87
|
-
manually outside `pr land`.
|
|
92
|
+
**Cwd-safe removal (#4140):** `worktree land --apply` (what `pr land` runs) releases the process cwd to
|
|
93
|
+
the primary checkout before deleting the tree (#1444/#2747) so Windows `rmdir` is not `EBUSY`. That does
|
|
94
|
+
**not** replace the agent rule above: still start `pr land` from the primary checkout (#4549). Prefer
|
|
95
|
+
primary cwd also when running `worktree land` manually outside `pr land`. If removal still fails (IDE
|
|
96
|
+
lock, antivirus), the deferred sweep retries from a safe cwd.
|
|
88
97
|
|
|
89
98
|
**No main lineage on a squashable development PR (#4365 / #4371):** never `git merge -s ours` (or otherwise
|
|
90
99
|
merge) a main-parented port commit into a development PR that will squash. Squash folds second-parent
|
|
@@ -96,6 +105,13 @@ that references that SHA in the message — do not pull the main commit into the
|
|
|
96
105
|
This does not weaken the `#3167` merge floor on `/hotfix` and `/release` (never squash a tagged commit;
|
|
97
106
|
alignment / roll-forward stays a true merge).
|
|
98
107
|
|
|
108
|
+
**Stay-open phrasing (JC#495 / #3718):** GitHub's closing-keyword parser is negation-blind. `Does not
|
|
109
|
+
close #N` still contains `close #N` and **closes the issue** on merge/squash (measured: Jerv-JervCode
|
|
110
|
+
PR #493 closed #487). When an issue must stay open, never put `close`/`closes`/`fix`/`resolve` + `#N`
|
|
111
|
+
in the PR body, commit message, or merge message — use `Part of #N`, `Refs #N`, or `leaves #N open` only.
|
|
112
|
+
`mmi-cli devops pr create` rewrites common negated phrases; `pr land` / `pr merge` still refuse any remaining
|
|
113
|
+
negation-blind close. `--force` only when those targets should actually close.
|
|
114
|
+
|
|
99
115
|
If a PR already inherited closed-issue `Closes` keywords from that anti-pattern and `pr land` / `pr merge`
|
|
100
116
|
refuses, land with `--force` only when those inherited targets are already closed — prefer preventing the
|
|
101
117
|
pollution above over relying on `--force`.
|
|
@@ -105,8 +121,8 @@ pollution above over relying on `--force`.
|
|
|
105
121
|
Record durable decisions on the issue or PR, then check the board again:
|
|
106
122
|
|
|
107
123
|
```bash
|
|
108
|
-
mmi-cli wave status # remaining worktrees, open PRs, local stages at a glance
|
|
109
|
-
mmi-cli next # the next actionable item
|
|
124
|
+
mmi-cli oracle wave status # remaining worktrees, open PRs, local stages at a glance
|
|
125
|
+
mmi-cli oracle next # the next actionable item
|
|
110
126
|
```
|
|
111
127
|
|
|
112
128
|
## Notes
|
|
@@ -128,4 +144,4 @@ about? (Process only — never the user's code or task; e.g. a create that branc
|
|
|
128
144
|
land that left a worktree behind.) If yes, file **one** lesson and move on; a clean run is silent (hard
|
|
129
145
|
cap: one per run). It lands on the Hub board (deduped) and is fixed only via a reviewed PR — never edit
|
|
130
146
|
the skill live; the retro is advisory, so if the call fails, note it and continue:
|
|
131
|
-
`mmi-cli skill-lesson --skill worktree --title "<what misfired>" --body "<what; evidence; proposed amendment>"`
|
|
147
|
+
`mmi-cli learning skill-lesson --skill worktree --title "<what misfired>" --body "<what; evidence; proposed amendment>"`
|