Files
document-haness/docs/clean-architecture-backend-template/final/evidence/raw/a05-f019-ssot.txt
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

66 lines
3.1 KiB
Plaintext

# 리프가 선언하는 export 목록
135: private static final Set<String> EXPORTED_PACKAGES =
136- Set.of(
137- // The contracts other leaves are meant to speak.
138- "api",
139- // Capability configuration facades, each assembling its own capability's internals.
140- "notification.configuration",
141- // Cross-cutting seams a composition root legitimately wires.
142- "transaction",
143- "security",
144- "observation",
145- "migration",
146- "hibernate",
147- "fileserver",
148- "failure",
149- "config");
# 컴포지션 루트의 소비자 규칙이 같은 목록을 다시 적는다
* implementation types by name — every store, every repository, the record mapper — which made
* each of them a cross-leaf source contract: moving one to another package, or reducing its
* visibility, broke this module's compile. The notification wiring is a facade the leaf owns now,
* and this keeps the surface from re-growing one convenient import at a time.
*
* <p>The list is the leaf's export allowlist, mirrored here because this is the consumer side of
* the same boundary. {@code JpaModuleBoundaryTest} owns the definition.
*/
@ArchTest
private static final java.util.Set<String> EXPORTED =
java.util.Set.of(
"api",
"notification.configuration",
"transaction",
"security",
"observation",
"migration",
"hibernate",
"fileserver",
"failure",
"config",
// The two vendor entry points. A vendor configuration imports the core JPA
// config rather than the reverse, so there is no single internal entry the
// composition root could gate instead — inverting the import to make one
// produced a package cycle. Admitting exactly these two, and no other
// vendor
// internals, is the narrower price.
"postgresql",
"h2");
# 두 집합의 차이
# 리프 10개 / 루트 12개
# 루트에만 있는 것: ['h2', 'postgresql']
# 리프에만 있는 것: []
# 사본은 정본을 이름으로 적는다
1118: * the same boundary. {@code JpaModuleBoundaryTest} owns the definition.
# app-bootstrap 에서 그 정본 클래스를 언급하는 줄: 1
# 선언 파일 밖에서 EXPORTED_PACKAGES 를 참조하는 자바 코드: 0
# 리프의 export 목록을 쓰는 두 시험이 무엇을 보는가
380: @DisplayName("the export list names only packages that exist")
381- void theExportListNamesOnlyPackagesThatExist() {
382- java.nio.file.Path root = sourceRoot().resolve(ROOT.replace('.', '/'));
396: @DisplayName("every exported package is one the catalog governs")
397- void everyExportedPackageIsGoverned() {
398- Set<String> ungoverned = new TreeSet<>();