You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
writ upgrade does its whole job: links added, orphans removed, stale links relinked, copies regenerated -- what the name promises #845
writ upgrade promises what its name means in every package manager: bring the installed state to the
current version — new files placed, files the new version no longer ships removed, nothing left
dangling from the old one. Today it regenerates copied files (templates, secrets) and its help says
"Symlinks are not affected" as if that were a feature. A user who upgraded and then found last
month's links still pointing at files that moved would be right to feel misled.
writ reconcile can already say what is wrong — linked, missing, conflict, absent, stale, orphan, modified — and nothing acts on what it says. deploy only adds; upgrade only regenerates
copies; decommission removes a whole project.
Observed, 2026-09-06
A layer's file was
after writ deploy again
on disk
added
linked
correct
removed
not planned, so untouched
the old link stays, dangling
moved
new path linked
old link dangles beside the new one
The three ~/.Personal-secrets/*.yaml links were this case for weeks: sources moved from noblefactor.Unix to common, deploy linked the new source, and the old dangling links survived
until a --conflict=replace run happened to overwrite them because the targets coincided. Had the
targets differed, they would still be there. deploy has no stale, orphan or prune handling of any
kind.
The feature: upgrade does its whole job
For the projects given (all, when none), bring the deployed state to the layers' current state:
missing (a source with no link): link it — what deploy does, now also what upgrade does.
orphan (a link writ made whose source left the layer): unlink. Refuse if the target is no
longer writ's own — a real file, a link pointing elsewhere — the way decommission refuses.
stale (a link pointing at a source that moved): relink, when the readback can prove it is the
same file (recorded identity, The catalog travels with the graph #581's catalog).
copied (templates, secrets): regenerate — today's behaviour, unchanged, with --force for
modified copies as now.
modified (a copied file the user changed): leave it, say so.
reconcile stays the report; upgrade is the verb that acts on it. No --apply flag on a report
command, no new converge verb — the verb already exists, and this is what it means. It pins and
records origin like deploy (#844), narrates every action per target (#842), and writes a graph and
trace like every run. The help text loses "Symlinks are not affected."
Why this is the epic's first feature
Epic:Reconciliation (#450) has no features; the report reads it as awaiting plan and design.
Drift detection without convergence is a dashboard; this is the feature that makes it a tool. It
depends on origin being surfaced (#473, Thread:WritOrigin beat 3) to say which layer's file is
orphaned, and on #471 to say it per source.
Not this feature
Cross-layer shadowing decisions (#470): when two sources provide one path, which wins is a tree
question, not a convergence question.
changed the title [-]Reconcile converges: orphaned links are removed, stale links relinked, missing links made -- the delta between a layer and the disk gets a verb[/-][+]writ upgrade does its whole job: links added, orphans removed, stale links relinked, copies regenerated -- what the name promises[/+]on Sep 6, 2026
Observed 2026-09-07 on Danoble-MBP-A after David-Noble-at-work/personal#174 moved 139 files from Home/common*/local/ into Home/noblefactor-ops.*/.local/ and renamed two projects.
Between the merge (the working tree the links point into moved) and the redeploy, 183 links dangled, including ~/.local/bin/Declare-BashScript and every git-* command — the tooling a PR script needs to close a branch.
writ deploy --allow-dirty --conflict=replace common noblefactor-ops relinked 269 targets and left the 121 old links under ~/local/bin and ~/local/share in place; find … -type l ! -exec test -e {} \; -delete removed them by hand.
After that, writ reconcile reports linked: 269, copied: 1, missing: 110: the store still carries the entries for the old targets, which are now gone, so a move looks like 110 losses until something forgets them.
Three halves of the job this issue names, seen in one afternoon: relink what moved, remove what it orphaned, and drop the store entries the removal leaves behind. The last is the one not yet in the issue text.
Revised 2026-09-28 by the kept-snapshots rulings (#847, ruling 5): upgrade moves a layer's links to its new snapshot along with its copies (lane 11, #928), but does not add links for files new to the commit or remove those gone from it: those are deploy's, since deploy replaces the record. Deploy's handling of a replaced lifetime's links is #971 (lane 17), which absorbs #960. This feature's promise of "links added, orphans removed" by upgrade is superseded accordingly.
Activity
[-]Reconcile converges: orphaned links are removed, stale links relinked, missing links made -- the delta between a layer and the disk gets a verb[/-][+]writ upgrade does its whole job: links added, orphans removed, stale links relinked, copies regenerated -- what the name promises[/+]David-Noble-at-work commentedon Sep 7, 2026
Observed 2026-09-07 on Danoble-MBP-A after David-Noble-at-work/personal#174 moved 139 files from
Home/common*/local/intoHome/noblefactor-ops.*/.local/and renamed two projects.~/.local/bin/Declare-BashScriptand everygit-*command — the tooling a PR script needs to close a branch.writ deploy --allow-dirty --conflict=replace common noblefactor-opsrelinked 269 targets and left the 121 old links under~/local/binand~/local/sharein place;find … -type l ! -exec test -e {} \; -deleteremoved them by hand.writ reconcilereportslinked: 269, copied: 1, missing: 110: the store still carries the entries for the old targets, which are now gone, so a move looks like 110 losses until something forgets them.Three halves of the job this issue names, seen in one afternoon: relink what moved, remove what it orphaned, and drop the store entries the removal leaves behind. The last is the one not yet in the issue text.
test(writ): the layer-journey scenario -- self install, repo set, dep…
David-Noble-at-work commentedon Sep 28, 2026
Revised 2026-09-28 by the kept-snapshots rulings (#847, ruling 5): upgrade moves a layer's links to its new snapshot along with its copies (lane 11, #928), but does not add links for files new to the commit or remove those gone from it: those are deploy's, since deploy replaces the record. Deploy's handling of a replaced lifetime's links is #971 (lane 17), which absorbs #960. This feature's promise of "links added, orphans removed" by upgrade is superseded accordingly.