From fd098799137270121a66515819cdb71f1c23d70c Mon Sep 17 00:00:00 2001 From: Benoit TRAVERS Date: Wed, 2 Sep 2026 14:42:24 +0200 Subject: [PATCH] =?UTF-8?q?docs:=20stop=20advertising=20client=20intercept?= =?UTF-8?q?ors=20=E2=80=94=20they=20were=20cut?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `533c796` removed `CreateClientOptions.interceptors`, `ClientInterceptor` and friends ("no consumer in the repo beyond a single test; every client method already returns an `AsyncResult` that composes"). Two places kept promising them: the README's feature list, where a reader would go looking for an option that does not exist, and the handlers rule, which told an agent the client has a mirror-image seam to the activity middleware. The rule now says why there is none, since that is the part worth knowing: a client call hands you an `AsyncResult`, so wrapping it is composing one — no registration, no hook. Activity middleware exists because the platform invokes the activity and the application never holds its `AsyncResult`. Refs #374 Claude-Session: https://claude.ai/code/session_01GGixjxi5AQ2cNK62bBymfF --- .agents/rules/handlers.md | 8 ++++++-- README.md | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.agents/rules/handlers.md b/.agents/rules/handlers.md index cd6200f1..19a0afce 100644 --- a/.agents/rules/handlers.md +++ b/.agents/rules/handlers.md @@ -69,8 +69,12 @@ boundary, operating on the `AsyncResult` — not thrown exceptions). Middleware accumulates context with bounded generics (`TContextOut extends TContextIn`, amqp-contract's model): `next({ context })` extends what downstream stages and the implementation see; `next({ input })` substitutes the input (re-validated). -The client has the mirror-image seam: `TypedClient.create({ interceptors })` -wraps start/execute/signalWithStart and handle-level signal/query/update. +The client has **no** mirror-image seam, deliberately: client interceptors were +cut in `533c796` because every client method already answers an `AsyncResult`, +so wrapping a call is composing one — `.tap`, `.flatMap`, `.mapErrCases` at the +call site, no registration and no framework hook to learn. Middleware exists on +the activity side because there is no `AsyncResult` in the caller's hand to +compose: the platform invokes the activity, not the application. ## Workflow Declaration diff --git a/README.md b/README.md index bedc27ba..cfd378f5 100644 --- a/README.md +++ b/README.md @@ -126,8 +126,8 @@ partial state, nothing to unwind. [unthrown](https://github.com/btravstack/unthrown), with a separate `defect` channel that keeps genuine bugs loud - **Child workflows** — typed, including across contracts and teams -- **Schedules, cancellation scopes, continue-as-new, activity middleware, client - interceptors** — all contract-aware +- **Schedules, cancellation scopes, continue-as-new, activity middleware** — + all contract-aware - **Testing utilities** — time-skipping (no Docker) and real-server (testcontainers) fixtures - **Nexus** — not implemented; see