--- id: gateway-dispatch name: GatewayDispatch — shared dispatch spine (invoke + streaming) status: pending depends_on: [server-core-types] scope: moderate risk: medium impact: component level: implementation tags: [gateway, phase-1] --- ## Description Port the dispatch spine from `/workspace/@alkdev/alknet/crates/alknet-http/src/gateway/dispatch.rs` to alkcall's API: `GatewayDispatch::new(registry, identity_provider)`, `invoke()` (identity resolve → root OperationContext → `OperationRegistry` invoke → ResponseEnvelope), and `invoke_streaming()` (`BoxStream` for Sub ops). The security invariants must hold identically across both: `External`-only (Internal → NOT_FOUND), `AccessControl::check` gating, no env-var reads. Port the error mapping (`gateway/error.rs`) too: CallError → HTTP status per docs/architecture/http-server.md §Error Mapping (NOT_FOUND→404, FORBIDDEN→401/403, INVALID_INPUT→422, TIMEOUT→504, INTERNAL→500, `HTTP_` passthrough, retryable→Retry-After hint). ## Acceptance Criteria - [ ] `invoke()` + `invoke_streaming()` ported against alkcall dispatch - [ ] Error mapping table ported with unit tests per row - [ ] Internal ops → 404 before ACL; ACL failure → 401/403 distinction preserved - [ ] `cargo test` passes ## References - docs/architecture/http-server.md (§HTTP-to-call dispatch, §Error Mapping) - docs/architecture/decisions/023-operation-error-schemas.md - alkcall ADR-016 (error schemas), ADR-017 (privilege model) ## Notes > Agent fills during implementation. ## Summary > Agent fills on completion.