ClientAuthProbe
Client-only half of the AuthGate: computes the session-derived authorization decision from live client state, on the client thread, every client tick, and publishes it to AuthGate's volatile. Touching Minecraft here keeps that link out of AuthGate, which loads on a dedicated server; there Lane.pump never takes the client branch, so this object is never reached.
Rides the client-lane heartbeat, which fires every tick regardless of active evals, so the gate stays fresh even when idle.
The client-known op level can read 0 for an instant right after connecting, which merely denies for that instant and self-heals on the next tick.
Types
A reflective probe resolved at most once. get answers null until Mappings.namesResolvable: before that, every mojmap name is a guaranteed miss, and probing anyway burns 2-3 thrown exceptions per client tick — for the whole session if the mapping load failed. A resolution FAILURE is cached as a re-throw; past that point the mapping table and the runtime classes are both fixed, so the miss is permanent.
Properties
WorldData's single-player "Allow Cheats" flag. The getter was renamed getAllowCommands() (<1.20.5) -> isAllowCommands() (>=1.20.5) — inside the 1.20 jar's own version range, so no compile-time choice spans it. Resolving the live method at runtime lets ONE jar span the rename.
Client player's "permission level >= 3" — the COMMANDS_ADMIN tier that gates commands/cheats. Two shapes, because the 26.1 permission rework left no single compiled name spanning the range:
One-shot latch for the probe-failure log. observe runs ~20x/s, so a deterministic failure would otherwise emit a stack trace every client tick.
Same, for the unresolved path — which compute reaches without throwing.
Functions
Still a denial — this is the authorization gate — but named: names WERE resolvable, or LazyProbe.get would have returned null, so what doesn't match is the runtime's shape, not the mapping table.