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>
This commit is contained in:
co-authored by
Claude Opus 5
parent
43bccd08a8
commit
b2963105a8
+60
@@ -0,0 +1,60 @@
|
||||
---
|
||||
kind: QUESTION
|
||||
slug: a02-f001-lro
|
||||
title: response/LRO invariant enforcement boundary
|
||||
topic: multitenancy-isolation
|
||||
project: clean-architecture-backend-template
|
||||
status: 게시 전
|
||||
sourceRevision: 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916
|
||||
rootTreeNode: open-question:a02-f001-lro
|
||||
questionStatus: OPEN
|
||||
verifiedOn: # 이 기록은 이번 회차에 실행 확인을 하지 않았다
|
||||
---
|
||||
|
||||
# response/LRO invariant enforcement boundary
|
||||
|
||||
응답 봉투 계열 타입의 유효한 형태가 팩토리 테스트에는 고정되어 있고 공개 정규 생성자에서는 강제되지 않는다. 생성자를 확장 표면으로 둘 것인지 결정이 필요하다.
|
||||
|
||||
## 사실
|
||||
|
||||
봉투와 벌크 봉투와 연산과 페이지 메타의 유효한 형태가 팩토리 테스트에 고정되어 있다.
|
||||
|
||||
공개 정규 생성자는 그 불변식을 강제하지 않는다.
|
||||
|
||||
## 가정
|
||||
|
||||
정규 생성자가 외부에서 호출되지 않을 것이라고 암묵적으로 전제하고 있다. 그 전제가 확인되지 않았다.
|
||||
|
||||
## 미지수
|
||||
|
||||
원시 생성자가 의도된 확장 표면인가.
|
||||
|
||||
유효하지 않은 상태를 생성자에서 차단해야 하는가.
|
||||
|
||||
## 제약
|
||||
|
||||
이 타입들은 공유 계약 계층에 있으므로 변경이 여러 어댑터에 영향을 준다.
|
||||
|
||||
## 선택지
|
||||
|
||||
생성자에 불변식을 넣는다
|
||||
팩토리와 같은 규칙이 적용되고 유효하지 않은 값이 존재할 수 없다. 확장 표면이 좁아진다.
|
||||
|
||||
확장 표면으로 유지하고 문서화한다
|
||||
허용 범위와 실패 의미를 계약에 적는다. 유효하지 않은 값이 만들어질 수 있다는 것을 받아들인다.
|
||||
|
||||
## 다음 검증
|
||||
|
||||
프로덕션에서 원시 생성자를 호출하는 곳을 전수 확인한다. 그리고 유효하지 않은 형태의 생성자 테스트를 추가해 현재 허용 표면을 고정한다.
|
||||
|
||||
원시 생성자가 외부 확장 계약이면 허용 범위와 실패 의미를 문서화한다.
|
||||
|
||||
그렇지 않으면 생성자 수준 불변식을 추가하고 팩토리와 같은 규칙을 검증한다.
|
||||
|
||||
## 관계
|
||||
|
||||
- **위험한 조합은 정책이 아니라 생성자가 거부하게 만든다**
|
||||
이 질문이 선택할 수 있는 한쪽 방향의 규칙이다.
|
||||
- **모르는 것은 성공도 실패도 아닌 세 번째 결과여야 한다**
|
||||
같은 계약 계층의 상태 어휘 원칙이다.
|
||||
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
---
|
||||
kind: QUESTION
|
||||
slug: a02-f002-domaincontextkey
|
||||
title: DomainContextKey same-name different-type collision
|
||||
topic: multitenancy-isolation
|
||||
project: clean-architecture-backend-template
|
||||
status: 게시 전
|
||||
sourceRevision: 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916
|
||||
rootTreeNode: open-question:a02-f002-domaincontextkey
|
||||
questionStatus: OPEN
|
||||
verifiedOn: # 이 기록은 이번 회차에 실행 확인을 하지 않았다
|
||||
---
|
||||
|
||||
# DomainContextKey same-name different-type collision
|
||||
|
||||
컨텍스트 키의 신원이 이름뿐인데 조회는 요청된 타입으로 캐스팅한다. 같은 이름의 다른 타입 키를 선언하는 것이 금지인지 허용인지 정해져 있지 않다.
|
||||
|
||||
## 사실
|
||||
|
||||
키의 신원은 이름만으로 정해진다.
|
||||
|
||||
조회는 요청된 타입으로 캐스팅한다.
|
||||
|
||||
## 가정
|
||||
|
||||
같은 이름의 키가 하나뿐일 것이라고 전제하고 있다. 그 전제를 강제하는 것이 없다.
|
||||
|
||||
## 미지수
|
||||
|
||||
같은 이름의 다른 타입 키 선언이 금지된 계약인가.
|
||||
|
||||
허용이라면 캐스팅 실패의 의미가 무엇인가.
|
||||
|
||||
## 제약
|
||||
|
||||
키 선언이 여러 모듈에 흩어져 있으면 생성 시점 충돌 탐지가 전역 레지스트리를 요구한다.
|
||||
|
||||
## 선택지
|
||||
|
||||
생성이나 등록 단계에서 충돌을 거부한다
|
||||
같은 이름이 두 번 선언되면 실패한다. 전역 레지스트리가 필요하다.
|
||||
|
||||
허용하고 실패 의미를 문서화한다
|
||||
캐스팅 실패가 언제 어떤 형태로 나타나는지 계약에 적는다.
|
||||
|
||||
## 다음 검증
|
||||
|
||||
같은 이름에 다른 타입을 갖는 키 픽스처를 만들고 생성과 조회의 실패를 고정한다. 그다음 레지스트리의 실제 키 선언을 전수 대조한다.
|
||||
|
||||
같은 이름 다른 타입이 금지라면 생성이나 등록 단계에서 충돌을 거부한다.
|
||||
|
||||
허용이라면 캐스팅 실패 의미와 사용 조건을 계약에 명시한다.
|
||||
|
||||
## 관계
|
||||
|
||||
- **이름은 값이 아니라 registry key다**
|
||||
이 질문이 다루는 이름의 성질이다.
|
||||
- **위험한 조합은 정책이 아니라 생성자가 거부하게 만든다**
|
||||
한쪽 방향의 구현 규칙이다.
|
||||
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
---
|
||||
kind: QUESTION
|
||||
slug: a05-f003-capabilitysupport-constraints
|
||||
title: CapabilitySupport.constraints 의 경계가 타입에 없다
|
||||
topic: multitenancy-isolation
|
||||
project: clean-architecture-backend-template
|
||||
status: 게시 전
|
||||
sourceRevision: 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916
|
||||
rootTreeNode: open-question:a05-f003-capabilitysupport-constraints
|
||||
questionStatus: OPEN
|
||||
verifiedOn: # 이 기록은 이번 회차에 실행 확인을 하지 않았다
|
||||
---
|
||||
|
||||
# CapabilitySupport.constraints 의 경계가 타입에 없다
|
||||
|
||||
능력 선언의 제약 목록이 경계가 있다고 서술되지만 십만 자 문자열도 받아들인다. 그 목록은 액추에이터 리포트 모델에 포함된다.
|
||||
|
||||
## 사실
|
||||
|
||||
십만 자 제약 문자열이 받아들여진다.
|
||||
|
||||
능력 목록은 플랫폼 리포트를 통해 액추에이터 엔드포인트 모델에 포함된다.
|
||||
|
||||
현재 출하 조립은 짧은 정적 리터럴만 만든다.
|
||||
|
||||
## 가정
|
||||
|
||||
외부나 동적 생산자가 임의 제약을 넣지 않을 것이라고 전제하고 있다. 그 전제를 확인하지 않았다.
|
||||
|
||||
## 미지수
|
||||
|
||||
외부나 포크나 동적 생산자가 공개 API 에 임의 제약을 넣는 실제 경로가 있는가.
|
||||
|
||||
경계를 타입이 소유해야 하는가 리포트 투영이 소유해야 하는가.
|
||||
|
||||
## 제약
|
||||
|
||||
현재 조립에서는 사고가 아니다. 공개 API 불변식의 공백이며, 포크나 동적 조립에서는 경계가 호출자 규율에 의존한다.
|
||||
|
||||
## 선택지
|
||||
|
||||
타입 수준 최대 길이나 어휘를 강제한다
|
||||
공개 API 를 쓰는 모든 생산자에 적용된다.
|
||||
|
||||
리포트 투영에서 경계를 건다
|
||||
공개되는 지점에서만 자른다. 값 자체는 자유롭다.
|
||||
|
||||
## 다음 검증
|
||||
|
||||
공개 API 의 외부 생산자와 포크 확장점을 추적하고, 과대 제약에 대한 생성자와 리포트 경계 테스트를 추가한다.
|
||||
|
||||
동적이나 외부 생산자가 확인되면 경계를 타입이나 리포트 투영에서 강제하고 이 항목을 Case 로 승격한다.
|
||||
|
||||
없다면 공개 불변식과 문서를 현재 조립의 보장 수준으로 좁힌다.
|
||||
|
||||
## 관계
|
||||
|
||||
- **진단 리포트가 살아 있는 리소스를 담지 않도록 값 타입을 좁혔다**
|
||||
같은 값 타입의 다른 제약이다.
|
||||
- **관측을 위해 수집한 데이터가 관측 대상보다 위험할 수 있다**
|
||||
리포트로 공개되는 값의 성질이다.
|
||||
- **카디널리티 경계를 타입으로 표현하기**
|
||||
경계를 타입에 두는 같은 계열의 개념이다.
|
||||
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
---
|
||||
kind: QUESTION
|
||||
slug: analysis-finding-a02-f003
|
||||
title: bounded operational record identifiers
|
||||
topic: multitenancy-isolation
|
||||
project: clean-architecture-backend-template
|
||||
status: 게시 전
|
||||
sourceRevision: 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916
|
||||
rootTreeNode: open-question:analysis-finding-a02-f003
|
||||
questionStatus: OPEN
|
||||
verifiedOn: # 이 기록은 이번 회차에 실행 확인을 하지 않았다
|
||||
---
|
||||
|
||||
# bounded operational record identifiers
|
||||
|
||||
운영 레코드의 네임스페이스와 키가 경계가 있다고 문서에 적혀 있는데, 생성자는 공백 여부만 확인한다. 그 경계를 공유 계약이 소유할지 어댑터가 소유할지 정해지지 않았다.
|
||||
|
||||
## 사실
|
||||
|
||||
운영 레코드 문서가 네임스페이스와 키를 경계가 있는 값으로 설명한다.
|
||||
|
||||
생성자는 공백 여부만 확인한다.
|
||||
|
||||
## 가정
|
||||
|
||||
각 어댑터가 자기 제공자의 제한을 알아서 지킬 것이라고 전제하고 있다. 그 전제를 확인하지 않았다.
|
||||
|
||||
## 미지수
|
||||
|
||||
제공자별 키 크기와 문자 집합 제한을 공유 계약이 소유해야 하는가 어댑터가 소유해야 하는가.
|
||||
|
||||
여러 제공자가 공통으로 요구하는 최소 경계가 있는가.
|
||||
|
||||
## 제약
|
||||
|
||||
공유 계약이 특정 제공자의 제한을 담으면 그 계약이 제공자에 묶인다.
|
||||
|
||||
어댑터가 각자 검증하면 같은 검사가 여러 곳에 생긴다.
|
||||
|
||||
## 선택지
|
||||
|
||||
공유 값 객체에서 공통 최소 경계를 강제한다
|
||||
여러 제공자가 공통 최소 경계를 요구하면 이쪽이 맞다.
|
||||
|
||||
공유 문서를 좁히고 어댑터 경계에서 검증한다
|
||||
제한이 제공자별이면 공유 계약은 경계를 주장하지 않는 편이 정확하다.
|
||||
|
||||
## 다음 검증
|
||||
|
||||
실제 제공자와 어댑터의 식별자 제한을 조사하고 프로덕션 생성 지점과 대조한다. 경계값 픽스처를 추가한다.
|
||||
|
||||
여러 제공자가 공통 최소 경계를 요구하면 공유 값 객체에서 강제한다.
|
||||
|
||||
제공자별이면 공유 문서의 표현을 좁히고 어댑터 경계에서 검증한다.
|
||||
|
||||
## 관계
|
||||
|
||||
- **카디널리티 경계를 타입으로 표현하기**
|
||||
경계를 타입으로 표현하는 같은 계열의 개념이다.
|
||||
- **위험한 조합은 정책이 아니라 생성자가 거부하게 만든다**
|
||||
값 타입에서 강제하는 방향의 규칙이다.
|
||||
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
---
|
||||
kind: QUESTION
|
||||
slug: analysis-finding-a02-f004
|
||||
title: permission component grammar
|
||||
topic: multitenancy-isolation
|
||||
project: clean-architecture-backend-template
|
||||
status: 게시 전
|
||||
sourceRevision: 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916
|
||||
rootTreeNode: open-question:analysis-finding-a02-f004
|
||||
questionStatus: OPEN
|
||||
verifiedOn: # 이 기록은 이번 회차에 실행 확인을 하지 않았다
|
||||
---
|
||||
|
||||
# permission component grammar
|
||||
|
||||
권한 값은 콜론 구분 세그먼트 수와 공백과 정규화를 강제하지만 세그먼트의 문자 문법은 제한하지 않는다. 레지스트리가 더 좁은 문법을 실제 정본으로 쓰는지 확인되지 않았다.
|
||||
|
||||
## 사실
|
||||
|
||||
권한 값 객체가 강제하는 것은 세 가지다. 콜론 세그먼트 수와 공백 여부와 정규화다.
|
||||
|
||||
세그먼트의 문자 문법은 제한하지 않는다.
|
||||
|
||||
## 가정
|
||||
|
||||
레지스트리의 권한 리터럴이 공유 값 객체가 허용하는 범위 안에 있을 것이라고 전제하고 있다. 반대 방향은 확인하지 않았다.
|
||||
|
||||
## 미지수
|
||||
|
||||
레지스트리 정본이 공유 값 객체보다 좁은 문자 문법을 계약으로 요구하는가.
|
||||
|
||||
## 제약
|
||||
|
||||
공유 값 객체를 좁히면 기존 권한 리터럴 중 일부가 무효가 될 수 있다.
|
||||
|
||||
## 선택지
|
||||
|
||||
공유 값 객체가 레지스트리와 같은 문법을 강제한다
|
||||
레지스트리가 더 좁은 문법을 실제 정본으로 쓰면 이쪽이 맞다. 패리티 테스트로 두 쪽을 고정한다.
|
||||
|
||||
현재의 넓은 문법이 의도임을 문서화한다
|
||||
레지스트리가 관행으로만 좁게 쓰는 것이면 이쪽이다.
|
||||
|
||||
## 다음 검증
|
||||
|
||||
레지스트리의 모든 권한 리터럴을 수집해 허용 문자 집합을 만들고, 공유 파서와 패리티 테스트로 대조한다.
|
||||
|
||||
레지스트리가 더 좁은 문법을 실제 정본으로 쓰면 공유 값 객체가 같은 문법을 강제한다.
|
||||
|
||||
아니면 현재의 넓은 문법이 의도임을 문서화한다.
|
||||
|
||||
## 관계
|
||||
|
||||
- **이름은 값이 아니라 registry key다**
|
||||
권한 값이 등록된 것인지 자유 문자열인지의 문제다.
|
||||
- **문서와 상수가 서로 일치하는 것으로는 아무것도 증명되지 않는다**
|
||||
패리티 테스트가 필요한 이유다.
|
||||
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
---
|
||||
kind: QUESTION
|
||||
slug: analysis-finding-a02-f005
|
||||
title: messaging schema qualification boundary
|
||||
topic: multitenancy-isolation
|
||||
project: clean-architecture-backend-template
|
||||
status: 게시 전
|
||||
sourceRevision: 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916
|
||||
rootTreeNode: open-question:analysis-finding-a02-f005
|
||||
questionStatus: OPEN
|
||||
verifiedOn: # 이 기록은 이번 회차에 실행 확인을 하지 않았다
|
||||
---
|
||||
|
||||
# messaging schema qualification boundary
|
||||
|
||||
현재 검사는 JDK 만으로 자원과 다이제스트와 선택된 의미 벡터를 검증한다. 실제 JSON 스키마 검증기와의 호환성은 그 검사만으로 주장할 수 없다.
|
||||
|
||||
## 사실
|
||||
|
||||
현재 테스트는 JDK 만 쓴다. 정확한 자원과 다이제스트와 선택된 의미 벡터를 검증한다.
|
||||
|
||||
그 테스트는 통과한다.
|
||||
|
||||
## 가정
|
||||
|
||||
JDK 만으로 만든 의미 벡터가 실제 검증기의 해석과 같을 것이라고 전제하고 있다. 그 전제가 확인되지 않았다.
|
||||
|
||||
## 미지수
|
||||
|
||||
채택할 검증기가 커밋된 스키마와 긍정 부정 벡터를 동일하게 해석하는가.
|
||||
|
||||
## 제약
|
||||
|
||||
검증기를 테스트 클래스패스에 추가하면 이 리프의 의존이 늘어난다. 프레임워크 없는 계약 리프를 유지하려는 방침과 충돌할 수 있다.
|
||||
|
||||
## 선택지
|
||||
|
||||
별도 소스셋이나 레인에서 실제 검증기로 실행한다
|
||||
리프의 기본 의존을 늘리지 않으면서 증거를 만든다.
|
||||
|
||||
현재 상태를 유지하고 표현을 좁힌다
|
||||
JDK 만으로 확인한 것이 무엇인지 문서에 적고 호환성 주장을 하지 않는다.
|
||||
|
||||
## 다음 검증
|
||||
|
||||
채택할 검증기로 커밋된 스키마와 긍정 부정 벡터를 실행하고 결과를 증거로 남긴다.
|
||||
|
||||
실제 검증기가 동일한 의미 벡터를 통과해야 호환성을 주장한다.
|
||||
|
||||
실패하면 스키마나 지원 범위를 수정하고 JDK 전용 게이트의 표현을 좁힌다.
|
||||
|
||||
## 관계
|
||||
|
||||
- **문서와 상수가 서로 일치하는 것으로는 아무것도 증명되지 않는다**
|
||||
이 질문이 다루는 증거의 성질이다.
|
||||
- **능력 등급은 코드가 아니라 실행된 증거에서 파생한다**
|
||||
호환성 주장에 증거가 필요한 이유다.
|
||||
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
---
|
||||
kind: QUESTION
|
||||
slug: analysis-finding-a03-f002
|
||||
title: notification derived idempotency key가 32-bit hash
|
||||
topic: multitenancy-isolation
|
||||
project: clean-architecture-backend-template
|
||||
status: 게시 전
|
||||
sourceRevision: 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916
|
||||
rootTreeNode: open-question:analysis-finding-a03-f002
|
||||
questionStatus: OPEN
|
||||
verifiedOn: # 이 기록은 이번 회차에 실행 확인을 하지 않았다
|
||||
---
|
||||
|
||||
# notification derived idempotency key가 32-bit hash
|
||||
|
||||
멱등성 키가 주어지지 않았을 때 쓰는 대체 키가 32비트 해시다. 서로 다른 요청의 충돌을 배제할 수 없어 문서의 강한 유일성 표현과 실제 보장이 맞지 않는다.
|
||||
|
||||
## 사실
|
||||
|
||||
대체 키는 표준 라이브러리 해시를 16진수 문자열로 만든 값이다. 32비트다.
|
||||
|
||||
정규 지문 비교가 별도로 존재한다.
|
||||
|
||||
## 가정
|
||||
|
||||
32비트 공간에서 실제 요청들이 충돌하지 않을 것이라고 전제하고 있다. 그 전제를 확인하지 않았다.
|
||||
|
||||
## 미지수
|
||||
|
||||
서로 다른 정규 요청이 같은 대체 키를 만들 수 있는가.
|
||||
|
||||
만들 수 있다면 하류가 잘못된 충돌로 끝나는가.
|
||||
|
||||
이 위험을 허용할 것인가.
|
||||
|
||||
## 제약
|
||||
|
||||
정규 지문 비교가 있으므로 조용한 수렴보다는 잘못된 충돌 쪽이 중심 위험이다. 즉 서로 다른 두 요청이 같은 것으로 합쳐지는 것이 아니라, 한쪽이 중복으로 거절될 수 있다.
|
||||
|
||||
## 선택지
|
||||
|
||||
정규 계획에 대한 암호학적 다이제스트로 교체한다
|
||||
충돌 확률이 실질적으로 사라진다. 키 길이가 늘어난다.
|
||||
|
||||
현재 값을 유지하고 문서를 좁힌다
|
||||
유일성 표현을 실제 보장 수준으로 낮춘다.
|
||||
|
||||
## 다음 검증
|
||||
|
||||
알려진 해시 충돌 픽스처나 속성 탐색으로 서로 다른 정규 요청이 같은 대체 키를 만드는 사례를 찾고, 그때 하류의 충돌 동작을 고정한다.
|
||||
|
||||
서로 다른 정규 요청의 충돌이 재현되면 암호학적 다이제스트로 교체한다.
|
||||
|
||||
재현하지 못해도 유일성 문서 표현은 실제 보장 수준으로 좁힌다.
|
||||
|
||||
## 관계
|
||||
|
||||
- **digest는 길이 프레이밍하고 버전을 붙인다**
|
||||
다이제스트로 교체할 때 따라야 할 규칙이다.
|
||||
- **모르는 것은 성공도 실패도 아닌 세 번째 결과여야 한다**
|
||||
잘못된 충돌이 어떤 결과로 보고되는지의 문제다.
|
||||
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
---
|
||||
kind: QUESTION
|
||||
slug: analysis-finding-a03-f004
|
||||
title: isolation vocabulary와 legacy routing capability의 시차
|
||||
topic: multitenancy-isolation
|
||||
project: clean-architecture-backend-template
|
||||
status: 게시 전
|
||||
sourceRevision: 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916
|
||||
rootTreeNode: open-question:analysis-finding-a03-f004
|
||||
questionStatus: OPEN
|
||||
verifiedOn: # 이 기록은 이번 회차에 실행 확인을 하지 않았다
|
||||
---
|
||||
|
||||
# isolation vocabulary와 legacy routing capability의 시차
|
||||
|
||||
공개 격리 수준 어휘에는 더 엄격한 값들이 있는데, 옛 트랜잭션 포트의 템플릿은 하나로 고정되어 있다. 어휘만 보면 이미 지원되는 능력으로 오해할 수 있다.
|
||||
|
||||
## 사실
|
||||
|
||||
공개 격리 수준 타입은 더 엄격한 값들을 표현한다.
|
||||
|
||||
옛 트랜잭션 포트의 템플릿은 읽기 커밋으로 고정되어 있다.
|
||||
|
||||
테스트도 더 엄격한 라우팅을 계획됨으로 적는다.
|
||||
|
||||
## 가정
|
||||
|
||||
어휘에 있는 값이 언젠가 라우팅될 것이라고 전제하고 있다. 그 시점과 소유자가 정해지지 않았다.
|
||||
|
||||
## 미지수
|
||||
|
||||
더 엄격한 격리를 옛 포트까지 확장할 것인가.
|
||||
|
||||
아니면 정규 정책 트랜잭션 경로에서만 제공할 것인가.
|
||||
|
||||
## 제약
|
||||
|
||||
라우팅 소유자가 둘이면 같은 유스케이스 정책이 어느 경로로 들어오느냐에 따라 다른 격리를 받는다.
|
||||
|
||||
## 선택지
|
||||
|
||||
옛 포트까지 확장한다
|
||||
기존 호출자가 그대로 더 엄격한 격리를 쓸 수 있다. 옛 포트의 표면이 넓어진다.
|
||||
|
||||
정규 경로에서만 제공한다
|
||||
소유자가 하나가 된다. 옛 포트 호출자는 이전해야 한다.
|
||||
|
||||
## 다음 검증
|
||||
|
||||
현재 프로덕션 유스케이스의 격리 요구와 옛 트랜잭션 포트 호출자를 대조한다. 그리고 라우팅 소유자를 하나로 정하는 설계와 계약 테스트를 만든다.
|
||||
|
||||
선택한 소유자에서 유스케이스 정책과 어댑터 트랜잭션 정의가 일대일로 검증되어야 한다.
|
||||
|
||||
지원하지 않는 경로는 능력으로 노출하지 않는다.
|
||||
|
||||
## 관계
|
||||
|
||||
- **트랜잭션 템플릿은 모드별로 미리 만들어 둔다**
|
||||
템플릿이 고정되어 있는 구조다.
|
||||
- **Bean 애너테이션이 있다는 것은 조립 증거가 아니다**
|
||||
어휘의 존재가 능력의 증거가 아니라는 같은 계열이다.
|
||||
- **등급은 네 단계로 나누고 관측보다 높게 적지 않는다**
|
||||
능력을 실제보다 높게 노출하지 않는 규칙이다.
|
||||
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
---
|
||||
kind: QUESTION
|
||||
slug: analysis-finding-a04-f006
|
||||
title: cache-redis 와 httpclient 의 support 간선이 죽었는지 확정되지 않았다
|
||||
topic: multitenancy-isolation
|
||||
project: clean-architecture-backend-template
|
||||
status: 게시 전
|
||||
sourceRevision: 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916
|
||||
rootTreeNode: open-question:analysis-finding-a04-f006
|
||||
questionStatus: OPEN
|
||||
verifiedOn: # 이 기록은 이번 회차에 실행 확인을 하지 않았다
|
||||
---
|
||||
|
||||
# cache-redis 와 httpclient 의 support 간선이 죽었는지 확정되지 않았다
|
||||
|
||||
두 리프가 지원 모듈에 대한 Gradle 의존을 갖는데 현재 프로덕션 자바 참조가 0 이고 지원 자원도 쓰지 않는다. 죽은 간선인지 아직 확정할 수 없다.
|
||||
|
||||
## 사실
|
||||
|
||||
두 리프 모두 지원 모듈에 대한 Gradle 의존이 선언되어 있다.
|
||||
|
||||
현재 프로덕션 자바 참조는 0 이다.
|
||||
|
||||
지원 모듈의 자원도 쓰지 않는다.
|
||||
|
||||
## 가정
|
||||
|
||||
빌드나 테스트나 리플렉션 경로에서 그 의존이 필요하지 않을 것이라고 전제하고 있다. 확인하지 않았다.
|
||||
|
||||
## 미지수
|
||||
|
||||
빌드나 테스트나 리플렉션이나 후속 범위에서 이 간선이 필요한가.
|
||||
|
||||
## 제약
|
||||
|
||||
각 리프의 전수 분석이 끝나기 전에는 죽은 간선으로 단정할 수 없다.
|
||||
|
||||
## 선택지
|
||||
|
||||
간선을 제거하고 레인을 돌린다
|
||||
불필요한 의존이 사라지고 클래스패스와 아키텍처 서술이 좁아진다. 소비자가 있으면 실패로 드러난다.
|
||||
|
||||
유지하고 소유자를 문서화한다
|
||||
소비자가 발견되면 그 이유를 적는다.
|
||||
|
||||
## 다음 검증
|
||||
|
||||
각 하류 리프의 전수 분석 결과를 확인한 뒤, 지원 의존을 제거한 상태로 집중 테스트와 애플리케이션 조립 테스트를 실행한다.
|
||||
|
||||
프로덕션과 빌드와 테스트와 런타임 소비자가 0 이고 의존 제거 후 관련 레인이 통과하면 간선을 제거한다.
|
||||
|
||||
소비자가 발견되면 그 소유자와 이유를 문서화한다.
|
||||
|
||||
## 관계
|
||||
|
||||
- **Bean 애너테이션이 있다는 것은 조립 증거가 아니다**
|
||||
선언과 사용을 구별하는 같은 계열이다.
|
||||
- **legacy compatibility surface의 제거 조건을 세 가지로 고정한다**
|
||||
제거 후보를 판정하는 같은 계열의 규칙이다.
|
||||
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
---
|
||||
kind: QUESTION
|
||||
slug: performance-and-capacity-unmeasured
|
||||
title: 실제 성능·용량 특성을 어떤 모듈에서도 측정하지 않았다
|
||||
topic: multitenancy-isolation
|
||||
project: clean-architecture-backend-template
|
||||
status: 게시 전
|
||||
sourceRevision: 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916
|
||||
rootTreeNode: open-question:performance-and-capacity-unmeasured
|
||||
questionStatus: OPEN
|
||||
verifiedOn: # 이 기록은 이번 회차에 실행 확인을 하지 않았다
|
||||
---
|
||||
|
||||
# 실제 성능·용량 특성을 어떤 모듈에서도 측정하지 않았다
|
||||
|
||||
이 분석은 성능을 측정하지 않았다. 문서에 남은 성능과 용량 관련 서술은 전부 코드가 선언한 상한과 그 강제 여부에 대한 것이다.
|
||||
|
||||
## 사실
|
||||
|
||||
성능 레인은 릴리스 게이트에서 의도적으로 빠져 있다. 기계 의존적인 측정을 게이트 판정의 입력으로 삼지 않는다는 결정이다.
|
||||
|
||||
풀 사이징 수식은 설정 파일 주석에 있고 부하 테스트로 조정하라고 적혀 있다.
|
||||
|
||||
테넌트 풀 예산은 두 상한을 갖지만 그 값이 어떤 부하에서 적절한지에 대한 근거가 없다.
|
||||
|
||||
httpclient 의 성능 레인과 벤치마크는 기계 의존적이라는 이유로 기본 검사에서 빠져 있다.
|
||||
|
||||
GraphQL 리프의 등급표는 실부하와 장애를 미달성으로 적고, 증거가 없으면 릴리스 게이트가 거부한다고 적는다.
|
||||
|
||||
## 가정
|
||||
|
||||
선언된 상한들이 합리적인 범위에 있다고 전제하고 있다. 그 전제의 근거는 문서에 적힌 시작점 수식이며 측정이 아니다.
|
||||
|
||||
## 미지수
|
||||
|
||||
각 상한이 실제 부하에서 적절한가.
|
||||
|
||||
테넌트 풀 예산의 두 상한이 어떤 테넌트 수와 부하에서 유효한가.
|
||||
|
||||
성능 회귀가 발생하면 무엇이 그것을 알아채는가.
|
||||
|
||||
## 제약
|
||||
|
||||
실부하 증거는 실제 부하 인프라를 요구한다. 리프 안에서 생성할 수 없다.
|
||||
|
||||
기계 의존적 측정을 게이트에 넣지 않는다는 결정이 이미 있다.
|
||||
|
||||
## 선택지
|
||||
|
||||
전용 성능 인프라를 만든다
|
||||
러너와 워밍업과 표본 수와 기록된 기준선이 필요하다. 그것이 생기면 별도 레인으로 만든다.
|
||||
|
||||
측정하지 않은 상태를 명시적으로 유지한다
|
||||
등급표가 이미 그렇게 하고 있다. 릴리스 게이트가 증거 없이는 거부한다.
|
||||
|
||||
## 다음 검증
|
||||
|
||||
성능 레인을 실행할 인프라를 정하고, 어떤 지표를 어떤 조건에서 잴지 먼저 문서로 고정한다. 그다음 기준선을 기록한다.
|
||||
|
||||
기준선이 기록되면 이 질문을 닫고, 이후의 측정은 그 기준선과의 비교가 된다.
|
||||
|
||||
인프라를 만들지 않기로 하면 그 결정과 그때 포기하는 것을 기록한다.
|
||||
|
||||
## 관계
|
||||
|
||||
- **성능 측정은 릴리스 게이트에 넣지 않는다**
|
||||
이 질문이 전제하는 결정이다.
|
||||
- **tenant별 풀이 개별적으로 합리적이고 그 합이 서버 상한을 넘긴다**
|
||||
측정되지 않은 용량 판단의 사례다.
|
||||
- **능력 등급은 코드가 아니라 실행된 증거에서 파생한다**
|
||||
실부하 증거가 최상위 등급의 조건인 이유다.
|
||||
|
||||
Reference in New Issue
Block a user