Files
document-haness/docs/clean-architecture-backend-template/final/evidence/meta/a19-f020-messaging-admin-api.json
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

15 lines
5.0 KiB
JSON

{
"assetKey": "a19-f020-messaging-admin-api",
"kind": "terminal",
"command": "#!/bin/bash\ncd /shared/codebase/clean-architecture-backend-template\n# leaf 이름을 남긴다. 긴 문자열 리터럴은 값이 새지 않도록 가린다.\nstrip() { sed -E 's#^src/messaging/([^/]+)/src/(main|test)/java/dev/caskeleton/[^:]*/([^:/]+):([0-9]+):# \\2 · \\1 · \\3:\\4 #' \\\n | sed -E 's#\"[^\"]{16,}\"#\"<가림>\"#g'; }\n\necho \"# 계약 leaf 와 그 소비자 leaf 의 소스 규모\"\nfor m in messaging-admin-api messaging-admin-runtime; do\n echo \" $m 의 소스 세트 : $(ls src/messaging/$m/src/ | tr '\\n' ' ')\"\n for ss in main test; do\n n=$(find src/messaging/$m/src/$ss -name '*.java' 2>/dev/null | wc -l)\n l=$(find src/messaging/$m/src/$ss -name '*.java' -exec cat {} + 2>/dev/null | wc -l)\n printf \" %-4s %2s 파일 · %4s 줄\\n\" \"$ss\" \"$n\" \"$l\"\n done\ndone\n\necho\necho \"# 계약 leaf 의 유일한 시험 파일이 담은 것\"\nT=src/messaging/messaging-admin-api/src/test/java/dev/caskeleton/messaging/admin/DestructiveOperationGuardTest.java\necho \" 파일 : $(basename $T) · @Test $(grep -c '@Test' $T) 개\"\ngrep -n 'void .*(' $T | sed -E 's#^([0-9]+): *# :\\1 #'\n\necho \" 그 시험들이 승인 객체를 어떻게 얻는가 :\"\nawk 'NR>=27 && NR<=33 {printf \" DestructiveOperationGuardTest.java:%d %s\\n\", NR, $0}' $T\nawk 'NR>=45 && NR<=48 {printf \" DestructiveOperationGuardTest.java:%d %s\\n\", NR, $0}' $T\necho \" 그 셋의 단언이 무엇에 떨어지는가 :\"\ngrep -n 'Optional.empty()\\|Optional.of(\\|hasMessageContaining\\|doesNotThrowAnyException' $T \\\n | sed -E 's#^([0-9]+): *# DestructiveOperationGuardTest.java:\\1 #' | sed -E 's#\"[^\"]{16,}\"#\"<가림>\"#g'\necho \" 가드가 그 메시지를 내는 자리 :\"\nG=$(find src -name DestructiveOperationGuard.java -path '*/main/*')\ngrep -n 'APPROVAL_REQUIRED\\|APPROVAL_EXPIRED\\|isValidAt' $G | sed -E 's#^([0-9]+): *# DestructiveOperationGuard.java:\\1 #'\n\necho\necho \"# 소비자 leaf 의 시험 여섯\"\nfor f in $(find src/messaging/messaging-admin-runtime/src/test -name '*.java' | sort); do\n printf \" %-34s @Test %s 개\\n\" \"$(basename $f)\" \"$(grep -c '@Test' $f)\"\ndone\necho \" 그중 승인 위조 시험이 단언하는 것 :\"\ngrep -n 'void .*(' src/messaging/messaging-admin-runtime/src/test/java/dev/caskeleton/messaging/admin/runtime/ApprovalForgeryTest.java \\\n | sed -E 's#^([0-9]+): *# ApprovalForgeryTest.java:\\1 #'\n\necho\necho \"# 계약 leaf 가 담은 main 타입 스물다섯\"\nfind src/messaging/messaging-admin-api/src/main -name '*.java' | sed 's#.*/##;s#\\.java$##' | sort | tr '\\n' ' ' | fold -w 92 -s | sed 's#^# #'\necho\n\necho \"# 승인 검증자는 어디서 만들어지는가\"\necho \" main 구현 :\"\ngit grep -n 'implements ApprovalVerifier' -- 'src/**/*.java' | strip\necho \" 생성 지점 :\"\ngit grep -n 'new HmacApprovalVerifier' -- 'src/**/*.java' | strip\necho \" 생성 지점 $(git grep -c 'new HmacApprovalVerifier' -- 'src/**/*.java' | awk -F: '{s+=$2} END{print s}') 곳 · 파일 $(git grep -l 'new HmacApprovalVerifier' -- 'src/**/*.java' | wc -l) 개\"\n\necho\necho \"# main 에 검증자를 두지 않는 것이 공백인가 경계인가\"\necho \" 자기 자바독이 적은 이유 :\"\nH=$(find src -name HmacApprovalVerifier.java -path '*/main/*')\nawk 'NR>=50 && NR<=53 {printf \" HmacApprovalVerifier.java:%d %s\\n\", NR, $0}' $H\necho \" 같은 사슬의 가드는 main 빈으로 있다 :\"\nA=$(find src -name MessagingAdminAutoConfiguration.java -path '*/main/*')\nawk 'NR>=35 && NR<=41 {printf \" MessagingAdminAutoConfiguration.java:%d %s\\n\", NR, $0}' $A\n\necho\necho \"# 계약 타입의 경계 조건이 따로 고정돼 있는가\"\nfor t in PlanDigest ApprovalGrant VerifiedApproval ApprovedRedrivePlan ApprovedReplayPlan TopologyManifest; do\n m=$(git grep -lw \"$t\" -- 'src/**/*.java' | grep '/main/' | grep -v \"/$t.java\" | wc -l)\n s=$(git grep -lw \"$t\" -- 'src/**/*.java' | grep '/test/' | wc -l)\n n=$(find src \\( -name \"*${t}*Test.java\" -o -name \"*${t}*Tests.java\" -o -name \"*${t}*IT.java\" \\) | wc -l)\n printf \" %-22s main %s 파일 · test %s 파일 · 그 이름을 건 시험 파일 %s 개\\n\" \"$t\" \"$m\" \"$s\" \"$n\"\ndone\necho \" 만료를 직접 고정하는 자리 :\"\ngit grep -n 'anExpiredGrantDoesNotVerify\\|anExpiredApprovalDoesNotAuthorise' -- 'src/**/*.java' | strip\necho \" PlanDigest 가 test 에서 어떻게 쓰이는가 :\"\ngit grep -n 'PlanDigest' -- 'src/**/*.java' | grep '/test/' | strip\n",
"cwd": "/shared/codebase/clean-architecture-backend-template",
"exitCode": 0,
"executedAt": "2026-09-04T02:14:47+00:00",
"sourceRevision": "21234e38cdb9a926cbc92bb97a2aee2e4a7d2916",
"raw": "evidence/raw/a19-f020-messaging-admin-api.txt",
"svg": "evidence/rendered/a19-f020-messaging-admin-api.svg",
"rawSha256": "3d4c0ce0b30a6f4b58a89ca9f07e3e7c3908f38328742dde04f6081727a32506",
"lines": 123,
"redaction": "시험 키 리터럴 가림"
}