Repository navigation
Conversation
Add scripts/checkprotocolversion, which compares the worktree with a base commit and fails when: - pkg/grpcprotocol.Version decreases or moves by more than one; - buf breaking (WIRE, SERVICE_NO_DELETE, RPC_NO_DELETE) reports a change on a type reachable from BucketService, ClusterService or RestoreService without a +1 revision. Findings on Raft-only or persisted-only messages are ignored by walking the gated services' type graph. The check runs in the invariants workflow for pull requests and merge-queue entries, and in agent-check-pr when misc/proto or pkg/grpcprotocol changes. buf joins the ci shell and is used only for classification; code generation stays on protoc. Claude-Session: https://claude.ai/code/session_01HxBUjBS5Loz1nkQZVxW1Mf
| # pull_request checks out the merge commit, so comparing with the | ||
| # current target tip also catches a revision another PR consumed. | ||
| PROTOCOL_BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.merge_group.base_sha }} | ||
| run: nix develop .#ci --command go run ./scripts/checkprotocolversion --base "$PROTOCOL_BASE_SHA" |
There was a problem hiding this comment.
🟡 [minor] Expose the protocol check through a shared Just recipe
The new CI step invokes go run directly rather than a Just task. RFC-0015 requires CI checks to use the shared Nix → Just task interface; the local gate also duplicates this invocation, leaving two entry points to maintain.
Suggestion: Add a parameterized protocol-revision recipe and invoke it from CI with nix develop --impure .#ci --command just <recipe> "$PROTOCOL_BASE_SHA"; use the same recipe from the local gate.
…o poc/protocol-version-buf-check
The service protocol revision is frozen during the v3 release-candidate phase (#2298). Switch checkprotocolversion from "bump on break" to the freeze: - any change to pkg/grpcprotocol.Version fails; - any buf WIRE/SERVICE_NO_DELETE/RPC_NO_DELETE finding on a type reachable from a gated service fails, and a bump no longer excuses it. Added fields and wire-compatible widenings such as int32 to int64 pass; Raft-only and persisted-only messages stay out of scope. The docs scope the "remove and realign" rule to those internal messages. Claude-Session: https://claude.ai/code/session_01HxBUjBS5Loz1nkQZVxW1Mf
| # pull_request checks out the merge commit, so comparing with the | ||
| # current target tip also catches a revision another PR consumed. | ||
| PROTOCOL_BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.merge_group.base_sha }} | ||
| run: nix develop .#ci --command go run ./scripts/checkprotocolversion --base "$PROTOCOL_BASE_SHA" |
There was a problem hiding this comment.
[P1][blocking] Make the protocol gate a required merge check
I changed GetLedgerRequest.ledger from string to int64 in an isolated checkout: checkprotocolversion correctly failed with FIELD_WIRE_COMPATIBLE_TYPE. But the effective GitHub rules for main require only Tests and Dirty, not invariants; the current target branch fix/grpcprotocol-back-to-40 has no effective rules. Thus a PR with a detected breaking change can still become mergeable once it leaves draft. Require invariants on every protected merge target, or run this gate inside an already required check, and verify that a failing protocol check blocks merge.
|
[P2][blocking] Re-run the protocol check when the PR base changes
|
Summary
#2298 freezes
pkg/grpcprotocol.Versionduring the v3 release-candidate phase: service gRPC contract changes must stay compatible instead of bumping the revision. Until now this rule relied only on review. This PR enforces its wire part deterministically.go run ./scripts/checkprotocolversion --base <sha>fails when:Versiondiffers from the base, in either direction.buf breaking(WIRE,SERVICE_NO_DELETE,RPC_NO_DELETE, seemisc/proto/buf.yaml) reports a finding on a type reachable fromBucketService,ClusterServiceorRestoreService. A revision bump does not excuse it.int32→int64(same varint wire type)VersionScope follows #2298: persisted and Raft-only messages keep the unreleased-v3 "remove and realign" rule. A finding is attributed to its innermost enclosing declaration; one that cannot be attributed counts when its file declares a gated type (conservative).
Semantic changes that keep the
.prototext unchanged are not detected and remain a review classification.Wiring
.github/workflows/invariants.yml: new step forpull_requestandmerge_group, compared with the target tip (the PR checkout is the merge commit).scripts/agent-check-pr:protocol-revisiongate whenmisc/proto/**orpkg/grpcprotocol/**changes.flake.nix:bufadded to thecishell (1.72, pinned by the existingflake.lock). Code generation stays onprotoc.protocol-compatibility.md;protobuf.mdscopes "remove and realign" to persisted and Raft-only messages, which answers the point left open in fix(grpcprotocol): freeze service protocol revision at 40 during RC #2298.Historical replay
Replayed on the 51 commits that touched
misc/protoorpkg/grpcprotocolsince the revision was introduced. Under the previous "bump on break" rule,buffound gated wire breaks without a bump in70eb1d0c0(#1933,CreatedIndexLogbool ↔ enum swap) and23ea97c7f(#2169,LedgerLogfield deletion), and correctly ignored internal-only breaks in0dfa940deanda98bed9da. Under the freeze, every historical bump would also fail, as intended.Open decision
Repository Invariantsis not a required status check today (onlyTestsandDirtyare). The check blocks merges only after a ruleset change, or if it moves into theDirtyjob.Validation
bash scripts/agent-check: PASSgo test -race ./scripts/checkprotocolversion ./scripts/agentcheckpr: PASS. End-to-end cases drive realgitandbufon a throwaway repository: addition,int32→int64, retype, deletion, RPC removal, bump, internal-only break.golangci-lint run ./scripts/checkprotocolversion/...: 0 issuescheckprotocolversion --base origin/fix/grpcprotocol-back-to-40: PASS;--base origin/main: FAIL on 41 → 40, as expectedhttps://claude.ai/code/session_01HxBUjBS5Loz1nkQZVxW1Mf