Files
document-haness/docs/clean-architecture-backend-template/final/evidence/raw/analysis-finding-a06-f002.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

163 lines
13 KiB
Plaintext

# 가드가 자기 목적을 어떻게 적는가
MongoNamespaceContractTest.java:14 /**
MongoNamespaceContractTest.java:15 * Production code and configuration name the canonical Mongo namespace (MNG-INT-002).
MongoNamespaceContractTest.java:16 *
MongoNamespaceContractTest.java:17 * <p>{@code spring.data.mongodb.*} is deprecated at error level in Spring Boot 4's metadata; the
MongoNamespaceContractTest.java:18 * canonical namespace is {@code spring.mongodb.*}. The runtime was never on the wrong one — every
MongoNamespaceContractTest.java:19 * Compose lane supplies {@code SPRING_MONGODB_URI} and {@code local-mongo} passes against a real
MongoNamespaceContractTest.java:20 * replica set — but {@code MongoPersistenceSettings}' own Javadoc pointed operators at the
MongoNamespaceContractTest.java:21 * deprecated key, which is the worst place for that drift to sit: somebody reads the class that
MongoNamespaceContractTest.java:22 * owns the switch, sets the property it names, and inherits a deprecation they did not choose.
MongoNamespaceContractTest.java:23 *
MongoNamespaceContractTest.java:24 * <p>Comments are stripped before the check. A sentence recording that the old namespace is
MongoNamespaceContractTest.java:25 * deprecated is the opposite of the defect — the defect was a document telling an operator to use
MongoNamespaceContractTest.java:26 * it. Resources are checked whole, because a key in a YAML file is never commentary.
MongoNamespaceContractTest.java:27 */
MongoNamespaceContractTest.java:28 class MongoNamespaceContractTest {
MongoNamespaceContractTest.java:29
MongoNamespaceContractTest.java:30 private static final String RETIRED_NAMESPACE = "spring.data.mongodb.";
MongoNamespaceContractTest.java:31
# 두 시험이 무엇을 보는가
MongoNamespaceContractTest.java:32 @Test
MongoNamespaceContractTest.java:33 @DisplayName("no production source names the deprecated namespace outside a comment")
MongoNamespaceContractTest.java:34 void noProductionSourceNamesTheDeprecatedNamespace() {
MongoNamespaceContractTest.java:35 List<Path> sources = productionSources(".java").toList();
MongoNamespaceContractTest.java:36
MongoNamespaceContractTest.java:37 assertThat(sources)
MongoNamespaceContractTest.java:38 .as("a scan that reached no source would report every reference as absent")
MongoNamespaceContractTest.java:39 .isNotEmpty();
MongoNamespaceContractTest.java:40
MongoNamespaceContractTest.java:41 List<String> offenders =
MongoNamespaceContractTest.java:42 sources.stream()
MongoNamespaceContractTest.java:43 .filter(path -> withoutJavaComments(read(path)).contains(RETIRED_NAMESPACE))
MongoNamespaceContractTest.java:44 .map(path -> path.getFileName().toString())
MongoNamespaceContractTest.java:45 .sorted()
MongoNamespaceContractTest.java:46 .toList();
MongoNamespaceContractTest.java:47
MongoNamespaceContractTest.java:48 assertThat(offenders)
MongoNamespaceContractTest.java:49 .as(
MongoNamespaceContractTest.java:50 "the canonical namespace is spring.mongodb.*; the old one is an error-level deprecation")
MongoNamespaceContractTest.java:51 .isEmpty();
MongoNamespaceContractTest.java:52 }
MongoNamespaceContractTest.java:53
MongoNamespaceContractTest.java:54 @Test
MongoNamespaceContractTest.java:55 @DisplayName("no shipped resource binds the deprecated namespace")
MongoNamespaceContractTest.java:56 void noShippedResourceBindsTheDeprecatedNamespace() {
MongoNamespaceContractTest.java:57 List<String> offenders =
MongoNamespaceContractTest.java:58 Stream.concat(productionSources(".yml"), productionSources(".properties"))
MongoNamespaceContractTest.java:59 .filter(path -> read(path).contains(RETIRED_NAMESPACE))
MongoNamespaceContractTest.java:60 .map(Path::toString)
MongoNamespaceContractTest.java:61 .sorted()
MongoNamespaceContractTest.java:62 .toList();
MongoNamespaceContractTest.java:63
MongoNamespaceContractTest.java:64 assertThat(offenders).as("a key in a configuration file is never commentary").isEmpty();
MongoNamespaceContractTest.java:65 }
# 그 탐색 범위를 만드는 코드
MongoNamespaceContractTest.java:67 /** Strips {@code //} and block comments, leaving the code a compiler would act on. */
MongoNamespaceContractTest.java:68 private static String withoutJavaComments(String source) {
MongoNamespaceContractTest.java:69 return source.replaceAll("(?s)/\\*.*?\\*/", " ").replaceAll("(?m)//.*$", " ");
MongoNamespaceContractTest.java:70 }
MongoNamespaceContractTest.java:71
MongoNamespaceContractTest.java:72 private static Stream<Path> productionSources(String suffix) {
MongoNamespaceContractTest.java:73 Path root = repositoryRoot().resolve("src");
MongoNamespaceContractTest.java:74 return Stream.of("adapter/outbound/persistence-mongo", "app-bootstrap")
MongoNamespaceContractTest.java:75 .map(root::resolve)
MongoNamespaceContractTest.java:76 .filter(Files::isDirectory)
MongoNamespaceContractTest.java:77 .flatMap(
MongoNamespaceContractTest.java:78 moduleRoot -> {
MongoNamespaceContractTest.java:79 try (Stream<Path> walk = Files.walk(moduleRoot)) {
MongoNamespaceContractTest.java:80 return walk
MongoNamespaceContractTest.java:81 .filter(path -> path.toString().endsWith(suffix))
MongoNamespaceContractTest.java:82 .filter(path -> path.toString().contains("/src/main/"))
MongoNamespaceContractTest.java:83 .filter(path -> !path.toString().contains("/build/"))
MongoNamespaceContractTest.java:84 .toList()
MongoNamespaceContractTest.java:85 .stream();
MongoNamespaceContractTest.java:86 } catch (IOException unreadable) {
MongoNamespaceContractTest.java:87 throw new UncheckedIOException(unreadable);
MongoNamespaceContractTest.java:88 }
MongoNamespaceContractTest.java:89 });
MongoNamespaceContractTest.java:90 }
MongoNamespaceContractTest.java:91
MongoNamespaceContractTest.java:92 private static String read(Path path) {
MongoNamespaceContractTest.java:93 try {
MongoNamespaceContractTest.java:94 return Files.readString(path);
MongoNamespaceContractTest.java:95 } catch (IOException unreadable) {
MongoNamespaceContractTest.java:96 throw new UncheckedIOException(unreadable);
MongoNamespaceContractTest.java:97 }
MongoNamespaceContractTest.java:98 }
MongoNamespaceContractTest.java:99
MongoNamespaceContractTest.java:100 private static Path repositoryRoot() {
MongoNamespaceContractTest.java:101 Path candidate = Path.of("").toAbsolutePath();
MongoNamespaceContractTest.java:102 while (candidate != null
MongoNamespaceContractTest.java:103 && !Files.isRegularFile(candidate.resolve("src/config/architecture/modules.json"))) {
MongoNamespaceContractTest.java:104 candidate = candidate.getParent();
MongoNamespaceContractTest.java:105 }
MongoNamespaceContractTest.java:106 if (candidate == null) {
MongoNamespaceContractTest.java:107 throw new IllegalStateException("could not locate the repository root from the test cwd");
MongoNamespaceContractTest.java:108 }
MongoNamespaceContractTest.java:109 return candidate;
MongoNamespaceContractTest.java:110 }
# 폐기된 키가 저장소 어디에 있는가 (시험 소스 제외)
docs/superpowers/plans/2026-08-15-wave2-module-on-path.md:124 - Modify: every source and test referencing `spring.data.mongodb.*`
docs/superpowers/plans/2026-08-15-wave2-module-on-path.md:127 **Context:** `spring.data.mongodb.*` is deprecated at error level in Spring Boot 4 metadata; the
docs/superpowers/plans/2026-08-15-wave2-module-on-path.md:133 `spring.data.mongodb.` — a source-tree scan, in the shape of the existing
docs/superpowers/plans/evidence/2026-08-15-wave2-decisions.md:610 `spring.data.mongodb.*` is deprecated at error level in Spring Boot 4's metadata; the canonical
docs/superpowers/specs/2026-08-15-five-adapter-runtime-remediation-review-design.md:343 현재 코드와 test가 참조하는 `spring.data.mongodb.*`는 Spring Boot 4 metadata에서 deprecated error
src/adapter/outbound/persistence-mongo/CLAUDE.md:25 `spring.data.mongodb.*` settings; platform profiles come from
src/adapter/outbound/persistence-mongo/README.md:37 spring.data.mongodb.uri=mongodb://localhost:27017/portfolio
src/adapter/outbound/persistence-mongo/README.md:53 표준 `spring.data.mongodb.*` 설정을 사용한다. 플랫폼 profile은
src/adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/MongoPersistenceSettings.java:15 * spring.data.mongodb.*} is deprecated at error level in its metadata. This Javadoc named the
# 그중 가드의 범위 안에 드는 것
docs/superpowers/plans/2026-08-15-wave2-module-on-path.md 범위 밖
docs/superpowers/plans/evidence/2026-08-15-wave2-decisions.md 범위 밖
docs/superpowers/specs/2026-08-15-five-adapter-runtime-remediation-review-design.md 범위 밖
src/adapter/outbound/persistence-mongo/CLAUDE.md 범위 밖
src/adapter/outbound/persistence-mongo/README.md 범위 밖
src/adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/MongoPersistenceSettings.java 범위 안
# 범위 안에 든 자바 파일에서 그 키가 놓인 자리
MongoPersistenceSettings.java:5 /**
MongoPersistenceSettings.java:6 * Typed enablement settings for the MongoDB infrastructure, bound from {@code
MongoPersistenceSettings.java:7 * ca-skeleton.persistence-mongo.*}.
MongoPersistenceSettings.java:8 *
MongoPersistenceSettings.java:9 * <p>The Mongo <b>connection URI</b> is intentionally NOT modelled here — it is read from Spring's
MongoPersistenceSettings.java:10 * own standard {@code spring.mongodb.uri} (owned by Spring Boot's {@code MongoProperties}), which
MongoPersistenceSettings.java:11 * keeps credentials, host, and database wiring in the one place operators already expect. This
MongoPersistenceSettings.java:12 * class owns only the module's opt-in switch.
MongoPersistenceSettings.java:13 *
MongoPersistenceSettings.java:14 * <p>{@code spring.mongodb.*} is the canonical namespace in Spring Boot 4; {@code
MongoPersistenceSettings.java:15 * spring.data.mongodb.*} is deprecated at error level in its metadata. This Javadoc named the
MongoPersistenceSettings.java:16 * deprecated one, which is the worst place for that drift to sit: an operator reads the class that
MongoPersistenceSettings.java:17 * owns the switch, sets the property it points at, and gets a deprecation they did not choose. The
MongoPersistenceSettings.java:18 * Compose lanes have always supplied {@code SPRING_MONGODB_URI}, so only the documentation was
MongoPersistenceSettings.java:19 * behind. {@code MongoNamespaceContractTest} keeps it from drifting back.
MongoPersistenceSettings.java:20 */
MongoPersistenceSettings.java:21 @ConfigurationProperties(prefix = "ca-skeleton.persistence-mongo")
MongoPersistenceSettings.java:22 public class MongoPersistenceSettings {
# 운영자가 읽는 두 문서가 그 키로 무엇을 말하는가
README.md:35 ```properties
README.md:36 ca-skeleton.persistence-mongo.enabled=true
README.md:37 spring.data.mongodb.uri=mongodb://localhost:27017/portfolio
README.md:38 ```
README.md:39
--
README.md:51
README.md:52 `MongoPersistenceProperties`는 모듈 opt-in만 소유한다. URI, database, credential은 Spring의
README.md:53 표준 `spring.data.mongodb.*` 설정을 사용한다. 플랫폼 profile은
README.md:54 `ca-skeleton.persistence-mongo.platform.*` (`MongoPlatformProperties`)이 소유한다.
README.md:55
CLAUDE.md:24 is gated on the same flag. The connection URI and database come from Spring's standard
CLAUDE.md:25 `spring.data.mongodb.*` settings; platform profiles come from
CLAUDE.md:26 `ca-skeleton.persistence-mongo.platform.*`.
# 시험 소스에는 그 키를 실제로 바인딩하는 자리가 있다
MongoNamespaceContractTest.java:17 * <p>{@code spring.data.mongodb.*} is deprecated at error level in Spring Boot 4's metadata; the
MongoNamespaceContractTest.java:30 private static final String RETIRED_NAMESPACE = "spring.data.mongodb.";
MongoPersistenceConfigTest.java:20 .withPropertyValues("spring.data.mongodb.database=portfolio");
MongoPersistenceConfigTest.java:64 "ca-skeleton.persistence-mongo.enabled=true", "spring.data.mongodb.database=portfolio")