@mutmutco/kilo-plugin 3.106.0 → 3.107.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mutmutco/kilo-plugin",
3
- "version": "3.106.0",
3
+ "version": "3.107.1",
4
4
  "description": "MMI workflow skills and org gates delivery.",
5
5
  "author": {
6
6
  "name": "MMI Future",
@@ -1,4 +1,4 @@
1
- // Scrooge v2 pillar 2 — Claude PostToolUse secret redaction (#1589). No throttling, no compaction; fail-soft always.
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>"`
@@ -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>"`
@@ -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
@@ -146,8 +146,8 @@ Hub docs catalog-lockstep refuses PRs into `development` that advance
146
146
  truth. When Publish-Truth / a version bump must advance the marketplace, do **not** land
147
147
  `release-distribution prepare` as a development PR — use this hotfix door:
148
148
 
149
- 1. `mmi-cli 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 hotfix release vX.Y.Z` (publish)
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
151
  3. land the automatic `hotfix-fold/<tag>` development fold PR (or follow its printed remedy)
152
152
 
153
153
  A development prepare PR that only exists to move marketplace ahead of main will keep failing
@@ -158,5 +158,5 @@ catalog-lockstep; that is not a false red — switch to the hotfix path above.
158
158
  If this skill's instructions themselves misfired, file one deduplicated lesson and continue:
159
159
 
160
160
  ```bash
161
- 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>"
162
162
  ```
@@ -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>"`
@@ -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>"`
@@ -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>"`
@@ -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>"`
@@ -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>"`
@@ -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>"`
@@ -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>"`
@@ -42,8 +42,8 @@ open — never move it by hand.
42
42
 
43
43
  ```bash
44
44
  git push origin <branch>:<branch> # explicit feature refspec — see below
45
- mmi-cli pr create --title "<title>" --body-file .jerv/PR_BODY.md --base development
46
- 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
47
47
  ```
48
48
 
49
49
  Write the PR body under `.jerv/` (#4405), never at the worktree root. `.jerv/` is the agent-artifact
@@ -57,9 +57,13 @@ share the push with staging or commit verbs in one compound command: the deny ap
57
57
  command, so a refused `git add … && git commit … && git push …` chain discards the add and commit
58
58
  with it. Stage, commit, and push as separate commands.
59
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
+
60
64
  ## Step 4 — land + clean up
61
65
 
62
- Under standing go (green CI, CI-gated PR) land to `development`. **Invoke `mmi-cli pr land` from the
66
+ Under standing go (green CI, CI-gated PR) land to `development`. **Invoke `mmi-cli devops pr land` from the
63
67
  primary checkout** (or any cwd that is not the PR worktree) (#4549). Landing while cwd is still inside
64
68
  the worktree that cleanup removes can merge successfully and still exit 1 with
65
69
  `cleanupError: … Unable to read current working directory` — post-merge `gh`/`git` follow-ups then have
@@ -67,7 +71,7 @@ no readable cwd even when removal itself chdir'd away (#4140).
67
71
 
68
72
  ```bash
69
73
  cd <primary-checkout> # e.g. the main MMI-Hub clone — not the slice worktree
70
- mmi-cli pr land <PR-number>
74
+ mmi-cli devops pr land <PR-number>
71
75
  ```
72
76
 
73
77
  `pr land` waits for checks, squash-merges, and does the full cleanup at the branch boundary: removes the
@@ -101,6 +105,13 @@ that references that SHA in the message — do not pull the main commit into the
101
105
  This does not weaken the `#3167` merge floor on `/hotfix` and `/release` (never squash a tagged commit;
102
106
  alignment / roll-forward stays a true merge).
103
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
+
104
115
  If a PR already inherited closed-issue `Closes` keywords from that anti-pattern and `pr land` / `pr merge`
105
116
  refuses, land with `--force` only when those inherited targets are already closed — prefer preventing the
106
117
  pollution above over relying on `--force`.
@@ -110,8 +121,8 @@ pollution above over relying on `--force`.
110
121
  Record durable decisions on the issue or PR, then check the board again:
111
122
 
112
123
  ```bash
113
- mmi-cli wave status # remaining worktrees, open PRs, local stages at a glance
114
- 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
115
126
  ```
116
127
 
117
128
  ## Notes
@@ -133,4 +144,4 @@ about? (Process only — never the user's code or task; e.g. a create that branc
133
144
  land that left a worktree behind.) If yes, file **one** lesson and move on; a clean run is silent (hard
134
145
  cap: one per run). It lands on the Hub board (deduped) and is fixed only via a reviewed PR — never edit
135
146
  the skill live; the retro is advisory, so if the call fails, note it and continue:
136
- `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>"`