Sub-scope 01 negative-space probes (public surface / conditional sibling / duplicate mechanism)
revision=a24ece9cf797f7ea647e33bf846b115208ed1ba5
executedAt=2026-08-29T14:36:26+00:00
cwd=/shared/codebase/clean-architecture-backend-template/src
observation boundary: tracked Java/YAML/Gradle sources at this revision; reflection, generated
registration and consumers outside this repository are not covered.

=== 8.1 public surface reachability: config package types outside the owning leaf ===
$ git grep -n -w PersistenceJpaConfig -- . ":!adapter/outbound/persistence-jpa/**"
sample-portfolio/README.md:404:  adapter-persistence `PersistenceJpaConfig` 등)를 자동으로 발견·배선합니다. `app-bootstrap` 에만 있어
sample-portfolio/src/main/java/dev/caskeleton/sample/portfolio/bootstrap/persistence/SamplePostgreSqlPersistenceConfig.java:3:import dev.caskeleton.adapter.outbound.persistence.config.PersistenceJpaConfig;
sample-portfolio/src/main/java/dev/caskeleton/sample/portfolio/bootstrap/persistence/SamplePostgreSqlPersistenceConfig.java:25:@Import(PersistenceJpaConfig.class)
exit=0

$ git grep -n -w JpaAdapterComponentsConfig -- . ":!adapter/outbound/persistence-jpa/**"
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/autoconfigure/persistencejpa/PersistenceJpaRootAutoConfiguration.java:3:import dev.caskeleton.adapter.outbound.persistence.config.JpaAdapterComponentsConfig;
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/autoconfigure/persistencejpa/PersistenceJpaRootAutoConfiguration.java:62:  JpaAdapterComponentsConfig.class,
exit=0

$ git grep -n -w PersistenceVendorSettings -- . ":!adapter/outbound/persistence-jpa/**"
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/autoconfigure/persistencejpa/PersistenceJpaRootAutoConfiguration.java:4:import dev.caskeleton.adapter.outbound.persistence.config.PersistenceVendorSettings;
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/autoconfigure/persistencejpa/PersistenceJpaRootAutoConfiguration.java:86:   * PersistenceVendorSettings}, because that type is not a registered bean here: the composition
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/autoconfigure/persistencejpa/PersistenceJpaRootAutoConfiguration.java:112:        environment.getProperty(PersistenceVendorSettings.VENDOR_PROPERTY, "postgresql").trim();
app-bootstrap/src/main/resources/application.yml:463:  # PersistenceVendorSettings (adapter-persistence), which rejects any other value at startup.
exit=0

=== 8.2 conditional sibling comparison: leaf @ConfigurationProperties types and their enablement ===
$ git grep -n "@ConfigurationProperties(" -- adapter/outbound/persistence-jpa/src/main
adapter/outbound/persistence-jpa/src/main/java/dev/caskeleton/adapter/outbound/persistence/config/PersistenceVendorSettings.java:18:@ConfigurationProperties(prefix = PersistenceVendorSettings.PREFIX)
adapter/outbound/persistence-jpa/src/main/java/dev/caskeleton/adapter/outbound/persistence/lock/LockSettings.java:14:@ConfigurationProperties(prefix = "ca-skeleton.lock")
adapter/outbound/persistence-jpa/src/main/java/dev/caskeleton/adapter/outbound/persistence/transaction/JpaTransactionSettings.java:10:@ConfigurationProperties(prefix = "ca-skeleton.jpa.transaction")
exit=0

$ git grep -n "@EnableConfigurationProperties" -- adapter/outbound/persistence-jpa/src
adapter/outbound/persistence-jpa/src/main/java/dev/caskeleton/adapter/outbound/persistence/lock/DistributedLockPersistenceConfig.java:24:@EnableConfigurationProperties(LockSettings.class)
adapter/outbound/persistence-jpa/src/main/java/dev/caskeleton/adapter/outbound/persistence/transaction/JpaTransactionConfig.java:23:@EnableConfigurationProperties(JpaTransactionSettings.class)
adapter/outbound/persistence-jpa/src/test/java/dev/caskeleton/adapter/outbound/persistence/config/PersistenceVendorSelectionTest.java:92:  @EnableConfigurationProperties(PersistenceVendorSettings.class)
exit=0

$ git grep -n -A22 "@ConfigurationPropertiesScan" -- app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java:21: * auto-configured packages with a regex filter; {@code @ConfigurationPropertiesScan} has no {@code
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-22- * excludeFilters} attribute, so it names the packages it does scan instead. The asymmetry that
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-23- * existed before — beans gated, settings not — is why a notification settings object bound itself
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-24- * in a deployment whose notification master was off. A capability whose beans are gated but whose
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-25- * settings still bind is gated only where somebody remembered to gate it.
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-26- *
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-27- * <p>The five optional adapters are absent from the list below on purpose. Each one\'s settings are
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-28- * registered by its capability root through {@code @EnableConfigurationProperties}, which is what
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-29- * ties binding to the master switch. Adding a package back here would restore the binding and
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-30- * silently undo the gate.
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-31- *
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-32- * <p>The third exclusion is what makes an optional capability optional. Configuration classes under
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-33- * {@code bootstrap.autoconfigure} are reachable only through their own auto-configuration entry,
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-34- * which carries the capability's master switch; leaving them inside the broad scan would let the
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-35- * component scanner discover each child configuration on its own and assemble the capability
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-36- * whatever that switch said. Registering them as auto-configuration instead makes "off" a
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-37- * structural fact rather than a condition every future bean has to remember to repeat.
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-38- */
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-39-@SpringBootConfiguration
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-40-@EnableAutoConfiguration
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-41-@ComponentScan(
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-42-    basePackages = {
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-43-      "dev.caskeleton.bootstrap",
--
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java:58:@ConfigurationPropertiesScan(
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-59-    basePackages = {
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-60-      "dev.caskeleton.bootstrap.async",
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-61-      "dev.caskeleton.bootstrap.autoconfigure.fileserver",
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-62-      "dev.caskeleton.bootstrap.autoconfigure.httpclient",
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-63-      "dev.caskeleton.bootstrap.concurrency",
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-64-      "dev.caskeleton.bootstrap.idempotency",
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-65-      "dev.caskeleton.bootstrap.outbox",
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-66-      "dev.caskeleton.bootstrap.redis",
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-67-      "dev.caskeleton.bootstrap.runtime",
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-68-      "dev.caskeleton.bootstrap.security",
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-69-      "dev.caskeleton.bootstrap.settings",
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-70-      "dev.caskeleton.bootstrap.tracing",
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-71-      "dev.caskeleton.adapter.inbound.grpc",
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-72-      "dev.caskeleton.adapter.inbound.web",
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-73-      "dev.caskeleton.adapter.inbound.websocket",
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-74-      "dev.caskeleton.adapter.outbound.cache.redis",
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-75-      "dev.caskeleton.adapter.outbound.fileserver",
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-76-      "dev.caskeleton.adapter.outbound.objectstorage",
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-77-      "dev.caskeleton.application",
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-78-      "dev.caskeleton.domain",
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-79-      "dev.caskeleton.shared"
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java-80-    })
exit=0

=== 8.2b vendor selector guards outside the leaf ===
$ git grep -n "ca-skeleton.persistence.vendor" -- app-bootstrap sample-portfolio
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/autoconfigure/persistencejpa/PersistenceJpaRootAutoConfiguration.java:32: * packages instead. They are mutually exclusive on {@code ca-skeleton.persistence.vendor}, so
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/runtime/PersistenceVendorProdSafetyValidator.java:11: * <p>{@code application-prod.yml} already pins {@code ca-skeleton.persistence.vendor=postgresql},
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/runtime/PersistenceVendorProdSafetyValidator.java:34:  static final String VENDOR_KEY = "ca-skeleton.persistence.vendor";
app-bootstrap/src/test/java/dev/caskeleton/bootstrap/autoconfigure/jpa/LocalJpaVendorParityTest.java:42:          "ca-skeleton.persistence.vendor",
app-bootstrap/src/test/java/dev/caskeleton/bootstrap/autoconfigure/jpa/LocalJpaVendorParityTest.java:71:    assertThat(local.getProperty("ca-skeleton.persistence.vendor")).isEqualTo("postgresql");
exit=0

=== 8.3 duplicate mechanism sweep: entity/repository/component scan declarations ===
$ git grep -n "@EntityScan\|@EnableJpaRepositories\|@ComponentScan(" -- "*.java"
adapter/outbound/persistence-jpa/src/main/java/dev/caskeleton/adapter/outbound/persistence/config/JpaAdapterComponentsConfig.java:59:@ComponentScan(
adapter/outbound/persistence-jpa/src/main/java/dev/caskeleton/adapter/outbound/persistence/config/PersistenceJpaConfig.java:38:@EntityScan(
adapter/outbound/persistence-jpa/src/main/java/dev/caskeleton/adapter/outbound/persistence/config/PersistenceJpaConfig.java:61:@EnableJpaRepositories(
adapter/outbound/persistence-jpa/src/main/java/dev/caskeleton/adapter/outbound/persistence/fileserver/FileserverJpaPersistenceConfig.java:33: * had nothing to decide about. {@code @EnableJpaRepositories} does not cover them — it registers
adapter/outbound/persistence-jpa/src/main/java/dev/caskeleton/adapter/outbound/persistence/fileserver/FileserverJpaPersistenceConfig.java:38:@EntityScan(basePackages = "dev.caskeleton.adapter.outbound.persistence.fileserver")
adapter/outbound/persistence-jpa/src/main/java/dev/caskeleton/adapter/outbound/persistence/fileserver/FileserverJpaPersistenceConfig.java:39:@EnableJpaRepositories(basePackages = "dev.caskeleton.adapter.outbound.persistence.fileserver")
adapter/outbound/persistence-jpa/src/main/java/dev/caskeleton/adapter/outbound/persistence/fileserver/FileserverJpaPersistenceConfig.java:40:@ComponentScan(basePackages = "dev.caskeleton.adapter.outbound.persistence.fileserver")
adapter/outbound/persistence-jpa/src/main/java/dev/caskeleton/adapter/outbound/persistence/notification/NotificationJpaPersistenceConfig.java:26:@EntityScan(basePackages = "dev.caskeleton.adapter.outbound.persistence.notification")
adapter/outbound/persistence-jpa/src/main/java/dev/caskeleton/adapter/outbound/persistence/notification/NotificationJpaPersistenceConfig.java:27:@EnableJpaRepositories(basePackages = "dev.caskeleton.adapter.outbound.persistence.notification")
adapter/outbound/persistence-jpa/src/postgresqlIntegrationTest/java/dev/caskeleton/adapter/outbound/persistence/readiness/FileserverJpaTestContext.java:68:  @EnableJpaRepositories(
adapter/outbound/persistence-jpa/src/postgresqlIntegrationTest/java/dev/caskeleton/adapter/outbound/persistence/readiness/FileserverJpaTestContext.java:70:  @ComponentScan(
app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java:41:@ComponentScan(
app-bootstrap/src/test/java/dev/caskeleton/bootstrap/activation/ShippedCompositionHarness.java:20: * {@code @EnableJpaRepositories} and the context dies with a {@code
app-bootstrap/src/test/java/dev/caskeleton/bootstrap/idempotency/IdempotencyProviderScanCollisionTest.java:96:  @ComponentScan("dev.caskeleton.adapter.outbound.persistence.postgresql.idempotency")
app-bootstrap/src/test/java/dev/caskeleton/bootstrap/integration/fileserver/FileserverRoundTripContractTest.java:472:  @ComponentScan(
app-bootstrap/src/test/java/dev/caskeleton/bootstrap/integration/fileserver/FileserverRoundTripContractTest.java:477:  // No @EntityScan or @EnableJpaRepositories here any more. FileserverJpaPersistenceConfig owns
app-bootstrap/src/test/java/dev/caskeleton/bootstrap/integration/outbox/OutboxContainerTestSupport.java:229:  @EnableJpaRepositories(basePackageClasses = OutboxEventJpaRepository.class)
sample-portfolio/src/main/java/dev/caskeleton/sample/portfolio/SamplePortfolioApplication.java:27:@ComponentScan(
sample-portfolio/src/main/java/dev/caskeleton/sample/portfolio/adapter/outbound/persistence/config/JpaConfig.java:14:@EntityScan(basePackages = "dev.caskeleton.sample.portfolio.adapter.outbound.persistence.entity")
sample-portfolio/src/main/java/dev/caskeleton/sample/portfolio/adapter/outbound/persistence/config/JpaConfig.java:15:@EnableJpaRepositories(
exit=0


=== 8.2c CaSkeletonApplication @ConfigurationPropertiesScan basePackages (exact annotation block) ===
$ sed -n 58,80p app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java
@ConfigurationPropertiesScan(
    basePackages = {
      "dev.caskeleton.bootstrap.async",
      "dev.caskeleton.bootstrap.autoconfigure.fileserver",
      "dev.caskeleton.bootstrap.autoconfigure.httpclient",
      "dev.caskeleton.bootstrap.concurrency",
      "dev.caskeleton.bootstrap.idempotency",
      "dev.caskeleton.bootstrap.outbox",
      "dev.caskeleton.bootstrap.redis",
      "dev.caskeleton.bootstrap.runtime",
      "dev.caskeleton.bootstrap.security",
      "dev.caskeleton.bootstrap.settings",
      "dev.caskeleton.bootstrap.tracing",
      "dev.caskeleton.adapter.inbound.grpc",
      "dev.caskeleton.adapter.inbound.web",
      "dev.caskeleton.adapter.inbound.websocket",
      "dev.caskeleton.adapter.outbound.cache.redis",
      "dev.caskeleton.adapter.outbound.fileserver",
      "dev.caskeleton.adapter.outbound.objectstorage",
      "dev.caskeleton.application",
      "dev.caskeleton.domain",
      "dev.caskeleton.shared"
    })
exit=0

=== 8.2d does any scanned base package cover dev.caskeleton.adapter.outbound.persistence? ===
$ sed -n 58,80p ... | grep -c outbound.persistence
0

=== 8.2e application.yml vendor comment ===
$ sed -n 458,468p app-bootstrap/src/main/resources/application.yml
  # domain (out of scope for this branch); code defaults in LockSettings mirror these.
  lock:
    wait-time: 3s
    lease-ttl: 30s
  # Which RDBMS vendor composition the persistence adapter registers: postgresql | h2. Bound to
  # PersistenceVendorSettings (adapter-persistence), which rejects any other value at startup.
  #
  # A property rather than a profile check, because the vendor belongs to the datastore and not to
  # the environment that happens to use it. The profiles then state their choice:
  # application-local.yml selects h2, application-dev.yml and application-prod.yml select
  # postgresql, and prod additionally refuses h2 through PersistenceVendorProdSafetyValidator.
exit=0
