@@ -121,6 +121,19 @@ describe('grant broker confinement predicate', () => {
121121 [ 'a padded adapter name' , undefined , { adapter : ' pi ' } , 'adapter_cannot_confine' ] ,
122122 [ 'a padded upper-case adapter name' , undefined , { adapter : 'PI ' } , 'adapter_cannot_confine' ] ,
123123 [ 'a normalised name that is not pi' , undefined , { adapter : ' claude ' } , null ] ,
124+ // TASK-175: the adapter is `runtime.adapter` OR `runtime.runtimeType`. A
125+ // hand-attached pi seat writes {runtimeType: 'pi', host: 'byo'} and no
126+ // adapter key (cli/src/commands/agent.js:664, :688), so reading `adapter`
127+ // alone admitted exactly the seat this rule exists to refuse.
128+ [ 'a pi seat tagged only by runtimeType (the hand-attached shape)' , undefined , { runtimeType : 'pi' , host : 'byo' } , 'adapter_cannot_confine' ] ,
129+ [ 'a pi runtimeType in another case' , undefined , { runtimeType : 'PI' } , 'adapter_cannot_confine' ] ,
130+ [ 'a declared adapter wins over a pi runtimeType, as it does in the daemon' , undefined , { adapter : 'claude' , runtimeType : 'pi' , host : 'byo' } , null ] ,
131+ [ 'a claude-code runtimeType' , undefined , { runtimeType : 'claude-code' , host : 'byo' } , null ] ,
132+ [ 'a webhook connect-page seat' , undefined , { runtimeType : 'webhook' , host : 'byo' } , null ] ,
133+ // The arm that rejects "refuse anything without an adapter": undeclared, the
134+ // daemon resolves only claude or codex (cli/src/commands/daemon.js:142), so
135+ // failing closed here would refuse working claude seats.
136+ [ 'a row naming neither adapter nor runtimeType' , undefined , { host : 'byo' } , null ] ,
124137 ] ) ( 'decides %s' , ( _label , environment , runtime , expected ) => {
125138 const refusal = grantBrokerRefusal ( environment , runtime ) ;
126139 if ( expected === null ) {
0 commit comments