From 9ad8113c79a032e202708a3a8e8e444702913bb6 Mon Sep 17 00:00:00 2001 From: Erik Date: Tue, 21 Jul 2026 09:04:31 +0200 Subject: [PATCH] docs(architecture): close selection extraction slice Record the measured GameWindow reduction, final review and test gates, durable selection/inventory ownership rules, and live animation presentation as Slice 2. Co-authored-by: OpenAI Codex --- AGENTS.md | 15 +++++--- CLAUDE.md | 15 +++++--- docs/ISSUES.md | 38 +++++++++++-------- docs/README.md | 7 ++-- docs/architecture/acdream-architecture.md | 5 ++- docs/architecture/code-structure.md | 36 +++++++++++------- docs/plans/2026-04-11-roadmap.md | 14 +++++-- docs/plans/2026-05-12-milestones.md | 7 ++-- ...amewindow-slice-1-selection-interaction.md | 23 ++++++++++- memory/project_ui_architecture.md | 33 ++++++++++++++++ 10 files changed, 141 insertions(+), 52 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index ccad370b..ce61024d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -115,13 +115,16 @@ and the final two-client portal-out/materialization observer flow are user-gated. Deterministic world-lifecycle automation protects fresh login, outdoor/world-edge/dungeon travel, same-location revisit, exact graceful disconnect, and uncapped fresh-process reconnect with JSON/PNG artifacts. -Release builds; 6,481 tests pass / 5 skip (17 tracked warnings, #228). +Release builds; 6,558 tests pass / 5 skip (17 tracked warnings, #228). -**Active prerequisite before new M4 subsystem work:** complete the -behavior-preserving `GameWindow` decomposition reconciled on 2026-07-21. The -next slice finishes selection/interaction ownership; later slices finish -animation presentation, live-session and live-entity App integration, -landblock presentation, update/render orchestration, and composition cleanup. +**Active prerequisite before new M4 subsystem work:** continue the +behavior-preserving `GameWindow` decomposition reconciled on 2026-07-21. +Selection/interaction Slice 1 is complete: `WorldSelectionQuery` and +`SelectionInteractionController` own the domain, exact-incarnation queued work, +and retail's shared inventory-request transaction. Slice 2 finishes live +animation presentation; later slices finish live-session and live-entity App +integration, landblock presentation, update/render orchestration, and +composition cleanup. See `docs/architecture/code-structure.md`. **Carried:** #153, #116, remaining R6 ownership cleanup, TS-50/TS-51, Modern Pipeline MP1b+, and #225's lifestone/particle alpha visual gate. diff --git a/CLAUDE.md b/CLAUDE.md index cd79a560..0ba9129b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -113,13 +113,16 @@ and the final two-client portal-out/materialization observer flow are user-gated. Deterministic world-lifecycle automation protects fresh login, outdoor/world-edge/dungeon travel, same-location revisit, exact graceful disconnect, and uncapped fresh-process reconnect with JSON/PNG artifacts. -Release builds; 6,481 tests pass / 5 skip (17 tracked warnings, #228). +Release builds; 6,558 tests pass / 5 skip (17 tracked warnings, #228). -**Active prerequisite before new M4 subsystem work:** complete the -behavior-preserving `GameWindow` decomposition reconciled on 2026-07-21. The -next slice finishes selection/interaction ownership; later slices finish -animation presentation, live-session and live-entity App integration, -landblock presentation, update/render orchestration, and composition cleanup. +**Active prerequisite before new M4 subsystem work:** continue the +behavior-preserving `GameWindow` decomposition reconciled on 2026-07-21. +Selection/interaction Slice 1 is complete: `WorldSelectionQuery` and +`SelectionInteractionController` own the domain, exact-incarnation queued work, +and retail's shared inventory-request transaction. Slice 2 finishes live +animation presentation; later slices finish live-session and live-entity App +integration, landblock presentation, update/render orchestration, and +composition cleanup. See `docs/architecture/code-structure.md`. **Carried:** #153, #116, remaining R6 ownership cleanup, TS-50/TS-51, Modern Pipeline MP1b+, and #225's lifestone/particle alpha visual gate. diff --git a/docs/ISSUES.md b/docs/ISSUES.md index 10a8dc8c..b988fa83 100644 --- a/docs/ISSUES.md +++ b/docs/ISSUES.md @@ -26,8 +26,8 @@ What does NOT go here: ## Current queue — 2026-07-21 -- **Active structural work:** `GameWindow` decomposition, beginning with the - selection/interaction ownership slice in +- **Active structural work:** `GameWindow` decomposition. Selection/interaction + ownership is complete; Slice 2 live animation presentation is next in [`docs/architecture/code-structure.md`](architecture/code-structure.md). This is the behavior-preserving prerequisite before new M4 feature bodies. - **Separate rendering gate:** `#225`, lifestone/particle alpha ordering. Its @@ -69,7 +69,7 @@ Copy this block when adding a new issue: ## #231 — F-key pickup omits retail pending destination-slot presentation -**Status:** FIXED (2026-07-21) — keyboard pickup uses the shared ItemHolder path +**Status:** DONE (2026-07-21, `52dbb574` + `5acc3f01`) **Severity:** MEDIUM **Filed:** 2026-07-21 **Component:** selection / inventory / retained UI @@ -86,9 +86,9 @@ always sends `CM_Item::SendNotice_ShowPendingInPlayer` before `ItemInteractionController` and raises `PendingBackpackPlacementRequested`; the F-key switch case bypasses that owner. -**Files:** `src/AcDream.App/Rendering/GameWindow.cs`; -`src/AcDream.App/UI/ItemInteractionController.cs`; -future `src/AcDream.App/Interaction/SelectionInteractionController.cs`. +**Files:** `src/AcDream.App/UI/ItemInteractionController.cs`; +`src/AcDream.App/Interaction/SelectionInteractionController.cs`; +`src/AcDream.App/UI/Layout/InventoryController.cs`. **Research:** [`docs/plans/2026-07-21-gamewindow-slice-1-selection-interaction.md`](plans/2026-07-21-gamewindow-slice-1-selection-interaction.md). @@ -99,15 +99,20 @@ Server confirmation settles it; server failure removes it without speculative ownership mutation. **Resolution:** `ItemInteractionController.PlaceWorldItemInBackpack` now owns -the shared pending-placement notification and request dispatch. Both -double-click activation and the F-key route enter that method, so they publish -the same destination container and placement before the server request. +the exact-token pending destination projection. The F-key route reserves it +before immediate or deferred MoveTo transport, promotes that same reservation +only when the packet is actually sent, and withdraws it on cancel/lifetime +loss. The review correction also ported the single global +`ACCWeenieObject::prevRequest` owner across inventory, external-container, +toolbar, paperdoll, give, merge, split, and drop routes. Optimistic placement, +server rollback, and authoritative response notifications are distinct; a +response clears global and local state atomically before reentrant observers. --- ## #230 — Selection hits and deferred actions can cross live GUID incarnations -**Status:** FIXED (2026-07-21) — incarnation identity is carried and revalidated +**Status:** DONE (2026-07-21, `047a4c83` + `5acc3f01`) **Severity:** HIGH **Filed:** 2026-07-21 **Component:** selection / live entity lifetime / interaction @@ -127,9 +132,9 @@ pending action. `CombatTargetController` also treats SessionReset like an ordinary clear and can re-acquire before live records drain. **Files:** `src/AcDream.Core/Selection/RetailSelectionMesh.cs`; -`src/AcDream.App/Rendering/Selection/`; -`src/AcDream.App/Rendering/GameWindow.cs`; -`src/AcDream.App/Combat/CombatTargetController.cs`. +`src/AcDream.App/Interaction/WorldSelectionQuery.cs`; +`src/AcDream.App/Interaction/SelectionInteractionController.cs`; +`src/AcDream.App/Input/OutboundInteractionQueue.cs`. **Research:** [`docs/plans/2026-07-21-gamewindow-slice-1-selection-interaction.md`](plans/2026-07-21-gamewindow-slice-1-selection-interaction.md). @@ -144,7 +149,10 @@ complete interaction lifetime and never auto-targets. current interaction-visible record. Deferred actions capture the same identity and teardown clears the captured action even after GUID replacement. Session reset now clears published selection geometry, lighting, ItemHolder target and -throttle state, and cannot trigger combat auto-target acquisition. +throttle state, and cannot trigger combat auto-target acquisition. Queued +input also captures the exact `ClientObject` reference, deferred movement is a +cancel-before-arm transaction, and session queue epochs prevent pre-reset work +from crossing into a new world. --- @@ -179,7 +187,7 @@ production runtime failure. **Acceptance:** A non-incremental Release solution build reports zero warnings and zero errors without suppressing analyzers or weakening nullable checking; -the full 6,481-pass / 5-skip suite remains green. +the full 6,558-pass / 5-skip suite remains green. --- diff --git a/docs/README.md b/docs/README.md index 049cac76..58380370 100644 --- a/docs/README.md +++ b/docs/README.md @@ -10,8 +10,9 @@ banner cannot silently override the current program state. world,” is next. - **Active program:** behavior-preserving `GameWindow` decomposition before new M4 subsystem work. The reconciled ownership ledger and slice order are - in [`architecture/code-structure.md`](architecture/code-structure.md); the - next slice finishes selection/interaction ownership. + in [`architecture/code-structure.md`](architecture/code-structure.md). + Selection/interaction Slice 1 is complete; live animation presentation is + next. - **Completed gates:** R6 locomotion/collision/projectile/teleport/radar and the final two-client portal-out/materialization observer comparison (`#218`). - **Separate visual verification:** the shared-alpha lifestone/particle result @@ -23,7 +24,7 @@ banner cannot silently override the current program state. - **Divergence audit:** 178 active rows — IA 17, AD 37, AP 85, TS 34, and UN 5 — plus the retained retired TS-37 history note. - **Latest automated baseline:** Release build succeeds with 17 known - test-project warnings (`#228`); 6,481 tests passed and 5 intentionally + test-project warnings (`#228`); 6,558 tests passed and 5 intentionally skipped. The unattended connected R6 route completed seven portal materializations, production input exercises, and a graceful close. See diff --git a/docs/architecture/acdream-architecture.md b/docs/architecture/acdream-architecture.md index 4c3b6449..97e0556f 100644 --- a/docs/architecture/acdream-architecture.md +++ b/docs/architecture/acdream-architecture.md @@ -833,7 +833,10 @@ Current movement/collision ownership: two-client observer gate; Track LH is the future presentation-independent Linux/headless extraction. - **The behavior-preserving thin-`GameWindow` ownership campaign is the active - prerequisite before new M4 subsystem bodies.** Its reconciled ledger and + prerequisite before new M4 subsystem bodies.** Selection/interaction Slice 1 + landed 2026-07-21 with `WorldSelectionQuery`, + `SelectionInteractionController`, and the shared retail inventory-request + owner; live animation presentation is next. The reconciled ledger and sequence live in `docs/architecture/code-structure.md`. This decision does not reclassify the remaining L.2 conformance work or Track LH. diff --git a/docs/architecture/code-structure.md b/docs/architecture/code-structure.md index 5f1d379f..633ea2b4 100644 --- a/docs/architecture/code-structure.md +++ b/docs/architecture/code-structure.md @@ -1,8 +1,8 @@ # acdream — code structure & extraction sequence **Status:** Living document. Created 2026-05-16; implementation reconciliation -completed 2026-07-21. This is the active structural program before new M4 -subsystems enter the App layer. +completed 2026-07-21; Slice 1 landed the same day. This is the active +structural program before new M4 subsystems enter the App layer. **Purpose:** Describe the desired structural state of the App layer, explain the rules we've adopted, and lay out the safe extraction sequence from today's reality (one 15,723-line `GameWindow.cs` at the @@ -22,8 +22,8 @@ layer is wire-compatible, the UI has a stable contract, plugins load. The structural debt is concentrated in **one file**: ``` -src/AcDream.App/Rendering/GameWindow.cs 15,723 lines (2026-07-21) - 258 fields / ~259 methods +baseline cf50ee3d 15,723 lines / 278 fields / 205 methods +after Slice 1 14,912 lines / 278 fields / 191 methods ``` `GameWindow` is the single object that: @@ -35,9 +35,9 @@ src/AcDream.App/Rendering/GameWindow.cs 15,723 lines (2026-07-21) `LiveSessionController` owns the socket/session shell. - Owns the adapters that hydrate canonical `LiveEntityRuntime` records into animation, collision, rendering, and DAT-backed appearance resources. -- Still drives selection / interaction (`WorldPicker`, target classification, - `SendUse`, `SendPickUp`, auto-walk deferral) despite the shipped item and - combat controllers. +- Composes the shipped `WorldSelectionQuery` and + `SelectionInteractionController`; it no longer owns world-picking, + selection intent, Use/PickUp, or auto-walk deferral algorithms. - Drives per-frame render orchestration (sky → terrain → opaque mesh → transparent mesh → particles → debug lines → UI). - Builds and applies streamed landblock presentation (DAT decode, scenery, @@ -391,7 +391,7 @@ useful ordering seam, but its ownership status is **partial**. | Inbound/object-frame order | **Partial** | `RetailInboundEventDispatcher`, `RetailLiveFrameCoordinator`, `LiveEntityAnimationScheduler`, static scheduler, remote/projectile updaters, and teleport owners are shipped. `AdvanceLiveObjectRuntimeCore`, final part/mesh/effect composition, and several integration tails remain in `GameWindow`. | | World reveal | **Complete** | `WorldRevealCoordinator` owns login/portal readiness and reveal lifetime (`a4ef5788`). The accepted deterministic lifecycle trace did not change after extraction. | | Retained gameplay UI | **Mostly complete feature ownership** | `RetailUiRuntime` and focused panel/controllers own layout and behavior. `GameWindow.OnLoad` still performs substantial service composition, which is allowed until the final composition cleanup. | -| Selection/interaction | **Partial** | `ItemInteractionController`, `CombatTargetController`, and `CombatAttackController` own focused rules. `GameWindow` still owns picking, target queries, selection intent, Use/PickUp sends, range/auto-walk deferral, and related input cases. | +| Selection/interaction | **Complete** | `WorldSelectionQuery` owns read-only picking/classification/range queries; `SelectionInteractionController` owns selection intent, Use/PickUp transport, exact-incarnation queues, and auto-walk deferral; `ItemInteractionController` owns ItemHolder policy plus the shared retail inventory-request transaction. `GameWindow` retains construction and narrow lifecycle forwarding only. | | Landblock presentation | **Not extracted** | Residency scheduling is extracted, but DAT build, scenery/EnvCell construction, apply, collision/resource publication, and retirement glue remain a large `GameWindow` body. | | Render-frame orchestration | **Not extracted** | `OnRender` plus its portal/PView/alpha/particle helpers still own the draw graph and frame-local scratch state. There is no `RenderFrameOrchestrator` yet. | | Unified `GameEntity` | **Deferred target** | `LiveEntityRuntime` already supplies the critical canonical owner. Full type aggregation is a separate high-risk migration and is not required to make `GameWindow` thin. | @@ -409,7 +409,7 @@ two-client portal observer gate form the pre-refactor baseline. Each later slice runs the subset capable of detecting its risk; render/session slices run the complete connected lifecycle gate. -#### Slice 1 — finish selection/interaction ownership — NEXT +#### Slice 1 — finish selection/interaction ownership — COMPLETE 2026-07-21 Detailed execution plan: [`docs/plans/2026-07-21-gamewindow-slice-1-selection-interaction.md`](../plans/2026-07-21-gamewindow-slice-1-selection-interaction.md). @@ -429,11 +429,21 @@ Split the old Step 4 into three reviewable commits: Tests cover read-only query classification separately from stateful intents, including direct use, distant auto-walk completion, corpse/container opening, pickup placement, hostile-only targeting, Hidden objects, and same-GUID reuse. -The connected gate is select → use door/NPC → distant corpse → loot/pickup → -combat target. This is the safest next slice because its outbound boundaries -are typed and existing controllers already hold most retail rules. +The cutover landed in `047a4c83`, `52dbb574`, `e74f2ca9`, `fa8d5232`, +`d2bb5af4`, and review-correction commit `5acc3f01`. The final review also +ported the shared `ACCWeenieObject::prevRequest` transaction shape across +inventory, toolbar, paperdoll, external-container, give, split, merge, and +drop routes. Queued actions, pending placements, and responses are bound to +exact object incarnations/tokens; optimistic projection, rollback projection, +and authoritative response notices are distinct. -#### Slice 2 — finish live animation presentation +Measured against `cf50ee3d`, `GameWindow` fell from 15,723 to 14,912 lines and +from 205 to 191 methods; field count stayed at 278 because the slice exchanged +legacy state for composed owners. Three independent retail, architecture, and +adversarial review loops finished clean. Release build passed; 6,558 tests +passed and five fixture/conformance tests skipped intentionally. + +#### Slice 2 — finish live animation presentation — NEXT Move `TickAnimations`, final rigid/visual part composition, effect-pose publication, and motion-done binding into `LiveEntityAnimationPresenter`. diff --git a/docs/plans/2026-04-11-roadmap.md b/docs/plans/2026-04-11-roadmap.md index 2b122386..8c5ca825 100644 --- a/docs/plans/2026-04-11-roadmap.md +++ b/docs/plans/2026-04-11-roadmap.md @@ -16,9 +16,15 @@ orchestration. **Current sequence:** The implementation audit, exact ownership ledger, slice boundaries, tests, connected gates, and exit criteria live in [`docs/architecture/code-structure.md`](../architecture/code-structure.md) §4. -The next slice is selection/interaction: extract the read-only world query, -move stateful Use/PickUp/auto-walk intent into one controller, then cut the -related input cases over and delete the old `GameWindow` bodies. +Slice 1 selection/interaction landed 2026-07-21: the read-only world query and +stateful intent owner are extracted, exact-incarnation lifetime is enforced, +and retail's global inventory-request transaction is shared across every UI +mutation surface. `GameWindow` is 811 lines and 14 methods smaller. + +**Next:** Slice 2 finishes live animation presentation by moving final +part/mesh/effect-pose composition and motion-done binding behind +`LiveEntityAnimationPresenter`, while preserving the shipped scheduler and +retail object-frame order. This is a behavior-preserving structural program. Severe regressions still get root-cause fixes in separate commits; ordinary feature work resumes with M4 @@ -1473,7 +1479,7 @@ OpenGL ceiling; revisit macOS only if a supported graphics backend is chosen. ## Cross-cutting work tracked in parallel -- **Test coverage.** Each phase lands with layer-matched unit and integration tests in `tests/`. Current Release baseline: 6,481 passed / 5 intentional skips (2026-07-21). +- **Test coverage.** Each phase lands with layer-matched unit and integration tests in `tests/`. Current Release baseline: 6,558 passed / 5 intentional skips (2026-07-21). - **Memory files.** Live subsystem state and digests are indexed by `claude-memory/MEMORY.md`; stable engineering references remain under `memory/`. Canonical program status stays in milestones/roadmap/issues. - **`CLAUDE.md` discipline.** Check all four references (ACE, ACViewer, WorldBuilder, Chorizite) before committing to an approach. WorldBuilder is the closest stack match and should be checked first. diff --git a/docs/plans/2026-05-12-milestones.md b/docs/plans/2026-05-12-milestones.md index 1819bd27..ac36e633 100644 --- a/docs/plans/2026-05-12-milestones.md +++ b/docs/plans/2026-05-12-milestones.md @@ -16,14 +16,15 @@ Before new M4 quest/emote/character-creation subsystem bodies enter the App layer, the active structural prerequisite is the behavior-preserving `GameWindow` decomposition in [`docs/architecture/code-structure.md`](../architecture/code-structure.md). -The 2026-07-21 audit found 15,723 lines, 258 fields, and about 259 methods; -the next slice finishes selection/interaction ownership. +The 2026-07-21 audit baseline was 15,723 lines, 278 fields, and 205 methods. +Selection/interaction Slice 1 is complete at 14,912 lines, 278 fields, and 191 +methods. Slice 2 — final live animation presentation ownership — is next. Carried: #153 far-teleport residual, #116 slide-response, the remaining R6 ownership cleanup plus registered TS-50/TS-51 timing residuals (the complete-root-Frame/object-workset cutover is automated- and visual-gate complete; Release builds with 17 known -test-project warnings tracked by #228, and 6,481 tests pass / 5 skip), and +test-project warnings tracked by #228, and 6,558 tests pass / 5 skip), and the deferred Modern Pipeline track (MP1b+). The separate #225 shared-alpha implementation has passed connected lifetime/performance gates and awaits only its lifestone/particle visual comparison. diff --git a/docs/plans/2026-07-21-gamewindow-slice-1-selection-interaction.md b/docs/plans/2026-07-21-gamewindow-slice-1-selection-interaction.md index 8a4629da..a61e1b58 100644 --- a/docs/plans/2026-07-21-gamewindow-slice-1-selection-interaction.md +++ b/docs/plans/2026-07-21-gamewindow-slice-1-selection-interaction.md @@ -1,12 +1,33 @@ # GameWindow Slice 1 — selection and interaction ownership -**Status:** Approved for execution 2026-07-21. +**Status:** COMPLETE — landed 2026-07-21. **Parent program:** [`docs/architecture/code-structure.md`](../architecture/code-structure.md), Slice 1. **Baseline:** `cf50ee3d`; `GameWindow.cs` is 15,723 lines before this slice. **Behavior rule:** Existing retail behavior moves unchanged. Any defect found by the extraction audit is fixed in a separately identified commit before the mechanical cutover. +## Landing record + +- Plan/oracle: `c2713837`. +- Exact-incarnation lifetime hardening: `047a4c83`. +- Retail pending keyboard-pickup presentation: `52dbb574`. +- Read-only query extraction: `e74f2ca9`. +- Stateful interaction owner: `fa8d5232`. +- `GameWindow` cutover: `d2bb5af4`. +- Three-review correction pass: `5acc3f01`. + +The correction pass unified retail's one-inventory-request-at-a-time owner +across every mutation surface, separated optimistic/rollback/authoritative +placement notices, made response completion atomic and reentrancy-safe, and +bound pending work to exact object identities and placement tokens. + +Final metrics: `GameWindow.cs` 15,723 → 14,912 lines and 205 → 191 methods; +fields remained 278. Release build passed, the focused selection/inventory +gate passed, the full suite passed 6,558 tests with five intentional skips, +and the retail-conformance, architecture/integration, and adversarial reviews +all finished with no actionable findings. + ## 1. Outcome `GameWindow` stops owning world selection and selection-driven interaction. diff --git a/memory/project_ui_architecture.md b/memory/project_ui_architecture.md index 3a575105..85879794 100644 --- a/memory/project_ui_architecture.md +++ b/memory/project_ui_architecture.md @@ -213,3 +213,36 @@ plus optional stack size, palette, and shade. Healing kit WCIDs are 628 crude, 629 plain, 630 good, 631 excellent, and 632 peerless. The `+Acdream` developer character can therefore create the best kit with either `/ci 632` or `@ci 632`; both forms must produce canonical `@ci 632` Talk text. + +## 2026-07-21 selection extraction and inventory transaction ownership + +`WorldSelectionQuery` is the read-only App boundary over canonical live state, +the completed render-selection frame, object metadata, camera/cursor inputs, +DAT selection bounds, hostile lookup, and Use/PickUp range classification. It +never mutates `SelectionState`, starts movement, or sends packets. + +`SelectionInteractionController` is the corresponding intent owner. It owns +world-click routing, closest/previous selection, the outbound frame-boundary +queue, Use/PickUp transport, and MoveTo deferral. Queued work captures both the +live local entity ID and exact `ClientObject` reference where available; +deferred movement uses cancel-before-arm ordering and a queue epoch prevents +pre-reset work from crossing session lifetime. + +`ItemInteractionController` owns the one global inventory transaction, shaped +after retail `ACCWeenieObject::prevRequest`. Inventory, external-container, +toolbar, paperdoll, give, merge, split, drop, and deferred keyboard pickup all +acquire the same owner. A destination waiting projection carries an exact token +and item identity. Keyboard pickup may remain reserved-but-undispatched while +MoveTo runs, then promotes that exact token only when the wire request is sent. + +`ClientObjectMoveOrigin` distinguishes immediate optimistic repaint, server +rollback repaint, and authoritative response. Only authoritative move/failure/ +remove/stack responses complete the transaction. Completion clears the global +owner and local waiting projection atomically, publishes the old token-specific +projection resolution, then advertises readiness. This order is essential: +reentrant observers may start the next request without the old response tail +rejecting, hiding, or consuming it. Do not regress to GUID-only cleanup or let +ordinary `ObjectUpdated` events complete inventory work. + +`GameWindow` now constructs and forwards narrow lifecycle edges to these +owners; no selection algorithm or interaction request body belongs there.