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

15 lines
4.4 KiB
JSON

{
"assetKey": "a14-f018-webplatformstartupvalidator",
"kind": "terminal",
"command": "set -e\nset -o pipefail\nP=src/adapter/inbound/web/src/main/java/dev/caskeleton/adapter/inbound/web/admin/platform\necho \"# 검증기가 자기 실행 시점과 이유를 적어 둔 자리\"\nsed -n '7,19p' $P/WebPlatformStartupValidator.java\necho\necho \"# admin/platform 두 파일의 이름이 자기 파일 밖에 나오는 줄 (시험 클래스 선언 포함)\"\nfor f in WebPlatformStartupValidator WebPlatformSnapshot; do\n echo \" $f :\"\n git grep -n \"$f\" -- \"src/**/*.java\" \\\n | awk -F: -v self=\"/$f.java\" 'index($1, self) == 0' \\\n | sed -E 's#^src/[^:]*/src/(main|test)/[^:]*/([^:/]+):([0-9]+):.*# \\1 · \\2:\\3#' | sort -u\ndone\necho\necho \"# 그 검증기를 가리키는 운영 문서\"\ngit grep -n 'WebPlatformStartupValidator' -- docs/ | sed -E 's#^docs/([^:]+):([0-9]+):# \\1:\\2 #'\nsed -n '27,29p' docs/web/runbook.md | sed 's#^# #'\necho\necho \"# 원문이 인용한 근거가 실제로 걸린 자리\"\ngrep -n 'Better to refuse to start' \\\n src/adapter/inbound/web/src/main/java/dev/caskeleton/adapter/inbound/web/fileserver/nginx/NginxInternalUriMapper.java \\\n | sed 's#^# NginxInternalUriMapper:#'\ngrep -n 'attestMapping()' \\\n src/app-bootstrap/src/main/java/dev/caskeleton/bootstrap/autoconfigure/fileserver/FileserverStartupConfiguration.java \\\n | sed 's#^# FileserverStartupConfiguration:#'\necho\necho \"# 같은 저장소가 시작 검증기를 실제로 거는 방식\"\ngrep -n -A3 'FileserverStartupValidator fileserverStartupValidator' \\\n src/app-bootstrap/src/main/java/dev/caskeleton/bootstrap/autoconfigure/fileserver/FileserverStartupConfiguration.java \\\n | sed 's#^# FileserverStartupConfiguration:#'\ngrep -n -A3 'HttpClientStartupValidator httpClientStartupValidator' \\\n src/app-bootstrap/src/main/java/dev/caskeleton/bootstrap/autoconfigure/httpclient/HttpClientProfileAutoConfiguration.java \\\n | sed 's#^# HttpClientProfileAutoConfiguration:#'\necho\necho \"# 이 리프가 자동설정으로 올리는 것\"\ncat src/adapter/inbound/web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports | sed 's#^# #'\necho -n \" 그 목록에서 admin 이라는 문자열을 담은 항목 : \"\n{ grep -c 'admin' src/adapter/inbound/web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports || true; }\necho -n \" 검증기 클래스에 스프링 스테레오타입이 붙어 있는가 : \"\n{ grep -cE '^@(Component|Service|Configuration|Bean)' $P/WebPlatformStartupValidator.java || true; }\necho\necho \"# src 에 선언된 *StartupValidator 를 모두 찾아, 자기 파일 밖 main 파일 수를 센다\"\ngit grep -lE '(class|interface|record) [A-Za-z0-9_]*StartupValidator\\b' -- \"src/**\" \\\n | sed -E 's#^.*/([^/]+)\\.java$#\\1#' | sort | while IFS= read -r v; do\n n=$(git grep -l \"$v\" -- \"src/**/*.java\" 2>/dev/null | awk -v self=\"/$v.java\" '$0 ~ /\\/src\\/main\\// && index($0, self) == 0 {c++} END {print c+0}')\n printf ' %-36s main 파일 %s (자바독 언급 포함)\\n' \"$v\" \"$n\"\ndone\necho\necho \"# 런북이 백틱으로 지목한 이름 중, main 에 그 이름의 파일이 있으면서 자기 파일 밖 main 참조가 0 인 것\"\ngit grep -ho '`[A-Z][A-Za-z0-9]\\{4,\\}`' -- docs/web/runbook.md docs/runbooks/ \\\n | tr -d '`' | sort -u | while IFS= read -r n; do\n case \"$n\" in *Test) continue ;; esac\n [ -n \"$(git ls-files \"src/**/src/main/**/$n.java\")\" ] || continue\n m=$(git grep -l \"$n\" -- \"src/**/*.java\" | awk -v s=\"/$n.java\" '$0 ~ /\\/src\\/main\\// && index($0, s) == 0 {c++} END {print c+0}')\n [ \"$m\" = \"0\" ] || continue\n printf ' %-34s main 참조 0 · ' \"$n\"\n git grep -l \"$n\" -- docs/web/runbook.md docs/runbooks/ | tr '\\n' ' '\n echo\ndone\necho \" 그중 이 리프 런북이 같은 추론을 거는 자리 :\"\nsed -n '27,29p;88,90p' docs/web/runbook.md | sed 's#^# #' \n",
"cwd": "/shared/codebase/clean-architecture-backend-template",
"exitCode": 0,
"executedAt": "2026-09-03T08:09:05+00:00",
"sourceRevision": "21234e38cdb9a926cbc92bb97a2aee2e4a7d2916",
"raw": "evidence/raw/a14-f018-webplatformstartupvalidator.txt",
"svg": "evidence/rendered/a14-f018-webplatformstartupvalidator.svg",
"rawSha256": "ee78c7ca7f4130cc824d2f1399ab9c580dcd10faf1db5939bbd3e924a5e84c29",
"lines": 84,
"redaction": "런북 지목 식별자로 훑도록 교체"
}