@@ -66,36 +66,41 @@ async function upgradeSqlite(directory: string, goal: string, execute: boolean):
6666 * All stores, including unselected shadows, must be readable by the new binary. */
6767export async function upgradeAuthorityFormats ( roots : readonly string [ ] , execute : boolean ) : Promise < JsonObject > {
6868 const results : JsonObject [ ] = [ ] ;
69- for ( const root of [ ...new Set ( roots . map ( requireLocalAuthorityRuntimeRoot ) ) ] ) {
70- for ( const provider of [ "file" , "sqlite" ] as const ) {
71- const directory = join ( root , "authority" , `${ provider } -v0` ) ;
72- const names = ( await entries ( directory ) ) . filter ( name =>
73- ( provider === "file" ? / ^ a u t h o r i t y - s t o r e - [ 0 - 9 a - f ] { 16 } \. j s o n $ / : / ^ a u t h o r i t y - [ 0 - 9 a - f ] { 64 } \. s q l i t e $ / ) . test ( name ) ) ;
74- if ( provider === "file" ) names . push ( ...( await entries ( join ( directory , "rollback" ) ) )
75- . filter ( name => / ^ a u t h o r i t y - s t o r e - [ 0 - 9 a - f ] { 24 } \. j s o n $ / . test ( name ) ) . map ( name => join ( "rollback" , name ) ) ) ;
76- for ( const name of names . sort ( ) ) {
77- const path = join ( directory , name ) ;
78- let goal : string | null = null ;
79- try {
80- const detected = await inspectAuthorityFormat ( path ) ;
81- if ( detected . artifact_kind !== "authority_store" || detected . provider !== provider ) {
82- throw new Error ( "Detected format does not match this provider directory; no migration selected" ) ;
69+ try {
70+ for ( const root of [ ...new Set ( roots . map ( requireLocalAuthorityRuntimeRoot ) ) ] ) {
71+ for ( const provider of [ "file" , "sqlite" ] as const ) {
72+ const directory = join ( root , "authority" , `${ provider } -v0` ) ;
73+ const names = ( await entries ( directory ) ) . filter ( name =>
74+ ( provider === "file" ? / ^ a u t h o r i t y - s t o r e - [ 0 - 9 a - f ] { 16 } \. j s o n $ / : / ^ a u t h o r i t y - [ 0 - 9 a - f ] { 64 } \. s q l i t e $ / ) . test ( name ) ) ;
75+ if ( provider === "file" ) names . push ( ...( await entries ( join ( directory , "rollback" ) ) )
76+ . filter ( name => / ^ a u t h o r i t y - s t o r e - [ 0 - 9 a - f ] { 24 } \. j s o n $ / . test ( name ) ) . map ( name => join ( "rollback" , name ) ) ) ;
77+ for ( const name of names . sort ( ) ) {
78+ const path = join ( directory , name ) ;
79+ let goal : string | null = null ;
80+ try {
81+ const detected = await inspectAuthorityFormat ( path ) ;
82+ if ( detected . artifact_kind !== "authority_store" || detected . provider !== provider ) {
83+ throw new Error ( "Detected format does not match this provider directory; no migration selected" ) ;
84+ }
85+ goal = detected . goal_id ;
86+ const expected = provider === "file" ? new FileAuthorityStore ( directory , goal , { existingOnly : true } ) . path
87+ : sqliteAuthorityPath ( directory , goal ) ;
88+ if ( ! name . startsWith ( "rollback" ) && expected !== path ) throw new Error ( "Authority filename does not match its goal" ) ;
89+ const result = provider === "file" ? await migrateFileAuthorityStore ( directory , goal , execute , { } , name . startsWith ( "rollback" ) ? path : undefined )
90+ : await upgradeSqlite ( directory , goal , execute ) ;
91+ results . push ( { goal_id : goal , detected_format : detected . format , ...result } ) ;
92+ } catch ( error ) {
93+ // Earlier stores may already have migrated. Never report global rollback
94+ // or overwrite their later commits. Retry resumes per-store publication.
95+ return { status : "failed" , results, failed_provider : provider , failed_goal_id : goal ,
96+ reason : error instanceof Error ? error . message : "Format upgrade failed" , retry_safe : true } ;
8397 }
84- goal = detected . goal_id ;
85- const expected = provider === "file" ? new FileAuthorityStore ( directory , goal , { existingOnly : true } ) . path
86- : sqliteAuthorityPath ( directory , goal ) ;
87- if ( ! name . startsWith ( "rollback" ) && expected !== path ) throw new Error ( "Authority filename does not match its goal" ) ;
88- const result = provider === "file" ? await migrateFileAuthorityStore ( directory , goal , execute , { } , name . startsWith ( "rollback" ) ? path : undefined )
89- : await upgradeSqlite ( directory , goal , execute ) ;
90- results . push ( { goal_id : goal , detected_format : detected . format , ...result } ) ;
91- } catch ( error ) {
92- // Earlier stores may already have migrated. Never report global rollback
93- // or overwrite their later commits. Retry resumes per-store publication.
94- return { status : "failed" , results, failed_provider : provider , failed_goal_id : goal ,
95- reason : error instanceof Error ? error . message : "Format upgrade failed" , retry_safe : true } ;
9698 }
9799 }
98100 }
101+ } catch ( error ) {
102+ return { status : "failed" , results, reason : error instanceof Error ? error . message : "Store discovery failed" ,
103+ retry_safe : true } ;
99104 }
100105 return { status : execute ? "upgraded" : "planned" , results, authority_changed : false } ;
101106}
0 commit comments