Skip to content

Confirm a restore with the server once its blob is verified - #4323

Merged
ss1909 merged 7 commits into
mainfrom
a-1775-refresh-expiry-after-blob-verified
Sep 7, 2026
Merged

Confirm a restore with the server once its blob is verified#4323
ss1909 merged 7 commits into
mainfrom
a-1775-refresh-expiry-after-blob-verified

Conversation

@ss1909

@ss1909 ss1909 commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Description

retrieve's response used to trigger a registry TTL bump server-side, before the agent had downloaded or verified anything -- the server has no visibility into whether the backing Namespace/S3 blob actually exists, so that bump was purely optimistic. If the blob turned out to be missing or corrupt, the entry's retention had already been extended for something about to be invalidated moments later.

Adds a CacheEntryConfirm call, mirroring CacheEntryExpire's shape (client-echoed scopes, best-effort roko retry), fired from Restore() only once the blob has been downloaded, digest-verified, and extracted -- the strictest "this restore is good" point available, not just the byte-for-byte digest check. Skipped for a fallback match, mirroring the backend's own (now-removed) bump guard on the same distinction.

Alternatives considered: none -- this is the client-side half of a companion server-side change (linked below), matching a design already settled there.

Context

Linear: https://linear.app/buildkite/issue/A-1775/refresh-cache-registry-expiry-only-after-backing-blob-is-verified
Server change: https://linear.app/buildkite/issue/A-1775/refresh-cache-registry-expiry-only-after-backing-blob-is-verified

Changes

  • api/cache.go -- new CacheEntryConfirmReq/CacheEntryConfirmResp + CacheEntryConfirm client method, identical shape to CacheEntryExpire.
  • internal/cache/client.go -- new CacheEntryConfirm method on the cacheAPI interface.
  • internal/cache/restore.go -- new confirmRestoreSucceeded, mirroring invalidateStaleEntry almost line-for-line (same retry/swallow pattern); called from Restore() after extraction succeeds, alongside a new cache.confirmed span attribute (matching the existing cache.invalidated convention).
  • Tests: unit coverage for confirmRestoreSucceeded (scopes echoed through, skipped on fallback, missing-address guard), a wire-level round trip in api/cache_test.go, and a full public-Restore()-path integration test proving confirm fires exactly once on a successful exact-match restore and not at all on a restore that ends in invalidation.

Testing

  • Tests have run locally (with go test ./...)
  • Code is formatted (with go tool gofumpt -extra -w .)

Disclosures / Credits

Claude Code implemented this change end-to-end (TDD: failing test first, then the fix), under my direction and review -- the client-side half of a fix designed together with its server-side companion.

@ss1909
ss1909 requested review from a team as code owners September 3, 2026 06:17
@ss1909 ss1909 added the bug label Sep 3, 2026

@buildsworth-bk-app buildsworth-bk-app Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The synchronous confirmation needs a total latency bound before this is safe on the restore path. I also left one non-blocking telemetry note inline.

Want to dig deeper?

Paste this into your agent to explore the findings from this review's Buildkite build:

Download the buildsworth logs from build 24976, then answer my questions about the findings.

Install the reading-buildsworth-logs skill to run this.

About buildsworth

Model: gpt-5.6-sol with xhigh thinking.

How to request a review: Comment @buildsworth-bk review on the PR, or request buildsworth-bk as a reviewer.

Risk labels (how buildsworth classifies risk) — buildsworth classifies risk itself from the diff. Unless repository policy already allows L2 approval, grant it by mentioning @buildsworth-bk (see approval ceiling and L2 approval grant):

  • L1 — Low risk (dep bumps, docs/copy, lockfiles, small presentational fixes). buildsworth may approve by default.
  • L2 — Standard risk (new UI, additive API fields, refactors). Approved only when repository policy or a verified grant allows it; otherwise comment-only.
  • L3 — High risk (auth, migrations, payments, secrets, perf-critical pipeline paths). Human review always required.

Comment thread internal/cache/restore.go
Comment thread internal/cache/restore.go
@ss1909
ss1909 force-pushed the a-1775-refresh-expiry-after-blob-verified branch from e90f1c8 to 87bd2d3 Compare September 4, 2026 01:29

@buildsworth-bk-app buildsworth-bk-app Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The previous concerns remain open in the current revision; I found no new issues in this pass.

Want to dig deeper?

Paste this into your agent to explore the findings from this review's Buildkite build:

Download the buildsworth logs from build 25365, then answer my questions about the findings.

Install the reading-buildsworth-logs skill to run this.

Addresses buildsworth review on #4323: the confirm call's retry loop had no
overall deadline, so a network partition could stall every successful
exact-match restore for up to 5 client timeouts. Also move TotalDuration's
assignment after confirmRestoreSucceeded so it reflects the true end-to-end
restore time.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@ss1909

ss1909 commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

@buildsworth-bk review

@buildsworth-bk-app
buildsworth-bk-app Bot dismissed their stale review September 4, 2026 01:45

Previous concerns have been addressed.

@buildsworth-bk-app buildsworth-bk-app Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Both previous concerns are addressed in the current revision; I found no new issues. This changes the latency-sensitive agent cache restore/API path, so it remains outside this review's L1 approval ceiling.

Want to dig deeper?

Paste this into your agent to explore the findings from this review's Buildkite build:

Download the buildsworth logs from build 25380, then answer my questions about the findings.

Install the reading-buildsworth-logs skill to run this.

@buildsworth-bk-app
buildsworth-bk-app Bot dismissed their stale review September 7, 2026 01:28

Previous concerns have been addressed.

@buildsworth-bk-app buildsworth-bk-app Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The earlier concerns remain addressed, and I found no new issues in the current revision. This changes the latency-sensitive agent cache restore/API path, so it remains outside this review's L1 approval ceiling.

Want to dig deeper?

Paste this into your agent to explore the findings from this review's Buildkite build:

Download the buildsworth logs from build 26026, then answer my questions about the findings.

Install the reading-buildsworth-logs skill to run this.

@blaknite

blaknite commented Sep 7, 2026

Copy link
Copy Markdown
Member

Implementation looks good!

Could we add two regression tests for the best-effort confirmation behaviour?

  1. A successful restore where the confirmation API fails: assert that Restore() still returns no error and CacheRestored remains true.
  2. A slow or blocked confirmation request: assert that the deadline bounds the entire operation, including requests and retry waits, rather than resetting per attempt.

@ss1909
ss1909 enabled auto-merge September 7, 2026 03:53
ss1909 and others added 2 commits September 7, 2026 13:53
Covers a successful restore surviving a failed confirmation call, and
confirmRestoreSucceeded's deadline bounding the whole retry loop rather
than resetting per attempt.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

@buildsworth-bk-app buildsworth-bk-app Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The earlier concerns remain addressed, and the new best-effort and deadline regression coverage exercises the requested paths. This remains outside the L1 approval ceiling because it changes the latency-sensitive agent cache restore/API path.

Want to dig deeper?

Paste this into your agent to explore the findings from this review's Buildkite build:

Download the buildsworth logs from build 26116, then answer my questions about the findings.

Install the reading-buildsworth-logs skill to run this.

@ss1909

ss1909 commented Sep 7, 2026

Copy link
Copy Markdown
Contributor Author

@blaknite , I've added the tests - thanks for the review Grant!

@buildsworth-bk-app buildsworth-bk-app Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The earlier concerns remain addressed, and I found no new issues in the current revision. This still changes the latency-sensitive agent cache restore/API path, so it remains outside this review’s L1 approval ceiling.

Want to dig deeper?

Paste this into your agent to explore the findings from this review's Buildkite build:

Download the buildsworth logs from build 26163, then answer my questions about the findings.

Install the reading-buildsworth-logs skill to run this.

Comment thread internal/cache/restore.go
// without waiting out the real timeout.
var confirmRestoreTimeout = 5 * time.Second

// confirmRestoreSucceeded tells the server this restore's blob was verified,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can you please shorten some of these code comments? This one for example could just be:

// confirmRestoreSucceeded tells the server this restore's blob was verified,
/ so the registry can safely refresh the entry's retention.
// Skipped for a fallback matched.

@ss1909
ss1909 merged commit 4d7550e into main Sep 7, 2026
6 checks passed
@ss1909
ss1909 deleted the a-1775-refresh-expiry-after-blob-verified branch September 7, 2026 07:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants