@@ -1741,6 +1741,132 @@ export class ToolRevalidator {
17411741
17421742 return extensions [ language ] || '.txt' ;
17431743 }
1744+
1745+ // ==========================================================================
1746+ // SESSION 89: Batch Validation Support
1747+ // ==========================================================================
1748+
1749+ /**
1750+ * SESSION 89: Validate multiple fixes in a batch
1751+ *
1752+ * Groups fixes by tool/language and validates each group together.
1753+ * More efficient than calling validateFix individually when you have
1754+ * multiple fixes for the same tool.
1755+ *
1756+ * @param requests - Array of validation requests with fixIds
1757+ * @returns Batch validation result with individual fix results
1758+ */
1759+ async validateBatch (
1760+ requests : Array < ToolRevalidationRequest & { fixId : string } >
1761+ ) : Promise < {
1762+ totalFixes : number ;
1763+ passedCount : number ;
1764+ failedCount : number ;
1765+ results : Map < string , ToolRevalidationResult & { fixId : string } > ;
1766+ toolExecutions : number ;
1767+ executionsSaved : number ;
1768+ totalDuration : number ;
1769+ summary : string ;
1770+ } > {
1771+ const startTime = Date . now ( ) ;
1772+ const results = new Map < string , ToolRevalidationResult & { fixId : string } > ( ) ;
1773+ let toolExecutions = 0 ;
1774+
1775+ if ( requests . length === 0 ) {
1776+ return {
1777+ totalFixes : 0 ,
1778+ passedCount : 0 ,
1779+ failedCount : 0 ,
1780+ results,
1781+ toolExecutions : 0 ,
1782+ executionsSaved : 0 ,
1783+ totalDuration : 0 ,
1784+ summary : 'No fixes to validate' ,
1785+ } ;
1786+ }
1787+
1788+ // Group fixes by tool:language for efficient processing
1789+ const groups = new Map < string , Array < ToolRevalidationRequest & { fixId : string } > > ( ) ;
1790+ for ( const request of requests ) {
1791+ const key = `${ request . tool . toLowerCase ( ) } :${ request . language . toLowerCase ( ) } ` ;
1792+ if ( ! groups . has ( key ) ) {
1793+ groups . set ( key , [ ] ) ;
1794+ }
1795+ groups . get ( key ) ! . push ( request ) ;
1796+ }
1797+
1798+ console . log (
1799+ `[ToolRevalidator:Batch] Grouped ${ requests . length } fixes into ${ groups . size } tool groups`
1800+ ) ;
1801+
1802+ // Process each group
1803+ const groupEntries = Array . from ( groups . entries ( ) ) ;
1804+ for ( const [ groupKey , groupRequests ] of groupEntries ) {
1805+ console . log (
1806+ `[ToolRevalidator:Batch] Processing group ${ groupKey } with ${ groupRequests . length } fixes`
1807+ ) ;
1808+ toolExecutions ++ ;
1809+
1810+ // Validate each fix in the group
1811+ // Note: Within a group, fixes share rate limiter context and tool config
1812+ for ( const request of groupRequests ) {
1813+ try {
1814+ const result = await this . validateFix ( request ) ;
1815+ results . set ( request . fixId , { ...result , fixId : request . fixId } ) ;
1816+ } catch ( error ) {
1817+ // If validation throws, record as failed
1818+ results . set ( request . fixId , {
1819+ fixId : request . fixId ,
1820+ passed : false ,
1821+ originalIssueResolved : false ,
1822+ hasRegressions : false ,
1823+ regressionCount : 0 ,
1824+ regressions : [ ] ,
1825+ toolExecution : {
1826+ tool : request . tool ,
1827+ command : 'N/A' ,
1828+ exitCode : - 1 ,
1829+ duration : 0 ,
1830+ stdout : '' ,
1831+ stderr : ( error as Error ) . message ,
1832+ } ,
1833+ summary : `Validation error: ${ ( error as Error ) . message } ` ,
1834+ } ) ;
1835+ }
1836+ }
1837+ }
1838+
1839+ // Calculate statistics
1840+ let passedCount = 0 ;
1841+ let failedCount = 0 ;
1842+ results . forEach ( ( result ) => {
1843+ if ( result . passed ) passedCount ++ ;
1844+ else failedCount ++ ;
1845+ } ) ;
1846+
1847+ const totalDuration = Date . now ( ) - startTime ;
1848+ const executionsSaved = Math . max ( 0 , requests . length - groups . size ) ;
1849+
1850+ const passRate = requests . length > 0 ? Math . round ( ( passedCount / requests . length ) * 100 ) : 0 ;
1851+ const savedPercent = requests . length > 0 ? Math . round ( ( executionsSaved / requests . length ) * 100 ) : 0 ;
1852+
1853+ const summary = `Batch validation: ${ passedCount } /${ requests . length } passed (${ passRate } %), ` +
1854+ `${ groups . size } tool executions (${ executionsSaved } groups saved, ${ savedPercent } % reduction), ` +
1855+ `${ totalDuration } ms` ;
1856+
1857+ console . log ( `[ToolRevalidator:Batch] ${ summary } ` ) ;
1858+
1859+ return {
1860+ totalFixes : requests . length ,
1861+ passedCount,
1862+ failedCount,
1863+ results,
1864+ toolExecutions : groups . size ,
1865+ executionsSaved,
1866+ totalDuration,
1867+ summary,
1868+ } ;
1869+ }
17441870}
17451871
17461872// ============================================================================
0 commit comments