@@ -379,6 +379,7 @@ interface OpenCodeThreadState {
379379 parentSubagent : OpenCodeSubagentContext | null ;
380380 nextChildTurnOrdinal : number ;
381381 nextAdmissionGeneration : number ;
382+ permission : PermissionRuleset ;
382383}
383384
384385interface OpenCodeRequestOwner {
@@ -1395,6 +1396,7 @@ export const makeOpenCodeAdapterV2 = Effect.fn("makeOpenCodeAdapterV2")(function
13951396 parentSubagent : context ,
13961397 nextChildTurnOrdinal : 1 ,
13971398 nextAdmissionGeneration : 1 ,
1399+ permission : childPermission ,
13981400 } ) ;
13991401 yield * emitProviderEvent ( {
14001402 type : "app_thread.created" ,
@@ -2775,6 +2777,8 @@ export const makeOpenCodeAdapterV2 = Effect.fn("makeOpenCodeAdapterV2")(function
27752777 if ( existing !== undefined ) {
27762778 existing . providerThread = providerThread ;
27772779 if ( appThread !== null ) existing . appThread = appThread ;
2780+ if ( nativeSession . permission !== undefined )
2781+ existing . permission = nativeSession . permission ;
27782782 return existing ;
27792783 }
27802784 const state : OpenCodeThreadState = {
@@ -2789,11 +2793,29 @@ export const makeOpenCodeAdapterV2 = Effect.fn("makeOpenCodeAdapterV2")(function
27892793 parentSubagent : subagentsByChildSessionId . get ( nativeSession . id ) ?? null ,
27902794 nextChildTurnOrdinal : 1 ,
27912795 nextAdmissionGeneration : 1 ,
2796+ permission : nativeSession . permission ?? [ ] ,
27922797 } ;
27932798 threads . set ( nativeSession . id , state ) ;
27942799 return state ;
27952800 } ;
27962801
2802+ const applyPermissionRules = Effect . fnUntraced ( function * (
2803+ state : OpenCodeThreadState ,
2804+ policy : ProviderAdapter . ProviderAdapterV2RuntimePolicy ,
2805+ ) {
2806+ const permission = openCodePermissionRules ( policy ) ;
2807+ if (
2808+ permission . length === state . permission . length &&
2809+ permission . every ( ( rule , index ) => permissionRuleEquals ( rule , state . permission [ index ] ! ) )
2810+ ) {
2811+ return ;
2812+ }
2813+ yield * sdkCall ( "session.update" , { sessionID : state . nativeSessionId , permission } , ( ) =>
2814+ client . session . update ( { sessionID : state . nativeSessionId , permission } ) ,
2815+ ) ;
2816+ state . permission = permission ;
2817+ } ) ;
2818+
27972819 const resolvePromptParts = Effect . fnUntraced ( function * (
27982820 turnInput : ProviderAdapter . ProviderAdapterV2TurnInput ,
27992821 ) {
@@ -2988,14 +3010,10 @@ export const makeOpenCodeAdapterV2 = Effect.fn("makeOpenCodeAdapterV2")(function
29883010 providerThread : threadInput . existingProviderThread ,
29893011 } ) ;
29903012 }
3013+ const permission = openCodePermissionRules ( threadInput . runtimePolicy ) ;
29913014 // OpenCode generates a title only when session.create leaves it unset.
2992- const response = yield * sdkCall (
2993- "session.create" ,
2994- { permission : openCodePermissionRules ( threadInput . runtimePolicy ) } ,
2995- ( ) =>
2996- client . session . create ( {
2997- permission : openCodePermissionRules ( threadInput . runtimePolicy ) ,
2998- } ) ,
3015+ const response = yield * sdkCall ( "session.create" , { permission } , ( ) =>
3016+ client . session . create ( { permission } ) ,
29993017 ) ;
30003018 const nativeSession = unwrapData ( "session.create" , response ) ;
30013019 const createdAt = yield * DateTime . now ;
@@ -3019,7 +3037,7 @@ export const makeOpenCodeAdapterV2 = Effect.fn("makeOpenCodeAdapterV2")(function
30193037 status : created . status ,
30203038 updatedAt : created . updatedAt ,
30213039 } ;
3022- registerThread ( nativeSession , providerThread , null ) ;
3040+ registerThread ( nativeSession , providerThread , null ) . permission = permission ;
30233041 return providerThread ;
30243042 } ,
30253043 ( effect , threadInput ) =>
@@ -3048,7 +3066,10 @@ export const makeOpenCodeAdapterV2 = Effect.fn("makeOpenCodeAdapterV2")(function
30483066 status : "idle" as const ,
30493067 updatedAt : dateTimeFromEpoch ( nativeSession . time . updated , resumedAt ) ,
30503068 } ;
3051- registerThread ( nativeSession , providerThread , null ) ;
3069+ const state = registerThread ( nativeSession , providerThread , null ) ;
3070+ if ( threadInput . runtimePolicy !== undefined ) {
3071+ yield * applyPermissionRules ( state , threadInput . runtimePolicy ) ;
3072+ }
30523073 return providerThread ;
30533074 } ,
30543075 ( effect , threadInput ) =>
@@ -3096,6 +3117,7 @@ export const makeOpenCodeAdapterV2 = Effect.fn("makeOpenCodeAdapterV2")(function
30963117 `OpenCode model '${ turnInput . modelSelection . model } ' must use provider/model format` ,
30973118 ) ;
30983119 }
3120+ yield * applyPermissionRules ( state , turnInput . runtimePolicy ) ;
30993121 const isCompaction =
31003122 turnInput . message . text . trim ( ) === "/compact" &&
31013123 turnInput . message . attachments . length === 0 ;
0 commit comments