2.9 KiB
ADR-GRPC-ADV-001: Each advanced capability has its own flag, its own grade and its own promotion
- Status: accepted
- Date: 2026-08-30
- Scope:
:grpc-advanced:*
Context
The advanced plan covers sixteen capabilities that differ by orders of magnitude in what they bring with them. gRPC-Web adds a proxy. Reactor adds a dependency. xDS adds a control plane, its outage modes, its own security boundary and its own version skew. Hedging duplicates production traffic.
Bundling them under one flag makes enabling the cheapest of those the same decision as enabling the most consequential.
Decision
One flag per capability, under ca-skeleton.grpc.advanced.<capability>.enabled, all off by
default.
Four grades. ADVANCED_STABLE starts on its flag; EXPERIMENTAL additionally needs a separate
production approval, because the flag says somebody wanted the feature and the approval says somebody
accepted that its failure modes are not fully characterised; WATCH cannot start at all; DISABLED
is withdrawn.
GrpcAdvancedModuleGuard distinguishes the three refusals — flag unset, grade unstartable,
production unapproved — because the remedy differs in each case.
Promotion evidence is per capability. GrpcAdvancedPromotionEvidence is one record per
capability, so no promotion can drag another along;
GrpcAdvancedPromotionGate.capabilitiesDraggedAlong returns an empty list, and that is a tested
property rather than a claim. Two thresholds: seven days of soak plus complete evidence for
ADVANCED_STABLE, thirty for a Stable default, because the second means every deployment gets the
capability's dependencies and its failure modes.
Infrastructure is named per capability. GrpcAdvancedInfrastructureTestkit records that
gRPC-Web needs a proxy, Servlet needs a container, xDS needs a stoppable control plane and Kotlin
needs a toolchain. A suite that runs without its infrastructure passes and establishes nothing, which
is worse than not having one.
Consequences
The Kotlin adapter fails closed here, and says why. This repository has no Kotlin toolchain, so
GrpcKotlinCompatibilityGate.supportableHere() returns false. The four contract requirements — one
schema source, coroutine cancellation propagation, Flow backpressure inside the Stable bounds,
platform evidence types preserved — are checkable and are checked; only the compile lane is missing.
Edition 2026 cannot be used however its watch report reads. GrpcEdition2026Guard is not
conditional on the report, because letting a status record also authorise use means a schema moves
onto an edition the moment somebody marks four fields SUPPORTED, with no promotion decision, no
consumer migration and no ADR.
xDS is not part of the Stable support statement. It works, behind its flag and its approval;
GrpcXdsStartupGuard.advertisableAsStableSupport() returns false so a support matrix cannot widen
quietly.