Sub-scope 03 (mongo) mapping + nativecap + geo — manifest and negative-space probes
revision=a24ece9cf797f7ea647e33bf846b115208ed1ba5
generatedAt=2026-08-29T23:49:32+00:00
cwd=/shared/codebase/clean-architecture-backend-template/src

=== OWNED FILES ===
72953a64190f0f694f89591c80a764b27db54069 main/java/dev/caskeleton/adapter/outbound/mongo/geo/MongoGeoDistance.java 54
944c7b86656ab33af7b42f82e15c8d735db13395 main/java/dev/caskeleton/adapter/outbound/mongo/geo/MongoGeoPoint.java 39
214513c7132868faf96e60d6bd0b02a4c221ab2a main/java/dev/caskeleton/adapter/outbound/mongo/geo/MongoGeoQuery.java 43
c437f2e6527dde79d91ad8a964a22a554fa8b1f3 main/java/dev/caskeleton/adapter/outbound/mongo/geo/MongoGeospatialOperations.java 21
bc2dbbfa7e681c4bbb4a59bce60c4a9ffa8bc191 main/java/dev/caskeleton/adapter/outbound/mongo/geo/SpringMongoGeospatialOperations.java 120
767ddc4caec1751d879a90ed4525dc54521d413a main/java/dev/caskeleton/adapter/outbound/mongo/mapping/BigDecimalToDecimal128Converter.java 56
a6670a37afd4c8e0f55063f99e7607b8182b01e4 main/java/dev/caskeleton/adapter/outbound/mongo/mapping/BigIntegerRepresentationConverters.java 96
7c1f34986f59537eb14277537c5e2c56c6ad3cc2 main/java/dev/caskeleton/adapter/outbound/mongo/mapping/Decimal128ToBigDecimalConverter.java 29
5bf3289eef7b7d51fc03f38b7f183af2def725b9 main/java/dev/caskeleton/adapter/outbound/mongo/mapping/DomainIdReadConverter.java 21
65ac609e91d4044dab7a2e599c8271756c96b240 main/java/dev/caskeleton/adapter/outbound/mongo/mapping/DomainIdWriteConverter.java 20
1d11c7523c07489299da5c6e169d3cce9a82daa9 main/java/dev/caskeleton/adapter/outbound/mongo/mapping/LocalDateTimeMappingGuard.java 61
3316ca832683b235c8e9b313afcfb68d271b86cc main/java/dev/caskeleton/adapter/outbound/mongo/mapping/MongoCustomConversionsFactory.java 87
9ff0549795955266fd4ece2368a27e90b2804301 main/java/dev/caskeleton/adapter/outbound/mongo/mapping/MongoMappingConfiguration.java 110
ab6677dcad01cc2e978967061bd71178c0a83838 main/java/dev/caskeleton/adapter/outbound/mongo/mapping/MongoTypeMetadataConfigurer.java 38
d1ed747d5bd36c632d0e5d98806ac53b8dd1513e main/java/dev/caskeleton/adapter/outbound/mongo/mapping/type/LongLivedMongoDocument.java 31
29ddc389b6530a6a6203d78a722a817d0de61f4b main/java/dev/caskeleton/adapter/outbound/mongo/mapping/type/MongoTypeMetadataDescriptor.java 46
1e9b1bb1072a5b0aea37a486cd169fc28040bcbb main/java/dev/caskeleton/adapter/outbound/mongo/mapping/type/MongoTypeMetadataRegistry.java 122
0fa892842fe5233aaf3b381fc3900dc28f2af2e9 main/java/dev/caskeleton/adapter/outbound/mongo/mapping/type/PolicyAwareMongoTypeMapper.java 205
8ddb11c59c6e405aaa119038f35279443891a784 main/java/dev/caskeleton/adapter/outbound/mongo/nativecap/ApprovedMongoNativeOperation.java 67
d39bcca075a57bc14dbe429f6918ae847af36d34 main/java/dev/caskeleton/adapter/outbound/mongo/nativecap/MongoNativeCapabilityGateway.java 14
b83fc163ef8b2bbc96c06869405290edac0b22ac main/java/dev/caskeleton/adapter/outbound/mongo/nativecap/MongoNativeCommandCategory.java 28
5f759fa4c14ccec81b5a421a728552c8f227fd48 main/java/dev/caskeleton/adapter/outbound/mongo/nativecap/MongoNativeOperationPolicy.java 148
a4b61e84e77ad188f521b1d754d673ecfd05851e main/java/dev/caskeleton/adapter/outbound/mongo/nativecap/PolicyAwareMongoNativeGateway.java 46
57693cee88da8503991f42d52cbfef9b9c796aab test/java/dev/caskeleton/adapter/outbound/mongo/geo/MongoGeoPointTest.java 58
e9327b84b30a1262b65d07a9e749826ae60efb90 test/java/dev/caskeleton/adapter/outbound/mongo/mapping/MongoMappingConfigurationTest.java 177
5b93db65a7ab80e91648322ebec0387f9072c834 test/java/dev/caskeleton/adapter/outbound/mongo/mapping/type/PolicyAwareMongoTypeMapperTest.java 118
f1ccfd0e6c231e5c3b77e8c4fc97d86972ab6ec5 test/java/dev/caskeleton/adapter/outbound/mongo/nativecap/PolicyAwareMongoNativeGatewayTest.java 148

production: 23
test: 4

=== 8.1 reachability: which of these types a production configuration actually builds ===
$ git grep -n 'MongoMappingConfiguration\|MongoTypeMetadataConfigurer\|MongoTypeMetadataRegistry\|LocalDateTimeMappingGuard\|MongoCustomConversionsFactory' -- 'adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo' | grep -v '/mapping/'
adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoPlatformAutoConfiguration.java:13:import dev.caskeleton.adapter.outbound.mongo.mapping.MongoMappingConfiguration;
adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoPlatformAutoConfiguration.java:48:@Import(MongoMappingConfiguration.class)
exit=0

$ git grep -n 'SpringMongoGeospatialOperations\|MongoGeospatialOperations' -- 'adapter/outbound/persistence-mongo/src/main' | grep -v '/geo/'
exit=1

$ git grep -n 'MongoNativeCapabilityGateway\|PolicyAwareMongoNativeGateway' -- 'adapter/outbound/persistence-mongo/src/main' | grep -v '/nativecap/'
exit=1

=== 8.2 sibling comparison: how the same 'unregistered type' question is answered ===
$ grep -n 'orElseThrow' -A 8 adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/mapping/type/PolicyAwareMongoTypeMapper.java | sed -n '1,14p'
75:            .orElseThrow(
76-                () ->
77-                    new IllegalStateException(
78-                        "no type metadata policy is registered for "
79-                            + rawType.getName()
80-                            + "; a stored document's type metadata outlives the class, so the"
81-                            + " policy is a decision to record rather than to default"));
82-    switch (policy) {
83-      case NO_TYPE_METADATA -> {
--
182:        .orElseThrow(
183-            () ->
184-                new MongoSchemaValidationException(
185-                    MongoFailureContext.schemaMismatch(READ_OPERATION)));
exit=0

$ grep -n 'orElse(MongoTypeMetadataPolicy.CLASS_METADATA_ALLOWED)' -B 4 adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/mapping/type/PolicyAwareMongoTypeMapper.java
130-      Optional<MongoTypeMetadataDescriptor> descriptor = registry.find(restrictedType);
131-      MongoTypeMetadataPolicy policy =
132-          descriptor
133-              .map(MongoTypeMetadataDescriptor::policy)
134:              .orElse(MongoTypeMetadataPolicy.CLASS_METADATA_ALLOWED);
exit=0

$ grep -n 'policyFor' -B 2 -A 5 adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/mapping/type/MongoTypeMetadataRegistry.java
72-
73-  /** The effective policy for a type; unregistered types keep Spring Data's default. */
74:  public MongoTypeMetadataPolicy policyFor(Class<?> documentType) {
75-    return find(documentType)
76-        .map(MongoTypeMetadataDescriptor::policy)
77-        .orElse(MongoTypeMetadataPolicy.CLASS_METADATA_ALLOWED);
78-  }
79-
exit=0

=== 8.2b the D3 gateway's documented sequence versus the checks that exist ===
$ grep -n 'Runs the design.s stated sequence' -A 4 adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/nativecap/PolicyAwareMongoNativeGateway.java
11: * <p>Runs the design's stated sequence and stops at the first refusal: registration, capability,
12- * database profile, collection profile, timeout, category, then execution. The audit record carries
13- * the operation id and the outcome and never the BSON arguments — the arguments are the part that
14- * contains data, and an audit trail that leaks data is a liability rather than a control.
15- */
exit=0

$ grep -n 'D3는 raw client escape가 아니다' -A 3 adapter/outbound/persistence-mongo/README.md
65:D3는 raw client escape가 아니다. `PolicyAwareMongoNativeGateway`가 capability → database profile →
66-collection allowlist → operation name → timeout → consistency → result limit → trace → redaction →
67-command category → D4 차단 순서를 고정한다.
68-
exit=0

$ grep -n 'throw MongoOperationRejectedException' adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/nativecap/MongoNativeOperationPolicy.java
56:      throw MongoOperationRejectedException.of(
64:      throw MongoOperationRejectedException.of(
75:      throw MongoOperationRejectedException.of(
80:      throw MongoOperationRejectedException.of(
85:      throw MongoOperationRejectedException.of(
92:      throw MongoOperationRejectedException.of(
exit=0

$ git grep -n 'operation.timeout()\|\.hasBody()' -- 'adapter/outbound/persistence-mongo/src/main'
exit=1

$ git grep -n 'operation.maxResults()' -- 'adapter/outbound/persistence-mongo/src/main'
exit=1

=== 8.3 duplicate mechanism: two result-limit vocabularies ===
$ git grep -ln 'maxResults()' -- 'adapter/outbound/persistence-mongo/src/main'
adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/aggregation/PolicyAwareMongoAggregationExecutor.java
adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/query/PolicyAwareMongoQueryBuilder.java
adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/query/budget/MongoBudgetEnforcer.java
adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/reactive/cursor/MongoReactiveCursorPublisher.java
adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/reactive/cursor/MongoResultBudgetTracker.java
exit=0

=== 8.4 geo: the index precondition and the unit type ===
$ grep -n 'requireSphereIndex' -A 6 adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/geo/SpringMongoGeospatialOperations.java | head -20
49:              requireSphereIndex(access.collection(), query.field());
50-              // $nearSphere over a GeoJSON point takes metres and already returns nearest-first, so
51-              // no sort stage is needed — and adding one would discard the index-ordered scan.
52-              Query near =
53-                  new Query(
54-                          Criteria.where(query.field())
55-                              .nearSphere(query.center().toGeoJsonPoint())
--
76:              requireSphereIndex(access.collection(), query.field());
77-              Circle circle =
78-                  new Circle(toPoint(query.center()), query.maxDistance().toSpringDistance());
79-              Query within =
80-                  new Query(Criteria.where(query.field()).withinSphere(circle))
81-                      .limit(query.resultLimit());
82-              return access.rawOperations().find(within, documentType, access.collection());
--
92:  private void requireSphereIndex(String collection, String field) {
93-    boolean supported =
94-        manifests
95-            .find(collection)
exit=0

$ grep -n 'toSpringDistance' -A 6 adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/geo/MongoGeoDistance.java
39:  public Distance toSpringDistance() {
40-    return unit == MongoDistanceUnit.KILOMETERS
41-        ? new Distance(value, Metrics.KILOMETERS)
42-        : new Distance(value / 1000, Metrics.KILOMETERS);
43-  }
44-
45-  /** The unit a geo distance is expressed in. */
exit=0

