cli: apply --wait-timeout before the first clone-probe token mint · Entire
cli: apply --wait-timeout before the first clone-probe token mint
2ebd0d8→main·
toothbrush·1mo ago·2 files·+36 added/-7 removed
waitForMirrorClone minted its first repo-scoped token before arming the wait deadline. That was tolerable when the mint was a single STS exchange, but it now spans cluster discovery and a possible login refresh — a slow auth path could block well past a small --wait-timeout before the timer even started. Arm the deadline first so the authorization phase consumes the user's wait budget.
The mint goes through a package seam so the regression test can pin a hung auth path against a 50ms timeout.
Co-Authored-By: Claude Fable 5 noreply@anthropic.com
Sessions
be119056ae83View transcript
[?
Auth Refactor: Eliminate Static FallbacksClaude Code·Fable 5.{1m}·2 steps](/content/gh/entireio/cli/session/e6146684-ebfa-4f57-beff-34194cac8c2a#timeline-be119056ae83/index.html)
Changes
2
cmd/entire/cli
Mrepo_mirror_probe.go+15/-7
Mrepo_mirror_test.go+21
161 unmodified lines
162
163
164
165
166
167
168
169
170
171
6 unmodified lines
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
182
196
197
198
199
1 unmodified line
201
202
203
190
191
192
193
194
195
204
205
206
161 unmodified lines
return true, NewSilentError(fmt.Errorf("mirror %s is suspended", mirrorID))
// mintRepoToken mints the repo-scoped pull token for the clone probe.
// Package var so tests can substitute a slow or failing auth path.
var mintRepoToken = auth.RepoScopedToken
// waitForMirrorClone blocks until the mirror at /gh/<owner>/<repo> on
// clusterHost advertises a resolvable HEAD (the initial GitHub→EntireDB
// clone has landed) or the deadline expires. It probes the data plane's
// rather than minting once up front. Re-mints are floored at
// minReauthInterval so a flapping STS can't be amplified into a re-mint
// every probeInterval ticks.
//
// The deadline is applied before the first mint: minting now spans cluster
// discovery and a possible login refresh, so the authorization phase must
// consume the user's wait budget, not run before it.
func waitForMirrorClone(ctx context.Context, out io.Writer, clusterHost, owner, repo string, timeout time.Duration) error {
if timeout > 0 {
var cancel context.CancelFunc
ctx, cancel = context.WithTimeout(ctx, timeout)
defer cancel()
}
repoSlug := "/gh/" + owner + "/" + repo
checkURL := fmt.Sprintf("https://%s%s/info/refs?service=git-upload-pack", clusterHost, repoSlug)
mintToken := func() (string, error) {
return auth.RepoScopedToken(ctx, clusterHost, repoSlug, "pull")
return mintRepoToken(ctx, clusterHost, repoSlug, "pull")
}
token, err := mintToken()
if err != nil {
1 unmodified line
}
lastMint := time.Now()
if timeout > 0 {
var cancel context.CancelFunc
ctx, cancel = context.WithTimeout(ctx, timeout)
defer cancel()
}
ticker := time.NewTicker(probeInterval)
defer ticker.Stop()
Mcmd/entire/cli/repo_mirror_probe.go+15/-7
4 unmodified lines
5
6
7
8
9
10
11
498 unmodified lines
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
4 unmodified lines
"context"
"errors"
"fmt"
"io"
"net"
"net/http"
"net/http/httptest"
498 unmodified lines
require.NoError(t, err)
return &http.Request{URL: u}
}
// TestWaitForMirrorClone_TimeoutBoundsAuthorization pins that --wait-timeout
// covers the initial token mint, not just the probe loop: minting spans
// cluster discovery and a possible login refresh, so a hung auth path must
// be cut off by the user's wait budget.
//
// Not parallel: swaps the package-level mintRepoToken seam.
func TestWaitForMirrorClone_TimeoutBoundsAuthorization(t *testing.T) {
prev := mintRepoToken
mintRepoToken = func(ctx context.Context, _, _, _ string) (string, error) {
<-ctx.Done() // hang until the wait deadline fires
return "", ctx.Err()
}
t.Cleanup(func() { mintRepoToken = prev })
start := time.Now()
err := waitForMirrorClone(context.Background(), io.Discard, "cluster.example", "o", "r", 50*time.Millisecond)
require.ErrorIs(t, err, context.DeadlineExceeded)
require.Less(t, time.Since(start), 10*time.Second, "first mint must be bounded by the wait timeout")
}
Mcmd/entire/cli/repo_mirror_test.go+21