Repository navigation
feat(repository): switch a repository between shared and private visibility - #404
Merged
danielhanold merged 20 commits intoOct 7, 2026
Conversation
…emove managed ignore blocks
…cklink is not the canonical relative link
…, and remove a remote
…or reuse The integration-test helper that computed the expected private layout is renamed to expectedPrivateLayout so the production privateLayoutOf can take its name; no assertion changed.
… runs, dirty metadata, and unset repositories
…o a local bare remote
…y to origin and restores the shared layout
…r every phase, private result, commit messages
…e config, the convention, and command help
…en going shared Review finding (blocker): going shared with cursor in agent_harnesses wedged on every run. sharedCommitPhase journaled every planned surface, including .cursor/rules/docket-dispatch.mdc, which the managed .gitignore block written by the earlier ignore phase ignores; CommitOwnPaths' `git add --intent-to-add` then refused the ignored path, and the surviving journal made every re-run fail the same way. The phase now journals only surfaces git status reports as changed and drops every other surface (unchanged, or ignored by the shared layout) from the journal, so an ignored path never reaches `git add` and a journal left by an earlier failed run self-heals. A new going-shared integration case with claude and cursor opted in reproduces the wedge and proves the add commit carries CLAUDE.md and AGENTS.md but not the ignored Cursor rule.
Review finding 2: going private disowned every working-tree surface, so the private install never retired the generated, ignored Cursor dispatch rule, and --remove-shared-files then left it untracked once the .gitignore block was stripped. Disown only the surfaces committed at the primary checkout's HEAD; the private install retires the rest.
…, not origin's docket tip Review finding 3: once the state folder has moved to the private layout and the dckt remote holds the dckt branch, the publish is behind the repository. A later set-visibility private run no longer refuses when a teammate advanced origin's docket branch past the private history, and no longer fast-forwards those writes into the dckt branch. --delete-shared-branch still keeps origin's branch on a tip mismatch.
…nless a switch is under way Review finding 4: a never-switched shared repository switched to shared planned the ignore, commit, and other going-shared phases, so it refused over the user's own edits to AGENTS.md or init's unstaged .gitignore, or made an unrequested add commit. Those phases now settle unless a switch is under way (not yet shared, a private trace left, or the switch journal), and a going-shared run opens the add journal before it retires any of the private layout, so a run killed after its last private trace is gone still resumes its commit. An empty journal of the other subject no longer blocks a new switch.
…s budget (review finding 5) The single repovisibility shard carried a 150s budget, nearly twice the largest existing row. Split its tests into three sibling shards by non-overlapping name prefixes — TestIntegrationRepoVisibilityPrivate, TestIntegrationRepoVisibilityShared, and TestIntegrationRepoVisibilitySwitch (preview, refusals, commit machinery, direction-neutral acceptance) — and split the interrupted-phases proof by direction so each half lands with its direction's shard. Budgets reseeded from measured serial runs (42s, 67s, 61s -> 50, 75, 70).
- 7: the identity-keys stop now returns an invalid-state needs-review result carrying the push remedy and the commit row, never applied (visibilityRun.stop carries the refusal; the phase seam still fires). - 8: the preview's commit rows come from the real targets: the removal targets of HEAD going private (deletions as delete), and going shared the config, the .gitignore block, and the planned non-ignored surfaces whose result differs from HEAD. - 9: the dirty-path refusal checks only the paths the pending commit writes or commits (planVisibilityCommit's guard). - 10: the surface path list derives from reposeed.SurfacePaths, guarded by a test that enumerates Plan; visibilityCommitPaths and the init clean-preflight set build on it. - 11: an unlocatable private store (origin URL or data home unreadable) is an unknown probe, not "init first"; an origin URL that names no store still means no store. - 12: going shared keeps an on-disk .docket.yml byte for byte when it declares the split's leaves (reposetup.SameConfigLeaves).
danielhanold
deleted the
feat/switch-a-repository-between-shared-and-private-visibility
branch
October 7, 2026 15:05
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.
Summary
Adds
docket repository set-visibility <shared|private>, the one supported way to move an existing repository between shared and private visibility while keeping every record.--yesapplies, pinned to the previewed state. Re-running resumes from the first unfinished phase. Refuses while any run, gate drive, or worktree lock is live.docketon origin,dckton the local bare remote). No record is rewritten (ADR-0147)..git/dckt/config.yml, renames the state folder, moves ignore entries to.git/info/exclude, moves the metadata worktree out of the clone.--delete-shared-branchdeletesorigin/docketonly on an exact tip match;--remove-shared-filesmakes one local commitRemove docket configurations from repository.dockethistory on origin, publishes, splits config, restores the shared layout, makes one local commitAdd docket configurations to repository, keeps the bare remote as a backup.repository checkreports, andrepository repairre-stamps, absolute spec/plan/results backlinks as relative links. The switch preview warns about them (never refuses).Review
Whole-branch review: deep tier. 12 findings, disposition below.
cursoropted in wedged: the add commit tried to commit the ignored Cursor ruleset-visibility privaterefused (or pulled teammate writes) onceorigin/docketmoved onapplied.docket.ymlTest plan
tests/test_go_integration_app_repovisibility{,_private,_shared}.sh.