Skip to content

The writ design record states the layer overlay, the implicit common project, the suffix chain, and the manifest union in one place #849

Open

Description

@David-Noble-at-work

Feature: #463 — writ command surface: layers, segments, adoption. Filed 2026-09-06 to carry the design ruling
recorded on #463 the same day into the record.

What is true today, and where it is written

  • Layer precedence (base → team → personal, later wins for a file at the same target): docs/guides/writ/repositories.md.
  • The implicit common project (deploys everywhere without being named; never decommissioned implicitly):
    docs/guides/writ/platform-awareness.md, repositories.md, and the completed plan docs/plans/implicit-common-project.md.
  • The suffix chain (.Unix is the family of Darwin and Linux; common, common.Unix, common.Darwin all
    deploy on macOS, more specific winning for files): platform-awareness.md; cmd/writ/writ/segment.
  • Manifests combine across layers and across the chain: nowhere. packages-manifest.yaml files collide like deployed files: the most specific one shadows the rest, so a layer's general packages are never planned #814 records the ruling; today the tree builder
    collides them like files.

No architecture document under docs/architecture covers writ's layer model at all; the three guides carry it.

Correction 2026-09-06: an earlier note here and on the Windows test claimed the base repository, noblefactor-ops, has no Home directory. It does: Home/common is on its develop as of today. The claim came from a stale clone and is withdrawn; the base layer contributes.

The task

  1. One design document, docs/architecture/<n>-writ-layers.md (numbered into the series), states the four rules
    above together with the user's worked example: base = noblefactor-ops, team = devlore-cli, personal = personal;
    writ deploy on Darwin overlays <repo>/Home/common{,.Unix,.Darwin} for each layer in order, and installs every
    package every one of those manifests names. The same shape on every platform.
  2. The three guides point at it and agree with it; docs/guides/writ/packages-manifest.md states the union rule beside
    the format.
  3. 4-resource-management.md or the deploy design, whichever owns the tree builder, records that manifests are not
    files: they land nowhere and therefore never collide.

Acceptance

  • the design document exists and the three guides link to it
  • the manifest guide states the union rule
  • Test-GuideFrontmatter and the doc lint pass

Related

#814 (the union), #819 (a layer whose HEAD has nothing under Home/), #821 (the team layer's project directory became
common, per this model), #796/#818/#820 (the manifests).

Activity

  1. David-Noble-at-work commented on Sep 7, 2026

    @David-Noble-at-work
    ContributorAuthor

    For the guide pass, the layout rule as the user stated it on 2026-09-07 (noblefactor-ops#147, personal#172), verbatim:

    • If I have code that takes a dependency on or contributes to some repo stack (e.g., noblefactor-ops), I put that code into a directory named Home/noblefactor-ops.
    • If not, I put it elsewhere. If I want what I have to be deployed unconditionally wherever I go, I put it into common.

    With #850's implicit selection that is also a deploy guard: personal/Home/noblefactor-ops.Darwin deploys only when a layer named noblefactor-ops is registered, so a script that sources the base's Declare-BashScript cannot land on a machine without it.

    Three places in the guides still use noblefactor as the example project name, which under this rule reads as a repository that does not exist:

    • docs/guides/writ/platform-awareness.md:55-57 — noblefactor.Unix/, noblefactor.Windows/
    • docs/guides/writ/repositories.md:94 — noblefactor.Unix/; :102 — Home/noblefactor/.config/git/config
    • docs/architecture/7-registry-knowledge.md:171 — Home/Configs/noblefactor.Unix (the pre-writ layout; historical)

    noblefactor-ops.Unix and Home/noblefactor-ops/... are the names the rule produces. personal#172 renames the real directories the same day.

  2. David-Noble-at-work commented on Sep 8, 2026

    @David-Noble-at-work
    ContributorAuthor

    One more rule for the design record's suffix-chain section, ruled 2026-09-07 and filed as #860: on Linux the chain follows the lineage os-release states in ID_LIKE, most general first, then the host's own ID — Unix → Linux → Debian → Ubuntu, Unix → Linux → Fedora → RHEL. "What deploys to Debian deploys to Ubuntu." Today segment/detect.go reads ID alone; the layer-journey scenario (#855) measured common.Debian absent on ubuntu-latest and now asserts the lineage, skipping by #860.

  3. David-Noble-at-work commented on Sep 26, 2026

    @David-Noble-at-work
    ContributorAuthor

    The implicit-set rule is now stated where the writ design lives today, landed with lane 10 of #916 (#850): the
    deploy row of docs/architecture/10-command-line-interface.md §3.1, and docs/guides/writ/repositories.md,
    platform-awareness.md and manage-environments.md. This issue's single-place record still stands to be written.

  4. David-Noble-at-work commented on Sep 30, 2026

    @David-Noble-at-work
    ContributorAuthor

    #944 settled the selector half of this record on 2026-09-30. It landed as #992, merged as e440151a, and also resolved #369 and #970. #860, cited above, was merged into #944 on 2026-09-28. docs/guides/selectors.md is now the one statement of the selector rules for both writ and lore. Ruled 2026-09-30: "we want one location with references from two locations: lore and writ" (docs/plans/feature/944-one-selector-api-writ-and-lore.md:328-330, Q15). What it settles:

    • The grammar: [<project>][.<os>][.<arch>][.<extra>...], in that order, with each part at most once. The OS part is one word, so common.Debian is the form and common.Linux.Debian is an error. Extras are declared in writ.segments, each with every value it may take (selectors.md:16-35, :90-123).

    • The chain: Unix → Linux → <ID_LIKE reversed> → <ID>, from os-release. On Ubuntu, Unix, Linux, Debian and Ubuntu apply. On Darwin the chain is Unix → Darwin (selectors.md:37-66; pkg/selector/host.go:61-106). The chain is built in pkg/selector. cmd/writ/writ/segment now calls it (segment/detect.go:27) and no longer builds it.

    • A closed vocabulary, and grammar errors refuse the run. A name that is out of order, has two words for one part, or holds a word no part knows refuses the run before anything changes. common.Debain is a misspelling. common.Nixos is refused on any machine but NixOS while the spelling table lacks NixOS; on NixOS itself it applies. The refusal lists every such name in every layer (selectors.md:155-168; pkg/selector/selector.go:115-148, :411-424; cmd/writ/writ/tree/builder.go:302-337). A well-formed name for another machine, such as common.Fedora on Ubuntu, is excluded without an error.

    • One total order of application, and the last applied wins (selectors.md:125-153; pkg/selector/selector.go:358-383):

      1. Projects in command-line order. The implicit projects come first (common, then one per layer repository), then the recorded projects that aren't named, then the named projects, left to right (cmd/writ/writ/selection.go:67-102).
      2. Within a project, the OS word's depth in the chain decides first, then the architecture, then each extra in its configured order.
      3. Layers are the outermost key. writ orders each layer's directories by 1 and 2, then applies base, then team, then personal, so every directory in a later layer is applied after every directory in an earlier one (cmd/writ/writ/layer.go:18; tree/builder.go:176-179, :208-219).

      This issue's "more specific winning for files" is now what the code does. At ea5cebd2, when two names had the same number of suffixes, the one os.ReadDir listed last won, so on macOS common.Unix beat common.Darwin (plan :61-64).

    • Naming an implicit project is a command-line error, including writ deploy common. The bare form is writ deploy (cmd/writ/writ/selection.go:73-75). Naming the same project twice is also refused (:76-78). This replaces The implicit projects are common and one per configured layer repository; a repository-named project in any layer deploys unnamed #850's 2026-09-26 ruling on the bare form (plan :369-376, Q27).

    • Manifests contribute in the same order. They still combine and never collide (packages-manifest.yaml files collide like deployed files: the most specific one shadows the rest, so a layer's general packages are never planned #814; tree/builder.go:89-94).

    What the design record should reference. It links docs/guides/selectors.md for the grammar, the chain, the vocabulary, the grammar errors and the order of application, and doesn't restate them. From docs/architecture/ the link is ../guides/selectors.md, the form 2.4-hermeticity-guarantees.md:139 and 2.5-lifecycle-pipeline-construction.md:46 already use. The selectors guide says nothing about manifests or decommissioning, so the record still states these itself:

    • the three layers
    • the implicit set, and that it is never decommissioned implicitly
    • the manifest union
    • the worked example

    writ's guides already link the selectors guide: platform-awareness.md:18-19, repositories.md:124 and manage-environments.md:42.

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 drifttaskImplementation work item

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions