Files
document-haness/docs/clean-architecture-backend-template/final/evidence/raw/132-mongo-query-aggregation-manifest-and-probes.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

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