diff --git a/core/src/main/java/ai/timefold/solver/core/api/domain/variable/AnchorShadowVariable.java b/core/src/main/java/ai/timefold/solver/core/api/domain/variable/AnchorShadowVariable.java
index b234ee9bc2..dc7fa89c3f 100644
--- a/core/src/main/java/ai/timefold/solver/core/api/domain/variable/AnchorShadowVariable.java
+++ b/core/src/main/java/ai/timefold/solver/core/api/domain/variable/AnchorShadowVariable.java
@@ -15,7 +15,10 @@
* variable.
*
* It is specified on a getter of a java bean property (or a field) of a {@link PlanningEntity} class.
+ *
+ * @deprecated Chained variable is deprecated. Use {@link PlanningListVariable list variable} instead.
*/
+@Deprecated(forRemoval = true, since = "1.31.0")
@Target({ METHOD, FIELD })
@Retention(RUNTIME)
public @interface AnchorShadowVariable {
diff --git a/core/src/main/java/ai/timefold/solver/core/api/domain/variable/PlanningVariable.java b/core/src/main/java/ai/timefold/solver/core/api/domain/variable/PlanningVariable.java
index 7f9967fd22..e3ad09bfde 100644
--- a/core/src/main/java/ai/timefold/solver/core/api/domain/variable/PlanningVariable.java
+++ b/core/src/main/java/ai/timefold/solver/core/api/domain/variable/PlanningVariable.java
@@ -56,7 +56,9 @@
* as specified by {@link PlanningVariableGraphType}.
*
* @return never null, defaults to {@link PlanningVariableGraphType#NONE}
+ * @deprecated Chained variable is deprecated. Use {@link PlanningListVariable list variable} instead.
*/
+ @Deprecated(forRemoval = true, since = "1.31.0")
PlanningVariableGraphType graphType() default PlanningVariableGraphType.NONE;
/**
diff --git a/core/src/main/java/ai/timefold/solver/core/api/domain/variable/PlanningVariableGraphType.java b/core/src/main/java/ai/timefold/solver/core/api/domain/variable/PlanningVariableGraphType.java
index 0d64354d70..f5b301989b 100644
--- a/core/src/main/java/ai/timefold/solver/core/api/domain/variable/PlanningVariableGraphType.java
+++ b/core/src/main/java/ai/timefold/solver/core/api/domain/variable/PlanningVariableGraphType.java
@@ -1,5 +1,9 @@
package ai.timefold.solver.core.api.domain.variable;
+/**
+ * @deprecated Chained variable is deprecated. Use {@link PlanningListVariable list variable} instead.
+ */
+@Deprecated(forRemoval = true, since = "1.31.0")
public enum PlanningVariableGraphType {
/**
* This is the default.
diff --git a/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/generic/chained/KOptMoveSelectorConfig.java b/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/generic/chained/KOptMoveSelectorConfig.java
index 299737dd40..62e1f060a3 100644
--- a/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/generic/chained/KOptMoveSelectorConfig.java
+++ b/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/generic/chained/KOptMoveSelectorConfig.java
@@ -5,6 +5,7 @@
import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlType;
+import ai.timefold.solver.core.api.domain.variable.PlanningListVariable;
import ai.timefold.solver.core.config.heuristic.selector.entity.EntitySelectorConfig;
import ai.timefold.solver.core.config.heuristic.selector.move.MoveSelectorConfig;
import ai.timefold.solver.core.config.heuristic.selector.value.ValueSelectorConfig;
@@ -17,11 +18,12 @@
* THIS CLASS IS EXPERIMENTAL AND UNSUPPORTED.
* Backward compatibility is not guaranteed.
* It's NOT DOCUMENTED because we'll only document it when it actually works in more than 1 use case.
- *
* Do not use.
*
* @see TailChainSwapMoveSelectorConfig
+ * @deprecated Chained variable is deprecated. Use {@link PlanningListVariable list variable} instead.
*/
+@Deprecated(forRemoval = true, since = "1.31.0")
@XmlType(propOrder = {
"entitySelectorConfig",
"valueSelectorConfig"
diff --git a/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/generic/chained/SubChainChangeMoveSelectorConfig.java b/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/generic/chained/SubChainChangeMoveSelectorConfig.java
index 7aebe9b97c..95382caef4 100644
--- a/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/generic/chained/SubChainChangeMoveSelectorConfig.java
+++ b/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/generic/chained/SubChainChangeMoveSelectorConfig.java
@@ -5,6 +5,7 @@
import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlType;
+import ai.timefold.solver.core.api.domain.variable.PlanningListVariable;
import ai.timefold.solver.core.config.heuristic.selector.move.MoveSelectorConfig;
import ai.timefold.solver.core.config.heuristic.selector.value.ValueSelectorConfig;
import ai.timefold.solver.core.config.heuristic.selector.value.chained.SubChainSelectorConfig;
@@ -13,6 +14,10 @@
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;
+/**
+ * @deprecated Chained variable is deprecated. Use {@link PlanningListVariable list variable} instead.
+ */
+@Deprecated(forRemoval = true, since = "1.31.0")
@XmlType(propOrder = {
"entityClass",
"subChainSelectorConfig",
diff --git a/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/generic/chained/SubChainSwapMoveSelectorConfig.java b/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/generic/chained/SubChainSwapMoveSelectorConfig.java
index 61011385fc..bbda8d09fc 100644
--- a/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/generic/chained/SubChainSwapMoveSelectorConfig.java
+++ b/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/generic/chained/SubChainSwapMoveSelectorConfig.java
@@ -5,6 +5,7 @@
import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlType;
+import ai.timefold.solver.core.api.domain.variable.PlanningListVariable;
import ai.timefold.solver.core.config.heuristic.selector.move.MoveSelectorConfig;
import ai.timefold.solver.core.config.heuristic.selector.value.chained.SubChainSelectorConfig;
import ai.timefold.solver.core.config.util.ConfigUtils;
@@ -12,6 +13,10 @@
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;
+/**
+ * @deprecated Chained variable is deprecated. Use {@link PlanningListVariable list variable} instead.
+ */
+@Deprecated(forRemoval = true, since = "1.31.0")
@XmlType(propOrder = {
"entityClass",
"subChainSelectorConfig",
diff --git a/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/generic/chained/TailChainSwapMoveSelectorConfig.java b/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/generic/chained/TailChainSwapMoveSelectorConfig.java
index a0c71dd100..ce248bc8d9 100644
--- a/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/generic/chained/TailChainSwapMoveSelectorConfig.java
+++ b/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/generic/chained/TailChainSwapMoveSelectorConfig.java
@@ -6,6 +6,7 @@
import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlType;
+import ai.timefold.solver.core.api.domain.variable.PlanningListVariable;
import ai.timefold.solver.core.config.heuristic.selector.entity.EntitySelectorConfig;
import ai.timefold.solver.core.config.heuristic.selector.move.MoveSelectorConfig;
import ai.timefold.solver.core.config.heuristic.selector.move.NearbyAutoConfigurationEnabled;
@@ -19,7 +20,10 @@
/**
* Also known as a 2-opt move selector config.
+ *
+ * @deprecated Chained variable is deprecated. Use {@link PlanningListVariable list variable} instead.
*/
+@Deprecated(forRemoval = true, since = "1.31.0")
@XmlType(propOrder = {
"entitySelectorConfig",
"valueSelectorConfig"
diff --git a/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/generic/chained/package-info.java b/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/generic/chained/package-info.java
index 783d2f2d44..91835b3d68 100644
--- a/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/generic/chained/package-info.java
+++ b/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/generic/chained/package-info.java
@@ -1,3 +1,8 @@
+/**
+ * @deprecated Chained variable is deprecated. Use {@link ai.timefold.solver.core.api.domain.variable.PlanningListVariable list
+ * variable} instead.
+ */
+@Deprecated(forRemoval = true, since = "1.31.0")
@XmlSchema(
namespace = SolverConfig.XML_NAMESPACE,
elementFormDefault = XmlNsForm.QUALIFIED)
diff --git a/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/chained/ChainedChangeMove.java b/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/chained/ChainedChangeMove.java
index fa09859033..1bd4e61a2c 100644
--- a/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/chained/ChainedChangeMove.java
+++ b/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/chained/ChainedChangeMove.java
@@ -3,6 +3,7 @@
import java.util.Objects;
import ai.timefold.solver.core.api.domain.solution.PlanningSolution;
+import ai.timefold.solver.core.api.domain.variable.PlanningListVariable;
import ai.timefold.solver.core.api.score.director.ScoreDirector;
import ai.timefold.solver.core.impl.domain.variable.descriptor.GenuineVariableDescriptor;
import ai.timefold.solver.core.impl.domain.variable.inverserelation.SingletonInverseVariableSupply;
@@ -11,7 +12,9 @@
/**
* @param the solution type, the class with the {@link PlanningSolution} annotation
+ * @deprecated Chained variable is deprecated. Use {@link PlanningListVariable list variable} instead.
*/
+@Deprecated(forRemoval = true, since = "1.31.0")
public class ChainedChangeMove extends ChangeMove {
protected final Object oldTrailingEntity;
diff --git a/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/chained/ChainedSwapMove.java b/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/chained/ChainedSwapMove.java
index 0861da6c46..f53c85ec06 100644
--- a/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/chained/ChainedSwapMove.java
+++ b/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/chained/ChainedSwapMove.java
@@ -5,6 +5,7 @@
import java.util.Objects;
import ai.timefold.solver.core.api.domain.solution.PlanningSolution;
+import ai.timefold.solver.core.api.domain.variable.PlanningListVariable;
import ai.timefold.solver.core.api.score.director.ScoreDirector;
import ai.timefold.solver.core.impl.domain.variable.descriptor.BasicVariableDescriptor;
import ai.timefold.solver.core.impl.domain.variable.descriptor.GenuineVariableDescriptor;
@@ -14,7 +15,9 @@
/**
* @param the solution type, the class with the {@link PlanningSolution} annotation
+ * @deprecated Chained variable is deprecated. Use {@link PlanningListVariable list variable} instead.
*/
+@Deprecated(forRemoval = true, since = "1.31.0")
public class ChainedSwapMove extends SwapMove {
protected final List