Sub-scope 02 (httpclient) api/** — manifest and probes revision=a24ece9cf797f7ea647e33bf846b115208ed1ba5 generatedAt=2026-08-30T05:25:21+00:00 === OWNED FILES === ac051d6ff5da098df0d5ead6080bebf8e9b2ffef main/java/dev/caskeleton/adapter/outbound/httpclient/api/ClientProfileName.java 22 109aa96a96dd955c954ac5e41e2d34a5c06c0b3f main/java/dev/caskeleton/adapter/outbound/httpclient/api/HttpMethod.java 34 c18b35c5c688e4b9193ea00a552ff09676d4a009 main/java/dev/caskeleton/adapter/outbound/httpclient/api/HttpStatus.java 40 5f930fd40a8eaf658b8b9801cbdc58c8c559febd main/java/dev/caskeleton/adapter/outbound/httpclient/api/IdempotencyKey.java 28 2723bdee659790f804bef0213d0e96a2b6f8fd90 main/java/dev/caskeleton/adapter/outbound/httpclient/api/OperationName.java 22 8206f618711a76c34f327a3759338a69bf28b41d main/java/dev/caskeleton/adapter/outbound/httpclient/api/body/BodySource.java 20 beea3c440a1cf407645de65ece036ad132278b19 main/java/dev/caskeleton/adapter/outbound/httpclient/api/body/ByteArrayBody.java 65 2c2e7aaa75c7edf52990ea2010c776b6cfebf014 main/java/dev/caskeleton/adapter/outbound/httpclient/api/body/EmptyBody.java 29 944d067221a145523c43eeb243bea0a760be6b38 main/java/dev/caskeleton/adapter/outbound/httpclient/api/body/IOSupplier.java 9 91b721cbf8d277b2ac726ab30091c301095750c5 main/java/dev/caskeleton/adapter/outbound/httpclient/api/body/ObjectBody.java 118 f2fa6c413f2576355c283bfb3f237514516f36a2 main/java/dev/caskeleton/adapter/outbound/httpclient/api/body/OneShotStreamBody.java 27 8aa57aff54ff417b111053a4bb15726328747a63 main/java/dev/caskeleton/adapter/outbound/httpclient/api/body/ReopenableStreamBody.java 27 8e63ae034dcdad46b94f9fb6da75f7bd08fcae1f main/java/dev/caskeleton/adapter/outbound/httpclient/api/error/HttpAmbiguousExecutionException.java 19 b63fd6bb8d8af82f0e37262bb676e06244bab808 main/java/dev/caskeleton/adapter/outbound/httpclient/api/error/HttpAuthenticationException.java 16 6b633552030b49f6ea3231b6b89ad814e0f053f2 main/java/dev/caskeleton/adapter/outbound/httpclient/api/error/HttpBulkheadRejectedException.java 16 22a6b2c916af9b6c3c3ecf3344efc879cb3edcff main/java/dev/caskeleton/adapter/outbound/httpclient/api/error/HttpCircuitOpenException.java 16 69086e6e4e21e023b33dc5dd22d01b117b4ec617 main/java/dev/caskeleton/adapter/outbound/httpclient/api/error/HttpClientException.java 29 0050f90d585e5cfb6402f23caf7a30d0ae7ea196 main/java/dev/caskeleton/adapter/outbound/httpclient/api/error/HttpConfigurationException.java 16 4c0eb81bb2a56187ba09e539e743a8dce733d917 main/java/dev/caskeleton/adapter/outbound/httpclient/api/error/HttpConnectException.java 15 fa715ffd09c733feb1710a23ec2a1e044b59f8a3 main/java/dev/caskeleton/adapter/outbound/httpclient/api/error/HttpDeadlineExceededException.java 16 c85fa8cbe40d4901c5c263d57f2b57e581380622 main/java/dev/caskeleton/adapter/outbound/httpclient/api/error/HttpDnsException.java 15 15adc48df968f15b228ec9b166fe4b699b227e71 main/java/dev/caskeleton/adapter/outbound/httpclient/api/error/HttpFailureMetadata.java 165 30cbf577a99199a4c59c4ef4bcf07180936ef642 main/java/dev/caskeleton/adapter/outbound/httpclient/api/error/HttpPoolAcquireTimeoutException.java 16 e5b6ab8bc194451149d817af6a6148fe3c8c90ce main/java/dev/caskeleton/adapter/outbound/httpclient/api/error/HttpProblemDetailException.java 32 711b28287f5ae6fe9dbe77bfb38aac5457d8224c main/java/dev/caskeleton/adapter/outbound/httpclient/api/error/HttpProxyException.java 17 2d5073e6785cfb3473b7222d99262368cce127d4 main/java/dev/caskeleton/adapter/outbound/httpclient/api/error/HttpRateLimitRejectedException.java 16 f0c69534090bf8c18b046e43b235afb5d3121eca main/java/dev/caskeleton/adapter/outbound/httpclient/api/error/HttpRedirectRejectedException.java 16 71d93c881ab34d7bb25e4b731bf5db68384feab4 main/java/dev/caskeleton/adapter/outbound/httpclient/api/error/HttpRemoteErrorException.java 29 3897621bca251274592cb1dafbcd12deb12ba259 main/java/dev/caskeleton/adapter/outbound/httpclient/api/error/HttpRequestWriteException.java 16 8f7f76ed629c45f5416627cf6d12c5ca3d1cd1a2 main/java/dev/caskeleton/adapter/outbound/httpclient/api/error/HttpResponseTimeoutException.java 16 4cf2f0d0b38e75684324bd7d8729070d5c627c45 main/java/dev/caskeleton/adapter/outbound/httpclient/api/error/HttpResponseTooLargeException.java 16 7962ed4ad2b06b595f0d8680f674967077a5f801 main/java/dev/caskeleton/adapter/outbound/httpclient/api/error/HttpResponseTruncatedException.java 16 e6c8e6e19142bcdc54444b4f69b79fe63e49c524 main/java/dev/caskeleton/adapter/outbound/httpclient/api/error/HttpSerializationException.java 16 e1f8c8bf715939797edab40e9c4ccfb46fd236aa main/java/dev/caskeleton/adapter/outbound/httpclient/api/error/HttpTargetRejectedException.java 16 168e969de17926f060ea768f20376cfdac56f32d main/java/dev/caskeleton/adapter/outbound/httpclient/api/error/HttpTlsException.java 15 6943b79d5426a289975d1ee004c07e7350a9b281 main/java/dev/caskeleton/adapter/outbound/httpclient/api/operation/AttemptStage.java 43 59c3b822c8a37d0625c225997eae28111c862d55 main/java/dev/caskeleton/adapter/outbound/httpclient/api/operation/BodyReplayability.java 37 a818cd22128bdcbc7edefdb76c53f2821bba3867 main/java/dev/caskeleton/adapter/outbound/httpclient/api/operation/ExecutionEvidence.java 14 108c539f1b3aba47836030c061b5d9fbf5c8b34b main/java/dev/caskeleton/adapter/outbound/httpclient/api/operation/FailureCategory.java 45 0c3f97572225856960cf6099593260cbb90973cc main/java/dev/caskeleton/adapter/outbound/httpclient/api/operation/HttpOperation.java 152 a6be4c7381a33fb7a3317e9396f092eaa02aace3 main/java/dev/caskeleton/adapter/outbound/httpclient/api/operation/OperationIdempotency.java 24 260ef842b64b68c7619b78cf9614bba9d2e70cd0 main/java/dev/caskeleton/adapter/outbound/httpclient/api/result/BlockingStreamingResponse.java 24 168e6efd79e971cfe1d28a048ecf00d65b90b600 main/java/dev/caskeleton/adapter/outbound/httpclient/api/result/ByteArrayResponseType.java 12 f22be085453a090ad5851ab3142609513ed1b8dc main/java/dev/caskeleton/adapter/outbound/httpclient/api/result/ClassResponseType.java 17 68a6444159dc880f1e60a0206ce206f2f2866529 main/java/dev/caskeleton/adapter/outbound/httpclient/api/result/EmptyResponseType.java 12 a58d109539ed76545cbf6b6c2879889d23f876c5 main/java/dev/caskeleton/adapter/outbound/httpclient/api/result/GenericResponseType.java 17 841b2cf0bc81440ec84d2676b0a1a50b4e92badf main/java/dev/caskeleton/adapter/outbound/httpclient/api/result/HttpCallResult.java 44 90c99ea907b3bf3d3f94a844f5597e248cc52768 main/java/dev/caskeleton/adapter/outbound/httpclient/api/result/IdempotencyKeyRequirement.java 36 f2743d32560f528841327d3fe12e3b8d0b60ccb9 main/java/dev/caskeleton/adapter/outbound/httpclient/api/result/RemoteProblem.java 47 2b5c882fb6cd993ebd1ec5c98b9f8b9aa92ffaed main/java/dev/caskeleton/adapter/outbound/httpclient/api/result/ResponseType.java 27 a029d27651075245e111b9b83c6def1a50b796ff test/java/dev/caskeleton/adapter/outbound/httpclient/api/CoreValueTypeTest.java 38 bcfbd36e3647ec65ca3fdf863c8745f931a2de43 test/java/dev/caskeleton/adapter/outbound/httpclient/api/body/BodyReplayabilityTest.java 58 370696c1bee9e2ea80364067270ba7e458f88e9e test/java/dev/caskeleton/adapter/outbound/httpclient/api/body/ObjectBodyReplayabilityTest.java 70 8d7cf44c0e992485297f92ad52c7050754a7fa11 test/java/dev/caskeleton/adapter/outbound/httpclient/api/error/StableExceptionTest.java 39 10909e199ca528b5f9fc4d50ed0d104922e58a08 test/java/dev/caskeleton/adapter/outbound/httpclient/api/operation/HttpOperationTest.java 69 main: 50 test: 5 === 8.1 안전한 toString: 값이 새는 타입이 남아 있는가 === $ git grep -Ln 'public String toString' -- 'adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/api/body' | head adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/api/body/BodySource.java adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/api/body/EmptyBody.java adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/api/body/IOSupplier.java adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/api/body/OneShotStreamBody.java adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/api/body/ReopenableStreamBody.java exit=0 $ grep -rn 'REDACTED\|toString()' adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/api/operation/HttpOperation.java adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/api/body/ObjectBody.java adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/api/IdempotencyKey.java | head adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/api/operation/HttpOperation.java:126: public String toString() { adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/api/body/ObjectBody.java:41: public String toString() { adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/api/body/ObjectBody.java:42: return "ObjectBody[" + value.getClass().getSimpleName() + ", " + mediaType + ", REDACTED]"; adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/api/IdempotencyKey.java:9: * exception messages, so {@link #toString()} is redacted. The raw value is available only through adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/api/IdempotencyKey.java:25: public String toString() { adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/api/IdempotencyKey.java:26: return "IdempotencyKey[REDACTED]"; exit=0 $ git grep -c 'record ' -- 'adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/api' | head -5 adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/api/ClientProfileName.java:1 adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/api/HttpStatus.java:1 adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/api/IdempotencyKey.java:1 adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/api/OperationName.java:1 adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/api/body/ByteArrayBody.java:1 exit=0 === 8.2 ObjectBody.deeplyImmutable의 허용 목록 === $ grep -n 'instanceof' adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/api/body/ObjectBody.java 60: if (candidate instanceof String 61: || candidate instanceof Number 62: || candidate instanceof Boolean 63: || candidate instanceof Character 64: || candidate instanceof Enum> 65: || candidate instanceof java.util.UUID 66: || candidate instanceof java.time.temporal.Temporal) { 69: if (candidate instanceof java.util.Collection> collection) { 73: if (candidate instanceof java.util.Map, ?> map) { exit=0 $ grep -n 'isImmutableCollectionView' -A 8 adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/api/body/ObjectBody.java | tail -12 81- return false; 82- } -- 106: private static boolean isImmutableCollectionView(Object collection) { 107- String name = collection.getClass().getName(); 108- return name.startsWith("java.util.ImmutableCollections") 109- || name.startsWith("java.util.Collections$Unmodifiable") 110- || name.startsWith("java.util.Collections$Empty") 111- || name.startsWith("java.util.Collections$Singleton"); 112- } 113- 114- @Override exit=0 === 8.3 실패 어휘와 예외 계층의 대응 === $ grep -oE '^ [A-Z_]+,' adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/api/operation/FailureCategory.java | tr -d ' ,' | sort AUTHENTICATION BULKHEAD_REJECTED CANCELLED CIRCUIT_OPEN CONFIGURATION CONNECT DEADLINE_EXCEEDED DNS NONE POOL_ACQUIRE_TIMEOUT PROXY RATE_LIMIT_REJECTED REDIRECT_REJECTED REMOTE_STATUS REQUEST_WRITE RESPONSE_TIMEOUT RESPONSE_TOO_LARGE RESPONSE_TRUNCATED SERIALIZATION TARGET_REJECTED TLS_PERMANENT TLS_TRANSIENT exit=0 $ git ls-files 'adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/api/error' | xargs -n1 basename | sed 's/\.java//' | sort HttpAmbiguousExecutionException HttpAuthenticationException HttpBulkheadRejectedException HttpCircuitOpenException HttpClientException HttpConfigurationException HttpConnectException HttpDeadlineExceededException HttpDnsException HttpFailureMetadata HttpPoolAcquireTimeoutException HttpProblemDetailException HttpProxyException HttpRateLimitRejectedException HttpRedirectRejectedException HttpRemoteErrorException HttpRequestWriteException HttpResponseTimeoutException HttpResponseTooLargeException HttpResponseTruncatedException HttpSerializationException HttpTargetRejectedException HttpTlsException exit=0 === 8.4 TRACE 부재 주장 === $ grep -n 'TRACE' adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/api/HttpMethod.java 6: *
TRACE is deliberately absent: design §31 requires the unsupported method to be impossible to exit=0 $ git grep -rn '"TRACE"\|HttpMethod.TRACE' -- 'adapter/outbound/httpclient/src' 'app-bootstrap/src' | head adapter/outbound/httpclient/src/test/java/dev/caskeleton/adapter/outbound/httpclient/api/CoreValueTypeTest.java:25: assertThat(Arrays.stream(HttpMethod.values()).map(Enum::name)).doesNotContain("TRACE"); exit=0 === 8.4b api test === $ git ls-files 'adapter/outbound/httpclient/src/test/java/dev/caskeleton/adapter/outbound/httpclient/api' | xargs -n1 basename CoreValueTypeTest.java BodyReplayabilityTest.java ObjectBodyReplayabilityTest.java StableExceptionTest.java HttpOperationTest.java exit=0 $ git grep -h ' void [a-z]' -- 'adapter/outbound/httpclient/src/test/java/dev/caskeleton/adapter/outbound/httpclient/api' | sed 's/^ *//' void validatesStableNames() { void exposesHttpMethodSemanticsWithoutTrace() { void redactsIdempotencyKeyInTextRepresentation() { void rejectsOutOfRangeStatus() { void classifiesBodySources() { void oneShotBodyRejectsNullStream() { void byteArrayBodyDefensivelyCopiesBothWays() { void compositeReplayabilityFollowsWeakestPart() { void anImmutableRecordReplays() { void aMutableValueIsOneShot() { void aRecordWrappingMutableStateIsOneShot() { void anArbitraryBeanIsOneShot() { void ambiguousFailurePreservesEvidenceWithoutSecrets() { void everyStableFailureExposesMetadata() { void remoteErrorExposesWireStatus() { void requiresIdempotencyKeyWhenPolicyRequiresIt() { void storesUriTemplateRatherThanExpandedUrl() { void headersAreDeeplyImmutable() { void callResultRequiresAtLeastOneAttempt() { exit=0