nexus-agents 8.19.1 → 8.20.0

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.
Files changed (25) hide show
  1. package/dist/{chunk-UDYR3ME6.js → chunk-ASUB4LSV.js} +3 -3
  2. package/dist/chunk-AWFW6FD4.js +7 -0
  3. package/dist/{chunk-XLNP4ODH.js → chunk-FZXMMOBQ.js} +2 -2
  4. package/dist/{chunk-PY6BGMNJ.js → chunk-PIWFHJSU.js} +300 -49
  5. package/dist/chunk-PIWFHJSU.js.map +1 -0
  6. package/dist/{chunk-DRD2GXBT.js → chunk-W5M6VFDH.js} +2 -2
  7. package/dist/{chunk-KRCRVSGX.js → chunk-XSRCJ7FA.js} +3 -3
  8. package/dist/cli.js +7 -7
  9. package/dist/{consensus-vote-QOWW7RVO.js → consensus-vote-X4XXWGDD.js} +4 -4
  10. package/dist/{improvement-review-MVM36CQM.js → improvement-review-I7NBW7QO.js} +4 -4
  11. package/dist/index.d.ts +18 -13
  12. package/dist/index.js +7 -137
  13. package/dist/index.js.map +1 -1
  14. package/dist/{setup-data-dir-TKS6JEYR.js → setup-data-dir-JHZPDCPY.js} +3 -3
  15. package/package.json +1 -1
  16. package/dist/chunk-CKTLFPT3.js +0 -7
  17. package/dist/chunk-PY6BGMNJ.js.map +0 -1
  18. /package/dist/{chunk-UDYR3ME6.js.map → chunk-ASUB4LSV.js.map} +0 -0
  19. /package/dist/{chunk-CKTLFPT3.js.map → chunk-AWFW6FD4.js.map} +0 -0
  20. /package/dist/{chunk-XLNP4ODH.js.map → chunk-FZXMMOBQ.js.map} +0 -0
  21. /package/dist/{chunk-DRD2GXBT.js.map → chunk-W5M6VFDH.js.map} +0 -0
  22. /package/dist/{chunk-KRCRVSGX.js.map → chunk-XSRCJ7FA.js.map} +0 -0
  23. /package/dist/{consensus-vote-QOWW7RVO.js.map → consensus-vote-X4XXWGDD.js.map} +0 -0
  24. /package/dist/{improvement-review-MVM36CQM.js.map → improvement-review-I7NBW7QO.js.map} +0 -0
  25. /package/dist/{setup-data-dir-TKS6JEYR.js.map → setup-data-dir-JHZPDCPY.js.map} +0 -0
@@ -23,10 +23,10 @@ import {
23
23
  toolSuccessStructured,
24
24
  withProgressHeartbeat,
25
25
  wrapToolWithTimeout
26
- } from "./chunk-XLNP4ODH.js";
26
+ } from "./chunk-FZXMMOBQ.js";
27
27
  import {
28
28
  VERSION
29
- } from "./chunk-CKTLFPT3.js";
29
+ } from "./chunk-AWFW6FD4.js";
30
30
  import {
31
31
  assessPanelIndependence,
32
32
  countDistinctModels,
@@ -7205,4 +7205,4 @@ export {
7205
7205
  CONSENSUS_VOTE_TOOL_SCHEMA,
7206
7206
  registerConsensusVoteTool
7207
7207
  };
7208
- //# sourceMappingURL=chunk-UDYR3ME6.js.map
7208
+ //# sourceMappingURL=chunk-ASUB4LSV.js.map
@@ -0,0 +1,7 @@
1
+ // src/version.ts
2
+ var VERSION = true ? "8.20.0" : "dev";
3
+
4
+ export {
5
+ VERSION
6
+ };
7
+ //# sourceMappingURL=chunk-AWFW6FD4.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-CKTLFPT3.js";
3
+ } from "./chunk-AWFW6FD4.js";
4
4
  import {
5
5
  emitClawGuardViolation
6
6
  } from "./chunk-TCTKOFNL.js";
@@ -2246,4 +2246,4 @@ export {
2246
2246
  VOTING_THRESHOLDS,
2247
2247
  ConsensusMetricsSchema
2248
2248
  };
2249
- //# sourceMappingURL=chunk-XLNP4ODH.js.map
2249
+ //# sourceMappingURL=chunk-FZXMMOBQ.js.map
@@ -21,7 +21,7 @@ import {
21
21
  import {
22
22
  DEFAULT_TASK_TTL_MS,
23
23
  clampTaskTtl
24
- } from "./chunk-KRCRVSGX.js";
24
+ } from "./chunk-XSRCJ7FA.js";
25
25
  import {
26
26
  executeExpert
27
27
  } from "./chunk-C7CSLODO.js";
@@ -48,7 +48,7 @@ import {
48
48
  simulationDeniedResult,
49
49
  toJobSummary,
50
50
  writeJobCancelled
51
- } from "./chunk-UDYR3ME6.js";
51
+ } from "./chunk-ASUB4LSV.js";
52
52
  import {
53
53
  allOf
54
54
  } from "./chunk-OQB3XC5O.js";
@@ -67,7 +67,7 @@ import {
67
67
  } from "./chunk-ZUK5BG3Q.js";
68
68
  import {
69
69
  withPrerequisite
70
- } from "./chunk-DRD2GXBT.js";
70
+ } from "./chunk-W5M6VFDH.js";
71
71
  import {
72
72
  NOOP_NOTIFIER,
73
73
  RateLimiter,
@@ -92,7 +92,7 @@ import {
92
92
  withAuditTrail,
93
93
  withProgressHeartbeat,
94
94
  wrapToolWithTimeout
95
- } from "./chunk-XLNP4ODH.js";
95
+ } from "./chunk-FZXMMOBQ.js";
96
96
  import {
97
97
  createAuditTrail,
98
98
  createGraphAuditBridge,
@@ -45808,6 +45808,149 @@ function checkpointToResult(state) {
45808
45808
  return result;
45809
45809
  }
45810
45810
 
45811
+ // src/pipeline/iterative-consensus.ts
45812
+ var defaultLogger3 = createLogger({ component: "iterative-consensus" });
45813
+ var DEFAULT_MAX_ITERATIONS = 3;
45814
+ var DEFAULT_MAX_NO_QUORUM_RETRIES = 2;
45815
+ var DEFAULT_MAX_PROPOSAL_LENGTH = 4e3;
45816
+ var DEFAULT_STRATEGY = "higher_order";
45817
+ var DEFAULT_PREFIX = "pipeline";
45818
+ async function voteWithQuorumRecovery(state) {
45819
+ const outcome = await retryNoQuorumVote(
45820
+ () => executeSingleVote(state.plan, state.config, state.log),
45821
+ state.maxNoQuorumRetries,
45822
+ (attempt, vote) => {
45823
+ state.log.warn("Vote reached no_quorum \u2014 re-running the missing voice (bounded)", {
45824
+ attempt,
45825
+ maxNoQuorumRetries: state.maxNoQuorumRetries,
45826
+ reason: vote.reason
45827
+ });
45828
+ emitPipelineStageEvent(state.prefix, "vote", "started");
45829
+ }
45830
+ );
45831
+ return outcome.vote;
45832
+ }
45833
+ async function retryNoQuorumVote(executeVote, maxRetries = DEFAULT_MAX_NO_QUORUM_RETRIES, onRetry) {
45834
+ let vote = await executeVote();
45835
+ let retries = 0;
45836
+ while (vote.kind === "no_quorum" && retries < maxRetries) {
45837
+ retries++;
45838
+ onRetry?.(retries, vote);
45839
+ vote = await executeVote();
45840
+ }
45841
+ return { vote, retries };
45842
+ }
45843
+ async function runOneIteration(state, iteration) {
45844
+ state.log.info("Consensus iteration", { iteration });
45845
+ emitPipelineStageEvent(state.prefix, "vote", "started");
45846
+ state.lastVote = await voteWithQuorumRecovery(state);
45847
+ const iterMs = getTimeProvider().now() - state.globalStart;
45848
+ const accepted = isVoteAccepted(state.lastVote);
45849
+ emitPipelineStageEvent(state.prefix, "vote", accepted ? "completed" : "failed", {
45850
+ durationMs: iterMs
45851
+ });
45852
+ if (accepted) {
45853
+ return { result: { vote: state.lastVote, iterations: iteration, durationMs: iterMs } };
45854
+ }
45855
+ if (state.lastVote.kind === "no_quorum") {
45856
+ const terminalVote = {
45857
+ kind: "no_quorum",
45858
+ reason: `vote could not reach quorum after ${String(state.maxNoQuorumRetries)} re-run(s): ${state.lastVote.reason}`,
45859
+ approvalPercentage: state.lastVote.approvalPercentage
45860
+ };
45861
+ return { terminal: { vote: terminalVote, iterations: iteration, durationMs: iterMs } };
45862
+ }
45863
+ return {};
45864
+ }
45865
+ async function runIterativeConsensus(initialPlan, revisePlan, config) {
45866
+ const maxIter = config?.maxIterations ?? DEFAULT_MAX_ITERATIONS;
45867
+ const state = {
45868
+ plan: initialPlan,
45869
+ lastVote: void 0,
45870
+ config,
45871
+ log: config?.logger ?? defaultLogger3,
45872
+ prefix: config?.pipelinePrefix ?? DEFAULT_PREFIX,
45873
+ globalStart: getTimeProvider().now(),
45874
+ maxNoQuorumRetries: config?.maxNoQuorumRetries ?? DEFAULT_MAX_NO_QUORUM_RETRIES
45875
+ };
45876
+ return runConsensusLoop(state, maxIter, revisePlan);
45877
+ }
45878
+ async function runConsensusLoop(state, maxIter, revisePlan) {
45879
+ for (let i = 0; i < maxIter; i++) {
45880
+ const outcome = await runOneIteration(state, i + 1);
45881
+ const done = outcome.result ?? outcome.terminal;
45882
+ if (done !== void 0) return done;
45883
+ await maybeRevise(state, i, maxIter, revisePlan);
45884
+ }
45885
+ return buildExhaustedResult(state, maxIter);
45886
+ }
45887
+ function isVoteAccepted(vote) {
45888
+ return vote.kind === "approved" || vote.kind === "conditional_go";
45889
+ }
45890
+ function extractFeedback2(vote) {
45891
+ if (vote === void 0) return "";
45892
+ return vote.kind === "rejected" ? vote.feedback : "";
45893
+ }
45894
+ async function maybeRevise(state, iteration, maxIter, revisePlan) {
45895
+ if (iteration >= maxIter - 1) return;
45896
+ state.log.info("Vote rejected, revising plan", { iteration: iteration + 1 });
45897
+ state.plan = await revisePlan(state.plan, extractFeedback2(state.lastVote));
45898
+ }
45899
+ function buildExhaustedResult(state, maxIter) {
45900
+ const totalMs = getTimeProvider().now() - state.globalStart;
45901
+ const fallback = {
45902
+ kind: "rejected",
45903
+ feedback: "No votes executed",
45904
+ approvalPercentage: 0
45905
+ };
45906
+ return { vote: state.lastVote ?? fallback, iterations: maxIter, durationMs: totalMs };
45907
+ }
45908
+ function buildVotingInput(plan, config) {
45909
+ const c = config ?? {};
45910
+ const maxLen = c.maxProposalLength ?? DEFAULT_MAX_PROPOSAL_LENGTH;
45911
+ return {
45912
+ proposal: plan.slice(0, maxLen),
45913
+ strategy: c.strategy ?? DEFAULT_STRATEGY,
45914
+ simulateVotes: c.simulateVotes ?? false,
45915
+ quickMode: c.quickMode ?? false,
45916
+ // #4138: this reusable helper opts into absolute_quorum by default.
45917
+ errorPolicy: c.errorPolicy ?? "absolute_quorum"
45918
+ };
45919
+ }
45920
+ async function executeSingleVote(plan, config, log) {
45921
+ try {
45922
+ const { executeVoting } = await import("./consensus-vote-X4XXWGDD.js");
45923
+ const input = buildVotingInput(plan, config);
45924
+ const result = await executeVoting(input, log);
45925
+ return parseVotingResult(result);
45926
+ } catch (error) {
45927
+ const msg = error instanceof Error ? error.message : String(error);
45928
+ log.warn("Vote execution failed, treating as rejected", { error: msg });
45929
+ return {
45930
+ kind: "rejected",
45931
+ feedback: `Vote infrastructure failed \u2014 no consensus produced: ${msg}`,
45932
+ approvalPercentage: 0
45933
+ };
45934
+ }
45935
+ }
45936
+ function parseVotingResult(result) {
45937
+ const total = Math.max(1, result.result.voteCounts.approve + result.result.voteCounts.reject);
45938
+ const pct = result.result.voteCounts.approve / total * 100;
45939
+ const decision = result.decision ?? (result.result.outcome === "approved" ? "approved" : "rejected");
45940
+ if (decision === "approved") {
45941
+ return { kind: "approved", approvalPercentage: pct };
45942
+ }
45943
+ if (decision === "no_quorum") {
45944
+ return {
45945
+ kind: "no_quorum",
45946
+ reason: "vote could not reach quorum (a voice was missing)",
45947
+ approvalPercentage: pct
45948
+ };
45949
+ }
45950
+ const feedback = result.votes.filter((v) => v.vote.decision !== "approve").map((v) => v.vote.reasoning).join("\n");
45951
+ return { kind: "rejected", feedback, approvalPercentage: pct };
45952
+ }
45953
+
45811
45954
  // src/orchestration/qa-loop.ts
45812
45955
  var logger40 = createLogger({ component: "qa-loop" });
45813
45956
  var DEFAULT_MAX_QA_ITERATIONS = 3;
@@ -45882,6 +46025,11 @@ async function runDevPipelineInner(task, stages, options, sid, prior) {
45882
46025
  logger41.info("Dry run \u2014 stopping after plan+vote");
45883
46026
  return buildDryRunResult(planResult);
45884
46027
  }
46028
+ if (planResult.planStatus !== void 0) {
46029
+ const result2 = buildPlanFailureResult(planResult);
46030
+ applyPipelineHindsight(bm, task, sid, result2);
46031
+ return result2;
46032
+ }
45885
46033
  enforceConsensusExecutePolicy(sid, trustTier, auditLogger);
45886
46034
  const tasks = await runOrResumeDecompose(prior, planResult.plan, stages, {
45887
46035
  conditional: planResult.conditional,
@@ -46083,7 +46231,25 @@ function buildDryRunResult(planResult) {
46083
46231
  // "the security gate rejected this"; `securityRan: false` says it never ran.
46084
46232
  securityPassed: false,
46085
46233
  securityRan: false,
46086
- ...planResult.plan.trim() === "" ? { planStatus: "empty" } : {}
46234
+ ...planResult.planStatus !== void 0 ? { planStatus: planResult.planStatus } : {},
46235
+ ...planResult.planVoteReason !== void 0 ? { planVoteReason: planResult.planVoteReason } : {},
46236
+ ...planResult.planVoteApprovalPercentage !== void 0 ? { planVoteApprovalPercentage: planResult.planVoteApprovalPercentage } : {},
46237
+ ...planResult.planVoteFeedback !== void 0 ? { planVoteFeedback: planResult.planVoteFeedback } : {}
46238
+ };
46239
+ }
46240
+ function buildPlanFailureResult(planResult) {
46241
+ return {
46242
+ completed: false,
46243
+ plan: planResult.plan,
46244
+ tasks: [],
46245
+ voteIterations: planResult.iterations,
46246
+ qaIterations: 0,
46247
+ securityPassed: false,
46248
+ securityRan: false,
46249
+ planStatus: planResult.planStatus ?? "unapproved",
46250
+ ...planResult.planVoteReason !== void 0 ? { planVoteReason: planResult.planVoteReason } : {},
46251
+ ...planResult.planVoteApprovalPercentage !== void 0 ? { planVoteApprovalPercentage: planResult.planVoteApprovalPercentage } : {},
46252
+ ...planResult.planVoteFeedback !== void 0 ? { planVoteFeedback: planResult.planVoteFeedback } : {}
46087
46253
  };
46088
46254
  }
46089
46255
  async function resolveResearch(prior, task, stages, options) {
@@ -46115,7 +46281,7 @@ async function runPlanningPhase(task, stages, prior, options) {
46115
46281
  sid,
46116
46282
  limits: resolveIterationLimits(options)
46117
46283
  });
46118
- if (sid !== void 0) {
46284
+ if (sid !== void 0 && planResult.planStatus === void 0) {
46119
46285
  saveStageCheckpoint(sid, "plan", {
46120
46286
  type: "plan",
46121
46287
  text: planResult.plan,
@@ -46123,7 +46289,7 @@ async function runPlanningPhase(task, stages, prior, options) {
46123
46289
  });
46124
46290
  saveStageCheckpoint(sid, "vote", {
46125
46291
  type: "vote",
46126
- approved: planResult.conditional || planResult.iterations > 0,
46292
+ approved: true,
46127
46293
  conditional: planResult.conditional,
46128
46294
  conditions: planResult.conditions,
46129
46295
  caveats: planResult.caveats,
@@ -46239,6 +46405,7 @@ function extractConditionalMeta(vote) {
46239
46405
  async function planVoteLoop(task, research, stages, sessionId, limits) {
46240
46406
  let feedback;
46241
46407
  let plan = "";
46408
+ let lastRejected;
46242
46409
  for (let i = 1; i <= limits.vote; i++) {
46243
46410
  plan = await withStep(
46244
46411
  { name: `plan (i=${String(i)})`, attrs: { iteration: i } },
@@ -46246,37 +46413,100 @@ async function planVoteLoop(task, research, stages, sessionId, limits) {
46246
46413
  );
46247
46414
  if (plan.trim() === "") {
46248
46415
  logger41.warn("Planner returned no plan \u2014 stopping before vote", { iteration: i, sessionId });
46249
- return { plan: "", iterations: i, conditional: false, conditions: [], caveats: [] };
46250
- }
46251
- const vote = await withStep(
46252
- { name: `vote (i=${String(i)})`, attrs: { iteration: i } },
46253
- async (ctx) => {
46254
- const r = await stages.vote(plan, research);
46255
- ctx.setSummary(
46256
- `${String(Math.round(r.approvalPercentage))}% ${isApproved(r) ? "approved" : "rejected"}`
46257
- );
46258
- return r;
46416
+ return {
46417
+ plan: "",
46418
+ iterations: i,
46419
+ conditional: false,
46420
+ conditions: [],
46421
+ caveats: [],
46422
+ planStatus: "empty"
46423
+ };
46424
+ }
46425
+ const voteOutcome = await retryNoQuorumVote(
46426
+ () => runPlanVote(plan, research, stages, i),
46427
+ DEFAULT_MAX_NO_QUORUM_RETRIES,
46428
+ (attempt, vote2) => {
46429
+ logQuorumRetry(attempt, vote2, sessionId);
46259
46430
  }
46260
46431
  );
46261
- if (isApproved(vote)) {
46262
- const meta = extractConditionalMeta(vote);
46263
- logger41.info("Plan approved", {
46264
- iteration: i,
46265
- approval: vote.approvalPercentage,
46266
- sessionId,
46267
- ...meta
46268
- });
46269
- return { plan, iterations: i, ...meta };
46432
+ const vote = voteOutcome.vote;
46433
+ if (vote.kind === "approved" || vote.kind === "conditional_go") {
46434
+ return buildApprovedPlanResult(plan, i, vote, sessionId);
46435
+ }
46436
+ if (vote.kind === "no_quorum") {
46437
+ return buildNoQuorumPlanResult(plan, i, vote, voteOutcome.retries);
46270
46438
  }
46271
- feedback = getVoteFeedback(vote);
46439
+ lastRejected = vote;
46440
+ feedback = vote.feedback;
46272
46441
  logger41.warn("Plan rejected, iterating", {
46273
46442
  iteration: i,
46274
46443
  feedback: feedback.slice(0, 200),
46275
46444
  sessionId
46276
46445
  });
46277
46446
  }
46278
- logger41.warn("Max vote iterations reached, proceeding with last plan", { sessionId });
46279
- return { plan, iterations: limits.vote, conditional: false, conditions: [], caveats: [] };
46447
+ return buildUnapprovedPlanResult(plan, limits.vote, lastRejected, sessionId);
46448
+ }
46449
+ function buildApprovedPlanResult(plan, iterations, vote, sessionId) {
46450
+ const meta = extractConditionalMeta(vote);
46451
+ logger41.info("Plan approved", {
46452
+ iteration: iterations,
46453
+ approval: vote.approvalPercentage,
46454
+ sessionId,
46455
+ ...meta
46456
+ });
46457
+ return { plan, iterations, ...meta };
46458
+ }
46459
+ async function runPlanVote(plan, research, stages, iteration) {
46460
+ return withStep({ name: `vote (i=${String(iteration)})`, attrs: { iteration } }, async (ctx) => {
46461
+ const result = await stages.vote(plan, research);
46462
+ const label = result.kind === "no_quorum" ? "no_quorum" : isApproved(result) ? "approved" : "rejected";
46463
+ ctx.setSummary(`${String(Math.round(result.approvalPercentage))}% ${label}`);
46464
+ return result;
46465
+ });
46466
+ }
46467
+ function logQuorumRetry(attempt, vote, sessionId) {
46468
+ logger41.warn("Plan vote reached no_quorum \u2014 re-running the same plan", {
46469
+ attempt,
46470
+ maxNoQuorumRetries: DEFAULT_MAX_NO_QUORUM_RETRIES,
46471
+ reason: vote.reason,
46472
+ sessionId
46473
+ });
46474
+ }
46475
+ function buildNoQuorumPlanResult(plan, iterations, vote, retries) {
46476
+ logger41.warn("Plan vote could not reach quorum \u2014 stopping", {
46477
+ retries,
46478
+ reason: vote.reason
46479
+ });
46480
+ return {
46481
+ plan,
46482
+ iterations,
46483
+ conditional: false,
46484
+ conditions: [],
46485
+ caveats: [],
46486
+ planStatus: "no_quorum",
46487
+ planVoteReason: vote.reason,
46488
+ planVoteApprovalPercentage: vote.approvalPercentage
46489
+ };
46490
+ }
46491
+ function buildUnapprovedPlanResult(plan, iterations, vote, sessionId) {
46492
+ const feedback = vote?.feedback ?? "No plan vote was run";
46493
+ const approvalPercentage = vote?.approvalPercentage ?? 0;
46494
+ logger41.warn("Max vote iterations reached without plan approval \u2014 stopping", {
46495
+ sessionId,
46496
+ iterations,
46497
+ approvalPercentage,
46498
+ feedback: feedback.slice(0, 200)
46499
+ });
46500
+ return {
46501
+ plan,
46502
+ iterations,
46503
+ conditional: false,
46504
+ conditions: [],
46505
+ caveats: [],
46506
+ planStatus: "unapproved",
46507
+ planVoteApprovalPercentage: approvalPercentage,
46508
+ planVoteFeedback: feedback
46509
+ };
46280
46510
  }
46281
46511
  async function implementSingleTask(task, stages, limits) {
46282
46512
  let currentTask = { ...task, status: "in_progress" };
@@ -47461,13 +47691,15 @@ ${contextBlock}`;
47461
47691
  const strategy = config.votingStrategy ?? "higher_order";
47462
47692
  await postProgress(config, "Vote", `Running consensus with ${strategy} strategy...`);
47463
47693
  try {
47464
- const { executeVoting } = await import("./consensus-vote-QOWW7RVO.js");
47694
+ const { executeVoting } = await import("./consensus-vote-X4XXWGDD.js");
47465
47695
  const votingResult = await executeVoting(
47466
47696
  {
47467
47697
  proposal: buildVoteProposal(plan, research),
47468
47698
  strategy,
47469
47699
  simulateVotes: config.simulateVotes ?? false,
47470
- quickMode: config.quickMode ?? false
47700
+ quickMode: config.quickMode ?? false,
47701
+ // #5506: plan approval requires the requested panel, not only survivors.
47702
+ errorPolicy: "absolute_quorum"
47471
47703
  },
47472
47704
  logger45
47473
47705
  );
@@ -50439,6 +50671,37 @@ function classifyDispatchError(err2) {
50439
50671
  return err2 instanceof MetaDispatchError && err2.code === "no_executor" ? "business" : "internal";
50440
50672
  }
50441
50673
 
50674
+ // src/mcp/tools/run-tool-incomplete.ts
50675
+ var FAILURE_PREFIX = "Engine reported failure:";
50676
+ function describePlanFailure(record) {
50677
+ if (record["planStatus"] === "empty") {
50678
+ return `${FAILURE_PREFIX} the planner returned no plan, so nothing was built`;
50679
+ }
50680
+ if (record["planStatus"] === "unapproved") {
50681
+ const iterations = typeof record["voteIterations"] === "number" ? String(record["voteIterations"]) : "an unknown number of";
50682
+ return `${FAILURE_PREFIX} the panel did not approve the plan after ${iterations} iterations`;
50683
+ }
50684
+ if (record["planStatus"] === "no_quorum") {
50685
+ const reason = typeof record["planVoteReason"] === "string" ? record["planVoteReason"] : "no reason was recorded";
50686
+ return `${FAILURE_PREFIX} the plan vote could not reach quorum: ${reason}`;
50687
+ }
50688
+ return void 0;
50689
+ }
50690
+ function describeIncompletePipeline(record) {
50691
+ const planFailure = describePlanFailure(record);
50692
+ if (planFailure !== void 0) return planFailure;
50693
+ if (record["securityRan"] === true) {
50694
+ return `${FAILURE_PREFIX} the security gate rejected the change`;
50695
+ }
50696
+ if (record["securityRan"] === false) {
50697
+ if (typeof record["securityNote"] === "string") {
50698
+ return `${FAILURE_PREFIX} the security scan did not run (${record["securityNote"]}); the change is blocked until it does`;
50699
+ }
50700
+ return `${FAILURE_PREFIX} the run stopped before the security gate, which never ran`;
50701
+ }
50702
+ return `${FAILURE_PREFIX} the dev pipeline did not complete`;
50703
+ }
50704
+
50442
50705
  // src/orchestration/meta-orchestrator.ts
50443
50706
  import { randomUUID as randomUUID14 } from "node:crypto";
50444
50707
 
@@ -51395,6 +51658,9 @@ function buildStructuredOutput(result, simulated) {
51395
51658
  // here, so they never reached the MCP surface.
51396
51659
  ...result.securityRan !== void 0 ? { securityRan: result.securityRan } : {},
51397
51660
  ...result.planStatus !== void 0 ? { planStatus: result.planStatus } : {},
51661
+ ...result.planVoteReason !== void 0 ? { planVoteReason: result.planVoteReason } : {},
51662
+ ...result.planVoteApprovalPercentage !== void 0 ? { planVoteApprovalPercentage: result.planVoteApprovalPercentage } : {},
51663
+ ...result.planVoteFeedback !== void 0 ? { planVoteFeedback: result.planVoteFeedback } : {},
51398
51664
  // #4993 added `dryRun` to DevPipelineResult for exactly the reason above —
51399
51665
  // it says `completed: false` was the request, not a fault — and then did
51400
51666
  // not list it here either. Same omission, same function, under the comment
@@ -51895,27 +52161,11 @@ function detectEngineFailure(result) {
51895
52161
  return { message: `Engine reported failure: ${detail}` };
51896
52162
  }
51897
52163
  if (record["completed"] === false) {
51898
- if (record["dryRun"] === true && record["planStatus"] !== "empty") return null;
52164
+ if (record["dryRun"] === true && record["planStatus"] === void 0) return null;
51899
52165
  return { message: describeIncompletePipeline(record), detail: record };
51900
52166
  }
51901
52167
  return null;
51902
52168
  }
51903
- function describeIncompletePipeline(record) {
51904
- const prefix = "Engine reported failure:";
51905
- if (record["planStatus"] === "empty") {
51906
- return `${prefix} the planner returned no plan, so nothing was built`;
51907
- }
51908
- if (record["securityRan"] === true) {
51909
- return `${prefix} the security gate rejected the change`;
51910
- }
51911
- if (record["securityRan"] === false) {
51912
- if (typeof record["securityNote"] === "string") {
51913
- return `${prefix} the security scan did not run (${record["securityNote"]}); the change is blocked until it does`;
51914
- }
51915
- return `${prefix} the run stopped before the security gate, which never ran`;
51916
- }
51917
- return `${prefix} the dev pipeline did not complete`;
51918
- }
51919
52169
  async function executeRunBody(input, logger57, trustTier, gatewayAdapters) {
51920
52170
  try {
51921
52171
  const exec2 = await executeGoal(input, {
@@ -56074,6 +56324,7 @@ export {
56074
56324
  loadCheckpointState,
56075
56325
  cleanupCheckpoint2 as cleanupCheckpoint,
56076
56326
  checkpointToResult,
56327
+ runIterativeConsensus,
56077
56328
  runDevPipeline,
56078
56329
  flushPipelineMemory,
56079
56330
  createAgentStages,
@@ -56125,4 +56376,4 @@ export {
56125
56376
  shutdownFeedbackSubscriber,
56126
56377
  createEventBusBridge
56127
56378
  };
56128
- //# sourceMappingURL=chunk-PY6BGMNJ.js.map
56379
+ //# sourceMappingURL=chunk-PIWFHJSU.js.map