Review 007 Unit 2 (the two "implement" decisions taken during
remediation, plus the coverage gap):
- WS-29: the `op/register` override surface review-006 UP-02 and
ADR-048 recorded as landed is now implemented. The hook threads an
`op_register_acl` `AccessControl` into `op_register_spec` (the
permissive `AccessControl::default()` remains the default
everywhere); the built-in surface sets it via
`HttpAdapter::with_ws_op_register_acl`, bare-registry/custom routes
via the `OpRegisterAcl` request extension (mirroring
`ChannelsPolicy`/`WsTimeouts`/`OpenableAlpns`). A peer whose
identity does not satisfy the ACL gets `FORBIDDEN` on the announce.
Gates: builder path (`FORBIDDEN` scope-less / announce-ok scoped)
+ extension path.
- WS-30: the bare-registry `SessionState` is built by `FromRef` per
request, so its default-cap semaphore bounds nothing across
requests (corrects review-002 WS-17's "bounded at 64 sessions"
claim). New `SessionSlots` request extension carries the shared
semaphore for routes that need an effective cap; the upgrade
handler prefers it over the state value. Doc comments corrected
(`SessionState`, `WsTimeouts`, `ws_upgrade_handler`). Gate:
cap-1 route → 503 over cap → slot freed on session end.
- WS-32: the built-in openables threading
(`with_ws_openable_alpns` → `RouterState` → `SessionState` → hook)
gets its first gate — every Unit-3 gate rode the `OpenableAlpns`
extension fallback. `builder_path_openables_serve_the_data_channel_
surface` discovers the openable via `services/list`, opens the
channel, and round-trips bytes through the builder-built router.
Verification: cargo test 454 passed / 0 failed; cargo test
--all-features 587 passed / 0 failed (+5 gates); clippy (both
configs) clean; fmt clean.
Review: docs/reviews/007-ws-data-channel-surface-review.md