@mutmutco/claude-plugin 4.5.173 → 4.5.175

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.
@@ -5,66 +5,48 @@ description: Split a vision or umbrella issue into linked child issues in one ba
5
5
 
6
6
  # /epic — decompose an umbrella into children
7
7
 
8
- Turn one large item — a vision issue, an epic, an umbrella issue — into a set of native sub-issues in a
9
- single pre-validated batch, each already linked to its parent. This is the slice-and-fan-out act done by
10
- hand today: draft the children, validate them all, create them, confirm the tree.
8
+ Turn one large item (vision, epic, umbrella issue) into native sub-issues in one pre-validated batch, each linked to its parent: draft the children, validate all, create, confirm the tree.
11
9
 
12
- ## Opening branch — create a new umbrella when none exists
10
+ ## Opening branch — no umbrella yet
13
11
 
14
- When the request is a product intent rather than an existing issue, gather the intent first, read the
15
- repo's live issue templates, draft the umbrella from the matching feature/task template, and show that
16
- draft for the user's go. Only then create one issue with the `epic` label and an explicit Priority field;
17
- re-read it from the board to prove the body, label, and priority landed. Stop there unless the user also
18
- asked for and approved child decomposition.
12
+ For a product intent rather than an existing issue: gather the intent, read the repo's live issue templates, draft the umbrella from the matching feature/task template and show the draft for the user's go. Then create one issue with the `epic` label and an explicit Priority field; re-read it from the board to prove body, label and priority landed. Stop there unless child decomposition was also asked for and approved.
19
13
 
20
14
  ## Step 0 — load the umbrella whole
21
15
 
22
- Read the parent end-to-end before slicing — body **and every comment**, treating later comments as
23
- superseding:
16
+ Read the body **and every comment** (later comments supersede):
24
17
 
25
18
  ```bash
26
- mmi-cli oracle board show <owner/repo#N> # status, body, and every comment for the umbrella
19
+ mmi-cli oracle board show <owner/repo#N>
27
20
  ```
28
21
 
29
- Slice by deliverable, not by phase: each child must be independently claimable and land in its own PR.
30
- Keep the parent as the umbrella — do not close it until the last child merges.
22
+ Slice by deliverable, not phase: each child is independently claimable and lands in its own PR. The parent stays open until the last child merges.
31
23
 
32
24
  ## Step 1 — draft the batch file
33
25
 
34
- Before drafting, inspect the umbrella's existing children:
26
+ Inspect existing children first:
35
27
 
36
28
  ```bash
37
- mmi-cli oracle issue children <owner/repo#N> # each child: number/title/state/repo/boardStatus/linkedPrs
29
+ mmi-cli oracle issue children <owner/repo#N>
38
30
  ```
39
31
 
40
- Write a JSON array (one object per child) to a scratch path under `.jerv/tmp/`, named uniquely for this
41
- epic — `.jerv/tmp/epic-<parentNumber>-children.json` (never reuse the file between epics: a previous
42
- epic's leftover batch collides with the new rows, silently on an unguarded host). Each row:
32
+ Write a JSON array, one object per child, to `.jerv/tmp/epic-<parentNumber>-children.json` (unique per epic; a leftover batch from another epic collides with the new rows):
43
33
 
44
34
  ```json
45
35
  [
46
36
  { "type": "task", "title": "C1: extract the shared frame", "body": "…", "priority": "high",
47
37
  "surface": "cli", "parent": "owner/repo#42" },
48
- { "type": "feature", "title": "C2: wire the new command", "body": "…", "priority": "medium",
49
- "parent": "owner/repo#42" }
38
+ { "type": "feature", "title": "C2: wire the new command", "body": "…", "parent": "owner/repo#42" }
50
39
  ]
51
40
  ```
52
41
 
53
- - `type` — `bug` · `feature` · `task` (required; maps to the repo's issue-template label).
54
- - `title` — required, non-empty; keep it a short, greppable deliverable.
55
- - `parent` — the umbrella ref (`N` or `#N` as a string, a bare JSON number, `owner/repo#N`, or
56
- URL); links each child as a native sub-issue on create, so you do not need a separate `link-child`
57
- pass. Cross-repo is fine (a Hub umbrella can parent product-repo children).
58
- - `priority` — `urgent|high|medium|low` (defaults to `medium`); sets the board Priority **field**.
59
- - `repo` — optional per-row target repo (`owner/repo`); defaults to `--repo`, then the current repo.
60
- This is how one batch fans children out across repos under a single umbrella.
61
- - `surface` — required when the target repo uses `surface:*` taxonomy; accepts the value with or without
62
- the prefix. A top-level `--surface <value>` may supply the default for every applicable row.
63
-
64
- The batch **pre-validates every row before creating any** — one bad row fails the whole set with an
65
- aggregate error, so you fix all of them once. It warns when a row title closely matches an existing open
66
- child of the same parent; inspect that warning before creating a duplicate. Get the user's go on the drafted
67
- set before writing.
42
+ - `type` — required: `bug` · `feature` · `task`.
43
+ - `title` — required, a short greppable deliverable.
44
+ - `parent` — the umbrella (`N`, `#N`, a bare number, `owner/repo#N` or URL); links the child as a native sub-issue on create, so no `link-child` pass. Cross-repo is fine.
45
+ - `priority` — `urgent|high|medium|low` (default `medium`); sets the board Priority field.
46
+ - `repo` — optional per-row `owner/repo`; defaults to `--repo`, then the current repo.
47
+ - `surface` — required when the target repo uses `surface:*` taxonomy, with or without the prefix; top-level `--surface <value>` sets the default.
48
+
49
+ The batch pre-validates every row before creating any; one bad row fails the set with an aggregate error. A warning that a title closely matches an open child of the same parent must be inspected before creating a duplicate. Get the user's go on the drafted set before writing.
68
50
 
69
51
  ## Step 2 — create the children
70
52
 
@@ -72,57 +54,30 @@ set before writing.
72
54
  mmi-cli oracle issue create --type task --batch .jerv/tmp/epic-42-children.json --surface cli
73
55
  ```
74
56
 
75
- `--type` is required by the create command but each row's own `type` governs; pass any valid type as the
76
- placeholder. It prints per-row `{number,url}` results and fails loud on any misfire. Add
77
- `--idempotency-key <key>` when a retried loop must not duplicate.
78
-
79
- When creating through `mmi-cli vault secrets use GH_TOKEN -- …`, the `GH_TOKEN` environment override can
80
- disrupt Hub session discovery and print `board attach skipped — no Hub session token` for batch rows. That
81
- warning can appear when placement is correct, but it is not harmless or proof of placement: final verification
82
- must prove every intended child is linked and on the board as Todo with `mmi-cli oracle issue children
83
- <owner/repo#N> --json`. `boardStatus: null` is **inconclusive** (the children walk can miss org-board
84
- Status that `board show` still sees) — it is not proof the child is off the board. A non-null Status
85
- (Todo / In Progress / …) is the placement proof; if Status stays null after this command, investigate
86
- with `board show` rather than treating null as "not on board".
57
+ `--type` is required but each row's own `type` governs. It prints per-row `{number,url}` and fails loud. Add `--idempotency-key <key>` when a retried loop must not duplicate. The lookup is find-before-create, not atomic: one batch writer at a time, never concurrent creates with the same key. Size the command's wall-clock budget for the whole sequential batch; on timeout the outcome is unknown, so confirm the process ended, wait for writes to quiesce, inspect the children, then retry the missing rows with the same key.
87
58
 
88
- The idempotency lookup is find-before-create, not an atomic reservation. Run one batch writer at a time:
89
- never submit concurrent creates with the same key. Size the calling command's wall-clock budget for the
90
- whole sequential batch. If the command times out, its outcome is unknown — confirm the process has ended,
91
- wait for writes to quiesce, inspect the children, then retry the missing rows with the same key.
59
+ Under `mmi-cli vault secrets use GH_TOKEN -- …` the `GH_TOKEN` override can break Hub session discovery and print `board attach skipped — no Hub session token`; that is not proof of placement either way, so verify in Step 3.
92
60
 
93
61
  ## Step 3 — confirm the tree
94
62
 
95
63
  ```bash
96
- mmi-cli oracle issue children <owner/repo#N> --json # each child: number/title/state/repo/assignee/boardStatus/linkedPrs
64
+ mmi-cli oracle issue children <owner/repo#N> --json
97
65
  ```
98
66
 
99
- This JSON is the final placement authority: verify every intended child is linked and on the board as Todo
100
- (`boardStatus` names Todo). `boardStatus: null` is inconclusive, not "not on board".
101
- If it does not prove that placement, investigate and correct the misfire. To link a child that already existed (not
102
- part of the batch), use the inverse-friendly single link:
67
+ This JSON is the placement authority: every intended child must be linked and on the board as Todo (`boardStatus` names it). `boardStatus: null` is inconclusive (the walk can miss org-board Status that `board show` still sees); investigate with `board show`. If placement is not proven, correct the misfire. Link a pre-existing child with:
103
68
 
104
69
  ```bash
105
70
  mmi-cli oracle issue link-child <parent> <child>
106
71
  ```
107
72
 
108
- Each child is now a parallel item — fan them out one worktree + PR each. On Windows, set
109
- `git config core.longpaths true` on the main checkout before the first `git worktree add` (#5499). When
110
- several linked worktrees belong to the same clone, serialize `git branch -m` / other ref renames (or retry
111
- serially on `.tmp-renamed-log`) so parallel agents do not race the shared ref log (#5485). **When the last
112
- child merges, close the umbrella** (its board `Done` follows automatically).
113
-
114
- ## Notes
115
-
116
- - Native sub-issues, not a body task-list: the parent renders a sub-issue checklist and each child renders
117
- its parent — nothing to hand-maintain.
118
- - Never free-type children with raw `gh issue create` — the batch path carries validation, board attach,
119
- and structured output.
120
-
121
- ## Retro — one check before you finish
122
- Before your final report, answer one question honestly: did **this skill's own instructions** misfire
123
- this run — ambiguous wording, a misleading message, or an environment failure it should have warned
124
- about? (Process only — never the user's code or task; e.g. a batch schema that rejected a valid row, or a
125
- link that attached to the wrong parent.) If yes, file **one** lesson and move on; a clean run is silent
126
- (hard cap: one per run). It lands on the owning board (deduped) and is fixed only via a reviewed PR — never
127
- edit the skill live; the retro is advisory, so if the call fails, note it and continue. File through MMI:
128
- `mmi-cli learning skill-lesson --skill epic --title "<what misfired>" --body "<what; evidence; proposed amendment>"`
73
+ Each child is now a parallel item: one worktree + PR each. On Windows set `git config core.longpaths true` on the main checkout before the first `git worktree add`. When linked worktrees share a clone, serialize `git branch -m` and other ref renames (or retry serially on `.tmp-renamed-log`). **When the last child merges, close the umbrella** (board `Done` follows).
74
+
75
+ Never free-type children with raw `gh issue create`: the batch path carries validation, board attach and structured output.
76
+
77
+ ## Retro
78
+
79
+ Before the final report, ask once: did this skill's own instructions misfire? Process only. If yes, file one lesson (hard cap: one per run); a clean run is silent; if the call fails, note it and continue. Never edit the skill live.
80
+
81
+ ```bash
82
+ mmi-cli learning skill-lesson --skill epic --title "<what misfired>" --body "<what; evidence; proposed amendment>"
83
+ ```
@@ -3,25 +3,23 @@ name: hotfix
3
3
  description: Promote a merged development fix to main and production via the Hub train.
4
4
  ---
5
5
 
6
- **Host-native invocation:** Claude `/mmi:hotfix` · Codex `$mmi:hotfix` · jervcode `/hotfix` · Hermes skill_view. A backticked `/name` in this doc names the matching workflow (this skill or a sibling), not a literal command.
6
+ **Host-native invocation:** Claude `/mmi:hotfix` · Codex `$mmi:hotfix` · jervcode `/hotfix` · Hermes skill_view.
7
7
 
8
- **Argument:** none. A hotfix is PATCH-only; leave `MMI_BUMP_INTENT` and `MMI_RELEASE_VERSION` unset — a non-patch declaration refuses.
8
+ **Argument:** none; PATCH-only (leave `MMI_BUMP_INTENT`, `MMI_RELEASE_VERSION` unset).
9
9
 
10
10
  # /hotfix — promote a development fix to main + prod
11
11
 
12
- A hotfix is promotion, not authoring. The fix lands on `development` first through a normal issue, worktree, PR, review and CI gate; Hub then ports that merged PR or SHA onto a main-base branch as a cherry-pick with `-x`, keeps the audit trail, and performs the PATCH release. Never author the fix on a branch off `main`. The FIX is never back-merged: `development` already has it, `rc` absorbs it at the next `/rcand`, and the release hotfix-coverage guard blocks a later candidate that omits it. The VERSION FOLD is different: `hotfix release` ports it to `development` as a fold PR — NOT a back-merge, nothing from `main` is merged into `development`.
12
+ The fix lands on `development` first; Hub ports that merged PR or SHA onto a main-base branch (cherry-pick with `-x`) and releases the PATCH. Never author the fix on a branch off `main`. The fix is NOT a back-merge (`rc` absorbs it next `/rcand`; the hotfix-coverage guard blocks a candidate omitting it).
13
13
 
14
14
  ## Lane
15
15
 
16
- For an MM-Work suite lead or member, read [suite.md](suite.md) before choosing a lane.
17
-
18
- Read META and name the lane before describing or executing anything:
16
+ MM-Work suite seats: read [suite.md](suite.md). Lane from META:
19
17
 
20
18
  ```bash
21
19
  mmi-cli oracle org project get {owner}/{repo} --json
22
20
  ```
23
21
 
24
- A hotfix always skips rc on every track: it cherry-picks `development → main` directly, MMI-Hub included. `deployModel` decides the release-triggered runs the train watches; on `vercel` nothing is dispatched — Vercel builds `main` on the push and the hotfix waits for its Production Deployment and probes the URL, same as `/release --watch`; a leg left pending settles on the next doctor `--heal`. Unreadable META → stop; never infer the lane from branch names, tags or release history.
22
+ A hotfix skips rc on every track; `deployModel: vercel` waits for the Production Deployment, then probes it. Unreadable META → stop; never infer the lane.
25
23
 
26
24
  ## Preflight
27
25
 
@@ -29,59 +27,41 @@ A hotfix always skips rc on every track: it cherry-picks `development → main`
29
27
  mmi-cli devops train doctor --lane hotfix --heal --json
30
28
  ```
31
29
 
32
- The JSON is on stdout alone; a stale CLI first prints its self-update notice on stderr and re-runs itself, so parse stdout only, never `2>&1`. Read `ready`, then `findings[]`: each carries `code`, `severity` (`blocker` · `warning` · `healed` · `info`), `source` (`local` · `origin`), `remedy` and `anchor`. `ready: false` → stop and quote every blocker's `code` and `remedy`; an unread origin is never green. `hotfix start` and `hotfix release` re-run this doctor as their step 0 with heal on.
30
+ Parse stdout only; never `2>&1`. `ready` false → stop and quote every blocker's `code` and `remedy`; an unread origin is never green. Findings carry `code`, `severity`, `source`, `remedy`, `anchor`.
33
31
 
34
32
  ## Apply
35
33
 
36
- Run from the primary checkout. One cycle carries as many merged fixes as you name, in pick order.
34
+ From the primary checkout.
37
35
 
38
- 1. Start from the merged development fix(es):
36
+ 1. Start (derives PATCH from the latest `origin/main` Release tag, branches `hotfix/vX.Y.Z`, folds the version, opens the PR; never repeat by hand):
39
37
 
40
38
  ```bash
41
39
  mkdir -p .jerv/tmp && r1=$(mktemp .jerv/tmp/hotfix-start.XXXXXX)
42
40
  mmi-cli devops hotfix start --from <pr|sha>[,<pr|sha>…] --json --out "$r1"
43
41
  ```
44
42
 
45
- `hotfix start` derives the PATCH from the latest Release tag on `origin/main`, branches `hotfix/vX.Y.Z` from `origin/main`, cherry-picks with `-x`, folds the version, pushes, and opens the main-base PR with its carries marker. Never duplicate those steps with raw branch, cherry-pick or PR commands.
46
-
47
- 2. Verify the main-base PR: the repo's local gate on the hotfix branch, the independent review the active agent doctrine requires, and the original issue's acceptance criteria. Then merge through Hub — it waits for required CI and demands the review verdict itself; the PR may squash, and the `-x` trailer must survive in the squash message:
48
-
49
- ```bash
50
- mmi-cli devops pr merge <number> --squash
51
- ```
52
-
53
- Because Hub's default branch is `development`, the main-base PR closes no tracking issue — the development PR already did; add no raw GitHub issue operations.
43
+ 2. Verify: local gate, required review, acceptance criteria. Merge with `mmi-cli devops pr merge <number> --squash` (waits for CI and review; keep the `-x` trailer). Because Hub's default branch is `development`, it closes no issue; no raw GitHub issue operations.
54
44
 
55
- 3. Release, naming every fix the cycle carries (each is proven an ancestor of the tagged SHA before tagging):
45
+ 3. Release:
56
46
 
57
47
  ```bash
58
- mkdir -p .jerv/tmp && r2=$(mktemp .jerv/tmp/hotfix-release.XXXXXX)
48
+ r2=$(mktemp .jerv/tmp/hotfix-release.XXXXXX)
59
49
  mmi-cli devops hotfix status --json
60
50
  mmi-cli devops hotfix release vX.Y.Z --carries <pr|sha>[,<pr|sha>…] --json --out "$r2"
61
51
  ```
62
52
 
63
- MMI-Hub adds `--announce-summary-file "$f"` with a fresh 3–6 line neutral summary — never a product or brand name; Hub scope is only `mutmutco/MMI-Hub`, never a product's board. `hotfix release` tags, publishes the Release, watches the release-triggered runs, announces once they are green (Hub), verifies distribution, and opens the `hotfix-fold/<tag>` development fold PR. Do not hand-dispatch a second publish or deploy path: duplicate release events race or double-publish.
53
+ MMI-Hub adds `--announce-summary-file "$f"`: a fresh 3–6 line neutral summary, no product or brand name, never a product's board (`mutmutco/MMI-Hub` only). It tags, publishes, watches, announces, verifies, opens the `hotfix-fold/<tag>` PR. Do not hand-dispatch a second publish or deploy.
64
54
 
65
55
  ## Verify
66
56
 
67
- Slack announcements use the GitHub-authenticated Hub service and its server-side MMI vault access.
68
- Developers need no local AWS tools, AWS identity, or shared Slack key. Preserve a failed summary
69
- for the supported continuation; never replay a delivery whose result is uncertain.
57
+ Read receipts, not the exit code (`1` = follow-up failed after tag; pending exits `0`):
70
58
 
71
- Read the receipts, never the exit code (exit `1` = a follow-up failed after the tag; a pending follow-up exits `0`, so a clean exit alone never means every leg resolved):
72
-
73
- - `runs[]` — the release-triggered runs on the tagged SHA (workflow, conclusion, url). Watch each non-success entry to conclusion: `gh run watch <run-id> --repo {owner}/{repo} --exit-status --interval 30`. Name which run is red: `deploy.yml` / `publish.yml` / `tenant-deploy.yml` / `jerv-gateway` is a deploy or publish verdict; a `gate` push run is ordinary CI sharing the SHA. `jerv-gateway` is the operator-host deploy leg: it has no run id to watch, so read its `deployNote` / `ledger.phases.deploy` — `pending` there means production was never deployed and blocks the next train run.
74
- - `foldStatus` + `foldNote` — the `hotfix-fold/<tag>` development PR; land it by true merge (Merge floor) and say whether it landed.
75
- - `announceNote` (Hub), `verifyNote`, `checkout`, `localSync`, `ledger` — the durable phase legs; a pending or failed leg is unresolved, never done.
76
- - `localInstall` (MMI-Hub) — the train installs the release on this machine via `mmi-hub update`; never run `npm i -g`.
77
-
78
- `mmi-cli devops hotfix status vX.Y.Z --json` re-derives the whole pipeline from live reads (`state`, `tagPushed`, `releaseExists`, `runs`, `alignmentStatus`, `npmVersion`, `next`). Then the bounded Latest Release read; its `tagName` must equal the tag:
79
-
80
- ```bash
81
- gh api repos/{owner}/{repo}/releases/latest --jq '{tagName:.tag_name,targetCommitish:.target_commitish,publishedAt:.published_at,url:.html_url}'
82
- ```
59
+ - `runs[]`: watch each non-success: `gh run watch <run-id> --repo {owner}/{repo} --exit-status --interval 30`. `deploy.yml`, `publish.yml`, `tenant-deploy.yml`, `jerv-gateway` are deploy/publish verdicts; a `gate` run is ordinary CI.
60
+ - `foldStatus`/`foldNote`: land the fold PR by true merge (Merge floor).
61
+ - `announceNote`, `verifyNote`, `checkout`, `localSync`, `ledger`: pending or failed = unresolved.
62
+ - `localInstall` (MMI-Hub): via `mmi-hub update`, never `npm i -g`.
83
63
 
84
- Branch facts close the verdict: the tag commit is on `origin/main`; `development` already had the fix before the hotfix began; `rc` is untouched by design; the fold PR landed or is named as pending.
64
+ `gh api repos/{owner}/{repo}/releases/latest --jq .tag_name` must equal the tag, on `origin/main`.
85
65
 
86
66
  ## Recovery
87
67
 
@@ -89,19 +69,19 @@ On any failure or interruption, read [recovery.md](recovery.md).
89
69
 
90
70
  ## Merge floor
91
71
 
92
- - **Never squash-merge a tagged commit (#3167).** A squash re-mints the SHA and orphans the tag from the branch lineage, so every tag-anchored check mis-reads forever after. Any merge that carries an already-tagged commit — the `main → development` roll-forward, an alignment PR, a hotfix fold PR — lands as a true merge: `mmi-cli devops pr merge <number> --auto --merge` (or `--wait --merge`); `--wait` alone still squashes. The hotfix main-base PR itself may squash: its tag lands after, on the merged `main` HEAD, and the `-x` trailer must survive the squash message.
72
+ - **Never squash-merge a tagged commit (#3167).** A squash re-mints the SHA and orphans the tag, so tag-anchored checks mis-read. Any merge that carries an already-tagged commit — the `main → development` roll-forward, an alignment PR, a hotfix fold PR — lands as a true merge: `mmi-cli devops pr merge <number> --auto --merge` (or `--wait --merge`); `--wait` alone still squashes. The hotfix main-base PR itself may squash: its tag lands after, on the merged `main` HEAD, and the `-x` trailer must survive the squash message.
93
73
  - **A refused train is a stop, never a license to finish by hand.** Every fail-closed halt — doctor blocker, authority probe, coverage guard, untolerated conflict, required checks, stray tag, ledger — ends the run. Fix the cause on `development` through a normal PR and rerun the train; never hand-resolve on `main`, hand-cherry-pick, bare-push a train branch, ack to save time, or bypass a check.
94
74
  - **Version probes anchor on the latest Release tag, not a branch (#2734).** A branch manifest or a stale local tag is not a version source; a surviving local tag silently mints the next version.
95
75
  - **One train at a time on a repo (#5380).** Two overlapping runs race the shared tag namespace; the ledger refuses the second — never start one to help the first.
96
- - **Tag and Release deletion are deletion-class:** the authorized human's explicit per-turn go, named in the guide entry that prescribes it.
76
+ - **Tag and Release deletion need Jervaise's yes (principle 12),** named in the guide entry that prescribes it.
97
77
 
98
78
  ## Report
99
79
 
100
- Title first, verdict first. Name the resolved tag (never a placeholder like `vX.Y.0`) and the Release URL, the receipt's status fields (`releaseStatus`, `followUpStatus`, `deployStatus`, `promoted`), and every workflow run row with its conclusion and evidence — use its URL when emitted, otherwise the receipt's explicit no-run-URL note — saying which run is red, and whether it is a deploy/publish verdict or ordinary CI — `announceNote`, the alignment note (`devRollForward`, `rcAlignment`, or the hotfix fold PR and whether it landed), the `checkout` clause, and the sanctioned dispatch mechanism you used. A pending follow-up is reported as unverified, never as success. Product names appear only when releasing that product's repo.
80
+ Verdict first: the resolved tag (never a placeholder like `vX.Y.0`), Release URL, `releaseStatus`, `followUpStatus`, `deployStatus`, `promoted`, each run's conclusion and URL (or the no-run-URL note), which run is red (deploy/publish verdict or ordinary CI), `announceNote`, the alignment note (`devRollForward`, `rcAlignment` or the fold PR), `checkout`, the dispatch used. Pending is unverified, never success. Product names only when releasing that product's repo.
101
81
 
102
82
  ## Retro
103
83
 
104
- Before the final report, answer one question honestly: did this skill's own instructions misfire this run — ambiguous wording, a misleading message, or an environment failure it should have warned about? Process only, never the user's code or task. If yes, file one lesson and move on; a clean run is silent (hard cap: one per run). It lands on the owning board, deduplicated, and is fixed only through a reviewed PR — never edit the skill live. The retro is advisory: if the call fails, note it and continue. File through MMI with the command below. The amendment itself stays reference-free: the skill-drift gate rejects issue references in any section outside Merge floor, so carry the evidence in words or point at the guide entry — never inline reference markers.
84
+ Before the final report: did this skill misfire? Process only. If yes, file one lesson (hard cap: one per run); a clean run is silent; if the call fails, note it and continue. Lessons are deduplicated on the owning board and change the skill only by reviewed PR, never live; no issue references outside Merge floor.
105
85
 
106
86
  ```bash
107
87
  mmi-cli learning skill-lesson --skill hotfix --title "<what misfired>" --body "<what; evidence; proposed amendment>"
@@ -2,3 +2,13 @@ Every refusal and every doctor blocker names its `code` and `anchor`: open `docs
2
2
 
3
3
  A prior release's unresolved ledger also blocks this lane — and when its only unresolved leg is a content-caused failed deploy on the already-published tag, this lane is the fix's carrier: close that leg first with the master-approved `mmi-cli devops release --supersede-deploy --apply` (the cause fix must already be merged on `development`), then run the hotfix; the gate archives the closed ledger aside on its own.
4
4
 
5
+
6
+ The `jerv-gateway` release leg has no run id: read `deployNote` / `ledger.phases.deploy`; `pending` means production was never deployed and blocks the next train run. Keep a failed announce summary for the supported continuation; never replay a delivery whose result is uncertain.
7
+
8
+ ## Field reference (moved from SKILL.md)
9
+
10
+ A hotfix always skips rc on every track: it cherry-picks `development → main` directly, MMI-Hub included. `deployModel` decides the release-triggered runs the train watches; on `vercel` nothing is dispatched — Vercel builds `main` on the push and the hotfix waits for its Production Deployment and probes the URL, same as `/release --watch`; a leg left pending settles on the next doctor `--heal`. Unreadable META → stop; never infer the lane from branch names, tags or release history.
11
+
12
+ The JSON is on stdout alone; a stale CLI first prints its self-update notice on stderr and re-runs itself, so parse stdout only, never `2>&1`. Read `ready`, then `findings[]`: each carries `code`, `severity` (`blocker` · `warning` · `healed` · `info`), `source` (`local` · `origin`), `remedy` and `anchor`. `ready: false` → stop and quote every blocker's `code` and `remedy`; an unread origin is never green. `hotfix start` and `hotfix release` re-run this doctor as their step 0 with heal on.
13
+
14
+ `mmi-cli devops hotfix status vX.Y.Z --json` re-derives the whole pipeline from live reads (`state`, `tagPushed`, `releaseExists`, `runs`, `alignmentStatus`, `npmVersion`, `next`). Then the bounded Latest Release read; its `tagName` must equal the tag:
@@ -3,27 +3,23 @@ name: rcand
3
3
  description: Promote development to a release candidate.
4
4
  ---
5
5
 
6
- **Host-native invocation:** Claude `/mmi:rcand` · Codex `$mmi:rcand` · jervcode `/rcand` · Hermes skill_view. A backticked `/name` in this doc names the matching workflow (this skill or a sibling), not a literal command.
6
+ **Host-native invocation:** Claude `/mmi:rcand` · Codex `$mmi:rcand` · jervcode `/rcand` · Hermes skill_view.
7
7
 
8
- **Argument:** `/rcand minor`, `/rcand major`, or `/rcand patch` — a bare bump word, never a `--flag` or env var. No argument → `patch`; declare `minor` or `major` for a planned feature cycle.
8
+ **Argument:** `/rcand minor|major|patch` — a bare bump word, never a flag or env var; none → `patch`.
9
9
 
10
10
  # /rcand — promote development to release-candidate
11
11
 
12
- Merge `development → rc`, tag `vX.Y.0-rc.N`, push the tag first, wait for the required checks, push the protected `rc` (the GitHub authority gate), then start the rc deploy. `rc` is a deploy stage, not a lane, and it is ephemeral: `/rcand` creates its runtime, `/release` ships exactly what is on `rc` and retires it. Train-authority gated: the repo's project-admin or the master. The board needs no touch: items reached `Done` when their PRs merged to `development`.
12
+ Merge `development → rc`, tag `vX.Y.0-rc.N`, push the tag, wait for required checks, push the protected `rc`, start the rc deploy. `rc` is ephemeral: `/release` ships exactly what is on it and retires it. Needs train authority (project-admin or master). The board needs no touch.
13
13
 
14
14
  ## Lane
15
15
 
16
- For an MM-Work suite lead or member, read [suite.md](suite.md) before choosing a lane.
17
-
18
- Read META and name the lane before describing or executing anything:
16
+ MM-Work suite lead or member: read [suite.md](suite.md) first. Name the lane from META:
19
17
 
20
18
  ```bash
21
19
  mmi-cli oracle org project get {owner}/{repo} --json
22
20
  ```
23
21
 
24
- `releaseTrack: direct` (product repos with explicit META, plus MMI-Hub) has no `rc`: stop here and run `/release` from `development`; `rcand --apply` refuses direct-track at its own preflight. Full-track runs from `development`, and a full-track repo may skip rc entirely with `/release --dev`. A full-track `deployModel: vercel` repo runs rcand as usual; the train dispatches nothing and, with `--watch`, waits for the non-Production Deployment Vercel builds for the rc push, then probes its URL. Unreadable META → stop; never infer the lane from branch names, a stale `rc` ref, or release history.
25
-
26
- Authority is structural and server-checked: the doctor asks the Hub, and the protected `rc` push allowlist carries the same people (master + that repo's project-admins). Gate ordering: the tag lands the rc SHA for checks, and every deploy side-effect waits until the protected `rc` push accepts that checked SHA.
22
+ `releaseTrack: direct` (product repos with explicit META, plus MMI-Hub) has no `rc`: run `/release` from `development`. Full-track may skip rc with `/release --dev`. On `deployModel: vercel` nothing is dispatched; `--watch` waits for the non-Production Vercel deployment, then probes its URL. Unreadable META → stop; never infer the lane.
27
23
 
28
24
  ## Preflight
29
25
 
@@ -31,31 +27,29 @@ Authority is structural and server-checked: the doctor asks the Hub, and the pro
31
27
  mmi-cli devops train doctor --lane rcand --heal --json
32
28
  ```
33
29
 
34
- The JSON is on stdout alone; a stale CLI first prints its self-update notice on stderr and re-runs itself, so parse stdout only, never `2>&1`. Read `ready`, then `findings[]`: each carries `code`, `severity` (`blocker` · `warning` · `healed` · `info`), `source` (`local` · `origin`), `remedy` and `anchor`. `ready: false` → stop and quote every blocker's `code` and `remedy`; an unread origin is never green. `--apply` re-runs this doctor as its step 0 with heal on.
30
+ Parse stdout only (never `2>&1`). `ready` false → stop and quote every blocker's `code` and `remedy`; an unread origin is never green. Findings carry `code`, `severity`, `source`, `remedy`, `anchor`. `--apply` re-runs the doctor.
35
31
 
36
32
  ## Apply
37
33
 
38
- Run from the primary checkout on `development`. Export the bump intent once from the bare argument — `MMI_BUMP_INTENT=minor|major|patch`, unset → `patch` — and keep it exported through the following `/release`; `MMI_RELEASE_VERSION=X.Y.Z` opens an exact cycle for both `/rcand` and `/release` only when the tag math cannot derive it.
34
+ From the primary checkout on `development`, export `MMI_BUMP_INTENT=minor|major|patch` once and keep it through the following `/release`; `MMI_RELEASE_VERSION=X.Y.Z` only when tag math cannot derive it.
39
35
 
40
36
  ```bash
41
37
  mkdir -p .jerv/tmp && r=$(mktemp .jerv/tmp/rcand-receipt.XXXXXX)
42
38
  mmi-cli devops rcand --apply --json --out "$r"
43
39
  ```
44
40
 
45
- Add `--watch` to block on the rc deploy; without it the deploy runs while you report and its verdict is
46
- collected in Verify — verification is never skipped, only un-blocked. The one command fetches, merges `development → rc` (version-manifest conflicts resolve to the `development` side; any other conflicted path refuses), tags the next `-rc.N` (re-run-safe), pushes the tag first, discovers and waits for the required contexts on `rc`, pushes `rc`, and starts the deploy by model — `tenant-deploy.yml` centrally (keyless) for tenant-container; nothing for serverless, registry-publish or solo-container, whose own push-triggered workflow deploys. Never `git push` rc by hand, never force, never commit to `rc` outside that merge.
41
+ `--watch` blocks on the deploy. Version-manifest merge conflicts take `development` (any other refuses); the `-rc.N` tag is re-run-safe. Deploy by model: `tenant-deploy.yml` for tenant-container; serverless, registry-publish and solo-container deploy via their push-triggered workflow. Never push, force or commit to `rc` by hand.
47
42
 
48
43
  ## Verify
49
44
 
50
- Read the receipt at `$r`, never the exit code (exit `1` = the deploy failed after promotion; an unresolved deploy exits `0`, so a clean exit alone never means every leg resolved):
45
+ Read the receipt at `$r`, never the exit code (`1` = deploy failed after promotion; unresolved exits `0`):
51
46
 
52
- - `promoted` — `true` even when the deploy failed; promotion and deploy are separate outcomes.
53
- - `tag` — the minted `vX.Y.0-rc.N`; `resumeNote` says an existing rc tag was resumed rather than minted.
54
- - `deployStatus` — `pending` is never terminal. `runId` / `runUrl` / `workflowRuns` name the run: the dispatched `tenant-deploy.yml` for tenant-container, the auto-fired `deploy.yml` for serverless. Watch each non-success entry to conclusion: `gh run watch <run-id> --repo {owner}/{repo} --exit-status --interval 30`.
55
- - `releaseVerdict` — `followUpStatus` (`complete` · `pending` · `failed`) and one `legs` row per follow-up; a failed row carries its error.
56
- - `checkout`, `localSync`, `ledger` — `checkout.status: returned` to `development` and phases-green, or the named reason it is not.
47
+ - `promoted` is `true` even when the deploy failed; `tag` is the minted `vX.Y.0-rc.N` (`resumeNote`: resumed).
48
+ - `deployStatus`: `pending` is never terminal. Watch each non-success run in `workflowRuns`: `gh run watch <run-id> --repo {owner}/{repo} --exit-status --interval 30`.
49
+ - `releaseVerdict`: `followUpStatus` (`complete` · `pending` · `failed`); a failed `legs` row carries its error.
50
+ - `checkout.status: returned` to `development` and `localSync`/`ledger` green, or the named reason.
57
51
 
58
- Then confirm origin: `git rev-list --count origin/rc..origin/development` is `0` and the rc tag is on origin. There is no GitHub Release at rc; the bounded Latest read belongs to `/release`. A red deploy after a green promotion is a deploy retry of the same candidate, never a re-tag or re-merge (Recovery).
52
+ Then confirm `git rev-list --count origin/rc..origin/development` is `0` and the rc tag is on origin (no GitHub Release at rc). A red deploy after green promotion is a deploy retry, never a re-tag or re-merge.
59
53
 
60
54
  ## Recovery
61
55
 
@@ -63,19 +57,19 @@ On any failure or interruption, read [recovery.md](recovery.md).
63
57
 
64
58
  ## Merge floor
65
59
 
66
- - **Never squash-merge a tagged commit (#3167).** A squash re-mints the SHA and orphans the tag from the branch lineage, so every tag-anchored check mis-reads forever after. Any merge that carries an already-tagged commit — the `main → development` roll-forward, an alignment PR, a hotfix fold PR — lands as a true merge: `mmi-cli devops pr merge <number> --auto --merge` (or `--wait --merge`); `--wait` alone still squashes. The hotfix main-base PR itself may squash: its tag lands after, on the merged `main` HEAD, and the `-x` trailer must survive the squash message.
60
+ - **Never squash-merge a tagged commit (#3167).** A squash re-mints the SHA and orphans the tag, so tag-anchored checks mis-read. Any merge that carries an already-tagged commit — the `main → development` roll-forward, an alignment PR, a hotfix fold PR — lands as a true merge: `mmi-cli devops pr merge <number> --auto --merge` (or `--wait --merge`); `--wait` alone still squashes. The hotfix main-base PR itself may squash: its tag lands after, on the merged `main` HEAD, and the `-x` trailer must survive the squash message.
67
61
  - **A refused train is a stop, never a license to finish by hand.** Every fail-closed halt — doctor blocker, authority probe, coverage guard, untolerated conflict, required checks, stray tag, ledger — ends the run. Fix the cause on `development` through a normal PR and rerun the train; never hand-resolve on `main`, hand-cherry-pick, bare-push a train branch, ack to save time, or bypass a check.
68
62
  - **Version probes anchor on the latest Release tag, not a branch (#2734).** A branch manifest or a stale local tag is not a version source; a surviving local tag silently mints the next version.
69
63
  - **One train at a time on a repo (#5380).** Two overlapping runs race the shared tag namespace; the ledger refuses the second — never start one to help the first.
70
- - **Tag and Release deletion are deletion-class:** the authorized human's explicit per-turn go, named in the guide entry that prescribes it.
64
+ - **Tag and Release deletion need Jervaise's yes (principle 12),** named in the guide entry that prescribes it.
71
65
 
72
66
  ## Report
73
67
 
74
- Title first, verdict first. Name the resolved tag (never a placeholder like `vX.Y.0`) and the Release URL, the receipt's status fields (`releaseStatus`, `followUpStatus`, `deployStatus`, `promoted`), and every workflow run row with its conclusion and evidence — use its URL when emitted, otherwise the receipt's explicit no-run-URL note — saying which run is red, and whether it is a deploy/publish verdict or ordinary CI — `announceNote`, the alignment note (`devRollForward`, `rcAlignment`, or the hotfix fold PR and whether it landed), the `checkout` clause, and the sanctioned dispatch mechanism you used. A pending follow-up is reported as unverified, never as success. Product names appear only when releasing that product's repo.
68
+ Verdict first: the resolved tag (never a placeholder like `vX.Y.0`), Release URL, `releaseStatus`, `followUpStatus`, `deployStatus`, `promoted`, each run's conclusion and URL (or the no-run-URL note), which run is red (deploy/publish verdict or ordinary CI), `announceNote`, the alignment note (`devRollForward`, `rcAlignment` or the fold PR), `checkout`, the dispatch used. Pending is unverified, never success. Product names only when releasing that product's repo.
75
69
 
76
70
  ## Retro
77
71
 
78
- Before the final report, answer one question honestly: did this skill's own instructions misfire this run — ambiguous wording, a misleading message, or an environment failure it should have warned about? Process only, never the user's code or task. If yes, file one lesson and move on; a clean run is silent (hard cap: one per run). It lands on the owning board, deduplicated, and is fixed only through a reviewed PR — never edit the skill live. The retro is advisory: if the call fails, note it and continue. File through MMI with the command below. The amendment itself stays reference-free: the skill-drift gate rejects issue references in any section outside Merge floor, so carry the evidence in words or point at the guide entry — never inline reference markers.
72
+ Before the final report: did this skill misfire? Process only. If yes, file one lesson (hard cap: one per run); a clean run is silent; if the call fails, note it and continue. Lessons are deduplicated on the owning board and change the skill only by reviewed PR, never live; no issue references outside Merge floor.
79
73
 
80
74
  ```bash
81
75
  mmi-cli learning skill-lesson --skill rcand --title "<what misfired>" --body "<what; evidence; proposed amendment>"
@@ -1,2 +1,10 @@
1
1
  Every refusal and every doctor blocker names its `code` and `anchor`: open `docs/Guides/train-troubleshooting.md#<code>` and follow that entry, nothing else. That guide is test-parsed, never free text — the infra drift and plugin-set suites validate every anchor cited here and assert policy from its wording — so an edit to it re-runs the infra suite (`npm --prefix infra test`) in the same PR: a heading or slug change is a code change. A candidate whose immutable rc tag passed policy but whose `origin/rc` was not pushed continues with `mmi-cli devops rcand --resume --watch --json --out <fresh-receipt>` — the only continuation form: `--resume` never re-tags, and `--apply` mints the next `-rc.N` for a new cut only. A promoted candidate whose rc deploy failed retries it, once the cause is fixed, with `mmi-cli devops rcand --retry-deploy --watch --json --out <fresh-receipt>` — same tag and SHA, never re-cut or re-pushed; `--resume` only re-reads that failed leg. Supersede is the last resort, with the authorized human's fresh approval. A refused train is a stop (Merge floor): fix the cause on `development` through a normal PR, then rerun; a rejected protected push leaves the local tag for an authorized rerun, never a force.
2
2
 
3
+
4
+ ## Field reference (moved from SKILL.md)
5
+
6
+ **Argument:** `/rcand minor`, `/rcand major`, or `/rcand patch` — a bare bump word, never a `--flag` or env var. No argument → `patch`; declare `minor` or `major` for a planned feature cycle.
7
+
8
+ The JSON is on stdout alone; a stale CLI first prints its self-update notice on stderr and re-runs itself, so parse stdout only, never `2>&1`. Read `ready`, then `findings[]`: each carries `code`, `severity` (`blocker` · `warning` · `healed` · `info`), `source` (`local` · `origin`), `remedy` and `anchor`. `ready: false` → stop and quote every blocker's `code` and `remedy`; an unread origin is never green. `--apply` re-runs this doctor as its step 0 with heal on.
9
+
10
+ - `deployStatus` — `pending` is never terminal. `runId` / `runUrl` / `workflowRuns` name the run: the dispatched `tenant-deploy.yml` for tenant-container, the auto-fired `deploy.yml` for serverless. Watch each non-success entry to conclusion: `gh run watch <run-id> --repo {owner}/{repo} --exit-status --interval 30`.