GoalBehavior.java
package network.ike.plugin.ws;
/**
* A goal's declared working-tree contract: how it treats an uncommitted tree
* on entry ({@link TreePreflight}) and how it commits the changes it authors
* ({@link AuthoredCommit}). Declared per {@link WsGoal} constant so the policy
* is compiler-visible and test-enforced rather than decided ad hoc per mojo
* (IKE-Network/ike-issues#780).
*
* <p>The named constants are the taxonomy clusters; a goal that does not fit a
* cluster constructs its own pair.
*
* <p><b>Status:</b> these declarations are the <em>locked target contract</em>
* from #780. Runtime enforcement is being brought up to them goal-by-goal —
* some goals (the #780 "laggards": {@code scaffold-publish}, {@code align-publish},
* {@code stignore}, {@code add}, {@code remove}, …) do not yet honor their
* declared behavior at runtime. The exhaustiveness test asserts every goal
* declares a behavior and the structural invariants; the per-goal
* declared-equals-observed enforcement lands with the migration slice.
*
* @param treePreflight the entry precondition on the working tree
* @param authoredCommit how the goal commits what it writes
*/
public record GoalBehavior(TreePreflight treePreflight,
AuthoredCommit authoredCommit) {
/**
* Pure read-only goals: {@code graph}, {@code overview}, {@code report},
* {@code release-status}, {@code help}, {@code lint}, {@code check-branch},
* {@code verify-convergence}, and the {@code commit-draft} preview (which
* must run against uncommitted changes). No preflight, nothing authored.
*/
public static final GoalBehavior READ_ONLY =
new GoalBehavior(TreePreflight.IGNORE, AuthoredCommit.NONE);
/**
* The {@code *-draft} preview goals: warn on an uncommitted tree but do
* not block; they write a {@code .gitignore}'d {@code .md} report and
* author no tracked commit.
*/
public static final GoalBehavior DRAFT =
new GoalBehavior(TreePreflight.WARN, AuthoredCommit.NONE);
/**
* Coordinating structural mutations ({@code scaffold-publish},
* {@code align-publish}, {@code stignore}, {@code checkpoint-publish},
* {@code feature-start*}/{@code feature-finish*}/{@code feature-abandon-publish},
* {@code post-release}, {@code update-feature-publish}, {@code add},
* {@code remove}, {@code reconcile-branches-publish}): require an
* unmodified tree (escapable with {@code -Dallow-uncommitted}) and commit
* authored changes in isolation.
*/
public static final GoalBehavior COORDINATING =
new GoalBehavior(TreePreflight.REQUIRE_UNMODIFIED,
AuthoredCommit.IN_ISOLATION);
/** The commit goal itself ({@code ws:commit-publish}). */
public static final GoalBehavior COMMIT =
new GoalBehavior(TreePreflight.IGNORE, AuthoredCommit.IS_THE_COMMIT);
/**
* VCS-state sync goals ({@code pull}, {@code sync}, {@code push},
* {@code refresh-main}, {@code cleanup-publish}, {@code scaffold-init}):
* uncommitted input is expected — they auto-stash in-flight WIP where
* needed rather than refuse — and they author no tracked commit.
*/
public static final GoalBehavior SYNC =
new GoalBehavior(TreePreflight.IGNORE, AuthoredCommit.NONE);
/**
* No clean-tree preflight, but commits its own changes in isolation:
* {@code release-publish} (honors interrupted-release roll-forward) and
* {@code switch-publish} (auto-stashes WIP, commits the manifest switch).
*/
public static final GoalBehavior NO_PREFLIGHT_COMMIT =
new GoalBehavior(TreePreflight.IGNORE, AuthoredCommit.IN_ISOLATION);
}