feat: grpc 기능 deep 구현
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
# ADR-GRPC-002: Schema governance runs without protoc and without the Buf CLI
|
||||
|
||||
- Status: accepted
|
||||
- Date: 2026-08-30
|
||||
- Scope: `:grpc:grpc-proto-contract`, `:grpc:grpc-codegen`
|
||||
|
||||
## Context
|
||||
|
||||
Stable Tasks 8 through 11 require proto style rules, Buf format/lint/breaking governance, a single
|
||||
Java codegen owner, and a descriptor artifact whose consumer-compile result gates a release.
|
||||
|
||||
Two of the tools those tasks name are absent from this toolchain. The Buf CLI is not installed. And
|
||||
`protoc` is available through the Gradle protobuf plugin, but every leaf in this repository passes
|
||||
spotless with google-java-format, checkstyle, SpotBugs at HIGH confidence, Error Prone and `-Werror`
|
||||
— and generated protobuf sources pass none of them. Turning codegen on means excluding a source set
|
||||
from five quality gates.
|
||||
|
||||
There is precedent for such an exclusion: the `jmh` source set has `spotbugsJmh` and `checkstyleJmh`
|
||||
disabled and Error Prone off. So the carve-out is available. It is also a decision about the quality
|
||||
baseline of a leaf, taken for one task, and outside what this work was asked to change.
|
||||
|
||||
`adapter:inbound:grpc` also carries a recorded decision in the opposite direction: its `CLAUDE.md`
|
||||
forbids the protobuf plugin and `.proto` in that leaf, on the grounds that a consuming feature module
|
||||
should own its schema.
|
||||
|
||||
## Decision
|
||||
|
||||
Commit the `.proto` sources and implement every rule the tasks require as executable Java, with no
|
||||
protoc run and no Buf CLI invocation.
|
||||
|
||||
`GrpcProtoContractValidator` reads `.proto` text and enforces proto3 syntax, the
|
||||
`{organization}.{domain}.v{major}` package rule, `java_multiple_files`, a generated Java package
|
||||
disjoint from the hand-written one, `_UNSPECIFIED` enum zero values, `reserved` declarations checked
|
||||
against a supplied removal history, a well-known-type allowlist and a map-field allowlist. It runs
|
||||
against the committed schema in its own test, so the shipped `.proto` files are live rather than
|
||||
decorative.
|
||||
|
||||
`GrpcBufPolicy` fixes the breaking gate at Buf's `FILE` category and names the four lifecycle stages
|
||||
a compliant pipeline registers. `GrpcCodegenManifest` fixes one codegen owner and refuses a literal
|
||||
generator version. `GrpcDescriptorArtifact`, `GrpcConsumerFixture` and `GrpcSchemaArtifactPublisher`
|
||||
carry the schema hash, the descriptor digest and the per-consumer source-break report, and refuse a
|
||||
publish that breaks a consumer or republishes a released version with different bytes.
|
||||
|
||||
The committed `buf.yaml` states the same rules, so running the CLI in an environment that has it
|
||||
reaches the same verdict.
|
||||
|
||||
## Consequences
|
||||
|
||||
**The invariants are enforced; the process is not run.** Everything Tasks 8 to 11 are about — which
|
||||
schema changes are refused, which consumer breaks block a release, who owns generation — is a
|
||||
build-checkable rule here. What is missing is the protoc invocation and the Buf binary.
|
||||
|
||||
**Turning codegen on is a bounded change.** `GrpcCodegenManifest.caSkeleton()` already names the
|
||||
owner, the managed version source, the build-directory output paths and the disjoint package policy
|
||||
that a real plugin configuration has to satisfy. The work is a source-set carve-out and a plugin
|
||||
block, not a redesign.
|
||||
|
||||
**The fixtures use a text codec.** `GrpcTextCodec` gives the testkit a UTF-8 marshaller so the
|
||||
in-process and Netty lanes can exercise interceptors, status mapping, metadata limits and stream
|
||||
sequencing without generated stubs. Those contracts are properties of the platform and the transport,
|
||||
not of any message shape, so the substitution costs nothing — and the lanes run today rather than
|
||||
after codegen lands.
|
||||
Reference in New Issue
Block a user