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>
62 lines
3.1 KiB
Markdown
62 lines
3.1 KiB
Markdown
---
|
|
kind: REFERENCE
|
|
slug: walk-the-cause-chain-most-specific-wins
|
|
title: 원인 사슬은 가장 구체적인 분류가 이기도록 순회한다
|
|
topic: http-failure-classification
|
|
project: clean-architecture-backend-template
|
|
status: 게시 전
|
|
sourceRevision: 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916
|
|
rootTreeNode: reference:walk-the-cause-chain-most-specific-wins
|
|
verifiedOn: # 이 기록은 이번 회차에 실행 확인을 하지 않았다
|
|
note: 이 규칙을 처음 끌어낸 사례는 나중에 철회되었다. httpclient 의 mTLS 테스트 3건이 실패한 원인은 분기 순서가 아니라 테스트 픽스처의 호스트명이었고, 그 저장소의 분류기는 이 실패의 사례가 아니다. 규칙 자체는 다른 근거로 유효하다.
|
|
---
|
|
|
|
# 원인 사슬은 가장 구체적인 분류가 이기도록 순회한다
|
|
|
|
## 목적
|
|
|
|
라이브러리가 구체적 원인을 일반적 예외로 감쌌을 때, 바깥 타입만 보고 분류해서 정확한 판정을 잃는 것을 막는다.
|
|
|
|
## 규칙
|
|
|
|
1. 바깥 타입 하나로 분류하지 않는다
|
|
Spring 이 엔진 예외를 감싸고 드라이버가 자기 예외를 다시 감싼다. 바깥 타입만 매칭하면 증명 가능한 판정이 모호한 판정으로 내려간다.
|
|
|
|
2. 기준은 순서가 아니라 구체성이다
|
|
이 사슬에서 가장 구체적인 분류가 이기는가를 묻는다. 구현은 두 가지다. 구체적 분기를 앞으로 옮기거나, 사슬 전체를 훑어 최선의 매치를 고른다.
|
|
|
|
3. 사이클 안전을 확보한다
|
|
이미 본 예외를 IdentityHashMap 으로 표시하거나 최대 깊이를 둔다. 순환 참조는 실제로 나타난다.
|
|
|
|
4. 벤더별 곁가지를 따라간다
|
|
getCause 만으로는 부족하다. SQLException 의 getNextException 처럼 벤더가 따로 두는 연결 고리가 있다.
|
|
|
|
5. 이 규칙이 실패의 원인이 아닐 수도 있다
|
|
잘못된 분류를 봤을 때 순서를 의심하기 전에, 그 원인이 사슬에 실제로 있는지 먼저 확인한다.
|
|
|
|
## 적용 조건
|
|
|
|
드라이버나 클라이언트 예외를 자기 범주로 번역하는 모든 분류기
|
|
|
|
특히 전송 계층 : 감싸기가 흔하다
|
|
|
|
## 예외
|
|
|
|
바깥 예외가 실제로 더 구체적인 경우가 있다. 그때는 순서가 아니라 우선순위 표가 필요하고, 그 표를 테스트로 고정해야 한다.
|
|
|
|
## 예시
|
|
|
|
이 저장소의 mongo 실패 추출기와 bulk 실패 추출기는 IdentityHashMap 으로 방문 표시를 두고 사슬을 훑는다.
|
|
|
|
jpa 의 SQL 상태 해석기는 getNextException 을 따라간다.
|
|
|
|
httpclient 의 분류기는 사슬 전체를 훑는다. 주석이 이유를 적는다. 감싸인 ConnectException 도 요청이 전송되지 않았음을 증명하므로, 바깥 타입만 매칭하면 증명 가능한 NOT_SENT 를 모호한 SENT_NO_RESPONSE 로 낮추게 된다.
|
|
|
|
## 관계
|
|
|
|
- **분류기는 엔진이 남긴 것만 볼 수 있다**
|
|
이 규칙의 상한을 정한다. 사슬에 없는 원인은 어떤 순회로도 분류되지 않는다.
|
|
- **붉은 테스트를 제품 결함으로 읽은 오진**
|
|
이 규칙을 잘못 적용한 기록이다.
|
|
|