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>
128 lines
6.3 KiB
Plaintext
128 lines
6.3 KiB
Plaintext
Sub-scope 01 (mongo) documentation / measured-count drift (deep-analysis-standard 8.4)
|
|
revision=a24ece9cf797f7ea647e33bf846b115208ed1ba5
|
|
executedAt=2026-08-29T23:04:26+00:00
|
|
cwd=/shared/codebase/clean-architecture-backend-template/src
|
|
observation boundary: tracked files at this revision; build output excluded.
|
|
|
|
=== A. public API surface: build.gradle claim vs baseline vs measurement ===
|
|
$ grep -n 'production files declare a public top-level type' adapter/outbound/persistence-mongo/build.gradle
|
|
260:// 311 of this leaf's 313 production files declare a public top-level type. One jar means `public`
|
|
exit=0
|
|
|
|
$ grep -n '^# types:' ../docs/architecture/mongo-api-surface.txt
|
|
8:# types: 346
|
|
exit=0
|
|
|
|
$ grep -vc '^#' ../docs/architecture/mongo-api-surface.txt
|
|
346
|
|
exit=0
|
|
|
|
$ git ls-files 'adapter/outbound/persistence-mongo/src/main/java' | grep -c '[.]java$'
|
|
351
|
|
exit=0
|
|
|
|
=== B. hermetic contract test count: build.gradle claim ===
|
|
$ grep -n '382 hermetic contract tests' adapter/outbound/persistence-mongo/build.gradle
|
|
87:// `mongoStableContractTest`, so every one of the 382 hermetic contract tests ran twice on a fresh
|
|
exit=0
|
|
|
|
$ git grep -c 'mongodb-contract' -- 'adapter/outbound/persistence-mongo/src/test' | wc -l
|
|
83
|
|
exit=0
|
|
|
|
=== C. the deprecated namespace guard and what it does not cover ===
|
|
$ grep -n 'RETIRED_NAMESPACE\|/src/main/' adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/MongoNamespaceContractTest.java
|
|
30: private static final String RETIRED_NAMESPACE = "spring.data.mongodb.";
|
|
43: .filter(path -> withoutJavaComments(read(path)).contains(RETIRED_NAMESPACE))
|
|
59: .filter(path -> read(path).contains(RETIRED_NAMESPACE))
|
|
82: .filter(path -> path.toString().contains("/src/main/"))
|
|
exit=0
|
|
|
|
$ git grep -n 'spring.data.mongodb' -- 'adapter/outbound/persistence-mongo/CLAUDE.md' 'adapter/outbound/persistence-mongo/README.md'
|
|
adapter/outbound/persistence-mongo/CLAUDE.md:25: `spring.data.mongodb.*` settings; platform profiles come from
|
|
adapter/outbound/persistence-mongo/README.md:37:spring.data.mongodb.uri=mongodb://localhost:27017/portfolio
|
|
adapter/outbound/persistence-mongo/README.md:53:표준 `spring.data.mongodb.*` 설정을 사용한다. 플랫폼 profile은
|
|
exit=0
|
|
|
|
$ git grep -n 'spring.data.mongodb' -- 'adapter/outbound/persistence-mongo/src/test'
|
|
adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/MongoNamespaceContractTest.java:17: * <p>{@code spring.data.mongodb.*} is deprecated at error level in Spring Boot 4's metadata; the
|
|
adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/MongoNamespaceContractTest.java:30: private static final String RETIRED_NAMESPACE = "spring.data.mongodb.";
|
|
adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/MongoPersistenceConfigTest.java:20: .withPropertyValues("spring.data.mongodb.database=portfolio");
|
|
adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/MongoPersistenceConfigTest.java:64: "ca-skeleton.persistence-mongo.enabled=true", "spring.data.mongodb.database=portfolio")
|
|
exit=0
|
|
|
|
$ git grep -n 'spring.data.mongodb' -- 'adapter/outbound/persistence-mongo/src/main'
|
|
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
|
|
exit=0
|
|
|
|
=== D. the leaf README activation recipe vs what the composition root requires ===
|
|
$ sed -n '33,40p' adapter/outbound/persistence-mongo/README.md
|
|
기본값은 비활성이다.
|
|
|
|
```properties
|
|
ca-skeleton.persistence-mongo.enabled=true
|
|
spring.data.mongodb.uri=mongodb://localhost:27017/portfolio
|
|
```
|
|
|
|
활성화 시 `MongoPersistenceConfig`가 Spring Boot의 Mongo client 및 data auto-configuration을
|
|
exit=0
|
|
|
|
$ sed -n '100,112p' app-bootstrap/src/main/java/dev/caskeleton/bootstrap/activation/CapabilityDependencyValidator.java
|
|
+ "=true.");
|
|
}
|
|
if (mongo
|
|
&& environment
|
|
.getProperty(
|
|
MasterSwitch.PERSISTENCE_MONGO.property().replace(".enabled", ".active-profile"),
|
|
"")
|
|
.isBlank()) {
|
|
violations.add(
|
|
MasterSwitch.PERSISTENCE_MONGO.property()
|
|
+ "=true needs exactly one profile; set "
|
|
+ "ca-skeleton.persistence-mongo.active-profile.");
|
|
}
|
|
exit=0
|
|
|
|
$ grep -n 'active-profile' app-bootstrap/src/main/resources/application.yml
|
|
370: active-profile: ${APP_PERSISTENCE_MONGO_ACTIVE_PROFILE:}
|
|
exit=0
|
|
|
|
=== E. README 'ArchUnit 10개 규칙' vs the boundary test's actual rule count ===
|
|
$ grep -n 'ArchUnit' adapter/outbound/persistence-mongo/README.md
|
|
73:| `api` (+ `capability`, `consistency`, `error`, `mapping`, `observation`, `profile`, `schema`) | framework 없는 core 계약. Spring/driver/BSON/Reactor import 금지 (ArchUnit) |
|
|
88:| `architecture` | fork가 자기 코드에 적용하는 `@MongoOperation` marker와 ArchUnit rule set |
|
|
96:- 패키지 간 방향은 `MongoModuleBoundaryTest`(ArchUnit) 10개 규칙이 강제한다: core-api는 framework
|
|
exit=0
|
|
|
|
$ grep -c '@Test' adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/architecture/MongoModuleBoundaryTest.java
|
|
13
|
|
exit=0
|
|
|
|
$ grep -n '@Test' adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/architecture/MongoModuleBoundaryTest.java
|
|
113: @Test
|
|
126: @Test
|
|
154: @Test
|
|
166: @Test
|
|
180: @Test
|
|
192: @Test
|
|
204: @Test
|
|
216: @Test
|
|
228: @Test
|
|
244: @Test
|
|
256: @Test
|
|
280: @Test
|
|
310: @Test
|
|
exit=0
|
|
|
|
=== F. leaf-count claims in this leaf's own adaptation document ===
|
|
$ grep -c '"id"' config/architecture/modules.json
|
|
44
|
|
exit=0
|
|
|
|
$ git grep -n '19 leaf\|19-leaf' -- ../docs/mongodb ../docs/adr adapter/outbound/persistence-mongo
|
|
../docs/adr/ADR-MONGO-001-platform-boundary.md:61:declares exactly 19 leaf identities, so the modules became package boundaries inside
|
|
../docs/mongodb/repository-adaptation.md:18:and `verifyCleanArchitectureDependencies`) declares **exactly 19 leaf identities**. Creating 31 more
|
|
adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/architecture/MongoModuleBoundaryTest.java:16: * <p>This repository's fail-closed 19-leaf registry outranks the design's 19-Gradle-module layout,
|
|
exit=0
|
|
|