@@ -94,7 +94,7 @@ ${source}`
9494})` )
9595 }
9696
97- it ( 'keeps chunk and KB updates working after a push drops the keyword table and reconciliation fails' , async ( ) => {
97+ it ( 'requires approval to retire keyword writers and preserves updates when later reconciliation fails' , async ( ) => {
9898 await sql `CREATE TABLE knowledge_base (id text PRIMARY KEY, is_search_index boolean NOT NULL DEFAULT false)`
9999 await sql `CREATE TABLE embedding (id text PRIMARY KEY, content text NOT NULL)`
100100 await sql `CREATE TABLE embedding_keyword_search (id text PRIMARY KEY, content text NOT NULL)`
@@ -121,16 +121,28 @@ ${source}`
121121export const knowledgeBases = pgTable('knowledge_base', {
122122 id: text('id').primaryKey(), isSearchIndex: boolean('is_search_index').notNull().default(false),
123123 })` )
124- const result = spawnSync (
125- 'bun' ,
126- [ '--no-env-file' , fileURLToPath ( new URL ( './push.ts' , import . meta. url ) ) , '--force' ] ,
127- {
128- cwd : directory ,
129- env : { ...process . env , DATABASE_URL : fixtureUrl , MIGRATION_DATABASE_URL : fixtureUrl } ,
130- encoding : 'utf8' ,
131- timeout : 30_000 ,
132- }
133- )
124+ function runPush ( args : string [ ] ) {
125+ return spawnSync (
126+ 'bun' ,
127+ [ '--no-env-file' , fileURLToPath ( new URL ( './push.ts' , import . meta. url ) ) , ...args ] ,
128+ {
129+ cwd : directory ,
130+ env : { ...process . env , DATABASE_URL : fixtureUrl , MIGRATION_DATABASE_URL : fixtureUrl } ,
131+ encoding : 'utf8' ,
132+ timeout : 30_000 ,
133+ }
134+ )
135+ }
136+ const denied = runPush ( [ ] )
137+ expect ( denied . error ) . toBeUndefined ( )
138+ expect ( denied . status , denied . stdout + denied . stderr ) . toBe ( 1 )
139+ await sql `UPDATE embedding SET content = 'unapproved push retained writer' WHERE id = 'chunk'`
140+ expect ( await sql `SELECT id FROM embedding_keyword_search` ) . toEqual ( [ ] )
141+ const emptyDenied = runPush ( [ ] )
142+ expect ( emptyDenied . error ) . toBeUndefined ( )
143+ expect ( emptyDenied . status , emptyDenied . stdout + emptyDenied . stderr ) . toBe ( 1 )
144+ await sql `UPDATE knowledge_base SET is_search_index = false WHERE id = 'kb'`
145+ const result = runPush ( [ '--force' ] )
134146 expect ( result . error ) . toBeUndefined ( )
135147 expect ( result . status , result . stdout + result . stderr ) . not . toBe ( 0 )
136148 expect ( await sql `SELECT to_regclass('embedding_keyword_search') AS projection` ) . toEqual ( [
0 commit comments