Files
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

69 lines
4.7 KiB
Plaintext

# 주제: DestructiveOperationGuard 의 6개 검사 중 2개가 어떤 테스트에도 도달하지 않으며,
# 클래스 javadoc 은 그 2개를 세지 않는다
# revision: 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916
# DestructiveOperationGuard.authorize 의 실제 분기 (DestructiveOperationGuard.java:54-93)
# 1) dryRun -> 무조건 통과 (:54-56)
# 2) !adminCredentialPresent -> ADMIN_CREDENTIAL_REQUIRED (:57-61)
# 3) approval 부재 -> APPROVAL_REQUIRED (:62-67)
# 4) !isValidAt(now) -> APPROVAL_EXPIRED (:68-71)
# 5) operation 불일치 -> APPROVAL_OPERATION_MISMATCH (:72-83)
# 6) source 불일치 -> APPROVAL_SOURCE_MISMATCH (:84-93)
#
# 클래스 javadoc (:12-15):
# "Four conditions, all required. The caller must hold the admin credential … The approval must
# be present and inside its validity window. And a dry run is always permitted …"
# -> 1~4만 서술한다. 5, 6은 언급되지 않는다.
# (5번 분기에는 별도 인라인 주석이 있다: "A guard that only checks presence and window
# lets a verified redrive approval authorise a destination deletion." — 즉 의도된 검사다.)
# command: git grep -n "\.authorize(" -- src | grep -i "messaging"
# exit: 0
src/messaging/messaging-admin-api/src/test/java/.../DestructiveOperationGuardTest.java:56,67,84,96,107 (테스트 5건)
src/messaging/messaging-admin-runtime/src/main/java/.../RedriveService.java:97
src/messaging/messaging-admin-runtime/src/main/java/.../ReplayService.java:59
# => guard.authorize 를 부르는 테스트는 DestructiveOperationGuardTest 의 5건이 전부다.
# 그 5건이 도달하는 분기:
# anApplicationRuntimeCannotRedrive -> 2 (ADMIN_CREDENTIAL_REQUIRED)
# anAdminRuntimeStillNeedsAnApproval -> 3 (APPROVAL_REQUIRED)
# anExpiredApprovalDoesNotAuthorise -> 4 (APPROVAL_EXPIRED)
# aDryRunIsAlwaysPermitted -> 1
# anApprovedAdminOperationIsAuthorised -> 통과
# => 분기 5, 6 에 도달하는 테스트가 없다.
# 주목: 유일하게 불일치 조합을 넘기는 테스트가 있으나 앞 분기에서 먼저 걸린다.
# DestructiveOperationGuardTest.java:52-59 anApplicationRuntimeCannotRedrive
# guard = new DestructiveOperationGuard(false) <- 자격증명 없음
# guard.authorize(DestructiveOperation.REDRIVE, ORDERS, Optional.of(VALID), false, NOW)
# VALID 는 :24-25 에서 DestructiveOperation.REPLAY 로 만들어진 승인이다.
# -> operation 이 실제로 불일치(REDRIVE vs REPLAY)하지만,
# 분기 2가 먼저 던지므로 단언은 "admin credential" 이다. 분기 5는 실행되지 않는다.
# command: git grep -n "APPROVAL_OPERATION_MISMATCH\|APPROVAL_SOURCE_MISMATCH" -- src | grep -v "messaging-admin-api/src/main"
# exit: 1 (출력 없음)
# => 두 에러 코드를 단언하는 테스트가 저장소 전체에 없다.
# (동명 개념은 ApprovedReplayPlan / ApprovedRedrivePlan 생성자에도 있고 그쪽은
# messaging-admin-runtime 의 ApprovalForgeryTest 가 행위로 검증한다:
# anApprovalForAReplayCannotAuthoriseARedrive, aVerifiedApprovalForTheWrongSourceCannotBeAttached.
# 그러나 그것은 record 생성자이지 guard 의 분기가 아니다 — 서로 다른 코드다.)
# ---- 배선 ----
# command: git grep -nE "new ([a-zA-Z0-9_.]+\.)?DestructiveOperationGuard\s*\(" -- src
src/messaging/messaging-admin-api/src/test/java/.../DestructiveOperationGuardTest.java:52,64,74,92,103
src/messaging/messaging-admin-runtime/src/test/java/.../RedriveResumptionTest.java:142 new DestructiveOperationGuard(true)
src/messaging/messaging-spring-boot-starter/src/main/java/.../MessagingAdminAutoConfiguration.java:40
return new DestructiveOperationGuard(false);
# => 프로덕션 생성은 1건이며 adminCredentialPresent=false 로 고정이다. 이는 의도된 설계이고
# 주석이 명시한다("An operator tool overrides this bean with true.").
# 결과적으로 부팅된 애플리케이션에서는 분기 2에서 항상 멈추므로 3~6은 도달 불가다.
# ---- ApprovalVerifier 배선 ----
# command: git grep -n "implements ApprovalVerifier" -- src
src/messaging/messaging-admin-api/.../HmacApprovalVerifier.java:26
# command: git grep -nE "new ([a-zA-Z0-9_.]+\.)?HmacApprovalVerifier\s*\(" -- src | grep "/src/main/"
# exit: 1 (출력 없음) — src/main 생성 0건, src/test 생성 5건
# => 부팅된 애플리케이션에는 ApprovalVerifier 빈이 없다. VerifiedApproval 을 만들 수 있는 주체가
# 프로덕션 배선에 존재하지 않는다. (스타터 javadoc 이 이 스탠스를 명시한다:
# "an operator tool that needs purge or delete registers one itself".)