Files
document-haness/docs/clean-architecture-backend-template/final/evidence/meta/a14-f010-no-store.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
6.4 KiB
JSON

{
"assetKey": "a14-f010-no-store",
"kind": "terminal",
"command": "set -e\nset -o pipefail\nW=adapter/inbound/web/src/main/java/dev/caskeleton/adapter/inbound/web\nP=sample-portfolio/src/main/java/dev/caskeleton/sample/portfolio/adapter/inbound/web/controller\necho \"# 필터가 무엇을 붙이고, 그것이 되돌려질 수 있다고 무엇이 말하는가\"\nsed -n '14,34p' $W/filter/CacheControlFilter.java\necho\necho \"# 그 정책을 이 필터가 혼자 갖도록 보안 설정이 프레임워크 기본값을 끈다\"\nsed -n '77,80p' $W/auth/SecurityConfig.java\necho -n \" 다만 픽스처 모듈은 그 설정을 스캔에서 뺀다 : \"\ngrep -n 'SecurityConfig.class' \\\n sample-portfolio/src/main/java/dev/caskeleton/sample/portfolio/SamplePortfolioApplication.java\necho \" 그 모듈이 적어 둔 제외 이유 :\"\nsed -n '36,37p' sample-portfolio/src/main/java/dev/caskeleton/sample/portfolio/SamplePortfolioApplication.java\necho \" 그 모듈이 대신 두는 체인. 캐시 기록기를 끄지 않는다 :\"\nsed -n '24,29p' \\\n sample-portfolio/src/main/java/dev/caskeleton/sample/portfolio/bootstrap/security/SamplePublicAccessSecurityConfig.java\necho\necho \"# 조건부 읽기를 구현한 자리 전부와 그것을 켜는 조건\"\necho \" main 에서 응답에 개체 태그를 쓰는 파일 (아웃바운드 S3 클라이언트는 뺐다) :\"\ngrep -rln 'HttpHeaders.ETAG\\|WebHeaderName.ETAG\\|ApiHeaders.ETAG\\|\\.eTag(' --include=*.java --exclude-dir=build . \\\n | grep '/main/' | grep -v '/objectstorage/' | sed -E 's#^\\./[^:]*/([^/]+)$# \\1#'\necho \" 이 파일들과 304 판정 클래스를, 시험을 빼고 부르는 자리가 있는지 :\"\nfor n in WebSuccessResponse WebResponseContract ConditionalReadEvaluator; do\n echo -n \" $n 를 부르는 자리 : \"\n { grep -rln \"$n\" --include=*.java --exclude-dir=build . | grep -v \"/$n.java\" | grep -v \"Test.java\" \\\n | sed -E \"s#^\\./[^:]*/([^/]+)\\$#\\1#\" | tr '\\n' ' ' || true; }\n echo \"(끝)\"\ndone\necho -n \" 같은 패키지의 ETags 를 실제로 호출하는 자리 : \"\n{ grep -rln 'ETags\\.' --include=*.java --exclude-dir=build . | grep -v '/ETags.java' \\\n | grep -v 'Test.java' | sed -E 's#^\\./[^:]*/([^/]+)$#\\1#' | tr '\\n' ' ' || true; }\necho \"(끝)\"\necho \" 레지스트리가 선언한 런타임 컴포지션과 이 리프의 소속 :\"\nsed -n '2,6p' config/architecture/modules.json\nsed -n '170p' config/architecture/modules.json\nsed -n '170,182p' config/architecture/modules.json | grep -A3 'runtime_memberships'\necho \" 304 판정을 구현해 둔 클래스와 그 자바독 첫 줄 :\"\nsed -n '6,7p' $W/conditional/ConditionalReadEvaluator.java\necho \" 내려받기 컨트롤러를 켜는 조건과 그 스위치의 출하값 :\"\ngrep -n 'ConditionalOnProperty' $W/fileserver/controller/FileDownloadController.java\ngrep -n 'APP_FILESERVER_PLATFORM_ENABLED' app-bootstrap/src/main/resources/application.yml\ngrep -n '^APP_FILESERVER_PLATFORM_ENABLED' .env .env.example\necho\necho \"# 내려받기 경로가 스스로 쓰는 태그와 지시자\"\ngrep -n 'ETAG\\|CACHE_CONTROL' $W/fileserver/http/MvcDownloadResponseWriter.java\necho \" 같은 문자열을 자바 밖에서 다시 쓰는 자리 :\"\ngrep -rIn 'no-store' --exclude=*.java --exclude-dir=build --exclude-dir=.git --exclude=*.md . \\\n | sed -E 's#^\\./# #'\ngrep -rn 'private, no-store' --include=*.java application-core/src/main app-bootstrap/src/main \\\n | sed -E 's#^[^:]*/([^:/]+):# \\1:#'\necho\necho \"# 픽스처 모듈 쪽 조건부 읽기 경로\"\nsed -n '137,148p' $P/WorkLogController.java\necho -n \" 이 모듈 main 에서 Cache-Control 을 스스로 정하는 자리 : \"\n{ grep -rc 'CacheControl' --include=*.java sample-portfolio/src/main | grep -v ':0$' || echo \"(0)\"; }\necho\necho \"# 둘을 조정하라고 만들어 둔 패키지\"\nfind $W/cache -name '*.java' | sort | while IFS= read -r f; do\n printf ' %3s줄 %s\\n' \"$(grep -c '' \"$f\")\" \"$(basename \"$f\")\"\ndone\necho \" 그 타입들을 이름으로 부르는 파일과 횟수 :\"\ngrep -rn 'WebCachePolicyCatalog\\|WebCachePolicy\\|WebVaryPolicy\\|WebCacheHeaders' --include=*.java . \\\n | sed -E 's#^\\./([^:]*)/src/(main|test)/[^:]*/([^:/]+):[0-9]+:.*# \\2 · \\3#' | sort | uniq -c\necho -n \" cache 패키지 밖에서 부르는 파일 : \"\n{ grep -rl 'WebCachePolicyCatalog\\|WebCachePolicy\\|WebVaryPolicy\\|WebCacheHeaders' --include=*.java . \\\n | grep -v '/web/cache/' || echo \"(0)\"; }\necho\necho \"# 그 패키지를 그렇게 둔 근거\"\nsed -n '80,87p' $W/moduleboundary/WebStableModule.java\necho\necho \"# 그 근거가 말한 적용자들이 실제로 무엇을 쓰는가\"\necho \" main 에서 Cache-Control 값을 정하는 자리 (헤더 이름 상수 두 파일은 뺐다) :\"\ngrep -rn 'CACHE_CONTROL\\|\"Cache-Control\"' --include=*.java . \\\n | grep -v '/test/' | grep -v 'WebHeaderName.java\\|ApiHeaders.java' \\\n | sed -E 's#^\\./[^:]*/([^:/]+):([0-9]+):# \\1:\\2 #'\necho \" 뺀 두 파일 :\"\n{ grep -rln 'CACHE_CONTROL' --include=*.java . | grep 'WebHeaderName.java\\|ApiHeaders.java' \\\n | sed -E 's#^\\./[^:]*/([^:/]+)$# \\1#' || echo \" (없음)\"; }\necho \" 연산 프로파일이 이름으로 들고 있는 캐시 정책과 그것을 읽는 자리 :\"\ngrep -n 'CachePolicyName cachePolicy\\|CachePolicyName.standard()' \\\n $W/operation/WebOperationProfile.java | head -3\necho -n \" cachePolicy() 를 읽는 자리 : \"\n{ grep -rn 'cachePolicy()' --include=*.java . | sed -E 's#^\\./[^:]*/([^:/]+):# \\1:#' || echo \"(0)\"; }\necho \" 지시자 문자열을 직접 들고 있는 main 자리 :\"\ngrep -rnE '\"(no-store|no-cache|public|private)[^\"]*\"|\"max-age=[^\"]*\"' --include=*.java . \\\n | grep -v '/test/' | grep -E 'no-store|max-age' \\\n | sed -E 's#^\\./[^:]*/([^:/]+):([0-9]+):# \\1:\\2 #'\necho \" 목록이 발행하는 프로파일 이름과 그 지시자 :\"\ngrep -n ' \"[a-z][a-z0-9.-]*\",' $W/cache/WebCachePolicyCatalog.java\n",
"cwd": "/shared/codebase/clean-architecture-backend-template/src",
"exitCode": 0,
"executedAt": "2026-09-03T00:50:42+00:00",
"sourceRevision": "21234e38cdb9a926cbc92bb97a2aee2e4a7d2916",
"raw": "evidence/raw/a14-f010-no-store.txt",
"svg": "evidence/rendered/a14-f010-no-store.svg",
"rawSha256": "d58724736c31739d70b595d250577993d313970fc026c0ebd945d2382ef6838a",
"lines": 158,
"redaction": "none — 코드베이스 정적 검색"
}