@mutmutco/claude-plugin 4.5.230 → 4.5.232

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.5.230",
4
+ "version": "4.5.232",
5
5
  "mmiCompat": "4.x",
6
6
  "description": "MMI workflow skills and org gates delivery.",
7
7
  "author": {
package/cli/dist/main.cjs CHANGED
@@ -1469,8 +1469,8 @@ function commandFromFailMessage(msg) {
1469
1469
  const head = msg.split(":", 1)[0].trim();
1470
1470
  if (!head || head.startsWith("-")) return "mmi-cli";
1471
1471
  if (!/^[a-z][a-z0-9-]*(?: [a-z][a-z0-9-]*){0,5}$/.test(head)) return "mmi-cli";
1472
- const canonical2 = canonicalPathFor(head);
1473
- if (canonical2) return canonical2;
1472
+ const canonical = canonicalPathFor(head);
1473
+ if (canonical) return canonical;
1474
1474
  return HOUSE_ROOTS.includes(head.split(" ")[0]) ? head : "mmi-cli";
1475
1475
  }
1476
1476
  function canonicalFailMessage(msg) {
@@ -24015,20 +24015,20 @@ function reseedProductRulesetStrictness(current, seed, declared = {}) {
24015
24015
  }
24016
24016
  return { policy: policy2, parameters: parameters2 };
24017
24017
  };
24018
- const canonical2 = parse2(seed);
24019
- const strict = canonical2.parameters.strict_required_status_checks_policy;
24018
+ const canonical = parse2(seed);
24019
+ const strict = canonical.parameters.strict_required_status_checks_policy;
24020
24020
  if (typeof strict !== "boolean") throw new Error("canonical product ruleset must declare boolean strictness");
24021
24021
  if (current === null) return seed;
24022
24022
  const { policy, parameters } = parse2(current);
24023
24023
  let changed = parameters.strict_required_status_checks_policy !== strict;
24024
24024
  parameters.strict_required_status_checks_policy = strict;
24025
24025
  if (declared.requiredChecks) {
24026
- const checks = canonical2.parameters.required_status_checks.map((check) => parameters.required_status_checks.find((old) => old.context === check.context) ?? check);
24026
+ const checks = canonical.parameters.required_status_checks.map((check) => parameters.required_status_checks.find((old) => old.context === check.context) ?? check);
24027
24027
  if (JSON.stringify(parameters.required_status_checks) !== JSON.stringify(checks)) changed = true;
24028
24028
  parameters.required_status_checks = checks;
24029
24029
  }
24030
24030
  if (declared.requiredCheckBranches) {
24031
- const refs = canonical2.policy.conditions?.ref_name?.include;
24031
+ const refs = canonical.policy.conditions?.ref_name?.include;
24032
24032
  if (!Array.isArray(refs) || !refs.length) throw new Error("canonical product ruleset must declare branch includes");
24033
24033
  const conditions = policy.conditions;
24034
24034
  const refName = conditions?.ref_name;
@@ -24297,13 +24297,13 @@ function upsertManagedSeedBlock(current, desired, begin, end) {
24297
24297
  if (desired.slice(0, desiredBegin.start).trim() || desired.slice(desiredEnd.end).trim()) {
24298
24298
  return { ok: false, reason: "managed block source must contain only the bounded block" };
24299
24299
  }
24300
- const canonical2 = desired.slice(desiredBegin.start, desiredEnd.textEnd);
24300
+ const canonical = desired.slice(desiredBegin.start, desiredEnd.textEnd);
24301
24301
  const currentLines = sourceLines(current);
24302
24302
  const begins = currentLines.filter((line) => line.text === begin);
24303
24303
  const ends = currentLines.filter((line) => line.text === end);
24304
24304
  if (begins.length === 0 && ends.length === 0) {
24305
24305
  const eol2 = current.match(/\r\n|\n|\r/)?.[0] ?? "\n";
24306
- const block2 = normalizeEol(canonical2).replace(/\n/g, eol2);
24306
+ const block2 = normalizeEol(canonical).replace(/\n/g, eol2);
24307
24307
  if (current.length === 0) return { ok: true, content: `${block2}${eol2}`, changed: true, action: "insert" };
24308
24308
  const separator = /(?:\r\n|\n|\r)$/.test(current) ? eol2 : `${eol2}${eol2}`;
24309
24309
  return { ok: true, content: `${current}${separator}${block2}${eol2}`, changed: true, action: "insert" };
@@ -24317,11 +24317,11 @@ function upsertManagedSeedBlock(current, desired, begin, end) {
24317
24317
  return { ok: false, reason: "malformed managed block markers (end precedes begin)" };
24318
24318
  }
24319
24319
  const existing = current.slice(currentBegin.start, currentEnd.textEnd);
24320
- if (normalizeEol(existing) === normalizeEol(canonical2)) {
24320
+ if (normalizeEol(existing) === normalizeEol(canonical)) {
24321
24321
  return { ok: true, content: current, changed: false, action: "current" };
24322
24322
  }
24323
24323
  const eol = current.match(/\r\n|\n|\r/)?.[0] ?? "\n";
24324
- const block = normalizeEol(canonical2).replace(/\n/g, eol);
24324
+ const block = normalizeEol(canonical).replace(/\n/g, eol);
24325
24325
  return {
24326
24326
  ok: true,
24327
24327
  content: `${current.slice(0, currentBegin.start)}${block}${current.slice(currentEnd.textEnd)}`,
@@ -27242,10 +27242,10 @@ var rollout_plan_default = {
27242
27242
  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)."
27243
27243
  },
27244
27244
  baseline: {
27245
- version: "4.5.230",
27246
- tag: "v4.5.230",
27247
- commit: "faa22acbc289",
27248
- npm: "@mutmutco/cli@4.5.230"
27245
+ version: "4.5.232",
27246
+ tag: "v4.5.232",
27247
+ commit: "cd546199eccb",
27248
+ npm: "@mutmutco/cli@4.5.232"
27249
27249
  },
27250
27250
  exitCriterion: "fleet-n-of-n",
27251
27251
  hubOnlyShortcut: "forbidden",
@@ -27262,14 +27262,14 @@ var rollout_plan_default = {
27262
27262
  repo: "mutmutco/mmi-hub",
27263
27263
  role: "canary",
27264
27264
  schedule: "train",
27265
- v3Target: "v4.5.230"
27265
+ v3Target: "v4.5.232"
27266
27266
  }
27267
27267
  ],
27268
27268
  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.",
27269
27269
  rollback: {
27270
27270
  independent: true,
27271
- mechanism: "npm dist-tag latest -> 4.5.230 and redeploy the Hub Lambda from tag v4.5.230 (faa22acbc289); installed clients repair via `mmi-cli doctor`. No other cohort is touched.",
27272
- v3Target: "v4.5.230 (@mutmutco/cli@4.5.230, tag commit faa22acbc289 \u2014 last known-good release carrying the repo-index v4-only contract)"
27271
+ mechanism: "npm dist-tag latest -> 4.5.232 and redeploy the Hub Lambda from tag v4.5.232 (cd546199eccb); installed clients repair via `mmi-cli doctor`. No other cohort is touched.",
27272
+ v3Target: "v4.5.232 (@mutmutco/cli@4.5.232, tag commit cd546199eccb \u2014 last known-good release carrying the repo-index v4-only contract)"
27273
27273
  }
27274
27274
  },
27275
27275
  {
@@ -28931,15 +28931,15 @@ function planFleetLockstepEnforcement(read, enrollment, stagePlan, statusFinding
28931
28931
  };
28932
28932
  }
28933
28933
  async function resolveCanonicalRepoNames(client, repos) {
28934
- const canonical2 = /* @__PURE__ */ new Map();
28934
+ const canonical = /* @__PURE__ */ new Map();
28935
28935
  for (const repo of repos) {
28936
28936
  const detail = await client.rest("GET", `repos/${repo}`, { timeoutMs: 2e4 });
28937
28937
  if (typeof detail?.name !== "string" || !detail.name) {
28938
28938
  throw new Error(`could not resolve the canonical repository name for ${repo} \u2014 refusing to write a ruleset include entry from guessed casing`);
28939
28939
  }
28940
- canonical2.set(repo.toLowerCase(), detail.name);
28940
+ canonical.set(repo.toLowerCase(), detail.name);
28941
28941
  }
28942
- return canonical2;
28942
+ return canonical;
28943
28943
  }
28944
28944
  async function writeFleetLockstepRuleset(client, body, liveId, target, org) {
28945
28945
  if (liveId == null) {
@@ -28963,7 +28963,7 @@ async function writeFleetLockstepRuleset(client, body, liveId, target, org) {
28963
28963
  verified: true
28964
28964
  };
28965
28965
  }
28966
- async function applyFleetLockstepStage(client, plan, target, canonical2, org = ORG_LOGIN) {
28966
+ async function applyFleetLockstepStage(client, plan, target, canonical, org = ORG_LOGIN) {
28967
28967
  const stage = plan.stages.find((s) => s.stage === target);
28968
28968
  if (!stage) throw new Error(`unknown arming stage ${target} \u2014 stages run 1..${plan.totalStages}`);
28969
28969
  if (target > plan.armedThroughStage + 1 && plan.state !== "disarmed") {
@@ -28972,7 +28972,7 @@ async function applyFleetLockstepStage(client, plan, target, canonical2, org = O
28972
28972
  );
28973
28973
  }
28974
28974
  const include = stage.cumulativeRepos.map((repo) => {
28975
- const name = canonical2.get(repo.toLowerCase());
28975
+ const name = canonical.get(repo.toLowerCase());
28976
28976
  if (!name) throw new Error(`no canonical name resolved for ${repo}`);
28977
28977
  return name;
28978
28978
  });
@@ -29276,8 +29276,8 @@ function registerFleetLockstepEnforce(program3) {
29276
29276
  rollback stays available: mmi-cli devops train enforce --apply --disarm`
29277
29277
  );
29278
29278
  }
29279
- const canonical2 = await resolveCanonicalRepoNames(client, plan.stages.find((s) => s.stage === target).cumulativeRepos);
29280
- const result = await applyFleetLockstepStage(client, plan, target, canonical2);
29279
+ const canonical = await resolveCanonicalRepoNames(client, plan.stages.find((s) => s.stage === target).cumulativeRepos);
29280
+ const result = await applyFleetLockstepStage(client, plan, target, canonical);
29281
29281
  const { plan: after } = await readEnforcementPlan(client);
29282
29282
  if (o.json) console.log(JSON.stringify({ result, plan: after }, null, 2));
29283
29283
  else {
@@ -30433,15 +30433,15 @@ function parseRuntimeIdentity(log, expected) {
30433
30433
  if (proofs.length !== 1) return unavailable("invalid-proof");
30434
30434
  const encoded = proofs[0].slice(prefix.length).trim();
30435
30435
  if (encoded.length > 16384) return unavailable("invalid-proof");
30436
- const object2 = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
30436
+ const object = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
30437
30437
  const keys = (v, allowed) => Object.keys(v).length === allowed.length && Object.keys(v).every((k) => allowed.includes(k));
30438
30438
  const text = (v, re) => typeof v === "string" && re.test(v);
30439
30439
  try {
30440
30440
  const p = JSON.parse(encoded);
30441
- if (JSON.stringify(p) !== encoded || !object2(p)) return unavailable("invalid-proof");
30441
+ if (JSON.stringify(p) !== encoded || !object(p)) return unavailable("invalid-proof");
30442
30442
  if (p.version !== 1) return unavailable("unsupported-version");
30443
30443
  const parts = expected.repo.split("/");
30444
- if (parts.length !== 2 || !parts.every(Boolean) || !object2(p.target) || !keys(p.target, ["slug", "stage"]) || p.target.slug !== parts[1].toLowerCase() || p.target.stage !== expected.stage) return unavailable("target-mismatch");
30444
+ if (parts.length !== 2 || !parts.every(Boolean) || !object(p.target) || !keys(p.target, ["slug", "stage"]) || p.target.slug !== parts[1].toLowerCase() || p.target.stage !== expected.stage) return unavailable("target-mismatch");
30445
30445
  if (p.status === "unavailable") {
30446
30446
  if (!keys(p, ["version", "target", "status", "reason"]) || typeof p.reason !== "string" || !["selection-unavailable", "inspection-failed", "snapshot-changed", "output-too-large"].includes(p.reason)) return unavailable("invalid-proof");
30447
30447
  return unavailable(p.reason);
@@ -30449,7 +30449,7 @@ function parseRuntimeIdentity(log, expected) {
30449
30449
  if (!keys(p, ["version", "target", "status", "slot", "replicas"]) || p.status !== "available" || p.slot !== "blue" && p.slot !== "green" || !Array.isArray(p.replicas) || !p.replicas.length) return unavailable("invalid-proof");
30450
30450
  const seen = /* @__PURE__ */ new Set();
30451
30451
  for (const r of p.replicas) {
30452
- if (!object2(r) || !keys(r, ["service", "container", "configuredRef", "actualImageID", "repoDigests", "health", "state"]) || !text(r.service, /^[A-Za-z0-9][A-Za-z0-9_-]*$/) || !text(r.container, /^[a-f0-9]{64}$/) || !text(r.configuredRef, /^[A-Za-z0-9][A-Za-z0-9._/@:-]*$/) || !text(r.actualImageID, /^sha256:[a-f0-9]{64}$/) || !Array.isArray(r.repoDigests) || !r.repoDigests.every((d) => text(d, /^[A-Za-z0-9][A-Za-z0-9._/:-]*@sha256:[a-f0-9]{64}$/)) || (typeof r.health !== "string" || !["healthy", "unhealthy", "starting", "not-configured", "unknown"].includes(r.health)) || r.state !== "running" || seen.has(r.container)) return unavailable("invalid-proof");
30452
+ if (!object(r) || !keys(r, ["service", "container", "configuredRef", "actualImageID", "repoDigests", "health", "state"]) || !text(r.service, /^[A-Za-z0-9][A-Za-z0-9_-]*$/) || !text(r.container, /^[a-f0-9]{64}$/) || !text(r.configuredRef, /^[A-Za-z0-9][A-Za-z0-9._/@:-]*$/) || !text(r.actualImageID, /^sha256:[a-f0-9]{64}$/) || !Array.isArray(r.repoDigests) || !r.repoDigests.every((d) => text(d, /^[A-Za-z0-9][A-Za-z0-9._/:-]*@sha256:[a-f0-9]{64}$/)) || (typeof r.health !== "string" || !["healthy", "unhealthy", "starting", "not-configured", "unknown"].includes(r.health)) || r.state !== "running" || seen.has(r.container)) return unavailable("invalid-proof");
30453
30453
  seen.add(r.container);
30454
30454
  }
30455
30455
  return p;
@@ -31932,114 +31932,6 @@ function parseRunnerJobs(source) {
31932
31932
  return void 0;
31933
31933
  }
31934
31934
  }
31935
- function parseRunnerWorkflowContract(source) {
31936
- if (!source || source.length > 15e5) return void 0;
31937
- try {
31938
- const doc = (0, import_yaml.parseDocument)(source, { uniqueKeys: true, stringKeys: true, merge: false, prettyErrors: false });
31939
- if (doc.errors.length || doc.warnings.length || !literalMap(doc.contents)) return void 0;
31940
- let invalid = false, nodes = 0;
31941
- (0, import_yaml.visit)(doc, (_key, node, path2) => {
31942
- if (++nodes > 1e5 || path2.length > 64 || !literal(node) || (0, import_yaml.isPair)(node) && (0, import_yaml.isScalar)(node.key) && node.key.value === "<<") {
31943
- invalid = true;
31944
- return import_yaml.visit.BREAK;
31945
- }
31946
- });
31947
- return invalid ? void 0 : doc.toJS({ maxAliasCount: 0 });
31948
- } catch {
31949
- return void 0;
31950
- }
31951
- }
31952
-
31953
- // ../shared/ci-allowance-contract.ts
31954
- var import_node_crypto9 = require("node:crypto");
31955
- var CLI_ALLOWANCE_MANIFEST = Object.freeze({
31956
- id: "hub-cli-v1",
31957
- parts: ["tests-1", "tests-2", "checks"],
31958
- // Includes checkout, toolchain, installation and teardown, not just the test subprocess.
31959
- jobMinutes: 10,
31960
- aggregateMinutes: 1,
31961
- maxAttempts: 3,
31962
- storageBytes: 0
31963
- });
31964
- var CLI_ATTEMPT_MINUTES = CLI_ALLOWANCE_MANIFEST.parts.length * CLI_ALLOWANCE_MANIFEST.jobMinutes + CLI_ALLOWANCE_MANIFEST.aggregateMinutes;
31965
- var CI_PROFILES = Object.freeze({
31966
- "included-linux": "ubuntu-latest",
31967
- "owned-linux": ["self-hosted", "linux", "x64", "mmi-live"]
31968
- });
31969
- var CLI_ADMISSION_IF = "${{ always() && !cancelled() && needs.cli-admission.result == 'success' && needs.cli-admission.outputs.admitted == 'true' && needs.cli-admission.outputs.attempt == format('{0}', github.run_attempt) && needs.cli-admission.outputs.candidate == github.sha && (needs.cli-admission.outputs.profile == 'included-linux' || needs.cli-admission.outputs.profile == 'owned-linux') }}";
31970
- var CLI_ADMISSION_RUNNER = `\${{ needs.cli-admission.outputs.profile == 'included-linux' && 'ubuntu-latest' || fromJSON('["self-hosted","linux","x64","mmi-live"]') }}`;
31971
- var CLI_AGGREGATE_SCRIPT = `test "$ADMISSION_RESULT" = success
31972
- test "$ADMITTED" = true
31973
- test "$ADMITTED_ATTEMPT" = "$CURRENT_ATTEMPT"
31974
- test "$ADMITTED_CANDIDATE" = "$CURRENT_CANDIDATE"
31975
- test "$PART_RESULT" = success`;
31976
- var aggregateEnv = {
31977
- ADMISSION_RESULT: "${{ needs.cli-admission.result }}",
31978
- ADMITTED: "${{ needs.cli-admission.outputs.admitted }}",
31979
- ADMITTED_ATTEMPT: "${{ needs.cli-admission.outputs.attempt }}",
31980
- CURRENT_ATTEMPT: "${{ github.run_attempt }}",
31981
- ADMITTED_CANDIDATE: "${{ needs.cli-admission.outputs.candidate }}",
31982
- CURRENT_CANDIDATE: "${{ github.sha }}",
31983
- PART_RESULT: "${{ needs.cli-part.result }}"
31984
- };
31985
- function object(value) {
31986
- return value !== null && typeof value === "object" && !Array.isArray(value);
31987
- }
31988
- function equal(a, b) {
31989
- return canonical(a) === canonical(b);
31990
- }
31991
- function canonical(value) {
31992
- if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
31993
- if (object(value)) return `{${Object.keys(value).sort().map((k) => `${JSON.stringify(k)}:${canonical(value[k])}`).join(",")}}`;
31994
- return JSON.stringify(value);
31995
- }
31996
- function cliAdmissionJobs(coordinatorSha) {
31997
- if (!/^[a-f0-9]{40}$/.test(coordinatorSha)) throw new Error("immutable coordinator SHA required");
31998
- return {
31999
- "cli-admission": { uses: `mutmutco/MMI-Hub/.github/workflows/ci-allowance.yml@${coordinatorSha}`, permissions: { "id-token": "write" } },
32000
- // Merge these keys into the EXISTING cli-part; retain every test/build step.
32001
- "cli-part": { needs: ["cli-admission"], if: CLI_ADMISSION_IF, "runs-on": CLI_ADMISSION_RUNNER, "timeout-minutes": CLI_ALLOWANCE_MANIFEST.jobMinutes },
32002
- cli: {
32003
- needs: ["cli-admission", "cli-part"],
32004
- if: "${{ always() && !cancelled() }}",
32005
- "runs-on": CI_PROFILES["owned-linux"],
32006
- "timeout-minutes": 1,
32007
- permissions: {},
32008
- steps: [{ name: "Require fresh admission and every CLI part", shell: "bash", env: aggregateEnv, run: CLI_AGGREGATE_SCRIPT }]
32009
- }
32010
- };
32011
- }
32012
- function verifyCliAdmissionContract(workflow, coordinatorSha) {
32013
- if (!object(workflow) || !object(workflow.jobs)) return null;
32014
- if (!equal(workflow.permissions, { contents: "read", "pull-requests": "read" })) return null;
32015
- const expected = cliAdmissionJobs(coordinatorSha);
32016
- const admission = workflow.jobs["cli-admission"], part = workflow.jobs["cli-part"], aggregate = workflow.jobs.cli;
32017
- if (!equal(admission, expected["cli-admission"]) || !equal(aggregate, expected.cli) || !object(part)) return null;
32018
- if (!Object.entries(expected["cli-part"]).every(([key, value]) => equal(part[key], value))) return null;
32019
- if (!object(part.strategy) || part.strategy["fail-fast"] !== false || !object(part.strategy.matrix) || !equal(part.strategy.matrix, { part: [...CLI_ALLOWANCE_MANIFEST.parts] }) || part["continue-on-error"]) return null;
32020
- if (!Array.isArray(part.steps) || !part.steps.every(object)) return null;
32021
- const toolchains = part.steps.filter((step) => step.uses === "./.github/actions/runner-node-toolchain");
32022
- if (toolchains.length !== 1 || !object(toolchains[0].with) || toolchains[0].with["package-manager-cache"] !== "false" || toolchains[0].with.cache !== "") return null;
32023
- if (part.steps.some((step) => typeof step.uses === "string" && /(?:upload-artifact|actions\/cache)/.test(step.uses))) return null;
32024
- return (0, import_node_crypto9.createHash)("sha256").update(canonical(workflow)).digest("hex");
32025
- }
32026
- var CLI_ALLOWANCE_SOURCE = Object.freeze({
32027
- repository: "mutmutco/MMI-Hub",
32028
- callerPath: ".github/workflows/gate.yml",
32029
- coordinatorPath: ".github/workflows/ci-allowance.yml",
32030
- coordinatorSha: "50f0bd4d8e35f3f09119bd3fa1bb7705fcc6f09b",
32031
- coordinatorSha256: "7b23f22131c5e08292f142eeed3899c8ecf49b1bdcc96bfdfe114cf1dca47b48",
32032
- executionSha256: "6198e0896a5533f9546e084642ceb214336c930561fe9f8292eb7e6a0972933b"
32033
- });
32034
- function verifyCliAdmissionSourceContract(workflow, coordinator) {
32035
- const source = CLI_ALLOWANCE_SOURCE;
32036
- if (coordinator.repo !== source.repository || coordinator.path !== source.coordinatorPath || coordinator.ref !== source.coordinatorSha || (0, import_node_crypto9.createHash)("sha256").update(coordinator.body).digest("hex") !== source.coordinatorSha256) return null;
32037
- const digest = verifyCliAdmissionContract(workflow, source.coordinatorSha);
32038
- if (!digest) return null;
32039
- const { jobs, ...context } = workflow;
32040
- const execution = { ...context, jobs: { "cli-admission": jobs["cli-admission"], "cli-part": jobs["cli-part"], cli: jobs.cli } };
32041
- return (0, import_node_crypto9.createHash)("sha256").update(canonical(execution)).digest("hex") === source.executionSha256 ? digest : null;
32042
- }
32043
31935
 
32044
31936
  // src/workflow-runner-source.ts
32045
31937
  var WORKFLOW_PATH = /^\.github\/workflows\/[\w.-]+\.ya?ml$/;
@@ -32161,15 +32053,12 @@ function classifyRunnerWorkflows(files) {
32161
32053
  return files.flatMap((file) => {
32162
32054
  const jobs = parsed.get(locationOf(file));
32163
32055
  if (!jobs) return [{ repo: file.repo, path: file.path, job: "(invalid YAML)", cost: "unknown", callee: false }];
32164
- const source = CLI_ALLOWANCE_SOURCE;
32165
- const coordinator = known.get(locationOf({ repo: source.repository, path: source.coordinatorPath, ref: source.coordinatorSha }));
32166
- const allowance2 = file.repo === source.repository && file.path === source.callerPath && coordinator && resolved(file, /* @__PURE__ */ new Set()) && verifyCliAdmissionSourceContract(parseRunnerWorkflowContract(file.body), coordinator) !== null;
32167
32056
  return [...jobs].flatMap(([id, job]) => {
32168
32057
  const hasCallee = Object.hasOwn(job, "uses");
32169
32058
  const uses = hasCallee && typeof job.uses === "string" && !Object.hasOwn(job, "runs-on") ? job.uses : void 0;
32170
32059
  const target = uses && resolveCallee(file, uses);
32171
32060
  if (target && known.has(locationOf(target)) && resolved(file, /* @__PURE__ */ new Set())) return [];
32172
- const cost = hasCallee ? "unknown" : id === "cli-part" && allowance2 ? "standard-hosted" : classifyJobRunnerCost(job, standardHostedLabelFor(file.repo, file.path, id));
32061
+ const cost = hasCallee ? "unknown" : classifyJobRunnerCost(job, standardHostedLabelFor(file.repo, file.path, id));
32173
32062
  return [{ repo: file.repo, path: file.path, job: id, cost, callee: hasCallee }];
32174
32063
  });
32175
32064
  });
@@ -33129,7 +33018,7 @@ function checkLineEndings(probe) {
33129
33018
  // src/release-ledger.ts
33130
33019
  var import_node_fs28 = require("node:fs");
33131
33020
  var import_node_path26 = require("node:path");
33132
- var import_node_crypto10 = require("node:crypto");
33021
+ var import_node_crypto9 = require("node:crypto");
33133
33022
 
33134
33023
  // src/file-lock.ts
33135
33024
  var import_promises2 = require("node:fs/promises");
@@ -33491,7 +33380,7 @@ function releaseLedgerPath(cwd) {
33491
33380
  }
33492
33381
  function atomicWriteJson(path2, ledger) {
33493
33382
  (0, import_node_fs28.mkdirSync)((0, import_node_path26.dirname)(path2), { recursive: true });
33494
- const tmp = `${path2}.tmp-${process.pid}-${(0, import_node_crypto10.randomBytes)(4).toString("hex")}`;
33383
+ const tmp = `${path2}.tmp-${process.pid}-${(0, import_node_crypto9.randomBytes)(4).toString("hex")}`;
33495
33384
  (0, import_node_fs28.writeFileSync)(tmp, `${JSON.stringify(ledger, null, 2)}
33496
33385
  `, "utf8");
33497
33386
  (0, import_node_fs28.renameSync)(tmp, path2);
@@ -40257,14 +40146,14 @@ function buildCommand(cmd, flatPath) {
40257
40146
  );
40258
40147
  }
40259
40148
  const aliases = cmd.aliases();
40260
- const canonical2 = canonicalPathFor(flatPath) ?? flatPath;
40149
+ const canonical = canonicalPathFor(flatPath) ?? flatPath;
40261
40150
  const out = {
40262
40151
  name: cmd.name(),
40263
- path: canonical2,
40152
+ path: canonical,
40264
40153
  flat_path: flatPath,
40265
40154
  ...aliases.length ? { aliases: [...aliases] } : {},
40266
40155
  house,
40267
- canonical: canonical2,
40156
+ canonical,
40268
40157
  arguments: cmd.registeredArguments.map(buildArgument),
40269
40158
  // A hand-parsed command registers no Commander options, so its declared set is merged in (#3682).
40270
40159
  options: [...cmd.options.map(buildOption), ...readDeclaredOptions(cmd)],
@@ -40436,8 +40325,8 @@ function findCommandByPath(root, path2) {
40436
40325
  function buildDoorsCatalog(tree) {
40437
40326
  return DOOR_DECLARATIONS.map((decl) => {
40438
40327
  const house = houseForPath(decl.path);
40439
- const canonical2 = canonicalPathFor(decl.path);
40440
- if (!house || !canonical2) {
40328
+ const canonical = canonicalPathFor(decl.path);
40329
+ if (!house || !canonical) {
40441
40330
  throw new Error(
40442
40331
  `command-manifest: doors catalog entry '${decl.door}' names path '${decl.path}' with no house assignment \u2014 fix DOOR_DECLARATIONS or cli/src/house-map.ts.`
40443
40332
  );
@@ -40447,7 +40336,7 @@ function buildDoorsCatalog(tree) {
40447
40336
  question: decl.question,
40448
40337
  house,
40449
40338
  command: decl.path,
40450
- canonical: canonical2,
40339
+ canonical,
40451
40340
  source: decl.source,
40452
40341
  live: Boolean(findCommandByPath(tree, decl.path))
40453
40342
  };
@@ -41270,8 +41159,8 @@ function registerBoardCommands(program3) {
41270
41159
  }
41271
41160
  });
41272
41161
  function resolveBoardStatus(status) {
41273
- const canonical2 = canonicalizeBoardStatus(status);
41274
- if (canonical2) return canonical2;
41162
+ const canonical = canonicalizeBoardStatus(status);
41163
+ if (canonical) return canonical;
41275
41164
  fail(`board move failed: unknown status '${status}'; expected one of ${BOARD_STATUSES.join(", ")}`, {
41276
41165
  code: ERROR_CODES.ERR_BAD_ENUM,
41277
41166
  expected: [...BOARD_STATUSES]
@@ -41731,7 +41620,7 @@ var import_node_os18 = require("node:os");
41731
41620
  var import_node_path31 = require("node:path");
41732
41621
 
41733
41622
  // src/box-control.ts
41734
- var import_node_crypto11 = require("node:crypto");
41623
+ var import_node_crypto10 = require("node:crypto");
41735
41624
  var MANIFEST_PATH = "infra/box-control/manifest.json";
41736
41625
  var ALLOWED_POST = /* @__PURE__ */ new Set(["systemctl daemon-reload"]);
41737
41626
  var sshdPost = (dest) => `if sshd -t; then systemctl reload ssh; else rm -f ${dest}; echo 'sshd -t rejected ${dest}: removed, not reloaded' >&2; exit 1; fi`;
@@ -41835,7 +41724,7 @@ function laneCoverageAction(files, box, op) {
41835
41724
  return { notice: `LANE_COVERAGE: ${mismatch}` };
41836
41725
  }
41837
41726
  function md5(content) {
41838
- return (0, import_node_crypto11.createHash)("md5").update(content).digest("hex");
41727
+ return (0, import_node_crypto10.createHash)("md5").update(content).digest("hex");
41839
41728
  }
41840
41729
  function planRemoteScript(dests) {
41841
41730
  const lines2 = ["set -u"];
@@ -42614,18 +42503,18 @@ function secretRemovalRefusal(existing, patch) {
42614
42503
  return `org project set: --unset-secret ${mapKey} is not declared in ${existing?.slug ?? "this project"}'s secrets catalog \u2014 nothing to remove`;
42615
42504
  }
42616
42505
  const at = mapKey.indexOf("@");
42617
- const canonical2 = at === -1 ? mapKey : mapKey.slice(0, at);
42506
+ const canonical = at === -1 ? mapKey : mapKey.slice(0, at);
42618
42507
  for (const [stage, names] of Object.entries(runtime)) {
42619
- if (Array.isArray(names) && names.includes(canonical2)) {
42620
- return `org project set: ${canonical2} is still required by stage ${stage} \u2014 drop it there first (--var requiredRuntimeSecrets=...)`;
42508
+ if (Array.isArray(names) && names.includes(canonical)) {
42509
+ return `org project set: ${canonical} is still required by stage ${stage} \u2014 drop it there first (--var requiredRuntimeSecrets=...)`;
42621
42510
  }
42622
42511
  }
42623
42512
  for (const raw of build) {
42624
42513
  if (typeof raw !== "string") continue;
42625
42514
  const eq = raw.indexOf("=");
42626
42515
  const ref = eq === -1 ? raw : raw.slice(eq + 1);
42627
- if (ref === canonical2) {
42628
- return `org project set: ${canonical2} is still required by the build secret contract \u2014 drop it there first (--var requiredBuildSecrets=...)`;
42516
+ if (ref === canonical) {
42517
+ return `org project set: ${canonical} is still required by the build secret contract \u2014 drop it there first (--var requiredBuildSecrets=...)`;
42629
42518
  }
42630
42519
  }
42631
42520
  }
@@ -43933,7 +43822,7 @@ function renderDeployPortDoctor(report) {
43933
43822
  }
43934
43823
 
43935
43824
  // src/bootstrap-drift.ts
43936
- var import_node_crypto12 = require("node:crypto");
43825
+ var import_node_crypto11 = require("node:crypto");
43937
43826
  function byteComparableSeeds(manifest, cls) {
43938
43827
  return manifest.seeds.filter((s) => s.ownership === "org" && s.source === "self" && s.classes.includes(cls));
43939
43828
  }
@@ -43953,7 +43842,7 @@ function compareSeedBytes(hubContent, repoContent) {
43953
43842
  return normalize(hubContent) === normalize(repoContent) ? "match" : "drift";
43954
43843
  }
43955
43844
  function seedContentHash(content) {
43956
- return (0, import_node_crypto12.createHash)("sha256").update(content.replace(/\r\n/g, "\n"), "utf8").digest("hex");
43845
+ return (0, import_node_crypto11.createHash)("sha256").update(content.replace(/\r\n/g, "\n"), "utf8").digest("hex");
43957
43846
  }
43958
43847
  function auditRepoSeedDrift(repo, seeds, hubContents, repoReads) {
43959
43848
  const byTarget = new Map(repoReads.map((r) => [r.target, r.content]));
@@ -44130,7 +44019,7 @@ function renderPropagationReport(plan) {
44130
44019
  }
44131
44020
 
44132
44021
  // src/bootstrap-propagation-identity.ts
44133
- var import_node_crypto13 = require("node:crypto");
44022
+ var import_node_crypto12 = require("node:crypto");
44134
44023
  var PROPAGATION_BRANCH_PREFIX = "seed-propagate-";
44135
44024
  var TARGET_MARKER_NAME = "mmi-bootstrap-propagation-target";
44136
44025
  function safeBranchPart(value, maxLength, fallback) {
@@ -44143,7 +44032,7 @@ function repoSlug2(repo) {
44143
44032
  function propagationBranch(repo, target) {
44144
44033
  const repoPart = safeBranchPart(repoSlug2(repo), 32, "repo");
44145
44034
  const targetPart = safeBranchPart(target, 48, "target");
44146
- const hash = (0, import_node_crypto13.createHash)("sha256").update(repo.trim().toLowerCase()).update("\0").update(target).digest("hex").slice(0, 12);
44035
+ const hash = (0, import_node_crypto12.createHash)("sha256").update(repo.trim().toLowerCase()).update("\0").update(target).digest("hex").slice(0, 12);
44147
44036
  return `${PROPAGATION_BRANCH_PREFIX}${repoPart}-${targetPart}-${hash}`;
44148
44037
  }
44149
44038
  function legacyPropagationBranch(repo) {
@@ -44663,11 +44552,11 @@ function boardGroupingDrift(board, wantColumn, wantSwimlane) {
44663
44552
  }
44664
44553
  return problems;
44665
44554
  }
44666
- function boardCardFieldDrift(visibleFields, canonical2) {
44555
+ function boardCardFieldDrift(visibleFields, canonical) {
44667
44556
  const have = new Set(visibleFields);
44668
- const want = new Set(canonical2);
44557
+ const want = new Set(canonical);
44669
44558
  return {
44670
- missing: canonical2.filter((f) => !have.has(f)),
44559
+ missing: canonical.filter((f) => !have.has(f)),
44671
44560
  extra: visibleFields.filter((f) => !want.has(f))
44672
44561
  };
44673
44562
  }
@@ -45385,7 +45274,7 @@ function renderBootstrapVerifyReport(report) {
45385
45274
  }
45386
45275
 
45387
45276
  // src/bootstrap-seed-delivery.ts
45388
- var import_node_crypto14 = require("node:crypto");
45277
+ var import_node_crypto13 = require("node:crypto");
45389
45278
  init_github_client();
45390
45279
  var SHA = /^[a-f0-9]{40}$/;
45391
45280
  async function readSeedFile(repo, target, ref, client) {
@@ -45418,7 +45307,7 @@ async function targetedSeedPlan(repo, slug, target, baseBranch, sourceSha, clien
45418
45307
  }
45419
45308
  const baseSha = base?.object?.sha;
45420
45309
  if (!baseSha || !SHA.test(baseSha) || !SHA.test(sourceSha)) throw new Error("bootstrap apply: seed identity is unreadable");
45421
- const identity = (0, import_node_crypto14.createHash)("sha256").update(JSON.stringify([repo.toLowerCase(), target, baseSha, sourceSha])).digest("hex").slice(0, 24);
45310
+ const identity = (0, import_node_crypto13.createHash)("sha256").update(JSON.stringify([repo.toLowerCase(), target, baseSha, sourceSha])).digest("hex").slice(0, 24);
45422
45311
  const delivery = planSeedDelivery(rules, slug, baseBranch, `bootstrap-seed-${identity}`);
45423
45312
  const scoped = forcePr && delivery.mode === "direct" ? { mode: "pr", ref: `bootstrap-seed-${identity}-${slug}`, branch: `bootstrap-seed-${identity}-${slug}`, reason: "registry gate render requires review" } : delivery;
45424
45313
  return { ...scoped, baseSha, baseBranch };
@@ -47263,7 +47152,7 @@ init_github_client();
47263
47152
  init_cli_shared();
47264
47153
 
47265
47154
  // src/suite-status.ts
47266
- var import_node_crypto15 = require("node:crypto");
47155
+ var import_node_crypto14 = require("node:crypto");
47267
47156
  var SUITE_REPO = "mutmutco/MM-Work";
47268
47157
  var REPOS = {
47269
47158
  "mmi-scout": "mutmutco/MMI-Scout",
@@ -47291,7 +47180,7 @@ function parseSuiteMapping(body) {
47291
47180
  return void 0;
47292
47181
  }
47293
47182
  }
47294
- var sha256 = (b) => (0, import_node_crypto15.createHash)("sha256").update(b).digest("hex");
47183
+ var sha256 = (b) => (0, import_node_crypto14.createHash)("sha256").update(b).digest("hex");
47295
47184
  async function proveBundle(url, tag, fetchUrl) {
47296
47185
  const get = async (u) => {
47297
47186
  try {
@@ -47548,7 +47437,7 @@ async function waitSuiteDev(deps, opts) {
47548
47437
  // src/suite-train.ts
47549
47438
  var import_node_fs36 = require("node:fs");
47550
47439
  var import_node_path33 = require("node:path");
47551
- var import_node_crypto16 = require("node:crypto");
47440
+ var import_node_crypto15 = require("node:crypto");
47552
47441
 
47553
47442
  // src/kit-version.ts
47554
47443
  var parse = (v) => /^(\d+)\.(\d+)\.(\d+)(-.+)?$/.exec(typeof v === "string" ? v.trim() : "");
@@ -47650,7 +47539,7 @@ function readSuiteCut(path2) {
47650
47539
  }
47651
47540
  function writeSuiteCut(path2, record2) {
47652
47541
  (0, import_node_fs36.mkdirSync)((0, import_node_path33.dirname)(path2), { recursive: true });
47653
- const temp = `${path2}.${(0, import_node_crypto16.randomBytes)(8).toString("hex")}.tmp`;
47542
+ const temp = `${path2}.${(0, import_node_crypto15.randomBytes)(8).toString("hex")}.tmp`;
47654
47543
  try {
47655
47544
  (0, import_node_fs36.writeFileSync)(temp, JSON.stringify(record2, null, 2), { flag: "wx" });
47656
47545
  (0, import_node_fs36.renameSync)(temp, path2);
@@ -51895,7 +51784,7 @@ async function deleteMergedRemoteBranch(options) {
51895
51784
  }
51896
51785
 
51897
51786
  // src/pr-merge-queue.ts
51898
- var import_node_crypto17 = require("node:crypto");
51787
+ var import_node_crypto16 = require("node:crypto");
51899
51788
  var import_node_fs39 = require("node:fs");
51900
51789
  var import_node_os21 = require("node:os");
51901
51790
  var import_node_path36 = require("node:path");
@@ -51920,12 +51809,17 @@ async function queueGraphql(repo, fields, gh2) {
51920
51809
  if (!response.data?.repository) throw new Error("merge queue repository read failed");
51921
51810
  return response.data.repository;
51922
51811
  }
51812
+ async function readArrayPages(endpoint, gh2, error) {
51813
+ const pages = parseNdjsonLines(await gh2([endpoint, "--paginate", "--jq", "{items: .}"]));
51814
+ if (!pages.length || !pages.every((page) => Array.isArray(page?.items))) throw new Error(error);
51815
+ return pages.flatMap((page) => page.items);
51816
+ }
51923
51817
  async function hasPrMergeQueue(repo, base, gh2 = readApi) {
51924
- const pages = JSON.parse(await gh2([`repos/${repo}/rules/branches/${encodeURIComponent(base)}?per_page=100`, "--paginate", "--slurp"]));
51925
- if (!Array.isArray(pages) || !pages.every((page) => Array.isArray(page) && page.every((rule) => rule && typeof rule.type === "string"))) {
51818
+ const rules = await readArrayPages(`repos/${repo}/rules/branches/${encodeURIComponent(base)}?per_page=100`, gh2, `merge queue policy unreadable for ${repo}:${base}`);
51819
+ if (!rules.every((rule) => typeof rule?.type === "string")) {
51926
51820
  throw new Error(`merge queue policy unreadable for ${repo}:${base}`);
51927
51821
  }
51928
- if (pages.flat().some((rule) => rule.type === "merge_queue")) return true;
51822
+ if (rules.some((rule) => rule.type === "merge_queue")) return true;
51929
51823
  const result = await queueGraphql(repo, `mergeQueue(branch:${JSON.stringify(base)}) { id }`, gh2 === readApi ? actorReadApi : gh2);
51930
51824
  if (result.mergeQueue === void 0) throw new Error(`merge queue policy unreadable for ${repo}:${base}`);
51931
51825
  return result.mergeQueue !== null;
@@ -51935,7 +51829,7 @@ var ASYNC_HEADERS = ["-H", "Accept: application/vnd.github+json", "-H", "X-GitHu
51935
51829
  var UUID = /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/i;
51936
51830
  function admissionJournal(repo, pr, root) {
51937
51831
  const stateRoot = root ?? (process.platform === "win32" ? (0, import_node_path36.join)(process.env.LOCALAPPDATA || (0, import_node_path36.join)((0, import_node_os21.homedir)(), "AppData", "Local"), "MMI Future", "mmi-cli", "queue-admissions") : (0, import_node_path36.join)(process.env.XDG_STATE_HOME || (0, import_node_path36.join)((0, import_node_os21.homedir)(), ".local", "state"), "mmi-cli", "queue-admissions"));
51938
- const directory = (0, import_node_path36.join)(stateRoot, (0, import_node_crypto17.createHash)("sha256").update(`${repo.toLowerCase()}#${pr}`).digest("hex"));
51832
+ const directory = (0, import_node_path36.join)(stateRoot, (0, import_node_crypto16.createHash)("sha256").update(`${repo.toLowerCase()}#${pr}`).digest("hex"));
51939
51833
  (0, import_node_fs39.mkdirSync)(directory, { recursive: true, mode: 448 });
51940
51834
  const attempts = (0, import_node_fs39.readdirSync)(directory).map((name) => {
51941
51835
  if (!/^[1-9][0-9]*\.jsonl$/.test(name)) throw new Error("queue admission receipt directory contains an unrecognized record");
@@ -51965,7 +51859,7 @@ function admissionJournal(repo, pr, root) {
51965
51859
  receipt: attempt ? load() : void 0,
51966
51860
  create(head) {
51967
51861
  const createdAt = Date.now();
51968
- const initial = { version: 1, repo: repo.toLowerCase(), pr, head, intentId: (0, import_node_crypto17.randomUUID)(), createdAt, observedAt: createdAt, state: "dispatching" };
51862
+ const initial = { version: 1, repo: repo.toLowerCase(), pr, head, intentId: (0, import_node_crypto16.randomUUID)(), createdAt, observedAt: createdAt, state: "dispatching" };
51969
51863
  try {
51970
51864
  (0, import_node_fs39.writeFileSync)(path2(attempt + 1), JSON.stringify(initial) + "\n", { flag: "wx", mode: 384, flush: true });
51971
51865
  } catch (error) {
@@ -52168,11 +52062,10 @@ async function enqueuePrMergeQueue(pr, repo, options = {}) {
52168
52062
  merge_commit_title: metadata.mergeCommitTitle,
52169
52063
  merge_commit_message: metadata.mergeCommitMessage
52170
52064
  };
52171
- const commitsPages = JSON.parse(await read([`repos/${repo}/pulls/${pr}/commits?per_page=100`, "--paginate", "--slurp"]));
52172
- if (!Array.isArray(commitsPages) || !commitsPages.every((rows) => Array.isArray(rows) && rows.every((row) => typeof row?.commit?.message === "string"))) {
52065
+ const commits = await readArrayPages(`repos/${repo}/pulls/${pr}/commits?per_page=100`, read, `queue commit messages unreadable for PR #${pr}`);
52066
+ if (!commits.every((row) => typeof row?.commit?.message === "string")) {
52173
52067
  throw new Error(`queue commit messages unreadable for PR #${pr}`);
52174
52068
  }
52175
- const commits = commitsPages.flat();
52176
52069
  if (!commits.length || commits.length !== pull.commits?.totalCount) throw new Error(`queue commit messages incomplete for PR #${pr}; no submission occurred`);
52177
52070
  const parsed = parseRestClosingGuardInput({ state: pull.state, title: pull.title, body: pull.body }, commits, repo);
52178
52071
  parsed.closing = closing;
@@ -52187,11 +52080,11 @@ async function enqueuePrMergeQueue(pr, repo, options = {}) {
52187
52080
  },
52188
52081
  error: `queue preparation needed: ${detail}`
52189
52082
  });
52190
- const rulePages = JSON.parse(await read([`repos/${repo}/rules/branches/${encodeURIComponent(pull.baseRefName)}?per_page=100`, "--paginate", "--slurp"]));
52191
- if (!Array.isArray(rulePages) || !rulePages.every((rules) => Array.isArray(rules) && rules.every((rule) => typeof rule?.type === "string"))) {
52083
+ const rules = await readArrayPages(`repos/${repo}/rules/branches/${encodeURIComponent(pull.baseRefName)}?per_page=100`, read, "queue merge method unreadable");
52084
+ if (!rules.every((rule) => typeof rule?.type === "string")) {
52192
52085
  throw new Error("queue merge method unreadable");
52193
52086
  }
52194
- const methods = [...new Set(rulePages.flat().filter((rule) => rule.type === "merge_queue").map((rule) => rule.parameters?.merge_method))];
52087
+ const methods = [...new Set(rules.filter((rule) => rule.type === "merge_queue").map((rule) => rule.parameters?.merge_method))];
52195
52088
  let method = methods.length === 1 ? methods[0] : void 0;
52196
52089
  if (!methods.length) {
52197
52090
  const legacy = await queueGraphql(
@@ -52315,7 +52208,7 @@ function hubReleaseCiRun(env) {
52315
52208
  }
52316
52209
 
52317
52210
  // src/release-custody.ts
52318
- var import_node_crypto18 = require("node:crypto");
52211
+ var import_node_crypto17 = require("node:crypto");
52319
52212
  var import_node_fs40 = require("node:fs");
52320
52213
  var import_node_path37 = require("node:path");
52321
52214
  init_github_client();
@@ -52538,7 +52431,7 @@ var ReleaseCustodyError = class extends Error {
52538
52431
  this.name = "ReleaseCustodyError";
52539
52432
  }
52540
52433
  };
52541
- var custodyDigest = (value) => (0, import_node_crypto18.createHash)("sha256").update(value).digest("hex");
52434
+ var custodyDigest = (value) => (0, import_node_crypto17.createHash)("sha256").update(value).digest("hex");
52542
52435
  function parseCustody(raw, repo) {
52543
52436
  const s = JSON.parse(raw);
52544
52437
  if (s.schema !== "mmi-release-custody/v1" || s.repo !== repo || !s.precutId || !Number.isSafeInteger(s.revision) || s.revision < 1 || !s.controller || !Number.isSafeInteger(s.controller.runId) || s.controller.runId <= 0 || !Number.isSafeInteger(s.controller.runAttempt) || s.controller.runAttempt <= 0 || !s.controller.token || !(s.ledger === null || typeof s.ledger === "string") || !s.archives || !s.effects) {
@@ -52626,7 +52519,7 @@ var ReleaseCustodySession = class _ReleaseCustodySession {
52626
52519
  throw new ReleaseCustodyError(`previous controller run ${found.state.controller.runId} attempt ${found.state.controller.runAttempt} is not proven terminal`);
52627
52520
  }
52628
52521
  let state = {
52629
- ...found.state ?? { schema: "mmi-release-custody/v1", repo, precutId: (0, import_node_crypto18.randomUUID)(), effects: {}, ...await initialize() },
52522
+ ...found.state ?? { schema: "mmi-release-custody/v1", repo, precutId: (0, import_node_crypto17.randomUUID)(), effects: {}, ...await initialize() },
52630
52523
  revision: (found.state?.revision ?? 0) + 1,
52631
52524
  controller
52632
52525
  };
@@ -52634,44 +52527,6 @@ var ReleaseCustodySession = class _ReleaseCustodySession {
52634
52527
  const sha = await store.compareAndSet(found.sha, state);
52635
52528
  return new _ReleaseCustodySession(store, sha, state);
52636
52529
  }
52637
- /** Incident recovery must already have custody: it cannot create, migrate or replace a release. */
52638
- static async acquireExisting(store, controller, repo) {
52639
- return this.acquire(store, controller, repo, async () => {
52640
- throw new ReleaseCustodyError("incident recovery requires existing authoritative custody; no initialization or migration");
52641
- }, async (state) => {
52642
- if (Object.values(state.archives).some((a) => a.disposition === "unresolved") || Object.values(state.effects).some((e) => e.state === "intent")) {
52643
- throw new ReleaseCustodyError("unresolved custody requires read-only reconciliation before incident recovery");
52644
- }
52645
- return state;
52646
- });
52647
- }
52648
- /** A fixed incident scope survives ledger replacement and a new precut ID. Even an acknowledged
52649
- * result is spent: a new controller can observe it but never re-execute the same operation kind. */
52650
- incidentEffect(incident, kind, identity, execute) {
52651
- const operation = this.effectTail.then(async () => {
52652
- this.assertWritable();
52653
- this.assertEvidenceResolved();
52654
- if (!/^[a-z0-9-]{1,80}$/.test(incident) || !/^[a-z0-9-]{1,80}$/.test(kind)) throw new ReleaseCustodyError("invalid incident identity");
52655
- const scope = `incident:${incident}`;
52656
- const id = custodyDigest(JSON.stringify({ scope, kind }));
52657
- if (this.state.effects[id] || Object.values(this.state.effects).some((e) => e.scope === scope && e.kind === kind)) {
52658
- throw new ReleaseCustodyError("incident operation is spent; observe it without another provider write");
52659
- }
52660
- if (Object.values(this.state.effects).some((e) => e.state === "intent")) throw new ReleaseCustodyError("unresolved effect blocks another provider write");
52661
- const effect = { id, scope, kind, identity, state: "intent", startedAt: (/* @__PURE__ */ new Date()).toISOString() };
52662
- await this.change((state) => ({ ...state, effects: { ...state.effects, [id]: effect } }));
52663
- let result;
52664
- try {
52665
- result = await execute();
52666
- } catch {
52667
- throw new ReleaseCustodyError("incident request outcome is unacknowledged; intent remains spent, observation only");
52668
- }
52669
- await this.change((state) => ({ ...state, effects: { ...state.effects, [id]: { ...effect, state: "observed", result } } }));
52670
- return result;
52671
- });
52672
- this.effectTail = operation.catch(() => void 0);
52673
- return operation;
52674
- }
52675
52530
  assertWritable() {
52676
52531
  if (this.poison) throw this.poison;
52677
52532
  }
@@ -52725,7 +52580,7 @@ var ReleaseCustodySession = class _ReleaseCustodySession {
52725
52580
  proof: { kind: "ledger-lifecycle", controller: state.controller }
52726
52581
  };
52727
52582
  }
52728
- return { ...state, ledger: raw, archives, precutId: state.ledger && !raw ? (0, import_node_crypto18.randomUUID)() : state.precutId };
52583
+ return { ...state, ledger: raw, archives, precutId: state.ledger && !raw ? (0, import_node_crypto17.randomUUID)() : state.precutId };
52729
52584
  });
52730
52585
  }
52731
52586
  async preserveLocal(raw) {
@@ -52832,7 +52687,12 @@ async function commandIdentity(file, args, run, repo) {
52832
52687
  const fields = Object.fromEntries(args.flatMap((arg, i) => ["-f", "--field", "-F", "--raw-field"].includes(arg) ? [args[i + 1].split(/=(.*)/s).slice(0, 2)] : []));
52833
52688
  const ref = args.includes("--ref") ? args[args.indexOf("--ref") + 1] : "main";
52834
52689
  const sha = (await run("git", ["rev-parse", `origin/${ref}`])).trim();
52835
- const before = JSON.parse(await run("gh", ["api", `repos/${repo}/actions/workflows/${args[2]}/runs?event=workflow_dispatch&per_page=100`]));
52690
+ const before = JSON.parse(await run("gh", [
52691
+ "api",
52692
+ `repos/${repo}/actions/workflows/${args[2]}/runs?event=workflow_dispatch&per_page=100`,
52693
+ "--jq",
52694
+ "{workflow_runs: [.workflow_runs[] | {id}]}"
52695
+ ]));
52836
52696
  return { kind: "workflow-dispatch", identity: { repo, workflow: args[2], fields, sha, beforeRunIds: before.workflow_runs.map((row) => row.id) } };
52837
52697
  }
52838
52698
  if (file === "gh" && args[0] === "run" && args[1] === "rerun") {
@@ -52914,7 +52774,7 @@ function withHubReleaseCustody(deps) {
52914
52774
  if (!authority.ok || !authority.train || authority.authenticatedDelegation !== true) {
52915
52775
  throw new ReleaseCustodyError("repository custody requires the server-verified owner-triggered train session");
52916
52776
  }
52917
- const controller = { ...runIdentity, token: (0, import_node_crypto18.randomUUID)() };
52777
+ const controller = { ...runIdentity, token: (0, import_node_crypto17.randomUUID)() };
52918
52778
  const raw = localRaw(path2);
52919
52779
  const requiredContexts = () => discoverRequiredCheckContexts(
52920
52780
  deps,
@@ -53619,7 +53479,7 @@ init_github_quota();
53619
53479
 
53620
53480
  // src/issue-commands.ts
53621
53481
  var import_node_fs43 = require("node:fs");
53622
- var import_node_crypto19 = require("node:crypto");
53482
+ var import_node_crypto18 = require("node:crypto");
53623
53483
  init_cli_shared();
53624
53484
  init_clean_exit();
53625
53485
  init_error_codes();
@@ -54092,7 +53952,7 @@ function rowIdempotencyKey(batchKey, spec) {
54092
53952
  const identity = `${spec.type}
54093
53953
  ${spec.title.trim()}
54094
53954
  ${spec.body ?? ""}`;
54095
- const hash = (0, import_node_crypto19.createHash)("sha256").update(identity).digest("hex").slice(0, 16);
53955
+ const hash = (0, import_node_crypto18.createHash)("sha256").update(identity).digest("hex").slice(0, 16);
54096
53956
  return `${batchKey}:${hash}`;
54097
53957
  }
54098
53958
  var BATCH_SPEC_KEYS = /* @__PURE__ */ new Set(["type", "title", "body", "priority", "labels", "label", "parent", "repo", "surface"]);
@@ -59656,7 +59516,7 @@ function releaseFollowUpLegs(result, projectInfoSync) {
59656
59516
  legs.push(...runs2.map((run) => ({
59657
59517
  leg: run.workflow,
59658
59518
  status: followUpLegStatus(run.conclusion),
59659
- ...run.conclusion === "failure" ? { error: run.workflow === "jerv-gateway" ? result.dispatch : `${run.workflow} reported failure` } : {}
59519
+ ...run.conclusion === "failure" ? { error: run.workflow === "jerv-gateway" ? result.dispatch : run.runUrlNote ?? `${run.workflow} reported failure` } : {}
59660
59520
  })));
59661
59521
  } else if (result.deployStatus && result.deployStatus !== "success") {
59662
59522
  legs.push({
@@ -63793,9 +63653,9 @@ function formatExplainCommand(cmd, rootName) {
63793
63653
  return lines2.join("\n").trimEnd();
63794
63654
  }
63795
63655
  function formatExplainGroup(cmd, rootName) {
63796
- const canonical2 = (node) => node.path;
63656
+ const canonical = (node) => node.path;
63797
63657
  const lines2 = [
63798
- `${rootName} ${canonical2(cmd)}${cmd.description ? ` \u2014 ${cmd.description}` : ""}`,
63658
+ `${rootName} ${canonical(cmd)}${cmd.description ? ` \u2014 ${cmd.description}` : ""}`,
63799
63659
  `Category: ${cmd.category} \xB7 Discovery: ${cmd.discovery}`,
63800
63660
  ""
63801
63661
  ];
@@ -63806,7 +63666,7 @@ function formatExplainGroup(cmd, rootName) {
63806
63666
  const name = arg.variadic ? `${arg.name}...` : arg.name;
63807
63667
  return arg.required ? `<${name}>` : `[${name}]`;
63808
63668
  }).join(" ");
63809
- lines2.push(` ${canonical2(child2)}${args ? ` ${args}` : ""}${child2.description ? ` \u2014 ${child2.description}` : ""}`);
63669
+ lines2.push(` ${canonical(child2)}${args ? ` ${args}` : ""}${child2.description ? ` \u2014 ${child2.description}` : ""}`);
63810
63670
  }
63811
63671
  return lines2.join("\n");
63812
63672
  }
@@ -66565,14 +66425,14 @@ vercel preview (${preview.branch}): ${d.state}${d.url ? ` \u2014 ${d.url}` : ""}
66565
66425
  }
66566
66426
 
66567
66427
  // src/tenant-artifact.ts
66568
- var import_node_crypto20 = require("node:crypto");
66428
+ var import_node_crypto19 = require("node:crypto");
66569
66429
  var import_node_fs58 = require("node:fs");
66570
66430
  var import_promises11 = require("node:fs/promises");
66571
66431
  var import_node_path53 = require("node:path");
66572
66432
  var ARTIFACT_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
66573
66433
  var MAX_BYTES2 = 5 * 1024 * 1024 * 1024;
66574
66434
  async function sha256File(path2) {
66575
- const hash = (0, import_node_crypto20.createHash)("sha256");
66435
+ const hash = (0, import_node_crypto19.createHash)("sha256");
66576
66436
  for await (const chunk of (0, import_node_fs58.createReadStream)(path2)) hash.update(chunk);
66577
66437
  return hash.digest("hex");
66578
66438
  }
@@ -67164,13 +67024,13 @@ async function executeWaveLand(plan, deps) {
67164
67024
 
67165
67025
  // src/dist-drift.ts
67166
67026
  var import_node_child_process22 = require("node:child_process");
67167
- var import_node_crypto22 = require("node:crypto");
67027
+ var import_node_crypto21 = require("node:crypto");
67168
67028
  var import_node_fs61 = require("node:fs");
67169
67029
  var import_node_os26 = require("node:os");
67170
67030
  var import_node_path56 = require("node:path");
67171
67031
 
67172
67032
  // ../scripts/distribution-digest.mjs
67173
- var import_node_crypto21 = require("node:crypto");
67033
+ var import_node_crypto20 = require("node:crypto");
67174
67034
  var import_node_fs60 = require("node:fs");
67175
67035
  var import_node_path55 = require("node:path");
67176
67036
  var slash = (value) => value.replaceAll("\\", "/");
@@ -67183,7 +67043,7 @@ function repoPath(root, declaredPath, label) {
67183
67043
  return target;
67184
67044
  }
67185
67045
  function digestFiles(files) {
67186
- const hash = (0, import_node_crypto21.createHash)("sha256");
67046
+ const hash = (0, import_node_crypto20.createHash)("sha256");
67187
67047
  for (const file of [...files].sort((a, b) => a.relative.localeCompare(b.relative))) {
67188
67048
  const content = file.stat.isSymbolicLink() ? Buffer.from((0, import_node_fs60.readlinkSync)(file.absolute), "utf8") : (0, import_node_fs60.readFileSync)(file.absolute);
67189
67049
  hash.update(file.relative, "utf8");
@@ -67214,7 +67074,7 @@ var DIST_ARTIFACTS = [
67214
67074
  ];
67215
67075
  var BOM_DIST_TREE_ID = "mmi-cli-dist";
67216
67076
  var ABSENT = "absent";
67217
- var sha2562 = (bytes) => `sha256:${(0, import_node_crypto22.createHash)("sha256").update(bytes).digest("hex")}`;
67077
+ var sha2562 = (bytes) => `sha256:${(0, import_node_crypto21.createHash)("sha256").update(bytes).digest("hex")}`;
67218
67078
  function artifactDrift(path2, committedBytes, rebuiltBytes) {
67219
67079
  const committed = committedBytes ? sha2562(committedBytes) : ABSENT;
67220
67080
  const rebuiltExpected = rebuiltBytes ? sha2562(rebuiltBytes) : ABSENT;
@@ -68549,8 +68409,8 @@ function resolveParseHint() {
68549
68409
  const candidates = unknownCommandCandidates(parent, allCommandPaths());
68550
68410
  const tail = unknownCommandTail(process.argv.slice(2), lastUnknownCommand);
68551
68411
  const path3 = lastUnknownCommand ? suggestCommandPath(lastUnknownCommand, candidates, tail) : void 0;
68552
- const canonical2 = path3 ? canonicalPathFor(path3) ?? path3 : void 0;
68553
- if (canonical2) return `(did you mean \`mmi-cli ${canonical2}\`? ${DISCOVERY_HINT})`;
68412
+ const canonical = path3 ? canonicalPathFor(path3) ?? path3 : void 0;
68413
+ if (canonical) return `(did you mean \`mmi-cli ${canonical}\`? ${DISCOVERY_HINT})`;
68554
68414
  return parent ? `(${DISCOVERY_HINT})` : STALE_HINT;
68555
68415
  }
68556
68416
  if (lastParseErrorKind !== "bad-arguments") return STALE_HINT;
@@ -68569,10 +68429,10 @@ function positionalCommandEntries(house) {
68569
68429
  if (commandMetadata(node)?.category !== "internal") {
68570
68430
  const args = node.registeredArguments ?? [];
68571
68431
  const path2 = commandPath3(node);
68572
- const canonical2 = path2 ? canonicalPathFor(path2) ?? path2 : "";
68573
- if (args[0] && canonical2 && (house === void 0 || houseForPath(canonical2) === house)) {
68432
+ const canonical = path2 ? canonicalPathFor(path2) ?? path2 : "";
68433
+ if (args[0] && canonical && (house === void 0 || houseForPath(canonical) === house)) {
68574
68434
  acc.push({
68575
- path: canonical2,
68435
+ path: canonical,
68576
68436
  names: [node.name(), ...node.aliases()],
68577
68437
  argName: args[0].name(),
68578
68438
  ownFlags: commandOwnLongFlags(node)
@@ -68587,8 +68447,8 @@ function positionalCommandEntries(house) {
68587
68447
  function excessArgumentCorrection(extra, argv) {
68588
68448
  const invoked = resolveCommandFromArgv(program2, [...argv]);
68589
68449
  if (!invoked || extra.length !== 1) return void 0;
68590
- const canonical2 = canonicalPathFor(commandPath3(invoked)) ?? commandPath3(invoked);
68591
- const entries = positionalCommandEntries(houseForPath(canonical2)).filter((e) => e.path !== canonical2);
68450
+ const canonical = canonicalPathFor(commandPath3(invoked)) ?? commandPath3(invoked);
68451
+ const entries = positionalCommandEntries(houseForPath(canonical)).filter((e) => e.path !== canonical);
68592
68452
  const sibling = siblingTakingPositional(invoked.name(), entries);
68593
68453
  return sibling ? correctedPositionalCommand(sibling, extra[0], argv) : void 0;
68594
68454
  }
package/cli/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mutmutco/cli",
3
- "version": "4.5.230",
3
+ "version": "4.5.232",
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.5.230",
3
+ "version": "4.5.232",
4
4
  "description": "MMI workflow skills and org gates delivery.",
5
5
  "author": {
6
6
  "name": "MMI Future",