Phase 18: respect buf.yaml dependency refs + prewarm removal - #38
Merged
Conversation
…e ref - TestIsSHA: 8 cases for the SHA-shape check (40/64 lowercase hex, reject refs and UUIDs) - TestIsUUID: 6 cases for the 32-lowercase-hex check - TestParseResourceRefName_ReadsRef: build a Name proto with ref=3, assert parsed - TestParseResourceRefName_NoRef: build a Name proto without ref, assert ref="" Tests fail at compile time: isSHA, isUUID, and moduleRef.ref do not exist yet. Co-Authored-By: Claude <noreply@anthropic.com>
Refs end-to-end:
- moduleRef gains a ref field (buf BSR Name.ref, proto field 3)
- parseResourceRefName reads field 3 (ref), keeps existing owner/module arms
- ServeHTTP and ServeGraph pass ref.ref to GetMeta (was ""), so a buf
client pinning cyp/cyp-net-listeners:main/v2 gets the SHA at main/v2
- ServeDownload unchanged (operates on UUIDs/SHAs, not refs)
Provider ref-resolution:
- Add isSHA helper in commits_helpers.go for the SHA-vs-ref gate
- Add isUUID helper for probeCommitID to detect UUID inputs
- Bitbucket: replace 'commit != "" && commit != "main"' with
isSHA(commit); non-SHA inputs call new getCommit(ctx, ref) which
hits /commits/{ref} and returns the resolved id
- GitHub: same gate; non-SHA inputs call repos.GetCommit(ctx, owner,
repo, ref, nil) and stamp rc.GetSHA() into meta.Commit
Provider tests:
- bitbucket/getrepo_test.go: 4 subtests (Empty, RawSHA_40, RawSHA_64,
ResolvesRef via httptest server returning {id,displayId})
- github/getrepo_test.go: 3 subtests (Empty, RawSHA_40, ResolvesRef
via new mockRepos that supports GetCommit)
- github/mockrepos_test.go: new mockRepos mock with GetCommit plumbing
and call-count tracking
Co-Authored-By: Claude <noreply@anthropic.com>
8 cases: - 4 success: round-trip a known 40-char SHA, all-zero, all-ones, and a 64-char SHA-256 (recovery is shape-independent) - 4 error: empty, 31 chars, 33 chars, 32 chars non-hex Tests fail at compile time: commitUUIDInverse is not defined yet. Co-Authored-By: Claude <noreply@anthropic.com>
The inverse of commitUUID: given a 32-char dashless UUID, recover the first 28 hex characters of the SHA that produced it. Used by probeCommitID (task 3) to derive a probe arg from a buf-issued UUID input on the post-restart Download cache-miss path. Inverse is lossy by design: commitUUID drops the last 6 bytes of the SHA (2^112 collision surface) and overwrites the version/variant bytes at positions 6 and 8. The recovered 14 bytes are sufficient to identify a specific source among the configured providers and to scope a probeCommitID fan-out to the right repository. TestCommitUUIDInverse (8 cases): - 4 success: round-trip a known 40-char SHA, all-zero, all-ones, and a 64-char SHA-256 (recovery is shape-independent) - 4 error: empty, 31 chars, 33 chars, 32 chars non-hex Co-Authored-By: Claude <noreply@anthropic.com>
…Inverse Prewarm removal: - Delete prewarmHeads and registerResolved from commits.go - Delete prewarmOnce, prewarmEnabled, prewarmTimeout fields from commitServiceHandler - Delete PrewarmEnabled, PrewarmTimeout fields from CommitResolution - Delete the goroutine launch in NewWithConfig - Delete PrewarmConfig struct from config.go - Drop cc.Prewarm.* references in main.go - Delete the now-obsolete TestPrewarmHeads_PopulatesCommitMap Probe rewrite (review.md finding #6 closure): - probeCommitID now uses commitUUIDInverse for 32-char UUID inputs and validates the source's meta.Commit starts with the recovered 28-char prefix (prefix-match validation; fail-closed on mismatch) - New registerResolvedAlias helper takes the buf-issued id (typically a UUID) as the primary key and the resolved SHA as the alias - Inputs that are neither SHA-shaped (40/64 hex) nor UUID-shaped (32 hex) are negative-cached and return early (no upstream fan-out) New tests: - TestServeDownload_AfterRestart_ProbeResolvesUUID: post-restart Download with a UUID succeeds via the inverse + prefix-match path - TestServeDownload_AfterRestart_ProbeMissesOnUnknownUUID: a UUID whose first 14 bytes do not match any source's HEAD returns 400 - Updated mockSource to accept a prefix match (HasPrefix check) for the post-restart probe fan-out Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
onokonem
added a commit
that referenced
this pull request
Jul 8, 2026
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.
Summary
Phase 18: Respect buf.yaml dependency refs (not always HEAD); fix related bug; remove prewarm logic
Goal: Three corrections to dependency resolution, shipped as one atomic pass: (1) honor the
reffield the buf CLI sends in theNamemessage so a dep likecyp/cyp-net-listeners:main/v2returns the SHA atmain/v2, not the HEAD; (2) replace thecommit != "" && commit != "main"short-circuit in both bitbucket and github providers with anisSHA(commit)gate so non-SHA inputs route through the providers' commit-fetch APIs to resolve; (3) drop theprewarmHeadsstartup fan-out and replace it with a UUID→SHA-prefix inverse function (commitUUIDInverse) that letsprobeCommitIDrecover the right module on a Download cache-miss without the prewarm.Status: Verified ✓
A
buf.yamldep likecyp/cyp-net-listeners:main/v2now returns the SHA atmain/v2, not HEAD —moduleRefplumbs the buf BSRName.ref(proto field 3) end-to-end throughparseResourceRefName→ServeHTTP/ServeGraph→ providerGetMeta. The two providers now gate onisSHA(commit)(40/64 lowercase hex) instead of thecommit != "" && commit != "main"short-circuit; non-SHA inputs route through their commit-fetch APIs. The prewarm fan-out is removed and replaced by acommitUUIDInversehelper that derives a 28-char SHA prefix from a 32-char buf-issued UUID;probeCommitIDvalidates that the source'smeta.Commitstarts with the recovered prefix (fail-closed), which closes the review.md finding #6 wrong-source-match risk.Changes
Plan 18-01: Refs respected + isSHA gate + prewarm removal
End-to-end ref support for buf.yaml deps + isSHA-gated provider ref-resolution + prewarm removal replaced by commitUUIDInverse-based probe
Key files created:
internal/providers/bitbucket/getrepo_test.go— 4 newTestGetMeta_*cases (Empty, RawSHA_40, RawSHA_64, ResolvesRef) for the Bitbucket providerinternal/providers/github/getrepo_test.go— 3 newTestGetMeta_*cases for the GitHub providerinternal/providers/github/mockrepos_test.go— newmockReposmock withGetCommitplumbing and call-count trackingKey files modified:
internal/connect/commits_helpers.go—moduleRefgainsref;parseResourceRefNamereads field 3; newisSHA,isUUID,commitUUIDInversehelpersinternal/connect/commits_helpers_test.go—TestIsSHA(8),TestIsUUID(6),TestParseResourceRefName_ReadsRef,TestParseResourceRefName_NoRef,TestCommitUUIDInverse(8)internal/connect/commits.go—ServeHTTP/ServeGraphpassref.ref;probeCommitIDrewritten withcommitUUIDInverse+ prefix-match;prewarmHeads/registerResolved/prewarm fields deletedinternal/connect/api.go—CommitResolutionlosesPrewarmEnabled/PrewarmTimeout;NewWithConfigdrops the goroutine launchinternal/connect/api_test.go—TestServeDownload_AfterRestart_ProbeResolvesUUID+TestServeDownload_AfterRestart_ProbeMissesOnUnknownUUID;mockSourceacceptsHasPrefix;TestPrewarmHeads_PopulatesCommitMapremovedinternal/connect/uuid_format_test.go— staleregisterResolvedcomment updatedinternal/providers/bitbucket/getrepo.go—getMetausesisSHA(commit)gate; newgetCommit(ctx, ref)helperinternal/providers/bitbucket/client.go— newtmplGetCommittemplate for/commits/{{.id}}internal/providers/github/getrepo.go—GetMetausesisSHA(commit)gate; non-SHA inputs route throughrepos.GetCommitcmd/easyp/internal/config/config.go—PrewarmConfigdeleted;ConnectretainsProbeonlycmd/easyp/main.go— handler factory dropscc.Prewarm.*referencesRequirements Addressed
GetCommits/GetGraphreturn UUID from ref, not HEADisSHAgateprewarmHeads,registerResolved, related fields, config blockcommitUUIDInverse+ round-trip testsVerification
go build ./...exits 0go vet ./...exits 0go test ./internal/connect/ -count=1passes (all tests, no skips)go test ./internal/providers/bitbucket/ -count=1passesgo test ./internal/providers/github/ -count=1passesTestCommitUUIDInverse(8 subtests),TestIsSHA(8),TestIsUUID(6),TestParseResourceRefName_ReadsRef,TestParseResourceRefName_NoRef,TestServeDownload_AfterRestart_ProbeResolvesUUID,TestServeDownload_AfterRestart_ProbeMissesOnUnknownUUIDTestServeHTTP_GetCommits_ReturnsDashlessUUID,TestServeDownload_RoundTripWithMintedUUID,TestCommitUUID_SHA256_KnownSHA,TestCommitUUID_KnownSHA*.gofiles):prewarmHeads/registerResolved$(old) /PrewarmConfig/PrewarmEnabled/prewarmEnabled/prewarmOnce/prewarmTimeout— 0 hitscommitUUIDInverse— 1 hitregisterResolvedAlias— 1 hitisSHA(commit)in bitbucket — 2 hitsisSHA(commit)in github — 2 hitsnum == 3 && typ == protowire.BytesType(ref field 3 parse) — 1 hitGetMeta(r.Context(), ref.owner, ref.module, ref.ref)(ServeHTTP + ServeGraph) — 2 hitsPrewarmincmd/easyp/main.goandcmd/easyp/internal/config/config.go— 0 hitsstrings.HasPrefix(meta.Commit, probeArg)(prefix-match validation) — 1 hitKey Decisions
isSHA/isUUIDare unexported in the connect package; each provider has its own 8-line localisSHA. Avoids an unexported-cross-package import path; helpers are pure functions, ~8 lines each, and the cost of one duplication is far less than the cost of exporting them and widening the public API.registerResolvedAliasis a new helper, not a rename ofregisterResolved. Takes the original client-sent id (typically a buf-issued UUID) as the primary key and the resolved SHA as the alias — matches the buf v1.69.0commit_idcontract.probeCommitIDfails closed on a prefix mismatch. A source whosemeta.Commitdoes not start with the recovered 28-char prefix is treated as a miss, not a hit. Closes review.md finding A tutorial is missing #6 (probe/register cache contract divergence): a wrong-source match would silently alias a real commit id to a wrong module and serve wrong content.probeCommitID. No upstream fan-out for unresolvable inputs. The'bogus000'fixture in Phase 16's probe tests was updated to a 40-char SHA to match the new gate.buf buildimmediately after a proxy restart will incur one extra upstream round-trip per module (the probe fan-out). TheprobeSemcap (maxConcurrentProbes=4) and per-sourceprobeTimeout(8s default) bound the worst case at4 × 8s = 32sper request in the absolute worst case; in practice the fan-out is parallel and completes in < 8s.Deviations (4 auto-fixed, all in test data/infrastructure)
TestCommitUUIDInverse— plan's fixture was off-by-two,commitUUIDrejected it. Truncated to 64 chars.TestCommitUUIDInverse— the inverse returns 14 bytes = 28 hex chars (the recoverable portion), not the full SHA. Plan's hand-derivation was off-by-four; function output is correct.TestProbeCommitID_*tests for the newisSHAgate — old fixtures ("bogus000","real") now bypass the probe via the early-return branch. Updated to 40-char lowercase hex.mockSource.GetMetato accept a SHA prefix — needed for the new post-restart probe path where the probe arg is a 28-char SHA prefix fromcommitUUIDInverse. Added!strings.HasPrefix(s.commit, commit)clause.No production code was changed beyond the plan's intent.