## Description The phantom-reachability helper registers a Java 9+ `Cleaner` action but discards the registration handle. Wrapper classes such as `PhantomReachableClosingHttpClient`, `PhantomReachableSleeper`, `PhantomReachableClosingStreamResponse`, `PhantomReachableClosingAsyncStreamResponse`, and `PhantomReachableClosingHttpRequestAuthenticator` then implement explicit `close()` by calling the underlying resource directly. That creates two independent cleanup paths: 1. explicit wrapper close; 2. the still-registered cleaner action after the wrapper becomes phantom reachable. A resource that is closed explicitly can therefore be closed a second time later by the cleaner. ## Why it matters `AutoCloseable.close()` is not generally required to be idempotent. Provider-owned authenticators, custom HTTP clients, stream responses, or sleepers can perform stateful cleanup or throw on repeated close. Cleanup should run at most once regardless of whether it is triggered explicitly or by GC fallback. ## Expected behavior Explicit cleanup and phantom-reachable cleanup should share one idempotent close gate. An explicit close should mark the registered cleanup as already performed, so a later Cleaner invocation becomes a no-op. ## Suggested approach Have `closeWhenPhantomReachable(...)` return a small close handle backed by a shared atomic once-guard. Register that same guarded action with the Cleaner and have explicit-close wrappers call the returned handle instead of closing the delegate independently. Java 8 can use the same handle for explicit cleanup while retaining the existing no-Cleaner fallback. ## Scope The executor-service wrapper is less sensitive because repeated `shutdown()` is safe, but the `AutoCloseable` wrappers should not rely on delegate idempotency.