Skip to content

BUG-083: #982 tightened the folder allow-list without a migration, so any dotf built from main refuses the already-deployed registry #992

Description

@mlorentedev

What

#982 renamed the ratified Bitwarden folder taxonomy from Dotfiles/apps / Dotfiles/infra to apps / infra, updating both secrets/registry.yaml and validBWFolders, the parser's allow-list. Both halves are correct. What is missing is that the deployed copy of the registry is a separate artifact with its own lifecycle (ADR-030): ~/.dotfiles/secrets/registry.yaml is refreshed by setup-linux.sh, not by merging a PR.

So a binary built from current main rejects the registry that is currently deployed on every machine:

$ cd ~/.dotfiles && dotf secrets ls
Error: secret "GITHUB_PERSONAL_ACCESS_TOKEN": bw.folder "Dotfiles/apps" is not in the ratified taxonomy (apps, infra)
$ grep -o 'folder: [A-Za-z/]*' ~/.dotfiles/secrets/registry.yaml | sort | uniq -c
     21 folder: Dotfiles/apps
      5 folder: Dotfiles/infra

Not currently broken, and that is the trap

The installed binary is 0.40.0, which predates #982, so today everything works. The failure is armed, not firing: it lands the moment anyone installs a build from main — the next release, or a scripts/install-dotf.sh run — and it lands on every machine simultaneously, before any of them has re-run setup.

Blast radius when it fires: ParseRegistry is the entry point for the whole dotf secrets surface, so ls, run, show, verify, render and two dotf doctor sections all fail at once. Reproduced here with a main-based build:

[Secrets integrity]
  [FAIL] secrets/registry.yaml not found or invalid

Note the message says "not found or invalid" for what is actually a validation failure on a file that is present and readable — so the first person to hit this will go looking for a missing file.

Why the guard did not catch it

The pattern is the dormant-value one this repo already has a lesson about, inverted: OPS-028 learned to validate bw.folder at write time rather than at activation time. This is the same field failing the other way — a value that was valid when written and was invalidated later by a change to the validator, in an artifact the validator's PR did not and could not update.

dotf doctor's deploy-drift check knows the deployed copy can lag the checkout; nothing checks that the lagging copy is still parseable by the current binary.

Options

  1. Accept both spellings for a deprecation windowvalidBWFolders takes the old values too, WARNing on them, removed after a release. Cheapest, and it makes the change survivable in any install order.
  2. Make the deploy a precondition of the parse tightening — ship the registry change, require setup, then tighten. Correct but needs coordination the release process does not currently have.
  3. Have dotf doctor --fix redeploy the registry when the deployed copy fails to parse but the checkout's parses. Fixes this instance and the next one of the same shape.

Recommend 1 now (it is what makes the already-merged change safe), plus 3 as the durable guard.

Acceptance criteria

  • A binary built from main parses the currently-deployed registry, or a documented, enforced ordering makes that impossible to hit.
  • ParseRegistry's failure is reported as a validation error naming the file and the rule, never as "not found or invalid".
  • A check fails when the deployed registry cannot be parsed by the running binary — the drift that is invisible until every secret command breaks at once.

Evidence

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingops

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions