Files
document-haness/docs/clean-architecture-backend-template/final/evidence/meta/a14-f002-webproblemsanitizer-alreadysafe-branch.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.2 KiB
JSON

{
"assetKey": "a14-f002-webproblemsanitizer-alreadysafe-branch",
"kind": "terminal",
"command": "set -e\nset -o pipefail\nD=$(mktemp -d); trap 'rm -rf \"$D\"' EXIT\nC=/shared/codebase/clean-architecture-backend-template\nW=$C/src/adapter/inbound/web\nCACHE=/root/.gradle/caches/modules-2/files-2.1\njava -version 2>&1 | head -1\ncp=\"\"\nwhile IFS= read -r line; do\n coord=${line%%=*}; confs=${line#*=}\n case \",$confs,\" in *\",runtimeClasspath,\"*) ;; *) continue ;; esac\n g=${coord%%:*}; rest=${coord#*:}; n=${rest%%:*}; v=${rest##*:}\n jar=$(find \"$CACHE/$g/$n/$v\" -name '*.jar' ! -name '*sources*' ! -name '*javadoc*' 2>/dev/null | head -1)\n [ -n \"$jar\" ] && cp=\"$cp:$jar\"\ndone < <(grep -E '^[a-zA-Z0-9._-]+:[^=]+=' \"$W/gradle.lockfile\")\nCP=$(find \"$W/build/libs\" -name '*+21234e38cdb9.jar' | tr '\\n' ':')${cp#:}\ncat > \"$D/AlreadySafeProbe.java\" <<'JAVA'\nimport dev.caskeleton.adapter.inbound.web.error.WebProblemSanitizer;\nimport java.util.LinkedHashMap;\nimport java.util.Locale;\nimport java.util.Map;\n\n/** alreadySafe 의 삼항이 어느 가지를 타는지 입력마다 직접 본다. */\npublic final class AlreadySafeProbe {\n\n /** 제어 문자를 소스에 직접 적지 않으려고 코드 점으로 만든다. */\n private static String ch(int code) {\n return String.valueOf((char) code);\n }\n\n /** 메서드 본문의 삼항 조건 그대로. */\n private static boolean takesRedactedBranch(String input) {\n return input.trim().toLowerCase(Locale.ROOT).isEmpty();\n }\n\n private static String show(String value) {\n StringBuilder shown = new StringBuilder();\n for (char each : value.toCharArray()) {\n shown.append(each < 0x20 || each > 0x7e ? String.format(\"U+%04X\", (int) each) : each);\n }\n return shown.toString();\n }\n\n /** 두 판정이 갈리는 코드 점을 전 범위에서 센다. 예시 몇 개로 \"틈\"을 말할 수 없다. */\n private static void sweep(WebProblemSanitizer sanitizer) {\n int gap = 0;\n int returnsTrue = 0;\n int first = -1;\n int last = -1;\n StringBuilder ranges = new StringBuilder();\n boolean inRun = false;\n for (int code = 0; code <= 0xFFFF; code++) {\n String value = ch(code);\n boolean inGap = !value.isBlank() && value.trim().isEmpty();\n if (inGap) {\n gap++;\n if (sanitizer.alreadySafe(value, 200)) {\n returnsTrue++;\n }\n if (!inRun) {\n first = code;\n inRun = true;\n }\n last = code;\n } else if (inRun) {\n ranges.append(ranges.length() == 0 ? \"\" : \", \")\n .append(String.format(\"U+%04X..U+%04X\", first, last));\n inRun = false;\n }\n }\n if (inRun) {\n ranges.append(ranges.length() == 0 ? \"\" : \", \")\n .append(String.format(\"U+%04X..U+%04X\", first, last));\n }\n System.out.println();\n System.out.println(\"[두 판정이 갈리는 코드 점 — 기본 다국어 평면 전체를 훑는다]\");\n System.out.printf(\" %-22s %d%n\", \"공백은 아닌데 다듬기면 비는 것\", gap);\n System.out.printf(\" %-22s %s%n\", \"그 구간\", ranges);\n System.out.printf(\" %-22s %d%n\", \"그중 alreadySafe 가 참\", returnsTrue);\n }\n\n public static void main(String[] args) {\n WebProblemSanitizer sanitizer = new WebProblemSanitizer();\n Map<String, String> inputs = new LinkedHashMap<>();\n inputs.put(\"보통 문장\", \"the request was rejected\");\n inputs.put(\"앞뒤 공백\", \" spaced \");\n inputs.put(\"널 문자\", ch(0));\n inputs.put(\"널 문자 셋\", ch(0) + ch(0) + ch(0));\n inputs.put(\"백스페이스\", ch(8));\n inputs.put(\"탈출 문자\", ch(27));\n inputs.put(\"삭제 문자\", ch(127));\n inputs.put(\"보통 공백만\", \" \");\n inputs.put(\"줄 구분자\", ch(0x2028));\n inputs.put(\"붙임 공백\", ch(0x00A0));\n\n System.out.println();\n System.out.printf(\" %-14s %-14s %-9s %-11s %-14s %s%n\",\n \"입력\", \"보인 값\", \"isBlank\", \"trim 이 빔\", \"편집됨 가지\", \"alreadySafe\");\n for (var entry : inputs.entrySet()) {\n String value = entry.getValue();\n boolean blank = value.isBlank();\n boolean trimmedEmpty = takesRedactedBranch(value);\n String branch = blank ? \"선행에서 끊김\" : (trimmedEmpty ? \"탄다\" : \"안 탄다\");\n System.out.printf(\" %-14s %-14s %-9s %-11s %-14s %s%n\",\n entry.getKey(), show(value), blank, trimmedEmpty, branch,\n sanitizer.alreadySafe(value, 200));\n }\n sweep(sanitizer);\n }\n}\nJAVA\njavac -encoding UTF-8 -cp \"$CP\" -d \"$D\" \"$D/AlreadySafeProbe.java\"\njava -Dstdout.encoding=UTF-8 -cp \"$CP:$D\" AlreadySafeProbe\n",
"cwd": "/shared/codebase/clean-architecture-backend-template/src",
"exitCode": 0,
"executedAt": "2026-09-02T19:53:40+00:00",
"sourceRevision": "21234e38cdb9a926cbc92bb97a2aee2e4a7d2916",
"raw": "evidence/raw/a14-f002-webproblemsanitizer-alreadysafe-branch.txt",
"svg": "evidence/rendered/a14-f002-webproblemsanitizer-alreadysafe-branch.svg",
"rawSha256": "23d08617b3c385461ef1a37aee15694efeb8f5ff1b141ad0191124a3d2aa81fe",
"lines": 18,
"redaction": "none — 제어 문자 입력은 이 프로브가 코드 점으로 만든 합성 값이다"
}