MergeConflict.java
package org.hammer.audio.workflow.history;
import java.util.Objects;
/**
* Sealed hierarchy of domain-level merge conflicts.
*
* <p>Each variant describes a specific type of conflict that arises when two independently evolving
* workflow branches are reconciled. Conflicts are reported as model-level domain objects, not as
* text-diff hunks.
*
* <p>Owned by the semantic-analysis/history-projection layer. Must not contain UI, JGit or
* execution dependencies.
*
* @see MergeConflictReport
*/
public sealed interface MergeConflict
permits MergeConflict.DeleteVsModify, MergeConflict.ConnectVsParameterChange {
/**
* One branch deleted a node while the other branch modified it (e.g. renamed or updated a
* parameter).
*
* <p>This conflict cannot be auto-resolved because discarding the modification would silently
* lose intent; keeping the node would ignore the deletion intent.
*
* @param nodeId stable identifier of the conflicting node
*/
record DeleteVsModify(String nodeId) implements MergeConflict {
public DeleteVsModify {
Objects.requireNonNull(nodeId, "nodeId");
}
}
/**
* One branch connected two ports (adding an edge) while the other branch changed a parameter on
* one of the involved nodes.
*
* <p>The new edge may be invalid after the parameter change, so the conflict must be reviewed by
* a human author.
*
* @param edgeId stable identifier of the newly added edge that may be invalid
* @param nodeId stable identifier of the node whose parameter was changed on the other branch
*/
record ConnectVsParameterChange(String edgeId, String nodeId) implements MergeConflict {
public ConnectVsParameterChange {
Objects.requireNonNull(edgeId, "edgeId");
Objects.requireNonNull(nodeId, "nodeId");
}
}
}