@@ -1867,6 +1867,35 @@ describe('permitted-document planner', () => {
18671867 expect ( ginStatements ( ) ) . toHaveLength ( 0 )
18681868 } )
18691869
1870+ it ( 'stays with the GIN ranking for the rest of a search once a page was handed to it' , async ( ) => {
1871+ /** Tin cannot fill the first page; GIN supplies it, and hydration keeps only half, so a second page follows. */
1872+ tinPages = [
1873+ { ranked : 2000 , candidates : [ ] } ,
1874+ { ranked : 20_000 , candidates : [ ] } ,
1875+ { ranked : 2000 , candidates : [ hit ( 'never' , 'src-a' ) ] } ,
1876+ ]
1877+ const ginRows = Array . from ( { length : 40 } , ( _ , index ) => hit ( `g-${ index } ` , 'src-a' ) )
1878+ const ginPages = [ ginRows , [ ] ]
1879+ const execute = dbChainMockFns . execute . getMockImplementation ( ) !
1880+ dbChainMockFns . execute . mockImplementation ( async ( query ) =>
1881+ render ( query ) . sql . includes ( 'WITH matched_keyword_chunks' )
1882+ ? ( ginPages . shift ( ) ?? [ ] )
1883+ : execute ( query )
1884+ )
1885+ queueTableRows (
1886+ schemaMock . embedding ,
1887+ ginRows . slice ( 0 , 20 ) . map ( ( row ) => ( { ...row , content : 'release notes' } ) )
1888+ )
1889+ const results = await keyword ( {
1890+ topK : 40 ,
1891+ permitted : { kind : 'bounded' , documents : large } ,
1892+ accessPlan,
1893+ } )
1894+ expect ( results . map ( ( row ) => row . id ) ) . not . toContain ( 'never' )
1895+ expect ( tinStatements ( ) ) . toHaveLength ( 2 )
1896+ expect ( ginStatements ( ) . length ) . toBeGreaterThanOrEqual ( 2 )
1897+ } )
1898+
18701899 it ( 'keeps the bounded read for a set under the size' , async ( ) => {
18711900 mockResolveTinKeywordQuery . mockResolvedValue ( null )
18721901 await keyword ( { permitted : { kind : 'bounded' , documents : large . slice ( 0 , - 1 ) } , accessPlan } )
0 commit comments