nexus-agents 2.112.0 → 2.114.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 (123) hide show
  1. package/dist/{child-mcp-config-UMNWY25S.js → child-mcp-config-BTYHNG2N.js} +2 -2
  2. package/dist/{chunk-7XAA2CSJ.js → chunk-36G75SD2.js} +1243 -3339
  3. package/dist/chunk-36G75SD2.js.map +1 -0
  4. package/dist/{chunk-5OOFU3EY.js → chunk-3S4N6OCF.js} +2 -2
  5. package/dist/{chunk-5P5KCVTX.js → chunk-4K4OVG4O.js} +163 -3
  6. package/dist/chunk-4K4OVG4O.js.map +1 -0
  7. package/dist/{chunk-5EH7WMME.js → chunk-5RDUP5K7.js} +2 -2
  8. package/dist/{chunk-3XGPHTO6.js → chunk-7AO4FKAD.js} +2 -2
  9. package/dist/{chunk-P2K5GCLL.js → chunk-7BZKZUVR.js} +4 -4
  10. package/dist/{chunk-GJ47JWNS.js → chunk-AREFHG4Q.js} +186 -340
  11. package/dist/chunk-AREFHG4Q.js.map +1 -0
  12. package/dist/chunk-ATI7W2FT.js +2474 -0
  13. package/dist/chunk-ATI7W2FT.js.map +1 -0
  14. package/dist/{chunk-6LFHI2KF.js → chunk-B32GCV25.js} +5 -5
  15. package/dist/{chunk-LUCPCWIZ.js → chunk-BXEOO2KK.js} +2 -2
  16. package/dist/{chunk-RPWYEJ66.js → chunk-CLL2GXNL.js} +4 -4
  17. package/dist/chunk-E2ER3LQF.js +149 -0
  18. package/dist/chunk-E2ER3LQF.js.map +1 -0
  19. package/dist/{chunk-TIOXPJIO.js → chunk-E4HZTSBP.js} +2 -2
  20. package/dist/{chunk-SXG2NPZP.js → chunk-F6NOHVYQ.js} +3 -3
  21. package/dist/{chunk-7EYPNMFQ.js → chunk-FSZNZZO5.js} +7 -7
  22. package/dist/{chunk-NCWD4UOI.js → chunk-IBRRXLMJ.js} +7 -7
  23. package/dist/{chunk-FSODHLOV.js → chunk-KTPMJSLZ.js} +3 -3
  24. package/dist/{chunk-2JIV7Q6A.js → chunk-MD6TVSOI.js} +3 -3
  25. package/dist/{chunk-WDOJESN6.js → chunk-MYN7CMD5.js} +2 -2
  26. package/dist/{chunk-ZSJG7EB2.js → chunk-N7NCTB3O.js} +5 -144
  27. package/dist/chunk-N7NCTB3O.js.map +1 -0
  28. package/dist/{chunk-XOKGSQIB.js → chunk-OTRXF5NM.js} +49 -3
  29. package/dist/chunk-OTRXF5NM.js.map +1 -0
  30. package/dist/{chunk-3DB4DEFY.js → chunk-Q6HUW6EI.js} +2 -2
  31. package/dist/{chunk-VV47MWHN.js → chunk-R2G4GZID.js} +3 -3
  32. package/dist/{chunk-AWXWDGG5.js → chunk-S7RTQRQ3.js} +2 -2
  33. package/dist/{chunk-N2HYXBQ6.js → chunk-VNU7OT7O.js} +2 -2
  34. package/dist/{chunk-VQVKI4XO.js → chunk-WJSQ5FRV.js} +2 -2
  35. package/dist/{chunk-F2ULTSZ6.js → chunk-XMNGHZBR.js} +7 -7
  36. package/dist/{chunk-2QBR4RVO.js → chunk-YJSXYHSK.js} +2 -2
  37. package/dist/{chunk-TI2BJ2OB.js → chunk-YKNLQLFM.js} +6 -6
  38. package/dist/{chunk-LMMMFZ64.js → chunk-YQW7MHST.js} +2 -2
  39. package/dist/{chunk-JRBUSUYD.js → chunk-ZXF2XA4R.js} +3 -3
  40. package/dist/{cli-circuit-breaker-XB5FPZJ5.js → cli-circuit-breaker-OR2Z2ZXU.js} +4 -4
  41. package/dist/cli.js +66 -63
  42. package/dist/cli.js.map +1 -1
  43. package/dist/{composite-router-VWQ65U6B.js → composite-router-QC4OLIQ5.js} +2 -2
  44. package/dist/{consensus-vote-SB2G2W6G.js → consensus-vote-JMIK4USL.js} +12 -12
  45. package/dist/context-retriever-CFINY4KH.js +24 -0
  46. package/dist/{doctor-deep-RFHTNO2P.js → doctor-deep-53KZ3IYQ.js} +3 -3
  47. package/dist/{expert-bridge-LDWFPVHK.js → expert-bridge-WWAGNKZY.js} +4 -4
  48. package/dist/factory-3FKPAH26.js +21 -0
  49. package/dist/{factory-IYL24RFV.js → factory-KIGMY2XP.js} +5 -5
  50. package/dist/{improvement-review-GFCDFNYV.js → improvement-review-A4HQ7KIQ.js} +6 -4
  51. package/dist/index.d.ts +9 -9
  52. package/dist/index.js +43 -42
  53. package/dist/index.js.map +1 -1
  54. package/dist/{init-opencode-26HTJ5QO.js → init-opencode-IMP5HG2J.js} +5 -5
  55. package/dist/{issue-triage-MVLE3SRA.js → issue-triage-VPL3N2AG.js} +5 -5
  56. package/dist/{pr-reviewer-helpers-HXEJ437Q.js → pr-reviewer-helpers-6FGXGRYA.js} +4 -4
  57. package/dist/{registry-command-RQH4YGK5.js → registry-command-IGVBSZX6.js} +2 -2
  58. package/dist/{repo-security-plan-SIOA64KN.js → repo-security-plan-PWFK3LCK.js} +3 -3
  59. package/dist/{research-helpers-synthesize-K43DWQVG.js → research-helpers-synthesize-IXWXFRKC.js} +4 -3
  60. package/dist/{routing-memory-AEYB4NPO.js → routing-memory-RQUM4XHT.js} +2 -2
  61. package/dist/{session-memory-GZOSVFDD.js → session-memory-7TDKNMRE.js} +3 -3
  62. package/dist/{setup-command-TEKCWGGU.js → setup-command-MWZ5M3UB.js} +11 -11
  63. package/dist/{setup-config-R7GWRUW2.js → setup-config-ICI5OIGW.js} +3 -3
  64. package/dist/{setup-custom-api-DXS3Y4XW.js → setup-custom-api-IVJLG6WI.js} +3 -3
  65. package/dist/{tool-memory-CXHXCI6Q.js → tool-memory-USBUCDTD.js} +5 -5
  66. package/dist/{weather-report-PYDBRULK.js → weather-report-ZLUBKEG3.js} +2 -2
  67. package/package.json +1 -1
  68. package/dist/chunk-5P5KCVTX.js.map +0 -1
  69. package/dist/chunk-7XAA2CSJ.js.map +0 -1
  70. package/dist/chunk-GJ47JWNS.js.map +0 -1
  71. package/dist/chunk-KWHJL7HX.js +0 -276
  72. package/dist/chunk-KWHJL7HX.js.map +0 -1
  73. package/dist/chunk-XOKGSQIB.js.map +0 -1
  74. package/dist/chunk-ZSJG7EB2.js.map +0 -1
  75. package/dist/context-retriever-5VFAIPHM.js +0 -19
  76. package/dist/factory-AIERXI3O.js +0 -21
  77. /package/dist/{child-mcp-config-UMNWY25S.js.map → child-mcp-config-BTYHNG2N.js.map} +0 -0
  78. /package/dist/{chunk-5OOFU3EY.js.map → chunk-3S4N6OCF.js.map} +0 -0
  79. /package/dist/{chunk-5EH7WMME.js.map → chunk-5RDUP5K7.js.map} +0 -0
  80. /package/dist/{chunk-3XGPHTO6.js.map → chunk-7AO4FKAD.js.map} +0 -0
  81. /package/dist/{chunk-P2K5GCLL.js.map → chunk-7BZKZUVR.js.map} +0 -0
  82. /package/dist/{chunk-6LFHI2KF.js.map → chunk-B32GCV25.js.map} +0 -0
  83. /package/dist/{chunk-LUCPCWIZ.js.map → chunk-BXEOO2KK.js.map} +0 -0
  84. /package/dist/{chunk-RPWYEJ66.js.map → chunk-CLL2GXNL.js.map} +0 -0
  85. /package/dist/{chunk-TIOXPJIO.js.map → chunk-E4HZTSBP.js.map} +0 -0
  86. /package/dist/{chunk-SXG2NPZP.js.map → chunk-F6NOHVYQ.js.map} +0 -0
  87. /package/dist/{chunk-7EYPNMFQ.js.map → chunk-FSZNZZO5.js.map} +0 -0
  88. /package/dist/{chunk-NCWD4UOI.js.map → chunk-IBRRXLMJ.js.map} +0 -0
  89. /package/dist/{chunk-FSODHLOV.js.map → chunk-KTPMJSLZ.js.map} +0 -0
  90. /package/dist/{chunk-2JIV7Q6A.js.map → chunk-MD6TVSOI.js.map} +0 -0
  91. /package/dist/{chunk-WDOJESN6.js.map → chunk-MYN7CMD5.js.map} +0 -0
  92. /package/dist/{chunk-3DB4DEFY.js.map → chunk-Q6HUW6EI.js.map} +0 -0
  93. /package/dist/{chunk-VV47MWHN.js.map → chunk-R2G4GZID.js.map} +0 -0
  94. /package/dist/{chunk-AWXWDGG5.js.map → chunk-S7RTQRQ3.js.map} +0 -0
  95. /package/dist/{chunk-N2HYXBQ6.js.map → chunk-VNU7OT7O.js.map} +0 -0
  96. /package/dist/{chunk-VQVKI4XO.js.map → chunk-WJSQ5FRV.js.map} +0 -0
  97. /package/dist/{chunk-F2ULTSZ6.js.map → chunk-XMNGHZBR.js.map} +0 -0
  98. /package/dist/{chunk-2QBR4RVO.js.map → chunk-YJSXYHSK.js.map} +0 -0
  99. /package/dist/{chunk-TI2BJ2OB.js.map → chunk-YKNLQLFM.js.map} +0 -0
  100. /package/dist/{chunk-LMMMFZ64.js.map → chunk-YQW7MHST.js.map} +0 -0
  101. /package/dist/{chunk-JRBUSUYD.js.map → chunk-ZXF2XA4R.js.map} +0 -0
  102. /package/dist/{cli-circuit-breaker-XB5FPZJ5.js.map → cli-circuit-breaker-OR2Z2ZXU.js.map} +0 -0
  103. /package/dist/{composite-router-VWQ65U6B.js.map → composite-router-QC4OLIQ5.js.map} +0 -0
  104. /package/dist/{consensus-vote-SB2G2W6G.js.map → consensus-vote-JMIK4USL.js.map} +0 -0
  105. /package/dist/{context-retriever-5VFAIPHM.js.map → context-retriever-CFINY4KH.js.map} +0 -0
  106. /package/dist/{doctor-deep-RFHTNO2P.js.map → doctor-deep-53KZ3IYQ.js.map} +0 -0
  107. /package/dist/{expert-bridge-LDWFPVHK.js.map → expert-bridge-WWAGNKZY.js.map} +0 -0
  108. /package/dist/{factory-AIERXI3O.js.map → factory-3FKPAH26.js.map} +0 -0
  109. /package/dist/{factory-IYL24RFV.js.map → factory-KIGMY2XP.js.map} +0 -0
  110. /package/dist/{improvement-review-GFCDFNYV.js.map → improvement-review-A4HQ7KIQ.js.map} +0 -0
  111. /package/dist/{init-opencode-26HTJ5QO.js.map → init-opencode-IMP5HG2J.js.map} +0 -0
  112. /package/dist/{issue-triage-MVLE3SRA.js.map → issue-triage-VPL3N2AG.js.map} +0 -0
  113. /package/dist/{pr-reviewer-helpers-HXEJ437Q.js.map → pr-reviewer-helpers-6FGXGRYA.js.map} +0 -0
  114. /package/dist/{registry-command-RQH4YGK5.js.map → registry-command-IGVBSZX6.js.map} +0 -0
  115. /package/dist/{repo-security-plan-SIOA64KN.js.map → repo-security-plan-PWFK3LCK.js.map} +0 -0
  116. /package/dist/{research-helpers-synthesize-K43DWQVG.js.map → research-helpers-synthesize-IXWXFRKC.js.map} +0 -0
  117. /package/dist/{routing-memory-AEYB4NPO.js.map → routing-memory-RQUM4XHT.js.map} +0 -0
  118. /package/dist/{session-memory-GZOSVFDD.js.map → session-memory-7TDKNMRE.js.map} +0 -0
  119. /package/dist/{setup-command-TEKCWGGU.js.map → setup-command-MWZ5M3UB.js.map} +0 -0
  120. /package/dist/{setup-config-R7GWRUW2.js.map → setup-config-ICI5OIGW.js.map} +0 -0
  121. /package/dist/{setup-custom-api-DXS3Y4XW.js.map → setup-custom-api-IVJLG6WI.js.map} +0 -0
  122. /package/dist/{tool-memory-CXHXCI6Q.js.map → tool-memory-USBUCDTD.js.map} +0 -0
  123. /package/dist/{weather-report-PYDBRULK.js.map → weather-report-ZLUBKEG3.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/research-helpers-synthesize.ts","../src/cli/research-alignment-map.ts","../src/research/topic-aliases.ts"],"sourcesContent":["/**\n * Research Synthesis Helper\n *\n * Groups papers by topic cluster and generates structured synthesis\n * summaries with themes, findings, and implementation opportunities.\n *\n * @module cli/research-helpers-synthesize\n * (Source: Issue #1386 — Research Synthesis Pipeline)\n */\n\nimport { z } from 'zod';\nimport { loadPapersRegistry } from './research-helpers-io.js';\nimport type { PapersRegistry } from './research-types.js';\nimport type { Result } from '../core/result.js';\nimport { getErrorMessage } from '../core/index.js';\nimport { TECHNIQUE_IMPLEMENTATION_MAP, FEATURE_GATE_INVENTORY } from './research-alignment-map.js';\nimport { normalizeTopicToCanonical } from '../research/topic-aliases.js';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/** A paper entry from the registry, simplified for synthesis. */\nexport interface SynthesisPaper {\n readonly id: string;\n readonly title: string;\n readonly topics: readonly string[];\n readonly tags: readonly string[];\n readonly summary: string;\n readonly keyFindings: readonly string[];\n readonly relevance: string;\n readonly implementationStatus: string;\n readonly techniquesExtracted: readonly string[];\n readonly qualityScore: number;\n readonly evidenceTier: 'high' | 'medium' | 'low';\n /** Source URI — the paper URL, or `arxiv:<id>` (#2663 provenance). */\n readonly sourceUri?: string;\n /** Publication date as recorded in the registry (#2663 provenance). */\n readonly publicationDate?: string;\n}\n\n/**\n * A reference to a source paper, carried into synthesis output so a\n * cluster is traceable back to its inputs (#2663).\n */\nexport interface SynthesisPaperRef {\n readonly id: string;\n readonly title: string;\n readonly sourceUri?: string;\n}\n\n/**\n * A synthesized insight with its provenance (#2663). `sourcePaperIds` is\n * never empty — every merged claim is attributed. When two papers assert\n * the same finding, BOTH ids appear, so a contradiction is *representable*\n * as multiple attributed sources rather than silently collapsed into one.\n */\nexport interface AttributedInsight {\n readonly insight: string;\n readonly sourcePaperIds: readonly string[];\n}\n\n/**\n * Structural enforcement of the #2663 provenance invariant: every\n * synthesized insight must carry at least one source paper id. A doc rule\n * alone is fragile — this Zod schema makes \"no unattributed claim\" a\n * validated guarantee, not a hope.\n */\nexport const AttributedInsightSchema = z.object({\n insight: z.string().min(1),\n sourcePaperIds: z.array(z.string().min(1)).min(1),\n});\n\n/** A cluster of related papers grouped by topic. */\nexport interface PaperCluster {\n readonly topic: string;\n readonly papers: readonly SynthesisPaper[];\n readonly paperCount: number;\n}\n\n/** A technique aligned to an existing implementation. */\nexport interface TechniqueAlignment {\n readonly technique: string;\n readonly status: 'implemented' | 'partial' | 'not-started';\n readonly canonicalPath?: string | undefined;\n readonly improvementHint?: string | undefined;\n}\n\n/** Quality distribution within a cluster. */\nexport interface QualityDistribution {\n readonly avgScore: number;\n readonly high: number;\n readonly medium: number;\n readonly low: number;\n}\n\n/** Synthesis output for a single topic cluster. */\nexport interface ClusterSynthesis {\n readonly topic: string;\n readonly paperCount: number;\n readonly papers: readonly SynthesisPaperRef[];\n readonly commonThemes: readonly string[];\n readonly keyInsights: readonly AttributedInsight[];\n readonly techniques: readonly string[];\n readonly implementationOpportunities: readonly string[];\n readonly gaps: readonly string[];\n readonly alignedTechniques: readonly TechniqueAlignment[];\n readonly qualityDistribution: QualityDistribution;\n}\n\n/** Summary of alignment between research and implementation. */\nexport interface AlignmentSummary {\n readonly implemented: number;\n readonly partial: number;\n readonly notStarted: number;\n readonly total: number;\n readonly topOpportunities: readonly string[];\n}\n\n/** Summary of a single feature gate for synthesis output. */\nexport interface FeatureGateStatus {\n readonly envVar: string;\n readonly defaultValue: string;\n readonly description: string;\n readonly linkedTechniqueCount: number;\n}\n\n/** Full synthesis result across all clusters. */\nexport interface SynthesisResult {\n readonly clusters: readonly ClusterSynthesis[];\n readonly totalPapers: number;\n readonly topicCount: number;\n readonly crossCuttingThemes: readonly string[];\n readonly alignmentSummary: AlignmentSummary;\n readonly featureGates: readonly FeatureGateStatus[];\n}\n\n/** Error for synthesis operations. */\nexport interface SynthesisError {\n readonly code: 'LOAD_ERROR' | 'NO_PAPERS';\n readonly message: string;\n}\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\n/** Minimum papers in a cluster to generate cross-cutting themes. */\nconst MIN_CROSS_CUTTING_CLUSTER_SIZE = 2;\n\n/** Tags that appear across many topics and indicate cross-cutting themes. */\nconst CROSS_CUTTING_TAG_THRESHOLD = 3;\n\n// =============================================================================\n// PUBLIC API\n// =============================================================================\n\n/**\n * Synthesize the research registry by grouping papers into topic clusters\n * and generating structured summaries.\n *\n * @param topicFilter - Optional topic to filter to a single cluster\n * @returns Structured synthesis result\n */\nexport async function synthesizeResearch(\n topicFilter?: string\n): Promise<Result<SynthesisResult, SynthesisError>> {\n const registryResult = await loadPapersRegistry();\n if (!registryResult.ok) {\n return {\n ok: false,\n error: {\n code: 'LOAD_ERROR',\n message: `Failed to load papers: ${getErrorMessage(registryResult.error)}`,\n },\n };\n }\n\n const papers = extractPapers(registryResult.value);\n if (papers.length === 0) {\n return {\n ok: false,\n error: { code: 'NO_PAPERS', message: 'No papers found in registry' },\n };\n }\n\n const clusters = groupByTopic(papers);\n const filtered =\n topicFilter !== undefined ? clusters.filter((c) => c.topic === topicFilter) : clusters;\n\n const syntheses = filtered.map(synthesizeCluster);\n const crossCutting = findCrossCuttingThemes(filtered);\n const alignmentSummary = buildAlignmentSummary(syntheses);\n const featureGates = buildFeatureGateSummary();\n\n return {\n ok: true,\n value: {\n clusters: syntheses,\n totalPapers: papers.length,\n topicCount: filtered.length,\n crossCuttingThemes: crossCutting,\n alignmentSummary,\n featureGates,\n },\n };\n}\n\n// =============================================================================\n// EXTRACTION\n// =============================================================================\n\n/**\n * Safely convert a field that types say is `readonly string[]` but may be\n * null/undefined at runtime (YAML parsing of empty array fields).\n */\nfunction safeArray(value: readonly string[]): string[] {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- YAML parsing can yield null despite type\n if (value === null || value === undefined) return [];\n return Array.from(value);\n}\n\n/** Extract papers from the registry structure. */\n/** Source URI for a paper: prefer the URL, else `arxiv:<id>` (#2663). */\nfunction paperSourceUri(p: PapersRegistry['papers'][string]): string | undefined {\n if (typeof p.url === 'string' && p.url.length > 0) return p.url;\n if (typeof p.arxiv_id === 'string' && p.arxiv_id.length > 0) return `arxiv:${p.arxiv_id}`;\n return undefined;\n}\n\nfunction extractPapers(registry: PapersRegistry): SynthesisPaper[] {\n return Object.entries(registry.papers).map(([id, p]) => {\n const sourceUri = paperSourceUri(p);\n return {\n id,\n title: p.title,\n topics: safeArray(p.topics),\n tags: safeArray(p.tags),\n summary: p.summary.trim(),\n keyFindings: safeArray(p.key_findings),\n relevance: p.relevance,\n implementationStatus: p.implementation_status,\n techniquesExtracted: safeArray(p.techniques_extracted),\n qualityScore: p.quality_score ?? 0,\n evidenceTier: p.evidence_tier ?? 'low',\n // #2663 — carry provenance from the registry into synthesis.\n ...(sourceUri !== undefined ? { sourceUri } : {}),\n ...(typeof p.publication_date === 'string' ? { publicationDate: p.publication_date } : {}),\n };\n });\n}\n\n// =============================================================================\n// GROUPING\n// =============================================================================\n\n/** Group papers by primary topic into clusters, normalizing free-form topics. */\nfunction groupByTopic(papers: readonly SynthesisPaper[]): PaperCluster[] {\n const topicMap = new Map<string, SynthesisPaper[]>();\n\n for (const paper of papers) {\n for (const rawTopic of paper.topics) {\n const topic = normalizeTopicToCanonical(rawTopic);\n const existing = topicMap.get(topic);\n if (existing !== undefined) {\n existing.push(paper);\n } else {\n topicMap.set(topic, [paper]);\n }\n }\n }\n\n const clusters: PaperCluster[] = [];\n for (const [topic, unsortedPapers] of topicMap) {\n // Sort papers within cluster by quality_score descending (high-quality first)\n const topicPapers = [...unsortedPapers].sort((a, b) => b.qualityScore - a.qualityScore);\n clusters.push({\n topic,\n papers: topicPapers,\n paperCount: topicPapers.length,\n });\n }\n\n return clusters.sort((a, b) => b.paperCount - a.paperCount);\n}\n\n// =============================================================================\n// SYNTHESIS\n// =============================================================================\n\n/** Generate synthesis for a single topic cluster. */\n/** Compute quality score distribution for a set of papers. */\nfunction computeClusterQuality(papers: readonly SynthesisPaper[]): QualityDistribution {\n const scores = papers.map((p) => p.qualityScore);\n const totalScore = scores.reduce((sum, s) => sum + s, 0);\n return {\n avgScore: scores.length > 0 ? Math.round((totalScore / scores.length) * 10) / 10 : 0,\n high: papers.filter((p) => p.evidenceTier === 'high').length,\n medium: papers.filter((p) => p.evidenceTier === 'medium').length,\n low: papers.filter((p) => p.evidenceTier === 'low').length,\n };\n}\n\nfunction synthesizeCluster(cluster: PaperCluster): ClusterSynthesis {\n const allTags = collectFrequencies(cluster.papers.flatMap((p) => [...p.tags]));\n const allTechniques = collectFrequencies(\n cluster.papers.flatMap((p) => [...p.techniquesExtracted])\n );\n\n // Common themes: tags that appear in 2+ papers\n const commonThemes = [...allTags.entries()]\n .filter(([, count]) => count >= MIN_CROSS_CUTTING_CLUSTER_SIZE)\n .sort((a, b) => b[1] - a[1])\n .map(([tag]) => tag);\n\n // Techniques across the cluster\n const techniques = [...allTechniques.entries()]\n .sort((a, b) => b[1] - a[1])\n .map(([tech, count]) => (count > 1 ? `${tech} (${String(count)} papers)` : tech));\n\n // Implementation opportunities: techniques not yet implemented\n const notStarted = cluster.papers\n .filter((p) => p.implementationStatus === 'not-started')\n .flatMap((p) => [...p.techniquesExtracted]);\n const uniqueOpportunities = [...new Set(notStarted)];\n\n // Gaps: topics with few papers or missing techniques\n const gaps: string[] = [];\n if (cluster.paperCount === 1) {\n gaps.push(`Only 1 paper — more research needed on ${cluster.topic}`);\n }\n const highRelevanceUnimplemented = cluster.papers.filter(\n (p) => p.relevance === 'high' && p.implementationStatus === 'not-started'\n );\n if (highRelevanceUnimplemented.length > 0) {\n gaps.push(\n `${String(highRelevanceUnimplemented.length)} high-relevance paper(s) not yet implemented`\n );\n }\n\n // Alignment analysis: map techniques to existing implementations\n const allTechNames = [...allTechniques.keys()];\n const alignedTechniques = analyzeClusterAlignment(allTechNames);\n\n const qualityDistribution = computeClusterQuality(cluster.papers);\n\n // Add quality gap if most papers are low-quality\n if (qualityDistribution.low > qualityDistribution.high + qualityDistribution.medium) {\n gaps.push(\n `Mostly low-evidence papers (${String(qualityDistribution.low)}/${String(cluster.paperCount)}) — findings need stronger validation`\n );\n }\n\n return {\n topic: cluster.topic,\n paperCount: cluster.paperCount,\n papers: cluster.papers.map(toPaperRef),\n commonThemes,\n keyInsights: attributeFindings(cluster.papers).slice(0, 10),\n techniques,\n implementationOpportunities: uniqueOpportunities,\n gaps,\n alignedTechniques,\n qualityDistribution,\n };\n}\n\n/** Find themes that span multiple topic clusters. */\nfunction findCrossCuttingThemes(clusters: readonly PaperCluster[]): string[] {\n const tagToTopics = new Map<string, Set<string>>();\n\n for (const cluster of clusters) {\n for (const paper of cluster.papers) {\n for (const tag of paper.tags) {\n const existing = tagToTopics.get(tag);\n if (existing !== undefined) {\n existing.add(cluster.topic);\n } else {\n tagToTopics.set(tag, new Set([cluster.topic]));\n }\n }\n }\n }\n\n return [...tagToTopics.entries()]\n .filter(([, topics]) => topics.size >= CROSS_CUTTING_TAG_THRESHOLD)\n .sort((a, b) => b[1].size - a[1].size)\n .map(([tag, topics]) => `${tag} (spans: ${[...topics].join(', ')})`);\n}\n\n// =============================================================================\n// ALIGNMENT ANALYSIS\n// =============================================================================\n\n/** Analyze technique alignment for a cluster. */\nfunction analyzeClusterAlignment(techniques: readonly string[]): TechniqueAlignment[] {\n const alignments: TechniqueAlignment[] = [];\n\n for (const tech of techniques) {\n // Strip count annotation like \"technique (2 papers)\"\n const baseTech = tech.replace(/\\s*\\(\\d+\\s*papers?\\)$/, '');\n const mapping = TECHNIQUE_IMPLEMENTATION_MAP.get(baseTech);\n\n if (mapping !== undefined) {\n alignments.push({\n technique: baseTech,\n status: mapping.status,\n canonicalPath: mapping.path,\n ...(mapping.hint !== undefined ? { improvementHint: mapping.hint } : {}),\n });\n } else {\n alignments.push({ technique: baseTech, status: 'not-started' });\n }\n }\n\n return alignments;\n}\n\n/** Build alignment summary across all clusters. */\nfunction buildAlignmentSummary(clusters: readonly ClusterSynthesis[]): AlignmentSummary {\n const allAlignments = clusters.flatMap((c) => c.alignedTechniques);\n const implemented = allAlignments.filter((a) => a.status === 'implemented').length;\n const partial = allAlignments.filter((a) => a.status === 'partial').length;\n const notStarted = allAlignments.filter((a) => a.status === 'not-started').length;\n\n // Top opportunities: partial implementations with hints (most improvable)\n const opportunities = allAlignments\n .filter((a) => a.status === 'partial' && a.improvementHint !== undefined)\n .map((a) => `${a.technique}: ${a.improvementHint ?? ''}`)\n .slice(0, 10);\n\n return {\n implemented,\n partial,\n notStarted,\n total: allAlignments.length,\n topOpportunities: opportunities,\n };\n}\n\n/** Build feature gate summary from the inventory. */\nfunction buildFeatureGateSummary(): FeatureGateStatus[] {\n return FEATURE_GATE_INVENTORY.map((g) => ({\n envVar: g.envVar,\n defaultValue: g.defaultValue,\n description: g.description,\n linkedTechniqueCount: g.techniques?.length ?? 0,\n }));\n}\n\n// =============================================================================\n// UTILITIES\n// =============================================================================\n\nfunction collectFrequencies(items: readonly string[]): Map<string, number> {\n const counts = new Map<string, number>();\n for (const item of items) {\n counts.set(item, (counts.get(item) ?? 0) + 1);\n }\n return counts;\n}\n\n/** Project a source paper to the lean reference carried into output (#2663). */\nfunction toPaperRef(p: SynthesisPaper): SynthesisPaperRef {\n return {\n id: p.id,\n title: p.title,\n ...(p.sourceUri !== undefined ? { sourceUri: p.sourceUri } : {}),\n };\n}\n\n/**\n * Deduplicate findings across a cluster's papers WHILE preserving\n * provenance (#2663). Findings are keyed by normalized text; when two\n * papers assert the same finding, both ids are collected — so a\n * contradiction is representable as multiple attributed sources rather\n * than silently collapsed. Every returned insight is validated to carry\n * at least one source id (`AttributedInsightSchema`).\n */\nfunction attributeFindings(papers: readonly SynthesisPaper[]): AttributedInsight[] {\n const byNormalized = new Map<string, { insight: string; sourcePaperIds: Set<string> }>();\n for (const paper of papers) {\n for (const finding of paper.keyFindings) {\n const normalized = finding.toLowerCase().trim();\n if (normalized.length === 0) continue;\n const existing = byNormalized.get(normalized);\n if (existing !== undefined) {\n existing.sourcePaperIds.add(paper.id);\n } else {\n byNormalized.set(normalized, {\n insight: finding,\n sourcePaperIds: new Set([paper.id]),\n });\n }\n }\n }\n return [...byNormalized.values()].map((e) =>\n AttributedInsightSchema.parse({ insight: e.insight, sourcePaperIds: [...e.sourcePaperIds] })\n );\n}\n","/**\n * Research Alignment Map\n *\n * Maps technique names from the research registry to canonical code paths\n * in the nexus-agents codebase. Used by research synthesis to determine\n * which paper techniques are implemented, partially implemented, or new.\n *\n * @module cli/research-alignment-map\n * (Source: Issue #1386 — Research Synthesis Pipeline)\n */\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/** Implementation status for a mapped technique. */\nexport interface TechniqueMapping {\n readonly status: 'implemented' | 'partial';\n readonly path: string;\n readonly hint?: string | undefined;\n}\n\n/** A feature gate that controls an implementation. */\nexport interface FeatureGate {\n /** Environment variable or config key. */\n readonly envVar: string;\n /** Default value when not explicitly set. */\n readonly defaultValue: string;\n /** Brief description of what the gate controls. */\n readonly description: string;\n /** Related technique names from the alignment map (if any). */\n readonly techniques?: readonly string[];\n}\n\n// =============================================================================\n// MAP\n// =============================================================================\n\n/**\n * Maps technique names to canonical code paths.\n * 'implemented' = full implementation exists matching the technique.\n * 'partial' = related code exists but doesn't fully implement the technique.\n */\nexport const TECHNIQUE_IMPLEMENTATION_MAP: ReadonlyMap<string, TechniqueMapping> = new Map([\n // Routing techniques\n ['linucb-routing', { status: 'implemented', path: 'cli-adapters/linucb-bandit.ts' }],\n ['topsis-routing', { status: 'implemented', path: 'cli-adapters/topsis-router.ts' }],\n [\n 'cascade-routing',\n { status: 'implemented', path: 'routing/stages/confidence-cascade-stage.ts' },\n ],\n [\n 'complexity-based-routing',\n { status: 'implemented', path: 'routing/stages/confidence-cascade-stage.ts' },\n ],\n [\n 'moe-routing',\n {\n status: 'implemented',\n path: 'cli-adapters/composite-router.ts',\n hint: '5-stage composite routing selects among specialized CLI experts based on task features',\n },\n ],\n ['two-stage-routing', { status: 'implemented', path: 'cli-adapters/composite-router-stages.ts' }],\n [\n 'capability-instruction-tuning',\n {\n status: 'partial',\n path: 'routing/stages/capability-match-stage.ts',\n hint: 'Static capability profiles, not instruction-tuned',\n },\n ],\n [\n 'knn-routing',\n {\n status: 'implemented',\n path: 'routing/stages/knn-routing-stage.ts',\n hint: 'KnnRoutingStage: cosine similarity over keyword vectors, K-nearest experience patterns, weighted by success rate',\n },\n ],\n ['pilot-budget-routing', { status: 'implemented', path: 'cli-adapters/budget-router.ts' }],\n [\n 'tolerance-routing',\n {\n status: 'implemented',\n path: 'cli-adapters/composite-router-helpers.ts',\n hint: 'TOPSIS_TOLERANCE_BAND_PERCENT (5%) identifies quality-equivalent candidates after TOPSIS ranking',\n },\n ],\n [\n 'sater-routing',\n {\n status: 'implemented',\n path: 'routing/stages/quality-constraint-stage.ts',\n hint: 'QualityConstraintStage filters models by min quality (0.7), max cost, max latency before selection',\n },\n ],\n [\n 'preference-trained-routing',\n { status: 'implemented', path: 'cli-adapters/preference-router.ts' },\n ],\n [\n 'strmac-state-routing',\n {\n status: 'implemented',\n path: 'context/routing-memory.ts',\n hint: 'RoutingMemory maintains state across calls (profile, experience, action cache) feeding LinUCB + weather bonus stages',\n },\n ],\n [\n 'cross-attention-routing',\n {\n status: 'implemented',\n path: 'routing/stages/capability-match-stage.ts',\n hint: 'AttentionMatrix maps task features to capability weights (configurable cross-attention)',\n },\n ],\n\n // Consensus techniques\n ['consensus-protocol', { status: 'implemented', path: 'consensus/engine.ts' }],\n ['majority-voting', { status: 'implemented', path: 'consensus/engine.ts' }],\n ['higher-order-voting', { status: 'implemented', path: 'consensus/higher-order-strategy.ts' }],\n [\n 'anti-conformity-weighting',\n { status: 'implemented', path: 'consensus/higher-order-strategy.ts' },\n ],\n [\n 'agreement-based-cascading',\n {\n status: 'implemented',\n path: 'consensus/engine.ts',\n hint: 'canCascadeEarly() closes proposals when outcome is mathematically determined',\n },\n ],\n [\n 'incremental-quorum',\n {\n status: 'implemented',\n path: 'consensus/incremental-quorum.ts',\n hint: 'Ambiguity detection + voter expansion via VoterExpansionCallback (#1408)',\n },\n ],\n [\n 'aegean-consensus',\n { status: 'partial', path: 'consensus/engine.ts', hint: 'Byzantine tolerance not implemented' },\n ],\n [\n 'cp-wbft-consensus',\n {\n status: 'partial',\n path: 'consensus/engine.ts',\n hint: 'No weighted Byzantine fault tolerance',\n },\n ],\n\n // Memory techniques\n ['adaptive-memory', { status: 'implemented', path: 'memory/adaptive/' }],\n ['mirix-six-type-memory', { status: 'implemented', path: 'memory/typed/' }],\n [\n 'mem0-memory-architecture',\n { status: 'partial', path: 'memory/', hint: 'Multi-backend memory but not mem0 pattern' },\n ],\n [\n 'graph-based-memory',\n {\n status: 'partial',\n path: 'memory/belief/',\n hint: 'Belief triples are graph-like but not full graph DB',\n },\n ],\n ['experience-memory', { status: 'implemented', path: 'memory/session/' }],\n ['hindsight-belief-memory', { status: 'implemented', path: 'memory/belief/' }],\n [\n 'profile-memory',\n {\n status: 'implemented',\n path: 'context/routing-memory.ts',\n hint: 'RoutingMemory stores model preferences per task type and feeds recommendations into composite router via PERSISTENCE_AWARE_FLAGS',\n },\n ],\n [\n 'action-memory',\n {\n status: 'implemented',\n path: 'orchestration/outcomes/',\n hint: 'OutcomeStore records actions+results+context with query-by-category/CLI/time and cross-session persistence',\n },\n ],\n ['reflection-memory', { status: 'implemented', path: 'mcp/tools/orchestrate-reflection.ts' }],\n [\n 'history-encoding',\n {\n status: 'partial',\n path: 'context/token-counter.ts',\n hint: 'Token counting exists but no learned history encoding',\n },\n ],\n\n // Orchestration techniques\n [\n 'aflow-mcts-workflows',\n {\n status: 'partial',\n path: 'workflows/aflow/',\n hint: 'AFlow scaffolding exists but MCTS not implemented',\n },\n ],\n [\n 'dynamic-agent-selection',\n { status: 'implemented', path: 'orchestration/aorchestra/agent-planner.ts' },\n ],\n ['dynamic-subagent-creation', { status: 'implemented', path: 'mcp/tools/create-expert.ts' }],\n ['role-based-protocols', { status: 'implemented', path: 'agents/expert-roles.ts' }],\n [\n 'rule-based-coordination',\n { status: 'implemented', path: 'orchestration/aorchestra/worker-dispatcher.ts' },\n ],\n [\n 'temporal-graph-orchestration',\n {\n status: 'partial',\n path: 'orchestration/graph/',\n hint: 'Graph workflows exist but not temporal-aware',\n },\n ],\n [\n 'model-based-coordination',\n {\n status: 'partial',\n path: 'orchestration/aorchestra/',\n hint: 'Worker dispatch but not model-based coordination theory',\n },\n ],\n [\n 'trinity-roles',\n {\n status: 'partial',\n path: 'agents/expert-roles.ts',\n hint: '10 expert roles, not trinity pattern',\n },\n ],\n [\n 'sew-self-evolving-workflows',\n {\n status: 'partial',\n path: 'workflows/aflow/',\n hint: 'AFlow framework but no self-evolution loop',\n },\n ],\n [\n 'scaling-coordination-predictor',\n {\n status: 'partial',\n path: 'orchestration/aorchestra/agent-planner.ts',\n hint: 'Wave sizing but no scaling prediction',\n },\n ],\n\n // Learning techniques\n [\n 'self-refine-loop',\n {\n status: 'implemented',\n path: 'mcp/tools/orchestrate-dispatch.ts',\n },\n ],\n [\n 'recursive-improvement',\n {\n status: 'implemented',\n path: 'mcp/tools/orchestrate-dispatch.ts',\n },\n ],\n [\n 'rl-orchestrator',\n {\n status: 'implemented',\n path: 'cli-adapters/linucb-bandit.ts',\n hint: 'LinUCB contextual bandit actively selects models via explore-exploit in routing pipeline',\n },\n ],\n ['reflexion-verbal-rl', { status: 'implemented', path: 'mcp/tools/orchestrate-reflection.ts' }],\n\n // Source-derived techniques (Wave 6 — from open-source project analysis)\n ['failure-lesson-injection', { status: 'implemented', path: 'orchestration/failure-lessons.ts' }],\n [\n 'skill-relevance-matching',\n {\n status: 'implemented',\n path: 'agents/experts/skill-matcher.ts',\n hint: 'Matches task keywords to agent skill descriptions for optimal routing',\n },\n ],\n [\n 'context-rot-prevention',\n {\n status: 'implemented',\n path: 'agents/context-pruner.ts',\n hint: 'Token-efficient context pruning prevents quality degradation in long sessions',\n },\n ],\n [\n 'wave-based-parallel-execution',\n {\n status: 'implemented',\n path: 'orchestration/aorchestra/worker-dispatcher.ts',\n hint: 'AOrchestra worker dispatch with cross-wave context sharing',\n },\n ],\n [\n 'write-time-deduplication',\n {\n status: 'implemented',\n path: 'mcp/tools/memory-write.ts',\n hint: 'Semantic dedup at write time prevents memory bloat',\n },\n ],\n]);\n\n// =============================================================================\n// FEATURE GATE INVENTORY\n// =============================================================================\n\n/** Inventory of feature gates linked to research-aligned techniques. */\nexport const FEATURE_GATE_INVENTORY: readonly FeatureGate[] = [\n {\n envVar: 'NEXUS_V2_MODE',\n defaultValue: 'full',\n description: 'V2 pipeline mode (off/partial/full)',\n techniques: ['two-stage-routing', 'cascade-routing'],\n },\n {\n envVar: 'NEXUS_AORCHESTRA',\n defaultValue: 'true',\n description: 'AOrchestra dynamic agent planning',\n techniques: ['dynamic-agent-selection', 'model-based-coordination'],\n },\n {\n envVar: 'NEXUS_AORCHESTRA_DISPATCH',\n defaultValue: 'true',\n description: 'AOrchestra worker dispatch',\n techniques: ['rule-based-coordination', 'self-refine-loop'],\n },\n {\n envVar: 'NEXUS_PERSIST_LEARNING',\n defaultValue: 'true',\n description: 'Cross-session routing persistence',\n techniques: ['linucb-routing', 'preference-trained-routing', 'experience-memory'],\n },\n {\n envVar: 'NEXUS_REFLECTIVE_MEMORY',\n defaultValue: 'shadow',\n description: 'Reflective memory retrieval (shadow=default, true=full, false=off)',\n techniques: ['reflection-memory', 'adaptive-memory', 'reflexion-verbal-rl'],\n },\n {\n envVar: 'NEXUS_BILLING_MODE',\n defaultValue: 'plan',\n description: 'Cost mode (plan=strongest, api=cost-aware)',\n techniques: ['pilot-budget-routing', 'topsis-routing'],\n },\n {\n envVar: 'NEXUS_WORKER_MAX_CALLS',\n defaultValue: '6',\n description: 'Max model calls per orchestrate',\n techniques: ['self-refine-loop', 'recursive-improvement'],\n },\n { envVar: 'NEXUS_AUTH_ENABLED', defaultValue: 'true', description: 'Server authentication' },\n { envVar: 'NEXUS_EVENTBUS_ENABLED', defaultValue: 'true', description: 'EventBus A2A bridge' },\n {\n envVar: 'NEXUS_RATE_LIMIT_ENABLED',\n defaultValue: 'true',\n description: 'Token-bucket rate limiter',\n },\n {\n envVar: 'NEXUS_CIRCUIT_BREAKER_THRESHOLD',\n defaultValue: '5',\n description: 'Circuit breaker failure threshold',\n },\n {\n envVar: 'NEXUS_V2_POLICY_MODE',\n defaultValue: 'block',\n description: 'Policy enforcement (off/warn/block)',\n },\n { envVar: 'NEXUS_LOG_LEVEL', defaultValue: 'info', description: 'Logging verbosity' },\n {\n envVar: 'NEXUS_DISABLE_SESSIONS',\n defaultValue: 'false',\n description: 'Disable session tracking',\n },\n {\n envVar: 'NEXUS_DISABLE_METRICS',\n defaultValue: 'false',\n description: 'Disable metrics tracking',\n },\n {\n envVar: 'NEXUS_ALLOW_MOCK_ORCHESTRATION',\n defaultValue: 'false',\n description: 'Allow mock orchestration (test/CI)',\n },\n {\n envVar: 'NEXUS_MAX_CONCURRENT_EXPERTS',\n defaultValue: '6',\n description: 'Expert pool semaphore capacity',\n },\n {\n envVar: 'NEXUS_VOTE_TIMEOUT_MS',\n defaultValue: '60000',\n description: 'Consensus vote timeout override',\n },\n {\n envVar: 'NEXUS_EXPERT_TIMEOUT_MS',\n defaultValue: '120000',\n description: 'Expert handler timeout override',\n },\n {\n envVar: 'NEXUS_WORKER_TIMEOUT_MS',\n defaultValue: '60000',\n description: 'Worker subprocess timeout override',\n },\n];\n","/**\n * Topic alias map for normalizing free-form topic strings to canonical topics.\n *\n * Maps 200+ free-form topic strings found in papers.yaml to 12 canonical topics.\n * Used by normalizeTopicToCanonical() in research-schemas.ts.\n *\n * @module research/topic-aliases\n * @see Issue #1578 — Topic taxonomy normalization\n */\n\n/**\n * Map of free-form topic strings to canonical topics.\n */\nexport const TOPIC_ALIASES: Readonly<Record<string, string>> = {\n // → consensus\n voting: 'consensus',\n 'consensus-voting': 'consensus',\n debate: 'consensus',\n quorum: 'consensus',\n byzantine: 'consensus',\n 'anti-conformity': 'consensus',\n 'agreement-based': 'consensus',\n 'correlation-aware': 'consensus',\n 'LLM consensus and multi-agent voting mechanisms': 'consensus',\n 'tolerance-parameter': 'consensus',\n\n // → routing\n 'model-routing': 'routing',\n 'model routing': 'routing',\n 'llm-routing': 'routing',\n cascade: 'routing',\n 'cascade-routing': 'routing',\n 'cost-optimization': 'routing',\n 'cost-reduction': 'routing',\n 'model-selection': 'routing',\n topsis: 'routing',\n linucb: 'routing',\n 'contextual-bandit': 'routing',\n 'quality-constrained': 'routing',\n 'budget-constraints': 'routing',\n 'unified-routing': 'routing',\n 'query-model-matching': 'routing',\n 'adaptive model routing and selection optimization': 'routing',\n 'multi-model routing optimization': 'routing',\n 'Single-head cross-attention for query-model matching': 'routing',\n 'performance-cost-tradeoff': 'routing',\n 'task-routing': 'routing',\n 'difficulty-estimation': 'routing',\n 'score-based': 'routing',\n 'optimal-weighting': 'routing',\n 'hierarchical-filtering': 'routing',\n 'preference-optimization': 'routing',\n 'preference-data': 'routing',\n dpo: 'routing',\n 'cross-attention': 'routing',\n 'cma-es': 'routing',\n profile: 'routing',\n prediction: 'routing',\n lightweight: 'routing',\n bayesian: 'routing',\n 'quality-diversity': 'routing',\n 'resource-optimization': 'routing',\n 'routing-latency': 'routing',\n optimization: 'routing',\n 'model-merging': 'routing',\n 'model-zoo': 'routing',\n\n // → memory\n 'context-management': 'memory',\n 'context-compression': 'memory',\n 'context-control': 'memory',\n compression: 'memory',\n 'kv-cache': 'memory',\n 'long-context': 'memory',\n 'long-term-memory': 'memory',\n 'episodic-memory': 'memory',\n 'graph-memory': 'memory',\n 'hierarchical-memory': 'memory',\n 'agentic-memory': 'memory',\n 'lifelong-learning': 'memory',\n 'cross-session-learning': 'memory',\n 'continual-learning': 'memory',\n 'self-editing-memory': 'memory',\n 'six-type-memory': 'memory',\n 'belief-memory': 'memory',\n 'belief-state': 'memory',\n 'action-memory': 'memory',\n 'memory-evolution': 'memory',\n 'virtual-context': 'memory',\n paging: 'memory',\n 'prompt-compression': 'memory',\n 'learned-compression': 'memory',\n zettelkasten: 'memory',\n 'knowledge-distillation': 'memory',\n 'history-encoding': 'memory',\n 'ictm-tuple': 'memory',\n 'latent-space': 'memory',\n 'vector-db': 'memory',\n embedding: 'memory',\n 'Taxonomy of context management strategies': 'memory',\n 'Task-specific context compression': 'memory',\n 'Learned compression modules': 'memory',\n rag: 'memory',\n 'retrieval augmented generation': 'memory',\n svd: 'memory',\n 'svd-mutation': 'memory',\n vae: 'memory',\n knn: 'memory',\n experience: 'memory',\n 'state-aware': 'memory',\n 'temporal-graph': 'memory',\n versioning: 'memory',\n\n // → code-generation\n 'code-repair': 'code-generation',\n 'code-agent': 'code-generation',\n 'code-review': 'code-generation',\n 'software-engineering': 'code-generation',\n 'swe-bench': 'code-generation',\n 'self-improvement': 'code-generation',\n 'self-evolving': 'code-generation',\n 'self-debug': 'code-generation',\n 'self-modification': 'code-generation',\n 'skill-library': 'code-generation',\n 'skill-discovery': 'code-generation',\n 'code review benchmarks': 'code-generation',\n 'code generation evaluation': 'code-generation',\n 'execution-feedback': 'code-generation',\n\n // → cli-tools\n mcp: 'cli-tools',\n 'MCP protocol': 'cli-tools',\n 'MCP security': 'cli-tools',\n 'MCP Security': 'cli-tools',\n 'mcp-applications': 'cli-tools',\n 'model-context-protocol': 'cli-tools',\n puppeteer: 'cli-tools',\n streaming: 'cli-tools',\n integration: 'cli-tools',\n\n // → orchestration\n 'multi-agent': 'orchestration',\n 'multi-agent-systems': 'orchestration',\n 'multi-agent orchestration': 'orchestration',\n 'Multi-Agent Orchestration': 'orchestration',\n 'multi-agent-orchestration': 'orchestration',\n 'multi-agent coordination': 'orchestration',\n 'multi-agent-coordination': 'orchestration',\n 'multi-agent-worker-dispatch': 'orchestration',\n 'multi-agent reliability': 'orchestration',\n 'multi-agent-rl': 'orchestration',\n coordination: 'orchestration',\n coordinator: 'orchestration',\n collaboration: 'orchestration',\n 'graph-orchestration': 'orchestration',\n 'agent architecture': 'orchestration',\n 'dynamic-agent-creation': 'orchestration',\n 'specialized-agents': 'orchestration',\n 'thinker-worker-verifier': 'orchestration',\n 'two-agent': 'orchestration',\n 'meta-agent': 'orchestration',\n agents: 'orchestration',\n 'workflow-optimization': 'orchestration',\n 'workflow-generation': 'orchestration',\n 'agent-communication': 'orchestration',\n 'inter-agent': 'orchestration',\n 'gvu-operator': 'orchestration',\n 'rubber-duck': 'orchestration',\n 'parallel-exploration': 'orchestration',\n kubernetes: 'orchestration',\n 'scale-to-zero': 'orchestration',\n edge: 'orchestration',\n llm: 'orchestration',\n multimodal: 'orchestration',\n production: 'orchestration',\n hybrid: 'orchestration',\n 'automatic-discovery': 'orchestration',\n roadmap: 'orchestration',\n\n // → security\n 'prompt injection defense': 'security',\n 'inter-agent-security': 'security',\n 'agent security': 'security',\n compliance: 'security',\n 'formal-verification': 'security',\n 'formal-safety': 'security',\n\n // → evaluation\n benchmark: 'evaluation',\n benchmarking: 'evaluation',\n survey: 'evaluation',\n 'autonomous agent evaluation benchmarks': 'evaluation',\n 'evaluation-methods': 'evaluation',\n 'LLM evaluation': 'evaluation',\n 'hallucination-detection': 'evaluation',\n 'self-evaluation': 'evaluation',\n 'confidence-probe': 'evaluation',\n 'confidence-aware': 'evaluation',\n verifier: 'evaluation',\n observability: 'evaluation',\n theoretical: 'evaluation',\n 'post-deployment': 'evaluation',\n capability: 'evaluation',\n 'knowledge-gaps': 'evaluation',\n helm: 'evaluation',\n\n // → safety\n 'agentic-safety': 'safety',\n 'agentic AI safety': 'safety',\n 'safety-evaluation': 'safety',\n 'reward-modeling': 'safety',\n 'constitutional-ai': 'safety',\n 'hazard-analysis': 'safety',\n stpa: 'safety',\n 'risk-assessment': 'safety',\n 'fault-tolerance': 'safety',\n 'ai-feedback': 'safety',\n rlaif: 'safety',\n 'human-in-the-loop': 'safety',\n feedback: 'safety',\n 'feedback-loop': 'safety',\n 'feedback-learning': 'safety',\n anthropic: 'safety',\n\n // → planning\n 'decision-making': 'planning',\n 'tree-search': 'planning',\n 'tree-structure': 'planning',\n 'multi-tree': 'planning',\n mcts: 'planning',\n backtrack: 'planning',\n hindsight: 'planning',\n 'task-specific': 'planning',\n\n // → tool-use\n 'tool use': 'tool-use',\n 'tool-augmented reasoning and function calling': 'tool-use',\n 'tool routing optimization': 'tool-use',\n 'dynamic-linking': 'tool-use',\n 'Sparse outcome rewards reduce tool calls by 72%': 'tool-use',\n\n // → reasoning\n 'test-time': 'reasoning',\n 'test-time-scaling': 'reasoning',\n 'inference-scaling': 'reasoning',\n 'inference-optimization': 'reasoning',\n 'self-critique': 'reasoning',\n 'self-reflection': 'reasoning',\n 'self-referential': 'reasoning',\n 'self-play': 'reasoning',\n reflexion: 'reasoning',\n reflection: 'reasoning',\n 'reasoning-optimization': 'reasoning',\n 'meta-thinking': 'reasoning',\n scaling: 'reasoning',\n recursive: 'reasoning',\n 'trajectory-abstraction': 'reasoning',\n 'verbal-rl': 'reasoning',\n exploration: 'reasoning',\n 'Reducible uncertainty modeling across agent trajectories': 'reasoning',\n 'Environmental feedback reduces uncertainty at decision gates': 'reasoning',\n 'reinforcement-learning': 'reasoning',\n transformer: 'reasoning',\n ssm: 'reasoning',\n 'sparse-activation': 'reasoning',\n 'behavior-distillation': 'reasoning',\n 'training-free': 'reasoning',\n 'transfer-learning': 'reasoning',\n 'instruction-tuning': 'reasoning',\n 'Dense process rewards improve performance by 22%': 'reasoning',\n 'prompt-optimization': 'reasoning',\n};\n\n/**\n * Normalize a free-form topic string to a canonical topic.\n * Returns the canonical topic if a mapping exists, otherwise the original string.\n */\nexport function normalizeTopicToCanonical(topic: string): string {\n return TOPIC_ALIASES[topic] ?? topic;\n}\n"],"mappings":"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","names":[]}
@@ -1,4 +1,5 @@
1
1
  import {
2
+ REJECTION_CATEGORIES,
2
3
  createSecureHandler,
3
4
  getToolAnnotations,
4
5
  getToolTimeout,
@@ -6,7 +7,7 @@ import {
6
7
  toolStructuredError,
7
8
  toolSuccessStructured,
8
9
  wrapToolWithTimeout
9
- } from "./chunk-5P5KCVTX.js";
10
+ } from "./chunk-4K4OVG4O.js";
10
11
  import {
11
12
  createLogger,
12
13
  formatZodError,
@@ -14,7 +15,7 @@ import {
14
15
  getOutcomeStore,
15
16
  getPipelineEventBus,
16
17
  getTimeProvider
17
- } from "./chunk-JRBUSUYD.js";
18
+ } from "./chunk-ZXF2XA4R.js";
18
19
  import {
19
20
  getNexusDataDir
20
21
  } from "./chunk-CH7QIDHQ.js";
@@ -766,6 +767,44 @@ function detectCliPerformanceFloor(outcomes, minSamples, windowLabel) {
766
767
  }
767
768
  return signals;
768
769
  }
770
+ var MIN_REJECTION_PATTERN = 3;
771
+ function detectConsensusRejectionSignals(events, windowLabel) {
772
+ if (events.length === 0) return [];
773
+ const allowed = new Set(REJECTION_CATEGORIES);
774
+ const byRule = /* @__PURE__ */ new Map();
775
+ for (const e of events) {
776
+ for (const rule of e.rejectionRules ?? []) {
777
+ if (!allowed.has(rule)) continue;
778
+ byRule.set(rule, (byRule.get(rule) ?? 0) + 1);
779
+ }
780
+ }
781
+ const signals = [];
782
+ for (const [rule, count] of byRule) {
783
+ if (count < MIN_REJECTION_PATTERN) continue;
784
+ signals.push({
785
+ category: "consensus",
786
+ signalKey: `consensus:rejection-pattern:${rule}`,
787
+ severity: count >= MIN_REJECTION_PATTERN * 2 ? "warning" : "info",
788
+ title: `consensus: ${String(count)} plans rejected for \`${rule}\` in ${windowLabel}`,
789
+ body: [
790
+ `Recurring consensus-rejection pattern in the ${windowLabel} window.`,
791
+ "",
792
+ `- Rejection rule: \`${rule}\` (ADR-0016 category)`,
793
+ `- Occurrences: ${String(count)} rejected plans`,
794
+ `- Threshold: \u2265${String(MIN_REJECTION_PATTERN)} plans citing the same rule`,
795
+ "",
796
+ "The planner keeps producing plans that voters reject for the same reason. Feed this back into plan generation (e.g. a planning guardrail or a targeted prompt note) rather than rejecting plan-by-plan. Inspect the rejected proposals via `query_trace` / the consensus audit chain."
797
+ ].join("\n"),
798
+ evidence: {
799
+ samples: count,
800
+ window: windowLabel,
801
+ observedValue: count,
802
+ threshold: MIN_REJECTION_PATTERN
803
+ }
804
+ });
805
+ }
806
+ return signals;
807
+ }
769
808
  function detectFailureCategoryConcentration(outcomes, windowLabel) {
770
809
  const failures = outcomes.filter((o) => !o.success);
771
810
  if (failures.length < 10) return [];
@@ -1004,6 +1043,10 @@ async function fileSignalsAsIssues(signals, ctx) {
1004
1043
  }
1005
1044
  return { issuesFiled, issuesSkipped };
1006
1045
  }
1046
+ function readBufferedVoteRejections(now, lookbackDays) {
1047
+ const cutoff = now - lookbackDays * DAY_MS;
1048
+ return getPipelineEventBus().query({ type: "signal.vote_rejected" }).filter((e) => e.type === "signal.vote_rejected").filter((e) => e.timestamp >= cutoff);
1049
+ }
1007
1050
  async function runImprovementReview(input, deps = {}) {
1008
1051
  const logger = deps.logger ?? createLogger({ component: "improvement_review" });
1009
1052
  const { lookbackDays, fileIssues, minSampleSize, fitnessFloor, selfEvalReportPath } = input;
@@ -1013,10 +1056,12 @@ async function runImprovementReview(input, deps = {}) {
1013
1056
  const windowed = filterByLookback(allOutcomes, lookbackDays, now);
1014
1057
  const audit = safeFitnessAudit(now, { logger });
1015
1058
  const selfEvalSignals = selfEvalReportPath !== void 0 ? await loadSelfEvalSignals(selfEvalReportPath, windowLabel, logger) : [];
1059
+ const rejectionEvents = readBufferedVoteRejections(now, lookbackDays);
1016
1060
  const signals = [
1017
1061
  ...detectCliPerformanceFloor(windowed, minSampleSize, windowLabel),
1018
1062
  ...detectFailureCategoryConcentration(windowed, windowLabel),
1019
1063
  ...detectFitnessSignals(audit, fitnessFloor),
1064
+ ...detectConsensusRejectionSignals(rejectionEvents, windowLabel),
1020
1065
  ...selfEvalSignals
1021
1066
  ];
1022
1067
  signals.sort((a, b) => SEVERITY_ORDER[a.severity] - SEVERITY_ORDER[b.severity]);
@@ -1085,6 +1130,7 @@ export {
1085
1130
  ImprovementReviewInputSchema,
1086
1131
  filterByLookback,
1087
1132
  detectCliPerformanceFloor,
1133
+ detectConsensusRejectionSignals,
1088
1134
  detectFailureCategoryConcentration,
1089
1135
  detectFitnessSignals,
1090
1136
  detectSelfEvalSignals,
@@ -1092,4 +1138,4 @@ export {
1092
1138
  runImprovementReview,
1093
1139
  registerImprovementReviewTool
1094
1140
  };
1095
- //# sourceMappingURL=chunk-XOKGSQIB.js.map
1141
+ //# sourceMappingURL=chunk-OTRXF5NM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/mcp/tools/improvement-review.ts","../src/mcp/middleware/tool-prerequisites.ts","../src/governance/fitness-score.ts","../src/mcp/tools/improvement-review-signals.ts"],"sourcesContent":["/**\n * nexus-agents/mcp - Improvement Review Tool\n *\n * Periodic, threshold-gated observability-driven improvement loop.\n *\n * Reads from existing observability primitives (OutcomeStore, weather-report,\n * fitness-audit, audit-chain) and surfaces patterns that cross documented\n * thresholds as candidate GitHub issues. Never auto-merges; humans or\n * `consensus_vote` decide what to implement.\n *\n * Replaces the deleted `src/workflows/self-development/` engine, which never\n * wired up to consume any of these signals.\n *\n * @module mcp/tools/improvement-review\n * (Source: Issue #2402)\n */\n\nimport { execFile } from 'node:child_process';\nimport { readFile } from 'node:fs/promises';\nimport { promisify } from 'node:util';\n/* eslint-disable max-lines */\nimport { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { createLogger, formatZodError, getErrorMessage } from '../../core/index.js';\nimport { wrapToolWithTimeout, toSdkCallback, getToolTimeout } from '../middleware/tool-wrapper.js';\nimport { createSecureHandler, type HandlerContext } from '../middleware/secure-handler.js';\nimport { withPrerequisite } from '../middleware/tool-prerequisites.js';\nimport {\n toolStructuredError,\n toolSuccessStructured,\n type ToolResult,\n type BaseMcpToolDeps,\n} from './tool-result.js';\nimport { getOutcomeStore } from '../../orchestration/outcomes/outcome-store.js';\nimport type { TaskOutcome } from '../../orchestration/outcomes/outcome-types.js';\nimport { calculateFitnessScore, type FitnessAudit } from '../../governance/fitness-score.js';\nimport { getPipelineEventBus } from '../../pipeline/event-bus.js';\nimport type { VoteRejectedSignalEvent } from '../../pipeline/event-types.js';\nimport { REJECTION_CATEGORIES } from '../../consensus/types-core.js';\nimport { emitFitnessDeclinedSignal } from './improvement-review-signals.js';\nimport { getToolAnnotations } from '../tool-annotations.js';\n\nconst execFileAsync = promisify(execFile);\n\n// ============================================================================\n// Schemas\n// ============================================================================\n\nexport const ImprovementReviewInputSchema = z.object({\n lookbackDays: z\n .number()\n .int()\n .min(1)\n .max(90)\n .optional()\n .default(7)\n .describe('Lookback window for outcome data, in days. Default 7.'),\n fileIssues: z\n .boolean()\n .optional()\n .default(false)\n .describe(\n 'When true, file candidate issues via `gh issue create` for crossed thresholds (rate-limited to 5 per run, deduped against open issues). When false (default), return signals only.'\n ),\n minSampleSize: z\n .number()\n .int()\n .min(1)\n .max(1000)\n .optional()\n .default(5)\n .describe('Minimum sample size before a CLI/category signal can fire.'),\n fitnessFloor: z\n .number()\n .int()\n .min(0)\n .max(100)\n .optional()\n .default(90)\n .describe('Fitness score below this threshold triggers a tech-debt signal.'),\n selfEvalReportPath: z\n .string()\n .optional()\n .describe(\n 'Optional path to a self-eval JSON report (from `self-eval --json`). When set, ' +\n 'high-confidence unanimous deprecate/refactor findings are surfaced as tech-debt ' +\n 'signals through the same deduped/rate-limited issue path (#3224). Unreadable/malformed ' +\n 'reports are skipped (no signal). Absent → no self-eval signals.'\n ),\n});\n\nexport type ImprovementReviewInput = z.infer<typeof ImprovementReviewInputSchema>;\n\nexport type SignalCategory = 'routing' | 'tech-debt' | 'bug' | 'security' | 'consensus';\n\nexport interface ImprovementSignal {\n readonly category: SignalCategory;\n /** Stable key used for dedup against existing issues. */\n readonly signalKey: string;\n /** Severity per CVSS-aligned scale (security uses critical; others use warning/info). */\n readonly severity: 'info' | 'warning' | 'critical';\n /** One-line title suitable for a GitHub issue. */\n readonly title: string;\n /** Multi-line body with evidence (sample counts, time windows, observed values). */\n readonly body: string;\n /** Linkable evidence the signal is grounded in observability data, not intuition. */\n readonly evidence: {\n readonly samples?: number;\n readonly window?: string;\n readonly observedValue?: number;\n readonly threshold?: number;\n };\n}\n\nexport interface ImprovementReviewResponse {\n readonly window: string;\n readonly totalOutcomes: number;\n readonly signals: readonly ImprovementSignal[];\n readonly issuesFiled: readonly { readonly signalKey: string; readonly issueUrl: string }[];\n readonly issuesSkipped: readonly { readonly signalKey: string; readonly reason: string }[];\n}\n\n// ============================================================================\n// Pure threshold logic (testable without fs / network)\n// ============================================================================\n\nconst MAX_ISSUES_PER_RUN = 5;\n\nconst HOUR_MS = 60 * 60 * 1000;\nconst DAY_MS = 24 * HOUR_MS;\n\n/** Filter outcomes to a lookback window. Outcome timestamps are ISO strings. */\nexport function filterByLookback(\n outcomes: readonly TaskOutcome[],\n lookbackDays: number,\n now: number\n): readonly TaskOutcome[] {\n const cutoff = now - lookbackDays * DAY_MS;\n return outcomes.filter((o) => {\n const t = Date.parse(o.timestamp);\n return Number.isFinite(t) && t >= cutoff;\n });\n}\n\n/**\n * Detect CLI × category pairs whose success rate has fallen below the\n * performance floor with at least minSamples observations.\n *\n * Threshold: success rate < 60% AND samples >= minSamples.\n */\nexport function detectCliPerformanceFloor(\n outcomes: readonly TaskOutcome[],\n minSamples: number,\n windowLabel: string\n): readonly ImprovementSignal[] {\n const buckets = new Map<string, { cli: string; category: string; ok: number; total: number }>();\n for (const o of outcomes) {\n const key = `${o.cli}::${o.category}`;\n const bucket = buckets.get(key) ?? { cli: o.cli, category: o.category, ok: 0, total: 0 };\n bucket.total += 1;\n if (o.success) bucket.ok += 1;\n buckets.set(key, bucket);\n }\n\n const signals: ImprovementSignal[] = [];\n for (const b of buckets.values()) {\n if (b.total < minSamples) continue;\n const rate = b.ok / b.total;\n if (rate >= 0.6) continue;\n const ratePct = Math.round(rate * 100);\n signals.push({\n category: 'routing',\n signalKey: `routing:cli-floor:${b.cli}:${b.category}`,\n severity: rate < 0.4 ? 'critical' : 'warning',\n title: `routing: ${b.cli} success rate ${String(ratePct)}% on ${b.category} (${windowLabel})`,\n body: [\n `Observed performance floor breach in the ${windowLabel} window.`,\n '',\n `- CLI: \\`${b.cli}\\``,\n `- Category: \\`${b.category}\\``,\n `- Success rate: ${String(ratePct)}% (${String(b.ok)}/${String(b.total)})`,\n `- Threshold: 60% with ≥${String(minSamples)} samples`,\n '',\n 'Consider routing this category away from this CLI, or investigating the failure pattern via `weather_report` and the OutcomeStore.',\n ].join('\\n'),\n evidence: {\n samples: b.total,\n window: windowLabel,\n observedValue: rate,\n threshold: 0.6,\n },\n });\n }\n return signals;\n}\n\n/**\n * Minimum number of rejected plans citing the same ADR-0016 rule before a\n * recurring-rejection pattern is worth surfacing. Two is coincidence; three is\n * a systemic planning gap (mirrors the DRY \"third occurrence\" rule).\n */\nconst MIN_REJECTION_PATTERN = 3;\n\n/**\n * Detect recurring consensus-rejection patterns (#3259): a single ADR-0016\n * rejection rule (`DRY_VIOLATION`, `OVER_ENGINEERING`, `SCOPE_CREEP`, …) cited\n * across ≥{@link MIN_REJECTION_PATTERN} rejected plans in the window. The\n * `signal.vote_rejected` events are produced by `consensus_vote` on rejection\n * (consensus-vote-signals.ts) and buffered on the pipeline event bus; this\n * detector closes the loop the system review flagged as missing — recurring\n * rejection for the same reason means the planner keeps making the same class\n * of mistake, which the next improvement cycle should name explicitly.\n *\n * Events with no `rejectionRules` (un-categorized rejections) contribute no\n * pattern signal — there is nothing actionable to aggregate on.\n */\nexport function detectConsensusRejectionSignals(\n events: readonly VoteRejectedSignalEvent[],\n windowLabel: string\n): readonly ImprovementSignal[] {\n if (events.length === 0) return [];\n\n // Defense-in-depth allowlist: the only producer (consensus-vote-signals.ts)\n // sources rules from the Zod-validated ADR-0016 enum, so a free-form/poisoned\n // rule cannot reach here today. Re-validating against REJECTION_CATEGORIES\n // makes that safety local — an unexpected rule string never reaches an issue\n // title/body — instead of relying on cross-file inference (#3259 review).\n const allowed = new Set<string>(REJECTION_CATEGORIES);\n const byRule = new Map<string, number>();\n for (const e of events) {\n for (const rule of e.rejectionRules ?? []) {\n if (!allowed.has(rule)) continue;\n byRule.set(rule, (byRule.get(rule) ?? 0) + 1);\n }\n }\n\n const signals: ImprovementSignal[] = [];\n for (const [rule, count] of byRule) {\n if (count < MIN_REJECTION_PATTERN) continue;\n signals.push({\n category: 'consensus',\n signalKey: `consensus:rejection-pattern:${rule}`,\n severity: count >= MIN_REJECTION_PATTERN * 2 ? 'warning' : 'info',\n title: `consensus: ${String(count)} plans rejected for \\`${rule}\\` in ${windowLabel}`,\n body: [\n `Recurring consensus-rejection pattern in the ${windowLabel} window.`,\n '',\n `- Rejection rule: \\`${rule}\\` (ADR-0016 category)`,\n `- Occurrences: ${String(count)} rejected plans`,\n `- Threshold: ≥${String(MIN_REJECTION_PATTERN)} plans citing the same rule`,\n '',\n 'The planner keeps producing plans that voters reject for the same reason. ' +\n 'Feed this back into plan generation (e.g. a planning guardrail or a ' +\n 'targeted prompt note) rather than rejecting plan-by-plan. Inspect the ' +\n 'rejected proposals via `query_trace` / the consensus audit chain.',\n ].join('\\n'),\n evidence: {\n samples: count,\n window: windowLabel,\n observedValue: count,\n threshold: MIN_REJECTION_PATTERN,\n },\n });\n }\n return signals;\n}\n\n/**\n * Detect failure-category concentration: a single failure category accounts\n * for > 50% of all failures with at least 10 failures observed.\n */\nexport function detectFailureCategoryConcentration(\n outcomes: readonly TaskOutcome[],\n windowLabel: string\n): readonly ImprovementSignal[] {\n const failures = outcomes.filter((o) => !o.success);\n if (failures.length < 10) return [];\n\n const byCategory = new Map<string, number>();\n for (const f of failures) {\n const cat = f.failureCategory ?? 'unknown';\n byCategory.set(cat, (byCategory.get(cat) ?? 0) + 1);\n }\n\n const signals: ImprovementSignal[] = [];\n for (const [cat, count] of byCategory) {\n const share = count / failures.length;\n if (share <= 0.5) continue;\n const sharePct = Math.round(share * 100);\n signals.push({\n category: 'bug',\n signalKey: `bug:failure-concentration:${cat}`,\n severity: 'warning',\n title: `bug: ${String(sharePct)}% of failures in ${windowLabel} share category \\`${cat}\\``,\n body: [\n `Failure-category concentration breach in the ${windowLabel} window.`,\n '',\n `- Category: \\`${cat}\\``,\n `- Share: ${String(sharePct)}% (${String(count)}/${String(failures.length)} failures)`,\n `- Threshold: > 50% with ≥10 failures`,\n '',\n 'A single failure mode dominating the error budget usually means a systemic bug or routing miss. Investigate via `query_trace` and the OutcomeStore.',\n ].join('\\n'),\n evidence: {\n samples: failures.length,\n window: windowLabel,\n observedValue: share,\n threshold: 0.5,\n },\n });\n }\n return signals;\n}\n\nfunction buildFloorSignal(audit: FitnessAudit, fitnessFloor: number): ImprovementSignal {\n return {\n category: 'tech-debt',\n signalKey: `tech-debt:fitness-below-floor`,\n severity: audit.score < 70 ? 'critical' : 'warning',\n title: `tech-debt: fitness score ${String(audit.score)}/100 below floor ${String(fitnessFloor)}`,\n body: [\n `Code fitness score has dropped below the governance floor.`,\n '',\n `- Score: ${String(audit.score)} / 100`,\n `- Floor: ${String(fitnessFloor)} (governance threshold per CLAUDE.md)`,\n `- Findings: ${String(audit.findings.length)} total`,\n '',\n 'Run `nexus-agents fitness-audit` for the full breakdown. Critical findings:',\n ...audit.findings\n .filter((f) => f.severity === 'critical')\n .slice(0, 5)\n .map((f) => `- ${f.dimension}: ${f.description}`),\n ].join('\\n'),\n evidence: { observedValue: audit.score, threshold: fitnessFloor },\n };\n}\n\nfunction buildCriticalFindingSignal(finding: FitnessAudit['findings'][number]): ImprovementSignal {\n return {\n category: 'tech-debt',\n signalKey: `tech-debt:fitness-critical:${finding.dimension}`,\n severity: 'critical',\n title: `tech-debt: critical fitness finding in ${finding.dimension}`,\n body: [\n `Fitness audit returned a CRITICAL finding.`,\n '',\n `- Dimension: \\`${finding.dimension}\\``,\n `- Description: ${finding.description}`,\n `- Points deducted: ${String(finding.pointsDeducted)}`,\n finding.location !== undefined ? `- Location: ${finding.location}` : '',\n finding.suggestion !== undefined ? `- Suggestion: ${finding.suggestion}` : '',\n ]\n .filter((line) => line.length > 0)\n .join('\\n'),\n evidence: { observedValue: -finding.pointsDeducted },\n };\n}\n\n/** Detect fitness signals: score below floor OR critical findings. */\nexport function detectFitnessSignals(\n audit: FitnessAudit,\n fitnessFloor: number\n): readonly ImprovementSignal[] {\n const signals: ImprovementSignal[] = [];\n if (audit.score < fitnessFloor) signals.push(buildFloorSignal(audit, fitnessFloor));\n for (const finding of audit.findings) {\n if (finding.severity === 'critical') signals.push(buildCriticalFindingSignal(finding));\n }\n return signals;\n}\n\n// ============================================================================\n// Self-eval findings → tech-debt signals (#3224)\n// ============================================================================\n\n/** Minimum confidence for a self-eval finding to surface as a signal. */\nconst SELF_EVAL_CONFIDENCE_FLOOR = 0.8;\n\n/**\n * Minimal, defensive schema for the `self-eval --json` report. We only read the\n * fields needed to surface a finding; unknown extras are ignored so the parse\n * tolerates schema drift in the (externally produced) artifact.\n */\nconst SelfEvalReportSchema = z.object({\n results: z.array(\n z.object({\n component: z.string(),\n finalRecommendation: z.string(),\n confidence: z.number(),\n dissent: z.array(z.unknown()).optional().default([]),\n evidenceQuality: z.number().optional(),\n })\n ),\n});\n\n/**\n * Convert a parsed self-eval report into tech-debt `ImprovementSignal`s.\n *\n * Only **actionable, high-confidence, unanimous** findings surface (#3224): a\n * `deprecate`/`refactor` recommendation with NO dissent and confidence at/above\n * {@link SELF_EVAL_CONFIDENCE_FLOOR}. This is a pure transform — it surfaces a\n * human decision point (a candidate issue), never an automatic routing change.\n */\nexport function detectSelfEvalSignals(\n report: z.infer<typeof SelfEvalReportSchema>,\n windowLabel: string\n): readonly ImprovementSignal[] {\n const signals: ImprovementSignal[] = [];\n for (const r of report.results) {\n const actionable =\n r.finalRecommendation === 'deprecate' || r.finalRecommendation === 'refactor';\n if (!actionable || r.dissent.length > 0 || r.confidence < SELF_EVAL_CONFIDENCE_FLOOR) continue;\n signals.push({\n category: 'tech-debt',\n signalKey: `tech-debt:self-eval:${r.component}:${r.finalRecommendation}`,\n severity: r.finalRecommendation === 'deprecate' ? 'warning' : 'info',\n title: `tech-debt: self-eval recommends ${r.finalRecommendation} for ${r.component}`,\n body: [\n `All self-eval evaluators agreed (no dissent) on **${r.finalRecommendation}** for \\`${r.component}\\``,\n `with confidence ${(r.confidence * 100).toFixed(0)}%${r.evidenceQuality !== undefined ? ` (evidence quality ${(r.evidenceQuality * 100).toFixed(0)}%)` : ''}.`,\n '',\n 'This is a RECOMMENDATION surfaced for human review — not an automatic change.',\n ].join('\\n'),\n evidence: {\n observedValue: r.confidence,\n threshold: SELF_EVAL_CONFIDENCE_FLOOR,\n window: windowLabel,\n },\n });\n }\n return signals;\n}\n\n/**\n * Read + parse a self-eval JSON report and convert it to signals. Fail-soft:\n * an unreadable or malformed report yields NO signals (logged at warn) rather\n * than breaking the review.\n */\nexport async function loadSelfEvalSignals(\n reportPath: string,\n windowLabel: string,\n logger: ReturnType<typeof createLogger>\n): Promise<readonly ImprovementSignal[]> {\n try {\n const raw = await readFile(reportPath, 'utf8');\n const parsed = SelfEvalReportSchema.safeParse(JSON.parse(raw));\n if (!parsed.success) {\n logger.warn('Self-eval report ignored — schema mismatch', {\n reportPath,\n error: formatZodError(parsed.error),\n });\n return [];\n }\n return detectSelfEvalSignals(parsed.data, windowLabel);\n } catch (error) {\n logger.warn('Self-eval report ignored — unreadable/invalid JSON', {\n reportPath,\n error: getErrorMessage(error),\n });\n return [];\n }\n}\n\n// ============================================================================\n// Issue filing (gated, dedup-checked, command-injection-safe)\n// ============================================================================\n\n/**\n * Check whether an existing OPEN issue already covers this signal key.\n * Uses `gh issue list --search` with the signal key as a literal phrase.\n * The signal key appears in our filed-issue body so this dedup is reliable.\n */\nasync function existingIssueForSignal(signalKey: string): Promise<string | null> {\n try {\n // Strip double-quotes from the search term so a quote in the signalKey\n // (e.g. an oddly-named self-eval component path, #3224) can't break the\n // `\"...\" in:body` phrase query and silently defeat dedup → refiling.\n const searchTerm = signalKey.replace(/\"/g, '');\n const { stdout } = await execFileAsync('gh', [\n 'issue',\n 'list',\n '--state',\n 'open',\n '--search',\n `\"${searchTerm}\" in:body`,\n '--json',\n 'number,url',\n '--limit',\n '5',\n ]);\n const parsed = JSON.parse(stdout) as readonly { url?: string }[];\n if (parsed.length > 0 && typeof parsed[0]?.url === 'string') {\n return parsed[0].url;\n }\n return null;\n } catch {\n // gh failure → conservatively treat as \"no dup\" but log upstream.\n return null;\n }\n}\n\n/**\n * File an issue via `gh issue create` using execFile (no shell, no\n * command-injection risk on errorMessage / title / body content).\n */\nasync function fileIssueForSignal(\n signal: ImprovementSignal\n): Promise<{ ok: true; url: string } | { ok: false; error: string }> {\n // Embed the signal key in the body so dedup is reliable on subsequent runs.\n const body = `${signal.body}\\n\\n---\\n\\n_Signal key (do not edit): \\`${signal.signalKey}\\` · Generated by \\`improvement_review\\` (#2402) · Severity: ${signal.severity}_`;\n const labels = signal.category === 'security' ? 'security' : signal.category;\n\n try {\n const { stdout } = await execFileAsync('gh', [\n 'issue',\n 'create',\n '--title',\n signal.title,\n '--body',\n body,\n '--label',\n labels,\n ]);\n const url = stdout.trim();\n if (!url.startsWith('https://')) {\n return { ok: false, error: `gh returned unexpected output: ${stdout.slice(0, 200)}` };\n }\n return { ok: true, url };\n } catch (caught) {\n const message = caught instanceof Error ? caught.message : String(caught);\n return { ok: false, error: message };\n }\n}\n\n// ============================================================================\n// Handler\n// ============================================================================\n\nfunction safeFitnessAudit(now: number, ctx: HandlerContext): FitnessAudit {\n try {\n return calculateFitnessScore('improvement-review');\n } catch (caught) {\n ctx.logger.warn('fitness audit failed; skipping fitness signals', {\n error: caught instanceof Error ? caught.message : String(caught),\n });\n return {\n score: 100,\n dimensions: {} as FitnessAudit['dimensions'],\n findings: [],\n timestamp: new Date(now).toISOString(),\n version: 'improvement-review-fallback',\n };\n }\n}\n\nconst SEVERITY_ORDER: Record<ImprovementSignal['severity'], number> = {\n critical: 0,\n warning: 1,\n info: 2,\n};\n\nasync function fileSignalsAsIssues(\n signals: readonly ImprovementSignal[],\n ctx: HandlerContext\n): Promise<{\n issuesFiled: { signalKey: string; issueUrl: string }[];\n issuesSkipped: { signalKey: string; reason: string }[];\n}> {\n const issuesFiled: { signalKey: string; issueUrl: string }[] = [];\n const issuesSkipped: { signalKey: string; reason: string }[] = [];\n\n for (const signal of signals) {\n if (issuesFiled.length >= MAX_ISSUES_PER_RUN) {\n issuesSkipped.push({ signalKey: signal.signalKey, reason: 'rate-limit' });\n continue;\n }\n const existing = await existingIssueForSignal(signal.signalKey);\n if (existing !== null) {\n issuesSkipped.push({ signalKey: signal.signalKey, reason: `dup:${existing}` });\n continue;\n }\n const result = await fileIssueForSignal(signal);\n if (result.ok) {\n issuesFiled.push({ signalKey: signal.signalKey, issueUrl: result.url });\n ctx.logger.info('improvement signal filed', {\n signalKey: signal.signalKey,\n url: result.url,\n });\n } else {\n issuesSkipped.push({ signalKey: signal.signalKey, reason: `error:${result.error}` });\n }\n }\n\n return { issuesFiled, issuesSkipped };\n}\n\n/**\n * Read `signal.vote_rejected` events from the pipeline bus's buffered history,\n * narrowed to the lookback window. Returns `[]` if the bus is empty or every\n * event predates the window. Fail-soft: never throws into the review run.\n *\n * The bus is a per-process module singleton (event-bus.ts), so this only sees\n * rejections emitted by `consensus_vote` *in the same process* — i.e. a\n * long-lived MCP server where both tools share the buffer. In separate\n * CLI invocations the buffer starts empty and this correctly yields no signals\n * (the loop degrades to \"no consensus data\" rather than misreporting).\n */\nfunction readBufferedVoteRejections(\n now: number,\n lookbackDays: number\n): readonly VoteRejectedSignalEvent[] {\n const cutoff = now - lookbackDays * DAY_MS;\n return getPipelineEventBus()\n .query({ type: 'signal.vote_rejected' })\n .filter((e): e is VoteRejectedSignalEvent => e.type === 'signal.vote_rejected')\n .filter((e) => e.timestamp >= cutoff);\n}\n\n/**\n * Context-free runner exposed for both the MCP handler and the\n * `nexus-agents improvement-review` CLI subcommand (#2444). Pure dependencies\n * — pass a logger and an OutcomeStore-query result if you want to inject test\n * data; defaults read the global store and a no-op logger.\n */\nexport async function runImprovementReview(\n input: ImprovementReviewInput,\n deps: { readonly logger?: ReturnType<typeof createLogger> } = {}\n): Promise<ImprovementReviewResponse> {\n const logger = deps.logger ?? createLogger({ component: 'improvement_review' });\n const { lookbackDays, fileIssues, minSampleSize, fitnessFloor, selfEvalReportPath } = input;\n const now = Date.now();\n const windowLabel = `${String(lookbackDays)}d`;\n\n const allOutcomes = getOutcomeStore().query();\n const windowed = filterByLookback(allOutcomes, lookbackDays, now);\n const audit = safeFitnessAudit(now, { logger } as HandlerContext);\n\n // Surface high-confidence unanimous self-eval findings as tech-debt signals\n // (#3224) — opt-in via selfEvalReportPath, fail-soft (no path / bad file → none).\n const selfEvalSignals =\n selfEvalReportPath !== undefined\n ? await loadSelfEvalSignals(selfEvalReportPath, windowLabel, logger)\n : [];\n\n // Recurring consensus-rejection patterns (#3259). `consensus_vote` buffers a\n // `signal.vote_rejected` event per rejected plan on the pipeline bus; read the\n // buffered history (not a live subscription — this is a one-shot tool) and\n // window-filter by event timestamp before aggregating.\n const rejectionEvents = readBufferedVoteRejections(now, lookbackDays);\n\n const signals: ImprovementSignal[] = [\n ...detectCliPerformanceFloor(windowed, minSampleSize, windowLabel),\n ...detectFailureCategoryConcentration(windowed, windowLabel),\n ...detectFitnessSignals(audit, fitnessFloor),\n ...detectConsensusRejectionSignals(rejectionEvents, windowLabel),\n ...selfEvalSignals,\n ];\n signals.sort((a, b) => SEVERITY_ORDER[a.severity] - SEVERITY_ORDER[b.severity]);\n\n // Close the self-tuning loop: a below-floor fitness audit emits\n // signal.fitness_declined onto the typed pipeline bus for the shadow\n // TuneStage (#3147; #3289 Option 2 — observability signals route through bus A).\n emitFitnessDeclinedSignal(audit, fitnessFloor, getPipelineEventBus(), logger);\n\n const { issuesFiled, issuesSkipped } = fileIssues\n ? await fileSignalsAsIssues(signals, { logger } as HandlerContext)\n : { issuesFiled: [], issuesSkipped: [] };\n\n return {\n window: windowLabel,\n totalOutcomes: windowed.length,\n signals,\n issuesFiled,\n issuesSkipped,\n };\n}\n\nasync function reviewHandler(args: unknown, ctx: HandlerContext): Promise<ToolResult> {\n const parsed = ImprovementReviewInputSchema.safeParse(args);\n if (!parsed.success) {\n return toolStructuredError({\n errorCategory: 'validation',\n message: `Validation error: ${formatZodError(parsed.error)}`,\n });\n }\n const response = await runImprovementReview(parsed.data, { logger: ctx.logger });\n return toolSuccessStructured(response as unknown as Record<string, unknown>);\n}\n\n// ============================================================================\n// Registration\n// ============================================================================\n\nexport type ImprovementReviewDeps = BaseMcpToolDeps;\n\nconst description =\n 'Periodic threshold-gated observability-driven improvement loop. Reads OutcomeStore + ' +\n 'fitness audit, surfaces patterns crossing documented thresholds as candidate findings. ' +\n 'When fileIssues=true, files candidate GitHub issues via `gh issue create` (rate-limited ' +\n 'to 5 per run, deduped against open issues). Never auto-merges. Replaces the deleted ' +\n 'self-development engine (#2402).';\n\nconst TOOL_INPUT_SCHEMA = {\n lookbackDays: z\n .number()\n .int()\n .min(1)\n .max(90)\n .optional()\n .describe('Lookback window for outcome data, in days. Default 7.'),\n fileIssues: z\n .boolean()\n .optional()\n .describe(\n 'When true, file candidate issues for crossed thresholds (default false — return signals only)'\n ),\n minSampleSize: z\n .number()\n .int()\n .min(1)\n .max(1000)\n .optional()\n .describe('Minimum sample size before a CLI/category signal fires (default 5).'),\n fitnessFloor: z\n .number()\n .int()\n .min(0)\n .max(100)\n .optional()\n .describe('Fitness score below this threshold triggers a tech-debt signal (default 90).'),\n selfEvalReportPath: z\n .string()\n .optional()\n .describe(\n 'Optional path to a self-eval JSON report. High-confidence unanimous ' +\n 'deprecate/refactor findings surface as tech-debt signals (#3224).'\n ),\n};\n\n/** @category MCP */\nexport function registerImprovementReviewTool(\n server: McpServer,\n deps: ImprovementReviewDeps\n): void {\n const logger = deps.logger ?? createLogger({ tool: 'improvement_review' });\n const secureHandler = createSecureHandler(reviewHandler, {\n toolName: 'improvement_review',\n rateLimiter: deps.rateLimiter,\n logger,\n });\n const guardedHandler = withPrerequisite('improvement_review', secureHandler);\n const timeoutMs = getToolTimeout('improvement_review', deps.security);\n const wrappedHandler = wrapToolWithTimeout('improvement_review', guardedHandler, {\n timeoutMs,\n logger,\n });\n server.registerTool(\n 'improvement_review',\n {\n description,\n inputSchema: TOOL_INPUT_SCHEMA,\n annotations: getToolAnnotations('improvement_review'),\n },\n toSdkCallback(wrappedHandler)\n );\n logger.info('Registered improvement_review tool');\n}\n","/**\n * nexus-agents/mcp - Tool Prerequisite Gates\n *\n * Blocks sensitive MCP tools from running unless a **world-state\n * precondition** holds at call time (Issue #2652, Epic B).\n *\n * DESIGN — predicate, not session-ordering. A prerequisite is a predicate\n * over observable world state (is `gh` installed? is the data dir\n * writable?), evaluated on every invocation. It is NOT \"tool A must have\n * been called before tool B\" — MCP `tools/call` invocations are\n * independent, and a session-ordering gate is satisfied by an LLM calling\n * the prior tool pointlessly without making the precondition true. If a\n * requirement can only be expressed as \"call X first,\" it is not a\n * prerequisite — it is the tool's own internal responsibility (e.g.\n * untrusted-input trust-tier classification stays inside `issue_triage`\n * per `.rules/untrusted-input.md`, it is not gated here).\n *\n * Fail-closed: a predicate that throws blocks the tool.\n *\n * @module mcp/middleware/tool-prerequisites\n * @see Issue #2652\n */\n\nimport { execFile } from 'node:child_process';\nimport { access, constants } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport { promisify } from 'node:util';\nimport { getErrorMessage } from '../../core/index.js';\nimport { getNexusDataDir } from '../../config/nexus-data-dir.js';\nimport { toolStructuredError, type ToolResult } from '../tools/tool-result.js';\nimport type { ContextAwareToolHandler, ToolHandler } from './middleware-chain.js';\n\nconst execFileAsync = promisify(execFile);\n\n/** Outcome of evaluating a prerequisite predicate. */\nexport interface PrerequisiteResult {\n ok: boolean;\n /** When `!ok`: what would make the predicate pass. Surfaced to the caller. */\n remediation?: string;\n}\n\n/** A world-state precondition a guarded tool requires at call time. */\nexport interface ToolPrerequisite {\n /** Stable identifier, e.g. `data-dir-writable`. */\n name: string;\n /** Why the tool needs it — for `.rules/tool-prerequisites.md` + the block envelope. */\n rationale: string;\n /** World-state predicate. MUST be cheap and side-effect-free. */\n check: () => Promise<PrerequisiteResult> | PrerequisiteResult;\n}\n\n// ============================================================================\n// Predicates\n// ============================================================================\n\n/** The `gh` CLI is on PATH — required by tools that file/read GitHub state. */\nasync function ghCliAvailable(): Promise<PrerequisiteResult> {\n try {\n await execFileAsync('gh', ['--version'], { timeout: 5000 });\n return { ok: true };\n } catch (err) {\n return {\n ok: false,\n remediation: `the 'gh' CLI is not available (${getErrorMessage(err)}) — install GitHub CLI and authenticate (\\`gh auth login\\`)`,\n };\n }\n}\n\n/**\n * The runtime data directory is writable, or — if it does not exist yet —\n * creatable (its parent is writable). Memory/registry backends create the\n * dir on demand, so \"not yet created\" is not a failure; an unwritable\n * parent is.\n */\nasync function dataDirWritable(): Promise<PrerequisiteResult> {\n const dir = getNexusDataDir();\n try {\n await access(dir, constants.W_OK);\n return { ok: true };\n } catch {\n // Dir may not exist yet — backends create it on demand. Treat a\n // writable parent (creatable) as satisfying the precondition.\n try {\n await access(dirname(dir), constants.W_OK);\n return { ok: true };\n } catch (err) {\n return {\n ok: false,\n remediation: `NEXUS_DATA_DIR (${dir}) is not writable or creatable (${getErrorMessage(err)}) — fix its permissions; run \\`nexus-agents doctor\\` to diagnose`,\n };\n }\n }\n}\n\n// ============================================================================\n// Registry\n// ============================================================================\n\n/**\n * Tools guarded by a call-time prerequisite. Keep this in sync with\n * `.rules/tool-prerequisites.md` — the `check:tool-prerequisites` CI gate\n * verifies every non-read-only tool is either listed here or in\n * `NO_PREREQUISITE` with a reason.\n */\nexport const TOOL_PREREQUISITES: Record<string, ToolPrerequisite> = {\n improvement_review: {\n name: 'gh-cli-available',\n rationale:\n \"improvement_review's fileIssues mode shells out to `gh` to file candidate issues; without it the write path fails mid-operation\",\n check: ghCliAvailable,\n },\n memory_write: {\n name: 'data-dir-writable',\n rationale:\n 'memory_write persists entries under NEXUS_DATA_DIR — an unwritable data dir fails the write confusingly mid-operation',\n check: dataDirWritable,\n },\n registry_import: {\n name: 'data-dir-writable',\n rationale:\n 'registry_import persists a draft registry entry under NEXUS_DATA_DIR when not in dryRun mode',\n check: dataDirWritable,\n },\n};\n\n/**\n * Non-read-only tools that deliberately have NO call-time prerequisite,\n * with the reason. The `check:tool-prerequisites` gate requires every\n * non-read-only tool to appear here or in `TOOL_PREREQUISITES`, so a newly\n * added sensitive tool can't ship ungated by omission.\n */\nexport const NO_PREREQUISITE: Record<string, string> = {\n orchestrate: 'orchestration is self-contained; sub-tool calls carry their own gates',\n create_expert: 'in-memory expert creation; no external precondition',\n execute_expert:\n 'adapter availability is handled by the resilient-adapter circuit breaker, not a pre-gate',\n run_workflow: 'workflow execution is self-contained; step tools carry their own gates',\n run_graph_workflow: 'graph execution is self-contained; node tools carry their own gates',\n run_pipeline: 'pipeline execution is self-contained; stage tools carry their own gates',\n run_dev_pipeline: 'pipeline execution is self-contained; stage tools carry their own gates',\n execute_spec: 'spec execution is self-contained; stage tools carry their own gates',\n consensus_vote: 'voter-CLI availability is handled by per-voter fallback, not a pre-gate',\n supply_chain_tradeoff_panel: 'wraps consensus_vote; same per-voter fallback applies',\n pr_review: 'wraps consensus_vote; same per-voter fallback applies',\n research_add:\n 'arXiv fetch failures surface as a transient envelope from the handler; no useful pre-gate',\n research_add_source:\n 'GitHub metadata fetch is best-effort with graceful fallback; no useful pre-gate',\n research_catalog_review: 'operates on local catalog state already loaded by the handler',\n issue_triage:\n 'untrusted-input safety (trust-tier classification, Rule of Two) is internal-handler logic per .rules/untrusted-input.md — not a call-time world-state predicate',\n cancel_job:\n 'reads + writes the local sidecar file only; cancel-after-complete is an idempotent no-op (first-wins) so misuse is bounded — no pre-gate needed',\n run_quality_gate:\n 'stateless QA gate over the given projectDir; a missing toolchain (tsc/eslint/vitest/build) surfaces as a check failure in the verdict, not a call-time world-state precondition — no pre-gate needed',\n};\n\n// ============================================================================\n// Middleware\n// ============================================================================\n\n/** Either MCP handler shape, both structurally callable with `(args, ctx?)`. */\ntype AnyToolHandler = ContextAwareToolHandler | ToolHandler;\n/** Concrete callable accepting an optional context — what the gate produces. */\ntype GuardedHandler = (args: unknown, ctx?: unknown) => Promise<ToolResult>;\n\n/**\n * Wrap `handler` so `prereq` is evaluated before it runs. A failing or\n * throwing predicate returns a structured `permission` error envelope\n * (#2649) carrying the failed prerequisite + a remediation hint in\n * `detail` — so the caller knows how to recover, not just that it was\n * blocked. Exported for testing; production code uses `withPrerequisite`.\n */\nexport function applyPrerequisite(\n toolName: string,\n prereq: ToolPrerequisite,\n handler: AnyToolHandler\n): GuardedHandler {\n return async (args: unknown, ctx?: unknown): Promise<ToolResult> => {\n let result: PrerequisiteResult;\n try {\n result = await prereq.check();\n } catch (err) {\n // Fail closed — a predicate that throws blocks the tool.\n result = { ok: false, remediation: `prerequisite check threw: ${getErrorMessage(err)}` };\n }\n if (!result.ok) {\n return toolStructuredError({\n errorCategory: 'permission',\n message: `${toolName} blocked: prerequisite '${prereq.name}' not satisfied`,\n detail: {\n failedPrerequisite: prereq.name,\n rationale: prereq.rationale,\n remediation: result.remediation ?? 'see .rules/tool-prerequisites.md',\n },\n });\n }\n return (handler as GuardedHandler)(args, ctx);\n };\n}\n\n/**\n * Wrap a handler so its tool's prerequisite (if any) is evaluated before\n * the handler runs. Tools with no entry in `TOOL_PREREQUISITES` pass\n * through untouched.\n */\nexport function withPrerequisite(toolName: string, handler: AnyToolHandler): AnyToolHandler {\n const prereq = TOOL_PREREQUISITES[toolName];\n if (prereq === undefined) return handler;\n return applyPrerequisite(toolName, prereq, handler);\n}\n","/**\n * CLI Orchestration Fitness Score — real filesystem analysis.\n * Penalizes duplicate paths, hidden behavior, non-determinism, poor\n * observability, config sprawl, cross-layer coupling. Rewards canonical\n * paths, determinism, telemetry, CLI ergonomics, governance.\n * @module governance/fitness-score\n */\n\n/* eslint-disable max-lines -- cohesive fitness calculator (governance allows 400-600) */\n\nimport { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { createLogger, type ILogger } from '../core/index.js';\n\n/** Find package root by walking up from current dir to find package.json with our name */\nfunction findPkgRoot(): string {\n let dir = import.meta.dirname;\n for (let i = 0; i < 10; i++) {\n const pkgPath = join(dir, 'package.json');\n if (existsSync(pkgPath)) {\n const content = readFileSync(pkgPath, 'utf-8');\n if (content.includes('\"nexus-agents\"')) return dir;\n }\n dir = join(dir, '..');\n }\n return join(import.meta.dirname, '../..');\n}\n\nconst PKG_ROOT = findPkgRoot();\nconst SRC_ROOT = join(PKG_ROOT, 'src');\nconst REPO_ROOT = join(PKG_ROOT, '../..');\nconst DOCS_ROOT = join(REPO_ROOT, 'docs');\n\nconst DETERMINISM_EXCLUDES: RegExp[] = [\n /\\.test\\.ts$/,\n /\\.spec\\.ts$/,\n /random-provider\\.ts$/,\n /time-provider\\.ts$/,\n];\n\n// =========================================================================\n// Filesystem utility methods (inlined from scripts/fitness-utils.ts)\n// =========================================================================\n\nfunction countFiles(dir: string, pattern: RegExp): number {\n if (!existsSync(dir)) return 0;\n let count = 0;\n for (const entry of readdirSync(dir)) {\n const fullPath = join(dir, entry);\n const stat = statSync(fullPath);\n if (stat.isDirectory() && !entry.startsWith('.')) {\n count += countFiles(fullPath, pattern);\n } else if (pattern.test(entry)) {\n count++;\n }\n }\n return count;\n}\n\nfunction fileContains(filePath: string, pattern: RegExp): boolean {\n if (!existsSync(filePath)) return false;\n return pattern.test(readFileSync(filePath, 'utf-8'));\n}\n\nfunction isExcluded(entry: string, excludePatterns?: RegExp[]): boolean {\n return excludePatterns?.some((p) => p.test(entry)) ?? false;\n}\n\nfunction countMatchesInFile(fullPath: string, contentPattern: RegExp): number {\n const matches = readFileSync(fullPath, 'utf-8').match(contentPattern);\n return matches?.length ?? 0;\n}\n\nfunction countPatternInDir(\n dir: string,\n filePattern: RegExp,\n contentPattern: RegExp,\n excludePatterns?: RegExp[]\n): number {\n if (!existsSync(dir)) return 0;\n let count = 0;\n for (const entry of readdirSync(dir)) {\n const fullPath = join(dir, entry);\n const stat = statSync(fullPath);\n if (stat.isDirectory() && !entry.startsWith('.') && entry !== 'node_modules') {\n count += countPatternInDir(fullPath, filePattern, contentPattern, excludePatterns);\n } else if (filePattern.test(entry) && !isExcluded(entry, excludePatterns)) {\n count += countMatchesInFile(fullPath, contentPattern);\n }\n }\n return count;\n}\n\n// =========================================================================\n// Public types\n// =========================================================================\n\n/**\n * Individual fitness dimension scores.\n */\nexport interface FitnessDimensions {\n /** Penalty: duplicate paths to same workflow (0-20, higher = better) */\n readonly canonicalPaths: number;\n /** Penalty: hidden/magic behavior (0-15, higher = better) */\n readonly explicitBehavior: number;\n /** Reward: deterministic execution (0-15, higher = better) */\n readonly determinism: number;\n /** Reward: observability coverage (0-15, higher = better) */\n readonly observability: number;\n /** Penalty: config surface area (0-10, higher = better) */\n readonly configSimplicity: number;\n /** Penalty: cross-layer coupling (0-10, higher = better) */\n readonly layerSeparation: number;\n /** Reward: CLI ergonomics (0-10, higher = better) */\n readonly operatorErgonomics: number;\n /** Reward: governance injection (0-5, higher = better) */\n readonly governanceIntegration: number;\n}\n\n/**\n * Detailed fitness audit result.\n */\nexport interface FitnessAudit {\n /** Overall score (0-100) */\n readonly score: number;\n /** Individual dimension scores */\n readonly dimensions: FitnessDimensions;\n /** Specific findings */\n readonly findings: readonly FitnessFinding[];\n /** Timestamp of audit */\n readonly timestamp: string;\n /** Version/commit reference */\n readonly version: string;\n}\n\n/**\n * Individual finding from audit.\n */\nexport interface FitnessFinding {\n /** Dimension affected */\n readonly dimension: keyof FitnessDimensions;\n /** Issue severity: 'info' | 'warning' | 'critical' */\n readonly severity: 'info' | 'warning' | 'critical';\n /** Description */\n readonly description: string;\n /** Points deducted */\n readonly pointsDeducted: number;\n /** Location in code (optional) */\n readonly location?: string;\n /** Suggested fix (optional) */\n readonly suggestion?: string;\n}\n\n/**\n * Fitness check definition.\n */\ninterface FitnessCheck {\n readonly dimension: keyof FitnessDimensions;\n readonly maxPoints: number;\n readonly name: string;\n readonly check: () => FitnessCheckResult;\n}\n\n/**\n * Result of a single fitness check.\n */\ninterface FitnessCheckResult {\n readonly score: number;\n readonly findings: FitnessFinding[];\n}\n\n/** Clamp score to [0, max]. */\nfunction clamp(score: number, max: number): number {\n return Math.max(0, Math.min(max, score));\n}\n\n/**\n * CLI Orchestration Fitness Score calculator.\n */\nexport class FitnessScoreCalculator {\n private readonly logger: ILogger;\n private readonly checks: FitnessCheck[] = [];\n\n constructor(logger?: ILogger) {\n this.logger = logger ?? createLogger({ component: 'FitnessScoreCalculator' });\n this.registerDefaultChecks();\n }\n\n /** Register default fitness checks. */\n private registerDefaultChecks(): void {\n const reg = (\n dimension: keyof FitnessDimensions,\n maxPoints: number,\n name: string,\n check: () => FitnessCheckResult\n ): void => {\n this.checks.push({ dimension, maxPoints, name, check });\n };\n reg('canonicalPaths', 20, 'Canonical Paths', () => this.checkCanonicalPaths());\n reg('explicitBehavior', 15, 'Explicit Behavior', () => this.checkExplicitBehavior());\n reg('determinism', 15, 'Determinism', () => this.checkDeterminism());\n reg('observability', 15, 'Observability', () => this.checkObservability());\n reg('configSimplicity', 10, 'Config Simplicity', () => this.checkConfigSimplicity());\n reg('layerSeparation', 10, 'Layer Separation', () => this.checkLayerSeparation());\n reg('operatorErgonomics', 10, 'Operator Ergonomics', () => this.checkOperatorErgonomics());\n reg('governanceIntegration', 5, 'Governance Integration', () =>\n this.checkGovernanceIntegration()\n );\n }\n\n /** Run full fitness audit. */\n audit(version: string): FitnessAudit {\n const findings: FitnessFinding[] = [];\n const dimensions: Record<string, number> = {};\n\n // #2716 — the audit's existsSync checks look at SRC_ROOT-relative paths\n // (cli-adapters/composite-router.ts, cli/doctor.ts, etc). When run from\n // an `npm install -g nexus-agents` copy, SRC_ROOT points at the installed\n // package's `src/` which only contains workflow templates — not the full\n // source tree. Result: every existsSync returns false and the audit\n // emits a parade of fictional \"missing\" findings against a healthy\n // source tree. (`npx nexus-agents fitness-audit` from a repo root hits\n // this path because npx resolves to the GLOBAL bin, not the local\n // workspace bundle.) Bail with a clear single-finding result instead.\n const cliAdaptersDir = join(SRC_ROOT, 'cli-adapters');\n if (!existsSync(cliAdaptersDir)) {\n return this.notSourceRepoResult(version);\n }\n\n for (const check of this.checks) {\n this.logger.debug(`Running fitness check: ${check.name}`);\n const result = check.check();\n dimensions[check.dimension] = result.score;\n findings.push(...result.findings);\n }\n\n const score = Object.values(dimensions).reduce((sum, val) => sum + val, 0);\n this.logger.info('Fitness audit complete', { score, version });\n\n // Build a strictly-typed FitnessDimensions instead of `as unknown as` cast\n // (#1913 Class G). If a check skipped a dimension it defaults to 0,\n // making it explicit rather than UB.\n const safeDim = (k: keyof FitnessDimensions): number => dimensions[k] ?? 0;\n const typedDimensions: FitnessDimensions = {\n canonicalPaths: safeDim('canonicalPaths'),\n explicitBehavior: safeDim('explicitBehavior'),\n determinism: safeDim('determinism'),\n observability: safeDim('observability'),\n configSimplicity: safeDim('configSimplicity'),\n layerSeparation: safeDim('layerSeparation'),\n operatorErgonomics: safeDim('operatorErgonomics'),\n governanceIntegration: safeDim('governanceIntegration'),\n };\n\n return {\n score,\n dimensions: typedDimensions,\n findings,\n timestamp: new Date().toISOString(),\n version,\n };\n }\n\n /**\n * Return when the runtime SRC_ROOT doesn't look like the nexus-agents\n * source tree (#2716). One finding, score 0 — distinct from \"the source\n * tree is broken\" because every existsSync would falsely report missing.\n */\n private notSourceRepoResult(version: string): FitnessAudit {\n const finding: FitnessFinding = {\n dimension: 'governanceIntegration',\n severity: 'info',\n description:\n 'fitness-audit must run against the nexus-agents source repo, ' +\n `but ${SRC_ROOT}/cli-adapters does not exist. You are likely ` +\n 'running the installed npm package via `npx nexus-agents`, which ' +\n 'ships only the bundled dist/. Clone the source repo and run ' +\n '`node packages/nexus-agents/dist/cli.js fitness-audit` (or invoke ' +\n '`pnpm fitness-audit` from the workspace root).',\n pointsDeducted: 0,\n };\n return {\n score: 0,\n dimensions: {\n canonicalPaths: 0,\n explicitBehavior: 0,\n determinism: 0,\n observability: 0,\n configSimplicity: 0,\n layerSeparation: 0,\n operatorErgonomics: 0,\n governanceIntegration: 0,\n },\n findings: [finding],\n timestamp: new Date().toISOString(),\n version,\n };\n }\n\n // =========================================================================\n // Individual Checks — real filesystem analysis\n // =========================================================================\n\n /**\n * Check canonical paths: penalize duplicate router implementations.\n *\n * The current minimum is 6 (raised from 5 in #2063 after an audit):\n * 1. composite-router — pipeline orchestrator\n * 2. budget-router — budget/cost filtering\n * 3. zero-router — hard-constraint exclusion\n * 4. preference-router — user/task preference application\n * 5. topsis-router — TOPSIS multi-criteria scoring\n * 6. agreement-cascade-router — agreement-based cascade retry\n *\n * Each stage is distinct per CLAUDE.md's documented pipeline:\n * Task → BudgetRouter → ZeroRouter → PreferenceRouter → TopsisRouter → Agreement → Model\n */\n private checkCanonicalPaths(): FitnessCheckResult {\n const findings: FitnessFinding[] = [];\n let score = 20;\n\n const routerCount = countFiles(join(SRC_ROOT, 'cli-adapters'), /router\\.ts$/);\n const ROUTER_COUNT_THRESHOLD = 6;\n if (routerCount > ROUTER_COUNT_THRESHOLD) {\n const excess = routerCount - ROUTER_COUNT_THRESHOLD;\n const deduction = Math.min(5, excess);\n score -= deduction;\n findings.push(\n this.finding(\n 'canonicalPaths',\n 'warning',\n `${String(routerCount)} router implementations found (target: <=${String(ROUTER_COUNT_THRESHOLD)})`,\n deduction,\n 'Consolidate duplicate routers into CompositeRouter'\n )\n );\n }\n\n if (existsSync(join(SRC_ROOT, 'cli-adapters/composite-router.ts'))) {\n score += 2;\n } else {\n score -= 3;\n findings.push(\n this.finding(\n 'canonicalPaths',\n 'critical',\n 'CompositeRouter missing — no unified routing entry point',\n 3\n )\n );\n }\n\n score = this.checkOrchestratorInterface(score, findings);\n\n return { score: clamp(score, 20), findings };\n }\n\n /** Sub-check for IOrchestrator interface and adapter wiring. */\n private checkOrchestratorInterface(score: number, findings: FitnessFinding[]): number {\n const orchPath = join(SRC_ROOT, 'core/types/orchestrator.ts');\n if (existsSync(orchPath) && fileContains(orchPath, /interface IOrchestrator/)) {\n score += 3;\n } else {\n score -= 2;\n findings.push(\n this.finding('canonicalPaths', 'warning', 'No IOrchestrator interface in core/types', 2)\n );\n }\n\n const adapterPath = join(SRC_ROOT, 'orchestration/orchestrator-adapters.ts');\n if (existsSync(adapterPath) && fileContains(adapterPath, /TechLeadAdapter|PuppeteerAdapter/)) {\n score += 2;\n }\n\n return score;\n }\n\n /**\n * Check explicit behavior: penalize hidden/magic behavior.\n *\n * Implementation is intentionally filesystem-signal-based (no AST parse).\n * The `NEXUS_ALLOW_MOCK_ORCHESTRATION` guard and magic-routing pattern\n * grep capture the observable failure modes that historically slipped\n * past review. AST-based detection of implicit fallbacks was considered\n * but not pursued — it would significantly widen this function's\n * footprint and the filesystem signals already catch the recurring\n * regressions. Revisit only if a new class of hidden-behavior bug\n * surfaces that this grep-over-source approach can't catch.\n */\n private checkExplicitBehavior(): FitnessCheckResult {\n const findings: FitnessFinding[] = [];\n let score = 15;\n\n // Check: mock orchestration requires explicit env var opt-in\n const mockGuardCount = countPatternInDir(\n SRC_ROOT,\n /\\.ts$/,\n /NEXUS_ALLOW_MOCK_ORCHESTRATION/g,\n DETERMINISM_EXCLUDES\n );\n if (mockGuardCount === 0) {\n score -= 3;\n findings.push(\n this.finding(\n 'explicitBehavior',\n 'warning',\n 'No NEXUS_ALLOW_MOCK_ORCHESTRATION guard found — mock fallback may be implicit',\n 3,\n 'Require explicit env var for mock orchestration'\n )\n );\n }\n\n // Check: magic routing patterns (delegate without explicit capability match)\n const magicRouting = countPatternInDir(\n SRC_ROOT,\n /\\.ts$/,\n /fallback.*=.*true|implicitRoute/g,\n DETERMINISM_EXCLUDES\n );\n if (magicRouting > 5) {\n const deduction = Math.min(3, Math.floor(magicRouting / 3));\n score -= deduction;\n findings.push(\n this.finding(\n 'explicitBehavior',\n 'info',\n `${String(magicRouting)} implicit fallback/routing patterns detected`,\n deduction\n )\n );\n }\n\n return { score: clamp(score, 15), findings };\n }\n\n /** Check determinism: penalize unseeded random and raw Date.now(). */\n private checkDeterminism(): FitnessCheckResult {\n const findings: FitnessFinding[] = [];\n let score = 15;\n\n score = this.checkRandomDeterminism(score, findings);\n score = this.checkTimeDeterminism(score, findings);\n\n return { score: clamp(score, 15), findings };\n }\n\n /** Sub-check for Math.random() and injectable random provider. */\n private checkRandomDeterminism(score: number, findings: FitnessFinding[]): number {\n const randomCount = countPatternInDir(\n SRC_ROOT,\n /\\.ts$/,\n /Math\\.random\\(\\)/g,\n DETERMINISM_EXCLUDES\n );\n if (randomCount > 10) {\n const deduction = Math.min(5, Math.floor(randomCount / 5));\n score -= deduction;\n findings.push(\n this.finding(\n 'determinism',\n 'warning',\n `${String(randomCount)} unseeded Math.random() calls in production code`,\n deduction,\n 'Use getRandomProvider() for injectable randomness'\n )\n );\n } else if (randomCount === 0) {\n score += 2;\n }\n\n if (existsSync(join(SRC_ROOT, 'core/random-provider.ts'))) {\n score += 1;\n }\n const randomUsage = countPatternInDir(\n SRC_ROOT,\n /\\.ts$/,\n /getRandomProvider\\(\\)/g,\n DETERMINISM_EXCLUDES\n );\n if (randomUsage > 5) {\n score += 1;\n }\n\n return score;\n }\n\n /** Sub-check for Date.now() and injectable time provider. */\n private checkTimeDeterminism(score: number, findings: FitnessFinding[]): number {\n const dateNowCount = countPatternInDir(\n SRC_ROOT,\n /\\.ts$/,\n /Date\\.now\\(\\)/g,\n DETERMINISM_EXCLUDES\n );\n if (dateNowCount > 50) {\n score -= 2;\n findings.push(\n this.finding(\n 'determinism',\n 'info',\n `${String(dateNowCount)} Date.now() calls in production code`,\n 2,\n 'Use getTimeProvider() for injectable time'\n )\n );\n }\n\n if (existsSync(join(SRC_ROOT, 'core/time-provider.ts'))) {\n score += 1;\n }\n const timeUsage = countPatternInDir(\n SRC_ROOT,\n /\\.ts$/,\n /getTimeProvider\\(\\)/g,\n DETERMINISM_EXCLUDES\n );\n if (timeUsage > 10) {\n score += 1;\n }\n\n return score;\n }\n\n /** Check observability: reward tracing, logging, and audit coverage. */\n private checkObservability(): FitnessCheckResult {\n const findings: FitnessFinding[] = [];\n let score = 15;\n\n if (existsSync(join(SRC_ROOT, 'observability/swarm-observer.ts'))) {\n score += 3;\n } else {\n score -= 3;\n findings.push(\n this.finding(\n 'observability',\n 'warning',\n 'No SwarmObserver found',\n 3,\n 'Add observability/swarm-observer.ts'\n )\n );\n }\n\n if (existsSync(join(SRC_ROOT, 'core/trace.ts'))) {\n score += 2;\n }\n\n const loggerCount = countPatternInDir(SRC_ROOT, /\\.ts$/, /createLogger\\(/g);\n if (loggerCount > 50) {\n score += 2;\n } else {\n findings.push(\n this.finding(\n 'observability',\n 'info',\n `Only ${String(loggerCount)} createLogger() calls (target: >50)`,\n 0\n )\n );\n }\n\n if (existsSync(join(SRC_ROOT, 'audit'))) {\n score += 2;\n }\n\n return { score: clamp(score, 15), findings };\n }\n\n /** Check config simplicity: penalize excessive schema sprawl. */\n private checkConfigSimplicity(): FitnessCheckResult {\n const findings: FitnessFinding[] = [];\n let score = 10;\n\n const schemaCount = countFiles(join(SRC_ROOT, 'config'), /schema.*\\.ts$/);\n if (schemaCount > 10) {\n score -= 2;\n findings.push(\n this.finding(\n 'configSimplicity',\n 'info',\n `${String(schemaCount)} config schemas (target: <=10)`,\n 2,\n 'Consolidate related schemas'\n )\n );\n } else {\n score += 1;\n }\n\n if (existsSync(join(SRC_ROOT, 'config/config-loader.ts'))) {\n score += 2;\n }\n if (existsSync(join(SRC_ROOT, 'config/config-manager.ts'))) {\n score += 1;\n }\n\n return { score: clamp(score, 10), findings };\n }\n\n /** Check layer separation: penalize cross-layer imports. */\n private checkLayerSeparation(): FitnessCheckResult {\n const findings: FitnessFinding[] = [];\n let score = 10;\n\n const adapterAgentImports = countPatternInDir(\n join(SRC_ROOT, 'adapters'),\n /\\.ts$/,\n /from ['\"]\\.\\.\\/agents\\//g\n );\n if (adapterAgentImports > 0) {\n const deduction = Math.min(5, adapterAgentImports);\n score -= deduction;\n findings.push(\n this.finding(\n 'layerSeparation',\n 'warning',\n `${String(adapterAgentImports)} adapter->agent import violations`,\n deduction,\n 'Adapters should not import from agents layer'\n )\n );\n } else {\n score += 2;\n }\n\n const coreMcpImports = countPatternInDir(\n join(SRC_ROOT, 'core'),\n /\\.ts$/,\n /from ['\"]\\.\\.\\/mcp\\//g\n );\n if (coreMcpImports > 0) {\n const deduction = Math.min(3, coreMcpImports);\n score -= deduction;\n findings.push(\n this.finding(\n 'layerSeparation',\n 'critical',\n `${String(coreMcpImports)} core->MCP import violations`,\n deduction,\n 'Core must not depend on MCP layer'\n )\n );\n } else {\n score += 1;\n }\n\n return { score: clamp(score, 10), findings };\n }\n\n /** Check operator ergonomics: reward rich CLI commands. */\n private checkOperatorErgonomics(): FitnessCheckResult {\n const findings: FitnessFinding[] = [];\n let score = 10;\n\n const commandCount = countFiles(join(SRC_ROOT, 'cli'), /\\.ts$/);\n if (commandCount >= 20) {\n score += 3;\n } else {\n findings.push(\n this.finding(\n 'operatorErgonomics',\n 'info',\n `${String(commandCount)} CLI commands (target: >=20)`,\n 0\n )\n );\n }\n\n score = this.checkCliCommands(score, findings);\n\n return { score: clamp(score, 10), findings };\n }\n\n /** Sub-check for essential CLI commands (doctor, setup, demo, config). */\n private checkCliCommands(score: number, findings: FitnessFinding[]): number {\n const commands: Array<[string, string, number]> = [\n ['cli/doctor.ts', 'Doctor command', 2],\n ['cli/setup-command.ts', 'Setup wizard', 2],\n ['cli/demo-command.ts', 'Demo command', 1],\n ['cli/config-command.ts', 'Config command', 1],\n ];\n\n for (const [path, name, bonus] of commands) {\n if (existsSync(join(SRC_ROOT, path))) {\n score += bonus;\n } else {\n findings.push(this.finding('operatorErgonomics', 'info', `Missing ${name} (${path})`, 0));\n }\n }\n\n return score;\n }\n\n /** Check governance integration: policy firewall, rate limiter, docs. */\n private checkGovernanceIntegration(): FitnessCheckResult {\n const findings: FitnessFinding[] = [];\n let score = 5;\n\n score = this.checkGovernanceDocs(score, findings);\n score = this.checkGovernanceInfra(score, findings);\n\n return { score: clamp(score, 5), findings };\n }\n\n /** Sub-check for governance documentation artifacts. */\n private checkGovernanceDocs(score: number, findings: FitnessFinding[]): number {\n if (!existsSync(join(REPO_ROOT, 'CLAUDE.md'))) {\n score -= 3;\n findings.push(\n this.finding('governanceIntegration', 'critical', 'No CLAUDE.md governance document', 3)\n );\n } else {\n score += 1;\n }\n\n if (existsSync(join(DOCS_ROOT, 'architecture/wiring-graph.json'))) {\n score += 1;\n }\n\n if (existsSync(join(DOCS_ROOT, 'adr'))) {\n score += 1;\n } else {\n findings.push(this.finding('governanceIntegration', 'info', 'No ADR directory', 0));\n }\n\n return score;\n }\n\n /** Sub-check for governance runtime infrastructure. */\n private checkGovernanceInfra(score: number, findings: FitnessFinding[]): number {\n const hasPolicyFirewall =\n countPatternInDir(join(SRC_ROOT, 'security'), /\\.ts$/, /PolicyGate|policyFirewall/g) > 0;\n if (hasPolicyFirewall) {\n score += 1;\n } else {\n findings.push(\n this.finding(\n 'governanceIntegration',\n 'warning',\n 'No policy firewall detected in security layer',\n 0\n )\n );\n }\n\n const hasRateLimiter = countPatternInDir(SRC_ROOT, /\\.ts$/, /RateLimiter|rateLimiter/g) > 0;\n if (hasRateLimiter) {\n score += 1;\n }\n\n return score;\n }\n\n /** Helper to create a FitnessFinding with defaults. */\n private finding(\n dimension: keyof FitnessDimensions,\n severity: FitnessFinding['severity'],\n description: string,\n pointsDeducted: number,\n suggestion?: string\n ): FitnessFinding {\n const base: FitnessFinding = { dimension, severity, description, pointsDeducted };\n if (suggestion !== undefined) {\n return { ...base, suggestion };\n }\n return base;\n }\n}\n\n/**\n * Create a fitness score calculator.\n */\nexport function createFitnessScoreCalculator(logger?: ILogger): FitnessScoreCalculator {\n return new FitnessScoreCalculator(logger);\n}\n\n/**\n * Quick function to get current fitness score.\n */\nexport function calculateFitnessScore(version: string): FitnessAudit {\n const calculator = createFitnessScoreCalculator();\n return calculator.audit(version);\n}\n","/**\n * improvement_review → pipeline-bus signal emitter (#3147, epic #3143 P2).\n *\n * Emits `signal.fitness_declined` onto the typed pipeline event bus when the\n * fitness audit score falls below the governance floor. Runs in the\n * `improvement_review` MCP tool (server context), so the live shadow TuneStage\n * consumes it. Lives at the MCP layer to keep `governance/fitness-score`\n * decoupled from the pipeline bus, preserving the `A = observability /\n * B = messaging` boundary adopted for #3289 (scope Option 2).\n *\n * @module mcp/tools/improvement-review-signals\n */\n\nimport { getErrorMessage, getTimeProvider } from '../../core/index.js';\nimport type { ILogger } from '../../core/index.js';\nimport type { FitnessAudit } from '../../governance/fitness-score.js';\nimport type { IEventBus } from '../../pipeline/event-types.js';\n\n/** The dimension of the finding that deducted the most points, if any. */\nfunction worstDimension(audit: FitnessAudit): string | undefined {\n let worst: { dimension: string; pointsDeducted: number } | undefined;\n for (const finding of audit.findings) {\n if (worst === undefined || finding.pointsDeducted > worst.pointsDeducted) {\n worst = { dimension: finding.dimension, pointsDeducted: finding.pointsDeducted };\n }\n }\n return worst?.dimension;\n}\n\n/**\n * Emit `signal.fitness_declined` onto `bus` when `audit.score < fitnessFloor`.\n * No-op at or above floor. Emission errors are swallowed and logged — signalling\n * must never break the improvement-review path.\n */\nexport function emitFitnessDeclinedSignal(\n audit: FitnessAudit,\n fitnessFloor: number,\n bus: IEventBus,\n logger: ILogger\n): void {\n if (audit.score >= fitnessFloor) return;\n try {\n const dimension = worstDimension(audit);\n bus.emit({\n type: 'signal.fitness_declined',\n timestamp: getTimeProvider().now(),\n score: audit.score,\n floor: fitnessFloor,\n ...(dimension !== undefined ? { dimension } : {}),\n });\n } catch (error) {\n logger.warn('Failed to emit signal.fitness_declined', { error: getErrorMessage(error) });\n }\n}\n"],"mappings":"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","names":["execFile","promisify","description","execFileAsync","promisify","execFile"]}
@@ -3,7 +3,7 @@ import {
3
3
  err,
4
4
  getErrorMessage,
5
5
  ok
6
- } from "./chunk-JRBUSUYD.js";
6
+ } from "./chunk-ZXF2XA4R.js";
7
7
 
8
8
  // src/scm/types.ts
9
9
  var ScmError = class extends Error {
@@ -258,4 +258,4 @@ export {
258
258
  ScmError,
259
259
  GitHubProvider
260
260
  };
261
- //# sourceMappingURL=chunk-3DB4DEFY.js.map
261
+ //# sourceMappingURL=chunk-Q6HUW6EI.js.map
@@ -9,11 +9,11 @@ import {
9
9
  gateWithReputation,
10
10
  resolveReputationGatingMode,
11
11
  sanitizeInput
12
- } from "./chunk-AWXWDGG5.js";
12
+ } from "./chunk-S7RTQRQ3.js";
13
13
  import {
14
14
  createLogger,
15
15
  getTimeProvider
16
- } from "./chunk-JRBUSUYD.js";
16
+ } from "./chunk-ZXF2XA4R.js";
17
17
 
18
18
  // src/dogfooding/pr-reviewer-helpers.ts
19
19
  import { randomUUID } from "crypto";
@@ -288,4 +288,4 @@ export {
288
288
  formatReviewComment,
289
289
  createFailedReview
290
290
  };
291
- //# sourceMappingURL=chunk-VV47MWHN.js.map
291
+ //# sourceMappingURL=chunk-R2G4GZID.js.map
@@ -2,7 +2,7 @@ import {
2
2
  CACHE_TIMEOUTS,
3
3
  createLogger,
4
4
  getTimeProvider
5
- } from "./chunk-JRBUSUYD.js";
5
+ } from "./chunk-ZXF2XA4R.js";
6
6
 
7
7
  // src/security/trust-types.ts
8
8
  import { z } from "zod";
@@ -560,4 +560,4 @@ export {
560
560
  resolveReputationGatingMode,
561
561
  gateWithReputation
562
562
  };
563
- //# sourceMappingURL=chunk-AWXWDGG5.js.map
563
+ //# sourceMappingURL=chunk-S7RTQRQ3.js.map
@@ -4,7 +4,7 @@ import {
4
4
  getErrorMessage,
5
5
  getTimeProvider,
6
6
  ok
7
- } from "./chunk-JRBUSUYD.js";
7
+ } from "./chunk-ZXF2XA4R.js";
8
8
 
9
9
  // src/context/session-memory.ts
10
10
  import * as fs from "fs";
@@ -351,4 +351,4 @@ export {
351
351
  SessionMemory,
352
352
  createSessionMemory
353
353
  };
354
- //# sourceMappingURL=chunk-N2HYXBQ6.js.map
354
+ //# sourceMappingURL=chunk-VNU7OT7O.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getErrorMessage
3
- } from "./chunk-JRBUSUYD.js";
3
+ } from "./chunk-ZXF2XA4R.js";
4
4
 
5
5
  // src/cli/setup-config.ts
6
6
  import { copyFileSync, existsSync, mkdirSync, writeFileSync } from "fs";
@@ -77,4 +77,4 @@ function ensureBackup(outputPath) {
77
77
  export {
78
78
  runConfigInitSync
79
79
  };
80
- //# sourceMappingURL=chunk-VQVKI4XO.js.map
80
+ //# sourceMappingURL=chunk-WJSQ5FRV.js.map
@@ -4,24 +4,24 @@ import {
4
4
  createStream,
5
5
  requireApiKey,
6
6
  validateApiKeyPresence
7
- } from "./chunk-5OOFU3EY.js";
7
+ } from "./chunk-3S4N6OCF.js";
8
8
  import {
9
9
  CUSTOM_API_BASE_URL_ENV,
10
10
  CUSTOM_API_DEFAULT_MODEL,
11
11
  PROVIDER_ENV_KEYS,
12
12
  assertCustomApiHostResolvesPublic,
13
13
  validateCustomApiBaseUrl
14
- } from "./chunk-3XGPHTO6.js";
14
+ } from "./chunk-7AO4FKAD.js";
15
15
  import {
16
16
  CliCircuitBreaker,
17
17
  DEFAULT_CIRCUIT_BREAKER_CONFIG
18
- } from "./chunk-5EH7WMME.js";
18
+ } from "./chunk-5RDUP5K7.js";
19
19
  import {
20
20
  getAvailabilityCache
21
- } from "./chunk-TIOXPJIO.js";
21
+ } from "./chunk-E4HZTSBP.js";
22
22
  import {
23
23
  generateHyphenId
24
- } from "./chunk-LUCPCWIZ.js";
24
+ } from "./chunk-BXEOO2KK.js";
25
25
  import {
26
26
  CLI_SUBPROCESS_TIMEOUTS,
27
27
  CLI_TIMEOUTS,
@@ -55,7 +55,7 @@ import {
55
55
  loadModelsDevSnapshot,
56
56
  ok,
57
57
  resolveCliAlias
58
- } from "./chunk-JRBUSUYD.js";
58
+ } from "./chunk-ZXF2XA4R.js";
59
59
 
60
60
  // src/cli-adapters/cli-to-model-adapter.ts
61
61
  var CliToModelAdapter = class {
@@ -4793,4 +4793,4 @@ export {
4793
4793
  SdkAdapter,
4794
4794
  createAutoAdapter
4795
4795
  };
4796
- //# sourceMappingURL=chunk-F2ULTSZ6.js.map
4796
+ //# sourceMappingURL=chunk-XMNGHZBR.js.map
@@ -2,7 +2,7 @@ import {
2
2
  createLogger,
3
3
  err,
4
4
  ok
5
- } from "./chunk-JRBUSUYD.js";
5
+ } from "./chunk-ZXF2XA4R.js";
6
6
 
7
7
  // src/scm/token-resolver.ts
8
8
  import { execFile } from "child_process";
@@ -87,4 +87,4 @@ export {
87
87
  hasToken,
88
88
  getTokenEnvVars
89
89
  };
90
- //# sourceMappingURL=chunk-2QBR4RVO.js.map
90
+ //# sourceMappingURL=chunk-YJSXYHSK.js.map