81 lines
4.7 KiB
Markdown
81 lines
4.7 KiB
Markdown
# 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`
|
|
|
|
- [x] Write RED tests for expiry, remaining time, finite bounds, and parent/child intersection.
|
|
- [x] Implement without Spring, wall-clock timestamps, scheduler, or HTTP types.
|
|
- [x] 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`
|
|
|
|
- [x] Write RED tests for ID/uniqueness/cross-field operation invariants.
|
|
- [x] Write RED tests rejecting absolute, scheme-relative, traversal, user-info, query/fragment, and
|
|
multi-segment variables.
|
|
- [x] Implement closed immutable descriptors and one-pass path-segment encoding.
|
|
- [x] 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`
|
|
|
|
- [x] Reproduce streaming 5xx body delivery and logical-call-only circuit-breaker counting.
|
|
- [x] Make streaming validate status before exposing the body and discard error bodies.
|
|
- [x] Put circuit breaker around each physical attempt and retry around the attempt loop.
|
|
- [x] Set JDK redirects to `NEVER` explicitly and validate legacy base URI/relative request targets.
|
|
- [x] 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`
|
|
|
|
- [x] Mark the implemented foundation and fixed legacy defects.
|
|
- [x] 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.
|
|
- [x] Run:
|
|
|
|
```bash
|
|
cd src
|
|
./gradlew :application-core:check :adapter:outbound:httpclient:check --console=plain
|
|
./gradlew verifyCleanArchitectureDependencies --console=plain
|
|
```
|