nexus-agents 8.23.2 → 8.23.4

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 (29) hide show
  1. package/dist/{chunk-KIAMP743.js → chunk-7JD5344Q.js} +12 -5
  2. package/dist/chunk-7JD5344Q.js.map +1 -0
  3. package/dist/{chunk-M7TUO6O7.js → chunk-DEVL62JD.js} +686 -209
  4. package/dist/chunk-DEVL62JD.js.map +1 -0
  5. package/dist/{chunk-OXUJBY4W.js → chunk-FKCE4X4F.js} +2 -2
  6. package/dist/{chunk-3CHPU46R.js → chunk-MQW3SXKC.js} +2 -2
  7. package/dist/{chunk-ZFZJ6LTJ.js → chunk-NUYJ4VW5.js} +2 -2
  8. package/dist/{chunk-TBOM7PJ7.js → chunk-TJFF2CHD.js} +2117 -2500
  9. package/dist/chunk-TJFF2CHD.js.map +1 -0
  10. package/dist/{chunk-TCUEFOPW.js → chunk-WCCU6D5G.js} +3 -3
  11. package/dist/cli.js +9 -9
  12. package/dist/{consensus-vote-NQPSFVEF.js → consensus-vote-SSTSB3ET.js} +4 -4
  13. package/dist/{improvement-review-5HMJ2NCH.js → improvement-review-3QHRGD4C.js} +4 -4
  14. package/dist/index.d.ts +16 -2
  15. package/dist/index.js +6 -6
  16. package/dist/{pr-reviewer-helpers-3VQNHIXI.js → pr-reviewer-helpers-HT3LU55R.js} +2 -2
  17. package/dist/{setup-data-dir-IJ6CYVCL.js → setup-data-dir-ECSNPFPF.js} +3 -3
  18. package/package.json +1 -1
  19. package/dist/chunk-KIAMP743.js.map +0 -1
  20. package/dist/chunk-M7TUO6O7.js.map +0 -1
  21. package/dist/chunk-TBOM7PJ7.js.map +0 -1
  22. /package/dist/{chunk-OXUJBY4W.js.map → chunk-FKCE4X4F.js.map} +0 -0
  23. /package/dist/{chunk-3CHPU46R.js.map → chunk-MQW3SXKC.js.map} +0 -0
  24. /package/dist/{chunk-ZFZJ6LTJ.js.map → chunk-NUYJ4VW5.js.map} +0 -0
  25. /package/dist/{chunk-TCUEFOPW.js.map → chunk-WCCU6D5G.js.map} +0 -0
  26. /package/dist/{consensus-vote-NQPSFVEF.js.map → consensus-vote-SSTSB3ET.js.map} +0 -0
  27. /package/dist/{improvement-review-5HMJ2NCH.js.map → improvement-review-3QHRGD4C.js.map} +0 -0
  28. /package/dist/{pr-reviewer-helpers-3VQNHIXI.js.map → pr-reviewer-helpers-HT3LU55R.js.map} +0 -0
  29. /package/dist/{setup-data-dir-IJ6CYVCL.js.map → setup-data-dir-ECSNPFPF.js.map} +0 -0
@@ -8,7 +8,7 @@ import {
8
8
  NODE_ENGINE_RANGE,
9
9
  VERSION,
10
10
  isNodeVersionSupported
11
- } from "./chunk-OXUJBY4W.js";
11
+ } from "./chunk-FKCE4X4F.js";
12
12
  import {
13
13
  capitalize
14
14
  } from "./chunk-7LP6VJRP.js";
@@ -1228,7 +1228,7 @@ async function runDoctorFix(result) {
1228
1228
  writeLine2("\u2500".repeat(40));
1229
1229
  let fixCount = 0;
1230
1230
  if (!result.dataDirectory.rootExists || result.dataDirectory.subdirectories.some((d) => !d.exists || !d.writable)) {
1231
- const { initDataDirectories: initDataDirectories2, describeDataDirFix: describeDataDirFix2 } = await import("./setup-data-dir-IJ6CYVCL.js");
1231
+ const { initDataDirectories: initDataDirectories2, describeDataDirFix: describeDataDirFix2 } = await import("./setup-data-dir-ECSNPFPF.js");
1232
1232
  const outcome = describeDataDirFix2(initDataDirectories2());
1233
1233
  writeLine2(outcome.line);
1234
1234
  if (outcome.counted) fixCount++;
@@ -1330,4 +1330,4 @@ export {
1330
1330
  startStdioServer,
1331
1331
  closeServer
1332
1332
  };
1333
- //# sourceMappingURL=chunk-TCUEFOPW.js.map
1333
+ //# sourceMappingURL=chunk-WCCU6D5G.js.map
package/dist/cli.js CHANGED
@@ -23,7 +23,7 @@ import {
23
23
  parseExpertReview,
24
24
  reviewPostingBlock,
25
25
  sumFindings
26
- } from "./chunk-KIAMP743.js";
26
+ } from "./chunk-7JD5344Q.js";
27
27
  import "./chunk-4E6T32D3.js";
28
28
  import {
29
29
  runConfigInitSync
@@ -157,7 +157,7 @@ import {
157
157
  validateNexusEnv,
158
158
  validateWorkflow,
159
159
  wrapInMarkdownFence
160
- } from "./chunk-TBOM7PJ7.js";
160
+ } from "./chunk-TJFF2CHD.js";
161
161
  import "./chunk-22EEMQUS.js";
162
162
  import "./chunk-DGWT7DXX.js";
163
163
  import "./chunk-64GMIUM5.js";
@@ -177,7 +177,7 @@ import {
177
177
  doctorCommand,
178
178
  initDataDirectories,
179
179
  runDoctor
180
- } from "./chunk-TCUEFOPW.js";
180
+ } from "./chunk-WCCU6D5G.js";
181
181
  import {
182
182
  buildOpenAICompatAdapters,
183
183
  readOpenAICompatEnv
@@ -196,7 +196,7 @@ import {
196
196
  recordAuthenticVote,
197
197
  registerConsensusVoteTool,
198
198
  toRecordDecision
199
- } from "./chunk-M7TUO6O7.js";
199
+ } from "./chunk-DEVL62JD.js";
200
200
  import {
201
201
  loadUsageEvents,
202
202
  rollupByModel
@@ -236,18 +236,18 @@ import {
236
236
  registerImprovementReviewTool,
237
237
  runImprovementReview,
238
238
  scanForSecrets
239
- } from "./chunk-3CHPU46R.js";
239
+ } from "./chunk-MQW3SXKC.js";
240
240
  import {
241
241
  createDefaultPolicyFirewall,
242
242
  setGlobalPolicyFirewall,
243
243
  setSecureHandlerAuditLogger,
244
244
  stagePolicyFirewallForRollout
245
- } from "./chunk-ZFZJ6LTJ.js";
245
+ } from "./chunk-NUYJ4VW5.js";
246
246
  import {
247
247
  NODE_ENGINE_RANGE,
248
248
  VERSION,
249
249
  isNodeVersionSupported
250
- } from "./chunk-OXUJBY4W.js";
250
+ } from "./chunk-FKCE4X4F.js";
251
251
  import "./chunk-YOT4GWJV.js";
252
252
  import {
253
253
  createUnifiedRegistry,
@@ -4455,7 +4455,7 @@ Provide a structured review with:
4455
4455
  * (Source: Issue #828 — Wire policy gate into production pipeline)
4456
4456
  */
4457
4457
  async postReviewToGitHub(provider, pr, result, gateDecision) {
4458
- const { formatReviewComment: formatReviewComment2 } = await import("./pr-reviewer-helpers-3VQNHIXI.js");
4458
+ const { formatReviewComment: formatReviewComment2 } = await import("./pr-reviewer-helpers-HT3LU55R.js");
4459
4459
  const formattedBody = formatReviewComment2(result);
4460
4460
  const body = truncateText(formattedBody, DRAFT_REPLY_BODY_MAX_LENGTH, "\u2026[review truncated]");
4461
4461
  const sources = pr.files.slice(0, 20).map((file) => ({ type: "repoFile", path: file.filename }));
@@ -19723,7 +19723,7 @@ function startImprovementReviewScheduler(options) {
19723
19723
  let running = false;
19724
19724
  const runOnce = async () => {
19725
19725
  try {
19726
- const { runImprovementReview: runImprovementReview2, ImprovementReviewInputSchema: ImprovementReviewInputSchema2 } = await import("./improvement-review-5HMJ2NCH.js");
19726
+ const { runImprovementReview: runImprovementReview2, ImprovementReviewInputSchema: ImprovementReviewInputSchema2 } = await import("./improvement-review-3QHRGD4C.js");
19727
19727
  const input = ImprovementReviewInputSchema2.parse({ fileIssues });
19728
19728
  const result = await runImprovementReview2(input, { logger: logger22 });
19729
19729
  logger22.info("Scheduled improvement_review complete", {
@@ -11,11 +11,11 @@ import {
11
11
  resetCorrelationTracker,
12
12
  runConsensusForGoal,
13
13
  unwrapVoteOrThrow
14
- } from "./chunk-M7TUO6O7.js";
14
+ } from "./chunk-DEVL62JD.js";
15
15
  import "./chunk-QEZGPM4S.js";
16
16
  import "./chunk-OQB3XC5O.js";
17
- import "./chunk-ZFZJ6LTJ.js";
18
- import "./chunk-OXUJBY4W.js";
17
+ import "./chunk-NUYJ4VW5.js";
18
+ import "./chunk-FKCE4X4F.js";
19
19
  import "./chunk-YOT4GWJV.js";
20
20
  import "./chunk-4O7NQB46.js";
21
21
  import "./chunk-JC3O7WTI.js";
@@ -50,4 +50,4 @@ export {
50
50
  runConsensusForGoal,
51
51
  unwrapVoteOrThrow
52
52
  };
53
- //# sourceMappingURL=consensus-vote-NQPSFVEF.js.map
53
+ //# sourceMappingURL=consensus-vote-SSTSB3ET.js.map
@@ -11,9 +11,9 @@ import {
11
11
  loadSelfEvalSignals,
12
12
  registerImprovementReviewTool,
13
13
  runImprovementReview
14
- } from "./chunk-3CHPU46R.js";
15
- import "./chunk-ZFZJ6LTJ.js";
16
- import "./chunk-OXUJBY4W.js";
14
+ } from "./chunk-MQW3SXKC.js";
15
+ import "./chunk-NUYJ4VW5.js";
16
+ import "./chunk-FKCE4X4F.js";
17
17
  import "./chunk-YOT4GWJV.js";
18
18
  import "./chunk-QOKSFHWH.js";
19
19
  import "./chunk-7WJGV5DN.js";
@@ -33,4 +33,4 @@ export {
33
33
  registerImprovementReviewTool,
34
34
  runImprovementReview
35
35
  };
36
- //# sourceMappingURL=improvement-review-5HMJ2NCH.js.map
36
+ //# sourceMappingURL=improvement-review-3QHRGD4C.js.map
package/dist/index.d.ts CHANGED
@@ -11676,8 +11676,10 @@ declare class Orchestrator extends BaseAgent {
11676
11676
  protected buildPrompt(task: Task$1): Message[];
11677
11677
  /** Analyze a task to understand its complexity and requirements. */
11678
11678
  analyzeTask(task: Task$1): Promise<Result<TaskAnalysis, AgentError$1>>;
11679
+ private analyzeTaskWithUsage;
11679
11680
  /** Decompose a task into subtasks. */
11680
11681
  decomposeTask(task: Task$1, analysis: TaskAnalysis): Promise<Result<SubTask[], AgentError$1>>;
11682
+ private decomposeTaskWithUsage;
11681
11683
  /** Select appropriate expert agents for each subtask. */
11682
11684
  selectExperts(subtasks: SubTask[]): ExpertAssignment[];
11683
11685
  /**
@@ -12093,8 +12095,20 @@ interface CodeChange {
12093
12095
  interface SecurityAnalysisResult extends ExpertOutput {
12094
12096
  /** Vulnerabilities found */
12095
12097
  vulnerabilities: Vulnerability[];
12096
- /** Security score (0-100) */
12098
+ /**
12099
+ * Security score (0-100). When `findingsCoverage === 'unmeasured'`, `securityScore` is `0`: a
12100
+ * fail-closed placeholder and the worst score, so a reader that ignores the marker errs toward
12101
+ * blocking, never toward a clean 100. `partial` scores only the validated findings; `complete` is
12102
+ * unchanged.
12103
+ */
12097
12104
  securityScore: number;
12105
+ /**
12106
+ * Coverage of the model-supplied findings after validation. When
12107
+ * `findingsCoverage === 'unmeasured'`, `securityScore` is `0`: a fail-closed placeholder and the
12108
+ * worst score, so a reader that ignores the marker errs toward blocking, never toward a clean
12109
+ * 100. `partial` keeps the score over the validated findings; `complete` is unchanged.
12110
+ */
12111
+ findingsCoverage?: 'complete' | 'partial' | 'unmeasured' | undefined;
12098
12112
  /** Compliance status */
12099
12113
  compliance?: ComplianceStatus;
12100
12114
  }
@@ -13777,8 +13791,8 @@ declare const TrinityRoleSchema: z.ZodEnum<{
13777
13791
  declare const TrinityPhaseSchema: z.ZodEnum<{
13778
13792
  thinking: "thinking";
13779
13793
  working: "working";
13780
- verifying: "verifying";
13781
13794
  complete: "complete";
13795
+ verifying: "verifying";
13782
13796
  }>;
13783
13797
  /** Schema for verifier verdict. */
13784
13798
  declare const VerifierVerdictSchema: z.ZodEnum<{
package/dist/index.js CHANGED
@@ -553,7 +553,7 @@ import {
553
553
  withLogging,
554
554
  withRetry,
555
555
  withRetryWrapper
556
- } from "./chunk-TBOM7PJ7.js";
556
+ } from "./chunk-TJFF2CHD.js";
557
557
  import {
558
558
  FALLBACK_SCANNER_DATA,
559
559
  buildPlanFromAnalysis,
@@ -586,7 +586,7 @@ import {
586
586
  connectTransport,
587
587
  createServer,
588
588
  startStdioServer
589
- } from "./chunk-TCUEFOPW.js";
589
+ } from "./chunk-WCCU6D5G.js";
590
590
  import {
591
591
  OPENAI_MODELS,
592
592
  OPENAI_MODEL_ALIASES,
@@ -644,7 +644,7 @@ import {
644
644
  generateProposalId,
645
645
  parseAgentPairKey,
646
646
  registerConsensusVoteTool
647
- } from "./chunk-M7TUO6O7.js";
647
+ } from "./chunk-DEVL62JD.js";
648
648
  import "./chunk-QEZGPM4S.js";
649
649
  import {
650
650
  allOf
@@ -702,7 +702,7 @@ import {
702
702
  import {
703
703
  ImprovementReviewInputSchema,
704
704
  registerImprovementReviewTool
705
- } from "./chunk-3CHPU46R.js";
705
+ } from "./chunk-MQW3SXKC.js";
706
706
  import {
707
707
  AgentPerformanceSchema,
708
708
  ConsensusAlgorithmSchema,
@@ -738,10 +738,10 @@ import {
738
738
  toolSuccess,
739
739
  toolSuccessStructured,
740
740
  validateToolInput
741
- } from "./chunk-ZFZJ6LTJ.js";
741
+ } from "./chunk-NUYJ4VW5.js";
742
742
  import {
743
743
  VERSION
744
- } from "./chunk-OXUJBY4W.js";
744
+ } from "./chunk-FKCE4X4F.js";
745
745
  import {
746
746
  AuditTrail,
747
747
  createAuditTrail,
@@ -20,7 +20,7 @@ import {
20
20
  parseSeverity,
21
21
  reviewPostingBlock,
22
22
  sumFindings
23
- } from "./chunk-KIAMP743.js";
23
+ } from "./chunk-7JD5344Q.js";
24
24
  import "./chunk-2G2ZXAD7.js";
25
25
  import "./chunk-OQB3XC5O.js";
26
26
  import "./chunk-OYTRYITB.js";
@@ -51,4 +51,4 @@ export {
51
51
  reviewPostingBlock,
52
52
  sumFindings
53
53
  };
54
- //# sourceMappingURL=pr-reviewer-helpers-3VQNHIXI.js.map
54
+ //# sourceMappingURL=pr-reviewer-helpers-HT3LU55R.js.map
@@ -2,11 +2,11 @@ import {
2
2
  NEXUS_DATA_DIR,
3
3
  describeDataDirFix,
4
4
  initDataDirectories
5
- } from "./chunk-TCUEFOPW.js";
5
+ } from "./chunk-WCCU6D5G.js";
6
6
  import "./chunk-OUOBB5XR.js";
7
7
  import "./chunk-QEZGPM4S.js";
8
8
  import "./chunk-OQB3XC5O.js";
9
- import "./chunk-OXUJBY4W.js";
9
+ import "./chunk-FKCE4X4F.js";
10
10
  import "./chunk-7LP6VJRP.js";
11
11
  import "./chunk-TPBPFBO3.js";
12
12
  import "./chunk-3VBOYUPH.js";
@@ -26,4 +26,4 @@ export {
26
26
  describeDataDirFix,
27
27
  initDataDirectories
28
28
  };
29
- //# sourceMappingURL=setup-data-dir-IJ6CYVCL.js.map
29
+ //# sourceMappingURL=setup-data-dir-ECSNPFPF.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nexus-agents",
3
- "version": "8.23.2",
3
+ "version": "8.23.4",
4
4
  "description": "Governance substrate for AI coding agents — adversarial PR review, drift-detected rules, tamper-evident audit, and closed-loop outcome routing for Claude, Codex, Gemini, and OpenCode",
5
5
  "mcpName": "io.github.nexus-substrate/nexus-agents",
6
6
  "license": "MIT",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/dogfooding/pr-reviewer-helpers.ts","../src/dogfooding/pr-review-stats.ts"],"sourcesContent":["/**\n * nexus-agents/dogfooding - PR Reviewer Helpers\n *\n * Helper functions for PR review formatting and aggregation.\n *\n * @module dogfooding/pr-reviewer-helpers\n * (Source: Issue #161, Alignment Roadmap Phase 3)\n */\n\nimport { randomUUID } from 'node:crypto';\nimport type { Result } from '../core/index.js';\nimport { getTimeProvider, createLogger, ok, err } from '../core/index.js';\nimport type { ScmUserMetadata } from '../scm/types.js';\nimport type {\n PRMetadata,\n PRReviewDraft,\n PRTrustAssessment,\n ExpertReviewResult,\n ReviewFinding,\n ReviewCategory,\n ReviewSeverity,\n ReviewDecision,\n} from './pr-review-types.js';\nimport {\n SEVERITY_ORDER,\n CATEGORY_DISPLAY_NAMES,\n SEVERITY_EMOJI,\n DECISION_EMOJI,\n} from './pr-review-types.js';\nimport { sanitizeInput } from '../security/input-sanitizer.js';\nimport { allOf } from '../utils/verdict-aggregation.js';\nimport { assessReputation } from '../security/reputation-model.js';\nimport type {\n ReputationCache,\n ReputationGateDecision,\n ReputationAssessment,\n GitHubUserMetadata,\n} from '../security/reputation-model.js';\nimport type { FirewallResult } from '../security/firewall/firewall-pipeline.js';\nimport { formatReviewStats } from './pr-review-stats.js';\n\nconst repLogger = createLogger({ component: 'PRReviewer.reputation' });\n\n// =============================================================================\n// Reputation Gating Helpers (#3123, epic #3118 Phase 5)\n// =============================================================================\n\n/**\n * Best-effort account-age lookup for a PR author (#3133, Phase-3 equivalent for\n * the PR path). Returns the author's real account age in days via the provider's\n * `fetchUserMetadata`, or `undefined` on any failure (err Result, unparseable\n * `createdAt`, or an unexpected rejection) — never fabricated, never throws, so\n * the review is never blocked by this lookup.\n */\nexport async function fetchAccountAgeDays(\n provider: { fetchUserMetadata: (u: string) => Promise<Result<ScmUserMetadata, Error>> },\n username: string\n): Promise<number | undefined> {\n try {\n const result = await provider.fetchUserMetadata(username);\n if (!result.ok) return undefined;\n const createdMs = Date.parse(result.value.createdAt);\n if (!Number.isFinite(createdMs)) return undefined;\n return Math.floor((getTimeProvider().now() - createdMs) / 86_400_000);\n } catch {\n return undefined;\n }\n}\n\n/**\n * Assesses the PR author's reputation from the signals available in the PR\n * event: author association + injection flags from the (sanitized) PR body, plus\n * the author's real account age when it was fetched (#3133). `accountAgeDays` is\n * OMITTED when the lookup failed — never fabricated, so the engine skips the\n * `new_account` signal. Returns undefined when reputation is disabled.\n */\nexport function assessPRReputation(\n pr: PRMetadata,\n cache: ReputationCache,\n enableReputation: boolean,\n accountAgeDays: number | undefined\n): ReputationAssessment | undefined {\n if (!enableReputation) return undefined;\n // Only `injectionFlags` is consumed here, and injection detection is\n // role-independent — the userRole arg ('unknown') and the sanitizer's own\n // trustTier output are intentionally irrelevant to this call.\n const sanitizeResult = sanitizeInput(pr.body, 'unknown', pr.author);\n const metadata: GitHubUserMetadata = {\n username: pr.author,\n ...(accountAgeDays !== undefined ? { accountAgeDays } : {}),\n authorAssociation: pr.authorAssociation,\n injectionFlags: sanitizeResult.injectionFlags,\n };\n return assessReputation(metadata, cache);\n}\n\n/** Builds the observability assessment surfaced on the review result (#3123). */\nexport function buildPRTrustAssessment(\n firewall: Pick<FirewallResult, 'trust' | 'isAllowlisted' | 'auditSink'>,\n reputation: ReputationAssessment | undefined,\n gateDecision: ReputationGateDecision\n): PRTrustAssessment {\n const trustResult = firewall.trust;\n // Tier-1 (owner/allowlisted) authors cannot be suspicious.\n const isTier1 = trustResult.trustTier === '1';\n return {\n trustTier: trustResult.trustTier,\n userRole: trustResult.userRole,\n // Measured or absent (#4992): never the classifier's default `false`.\n ...(firewall.isAllowlisted !== undefined ? { isAllowlisted: firewall.isAllowlisted } : {}),\n auditSink: firewall.auditSink,\n reputationScore: reputation?.reputationScore,\n suspiciousSignals: isTier1 ? [] : (reputation?.suspiciousSignals ?? []),\n isSuspicious: isTier1 ? false : (reputation?.isSuspicious ?? false),\n enforcedTrustTier: gateDecision.enforcedTier,\n reputationReconciledTier: gateDecision.reconciledTier,\n gatingMode: gateDecision.mode,\n };\n}\n\n/**\n * Reads the reputation gate decision the firewall computed for this PR (#3123\n * gating; #4992 review: ONE gate, shared with the firewall's Rule-of-Two\n * signal) and builds the assessment surfaced on the result. A suppressed\n * demotion (audit/off) is logged. Fails closed when the firewall returned no\n * gate — structurally unreachable, since the caller always supplies the\n * reputation option, but the classifier tier must never stand in for it.\n */\nexport function gatePRAuthor(\n pr: PRMetadata,\n firewall: Pick<FirewallResult, 'trust' | 'isAllowlisted' | 'auditSink' | 'reputationGate'>,\n reputation: ReputationAssessment | undefined\n): Result<{ gateDecision: ReputationGateDecision; trustAssessment: PRTrustAssessment }, Error> {\n const trustResult = firewall.trust;\n const gateDecision = firewall.reputationGate;\n if (gateDecision === undefined) {\n return err(new Error('Untrusted-input firewall returned no reputation gate decision'));\n }\n if (gateDecision.demotionSuppressed) {\n repLogger.warn('Reputation demotion suppressed by gating mode (would block under enforce)', {\n prNumber: pr.number,\n author: pr.author,\n mode: gateDecision.mode,\n classifierTier: trustResult.trustTier,\n reconciledTier: gateDecision.reconciledTier,\n });\n }\n return ok({\n gateDecision,\n trustAssessment: buildPRTrustAssessment(firewall, reputation, gateDecision),\n });\n}\n\n// =============================================================================\n// Parsing Helpers\n// =============================================================================\n\nexport function parseSeverity(value: unknown): ReviewSeverity {\n if (typeof value === 'string') {\n const lower = value.toLowerCase();\n if (lower in SEVERITY_ORDER) return lower as ReviewSeverity;\n }\n return 'medium';\n}\n\nexport function parseCategory(value: unknown): ReviewCategory {\n if (typeof value === 'string') {\n const lower = value.toLowerCase();\n if (lower in CATEGORY_DISPLAY_NAMES) return lower as ReviewCategory;\n }\n return 'code_quality';\n}\n\nexport function extractSummary(output: Record<string, unknown>): string {\n if (typeof output.summary === 'string') return output.summary;\n if (typeof output.content === 'string') return output.content;\n if (typeof output.message === 'string') return output.message;\n return 'Review completed';\n}\n\nexport function extractStringField(\n record: Record<string, unknown>,\n ...keys: string[]\n): string | undefined {\n for (const key of keys) {\n const value = record[key];\n if (typeof value === 'string') return value;\n }\n return undefined;\n}\n\n/** Formats fetched patches and reports how many were supplied without truncation. */\nexport function formatDiffs(pr: PRMetadata): {\n readonly text: string;\n readonly filesIncluded: number;\n} {\n const maxDiffLength = 2000;\n let totalLength = 0;\n let filesIncluded = 0;\n const diffs: string[] = [];\n for (const file of pr.files) {\n if (file.patch === undefined) continue;\n const diff = `\\`\\`\\`diff\\n# ${file.filename}\\n${file.patch}\\n\\`\\`\\``;\n if (totalLength + diff.length > maxDiffLength * pr.files.length) {\n diffs.push(`# ${file.filename}\\n(diff truncated)`);\n } else {\n diffs.push(diff);\n totalLength += diff.length;\n filesIncluded++;\n }\n }\n return { text: diffs.join('\\n\\n'), filesIncluded };\n}\n\n// =============================================================================\n// Finding Parsing\n// =============================================================================\n\nexport function parseFindings(\n output: Record<string, unknown>,\n expertId: string,\n minSeverity: ReviewSeverity\n): ReviewFinding[] {\n const minOrder = SEVERITY_ORDER[minSeverity];\n const sources = collectSources(output);\n\n const findings: ReviewFinding[] = [];\n for (const source of sources) {\n if (!Array.isArray(source)) continue;\n for (const item of source) {\n const finding = parseOneFinding(item, expertId, minOrder);\n if (finding !== null) findings.push(finding);\n }\n }\n for (const warning of parseWarnings(output.warnings)) {\n const finding = parseWarningFinding(warning, expertId, minOrder);\n if (finding !== null) findings.push(finding);\n }\n return findings;\n}\n\nfunction collectSources(output: Record<string, unknown>): unknown[] {\n return [\n output.findings,\n output.vulnerabilities,\n output.issues,\n (output as { content?: { findings?: unknown } }).content,\n ];\n}\n\nfunction parseOneFinding(item: unknown, expertId: string, minOrder: number): ReviewFinding | null {\n if (typeof item !== 'object' || item === null) return null;\n\n const record = item as Record<string, unknown>;\n const severity = parseSeverity(record.severity);\n if (SEVERITY_ORDER[severity] < minOrder) return null;\n\n return {\n id: randomUUID(),\n category: parseCategory(record.category),\n severity,\n title: extractStringField(record, 'title', 'name') ?? 'Finding',\n description: extractStringField(record, 'description', 'message') ?? '',\n file: typeof record.file === 'string' ? record.file : undefined,\n line: typeof record.line === 'number' ? record.line : undefined,\n suggestion: typeof record.suggestion === 'string' ? record.suggestion : undefined,\n expertId,\n confidence: typeof record.confidence === 'number' ? record.confidence : 0.7,\n };\n}\n\nfunction parseWarnings(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return value.filter((warning): warning is string => typeof warning === 'string');\n}\n\nfunction parseWarningFinding(\n warning: string,\n expertId: string,\n minOrder: number\n): ReviewFinding | null {\n const severity = parseSeverity(\n warning.match(/\\b(critical|high|medium|low|info)-?severity\\b/i)?.[1]\n );\n return parseOneFinding(\n {\n title: 'Expert warning',\n description: warning,\n severity,\n category: parseCategory(expertId.replace(/-expert$/, '')),\n },\n expertId,\n minOrder\n );\n}\n\ntype ExpertVerdict = 'approved' | 'changes_requested' | 'findings' | 'errored';\n\ninterface ParsedExpertReview {\n readonly findings: ReviewFinding[];\n readonly verdict: ExpertVerdict;\n}\n\nfunction parseVerdictMarker(\n value: unknown\n): Exclude<ExpertVerdict, 'findings' | 'errored'> | undefined {\n if (typeof value !== 'string') return undefined;\n const normalized = value.toUpperCase().replaceAll('-', '_').replaceAll(' ', '_');\n if (/\\b(?:CHANGES_REQUESTED|REQUEST_CHANGES)\\b/.test(normalized)) return 'changes_requested';\n if (/\\b(?:APPROVED|APPROVE)\\b/.test(normalized)) return 'approved';\n return undefined;\n}\n\n/** Parses one expert output into a single, validated review verdict. */\nexport function parseExpertReview(\n output: Record<string, unknown>,\n expertId: string,\n minSeverity: ReviewSeverity\n): ParsedExpertReview {\n const findings = parseFindings(output, expertId, minSeverity);\n const verdict = parseVerdictMarker(output.verdict) ?? parseVerdictMarker(output.content);\n if (verdict !== undefined) return { findings, verdict };\n const hasFindingShape = collectSources(output).some((source) => Array.isArray(source));\n const hasWarningShape = parseWarnings(output.warnings).length > 0;\n return { findings, verdict: hasFindingShape || hasWarningShape ? 'findings' : 'errored' };\n}\n\n// =============================================================================\n// Decision Helpers\n// =============================================================================\n\nexport function determineApproval(\n findings: ReviewFinding[],\n verdict: ExpertVerdict = 'findings'\n): boolean {\n if (verdict === 'errored' || verdict === 'changes_requested') return false;\n const hasBlocking = findings.some((f) => f.severity === 'critical' || f.severity === 'high');\n return !hasBlocking;\n}\n\nexport function determineDecision(\n reviews: ExpertReviewResult[],\n findings: ReviewFinding[]\n): ReviewDecision {\n // #5012: an expert that errored produced no verdict, so it can neither\n // approve nor object. `allOf(reviews, …, false)` already refuses to call\n // ZERO reviews unanimous approval (#4581); feeding it synthetic approvals\n // for failed experts defeated that guard by making the list non-empty.\n const completedReviews = reviews.filter((r) => r.errored !== true);\n const hasCritical = findings.some((f) => f.severity === 'critical');\n const hasHigh = findings.some((f) => f.severity === 'high');\n // Zero expert reviews is not unanimous approval (#4581): with `true` here the\n // `hasHigh && !allApproved` branch could never fire on an unreviewed PR, so a\n // HIGH finding silently downgraded from request_changes to comment.\n const allApproved = allOf(reviews, (r) => r.errored !== true && r.approved, false);\n\n if (hasCritical) return 'request_changes';\n if (hasHigh && !allApproved) return 'request_changes';\n if (findings.length > 0) return 'comment';\n // Nothing read the diff, so there is nothing to approve. `comment` posts the\n // failure summaries without asserting the change is fine.\n if (completedReviews.length === 0 || !allApproved) return 'comment';\n return 'approve';\n}\n\nexport function calculateConsensus(reviews: ExpertReviewResult[]): number {\n if (reviews.length === 0) return 1;\n const approvals = reviews.filter((r) => r.approved).length;\n return approvals / reviews.length;\n}\n\n// =============================================================================\n// Counting Helpers\n// =============================================================================\n\nexport function countBySeverity(findings: ReviewFinding[]): Record<ReviewSeverity, number> {\n const counts: Record<ReviewSeverity, number> = {\n critical: 0,\n high: 0,\n medium: 0,\n low: 0,\n info: 0,\n };\n\n for (const f of findings) {\n counts[f.severity]++;\n }\n\n return counts;\n}\n\nexport function countByCategory(findings: ReviewFinding[]): Record<ReviewCategory, number> {\n const counts: Record<ReviewCategory, number> = {\n security: 0,\n performance: 0,\n code_quality: 0,\n testing: 0,\n documentation: 0,\n architecture: 0,\n };\n\n for (const f of findings) {\n counts[f.category]++;\n }\n\n return counts;\n}\n\nexport function sumFindings(counts: Record<ReviewSeverity, number>): number {\n return Object.values(counts).reduce((a, b) => a + b, 0);\n}\n\n// =============================================================================\n// Summary Generation\n// =============================================================================\n\nexport function generateSummary(\n pr: PRMetadata,\n reviews: ExpertReviewResult[],\n decision: ReviewDecision\n): string {\n const expertSummaries = reviews\n .map((r) => `- **${CATEGORY_DISPLAY_NAMES[r.expertType as ReviewCategory]}**: ${r.summary}`)\n .join('\\n');\n\n return `Reviewed PR #${String(pr.number)}: ${pr.title}\n\n**Decision:** ${decision.replaceAll('_', ' ')}\n**Experts consulted:** ${String(reviews.length)}\n\n${expertSummaries}`;\n}\n\n// =============================================================================\n// GitHub Comment Formatting\n// =============================================================================\n\n/**\n * Formats the review result as a GitHub comment.\n */\nexport function formatReviewComment(result: PRReviewDraft): string {\n const emoji = DECISION_EMOJI[result.decision];\n const decisionText = result.decision.replaceAll('_', ' ').toUpperCase();\n\n const findingsSection = formatFindingsSection(result);\n const statsSection = formatReviewStats(result);\n\n return `## ${emoji} Nexus Agents Review: ${decisionText}\n\n${result.summary}\n\n${findingsSection}\n\n${statsSection}\n\n---\n*Reviewed by [nexus-agents](https://github.com/nexus-substrate/nexus-agents) in ${String(result.totalDurationMs)}ms*`;\n}\n\nfunction formatFindingsSection(result: PRReviewDraft): string {\n const allFindings = result.expertReviews.flatMap((r) => r.findings);\n\n if (allFindings.length === 0) {\n return '_No issues found._';\n }\n\n const sorted = [...allFindings].sort(\n (a, b) => SEVERITY_ORDER[b.severity] - SEVERITY_ORDER[a.severity]\n );\n\n const lines = ['### Findings', ''];\n\n for (const f of sorted) {\n const emoji = SEVERITY_EMOJI[f.severity];\n const loc =\n f.file !== undefined\n ? ` (\\`${f.file}${f.line !== undefined ? `:${String(f.line)}` : ''}\\`)`\n : '';\n lines.push(`${emoji} **${f.title}**${loc}`);\n lines.push(`> ${f.description}`);\n if (f.suggestion !== undefined) {\n lines.push(`> 💡 ${f.suggestion}`);\n }\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n\n// =============================================================================\n// Failed Review Factory\n// =============================================================================\n\nexport function createFailedReview(\n expertId: string,\n category: ReviewCategory,\n durationMs: number,\n error: string\n): ExpertReviewResult {\n return {\n expertId,\n expertType: category,\n // #5012: NOT `approved: true`. \"Don't block on failures\" made an expert\n // that never ran indistinguishable from one that read the diff and had no\n // objection, and `determineDecision` turned three of those into an APPROVE\n // posted to GitHub.\n approved: false,\n errored: true,\n summary: `Review failed: ${error}`,\n findings: [],\n durationMs,\n confidence: 0,\n };\n}\n\n/** The policy gate's verdict on posting a review, as the caller needs it. */\nexport interface ReviewPostingVerdict {\n readonly allowed: boolean;\n readonly hasRuleOfTwoViolation: boolean;\n readonly violations: readonly { rule: string; message?: string }[];\n}\n\n/**\n * Decide whether review posting is blocked, and how to describe it.\n *\n * Consumes the gate's own `allowed` rather than re-deriving a narrower\n * condition. The caller previously blocked on `hasRuleOfTwoViolation` alone\n * while `evaluatePolicy` had already computed `allowed`.\n *\n * For the action `auditReviewAction` builds, the two are currently EQUIVALENT:\n * tiers 1-2 yield no violations, tiers 3-4 yield INSUFFICIENT_TRUST +\n * UNTRUSTED_INFLUENCE + RULE_OF_TWO together. So this changes no behaviour\n * today. It makes the equivalence guaranteed rather than accidental — it holds\n * only because that context hardcodes `hasWriteAccess` and `hasSecretAccess`\n * to true, which is what makes `checkRuleOfTwo` fire at tier 3+. Make either\n * conditional and RULE_OF_TWO stops firing while the other two blocking rules\n * still do, and a review would post against `allowed: false`.\n *\n * Returns `undefined` when posting may proceed. Rule of Two keeps its own\n * label: it is the distinctive condition (untrusted input + write access +\n * secrets at once) and reads very differently from a trust-tier block.\n */\nexport function reviewPostingBlock(\n verdict: ReviewPostingVerdict\n): { label: string; reason: string } | undefined {\n if (verdict.allowed) return undefined;\n const label = verdict.hasRuleOfTwoViolation ? 'Rule of Two' : 'Policy gate';\n return { label, reason: `${label}: ${verdict.violations.map((v) => v.rule).join(', ')}` };\n}\n","/**\n * Review coverage calculation and statistics rendering.\n *\n * @module dogfooding/pr-review-stats\n */\n\nimport type {\n ExpertReviewResult,\n PRMetadata,\n PRReviewDraft,\n ReviewSeverity,\n} from './pr-review-types.js';\nimport { SEVERITY_EMOJI } from './pr-review-types.js';\n\n/** Calculates how much of the fetched PR was supplied to a successful expert. */\nexport function getFileReviewCoverage(\n pr: PRMetadata,\n reviews: readonly ExpertReviewResult[],\n filesIncluded: number\n): Pick<PRReviewDraft, 'totalFiles' | 'filesWithPatch' | 'filesReviewed' | 'reviewCoverage'> {\n const totalFiles = pr.files.length;\n const filesWithPatch = pr.files.filter((file) => file.patch !== undefined).length;\n const hasSuccessfulReview = reviews.some((review) => review.errored !== true);\n const filesReviewed = hasSuccessfulReview ? filesIncluded : 0;\n const reviewCoverage =\n filesReviewed === 0 ? 'none' : filesReviewed === totalFiles ? 'full' : 'partial';\n return { totalFiles, filesWithPatch, filesReviewed, reviewCoverage };\n}\n\n/** Formats the measured file-review coverage without losing the PR total. */\nexport function formatFileReviewCoverage(result: PRReviewDraft): string {\n return `${String(result.filesReviewed)} of ${String(result.totalFiles)} files reviewed (${result.reviewCoverage})`;\n}\n\n/** Renders the collapsible statistics section in a GitHub review comment. */\nexport function formatReviewStats(result: PRReviewDraft): string {\n const total = Object.values(result.findingsBySeverity).reduce((a, b) => a + b, 0);\n const parts: string[] = [];\n for (const severity of ['critical', 'high', 'medium', 'low', 'info'] as ReviewSeverity[]) {\n const count = result.findingsBySeverity[severity];\n if (count > 0) parts.push(`${SEVERITY_EMOJI[severity]} ${String(count)} ${severity}`);\n }\n\n return `<details>\n<summary>Review Statistics (${String(total)} findings)</summary>\n\n- Experts: ${String(result.expertCount)}\n- Files: ${formatFileReviewCoverage(result)}\n- Consensus: ${(result.consensusScore * 100).toFixed(0)}%\n- Duration: ${String(result.totalDurationMs)}ms\n- Findings: ${parts.join(', ') || 'none'}\n\n</details>`;\n}\n"],"mappings":"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","names":[]}