Files
clean-architecture-backend-…/docs/superpowers/plans/2026-07-28-httpclient-production-capability-foundation.md

4.7 KiB

HTTP Client Production Capability Foundation Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task.

Goal: Establish the framework-free call-budget and typed operation/target foundation, then close two proven safety defects in the legacy JDK provider without claiming Apache HC5, hard total deadline, egress security, or R2 readiness.

Architecture: application-core owns only a monotonic CallBudget. Product forks continue to own feature-specific semantic ports. adapter:outbound:httpclient owns destination/operation IDs, immutable operation descriptors, relative target construction, status/retry/body semantics, and legacy provider fixes. The generic OutboundHttpClient remains a migration facade.

Scope boundary: This applies Phase 0 and a bounded Phase 1 foundation. Canonical zero-binding composition and active logical cancellation were implemented by later tracked plans. Exact readiness tuple registry, Apache HC5 pool, TLS/DNS/proxy, auth, codec, and real-network qualification remain unimplemented.


Task 1: Add a framework-free monotonic call budget

Files:

  • Create: src/application-core/src/main/java/dev/caskeleton/application/outbound/CallBudget.java

  • Test: src/application-core/src/test/java/dev/caskeleton/application/outbound/CallBudgetTest.java

  • Write RED tests for expiry, remaining time, finite bounds, and parent/child intersection.

  • Implement without Spring, wall-clock timestamps, scheduler, or HTTP types.

  • Verify GREEN.

Task 2: Add typed operation catalog and safe target construction

Files:

  • Modify: src/adapter/outbound/httpclient/build.gradle

  • Create: src/adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/operation/HttpDestinationId.java

  • Create: src/adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/operation/HttpOperationId.java

  • Create: src/adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/operation/HttpOperationDescriptor.java

  • Create: src/adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/operation/HttpOperationCatalog.java

  • Create: src/adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/target/FixedHttpDestination.java

  • Create: src/adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/target/HttpTargetBuilder.java

  • Test: src/adapter/outbound/httpclient/src/test/java/dev/caskeleton/adapter/outbound/httpclient/operation/HttpOperationCatalogTest.java

  • Test: src/adapter/outbound/httpclient/src/test/java/dev/caskeleton/adapter/outbound/httpclient/target/HttpTargetBuilderTest.java

  • Write RED tests for ID/uniqueness/cross-field operation invariants.

  • Write RED tests rejecting absolute, scheme-relative, traversal, user-info, query/fragment, and multi-segment variables.

  • Implement closed immutable descriptors and one-pass path-segment encoding.

  • Verify GREEN.

Task 3: Correct characterized legacy provider safety defects

Files:

  • Modify: src/adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/OutboundHttpClient.java

  • Modify: src/adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/OutboundHttpRestClientFactory.java

  • Test: src/adapter/outbound/httpclient/src/test/java/dev/caskeleton/adapter/outbound/httpclient/OutboundHttpClientSafetyRegressionTest.java

  • Reproduce streaming 5xx body delivery and logical-call-only circuit-breaker counting.

  • Make streaming validate status before exposing the body and discard error bodies.

  • Put circuit breaker around each physical attempt and retry around the attempt loop.

  • Set JDK redirects to NEVER explicitly and validate legacy base URI/relative request targets.

  • Verify focused regressions and the full legacy test suite.

Task 4: Record exact readiness and verify

Files:

  • Modify: src/adapter/outbound/httpclient/README.md

  • Modify: src/adapter/outbound/httpclient/CLAUDE.md

  • Modify: docs/superpowers/specs/2026-07-27-httpclient-production-capability-design.md

  • Mark the implemented foundation and fixed legacy defects.

  • Track later total-deadline and canonical-zero-binding increments separately while keeping Apache pool, fixed egress, TLS/auth, bounded decoded streaming, and R2 cards unimplemented.

  • Run:

cd src
./gradlew :application-core:check :adapter:outbound:httpclient:check --console=plain
./gradlew verifyCleanArchitectureDependencies --console=plain