feat(adopt): consented user-scope migration plus rollback fidelity - #105
Merged
Conversation
Adopt refuses to convert a repo whose foreign channel comes from a machine-wide (user-scope) enable, and the refusal had no answer in the tool: the operator had to hand-edit settings in every repo that depended on that enable, with nothing checking the result. 'sideshow adopt <pack> --migrate-user-scope' is the consented path out. It pins the foreign channel in each swept repo that DEPENDS on the machine-wide enable, removes the machine-wide entry, then verifies against disk, per repo, that removing it changed nothing. A repo enabled independently gets no write; a repo that suppresses the identity gets no write. Any mismatch, or a factory run in flight in any swept repo, rolls the whole migration back. The sweep set is disclosed rather than guessed: adoption target, sideshow ledger repos, harness-recorded project-scope installs, plus --also-repo and --sweep-root. The plan states the limit plainly, because sideshow cannot enumerate every repo on a machine. Per-repo enables land in settings.local.json by default; project scope also requires --commit-consent. Also fixes a rollback defect this shape exposes. A repo already carrying a per-repo enable has a true in the very key adopt's suppression overwrites, and rollback deleted the key rather than restoring the value, switching the foreign channel off in a repo nobody converted. The regression test was verified failing against the prior code. The created-file removal path now calls the preserve floor. Two smaller pieces: adopt --finish decides the marketplace question from the install registry instead of deferring it to the operator, and the dry-run write validator creates nothing, not even the parent directory a real write would make. Refs: aae-orc-d3nq.22
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A consumer whose vsdd-factory plugin is enabled machine-wide currently cannot adopt any repo: adopt refuses the user-scope enable (correctly, since converting one repo would leave every other repo on the machine in the posture the containment mandate grades an error), and the refusal pointed at hand-editing settings files with nothing checking the result. This closes the last gap in the conversion toolkit for that consumer, and fixes a rollback defect that shape exposes.
What changed
sideshow adopt <pack> --migrate-user-scopemoves the machine-wide enable to per-repo enables:The sweep set is disclosed rather than guessed: adoption target, sideshow ledger repos, harness-recorded project-scope installs, plus
--also-repo <path>and--sweep-root <dir>. The plan prints the limit plainly, because sideshow cannot enumerate every repo on a machine and only the operator can finish that list. Consent is--yesafter a printed plan, never an unanswered prompt (sideshow#94). Per-repo enables land insettings.local.json;--scope projectwrites the tracked file and also requires--commit-consent.Rollback fix. A repo already carrying a per-repo enable has a
truein the very key adopt's suppression overwrites, and rollback deleted the key instead of restoring the value, switching the foreign channel off in a repo nobody converted. That shape predates this branch (any hand-written local enable had it) and the migration produces it by design, so it is fixed here. The created-file removal path now also calls the preserve floor.Two smaller pieces:
adopt --finishdecides the marketplace-removal question from the install registry ("serves only vsdd-factory, so removal is safe" with the command, or "KEEP" naming what else it serves) instead of deferring it, and the dry-run write validator creates nothing, not even the parent directory a real write would make.The executing half of
--finish(uninstall per scope, cache purge, marketplace removal) stays print-only: it is gated behindaae-orc-d3nq.20, and no removal path for a store version exists yet.Tests
go test ./...green,golangci-lint run ./...reports 0 issues, gofmt clean. Test functions 270 to 289; cases including subtests 329 to 365.The rollback regression test was verified failing against the pre-fix code (
repo not restored after rollback: [.claude/settings.local.json],prior local enable not restored: map[]) before the fix landed. The dry-run test caught a real bug during development: the write validator was creating.claude/directories, so a dry run wrote. Coverage includes the pin/no-pin decision across all four repo shapes, adopt succeeding on the target after migration, dry run writing nothing anywhere, four refusals (no machine-wide enable, project scope without commit consent, bad scope, factory lock in a swept repo that is not the target), the unwritable-settings prediction, project-scope pinning, the undo log, the sweep-root scanner, and the marketplace verdict both ways.Cost of merge
Additive. The one behavior change to an existing path is the rollback restoring a prior enable instead of deleting it, which is strictly closer to "repo exactly as found."