diff --git a/devTools/types/FC/RA.d.ts b/devTools/types/FC/RA.d.ts
index 5c9869eebf40ce0f04076567ab027654debce32d..a7dbfbbdaf7ea25173b7eec3cf496466a3aaa078 100644
--- a/devTools/types/FC/RA.d.ts
+++ b/devTools/types/FC/RA.d.ts
@@ -16,6 +16,7 @@ declare namespace FC {
 			assignment: Assignment[];
 			selectedSlaves: number[];
 			excludedSlaves: number[];
+			applyRuleOnce: boolean;
 		}
 
 		interface RuleSurgerySettings {
diff --git a/js/003-data/gameVariableData.js b/js/003-data/gameVariableData.js
index 99506112fb311cc155888ffd65b41485ff1775c9..a632beba1a2f64dcc587ad48aadc0761125d3447 100644
--- a/js/003-data/gameVariableData.js
+++ b/js/003-data/gameVariableData.js
@@ -474,6 +474,7 @@ App.Data.resetOnNGPlus = {
 	enduringDevotion: 0,
 	/** @type {FC.RA.Rule[]} */
 	defaultRules: [],
+	rulesToApplyOnce: {},
 
 	REFeminizationCheckinIDs: [],
 	REMILFCheckinIDs: [],
diff --git a/src/data/backwardsCompatibility/backwardsCompatibility.js b/src/data/backwardsCompatibility/backwardsCompatibility.js
index 461923d668c58af6a30986941a4ef21236d0c47e..05ac47febd792f9464cbeaf66a72c8d5f824867f 100644
--- a/src/data/backwardsCompatibility/backwardsCompatibility.js
+++ b/src/data/backwardsCompatibility/backwardsCompatibility.js
@@ -1525,7 +1525,22 @@ App.Update.genePoolRecords = function(node) {
 };
 
 App.Update.RAassistantData = function(node) {
+	const ruleIDs = V.defaultRules.map(rule => rule.ID);
+	const slaveIDs = V.slaves.map(slave => slave.ID);
 	V.defaultRules = V.defaultRules.map(rule => App.Entity.Utils.RARuleDatatypeCleanup(rule));
+
+	for (const ruleID of Object.keys(V.rulesToApplyOnce)) {
+		if (!ruleIDs.includes(ruleID)) {
+			delete V.rulesToApplyOnce[ruleID];
+		} else {
+			for (const slaveID of V.rulesToApplyOnce[ruleID]) {
+				if (!slaveIDs.includes(slaveID)) {
+					V.rulesToApplyOnce[ruleID].delete(slaveID);
+				}
+			}
+		}
+	}
+
 	node.append(`Done!`);
 };
 
diff --git a/src/interaction/siRules.js b/src/interaction/siRules.js
index bf16d17c1e88f97ce39dd2f074a9510d9a9c4dc4..0a2a8e381634687f4330d665bde0e4d9826be815 100644
--- a/src/interaction/siRules.js
+++ b/src/interaction/siRules.js
@@ -90,6 +90,16 @@ App.UI.SlaveInteract.rules = function(slave) {
 				}
 			)
 		);
+		array.push(
+			App.UI.DOM.link(
+				`Apply all rules to ${him} again`,
+				() => {
+					removeFromRulesToApplyOnce(slave);
+					DefaultRules(slave);
+					refresh();
+				}
+			)
+		);
 		array.push(App.UI.DOM.passageLink("Rules Assistant Options", "Rules Assistant"));
 	}
 	p.append(App.UI.DOM.generateLinksStrip(array));
diff --git a/src/js/DefaultRules.js b/src/js/DefaultRules.js
index 6b17e48aab38a9fed4b457a585b3f2ae27739a11..e39da3fd2d9e3ccf91745298596da8587d047603 100644
--- a/src/js/DefaultRules.js
+++ b/src/js/DefaultRules.js
@@ -109,7 +109,7 @@ globalThis.DefaultRules = (function() {
 	function ProcessSlaveRules(slave) {
 		// merge all rules applying on a slave into one big rule
 		/** @type {FC.RA.Rule[]} */
-		const rules = V.defaultRules.filter((x) => ruleAppliesP(x.condition, slave));
+		const rules = V.defaultRules.filter((rule) => ruleAppliesP(rule, slave));
 		const ruleIds = [], assignments = [];
 		for (const rule of rules) {
 			ruleIds.push(rule.ID);
@@ -3046,3 +3046,11 @@ globalThis.DefaultRules = (function() {
 	globalThis.DefaultRulesError = () => V.defaultRules.some(r => RuleHasError(r));
 	return DefaultRules;
 })();
+
+globalThis.removeFromRulesToApplyOnce = function(slave) {
+    for (const rule of Object.keys(V.rulesToApplyOnce)) {
+        if (V.rulesToApplyOnce[rule].includes(slave.ID)) {
+            V.rulesToApplyOnce[rule].delete(slave.ID);
+        }
+    }
+};
\ No newline at end of file
diff --git a/src/js/assayJS.js b/src/js/assayJS.js
index ed35411dddaece5c2dd9db63ebaeaf28f925880f..5764907752a870d7ef55d19af92fe9b64c94b477 100644
--- a/src/js/assayJS.js
+++ b/src/js/assayJS.js
@@ -1673,4 +1673,5 @@ globalThis.initRules = function() {
 	rule.set.removalAssignment = "rest";
 
 	V.defaultRules = [rule];
+	V.rulesToApplyOnce = {};
 };
diff --git a/src/js/removeSlave.js b/src/js/removeSlave.js
index f5db93e4917e0e0f4b50a31196cbf204ae0dfeea..57cadb798d59a47d16cd46689c47519fd40a557e 100644
--- a/src/js/removeSlave.js
+++ b/src/js/removeSlave.js
@@ -242,6 +242,9 @@ globalThis.removeSlave = function(slave) {
 			delete V.assignmentRecords[AS_ID];
 		}
 
+		// remove slaves from V.rulesToApplyOnce if needed
+		removeFromRulesToApplyOnce(slave);
+
 		V.slaves.deleteAt(INDEX);
 		V.slaveIndices = slaves2indices();
 		LENGTH--;
diff --git a/src/js/rulesAssistant.js b/src/js/rulesAssistant.js
index febf9cf4b3a3ef1fa5b7f260acd0f6d01261e361..fcde2c4ddc2e2ec9988d8b79fa5985f89961a0fc 100644
--- a/src/js/rulesAssistant.js
+++ b/src/js/rulesAssistant.js
@@ -102,13 +102,31 @@ globalThis.RAFacilityRemove = function(slave, rule) {
 
 /**
  * return whether the rule applies to the slave
- * @param {FC.RA.RuleConditions} cond
+ * @param {FC.RA.Rule} rule
  * @param {App.Entity.SlaveState} slave
  * @returns {boolean} flag */
-globalThis.ruleAppliesP = function(cond, slave) {
+globalThis.ruleAppliesP = function(rule, slave) {
 	let flag = true;
+	let V = State.variables;
+	let cond = rule.condition;
 	let slaveAttribute = slave[cond.data.attribute];
 
+	// Check if slave should be excluded from having rule applied to again
+	if (cond.applyRuleOnce) {
+		if (!V.rulesToApplyOnce[rule.ID]) {
+			V.rulesToApplyOnce[rule.ID] = [];
+		}
+		if (V.rulesToApplyOnce[rule.ID].includes(slave.ID)) {
+			return false;
+		} else {
+			V.rulesToApplyOnce[rule.ID].push(slave.ID);
+		}
+	} else {
+		if (V.rulesToApplyOnce[rule.ID]) {
+			delete V.rulesToApplyOnce[rule.ID];
+		}
+	}
+
 	// attribute / function check
 	switch (cond.function) {
 		case false: // never applies
@@ -178,6 +196,7 @@ App.RA.newRule = function() {
 			assignment: [],
 			selectedSlaves: [],
 			excludedSlaves: [],
+			applyRuleOnce: false,
 		};
 	}
 	/** @returns {FC.RA.RuleSetters} */
diff --git a/src/js/rulesAssistantOptions.js b/src/js/rulesAssistantOptions.js
index fb79af53893405046e7f6e9a19bdd552c4ebe623..2c7c384dc4edcb5a5facb2f9d71ef6ee463a4e1a 100644
--- a/src/js/rulesAssistantOptions.js
+++ b/src/js/rulesAssistantOptions.js
@@ -39,6 +39,9 @@ globalThis.rulesAssistantOptions = (function() {
 
 	function removeRule() {
 		const idx = V.defaultRules.findIndex(rule => rule.ID === current_rule.ID);
+		if (V.rulesToApplyOnce[V.defaultRules[idx].ID] !== "undefined") {
+			delete V.rulesToApplyOnce[V.defaultRules[idx].ID];
+		}
 		V.defaultRules.splice(idx, 1);
 		if (V.defaultRules.length > 0) {
 			const new_idx = idx < V.defaultRules.length ? idx : V.defaultRules.length - 1;
@@ -1157,6 +1160,7 @@ globalThis.rulesAssistantOptions = (function() {
 			this.appendChild(new AssignmentInclusion());
 			this.appendChild(new FacilityHeadAssignmentInclusion());
 			this.appendChild(new SpecificInclusionExclusion());
+			this.appendChild(new ApplyRuleOnce());
 		}
 	}
 
@@ -1548,6 +1552,20 @@ globalThis.rulesAssistantOptions = (function() {
 		}
 	}
 
+	class ApplyRuleOnce extends ButtonItem {
+		constructor() {
+			super("Do not apply rule (and overwrite manual changes) every time rule is executed, but only once per slave", false, (current_rule.condition.applyRuleOnce === true));
+		}
+
+		onchange() {
+			if (!current_rule.condition.applyRuleOnce) {
+				current_rule.condition.applyRuleOnce = true;
+			} else {
+				current_rule.condition.applyRuleOnce = false;
+			}
+		}
+	}
+
 	// parent section for effect editing
 	class EffectEditor extends Element {
 		constructor() {