Repository navigation
writ command surface: layers, segments, adoption #463
Description
Epic: #447
How writ names what it deploys and takes ownership of what already exists: the layer tree, the segment
suffix grammar and its validation, and adoption of files a user already has.
Spec: 5.1-reconciliation.md
Design ruling (USER, 2026-09-06): layers overlay, and every manifest installs
Writ layers name the base, team, and personal repositories from which tools and configuration are drawn for a deployment. The layers overlay one another, and the deploy ensures that every package in every packages-manifest.yaml under each project's Home is installed — the manifests combine, they never shadow one another (#814).
With the repositories
| Layer | Repository |
|---|---|
| base | noblefactor-ops |
| team | devlore-cli |
| personal | personal |
writ deploy on Darwin overlays these Home directories, in this order (later wins for files; all contribute packages):
noblefactor-ops/Home/common{,.Unix,.Darwin}
devlore-cli/Home/common{,.Unix,.Darwin}
personal/Home/common{,.Unix,.Darwin}
and the same shape on every platform, with that platform's suffix chain.
Design ruling (USER, 2026-09-06): the implicit projects are common and one per configured layer repository
Other projects are brought in by naming them on the command line. With base = noblefactor-ops, team = devlore-cli, and personal = personal, the projects noblefactor-ops, devlore-cli, and personal are implicit as well: a Home/noblefactor-ops, Home/devlore-cli, or Home/personal directory in any layer's Home is included by a bare writ deploy, with its suffix chain, exactly as common is. So if personal/Home/devlore-cli and personal/Home/noblefactor-ops exist, a bare writ deploy brings them in — the personal layer's overrides for working with those repositories. A project named for nothing configured, noblefamily, must be named: writ deploy noblefamily overlays it on top of all of the above.
Design rulings (USER, 2026-09-06): deploy adds and the store remembers; decommission subtracts, by name or --all
writ deployis additive with persistence. A barewrit deployconverges the implicit set (commonand the repository-named projects) plus every project this machine has already selected.writ deploy noblefamilyadds noblefamily to the selection and converges. The selection is remembered — the reading to confirm is that the store already is the record: a project is selected while it has entries in the store. No--only; the extra complexity is skipped.writ decommission <project>...subtracts by name, as it does today, and after removal it re-converges the remaining set so a target the removed project overlaid reverts to the next layer's version rather than vanishing. It is persistent: the project's store entries go, so it is no longer selected, and the nextdeployorupgradedoes not bring it back.- Implicit projects are not decommissionable by name; the refusal points at
writ repo unset <layer>, the verb that retires what a layer contributes. writ decommission --alldecommissions everything writ deployed. The bare form stays refused. No--from <layer>clause: a per-layer exclusion would be a fourth kind of persistent state the repositories do not record; remove the files from the repository, or unset the layer.writ upgradeselects exactly as deploy does, so after a decommission it regenerates nothing of the removed project.
Activity