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>
136 lines
11 KiB
Plaintext
136 lines
11 KiB
Plaintext
Sub-scope 05 (mongo) query + aggregation — manifest and negative-space probes
|
|
revision=a24ece9cf797f7ea647e33bf846b115208ed1ba5
|
|
generatedAt=2026-08-29T23:56:53+00:00
|
|
cwd=/shared/codebase/clean-architecture-backend-template/src
|
|
|
|
=== OWNED FILES ===
|
|
bd1a00feb05bd763ac1b60c4bba58cb10fb20f66 main/java/dev/caskeleton/adapter/outbound/mongo/aggregation/MongoAggregationPlan.java 74
|
|
0d418661496039271fddf141871db7da9ad625f6 main/java/dev/caskeleton/adapter/outbound/mongo/aggregation/MongoAggregationProfile.java 137
|
|
77dfb8127f180887cdd8ccccf168b924a7835f47 main/java/dev/caskeleton/adapter/outbound/mongo/aggregation/MongoAggregationRisk.java 35
|
|
e3943a285f45a7938929305020c0a18a81a1c3d7 main/java/dev/caskeleton/adapter/outbound/mongo/aggregation/MongoAggregationStageDescriptor.java 70
|
|
8ed663b789d66ef063c45ec7b84c08a8a3a142b6 main/java/dev/caskeleton/adapter/outbound/mongo/aggregation/PolicyAwareMongoAggregationExecutor.java 109
|
|
fa19ea3af90410955979662933050214fb362ae5 main/java/dev/caskeleton/adapter/outbound/mongo/query/MongoFieldDescriptor.java 48
|
|
37aad70d93eec8e780299bae74f1b5d8f1aec99e main/java/dev/caskeleton/adapter/outbound/mongo/query/MongoOperator.java 73
|
|
0df5cb53d9ffd0cb8805d032f040301aeb4439ce main/java/dev/caskeleton/adapter/outbound/mongo/query/MongoQueryPolicy.java 197
|
|
76b64aea8129c7b2af6c93ac61fbc2fe26d985ef main/java/dev/caskeleton/adapter/outbound/mongo/query/MongoRegexPolicy.java 182
|
|
aa6db8904a9faf7658c5fa20da2868a7f03a9ae8 main/java/dev/caskeleton/adapter/outbound/mongo/query/MongoSortDescriptor.java 35
|
|
ccd0d04e560b03aba3ba773ef53d3d86e5fd83a0 main/java/dev/caskeleton/adapter/outbound/mongo/query/PolicyAwareMongoQueryBuilder.java 215
|
|
52caac4c793029523101f7005a360f3c75a5683e main/java/dev/caskeleton/adapter/outbound/mongo/query/budget/MongoBudgetEnforcer.java 59
|
|
227276706036025d4ade7ed73c2c31efad40b9db main/java/dev/caskeleton/adapter/outbound/mongo/query/budget/MongoBudgetPolicyRegistry.java 80
|
|
874b21adb182e2b76fb114312c61491590f65357 main/java/dev/caskeleton/adapter/outbound/mongo/query/budget/MongoOperationBudget.java 50
|
|
fd25ddbec5850e8aa720e2b6b04807a9624cf2ce main/java/dev/caskeleton/adapter/outbound/mongo/query/pagination/MongoCursorValueCodec.java 147
|
|
8e8d0f24a64bd65a99fa2709fcebe5d7aeff4f7c main/java/dev/caskeleton/adapter/outbound/mongo/query/pagination/MongoKeysetCursor.java 60
|
|
06d538f210979f1b692a60f82a20347e5180a382 main/java/dev/caskeleton/adapter/outbound/mongo/query/pagination/MongoKeysetCursorCodec.java 179
|
|
3c4b1ab9cd19e318c6f5b8ad7325a95dcd56f8cf main/java/dev/caskeleton/adapter/outbound/mongo/query/pagination/MongoKeysetPageRequest.java 79
|
|
fbb9597c181122d7ea6b91bb1688ced9e5d87960 main/java/dev/caskeleton/adapter/outbound/mongo/query/pagination/MongoKeysetQueryBuilder.java 118
|
|
c8ed45c5758ae57847e7230260bc61d6336106f1 main/java/dev/caskeleton/adapter/outbound/mongo/query/pagination/MongoKeysetSlice.java 41
|
|
c5e4dcc1f15e76650ef13bedc05b8e94e1dbbe04 main/java/dev/caskeleton/adapter/outbound/mongo/query/pagination/MongoKeysetSort.java 73
|
|
2eba3b368b9c5f49f2176b1799e3de2adf4b93ed main/java/dev/caskeleton/adapter/outbound/mongo/query/pagination/MongoNullSortOrdering.java 21
|
|
89fd5ff0bde84c41e4e04760de13b8db29d94002 test/java/dev/caskeleton/adapter/outbound/mongo/aggregation/PolicyAwareMongoAggregationExecutorTest.java 108
|
|
b4a31a13b36509bc834917990384451d10fbcf7d test/java/dev/caskeleton/adapter/outbound/mongo/query/LiteralSearchIsExpressibleTest.java 88
|
|
f64f31f195837c736b4793b31dc72e10aa277c28 test/java/dev/caskeleton/adapter/outbound/mongo/query/PolicyAwareMongoQueryBuilderTest.java 118
|
|
16b5af361b3761756391ca085bf2baebf965fdc6 test/java/dev/caskeleton/adapter/outbound/mongo/query/budget/MongoBudgetEnforcerTest.java 74
|
|
114650961653168159cecbe5ec0dcde400a4002a test/java/dev/caskeleton/adapter/outbound/mongo/query/pagination/MongoKeysetCursorTypeTest.java 113
|
|
68b0ef6e5d06224088402d2477b3a1f9831df179 test/java/dev/caskeleton/adapter/outbound/mongo/query/pagination/MongoKeysetPageRequestBoundsTest.java 73
|
|
8882413c97ee97c4e17e24b88f91e3d93a1148e3 test/java/dev/caskeleton/adapter/outbound/mongo/query/pagination/MongoKeysetQueryBuilderTest.java 116
|
|
|
|
production: 22
|
|
test: 7
|
|
production LOC: 2082 total
|
|
|
|
=== 8.1 reachability: what the auto-configuration builds from this sub-scope ===
|
|
$ grep -n 'Aggregation\|QueryBuilder\|Keyset\|BudgetPolicyRegistry\|BudgetEnforcer\|QueryPolicy\|RegexPolicy' adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoPlatformAutoConfiguration.java
|
|
15:import dev.caskeleton.adapter.outbound.mongo.query.budget.MongoBudgetEnforcer;
|
|
308: public MongoBudgetEnforcer mongoBudgetEnforcer() {
|
|
309: return new MongoBudgetEnforcer();
|
|
exit=0
|
|
|
|
$ git grep -n 'MongoBudgetEnforcer' -- 'adapter/outbound/persistence-mongo/src/main' | grep -v 'query/budget/MongoBudgetEnforcer.java'
|
|
adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/aggregation/PolicyAwareMongoAggregationExecutor.java:5:import dev.caskeleton.adapter.outbound.mongo.query.budget.MongoBudgetEnforcer;
|
|
adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/aggregation/PolicyAwareMongoAggregationExecutor.java:30: private final MongoBudgetEnforcer enforcer;
|
|
adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/aggregation/PolicyAwareMongoAggregationExecutor.java:33: MongoOperations operations, MongoBudgetPolicyRegistry budgets, MongoBudgetEnforcer enforcer) {
|
|
adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoPlatformAutoConfiguration.java:15:import dev.caskeleton.adapter.outbound.mongo.query.budget.MongoBudgetEnforcer;
|
|
adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoPlatformAutoConfiguration.java:308: public MongoBudgetEnforcer mongoBudgetEnforcer() {
|
|
adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoPlatformAutoConfiguration.java:309: return new MongoBudgetEnforcer();
|
|
exit=0
|
|
|
|
$ git grep -n 'PolicyAwareMongoAggregationExecutor\|PolicyAwareMongoQueryBuilder\|MongoKeysetCursorCodec\|MongoBudgetPolicyRegistry' -- 'adapter/outbound/persistence-mongo/src/main' | grep -v '/query/' | grep -v '/aggregation/'
|
|
exit=1
|
|
|
|
=== 8.2 the collection-name invariant and the one signature that takes a String ===
|
|
$ grep -n 'there is no path from a string to a collection' -B 4 adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/imperative/MongoCollectionProfileRegistry.java
|
|
exit=1
|
|
|
|
$ grep -n 'String collection' -B 6 -A 10 adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/aggregation/PolicyAwareMongoAggregationExecutor.java | sed -n '1,30p'
|
|
57- * permitted
|
|
58- */
|
|
59- public <T> List<T> execute(
|
|
60- MongoOperationContext context,
|
|
61- MongoAggregationProfile profile,
|
|
62- MongoAggregationPlan plan,
|
|
63: String collection,
|
|
64- Class<T> outputType) {
|
|
65- Objects.requireNonNull(context, "context");
|
|
66- Objects.requireNonNull(collection, "collection");
|
|
67- Objects.requireNonNull(outputType, "outputType");
|
|
68- validate(plan, profile);
|
|
69-
|
|
70- MongoOperationBudget budget = budgets.require(context.operationName());
|
|
71- MongoOperationBudget effective =
|
|
72- enforcer.narrow(budget, budget.narrowedTo(budgetFor(context, budget)));
|
|
73-
|
|
exit=0
|
|
|
|
$ grep -n 'operations.aggregate' adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/aggregation/PolicyAwareMongoAggregationExecutor.java
|
|
76: AggregationResults<T> results = operations.aggregate(aggregation, collection, outputType);
|
|
exit=0
|
|
|
|
=== 8.2b aggregation runs outside the imperative execution scope ===
|
|
$ grep -n 'MongoOperations operations' adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/aggregation/PolicyAwareMongoAggregationExecutor.java
|
|
26: private final MongoOperations operations;
|
|
33: MongoOperations operations, MongoBudgetPolicyRegistry budgets, MongoBudgetEnforcer enforcer) {
|
|
exit=0
|
|
|
|
$ grep -n 'observer\|observation\|translator' adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/aggregation/PolicyAwareMongoAggregationExecutor.java
|
|
exit=1
|
|
|
|
=== 8.3 regex policy: what 'forbidden' actually forbids ===
|
|
$ grep -n 'public static MongoRegexPolicy forbidden' -A 4 adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/query/MongoRegexPolicy.java
|
|
91: public static MongoRegexPolicy forbidden() {
|
|
92- return new MongoRegexPolicy(1, Set.of(), true);
|
|
93- }
|
|
94-
|
|
95- /**
|
|
exit=0
|
|
|
|
$ grep -n 'requireWithinLength(pattern)\|requireAnchored\|hasNestedQuantifier(pattern)' adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/query/MongoRegexPolicy.java
|
|
28: int maxLength, Set<Character> allowedFlags, boolean requireAnchored) {
|
|
103: requireWithinLength(pattern);
|
|
111: if (requireAnchored && !pattern.startsWith("^")) {
|
|
117: if (hasNestedQuantifier(pattern)) {
|
|
exit=0
|
|
|
|
=== 8.4 keyset cursor: signing key origin ===
|
|
$ grep -n 'MINIMUM_KEY_BYTES\|public MongoKeysetCursorCodec' -A 3 adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/query/pagination/MongoKeysetCursorCodec.java
|
|
46: private static final int MINIMUM_KEY_BYTES = 32;
|
|
47-
|
|
48- private final SecretKeySpec key;
|
|
49-
|
|
50: public MongoKeysetCursorCodec(byte[] secret) {
|
|
51- Objects.requireNonNull(secret, "secret");
|
|
52: if (secret.length < MINIMUM_KEY_BYTES) {
|
|
53- throw new IllegalArgumentException(
|
|
54: "a cursor signing key needs at least " + MINIMUM_KEY_BYTES + " bytes");
|
|
55- }
|
|
56- this.key = new SecretKeySpec(secret.clone(), HMAC_ALGORITHM);
|
|
57- }
|
|
exit=0
|
|
|
|
$ git grep -n 'new MongoKeysetCursorCodec' -- 'adapter/outbound/persistence-mongo/src'
|
|
adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/query/pagination/MongoKeysetCursorTypeTest.java:29: new MongoKeysetCursorCodec("k".repeat(32).getBytes(java.nio.charset.StandardCharsets.UTF_8));
|
|
adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/query/pagination/MongoKeysetQueryBuilderTest.java:66: MongoKeysetCursorCodec codec = new MongoKeysetCursorCodec(SIGNING_KEY);
|
|
adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/query/pagination/MongoKeysetQueryBuilderTest.java:78: MongoKeysetCursorCodec codec = new MongoKeysetCursorCodec(SIGNING_KEY);
|
|
adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/query/pagination/MongoKeysetQueryBuilderTest.java:113: assertThatThrownBy(() -> new MongoKeysetCursorCodec(new byte[16]))
|
|
exit=0
|
|
|