@@ -331,7 +331,7 @@ impl StoredAgentIdentity {
331331 Ok ( Self {
332332 binding_id : binding. binding_id . clone ( ) ,
333333 chatgpt_account_id : binding. chatgpt_account_id . clone ( ) ,
334- chatgpt_user_id : binding . chatgpt_user_id . clone ( ) ,
334+ chatgpt_user_id : record . chatgpt_user_id ,
335335 agent_runtime_id : record. agent_runtime_id ,
336336 private_key_pkcs8_base64 : record. agent_private_key ,
337337 public_key_ssh : encode_ssh_ed25519_public_key ( & signing_key. verifying_key ( ) ) ,
@@ -343,6 +343,7 @@ impl StoredAgentIdentity {
343343 fn to_auth_record ( & self ) -> AgentIdentityAuthRecord {
344344 AgentIdentityAuthRecord {
345345 workspace_id : self . chatgpt_account_id . clone ( ) ,
346+ chatgpt_user_id : self . chatgpt_user_id . clone ( ) ,
346347 agent_runtime_id : self . agent_runtime_id . clone ( ) ,
347348 agent_private_key : self . private_key_pkcs8_base64 . clone ( ) ,
348349 registered_at : self . registered_at . clone ( ) ,
@@ -589,6 +590,7 @@ mod tests {
589590 AgentIdentityBinding :: from_auth ( & auth, /*forced_workspace_id*/ None ) . expect ( "binding" ) ;
590591 auth. set_agent_identity ( AgentIdentityAuthRecord {
591592 workspace_id : "account-123" . to_string ( ) ,
593+ chatgpt_user_id : Some ( "user-123" . to_string ( ) ) ,
592594 agent_runtime_id : "agent_invalid" . to_string ( ) ,
593595 agent_private_key : "not-valid-base64" . to_string ( ) ,
594596 registered_at : "2026-01-01T00:00:00Z" . to_string ( ) ,
@@ -608,6 +610,55 @@ mod tests {
608610 assert_eq ! ( persisted. agent_runtime_id, "agent_456" ) ;
609611 }
610612
613+ #[ tokio:: test]
614+ async fn ensure_registered_identity_deletes_different_user_identity_and_reregisters ( ) {
615+ let server = MockServer :: start ( ) . await ;
616+ let chatgpt_base_url = server. uri ( ) ;
617+ mount_human_biscuit ( & server, & chatgpt_base_url) . await ;
618+ Mock :: given ( method ( "POST" ) )
619+ . and ( path ( "/v1/agent/register" ) )
620+ . and ( header ( "x-openai-authorization" , "human-biscuit" ) )
621+ . respond_with ( ResponseTemplate :: new ( 200 ) . set_body_json ( serde_json:: json!( {
622+ "agent_runtime_id" : "agent_new" ,
623+ } ) ) )
624+ . expect ( 1 )
625+ . mount ( & server)
626+ . await ;
627+
628+ let auth = make_chatgpt_auth ( "account-123" , Some ( "user-new" ) ) ;
629+ let stale_key = generate_agent_key_material ( ) . expect ( "key material" ) ;
630+ auth. set_agent_identity ( AgentIdentityAuthRecord {
631+ workspace_id : "account-123" . to_string ( ) ,
632+ chatgpt_user_id : Some ( "user-old" . to_string ( ) ) ,
633+ agent_runtime_id : "agent_old" . to_string ( ) ,
634+ agent_private_key : stale_key. private_key_pkcs8_base64 ,
635+ registered_at : "2026-01-01T00:00:00Z" . to_string ( ) ,
636+ } )
637+ . expect ( "seed stale identity" ) ;
638+
639+ let auth_manager = AuthManager :: from_auth_for_testing ( auth. clone ( ) ) ;
640+ let manager = AgentIdentityManager :: new_for_tests (
641+ auth_manager,
642+ /*feature_enabled*/ true ,
643+ chatgpt_base_url,
644+ SessionSource :: Cli ,
645+ ) ;
646+
647+ let stored = manager
648+ . ensure_registered_identity ( )
649+ . await
650+ . unwrap ( )
651+ . expect ( "identity should be registered" ) ;
652+
653+ assert_eq ! ( stored. agent_runtime_id, "agent_new" ) ;
654+ assert_eq ! ( stored. chatgpt_user_id. as_deref( ) , Some ( "user-new" ) ) ;
655+ let persisted = auth
656+ . get_agent_identity ( "account-123" )
657+ . expect ( "stored identity" ) ;
658+ assert_eq ! ( persisted. agent_runtime_id, "agent_new" ) ;
659+ assert_eq ! ( persisted. chatgpt_user_id. as_deref( ) , Some ( "user-new" ) ) ;
660+ }
661+
611662 #[ tokio:: test]
612663 async fn ensure_registered_identity_uses_chatgpt_base_url ( ) {
613664 let server = MockServer :: start ( ) . await ;
0 commit comments