diff --git a/app/but/jury_but.py b/app/but/jury_but.py
index 86a5e4a9a4561868f3af3468152b56e469964239..e01703ad627a5c265da1f4cb781b98a2228e028f 100644
--- a/app/but/jury_but.py
+++ b/app/but/jury_but.py
@@ -350,8 +350,9 @@ class DecisionsProposeesAnnee(DecisionsProposees):
         )
         "vrai si l'année est réussie, tous niveaux validables ou validés par le jury"
         self.valide_moitie_rcue = self.nb_validables > (self.nb_competences // 2)
-        "Peut passer si plus de la moitié validables et tous > 8"
+        "Vrai si plus de la moitié des RCUE validables"
         self.passage_de_droit = self.valide_moitie_rcue and (self.nb_rcues_under_8 == 0)
+        "Vrai si peut passer dans l'année BUT suivante: plus de la moitié validables et tous > 8"
         # XXX TODO ajouter condition pour passage en S5
 
         # Enfin calcule les codes des UE:
@@ -752,8 +753,9 @@ class DecisionsProposeesAnnee(DecisionsProposees):
         pour cette année: décisions d'UE, de RCUE, d'année,
         et autorisations d'inscription émises.
         Efface même si étudiant DEM ou DEF.
+        Si à cheval, n'efface que pour le semestre d'origine du deca.
         """
-        if only_one_sem:
+        if only_one_sem or self.a_cheval:
             # N'efface que les autorisations venant de ce semestre,
             # et les validations de ses UEs
             ScolarAutorisationInscription.delete_autorisation_etud(
@@ -906,6 +908,19 @@ class DecisionsProposeesRCUE(DecisionsProposees):
             or dec_prop_annee.formsemestre_pair.modalite == "EXT"
         ):
             self.codes.insert(0, sco_codes.ADM)
+        # S'il y a une décision enregistrée: si elle est plus favorable que celle que l'on
+        # proposerait, la place en tête.
+        # Sinon, la place en seconde place
+        if self.code_valide and self.code_valide != self.codes[0]:
+            code_default = self.codes[0]
+            if self.code_valide in self.codes:
+                self.codes.remove(self.code_valide)
+            if sco_codes.BUT_CODES_ORDERED.get(
+                self.code_valide, 0
+            ) > sco_codes.BUT_CODES_ORDERED.get(code_default, 0):
+                self.codes.insert(0, self.code_valide)
+            else:
+                self.codes.insert(1, self.code_valide)
 
     def record(self, code: str, no_overwrite=False):
         """Enregistre le code"""
diff --git a/app/but/jury_but_view.py b/app/but/jury_but_view.py
index 24224d62946e0ac9fa7d176cdf78648c055b2a71..d08329ea477e70f0c92f2ef43ba6a49e7f40f5a6 100644
--- a/app/but/jury_but_view.py
+++ b/app/but/jury_but_view.py
@@ -41,32 +41,21 @@ def show_etud(deca: DecisionsProposeesAnnee, read_only: bool = True) -> str:
     Si pas read_only, menus sélection codes jury.
     """
     H = []
-    if deca.code_valide and not read_only:
-        erase_span = f"""<a href="{
-            url_for("notes.formsemestre_jury_but_erase", 
-            scodoc_dept=g.scodoc_dept, formsemestre_id=deca.formsemestre_id, 
-            etudid=deca.etud.id)}" class="stdlink">effacer décisions</a>"""
-    else:
-        erase_span = ""
 
     H.append("""<div class="but_section_annee">""")
-    if deca.jury_annuel:
-        H.append(
-            f"""
-            <div>
-                <b>Décision de jury pour l'année :</b> {
-                    _gen_but_select("code_annee", deca.codes, deca.code_valide,
-                        disabled=True, klass="manual")
-                }
-                <span>({'non ' if deca.code_valide is None else ''}enregistrée)</span>
-                <span>{erase_span}</span>
-            </div>
+    H.append(
+        f"""
+        <div>
+            <b>Décision de jury pour l'année :</b> {
+                _gen_but_select("code_annee", deca.codes, deca.code_valide,
+                    disabled=True, klass="manual")
+            }
+            <span>({'non ' if deca.code_valide is None else ''}enregistrée)</span>
+        </div>
         """
-        )
-        div_explanation = f"""<div class="but_explanation">{deca.explanation}</div>"""
-    else:
-        H.append("""<div><em>Pas de décision annuelle (sem. impair).</em></div>""")
-        div_explanation = ""
+    )
+    div_explanation = f"""<div class="but_explanation">{deca.explanation}</div>"""
+
     H.append("""</div>""")
 
     formsemestre_1 = deca.formsemestre_impair
@@ -245,9 +234,16 @@ def _gen_but_rcue(dec_rcue: DecisionsProposeesRCUE, niveau: ApcNiveau) -> str:
         else ""
     )
 
+    # Déjà enregistré ?
+    niveau_rcue_class = ""
+    if dec_rcue.code_valide is not None and dec_rcue.codes:
+        if dec_rcue.code_valide == dec_rcue.codes[0]:
+            niveau_rcue_class = "recorded"
+        else:
+            niveau_rcue_class = "recorded_different"
+
     return f"""
-        <div class="but_niveau_rcue
-        {'recorded' if dec_rcue.code_valide is not None else ''}
+        <div class="but_niveau_rcue {niveau_rcue_class}
         ">
             <div class="but_note with_scoplement">
                 <div>{scu.fmt_note(dec_rcue.rcue.moy_rcue)}</div>
@@ -351,7 +347,7 @@ def jury_but_semestriel(
         warning = ""
     H = [
         html_sco_header.sco_header(
-            page_title="Validation BUT",
+            page_title=f"Validation BUT S{formsemestre.semestre_id}",
             formsemestre_id=formsemestre.id,
             etudid=etud.id,
             cssstyles=("css/jury_but.css",),
@@ -376,21 +372,21 @@ def jury_but_semestriel(
         {warning}
         </div>
 
-        <form method="POST">
+        <form method="post" id="jury_but">
         """,
     ]
     if (not read_only) and any([dec.code_valide for dec in decisions_ues.values()]):
         erase_span = f"""<a href="{
             url_for("notes.formsemestre_jury_but_erase", 
             scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre.id, 
-            etudid=etud.id, only_one_sem=1)}" class="stdlink">effacer les décisions enregistrées</a>"""
+            etudid=etud.id, only_one_sem=1)
+            }" class="stdlink">effacer les décisions enregistrées</a>"""
     else:
         erase_span = "Cet étudiant n'a aucune décision enregistrée pour ce semestre."
 
     H.append(
         f"""
     <div class="but_section_annee">
-        <span>{erase_span}</span>
     </div>
     <div><b>Unités d'enseignement de S{formsemestre.semestre_id}:</b></div>
     """
@@ -447,9 +443,10 @@ def jury_but_semestriel(
         else:
             H.append("""<div class="help">dernier semestre de la formation.</div>""")
         H.append(
-            """
+            f"""
             <div class="but_buttons">
-                <input type="submit" value="Enregistrer ces décisions">
+                <span><input type="submit" value="Enregistrer ces décisions"></span>
+                <span>{erase_span}</span>
             </div>
             """
         )
diff --git a/app/models/but_validations.py b/app/models/but_validations.py
index ad191d29b93c54e7f4f94fd17c40ce9c49578dbb..ab820bc38663792d48f9a94b3d548c64009bbd11 100644
--- a/app/models/but_validations.py
+++ b/app/models/but_validations.py
@@ -180,8 +180,9 @@ class RegroupementCoherentUE:
         return self.query_validations().count() > 0
 
     def est_compensable(self):
-        """Vrai si ce RCUE est validable par compensation
-        c'est à dire que sa moyenne est > 10 avec une UE < 10
+        """Vrai si ce RCUE est validable (uniquement) par compensation
+        c'est à dire que sa moyenne est > 10 avec une UE < 10.
+        Note: si ADM, est_compensable est faux.
         """
         return (
             (self.moy_rcue is not None)
diff --git a/app/scodoc/sco_codes_parcours.py b/app/scodoc/sco_codes_parcours.py
index 299ccdde88f50d73907434b84a3a8d541e501fcd..7d90edbcb173f1ff15a9d8079f7fb91f47780419 100644
--- a/app/scodoc/sco_codes_parcours.py
+++ b/app/scodoc/sco_codes_parcours.py
@@ -205,6 +205,20 @@ BUT_CODES_PASSAGE = {
     PAS1NCI,
     ATJ,
 }
+# les codes, du plus "défavorable" à l'étudiant au plus favorable:
+# (valeur par défaut 0)
+BUT_CODES_ORDERED = {
+    "NAR": 0,
+    "DEF": 0,
+    "AJ": 10,
+    "ATJ": 20,
+    "CMP": 50,
+    "ADC": 50,
+    "PASD": 50,
+    "PAS1NCI": 60,
+    "ADJ": 100,
+    "ADM": 100,
+}
 
 
 def code_semestre_validant(code: str) -> bool:
diff --git a/app/static/css/jury_but.css b/app/static/css/jury_but.css
index 955aed943a99dc91161ce3990f6d19246e4bab68..f865400a046140695697e7ec7d8263d3b493b555 100644
--- a/app/static/css/jury_but.css
+++ b/app/static/css/jury_but.css
@@ -22,7 +22,7 @@
     margin-left: 32px;
     display: inline-grid;
     grid-template-columns: repeat(4, auto);
-    gap: 4px;
+    gap: 8px;
 }
 
 .but_annee_caption {
@@ -143,8 +143,14 @@ div.but_code {
 
 div.but_niveau_ue.recorded,
 div.but_niveau_rcue.recorded {
-    border-color: rgb(136, 252, 136);
-    border-width: 2px;
+    border-color: rgb(0, 169, 0);
+    border-width: 3px;
+}
+
+div.but_niveau_ue.recorded_different,
+div.but_niveau_rcue.recorded_different {
+    box-shadow: 0 0 0 3px red;
+    outline: dashed 3px rgb(0, 169, 0);
 }
 
 div.but_niveau_ue.annee_prec {
@@ -160,6 +166,7 @@ div.but_buttons {
 }
 
 div.but_buttons span {
+    margin-left: 16px;
     margin-right: 16px;
 }
 
diff --git a/app/static/js/jury_but.js b/app/static/js/jury_but.js
index c90f95d633019ee8f9efd5b570021f3a14e6eba8..54d28a841d7c98a6329e1adced62a812324a3ac6 100644
--- a/app/static/js/jury_but.js
+++ b/app/static/js/jury_but.js
@@ -63,6 +63,8 @@ $(function () {
 
 //  ----- Etat du formulaire jury pour éviter sortie sans enregistrer
 let FORM_STATE = "";
+let IS_SUBMITTING = false;
+
 // Une chaine décrivant l'état du form
 function get_form_state() {
     let codes = [];
@@ -73,13 +75,19 @@ function get_form_state() {
 
 $('document').ready(function () {
     FORM_STATE = get_form_state();
+    document.querySelector("form#jury_but").addEventListener('submit', jury_form_submit);
 });
 
 function is_modified() {
     return FORM_STATE != get_form_state();
 }
+
+function jury_form_submit(event) {
+    IS_SUBMITTING = true;
+}
+
 window.addEventListener("beforeunload", function (e) {
-    if (is_modified()) {
+    if ((!IS_SUBMITTING) && is_modified()) {
         var confirmationMessage = 'Changements non enregistrés !';
         (e || window.event).returnValue = confirmationMessage;
         return confirmationMessage;
diff --git a/app/views/notes.py b/app/views/notes.py
index 48fb28aea38eaf56dc43a5a2188844f046f3f737..06d62445d499f2d26a6f97375e288905f1668db3 100644
--- a/app/views/notes.py
+++ b/app/views/notes.py
@@ -2327,17 +2327,17 @@ def formsemestre_validation_but(
     # provisoires avec NEXT et PREV
     try:
         etudid = int(etudid)
-    except:
+    except ValueError:
         abort(404, "invalid etudid")
     read_only = not sco_permissions_check.can_validate_sem(formsemestre_id)
 
     # --- Navigation
-    prev = f"""{scu.EMO_PREV_ARROW}&nbsp;<a href="{url_for(
+    prev_lnk = f"""{scu.EMO_PREV_ARROW}&nbsp;<a href="{url_for(
                 "notes.formsemestre_validation_but", scodoc_dept=g.scodoc_dept,
                 formsemestre_id=formsemestre_id, etudid="PREV"
             )}" class="stdlink"">précédent</a>
     """
-    next = f"""<a href="{url_for(
+    next_lnk = f"""<a href="{url_for(
                 "notes.formsemestre_validation_but", scodoc_dept=g.scodoc_dept,
                 formsemestre_id=formsemestre_id, etudid="NEXT"
             )}" class="stdlink"">suivant</a>&nbsp;{scu.EMO_NEXT_ARROW}
@@ -2345,7 +2345,7 @@ def formsemestre_validation_but(
     navigation_div = f"""
     <div class="but_navigation">
         <div class="prev">
-           {prev}
+           {prev_lnk}
         </div>
         <div class="back_list">
             <a href="{url_for(
@@ -2354,21 +2354,20 @@ def formsemestre_validation_but(
             )}" class="stdlink">retour à la liste</a>
         </div>
         <div class="next">
-            {next}
+            {next_lnk}
         </div>
     </div>
     """
 
     H = [
         html_sco_header.sco_header(
-            page_title="Validation BUT",
+            page_title=f"Validation BUT S{formsemestre.semestre_id}",
             formsemestre_id=formsemestre_id,
             etudid=etudid,
             cssstyles=("css/jury_but.css",),
             javascripts=("js/jury_but.js",),
         ),
-        f"""
-        <div class="jury_but">
+        """<div class="jury_but">
         """,
     ]
 
@@ -2401,7 +2400,6 @@ def formsemestre_validation_but(
 
     deca = jury_but.DecisionsProposeesAnnee(etud, formsemestre)
     if len(deca.rcues_annee) == 0:
-        # raise ScoValueError("année incomplète: pas de jury BUT annuel possible")
         return jury_but_view.jury_but_semestriel(
             formsemestre, etud, read_only, navigation_div=navigation_div
         )
@@ -2421,7 +2419,7 @@ def formsemestre_validation_but(
     warning = ""
     if len(deca.niveaux_competences) != len(deca.decisions_rcue_by_niveau):
         if deca.a_cheval:
-            warning += f"""<div class="warning">Attention: regroupements RCUE
+            warning += """<div class="warning">Attention: regroupements RCUE
                 entre années (redoublement).</div>"""
         else:
             warning += f"""<div class="warning">Attention: {len(deca.niveaux_competences)}
@@ -2454,7 +2452,7 @@ def formsemestre_validation_but(
         {warning}
     </div>
 
-    <form method="POST">
+    <form method="post" id="jury_but">
     """
     )
 
@@ -2467,6 +2465,10 @@ def formsemestre_validation_but(
             Les champs entourés en vert sont enregistrés.</div>"""
         )
     else:
+        erase_span = f"""<a href="{
+            url_for("notes.formsemestre_jury_but_erase",
+            scodoc_dept=g.scodoc_dept, formsemestre_id=deca.formsemestre_id,
+            etudid=deca.etud.id)}" class="stdlink">effacer décisions</a>"""
         H.append(
             f"""<div class="but_settings">
             <input type="checkbox" onchange="enable_manual_codes(this)">
@@ -2477,7 +2479,8 @@ def formsemestre_validation_but(
             </div>
 
             <div class="but_buttons">
-                <input type="submit" value="Enregistrer ces décisions">
+                <span><input type="submit" value="Enregistrer ces décisions"></span>
+                <span>{erase_span}</span>
             </div>
             """
         )
@@ -2790,7 +2793,9 @@ def formsemestre_jury_but_erase(
         explanation=f"""Les validations d'UE et autorisations de passage
             du semestre S{formsemestre.semestre_id} seront effacées."""
         if only_one_sem
-        else """Les validations de toutes les UE, RCUE (compétences) et année seront effacées.""",
+        else """Les validations de toutes les UE, RCUE (compétences) et année seront effacées.
+        Les décisions de l'année scolaire précédente ne seront pas modifiées.
+        """,
         cancel_url=dest_url,
     )