Skip to content

Accept the join_verify degraded verdict and log it at warn - #5881

Merged
evanpelle merged 1 commit into
mainfrom
claude/ai-ops-98
Oct 12, 2026
Merged

evanpelle merged 1 commit into
mainfrom
claude/ai-ops-98

Conversation

@evanpelle

Copy link
Copy Markdown
Collaborator

Resolves openfrontio/ai-ops#98 (no OpenFrontIO issue; filed by the ops pipeline)

Description:

What was wrong. infra #928 bounds POST /join_verify at 4 s. When siteverify or the name check fails or runs past that budget, it answers 200 {status:"error", reason, username?, clanTag?}, with the screened identity attached when the name check finished. JoinVerifyVerdictSchema here accepted only approved and rejected. Once #928 is deployed, every one of those answers would be logged as api-worker returned malformed response at error level, and the API's name verdict would be thrown away. Fail-open joins were already running at about 10× their usual rate (see the ai-ops issue), so those lines would keep firing and the joins would fall back to the coarser local censor.

What changed.

  • src/server/JoinVerify.ts: the schema now accepts status: "error". JoinVerifyResponse's error variant gains two fields:
    • degraded: true when the API itself reported the failure, false for abort/network, non-2xx or a malformed body.
    • identity: the API's screened {username, clanTag}, present only when the name check finished; an absent clanTag becomes null.
  • src/server/Worker.ts: on error, the join uses the API's identity when it is present and otherwise keeps the locally screened name, as before. The API-reported case is logged as join_verify degraded at warn. An unreachable or broken API is still join_verify error at error.
  • This works with the API currently in production, which never sends status: "error".

Note for dashboards and alerts: budgeted degradations move from the join_verify error line to join_verify degraded. Nothing in infra's src/ops queries this line. Grafana queries such as the issue's |= "join_verify error" will only count real outages from now on.

Alternatives considered. I kept one log message and only lowered its level. Two distinct messages make the outage case easy to count on its own, and the existing query keeps its meaning. I also considered keeping the local censor even when the API sends an identity. The API's name check is the authoritative screen, and the same identity is applied on approval, so this PR uses it.

What I ran.

  • I ran npx vitest tests/server/JoinVerify.test.ts --run with the new tests and without the fix: 7 failed (3 new degraded-verdict tests, plus 4 existing failure-mode tests that now also assert degraded: false). With the fix all 23 pass.
  • npx vitest tests/server --run: 912 passed.
  • npm run typecheck, npm run lint and prettier on the touched files all pass.

Please complete the following:

  • I have added screenshots for all UI updates (no UI changes)
  • I process any text displayed to the user through translateText() and I've added it to the en.json file (no user-visible text)
  • I have added relevant tests to the test directory

Fixes openfrontio/ai-ops#98

🤖 Generated with Claude Code

https://claude.ai/code/session_01Pn2xZjE8oUY44wToJE4NFe


Generated by Claude Code

infra #928 lets POST /join_verify answer 200 {status:"error"} when
siteverify or the name check fails or runs past its 4 s budget, with the
screened username/clanTag attached when the name check finished. The game
server's verdict schema only accepted approved/rejected, so that answer
was logged as a malformed response at error level and the API's name
verdict was dropped.

Accept the error status, use the API's identity when present, and log the
API-reported degradation as "join_verify degraded" at warn. An unreachable
API, a non-2xx or a malformed body stays "join_verify error" at error.
Compatible with the current API, which never sends status "error".

Fixes openfrontio/ai-ops#98

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pn2xZjE8oUY44wToJE4NFe
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@coderabbitai

coderabbitai Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 0d69f479-1a37-4133-817b-2c9db7dfa2a0

📥 Commits

Reviewing files that changed from the base of the PR and between b773251 and d502275.


📒 Files selected for processing (3)
  • src/server/JoinVerify.ts
  • src/server/Worker.ts
  • tests/server/JoinVerify.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.



Walkthrough

Join verification errors now indicate whether the failure is degraded and may include an API-screened identity. The worker applies that identity when present and logs degraded verdicts as warnings.

Changes

Join verification

Layer / File(s) Summary
Verification verdict and fallback
src/server/JoinVerify.ts, tests/server/JoinVerify.test.ts
API error verdicts now include degraded: true and may include a screened identity. HTTP errors, malformed responses, and caught failures use degraded: false. Tests cover identity handling and failure statuses.
Worker error handling
src/server/Worker.ts
The worker applies the verdict identity when present and otherwise uses the locally screened identity. It logs degraded verdicts as warnings and other verification errors as errors.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~12 minutes

Change: Bug fix

Suggested reviewers: celant

Merge Risk: ⚪ Minimal · up to d5022

No actionable merge-blocking issue was established; the change is ready for normal merge checks.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description check Passed The description clearly explains the degraded verdict handling, identity preservation, logging changes, tests, and operational impact.
Title check Passed The title clearly summarizes the main change: accepting the join_verify degraded verdict and logging it at warning level.
Docstring Coverage Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 3 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.


✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Commit to this branch
  • Create a new PR


  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

An API name arrives,
A clan tag may follow.
Degraded errors are marked,
The worker checks the identity.
Warnings light the path.

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

@github-actions

github-actions Bot commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

🤖 Claude Code Review

Verdict: No issues found. 0 findings (0 high, 0 medium, 0 low).

Checked for bugs and CLAUDE.md compliance. The new status: "error" schema variant, the degraded/identity fields (every error path in verifyJoin sets degraded, and verifyJoin is the only producer of JoinVerifyResponse), and the Worker.ts fail-open branch (it uses the API identity when present and otherwise keeps the local censorPlayer result, which then flows into rejoinClient and the join) all look correct. The tests cover the new verdict shapes.

@evanpelle evanpelle added this to the v35 milestone Oct 12, 2026
@evanpelle
evanpelle merged commit cce492a into main Oct 12, 2026
17 of 19 checks passed
@evanpelle
evanpelle deleted the claude/ai-ops-98 branch October 12, 2026 18:24

This branch was successfully deployed

2 active deployments
backport — d5022752 Deployed Oct 12, 2026 by evanpelle via Cherry-pick #281
staging — d5022752 Deployed Oct 9, 2026 by openfrontio[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Complete

Development

Successfully merging this pull request may close these issues.

3 participants