Skip to content

feat(file): move takes any kind; move_directory retires - #636

Merged
David-Noble-at-work merged 1 commit into
developfrom
move-unifies
Aug 24, 2026
Merged

David-Noble-at-work merged 1 commit into
developfrom
move-unifies

Conversation

@David-Noble-at-work

Copy link
Copy Markdown
Contributor

Phase 4 of any-entry-claims.md. Closes #620. Feature: #616.

A symbolic link can be moved again — the capability that regressed when kind-honest activation landed
(#611), and the reason this feature exists.

file.move(source, destination_path) takes the taxonomy interface, so an authored path claims as
file.Any and resolves to whatever the disk holds. The two typed fronts and the shared moveEntry core
collapse into one method; file.move_directory is removed; writ migrate's layer registration reverts to
plain file.move; Backup delegates without a policy argument.

on_missing is gone from move. Moving something that is gone accomplishes nothing, and a tolerated
miss returned a nil product — handing downstream consumers a nil promise, the pathology that had Skip
dropped from MissingResourcePolicy (#605). The claim is required, so the verdict lands at pre-flight.

Two findings the acceptance scenarios earned

The collision arrived early, in immediate mode. file.copy interns a product as *Regular; a later
file.move on the same rel mints an Any claim, and internEntry's type assertion refused it. The
ruled semantics were never in doubt — one identity, the kinded entry keeps the slot — but a constructor
promising *Any would have to fail in exactly the case the rule says should succeed. So DiscoverAny
returns the taxonomy interface
, the one constructor that does and deliberately. The generator learned a
matching, narrow fallback: every constructor in the tree returns *T, so a non-pointer return is the
interface case, and the announced type comes from the constructor's name (Discover<T>) — a convention
every provider already follows.

file.Any was not enrolled in pre-flight's staged verification gate, so its claims were skipped
entirely and a missing source was rediscovered mid-run by the mover's own I/O rather than failing at the
starting line. Caught by the missing-source scenario, which is exactly what an acceptance pin is for.

Also: immediate mode needed the designation too — it bypasses the planner and converts directly, so
Convert's registered-construction step consults the same registry. One designation, both seams.

Scenarios

test_judgment_move_any_kind.star moves all three kinds in one graph, with the sharp assertion on the
link: the link moves, its target does not — a follow would be unmistakable, since the target would
vanish from its original path. test_judgment_move_missing_source.star pins the verdict's location —
the catalog's "verify existence" at pre-flight, not a rename failure at dispatch.

Gate: make test 103 ok / 0 fail; make vet clean under darwin, windows, and linux; gofmt -l clean.

@David-Noble-at-work David-Noble-at-work self-assigned this Aug 24, 2026
@David-Noble-at-work
David-Noble-at-work merged commit 1908a34 into develop Aug 24, 2026
8 checks passed
@David-Noble-at-work
David-Noble-at-work deleted the move-unifies branch August 24, 2026 04:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

file.move unifies: any kind, no policy, move_directory retires

1 participant