Skip to content

writ self install creates empty layers/base and layers/team, which repo list reads as registrations and repo add refuses #840

Open

Description

@David-Noble-at-work

writ self install creates empty directories layers/base and layers/team under the writ data
home. writ repo list reads any entry under layers/ as a registration, and writ repo add refuses
a layer that "is already registered" — so a fresh install manufactures two fake registrations that
block the two real ones.

Observed, 2026-09-05

$ make install                      # lore, star, writ self install ~/.local
$ ls -la ~/.local/share/devlore/writ/layers
drwxr-x---  Sep 5  base            <- empty, created by self install
lrwxr-xr-x  Aug 9  personal -> …/writ/repos/personal
drwxr-x---  Sep 5  team            <- empty, created by self install
$ writ repo list
base     -> …/writ/layers/base    <- a plain empty directory, listed as registered
$ writ repo add base ~/Workspace/NobleFactor/noblefactor-ops
Error: layer base is already registered; run 'writ repo remove base' first

The same two placeholders existed dated Aug 31 from an earlier install, which is why base and
team looked "registered but empty" for a week.

Why it matters

The design (repo_cmd.go): "a layer is a symlink under the layers directory, never a config key."
A directory there is not a registration under that definition, and nothing should create one. The
first-run experience is: install, try to register your base layer, be told it already is.

Fix

Either of:

  • self install stops creating layers/<name> placeholders — the layers directory itself is all
    that needs to exist; or
  • repo list and repo add treat a non-symlink entry under layers/ as unregistered (and list
    says why), so a stray directory cannot block a real registration.

The first is the real fix; the second is defence in depth and worth having anyway.

Related

#791 (repo set replaces add/remove: re-pointing is one command) would make the workaround one
step instead of two, but the placeholder should not exist in the first place.


Epic: #447


Feature: #463

Activity

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

    @David-Noble-at-work
    ContributorAuthor

    Measured 2026-09-07 by the layer-journey scenario (#855, step 0.2) against build 155067ae in a pristine sandbox: writ self install <home>/.local --shell bash leaves three placeholders under XDG_DATA_HOME/devlore/writ/layers/ — base, personal and team — not the two this issue names. The scenario skips step 0.2 by this issue's number until a fresh install registers nothing; that step is your acceptance test.

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

    @David-Noble-at-work
    ContributorAuthor

    Confirmed on a fresh Linux machine, 2026-09-13, with one detail this issue does not record: repo add clones
    before it refuses.

    danoble-ud24-1.local, linux/arm64, no devlore presence of any kind beforehand. After writ self install:

    $ ls -la ~/.local/share/devlore/writ/layers/
    drwxr-x--- 2 david-noble david-noble 4096 Sep 13 19:07 base
    drwxr-x--- 2 david-noble david-noble 4096 Sep 13 19:07 personal
    drwxr-x--- 2 david-noble david-noble 4096 Sep 13 19:07 team
    
    $ writ repo list --output table
    LAYER     ROOT                                                         STATE
    base      /home/david-noble/.local/share/devlore/writ/layers/base      registered
    team      /home/david-noble/.local/share/devlore/writ/layers/team      registered
    personal  /home/david-noble/.local/share/devlore/writ/layers/personal  registered
    

    Three phantom registrations whose root is the registration directory itself. Then:

    $ writ repo add base [email protected]:NobleFactor/noblefactor-ops.git
    Cloning into '/home/david-noble/.local/share/devlore/writ/repos/base'...
    Error: layer base is already registered; run 'writ repo remove base' first
    

    The clone completes and the registration is then refused. The machine is left with a full clone at
    repos/base that nothing points at, which is #792's orphan arriving by a second route. The refusal happens
    after the expensive, network-bound, side-effecting half rather than before it.

    So a fresh install cannot register a layer until the user removes three registrations they never made, and one
    attempt to do so leaves a repository behind. The state that now exists on that machine is the evidence.

    (The state and root columns above are writ repo list's new result form, from
    #794; the behaviour they report is unchanged.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Epic:WritDeploymentwrit deployment: layers, adoption, and driftThread:WritSelfInstalla fresh machine installs writ and can use itbugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions