nexus-agents 2.150.3 → 2.151.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.
@@ -18,7 +18,7 @@ import {
18
18
  DEFAULT_TASK_TTL_MS,
19
19
  DEFAULT_TOOL_RATE_LIMITS,
20
20
  clampTaskTtl
21
- } from "./chunk-DFK6H3KT.js";
21
+ } from "./chunk-O6PPXOH6.js";
22
22
  import {
23
23
  executeExpert
24
24
  } from "./chunk-JYHSZDKL.js";
@@ -41,7 +41,7 @@ import {
41
41
  toJobSummary,
42
42
  warnIfSimulatedOutsideTests,
43
43
  writeJobCancelled
44
- } from "./chunk-SF3AM3SY.js";
44
+ } from "./chunk-UIL37D2V.js";
45
45
  import {
46
46
  normalizeTopicToCanonical,
47
47
  synthesizeResearch
@@ -43446,7 +43446,7 @@ ${contextBlock}`;
43446
43446
  const strategy = config.votingStrategy ?? "higher_order";
43447
43447
  await postProgress(config, "Vote", `Running consensus with ${strategy} strategy...`);
43448
43448
  try {
43449
- const { executeVoting } = await import("./consensus-vote-3R7MNO26.js");
43449
+ const { executeVoting } = await import("./consensus-vote-72AX6HNF.js");
43450
43450
  const votingResult = await executeVoting(
43451
43451
  {
43452
43452
  proposal: buildVoteProposal(plan, research),
@@ -44417,6 +44417,20 @@ var PrReviewInputSchema = z91.object({
44417
44417
  "40-hex base commit sha the reviewed diff was computed from (Option-C binding, #4031)"
44418
44418
  ),
44419
44419
  simulate: z91.boolean().default(false).describe("Use simulated voters (testing only; never ship live with this true)"),
44420
+ /**
44421
+ * Error policy (#4132). `standard` (default) keeps the pre-#4132 aggregation:
44422
+ * an errored voter is simply excluded from the panel. `absolute_quorum` gates
44423
+ * the verified-approve verdict on a COMPLETE, error-free panel with the
44424
+ * contrarian (catfish) present and approving — any errored voter (especially
44425
+ * catfish) degrades the verdict to a recoverable `{ decision: 'abstain',
44426
+ * verified: false }` (the no_quorum analogue; `PrReviewAggregate` has no
44427
+ * `no_quorum` state), so an induced voter error can never manufacture a
44428
+ * verified approve. A genuine `request_changes` blocker still wins (Tiers 1-2
44429
+ * run first).
44430
+ */
44431
+ errorPolicy: z91.enum(["standard", "absolute_quorum"]).default("standard").describe(
44432
+ "Error policy (#4132). 'standard' (default): errored voters excluded. 'absolute_quorum': any errored voter \u2014 esp. the contrarian \u2014 degrades a would-be approve to a recoverable abstain (verified:false); never manufactures a verified approve from an induced error."
44433
+ ),
44420
44434
  /**
44421
44435
  * Dispatch mode (#3731). `sync` (default) runs the 5-voter panel inline and
44422
44436
  * returns the result — but a live fan-out can exceed the MCP request timeout.
@@ -44433,7 +44447,7 @@ function mapVoteDecisionToPrDecision(voteDecision) {
44433
44447
  return voteDecision;
44434
44448
  }
44435
44449
  var SOFT_BLOCK_REQUEST_CHANGES_THRESHOLD = 3;
44436
- function aggregatePrDecisions(reviews) {
44450
+ function aggregatePrDecisions(reviews, errorPolicy = "standard") {
44437
44451
  const valid = reviews.filter((r) => r.source !== "error");
44438
44452
  if (valid.length === 0) return { decision: "abstain", verified: true };
44439
44453
  const hasVerifiedBlocker = valid.some(
@@ -44445,10 +44459,31 @@ function aggregatePrDecisions(reviews) {
44445
44459
  return { decision: "request_changes", verified: false };
44446
44460
  }
44447
44461
  if (valid.every((r) => r.decision === "approve")) {
44462
+ if (errorPolicy === "absolute_quorum") {
44463
+ return absoluteQuorumApprove(reviews, valid);
44464
+ }
44448
44465
  return { decision: "approve", verified: true };
44449
44466
  }
44450
44467
  return { decision: "abstain", verified: true };
44451
44468
  }
44469
+ function absoluteQuorumApprove(reviews, valid) {
44470
+ const errorCount = reviews.length - valid.length;
44471
+ const erroredRoles = reviews.filter((r) => r.source === "error").map((r) => r.role);
44472
+ const catfish = valid.find((r) => r.role === "catfish");
44473
+ const catfishApproved = catfish?.decision === "approve";
44474
+ const panelComplete = valid.length === PR_REVIEW_ROLES.length;
44475
+ if (errorCount > 0 || !catfishApproved || !panelComplete) {
44476
+ const missing = catfishApproved ? [] : ["catfish"];
44477
+ const named = [...erroredRoles, ...missing];
44478
+ const list = named.length > 0 ? named.join(", ") : "incomplete panel";
44479
+ return {
44480
+ decision: "abstain",
44481
+ verified: false,
44482
+ reason: `no_quorum: re-run \u2014 voter(s) [${list}] errored/missing (absolute_quorum)`
44483
+ };
44484
+ }
44485
+ return { decision: "approve", verified: true };
44486
+ }
44452
44487
  function buildPrReviewProposal(input) {
44453
44488
  const parts = [];
44454
44489
  parts.push(`# Pull Request Review
@@ -44533,6 +44568,16 @@ function summarizeReviews(reviews) {
44533
44568
  errorCount: reviews.filter((r) => r.source === "error").length
44534
44569
  };
44535
44570
  }
44571
+ function aggregateWithTelemetry(reviews, errorPolicy, errorCount, logger58) {
44572
+ const aggregate = aggregatePrDecisions(reviews, errorPolicy);
44573
+ if (aggregate.reason !== void 0) {
44574
+ logger58.warn("pr_review degraded to no_quorum under absolute_quorum (#4132)", {
44575
+ reason: aggregate.reason,
44576
+ errorCount
44577
+ });
44578
+ }
44579
+ return aggregate;
44580
+ }
44536
44581
  async function executePrReviewBody(input, logger58, gatewayAdapters) {
44537
44582
  const start = Date.now();
44538
44583
  const proposal = buildPrReviewProposal(input);
@@ -44545,7 +44590,7 @@ async function executePrReviewBody(input, logger58, gatewayAdapters) {
44545
44590
  });
44546
44591
  const reviews = voteResults.map(toPrReviewVote);
44547
44592
  const counts = summarizeReviews(reviews);
44548
- const aggregate = aggregatePrDecisions(reviews);
44593
+ const aggregate = aggregateWithTelemetry(reviews, input.errorPolicy, counts.errorCount, logger58);
44549
44594
  let costSummary;
44550
44595
  try {
44551
44596
  costSummary = recordDecisionCost({
@@ -51228,4 +51273,4 @@ export {
51228
51273
  shutdownFeedbackSubscriber,
51229
51274
  createEventBusBridge
51230
51275
  };
51231
- //# sourceMappingURL=chunk-OSOHRYY5.js.map
51276
+ //# sourceMappingURL=chunk-KRCL3VT6.js.map