Skip to content

feat(sync): seed remote Git metadata from local objects #1593

Description

@coygeek

Summary

Add an explicit, opt-in synchronization path that creates a remote Git workspace from sanitized local Git objects when the runner cannot read the repository origin. This should support valid private, SSH, authenticated, host-local, or otherwise runner-unreachable origins without forwarding origin credentials or copying raw local .git state.

Ordinary manifest sync should remain the default and the authoritative source for working-tree content.

Problem to solve

Crabbox normally seeds a runner by cloning or fetching the local HEAD from origin, then overlays the Git-managed working set. If the origin is not readable from the runner, seeding fails and Crabbox falls back to ordinary file sync. The files arrive, but the remote workspace has no .git metadata.

That fallback is correct for file-only workloads and protects credentials, but it leaves no supported route for private or host-local repositories whose remote commands need repository identity or history. Builds and tests commonly call git rev-parse, git describe, git merge-base, version generators, change selectors, or tools that locate the repository root. Copying the working tree cannot satisfy those contracts.

The current opt-in Git-overlay feature does not fill this gap. Merged pull request #1453 deliberately requires an anonymous HTTP(S) or remotely readable filesystem origin and falls back for private, SSH, embedded-credential, and runner-unreachable origins.

Proposed behavior

Provide an explicit local-object seed mode for valid Git worktrees whose current commit cannot be fetched safely by the runner.

The mode should:

  • construct a bounded, inspectable seed from local Git objects sufficient for the advertised HEAD and the documented history operations;
  • transfer it through the existing provider-neutral SSH synchronization path;
  • create a normal remote Git workspace at the exact local commit before applying the ordinary working-set manifest;
  • keep the existing manifest, exclusions, executable bits, symlink identities, staged/unstaged/untracked changes, and deletion list authoritative for the resulting worktree;
  • exclude origin URLs, credentials, credential helpers, prompts, hooks, global or repository configuration, filters, reflogs, linked-worktree metadata, alternates, and unrelated unreachable objects;
  • apply existing transfer size limits, path validation, reserved-path rules, sparse-checkout and incomplete-worktree checks, workspace ownership, and cleanup guarantees; and
  • fail with an actionable local preflight or seed diagnostic when a safe bounded seed cannot be constructed.

The exact command or configuration name is a product decision. The authority change should remain explicit rather than becoming an automatic fallback for every failed remote clone.

Acceptance criteria

  • A valid local repository with an origin unavailable from the runner can opt in and produce a remote workspace where git rev-parse HEAD equals the exact local commit.
  • The documented bounded history operations, such as HEAD^ or a merge-base against a caller-selected base when supported by the mode, work without making the origin reachable from the runner.
  • Dirty tracked files, untracked files, deletions, renames, executable bits, symlinks, excludes, and the complete ordinary sync manifest retain their existing behavior.
  • The seed contains no remote credential, credential helper, prompt configuration, hook, filter, reflog, alternate object path, worktree-private metadata, or unrelated unreachable object.
  • A credential-bearing, SSH, private HTTP, or host-local origin is never forwarded to the lease as a side effect of enabling the mode.
  • The mode reports its selected/fallback state and transferred seed size in sync diagnostics and timing JSON.
  • An oversized, incomplete, conflicted, sparse-hidden, submodule-dependent, corrupt, or otherwise unsupported repository state fails before remote mutation or uses a documented safe fallback.
  • Existing ordinary Git seeding, default-off Git overlay, fresh-PR checkout, Actions-owned workspaces, and no-sync behavior remain unchanged when the new mode is not selected.
  • Regression coverage includes a runner-unreachable local origin, a private-origin credential canary, a dirty working tree, deletion and executable/symlink changes, bounded ancestry, size rejection, and cleanup after an interrupted seed.

Affected area

  • Local Git eligibility and seed planning in internal/cli/repo.go.
  • SSH-backed seed transfer, workspace preparation, and finalization in internal/cli/run.go and internal/cli/ssh.go.
  • Sync configuration, diagnostics, timing evidence, and sync-plan inspection.
  • POSIX, WSL2, and native-Windows behavior to the extent supported by the existing Git seed transport.
  • Sync, security, and troubleshooting documentation.

Non-goals

  • Forwarding a user's Git credentials, SSH agent, credential helper, or authenticated origin URL to a lease.
  • Copying the local .git directory wholesale.
  • Making an implicit local-object transfer after any ordinary clone or fetch failure.
  • Replacing --fresh-pr, Actions hydration, or the existing anonymous-origin Git-overlay optimization.
  • Synchronizing an intentionally non-Git local directory; that separate request is tracked in #1334.
  • Adding native Jujutsu revision mapping; that remains tracked in #1081.
  • Guaranteeing the complete repository history when the selected bounded history contract does not request it.

Alternatives considered

Make the private origin readable from the runner

Installing standing credentials or forwarding an SSH agent can make the existing clone path work, but it expands the credential boundary and is unavailable for host-local origins. The feature should preserve the protections established after #928 and #1029.

Copy the entire .git directory

Raw Git metadata can contain credentials, hooks, filters, alternates, reflogs, worktree paths, and unrelated objects. It also transfers more state than the runner needs. A sanitized bounded object seed has a narrower contract.

Use ordinary file sync

This is the current safe fallback and should remain the default. It cannot satisfy Git-dependent build and test commands because the remote workspace is not a repository.

Use current Git overlay

Git overlay minimizes working-tree transfer after the runner fetches filtered history from an eligible origin. It explicitly excludes the private and runner-unreachable cases this request addresses, so extending that origin requirement is the missing user-visible outcome rather than a duplicate of the merged feature.

Supporting context

The reproduction successfully transferred the tracked file, printed git_dir=absent, exited 0, and cleaned up the lease. It proves the current safe file-sync fallback and the absence of a remote Git workspace for an origin the runner cannot read.

The full 16-commit range from v0.47.0 through the exact current-main SHA was inspected. The complete live corpus of 23 open issues, 15 open pull requests, all 15 open issues authored by coygeek, and relevant closed issues and merged pull requests was screened. No current item requests a credential-free local-object seed for private, SSH, authenticated, host-local, or otherwise runner-unreachable origins.

The feature has one independent closure signal: an opted-in run creates a sanitized remote Git workspace at the exact local commit without exposing origin credentials or weakening ordinary manifest authority.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Low-risk cleanup, docs, polish, ergonomics, or speculative feature.clawsweeper:bulk-filedClawSweeper detected a high recent issue-filing volume from this author.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-product-decisionClawSweeper marked this issue as needing a product or behavior decision.clawsweeper:needs-security-reviewClawSweeper marked this issue as needing security-sensitive review.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:otherThis issue has meaningful maintainer-visible impact outside the owned taxonomy.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions