Skip to content

gr sync can fork a second gripspace clone and compose stale content after a branch-mismatch refusal #895

Description

@laynepenney

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

  1. Configure a gripspace source at a repository URL and branch main.
  2. Materialize it, create and publish another branch such as scratch, then attach the managed clone to scratch.
  3. Advance main upstream so the two branches contain observably different linked content.
  4. Run gr link --apply.
  5. Confirm it refuses the branch mismatch and recommends gr sync.
  6. Run gr sync.
  7. Inspect the managed gripspace directories and the composed output.
  8. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions