@mutmutco/cli 4.5.157 → 4.5.158

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/dist/main.cjs CHANGED
@@ -16372,6 +16372,38 @@ function checkRunbookCoverage(docs, base, git3) {
16372
16372
  }
16373
16373
  return findings;
16374
16374
  }
16375
+ function checkSeedRunbookReview(root, base, readFile10, git3) {
16376
+ const manifestJson = readFile10((0, import_node_path15.join)(root, "skills/bootstrap/seeds/manifest.json"));
16377
+ if (!manifestJson) return [];
16378
+ const changed = new Set(git3(["diff", "--name-only", `${base}...HEAD`]).split(/\r?\n/).filter(Boolean));
16379
+ const touched = loadBootstrapSeeds(manifestJson).seeds.filter((seed) => isPropagatableSeed(seed) && changed.has(seedSourcePath(seed)));
16380
+ if (!touched.length) return [];
16381
+ let declarations = null;
16382
+ try {
16383
+ declarations = JSON.parse(readFile10((0, import_node_path15.join)(root, RUNBOOK_UNAFFECTED_PATH)) ?? "null");
16384
+ } catch {
16385
+ declarations = null;
16386
+ }
16387
+ const findings = [];
16388
+ for (const seed of touched) {
16389
+ const source = seedSourcePath(seed);
16390
+ let blob;
16391
+ try {
16392
+ blob = git3(["rev-parse", `HEAD:${source}`]).trim();
16393
+ } catch {
16394
+ continue;
16395
+ }
16396
+ if (!runbookUnaffectedReason(declarations, seed.target, blob)) {
16397
+ findings.push({
16398
+ kind: "seed-runbook-unreviewed",
16399
+ doc: source,
16400
+ line: 0,
16401
+ detail: `${seed.target} (source blob ${blob}): propagatable seed changed without a runbook impact decision; add "${seed.target}": { "blob": "${blob}", "reason": "<why>" } to ${RUNBOOK_UNAFFECTED_PATH} or declare Seed-Runbook-Affected: <reason> in a commit message`
16402
+ });
16403
+ }
16404
+ }
16405
+ return findings;
16406
+ }
16375
16407
  function readFileOrNull(path2) {
16376
16408
  return (0, import_node_fs17.existsSync)(path2) ? (0, import_node_fs17.readFileSync)(path2, "utf8") : null;
16377
16409
  }
@@ -16505,11 +16537,14 @@ function runDocRefs(root, deps = {}) {
16505
16537
  if (deps.base) {
16506
16538
  const git3 = deps.git ?? ((args) => (0, import_node_child_process6.execFileSync)("git", args, { cwd: root, encoding: "utf8", maxBuffer: CHECK_IGNORE_MAX_BUFFER, windowsHide: true }));
16507
16539
  const stale = checkRunbookCoverage(runbooks, deps.base, git3);
16540
+ const seedStale = checkSeedRunbookReview(root, deps.base, readFile10, git3);
16508
16541
  const messages = git3(["log", "--format=%B", `${deps.base}..HEAD`]);
16509
- const sourceMessages = stale.length ? mergeGroupRunbookMessages(root, deps, readFile10, warnings) : "";
16510
- const override = /^Runbook-Unaffected:[ \t]*\S.*$/m.test(`${messages}
16511
- ${sourceMessages}`);
16542
+ const sourceMessages = stale.length || seedStale.length ? mergeGroupRunbookMessages(root, deps, readFile10, warnings) : "";
16543
+ const allMessages = `${messages}
16544
+ ${sourceMessages}`;
16545
+ const override = /^Runbook-Unaffected:[ \t]*\S.*$/m.test(allMessages);
16512
16546
  (override ? warnings : findings).push(...stale);
16547
+ if (!/^Seed-Runbook-Affected:[ \t]*\S.*$/m.test(allMessages)) findings.push(...seedStale);
16513
16548
  }
16514
16549
  return {
16515
16550
  ok: findings.length === 0,
@@ -18741,10 +18776,10 @@ var rollout_plan_default = {
18741
18776
  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)."
18742
18777
  },
18743
18778
  baseline: {
18744
- version: "4.5.157",
18745
- tag: "v4.5.157",
18746
- commit: "a6662d29e5ff",
18747
- npm: "@mutmutco/cli@4.5.157"
18779
+ version: "4.5.158",
18780
+ tag: "v4.5.158",
18781
+ commit: "21733e84802e",
18782
+ npm: "@mutmutco/cli@4.5.158"
18748
18783
  },
18749
18784
  exitCriterion: "fleet-n-of-n",
18750
18785
  hubOnlyShortcut: "forbidden",
@@ -18761,14 +18796,14 @@ var rollout_plan_default = {
18761
18796
  repo: "mutmutco/mmi-hub",
18762
18797
  role: "canary",
18763
18798
  schedule: "train",
18764
- v3Target: "v4.5.157"
18799
+ v3Target: "v4.5.158"
18765
18800
  }
18766
18801
  ],
18767
18802
  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.",
18768
18803
  rollback: {
18769
18804
  independent: true,
18770
- mechanism: "npm dist-tag latest -> 4.5.157 and redeploy the Hub Lambda from tag v4.5.157 (a6662d29e5ff); installed clients repair via `mmi-cli doctor`. No other cohort is touched.",
18771
- v3Target: "v4.5.157 (@mutmutco/cli@4.5.157, tag commit a6662d29e5ff \u2014 last known-good release carrying the repo-index v4-only contract)"
18805
+ mechanism: "npm dist-tag latest -> 4.5.158 and redeploy the Hub Lambda from tag v4.5.158 (21733e84802e); installed clients repair via `mmi-cli doctor`. No other cohort is touched.",
18806
+ v3Target: "v4.5.158 (@mutmutco/cli@4.5.158, tag commit 21733e84802e \u2014 last known-good release carrying the repo-index v4-only contract)"
18772
18807
  }
18773
18808
  },
18774
18809
  {
@@ -334,6 +334,53 @@ module.exports = __toCommonJS(runbook_sweep_entry_exports);
334
334
  var import_node_child_process = require("node:child_process");
335
335
  var import_node_fs = require("node:fs");
336
336
  var import_node_path = require("node:path");
337
+
338
+ // src/bootstrap-seeds.ts
339
+ function loadBootstrapSeeds(manifestJson) {
340
+ let parsed;
341
+ try {
342
+ parsed = JSON.parse(manifestJson);
343
+ } catch {
344
+ throw new Error("bootstrap seed manifest is not valid JSON");
345
+ }
346
+ const obj = parsed ?? {};
347
+ const seeds = obj.seeds ?? [];
348
+ for (const s of seeds) {
349
+ if (!s || !s.target || !s.source || !Array.isArray(s.classes)) {
350
+ throw new Error(`invalid seed entry (needs target, source, classes): ${JSON.stringify(s)}`);
351
+ }
352
+ if (s.ownership !== "org" && s.ownership !== "repo") {
353
+ throw new Error(`invalid seed ownership '${s.ownership}' for ${s.target} (must be 'org' or 'repo')`);
354
+ }
355
+ if (s.managedBlock) {
356
+ const block = s.managedBlock;
357
+ if (!block.source || !block.begin || !block.end || block.begin === block.end || /[\r\n]/.test(block.begin + block.end)) {
358
+ throw new Error(`invalid managedBlock for ${s.target} (needs source and distinct single-line begin/end markers)`);
359
+ }
360
+ }
361
+ }
362
+ return {
363
+ seeds,
364
+ labels: obj.labels ?? [],
365
+ placeholders: obj.placeholders ?? []
366
+ };
367
+ }
368
+ function isPropagatableSeed(seed) {
369
+ return seed.ownership === "org" && seed.source === "self" || seed.managedBlock != null;
370
+ }
371
+ function seedSourcePath(seed) {
372
+ const source = seed.managedBlock?.source ?? seed.source;
373
+ return source.startsWith("seed:") ? `skills/bootstrap/seeds/${source.slice(5)}` : seed.target;
374
+ }
375
+ var RUNBOOK_UNAFFECTED_PATH = "skills/bootstrap/seeds/runbook-unaffected.json";
376
+ function runbookUnaffectedReason(declarations, target, sourceBlob) {
377
+ const entry = declarations?.[target];
378
+ if (!entry || entry.blob !== sourceBlob || typeof entry.reason !== "string") return void 0;
379
+ const reason = entry.reason.trim();
380
+ return reason && !/[\r\n]/.test(reason) ? reason : void 0;
381
+ }
382
+
383
+ // src/doc-refs-core.ts
337
384
  var PIN_RE = /<!--\s*pinned by\s+([^:]+?)\s*:\s*"([^"]+)"[^"]*-->/;
338
385
  var PIN_MENTION_RE = /<!--\s*pinned by\b/;
339
386
  var FWD_RE = /<!--\s*forward-ref:\s*(\S+?)\s*-->/;
@@ -669,6 +716,38 @@ function checkRunbookCoverage(docs, base, git) {
669
716
  }
670
717
  return findings;
671
718
  }
719
+ function checkSeedRunbookReview(root, base, readFile2, git) {
720
+ const manifestJson = readFile2((0, import_node_path.join)(root, "skills/bootstrap/seeds/manifest.json"));
721
+ if (!manifestJson) return [];
722
+ const changed = new Set(git(["diff", "--name-only", `${base}...HEAD`]).split(/\r?\n/).filter(Boolean));
723
+ const touched = loadBootstrapSeeds(manifestJson).seeds.filter((seed) => isPropagatableSeed(seed) && changed.has(seedSourcePath(seed)));
724
+ if (!touched.length) return [];
725
+ let declarations = null;
726
+ try {
727
+ declarations = JSON.parse(readFile2((0, import_node_path.join)(root, RUNBOOK_UNAFFECTED_PATH)) ?? "null");
728
+ } catch {
729
+ declarations = null;
730
+ }
731
+ const findings = [];
732
+ for (const seed of touched) {
733
+ const source = seedSourcePath(seed);
734
+ let blob;
735
+ try {
736
+ blob = git(["rev-parse", `HEAD:${source}`]).trim();
737
+ } catch {
738
+ continue;
739
+ }
740
+ if (!runbookUnaffectedReason(declarations, seed.target, blob)) {
741
+ findings.push({
742
+ kind: "seed-runbook-unreviewed",
743
+ doc: source,
744
+ line: 0,
745
+ detail: `${seed.target} (source blob ${blob}): propagatable seed changed without a runbook impact decision; add "${seed.target}": { "blob": "${blob}", "reason": "<why>" } to ${RUNBOOK_UNAFFECTED_PATH} or declare Seed-Runbook-Affected: <reason> in a commit message`
746
+ });
747
+ }
748
+ }
749
+ return findings;
750
+ }
672
751
  function readFileOrNull(path2) {
673
752
  return (0, import_node_fs.existsSync)(path2) ? (0, import_node_fs.readFileSync)(path2, "utf8") : null;
674
753
  }
@@ -802,11 +881,14 @@ function runDocRefs(root, deps = {}) {
802
881
  if (deps.base) {
803
882
  const git = deps.git ?? ((args) => (0, import_node_child_process.execFileSync)("git", args, { cwd: root, encoding: "utf8", maxBuffer: CHECK_IGNORE_MAX_BUFFER, windowsHide: true }));
804
883
  const stale = checkRunbookCoverage(runbooks, deps.base, git);
884
+ const seedStale = checkSeedRunbookReview(root, deps.base, readFile2, git);
805
885
  const messages = git(["log", "--format=%B", `${deps.base}..HEAD`]);
806
- const sourceMessages = stale.length ? mergeGroupRunbookMessages(root, deps, readFile2, warnings) : "";
807
- const override = /^Runbook-Unaffected:[ \t]*\S.*$/m.test(`${messages}
808
- ${sourceMessages}`);
886
+ const sourceMessages = stale.length || seedStale.length ? mergeGroupRunbookMessages(root, deps, readFile2, warnings) : "";
887
+ const allMessages = `${messages}
888
+ ${sourceMessages}`;
889
+ const override = /^Runbook-Unaffected:[ \t]*\S.*$/m.test(allMessages);
809
890
  (override ? warnings : findings).push(...stale);
891
+ if (!/^Seed-Runbook-Affected:[ \t]*\S.*$/m.test(allMessages)) findings.push(...seedStale);
810
892
  }
811
893
  return {
812
894
  ok: findings.length === 0,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mutmutco/cli",
3
- "version": "4.5.157",
3
+ "version": "4.5.158",
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",