docs(keycloak-session-store): take the sentences out of the diagram canvases

The skill says drawings carry names and sentences go in <desc> and the
paragraph beside the figure. I put sentences in node details and edge labels
instead, and 27 of the 28 diagrams shipped with prose inside the canvas —
"예측 다섯 개가 틀렸다", "아홉 번 조용히 실패했다", "막혀서 닿지 않는다".

Only label and details render on the canvas; description does not. So every
sentence moved to a noun phrase and the meaning stays in description, which
was already carrying it.

  막혀서 닿지 않는다              -> 차단
  아홉 번 조용히 실패했다         -> 조용한 실패 9건
  예측 다섯 개가 틀렸다           -> 틀린 예측 5건
  로그아웃이 정리하지 않는다      -> 로그아웃 미정리
  볼륨이 없으면 여기까지다        -> 볼륨 없음

Three node labels were sentences too and became names: 세션 스냅샷, 예측
선기록, 대조군 확보.

What stays is what the rules protect — identifiers, commands and measured
values: PRIMARY KEY (client_registration_id, principal_name),
ValidationFailedException: 1 changesets check sum, nginx -t && nginx -s
reload, SET LOCAL synchronous_commit TO OFF. Those are names of things, not
prose about them.

294 canvas strings across 28 diagrams, none matching a sentence ending,
average 11 characters. All 28 still lint clean and re-rendered.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
DongHyeonka
2026-09-05 11:50:33 +09:00
co-authored by Claude Opus 5
parent 75bed382c8
commit 95c0e680b5
221 changed files with 1156 additions and 1152 deletions
@@ -10,13 +10,13 @@
## Elements and evidence
- **산문으로 적힌 측정 장치** (component): 괄호와 설명으로 남아 있었다. Evidence: L598L610.
- **산문 상태의 측정 장치** (component): 괄호와 설명으로 남아 있었다. Evidence: L598L610.
- **셸 표현식** (component): 붙여넣으면 도는 형태. Evidence: L598L614.
- **실제 실행 확인** (process): 여기서 한 건이 깨졌다. Evidence: L615L622.
- **재현 가능** (component): 실행까지 확인된 것만. Evidence: L615L622.
## Relationships
- **셸 표현식 → 실제 실행 확인:** 돌려본다. Evidence: L615L622.
- **실제 실행 확인 → 재현 가능:** 통과한 것만 남긴다. Evidence: L615L622.
- **산문으로 적힌 측정 장치 → 셸 표현식:** 바꿔 적는다. Evidence: L598L614.
- **셸 표현식 → 실제 실행 확인:** 실행. Evidence: L615L622.
- **실제 실행 확인 → 재현 가능:** 통과분 채택. Evidence: L615L622.
- **산문 상태의 측정 장치 → 셸 표현식:** 명령화. Evidence: L598L614.
@@ -1,7 +1,7 @@
# 명령으로 적는 것과 도는 것
# Question: 절차를 명령으로 적으면 재현이 보장되는가
direction: down
n0: "산문으로 적힌 측정 장치" {
n0: "산문 상태의 측정 장치" {
shape: rectangle
}
n1: "셸 표현식" {
@@ -13,6 +13,6 @@ n2: "실제 실행 확인" {
n3: "재현 가능" {
shape: rectangle
}
n0 -> n1: "바꿔 적는다"
n1 -> n2: "돌려본다"
n2 -> n3: "통과한 것만 남긴다"
n0 -> n1: "명령화"
n1 -> n2: "실행"
n2 -> n3: "통과분 채택"
@@ -2,11 +2,11 @@ digraph techviz {
graph [rankdir=TB, splines=ortho, nodesep=0.55, ranksep=0.85];
node [fontname=Helvetica, fontsize=11, margin="0.18,0.12", style="rounded,filled", fillcolor=white, color="#2d4357", penwidth=1.5];
edge [fontname=Helvetica, fontsize=10, color="#364b5f", penwidth=1.4, arrowsize=0.75];
n0 [label="산문으로 적힌 측정 장치", shape=box, style="rounded,filled"];
n0 [label="산문 상태의 측정 장치", shape=box, style="rounded,filled"];
n1 [label="셸 표현식", shape=box, style="rounded,filled"];
n2 [label="실제 실행 확인", shape=box, style="rounded,filled"];
n3 [label="재현 가능", shape=box, style="rounded,filled"];
n0 -> n1 [label="바꿔 적는다", style=solid];
n1 -> n2 [label="돌려본다", style=solid];
n2 -> n3 [label="통과한 것만 남긴다", style=solid];
n0 -> n1 [label="명령화", style=solid];
n1 -> n2 [label="실행", style=solid];
n2 -> n3 [label="통과분 채택", style=solid];
}
@@ -5,31 +5,31 @@
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="n_prose" value="산문으로 적힌 측정 장치&lt;br/&gt;( curl ... ) &amp; 를 20개 띄우고 wait" tooltip="괄호와 설명으로 남아 있었다. | Evidence: L598-L610" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;strokeColor=#d97706;fillColor=#fffdf5;" vertex="1" parent="1">
<mxGeometry x="70.0" y="60.0" width="237.0" height="71.0" as="geometry"/>
<mxCell id="n_prose" value="산문 상태의 측정 장치&lt;br/&gt;부하 생성기 20건" tooltip="괄호와 설명으로 남아 있었다. | Evidence: L598-L610" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;strokeColor=#d97706;fillColor=#fffdf5;" vertex="1" parent="1">
<mxGeometry x="70.0" y="60.0" width="150.0" height="71.0" as="geometry"/>
</mxCell>
<mxCell id="n_command" value="셸 표현식" tooltip="붙여넣으면 도는 형태. | Evidence: L598-L614" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="113.5" y="227.0" width="150.0" height="64.0" as="geometry"/>
<mxGeometry x="70.0" y="227.0" width="150.0" height="64.0" as="geometry"/>
</mxCell>
<mxCell id="n_execute" value="실제 실행 확인&lt;br/&gt;일회성 파드의 출력 유실" tooltip="여기서 한 건이 깨졌다. | Evidence: L615-L622" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;strokeColor=#2563eb;strokeWidth=2;" vertex="1" parent="1">
<mxGeometry x="113.5" y="387.0" width="150.0" height="71.0" as="geometry"/>
<mxGeometry x="70.0" y="387.0" width="150.0" height="71.0" as="geometry"/>
</mxCell>
<mxCell id="n_verified" value="재현 가능&lt;br/&gt;상주 탐침으로 20/20" tooltip="실행까지 확인된 것만. | Evidence: L615-L622" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;strokeColor=#2563eb;strokeWidth=2;" vertex="1" parent="1">
<mxGeometry x="113.5" y="554.0" width="150.0" height="71.0" as="geometry"/>
<mxCell id="n_verified" value="재현 가능&lt;br/&gt;상주 탐침 20/20" tooltip="실행까지 확인된 것만. | Evidence: L615-L622" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;strokeColor=#2563eb;strokeWidth=2;" vertex="1" parent="1">
<mxGeometry x="70.0" y="554.0" width="150.0" height="71.0" as="geometry"/>
</mxCell>
<mxCell id="e_c-e" value="돌려본다" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_command" target="n_execute">
<mxCell id="e_c-e" value="실행" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_command" target="n_execute">
<mxGeometry relative="1" as="geometry">
<mxPoint x="212.5" y="339.0" as="offset"/>
<mxPoint x="169.0" y="339.0" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_e-v" value="통과한 것만 남긴다" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_execute" target="n_verified">
<mxCell id="e_e-v" value="통과분 채택" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_execute" target="n_verified">
<mxGeometry relative="1" as="geometry">
<mxPoint x="212.5" y="506.0" as="offset"/>
<mxPoint x="169.0" y="506.0" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_p-c" value="바꿔 적는다" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_prose" target="n_command">
<mxCell id="e_p-c" value="명령화" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_prose" target="n_command">
<mxGeometry relative="1" as="geometry">
<mxPoint x="212.5" y="179.0" as="offset"/>
<mxPoint x="169.0" y="179.0" as="offset"/>
</mxGeometry>
</mxCell>
</root>
@@ -6,7 +6,7 @@
{
"id": "edge-c-e",
"type": "arrow",
"x": 188.5,
"x": 145.0,
"y": 291.0,
"width": 0.0,
"height": 96.0,
@@ -66,7 +66,7 @@
{
"id": "edge-label-c-e",
"type": "text",
"x": 167.5,
"x": 124.0,
"y": 327.0,
"width": 90,
"height": 24,
@@ -94,18 +94,18 @@
"locked": false,
"fontSize": 13,
"fontFamily": 5,
"text": "돌려본다",
"text": "실행",
"textAlign": "center",
"verticalAlign": "middle",
"containerId": null,
"originalText": "돌려본다",
"originalText": "실행",
"autoResize": true,
"lineHeight": 1.25
},
{
"id": "edge-e-v",
"type": "arrow",
"x": 188.5,
"x": 145.0,
"y": 458.0,
"width": 0.0,
"height": 96.0,
@@ -165,7 +165,7 @@
{
"id": "edge-label-e-v",
"type": "text",
"x": 167.5,
"x": 124.0,
"y": 494.0,
"width": 90,
"height": 24,
@@ -193,18 +193,18 @@
"locked": false,
"fontSize": 13,
"fontFamily": 5,
"text": "통과한 것만 남긴다",
"text": "통과분 채택",
"textAlign": "center",
"verticalAlign": "middle",
"containerId": null,
"originalText": "통과한 것만 남긴다",
"originalText": "통과분 채택",
"autoResize": true,
"lineHeight": 1.25
},
{
"id": "edge-p-c",
"type": "arrow",
"x": 188.5,
"x": 145.0,
"y": 131.0,
"width": 0.0,
"height": 96.0,
@@ -264,7 +264,7 @@
{
"id": "edge-label-p-c",
"type": "text",
"x": 167.5,
"x": 124.0,
"y": 167.0,
"width": 90,
"height": 24,
@@ -292,11 +292,11 @@
"locked": false,
"fontSize": 13,
"fontFamily": 5,
"text": "바꿔 적는다",
"text": "명령화",
"textAlign": "center",
"verticalAlign": "middle",
"containerId": null,
"originalText": "바꿔 적는다",
"originalText": "명령화",
"autoResize": true,
"lineHeight": 1.25
},
@@ -305,7 +305,7 @@
"type": "rectangle",
"x": 70.0,
"y": 60.0,
"width": 237.0,
"width": 150.0,
"height": 71.0,
"angle": 0,
"strokeColor": "#1e1e1e",
@@ -335,7 +335,7 @@
"type": "text",
"x": 80.0,
"y": 70.0,
"width": 217.0,
"width": 130.0,
"height": 51.0,
"angle": 0,
"strokeColor": "#1e1e1e",
@@ -361,18 +361,18 @@
"locked": false,
"fontSize": 15,
"fontFamily": 5,
"text": "산문으로 적힌 측정 장치\n( curl ... ) & 를 20개 띄우고 wait",
"text": "산문 상태의 측정 장치\n부하 생성기 20건",
"textAlign": "center",
"verticalAlign": "middle",
"containerId": null,
"originalText": "산문으로 적힌 측정 장치\n( curl ... ) & 를 20개 띄우고 wait",
"originalText": "산문 상태의 측정 장치\n부하 생성기 20건",
"autoResize": true,
"lineHeight": 1.25
},
{
"id": "node-command",
"type": "rectangle",
"x": 113.5,
"x": 70.0,
"y": 227.0,
"width": 150.0,
"height": 64.0,
@@ -402,7 +402,7 @@
{
"id": "node-label-command",
"type": "text",
"x": 123.5,
"x": 80.0,
"y": 237.0,
"width": 130.0,
"height": 44.0,
@@ -441,7 +441,7 @@
{
"id": "node-execute",
"type": "rectangle",
"x": 113.5,
"x": 70.0,
"y": 387.0,
"width": 150.0,
"height": 71.0,
@@ -471,7 +471,7 @@
{
"id": "node-label-execute",
"type": "text",
"x": 123.5,
"x": 80.0,
"y": 397.0,
"width": 130.0,
"height": 51.0,
@@ -510,7 +510,7 @@
{
"id": "node-verified",
"type": "rectangle",
"x": 113.5,
"x": 70.0,
"y": 554.0,
"width": 150.0,
"height": 71.0,
@@ -540,7 +540,7 @@
{
"id": "node-label-verified",
"type": "text",
"x": 123.5,
"x": 80.0,
"y": 564.0,
"width": 130.0,
"height": 51.0,
@@ -568,11 +568,11 @@
"locked": false,
"fontSize": 15,
"fontFamily": 5,
"text": "재현 가능\n상주 탐침으로 20/20",
"text": "재현 가능\n상주 탐침 20/20",
"textAlign": "center",
"verticalAlign": "middle",
"containerId": null,
"originalText": "재현 가능\n상주 탐침으로 20/20",
"originalText": "재현 가능\n상주 탐침 20/20",
"autoResize": true,
"lineHeight": 1.25
}
@@ -2,7 +2,7 @@
"harness_version": "0.2.0",
"spec_id": "reproducibility-gap",
"spec_version": "1.1",
"spec_sha256": "f869b1dec58438616a980ae048ea5c43e8f56634949eaddb25d06057728c008f",
"spec_sha256": "9abe66c731b4e2a6740d245cd6c9018517553efc0a17d4bedef56adde13ad97c",
"source_context": {
"document": "docs/keycloak-session-store/final/document.md",
"document_sha256": "1d44cba1905544d92f1d26ae36a8deb64a3db3914d6b488fd30d6ae7f8cfbabe",
@@ -1,10 +1,10 @@
%% 명령으로 적는 것과 도는 것
%% question: 절차를 명령으로 적으면 재현이 보장되는가
flowchart TB
n0["산문으로 적힌 측정 장치"]
n0["산문 상태의 측정 장치"]
n1["셸 표현식"]
n2["실제 실행 확인"]
n3["재현 가능"]
n0 -->|"바꿔 적는다"| n1
n1 -->|"돌려본다"| n2
n2 -->|"통과한 것만 남긴다"| n3
n0 -->|"명령화"| n1
n1 -->|"실행"| n2
n2 -->|"통과분 채택"| n3
@@ -50,35 +50,35 @@
</style>
</defs>
<rect class="canvas" width="680" height="670" />
<polyline class="edge kind-request style-solid emphasis-normal" points="188.5,291.0 188.5,339.0 188.5,339.0 188.5,387.0" data-evidence="615-622" />
<rect class="edge-label-bg" x="190.1" y="325.0" width="44.8" height="22" rx="3" />
<text class="edge-label" x="212.5" y="340.0">돌려본다</text>
<polyline class="edge kind-request style-solid emphasis-normal" points="188.5,458.0 188.5,506.0 188.5,506.0 188.5,554.0" data-evidence="615-622" />
<rect class="edge-label-bg" x="170.0" y="492.0" width="85.0" height="22" rx="3" />
<text class="edge-label" x="212.5" y="507.0">통과한 것만 남긴다</text>
<polyline class="edge kind-request style-solid emphasis-normal" points="188.5,131.0 188.5,179.0 188.5,179.0 188.5,227.0" data-evidence="598-614" />
<rect class="edge-label-bg" x="183.4" y="165.0" width="58.2" height="22" rx="3" />
<text class="edge-label" x="212.5" y="180.0">바꿔 적는다</text>
<polyline class="edge kind-request style-solid emphasis-normal" points="145.0,291.0 145.0,339.0 145.0,339.0 145.0,387.0" data-evidence="615-622" />
<rect class="edge-label-bg" x="147.0" y="325.0" width="44.0" height="22" rx="3" />
<text class="edge-label" x="169.0" y="340.0">실행</text>
<polyline class="edge kind-request style-solid emphasis-normal" points="145.0,458.0 145.0,506.0 145.0,506.0 145.0,554.0" data-evidence="615-622" />
<rect class="edge-label-bg" x="139.9" y="492.0" width="58.2" height="22" rx="3" />
<text class="edge-label" x="169.0" y="507.0">통과분 채택</text>
<polyline class="edge kind-request style-solid emphasis-normal" points="145.0,131.0 145.0,179.0 145.0,179.0 145.0,227.0" data-evidence="598-614" />
<rect class="edge-label-bg" x="147.0" y="165.0" width="44.0" height="22" rx="3" />
<text class="edge-label" x="169.0" y="180.0">명령화</text>
<g id="node-prose">
<rect class="node-shape kind-component emphasis-warning role-source" data-evidence="598-610" x="70.0" y="60.0" width="237.0" height="71.0" rx="7" />
<text class="node-label" x="188.5" y="87.0">산문으로 적힌 측정 장치</text>
<line class="node-detail-divider" x1="84.0" y1="108.0" x2="293.0" y2="108.0" />
<text class="node-detail" x="86.0" y="125.0">( curl ... ) &amp; 를 20개 띄우고 wait</text>
<rect class="node-shape kind-component emphasis-warning role-source" data-evidence="598-610" x="70.0" y="60.0" width="150.0" height="71.0" rx="7" />
<text class="node-label" x="145.0" y="87.0">산문 상태의 측정 장치</text>
<line class="node-detail-divider" x1="84.0" y1="108.0" x2="206.0" y2="108.0" />
<text class="node-detail" x="86.0" y="125.0">부하 생성기 20건</text>
</g>
<g id="node-command">
<rect class="node-shape kind-component emphasis-normal role-control" data-evidence="598-614" x="113.5" y="227.0" width="150.0" height="64.0" rx="7" />
<text class="node-label" x="188.5" y="257.0">셸 표현식</text>
<rect class="node-shape kind-component emphasis-normal role-control" data-evidence="598-614" x="70.0" y="227.0" width="150.0" height="64.0" rx="7" />
<text class="node-label" x="145.0" y="257.0">셸 표현식</text>
</g>
<g id="node-execute">
<rect class="node-shape kind-process emphasis-primary role-control" data-evidence="615-622" x="113.5" y="387.0" width="150.0" height="71.0" rx="7" />
<text class="node-label" x="188.5" y="414.0">실제 실행 확인</text>
<line class="node-detail-divider" x1="127.5" y1="435.0" x2="249.5" y2="435.0" />
<text class="node-detail" x="129.5" y="452.0">일회성 파드의 출력 유실</text>
<rect class="node-shape kind-process emphasis-primary role-control" data-evidence="615-622" x="70.0" y="387.0" width="150.0" height="71.0" rx="7" />
<text class="node-label" x="145.0" y="414.0">실제 실행 확인</text>
<line class="node-detail-divider" x1="84.0" y1="435.0" x2="206.0" y2="435.0" />
<text class="node-detail" x="86.0" y="452.0">일회성 파드의 출력 유실</text>
</g>
<g id="node-verified">
<rect class="node-shape kind-component emphasis-primary role-target" data-evidence="615-622" x="113.5" y="554.0" width="150.0" height="71.0" rx="7" />
<text class="node-label" x="188.5" y="581.0">재현 가능</text>
<line class="node-detail-divider" x1="127.5" y1="602.0" x2="249.5" y2="602.0" />
<text class="node-detail" x="129.5" y="619.0">상주 탐침으로 20/20</text>
<rect class="node-shape kind-component emphasis-primary role-target" data-evidence="615-622" x="70.0" y="554.0" width="150.0" height="71.0" rx="7" />
<text class="node-label" x="145.0" y="581.0">재현 가능</text>
<line class="node-detail-divider" x1="84.0" y1="602.0" x2="206.0" y2="602.0" />
<text class="node-detail" x="86.0" y="619.0">상주 탐침 20/20</text>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB