@@ -5,6 +5,8 @@ const path = require('path');
55const { LIKU_HOME } = require ( path . join ( __dirname , '..' , 'src' , 'shared' , 'liku-home.js' ) ) ;
66
77const PROOF_RESULT_LOG = path . join ( LIKU_HOME , 'telemetry' , 'logs' , 'chat-inline-proof-results.jsonl' ) ;
8+ const PHASE3_POSTFIX_STARTED_AT = '2026-03-21T05:17:35.645Z' ;
9+ const PHASE3_POSTFIX_STARTED_AT_MS = Date . parse ( PHASE3_POSTFIX_STARTED_AT ) ;
810
911function getArgValue ( flagName ) {
1012 const index = process . argv . indexOf ( flagName ) ;
@@ -41,10 +43,17 @@ function resolveEntryModel(entry) {
4143 return entry ?. requestedModel || entry ?. observedRequestedModels ?. [ 0 ] || entry ?. observedRuntimeModels ?. [ 0 ] || 'default' ;
4244}
4345
46+ function resolveEntryCohort ( entry ) {
47+ const timestamp = Date . parse ( entry ?. timestamp || '' ) ;
48+ if ( ! Number . isFinite ( timestamp ) ) return 'unknown' ;
49+ return timestamp >= PHASE3_POSTFIX_STARTED_AT_MS ? 'phase3-postfix' : 'pre-phase3-postfix' ;
50+ }
51+
4452function passesFilter ( entry , filters = { } ) {
4553 if ( filters . suite && entry . suite !== filters . suite ) return false ;
4654 if ( filters . model && resolveEntryModel ( entry ) !== filters . model ) return false ;
4755 if ( filters . mode && entry . mode !== filters . mode ) return false ;
56+ if ( filters . cohort && resolveEntryCohort ( entry ) !== filters . cohort ) return false ;
4857 if ( filters . since ) {
4958 const timestamp = Date . parse ( entry . timestamp || '' ) ;
5059 if ( ! Number . isFinite ( timestamp ) || timestamp < filters . since ) return false ;
@@ -73,13 +82,15 @@ function summarizeProofEntries(entries) {
7382 const bySuite = new Map ( ) ;
7483 const byModel = new Map ( ) ;
7584 const bySuiteModel = new Map ( ) ;
85+ const byCohort = new Map ( ) ;
7686
7787 for ( const entry of normalized ) {
7888 const suiteKey = entry . suite || 'unknown' ;
7989 const modelKey = resolveEntryModel ( entry ) ;
90+ const cohortKey = resolveEntryCohort ( entry ) ;
8091 const suiteModelKey = `${ suiteKey } ::${ modelKey } ` ;
8192
82- for ( const [ bucket , key ] of [ [ bySuite , suiteKey ] , [ byModel , modelKey ] , [ bySuiteModel , suiteModelKey ] ] ) {
93+ for ( const [ bucket , key ] of [ [ bySuite , suiteKey ] , [ byModel , modelKey ] , [ bySuiteModel , suiteModelKey ] , [ byCohort , cohortKey ] ] ) {
8394 if ( ! bucket . has ( key ) ) bucket . set ( key , [ ] ) ;
8495 bucket . get ( key ) . push ( entry ) ;
8596 }
@@ -91,6 +102,7 @@ function summarizeProofEntries(entries) {
91102
92103 return {
93104 totals,
105+ phase3PostfixStartedAt : PHASE3_POSTFIX_STARTED_AT ,
94106 bySuite : materialize ( bySuite , ( key , bucketEntries ) => {
95107 const passed = bucketEntries . filter ( ( entry ) => entry . passed ) . length ;
96108 return {
@@ -117,6 +129,19 @@ function summarizeProofEntries(entries) {
117129 runtimeModels : [ ...new Set ( bucketEntries . flatMap ( ( entry ) => entry . observedRuntimeModels || [ ] ) ) ] . sort ( )
118130 } ;
119131 } ) ,
132+ byCohort : materialize ( byCohort , ( key , bucketEntries ) => {
133+ const passed = bucketEntries . filter ( ( entry ) => entry . passed ) . length ;
134+ return {
135+ key,
136+ runs : bucketEntries . length ,
137+ passed,
138+ failed : bucketEntries . length - passed ,
139+ passRate : Number ( ( ( passed / bucketEntries . length ) * 100 ) . toFixed ( 1 ) ) ,
140+ trend : buildTrend ( bucketEntries ) ,
141+ lastRunAt : bucketEntries [ 0 ] ?. timestamp || null ,
142+ models : [ ...new Set ( bucketEntries . map ( ( entry ) => resolveEntryModel ( entry ) ) ) ] . sort ( )
143+ } ;
144+ } ) ,
120145 bySuiteModel : materialize ( bySuiteModel , ( key , bucketEntries ) => {
121146 const [ suite , model ] = key . split ( '::' ) ;
122147 const passed = bucketEntries . filter ( ( entry ) => entry . passed ) . length ;
@@ -151,13 +176,19 @@ function main() {
151176 const suite = getArgValue ( '--suite' ) || null ;
152177 const model = getArgValue ( '--model' ) || null ;
153178 const mode = getArgValue ( '--mode' ) || null ;
179+ const rawSince = getArgValue ( '--since' ) ;
180+ const cohort = hasFlag ( '--phase3-postfix' ) ? 'phase3-postfix' : ( getArgValue ( '--cohort' ) || null ) ;
154181 const limit = Math . max ( 1 , parseInt ( getArgValue ( '--limit' ) , 10 ) || 10 ) ;
155182 const days = Math . max ( 0 , parseInt ( getArgValue ( '--days' ) , 10 ) || 0 ) ;
183+ const since = rawSince ? Date . parse ( rawSince ) : null ;
156184 const filters = {
157185 suite,
158186 model,
159187 mode,
160- since : days > 0 ? Date . now ( ) - ( days * 24 * 60 * 60 * 1000 ) : null
188+ cohort,
189+ since : Number . isFinite ( since )
190+ ? since
191+ : ( days > 0 ? Date . now ( ) - ( days * 24 * 60 * 60 * 1000 ) : null )
161192 } ;
162193
163194 const entries = parseProofEntries ( ) . filter ( ( entry ) => passesFilter ( entry , filters ) ) ;
@@ -181,6 +212,14 @@ function main() {
181212
182213 console . log ( 'Inline Chat Proof Summary' ) ;
183214 console . log ( `Runs: ${ summary . totals . runs } | Passed: ${ summary . totals . passed } | Failed: ${ summary . totals . failed } | Pass rate: ${ formatPercent ( summary . totals . passRate ) } ` ) ;
215+ if ( ! filters . cohort ) {
216+ console . log ( `Phase 3 post-fix cohort starts at: ${ summary . phase3PostfixStartedAt } ` ) ;
217+ }
218+
219+ printGroup ( 'By Cohort' , summary . byCohort . slice ( 0 , limit ) , ( row ) => {
220+ const models = row . models . length ? ` | models=${ row . models . join ( ',' ) } ` : '' ;
221+ return `- ${ row . key } : ${ row . passed } /${ row . runs } passed (${ formatPercent ( row . passRate ) } ) | trend=${ row . trend || '-' } ${ models } ` ;
222+ } ) ;
184223
185224 printGroup ( 'By Suite' , summary . bySuite . slice ( 0 , limit ) , ( row ) => {
186225 const models = row . models . length ? ` | models=${ row . models . join ( ',' ) } ` : '' ;
@@ -202,8 +241,10 @@ if (require.main === module) {
202241}
203242
204243module . exports = {
244+ PHASE3_POSTFIX_STARTED_AT ,
205245 PROOF_RESULT_LOG ,
206246 parseProofEntries,
247+ resolveEntryCohort,
207248 resolveEntryModel,
208249 summarizeProofEntries,
209250 buildTrend,
0 commit comments