Problem
gr link --apply now refuses a managed gripspace source that is attached to a branch different from the configured revision. Its diagnostic tells the operator to run gr sync.
In that topology, gr sync does not reconcile the existing managed clone. It creates a second clone with the configured revision appended to the directory name, then reports success while link composition still resolves the original drifted directory by its gripspace name.
The next gr link --apply sees both clones, refuses on ambiguity, and repeats the same gr sync remedy. The documented recovery path is therefore a loop.
Reproduction
- Configure a gripspace source at a repository URL and branch
main.
- Materialize it, create and publish another branch such as
scratch, then attach the managed clone to scratch.
- Advance
main upstream so the two branches contain observably different linked content.
- Run
gr link --apply.
- Confirm it refuses the branch mismatch and recommends
gr sync.
- Run
gr sync.
- Inspect the managed gripspace directories and the composed output.
- Run
gr link --apply again.
Observed
- The first apply refuses with exit 2 and leaves the clone and composed output untouched.
gr sync creates a second managed clone for main rather than reconciling the existing clone.
- The sync exits 0 and reports links applied, but the composed output still comes from the stale original directory.
- The next apply refuses because two candidates now resolve to the same gripspace name and again recommends
gr sync.
Expected
gr sync should reconcile the managed source selected by the manifest's repository URL and configured revision, or refuse without changing the workspace. It must not report success while composing from a different managed directory than the one it just synchronized.
Likely seam
The existing source match in resolve_space_name / is_same_remote_and_rev compares repository identity without consulting the recorded revision key. The resolution key needs to include the configured revision so sync, name resolution, and composition select the same managed source.
Acceptance
- The branch-mismatch diagnostic's
gr sync remedy terminates in a usable workspace.
- Sync does not create an ambiguous second clone for the same configured source.
- A successful sync composes from the source it synchronized.
- A binary-level witness covers branch mismatch → sync → apply, including the stale-content discriminator.
Follow-up to #890 and #891. The branch-mismatch refusal made this pre-existing recovery defect observable. It did not introduce it.
Problem
gr link --applynow refuses a managed gripspace source that is attached to a branch different from the configured revision. Its diagnostic tells the operator to rungr sync.In that topology,
gr syncdoes not reconcile the existing managed clone. It creates a second clone with the configured revision appended to the directory name, then reports success while link composition still resolves the original drifted directory by its gripspace name.The next
gr link --applysees both clones, refuses on ambiguity, and repeats the samegr syncremedy. The documented recovery path is therefore a loop.Reproduction
main.scratch, then attach the managed clone toscratch.mainupstream so the two branches contain observably different linked content.gr link --apply.gr sync.gr sync.gr link --applyagain.Observed
gr synccreates a second managed clone formainrather than reconciling the existing clone.gr sync.Expected
gr syncshould reconcile the managed source selected by the manifest's repository URL and configured revision, or refuse without changing the workspace. It must not report success while composing from a different managed directory than the one it just synchronized.Likely seam
The existing source match in
resolve_space_name/is_same_remote_and_revcompares repository identity without consulting the recorded revision key. The resolution key needs to include the configured revision so sync, name resolution, and composition select the same managed source.Acceptance
gr syncremedy terminates in a usable workspace.Follow-up to #890 and #891. The branch-mismatch refusal made this pre-existing recovery defect observable. It did not introduce it.