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>
2.9 KiB
kind, slug, title, topic, project, status, sourceRevision, rootTreeNode, verifiedOn
| kind | slug | title | topic | project | status | sourceRevision | rootTreeNode | verifiedOn |
|---|---|---|---|---|---|---|---|---|
| REFERENCE | make-the-unsafe-state-unrepresentable | 위험한 조합은 정책이 아니라 생성자가 거부하게 만든다 | commit-ambiguity-as-a-result | clean-architecture-backend-template | 게시 전 | 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916 | reference:make-the-unsafe-state-unrepresentable |
위험한 조합은 정책이 아니라 생성자가 거부하게 만든다
목적
이 조합은 하면 안 된다는 규칙을 리뷰나 정책 코드에 두어, 정책 버그가 그 조합을 만들 수 있게 남겨 두는 것을 막는다.
규칙
-
값이 존재할 수 없게 만든다 생성자가 거부하면 그 조합을 가진 값이 프로그램 안에 존재하지 않는다. 정책이 거부하면 정책을 지나치는 경로마다 같은 검사가 필요하다.
-
검사는 값 타입 안에 둔다 두 필드의 조합이 의미상 불가능한 값 타입이 대상이다. 컴팩트 생성자 한 줄이면 되고 비용이 거의 없다.
-
예외를 재구성할 때도 같은 팩토리를 지난다 컨텍스트를 다시 만드는 경로가 검사를 우회하면 방어가 반쪽이 된다. 안전 팩토리를 통해서만 재구성하게 해서 이중으로 막는다.
-
조합이 다른 객체의 상태에 의존하면 자리가 다르다 그때는 생성자가 아니라 조립 지점의 시작 검증기가 맡는다.
적용 조건
두 필드의 조합이 의미상 불가능한 모든 값 타입
이 저장소의 예 : JpaFailureContext 가 completionUnknown 과 retryable 의 동시 참을 거부한다. PublishEvidence 가 두 조합을 거부한다. GrpcExecutionEvidence 가 스트림 증거를 가진 unary 호출을 거부한다. TransactionResult.Indeterminate 가 operationId 없는 조정 참조를 거부한다.
예외
유효성이 다른 객체의 상태나 실행 시점의 설정에 의존하면 생성자 검증으로 표현되지 않는다. 조립 지점의 시작 검증기가 그 자리다.
예시
completionUnknown 이면서 retryable 인 실패 컨텍스트는 만들 수 없다. 그 조합이 존재하면 재시도 정책이 커밋됐을 수도 있는 쓰기를 재시도한다.
조정 참조가 있는데 안정적인 operationId 가 없는 불확정 결과는 만들 수 없다. 조정할 대상을 지목할 수 없는 조정 참조이기 때문이다.
관계
- 모르는 것은 성공도 실패도 아닌 세 번째 결과여야 한다 이 규칙이 지키려는 상태 어휘를 정의한다.
- completion-unknown은 자동으로도 수동으로도 재시도하지 않는다 이 규칙으로 타입 수준에서 강제되는 결정이다.
- 전송·업무·스트림 증거는 세 축이고 서로를 함의하지 않는다 같은 규칙이 gRPC 쪽에서 적용된 결정이다.