Repository navigation
writ repo remove leaves the clone it made in the writ-owned home #792
Description
Feature: #463 — writ command surface: layers, segments, adoption.
writ repo add <layer> <repository-url> clones into the writ-owned home, XDG_DATA_HOME/devlore/writ/repos/<layer>.
writ repo remove <layer> drops the registration and leaves that clone behind. The next add of the same
layer from a URL then finds the directory occupied, and the user is cleaning up writ’s own state by hand.
Ruled 2026-09-04: a clone writ made in its own home is writ’s to remove. Unregistering a layer removes
the registration and the writ-owned clone, and says so. A working tree the user registered by path — theirs,
anywhere else on disk — is never touched; the registration alone goes. The same distinction governs set
replacing a registration (#791): the displaced writ-owned clone is removed, a displaced user path is left
alone.
The verbs become set and unset in #791; this fix rides on whichever spelling lands first. Both are lanes of
#887 (schedule) — #791 is lane 8, this is lane 9.
The record, ruled 2026-09-18
Ownership is not narration: it reaches stdout as a field, so a script and a --dry-run can both read it. The
shape is #791’s, and unset emits:
{
"layer": "personal",
"state": "unregistered",
"previous": {
"source": "[email protected]:me/personal.git",
"root": "/Users/me/.local/share/devlore/writ/repos/personal",
"owner": "writ"
}
}previous.owner is the whole ruling: writ means the tree at previous.root was removed with the
registration, user means only the registration went. There is no separate removed field — writ clones only
into <data home>/devlore/writ/repos/<name>, so a removed clone is always previous.root.
--dry-run emits the same record and does nothing, which is how a caller learns what would go.
Acceptance
- unsetting a layer registered from a URL removes
XDG_DATA_HOME/devlore/writ/repos/<layer>and narrates it - unsetting a layer registered by path removes the registration only, asserted
- the record carries
previous.rootandprevious.owner, and--dry-runemits it without removing anything - the guide
docs/guides/writ/repositories.mdsays which clones writ owns and removes
Activity
test(writ): the layer-journey scenario -- self install, repo set, dep…
David-Noble-at-work commentedon Sep 14, 2026
A second route to the same orphan, observed 2026-09-13 on
danoble-ud24-1.local.This issue records the clone left behind by
repo remove. The same orphan arrives without anyremoveat all,because
repo addclones before it validates:The clone is complete and unreferenced; the registration never happened. On that machine it was
#840's phantom registration that triggered the refusal,
but any refusal after the clone does the same thing.
Whichever spelling lands,
setoradd, the validation belongs before the network operation: a registrationthat will be refused should be refused before anything is written to disk. That is the cheaper half of the same
ruling this issue already makes about ownership of a writ-owned clone.
The end-to-end record says what actually ran
A document rendering, a terminal one, the renderings grouped, and pag…
doc(writ): the maintainer owns every merge; upgrade moves links; writ…
doc(writ): kept snapshots -- reconcile against the ref that produced …