Files
document-haness/docs/clean-architecture-backend-template/final/evidence/rendered/analysis-finding-a05-f010.svg
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

148 lines
27 KiB
XML

<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="2900" viewBox="0 0 1200 2900" role="img">
<title>terminal evidence</title>
<desc>Terminal-style rendering generated from retained command output. Sensitive-looking values are redacted in the visual asset.</desc>
<rect x="1" y="1" width="1198" height="2898" rx="14" fill="#0d1117" stroke="#30363d"/>
<rect x="1" y="1" width="1198" height="44" rx="14" fill="#161b22"/>
<rect x="1" y="30" width="1198" height="14" fill="#161b22"/>
<circle cx="24" cy="22" r="6" fill="#ff5f57"/>
<circle cx="44" cy="22" r="6" fill="#febc2e"/>
<circle cx="64" cy="22" r="6" fill="#28c840"/>
<text x="92" y="27" fill="#8b949e" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace">terminal evidence</text>
<text x="24" y="68" fill="#c9d1d9" font-size="15" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">$ #!/bin/bash
set -euo pipefail
cd /shared/codebase/clean-architecture-backend-template
hits() {
local out rc
out=$(</tspan><tspan x="24" dy="22">git grep -nE &quot;$1&quot; -- &quot;$2&quot;) &amp;&amp; rc=0 || rc=$?
[ &quot;$rc&quot; -le 1 ] || { echo &quot;SEARCH FAILED rc=$rc : $1&quot; &gt;&amp;2; return 2; }
[</tspan><tspan x="24" dy="22"> &quot;$rc&quot; -eq 0 ] &amp;&amp; printf &#x27;%s\n&#x27; &quot;$out&quot; || true
}
mod() { sed -E &#x27;s#^src/(.*)/src/([a-zA-Z]+)/java/.*/([A-Za-z]+\.java):(</tspan><tspan x="24" dy="22">[0-9]+): *# \1 · \2 · \3:\4 #&#x27;; }
at() { awk -v s=&quot;$2&quot; -v e=&quot;$3&quot; -v n=&quot;$4&quot; &#x27;NR&gt;=s &amp;&amp; NR&lt;=e {printf &quot; %s:%d %s\n&quot;, n</tspan><tspan x="24" dy="22">, NR, $0}&#x27; &quot;$1&quot;; }
B=src/app-bootstrap/src/main/java/dev/caskeleton/bootstrap/autoconfigure/jpa/JpaTransactionAutoConfig</tspan><tspan x="24" dy="22">uration.java
S=src/adapter/outbound/persistence-jpa/src/main/java/dev/caskeleton/adapter/outbound/persistence/transactio</tspan><tspan x="24" dy="22">n/SpringTransactionPort.java
test -f &quot;$B&quot; &amp;&amp; test -f &quot;$S&quot;
echo &quot;# 자동설정 주석이 코디네이터를 어떻게 설명하는가&quot;
at &quot;$</tspan><tspan x="24" dy="22">B&quot; 28 55 JpaTransactionAutoConfiguration.java
echo
echo &quot;# PolicyTransactionPort 를 구현한다고 선언한 클래스&quot;
hits &#x27;imp</tspan><tspan x="24" dy="22">lements[[:space:]]+([A-Za-z0-9_.]+,[[:space:]]*)*PolicyTransactionPort&#x27; &#x27;src/**/*.java&#x27; | mod
echo &quot; [자기시험] 없는 이</tspan><tspan x="24" dy="22">름으로 같은 검색 : $(
hits &#x27;implements[[:space:]]+PolicyTransactionPortZZZ&#x27; &#x27;src/**/*.java&#x27; | grep -c . || true) 개&quot;
e</tspan><tspan x="24" dy="22">cho &quot; [대조] implements TransactionPort : $(
hits &#x27;implements[[:space:]]+([A-Za-z0-9_.]+,[[:space:]]*)*TransactionPor</tspan><tspan x="24" dy="22">t&#x27; &#x27;src/**/*.java&#x27; | grep -c . || true) 개&quot;
echo
echo &quot;# 그 구현체의 선언과 자바독&quot;
at &quot;$S&quot; 24 40 SpringTransactionPort</tspan><tspan x="24" dy="22">.java
echo
echo &quot;# 코디네이터와 런타임 빈이 무엇을 만드는가&quot;
hits &#x27;@Bean&#x27; &quot;$B&quot; | sed -E &#x27;s#^([0-9]+): *# JpaTransactio</tspan><tspan x="24" dy="22">nAutoConfiguration.java:\1 #&#x27;
{ grep -nE &#x27;^ public [A-Za-z]&#x27; &quot;$B&quot; || true; } | sed -E &#x27;s#^([0-9]+): *# JpaTransaction</tspan><tspan x="24" dy="22">AutoConfiguration.java:\1 #&#x27;
echo
echo &quot;# 두 스택을 부르는 자리&quot;
for n in PolicyTransactionPort FullTransactionRetryCo</tspan><tspan x="24" dy="22">ordinator SpringJpaTransactionExecutor SpringTransactionPort; do
printf &#x27; %s 를 참조하는 main 파일 : %s 개\n&#x27; &quot;$n&quot; \
</tspan><tspan x="24" dy="22"> &quot;$(hits &quot;$n&quot; &#x27;src/**/*.java&#x27; | { grep &#x27;/src/main/&#x27; || true; } | cut -d: -f1 | sort -u | grep -c . || true)&quot;
done
ech</tspan><tspan x="24" dy="22">o &quot; PolicyTransactionPort 를 참조하는 main 파일 :&quot;
hits &#x27;PolicyTransactionPort&#x27; &#x27;src/**/*.java&#x27; | { grep &#x27;/src/main/&#x27; |</tspan><tspan x="24" dy="22">| true; } | cut -d: -f1 | sort -u | sed &#x27;s#.*/# #&#x27;
echo
echo &quot;# 문서 쪽 서술&quot;
{ git grep -rn &#x27;PolicyTransactionPort&#x27;</tspan><tspan x="24" dy="22"> -- &#x27;docs/**/*.md&#x27; &#x27;src/**/*.md&#x27; || true; } \
| sed -E &#x27;s#^([^:]+):([0-9]+): *# \1:\2 #&#x27; | head -8
</tspan></text>
<text x="24" y="508" fill="#8b949e" font-size="13" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">cwd: /shared/codebase/clean-architecture-backend-template</tspan></text>
<text x="24" y="530" fill="#8b949e" font-size="13" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">time: 2026-09-04T06:08:24+00:00 · exit 0</tspan></text>
<line x1="24" y1="544" x2="1176" y2="544" stroke="#30363d"/>
<text x="24" y="584" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 자동설정 주석이 코디네이터를 어떻게 설명하는가</tspan></text>
<text x="24" y="606" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaTransactionAutoConfiguration.java:28 *</tspan></text>
<text x="24" y="628" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaTransactionAutoConfiguration.java:29 * &lt;p&gt;Plain construction rather than Spring auto-configuration: this repository&#x27;s comp</tspan><tspan x="24" dy="22">osition root</tspan></text>
<text x="24" y="672" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaTransactionAutoConfiguration.java:30 * owns wiring, and an adapter leaf that auto-configured a transaction manager would s</tspan><tspan x="24" dy="22">ilently</tspan></text>
<text x="24" y="716" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaTransactionAutoConfiguration.java:31 * replace one the application had deliberately chosen.</tspan></text>
<text x="24" y="738" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaTransactionAutoConfiguration.java:32 *</tspan></text>
<text x="24" y="760" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaTransactionAutoConfiguration.java:33 * &lt;p&gt;There is no declarative retry annotation any more. {@code @RetryableJpaTransacti</tspan><tspan x="24" dy="22">on} lived in</tspan></text>
<text x="24" y="804" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaTransactionAutoConfiguration.java:34 * the persistence leaf and documented itself as something an application service woul</tspan><tspan x="24" dy="22">d put on its</tspan></text>
<text x="24" y="848" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaTransactionAutoConfiguration.java:35 * own methods — which application-core cannot do without importing an outbound adapt</tspan><tspan x="24" dy="22">er and</tspan></text>
<text x="24" y="892" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaTransactionAutoConfiguration.java:36 * inverting the dependency this architecture is built on. The canonical boundary is {</tspan><tspan x="24" dy="22">@code</tspan></text>
<text x="24" y="936" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaTransactionAutoConfiguration.java:37 * PolicyTransactionPort.inTransaction(TransactionRequest, Supplier)}; the retry coord</tspan><tspan x="24" dy="22">inator below</tspan></text>
<text x="24" y="980" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaTransactionAutoConfiguration.java:38 * is what implements it, not a second way to ask for the same thing.</tspan></text>
<text x="24" y="1002" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaTransactionAutoConfiguration.java:39 */</tspan></text>
<text x="24" y="1024" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaTransactionAutoConfiguration.java:40 public final class JpaTransactionAutoConfiguration {</tspan></text>
<text x="24" y="1046" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaTransactionAutoConfiguration.java:41 </tspan></text>
<text x="24" y="1068" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaTransactionAutoConfiguration.java:42 /** How long a logical operation may keep retrying before the budget is spent regard</tspan><tspan x="24" dy="22">less. */</tspan></text>
<text x="24" y="1112" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaTransactionAutoConfiguration.java:43 public static final Duration DEFAULT_MAX_RETRY_ELAPSED = Duration.ofSeconds(30);</tspan></text>
<text x="24" y="1134" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaTransactionAutoConfiguration.java:44 </tspan></text>
<text x="24" y="1156" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaTransactionAutoConfiguration.java:45 private final Clock clock;</tspan></text>
<text x="24" y="1178" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaTransactionAutoConfiguration.java:46 </tspan></text>
<text x="24" y="1200" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaTransactionAutoConfiguration.java:47 public JpaTransactionAutoConfiguration(Clock clock) {</tspan></text>
<text x="24" y="1222" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaTransactionAutoConfiguration.java:48 this.clock = Objects.requireNonNull(clock, &quot;clock&quot;);</tspan></text>
<text x="24" y="1244" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaTransactionAutoConfiguration.java:49 }</tspan></text>
<text x="24" y="1266" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaTransactionAutoConfiguration.java:50 </tspan></text>
<text x="24" y="1288" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaTransactionAutoConfiguration.java:51 /**</tspan></text>
<text x="24" y="1310" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaTransactionAutoConfiguration.java:52 * The commit-phase classifier the evidence-aware transaction manager is built with.</tspan></text>
<text x="24" y="1332" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaTransactionAutoConfiguration.java:53 *</tspan></text>
<text x="24" y="1354" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaTransactionAutoConfiguration.java:54 * &lt;p&gt;The manager itself is constructed inside the persistence leaf, through {@code</tspan></text>
<text x="24" y="1376" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaTransactionAutoConfiguration.java:55 * EvidenceAwareJpaTransactionManager.standard(entityManagerFactory, clock)}. The co</tspan><tspan x="24" dy="22">mposition root</tspan></text>
<text x="24" y="1420" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
<text x="24" y="1442" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># PolicyTransactionPort 를 구현한다고 선언한 클래스</tspan></text>
<text x="24" y="1464" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> adapter/outbound/persistence-jpa · main · SpringTransactionPort.java:31 public class SpringTransactionPort implements Polic</tspan><tspan x="24" dy="22">yTransactionPort {</tspan></text>
<text x="24" y="1508" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> [자기시험] 없는 이름으로 같은 검색 : 0 개</tspan></text>
<text x="24" y="1530" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> [대조] implements TransactionPort : 21 개</tspan></text>
<text x="24" y="1552" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
<text x="24" y="1574" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 그 구현체의 선언과 자바독</tspan></text>
<text x="24" y="1596" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> SpringTransactionPort.java:24 </tspan></text>
<text x="24" y="1618" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> SpringTransactionPort.java:25 /**</tspan></text>
<text x="24" y="1640" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> SpringTransactionPort.java:26 * Spring-backed {@link PolicyTransactionPort}: one pre-built {@link TransactionTemplate} per mo</tspan><tspan x="24" dy="22">de,</tspan></text>
<text x="24" y="1684" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> SpringTransactionPort.java:27 * all pinned to {@link Isolation#READ_COMMITTED}. See README &quot;transaction&quot; for why the template</tspan><tspan x="24" dy="22">s</tspan></text>
<text x="24" y="1728" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> SpringTransactionPort.java:28 * are pre-built (mutable-template race) and CLAUDE.md for the mode table.</tspan></text>
<text x="24" y="1750" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> SpringTransactionPort.java:29 */</tspan></text>
<text x="24" y="1772" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> SpringTransactionPort.java:30 @Component</tspan></text>
<text x="24" y="1794" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> SpringTransactionPort.java:31 public class SpringTransactionPort implements PolicyTransactionPort {</tspan></text>
<text x="24" y="1816" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> SpringTransactionPort.java:32 </tspan></text>
<text x="24" y="1838" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> SpringTransactionPort.java:33 private final TransactionTemplate writeTemplate;</tspan></text>
<text x="24" y="1860" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> SpringTransactionPort.java:34 private final TransactionTemplate readTemplate;</tspan></text>
<text x="24" y="1882" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> SpringTransactionPort.java:35 private final TransactionTemplate requiresNewTemplate;</tspan></text>
<text x="24" y="1904" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> SpringTransactionPort.java:36 private final SpringPolicyTransactionPort policyExecutor;</tspan></text>
<text x="24" y="1926" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> SpringTransactionPort.java:37 private final PersistenceExceptionTranslator exceptionTranslator;</tspan></text>
<text x="24" y="1948" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> SpringTransactionPort.java:38 </tspan></text>
<text x="24" y="1970" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> SpringTransactionPort.java:39 public SpringTransactionPort(PlatformTransactionManager transactionManager) {</tspan></text>
<text x="24" y="1992" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> SpringTransactionPort.java:40 this(</tspan></text>
<text x="24" y="2014" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
<text x="24" y="2036" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 코디네이터와 런타임 빈이 무엇을 만드는가</tspan></text>
<text x="24" y="2058" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaTransactionAutoConfiguration.java:43 public static final Duration DEFAULT_MAX_RETRY_ELAPSED = Duration.ofSeconds(30);</tspan></text>
<text x="24" y="2080" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaTransactionAutoConfiguration.java:47 public JpaTransactionAutoConfiguration(Clock clock) {</tspan></text>
<text x="24" y="2102" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaTransactionAutoConfiguration.java:61 public CommitFailureClassifier commitFailureClassifier() {</tspan></text>
<text x="24" y="2124" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaTransactionAutoConfiguration.java:66 public SpringJpaTransactionExecutor transactionExecutor(</tspan></text>
<text x="24" y="2146" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaTransactionAutoConfiguration.java:82 public SpringJpaTransactionExecutor transactionExecutor(</tspan></text>
<text x="24" y="2168" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaTransactionAutoConfiguration.java:99 public FullTransactionRetryCoordinator retryCoordinator(</tspan></text>
<text x="24" y="2190" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaTransactionAutoConfiguration.java:107 public FullTransactionRetryCoordinator retryCoordinator(</tspan></text>
<text x="24" y="2212" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaTransactionAutoConfiguration.java:114 public RetrySleeper retrySleeper() {</tspan></text>
<text x="24" y="2234" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
<text x="24" y="2256" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 두 스택을 부르는 자리</tspan></text>
<text x="24" y="2278" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> PolicyTransactionPort 를 참조하는 main 파일 : 4 개</tspan></text>
<text x="24" y="2300" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> FullTransactionRetryCoordinator 를 참조하는 main 파일 : 4 개</tspan></text>
<text x="24" y="2322" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> SpringJpaTransactionExecutor 를 참조하는 main 파일 : 4 개</tspan></text>
<text x="24" y="2344" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> SpringTransactionPort 를 참조하는 main 파일 : 4 개</tspan></text>
<text x="24" y="2366" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> PolicyTransactionPort 를 참조하는 main 파일 :</tspan></text>
<text x="24" y="2388" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> SpringPolicyTransactionPort.java</tspan></text>
<text x="24" y="2410" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> SpringTransactionPort.java</tspan></text>
<text x="24" y="2432" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> JpaTransactionAutoConfiguration.java</tspan></text>
<text x="24" y="2454" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> PolicyTransactionPort.java</tspan></text>
<text x="24" y="2476" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
<text x="24" y="2498" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 문서 쪽 서술</tspan></text>
<text x="24" y="2520" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> docs/reviews/2026-08-14-jpa-module-code-review.md:31 5. application이 이미 사용하는 `PolicyTransactionPort`와 새 JPA executor</tspan><tspan x="24" dy="22">/AOP 계약이 두 벌로 존재하고,</tspan></text>
<text x="24" y="2564" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> docs/reviews/2026-08-14-jpa-module-code-review.md:41 - `PolicyTransactionPort`를 application-facing transaction SSOT로 유지하</tspan><tspan x="24" dy="22">고 병렬 transaction API를 더</tspan></text>
<text x="24" y="2608" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> docs/reviews/2026-08-14-jpa-module-code-review.md:119 | JPA-007 | P1 | High | transaction authority와 application contract가 </tspan><tspan x="24" dy="22">두 벌 | `PolicyTransactionPort` 단일 facade로 통합 |</tspan></text>
<text x="24" y="2652" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> docs/reviews/2026-08-14-jpa-module-code-review.md:404 - application에는 `TransactionPort`, `PolicyTransactionPort`, `Transact</tspan><tspan x="24" dy="22">ionRequest`,</tspan></text>
<text x="24" y="2696" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> docs/reviews/2026-08-14-jpa-module-code-review.md:406 - live adapter인 `SpringTransactionPort.java:31-32`는 `@Component`이며 </tspan><tspan x="24" dy="22">`PolicyTransactionPort`를</tspan></text>
<text x="24" y="2740" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> docs/reviews/2026-08-14-jpa-module-code-review.md:427 1. 템플릿의 canonical boundary를 `PolicyTransactionPort.inTransaction(T</tspan><tspan x="24" dy="22">ransactionRequest, Supplier)`로</tspan></text>
<text x="24" y="2784" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> docs/reviews/2026-08-14-jpa-module-code-review.md:442 - application unit에서 fake `PolicyTransactionPort`로 committed, determ</tspan><tspan x="24" dy="22">inate rollback, indeterminate,</tspan></text>
<text x="24" y="2828" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> docs/reviews/2026-08-14-jpa-module-code-review.md:1291 | application transaction 계약 두 벌 | Facade + Adapter | `PolicyTrans</tspan><tspan x="24" dy="22">actionPort` 구현 | application port 하나만 public, JPA engine은 internal |</tspan></text>
</svg>