Repository navigation
writ deploy pins each layer by a private ref and links into a sparse snapshot of every scope directory #971
Description
Epic: #466 · Feature: #847 Kept snapshots · Schedule: #916, lane 17, PR D · Waits on: #846 (lane 16)
Ruled 2026-09-27 and 2026-09-28 on #847 (plan): a deployment lifetime keeps the snapshot each layer was planned from, and links target it.
What deploy does
- Pins each layer by a private ref under
refs/devlore/(ruled over tags: never pushed by--tags, never pruned byfetch --prune-tags, invisible togit taganddescribe). - Keeps a sparse snapshot of the pinned commit as a locked worktree: every scope directory --
Home,Systemand, on Windows,ProgramFiles,ProgramDataand whateverwrit.scopesadds (--scope, multi-valued and writ-only, replaces the inert --target: absent means every scope defined on this platform; Home and System are well known, Windows adds ProgramFiles and ProgramData, and writ.scopes adds the rest #926). One snapshot per layer per run, in the state home (A pinned snapshot worktree survived its run: cleanup is not reached on every path, and the cache is the wrong home if snapshots are ever kept #846). - Links target the snapshot, not the working tree, for every layer: live is retired (ruled 2026-09-28: "i don't want personal to be live"). Where a clone lives and who owns it changes nothing.
- Snapshots are writable; what reconcile does with an edit is lanes 18 and 5.
- The record names each layer's commit and its snapshot, so the deployed commit per layer is structural. Closes Record the deployed commit for each layer source #473.
Absorbs #960
Agreed 2026-09-28 with the session that held #960 as its schedule #949's lane 15: deploy loses a removed source precisely because it replaces the lifetime, so deploy's handling of the replaced lifetime's links is designed here, once, against snapshots. When a deploy replaces a lifetime, every link the replaced lifetime made that the new one does not is removed and narrated, never left serving the old commit, and never dropped from the record silently. personal#236 (26 dangling links on DANOBLE-UD24-1) waits on this lane; the links can be removed by hand meanwhile.
Invariant
The maintainer owns every merge: writ never merges, commits to, moves or pushes any branch except its own retain/* branches. In a clone writ writes only refs under refs/devlore/, branches under retain/, and locked worktree registrations, and removes its own -- an exception to #792, ruled 2026-09-28. Stated in docs/architecture/5.1-reconciliation.md.
Acceptance
- a deploy leaves one locked, sparse snapshot per layer in the state home, pinned by a
refs/devlore/ref, and every link resolves into it -
git statusin each clone is unchanged by a deploy; onlyrefs/devlore/refs and locked worktree entries are added - a pull or an uncommitted edit in a clone does not change the deployment
- the scope directories of the platform, and only those, are checked out in each snapshot
- a deploy that replaces a lifetime removes and narrates the replaced lifetime's links the new one does not make (writ deploy leaves the links of removed sources dangling and drops them from the record: reconcile then reports a clean machine #960)
- both VMs
Activity
doc(writ): kept snapshots complete -- the words against the ref, live…
doc(writ): kept snapshots -- reconcile against the ref that produced …
David-Noble-at-work commentedon Oct 2, 2026
Amended by the owner's ruling of 2026-10-02, lifetimes are generations: writ follows git and Nix. It is stated in
docs/architecture/5.1-reconciliation.md§ Lifetimes are generations, recorded on #916, and its finding is open question 5 of lane 7's plan,docs/plans/task/926-scope-flag.md(#926). The lane's plan takes this up when the schedule reaches it.Deploy pins per run: each scope's run records, for each layer, the commit it deployed from, and links into the snapshot of that layer at that commit -- one per layer and commit, holding the scopes deployed from it. A deploy without
--scopestill puts every scope of a layer at one commit. When deploy replaces a scope, it removes what the replaced runs held and the new ones do not, if still as recorded, and keeps and reports what was changed: home-manager's cleanup, which is #960's question.