OrphanEntry.java
package network.ike.plugin.scaffold;
import java.nio.file.Path;
import java.util.Objects;
/**
* A scaffold file recorded in {@code .ike/scaffold.lock} whose
* {@code dest} the current manifest no longer ships — the file was
* installed by a {@code scaffold-publish} run under a scaffold
* strategy that has since been retired.
*
* <p>{@link ScaffoldPlanner} only iterates manifest entries, so a
* lockfile entry with no manifest counterpart would otherwise stay on
* disk and in the lockfile forever. {@link OrphanScanner} finds these;
* {@code ike:scaffold-draft} reports them and {@code ike:scaffold-publish}
* removes them.
*
* @param dest the lockfile/manifest {@code dest} string
* @param resolvedDest absolute on-disk path the {@code dest} expands to
* @param tier the ownership tier recorded in the lockfile
* @param disposition what {@code scaffold-publish} will do with it
* @param reason human-readable detail for draft/publish output
*/
public record OrphanEntry(
String dest,
Path resolvedDest,
ScaffoldTier tier,
Disposition disposition,
String reason) {
/** Canonical constructor with null guards. */
public OrphanEntry {
Objects.requireNonNull(dest, "dest");
Objects.requireNonNull(resolvedDest, "resolvedDest");
Objects.requireNonNull(tier, "tier");
Objects.requireNonNull(disposition, "disposition");
Objects.requireNonNull(reason, "reason");
}
/** What {@code scaffold-publish} will do with an orphan. */
public enum Disposition {
/**
* On-disk content still matches the lockfile hash — publish
* deletes the file and drops the lockfile entry.
*/
REMOVE,
/**
* File diverged from the lockfile hash, or its tier is shared
* ({@code tracked-block}) or user-owned ({@code model-managed}).
* Publish leaves the file untouched and keeps the lockfile
* entry so the orphan keeps surfacing until resolved.
*/
SKIP_USER_EDITED,
/**
* File is already gone — publish just drops the stale lockfile
* entry.
*/
ALREADY_ABSENT
}
}