Files
document-haness/docs/clean-architecture-backend-template/final/evidence/meta/a16-f002-oneof-run.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.1 KiB
JSON

{
"assetKey": "a16-f002-oneof-run",
"kind": "terminal",
"command": "set -e\nset -o pipefail\nD=$(mktemp -d); trap 'rm -rf \"$D\"' EXIT\nC=/shared/codebase/clean-architecture-backend-template\nM=$C/src/adapter/inbound/graphql\nCACHE=/root/.gradle/caches/modules-2/files-2.1\njava -version 2>&1 | grep version\ncp=\"\"\nwhile IFS= read -r line; do\n coord=${line%%=*}; confs=${line#*=}\n case \",$confs,\" in *\",testRuntimeClasspath,\"*) ;; *) 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) || true\n [ -n \"$jar\" ] && cp=\"$cp:$jar\"\ndone < <(grep -E '^[a-zA-Z0-9._-]+:[^=]+=' \"$M/gradle.lockfile\")\nSIB=$(find \"$C/src\" -path '*/build/libs/*+21234e38cdb9*.jar' ! -name '*-testkit.jar' | sort | tr '\\n' ':')\n\ncat > \"$D/OneOfProbe.java\" <<'JAVA'\nimport dev.caskeleton.adapter.inbound.graphql.schema.GraphQlOneOfSchemaGate;\nimport graphql.ExecutionInput;\nimport graphql.GraphQL;\nimport graphql.schema.idl.RuntimeWiring;\nimport graphql.schema.idl.SchemaGenerator;\nimport graphql.schema.idl.SchemaParser;\nimport java.util.Map;\n\n/** graphql-java 가 스스로 하는 것과 스키마 게이트가 따로 하는 것을 갈라 본다. */\npublic final class OneOfProbe {\n\n /** 규칙에 맞게 선언한 one-of 입력. 구성원이 전부 널 허용이고 기본값이 없다. */\n private static final String VALID =\n \"\"\"\n type Query { order(by: OrderSelector!): String }\n input OrderSelector @oneOf { id: ID, number: String }\n \"\"\";\n\n /** 규칙을 어긴 선언. 구성원 하나가 비널이고 하나는 기본값을 갖는다. */\n private static final String INVALID =\n \"\"\"\n type Query { order(by: OrderSelector!): String }\n input OrderSelector @oneOf { id: ID!, number: String = \"N-1\" }\n \"\"\";\n\n private static GraphQL build(String sdl) {\n var registry = new SchemaParser().parse(sdl);\n var wiring =\n RuntimeWiring.newRuntimeWiring()\n .type(\"Query\", builder -> builder.dataFetcher(\"order\", env -> \"ok\"))\n .build();\n return GraphQL.newGraphQL(new SchemaGenerator().makeExecutableSchema(registry, wiring)).build();\n }\n\n private static void gate(String label, String sdl) {\n System.out.printf(\" %-22s \", label);\n try {\n GraphQlOneOfSchemaGate.verify(sdl);\n System.out.println(\"통과\");\n } catch (RuntimeException refused) {\n System.out.println(refused.getClass().getSimpleName() + \" : \" + refused.getMessage());\n }\n }\n\n private static void library(String label, String sdl) {\n System.out.printf(\" %-22s \", label);\n try {\n build(sdl);\n System.out.println(\"스키마가 만들어짐\");\n } catch (RuntimeException refused) {\n System.out.println(refused.getClass().getSimpleName() + \" : \" + refused.getMessage());\n }\n }\n\n private static void execute(String label, Object selector) {\n var result =\n build(VALID)\n .execute(\n ExecutionInput.newExecutionInput()\n .query(\"query Q($s: OrderSelector!) { order(by: $s) }\")\n .variables(Map.of(\"s\", selector))\n .build());\n System.out.printf(\" %-30s \", label);\n if (result.getErrors().isEmpty()) {\n System.out.println(\"통과 · \" + result.getData().toString());\n } else {\n System.out.println(\"거부 · \" + result.getErrors().get(0).getMessage());\n }\n }\n\n public static void main(String[] args) {\n System.out.println();\n System.out.println(\"[라이브러리가 선언을 어떻게 받는가 · graphql-java 25.0]\");\n library(\"규칙에 맞는 선언\", VALID);\n library(\"규칙을 어긴 선언\", INVALID);\n\n System.out.println();\n System.out.println(\"[같은 두 선언을 스키마 게이트에 넣으면]\");\n gate(\"규칙에 맞는 선언\", VALID);\n gate(\"규칙을 어긴 선언\", INVALID);\n\n System.out.println();\n System.out.println(\"[규칙에 맞는 스키마에 값을 실어 보낸다]\");\n execute(\"구성원 하나만 채움\", Map.of(\"id\", \"o-1\"));\n execute(\"구성원 둘을 채움\", Map.of(\"id\", \"o-1\", \"number\", \"N-1\"));\n execute(\"아무것도 채우지 않음\", Map.of());\n }\n}\nJAVA\njavac -encoding UTF-8 -cp \"$SIB$cp\" -d \"$D/out\" \"$D/OneOfProbe.java\" 2>&1 | head -8\nprintf '%s\\n' '<configuration><root level=\"OFF\"/></configuration>' > \"$D/out/logback.xml\"\njava -Dstdout.encoding=UTF-8 -cp \"$D/out:$SIB$cp\" OneOfProbe 2>&1 | grep -vE '^[0-9]{4}-|^\\s+at |WARN|INFO'\n",
"cwd": "/shared/codebase/clean-architecture-backend-template/src",
"exitCode": 0,
"executedAt": "2026-09-03T08:09:09+00:00",
"sourceRevision": "21234e38cdb9a926cbc92bb97a2aee2e4a7d2916",
"raw": "evidence/raw/a16-f002-oneof-run.txt",
"svg": "evidence/rendered/a16-f002-oneof-run.svg",
"rawSha256": "c77d9b655f27b008b245ea1b676de1f9f9b9a31db53d2f3060348d95a94b0f64",
"lines": 16,
"redaction": "코드베이스 측정과 실행 결과로 교체"
}