Skip to content

refactor(trainer): typed refusals across the tier contract - #418

Merged
Mathih13 merged 3 commits into
mainfrom
refactor/trainer-typed-refusals
Sep 4, 2026
Merged

Mathih13 merged 3 commits into
mainfrom
refactor/trainer-typed-refusals

Conversation

@Mathih13

@Mathih13 Mathih13 commented Sep 3, 2026 •

Copy link
Copy Markdown
Contributor

Trainer timeouts were reported as ordinary purchase refusals, even when the purchase result was unknown. The Module now returns stable TrainerRefusal tags. The Coordinator translates known tags into client outcomes and propagates transport failures, timeouts and unknown results so they end the World Session.

Taxi-flight purchases remain an expected Unavailable refusal. Missing Actors and Operator failures remain fatal. Client failure codes and successful purchases keep their existing behavior.

Verification: shared tag round trips, Module purchase Gate tests, Gateway client-code mapping and timeout behavior, and cargo check -p lyracore-gateway --tests. The review fixes are rebased onto main at 3850bae. CI runs the full checks.

Review fixes by GPT-5.6 Sol through Codex, reviewed by GPT-6 through Codex.

Summary by CodeRabbit

  • New Features

    • Trainer purchases now provide clear, standardized refusal reasons, including unavailable trainers, unmet level requirements, missing prerequisites, known spells, and insufficient funds.
    • Successful purchases are distinguished from gameplay refusals, allowing appropriate client-facing feedback.
  • Bug Fixes

    • Unexpected system and timeout errors remain distinct from normal trainer purchase refusals instead of being misreported as gameplay outcomes.
    • Trainer interactions during taxi flight now return an appropriate trainer-specific refusal.
  • Documentation

    • Updated documented trainer error tags to match the standardized refusal format.

@Mathih13
Mathih13 force-pushed the refactor/trainer-typed-refusals branch from 1da2a4b to f4ca58e Compare September 3, 2026 21:03
@Mathih13

Mathih13 commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Sep 4, 2026 •

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@coderabbitai

coderabbitai Bot commented Sep 4, 2026 •

Copy link
Copy Markdown

Review Change Stack

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: dacb9f84-f346-4067-a162-5fce1cc13858

📥 Commits

Reviewing files that changed from the base of the PR and between f4ca58e and c401771.

📒 Files selected for processing (3)
  • gateway/src/world/mod.rs
  • module/src/gw.rs
  • module/src/trainer.rs

Included review availability: Your plan provides up to 10 included reviews per hour; 1 remains after this review.


📝 Walkthrough

Walkthrough

Trainer purchase failures now use typed TrainerRefusal values. Gateway reducers and world handlers distinguish gameplay refusals from durable errors and map refusals to client protocol reasons.

Changes

Trainer refusal flow

Layer / File(s) Summary
Typed refusal contracts and producer mappings
crates/lyracore-shared/src/trainer.rs, module/src/trainer.rs, module/src/gw.rs, module/src/skill.rs
Defines TrainerRefusal, canonical tags, parsing, and tests. Trainer validation and actor resolution now return typed refusal variants.
Reducer outcome conversion and packet encoding
gateway/src/stdb/reducers.rs, gateway/src/codec/trainer.rs
Parses recognized refusal tags into TrainerBuyOutcome values. Fatal and unrelated errors remain failures. Trainer failure packets accept TrainingFailureReason directly.
World-store propagation and handler behavior
gateway/src/world/store.rs, gateway/src/stdb/world_store.rs, gateway/src/world/handlers/trainer.rs, gateway/src/world/handlers/mod.rs, gateway/src/world/mod.rs, gateway/src/world/tests.rs
Forwards typed outcomes, sends explicit refusal packets, propagates durable errors, updates exports and login-queue wiring, and tests refusal mappings and timeout handling.

Estimated code review effort: 4 (Complex) | ~45 minutes

Merge Risk: ⚪ Minimal · up to c4017

Trainer purchase refusals now use typed outcomes across the module and gateway, preserving explicit client failure responses while durable failures terminate the session. No concrete current-head merge-blocking risk remains.

Sequence Diagram(s)

sequenceDiagram
  participant TrainerHandler
  participant WorldStore
  participant StdbReducers
  participant TrainerCodec
  TrainerHandler->>WorldStore: buy_trainer_spell
  WorldStore->>StdbReducers: request trainer purchase
  StdbReducers-->>WorldStore: Learned or Refused
  WorldStore-->>TrainerHandler: return TrainerBuyOutcome
  TrainerHandler->>TrainerCodec: build_trainer_buy_failed
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 81.58% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 38 functions across 12 files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: introducing typed trainer refusals across the Module, Coordinator, and shared contract.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/trainer-typed-refusals

Comment @coderabbitai help to get the list of available commands.

Mathih13 and others added 2 commits September 4, 2026 23:05
The Module refused a trainer buy with a "[N] detail" string and the Gateway
searched that text for "[1]" or "[2]". Any failure without a bracket, a reducer
timeout included, reached the client as a gameplay refusal.

One shared `TrainerRefusal` enum now defines the contract. The Module sends only
the tag and keeps the human detail in its log. The Gateway parses the tag from a
reducer the Module rejected; a timeout, transport, or SDK failure stays an error
and ends the session. `TrainerBuyOutcome` holds the client mapping onto gtker's
three `TrainingFailureReason` codes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@Mathih13
Mathih13 force-pushed the refactor/trainer-typed-refusals branch from f4ca58e to af90e69 Compare September 4, 2026 21:08
@Mathih13
Mathih13 merged commit e231e2f into main Sep 4, 2026
6 checks passed
@Mathih13
Mathih13 deleted the refactor/trainer-typed-refusals branch October 11, 2026 18:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant