Skip to content

fix: preserve private mirror branches#30

Merged
steipete merged 3 commits into
mainfrom
codex/private-mirror-branches
Jun 19, 2026
Merged

fix: preserve private mirror branches#30
steipete merged 3 commits into
mainfrom
codex/private-mirror-branches

Conversation

@steipete

Copy link
Copy Markdown
Contributor

Summary

  • preserve unpublished local mirror branches while still rejecting deleted tracked branches
  • let callers enforce private mirror repository directory modes
  • cover local initialization, clone permissions, unpublished branches, and deleted tracked branches

Proof

  • go test ./...
  • go test -race ./...
  • GOWORK=off go vet ./...
  • GOWORK=off go run golang.org/x/tools/cmd/deadcode@v0.45.0 -test ./...
  • autoreview clean

@clawsweeper

clawsweeper Bot commented Jun 19, 2026

Copy link
Copy Markdown

Codex review: needs real behavior proof before merge. Reviewed June 19, 2026, 7:22 AM ET / 11:22 UTC.

Summary
The PR updates the shared mirror package to preserve unpublished local branches during PullCurrent, reject deleted tracked branches, clone the requested remote branch, add caller-selected repository directory modes, and cover those paths with mirror tests.

Reproducibility: yes. by source inspection: current main's PullCurrent always pulls origin/<branch> after checking out an existing local branch, which is the path that fails unpublished local branches. I did not run the temp-repo reproduction because this review kept the checkout read-only.

Review metrics: 2 noteworthy metrics.

  • Public API surface: 1 exported field added. mirror.Options.DirMode is additive but public, so downstream compatibility review matters before merge.
  • Changed files: 3 files affected. The diff is tightly scoped to mirror code/tests plus one release-owned changelog line.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🧂 unranked krab
Patch quality: 🐚 platinum hermit
Result: blocked until real behavior proof from a real setup is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P1] Add redacted real behavior proof from a temp mirror run showing unpublished branch preservation and deleted tracked-branch rejection.
  • Remove the CHANGELOG.md edit and keep release-note context in the PR body or commit message.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The PR body only lists tests/static checks; please add redacted terminal output, logs, or a terminal screenshot from a real temp mirror run, then update the PR body to trigger a fresh ClawSweeper review or ask a maintainer to comment @clawsweeper re-review.

Risk before merge

  • [P1] The PR has only test/static-check proof; it still needs redacted terminal output, logs, or a terminal screenshot from a real temp mirror run showing the after-fix behavior.
  • [P1] The branch edits release-owned CHANGELOG.md; release-note context should stay in the PR body or commit message for this normal PR.

Maintainer options:

  1. Decide the mitigation before merge
    Land the mirror fix after removing the release-owned changelog entry and adding redacted real behavior proof for the branch-preservation and deleted-tracked-branch paths.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Next step before merge

  • [P1] Needs contributor-supplied real behavior proof and a release-owned changelog cleanup before normal maintainer merge review; automation cannot supply the contributor proof.

Security
Cleared: No concrete security or supply-chain regression found; the filesystem-permission change is opt-in and no CI, dependency, secret, or download path changed.

Review findings

  • [P3] Remove the release-owned changelog entry — CHANGELOG.md:5
Review details

Best possible solution:

Land the mirror fix after removing the release-owned changelog entry and adding redacted real behavior proof for the branch-preservation and deleted-tracked-branch paths.

Do we have a high-confidence way to reproduce the issue?

Yes, by source inspection: current main's PullCurrent always pulls origin/<branch> after checking out an existing local branch, which is the path that fails unpublished local branches. I did not run the temp-repo reproduction because this review kept the checkout read-only.

Is this the best way to solve the issue?

Mostly yes: the mirror change is narrow, additive, and covered by temp-repo tests. The best mergeable version should drop the CHANGELOG.md edit and add real behavior proof from an actual mirror run.

Full review comments:

  • [P3] Remove the release-owned changelog entry — CHANGELOG.md:5
    CHANGELOG.md is release-owned for OpenClaw PR review, so normal PRs should keep release-note context in the PR body or commit message instead of editing this file. Please remove this line from the branch.
    Confidence: 0.91

Overall correctness: patch is correct
Overall confidence: 0.78

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 3f71740424ec.

Label changes

Label changes:

  • add P2: This is a normal-priority shared mirror fix/API improvement with limited blast radius but real local archive branch-preservation impact.
  • add rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🐚 platinum hermit.
  • add status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR body only lists tests/static checks; please add redacted terminal output, logs, or a terminal screenshot from a real temp mirror run, then update the PR body to trigger a fresh ClawSweeper review or ask a maintainer to comment @clawsweeper re-review.

Label justifications:

  • P2: This is a normal-priority shared mirror fix/API improvement with limited blast radius but real local archive branch-preservation impact.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🐚 platinum hermit.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR body only lists tests/static checks; please add redacted terminal output, logs, or a terminal screenshot from a real temp mirror run, then update the PR body to trigger a fresh ClawSweeper review or ask a maintainer to comment @clawsweeper re-review.
Evidence reviewed

What I checked:

  • Repository policy applied: Full AGENTS.md was read; it identifies mirror as a stable public package noun and requires compatibility care for exported API changes in this shared Go library. (AGENTS.md:1, 3f71740424ec)
  • Ownership boundary: docs/boundary.md places provider-neutral Git mirror mechanics in crawlkit, so this branch's mirror behavior belongs in this repository rather than a downstream app. (docs/boundary.md:31, 3f71740424ec)
  • Current main behavior: Current main's PullCurrent fetches origin, checks only the local branch, then always runs git pull --ff-only origin <branch>, so it does not distinguish unpublished local branches from deleted tracked branches. (mirror/mirror.go:84, 3f71740424ec)
  • PR implementation surface: The live PR head adds local/remote ref checks in PullCurrent, an opt-in DirMode field, requested-branch checkout after clone, and matching regression tests. (mirror/mirror.go:115, 0caab8d31b46)
  • PR proof is only tests/static checks: The PR body lists go test, race tests, vet, deadcode, and autoreview clean, but it does not include terminal output, logs, screenshots, or other after-fix real behavior proof from a mirror run. (0caab8d31b46)
  • Release-owned file touched: The PR head adds an Unreleased changelog entry; the review policy keeps CHANGELOG.md release-owned for normal OpenClaw PRs. (CHANGELOG.md:5, 0caab8d31b46)

Likely related people:

  • steipete: Current main blame and log history show Peter Steinberger introduced the mirror API surface and recently extended durable mirror synchronization around this code path. (role: feature owner and recent area contributor; confidence: high; commits: 94bbcd72fa6f, 3ff7edef8b33, 6e14735bb248; files: mirror/mirror.go, mirror/mirror_test.go)
  • Vincent Koc: Recent history shows Vincent Koc touched mirror code/tests during crawlkit audit hardening and public compatibility coverage, though not the central PullCurrent lines. (role: adjacent hardening contributor; confidence: medium; commits: 2b7d5222adea, d5cbaf00cd02; files: mirror/mirror.go, mirror/mirror_test.go)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 130b520ca7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread mirror/mirror_test.go
Comment on lines +85 to +86
if mode := info.Mode().Perm(); mode != 0o750 {
t.Fatalf("repo mode = %o, want 750", mode)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Skip POSIX mode assertions on Windows

This new assertion is also exercised by the windows-test job in .github/workflows/ci.yml, which runs go test ./... on windows-latest. On Windows, Go's os.Chmod only maps to the read-only attribute and directory Mode().Perm() does not round-trip POSIX permissions like 0750, so this test will fail in CI even though the repository was created successfully; guard the POSIX permission check by platform or use a Windows-specific expectation.

Useful? React with 👍 / 👎.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jun 19, 2026
@clawsweeper clawsweeper Bot added the P2 Normal priority bug or improvement with limited blast radius. label Jun 19, 2026
@steipete
steipete force-pushed the codex/private-mirror-branches branch from ba7c157 to 88ac074 Compare June 19, 2026 11:22
@steipete
steipete merged commit 82bf182 into main Jun 19, 2026
6 checks passed
@steipete
steipete deleted the codex/private-mirror-branches branch June 19, 2026 11:25
@steipete

Copy link
Copy Markdown
Contributor Author

Landed in 82bf1826da3f4ef61a5f9df17a044cce0dc3ffe9.

Proof: full tests, race tests, vet, dead-code analysis, and autoreview passed locally. GitHub Linux, Windows, CodeQL, secret scanning, race, and vulnerability gates passed on the merged head.

@steipete

Copy link
Copy Markdown
Contributor Author

Post-merge behavior proof for 82bf1826da3f4ef61a5f9df17a044cce0dc3ffe9 on current main.

I ran an external Go harness against github.com/openclaw/crawlkit/mirror using only freshly created temporary local Git repositories. It emitted no repository paths, commit hashes, remotes, credentials, or private data:

PASS unpublished-local: HEAD preserved; local content preserved
PASS deleted-tracked: rejected with expected missing-origin error
PASS requested-branch: release checked out; release content present
PASS DirMode: clone=0750; initialized/existing repository=0750
PASS cleanup: synthetic temporary repositories only

Focused regression proof:

GOWORK=off go test -count=1 -v ./mirror -run 'Test(EnsureRepoAppliesPrivateDirectoryMode|EnsureRepoClonesRequestedRemoteBranch|PullCurrentPreservesUnpublishedLocalBranch|PullCurrentRejectsDeletedTrackedBranch)$'
PASS — all four tests

Full local proof:

GOWORK=off go test -count=1 ./...       # pass, 17 packages
GOWORK=off go test -race -count=1 ./... # pass, 17 packages
GOWORK=off go vet ./...                 # pass

Exact merged-head GitHub proof:

The final changelog entry matches the verified behavior. No follow-up defect found; no corrective PR needed.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 88ac07442c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread mirror/mirror.go
Comment on lines +129 to +131
trackedRemote, err := output(ctx, opts.RepoPath, opts.Git, "config", "--get", "branch."+opts.Branch+".remote")
if err == nil && strings.TrimSpace(trackedRemote) == "origin" {
return fmt.Errorf("tracked remote branch origin/%s is missing", opts.Branch)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Verify the branch merge ref before rejecting

For a local-only mirror branch created from another upstream, e.g. git checkout -b private origin/main, Git records branch.private.remote=origin but branch.private.merge=refs/heads/main. When origin/private does not exist, this check still reports the tracked branch as deleted even though the configured upstream is origin/main, so PullCurrent fails instead of preserving that unpublished local branch; also compare branch.<name>.merge to refs/heads/<name> before treating the missing ref as a deleted tracked branch.

Useful? React with 👍 / 👎.

Comment thread mirror/mirror.go
Comment on lines +45 to +47
if opts.DirMode != 0 {
if err := os.Chmod(opts.RepoPath, opts.DirMode); err != nil {
return fmt.Errorf("set repo permissions: %w", err)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Create the private destination before cloning

When DirMode is requested under an already-existing parent with broader permissions, git clone creates and populates RepoPath using Git's default directory mode before this post-clone Chmod narrows it. That leaves a window where other local users can read the cloned archive despite the caller asking for a private mirror; create/chmod an empty destination before cloning, or run the clone with a restrictive umask.

Useful? React with 👍 / 👎.

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

Labels

P2 Normal priority bug or improvement with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant