Repository navigation
feat(core): operator read tools and the agent-chat grant for the back-office assistant - #401
Open
mp-blurify wants to merge 6 commits into
Open
mp-blurify wants to merge 6 commits into
mp-blurify wants to merge 6 commits into
Conversation
…tant The agent hub gates its back-office assistant on `agent-chat:use`. Core only declares the grant: the assistant reads platform tools through the MCP kernel on the asking admin's own grants. The static admin role and the seeded admin role hold it, like `mcp-access`, and only the read-write level grants it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Mateusz Paś <mateusz.pas@studiosoftware.com>
Two operator-level read tools for the back-office assistant, both gated on `analytics:view`: - `payments.flow_daily` counts and sums deposits and withdrawals per UTC day or ISO week, type, status (every wallet transaction status) and currency over at most 92 days, 14 by default. One grouped query, cached like the other financial reports, capped at 1000 rows with a `truncated` flag. It names no player. - `financial.summary` wraps the existing summary and product split: deposits, withdrawals, net deposits, GGR, bonus cost and NGR per currency, rails folded together, plus stakes, payouts and GGR per product, over at most 366 days. Every list is capped. The day-range defaults and bounds of `ggr.summary` move into one helper the three tools share. Bonus cost keeps its meaning (bonus money converted to cash); the description says that cashback credits such as rakeback are not in it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Mateusz Paś <mateusz.pas@studiosoftware.com>
…ools Two operator-level read tools for the back-office assistant: - `withdrawals.queue` (`withdrawal:view`) gives the queue's pending and on-hold counts, totals per currency and average pending wait, plus the oldest 1 to 20 queued withdrawals with their withdrawal id, player id, amount, status, wait, KYC status and the queue's risk tags. It reads no review note, address, hash, username or email. The risk tags the admin queue shows move into one helper both use. - `players.deposit_compare` (`transaction:view`) compares the completed deposits of a tagged segment between two windows of at most 92 days, each player priced into the fx pivot currency, and ranks the largest drops or rises (at most 50). It pages the segment through `PLAYER_SEGMENT_READER` and refuses a segment above 20 000 players as `segment_too_large`. Each page costs one query for its user ids and one array-parameter query for its deposits; a quote is fetched once per currency pair. A player with an unpriceable deposit is counted, never guessed. `IdentityReader` gains an optional batched `getUserIdsByPlayerIds` (with `userIdsOfPlayers`, which fails closed when it is missing), and the pivot pricing the wallet reader used moves into a module helper the comparison shares. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Mateusz Paś <mateusz.pas@studiosoftware.com>
…cp kernel The kernel suite now expects the eight read tools and calls each new one against seeded ledger rows: exactly the allow-listed keys, realistic totals (every status of a payment day, cashback outside bonus cost, the oldest held withdrawal, a vip segment's drop in the pivot currency), no review note, address, email or user id in what is served, and `invalid_input` for an out-of-bounds range, window or limit. An admin whose seeded role lacks the tool's grant gets `forbidden`, audited once. The transport suite lists the new tools under their model names. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Mateusz Paś <mateusz.pas@studiosoftware.com>
ADR-0042 gains a dated update: the four operator-level read tools and their grants, the bounds and caps every one of them keeps, the free text and identifiers none of them returns, the rule that a player is named only by player id under a `playerId`-style key because consumers pseudonymise by key name, and the `agent-chat:use` grant. The wallet module doc lists its two new tools. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Mateusz Paś <mateusz.pas@studiosoftware.com>
mp-blurify
marked this pull request as ready for review
November 6, 2026 12:06
mp-blurify
requested review from
jakubfilinger-b,
klaudia-blazyczek-blurify,
marek-chmielowski-blurify,
okapitula and
zaxovaiko
as code owners
November 6, 2026 12:06
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
agent-chat:usegrant that a back-office AI assistant is gated on; the static and seeded admin roles hold it, and only the read-write level grants it.payments.flow_dailyandfinancial.summaryanalytics read tools (analytics:view).withdrawals.queue(withdrawal:view) andplayers.deposit_compare(transaction:view) wallet read tools.IdentityReadergains an optional batchedgetUserIdsByPlayerIds; the comparison fails closed without it.Why
An assistant that answers an operator's questions reads platform tools through the MCP kernel on the asking admin's own grants. The tools so far are per player or narrow reports: the questions an operator asks first - how payments flowed this week, what waits in the withdrawal queue, which segment deposits less than last month, the financial summary of a period - had no tool. Core also had no grant to let an admin use such an assistant apart from running agents.
Every new tool is bounded (windows of at most 92 or 366 days, capped lists with a
truncatedflag or a hard limit), returns only allow-listed keys, and names a player only by player id under aplayerId-style key, because consumers pseudonymise by key name. None returns a review note, address, transaction hash, username, email or user id.Diagram
flowchart LR A[Admin's question] --> H[Assistant turn] H -->|tool call| K[MCP kernel] K -->|grant check on the admin's roles| G{granted?} G -->|no| F[forbidden, audited] G -->|yes| V[input contract: bounded windows and limits] V --> T[read tool: analytics or wallet] T --> R[allow-listed keys, playerId keys only] R --> HAlternatives considered
Risks
agent-chat:useis new: roles other than the static and seeded admin roles do not hold it until an operator grants it, and nothing checks it until a consumer gates on it.players.deposit_comparerefuses a segment above 20 000 players (segment_too_large).IdentityReaderwithoutgetUserIdsByPlayerIdsmakes the deposit comparison fail closed.financial.summarykeeps bonus cost as bonus money converted to cash, so NGR does not deduct cashback credits such as rakeback; the tool description says so. Whether NGR should deduct them is a separate decision.