Why it exists
Put identity, rank, target, and API checks around staff-facing role changes.
A Discord command can cause a Roblox group write, so the executor, target, current role, and failure path need explicit handling.
Based on the code in the private Valor repo.
How it works
- 01
Receive command
Slash-command modules parse a staff action such as promote, demote, accept, inspect, or exile.
- 02
Resolve identities
The command resolves a Discord member and the corresponding Roblox user and membership.
- 03
Authorize
Rank, self-targeting, and target hierarchy checks run before a role-changing operation.
- 04
Call Roblox
RobloxClient handles Open Cloud requests, bounded retries, timeouts, and rate-limit responses.
- 05
Respond and audit
CommandResponse returns an outcome while audit and error paths record the attempted operation.
Selected code
These excerpts are from the paths shown on each patch. Select an annotation for a focused note; copy code directly from each patch.
Authorise.ts
src/backend/authorization/Authorise.ts
The command authorization module prevents self-targeting and equal-or-higher-rank targets before a role operation.
function notSelf(): AuthoriseCondition {
return async (context): Promise<AuthoriseResult> => {
if (!context.target) {
return { allowed: false, reason: "The target could not be found." };
}
const sameDiscordUser =
context.target.discordId !== undefined &&
context.target.discordId === context.executor.discordId;
const sameRobloxUser =
context.target.robloxUserId !== undefined &&
context.target.robloxUserId === context.executor.robloxUserId;
if (!sameDiscordUser && !sameRobloxUser) return { allowed: true };
return { allowed: false, reason: "You cannot target yourself." };
};
}
function targetBelowExecutor(): AuthoriseCondition {
return async (context): Promise<AuthoriseResult> => {
const targetRankId = context.target?.robloxRankId;
if (
targetRankId !== undefined &&
targetRankId < context.executor.robloxRankId
) {
return { allowed: true };
}
return {
allowed: false,
reason: "You cannot target someone with an equal or higher rank.",
};
};
}Engineering decisions
Composable authorization
- Reason
- Reusable conditions keep rank and target checks visible at command boundaries.
- Alternative
- Rely on Discord command visibility alone.
- Tradeoff
- Each command must assemble the conditions it needs.
Bounded API retries
- Reason
- RobloxClient retries network failures and 429/5xx responses within a fixed attempt limit.
- Alternative
- Fail every transient response immediately.
- Tradeoff
- Retries add latency and do not guarantee a successful write.
Outcome & next steps
Outcome
The source implements modular commands, authorization conditions, a Roblox API client, health checks, and audit handling.
What improved
The role-changing commands put target and hierarchy checks before external writes.
Current limitations
- The repository states that it has typecheck and build validation but no automated test or lint script.
- A successful live role write was not verified in this audit.
Future improvements
- Add automated command and Roblox-client tests using mocked API responses.
What this demonstrates
Typed Discord command boundaries, authorization, and defensive third-party API handling.