nexus-agents 8.19.1 → 8.20.1

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-3ZPDWKYB.js +7 -0
  2. package/dist/{chunk-KRCRVSGX.js → chunk-4EJYBLQ3.js} +3 -3
  3. package/dist/{chunk-XLNP4ODH.js → chunk-DXE2DPT5.js} +2 -2
  4. package/dist/{chunk-UDYR3ME6.js → chunk-RHKJBVSU.js} +3 -3
  5. package/dist/{chunk-PY6BGMNJ.js → chunk-UIML3UMD.js} +311 -49
  6. package/dist/chunk-UIML3UMD.js.map +1 -0
  7. package/dist/{chunk-DRD2GXBT.js → chunk-WYVDJAL5.js} +2 -2
  8. package/dist/cli.js +7 -7
  9. package/dist/{consensus-vote-QOWW7RVO.js → consensus-vote-O2MXPQRL.js} +4 -4
  10. package/dist/{improvement-review-MVM36CQM.js → improvement-review-NJS2HJPQ.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-524NSTT3.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-CKTLFPT3.js.map → chunk-3ZPDWKYB.js.map} +0 -0
  19. /package/dist/{chunk-KRCRVSGX.js.map → chunk-4EJYBLQ3.js.map} +0 -0
  20. /package/dist/{chunk-XLNP4ODH.js.map → chunk-DXE2DPT5.js.map} +0 -0
  21. /package/dist/{chunk-UDYR3ME6.js.map → chunk-RHKJBVSU.js.map} +0 -0
  22. /package/dist/{chunk-DRD2GXBT.js.map → chunk-WYVDJAL5.js.map} +0 -0
  23. /package/dist/{consensus-vote-QOWW7RVO.js.map → consensus-vote-O2MXPQRL.js.map} +0 -0
  24. /package/dist/{improvement-review-MVM36CQM.js.map → improvement-review-NJS2HJPQ.js.map} +0 -0
  25. /package/dist/{setup-data-dir-TKS6JEYR.js.map → setup-data-dir-524NSTT3.js.map} +0 -0
@@ -0,0 +1,7 @@
1
+ // src/version.ts
2
+ var VERSION = true ? "8.20.1" : "dev";
3
+
4
+ export {
5
+ VERSION
6
+ };
7
+ //# sourceMappingURL=chunk-3ZPDWKYB.js.map
@@ -6,7 +6,7 @@ import {
6
6
  } from "./chunk-OQB3XC5O.js";
7
7
  import {
8
8
  VERSION
9
- } from "./chunk-CKTLFPT3.js";
9
+ } from "./chunk-3ZPDWKYB.js";
10
10
  import {
11
11
  capitalize
12
12
  } from "./chunk-7LP6VJRP.js";
@@ -1220,7 +1220,7 @@ async function runDoctorFix(result) {
1220
1220
  writeLine2("\u2500".repeat(40));
1221
1221
  let fixCount = 0;
1222
1222
  if (!result.dataDirectory.rootExists || result.dataDirectory.subdirectories.some((d) => !d.exists || !d.writable)) {
1223
- const { initDataDirectories: initDataDirectories2, describeDataDirFix: describeDataDirFix2 } = await import("./setup-data-dir-TKS6JEYR.js");
1223
+ const { initDataDirectories: initDataDirectories2, describeDataDirFix: describeDataDirFix2 } = await import("./setup-data-dir-524NSTT3.js");
1224
1224
  const outcome = describeDataDirFix2(initDataDirectories2());
1225
1225
  writeLine2(outcome.line);
1226
1226
  if (outcome.counted) fixCount++;
@@ -1322,4 +1322,4 @@ export {
1322
1322
  startStdioServer,
1323
1323
  closeServer
1324
1324
  };
1325
- //# sourceMappingURL=chunk-KRCRVSGX.js.map
1325
+ //# sourceMappingURL=chunk-4EJYBLQ3.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-CKTLFPT3.js";
3
+ } from "./chunk-3ZPDWKYB.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-DXE2DPT5.js.map
@@ -23,10 +23,10 @@ import {
23
23
  toolSuccessStructured,
24
24
  withProgressHeartbeat,
25
25
  wrapToolWithTimeout
26
- } from "./chunk-XLNP4ODH.js";
26
+ } from "./chunk-DXE2DPT5.js";
27
27
  import {
28
28
  VERSION
29
- } from "./chunk-CKTLFPT3.js";
29
+ } from "./chunk-3ZPDWKYB.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-RHKJBVSU.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-4EJYBLQ3.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-RHKJBVSU.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-WYVDJAL5.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-DXE2DPT5.js";
96
96
  import {
97
97
  createAuditTrail,
98
98
  createGraphAuditBridge,
@@ -22446,6 +22446,14 @@ function mapInputDefinition(input) {
22446
22446
  if (input.default !== void 0) inputDef.default = input.default;
22447
22447
  return inputDef;
22448
22448
  }
22449
+ function mapPartialContextBudget(source) {
22450
+ const budget = {};
22451
+ if (source.system !== void 0) budget.system = source.system;
22452
+ if (source.task !== void 0) budget.task = source.task;
22453
+ if (source.active !== void 0) budget.active = source.active;
22454
+ if (source.reserved !== void 0) budget.reserved = source.reserved;
22455
+ return budget;
22456
+ }
22449
22457
  function mapWorkflowStep(step) {
22450
22458
  const stepDef = {
22451
22459
  id: step.id,
@@ -22458,6 +22466,8 @@ function mapWorkflowStep(step) {
22458
22466
  if (step.retries !== void 0) stepDef.retries = step.retries;
22459
22467
  if (step.timeout !== void 0) stepDef.timeout = step.timeout;
22460
22468
  if (step.condition !== void 0) stepDef.condition = step.condition;
22469
+ if (step.contextBudget !== void 0)
22470
+ stepDef.contextBudget = mapPartialContextBudget(step.contextBudget);
22461
22471
  return stepDef;
22462
22472
  }
22463
22473
  function toWorkflowDefinition(data) {
@@ -22469,6 +22479,7 @@ function toWorkflowDefinition(data) {
22469
22479
  };
22470
22480
  if (data.description !== void 0) workflow.description = data.description;
22471
22481
  if (data.timeout !== void 0) workflow.timeout = data.timeout;
22482
+ if (data.defaultBudget !== void 0) workflow.defaultBudget = data.defaultBudget;
22472
22483
  return workflow;
22473
22484
  }
22474
22485
  async function loadWorkflowFile(filePath, allowedRoot = process.cwd()) {
@@ -45808,6 +45819,149 @@ function checkpointToResult(state) {
45808
45819
  return result;
45809
45820
  }
45810
45821
 
45822
+ // src/pipeline/iterative-consensus.ts
45823
+ var defaultLogger3 = createLogger({ component: "iterative-consensus" });
45824
+ var DEFAULT_MAX_ITERATIONS = 3;
45825
+ var DEFAULT_MAX_NO_QUORUM_RETRIES = 2;
45826
+ var DEFAULT_MAX_PROPOSAL_LENGTH = 4e3;
45827
+ var DEFAULT_STRATEGY = "higher_order";
45828
+ var DEFAULT_PREFIX = "pipeline";
45829
+ async function voteWithQuorumRecovery(state) {
45830
+ const outcome = await retryNoQuorumVote(
45831
+ () => executeSingleVote(state.plan, state.config, state.log),
45832
+ state.maxNoQuorumRetries,
45833
+ (attempt, vote) => {
45834
+ state.log.warn("Vote reached no_quorum \u2014 re-running the missing voice (bounded)", {
45835
+ attempt,
45836
+ maxNoQuorumRetries: state.maxNoQuorumRetries,
45837
+ reason: vote.reason
45838
+ });
45839
+ emitPipelineStageEvent(state.prefix, "vote", "started");
45840
+ }
45841
+ );
45842
+ return outcome.vote;
45843
+ }
45844
+ async function retryNoQuorumVote(executeVote, maxRetries = DEFAULT_MAX_NO_QUORUM_RETRIES, onRetry) {
45845
+ let vote = await executeVote();
45846
+ let retries = 0;
45847
+ while (vote.kind === "no_quorum" && retries < maxRetries) {
45848
+ retries++;
45849
+ onRetry?.(retries, vote);
45850
+ vote = await executeVote();
45851
+ }
45852
+ return { vote, retries };
45853
+ }
45854
+ async function runOneIteration(state, iteration) {
45855
+ state.log.info("Consensus iteration", { iteration });
45856
+ emitPipelineStageEvent(state.prefix, "vote", "started");
45857
+ state.lastVote = await voteWithQuorumRecovery(state);
45858
+ const iterMs = getTimeProvider().now() - state.globalStart;
45859
+ const accepted = isVoteAccepted(state.lastVote);
45860
+ emitPipelineStageEvent(state.prefix, "vote", accepted ? "completed" : "failed", {
45861
+ durationMs: iterMs
45862
+ });
45863
+ if (accepted) {
45864
+ return { result: { vote: state.lastVote, iterations: iteration, durationMs: iterMs } };
45865
+ }
45866
+ if (state.lastVote.kind === "no_quorum") {
45867
+ const terminalVote = {
45868
+ kind: "no_quorum",
45869
+ reason: `vote could not reach quorum after ${String(state.maxNoQuorumRetries)} re-run(s): ${state.lastVote.reason}`,
45870
+ approvalPercentage: state.lastVote.approvalPercentage
45871
+ };
45872
+ return { terminal: { vote: terminalVote, iterations: iteration, durationMs: iterMs } };
45873
+ }
45874
+ return {};
45875
+ }
45876
+ async function runIterativeConsensus(initialPlan, revisePlan, config) {
45877
+ const maxIter = config?.maxIterations ?? DEFAULT_MAX_ITERATIONS;
45878
+ const state = {
45879
+ plan: initialPlan,
45880
+ lastVote: void 0,
45881
+ config,
45882
+ log: config?.logger ?? defaultLogger3,
45883
+ prefix: config?.pipelinePrefix ?? DEFAULT_PREFIX,
45884
+ globalStart: getTimeProvider().now(),
45885
+ maxNoQuorumRetries: config?.maxNoQuorumRetries ?? DEFAULT_MAX_NO_QUORUM_RETRIES
45886
+ };
45887
+ return runConsensusLoop(state, maxIter, revisePlan);
45888
+ }
45889
+ async function runConsensusLoop(state, maxIter, revisePlan) {
45890
+ for (let i = 0; i < maxIter; i++) {
45891
+ const outcome = await runOneIteration(state, i + 1);
45892
+ const done = outcome.result ?? outcome.terminal;
45893
+ if (done !== void 0) return done;
45894
+ await maybeRevise(state, i, maxIter, revisePlan);
45895
+ }
45896
+ return buildExhaustedResult(state, maxIter);
45897
+ }
45898
+ function isVoteAccepted(vote) {
45899
+ return vote.kind === "approved" || vote.kind === "conditional_go";
45900
+ }
45901
+ function extractFeedback2(vote) {
45902
+ if (vote === void 0) return "";
45903
+ return vote.kind === "rejected" ? vote.feedback : "";
45904
+ }
45905
+ async function maybeRevise(state, iteration, maxIter, revisePlan) {
45906
+ if (iteration >= maxIter - 1) return;
45907
+ state.log.info("Vote rejected, revising plan", { iteration: iteration + 1 });
45908
+ state.plan = await revisePlan(state.plan, extractFeedback2(state.lastVote));
45909
+ }
45910
+ function buildExhaustedResult(state, maxIter) {
45911
+ const totalMs = getTimeProvider().now() - state.globalStart;
45912
+ const fallback = {
45913
+ kind: "rejected",
45914
+ feedback: "No votes executed",
45915
+ approvalPercentage: 0
45916
+ };
45917
+ return { vote: state.lastVote ?? fallback, iterations: maxIter, durationMs: totalMs };
45918
+ }
45919
+ function buildVotingInput(plan, config) {
45920
+ const c = config ?? {};
45921
+ const maxLen = c.maxProposalLength ?? DEFAULT_MAX_PROPOSAL_LENGTH;
45922
+ return {
45923
+ proposal: plan.slice(0, maxLen),
45924
+ strategy: c.strategy ?? DEFAULT_STRATEGY,
45925
+ simulateVotes: c.simulateVotes ?? false,
45926
+ quickMode: c.quickMode ?? false,
45927
+ // #4138: this reusable helper opts into absolute_quorum by default.
45928
+ errorPolicy: c.errorPolicy ?? "absolute_quorum"
45929
+ };
45930
+ }
45931
+ async function executeSingleVote(plan, config, log) {
45932
+ try {
45933
+ const { executeVoting } = await import("./consensus-vote-O2MXPQRL.js");
45934
+ const input = buildVotingInput(plan, config);
45935
+ const result = await executeVoting(input, log);
45936
+ return parseVotingResult(result);
45937
+ } catch (error) {
45938
+ const msg = error instanceof Error ? error.message : String(error);
45939
+ log.warn("Vote execution failed, treating as rejected", { error: msg });
45940
+ return {
45941
+ kind: "rejected",
45942
+ feedback: `Vote infrastructure failed \u2014 no consensus produced: ${msg}`,
45943
+ approvalPercentage: 0
45944
+ };
45945
+ }
45946
+ }
45947
+ function parseVotingResult(result) {
45948
+ const total = Math.max(1, result.result.voteCounts.approve + result.result.voteCounts.reject);
45949
+ const pct = result.result.voteCounts.approve / total * 100;
45950
+ const decision = result.decision ?? (result.result.outcome === "approved" ? "approved" : "rejected");
45951
+ if (decision === "approved") {
45952
+ return { kind: "approved", approvalPercentage: pct };
45953
+ }
45954
+ if (decision === "no_quorum") {
45955
+ return {
45956
+ kind: "no_quorum",
45957
+ reason: "vote could not reach quorum (a voice was missing)",
45958
+ approvalPercentage: pct
45959
+ };
45960
+ }
45961
+ const feedback = result.votes.filter((v) => v.vote.decision !== "approve").map((v) => v.vote.reasoning).join("\n");
45962
+ return { kind: "rejected", feedback, approvalPercentage: pct };
45963
+ }
45964
+
45811
45965
  // src/orchestration/qa-loop.ts
45812
45966
  var logger40 = createLogger({ component: "qa-loop" });
45813
45967
  var DEFAULT_MAX_QA_ITERATIONS = 3;
@@ -45882,6 +46036,11 @@ async function runDevPipelineInner(task, stages, options, sid, prior) {
45882
46036
  logger41.info("Dry run \u2014 stopping after plan+vote");
45883
46037
  return buildDryRunResult(planResult);
45884
46038
  }
46039
+ if (planResult.planStatus !== void 0) {
46040
+ const result2 = buildPlanFailureResult(planResult);
46041
+ applyPipelineHindsight(bm, task, sid, result2);
46042
+ return result2;
46043
+ }
45885
46044
  enforceConsensusExecutePolicy(sid, trustTier, auditLogger);
45886
46045
  const tasks = await runOrResumeDecompose(prior, planResult.plan, stages, {
45887
46046
  conditional: planResult.conditional,
@@ -46083,7 +46242,25 @@ function buildDryRunResult(planResult) {
46083
46242
  // "the security gate rejected this"; `securityRan: false` says it never ran.
46084
46243
  securityPassed: false,
46085
46244
  securityRan: false,
46086
- ...planResult.plan.trim() === "" ? { planStatus: "empty" } : {}
46245
+ ...planResult.planStatus !== void 0 ? { planStatus: planResult.planStatus } : {},
46246
+ ...planResult.planVoteReason !== void 0 ? { planVoteReason: planResult.planVoteReason } : {},
46247
+ ...planResult.planVoteApprovalPercentage !== void 0 ? { planVoteApprovalPercentage: planResult.planVoteApprovalPercentage } : {},
46248
+ ...planResult.planVoteFeedback !== void 0 ? { planVoteFeedback: planResult.planVoteFeedback } : {}
46249
+ };
46250
+ }
46251
+ function buildPlanFailureResult(planResult) {
46252
+ return {
46253
+ completed: false,
46254
+ plan: planResult.plan,
46255
+ tasks: [],
46256
+ voteIterations: planResult.iterations,
46257
+ qaIterations: 0,
46258
+ securityPassed: false,
46259
+ securityRan: false,
46260
+ planStatus: planResult.planStatus ?? "unapproved",
46261
+ ...planResult.planVoteReason !== void 0 ? { planVoteReason: planResult.planVoteReason } : {},
46262
+ ...planResult.planVoteApprovalPercentage !== void 0 ? { planVoteApprovalPercentage: planResult.planVoteApprovalPercentage } : {},
46263
+ ...planResult.planVoteFeedback !== void 0 ? { planVoteFeedback: planResult.planVoteFeedback } : {}
46087
46264
  };
46088
46265
  }
46089
46266
  async function resolveResearch(prior, task, stages, options) {
@@ -46115,7 +46292,7 @@ async function runPlanningPhase(task, stages, prior, options) {
46115
46292
  sid,
46116
46293
  limits: resolveIterationLimits(options)
46117
46294
  });
46118
- if (sid !== void 0) {
46295
+ if (sid !== void 0 && planResult.planStatus === void 0) {
46119
46296
  saveStageCheckpoint(sid, "plan", {
46120
46297
  type: "plan",
46121
46298
  text: planResult.plan,
@@ -46123,7 +46300,7 @@ async function runPlanningPhase(task, stages, prior, options) {
46123
46300
  });
46124
46301
  saveStageCheckpoint(sid, "vote", {
46125
46302
  type: "vote",
46126
- approved: planResult.conditional || planResult.iterations > 0,
46303
+ approved: true,
46127
46304
  conditional: planResult.conditional,
46128
46305
  conditions: planResult.conditions,
46129
46306
  caveats: planResult.caveats,
@@ -46239,6 +46416,7 @@ function extractConditionalMeta(vote) {
46239
46416
  async function planVoteLoop(task, research, stages, sessionId, limits) {
46240
46417
  let feedback;
46241
46418
  let plan = "";
46419
+ let lastRejected;
46242
46420
  for (let i = 1; i <= limits.vote; i++) {
46243
46421
  plan = await withStep(
46244
46422
  { name: `plan (i=${String(i)})`, attrs: { iteration: i } },
@@ -46246,37 +46424,100 @@ async function planVoteLoop(task, research, stages, sessionId, limits) {
46246
46424
  );
46247
46425
  if (plan.trim() === "") {
46248
46426
  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;
46427
+ return {
46428
+ plan: "",
46429
+ iterations: i,
46430
+ conditional: false,
46431
+ conditions: [],
46432
+ caveats: [],
46433
+ planStatus: "empty"
46434
+ };
46435
+ }
46436
+ const voteOutcome = await retryNoQuorumVote(
46437
+ () => runPlanVote(plan, research, stages, i),
46438
+ DEFAULT_MAX_NO_QUORUM_RETRIES,
46439
+ (attempt, vote2) => {
46440
+ logQuorumRetry(attempt, vote2, sessionId);
46259
46441
  }
46260
46442
  );
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 };
46443
+ const vote = voteOutcome.vote;
46444
+ if (vote.kind === "approved" || vote.kind === "conditional_go") {
46445
+ return buildApprovedPlanResult(plan, i, vote, sessionId);
46270
46446
  }
46271
- feedback = getVoteFeedback(vote);
46447
+ if (vote.kind === "no_quorum") {
46448
+ return buildNoQuorumPlanResult(plan, i, vote, voteOutcome.retries);
46449
+ }
46450
+ lastRejected = vote;
46451
+ feedback = vote.feedback;
46272
46452
  logger41.warn("Plan rejected, iterating", {
46273
46453
  iteration: i,
46274
46454
  feedback: feedback.slice(0, 200),
46275
46455
  sessionId
46276
46456
  });
46277
46457
  }
46278
- logger41.warn("Max vote iterations reached, proceeding with last plan", { sessionId });
46279
- return { plan, iterations: limits.vote, conditional: false, conditions: [], caveats: [] };
46458
+ return buildUnapprovedPlanResult(plan, limits.vote, lastRejected, sessionId);
46459
+ }
46460
+ function buildApprovedPlanResult(plan, iterations, vote, sessionId) {
46461
+ const meta = extractConditionalMeta(vote);
46462
+ logger41.info("Plan approved", {
46463
+ iteration: iterations,
46464
+ approval: vote.approvalPercentage,
46465
+ sessionId,
46466
+ ...meta
46467
+ });
46468
+ return { plan, iterations, ...meta };
46469
+ }
46470
+ async function runPlanVote(plan, research, stages, iteration) {
46471
+ return withStep({ name: `vote (i=${String(iteration)})`, attrs: { iteration } }, async (ctx) => {
46472
+ const result = await stages.vote(plan, research);
46473
+ const label = result.kind === "no_quorum" ? "no_quorum" : isApproved(result) ? "approved" : "rejected";
46474
+ ctx.setSummary(`${String(Math.round(result.approvalPercentage))}% ${label}`);
46475
+ return result;
46476
+ });
46477
+ }
46478
+ function logQuorumRetry(attempt, vote, sessionId) {
46479
+ logger41.warn("Plan vote reached no_quorum \u2014 re-running the same plan", {
46480
+ attempt,
46481
+ maxNoQuorumRetries: DEFAULT_MAX_NO_QUORUM_RETRIES,
46482
+ reason: vote.reason,
46483
+ sessionId
46484
+ });
46485
+ }
46486
+ function buildNoQuorumPlanResult(plan, iterations, vote, retries) {
46487
+ logger41.warn("Plan vote could not reach quorum \u2014 stopping", {
46488
+ retries,
46489
+ reason: vote.reason
46490
+ });
46491
+ return {
46492
+ plan,
46493
+ iterations,
46494
+ conditional: false,
46495
+ conditions: [],
46496
+ caveats: [],
46497
+ planStatus: "no_quorum",
46498
+ planVoteReason: vote.reason,
46499
+ planVoteApprovalPercentage: vote.approvalPercentage
46500
+ };
46501
+ }
46502
+ function buildUnapprovedPlanResult(plan, iterations, vote, sessionId) {
46503
+ const feedback = vote?.feedback ?? "No plan vote was run";
46504
+ const approvalPercentage = vote?.approvalPercentage ?? 0;
46505
+ logger41.warn("Max vote iterations reached without plan approval \u2014 stopping", {
46506
+ sessionId,
46507
+ iterations,
46508
+ approvalPercentage,
46509
+ feedback: feedback.slice(0, 200)
46510
+ });
46511
+ return {
46512
+ plan,
46513
+ iterations,
46514
+ conditional: false,
46515
+ conditions: [],
46516
+ caveats: [],
46517
+ planStatus: "unapproved",
46518
+ planVoteApprovalPercentage: approvalPercentage,
46519
+ planVoteFeedback: feedback
46520
+ };
46280
46521
  }
46281
46522
  async function implementSingleTask(task, stages, limits) {
46282
46523
  let currentTask = { ...task, status: "in_progress" };
@@ -47461,13 +47702,15 @@ ${contextBlock}`;
47461
47702
  const strategy = config.votingStrategy ?? "higher_order";
47462
47703
  await postProgress(config, "Vote", `Running consensus with ${strategy} strategy...`);
47463
47704
  try {
47464
- const { executeVoting } = await import("./consensus-vote-QOWW7RVO.js");
47705
+ const { executeVoting } = await import("./consensus-vote-O2MXPQRL.js");
47465
47706
  const votingResult = await executeVoting(
47466
47707
  {
47467
47708
  proposal: buildVoteProposal(plan, research),
47468
47709
  strategy,
47469
47710
  simulateVotes: config.simulateVotes ?? false,
47470
- quickMode: config.quickMode ?? false
47711
+ quickMode: config.quickMode ?? false,
47712
+ // #5506: plan approval requires the requested panel, not only survivors.
47713
+ errorPolicy: "absolute_quorum"
47471
47714
  },
47472
47715
  logger45
47473
47716
  );
@@ -50439,6 +50682,37 @@ function classifyDispatchError(err2) {
50439
50682
  return err2 instanceof MetaDispatchError && err2.code === "no_executor" ? "business" : "internal";
50440
50683
  }
50441
50684
 
50685
+ // src/mcp/tools/run-tool-incomplete.ts
50686
+ var FAILURE_PREFIX = "Engine reported failure:";
50687
+ function describePlanFailure(record) {
50688
+ if (record["planStatus"] === "empty") {
50689
+ return `${FAILURE_PREFIX} the planner returned no plan, so nothing was built`;
50690
+ }
50691
+ if (record["planStatus"] === "unapproved") {
50692
+ const iterations = typeof record["voteIterations"] === "number" ? String(record["voteIterations"]) : "an unknown number of";
50693
+ return `${FAILURE_PREFIX} the panel did not approve the plan after ${iterations} iterations`;
50694
+ }
50695
+ if (record["planStatus"] === "no_quorum") {
50696
+ const reason = typeof record["planVoteReason"] === "string" ? record["planVoteReason"] : "no reason was recorded";
50697
+ return `${FAILURE_PREFIX} the plan vote could not reach quorum: ${reason}`;
50698
+ }
50699
+ return void 0;
50700
+ }
50701
+ function describeIncompletePipeline(record) {
50702
+ const planFailure = describePlanFailure(record);
50703
+ if (planFailure !== void 0) return planFailure;
50704
+ if (record["securityRan"] === true) {
50705
+ return `${FAILURE_PREFIX} the security gate rejected the change`;
50706
+ }
50707
+ if (record["securityRan"] === false) {
50708
+ if (typeof record["securityNote"] === "string") {
50709
+ return `${FAILURE_PREFIX} the security scan did not run (${record["securityNote"]}); the change is blocked until it does`;
50710
+ }
50711
+ return `${FAILURE_PREFIX} the run stopped before the security gate, which never ran`;
50712
+ }
50713
+ return `${FAILURE_PREFIX} the dev pipeline did not complete`;
50714
+ }
50715
+
50442
50716
  // src/orchestration/meta-orchestrator.ts
50443
50717
  import { randomUUID as randomUUID14 } from "node:crypto";
50444
50718
 
@@ -51395,6 +51669,9 @@ function buildStructuredOutput(result, simulated) {
51395
51669
  // here, so they never reached the MCP surface.
51396
51670
  ...result.securityRan !== void 0 ? { securityRan: result.securityRan } : {},
51397
51671
  ...result.planStatus !== void 0 ? { planStatus: result.planStatus } : {},
51672
+ ...result.planVoteReason !== void 0 ? { planVoteReason: result.planVoteReason } : {},
51673
+ ...result.planVoteApprovalPercentage !== void 0 ? { planVoteApprovalPercentage: result.planVoteApprovalPercentage } : {},
51674
+ ...result.planVoteFeedback !== void 0 ? { planVoteFeedback: result.planVoteFeedback } : {},
51398
51675
  // #4993 added `dryRun` to DevPipelineResult for exactly the reason above —
51399
51676
  // it says `completed: false` was the request, not a fault — and then did
51400
51677
  // not list it here either. Same omission, same function, under the comment
@@ -51895,27 +52172,11 @@ function detectEngineFailure(result) {
51895
52172
  return { message: `Engine reported failure: ${detail}` };
51896
52173
  }
51897
52174
  if (record["completed"] === false) {
51898
- if (record["dryRun"] === true && record["planStatus"] !== "empty") return null;
52175
+ if (record["dryRun"] === true && record["planStatus"] === void 0) return null;
51899
52176
  return { message: describeIncompletePipeline(record), detail: record };
51900
52177
  }
51901
52178
  return null;
51902
52179
  }
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
52180
  async function executeRunBody(input, logger57, trustTier, gatewayAdapters) {
51920
52181
  try {
51921
52182
  const exec2 = await executeGoal(input, {
@@ -56074,6 +56335,7 @@ export {
56074
56335
  loadCheckpointState,
56075
56336
  cleanupCheckpoint2 as cleanupCheckpoint,
56076
56337
  checkpointToResult,
56338
+ runIterativeConsensus,
56077
56339
  runDevPipeline,
56078
56340
  flushPipelineMemory,
56079
56341
  createAgentStages,
@@ -56125,4 +56387,4 @@ export {
56125
56387
  shutdownFeedbackSubscriber,
56126
56388
  createEventBusBridge
56127
56389
  };
56128
- //# sourceMappingURL=chunk-PY6BGMNJ.js.map
56390
+ //# sourceMappingURL=chunk-UIML3UMD.js.map