@@ -158,10 +158,9 @@ fn build_deploy_payload(
158158
159159 // Resolve effective model/provider from the persona's structured fields.
160160 // Agent record's model takes precedence (user override via UI).
161+ let personas = load_personas ( app)
162+ . map_err ( |e| format ! ( "failed to load personas for deploy payload resolution: {e}" ) ) ?;
161163 let ( effective_model, effective_provider) = if let Some ( ref pid) = record. persona_id {
162- let personas = load_personas ( app) . map_err ( |e| {
163- format ! ( "failed to load personas for deploy payload model resolution: {e}" )
164- } ) ?;
165164 let persona = personas. iter ( ) . find ( |p| p. id == * pid) ;
166165 let model = record
167166 . model
@@ -173,6 +172,17 @@ fn build_deploy_payload(
173172 ( record. model . clone ( ) , None )
174173 } ;
175174
175+ // Resolve the effective harness (persona-wins, override-honored) so the
176+ // remote provider runs the same harness a local spawn would — derive args
177+ // from it rather than the frozen record snapshot.
178+ let effective_command = crate :: managed_agents:: effective_agent_command (
179+ record. persona_id . as_deref ( ) ,
180+ & personas,
181+ record. agent_command_override . as_deref ( ) ,
182+ ) ;
183+ let effective_args =
184+ crate :: managed_agents:: normalize_agent_args ( & effective_command, record. agent_args . clone ( ) ) ;
185+
176186 Ok ( serde_json:: json!( {
177187 "name" : & record. name,
178188 // Resolve the per-agent pin against the active workspace relay here:
@@ -186,8 +196,8 @@ fn build_deploy_payload(
186196 ) ,
187197 "private_key_nsec" : & record. private_key_nsec,
188198 "auth_tag" : & record. auth_tag,
189- "agent_command" : & record . agent_command ,
190- "agent_args" : & record . agent_args ,
199+ "agent_command" : & effective_command ,
200+ "agent_args" : & effective_args ,
191201 "system_prompt" : & record. system_prompt,
192202 "model" : effective_model,
193203 "provider" : effective_provider,
@@ -461,13 +471,31 @@ pub async fn create_managed_agent(
461471 None
462472 } ;
463473
464- let agent_command = input
465- . agent_command
466- . as_deref ( )
467- . map ( str:: trim)
468- . filter ( |value| !value. is_empty ( ) )
469- . map ( str:: to_string)
470- . unwrap_or_else ( crate :: managed_agents:: default_agent_command) ;
474+ // Load personas once for harness/pack/avatar resolution below.
475+ let personas = load_personas ( & app) . unwrap_or_default ( ) ;
476+
477+ // Harness resolution: the persona's runtime is authoritative. A
478+ // persona-backed create stores an `agent_command_override` ONLY when the
479+ // user deliberately picked a divergent runtime (`harness_override`) —
480+ // e.g. AddChannelBotDialog's runtime selector. A divergence WITHOUT that
481+ // flag is a missing-runtime fallback from `resolvePersonaRuntime`, not a
482+ // pin, and must inherit so it doesn't freeze on the fallback harness once
483+ // the persona's runtime is installed. A persona-less create always
484+ // preserves the picked command as a real pin.
485+ let agent_command_override = crate :: managed_agents:: create_time_agent_command_override (
486+ requested_persona_id. as_deref ( ) ,
487+ & personas,
488+ input. agent_command . as_deref ( ) ,
489+ input. harness_override ,
490+ ) ;
491+ // The create-time snapshot used for arg/mcp/avatar derivations and
492+ // legacy reconcile. Authoritative spawn resolution re-derives this via
493+ // `effective_agent_command` at use-time.
494+ let agent_command = crate :: managed_agents:: effective_agent_command (
495+ requested_persona_id. as_deref ( ) ,
496+ & personas,
497+ agent_command_override. as_deref ( ) ,
498+ ) ;
471499 let agent_args = normalize_agent_args (
472500 & agent_command,
473501 input
@@ -496,7 +524,6 @@ pub async fn create_managed_agent(
496524 // matches on this internal name, NOT display_name.
497525 let pack_metadata: Option < ( std:: path:: PathBuf , String ) > =
498526 requested_persona_id. as_deref ( ) . and_then ( |pid| {
499- let personas = load_personas ( & app) . ok ( ) ?;
500527 let persona = personas. iter ( ) . find ( |p| p. id == pid) ?;
501528 let team_id = persona. source_team . as_deref ( ) ?;
502529 let slug = persona. source_team_persona_slug . as_deref ( ) ?;
@@ -512,11 +539,11 @@ pub async fn create_managed_agent(
512539 // fallback. Storing it lets reconciliation compare against what was
513540 // actually published instead of re-deriving it.
514541 let persona_avatar_url = requested_persona_id. as_ref ( ) . and_then ( |persona_id| {
515- load_personas ( & app)
516- . ok ( ) ?
517- . into_iter ( )
542+ personas
543+ . iter ( )
518544 . find ( |persona| persona. id == * persona_id) ?
519545 . avatar_url
546+ . clone ( )
520547 } ) ;
521548 let resolved_avatar_url = resolve_created_avatar_url (
522549 input. avatar_url . as_deref ( ) ,
@@ -540,6 +567,7 @@ pub async fn create_managed_agent(
540567 . unwrap_or ( DEFAULT_ACP_COMMAND )
541568 . to_string ( ) ,
542569 agent_command,
570+ agent_command_override,
543571 agent_args,
544572 mcp_command,
545573 turn_timeout_seconds : input
@@ -797,14 +825,24 @@ pub async fn start_managed_agent(
797825
798826 let record = find_managed_agent_mut ( & mut records, & pubkey) ?;
799827
828+ // Resolve the effective harness for the avatar-fallback derivation in
829+ // profile reconcile (the create-time snapshot may be empty or stale for
830+ // a persona-inherited harness).
831+ let reconcile_personas = load_personas ( & app) . unwrap_or_default ( ) ;
832+ let reconcile_effective_command = crate :: managed_agents:: effective_agent_command (
833+ record. persona_id . as_deref ( ) ,
834+ & reconcile_personas,
835+ record. agent_command_override . as_deref ( ) ,
836+ ) ;
837+
800838 let reconcile = ProfileReconcileData {
801839 private_key_nsec : record. private_key_nsec . clone ( ) ,
802840 name : record. name . clone ( ) ,
803841 relay_url : record. relay_url . clone ( ) ,
804842 avatar_url : record. avatar_url . clone ( ) ,
805843 auth_tag : record. auth_tag . clone ( ) ,
806844 pubkey : record. pubkey . clone ( ) ,
807- agent_command : record . agent_command . clone ( ) ,
845+ agent_command : reconcile_effective_command ,
808846 persona_id : record. persona_id . clone ( ) ,
809847 } ;
810848
0 commit comments