Sub-scope 01 (inbound-graphql) governance + autoconfigure + moduleboundary + architecture + api
revision=a24ece9cf797f7ea647e33bf846b115208ed1ba5
generatedAt=2026-08-30T08:27:13+00:00

=== OWNED FILES ===
434aeacc2a92ec3f812fd77999192c4410713c8a CLAUDE.md 224
7e3fc1f6019455df9a7a71ebe9ba67182b5cb0fa README.md 224
42cebcf264bcbd74dd6b843a0ea54b6113446b09 build.gradle 174
74f612c854c95a48370a3608825866d192098b1b gradle.lockfile 178
4c01cbfdef67b3705c97570c4c36d762786dd9f1 src/main/java/dev/caskeleton/HealthGraphqlController.java 25
f2c0492b134eab75b7da6067987a10cbee2a88c8 src/main/java/dev/caskeleton/api/GraphQlClientProfile.java 27
86602c8c38d90d35f8e18374efb87eb7de8e6af6 src/main/java/dev/caskeleton/api/GraphQlClientProfileName.java 50
061a5a56bb501104162e08369f27813b395e8f87 src/main/java/dev/caskeleton/api/GraphQlOperationId.java 24
25fbe6e3f919e5635b0173c32202e2a4ec4a38a6 src/main/java/dev/caskeleton/api/GraphQlOperationName.java 43
f9c4a18019af5ca8400bfea60815afc1aa923a64 src/main/java/dev/caskeleton/api/GraphQlSchemaCoordinate.java 61
d1abaaaedf7c0bfb8ae2e6541a82267eec218c61 src/main/java/dev/caskeleton/architecture/GraphQlAsyncReturnShape.java 72
47ba73dfbd1e5c732cd68006bdb53085415b9f4d src/main/java/dev/caskeleton/architecture/GraphQlControllerContractException.java 40
419ab3992b89c8cc5cbb802446b7b5f91998b36a src/main/java/dev/caskeleton/architecture/GraphQlControllerInspector.java 109
770738711cad63f25c19ca686717f36018e0a5b8 src/main/java/dev/caskeleton/architecture/GraphQlControllerTransactionRule.java 81
647166f486151c90a602dd54a571ebb46f3554ab src/main/java/dev/caskeleton/architecture/GraphQlInputTypePolicy.java 44
8986f2fb27b1ff10c3524710c5f863dffd8e450d src/main/java/dev/caskeleton/architecture/GraphQlResolverBoundaryRules.java 313
d4f7e591ad688299691fb26650c4e1c57d8148ec src/main/java/dev/caskeleton/architecture/GraphQlReturnTypePolicy.java 111
fc934d492e2ef4141a0ed46f8db15d96b0bdcb6b src/main/java/dev/caskeleton/architecture/GraphQlTransportTypeRules.java 87
a32cb82a95758cdafa33be8df27dd28a959ecb5d src/main/java/dev/caskeleton/architecture/GraphQlTypeGraph.java 112
346dc5a32d924565420ab6b61ed20595985522d2 src/main/java/dev/caskeleton/autoconfigure/GraphQlActivationEnvironmentPostProcessor.java 75
afae197bac923e62990079f5cd69853a4dde1891 src/main/java/dev/caskeleton/autoconfigure/GraphQlDeploymentMode.java 72
97477157ffdc72e2b41cf964e65a7ff6c74cb709 src/main/java/dev/caskeleton/autoconfigure/GraphQlOffAutoConfigurationImportFilter.java 60
2ad7108f3a7da65ad80031a3ad84651c271bc6fb src/main/java/dev/caskeleton/autoconfigure/GraphQlPlatformActuatorEndpoint.java 71
a3a2824a48c2f040bf58c3fe2bc10dfcda010b93 src/main/java/dev/caskeleton/autoconfigure/GraphQlPlatformAutoConfiguration.java 704
9f9aff73688ee5e8305dee46eb4c5a138320df65 src/main/java/dev/caskeleton/autoconfigure/GraphQlPlatformConfigurationException.java 31
8c0237214cff7d1a49aa664f0baf0e56f409dc1b src/main/java/dev/caskeleton/autoconfigure/GraphQlPlatformConfigurationReport.java 55
3cbba44d38253207d5e20ed839ef4de791b4bc81 src/main/java/dev/caskeleton/autoconfigure/GraphQlPlatformRuntime.java 43
dd6d37a76d8ecbce963f6d33ef08d8b000b98391 src/main/java/dev/caskeleton/autoconfigure/GraphQlPlatformSettings.java 307
bf93f72b05eb35e7c6bb338682f61168fa459683 src/main/java/dev/caskeleton/autoconfigure/GraphQlPlatformStartupValidator.java 185
55b71a3ccc5cbf053e58ca0316c9d35a5546b120 src/main/java/dev/caskeleton/autoconfigure/GraphQlRetiredSafetyAxis.java 62
a012a182cbf836c62382852f4aba7da5a23dbd6d src/main/java/dev/caskeleton/autoconfigure/GraphQlRootAutoConfiguration.java 33
2281a8283a6a70bfcf5bd5272630ec37a6ca5c0d src/main/java/dev/caskeleton/autoconfigure/GraphQlRuntimeTransport.java 44
434b330b37a4a8f0de417237985dd2cd42b311d8 src/main/java/dev/caskeleton/moduleboundary/GraphQlAdvancedModule.java 167
8d7b467dc93277674057822b4b9be70a1d24b9a7 src/main/java/dev/caskeleton/moduleboundary/GraphQlModuleBoundary.java 126
e86b13a08b20fa55da21c76675294c665207db53 src/main/java/dev/caskeleton/moduleboundary/GraphQlModulePurity.java 19
9a9c652043da9eb128ecf9c39d093ab9e325dbdd src/main/java/dev/caskeleton/moduleboundary/GraphQlStableModule.java 225
bc2a2210fa31d43cf623ed3c40f1b3e82f02ec1a src/main/resources/META-INF/spring.factories 4
0a4f208e8a07fb853e9e798007a3fed85c78b1ad src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 1
c8093c523d6126bc7f77bdf31e46a7b7f0ed3d26 src/main/resources/graphql/skeleton.graphqls 10
de73f5a1d2eae599e16cbd6e3315abb77297be95 src/test/java/dev/caskeleton/api/GraphQlIdentifiersTest.java 76
d6e0f92cccd62bcab06ea64790db57ab741c20ee src/test/java/dev/caskeleton/architecture/GraphQlControllerInspectorTest.java 117
62b18a7b5fc5f6ae49df4d03876ca37d6c54cc82 src/test/java/dev/caskeleton/architecture/GraphQlGeneratedResolverBoundaryTest.java 114
e5adb01dd691ef265eb0f832dc06bc9eae21a09c src/test/java/dev/caskeleton/architecture/GraphQlResolverBoundaryRulesTest.java 92
68b6e28036582d7c452cd84ed8cfd8bcb873196a src/test/java/dev/caskeleton/architecture/GraphQlResolverGenericBoundaryTest.java 189
8bb61d7384f83054472b5a0d3d68b78f6bfa3aa3 src/test/java/dev/caskeleton/architecture/fixture/compliant/FindOrderUseCase.java 12
a38b669abca65734c5c09af9e836b538119c7b0e src/test/java/dev/caskeleton/architecture/fixture/compliant/OrderGraphQlController.java 31
be295c28ebde5dc0e1469d5386247c1b489907c2 src/test/java/dev/caskeleton/architecture/fixture/compliant/OrderView.java 9
b8584addc14a314faffec67f0a44bb6b6d1c8d0a src/test/java/dev/caskeleton/architecture/fixture/violating/LeakyGraphQlController.java 33
38bac70c896e5248fdde731a32b91e856c08d68b src/test/java/dev/caskeleton/architecture/fixture/violating/OrderRepository.java 12
f91fec9cc5d1b03a5a67701dababbc386519f2a6 src/test/java/dev/caskeleton/architecture/fixture/violating/Transactional.java 17
9a96cc94002d21e9763c80d009430dd7737114c4 src/test/java/dev/caskeleton/autoconfigure/GraphQlBatchLoaderWiringTest.java 54
f84ccbd8d86b7ee09e862316093a4798868e8648 src/test/java/dev/caskeleton/autoconfigure/GraphQlDeploymentModeContractTest.java 274
d0f5181e6b0e8bbb7725bc7fc615ee0d10f2aa9a src/test/java/dev/caskeleton/autoconfigure/GraphQlObservationWiringTest.java 62
73a31121c66bfbdf10aee97e592e33e86bb0d342 src/test/java/dev/caskeleton/autoconfigure/GraphQlPlatformAutoConfigurationTest.java 236
41cc6798cabe1267dbf2dd6708139e49ee41a63f src/test/java/dev/caskeleton/autoconfigure/GraphQlPlatformStartupValidatorTest.java 123
1dcaa60e23659d433354552a0de3bb7aa94c9b8b src/test/java/dev/caskeleton/autoconfigure/GraphQlPolicyRequestPathTest.java 112
ffbb69d6ce2236a42907d39019eb0c0450ab94f5 src/test/java/dev/caskeleton/autoconfigure/GraphQlTransportNeutralityTest.java 201
aca33a89df432c626eab84c545e73eed7931f04e src/test/java/dev/caskeleton/moduleboundary/GraphQlBuildModel.java 293
d324b1bc361a492cfc362ec1d2b8e6eedf9c75c6 src/test/java/dev/caskeleton/moduleboundary/GraphQlModuleBoundaryTest.java 190
143beb792061e08b66e2a2bb2519b771a39dea79 src/test/java/dev/caskeleton/moduleboundary/GraphQlSourceGraph.java 30
file_count=60

=== 8.1 조립 진입점과 컴포지션 루트의 관계 ===
$ cat adapter/inbound/graphql/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
dev.caskeleton.adapter.inbound.graphql.autoconfigure.GraphQlRootAutoConfiguration
exit=0

$ cat adapter/inbound/graphql/src/main/resources/META-INF/spring.factories
org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\
dev.caskeleton.adapter.inbound.graphql.autoconfigure.GraphQlOffAutoConfigurationImportFilter
org.springframework.boot.EnvironmentPostProcessor=\
dev.caskeleton.adapter.inbound.graphql.autoconfigure.GraphQlActivationEnvironmentPostProcessor
exit=0

$ grep -n 'graphql' app-bootstrap/src/main/java/dev/caskeleton/bootstrap/CaSkeletonApplication.java
108:          + "|dev\\.caskeleton\\.adapter\\.inbound\\.graphql\\..*"
exit=0

$ grep -rn 'inbound.graphql' --include=*.java app-bootstrap/src/main sample-portfolio/src/main | wc -l
0
exit=0

$ grep -n '@Import' -A 12 adapter/inbound/graphql/src/main/java/dev/caskeleton/adapter/inbound/graphql/autoconfigure/GraphQlRootAutoConfiguration.java
23:@Import({
24-  GraphQlPlatformAutoConfiguration.class,
25-  // The resolver for the schema's only field. It is a @Controller in a package the composition
26-  // root's component scan excludes by regex — the exclusion that makes this capability optional —
27-  // and no root imported it, so a deployment with GraphQL on served a schema declaring
28-  // `_health: String!` with nothing to resolve it. Every query answered
29-  // NullValueInNonNullableField. Its own tests passed throughout by registering the class
30-  // themselves, which is the shape of the defect rather than a defence against it.
31-  dev.caskeleton.adapter.inbound.graphql.HealthGraphqlController.class
32-})
33-public class GraphQlRootAutoConfiguration {}
exit=0

=== 8.2 off 계약: 프레임워크 자동설정 차단 ===
$ grep -c 'org.springframework.boot.graphql.autoconfigure' adapter/inbound/graphql/src/main/java/dev/caskeleton/adapter/inbound/graphql/autoconfigure/GraphQlOffAutoConfigurationImportFilter.java
10
exit=0

$ grep -n 'fails open silently' -B 2 -A 2 adapter/inbound/graphql/src/main/java/dev/caskeleton/adapter/inbound/graphql/autoconfigure/GraphQlOffAutoConfigurationImportFilter.java
16- * one whose project beans are absent while the framework serves it anyway.
17- *
18: * <p>A misspelled entry fails open silently — the filter simply never matches — so the test that
19- * protects this asserts a 404 on the real port rather than checking what this method returns.
20- */
exit=0

$ grep -rn 'backend.graphql.enabled=false' --include=*.java adapter/inbound/graphql/src | wc -l
0
exit=0

$ grep -n 'void \|@DisplayName\|statusCode' app-bootstrap/src/test/java/dev/caskeleton/bootstrap/activation/GraphQlShippedAndGatedTest.java | head -14
34:  static void startAllOff() {
43:  static void stop() {
50:  @DisplayName("the GraphQL facade is on the shipped classpath")
51:  void facadeIsShipped() throws ClassNotFoundException {
70:  @DisplayName("GraphQL off publishes no endpoint")
71:  void graphQlOffPublishesNoEndpoint() throws IOException, InterruptedException {
75:    assertThat(graphQl.statusCode())
81:        .isEqualTo(neverMapped.statusCode());
82:    assertThat(graphQl.statusCode())
88:  @DisplayName("GraphQL off holds no schema and no execution bean")
89:  void graphQlOffHoldsNothing() {
exit=0

=== 8.3 은퇴한 설정 키를 무시가 아니라 거부 ===
$ grep -n 'RETIRED_KEYS' -A 10 adapter/inbound/graphql/src/main/java/dev/caskeleton/adapter/inbound/graphql/autoconfigure/GraphQlRetiredSafetyAxis.java | head -14
27:  private static final Map<String, String> RETIRED_KEYS =
28-      Map.of(
29-          "backend.graphql.production",
30-              "it drove anonymous principal handling and allow-by-default authorization while the "
31-                  + "environment enum drove introspection, so the two could disagree",
32-          "backend.graphql.environment",
33-              "it drove introspection and GraphiQL while the production boolean drove authorization, "
34-                  + "so the two could disagree");
35-
36-  private GraphQlRetiredSafetyAxis() {}
37-
--
49:    for (String key : RETIRED_KEYS.keySet().stream().sorted().toList()) {
50-      if (environment.containsProperty(key)) {
exit=0

=== 8.4 시작 검증 규칙 수와 .imports 메타데이터 고정 ===
$ grep -c 'problems.add' adapter/inbound/graphql/src/main/java/dev/caskeleton/adapter/inbound/graphql/autoconfigure/GraphQlPlatformStartupValidator.java
21
exit=0

$ grep -c '@Bean' adapter/inbound/graphql/src/main/java/dev/caskeleton/adapter/inbound/graphql/autoconfigure/GraphQlPlatformAutoConfiguration.java
39
exit=0

$ grep -c '@ConditionalOn' adapter/inbound/graphql/src/main/java/dev/caskeleton/adapter/inbound/graphql/autoconfigure/GraphQlPlatformAutoConfiguration.java
43
exit=0

$ grep -n 'theAutoConfigurationIsRegisteredInTheImportsMetadata' -A 14 adapter/inbound/graphql/src/test/java/dev/caskeleton/adapter/inbound/graphql/autoconfigure/GraphQlPlatformAutoConfigurationTest.java
186:  void theAutoConfigurationIsRegisteredInTheImportsMetadata() {
187-    String imports =
188-        readClasspathResource(
189-            "META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports");
190-
191-    assertThat(imports)
192-        .as(
193-            "the registered entry is the master-gated root, not the platform configuration it "
194-                + "imports; registering the platform directly is what let a context assemble a "
195-                + "GraphQL endpoint that no switch had asked for")
196-        .contains(GraphQlRootAutoConfiguration.class.getName())
197-        .doesNotContain(GraphQlPlatformAutoConfiguration.class.getName() + "\n");
198-  }
199-
200-  @Test
exit=0

