Files
document-haness/docs/clean-architecture-backend-template/tech-log-studio/grpc-and-streaming/case/case-analysis-finding-a15-f002.md
T
DongHyeonkaandClaude Opus 5 b2963105a8 docs(keycloak-session-store): import the session-storage lab as a new project
The keycloak project ended with four open questions that design could not
settle. A two-VM lab was built to answer them by measurement, and this is
that material: 26 experiments, 125 raw command outputs, 22 browser captures.

Follows the import procedure in README.md.

  source/     the originating repository verbatim — 78 documents, 28 SVGs,
              8 manifests, plus .source-revision recording the commit
  final/      the SSOT
    document.md   729 lines written from the 29 experiment documents, not
                  concatenated: what was predicted, what was measured, and
                  where the measurement itself was wrong
    evidence/raw    125 outputs, flattened to <experiment>__<file> because
                    the originals collided (01-baseline.txt appeared three
                    times) and the audit only globs the top level
    evidence/meta   one per raw file; command and exitCode are null and the
                    README says why rather than inventing them
    evidence/browser  22 captures
    assets/       three diagrams through techviz
    .techviz/     their VizSpecs

A separate project rather than an addition to keycloak: the B-layer answers
that project's four questions, but the A, C and D layers are about cluster
failure, SSO and operations, and one document.md should hold one subject.
The four question records there can point here through 관계.

Recorded rather than papered over: only three of the 28 diagrams were
remade. The repository forbids hand-drawn SVG and forbids titles inside the
canvas; all 28 originals carry both, so converting them is redrawing, not
reformatting. They stay in source/ and the gap is written into the document.

verify-pipeline.py passes. audit-records.py reports no issues.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 22:51:59 +09:00

5.2 KiB

kind, slug, title, topic, project, status, sourceRevision, rootTreeNode, evidenceCapturedOn, body, assets, evidence, source
kind slug title topic project status sourceRevision rootTreeNode evidenceCapturedOn body assets evidence source
CASE analysis-finding-a15-f002 설정 바인딩이 마스터 스위치 밖에서 일어난다. 컴포지션 루트의 자기 규칙과 어긋난다 grpc-and-streaming clean-architecture-backend-template 게시 전 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916 case:analysis-finding-a15-f002 2026-09-01 case-analysis-finding-a15-f002.body.md
key file
analysis-finding-a15-f002 ../../../final/evidence/rendered/analysis-finding-a15-f002.svg
../../../final/evidence/raw/analysis-finding-a15-f002.txt
원본 분석 절은 analysis/15-adapter-inbound-grpc.md#L187 이다.

설정 바인딩이 마스터 스위치 밖에서 일어난다. 컴포지션 루트의 자기 규칙과 어긋난다

설정 객체가 두 경로로 등록된다. 게이트 안쪽의 명시적 활성화와 게이트 바깥의 전역 훑기다. 후자가 있으면 마스터 스위치와 무관하게 결속이 일어난다. 조립 루트의 자바독이 과거에 같은 비대칭이 만든 사고를 기록한다.

관계

  • 원인 사슬 순회가 2-순환에서 무한 루프에 빠지고 저장소는 이미 그 사례를 이름으로 적어 두었다 같은 리프의 다른 사례다.
  • 지금 안전한 것은 규칙이 지켜져서가 아니라 기본값이 유효해서다 이 사례가 그 규칙의 형태다.
  • 문서가 선언한 경계는 코드가 닫아야 경계다 같은 계열의 규칙이다.

문제

이 리프의 설정 객체가 마스터 스위치 뒤에 있어야 한다.

등록 경로를 확인했다.

결론

두 경로가 있다.

하나는 리프 설정 클래스의 명시적 활성화다. 게이트 안쪽이다.

다른 하나는 조립 루트의 전역 설정 훑기다. 게이트 바깥이다.

후자가 있으면 마스터 스위치와 무관하게 결속이 일어난다.

조립 루트의 자바독이 이 구조가 과거에 만든 사고를 기록한다.

이전에 있던 비대칭이 문제였다는 것이다. 빈은 게이트를 받고 설정은 받지 않았기 때문에, 알림 마스터가 꺼진 배포에서 알림 설정 객체가 스스로 결속했다는 것이다.

그리고 그 교훈을 다섯 선택 어댑터에 적용하면서 이 리프를 포함한 셋은 목록에 남겼다.

지금 이 리프에서는 무해하다.

검증이 전부 게이트를 존중하거나 안전한 기본값을 갖는다.

지역 비보안 설정 검증은 비활성일 때 즉시 참이 된다. 포트 범위 검증과 결속 주소 검증과 종료 유예 검증은 모두 유효한 기본값을 가진다.

부작용은 두 가지뿐이다.

비활성 배포에서도 속성 빈이 만들어진다. 그리고 미지 필드 거부가 켜져 있으므로 이 이름공간 아래 오타 하나가 이 기능을 쓰지 않는 배포의 부팅을 실패시킨다.

둘째는 오히려 바람직한 쪽에 가깝다.

기록하는 이유는 규칙과 적용이 갈린다는 점이다.

같은 자바독이 이 목록에 패키지를 되돌리면 결속이 복원되어 게이트를 조용히 무효화한다고 경고하고, 이 패키지가 그 목록에 있다.

지금 이 리프가 안전한 것은 규칙이 지켜져서가 아니라 기본값이 전부 유효하기 때문이고, 새 검증이 하나 추가되면 그 보호막이 사라진다.

판정은 P3 다.

검증 환경

Spring Boot : 4.0.8 확인 방식 : 등록 경로 대조와 검증 애너테이션 확인 소스 수정 : x

재현 조건

원문은 final/evidence/raw/179 계열에 있다.

  1. 설정 객체의 등록 경로를 모두 찾는다.
  2. 각 경로가 게이트 안쪽인지 바깥인지 확인한다.
  3. 조립 루트의 자바독을 읽는다.
  4. 그 자바독이 든 목록에 이 패키지가 있는지 확인한다.
  5. 설정 객체의 검증 애너테이션과 기본값을 확인한다.

본문

GrpcServerProperties는 두 경로로 등록된다 — GrpcServerConfig@EnableConfigurationProperties(게이트 안쪽)와 CaSkeletonApplication@ConfigurationPropertiesScan(게이트 바깥). 후자가 있으면 ca-skeleton.grpc.enabled와 무관하게 바인딩이 일어난다(§3.4).

GrpcServerProperties 참조 위치

:::evidence key="analysis-finding-a15-f002" alt="코드베이스에서 GrpcServerProperties 를 검색한 출력 4줄. 이 기록이 세는 참조가 그 출력에 그대로 보인다." caption="GrpcServerProperties 코드베이스 검색 — 4줄 · exit 0" zoom="true" :::

컴포지션 루트가 이 형태를 사고로 기록했다

CaSkeletonApplication의 javadoc — "The asymmetry that existed before — beans gated, settings not — is why a notification settings object bound itself in a deployment whose notification master was off." 그 교훈을 다섯 optional 어댑터에 적용하면서 grpc·web·websocket은 목록에 남겼다.

지금 이 leaf에서는 무해하다

검증이 전부 게이트를 존중하거나 안전한 기본값을 갖는다. P3.

확인하지 못한 것

마스터 스위치를 끄고 띄워 속성 빈이 만들어지는 것을 확인하지 않았다. 등록 경로상 그 결과가 나온다.