🤖 fix: harden remote base repo normalization#3496
Conversation
Keep SSH remote .mux-base.git repositories from leaking shared checkout config into linked worktrees. The runtime now strips core.bare/core.worktree, keeps the base HEAD on an internal sentinel ref, and creates new worktrees via detached checkout before attaching the workspace branch so the base repo never masquerades as trunk. --- _Generated with `mux` • Model: `openai:gpt-5.5` • Thinking: `xhigh` • Cost: `$27.40`_ <!-- mux-attribution: model=openai:gpt-5.5 thinking=xhigh costs=27.40 -->
|
@codex review |
|
Codex Review: Didn't find any major issues. Chef's kiss. ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
Git versions used by CI can report the intentional refs/mux-internal/base-head sentinel as fsck badHeadTarget. Treat that HEAD-only complaint as healthy for explicit base-repo connectivity probes while preserving missing-object failures. --- _Generated with `mux` • Model: `openai:gpt-5.5` • Thinking: `xhigh` • Cost: `$29.32`_ <!-- mux-attribution: model=openai:gpt-5.5 thinking=xhigh costs=29.32 -->
|
@codex review Follow-up pushed for the CI Git/fsck behavior: base repo connectivity probes now ignore only the expected HEAD-only badHeadTarget complaint for refs/mux-internal/base-head, while preserving real missing-object failures. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: abd4c52851
ℹ️ 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".
Avoid git branch -D in SSH base repos because the base HEAD intentionally points at refs/mux-internal/base-head. Delete the workspace branch ref directly so cleanup still works with the sentinel HEAD invariant. --- _Generated with `mux` • Model: `openai:gpt-5.5` • Thinking: `xhigh` • Cost: `$29.32`_ <!-- mux-attribution: model=openai:gpt-5.5 thinking=xhigh costs=29.32 -->
|
@codex review Addressed the branch deletion finding by replacing |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 42693ea000
ℹ️ 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".
Keep the sentinel-HEAD-safe update-ref cleanup, but only delete the workspace branch ref after verifying no worktree still reports that branch and by passing the expected old OID. --- _Generated with `mux` • Model: `openai:gpt-5.5` • Thinking: `xhigh` • Cost: `$29.32`_ <!-- mux-attribution: model=openai:gpt-5.5 thinking=xhigh costs=29.32 -->
|
@codex review Addressed the active-branch guard concern: the update-ref cleanup now first verifies no worktree still owns the branch and deletes with the expected old OID. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bb6a747899
ℹ️ 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".
Use an unborn internal branch only as the empty-repo neutral state, then detach the shared base repo HEAD at the selected worktree base commit when one is available. This keeps Graphite from seeing a user branch checked out at .mux-base.git while preserving Git's normal worktree, fsck, and branch-delete porcelain behavior. --- _Generated with `mux` • Model: `openai:gpt-5.5` • Thinking: `xhigh` • Cost: `7.50`_ <!-- mux-attribution: model=openai:gpt-5.5 thinking=xhigh costs=37.50 -->
|
@codex review I pushed an elegant-redesign pass that keeps the base repo HEAD Git-native: unborn internal branch while empty, detached at the selected base commit once materializing a workspace. This lets the PR keep normal Git porcelain ( |
|
Resolved the remaining Codex thread from the prior @codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5dc4ac8588
ℹ️ 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".
Treat warm-path base repo config cleanup failures as cache misses so poisoned shared config never leaks into a newly materialized worktree. The slow path already owns retry and hard-error handling for lock conflicts and other cleanup failures. --- _Generated with `mux` • Model: `openai:gpt-5.5` • Thinking: `xhigh` • Cost: `$47.88`_ <!-- mux-attribution: model=openai:gpt-5.5 thinking=xhigh costs=47.88 -->
|
Addressed the warm-path cleanup feedback: @codex review |
|
Codex Review: Didn't find any major issues. Already looking forward to the next diff. ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b19d59a3bd
ℹ️ 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".
deleteWorkspace resolves the worktree common git dir from the workspace itself, which for hand-crafted/legacy worktrees can be a real checkout .git rather than the Mux-owned .mux-base.git. Rewriting that HEAD onto the unborn internal branch would strand the user checkout, so gate the neutralization on the resolved dir basename being .mux-base.git. --- _Generated with `mux` • Model: `anthropic:claude-fable-5` • Thinking: `xhigh` • Cost: `$56.34`_ <!-- mux-attribution: model=anthropic:claude-fable-5 thinking=xhigh costs=56.34 -->
|
Addressed the P1 ( |
|
@codex review |
|
Codex Review: Didn't find any major issues. Can't wait for the next one! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
|
@codex review |
|
Codex Review: Didn't find any major issues. Nice work! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
Summary
Hardens SSH/Coder remote workspace setup so Mux treats
.mux-base.gitas an internal bare common git directory rather than a checkout. Shared base repos are normalized by removing leakedcore.bare/core.worktreeconfig, keeping the base repo's ownHEADoff user branches, and healing poisoned warm-path caches before materializing new workspaces.Background
A remote Coder host ended up with
.mux-base.git/configcontaining shared checkout config (core.bare=falseandcore.worktree=<synthetic path>). Linked worktrees inherit that common config, so a repair that made one workspace look healthy poisoned future sibling workspaces. Separately, leaving the base repoHEADon trunk makes checkout-aware tools such as Graphite interpret the bare cache as the real trunk checkout.Implementation
The base repo invariant is now explicit:
.mux-base.gitis bare by layout, has no shared checkout config, and does not advertise a user branch ingit worktree list --porcelain. Empty base repos pointHEADat an unborn internal branch so Git porcelain stays branch-shaped; once Mux selects a real worktree base commit, it detaches the base repoHEADat that commit. This keeps Graphite from seeing trunk checked out at the base repo while preserving normal Git behavior forworktree add -B,worktree add -b,fsck, andbranch -D.Both the slow sync path and the fused warm fast-path normalize poisoned base repos before checkout. The warm path treats cleanup failures as cache misses so the slow path can run its retry/error handling instead of materializing from still-poisoned shared config. Branch cleanup after workspace deletion keeps Git's own active-worktree guard by neutralizing base
HEADand usinggit branch -Dinstead of raw ref deletion; theHEADrewrite is scoped to common git dirs named.mux-base.gitso deleting a worktree of an unmanaged real checkout never strands that checkout on the internal branch. Regression coverage exercises pre-existing poisonedcore.bare/core.worktree, neutral baseHEAD, warm fast-path healing, missing-object repair, and deleted-worktree branch cleanup.Validation
Focused SSH integration coverage was run for the poisoned-config, neutral-HEAD, warm-path healing, missing-object repair, and worktree-delete cases. Local static validation also passed with
MUX_ESLINT_CONCURRENCY=1 make static-check.Risks
This touches remote SSH workspace materialization and deletion. The riskiest area is old/corrupted shared base repos, but the change is intentionally defensive: normalization is idempotent, warm-path cleanup failures fall back to the slow path, missing-object repair remains in the checkout path, and branch cleanup is best-effort.
Generated with
mux• Model:openai:gpt-5.5• Thinking:xhigh• Cost:$47.88