I've got it! Thank Og for strange foreign language blogs :)
To fix it, I can simply tell the ASP.NET AJAX client-side framework to direct the partial request directly at the real target of the Server.Transfer() call. I am quite scared of the possible side-effects (who knows what this skips - the infrastructure does have a purpose) but it seems to be working fine so far.
Here is the method that fixes the problem, called in my page's Load event:
 ///
 /// Adds to the page a JavaScript that corrects the misbehavior of AJAX when a page is target of a Server.Transfer call.
 ///
 protected void AjaxUrlBugCorrection()
 {
  string actualFile = Server.MapPath(AppRelativeVirtualPath);
  string redirectFile = Server.MapPath(Context.Request.FilePath);
  string baseSiteVirtualPath = HttpRuntime.AppDomainAppVirtualPath;
  if (actualFile != redirectFile)
  {
   System.Text.StringBuilder sbJS = new System.Text.StringBuilder();
   string actionUrl = string.Format("'{0}'", baseSiteVirtualPath + AppRelativeVirtualPath.Replace("~", String.Empty));
   sbJS.Append("Sys.Application.add_load(function(){");
   sbJS.Append(" var form = Sys.WebForms.PageRequestManager.getInstance()._form;");
   sbJS.Append(" form._initialAction = " + actionUrl + ";");
   sbJS.Append(" form.action = " + actionUrl + ";");
   sbJS.Append("});");
   ClientScript.RegisterStartupScript(this.GetType(), "CorrecaoAjax", sbJS.ToString(), true);
  }
 }