Skip to content

writ command surface: layers, segments, adoption #463

Open

Description

@David-Noble-at-work

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 deploy is additive with persistence. A bare writ deploy converges the implicit set (common and the repository-named projects) plus every project this machine has already selected. writ deploy noblefamily adds 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 next deploy or upgrade does 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 --all decommissions 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 upgrade selects exactly as deploy does, so after a decommission it regenerates nothing of the removed project.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Epic:WritDeploymentwrit deployment: layers, adoption, and driftfeatureDeliverable unit within an epic

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions