@mutmutco/claude-plugin 4.6.41 → 4.6.43

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mmi",
3
3
  "displayName": "MMI",
4
- "version": "4.6.41",
4
+ "version": "4.6.43",
5
5
  "mmiCompat": "4.x",
6
6
  "description": "MMI workflow skills and org gates delivery.",
7
7
  "author": {
package/cli/dist/main.cjs CHANGED
@@ -25273,6 +25273,31 @@ function missingPlaceholders(rendered) {
25273
25273
  for (const m of rendered.matchAll(PLACEHOLDER_RE)) out.add(m[1]);
25274
25274
  return [...out];
25275
25275
  }
25276
+ function seedMatchesReleaseTrack(seed, releaseTrack) {
25277
+ if (!seed.releaseTracks?.length) return true;
25278
+ return releaseTrack != null && seed.releaseTracks.includes(releaseTrack);
25279
+ }
25280
+ var TRAIN_ONLY_BEGIN = "mmi-train-only:start";
25281
+ var TRAIN_ONLY_END = "mmi-train-only:end";
25282
+ function renderSelfSeedForTrack(content, releaseTrack) {
25283
+ if (releaseTrack !== "single") return content;
25284
+ const lines2 = content.split(/(?<=\n)/);
25285
+ const out = [];
25286
+ let skipping = false;
25287
+ for (const line of lines2) {
25288
+ if (!skipping && line.includes(TRAIN_ONLY_BEGIN)) {
25289
+ skipping = true;
25290
+ continue;
25291
+ }
25292
+ if (skipping) {
25293
+ if (line.includes(TRAIN_ONLY_END)) skipping = false;
25294
+ continue;
25295
+ }
25296
+ out.push(line);
25297
+ }
25298
+ if (skipping) throw new Error(`unterminated ${TRAIN_ONLY_BEGIN} region`);
25299
+ return out.join("");
25300
+ }
25276
25301
  function isPropagatableSeed(seed) {
25277
25302
  return seed.ownership === "org" && seed.source === "self" || seed.managedBlock != null;
25278
25303
  }
@@ -26639,6 +26664,7 @@ function withDerivedRepoVars(vars, parsed, cls, releaseTrack, requiredCheckBranc
26639
26664
  out.CLASS ??= cls;
26640
26665
  out.PROJECT_OWNER ??= parsed.owner;
26641
26666
  const track = releaseTrack ?? resolveBootstrapReleaseTrack(cls);
26667
+ out.RELEASE_TRACK ??= track;
26642
26668
  const runtime = out.GATE_RUNTIME === "python" ? "python" : "node";
26643
26669
  for (const [key, value] of Object.entries(gateSeedVars(cls, track, runtime, requiredCheckBranches, requiredChecks))) {
26644
26670
  out[key] ??= value;
@@ -26998,7 +27024,10 @@ function renderBootstrapAncillaryPlan(labels, environments, exceptions = []) {
26998
27024
  ].join("\n");
26999
27025
  }
27000
27026
  function resolveSeedContent(seed, vars, readFile11) {
27001
- if (seed.source === "self") return readFile11(seed.target);
27027
+ if (seed.source === "self") {
27028
+ const own = readFile11(seed.target);
27029
+ return own == null ? null : renderSelfSeedForTrack(own, vars.RELEASE_TRACK);
27030
+ }
27002
27031
  if (seed.source.startsWith("seed:")) {
27003
27032
  const tmpl = readFile11(`skills/bootstrap/seeds/${seed.source.slice("seed:".length)}`);
27004
27033
  return tmpl == null ? null : renderSeed(tmpl, vars);
@@ -28527,10 +28556,10 @@ var rollout_plan_default = {
28527
28556
  note: "The v4.0.0 stamp happens at cut time (D6e #4463); until then the candidate is the origin/development head artifacts (built cli/dist + npm pack), identity proven by dist content hash (D6a)."
28528
28557
  },
28529
28558
  baseline: {
28530
- version: "4.6.41",
28531
- tag: "v4.6.41",
28532
- commit: "2cf5b22abb64",
28533
- npm: "@mutmutco/cli@4.6.41"
28559
+ version: "4.6.43",
28560
+ tag: "v4.6.43",
28561
+ commit: "856f4651277d",
28562
+ npm: "@mutmutco/cli@4.6.43"
28534
28563
  },
28535
28564
  exitCriterion: "fleet-n-of-n",
28536
28565
  hubOnlyShortcut: "forbidden",
@@ -28547,14 +28576,14 @@ var rollout_plan_default = {
28547
28576
  repo: "mutmutco/mmi-hub",
28548
28577
  role: "canary",
28549
28578
  schedule: "train",
28550
- v3Target: "v4.6.41"
28579
+ v3Target: "v4.6.43"
28551
28580
  }
28552
28581
  ],
28553
28582
  rollbackTrigger: "Any red inside the post-contract soak window: `devops train gate` FAIL attributable to the v4 doors, Hub endpoint health probe failure, a pre-v4 client admitted instead of receiving actionable HTTP 426, or npm consumer install/doctor failure on the v4-only dist.",
28554
28583
  rollback: {
28555
28584
  independent: true,
28556
- mechanism: "npm dist-tag latest -> 4.6.41 and redeploy the Hub Lambda from tag v4.6.41 (2cf5b22abb64); installed clients repair via `mmi-cli doctor`. No other cohort is touched.",
28557
- v3Target: "v4.6.41 (@mutmutco/cli@4.6.41, tag commit 2cf5b22abb64 \u2014 last known-good release carrying the repo-index v4-only contract)"
28585
+ mechanism: "npm dist-tag latest -> 4.6.43 and redeploy the Hub Lambda from tag v4.6.43 (856f4651277d); installed clients repair via `mmi-cli doctor`. No other cohort is touched.",
28586
+ v3Target: "v4.6.43 (@mutmutco/cli@4.6.43, tag commit 856f4651277d \u2014 last known-good release carrying the repo-index v4-only contract)"
28558
28587
  }
28559
28588
  },
28560
28589
  {
@@ -31670,17 +31699,17 @@ function isBundleOnlySuiteMember(repo, suite) {
31670
31699
  if (!suite) return false;
31671
31700
  return repo.split("/")[1]?.toLowerCase() !== suite.toLowerCase();
31672
31701
  }
31702
+ var MM_GOES_LIVE = "MM-Work and its modules merge to development and it goes live; there is no release, rc or candidate stage.";
31673
31703
  function suiteMemberRefusal(repo, meta, lane, solo = false, cut) {
31674
31704
  const suite = meta?.suite;
31675
31705
  if (!suite) return null;
31676
31706
  if (!isBundleOnlySuiteMember(repo, suite)) {
31677
31707
  if (solo || cut?.token === SUITE_LEAD_TOKEN && cut.repo.toLowerCase() === repo.toLowerCase()) return null;
31678
- const route = lane === "hotfix" ? "hotfix the affected member from its own checkout, then run mmi-cli devops suite release --owner-go" : `run mmi-cli devops suite ${lane} --owner-go`;
31679
- return `${repo} is the ${suite} suite lead; a plain ${lane} would cut it without its members: ${route}. A lead-only ${lane} needs --suite-solo --owner-go.`;
31708
+ return `${repo} is the ${suite} suite lead; ${MM_GOES_LIVE} There is no ${lane} to run: land the change through a normal PR to development and state what landed.`;
31680
31709
  }
31681
31710
  if (authorisedSuiteCut(repo, meta, cut)) return null;
31682
31711
  if (lane !== "rcand" && solo) return null;
31683
- return `${repo} is part of the ${suite} suite; the cut comes from the suite lead ${suiteLeadRepo(repo, suite)}. A suite member never asks for, proposes or prompts an rc, release or hotfix: the suite orchestrator is the only voice that brings a cut to Jervaise, so state what landed and stop. --owner-go and --suite-solo are never self-authorized; only a backward-compatible solo backend release/hotfix with actual owner approval may pass --suite-solo --owner-go.`;
31712
+ return `${repo} is part of the ${suite} suite; ${MM_GOES_LIVE} A suite member never asks for, proposes or prompts an rc, release or hotfix: there is none, so state what landed and stop.`;
31684
31713
  }
31685
31714
 
31686
31715
  // src/tenant-control-parse.ts
@@ -51008,7 +51037,7 @@ async function verifyBootstrap(repo, repoClass, deps, releaseTrack) {
51008
51037
  detail: `expected: ${requiredProductRulesetRef} (apply as an active repo ruleset after bootstrap)`
51009
51038
  });
51010
51039
  }
51011
- if (repoClass === "deployable") {
51040
+ if (repoClass === "deployable" && effectiveTrack !== "single") {
51012
51041
  const trainScript = "scripts/next-version.mjs";
51013
51042
  checks.push({ ok: await contentExists2(deps, repo, baseBranch, trainScript), label: `train tooling script exists: ${trainScript}` });
51014
51043
  }
@@ -51734,7 +51763,9 @@ function registerBootstrapCommands(program3) {
51734
51763
  for (const repo of targets) {
51735
51764
  const cls = classOf(repo);
51736
51765
  const meta = metaOf(repo);
51737
- const seeds = byteComparableSeeds(manifest, cls);
51766
+ const track = resolveReleaseTrack(metaWithDeclaredClass(meta, cls), void 0, repo);
51767
+ const seeds = byteComparableSeeds(manifest, cls).filter((s) => seedMatchesReleaseTrack(s, track));
51768
+ const trackHubContents = new Map([...hubContents].map(([t, c]) => [t, c == null ? c : renderSelfSeedForTrack(c, track)]));
51738
51769
  seedsPerRepo = Math.max(seedsPerRepo, seeds.length);
51739
51770
  const baseBranch = cls === "content" ? "main" : "development";
51740
51771
  const reads = [];
@@ -51749,9 +51780,8 @@ function registerBootstrapCommands(program3) {
51749
51780
  }
51750
51781
  reads.push({ target: seed.target, content });
51751
51782
  }
51752
- findings.push(...auditRepoSeedDrift(repo, seeds, hubContents, reads));
51783
+ findings.push(...auditRepoSeedDrift(repo, seeds, trackHubContents, reads));
51753
51784
  findings.push(...declaredRenderWaivers(manifest, repo));
51754
- const track = resolveReleaseTrack(metaWithDeclaredClass(meta, cls), void 0, repo);
51755
51785
  const github = await readBootstrapGitHubFacts(repo, track, controlClient);
51756
51786
  const deployFacts = await fetchDeployFactsBySlug((repo.split("/").pop() ?? repo).toLowerCase(), registryClientDeps(await loadConfig()));
51757
51787
  const controlRows = planBootstrapControlPlane({
@@ -52176,6 +52206,7 @@ function registerBootstrapCommands(program3) {
52176
52206
  if (!seed.classes.includes(o.class)) continue;
52177
52207
  if (!seedMatchesDeployModel(seed, applyDeployModel)) continue;
52178
52208
  if (!seedMatchesProjectType(seed, applyProjectType)) continue;
52209
+ if (!seedMatchesReleaseTrack(seed, vars.RELEASE_TRACK)) continue;
52179
52210
  const waiver = seed.waivers?.[slug];
52180
52211
  if (waiver) {
52181
52212
  actions.push({ action: "skip", target: seed.target, ownership: seed.ownership, reason: `waived: ${waiver}` });
@@ -52670,7 +52701,12 @@ LIVE apply to ${repo}:
52670
52701
  const readSeedFile2 = (path2) => (0, import_node_fs40.existsSync)(path2) ? (0, import_node_fs40.readFileSync)(path2, "utf8") : null;
52671
52702
  const isWorkflowSeed = seed.target.startsWith(".github/workflows/");
52672
52703
  const { projects, classOf, inClassRepos, canarySlug, sourcePilot } = await propagationScope(seed.classes, `target '${seed.target}'`);
52673
- const repos = inClassRepos.map((repo) => {
52704
+ const trackOf = (repo) => resolveReleaseTrack(
52705
+ projects.find((p) => (p.repos ?? []).some((r) => r.toLowerCase() === repo.toLowerCase())),
52706
+ void 0,
52707
+ repo
52708
+ );
52709
+ const repos = inClassRepos.filter((repo) => seedMatchesReleaseTrack(seed, trackOf(repo))).map((repo) => {
52674
52710
  const slug = repo.split("/").pop().toLowerCase();
52675
52711
  const waiver = seed.waivers?.[slug];
52676
52712
  return { repo, slug, waiver };
@@ -52718,7 +52754,7 @@ LIVE apply to ${repo}:
52718
52754
  }
52719
52755
  desired = resolved.content;
52720
52756
  } else {
52721
- desired = hubContent;
52757
+ desired = renderSelfSeedForTrack(hubContent, trackOf(r.repo));
52722
52758
  }
52723
52759
  desiredByRepo.set(r.repo, desired);
52724
52760
  const drift = compareSeedBytes(desired, content);
@@ -59669,7 +59705,7 @@ function branchRulesReadHint(path2) {
59669
59705
  const match = new RegExp(`^repos/(${NAME})/(${NAME})/(?:rules/branches/[^/?#]+|branches/[^/?#]+/protection(?:/|$)|rulesets(?:/|$))`).exec(path2.split("?")[0]);
59670
59706
  if (!match) return "";
59671
59707
  const slug = `${match[1]}/${match[2]}`;
59672
- return ` No raw rules, rulesets or branch-protection read is on the App allowlist, so retrying path or query variants cannot work \u2014 inspect a PR's required status contexts with \`MMI_ACTOR=app mmi-cli devops pr checks-required <pr> --repo ${slug} --json\`, or verify repository ruleset and branch-protection health with \`mmi-cli devops bootstrap verify --repo ${slug} --json\` and \`mmi-cli devops ci audit --repo ${slug} --json\`.`;
59708
+ return ` No raw rules, rulesets or branch-protection read is on the App allowlist, so retrying path or query variants cannot work \u2014 inspect a PR's required status contexts with \`MMI_ACTOR=app mmi-cli devops pr checks-required <pr> --repo ${slug} --json\`, or verify repository ruleset and branch-protection health with \`mmi-cli devops bootstrap verify --repo ${slug} --json\` and \`mmi-cli devops ci audit --repo ${slug} --json\`. Stepping around it with a raw \`gh api repos/${slug}/rulesets/<id> > file\` is not a substitute \u2014 when that read fails it leaves an EMPTY file, and a later require/JSON.parse throws 'Unexpected end of JSON input' that looks like corrupt data while the real refusal is only on stderr; check the exit code and file size, or ask a human token holder for the raw ruleset body.`;
59673
59709
  }
59674
59710
  function commitsReadHint(path2) {
59675
59711
  const clean4 = path2.split("?")[0];
@@ -61643,7 +61679,8 @@ async function observePrCreateClaims(body, repoOption, deps = {}) {
61643
61679
  continue;
61644
61680
  }
61645
61681
  const holder = contest.marker ? `lane ${describeClaimMarker(contest.marker)} (claim marker read from ${commentsPath}${posted})` : `an unreadable lane (its claim-marker comments could not be read${throttledPaths.has(commentsPath) ? " \u2014 GitHub rate-limited the read (HTTP 403) and the bounded reset-aware retry could not clear it" : ""}; the holder may be this very lane)`;
61646
- findings.push(`pr create: REFUSED \u2014 ${ref} is held by ${holder} with ${kinds} work evidence (${why}); run \`mmi-cli oracle board claim ${ref} --force\` (move it to In Progress first if it sits In Review) or drop the closing line before creating this PR; ${requester}`);
61682
+ const localLive = contest.marker && contest.live.some((l) => l.endsWith("has recent local transcript activity")) ? ` The holder ${describeClaimMarker(contest.marker)} is running on THIS host (marker ${Number.isFinite(postedMs) ? `${formatClaimAge(now() - postedMs)} old` : "age unknown"}), so --force would race it: if it is this lane's own earlier incarnation (same task, same branch this PR lands), reclaim with \`mmi-cli oracle board claim ${ref} --force\`; otherwise stop and leave ${ref} to it.` : "";
61683
+ findings.push(`pr create: REFUSED \u2014 ${ref} is held by ${holder} with ${kinds} work evidence (${why}); run \`mmi-cli oracle board claim ${ref} --force\` (move it to In Progress first if it sits In Review) or drop the closing line before creating this PR;${localLive} ${requester}`);
61647
61684
  }
61648
61685
  let attempted = false;
61649
61686
  return {
package/cli/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mutmutco/cli",
3
- "version": "4.6.41",
3
+ "version": "4.6.43",
4
4
  "description": "MMI Future CLI — the org dev toolbox and shared cross-IDE engine for every registry-declared MMI coding surface.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mutmutco/claude-plugin",
3
- "version": "4.6.41",
3
+ "version": "4.6.43",
4
4
  "description": "MMI workflow skills and org gates delivery.",
5
5
  "author": {
6
6
  "name": "MMI Future",
@@ -1,6 +1,7 @@
1
1
  name: gate
2
2
  # Org-standard green-before-merge gate for product repos (#1333). Runs on PRs, train-branch pushes,
3
- # and v* tags so /release and /hotfix can discover required contexts on the tagged SHA.
3
+ # and v* tags so /release and /hotfix can discover required contexts on the tagged SHA (repos with a
4
+ # release train only; MM-Work and its modules have none — they merge to development and it goes live).
4
5
  #
5
6
  # Runner (#9248, owner 29 Oct 2026): included GitHub-hosted capacity is FIRST CHOICE for CI — this gate
6
7
  # runs on `ubuntu-latest`, which costs included Enterprise minutes, not spend. Self-hosted lanes
@@ -196,7 +197,7 @@ jobs:
196
197
  - run: {{GATE_INSTALL_CMD}}
197
198
  if: ${{ steps.development-gate.outputs.reuse != 'true' }}{{GATE_JEV_FETCH_YAML}}{{GATE_CHECK_POLICY_STEP_YAML}}
198
199
  # #3178: the check runs under the org wall-clock budget — a hung suite dies at the ceiling instead
199
- # of squatting a runner lane for GitHub's 6h default. ci-audit + the release train enforce this step.
200
+ # of squatting a runner lane for GitHub's 6h default. ci-audit (and, on repos that have one, the release train) enforce this step.
200
201
  # #9293: PRs fail fast, merge_group and tags run everything. pytest reads PYTEST_ADDOPTS natively; a
201
202
  # Node check script opts in with MMI_FAIL_FAST (`vitest run ${MMI_FAIL_FAST:+--bail=1}`, or
202
203
  # `--fail-fast` on the org node runner). #9295: on PRs the Jev plan step exports JEV_PYTEST_ARGS
@@ -1,12 +1,12 @@
1
1
  {
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 legacy org-managed .gitignore block in place. managedBlock declares a separately sourced, exact-marker-bounded Hub-owned region inside a repo-owned containing file; apply/propagate reconcile only that region and refuse malformed markers. 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 legacy org-managed .gitignore block in place. managedBlock declares a separately sourced, exact-marker-bounded Hub-owned region inside a repo-owned containing file; apply/propagate reconcile only that region and refuse malformed markers. 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. releaseTracks (#10076): when set, only repos on those registry release tracks receive it; a 'self' seed's '# mmi-train-only:start' ... ':end' line regions are dropped for single-track repos.",
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", "GATE_RULESET_CONTEXTS_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"] },
6
6
  { "target": ".github/ISSUE_TEMPLATE/feature.yml", "source": "self", "ownership": "org", "classes": ["deployable", "content"] },
7
7
  { "target": ".github/ISSUE_TEMPLATE/task.yml", "source": "self", "ownership": "org", "classes": ["deployable", "content"] },
8
8
  { "target": ".github/ISSUE_TEMPLATE/config.yml", "source": "self", "ownership": "repo", "classes": ["deployable", "content"] },
9
- { "target": "scripts/next-version.mjs", "source": "self", "ownership": "org", "classes": ["deployable"] },
9
+ { "target": "scripts/next-version.mjs", "source": "self", "ownership": "org", "classes": ["deployable"], "releaseTracks": ["full", "direct", "trunk"] },
10
10
  { "target": ".github/workflows/gate.yml", "source": "seed:gate.template.yml", "ownership": "repo", "classes": ["deployable"], "waivers": { "mmi-katip": "gates through py-gate and web-gate (in-job path filters, #3836) and its registry requiredChecks name exactly those two; a generic Node gate.yml here is red noise on every PR and would be re-created by every apply (#6333)." } },
11
11
  { "target": ".github/workflows/agent-pr.yml", "source": "self", "ownership": "org", "classes": ["deployable"], "waivers": { "jerv-jervcode": "pins this workflow's EXACT step shapes in its own scripts/workflow-boundary-core.mjs — a literal repositories: Jerv-JervCode token scope, and whole-step equality for the surface and verdict legs. #4040 widened the org seed to the same hardened boundary (pull_request_target off the trusted base, an immutable BASE..HEAD compare with a file-count equality wall, a per-repo App token scope, and a certified-head merge), so the two now agree on substance. They cannot agree on bytes: a seed serving 16 repos resolves its token scope and its required contexts at run time, which exact-step equality rejects by construction. The waiver is permanent by design, not a deferral — lifting it would mean weakening the strictest repo to match a fleet file." } },
12
12
  { "target": ".github/rulesets/mmi-product-required-checks.json", "source": "seed:mmi-product-required-checks.template.json", "ownership": "org", "classes": ["deployable"] },
@@ -4,5 +4,5 @@
4
4
  Use the [canonical MMI developer-environment guide](https://github.com/mutmutco/MMI-Hub/blob/main/docs/Architecture/agentic-dev-environment.md) for shared setup and daily agent work.
5
5
 
6
6
  Daily loop: `mmi-cli oracle issue create` → `mmi-cli oracle board claim <n>` (stamps the mmi-claim lease) → `mmi-cli devops pr create` → `mmi-cli devops pr land <pr>`.
7
- Any org member with repository write (developer) or repository admin (project admin) can run it, with no vault access; release trains stay org-owner only.
7
+ Any org member with repository write (developer) or repository admin (project admin) can run it, with no vault access; Hub release trains (repos that have one) stay org-owner only; MM-Work and its modules have none — merge and go live.
8
8
  <!-- mmi-developer-environment:end -->
@@ -1,14 +1,14 @@
1
1
  {
2
2
  ".github/workflows/agent-pr.yml": {
3
- "blob": "e85a80c65b26531a330917fb4b5d8f563a0f0d0c",
4
- "reason": "sole-write-path guard reads retry transient GitHub API 5xx/429/transport failures up to 3 attempts, then fail closed with the same messages (#9911); permissions, refs, guarded paths and operator responsibilities unchanged"
3
+ "blob": "a99d0be49e66423dfbafb9db6273a6b841752972",
4
+ "reason": "train-only markers around the release-align replay and its comment, stripped for single-track repos (#10076); the #7717 note says it applies only on repos with a release train (#10071); guarded paths, permissions and operator responsibilities unchanged"
5
5
  },
6
6
  "scripts/next-version.mjs": {
7
- "blob": "2c1985b59edc779695479559074e7654c1574a11",
8
- "reason": "comment-only note that rc/release modes are unused in dev-only MM suite repos (#8282), no runtime or operator behaviour change"
7
+ "blob": "7faba0bb3ee48074702da48d149657820d74de1a",
8
+ "reason": "comment-only header: the train applies only to repos with a release lane; MM-Work and its modules merge to development and it goes live with no release, rc or candidate stage (#10071); no runtime or operator behaviour change"
9
9
  },
10
10
  "README.md": {
11
- "blob": "768c5e35cdb48849c77bce6b334658adefe6a5d8",
12
- "reason": "the developer-environment seed block now states the concrete mmi-cli loop (issue create, board claim, PR create, PR land) and who may run it — the README propagation is intended (#9987); no runbook step changes"
11
+ "blob": "46f5e07288931eee1c26362219b9d4271a5ed49e",
12
+ "reason": "the developer-environment seed block now says Hub release trains (repos that have one) stay org-owner only and MM-Work and its modules have none — merge and go live (#10071); no runbook step changes"
13
13
  }
14
14
  }
@@ -15,7 +15,7 @@ Pushing to `main` and production needs Jervaise's yes unless a standing authoriz
15
15
 
16
16
  ## Lane
17
17
 
18
- MM-Work suite seats: read [suite.md](suite.md). Lane from META:
18
+ MM-Work and its modules have no hotfix: a fix merges to development and it goes live ([suite.md](suite.md)). Every other repo, lane from META:
19
19
 
20
20
  ```bash
21
21
  mmi-cli oracle org project get {owner}/{repo} --json
@@ -1,2 +1 @@
1
- In the suite lead (MM-Work) a plain rcand, release or hotfix refuses: run `mmi-cli devops suite rcand --owner-go` or `mmi-cli devops suite release --owner-go` instead (a lead-only cut needs `--suite-solo --owner-go`). On your own, run only the read-only previews `mmi-cli devops suite rcand --dry-run` and `mmi-cli devops suite hotfix <member> --dry-run`; `suite release` and `suite abandon` have no dry-run, so never run them yourself. A real suite rcand, release, hotfix or abandon runs only on the owner's go, executed by the owner or the suite orchestrator. A suite member cannot run standalone rcand, release or hotfix: cut from the suite lead; only a backward-compatible solo backend release/hotfix with explicit owner approval may pass `--suite-solo --owner-go`, and its MM-Work development pin PR must land before the suite is in sync. A suite member never asks for, proposes or prompts an rc, release or hotfix — the suite orchestrator is the only voice that brings a cut to Jervaise, so a member session states what landed and stops instead of offering a cut.
2
-
1
+ MM-Work and its modules (MM-Account, MM-Chat, MM-Inspo, MM-Moments, MM-PM, MM-Strategy, MMI-Junior, MMI-Katip, MMI-Pulse, MMI-Scout, MM-Talent) merge to development and it goes live. No release, rc or candidate stage (owner ruling 2026-11-05): `development` is their only branch, and a merged change is live once its deploy is green. There is no suite rcand, suite release or suite hotfix for them and no `--suite-solo` path: never run `/release`, `/rcand` or `/hotfix` in these repos (the CLI refuses), and never tell the owner a landed change waits on a release. An urgent fix is a normal PR to development. A suite member never asks for, proposes or prompts an rc, release or hotfix — there is none; state what landed and stop.
@@ -27,8 +27,8 @@ mmi-cli devops pr land <pr-number>
27
27
 
28
28
  Board writes (attach, claim stamp, status move) gate on org owner, repo admin or repository write, so
29
29
  these roles pass. Where the GitHub App route is absent the writes go as the person's own GitHub login
30
- (one note says so); an agent host with the App route writes as the App. MMI-Hub's own merges and all
31
- release trains stay org-owner only.
30
+ (one note says so); an agent host with the App route writes as the App. MMI-Hub's own merges and the Hub
31
+ release trains (repos that have one) stay org-owner only; MM-Work and its modules have none: merge and go live.
32
32
 
33
33
  Start with `mmi-cli onboard` and the [board skill](../../board/SKILL.md).
34
34
  Reading or discussing the board is read-only until the developer authorizes work.
@@ -169,8 +169,9 @@ development. A trunk repository follows its single branch and declared workflow
169
169
  No box stage.
170
170
  - Trunk track: one main branch, without an rc/development promotion train. Follow the repository's
171
171
  declared publishing workflow rather than manufacturing train branches.
172
- - Single track (MM-Work and its modules): one environment. Every merge to development auto-deploys
173
- the `main` stage; there is no rc, dev stage or release train, and release, rcand and hotfix refuse.
172
+ - MM-Work and its modules (registry `releaseTrack: single`) are not on any of these trains: MM-Work and
173
+ its modules merge to development and it goes live. No release, rc or candidate stage; `development`
174
+ is their only branch, and release, rcand and hotfix refuse. The Hub's own release train never applies to them.
174
175
  - Urgent already-merged fixes: use [hotfix](../../hotfix/SKILL.md), which carries selected development
175
176
  fixes directly to main on either track.
176
177
 
@@ -199,7 +200,7 @@ refresh tags with `git fetch origin --tags --force` (or `git fetch origin '+refs
199
200
  never chain a plain tag fetch with `&&` ahead of a read-only `git log <tag>..origin/<branch>` range (#9517).
200
201
  A Hub summary never mentions a Jerv-side project; the train
201
202
  refuses such a line.
202
- Every new MM-Work suite Release, solo and hotfix included, requires `--announce-summary-file` and `--announce-summary-file-tr` in the bilingual update-notes template of the [MM-Work GUIDE, "Update notes"](https://github.com/mutmutco/MM-Work/blob/development/packages/mmwork-ds/GUIDE.md#update-notes) (`Fixed`/`Düzeldi`, then `New`/`Yeni`, with `<Area>: <sentence>.` lines; a Fixed line states what works now, never the problem). A suite release requires `--member-summary-file owner/repo=path` and `--member-summary-file-tr owner/repo=path` for every member it releases. A suite cut's `--owner-go` records the owner's explicit go for that one cut, never an agent's own decision: a held train or stale MM-Work cut goes to the suite orchestrator with the exact owner-gated commands. On its own an agent runs only `suite rcand --dry-run` and `suite hotfix <member> --dry-run`; it never runs `suite release` or `suite abandon`, which have no dry-run. Details: the release skill.
203
+ MM-Work and its modules never cut a release, so they write no release summary: MM-Work and its modules merge to development and it goes live. No release, rc or candidate stage, no suite cut and no `--suite-solo` path (owner ruling 2026-11-05). Details: the release skill's suite.md.
203
204
 
204
205
  Announcement delivery uses the developer's GitHub-authenticated Hub session. The Hub checks project
205
206
  authority, resolves the registered channel, and reads the MMI Future Slack key inside its vault boundary.
@@ -13,7 +13,7 @@ Merge `development → rc`, tag `vX.Y.0-rc.N`, push the tag, wait for required c
13
13
 
14
14
  ## Lane
15
15
 
16
- MM-Work suite lead or member: read [suite.md](suite.md) first. Name the lane from META:
16
+ MM-Work and its modules have no rcand: they merge to development and it goes live ([suite.md](suite.md)). Every other repo: Name the lane from META:
17
17
 
18
18
  ```bash
19
19
  mmi-cli oracle org project get {owner}/{repo} --json
@@ -1,4 +1 @@
1
- In the suite lead (MM-Work) a plain rcand, release or hotfix refuses: the suite path is `mmi-cli devops suite rcand --owner-go` or `mmi-cli devops suite release --owner-go` (a lead-only cut needs `--suite-solo --owner-go`). `--owner-go` records Jervaise's explicit go for that one cut; it is never the agent's own flag. Never pass it on your own authority: a held train or a stale MM-Work cut (`suite abandon --owner-go`, then `suite rcand --owner-go`) is handed to the suite orchestrator with that exact command sequence, and runs only after the owner says go. On your own, run only the read-only previews `mmi-cli devops suite rcand --dry-run` and `mmi-cli devops suite hotfix <member> --dry-run`; `suite release` and `suite abandon` have no dry-run, so never run them yourself. A real suite rcand, release, hotfix or abandon runs only on the owner's go, executed by the owner or the suite orchestrator. A suite member cannot run standalone rcand, release or hotfix: cut from the suite lead; only a backward-compatible solo backend release/hotfix with explicit owner approval may pass `--suite-solo --owner-go`, and its MM-Work development pin PR must land before the suite is in sync. A suite member never asks for, proposes or prompts an rc, release or hotfix — the suite orchestrator is the only voice that brings a cut to Jervaise, so a member session states what landed and stops instead of offering a cut.
2
-
3
- Support sessions (MMI-Hub, Jerv-Hub, Jerv-JervCode) are not suite members and hold standing owner authorization (2026-10-25) to cut and ship releases at their discretion during suite runs without repeated per-release approval, and under the owner's 2026-11-01 ruling each support session strives during a suite run to finish its own board and cut a patch release for landed-but-unreleased merges so suite members pick the update up in that run instead of waiting for a later cut, keeping all standard release preflight, gate, and verification checks.
4
-
1
+ MM-Work and its modules (MM-Account, MM-Chat, MM-Inspo, MM-Moments, MM-PM, MM-Strategy, MMI-Junior, MMI-Katip, MMI-Pulse, MMI-Scout, MM-Talent) merge to development and it goes live. No release, rc or candidate stage (owner ruling 2026-11-05): `development` is their only branch, and a merged change is live once its deploy is green. There is no suite rcand, suite release or suite hotfix for them and no `--suite-solo` path: never run `/release`, `/rcand` or `/hotfix` in these repos (the CLI refuses), and never tell the owner a landed change waits on a release. An urgent fix is a normal PR to development. A suite member never asks for, proposes or prompts an rc, release or hotfix — there is none; state what landed and stop.
@@ -11,7 +11,7 @@ Bare `minor|major|patch` (default `patch`), never a flag. A production release n
11
11
 
12
12
  ## Lane
13
13
 
14
- Read `mmi-cli oracle org project get {owner}/{repo} --json` and name the lane ([verification.md](verification.md) Lane rules); unreadable META → stop. On `releaseTrack: single` (MM-Work and its modules) or `trunk` there is no release lane. On single track a merge to development auto-deploys the `main` stage, and release, rcand and hotfix refuse. A merged single-track change is live once that deploy is green. A trunk repo follows its own declared publishing workflow. Never tell the owner a landed change waits on a release. [suite.md](suite.md) for suite cuts; [vercel.md](vercel.md) for Vercel.
14
+ Read `mmi-cli oracle org project get {owner}/{repo} --json` and name the lane ([verification.md](verification.md) Lane rules); unreadable META → stop. MM-Work and its modules merge to development and it goes live. No release, rc or candidate stage: release, rcand and hotfix refuse there, and a merged change is live once its deploy is green ([suite.md](suite.md)). A `trunk` repo has no release lane either and follows its own declared publishing workflow. Never tell the owner a landed change waits on a release. [vercel.md](vercel.md) for Vercel.
15
15
 
16
16
  ## Preflight
17
17
 
@@ -1,9 +1,5 @@
1
- MM-Work and most of its modules are `releaseTrack: single` ([work-and-releases.md](../org-guide/references/work-and-releases.md)). A merge to development auto-deploys their `main` stage, so a landed change is live once that deploy is green. Never tell the owner such a change waits on a release. Read each repo's `releaseTrack` with `mmi-cli oracle org project get <owner/repo> --json` before naming any cut. A suite cut also cuts the MM-Work lead's rcand, which refuses while MM-Work is single track.
1
+ MM-Work and its modules (MM-Account, MM-Chat, MM-Inspo, MM-Moments, MM-PM, MM-Strategy, MMI-Junior, MMI-Katip, MMI-Pulse, MMI-Scout, MM-Talent) merge to development and it goes live. No release, rc or candidate stage (owner ruling 2026-11-05): `development` is their only branch, and a merged change is live once its deploy is green. There is no suite rcand, suite release or suite hotfix for them and no `--suite-solo` path: never run `/release`, `/rcand` or `/hotfix` in these repos (the CLI refuses), and never tell the owner a landed change waits on a release. An urgent fix is a normal PR to development. A suite member never asks for, proposes or prompts an rc, release or hotfix — there is none; state what landed and stop.
2
2
 
3
- In the suite lead (MM-Work) a plain rcand, release or hotfix refuses: the suite path is `mmi-cli devops suite rcand --owner-go` or `mmi-cli devops suite release --owner-go` (a lead-only cut needs `--suite-solo --owner-go`). `--owner-go` records Jervaise's explicit go for that one cut; it is never the agent's own flag. Never pass it on your own authority: a held train or a stale MM-Work cut (`suite abandon --owner-go`, then `suite rcand --owner-go`) is handed to the suite orchestrator with that exact command sequence, and runs only after the owner says go. On your own, run only the read-only previews `mmi-cli devops suite rcand --dry-run` and `mmi-cli devops suite hotfix <member> --dry-run`; `suite release` and `suite abandon` have no dry-run, so never run them yourself. A real suite rcand, release, hotfix or abandon runs only on the owner's go, executed by the owner or the suite orchestrator. A suite member cannot run standalone rcand, release or hotfix: cut from the suite lead; only a backward-compatible solo backend release/hotfix with explicit owner approval may pass `--suite-solo --owner-go`, and its MM-Work development pin PR must land before the suite is in sync. A suite member never asks for, proposes or prompts an rc, release or hotfix — the suite orchestrator is the only voice that brings a cut to Jervaise, so a member session states what landed and stops instead of offering a cut.
3
+ The Hub's own release train (MMI-Hub, Jerv-Hub, Jerv-JervCode and other non-MM repos with a release lane) is unchanged and never applies to MM-Work or its modules.
4
4
 
5
5
  Support sessions (MMI-Hub, Jerv-Hub, Jerv-JervCode) are not suite members and hold standing owner authorization (2026-10-25) to cut and ship releases at their discretion during suite runs without repeated per-release approval, and under the owner's 2026-11-01 ruling each support session strives during a suite run to finish its own board and cut a patch release for landed-but-unreleased merges so suite members pick the update up in that run instead of waiting for a later cut, keeping all standard release preflight, gate, and verification checks.
6
-
7
- Every new mm-work suite Release (including solo and hotfix releases) requires both `--announce-summary-file <path>` (English) and `--announce-summary-file-tr <path>` (Turkish, "sen" form) in the update-notes template. The canonical wording lives in the [MM-Work GUIDE, "Update notes"](https://github.com/mutmutco/MM-Work/blob/development/packages/mmwork-ds/GUIDE.md#update-notes); this repo links it and never copies it. Each file has the section word `Fixed` / `Düzeldi` (what works now, never the problem: "Drive: Scans of large drives now finish without timing out."; a line without now / again / no longer, or artık / yeniden / tekrar / yine, is refused) and/or `New` / `Yeni` (what you can now do) on its own line, Fixed first, each only when it has lines. Under them go 1–8 lines of `<Area>: <sentence>.`, each at most 120 characters, with no issue numbers, versions or commit prefixes. Off-template or missing files refuse before tagging. Do not write the head (app · date · time) or the thanks line: MM-Work renders both from the Release date and credits. Suite release also requires a valid `--member-summary-file <owner/repo=path>` and `--member-summary-file-tr <owner/repo=path>` for every member being released, before promoting any member. Carried, held and already-released members need none, and existing Releases can resume without new files.
8
- The `/user-releases` feed serves template notes as `updateNotes: {en?, tr?: {fixed[], new[]}}`. Older title-and-notes bodies keep `plainWords` and get `updateNotes: null`.
9
-
@@ -8,7 +8,7 @@ Do not use a `--jq` formatter, raw `gh` reads (`gh run list`, `gh run list --com
8
8
 
9
9
  ## Release summary file
10
10
 
11
- Required for MMI-Hub and any product whose META carries `releaseChannel`; an mm-work suite repo needs one for its GitHub Release, following the update-notes template in [suite.md](suite.md). Run `mkdir -p .jerv/tmp` and write 3–6 lines to a file made by `mktemp .jerv/tmp/release-summary.XXXXXX` (scratch lives under `.jerv/tmp` in every repo; a repo-root `tmp/` may not exist and a host guards root writes).
11
+ Required for MMI-Hub and any product whose META carries `releaseChannel`. MM-Work and its modules never cut a release, so they never write one ([suite.md](suite.md)). Run `mkdir -p .jerv/tmp` and write 3–6 lines to a file made by `mktemp .jerv/tmp/release-summary.XXXXXX` (scratch lives under `.jerv/tmp` in every repo; a repo-root `tmp/` may not exist and a host guards root writes).
12
12
 
13
13
  - MMI-Hub: neutral Hub-subsystem terms, never a product or brand name or a Jerv-side project (the train refuses one). Build every line from `git log --stat --format='%h %s%n%b' origin/main..origin/development`; a line you cannot point to there stays out, and every cited `#N` must appear there.
14
14
  - Product: in `releaseLanguage` (default `en`), plain words on what changed and why it matters; no prefixes, issue/PR numbers, file names or jargon.