# 주제: grpc-policy 의 주요 타입이 블록 *안에서도* 대부분 쓰이지 않는다
# revision: 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916

# EVD-325 는 블록 전체가 배포되지 않는다는 사실이다. 이 파일은 그보다 안쪽의 측정이다:
# grpc-policy 가 정의한 것을 grpc 블록의 다른 리프가 쓰는가.

# command: git grep -ln "<T>" -- src/grpc src/grpc-advanced | grep -v "grpc-policy/" | wc -l
#          git grep -nE "new ([a-zA-Z0-9_.]+\.)?<T>\s*\(" -- src | grep "/src/main/" | wc -l
  타입                            다른 리프 파일   src/main 생성
  GrpcTlsProfile                       8              3      <- 널리 쓰임
  GrpcErrorMapper                      3              1
  GrpcContextBinder                    1              1
  GrpcRetryCoordinator                 0              0      <- 블록 안에서도 미사용
  GrpcIdempotencyInterceptor           0              0      <-
  GrpcResumeTokenCodec                 0              0      <-
  ProtovalidateGrpcInterceptor         0              0      <-
  GrpcCompletionReconciler             0              0      <-
  GrpcCredentialRotationManager        0              0      <-
  GrpcSerializedStreamWriter           0              0      <-
# => 표본 10개 중 7개가 자기 리프 밖 참조 0, src/main 생성 0 이다.
#    grpc-policy 는 62개 main 파일 7,581 LOC 로 블록 최대 리프인데,
#    그 대부분이 자기 테스트에서만 실행된다.

# ---- 재개 토큰의 구분자 처리 (messaging PlanDigest 와의 대비) ----
# GrpcResumeTokenCodec 은 payload 를 '|' 로 join 하고 HMAC 서명한다.
#   encode: Base64( canonicalPayload + "|" + Base64(HMAC(payload)) )
#   decode: lastIndexOf('|') 로 payload/signature 분리
#           FIELD_SEPARATOR.split(payload, -1) 의 길이가 정확히 9가 아니면 Optional.empty()
#
# GrpcResumeToken 의 String 필드 5개(streamId, snapshotVersion, callerFingerprint,
# filterFingerprint, signingKeyId)는 GrpcIdentifiers.requireBounded 로 검증되는데,
# 그 검사는 제어문자와 공백만 금지한다 — '|' 는 허용한다.
#
# 그러나 **디코드가 정확히 9개 필드를 요구하므로** 필드에 '|' 가 섞인 토큰은
# 10개 이상으로 쪼개져 거절된다. 두 다른 필드 조합이 같은 payload 문자열을 만들어도
# (예: streamId="a|b",snapshot="c" 와 streamId="a",snapshot="b|c")
# 양쪽 다 10개로 쪼개져 어느 쪽도 디코드되지 않는다.
# => fail-closed 다. 혼동이 아니라 사용 불가가 된다.
#
# 대조: messaging 의 ReplayPlan.digest()/RedrivePlan.digest() 도 String.join("|") 을 쓰지만
#       그 결과는 **해시될 뿐 디코드되지 않으므로** 개수 검사가 없다.
#       거기서는 단사성이 "자유 형식 필드가 하나뿐" 이라는 조건에 의존한다(EVD-304).
#       같은 구분자 기법이 한쪽에서는 개수 검사로 닫히고 다른 쪽에서는 우연에 의존한다.

# ---- decode 가 세 실패를 구별하지 않는 이유 ----
# GrpcResumeTokenCodec.decode javadoc:
#   "@return empty when the token is malformed, signed by an unknown key, or does not verify. The
#    three are deliberately indistinguishable to a caller: telling them apart is a probing oracle."
# 그리고 알 수 없는 key id 에 대해 현재 키로 폴백하지 않는다:
#   "A codec that retries verification with every key it holds turns key rotation into a
#    window in which a token signed by a compromised key still verifies."
