diff --git a/daemons/fenced/fenced_history.c b/daemons/fenced/fenced_history.c
index 4e9dafae2e..8102e8f810 100644
--- a/daemons/fenced/fenced_history.c
+++ b/daemons/fenced/fenced_history.c
@@ -1,553 +1,556 @@
 /*
  * Copyright 2009-2024 the Pacemaker project contributors
  *
  * The version control history for this file may have further details.
  *
  * This source code is licensed under the GNU General Public License version 2
  * or later (GPLv2+) WITHOUT ANY WARRANTY.
  */
 
 #include <crm_internal.h>
 
 #include <stdio.h>
 #include <unistd.h>
 #include <stdlib.h>
 
 #include <crm/crm.h>
 #include <crm/common/ipc.h>
 #include <crm/common/ipc_internal.h>
 #include <crm/cluster/internal.h>
 
 #include <crm/stonith-ng.h>
 #include <crm/fencing/internal.h>
 #include <crm/common/xml.h>
 #include <crm/common/xml_internal.h>
 
 #include <pacemaker-fenced.h>
 
 #define MAX_STONITH_HISTORY 500
 
 /*!
  * \internal
  * \brief Send a broadcast to all nodes to trigger cleanup or
  *        history synchronisation
  *
  * \param[in] history   Optional history to be attached
  * \param[in] callopts  We control cleanup via a flag in the callopts
  * \param[in] target    Cleanup can be limited to certain fence-targets
  */
 static void
 stonith_send_broadcast_history(xmlNode *history,
                                int callopts,
                                const char *target)
 {
     xmlNode *bcast = create_xml_node(NULL, "stonith_command");
     xmlNode *data = create_xml_node(NULL, __func__);
 
     if (target) {
         crm_xml_add(data, PCMK__XA_ST_TARGET, target);
     }
     crm_xml_add(bcast, PCMK__XA_T, T_STONITH_NG);
     crm_xml_add(bcast, PCMK__XA_SUBT, "broadcast");
     crm_xml_add(bcast, PCMK__XA_ST_OP, STONITH_OP_FENCE_HISTORY);
     crm_xml_add_int(bcast, PCMK__XA_ST_CALLOPT, callopts);
     if (history) {
         add_node_copy(data, history);
     }
     add_message_xml(bcast, PCMK__XA_ST_CALLDATA, data);
     send_cluster_message(NULL, crm_msg_stonith_ng, bcast, FALSE);
 
     free_xml(data);
     free_xml(bcast);
 }
 
 static gboolean
 stonith_remove_history_entry (gpointer key,
                               gpointer value,
                               gpointer user_data)
 {
     remote_fencing_op_t *op = value;
     const char *target = (const char *) user_data;
 
     if ((op->state == st_failed) || (op->state == st_done)) {
         if ((target) && (strcmp(op->target, target) != 0)) {
             return FALSE;
         }
         return TRUE;
     }
 
     return FALSE; /* don't clean pending operations */
 }
 
 /*!
  * \internal
  * \brief Send out a cleanup broadcast or do a local history-cleanup
  *
  * \param[in] target    Cleanup can be limited to certain fence-targets
  * \param[in] broadcast Send out a cleanup broadcast
  */
 static void
 stonith_fence_history_cleanup(const char *target,
                               gboolean broadcast)
 {
     if (broadcast) {
         stonith_send_broadcast_history(NULL,
                                        st_opt_cleanup | st_opt_discard_reply,
                                        target);
         /* we'll do the local clean when we receive back our own broadcast */
     } else if (stonith_remote_op_list) {
         g_hash_table_foreach_remove(stonith_remote_op_list,
                              stonith_remove_history_entry,
                              (gpointer) target);
         fenced_send_notification(T_STONITH_NOTIFY_HISTORY, NULL, NULL);
     }
 }
 
 /* keeping the length of fence-history within bounds
  * =================================================
  *
  * If things are really running wild a lot of fencing-attempts
  * might fill up the hash-map, eventually using up a lot
  * of memory and creating huge history-sync messages.
  * Before the history being synced across nodes at least
  * the reboot of a cluster-node helped keeping the
  * history within bounds even though not in a reliable
  * manner.
  *
  * stonith_remote_op_list isn't sorted for time-stamps
  * thus it would be kind of expensive to delete e.g.
  * the oldest entry if it would grow past MAX_STONITH_HISTORY
  * entries.
  * It is more efficient to purge MAX_STONITH_HISTORY/2
  * entries whenever the list grows beyond MAX_STONITH_HISTORY.
  * (sort for age + purge the MAX_STONITH_HISTORY/2 oldest)
  * That done on a per-node-base might raise the
  * probability of large syncs to occur.
  * Things like introducing a broadcast to purge
  * MAX_STONITH_HISTORY/2 entries or not sync above a certain
  * threshold coming to mind ...
  * Simplest thing though is to purge the full history
  * throughout the cluster once MAX_STONITH_HISTORY is reached.
  * On the other hand this leads to purging the history in
  * situations where it would be handy to have it probably.
  */
 
 
 static int
 op_time_sort(const void *a_voidp, const void *b_voidp)
 {
     const remote_fencing_op_t **a = (const remote_fencing_op_t **) a_voidp;
     const remote_fencing_op_t **b = (const remote_fencing_op_t **) b_voidp;
     gboolean a_pending = ((*a)->state != st_failed) && ((*a)->state != st_done);
     gboolean b_pending = ((*b)->state != st_failed) && ((*b)->state != st_done);
 
     if (a_pending && b_pending) {
         return 0;
     } else if (a_pending) {
         return -1;
     } else if (b_pending) {
         return 1;
     } else if ((*b)->completed == (*a)->completed) {
         if ((*b)->completed_nsec > (*a)->completed_nsec) {
             return 1;
         } else if ((*b)->completed_nsec == (*a)->completed_nsec) {
             return 0;
         }
     } else if ((*b)->completed > (*a)->completed) {
         return 1;
     }
 
     return -1;
 }
 
 
 /*!
  * \internal
  * \brief Do a local history-trim to MAX_STONITH_HISTORY / 2 entries
  *        once over MAX_STONITH_HISTORY
  */
 void
 stonith_fence_history_trim(void)
 {
     guint num_ops;
 
     if (!stonith_remote_op_list) {
         return;
     }
     num_ops = g_hash_table_size(stonith_remote_op_list);
     if (num_ops > MAX_STONITH_HISTORY) {
         remote_fencing_op_t *ops[num_ops];
         remote_fencing_op_t *op = NULL;
         GHashTableIter iter;
         int i;
 
         crm_trace("Fencing History growing beyond limit of %d so purge "
                   "half of failed/successful attempts", MAX_STONITH_HISTORY);
 
         /* write all ops into an array */
         i = 0;
         g_hash_table_iter_init(&iter, stonith_remote_op_list);
         while (g_hash_table_iter_next(&iter, NULL, (void **)&op)) {
             ops[i++] = op;
         }
         /* run quicksort over the array so that we get pending ops
          * first and then sorted most recent to oldest
          */
         qsort(ops, num_ops, sizeof(remote_fencing_op_t *), op_time_sort);
         /* purgest oldest half of the history entries */
         for (i = MAX_STONITH_HISTORY / 2; i < num_ops; i++) {
             /* keep pending ops even if they shouldn't fill more than
              * half of our buffer
              */
             if ((ops[i]->state == st_failed) || (ops[i]->state == st_done)) {
                 g_hash_table_remove(stonith_remote_op_list, ops[i]->id);
             }
         }
         /* we've just purged valid data from the list so there is no need
          * to create a notification - if displayed it can stay
          */
     }
 }
 
 /*!
  * \internal
  * \brief Convert xml fence-history to a hash-table like stonith_remote_op_list
  *
  * \param[in] history   Fence-history in xml
  *
  * \return Fence-history as hash-table
  */
 static GHashTable *
 stonith_xml_history_to_list(const xmlNode *history)
 {
     xmlNode *xml_op = NULL;
     GHashTable *rv = NULL;
 
     init_stonith_remote_op_hash_table(&rv);
 
     CRM_LOG_ASSERT(rv != NULL);
 
     for (xml_op = pcmk__xml_first_child(history); xml_op != NULL;
          xml_op = pcmk__xml_next(xml_op)) {
         remote_fencing_op_t *op = NULL;
         char *id = crm_element_value_copy(xml_op, PCMK__XA_ST_REMOTE_OP);
         int state;
         int exit_status = CRM_EX_OK;
         int execution_status = PCMK_EXEC_DONE;
         long long completed;
         long long completed_nsec = 0L;
 
         if (!id) {
             crm_warn("Malformed fencing history received from peer");
             continue;
         }
 
         crm_trace("Attaching op %s to hashtable", id);
 
         op = calloc(1, sizeof(remote_fencing_op_t));
 
         op->id = id;
         op->target = crm_element_value_copy(xml_op, PCMK__XA_ST_TARGET);
         op->action = crm_element_value_copy(xml_op, F_STONITH_ACTION);
         op->originator = crm_element_value_copy(xml_op, PCMK__XA_ST_ORIGIN);
         op->delegate = crm_element_value_copy(xml_op, PCMK__XA_ST_DELEGATE);
         op->client_name = crm_element_value_copy(xml_op,
                                                  PCMK__XA_ST_CLIENTNAME);
         crm_element_value_ll(xml_op, PCMK__XA_ST_DATE, &completed);
         op->completed = (time_t) completed;
         crm_element_value_ll(xml_op, PCMK__XA_ST_DATE_NSEC, &completed_nsec);
         op->completed_nsec = completed_nsec;
         crm_element_value_int(xml_op, PCMK__XA_ST_STATE, &state);
         op->state = (enum op_state) state;
 
         /* @COMPAT We can't use stonith__xe_get_result() here because
          * fencers <2.1.3 didn't include results, leading it to assume an error
          * status. Instead, set an unknown status in that case.
          */
         if ((crm_element_value_int(xml_op, PCMK__XA_RC_CODE, &exit_status) < 0)
             || (crm_element_value_int(xml_op, PCMK__XA_OP_STATUS,
                                       &execution_status) < 0)) {
             exit_status = CRM_EX_INDETERMINATE;
             execution_status = PCMK_EXEC_UNKNOWN;
         }
         pcmk__set_result(&op->result, exit_status, execution_status,
                          crm_element_value(xml_op, PCMK_XA_EXIT_REASON));
         pcmk__set_result_output(&op->result,
                                 crm_element_value_copy(xml_op,
                                                        PCMK__XA_ST_OUTPUT),
                                 NULL);
 
 
         g_hash_table_replace(rv, id, op);
         CRM_LOG_ASSERT(g_hash_table_lookup(rv, id) != NULL);
     }
 
     return rv;
 }
 
 /*!
  * \internal
  * \brief Craft xml difference between local fence-history and a history
  *        coming from remote, and merge the remote history into the local
  *
  * \param[in,out] remote_history  Fence-history as hash-table (may be NULL)
  * \param[in]     add_id          If crafting the answer for an API
  *                                history-request there is no need for the id
  * \param[in]     target          Optionally limit to certain fence-target
  *
  * \return The fence-history as xml
  */
 static xmlNode *
 stonith_local_history_diff_and_merge(GHashTable *remote_history,
                                      gboolean add_id, const char *target)
 {
     xmlNode *history = NULL;
     GHashTableIter iter;
     remote_fencing_op_t *op = NULL;
     gboolean updated = FALSE;
     int cnt = 0;
 
     if (stonith_remote_op_list) {
             char *id = NULL;
 
             history = create_xml_node(NULL, PCMK__XE_ST_HISTORY);
 
             g_hash_table_iter_init(&iter, stonith_remote_op_list);
             while (g_hash_table_iter_next(&iter, (void **)&id, (void **)&op)) {
                 xmlNode *entry = NULL;
 
                 if (remote_history) {
                     remote_fencing_op_t *remote_op =
                         g_hash_table_lookup(remote_history, op->id);
 
                     if (remote_op) {
                         if (stonith__op_state_pending(op->state)
                             && !stonith__op_state_pending(remote_op->state)) {
 
                             crm_debug("Updating outdated pending operation %.8s "
                                       "(state=%s) according to the one (state=%s) from "
                                       "remote peer history",
                                       op->id, stonith_op_state_str(op->state),
                                       stonith_op_state_str(remote_op->state));
 
                             g_hash_table_steal(remote_history, op->id);
                             op->id = remote_op->id;
                             remote_op->id = id;
                             g_hash_table_iter_replace(&iter, remote_op);
 
                             updated = TRUE;
                             continue; /* skip outdated entries */
 
                         } else if (!stonith__op_state_pending(op->state)
                                    && stonith__op_state_pending(remote_op->state)) {
 
                             crm_debug("Broadcasting operation %.8s (state=%s) to "
                                       "update the outdated pending one "
                                       "(state=%s) in remote peer history",
                                       op->id, stonith_op_state_str(op->state),
                                       stonith_op_state_str(remote_op->state));
 
                             g_hash_table_remove(remote_history, op->id);
 
                         } else {
                             g_hash_table_remove(remote_history, op->id);
                             continue; /* skip entries broadcasted already */
                         }
                     }
                 }
 
                 if (!pcmk__str_eq(target, op->target, pcmk__str_null_matches)) {
                     continue;
                 }
 
                 cnt++;
                 crm_trace("Attaching op %s", op->id);
                 entry = create_xml_node(history, STONITH_OP_EXEC);
                 if (add_id) {
                     crm_xml_add(entry, PCMK__XA_ST_REMOTE_OP, op->id);
                 }
                 crm_xml_add(entry, PCMK__XA_ST_TARGET, op->target);
                 crm_xml_add(entry, F_STONITH_ACTION, op->action);
                 crm_xml_add(entry, PCMK__XA_ST_ORIGIN, op->originator);
                 crm_xml_add(entry, PCMK__XA_ST_DELEGATE, op->delegate);
                 crm_xml_add(entry, PCMK__XA_ST_CLIENTNAME, op->client_name);
                 crm_xml_add_ll(entry, PCMK__XA_ST_DATE, op->completed);
                 crm_xml_add_ll(entry, PCMK__XA_ST_DATE_NSEC,
                                op->completed_nsec);
                 crm_xml_add_int(entry, PCMK__XA_ST_STATE, op->state);
                 stonith__xe_set_result(entry, &op->result);
             }
     }
 
     if (remote_history) {
         init_stonith_remote_op_hash_table(&stonith_remote_op_list);
 
         updated |= g_hash_table_size(remote_history);
 
         g_hash_table_iter_init(&iter, remote_history);
         while (g_hash_table_iter_next(&iter, NULL, (void **)&op)) {
             if (stonith__op_state_pending(op->state) &&
                 pcmk__str_eq(op->originator, stonith_our_uname, pcmk__str_casei)) {
 
                 crm_warn("Failing pending operation %.8s originated by us but "
                          "known only from peer history", op->id);
                 op->state = st_failed;
                 set_fencing_completed(op);
 
                 /* CRM_EX_EXPIRED + PCMK_EXEC_INVALID prevents finalize_op()
                  * from setting a delegate
                  */
                 pcmk__set_result(&op->result, CRM_EX_EXPIRED, PCMK_EXEC_INVALID,
                                  "Initiated by earlier fencer "
                                  "process and presumed failed");
                 fenced_broadcast_op_result(op, false);
             }
 
             g_hash_table_iter_steal(&iter);
             g_hash_table_replace(stonith_remote_op_list, op->id, op);
             /* we could trim the history here but if we bail
              * out after trim we might miss more recent entries
              * of those that might still be in the list
              * if we don't bail out trimming once is more
              * efficient and memory overhead is minimal as
              * we are just moving pointers from one hash to
              * another
              */
         }
 
         g_hash_table_destroy(remote_history); /* remove what is left */
     }
 
     if (updated) {
         stonith_fence_history_trim();
         fenced_send_notification(T_STONITH_NOTIFY_HISTORY, NULL, NULL);
     }
 
     if (cnt == 0) {
         free_xml(history);
         return NULL;
     } else {
         return history;
     }
 }
 
 /*!
  * \internal
  * \brief Craft xml from the local fence-history
  *
  * \param[in] add_id            If crafting the answer for an API
  *                              history-request there is no need for the id
  * \param[in] target            Optionally limit to certain fence-target
  *
  * \return The fence-history as xml
  */
 static xmlNode *
 stonith_local_history(gboolean add_id, const char *target)
 {
     return stonith_local_history_diff_and_merge(NULL, add_id, target);
 }
 
 /*!
  * \internal
  * \brief Handle fence-history messages (from API or coming in as broadcasts)
  *
  * \param[in,out] msg          Request XML
  * \param[out]    output       Where to set local history, if requested
  * \param[in]     remote_peer  If broadcast, peer that sent it
  * \param[in]     options      Call options from the request
  */
 void
 stonith_fence_history(xmlNode *msg, xmlNode **output,
                       const char *remote_peer, int options)
 {
     const char *target = NULL;
     xmlNode *dev = get_xpath_object("//@" PCMK__XA_ST_TARGET, msg, LOG_NEVER);
     xmlNode *out_history = NULL;
 
     if (dev) {
         target = crm_element_value(dev, PCMK__XA_ST_TARGET);
         if (target && (options & st_opt_cs_nodeid)) {
             int nodeid;
             crm_node_t *node;
 
             pcmk__scan_min_int(target, &nodeid, 0);
             node = pcmk__search_node_caches(nodeid, NULL,
                                             pcmk__node_search_any
                                             |pcmk__node_search_known);
             if (node) {
                 target = node->uname;
             }
         }
     }
 
     if (options & st_opt_cleanup) {
         const char *call_id = crm_element_value(msg, PCMK__XA_ST_CALLID);
 
         crm_trace("Cleaning up operations on %s in %p", target,
                   stonith_remote_op_list);
         stonith_fence_history_cleanup(target, (call_id != NULL));
 
     } else if (options & st_opt_broadcast) {
         /* there is no clear sign atm for when a history sync
            is done so send a notification for anything
            that smells like history-sync
          */
         fenced_send_notification(T_STONITH_NOTIFY_HISTORY_SYNCED, NULL, NULL);
         if (crm_element_value(msg, PCMK__XA_ST_CALLID) != NULL) {
             /* this is coming from the stonith-API
             *
             * craft a broadcast with node's history
             * so that every node can merge and broadcast
             * what it has on top
             */
             out_history = stonith_local_history(TRUE, NULL);
             crm_trace("Broadcasting history to peers");
             stonith_send_broadcast_history(out_history,
                                         st_opt_broadcast | st_opt_discard_reply,
                                         NULL);
         } else if (remote_peer &&
                    !pcmk__str_eq(remote_peer, stonith_our_uname, pcmk__str_casei)) {
             xmlNode *history = get_xpath_object("//" PCMK__XE_ST_HISTORY, msg,
                                                 LOG_NEVER);
 
             /* either a broadcast created directly upon stonith-API request
             * or a diff as response to such a thing
             *
             * in both cases it may have a history or not
             * if we have differential data
             * merge in what we've received and stop
             * otherwise broadcast what we have on top
             * marking as differential and merge in afterwards
             */
-            if (!history || !pcmk__xe_attr_is_true(history, F_STONITH_DIFFERENTIAL)) {
+            if (!history
+                || !pcmk__xe_attr_is_true(history, PCMK__XA_ST_DIFFERENTIAL)) {
+
                 GHashTable *received_history = NULL;
 
                 if (history != NULL) {
                     received_history = stonith_xml_history_to_list(history);
                 }
                 out_history =
                     stonith_local_history_diff_and_merge(received_history, TRUE, NULL);
                 if (out_history) {
                     crm_trace("Broadcasting history-diff to peers");
-                    pcmk__xe_set_bool_attr(out_history, F_STONITH_DIFFERENTIAL, true);
+                    pcmk__xe_set_bool_attr(out_history,
+                                           PCMK__XA_ST_DIFFERENTIAL, true);
                     stonith_send_broadcast_history(out_history,
                         st_opt_broadcast | st_opt_discard_reply,
                         NULL);
                 } else {
                     crm_trace("History-diff is empty - skip broadcast");
                 }
             }
         } else {
             crm_trace("Skipping history-query-broadcast (%s%s)"
                       " we sent ourselves",
                       remote_peer?"remote-peer=":"local-ipc",
                       remote_peer?remote_peer:"");
         }
     } else {
         /* plain history request */
         crm_trace("Looking for operations on %s in %p", target,
                   stonith_remote_op_list);
         *output = stonith_local_history(FALSE, target);
     }
     free_xml(out_history);
 }
diff --git a/include/crm/common/xml_names_internal.h b/include/crm/common/xml_names_internal.h
index 5e25be570b..2f8fb152ff 100644
--- a/include/crm/common/xml_names_internal.h
+++ b/include/crm/common/xml_names_internal.h
@@ -1,247 +1,248 @@
 /*
  * Copyright 2004-2024 the Pacemaker project contributors
  *
  * The version control history for this file may have further details.
  *
  * This source code is licensed under the GNU Lesser General Public License
  * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
  */
 
 #ifndef PCMK__CRM_COMMON_XML_NAMES_INTERNAL__H
 #  define PCMK__CRM_COMMON_XML_NAMES_INTERNAL__H
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 /*
  * XML element names used only by internal code
  */
 
 #define PCMK__XE_ACK                    "ack"
 #define PCMK__XE_ATTRIBUTES             "attributes"
 #define PCMK__XE_CRM_EVENT              "crm_event"
 #define PCMK__XE_CRM_XML                "crm_xml"
 #define PCMK__XE_DIV                    "div"
 #define PCMK__XE_DOWNED                 "downed"
 #define PCMK__XE_FAILED                 "failed"
 #define PCMK__XE_FAILED_UPDATE          "failed_update"
 #define PCMK__XE_GENERATION_TUPLE       "generation_tuple"
 #define PCMK__XE_LRM                    "lrm"
 #define PCMK__XE_LRM_RESOURCE           "lrm_resource"
 #define PCMK__XE_LRM_RESOURCES          "lrm_resources"
 #define PCMK__XE_LRM_RSC_OP             "lrm_rsc_op"
 #define PCMK__XE_MAINTENANCE            "maintenance"
 #define PCMK__XE_META                   "meta"
 #define PCMK__XE_NACK                   "nack"
 #define PCMK__XE_NODE_STATE             "node_state"
 #define PCMK__XE_OPTIONS                "options"
 #define PCMK__XE_PARAM                  "param"
 #define PCMK__XE_PING                   "ping"
 #define PCMK__XE_PING_RESPONSE          "ping_response"
 #define PCMK__XE_PSEUDO_EVENT           "pseudo_event"
 #define PCMK__XE_RSC_OP                 "rsc_op"
 #define PCMK__XE_SHUTDOWN               "shutdown"
 #define PCMK__XE_SPAN                   "span"
 #define PCMK__XE_ST_HISTORY             "st_history"
 #define PCMK__XE_TICKET_STATE           "ticket_state"
 #define PCMK__XE_TRANSIENT_ATTRIBUTES   "transient_attributes"
 #define PCMK__XE_TRANSITION_GRAPH       "transition_graph"
 #define PCMK__XE_XPATH_QUERY            "xpath-query"
 #define PCMK__XE_XPATH_QUERY_PATH       "xpath-query-path"
 
 // @COMPAT Deprecated since 1.1.12
 #define PCMK__XE_ACL_USER               "acl_user"
 
 /* @COMPAT Deprecate somehow. It's undocumented and behaves the same as
  * PCMK__XE_CIB in places where it's recognized.
  */
 #define PCMK__XE_ALL                    "all"
 
 // @COMPAT Deprecated since 2.1.7
 #define PCMK__XE_DIFF_ADDED             "diff-added"
 
 // @COMPAT Deprecated since 2.1.7
 #define PCMK__XE_DIFF_REMOVED           "diff-removed"
 
 // @COMPAT Deprecated since 1.0.8 (commit 4cb100f)
 #define PCMK__XE_LIFETIME               "lifetime"
 
 /* @COMPAT Deprecated since 2.0.0; alias for <clone> with PCMK_META_PROMOTABLE
  * set to "true"
  */
 #define PCMK__XE_PROMOTABLE_LEGACY      "master"
 
 // @COMPAT Support for rkt is deprecated since 2.1.8
 #define PCMK__XE_RKT                    "rkt"
 
 // @COMPAT Deprecated since 1.1.12
 #define PCMK__XE_ROLE_REF               "role_ref"
 
 
 /*
  * XML attribute names used only by internal code
  */
 
 #define PCMK__XA_ATTR_CLEAR_INTERVAL    "attr_clear_interval"
 #define PCMK__XA_ATTR_CLEAR_OPERATION   "attr_clear_operation"
 #define PCMK__XA_ATTR_DAMPENING         "attr_dampening"
 #define PCMK__XA_ATTR_HOST              "attr_host"
 #define PCMK__XA_ATTR_HOST_ID           "attr_host_id"
 #define PCMK__XA_ATTR_IS_PRIVATE        "attr_is_private"
 #define PCMK__XA_ATTR_IS_REMOTE         "attr_is_remote"
 #define PCMK__XA_ATTR_KEY               "attr_key"
 #define PCMK__XA_ATTR_NAME              "attr_name"
 #define PCMK__XA_ATTR_REGEX             "attr_regex"
 #define PCMK__XA_ATTR_RESOURCE          "attr_resource"
 #define PCMK__XA_ATTR_SECTION           "attr_section"
 #define PCMK__XA_ATTR_SET               "attr_set"
 #define PCMK__XA_ATTR_SET_TYPE          "attr_set_type"
 #define PCMK__XA_ATTR_SYNC_POINT        "attr_sync_point"
 #define PCMK__XA_ATTR_USER              "attr_user"
 #define PCMK__XA_ATTR_VALUE             "attr_value"
 #define PCMK__XA_ATTR_VERSION           "attr_version"
 #define PCMK__XA_ATTR_WRITER            "attr_writer"
 #define PCMK__XA_ATTRD_IS_FORCE_WRITE   "attrd_is_force_write"
 #define PCMK__XA_CALL_ID                "call-id"
 #define PCMK__XA_CLIENT_NAME            "client_name"
 #define PCMK__XA_CLIENT_UUID            "client_uuid"
 #define PCMK__XA_CONFIG_ERRORS          "config-errors"
 #define PCMK__XA_CONFIG_WARNINGS        "config-warnings"
 #define PCMK__XA_CONFIRM                "confirm"
 #define PCMK__XA_CONNECTION_HOST        "connection_host"
 #define PCMK__XA_CONTENT                "content"
 #define PCMK__XA_CRMD_STATE             "crmd_state"
 #define PCMK__XA_CRM_HOST_TO            "crm_host_to"
 #define PCMK__XA_CRM_LIMIT_MAX          "crm-limit-max"
 #define PCMK__XA_CRM_LIMIT_MODE         "crm-limit-mode"
 #define PCMK__XA_CRM_SUBSYSTEM          "crm_subsystem"
 #define PCMK__XA_CRM_SYS_FROM           "crm_sys_from"
 #define PCMK__XA_CRM_SYS_TO             "crm_sys_to"
 #define PCMK__XA_CRM_TASK               "crm_task"
 #define PCMK__XA_CRM_TGRAPH_IN          "crm-tgraph-in"
 #define PCMK__XA_CRM_USER               "crm_user"
 #define PCMK__XA_DC_LEAVING             "dc-leaving"
 #define PCMK__XA_DIGEST                 "digest"
 #define PCMK__XA_ELECTION_AGE_SEC       "election-age-sec"
 #define PCMK__XA_ELECTION_AGE_NANO_SEC  "election-age-nano-sec"
 #define PCMK__XA_ELECTION_ID            "election-id"
 #define PCMK__XA_ELECTION_OWNER         "election-owner"
 #define PCMK__XA_GRANTED                "granted"
 #define PCMK__XA_GRAPH_ERRORS           "graph-errors"
 #define PCMK__XA_GRAPH_WARNINGS         "graph-warnings"
 #define PCMK__XA_HIDDEN                 "hidden"
 #define PCMK__XA_HTTP_EQUIV             "http-equiv"
 #define PCMK__XA_IN_CCM                 "in_ccm"
 #define PCMK__XA_JOIN                   "join"
 #define PCMK__XA_JOIN_ID                "join_id"
 #define PCMK__XA_LINE                   "line"
 #define PCMK__XA_LONG_ID                "long-id"
 #define PCMK__XA_MAJOR_VERSION          "major_version"
 #define PCMK__XA_MINOR_VERSION          "minor_version"
 #define PCMK__XA_MODE                   "mode"
 #define PCMK__XA_MOON                   "moon"
 #define PCMK__XA_NAMESPACE              "namespace"
 #define PCMK__XA_NODE_FENCED            "node_fenced"
 #define PCMK__XA_NODE_IN_MAINTENANCE    "node_in_maintenance"
 #define PCMK__XA_NODE_START_STATE       "node_start_state"
 #define PCMK__XA_NODE_STATE             "node_state"
 #define PCMK__XA_OP_DIGEST              "op-digest"
 #define PCMK__XA_OP_FORCE_RESTART       "op-force-restart"
 #define PCMK__XA_OP_RESTART_DIGEST      "op-restart-digest"
 #define PCMK__XA_OP_SECURE_DIGEST       "op-secure-digest"
 #define PCMK__XA_OP_SECURE_PARAMS       "op-secure-params"
 #define PCMK__XA_OP_STATUS              "op-status"
 #define PCMK__XA_OPERATION_KEY          "operation_key"
 #define PCMK__XA_PACEMAKERD_STATE       "pacemakerd_state"
 #define PCMK__XA_PASSWORD               "password"
 #define PCMK__XA_PRIORITY               "priority"
 #define PCMK__XA_RC_CODE                "rc-code"
 #define PCMK__XA_REAP                   "reap"
 
 /* Actions to be executed on Pacemaker Remote nodes are routed through the
  * controller on the cluster node hosting the remote connection. That cluster
  * node is considered the router node for the action.
  */
 #define PCMK__XA_ROUTER_NODE            "router_node"
 
 #define PCMK__XA_RSC_ID                 "rsc-id"
 #define PCMK__XA_RSC_PROVIDES           "rsc_provides"
 #define PCMK__XA_SCHEMA                 "schema"
 #define PCMK__XA_SCHEMAS                "schemas"
 #define PCMK__XA_SRC                    "src"
 #define PCMK__XA_ST_ACTION_DISALLOWED   "st_action_disallowed"
 #define PCMK__XA_ST_ACTION_TIMEOUT      "st_action_timeout"
 #define PCMK__XA_ST_AVAILABLE_DEVICES   "st-available-devices"
 #define PCMK__XA_ST_CALLID              "st_callid"
 #define PCMK__XA_ST_CALLDATA            "st_calldata"
 #define PCMK__XA_ST_CALLOPT             "st_callopt"
 #define PCMK__XA_ST_CLIENTID            "st_clientid"
 #define PCMK__XA_ST_CLIENTNAME          "st_clientname"
 #define PCMK__XA_ST_CLIENTNODE          "st_clientnode"
 #define PCMK__XA_ST_DATE                "st_date"
 #define PCMK__XA_ST_DATE_NSEC           "st_date_nsec"
 #define PCMK__XA_ST_DELAY               "st_delay"
 #define PCMK__XA_ST_DELAY_BASE          "st_delay_base"
 #define PCMK__XA_ST_DELAY_MAX           "st_delay_max"
 #define PCMK__XA_ST_DELEGATE            "st_delegate"
 #define PCMK__XA_ST_DEVICE_SUPPORT_FLAGS    "st_device_support_flags"
+#define PCMK__XA_ST_DIFFERENTIAL        "st_differential"
 #define PCMK__XA_ST_MONITOR_VERIFIED    "st_monitor_verified"
 #define PCMK__XA_ST_NOTIFY_ACTIVATE     "st_notify_activate"
 #define PCMK__XA_ST_NOTIFY_DEACTIVATE   "st_notify_deactivate"
 #define PCMK__XA_ST_OP                  "st_op"
 #define PCMK__XA_ST_ORIGIN              "st_origin"
 #define PCMK__XA_ST_OUTPUT              "st_output"
 #define PCMK__XA_ST_RC                  "st_rc"
 #define PCMK__XA_ST_REMOTE_OP           "st_remote_op"
 #define PCMK__XA_ST_REMOTE_OP_RELAY     "st_remote_op_relay"
 #define PCMK__XA_ST_REQUIRED            "st_required"
 #define PCMK__XA_ST_STATE               "st_state"
 #define PCMK__XA_ST_TARGET              "st_target"
 #define PCMK__XA_ST_TIMEOUT             "st_timeout"
 #define PCMK__XA_ST_TOLERANCE           "st_tolerance"
 #define PCMK__XA_SUBT                   "subt"                  // subtype
 #define PCMK__XA_T                      "t"                     // type
 #define PCMK__XA_TRANSITION_KEY         "transition-key"
 #define PCMK__XA_TRANSITION_MAGIC       "transition-magic"
 #define PCMK__XA_UPTIME                 "uptime"
 
 // @COMPAT Used only with v1 patchsets
 #define PCMK__XA_CRM_DIFF_MARKER        "__crm_diff_marker__"
 
 // @COMPAT Deprecated since 2.1.5
 #define PCMK__XA_FIRST_INSTANCE         "first-instance"
 
 // @COMPAT Deprecated since 2.1.7
 #define PCMK__XA_ORDERING               "ordering"
 
 // @COMPAT Deprecated alias for PCMK_XA_PROMOTED_MAX since 2.0.0
 #define PCMK__XA_PROMOTED_MAX_LEGACY    "masters"
 
 // @COMPAT Deprecated alias for PCMK_XA_PROMOTED_ONLY since 2.0.0
 #define PCMK__XA_PROMOTED_ONLY_LEGACY   "master_only"
 
 // @COMPAT Deprecated since 1.1.12
 #define PCMK__XA_REF                    "ref"
 
 // @COMPAT Deprecated since 2.1.6
 #define PCMK__XA_REPLACE                "replace"
 
 // @COMPAT Deprecated alias for \c PCMK_XA_AUTOMATIC since 1.1.14
 #define PCMK__XA_REQUIRED               "required"
 
 // @COMPAT Deprecated since 2.1.5
 #define PCMK__XA_RSC_INSTANCE           "rsc-instance"
 
 // @COMPAT Deprecated since 2.1.5
 #define PCMK__XA_THEN_INSTANCE          "then-instance"
 
 // @COMPAT Deprecated since 2.1.5
 #define PCMK__XA_WITH_RSC_INSTANCE      "with-rsc-instance"
 
 
 #ifdef __cplusplus
 }
 #endif
 
 #endif // PCMK__CRM_COMMON_XML_NAMES_INTERNAL__H
diff --git a/include/crm/fencing/internal.h b/include/crm/fencing/internal.h
index 6e7e5b70ac..429e7af79c 100644
--- a/include/crm/fencing/internal.h
+++ b/include/crm/fencing/internal.h
@@ -1,176 +1,174 @@
 /*
  * Copyright 2011-2024 the Pacemaker project contributors
  *
  * The version control history for this file may have further details.
  *
  * This source code is licensed under the GNU Lesser General Public License
  * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
  */
 
 #ifndef STONITH_NG_INTERNAL__H
 #  define STONITH_NG_INTERNAL__H
 
 #  include <glib.h>
 #  include <crm/common/ipc.h>
 #  include <crm/common/xml.h>
 #  include <crm/common/output_internal.h>
 #  include <crm/stonith-ng.h>
 
 enum st_device_flags {
     st_device_supports_none             = (0 << 0),
     st_device_supports_list             = (1 << 0),
     st_device_supports_status           = (1 << 1),
     st_device_supports_reboot           = (1 << 2),
     st_device_supports_parameter_plug   = (1 << 3),
     st_device_supports_parameter_port   = (1 << 4),
     st_device_supports_on               = (1 << 5),
 };
 
 #define stonith__set_device_flags(device_flags, device_id, flags_to_set) do { \
         device_flags = pcmk__set_flags_as(__func__, __LINE__, LOG_TRACE,      \
                                           "Fence device", device_id,          \
                                           (device_flags), (flags_to_set),     \
                                           #flags_to_set);                     \
     } while (0)
 
 #define stonith__set_call_options(st_call_opts, call_for, flags_to_set) do { \
         st_call_opts = pcmk__set_flags_as(__func__, __LINE__, LOG_TRACE,     \
                                           "Fencer call", (call_for),         \
                                           (st_call_opts), (flags_to_set),    \
                                           #flags_to_set);                    \
     } while (0)
 
 #define stonith__clear_call_options(st_call_opts, call_for, flags_to_clear) do { \
         st_call_opts = pcmk__clear_flags_as(__func__, __LINE__, LOG_TRACE,     \
                                             "Fencer call", (call_for),         \
                                             (st_call_opts), (flags_to_clear),  \
                                             #flags_to_clear);                  \
     } while (0)
 
 struct stonith_action_s;
 typedef struct stonith_action_s stonith_action_t;
 
 stonith_action_t *stonith__action_create(const char *agent,
                                          const char *action_name,
                                          const char *target,
                                          uint32_t target_nodeid,
                                          int timeout_sec,
                                          GHashTable *device_args,
                                          GHashTable *port_map,
                                          const char *host_arg);
 void stonith__destroy_action(stonith_action_t *action);
 pcmk__action_result_t *stonith__action_result(stonith_action_t *action);
 int stonith__result2rc(const pcmk__action_result_t *result);
 void stonith__xe_set_result(xmlNode *xml, const pcmk__action_result_t *result);
 void stonith__xe_get_result(const xmlNode *xml, pcmk__action_result_t *result);
 xmlNode *stonith__find_xe_with_result(xmlNode *xml);
 
 int stonith__execute_async(stonith_action_t *action, void *userdata,
                            void (*done) (int pid,
                                          const pcmk__action_result_t *result,
                                          void *user_data),
                            void (*fork_cb) (int pid, void *user_data));
 
 int stonith__metadata_async(const char *agent, int timeout_sec,
                             void (*callback)(int pid,
                                              const pcmk__action_result_t *result,
                                              void *user_data),
                             void *user_data);
 
 xmlNode *create_level_registration_xml(const char *node, const char *pattern,
                                        const char *attr, const char *value,
                                        int level,
                                        const stonith_key_value_t *device_list);
 
 xmlNode *create_device_registration_xml(const char *id,
                                         enum stonith_namespace namespace,
                                         const char *agent,
                                         const stonith_key_value_t *params,
                                         const char *rsc_provides);
 
 void stonith__register_messages(pcmk__output_t *out);
 
 GList *stonith__parse_targets(const char *hosts);
 
 const char *stonith__later_succeeded(const stonith_history_t *event,
                                      const stonith_history_t *top_history);
 stonith_history_t *stonith__sort_history(stonith_history_t *history);
 
 void stonith__device_parameter_flags(uint32_t *device_flags,
                                      const char *device_name,
                                      xmlNode *metadata);
 
 #  define ST_LEVEL_MAX 10
 
-#  define F_STONITH_DIFFERENTIAL  "st_differential"
-
 #  define F_STONITH_DEVICE        "st_device_id"
 #  define F_STONITH_ACTION        "st_device_action"
 #  define F_STONITH_MERGED        "st_op_merged"
 
 #  define T_STONITH_NG        "stonith-ng"
 #  define T_STONITH_REPLY     "st-reply"
 /*! For async operations, an event from the server containing
  * the total amount of time the server is allowing for the operation
  * to take place is returned to the client. */
 #  define T_STONITH_TIMEOUT_VALUE "st-async-timeout-value"
 #  define T_STONITH_NOTIFY    "st_notify"
 
 #  define STONITH_ATTR_ACTION_OP   "action"
 
 #  define STONITH_OP_EXEC        "st_execute"
 #  define STONITH_OP_TIMEOUT_UPDATE        "st_timeout_update"
 #  define STONITH_OP_QUERY       "st_query"
 #  define STONITH_OP_FENCE       "st_fence"
 #  define STONITH_OP_RELAY       "st_relay"
 #  define STONITH_OP_DEVICE_ADD      "st_device_register"
 #  define STONITH_OP_DEVICE_DEL      "st_device_remove"
 #  define STONITH_OP_FENCE_HISTORY   "st_fence_history"
 #  define STONITH_OP_LEVEL_ADD       "st_level_add"
 #  define STONITH_OP_LEVEL_DEL       "st_level_remove"
 
 #  define STONITH_WATCHDOG_AGENT          "fence_watchdog"
 /* Don't change 2 below as it would break rolling upgrade */
 #  define STONITH_WATCHDOG_AGENT_INTERNAL "#watchdog"
 #  define STONITH_WATCHDOG_ID             "watchdog"
 
 stonith_history_t *stonith__first_matching_event(stonith_history_t *history,
                                                  bool (*matching_fn)(stonith_history_t *, void *),
                                                  void *user_data);
 bool stonith__event_state_pending(stonith_history_t *history, void *user_data);
 bool stonith__event_state_eq(stonith_history_t *history, void *user_data);
 bool stonith__event_state_neq(stonith_history_t *history, void *user_data);
 
 int stonith__legacy2status(int rc);
 
 int stonith__exit_status(const stonith_callback_data_t *data);
 int stonith__execution_status(const stonith_callback_data_t *data);
 const char *stonith__exit_reason(const stonith_callback_data_t *data);
 
 int stonith__event_exit_status(const stonith_event_t *event);
 int stonith__event_execution_status(const stonith_event_t *event);
 const char *stonith__event_exit_reason(const stonith_event_t *event);
 char *stonith__event_description(const stonith_event_t *event);
 gchar *stonith__history_description(const stonith_history_t *event,
                                     bool full_history,
                                     const char *later_succeeded,
                                     uint32_t show_opts);
 
 /*!
  * \internal
  * \brief Is a fencing operation in pending state?
  *
  * \param[in] state     State as enum op_state value
  *
  * \return A boolean
  */
 static inline bool
 stonith__op_state_pending(enum op_state state)
 {
     return state != st_failed && state != st_done;
 }
 
 gboolean stonith__watchdog_fencing_enabled_for_node(const char *node);
 gboolean stonith__watchdog_fencing_enabled_for_node_api(stonith_t *st, const char *node);
 
 #endif