fix(repo mirror): route cluster-addressed commands to the cluster's core - #1475
Merged
Conversation
`entire repo mirror create/remove` and `collaborators add/remove/list` took the active context's core, so addressing a cluster in another federation (e.g. a prod aws-us-east-2.entire.io cluster while logged into partial.to) 400'd with "unknown cluster_host". These commands are resource-providers: the cluster-host names where the mirror lives. They now resolve the core from the cluster's /.well-known/entire-cluster.json and authenticate with the matching local context (active-wins-if-eligible, else sole eligible, else a login hint) — the same discovery the git/data-API paths already use. Account-scoped commands (repo create/list, mirror list/get) still use the active context. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Removes the duplicated context→ControlPlaneTarget tail between ResolveControlPlaneTarget and ResolveControlPlaneTargetForCluster. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes cluster-scoped repo mirror mutations failing with unknown cluster_host when the active login’s core doesn’t front the target cluster, by routing those commands to the cluster’s own control-plane core discovered via /.well-known/entire-cluster.json and selecting an eligible local context for auth (active if eligible → sole eligible → login hint).
Changes:
- Add cluster-aware control-plane client creation (
coreapi.NewForCluster) and wire cluster-scoped mirror commands to use it. - Refactor control-plane command runners to share a common preamble (
runCoreClient) and add cluster-scoped list helper (runCoreListForCluster). - Introduce
auth.ResolveControlPlaneTargetForCluster(cluster discovery + context selection) and add unit tests covering cluster-vs-active selection and empty cluster host.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| internal/coreapi/client.go | Adds NewForCluster and factors ENTIRE_TOKEN handling into clientFromEnvToken + shared clientForTarget. |
| cmd/entire/cli/repo_mirror.go | Routes mirror create/remove through runCoreForCluster so the correct federation core is dialed. |
| cmd/entire/cli/repo_mirror_collaborators.go | Routes collaborators add/remove/list through cluster-aware runners (runCoreForCluster / runCoreListForCluster). |
| cmd/entire/cli/corecmd.go | Refactors core runner plumbing (runCoreClient) and shares list rendering via renderCoreList. |
| cmd/entire/cli/auth/control_plane.go | Adds ResolveControlPlaneTargetForCluster and refactors shared targetForContext. |
| cmd/entire/cli/auth/control_plane_test.go | Adds tests asserting cluster-scoped resolution uses the cluster’s core, not the active context, plus empty-host validation. |
`mirror list` is identity-scoped (active context), so its visible set is whatever the active login's federation can see. Print "Listing mirrors on <login server>" (stderr, skipped for --json) so a surprising empty result — e.g. mirrors that live in another deployment — is legible rather than looking like data loss. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…eader Drop the bespoke activeLoginServer helper (and its tests) — the active context's core URL is already what auth.ResolveControlPlaneTarget returns, which is the same target coreapi.New dials. Header now reuses it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Soph
approved these changes
Jun 19, 2026
SnowingFox
pushed a commit
to SnowingFox/cli
that referenced
this pull request
Jul 8, 2026
`entire repo mirror get entire://<cluster>/gh/<owner>/<repo>` listed mirrors on the active context's core, so a clone URL for a cluster in a different federation failed with "no mirror matching" until the user manually switched contexts with `entire auth use`. The clone URL already names its cluster; dial the core fronting it — discovered from the cluster's /.well-known/entire-cluster.json and authenticated with the matching local context — the same routing `mirror create`/`remove` (PR entireio#1475) and `repo clone --cluster` (PR entireio#1529) already use. A ULID ref carries no cluster coordinate and stays on the active context. Adds runCoreObjectForCluster (mirroring runCoreListForCluster) and a clusterCoreClient test seam alongside activeCoreClient so the routing decision is pinned by command-level tests without live discovery. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Entire-Checkpoint: 01KX0ENQ9M4C5P85G431G5YR2E
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
https://entire.io/gh/entireio/cli/trails/615
Failure mode
entire repo mirror collaborators list github.com/… aws-us-east-2.entire.io(andcreate/remove,collaborators add/remove) 400'd withunknown cluster_hostwhenever the active context's core didn't front that cluster — e.g. addressing a prodentire.iocluster while logged intopartial.to.Insight
The mirror verbs added in #1458 are the first cluster-anchored core calls: the user supplies a
<cluster-host>and an upstream, and the owning project is the per-cell, system-managedgh:mirrors:*project derived server-side from the cluster. So the core to dial is a property of the cluster, not the user.Every other core call is anchored to an identity-owned resource and correctly dials the active context.
repo create, for instance, takes a required--project; the repo's project and its target cluster must be co-located on one core, so the project (which lives in your federation) is the anchor and--cluster-hostis just an in-federation placement — routing it by cluster would be wrong.So the mirror verbs now resolve the core from the cluster's
/.well-known/entire-cluster.jsonand authenticate with the matching local context (active-wins-if-eligible → sole eligible → login hint) — the same discovery the git/data-API paths already use. Project/identity-anchored commands (repo create/list,mirror list/get) are unchanged.Note
Medium Risk
Changes which core and credentials mirror mutations use in multi-federation setups; behavior is localized to cluster-scoped mirror commands with tests, but mis-discovery could still send requests to the wrong federation.
Overview
Fixes
unknown cluster_hoston mirror verbs when the active login’s core does not front the target cluster (e.g. prodentire.iocluster with apartial.toactive context).Cluster-scoped mirror commands (
create/remove, collaboratorsadd/remove/list) now resolve the control-plane core from the cluster’s/.well-known/entire-cluster.jsonand authenticate with the matching local context (same rules as git/data-API), viaResolveControlPlaneTargetForCluster,coreapi.NewForCluster, andrunCoreForCluster/runCoreListForCluster. Identity-scoped mirror calls (list/get) still use the active context.ResolveControlPlaneTargetis refactored to sharetargetForContext;coreapi.NewpullsENTIRE_TOKENhandling intoclientFromEnvToken/clientForTarget. Tests cover cluster vs active context selection and empty cluster host.Reviewed by Cursor Bugbot for commit 7c3e161. Configure here.